ipq40xx: fix build error

This commit is contained in:
AmadeusGhost 2020-03-02 09:15:43 +08:00
parent fad657cacb
commit 679961d1b5
18 changed files with 326 additions and 1287 deletions

View File

@ -14,11 +14,6 @@ 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

@ -105,11 +105,6 @@ 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)
;;
@ -133,6 +128,11 @@ ipq40xx_setup_macs()
wan_mac=$(mtd_get_mac_ascii devinfo hw_mac_addr)
lan_mac=$(macaddr_add "$wan_mac" 1)
;;
p2w,r619ac|\
p2w,r619ac-128m)
wan_mac=$(cat /sys/class/net/eth0/address)
lan_mac=$(macaddr_add "$wan_mac" 1)
;;
esac
[ -n "$lan_mac" ] && ucidef_set_interface_macaddr "lan" $lan_mac

View File

@ -68,10 +68,6 @@ 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"
@ -81,7 +77,9 @@ platform_do_upgrade() {
CI_KERNPART="linux"
nand_do_upgrade "$1"
;;
compex,wpj419)
compex,wpj419|\
p2w,r619ac|\
p2w,r619ac-128m)
nand_do_upgrade "$1"
;;
linksys,ea6350v3 |\

View File

@ -0,0 +1,292 @@
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
#include "qcom-ipq4019.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/soc/qcom,tcsr.h>
/ {
aliases {
led-boot = &led_sys;
led-failsafe = &led_sys;
led-running = &led_sys;
led-upgrade = &led_sys;
label-mac-device = &gmac0;
};
soc {
rng@22000 {
status = "okay";
};
mdio@90000 {
status = "okay";
pinctrl-0 = <&mdio_pins>;
pinctrl-names = "default";
};
ess-psgmii@98000 {
status = "okay";
};
tcsr@1949000 {
compatible = "qcom,tcsr";
reg = <0x1949000 0x100>;
qcom,wifi_glb_cfg = <TCSR_WIFI_GLB_CFG>;
};
tcsr@194b000 {
compatible = "qcom,tcsr";
reg = <0x194b000 0x100>;
qcom,usb-hsphy-mode-select = <TCSR_USB_HSPHY_HOST_MODE>;
};
ess_tcsr@1953000 {
compatible = "qcom,tcsr";
reg = <0x1953000 0x1000>;
qcom,ess-interface-select = <TCSR_ESS_PSGMII>;
};
tcsr@1957000 {
compatible = "qcom,tcsr";
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
usb2@60f8800 {
status = "okay";
};
usb3@8af8800 {
status = "okay";
};
crypto@8e3a000 {
status = "okay";
};
watchdog@b017000 {
status = "okay";
};
ess-switch@c000000 {
status = "okay";
};
edma@c080000 {
status = "okay";
};
};
leds {
compatible = "gpio-leds";
pinctrl-0 = <&led_pins>;
pinctrl-names = "default";
led_sys: sys {
label = "r619ac:blue:sys";
gpios = <&tlmm 39 GPIO_ACTIVE_HIGH>;
};
wlan2g {
label = "r619ac:blue:wlan2g";
gpios = <&tlmm 32 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "phy0tpt";
};
wlan5g {
label = "r619ac:blue:wlan5g";
gpios = <&tlmm 50 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "phy1tpt";
};
};
keys {
compatible = "gpio-keys";
reset {
label = "reset";
gpios = <&tlmm 18 GPIO_ACTIVE_LOW>;
linux,code = <KEY_RESTART>;
};
};
};
&blsp_dma {
status = "okay";
};
&blsp1_spi1 {
status = "okay";
flash@0 {
reg = <0>;
compatible = "jedec,spi-nor";
spi-max-frequency = <24000000>;
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
partition@1 {
label = "Bootloader";
reg = <0x0 0x170000>;
};
partition@170000 {
label = "ART";
reg = <0x170000 0x10000>;
};
partition@180000 {
label = "unused";
reg = <0x180000 0xe80000>;
};
};
};
};
&blsp1_uart1 {
pinctrl-0 = <&serial_0_pins>;
pinctrl-names = "default";
status = "okay";
};
&cryptobam {
status = "okay";
};
&nand {
status = "okay";
nand@0 {
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
rootfs_part1: partition@0 {
label = "rootfs";
reg = <0x0 0x4000000>;
};
rootfs_part2: partition@4000000 {
label = "unused1";
reg = <0x4000000 0x4000000>;
};
};
};
};
&pcie0 {
status = "okay";
perst-gpio = <&tlmm 4 GPIO_ACTIVE_LOW>;
wake-gpio = <&tlmm 40 GPIO_ACTIVE_HIGH>;
/* Free slot for use */
bridge@0,0 {
reg = <0x00000000 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
ranges;
};
};
&qpic_bam {
status = "okay";
};
&sdhci {
pinctrl-0 = <&sd_0_pins>;
pinctrl-names = "default";
vqmmc-supply = <&vqmmc>;
status = "okay";
};
&tlmm {
mdio_pins: mdio_pinmux {
mux_1 {
pins = "gpio6";
function = "mdio";
bias-pull-up;
};
mux_2 {
pins = "gpio7";
function = "mdc";
bias-pull-up;
};
};
sd_0_pins: sd_0_pinmux {
mux_1 {
pins = "gpio23", "gpio24", "gpio25", "gpio26", "gpio28";
function = "sdio";
drive-strength = <10>;
};
mux_2 {
pins = "gpio27";
function = "sdio";
drive-strength = <16>;
};
};
serial_0_pins: serial0-pinmux {
mux {
pins = "gpio16", "gpio17";
function = "blsp_uart0";
bias-disable;
};
};
led_pins: led_pinmux {
mux {
pins = "gpio32", "gpio39", "gpio50";
function = "gpio";
bias-pull-up;
output-low;
};
mux_1 {
pins = "gpio52";
function = "gpio";
bias-pull-up;
output-high;
};
mux_2 {
pins = "gpio61";
function = "gpio";
bias-pull-down;
output-high;
};
};
};
&usb3_ss_phy {
status = "okay";
};
&usb3_hs_phy {
status = "okay";
};
&usb2_hs_phy {
status = "okay";
};
&vqmmc {
status = "okay";
};
&wifi0 {
status = "okay";
qcom,ath10k-calibration-variant = "R619AC";
};
&wifi1 {
status = "okay";
qcom,ath10k-calibration-variant = "R619AC";
};

