target: add support for p2w-r619ac

This commit is contained in:
CN_SZTL 2020-02-01 01:49:51 +08:00
parent 79c0342e2d
commit a139f9c9e9
No known key found for this signature in database
GPG Key ID: 6850B6345C862176
34 changed files with 4620 additions and 1 deletions

View File

@ -31,7 +31,8 @@ ALLWIFIBOARDS:= \
engenius_emd1 \
ezviz_cs-w3-wd1200g-eup \
linksys_ea8300 \
qxwlan_e2600ac
qxwlan_e2600ac \
p2w_r619ac
ALLWIFIPACKAGES:=$(foreach BOARD,$(ALLWIFIBOARDS),ipq-wifi-$(BOARD))
@ -99,5 +100,6 @@ $(eval $(call generate-ipq-wifi-package,engenius_emd1,EnGenius EMD1))
$(eval $(call generate-ipq-wifi-package,ezviz_cs-w3-wd1200g-eup,EZVIZ CS-W3-WD1200G EUP))
$(eval $(call generate-ipq-wifi-package,linksys_ea8300,Linksys EA8300))
$(eval $(call generate-ipq-wifi-package,qxwlan_e2600ac,Qxwlan E2600AC))
$(eval $(call generate-ipq-wifi-package,p2w_r619ac,board-p2w_r619ac.qca4019,P&W R619AC))
$(foreach PACKAGE,$(ALLWIFIPACKAGES),$(eval $(call BuildPackage,$(PACKAGE))))

View File

@ -14,6 +14,11 @@ case "$board" in
alfa-network,ap120c-ac)
ucidef_set_led_netdev "wan" "WAN" "${boardname}:amber:wan" "eth1"
;;
p2w,r619ac |\
p2w,r619ac-128m)
ucidef_set_led_wlan "wlan2g" "WLAN2G" "r619ac:blue:wlan2g" "phy0tpt"
ucidef_set_led_wlan "wlan5g" "WLAN5G" "r619ac:blue:wlan5g" "phy1tpt"
;;
asus,rt-ac58u)
ucidef_set_led_netdev "wan" "WAN" "${boardname}:blue:wan" "eth1"
ucidef_set_led_switch "lan" "LAN" "${boardname}:blue:lan" "switch0" "0x1e"

View File

@ -29,6 +29,8 @@ ipq40xx_setup_interfaces()
ucidef_set_interfaces_lan_wan "eth1" "eth0"
;;
asus,rt-ac58u|\
p2w,r619ac|\
p2w,r619ac-128m|\
zyxel,nbg6617)
ucidef_set_interfaces_lan_wan "eth0" "eth1"
ucidef_add_switch "switch0" \
@ -102,6 +104,11 @@ ipq40xx_setup_macs()
lan_mac=$(mtd_get_mac_binary_ubi Factory 0x5006)
label_mac=$wan_mac
;;
p2w,r619ac|\
p2w,r619ac-128m)
wan_mac=$(cat /sys/class/net/eth0/address)
lan_mac=$(macaddr_add "$wan_mac" 1)
;;
cilab,meshpoint-one)
label_mac=$(mtd_get_mac_binary "ART" 0x1006)
;;

View File

@ -39,6 +39,10 @@ case "$FIRMWARE" in
openmesh,a62)
caldata_extract "0:ART" 0x9000 0x2f20
;;
p2w,r619ac |\
p2w,r619ac-128m)
ath10kcal_extract "ART" 36864 12064
;;
esac
;;
"ath10k/pre-cal-ahb-a000000.wifi.bin")
@ -49,6 +53,8 @@ case "$FIRMWARE" in
ezviz,cs-w3-wd1200g-eup |\
glinet,gl-b1300 |\
linksys,ea6350v3 |\
p2w,r619ac |\
p2w,r619ac-128m |\
qcom,ap-dk01.1-c1)
caldata_extract "ART" 0x1000 0x2f20
;;
@ -128,6 +134,8 @@ case "$FIRMWARE" in
ezviz,cs-w3-wd1200g-eup |\
glinet,gl-b1300 |\
linksys,ea6350v3 |\
p2w,r619ac |\
p2w,r619ac-128m |\
qcom,ap-dk01.1-c1)
caldata_extract "ART" 0x5000 0x2f20
;;

View File

@ -67,6 +67,10 @@ platform_do_upgrade() {
fi
nand_do_upgrade "$1"
;;
p2w,r619ac|\
p2w,r619ac-128m)
nand_do_upgrade "$1"
;;
asus,map-ac2200)
CI_KERNPART="linux"
nand_do_upgrade "$1"

View File

@ -0,0 +1,18 @@
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
#include "qcom-ipq4019-r619ac.dtsi"
/ {
model = "P&W R619AC 128M";
compatible = "p2w,r619ac-128m";
chosen {
bootargs-append = " root=/dev/ubiblock0_1 rootfstype=squashfs";
};
};
&rootfs_part1 {
reg = <0x0 0x8000000>;
};
/delete-node/ &rootfs_part2;

View File

@ -0,0 +1,12 @@
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
#include "qcom-ipq4019-r619ac.dtsi"
/ {
model = "P&W R619AC";
compatible = "p2w,r619ac";
chosen {
bootargs-append = " root=/dev/ubiblock0_1 rootfstype=squashfs";
};
};

View File

@ -0,0 +1,18 @@
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
#include "qcom-ipq4019-r619ac.dtsi"
/ {
model = "P&W R619AC 128M";
compatible = "p2w,r619ac-128m";
chosen {
bootargs-append = " root=/dev/ubiblock0_1 rootfstype=squashfs";
};
};
&rootfs_part1 {
reg = <0x0 0x8000000>;
};
/delete-node/ &rootfs_part2;

View File

@ -0,0 +1,12 @@
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
#include "qcom-ipq4019-r619ac.dtsi"
/ {
model = "P&W R619AC";
compatible = "p2w,r619ac";
chosen {
bootargs-append = " root=/dev/ubiblock0_1 rootfstype=squashfs";
};
};

View File

@ -484,6 +484,35 @@ define Device/qcom_ap-dk01.1-c1
endef
TARGET_DEVICES += qcom_ap-dk01.1-c1
define Device/p2w_r619ac
$(call Device/FitzImage)
$(call Device/UbiFit)
DEVICE_VENDOR := P&W
DEVICE_MODEL := R619AC
DEVICE_DTS := qcom-ipq4019-r619ac
DEVICE_DTS_CONFIG := config@10
BLOCKSIZE := 128k
PAGESIZE := 2048
IMAGES += nand-factory.bin
IMAGE/nand-factory.bin := append-ubi | qsdk-ipq-factory-nand
DEVICE_PACKAGES := ipq-wifi-p2w_r619ac
endef
TARGET_DEVICES += p2w_r619ac
define Device/p2w_r619ac-128m
$(call Device/FitzImage)
$(call Device/UbiFit)
DEVICE_VENDOR := P&W
DEVICE_MODEL := R619AC
DEVICE_VARIANT := 128M
DEVICE_DTS := qcom-ipq4019-r619ac-128m
DEVICE_DTS_CONFIG := config@10
BLOCKSIZE := 128k
PAGESIZE := 2048
DEVICE_PACKAGES := ipq-wifi-p2w_r619ac
endef
TARGET_DEVICES += p2w_r619ac-128m
define Device/qcom_ap-dk04.1-c1
$(call Device/FitImage)
$(call Device/UbiFit)

View File

