KERNEL_PATCHVER:=$(KERNEL_TESTING_PATCHVER)
endif
-LINUX_VERSION-4.14 = .173
+LINUX_VERSION-4.14 = .185
-LINUX_KERNEL_HASH-4.14.173 = 615f3a798d99b2e986627f0c5618bee8dfd61e7f645bcc3bb90cfaf953d9cb26
+LINUX_KERNEL_HASH-4.14.185 = 181f18ab15236ea3f6ec83ad95b4b9c630933a35f3ce15a722eb60555fce924c
remove_uri_prefix=$(subst git://,,$(subst http://,,$(subst https://,,$(1))))
sanitize_uri=$(call qstrip,$(subst @,_,$(subst :,_,$(subst .,_,$(subst -,_,$(subst /,_,$(1)))))))
$(eval $(call SetupHostCommand,perl,Please install Perl 5.x, \
perl --version | grep "perl.*v5"))
-$(eval $(call CleanupPython3))
-
-$(eval $(call SetupHostCommand,python,Please install Python 2.x, \
- python2.7 -V 2>&1 | grep 'Python 2.7', \
- python2 -V 2>&1 | grep 'Python 2', \
- python -V 2>&1 | grep 'Python 2'))
+$(eval $(call CleanupPython2))
+
+$(eval $(call SetupHostCommand,python,Please install Python >= 3.5, \
+ python3.8 -V 2>&1 | grep 'Python 3', \
+ python3.7 -V 2>&1 | grep 'Python 3', \
+ python3.6 -V 2>&1 | grep 'Python 3', \
+ python3.5 -V 2>&1 | grep 'Python 3', \
+ python3 -V 2>&1 | grep -E 'Python 3\.[5-9]\.?'))
$(eval $(call SetupHostCommand,git,Please install Git (git-core) >= 1.7.12.2, \
git --exec-path | xargs -I % -- grep -q -- --recursive %/git-submodule))
$$(eval $$(call Require,$(1),$(2)))
endef
-define CleanupPython3
- define Require/python3-cleanup
+define CleanupPython2
+ define Require/python2-cleanup
if [ -f "$(STAGING_DIR_HOST)/bin/python" ] && \
$(STAGING_DIR_HOST)/bin/python -V 2>&1 | \
- grep -q 'Python 3'; then \
+ grep -q 'Python 2'; then \
rm $(STAGING_DIR_HOST)/bin/python; \
fi
endef
- $$(eval $$(call Require,python3-cleanup))
+ $$(eval $$(call Require,python2-cleanup))
endef
define QuoteHostCommand
+++ /dev/null
-export PLATFORM=posix
-
-SCONS_VARS = \
- CC="$(TARGET_CC_NOCACHE)" \
- CXX="$(TARGET_CXX_NOCACHE)" \
- CFLAGS="$(TARGET_CFLAGS) $(EXTRA_CFLAGS)" \
- CXXFLAGS="$(TARGET_CXXFLAGS) $(EXTRA_CXXFLAGS)" \
- CPPFLAGS="$(TARGET_CPPFLAGS) $(EXTRA_CPPFLAGS)" \
- LDFLAGS="$(TARGET_LDFLAGS) $(EXTRA_LDFLAGS)" \
- DESTDIR="$(PKG_INSTALL_DIR)"
-
-define Build/Configure/Default
- (cd $(PKG_BUILD_DIR); \
- $(SCONS_VARS) \
- scons \
- prefix=/usr \
- $(SCONS_OPTIONS) \
- install \
- )
-endef
-
-define Build/Compile
-endef
sanitize = $(call tolower,$(subst _,-,$(subst $(space),-,$(1))))
VERSION_NUMBER:=$(call qstrip,$(CONFIG_VERSION_NUMBER))
-VERSION_NUMBER:=$(if $(VERSION_NUMBER),$(VERSION_NUMBER),v1.5.1)
+VERSION_NUMBER:=$(if $(VERSION_NUMBER),$(VERSION_NUMBER),v1.5.2)
VERSION_CODE:=$(call qstrip,$(CONFIG_VERSION_CODE))
VERSION_CODE:=$(if $(VERSION_CODE),$(VERSION_CODE),$(REVISION))
NO_LIBAUDIT=1 \
NO_LIBCRYPTO=1 \
NO_LIBUNWIND=1 \
+ NO_LIBCAP=1 \
CROSS_COMPILE="$(TARGET_CROSS)" \
CC="$(TARGET_CC)" \
LD="$(TARGET_CROSS)ld" \
PKG_NAME:=wireless-regdb
PKG_VERSION:=2019.06.03
+PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=@KERNEL/software/network/wireless-regdb/
--- /dev/null
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Martin Willi <martin@strongswan.org>
+Date: Tue, 2 Jul 2019 16:19:44 +0200
+Subject: [PATCH] wireless-regdb: Fix overlapping ranges for Switzerland and
+ Liechtenstein
+
+The commit referenced below changes the 5GHz frequency range 5250-5330
+to 5150-5330, making that range overlapping with the existing range
+5170-5250. This imposes DFS limitations and a reduced maximum power
+level for the range 5170-5250.
+
+The change of the frequency range seems not intentional. Instead the
+commit should have changed the 5170-5250 range to 5150-5250, and the
+5250-5330 range to 5250-5350 (see [1]).
+
+[1] https://www.ofcomnet.ch/api/rir/1010/05
+
+Fixes: 957a7cff72a3 ("wireless-regdb: update regulatory rules for Switzerland (CH), and Liechtenstein (LI) on 5GHz")
+Signed-off-by: Martin Willi <martin@strongswan.org>
+Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
+
+diff --git a/db.txt b/db.txt
+index d47ab94c3aa5..37393e6a793e 100644
+--- a/db.txt
++++ b/db.txt
+@@ -271,8 +271,8 @@ country CF: DFS-FCC
+ # transmitter power control is in use: 5250-5330@23db, 5490-5710@30db
+ country CH: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+- (5170 - 5250 @ 80), (23), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
+- (5150 - 5330 @ 80), (20), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
++ (5150 - 5250 @ 80), (23), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
++ (5250 - 5350 @ 80), (20), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
+ (5490 - 5710 @ 160), (27), DFS, wmmrule=ETSI
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+@@ -747,8 +747,8 @@ country LC: DFS-ETSI
+ # transmitter power control is in use: 5250-5330@23db, 5490-5710@30db
+ country LI: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+- (5170 - 5250 @ 80), (23), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
+- (5150 - 5330 @ 80), (20), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
++ (5150 - 5250 @ 80), (23), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
++ (5250 - 5350 @ 80), (20), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
+ (5490 - 5710 @ 160), (27), DFS, wmmrule=ETSI
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
--- /dev/null
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Emil Petersky <emil.petersky@streamunlimited.com>
+Date: Tue, 17 Sep 2019 09:49:19 +0200
+Subject: [PATCH] wireless-regdb: Fix ranges of EU countries as they are
+ harmonized since 2014
+
+This patch unites entries for EU countries, as they have been harmonized
+latest by July 2014...
+
+EU decision 2005/513/EC:
+https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02005D0513-20070213
+EU decision 2006/771/EC:
+https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02008D0432-20080611
+
+Signed-off-by: Emil Petersky <emil.petersky@streamunlimited.com>
+Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
+
+diff --git a/db.txt b/db.txt
+index 2e149b6e0ea2..a57452479a9b 100644
+--- a/db.txt
++++ b/db.txt
+@@ -87,12 +87,20 @@ country AS: DFS-FCC
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
++# AT as part of EU/CEPT accepted decisions 2005/513/EC (5GHz RLAN, EN 301 893)
++# and 2006/771/EC (amended by 2008/432/EC, Short-Range Devices, EN 300 440)
++# EU decision 2005/513/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02005D0513-20070213
++# EU decision 2006/771/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02008D0432-20080611
++# AT: https://www.rtr.at/en/tk/Spektrum5GHz/1997_bmvit-info-052010en.pdf
++# AT: acceptance https://www.ris.bka.gv.at/Dokumente/BgblAuth/BGBLA_2014_II_63/BGBLA_2014_II_63.pdfsig
+ country AT: DFS-ETSI
+- (2402 - 2482 @ 40), (20)
+- (5170 - 5250 @ 80), (20), AUTO-BW, wmmrule=ETSI
+- (5250 - 5330 @ 80), (20), DFS, AUTO-BW, wmmrule=ETSI
+- (5490 - 5710 @ 160), (27), DFS, wmmrule=ETSI
+- # 60 GHz band channels 1-4, ref: Etsi En 302 567
++ (2400 - 2483.5 @ 40), (100 mW)
++ (5150 - 5250 @ 80), (200 mW), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
++ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
++ (5470 - 5725 @ 160), (500 mW), DFS, wmmrule=ETSI
++ # short range devices (ETSI EN 300 440-1)
++ (5725 - 5875 @ 80), (25 mW)
++ # 60 GHz band channels 1-4 (ETSI EN 302 567)
+ (57000 - 66000 @ 2160), (40)
+
+ # Source:
+@@ -139,12 +147,22 @@ country BD: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5735 - 5835 @ 80), (30)
+
++# BE as part of EU/CEPT accepted decisions 2005/513/EC (5GHz RLAN, EN 301 893)
++# and 2006/771/EC (amended by 2008/432/EC, Short-Range Devices, EN 300 440)
++# EU decision 2005/513/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02005D0513-20070213
++# EU decision 2006/771/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02008D0432-20080611
++# BE: https://www.ibpt.be/public/files/en/21760/B03-01_2.1_EN.pdf
++# BE: https://www.ibpt.be/public/files/en/21761/B03-02_2.1_EN.pdf
++# BE: https://www.ibpt.be/public/files/en/21762/B03-03_2.1_EN.pdf
++# BE: https://www.ibpt.be/public/files/en/22165/B01-28_3.1_EN.pdf
+ country BE: DFS-ETSI
+- (2402 - 2482 @ 40), (20)
+- (5170 - 5250 @ 80), (20), AUTO-BW, wmmrule=ETSI
+- (5250 - 5330 @ 80), (20), DFS, AUTO-BW, wmmrule=ETSI
+- (5490 - 5710 @ 160), (27), DFS, wmmrule=ETSI
+- # 60 GHz band channels 1-4, ref: Etsi En 302 567
++ (2400 - 2483.5 @ 40), (100 mW)
++ (5150 - 5250 @ 80), (200 mW), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
++ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
++ (5470 - 5725 @ 160), (500 mW), DFS, wmmrule=ETSI
++ # short range devices (ETSI EN 300 440-1)
++ (5725 - 5875 @ 80), (25 mW)
++ # 60 GHz band channels 1-4 (ETSI EN 302 567)
+ (57000 - 66000 @ 2160), (40)
+
+ country BF: DFS-FCC
+@@ -167,22 +185,29 @@ country BF: DFS-FCC
+ #
+ # Note: The transmit power limits in the 5250-5350 MHz and 5470-5725 MHz bands
+ # can be raised by 3 dBm if TPC is enabled. Refer to BDS EN 301 893 for details.
++#
++# BG as part of EU/CEPT accepted decisions 2005/513/EC (5GHz RLAN, EN 301 893)
++# and 2006/771/EC (amended by 2008/432/EC, Short-Range Devices, EN 300 440)
++# EU decision 2005/513/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02005D0513-20070213
++# EU decision 2006/771/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02008D0432-20080611
++# BG: https://crc.bg/files/_en/Electronic_Communications_Revised_EN1.pdf
++# BG: acceptance of 2006/771/EC https://crc.bg/files/Pravila_06_12_2018.pdf
+ country BG: DFS-ETSI
+ # Wideband data transmission systems (WDTS) in the 2.4GHz ISM band, ref:
+ # I.22 of the List, BDS EN 300 328
+- (2402 - 2482 @ 40), (20)
++ (2400 - 2483.5 @ 40), (100 mW)
+ # 5 GHz Radio Local Area Networks (RLANs), ref:
+ # II.H01 of the List, BDS EN 301 893
+- (5170 - 5250 @ 80), (23), AUTO-BW, wmmrule=ETSI
+- (5250 - 5330 @ 80), (20), DFS, AUTO-BW, wmmrule=ETSI
++ (5150 - 5250 @ 80), (200 mW), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
++ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
+ # II.H01 of the List, I.54 from the List, BDS EN 301 893
+- (5490 - 5710 @ 160), (27), DFS, wmmrule=ETSI
+- # Short range devices (SRDs) in the 5725-5875 MHz frequency range, ref:
++ (5470 - 5725 @ 160), (500 mW), DFS, wmmrule=ETSI
++ # short range devices (ETSI EN 300 440-1)
+ # I.43 of the List, BDS EN 300 440-2, BDS EN 300 440-1
+- (5725 - 5875 @ 80), (14)
+- # 60 GHz Multiple-Gigabit RLAN Systems, ref:
++ (5725 - 5875 @ 80), (25 mW)
++ # 60 GHz band channels 1-4 (ETSI EN 302 567)
+ # II.H03 of the List, BDS EN 302 567-2
+- (57000 - 66000 @ 2160), (40), NO-OUTDOOR
++ (57000 - 66000 @ 2160), (40)
+
+ country BH: DFS-JP
+ (2402 - 2482 @ 40), (20)
+@@ -265,16 +290,22 @@ country CF: DFS-FCC
+ (5490 - 5730 @ 40), (24), DFS
+ (5735 - 5835 @ 40), (30)
+
+-# Source:
+-# https://www.ofcomnet.ch/#/fatTable
+-# Note that the maximum transmitter power can be doubled for 5250-5710MHz if
+-# transmitter power control is in use: 5250-5330@23db, 5490-5710@30db
++# CH as part of CEPT accepted decisions 2005/513/EC (5GHz RLAN, EN 301 893)
++# and 2006/771/EC (amended by 2008/432/EC, Short-Range Devices, EN 300 440)
++# EU decision 2005/513/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02005D0513-20070213
++# EU decision 2006/771/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02008D0432-20080611
++# CH: https://www.ofcomnet.ch/api/rir/1010/05
++# CH: https://www.ofcomnet.ch/api/rir/1010/04
++# CH: https://www.ofcomnet.ch/api/rir/1008/12
++# CH: https://www.ofcomnet.ch/#/fatTable
+ country CH: DFS-ETSI
+- (2402 - 2482 @ 40), (20)
+- (5150 - 5250 @ 80), (23), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
+- (5250 - 5350 @ 80), (20), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
+- (5490 - 5710 @ 160), (27), DFS, wmmrule=ETSI
+- # 60 GHz band channels 1-4, ref: Etsi En 302 567
++ (2400 - 2483.5 @ 40), (100 mW)
++ (5150 - 5250 @ 80), (200 mW), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
++ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
++ (5470 - 5725 @ 160), (500 mW), DFS, wmmrule=ETSI
++ # short range devices (ETSI EN 300 440-1)
++ (5725 - 5875 @ 80), (25 mW)
++ # 60 GHz band channels 1-4 (ETSI EN 302 567)
+ (57000 - 66000 @ 2160), (40)
+
+ country CI: DFS-FCC
+@@ -329,26 +360,42 @@ country CX: DFS-FCC
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
++# CY as part of EU/CEPT accepted decisions 2005/513/EC (5GHz RLAN, EN 301 893)
++# and 2006/771/EC (amended by 2008/432/EC, Short-Range Devices, EN 300 440)
++# EU decision 2005/513/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02005D0513-20070213
++# EU decision 2006/771/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02008D0432-20080611
++# CY: http://www.mcw.gov.cy/mcw/dec/dec.nsf/all/292484CFC7013DD4C2256EBA0023D447/$file/Sxedio%20Radiosyxnothtwn%20ths%20Dhmokratias-3-8-2018-E2.2(English%20Unified%20Unofficial).pdf?openelement
+ country CY: DFS-ETSI
+- (2402 - 2482 @ 40), (20)
+- (5170 - 5250 @ 80), (20), AUTO-BW, wmmrule=ETSI
+- (5250 - 5330 @ 80), (20), DFS, AUTO-BW, wmmrule=ETSI
+- (5490 - 5710 @ 160), (27), DFS, wmmrule=ETSI
+- # 60 GHz band channels 1-4, ref: Etsi En 302 567
++ (2400 - 2483.5 @ 40), (100 mW)
++ (5150 - 5250 @ 80), (200 mW), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
++ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
++ (5470 - 5725 @ 160), (500 mW), DFS, wmmrule=ETSI
++ # short range devices (ETSI EN 300 440-1)
++ (5725 - 5875 @ 80), (25 mW)
++ # 60 GHz band channels 1-4 (ETSI EN 302 567)
+ (57000 - 66000 @ 2160), (40)
+
+-# Data from http://www.ctu.eu/164/download/VOR/VOR-12-08-2005-34.pdf
+-# and http://www.ctu.eu/164/download/VOR/VOR-12-05-2007-6-AN.pdf
+-# Power at 5250 - 5350 MHz and 5470 - 5725 MHz can be doubled if TPC is
+-# implemented.
++# CZ as part of EU/CEPT accepted decisions 2005/513/EC (5GHz RLAN, EN 301 893)
++# and 2006/771/EC (amended by 2008/432/EC, Short-Range Devices, EN 300 440)
++# EU decision 2005/513/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02005D0513-20070213
++# EU decision 2006/771/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02008D0432-20080611
++# CZ: https://www.ctu.cz/cs/download/vseobecna-opravneni/archiv/vo-r_12-06_2010-09.pdf
++# CZ: https://www.ctu.cz/sites/default/files/obsah/ctu/vseobecne-opravneni-c.vo-r/10/12.2017-10/obrazky/vo-r10-122017-10.pdf
+ country CZ: DFS-ETSI
+ (2400 - 2483.5 @ 40), (100 mW)
+ (5150 - 5250 @ 80), (200 mW), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
+ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
+ (5470 - 5725 @ 160), (500 mW), DFS, wmmrule=ETSI
+- # 60 GHz band channels 1-4, ref: Etsi En 302 567
++ # short range devices (ETSI EN 300 440-1)
++ (5725 - 5875 @ 80), (25 mW)
++ # 60 GHz band channels 1-4 (ETSI EN 302 567)
+ (57000 - 66000 @ 2160), (40)
+
++# DE as part of EU/CEPT accepted decisions 2005/513/EC (5GHz RLAN, EN 301 893)
++# and 2006/771/EC (amended by 2008/432/EC, Short-Range Devices, EN 300 440)
++# EU decision 2005/513/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02005D0513-20070213
++# EU decision 2006/771/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02008D0432-20080611
++#
+ # Allocation for the 2.4 GHz band (Vfg 10 / 2013, Allgemeinzuteilung von
+ # Frequenzen für die Nutzung in lokalen Netzwerken; Wireless Local Area
+ # Networks (WLAN-Funkanwendungen).
+@@ -379,16 +426,22 @@ country DE: DFS-ETSI
+ # 60 GHz band channels 1-4 (ETSI EN 302 567)
+ (57000 - 66000 @ 2160), (40)
+
+-# Sources:
++# DK as part of EU/CEPT accepted decisions 2005/513/EC (5GHz RLAN, EN 301 893)
++# and 2006/771/EC (amended by 2008/432/EC, Short-Range Devices, EN 300 440)
++# EU decision 2005/513/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02005D0513-20070213
++# EU decision 2006/771/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02008D0432-20080611
++# DK: https://ens.dk/sites/ens.dk/files/Tele/frekvensplan_0.pdf
+ # 5GHz: https://erhvervsstyrelsen.dk/sites/default/files/007_interface-datanet_5-6_ghz.pdf.pdf
+ # 60GHz: https://erhvervsstyrelsen.dk/sites/default/files/radiograenseflader-63.pdf
+ country DK: DFS-ETSI
+- (2400 - 2483.5 @ 40), (20)
+- (5150 - 5250 @ 80), (23), AUTO-BW, wmmrule=ETSI
+- (5250 - 5350 @ 80), (20), DFS, AUTO-BW, wmmrule=ETSI
+- (5470 - 5725 @ 160), (27), DFS, wmmrule=ETSI
++ (2400 - 2483.5 @ 40), (100 mW)
++ (5150 - 5250 @ 80), (200 mW), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
++ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
++ (5470 - 5725 @ 160), (500 mW), DFS, wmmrule=ETSI
++ # short range devices (ETSI EN 300 440-1)
++ (5725 - 5875 @ 80), (25 mW)
+ # 60 GHz band channels 1-4 (ETSI EN 302 567)
+- (57000 - 66000 @ 2160), (40), NO-OUTDOOR
++ (57000 - 66000 @ 2160), (40)
+
+ # Source:
+ # http://www.ntrcdom.org/index.php?option=com_content&view=category&layout=blog&id=10&Itemid=55
+@@ -417,12 +470,20 @@ country EC: DFS-FCC
+ (5490 - 5730 @ 20), (24), DFS
+ (5735 - 5835 @ 20), (30)
+
++# EE as part of EU/CEPT accepted decisions 2005/513/EC (5GHz RLAN, EN 301 893)
++# and 2006/771/EC (amended by 2008/432/EC, Short-Range Devices, EN 300 440)
++# EU decision 2005/513/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02005D0513-20070213
++# EU decision 2006/771/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02008D0432-20080611
++# EE: https://www.ttja.ee/et/ettevottele-organisatsioonile/sideteenused/raadioseadmed/wifi-seade
++# EE: https://www.itu.int/ITU-D/study_groups/SGP_1998-2002/JGRES09/pdf/estonia.pdf
+ country EE: DFS-ETSI
+- (2402 - 2482 @ 40), (20)
+- (5170 - 5250 @ 80), (20), AUTO-BW, wmmrule=ETSI
+- (5250 - 5330 @ 80), (20), DFS, AUTO-BW, wmmrule=ETSI
+- (5490 - 5710 @ 160), (27), DFS, wmmrule=ETSI
+- # 60 GHz band channels 1-4, ref: Etsi En 302 567
++ (2400 - 2483.5 @ 40), (100 mW)
++ (5150 - 5250 @ 80), (200 mW), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
++ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
++ (5470 - 5725 @ 160), (500 mW), DFS, wmmrule=ETSI
++ # short range devices (ETSI EN 300 440-1)
++ (5725 - 5875 @ 80), (25 mW)
++ # 60 GHz band channels 1-4 (ETSI EN 302 567)
+ (57000 - 66000 @ 2160), (40)
+
+ country EG: DFS-ETSI
+@@ -430,17 +491,19 @@ country EG: DFS-ETSI
+ (5170 - 5250 @ 40), (20)
+ (5250 - 5330 @ 40), (20), DFS
+
+-# Source:
+-# Cuadro nacional de atribución de frecuencias (CNAF)
+-# https://avancedigital.gob.es/espectro/Paginas/cnaf.aspx
++# ES as part of EU/CEPT accepted decisions 2005/513/EC (5GHz RLAN, EN 301 893)
++# and 2006/771/EC (amended by 2008/432/EC, Short-Range Devices, EN 300 440)
++# EU decision 2005/513/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02005D0513-20070213
++# EU decision 2006/771/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02008D0432-20080611
++# ES: https://avancedigital.gob.es/espectro/Paginas/cnaf.aspx
+ country ES: DFS-ETSI
+ (2400 - 2483.5 @ 40), (100 mW)
+ (5150 - 5250 @ 80), (200 mW), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
+ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
+ (5470 - 5725 @ 160), (500 mW), DFS, wmmrule=ETSI
+- # Short Range Devices (SRD) (ETSI EN 300 440)
++ # short range devices (ETSI EN 300 440-1)
+ (5725 - 5875 @ 80), (25 mW)
+- # 60 GHz band channels 1-4, ref: Etsi En 302 567
++ # 60 GHz band channels 1-4 (ETSI EN 302 567)
+ (57000 - 66000 @ 2160), (40)
+
+ country ET: DFS-ETSI
+@@ -449,14 +512,18 @@ country ET: DFS-ETSI
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
++# FI as part of EU/CEPT accepted decisions 2005/513/EC (5GHz RLAN, EN 301 893)
++# and 2006/771/EC (amended by 2008/432/EC, Short-Range Devices, EN 300 440)
++# EU decision 2005/513/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02005D0513-20070213
++# EU decision 2006/771/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02008D0432-20080611
+ country FI: DFS-ETSI
+- (2400 - 2483.5 @ 40), (20)
+- (5150 - 5250 @ 80), (23), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
+- (5250 - 5350 @ 80), (20), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
+- (5470 - 5725 @ 160), (27), DFS, wmmrule=ETSI
++ (2400 - 2483.5 @ 40), (100 mW)
++ (5150 - 5250 @ 80), (200 mW), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
++ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
++ (5470 - 5725 @ 160), (500 mW), DFS, wmmrule=ETSI
+ # short range devices (ETSI EN 300 440-1)
+ (5725 - 5875 @ 80), (25 mW)
+- # 60 GHz band channels 1-4, ref: Etsi En 302 567
++ # 60 GHz band channels 1-4 (ETSI EN 302 567)
+ (57000 - 66000 @ 2160), (40)
+
+ country FM: DFS-FCC
+@@ -466,22 +533,34 @@ country FM: DFS-FCC
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
++# FR as part of EU/CEPT accepted decisions 2005/513/EC (5GHz RLAN, EN 301 893)
++# and 2006/771/EC (amended by 2008/432/EC, Short-Range Devices, EN 300 440)
++# EU decision 2005/513/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02005D0513-20070213
++# EU decision 2006/771/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02008D0432-20080611
+ country FR: DFS-ETSI
+- (2402 - 2482 @ 40), (20)
+- (5150 - 5250 @ 80), (23), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
+- (5250 - 5350 @ 80), (20), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
+- (5470 - 5725 @ 160), (27), DFS, wmmrule=ETSI
+- # short range devices (ETSI EN 300 440)
++ (2400 - 2483.5 @ 40), (100 mW)
++ (5150 - 5250 @ 80), (200 mW), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
++ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
++ (5470 - 5725 @ 160), (500 mW), DFS, wmmrule=ETSI
++ # short range devices (ETSI EN 300 440-1)
+ (5725 - 5875 @ 80), (25 mW)
+- # 60 GHz band channels 1-4, ref: Etsi En 302 567
++ # 60 GHz band channels 1-4 (ETSI EN 302 567)
+ (57000 - 66000 @ 2160), (40)
+
++# GB as part of EU/CEPT accepted decisions 2005/513/EC (5GHz RLAN, EN 301 893)
++# and 2006/771/EC (amended by 2008/432/EC, Short-Range Devices, EN 300 440)
++# EU decision 2005/513/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02005D0513-20070213
++# EU decision 2006/771/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02008D0432-20080611
++# GB: https://www.ofcom.org.uk/__data/assets/pdf_file/0019/136009/Ofcom-Information-Sheet-5-GHz-RLANs.pdf
++# GB: https://www.ofcom.org.uk/__data/assets/pdf_file/0028/84970/ir-2030.pdf
+ country GB: DFS-ETSI
+- (2402 - 2482 @ 40), (20)
+- (5170 - 5250 @ 80), (20), AUTO-BW, wmmrule=ETSI
+- (5250 - 5330 @ 80), (20), DFS, AUTO-BW, wmmrule=ETSI
+- (5490 - 5710 @ 160), (27), DFS, wmmrule=ETSI
+- # 60 GHz band channels 1-4, ref: Etsi En 302 567
++ (2400 - 2483.5 @ 40), (100 mW)
++ (5150 - 5250 @ 80), (200 mW), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
++ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
++ (5470 - 5725 @ 160), (500 mW), DFS, wmmrule=ETSI
++ # short range devices (ETSI EN 300 440-1)
++ (5725 - 5875 @ 80), (25 mW)
++ # 60 GHz band channels 1-4 (ETSI EN 302 567)
+ (57000 - 66000 @ 2160), (40)
+
+ country GD: DFS-FCC
+@@ -523,12 +602,20 @@ country GP: DFS-ETSI
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW, wmmrule=ETSI
+ (5490 - 5710 @ 160), (27), DFS, wmmrule=ETSI
+
++# GR as part of EU/CEPT accepted decisions 2005/513/EC (5GHz RLAN, EN 301 893)
++# and 2006/771/EC (amended by 2008/432/EC, Short-Range Devices, EN 300 440)
++# EU decision 2005/513/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02005D0513-20070213
++# EU decision 2006/771/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02008D0432-20080611
++# GR: https://www.eett.gr/opencms/export/sites/default/EETT_EN/Electronic_Communications/Radio_Communications/TelecommunicationEquipment/Radio_equipment_interface_requirement_2012.pdf
++# GR: https://www.eett.gr/opencms/export/sites/default/EETT_EN/Electronic_Communications/Radio_Communications/TelecommunicationEquipment/Radio_equipment_interface_requirement_107.pdf
+ country GR: DFS-ETSI
+- (2402 - 2482 @ 40), (20)
+- (5170 - 5250 @ 80), (20), AUTO-BW, wmmrule=ETSI
+- (5250 - 5330 @ 80), (20), DFS, AUTO-BW, wmmrule=ETSI
+- (5490 - 5710 @ 160), (27), DFS, wmmrule=ETSI
+- # 60 GHz band channels 1-4, ref: Etsi En 302 567
++ (2400 - 2483.5 @ 40), (100 mW)
++ (5150 - 5250 @ 80), (200 mW), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
++ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
++ (5470 - 5725 @ 160), (500 mW), DFS, wmmrule=ETSI
++ # short range devices (ETSI EN 300 440-1)
++ (5725 - 5875 @ 80), (25 mW)
++ # 60 GHz band channels 1-4 (ETSI EN 302 567)
+ (57000 - 66000 @ 2160), (40)
+
+ country GT: DFS-FCC
+@@ -563,11 +650,18 @@ country HN: DFS-FCC
+ (5735 - 5835 @ 80), (30)
+
+ country HR: DFS-ETSI
+- (2400 - 2483.5 @ 40), (20)
+- (5150 - 5250 @ 80), (23), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
+- (5250 - 5350 @ 80), (20), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
+- (5470 - 5725 @ 160), (27), DFS, wmmrule=ETSI
+- # 60 GHz band channels 1-4, ref: Etsi En 302 567
++# HR as part of EU/CEPT accepted decisions 2005/513/EC (5GHz RLAN, EN 301 893)
++# and 2006/771/EC (amended by 2008/432/EC, Short-Range Devices, EN 300 440)
++# EU decision 2005/513/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02005D0513-20070213
++# EU decision 2006/771/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02008D0432-20080611
++# HR: http://tablice.hakom.hr:8080/vis?lang=en
++ (2400 - 2483.5 @ 40), (100 mW)
++ (5150 - 5250 @ 80), (200 mW), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
++ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
++ (5470 - 5725 @ 160), (500 mW), DFS, wmmrule=ETSI
++ # short range devices (ETSI EN 300 440-1)
++ (5725 - 5875 @ 80), (25 mW)
++ # 60 GHz band channels 1-4 (ETSI EN 302 567)
+ (57000 - 66000 @ 2160), (40)
+
+ country HT: DFS-FCC
+@@ -577,37 +671,42 @@ country HT: DFS-FCC
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+-# http://stir.nmhh.hu/?oldal=dokumentumGeneralo&root_rendeletelem_id=3&hatalyos=1
+-# http://english.nmhh.hu/cikk/297/Eljarasi_tajekoztato_a_24_GHzes_es_az_5_GHzes_savban_mukodo_berendezesek_engedelyezeserol
+-# http://nmhh.hu/dokumentum/319/kis_hatotavolsagu_eszkozok_srdk.pdf
++# HU as part of EU/CEPT accepted decisions 2005/513/EC (5GHz RLAN, EN 301 893)
++# and 2006/771/EC (amended by 2008/432/EC, Short-Range Devices, EN 300 440)
++# EU decision 2005/513/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02005D0513-20070213
++# EU decision 2006/771/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02008D0432-20080611
++# HU: http://stir.nmhh.hu/?oldal=dokumentumGeneralo&root_rendeletelem_id=3&hatalyos=1
++# HU: http://english.nmhh.hu/cikk/297/Eljarasi_tajekoztato_a_24_GHzes_es_az_5_GHzes_savban_mukodo_berendezesek_engedelyezeserol
++# HU: http://nmhh.hu/dokumentum/319/kis_hatotavolsagu_eszkozok_srdk.pdf
+ country HU: DFS-ETSI
+- # ref: 2006/771/EK, (EU) 2017/1483, MSZ EN 300 328
+- # additionally: 100mW @ 10MHz channels, 50mW @ 5MHz (max. 10mW/MHz)
+- (2400 - 2483.5 @ 40), (20)
+- # ref: 2005/513/EK
+- # note: TPC not needed @ 5150-5250
+- (5150 - 5250 @ 80), (23), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
+- # note: max would be +3dB with TPC @ 5250-5725
+- (5250 - 5350 @ 80), (20), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
+- (5470 - 5725 @ 160), (27), DFS, wmmrule=ETSI
+- # "Short Range Devices (SRD)"
+- # ref: 2006/771/EK, (EU) 2017/1483, MSZ EN 300 440, MSZ EN 302 064
++ (2400 - 2483.5 @ 40), (100 mW)
++ (5150 - 5250 @ 80), (200 mW), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
++ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
++ (5470 - 5725 @ 160), (500 mW), DFS, wmmrule=ETSI
++ # short range devices (ETSI EN 300 440-1)
+ (5725 - 5875 @ 80), (25 mW)
+- # 60 GHz band channels 1-4, "Fixed outdoor installation not allowed"
+- # ref: 2006/771/EK, (EU) 2017/1483, MSZ EN 302 567
+- (57000 - 66000 @ 2160), (40), NO-OUTDOOR
++ # 60 GHz band channels 1-4 (ETSI EN 302 567)
++ (57000 - 66000 @ 2160), (40)
+
+ country ID: DFS-JP
+ # ref: http://www.postel.go.id/content/ID/regulasi/standardisasi/kepdir/bwa%205,8%20ghz.pdf
+ (2402 - 2482 @ 20), (20)
+ (5735 - 5815 @ 20), (23)
+
++# IE as part of EU/CEPT accepted decisions 2005/513/EC (5GHz RLAN, EN 301 893)
++# and 2006/771/EC (amended by 2008/432/EC, Short-Range Devices, EN 300 440)
++# EU decision 2005/513/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02005D0513-20070213
++# EU decision 2006/771/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02008D0432-20080611
++# IE: https://www.comreg.ie/publication-download/interface-requirements-for-radio-services-in-ireland
++# IE: https://www.comreg.ie/publication-download/permitted-short-range-devices-ireland
+ country IE: DFS-ETSI
+- (2402 - 2482 @ 40), (20)
+- (5170 - 5250 @ 80), (20), AUTO-BW, wmmrule=ETSI
+- (5250 - 5330 @ 80), (20), DFS, AUTO-BW, wmmrule=ETSI
+- (5490 - 5710 @ 160), (27), DFS, wmmrule=ETSI
+- # 60 GHz band channels 1-4, ref: Etsi En 302 567
++ (2400 - 2483.5 @ 40), (100 mW)
++ (5150 - 5250 @ 80), (200 mW), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
++ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
++ (5470 - 5725 @ 160), (500 mW), DFS, wmmrule=ETSI
++ # short range devices (ETSI EN 300 440-1)
++ (5725 - 5875 @ 80), (25 mW)
++ # 60 GHz band channels 1-4 (ETSI EN 302 567)
+ (57000 - 66000 @ 2160), (40)
+
+ country IL: DFS-ETSI
+@@ -626,20 +725,33 @@ country IR: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5735 - 5835 @ 80), (30)
+
++# IS as part of CEPT accepted decisions 2005/513/EC (5GHz RLAN, EN 301 893)
++# and 2006/771/EC (amended by 2008/432/EC, Short-Range Devices, EN 300 440)
++# EU decision 2005/513/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02005D0513-20070213
++# EU decision 2006/771/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02008D0432-20080611
++# IS: https://www.pfs.is/library/Skrar/Tidnir-og-taekni/MHZ_21022019.pdf
+ country IS: DFS-ETSI
+- (2402 - 2482 @ 40), (20)
+- (5170 - 5250 @ 80), (20), AUTO-BW, wmmrule=ETSI
+- (5250 - 5330 @ 80), (20), DFS, AUTO-BW, wmmrule=ETSI
+- (5490 - 5710 @ 160), (27), DFS, wmmrule=ETSI
+- # 60 GHz band channels 1-4, ref: Etsi En 302 567
++ (2400 - 2483.5 @ 40), (100 mW)
++ (5150 - 5250 @ 80), (200 mW), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
++ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
++ (5470 - 5725 @ 160), (500 mW), DFS, wmmrule=ETSI
++ # short range devices (ETSI EN 300 440-1)
++ (5725 - 5875 @ 80), (25 mW)
++ # 60 GHz band channels 1-4 (ETSI EN 302 567)
+ (57000 - 66000 @ 2160), (40)
+
++# IT as part of EU/CEPT accepted decisions 2005/513/EC (5GHz RLAN, EN 301 893)
++# and 2006/771/EC (amended by 2008/432/EC, Short-Range Devices, EN 300 440)
++# EU decision 2005/513/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02005D0513-20070213
++# EU decision 2006/771/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02008D0432-20080611
+ country IT: DFS-ETSI
+- (2402 - 2482 @ 40), (20)
+- (5170 - 5250 @ 80), (20), AUTO-BW, wmmrule=ETSI
+- (5250 - 5330 @ 80), (20), DFS, AUTO-BW, wmmrule=ETSI
+- (5490 - 5710 @ 160), (27), DFS, wmmrule=ETSI
+- # 60 GHz band channels 1-4, ref: Etsi En 302 567
++ (2400 - 2483.5 @ 40), (100 mW)
++ (5150 - 5250 @ 80), (200 mW), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
++ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
++ (5470 - 5725 @ 160), (500 mW), DFS, wmmrule=ETSI
++ # short range devices (ETSI EN 300 440-1)
++ (5725 - 5875 @ 80), (25 mW)
++ # 60 GHz band channels 1-4 (ETSI EN 302 567)
+ (57000 - 66000 @ 2160), (40)
+
+ country JM: DFS-FCC
+@@ -741,16 +853,22 @@ country LC: DFS-ETSI
+ (5490 - 5710 @ 160), (30), DFS
+ (5735 - 5815 @ 80), (30)
+
+-# Source:
+-# https://www.ofcomnet.ch/#/fatTable
+-# Note that the maximum transmitter power can be doubled for 5250-5710MHz if
+-# transmitter power control is in use: 5250-5330@23db, 5490-5710@30db
++# LI as part of CEPT accepted decisions 2005/513/EC (5GHz RLAN, EN 301 893)
++# and 2006/771/EC (amended by 2008/432/EC, Short-Range Devices, EN 300 440)
++# EU decision 2005/513/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02005D0513-20070213
++# EU decision 2006/771/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02008D0432-20080611
++# LI: https://www.ofcomnet.ch/api/rir/1010/05
++# LI: https://www.ofcomnet.ch/api/rir/1010/04
++# LI: https://www.ofcomnet.ch/api/rir/1008/12
++# LI: https://www.ofcomnet.ch/#/fatTable
+ country LI: DFS-ETSI
+- (2402 - 2482 @ 40), (20)
+- (5150 - 5250 @ 80), (23), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
+- (5250 - 5350 @ 80), (20), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
+- (5490 - 5710 @ 160), (27), DFS, wmmrule=ETSI
+- # 60 GHz band channels 1-4, ref: Etsi En 302 567
++ (2400 - 2483.5 @ 40), (100 mW)
++ (5150 - 5250 @ 80), (200 mW), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
++ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
++ (5470 - 5725 @ 160), (500 mW), DFS, wmmrule=ETSI
++ # short range devices (ETSI EN 300 440-1)
++ (5725 - 5875 @ 80), (25 mW)
++ # 60 GHz band channels 1-4 (ETSI EN 302 567)
+ (57000 - 66000 @ 2160), (40)
+
+ country LK: DFS-FCC
+@@ -768,28 +886,50 @@ country LS: DFS-ETSI
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
++# LT as part of EU/CEPT accepted decisions 2005/513/EC (5GHz RLAN, EN 301 893)
++# and 2006/771/EC (amended by 2008/432/EC, Short-Range Devices, EN 300 440)
++# EU decision 2005/513/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02005D0513-20070213
++# EU decision 2006/771/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02008D0432-20080611
++# LT: https://www.rrt.lt/en/radio-spectrum/frequency-management/ or direct link:
++# LT: https://www.e-tar.lt/portal/lt/legalAct/6e718fd037a011e69101aaab2992cbcd/dGRioCBBHb
+ country LT: DFS-ETSI
+- (2402 - 2482 @ 40), (20)
+- (5170 - 5250 @ 80), (20), AUTO-BW, wmmrule=ETSI
+- (5250 - 5330 @ 80), (20), DFS, AUTO-BW, wmmrule=ETSI
+- (5490 - 5710 @ 160), (27), DFS, wmmrule=ETSI
+- # 60 GHz band channels 1-4, ref: Etsi En 302 567
++ (2400 - 2483.5 @ 40), (100 mW)
++ (5150 - 5250 @ 80), (200 mW), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
++ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
++ (5470 - 5725 @ 160), (500 mW), DFS, wmmrule=ETSI
++ # short range devices (ETSI EN 300 440-1)
++ (5725 - 5875 @ 80), (25 mW)
++ # 60 GHz band channels 1-4 (ETSI EN 302 567)
+ (57000 - 66000 @ 2160), (40)
+
++# LU as part of EU/CEPT accepted decisions 2005/513/EC (5GHz RLAN, EN 301 893)
++# and 2006/771/EC (amended by 2008/432/EC, Short-Range Devices, EN 300 440)
++# EU decision 2005/513/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02005D0513-20070213
++# EU decision 2006/771/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02008D0432-20080611
++# LU: https://assets.ilr.lu/frequences/Documents/ILRLU-1723895916-183.pdf#search=en%20300%20440
+ country LU: DFS-ETSI
+- (2402 - 2482 @ 40), (20)
+- (5170 - 5250 @ 80), (20), AUTO-BW, wmmrule=ETSI
+- (5250 - 5330 @ 80), (20), DFS, AUTO-BW, wmmrule=ETSI
+- (5490 - 5710 @ 160), (27), DFS, wmmrule=ETSI
+- # 60 GHz band channels 1-4, ref: Etsi En 302 567
++ (2400 - 2483.5 @ 40), (100 mW)
++ (5150 - 5250 @ 80), (200 mW), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
++ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
++ (5470 - 5725 @ 160), (500 mW), DFS, wmmrule=ETSI
++ # short range devices (ETSI EN 300 440-1)
++ (5725 - 5875 @ 80), (25 mW)
++ # 60 GHz band channels 1-4 (ETSI EN 302 567)
+ (57000 - 66000 @ 2160), (40)
+
++# LV as part of EU/CEPT accepted decisions 2005/513/EC (5GHz RLAN, EN 301 893)
++# and 2006/771/EC (amended by 2008/432/EC, Short-Range Devices, EN 300 440)
++# EU decision 2005/513/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02005D0513-20070213
++# EU decision 2006/771/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02008D0432-20080611
++# LV: http://likumi.lv/doc.php?id=198903
+ country LV: DFS-ETSI
+- (2402 - 2482 @ 40), (20)
+- (5170 - 5250 @ 80), (20), AUTO-BW, wmmrule=ETSI
+- (5250 - 5330 @ 80), (20), DFS, AUTO-BW, wmmrule=ETSI
+- (5490 - 5710 @ 160), (27), DFS, wmmrule=ETSI
+- # 60 GHz band channels 1-4, ref: Etsi En 302 567
++ (2400 - 2483.5 @ 40), (100 mW)
++ (5150 - 5250 @ 80), (200 mW), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
++ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
++ (5470 - 5725 @ 160), (500 mW), DFS, wmmrule=ETSI
++ # short range devices (ETSI EN 300 440-1)
++ (5725 - 5875 @ 80), (25 mW)
++ # 60 GHz band channels 1-4 (ETSI EN 302 567)
+ (57000 - 66000 @ 2160), (40)
+
+ country MA: DFS-ETSI
+@@ -875,12 +1015,19 @@ country MR: DFS-ETSI
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
++# MT as part of EU/CEPT accepted decisions 2005/513/EC (5GHz RLAN, EN 301 893)
++# and 2006/771/EC (amended by 2008/432/EC, Short-Range Devices, EN 300 440)
++# EU decision 2005/513/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02005D0513-20070213
++# EU decision 2006/771/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02008D0432-20080611
++# MT: https://www.mca.org.mt/sites/default/files/NFP_edition%206-1.pdf
+ country MT: DFS-ETSI
+- (2402 - 2482 @ 40), (20)
+- (5170 - 5250 @ 80), (20), AUTO-BW, wmmrule=ETSI
+- (5250 - 5330 @ 80), (20), DFS, AUTO-BW, wmmrule=ETSI
+- (5490 - 5710 @ 160), (27), DFS, wmmrule=ETSI
+- # 60 GHz band channels 1-4, ref: Etsi En 302 567
++ (2400 - 2483.5 @ 40), (100 mW)
++ (5150 - 5250 @ 80), (200 mW), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
++ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
++ (5470 - 5725 @ 160), (500 mW), DFS, wmmrule=ETSI
++ # short range devices (ETSI EN 300 440-1)
++ (5725 - 5875 @ 80), (25 mW)
++ # 60 GHz band channels 1-4 (ETSI EN 302 567)
+ (57000 - 66000 @ 2160), (40)
+
+ country MU: DFS-FCC
+@@ -930,34 +1077,36 @@ country NI: DFS-FCC
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+-# Regulation on the use of frequency space without a license and
+-# without notification 2015
+-#
+-# http://wetten.overheid.nl/BWBR0036378/2015-03-05
+-
++# NL as part of EU/CEPT accepted decisions 2005/513/EC (5GHz RLAN, EN 301 893)
++# and 2006/771/EC (amended by 2008/432/EC, Short-Range Devices, EN 300 440)
++# EU decision 2005/513/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02005D0513-20070213
++# EU decision 2006/771/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02008D0432-20080611
++# NL: http://wetten.overheid.nl/BWBR0036378/2015-03-05
+ country NL: DFS-ETSI
+- (2402 - 2482 @ 40), (20)
+- (5170 - 5250 @ 80), (20), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
+- (5250 - 5330 @ 80), (20), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
+- (5490 - 5710 @ 160), (27), DFS, wmmrule=ETSI
++ (2400 - 2483.5 @ 40), (100 mW)
++ (5150 - 5250 @ 80), (200 mW), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
++ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
++ (5470 - 5725 @ 160), (500 mW), DFS, wmmrule=ETSI
+ # short range devices (ETSI EN 300 440-1)
+ (5725 - 5875 @ 80), (25 mW)
+- # 60 GHz band channels 1-4, ref: Etsi En 302 567
++ # 60 GHz band channels 1-4 (ETSI EN 302 567)
+ (57000 - 66000 @ 2160), (40)
+
+-# Data from http://www.lovdata.no/dokument/SF/forskrift/2012-01-19-77
+-# Power at 5250 - 5350 MHz, 5470 - 5725 MHz and 5815 – 5850 MHz can
+-# be doubled if TPC is implemented.
+-# Up to 2W (or 4W with TPC) is allowed in the 5725 – 5795 MHz band
+-# which has been merged with 5470 - 5725 MHz to allow wide channels
++# NO as part of CEPT accepted decisions 2005/513/EC (5GHz RLAN, EN 301 893)
++# and 2006/771/EC (amended by 2008/432/EC, Short-Range Devices, EN 300 440)
++# EU decision 2005/513/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02005D0513-20070213
++# EU decision 2006/771/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02008D0432-20080611
++# NO: https://eng.nkom.no/technical/temporary-licenses/mobile-videolink/wireless-cameras-mobile-video-links/_attachment/9947
++# NO: http://www.lovdata.no/dokument/SF/forskrift/2012-01-19-77
++# In addition to EU NO can use 5725–5795 MHz and 5815–5850 bands with limit of 4 W EIRP (with DFS and TPC)
+ country NO: DFS-ETSI
+ (2400 - 2483.5 @ 40), (100 mW)
+- (5150 - 5250 @ 80), (200 mW), AUTO-BW, wmmrule=ETSI
+- (5250 - 5350 @ 80), (100 mW), DFS, AUTO-BW, wmmrule=ETSI
+- (5470 - 5795 @ 160), (500 mW), DFS, wmmrule=ETSI
+- (5815 - 5850 @ 35), (2000 mW), DFS
+- (17100 - 17300 @ 200), (100 mW)
+- # 60 GHz band channels 1-4, ref: Etsi En 302 567
++ (5150 - 5250 @ 80), (200 mW), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
++ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
++ (5470 - 5725 @ 160), (500 mW), DFS, wmmrule=ETSI
++ # short range devices (ETSI EN 300 440-1)
++ (5725 - 5875 @ 80), (25 mW)
++ # 60 GHz band channels 1-4 (ETSI EN 302 567)
+ (57000 - 66000 @ 2160), (40)
+
+ country NP: DFS-JP
+@@ -1020,12 +1169,18 @@ country PK: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5735 - 5835 @ 80), (30)
+
++# PL as part of EU/CEPT accepted decisions 2005/513/EC (5GHz RLAN, EN 301 893)
++# and 2006/771/EC (amended by 2008/432/EC, Short-Range Devices, EN 300 440)
++# EU decision 2005/513/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02005D0513-20070213
++# EU decision 2006/771/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02008D0432-20080611
+ country PL: DFS-ETSI
+- (2402 - 2482 @ 40), (20)
+- (5170 - 5250 @ 80), (20), AUTO-BW, wmmrule=ETSI
+- (5250 - 5330 @ 80), (20), DFS, AUTO-BW, wmmrule=ETSI
+- (5490 - 5710 @ 160), (27), DFS, wmmrule=ETSI
+- # 60 GHz band channels 1-4, ref: Etsi En 302 567
++ (2400 - 2483.5 @ 40), (100 mW)
++ (5150 - 5250 @ 80), (200 mW), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
++ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
++ (5470 - 5725 @ 160), (500 mW), DFS, wmmrule=ETSI
++ # short range devices (ETSI EN 300 440-1)
++ (5725 - 5875 @ 80), (25 mW)
++ # 60 GHz band channels 1-4 (ETSI EN 302 567)
+ (57000 - 66000 @ 2160), (40)
+
+ country PM: DFS-ETSI
+@@ -1041,14 +1196,19 @@ country PR: DFS-FCC
+ (5490 - 5730 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
++# PT as part of EU/CEPT accepted decisions 2005/513/EC (5GHz RLAN, EN 301 893)
++# and 2006/771/EC (amended by 2008/432/EC, Short-Range Devices, EN 300 440)
++# EU decision 2005/513/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02005D0513-20070213
++# EU decision 2006/771/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02008D0432-20080611
++# PT: https://www.anacom.pt/render.jsp?categoryId=336334
+ country PT: DFS-ETSI
+- (2402 - 2482 @ 40), (20)
+- (5170 - 5250 @ 80), (20), AUTO-BW, wmmrule=ETSI
+- (5250 - 5330 @ 80), (20), DFS, AUTO-BW, wmmrule=ETSI
+- (5490 - 5710 @ 160), (27), DFS, wmmrule=ETSI
++ (2400 - 2483.5 @ 40), (100 mW)
++ (5150 - 5250 @ 80), (200 mW), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
++ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
++ (5470 - 5725 @ 160), (500 mW), DFS, wmmrule=ETSI
+ # short range devices (ETSI EN 300 440-1)
+ (5725 - 5875 @ 80), (25 mW)
+- # 60 GHz band channels 1-4, ref: Etsi En 302 567
++ # 60 GHz band channels 1-4 (ETSI EN 302 567)
+ (57000 - 66000 @ 2160), (40)
+
+ country PW: DFS-FCC
+@@ -1079,15 +1239,21 @@ country RE: DFS-ETSI
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW, wmmrule=ETSI
+ (5490 - 5710 @ 160), (27), DFS, wmmrule=ETSI
+
++# RO as part of EU/CEPT accepted decisions 2005/513/EC (5GHz RLAN, EN 301 893)
++# and 2006/771/EC (amended by 2008/432/EC, Short-Range Devices, EN 300 440)
++# EU decision 2005/513/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02005D0513-20070213
++# EU decision 2006/771/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02008D0432-20080611
++# RO: http://www.ancom.org.ro/en/uploads/links_files/ordin_262_2006.pdf
+ country RO: DFS-ETSI
+- (2402 - 2482 @ 40), (20)
+- (5170 - 5250 @ 80), (20), AUTO-BW, wmmrule=ETSI
+- (5250 - 5330 @ 80), (20), DFS, AUTO-BW, wmmrule=ETSI
+- (5490 - 5710 @ 160), (27), DFS, wmmrule=ETSI
+- # 60 GHz band channels 1-4, ref: Etsi En 302 567
++ (2400 - 2483.5 @ 40), (100 mW)
++ (5150 - 5250 @ 80), (200 mW), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
++ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
++ (5470 - 5725 @ 160), (500 mW), DFS, wmmrule=ETSI
++ # short range devices (ETSI EN 300 440-1)
++ (5725 - 5875 @ 80), (25 mW)
++ # 60 GHz band channels 1-4 (ETSI EN 302 567)
+ (57000 - 66000 @ 2160), (40)
+
+-
+ # Source:
+ # http://www.ratel.rs/upload/documents/Plan_namene/Plan_namene-sl_glasnik.pdf
+ country RS: DFS-ETSI
+@@ -1119,18 +1285,20 @@ country SA: DFS-ETSI
+ (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (27), DFS
+
+-# Source:
+-# https://pts.se/globalassets/startpage/dokument/legala-dokument/foreskrifter/radio/beslutade_ptsfs-2018-3-undantagsforeskrifter.pdf
++# SE as part of EU/CEPT accepted decisions 2005/513/EC (5GHz RLAN, EN 301 893)
++# and 2006/771/EC (amended by 2008/432/EC, Short-Range Devices, EN 300 440)
++# EU decision 2005/513/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02005D0513-20070213
++# EU decision 2006/771/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02008D0432-20080611
++# SE: https://pts.se/globalassets/startpage/dokument/legala-dokument/foreskrifter/radio/beslutade_ptsfs-2018-3-undantagsforeskrifter.pdf
+ country SE: DFS-ETSI
+- (2400 - 2483.5 @ 40), (20)
+- (5150 - 5250 @ 80), (23), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
+- # note: max would be +3dB with TPC @ 5250-5725
+- (5250 - 5350 @ 80), (20), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
+- (5470 - 5725 @ 160), (27), DFS, wmmrule=ETSI
+- # short range devices (ETSI EN 300 440)
++ (2400 - 2483.5 @ 40), (100 mW)
++ (5150 - 5250 @ 80), (200 mW), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
++ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
++ (5470 - 5725 @ 160), (500 mW), DFS, wmmrule=ETSI
++ # short range devices (ETSI EN 300 440-1)
+ (5725 - 5875 @ 80), (25 mW)
+- # 60 GHz band channels 1-4, ref: Etsi En 302 567
+- (57000 - 66000 @ 2160), (40), NO-OUTDOOR
++ # 60 GHz band channels 1-4 (ETSI EN 302 567)
++ (57000 - 66000 @ 2160), (40)
+
+ # Source
+ # https://www.imda.gov.sg/~/media/imda/files/regulation%20licensing%20and%20consultations/ict%20standards/telecommunication%20standards/radio-comms/imdatssrd.pdf?la=en
+@@ -1144,20 +1312,36 @@ country SG: DFS-FCC
+ # (5470 - 5725 @ 160), (30), DFS
+ (5725 - 5850 @ 80), (30)
+
++# SI as part of EU/CEPT accepted decisions 2005/513/EC (5GHz RLAN, EN 301 893)
++# and 2006/771/EC (amended by 2008/432/EC, Short-Range Devices, EN 300 440)
++# EU decision 2005/513/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02005D0513-20070213
++# EU decision 2006/771/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02008D0432-20080611
++# SI: https://www.akos-rs.si/bwa
+ country SI: DFS-ETSI
+- (2402 - 2482 @ 40), (20)
+- (5170 - 5250 @ 80), (20), AUTO-BW, wmmrule=ETSI
+- (5250 - 5330 @ 80), (20), DFS, AUTO-BW, wmmrule=ETSI
+- (5490 - 5710 @ 160), (27), DFS, wmmrule=ETSI
+- # 60 GHz band channels 1-4, ref: Etsi En 302 567
++ (2400 - 2483.5 @ 40), (100 mW)
++ (5150 - 5250 @ 80), (200 mW), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
++ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
++ (5470 - 5725 @ 160), (500 mW), DFS, wmmrule=ETSI
++ # short range devices (ETSI EN 300 440-1)
++ (5725 - 5875 @ 80), (25 mW)
++ # 60 GHz band channels 1-4 (ETSI EN 302 567)
+ (57000 - 66000 @ 2160), (40)
+
++# SK as part of EU/CEPT accepted decisions 2005/513/EC (5GHz RLAN, EN 301 893)
++# and 2006/771/EC (amended by 2008/432/EC, Short-Range Devices, EN 300 440)
++# EU decision 2005/513/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02005D0513-20070213
++# EU decision 2006/771/EC: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02008D0432-20080611
++# SK: https://www.teleoff.gov.sk/data/files/25911.pdf
++# SK: https://www.teleoff.gov.sk/data/files/41072.pdf
++# SK: https://www.teleoff.gov.sk/data/files/49125_vpr-01_2018-rusi-vpr-10_2014a21_2012-nespecifik-srd_021018.pdf
+ country SK: DFS-ETSI
+- (2402 - 2482 @ 40), (20)
+- (5170 - 5250 @ 80), (20), AUTO-BW, wmmrule=ETSI
+- (5250 - 5330 @ 80), (20), DFS, AUTO-BW, wmmrule=ETSI
+- (5490 - 5710 @ 160), (27), DFS, wmmrule=ETSI
+- # 60 GHz band channels 1-4, ref: Etsi En 302 567
++ (2400 - 2483.5 @ 40), (100 mW)
++ (5150 - 5250 @ 80), (200 mW), NO-OUTDOOR, AUTO-BW, wmmrule=ETSI
++ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR, DFS, AUTO-BW, wmmrule=ETSI
++ (5470 - 5725 @ 160), (500 mW), DFS, wmmrule=ETSI
++ # short range devices (ETSI EN 300 440-1)
++ (5725 - 5875 @ 80), (25 mW)
++ # 60 GHz band channels 1-4 (ETSI EN 302 567)
+ (57000 - 66000 @ 2160), (40)
+
+ # Source:
--- /dev/null
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Dmitry Tunin <hanipouspilot@gmail.com>
+Date: Sat, 24 Aug 2019 11:48:10 +0300
+Subject: [PATCH] wireless-regdb: Update regulatory rules for Russia (RU)
+
+Russian entry is incorrect. According to the last regulations
+document of Feb 29, 2016, 160 MHz channels and 802.11ad are allowed.
+
+http://rfs-rf.ru/upload/medialibrary/c1a/prilozhenie-1-k-resheniyu-gkrch-_-16_36_03.pdf
+
+Note that there was never a DFS requirement in Russia, but always was
+NO-OUTDOOR on 5GHz.
+Maximum power is 200mW that is ~23dBm on all 5GHz channels.
+Also Russia has never been regulated by ETSI.
+
+EIRP has been reduced by 4dBm because of TPC requirement.
+
+Signed-off-by: Dmitry Tunin <hanipouspilot@gmail.com>
+Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
+
+diff --git a/db.txt b/db.txt
+index f6b2f921416c..9c4b447536e4 100644
+--- a/db.txt
++++ b/db.txt
+@@ -1349,14 +1349,12 @@ country RS: DFS-ETSI
+ # 60 GHz band channels 1-4, ref: Etsi En 302 567
+ (57000 - 66000 @ 2160), (40)
+
+-country RU: DFS-ETSI
+- (2402 - 2482 @ 40), (20)
+- (5170 - 5250 @ 80), (20), AUTO-BW
+- (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+- (5650 - 5730 @ 80), (30), DFS
+- (5735 - 5835 @ 80), (30)
++country RU:
++ (2400 - 2483.5 @ 40), (20)
++ (5150 - 5350 @ 160), (20), NO-OUTDOOR
++ (5650 - 5850 @ 160), (20), NO-OUTDOOR
+ # 60 GHz band channels 1-4, ref: Changes to NLA 124_Order â„–129_22042015.pdf
+- (57000 - 66000 @ 2160), (40)
++ (57000 - 66000 @ 2160), (40), NO-OUTDOOR
+
+ country RW: DFS-FCC
+ (2402 - 2482 @ 40), (20)
PKG_NAME:=mac80211
-PKG_VERSION:=4.19.112-1
+PKG_VERSION:=4.19.120-1
PKG_RELEASE:=1
-PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v4.19.112/
-PKG_HASH:=e60a7aec902638c538b150d0d6165d866eb804845b97d7770acd653fd6a6b718
+PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v4.19.120/
+PKG_HASH:=2bafd75da301a30a5f2b98f433b6545d7b58c1fc3af15e9e9aa085df7f9db1d4
PKG_SOURCE:=backports-$(PKG_VERSION).tar.xz
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/backports-$(PKG_VERSION)
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
-@@ -3800,6 +3800,12 @@ out:
+@@ -3822,6 +3822,12 @@ out:
netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
struct net_device *dev)
{
atomic_t agg_queue_stop[IEEE80211_MAX_QUEUES];
-@@ -2046,6 +2048,7 @@ void ieee80211_txq_remove_vlan(struct ie
+@@ -2047,6 +2049,7 @@ void ieee80211_txq_remove_vlan(struct ie
struct ieee80211_sub_if_data *sdata);
void ieee80211_fill_txq_stats(struct cfg80211_txq_stats *txqstats,
struct txq_info *txqi);
(unsigned long) local);
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
-@@ -3485,13 +3485,19 @@ struct sk_buff *ieee80211_tx_dequeue(str
+@@ -3487,13 +3487,19 @@ struct sk_buff *ieee80211_tx_dequeue(str
struct ieee80211_tx_info *info;
struct ieee80211_tx_data tx;
ieee80211_tx_result r;
/* Make sure fragments stay together. */
skb = __skb_dequeue(&txqi->frags);
if (skb)
-@@ -3586,6 +3592,7 @@ begin:
+@@ -3606,6 +3612,7 @@ begin:
}
IEEE80211_SKB_CB(skb)->control.vif = vif;
--- /dev/null
+From: Markus Theil <markus.theil@tu-ilmenau.de>
+Date: Wed, 18 Dec 2019 15:27:36 +0100
+Subject: [PATCH] mac80211: fix tx status for no ack cases
+
+Before this patch, frames which where successfully transmitted without
+requiring acks where accounted as lost frames.
+
+Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de>
+Link: https://lore.kernel.org/r/20191218142736.15843-1-markus.theil@tu-ilmenau.de
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+---
+
+--- a/net/mac80211/status.c
++++ b/net/mac80211/status.c
+@@ -719,6 +719,7 @@ static void __ieee80211_tx_status(struct
+ int rates_idx;
+ bool send_to_cooked;
+ bool acked;
++ bool noack_success;
+ struct ieee80211_bar *bar;
+ int shift = 0;
+ int tid = IEEE80211_NUM_TIDS;
+@@ -736,6 +737,8 @@ static void __ieee80211_tx_status(struct
+ clear_sta_flag(sta, WLAN_STA_SP);
+
+ acked = !!(info->flags & IEEE80211_TX_STAT_ACK);
++ noack_success = !!(info->flags &
++ IEEE80211_TX_STAT_NOACK_TRANSMITTED);
+
+ /* mesh Peer Service Period support */
+ if (ieee80211_vif_is_mesh(&sta->sdata->vif) &&
+@@ -800,12 +803,12 @@ static void __ieee80211_tx_status(struct
+ ieee80211_handle_filtered_frame(local, sta, skb);
+ return;
+ } else {
+- if (!acked)
++ if (!acked && !noack_success)
+ sta->status_stats.retry_failed++;
+ sta->status_stats.retry_count += retry_count;
+
+ if (ieee80211_is_data_present(fc)) {
+- if (!acked)
++ if (!acked && !noack_success)
+ sta->status_stats.msdu_failed[tid]++;
+
+ sta->status_stats.msdu_retries[tid] +=
+@@ -826,7 +829,7 @@ static void __ieee80211_tx_status(struct
+ acked, info->status.tx_time);
+
+ if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS)) {
+- if (info->flags & IEEE80211_TX_STAT_ACK) {
++ if (acked) {
+ if (sta->status_stats.lost_packets)
+ sta->status_stats.lost_packets = 0;
+
+@@ -834,6 +837,8 @@ static void __ieee80211_tx_status(struct
+ if (test_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH))
+ sta->status_stats.last_tdls_pkt_time =
+ jiffies;
++ } else if (noack_success) {
++ /* nothing to do here, do not account as lost */
+ } else {
+ ieee80211_lost_packet(sta, info);
+ }
+@@ -959,7 +964,7 @@ void ieee80211_tx_status_ext(struct ieee
+
+ sta = container_of(pubsta, struct sta_info, sta);
+
+- if (!acked)
++ if (!acked && !noack_success)
+ sta->status_stats.retry_failed++;
+ sta->status_stats.retry_count += retry_count;
+
+@@ -974,6 +979,8 @@ void ieee80211_tx_status_ext(struct ieee
+ sta->status_stats.last_tdls_pkt_time = jiffies;
+ } else if (test_sta_flag(sta, WLAN_STA_PS_STA)) {
+ return;
++ } else if (noack_success) {
++ /* nothing to do here, do not account as lost */
+ } else {
+ ieee80211_lost_packet(sta, info);
+ }
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
-@@ -1244,7 +1244,7 @@ void ieee80211_sta_ps_deliver_wakeup(str
+@@ -1249,7 +1249,7 @@ void ieee80211_sta_ps_deliver_wakeup(str
if (!txq_has_queue(sta->sta.txq[i]))
continue;
return true;
}
-@@ -3600,6 +3604,60 @@ out:
+@@ -3620,6 +3624,60 @@ out:
}
EXPORT_SYMBOL(ieee80211_tx_dequeue);
+
void __ieee80211_subif_start_xmit(struct sk_buff *skb,
struct net_device *dev,
- u32 info_flags)
+ u32 info_flags,
}
for (i = 0; i < IEEE80211_NUM_TIDS; i++)
-@@ -1821,6 +1821,27 @@ void ieee80211_sta_set_buffered(struct i
+@@ -1826,6 +1826,27 @@ void ieee80211_sta_set_buffered(struct i
}
EXPORT_SYMBOL(ieee80211_sta_set_buffered);
int sta_info_move_state(struct sta_info *sta,
enum ieee80211_sta_state new_state)
{
-@@ -2187,6 +2208,23 @@ void sta_set_sinfo(struct sta_info *sta,
+@@ -2192,6 +2213,23 @@ void sta_set_sinfo(struct sta_info *sta,
sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED);
}
*/
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
-@@ -825,6 +825,12 @@ static void __ieee80211_tx_status(struct
+@@ -828,6 +828,12 @@ static void __ieee80211_tx_status(struct
ieee80211_sta_tx_notify(sta->sdata, (void *) skb->data,
acked, info->status.tx_time);
+ info->status.tx_time, 0);
+
if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS)) {
- if (info->flags & IEEE80211_TX_STAT_ACK) {
+ if (acked) {
if (sta->status_stats.lost_packets)
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
spin_lock_bh(&local->active_txq_lock[txqi->txq.ac]);
list_del_init(&txqi->schedule_order);
spin_unlock_bh(&local->active_txq_lock[txqi->txq.ac]);
-@@ -3611,11 +3614,28 @@ struct ieee80211_txq *ieee80211_next_txq
+@@ -3631,11 +3634,28 @@ struct ieee80211_txq *ieee80211_next_txq
lockdep_assert_held(&local->active_txq_lock[ac]);
return NULL;
list_del_init(&txqi->schedule_order);
-@@ -3633,12 +3653,74 @@ void ieee80211_return_txq(struct ieee802
+@@ -3653,12 +3673,74 @@ void ieee80211_return_txq(struct ieee802
lockdep_assert_held(&local->active_txq_lock[txq->ac]);
if (list_empty(&txqi->schedule_order) &&
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
-@@ -3673,6 +3673,19 @@ void ieee80211_return_txq(struct ieee802
+@@ -3693,6 +3693,19 @@ void ieee80211_return_txq(struct ieee802
}
EXPORT_SYMBOL(ieee80211_return_txq);
if (likely(sta)) {
if (!IS_ERR(sta))
tx->sta = sta;
-@@ -3523,6 +3523,7 @@ begin:
+@@ -3525,6 +3525,7 @@ begin:
tx.local = local;
tx.skb = skb;
tx.sdata = vif_to_sdata(info->control.vif);
+ tx.hdrlen = ieee80211_hdrlen(hdr->frame_control);
- if (txq->sta)
+ if (txq->sta) {
tx.sta = container_of(txq->sta, struct sta_info, sta);
-@@ -3549,7 +3550,7 @@ begin:
+@@ -3569,7 +3570,7 @@ begin:
if (tx.key &&
(tx.key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV))
ieee80211_xmit_fast_finish(sta->sdata, sta, pn_offs,
tx.key, skb);
-@@ -4006,6 +4007,7 @@ ieee80211_build_data_template(struct iee
+@@ -4028,6 +4029,7 @@ ieee80211_build_data_template(struct iee
hdr = (void *)skb->data;
tx.sta = sta_info_get(sdata, hdr->addr1);
tx.skb = skb;
if (skb->len < len_rthdr + hdrlen)
goto fail;
-@@ -2440,7 +2439,7 @@ static struct sk_buff *ieee80211_build_h
+@@ -2441,7 +2440,7 @@ static struct sk_buff *ieee80211_build_h
struct ieee80211_chanctx_conf *chanctx_conf;
struct ieee80211_sub_if_data *ap_sdata;
enum nl80211_band band;
if (IS_ERR(sta))
sta = NULL;
-@@ -2739,7 +2738,9 @@ static struct sk_buff *ieee80211_build_h
+@@ -2740,7 +2739,9 @@ static struct sk_buff *ieee80211_build_h
}
skb_pull(skb, skip_header_bytes);
/*
* So we need to modify the skb header and hence need a copy of
-@@ -2772,6 +2773,9 @@ static struct sk_buff *ieee80211_build_h
+@@ -2773,6 +2774,9 @@ static struct sk_buff *ieee80211_build_h
memcpy(skb_push(skb, meshhdrlen), &mesh_hdr, meshhdrlen);
#endif
if (ieee80211_is_data_qos(fc)) {
__le16 *qos_control;
-@@ -2947,6 +2951,8 @@ void ieee80211_check_fast_xmit(struct st
+@@ -2949,6 +2953,8 @@ void ieee80211_check_fast_xmit(struct st
fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
}
/* We store the key here so there's no point in using rcu_dereference()
* but that's fine because the code that changes the pointers will call
* this function after doing so. For a single CPU that would be enough,
-@@ -3523,7 +3529,7 @@ begin:
+@@ -3525,7 +3531,7 @@ begin:
tx.local = local;
tx.skb = skb;
tx.sdata = vif_to_sdata(info->control.vif);
- tx.hdrlen = ieee80211_hdrlen(hdr->frame_control);
+ tx.hdrlen = ieee80211_padded_hdrlen(hw, hdr->frame_control);
- if (txq->sta)
+ if (txq->sta) {
tx.sta = container_of(txq->sta, struct sta_info, sta);
-@@ -4007,7 +4013,7 @@ ieee80211_build_data_template(struct iee
+@@ -4029,7 +4035,7 @@ ieee80211_build_data_template(struct iee
hdr = (void *)skb->data;
tx.sta = sta_info_get(sdata, hdr->addr1);
tx.skb = skb;
* ieee80211_txq_may_transmit - check whether TXQ is allowed to transmit
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
-@@ -3617,16 +3617,17 @@ EXPORT_SYMBOL(ieee80211_tx_dequeue);
+@@ -3637,16 +3637,17 @@ EXPORT_SYMBOL(ieee80211_tx_dequeue);
struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac)
{
struct ieee80211_local *local = hw_to_local(hw);
if (txqi->txq.sta) {
struct sta_info *sta = container_of(txqi->txq.sta,
-@@ -3643,21 +3644,25 @@ struct ieee80211_txq *ieee80211_next_txq
+@@ -3663,21 +3664,25 @@ struct ieee80211_txq *ieee80211_next_txq
if (txqi->schedule_round == local->schedule_round[ac])
if (list_empty(&txqi->schedule_order) &&
(!skb_queue_empty(&txqi->frags) || txqi->tin.backlog_packets)) {
-@@ -3677,18 +3682,7 @@ void ieee80211_return_txq(struct ieee802
+@@ -3697,18 +3702,7 @@ void ieee80211_return_txq(struct ieee802
list_add_tail(&txqi->schedule_order,
&local->active_txqs[txq->ac]);
}
spin_unlock_bh(&local->active_txq_lock[txq->ac]);
}
EXPORT_SYMBOL(ieee80211_schedule_txq);
-@@ -3701,7 +3695,7 @@ bool ieee80211_txq_may_transmit(struct i
+@@ -3721,7 +3715,7 @@ bool ieee80211_txq_may_transmit(struct i
struct sta_info *sta;
u8 ac = txq->ac;
if (!txqi->txq.sta)
goto out;
-@@ -3731,34 +3725,27 @@ bool ieee80211_txq_may_transmit(struct i
+@@ -3751,34 +3745,27 @@ bool ieee80211_txq_may_transmit(struct i
sta->airtime[ac].deficit += sta->airtime_weight;
list_move_tail(&txqi->schedule_order, &local->active_txqs[ac]);
}
}
-@@ -1146,13 +1142,10 @@ int mesh_nexthop_resolve(struct ieee8021
+@@ -1147,13 +1143,10 @@ int mesh_nexthop_resolve(struct ieee8021
info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
ieee80211_set_qos_hdr(sdata, skb);
skb_queue_tail(&mpath->frame_queue, skb);
}
/**
-@@ -1172,13 +1165,10 @@ int mesh_nexthop_lookup(struct ieee80211
+@@ -1173,13 +1166,10 @@ int mesh_nexthop_lookup(struct ieee80211
struct sta_info *next_hop;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
u8 *target_addr = hdr->addr3;
if (time_after(jiffies,
mpath->exp_time -
-@@ -1193,12 +1183,10 @@ int mesh_nexthop_lookup(struct ieee80211
+@@ -1194,12 +1184,10 @@ int mesh_nexthop_lookup(struct ieee80211
memcpy(hdr->addr1, next_hop->sta.addr, ETH_ALEN);
memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN);
ieee80211_mps_set_frame_flags(sdata, next_hop, hdr);
schedule_and_wake_txq(local, txqi);
-@@ -3198,6 +3199,7 @@ static bool ieee80211_amsdu_aggregate(st
+@@ -3200,6 +3201,7 @@ static bool ieee80211_amsdu_aggregate(st
u8 max_subframes = sta->sta.max_amsdu_subframes;
int max_frags = local->hw.max_tx_fragments;
int max_amsdu_len = sta->sta.max_amsdu_len;
int orig_truesize;
__be16 len;
void *data;
-@@ -3220,6 +3222,8 @@ static bool ieee80211_amsdu_aggregate(st
+@@ -3222,6 +3224,8 @@ static bool ieee80211_amsdu_aggregate(st
max_amsdu_len = min_t(int, max_amsdu_len,
sta->sta.max_rc_amsdu_len);
spin_lock_bh(&fq->lock);
/* TODO: Ideally aggregation should be done on dequeue to remain
-@@ -3227,7 +3231,8 @@ static bool ieee80211_amsdu_aggregate(st
+@@ -3229,7 +3233,8 @@ static bool ieee80211_amsdu_aggregate(st
*/
tin = &txqi->tin;
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
-@@ -3505,6 +3505,7 @@ struct sk_buff *ieee80211_tx_dequeue(str
+@@ -3507,6 +3507,7 @@ struct sk_buff *ieee80211_tx_dequeue(str
ieee80211_tx_result r;
struct ieee80211_vif *vif = txq->vif;
spin_lock_bh(&fq->lock);
if (test_bit(IEEE80211_TXQ_STOP, &txqi->flags) ||
-@@ -3521,11 +3522,12 @@ struct sk_buff *ieee80211_tx_dequeue(str
+@@ -3523,11 +3524,12 @@ struct sk_buff *ieee80211_tx_dequeue(str
if (skb)
goto out;
hdr = (struct ieee80211_hdr *)skb->data;
info = IEEE80211_SKB_CB(skb);
-@@ -3571,8 +3573,11 @@ begin:
+@@ -3591,8 +3593,11 @@ begin:
skb = __skb_dequeue(&tx.skbs);
}
if (skb && skb_has_frag_list(skb) &&
-@@ -3611,6 +3616,7 @@ begin:
+@@ -3631,6 +3636,7 @@ begin:
}
IEEE80211_SKB_CB(skb)->control.vif = vif;
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
-@@ -1761,6 +1761,9 @@ void ieee80211_clear_fast_xmit(struct st
+@@ -1762,6 +1762,9 @@ void ieee80211_clear_fast_xmit(struct st
int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
const u8 *buf, size_t len,
const u8 *dest, __be16 proto, bool unencrypted);
ieee80211_free_txskb(&local->hw, skb);
return;
}
-@@ -2740,30 +2746,14 @@ static struct sk_buff *ieee80211_build_h
+@@ -2741,30 +2747,14 @@ static struct sk_buff *ieee80211_build_h
skb_pull(skb, skip_header_bytes);
padsize = ieee80211_hdr_padsize(&local->hw, hdrlen);
}
if (encaps_data)
-@@ -3375,7 +3365,6 @@ static bool ieee80211_xmit_fast(struct i
+@@ -3377,7 +3367,6 @@ static bool ieee80211_xmit_fast(struct i
struct ieee80211_local *local = sdata->local;
u16 ethertype = (skb->data[12] << 8) | skb->data[13];
int extra_head = fast_tx->hdr_len - (ETH_HLEN - 2);
struct ethhdr eth;
struct ieee80211_tx_info *info;
struct ieee80211_hdr *hdr = (void *)fast_tx->hdr;
-@@ -3427,10 +3416,7 @@ static bool ieee80211_xmit_fast(struct i
+@@ -3429,10 +3418,7 @@ static bool ieee80211_xmit_fast(struct i
* as the may-encrypt argument for the resize to not account for
* more room than we already have in 'extra_head'
*/
/**
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
-@@ -3653,8 +3653,9 @@ out:
+@@ -3673,8 +3673,9 @@ out:
}
EXPORT_SYMBOL(ieee80211_next_txq);
{
struct ieee80211_local *local = hw_to_local(hw);
struct txq_info *txqi = to_txq_info(txq);
-@@ -3662,7 +3663,8 @@ void ieee80211_schedule_txq(struct ieee8
+@@ -3682,7 +3683,8 @@ void ieee80211_schedule_txq(struct ieee8
spin_lock_bh(&local->active_txq_lock[txq->ac]);
if (list_empty(&txqi->schedule_order) &&
/* If airtime accounting is active, always enqueue STAs at the
* head of the list to ensure that they only get moved to the
* back by the airtime DRR scheduler once they have a negative
-@@ -3682,7 +3684,7 @@ void ieee80211_schedule_txq(struct ieee8
+@@ -3702,7 +3704,7 @@ void ieee80211_schedule_txq(struct ieee8
spin_unlock_bh(&local->active_txq_lock[txq->ac]);
}
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
-@@ -3751,6 +3751,7 @@ void __ieee80211_subif_start_xmit(struct
- u32 info_flags)
+@@ -3772,6 +3772,7 @@ void __ieee80211_subif_start_xmit(struct
+ u32 ctrl_flags)
{
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ struct ieee80211_local *local = sdata->local;
struct sta_info *sta;
struct sk_buff *next;
-@@ -3764,7 +3765,15 @@ void __ieee80211_subif_start_xmit(struct
+@@ -3785,7 +3786,15 @@ void __ieee80211_subif_start_xmit(struct
if (ieee80211_lookup_ra_sta(sdata, skb, &sta))
goto out_free;
}
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
-@@ -2070,7 +2070,8 @@ void ieee80211_send_auth(struct ieee8021
+@@ -2071,7 +2071,8 @@ void ieee80211_send_auth(struct ieee8021
const u8 *da, const u8 *key, u8 key_len, u8 key_idx,
u32 tx_flags);
void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
PKG_NAME:=json-c
PKG_VERSION:=0.12.1
-PKG_RELEASE:=3
+PKG_RELEASE:=3.1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-nodoc.tar.gz
PKG_SOURCE_URL:=https://s3.amazonaws.com/json-c_releases/releases/
--- a/configure.ac
+++ b/configure.ac
-@@ -43,12 +43,6 @@
+@@ -43,12 +43,6 @@ AC_FUNC_MEMCMP
AC_FUNC_MALLOC
AC_FUNC_REALLOC
AC_CHECK_FUNCS(strcasecmp strdup strerror snprintf vsnprintf vasprintf open vsyslog strncasecmp setlocale)
--- /dev/null
+From 77d935b7ae7871a1940cd827e850e6063044ec45 Mon Sep 17 00:00:00 2001
+From: Tobias Stoeckmann <tobias@stoeckmann.org>
+Date: Mon, 4 May 2020 19:46:45 +0200
+Subject: [PATCH 2/2] Prevent division by zero in linkhash.
+
+If a linkhash with a size of zero is created, then modulo operations
+are prone to division by zero operations.
+
+Purely protective measure against bad usage.
+---
+ linkhash.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/linkhash.c
++++ b/linkhash.c
+@@ -10,6 +10,7 @@
+ *
+ */
+
++#include <assert.h>
+ #include <stdio.h>
+ #include <string.h>
+ #include <stdlib.h>
+@@ -431,6 +432,8 @@ struct lh_table* lh_table_new(int size,
+ int i;
+ struct lh_table *t;
+
++ /* Allocate space for elements to avoid divisions by zero. */
++ assert(size > 0);
+ t = (struct lh_table*)calloc(1, sizeof(struct lh_table));
+ if(!t) lh_abort("lh_table_new: calloc failed\n");
+ t->count = 0;
--- /dev/null
+From d07b91014986900a3a75f306d302e13e005e9d67 Mon Sep 17 00:00:00 2001
+From: Tobias Stoeckmann <tobias@stoeckmann.org>
+Date: Mon, 4 May 2020 19:47:25 +0200
+Subject: [PATCH] Fix integer overflows.
+
+The data structures linkhash and printbuf are limited to 2 GB in size
+due to a signed integer being used to track their current size.
+
+If too much data is added, then size variable can overflow, which is
+an undefined behaviour in C programming language.
+
+Assuming that a signed int overflow just leads to a negative value,
+like it happens on many sytems (Linux i686/amd64 with gcc), then
+printbuf is vulnerable to an out of boundary write on 64 bit systems.
+---
+ linkhash.c | 7 +++++--
+ printbuf.c | 19 ++++++++++++++++---
+ 2 files changed, 21 insertions(+), 5 deletions(-)
+
+--- a/linkhash.c
++++ b/linkhash.c
+@@ -498,7 +498,12 @@ int lh_table_insert(struct lh_table *t,
+ unsigned long h, n;
+
+ t->inserts++;
+- if(t->count >= t->size * LH_LOAD_FACTOR) lh_table_resize(t, t->size * 2);
++ if(t->count >= t->size * LH_LOAD_FACTOR) {
++ /* Avoid signed integer overflow with large tables. */
++ int new_size = (t->size > INT_MAX / 2) ? INT_MAX : (t->size * 2);
++ if (t->size != INT_MAX)
++ lh_table_resize(t, new_size);
++ }
+
+ h = t->hash_fn(k);
+ n = h % t->size;
+--- a/printbuf.c
++++ b/printbuf.c
+@@ -15,6 +15,7 @@
+
+ #include "config.h"
+
++#include <limits.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+@@ -63,7 +64,16 @@ static int printbuf_extend(struct printb
+ if (p->size >= min_size)
+ return 0;
+
+- new_size = json_max(p->size * 2, min_size + 8);
++ /* Prevent signed integer overflows with large buffers. */
++ if (min_size > INT_MAX - 8)
++ return -1;
++ if (p->size > INT_MAX / 2)
++ new_size = min_size + 8;
++ else {
++ new_size = p->size * 2;
++ if (new_size < min_size + 8)
++ new_size = min_size + 8;
++ }
+ #ifdef PRINTBUF_DEBUG
+ MC_DEBUG("printbuf_memappend: realloc "
+ "bpos=%d min_size=%d old_size=%d new_size=%d\n",
+@@ -78,6 +88,9 @@ static int printbuf_extend(struct printb
+
+ int printbuf_memappend(struct printbuf *p, const char *buf, int size)
+ {
++ /* Prevent signed integer overflows with large buffers. */
++ if (size > INT_MAX - p->bpos - 1)
++ return -1;
+ if (p->size <= p->bpos + size + 1) {
+ if (printbuf_extend(p, p->bpos + size + 1) < 0)
+ return -1;
+@@ -94,6 +107,9 @@ int printbuf_memset(struct printbuf *pb,
+
+ if (offset == -1)
+ offset = pb->bpos;
++ /* Prevent signed integer overflows with large buffers. */
++ if (len > INT_MAX - offset)
++ return -1;
+ size_needed = offset + len;
+ if (pb->size < size_needed)
+ {
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
PKG_INSTALL:=1
-PKG_BUILD_PARALLEL:=1
+PKG_BUILD_PARALLEL:=0
PKG_LICENSE:=BSD-3-Clause
include $(INCLUDE_DIR)/package.mk
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=$(PROJECT_GIT)/libubox.git
-PKG_MIRROR_HASH:=c53aae4b8d5ec15625a4cbf7f37e6b62a6cb258ef0310c0f620064ba94589377
-PKG_SOURCE_DATE:=2020-01-20
-PKG_SOURCE_VERSION:=43a103ff17ee5872669f8712606578c90c14591d
+PKG_MIRROR_HASH:=3d58def8e415ceda8aacfd8453813d8bf2a05991c0df0c074744639ab04321ba
+PKG_SOURCE_DATE:=2020-05-25
+PKG_SOURCE_VERSION:=66195aee50424cbda0c2d858014e4cc58a2dc029
CMAKE_INSTALL:=1
PKG_LICENSE:=ISC
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=$(PROJECT_GIT)/uclient.git
-PKG_MIRROR_HASH:=b1127b28f98c9b45e046a76086b281b35c094fad1dc511ce0af095b733c86359
-PKG_SOURCE_DATE:=2019-05-30
-PKG_SOURCE_VERSION:=3b3e368dead01979e985cb167873fe9868b15d19
+PKG_MIRROR_HASH:=09857c0463c9ff56ae37fff4a73f58008ea2d844c909aab6669277afa8ef1e72
+PKG_SOURCE_DATE:=2020-06-17
+PKG_SOURCE_VERSION:=51e16ebffc740c6afcdd45aced20fc0354a502d7
CMAKE_INSTALL:=1
PKG_BUILD_DEPENDS:=ustream-ssl
include $(TOPDIR)/rules.mk
PKG_NAME:=ustream-ssl
-PKG_RELEASE:=2
+PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=$(PROJECT_GIT)/ustream-ssl.git
-PKG_SOURCE_DATE:=2019-11-05
-PKG_SOURCE_VERSION:=c9b6668215a27f2346d5eedd6f29cc720985b448
-PKG_MIRROR_HASH:=28b53b7e27b68d62c8fbbc57660d915bdcb6a464157c1930f16ed67e151398e9
+PKG_SOURCE_DATE:=2020-03-13
+PKG_SOURCE_VERSION:=40b563b1ea89dabb2b6cd90644908134a0c8eff2
+PKG_MIRROR_HASH:=db562c9919b4045c7b735c935b0a93983686b827ec4d537e8aa875c7e6df21a1
CMAKE_INSTALL:=1
PKG_LICENSE:=ISC
PKG_NAME:=qos-scripts
PKG_VERSION:=1.3.1
-PKG_RELEASE:=1
+PKG_RELEASE:=2
PKG_LICENSE:=GPL-2.0
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
[ -e /etc/config/network ] && {
# only try to parse network config on librecmc
- find_ifname() {(
- reset_cb
- include /lib/network
- scan_interfaces
- config_get "$1" ifname
- )}
+ . /lib/functions/network.sh
+
+ find_ifname() {
+ local ifname
+ if network_get_device ifname "$1"; then
+ echo "$ifname"
+ else
+ echo "Device for interface $1 not found." >&2
+ exit 1
+ fi
+ }
} || {
find_ifname() {
- echo "Interface not found."
+ echo "Interface not found." >&2
exit 1
}
}
config_get device "$1" device
[ -z "$device" ] && {
device="$(find_ifname $1)"
+ [ -z "$device" ] && exit 1
config_set "$1" device "$device"
}
}
PKG_NAME:=dnsmasq
PKG_UPSTREAM_VERSION:=2.80
PKG_VERSION:=$(subst test,~~test,$(subst rc,~rc,$(PKG_UPSTREAM_VERSION)))
-PKG_RELEASE:=16
+PKG_RELEASE:=16.1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_UPSTREAM_VERSION).tar.xz
PKG_SOURCE_URL:=http://thekelleys.org.uk/dnsmasq
xappend "--conf-file=$TRUSTANCHORSFILE"
xappend "--dnssec"
[ -x /etc/init.d/sysntpd ] && {
- /etc/init.d/sysntpd enabled
- [ "$?" -ne 0 -o "$(uci_get system.ntp.enabled)" = "1" ] && {
+ if /etc/init.d/sysntpd enabled || [ "$(uci_get system.ntp.enabled)" = "1" ] ; then
[ -f "$TIMEVALIDFILE" ] || xappend "--dnssec-no-timecheck"
- }
+ fi
}
append_bool "$cfg" dnsseccheckunsigned "--dnssec-check-unsigned"
}
include $(TOPDIR)/rules.mk
PKG_NAME:=hostapd
-PKG_RELEASE:=1
+PKG_RELEASE:=4
PKG_SOURCE_URL:=http://w1.fi/hostap.git
PKG_SOURCE_PROTO:=git
local ap_scan=
_w_mode="$mode"
- _w_modestr=
[[ "$mode" = adhoc ]] && {
ap_scan="ap_scan=2"
-
- _w_modestr="mode=1"
}
local country_str=
[[ "$_w_mode" = "adhoc" ]] && {
append network_data "mode=1" "$N$T"
[ -n "$freq" ] && wpa_supplicant_set_fixed_freq "$freq" "$htmode"
+ [ "$noscan" = "1" ] && append network_data "noscan=1" "$N$T"
scan_ssid="scan_ssid=0"
scan_ssid=""
}
- [ "$_w_mode" = "adhoc" -o "$_w_mode" = "mesh" ] && append network_data "$_w_modestr" "$N$T"
-
[ "$multi_ap" = 1 -a "$_w_mode" = "sta" ] && append network_data "multi_ap_backhaul_sta=1" "$N$T"
case "$auth_type" in
--- /dev/null
+From 1766e608ba1114220f3b3598e77aa53b50c38a6e Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <jouni@codeaurora.org>
+Date: Mon, 14 Oct 2019 19:27:47 +0300
+Subject: [PATCH] wolfSSL: Fix crypto_bignum_sub()
+
+The initial crypto wrapper implementation for wolfSSL seems to have
+included a copy-paste error in crypto_bignum_sub() implementation that
+was identical to crypto_bignum_add() while mp_sub() should have been
+used instead of mp_add().
+
+Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
+---
+ src/crypto/crypto_wolfssl.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/src/crypto/crypto_wolfssl.c
++++ b/src/crypto/crypto_wolfssl.c
+@@ -1151,7 +1151,7 @@ int crypto_bignum_sub(const struct crypt
+ if (TEST_FAIL())
+ return -1;
+
+- return mp_add((mp_int *) a, (mp_int *) b,
++ return mp_sub((mp_int *) a, (mp_int *) b,
+ (mp_int *) r) == MP_OKAY ? 0 : -1;
+ }
+
--- /dev/null
+From 6a28c4dbc102de3fed9db44637f47a10e7adfb78 Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <j@w1.fi>
+Date: Sat, 16 May 2020 21:01:51 +0300
+Subject: [PATCH 1/3] wolfssl: Fix compiler warnings on size_t printf format
+ use
+
+Signed-off-by: Jouni Malinen <j@w1.fi>
+---
+ src/crypto/tls_wolfssl.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/src/crypto/tls_wolfssl.c
++++ b/src/crypto/tls_wolfssl.c
+@@ -1741,7 +1741,7 @@ struct wpabuf * tls_connection_encrypt(v
+ if (!conn)
+ return NULL;
+
+- wpa_printf(MSG_DEBUG, "SSL: encrypt: %ld bytes", wpabuf_len(in_data));
++ wpa_printf(MSG_DEBUG, "SSL: encrypt: %zu bytes", wpabuf_len(in_data));
+
+ wolfssl_reset_out_data(&conn->output);
+
+@@ -1792,7 +1792,7 @@ struct wpabuf * tls_connection_decrypt(v
+ }
+ wpabuf_put(buf, res);
+
+- wpa_printf(MSG_DEBUG, "SSL: decrypt: %ld bytes", wpabuf_len(buf));
++ wpa_printf(MSG_DEBUG, "SSL: decrypt: %zu bytes", wpabuf_len(buf));
+
+ return buf;
+ }
--- /dev/null
+From eb595b3e3ab531645a5bde71cf6385335b7a4b95 Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <j@w1.fi>
+Date: Sat, 16 May 2020 21:02:17 +0300
+Subject: [PATCH 2/3] wolfssl: Fix crypto_bignum_rand() implementation
+
+The previous implementation used mp_rand_prime() to generate a random
+value in range 0..m. That is insanely slow way of generating a random
+value since mp_rand_prime() is for generating a random _prime_ which is
+not what is needed here. Replace that implementation with generationg of
+a random value in the requested range without doing any kind of prime
+number checks or loops to reject values that are not primes.
+
+This speeds up SAE and EAP-pwd routines by couple of orders of
+magnitude..
+
+Signed-off-by: Jouni Malinen <j@w1.fi>
+---
+ src/crypto/crypto_wolfssl.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+--- a/src/crypto/crypto_wolfssl.c
++++ b/src/crypto/crypto_wolfssl.c
+@@ -1084,19 +1084,21 @@ int crypto_bignum_rand(struct crypto_big
+ {
+ int ret = 0;
+ WC_RNG rng;
++ size_t len;
++ u8 *buf;
+
+ if (TEST_FAIL())
+ return -1;
+ if (wc_InitRng(&rng) != 0)
+ return -1;
+- if (mp_rand_prime((mp_int *) r,
+- (mp_count_bits((mp_int *) m) + 7) / 8 * 2,
+- &rng, NULL) != 0)
+- ret = -1;
+- if (ret == 0 &&
++ len = (mp_count_bits((mp_int *) m) + 7) / 8;
++ buf = os_malloc(len);
++ if (!buf || wc_RNG_GenerateBlock(&rng, buf, len) != 0 ||
++ mp_read_unsigned_bin((mp_int *) r, buf, len) != MP_OKAY ||
+ mp_mod((mp_int *) r, (mp_int *) m, (mp_int *) r) != 0)
+ ret = -1;
+ wc_FreeRng(&rng);
++ bin_clear_free(buf, len);
+ return ret;
+ }
+
--- /dev/null
+From 79488da576aeeb9400e1742fab7f463eed0fa7a1 Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <j@w1.fi>
+Date: Sat, 16 May 2020 21:07:45 +0300
+Subject: [PATCH 3/3] wolfssl: Do not hardcode include directory in
+ wpa_supplicant build
+
+This is not really appropriate for any kind of cross compilations and is
+not really needed in general since system specific values can be set in
+.config.
+
+Signed-off-by: Jouni Malinen <j@w1.fi>
+---
+ wpa_supplicant/Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/wpa_supplicant/Makefile
++++ b/wpa_supplicant/Makefile
+@@ -1086,7 +1086,7 @@ endif
+
+ ifeq ($(CONFIG_TLS), wolfssl)
+ ifdef TLS_FUNCS
+-CFLAGS += -DWOLFSSL_DER_LOAD -I/usr/local/include/wolfssl
++CFLAGS += -DWOLFSSL_DER_LOAD
+ OBJS += ../src/crypto/tls_wolfssl.o
+ endif
+ OBJS += ../src/crypto/crypto_wolfssl.o
--- a/wpa_supplicant/wpa_cli.c
+++ b/wpa_supplicant/wpa_cli.c
-@@ -26,6 +26,9 @@
+@@ -26,6 +26,15 @@
#include <cutils/properties.h>
#endif /* ANDROID */
+#ifndef CONFIG_P2P
+#define CONFIG_P2P
++#endif
++#ifndef CONFIG_AP
++#define CONFIG_AP
++#endif
++#ifndef CONFIG_MESH
++#define CONFIG_MESH
+#endif
static const char *const wpa_cli_version =
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=$(PROJECT_GIT)/odhcpd.git
-PKG_SOURCE_DATE:=2019-12-16
-PKG_SOURCE_VERSION:=e53fec897838aca411cb5fcdb9bf795e73414565
-PKG_MIRROR_HASH:=853dfcd464e2c6d09e37720421ebccb20581159763416fcd5ac8aad439e206b7
+PKG_SOURCE_DATE:=2020-05-03
+PKG_SOURCE_VERSION:=49e4949c6dee4a7e528e9bc51e9813228c3c16d8
+PKG_MIRROR_HASH:=5e23b60211a171d17d7015ce604b5fa128f0fbe4d7e7ddd48063b40590e17d4c
PKG_MAINTAINER:=Hans Dedecker <dedeckeh@gmail.com>
PKG_LICENSE:=GPL-2.0
PKG_SOURCE_URL=$(PROJECT_GIT)/relayd.git
PKG_SOURCE_PROTO:=git
-PKG_SOURCE_DATE:=2020-04-20
-PKG_SOURCE_VERSION:=ad0b25ad74345d367c62311e14b279f5ccb8ef13
-PKG_MIRROR_HASH:=e3e3598e5d37ea225db153288726036c5164bfc98e46d76ad8c317cc19b25a22
+PKG_SOURCE_DATE:=2020-04-25
+PKG_SOURCE_VERSION:=f4d759be54ceb37714e9a6ca320d5b50c95e9ce9
+PKG_MIRROR_HASH:=b1ff6e99072867be0975ba0be52ba9da3a876c8b8da893d68301e8238243a51e
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
PKG_LICENSE:=GPL-2.0
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=$(PROJECT_GIT)/uhttpd.git
-PKG_SOURCE_DATE:=2020-02-12
-PKG_SOURCE_VERSION:=2ee323c01079248baa9465969df9e25b5fb68cdf
-PKG_MIRROR_HASH:=ebec09286cf5f977cac893931a5a4f27ba891db88d5e44a9b0de9446ae431527
+PKG_SOURCE_DATE:=2020-03-13
+PKG_SOURCE_VERSION:=975dce23257e713e5e52eb87b194513eb81110a5
+PKG_MIRROR_HASH:=e5fba74f1519ce461a09bf7e52685d67e99c1157b050b4f91e718146e690e0c1
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
PKG_LICENSE:=ISC
PKG_SOURCE_URL=$(PROJECT_GIT)/mdnsd.git
PKG_SOURCE_PROTO:=git
-PKG_SOURCE_DATE:=2020-04-20
-PKG_SOURCE_VERSION:=e74a3f9883199e9db7220d52b78e5fbdb4441ca3
-PKG_MIRROR_HASH:=a54410a6407c3dad985c94e3ca6f9c2bb5786876c9545cf65a56e4dfc2b380ff
+PKG_SOURCE_DATE:=2020-04-25
+PKG_SOURCE_VERSION:=cdac0460ba50dc45735f0be2e19a5a8efc3dafe1
+PKG_MIRROR_HASH:=261cb929dfc03c1f293156cfdec8c2cd1541dcdc57ae42a323f9df5d26e6f7d2
PKG_MAINTAINER:=John Crispin <john@phrozen.org>
PKG_LICENSE:=LGPL-2.1
PKG_NAME:=wireguard
-PKG_VERSION:=1.0.20200330
+PKG_VERSION:=1.0.20200623
PKG_RELEASE:=1
PKG_SOURCE:=wireguard-linux-compat-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://git.zx2c4.com/wireguard-linux-compat/snapshot/
-PKG_HASH:=2d57b239605be2ee0e4c2da935ff1a23e9ed8bb3ee692e10ae032ae50f280bef
+PKG_HASH:=130937724515799edf05ff8216bc837df8acda879428f3a7f96a3287758f9445
PKG_LICENSE:=GPL-2.0
PKG_LICENSE_FILES:=COPYING
CATEGORY:=Network
SUBMENU:=VPN
URL:=https://www.wireguard.com
- MAINTAINER:=Jason A. Donenfeld <Jason@zx2c4.com>
+ MAINTAINER:=Jason A. Donenfeld <Jason@zx2c4.com> \
+ Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
+
endef
define Package/wireguard/Default/description
PKG_NAME:=curl
PKG_VERSION:=7.66.0
-PKG_RELEASE:=1
+PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://dl.uxnr.de/mirror/curl/ \
--- /dev/null
+From 1b71bc532bde8621fd3260843f8197182a467ff2 Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg <daniel@haxx.se>
+Date: Thu, 7 Nov 2019 10:13:01 +0100
+Subject: [PATCH] file: on Windows, refuse paths that start with \\
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+... as that might cause an unexpected SMB connection to a given host
+name.
+
+Reported-by: Fernando Muñoz
+CVE-2019-15601
+Bug: https://curl.haxx.se/docs/CVE-2019-15601.html
+
+Signed-off-by: Petr Å tetiar <ynezz@true.cz>
+---
+ lib/file.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/lib/file.c b/lib/file.c
+index d349cd9241cd..166931d7f1ba 100644
+--- a/lib/file.c
++++ b/lib/file.c
+@@ -136,7 +136,7 @@ static CURLcode file_connect(struct connectdata *conn, bool *done)
+ struct Curl_easy *data = conn->data;
+ char *real_path;
+ struct FILEPROTO *file = data->req.protop;
+- int fd;
++ int fd = -1;
+ #ifdef DOS_FILESYSTEM
+ size_t i;
+ char *actual_path;
+@@ -181,7 +181,9 @@ static CURLcode file_connect(struct connectdata *conn, bool *done)
+ return CURLE_URL_MALFORMAT;
+ }
+
+- fd = open_readonly(actual_path, O_RDONLY|O_BINARY);
++ if(strncmp("\\\\", actual_path, 2))
++ /* refuse to open path that starts with two backslashes */
++ fd = open_readonly(actual_path, O_RDONLY|O_BINARY);
+ file->path = actual_path;
+ #else
+ if(memchr(real_path, 0, real_path_len)) {
PKG_NAME:=dante
PKG_VERSION:=1.4.1
-PKG_RELEASE:=3
+PKG_RELEASE:=4
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=http://www.inet.no/dante/files/
--- /dev/null
+When compiled with glibc the config_scan.c wants to use the
+cpupolicy2numeric() function which is only available when
+HAVE_SCHED_SETSCHEDULER is set. It looks like the wrong define was used here.
+
+This fixes a build problem with glibc in combination with the force
+ac_cv_func_sched_setscheduler=no in the OpenWrt CONFIGURE_VARS.
+
+--- a/lib/config_scan.c
++++ b/lib/config_scan.c
+@@ -3891,7 +3891,7 @@ YY_RULE_SETUP
+ SERRX(0);
+
+ #else /* !SOCKS_CLIENT */
+-#if HAVE_SCHED_SETAFFINITY
++#if HAVE_SCHED_SETSCHEDULER
+
+ BEGIN(0);
+
+@@ -3899,9 +3899,9 @@ YY_RULE_SETUP
+ yyerrorx("unknown scheduling policy \"%s\"", yytext);
+
+ return SCHEDULEPOLICY;
+-#else /* !HAVE_SCHED_SETAFFINITY */
++#else /* !HAVE_SCHED_SETSCHEDULER */
+ yyerrorx("setting cpu scheduling policy is not supported on this platform");
+-#endif /* !HAVE_SCHED_SETAFFINITY */
++#endif /* !HAVE_SCHED_SETSCHEDULER */
+
+ #endif /* SOCKS_CLIENT */
+ }
+--- a/lib/config_scan.l
++++ b/lib/config_scan.l
+@@ -456,7 +456,7 @@ cpu {
+ SERRX(0);
+
+ #else /* !SOCKS_CLIENT */
+-#if HAVE_SCHED_SETAFFINITY
++#if HAVE_SCHED_SETSCHEDULER
+
+ BEGIN(0);
+
+@@ -464,9 +464,9 @@ cpu {
+ yyerrorx("unknown scheduling policy \"%s\"", yytext);
+
+ return SCHEDULEPOLICY;
+-#else /* !HAVE_SCHED_SETAFFINITY */
++#else /* !HAVE_SCHED_SETSCHEDULER */
+ yyerrorx("setting cpu scheduling policy is not supported on this platform");
+-#endif /* !HAVE_SCHED_SETAFFINITY */
++#endif /* !HAVE_SCHED_SETSCHEDULER */
+
+ #endif /* SOCKS_CLIENT */
+ }
PKG_NAME:=wireguard-tools
-PKG_VERSION:=1.0.20200319
+PKG_VERSION:=1.0.20200513
PKG_RELEASE:=1
PKG_SOURCE:=wireguard-tools-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://git.zx2c4.com/wireguard-tools/snapshot/
-PKG_HASH:=757ed31d4d48d5fd7853bfd9bfa6a3a1b53c24a94fe617439948784a2c0ed987
+PKG_HASH:=e73409a9fb8c90506db241d1e1a4e7372a60dbfa400e37f4ab2fd70a92ba495f
PKG_LICENSE:=GPL-2.0
PKG_LICENSE_FILES:=COPYING
include $(TOPDIR)/rules.mk
PKG_NAME:=ca-certificates
-PKG_VERSION:=20190110
-PKG_RELEASE:=2
+PKG_VERSION:=20200601
+PKG_RELEASE:=1
PKG_MAINTAINER:=
PKG_SOURCE:=$(PKG_NAME)_$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=http://ftp.debian.org/debian/pool/main/c/ca-certificates
-PKG_HASH:=ee4bf0f4c6398005f5b5ca4e0b87b82837ac5c3b0280a1cb3a63c47555c3a675
-
+PKG_HASH:=43766d5a436519503dfd65ab83488ae33ab4d4ca3d0993797b58c92eb9ed4e63
+PKG_BUILD_DIR:=$(BUILD_DIR)/work
PKG_INSTALL:=1
include $(INCLUDE_DIR)/package.mk
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=$(PROJECT_GIT)/fstools.git
-PKG_MIRROR_HASH:=ca3cc1d4a2de3014e63ec1fa223c5250116c6ae5cdc4e41b2053ca7b3c0a3d96
-PKG_SOURCE_DATE:=2020-01-18
-PKG_SOURCE_VERSION:=189b41b6b48786a51eb2b8bc450cb7d560f030f0
+PKG_MIRROR_HASH:=1b875efd7d675d74a56602f57dd27093e2feef8761ba28b567e2d2f43db14b48
+PKG_SOURCE_DATE:=2020-05-12
+PKG_SOURCE_VERSION:=84269037b75de93bdd4ea75b7f50ba77ba976377
CMAKE_INSTALL:=1
PKG_LICENSE:=GPL-2.0
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://git.openwrt.org/project/opkg-lede.git
-PKG_SOURCE_DATE:=2020-01-25
-PKG_SOURCE_VERSION:=c09fe2098718807ddbca13ee36e3e38801822946
-PKG_MIRROR_HASH:=b2fba519fb3bf2da2e325a33eee951b85c7c1886e48ebaac3892435a71ae33d5
+PKG_SOURCE_DATE:=2020-05-07
+PKG_SOURCE_VERSION:=f2166a89b7e96e2c60002959731eebc5f45fa318
+PKG_MIRROR_HASH:=67e55cd9fb93bb5b62e2c7b11946483b5570287bd1504aa2a3886d11f8b750b9
PKG_LICENSE:=GPL-2.0
PKG_LICENSE_FILES:=COPYING
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=$(PROJECT_GIT)/rpcd.git
-PKG_SOURCE_DATE:=2019-11-10
-PKG_SOURCE_VERSION:=77ad0de09247b9bdce50f4cecf3e5beb5636f57f
+PKG_SOURCE_DATE:=2020-05-26
+PKG_SOURCE_VERSION:=67c8a3fda26e441d3ec4a19f50ac72eca8deb14b
PKG_MAINTAINER:=Jo-Philipp Wich <jo@mein.io>
-PKG_MIRROR_HASH:=d36caff85bebbf7fb1b512359243bdbb7d9b16140e0d631afae9de2c3b8e4dff
+PKG_MIRROR_HASH:=cfe44e600093a424d1133b55a141c5becb708f48ee4fc8b7a98a82495ced7c72
PKG_LICENSE:=ISC
PKG_LICENSE_FILES:=
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=$(PROJECT_GIT)/ucert.git
-PKG_SOURCE_DATE:=2019-12-19
-PKG_SOURCE_VERSION:=14a279411cff06f9b1363711df4ec3b5db73f042
-PKG_MIRROR_HASH:=797f35138c6e1099a839e768d9e01db022223884d9e0a6d09965e625caf0ae79
+PKG_SOURCE_DATE:=2020-05-24
+PKG_SOURCE_VERSION:=00b921d80ac0dc47339305d803f865ff43c56d63
+PKG_MIRROR_HASH:=839fda1811a58a495ac7bbc41db75222dd5a15e4d72110ca6acc4cdad56908fe
CMAKE_INSTALL:=1
PKG_CHECK_FORMAT_SECURITY:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=$(PROJECT_GIT)/usign.git
-PKG_SOURCE_DATE:=2019-08-06
-PKG_SOURCE_VERSION:=5a52b379902471cef495687547c7b568142f66d2
-PKG_MIRROR_HASH:=9779f6d6718a7f7cd3e28aa7feefc9b3f4b0c7a85cb58ff18afbeb6b4372177a
+PKG_SOURCE_DATE:=2020-05-23
+PKG_SOURCE_VERSION:=f1f65026a94137c91b5466b149ef3ea3f20091e9
+PKG_MIRROR_HASH:=3f6569a5e63fdfd032976ac0f79d736d3935101ac1b97fb370514b013c5e6bb6
CMAKE_INSTALL:=1
PKG_CHECK_FORMAT_SECURITY:=1
PKG_USE_MIPS16:=0
},
{
.desc = "sw1",
- .type = EV_KEY,
+ .type = EV_SW,
.code = BTN_0,
.debounce_interval = TL_MR3020_KEYS_DEBOUNCE_INTERVAL,
.gpio = TL_MR3020_GPIO_BTN_SW1,
},
{
.desc = "sw2",
- .type = EV_KEY,
+ .type = EV_SW,
.code = BTN_1,
.debounce_interval = TL_MR3020_KEYS_DEBOUNCE_INTERVAL,
.gpio = TL_MR3020_GPIO_BTN_SW2,
#include "machtypes.h"
#define TL_WR802N_GPIO_LED_SYSTEM 13
-#define TL_WR802N_GPIO_BTN_RESET 11
+#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)
.code = KEY_RESTART,
.debounce_interval = TL_WR802N_KEYS_DEBOUNCE_INTERVAL,
.gpio = TL_WR802N_GPIO_BTN_RESET,
- .active_low = 0,
+ .active_low = 1,
}
};
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
-@@ -1299,4 +1299,12 @@ config GPIO_VIPERBOARD
+@@ -1300,4 +1300,12 @@ config GPIO_VIPERBOARD
endmenu
+#endif
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
-@@ -1251,7 +1251,6 @@ menu "SPI GPIO expanders"
+@@ -1252,7 +1252,6 @@ menu "SPI GPIO expanders"
config GPIO_74X164
tristate "74x164 serial-in/parallel-out 8-bits shift register"
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
-@@ -1306,4 +1306,9 @@ config GPIO_NXP_74HC153
+@@ -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.
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
-@@ -1152,6 +1152,9 @@ config MIPS_MSC
+@@ -1153,6 +1153,9 @@ config MIPS_MSC
config MIPS_NILE4
bool
for (p = *head; p; p = p->next) {
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
-@@ -465,7 +465,7 @@ static struct neighbour *ipv4_neigh_look
+@@ -466,7 +466,7 @@ static struct neighbour *ipv4_neigh_look
else if (skb)
pkey = &ip_hdr(skb)->daddr;
EXPORT_SYMBOL(xfrm_parse_spi);
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
-@@ -3874,14 +3874,16 @@ static bool tcp_parse_aligned_timestamp(
+@@ -3878,14 +3878,16 @@ static bool tcp_parse_aligned_timestamp(
{
const __be32 *ptr = (const __be32 *)(th + 1);
* No flags defined yet.
--- a/net/core/utils.c
+++ b/net/core/utils.c
-@@ -424,8 +424,14 @@ void inet_proto_csum_replace16(__sum16 *
+@@ -441,8 +441,14 @@ void inet_proto_csum_replace16(__sum16 *
bool pseudohdr)
{
__be32 diff[] = {
read-only;
};
};
+
+&ath9k1 {
+ /* The original WNDR3700(v1) variant have four antennae dedicated
+ * to the 5GHz radio as well. Again, two antennae are available for
+ * each chain to switch between. The following configuration is the
+ * default setting which taken from the vendor's wifi
+ * code for that radio.
+ *
+ * All possible options [GPIO6,GPIO7,GPIO8,GPIO9]:
+ * [0,1,0,1], [0,1,1,0], [1,0,0,1], [1,0,1,0]
+ */
+ antenna-demux {
+ gpio-hog;
+ line-name = "fixed antenna group 2";
+ gpios = <6 GPIO_ACTIVE_LOW>,
+ <7 GPIO_ACTIVE_HIGH>,
+ <8 GPIO_ACTIVE_HIGH>,
+ <9 GPIO_ACTIVE_LOW>;
+ output-high;
+ };
+};
qca,no-eeprom;
#gpio-cells = <2>;
gpio-controller;
+
+ /* all WNDR3700 variants have four antennae dedicated
+ * to the 2.4GHz radio. Two antennae are available for
+ * each chain. The following configuration is the
+ * default setting which taken from the vendor's wifi
+ * code for that radio.
+ *
+ * All possible options [GPIO6,GPIO7,GPIO8,GPIO9]:
+ * [0,1,0,1], [0,1,1,0], [1,0,0,1], [1,0,1,0]
+ */
+ antenna-demux {
+ gpio-hog;
+ line-name = "fixed antenna group 1";
+ gpios = <6 GPIO_ACTIVE_LOW>,
+ <7 GPIO_ACTIVE_HIGH>,
+ <8 GPIO_ACTIVE_LOW>,
+ <9 GPIO_ACTIVE_HIGH>;
+ output-high;
+ };
};
ath9k1: wifi@0,12 {
compatible = "tplink,tl-mr3040-v2", "qca,ar9331";
aliases {
+ serial0 = &uart;
led-boot = &led_lan;
led-failsafe = &led_lan;
};
xip_enable(map, chip, adr);
op_done:
if (mode == FL_OTP_WRITE)
-@@ -2236,7 +2238,6 @@ static int cfi_amdstd_panic_write(struct
+@@ -2240,7 +2242,6 @@ static int cfi_amdstd_panic_write(struct
return 0;
}
/*
* Handle devices with one erase region, that only implement
* the chip erase command.
-@@ -2304,7 +2305,7 @@ static int __xipram do_erase_chip(struct
+@@ -2308,7 +2309,7 @@ static int __xipram do_erase_chip(struct
}
if (chip_good(map, adr, map_word_ff(map)))
if (time_after(jiffies, timeo)) {
printk(KERN_WARNING "MTD %s(): software timeout\n",
-@@ -2328,6 +2329,7 @@ static int __xipram do_erase_chip(struct
+@@ -2332,6 +2333,7 @@ static int __xipram do_erase_chip(struct
}
}
chip->state = FL_READY;
xip_enable(map, chip, adr);
DISABLE_VPP(map);
-@@ -2401,7 +2403,7 @@ static int __xipram do_erase_oneblock(st
+@@ -2405,7 +2407,7 @@ static int __xipram do_erase_oneblock(st
if (chip_good(map, adr, map_word_ff(map))) {
xip_enable(map, chip, adr);
}
if (time_after(jiffies, timeo)) {
-@@ -2427,6 +2429,7 @@ static int __xipram do_erase_oneblock(st
+@@ -2431,6 +2433,7 @@ static int __xipram do_erase_oneblock(st
}
}
#include <linux/uaccess.h>
#include <linux/ipv6.h>
#include <linux/icmpv6.h>
-@@ -820,10 +821,10 @@ static void tcp_v6_send_response(const s
+@@ -819,10 +820,10 @@ static void tcp_v6_send_response(const s
topt = (__be32 *)(t1 + 1);
if (tsecr) {
for (p = *head; p; p = p->next) {
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
-@@ -466,7 +466,7 @@ static struct neighbour *ipv4_neigh_look
+@@ -464,7 +464,7 @@ static struct neighbour *ipv4_neigh_look
else if (skb)
pkey = &ip_hdr(skb)->daddr;
rwlock_t sk_callback_lock;
--- a/net/core/sock.c
+++ b/net/core/sock.c
-@@ -2745,6 +2745,7 @@ void sock_init_data(struct socket *sock,
+@@ -2748,6 +2748,7 @@ void sock_init_data(struct socket *sock,
sk->sk_max_pacing_rate = ~0U;
sk->sk_pacing_rate = ~0U;
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
-@@ -1981,7 +1981,8 @@ static const struct usb_device_id option
+@@ -1987,7 +1987,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) },
--- /dev/null
+From dda9f4b9cac6bdd2a96253b4444d7a6ce5132edb Mon Sep 17 00:00:00 2001
+From: Chao Yu <yuchao0@huawei.com>
+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 <yuchao0@huawei.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+---
+ 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;
#define INADDR_ANY ((unsigned long int) 0x00000000)
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
-@@ -929,7 +929,7 @@ static int inet_abc_len(__be32 addr)
+@@ -935,7 +935,7 @@ static int inet_abc_len(__be32 addr)
{
int rc = -1; /* Something else, probably a multicast. */
rc = 0;
else {
__u32 haddr = ntohl(addr);
-@@ -940,6 +940,8 @@ static int inet_abc_len(__be32 addr)
+@@ -946,6 +946,8 @@ static int inet_abc_len(__be32 addr)
rc = 16;
else if (IN_CLASSC(haddr))
rc = 24;
--- a/net/batman-adv/bat_iv_ogm.c
+++ b/net/batman-adv/bat_iv_ogm.c
-@@ -51,6 +51,7 @@
+@@ -52,6 +52,7 @@
#include <linux/workqueue.h>
#include <net/genetlink.h>
#include <net/netlink.h>
#include <uapi/linux/batman_adv.h>
#include "bat_algo.h"
-@@ -62,7 +63,6 @@
+@@ -63,7 +64,6 @@
#include "netlink.h"
#include "network-coding.h"
#include "originator.h"
#include "translation-table.h"
--- a/net/batman-adv/bat_v.c
+++ b/net/batman-adv/bat_v.c
-@@ -37,6 +37,7 @@
+@@ -36,6 +36,7 @@
#include <linux/workqueue.h>
#include <net/genetlink.h>
#include <net/netlink.h>
#include <uapi/linux/batman_adv.h>
#include "bat_algo.h"
-@@ -49,7 +50,6 @@
+@@ -48,7 +49,6 @@
#include "log.h"
#include "netlink.h"
#include "originator.h"
--- a/net/batman-adv/bat_v_ogm.c
+++ b/net/batman-adv/bat_v_ogm.c
-@@ -38,13 +38,13 @@
+@@ -40,13 +40,13 @@
#include <linux/string.h>
#include <linux/types.h>
#include <linux/workqueue.h>
/**
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
-@@ -36,6 +36,7 @@
+@@ -37,6 +37,7 @@
#include <linux/spinlock.h>
#include <net/net_namespace.h>
#include <net/rtnetlink.h>
#include "bat_v.h"
#include "bridge_loop_avoidance.h"
-@@ -44,7 +45,6 @@
+@@ -45,7 +46,6 @@
#include "gateway_client.h"
#include "log.h"
#include "originator.h"
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
-@@ -34,10 +34,9 @@
+@@ -35,10 +35,9 @@
#include <linux/types.h>
#include <linux/wait.h>
#include <linux/workqueue.h>
+
int ip6_dst_lookup(struct net *net, struct sock *sk, struct dst_entry **dst,
struct flowi6 *fl6);
- struct dst_entry *ip6_dst_lookup_flow(const struct sock *sk, 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
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
-@@ -252,4 +252,26 @@ static inline bool rt6_duplicate_nexthop
+@@ -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);
}
-
int ip6_dst_lookup(struct net *net, struct sock *sk, struct dst_entry **dst,
struct flowi6 *fl6);
- struct dst_entry *ip6_dst_lookup_flow(const struct sock *sk, 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
+++ /dev/null
-From 82afdcd4ec3c8ca6551cbf7c43c09e2fd240487a Mon Sep 17 00:00:00 2001
-From: Hangbin Liu <liuhangbin@gmail.com>
-Date: Tue, 10 Mar 2020 15:27:37 +0800
-Subject: [PATCH] ipv6/addrconf: call ipv6_mc_up() for non-Ethernet interface
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Rafał found an issue that for non-Ethernet interface, if we down and up
-frequently, the memory will be consumed slowly.
-
-The reason is we add allnodes/allrouters addressed in multicast list in
-ipv6_add_dev(). When link down, we call ipv6_mc_down(), store all multicast
-addresses via mld_add_delrec(). But when link up, we don't call ipv6_mc_up()
-for non-Ethernet interface to remove the addresses. This makes idev->mc_tomb
-getting bigger and bigger. The call stack looks like:
-
-addrconf_notify(NETDEV_REGISTER)
- ipv6_add_dev
- ipv6_dev_mc_inc(ff01::1)
- ipv6_dev_mc_inc(ff02::1)
- ipv6_dev_mc_inc(ff02::2)
-
-addrconf_notify(NETDEV_UP)
- addrconf_dev_config
- /* Alas, we support only Ethernet autoconfiguration. */
- return;
-
-addrconf_notify(NETDEV_DOWN)
- addrconf_ifdown
- ipv6_mc_down
- igmp6_group_dropped(ff02::2)
- mld_add_delrec(ff02::2)
- igmp6_group_dropped(ff02::1)
- igmp6_group_dropped(ff01::1)
-
-After investigating, I can't found a rule to disable multicast on
-non-Ethernet interface. In RFC2460, the link could be Ethernet, PPP, ATM,
-tunnels, etc. In IPv4, it doesn't check the dev type when calls ip_mc_up()
-in inetdev_event(). Even for IPv6, we don't check the dev type and call
-ipv6_add_dev(), ipv6_dev_mc_inc() after register device.
-
-So I think it's OK to fix this memory consumer by calling ipv6_mc_up() for
-non-Ethernet interface.
-
-v2: Also check IFF_MULTICAST flag to make sure the interface supports
- multicast
-
-Reported-by: Rafał Miłecki <zajec5@gmail.com>
-Tested-by: Rafał Miłecki <zajec5@gmail.com>
-Fixes: 74235a25c673 ("[IPV6] addrconf: Fix IPv6 on tuntap tunnels")
-Fixes: 1666d49e1d41 ("mld: do not remove mld souce list info when set link down")
-Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- net/ipv6/addrconf.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/net/ipv6/addrconf.c
-+++ b/net/ipv6/addrconf.c
-@@ -3223,6 +3223,10 @@ static void addrconf_dev_config(struct n
- (dev->type != ARPHRD_TUNNEL) &&
- (dev->type != ARPHRD_NONE)) {
- /* Alas, we support only Ethernet autoconfiguration. */
-+ idev = __in6_dev_get(dev);
-+ if (!IS_ERR_OR_NULL(idev) && dev->flags & IFF_UP &&
-+ dev->flags & IFF_MULTICAST)
-+ ipv6_mc_up(idev);
- return;
- }
-
--- a/Makefile
+++ b/Makefile
-@@ -1252,7 +1252,6 @@ all: modules
+@@ -1260,7 +1260,6 @@ endif
PHONY += modules
modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux) modules.builtin
@$(kecho) ' Building modules, stage 2.';
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
-@@ -1281,7 +1280,6 @@ _modinst_:
+@@ -1289,7 +1288,6 @@ _modinst_:
rm -f $(MODLIB)/build ; \
ln -s $(CURDIR) $(MODLIB)/build ; \
fi
# 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)
-@@ -789,11 +794,6 @@ ifdef CONFIG_DEBUG_SECTION_MISMATCH
+@@ -779,11 +784,6 @@ ifdef CONFIG_DEBUG_SECTION_MISMATCH
KBUILD_CFLAGS += $(call cc-option, -fno-inline-functions-called-once)
endif
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
-@@ -547,6 +547,12 @@ struct phy_driver {
+@@ -549,6 +549,12 @@ struct phy_driver {
/* Determines the negotiated speed and duplex */
int (*read_status)(struct phy_device *phydev);
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
-@@ -1462,6 +1462,9 @@ int genphy_update_link(struct phy_device
+@@ -1466,6 +1466,9 @@ int genphy_update_link(struct phy_device
{
int status;
u64 res;
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
-@@ -420,6 +420,7 @@ config INET_XFRM_MODE_BEET
+@@ -421,6 +421,7 @@ config INET_XFRM_MODE_BEET
config INET_DIAG
tristate "INET: socket monitoring interface"
return -ENOMEM;
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
-@@ -2783,6 +2783,8 @@ static const struct file_operations proc
+@@ -2798,6 +2798,8 @@ static const struct file_operations proc
static int __init proc_vmalloc_init(void)
{
--- a/net/core/sock.c
+++ b/net/core/sock.c
-@@ -3384,6 +3384,8 @@ static __net_initdata struct pernet_oper
+@@ -3387,6 +3387,8 @@ static __net_initdata struct pernet_oper
static int __init proto_init(void)
{
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
-@@ -2740,10 +2740,12 @@ static const struct file_operations fib_
+@@ -2743,10 +2743,12 @@ static const struct file_operations fib_
int __net_init fib_proc_init(struct net *net)
{
&fib_triestat_fops))
goto out2;
-@@ -2753,17 +2755,21 @@ int __net_init fib_proc_init(struct net
+@@ -2756,17 +2758,21 @@ int __net_init fib_proc_init(struct net
return 0;
out3:
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
-@@ -428,6 +428,9 @@ static struct pernet_operations ip_rt_pr
+@@ -426,6 +426,9 @@ static struct pernet_operations ip_rt_pr
static int __init ip_rt_proc_init(void)
{
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
-@@ -6145,7 +6145,7 @@ static void __ref alloc_node_mem_map(str
+@@ -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)
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
-@@ -5082,7 +5082,7 @@ static bool e1000e_has_link(struct e1000
+@@ -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
* for copper adapters ONLY
*/
switch (hw->phy.media_type) {
-@@ -5100,7 +5100,7 @@ static bool e1000e_has_link(struct e1000
+@@ -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);
-From: Felix Fietkau <nbd@nbd.name>
-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 <nbd@nbd.name>
----
- Makefile | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
--- a/Makefile
+++ b/Makefile
-@@ -656,12 +656,12 @@ KBUILD_CFLAGS += $(call cc-disable-warni
+@@ -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 $(call cc-disable-warning,maybe-uninitialized,)
-+KBUILD_CFLAGS += -Os $(call cc-disable-warning,maybe-uninitialized,) $(EXTRA_OPTIMIZATION)
- else
- ifdef CONFIG_PROFILE_ALL_BRANCHES
--KBUILD_CFLAGS += -O2 $(call cc-disable-warning,maybe-uninitialized,)
-+KBUILD_CFLAGS += -O2 $(call cc-disable-warning,maybe-uninitialized,) $(EXTRA_OPTIMIZATION)
+-KBUILD_CFLAGS += -Os
++KBUILD_CFLAGS += -Os $(EXTRA_OPTIMIZATION)
else
-KBUILD_CFLAGS += -O2
-+KBUILD_CFLAGS += -O2 -fno-reorder-blocks -fno-tree-ch $(EXTRA_OPTIMIZATION)
- endif
++KBUILD_CFLAGS += -O2 $(EXTRA_OPTIMIZATION)
endif
+ # Tell gcc to never replace conditional load with a non-conditional one
select OF
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
-@@ -315,7 +315,7 @@ OBJCOPYFLAGS += --remove-section=.regin
+@@ -326,7 +326,7 @@ OBJCOPYFLAGS += --remove-section=.regin
head-y := arch/mips/kernel/head.o
libs-y += arch/mips/lib/
;----------------------------------------------------------------
--- a/arch/arc/kernel/setup.c
+++ b/arch/arc/kernel/setup.c
-@@ -437,6 +437,8 @@ static inline bool uboot_arg_invalid(uns
+@@ -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
void __init handle_uboot_args(void)
{
bool use_embedded_dtb = true;
-@@ -477,7 +479,7 @@ ignore_uboot_args:
+@@ -478,7 +480,7 @@ ignore_uboot_args:
#endif
if (use_embedded_dtb) {
if (!net_eq(dev_net(dev), sock_net(sk)))
goto drop;
-@@ -2213,12 +2215,12 @@ static int tpacket_rcv(struct sk_buff *s
+@@ -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 (!net_eq(dev_net(dev), sock_net(sk)))
goto drop;
-@@ -3301,6 +3303,7 @@ static int packet_create(struct net *net
+@@ -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;
if (sock->type == SOCK_PACKET)
po->prot_hook.func = packet_rcv_spkt;
-@@ -3923,6 +3926,16 @@ packet_setsockopt(struct socket *sock, i
+@@ -3935,6 +3938,16 @@ packet_setsockopt(struct socket *sock, i
po->xmit = val ? packet_direct_xmit : dev_queue_xmit;
return 0;
}
default:
return -ENOPROTOOPT;
}
-@@ -3975,6 +3988,13 @@ static int packet_getsockopt(struct sock
+@@ -3987,6 +4000,13 @@ static int packet_getsockopt(struct sock
case PACKET_VNET_HDR:
val = po->has_vnet_hdr;
break;
break;
--- a/net/packet/internal.h
+++ b/net/packet/internal.h
-@@ -132,6 +132,7 @@ struct packet_sock {
+@@ -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;
struct nf_flow_route {
--- a/net/netfilter/nf_flow_table_hw.c
+++ b/net/netfilter/nf_flow_table_hw.c
-@@ -19,48 +19,75 @@ struct flow_offload_hw {
+@@ -19,48 +19,77 @@ struct flow_offload_hw {
enum flow_offload_type type;
struct flow_offload *flow;
struct nf_conn *ct;
-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;
- dev_put(indev);
+ memcpy(path->eth_src, path->dev->dev_addr, ETH_ALEN);
-+ n = dst_neigh_lookup(tuple->dst_cache, &tuple->src_v4);
++ n = dst_neigh_lookup(dst, &tuple->src_v4);
+ if (!n)
+ return;
-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;
+ return -ENOENT;
+
+ path->dev = dev;
-+ flow_offload_check_ethernet(tuple, path);
++ 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);
+ /* restore devices in case the driver mangled them */
+ offload->src.dev = src_dev;
+ offload->dest.dev = dest_dev;
-+
-+ return ret;
-+}
- 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);
}
static void flow_offload_hw_work(struct work_struct *work)
-@@ -73,18 +100,22 @@ static void flow_offload_hw_work(struct
+@@ -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) {
}
}
-@@ -97,20 +128,55 @@ static void flow_offload_queue_work(stru
+@@ -97,20 +130,56 @@ static void flow_offload_queue_work(stru
schedule_work(&nf_flow_offload_hw_work);
}
+{
+ struct flow_offload_hw_path src = {};
+ struct flow_offload_hw_path dest = {};
-+ struct flow_offload_tuple *tuple;
++ struct flow_offload_tuple *tuple_s, *tuple_d;
+ struct flow_offload_hw *offload = NULL;
+
+ rcu_read_lock_bh();
+
-+ tuple = &flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple;
-+ if (flow_offload_check_path(net, tuple, &src))
++ 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;
+
-+ tuple = &flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple;
-+ if (flow_offload_check_path(net, tuple, &dest))
++ if (flow_offload_check_path(net, tuple_d, tuple_s->dst_cache, &dest))
+ goto out;
+
+ if (!src.dev->netdev_ops->ndo_flow_offload)
flow_offload_queue_work(offload);
}
-@@ -119,14 +185,11 @@ static void flow_offload_hw_del(struct n
+@@ -119,14 +188,11 @@ static void flow_offload_hw_del(struct n
{
struct flow_offload_hw *offload;
flow_offload_queue_work(offload);
}
-@@ -153,12 +216,8 @@ static void __exit nf_flow_table_hw_modu
+@@ -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);
#include <linux/nsproxy.h>
#include <net/net_namespace.h>
#include <net/netns/generic.h>
-@@ -978,8 +983,36 @@ static int pppoe_xmit(struct ppp_channel
+@@ -981,8 +986,36 @@ static int pppoe_xmit(struct ppp_channel
return __pppoe_xmit(sk, skb);
}
static void rt_fibinfo_free(struct rtable __rcu **rtp)
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
-@@ -2469,6 +2469,7 @@ static const char *const rtn_type_names[
+@@ -2472,6 +2472,7 @@ static const char *const rtn_type_names[
[RTN_THROW] = "THROW",
[RTN_NAT] = "NAT",
[RTN_XRESOLVE] = "XRESOLVE",
static const struct rt6_info ip6_blk_hole_entry_template = {
.dst = {
.__refcnt = ATOMIC_INIT(1),
-@@ -2054,6 +2071,11 @@ static struct rt6_info *ip6_route_info_c
+@@ -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_THROW:
case RTN_UNREACHABLE:
default:
-@@ -2779,6 +2801,17 @@ static int ip6_pkt_prohibit_out(struct n
+@@ -2781,6 +2803,17 @@ static int ip6_pkt_prohibit_out(struct n
return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES);
}
/*
* Allocate a dst for local (unicast / anycast) address.
*/
-@@ -3015,7 +3048,8 @@ static int rtm_to_fib6_config(struct sk_
+@@ -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 ||
cfg->fc_flags |= RTF_REJECT;
if (rtm->rtm_type == RTN_LOCAL)
-@@ -3515,6 +3549,9 @@ static int rt6_fill_node(struct net *net
+@@ -3517,6 +3551,9 @@ static int rt6_fill_node(struct net *net
case -EACCES:
rtm->rtm_type = RTN_PROHIBIT;
break;
case -EAGAIN:
rtm->rtm_type = RTN_THROW;
break;
-@@ -3833,6 +3870,8 @@ static int ip6_route_dev_notify(struct n
+@@ -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_blk_hole_entry->dst.dev = dev;
net->ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(dev);
#endif
-@@ -3844,6 +3883,7 @@ static int ip6_route_dev_notify(struct n
+@@ -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_blk_hole_entry->rt6i_idev);
#endif
}
-@@ -4060,6 +4100,17 @@ static int __net_init ip6_route_net_init
+@@ -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);
#endif
net->ipv6.sysctl.flush_delay = 0;
-@@ -4078,6 +4129,8 @@ out:
+@@ -4080,6 +4131,8 @@ out:
return ret;
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
out_ip6_prohibit_entry:
kfree(net->ipv6.ip6_prohibit_entry);
out_ip6_null_entry:
-@@ -4095,6 +4148,7 @@ static void __net_exit ip6_route_net_exi
+@@ -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);
#endif
dst_entries_destroy(&net->ipv6.ip6_dst_ops);
}
-@@ -4168,6 +4222,9 @@ void __init ip6_route_init_special_entri
+@@ -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);
__u16 tc_index; /* traffic control index */
--- a/net/core/dev.c
+++ b/net/core/dev.c
-@@ -4805,6 +4805,9 @@ static enum gro_result dev_gro_receive(s
+@@ -4806,6 +4806,9 @@ static enum gro_result dev_gro_receive(s
enum gro_result ret;
int grow;
if (netif_elide_gro(skb->dev))
goto normal;
-@@ -6282,6 +6285,48 @@ static void __netdev_adjacent_dev_unlink
+@@ -6283,6 +6286,48 @@ static void __netdev_adjacent_dev_unlink
&upper_dev->adj_list.lower);
}
static int __netdev_upper_dev_link(struct net_device *dev,
struct net_device *upper_dev, bool master,
void *upper_priv, void *upper_info)
-@@ -6320,6 +6365,7 @@ static int __netdev_upper_dev_link(struc
+@@ -6321,6 +6366,7 @@ static int __netdev_upper_dev_link(struc
if (ret)
return ret;
ret = call_netdevice_notifiers_info(NETDEV_CHANGEUPPER, dev,
&changeupper_info.info);
ret = notifier_to_errno(ret);
-@@ -6397,6 +6443,7 @@ void netdev_upper_dev_unlink(struct net_
+@@ -6398,6 +6444,7 @@ void netdev_upper_dev_unlink(struct net_
__netdev_adjacent_dev_unlink_neighbour(dev, upper_dev);
call_netdevice_notifiers_info(NETDEV_CHANGEUPPER, dev,
&changeupper_info.info);
}
-@@ -6961,6 +7008,7 @@ int dev_set_mac_address(struct net_devic
+@@ -6962,6 +7009,7 @@ int dev_set_mac_address(struct net_devic
if (err)
return err;
dev->addr_assign_type = NET_ADDR_SET;
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
-@@ -1106,6 +1106,9 @@ void phy_detach(struct phy_device *phyde
+@@ -1110,6 +1110,9 @@ void phy_detach(struct phy_device *phyde
struct module *ndev_owner = dev->dev.parent->driver->owner;
struct mii_bus *bus;
sysfs_remove_link(&phydev->mdio.dev.kobj, "attached_dev");
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
-@@ -559,6 +559,12 @@ struct phy_driver {
+@@ -561,6 +561,12 @@ struct phy_driver {
*/
int (*did_interrupt)(struct phy_device *phydev);
default y
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
-@@ -43,6 +43,7 @@ static void quirk_mmio_always_on(struct
+@@ -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);
/* 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.
-@@ -3094,6 +3095,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_I
+@@ -3095,6 +3096,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);
/*
* Ivytown NTB BAR sizes are misreported by the hardware due to an erratum. To
-@@ -3150,6 +3152,8 @@ static void fixup_debug_report(struct pc
+@@ -3151,6 +3153,8 @@ static void fixup_debug_report(struct pc
}
}
/*
* Some BIOS implementations leave the Intel GPU interrupts enabled,
* even though no one is handling them (f.e. i915 driver is never loaded).
-@@ -3188,6 +3192,8 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_IN
+@@ -3189,6 +3193,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);
--- /dev/null
+#
+# Copyright (C) 2012-2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+
+BOARD:=mvebu
+BOARDNAME:=Marvell EBU Armada
+FEATURES:=fpu usb pci pcie gpio nand squashfs ramdisk boot-part rootfs-part
+SUBTARGETS:=cortexa9
+MAINTAINER:=Imre Kaloz <kaloz@openwrt.org>
+
+KERNEL_PATCHVER:=4.14
+
+include $(INCLUDE_DIR)/target.mk
+
+DEFAULT_PACKAGES += uboot-envtools kmod-gpio-button-hotplug
+
+$(eval $(call BuildTarget))
--- /dev/null
+#!/bin/sh
+#
+# Copyright (C) 2014-2016 OpenWrt.org
+# Copyright (C) 2016 LEDE-Project.org
+#
+
+. /lib/functions/uci-defaults.sh
+
+board_config_update
+
+board=$(board_name)
+
+case "$board" in
+linksys,caiman)
+ ucidef_set_led_netdev "wan" "WAN" "pca963x:caiman:white:wan" "eth1"
+ ucidef_set_led_usbport "usb1" "USB 1" "pca963x:caiman:white:usb2" "usb1-port1"
+ ucidef_set_led_usbport "usb2" "USB 2" "pca963x:caiman:white:usb3_1" "usb2-port1" "usb3-port1"
+ ucidef_set_led_usbport "usb2_ss" "USB 2 SS" "pca963x:caiman:white:usb3_2" "usb3-port1"
+ ;;
+linksys,cobra)
+ ucidef_set_led_netdev "wan" "WAN" "pca963x:cobra:white:wan" "eth1"
+ ucidef_set_led_usbport "usb1" "USB 1" "pca963x:cobra:white:usb2" "usb1-port1"
+ ucidef_set_led_usbport "usb2" "USB 2" "pca963x:cobra:white:usb3_1" "usb2-port1" "usb3-port1"
+ ucidef_set_led_usbport "usb2_ss" "USB 2 SS" "pca963x:cobra:white:usb3_2" "usb3-port1"
+ ;;
+linksys,mamba)
+ ucidef_set_led_netdev "wan" "WAN" "mamba:white:wan" "eth1"
+ ucidef_set_led_usbport "usb1" "USB 1" "mamba:white:usb2" "usb1-port1"
+ ucidef_set_led_usbport "usb2" "USB 2" "mamba:white:usb3_1" "usb2-port1" "usb3-port1"
+ ucidef_set_led_usbport "usb2_ss" "USB 2 SS" "mamba:white:usb3_2" "usb3-port2"
+ ;;
+linksys,rango)
+ ucidef_set_led_netdev "wan" "WAN" "pca963x:rango:white:wan" "eth1"
+ ucidef_set_led_usbport "usb1" "USB 1" "pca963x:rango:white:usb2" "usb1-port1"
+ ucidef_set_led_usbport "usb2" "USB 2" "pca963x:rango:white:usb3_1" "usb2-port1" "usb3-port1"
+ ucidef_set_led_usbport "usb2_ss" "USB 2 SS" "pca963x:rango:white:usb3_2" "usb3-port1"
+ ;;
+linksys,shelby)
+ ucidef_set_led_netdev "wan" "WAN" "pca963x:shelby:white:wan" "eth1"
+ ucidef_set_led_usbport "usb1" "USB 1" "pca963x:shelby:white:usb2" "usb1-port1"
+ ucidef_set_led_usbport "usb2" "USB 2" "pca963x:shelby:white:usb3_1" "usb2-port1" "usb3-port1"
+ ucidef_set_led_usbport "usb2_ss" "USB 2 SS" "pca963x:shelby:white:usb3_2" "usb3-port1"
+ ;;
+linksys,venom)
+ ucidef_set_led_netdev "wan" "WAN" "pca963x:venom:blue:wan" "eth1"
+ ucidef_set_led_usbport "usb1" "USB 1" "pca963x:venom:blue:usb2" "usb1-port1"
+ ucidef_set_led_usbport "usb2" "USB 2" "pca963x:venom:blue:usb3_1" "usb2-port1" "usb3-port1"
+ ucidef_set_led_usbport "usb2_ss" "USB 2 SS" "pca963x:venom:blue:usb3_2" "usb3-port1"
+ ;;
+
+esac
+
+board_config_flush
+
+exit 0
--- /dev/null
+#!/bin/sh
+#
+# Copyright (C) 2014-2016 OpenWrt.org
+# Copyright (C) 2016 LEDE-Project.org
+#
+
+. /lib/functions/uci-defaults.sh
+
+board_config_update
+
+board=$(board_name)
+
+case "$board" in
+cznic,turris-omnia)
+ ucidef_set_interface_lan "lan0 lan1 lan2 lan3 lan4"
+ ucidef_set_interface_wan "eth2"
+ ;;
+globalscale,espressobin|\
+globalscale,espressobin-emmc|\
+globalscale,espressobin-v7|\
+globalscale,espressobin-v7-emmc)
+ ucidef_set_interfaces_lan_wan "lan0 lan1" "wan"
+ ;;
+linksys,caiman|\
+linksys,cobra|\
+linksys,mamba|\
+linksys,rango|\
+linksys,shelby|\
+linksys,venom)
+ ucidef_set_interfaces_lan_wan "eth0.1" "eth1.2"
+ ucidef_add_switch "switch0" \
+ "0:lan:4" "1:lan:3" "2:lan:2" "3:lan:1" "5@eth0" "4:wan" "6@eth1"
+ ;;
+marvell,a385-db-ap)
+ ucidef_set_interfaces_lan_wan "eth0 eth1" "eth2"
+ ;;
+marvell,armada8040-mcbin)
+ ucidef_set_interfaces_lan_wan "eth0 eth1 eth3" "eth2"
+ ;;
+marvell,armada8040-db)
+ ucidef_set_interfaces_lan_wan "eth0 eth2 eth3" "eth1"
+ ;;
+marvell,armada7040-db)
+ ucidef_set_interfaces_lan_wan "eth0 eth2" "eth1"
+ ;;
+marvell,armada-3720-db)
+ ucidef_set_interfaces_lan_wan "eth1" "eth0"
+ ;;
+marvell,axp-gp)
+ ucidef_set_interface_lan "eth0 eth1 eth2 eth3"
+ ;;
+solidrun,clearfog*a1)
+ # eth0 is standalone ethernet
+ # eth1 is switch (-pro) or standalone ethernet (-base)
+ # eth2 is SFP
+ ucidef_set_interfaces_lan_wan "eth1" "eth0 eth2"
+
+ # if switch exists (clearfog-pro)
+ # switch port 5 is connected to eth1
+ swconfig list 2>&1 | grep -q switch0 && \
+ ucidef_add_switch "switch0" \
+ "0:lan:5" "1:lan:4" "2:lan:3" "3:lan:2" "4:lan:1" "5u@eth1" "6:lan:6"
+ ;;
+*)
+ ucidef_set_interface_lan "eth0"
+ ;;
+esac
+
+board_config_flush
+
+exit 0
--- /dev/null
+#!/bin/sh
+# Copyright (C) 2014-2016 OpenWrt.org
+# Copyright (C) 2016 LEDE-Project.org
+
+. /lib/functions.sh
+. /lib/functions/leds.sh
+
+get_status_led() {
+ case $(board_name) in
+ linksys,caiman)
+ status_led="caiman:white:power"
+ ;;
+ linksys,cobra)
+ status_led="cobra:white:power"
+ ;;
+ linksys,mamba)
+ status_led="mamba:white:power"
+ ;;
+ linksys,rango)
+ status_led="rango:white:power"
+ ;;
+ linksys,shelby)
+ status_led="shelby:white:power"
+ ;;
+ linksys,venom)
+ status_led="venom:blue:power"
+ ;;
+ 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
+ ;;
+ done)
+ status_led_on
+ ;;
+ esac
+}
--- /dev/null
+#!/bin/sh
+
+# The pcie-controller device was renamed to pcie in Linux kernel 4.14
+# commit 28fbb9c539e2 ("ARM: dts: marvell: fix PCI bus dtc warnings").
+# This script migrates the path in the UCI configuration from the old
+# name to the new name and also back, when am upgrade or downgrade is
+# done. It checks if the name exists before changing the configuration.
+# This has to be done before the 10-wifi-detect script from mac80211 is
+# executed because this would add the devices again under the new path
+# name.
+
+. /lib/functions.sh
+
+PATH_CHANGED=0
+
+rename_wifi_path() {
+ local path_old=$(uci get wireless.${1}.path)
+ local path_new=$(echo ${path_old} | sed "${2}")
+
+ if [ -e "/sys/devices/platform/${path_new}" ] && [ ${path_old} != ${path_new} ]
+ then
+ uci set wireless.${1}.path=${path_new}
+ PATH_CHANGED=1
+ fi
+}
+
+rename_wifi_path_list() {
+ # migration from kernel 4.9 to 4.14
+ rename_wifi_path $1 "s/soc:pcie-controller/soc:pcie/"
+ # migration from kernel 4.14 to 4.9
+ rename_wifi_path $1 "s/soc:pcie/soc:pcie-controller/"
+}
+
+[ "${ACTION}" = "add" ] && {
+ [ ! -e /etc/config/wireless ] && return
+
+ config_load wireless
+ config_foreach rename_wifi_path_list wifi-device
+
+ [ "$PATH_CHANGED" = "1" ] && uci commit wireless
+}
--- /dev/null
+#!/bin/sh /etc/rc.common
+
+START=99
+
+start() {
+ . /lib/functions.sh
+
+ case $(board_name) in
+ linksys,caiman |\
+ linksys,cobra |\
+ linksys,mamba |\
+ linksys,rango |\
+ linksys,shelby |\
+ linksys,venom)
+ mtd resetbc s_env || true
+ ;;
+ esac
+}
--- /dev/null
+#!/bin/sh
+#
+# Copyright (C) 2015 OpenWrt.org
+#
+
+[ ! -e /etc/config/wireless ] && exit 0
+
+. /lib/functions.sh
+. /lib/functions/system.sh
+
+board=$(board_name)
+
+case "$board" in
+linksys,caiman|linksys,cobra|linksys,mamba|linksys,shelby|linksys,venom)
+ SKU=$(strings /dev/mtd3|sed -ne 's/^cert_region=//p')
+ WIFIMAC2G=$(macaddr_add $(cat /sys/class/net/eth0/address) +1)
+ WIFIMAC5G=$(macaddr_add $WIFIMAC2G +1)
+ case "$SKU" in
+ AP)
+ REGD=CN
+ ;;
+ AU)
+ REGD=AU
+ ;;
+ CA)
+ REGD=CA
+ ;;
+ EU)
+ REGD=DE
+ ;;
+ US)
+ REGD=US
+ ;;
+ esac
+
+ case "$board" in
+ linksys,mamba)
+ WIFIMAC0=$WIFIMAC2G
+ WIFIMAC1=$WIFIMAC5G
+ ;;
+ *)
+ WIFIMAC0=$WIFIMAC5G
+ WIFIMAC1=$WIFIMAC2G
+ ;;
+ esac
+
+ uci get wireless.radio0.country || uci set wireless.radio0.country=$REGD
+ uci get wireless.@wifi-iface[0].macaddr || uci set wireless.@wifi-iface[0].macaddr=$WIFIMAC0
+ uci get wireless.radio1.country || uci set wireless.radio1.country=$REGD
+ uci get wireless.@wifi-iface[1].macaddr || uci set wireless.@wifi-iface[1].macaddr=$WIFIMAC1
+ ;;
+esac
+
+uci commit wireless
+
+exit 0
--- /dev/null
+#!/bin/sh
+#
+# Copyright (C) 2017 LEDE-Project.org
+#
+
+. /lib/functions.sh
+
+board=$(board_name)
+
+case "$board" in
+linksys,mamba)
+ # Set fan script execution in crontab
+ grep -s -q fan_ctrl.sh /etc/crontabs/root && exit 0
+
+ echo "# mamba fan script runs every 5 minutes" >> /etc/crontabs/root
+ echo "*/5 * * * * /sbin/fan_ctrl.sh" >> /etc/crontabs/root
+
+ # Execute one time after initial flash (instead of waiting 5 min for cron)
+ /sbin/fan_ctrl.sh
+ ;;
+esac
+
+exit 0
--- /dev/null
+#
+# Copyright (C) 2014-2015 OpenWrt.org
+# Copyright (C) 2016 LEDE-Project.org
+#
+
+preinit_set_mac_address() {
+ local mac
+
+ . /lib/functions.sh
+
+ case $(board_name) in
+ linksys,caiman|linksys,cobra|linksys,rango|linksys,shelby|linksys,venom)
+ # rename interfaces back to the way they were with 4.4
+ case "$(readlink /sys/class/net/eth0)" in
+ *f1070000*)
+ ip link set eth0 name tmp0
+ ip link set eth1 name eth0
+ ip link set tmp0 name eth1
+ ;;
+ esac
+
+ mac=$(mtd_get_mac_ascii devinfo hw_mac_addr)
+ mac_wan=$(macaddr_setbit_la "$mac")
+ ip link set dev eth1 address $mac 2>/dev/null
+ ip link set dev eth0 address $mac_wan 2>/dev/null
+ ;;
+ linksys,mamba)
+ mac=$(mtd_get_mac_ascii devinfo hw_mac_addr)
+ ip link set dev eth0 address $mac 2>/dev/null
+ ip link set dev eth1 address $mac 2>/dev/null
+ ;;
+ marvell,a385-db-ap|solidrun,clearfog*a1)
+ # rename interfaces back to the way they were with 4.4
+ case "$(readlink /sys/class/net/eth0)" in
+ *f1070000*)
+ ip link set eth0 name tmp0
+ ip link set eth1 name eth0
+ ip link set eth2 name eth1
+ ip link set tmp0 name eth2
+ ;;
+ esac
+ ;;
+ esac
+}
+
+boot_hook_add preinit_main preinit_set_mac_address
--- /dev/null
+#!/bin/sh
+# Copyright (C) 2015 OpenWrt.org
+
+. /lib/functions.sh
+. /lib/upgrade/common.sh
+
+move_config() {
+ local partdev
+
+ if export_bootdevice && export_partdevice partdev 1; then
+ case $(board_name) in
+ cznic,turris-omnia)
+ insmod nls_cp437
+ insmod nls_iso8859-1
+ insmod fat
+ insmod vfat
+ ;;
+ esac
+ mkdir -p /boot
+ mount -o rw,noatime "/dev/$partdev" /boot
+ [ -f "/boot/$BACKUP_FILE" ] && mv -f "/boot/$BACKUP_FILE" /
+ umount /boot
+ fi
+}
+
+boot_hook_add preinit_mount_root move_config
--- /dev/null
+#
+# Copyright (C) 2014-2016 OpenWrt.org
+# Copyright (C) 2016 LEDE-Project.org
+#
+
+preinit_mount_syscfg() {
+ . /lib/functions.sh
+ . /lib/upgrade/common.sh
+
+ case $(board_name) in
+ linksys,caiman|linksys,cobra|linksys,mamba|linksys,rango|linksys,shelby|linksys,venom)
+ needs_recovery=0
+ syscfg_part=$(grep syscfg /proc/mtd |cut -c4)
+ ubiattach -m $syscfg_part || needs_recovery=1
+ if [ $needs_recovery -eq 1 ]
+ then
+ echo "ubifs syscfg partition is damaged, reformatting"
+ ubidetach -m $syscfg_part
+ ubiformat -y -O 2048 -q /dev/mtd$syscfg_part
+ ubiattach -m $syscfg_part
+ ubimkvol /dev/ubi1 -n 0 -N syscfg -t dynamic --maxavsize
+ fi
+ mkdir /tmp/syscfg
+ mount -t ubifs ubi1:syscfg /tmp/syscfg
+ [ -f "/tmp/syscfg/$BACKUP_FILE" ] && {
+ echo "- config restore -"
+ cd /
+ mv "/tmp/syscfg/$BACKUP_FILE" /tmp
+ tar xzf "/tmp/$BACKUP_FILE"
+ rm -f "/tmp/$BACKUP_FILE"
+ sync
+ }
+ ;;
+ esac
+}
+
+boot_hook_add preinit_main preinit_mount_syscfg
--- /dev/null
+#
+# Copyright (C) 2014-2015 OpenWrt.org
+#
+
+linksys_get_target_firmware() {
+
+ local cur_boot_part mtd_ubi0
+
+ cur_boot_part=`/usr/sbin/fw_printenv -n boot_part`
+ if [ -z "${cur_boot_part}" ] ; then
+ mtd_ubi0=$(cat /sys/devices/virtual/ubi/ubi0/mtd_num)
+ case $(egrep ^mtd${mtd_ubi0}: /proc/mtd | cut -d '"' -f 2) in
+ kernel1|rootfs1)
+ cur_boot_part=1
+ ;;
+ kernel2|rootfs2)
+ cur_boot_part=2
+ ;;
+ esac
+ >&2 printf "Current boot_part='%s' selected from ubi0/mtd_num='%s'" \
+ "${cur_boot_part}" "${mtd_ubi0}"
+ fi
+
+ case $cur_boot_part in
+ 1)
+ fw_setenv -s - <<-EOF
+ boot_part 2
+ bootcmd "run altnandboot"
+ EOF
+ printf "kernel2"
+ return
+ ;;
+ 2)
+ fw_setenv -s - <<-EOF
+ boot_part 1
+ bootcmd "run nandboot"
+ EOF
+ printf "kernel1"
+ return
+ ;;
+ *)
+ return
+ ;;
+ esac
+}
+
+linksys_get_root_magic() {
+ (get_image "$@" | dd skip=786432 bs=4 count=1 | hexdump -v -n 4 -e '1/1 "%02x"') 2>/dev/null
+}
+
+platform_do_upgrade_linksys() {
+ local magic_long="$(get_magic_long "$1")"
+
+ mkdir -p /var/lock
+ local part_label="$(linksys_get_target_firmware)"
+ touch /var/lock/fw_printenv.lock
+
+ if [ ! -n "$part_label" ]
+ then
+ echo "cannot find target partition"
+ exit 1
+ fi
+
+ local target_mtd=$(find_mtd_part $part_label)
+
+ [ "$magic_long" = "73797375" ] && {
+ CI_KERNPART="$part_label"
+ if [ "$part_label" = "kernel1" ]
+ then
+ CI_UBIPART="rootfs1"
+ else
+ CI_UBIPART="rootfs2"
+ fi
+
+ nand_upgrade_tar "$1"
+ }
+ [ "$magic_long" = "27051956" -o "$magic_long" = "0000a0e1" ] && {
+ # check firmwares' rootfs types
+ local target_mtd=$(find_mtd_part $part_label)
+ local oldroot="$(linksys_get_root_magic $target_mtd)"
+ local newroot="$(linksys_get_root_magic "$1")"
+
+ if [ "$newroot" = "55424923" -a "$oldroot" = "55424923" ]
+ # we're upgrading from a firmware with UBI to one with UBI
+ then
+ # erase everything to be safe
+ mtd erase $part_label
+ get_image "$1" | mtd -n write - $part_label
+ else
+ get_image "$1" | mtd write - $part_label
+ fi
+ }
+}
+
+platform_copy_config_linksys() {
+ cp -f "$UPGRADE_BACKUP" "/tmp/syscfg/$BACKUP_FILE"
+ sync
+}
--- /dev/null
+#
+# Copyright (C) 2014-2016 OpenWrt.org
+# Copyright (C) 2016 LEDE-Project.org
+#
+
+RAMFS_COPY_BIN='fw_printenv fw_setenv'
+RAMFS_COPY_DATA='/etc/fw_env.config /var/lock/fw_printenv.lock'
+REQUIRE_IMAGE_METADATA=1
+
+platform_check_image() {
+ case "$(board_name)" in
+ cznic,turris-omnia|globalscale,espressobin|globalscale,espressobin-emmc|globalscale,espressobin-v7|globalscale,espressobin-v7-emmc|\
+ marvell,armada8040-mcbin|solidrun,clearfog-base-a1|solidrun,clearfog-pro-a1)
+ platform_check_image_sdcard "$1"
+ ;;
+ *)
+ return 0
+ ;;
+ esac
+}
+
+platform_do_upgrade() {
+ case "$(board_name)" in
+ linksys,caiman|linksys,cobra|linksys,mamba|linksys,rango|linksys,shelby|linksys,venom)
+ platform_do_upgrade_linksys "$1"
+ ;;
+ cznic,turris-omnia|globalscale,espressobin|globalscale,espressobin-emmc|globalscale,espressobin-v7|globalscale,espressobin-v7-emmc|\
+ marvell,armada8040-mcbin|solidrun,clearfog-base-a1|solidrun,clearfog-pro-a1)
+ platform_do_upgrade_sdcard "$1"
+ ;;
+ *)
+ default_do_upgrade "$1"
+ ;;
+ esac
+}
+platform_copy_config() {
+ case "$(board_name)" in
+ linksys,caiman|linksys,cobra|linksys,mamba|linksys,rango|linksys,shelby|linksys,venom)
+ platform_copy_config_linksys
+ ;;
+ cznic,turris-omnia|globalscale,espressobin|globalscale,espressobin-emmc|globalscale,espressobin-v7|globalscale,espressobin-v7-emmc|\
+ marvell,armada8040-mcbin|solidrun,clearfog-base-a1|solidrun,clearfog-pro-a1)
+ platform_copy_config_sdcard
+ ;;
+ esac
+}
--- /dev/null
+get_magic_at() {
+ local file="$1"
+ local pos="$2"
+ get_image "$file" | dd bs=1 count=2 skip="$pos" 2>/dev/null | hexdump -v -n 2 -e '1/1 "%02x"'
+}
+
+platform_check_image_sdcard() {
+ local file="$1"
+ local magic diskdev partdev diff
+
+ magic=$(get_magic_at "$file" 510)
+ [ "$magic" != "55aa" ] && {
+ echo "Failed to verify MBR boot signature."
+ return 1
+ }
+
+ export_bootdevice && export_partdevice diskdev 0 || {
+ echo "Unable to determine upgrade device"
+ return 1
+ }
+
+ get_partitions "/dev/$diskdev" bootdisk
+
+ #extract the boot sector from the image
+ get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b 2>/dev/null
+
+ get_partitions /tmp/image.bs image
+
+ #compare tables
+ diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)"
+
+ rm -f /tmp/image.bs /tmp/partmap.bootdisk /tmp/partmap.image
+
+ if [ -n "$diff" ]; then
+ echo "Partition layout has changed. Full image will be written."
+ ask_bool 0 "Abort" && exit 1
+ return 0
+ fi
+}
+
+platform_do_upgrade_sdcard() {
+ local board=$(board_name)
+ local diskdev partdev diff
+
+ export_bootdevice && export_partdevice diskdev 0 || {
+ echo "Unable to determine upgrade device"
+ return 1
+ }
+
+ sync
+
+ if [ "$UPGRADE_OPT_SAVE_PARTITIONS" = "1" ]; then
+ get_partitions "/dev/$diskdev" bootdisk
+
+ #extract the boot sector from the image
+ get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b
+
+ get_partitions /tmp/image.bs image
+
+ #compare tables
+ diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)"
+ else
+ diff=1
+ fi
+
+ if [ -n "$diff" ]; then
+ get_image "$@" | dd of="/dev/$diskdev" bs=4096 conv=fsync
+
+ # Separate removal and addtion is necessary; otherwise, partition 1
+ # will be missing if it overlaps with the old partition 2
+ partx -d - "/dev/$diskdev"
+ partx -a - "/dev/$diskdev"
+ else
+ #write uboot image
+ get_image "$@" | dd of="$diskdev" bs=512 skip=1 seek=1 count=2048 conv=fsync
+ #iterate over each partition from the image and write it to the boot disk
+ while read part start size; do
+ if export_partdevice partdev $part; then
+ echo "Writing image to /dev/$partdev..."
+ get_image "$@" | dd of="/dev/$partdev" ibs="512" obs=1M skip="$start" count="$size" conv=fsync
+ else
+ echo "Unable to find partition $part device, skipped."
+ fi
+ done < /tmp/partmap.image
+
+ #copy partition uuid
+ echo "Writing new UUID to /dev/$diskdev..."
+ get_image "$@" | dd of="/dev/$diskdev" bs=1 skip=440 count=4 seek=440 conv=fsync
+ fi
+
+ case "$board" in
+ cznic,turris-omnia)
+ fw_setenv openwrt_bootargs 'earlyprintk console=ttyS0,115200 root=/dev/mmcblk0p2 rootfstype=auto rootwait'
+ fw_setenv openwrt_mmcload 'setenv bootargs "$openwrt_bootargs cfg80211.freg=$regdomain"; fatload mmc 0 0x01000000 zImage; fatload mmc 0 0x02000000 armada-385-turris-omnia.dtb'
+ fw_setenv factory_mmcload 'setenv bootargs "$bootargs cfg80211.freg=$regdomain"; btrload mmc 0 0x01000000 boot/zImage @; btrload mmc 0 0x02000000 boot/dtb @'
+ fw_setenv mmcboot 'run openwrt_mmcload || run factory_mmcload; bootz 0x01000000 - 0x02000000'
+ ;;
+ esac
+
+ sleep 1
+}
+
+platform_copy_config_sdcard() {
+ local partdev
+
+ if export_partdevice partdev 1; then
+ mkdir -p /boot
+ [ -f /boot/kernel.img ] || mount -o rw,noatime /dev/$partdev /boot
+ cp -af "$UPGRADE_BACKUP" "/boot/$BACKUP_FILE"
+ sync
+ umount /boot
+ fi
+}
--- /dev/null
+#!/bin/sh
+
+CPU_TEMP=`cut -c1-2 /sys/class/hwmon/hwmon2/temp1_input`
+DDR_TEMP=`cut -c1-2 /sys/class/hwmon/hwmon1/temp1_input`
+WIFI_TEMP=`cut -c1-2 /sys/class/hwmon/hwmon1/temp2_input`
+
+CPU_LOW=85
+CPU_HIGH=95
+DDR_LOW=65
+DDR_HIGH=75
+WIFI_LOW=100
+WIFI_HIGH=115
+
+if [ -d /sys/devices/pwm_fan ];then
+ FAN_CTRL=/sys/devices/pwm_fan/hwmon/hwmon0/pwm1
+elif [ -d /sys/devices/platform/pwm_fan ];then
+ FAN_CTRL=/sys/devices/platform/pwm_fan/hwmon/hwmon0/pwm1
+else
+ exit 0
+fi
+
+if [ "$CPU_TEMP" -ge "$CPU_HIGH" -o "$DDR_TEMP" -ge "$DDR_HIGH" -o "$WIFI_TEMP" -ge "$WIFI_HIGH" ];then
+ echo "255" > $FAN_CTRL
+elif [ "$CPU_TEMP" -ge "$CPU_LOW" -o "$DDR_TEMP" -ge "$DDR_LOW" -o "$WIFI_TEMP" -ge "$WIFI_LOW" ];then
+ echo "100" > $FAN_CTRL
+else
+ echo "0" > $FAN_CTRL
+fi
--- /dev/null
+CONFIG_AHCI_MVEBU=y
+CONFIG_ALIGNMENT_TRAP=y
+CONFIG_ARCH_CLOCKSOURCE_DATA=y
+CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y
+CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
+CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y
+CONFIG_ARCH_HAS_SET_MEMORY=y
+CONFIG_ARCH_HAS_SG_CHAIN=y
+CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y
+CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y
+CONFIG_ARCH_HAS_TICK_BROADCAST=y
+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
+CONFIG_ARCH_MULTIPLATFORM=y
+# CONFIG_ARCH_MULTI_CPU_AUTO is not set
+CONFIG_ARCH_MULTI_V6_V7=y
+CONFIG_ARCH_MULTI_V7=y
+CONFIG_ARCH_MVEBU=y
+CONFIG_ARCH_NR_GPIO=0
+CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
+CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
+CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y
+CONFIG_ARCH_SUPPORTS_UPROBES=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_USE_BUILTIN_BSWAP=y
+CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y
+CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
+CONFIG_ARM=y
+CONFIG_ARMADA_370_CLK=y
+CONFIG_ARMADA_370_XP_IRQ=y
+CONFIG_ARMADA_370_XP_TIMER=y
+CONFIG_ARMADA_38X_CLK=y
+CONFIG_ARMADA_THERMAL=y
+CONFIG_ARMADA_XP_CLK=y
+CONFIG_ARM_APPENDED_DTB=y
+# CONFIG_ARM_ARMADA_37XX_CPUFREQ is not set
+CONFIG_ARM_ATAG_DTB_COMPAT=y
+# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set
+# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER is not set
+CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE=y
+CONFIG_ARM_CPU_SUSPEND=y
+CONFIG_ARM_CRYPTO=y
+CONFIG_ARM_ERRATA_720789=y
+CONFIG_ARM_ERRATA_764369=y
+CONFIG_ARM_GIC=y
+CONFIG_ARM_GLOBAL_TIMER=y
+CONFIG_ARM_HAS_SG_CHAIN=y
+CONFIG_ARM_HEAVY_MB=y
+CONFIG_ARM_L1_CACHE_SHIFT=6
+CONFIG_ARM_L1_CACHE_SHIFT_6=y
+# CONFIG_ARM_LPAE is not set
+CONFIG_ARM_MVEBU_V7_CPUIDLE=y
+CONFIG_ARM_PATCH_IDIV=y
+CONFIG_ARM_PATCH_PHYS_VIRT=y
+CONFIG_ARM_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+CONFIG_ARM_UNWIND=y
+CONFIG_ARM_VIRT_EXT=y
+CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH=y
+CONFIG_ATA=y
+CONFIG_ATAGS=y
+CONFIG_AUTO_ZRELADDR=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_MQ_PCI=y
+CONFIG_BLK_SCSI_REQUEST=y
+CONFIG_BOUNCE=y
+# CONFIG_CACHE_FEROCEON_L2 is not set
+CONFIG_CACHE_L2X0=y
+CONFIG_CLKDEV_LOOKUP=y
+CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK=y
+CONFIG_CLKSRC_MMIO=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_COMMON_CLK=y
+CONFIG_CPUFREQ_DT=y
+CONFIG_CPUFREQ_DT_PLATDEV=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_GOV_ATTR_SET=y
+CONFIG_CPU_FREQ_GOV_COMMON=y
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_GOV_USERSPACE is not set
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_HAS_ASID=y
+# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_PJ4B=y
+CONFIG_CPU_PM=y
+CONFIG_CPU_RMAP=y
+CONFIG_CPU_SPECTRE=y
+CONFIG_CPU_THERMAL=y
+CONFIG_CPU_THUMB_CAPABLE=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_V7=y
+CONFIG_CRC16=y
+CONFIG_CRYPTO_ACOMP2=y
+CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_AES_ARM=y
+CONFIG_CRYPTO_AES_ARM_BS=y
+# CONFIG_CRYPTO_AES_ARM_CE is not set
+# CONFIG_CRYPTO_CHACHA20_NEON is not set
+CONFIG_CRYPTO_CRC32=y
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_CRC32_ARM_CE is not set
+CONFIG_CRYPTO_CRYPTD=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_DEV_MARVELL_CESA=y
+# CONFIG_CRYPTO_GHASH_ARM_CE is not set
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_HW=y
+CONFIG_CRYPTO_LZO=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+CONFIG_CRYPTO_NULL2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA1_ARM=y
+# CONFIG_CRYPTO_SHA1_ARM_CE is not set
+CONFIG_CRYPTO_SHA1_ARM_NEON=y
+CONFIG_CRYPTO_SHA256_ARM=y
+# CONFIG_CRYPTO_SHA2_ARM_CE is not set
+CONFIG_CRYPTO_SHA512_ARM=y
+CONFIG_CRYPTO_SIMD=y
+CONFIG_CRYPTO_WORKQUEUE=y
+CONFIG_DCACHE_WORD_ACCESS=y
+CONFIG_DEBUG_ALIGN_RODATA=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_LL=y
+CONFIG_DEBUG_LL_INCLUDE="debug/8250.S"
+CONFIG_DEBUG_MVEBU_UART0=y
+# CONFIG_DEBUG_MVEBU_UART0_ALTERNATE is not set
+# CONFIG_DEBUG_MVEBU_UART1_ALTERNATE is not set
+CONFIG_DEBUG_UART_8250=y
+# CONFIG_DEBUG_UART_8250_FLOW_CONTROL is not set
+CONFIG_DEBUG_UART_8250_SHIFT=2
+# CONFIG_DEBUG_UART_8250_WORD is not set
+CONFIG_DEBUG_UART_PHYS=0xd0012000
+CONFIG_DEBUG_UART_VIRT=0xfec12000
+CONFIG_DEBUG_UNCOMPRESS=y
+CONFIG_DEBUG_USER=y
+CONFIG_DMADEVICES=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_ENGINE_RAID=y
+CONFIG_DMA_OF=y
+CONFIG_DTC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_EDAC_ATOMIC_SCRUB=y
+CONFIG_EDAC_SUPPORT=y
+CONFIG_EXT4_FS=y
+CONFIG_EXTCON=y
+# CONFIG_F2FS_CHECK_FS is not set
+CONFIG_F2FS_FS=y
+# CONFIG_F2FS_FS_SECURITY is not set
+CONFIG_F2FS_FS_XATTR=y
+CONFIG_F2FS_STAT_FS=y
+CONFIG_FIXED_PHY=y
+CONFIG_FIX_EARLYCON_MEM=y
+CONFIG_FS_MBCACHE=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_GENERIC_ARCH_TOPOLOGY=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+CONFIG_GENERIC_CPU_AUTOPROBE=y
+CONFIG_GENERIC_EARLY_IOREMAP=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_GENERIC_IO=y
+CONFIG_GENERIC_IRQ_CHIP=y
+CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
+CONFIG_GENERIC_MSI_IRQ=y
+CONFIG_GENERIC_MSI_IRQ_DOMAIN=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_PHY=y
+CONFIG_GENERIC_SCHED_CLOCK=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GLOB=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIOLIB_IRQCHIP=y
+CONFIG_GPIO_GENERIC=y
+CONFIG_GPIO_GENERIC_PLATFORM=y
+CONFIG_GPIO_MVEBU=y
+CONFIG_GPIO_PCA953X=y
+CONFIG_GPIO_PCA953X_IRQ=y
+CONFIG_GPIO_SYSFS=y
+# CONFIG_GRO_CELLS is not set
+CONFIG_HANDLE_DOMAIN_IRQ=y
+CONFIG_HARDEN_BRANCH_PREDICTOR=y
+CONFIG_HARDIRQS_SW_RESEND=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_AUDITSYSCALL=y
+CONFIG_HAVE_ARCH_BITREVERSE=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_HAVE_ARCH_PFN_VALID=y
+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_ARM_SCU=y
+CONFIG_HAVE_ARM_SMCCC=y
+CONFIG_HAVE_ARM_TWD=y
+# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
+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_DMA_API_DEBUG=y
+CONFIG_HAVE_DMA_CONTIGUOUS=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y
+CONFIG_HAVE_EBPF_JIT=y
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=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_TIME_ACCOUNTING=y
+CONFIG_HAVE_MEMBLOCK=y
+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
+CONFIG_HAVE_NET_DSA=y
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_OPTPROBES=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_HAVE_PERF_REGS=y
+CONFIG_HAVE_PERF_USER_STACK_DUMP=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_SMP=y
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_HAVE_UID16=y
+CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
+CONFIG_HIGHMEM=y
+# CONFIG_HIGHPTE is not set
+CONFIG_HOTPLUG_CPU=y
+CONFIG_HWBM=y
+CONFIG_HWMON=y
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_OMAP is not set
+CONFIG_HZ_FIXED=0
+CONFIG_HZ_PERIODIC=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MV64XXX=y
+# CONFIG_I2C_PXA is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_IOMMU_HELPER=y
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_DEBUG=y
+CONFIG_IRQ_DOMAIN_HIERARCHY=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_WORK=y
+# CONFIG_IWMMXT is not set
+CONFIG_JBD2=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_PCA963X=y
+CONFIG_LEDS_TLC591XX=y
+CONFIG_LEDS_TRIGGER_DISK=y
+CONFIG_LIBFDT=y
+CONFIG_LOCK_SPIN_ON_OWNER=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_MACH_ARMADA_370=y
+# CONFIG_MACH_ARMADA_375 is not set
+CONFIG_MACH_ARMADA_38X=y
+# CONFIG_MACH_ARMADA_39X is not set
+CONFIG_MACH_ARMADA_XP=y
+# CONFIG_MACH_DOVE is not set
+CONFIG_MACH_MVEBU_ANY=y
+CONFIG_MACH_MVEBU_V7=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_MANGLE_BOOTARGS=y
+CONFIG_MARVELL_PHY=y
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MDIO_I2C=y
+CONFIG_MEMORY=y
+CONFIG_MIGHT_HAVE_CACHE_L2X0=y
+CONFIG_MIGHT_HAVE_PCI=y
+CONFIG_MIGRATION=y
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_MVSDIO=y
+CONFIG_MMC_SDHCI=y
+# CONFIG_MMC_SDHCI_PCI is not set
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_PXAV3=y
+# CONFIG_MMC_TIFM_SD is not set
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_M25P80=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_ECC=y
+CONFIG_MTD_NAND_PXA3xx=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_SPLIT_FIRMWARE=y
+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_MULTI_IRQ_HANDLER=y
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+CONFIG_MVEBU_CLK_COMMON=y
+CONFIG_MVEBU_CLK_COREDIV=y
+CONFIG_MVEBU_CLK_CPU=y
+CONFIG_MVEBU_DEVBUS=y
+CONFIG_MVEBU_MBUS=y
+CONFIG_MVMDIO=y
+CONFIG_MVNETA=y
+CONFIG_MVNETA_BM=y
+CONFIG_MVNETA_BM_ENABLE=y
+CONFIG_MVPP2=y
+CONFIG_MVSW61XX_PHY=y
+CONFIG_MV_XOR=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEON=y
+CONFIG_NET_DSA=y
+CONFIG_NET_DSA_MV88E6XXX=y
+CONFIG_NET_DSA_MV88E6XXX_GLOBAL2=y
+CONFIG_NET_DSA_TAG_DSA=y
+CONFIG_NET_DSA_TAG_EDSA=y
+CONFIG_NET_FLOW_LIMIT=y
+CONFIG_NET_SWITCHDEV=y
+CONFIG_NLS=y
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_NO_BOOTMEM=y
+CONFIG_NR_CPUS=4
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_ADDRESS_PCI=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_GPIO=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_MDIO=y
+CONFIG_OF_NET=y
+CONFIG_OF_PCI=y
+CONFIG_OF_PCI_IRQ=y
+CONFIG_OF_RESERVED_MEM=y
+CONFIG_OLD_SIGACTION=y
+CONFIG_OLD_SIGSUSPEND3=y
+CONFIG_ORION_WATCHDOG=y
+CONFIG_OUTER_CACHE=y
+CONFIG_OUTER_CACHE_SYNC=y
+CONFIG_PADATA=y
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_DOMAINS_GENERIC=y
+CONFIG_PCI_MSI=y
+CONFIG_PCI_MSI_IRQ_DOMAIN=y
+CONFIG_PCI_MVEBU=y
+CONFIG_PERF_USE_VMALLOC=y
+CONFIG_PGTABLE_LEVELS=2
+CONFIG_PHYLIB=y
+CONFIG_PHYLINK=y
+# CONFIG_PHY_MVEBU_CP110_COMPHY is not set
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_ARMADA_370=y
+CONFIG_PINCTRL_ARMADA_38X=y
+CONFIG_PINCTRL_ARMADA_XP=y
+CONFIG_PINCTRL_MVEBU=y
+# CONFIG_PINCTRL_SINGLE is not set
+CONFIG_PJ4B_ERRATA_4742=y
+# CONFIG_PL310_ERRATA_588369 is not set
+# CONFIG_PL310_ERRATA_727915 is not set
+CONFIG_PL310_ERRATA_753970=y
+# CONFIG_PL310_ERRATA_769419 is not set
+CONFIG_PLAT_ORION=y
+CONFIG_PM_OPP=y
+CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=11
+CONFIG_PWM=y
+CONFIG_PWM_SYSFS=y
+CONFIG_RATIONAL=y
+CONFIG_RCU_NEED_SEGCBLIST=y
+CONFIG_RCU_STALL_COMMON=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_REGMAP_SPI=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_RFS_ACCEL=y
+CONFIG_RPS=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_ARMADA38X=y
+CONFIG_RTC_DRV_MV=y
+CONFIG_RTC_I2C_AND_SPI=y
+CONFIG_RTC_MC146818_LIB=y
+CONFIG_RWSEM_SPIN_ON_OWNER=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_SATA_AHCI_PLATFORM=y
+CONFIG_SATA_MV=y
+CONFIG_SATA_PMP=y
+# CONFIG_SCHED_INFO is not set
+CONFIG_SCSI=y
+CONFIG_SENSORS_PWM_FAN=y
+CONFIG_SENSORS_TMP421=y
+CONFIG_SERIAL_8250_DW=y
+CONFIG_SERIAL_8250_FSL=y
+CONFIG_SERIAL_MVEBU_CONSOLE=y
+CONFIG_SERIAL_MVEBU_UART=y
+CONFIG_SFP=y
+CONFIG_SG_POOL=y
+CONFIG_SMP=y
+CONFIG_SMP_ON_UP=y
+CONFIG_SOC_BUS=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_SPI=y
+# CONFIG_SPI_ARMADA_3700 is not set
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_ORION=y
+CONFIG_SRAM=y
+CONFIG_SRAM_EXEC=y
+CONFIG_SRCU=y
+CONFIG_SWCONFIG=y
+CONFIG_SWIOTLB=y
+CONFIG_SWPHY=y
+CONFIG_SWP_EMULATE=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_THERMAL=y
+CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
+CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
+CONFIG_THERMAL_GOV_STEP_WISE=y
+CONFIG_THERMAL_HWMON=y
+CONFIG_THERMAL_OF=y
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TIMER_OF=y
+CONFIG_TIMER_PROBE=y
+CONFIG_TREE_RCU=y
+CONFIG_TREE_SRCU=y
+CONFIG_UBIFS_FS=y
+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
+CONFIG_USB=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_HCD_ORION=y
+CONFIG_USB_EHCI_HCD_PLATFORM=y
+CONFIG_USB_LEDS_TRIGGER_USBPORT=y
+CONFIG_USB_PHY=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_MVEBU=y
+CONFIG_USB_XHCI_PCI=y
+CONFIG_USB_XHCI_PLATFORM=y
+CONFIG_USE_OF=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_WATCHDOG_CORE=y
+CONFIG_XPS=y
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_BCJ=y
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_ZLIB_INFLATE=y
--- /dev/null
+#
+# Copyright (C) 2017 Hauke Mehrtens
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+ARCH:=arm
+BOARDNAME:=Marvell Armada 37x/38x/XP
+CPU_TYPE:=cortex-a9
+CPU_SUBTYPE:=vfpv3-d16
+KERNELNAME:=zImage dtbs
--- /dev/null
+/*
+ * Device Tree file for the Linksys WRT32X (Venom)
+ *
+ * Copyright (C) 2017 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without
+ * any warranty of any kind, whether express or implied.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include "armada-385-linksys.dtsi"
+
+/ {
+ model = "Linksys WRT32X";
+ compatible = "linksys,venom", "linksys,armada385", "marvell,armada385",
+ "marvell,armada380";
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ stdout-path = "serial0:115200n8";
+ append-rootblock = "root=/dev/mtdblock";
+ };
+};
+
+ &expander0 {
+ wan_amber@0 {
+ label = "venom:amber:wan";
+ reg = <0x0>;
+ };
+
+ wan_blue@1 {
+ label = "venom:blue:wan";
+ reg = <0x1>;
+ };
+
+ usb2@5 {
+ label = "venom:blue:usb2";
+ reg = <0x5>;
+ };
+
+ usb3_1@6 {
+ label = "venom:blue:usb3_1";
+ reg = <0x6>;
+ };
+
+ usb3_2@7 {
+ label = "venom:blue:usb3_2";
+ reg = <0x7>;
+ };
+
+ wps_blue@8 {
+ label = "venom:blue:wps";
+ reg = <0x8>;
+ };
+
+ wps_amber@9 {
+ label = "venom:amber:wps";
+ reg = <0x9>;
+ };
+ };
+
+ &gpio_leds {
+ power {
+ gpios = <&gpio1 24 GPIO_ACTIVE_HIGH>;
+ label = "venom:blue:power";
+ };
+
+ sata {
+ gpios = <&gpio1 21 GPIO_ACTIVE_LOW>;
+ label = "venom:blue:sata";
+ };
+
+ wlan_2g {
+ gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
+ label = "venom:blue:wlan_2g";
+ };
+
+ wlan_5g {
+ gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
+ label = "venom:blue:wlan_5g";
+ };
+ };
+
+ &gpio_leds_pins {
+ marvell,pins = "mpp21", "mpp45", "mpp46", "mpp56";
+ };
+
+ &nand {
+ /* Spansion S34ML02G2 256MiB, OEM Layout */
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0000000 0x200000>; /* 2MB */
+ read-only;
+ };
+
+ partition@200000 {
+ label = "u_env";
+ reg = <0x200000 0x20000>; /* 128KB */
+ };
+
+ partition@220000 {
+ label = "s_env";
+ reg = <0x220000 0x40000>; /* 256KB */
+ };
+
+ partition@180000 {
+ label = "unused_area";
+ reg = <0x260000 0x5c0000>; /* 5.75MB */
+ };
+
+ partition@7e0000 {
+ label = "devinfo";
+ reg = <0x7e0000 0x40000>; /* 256KB */
+ read-only;
+ };
+
+ /* kernel1 overlaps with rootfs1 by design */
+ partition@900000 {
+ label = "kernel1";
+ reg = <0x900000 0x7b00000>; /* 123MB */
+ };
+
+ partition@c00000 {
+ label = "rootfs1";
+ reg = <0xc00000 0x7800000>; /* 120MB */
+ };
+
+ /* kernel2 overlaps with rootfs2 by design */
+ partition@8400000 {
+ label = "kernel2";
+ reg = <0x8400000 0x7b00000>; /* 123MB */
+ };
+
+ partition@8700000 {
+ label = "rootfs2";
+ reg = <0x8700000 0x7800000>; /* 120MB */
+ };
+
+ /* last MB is for the BBT, not writable */
+ partition@ff00000 {
+ label = "BBT";
+ reg = <0xff00000 0x100000>;
+ };
+ };
+
+
+ &pcie1 {
+ mwlwifi {
+ marvell,chainmask = <4 4>;
+ };
+ };
+
+ &pcie2 {
+ mwlwifi {
+ marvell,chainmask = <4 4>;
+ };
+ };
+
+ &sdhci {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdhci_pins>;
+ no-1-8-v;
+ non-removable;
+ wp-inverted;
+ bus-width = <8>;
+ status = "okay";
+ };
+
+ &usb3_1_vbus {
+ gpio = <&gpio1 12 GPIO_ACTIVE_HIGH>;
+ };
+
+ &usb3_1_vbus_pins {
+ marvell,pins = "mpp44";
+ };
--- /dev/null
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Device Tree file for Globalscale Marvell ESPRESSOBin Board with eMMC
+ * Copyright (C) 2018 Marvell
+ *
+ * Romain Perier <romain.perier@free-electrons.com>
+ * Konstantin Porotchkin <kostap@marvell.com>
+ *
+ */
+
+#include "armada-3720-espressobin.dts"
+
+/ {
+ model = "Globalscale Marvell ESPRESSOBin Board (eMMC)";
+ compatible = "globalscale,espressobin-emmc", "globalscale,espressobin",
+ "marvell,armada3720", "marvell,armada3710";
+};
+
+&sdhci0 {
+ status = "okay";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ mmccard: mmccard@0 {
+ compatible = "mmc-card";
+ reg = <0>;
+ };
+};
--- /dev/null
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Device Tree file for Globalscale Marvell ESPRESSOBin Board V7 with eMMC
+ * Copyright (C) 2018 Marvell
+ *
+ * Romain Perier <romain.perier@free-electrons.com>
+ * Konstantin Porotchkin <kostap@marvell.com>
+ *
+ */
+
+#include "armada-3720-espressobin.dts"
+
+/ {
+ model = "Globalscale Marvell ESPRESSOBin Board V7 (eMMC)";
+ compatible = "globalscale,espressobin-v7-emmc", "globalscale,espressobin-v7",
+ "globalscale,espressobin", "marvell,armada3720",
+ "marvell,armada3710";
+};
+
+&ports {
+ port@1 {
+ reg = <1>;
+ label = "lan1";
+ phy-handle = <&switch0phy0>;
+ };
+
+ port@3 {
+ reg = <3>;
+ label = "wan";
+ phy-handle = <&switch0phy2>;
+ };
+};
+
+&sdhci0 {
+ status = "okay";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ mmccard: mmccard@0 {
+ compatible = "mmc-card";
+ reg = <0>;
+ };
+};
--- /dev/null
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Device Tree file for Globalscale Marvell ESPRESSOBin Board V7
+ * Copyright (C) 2018 Marvell
+ *
+ * Romain Perier <romain.perier@free-electrons.com>
+ * Konstantin Porotchkin <kostap@marvell.com>
+ *
+ */
+
+#include "armada-3720-espressobin.dts"
+
+/ {
+ model = "Globalscale Marvell ESPRESSOBin Board V7";
+ compatible = "globalscale,espressobin-v7", "globalscale,espressobin",
+ "marvell,armada3720", "marvell,armada3710";
+};
+
+&ports {
+ port@1 {
+ reg = <1>;
+ label = "lan1";
+ phy-handle = <&switch0phy0>;
+ };
+
+ port@3 {
+ reg = <3>;
+ label = "wan";
+ phy-handle = <&switch0phy2>;
+ };
+};
--- /dev/null
+#
+# Copyright (C) 2012-2016 OpenWrt.org
+# Copyright (C) 2016 LEDE-project.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+JFFS2_BLOCKSIZE = 128k
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/image.mk
+
+KERNEL_LOADADDR := 0x00008000
+
+SIGNATURE:=$(shell printf "%.8s" $(SOURCE_DATE_EPOCH))
+
+define Build/boot-scr
+ rm -f $@-boot.scr
+ sed \
+ -e 's#@ROOT@#$(SIGNATURE)#g' \
+ -e 's#@DTB@#$(firstword $(DEVICE_DTS))#g' \
+ $(BOOT_SCRIPT).bootscript > $@-new.bootscript
+ mkimage -A arm -O linux -T script -C none -a 0 -e 0 -d $@-new.bootscript $@-boot.scr
+endef
+
+define Build/boot-img
+ rm -f $@.boot
+ mkfs.fat -C $@.boot $$(( $(CONFIG_TARGET_KERNEL_PARTSIZE) * 1024 ))
+ $(foreach dts,$(DEVICE_DTS), mcopy -i $@.boot $(KDIR)/image-$(dts).dtb ::$(dts).dtb;)
+ mcopy -i $@.boot $(IMAGE_KERNEL) ::$(KERNEL_NAME)
+ -mcopy -i $@.boot $@-boot.scr ::boot.scr
+endef
+
+define Build/boot-img-ext4
+ rm -fR $@.boot
+ mkdir -p $@.boot
+ $(foreach dts,$(DEVICE_DTS), $(CP) $(KDIR)/image-$(dts).dtb $@.boot/$(dts).dtb;)
+ $(CP) $(IMAGE_KERNEL) $@.boot/$(KERNEL_NAME)
+ -$(CP) $@-boot.scr $@.boot/boot.scr
+ make_ext4fs -J -l $(CONFIG_TARGET_KERNEL_PARTSIZE)M $@.bootimg $@.boot
+endef
+
+define Build/sdcard-img
+ SIGNATURE="$(SIGNATURE)" \
+ ./gen_mvebu_sdcard_img.sh $@ \
+ $(if $(UBOOT),$(STAGING_DIR_IMAGE)/$(UBOOT)) \
+ c $(CONFIG_TARGET_KERNEL_PARTSIZE) $@.boot \
+ 83 $(CONFIG_TARGET_ROOTFS_PARTSIZE) $(IMAGE_ROOTFS)
+endef
+
+define Build/sdcard-img-ext4
+ SIGNATURE="$(SIGNATURE)" \
+ ./gen_mvebu_sdcard_img.sh $@ \
+ $(if $(UBOOT),$(STAGING_DIR_IMAGE)/$(UBOOT)) \
+ 83 $(CONFIG_TARGET_KERNEL_PARTSIZE) $@.bootimg \
+ 83 $(CONFIG_TARGET_ROOTFS_PARTSIZE) $(IMAGE_ROOTFS)
+endef
+
+define Build/omnia-medkit-initramfs
+ $(TAR) -c -T /dev/null -f $@
+ rm -rf $(dir $(IMAGE_KERNEL))boot
+ mkdir -p $(dir $(IMAGE_KERNEL))boot/boot/
+ cp $(KDIR)/zImage-initramfs $(dir $(IMAGE_KERNEL))boot/boot/zImage
+ cp $(KDIR)/image-$(DEVICE_DTS).dtb $(dir $(IMAGE_KERNEL))boot/boot/dtb
+ $(TAR) -rp --numeric-owner --owner=0 --group=0 --sort=name \
+ $(if $(SOURCE_DATE_EPOCH),--mtime="@$(SOURCE_DATE_EPOCH)") \
+ --file=$@ -C $(dir $(IMAGE_KERNEL))boot/ .
+endef
+
+define Device/Default
+ PROFILES := Default
+ BOARD_NAME = $$(DEVICE_DTS)
+ KERNEL_NAME := zImage
+ KERNEL := kernel-bin | append-dtb | uImage none
+ IMAGES := sysupgrade.bin
+ IMAGE/factory.img := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-ubi | pad-to $$$$(PAGESIZE)
+ IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
+ SUPPORTED_DEVICES = $(subst _,$(comma),$(1))
+ UBINIZE_OPTS := -E 5
+ UBOOT :=
+ BOOT_SCRIPT :=
+endef
+DEVICE_VARS += BOOT_SCRIPT UBOOT
+
+define Device/Default-arm64
+ BOOT_SCRIPT := generic-arm64
+ DTS_DIR := $(DTS_DIR)/marvell
+ IMAGES := sdcard.img.gz
+ IMAGE/sdcard.img.gz := boot-scr | boot-img-ext4 | sdcard-img-ext4 | gzip | append-metadata
+ KERNEL_NAME := Image
+ KERNEL := kernel-bin
+endef
+
+define Device/NAND-128K
+ BLOCKSIZE := 128k
+ PAGESIZE := 2048
+ SUBPAGESIZE := 512
+ VID_HDR_OFFSET := 2048
+endef
+
+define Device/NAND-256K
+ BLOCKSIZE := 256k
+ PAGESIZE := 4096
+endef
+
+define Device/NAND-512K
+ BLOCKSIZE := 512k
+ PAGESIZE := 4096
+endef
+
+include cortex-a9.mk
+
+$(eval $(call BuildImage))
--- /dev/null
+# Standard Boot-Script
+# use only well-known variable names provided by U-Boot Distro boot
+# This script assumes that there is a boot partition,
+# and that the root partition is always the next one.
+
+# rootfs is always on the next partition
+setexpr openwrt_rootpart ${distro_bootpart} + 1
+
+# figure out partition uuid to pass to the kernel as root=
+part uuid ${devtype} ${devnum}:${openwrt_rootpart} uuid
+
+# generate bootargs (rootfs)
+setenv bootargs ${bootargs} root=PARTUUID=${uuid} rootfstype=auto rootwait
+
+# add console= option to bootargs, if any
+if test -n "${console}"; then
+ setenv bootargs ${bootargs} console=${console}
+fi
+
+echo "Booting Linux with ${bootargs}"
+load ${devtype} ${devnum}:${distro_bootpart} ${fdt_addr_r} @DTB@.dtb
+load ${devtype} ${devnum}:${distro_bootpart} ${kernel_addr_r} zImage
+bootz ${kernel_addr_r} - ${fdt_addr_r}
--- /dev/null
+#
+# Copyright (C) 2012-2016 OpenWrt.org
+# Copyright (C) 2016 LEDE-project.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+ifeq ($(SUBTARGET),cortexa9)
+
+define Device/linksys
+ $(Device/NAND-128K)
+ DEVICE_TITLE := Linksys $(1)
+ DEVICE_PACKAGES := swconfig wpad-basic
+ IMAGES += factory.img
+ KERNEL_SIZE := 6144k
+endef
+
+define Device/linksys_wrt1900ac
+ $(call Device/linksys,WRT1900AC (Mamba))
+ DEVICE_DTS := armada-xp-linksys-mamba
+ DEVICE_PACKAGES := kmod-ath9k
+ KERNEL_SIZE := 3072k
+ SUPPORTED_DEVICES := armada-xp-linksys-mamba linksys,mamba
+endef
+TARGET_DEVICES += linksys_wrt1900ac
+
+define Device/cznic_turris-omnia
+ KERNEL_INSTALL := 1
+ KERNEL := kernel-bin
+ KERNEL_INITRAMFS := kernel-bin
+ DEVICE_TITLE := Turris Omnia
+ DEVICE_PACKAGES := \
+ mkf2fs e2fsprogs kmod-fs-vfat kmod-nls-cp437 kmod-nls-iso8859-1 \
+ wpad-basic kmod-ath9k partx-utils kmod-i2c-core kmod-i2c-mux \
+ kmod-i2c-mux-pca954x
+ IMAGES := $$(IMAGE_PREFIX)-sysupgrade.img.gz omnia-medkit-$$(IMAGE_PREFIX)-initramfs.tar.gz
+ IMAGE/$$(IMAGE_PREFIX)-sysupgrade.img.gz := boot-img | sdcard-img | gzip | append-metadata
+ IMAGE/omnia-medkit-$$(IMAGE_PREFIX)-initramfs.tar.gz := omnia-medkit-initramfs | gzip
+ IMAGE_NAME = $$(2)
+ DEVICE_DTS := armada-385-turris-omnia
+ SUPPORTED_DEVICES += armada-385-turris-omnia
+endef
+TARGET_DEVICES += cznic_turris-omnia
+
+endif
--- /dev/null
+#!/usr/bin/env bash
+#
+# Copyright (C) 2016 Josua Mayer
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+
+usage() {
+ echo "$0 <outfile> [<bootloader> <type_partitionN> <size_partitionN> <img_partitionN>]?"
+}
+
+# always require first 2 or 3 arguments
+# then in pairs up to 8 more for a total of up to 4 partitions
+if [ $# -lt 1 ] || [ $# -gt 14 ] || [ $((($# - 1) % 3)) -ne 0 ]; then
+ if [ $# -lt 2 ] || [ $# -gt 15 ] || [ $((($# - 2) % 3)) -ne 0 ]; then
+ usage
+ exit 1
+ else
+ BOOTLOADER="$2"
+ fi
+fi
+
+set -e
+
+# parameters
+OUTFILE="$1"; shift
+if [ -n "$BOOTLOADER" ]; then
+ shift
+fi
+
+# generate image file
+printf "Creating $OUTFILE from /dev/zero: "
+dd if=/dev/zero of="$OUTFILE" bs=512 count=1 >/dev/null
+printf "Done\n"
+
+while [ "$#" -ge 3 ]; do
+ ptgen_args="$ptgen_args -t $1 -p $(($2 * 1024 + 256))"
+ parts="$parts$3 "
+ shift; shift; shift
+done
+
+head=16
+sect=63
+
+# create real partition table using fdisk
+printf "Creating partition table: "
+set `ptgen -o "$OUTFILE" -h $head -s $sect -l 1024 -S 0x$SIGNATURE $ptgen_args`
+printf "Done\n"
+
+# install bootloader
+if [ -n "$BOOTLOADER" ]; then
+ printf "Writing bootloader: "
+ dd of="$OUTFILE" if="$BOOTLOADER" bs=512 seek=1 conv=notrunc 2>/dev/null
+ printf "Done\n"
+fi
+
+i=1
+while [ "$#" -ge 2 ]; do
+ img="${parts%% *}"
+ parts="${parts#* }"
+
+ printf "Writing %s to partition %i: " "$img" $i
+ (
+ cat "$img"
+ # add padding to avoid leaving behind old overlay fs data
+ dd if=/dev/zero bs=128k count=1 2>/dev/null
+ ) | dd of="$OUTFILE" bs=512 seek=$(($1 / 512)) conv=notrunc 2>/dev/null
+ printf "Done\n"
+
+ let i=i+1
+ shift; shift
+done
--- /dev/null
+setenv bootargs "root=PARTUUID=@ROOT@-02 rw rootwait"
+
+if test -n "${console}"; then
+ setenv bootargs "${bootargs} ${console}"
+fi
+
+if mmc dev 0; then
+ setenv mmcdev 0
+elif mmc dev 1; then
+ setenv mmcdev 1
+fi
+
+load mmc ${mmcdev}:1 ${fdt_addr} @DTB@.dtb
+load mmc ${mmcdev}:1 ${kernel_addr} Image
+
+booti ${kernel_addr} - ${fdt_addr}
--- /dev/null
+--- a/arch/arm/boot/dts/armada-385-linksys.dtsi
++++ b/arch/arm/boot/dts/armada-385-linksys.dtsi
+@@ -237,11 +237,19 @@
+ &pcie1 {
+ /* Marvell 88W8864, 5GHz-only */
+ status = "okay";
++
++ mwlwifi {
++ marvell,2ghz = <0>;
++ };
+ };
+
+ &pcie2 {
+ /* Marvell 88W8864, 2GHz-only */
+ status = "okay";
++
++ mwlwifi {
++ marvell,5ghz = <0>;
++ };
+ };
+
+ &pinctrl {
+--- a/arch/arm/boot/dts/armada-385-linksys-caiman.dts
++++ b/arch/arm/boot/dts/armada-385-linksys-caiman.dts
+@@ -169,3 +169,205 @@
+ reg = <0x280000 0x680000>; /* 6.5MiB */
+ };
+ };
++
++&pcie1 {
++ mwlwifi {
++ marvell,chainmask = <2 2>;
++ marvell,powertable {
++ AU =
++ <36 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <40 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <44 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <48 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <52 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <56 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <60 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <64 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <100 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>,
++ <104 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>,
++ <108 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>,
++ <112 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>,
++ <116 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>,
++ <120 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>,
++ <124 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>,
++ <128 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>,
++ <132 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>,
++ <136 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>,
++ <140 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>,
++ <149 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x1a 0x1a 0x17 0x14 0 0xf>,
++ <153 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x1a 0x1a 0x17 0x14 0 0xf>,
++ <157 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x1a 0x1a 0x17 0x14 0 0xf>,
++ <161 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x1a 0x1a 0x17 0x14 0 0xf>,
++ <165 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x1a 0x1a 0x17 0x14 0 0xf>;
++ CA =
++ <36 0 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0 0xf>,
++ <40 0 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0 0xf>,
++ <44 0 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0 0xf>,
++ <48 0 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0 0xf>,
++ <52 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
++ <56 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
++ <60 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
++ <64 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
++ <100 0 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
++ <104 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
++ <108 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <112 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <116 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <120 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <124 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <128 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <132 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <136 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <140 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <149 0 0x1a 0x1a 0x18 0x17 0x19 0x19 0x17 0x15 0x18 0x18 0x17 0x14 0x15 0x15 0x15 0x14 0 0xf>,
++ <153 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x15 0x15 0x15 0x14 0 0xf>,
++ <157 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x15 0x15 0x15 0x14 0 0xf>,
++ <161 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x15 0x15 0x15 0x14 0 0xf>,
++ <165 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x15 0x15 0x15 0x14 0 0xf>;
++ CN =
++ <36 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <40 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <44 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <48 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <52 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <56 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <60 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <64 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <100 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <104 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <108 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <112 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <116 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <120 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <124 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <128 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <132 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <136 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <140 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <149 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0x11 0x11 0x11 0x11 0 0xf>,
++ <153 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0 0xf>,
++ <157 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0 0xf>,
++ <161 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0 0xf>,
++ <165 0 0x15 0x15 0x15 0x15 0x16 0x16 0x16 0x15 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0 0xf>;
++ ETSI =
++ <36 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <40 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <44 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <48 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <52 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <56 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <60 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <64 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <100 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <104 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <108 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <112 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <116 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <120 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <124 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <128 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <132 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <136 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <140 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
++ <149 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>;
++ FCC =
++ <36 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
++ <40 0 0x19 0x19 0x18 0x17 0x19 0x19 0x17 0x15 0x17 0x17 0x17 0x14 0x10 0x10 0x10 0x10 0 0xf>,
++ <44 0 0x19 0x19 0x18 0x17 0x19 0x19 0x17 0x15 0x17 0x17 0x17 0x14 0x10 0x10 0x10 0x10 0 0xf>,
++ <48 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x17 0x17 0x17 0x14 0x10 0x10 0x10 0x10 0 0xf>,
++ <52 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
++ <56 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
++ <60 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
++ <64 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
++ <100 0 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
++ <104 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
++ <108 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <112 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <116 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <120 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <124 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <128 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <132 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <136 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <140 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <149 0 0x1a 0x1a 0x18 0x17 0x19 0x19 0x17 0x15 0x18 0x18 0x17 0x14 0x15 0x15 0x15 0x14 0 0xf>,
++ <153 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x15 0x15 0x15 0x14 0 0xf>,
++ <157 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x15 0x15 0x15 0x14 0 0xf>,
++ <161 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x15 0x15 0x15 0x14 0 0xf>,
++ <165 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x15 0x15 0x15 0x14 0 0xf>;
++ };
++ };
++};
++
++&pcie2 {
++ mwlwifi {
++ marvell,chainmask = <2 2>;
++ marvell,powertable {
++ AU =
++ <1 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
++ <2 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
++ <3 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
++ <4 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
++ <5 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
++ <6 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
++ <7 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
++ <8 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
++ <9 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
++ <10 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
++ <11 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>;
++ CA =
++ <1 0 0x19 0x14 0x14 0x14 0x13 0x13 0x13 0x13 0x10 0x10 0x10 0x10 0x00 0x00 0x00 0x00 0 0xf>,
++ <2 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x00 0x00 0x00 0x00 0 0xf>,
++ <3 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x00 0x00 0x00 0x00 0 0xf>,
++ <4 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x00 0x00 0x00 0x00 0 0xf>,
++ <5 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x00 0x00 0x00 0x00 0 0xf>,
++ <6 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x00 0x00 0x00 0x00 0 0xf>,
++ <7 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x00 0x00 0x00 0x00 0 0xf>,
++ <8 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x00 0x00 0x00 0x00 0 0xf>,
++ <9 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x00 0x00 0x00 0x00 0 0xf>,
++ <10 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x00 0x00 0x00 0x00 0 0xf>,
++ <11 0 0x19 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0x13 0x13 0x13 0x13 0x00 0x00 0x00 0x00 0 0xf>;
++ CN =
++ <1 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
++ <2 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
++ <3 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
++ <4 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
++ <5 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
++ <6 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
++ <7 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
++ <8 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
++ <9 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
++ <10 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
++ <11 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
++ <12 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
++ <13 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
++ <14 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>;
++ ETSI =
++ <1 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
++ <2 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
++ <3 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
++ <4 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
++ <5 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
++ <6 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
++ <7 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
++ <8 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
++ <9 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
++ <10 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
++ <11 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
++ <12 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
++ <13 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>;
++ FCC =
++ <1 0 0x19 0x14 0x14 0x14 0x13 0x13 0x13 0x13 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>,
++ <2 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x0 0x0 0x0 0x0 0 0xf>,
++ <3 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x0 0x0 0x0 0x0 0 0xf>,
++ <4 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x0 0x0 0x0 0x0 0 0xf>,
++ <5 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x0 0x0 0x0 0x0 0 0xf>,
++ <6 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x0 0x0 0x0 0x0 0 0xf>,
++ <7 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x0 0x0 0x0 0x0 0 0xf>,
++ <8 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x0 0x0 0x0 0x0 0 0xf>,
++ <9 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x0 0x0 0x0 0x0 0 0xf>,
++ <10 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x0 0x0 0x0 0x0 0 0xf>,
++ <11 0 0x19 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0x13 0x13 0x13 0x13 0x0 0x0 0x0 0x0 0 0xf>;
++ };
++ };
++};
+--- a/arch/arm/boot/dts/armada-385-linksys-cobra.dts
++++ b/arch/arm/boot/dts/armada-385-linksys-cobra.dts
+@@ -169,3 +169,205 @@
+ reg = <0x280000 0x680000>; /* 6.5MiB */
+ };
+ };
++
++&pcie1 {
++ mwlwifi {
++ marvell,chainmask = <4 4>;
++ marvell,powertable {
++ AU =
++ <36 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <40 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <44 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <48 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <52 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <56 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <60 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <64 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <100 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++ <104 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++ <108 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++ <112 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++ <116 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++ <120 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++ <124 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++ <128 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++ <132 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++ <136 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++ <140 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++ <149 0 0x19 0x19 0x19 0x17 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0 0xf>,
++ <153 0 0x19 0x19 0x19 0x17 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0 0xf>,
++ <157 0 0x19 0x19 0x19 0x17 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0 0xf>,
++ <161 0 0x19 0x19 0x19 0x17 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0 0xf>,
++ <165 0 0x19 0x19 0x19 0x17 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0 0xf>;
++ CA =
++ <36 0 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>,
++ <40 0 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>,
++ <44 0 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>,
++ <48 0 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>,
++ <52 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
++ <56 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
++ <60 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
++ <64 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
++ <100 0 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
++ <104 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
++ <108 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <112 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <116 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <120 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <124 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <128 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <132 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <136 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <140 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <149 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>,
++ <153 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>,
++ <157 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>,
++ <161 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>,
++ <165 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>;
++ CN =
++ <36 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <40 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <44 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <48 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <52 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <56 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <60 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <64 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <100 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <104 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <108 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <112 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <116 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <120 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <124 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <128 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <132 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <136 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <140 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <149 0 0x14 0x14 0x14 0x14 0x13 0x13 0x13 0x13 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <153 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0x10 0x10 0x10 0x10 0 0xf>,
++ <157 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0x10 0x10 0x10 0x10 0 0xf>,
++ <161 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0x10 0x10 0x10 0x10 0 0xf>,
++ <165 0 0x13 0x13 0x13 0x13 0x13 0x13 0x13 0x13 0x14 0x14 0x14 0x14 0x10 0x10 0x10 0x10 0 0xf>;
++ ETSI =
++ <36 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <40 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <44 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <48 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <52 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <56 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <60 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <64 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <100 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <104 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <108 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <112 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <116 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <120 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <124 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <128 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <132 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <136 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <140 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <149 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>;
++ FCC =
++ <36 0 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0xf 0xf 0xf 0xf 0 0xf>,
++ <40 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0xf 0xf 0xf 0xf 0 0xf>,
++ <44 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0xf 0xf 0xf 0xf 0 0xf>,
++ <48 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0xf 0xf 0xf 0xf 0 0xf>,
++ <52 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
++ <56 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
++ <60 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
++ <64 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
++ <100 0 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
++ <104 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
++ <108 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <112 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <116 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <120 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <124 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <128 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <132 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <136 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <140 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <149 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>,
++ <153 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>,
++ <157 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>,
++ <161 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>,
++ <165 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>;
++ };
++ };
++};
++
++&pcie2 {
++ mwlwifi {
++ marvell,chainmask = <4 4>;
++ marvell,powertable {
++ AU =
++ <1 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <2 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <3 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <4 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <5 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <6 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <7 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <8 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <9 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <10 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <11 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>;
++ CA =
++ <1 0 0x17 0x10 0x10 0x10 0xf 0xf 0xf 0xf 0xe 0xe 0xe 0xe 0x0 0x0 0x0 0x0 0 0xf>,
++ <2 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
++ <3 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
++ <4 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
++ <5 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
++ <6 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
++ <7 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
++ <8 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
++ <9 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
++ <10 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
++ <11 0 0x17 0x12 0x12 0x12 0x13 0x13 0x13 0x13 0xf 0xf 0xf 0xf 0x0 0x0 0x0 0x0 0 0xf>;
++ CN =
++ <1 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <2 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <3 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <4 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <5 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <6 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <7 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <8 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <9 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <10 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <11 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <12 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <13 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <14 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>;
++ ETSI =
++ <1 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <2 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <3 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <4 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <5 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <6 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <7 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <8 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <9 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <10 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <11 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <12 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <13 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>;
++ FCC =
++ <1 0 0x17 0x10 0x10 0x10 0xf 0xf 0xf 0xf 0xe 0xe 0xe 0xe 0x0 0x0 0x0 0x0 0 0xf>,
++ <2 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
++ <3 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
++ <4 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
++ <5 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
++ <6 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
++ <7 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
++ <8 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
++ <9 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
++ <10 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
++ <11 0 0x17 0x12 0x12 0x12 0x13 0x13 0x13 0x13 0xf 0xf 0xf 0xf 0x0 0x0 0x0 0x0 0 0xf>;
++ };
++ };
++};
+--- a/arch/arm/boot/dts/armada-385-linksys-shelby.dts
++++ b/arch/arm/boot/dts/armada-385-linksys-shelby.dts
+@@ -169,3 +169,205 @@
+ reg = <0x280000 0x680000>; /* 6.5MiB */
+ };
+ };
++
++&pcie1 {
++ mwlwifi {
++ marvell,chainmask = <4 4>;
++ marvell,powertable {
++ AU =
++ <36 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <40 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <44 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <48 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <52 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <56 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <60 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <64 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <100 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++ <104 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++ <108 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++ <112 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++ <116 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++ <120 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++ <124 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++ <128 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++ <132 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++ <136 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++ <140 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++ <149 0 0x19 0x19 0x19 0x17 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0 0xf>,
++ <153 0 0x19 0x19 0x19 0x17 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0 0xf>,
++ <157 0 0x19 0x19 0x19 0x17 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0 0xf>,
++ <161 0 0x19 0x19 0x19 0x17 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0 0xf>,
++ <165 0 0x19 0x19 0x19 0x17 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0 0xf>;
++ CA =
++ <36 0 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>,
++ <40 0 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>,
++ <44 0 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>,
++ <48 0 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>,
++ <52 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
++ <56 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
++ <60 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
++ <64 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
++ <100 0 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
++ <104 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
++ <108 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <112 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <116 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <120 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <124 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <128 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <132 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <136 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <140 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <149 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>,
++ <153 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>,
++ <157 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>,
++ <161 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>,
++ <165 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>;
++ CN =
++ <36 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <40 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <44 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <48 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <52 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <56 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <60 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <64 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <100 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <104 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <108 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <112 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <116 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <120 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <124 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <128 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <132 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <136 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <140 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <149 0 0x14 0x14 0x14 0x14 0x13 0x13 0x13 0x13 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <153 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0x10 0x10 0x10 0x10 0 0xf>,
++ <157 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0x10 0x10 0x10 0x10 0 0xf>,
++ <161 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0x10 0x10 0x10 0x10 0 0xf>,
++ <165 0 0x13 0x13 0x13 0x13 0x13 0x13 0x13 0x13 0x14 0x14 0x14 0x14 0x10 0x10 0x10 0x10 0 0xf>;
++ ETSI =
++ <36 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <40 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <44 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <48 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <52 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <56 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <60 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <64 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <100 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <104 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <108 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <112 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <116 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <120 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <124 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <128 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <132 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <136 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <140 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
++ <149 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>;
++ FCC =
++ <36 0 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0xf 0xf 0xf 0xf 0 0xf>,
++ <40 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0xf 0xf 0xf 0xf 0 0xf>,
++ <44 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0xf 0xf 0xf 0xf 0 0xf>,
++ <48 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0xf 0xf 0xf 0xf 0 0xf>,
++ <52 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
++ <56 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
++ <60 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
++ <64 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
++ <100 0 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
++ <104 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
++ <108 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <112 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <116 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <120 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <124 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <128 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <132 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <136 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <140 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
++ <149 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>,
++ <153 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>,
++ <157 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>,
++ <161 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>,
++ <165 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>;
++ };
++ };
++};
++
++&pcie2 {
++ mwlwifi {
++ marvell,chainmask = <4 4>;
++ marvell,powertable {
++ AU =
++ <1 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <2 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <3 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <4 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <5 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <6 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <7 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <8 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <9 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <10 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <11 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>;
++ CA =
++ <1 0 0x17 0x10 0x10 0x10 0xf 0xf 0xf 0xf 0xe 0xe 0xe 0xe 0x0 0x0 0x0 0x0 0 0xf>,
++ <2 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
++ <3 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
++ <4 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
++ <5 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
++ <6 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
++ <7 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
++ <8 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
++ <9 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
++ <10 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
++ <11 0 0x17 0x12 0x12 0x12 0x13 0x13 0x13 0x13 0xf 0xf 0xf 0xf 0x0 0x0 0x0 0x0 0 0xf>;
++ CN =
++ <1 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <2 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <3 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <4 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <5 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <6 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <7 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <8 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <9 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <10 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <11 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <12 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <13 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <14 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>;
++ ETSI =
++ <1 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <2 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <3 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <4 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <5 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <6 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <7 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <8 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <9 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <10 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <11 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <12 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
++ <13 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>;
++ FCC =
++ <1 0 0x17 0x10 0x10 0x10 0xf 0xf 0xf 0xf 0xe 0xe 0xe 0xe 0x0 0x0 0x0 0x0 0 0xf>,
++ <2 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
++ <3 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
++ <4 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
++ <5 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
++ <6 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
++ <7 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
++ <8 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
++ <9 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
++ <10 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
++ <11 0 0x17 0x12 0x12 0x12 0x13 0x13 0x13 0x13 0xf 0xf 0xf 0xf 0x0 0x0 0x0 0x0 0 0xf>;
++ };
++ };
++};
+--- a/arch/arm/boot/dts/armada-385-linksys-rango.dts
++++ b/arch/arm/boot/dts/armada-385-linksys-rango.dts
+@@ -184,6 +184,18 @@
+ };
+ };
+
++&pcie1 {
++ mwlwifi {
++ marvell,chainmask = <4 4>;
++ };
++};
++
++&pcie2 {
++ mwlwifi {
++ marvell,chainmask = <4 4>;
++ };
++};
++
+ &sdhci {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdhci_pins>;
+--- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
++++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
+@@ -376,12 +376,100 @@
+ pcie@2,0 {
+ /* Port 0, Lane 1 */
+ status = "okay";
++
++ mwlwifi {
++ marvell,5ghz = <0>;
++ marvell,chainmask = <4 4>;
++ marvell,powertable {
++ FCC =
++ <1 0 0x17 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0xf 0xf 0xf 0xf 0x0 0x0 0x0 0x0 0 0xf>,
++ <2 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>,
++ <3 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>,
++ <4 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>,
++ <5 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>,
++ <6 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>,
++ <7 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>,
++ <8 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>,
++ <9 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>,
++ <10 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>,
++ <11 0 0x17 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>;
++
++ ETSI =
++ <1 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>,
++ <2 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>,
++ <3 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>,
++ <4 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>,
++ <5 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>,
++ <6 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>,
++ <7 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>,
++ <8 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>,
++ <9 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>,
++ <10 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>,
++ <11 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>,
++ <12 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>,
++ <13 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>;
++ };
++ };
+ };
+
+ /* Second mini-PCIe port */
+ pcie@3,0 {
+ /* Port 0, Lane 3 */
+ status = "okay";
++
++ mwlwifi {
++ marvell,2ghz = <0>;
++ marvell,chainmask = <4 4>;
++ marvell,powertable {
++ FCC =
++ <36 0 0x8 0x8 0x8 0x8 0x8 0x8 0x8 0x8 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>,
++ <40 0 0x8 0x8 0x8 0x8 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>,
++ <44 0 0x8 0x8 0x8 0x8 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>,
++ <48 0 0x8 0x8 0x8 0x8 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>,
++ <52 0 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0 0xf>,
++ <56 0 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0 0xf>,
++ <60 0 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0 0xf>,
++ <64 0 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0 0xf>,
++ <100 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++ <104 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++ <108 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++ <112 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++ <116 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++ <120 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++ <124 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++ <128 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++ <132 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++ <136 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++ <140 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
++ <149 0 0x16 0x16 0x16 0x16 0x14 0x14 0x14 0x14 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0 0xf>,
++ <153 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0 0xf>,
++ <157 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0 0xf>,
++ <161 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0 0xf>,
++ <165 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0 0xf>;
++
++ ETSI =
++ <36 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
++ <40 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
++ <44 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
++ <48 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
++ <52 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
++ <56 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
++ <60 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
++ <64 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
++ <100 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
++ <104 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
++ <108 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
++ <112 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
++ <116 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
++ <120 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
++ <124 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
++ <128 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
++ <132 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
++ <136 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
++ <140 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
++ <149 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>;
++ };
++ };
+ };
+ };
+
--- /dev/null
+--- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
++++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
+@@ -361,6 +361,16 @@
+ };
+ };
+ };
++
++ mvsw61xx {
++ compatible = "marvell,88e6172";
++ status = "okay";
++ reg = <0x10>;
++
++ mii-bus = <&mdio>;
++ cpu-port-0 = <5>;
++ cpu-port-1 = <6>;
++ };
+ };
+
+ &pciec {
+--- a/arch/arm/boot/dts/armada-385-linksys.dtsi
++++ b/arch/arm/boot/dts/armada-385-linksys.dtsi
+@@ -113,6 +113,18 @@
+ linux,default-trigger = "disk-activity";
+ };
+ };
++
++ mvsw61xx {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "marvell,88e6176";
++ status = "okay";
++ reg = <0x10>;
++
++ mii-bus = <&mdio>;
++ cpu-port-0 = <5>;
++ cpu-port-1 = <6>;
++ };
+ };
+
+ &ahci0 {
--- /dev/null
+From 172230195068703b78ad5733a09492f5d6814c09 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Tue, 28 Feb 2017 14:15:50 +0100
+Subject: [PATCH] ARM: dts: armada: Add default trigger for sata led
+
+In others board we have the sata led set to function
+with the sata led trigger by default.
+This patch makes the same for these board that have sata
+led but get disabled by not associating it to any trigger.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Acked-by: Jason Cooper <jason@lakedaemon.net>
+Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
+---
+ arch/arm/boot/dts/armada-385-linksys-caiman.dts | 1 +
+ arch/arm/boot/dts/armada-385-linksys-cobra.dts | 1 +
+ arch/arm/boot/dts/armada-xp-linksys-mamba.dts | 1 +
+ 3 files changed, 3 insertions(+)
+
+--- a/arch/arm/boot/dts/armada-385-linksys-caiman.dts
++++ b/arch/arm/boot/dts/armada-385-linksys-caiman.dts
+@@ -100,6 +100,7 @@
+
+ sata {
+ label = "caiman:white:sata";
++ linux,default-trigger = "disk-activity";
+ };
+ };
+
+--- a/arch/arm/boot/dts/armada-385-linksys-cobra.dts
++++ b/arch/arm/boot/dts/armada-385-linksys-cobra.dts
+@@ -100,6 +100,7 @@
+
+ sata {
+ label = "cobra:white:sata";
++ linux,default-trigger = "disk-activity";
+ };
+ };
+
--- /dev/null
+Newer Linksys boards might come with a Winbond W29N02GV which can be
+configured in different ways. Make sure we configure it the same way
+as the older chips so everything keeps working.
+
+Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
+
+--- a/arch/arm/boot/dts/armada-385-linksys.dtsi
++++ b/arch/arm/boot/dts/armada-385-linksys.dtsi
+@@ -185,6 +185,8 @@
+ /* 128MiB or 256MiB */
+ status = "okay";
+ num-cs = <1>;
++ nand-ecc-strength = <4>;
++ nand-ecc-step-size = <512>;
+ marvell,nand-keep-config;
+ marvell,nand-enable-arbiter;
+ nand-on-flash-bbt;
--- /dev/null
+From 71270226b14733a4b1f2cde58ea9265caa50b38d Mon Sep 17 00:00:00 2001
+From: Adrian Panella <ianchi74@outlook.com>
+Date: Thu, 9 Mar 2017 09:37:17 +0100
+Subject: [PATCH 67/69] generic: Mangle bootloader's kernel arguments
+
+The command-line arguments provided by the boot loader will be
+appended to a new device tree property: bootloader-args.
+If there is a property "append-rootblock" in DT under /chosen
+and a root= option in bootloaders command line it will be parsed
+and added to DT bootargs with the form: <append-rootblock>XX.
+Only command line ATAG will be processed, the rest of the ATAGs
+sent by bootloader will be ignored.
+This is usefull in dual boot systems, to get the current root partition
+without afecting the rest of the system.
+
+Signed-off-by: Adrian Panella <ianchi74@outlook.com>
+
+This patch has been modified to be mvebu specific. The original patch
+did not pass the bootloader cmdline on if no append-rootblock stanza
+was found, resulting in blank cmdline and failure to boot.
+
+Signed-off-by: Michael Gray <michael.gray@lantisproject.com>
+---
+ arch/arm/Kconfig | 11 +++++
+ arch/arm/boot/compressed/atags_to_fdt.c | 72 ++++++++++++++++++++++++++++++++-
+ init/main.c | 16 ++++++++
+ 3 files changed, 98 insertions(+), 1 deletion(-)
+
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -1934,6 +1934,17 @@ config ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEN
+ The command-line arguments provided by the boot loader will be
+ appended to the the device tree bootargs property.
+
++config ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE
++ bool "Append rootblock parsing bootloader's kernel arguments"
++ help
++ The command-line arguments provided by the boot loader will be
++ appended to a new device tree property: bootloader-args.
++ If there is a property "append-rootblock" in DT under /chosen
++ and a root= option in bootloaders command line it will be parsed
++ and added to DT bootargs with the form: <append-rootblock>XX.
++ Only command line ATAG will be processed, the rest of the ATAGs
++ sent by bootloader will be ignored.
++
+ endchoice
+
+ config CMDLINE
+--- a/arch/arm/boot/compressed/atags_to_fdt.c
++++ b/arch/arm/boot/compressed/atags_to_fdt.c
+@@ -4,6 +4,8 @@
+
+ #if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND)
+ #define do_extend_cmdline 1
++#elif defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
++#define do_extend_cmdline 1
+ #else
+ #define do_extend_cmdline 0
+ #endif
+@@ -67,6 +69,65 @@ static uint32_t get_cell_size(const void
+ return cell_size;
+ }
+
++#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
++
++static char *append_rootblock(char *dest, const char *str, int len, void *fdt)
++{
++ char *ptr, *end;
++ char *root="root=";
++ int i, l;
++ const char *rootblock;
++
++ //ARM doesn't have __HAVE_ARCH_STRSTR, so search manually
++ ptr = str - 1;
++
++ do {
++ //first find an 'r' at the begining or after a space
++ do {
++ ptr++;
++ ptr = strchr(ptr, 'r');
++ if(!ptr) return dest;
++
++ } while (ptr != str && *(ptr-1) != ' ');
++
++ //then check for the rest
++ for(i = 1; i <= 4; i++)
++ if(*(ptr+i) != *(root+i)) break;
++
++ } while (i != 5);
++
++ end = strchr(ptr, ' ');
++ end = end ? (end - 1) : (strchr(ptr, 0) - 1);
++
++ //find partition number (assumes format root=/dev/mtdXX | /dev/mtdblockXX | yy:XX )
++ for( i = 0; end >= ptr && *end >= '0' && *end <= '9'; end--, i++);
++ ptr = end + 1;
++
++ /* if append-rootblock property is set use it to append to command line */
++ rootblock = getprop(fdt, "/chosen", "append-rootblock", &l);
++ if(rootblock != NULL) {
++ if(*dest != ' ') {
++ *dest = ' ';
++ dest++;
++ len++;
++ }
++ if (len + l + i <= COMMAND_LINE_SIZE) {
++ memcpy(dest, rootblock, l);
++ dest += l - 1;
++ memcpy(dest, ptr, i);
++ dest += i;
++ }
++ } else {
++ len = strlen(str);
++ if (len + 1 < COMMAND_LINE_SIZE) {
++ memcpy(dest, str, len);
++ dest += len;
++ }
++ }
++ return dest;
++}
++#endif
++
+ static void merge_fdt_bootargs(void *fdt, const char *fdt_cmdline)
+ {
+ char cmdline[COMMAND_LINE_SIZE];
+@@ -86,12 +147,21 @@ static void merge_fdt_bootargs(void *fdt
+
+ /* and append the ATAG_CMDLINE */
+ if (fdt_cmdline) {
++
++#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
++ //save original bootloader args
++ //and append ubi.mtd with root partition number to current cmdline
++ setprop_string(fdt, "/chosen", "bootloader-args", fdt_cmdline);
++ ptr = append_rootblock(ptr, fdt_cmdline, len, fdt);
++
++#else
+ len = strlen(fdt_cmdline);
+ if (ptr - cmdline + len + 2 < COMMAND_LINE_SIZE) {
+ *ptr++ = ' ';
+ memcpy(ptr, fdt_cmdline, len);
+ ptr += len;
+ }
++#endif
+ }
+ *ptr = '\0';
+
+@@ -148,7 +218,9 @@ int atags_to_fdt(void *atag_list, void *
+ else
+ setprop_string(fdt, "/chosen", "bootargs",
+ atag->u.cmdline.cmdline);
+- } else if (atag->hdr.tag == ATAG_MEM) {
++ }
++#ifndef CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE
++ else if (atag->hdr.tag == ATAG_MEM) {
+ if (memcount >= sizeof(mem_reg_property)/4)
+ continue;
+ if (!atag->u.mem.size)
+@@ -187,6 +259,10 @@ int atags_to_fdt(void *atag_list, void *
+ setprop(fdt, "/memory", "reg", mem_reg_property,
+ 4 * memcount * memsize);
+ }
++#else
++
++ }
++#endif
+
+ return fdt_pack(fdt);
+ }
+--- a/init/main.c
++++ b/init/main.c
+@@ -95,6 +95,10 @@
+ #include <asm/sections.h>
+ #include <asm/cacheflush.h>
+
++#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
++#include <linux/of.h>
++#endif
++
+ static int kernel_init(void *);
+
+ extern void init_IRQ(void);
+@@ -573,6 +577,18 @@ asmlinkage __visible void __init start_k
+ page_alloc_init();
+
+ pr_notice("Kernel command line: %s\n", boot_command_line);
++
++#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
++ //Show bootloader's original command line for reference
++ if(of_chosen) {
++ const char *prop = of_get_property(of_chosen, "bootloader-args", NULL);
++ if(prop)
++ pr_notice("Bootloader command line (ignored): %s\n", prop);
++ else
++ pr_notice("Bootloader command line not present\n");
++ }
++#endif
++
+ /* parameters may set static keys */
+ jump_label_init();
+ parse_early_param();
--- /dev/null
+The WRT1900AC among other Linksys routers uses a dual-firmware layout.
+Dynamically rename the active partition to "ubi".
+
+Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
+
+--- a/drivers/mtd/ofpart.c
++++ b/drivers/mtd/ofpart.c
+@@ -25,6 +25,8 @@ static bool node_has_compatible(struct d
+ return of_get_property(pp, "compatible", NULL);
+ }
+
++static int mangled_rootblock;
++
+ static int parse_fixed_partitions(struct mtd_info *master,
+ const struct mtd_partition **pparts,
+ struct mtd_part_parser_data *data)
+@@ -33,6 +35,7 @@ static int parse_fixed_partitions(struct
+ struct device_node *mtd_node;
+ struct device_node *ofpart_node;
+ const char *partname;
++ const char *owrtpart = "ubi";
+ struct device_node *pp;
+ int nr_parts, i, ret = 0;
+ bool dedicated = true;
+@@ -110,9 +113,13 @@ static int parse_fixed_partitions(struct
+ parts[i].size = of_read_number(reg + a_cells, s_cells);
+ parts[i].of_node = pp;
+
+- partname = of_get_property(pp, "label", &len);
+- if (!partname)
+- partname = of_get_property(pp, "name", &len);
++ if (mangled_rootblock && (i == mangled_rootblock)) {
++ partname = owrtpart;
++ } else {
++ partname = of_get_property(pp, "label", &len);
++ if (!partname)
++ partname = of_get_property(pp, "name", &len);
++ }
+ parts[i].name = partname;
+
+ if (of_get_property(pp, "read-only", &len))
+@@ -219,6 +226,18 @@ static int __init ofpart_parser_init(voi
+ return 0;
+ }
+
++static int __init active_root(char *str)
++{
++ get_option(&str, &mangled_rootblock);
++
++ if (!mangled_rootblock)
++ return 1;
++
++ return 1;
++}
++
++__setup("mangled_rootblock=", active_root);
++
+ static void __exit ofpart_parser_exit(void)
+ {
+ deregister_mtd_parser(&ofpart_parser);
--- /dev/null
+--- a/arch/arm/boot/dts/armada-xp.dtsi
++++ b/arch/arm/boot/dts/armada-xp.dtsi
+@@ -274,12 +274,10 @@
+ };
+
+ &i2c0 {
+- compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c";
+ reg = <0x11000 0x100>;
+ };
+
+ &i2c1 {
+- compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c";
+ reg = <0x11100 0x100>;
+ };
+
--- /dev/null
+Remove a BUG() call that would crash on a race condition that should
+otherwise be harmless.
+
+--- a/drivers/mtd/nand/pxa3xx_nand.c
++++ b/drivers/mtd/nand/pxa3xx_nand.c
+@@ -727,7 +727,6 @@ static void handle_data_pio(struct pxa3x
+ default:
+ dev_err(&info->pdev->dev, "%s: invalid state %d\n", __func__,
+ info->state);
+- BUG();
+ }
+
+ /* Update buffer pointers for multi-page read/write */
--- /dev/null
+--- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
++++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
+@@ -200,7 +200,6 @@
+ nand@d0000 {
+ status = "okay";
+ num-cs = <1>;
+- marvell,nand-keep-config;
+ marvell,nand-enable-arbiter;
+ nand-on-flash-bbt;
+ nand-ecc-strength = <4>;
--- /dev/null
+Revert "mtd: pxa3xx-nand: handle PIO in threaded interrupt"
+
+This reverts commit 24542257a3b987025d4b998ec2d15e556c98ad3f
+This upstream change has been causing spurious timeouts on accesses
+to the NAND flash if something else on the system is causing
+significant latency.
+
+Nothing guarantees that the thread will run in time, so the
+usual timeout is unreliable.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+
+--- a/drivers/mtd/nand/pxa3xx_nand.c
++++ b/drivers/mtd/nand/pxa3xx_nand.c
+@@ -791,24 +791,11 @@ static void start_data_dma(struct pxa3xx
+ __func__, direction, info->dma_cookie, info->sg.length);
+ }
+
+-static irqreturn_t pxa3xx_nand_irq_thread(int irq, void *data)
+-{
+- struct pxa3xx_nand_info *info = data;
+-
+- handle_data_pio(info);
+-
+- info->state = STATE_CMD_DONE;
+- nand_writel(info, NDSR, NDSR_WRDREQ | NDSR_RDDREQ);
+-
+- return IRQ_HANDLED;
+-}
+-
+ static irqreturn_t pxa3xx_nand_irq(int irq, void *devid)
+ {
+ struct pxa3xx_nand_info *info = devid;
+ unsigned int status, is_completed = 0, is_ready = 0;
+ unsigned int ready, cmd_done;
+- irqreturn_t ret = IRQ_HANDLED;
+
+ if (info->cs == 0) {
+ ready = NDSR_FLASH_RDY;
+@@ -850,8 +837,7 @@ static irqreturn_t pxa3xx_nand_irq(int i
+ } else {
+ info->state = (status & NDSR_RDDREQ) ?
+ STATE_PIO_READING : STATE_PIO_WRITING;
+- ret = IRQ_WAKE_THREAD;
+- goto NORMAL_IRQ_EXIT;
++ handle_data_pio(info);
+ }
+ }
+ if (status & cmd_done) {
+@@ -896,7 +882,7 @@ static irqreturn_t pxa3xx_nand_irq(int i
+ if (is_ready)
+ complete(&info->dev_ready);
+ NORMAL_IRQ_EXIT:
+- return ret;
++ return IRQ_HANDLED;
+ }
+
+ static inline int is_buf_blank(uint8_t *buf, size_t len)
+@@ -1865,9 +1851,7 @@ static int alloc_nand_resource(struct pl
+ /* initialize all interrupts to be disabled */
+ disable_int(info, NDSR_MASK);
+
+- ret = request_threaded_irq(irq, pxa3xx_nand_irq,
+- pxa3xx_nand_irq_thread, IRQF_ONESHOT,
+- pdev->name, info);
++ ret = request_irq(irq, pxa3xx_nand_irq, 0, pdev->name, info);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to request IRQ: %d\n", ret);
+ goto fail_free_buf;
--- /dev/null
+--- a/arch/arm/boot/dts/armada-388-rd.dts
++++ b/arch/arm/boot/dts/armada-388-rd.dts
+@@ -140,6 +140,16 @@
+ compatible = "st,m25p128", "jedec,spi-nor";
+ reg = <0>; /* Chip select 0 */
+ spi-max-frequency = <108000000>;
++
++ partition@0 {
++ label = "uboot";
++ reg = <0 0x400000>;
++ };
++
++ partition@1 {
++ label = "firmware";
++ reg = <0x400000 0xc00000>;
++ };
+ };
+ };
+
--- /dev/null
+From 9861f93a59142a3131870df2521eb2deb73026d7 Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime.ripard@free-electrons.com>
+Date: Tue, 13 Jan 2015 11:14:09 +0100
+Subject: [PATCH 2/2] ARM: mvebu: 385-ap: Add partitions
+
+Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+---
+ arch/arm/boot/dts/armada-385-db-ap.dts | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+--- a/arch/arm/boot/dts/armada-385-db-ap.dts
++++ b/arch/arm/boot/dts/armada-385-db-ap.dts
+@@ -181,19 +181,19 @@
+ #size-cells = <1>;
+
+ partition@0 {
+- label = "U-Boot";
++ label = "u-boot";
+ reg = <0x00000000 0x00800000>;
+ read-only;
+ };
+
+ partition@800000 {
+- label = "uImage";
++ label = "kernel";
+ reg = <0x00800000 0x00400000>;
+ read-only;
+ };
+
+ partition@c00000 {
+- label = "Root";
++ label = "ubi";
+ reg = <0x00c00000 0x3f400000>;
+ };
+ };
--- /dev/null
+--- a/arch/arm/boot/dts/armada-388-clearfog.dts
++++ b/arch/arm/boot/dts/armada-388-clearfog.dts
+@@ -129,6 +129,18 @@
+ };
+ };
+
++ mvsw61xx {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "marvell,88e6176";
++ status = "okay";
++ reg = <0x4>;
++ is-indirect;
++
++ mii-bus = <&mdio>;
++ cpu-port-0 = <5>;
++ };
++
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-0 = <&rear_button_pins>;
--- /dev/null
+--- a/arch/arm/boot/dts/armada-385-linksys.dtsi
++++ b/arch/arm/boot/dts/armada-385-linksys.dtsi
+@@ -196,6 +196,7 @@
+ status = "okay";
+
+ switch@0 {
++ status = "disabled";
+ compatible = "marvell,mv88e6085";
+ #address-cells = <1>;
+ #size-cells = <0>;
+--- a/arch/arm/boot/dts/armada-388-clearfog.dts
++++ b/arch/arm/boot/dts/armada-388-clearfog.dts
+@@ -202,6 +202,7 @@
+ status = "okay";
+
+ switch@4 {
++ status = "disabled";
+ compatible = "marvell,mv88e6085";
+ #address-cells = <1>;
+ #size-cells = <0>;
+--- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
++++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
+@@ -516,6 +516,7 @@
+ status = "okay";
+
+ switch@0 {
++ status = "disabled";
+ compatible = "marvell,mv88e6085";
+ #address-cells = <1>;
+ #size-cells = <0>;
--- /dev/null
+--- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
++++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
+@@ -563,3 +563,7 @@
+ };
+ };
+ };
++
++&coherencyfab {
++ broken-idle;
++};
--- /dev/null
+The hardware queue scheduling is apparently configured with fixed
+priorities, which creates a nasty fairness issue where traffic from one
+CPU can starve traffic from all other CPUs.
+
+Work around this issue by forcing all tx packets to go through one CPU,
+until this issue is fixed properly.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+--- a/drivers/net/ethernet/marvell/mvneta.c
++++ b/drivers/net/ethernet/marvell/mvneta.c
+@@ -3960,6 +3960,15 @@ static int mvneta_ethtool_set_wol(struct
+ return ret;
+ }
+
++static u16 mvneta_select_queue(struct net_device *dev, struct sk_buff *skb,
++ void *accel_priv,
++ select_queue_fallback_t fallback)
++{
++ /* XXX: hardware queue scheduling is broken,
++ * use only one queue until it is fixed */
++ return 0;
++}
++
+ static const struct net_device_ops mvneta_netdev_ops = {
+ .ndo_open = mvneta_open,
+ .ndo_stop = mvneta_stop,
+@@ -3970,6 +3979,7 @@ static const struct net_device_ops mvnet
+ .ndo_fix_features = mvneta_fix_features,
+ .ndo_get_stats64 = mvneta_get_stats64,
+ .ndo_do_ioctl = mvneta_ioctl,
++ .ndo_select_queue = mvneta_select_queue,
+ };
+
+ static const struct ethtool_ops mvneta_eth_tool_ops = {
--- /dev/null
+From c28b2d367da8a471482e6a4aa8337ab6369a80c2 Mon Sep 17 00:00:00 2001
+From: Russell King <rmk+kernel@arm.linux.org.uk>
+Date: Sat, 3 Oct 2015 09:13:05 +0100
+Subject: cpuidle: mvebu: indicate failure to enter deeper sleep states
+
+The cpuidle ->enter method expects the return value to be the sleep
+state we entered. Returning negative numbers or other codes is not
+permissible since coupled CPU idle was merged.
+
+At least some of the mvebu_v7_cpu_suspend() implementations return the
+value from cpu_suspend(), which returns zero if the CPU vectors back
+into the kernel via cpu_resume() (the success case), or the non-zero
+return value of the suspend actor, or one (failure cases).
+
+We do not want to be returning the failure case value back to CPU idle
+as that indicates that we successfully entered one of the deeper idle
+states. Always return zero instead, indicating that we slept for the
+shortest amount of time.
+
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+---
+ drivers/cpuidle/cpuidle-mvebu-v7.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/cpuidle/cpuidle-mvebu-v7.c
++++ b/drivers/cpuidle/cpuidle-mvebu-v7.c
+@@ -39,8 +39,12 @@ static int mvebu_v7_enter_idle(struct cp
+ ret = mvebu_v7_cpu_suspend(deepidle);
+ cpu_pm_exit();
+
++ /*
++ * If we failed to enter the desired state, indicate that we
++ * slept lightly.
++ */
+ if (ret)
+- return ret;
++ return 0;
+
+ return index;
+ }
--- /dev/null
+From 287b9df160b6159f8d385424904f8bac501280c1 Mon Sep 17 00:00:00 2001
+From: Russell King <rmk+kernel@armlinux.org.uk>
+Date: Sat, 9 Jul 2016 10:58:16 +0100
+Subject: pci: mvebu: time out reset on link up
+
+If the port reports that the link is up while we are resetting, there's
+little point in waiting for the full duration.
+
+Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
+---
+ drivers/pci/host/pci-mvebu.c | 20 ++++++++++++++------
+ 1 file changed, 14 insertions(+), 6 deletions(-)
+
+--- a/drivers/pci/host/pci-mvebu.c
++++ b/drivers/pci/host/pci-mvebu.c
+@@ -1167,6 +1167,7 @@ static int mvebu_pcie_powerup(struct mve
+
+ if (port->reset_gpio) {
+ u32 reset_udelay = PCI_PM_D3COLD_WAIT * 1000;
++ unsigned int i;
+
+ of_property_read_u32(port->dn, "reset-delay-us",
+ &reset_udelay);
+@@ -1174,7 +1175,13 @@ static int mvebu_pcie_powerup(struct mve
+ udelay(100);
+
+ gpiod_set_value_cansleep(port->reset_gpio, 0);
+- msleep(reset_udelay / 1000);
++ for (i = 0; i < reset_udelay; i += 1000) {
++ if (mvebu_pcie_link_up(port))
++ break;
++ msleep(1);
++ }
++
++ printk("%s: reset completed in %dus\n", port->name, i);
+ }
+
+ return 0;
+@@ -1261,15 +1268,16 @@ static int mvebu_pcie_probe(struct platf
+ if (!child)
+ continue;
+
+- ret = mvebu_pcie_powerup(port);
+- if (ret < 0)
+- continue;
+-
+ port->base = mvebu_pcie_map_registers(pdev, child, port);
+ if (IS_ERR(port->base)) {
+ dev_err(dev, "%s: cannot map registers\n", port->name);
+ port->base = NULL;
+- mvebu_pcie_powerdown(port);
++ continue;
++ }
++
++ ret = mvebu_pcie_powerup(port);
++ if (ret < 0) {
++ port->base = NULL;
+ continue;
+ }
+
--- /dev/null
+From e76632d118659347d9261a4470d9f60bfbe0044c Mon Sep 17 00:00:00 2001
+From: Russell King <rmk+kernel@arm.linux.org.uk>
+Date: Sun, 13 Sep 2015 01:06:31 +0100
+Subject: sfp: display SFP module information
+
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+---
+ drivers/net/phy/sfp.c | 254 +++++++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 253 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/phy/sfp.c
++++ b/drivers/net/phy/sfp.c
+@@ -265,6 +265,184 @@ static unsigned int sfp_check(void *buf,
+ return check;
+ }
+
++static const char *sfp_link_len(char *buf, size_t size, unsigned int length,
++ unsigned int multiplier)
++{
++ if (length == 0)
++ return "unsupported/unspecified";
++
++ if (length == 255) {
++ *buf++ = '>';
++ size -= 1;
++ length -= 1;
++ }
++
++ length *= multiplier;
++
++ if (length >= 1000)
++ snprintf(buf, size, "%u.%0*ukm",
++ length / 1000,
++ multiplier > 100 ? 1 :
++ multiplier > 10 ? 2 : 3,
++ length % 1000);
++ else
++ snprintf(buf, size, "%um", length);
++
++ return buf;
++}
++
++struct bitfield {
++ unsigned int mask;
++ unsigned int val;
++ const char *str;
++};
++
++static const struct bitfield sfp_options[] = {
++ {
++ .mask = SFP_OPTIONS_HIGH_POWER_LEVEL,
++ .val = SFP_OPTIONS_HIGH_POWER_LEVEL,
++ .str = "hpl",
++ }, {
++ .mask = SFP_OPTIONS_PAGING_A2,
++ .val = SFP_OPTIONS_PAGING_A2,
++ .str = "paginga2",
++ }, {
++ .mask = SFP_OPTIONS_RETIMER,
++ .val = SFP_OPTIONS_RETIMER,
++ .str = "retimer",
++ }, {
++ .mask = SFP_OPTIONS_COOLED_XCVR,
++ .val = SFP_OPTIONS_COOLED_XCVR,
++ .str = "cooled",
++ }, {
++ .mask = SFP_OPTIONS_POWER_DECL,
++ .val = SFP_OPTIONS_POWER_DECL,
++ .str = "powerdecl",
++ }, {
++ .mask = SFP_OPTIONS_RX_LINEAR_OUT,
++ .val = SFP_OPTIONS_RX_LINEAR_OUT,
++ .str = "rxlinear",
++ }, {
++ .mask = SFP_OPTIONS_RX_DECISION_THRESH,
++ .val = SFP_OPTIONS_RX_DECISION_THRESH,
++ .str = "rxthresh",
++ }, {
++ .mask = SFP_OPTIONS_TUNABLE_TX,
++ .val = SFP_OPTIONS_TUNABLE_TX,
++ .str = "tunabletx",
++ }, {
++ .mask = SFP_OPTIONS_RATE_SELECT,
++ .val = SFP_OPTIONS_RATE_SELECT,
++ .str = "ratesel",
++ }, {
++ .mask = SFP_OPTIONS_TX_DISABLE,
++ .val = SFP_OPTIONS_TX_DISABLE,
++ .str = "txdisable",
++ }, {
++ .mask = SFP_OPTIONS_TX_FAULT,
++ .val = SFP_OPTIONS_TX_FAULT,
++ .str = "txfault",
++ }, {
++ .mask = SFP_OPTIONS_LOS_INVERTED,
++ .val = SFP_OPTIONS_LOS_INVERTED,
++ .str = "los-",
++ }, {
++ .mask = SFP_OPTIONS_LOS_NORMAL,
++ .val = SFP_OPTIONS_LOS_NORMAL,
++ .str = "los+",
++ }, { }
++};
++
++static const struct bitfield diagmon[] = {
++ {
++ .mask = SFP_DIAGMON_DDM,
++ .val = SFP_DIAGMON_DDM,
++ .str = "ddm",
++ }, {
++ .mask = SFP_DIAGMON_INT_CAL,
++ .val = SFP_DIAGMON_INT_CAL,
++ .str = "intcal",
++ }, {
++ .mask = SFP_DIAGMON_EXT_CAL,
++ .val = SFP_DIAGMON_EXT_CAL,
++ .str = "extcal",
++ }, {
++ .mask = SFP_DIAGMON_RXPWR_AVG,
++ .val = SFP_DIAGMON_RXPWR_AVG,
++ .str = "rxpwravg",
++ }, { }
++};
++
++static const char *sfp_bitfield(char *out, size_t outsz, const struct bitfield *bits, unsigned int val)
++{
++ char *p = out;
++ int n;
++
++ *p = '\0';
++ while (bits->mask) {
++ if ((val & bits->mask) == bits->val) {
++ n = snprintf(p, outsz, "%s%s",
++ out != p ? ", " : "",
++ bits->str);
++ if (n == outsz)
++ break;
++ p += n;
++ outsz -= n;
++ }
++ bits++;
++ }
++
++ return out;
++}
++
++static const char *sfp_connector(unsigned int connector)
++{
++ switch (connector) {
++ case SFP_CONNECTOR_UNSPEC:
++ return "unknown/unspecified";
++ case SFP_CONNECTOR_SC:
++ return "SC";
++ case SFP_CONNECTOR_FIBERJACK:
++ return "Fiberjack";
++ case SFP_CONNECTOR_LC:
++ return "LC";
++ case SFP_CONNECTOR_MT_RJ:
++ return "MT-RJ";
++ case SFP_CONNECTOR_MU:
++ return "MU";
++ case SFP_CONNECTOR_SG:
++ return "SG";
++ case SFP_CONNECTOR_OPTICAL_PIGTAIL:
++ return "Optical pigtail";
++ case SFP_CONNECTOR_HSSDC_II:
++ return "HSSDC II";
++ case SFP_CONNECTOR_COPPER_PIGTAIL:
++ return "Copper pigtail";
++ default:
++ return "unknown";
++ }
++}
++
++static const char *sfp_encoding(unsigned int encoding)
++{
++ switch (encoding) {
++ case SFP_ENCODING_UNSPEC:
++ return "unspecified";
++ case SFP_ENCODING_8472_64B66B:
++ return "64b66b";
++ case SFP_ENCODING_8B10B:
++ return "8b10b";
++ case SFP_ENCODING_4B5B:
++ return "4b5b";
++ case SFP_ENCODING_NRZ:
++ return "NRZ";
++ case SFP_ENCODING_8472_MANCHESTER:
++ return "MANCHESTER";
++ default:
++ return "unknown";
++ }
++}
++
+ /* Helpers */
+ static void sfp_module_tx_disable(struct sfp *sfp)
+ {
+@@ -433,6 +611,7 @@ static int sfp_sm_mod_probe(struct sfp *
+ char sn[17];
+ char date[9];
+ char rev[5];
++ char options[80];
+ u8 check;
+ int err;
+
+@@ -476,10 +655,83 @@ static int sfp_sm_mod_probe(struct sfp *
+ rev[4] = '\0';
+ memcpy(sn, sfp->id.ext.vendor_sn, 16);
+ sn[16] = '\0';
+- memcpy(date, sfp->id.ext.datecode, 8);
++ date[0] = sfp->id.ext.datecode[4];
++ date[1] = sfp->id.ext.datecode[5];
++ date[2] = '-';
++ date[3] = sfp->id.ext.datecode[2];
++ date[4] = sfp->id.ext.datecode[3];
++ date[5] = '-';
++ date[6] = sfp->id.ext.datecode[0];
++ date[7] = sfp->id.ext.datecode[1];
+ date[8] = '\0';
+
+ dev_info(sfp->dev, "module %s %s rev %s sn %s dc %s\n", vendor, part, rev, sn, date);
++ dev_info(sfp->dev, " %s connector, encoding %s, nominal bitrate %u.%uGbps +%u%% -%u%%\n",
++ sfp_connector(sfp->id.base.connector),
++ sfp_encoding(sfp->id.base.encoding),
++ sfp->id.base.br_nominal / 10,
++ sfp->id.base.br_nominal % 10,
++ sfp->id.ext.br_max, sfp->id.ext.br_min);
++ dev_info(sfp->dev, " 1000BaseSX%c 1000BaseLX%c 1000BaseCX%c 1000BaseT%c 100BaseTLX%c 1000BaseFX%c BaseBX10%c BasePX%c\n",
++ sfp->id.base.e1000_base_sx ? '+' : '-',
++ sfp->id.base.e1000_base_lx ? '+' : '-',
++ sfp->id.base.e1000_base_cx ? '+' : '-',
++ sfp->id.base.e1000_base_t ? '+' : '-',
++ sfp->id.base.e100_base_lx ? '+' : '-',
++ sfp->id.base.e100_base_fx ? '+' : '-',
++ sfp->id.base.e_base_bx10 ? '+' : '-',
++ sfp->id.base.e_base_px ? '+' : '-');
++ dev_info(sfp->dev, " 10GBaseSR%c 10GBaseLR%c 10GBaseLRM%c 10GBaseER%c\n",
++ sfp->id.base.e10g_base_sr ? '+' : '-',
++ sfp->id.base.e10g_base_lr ? '+' : '-',
++ sfp->id.base.e10g_base_lrm ? '+' : '-',
++ sfp->id.base.e10g_base_er ? '+' : '-');
++
++ if (!sfp->id.base.sfp_ct_passive && !sfp->id.base.sfp_ct_active &&
++ !sfp->id.base.e1000_base_t) {
++ char len_9um[16], len_om[16];
++
++ dev_info(sfp->dev, " Wavelength %unm, fiber lengths:\n",
++ be16_to_cpup(&sfp->id.base.optical_wavelength));
++
++ if (sfp->id.base.link_len[0] == 255)
++ strcpy(len_9um, ">254km");
++ else if (sfp->id.base.link_len[1] && sfp->id.base.link_len[1] != 255)
++ sprintf(len_9um, "%um",
++ sfp->id.base.link_len[1] * 100);
++ else if (sfp->id.base.link_len[0])
++ sprintf(len_9um, "%ukm", sfp->id.base.link_len[0]);
++ else if (sfp->id.base.link_len[1] == 255)
++ strcpy(len_9um, ">25.4km");
++ else
++ strcpy(len_9um, "unsupported");
++
++ dev_info(sfp->dev, " 9µm SM : %s\n", len_9um);
++ dev_info(sfp->dev, " 62.5µm MM OM1: %s\n",
++ sfp_link_len(len_om, sizeof(len_om),
++ sfp->id.base.link_len[3], 10));
++ dev_info(sfp->dev, " 50µm MM OM2: %s\n",
++ sfp_link_len(len_om, sizeof(len_om),
++ sfp->id.base.link_len[2], 10));
++ dev_info(sfp->dev, " 50µm MM OM3: %s\n",
++ sfp_link_len(len_om, sizeof(len_om),
++ sfp->id.base.link_len[5], 10));
++ dev_info(sfp->dev, " 50µm MM OM4: %s\n",
++ sfp_link_len(len_om, sizeof(len_om),
++ sfp->id.base.link_len[4], 10));
++ } else {
++ char len[16];
++ dev_info(sfp->dev, " Copper length: %s\n",
++ sfp_link_len(len, sizeof(len),
++ sfp->id.base.link_len[4], 1));
++ }
++
++ dev_info(sfp->dev, " Options: %s\n",
++ sfp_bitfield(options, sizeof(options), sfp_options,
++ be16_to_cpu(sfp->id.ext.options)));
++ dev_info(sfp->dev, " Diagnostics: %s\n",
++ sfp_bitfield(options, sizeof(options), diagmon,
++ sfp->id.ext.diagmon));
+
+ /* We only support SFP modules, not the legacy GBIC modules. */
+ if (sfp->id.base.phys_id != SFP_PHYS_ID_SFP ||
--- /dev/null
+From 36f29e6cf8071fed3854d9825217ed2a3c83b990 Mon Sep 17 00:00:00 2001
+From: Russell King <rmk+kernel@arm.linux.org.uk>
+Date: Wed, 16 Sep 2015 21:27:10 +0100
+Subject: net: mvneta: convert to phylink
+
+Convert mvneta to use phylink, which models the MAC to PHY link in
+a generic, reusable form.
+
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+
+- remove unused sync status
+---
+ drivers/net/ethernet/marvell/Kconfig | 2 +-
+ drivers/net/ethernet/marvell/mvneta.c | 594 ++++++++++++++++++++--------------
+ 2 files changed, 349 insertions(+), 247 deletions(-)
+
+--- a/drivers/net/ethernet/marvell/Kconfig
++++ b/drivers/net/ethernet/marvell/Kconfig
+@@ -60,7 +60,7 @@ config MVNETA
+ depends on ARCH_MVEBU || COMPILE_TEST
+ depends on HAS_DMA
+ select MVMDIO
+- select FIXED_PHY
++ select PHYLINK
+ ---help---
+ This driver supports the network interface units in the
+ Marvell ARMADA XP, ARMADA 370, ARMADA 38x and
+--- a/drivers/net/ethernet/marvell/mvneta.c
++++ b/drivers/net/ethernet/marvell/mvneta.c
+@@ -28,7 +28,7 @@
+ #include <linux/of_mdio.h>
+ #include <linux/of_net.h>
+ #include <linux/phy.h>
+-#include <linux/phy_fixed.h>
++#include <linux/phylink.h>
+ #include <linux/platform_device.h>
+ #include <linux/skbuff.h>
+ #include <net/hwbm.h>
+@@ -189,6 +189,7 @@
+ #define MVNETA_GMAC_CTRL_0 0x2c00
+ #define MVNETA_GMAC_MAX_RX_SIZE_SHIFT 2
+ #define MVNETA_GMAC_MAX_RX_SIZE_MASK 0x7ffc
++#define MVNETA_GMAC0_PORT_1000BASE_X BIT(1)
+ #define MVNETA_GMAC0_PORT_ENABLE BIT(0)
+ #define MVNETA_GMAC_CTRL_2 0x2c08
+ #define MVNETA_GMAC2_INBAND_AN_ENABLE BIT(0)
+@@ -204,13 +205,19 @@
+ #define MVNETA_GMAC_TX_FLOW_CTRL_ENABLE BIT(5)
+ #define MVNETA_GMAC_RX_FLOW_CTRL_ACTIVE BIT(6)
+ #define MVNETA_GMAC_TX_FLOW_CTRL_ACTIVE BIT(7)
++#define MVNETA_GMAC_AN_COMPLETE BIT(11)
++#define MVNETA_GMAC_SYNC_OK BIT(14)
+ #define MVNETA_GMAC_AUTONEG_CONFIG 0x2c0c
+ #define MVNETA_GMAC_FORCE_LINK_DOWN BIT(0)
+ #define MVNETA_GMAC_FORCE_LINK_PASS BIT(1)
+ #define MVNETA_GMAC_INBAND_AN_ENABLE BIT(2)
++#define MVNETA_GMAC_AN_BYPASS_ENABLE BIT(3)
++#define MVNETA_GMAC_INBAND_RESTART_AN BIT(4)
+ #define MVNETA_GMAC_CONFIG_MII_SPEED BIT(5)
+ #define MVNETA_GMAC_CONFIG_GMII_SPEED BIT(6)
+ #define MVNETA_GMAC_AN_SPEED_EN BIT(7)
++#define MVNETA_GMAC_CONFIG_FLOW_CTRL BIT(8)
++#define MVNETA_GMAC_ADVERT_SYM_FLOW_CTRL BIT(9)
+ #define MVNETA_GMAC_AN_FLOW_CTRL_EN BIT(11)
+ #define MVNETA_GMAC_CONFIG_FULL_DUPLEX BIT(12)
+ #define MVNETA_GMAC_AN_DUPLEX_EN BIT(13)
+@@ -237,6 +244,12 @@
+ #define MVNETA_TXQ_TOKEN_SIZE_REG(q) (0x3e40 + ((q) << 2))
+ #define MVNETA_TXQ_TOKEN_SIZE_MAX 0x7fffffff
+
++#define MVNETA_LPI_CTRL_0 0x2cc0
++#define MVNETA_LPI_CTRL_1 0x2cc4
++#define MVNETA_LPI_REQUEST_ENABLE BIT(0)
++#define MVNETA_LPI_CTRL_2 0x2cc8
++#define MVNETA_LPI_STATUS 0x2ccc
++
+ #define MVNETA_CAUSE_TXQ_SENT_DESC_ALL_MASK 0xff
+
+ /* Descriptor ring Macros */
+@@ -313,6 +326,11 @@
+ #define MVNETA_RX_GET_BM_POOL_ID(rxd) \
+ (((rxd)->status & MVNETA_RXD_BM_POOL_MASK) >> MVNETA_RXD_BM_POOL_SHIFT)
+
++enum {
++ ETHTOOL_STAT_EEE_WAKEUP,
++ ETHTOOL_MAX_STATS,
++};
++
+ struct mvneta_statistic {
+ unsigned short offset;
+ unsigned short type;
+@@ -321,6 +339,7 @@ struct mvneta_statistic {
+
+ #define T_REG_32 32
+ #define T_REG_64 64
++#define T_SW 1
+
+ static const struct mvneta_statistic mvneta_statistics[] = {
+ { 0x3000, T_REG_64, "good_octets_received", },
+@@ -355,6 +374,7 @@ static const struct mvneta_statistic mvn
+ { 0x304c, T_REG_32, "broadcast_frames_sent", },
+ { 0x3054, T_REG_32, "fc_sent", },
+ { 0x300c, T_REG_32, "internal_mac_transmit_err", },
++ { ETHTOOL_STAT_EEE_WAKEUP, T_SW, "eee_wakeup_errors", },
+ };
+
+ struct mvneta_pcpu_stats {
+@@ -407,20 +427,19 @@ struct mvneta_port {
+ u16 tx_ring_size;
+ u16 rx_ring_size;
+
+- struct mii_bus *mii_bus;
+- phy_interface_t phy_interface;
+- struct device_node *phy_node;
+- unsigned int link;
+- unsigned int duplex;
+- unsigned int speed;
++ struct device_node *dn;
+ unsigned int tx_csum_limit;
+- unsigned int use_inband_status:1;
++ struct phylink *phylink;
+
+ struct mvneta_bm *bm_priv;
+ struct mvneta_bm_pool *pool_long;
+ struct mvneta_bm_pool *pool_short;
+ int bm_win_id;
+
++ bool eee_enabled;
++ bool eee_active;
++ bool tx_lpi_enabled;
++
+ u64 ethtool_stats[ARRAY_SIZE(mvneta_statistics)];
+
+ u32 indir[MVNETA_RSS_LU_TABLE_SIZE];
+@@ -1215,10 +1234,6 @@ static void mvneta_port_disable(struct m
+ val &= ~MVNETA_GMAC0_PORT_ENABLE;
+ mvreg_write(pp, MVNETA_GMAC_CTRL_0, val);
+
+- pp->link = 0;
+- pp->duplex = -1;
+- pp->speed = 0;
+-
+ udelay(200);
+ }
+
+@@ -1278,44 +1293,6 @@ static void mvneta_set_other_mcast_table
+ mvreg_write(pp, MVNETA_DA_FILT_OTH_MCAST + offset, val);
+ }
+
+-static void mvneta_set_autoneg(struct mvneta_port *pp, int enable)
+-{
+- u32 val;
+-
+- if (enable) {
+- val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG);
+- val &= ~(MVNETA_GMAC_FORCE_LINK_PASS |
+- MVNETA_GMAC_FORCE_LINK_DOWN |
+- MVNETA_GMAC_AN_FLOW_CTRL_EN);
+- val |= MVNETA_GMAC_INBAND_AN_ENABLE |
+- MVNETA_GMAC_AN_SPEED_EN |
+- MVNETA_GMAC_AN_DUPLEX_EN;
+- mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val);
+-
+- val = mvreg_read(pp, MVNETA_GMAC_CLOCK_DIVIDER);
+- val |= MVNETA_GMAC_1MS_CLOCK_ENABLE;
+- mvreg_write(pp, MVNETA_GMAC_CLOCK_DIVIDER, val);
+-
+- val = mvreg_read(pp, MVNETA_GMAC_CTRL_2);
+- val |= MVNETA_GMAC2_INBAND_AN_ENABLE;
+- mvreg_write(pp, MVNETA_GMAC_CTRL_2, val);
+- } else {
+- val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG);
+- val &= ~(MVNETA_GMAC_INBAND_AN_ENABLE |
+- MVNETA_GMAC_AN_SPEED_EN |
+- MVNETA_GMAC_AN_DUPLEX_EN);
+- mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val);
+-
+- val = mvreg_read(pp, MVNETA_GMAC_CLOCK_DIVIDER);
+- val &= ~MVNETA_GMAC_1MS_CLOCK_ENABLE;
+- mvreg_write(pp, MVNETA_GMAC_CLOCK_DIVIDER, val);
+-
+- val = mvreg_read(pp, MVNETA_GMAC_CTRL_2);
+- val &= ~MVNETA_GMAC2_INBAND_AN_ENABLE;
+- mvreg_write(pp, MVNETA_GMAC_CTRL_2, val);
+- }
+-}
+-
+ static void mvneta_percpu_unmask_interrupt(void *arg)
+ {
+ struct mvneta_port *pp = arg;
+@@ -1468,7 +1445,6 @@ static void mvneta_defaults_set(struct m
+ val &= ~MVNETA_PHY_POLLING_ENABLE;
+ mvreg_write(pp, MVNETA_UNIT_CONTROL, val);
+
+- mvneta_set_autoneg(pp, pp->use_inband_status);
+ mvneta_set_ucast_table(pp, -1);
+ mvneta_set_special_mcast_table(pp, -1);
+ mvneta_set_other_mcast_table(pp, -1);
+@@ -2693,26 +2669,11 @@ static irqreturn_t mvneta_percpu_isr(int
+ return IRQ_HANDLED;
+ }
+
+-static int mvneta_fixed_link_update(struct mvneta_port *pp,
+- struct phy_device *phy)
++static void mvneta_link_change(struct mvneta_port *pp)
+ {
+- struct fixed_phy_status status;
+- struct fixed_phy_status changed = {};
+ u32 gmac_stat = mvreg_read(pp, MVNETA_GMAC_STATUS);
+
+- status.link = !!(gmac_stat & MVNETA_GMAC_LINK_UP);
+- if (gmac_stat & MVNETA_GMAC_SPEED_1000)
+- status.speed = SPEED_1000;
+- else if (gmac_stat & MVNETA_GMAC_SPEED_100)
+- status.speed = SPEED_100;
+- else
+- status.speed = SPEED_10;
+- status.duplex = !!(gmac_stat & MVNETA_GMAC_FULL_DUPLEX);
+- changed.link = 1;
+- changed.speed = 1;
+- changed.duplex = 1;
+- fixed_phy_update_state(phy, &status, &changed);
+- return 0;
++ phylink_mac_change(pp->phylink, !!(gmac_stat & MVNETA_GMAC_LINK_UP));
+ }
+
+ /* NAPI handler
+@@ -2728,7 +2689,6 @@ static int mvneta_poll(struct napi_struc
+ u32 cause_rx_tx;
+ int rx_queue;
+ struct mvneta_port *pp = netdev_priv(napi->dev);
+- struct net_device *ndev = pp->dev;
+ struct mvneta_pcpu_port *port = this_cpu_ptr(pp->ports);
+
+ if (!netif_running(pp->dev)) {
+@@ -2742,12 +2702,11 @@ static int mvneta_poll(struct napi_struc
+ u32 cause_misc = mvreg_read(pp, MVNETA_INTR_MISC_CAUSE);
+
+ mvreg_write(pp, MVNETA_INTR_MISC_CAUSE, 0);
+- if (pp->use_inband_status && (cause_misc &
+- (MVNETA_CAUSE_PHY_STATUS_CHANGE |
+- MVNETA_CAUSE_LINK_CHANGE |
+- MVNETA_CAUSE_PSC_SYNC_CHANGE))) {
+- mvneta_fixed_link_update(pp, ndev->phydev);
+- }
++
++ if (cause_misc & (MVNETA_CAUSE_PHY_STATUS_CHANGE |
++ MVNETA_CAUSE_LINK_CHANGE |
++ MVNETA_CAUSE_PSC_SYNC_CHANGE))
++ mvneta_link_change(pp);
+ }
+
+ /* Release Tx descriptors */
+@@ -3060,7 +3019,6 @@ static int mvneta_setup_txqs(struct mvne
+ static void mvneta_start_dev(struct mvneta_port *pp)
+ {
+ int cpu;
+- struct net_device *ndev = pp->dev;
+
+ mvneta_max_rx_size_set(pp, pp->pkt_size);
+ mvneta_txq_max_tx_size_set(pp, pp->pkt_size);
+@@ -3088,16 +3046,15 @@ static void mvneta_start_dev(struct mvne
+ MVNETA_CAUSE_LINK_CHANGE |
+ MVNETA_CAUSE_PSC_SYNC_CHANGE);
+
+- phy_start(ndev->phydev);
++ phylink_start(pp->phylink);
+ netif_tx_start_all_queues(pp->dev);
+ }
+
+ static void mvneta_stop_dev(struct mvneta_port *pp)
+ {
+ unsigned int cpu;
+- struct net_device *ndev = pp->dev;
+
+- phy_stop(ndev->phydev);
++ phylink_stop(pp->phylink);
+
+ if (!pp->neta_armada3700) {
+ for_each_online_cpu(cpu) {
+@@ -3250,103 +3207,232 @@ static int mvneta_set_mac_addr(struct ne
+ return 0;
+ }
+
+-static void mvneta_adjust_link(struct net_device *ndev)
++static void mvneta_validate(struct net_device *ndev, unsigned long *supported,
++ struct phylink_link_state *state)
++{
++ __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
++
++ /* Allow all the expected bits */
++ phylink_set(mask, Autoneg);
++ phylink_set_port_modes(mask);
++
++ /* Asymmetric pause is unsupported */
++ phylink_set(mask, Pause);
++ /* Half-duplex at speeds higher than 100Mbit is unsupported */
++ phylink_set(mask, 1000baseT_Full);
++ phylink_set(mask, 1000baseX_Full);
++
++ if (state->interface != PHY_INTERFACE_MODE_1000BASEX) {
++ /* 10M and 100M are only supported in non-802.3z mode */
++ phylink_set(mask, 10baseT_Half);
++ phylink_set(mask, 10baseT_Full);
++ phylink_set(mask, 100baseT_Half);
++ phylink_set(mask, 100baseT_Full);
++ }
++
++ bitmap_and(supported, supported, mask,
++ __ETHTOOL_LINK_MODE_MASK_NBITS);
++ bitmap_and(state->advertising, state->advertising, mask,
++ __ETHTOOL_LINK_MODE_MASK_NBITS);
++}
++
++static int mvneta_mac_link_state(struct net_device *ndev,
++ struct phylink_link_state *state)
+ {
+ struct mvneta_port *pp = netdev_priv(ndev);
+- struct phy_device *phydev = ndev->phydev;
+- int status_change = 0;
++ u32 gmac_stat;
+
+- if (phydev->link) {
+- if ((pp->speed != phydev->speed) ||
+- (pp->duplex != phydev->duplex)) {
+- u32 val;
+-
+- val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG);
+- val &= ~(MVNETA_GMAC_CONFIG_MII_SPEED |
+- MVNETA_GMAC_CONFIG_GMII_SPEED |
+- MVNETA_GMAC_CONFIG_FULL_DUPLEX);
+-
+- if (phydev->duplex)
+- val |= MVNETA_GMAC_CONFIG_FULL_DUPLEX;
+-
+- if (phydev->speed == SPEED_1000)
+- val |= MVNETA_GMAC_CONFIG_GMII_SPEED;
+- else if (phydev->speed == SPEED_100)
+- val |= MVNETA_GMAC_CONFIG_MII_SPEED;
++ gmac_stat = mvreg_read(pp, MVNETA_GMAC_STATUS);
+
+- mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val);
++ if (gmac_stat & MVNETA_GMAC_SPEED_1000)
++ state->speed = SPEED_1000;
++ else if (gmac_stat & MVNETA_GMAC_SPEED_100)
++ state->speed = SPEED_100;
++ else
++ state->speed = SPEED_10;
+
+- pp->duplex = phydev->duplex;
+- pp->speed = phydev->speed;
+- }
++ state->an_complete = !!(gmac_stat & MVNETA_GMAC_AN_COMPLETE);
++ state->link = !!(gmac_stat & MVNETA_GMAC_LINK_UP);
++ state->duplex = !!(gmac_stat & MVNETA_GMAC_FULL_DUPLEX);
++
++ state->pause = 0;
++ if (gmac_stat & MVNETA_GMAC_RX_FLOW_CTRL_ENABLE)
++ state->pause |= MLO_PAUSE_RX;
++ if (gmac_stat & MVNETA_GMAC_TX_FLOW_CTRL_ENABLE)
++ state->pause |= MLO_PAUSE_TX;
++
++ return 1;
++}
++
++static void mvneta_mac_an_restart(struct net_device *ndev)
++{
++ struct mvneta_port *pp = netdev_priv(ndev);
++ u32 gmac_an = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG);
++
++ mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG,
++ gmac_an | MVNETA_GMAC_INBAND_RESTART_AN);
++ mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG,
++ gmac_an & ~MVNETA_GMAC_INBAND_RESTART_AN);
++}
++
++static void mvneta_mac_config(struct net_device *ndev, unsigned int mode,
++ const struct phylink_link_state *state)
++{
++ struct mvneta_port *pp = netdev_priv(ndev);
++ u32 new_ctrl0, gmac_ctrl0 = mvreg_read(pp, MVNETA_GMAC_CTRL_0);
++ u32 new_ctrl2, gmac_ctrl2 = mvreg_read(pp, MVNETA_GMAC_CTRL_2);
++ u32 new_clk, gmac_clk = mvreg_read(pp, MVNETA_GMAC_CLOCK_DIVIDER);
++ u32 new_an, gmac_an = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG);
++
++ new_ctrl0 = gmac_ctrl0 & ~MVNETA_GMAC0_PORT_1000BASE_X;
++ new_ctrl2 = gmac_ctrl2 & ~MVNETA_GMAC2_INBAND_AN_ENABLE;
++ new_clk = gmac_clk & ~MVNETA_GMAC_1MS_CLOCK_ENABLE;
++ new_an = gmac_an & ~(MVNETA_GMAC_INBAND_AN_ENABLE |
++ MVNETA_GMAC_INBAND_RESTART_AN |
++ MVNETA_GMAC_CONFIG_MII_SPEED |
++ MVNETA_GMAC_CONFIG_GMII_SPEED |
++ MVNETA_GMAC_AN_SPEED_EN |
++ MVNETA_GMAC_ADVERT_SYM_FLOW_CTRL |
++ MVNETA_GMAC_CONFIG_FLOW_CTRL |
++ MVNETA_GMAC_AN_FLOW_CTRL_EN |
++ MVNETA_GMAC_CONFIG_FULL_DUPLEX |
++ MVNETA_GMAC_AN_DUPLEX_EN);
++
++ if (phylink_test(state->advertising, Pause))
++ new_an |= MVNETA_GMAC_ADVERT_SYM_FLOW_CTRL;
++ if (state->pause & MLO_PAUSE_TXRX_MASK)
++ new_an |= MVNETA_GMAC_CONFIG_FLOW_CTRL;
++
++ if (!phylink_autoneg_inband(mode)) {
++ /* Phy or fixed speed */
++ if (state->duplex)
++ new_an |= MVNETA_GMAC_CONFIG_FULL_DUPLEX;
++
++ if (state->speed == SPEED_1000)
++ new_an |= MVNETA_GMAC_CONFIG_GMII_SPEED;
++ else if (state->speed == SPEED_100)
++ new_an |= MVNETA_GMAC_CONFIG_MII_SPEED;
++ } else if (state->interface == PHY_INTERFACE_MODE_SGMII) {
++ /* SGMII mode receives the state from the PHY */
++ new_ctrl2 |= MVNETA_GMAC2_INBAND_AN_ENABLE;
++ new_clk |= MVNETA_GMAC_1MS_CLOCK_ENABLE;
++ new_an = (new_an & ~(MVNETA_GMAC_FORCE_LINK_DOWN |
++ MVNETA_GMAC_FORCE_LINK_PASS)) |
++ MVNETA_GMAC_INBAND_AN_ENABLE |
++ MVNETA_GMAC_AN_SPEED_EN |
++ MVNETA_GMAC_AN_DUPLEX_EN;
++ } else {
++ /* 802.3z negotiation - only 1000base-X */
++ new_ctrl0 |= MVNETA_GMAC0_PORT_1000BASE_X;
++ new_clk |= MVNETA_GMAC_1MS_CLOCK_ENABLE;
++ new_an = (new_an & ~(MVNETA_GMAC_FORCE_LINK_DOWN |
++ MVNETA_GMAC_FORCE_LINK_PASS)) |
++ MVNETA_GMAC_INBAND_AN_ENABLE |
++ MVNETA_GMAC_CONFIG_GMII_SPEED |
++ /* The MAC only supports FD mode */
++ MVNETA_GMAC_CONFIG_FULL_DUPLEX;
++
++ if (state->pause & MLO_PAUSE_AN && state->an_enabled)
++ new_an |= MVNETA_GMAC_AN_FLOW_CTRL_EN;
++ }
++
++ /* Armada 370 documentation says we can only change the port mode
++ * and in-band enable when the link is down, so force it down
++ * while making these changes. We also do this for GMAC_CTRL2 */
++ if ((new_ctrl0 ^ gmac_ctrl0) & MVNETA_GMAC0_PORT_1000BASE_X ||
++ (new_ctrl2 ^ gmac_ctrl2) & MVNETA_GMAC2_INBAND_AN_ENABLE ||
++ (new_an ^ gmac_an) & MVNETA_GMAC_INBAND_AN_ENABLE) {
++ mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG,
++ (gmac_an & ~MVNETA_GMAC_FORCE_LINK_PASS) |
++ MVNETA_GMAC_FORCE_LINK_DOWN);
++ }
++
++ if (new_ctrl0 != gmac_ctrl0)
++ mvreg_write(pp, MVNETA_GMAC_CTRL_0, new_ctrl0);
++ if (new_ctrl2 != gmac_ctrl2)
++ mvreg_write(pp, MVNETA_GMAC_CTRL_2, new_ctrl2);
++ if (new_clk != gmac_clk)
++ mvreg_write(pp, MVNETA_GMAC_CLOCK_DIVIDER, new_clk);
++ if (new_an != gmac_an)
++ mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, new_an);
++}
++
++static void mvneta_set_eee(struct mvneta_port *pp, bool enable)
++{
++ u32 lpi_ctl1;
++
++ lpi_ctl1 = mvreg_read(pp, MVNETA_LPI_CTRL_1);
++ if (enable)
++ lpi_ctl1 |= MVNETA_LPI_REQUEST_ENABLE;
++ else
++ lpi_ctl1 &= ~MVNETA_LPI_REQUEST_ENABLE;
++ mvreg_write(pp, MVNETA_LPI_CTRL_1, lpi_ctl1);
++}
++
++static void mvneta_mac_link_down(struct net_device *ndev, unsigned int mode)
++{
++ struct mvneta_port *pp = netdev_priv(ndev);
++ u32 val;
++
++ mvneta_port_down(pp);
++
++ if (!phylink_autoneg_inband(mode)) {
++ val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG);
++ val &= ~MVNETA_GMAC_FORCE_LINK_PASS;
++ val |= MVNETA_GMAC_FORCE_LINK_DOWN;
++ mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val);
+ }
+
+- if (phydev->link != pp->link) {
+- if (!phydev->link) {
+- pp->duplex = -1;
+- pp->speed = 0;
+- }
++ pp->eee_active = false;
++ mvneta_set_eee(pp, false);
++}
++
++static void mvneta_mac_link_up(struct net_device *ndev, unsigned int mode,
++ struct phy_device *phy)
++{
++ struct mvneta_port *pp = netdev_priv(ndev);
++ u32 val;
+
+- pp->link = phydev->link;
+- status_change = 1;
++ if (!phylink_autoneg_inband(mode)) {
++ val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG);
++ val &= ~MVNETA_GMAC_FORCE_LINK_DOWN;
++ val |= MVNETA_GMAC_FORCE_LINK_PASS;
++ mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val);
+ }
+
+- if (status_change) {
+- if (phydev->link) {
+- if (!pp->use_inband_status) {
+- u32 val = mvreg_read(pp,
+- MVNETA_GMAC_AUTONEG_CONFIG);
+- val &= ~MVNETA_GMAC_FORCE_LINK_DOWN;
+- val |= MVNETA_GMAC_FORCE_LINK_PASS;
+- mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG,
+- val);
+- }
+- mvneta_port_up(pp);
+- } else {
+- if (!pp->use_inband_status) {
+- u32 val = mvreg_read(pp,
+- MVNETA_GMAC_AUTONEG_CONFIG);
+- val &= ~MVNETA_GMAC_FORCE_LINK_PASS;
+- val |= MVNETA_GMAC_FORCE_LINK_DOWN;
+- mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG,
+- val);
+- }
+- mvneta_port_down(pp);
+- }
+- phy_print_status(phydev);
++ mvneta_port_up(pp);
++
++ if (phy && pp->eee_enabled) {
++ pp->eee_active = phy_init_eee(phy, 0) >= 0;
++ mvneta_set_eee(pp, pp->eee_active && pp->tx_lpi_enabled);
+ }
+ }
+
++static const struct phylink_mac_ops mvneta_phylink_ops = {
++ .validate = mvneta_validate,
++ .mac_link_state = mvneta_mac_link_state,
++ .mac_an_restart = mvneta_mac_an_restart,
++ .mac_config = mvneta_mac_config,
++ .mac_link_down = mvneta_mac_link_down,
++ .mac_link_up = mvneta_mac_link_up,
++};
++
+ static int mvneta_mdio_probe(struct mvneta_port *pp)
+ {
+- struct phy_device *phy_dev;
+ struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL };
++ int err = phylink_of_phy_connect(pp->phylink, pp->dn);
++ if (err)
++ netdev_err(pp->dev, "could not attach PHY\n");
+
+- phy_dev = of_phy_connect(pp->dev, pp->phy_node, mvneta_adjust_link, 0,
+- pp->phy_interface);
+- if (!phy_dev) {
+- netdev_err(pp->dev, "could not find the PHY\n");
+- return -ENODEV;
+- }
+-
+- phy_ethtool_get_wol(phy_dev, &wol);
++ phylink_ethtool_get_wol(pp->phylink, &wol);
+ device_set_wakeup_capable(&pp->dev->dev, !!wol.supported);
+
+- phy_dev->supported &= PHY_GBIT_FEATURES;
+- phy_dev->advertising = phy_dev->supported;
+-
+- pp->link = 0;
+- pp->duplex = 0;
+- pp->speed = 0;
+-
+- return 0;
++ return err;
+ }
+
+ static void mvneta_mdio_remove(struct mvneta_port *pp)
+ {
+- struct net_device *ndev = pp->dev;
+-
+- phy_disconnect(ndev->phydev);
++ phylink_disconnect_phy(pp->phylink);
+ }
+
+ /* Electing a CPU must be done in an atomic way: it should be done
+@@ -3625,10 +3711,9 @@ static int mvneta_stop(struct net_device
+
+ static int mvneta_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+ {
+- if (!dev->phydev)
+- return -ENOTSUPP;
++ struct mvneta_port *pp = netdev_priv(dev);
+
+- return phy_mii_ioctl(dev->phydev, ifr, cmd);
++ return phylink_mii_ioctl(pp->phylink, ifr, cmd);
+ }
+
+ /* Ethtool methods */
+@@ -3639,44 +3724,25 @@ mvneta_ethtool_set_link_ksettings(struct
+ const struct ethtool_link_ksettings *cmd)
+ {
+ struct mvneta_port *pp = netdev_priv(ndev);
+- struct phy_device *phydev = ndev->phydev;
+
+- if (!phydev)
+- return -ENODEV;
+-
+- if ((cmd->base.autoneg == AUTONEG_ENABLE) != pp->use_inband_status) {
+- u32 val;
+-
+- mvneta_set_autoneg(pp, cmd->base.autoneg == AUTONEG_ENABLE);
+-
+- if (cmd->base.autoneg == AUTONEG_DISABLE) {
+- val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG);
+- val &= ~(MVNETA_GMAC_CONFIG_MII_SPEED |
+- MVNETA_GMAC_CONFIG_GMII_SPEED |
+- MVNETA_GMAC_CONFIG_FULL_DUPLEX);
+-
+- if (phydev->duplex)
+- val |= MVNETA_GMAC_CONFIG_FULL_DUPLEX;
++ return phylink_ethtool_ksettings_set(pp->phylink, cmd);
++}
+
+- if (phydev->speed == SPEED_1000)
+- val |= MVNETA_GMAC_CONFIG_GMII_SPEED;
+- else if (phydev->speed == SPEED_100)
+- val |= MVNETA_GMAC_CONFIG_MII_SPEED;
++/* Get link ksettings for ethtools */
++static int
++mvneta_ethtool_get_link_ksettings(struct net_device *ndev,
++ struct ethtool_link_ksettings *cmd)
++{
++ struct mvneta_port *pp = netdev_priv(ndev);
+
+- mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val);
+- }
++ return phylink_ethtool_ksettings_get(pp->phylink, cmd);
++}
+
+- pp->use_inband_status = (cmd->base.autoneg == AUTONEG_ENABLE);
+- netdev_info(pp->dev, "autoneg status set to %i\n",
+- pp->use_inband_status);
+-
+- if (netif_running(ndev)) {
+- mvneta_port_down(pp);
+- mvneta_port_up(pp);
+- }
+- }
++static int mvneta_ethtool_nway_reset(struct net_device *dev)
++{
++ struct mvneta_port *pp = netdev_priv(dev);
+
+- return phy_ethtool_ksettings_set(ndev->phydev, cmd);
++ return phylink_ethtool_nway_reset(pp->phylink);
+ }
+
+ /* Set interrupt coalescing for ethtools */
+@@ -3768,6 +3834,22 @@ static int mvneta_ethtool_set_ringparam(
+ return 0;
+ }
+
++static void mvneta_ethtool_get_pauseparam(struct net_device *dev,
++ struct ethtool_pauseparam *pause)
++{
++ struct mvneta_port *pp = netdev_priv(dev);
++
++ phylink_ethtool_get_pauseparam(pp->phylink, pause);
++}
++
++static int mvneta_ethtool_set_pauseparam(struct net_device *dev,
++ struct ethtool_pauseparam *pause)
++{
++ struct mvneta_port *pp = netdev_priv(dev);
++
++ return phylink_ethtool_set_pauseparam(pp->phylink, pause);
++}
++
+ static void mvneta_ethtool_get_strings(struct net_device *netdev, u32 sset,
+ u8 *data)
+ {
+@@ -3784,26 +3866,35 @@ static void mvneta_ethtool_update_stats(
+ {
+ const struct mvneta_statistic *s;
+ void __iomem *base = pp->base;
+- u32 high, low, val;
+- u64 val64;
++ u32 high, low;
++ u64 val;
+ int i;
+
+ for (i = 0, s = mvneta_statistics;
+ s < mvneta_statistics + ARRAY_SIZE(mvneta_statistics);
+ s++, i++) {
++ val = 0;
++
+ switch (s->type) {
+ case T_REG_32:
+ val = readl_relaxed(base + s->offset);
+- pp->ethtool_stats[i] += val;
+ break;
+ case T_REG_64:
+ /* Docs say to read low 32-bit then high */
+ low = readl_relaxed(base + s->offset);
+ high = readl_relaxed(base + s->offset + 4);
+- val64 = (u64)high << 32 | low;
+- pp->ethtool_stats[i] += val64;
++ val = (u64)high << 32 | low;
++ break;
++ case T_SW:
++ switch (s->offset) {
++ case ETHTOOL_STAT_EEE_WAKEUP:
++ val = phylink_get_eee_err(pp->phylink);
++ break;
++ }
+ break;
+ }
++
++ pp->ethtool_stats[i] += val;
+ }
+ }
+
+@@ -3938,28 +4029,65 @@ static int mvneta_ethtool_get_rxfh(struc
+ static void mvneta_ethtool_get_wol(struct net_device *dev,
+ struct ethtool_wolinfo *wol)
+ {
+- wol->supported = 0;
+- wol->wolopts = 0;
++ struct mvneta_port *pp = netdev_priv(dev);
+
+- if (dev->phydev)
+- phy_ethtool_get_wol(dev->phydev, wol);
++ phylink_ethtool_get_wol(pp->phylink, wol);
+ }
+
+ static int mvneta_ethtool_set_wol(struct net_device *dev,
+ struct ethtool_wolinfo *wol)
+ {
++ struct mvneta_port *pp = netdev_priv(dev);
+ int ret;
+
+- if (!dev->phydev)
+- return -EOPNOTSUPP;
+-
+- ret = phy_ethtool_set_wol(dev->phydev, wol);
++ ret = phylink_ethtool_set_wol(pp->phylink, wol);
+ if (!ret)
+ device_set_wakeup_enable(&dev->dev, !!wol->wolopts);
+
+ return ret;
+ }
+
++static int mvneta_ethtool_get_eee(struct net_device *dev,
++ struct ethtool_eee *eee)
++{
++ struct mvneta_port *pp = netdev_priv(dev);
++ u32 lpi_ctl0;
++
++ lpi_ctl0 = mvreg_read(pp, MVNETA_LPI_CTRL_0);
++
++ eee->eee_enabled = pp->eee_enabled;
++ eee->eee_active = pp->eee_active;
++ eee->tx_lpi_enabled = pp->tx_lpi_enabled;
++ eee->tx_lpi_timer = (lpi_ctl0) >> 8; // * scale;
++
++ return phylink_ethtool_get_eee(pp->phylink, eee);
++}
++
++static int mvneta_ethtool_set_eee(struct net_device *dev,
++ struct ethtool_eee *eee)
++{
++ struct mvneta_port *pp = netdev_priv(dev);
++ u32 lpi_ctl0;
++
++ /* The Armada 37x documents do not give limits for this other than
++ * it being an 8-bit register. */
++ if (eee->tx_lpi_enabled &&
++ (eee->tx_lpi_timer < 0 || eee->tx_lpi_timer > 255))
++ return -EINVAL;
++
++ lpi_ctl0 = mvreg_read(pp, MVNETA_LPI_CTRL_0);
++ lpi_ctl0 &= ~(0xff << 8);
++ lpi_ctl0 |= eee->tx_lpi_timer << 8;
++ mvreg_write(pp, MVNETA_LPI_CTRL_0, lpi_ctl0);
++
++ pp->eee_enabled = eee->eee_enabled;
++ pp->tx_lpi_enabled = eee->tx_lpi_enabled;
++
++ mvneta_set_eee(pp, eee->tx_lpi_enabled && eee->eee_enabled);
++
++ return phylink_ethtool_set_eee(pp->phylink, eee);
++}
++
+ static u16 mvneta_select_queue(struct net_device *dev, struct sk_buff *skb,
+ void *accel_priv,
+ select_queue_fallback_t fallback)
+@@ -3983,13 +4111,15 @@ static const struct net_device_ops mvnet
+ };
+
+ static const struct ethtool_ops mvneta_eth_tool_ops = {
+- .nway_reset = phy_ethtool_nway_reset,
++ .nway_reset = mvneta_ethtool_nway_reset,
+ .get_link = ethtool_op_get_link,
+ .set_coalesce = mvneta_ethtool_set_coalesce,
+ .get_coalesce = mvneta_ethtool_get_coalesce,
+ .get_drvinfo = mvneta_ethtool_get_drvinfo,
+ .get_ringparam = mvneta_ethtool_get_ringparam,
+ .set_ringparam = mvneta_ethtool_set_ringparam,
++ .get_pauseparam = mvneta_ethtool_get_pauseparam,
++ .set_pauseparam = mvneta_ethtool_set_pauseparam,
+ .get_strings = mvneta_ethtool_get_strings,
+ .get_ethtool_stats = mvneta_ethtool_get_stats,
+ .get_sset_count = mvneta_ethtool_get_sset_count,
+@@ -3997,10 +4127,12 @@ static const struct ethtool_ops mvneta_e
+ .get_rxnfc = mvneta_ethtool_get_rxnfc,
+ .get_rxfh = mvneta_ethtool_get_rxfh,
+ .set_rxfh = mvneta_ethtool_set_rxfh,
+- .get_link_ksettings = phy_ethtool_get_link_ksettings,
++ .get_link_ksettings = mvneta_ethtool_get_link_ksettings,
+ .set_link_ksettings = mvneta_ethtool_set_link_ksettings,
+ .get_wol = mvneta_ethtool_get_wol,
+ .set_wol = mvneta_ethtool_set_wol,
++ .get_eee = mvneta_ethtool_get_eee,
++ .set_eee = mvneta_ethtool_set_eee,
+ };
+
+ /* Initialize hw */
+@@ -4145,14 +4277,13 @@ static int mvneta_probe(struct platform_
+ {
+ struct resource *res;
+ struct device_node *dn = pdev->dev.of_node;
+- struct device_node *phy_node;
+ struct device_node *bm_node;
+ struct mvneta_port *pp;
+ struct net_device *dev;
++ struct phylink *phylink;
+ const char *dt_mac_addr;
+ char hw_mac_addr[ETH_ALEN];
+ const char *mac_from;
+- const char *managed;
+ int tx_csum_limit;
+ int phy_mode;
+ int err;
+@@ -4168,31 +4299,11 @@ static int mvneta_probe(struct platform_
+ goto err_free_netdev;
+ }
+
+- phy_node = of_parse_phandle(dn, "phy", 0);
+- if (!phy_node) {
+- if (!of_phy_is_fixed_link(dn)) {
+- dev_err(&pdev->dev, "no PHY specified\n");
+- err = -ENODEV;
+- goto err_free_irq;
+- }
+-
+- err = of_phy_register_fixed_link(dn);
+- if (err < 0) {
+- dev_err(&pdev->dev, "cannot register fixed PHY\n");
+- goto err_free_irq;
+- }
+-
+- /* In the case of a fixed PHY, the DT node associated
+- * to the PHY is the Ethernet MAC DT node.
+- */
+- phy_node = of_node_get(dn);
+- }
+-
+ phy_mode = of_get_phy_mode(dn);
+ if (phy_mode < 0) {
+ dev_err(&pdev->dev, "incorrect phy-mode\n");
+ err = -EINVAL;
+- goto err_put_phy_node;
++ goto err_free_irq;
+ }
+
+ dev->tx_queue_len = MVNETA_MAX_TXD;
+@@ -4203,12 +4314,7 @@ static int mvneta_probe(struct platform_
+
+ pp = netdev_priv(dev);
+ spin_lock_init(&pp->lock);
+- pp->phy_node = phy_node;
+- pp->phy_interface = phy_mode;
+-
+- err = of_property_read_string(dn, "managed", &managed);
+- pp->use_inband_status = (err == 0 &&
+- strcmp(managed, "in-band-status") == 0);
++ pp->dn = dn;
+
+ pp->rxq_def = rxq_def;
+
+@@ -4230,7 +4336,7 @@ static int mvneta_probe(struct platform_
+ pp->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(pp->clk)) {
+ err = PTR_ERR(pp->clk);
+- goto err_put_phy_node;
++ goto err_free_irq;
+ }
+
+ clk_prepare_enable(pp->clk);
+@@ -4356,6 +4462,14 @@ static int mvneta_probe(struct platform_
+ /* 9676 == 9700 - 20 and rounding to 8 */
+ dev->max_mtu = 9676;
+
++ phylink = phylink_create(dev, dn, phy_mode, &mvneta_phylink_ops);
++ if (IS_ERR(phylink)) {
++ err = PTR_ERR(phylink);
++ goto err_netdev;
++ }
++
++ pp->phylink = phylink;
++
+ err = register_netdev(dev);
+ if (err < 0) {
+ dev_err(&pdev->dev, "failed to register\n");
+@@ -4367,14 +4481,6 @@ static int mvneta_probe(struct platform_
+
+ platform_set_drvdata(pdev, pp->dev);
+
+- if (pp->use_inband_status) {
+- struct phy_device *phy = of_phy_find_device(dn);
+-
+- mvneta_fixed_link_update(pp, phy);
+-
+- put_device(&phy->mdio.dev);
+- }
+-
+ return 0;
+
+ err_netdev:
+@@ -4383,16 +4489,14 @@ err_netdev:
+ mvneta_bm_pool_destroy(pp->bm_priv, pp->pool_short,
+ 1 << pp->id);
+ }
++ if (pp->phylink)
++ phylink_destroy(pp->phylink);
+ free_percpu(pp->stats);
+ err_free_ports:
+ free_percpu(pp->ports);
+ err_clk:
+ clk_disable_unprepare(pp->clk_bus);
+ clk_disable_unprepare(pp->clk);
+-err_put_phy_node:
+- of_node_put(phy_node);
+- if (of_phy_is_fixed_link(dn))
+- of_phy_deregister_fixed_link(dn);
+ err_free_irq:
+ irq_dispose_mapping(dev->irq);
+ err_free_netdev:
+@@ -4404,7 +4508,6 @@ err_free_netdev:
+ static int mvneta_remove(struct platform_device *pdev)
+ {
+ struct net_device *dev = platform_get_drvdata(pdev);
+- struct device_node *dn = pdev->dev.of_node;
+ struct mvneta_port *pp = netdev_priv(dev);
+
+ unregister_netdev(dev);
+@@ -4412,10 +4515,8 @@ static int mvneta_remove(struct platform
+ clk_disable_unprepare(pp->clk);
+ free_percpu(pp->ports);
+ free_percpu(pp->stats);
+- if (of_phy_is_fixed_link(dn))
+- of_phy_deregister_fixed_link(dn);
+ irq_dispose_mapping(dev->irq);
+- of_node_put(pp->phy_node);
++ phylink_destroy(pp->phylink);
+ free_netdev(dev);
+
+ if (pp->bm_priv) {
+@@ -4467,9 +4568,6 @@ static int mvneta_resume(struct device *
+ return err;
+ }
+
+- if (pp->use_inband_status)
+- mvneta_fixed_link_update(pp, dev->phydev);
+-
+ netif_device_attach(dev);
+ if (netif_running(dev)) {
+ mvneta_open(dev);
--- /dev/null
+From acdfcc7ef78c46baca1439a1cac5b73008abc672 Mon Sep 17 00:00:00 2001
+From: Russell King <rmk+kernel@armlinux.org.uk>
+Date: Tue, 16 May 2017 11:55:58 +0100
+Subject: net: mvneta: hack fix phy_interface
+
+Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
+---
+ drivers/net/ethernet/marvell/mvneta.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/net/ethernet/marvell/mvneta.c
++++ b/drivers/net/ethernet/marvell/mvneta.c
+@@ -427,6 +427,7 @@ struct mvneta_port {
+ u16 tx_ring_size;
+ u16 rx_ring_size;
+
++ phy_interface_t phy_interface;
+ struct device_node *dn;
+ unsigned int tx_csum_limit;
+ struct phylink *phylink;
+@@ -4314,6 +4315,7 @@ static int mvneta_probe(struct platform_
+
+ pp = netdev_priv(dev);
+ spin_lock_init(&pp->lock);
++ pp->phy_interface = phy_mode;
+ pp->dn = dn;
+
+ pp->rxq_def = rxq_def;
--- /dev/null
+From fde9e742a47606110232b7464608b6f9c0510938 Mon Sep 17 00:00:00 2001
+From: Russell King <rmk+kernel@armlinux.org.uk>
+Date: Sat, 24 Dec 2016 10:27:08 +0000
+Subject: net: mvneta: disable MVNETA_CAUSE_PSC_SYNC_CHANGE interrupt
+
+The PSC sync change interrupt can fire multiple times while the link is
+down. As this isn't information we make use of, it's pointless having
+the interrupt enabled, so let's disable this interrupt.
+
+Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
+---
+ drivers/net/ethernet/marvell/mvneta.c | 12 ++++--------
+ 1 file changed, 4 insertions(+), 8 deletions(-)
+
+--- a/drivers/net/ethernet/marvell/mvneta.c
++++ b/drivers/net/ethernet/marvell/mvneta.c
+@@ -2705,8 +2705,7 @@ static int mvneta_poll(struct napi_struc
+ mvreg_write(pp, MVNETA_INTR_MISC_CAUSE, 0);
+
+ if (cause_misc & (MVNETA_CAUSE_PHY_STATUS_CHANGE |
+- MVNETA_CAUSE_LINK_CHANGE |
+- MVNETA_CAUSE_PSC_SYNC_CHANGE))
++ MVNETA_CAUSE_LINK_CHANGE))
+ mvneta_link_change(pp);
+ }
+
+@@ -3044,8 +3043,7 @@ static void mvneta_start_dev(struct mvne
+
+ mvreg_write(pp, MVNETA_INTR_MISC_MASK,
+ MVNETA_CAUSE_PHY_STATUS_CHANGE |
+- MVNETA_CAUSE_LINK_CHANGE |
+- MVNETA_CAUSE_PSC_SYNC_CHANGE);
++ MVNETA_CAUSE_LINK_CHANGE);
+
+ phylink_start(pp->phylink);
+ netif_tx_start_all_queues(pp->dev);
+@@ -3541,8 +3539,7 @@ static int mvneta_cpu_online(unsigned in
+ on_each_cpu(mvneta_percpu_unmask_interrupt, pp, true);
+ mvreg_write(pp, MVNETA_INTR_MISC_MASK,
+ MVNETA_CAUSE_PHY_STATUS_CHANGE |
+- MVNETA_CAUSE_LINK_CHANGE |
+- MVNETA_CAUSE_PSC_SYNC_CHANGE);
++ MVNETA_CAUSE_LINK_CHANGE);
+ netif_tx_start_all_queues(pp->dev);
+ spin_unlock(&pp->lock);
+ return 0;
+@@ -3583,8 +3580,7 @@ static int mvneta_cpu_dead(unsigned int
+ on_each_cpu(mvneta_percpu_unmask_interrupt, pp, true);
+ mvreg_write(pp, MVNETA_INTR_MISC_MASK,
+ MVNETA_CAUSE_PHY_STATUS_CHANGE |
+- MVNETA_CAUSE_LINK_CHANGE |
+- MVNETA_CAUSE_PSC_SYNC_CHANGE);
++ MVNETA_CAUSE_LINK_CHANGE);
+ netif_tx_start_all_queues(pp->dev);
+ return 0;
+ }
--- /dev/null
+From 2ff039aa4462c2104c210b7cf39691c612de8214 Mon Sep 17 00:00:00 2001
+From: Russell King <rmk+kernel@arm.linux.org.uk>
+Date: Thu, 1 Oct 2015 23:32:39 +0100
+Subject: net: mvneta: add module EEPROM reading support
+
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+---
+ drivers/net/ethernet/marvell/mvneta.c | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+--- a/drivers/net/ethernet/marvell/mvneta.c
++++ b/drivers/net/ethernet/marvell/mvneta.c
+@@ -4044,6 +4044,22 @@ static int mvneta_ethtool_set_wol(struct
+ return ret;
+ }
+
++static int mvneta_ethtool_get_module_info(struct net_device *dev,
++ struct ethtool_modinfo *modinfo)
++{
++ struct mvneta_port *pp = netdev_priv(dev);
++
++ return phylink_ethtool_get_module_info(pp->phylink, modinfo);
++}
++
++static int mvneta_ethtool_get_module_eeprom(struct net_device *dev,
++ struct ethtool_eeprom *ee, u8 *buf)
++{
++ struct mvneta_port *pp = netdev_priv(dev);
++
++ return phylink_ethtool_get_module_eeprom(pp->phylink, ee, buf);
++}
++
+ static int mvneta_ethtool_get_eee(struct net_device *dev,
+ struct ethtool_eee *eee)
+ {
+@@ -4128,6 +4144,8 @@ static const struct ethtool_ops mvneta_e
+ .set_link_ksettings = mvneta_ethtool_set_link_ksettings,
+ .get_wol = mvneta_ethtool_get_wol,
+ .set_wol = mvneta_ethtool_set_wol,
++ .get_module_info = mvneta_ethtool_get_module_info,
++ .get_module_eeprom = mvneta_ethtool_get_module_eeprom,
+ .get_eee = mvneta_ethtool_get_eee,
+ .set_eee = mvneta_ethtool_set_eee,
+ };
--- /dev/null
+From 774ce2eda0a929f79ee398ba6d2d13fd406f31c4 Mon Sep 17 00:00:00 2001
+From: Russell King <rmk+kernel@arm.linux.org.uk>
+Date: Fri, 2 Oct 2015 22:46:54 +0100
+Subject: phy: fixed-phy: remove fixed_phy_update_state()
+
+mvneta is the only user of fixed_phy_update_state(), which has been
+converted to use phylink instead. Remove fixed_phy_update_state().
+
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+---
+ drivers/net/phy/fixed_phy.c | 31 -------------------------------
+ include/linux/phy_fixed.h | 9 ---------
+ 2 files changed, 40 deletions(-)
+
+--- a/drivers/net/phy/fixed_phy.c
++++ b/drivers/net/phy/fixed_phy.c
+@@ -115,37 +115,6 @@ int fixed_phy_set_link_update(struct phy
+ }
+ EXPORT_SYMBOL_GPL(fixed_phy_set_link_update);
+
+-int fixed_phy_update_state(struct phy_device *phydev,
+- const struct fixed_phy_status *status,
+- const struct fixed_phy_status *changed)
+-{
+- struct fixed_mdio_bus *fmb = &platform_fmb;
+- struct fixed_phy *fp;
+-
+- if (!phydev || phydev->mdio.bus != fmb->mii_bus)
+- return -EINVAL;
+-
+- list_for_each_entry(fp, &fmb->phys, node) {
+- if (fp->addr == phydev->mdio.addr) {
+- write_seqcount_begin(&fp->seqcount);
+-#define _UPD(x) if (changed->x) \
+- fp->status.x = status->x
+- _UPD(link);
+- _UPD(speed);
+- _UPD(duplex);
+- _UPD(pause);
+- _UPD(asym_pause);
+-#undef _UPD
+- fixed_phy_update(fp);
+- write_seqcount_end(&fp->seqcount);
+- return 0;
+- }
+- }
+-
+- return -ENOENT;
+-}
+-EXPORT_SYMBOL(fixed_phy_update_state);
+-
+ int fixed_phy_add(unsigned int irq, int phy_addr,
+ struct fixed_phy_status *status,
+ int link_gpio)
+--- a/include/linux/phy_fixed.h
++++ b/include/linux/phy_fixed.h
+@@ -24,9 +24,6 @@ extern void fixed_phy_unregister(struct
+ extern int fixed_phy_set_link_update(struct phy_device *phydev,
+ int (*link_update)(struct net_device *,
+ struct fixed_phy_status *));
+-extern int fixed_phy_update_state(struct phy_device *phydev,
+- const struct fixed_phy_status *status,
+- const struct fixed_phy_status *changed);
+ #else
+ static inline int fixed_phy_add(unsigned int irq, int phy_id,
+ struct fixed_phy_status *status,
+@@ -50,12 +47,6 @@ static inline int fixed_phy_set_link_upd
+ {
+ return -ENODEV;
+ }
+-static inline int fixed_phy_update_state(struct phy_device *phydev,
+- const struct fixed_phy_status *status,
+- const struct fixed_phy_status *changed)
+-{
+- return -ENODEV;
+-}
+ #endif /* CONFIG_FIXED_PHY */
+
+ #endif /* __PHY_FIXED_H */
--- /dev/null
+From c47beb7e3f8575dfd7d58240a72c4e4e66ce5449 Mon Sep 17 00:00:00 2001
+From: Russell King <rmk+kernel@armlinux.org.uk>
+Date: Fri, 14 Apr 2017 15:26:32 +0100
+Subject: sfp: move module eeprom ethtool access into netdev core ethtool
+
+Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
+---
+ drivers/net/ethernet/marvell/mvneta.c | 18 ------------------
+ drivers/net/phy/phylink.c | 28 ----------------------------
+ drivers/net/phy/sfp-bus.c | 6 ++----
+ include/linux/netdevice.h | 2 ++
+ include/linux/phylink.h | 3 ---
+ net/core/ethtool.c | 7 +++++++
+ 6 files changed, 11 insertions(+), 53 deletions(-)
+
+--- a/drivers/net/ethernet/marvell/mvneta.c
++++ b/drivers/net/ethernet/marvell/mvneta.c
+@@ -4044,22 +4044,6 @@ static int mvneta_ethtool_set_wol(struct
+ return ret;
+ }
+
+-static int mvneta_ethtool_get_module_info(struct net_device *dev,
+- struct ethtool_modinfo *modinfo)
+-{
+- struct mvneta_port *pp = netdev_priv(dev);
+-
+- return phylink_ethtool_get_module_info(pp->phylink, modinfo);
+-}
+-
+-static int mvneta_ethtool_get_module_eeprom(struct net_device *dev,
+- struct ethtool_eeprom *ee, u8 *buf)
+-{
+- struct mvneta_port *pp = netdev_priv(dev);
+-
+- return phylink_ethtool_get_module_eeprom(pp->phylink, ee, buf);
+-}
+-
+ static int mvneta_ethtool_get_eee(struct net_device *dev,
+ struct ethtool_eee *eee)
+ {
+@@ -4144,8 +4128,6 @@ static const struct ethtool_ops mvneta_e
+ .set_link_ksettings = mvneta_ethtool_set_link_ksettings,
+ .get_wol = mvneta_ethtool_get_wol,
+ .set_wol = mvneta_ethtool_set_wol,
+- .get_module_info = mvneta_ethtool_get_module_info,
+- .get_module_eeprom = mvneta_ethtool_get_module_eeprom,
+ .get_eee = mvneta_ethtool_get_eee,
+ .set_eee = mvneta_ethtool_set_eee,
+ };
+--- a/drivers/net/phy/phylink.c
++++ b/drivers/net/phy/phylink.c
+@@ -1060,34 +1060,6 @@ int phylink_ethtool_set_pauseparam(struc
+ }
+ EXPORT_SYMBOL_GPL(phylink_ethtool_set_pauseparam);
+
+-int phylink_ethtool_get_module_info(struct phylink *pl,
+- struct ethtool_modinfo *modinfo)
+-{
+- int ret = -EOPNOTSUPP;
+-
+- WARN_ON(!lockdep_rtnl_is_held());
+-
+- if (pl->sfp_bus)
+- ret = sfp_get_module_info(pl->sfp_bus, modinfo);
+-
+- return ret;
+-}
+-EXPORT_SYMBOL_GPL(phylink_ethtool_get_module_info);
+-
+-int phylink_ethtool_get_module_eeprom(struct phylink *pl,
+- struct ethtool_eeprom *ee, u8 *buf)
+-{
+- int ret = -EOPNOTSUPP;
+-
+- WARN_ON(!lockdep_rtnl_is_held());
+-
+- if (pl->sfp_bus)
+- ret = sfp_get_module_eeprom(pl->sfp_bus, ee, buf);
+-
+- return ret;
+-}
+-EXPORT_SYMBOL_GPL(phylink_ethtool_get_module_eeprom);
+-
+ int phylink_init_eee(struct phylink *pl, bool clk_stop_enable)
+ {
+ int ret = -EPROTONOSUPPORT;
+--- a/drivers/net/phy/sfp-bus.c
++++ b/drivers/net/phy/sfp-bus.c
+@@ -279,6 +279,7 @@ static int sfp_register_bus(struct sfp_b
+ bus->socket_ops->attach(bus->sfp);
+ if (bus->started)
+ bus->socket_ops->start(bus->sfp);
++ bus->netdev->sfp_bus = bus;
+ bus->registered = true;
+ return 0;
+ }
+@@ -294,14 +295,13 @@ static void sfp_unregister_bus(struct sf
+ if (bus->phydev && ops && ops->disconnect_phy)
+ ops->disconnect_phy(bus->upstream);
+ }
++ bus->netdev->sfp_bus = NULL;
+ bus->registered = false;
+ }
+
+
+ int sfp_get_module_info(struct sfp_bus *bus, struct ethtool_modinfo *modinfo)
+ {
+- if (!bus->registered)
+- return -ENOIOCTLCMD;
+ return bus->socket_ops->module_info(bus->sfp, modinfo);
+ }
+ EXPORT_SYMBOL_GPL(sfp_get_module_info);
+@@ -309,8 +309,6 @@ EXPORT_SYMBOL_GPL(sfp_get_module_info);
+ int sfp_get_module_eeprom(struct sfp_bus *bus, struct ethtool_eeprom *ee,
+ u8 *data)
+ {
+- if (!bus->registered)
+- return -ENOIOCTLCMD;
+ return bus->socket_ops->module_eeprom(bus->sfp, ee, data);
+ }
+ EXPORT_SYMBOL_GPL(sfp_get_module_eeprom);
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -57,6 +57,7 @@ struct device;
+ struct phy_device;
+ struct dsa_switch_tree;
+
++struct sfp_bus;
+ /* 802.11 specific */
+ struct wireless_dev;
+ /* 802.15.4 specific */
+@@ -1940,6 +1941,7 @@ struct net_device {
+ struct netprio_map __rcu *priomap;
+ #endif
+ struct phy_device *phydev;
++ struct sfp_bus *sfp_bus;
+ struct lock_class_key *qdisc_tx_busylock;
+ struct lock_class_key *qdisc_running_key;
+ bool proto_down;
+--- a/include/linux/phylink.h
++++ b/include/linux/phylink.h
+@@ -125,9 +125,6 @@ void phylink_ethtool_get_pauseparam(stru
+ struct ethtool_pauseparam *);
+ int phylink_ethtool_set_pauseparam(struct phylink *,
+ struct ethtool_pauseparam *);
+-int phylink_ethtool_get_module_info(struct phylink *, struct ethtool_modinfo *);
+-int phylink_ethtool_get_module_eeprom(struct phylink *,
+- struct ethtool_eeprom *, u8 *);
+ int phylink_init_eee(struct phylink *, bool);
+ int phylink_get_eee_err(struct phylink *);
+ int phylink_ethtool_get_eee(struct phylink *, struct ethtool_eee *);
+--- a/net/core/ethtool.c
++++ b/net/core/ethtool.c
+@@ -22,6 +22,7 @@
+ #include <linux/bitops.h>
+ #include <linux/uaccess.h>
+ #include <linux/vmalloc.h>
++#include <linux/sfp.h>
+ #include <linux/slab.h>
+ #include <linux/rtnetlink.h>
+ #include <linux/sched/signal.h>
+@@ -2214,6 +2215,9 @@ static int __ethtool_get_module_info(str
+ const struct ethtool_ops *ops = dev->ethtool_ops;
+ struct phy_device *phydev = dev->phydev;
+
++ if (dev->sfp_bus)
++ return sfp_get_module_info(dev->sfp_bus, modinfo);
++
+ if (phydev && phydev->drv && phydev->drv->module_info)
+ return phydev->drv->module_info(phydev, modinfo);
+
+@@ -2248,6 +2252,9 @@ static int __ethtool_get_module_eeprom(s
+ const struct ethtool_ops *ops = dev->ethtool_ops;
+ struct phy_device *phydev = dev->phydev;
+
++ if (dev->sfp_bus)
++ return sfp_get_module_eeprom(dev->sfp_bus, ee, data);
++
+ if (phydev && phydev->drv && phydev->drv->module_eeprom)
+ return phydev->drv->module_eeprom(phydev, ee, data);
+
--- /dev/null
+From 883dc66755313e133a787eba4dfde313fe33525b Mon Sep 17 00:00:00 2001
+From: Russell King <rmk+kernel@armlinux.org.uk>
+Date: Fri, 14 Apr 2017 16:41:55 +0100
+Subject: sfp: use netdev sfp_bus for start/stop
+
+Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
+---
+ drivers/net/phy/phylink.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/phy/phylink.c
++++ b/drivers/net/phy/phylink.c
+@@ -777,8 +777,8 @@ void phylink_start(struct phylink *pl)
+ clear_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state);
+ phylink_run_resolve(pl);
+
+- if (pl->sfp_bus)
+- sfp_upstream_start(pl->sfp_bus);
++ if (pl->netdev->sfp_bus)
++ sfp_upstream_start(pl->netdev->sfp_bus);
+ if (pl->phydev)
+ phy_start(pl->phydev);
+ }
+@@ -790,8 +790,8 @@ void phylink_stop(struct phylink *pl)
+
+ if (pl->phydev)
+ phy_stop(pl->phydev);
+- if (pl->sfp_bus)
+- sfp_upstream_stop(pl->sfp_bus);
++ if (pl->netdev->sfp_bus)
++ sfp_upstream_stop(pl->netdev->sfp_bus);
+
+ phylink_run_resolve_and_disable(pl, PHYLINK_DISABLE_STOPPED);
+ }
--- /dev/null
+From 4a4aca08b11501cb1b2c509113bbb65eb66a1f45 Mon Sep 17 00:00:00 2001
+From: Russell King <rmk+kernel@armlinux.org.uk>
+Date: Fri, 14 Apr 2017 14:21:25 +0100
+Subject: sfp: hack: allow marvell 10G phy support to use SFP
+
+Allow the Marvell 10G PHY to register with the SFP bus, so that SFP+
+cages can work. This bypasses phylink, meaning that socket status
+is not taken into account for the link state. Also, the tx-disable
+signal must be commented out in DT for this to work...
+
+Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
+---
+ drivers/net/phy/marvell10g.c | 54 +++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 53 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/phy/marvell10g.c
++++ b/drivers/net/phy/marvell10g.c
+@@ -15,8 +15,10 @@
+ * If both the fiber and copper ports are connected, the first to gain
+ * link takes priority and the other port is completely locked out.
+ */
++#include <linux/of.h>
+ #include <linux/phy.h>
+ #include <linux/marvell_phy.h>
++#include <linux/sfp.h>
+
+ enum {
+ MV_PMA_BOOT = 0xc050,
+@@ -41,6 +43,11 @@ enum {
+ MV_AN_RESULT_SPD_10000 = BIT(15),
+ };
+
++struct mv3310_priv {
++ struct device_node *sfp_node;
++ struct sfp_bus *sfp_bus;
++};
++
+ static int mv3310_modify(struct phy_device *phydev, int devad, u16 reg,
+ u16 mask, u16 bits)
+ {
+@@ -59,8 +66,25 @@ static int mv3310_modify(struct phy_devi
+ return ret < 0 ? ret : 1;
+ }
+
++static int mv3310_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
++{
++ struct phy_device *phydev = upstream;
++ struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
++
++ if (sfp_parse_interface(priv->sfp_bus, id) != PHY_INTERFACE_MODE_10GKR) {
++ dev_err(&phydev->mdio.dev, "incompatible SFP module inserted\n");
++ return -EINVAL;
++ }
++ return 0;
++}
++
++static const struct sfp_upstream_ops mv3310_sfp_ops = {
++ .module_insert = mv3310_sfp_insert,
++};
++
+ static int mv3310_probe(struct phy_device *phydev)
+ {
++ struct mv3310_priv *priv;
+ u32 mmd_mask = MDIO_DEVS_PMAPMD | MDIO_DEVS_AN;
+ int ret;
+
+@@ -78,9 +102,27 @@ static int mv3310_probe(struct phy_devic
+ return -ENODEV;
+ }
+
++ priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ dev_set_drvdata(&phydev->mdio.dev, priv);
++
++ if (phydev->mdio.dev.of_node)
++ priv->sfp_node = of_parse_phandle(phydev->mdio.dev.of_node,
++ "sfp", 0);
++
+ return 0;
+ }
+
++static void mv3310_remove(struct phy_device *phydev)
++{
++ struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
++
++ if (priv->sfp_bus)
++ sfp_unregister_upstream(priv->sfp_bus);
++}
++
+ /*
+ * Resetting the MV88X3310 causes it to become non-responsive. Avoid
+ * setting the reset bit(s).
+@@ -92,6 +134,7 @@ static int mv3310_soft_reset(struct phy_
+
+ static int mv3310_config_init(struct phy_device *phydev)
+ {
++ struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = { 0, };
+ u32 mask;
+ int val;
+@@ -180,6 +223,14 @@ static int mv3310_config_init(struct phy
+ phydev->supported &= mask;
+ phydev->advertising &= phydev->supported;
+
++ /* Would be nice to do this in the probe function, but unfortunately,
++ * phylib doesn't have phydev->attached_dev set there.
++ */
++ if (priv->sfp_node && !priv->sfp_bus)
++ priv->sfp_bus = sfp_register_upstream(priv->sfp_node,
++ phydev->attached_dev,
++ phydev, &mv3310_sfp_ops);
++
+ return 0;
+ }
+
+@@ -363,12 +414,13 @@ static struct phy_driver mv3310_drivers[
+ SUPPORTED_FIBRE |
+ SUPPORTED_10000baseT_Full |
+ SUPPORTED_Backplane,
+- .probe = mv3310_probe,
+ .soft_reset = mv3310_soft_reset,
+ .config_init = mv3310_config_init,
++ .probe = mv3310_probe,
+ .config_aneg = mv3310_config_aneg,
+ .aneg_done = mv3310_aneg_done,
+ .read_status = mv3310_read_status,
++ .remove = mv3310_remove,
+ },
+ };
+
--- /dev/null
+From 3344f73509a34d2124b716efc79cd9787773018b Mon Sep 17 00:00:00 2001
+From: Russell King <rmk+kernel@armlinux.org.uk>
+Date: Fri, 14 Apr 2017 20:17:13 +0100
+Subject: sfp: add sfp+ compatible
+
+Add a compatible for SFP+ cages. SFP+ cages are backwards compatible,
+but the ethernet device behind them may not support the slower speeds
+of SFP modules.
+
+Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
+---
+ drivers/net/phy/sfp.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/phy/sfp.c
++++ b/drivers/net/phy/sfp.c
+@@ -1168,6 +1168,7 @@ static int sfp_remove(struct platform_de
+
+ static const struct of_device_id sfp_of_match[] = {
+ { .compatible = "sff,sfp", },
++ { .compatible = "sff,sfp+", },
+ { },
+ };
+ MODULE_DEVICE_TABLE(of, sfp_of_match);
--- /dev/null
+From 8137da20701c776ad3481115305a5e8e410871ba Mon Sep 17 00:00:00 2001
+From: Russell King <rmk+kernel@armlinux.org.uk>
+Date: Tue, 29 Nov 2016 10:15:45 +0000
+Subject: ARM: dts: armada388-clearfog: emmc on clearfog base
+
+Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
+---
+ arch/arm/boot/dts/armada-388-clearfog-base.dts | 1 +
+ .../dts/armada-38x-solidrun-microsom-emmc.dtsi | 62 ++++++++++++++++++++++
+ 2 files changed, 63 insertions(+)
+ create mode 100644 arch/arm/boot/dts/armada-38x-solidrun-microsom-emmc.dtsi
+
+--- a/arch/arm/boot/dts/armada-388-clearfog-base.dts
++++ b/arch/arm/boot/dts/armada-388-clearfog-base.dts
+@@ -48,6 +48,7 @@
+
+ /dts-v1/;
+ #include "armada-388-clearfog.dtsi"
++#include "armada-38x-solidrun-microsom-emmc.dtsi"
+
+ / {
+ model = "SolidRun Clearfog Base A1";
+--- /dev/null
++++ b/arch/arm/boot/dts/armada-38x-solidrun-microsom-emmc.dtsi
+@@ -0,0 +1,62 @@
++/*
++ * Device Tree file for SolidRun Armada 38x Microsom add-on for eMMC
++ *
++ * Copyright (C) 2015 Russell King
++ *
++ * This board is in development; the contents of this file work with
++ * the A1 rev 2.0 of the board, which does not represent final
++ * production board. Things will change, don't expect this file to
++ * remain compatible info the future.
++ *
++ * This file is dual-licensed: you can use it either under the terms
++ * of the GPL or the X11 license, at your option. Note that this dual
++ * licensing only applies to this file, and not this project as a
++ * whole.
++ *
++ * a) This file is free software; you can 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 file is distributed in the hope that it will be useful
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * Or, alternatively
++ *
++ * b) Permission is hereby granted, free of charge, to any person
++ * obtaining a copy of this software and associated documentation
++ * files (the "Software"), to deal in the Software without
++ * restriction, including without limitation the rights to use
++ * copy, modify, merge, publish, distribute, sublicense, and/or
++ * sell copies of the Software, and to permit persons to whom the
++ * Software is furnished to do so, subject to the following
++ * conditions:
++ *
++ * The above copyright notice and this permission notice shall be
++ * included in all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
++ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
++ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
++ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
++ * OTHER DEALINGS IN THE SOFTWARE.
++ */
++/ {
++ soc {
++ internal-regs {
++ sdhci@d8000 {
++ bus-width = <4>;
++ no-1-8-v;
++ non-removable;
++ pinctrl-0 = <µsom_sdhci_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++ wp-inverted;
++ };
++ };
++ };
++};
--- /dev/null
+From 6e127081e669cf163a818dc04d590790e4ed9527 Mon Sep 17 00:00:00 2001
+From: Russell King <rmk+kernel@armlinux.org.uk>
+Date: Tue, 29 Nov 2016 20:06:44 +0000
+Subject: ARM: dts: armada388-clearfog: increase speed of i2c0 to 400kHz
+
+All the devices on I2C0 support fast mode, so increase the bus speed
+to match. The Armada 388 is known to have a timing issue when in
+standard mode, which we believe causes the ficticious device at 0x64
+to appear.
+
+Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
+---
+ arch/arm/boot/dts/armada-388-clearfog.dtsi | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+--- a/arch/arm/boot/dts/armada-388-clearfog.dtsi
++++ b/arch/arm/boot/dts/armada-388-clearfog.dtsi
+@@ -143,8 +143,7 @@
+ };
+
+ &i2c0 {
+- /* Is there anything on this? */
+- clock-frequency = <100000>;
++ clock-frequency = <400000>;
+ pinctrl-0 = <&i2c0_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+@@ -239,13 +238,11 @@
+ };
+ };
+
+- /* The MCP3021 is 100kHz clock only */
++ /* The MCP3021 supports standard and fast modes */
+ mikrobus_adc: mcp3021@4c {
+ compatible = "microchip,mcp3021";
+ reg = <0x4c>;
+ };
+-
+- /* Also something at 0x64 */
+ };
+
+ &i2c1 {
--- /dev/null
+From 74fa68669c88f73bceff523cb764297b7d1e132b Mon Sep 17 00:00:00 2001
+From: Russell King <rmk+kernel@arm.linux.org.uk>
+Date: Tue, 29 Nov 2016 10:13:44 +0000
+Subject: ARM: dts: armada388-clearfog: add SFP module support
+
+Add SFP module support for Clearfog using the SFP phylink support.
+
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+---
+ arch/arm/boot/dts/armada-388-clearfog.dtsi | 44 ++++++++----------------------
+ 1 file changed, 11 insertions(+), 33 deletions(-)
+
+--- a/arch/arm/boot/dts/armada-388-clearfog.dtsi
++++ b/arch/arm/boot/dts/armada-388-clearfog.dtsi
+@@ -117,6 +117,15 @@
+ };
+ };
+ };
++
++ sfp: sfp {
++ compatible = "sff,sfp";
++ i2c-bus = <&i2c1>;
++ los-gpio = <&expander0 12 GPIO_ACTIVE_HIGH>;
++ mod-def0-gpio = <&expander0 15 GPIO_ACTIVE_LOW>;
++ tx-disable-gpio = <&expander0 14 GPIO_ACTIVE_HIGH>;
++ tx-fault-gpio = <&expander0 13 GPIO_ACTIVE_HIGH>;
++ };
+ };
+
+ ð1 {
+@@ -133,13 +142,10 @@
+ bm,pool-long = <3>;
+ bm,pool-short = <1>;
+ buffer-manager = <&bm>;
++ managed = "in-band-status";
+ phy-mode = "sgmii";
++ sfp = <&sfp>;
+ status = "okay";
+-
+- fixed-link {
+- speed = <1000>;
+- full-duplex;
+- };
+ };
+
+ &i2c0 {
+@@ -208,34 +214,6 @@
+ output-low;
+ line-name = "m.2 devslp";
+ };
+- sfp_los {
+- /* SFP loss of signal */
+- gpio-hog;
+- gpios = <12 GPIO_ACTIVE_HIGH>;
+- input;
+- line-name = "sfp-los";
+- };
+- sfp_tx_fault {
+- /* SFP laser fault */
+- gpio-hog;
+- gpios = <13 GPIO_ACTIVE_HIGH>;
+- input;
+- line-name = "sfp-tx-fault";
+- };
+- sfp_tx_disable {
+- /* SFP transmit disable */
+- gpio-hog;
+- gpios = <14 GPIO_ACTIVE_HIGH>;
+- output-low;
+- line-name = "sfp-tx-disable";
+- };
+- sfp_mod_def0 {
+- /* SFP module present */
+- gpio-hog;
+- gpios = <15 GPIO_ACTIVE_LOW>;
+- input;
+- line-name = "sfp-mod-def0";
+- };
+ };
+
+ /* The MCP3021 supports standard and fast modes */
--- /dev/null
+From 09a0122c74ec076e08512f1b00b7ccb8a450282f Mon Sep 17 00:00:00 2001
+From: Russell King <rmk+kernel@arm.linux.org.uk>
+Date: Tue, 29 Nov 2016 10:15:43 +0000
+Subject: ARM: dts: armada388-clearfog: document MPP usage
+
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+---
+ arch/arm/boot/dts/armada-388-clearfog-base.dts | 51 ++++++++++++++++++++++++++
+ arch/arm/boot/dts/armada-388-clearfog.dts | 50 +++++++++++++++++++++++++
+ 2 files changed, 101 insertions(+)
+
+--- a/arch/arm/boot/dts/armada-388-clearfog-base.dts
++++ b/arch/arm/boot/dts/armada-388-clearfog-base.dts
+@@ -108,3 +108,54 @@
+ marvell,function = "gpio";
+ };
+ };
++
++/*
++MPP
++18: pu gpio pca9655 int
++19: gpio phy reset
++20: pu gpio sd0 detect
++21: sd0:cmd
++22: pd gpio mikro int
++23:
++
++24: ua1:rxd mikro rx
++25: ua1:txd mikro tx
++26: pu i2c1:sck
++27: pu i2c1:sda
++28: sd0:clk
++29: pd gpio mikro rst
++30:
++31:
++
++32:
++33:
++34:
++35:
++36:
++37: sd0:d3
++38: sd0:d0
++39: sd0:d1
++
++40: sd0:d2
++41:
++42:
++43: spi1:cs2 mikro cs
++44: gpio rear button sw3
++45: ref:clk_out0 phy#0 clock
++46: ref:clk_out1 phy#1 clock
++47:
++
++48: gpio J18 spare gpio
++49: gpio U10 I2C_IRQ(GNSS)
++50: gpio board id?
++51:
++52:
++53:
++54: gpio mikro pwm
++55:
++
++56: pu spi1:mosi mikro mosi
++57: pd spi1:sck mikro sck
++58: spi1:miso mikro miso
++59:
++*/
+--- a/arch/arm/boot/dts/armada-388-clearfog.dts
++++ b/arch/arm/boot/dts/armada-388-clearfog.dts
+@@ -290,3 +290,53 @@
+ */
+ pinctrl-0 = <&spi1_pins &clearfog_spi1_cs_pins &mikro_spi_pins>;
+ };
++/*
+++#define A38x_CUSTOMER_BOARD_1_MPP16_23 0x00400011
++MPP18: gpio ? (pca9655 int?)
++MPP19: gpio ? (clkreq?)
++MPP20: gpio ? (sd0 detect)
++MPP21: sd0:cmd x sd0
++MPP22: gpio x mikro int
++MPP23: gpio x switch irq
+++#define A38x_CUSTOMER_BOARD_1_MPP24_31 0x22043333
++MPP24: ua1:rxd x mikro rx
++MPP25: ua1:txd x mikro tx
++MPP26: i2c1:sck x mikro sck
++MPP27: i2c1:sda x mikro sda
++MPP28: sd0:clk x sd0
++MPP29: gpio x mikro rst
++MPP30: ge1:txd2 ? (config)
++MPP31: ge1:txd3 ? (config)
+++#define A38x_CUSTOMER_BOARD_1_MPP32_39 0x44400002
++MPP32: ge1:txctl ? (unused)
++MPP33: gpio ? (pic_com0)
++MPP34: gpio x rear button (pic_com1)
++MPP35: gpio ? (pic_com2)
++MPP36: gpio ? (unused)
++MPP37: sd0:d3 x sd0
++MPP38: sd0:d0 x sd0
++MPP39: sd0:d1 x sd0
+++#define A38x_CUSTOMER_BOARD_1_MPP40_47 0x41144004
++MPP40: sd0:d2 x sd0
++MPP41: gpio x switch reset
++MPP42: gpio ? sw1-1
++MPP43: spi1:cs2 x mikro cs
++MPP44: sata3:prsnt ? (unused)
++MPP45: ref:clk_out0 ?
++MPP46: ref:clk_out1 x switch clk
++MPP47: 4 ? (unused)
+++#define A38x_CUSTOMER_BOARD_1_MPP48_55 0x40333333
++MPP48: tdm:pclk
++MPP49: tdm:fsync
++MPP50: tdm:drx
++MPP51: tdm:dtx
++MPP52: tdm:int
++MPP53: tdm:rst
++MPP54: gpio ? (pwm)
++MPP55: spi1:cs1 x slic
+++#define A38x_CUSTOMER_BOARD_1_MPP56_63 0x00004444
++MPP56: spi1:mosi x mikro mosi
++MPP57: spi1:sck x mikro sck
++MPP58: spi1:miso x mikro miso
++MPP59: spi1:cs0 x w25q32
++*/
--- /dev/null
+commit f94ffbc2c2a4128c4412bb483d0807722dfb682b
+Author: Russell King <rmk+kernel@armlinux.org.uk>
+Date: Fri Sep 29 11:23:31 2017 +0100
+
+ rtc: armada38x: add support for trimming the RTC
+
+ Add support for trimming the RTC using the offset mechanism. This RTC
+ supports two modes: low update mode and high update mode. Low update
+ mode has finer precision than high update mode, so we use the low mode
+ where possible.
+
+ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
+ Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+
+--- a/drivers/rtc/rtc-armada38x.c
++++ b/drivers/rtc/rtc-armada38x.c
+@@ -28,6 +28,8 @@
+ #define RTC_IRQ_AL_EN BIT(0)
+ #define RTC_IRQ_FREQ_EN BIT(1)
+ #define RTC_IRQ_FREQ_1HZ BIT(2)
++#define RTC_CCR 0x18
++#define RTC_CCR_MODE BIT(15)
+
+ #define RTC_TIME 0xC
+ #define RTC_ALARM1 0x10
+@@ -343,18 +345,117 @@ static irqreturn_t armada38x_rtc_alarm_i
+ return IRQ_HANDLED;
+ }
+
++/*
++ * The information given in the Armada 388 functional spec is complex.
++ * They give two different formulas for calculating the offset value,
++ * but when considering "Offset" as an 8-bit signed integer, they both
++ * reduce down to (we shall rename "Offset" as "val" here):
++ *
++ * val = (f_ideal / f_measured - 1) / resolution where f_ideal = 32768
++ *
++ * Converting to time, f = 1/t:
++ * val = (t_measured / t_ideal - 1) / resolution where t_ideal = 1/32768
++ *
++ * => t_measured / t_ideal = val * resolution + 1
++ *
++ * "offset" in the RTC interface is defined as:
++ * t = t0 * (1 + offset * 1e-9)
++ * where t is the desired period, t0 is the measured period with a zero
++ * offset, which is t_measured above. With t0 = t_measured and t = t_ideal,
++ * offset = (t_ideal / t_measured - 1) / 1e-9
++ *
++ * => t_ideal / t_measured = offset * 1e-9 + 1
++ *
++ * so:
++ *
++ * offset * 1e-9 + 1 = 1 / (val * resolution + 1)
++ *
++ * We want "resolution" to be an integer, so resolution = R * 1e-9, giving
++ * offset = 1e18 / (val * R + 1e9) - 1e9
++ * val = (1e18 / (offset + 1e9) - 1e9) / R
++ * with a common transformation:
++ * f(x) = 1e18 / (x + 1e9) - 1e9
++ * offset = f(val * R)
++ * val = f(offset) / R
++ *
++ * Armada 38x supports two modes, fine mode (954ppb) and coarse mode (3815ppb).
++ */
++static long armada38x_ppb_convert(long ppb)
++{
++ long div = ppb + 1000000000L;
++
++ return div_s64(1000000000000000000LL + div / 2, div) - 1000000000L;
++}
++
++static int armada38x_rtc_read_offset(struct device *dev, long *offset)
++{
++ struct armada38x_rtc *rtc = dev_get_drvdata(dev);
++ unsigned long ccr, flags;
++ long ppb_cor;
++
++ spin_lock_irqsave(&rtc->lock, flags);
++ ccr = rtc->data->read_rtc_reg(rtc, RTC_CCR);
++ spin_unlock_irqrestore(&rtc->lock, flags);
++
++ ppb_cor = (ccr & RTC_CCR_MODE ? 3815 : 954) * (s8)ccr;
++ /* ppb_cor + 1000000000L can never be zero */
++ *offset = armada38x_ppb_convert(ppb_cor);
++
++ return 0;
++}
++
++static int armada38x_rtc_set_offset(struct device *dev, long offset)
++{
++ struct armada38x_rtc *rtc = dev_get_drvdata(dev);
++ unsigned long ccr = 0;
++ long ppb_cor, off;
++
++ /*
++ * The maximum ppb_cor is -128 * 3815 .. 127 * 3815, but we
++ * need to clamp the input. This equates to -484270 .. 488558.
++ * Not only is this to stop out of range "off" but also to
++ * avoid the division by zero in armada38x_ppb_convert().
++ */
++ offset = clamp(offset, -484270L, 488558L);
++
++ ppb_cor = armada38x_ppb_convert(offset);
++
++ /*
++ * Use low update mode where possible, which gives a better
++ * resolution of correction.
++ */
++ off = DIV_ROUND_CLOSEST(ppb_cor, 954);
++ if (off > 127 || off < -128) {
++ ccr = RTC_CCR_MODE;
++ off = DIV_ROUND_CLOSEST(ppb_cor, 3815);
++ }
++
++ /*
++ * Armada 388 requires a bit pattern in bits 14..8 depending on
++ * the sign bit: { 0, ~S, S, S, S, S, S }
++ */
++ ccr |= (off & 0x3fff) ^ 0x2000;
++ rtc_delayed_write(ccr, rtc, RTC_CCR);
++
++ return 0;
++}
++
+ static const struct rtc_class_ops armada38x_rtc_ops = {
+ .read_time = armada38x_rtc_read_time,
+ .set_time = armada38x_rtc_set_time,
+ .read_alarm = armada38x_rtc_read_alarm,
+ .set_alarm = armada38x_rtc_set_alarm,
+ .alarm_irq_enable = armada38x_rtc_alarm_irq_enable,
++ .read_offset = armada38x_rtc_read_offset,
++ .set_offset = armada38x_rtc_set_offset,
+ };
+
+ static const struct rtc_class_ops armada38x_rtc_ops_noirq = {
+ .read_time = armada38x_rtc_read_time,
+ .set_time = armada38x_rtc_set_time,
+ .read_alarm = armada38x_rtc_read_alarm,
++ .read_offset = armada38x_rtc_read_offset,
++ .set_offset = armada38x_rtc_set_offset,
+ };
+
+ static const struct armada38x_rtc_data armada38x_data = {
--- /dev/null
+From 1a990fefb641398fb580a0ea0be99b0ff27cbb9b Mon Sep 17 00:00:00 2001
+From: Baruch Siach <baruch@tkos.co.il>
+Date: Thu, 21 Jun 2018 20:40:23 +0300
+Subject: [PATCH] rtc: armada38x: reset after rtc power loss
+
+When the RTC block looses power it needs a reset sequence to make it
+usable again. Otherwise, writes to the time register have no effect.
+
+This reset sequence combines information from the mvebu_rtc driver in
+the Marvell provided U-Boot, and the SolidRun provided U-Boot repo.
+
+Tested on the Armada 388 based SolidRun Clearfog Base.
+
+Signed-off-by: Baruch Siach <baruch@tkos.co.il>
+Acked-by: Gregory CLEMENT <gregory.clement@bootlin.com>
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+---
+ drivers/rtc/rtc-armada38x.c | 23 +++++++++++++++++++++++
+ 1 file changed, 23 insertions(+)
+
+--- a/drivers/rtc/rtc-armada38x.c
++++ b/drivers/rtc/rtc-armada38x.c
+@@ -30,6 +30,8 @@
+ #define RTC_IRQ_FREQ_1HZ BIT(2)
+ #define RTC_CCR 0x18
+ #define RTC_CCR_MODE BIT(15)
++#define RTC_CONF_TEST 0x1C
++#define RTC_NOMINAL_TIMING BIT(13)
+
+ #define RTC_TIME 0xC
+ #define RTC_ALARM1 0x10
+@@ -75,6 +77,7 @@ struct armada38x_rtc {
+ void __iomem *regs_soc;
+ spinlock_t lock;
+ int irq;
++ bool initialized;
+ struct value_to_freq *val_to_freq;
+ struct armada38x_rtc_data *data;
+ };
+@@ -226,6 +229,23 @@ static int armada38x_rtc_read_time(struc
+ return 0;
+ }
+
++static void armada38x_rtc_reset(struct armada38x_rtc *rtc)
++{
++ u32 reg;
++
++ reg = rtc->data->read_rtc_reg(rtc, RTC_CONF_TEST);
++ /* If bits [7:0] are non-zero, assume RTC was uninitialized */
++ if (reg & 0xff) {
++ rtc_delayed_write(0, rtc, RTC_CONF_TEST);
++ msleep(500); /* Oscillator startup time */
++ rtc_delayed_write(0, rtc, RTC_TIME);
++ rtc_delayed_write(SOC_RTC_ALARM1 | SOC_RTC_ALARM2, rtc,
++ RTC_STATUS);
++ rtc_delayed_write(RTC_NOMINAL_TIMING, rtc, RTC_CCR);
++ }
++ rtc->initialized = true;
++}
++
+ static int armada38x_rtc_set_time(struct device *dev, struct rtc_time *tm)
+ {
+ struct armada38x_rtc *rtc = dev_get_drvdata(dev);
+@@ -237,6 +257,9 @@ static int armada38x_rtc_set_time(struct
+ if (ret)
+ goto out;
+
++ if (!rtc->initialized)
++ armada38x_rtc_reset(rtc);
++
+ spin_lock_irqsave(&rtc->lock, flags);
+ rtc_delayed_write(time, rtc, RTC_TIME);
+ spin_unlock_irqrestore(&rtc->lock, flags);
--- /dev/null
+From e1cac198fea08c31ec204bed84c279ab05d20389 Mon Sep 17 00:00:00 2001
+From: Hauke Mehrtens <hauke@hauke-m.de>
+Date: Sat, 17 Mar 2018 15:22:25 +0100
+Subject: ARM: dts: armada-385-linksys: Disable internal RTC
+
+The internal RTC does not work correctly on these Linksys boards based
+on Marvell SoCs. For me it only shows Wed Dec 31 23:59:59 1969 and for
+others it is off by 3 minutes in 10 minutes running, this was reported
+by multiple users. On the Linksys Mamba device the device tree comment
+says that no crystal is connected to the internal RTC, this is probably
+also true for the other devices.
+
+Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+---
+ arch/arm/boot/dts/armada-385-linksys.dtsi | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/arch/arm/boot/dts/armada-385-linksys.dtsi
++++ b/arch/arm/boot/dts/armada-385-linksys.dtsi
+@@ -304,3 +304,8 @@
+ status = "okay";
+ usb-phy = <&usb3_1_phy>;
+ };
++
++&rtc {
++ /* No crystal connected to the internal RTC */
++ status = "disabled";
++};
--- /dev/null
+From 28baa5e2635285b178326b301f534ed95c65dd01 Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jonas.gorski@gmail.com>
+Date: Thu, 29 Sep 2016 11:44:39 +0200
+Subject: [PATCH] sfp: retry phy probe if unsuccessful
+
+Some phys seem to take longer than 50 ms to come out of reset, so retry
+until we find a phy.
+
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+---
+ drivers/net/phy/sfp.c | 38 +++++++++++++++++++++++++-------------
+ 1 file changed, 25 insertions(+), 13 deletions(-)
+
+--- a/drivers/net/phy/sfp.c
++++ b/drivers/net/phy/sfp.c
+@@ -506,7 +506,7 @@ static void sfp_sm_phy_detach(struct sfp
+ sfp->mod_phy = NULL;
+ }
+
+-static void sfp_sm_probe_phy(struct sfp *sfp)
++static int sfp_sm_probe_phy(struct sfp *sfp)
+ {
+ struct phy_device *phy;
+ int err;
+@@ -516,11 +516,11 @@ static void sfp_sm_probe_phy(struct sfp
+ phy = mdiobus_scan(sfp->i2c_mii, SFP_PHY_ADDR);
+ if (phy == ERR_PTR(-ENODEV)) {
+ dev_info(sfp->dev, "no PHY detected\n");
+- return;
++ return -EAGAIN;
+ }
+ if (IS_ERR(phy)) {
+ dev_err(sfp->dev, "mdiobus scan returned %ld\n", PTR_ERR(phy));
+- return;
++ return PTR_ERR(phy);
+ }
+
+ err = sfp_add_phy(sfp->sfp_bus, phy);
+@@ -528,11 +528,13 @@ static void sfp_sm_probe_phy(struct sfp
+ phy_device_remove(phy);
+ phy_device_free(phy);
+ dev_err(sfp->dev, "sfp_add_phy failed: %d\n", err);
+- return;
++ return err;
+ }
+
+ sfp->mod_phy = phy;
+ phy_start(phy);
++
++ return 0;
+ }
+
+ static void sfp_sm_link_up(struct sfp *sfp)
+@@ -578,14 +580,9 @@ static void sfp_sm_fault(struct sfp *sfp
+
+ static void sfp_sm_mod_init(struct sfp *sfp)
+ {
+- sfp_module_tx_enable(sfp);
++ int ret = 0;
+
+- /* Wait t_init before indicating that the link is up, provided the
+- * current state indicates no TX_FAULT. If TX_FAULT clears before
+- * this time, that's fine too.
+- */
+- sfp_sm_next(sfp, SFP_S_INIT, T_INIT_JIFFIES);
+- sfp->sm_retries = 5;
++ sfp_module_tx_enable(sfp);
+
+ /* Setting the serdes link mode is guesswork: there's no
+ * field in the EEPROM which indicates what mode should
+@@ -599,7 +596,22 @@ static void sfp_sm_mod_init(struct sfp *
+ if (sfp->id.base.e1000_base_t ||
+ sfp->id.base.e100_base_lx ||
+ sfp->id.base.e100_base_fx)
+- sfp_sm_probe_phy(sfp);
++ ret = sfp_sm_probe_phy(sfp);
++
++ if (!ret) {
++ /* Wait t_init before indicating that the link is up, provided
++ * the current state indicates no TX_FAULT. If TX_FAULT clears
++ * this time, that's fine too.
++ */
++ sfp_sm_next(sfp, SFP_S_INIT, T_INIT_JIFFIES);
++ sfp->sm_retries = 5;
++ return;
++ }
++
++ if (ret == -EAGAIN)
++ sfp_sm_set_timer(sfp, T_PROBE_RETRY);
++ else
++ sfp_sm_next(sfp, SFP_S_TX_DISABLE, 0);
+ }
+
+ static int sfp_sm_mod_probe(struct sfp *sfp)
--- /dev/null
+From dd7aa8d4b53b3484ba31ba56f3ff1be7deb38530 Mon Sep 17 00:00:00 2001
+From: Maxime Chevallier <maxime.chevallier@smile.fr>
+Date: Tue, 10 Oct 2017 10:43:18 +0200
+Subject: spi: a3700: Change SPI mode before asserting chip-select
+
+The spi device mode should be configured in the controller before the
+chip-select is asserted, so that a clock polarity configuration change
+is not interpreted as a clock tick by the device.
+
+This patch moves the mode setting to the 'prepare_message' function
+instead of the 'transfer_one' function.
+
+By doing so, this patch also removes redundant code in
+a3700_spi_clock_set.
+
+This was tested on EspressoBin board, with spidev.
+
+Signed-off-by: Maxime Chevallier <maxime.chevallier@smile.fr>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+---
+ drivers/spi/spi-armada-3700.c | 17 ++++-------------
+ 1 file changed, 4 insertions(+), 13 deletions(-)
+
+--- a/drivers/spi/spi-armada-3700.c
++++ b/drivers/spi/spi-armada-3700.c
+@@ -214,7 +214,7 @@ static void a3700_spi_mode_set(struct a3
+ }
+
+ static void a3700_spi_clock_set(struct a3700_spi *a3700_spi,
+- unsigned int speed_hz, u16 mode)
++ unsigned int speed_hz)
+ {
+ u32 val;
+ u32 prescale;
+@@ -239,17 +239,6 @@ static void a3700_spi_clock_set(struct a
+ val |= A3700_SPI_CLK_CAPT_EDGE;
+ spireg_write(a3700_spi, A3700_SPI_IF_TIME_REG, val);
+ }
+-
+- val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG);
+- val &= ~(A3700_SPI_CLK_POL | A3700_SPI_CLK_PHA);
+-
+- if (mode & SPI_CPOL)
+- val |= A3700_SPI_CLK_POL;
+-
+- if (mode & SPI_CPHA)
+- val |= A3700_SPI_CLK_PHA;
+-
+- spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val);
+ }
+
+ static void a3700_spi_bytelen_set(struct a3700_spi *a3700_spi, unsigned int len)
+@@ -431,7 +420,7 @@ static void a3700_spi_transfer_setup(str
+
+ a3700_spi = spi_master_get_devdata(spi->master);
+
+- a3700_spi_clock_set(a3700_spi, xfer->speed_hz, spi->mode);
++ a3700_spi_clock_set(a3700_spi, xfer->speed_hz);
+
+ byte_len = xfer->bits_per_word >> 3;
+
+@@ -592,6 +581,8 @@ static int a3700_spi_prepare_message(str
+
+ a3700_spi_bytelen_set(a3700_spi, 4);
+
++ a3700_spi_mode_set(a3700_spi, spi->mode);
++
+ return 0;
+ }
+
--- /dev/null
+From 2ff0d0b5bb397c3dc5c9b97bd0f20948f0b77740 Mon Sep 17 00:00:00 2001
+From: Miquel Raynal <miquel.raynal@free-electrons.com>
+Date: Fri, 13 Oct 2017 11:01:57 +0200
+Subject: arm64: dts: marvell: armada-37xx: add UART clock
+
+Add the missing clock property to armada-3700 UART node.
+
+This clock will be used to derive the prescaler value to comply with
+the requested baudrate.
+
+Signed-off-by: Miquel Raynal <miquel.raynal@free-electrons.com>
+Acked-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
+Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
+---
+ arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
++++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
+@@ -135,6 +135,7 @@
+ uart0: serial@12000 {
+ compatible = "marvell,armada-3700-uart";
+ reg = <0x12000 0x200>;
++ clocks = <&xtalclk>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
--- /dev/null
+From adf4e289dd7f801c3fe12e0e6b491e11e548cd3d Mon Sep 17 00:00:00 2001
+From: Gregory CLEMENT <gregory.clement@free-electrons.com>
+Date: Thu, 30 Nov 2017 14:40:27 +0100
+Subject: clk: mvebu: armada-37xx-periph: cosmetic changes
+
+This patches fixes few cosmetic issues such as alignment, blank lines
+and required space.
+
+Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+---
+ drivers/clk/mvebu/armada-37xx-periph.c | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+--- a/drivers/clk/mvebu/armada-37xx-periph.c
++++ b/drivers/clk/mvebu/armada-37xx-periph.c
+@@ -79,6 +79,7 @@ static const struct clk_div_table clk_ta
+ { .val = 1, .div = 4, },
+ { .val = 0, .div = 0, }, /* last entry */
+ };
++
+ static const struct clk_ops clk_double_div_ops;
+
+ #define PERIPH_GATE(_name, _bit) \
+@@ -217,7 +218,7 @@ PERIPH_CLK_FULL(counter, 23, 20, DIV_SEL
+ PERIPH_CLK_FULL_DD(eip97, 24, 24, DIV_SEL2, DIV_SEL2, 22, 19);
+ PERIPH_CLK_MUX_DIV(cpu, 22, DIV_SEL0, 28, clk_table6);
+
+-static struct clk_periph_data data_nb[] ={
++static struct clk_periph_data data_nb[] = {
+ REF_CLK_FULL_DD(mmc),
+ REF_CLK_FULL_DD(sata_host),
+ REF_CLK_FULL_DD(sec_at),
+@@ -281,7 +282,7 @@ static unsigned int get_div(void __iomem
+ }
+
+ static unsigned long clk_double_div_recalc_rate(struct clk_hw *hw,
+- unsigned long parent_rate)
++ unsigned long parent_rate)
+ {
+ struct clk_double_div *double_div = to_clk_double_div(hw);
+ unsigned int div;
+@@ -303,6 +304,7 @@ static const struct of_device_id armada_
+ .data = data_sb, },
+ { }
+ };
++
+ static int armada_3700_add_composite_clk(const struct clk_periph_data *data,
+ void __iomem *reg, spinlock_t *lock,
+ struct device *dev, struct clk_hw **hw)
+@@ -355,9 +357,9 @@ static int armada_3700_add_composite_clk
+ }
+
+ *hw = clk_hw_register_composite(dev, data->name, data->parent_names,
+- data->num_parents, mux_hw,
+- mux_ops, rate_hw, rate_ops,
+- gate_hw, gate_ops, CLK_IGNORE_UNUSED);
++ data->num_parents, mux_hw,
++ mux_ops, rate_hw, rate_ops,
++ gate_hw, gate_ops, CLK_IGNORE_UNUSED);
+
+ if (IS_ERR(*hw))
+ return PTR_ERR(*hw);
+@@ -406,12 +408,11 @@ static int armada_3700_periph_clock_prob
+ if (armada_3700_add_composite_clk(&data[i], reg,
+ &driver_data->lock, dev, hw))
+ dev_err(dev, "Can't register periph clock %s\n",
+- data[i].name);
+-
++ data[i].name);
+ }
+
+ ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get,
+- driver_data->hw_data);
++ driver_data->hw_data);
+ if (ret) {
+ for (i = 0; i < num_periph; i++)
+ clk_hw_unregister(driver_data->hw_data->hws[i]);
--- /dev/null
+From 9818a7a4fd10f72537cdf2a5ec3402f2c245ea24 Mon Sep 17 00:00:00 2001
+From: Gregory CLEMENT <gregory.clement@free-electrons.com>
+Date: Thu, 30 Nov 2017 14:40:28 +0100
+Subject: clk: mvebu: armada-37xx-periph: prepare cpu clk to be
+ used with DVFS
+
+When DVFS will be enabled then the cpu clk will use a different set of
+register at run time. That means that we won't be able to use the common
+callback and need to use our own ones.
+
+This patch prepares this change by switching on our own set of callbacks
+without modifying the behavior of the clocks.
+
+Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+---
+ drivers/clk/mvebu/armada-37xx-periph.c | 82 ++++++++++++++++++++++++++++++----
+ 1 file changed, 73 insertions(+), 9 deletions(-)
+
+--- a/drivers/clk/mvebu/armada-37xx-periph.c
++++ b/drivers/clk/mvebu/armada-37xx-periph.c
+@@ -46,7 +46,17 @@ struct clk_double_div {
+ u8 shift2;
+ };
+
++struct clk_pm_cpu {
++ struct clk_hw hw;
++ void __iomem *reg_mux;
++ u8 shift_mux;
++ u32 mask_mux;
++ void __iomem *reg_div;
++ u8 shift_div;
++};
++
+ #define to_clk_double_div(_hw) container_of(_hw, struct clk_double_div, hw)
++#define to_clk_pm_cpu(_hw) container_of(_hw, struct clk_pm_cpu, hw)
+
+ struct clk_periph_data {
+ const char *name;
+@@ -55,6 +65,7 @@ struct clk_periph_data {
+ struct clk_hw *mux_hw;
+ struct clk_hw *rate_hw;
+ struct clk_hw *gate_hw;
++ struct clk_hw *muxrate_hw;
+ bool is_double_div;
+ };
+
+@@ -81,6 +92,7 @@ static const struct clk_div_table clk_ta
+ };
+
+ static const struct clk_ops clk_double_div_ops;
++static const struct clk_ops clk_pm_cpu_ops;
+
+ #define PERIPH_GATE(_name, _bit) \
+ struct clk_gate gate_##_name = { \
+@@ -122,6 +134,18 @@ struct clk_divider rate_##_name = { \
+ } \
+ };
+
++#define PERIPH_PM_CPU(_name, _shift1, _reg, _shift2) \
++struct clk_pm_cpu muxrate_##_name = { \
++ .reg_mux = (void *)TBG_SEL, \
++ .mask_mux = 3, \
++ .shift_mux = _shift1, \
++ .reg_div = (void *)_reg, \
++ .shift_div = _shift2, \
++ .hw.init = &(struct clk_init_data){ \
++ .ops = &clk_pm_cpu_ops, \
++ } \
++};
++
+ #define PERIPH_CLK_FULL_DD(_name, _bit, _shift, _reg1, _reg2, _shift1, _shift2)\
+ static PERIPH_GATE(_name, _bit); \
+ static PERIPH_MUX(_name, _shift); \
+@@ -136,10 +160,6 @@ static PERIPH_DIV(_name, _reg, _shift1,
+ static PERIPH_GATE(_name, _bit); \
+ static PERIPH_DIV(_name, _reg, _shift, _table);
+
+-#define PERIPH_CLK_MUX_DIV(_name, _shift, _reg, _shift_div, _table) \
+-static PERIPH_MUX(_name, _shift); \
+-static PERIPH_DIV(_name, _reg, _shift_div, _table);
+-
+ #define PERIPH_CLK_MUX_DD(_name, _shift, _reg1, _reg2, _shift1, _shift2)\
+ static PERIPH_MUX(_name, _shift); \
+ static PERIPH_DOUBLEDIV(_name, _reg1, _reg2, _shift1, _shift2);
+@@ -180,13 +200,12 @@ static PERIPH_DOUBLEDIV(_name, _reg1, _r
+ .rate_hw = &rate_##_name.hw, \
+ }
+
+-#define REF_CLK_MUX_DIV(_name) \
++#define REF_CLK_PM_CPU(_name) \
+ { .name = #_name, \
+ .parent_names = (const char *[]){ "TBG-A-P", \
+ "TBG-B-P", "TBG-A-S", "TBG-B-S"}, \
+ .num_parents = 4, \
+- .mux_hw = &mux_##_name.hw, \
+- .rate_hw = &rate_##_name.hw, \
++ .muxrate_hw = &muxrate_##_name.hw, \
+ }
+
+ #define REF_CLK_MUX_DD(_name) \
+@@ -216,7 +235,7 @@ PERIPH_CLK_FULL_DD(ddr_fclk, 21, 16, DIV
+ PERIPH_CLK_FULL(trace, 22, 18, DIV_SEL0, 20, clk_table6);
+ PERIPH_CLK_FULL(counter, 23, 20, DIV_SEL0, 23, clk_table6);
+ PERIPH_CLK_FULL_DD(eip97, 24, 24, DIV_SEL2, DIV_SEL2, 22, 19);
+-PERIPH_CLK_MUX_DIV(cpu, 22, DIV_SEL0, 28, clk_table6);
++static PERIPH_PM_CPU(cpu, 22, DIV_SEL0, 28);
+
+ static struct clk_periph_data data_nb[] = {
+ REF_CLK_FULL_DD(mmc),
+@@ -235,7 +254,7 @@ static struct clk_periph_data data_nb[]
+ REF_CLK_FULL(trace),
+ REF_CLK_FULL(counter),
+ REF_CLK_FULL_DD(eip97),
+- REF_CLK_MUX_DIV(cpu),
++ REF_CLK_PM_CPU(cpu),
+ { },
+ };
+
+@@ -297,6 +316,37 @@ static const struct clk_ops clk_double_d
+ .recalc_rate = clk_double_div_recalc_rate,
+ };
+
++static u8 clk_pm_cpu_get_parent(struct clk_hw *hw)
++{
++ struct clk_pm_cpu *pm_cpu = to_clk_pm_cpu(hw);
++ int num_parents = clk_hw_get_num_parents(hw);
++ u32 val;
++
++ val = readl(pm_cpu->reg_mux) >> pm_cpu->shift_mux;
++ val &= pm_cpu->mask_mux;
++
++ if (val >= num_parents)
++ return -EINVAL;
++
++ return val;
++}
++
++static unsigned long clk_pm_cpu_recalc_rate(struct clk_hw *hw,
++ unsigned long parent_rate)
++{
++ struct clk_pm_cpu *pm_cpu = to_clk_pm_cpu(hw);
++ unsigned int div;
++
++ div = get_div(pm_cpu->reg_div, pm_cpu->shift_div);
++
++ return DIV_ROUND_UP_ULL((u64)parent_rate, div);
++}
++
++static const struct clk_ops clk_pm_cpu_ops = {
++ .get_parent = clk_pm_cpu_get_parent,
++ .recalc_rate = clk_pm_cpu_recalc_rate,
++};
++
+ static const struct of_device_id armada_3700_periph_clock_of_match[] = {
+ { .compatible = "marvell,armada-3700-periph-clock-nb",
+ .data = data_nb, },
+@@ -356,6 +406,20 @@ static int armada_3700_add_composite_clk
+ }
+ }
+
++ if (data->muxrate_hw) {
++ struct clk_pm_cpu *pmcpu_clk;
++ struct clk_hw *muxrate_hw = data->muxrate_hw;
++
++ pmcpu_clk = to_clk_pm_cpu(muxrate_hw);
++ pmcpu_clk->reg_mux = reg + (u64)pmcpu_clk->reg_mux;
++ pmcpu_clk->reg_div = reg + (u64)pmcpu_clk->reg_div;
++
++ mux_hw = muxrate_hw;
++ rate_hw = muxrate_hw;
++ mux_ops = muxrate_hw->init->ops;
++ rate_ops = muxrate_hw->init->ops;
++ }
++
+ *hw = clk_hw_register_composite(dev, data->name, data->parent_names,
+ data->num_parents, mux_hw,
+ mux_ops, rate_hw, rate_ops,
--- /dev/null
+From 2089dc33ea0e3917465929d4020fbff3d6dbf7f4 Mon Sep 17 00:00:00 2001
+From: Gregory CLEMENT <gregory.clement@free-electrons.com>
+Date: Thu, 30 Nov 2017 14:40:29 +0100
+Subject: clk: mvebu: armada-37xx-periph: add DVFS support for cpu clocks
+
+When DVFS is enabled the CPU clock setting is done using an other set of
+registers.
+
+These Power Management registers are exposed through a syscon as they
+will also be used by other drivers such as the cpufreq.
+
+This patch add the possibility to modify the CPU frequency using the
+associate load level matching the target frequency. Then all the
+frequency switch is handle by the hardware.
+
+Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
+[sboyd@codeaurora.org: Grow a local variable for regmap pointer
+to keep lines shorter]
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+---
+ drivers/clk/mvebu/armada-37xx-periph.c | 221 ++++++++++++++++++++++++++++++++-
+ 1 file changed, 217 insertions(+), 4 deletions(-)
+
+--- a/drivers/clk/mvebu/armada-37xx-periph.c
++++ b/drivers/clk/mvebu/armada-37xx-periph.c
+@@ -21,9 +21,11 @@
+ */
+
+ #include <linux/clk-provider.h>
++#include <linux/mfd/syscon.h>
+ #include <linux/of.h>
+ #include <linux/of_device.h>
+ #include <linux/platform_device.h>
++#include <linux/regmap.h>
+ #include <linux/slab.h>
+
+ #define TBG_SEL 0x0
+@@ -33,6 +35,26 @@
+ #define CLK_SEL 0x10
+ #define CLK_DIS 0x14
+
++#define LOAD_LEVEL_NR 4
++
++#define ARMADA_37XX_NB_L0L1 0x18
++#define ARMADA_37XX_NB_L2L3 0x1C
++#define ARMADA_37XX_NB_TBG_DIV_OFF 13
++#define ARMADA_37XX_NB_TBG_DIV_MASK 0x7
++#define ARMADA_37XX_NB_CLK_SEL_OFF 11
++#define ARMADA_37XX_NB_CLK_SEL_MASK 0x1
++#define ARMADA_37XX_NB_TBG_SEL_OFF 9
++#define ARMADA_37XX_NB_TBG_SEL_MASK 0x3
++#define ARMADA_37XX_NB_CONFIG_SHIFT 16
++#define ARMADA_37XX_NB_DYN_MOD 0x24
++#define ARMADA_37XX_NB_DFS_EN 31
++#define ARMADA_37XX_NB_CPU_LOAD 0x30
++#define ARMADA_37XX_NB_CPU_LOAD_MASK 0x3
++#define ARMADA_37XX_DVFS_LOAD_0 0
++#define ARMADA_37XX_DVFS_LOAD_1 1
++#define ARMADA_37XX_DVFS_LOAD_2 2
++#define ARMADA_37XX_DVFS_LOAD_3 3
++
+ struct clk_periph_driver_data {
+ struct clk_hw_onecell_data *hw_data;
+ spinlock_t lock;
+@@ -53,6 +75,7 @@ struct clk_pm_cpu {
+ u32 mask_mux;
+ void __iomem *reg_div;
+ u8 shift_div;
++ struct regmap *nb_pm_base;
+ };
+
+ #define to_clk_double_div(_hw) container_of(_hw, struct clk_double_div, hw)
+@@ -316,14 +339,94 @@ static const struct clk_ops clk_double_d
+ .recalc_rate = clk_double_div_recalc_rate,
+ };
+
++static void armada_3700_pm_dvfs_update_regs(unsigned int load_level,
++ unsigned int *reg,
++ unsigned int *offset)
++{
++ if (load_level <= ARMADA_37XX_DVFS_LOAD_1)
++ *reg = ARMADA_37XX_NB_L0L1;
++ else
++ *reg = ARMADA_37XX_NB_L2L3;
++
++ if (load_level == ARMADA_37XX_DVFS_LOAD_0 ||
++ load_level == ARMADA_37XX_DVFS_LOAD_2)
++ *offset += ARMADA_37XX_NB_CONFIG_SHIFT;
++}
++
++static bool armada_3700_pm_dvfs_is_enabled(struct regmap *base)
++{
++ unsigned int val, reg = ARMADA_37XX_NB_DYN_MOD;
++
++ if (IS_ERR(base))
++ return false;
++
++ regmap_read(base, reg, &val);
++
++ return !!(val & BIT(ARMADA_37XX_NB_DFS_EN));
++}
++
++static unsigned int armada_3700_pm_dvfs_get_cpu_div(struct regmap *base)
++{
++ unsigned int reg = ARMADA_37XX_NB_CPU_LOAD;
++ unsigned int offset = ARMADA_37XX_NB_TBG_DIV_OFF;
++ unsigned int load_level, div;
++
++ /*
++ * This function is always called after the function
++ * armada_3700_pm_dvfs_is_enabled, so no need to check again
++ * if the base is valid.
++ */
++ regmap_read(base, reg, &load_level);
++
++ /*
++ * The register and the offset inside this register accessed to
++ * read the current divider depend on the load level
++ */
++ load_level &= ARMADA_37XX_NB_CPU_LOAD_MASK;
++ armada_3700_pm_dvfs_update_regs(load_level, ®, &offset);
++
++ regmap_read(base, reg, &div);
++
++ return (div >> offset) & ARMADA_37XX_NB_TBG_DIV_MASK;
++}
++
++static unsigned int armada_3700_pm_dvfs_get_cpu_parent(struct regmap *base)
++{
++ unsigned int reg = ARMADA_37XX_NB_CPU_LOAD;
++ unsigned int offset = ARMADA_37XX_NB_TBG_SEL_OFF;
++ unsigned int load_level, sel;
++
++ /*
++ * This function is always called after the function
++ * armada_3700_pm_dvfs_is_enabled, so no need to check again
++ * if the base is valid
++ */
++ regmap_read(base, reg, &load_level);
++
++ /*
++ * The register and the offset inside this register accessed to
++ * read the current divider depend on the load level
++ */
++ load_level &= ARMADA_37XX_NB_CPU_LOAD_MASK;
++ armada_3700_pm_dvfs_update_regs(load_level, ®, &offset);
++
++ regmap_read(base, reg, &sel);
++
++ return (sel >> offset) & ARMADA_37XX_NB_TBG_SEL_MASK;
++}
++
+ static u8 clk_pm_cpu_get_parent(struct clk_hw *hw)
+ {
+ struct clk_pm_cpu *pm_cpu = to_clk_pm_cpu(hw);
+ int num_parents = clk_hw_get_num_parents(hw);
+ u32 val;
+
+- val = readl(pm_cpu->reg_mux) >> pm_cpu->shift_mux;
+- val &= pm_cpu->mask_mux;
++ if (armada_3700_pm_dvfs_is_enabled(pm_cpu->nb_pm_base)) {
++ val = armada_3700_pm_dvfs_get_cpu_parent(pm_cpu->nb_pm_base);
++ } else {
++ val = readl(pm_cpu->reg_mux) >> pm_cpu->shift_mux;
++ val &= pm_cpu->mask_mux;
++ }
+
+ if (val >= num_parents)
+ return -EINVAL;
+@@ -331,19 +434,124 @@ static u8 clk_pm_cpu_get_parent(struct c
+ return val;
+ }
+
++static int clk_pm_cpu_set_parent(struct clk_hw *hw, u8 index)
++{
++ struct clk_pm_cpu *pm_cpu = to_clk_pm_cpu(hw);
++ struct regmap *base = pm_cpu->nb_pm_base;
++ int load_level;
++
++ /*
++ * We set the clock parent only if the DVFS is available but
++ * not enabled.
++ */
++ if (IS_ERR(base) || armada_3700_pm_dvfs_is_enabled(base))
++ return -EINVAL;
++
++ /* Set the parent clock for all the load level */
++ for (load_level = 0; load_level < LOAD_LEVEL_NR; load_level++) {
++ unsigned int reg, mask, val,
++ offset = ARMADA_37XX_NB_TBG_SEL_OFF;
++
++ armada_3700_pm_dvfs_update_regs(load_level, ®, &offset);
++
++ val = index << offset;
++ mask = ARMADA_37XX_NB_TBG_SEL_MASK << offset;
++ regmap_update_bits(base, reg, mask, val);
++ }
++ return 0;
++}
++
+ static unsigned long clk_pm_cpu_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+ {
+ struct clk_pm_cpu *pm_cpu = to_clk_pm_cpu(hw);
+ unsigned int div;
+
+- div = get_div(pm_cpu->reg_div, pm_cpu->shift_div);
+-
++ if (armada_3700_pm_dvfs_is_enabled(pm_cpu->nb_pm_base))
++ div = armada_3700_pm_dvfs_get_cpu_div(pm_cpu->nb_pm_base);
++ else
++ div = get_div(pm_cpu->reg_div, pm_cpu->shift_div);
+ return DIV_ROUND_UP_ULL((u64)parent_rate, div);
+ }
+
++static long clk_pm_cpu_round_rate(struct clk_hw *hw, unsigned long rate,
++ unsigned long *parent_rate)
++{
++ struct clk_pm_cpu *pm_cpu = to_clk_pm_cpu(hw);
++ struct regmap *base = pm_cpu->nb_pm_base;
++ unsigned int div = *parent_rate / rate;
++ unsigned int load_level;
++ /* only available when DVFS is enabled */
++ if (!armada_3700_pm_dvfs_is_enabled(base))
++ return -EINVAL;
++
++ for (load_level = 0; load_level < LOAD_LEVEL_NR; load_level++) {
++ unsigned int reg, val, offset = ARMADA_37XX_NB_TBG_DIV_OFF;
++
++ armada_3700_pm_dvfs_update_regs(load_level, ®, &offset);
++
++ regmap_read(base, reg, &val);
++
++ val >>= offset;
++ val &= ARMADA_37XX_NB_TBG_DIV_MASK;
++ if (val == div)
++ /*
++ * We found a load level matching the target
++ * divider, switch to this load level and
++ * return.
++ */
++ return *parent_rate / div;
++ }
++
++ /* We didn't find any valid divider */
++ return -EINVAL;
++}
++
++static int clk_pm_cpu_set_rate(struct clk_hw *hw, unsigned long rate,
++ unsigned long parent_rate)
++{
++ struct clk_pm_cpu *pm_cpu = to_clk_pm_cpu(hw);
++ struct regmap *base = pm_cpu->nb_pm_base;
++ unsigned int div = parent_rate / rate;
++ unsigned int load_level;
++
++ /* only available when DVFS is enabled */
++ if (!armada_3700_pm_dvfs_is_enabled(base))
++ return -EINVAL;
++
++ for (load_level = 0; load_level < LOAD_LEVEL_NR; load_level++) {
++ unsigned int reg, mask, val,
++ offset = ARMADA_37XX_NB_TBG_DIV_OFF;
++
++ armada_3700_pm_dvfs_update_regs(load_level, ®, &offset);
++
++ regmap_read(base, reg, &val);
++ val >>= offset;
++ val &= ARMADA_37XX_NB_TBG_DIV_MASK;
++
++ if (val == div) {
++ /*
++ * We found a load level matching the target
++ * divider, switch to this load level and
++ * return.
++ */
++ reg = ARMADA_37XX_NB_CPU_LOAD;
++ mask = ARMADA_37XX_NB_CPU_LOAD_MASK;
++ regmap_update_bits(base, reg, mask, load_level);
++
++ return rate;
++ }
++ }
++
++ /* We didn't find any valid divider */
++ return -EINVAL;
++}
++
+ static const struct clk_ops clk_pm_cpu_ops = {
+ .get_parent = clk_pm_cpu_get_parent,
++ .set_parent = clk_pm_cpu_set_parent,
++ .round_rate = clk_pm_cpu_round_rate,
++ .set_rate = clk_pm_cpu_set_rate,
+ .recalc_rate = clk_pm_cpu_recalc_rate,
+ };
+
+@@ -409,6 +617,7 @@ static int armada_3700_add_composite_clk
+ if (data->muxrate_hw) {
+ struct clk_pm_cpu *pmcpu_clk;
+ struct clk_hw *muxrate_hw = data->muxrate_hw;
++ struct regmap *map;
+
+ pmcpu_clk = to_clk_pm_cpu(muxrate_hw);
+ pmcpu_clk->reg_mux = reg + (u64)pmcpu_clk->reg_mux;
+@@ -418,6 +627,10 @@ static int armada_3700_add_composite_clk
+ rate_hw = muxrate_hw;
+ mux_ops = muxrate_hw->init->ops;
+ rate_ops = muxrate_hw->init->ops;
++
++ map = syscon_regmap_lookup_by_compatible(
++ "marvell,armada-3700-nb-pm");
++ pmcpu_clk->nb_pm_base = map;
+ }
+
+ *hw = clk_hw_register_composite(dev, data->name, data->parent_names,
--- /dev/null
+From 92ce45fb875d7c3e021cc454482fe0687ff54f29 Mon Sep 17 00:00:00 2001
+From: Gregory CLEMENT <gregory.clement@free-electrons.com>
+Date: Thu, 14 Dec 2017 16:00:05 +0100
+Subject: cpufreq: Add DVFS support for Armada 37xx
+
+This patch adds DVFS support for the Armada 37xx SoCs
+
+There are up to four CPU frequency loads for Armada 37xx controlled by
+the hardware.
+
+This driver associates the CPU load level to a frequency, then the
+hardware will switch while selecting a load level.
+
+The hardware also can associate a voltage for each level (AVS support)
+but it is not yet supported
+
+Tested-by: Andre Heider <a.heider@gmail.com>
+Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+---
+ drivers/cpufreq/Kconfig.arm | 7 +
+ drivers/cpufreq/Makefile | 1 +
+ drivers/cpufreq/armada-37xx-cpufreq.c | 241 ++++++++++++++++++++++++++++++++++
+ 3 files changed, 249 insertions(+)
+ create mode 100644 drivers/cpufreq/armada-37xx-cpufreq.c
+
+--- a/drivers/cpufreq/Kconfig.arm
++++ b/drivers/cpufreq/Kconfig.arm
+@@ -2,6 +2,13 @@
+ # ARM CPU Frequency scaling drivers
+ #
+
++config ARM_ARMADA_37XX_CPUFREQ
++ tristate "Armada 37xx CPUFreq support"
++ depends on ARCH_MVEBU
++ help
++ This adds the CPUFreq driver support for Marvell Armada 37xx SoCs.
++ The Armada 37xx PMU supports 4 frequency and VDD levels.
++
+ # big LITTLE core layer and glue drivers
+ config ARM_BIG_LITTLE_CPUFREQ
+ tristate "Generic ARM big LITTLE CPUfreq driver"
+--- a/drivers/cpufreq/Makefile
++++ b/drivers/cpufreq/Makefile
+@@ -52,6 +52,7 @@ obj-$(CONFIG_ARM_BIG_LITTLE_CPUFREQ) +=
+ # LITTLE drivers, so that it is probed last.
+ obj-$(CONFIG_ARM_DT_BL_CPUFREQ) += arm_big_little_dt.o
+
++obj-$(CONFIG_ARM_ARMADA_37XX_CPUFREQ) += armada-37xx-cpufreq.o
+ obj-$(CONFIG_ARM_BRCMSTB_AVS_CPUFREQ) += brcmstb-avs-cpufreq.o
+ obj-$(CONFIG_ARCH_DAVINCI) += davinci-cpufreq.o
+ obj-$(CONFIG_ARM_EXYNOS5440_CPUFREQ) += exynos5440-cpufreq.o
+--- /dev/null
++++ b/drivers/cpufreq/armada-37xx-cpufreq.c
+@@ -0,0 +1,241 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ * CPU frequency scaling support for Armada 37xx platform.
++ *
++ * Copyright (C) 2017 Marvell
++ *
++ * Gregory CLEMENT <gregory.clement@free-electrons.com>
++ */
++
++#include <linux/clk.h>
++#include <linux/cpu.h>
++#include <linux/cpufreq.h>
++#include <linux/err.h>
++#include <linux/interrupt.h>
++#include <linux/io.h>
++#include <linux/mfd/syscon.h>
++#include <linux/module.h>
++#include <linux/of_address.h>
++#include <linux/of_device.h>
++#include <linux/of_irq.h>
++#include <linux/platform_device.h>
++#include <linux/pm_opp.h>
++#include <linux/regmap.h>
++#include <linux/slab.h>
++
++/* Power management in North Bridge register set */
++#define ARMADA_37XX_NB_L0L1 0x18
++#define ARMADA_37XX_NB_L2L3 0x1C
++#define ARMADA_37XX_NB_TBG_DIV_OFF 13
++#define ARMADA_37XX_NB_TBG_DIV_MASK 0x7
++#define ARMADA_37XX_NB_CLK_SEL_OFF 11
++#define ARMADA_37XX_NB_CLK_SEL_MASK 0x1
++#define ARMADA_37XX_NB_CLK_SEL_TBG 0x1
++#define ARMADA_37XX_NB_TBG_SEL_OFF 9
++#define ARMADA_37XX_NB_TBG_SEL_MASK 0x3
++#define ARMADA_37XX_NB_VDD_SEL_OFF 6
++#define ARMADA_37XX_NB_VDD_SEL_MASK 0x3
++#define ARMADA_37XX_NB_CONFIG_SHIFT 16
++#define ARMADA_37XX_NB_DYN_MOD 0x24
++#define ARMADA_37XX_NB_CLK_SEL_EN BIT(26)
++#define ARMADA_37XX_NB_TBG_EN BIT(28)
++#define ARMADA_37XX_NB_DIV_EN BIT(29)
++#define ARMADA_37XX_NB_VDD_EN BIT(30)
++#define ARMADA_37XX_NB_DFS_EN BIT(31)
++#define ARMADA_37XX_NB_CPU_LOAD 0x30
++#define ARMADA_37XX_NB_CPU_LOAD_MASK 0x3
++#define ARMADA_37XX_DVFS_LOAD_0 0
++#define ARMADA_37XX_DVFS_LOAD_1 1
++#define ARMADA_37XX_DVFS_LOAD_2 2
++#define ARMADA_37XX_DVFS_LOAD_3 3
++
++/*
++ * On Armada 37xx the Power management manages 4 level of CPU load,
++ * each level can be associated with a CPU clock source, a CPU
++ * divider, a VDD level, etc...
++ */
++#define LOAD_LEVEL_NR 4
++
++struct armada_37xx_dvfs {
++ u32 cpu_freq_max;
++ u8 divider[LOAD_LEVEL_NR];
++};
++
++static struct armada_37xx_dvfs armada_37xx_dvfs[] = {
++ {.cpu_freq_max = 1200*1000*1000, .divider = {1, 2, 4, 6} },
++ {.cpu_freq_max = 1000*1000*1000, .divider = {1, 2, 4, 5} },
++ {.cpu_freq_max = 800*1000*1000, .divider = {1, 2, 3, 4} },
++ {.cpu_freq_max = 600*1000*1000, .divider = {2, 4, 5, 6} },
++};
++
++static struct armada_37xx_dvfs *armada_37xx_cpu_freq_info_get(u32 freq)
++{
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(armada_37xx_dvfs); i++) {
++ if (freq == armada_37xx_dvfs[i].cpu_freq_max)
++ return &armada_37xx_dvfs[i];
++ }
++
++ pr_err("Unsupported CPU frequency %d MHz\n", freq/1000000);
++ return NULL;
++}
++
++/*
++ * Setup the four level managed by the hardware. Once the four level
++ * will be configured then the DVFS will be enabled.
++ */
++static void __init armada37xx_cpufreq_dvfs_setup(struct regmap *base,
++ struct clk *clk, u8 *divider)
++{
++ int load_lvl;
++ struct clk *parent;
++
++ for (load_lvl = 0; load_lvl < LOAD_LEVEL_NR; load_lvl++) {
++ unsigned int reg, mask, val, offset = 0;
++
++ if (load_lvl <= ARMADA_37XX_DVFS_LOAD_1)
++ reg = ARMADA_37XX_NB_L0L1;
++ else
++ reg = ARMADA_37XX_NB_L2L3;
++
++ if (load_lvl == ARMADA_37XX_DVFS_LOAD_0 ||
++ load_lvl == ARMADA_37XX_DVFS_LOAD_2)
++ offset += ARMADA_37XX_NB_CONFIG_SHIFT;
++
++ /* Set cpu clock source, for all the level we use TBG */
++ val = ARMADA_37XX_NB_CLK_SEL_TBG << ARMADA_37XX_NB_CLK_SEL_OFF;
++ mask = (ARMADA_37XX_NB_CLK_SEL_MASK
++ << ARMADA_37XX_NB_CLK_SEL_OFF);
++
++ /*
++ * Set cpu divider based on the pre-computed array in
++ * order to have balanced step.
++ */
++ val |= divider[load_lvl] << ARMADA_37XX_NB_TBG_DIV_OFF;
++ mask |= (ARMADA_37XX_NB_TBG_DIV_MASK
++ << ARMADA_37XX_NB_TBG_DIV_OFF);
++
++ /* Set VDD divider which is actually the load level. */
++ val |= load_lvl << ARMADA_37XX_NB_VDD_SEL_OFF;
++ mask |= (ARMADA_37XX_NB_VDD_SEL_MASK
++ << ARMADA_37XX_NB_VDD_SEL_OFF);
++
++ val <<= offset;
++ mask <<= offset;
++
++ regmap_update_bits(base, reg, mask, val);
++ }
++
++ /*
++ * Set cpu clock source, for all the level we keep the same
++ * clock source that the one already configured. For this one
++ * we need to use the clock framework
++ */
++ parent = clk_get_parent(clk);
++ clk_set_parent(clk, parent);
++}
++
++static void __init armada37xx_cpufreq_disable_dvfs(struct regmap *base)
++{
++ unsigned int reg = ARMADA_37XX_NB_DYN_MOD,
++ mask = ARMADA_37XX_NB_DFS_EN;
++
++ regmap_update_bits(base, reg, mask, 0);
++}
++
++static void __init armada37xx_cpufreq_enable_dvfs(struct regmap *base)
++{
++ unsigned int val, reg = ARMADA_37XX_NB_CPU_LOAD,
++ mask = ARMADA_37XX_NB_CPU_LOAD_MASK;
++
++ /* Start with the highest load (0) */
++ val = ARMADA_37XX_DVFS_LOAD_0;
++ regmap_update_bits(base, reg, mask, val);
++
++ /* Now enable DVFS for the CPUs */
++ reg = ARMADA_37XX_NB_DYN_MOD;
++ mask = ARMADA_37XX_NB_CLK_SEL_EN | ARMADA_37XX_NB_TBG_EN |
++ ARMADA_37XX_NB_DIV_EN | ARMADA_37XX_NB_VDD_EN |
++ ARMADA_37XX_NB_DFS_EN;
++
++ regmap_update_bits(base, reg, mask, mask);
++}
++
++static int __init armada37xx_cpufreq_driver_init(void)
++{
++ struct armada_37xx_dvfs *dvfs;
++ struct platform_device *pdev;
++ unsigned int cur_frequency;
++ struct regmap *nb_pm_base;
++ struct device *cpu_dev;
++ int load_lvl, ret;
++ struct clk *clk;
++
++ nb_pm_base =
++ syscon_regmap_lookup_by_compatible("marvell,armada-3700-nb-pm");
++
++ if (IS_ERR(nb_pm_base))
++ return -ENODEV;
++
++ /* Before doing any configuration on the DVFS first, disable it */
++ armada37xx_cpufreq_disable_dvfs(nb_pm_base);
++
++ /*
++ * On CPU 0 register the operating points supported (which are
++ * the nominal CPU frequency and full integer divisions of
++ * it).
++ */
++ cpu_dev = get_cpu_device(0);
++ if (!cpu_dev) {
++ dev_err(cpu_dev, "Cannot get CPU\n");
++ return -ENODEV;
++ }
++
++ clk = clk_get(cpu_dev, 0);
++ if (IS_ERR(clk)) {
++ dev_err(cpu_dev, "Cannot get clock for CPU0\n");
++ return PTR_ERR(clk);
++ }
++
++ /* Get nominal (current) CPU frequency */
++ cur_frequency = clk_get_rate(clk);
++ if (!cur_frequency) {
++ dev_err(cpu_dev, "Failed to get clock rate for CPU\n");
++ return -EINVAL;
++ }
++
++ dvfs = armada_37xx_cpu_freq_info_get(cur_frequency);
++ if (!dvfs)
++ return -EINVAL;
++
++ armada37xx_cpufreq_dvfs_setup(nb_pm_base, clk, dvfs->divider);
++
++ for (load_lvl = ARMADA_37XX_DVFS_LOAD_0; load_lvl < LOAD_LEVEL_NR;
++ load_lvl++) {
++ unsigned long freq = cur_frequency / dvfs->divider[load_lvl];
++
++ ret = dev_pm_opp_add(cpu_dev, freq, 0);
++ if (ret) {
++ /* clean-up the already added opp before leaving */
++ while (load_lvl-- > ARMADA_37XX_DVFS_LOAD_0) {
++ freq = cur_frequency / dvfs->divider[load_lvl];
++ dev_pm_opp_remove(cpu_dev, freq);
++ }
++ return ret;
++ }
++ }
++
++ /* Now that everything is setup, enable the DVFS at hardware level */
++ armada37xx_cpufreq_enable_dvfs(nb_pm_base);
++
++ pdev = platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
++
++ return PTR_ERR_OR_ZERO(pdev);
++}
++/* late_initcall, to guarantee the driver is loaded after A37xx clock driver */
++late_initcall(armada37xx_cpufreq_driver_init);
++
++MODULE_AUTHOR("Gregory CLEMENT <gregory.clement@free-electrons.com>");
++MODULE_DESCRIPTION("Armada 37xx cpufreq driver");
++MODULE_LICENSE("GPL");
--- /dev/null
+From e8d66e7927b2a15310df0eb44a67d120ea147a59 Mon Sep 17 00:00:00 2001
+From: Gregory CLEMENT <gregory.clement@free-electrons.com>
+Date: Thu, 14 Dec 2017 16:00:06 +0100
+Subject: arm64: dts: marvell: armada-37xx: add nodes allowing cpufreq
+ support
+
+In order to be able to use cpu freq, we need to associate a clock to each
+CPU and to expose the power management registers.
+
+Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
+---
+ arch/arm64/boot/dts/marvell/armada-372x.dtsi | 1 +
+ arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 7 +++++++
+ 2 files changed, 8 insertions(+)
+
+--- a/arch/arm64/boot/dts/marvell/armada-372x.dtsi
++++ b/arch/arm64/boot/dts/marvell/armada-372x.dtsi
+@@ -56,6 +56,7 @@
+ device_type = "cpu";
+ compatible = "arm,cortex-a53","arm,armv8";
+ reg = <0x1>;
++ clocks = <&nb_periph_clk 16>;
+ enable-method = "psci";
+ };
+ };
+--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
++++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
+@@ -64,6 +64,7 @@
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ reg = <0>;
++ clocks = <&nb_periph_clk 16>;
+ enable-method = "psci";
+ };
+ };
+@@ -219,6 +220,12 @@
+ };
+ };
+
++ nb_pm: syscon@14000 {
++ compatible = "marvell,armada-3700-nb-pm",
++ "syscon";
++ reg = <0x14000 0x60>;
++ };
++
+ pinctrl_sb: pinctrl@18800 {
+ compatible = "marvell,armada3710-sb-pinctrl",
+ "syscon", "simple-mfd";
--- /dev/null
+From bffed3d4abcd32ba6d492a9bd7ebe81dc92eaa9a Mon Sep 17 00:00:00 2001
+From: Ellie Reeves <ellierevves@gmail.com>
+Date: Sun, 25 Mar 2018 21:57:36 +0200
+Subject: [PATCH] arm64: dts: armada-3720-espressobin: wire up spi flash
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This is the storage the machine boots from by default. The partitioning
+is taken from the U-Boot that is shipped with the board. There is some
+more space on the flash that isn't used.
+
+Tested-by: Gregory CLEMENT <gregory.clement@bootlin.com>
+Signed-off-by: Ellie Reeves <ellierevves@gmail.com>
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
+---
+ .../dts/marvell/armada-3720-espressobin.dts | 27 +++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+
+--- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts
++++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts
+@@ -96,6 +96,33 @@
+ status = "okay";
+ };
+
++&spi0 {
++ status = "okay";
++
++ flash@0 {
++ reg = <0>;
++ compatible = "winbond,w25q32dw", "jedec,spi-flash";
++ spi-max-frequency = <104000000>;
++ m25p,fast-read;
++
++ partitions {
++ compatible = "fixed-partitions";
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ partition@0 {
++ label = "uboot";
++ reg = <0 0x180000>;
++ };
++
++ partition@180000 {
++ label = "ubootenv";
++ reg = <0x180000 0x10000>;
++ };
++ };
++ };
++};
++
+ /* Exported on the micro USB connector J5 through an FTDI */
+ &uart0 {
+ status = "okay";
--- /dev/null
+From bbcc328561040292f7d6796954d478e4a2335e6f Mon Sep 17 00:00:00 2001
+From: Gregory CLEMENT <gregory.clement@bootlin.com>
+Date: Wed, 4 Apr 2018 16:44:44 +0200
+Subject: [PATCH] cpufreq: armada-37xx: Fix clock leak
+
+There was no clk_put() balancing the clk_get(). This commit fixes it.
+
+Fixes: 92ce45fb875d (cpufreq: Add DVFS support for Armada 37xx)
+Cc: 4.16+ <stable@vger.kernel.org> # 4.16+
+Reported-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
+Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
+Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+---
+ drivers/cpufreq/armada-37xx-cpufreq.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/cpufreq/armada-37xx-cpufreq.c
++++ b/drivers/cpufreq/armada-37xx-cpufreq.c
+@@ -202,6 +202,7 @@ static int __init armada37xx_cpufreq_dri
+ cur_frequency = clk_get_rate(clk);
+ if (!cur_frequency) {
+ dev_err(cpu_dev, "Failed to get clock rate for CPU\n");
++ clk_put(clk);
+ return -EINVAL;
+ }
+
+@@ -210,6 +211,7 @@ static int __init armada37xx_cpufreq_dri
+ return -EINVAL;
+
+ armada37xx_cpufreq_dvfs_setup(nb_pm_base, clk, dvfs->divider);
++ clk_put(clk);
+
+ for (load_lvl = ARMADA_37XX_DVFS_LOAD_0; load_lvl < LOAD_LEVEL_NR;
+ load_lvl++) {
--- /dev/null
+From 61c40f35f5cd6f67ccbd7319a1722eb78c815989 Mon Sep 17 00:00:00 2001
+From: Gregory CLEMENT <gregory.clement@bootlin.com>
+Date: Tue, 19 Jun 2018 14:34:45 +0200
+Subject: [PATCH] clk: mvebu: armada-37xx-periph: Fix switching CPU rate from
+ 300Mhz to 1.2GHz
+
+Switching the CPU from the L2 or L3 frequencies (300 and 200 Mhz
+respectively) to L0 frequency (1.2 Ghz) requires a significant amount
+of time to let VDD stabilize to the appropriate voltage. This amount of
+time is large enough that it cannot be covered by the hardware
+countdown register. Due to this, the CPU might start operating at L0
+before the voltage is stabilized, leading to CPU stalls.
+
+To work around this problem, we prevent switching directly from the
+L2/L3 frequencies to the L0 frequency, and instead switch to the L1
+frequency in-between. The sequence therefore becomes:
+
+1. First switch from L2/L3(200/300MHz) to L1(600MHZ)
+2. Sleep 20ms for stabling VDD voltage
+3. Then switch from L1(600MHZ) to L0(1200Mhz).
+
+It is based on the work done by Ken Ma <make@marvell.com>
+
+Cc: stable@vger.kernel.org
+Fixes: 2089dc33ea0e ("clk: mvebu: armada-37xx-periph: add DVFS support for cpu clocks")
+Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+---
+ drivers/clk/mvebu/armada-37xx-periph.c | 38 ++++++++++++++++++++++++++
+ 1 file changed, 38 insertions(+)
+
+--- a/drivers/clk/mvebu/armada-37xx-periph.c
++++ b/drivers/clk/mvebu/armada-37xx-periph.c
+@@ -35,6 +35,7 @@
+ #define CLK_SEL 0x10
+ #define CLK_DIS 0x14
+
++#define ARMADA_37XX_DVFS_LOAD_1 1
+ #define LOAD_LEVEL_NR 4
+
+ #define ARMADA_37XX_NB_L0L1 0x18
+@@ -507,6 +508,40 @@ static long clk_pm_cpu_round_rate(struct
+ return -EINVAL;
+ }
+
++/*
++ * Switching the CPU from the L2 or L3 frequencies (300 and 200 Mhz
++ * respectively) to L0 frequency (1.2 Ghz) requires a significant
++ * amount of time to let VDD stabilize to the appropriate
++ * voltage. This amount of time is large enough that it cannot be
++ * covered by the hardware countdown register. Due to this, the CPU
++ * might start operating at L0 before the voltage is stabilized,
++ * leading to CPU stalls.
++ *
++ * To work around this problem, we prevent switching directly from the
++ * L2/L3 frequencies to the L0 frequency, and instead switch to the L1
++ * frequency in-between. The sequence therefore becomes:
++ * 1. First switch from L2/L3(200/300MHz) to L1(600MHZ)
++ * 2. Sleep 20ms for stabling VDD voltage
++ * 3. Then switch from L1(600MHZ) to L0(1200Mhz).
++ */
++static void clk_pm_cpu_set_rate_wa(unsigned long rate, struct regmap *base)
++{
++ unsigned int cur_level;
++
++ if (rate != 1200 * 1000 * 1000)
++ return;
++
++ regmap_read(base, ARMADA_37XX_NB_CPU_LOAD, &cur_level);
++ cur_level &= ARMADA_37XX_NB_CPU_LOAD_MASK;
++ if (cur_level <= ARMADA_37XX_DVFS_LOAD_1)
++ return;
++
++ regmap_update_bits(base, ARMADA_37XX_NB_CPU_LOAD,
++ ARMADA_37XX_NB_CPU_LOAD_MASK,
++ ARMADA_37XX_DVFS_LOAD_1);
++ msleep(20);
++}
++
+ static int clk_pm_cpu_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+ {
+@@ -537,6 +572,9 @@ static int clk_pm_cpu_set_rate(struct cl
+ */
+ reg = ARMADA_37XX_NB_CPU_LOAD;
+ mask = ARMADA_37XX_NB_CPU_LOAD_MASK;
++
++ clk_pm_cpu_set_rate_wa(rate, base);
++
+ regmap_update_bits(base, reg, mask, load_level);
+
+ return rate;
--- /dev/null
+From 616bf80d381da13fbb392ebff06f46f946e3ee84 Mon Sep 17 00:00:00 2001
+From: Gregory CLEMENT <gregory.clement@bootlin.com>
+Date: Fri, 13 Jul 2018 12:27:26 +0200
+Subject: [PATCH] clk: mvebu: armada-37xx-periph: Fix wrong return value in
+ get_parent
+
+The return value of the get_parent operation is a u8, whereas a -EINVAL
+was returned. This wrong value was return if the value was bigger that
+the number of parent but this case was already handled by the core.
+
+So we can just remove this chunk of code to fix the issue.
+
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Fixes: 9818a7a4fd10 ("clk: mvebu: armada-37xx-periph: prepare cpu clk to
+be used with DVFS")
+Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+---
+ drivers/clk/mvebu/armada-37xx-periph.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+--- a/drivers/clk/mvebu/armada-37xx-periph.c
++++ b/drivers/clk/mvebu/armada-37xx-periph.c
+@@ -429,9 +429,6 @@ static u8 clk_pm_cpu_get_parent(struct c
+ val &= pm_cpu->mask_mux;
+ }
+
+- if (val >= num_parents)
+- return -EINVAL;
+-
+ return val;
+ }
+
--- /dev/null
+From 8927c27b32703e28041ae19bf25ea53461be83a1 Mon Sep 17 00:00:00 2001
+From: Anders Roxell <anders.roxell@linaro.org>
+Date: Fri, 27 Jul 2018 00:27:21 +0200
+Subject: [PATCH] clk: mvebu: armada-37xx-periph: Remove unused var num_parents
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+When building armada-37xx-periph, num_parents isn't used in function
+clk_pm_cpu_get_parent:
+drivers/clk/mvebu/armada-37xx-periph.c: In function ‘clk_pm_cpu_get_parent’:
+drivers/clk/mvebu/armada-37xx-periph.c:419:6: warning: unused variable ‘num_parents’ [-Wunused-variable]
+ int num_parents = clk_hw_get_num_parents(hw);
+ ^~~~~~~~~~~
+Remove the declaration of num_parents to dispose the warning.
+
+Fixes: 616bf80d381d ("clk: mvebu: armada-37xx-periph: Fix wrong return value in get_parent")
+Signed-off-by: Anders Roxell <anders.roxell@linaro.org>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+---
+ drivers/clk/mvebu/armada-37xx-periph.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/clk/mvebu/armada-37xx-periph.c
++++ b/drivers/clk/mvebu/armada-37xx-periph.c
+@@ -419,7 +419,6 @@ static unsigned int armada_3700_pm_dvfs_
+ static u8 clk_pm_cpu_get_parent(struct clk_hw *hw)
+ {
+ struct clk_pm_cpu *pm_cpu = to_clk_pm_cpu(hw);
+- int num_parents = clk_hw_get_num_parents(hw);
+ u32 val;
+
+ if (armada_3700_pm_dvfs_is_enabled(pm_cpu->nb_pm_base)) {
--- /dev/null
+From eefe328439642101774f0f5c4ea0dc6ba1cfb687 Mon Sep 17 00:00:00 2001
+From: Ding Tao <miyatsu@qq.com>
+Date: Fri, 26 Oct 2018 11:50:27 +0000
+Subject: [PATCH] arm64: dts: marvell: armada37xx: Add emmc/sdio pinctrl
+ definition
+
+Add emmc/sdio pinctrl definition for marvell armada37xx SoCs.
+
+Signed-off-by: Ding Tao <miyatsu@qq.com>
+Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
+---
+ arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
++++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
+@@ -218,6 +218,11 @@
+ groups = "uart2";
+ function = "uart";
+ };
++
++ mmc_pins: mmc-pins {
++ groups = "emmc_nb";
++ function = "emmc";
++ };
+ };
+
+ nb_pm: syscon@14000 {
+@@ -247,6 +252,11 @@
+ function = "mii";
+ };
+
++ sdio_pins: sdio-pins {
++ groups = "sdio_sb";
++ function = "sdio";
++ };
++
+ };
+
+ eth0: ethernet@30000 {
--- /dev/null
+From 43ebc7c1b3ed8198b9acf3019eca16e722f7331c Mon Sep 17 00:00:00 2001
+From: Ding Tao <miyatsu@qq.com>
+Date: Fri, 26 Oct 2018 11:50:28 +0000
+Subject: [PATCH] arm64: dts: marvell: armada-37xx: Enable emmc on espressobin
+
+The ESPRESSObin board has a emmc interface available on U11: declare it
+and let the bootloader enable it if the emmc is present.
+
+[gregory.clement@bootlin.com: disable the emmc by default]
+Signed-off-by: Ding Tao <miyatsu@qq.com>
+Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
+---
+ .../dts/marvell/armada-3720-espressobin.dts | 22 +++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
+--- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts
++++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts
+@@ -93,9 +93,31 @@
+ cd-gpios = <&gpionb 3 GPIO_ACTIVE_LOW>;
+ marvell,pad-type = "sd";
+ vqmmc-supply = <&vcc_sd_reg1>;
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdio_pins>;
+ status = "okay";
+ };
+
++/* U11 */
++&sdhci0 {
++ non-removable;
++ bus-width = <8>;
++ mmc-ddr-1_8v;
++ mmc-hs400-1_8v;
++ marvell,xenon-emmc;
++ marvell,xenon-tun-count = <9>;
++ marvell,pad-type = "fixed-1-8v";
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&mmc_pins>;
++/*
++ * This eMMC is not populated on all boards, so disable it by
++ * default and let the bootloader enable it, if it is present
++ */
++ status = "disabled";
++};
++
+ &spi0 {
+ status = "okay";
+
--- /dev/null
+From be893f672e340b56ca60f2f6c32fdd713a5852f5 Mon Sep 17 00:00:00 2001
+From: Kevin Mihelich <kevin@archlinuxarm.org>
+Date: Tue, 4 Jul 2017 19:25:28 -0600
+Subject: arm64: dts: marvell: armada37xx: Add eth0 alias
+
+Signed-off-by: Kevin Mihelich <kevin@archlinuxarm.org>
+---
+ arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
++++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
+@@ -54,6 +54,7 @@
+ #size-cells = <2>;
+
+ aliases {
++ ethernet0 = ð0;
+ serial0 = &uart0;
+ };
+
--- /dev/null
+From 3217cdfe8a3eae76fafbebbe407be5985a7fd4c2 Mon Sep 17 00:00:00 2001
+From: Tomasz Maciej Nowak <tmn505@gmail.com>
+Date: Mon, 31 Dec 2018 14:18:50 +0100
+Subject: [PATCH] arm64: dts: armada-3720-espressobin: correct spi node
+
+The manufacturer of this board, ships it with various SPI NOR chips and
+increments U-Boot bootloader version along the time. There is no way to
+tell which is placed on the board since no revision bump takes place.
+This creates two issues.
+
+The first, cosmetic. Since the SPI chip may differ, there's message on
+boot stating that kernel expected w25q32dw and found different one. To
+correct this, remove optional device-specific compatible string. Being
+here lets replace bogus "spi-flash" string with proper one.
+
+The second is linked to partitions layout, it changed after commit [1]
+in Marvells downstream U-Boot fork, shifting environment location to the
+end of boot device. Since the new boards can have U-Boot with this
+change it can lead to improper results writing or reading from these
+partitions. We can't tell if users will update bootloader to recent
+version, so let's drop current layout.
+
+1. https://github.com/MarvellEmbeddedProcessors/u-boot-marvell/commit/81e7251252aefe1a6b829ed05f3586320cb45372
+
+Signed-off-by: Tomasz Maciej Nowak <tmn505@gmail.com>
+---
+ .../dts/marvell/armada-3720-espressobin.dts | 18 +-----------------
+ 1 file changed, 1 insertion(+), 17 deletions(-)
+
+--- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts
++++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts
+@@ -123,25 +123,9 @@
+
+ flash@0 {
+ reg = <0>;
+- compatible = "winbond,w25q32dw", "jedec,spi-flash";
++ compatible = "jedec,spi-nor";
+ spi-max-frequency = <104000000>;
+ m25p,fast-read;
+-
+- partitions {
+- compatible = "fixed-partitions";
+- #address-cells = <1>;
+- #size-cells = <1>;
+-
+- partition@0 {
+- label = "uboot";
+- reg = <0 0x180000>;
+- };
+-
+- partition@180000 {
+- label = "ubootenv";
+- reg = <0x180000 0x10000>;
+- };
+- };
+ };
+ };
+
--- /dev/null
+From 6ea9a1ee9367fb35acff1c08a0dc4213ff4687a0 Mon Sep 17 00:00:00 2001
+From: Tomasz Maciej Nowak <tmn505@gmail.com>
+Date: Tue, 9 Apr 2019 15:53:42 +0200
+Subject: [PATCH] arm64: dts: marvell: armada-3720-espressobin: add ports
+ phandle
+
+Instead of referencing the whole mdio node, add ports phandle to adjust
+port labels in dts for different hardware iterations of ESPRESSObin
+boards.
+
+Signed-off-by: Tomasz Maciej Nowak <tmn505@gmail.com>
+---
+ arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts
++++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts
+@@ -153,7 +153,7 @@
+
+ dsa,member = <0 0>;
+
+- ports {
++ ports: ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
--- /dev/null
+From patchwork Thu Sep 28 12:58:34 2017
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Subject: [v2,
+ 3/7] PCI: aardvark: set host and device to the same MAX payload size
+X-Patchwork-Submitter: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+X-Patchwork-Id: 819587
+Message-Id: <20170928125838.11887-4-thomas.petazzoni@free-electrons.com>
+To: Bjorn Helgaas <bhelgaas@google.com>, linux-pci@vger.kernel.org
+Cc: Jason Cooper <jason@lakedaemon.net>, Andrew Lunn <andrew@lunn.ch>,
+ Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>, Gregory Clement
+ <gregory.clement@free-electrons.com>,
+ Nadav Haklai <nadavh@marvell.com>, Hanna Hawa <hannah@marvell.com>,
+ Yehuda Yitschak <yehuday@marvell.com>,
+ linux-arm-kernel@lists.infradead.org, Antoine Tenart
+ <antoine.tenart@free-electrons.com>, =?utf-8?q?Miqu=C3=A8l_Raynal?=
+ <miquel.raynal@free-electrons.com>, Victor Gu <xigu@marvell.com>,
+ Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+Date: Thu, 28 Sep 2017 14:58:34 +0200
+From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+List-Id: <linux-pci.vger.kernel.org>
+
+From: Victor Gu <xigu@marvell.com>
+
+Since the Aardvark does not implement a PCIe root bus, the Linux PCIe
+subsystem will not align the MAX payload size between the host and the
+device. This patch ensures that the host and device have the same MAX
+payload size, fixing a number of problems with various PCIe devices.
+
+This is part of fixing bug
+https://bugzilla.kernel.org/show_bug.cgi?id=196339, this commit was
+reported as the user to be important to get a Intel 7260 mini-PCIe
+WiFi card working.
+
+Fixes: Fixes: 8c39d710363c1 ("PCI: aardvark: Add Aardvark PCI host controller driver")
+Signed-off-by: Victor Gu <xigu@marvell.com>
+Reviewed-by: Evan Wang <xswang@marvell.com>
+Reviewed-by: Nadav Haklai <nadavh@marvell.com>
+[Thomas: tweak commit log.]
+Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+---
+ drivers/pci/host/pci-aardvark.c | 60 ++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 59 insertions(+), 1 deletion(-)
+
+--- a/drivers/pci/host/pci-aardvark.c
++++ b/drivers/pci/host/pci-aardvark.c
+@@ -30,9 +30,11 @@
+ #define PCIE_CORE_DEV_CTRL_STATS_REG 0xc8
+ #define PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE (0 << 4)
+ #define PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT 5
++#define PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ 0x2
+ #define PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE (0 << 11)
+ #define PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT 12
+ #define PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SZ 0x2
++#define PCIE_CORE_MPS_UNIT_BYTE 128
+ #define PCIE_CORE_LINK_CTRL_STAT_REG 0xd0
+ #define PCIE_CORE_LINK_L0S_ENTRY BIT(0)
+ #define PCIE_CORE_LINK_TRAINING BIT(5)
+@@ -297,7 +299,8 @@ static void advk_pcie_setup_hw(struct ad
+
+ /* Set PCIe Device Control and Status 1 PF0 register */
+ reg = PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE |
+- (7 << PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT) |
++ (PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ <<
++ PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT) |
+ PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE |
+ (PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SZ <<
+ PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT);
+@@ -886,6 +889,58 @@ out_release_res:
+ return err;
+ }
+
++static int advk_pcie_find_smpss(struct pci_dev *dev, void *data)
++{
++ u8 *smpss = data;
++
++ if (!dev)
++ return 0;
++
++ if (!pci_is_pcie(dev))
++ return 0;
++
++ if (*smpss > dev->pcie_mpss)
++ *smpss = dev->pcie_mpss;
++
++ return 0;
++}
++
++static int advk_pcie_bus_configure_mps(struct pci_dev *dev, void *data)
++{
++ int mps;
++
++ if (!dev)
++ return 0;
++
++ if (!pci_is_pcie(dev))
++ return 0;
++
++ mps = PCIE_CORE_MPS_UNIT_BYTE << *(u8 *)data;
++ pcie_set_mps(dev, mps);
++
++ return 0;
++}
++
++static void advk_pcie_configure_mps(struct pci_bus *bus, struct advk_pcie *pcie)
++{
++ u8 smpss = PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ;
++ u32 reg;
++
++ /* Find the minimal supported MAX payload size */
++ advk_pcie_find_smpss(bus->self, &smpss);
++ pci_walk_bus(bus, advk_pcie_find_smpss, &smpss);
++
++ /* Configure RC MAX payload size */
++ reg = advk_readl(pcie, PCIE_CORE_DEV_CTRL_STATS_REG);
++ reg &= ~PCI_EXP_DEVCTL_PAYLOAD;
++ reg |= smpss << PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT;
++ advk_writel(pcie, reg, PCIE_CORE_DEV_CTRL_STATS_REG);
++
++ /* Configure device MAX payload size */
++ advk_pcie_bus_configure_mps(bus->self, &smpss);
++ pci_walk_bus(bus, advk_pcie_bus_configure_mps, &smpss);
++}
++
+ static int advk_pcie_probe(struct platform_device *pdev)
+ {
+ struct device *dev = &pdev->dev;
+@@ -960,6 +1015,9 @@ static int advk_pcie_probe(struct platfo
+ list_for_each_entry(child, &bus->children, node)
+ pcie_bus_configure_settings(child);
+
++ /* Configure the MAX pay load size */
++ advk_pcie_configure_mps(bus, pcie);
++
+ pci_bus_add_devices(bus);
+ return 0;
+ }
--- /dev/null
+From patchwork Thu Sep 28 12:58:36 2017
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Subject: [v2,5/7] PCI: aardvark: disable LOS state by default
+X-Patchwork-Submitter: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+X-Patchwork-Id: 819590
+Message-Id: <20170928125838.11887-6-thomas.petazzoni@free-electrons.com>
+To: Bjorn Helgaas <bhelgaas@google.com>, linux-pci@vger.kernel.org
+Cc: Jason Cooper <jason@lakedaemon.net>, Andrew Lunn <andrew@lunn.ch>,
+ Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>, Gregory Clement
+ <gregory.clement@free-electrons.com>,
+ Nadav Haklai <nadavh@marvell.com>, Hanna Hawa <hannah@marvell.com>,
+ Yehuda Yitschak <yehuday@marvell.com>,
+ linux-arm-kernel@lists.infradead.org, Antoine Tenart
+ <antoine.tenart@free-electrons.com>, =?utf-8?q?Miqu=C3=A8l_Raynal?=
+ <miquel.raynal@free-electrons.com>, Victor Gu <xigu@marvell.com>,
+ Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+Date: Thu, 28 Sep 2017 14:58:36 +0200
+From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+List-Id: <linux-pci.vger.kernel.org>
+
+From: Victor Gu <xigu@marvell.com>
+
+Some PCIe devices do not support LOS, and will cause timeouts if the
+root complex forces the LOS state. This patch disables the LOS state
+by default.
+
+This is part of fixing bug
+https://bugzilla.kernel.org/show_bug.cgi?id=196339, this commit was
+reported as the user to be important to get a Intel 7260 mini-PCIe
+WiFi card working.
+
+Fixes: 8c39d710363c1 ("PCI: aardvark: Add Aardvark PCI host controller driver")
+Signed-off-by: Victor Gu <xigu@marvell.com>
+Reviewed-by: Evan Wang <xswang@marvell.com>
+Reviewed-by: Nadav Haklai <nadavh@marvell.com>
+[Thomas: tweak commit log.]
+Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+---
+ drivers/pci/host/pci-aardvark.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/pci/host/pci-aardvark.c
++++ b/drivers/pci/host/pci-aardvark.c
+@@ -368,8 +368,7 @@ static void advk_pcie_setup_hw(struct ad
+
+ advk_pcie_wait_for_link(pcie);
+
+- reg = PCIE_CORE_LINK_L0S_ENTRY |
+- (1 << PCIE_CORE_LINK_WIDTH_SHIFT);
++ reg = (1 << PCIE_CORE_LINK_WIDTH_SHIFT);
+ advk_writel(pcie, reg, PCIE_CORE_LINK_CTRL_STAT_REG);
+
+ reg = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG);
--- /dev/null
+From f70b629e488cc3f2a325ac35476f4f7ae502c5d0 Mon Sep 17 00:00:00 2001
+From: Tomasz Maciej Nowak <tmn505@gmail.com>
+Date: Thu, 14 Jun 2018 14:24:40 +0200
+Subject: [PATCH 1/2] PCI: aardvark: allow to specify link capability
+
+Use DT of_pci_get_max_link_speed() facility to allow specifying link
+capability. If none or unspecified value is given it falls back to gen2,
+which is default for Armada 3700 SoC.
+
+Signed-off-by: Tomasz Maciej Nowak <tmn505@gmail.com>
+---
+ drivers/pci/host/pci-aardvark.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+--- a/drivers/pci/host/pci-aardvark.c
++++ b/drivers/pci/host/pci-aardvark.c
+@@ -272,6 +272,8 @@ static void advk_pcie_set_ob_win(struct
+
+ static void advk_pcie_setup_hw(struct advk_pcie *pcie)
+ {
++ struct device *dev = &pcie->pdev->dev;
++ struct device_node *node = dev->of_node;
+ u32 reg;
+ int i;
+
+@@ -311,10 +313,15 @@ static void advk_pcie_setup_hw(struct ad
+ PCIE_CORE_CTRL2_TD_ENABLE;
+ advk_writel(pcie, reg, PCIE_CORE_CTRL2_REG);
+
+- /* Set GEN2 */
++ /* Set GEN */
+ reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG);
+ reg &= ~PCIE_GEN_SEL_MSK;
+- reg |= SPEED_GEN_2;
++ if (of_pci_get_max_link_speed(node) == 1)
++ reg |= SPEED_GEN_1;
++ else if (of_pci_get_max_link_speed(node) == 3)
++ reg |= SPEED_GEN_3;
++ else
++ reg |= SPEED_GEN_2;
+ advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG);
+
+ /* Set lane X1 */
--- /dev/null
+From 33f8fdcedb01680427328d710594facef7a0092c Mon Sep 17 00:00:00 2001
+From: Tomasz Maciej Nowak <tmn505@gmail.com>
+Date: Thu, 14 Jun 2018 14:40:26 +0200
+Subject: [PATCH 2/2] arm64: dts: armada-3720-espressobin: set max link to gen1
+
+Since the beginning there's been an issue with initializing the Atheros
+based MiniPCIe wireless cards. Here's an example of kerenel log:
+
+ OF: PCI: host bridge /soc/pcie@d0070000 ranges:
+ OF: PCI: MEM 0xe8000000..0xe8ffffff -> 0xe8000000
+ OF: PCI: IO 0xe9000000..0xe900ffff -> 0xe9000000
+ advk-pcie d0070000.pcie: link up
+ advk-pcie d0070000.pcie: PCI host bridge to bus 0000:00
+ pci_bus 0000:00: root bus resource [bus 00-ff]
+ pci_bus 0000:00: root bus resource [mem0xe8000000-0xe8ffffff]
+ pci_bus 0000:00: root bus resource [io 0x0000-0xffff](bus address [0xe9000000-0xe900ffff])
+ pci 0000:00:00.0: BAR 0: assigned [mem0xe8000000-0xe801ffff 64bit]
+ pci 0000:00:00.0: BAR 6: assigned [mem0xe8020000-0xe802ffff pref]
+ [...]
+ advk-pcie d0070000.pcie: Posted PIO Response Status: CA,0xe00 @ 0x3c
+ advk-pcie d0070000.pcie: Posted PIO Response Status: CA,0xe00 @ 0x44
+ advk-pcie d0070000.pcie: Posted PIO Response Status: CA,0xe00 @ 0x4
+ ath9k 0000:00:00.0: enabling device (0000 -> 0002)
+ advk-pcie d0070000.pcie: Posted PIO Response Status: CA,0xe00 @ 0x3c
+ advk-pcie d0070000.pcie: Posted PIO Response Status: CA,0xe00 @ 0xc
+ advk-pcie d0070000.pcie: Posted PIO Response Status: CA,0xe00 @ 0x4
+ advk-pcie d0070000.pcie: Posted PIO Response Status: CA,0xe00 @ 0x40
+ ath9k 0000:00:00.0: request_irq failed
+ advk-pcie d0070000.pcie: Posted PIO Response Status: CA,0xe00 @ 0x4
+ ath9k: probe of 0000:00:00.0 failed with error -22
+
+The same happens for ath5k cards, while ath10k card didn't appear at
+all (not detected):
+
+ OF: PCI: host bridge /soc/pcie@d0070000 ranges:
+ OF: PCI: MEM 0xe8000000..0xe8ffffff -> 0xe8000000
+ OF: PCI: IO 0xe9000000..0xe900ffff -> 0xe9000000
+ advk-pcie d0070000.pcie: link never came up
+ advk-pcie d0070000.pcie: PCI host bridge to bus 0000:00
+ pci_bus 0000:00: root bus resource [bus 00-ff]
+ pci_bus 0000:00: root bus resource [mem0xe8000000-0xe8ffffff]
+ pci_bus 0000:00: root bus resource [io 0x0000-0xffff](bus address [0xe9000000-0xe900ffff])
+ advk-pcie d0070000.pcie: config read/write timed out
+
+Following the issue on esppressobin.net forum [1] the workaround seems
+to be limiting the speed of PCIe bridge to 1st generation. This fixed
+the initialisation of all tested Atheros wireless cards.
+The patch in the forum thread swaped registers which would limit speed
+for all Armada 3700 based boards. The approach in this patch, in
+conjunction with "PCI: aardvark: allow to specify link capability" patch
+is less invasive, it only touches the affected board.
+
+For the record, the iwlwifi and mt76 cards were not affected by this
+issue.
+
+1. http://espressobin.net/forums/topic/which-pcie-wlan-cards-are-supported
+
+Signed-off-by: Tomasz Maciej Nowak <tmn505@gmail.com>
+---
+ arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts
++++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts
+@@ -79,6 +79,8 @@
+ /* J9 */
+ &pcie0 {
+ status = "okay";
++
++ max-link-speed = <1>;
+ };
+
+ /* J6 */
--- /dev/null
+From bb683d7ad9d53442586cfdd0a79a6d6c1fec344e Mon Sep 17 00:00:00 2001
+From: Baruch Siach <baruch@tkos.co.il>
+Date: Thu, 28 Jun 2018 10:13:35 +0300
+Subject: [PATCH] ARM: dts: armada388-clearfog: enable spi flash
+
+The SolidRun Armada 388 SOM has the SPI flash populated by default
+unless the customer explicitly asks otherwise. Enable support by
+default.
+
+Signed-off-by: Baruch Siach <baruch@tkos.co.il>
+Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
+---
+ arch/arm/boot/dts/armada-388-clearfog.dts | 2 +-
+ arch/arm/boot/dts/armada-388-clearfog.dtsi | 2 +-
+ arch/arm/boot/dts/armada-38x-solidrun-microsom.dtsi | 1 -
+ 3 files changed, 2 insertions(+), 3 deletions(-)
+
+--- a/arch/arm/boot/dts/armada-388-clearfog.dts
++++ b/arch/arm/boot/dts/armada-388-clearfog.dts
+@@ -284,7 +284,7 @@
+ &spi1 {
+ /*
+ * Add SPI CS pins for clearfog:
+- * CS0: W25Q32 (not populated on uSOM)
++ * CS0: W25Q32
+ * CS1:
+ * CS2: mikrobus
+ */
+--- a/arch/arm/boot/dts/armada-388-clearfog.dtsi
++++ b/arch/arm/boot/dts/armada-388-clearfog.dtsi
+@@ -265,7 +265,7 @@
+ &spi1 {
+ /*
+ * Add SPI CS pins for clearfog:
+- * CS0: W25Q32 (not populated on uSOM)
++ * CS0: W25Q32
+ * CS1: PIC microcontroller (Pro models)
+ * CS2: mikrobus
+ */
+--- a/arch/arm/boot/dts/armada-38x-solidrun-microsom.dtsi
++++ b/arch/arm/boot/dts/armada-38x-solidrun-microsom.dtsi
+@@ -135,7 +135,6 @@
+ compatible = "w25q32", "jedec,spi-nor";
+ reg = <0>; /* Chip select 0 */
+ spi-max-frequency = <3000000>;
+- status = "disabled";
+ };
+ };
+
--- /dev/null
+From e01b5939b38aea5ecbe41670643199825874b26c Mon Sep 17 00:00:00 2001
+From: Rich Felker <dalias@aerifal.cx>
+Date: Thu, 21 May 2020 23:32:45 -0400
+Subject: [PATCH 2/4] don't use libc.threads_minus_1 as relaxed atomic for
+ skipping locks
+
+after all but the last thread exits, the next thread to observe
+libc.threads_minus_1==0 and conclude that it can skip locking fails to
+synchronize with any changes to memory that were made by the
+last-exiting thread. this can produce data races.
+
+on some archs, at least x86, memory synchronization is unlikely to be
+a problem; however, with the inline locks in malloc, skipping the lock
+also eliminated the compiler barrier, and caused code that needed to
+re-check chunk in-use bits after obtaining the lock to reuse a stale
+value, possibly from before the process became single-threaded. this
+in turn produced corruption of the heap state.
+
+some uses of libc.threads_minus_1 remain, especially for allocation of
+new TLS in the dynamic linker; otherwise, it could be removed
+entirely. it's made non-volatile to reflect that the remaining
+accesses are only made under lock on the thread list.
+
+instead of libc.threads_minus_1, libc.threaded is now used for
+skipping locks. the difference is that libc.threaded is permanently
+true once an additional thread has been created. this will produce
+some performance regression in processes that are mostly
+single-threaded but occasionally creating threads. in the future it
+may be possible to bring back the full lock-skipping, but more care
+needs to be taken to produce a safe design.
+---
+ src/internal/libc.h | 2 +-
+ src/malloc/malloc.c | 2 +-
+ src/thread/__lock.c | 2 +-
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+--- a/src/internal/libc.h
++++ b/src/internal/libc.h
+@@ -21,7 +21,7 @@ struct __libc {
+ int can_do_threads;
+ int threaded;
+ int secure;
+- volatile int threads_minus_1;
++ int threads_minus_1;
+ size_t *auxv;
+ struct tls_module *tls_head;
+ size_t tls_size, tls_align, tls_cnt;
+--- a/src/malloc/malloc.c
++++ b/src/malloc/malloc.c
+@@ -26,7 +26,7 @@ int __malloc_replaced;
+
+ static inline void lock(volatile int *lk)
+ {
+- if (libc.threads_minus_1)
++ if (libc.threaded)
+ while(a_swap(lk, 1)) __wait(lk, lk+1, 1, 1);
+ }
+
+--- a/src/thread/__lock.c
++++ b/src/thread/__lock.c
+@@ -18,7 +18,7 @@
+
+ void __lock(volatile int *l)
+ {
+- if (!libc.threads_minus_1) return;
++ if (!libc.threaded) return;
+ /* fast path: INT_MIN for the lock, +1 for the congestion */
+ int current = a_cas(l, 0, INT_MIN + 1);
+ if (!current) return;
tools-y += m4 libtool autoconf automake flex bison pkg-config mklibs zlib
tools-y += sstrip make-ext4fs e2fsprogs mtd-utils mkimage
tools-y += firmware-utils patch-image quilt padjffs2
-tools-y += mm-macros missing-macros cmake scons bc findutils gengetopt patchelf
+tools-y += mm-macros missing-macros cmake bc findutils gengetopt patchelf
tools-y += mtools dosfstools libressl
tools-$(CONFIG_TARGET_orion_generic) += wrt350nv2-builder upslug2
tools-$(CONFIG_TARGET_x86) += qemu
+++ /dev/null
-#
-# Copyright (C) 2011-2015 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-include $(TOPDIR)/rules.mk
-
-PKG_NAME:=scons
-PKG_VERSION:=3.0.5
-
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=@SF/scons \
- http://fossies.org/linux/misc/
-PKG_HASH:=df676f23dc6d4bfa384fc389d95dcd21ab907e6349d4c848958ba4befb73c73e
-
-include $(INCLUDE_DIR)/host-build.mk
-
-define Host/Configure
-endef
-
-define Host/Compile
-endef
-
-define Host/Install
- ./files/pywrap.sh $(HOST_BUILD_DIR)/setup.py install --prefix=$(STAGING_DIR_HOST)
- rm -f $(STAGING_DIR_HOST)/bin/scons*.py
- for bin in $(STAGING_DIR_HOST)/bin/scons*; do \
- mv "$$$$bin" "$$$$bin.py"; \
- cp ./files/pywrap.sh "$$$$bin"; \
- done
-endef
-
-$(eval $(call HostBuild))
+++ /dev/null
-#!/usr/bin/env bash
-
-case "${0##*/}" in
- pywrap.sh) arg1="";;
- *) arg1="$0.py" ;;
-esac
-
-for bin in python python2 python2.7 python2.6 python2.5 python2.4; do
- case "$($bin -V 2>&1)" in
- "Python 2"*) exec $bin $arg1 "$@" ;;
- esac
-done
-
-echo "Unable to find a Python 2.x interpreter for executing ${arg1:+$arg1 }$@ !" >&2
-exit 1
+++ /dev/null
---- a/engine/SCons/Platform/__init__.py
-+++ b/engine/SCons/Platform/__init__.py
-@@ -65,6 +65,8 @@ def platform_default():
- care about the machine architecture.
- """
- osname = os.name
-+ if 'PLATFORM' in os.environ:
-+ return os.environ['PLATFORM']
- if osname == 'java':
- osname = os._osType
- if osname == 'posix':
--- /dev/null
+Fixes the following build error with GCC 10:
+ /usr/bin/ld: read_fs.o:(.bss+0x0): multiple definition of `swap'; mksquashfs.o:(.bss+0x1b2a88): first defined here
+And a compile warning.
+
+--- a/squashfs-tools/read_fs.c
++++ b/squashfs-tools/read_fs.c
+@@ -61,7 +61,7 @@ extern int add_file(long long, long long
+ fprintf(stderr, s, ## args); \
+ } while(0)
+
+-int swap;
++static int swap;
+
+ int read_block(int fd, long long start, long long *next, unsigned char *block, squashfs_super_block *sBlk)
+ {
+--- a/squashfs-tools/mksquashfs.c
++++ b/squashfs-tools/mksquashfs.c
+@@ -258,6 +258,7 @@ int read_sort_file(char *filename, int s
+ void sort_files_and_write(struct dir_info *dir);
+ struct file_info *duplicate(char *(get_next_file_block)(struct duplicate_buffer_handle *, unsigned int), struct duplicate_buffer_handle *file_start, long long bytes, unsigned int **block_list, long long *start, int blocks, struct fragment **fragment, char *frag_data, int frag_bytes);
+ struct dir_info *dir_scan1(char *, int (_readdir)(char *, char *, struct dir_info *));
++int dir_scan2(squashfs_inode *inode, struct dir_info *dir_info);
+
+ #define MKINODE(A) ((squashfs_inode)(((squashfs_inode) inode_bytes << 16) + (((char *)A) - data_cache)))
+