View File

@ -480,28 +480,12 @@ endef
TARGET_DEVICES += openmesh_a62
define Device/qcom_ap-dk01.1-c1
DEVICE_VENDOR := Qualcomm Atheros
DEVICE_MODEL := AP-DK01.1
DEVICE_VARIANT := C1
BOARD_NAME := ap-dk01.1-c1
SOC := qcom-ipq4019
DEVICE_DTS := qcom-ipq4019-ap.dk01.1-c1
KERNEL_INSTALL := 1
KERNEL_SIZE := 4096k
IMAGE_SIZE := 26624k
$(call Device/FitImage)
IMAGES := sysupgrade.bin
IMAGE/sysupgrade.bin := append-kernel | pad-to $$$${KERNEL_SIZE} | append-rootfs | pad-rootfs | append-metadata
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
SOC := qcom-ipq4019
DEVICE_DTS_CONFIG := config@10
BLOCKSIZE := 128k
PAGESIZE := 2048
@ -517,7 +501,7 @@ define Device/p2w_r619ac-128m
DEVICE_VENDOR := P&W
DEVICE_MODEL := R619AC
DEVICE_VARIANT := 128M
DEVICE_DTS := qcom-ipq4019-r619ac-128m
SOC := qcom-ipq4019
DEVICE_DTS_CONFIG := config@10
BLOCKSIZE := 128k
PAGESIZE := 2048
@ -525,6 +509,22 @@ define Device/p2w_r619ac-128m
endef
TARGET_DEVICES += p2w_r619ac-128m
define Device/qcom_ap-dk01.1-c1
DEVICE_VENDOR := Qualcomm Atheros
DEVICE_MODEL := AP-DK01.1
DEVICE_VARIANT := C1
BOARD_NAME := ap-dk01.1-c1
SOC := qcom-ipq4019
DEVICE_DTS := qcom-ipq4019-ap.dk01.1-c1
KERNEL_INSTALL := 1
KERNEL_SIZE := 4096k
IMAGE_SIZE := 26624k
$(call Device/FitImage)
IMAGES := sysupgrade.bin
IMAGE/sysupgrade.bin := append-kernel | pad-to $$$${KERNEL_SIZE} | append-rootfs | pad-rootfs | append-metadata
endef
TARGET_DEVICES += qcom_ap-dk01.1-c1
define Device/qcom_ap-dk04.1-c1
$(call Device/FitImage)
$(call Device/UbiFit)

