]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/6.6.26/net-wwan-t7xx-split-64bit-accesses-to-fix-alignment-.patch
Linux 6.6.26
[thirdparty/kernel/stable-queue.git] / releases / 6.6.26 / net-wwan-t7xx-split-64bit-accesses-to-fix-alignment-.patch
1 From c8f04cffdf334ffdc00b2d4ff06a66c247213751 Mon Sep 17 00:00:00 2001
2 From: Sasha Levin <sashal@kernel.org>
3 Date: Fri, 22 Mar 2024 15:40:00 +0100
4 Subject: net: wwan: t7xx: Split 64bit accesses to fix alignment issues
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 From: Bjørn Mork <bjorn@mork.no>
10
11 [ Upstream commit 7d5a7dd5a35876f0ecc286f3602a88887a788217 ]
12
13 Some of the registers are aligned on a 32bit boundary, causing
14 alignment faults on 64bit platforms.
15
16 Unable to handle kernel paging request at virtual address ffffffc084a1d004
17 Mem abort info:
18 ESR = 0x0000000096000061
19 EC = 0x25: DABT (current EL), IL = 32 bits
20 SET = 0, FnV = 0
21 EA = 0, S1PTW = 0
22 FSC = 0x21: alignment fault
23 Data abort info:
24 ISV = 0, ISS = 0x00000061, ISS2 = 0x00000000
25 CM = 0, WnR = 1, TnD = 0, TagAccess = 0
26 GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
27 swapper pgtable: 4k pages, 39-bit VAs, pgdp=0000000046ad6000
28 [ffffffc084a1d004] pgd=100000013ffff003, p4d=100000013ffff003, pud=100000013ffff003, pmd=0068000020a00711
29 Internal error: Oops: 0000000096000061 [#1] SMP
30 Modules linked in: mtk_t7xx(+) qcserial pppoe ppp_async option nft_fib_inet nf_flow_table_inet mt7921u(O) mt7921s(O) mt7921e(O) mt7921_common(O) iwlmvm(O) iwldvm(O) usb_wwan rndis_host qmi_wwan pppox ppp_generic nft_reject_ipv6 nft_reject_ipv4 nft_reject_inet nft_reject nft_redir nft_quota nft_numgen nft_nat nft_masq nft_log nft_limit nft_hash nft_flow_offload nft_fib_ipv6 nft_fib_ipv4 nft_fib nft_ct nft_chain_nat nf_tables nf_nat nf_flow_table nf_conntrack mt7996e(O) mt792x_usb(O) mt792x_lib(O) mt7915e(O) mt76_usb(O) mt76_sdio(O) mt76_connac_lib(O) mt76(O) mac80211(O) iwlwifi(O) huawei_cdc_ncm cfg80211(O) cdc_ncm cdc_ether wwan usbserial usbnet slhc sfp rtc_pcf8563 nfnetlink nf_reject_ipv6 nf_reject_ipv4 nf_log_syslog nf_defrag_ipv6 nf_defrag_ipv4 mt6577_auxadc mdio_i2c libcrc32c compat(O) cdc_wdm cdc_acm at24 crypto_safexcel pwm_fan i2c_gpio i2c_smbus industrialio i2c_algo_bit i2c_mux_reg i2c_mux_pca954x i2c_mux_pca9541 i2c_mux_gpio i2c_mux dummy oid_registry tun sha512_arm64 sha1_ce sha1_generic seqiv
31 md5 geniv des_generic libdes cbc authencesn authenc leds_gpio xhci_plat_hcd xhci_pci xhci_mtk_hcd xhci_hcd nvme nvme_core gpio_button_hotplug(O) dm_mirror dm_region_hash dm_log dm_crypt dm_mod dax usbcore usb_common ptp aquantia pps_core mii tpm encrypted_keys trusted
32 CPU: 3 PID: 5266 Comm: kworker/u9:1 Tainted: G O 6.6.22 #0
33 Hardware name: Bananapi BPI-R4 (DT)
34 Workqueue: md_hk_wq t7xx_fsm_uninit [mtk_t7xx]
35 pstate: 804000c5 (Nzcv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
36 pc : t7xx_cldma_hw_set_start_addr+0x1c/0x3c [mtk_t7xx]
37 lr : t7xx_cldma_start+0xac/0x13c [mtk_t7xx]
38 sp : ffffffc085d63d30
39 x29: ffffffc085d63d30 x28: 0000000000000000 x27: 0000000000000000
40 x26: 0000000000000000 x25: ffffff80c804f2c0 x24: ffffff80ca196c05
41 x23: 0000000000000000 x22: ffffff80c814b9b8 x21: ffffff80c814b128
42 x20: 0000000000000001 x19: ffffff80c814b080 x18: 0000000000000014
43 x17: 0000000055c9806b x16: 000000007c5296d0 x15: 000000000f6bca68
44 x14: 00000000dbdbdce4 x13: 000000001aeaf72a x12: 0000000000000001
45 x11: 0000000000000000 x10: 0000000000000000 x9 : 0000000000000000
46 x8 : ffffff80ca1ef6b4 x7 : ffffff80c814b818 x6 : 0000000000000018
47 x5 : 0000000000000870 x4 : 0000000000000000 x3 : 0000000000000000
48 x2 : 000000010a947000 x1 : ffffffc084a1d004 x0 : ffffffc084a1d004
49 Call trace:
50 t7xx_cldma_hw_set_start_addr+0x1c/0x3c [mtk_t7xx]
51 t7xx_fsm_uninit+0x578/0x5ec [mtk_t7xx]
52 process_one_work+0x154/0x2a0
53 worker_thread+0x2ac/0x488
54 kthread+0xe0/0xec
55 ret_from_fork+0x10/0x20
56 Code: f9400800 91001000 8b214001 d50332bf (f9000022)
57 ---[ end trace 0000000000000000 ]---
58
59 The inclusion of io-64-nonatomic-lo-hi.h indicates that all 64bit
60 accesses can be replaced by pairs of nonatomic 32bit access. Fix
61 alignment by forcing all accesses to be 32bit on 64bit platforms.
62
63 Link: https://forum.openwrt.org/t/fibocom-fm350-gl-support/142682/72
64 Fixes: 39d439047f1d ("net: wwan: t7xx: Add control DMA interface")
65 Signed-off-by: Bjørn Mork <bjorn@mork.no>
66 Reviewed-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
67 Tested-by: Liviu Dudau <liviu@dudau.co.uk>
68 Link: https://lore.kernel.org/r/20240322144000.1683822-1-bjorn@mork.no
69 Signed-off-by: Jakub Kicinski <kuba@kernel.org>
70 Signed-off-by: Sasha Levin <sashal@kernel.org>
71 ---
72 drivers/net/wwan/t7xx/t7xx_cldma.c | 4 ++--
73 drivers/net/wwan/t7xx/t7xx_hif_cldma.c | 9 +++++----
74 drivers/net/wwan/t7xx/t7xx_pcie_mac.c | 8 ++++----
75 3 files changed, 11 insertions(+), 10 deletions(-)
76
77 diff --git a/drivers/net/wwan/t7xx/t7xx_cldma.c b/drivers/net/wwan/t7xx/t7xx_cldma.c
78 index 9f43f256db1d0..f0a4783baf1f3 100644
79 --- a/drivers/net/wwan/t7xx/t7xx_cldma.c
80 +++ b/drivers/net/wwan/t7xx/t7xx_cldma.c
81 @@ -106,7 +106,7 @@ bool t7xx_cldma_tx_addr_is_set(struct t7xx_cldma_hw *hw_info, unsigned int qno)
82 {
83 u32 offset = REG_CLDMA_UL_START_ADDRL_0 + qno * ADDR_SIZE;
84
85 - return ioread64(hw_info->ap_pdn_base + offset);
86 + return ioread64_lo_hi(hw_info->ap_pdn_base + offset);
87 }
88
89 void t7xx_cldma_hw_set_start_addr(struct t7xx_cldma_hw *hw_info, unsigned int qno, u64 address,
90 @@ -117,7 +117,7 @@ void t7xx_cldma_hw_set_start_addr(struct t7xx_cldma_hw *hw_info, unsigned int qn
91
92 reg = tx_rx == MTK_RX ? hw_info->ap_ao_base + REG_CLDMA_DL_START_ADDRL_0 :
93 hw_info->ap_pdn_base + REG_CLDMA_UL_START_ADDRL_0;
94 - iowrite64(address, reg + offset);
95 + iowrite64_lo_hi(address, reg + offset);
96 }
97
98 void t7xx_cldma_hw_resume_queue(struct t7xx_cldma_hw *hw_info, unsigned int qno,
99 diff --git a/drivers/net/wwan/t7xx/t7xx_hif_cldma.c b/drivers/net/wwan/t7xx/t7xx_hif_cldma.c
100 index cc70360364b7d..554ba4669cc8d 100644
101 --- a/drivers/net/wwan/t7xx/t7xx_hif_cldma.c
102 +++ b/drivers/net/wwan/t7xx/t7xx_hif_cldma.c
103 @@ -139,8 +139,9 @@ static int t7xx_cldma_gpd_rx_from_q(struct cldma_queue *queue, int budget, bool
104 return -ENODEV;
105 }
106
107 - gpd_addr = ioread64(hw_info->ap_pdn_base + REG_CLDMA_DL_CURRENT_ADDRL_0 +
108 - queue->index * sizeof(u64));
109 + gpd_addr = ioread64_lo_hi(hw_info->ap_pdn_base +
110 + REG_CLDMA_DL_CURRENT_ADDRL_0 +
111 + queue->index * sizeof(u64));
112 if (req->gpd_addr == gpd_addr || hwo_polling_count++ >= 100)
113 return 0;
114
115 @@ -318,8 +319,8 @@ static void t7xx_cldma_txq_empty_hndl(struct cldma_queue *queue)
116 struct t7xx_cldma_hw *hw_info = &md_ctrl->hw_info;
117
118 /* Check current processing TGPD, 64-bit address is in a table by Q index */
119 - ul_curr_addr = ioread64(hw_info->ap_pdn_base + REG_CLDMA_UL_CURRENT_ADDRL_0 +
120 - queue->index * sizeof(u64));
121 + ul_curr_addr = ioread64_lo_hi(hw_info->ap_pdn_base + REG_CLDMA_UL_CURRENT_ADDRL_0 +
122 + queue->index * sizeof(u64));
123 if (req->gpd_addr != ul_curr_addr) {
124 spin_unlock_irqrestore(&md_ctrl->cldma_lock, flags);
125 dev_err(md_ctrl->dev, "CLDMA%d queue %d is not empty\n",
126 diff --git a/drivers/net/wwan/t7xx/t7xx_pcie_mac.c b/drivers/net/wwan/t7xx/t7xx_pcie_mac.c
127 index 76da4c15e3de1..f071ec7ff23d5 100644
128 --- a/drivers/net/wwan/t7xx/t7xx_pcie_mac.c
129 +++ b/drivers/net/wwan/t7xx/t7xx_pcie_mac.c
130 @@ -75,7 +75,7 @@ static void t7xx_pcie_mac_atr_tables_dis(void __iomem *pbase, enum t7xx_atr_src_
131 for (i = 0; i < ATR_TABLE_NUM_PER_ATR; i++) {
132 offset = ATR_PORT_OFFSET * port + ATR_TABLE_OFFSET * i;
133 reg = pbase + ATR_PCIE_WIN0_T0_ATR_PARAM_SRC_ADDR + offset;
134 - iowrite64(0, reg);
135 + iowrite64_lo_hi(0, reg);
136 }
137 }
138
139 @@ -112,17 +112,17 @@ static int t7xx_pcie_mac_atr_cfg(struct t7xx_pci_dev *t7xx_dev, struct t7xx_atr_
140
141 reg = pbase + ATR_PCIE_WIN0_T0_TRSL_ADDR + offset;
142 value = cfg->trsl_addr & ATR_PCIE_WIN0_ADDR_ALGMT;
143 - iowrite64(value, reg);
144 + iowrite64_lo_hi(value, reg);
145
146 reg = pbase + ATR_PCIE_WIN0_T0_TRSL_PARAM + offset;
147 iowrite32(cfg->trsl_id, reg);
148
149 reg = pbase + ATR_PCIE_WIN0_T0_ATR_PARAM_SRC_ADDR + offset;
150 value = (cfg->src_addr & ATR_PCIE_WIN0_ADDR_ALGMT) | (atr_size << 1) | BIT(0);
151 - iowrite64(value, reg);
152 + iowrite64_lo_hi(value, reg);
153
154 /* Ensure ATR is set */
155 - ioread64(reg);
156 + ioread64_lo_hi(reg);
157 return 0;
158 }
159
160 --
161 2.43.0
162