]>
Commit | Line | Data |
---|---|---|
8ac8321e SG |
1 | /* |
2 | * Copyright (C) 2007, 2011 Wolfgang Grandegger <wg@grandegger.com> | |
3 | * Copyright (C) 2012 Stephane Grosjean <s.grosjean@peak-system.com> | |
4 | * | |
5 | * Derived from the PCAN project file driver/src/pcan_pci.c: | |
6 | * | |
7 | * Copyright (C) 2001-2006 PEAK System-Technik GmbH | |
8 | * | |
9 | * This program is free software; you can redistribute it and/or modify | |
10 | * it under the terms of the version 2 of the GNU General Public License | |
11 | * as published by the Free Software Foundation | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | * GNU General Public License for more details. | |
17 | */ | |
18 | ||
19 | #include <linux/kernel.h> | |
20 | #include <linux/module.h> | |
21 | #include <linux/interrupt.h> | |
22 | #include <linux/netdevice.h> | |
23 | #include <linux/delay.h> | |
24 | #include <linux/pci.h> | |
25 | #include <linux/io.h> | |
26 | #include <linux/can.h> | |
27 | #include <linux/can/dev.h> | |
28 | ||
29 | #include "peak_canfd_user.h" | |
30 | ||
31 | MODULE_AUTHOR("Stephane Grosjean <s.grosjean@peak-system.com>"); | |
3ff8ad1f SG |
32 | MODULE_DESCRIPTION("Socket-CAN driver for PEAK PCAN PCIe/M.2 FD family cards"); |
33 | MODULE_SUPPORTED_DEVICE("PEAK PCAN PCIe/M.2 FD CAN cards"); | |
8ac8321e SG |
34 | MODULE_LICENSE("GPL v2"); |
35 | ||
36 | #define PCIEFD_DRV_NAME "peak_pciefd" | |
37 | ||
38 | #define PEAK_PCI_VENDOR_ID 0x001c /* The PCI device and vendor IDs */ | |
39 | #define PEAK_PCIEFD_ID 0x0013 /* for PCIe slot cards */ | |
3ff8ad1f SG |
40 | #define PCAN_CPCIEFD_ID 0x0014 /* for Compact-PCI Serial slot cards */ |
41 | #define PCAN_PCIE104FD_ID 0x0017 /* for PCIe-104 Express slot cards */ | |
42 | #define PCAN_MINIPCIEFD_ID 0x0018 /* for mini-PCIe slot cards */ | |
43 | #define PCAN_PCIEFD_OEM_ID 0x0019 /* for PCIe slot OEM cards */ | |
44 | #define PCAN_M2_ID 0x001a /* for M2 slot cards */ | |
8ac8321e SG |
45 | |
46 | /* PEAK PCIe board access description */ | |
47 | #define PCIEFD_BAR0_SIZE (64 * 1024) | |
48 | #define PCIEFD_RX_DMA_SIZE (4 * 1024) | |
49 | #define PCIEFD_TX_DMA_SIZE (4 * 1024) | |
50 | ||
51 | #define PCIEFD_TX_PAGE_SIZE (2 * 1024) | |
52 | ||
53 | /* System Control Registers */ | |
54 | #define PCIEFD_REG_SYS_CTL_SET 0x0000 /* set bits */ | |
55 | #define PCIEFD_REG_SYS_CTL_CLR 0x0004 /* clear bits */ | |
56 | ||
57 | /* Version info registers */ | |
58 | #define PCIEFD_REG_SYS_VER1 0x0040 /* version reg #1 */ | |
59 | #define PCIEFD_REG_SYS_VER2 0x0044 /* version reg #2 */ | |
60 | ||
61 | /* System Control Registers Bits */ | |
62 | #define PCIEFD_SYS_CTL_TS_RST 0x00000001 /* timestamp clock */ | |
63 | #define PCIEFD_SYS_CTL_CLK_EN 0x00000002 /* system clock */ | |
64 | ||
65 | /* CAN-FD channel addresses */ | |
66 | #define PCIEFD_CANX_OFF(c) (((c) + 1) * 0x1000) | |
67 | ||
68 | #define PCIEFD_ECHO_SKB_MAX PCANFD_ECHO_SKB_DEF | |
69 | ||
70 | /* CAN-FD channel registers */ | |
71 | #define PCIEFD_REG_CAN_MISC 0x0000 /* Misc. control */ | |
72 | #define PCIEFD_REG_CAN_CLK_SEL 0x0008 /* Clock selector */ | |
73 | #define PCIEFD_REG_CAN_CMD_PORT_L 0x0010 /* 64-bits command port */ | |
74 | #define PCIEFD_REG_CAN_CMD_PORT_H 0x0014 | |
75 | #define PCIEFD_REG_CAN_TX_REQ_ACC 0x0020 /* Tx request accumulator */ | |
76 | #define PCIEFD_REG_CAN_TX_CTL_SET 0x0030 /* Tx control set register */ | |
77 | #define PCIEFD_REG_CAN_TX_CTL_CLR 0x0038 /* Tx control clear register */ | |
78 | #define PCIEFD_REG_CAN_TX_DMA_ADDR_L 0x0040 /* 64-bits addr for Tx DMA */ | |
79 | #define PCIEFD_REG_CAN_TX_DMA_ADDR_H 0x0044 | |
80 | #define PCIEFD_REG_CAN_RX_CTL_SET 0x0050 /* Rx control set register */ | |
81 | #define PCIEFD_REG_CAN_RX_CTL_CLR 0x0058 /* Rx control clear register */ | |
82 | #define PCIEFD_REG_CAN_RX_CTL_WRT 0x0060 /* Rx control write register */ | |
83 | #define PCIEFD_REG_CAN_RX_CTL_ACK 0x0068 /* Rx control ACK register */ | |
84 | #define PCIEFD_REG_CAN_RX_DMA_ADDR_L 0x0070 /* 64-bits addr for Rx DMA */ | |
85 | #define PCIEFD_REG_CAN_RX_DMA_ADDR_H 0x0074 | |
86 | ||
87 | /* CAN-FD channel misc register bits */ | |
88 | #define CANFD_MISC_TS_RST 0x00000001 /* timestamp cnt rst */ | |
89 | ||
90 | /* CAN-FD channel Clock SELector Source & DIVider */ | |
91 | #define CANFD_CLK_SEL_DIV_MASK 0x00000007 | |
92 | #define CANFD_CLK_SEL_DIV_60MHZ 0x00000000 /* SRC=240MHz only */ | |
93 | #define CANFD_CLK_SEL_DIV_40MHZ 0x00000001 /* SRC=240MHz only */ | |
94 | #define CANFD_CLK_SEL_DIV_30MHZ 0x00000002 /* SRC=240MHz only */ | |
95 | #define CANFD_CLK_SEL_DIV_24MHZ 0x00000003 /* SRC=240MHz only */ | |
96 | #define CANFD_CLK_SEL_DIV_20MHZ 0x00000004 /* SRC=240MHz only */ | |
97 | ||
98 | #define CANFD_CLK_SEL_SRC_MASK 0x00000008 /* 0=80MHz, 1=240MHz */ | |
99 | #define CANFD_CLK_SEL_SRC_240MHZ 0x00000008 | |
100 | #define CANFD_CLK_SEL_SRC_80MHZ (~CANFD_CLK_SEL_SRC_240MHZ & \ | |
101 | CANFD_CLK_SEL_SRC_MASK) | |
102 | ||
103 | #define CANFD_CLK_SEL_20MHZ (CANFD_CLK_SEL_SRC_240MHZ |\ | |
104 | CANFD_CLK_SEL_DIV_20MHZ) | |
105 | #define CANFD_CLK_SEL_24MHZ (CANFD_CLK_SEL_SRC_240MHZ |\ | |
106 | CANFD_CLK_SEL_DIV_24MHZ) | |
107 | #define CANFD_CLK_SEL_30MHZ (CANFD_CLK_SEL_SRC_240MHZ |\ | |
108 | CANFD_CLK_SEL_DIV_30MHZ) | |
109 | #define CANFD_CLK_SEL_40MHZ (CANFD_CLK_SEL_SRC_240MHZ |\ | |
110 | CANFD_CLK_SEL_DIV_40MHZ) | |
111 | #define CANFD_CLK_SEL_60MHZ (CANFD_CLK_SEL_SRC_240MHZ |\ | |
112 | CANFD_CLK_SEL_DIV_60MHZ) | |
113 | #define CANFD_CLK_SEL_80MHZ (CANFD_CLK_SEL_SRC_80MHZ) | |
114 | ||
115 | /* CAN-FD channel Rx/Tx control register bits */ | |
116 | #define CANFD_CTL_UNC_BIT 0x00010000 /* Uncached DMA mem */ | |
117 | #define CANFD_CTL_RST_BIT 0x00020000 /* reset DMA action */ | |
118 | #define CANFD_CTL_IEN_BIT 0x00040000 /* IRQ enable */ | |
119 | ||
120 | /* Rx IRQ Count and Time Limits */ | |
121 | #define CANFD_CTL_IRQ_CL_DEF 16 /* Rx msg max nb per IRQ in Rx DMA */ | |
122 | #define CANFD_CTL_IRQ_TL_DEF 10 /* Time before IRQ if < CL (x100 µs) */ | |
123 | ||
124 | #define CANFD_OPTIONS_SET (CANFD_OPTION_ERROR | CANFD_OPTION_BUSLOAD) | |
125 | ||
126 | /* Tx anticipation window (link logical address should be aligned on 2K | |
127 | * boundary) | |
128 | */ | |
129 | #define PCIEFD_TX_PAGE_COUNT (PCIEFD_TX_DMA_SIZE / PCIEFD_TX_PAGE_SIZE) | |
130 | ||
131 | #define CANFD_MSG_LNK_TX 0x1001 /* Tx msgs link */ | |
132 | ||
133 | /* 32-bits IRQ status fields, heading Rx DMA area */ | |
134 | static inline int pciefd_irq_tag(u32 irq_status) | |
135 | { | |
136 | return irq_status & 0x0000000f; | |
137 | } | |
138 | ||
139 | static inline int pciefd_irq_rx_cnt(u32 irq_status) | |
140 | { | |
141 | return (irq_status & 0x000007f0) >> 4; | |
142 | } | |
143 | ||
144 | static inline int pciefd_irq_is_lnk(u32 irq_status) | |
145 | { | |
146 | return irq_status & 0x00010000; | |
147 | } | |
148 | ||
149 | /* Rx record */ | |
150 | struct pciefd_rx_dma { | |
151 | __le32 irq_status; | |
152 | __le32 sys_time_low; | |
153 | __le32 sys_time_high; | |
154 | struct pucan_rx_msg msg[0]; | |
155 | } __packed __aligned(4); | |
156 | ||
157 | /* Tx Link record */ | |
158 | struct pciefd_tx_link { | |
159 | __le16 size; | |
160 | __le16 type; | |
161 | __le32 laddr_lo; | |
162 | __le32 laddr_hi; | |
163 | } __packed __aligned(4); | |
164 | ||
165 | /* Tx page descriptor */ | |
166 | struct pciefd_page { | |
167 | void *vbase; /* page virtual address */ | |
168 | dma_addr_t lbase; /* page logical address */ | |
169 | u32 offset; | |
170 | u32 size; | |
171 | }; | |
172 | ||
173 | #define CANFD_IRQ_SET 0x00000001 | |
174 | #define CANFD_TX_PATH_SET 0x00000002 | |
175 | ||
176 | /* CAN-FD channel object */ | |
177 | struct pciefd_board; | |
178 | struct pciefd_can { | |
179 | struct peak_canfd_priv ucan; /* must be the first member */ | |
180 | void __iomem *reg_base; /* channel config base addr */ | |
181 | struct pciefd_board *board; /* reverse link */ | |
182 | ||
183 | struct pucan_command pucan_cmd; /* command buffer */ | |
184 | ||
185 | dma_addr_t rx_dma_laddr; /* DMA virtual and logical addr */ | |
186 | void *rx_dma_vaddr; /* for Rx and Tx areas */ | |
187 | dma_addr_t tx_dma_laddr; | |
188 | void *tx_dma_vaddr; | |
189 | ||
190 | struct pciefd_page tx_pages[PCIEFD_TX_PAGE_COUNT]; | |
191 | u16 tx_pages_free; /* free Tx pages counter */ | |
192 | u16 tx_page_index; /* current page used for Tx */ | |
193 | spinlock_t tx_lock; | |
194 | ||
195 | u32 irq_status; | |
196 | u32 irq_tag; /* next irq tag */ | |
197 | }; | |
198 | ||
199 | /* PEAK-PCIe FD board object */ | |
200 | struct pciefd_board { | |
201 | void __iomem *reg_base; | |
202 | struct pci_dev *pci_dev; | |
203 | int can_count; | |
204 | spinlock_t cmd_lock; /* 64-bits cmds must be atomic */ | |
205 | struct pciefd_can *can[0]; /* array of network devices */ | |
206 | }; | |
207 | ||
208 | /* supported device ids. */ | |
209 | static const struct pci_device_id peak_pciefd_tbl[] = { | |
210 | {PEAK_PCI_VENDOR_ID, PEAK_PCIEFD_ID, PCI_ANY_ID, PCI_ANY_ID,}, | |
3ff8ad1f SG |
211 | {PEAK_PCI_VENDOR_ID, PCAN_CPCIEFD_ID, PCI_ANY_ID, PCI_ANY_ID,}, |
212 | {PEAK_PCI_VENDOR_ID, PCAN_PCIE104FD_ID, PCI_ANY_ID, PCI_ANY_ID,}, | |
213 | {PEAK_PCI_VENDOR_ID, PCAN_MINIPCIEFD_ID, PCI_ANY_ID, PCI_ANY_ID,}, | |
214 | {PEAK_PCI_VENDOR_ID, PCAN_PCIEFD_OEM_ID, PCI_ANY_ID, PCI_ANY_ID,}, | |
215 | {PEAK_PCI_VENDOR_ID, PCAN_M2_ID, PCI_ANY_ID, PCI_ANY_ID,}, | |
8ac8321e SG |
216 | {0,} |
217 | }; | |
218 | ||
219 | MODULE_DEVICE_TABLE(pci, peak_pciefd_tbl); | |
220 | ||
221 | /* read a 32 bits value from a SYS block register */ | |
222 | static inline u32 pciefd_sys_readreg(const struct pciefd_board *priv, u16 reg) | |
223 | { | |
224 | return readl(priv->reg_base + reg); | |
225 | } | |
226 | ||
227 | /* write a 32 bits value into a SYS block register */ | |
228 | static inline void pciefd_sys_writereg(const struct pciefd_board *priv, | |
229 | u32 val, u16 reg) | |
230 | { | |
231 | writel(val, priv->reg_base + reg); | |
232 | } | |
233 | ||
234 | /* read a 32 bits value from CAN-FD block register */ | |
235 | static inline u32 pciefd_can_readreg(const struct pciefd_can *priv, u16 reg) | |
236 | { | |
237 | return readl(priv->reg_base + reg); | |
238 | } | |
239 | ||
240 | /* write a 32 bits value into a CAN-FD block register */ | |
241 | static inline void pciefd_can_writereg(const struct pciefd_can *priv, | |
242 | u32 val, u16 reg) | |
243 | { | |
244 | writel(val, priv->reg_base + reg); | |
245 | } | |
246 | ||
247 | /* give a channel logical Rx DMA address to the board */ | |
248 | static void pciefd_can_setup_rx_dma(struct pciefd_can *priv) | |
249 | { | |
250 | #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT | |
251 | const u32 dma_addr_h = (u32)(priv->rx_dma_laddr >> 32); | |
252 | #else | |
253 | const u32 dma_addr_h = 0; | |
254 | #endif | |
255 | ||
256 | /* (DMA must be reset for Rx) */ | |
257 | pciefd_can_writereg(priv, CANFD_CTL_RST_BIT, PCIEFD_REG_CAN_RX_CTL_SET); | |
258 | ||
259 | /* write the logical address of the Rx DMA area for this channel */ | |
260 | pciefd_can_writereg(priv, (u32)priv->rx_dma_laddr, | |
261 | PCIEFD_REG_CAN_RX_DMA_ADDR_L); | |
262 | pciefd_can_writereg(priv, dma_addr_h, PCIEFD_REG_CAN_RX_DMA_ADDR_H); | |
263 | ||
264 | /* also indicates that Rx DMA is cacheable */ | |
265 | pciefd_can_writereg(priv, CANFD_CTL_UNC_BIT, PCIEFD_REG_CAN_RX_CTL_CLR); | |
266 | } | |
267 | ||
268 | /* clear channel logical Rx DMA address from the board */ | |
269 | static void pciefd_can_clear_rx_dma(struct pciefd_can *priv) | |
270 | { | |
271 | /* DMA must be reset for Rx */ | |
272 | pciefd_can_writereg(priv, CANFD_CTL_RST_BIT, PCIEFD_REG_CAN_RX_CTL_SET); | |
273 | ||
274 | /* clear the logical address of the Rx DMA area for this channel */ | |
275 | pciefd_can_writereg(priv, 0, PCIEFD_REG_CAN_RX_DMA_ADDR_L); | |
276 | pciefd_can_writereg(priv, 0, PCIEFD_REG_CAN_RX_DMA_ADDR_H); | |
277 | } | |
278 | ||
279 | /* give a channel logical Tx DMA address to the board */ | |
280 | static void pciefd_can_setup_tx_dma(struct pciefd_can *priv) | |
281 | { | |
282 | #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT | |
283 | const u32 dma_addr_h = (u32)(priv->tx_dma_laddr >> 32); | |
284 | #else | |
285 | const u32 dma_addr_h = 0; | |
286 | #endif | |
287 | ||
288 | /* (DMA must be reset for Tx) */ | |
289 | pciefd_can_writereg(priv, CANFD_CTL_RST_BIT, PCIEFD_REG_CAN_TX_CTL_SET); | |
290 | ||
291 | /* write the logical address of the Tx DMA area for this channel */ | |
292 | pciefd_can_writereg(priv, (u32)priv->tx_dma_laddr, | |
293 | PCIEFD_REG_CAN_TX_DMA_ADDR_L); | |
294 | pciefd_can_writereg(priv, dma_addr_h, PCIEFD_REG_CAN_TX_DMA_ADDR_H); | |
295 | ||
296 | /* also indicates that Tx DMA is cacheable */ | |
297 | pciefd_can_writereg(priv, CANFD_CTL_UNC_BIT, PCIEFD_REG_CAN_TX_CTL_CLR); | |
298 | } | |
299 | ||
300 | /* clear channel logical Tx DMA address from the board */ | |
301 | static void pciefd_can_clear_tx_dma(struct pciefd_can *priv) | |
302 | { | |
303 | /* DMA must be reset for Tx */ | |
304 | pciefd_can_writereg(priv, CANFD_CTL_RST_BIT, PCIEFD_REG_CAN_TX_CTL_SET); | |
305 | ||
306 | /* clear the logical address of the Tx DMA area for this channel */ | |
307 | pciefd_can_writereg(priv, 0, PCIEFD_REG_CAN_TX_DMA_ADDR_L); | |
308 | pciefd_can_writereg(priv, 0, PCIEFD_REG_CAN_TX_DMA_ADDR_H); | |
309 | } | |
310 | ||
311 | static void pciefd_can_ack_rx_dma(struct pciefd_can *priv) | |
312 | { | |
313 | /* read value of current IRQ tag and inc it for next one */ | |
314 | priv->irq_tag = le32_to_cpu(*(__le32 *)priv->rx_dma_vaddr); | |
315 | priv->irq_tag++; | |
316 | priv->irq_tag &= 0xf; | |
317 | ||
318 | /* write the next IRQ tag for this CAN */ | |
319 | pciefd_can_writereg(priv, priv->irq_tag, PCIEFD_REG_CAN_RX_CTL_ACK); | |
320 | } | |
321 | ||
322 | /* IRQ handler */ | |
323 | static irqreturn_t pciefd_irq_handler(int irq, void *arg) | |
324 | { | |
325 | struct pciefd_can *priv = arg; | |
326 | struct pciefd_rx_dma *rx_dma = priv->rx_dma_vaddr; | |
327 | ||
328 | /* INTA mode only to sync with PCIe transaction */ | |
329 | if (!pci_dev_msi_enabled(priv->board->pci_dev)) | |
330 | (void)pciefd_sys_readreg(priv->board, PCIEFD_REG_SYS_VER1); | |
331 | ||
332 | /* read IRQ status from the first 32-bits of the Rx DMA area */ | |
333 | priv->irq_status = le32_to_cpu(rx_dma->irq_status); | |
334 | ||
335 | /* check if this (shared) IRQ is for this CAN */ | |
336 | if (pciefd_irq_tag(priv->irq_status) != priv->irq_tag) | |
337 | return IRQ_NONE; | |
338 | ||
339 | /* handle rx messages (if any) */ | |
340 | peak_canfd_handle_msgs_list(&priv->ucan, | |
341 | rx_dma->msg, | |
342 | pciefd_irq_rx_cnt(priv->irq_status)); | |
343 | ||
344 | /* handle tx link interrupt (if any) */ | |
345 | if (pciefd_irq_is_lnk(priv->irq_status)) { | |
346 | unsigned long flags; | |
347 | ||
348 | spin_lock_irqsave(&priv->tx_lock, flags); | |
349 | priv->tx_pages_free++; | |
350 | spin_unlock_irqrestore(&priv->tx_lock, flags); | |
351 | ||
352 | /* wake producer up */ | |
353 | netif_wake_queue(priv->ucan.ndev); | |
354 | } | |
355 | ||
356 | /* re-enable Rx DMA transfer for this CAN */ | |
357 | pciefd_can_ack_rx_dma(priv); | |
358 | ||
359 | return IRQ_HANDLED; | |
360 | } | |
361 | ||
362 | static int pciefd_enable_tx_path(struct peak_canfd_priv *ucan) | |
363 | { | |
364 | struct pciefd_can *priv = (struct pciefd_can *)ucan; | |
365 | int i; | |
366 | ||
367 | /* initialize the Tx pages descriptors */ | |
368 | priv->tx_pages_free = PCIEFD_TX_PAGE_COUNT - 1; | |
369 | priv->tx_page_index = 0; | |
370 | ||
371 | priv->tx_pages[0].vbase = priv->tx_dma_vaddr; | |
372 | priv->tx_pages[0].lbase = priv->tx_dma_laddr; | |
373 | ||
374 | for (i = 0; i < PCIEFD_TX_PAGE_COUNT; i++) { | |
375 | priv->tx_pages[i].offset = 0; | |
376 | priv->tx_pages[i].size = PCIEFD_TX_PAGE_SIZE - | |
377 | sizeof(struct pciefd_tx_link); | |
378 | if (i) { | |
379 | priv->tx_pages[i].vbase = | |
380 | priv->tx_pages[i - 1].vbase + | |
381 | PCIEFD_TX_PAGE_SIZE; | |
382 | priv->tx_pages[i].lbase = | |
383 | priv->tx_pages[i - 1].lbase + | |
384 | PCIEFD_TX_PAGE_SIZE; | |
385 | } | |
386 | } | |
387 | ||
388 | /* setup Tx DMA addresses into IP core */ | |
389 | pciefd_can_setup_tx_dma(priv); | |
390 | ||
391 | /* start (TX_RST=0) Tx Path */ | |
392 | pciefd_can_writereg(priv, CANFD_CTL_RST_BIT, PCIEFD_REG_CAN_TX_CTL_CLR); | |
393 | ||
394 | return 0; | |
395 | } | |
396 | ||
397 | /* board specific CANFD command pre-processing */ | |
398 | static int pciefd_pre_cmd(struct peak_canfd_priv *ucan) | |
399 | { | |
400 | struct pciefd_can *priv = (struct pciefd_can *)ucan; | |
401 | u16 cmd = pucan_cmd_get_opcode(&priv->pucan_cmd); | |
402 | int err; | |
403 | ||
404 | /* pre-process command */ | |
405 | switch (cmd) { | |
406 | case PUCAN_CMD_NORMAL_MODE: | |
407 | case PUCAN_CMD_LISTEN_ONLY_MODE: | |
408 | ||
409 | if (ucan->can.state == CAN_STATE_BUS_OFF) | |
410 | break; | |
411 | ||
412 | /* going into operational mode: setup IRQ handler */ | |
413 | err = request_irq(priv->board->pci_dev->irq, | |
414 | pciefd_irq_handler, | |
415 | IRQF_SHARED, | |
416 | PCIEFD_DRV_NAME, | |
417 | priv); | |
418 | if (err) | |
419 | return err; | |
420 | ||
421 | /* setup Rx DMA address */ | |
422 | pciefd_can_setup_rx_dma(priv); | |
423 | ||
424 | /* setup max count of msgs per IRQ */ | |
425 | pciefd_can_writereg(priv, (CANFD_CTL_IRQ_TL_DEF) << 8 | | |
426 | CANFD_CTL_IRQ_CL_DEF, | |
427 | PCIEFD_REG_CAN_RX_CTL_WRT); | |
428 | ||
429 | /* clear DMA RST for Rx (Rx start) */ | |
430 | pciefd_can_writereg(priv, CANFD_CTL_RST_BIT, | |
431 | PCIEFD_REG_CAN_RX_CTL_CLR); | |
432 | ||
433 | /* reset timestamps */ | |
434 | pciefd_can_writereg(priv, !CANFD_MISC_TS_RST, | |
435 | PCIEFD_REG_CAN_MISC); | |
436 | ||
437 | /* do an initial ACK */ | |
438 | pciefd_can_ack_rx_dma(priv); | |
439 | ||
440 | /* enable IRQ for this CAN after having set next irq_tag */ | |
441 | pciefd_can_writereg(priv, CANFD_CTL_IEN_BIT, | |
442 | PCIEFD_REG_CAN_RX_CTL_SET); | |
443 | ||
444 | /* Tx path will be setup as soon as RX_BARRIER is received */ | |
445 | break; | |
446 | default: | |
447 | break; | |
448 | } | |
449 | ||
450 | return 0; | |
451 | } | |
452 | ||
453 | /* write a command */ | |
454 | static int pciefd_write_cmd(struct peak_canfd_priv *ucan) | |
455 | { | |
456 | struct pciefd_can *priv = (struct pciefd_can *)ucan; | |
457 | unsigned long flags; | |
458 | ||
459 | /* 64-bits command is atomic */ | |
460 | spin_lock_irqsave(&priv->board->cmd_lock, flags); | |
461 | ||
462 | pciefd_can_writereg(priv, *(u32 *)ucan->cmd_buffer, | |
463 | PCIEFD_REG_CAN_CMD_PORT_L); | |
464 | pciefd_can_writereg(priv, *(u32 *)(ucan->cmd_buffer + 4), | |
465 | PCIEFD_REG_CAN_CMD_PORT_H); | |
466 | ||
467 | spin_unlock_irqrestore(&priv->board->cmd_lock, flags); | |
468 | ||
469 | return 0; | |
470 | } | |
471 | ||
472 | /* board specific CANFD command post-processing */ | |
473 | static int pciefd_post_cmd(struct peak_canfd_priv *ucan) | |
474 | { | |
475 | struct pciefd_can *priv = (struct pciefd_can *)ucan; | |
476 | u16 cmd = pucan_cmd_get_opcode(&priv->pucan_cmd); | |
477 | ||
478 | switch (cmd) { | |
479 | case PUCAN_CMD_RESET_MODE: | |
480 | ||
481 | if (ucan->can.state == CAN_STATE_STOPPED) | |
482 | break; | |
483 | ||
484 | /* controller now in reset mode: */ | |
485 | ||
486 | /* stop and reset DMA addresses in Tx/Rx engines */ | |
487 | pciefd_can_clear_tx_dma(priv); | |
488 | pciefd_can_clear_rx_dma(priv); | |
489 | ||
490 | /* disable IRQ for this CAN */ | |
491 | pciefd_can_writereg(priv, CANFD_CTL_IEN_BIT, | |
492 | PCIEFD_REG_CAN_RX_CTL_CLR); | |
493 | ||
494 | free_irq(priv->board->pci_dev->irq, priv); | |
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, | |
633 | "Tx dmaim_alloc_coherent(%u) failure\n", | |
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 | ||
663 | /* fallthough */ | |
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", | |
686 | ndev->name, priv->reg_base, pciefd->pci_dev->irq); | |
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 */ | |
751 | pciefd = devm_kzalloc(&pdev->dev, sizeof(*pciefd) + | |
752 | can_count * sizeof(*pciefd->can), | |
753 | GFP_KERNEL); | |
754 | if (!pciefd) { | |
755 | err = -ENOMEM; | |
756 | goto err_release_regions; | |
757 | } | |
758 | ||
759 | /* initialize the board structure */ | |
760 | pciefd->pci_dev = pdev; | |
761 | spin_lock_init(&pciefd->cmd_lock); | |
762 | ||
763 | /* save the PCI BAR0 virtual address for further system regs access */ | |
764 | pciefd->reg_base = pci_iomap(pdev, 0, PCIEFD_BAR0_SIZE); | |
765 | if (!pciefd->reg_base) { | |
766 | dev_err(&pdev->dev, "failed to map PCI resource #0\n"); | |
767 | err = -ENOMEM; | |
768 | goto err_release_regions; | |
769 | } | |
770 | ||
771 | /* read the firmware version number */ | |
772 | v2 = pciefd_sys_readreg(pciefd, PCIEFD_REG_SYS_VER2); | |
773 | ||
774 | hw_ver_major = (v2 & 0x0000f000) >> 12; | |
775 | hw_ver_minor = (v2 & 0x00000f00) >> 8; | |
776 | hw_ver_sub = (v2 & 0x000000f0) >> 4; | |
777 | ||
778 | dev_info(&pdev->dev, | |
779 | "%ux CAN-FD PCAN-PCIe FPGA v%u.%u.%u:\n", can_count, | |
780 | hw_ver_major, hw_ver_minor, hw_ver_sub); | |
781 | ||
782 | /* stop system clock */ | |
783 | pciefd_sys_writereg(pciefd, PCIEFD_SYS_CTL_CLK_EN, | |
784 | PCIEFD_REG_SYS_CTL_CLR); | |
785 | ||
786 | pci_set_master(pdev); | |
787 | ||
788 | /* create now the corresponding channels objects */ | |
789 | while (pciefd->can_count < can_count) { | |
790 | err = pciefd_can_probe(pciefd); | |
791 | if (err) | |
792 | goto err_free_canfd; | |
793 | ||
794 | pciefd->can_count++; | |
795 | } | |
796 | ||
797 | /* set system timestamps counter in RST mode */ | |
798 | pciefd_sys_writereg(pciefd, PCIEFD_SYS_CTL_TS_RST, | |
799 | PCIEFD_REG_SYS_CTL_SET); | |
800 | ||
801 | /* wait a bit (read cycle) */ | |
802 | (void)pciefd_sys_readreg(pciefd, PCIEFD_REG_SYS_VER1); | |
803 | ||
804 | /* free all clocks */ | |
805 | pciefd_sys_writereg(pciefd, PCIEFD_SYS_CTL_TS_RST, | |
806 | PCIEFD_REG_SYS_CTL_CLR); | |
807 | ||
808 | /* start system clock */ | |
809 | pciefd_sys_writereg(pciefd, PCIEFD_SYS_CTL_CLK_EN, | |
810 | PCIEFD_REG_SYS_CTL_SET); | |
811 | ||
812 | /* remember the board structure address in the device user data */ | |
813 | pci_set_drvdata(pdev, pciefd); | |
814 | ||
815 | return 0; | |
816 | ||
817 | err_free_canfd: | |
818 | pciefd_can_remove_all(pciefd); | |
819 | ||
820 | pci_iounmap(pdev, pciefd->reg_base); | |
821 | ||
822 | err_release_regions: | |
823 | pci_release_regions(pdev); | |
824 | ||
825 | err_disable_pci: | |
826 | pci_disable_device(pdev); | |
827 | ||
828 | return err; | |
829 | } | |
830 | ||
831 | /* free the board structure object, as well as its resources: */ | |
832 | static void peak_pciefd_remove(struct pci_dev *pdev) | |
833 | { | |
834 | struct pciefd_board *pciefd = pci_get_drvdata(pdev); | |
835 | ||
836 | /* release CAN-FD channels resources */ | |
837 | pciefd_can_remove_all(pciefd); | |
838 | ||
839 | pci_iounmap(pdev, pciefd->reg_base); | |
840 | ||
841 | pci_release_regions(pdev); | |
842 | pci_disable_device(pdev); | |
843 | } | |
844 | ||
845 | static struct pci_driver peak_pciefd_driver = { | |
846 | .name = PCIEFD_DRV_NAME, | |
847 | .id_table = peak_pciefd_tbl, | |
848 | .probe = peak_pciefd_probe, | |
849 | .remove = peak_pciefd_remove, | |
850 | }; | |
851 | ||
852 | module_pci_driver(peak_pciefd_driver); |