]>
Commit | Line | Data |
---|---|---|
f524f829 DM |
1 | // SPDX-License-Identifier: GPL-2.0 |
2 | // CAN bus driver for Bosch M_CAN controller | |
3 | // Copyright (C) 2014 Freescale Semiconductor, Inc. | |
4 | // Dong Aisheng <b29396@freescale.com> | |
5 | // Copyright (C) 2018-19 Texas Instruments Incorporated - http://www.ti.com/ | |
6 | ||
7 | /* Bosch M_CAN user manual can be obtained from: | |
4c832b38 | 8 | * https://github.com/linux-can/can-doc/tree/master/m_can |
e0d1f481 DA |
9 | */ |
10 | ||
17447f08 | 11 | #include <linux/bitfield.h> |
e0d1f481 DA |
12 | #include <linux/interrupt.h> |
13 | #include <linux/io.h> | |
14 | #include <linux/kernel.h> | |
15 | #include <linux/module.h> | |
16 | #include <linux/netdevice.h> | |
17 | #include <linux/of.h> | |
18 | #include <linux/of_device.h> | |
19 | #include <linux/platform_device.h> | |
cdf8259d | 20 | #include <linux/pm_runtime.h> |
b03cfc5b | 21 | #include <linux/iopoll.h> |
e0d1f481 | 22 | #include <linux/can/dev.h> |
c9b3bce1 | 23 | #include <linux/pinctrl/consumer.h> |
d836cb5f | 24 | #include <linux/phy/phy.h> |
e0d1f481 | 25 | |
f524f829 | 26 | #include "m_can.h" |
e0d1f481 DA |
27 | |
28 | /* registers definition */ | |
29 | enum m_can_reg { | |
30 | M_CAN_CREL = 0x0, | |
31 | M_CAN_ENDN = 0x4, | |
32 | M_CAN_CUST = 0x8, | |
5e1bd15a | 33 | M_CAN_DBTP = 0xc, |
e0d1f481 DA |
34 | M_CAN_TEST = 0x10, |
35 | M_CAN_RWD = 0x14, | |
36 | M_CAN_CCCR = 0x18, | |
5e1bd15a | 37 | M_CAN_NBTP = 0x1c, |
e0d1f481 DA |
38 | M_CAN_TSCC = 0x20, |
39 | M_CAN_TSCV = 0x24, | |
40 | M_CAN_TOCC = 0x28, | |
41 | M_CAN_TOCV = 0x2c, | |
42 | M_CAN_ECR = 0x40, | |
43 | M_CAN_PSR = 0x44, | |
709efa6f | 44 | /* TDCR Register only available for version >=3.1.x */ |
5e1bd15a | 45 | M_CAN_TDCR = 0x48, |
e0d1f481 DA |
46 | M_CAN_IR = 0x50, |
47 | M_CAN_IE = 0x54, | |
48 | M_CAN_ILS = 0x58, | |
49 | M_CAN_ILE = 0x5c, | |
50 | M_CAN_GFC = 0x80, | |
51 | M_CAN_SIDFC = 0x84, | |
52 | M_CAN_XIDFC = 0x88, | |
53 | M_CAN_XIDAM = 0x90, | |
54 | M_CAN_HPMS = 0x94, | |
55 | M_CAN_NDAT1 = 0x98, | |
56 | M_CAN_NDAT2 = 0x9c, | |
57 | M_CAN_RXF0C = 0xa0, | |
58 | M_CAN_RXF0S = 0xa4, | |
59 | M_CAN_RXF0A = 0xa8, | |
60 | M_CAN_RXBC = 0xac, | |
61 | M_CAN_RXF1C = 0xb0, | |
62 | M_CAN_RXF1S = 0xb4, | |
63 | M_CAN_RXF1A = 0xb8, | |
64 | M_CAN_RXESC = 0xbc, | |
65 | M_CAN_TXBC = 0xc0, | |
66 | M_CAN_TXFQS = 0xc4, | |
67 | M_CAN_TXESC = 0xc8, | |
68 | M_CAN_TXBRP = 0xcc, | |
69 | M_CAN_TXBAR = 0xd0, | |
70 | M_CAN_TXBCR = 0xd4, | |
71 | M_CAN_TXBTO = 0xd8, | |
72 | M_CAN_TXBCF = 0xdc, | |
73 | M_CAN_TXBTIE = 0xe0, | |
74 | M_CAN_TXBCIE = 0xe4, | |
75 | M_CAN_TXEFC = 0xf0, | |
76 | M_CAN_TXEFS = 0xf4, | |
77 | M_CAN_TXEFA = 0xf8, | |
78 | }; | |
79 | ||
f524f829 DM |
80 | /* napi related */ |
81 | #define M_CAN_NAPI_WEIGHT 64 | |
e0d1f481 | 82 | |
f524f829 DM |
83 | /* message ram configuration data length */ |
84 | #define MRAM_CFG_LEN 8 | |
e0d1f481 | 85 | |
b03cfc5b | 86 | /* Core Release Register (CREL) */ |
20779943 TCB |
87 | #define CREL_REL_MASK GENMASK(31, 28) |
88 | #define CREL_STEP_MASK GENMASK(27, 24) | |
89 | #define CREL_SUBSTEP_MASK GENMASK(23, 20) | |
b03cfc5b | 90 | |
5e1bd15a MH |
91 | /* Data Bit Timing & Prescaler Register (DBTP) */ |
92 | #define DBTP_TDC BIT(23) | |
20779943 TCB |
93 | #define DBTP_DBRP_MASK GENMASK(20, 16) |
94 | #define DBTP_DTSEG1_MASK GENMASK(12, 8) | |
95 | #define DBTP_DTSEG2_MASK GENMASK(7, 4) | |
96 | #define DBTP_DSJW_MASK GENMASK(3, 0) | |
80646733 | 97 | |
e759c626 | 98 | /* Transmitter Delay Compensation Register (TDCR) */ |
20779943 TCB |
99 | #define TDCR_TDCO_MASK GENMASK(14, 8) |
100 | #define TDCR_TDCF_MASK GENMASK(6, 0) | |
e759c626 | 101 | |
e0d1f481 | 102 | /* Test Register (TEST) */ |
5e1bd15a | 103 | #define TEST_LBCK BIT(4) |
e0d1f481 | 104 | |
50fe7547 | 105 | /* CC Control Register (CCCR) */ |
5e1bd15a | 106 | #define CCCR_TXP BIT(14) |
80646733 | 107 | #define CCCR_TEST BIT(7) |
fb7d6a81 | 108 | #define CCCR_DAR BIT(6) |
80646733 | 109 | #define CCCR_MON BIT(5) |
5e1bd15a MH |
110 | #define CCCR_CSR BIT(4) |
111 | #define CCCR_CSA BIT(3) | |
112 | #define CCCR_ASM BIT(2) | |
80646733 DA |
113 | #define CCCR_CCE BIT(1) |
114 | #define CCCR_INIT BIT(0) | |
38395f30 TCB |
115 | /* for version 3.0.x */ |
116 | #define CCCR_CMR_MASK GENMASK(11, 10) | |
117 | #define CCCR_CMR_CANFD 0x1 | |
118 | #define CCCR_CMR_CANFD_BRS 0x2 | |
119 | #define CCCR_CMR_CAN 0x3 | |
120 | #define CCCR_CME_MASK GENMASK(9, 8) | |
121 | #define CCCR_CME_CAN 0 | |
122 | #define CCCR_CME_CANFD 0x1 | |
123 | #define CCCR_CME_CANFD_BRS 0x2 | |
5e1bd15a MH |
124 | /* for version >=3.1.x */ |
125 | #define CCCR_EFBI BIT(13) | |
126 | #define CCCR_PXHD BIT(12) | |
127 | #define CCCR_BRSE BIT(9) | |
128 | #define CCCR_FDOE BIT(8) | |
38395f30 | 129 | /* for version >=3.2.x */ |
5e1bd15a | 130 | #define CCCR_NISO BIT(15) |
38395f30 TCB |
131 | /* for version >=3.3.x */ |
132 | #define CCCR_WMM BIT(11) | |
133 | #define CCCR_UTSU BIT(10) | |
5e1bd15a MH |
134 | |
135 | /* Nominal Bit Timing & Prescaler Register (NBTP) */ | |
20779943 TCB |
136 | #define NBTP_NSJW_MASK GENMASK(31, 25) |
137 | #define NBTP_NBRP_MASK GENMASK(24, 16) | |
138 | #define NBTP_NTSEG1_MASK GENMASK(15, 8) | |
139 | #define NBTP_NTSEG2_MASK GENMASK(6, 0) | |
e0d1f481 | 140 | |
17447f08 TCB |
141 | /* Timestamp Counter Configuration Register (TSCC) */ |
142 | #define TSCC_TCP_MASK GENMASK(19, 16) | |
143 | #define TSCC_TSS_MASK GENMASK(1, 0) | |
144 | #define TSCC_TSS_DISABLE 0x0 | |
145 | #define TSCC_TSS_INTERNAL 0x1 | |
146 | #define TSCC_TSS_EXTERNAL 0x2 | |
147 | ||
148 | /* Timestamp Counter Value Register (TSCV) */ | |
149 | #define TSCV_TSC_MASK GENMASK(15, 0) | |
150 | ||
50fe7547 | 151 | /* Error Counter Register (ECR) */ |
e0d1f481 | 152 | #define ECR_RP BIT(15) |
20779943 TCB |
153 | #define ECR_REC_MASK GENMASK(14, 8) |
154 | #define ECR_TEC_MASK GENMASK(7, 0) | |
e0d1f481 | 155 | |
50fe7547 | 156 | /* Protocol Status Register (PSR) */ |
e0d1f481 DA |
157 | #define PSR_BO BIT(7) |
158 | #define PSR_EW BIT(6) | |
159 | #define PSR_EP BIT(5) | |
20779943 | 160 | #define PSR_LEC_MASK GENMASK(2, 0) |
e0d1f481 | 161 | |
50fe7547 | 162 | /* Interrupt Register (IR) */ |
e0d1f481 | 163 | #define IR_ALL_INT 0xffffffff |
5e1bd15a MH |
164 | |
165 | /* Renamed bits for versions > 3.1.x */ | |
166 | #define IR_ARA BIT(29) | |
167 | #define IR_PED BIT(28) | |
168 | #define IR_PEA BIT(27) | |
169 | ||
170 | /* Bits for version 3.0.x */ | |
e0d1f481 DA |
171 | #define IR_STE BIT(31) |
172 | #define IR_FOE BIT(30) | |
173 | #define IR_ACKE BIT(29) | |
174 | #define IR_BE BIT(28) | |
175 | #define IR_CRCE BIT(27) | |
176 | #define IR_WDI BIT(26) | |
177 | #define IR_BO BIT(25) | |
178 | #define IR_EW BIT(24) | |
179 | #define IR_EP BIT(23) | |
180 | #define IR_ELO BIT(22) | |
181 | #define IR_BEU BIT(21) | |
182 | #define IR_BEC BIT(20) | |
183 | #define IR_DRX BIT(19) | |
184 | #define IR_TOO BIT(18) | |
185 | #define IR_MRAF BIT(17) | |
186 | #define IR_TSW BIT(16) | |
187 | #define IR_TEFL BIT(15) | |
188 | #define IR_TEFF BIT(14) | |
189 | #define IR_TEFW BIT(13) | |
190 | #define IR_TEFN BIT(12) | |
191 | #define IR_TFE BIT(11) | |
192 | #define IR_TCF BIT(10) | |
193 | #define IR_TC BIT(9) | |
194 | #define IR_HPM BIT(8) | |
195 | #define IR_RF1L BIT(7) | |
196 | #define IR_RF1F BIT(6) | |
197 | #define IR_RF1W BIT(5) | |
198 | #define IR_RF1N BIT(4) | |
199 | #define IR_RF0L BIT(3) | |
200 | #define IR_RF0F BIT(2) | |
201 | #define IR_RF0W BIT(1) | |
202 | #define IR_RF0N BIT(0) | |
203 | #define IR_ERR_STATE (IR_BO | IR_EW | IR_EP) | |
5e1bd15a MH |
204 | |
205 | /* Interrupts for version 3.0.x */ | |
206 | #define IR_ERR_LEC_30X (IR_STE | IR_FOE | IR_ACKE | IR_BE | IR_CRCE) | |
207 | #define IR_ERR_BUS_30X (IR_ERR_LEC_30X | IR_WDI | IR_ELO | IR_BEU | \ | |
208 | IR_BEC | IR_TOO | IR_MRAF | IR_TSW | IR_TEFL | \ | |
209 | IR_RF1L | IR_RF0L) | |
210 | #define IR_ERR_ALL_30X (IR_ERR_STATE | IR_ERR_BUS_30X) | |
20779943 | 211 | |
5e1bd15a MH |
212 | /* Interrupts for version >= 3.1.x */ |
213 | #define IR_ERR_LEC_31X (IR_PED | IR_PEA) | |
214 | #define IR_ERR_BUS_31X (IR_ERR_LEC_31X | IR_WDI | IR_ELO | IR_BEU | \ | |
e0d1f481 DA |
215 | IR_BEC | IR_TOO | IR_MRAF | IR_TSW | IR_TEFL | \ |
216 | IR_RF1L | IR_RF0L) | |
5e1bd15a | 217 | #define IR_ERR_ALL_31X (IR_ERR_STATE | IR_ERR_BUS_31X) |
e0d1f481 DA |
218 | |
219 | /* Interrupt Line Select (ILS) */ | |
220 | #define ILS_ALL_INT0 0x0 | |
221 | #define ILS_ALL_INT1 0xFFFFFFFF | |
222 | ||
223 | /* Interrupt Line Enable (ILE) */ | |
e0d1f481 | 224 | #define ILE_EINT1 BIT(1) |
5e1bd15a | 225 | #define ILE_EINT0 BIT(0) |
e0d1f481 DA |
226 | |
227 | /* Rx FIFO 0/1 Configuration (RXF0C/RXF1C) */ | |
20779943 TCB |
228 | #define RXFC_FWM_MASK GENMASK(30, 24) |
229 | #define RXFC_FS_MASK GENMASK(22, 16) | |
e0d1f481 DA |
230 | |
231 | /* Rx FIFO 0/1 Status (RXF0S/RXF1S) */ | |
232 | #define RXFS_RFL BIT(25) | |
233 | #define RXFS_FF BIT(24) | |
20779943 TCB |
234 | #define RXFS_FPI_MASK GENMASK(21, 16) |
235 | #define RXFS_FGI_MASK GENMASK(13, 8) | |
236 | #define RXFS_FFL_MASK GENMASK(6, 0) | |
e0d1f481 DA |
237 | |
238 | /* Rx Buffer / FIFO Element Size Configuration (RXESC) */ | |
0f315716 TCB |
239 | #define RXESC_RBDS_MASK GENMASK(10, 8) |
240 | #define RXESC_F1DS_MASK GENMASK(6, 4) | |
241 | #define RXESC_F0DS_MASK GENMASK(2, 0) | |
242 | #define RXESC_64B 0x7 | |
e0d1f481 | 243 | |
20779943 TCB |
244 | /* Tx Buffer Configuration (TXBC) */ |
245 | #define TXBC_TFQS_MASK GENMASK(29, 24) | |
246 | #define TXBC_NDTB_MASK GENMASK(21, 16) | |
5e1bd15a MH |
247 | |
248 | /* Tx FIFO/Queue Status (TXFQS) */ | |
249 | #define TXFQS_TFQF BIT(21) | |
20779943 TCB |
250 | #define TXFQS_TFQPI_MASK GENMASK(20, 16) |
251 | #define TXFQS_TFGI_MASK GENMASK(12, 8) | |
252 | #define TXFQS_TFFL_MASK GENMASK(5, 0) | |
e0d1f481 | 253 | |
50fe7547 | 254 | /* Tx Buffer Element Size Configuration (TXESC) */ |
0f315716 TCB |
255 | #define TXESC_TBDS_MASK GENMASK(2, 0) |
256 | #define TXESC_TBDS_64B 0x7 | |
e0d1f481 | 257 | |
5e1bd15a | 258 | /* Tx Event FIFO Configuration (TXEFC) */ |
20779943 | 259 | #define TXEFC_EFS_MASK GENMASK(21, 16) |
5e1bd15a MH |
260 | |
261 | /* Tx Event FIFO Status (TXEFS) */ | |
262 | #define TXEFS_TEFL BIT(25) | |
263 | #define TXEFS_EFF BIT(24) | |
20779943 TCB |
264 | #define TXEFS_EFGI_MASK GENMASK(12, 8) |
265 | #define TXEFS_EFFL_MASK GENMASK(5, 0) | |
5e1bd15a MH |
266 | |
267 | /* Tx Event FIFO Acknowledge (TXEFA) */ | |
20779943 | 268 | #define TXEFA_EFAI_MASK GENMASK(4, 0) |
e0d1f481 DA |
269 | |
270 | /* Message RAM Configuration (in bytes) */ | |
271 | #define SIDF_ELEMENT_SIZE 4 | |
272 | #define XIDF_ELEMENT_SIZE 8 | |
80646733 DA |
273 | #define RXF0_ELEMENT_SIZE 72 |
274 | #define RXF1_ELEMENT_SIZE 72 | |
5e1bd15a | 275 | #define RXB_ELEMENT_SIZE 72 |
e0d1f481 | 276 | #define TXE_ELEMENT_SIZE 8 |
80646733 | 277 | #define TXB_ELEMENT_SIZE 72 |
e0d1f481 DA |
278 | |
279 | /* Message RAM Elements */ | |
280 | #define M_CAN_FIFO_ID 0x0 | |
281 | #define M_CAN_FIFO_DLC 0x4 | |
282 | #define M_CAN_FIFO_DATA(n) (0x8 + ((n) << 2)) | |
283 | ||
284 | /* Rx Buffer Element */ | |
80646733 | 285 | /* R0 */ |
e0d1f481 DA |
286 | #define RX_BUF_ESI BIT(31) |
287 | #define RX_BUF_XTD BIT(30) | |
288 | #define RX_BUF_RTR BIT(29) | |
80646733 DA |
289 | /* R1 */ |
290 | #define RX_BUF_ANMF BIT(31) | |
5e1bd15a | 291 | #define RX_BUF_FDF BIT(21) |
80646733 | 292 | #define RX_BUF_BRS BIT(20) |
17447f08 | 293 | #define RX_BUF_RXTS_MASK GENMASK(15, 0) |
e0d1f481 DA |
294 | |
295 | /* Tx Buffer Element */ | |
5e1bd15a MH |
296 | /* T0 */ |
297 | #define TX_BUF_ESI BIT(31) | |
e0d1f481 DA |
298 | #define TX_BUF_XTD BIT(30) |
299 | #define TX_BUF_RTR BIT(29) | |
5e1bd15a MH |
300 | /* T1 */ |
301 | #define TX_BUF_EFC BIT(23) | |
302 | #define TX_BUF_FDF BIT(21) | |
303 | #define TX_BUF_BRS BIT(20) | |
20779943 TCB |
304 | #define TX_BUF_MM_MASK GENMASK(31, 24) |
305 | #define TX_BUF_DLC_MASK GENMASK(19, 16) | |
e0d1f481 | 306 | |
10c1c397 MH |
307 | /* Tx event FIFO Element */ |
308 | /* E1 */ | |
20779943 | 309 | #define TX_EVENT_MM_MASK GENMASK(31, 24) |
17447f08 | 310 | #define TX_EVENT_TXTS_MASK GENMASK(15, 0) |
10c1c397 | 311 | |
441ac340 | 312 | static inline u32 m_can_read(struct m_can_classdev *cdev, enum m_can_reg reg) |
f524f829 | 313 | { |
441ac340 | 314 | return cdev->ops->read_reg(cdev, reg); |
f524f829 | 315 | } |
e0d1f481 | 316 | |
441ac340 | 317 | static inline void m_can_write(struct m_can_classdev *cdev, enum m_can_reg reg, |
f524f829 | 318 | u32 val) |
e0d1f481 | 319 | { |
441ac340 | 320 | cdev->ops->write_reg(cdev, reg, val); |
e0d1f481 DA |
321 | } |
322 | ||
441ac340 | 323 | static u32 m_can_fifo_read(struct m_can_classdev *cdev, |
f524f829 | 324 | u32 fgi, unsigned int offset) |
e0d1f481 | 325 | { |
441ac340 | 326 | u32 addr_offset = cdev->mcfg[MRAM_RXF0].off + fgi * RXF0_ELEMENT_SIZE + |
709efa6f | 327 | offset; |
f524f829 | 328 | |
441ac340 | 329 | return cdev->ops->read_fifo(cdev, addr_offset); |
e0d1f481 DA |
330 | } |
331 | ||
441ac340 | 332 | static void m_can_fifo_write(struct m_can_classdev *cdev, |
f524f829 | 333 | u32 fpi, unsigned int offset, u32 val) |
e0d1f481 | 334 | { |
441ac340 | 335 | u32 addr_offset = cdev->mcfg[MRAM_TXB].off + fpi * TXB_ELEMENT_SIZE + |
709efa6f | 336 | offset; |
f524f829 | 337 | |
441ac340 | 338 | cdev->ops->write_fifo(cdev, addr_offset, val); |
e0d1f481 DA |
339 | } |
340 | ||
441ac340 | 341 | static inline void m_can_fifo_write_no_off(struct m_can_classdev *cdev, |
f524f829 | 342 | u32 fpi, u32 val) |
e0d1f481 | 343 | { |
441ac340 | 344 | cdev->ops->write_fifo(cdev, fpi, val); |
e0d1f481 DA |
345 | } |
346 | ||
441ac340 | 347 | static u32 m_can_txe_fifo_read(struct m_can_classdev *cdev, u32 fgi, u32 offset) |
f524f829 | 348 | { |
441ac340 | 349 | u32 addr_offset = cdev->mcfg[MRAM_TXE].off + fgi * TXE_ELEMENT_SIZE + |
709efa6f | 350 | offset; |
f524f829 | 351 | |
441ac340 | 352 | return cdev->ops->read_fifo(cdev, addr_offset); |
428479e4 MH |
353 | } |
354 | ||
441ac340 | 355 | static inline bool m_can_tx_fifo_full(struct m_can_classdev *cdev) |
428479e4 | 356 | { |
709efa6f | 357 | return !!(m_can_read(cdev, M_CAN_TXFQS) & TXFQS_TFQF); |
428479e4 MH |
358 | } |
359 | ||
78e19a29 | 360 | static void m_can_config_endisable(struct m_can_classdev *cdev, bool enable) |
e0d1f481 | 361 | { |
441ac340 | 362 | u32 cccr = m_can_read(cdev, M_CAN_CCCR); |
e0d1f481 DA |
363 | u32 timeout = 10; |
364 | u32 val = 0; | |
365 | ||
f524f829 DM |
366 | /* Clear the Clock stop request if it was set */ |
367 | if (cccr & CCCR_CSR) | |
368 | cccr &= ~CCCR_CSR; | |
369 | ||
e0d1f481 DA |
370 | if (enable) { |
371 | /* enable m_can configuration */ | |
441ac340 | 372 | m_can_write(cdev, M_CAN_CCCR, cccr | CCCR_INIT); |
7660f633 | 373 | udelay(5); |
e0d1f481 | 374 | /* CCCR.CCE can only be set/reset while CCCR.INIT = '1' */ |
441ac340 | 375 | m_can_write(cdev, M_CAN_CCCR, cccr | CCCR_INIT | CCCR_CCE); |
e0d1f481 | 376 | } else { |
441ac340 | 377 | m_can_write(cdev, M_CAN_CCCR, cccr & ~(CCCR_INIT | CCCR_CCE)); |
e0d1f481 DA |
378 | } |
379 | ||
380 | /* there's a delay for module initialization */ | |
381 | if (enable) | |
382 | val = CCCR_INIT | CCCR_CCE; | |
383 | ||
441ac340 | 384 | while ((m_can_read(cdev, M_CAN_CCCR) & (CCCR_INIT | CCCR_CCE)) != val) { |
e0d1f481 | 385 | if (timeout == 0) { |
441ac340 | 386 | netdev_warn(cdev->net, "Failed to init module\n"); |
e0d1f481 DA |
387 | return; |
388 | } | |
389 | timeout--; | |
390 | udelay(1); | |
391 | } | |
392 | } | |
393 | ||
441ac340 | 394 | static inline void m_can_enable_all_interrupts(struct m_can_classdev *cdev) |
e0d1f481 | 395 | { |
52973810 | 396 | /* Only interrupt line 0 is used in this driver */ |
441ac340 | 397 | m_can_write(cdev, M_CAN_ILE, ILE_EINT0); |
e0d1f481 DA |
398 | } |
399 | ||
441ac340 | 400 | static inline void m_can_disable_all_interrupts(struct m_can_classdev *cdev) |
e0d1f481 | 401 | { |
441ac340 | 402 | m_can_write(cdev, M_CAN_ILE, 0x0); |
e0d1f481 DA |
403 | } |
404 | ||
17447f08 TCB |
405 | /* Retrieve internal timestamp counter from TSCV.TSC, and shift it to 32-bit |
406 | * width. | |
407 | */ | |
408 | static u32 m_can_get_timestamp(struct m_can_classdev *cdev) | |
409 | { | |
410 | u32 tscv; | |
411 | u32 tsc; | |
412 | ||
413 | tscv = m_can_read(cdev, M_CAN_TSCV); | |
414 | tsc = FIELD_GET(TSCV_TSC_MASK, tscv); | |
415 | ||
416 | return (tsc << 16); | |
417 | } | |
418 | ||
f524f829 DM |
419 | static void m_can_clean(struct net_device *net) |
420 | { | |
441ac340 | 421 | struct m_can_classdev *cdev = netdev_priv(net); |
f524f829 | 422 | |
441ac340 | 423 | if (cdev->tx_skb) { |
f524f829 DM |
424 | int putidx = 0; |
425 | ||
426 | net->stats.tx_errors++; | |
441ac340 | 427 | if (cdev->version > 30) |
20779943 TCB |
428 | putidx = FIELD_GET(TXFQS_TFQPI_MASK, |
429 | m_can_read(cdev, M_CAN_TXFQS)); | |
f524f829 | 430 | |
f318482a | 431 | can_free_echo_skb(cdev->net, putidx, NULL); |
441ac340 | 432 | cdev->tx_skb = NULL; |
f524f829 DM |
433 | } |
434 | } | |
435 | ||
1be37d3b TCB |
436 | /* For peripherals, pass skb to rx-offload, which will push skb from |
437 | * napi. For non-peripherals, RX is done in napi already, so push | |
438 | * directly. timestamp is used to ensure good skb ordering in | |
439 | * rx-offload and is ignored for non-peripherals. | |
440 | */ | |
441 | static void m_can_receive_skb(struct m_can_classdev *cdev, | |
442 | struct sk_buff *skb, | |
443 | u32 timestamp) | |
444 | { | |
644022b1 MKB |
445 | if (cdev->is_peripheral) { |
446 | struct net_device_stats *stats = &cdev->net->stats; | |
447 | int err; | |
448 | ||
449 | err = can_rx_offload_queue_sorted(&cdev->offload, skb, | |
450 | timestamp); | |
451 | if (err) | |
452 | stats->rx_fifo_errors++; | |
453 | } else { | |
1be37d3b | 454 | netif_receive_skb(skb); |
644022b1 | 455 | } |
1be37d3b TCB |
456 | } |
457 | ||
80646733 | 458 | static void m_can_read_fifo(struct net_device *dev, u32 rxfs) |
e0d1f481 | 459 | { |
80646733 | 460 | struct net_device_stats *stats = &dev->stats; |
441ac340 | 461 | struct m_can_classdev *cdev = netdev_priv(dev); |
80646733 DA |
462 | struct canfd_frame *cf; |
463 | struct sk_buff *skb; | |
921f1681 | 464 | u32 id, fgi, dlc; |
1be37d3b | 465 | u32 timestamp = 0; |
80646733 | 466 | int i; |
e0d1f481 DA |
467 | |
468 | /* calculate the fifo get index for where to read data */ | |
20779943 | 469 | fgi = FIELD_GET(RXFS_FGI_MASK, rxfs); |
441ac340 | 470 | dlc = m_can_fifo_read(cdev, fgi, M_CAN_FIFO_DLC); |
5e1bd15a | 471 | if (dlc & RX_BUF_FDF) |
80646733 DA |
472 | skb = alloc_canfd_skb(dev, &cf); |
473 | else | |
474 | skb = alloc_can_skb(dev, (struct can_frame **)&cf); | |
475 | if (!skb) { | |
476 | stats->rx_dropped++; | |
477 | return; | |
478 | } | |
479 | ||
5e1bd15a | 480 | if (dlc & RX_BUF_FDF) |
3ab4ce0d | 481 | cf->len = can_fd_dlc2len((dlc >> 16) & 0x0F); |
80646733 | 482 | else |
69d98969 | 483 | cf->len = can_cc_dlc2len((dlc >> 16) & 0x0F); |
80646733 | 484 | |
441ac340 | 485 | id = m_can_fifo_read(cdev, fgi, M_CAN_FIFO_ID); |
e0d1f481 DA |
486 | if (id & RX_BUF_XTD) |
487 | cf->can_id = (id & CAN_EFF_MASK) | CAN_EFF_FLAG; | |
488 | else | |
489 | cf->can_id = (id >> 18) & CAN_SFF_MASK; | |
490 | ||
80646733 DA |
491 | if (id & RX_BUF_ESI) { |
492 | cf->flags |= CANFD_ESI; | |
493 | netdev_dbg(dev, "ESI Error\n"); | |
494 | } | |
921f1681 | 495 | |
5e1bd15a | 496 | if (!(dlc & RX_BUF_FDF) && (id & RX_BUF_RTR)) { |
e0d1f481 DA |
497 | cf->can_id |= CAN_RTR_FLAG; |
498 | } else { | |
80646733 DA |
499 | if (dlc & RX_BUF_BRS) |
500 | cf->flags |= CANFD_BRS; | |
501 | ||
502 | for (i = 0; i < cf->len; i += 4) | |
503 | *(u32 *)(cf->data + i) = | |
441ac340 | 504 | m_can_fifo_read(cdev, fgi, |
80646733 | 505 | M_CAN_FIFO_DATA(i / 4)); |
e0d1f481 DA |
506 | } |
507 | ||
508 | /* acknowledge rx fifo 0 */ | |
441ac340 | 509 | m_can_write(cdev, M_CAN_RXF0A, fgi); |
80646733 DA |
510 | |
511 | stats->rx_packets++; | |
512 | stats->rx_bytes += cf->len; | |
513 | ||
1be37d3b TCB |
514 | timestamp = FIELD_GET(RX_BUF_RXTS_MASK, dlc); |
515 | ||
516 | m_can_receive_skb(cdev, skb, timestamp); | |
e0d1f481 DA |
517 | } |
518 | ||
519 | static int m_can_do_rx_poll(struct net_device *dev, int quota) | |
520 | { | |
441ac340 | 521 | struct m_can_classdev *cdev = netdev_priv(dev); |
e0d1f481 DA |
522 | u32 pkts = 0; |
523 | u32 rxfs; | |
524 | ||
441ac340 | 525 | rxfs = m_can_read(cdev, M_CAN_RXF0S); |
e0d1f481 DA |
526 | if (!(rxfs & RXFS_FFL_MASK)) { |
527 | netdev_dbg(dev, "no messages in fifo0\n"); | |
528 | return 0; | |
529 | } | |
530 | ||
531 | while ((rxfs & RXFS_FFL_MASK) && (quota > 0)) { | |
80646733 | 532 | m_can_read_fifo(dev, rxfs); |
e0d1f481 DA |
533 | |
534 | quota--; | |
535 | pkts++; | |
441ac340 | 536 | rxfs = m_can_read(cdev, M_CAN_RXF0S); |
e0d1f481 DA |
537 | } |
538 | ||
539 | if (pkts) | |
540 | can_led_event(dev, CAN_LED_EVENT_RX); | |
541 | ||
542 | return pkts; | |
543 | } | |
544 | ||
545 | static int m_can_handle_lost_msg(struct net_device *dev) | |
546 | { | |
1be37d3b | 547 | struct m_can_classdev *cdev = netdev_priv(dev); |
e0d1f481 DA |
548 | struct net_device_stats *stats = &dev->stats; |
549 | struct sk_buff *skb; | |
550 | struct can_frame *frame; | |
1be37d3b | 551 | u32 timestamp = 0; |
e0d1f481 DA |
552 | |
553 | netdev_err(dev, "msg lost in rxf0\n"); | |
554 | ||
555 | stats->rx_errors++; | |
556 | stats->rx_over_errors++; | |
557 | ||
558 | skb = alloc_can_err_skb(dev, &frame); | |
559 | if (unlikely(!skb)) | |
560 | return 0; | |
561 | ||
562 | frame->can_id |= CAN_ERR_CRTL; | |
563 | frame->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; | |
564 | ||
1be37d3b TCB |
565 | if (cdev->is_peripheral) |
566 | timestamp = m_can_get_timestamp(cdev); | |
567 | ||
568 | m_can_receive_skb(cdev, skb, timestamp); | |
e0d1f481 DA |
569 | |
570 | return 1; | |
571 | } | |
572 | ||
573 | static int m_can_handle_lec_err(struct net_device *dev, | |
574 | enum m_can_lec_type lec_type) | |
575 | { | |
441ac340 | 576 | struct m_can_classdev *cdev = netdev_priv(dev); |
e0d1f481 DA |
577 | struct net_device_stats *stats = &dev->stats; |
578 | struct can_frame *cf; | |
579 | struct sk_buff *skb; | |
1be37d3b | 580 | u32 timestamp = 0; |
e0d1f481 | 581 | |
441ac340 | 582 | cdev->can.can_stats.bus_error++; |
e0d1f481 DA |
583 | stats->rx_errors++; |
584 | ||
585 | /* propagate the error condition to the CAN stack */ | |
586 | skb = alloc_can_err_skb(dev, &cf); | |
587 | if (unlikely(!skb)) | |
588 | return 0; | |
589 | ||
590 | /* check for 'last error code' which tells us the | |
591 | * type of the last error to occur on the CAN bus | |
592 | */ | |
593 | cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; | |
e0d1f481 DA |
594 | |
595 | switch (lec_type) { | |
596 | case LEC_STUFF_ERROR: | |
597 | netdev_dbg(dev, "stuff error\n"); | |
598 | cf->data[2] |= CAN_ERR_PROT_STUFF; | |
599 | break; | |
600 | case LEC_FORM_ERROR: | |
601 | netdev_dbg(dev, "form error\n"); | |
602 | cf->data[2] |= CAN_ERR_PROT_FORM; | |
603 | break; | |
604 | case LEC_ACK_ERROR: | |
605 | netdev_dbg(dev, "ack error\n"); | |
ffd461f8 | 606 | cf->data[3] = CAN_ERR_PROT_LOC_ACK; |
e0d1f481 DA |
607 | break; |
608 | case LEC_BIT1_ERROR: | |
609 | netdev_dbg(dev, "bit1 error\n"); | |
610 | cf->data[2] |= CAN_ERR_PROT_BIT1; | |
611 | break; | |
612 | case LEC_BIT0_ERROR: | |
613 | netdev_dbg(dev, "bit0 error\n"); | |
614 | cf->data[2] |= CAN_ERR_PROT_BIT0; | |
615 | break; | |
616 | case LEC_CRC_ERROR: | |
617 | netdev_dbg(dev, "CRC error\n"); | |
ffd461f8 | 618 | cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ; |
e0d1f481 DA |
619 | break; |
620 | default: | |
621 | break; | |
622 | } | |
623 | ||
624 | stats->rx_packets++; | |
c7b74967 | 625 | stats->rx_bytes += cf->len; |
1be37d3b TCB |
626 | |
627 | if (cdev->is_peripheral) | |
628 | timestamp = m_can_get_timestamp(cdev); | |
629 | ||
630 | m_can_receive_skb(cdev, skb, timestamp); | |
e0d1f481 DA |
631 | |
632 | return 1; | |
633 | } | |
634 | ||
f6a99649 DA |
635 | static int __m_can_get_berr_counter(const struct net_device *dev, |
636 | struct can_berr_counter *bec) | |
637 | { | |
441ac340 | 638 | struct m_can_classdev *cdev = netdev_priv(dev); |
f6a99649 DA |
639 | unsigned int ecr; |
640 | ||
441ac340 | 641 | ecr = m_can_read(cdev, M_CAN_ECR); |
20779943 TCB |
642 | bec->rxerr = FIELD_GET(ECR_REC_MASK, ecr); |
643 | bec->txerr = FIELD_GET(ECR_TEC_MASK, ecr); | |
f6a99649 DA |
644 | |
645 | return 0; | |
646 | } | |
647 | ||
441ac340 | 648 | static int m_can_clk_start(struct m_can_classdev *cdev) |
e0d1f481 | 649 | { |
441ac340 | 650 | if (cdev->pm_clock_support == 0) |
f524f829 DM |
651 | return 0; |
652 | ||
b8d62555 | 653 | return pm_runtime_resume_and_get(cdev->dev); |
ef7b8aa8 | 654 | } |
e0d1f481 | 655 | |
441ac340 | 656 | static void m_can_clk_stop(struct m_can_classdev *cdev) |
ef7b8aa8 | 657 | { |
441ac340 DM |
658 | if (cdev->pm_clock_support) |
659 | pm_runtime_put_sync(cdev->dev); | |
ef7b8aa8 QS |
660 | } |
661 | ||
662 | static int m_can_get_berr_counter(const struct net_device *dev, | |
663 | struct can_berr_counter *bec) | |
664 | { | |
441ac340 | 665 | struct m_can_classdev *cdev = netdev_priv(dev); |
ef7b8aa8 QS |
666 | int err; |
667 | ||
441ac340 | 668 | err = m_can_clk_start(cdev); |
ef7b8aa8 QS |
669 | if (err) |
670 | return err; | |
671 | ||
672 | __m_can_get_berr_counter(dev, bec); | |
673 | ||
441ac340 | 674 | m_can_clk_stop(cdev); |
e0d1f481 DA |
675 | |
676 | return 0; | |
677 | } | |
678 | ||
679 | static int m_can_handle_state_change(struct net_device *dev, | |
680 | enum can_state new_state) | |
681 | { | |
441ac340 | 682 | struct m_can_classdev *cdev = netdev_priv(dev); |
e0d1f481 DA |
683 | struct net_device_stats *stats = &dev->stats; |
684 | struct can_frame *cf; | |
685 | struct sk_buff *skb; | |
686 | struct can_berr_counter bec; | |
687 | unsigned int ecr; | |
1be37d3b | 688 | u32 timestamp = 0; |
e0d1f481 DA |
689 | |
690 | switch (new_state) { | |
cd0d83ea | 691 | case CAN_STATE_ERROR_WARNING: |
e0d1f481 | 692 | /* error warning state */ |
441ac340 DM |
693 | cdev->can.can_stats.error_warning++; |
694 | cdev->can.state = CAN_STATE_ERROR_WARNING; | |
e0d1f481 DA |
695 | break; |
696 | case CAN_STATE_ERROR_PASSIVE: | |
697 | /* error passive state */ | |
441ac340 DM |
698 | cdev->can.can_stats.error_passive++; |
699 | cdev->can.state = CAN_STATE_ERROR_PASSIVE; | |
e0d1f481 DA |
700 | break; |
701 | case CAN_STATE_BUS_OFF: | |
702 | /* bus-off state */ | |
441ac340 DM |
703 | cdev->can.state = CAN_STATE_BUS_OFF; |
704 | m_can_disable_all_interrupts(cdev); | |
705 | cdev->can.can_stats.bus_off++; | |
e0d1f481 DA |
706 | can_bus_off(dev); |
707 | break; | |
708 | default: | |
709 | break; | |
710 | } | |
711 | ||
712 | /* propagate the error condition to the CAN stack */ | |
713 | skb = alloc_can_err_skb(dev, &cf); | |
714 | if (unlikely(!skb)) | |
715 | return 0; | |
716 | ||
f6a99649 | 717 | __m_can_get_berr_counter(dev, &bec); |
e0d1f481 DA |
718 | |
719 | switch (new_state) { | |
cd0d83ea | 720 | case CAN_STATE_ERROR_WARNING: |
e0d1f481 DA |
721 | /* error warning state */ |
722 | cf->can_id |= CAN_ERR_CRTL; | |
723 | cf->data[1] = (bec.txerr > bec.rxerr) ? | |
724 | CAN_ERR_CRTL_TX_WARNING : | |
725 | CAN_ERR_CRTL_RX_WARNING; | |
726 | cf->data[6] = bec.txerr; | |
727 | cf->data[7] = bec.rxerr; | |
728 | break; | |
729 | case CAN_STATE_ERROR_PASSIVE: | |
730 | /* error passive state */ | |
731 | cf->can_id |= CAN_ERR_CRTL; | |
441ac340 | 732 | ecr = m_can_read(cdev, M_CAN_ECR); |
e0d1f481 DA |
733 | if (ecr & ECR_RP) |
734 | cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE; | |
735 | if (bec.txerr > 127) | |
736 | cf->data[1] |= CAN_ERR_CRTL_TX_PASSIVE; | |
737 | cf->data[6] = bec.txerr; | |
738 | cf->data[7] = bec.rxerr; | |
739 | break; | |
740 | case CAN_STATE_BUS_OFF: | |
741 | /* bus-off state */ | |
742 | cf->can_id |= CAN_ERR_BUSOFF; | |
743 | break; | |
744 | default: | |
745 | break; | |
746 | } | |
747 | ||
748 | stats->rx_packets++; | |
c7b74967 | 749 | stats->rx_bytes += cf->len; |
1be37d3b TCB |
750 | |
751 | if (cdev->is_peripheral) | |
752 | timestamp = m_can_get_timestamp(cdev); | |
753 | ||
754 | m_can_receive_skb(cdev, skb, timestamp); | |
e0d1f481 DA |
755 | |
756 | return 1; | |
757 | } | |
758 | ||
759 | static int m_can_handle_state_errors(struct net_device *dev, u32 psr) | |
760 | { | |
441ac340 | 761 | struct m_can_classdev *cdev = netdev_priv(dev); |
e0d1f481 DA |
762 | int work_done = 0; |
763 | ||
441ac340 | 764 | if (psr & PSR_EW && cdev->can.state != CAN_STATE_ERROR_WARNING) { |
e0d1f481 DA |
765 | netdev_dbg(dev, "entered error warning state\n"); |
766 | work_done += m_can_handle_state_change(dev, | |
767 | CAN_STATE_ERROR_WARNING); | |
768 | } | |
769 | ||
441ac340 | 770 | if (psr & PSR_EP && cdev->can.state != CAN_STATE_ERROR_PASSIVE) { |
a93f5cae | 771 | netdev_dbg(dev, "entered error passive state\n"); |
e0d1f481 DA |
772 | work_done += m_can_handle_state_change(dev, |
773 | CAN_STATE_ERROR_PASSIVE); | |
774 | } | |
775 | ||
441ac340 | 776 | if (psr & PSR_BO && cdev->can.state != CAN_STATE_BUS_OFF) { |
a93f5cae | 777 | netdev_dbg(dev, "entered error bus off state\n"); |
e0d1f481 DA |
778 | work_done += m_can_handle_state_change(dev, |
779 | CAN_STATE_BUS_OFF); | |
780 | } | |
781 | ||
782 | return work_done; | |
783 | } | |
784 | ||
785 | static void m_can_handle_other_err(struct net_device *dev, u32 irqstatus) | |
786 | { | |
787 | if (irqstatus & IR_WDI) | |
788 | netdev_err(dev, "Message RAM Watchdog event due to missing READY\n"); | |
a93f5cae | 789 | if (irqstatus & IR_ELO) |
e0d1f481 DA |
790 | netdev_err(dev, "Error Logging Overflow\n"); |
791 | if (irqstatus & IR_BEU) | |
792 | netdev_err(dev, "Bit Error Uncorrected\n"); | |
793 | if (irqstatus & IR_BEC) | |
794 | netdev_err(dev, "Bit Error Corrected\n"); | |
795 | if (irqstatus & IR_TOO) | |
796 | netdev_err(dev, "Timeout reached\n"); | |
797 | if (irqstatus & IR_MRAF) | |
798 | netdev_err(dev, "Message RAM access failure occurred\n"); | |
799 | } | |
800 | ||
801 | static inline bool is_lec_err(u32 psr) | |
802 | { | |
803 | psr &= LEC_UNUSED; | |
804 | ||
805 | return psr && (psr != LEC_UNUSED); | |
806 | } | |
807 | ||
6b43a265 PS |
808 | static inline bool m_can_is_protocol_err(u32 irqstatus) |
809 | { | |
810 | return irqstatus & IR_ERR_LEC_31X; | |
811 | } | |
812 | ||
813 | static int m_can_handle_protocol_error(struct net_device *dev, u32 irqstatus) | |
814 | { | |
815 | struct net_device_stats *stats = &dev->stats; | |
816 | struct m_can_classdev *cdev = netdev_priv(dev); | |
817 | struct can_frame *cf; | |
818 | struct sk_buff *skb; | |
1be37d3b | 819 | u32 timestamp = 0; |
6b43a265 PS |
820 | |
821 | /* propagate the error condition to the CAN stack */ | |
822 | skb = alloc_can_err_skb(dev, &cf); | |
823 | ||
824 | /* update tx error stats since there is protocol error */ | |
825 | stats->tx_errors++; | |
826 | ||
827 | /* update arbitration lost status */ | |
828 | if (cdev->version >= 31 && (irqstatus & IR_PEA)) { | |
829 | netdev_dbg(dev, "Protocol error in Arbitration fail\n"); | |
830 | cdev->can.can_stats.arbitration_lost++; | |
831 | if (skb) { | |
832 | cf->can_id |= CAN_ERR_LOSTARB; | |
833 | cf->data[0] |= CAN_ERR_LOSTARB_UNSPEC; | |
834 | } | |
835 | } | |
836 | ||
837 | if (unlikely(!skb)) { | |
838 | netdev_dbg(dev, "allocation of skb failed\n"); | |
839 | return 0; | |
840 | } | |
1be37d3b TCB |
841 | |
842 | if (cdev->is_peripheral) | |
843 | timestamp = m_can_get_timestamp(cdev); | |
844 | ||
845 | m_can_receive_skb(cdev, skb, timestamp); | |
6b43a265 PS |
846 | |
847 | return 1; | |
848 | } | |
849 | ||
e0d1f481 DA |
850 | static int m_can_handle_bus_errors(struct net_device *dev, u32 irqstatus, |
851 | u32 psr) | |
852 | { | |
441ac340 | 853 | struct m_can_classdev *cdev = netdev_priv(dev); |
e0d1f481 DA |
854 | int work_done = 0; |
855 | ||
856 | if (irqstatus & IR_RF0L) | |
857 | work_done += m_can_handle_lost_msg(dev); | |
858 | ||
859 | /* handle lec errors on the bus */ | |
441ac340 | 860 | if ((cdev->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) && |
e0d1f481 DA |
861 | is_lec_err(psr)) |
862 | work_done += m_can_handle_lec_err(dev, psr & LEC_UNUSED); | |
863 | ||
6b43a265 PS |
864 | /* handle protocol errors in arbitration phase */ |
865 | if ((cdev->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) && | |
866 | m_can_is_protocol_err(irqstatus)) | |
867 | work_done += m_can_handle_protocol_error(dev, irqstatus); | |
868 | ||
e0d1f481 DA |
869 | /* other unproccessed error interrupts */ |
870 | m_can_handle_other_err(dev, irqstatus); | |
871 | ||
872 | return work_done; | |
873 | } | |
874 | ||
f524f829 | 875 | static int m_can_rx_handler(struct net_device *dev, int quota) |
e0d1f481 | 876 | { |
441ac340 | 877 | struct m_can_classdev *cdev = netdev_priv(dev); |
e0d1f481 DA |
878 | int work_done = 0; |
879 | u32 irqstatus, psr; | |
880 | ||
441ac340 | 881 | irqstatus = cdev->irqstatus | m_can_read(cdev, M_CAN_IR); |
e0d1f481 DA |
882 | if (!irqstatus) |
883 | goto end; | |
884 | ||
3e82f2f3 EH |
885 | /* Errata workaround for issue "Needless activation of MRAF irq" |
886 | * During frame reception while the MCAN is in Error Passive state | |
887 | * and the Receive Error Counter has the value MCAN_ECR.REC = 127, | |
888 | * it may happen that MCAN_IR.MRAF is set although there was no | |
889 | * Message RAM access failure. | |
890 | * If MCAN_IR.MRAF is enabled, an interrupt to the Host CPU is generated | |
891 | * The Message RAM Access Failure interrupt routine needs to check | |
892 | * whether MCAN_ECR.RP = ’1’ and MCAN_ECR.REC = 127. | |
893 | * In this case, reset MCAN_IR.MRAF. No further action is required. | |
894 | */ | |
441ac340 DM |
895 | if (cdev->version <= 31 && irqstatus & IR_MRAF && |
896 | m_can_read(cdev, M_CAN_ECR) & ECR_RP) { | |
3e82f2f3 EH |
897 | struct can_berr_counter bec; |
898 | ||
899 | __m_can_get_berr_counter(dev, &bec); | |
900 | if (bec.rxerr == 127) { | |
441ac340 | 901 | m_can_write(cdev, M_CAN_IR, IR_MRAF); |
3e82f2f3 EH |
902 | irqstatus &= ~IR_MRAF; |
903 | } | |
904 | } | |
905 | ||
441ac340 DM |
906 | psr = m_can_read(cdev, M_CAN_PSR); |
907 | ||
e0d1f481 DA |
908 | if (irqstatus & IR_ERR_STATE) |
909 | work_done += m_can_handle_state_errors(dev, psr); | |
910 | ||
5e1bd15a | 911 | if (irqstatus & IR_ERR_BUS_30X) |
e0d1f481 DA |
912 | work_done += m_can_handle_bus_errors(dev, irqstatus, psr); |
913 | ||
914 | if (irqstatus & IR_RF0N) | |
915 | work_done += m_can_do_rx_poll(dev, (quota - work_done)); | |
f524f829 DM |
916 | end: |
917 | return work_done; | |
918 | } | |
e0d1f481 | 919 | |
f524f829 DM |
920 | static int m_can_rx_peripheral(struct net_device *dev) |
921 | { | |
441ac340 | 922 | struct m_can_classdev *cdev = netdev_priv(dev); |
f524f829 | 923 | |
e98d9ee6 | 924 | m_can_rx_handler(dev, M_CAN_NAPI_WEIGHT); |
f524f829 | 925 | |
441ac340 | 926 | m_can_enable_all_interrupts(cdev); |
f524f829 DM |
927 | |
928 | return 0; | |
929 | } | |
930 | ||
931 | static int m_can_poll(struct napi_struct *napi, int quota) | |
932 | { | |
933 | struct net_device *dev = napi->dev; | |
441ac340 | 934 | struct m_can_classdev *cdev = netdev_priv(dev); |
f524f829 DM |
935 | int work_done; |
936 | ||
937 | work_done = m_can_rx_handler(dev, quota); | |
e0d1f481 | 938 | if (work_done < quota) { |
6ad20165 | 939 | napi_complete_done(napi, work_done); |
441ac340 | 940 | m_can_enable_all_interrupts(cdev); |
e0d1f481 DA |
941 | } |
942 | ||
e0d1f481 DA |
943 | return work_done; |
944 | } | |
945 | ||
1be37d3b TCB |
946 | /* Echo tx skb and update net stats. Peripherals use rx-offload for |
947 | * echo. timestamp is used for peripherals to ensure correct ordering | |
948 | * by rx-offload, and is ignored for non-peripherals. | |
949 | */ | |
950 | static void m_can_tx_update_stats(struct m_can_classdev *cdev, | |
951 | unsigned int msg_mark, | |
952 | u32 timestamp) | |
953 | { | |
954 | struct net_device *dev = cdev->net; | |
955 | struct net_device_stats *stats = &dev->stats; | |
956 | ||
957 | if (cdev->is_peripheral) | |
958 | stats->tx_bytes += | |
959 | can_rx_offload_get_echo_skb(&cdev->offload, | |
960 | msg_mark, | |
961 | timestamp, | |
962 | NULL); | |
963 | else | |
964 | stats->tx_bytes += can_get_echo_skb(dev, msg_mark, NULL); | |
965 | ||
966 | stats->tx_packets++; | |
967 | } | |
968 | ||
10c1c397 MH |
969 | static void m_can_echo_tx_event(struct net_device *dev) |
970 | { | |
971 | u32 txe_count = 0; | |
972 | u32 m_can_txefs; | |
973 | u32 fgi = 0; | |
974 | int i = 0; | |
975 | unsigned int msg_mark; | |
976 | ||
441ac340 | 977 | struct m_can_classdev *cdev = netdev_priv(dev); |
10c1c397 MH |
978 | |
979 | /* read tx event fifo status */ | |
441ac340 | 980 | m_can_txefs = m_can_read(cdev, M_CAN_TXEFS); |
10c1c397 MH |
981 | |
982 | /* Get Tx Event fifo element count */ | |
20779943 | 983 | txe_count = FIELD_GET(TXEFS_EFFL_MASK, m_can_txefs); |
10c1c397 MH |
984 | |
985 | /* Get and process all sent elements */ | |
986 | for (i = 0; i < txe_count; i++) { | |
1be37d3b TCB |
987 | u32 txe, timestamp = 0; |
988 | ||
10c1c397 | 989 | /* retrieve get index */ |
20779943 | 990 | fgi = FIELD_GET(TXEFS_EFGI_MASK, m_can_read(cdev, M_CAN_TXEFS)); |
10c1c397 | 991 | |
1be37d3b TCB |
992 | /* get message marker, timestamp */ |
993 | txe = m_can_txe_fifo_read(cdev, fgi, 4); | |
20779943 | 994 | msg_mark = FIELD_GET(TX_EVENT_MM_MASK, txe); |
1be37d3b | 995 | timestamp = FIELD_GET(TX_EVENT_TXTS_MASK, txe); |
10c1c397 MH |
996 | |
997 | /* ack txe element */ | |
20779943 TCB |
998 | m_can_write(cdev, M_CAN_TXEFA, FIELD_PREP(TXEFA_EFAI_MASK, |
999 | fgi)); | |
10c1c397 MH |
1000 | |
1001 | /* update stats */ | |
1be37d3b | 1002 | m_can_tx_update_stats(cdev, msg_mark, timestamp); |
10c1c397 MH |
1003 | } |
1004 | } | |
1005 | ||
e0d1f481 DA |
1006 | static irqreturn_t m_can_isr(int irq, void *dev_id) |
1007 | { | |
1008 | struct net_device *dev = (struct net_device *)dev_id; | |
441ac340 | 1009 | struct m_can_classdev *cdev = netdev_priv(dev); |
e0d1f481 DA |
1010 | u32 ir; |
1011 | ||
a1f63446 JN |
1012 | if (pm_runtime_suspended(cdev->dev)) |
1013 | return IRQ_NONE; | |
441ac340 | 1014 | ir = m_can_read(cdev, M_CAN_IR); |
e0d1f481 DA |
1015 | if (!ir) |
1016 | return IRQ_NONE; | |
1017 | ||
1018 | /* ACK all irqs */ | |
1019 | if (ir & IR_ALL_INT) | |
441ac340 | 1020 | m_can_write(cdev, M_CAN_IR, ir); |
e0d1f481 | 1021 | |
441ac340 DM |
1022 | if (cdev->ops->clear_interrupts) |
1023 | cdev->ops->clear_interrupts(cdev); | |
f524f829 | 1024 | |
e0d1f481 DA |
1025 | /* schedule NAPI in case of |
1026 | * - rx IRQ | |
1027 | * - state change IRQ | |
1028 | * - bus error IRQ and bus error reporting | |
1029 | */ | |
5e1bd15a | 1030 | if ((ir & IR_RF0N) || (ir & IR_ERR_ALL_30X)) { |
441ac340 DM |
1031 | cdev->irqstatus = ir; |
1032 | m_can_disable_all_interrupts(cdev); | |
1033 | if (!cdev->is_peripheral) | |
1034 | napi_schedule(&cdev->napi); | |
f524f829 DM |
1035 | else |
1036 | m_can_rx_peripheral(dev); | |
e0d1f481 DA |
1037 | } |
1038 | ||
441ac340 | 1039 | if (cdev->version == 30) { |
10c1c397 MH |
1040 | if (ir & IR_TC) { |
1041 | /* Transmission Complete Interrupt*/ | |
1be37d3b TCB |
1042 | u32 timestamp = 0; |
1043 | ||
1044 | if (cdev->is_peripheral) | |
1045 | timestamp = m_can_get_timestamp(cdev); | |
1046 | m_can_tx_update_stats(cdev, 0, timestamp); | |
1047 | ||
10c1c397 MH |
1048 | can_led_event(dev, CAN_LED_EVENT_TX); |
1049 | netif_wake_queue(dev); | |
1050 | } | |
1051 | } else { | |
1052 | if (ir & IR_TEFN) { | |
1053 | /* New TX FIFO Element arrived */ | |
1054 | m_can_echo_tx_event(dev); | |
1055 | can_led_event(dev, CAN_LED_EVENT_TX); | |
1056 | if (netif_queue_stopped(dev) && | |
441ac340 | 1057 | !m_can_tx_fifo_full(cdev)) |
10c1c397 MH |
1058 | netif_wake_queue(dev); |
1059 | } | |
e0d1f481 DA |
1060 | } |
1061 | ||
c757096e | 1062 | if (cdev->is_peripheral) |
30bfec4f | 1063 | can_rx_offload_threaded_irq_finish(&cdev->offload); |
c757096e | 1064 | |
e0d1f481 DA |
1065 | return IRQ_HANDLED; |
1066 | } | |
1067 | ||
b03cfc5b | 1068 | static const struct can_bittiming_const m_can_bittiming_const_30X = { |
e0d1f481 DA |
1069 | .name = KBUILD_MODNAME, |
1070 | .tseg1_min = 2, /* Time segment 1 = prop_seg + phase_seg1 */ | |
1071 | .tseg1_max = 64, | |
1072 | .tseg2_min = 1, /* Time segment 2 = phase_seg2 */ | |
1073 | .tseg2_max = 16, | |
1074 | .sjw_max = 16, | |
1075 | .brp_min = 1, | |
1076 | .brp_max = 1024, | |
1077 | .brp_inc = 1, | |
1078 | }; | |
1079 | ||
b03cfc5b | 1080 | static const struct can_bittiming_const m_can_data_bittiming_const_30X = { |
80646733 DA |
1081 | .name = KBUILD_MODNAME, |
1082 | .tseg1_min = 2, /* Time segment 1 = prop_seg + phase_seg1 */ | |
1083 | .tseg1_max = 16, | |
1084 | .tseg2_min = 1, /* Time segment 2 = phase_seg2 */ | |
1085 | .tseg2_max = 8, | |
1086 | .sjw_max = 4, | |
1087 | .brp_min = 1, | |
1088 | .brp_max = 32, | |
1089 | .brp_inc = 1, | |
1090 | }; | |
1091 | ||
b03cfc5b MH |
1092 | static const struct can_bittiming_const m_can_bittiming_const_31X = { |
1093 | .name = KBUILD_MODNAME, | |
1094 | .tseg1_min = 2, /* Time segment 1 = prop_seg + phase_seg1 */ | |
1095 | .tseg1_max = 256, | |
e3409e41 | 1096 | .tseg2_min = 2, /* Time segment 2 = phase_seg2 */ |
b03cfc5b MH |
1097 | .tseg2_max = 128, |
1098 | .sjw_max = 128, | |
1099 | .brp_min = 1, | |
1100 | .brp_max = 512, | |
1101 | .brp_inc = 1, | |
1102 | }; | |
1103 | ||
1104 | static const struct can_bittiming_const m_can_data_bittiming_const_31X = { | |
1105 | .name = KBUILD_MODNAME, | |
1106 | .tseg1_min = 1, /* Time segment 1 = prop_seg + phase_seg1 */ | |
1107 | .tseg1_max = 32, | |
1108 | .tseg2_min = 1, /* Time segment 2 = phase_seg2 */ | |
1109 | .tseg2_max = 16, | |
1110 | .sjw_max = 16, | |
1111 | .brp_min = 1, | |
1112 | .brp_max = 32, | |
1113 | .brp_inc = 1, | |
1114 | }; | |
1115 | ||
e0d1f481 DA |
1116 | static int m_can_set_bittiming(struct net_device *dev) |
1117 | { | |
441ac340 DM |
1118 | struct m_can_classdev *cdev = netdev_priv(dev); |
1119 | const struct can_bittiming *bt = &cdev->can.bittiming; | |
1120 | const struct can_bittiming *dbt = &cdev->can.data_bittiming; | |
e0d1f481 DA |
1121 | u16 brp, sjw, tseg1, tseg2; |
1122 | u32 reg_btp; | |
1123 | ||
1124 | brp = bt->brp - 1; | |
1125 | sjw = bt->sjw - 1; | |
1126 | tseg1 = bt->prop_seg + bt->phase_seg1 - 1; | |
1127 | tseg2 = bt->phase_seg2 - 1; | |
20779943 TCB |
1128 | reg_btp = FIELD_PREP(NBTP_NBRP_MASK, brp) | |
1129 | FIELD_PREP(NBTP_NSJW_MASK, sjw) | | |
1130 | FIELD_PREP(NBTP_NTSEG1_MASK, tseg1) | | |
1131 | FIELD_PREP(NBTP_NTSEG2_MASK, tseg2); | |
441ac340 | 1132 | m_can_write(cdev, M_CAN_NBTP, reg_btp); |
80646733 | 1133 | |
441ac340 | 1134 | if (cdev->can.ctrlmode & CAN_CTRLMODE_FD) { |
e759c626 | 1135 | reg_btp = 0; |
80646733 DA |
1136 | brp = dbt->brp - 1; |
1137 | sjw = dbt->sjw - 1; | |
1138 | tseg1 = dbt->prop_seg + dbt->phase_seg1 - 1; | |
1139 | tseg2 = dbt->phase_seg2 - 1; | |
e759c626 FCJ |
1140 | |
1141 | /* TDC is only needed for bitrates beyond 2.5 MBit/s. | |
1142 | * This is mentioned in the "Bit Time Requirements for CAN FD" | |
1143 | * paper presented at the International CAN Conference 2013 | |
1144 | */ | |
1145 | if (dbt->bitrate > 2500000) { | |
1146 | u32 tdco, ssp; | |
1147 | ||
1148 | /* Use the same value of secondary sampling point | |
1149 | * as the data sampling point | |
1150 | */ | |
1151 | ssp = dbt->sample_point; | |
1152 | ||
1153 | /* Equation based on Bosch's M_CAN User Manual's | |
1154 | * Transmitter Delay Compensation Section | |
1155 | */ | |
441ac340 | 1156 | tdco = (cdev->can.clock.freq / 1000) * |
709efa6f | 1157 | ssp / dbt->bitrate; |
e759c626 FCJ |
1158 | |
1159 | /* Max valid TDCO value is 127 */ | |
1160 | if (tdco > 127) { | |
1161 | netdev_warn(dev, "TDCO value of %u is beyond maximum. Using maximum possible value\n", | |
1162 | tdco); | |
1163 | tdco = 127; | |
1164 | } | |
1165 | ||
1166 | reg_btp |= DBTP_TDC; | |
441ac340 | 1167 | m_can_write(cdev, M_CAN_TDCR, |
20779943 | 1168 | FIELD_PREP(TDCR_TDCO_MASK, tdco)); |
e759c626 FCJ |
1169 | } |
1170 | ||
20779943 TCB |
1171 | reg_btp = FIELD_PREP(NBTP_NBRP_MASK, brp) | |
1172 | FIELD_PREP(NBTP_NSJW_MASK, sjw) | | |
1173 | FIELD_PREP(NBTP_NTSEG1_MASK, tseg1) | | |
1174 | FIELD_PREP(NBTP_NTSEG2_MASK, tseg2); | |
e759c626 | 1175 | |
441ac340 | 1176 | m_can_write(cdev, M_CAN_DBTP, reg_btp); |
80646733 | 1177 | } |
e0d1f481 DA |
1178 | |
1179 | return 0; | |
1180 | } | |
1181 | ||
1182 | /* Configure M_CAN chip: | |
1183 | * - set rx buffer/fifo element size | |
1184 | * - configure rx fifo | |
1185 | * - accept non-matching frame into fifo 0 | |
1186 | * - configure tx buffer | |
428479e4 | 1187 | * - >= v3.1.x: TX FIFO is used |
e0d1f481 DA |
1188 | * - configure mode |
1189 | * - setup bittiming | |
df06fd67 | 1190 | * - configure timestamp generation |
e0d1f481 DA |
1191 | */ |
1192 | static void m_can_chip_config(struct net_device *dev) | |
1193 | { | |
441ac340 | 1194 | struct m_can_classdev *cdev = netdev_priv(dev); |
e0d1f481 DA |
1195 | u32 cccr, test; |
1196 | ||
441ac340 | 1197 | m_can_config_endisable(cdev, true); |
e0d1f481 | 1198 | |
80646733 | 1199 | /* RX Buffer/FIFO Element Size 64 bytes data field */ |
0f315716 TCB |
1200 | m_can_write(cdev, M_CAN_RXESC, |
1201 | FIELD_PREP(RXESC_RBDS_MASK, RXESC_64B) | | |
1202 | FIELD_PREP(RXESC_F1DS_MASK, RXESC_64B) | | |
1203 | FIELD_PREP(RXESC_F0DS_MASK, RXESC_64B)); | |
e0d1f481 DA |
1204 | |
1205 | /* Accept Non-matching Frames Into FIFO 0 */ | |
441ac340 | 1206 | m_can_write(cdev, M_CAN_GFC, 0x0); |
e0d1f481 | 1207 | |
441ac340 | 1208 | if (cdev->version == 30) { |
428479e4 | 1209 | /* only support one Tx Buffer currently */ |
20779943 | 1210 | m_can_write(cdev, M_CAN_TXBC, FIELD_PREP(TXBC_NDTB_MASK, 1) | |
709efa6f | 1211 | cdev->mcfg[MRAM_TXB].off); |
428479e4 MH |
1212 | } else { |
1213 | /* TX FIFO is used for newer IP Core versions */ | |
441ac340 | 1214 | m_can_write(cdev, M_CAN_TXBC, |
20779943 TCB |
1215 | FIELD_PREP(TXBC_TFQS_MASK, |
1216 | cdev->mcfg[MRAM_TXB].num) | | |
1217 | cdev->mcfg[MRAM_TXB].off); | |
428479e4 | 1218 | } |
e0d1f481 | 1219 | |
80646733 | 1220 | /* support 64 bytes payload */ |
0f315716 TCB |
1221 | m_can_write(cdev, M_CAN_TXESC, |
1222 | FIELD_PREP(TXESC_TBDS_MASK, TXESC_TBDS_64B)); | |
e0d1f481 | 1223 | |
428479e4 | 1224 | /* TX Event FIFO */ |
441ac340 | 1225 | if (cdev->version == 30) { |
20779943 TCB |
1226 | m_can_write(cdev, M_CAN_TXEFC, |
1227 | FIELD_PREP(TXEFC_EFS_MASK, 1) | | |
709efa6f | 1228 | cdev->mcfg[MRAM_TXE].off); |
428479e4 MH |
1229 | } else { |
1230 | /* Full TX Event FIFO is used */ | |
441ac340 | 1231 | m_can_write(cdev, M_CAN_TXEFC, |
20779943 TCB |
1232 | FIELD_PREP(TXEFC_EFS_MASK, |
1233 | cdev->mcfg[MRAM_TXE].num) | | |
441ac340 | 1234 | cdev->mcfg[MRAM_TXE].off); |
428479e4 | 1235 | } |
e0d1f481 DA |
1236 | |
1237 | /* rx fifo configuration, blocking mode, fifo size 1 */ | |
441ac340 | 1238 | m_can_write(cdev, M_CAN_RXF0C, |
20779943 | 1239 | FIELD_PREP(RXFC_FS_MASK, cdev->mcfg[MRAM_RXF0].num) | |
709efa6f | 1240 | cdev->mcfg[MRAM_RXF0].off); |
e0d1f481 | 1241 | |
441ac340 | 1242 | m_can_write(cdev, M_CAN_RXF1C, |
20779943 | 1243 | FIELD_PREP(RXFC_FS_MASK, cdev->mcfg[MRAM_RXF1].num) | |
709efa6f | 1244 | cdev->mcfg[MRAM_RXF1].off); |
e0d1f481 | 1245 | |
441ac340 DM |
1246 | cccr = m_can_read(cdev, M_CAN_CCCR); |
1247 | test = m_can_read(cdev, M_CAN_TEST); | |
e0d1f481 | 1248 | test &= ~TEST_LBCK; |
441ac340 | 1249 | if (cdev->version == 30) { |
709efa6f | 1250 | /* Version 3.0.x */ |
e0d1f481 | 1251 | |
fb7d6a81 | 1252 | cccr &= ~(CCCR_TEST | CCCR_MON | CCCR_DAR | |
20779943 TCB |
1253 | FIELD_PREP(CCCR_CMR_MASK, FIELD_MAX(CCCR_CMR_MASK)) | |
1254 | FIELD_PREP(CCCR_CME_MASK, FIELD_MAX(CCCR_CME_MASK))); | |
b03cfc5b | 1255 | |
441ac340 | 1256 | if (cdev->can.ctrlmode & CAN_CTRLMODE_FD) |
20779943 | 1257 | cccr |= FIELD_PREP(CCCR_CME_MASK, CCCR_CME_CANFD_BRS); |
b03cfc5b MH |
1258 | |
1259 | } else { | |
709efa6f | 1260 | /* Version 3.1.x or 3.2.x */ |
393753b2 | 1261 | cccr &= ~(CCCR_TEST | CCCR_MON | CCCR_BRSE | CCCR_FDOE | |
fb7d6a81 | 1262 | CCCR_NISO | CCCR_DAR); |
b03cfc5b MH |
1263 | |
1264 | /* Only 3.2.x has NISO Bit implemented */ | |
441ac340 | 1265 | if (cdev->can.ctrlmode & CAN_CTRLMODE_FD_NON_ISO) |
b03cfc5b MH |
1266 | cccr |= CCCR_NISO; |
1267 | ||
441ac340 | 1268 | if (cdev->can.ctrlmode & CAN_CTRLMODE_FD) |
b03cfc5b MH |
1269 | cccr |= (CCCR_BRSE | CCCR_FDOE); |
1270 | } | |
e0d1f481 | 1271 | |
b03cfc5b | 1272 | /* Loopback Mode */ |
441ac340 | 1273 | if (cdev->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) { |
b03cfc5b | 1274 | cccr |= CCCR_TEST | CCCR_MON; |
e0d1f481 DA |
1275 | test |= TEST_LBCK; |
1276 | } | |
1277 | ||
b03cfc5b | 1278 | /* Enable Monitoring (all versions) */ |
441ac340 | 1279 | if (cdev->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) |
b03cfc5b | 1280 | cccr |= CCCR_MON; |
80646733 | 1281 | |
fb7d6a81 PS |
1282 | /* Disable Auto Retransmission (all versions) */ |
1283 | if (cdev->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT) | |
1284 | cccr |= CCCR_DAR; | |
1285 | ||
b03cfc5b | 1286 | /* Write config */ |
441ac340 DM |
1287 | m_can_write(cdev, M_CAN_CCCR, cccr); |
1288 | m_can_write(cdev, M_CAN_TEST, test); | |
e0d1f481 | 1289 | |
b03cfc5b | 1290 | /* Enable interrupts */ |
441ac340 DM |
1291 | m_can_write(cdev, M_CAN_IR, IR_ALL_INT); |
1292 | if (!(cdev->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)) | |
1293 | if (cdev->version == 30) | |
1294 | m_can_write(cdev, M_CAN_IE, IR_ALL_INT & | |
b03cfc5b MH |
1295 | ~(IR_ERR_LEC_30X)); |
1296 | else | |
441ac340 | 1297 | m_can_write(cdev, M_CAN_IE, IR_ALL_INT & |
b03cfc5b | 1298 | ~(IR_ERR_LEC_31X)); |
e0d1f481 | 1299 | else |
441ac340 | 1300 | m_can_write(cdev, M_CAN_IE, IR_ALL_INT); |
e0d1f481 DA |
1301 | |
1302 | /* route all interrupts to INT0 */ | |
441ac340 | 1303 | m_can_write(cdev, M_CAN_ILS, ILS_ALL_INT0); |
e0d1f481 DA |
1304 | |
1305 | /* set bittiming params */ | |
1306 | m_can_set_bittiming(dev); | |
1307 | ||
df06fd67 TCB |
1308 | /* enable internal timestamp generation, with a prescalar of 16. The |
1309 | * prescalar is applied to the nominal bit timing */ | |
1310 | m_can_write(cdev, M_CAN_TSCC, FIELD_PREP(TSCC_TCP_MASK, 0xf)); | |
1311 | ||
441ac340 | 1312 | m_can_config_endisable(cdev, false); |
f524f829 | 1313 | |
441ac340 DM |
1314 | if (cdev->ops->init) |
1315 | cdev->ops->init(cdev); | |
e0d1f481 DA |
1316 | } |
1317 | ||
1318 | static void m_can_start(struct net_device *dev) | |
1319 | { | |
441ac340 | 1320 | struct m_can_classdev *cdev = netdev_priv(dev); |
e0d1f481 DA |
1321 | |
1322 | /* basic m_can configuration */ | |
1323 | m_can_chip_config(dev); | |
1324 | ||
441ac340 | 1325 | cdev->can.state = CAN_STATE_ERROR_ACTIVE; |
e0d1f481 | 1326 | |
441ac340 | 1327 | m_can_enable_all_interrupts(cdev); |
e0d1f481 DA |
1328 | } |
1329 | ||
1330 | static int m_can_set_mode(struct net_device *dev, enum can_mode mode) | |
1331 | { | |
1332 | switch (mode) { | |
1333 | case CAN_MODE_START: | |
f524f829 | 1334 | m_can_clean(dev); |
e0d1f481 DA |
1335 | m_can_start(dev); |
1336 | netif_wake_queue(dev); | |
1337 | break; | |
1338 | default: | |
1339 | return -EOPNOTSUPP; | |
1340 | } | |
1341 | ||
1342 | return 0; | |
1343 | } | |
1344 | ||
b03cfc5b MH |
1345 | /* Checks core release number of M_CAN |
1346 | * returns 0 if an unsupported device is detected | |
1347 | * else it returns the release and step coded as: | |
1348 | * return value = 10 * <release> + 1 * <step> | |
1349 | */ | |
441ac340 | 1350 | static int m_can_check_core_release(struct m_can_classdev *cdev) |
b03cfc5b MH |
1351 | { |
1352 | u32 crel_reg; | |
1353 | u8 rel; | |
1354 | u8 step; | |
1355 | int res; | |
b03cfc5b MH |
1356 | |
1357 | /* Read Core Release Version and split into version number | |
1358 | * Example: Version 3.2.1 => rel = 3; step = 2; substep = 1; | |
1359 | */ | |
441ac340 | 1360 | crel_reg = m_can_read(cdev, M_CAN_CREL); |
20779943 TCB |
1361 | rel = (u8)FIELD_GET(CREL_REL_MASK, crel_reg); |
1362 | step = (u8)FIELD_GET(CREL_STEP_MASK, crel_reg); | |
b03cfc5b MH |
1363 | |
1364 | if (rel == 3) { | |
1365 | /* M_CAN v3.x.y: create return value */ | |
1366 | res = 30 + step; | |
1367 | } else { | |
1368 | /* Unsupported M_CAN version */ | |
1369 | res = 0; | |
1370 | } | |
1371 | ||
1372 | return res; | |
1373 | } | |
1374 | ||
1375 | /* Selectable Non ISO support only in version 3.2.x | |
1376 | * This function checks if the bit is writable. | |
1377 | */ | |
441ac340 | 1378 | static bool m_can_niso_supported(struct m_can_classdev *cdev) |
b03cfc5b | 1379 | { |
f524f829 DM |
1380 | u32 cccr_reg, cccr_poll = 0; |
1381 | int niso_timeout = -ETIMEDOUT; | |
1382 | int i; | |
b03cfc5b | 1383 | |
441ac340 DM |
1384 | m_can_config_endisable(cdev, true); |
1385 | cccr_reg = m_can_read(cdev, M_CAN_CCCR); | |
b03cfc5b | 1386 | cccr_reg |= CCCR_NISO; |
441ac340 | 1387 | m_can_write(cdev, M_CAN_CCCR, cccr_reg); |
b03cfc5b | 1388 | |
f524f829 | 1389 | for (i = 0; i <= 10; i++) { |
441ac340 | 1390 | cccr_poll = m_can_read(cdev, M_CAN_CCCR); |
f524f829 DM |
1391 | if (cccr_poll == cccr_reg) { |
1392 | niso_timeout = 0; | |
1393 | break; | |
1394 | } | |
1395 | ||
1396 | usleep_range(1, 5); | |
1397 | } | |
b03cfc5b MH |
1398 | |
1399 | /* Clear NISO */ | |
1400 | cccr_reg &= ~(CCCR_NISO); | |
441ac340 | 1401 | m_can_write(cdev, M_CAN_CCCR, cccr_reg); |
b03cfc5b | 1402 | |
441ac340 | 1403 | m_can_config_endisable(cdev, false); |
b03cfc5b MH |
1404 | |
1405 | /* return false if time out (-ETIMEDOUT), else return true */ | |
1406 | return !niso_timeout; | |
1407 | } | |
1408 | ||
3b464aff | 1409 | static int m_can_dev_setup(struct m_can_classdev *cdev) |
e0d1f481 | 1410 | { |
3b464aff | 1411 | struct net_device *dev = cdev->net; |
b03cfc5b | 1412 | int m_can_version; |
b03cfc5b | 1413 | |
3b464aff | 1414 | m_can_version = m_can_check_core_release(cdev); |
b03cfc5b MH |
1415 | /* return if unsupported version */ |
1416 | if (!m_can_version) { | |
3b464aff | 1417 | dev_err(cdev->dev, "Unsupported version number: %2d", |
5e520edd FA |
1418 | m_can_version); |
1419 | return -EINVAL; | |
b03cfc5b | 1420 | } |
e0d1f481 | 1421 | |
3b464aff MKB |
1422 | if (!cdev->is_peripheral) |
1423 | netif_napi_add(dev, &cdev->napi, | |
f524f829 | 1424 | m_can_poll, M_CAN_NAPI_WEIGHT); |
e0d1f481 | 1425 | |
b03cfc5b | 1426 | /* Shared properties of all M_CAN versions */ |
3b464aff MKB |
1427 | cdev->version = m_can_version; |
1428 | cdev->can.do_set_mode = m_can_set_mode; | |
1429 | cdev->can.do_get_berr_counter = m_can_get_berr_counter; | |
6cfda7fb | 1430 | |
b03cfc5b | 1431 | /* Set M_CAN supported operations */ |
3b464aff | 1432 | cdev->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK | |
709efa6f MKB |
1433 | CAN_CTRLMODE_LISTENONLY | |
1434 | CAN_CTRLMODE_BERR_REPORTING | | |
1435 | CAN_CTRLMODE_FD | | |
1436 | CAN_CTRLMODE_ONE_SHOT; | |
e0d1f481 | 1437 | |
b03cfc5b | 1438 | /* Set properties depending on M_CAN version */ |
3b464aff | 1439 | switch (cdev->version) { |
b03cfc5b MH |
1440 | case 30: |
1441 | /* CAN_CTRLMODE_FD_NON_ISO is fixed with M_CAN IP v3.0.x */ | |
1442 | can_set_static_ctrlmode(dev, CAN_CTRLMODE_FD_NON_ISO); | |
0ddd83fb MKB |
1443 | cdev->can.bittiming_const = &m_can_bittiming_const_30X; |
1444 | cdev->can.data_bittiming_const = &m_can_data_bittiming_const_30X; | |
b03cfc5b MH |
1445 | break; |
1446 | case 31: | |
1447 | /* CAN_CTRLMODE_FD_NON_ISO is fixed with M_CAN IP v3.1.x */ | |
1448 | can_set_static_ctrlmode(dev, CAN_CTRLMODE_FD_NON_ISO); | |
0ddd83fb MKB |
1449 | cdev->can.bittiming_const = &m_can_bittiming_const_31X; |
1450 | cdev->can.data_bittiming_const = &m_can_data_bittiming_const_31X; | |
b03cfc5b MH |
1451 | break; |
1452 | case 32: | |
5c7d55bd PS |
1453 | case 33: |
1454 | /* Support both MCAN version v3.2.x and v3.3.0 */ | |
0ddd83fb MKB |
1455 | cdev->can.bittiming_const = &m_can_bittiming_const_31X; |
1456 | cdev->can.data_bittiming_const = &m_can_data_bittiming_const_31X; | |
f524f829 | 1457 | |
3b464aff MKB |
1458 | cdev->can.ctrlmode_supported |= |
1459 | (m_can_niso_supported(cdev) ? | |
709efa6f | 1460 | CAN_CTRLMODE_FD_NON_ISO : 0); |
b03cfc5b MH |
1461 | break; |
1462 | default: | |
3b464aff MKB |
1463 | dev_err(cdev->dev, "Unsupported version number: %2d", |
1464 | cdev->version); | |
5e520edd | 1465 | return -EINVAL; |
b03cfc5b MH |
1466 | } |
1467 | ||
3b464aff MKB |
1468 | if (cdev->ops->init) |
1469 | cdev->ops->init(cdev); | |
e0d1f481 DA |
1470 | |
1471 | return 0; | |
e0d1f481 DA |
1472 | } |
1473 | ||
1474 | static void m_can_stop(struct net_device *dev) | |
1475 | { | |
441ac340 | 1476 | struct m_can_classdev *cdev = netdev_priv(dev); |
e0d1f481 DA |
1477 | |
1478 | /* disable all interrupts */ | |
441ac340 | 1479 | m_can_disable_all_interrupts(cdev); |
e0d1f481 | 1480 | |
a584e9bc FA |
1481 | /* Set init mode to disengage from the network */ |
1482 | m_can_config_endisable(cdev, true); | |
1483 | ||
e0d1f481 | 1484 | /* set the state as STOPPED */ |
441ac340 | 1485 | cdev->can.state = CAN_STATE_STOPPED; |
e0d1f481 DA |
1486 | } |
1487 | ||
1488 | static int m_can_close(struct net_device *dev) | |
1489 | { | |
441ac340 | 1490 | struct m_can_classdev *cdev = netdev_priv(dev); |
e0d1f481 DA |
1491 | |
1492 | netif_stop_queue(dev); | |
441ac340 DM |
1493 | |
1494 | if (!cdev->is_peripheral) | |
1495 | napi_disable(&cdev->napi); | |
1496 | ||
e0d1f481 | 1497 | m_can_stop(dev); |
441ac340 | 1498 | m_can_clk_stop(cdev); |
e0d1f481 | 1499 | free_irq(dev->irq, dev); |
f524f829 | 1500 | |
441ac340 DM |
1501 | if (cdev->is_peripheral) { |
1502 | cdev->tx_skb = NULL; | |
1503 | destroy_workqueue(cdev->tx_wq); | |
1504 | cdev->tx_wq = NULL; | |
f524f829 DM |
1505 | } |
1506 | ||
1be37d3b TCB |
1507 | if (cdev->is_peripheral) |
1508 | can_rx_offload_disable(&cdev->offload); | |
1509 | ||
e0d1f481 DA |
1510 | close_candev(dev); |
1511 | can_led_event(dev, CAN_LED_EVENT_STOP); | |
1512 | ||
d836cb5f FA |
1513 | phy_power_off(cdev->transceiver); |
1514 | ||
e0d1f481 DA |
1515 | return 0; |
1516 | } | |
1517 | ||
10c1c397 MH |
1518 | static int m_can_next_echo_skb_occupied(struct net_device *dev, int putidx) |
1519 | { | |
441ac340 | 1520 | struct m_can_classdev *cdev = netdev_priv(dev); |
10c1c397 | 1521 | /*get wrap around for loopback skb index */ |
441ac340 | 1522 | unsigned int wrap = cdev->can.echo_skb_max; |
10c1c397 MH |
1523 | int next_idx; |
1524 | ||
1525 | /* calculate next index */ | |
1526 | next_idx = (++putidx >= wrap ? 0 : putidx); | |
1527 | ||
1528 | /* check if occupied */ | |
441ac340 | 1529 | return !!cdev->can.echo_skb[next_idx]; |
10c1c397 MH |
1530 | } |
1531 | ||
441ac340 | 1532 | static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev) |
e0d1f481 | 1533 | { |
441ac340 DM |
1534 | struct canfd_frame *cf = (struct canfd_frame *)cdev->tx_skb->data; |
1535 | struct net_device *dev = cdev->net; | |
1536 | struct sk_buff *skb = cdev->tx_skb; | |
10c1c397 | 1537 | u32 id, cccr, fdflags; |
80646733 | 1538 | int i; |
10c1c397 | 1539 | int putidx; |
e0d1f481 | 1540 | |
e04b2cfe MKB |
1541 | cdev->tx_skb = NULL; |
1542 | ||
10c1c397 MH |
1543 | /* Generate ID field for TX buffer Element */ |
1544 | /* Common to all supported M_CAN versions */ | |
e0d1f481 DA |
1545 | if (cf->can_id & CAN_EFF_FLAG) { |
1546 | id = cf->can_id & CAN_EFF_MASK; | |
1547 | id |= TX_BUF_XTD; | |
1548 | } else { | |
1549 | id = ((cf->can_id & CAN_SFF_MASK) << 18); | |
1550 | } | |
1551 | ||
1552 | if (cf->can_id & CAN_RTR_FLAG) | |
1553 | id |= TX_BUF_RTR; | |
1554 | ||
441ac340 | 1555 | if (cdev->version == 30) { |
10c1c397 MH |
1556 | netif_stop_queue(dev); |
1557 | ||
1558 | /* message ram configuration */ | |
441ac340 DM |
1559 | m_can_fifo_write(cdev, 0, M_CAN_FIFO_ID, id); |
1560 | m_can_fifo_write(cdev, 0, M_CAN_FIFO_DLC, | |
3ab4ce0d | 1561 | can_fd_len2dlc(cf->len) << 16); |
80646733 | 1562 | |
10c1c397 | 1563 | for (i = 0; i < cf->len; i += 4) |
441ac340 | 1564 | m_can_fifo_write(cdev, 0, |
10c1c397 MH |
1565 | M_CAN_FIFO_DATA(i / 4), |
1566 | *(u32 *)(cf->data + i)); | |
1567 | ||
1dcb6e57 | 1568 | can_put_echo_skb(skb, dev, 0, 0); |
10c1c397 | 1569 | |
441ac340 DM |
1570 | if (cdev->can.ctrlmode & CAN_CTRLMODE_FD) { |
1571 | cccr = m_can_read(cdev, M_CAN_CCCR); | |
20779943 | 1572 | cccr &= ~CCCR_CMR_MASK; |
10c1c397 MH |
1573 | if (can_is_canfd_skb(skb)) { |
1574 | if (cf->flags & CANFD_BRS) | |
20779943 TCB |
1575 | cccr |= FIELD_PREP(CCCR_CMR_MASK, |
1576 | CCCR_CMR_CANFD_BRS); | |
10c1c397 | 1577 | else |
20779943 TCB |
1578 | cccr |= FIELD_PREP(CCCR_CMR_MASK, |
1579 | CCCR_CMR_CANFD); | |
10c1c397 | 1580 | } else { |
20779943 | 1581 | cccr |= FIELD_PREP(CCCR_CMR_MASK, CCCR_CMR_CAN); |
10c1c397 | 1582 | } |
441ac340 | 1583 | m_can_write(cdev, M_CAN_CCCR, cccr); |
10c1c397 | 1584 | } |
441ac340 DM |
1585 | m_can_write(cdev, M_CAN_TXBTIE, 0x1); |
1586 | m_can_write(cdev, M_CAN_TXBAR, 0x1); | |
10c1c397 MH |
1587 | /* End of xmit function for version 3.0.x */ |
1588 | } else { | |
1589 | /* Transmit routine for version >= v3.1.x */ | |
1590 | ||
1591 | /* Check if FIFO full */ | |
441ac340 | 1592 | if (m_can_tx_fifo_full(cdev)) { |
10c1c397 MH |
1593 | /* This shouldn't happen */ |
1594 | netif_stop_queue(dev); | |
1595 | netdev_warn(dev, | |
1596 | "TX queue active although FIFO is full."); | |
441ac340 DM |
1597 | |
1598 | if (cdev->is_peripheral) { | |
f524f829 DM |
1599 | kfree_skb(skb); |
1600 | dev->stats.tx_dropped++; | |
1601 | return NETDEV_TX_OK; | |
1602 | } else { | |
1603 | return NETDEV_TX_BUSY; | |
1604 | } | |
10c1c397 | 1605 | } |
80646733 | 1606 | |
10c1c397 | 1607 | /* get put index for frame */ |
20779943 TCB |
1608 | putidx = FIELD_GET(TXFQS_TFQPI_MASK, |
1609 | m_can_read(cdev, M_CAN_TXFQS)); | |
10c1c397 | 1610 | /* Write ID Field to FIFO Element */ |
441ac340 | 1611 | m_can_fifo_write(cdev, putidx, M_CAN_FIFO_ID, id); |
e0d1f481 | 1612 | |
10c1c397 MH |
1613 | /* get CAN FD configuration of frame */ |
1614 | fdflags = 0; | |
80646733 | 1615 | if (can_is_canfd_skb(skb)) { |
10c1c397 | 1616 | fdflags |= TX_BUF_FDF; |
80646733 | 1617 | if (cf->flags & CANFD_BRS) |
10c1c397 | 1618 | fdflags |= TX_BUF_BRS; |
80646733 | 1619 | } |
80646733 | 1620 | |
10c1c397 MH |
1621 | /* Construct DLC Field. Also contains CAN-FD configuration |
1622 | * use put index of fifo as message marker | |
1623 | * it is used in TX interrupt for | |
1624 | * sending the correct echo frame | |
1625 | */ | |
441ac340 | 1626 | m_can_fifo_write(cdev, putidx, M_CAN_FIFO_DLC, |
20779943 TCB |
1627 | FIELD_PREP(TX_BUF_MM_MASK, putidx) | |
1628 | FIELD_PREP(TX_BUF_DLC_MASK, | |
1629 | can_fd_len2dlc(cf->len)) | | |
10c1c397 MH |
1630 | fdflags | TX_BUF_EFC); |
1631 | ||
1632 | for (i = 0; i < cf->len; i += 4) | |
441ac340 | 1633 | m_can_fifo_write(cdev, putidx, M_CAN_FIFO_DATA(i / 4), |
10c1c397 MH |
1634 | *(u32 *)(cf->data + i)); |
1635 | ||
1636 | /* Push loopback echo. | |
1637 | * Will be looped back on TX interrupt based on message marker | |
1638 | */ | |
1dcb6e57 | 1639 | can_put_echo_skb(skb, dev, putidx, 0); |
10c1c397 MH |
1640 | |
1641 | /* Enable TX FIFO element to start transfer */ | |
441ac340 | 1642 | m_can_write(cdev, M_CAN_TXBAR, (1 << putidx)); |
10c1c397 MH |
1643 | |
1644 | /* stop network queue if fifo full */ | |
441ac340 | 1645 | if (m_can_tx_fifo_full(cdev) || |
f524f829 DM |
1646 | m_can_next_echo_skb_occupied(dev, putidx)) |
1647 | netif_stop_queue(dev); | |
10c1c397 | 1648 | } |
e0d1f481 DA |
1649 | |
1650 | return NETDEV_TX_OK; | |
1651 | } | |
1652 | ||
f524f829 DM |
1653 | static void m_can_tx_work_queue(struct work_struct *ws) |
1654 | { | |
441ac340 | 1655 | struct m_can_classdev *cdev = container_of(ws, struct m_can_classdev, |
709efa6f | 1656 | tx_work); |
441ac340 DM |
1657 | |
1658 | m_can_tx_handler(cdev); | |
f524f829 DM |
1659 | } |
1660 | ||
1661 | static netdev_tx_t m_can_start_xmit(struct sk_buff *skb, | |
1662 | struct net_device *dev) | |
1663 | { | |
441ac340 | 1664 | struct m_can_classdev *cdev = netdev_priv(dev); |
f524f829 DM |
1665 | |
1666 | if (can_dropped_invalid_skb(dev, skb)) | |
1667 | return NETDEV_TX_OK; | |
1668 | ||
441ac340 DM |
1669 | if (cdev->is_peripheral) { |
1670 | if (cdev->tx_skb) { | |
f524f829 DM |
1671 | netdev_err(dev, "hard_xmit called while tx busy\n"); |
1672 | return NETDEV_TX_BUSY; | |
1673 | } | |
1674 | ||
441ac340 | 1675 | if (cdev->can.state == CAN_STATE_BUS_OFF) { |
f524f829 DM |
1676 | m_can_clean(dev); |
1677 | } else { | |
1678 | /* Need to stop the queue to avoid numerous requests | |
1679 | * from being sent. Suggested improvement is to create | |
1680 | * a queueing mechanism that will queue the skbs and | |
1681 | * process them in order. | |
1682 | */ | |
441ac340 DM |
1683 | cdev->tx_skb = skb; |
1684 | netif_stop_queue(cdev->net); | |
1685 | queue_work(cdev->tx_wq, &cdev->tx_work); | |
f524f829 DM |
1686 | } |
1687 | } else { | |
441ac340 DM |
1688 | cdev->tx_skb = skb; |
1689 | return m_can_tx_handler(cdev); | |
f524f829 DM |
1690 | } |
1691 | ||
1692 | return NETDEV_TX_OK; | |
1693 | } | |
1694 | ||
1695 | static int m_can_open(struct net_device *dev) | |
1696 | { | |
441ac340 | 1697 | struct m_can_classdev *cdev = netdev_priv(dev); |
f524f829 DM |
1698 | int err; |
1699 | ||
d836cb5f | 1700 | err = phy_power_on(cdev->transceiver); |
f524f829 DM |
1701 | if (err) |
1702 | return err; | |
1703 | ||
d836cb5f FA |
1704 | err = m_can_clk_start(cdev); |
1705 | if (err) | |
1706 | goto out_phy_power_off; | |
1707 | ||
f524f829 DM |
1708 | /* open the can device */ |
1709 | err = open_candev(dev); | |
1710 | if (err) { | |
1711 | netdev_err(dev, "failed to open can device\n"); | |
1712 | goto exit_disable_clks; | |
1713 | } | |
1714 | ||
1be37d3b TCB |
1715 | if (cdev->is_peripheral) |
1716 | can_rx_offload_enable(&cdev->offload); | |
1717 | ||
f524f829 | 1718 | /* register interrupt handler */ |
441ac340 DM |
1719 | if (cdev->is_peripheral) { |
1720 | cdev->tx_skb = NULL; | |
1721 | cdev->tx_wq = alloc_workqueue("mcan_wq", | |
f524f829 | 1722 | WQ_FREEZABLE | WQ_MEM_RECLAIM, 0); |
441ac340 | 1723 | if (!cdev->tx_wq) { |
f524f829 DM |
1724 | err = -ENOMEM; |
1725 | goto out_wq_fail; | |
1726 | } | |
1727 | ||
441ac340 | 1728 | INIT_WORK(&cdev->tx_work, m_can_tx_work_queue); |
f524f829 DM |
1729 | |
1730 | err = request_threaded_irq(dev->irq, NULL, m_can_isr, | |
865f5b67 | 1731 | IRQF_ONESHOT, |
f524f829 DM |
1732 | dev->name, dev); |
1733 | } else { | |
1734 | err = request_irq(dev->irq, m_can_isr, IRQF_SHARED, dev->name, | |
1735 | dev); | |
1736 | } | |
1737 | ||
1738 | if (err < 0) { | |
1739 | netdev_err(dev, "failed to request interrupt\n"); | |
1740 | goto exit_irq_fail; | |
1741 | } | |
1742 | ||
1743 | /* start the m_can controller */ | |
1744 | m_can_start(dev); | |
1745 | ||
1746 | can_led_event(dev, CAN_LED_EVENT_OPEN); | |
1747 | ||
441ac340 DM |
1748 | if (!cdev->is_peripheral) |
1749 | napi_enable(&cdev->napi); | |
f524f829 DM |
1750 | |
1751 | netif_start_queue(dev); | |
1752 | ||
1753 | return 0; | |
1754 | ||
1755 | exit_irq_fail: | |
441ac340 DM |
1756 | if (cdev->is_peripheral) |
1757 | destroy_workqueue(cdev->tx_wq); | |
f524f829 | 1758 | out_wq_fail: |
1be37d3b TCB |
1759 | if (cdev->is_peripheral) |
1760 | can_rx_offload_disable(&cdev->offload); | |
f524f829 DM |
1761 | close_candev(dev); |
1762 | exit_disable_clks: | |
441ac340 | 1763 | m_can_clk_stop(cdev); |
d836cb5f FA |
1764 | out_phy_power_off: |
1765 | phy_power_off(cdev->transceiver); | |
f524f829 DM |
1766 | return err; |
1767 | } | |
1768 | ||
e0d1f481 DA |
1769 | static const struct net_device_ops m_can_netdev_ops = { |
1770 | .ndo_open = m_can_open, | |
1771 | .ndo_stop = m_can_close, | |
1772 | .ndo_start_xmit = m_can_start_xmit, | |
d6fdb38b | 1773 | .ndo_change_mtu = can_change_mtu, |
e0d1f481 DA |
1774 | }; |
1775 | ||
1776 | static int register_m_can_dev(struct net_device *dev) | |
1777 | { | |
1778 | dev->flags |= IFF_ECHO; /* we support local echo */ | |
1779 | dev->netdev_ops = &m_can_netdev_ops; | |
1780 | ||
1781 | return register_candev(dev); | |
1782 | } | |
1783 | ||
441ac340 | 1784 | static void m_can_of_parse_mram(struct m_can_classdev *cdev, |
b03cfc5b | 1785 | const u32 *mram_config_vals) |
e0d1f481 | 1786 | { |
441ac340 DM |
1787 | cdev->mcfg[MRAM_SIDF].off = mram_config_vals[0]; |
1788 | cdev->mcfg[MRAM_SIDF].num = mram_config_vals[1]; | |
1789 | cdev->mcfg[MRAM_XIDF].off = cdev->mcfg[MRAM_SIDF].off + | |
709efa6f | 1790 | cdev->mcfg[MRAM_SIDF].num * SIDF_ELEMENT_SIZE; |
441ac340 DM |
1791 | cdev->mcfg[MRAM_XIDF].num = mram_config_vals[2]; |
1792 | cdev->mcfg[MRAM_RXF0].off = cdev->mcfg[MRAM_XIDF].off + | |
709efa6f | 1793 | cdev->mcfg[MRAM_XIDF].num * XIDF_ELEMENT_SIZE; |
441ac340 | 1794 | cdev->mcfg[MRAM_RXF0].num = mram_config_vals[3] & |
20779943 | 1795 | FIELD_MAX(RXFC_FS_MASK); |
441ac340 | 1796 | cdev->mcfg[MRAM_RXF1].off = cdev->mcfg[MRAM_RXF0].off + |
709efa6f | 1797 | cdev->mcfg[MRAM_RXF0].num * RXF0_ELEMENT_SIZE; |
441ac340 | 1798 | cdev->mcfg[MRAM_RXF1].num = mram_config_vals[4] & |
20779943 | 1799 | FIELD_MAX(RXFC_FS_MASK); |
441ac340 | 1800 | cdev->mcfg[MRAM_RXB].off = cdev->mcfg[MRAM_RXF1].off + |
709efa6f | 1801 | cdev->mcfg[MRAM_RXF1].num * RXF1_ELEMENT_SIZE; |
441ac340 DM |
1802 | cdev->mcfg[MRAM_RXB].num = mram_config_vals[5]; |
1803 | cdev->mcfg[MRAM_TXE].off = cdev->mcfg[MRAM_RXB].off + | |
709efa6f | 1804 | cdev->mcfg[MRAM_RXB].num * RXB_ELEMENT_SIZE; |
441ac340 DM |
1805 | cdev->mcfg[MRAM_TXE].num = mram_config_vals[6]; |
1806 | cdev->mcfg[MRAM_TXB].off = cdev->mcfg[MRAM_TXE].off + | |
709efa6f | 1807 | cdev->mcfg[MRAM_TXE].num * TXE_ELEMENT_SIZE; |
441ac340 | 1808 | cdev->mcfg[MRAM_TXB].num = mram_config_vals[7] & |
20779943 | 1809 | FIELD_MAX(TXBC_NDTB_MASK); |
e0d1f481 | 1810 | |
441ac340 | 1811 | dev_dbg(cdev->dev, |
f524f829 | 1812 | "sidf 0x%x %d xidf 0x%x %d rxf0 0x%x %d rxf1 0x%x %d rxb 0x%x %d txe 0x%x %d txb 0x%x %d\n", |
441ac340 DM |
1813 | cdev->mcfg[MRAM_SIDF].off, cdev->mcfg[MRAM_SIDF].num, |
1814 | cdev->mcfg[MRAM_XIDF].off, cdev->mcfg[MRAM_XIDF].num, | |
1815 | cdev->mcfg[MRAM_RXF0].off, cdev->mcfg[MRAM_RXF0].num, | |
1816 | cdev->mcfg[MRAM_RXF1].off, cdev->mcfg[MRAM_RXF1].num, | |
1817 | cdev->mcfg[MRAM_RXB].off, cdev->mcfg[MRAM_RXB].num, | |
1818 | cdev->mcfg[MRAM_TXE].off, cdev->mcfg[MRAM_TXE].num, | |
1819 | cdev->mcfg[MRAM_TXB].off, cdev->mcfg[MRAM_TXB].num); | |
e0d1f481 DA |
1820 | } |
1821 | ||
441ac340 | 1822 | void m_can_init_ram(struct m_can_classdev *cdev) |
e0d1f481 | 1823 | { |
f524f829 | 1824 | int end, i, start; |
e0d1f481 | 1825 | |
f524f829 DM |
1826 | /* initialize the entire Message RAM in use to avoid possible |
1827 | * ECC/parity checksum errors when reading an uninitialized buffer | |
1828 | */ | |
441ac340 DM |
1829 | start = cdev->mcfg[MRAM_SIDF].off; |
1830 | end = cdev->mcfg[MRAM_TXB].off + | |
1831 | cdev->mcfg[MRAM_TXB].num * TXB_ELEMENT_SIZE; | |
b03cfc5b | 1832 | |
f524f829 | 1833 | for (i = start; i < end; i += 4) |
441ac340 | 1834 | m_can_fifo_write_no_off(cdev, i, 0x0); |
f524f829 DM |
1835 | } |
1836 | EXPORT_SYMBOL_GPL(m_can_init_ram); | |
e0d1f481 | 1837 | |
3b464aff | 1838 | int m_can_class_get_clocks(struct m_can_classdev *cdev) |
f524f829 DM |
1839 | { |
1840 | int ret = 0; | |
e0d1f481 | 1841 | |
3b464aff MKB |
1842 | cdev->hclk = devm_clk_get(cdev->dev, "hclk"); |
1843 | cdev->cclk = devm_clk_get(cdev->dev, "cclk"); | |
e0d1f481 | 1844 | |
3b464aff MKB |
1845 | if (IS_ERR(cdev->cclk)) { |
1846 | dev_err(cdev->dev, "no clock found\n"); | |
b03cfc5b | 1847 | ret = -ENODEV; |
b03cfc5b MH |
1848 | } |
1849 | ||
f524f829 DM |
1850 | return ret; |
1851 | } | |
1852 | EXPORT_SYMBOL_GPL(m_can_class_get_clocks); | |
b03cfc5b | 1853 | |
ac33ffd3 MKB |
1854 | struct m_can_classdev *m_can_class_allocate_dev(struct device *dev, |
1855 | int sizeof_priv) | |
f524f829 | 1856 | { |
441ac340 | 1857 | struct m_can_classdev *class_dev = NULL; |
f524f829 DM |
1858 | u32 mram_config_vals[MRAM_CFG_LEN]; |
1859 | struct net_device *net_dev; | |
1860 | u32 tx_fifo_size; | |
1861 | int ret; | |
1862 | ||
1863 | ret = fwnode_property_read_u32_array(dev_fwnode(dev), | |
1864 | "bosch,mram-cfg", | |
1865 | mram_config_vals, | |
1866 | sizeof(mram_config_vals) / 4); | |
b03cfc5b | 1867 | if (ret) { |
f524f829 DM |
1868 | dev_err(dev, "Could not get Message RAM configuration."); |
1869 | goto out; | |
b03cfc5b MH |
1870 | } |
1871 | ||
1872 | /* Get TX FIFO size | |
1873 | * Defines the total amount of echo buffers for loopback | |
1874 | */ | |
1875 | tx_fifo_size = mram_config_vals[7]; | |
1876 | ||
1877 | /* allocate the m_can device */ | |
ac33ffd3 | 1878 | net_dev = alloc_candev(sizeof_priv, tx_fifo_size); |
f524f829 DM |
1879 | if (!net_dev) { |
1880 | dev_err(dev, "Failed to allocate CAN device"); | |
1881 | goto out; | |
b03cfc5b | 1882 | } |
5e520edd | 1883 | |
f524f829 | 1884 | class_dev = netdev_priv(net_dev); |
f524f829 DM |
1885 | class_dev->net = net_dev; |
1886 | class_dev->dev = dev; | |
1887 | SET_NETDEV_DEV(net_dev, dev); | |
e0d1f481 | 1888 | |
f524f829 DM |
1889 | m_can_of_parse_mram(class_dev, mram_config_vals); |
1890 | out: | |
1891 | return class_dev; | |
1892 | } | |
1893 | EXPORT_SYMBOL_GPL(m_can_class_allocate_dev); | |
1894 | ||
a8c22f5b DM |
1895 | void m_can_class_free_dev(struct net_device *net) |
1896 | { | |
1897 | free_candev(net); | |
1898 | } | |
1899 | EXPORT_SYMBOL_GPL(m_can_class_free_dev); | |
1900 | ||
3b464aff | 1901 | int m_can_class_register(struct m_can_classdev *cdev) |
f524f829 DM |
1902 | { |
1903 | int ret; | |
cdf8259d | 1904 | |
3b464aff MKB |
1905 | if (cdev->pm_clock_support) { |
1906 | ret = m_can_clk_start(cdev); | |
f524f829 | 1907 | if (ret) |
227619c3 | 1908 | return ret; |
f524f829 DM |
1909 | } |
1910 | ||
1be37d3b TCB |
1911 | if (cdev->is_peripheral) { |
1912 | ret = can_rx_offload_add_manual(cdev->net, &cdev->offload, | |
1913 | M_CAN_NAPI_WEIGHT); | |
1914 | if (ret) | |
1915 | goto clk_disable; | |
1916 | } | |
1917 | ||
3b464aff | 1918 | ret = m_can_dev_setup(cdev); |
cdf8259d | 1919 | if (ret) |
1be37d3b | 1920 | goto rx_offload_del; |
cdf8259d | 1921 | |
3b464aff | 1922 | ret = register_m_can_dev(cdev->net); |
e0d1f481 | 1923 | if (ret) { |
3b464aff MKB |
1924 | dev_err(cdev->dev, "registering %s failed (err=%d)\n", |
1925 | cdev->net->name, ret); | |
1be37d3b | 1926 | goto rx_offload_del; |
e0d1f481 DA |
1927 | } |
1928 | ||
3b464aff | 1929 | devm_can_led_init(cdev->net); |
e0d1f481 | 1930 | |
3b464aff | 1931 | of_can_transceiver(cdev->net); |
31643dc8 | 1932 | |
3b464aff MKB |
1933 | dev_info(cdev->dev, "%s device registered (irq=%d, version=%d)\n", |
1934 | KBUILD_MODNAME, cdev->net->irq, cdev->version); | |
e0d1f481 | 1935 | |
b03cfc5b MH |
1936 | /* Probe finished |
1937 | * Stop clocks. They will be reactivated once the M_CAN device is opened | |
1938 | */ | |
1be37d3b TCB |
1939 | m_can_clk_stop(cdev); |
1940 | ||
1941 | return 0; | |
1942 | ||
1943 | rx_offload_del: | |
1944 | if (cdev->is_peripheral) | |
1945 | can_rx_offload_del(&cdev->offload); | |
cdf8259d | 1946 | clk_disable: |
3b464aff | 1947 | m_can_clk_stop(cdev); |
f524f829 | 1948 | |
e0d1f481 DA |
1949 | return ret; |
1950 | } | |
f524f829 | 1951 | EXPORT_SYMBOL_GPL(m_can_class_register); |
e0d1f481 | 1952 | |
3b464aff | 1953 | void m_can_class_unregister(struct m_can_classdev *cdev) |
6d9986b4 | 1954 | { |
1be37d3b TCB |
1955 | if (cdev->is_peripheral) |
1956 | can_rx_offload_del(&cdev->offload); | |
3b464aff | 1957 | unregister_candev(cdev->net); |
6d9986b4 MKB |
1958 | } |
1959 | EXPORT_SYMBOL_GPL(m_can_class_unregister); | |
1960 | ||
f524f829 | 1961 | int m_can_class_suspend(struct device *dev) |
e0d1f481 | 1962 | { |
c6b73489 MKB |
1963 | struct m_can_classdev *cdev = dev_get_drvdata(dev); |
1964 | struct net_device *ndev = cdev->net; | |
e0d1f481 DA |
1965 | |
1966 | if (netif_running(ndev)) { | |
1967 | netif_stop_queue(ndev); | |
1968 | netif_device_detach(ndev); | |
d14ccea0 | 1969 | m_can_stop(ndev); |
441ac340 | 1970 | m_can_clk_stop(cdev); |
e0d1f481 DA |
1971 | } |
1972 | ||
c9b3bce1 BH |
1973 | pinctrl_pm_select_sleep_state(dev); |
1974 | ||
441ac340 | 1975 | cdev->can.state = CAN_STATE_SLEEPING; |
e0d1f481 DA |
1976 | |
1977 | return 0; | |
1978 | } | |
f524f829 | 1979 | EXPORT_SYMBOL_GPL(m_can_class_suspend); |
e0d1f481 | 1980 | |
f524f829 | 1981 | int m_can_class_resume(struct device *dev) |
e0d1f481 | 1982 | { |
c6b73489 MKB |
1983 | struct m_can_classdev *cdev = dev_get_drvdata(dev); |
1984 | struct net_device *ndev = cdev->net; | |
e0d1f481 | 1985 | |
c9b3bce1 BH |
1986 | pinctrl_pm_select_default_state(dev); |
1987 | ||
441ac340 | 1988 | cdev->can.state = CAN_STATE_ERROR_ACTIVE; |
e0d1f481 DA |
1989 | |
1990 | if (netif_running(ndev)) { | |
d14ccea0 QS |
1991 | int ret; |
1992 | ||
441ac340 | 1993 | ret = m_can_clk_start(cdev); |
d14ccea0 QS |
1994 | if (ret) |
1995 | return ret; | |
1996 | ||
441ac340 | 1997 | m_can_init_ram(cdev); |
d14ccea0 | 1998 | m_can_start(ndev); |
e0d1f481 DA |
1999 | netif_device_attach(ndev); |
2000 | netif_start_queue(ndev); | |
2001 | } | |
2002 | ||
2003 | return 0; | |
2004 | } | |
f524f829 | 2005 | EXPORT_SYMBOL_GPL(m_can_class_resume); |
e0d1f481 | 2006 | |
e0d1f481 | 2007 | MODULE_AUTHOR("Dong Aisheng <b29396@freescale.com>"); |
f524f829 | 2008 | MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>"); |
e0d1f481 DA |
2009 | MODULE_LICENSE("GPL v2"); |
2010 | MODULE_DESCRIPTION("CAN bus driver for Bosch M_CAN controller"); |