]>
Commit | Line | Data |
---|---|---|
aaa7cb26 | 1 | // SPDX-License-Identifier: GPL-2.0-only |
8ac8321e SG |
2 | /* |
3 | * Copyright (C) 2007, 2011 Wolfgang Grandegger <wg@grandegger.com> | |
4 | * Copyright (C) 2012 Stephane Grosjean <s.grosjean@peak-system.com> | |
5 | * | |
6 | * Derived from the PCAN project file driver/src/pcan_pci.c: | |
7 | * | |
8 | * Copyright (C) 2001-2006 PEAK System-Technik GmbH | |
8ac8321e SG |
9 | */ |
10 | ||
11 | #include <linux/kernel.h> | |
12 | #include <linux/module.h> | |
13 | #include <linux/interrupt.h> | |
14 | #include <linux/netdevice.h> | |
15 | #include <linux/delay.h> | |
16 | #include <linux/pci.h> | |
17 | #include <linux/io.h> | |
18 | #include <linux/can.h> | |
19 | #include <linux/can/dev.h> | |
20 | ||
21 | #include "peak_canfd_user.h" | |
22 | ||
23 | MODULE_AUTHOR("Stephane Grosjean <s.grosjean@peak-system.com>"); | |
4cbdd0ee SG |
24 | MODULE_DESCRIPTION("Socket-CAN driver for PEAK PCAN PCIe/M.2 FD family cards"); |
25 | MODULE_SUPPORTED_DEVICE("PEAK PCAN PCIe/M.2 FD CAN cards"); | |
8ac8321e SG |
26 | MODULE_LICENSE("GPL v2"); |
27 | ||
28 | #define PCIEFD_DRV_NAME "peak_pciefd" | |
29 | ||
30 | #define PEAK_PCI_VENDOR_ID 0x001c /* The PCI device and vendor IDs */ | |
31 | #define PEAK_PCIEFD_ID 0x0013 /* for PCIe slot cards */ | |
4cbdd0ee SG |
32 | #define PCAN_CPCIEFD_ID 0x0014 /* for Compact-PCI Serial slot cards */ |
33 | #define PCAN_PCIE104FD_ID 0x0017 /* for PCIe-104 Express slot cards */ | |
34 | #define PCAN_MINIPCIEFD_ID 0x0018 /* for mini-PCIe slot cards */ | |
35 | #define PCAN_PCIEFD_OEM_ID 0x0019 /* for PCIe slot OEM cards */ | |
36 | #define PCAN_M2_ID 0x001a /* for M2 slot cards */ | |
8ac8321e SG |
37 | |
38 | /* PEAK PCIe board access description */ | |
39 | #define PCIEFD_BAR0_SIZE (64 * 1024) | |
40 | #define PCIEFD_RX_DMA_SIZE (4 * 1024) | |
41 | #define PCIEFD_TX_DMA_SIZE (4 * 1024) | |
42 | ||
43 | #define PCIEFD_TX_PAGE_SIZE (2 * 1024) | |
44 | ||
45 | /* System Control Registers */ | |
46 | #define PCIEFD_REG_SYS_CTL_SET 0x0000 /* set bits */ | |
47 | #define PCIEFD_REG_SYS_CTL_CLR 0x0004 /* clear bits */ | |
48 | ||
49 | /* Version info registers */ | |
50 | #define PCIEFD_REG_SYS_VER1 0x0040 /* version reg #1 */ | |
51 | #define PCIEFD_REG_SYS_VER2 0x0044 /* version reg #2 */ | |
52 | ||
5d4c94ed SG |
53 | #define PCIEFD_FW_VERSION(x, y, z) (((u32)(x) << 24) | \ |
54 | ((u32)(y) << 16) | \ | |
55 | ((u32)(z) << 8)) | |
56 | ||
8ac8321e SG |
57 | /* System Control Registers Bits */ |
58 | #define PCIEFD_SYS_CTL_TS_RST 0x00000001 /* timestamp clock */ | |
59 | #define PCIEFD_SYS_CTL_CLK_EN 0x00000002 /* system clock */ | |
60 | ||
61 | /* CAN-FD channel addresses */ | |
62 | #define PCIEFD_CANX_OFF(c) (((c) + 1) * 0x1000) | |
63 | ||
64 | #define PCIEFD_ECHO_SKB_MAX PCANFD_ECHO_SKB_DEF | |
65 | ||
66 | /* CAN-FD channel registers */ | |
67 | #define PCIEFD_REG_CAN_MISC 0x0000 /* Misc. control */ | |
68 | #define PCIEFD_REG_CAN_CLK_SEL 0x0008 /* Clock selector */ | |
69 | #define PCIEFD_REG_CAN_CMD_PORT_L 0x0010 /* 64-bits command port */ | |
70 | #define PCIEFD_REG_CAN_CMD_PORT_H 0x0014 | |
71 | #define PCIEFD_REG_CAN_TX_REQ_ACC 0x0020 /* Tx request accumulator */ | |
72 | #define PCIEFD_REG_CAN_TX_CTL_SET 0x0030 /* Tx control set register */ | |
73 | #define PCIEFD_REG_CAN_TX_CTL_CLR 0x0038 /* Tx control clear register */ | |
74 | #define PCIEFD_REG_CAN_TX_DMA_ADDR_L 0x0040 /* 64-bits addr for Tx DMA */ | |
75 | #define PCIEFD_REG_CAN_TX_DMA_ADDR_H 0x0044 | |
76 | #define PCIEFD_REG_CAN_RX_CTL_SET 0x0050 /* Rx control set register */ | |
77 | #define PCIEFD_REG_CAN_RX_CTL_CLR 0x0058 /* Rx control clear register */ | |
78 | #define PCIEFD_REG_CAN_RX_CTL_WRT 0x0060 /* Rx control write register */ | |
79 | #define PCIEFD_REG_CAN_RX_CTL_ACK 0x0068 /* Rx control ACK register */ | |
80 | #define PCIEFD_REG_CAN_RX_DMA_ADDR_L 0x0070 /* 64-bits addr for Rx DMA */ | |
81 | #define PCIEFD_REG_CAN_RX_DMA_ADDR_H 0x0074 | |
82 | ||
83 | /* CAN-FD channel misc register bits */ | |
84 | #define CANFD_MISC_TS_RST 0x00000001 /* timestamp cnt rst */ | |
85 | ||
86 | /* CAN-FD channel Clock SELector Source & DIVider */ | |
87 | #define CANFD_CLK_SEL_DIV_MASK 0x00000007 | |
88 | #define CANFD_CLK_SEL_DIV_60MHZ 0x00000000 /* SRC=240MHz only */ | |
89 | #define CANFD_CLK_SEL_DIV_40MHZ 0x00000001 /* SRC=240MHz only */ | |
90 | #define CANFD_CLK_SEL_DIV_30MHZ 0x00000002 /* SRC=240MHz only */ | |
91 | #define CANFD_CLK_SEL_DIV_24MHZ 0x00000003 /* SRC=240MHz only */ | |
92 | #define CANFD_CLK_SEL_DIV_20MHZ 0x00000004 /* SRC=240MHz only */ | |
93 | ||
94 | #define CANFD_CLK_SEL_SRC_MASK 0x00000008 /* 0=80MHz, 1=240MHz */ | |
95 | #define CANFD_CLK_SEL_SRC_240MHZ 0x00000008 | |
96 | #define CANFD_CLK_SEL_SRC_80MHZ (~CANFD_CLK_SEL_SRC_240MHZ & \ | |
97 | CANFD_CLK_SEL_SRC_MASK) | |
98 | ||
99 | #define CANFD_CLK_SEL_20MHZ (CANFD_CLK_SEL_SRC_240MHZ |\ | |
100 | CANFD_CLK_SEL_DIV_20MHZ) | |
101 | #define CANFD_CLK_SEL_24MHZ (CANFD_CLK_SEL_SRC_240MHZ |\ | |
102 | CANFD_CLK_SEL_DIV_24MHZ) | |
103 | #define CANFD_CLK_SEL_30MHZ (CANFD_CLK_SEL_SRC_240MHZ |\ | |
104 | CANFD_CLK_SEL_DIV_30MHZ) | |
105 | #define CANFD_CLK_SEL_40MHZ (CANFD_CLK_SEL_SRC_240MHZ |\ | |
106 | CANFD_CLK_SEL_DIV_40MHZ) | |
107 | #define CANFD_CLK_SEL_60MHZ (CANFD_CLK_SEL_SRC_240MHZ |\ | |
108 | CANFD_CLK_SEL_DIV_60MHZ) | |
109 | #define CANFD_CLK_SEL_80MHZ (CANFD_CLK_SEL_SRC_80MHZ) | |
110 | ||
111 | /* CAN-FD channel Rx/Tx control register bits */ | |
112 | #define CANFD_CTL_UNC_BIT 0x00010000 /* Uncached DMA mem */ | |
113 | #define CANFD_CTL_RST_BIT 0x00020000 /* reset DMA action */ | |
114 | #define CANFD_CTL_IEN_BIT 0x00040000 /* IRQ enable */ | |
115 | ||
116 | /* Rx IRQ Count and Time Limits */ | |
117 | #define CANFD_CTL_IRQ_CL_DEF 16 /* Rx msg max nb per IRQ in Rx DMA */ | |
118 | #define CANFD_CTL_IRQ_TL_DEF 10 /* Time before IRQ if < CL (x100 µs) */ | |
119 | ||
120 | #define CANFD_OPTIONS_SET (CANFD_OPTION_ERROR | CANFD_OPTION_BUSLOAD) | |
121 | ||
122 | /* Tx anticipation window (link logical address should be aligned on 2K | |
123 | * boundary) | |
124 | */ | |
125 | #define PCIEFD_TX_PAGE_COUNT (PCIEFD_TX_DMA_SIZE / PCIEFD_TX_PAGE_SIZE) | |
126 | ||
127 | #define CANFD_MSG_LNK_TX 0x1001 /* Tx msgs link */ | |
128 | ||
129 | /* 32-bits IRQ status fields, heading Rx DMA area */ | |
130 | static inline int pciefd_irq_tag(u32 irq_status) | |
131 | { | |
132 | return irq_status & 0x0000000f; | |
133 | } | |
134 | ||
135 | static inline int pciefd_irq_rx_cnt(u32 irq_status) | |
136 | { | |
137 | return (irq_status & 0x000007f0) >> 4; | |
138 | } | |
139 | ||
140 | static inline int pciefd_irq_is_lnk(u32 irq_status) | |
141 | { | |
142 | return irq_status & 0x00010000; | |
143 | } | |
144 | ||
145 | /* Rx record */ | |
146 | struct pciefd_rx_dma { | |
147 | __le32 irq_status; | |
148 | __le32 sys_time_low; | |
149 | __le32 sys_time_high; | |
150 | struct pucan_rx_msg msg[0]; | |
151 | } __packed __aligned(4); | |
152 | ||
153 | /* Tx Link record */ | |
154 | struct pciefd_tx_link { | |
155 | __le16 size; | |
156 | __le16 type; | |
157 | __le32 laddr_lo; | |
158 | __le32 laddr_hi; | |
159 | } __packed __aligned(4); | |
160 | ||
161 | /* Tx page descriptor */ | |
162 | struct pciefd_page { | |
163 | void *vbase; /* page virtual address */ | |
164 | dma_addr_t lbase; /* page logical address */ | |
165 | u32 offset; | |
166 | u32 size; | |
167 | }; | |
168 | ||
8ac8321e SG |
169 | /* CAN-FD channel object */ |
170 | struct pciefd_board; | |
171 | struct pciefd_can { | |
172 | struct peak_canfd_priv ucan; /* must be the first member */ | |
173 | void __iomem *reg_base; /* channel config base addr */ | |
174 | struct pciefd_board *board; /* reverse link */ | |
175 | ||
176 | struct pucan_command pucan_cmd; /* command buffer */ | |
177 | ||
178 | dma_addr_t rx_dma_laddr; /* DMA virtual and logical addr */ | |
179 | void *rx_dma_vaddr; /* for Rx and Tx areas */ | |
180 | dma_addr_t tx_dma_laddr; | |
181 | void *tx_dma_vaddr; | |
182 | ||
183 | struct pciefd_page tx_pages[PCIEFD_TX_PAGE_COUNT]; | |
184 | u16 tx_pages_free; /* free Tx pages counter */ | |
185 | u16 tx_page_index; /* current page used for Tx */ | |
186 | spinlock_t tx_lock; | |
187 | ||
188 | u32 irq_status; | |
189 | u32 irq_tag; /* next irq tag */ | |
190 | }; | |
191 | ||
192 | /* PEAK-PCIe FD board object */ | |
193 | struct pciefd_board { | |
194 | void __iomem *reg_base; | |
195 | struct pci_dev *pci_dev; | |
196 | int can_count; | |
197 | spinlock_t cmd_lock; /* 64-bits cmds must be atomic */ | |
198 | struct pciefd_can *can[0]; /* array of network devices */ | |
199 | }; | |
200 | ||
201 | /* supported device ids. */ | |
202 | static const struct pci_device_id peak_pciefd_tbl[] = { | |
203 | {PEAK_PCI_VENDOR_ID, PEAK_PCIEFD_ID, PCI_ANY_ID, PCI_ANY_ID,}, | |
4cbdd0ee SG |
204 | {PEAK_PCI_VENDOR_ID, PCAN_CPCIEFD_ID, PCI_ANY_ID, PCI_ANY_ID,}, |
205 | {PEAK_PCI_VENDOR_ID, PCAN_PCIE104FD_ID, PCI_ANY_ID, PCI_ANY_ID,}, | |
206 | {PEAK_PCI_VENDOR_ID, PCAN_MINIPCIEFD_ID, PCI_ANY_ID, PCI_ANY_ID,}, | |
207 | {PEAK_PCI_VENDOR_ID, PCAN_PCIEFD_OEM_ID, PCI_ANY_ID, PCI_ANY_ID,}, | |
208 | {PEAK_PCI_VENDOR_ID, PCAN_M2_ID, PCI_ANY_ID, PCI_ANY_ID,}, | |
8ac8321e SG |
209 | {0,} |
210 | }; | |
211 | ||
212 | MODULE_DEVICE_TABLE(pci, peak_pciefd_tbl); | |
213 | ||
214 | /* read a 32 bits value from a SYS block register */ | |
215 | static inline u32 pciefd_sys_readreg(const struct pciefd_board *priv, u16 reg) | |
216 | { | |
217 | return readl(priv->reg_base + reg); | |
218 | } | |
219 | ||
220 | /* write a 32 bits value into a SYS block register */ | |
221 | static inline void pciefd_sys_writereg(const struct pciefd_board *priv, | |
222 | u32 val, u16 reg) | |
223 | { | |
224 | writel(val, priv->reg_base + reg); | |
225 | } | |
226 | ||
227 | /* read a 32 bits value from CAN-FD block register */ | |
228 | static inline u32 pciefd_can_readreg(const struct pciefd_can *priv, u16 reg) | |
229 | { | |
230 | return readl(priv->reg_base + reg); | |
231 | } | |
232 | ||
233 | /* write a 32 bits value into a CAN-FD block register */ | |
234 | static inline void pciefd_can_writereg(const struct pciefd_can *priv, | |
235 | u32 val, u16 reg) | |
236 | { | |
237 | writel(val, priv->reg_base + reg); | |
238 | } | |
239 | ||
240 | /* give a channel logical Rx DMA address to the board */ | |
241 | static void pciefd_can_setup_rx_dma(struct pciefd_can *priv) | |
242 | { | |
243 | #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT | |
244 | const u32 dma_addr_h = (u32)(priv->rx_dma_laddr >> 32); | |
245 | #else | |
246 | const u32 dma_addr_h = 0; | |
247 | #endif | |
248 | ||
249 | /* (DMA must be reset for Rx) */ | |
250 | pciefd_can_writereg(priv, CANFD_CTL_RST_BIT, PCIEFD_REG_CAN_RX_CTL_SET); | |
251 | ||
252 | /* write the logical address of the Rx DMA area for this channel */ | |
253 | pciefd_can_writereg(priv, (u32)priv->rx_dma_laddr, | |
254 | PCIEFD_REG_CAN_RX_DMA_ADDR_L); | |
255 | pciefd_can_writereg(priv, dma_addr_h, PCIEFD_REG_CAN_RX_DMA_ADDR_H); | |
256 | ||
257 | /* also indicates that Rx DMA is cacheable */ | |
258 | pciefd_can_writereg(priv, CANFD_CTL_UNC_BIT, PCIEFD_REG_CAN_RX_CTL_CLR); | |
259 | } | |
260 | ||
261 | /* clear channel logical Rx DMA address from the board */ | |
262 | static void pciefd_can_clear_rx_dma(struct pciefd_can *priv) | |
263 | { | |
264 | /* DMA must be reset for Rx */ | |
265 | pciefd_can_writereg(priv, CANFD_CTL_RST_BIT, PCIEFD_REG_CAN_RX_CTL_SET); | |
266 | ||
267 | /* clear the logical address of the Rx DMA area for this channel */ | |
268 | pciefd_can_writereg(priv, 0, PCIEFD_REG_CAN_RX_DMA_ADDR_L); | |
269 | pciefd_can_writereg(priv, 0, PCIEFD_REG_CAN_RX_DMA_ADDR_H); | |
270 | } | |
271 | ||
272 | /* give a channel logical Tx DMA address to the board */ | |
273 | static void pciefd_can_setup_tx_dma(struct pciefd_can *priv) | |
274 | { | |
275 | #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT | |
276 | const u32 dma_addr_h = (u32)(priv->tx_dma_laddr >> 32); | |
277 | #else | |
278 | const u32 dma_addr_h = 0; | |
279 | #endif | |
280 | ||
281 | /* (DMA must be reset for Tx) */ | |
282 | pciefd_can_writereg(priv, CANFD_CTL_RST_BIT, PCIEFD_REG_CAN_TX_CTL_SET); | |
283 | ||
284 | /* write the logical address of the Tx DMA area for this channel */ | |
285 | pciefd_can_writereg(priv, (u32)priv->tx_dma_laddr, | |
286 | PCIEFD_REG_CAN_TX_DMA_ADDR_L); | |
287 | pciefd_can_writereg(priv, dma_addr_h, PCIEFD_REG_CAN_TX_DMA_ADDR_H); | |
288 | ||
289 | /* also indicates that Tx DMA is cacheable */ | |
290 | pciefd_can_writereg(priv, CANFD_CTL_UNC_BIT, PCIEFD_REG_CAN_TX_CTL_CLR); | |
291 | } | |
292 | ||
293 | /* clear channel logical Tx DMA address from the board */ | |
294 | static void pciefd_can_clear_tx_dma(struct pciefd_can *priv) | |
295 | { | |
296 | /* DMA must be reset for Tx */ | |
297 | pciefd_can_writereg(priv, CANFD_CTL_RST_BIT, PCIEFD_REG_CAN_TX_CTL_SET); | |
298 | ||
299 | /* clear the logical address of the Tx DMA area for this channel */ | |
300 | pciefd_can_writereg(priv, 0, PCIEFD_REG_CAN_TX_DMA_ADDR_L); | |
301 | pciefd_can_writereg(priv, 0, PCIEFD_REG_CAN_TX_DMA_ADDR_H); | |
302 | } | |
303 | ||
304 | static void pciefd_can_ack_rx_dma(struct pciefd_can *priv) | |
305 | { | |
306 | /* read value of current IRQ tag and inc it for next one */ | |
307 | priv->irq_tag = le32_to_cpu(*(__le32 *)priv->rx_dma_vaddr); | |
308 | priv->irq_tag++; | |
309 | priv->irq_tag &= 0xf; | |
310 | ||
311 | /* write the next IRQ tag for this CAN */ | |
312 | pciefd_can_writereg(priv, priv->irq_tag, PCIEFD_REG_CAN_RX_CTL_ACK); | |
313 | } | |
314 | ||
315 | /* IRQ handler */ | |
316 | static irqreturn_t pciefd_irq_handler(int irq, void *arg) | |
317 | { | |
318 | struct pciefd_can *priv = arg; | |
319 | struct pciefd_rx_dma *rx_dma = priv->rx_dma_vaddr; | |
320 | ||
321 | /* INTA mode only to sync with PCIe transaction */ | |
322 | if (!pci_dev_msi_enabled(priv->board->pci_dev)) | |
323 | (void)pciefd_sys_readreg(priv->board, PCIEFD_REG_SYS_VER1); | |
324 | ||
325 | /* read IRQ status from the first 32-bits of the Rx DMA area */ | |
326 | priv->irq_status = le32_to_cpu(rx_dma->irq_status); | |
327 | ||
328 | /* check if this (shared) IRQ is for this CAN */ | |
329 | if (pciefd_irq_tag(priv->irq_status) != priv->irq_tag) | |
330 | return IRQ_NONE; | |
331 | ||
332 | /* handle rx messages (if any) */ | |
333 | peak_canfd_handle_msgs_list(&priv->ucan, | |
334 | rx_dma->msg, | |
335 | pciefd_irq_rx_cnt(priv->irq_status)); | |
336 | ||
337 | /* handle tx link interrupt (if any) */ | |
338 | if (pciefd_irq_is_lnk(priv->irq_status)) { | |
339 | unsigned long flags; | |
340 | ||
341 | spin_lock_irqsave(&priv->tx_lock, flags); | |
342 | priv->tx_pages_free++; | |
343 | spin_unlock_irqrestore(&priv->tx_lock, flags); | |
344 | ||
e6048a00 SG |
345 | /* wake producer up (only if enough room in echo_skb array) */ |
346 | spin_lock_irqsave(&priv->ucan.echo_lock, flags); | |
347 | if (!priv->ucan.can.echo_skb[priv->ucan.echo_idx]) | |
348 | netif_wake_queue(priv->ucan.ndev); | |
349 | ||
350 | spin_unlock_irqrestore(&priv->ucan.echo_lock, flags); | |
8ac8321e SG |
351 | } |
352 | ||
353 | /* re-enable Rx DMA transfer for this CAN */ | |
354 | pciefd_can_ack_rx_dma(priv); | |
355 | ||
356 | return IRQ_HANDLED; | |
357 | } | |
358 | ||
359 | static int pciefd_enable_tx_path(struct peak_canfd_priv *ucan) | |
360 | { | |
361 | struct pciefd_can *priv = (struct pciefd_can *)ucan; | |
362 | int i; | |
363 | ||
364 | /* initialize the Tx pages descriptors */ | |
365 | priv->tx_pages_free = PCIEFD_TX_PAGE_COUNT - 1; | |
366 | priv->tx_page_index = 0; | |
367 | ||
368 | priv->tx_pages[0].vbase = priv->tx_dma_vaddr; | |
369 | priv->tx_pages[0].lbase = priv->tx_dma_laddr; | |
370 | ||
371 | for (i = 0; i < PCIEFD_TX_PAGE_COUNT; i++) { | |
372 | priv->tx_pages[i].offset = 0; | |
373 | priv->tx_pages[i].size = PCIEFD_TX_PAGE_SIZE - | |
374 | sizeof(struct pciefd_tx_link); | |
375 | if (i) { | |
376 | priv->tx_pages[i].vbase = | |
377 | priv->tx_pages[i - 1].vbase + | |
378 | PCIEFD_TX_PAGE_SIZE; | |
379 | priv->tx_pages[i].lbase = | |
380 | priv->tx_pages[i - 1].lbase + | |
381 | PCIEFD_TX_PAGE_SIZE; | |
382 | } | |
383 | } | |
384 | ||
385 | /* setup Tx DMA addresses into IP core */ | |
386 | pciefd_can_setup_tx_dma(priv); | |
387 | ||
388 | /* start (TX_RST=0) Tx Path */ | |
389 | pciefd_can_writereg(priv, CANFD_CTL_RST_BIT, PCIEFD_REG_CAN_TX_CTL_CLR); | |
390 | ||
391 | return 0; | |
392 | } | |
393 | ||
394 | /* board specific CANFD command pre-processing */ | |
395 | static int pciefd_pre_cmd(struct peak_canfd_priv *ucan) | |
396 | { | |
397 | struct pciefd_can *priv = (struct pciefd_can *)ucan; | |
398 | u16 cmd = pucan_cmd_get_opcode(&priv->pucan_cmd); | |
399 | int err; | |
400 | ||
401 | /* pre-process command */ | |
402 | switch (cmd) { | |
403 | case PUCAN_CMD_NORMAL_MODE: | |
404 | case PUCAN_CMD_LISTEN_ONLY_MODE: | |
405 | ||
406 | if (ucan->can.state == CAN_STATE_BUS_OFF) | |
407 | break; | |
408 | ||
409 | /* going into operational mode: setup IRQ handler */ | |
cc5f9bb0 | 410 | err = request_irq(priv->ucan.ndev->irq, |
8ac8321e SG |
411 | pciefd_irq_handler, |
412 | IRQF_SHARED, | |
413 | PCIEFD_DRV_NAME, | |
414 | priv); | |
415 | if (err) | |
416 | return err; | |
417 | ||
418 | /* setup Rx DMA address */ | |
419 | pciefd_can_setup_rx_dma(priv); | |
420 | ||
421 | /* setup max count of msgs per IRQ */ | |
422 | pciefd_can_writereg(priv, (CANFD_CTL_IRQ_TL_DEF) << 8 | | |
423 | CANFD_CTL_IRQ_CL_DEF, | |
424 | PCIEFD_REG_CAN_RX_CTL_WRT); | |
425 | ||
426 | /* clear DMA RST for Rx (Rx start) */ | |
427 | pciefd_can_writereg(priv, CANFD_CTL_RST_BIT, | |
428 | PCIEFD_REG_CAN_RX_CTL_CLR); | |
429 | ||
430 | /* reset timestamps */ | |
431 | pciefd_can_writereg(priv, !CANFD_MISC_TS_RST, | |
432 | PCIEFD_REG_CAN_MISC); | |
433 | ||
434 | /* do an initial ACK */ | |
435 | pciefd_can_ack_rx_dma(priv); | |
436 | ||
437 | /* enable IRQ for this CAN after having set next irq_tag */ | |
438 | pciefd_can_writereg(priv, CANFD_CTL_IEN_BIT, | |
439 | PCIEFD_REG_CAN_RX_CTL_SET); | |
440 | ||
441 | /* Tx path will be setup as soon as RX_BARRIER is received */ | |
442 | break; | |
443 | default: | |
444 | break; | |
445 | } | |
446 | ||
447 | return 0; | |
448 | } | |
449 | ||
450 | /* write a command */ | |
451 | static int pciefd_write_cmd(struct peak_canfd_priv *ucan) | |
452 | { | |
453 | struct pciefd_can *priv = (struct pciefd_can *)ucan; | |
454 | unsigned long flags; | |
455 | ||
456 | /* 64-bits command is atomic */ | |
457 | spin_lock_irqsave(&priv->board->cmd_lock, flags); | |
458 | ||
459 | pciefd_can_writereg(priv, *(u32 *)ucan->cmd_buffer, | |
460 | PCIEFD_REG_CAN_CMD_PORT_L); | |
461 | pciefd_can_writereg(priv, *(u32 *)(ucan->cmd_buffer + 4), | |
462 | PCIEFD_REG_CAN_CMD_PORT_H); | |
463 | ||
464 | spin_unlock_irqrestore(&priv->board->cmd_lock, flags); | |
465 | ||
466 | return 0; | |
467 | } | |
468 | ||
469 | /* board specific CANFD command post-processing */ | |
470 | static int pciefd_post_cmd(struct peak_canfd_priv *ucan) | |
471 | { | |
472 | struct pciefd_can *priv = (struct pciefd_can *)ucan; | |
473 | u16 cmd = pucan_cmd_get_opcode(&priv->pucan_cmd); | |
474 | ||
475 | switch (cmd) { | |
476 | case PUCAN_CMD_RESET_MODE: | |
477 | ||
478 | if (ucan->can.state == CAN_STATE_STOPPED) | |
479 | break; | |
480 | ||
481 | /* controller now in reset mode: */ | |
482 | ||
5592cd03 SG |
483 | /* disable IRQ for this CAN */ |
484 | pciefd_can_writereg(priv, CANFD_CTL_IEN_BIT, | |
485 | PCIEFD_REG_CAN_RX_CTL_CLR); | |
486 | ||
8ac8321e SG |
487 | /* stop and reset DMA addresses in Tx/Rx engines */ |
488 | pciefd_can_clear_tx_dma(priv); | |
489 | pciefd_can_clear_rx_dma(priv); | |
490 | ||
5592cd03 SG |
491 | /* wait for above commands to complete (read cycle) */ |
492 | (void)pciefd_sys_readreg(priv->board, PCIEFD_REG_SYS_VER1); | |
8ac8321e | 493 | |
cc5f9bb0 | 494 | free_irq(priv->ucan.ndev->irq, priv); |
8ac8321e SG |
495 | |
496 | ucan->can.state = CAN_STATE_STOPPED; | |
497 | ||
498 | break; | |
499 | } | |
500 | ||
501 | return 0; | |
502 | } | |
503 | ||
504 | static void *pciefd_alloc_tx_msg(struct peak_canfd_priv *ucan, u16 msg_size, | |
505 | int *room_left) | |
506 | { | |
507 | struct pciefd_can *priv = (struct pciefd_can *)ucan; | |
508 | struct pciefd_page *page = priv->tx_pages + priv->tx_page_index; | |
509 | unsigned long flags; | |
510 | void *msg; | |
511 | ||
512 | spin_lock_irqsave(&priv->tx_lock, flags); | |
513 | ||
514 | if (page->offset + msg_size > page->size) { | |
515 | struct pciefd_tx_link *lk; | |
516 | ||
517 | /* not enough space in this page: try another one */ | |
518 | if (!priv->tx_pages_free) { | |
519 | spin_unlock_irqrestore(&priv->tx_lock, flags); | |
520 | ||
521 | /* Tx overflow */ | |
522 | return NULL; | |
523 | } | |
524 | ||
525 | priv->tx_pages_free--; | |
526 | ||
527 | /* keep address of the very last free slot of current page */ | |
528 | lk = page->vbase + page->offset; | |
529 | ||
530 | /* next, move on a new free page */ | |
531 | priv->tx_page_index = (priv->tx_page_index + 1) % | |
532 | PCIEFD_TX_PAGE_COUNT; | |
533 | page = priv->tx_pages + priv->tx_page_index; | |
534 | ||
535 | /* put link record to this new page at the end of prev one */ | |
536 | lk->size = cpu_to_le16(sizeof(*lk)); | |
537 | lk->type = cpu_to_le16(CANFD_MSG_LNK_TX); | |
538 | lk->laddr_lo = cpu_to_le32(page->lbase); | |
539 | ||
540 | #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT | |
541 | lk->laddr_hi = cpu_to_le32(page->lbase >> 32); | |
542 | #else | |
543 | lk->laddr_hi = 0; | |
544 | #endif | |
545 | /* next msgs will be put from the begininng of this new page */ | |
546 | page->offset = 0; | |
547 | } | |
548 | ||
549 | *room_left = priv->tx_pages_free * page->size; | |
550 | ||
551 | spin_unlock_irqrestore(&priv->tx_lock, flags); | |
552 | ||
553 | msg = page->vbase + page->offset; | |
554 | ||
555 | /* give back room left in the tx ring */ | |
556 | *room_left += page->size - (page->offset + msg_size); | |
557 | ||
558 | return msg; | |
559 | } | |
560 | ||
561 | static int pciefd_write_tx_msg(struct peak_canfd_priv *ucan, | |
562 | struct pucan_tx_msg *msg) | |
563 | { | |
564 | struct pciefd_can *priv = (struct pciefd_can *)ucan; | |
565 | struct pciefd_page *page = priv->tx_pages + priv->tx_page_index; | |
566 | ||
567 | /* this slot is now reserved for writing the frame */ | |
568 | page->offset += le16_to_cpu(msg->size); | |
569 | ||
570 | /* tell the board a frame has been written in Tx DMA area */ | |
571 | pciefd_can_writereg(priv, 1, PCIEFD_REG_CAN_TX_REQ_ACC); | |
572 | ||
573 | return 0; | |
574 | } | |
575 | ||
576 | /* probe for CAN-FD channel #pciefd_board->can_count */ | |
577 | static int pciefd_can_probe(struct pciefd_board *pciefd) | |
578 | { | |
579 | struct net_device *ndev; | |
580 | struct pciefd_can *priv; | |
581 | u32 clk; | |
582 | int err; | |
583 | ||
584 | /* allocate the candev object with default isize of echo skbs ring */ | |
585 | ndev = alloc_peak_canfd_dev(sizeof(*priv), pciefd->can_count, | |
586 | PCIEFD_ECHO_SKB_MAX); | |
587 | if (!ndev) { | |
588 | dev_err(&pciefd->pci_dev->dev, | |
589 | "failed to alloc candev object\n"); | |
590 | goto failure; | |
591 | } | |
592 | ||
593 | priv = netdev_priv(ndev); | |
594 | ||
595 | /* fill-in candev private object: */ | |
596 | ||
597 | /* setup PCIe-FD own callbacks */ | |
598 | priv->ucan.pre_cmd = pciefd_pre_cmd; | |
599 | priv->ucan.write_cmd = pciefd_write_cmd; | |
600 | priv->ucan.post_cmd = pciefd_post_cmd; | |
601 | priv->ucan.enable_tx_path = pciefd_enable_tx_path; | |
602 | priv->ucan.alloc_tx_msg = pciefd_alloc_tx_msg; | |
603 | priv->ucan.write_tx_msg = pciefd_write_tx_msg; | |
604 | ||
605 | /* setup PCIe-FD own command buffer */ | |
606 | priv->ucan.cmd_buffer = &priv->pucan_cmd; | |
607 | priv->ucan.cmd_maxlen = sizeof(priv->pucan_cmd); | |
608 | ||
609 | priv->board = pciefd; | |
610 | ||
611 | /* CAN config regs block address */ | |
612 | priv->reg_base = pciefd->reg_base + PCIEFD_CANX_OFF(priv->ucan.index); | |
613 | ||
614 | /* allocate non-cacheable DMA'able 4KB memory area for Rx */ | |
615 | priv->rx_dma_vaddr = dmam_alloc_coherent(&pciefd->pci_dev->dev, | |
616 | PCIEFD_RX_DMA_SIZE, | |
617 | &priv->rx_dma_laddr, | |
618 | GFP_KERNEL); | |
619 | if (!priv->rx_dma_vaddr) { | |
620 | dev_err(&pciefd->pci_dev->dev, | |
621 | "Rx dmam_alloc_coherent(%u) failure\n", | |
622 | PCIEFD_RX_DMA_SIZE); | |
623 | goto err_free_candev; | |
624 | } | |
625 | ||
626 | /* allocate non-cacheable DMA'able 4KB memory area for Tx */ | |
627 | priv->tx_dma_vaddr = dmam_alloc_coherent(&pciefd->pci_dev->dev, | |
628 | PCIEFD_TX_DMA_SIZE, | |
629 | &priv->tx_dma_laddr, | |
630 | GFP_KERNEL); | |
631 | if (!priv->tx_dma_vaddr) { | |
632 | dev_err(&pciefd->pci_dev->dev, | |
d31f8513 | 633 | "Tx dmam_alloc_coherent(%u) failure\n", |
8ac8321e SG |
634 | PCIEFD_TX_DMA_SIZE); |
635 | goto err_free_candev; | |
636 | } | |
637 | ||
638 | /* CAN clock in RST mode */ | |
639 | pciefd_can_writereg(priv, CANFD_MISC_TS_RST, PCIEFD_REG_CAN_MISC); | |
640 | ||
641 | /* read current clock value */ | |
642 | clk = pciefd_can_readreg(priv, PCIEFD_REG_CAN_CLK_SEL); | |
643 | switch (clk) { | |
644 | case CANFD_CLK_SEL_20MHZ: | |
645 | priv->ucan.can.clock.freq = 20 * 1000 * 1000; | |
646 | break; | |
647 | case CANFD_CLK_SEL_24MHZ: | |
648 | priv->ucan.can.clock.freq = 24 * 1000 * 1000; | |
649 | break; | |
650 | case CANFD_CLK_SEL_30MHZ: | |
651 | priv->ucan.can.clock.freq = 30 * 1000 * 1000; | |
652 | break; | |
653 | case CANFD_CLK_SEL_40MHZ: | |
654 | priv->ucan.can.clock.freq = 40 * 1000 * 1000; | |
655 | break; | |
656 | case CANFD_CLK_SEL_60MHZ: | |
657 | priv->ucan.can.clock.freq = 60 * 1000 * 1000; | |
658 | break; | |
659 | default: | |
660 | pciefd_can_writereg(priv, CANFD_CLK_SEL_80MHZ, | |
661 | PCIEFD_REG_CAN_CLK_SEL); | |
662 | ||
5a8dadbc | 663 | /* fall through */ |
8ac8321e SG |
664 | case CANFD_CLK_SEL_80MHZ: |
665 | priv->ucan.can.clock.freq = 80 * 1000 * 1000; | |
666 | break; | |
667 | } | |
668 | ||
669 | ndev->irq = pciefd->pci_dev->irq; | |
670 | ||
671 | SET_NETDEV_DEV(ndev, &pciefd->pci_dev->dev); | |
672 | ||
673 | err = register_candev(ndev); | |
674 | if (err) { | |
675 | dev_err(&pciefd->pci_dev->dev, | |
676 | "couldn't register CAN device: %d\n", err); | |
677 | goto err_free_candev; | |
678 | } | |
679 | ||
680 | spin_lock_init(&priv->tx_lock); | |
681 | ||
682 | /* save the object address in the board structure */ | |
683 | pciefd->can[pciefd->can_count] = priv; | |
684 | ||
685 | dev_info(&pciefd->pci_dev->dev, "%s at reg_base=0x%p irq=%d\n", | |
cc5f9bb0 | 686 | ndev->name, priv->reg_base, ndev->irq); |
8ac8321e SG |
687 | |
688 | return 0; | |
689 | ||
690 | err_free_candev: | |
691 | free_candev(ndev); | |
692 | ||
693 | failure: | |
694 | return -ENOMEM; | |
695 | } | |
696 | ||
697 | /* remove a CAN-FD channel by releasing all of its resources */ | |
698 | static void pciefd_can_remove(struct pciefd_can *priv) | |
699 | { | |
700 | /* unregister (close) the can device to go back to RST mode first */ | |
701 | unregister_candev(priv->ucan.ndev); | |
702 | ||
703 | /* finally, free the candev object */ | |
704 | free_candev(priv->ucan.ndev); | |
705 | } | |
706 | ||
707 | /* remove all CAN-FD channels by releasing their own resources */ | |
708 | static void pciefd_can_remove_all(struct pciefd_board *pciefd) | |
709 | { | |
710 | while (pciefd->can_count > 0) | |
711 | pciefd_can_remove(pciefd->can[--pciefd->can_count]); | |
712 | } | |
713 | ||
714 | /* probe for the entire device */ | |
715 | static int peak_pciefd_probe(struct pci_dev *pdev, | |
716 | const struct pci_device_id *ent) | |
717 | { | |
718 | struct pciefd_board *pciefd; | |
719 | int err, can_count; | |
720 | u16 sub_sys_id; | |
721 | u8 hw_ver_major; | |
722 | u8 hw_ver_minor; | |
723 | u8 hw_ver_sub; | |
724 | u32 v2; | |
725 | ||
726 | err = pci_enable_device(pdev); | |
727 | if (err) | |
728 | return err; | |
729 | err = pci_request_regions(pdev, PCIEFD_DRV_NAME); | |
730 | if (err) | |
731 | goto err_disable_pci; | |
732 | ||
733 | /* the number of channels depends on sub-system id */ | |
734 | err = pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &sub_sys_id); | |
735 | if (err) | |
736 | goto err_release_regions; | |
737 | ||
738 | dev_dbg(&pdev->dev, "probing device %04x:%04x:%04x\n", | |
739 | pdev->vendor, pdev->device, sub_sys_id); | |
740 | ||
741 | if (sub_sys_id >= 0x0012) | |
742 | can_count = 4; | |
743 | else if (sub_sys_id >= 0x0010) | |
744 | can_count = 3; | |
745 | else if (sub_sys_id >= 0x0004) | |
746 | can_count = 2; | |
747 | else | |
748 | can_count = 1; | |
749 | ||
750 | /* allocate board structure object */ | |
0ed2dd03 | 751 | pciefd = devm_kzalloc(&pdev->dev, struct_size(pciefd, can, can_count), |
8ac8321e SG |
752 | GFP_KERNEL); |
753 | if (!pciefd) { | |
754 | err = -ENOMEM; | |
755 | goto err_release_regions; | |
756 | } | |
757 | ||
758 | /* initialize the board structure */ | |
759 | pciefd->pci_dev = pdev; | |
760 | spin_lock_init(&pciefd->cmd_lock); | |
761 | ||
762 | /* save the PCI BAR0 virtual address for further system regs access */ | |
763 | pciefd->reg_base = pci_iomap(pdev, 0, PCIEFD_BAR0_SIZE); | |
764 | if (!pciefd->reg_base) { | |
765 | dev_err(&pdev->dev, "failed to map PCI resource #0\n"); | |
766 | err = -ENOMEM; | |
767 | goto err_release_regions; | |
768 | } | |
769 | ||
770 | /* read the firmware version number */ | |
771 | v2 = pciefd_sys_readreg(pciefd, PCIEFD_REG_SYS_VER2); | |
772 | ||
773 | hw_ver_major = (v2 & 0x0000f000) >> 12; | |
774 | hw_ver_minor = (v2 & 0x00000f00) >> 8; | |
775 | hw_ver_sub = (v2 & 0x000000f0) >> 4; | |
776 | ||
777 | dev_info(&pdev->dev, | |
778 | "%ux CAN-FD PCAN-PCIe FPGA v%u.%u.%u:\n", can_count, | |
779 | hw_ver_major, hw_ver_minor, hw_ver_sub); | |
780 | ||
5d4c94ed SG |
781 | #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT |
782 | /* FW < v3.3.0 DMA logic doesn't handle correctly the mix of 32-bit and | |
783 | * 64-bit logical addresses: this workaround forces usage of 32-bit | |
784 | * DMA addresses only when such a fw is detected. | |
785 | */ | |
786 | if (PCIEFD_FW_VERSION(hw_ver_major, hw_ver_minor, hw_ver_sub) < | |
787 | PCIEFD_FW_VERSION(3, 3, 0)) { | |
788 | err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); | |
789 | if (err) | |
790 | dev_warn(&pdev->dev, | |
791 | "warning: can't set DMA mask %llxh (err %d)\n", | |
792 | DMA_BIT_MASK(32), err); | |
793 | } | |
794 | #endif | |
795 | ||
8ac8321e SG |
796 | /* stop system clock */ |
797 | pciefd_sys_writereg(pciefd, PCIEFD_SYS_CTL_CLK_EN, | |
798 | PCIEFD_REG_SYS_CTL_CLR); | |
799 | ||
800 | pci_set_master(pdev); | |
801 | ||
802 | /* create now the corresponding channels objects */ | |
803 | while (pciefd->can_count < can_count) { | |
804 | err = pciefd_can_probe(pciefd); | |
805 | if (err) | |
806 | goto err_free_canfd; | |
807 | ||
808 | pciefd->can_count++; | |
809 | } | |
810 | ||
811 | /* set system timestamps counter in RST mode */ | |
812 | pciefd_sys_writereg(pciefd, PCIEFD_SYS_CTL_TS_RST, | |
813 | PCIEFD_REG_SYS_CTL_SET); | |
814 | ||
815 | /* wait a bit (read cycle) */ | |
816 | (void)pciefd_sys_readreg(pciefd, PCIEFD_REG_SYS_VER1); | |
817 | ||
818 | /* free all clocks */ | |
819 | pciefd_sys_writereg(pciefd, PCIEFD_SYS_CTL_TS_RST, | |
820 | PCIEFD_REG_SYS_CTL_CLR); | |
821 | ||
822 | /* start system clock */ | |
823 | pciefd_sys_writereg(pciefd, PCIEFD_SYS_CTL_CLK_EN, | |
824 | PCIEFD_REG_SYS_CTL_SET); | |
825 | ||
826 | /* remember the board structure address in the device user data */ | |
827 | pci_set_drvdata(pdev, pciefd); | |
828 | ||
829 | return 0; | |
830 | ||
831 | err_free_canfd: | |
832 | pciefd_can_remove_all(pciefd); | |
833 | ||
834 | pci_iounmap(pdev, pciefd->reg_base); | |
835 | ||
836 | err_release_regions: | |
837 | pci_release_regions(pdev); | |
838 | ||
839 | err_disable_pci: | |
840 | pci_disable_device(pdev); | |
841 | ||
5c2cb02e SG |
842 | /* pci_xxx_config_word() return positive PCIBIOS_xxx error codes while |
843 | * the probe() function must return a negative errno in case of failure | |
844 | * (err is unchanged if negative) */ | |
845 | return pcibios_err_to_errno(err); | |
8ac8321e SG |
846 | } |
847 | ||
848 | /* free the board structure object, as well as its resources: */ | |
849 | static void peak_pciefd_remove(struct pci_dev *pdev) | |
850 | { | |
851 | struct pciefd_board *pciefd = pci_get_drvdata(pdev); | |
852 | ||
853 | /* release CAN-FD channels resources */ | |
854 | pciefd_can_remove_all(pciefd); | |
855 | ||
856 | pci_iounmap(pdev, pciefd->reg_base); | |
857 | ||
858 | pci_release_regions(pdev); | |
859 | pci_disable_device(pdev); | |
860 | } | |
861 | ||
862 | static struct pci_driver peak_pciefd_driver = { | |
863 | .name = PCIEFD_DRV_NAME, | |
864 | .id_table = peak_pciefd_tbl, | |
865 | .probe = peak_pciefd_probe, | |
866 | .remove = peak_pciefd_remove, | |
867 | }; | |
868 | ||
869 | module_pci_driver(peak_pciefd_driver); |