@ -0,0 +1,27 @@
From 61a3bd10082b0e861b4e1bc451a92e20181a52f5 Mon Sep 17 00:00:00 2001
From: Felix Fietkau <nbd@nbd.name>
Date: Mon, 23 Jul 2018 16:17:35 +0200
Subject: [PATCH] soc: qcom: spm: add SCM probe dependency
Check for SCM availability before attempting to use SPM. SPM probe will
fail otherwise.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: John Crispin <john@phrozen.org>
Signed-off-by: Andy Gross <andy.gross@linaro.org>
---
drivers/soc/qcom/spm.c | 3 +++
1 file changed, 3 insertions(+)
--- a/drivers/soc/qcom/spm.c
+++ b/drivers/soc/qcom/spm.c
@@ -219,6 +219,9 @@ static int __init qcom_cpuidle_init(stru
cpumask_t mask;
bool use_scm_power_down = false;
+ if (!qcom_scm_is_available())
+ return -EPROBE_DEFER;
+
for (i = 0; ; i++) {
state_node = of_parse_phandle(cpu_node, "cpu-idle-states", i);
if (!state_node)

View File

@ -0,0 +1,97 @@
From 233c77d4f1d12e4337fba1146d5197f4c0f9107d Mon Sep 17 00:00:00 2001
From: Matthew McClintock <mmcclint@codeaurora.org>
Date: Wed, 25 Jul 2018 10:37:45 +0200
Subject: [PATCH] ARM: dts: qcom: ipq4019: use v2 of the kpss bringup mechanism
v1 was the incorrect choice here and sometimes the board
would not come up properly.
Signed-off-by: Matthew McClintock <mmcclint@codeaurora.org>
Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
Signed-off-by: John Crispin <john@phrozen.org>
Signed-off-by: Andy Gross <andy.gross@linaro.org>
---
arch/arm/boot/dts/qcom-ipq4019.dtsi | 25 +++++++++++++++++--------
1 file changed, 17 insertions(+), 8 deletions(-)
--- a/arch/arm/boot/dts/qcom-ipq4019.dtsi
+++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi
@@ -52,7 +52,8 @@
cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-a7";
- enable-method = "qcom,kpss-acc-v1";
+ enable-method = "qcom,kpss-acc-v2";
+ next-level-cache = <&L2>;
qcom,acc = <&acc0>;
qcom,saw = <&saw0>;
reg = <0x0>;
@@ -71,7 +72,8 @@
cpu@1 {
device_type = "cpu";
compatible = "arm,cortex-a7";
- enable-method = "qcom,kpss-acc-v1";
+ enable-method = "qcom,kpss-acc-v2";
+ next-level-cache = <&L2>;
qcom,acc = <&acc1>;
qcom,saw = <&saw1>;
reg = <0x1>;
@@ -90,7 +92,8 @@
cpu@2 {
device_type = "cpu";
compatible = "arm,cortex-a7";
- enable-method = "qcom,kpss-acc-v1";
+ enable-method = "qcom,kpss-acc-v2";
+ next-level-cache = <&L2>;
qcom,acc = <&acc2>;
qcom,saw = <&saw2>;
reg = <0x2>;
@@ -109,7 +112,8 @@
cpu@3 {
device_type = "cpu";
compatible = "arm,cortex-a7";
- enable-method = "qcom,kpss-acc-v1";
+ enable-method = "qcom,kpss-acc-v2";
+ next-level-cache = <&L2>;
qcom,acc = <&acc3>;
qcom,saw = <&saw3>;
reg = <0x3>;
@@ -124,6 +128,11 @@
>;
clock-latency = <256000>;
};
+
+ L2: l2-cache {
+ compatible = "cache";
+ cache-level = <2>;
+ };
};
pmu {
@@ -292,22 +301,22 @@
};
acc0: clock-controller@b088000 {
- compatible = "qcom,kpss-acc-v1";
+ compatible = "qcom,kpss-acc-v2";
reg = <0x0b088000 0x1000>, <0xb008000 0x1000>;
};
acc1: clock-controller@b098000 {
- compatible = "qcom,kpss-acc-v1";
+ compatible = "qcom,kpss-acc-v2";
reg = <0x0b098000 0x1000>, <0xb008000 0x1000>;
};
acc2: clock-controller@b0a8000 {
- compatible = "qcom,kpss-acc-v1";
+ compatible = "qcom,kpss-acc-v2";
reg = <0x0b0a8000 0x1000>, <0xb008000 0x1000>;
};
acc3: clock-controller@b0b8000 {
- compatible = "qcom,kpss-acc-v1";
+ compatible = "qcom,kpss-acc-v2";
reg = <0x0b0b8000 0x1000>, <0xb008000 0x1000>;
};

View File

@ -0,0 +1,38 @@
From 8a4540321e8bcf7a5b485c332a2e78f3501c78ed Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Thu, 29 Nov 2018 22:29:36 +0100
Subject: [PATCH] ipq40xx: Fix booting secondary cores
Add the second part of old 071-qcom-ipq4019-use-v2-of-the-kpss-bringup-mechanism.patch
We dont modify the patch itself as its upstream and this change is not.
Originally added by Mantas Pucka Mantas Pucka <mantas@8devices.com>
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
arch/arm/boot/dts/qcom-ipq4019.dtsi | 7 +++++++
1 file changed, 7 insertions(+)
--- a/arch/arm/boot/dts/qcom-ipq4019.dtsi
+++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi
@@ -132,6 +132,7 @@
L2: l2-cache {
compatible = "cache";
cache-level = <2>;
+ qcom,saw = <&saw_l2>;
};
};
@@ -344,6 +345,12 @@
regulator;
};
+ saw_l2: regulator@b012000 {
+ compatible = "qcom,saw2";
+ reg = <0xb012000 0x1000>;
+ regulator;
+ };
+
blsp1_uart1: serial@78af000 {
compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
reg = <0x78af000 0x200>;

View File

@ -0,0 +1,114 @@
From bcb9ab4c2917e92114d2f4c2b1da97cdf15b471b Mon Sep 17 00:00:00 2001
From: Matthew McClintock <mmcclint@codeaurora.org>
Date: Wed, 25 Jul 2018 10:37:46 +0200
Subject: [PATCH] ARM: dts: qcom: ipq4019: add cpu operating points for cpufreq
support
This adds some operating points for cpu frequeny scaling
Signed-off-by: Matthew McClintock <mmcclint@codeaurora.org>
Signed-off-by: John Crispin <john@phrozen.org>
Signed-off-by: Andy Gross <andy.gross@linaro.org>
---
arch/arm/boot/dts/qcom-ipq4019.dtsi | 58 ++++++++++++++---------------
1 file changed, 30 insertions(+), 28 deletions(-)
--- a/arch/arm/boot/dts/qcom-ipq4019.dtsi
+++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi
@@ -59,14 +59,8 @@
reg = <0x0>;
clocks = <&gcc GCC_APPS_CLK_SRC>;
clock-frequency = <0>;
- operating-points = <
- /* kHz uV (fixed) */
- 48000 1100000
- 200000 1100000
- 500000 1100000
- 716000 1100000
- >;
clock-latency = <256000>;
+ operating-points-v2 = <&cpu0_opp_table>;
};
cpu@1 {
@@ -79,14 +73,8 @@
reg = <0x1>;
clocks = <&gcc GCC_APPS_CLK_SRC>;
clock-frequency = <0>;
- operating-points = <
- /* kHz uV (fixed) */
- 48000 1100000
- 200000 1100000
- 500000 1100000
- 666000 1100000
- >;
clock-latency = <256000>;
+ operating-points-v2 = <&cpu0_opp_table>;
};
cpu@2 {
@@ -99,14 +87,8 @@
reg = <0x2>;
clocks = <&gcc GCC_APPS_CLK_SRC>;
clock-frequency = <0>;
- operating-points = <
- /* kHz uV (fixed) */
- 48000 1100000
- 200000 1100000
- 500000 1100000
- 666000 1100000
- >;
clock-latency = <256000>;
+ operating-points-v2 = <&cpu0_opp_table>;
};
cpu@3 {
@@ -119,14 +101,8 @@
reg = <0x3>;
clocks = <&gcc GCC_APPS_CLK_SRC>;
clock-frequency = <0>;
- operating-points = <
- /* kHz uV (fixed) */
- 48000 1100000
- 200000 1100000
- 500000 1100000
- 666000 1100000
- >;
clock-latency = <256000>;
+ operating-points-v2 = <&cpu0_opp_table>;
};
L2: l2-cache {
@@ -136,6 +112,32 @@
};
};
+ cpu0_opp_table: opp_table0 {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ opp-48000000 {
+ opp-hz = /bits/ 64 <48000000>;
+ opp-microvolt = <1100000>;
+ clock-latency-ns = <256000>;
+ };
+ opp-200000000 {
+ opp-hz = /bits/ 64 <200000000>;
+ opp-microvolt = <1100000>;
+ clock-latency-ns = <256000>;
+ };
+ opp-500000000 {
+ opp-hz = /bits/ 64 <500000000>;
+ opp-microvolt = <1100000>;
+ clock-latency-ns = <256000>;
+ };
+ opp-716000000 {
+ opp-hz = /bits/ 64 <716000000>;
+ opp-microvolt = <1100000>;
+ clock-latency-ns = <256000>;
+ };
+ };
+
pmu {
compatible = "arm,cortex-a7-pmu";
interrupts = <GIC_PPI 7 (GIC_CPU_MASK_SIMPLE(4) |

View File

@ -0,0 +1,70 @@
From patchwork Mon May 21 20:57:38 2018
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: [v5,3/4] ARM: dts: qcom: add gpio-ranges property
X-Patchwork-Submitter: Christian Lamparter <chunkeey@gmail.com>
X-Patchwork-Id: 917856
Message-Id: <0ae3376606a89bcdf3fe753a5c967f7103699e09.1526935804.git.chunkeey@gmail.com>
To: linux-gpio@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-arm-msm@vger.kernel.org, devicetree@vger.kernel.org
Cc: Bjorn Andersson <bjorn.andersson@linaro.org>,
Linus Walleij <linus.walleij@linaro.org>,
Stephen Boyd <sboyd@kernel.org>, David Brown <david.brown@linaro.org>,
Rob Herring <robh+dt@kernel.org>, Mark Rutland <mark.rutland@arm.com>,
Andy Gross <andy.gross@linaro.org>,
Sven Eckelmann <sven.eckelmann@openmesh.com>
Date: Mon, 21 May 2018 22:57:38 +0200
From: Christian Lamparter <chunkeey@gmail.com>
List-Id: <linux-gpio.vger.kernel.org>
This patch adds the gpio-ranges property to almost all of
the Qualcomm ARM platforms that utilize the pinctrl-msm
framework.
The gpio-ranges property is part of the gpiolib subsystem.
As a result, the binding text is available in section
"2.1 gpio- and pin-controller interaction" of
Documentation/devicetree/bindings/gpio/gpio.txt
For more information please see the patch titled:
"pinctrl: msm: fix gpio-hog related boot issues" from
this series.
Reported-by: Sven Eckelmann <sven.eckelmann@openmesh.com>
Tested-by: Sven Eckelmann <sven.eckelmann@openmesh.com> [ipq4019]
Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
---
To help with git bisect, the DT update patch has been intentionally
placed after the "pinctrl: msm: fix gpio-hog related boot issues".
Otherwise - if the order was reveresed - and bisect decides to split
between these two patches, the gpiochip_add_pin_ranges() function
will be executed twice with the same parameters for the same pinctrl.
---
arch/arm/boot/dts/qcom-apq8064.dtsi | 1 +
arch/arm/boot/dts/qcom-apq8084.dtsi | 1 +
arch/arm/boot/dts/qcom-ipq4019.dtsi | 1 +
arch/arm/boot/dts/qcom-ipq8064.dtsi | 1 +
arch/arm/boot/dts/qcom-mdm9615.dtsi | 1 +
arch/arm/boot/dts/qcom-msm8660.dtsi | 1 +
arch/arm/boot/dts/qcom-msm8960.dtsi | 1 +
arch/arm/boot/dts/qcom-msm8974.dtsi | 1 +
arch/arm64/boot/dts/qcom/ipq8074.dtsi | 3 ++-
arch/arm64/boot/dts/qcom/msm8916.dtsi | 1 +
arch/arm64/boot/dts/qcom/msm8992.dtsi | 1 +
arch/arm64/boot/dts/qcom/msm8994.dtsi | 1 +
arch/arm64/boot/dts/qcom/msm8996.dtsi | 1 +
13 files changed, 14 insertions(+), 1 deletion(-)
--- a/arch/arm/boot/dts/qcom-ipq4019.dtsi
+++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi
@@ -206,6 +206,7 @@
compatible = "qcom,ipq4019-pinctrl";
reg = <0x01000000 0x300000>;
gpio-controller;
+ gpio-ranges = <&tlmm 0 0 100>;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;

View File

@ -0,0 +1,29 @@
From 09f145f417a5d64d6b8d4476699dfb0eccc6c784 Mon Sep 17 00:00:00 2001
From: Abhishek Sahu <absahu@codeaurora.org>
Date: Tue, 7 May 2019 10:14:05 +0300
Subject: [PATCH] ipq40xx: fix high resolution timer
Cherry-picked from CAF QSDK repo.
Original commit message:
The kernel is failing in switching the timer for high resolution
mode and clock source operates in 10ms resolution. The always-on
property needs to be given for timer device tree node to make
clock source working in 1ns resolution.
Change-Id: I7c00b3c74d97c2a30ac9f05e18b511a0550fd459
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
Signed-off-by: Pavel Kubelun <be.dissent@gmail.com>
---
arch/arm/boot/dts/qcom-ipq4019.dtsi | 1 +
1 file changed, 1 insertion(+)
--- a/arch/arm/boot/dts/qcom-ipq4019.dtsi
+++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi
@@ -171,6 +171,7 @@
<1 4 0xf08>,
<1 1 0xf08>;
clock-frequency = <48000000>;
+ always-on;
};
soc {

View File

@ -0,0 +1,11 @@
--- a/drivers/crypto/qce/ablkcipher.c 2019-10-21 17:18:47.311684603 -0300
+++ b/drivers/crypto/qce/ablkcipher.c 2019-10-21 17:20:32.080765945 -0300
@@ -292,7 +292,7 @@
.name = "ctr(aes)",
.drv_name = "ctr-aes-qce",
.blocksize = AES_BLOCK_SIZE,
- .ivsize = AES_BLOCK_SIZE,
+ .ivsize = 1,
.min_keysize = AES_MIN_KEY_SIZE,
.max_keysize = AES_MAX_KEY_SIZE,
},

View File

@ -0,0 +1,68 @@
diff --git a/drivers/crypto/qce/ablkcipher.c b/drivers/crypto/qce/ablkcipher.c
index 7a98bf5cc967..b935ce0acc1c 100644
--- a/drivers/crypto/qce/ablkcipher.c
+++ b/drivers/crypto/qce/ablkcipher.c
@@ -14,6 +14,20 @@
static LIST_HEAD(ablkcipher_algs);
+static void qce_update_ctr_iv(u8 *iv, unsigned int ivsize, u32 add)
+{
+ __be32 *a = (__be32 *)(iv + ivsize);
+ u32 b;
+
+ for (; ivsize >= 4; ivsize -= 4) {
+ b = be32_to_cpu(*--a) + add;
+ *a = cpu_to_be32(b);
+ if (b >= add)
+ return;
+ add = 1;
+ }
+}
+
static void qce_ablkcipher_done(void *data)
{
struct crypto_async_request *async_req = data;
@@ -39,6 +53,18 @@ static void qce_ablkcipher_done(void *data)
dma_unmap_sg(qce->dev, rctx->src_sg, rctx->src_nents, dir_src);
dma_unmap_sg(qce->dev, rctx->dst_sg, rctx->dst_nents, dir_dst);
+ if (IS_CBC(rctx->flags)) {
+ if (IS_ENCRYPT(rctx->flags))
+ sg_pcopy_to_buffer(rctx->dst_sg, rctx->dst_nents,
+ rctx->iv, rctx->ivsize,
+ rctx->cryptlen - rctx->ivsize);
+ else
+ memcpy(rctx->iv, rctx->saved_iv, rctx->ivsize);
+ } else if (IS_CTR(rctx->flags) && IS_AES(rctx->flags)) {
+ qce_update_ctr_iv(rctx->iv, rctx->ivsize,
+ DIV_ROUND_UP(rctx->cryptlen, AES_BLOCK_SIZE));
+ }
+
sg_free_table(&rctx->dst_tbl);
error = qce_check_status(qce, &status);
@@ -131,6 +157,11 @@ qce_ablkcipher_async_req_handle(struct crypto_async_request *async_req)
qce_dma_issue_pending(&qce->dma);
+ if (IS_CBC(rctx->flags) && IS_DECRYPT(rctx->flags))
+ sg_pcopy_to_buffer(rctx->src_sg, rctx->src_nents,
+ rctx->saved_iv, rctx->ivsize,
+ rctx->cryptlen - rctx->ivsize);
+
ret = qce_start(async_req, tmpl->crypto_alg_type, req->nbytes, 0);
if (ret)
goto error_terminate;
diff --git a/drivers/crypto/qce/cipher.h b/drivers/crypto/qce/cipher.h
index 5cab8f0706a8..a919022e28df 100644
--- a/drivers/crypto/qce/cipher.h
+++ b/drivers/crypto/qce/cipher.h
@@ -43,6 +43,7 @@ struct qce_cipher_reqctx {
struct sg_table src_tbl;
struct scatterlist *src_sg;
unsigned int cryptlen;
+ u8 saved_iv[QCE_MAX_IV_SIZE];
};
static inline struct qce_alg_template *to_cipher_tmpl(struct crypto_tfm *tfm)

View File

@ -0,0 +1,91 @@
From 2f23be905522cc67505daaf4d94c0292dbddd315 Mon Sep 17 00:00:00 2001
From: Eneas U de Queiroz <cotequeiroz@gmail.com>
Date: Mon, 28 Oct 2019 15:17:19 -0300
Subject: [PATCH] crypto: qce - allow building only hashes/ciphers
Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index 1fb622f2a87d..0dc4bbcfc092 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -580,5 +580,13 @@ config CRYPTO_DEV_QCE
tristate "Qualcomm crypto engine accelerator"
depends on (ARCH_QCOM || COMPILE_TEST) && HAS_DMA && HAS_IOMEM
+ help
+ This driver supports Qualcomm crypto engine accelerator
+ hardware. To compile this driver as a module, choose M here. The
+ module will be called qcrypto.
+
+config CRYPTO_DEV_QCE_BLKCIPHER
+ bool
+ depends on CRYPTO_DEV_QCE
select CRYPTO_AES
select CRYPTO_LIB_DES
select CRYPTO_ECB
@@ -580,10 +588,29 @@ config CRYPTO_DEV_QCE
select CRYPTO_XTS
select CRYPTO_CTR
select CRYPTO_BLKCIPHER
- help
- This driver supports Qualcomm crypto engine accelerator
- hardware. To compile this driver as a module, choose M here. The
- module will be called qcrypto.
+
+config CRYPTO_DEV_QCE_SHA
+ bool
+ depends on CRYPTO_DEV_QCE
+
+choice
+ prompt "Algorithms enabled for QCE acceleration"
+ default CRYPTO_DEV_QCE_ENABLE_ALL
+ depends on CRYPTO_DEV_QCE
+
+ config CRYPTO_DEV_QCE_ENABLE_ALL
+ bool "All supported algorithms"
+ select CRYPTO_DEV_QCE_BLKCIPHER
+ select CRYPTO_DEV_QCE_SHA
+
+ config CRYPTO_DEV_QCE_ENABLE_BLKCIPHER
+ bool "Block ciphers only"
+ select CRYPTO_DEV_QCE_BLKCIPHER
+
+ config CRYPTO_DEV_QCE_ENABLE_SHA
+ bool "Hash/HMAC only"
+ select CRYPTO_DEV_QCE_SHA
+endchoice
config CRYPTO_DEV_QCOM_RNG
tristate "Qualcomm Random Number Generator Driver"
diff --git a/drivers/crypto/qce/Makefile b/drivers/crypto/qce/Makefile
index 19a7f899acff..f6a411c255b8 100644
--- a/drivers/crypto/qce/Makefile
+++ b/drivers/crypto/qce/Makefile
@@ -2,6 +2,7 @@
obj-$(CONFIG_CRYPTO_DEV_QCE) += qcrypto.o
qcrypto-objs := core.o \
common.o \
- dma.o \
- sha.o \
- ablkcipher.o
+ dma.o
+
+qcrypto-$(CONFIG_CRYPTO_DEV_QCE_SHA) += sha.o
+qcrypto-$(CONFIG_CRYPTO_DEV_QCE_BLKCIPHER) += ablkcipher.o
diff --git a/drivers/crypto/qce/core.c b/drivers/crypto/qce/core.c
index 08d4ce3bfddf..3428746f1869 100644
--- a/drivers/crypto/qce/core.c
+++ b/drivers/crypto/qce/core.c
@@ -22,8 +22,12 @@
#define QCE_QUEUE_LENGTH 1
static const struct qce_algo_ops *qce_ops[] = {
+#ifdef CONFIG_CRYPTO_DEV_QCE_BLKCIPHER
&ablkcipher_ops,
+#endif
+#ifdef CONFIG_CRYPTO_DEV_QCE_SHA
&ahash_ops,
+#endif
};
static void qce_unregister_algs(struct qce_device *qce)

View File

@ -0,0 +1,11 @@
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -1681,7 +1681,7 @@ MODULE_DEVICE_TABLE(of, sdhci_msm_dt_mat
static const struct sdhci_ops sdhci_msm_ops = {
.reset = sdhci_reset,
- .set_clock = sdhci_msm_set_clock,
+ .set_clock = sdhci_set_clock,
.get_min_clock = sdhci_msm_get_min_clock,
.get_max_clock = sdhci_msm_get_max_clock,
.set_bus_width = sdhci_set_bus_width,

View File

@ -0,0 +1,225 @@
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -524,6 +524,13 @@ config XILINX_GMII2RGMII
the Reduced Gigabit Media Independent Interface(RGMII) between
Ethernet physical media devices and the Gigabit Ethernet controller.
+config MDIO_IPQ40XX
+ tristate "Qualcomm Atheros ipq40xx MDIO interface"
+ depends on HAS_IOMEM && OF
+ ---help---
+ This driver supports the MDIO interface found in Qualcomm
+ Atheros ipq40xx Soc chip.
+
endif # PHYLIB
config MICREL_KS8995MA
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_MDIO_CAVIUM) += mdio-cavium
obj-$(CONFIG_MDIO_GPIO) += mdio-gpio.o
obj-$(CONFIG_MDIO_HISI_FEMAC) += mdio-hisi-femac.o
obj-$(CONFIG_MDIO_I2C) += mdio-i2c.o
+obj-$(CONFIG_MDIO_IPQ40XX) += mdio-ipq40xx.o
obj-$(CONFIG_MDIO_MOXART) += mdio-moxart.o
obj-$(CONFIG_MDIO_MSCC_MIIM) += mdio-mscc-miim.o
obj-$(CONFIG_MDIO_OCTEON) += mdio-octeon.o
--- /dev/null
+++ b/drivers/net/phy/mdio-ipq40xx.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/of_mdio.h>
+#include <linux/phy.h>
+#include <linux/platform_device.h>
+
+#define MDIO_CTRL_0_REG 0x40
+#define MDIO_CTRL_1_REG 0x44
+#define MDIO_CTRL_2_REG 0x48
+#define MDIO_CTRL_3_REG 0x4c
+#define MDIO_CTRL_4_REG 0x50
+#define MDIO_CTRL_4_ACCESS_BUSY BIT(16)
+#define MDIO_CTRL_4_ACCESS_START BIT(8)
+#define MDIO_CTRL_4_ACCESS_CODE_READ 0
+#define MDIO_CTRL_4_ACCESS_CODE_WRITE 1
+#define CTRL_0_REG_DEFAULT_VALUE 0x150FF
+
+#define IPQ40XX_MDIO_RETRY 1000
+#define IPQ40XX_MDIO_DELAY 10
+
+struct ipq40xx_mdio_data {
+ struct mii_bus *mii_bus;
+ void __iomem *membase;
+ struct device *dev;
+};
+
+static int ipq40xx_mdio_wait_busy(struct ipq40xx_mdio_data *am)
+{
+ int i;
+
+ for (i = 0; i < IPQ40XX_MDIO_RETRY; i++) {
+ unsigned int busy;
+
+ busy = readl(am->membase + MDIO_CTRL_4_REG) &
+ MDIO_CTRL_4_ACCESS_BUSY;
+ if (!busy)
+ return 0;
+
+ /* BUSY might take to be cleard by 15~20 times of loop */
+ udelay(IPQ40XX_MDIO_DELAY);
+ }
+
+ dev_err(am->dev, "%s: MDIO operation timed out\n", am->mii_bus->name);
+
+ return -ETIMEDOUT;
+}
+
+static int ipq40xx_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
+{
+ struct ipq40xx_mdio_data *am = bus->priv;
+ int value = 0;
+ unsigned int cmd = 0;
+
+ lockdep_assert_held(&bus->mdio_lock);
+
+ if (ipq40xx_mdio_wait_busy(am))
+ return -ETIMEDOUT;
+
+ /* issue the phy address and reg */
+ writel((mii_id << 8) | regnum, am->membase + MDIO_CTRL_1_REG);
+
+ cmd = MDIO_CTRL_4_ACCESS_START|MDIO_CTRL_4_ACCESS_CODE_READ;
+
+ /* issue read command */
+ writel(cmd, am->membase + MDIO_CTRL_4_REG);
+
+ /* Wait read complete */
+ if (ipq40xx_mdio_wait_busy(am))
+ return -ETIMEDOUT;
+
+ /* Read data */
+ value = readl(am->membase + MDIO_CTRL_3_REG);
+
+ return value;
+}
+
+static int ipq40xx_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
+ u16 value)
+{
+ struct ipq40xx_mdio_data *am = bus->priv;
+ unsigned int cmd = 0;
+
+ lockdep_assert_held(&bus->mdio_lock);
+
+ if (ipq40xx_mdio_wait_busy(am))
+ return -ETIMEDOUT;
+
+ /* issue the phy address and reg */
+ writel((mii_id << 8) | regnum, am->membase + MDIO_CTRL_1_REG);
+
+ /* issue write data */
+ writel(value, am->membase + MDIO_CTRL_2_REG);
+
+ cmd = MDIO_CTRL_4_ACCESS_START|MDIO_CTRL_4_ACCESS_CODE_WRITE;
+ /* issue write command */
+ writel(cmd, am->membase + MDIO_CTRL_4_REG);
+
+ /* Wait write complete */
+ if (ipq40xx_mdio_wait_busy(am))
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+static int ipq40xx_mdio_probe(struct platform_device *pdev)
+{
+ struct ipq40xx_mdio_data *am;
+ struct resource *res;
+ int i;
+
+ am = devm_kzalloc(&pdev->dev, sizeof(*am), GFP_KERNEL);
+ if (!am)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "no iomem resource found\n");
+ return -ENXIO;
+ }
+
+ am->membase = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(am->membase)) {
+ dev_err(&pdev->dev, "unable to ioremap registers\n");
+ return PTR_ERR(am->membase);
+ }
+
+ am->mii_bus = devm_mdiobus_alloc(&pdev->dev);
+ if (!am->mii_bus)
+ return -ENOMEM;
+
+ writel(CTRL_0_REG_DEFAULT_VALUE, am->membase + MDIO_CTRL_0_REG);
+
+ am->mii_bus->name = "ipq40xx_mdio";
+ am->mii_bus->read = ipq40xx_mdio_read;
+ am->mii_bus->write = ipq40xx_mdio_write;
+ am->mii_bus->priv = am;
+ am->mii_bus->parent = &pdev->dev;
+ snprintf(am->mii_bus->id, MII_BUS_ID_SIZE, "%s", dev_name(&pdev->dev));
+
+ am->dev = &pdev->dev;
+ platform_set_drvdata(pdev, am);
+
+ return of_mdiobus_register(am->mii_bus, pdev->dev.of_node);
+}
+
+static int ipq40xx_mdio_remove(struct platform_device *pdev)
+{
+ struct ipq40xx_mdio_data *am = platform_get_drvdata(pdev);
+
+ mdiobus_unregister(am->mii_bus);
+
+ return 0;
+}
+
+static const struct of_device_id ipq40xx_mdio_dt_ids[] = {
+ { .compatible = "qcom,ipq4019-mdio" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, ipq40xx_mdio_dt_ids);
+
+static struct platform_driver ipq40xx_mdio_driver = {
+ .probe = ipq40xx_mdio_probe,
+ .remove = ipq40xx_mdio_remove,
+ .driver = {
+ .name = "ipq40xx-mdio",
+ .of_match_table = ipq40xx_mdio_dt_ids,
+ },
+};
+
+module_platform_driver(ipq40xx_mdio_driver);
+
+#define DRV_VERSION "1.0"
+
+MODULE_DESCRIPTION("IPQ40XX MDIO interface driver");
+MODULE_AUTHOR("Qualcomm Atheros");
+MODULE_VERSION(DRV_VERSION);
+MODULE_LICENSE("Dual BSD/GPL");

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,144 @@
From 0bcfbe3c613d6ed8044404bc1cc3c29ff961d89c Mon Sep 17 00:00:00 2001
From: Chen Minqiang <ptpt52@gmail.com>
Date: Thu, 15 Mar 2018 04:59:57 +0800
Subject: [PATCH 1/2] essedma: fixup ethernet driver rx bug
- modify the error rx ring full conditions
- in rare cases, out of memory allocation failure causes the receive queues stop
we use the timer to re-alloc rx rings under these circumstances
Signed-off-by: Chen Minqiang <ptpt52@gmail.com>
---
drivers/net/ethernet/qualcomm/essedma/edma.c | 51 ++++++++++++++++++++++--
drivers/net/ethernet/qualcomm/essedma/edma.h | 3 ++
drivers/net/ethernet/qualcomm/essedma/edma_axi.c | 8 ++++
3 files changed, 58 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/qualcomm/essedma/edma.c b/drivers/net/ethernet/qualcomm/essedma/edma.c
index fecc0ba..3f1da93 100644
--- a/drivers/net/ethernet/qualcomm/essedma/edma.c
+++ b/drivers/net/ethernet/qualcomm/essedma/edma.c
@@ -530,6 +530,47 @@ static int edma_rx_complete_paged(struct sk_buff *skb, u16 num_rfds, u16 length,
return sw_next_to_clean;
}
+static int edma_rfd_desc_unused(struct edma_rfd_desc_ring *erdr)
+{
+ if (erdr->sw_next_to_clean > erdr->sw_next_to_fill)
+ return erdr->sw_next_to_clean - erdr->sw_next_to_fill - 1;
+ return erdr->count + erdr->sw_next_to_clean - erdr->sw_next_to_fill - 1;
+}
+
+void edma_rx_realloc(unsigned long data)
+{
+ struct edma_per_cpu_queues_info *edma_percpu_info = (struct edma_per_cpu_queues_info *)data;
+ struct edma_common_info *edma_cinfo = edma_percpu_info->edma_cinfo;
+ s32 status = edma_percpu_info->rx_realloc_status;
+
+ while (status) {
+ int queue_id;
+ int ret_count;
+ struct edma_rfd_desc_ring *erdr;
+
+ queue_id = ffs(status) - 1;
+ erdr = edma_cinfo->rfd_ring[queue_id];
+ ret_count = edma_alloc_rx_buf(edma_cinfo, erdr, edma_rfd_desc_unused(erdr), queue_id);
+ if (ret_count == 0) {
+ edma_percpu_info->rx_realloc_status &= ~(1 << queue_id);
+ }
+ status &= ~(1 << queue_id);
+ }
+
+ if (edma_percpu_info->rx_realloc_status) {
+ mod_timer(&edma_percpu_info->rx_realloc_timer, jiffies + HZ);
+ }
+}
+
+static inline void edma_realloc_timer_start(struct napi_struct *napi, int queue_id)
+{
+ struct edma_per_cpu_queues_info *edma_percpu_info = container_of(napi,
+ struct edma_per_cpu_queues_info, napi);
+
+ edma_percpu_info->rx_realloc_status |= (1 << queue_id);
+ mod_timer(&edma_percpu_info->rx_realloc_timer, jiffies + 5 * HZ); /* restart alloc in 5 secs */
+}
+
/*
* edma_rx_complete()
* Main api called from the poll function to process rx packets.
@@ -754,10 +795,12 @@ static void edma_rx_complete(struct edma_common_info *edma_cinfo,
erdr->sw_next_to_clean = sw_next_to_clean;
/* Refill here in case refill threshold wasn't reached */
- if (likely(cleaned_count)) {
- ret_count = edma_alloc_rx_buf(edma_cinfo, erdr, cleaned_count, queue_id);
- if (ret_count)
+ if (edma_rfd_desc_unused(erdr)) {
+ ret_count = edma_alloc_rx_buf(edma_cinfo, erdr, edma_rfd_desc_unused(erdr), queue_id);
+ if (ret_count) {
dev_dbg(&pdev->dev, "Not all buffers was reallocated");
+ edma_realloc_timer_start(napi, queue_id);
+ }
edma_write_reg(EDMA_REG_RX_SW_CONS_IDX_Q(queue_id),
erdr->sw_next_to_clean);
}
@@ -1801,7 +1844,7 @@ int edma_configure(struct edma_common_info *edma_cinfo)
/* Allocate the RX buffer */
for (i = 0, j = 0; i < edma_cinfo->num_rx_queues; i++) {
struct edma_rfd_desc_ring *ring = edma_cinfo->rfd_ring[j];
- ret_count = edma_alloc_rx_buf(edma_cinfo, ring, ring->count, j);
+ ret_count = edma_alloc_rx_buf(edma_cinfo, ring, edma_rfd_desc_unused(ring), j);
if (ret_count) {
dev_dbg(&edma_cinfo->pdev->dev, "not all rx buffers allocated\n");
}
diff --git a/drivers/net/ethernet/qualcomm/essedma/edma.h b/drivers/net/ethernet/qualcomm/essedma/edma.h
index 5d6dc73..29c8379 100644
--- a/drivers/net/ethernet/qualcomm/essedma/edma.h
+++ b/drivers/net/ethernet/qualcomm/essedma/edma.h
@@ -304,6 +304,8 @@ struct edma_per_cpu_queues_info {
u32 tx_start; /* tx queue start */
u32 rx_start; /* rx queue start */
struct edma_common_info *edma_cinfo; /* edma common info */
+ u32 rx_realloc_status;
+ struct timer_list rx_realloc_timer;
};
/* edma specific common info */
@@ -448,6 +450,7 @@ void edma_change_tx_coalesce(int usecs);
void edma_change_rx_coalesce(int usecs);
void edma_get_tx_rx_coalesce(u32 *reg_val);
void edma_clear_irq_status(void);
+void edma_rx_realloc(unsigned long data);
void ess_set_port_status_speed(struct edma_common_info *edma_cinfo,
struct phy_device *phydev, uint8_t port_id);
#endif /* _EDMA_H_ */
diff --git a/drivers/net/ethernet/qualcomm/essedma/edma_axi.c b/drivers/net/ethernet/qualcomm/essedma/edma_axi.c
index 81fc1e1..d9f8b52 100644
--- a/drivers/net/ethernet/qualcomm/essedma/edma_axi.c
+++ b/drivers/net/ethernet/qualcomm/essedma/edma_axi.c
@@ -1131,6 +1131,11 @@ static int edma_axi_probe(struct platform_device *pdev)
edma_cinfo->edma_percpu_info[i].rx_status = 0;
edma_cinfo->edma_percpu_info[i].edma_cinfo = edma_cinfo;
+ edma_cinfo->edma_percpu_info[i].rx_realloc_status = 0;
+ init_timer(&edma_cinfo->edma_percpu_info[i].rx_realloc_timer);
+ edma_cinfo->edma_percpu_info[i].rx_realloc_timer.function = edma_rx_realloc;
+ edma_cinfo->edma_percpu_info[i].rx_realloc_timer.data = (unsigned long)&edma_cinfo->edma_percpu_info[i];
+
/* Request irq per core */
for (j = edma_cinfo->edma_percpu_info[i].tx_start;
j < tx_start[i] + 4; j++) {
@@ -1259,7 +1264,10 @@ err_configure:
err_rmap_add_fail:
edma_free_irqs(adapter[0]);
for (i = 0; i < CONFIG_NR_CPUS; i++)
+ {
napi_disable(&edma_cinfo->edma_percpu_info[i].napi);
+ del_timer_sync(&edma_cinfo->edma_percpu_info[i].rx_realloc_timer);
+ }
err_reset:
err_unregister_sysctl_tbl:
err_rmap_alloc_fail:
--
2.7.4

View File

@ -0,0 +1,223 @@
From 7be0cb35513b07bf74d93d052d57b12e2c654b43 Mon Sep 17 00:00:00 2001
From: Chen Minqiang <ptpt52@gmail.com>
Date: Thu, 15 Mar 2018 05:04:37 +0800
Subject: [PATCH 2/2] essedma: refine txq to be adaptive of cpus and netdev
- use 4 queue for each cpu if only 1 netdev
- use all 16 txqueue if only 1 netdev
Signed-off-by: Chen Minqiang <ptpt52@gmail.com>
---
drivers/net/ethernet/qualcomm/essedma/edma.c | 22 +++++--------
drivers/net/ethernet/qualcomm/essedma/edma.h | 5 +--
drivers/net/ethernet/qualcomm/essedma/edma_axi.c | 40 ++++++++++++++----------
3 files changed, 35 insertions(+), 32 deletions(-)
diff --git a/drivers/net/ethernet/qualcomm/essedma/edma.c b/drivers/net/ethernet/qualcomm/essedma/edma.c
index 3f1da93..05f9ce9 100644
--- a/drivers/net/ethernet/qualcomm/essedma/edma.c
+++ b/drivers/net/ethernet/qualcomm/essedma/edma.c
@@ -22,14 +22,6 @@ extern struct net_device *edma_netdev[EDMA_MAX_PORTID_SUPPORTED];
bool edma_stp_rstp;
u16 edma_ath_eth_type;
-/* edma_skb_priority_offset()
- * get edma skb priority
- */
-static unsigned int edma_skb_priority_offset(struct sk_buff *skb)
-{
- return (skb->priority >> 2) & 1;
-}
-
/* edma_alloc_tx_ring()
* Allocate Tx descriptors ring
*/
@@ -1042,13 +1034,14 @@ static inline u16 edma_tpd_available(struct edma_common_info *edma_cinfo,
/* edma_tx_queue_get()
* Get the starting number of the queue
*/
-static inline int edma_tx_queue_get(struct edma_adapter *adapter,
+static inline int edma_tx_queue_get(struct edma_common_info *edma_cinfo, struct edma_adapter *adapter,
struct sk_buff *skb, int txq_id)
{
/* skb->priority is used as an index to skb priority table
* and based on packet priority, correspong queue is assigned.
+ * FIXME we just simple use jiffies for time base balance
*/
- return adapter->tx_start_offset[txq_id] + edma_skb_priority_offset(skb);
+ return adapter->tx_start_offset[txq_id] + (jiffies % edma_cinfo->num_txq_per_core_netdev);
}
/* edma_tx_update_hw_idx()
@@ -1417,8 +1410,9 @@ netdev_tx_t edma_xmit(struct sk_buff *skb,
}
/* this will be one of the 4 TX queues exposed to linux kernel */
- txq_id = skb_get_queue_mapping(skb);
- queue_id = edma_tx_queue_get(adapter, skb, txq_id);
+ /* XXX what if num_online_cpus() > EDMA_CPU_CORES_SUPPORTED */
+ txq_id = smp_processor_id() % EDMA_CPU_CORES_SUPPORTED;
+ queue_id = edma_tx_queue_get(edma_cinfo, adapter, skb, txq_id);
etdr = edma_cinfo->tpd_ring[queue_id];
nq = netdev_get_tx_queue(net_dev, txq_id);
@@ -1899,8 +1893,8 @@ void edma_free_irqs(struct edma_adapter *adapter)
int i, j;
int k = ((edma_cinfo->num_rx_queues == 4) ? 1 : 2);
- for (i = 0; i < CONFIG_NR_CPUS; i++) {
- for (j = edma_cinfo->edma_percpu_info[i].tx_start; j < (edma_cinfo->edma_percpu_info[i].tx_start + 4); j++)
+ for (i = 0; i < num_online_cpus() && i < EDMA_CPU_CORES_SUPPORTED; i++) {
+ for (j = edma_cinfo->edma_percpu_info[i].tx_start; j < (edma_cinfo->edma_percpu_info[i].tx_start + edma_cinfo->num_txq_per_core); j++)
free_irq(edma_cinfo->tx_irq[j], &edma_cinfo->edma_percpu_info[i]);
for (j = edma_cinfo->edma_percpu_info[i].rx_start; j < (edma_cinfo->edma_percpu_info[i].rx_start + k); j++)
diff --git a/drivers/net/ethernet/qualcomm/essedma/edma.h b/drivers/net/ethernet/qualcomm/essedma/edma.h
index 29c8379..2ba43e0 100644
--- a/drivers/net/ethernet/qualcomm/essedma/edma.h
+++ b/drivers/net/ethernet/qualcomm/essedma/edma.h
@@ -325,6 +325,7 @@ struct edma_common_info {
u32 from_cpu; /* from CPU TPD field */
u32 num_rxq_per_core; /* Rx queues per core */
u32 num_txq_per_core; /* Tx queues per core */
+ u32 num_txq_per_core_netdev; /* Tx queues per core per netdev */
u16 tx_ring_count; /* Tx ring count */
u16 rx_ring_count; /* Rx ring*/
u16 rx_head_buffer_len; /* rx buffer length */
@@ -332,7 +333,7 @@ struct edma_common_info {
u32 page_mode; /* Jumbo frame supported flag */
u32 fraglist_mode; /* fraglist supported flag */
struct edma_hw hw; /* edma hw specific structure */
- struct edma_per_cpu_queues_info edma_percpu_info[CONFIG_NR_CPUS]; /* per cpu information */
+ struct edma_per_cpu_queues_info edma_percpu_info[EDMA_CPU_CORES_SUPPORTED]; /* per cpu information */
spinlock_t stats_lock; /* protect edma stats area for updation */
bool is_single_phy;
@@ -401,7 +402,7 @@ struct edma_adapter {
u32 link_state; /* phy link state */
u32 phy_mdio_addr; /* PHY device address on MII interface */
u32 poll_required; /* check if link polling is required */
- u32 tx_start_offset[CONFIG_NR_CPUS]; /* tx queue start */
+ u32 tx_start_offset[EDMA_CPU_CORES_SUPPORTED]; /* tx queue start */
u32 default_vlan_tag; /* vlan tag */
u32 dp_bitmap;
uint8_t phy_id[MII_BUS_ID_SIZE + 3];
diff --git a/drivers/net/ethernet/qualcomm/essedma/edma_axi.c b/drivers/net/ethernet/qualcomm/essedma/edma_axi.c
index d9f8b52..5824680 100644
--- a/drivers/net/ethernet/qualcomm/essedma/edma_axi.c
+++ b/drivers/net/ethernet/qualcomm/essedma/edma_axi.c
@@ -721,11 +721,7 @@ static int edma_axi_probe(struct platform_device *pdev)
int i, j, k, err = 0;
int portid_bmp;
int idx = 0, idx_mac = 0;
-
- if (CONFIG_NR_CPUS != EDMA_CPU_CORES_SUPPORTED) {
- dev_err(&pdev->dev, "Invalid CPU Cores\n");
- return -EINVAL;
- }
+ int netdev_group = 2;
if ((num_rxq != 4) && (num_rxq != 8)) {
dev_err(&pdev->dev, "Invalid RX queue, edma probe failed\n");
@@ -749,7 +745,7 @@ static int edma_axi_probe(struct platform_device *pdev)
/* Initialize the netdev array before allocation
* to avoid double free
*/
- for (i = 0 ; i < edma_cinfo->num_gmac ; i++)
+ for (i = 0 ; i < EDMA_MAX_PORTID_SUPPORTED; i++)
edma_netdev[i] = NULL;
for (i = 0 ; i < edma_cinfo->num_gmac ; i++) {
@@ -770,8 +766,11 @@ static int edma_axi_probe(struct platform_device *pdev)
/* Fill ring details */
edma_cinfo->num_tx_queues = EDMA_MAX_TRANSMIT_QUEUE;
- edma_cinfo->num_txq_per_core = (EDMA_MAX_TRANSMIT_QUEUE / 4);
+ edma_cinfo->num_txq_per_core = (EDMA_MAX_TRANSMIT_QUEUE / num_online_cpus());
+ edma_cinfo->num_txq_per_core_netdev = (EDMA_MAX_TRANSMIT_QUEUE / netdev_group / num_online_cpus());
edma_cinfo->tx_ring_count = EDMA_TX_RING_SIZE;
+ if (edma_cinfo->num_txq_per_core == 0)
+ edma_cinfo->num_txq_per_core = 1;
/* Update num rx queues based on module parameter */
edma_cinfo->num_rx_queues = num_rxq;
@@ -941,6 +940,13 @@ static int edma_axi_probe(struct platform_device *pdev)
idx_mac++;
}
+ if (edma_cinfo->num_gmac == 1) {
+ netdev_group = 1;
+ edma_cinfo->num_txq_per_core_netdev = (EDMA_MAX_TRANSMIT_QUEUE / netdev_group / num_online_cpus());
+ }
+ if (edma_cinfo->num_txq_per_core_netdev == 0)
+ edma_cinfo->num_txq_per_core_netdev = 1;
+
/* Populate the adapter structure register the netdevice */
for (i = 0; i < edma_cinfo->num_gmac; i++) {
int k, m;
@@ -948,17 +954,16 @@ static int edma_axi_probe(struct platform_device *pdev)
adapter[i] = netdev_priv(edma_netdev[i]);
adapter[i]->netdev = edma_netdev[i];
adapter[i]->pdev = pdev;
- for (j = 0; j < CONFIG_NR_CPUS; j++) {
- m = i % 2;
- adapter[i]->tx_start_offset[j] =
- ((j << EDMA_TX_CPU_START_SHIFT) + (m << 1));
+ for (j = 0; j < num_online_cpus() && j < EDMA_CPU_CORES_SUPPORTED; j++) {
+ m = i % netdev_group;
+ adapter[i]->tx_start_offset[j] = j * edma_cinfo->num_txq_per_core + m * edma_cinfo->num_txq_per_core_netdev;
/* Share the queues with available net-devices.
* For instance , with 5 net-devices
* eth0/eth2/eth4 will share q0,q1,q4,q5,q8,q9,q12,q13
* and eth1/eth3 will get the remaining.
*/
for (k = adapter[i]->tx_start_offset[j]; k <
- (adapter[i]->tx_start_offset[j] + 2); k++) {
+ (adapter[i]->tx_start_offset[j] + edma_cinfo->num_txq_per_core_netdev); k++) {
if (edma_fill_netdev(edma_cinfo, k, i, j)) {
pr_err("Netdev overflow Error\n");
goto err_register;
@@ -1111,9 +1116,12 @@ static int edma_axi_probe(struct platform_device *pdev)
/* populate per_core_info, do a napi_Add, request 16 TX irqs,
* 8 RX irqs, do a napi enable
*/
- for (i = 0; i < CONFIG_NR_CPUS; i++) {
+ for (i = 0; i < num_online_cpus() && i < EDMA_MAX_TRANSMIT_QUEUE; i++) {
u8 rx_start;
+ tx_mask[i] = (0xFFFF >> (16 - edma_cinfo->num_txq_per_core)) << (i * edma_cinfo->num_txq_per_core);
+ tx_start[i] = i * edma_cinfo->num_txq_per_core;
+
edma_cinfo->edma_percpu_info[i].napi.state = 0;
netif_napi_add(edma_netdev[0],
@@ -1138,7 +1146,7 @@ static int edma_axi_probe(struct platform_device *pdev)
/* Request irq per core */
for (j = edma_cinfo->edma_percpu_info[i].tx_start;
- j < tx_start[i] + 4; j++) {
+ j < tx_start[i] + edma_cinfo->num_txq_per_core; j++) {
sprintf(&edma_tx_irq[j][0], "edma_eth_tx%d", j);
err = request_irq(edma_cinfo->tx_irq[j],
edma_interrupt,
@@ -1263,7 +1271,7 @@ err_configure:
#endif
err_rmap_add_fail:
edma_free_irqs(adapter[0]);
- for (i = 0; i < CONFIG_NR_CPUS; i++)
+ for (i = 0; i < num_online_cpus() && i < EDMA_CPU_CORES_SUPPORTED; i++)
{
napi_disable(&edma_cinfo->edma_percpu_info[i].napi);
del_timer_sync(&edma_cinfo->edma_percpu_info[i].rx_realloc_timer);
@@ -1314,7 +1322,7 @@ static int edma_axi_remove(struct platform_device *pdev)
unregister_netdev(edma_netdev[i]);
edma_stop_rx_tx(hw);
- for (i = 0; i < CONFIG_NR_CPUS; i++)
+ for (i = 0; i < num_online_cpus() && i < EDMA_CPU_CORES_SUPPORTED; i++)
napi_disable(&edma_cinfo->edma_percpu_info[i].napi);
edma_irq_disable(edma_cinfo);
--
2.7.4

View File

@ -0,0 +1,205 @@
diff --git a/drivers/net/ethernet/qualcomm/essedma/edma.c b/drivers/net/ethernet/qualcomm/essedma/edma.c
index 724f355..7a16236 100644
--- a/drivers/net/ethernet/qualcomm/essedma/edma.c
+++ b/drivers/net/ethernet/qualcomm/essedma/edma.c
@@ -22,14 +22,6 @@ extern struct net_device *edma_netdev[EDMA_MAX_PORTID_SUPPORTED];
bool edma_stp_rstp;
u16 edma_ath_eth_type;
-/* edma_skb_priority_offset()
- * get edma skb priority
- */
-static unsigned int edma_skb_priority_offset(struct sk_buff *skb)
-{
- return (skb->priority >> 2) & 1;
-}
-
/* edma_alloc_tx_ring()
* Allocate Tx descriptors ring
*/
@@ -1014,13 +1006,14 @@ static inline u16 edma_tpd_available(struct edma_common_info *edma_cinfo,
/* edma_tx_queue_get()
* Get the starting number of the queue
*/
-static inline int edma_tx_queue_get(struct edma_adapter *adapter,
+static inline int edma_tx_queue_get(struct edma_common_info *edma_cinfo, struct edma_adapter *adapter,
struct sk_buff *skb, int txq_id)
{
/* skb->priority is used as an index to skb priority table
* and based on packet priority, correspong queue is assigned.
+ * FIXME we just simple use jiffies for time base balance
*/
- return adapter->tx_start_offset[txq_id] + edma_skb_priority_offset(skb);
+ return adapter->tx_start_offset[txq_id] + (smp_processor_id() % edma_cinfo->num_txq_per_core_netdev);
}
/* edma_tx_update_hw_idx()
@@ -1389,8 +1382,9 @@ netdev_tx_t edma_xmit(struct sk_buff *skb,
}
/* this will be one of the 4 TX queues exposed to linux kernel */
- txq_id = skb_get_queue_mapping(skb);
- queue_id = edma_tx_queue_get(adapter, skb, txq_id);
+ /* XXX what if num_online_cpus() > EDMA_CPU_CORES_SUPPORTED */
+ txq_id = ((jiffies >> 5) % (EDMA_CPU_CORES_SUPPORTED - 1) + smp_processor_id() + 1) % EDMA_CPU_CORES_SUPPORTED;
+ queue_id = edma_tx_queue_get(edma_cinfo, adapter, skb, txq_id);
etdr = edma_cinfo->tpd_ring[queue_id];
nq = netdev_get_tx_queue(net_dev, txq_id);
@@ -1871,8 +1865,8 @@ void edma_free_irqs(struct edma_adapter *adapter)
int i, j;
int k = ((edma_cinfo->num_rx_queues == 4) ? 1 : 2);
- for (i = 0; i < CONFIG_NR_CPUS; i++) {
- for (j = edma_cinfo->edma_percpu_info[i].tx_start; j < (edma_cinfo->edma_percpu_info[i].tx_start + 4); j++)
+ for (i = 0; i < num_online_cpus() && i < EDMA_CPU_CORES_SUPPORTED; i++) {
+ for (j = edma_cinfo->edma_percpu_info[i].tx_start; j < (edma_cinfo->edma_percpu_info[i].tx_start + edma_cinfo->num_txq_per_core); j++)
free_irq(edma_cinfo->tx_irq[j], &edma_cinfo->edma_percpu_info[i]);
for (j = edma_cinfo->edma_percpu_info[i].rx_start; j < (edma_cinfo->edma_percpu_info[i].rx_start + k); j++)
diff --git a/drivers/net/ethernet/qualcomm/essedma/edma.h b/drivers/net/ethernet/qualcomm/essedma/edma.h
index 015e5f5..abb0bd5 100644
--- a/drivers/net/ethernet/qualcomm/essedma/edma.h
+++ b/drivers/net/ethernet/qualcomm/essedma/edma.h
@@ -324,6 +324,7 @@ struct edma_common_info {
u32 from_cpu; /* from CPU TPD field */
u32 num_rxq_per_core; /* Rx queues per core */
u32 num_txq_per_core; /* Tx queues per core */
+ u32 num_txq_per_core_netdev; /* Tx queues per core per netdev */
u16 tx_ring_count; /* Tx ring count */
u16 rx_ring_count; /* Rx ring*/
u16 rx_head_buffer_len; /* rx buffer length */
@@ -331,7 +332,7 @@ struct edma_common_info {
u32 page_mode; /* Jumbo frame supported flag */
u32 fraglist_mode; /* fraglist supported flag */
struct edma_hw hw; /* edma hw specific structure */
- struct edma_per_cpu_queues_info edma_percpu_info[CONFIG_NR_CPUS]; /* per cpu information */
+ struct edma_per_cpu_queues_info edma_percpu_info[EDMA_CPU_CORES_SUPPORTED]; /* per cpu information */
spinlock_t stats_lock; /* protect edma stats area for updation */
struct timer_list edma_stats_timer;
bool is_single_phy;
@@ -401,7 +402,7 @@ struct edma_adapter {
u32 link_state; /* phy link state */
u32 phy_mdio_addr; /* PHY device address on MII interface */
u32 poll_required; /* check if link polling is required */
- u32 tx_start_offset[CONFIG_NR_CPUS]; /* tx queue start */
+ u32 tx_start_offset[EDMA_CPU_CORES_SUPPORTED]; /* tx queue start */
u32 default_vlan_tag; /* vlan tag */
u32 dp_bitmap;
uint8_t phy_id[MII_BUS_ID_SIZE + 3];
diff --git a/drivers/net/ethernet/qualcomm/essedma/edma_axi.c b/drivers/net/ethernet/qualcomm/essedma/edma_axi.c
index d53c63b..2d4770c 100644
--- a/drivers/net/ethernet/qualcomm/essedma/edma_axi.c
+++ b/drivers/net/ethernet/qualcomm/essedma/edma_axi.c
@@ -719,11 +719,7 @@ static int edma_axi_probe(struct platform_device *pdev)
int i, j, k, err = 0;
int portid_bmp;
int idx = 0, idx_mac = 0;
-
- if (CONFIG_NR_CPUS != EDMA_CPU_CORES_SUPPORTED) {
- dev_err(&pdev->dev, "Invalid CPU Cores\n");
- return -EINVAL;
- }
+ int netdev_group = 2;
if ((num_rxq != 4) && (num_rxq != 8)) {
dev_err(&pdev->dev, "Invalid RX queue, edma probe failed\n");
@@ -747,7 +743,7 @@ static int edma_axi_probe(struct platform_device *pdev)
/* Initialize the netdev array before allocation
* to avoid double free
*/
- for (i = 0 ; i < edma_cinfo->num_gmac ; i++)
+ for (i = 0 ; i < EDMA_MAX_PORTID_SUPPORTED; i++)
edma_netdev[i] = NULL;
for (i = 0 ; i < edma_cinfo->num_gmac ; i++) {
@@ -768,8 +764,11 @@ static int edma_axi_probe(struct platform_device *pdev)
/* Fill ring details */
edma_cinfo->num_tx_queues = EDMA_MAX_TRANSMIT_QUEUE;
- edma_cinfo->num_txq_per_core = (EDMA_MAX_TRANSMIT_QUEUE / 4);
+ edma_cinfo->num_txq_per_core = (EDMA_MAX_TRANSMIT_QUEUE / num_online_cpus());
+ edma_cinfo->num_txq_per_core_netdev = (EDMA_MAX_TRANSMIT_QUEUE / netdev_group / num_online_cpus());
edma_cinfo->tx_ring_count = EDMA_TX_RING_SIZE;
+ if (edma_cinfo->num_txq_per_core == 0)
+ edma_cinfo->num_txq_per_core = 1;
/* Update num rx queues based on module parameter */
edma_cinfo->num_rx_queues = num_rxq;
@@ -939,6 +938,13 @@ static int edma_axi_probe(struct platform_device *pdev)
idx_mac++;
}
+ if (edma_cinfo->num_gmac == 1) {
+ netdev_group = 1;
+ edma_cinfo->num_txq_per_core_netdev = (EDMA_MAX_TRANSMIT_QUEUE / netdev_group / num_online_cpus());
+ }
+ if (edma_cinfo->num_txq_per_core_netdev == 0)
+ edma_cinfo->num_txq_per_core_netdev = 1;
+
/* Populate the adapter structure register the netdevice */
for (i = 0; i < edma_cinfo->num_gmac; i++) {
int k, m;
@@ -946,17 +952,16 @@ static int edma_axi_probe(struct platform_device *pdev)
adapter[i] = netdev_priv(edma_netdev[i]);
adapter[i]->netdev = edma_netdev[i];
adapter[i]->pdev = pdev;
- for (j = 0; j < CONFIG_NR_CPUS; j++) {
- m = i % 2;
- adapter[i]->tx_start_offset[j] =
- ((j << EDMA_TX_CPU_START_SHIFT) + (m << 1));
+ for (j = 0; j < num_online_cpus() && j < EDMA_CPU_CORES_SUPPORTED; j++) {
+ m = i % netdev_group;
+ adapter[i]->tx_start_offset[j] = j * edma_cinfo->num_txq_per_core + m * edma_cinfo->num_txq_per_core_netdev;
/* Share the queues with available net-devices.
* For instance , with 5 net-devices
* eth0/eth2/eth4 will share q0,q1,q4,q5,q8,q9,q12,q13
* and eth1/eth3 will get the remaining.
*/
for (k = adapter[i]->tx_start_offset[j]; k <
- (adapter[i]->tx_start_offset[j] + 2); k++) {
+ (adapter[i]->tx_start_offset[j] + edma_cinfo->num_txq_per_core_netdev); k++) {
if (edma_fill_netdev(edma_cinfo, k, i, j)) {
pr_err("Netdev overflow Error\n");
goto err_register;
@@ -1109,9 +1114,12 @@ static int edma_axi_probe(struct platform_device *pdev)
/* populate per_core_info, do a napi_Add, request 16 TX irqs,
* 8 RX irqs, do a napi enable
*/
- for (i = 0; i < CONFIG_NR_CPUS; i++) {
+ for (i = 0; i < num_online_cpus() && i < EDMA_CPU_CORES_SUPPORTED; i++) {
u8 rx_start;
+ tx_mask[i] = (0xFFFF >> (16 - edma_cinfo->num_txq_per_core)) << (i * edma_cinfo->num_txq_per_core);
+ tx_start[i] = i * edma_cinfo->num_txq_per_core;
+
edma_cinfo->edma_percpu_info[i].napi.state = 0;
netif_napi_add(edma_netdev[0],
@@ -1131,7 +1139,7 @@ static int edma_axi_probe(struct platform_device *pdev)
/* Request irq per core */
for (j = edma_cinfo->edma_percpu_info[i].tx_start;
- j < tx_start[i] + 4; j++) {
+ j < tx_start[i] + edma_cinfo->num_txq_per_core; j++) {
sprintf(&edma_tx_irq[j][0], "edma_eth_tx%d", j);
err = request_irq(edma_cinfo->tx_irq[j],
edma_interrupt,
@@ -1253,7 +1261,7 @@ static int edma_axi_probe(struct platform_device *pdev)
#endif
err_rmap_add_fail:
edma_free_irqs(adapter[0]);
- for (i = 0; i < CONFIG_NR_CPUS; i++)
+ for (i = 0; i < num_online_cpus() && i < EDMA_CPU_CORES_SUPPORTED; i++)
napi_disable(&edma_cinfo->edma_percpu_info[i].napi);
err_reset:
err_unregister_sysctl_tbl:
@@ -1301,7 +1309,7 @@ static int edma_axi_remove(struct platform_device *pdev)
unregister_netdev(edma_netdev[i]);
edma_stop_rx_tx(hw);
- for (i = 0; i < CONFIG_NR_CPUS; i++)
+ for (i = 0; i < num_online_cpus() && i < EDMA_CPU_CORES_SUPPORTED; i++)
napi_disable(&edma_cinfo->edma_percpu_info[i].napi);
edma_irq_disable(edma_cinfo);

View File

@ -0,0 +1,54 @@
diff --git a/drivers/net/ethernet/qualcomm/essedma/edma.c b/drivers/net/ethernet/qualcomm/essedma/edma.c
index fc274c8..e9d12a4 100644
--- a/drivers/net/ethernet/qualcomm/essedma/edma.c
+++ b/drivers/net/ethernet/qualcomm/essedma/edma.c
@@ -2075,15 +2075,13 @@ int edma_poll(struct napi_struct *napi, int budget)
int i, work_done = 0;
u16 rx_pending_fill;
- /* Store the Rx/Tx status by ANDing it with
- * appropriate CPU RX?TX mask
+ /* Store the Tx status by ANDing it with
+ * appropriate CPU TX mask
*/
- edma_read_reg(EDMA_REG_RX_ISR, &reg_data);
- edma_percpu_info->rx_status |= reg_data & edma_percpu_info->rx_mask;
- shadow_rx_status = edma_percpu_info->rx_status;
edma_read_reg(EDMA_REG_TX_ISR, &reg_data);
edma_percpu_info->tx_status |= reg_data & edma_percpu_info->tx_mask;
shadow_tx_status = edma_percpu_info->tx_status;
+ edma_write_reg(EDMA_REG_TX_ISR, shadow_tx_status);
/* Every core will have a start, which will be computed
* in probe and stored in edma_percpu_info->tx_start variable.
@@ -2098,6 +2096,14 @@ int edma_poll(struct napi_struct *napi, int budget)
edma_percpu_info->tx_status &= ~(1 << queue_id);
}
+ /* Store the Rx status by ANDing it with
+ * appropriate CPU RX mask
+ */
+ edma_read_reg(EDMA_REG_RX_ISR, &reg_data);
+ edma_percpu_info->rx_status |= reg_data & edma_percpu_info->rx_mask;
+ shadow_rx_status = edma_percpu_info->rx_status;
+ edma_write_reg(EDMA_REG_RX_ISR, shadow_rx_status);
+
/* Every core will have a start, which will be computed
* in probe and stored in edma_percpu_info->tx_start variable.
* We will shift the status bit by tx_start to obtain
@@ -2122,15 +2128,6 @@ int edma_poll(struct napi_struct *napi, int budget)
}
}
- /* Clear the status register, to avoid the interrupts to
- * reoccur.This clearing of interrupt status register is
- * done here as writing to status register only takes place
- * once the producer/consumer index has been updated to
- * reflect that the packet transmission/reception went fine.
- */
- edma_write_reg(EDMA_REG_RX_ISR, shadow_rx_status);
- edma_write_reg(EDMA_REG_TX_ISR, shadow_tx_status);
-
/* If budget not fully consumed, exit the polling mode */
if (likely(work_done < budget)) {
napi_complete(napi);

View File

@ -0,0 +1,26 @@
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -334,6 +334,13 @@ config REGULATOR_HI655X
This driver provides support for the voltage regulators of the
Hisilicon Hi655x PMIC device.
+config REGULATOR_VQMMC_IPQ4019
+ tristate "IPQ4019 VQMMC SD LDO regulator support"
+ depends on ARCH_QCOM
+ help
+ This driver provides support for the VQMMC LDO I/0
+ voltage regulator of the IPQ4019 SD/EMMC controller.
+
config REGULATOR_ISL9305
tristate "Intersil ISL9305 regulator"
depends on I2C
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -43,6 +43,7 @@ obj-$(CONFIG_REGULATOR_GPIO) += gpio-reg
obj-$(CONFIG_REGULATOR_HI6421) += hi6421-regulator.o
obj-$(CONFIG_REGULATOR_HI6421V530) += hi6421v530-regulator.o
obj-$(CONFIG_REGULATOR_HI655X) += hi655x-regulator.o
+obj-$(CONFIG_REGULATOR_VQMMC_IPQ4019) += ipq4019-vqmmc-regulator.o
obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o
obj-$(CONFIG_REGULATOR_ISL9305) += isl9305.o
obj-$(CONFIG_REGULATOR_LM363X) += lm363x-regulator.o

View File

@ -0,0 +1,33 @@
From beae4078c07d3cdc90473a2b35eb0d2b4f3c922c Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Sat, 14 Sep 2019 23:13:17 +0200
Subject: [PATCH] ARM: dts: qcom: ipq4019: Add SDHCI VQMMC LDO regulator node
IPQ4019 has a built in SD/eMMC controller which depends on
VQMMC LDO regulator working.
Since we have a driver for it lets add the appropriate node for it.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
arch/arm/boot/dts/qcom-ipq4019.dtsi | 10 ++++++++++
1 file changed, 10 insertions(+)
--- a/arch/arm/boot/dts/qcom-ipq4019.dtsi
+++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi
@@ -216,6 +216,16 @@
interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
};
+ vqmmc: regulator@1948000 {
+ compatible = "qcom,ipq4019-vqmmc-regulator";
+ reg = <0x01948000 0x4>;
+ regulator-name = "vqmmc";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+ status = "disabled";
+ };
+
blsp_dma: dma@7884000 {
compatible = "qcom,bam-v1.7.0";
reg = <0x07884000 0x23000>;

View File

@ -0,0 +1,41 @@
Subject: [PATCH] ARM: dts: qcom: ipq4019: Add SDHCI controller node
Date: Thu, 15 Aug 2019 19:28:23 +0200
Message-Id: <20190815172823.12028-1-robimarko@gmail.com>
X-Mailer: git-send-email 2.21.0
MIME-Version: 1.0
Sender: linux-arm-msm-owner@vger.kernel.org
Precedence: bulk
List-ID: <linux-arm-msm.vger.kernel.org>
X-Mailing-List: linux-arm-msm@vger.kernel.org
X-Virus-Scanned: ClamAV using ClamSMTP
IPQ4019 has a built in SD/eMMC controller which is supported by the
SDHCI MSM driver, by the "qcom,sdhci-msm-v4" binding.
So lets add the appropriate node for it.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
arch/arm/boot/dts/qcom-ipq4019.dtsi | 12 ++++++++++++
1 file changed, 12 insertions(+)
--- a/arch/arm/boot/dts/qcom-ipq4019.dtsi
+++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi
@@ -226,6 +226,18 @@
status = "disabled";
};
+ sdhci: sdhci@7824900 {
+ compatible = "qcom,sdhci-msm-v4";
+ reg = <0x7824900 0x11c>, <0x7824000 0x800>;
+ interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "hc_irq", "pwr_irq";
+ bus-width = <8>;
+ clocks = <&gcc GCC_SDCC1_APPS_CLK>, <&gcc GCC_SDCC1_AHB_CLK>,
+ <&gcc GCC_DCD_XO_CLK>;
+ clock-names = "core", "iface", "xo";
+ status = "disabled";
+ };
+
blsp_dma: dma@7884000 {
compatible = "qcom,bam-v1.7.0";
reg = <0x07884000 0x23000>;

View File

@ -0,0 +1,57 @@
From: Georgi Djakov <georgi.djakov@linaro.org>
Date: Mon, 28 Nov 2016 19:39:20 +0200
Subject: [PATCH v2] mmc: sdhci-msm: Add sdhci_reset() implementation
Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>
---
drivers/mmc/host/sdhci-msm.c | 29 ++++++++++++++++++++++++++++-
1 file changed, 28 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 32879b845b75..157ae07f9309 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -1117,6 +1117,33 @@ static void sdhci_msm_set_clock(struct sdhci_host *host, unsigned int clock)
__sdhci_msm_set_clock(host, clock);
}
+void sdhci_msm_reset(struct sdhci_host *host, u8 mask)
+{
+ unsigned long timeout = 100;
+
+ sdhci_writeb(host, mask, SDHCI_SOFTWARE_RESET);
+
+ if (mask & SDHCI_RESET_ALL) {
+ host->clock = 0;
+
+ /*
+ * SDHCI_RESET_ALL triggers the PWR IRQ
+ * and we need to handle it here.
+ */
+ sdhci_msm_voltage_switch(host);
+ }
+
+ while (sdhci_readb(host, SDHCI_SOFTWARE_RESET) & mask) {
+ if (timeout == 0) {
+ pr_err("%s: Reset 0x%x never completed.\n",
+ mmc_hostname(host->mmc), (int)mask);
+ return;
+ }
+ timeout--;
+ mdelay(1);
+ }
+}
+
static void sdhci_msm_write_w(struct sdhci_host *host, u16 val, int reg)
{
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -1148,7 +1174,7 @@ static const struct of_device_id sdhci_msm_dt_match[] = {
MODULE_DEVICE_TABLE(of, sdhci_msm_dt_match);
static const struct sdhci_ops sdhci_msm_ops = {
- .reset = sdhci_reset,
+ .reset = sdhci_msm_reset,
.set_clock = sdhci_set_clock,
.get_min_clock = sdhci_msm_get_min_clock,
.get_max_clock = sdhci_msm_get_max_clock,

View File

@ -0,0 +1,82 @@
From 42b508d91b7f51b054f383e3aa42089ccab9300d Mon Sep 17 00:00:00 2001
From: Chen Minqiang <ptpt52@gmail.com>
Date: Thu, 15 Mar 2018 05:33:46 +0800
Subject: [PATCH] essedma: disable default vlan tagging
The essedma driver has its own unique take on VLAN management
and its configuration. In the original SDK, each VLAN is
assigned one virtual ethernet netdev.
However, this is non-standard. So, this patch does away
with the default_vlan_tag property the driver is using
and therefore forces the user to use the kernel's vlan
feature.
This patch also removes the "qcom,poll_required = <1>;" from
the essedma node.
Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
Signed-off-by: Chen Minqiang <ptpt52@gmail.com>
---
arch/arm/boot/dts/qcom-ipq4019.dtsi | 5 ++---
drivers/net/ethernet/qualcomm/essedma/edma.c | 14 +++++---------
2 files changed, 7 insertions(+), 12 deletions(-)
diff --git a/arch/arm/boot/dts/qcom-ipq4019.dtsi b/arch/arm/boot/dts/qcom-ipq4019.dtsi
index 3c4617f..7c3af8e 100644
--- a/arch/arm/boot/dts/qcom-ipq4019.dtsi
+++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi
@@ -598,8 +598,7 @@
qcom,page-mode = <0>;
qcom,rx_head_buf_size = <1540>;
qcom,mdio_supported;
- qcom,poll_required = <1>;
- qcom,num_gmac = <2>;
+ qcom,num_gmac = <1>;
interrupts = <0 65 IRQ_TYPE_EDGE_RISING
0 66 IRQ_TYPE_EDGE_RISING
0 67 IRQ_TYPE_EDGE_RISING
@@ -637,7 +636,7 @@
gmac0: gmac0 {
local-mac-address = [00 00 00 00 00 00];
- vlan_tag = <1 0x1f>;
+ vlan_tag = <1 0x3f>;
};
gmac1: gmac1 {
diff --git a/drivers/net/ethernet/qualcomm/essedma/edma.c b/drivers/net/ethernet/qualcomm/essedma/edma.c
index 05f9ce9..a3c0d66 100644
--- a/drivers/net/ethernet/qualcomm/essedma/edma.c
+++ b/drivers/net/ethernet/qualcomm/essedma/edma.c
@@ -750,13 +750,11 @@ static void edma_rx_complete(struct edma_common_info *edma_cinfo,
edma_receive_checksum(rd, skb);
/* Process VLAN HW acceleration indication provided by HW */
- if (unlikely(adapter->default_vlan_tag != rd->rrd4)) {
- vlan = rd->rrd4;
- if (likely(rd->rrd7 & EDMA_RRD_CVLAN))
- __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan);
- else if (rd->rrd1 & EDMA_RRD_SVLAN)
- __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021AD), vlan);
- }
+ vlan = rd->rrd4;
+ if (likely(rd->rrd7 & EDMA_RRD_CVLAN))
+ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan);
+ else if (rd->rrd1 & EDMA_RRD_SVLAN)
+ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021AD), vlan);
/* Update rx statistics */
adapter->stats.rx_packets++;
@@ -1434,8 +1432,6 @@ netdev_tx_t edma_xmit(struct sk_buff *skb,
if (!adapter->edma_cinfo->is_single_phy) {
if (unlikely(skb_vlan_tag_present(skb)))
flags_transmit |= EDMA_VLAN_TX_TAG_INSERT_FLAG;
- else if (adapter->default_vlan_tag)
- flags_transmit |= EDMA_VLAN_TX_TAG_INSERT_DEFAULT_FLAG;
}
/* Check and mark checksum offload */
--
2.7.4

View File

@ -0,0 +1,313 @@
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index 4f76ba5d78a9..eef0d931dd4e 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -38,18 +38,21 @@
static bool uart_print;
static bool skip_otp;
static bool rawmode;
+static bool ethernetmode;
module_param_named(debug_mask, ath10k_debug_mask, uint, 0644);
module_param_named(cryptmode, ath10k_cryptmode_param, uint, 0644);
module_param(uart_print, bool, 0644);
module_param(skip_otp, bool, 0644);
module_param(rawmode, bool, 0644);
+module_param(ethernetmode, bool, 0644);
MODULE_PARM_DESC(debug_mask, "Debugging mask");
MODULE_PARM_DESC(uart_print, "Uart target debugging");
MODULE_PARM_DESC(skip_otp, "Skip otp failure for calibration in testmode");
MODULE_PARM_DESC(cryptmode, "Crypto mode: 0-hardware, 1-software");
MODULE_PARM_DESC(rawmode, "Use raw 802.11 frame datapath");
+MODULE_PARM_DESC(ethernetmode, "Use ethernet frame datapath");
static const struct ath10k_hw_params ath10k_hw_params_list[] = {
{
@@ -2390,6 +2393,15 @@
/* peer stats are enabled by default */
set_bit(ATH10K_FLAG_PEER_STATS, &ar->dev_flags);
+
+ if (ethernetmode && rawmode) {
+ ath10k_err(ar, "ethernet and raw mode cannot co-exist\n");
+ status = -EINVAL;
+ goto err;
+ }
+
+ ar->ethernetmode = ethernetmode;
+
status = ath10k_core_probe_fw(ar);
if (status) {
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index af68eb5d0776..251fb57cbe8f 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -117,6 +117,7 @@
ATH10K_SKB_F_DELIVER_CAB = BIT(2),
ATH10K_SKB_F_MGMT = BIT(3),
ATH10K_SKB_F_QOS = BIT(4),
+ ATH10K_SKB_F_HW_80211_ENCAP = BIT(6),
};
struct ath10k_skb_cb {
@@ -1000,6 +1001,8 @@
u32 ampdu_reference;
void *ce_priv;
+
+ bool ethernetmode;
/* must be last */
u8 drv_priv[0] __aligned(sizeof(void *));
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index a182c0944cc7..0ca0705fe69a 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -812,6 +812,10 @@ static u8 ath10k_htt_tx_get_tid(struct sk_buff *skb, bool is_eth)
struct ieee80211_hdr *hdr = (void *)skb->data;
struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
+ /* Firmware takes care of tid classification for ethernet format */
+ if (cb->flags & ATH10K_SKB_F_HW_80211_ENCAP)
+ return skb->priority % IEEE80211_QOS_CTL_TID_MASK;
+
if (!is_eth && ieee80211_is_mgmt(hdr->frame_control))
return HTT_DATA_TX_EXT_TID_MGMT;
else if (cb->flags & ATH10K_SKB_F_QOS)
@@ -933,15 +937,17 @@ int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
txbuf_paddr = htt->txbuf.paddr +
(sizeof(struct ath10k_htt_txbuf) * msdu_id);
- if ((ieee80211_is_action(hdr->frame_control) ||
- ieee80211_is_deauth(hdr->frame_control) ||
- ieee80211_is_disassoc(hdr->frame_control)) &&
- ieee80211_has_protected(hdr->frame_control)) {
- skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
- } else if (!(skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT) &&
- txmode == ATH10K_HW_TXRX_RAW &&
- ieee80211_has_protected(hdr->frame_control)) {
- skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
+ if (!(info->control.flags & IEEE80211_TX_CTRL_HW_80211_ENCAP)) {
+ if ((ieee80211_is_action(hdr->frame_control) ||
+ ieee80211_is_deauth(hdr->frame_control) ||
+ ieee80211_is_disassoc(hdr->frame_control)) &&
+ ieee80211_has_protected(hdr->frame_control)) {
+ skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
+ } else if (!(skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT) &&
+ txmode == ATH10K_HW_TXRX_RAW &&
+ ieee80211_has_protected(hdr->frame_control)) {
+ skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
+ }
}
skb_cb->paddr = dma_map_single(dev, msdu->data, msdu->len,
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 83cc8778ca1e..0ea0d0be74a1 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -3363,10 +3363,14 @@
struct sk_buff *skb)
{
const struct ieee80211_hdr *hdr = (void *)skb->data;
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
__le16 fc = hdr->frame_control;
if (!vif || vif->type == NL80211_IFTYPE_MONITOR)
return ATH10K_HW_TXRX_RAW;
+
+ if (tx_info->control.flags & IEEE80211_TX_CTRL_HW_80211_ENCAP)
+ return ATH10K_HW_TXRX_ETHERNET;
if (ieee80211_is_mgmt(fc))
return ATH10K_HW_TXRX_MGMT;
@@ -3516,6 +3520,15 @@
struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
cb->flags = 0;
+ cb->vif = vif;
+ cb->txq = txq;
+ cb->airtime_est = airtime;
+
+ if (info->control.flags & IEEE80211_TX_CTRL_HW_80211_ENCAP) {
+ cb->flags |= ATH10K_SKB_F_HW_80211_ENCAP;
+ return;
+ }
+
if (!ath10k_tx_h_use_hwcrypto(vif, skb))
cb->flags |= ATH10K_SKB_F_NO_HWCRYPT;
@@ -3525,8 +3538,6 @@
if (ieee80211_is_data_qos(hdr->frame_control))
cb->flags |= ATH10K_SKB_F_QOS;
- cb->vif = vif;
- cb->txq = txq;
}
bool ath10k_mac_tx_frm_has_freq(struct ath10k *ar)
@@ -3631,7 +3642,10 @@
{
struct ieee80211_hw *hw = ar->hw;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- int ret;
+ int ret;.
+
+ if (info->control.flags & IEEE80211_TX_CTRL_HW_80211_ENCAP)
+ goto skip_encap;
/* We should disable CCK RATE due to P2P */
if (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE)
@@ -3655,6 +3669,7 @@
}
}
+ skip_encap:
if (!noque_offchan && info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) {
if (!ath10k_mac_tx_frm_has_freq(ar)) {
ath10k_dbg(ar, ATH10K_DBG_MAC, "mac queued offchannel skb %pK len %d\n",
@@ -3704,6 +3719,7 @@
int ret;
unsigned long time_left;
bool tmp_peer_created = false;
+ struct ieee80211_tx_info *info;
/* FW requirement: We must create a peer before FW will send out
* an offchannel frame. Otherwise the frame will be stuck and
@@ -3723,8 +3739,15 @@
ath10k_dbg(ar, ATH10K_DBG_MAC, "mac offchannel skb %pK len %d\n",
skb, skb->len);
- hdr = (struct ieee80211_hdr *)skb->data;
- peer_addr = ieee80211_get_DA(hdr);
+ info = IEEE80211_SKB_CB(skb);
+
+ if (info->control.flags & IEEE80211_TX_CTRL_HW_80211_ENCAP) {
+ peer_addr = skb->data;
+ } else {
+ hdr = (struct ieee80211_hdr *)skb->data;
+ peer_addr = ieee80211_get_DA(hdr);
+ }
+
spin_lock_bh(&ar->data_lock);
vdev_id = ar->scan.vdev_id;
@@ -4198,7 +4221,7 @@
struct ieee80211_vif *vif = info->control.vif;
struct ieee80211_sta *sta = control->sta;
struct ieee80211_txq *txq = NULL;
- struct ieee80211_hdr *hdr = (void *)skb->data;
+ struct ieee80211_hdr *hdr;
enum ath10k_hw_txrx_mode txmode;
enum ath10k_mac_tx_path txpath;
bool is_htt;
@@ -4227,14 +4250,20 @@
return;
}
- ret = ath10k_htt_tx_mgmt_inc_pending(htt, is_mgmt, is_presp);
- if (ret) {
- ath10k_dbg(ar, ATH10K_DBG_MAC, "failed to increase tx mgmt pending count: %d, dropping\n",
- ret);
- ath10k_htt_tx_dec_pending(htt);
- spin_unlock_bh(&ar->htt.tx_lock);
- ieee80211_free_txskb(ar->hw, skb);
- return;
+ if (is_mgmt) {
+ hdr = (struct ieee80211_hdr *)skb->data;
+ is_presp = ieee80211_is_probe_resp(hdr->frame_control);
+
+ ret = ath10k_htt_tx_mgmt_inc_pending(htt, is_mgmt,
+ is_presp);
+ if (ret) {
+ ath10k_dbg(ar, ATH10K_DBG_MAC, "failed to increase tx mgmt pending count: %d, dropping\n",
+ ret);
+ ath10k_htt_tx_dec_pending(htt);
+ spin_unlock_bh(&ar->htt.tx_lock);
+ ieee80211_free_txskb(ar->hw, skb);
+ return;
+ }
}
spin_unlock_bh(&ar->htt.tx_lock);
}
@@ -4929,10 +4958,12 @@
static int ath10k_add_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
+ struct wireless_dev *wdev = ieee80211_vif_to_wdev(vif);
struct ath10k *ar = hw->priv;
struct ath10k_vif *arvif = (void *)vif->drv_priv;
struct ath10k_peer *peer;
enum wmi_sta_powersave_param param;
+ int hw_encap = 0;
int ret = 0;
u32 value;
int bit;
@@ -5023,6 +5054,21 @@
WARN_ON(1);
break;
}
+
+ switch (vif->type) {
+ case NL80211_IFTYPE_STATION:
+ case NL80211_IFTYPE_AP_VLAN:
+ if (wdev->netdev->ieee80211_ptr->use_4addr)
+ break;
+ /* fall through */
+ case NL80211_IFTYPE_AP:
+ hw_encap = 1;
+ break;
+ default:
+ break;
+ }
+
+ ieee80211_set_hw_80211_encap(vif, ar->ethernetmode & hw_encap);
/* Using vdev_id as queue number will make it very easy to do per-vif
* tx queue locking. This shouldn't wrap due to interface combinations
@@ -8208,6 +8254,8 @@
ieee80211_hw_set(ar->hw, QUEUE_CONTROL);
ieee80211_hw_set(ar->hw, SUPPORTS_TX_FRAG);
ieee80211_hw_set(ar->hw, REPORTS_LOW_ACK);
+ if (ar->ethernetmode)
+ ieee80211_hw_set(ar->hw, SUPPORTS_80211_ENCAP);
if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
ieee80211_hw_set(ar->hw, SW_CRYPTO_CONTROL);
diff --git a/drivers/net/wireless/ath/ath10k/txrx.c b/drivers/net/wireless/ath/ath10k/txrx.c
index 39abf8b12903..1d8a6c2571a1 100644
--- a/drivers/net/wireless/ath/ath10k/txrx.c
+++ b/drivers/net/wireless/ath/ath10k/txrx.c
@@ -60,6 +60,8 @@ int ath10k_txrx_tx_unref(struct ath10k_htt *htt,
struct ath10k_skb_cb *skb_cb;
struct ath10k_txq *artxq;
struct sk_buff *msdu;
+ struct ieee80211_vif *vif;
+ u8 flags;
ath10k_dbg(ar, ATH10K_DBG_HTT,
"htt tx completion msdu_id %u status %d\n",
@@ -88,6 +90,9 @@ int ath10k_txrx_tx_unref(struct ath10k_htt *htt,
artxq->num_fw_queued--;
}
+ flags = skb_cb->flags;
+ vif = skb_cb->vif;
+
ath10k_htt_tx_free_msdu_id(htt, tx_done->msdu_id);
ath10k_htt_tx_dec_pending(htt);
if (htt->num_pending_tx == 0)
@@ -119,7 +124,11 @@ int ath10k_txrx_tx_unref(struct ath10k_htt *htt,
(info->flags & IEEE80211_TX_CTL_NO_ACK))
info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED;
- ieee80211_tx_status(htt->ar->hw, msdu);
+ if (flags & ATH10K_SKB_F_HW_80211_ENCAP)
+ ieee80211_tx_status_8023(htt->ar->hw, vif, msdu);
+ else
+ ieee80211_tx_status(htt->ar->hw, msdu);
+
/* we do not own the msdu anymore */
return 0;

View File

@ -0,0 +1,19 @@
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 10a4467..eb8fb94 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -1218,10 +1218,10 @@
if (ret) {
if (!(opt_flags & FW_OPT_NO_WARN))
dev_warn(device,
- "Direct firmware load for %s failed with error %d\n",
- name, ret);
+ "Direct firmware load for %s \n",
+ name);
if (opt_flags & FW_OPT_USERHELPER) {
- dev_warn(device, "Falling back to user helper\n");
+ dev_warn(device, "Load Wireless ART files\n");
ret = fw_load_from_user_helper(fw, name, device,
opt_flags);
}

View File

@ -0,0 +1,34 @@
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 24e1ea3..b1ff69a 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -313,6 +313,21 @@ static int m25p_remove(struct spi_device *spi)
return mtd_device_unregister(&flash->spi_nor.mtd);
}
+static void m25p_shutdown(struct spi_device *spi)
+{
+ struct m25p *flash = spi_get_drvdata(spi);
+
+ if ((&flash->spi_nor)->addr_width > 3) {
+ printk(KERN_INFO "m25p80: exit 4-byte address mode\n");
+ flash->command[0] = SPINOR_OP_EX4B; // exit 4-byte address mode: 0xe9
+ spi_write(flash->spi, flash->command, 1);
+ flash->command[0] = 0x66; // enable reset
+ spi_write(flash->spi, flash->command, 1);
+ flash->command[0] = 0x99; // reset
+ spi_write(flash->spi, flash->command, 1);
+ }
+}
+
/*
* Do NOT add to this array without reading the following:
*
@@ -387,6 +402,7 @@ static struct spi_driver m25p80_driver = {
.id_table = m25p_ids,
.probe = m25p_probe,
.remove = m25p_remove,
+ .shutdown = m25p_shutdown,
/* REVISIT: many of these chips have deep power-down modes, which
* should clearly be entered on suspend() to minimize power use.