View File

@ -1,11 +0,0 @@
--- 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

@ -1,68 +0,0 @@
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

@ -1,91 +0,0 @@
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

@ -1,144 +0,0 @@
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

@ -1,223 +0,0 @@
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

@ -1,205 +0,0 @@
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

@ -1,54 +0,0 @@
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

@ -5,12 +5,12 @@ Subject: [PATCH 69/69] arm: boot: add dts files
Signed-off-by: John Crispin <john@phrozen.org>
---
arch/arm/boot/dts/Makefile | 10 ++++++++
1 file changed, 10 insertions(+)
arch/arm/boot/dts/Makefile | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -697,7 +697,33 @@ dtb-$(CONFIG_ARCH_QCOM) += \
@@ -697,7 +697,31 @@ dtb-$(CONFIG_ARCH_QCOM) += \
qcom-apq8074-dragonboard.dtb \
qcom-apq8084-ifc6540.dtb \
qcom-apq8084-mtp.dtb \
@ -34,8 +34,6 @@ Signed-off-by: John Crispin <john@phrozen.org>
+ qcom-ipq4019-fritzrepeater-3000.dtb \
+ qcom-ipq4019-ea8300.dtb \
+ qcom-ipq4019-map-ac2200.dtb \
+ qcom-ipq4019-r619ac.dtb \
+ qcom-ipq4019-r619ac-128m.dtb \
+ qcom-ipq4019-e2600ac-c1.dtb \
+ qcom-ipq4019-e2600ac-c2.dtb \
+ qcom-ipq4028-wpj428.dtb \

View File

@ -1,82 +0,0 @@
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

@ -1,313 +0,0 @@
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

@ -1,19 +0,0 @@
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

@ -1,34 +0,0 @@
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.

View File

@ -5,12 +5,12 @@ Subject: [PATCH] arm: boot: add dts files
Signed-off-by: John Crispin <john@phrozen.org>
---
arch/arm/boot/dts/Makefile | 25 +++++++++++++++++++++++
1 file changed, 25 insertions(+)
arch/arm/boot/dts/Makefile | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -785,11 +785,44 @@ dtb-$(CONFIG_ARCH_QCOM) += \
@@ -785,11 +785,45 @@ dtb-$(CONFIG_ARCH_QCOM) += \
qcom-apq8074-dragonboard.dtb \
qcom-apq8084-ifc6540.dtb \
qcom-apq8084-mtp.dtb \
@ -42,10 +42,10 @@ Signed-off-by: John Crispin <john@phrozen.org>
+ qcom-ipq4019-fritzrepeater-3000.dtb \
+ qcom-ipq4019-ea8300.dtb \
+ qcom-ipq4019-map-ac2200.dtb \
+ qcom-ipq4019-r619ac.dtb \
+ qcom-ipq4019-r619ac-128m.dtb \
+ qcom-ipq4019-e2600ac-c1.dtb \
+ qcom-ipq4019-e2600ac-c2.dtb \
+ qcom-ipq4019-r619ac.dtb \
+ qcom-ipq4019-r619ac-128m.dtb \
+ qcom-ipq4019-u4019-32m.dtb \
+ qcom-ipq4019-wpj419.dtb \
+ qcom-ipq4028-wpj428.dtb \