1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Copyright (C) 2008-2010 |
4 | * |
5 | * - Kurt Van Dijck, EIA Electronics |
6 | */ |
7 | |
8 | #include <linux/firmware.h> |
9 | #include <linux/sched/signal.h> |
10 | #include <asm/div64.h> |
11 | #include <asm/io.h> |
12 | |
13 | #include "softing.h" |
14 | |
15 | /* |
16 | * low level DPRAM command. |
17 | * Make sure that card->dpram[DPRAM_FCT_HOST] is preset |
18 | */ |
19 | static int _softing_fct_cmd(struct softing *card, int16_t cmd, uint16_t vector, |
20 | const char *msg) |
21 | { |
22 | int ret; |
23 | unsigned long stamp; |
24 | |
25 | iowrite16(cmd, &card->dpram[DPRAM_FCT_PARAM]); |
26 | iowrite8(vector >> 8, &card->dpram[DPRAM_FCT_HOST + 1]); |
27 | iowrite8(vector, &card->dpram[DPRAM_FCT_HOST]); |
28 | /* be sure to flush this to the card */ |
29 | wmb(); |
30 | stamp = jiffies + 1 * HZ; |
31 | /* wait for card */ |
32 | do { |
33 | /* DPRAM_FCT_HOST is _not_ aligned */ |
34 | ret = ioread8(&card->dpram[DPRAM_FCT_HOST]) + |
35 | (ioread8(&card->dpram[DPRAM_FCT_HOST + 1]) << 8); |
36 | /* don't have any cached variables */ |
37 | rmb(); |
38 | if (ret == RES_OK) |
39 | /* read return-value now */ |
40 | return ioread16(&card->dpram[DPRAM_FCT_RESULT]); |
41 | |
42 | if ((ret != vector) || time_after(jiffies, stamp)) |
43 | break; |
44 | /* process context => relax */ |
45 | usleep_range(min: 500, max: 10000); |
46 | } while (1); |
47 | |
48 | ret = (ret == RES_NONE) ? -ETIMEDOUT : -ECANCELED; |
49 | dev_alert(&card->pdev->dev, "firmware %s failed (%i)\n" , msg, ret); |
50 | return ret; |
51 | } |
52 | |
53 | static int softing_fct_cmd(struct softing *card, int16_t cmd, const char *msg) |
54 | { |
55 | int ret; |
56 | |
57 | ret = _softing_fct_cmd(card, cmd, vector: 0, msg); |
58 | if (ret > 0) { |
59 | dev_alert(&card->pdev->dev, "%s returned %u\n" , msg, ret); |
60 | ret = -EIO; |
61 | } |
62 | return ret; |
63 | } |
64 | |
65 | int softing_bootloader_command(struct softing *card, int16_t cmd, |
66 | const char *msg) |
67 | { |
68 | int ret; |
69 | unsigned long stamp; |
70 | |
71 | iowrite16(RES_NONE, &card->dpram[DPRAM_RECEIPT]); |
72 | iowrite16(cmd, &card->dpram[DPRAM_COMMAND]); |
73 | /* be sure to flush this to the card */ |
74 | wmb(); |
75 | stamp = jiffies + 3 * HZ; |
76 | /* wait for card */ |
77 | do { |
78 | ret = ioread16(&card->dpram[DPRAM_RECEIPT]); |
79 | /* don't have any cached variables */ |
80 | rmb(); |
81 | if (ret == RES_OK) |
82 | return 0; |
83 | if (time_after(jiffies, stamp)) |
84 | break; |
85 | /* process context => relax */ |
86 | usleep_range(min: 500, max: 10000); |
87 | } while (!signal_pending(current)); |
88 | |
89 | ret = (ret == RES_NONE) ? -ETIMEDOUT : -ECANCELED; |
90 | dev_alert(&card->pdev->dev, "bootloader %s failed (%i)\n" , msg, ret); |
91 | return ret; |
92 | } |
93 | |
94 | static int fw_parse(const uint8_t **pmem, uint16_t *ptype, uint32_t *paddr, |
95 | uint16_t *plen, const uint8_t **pdat) |
96 | { |
97 | uint16_t checksum[2]; |
98 | const uint8_t *mem; |
99 | const uint8_t *end; |
100 | |
101 | /* |
102 | * firmware records are a binary, unaligned stream composed of: |
103 | * uint16_t type; |
104 | * uint32_t addr; |
105 | * uint16_t len; |
106 | * uint8_t dat[len]; |
107 | * uint16_t checksum; |
108 | * all values in little endian. |
109 | * We could define a struct for this, with __attribute__((packed)), |
110 | * but would that solve the alignment in _all_ cases (cfr. the |
111 | * struct itself may be an odd address)? |
112 | * |
113 | * I chose to use leXX_to_cpup() since this solves both |
114 | * endianness & alignment. |
115 | */ |
116 | mem = *pmem; |
117 | *ptype = le16_to_cpup(p: (void *)&mem[0]); |
118 | *paddr = le32_to_cpup(p: (void *)&mem[2]); |
119 | *plen = le16_to_cpup(p: (void *)&mem[6]); |
120 | *pdat = &mem[8]; |
121 | /* verify checksum */ |
122 | end = &mem[8 + *plen]; |
123 | checksum[0] = le16_to_cpup(p: (void *)end); |
124 | for (checksum[1] = 0; mem < end; ++mem) |
125 | checksum[1] += *mem; |
126 | if (checksum[0] != checksum[1]) |
127 | return -EINVAL; |
128 | /* increment */ |
129 | *pmem += 10 + *plen; |
130 | return 0; |
131 | } |
132 | |
133 | int softing_load_fw(const char *file, struct softing *card, |
134 | __iomem uint8_t *dpram, unsigned int size, int offset) |
135 | { |
136 | const struct firmware *fw; |
137 | int ret; |
138 | const uint8_t *mem, *end, *dat; |
139 | uint16_t type, len; |
140 | uint32_t addr; |
141 | uint8_t *buf = NULL, *new_buf; |
142 | int buflen = 0; |
143 | int8_t type_end = 0; |
144 | |
145 | ret = request_firmware(fw: &fw, name: file, device: &card->pdev->dev); |
146 | if (ret < 0) |
147 | return ret; |
148 | dev_dbg(&card->pdev->dev, "%s, firmware(%s) got %u bytes" |
149 | ", offset %c0x%04x\n" , |
150 | card->pdat->name, file, (unsigned int)fw->size, |
151 | (offset >= 0) ? '+' : '-', (unsigned int)abs(offset)); |
152 | /* parse the firmware */ |
153 | mem = fw->data; |
154 | end = &mem[fw->size]; |
155 | /* look for header record */ |
156 | ret = fw_parse(pmem: &mem, ptype: &type, paddr: &addr, plen: &len, pdat: &dat); |
157 | if (ret < 0) |
158 | goto failed; |
159 | if (type != 0xffff) |
160 | goto failed; |
161 | if (strncmp("Structured Binary Format, Softing GmbH" , dat, len)) { |
162 | ret = -EINVAL; |
163 | goto failed; |
164 | } |
165 | /* ok, we had a header */ |
166 | while (mem < end) { |
167 | ret = fw_parse(pmem: &mem, ptype: &type, paddr: &addr, plen: &len, pdat: &dat); |
168 | if (ret < 0) |
169 | goto failed; |
170 | if (type == 3) { |
171 | /* start address, not used here */ |
172 | continue; |
173 | } else if (type == 1) { |
174 | /* eof */ |
175 | type_end = 1; |
176 | break; |
177 | } else if (type != 0) { |
178 | ret = -EINVAL; |
179 | goto failed; |
180 | } |
181 | |
182 | if ((addr + len + offset) > size) |
183 | goto failed; |
184 | memcpy_toio(&dpram[addr + offset], dat, len); |
185 | /* be sure to flush caches from IO space */ |
186 | mb(); |
187 | if (len > buflen) { |
188 | /* align buflen */ |
189 | buflen = (len + (1024-1)) & ~(1024-1); |
190 | new_buf = krealloc(objp: buf, new_size: buflen, GFP_KERNEL); |
191 | if (!new_buf) { |
192 | ret = -ENOMEM; |
193 | goto failed; |
194 | } |
195 | buf = new_buf; |
196 | } |
197 | /* verify record data */ |
198 | memcpy_fromio(buf, &dpram[addr + offset], len); |
199 | if (memcmp(p: buf, q: dat, size: len)) { |
200 | /* is not ok */ |
201 | dev_alert(&card->pdev->dev, "DPRAM readback failed\n" ); |
202 | ret = -EIO; |
203 | goto failed; |
204 | } |
205 | } |
206 | if (!type_end) |
207 | /* no end record seen */ |
208 | goto failed; |
209 | ret = 0; |
210 | failed: |
211 | kfree(objp: buf); |
212 | release_firmware(fw); |
213 | if (ret < 0) |
214 | dev_info(&card->pdev->dev, "firmware %s failed\n" , file); |
215 | return ret; |
216 | } |
217 | |
218 | int softing_load_app_fw(const char *file, struct softing *card) |
219 | { |
220 | const struct firmware *fw; |
221 | const uint8_t *mem, *end, *dat; |
222 | int ret, j; |
223 | uint16_t type, len; |
224 | uint32_t addr, start_addr = 0; |
225 | unsigned int sum, rx_sum; |
226 | int8_t type_end = 0, type_entrypoint = 0; |
227 | |
228 | ret = request_firmware(fw: &fw, name: file, device: &card->pdev->dev); |
229 | if (ret) { |
230 | dev_alert(&card->pdev->dev, "request_firmware(%s) got %i\n" , |
231 | file, ret); |
232 | return ret; |
233 | } |
234 | dev_dbg(&card->pdev->dev, "firmware(%s) got %lu bytes\n" , |
235 | file, (unsigned long)fw->size); |
236 | /* parse the firmware */ |
237 | mem = fw->data; |
238 | end = &mem[fw->size]; |
239 | /* look for header record */ |
240 | ret = fw_parse(pmem: &mem, ptype: &type, paddr: &addr, plen: &len, pdat: &dat); |
241 | if (ret) |
242 | goto failed; |
243 | ret = -EINVAL; |
244 | if (type != 0xffff) { |
245 | dev_alert(&card->pdev->dev, "firmware starts with type 0x%x\n" , |
246 | type); |
247 | goto failed; |
248 | } |
249 | if (strncmp("Structured Binary Format, Softing GmbH" , dat, len)) { |
250 | dev_alert(&card->pdev->dev, "firmware string '%.*s' fault\n" , |
251 | len, dat); |
252 | goto failed; |
253 | } |
254 | /* ok, we had a header */ |
255 | while (mem < end) { |
256 | ret = fw_parse(pmem: &mem, ptype: &type, paddr: &addr, plen: &len, pdat: &dat); |
257 | if (ret) |
258 | goto failed; |
259 | |
260 | if (type == 3) { |
261 | /* start address */ |
262 | start_addr = addr; |
263 | type_entrypoint = 1; |
264 | continue; |
265 | } else if (type == 1) { |
266 | /* eof */ |
267 | type_end = 1; |
268 | break; |
269 | } else if (type != 0) { |
270 | dev_alert(&card->pdev->dev, |
271 | "unknown record type 0x%04x\n" , type); |
272 | ret = -EINVAL; |
273 | goto failed; |
274 | } |
275 | |
276 | /* regular data */ |
277 | for (sum = 0, j = 0; j < len; ++j) |
278 | sum += dat[j]; |
279 | /* work in 16bit (target) */ |
280 | sum &= 0xffff; |
281 | |
282 | memcpy_toio(&card->dpram[card->pdat->app.offs], dat, len); |
283 | iowrite32(card->pdat->app.offs + card->pdat->app.addr, |
284 | &card->dpram[DPRAM_COMMAND + 2]); |
285 | iowrite32(addr, &card->dpram[DPRAM_COMMAND + 6]); |
286 | iowrite16(len, &card->dpram[DPRAM_COMMAND + 10]); |
287 | iowrite8(1, &card->dpram[DPRAM_COMMAND + 12]); |
288 | ret = softing_bootloader_command(card, cmd: 1, msg: "loading app." ); |
289 | if (ret < 0) |
290 | goto failed; |
291 | /* verify checksum */ |
292 | rx_sum = ioread16(&card->dpram[DPRAM_RECEIPT + 2]); |
293 | if (rx_sum != sum) { |
294 | dev_alert(&card->pdev->dev, "SRAM seems to be damaged" |
295 | ", wanted 0x%04x, got 0x%04x\n" , sum, rx_sum); |
296 | ret = -EIO; |
297 | goto failed; |
298 | } |
299 | } |
300 | if (!type_end || !type_entrypoint) |
301 | goto failed; |
302 | /* start application in card */ |
303 | iowrite32(start_addr, &card->dpram[DPRAM_COMMAND + 2]); |
304 | iowrite8(1, &card->dpram[DPRAM_COMMAND + 6]); |
305 | ret = softing_bootloader_command(card, cmd: 3, msg: "start app." ); |
306 | if (ret < 0) |
307 | goto failed; |
308 | ret = 0; |
309 | failed: |
310 | release_firmware(fw); |
311 | if (ret < 0) |
312 | dev_info(&card->pdev->dev, "firmware %s failed\n" , file); |
313 | return ret; |
314 | } |
315 | |
316 | static int softing_reset_chip(struct softing *card) |
317 | { |
318 | int ret; |
319 | |
320 | do { |
321 | /* reset chip */ |
322 | iowrite8(0, &card->dpram[DPRAM_RESET_RX_FIFO]); |
323 | iowrite8(0, &card->dpram[DPRAM_RESET_RX_FIFO+1]); |
324 | iowrite8(1, &card->dpram[DPRAM_RESET]); |
325 | iowrite8(0, &card->dpram[DPRAM_RESET+1]); |
326 | |
327 | ret = softing_fct_cmd(card, cmd: 0, msg: "reset_can" ); |
328 | if (!ret) |
329 | break; |
330 | if (signal_pending(current)) |
331 | /* don't wait any longer */ |
332 | break; |
333 | } while (1); |
334 | card->tx.pending = 0; |
335 | return ret; |
336 | } |
337 | |
338 | int softing_chip_poweron(struct softing *card) |
339 | { |
340 | int ret; |
341 | /* sync */ |
342 | ret = _softing_fct_cmd(card, cmd: 99, vector: 0x55, msg: "sync-a" ); |
343 | if (ret < 0) |
344 | goto failed; |
345 | |
346 | ret = _softing_fct_cmd(card, cmd: 99, vector: 0xaa, msg: "sync-b" ); |
347 | if (ret < 0) |
348 | goto failed; |
349 | |
350 | ret = softing_reset_chip(card); |
351 | if (ret < 0) |
352 | goto failed; |
353 | /* get_serial */ |
354 | ret = softing_fct_cmd(card, cmd: 43, msg: "get_serial_number" ); |
355 | if (ret < 0) |
356 | goto failed; |
357 | card->id.serial = ioread32(&card->dpram[DPRAM_FCT_PARAM]); |
358 | /* get_version */ |
359 | ret = softing_fct_cmd(card, cmd: 12, msg: "get_version" ); |
360 | if (ret < 0) |
361 | goto failed; |
362 | card->id.fw_version = ioread16(&card->dpram[DPRAM_FCT_PARAM + 2]); |
363 | card->id.hw_version = ioread16(&card->dpram[DPRAM_FCT_PARAM + 4]); |
364 | card->id.license = ioread16(&card->dpram[DPRAM_FCT_PARAM + 6]); |
365 | card->id.chip[0] = ioread16(&card->dpram[DPRAM_FCT_PARAM + 8]); |
366 | card->id.chip[1] = ioread16(&card->dpram[DPRAM_FCT_PARAM + 10]); |
367 | return 0; |
368 | failed: |
369 | return ret; |
370 | } |
371 | |
372 | static void softing_initialize_timestamp(struct softing *card) |
373 | { |
374 | uint64_t ovf; |
375 | |
376 | card->ts_ref = ktime_get(); |
377 | |
378 | /* 16MHz is the reference */ |
379 | ovf = 0x100000000ULL * 16; |
380 | do_div(ovf, card->pdat->freq ?: 16); |
381 | |
382 | card->ts_overflow = ktime_add_us(kt: 0, usec: ovf); |
383 | } |
384 | |
385 | ktime_t softing_raw2ktime(struct softing *card, u32 raw) |
386 | { |
387 | uint64_t rawl; |
388 | ktime_t now, real_offset; |
389 | ktime_t target; |
390 | ktime_t tmp; |
391 | |
392 | now = ktime_get(); |
393 | real_offset = ktime_sub(ktime_get_real(), now); |
394 | |
395 | /* find nsec from card */ |
396 | rawl = raw * 16; |
397 | do_div(rawl, card->pdat->freq ?: 16); |
398 | target = ktime_add_us(kt: card->ts_ref, usec: rawl); |
399 | /* test for overflows */ |
400 | tmp = ktime_add(target, card->ts_overflow); |
401 | while (unlikely(ktime_to_ns(tmp) > ktime_to_ns(now))) { |
402 | card->ts_ref = ktime_add(card->ts_ref, card->ts_overflow); |
403 | target = tmp; |
404 | tmp = ktime_add(target, card->ts_overflow); |
405 | } |
406 | return ktime_add(target, real_offset); |
407 | } |
408 | |
409 | static inline int softing_error_reporting(struct net_device *netdev) |
410 | { |
411 | struct softing_priv *priv = netdev_priv(dev: netdev); |
412 | |
413 | return (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) |
414 | ? 1 : 0; |
415 | } |
416 | |
417 | int softing_startstop(struct net_device *dev, int up) |
418 | { |
419 | int ret; |
420 | struct softing *card; |
421 | struct softing_priv *priv; |
422 | struct net_device *netdev; |
423 | int bus_bitmask_start; |
424 | int j, error_reporting; |
425 | struct can_frame msg; |
426 | const struct can_bittiming *bt; |
427 | |
428 | priv = netdev_priv(dev); |
429 | card = priv->card; |
430 | |
431 | if (!card->fw.up) |
432 | return -EIO; |
433 | |
434 | ret = mutex_lock_interruptible(&card->fw.lock); |
435 | if (ret) |
436 | return ret; |
437 | |
438 | bus_bitmask_start = 0; |
439 | if (up) |
440 | /* prepare to start this bus as well */ |
441 | bus_bitmask_start |= (1 << priv->index); |
442 | /* bring netdevs down */ |
443 | for (j = 0; j < ARRAY_SIZE(card->net); ++j) { |
444 | netdev = card->net[j]; |
445 | if (!netdev) |
446 | continue; |
447 | priv = netdev_priv(dev: netdev); |
448 | |
449 | if (dev != netdev) |
450 | netif_stop_queue(dev: netdev); |
451 | |
452 | if (netif_running(dev: netdev)) { |
453 | if (dev != netdev) |
454 | bus_bitmask_start |= (1 << j); |
455 | priv->tx.pending = 0; |
456 | priv->tx.echo_put = 0; |
457 | priv->tx.echo_get = 0; |
458 | /* |
459 | * this bus' may just have called open_candev() |
460 | * which is rather stupid to call close_candev() |
461 | * already |
462 | * but we may come here from busoff recovery too |
463 | * in which case the echo_skb _needs_ flushing too. |
464 | * just be sure to call open_candev() again |
465 | */ |
466 | close_candev(dev: netdev); |
467 | } |
468 | priv->can.state = CAN_STATE_STOPPED; |
469 | } |
470 | card->tx.pending = 0; |
471 | |
472 | softing_enable_irq(card, enable: 0); |
473 | ret = softing_reset_chip(card); |
474 | if (ret) |
475 | goto failed; |
476 | if (!bus_bitmask_start) |
477 | /* no buses to be brought up */ |
478 | goto card_done; |
479 | |
480 | if ((bus_bitmask_start & 1) && (bus_bitmask_start & 2) |
481 | && (softing_error_reporting(netdev: card->net[0]) |
482 | != softing_error_reporting(netdev: card->net[1]))) { |
483 | dev_alert(&card->pdev->dev, |
484 | "err_reporting flag differs for buses\n" ); |
485 | goto invalid; |
486 | } |
487 | error_reporting = 0; |
488 | if (bus_bitmask_start & 1) { |
489 | netdev = card->net[0]; |
490 | priv = netdev_priv(dev: netdev); |
491 | error_reporting += softing_error_reporting(netdev); |
492 | /* init chip 1 */ |
493 | bt = &priv->can.bittiming; |
494 | iowrite16(bt->brp, &card->dpram[DPRAM_FCT_PARAM + 2]); |
495 | iowrite16(bt->sjw, &card->dpram[DPRAM_FCT_PARAM + 4]); |
496 | iowrite16(bt->phase_seg1 + bt->prop_seg, |
497 | &card->dpram[DPRAM_FCT_PARAM + 6]); |
498 | iowrite16(bt->phase_seg2, &card->dpram[DPRAM_FCT_PARAM + 8]); |
499 | iowrite16((priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) ? 1 : 0, |
500 | &card->dpram[DPRAM_FCT_PARAM + 10]); |
501 | ret = softing_fct_cmd(card, cmd: 1, msg: "initialize_chip[0]" ); |
502 | if (ret < 0) |
503 | goto failed; |
504 | /* set mode */ |
505 | iowrite16(0, &card->dpram[DPRAM_FCT_PARAM + 2]); |
506 | iowrite16(0, &card->dpram[DPRAM_FCT_PARAM + 4]); |
507 | ret = softing_fct_cmd(card, cmd: 3, msg: "set_mode[0]" ); |
508 | if (ret < 0) |
509 | goto failed; |
510 | /* set filter */ |
511 | /* 11bit id & mask */ |
512 | iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 2]); |
513 | iowrite16(0x07ff, &card->dpram[DPRAM_FCT_PARAM + 4]); |
514 | /* 29bit id.lo & mask.lo & id.hi & mask.hi */ |
515 | iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 6]); |
516 | iowrite16(0xffff, &card->dpram[DPRAM_FCT_PARAM + 8]); |
517 | iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 10]); |
518 | iowrite16(0x1fff, &card->dpram[DPRAM_FCT_PARAM + 12]); |
519 | ret = softing_fct_cmd(card, cmd: 7, msg: "set_filter[0]" ); |
520 | if (ret < 0) |
521 | goto failed; |
522 | /* set output control */ |
523 | iowrite16(priv->output, &card->dpram[DPRAM_FCT_PARAM + 2]); |
524 | ret = softing_fct_cmd(card, cmd: 5, msg: "set_output[0]" ); |
525 | if (ret < 0) |
526 | goto failed; |
527 | } |
528 | if (bus_bitmask_start & 2) { |
529 | netdev = card->net[1]; |
530 | priv = netdev_priv(dev: netdev); |
531 | error_reporting += softing_error_reporting(netdev); |
532 | /* init chip2 */ |
533 | bt = &priv->can.bittiming; |
534 | iowrite16(bt->brp, &card->dpram[DPRAM_FCT_PARAM + 2]); |
535 | iowrite16(bt->sjw, &card->dpram[DPRAM_FCT_PARAM + 4]); |
536 | iowrite16(bt->phase_seg1 + bt->prop_seg, |
537 | &card->dpram[DPRAM_FCT_PARAM + 6]); |
538 | iowrite16(bt->phase_seg2, &card->dpram[DPRAM_FCT_PARAM + 8]); |
539 | iowrite16((priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) ? 1 : 0, |
540 | &card->dpram[DPRAM_FCT_PARAM + 10]); |
541 | ret = softing_fct_cmd(card, cmd: 2, msg: "initialize_chip[1]" ); |
542 | if (ret < 0) |
543 | goto failed; |
544 | /* set mode2 */ |
545 | iowrite16(0, &card->dpram[DPRAM_FCT_PARAM + 2]); |
546 | iowrite16(0, &card->dpram[DPRAM_FCT_PARAM + 4]); |
547 | ret = softing_fct_cmd(card, cmd: 4, msg: "set_mode[1]" ); |
548 | if (ret < 0) |
549 | goto failed; |
550 | /* set filter2 */ |
551 | /* 11bit id & mask */ |
552 | iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 2]); |
553 | iowrite16(0x07ff, &card->dpram[DPRAM_FCT_PARAM + 4]); |
554 | /* 29bit id.lo & mask.lo & id.hi & mask.hi */ |
555 | iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 6]); |
556 | iowrite16(0xffff, &card->dpram[DPRAM_FCT_PARAM + 8]); |
557 | iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 10]); |
558 | iowrite16(0x1fff, &card->dpram[DPRAM_FCT_PARAM + 12]); |
559 | ret = softing_fct_cmd(card, cmd: 8, msg: "set_filter[1]" ); |
560 | if (ret < 0) |
561 | goto failed; |
562 | /* set output control2 */ |
563 | iowrite16(priv->output, &card->dpram[DPRAM_FCT_PARAM + 2]); |
564 | ret = softing_fct_cmd(card, cmd: 6, msg: "set_output[1]" ); |
565 | if (ret < 0) |
566 | goto failed; |
567 | } |
568 | |
569 | /* enable_error_frame |
570 | * |
571 | * Error reporting is switched off at the moment since |
572 | * the receiving of them is not yet 100% verified |
573 | * This should be enabled sooner or later |
574 | */ |
575 | if (0 && error_reporting) { |
576 | ret = softing_fct_cmd(card, cmd: 51, msg: "enable_error_frame" ); |
577 | if (ret < 0) |
578 | goto failed; |
579 | } |
580 | |
581 | /* initialize interface */ |
582 | iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 2]); |
583 | iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 4]); |
584 | iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 6]); |
585 | iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 8]); |
586 | iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 10]); |
587 | iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 12]); |
588 | iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 14]); |
589 | iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 16]); |
590 | iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 18]); |
591 | iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 20]); |
592 | ret = softing_fct_cmd(card, cmd: 17, msg: "initialize_interface" ); |
593 | if (ret < 0) |
594 | goto failed; |
595 | /* enable_fifo */ |
596 | ret = softing_fct_cmd(card, cmd: 36, msg: "enable_fifo" ); |
597 | if (ret < 0) |
598 | goto failed; |
599 | /* enable fifo tx ack */ |
600 | ret = softing_fct_cmd(card, cmd: 13, msg: "fifo_tx_ack[0]" ); |
601 | if (ret < 0) |
602 | goto failed; |
603 | /* enable fifo tx ack2 */ |
604 | ret = softing_fct_cmd(card, cmd: 14, msg: "fifo_tx_ack[1]" ); |
605 | if (ret < 0) |
606 | goto failed; |
607 | /* start_chip */ |
608 | ret = softing_fct_cmd(card, cmd: 11, msg: "start_chip" ); |
609 | if (ret < 0) |
610 | goto failed; |
611 | iowrite8(0, &card->dpram[DPRAM_INFO_BUSSTATE]); |
612 | iowrite8(0, &card->dpram[DPRAM_INFO_BUSSTATE2]); |
613 | if (card->pdat->generation < 2) { |
614 | iowrite8(0, &card->dpram[DPRAM_V2_IRQ_TOHOST]); |
615 | /* flush the DPRAM caches */ |
616 | wmb(); |
617 | } |
618 | |
619 | softing_initialize_timestamp(card); |
620 | |
621 | /* |
622 | * do socketcan notifications/status changes |
623 | * from here, no errors should occur, or the failed: part |
624 | * must be reviewed |
625 | */ |
626 | memset(&msg, 0, sizeof(msg)); |
627 | msg.can_id = CAN_ERR_FLAG | CAN_ERR_RESTARTED; |
628 | msg.len = CAN_ERR_DLC; |
629 | for (j = 0; j < ARRAY_SIZE(card->net); ++j) { |
630 | if (!(bus_bitmask_start & (1 << j))) |
631 | continue; |
632 | netdev = card->net[j]; |
633 | if (!netdev) |
634 | continue; |
635 | priv = netdev_priv(dev: netdev); |
636 | priv->can.state = CAN_STATE_ERROR_ACTIVE; |
637 | open_candev(dev: netdev); |
638 | if (dev != netdev) { |
639 | /* notify other buses on the restart */ |
640 | softing_netdev_rx(netdev, msg: &msg, ktime: 0); |
641 | ++priv->can.can_stats.restarts; |
642 | } |
643 | netif_wake_queue(dev: netdev); |
644 | } |
645 | |
646 | /* enable interrupts */ |
647 | ret = softing_enable_irq(card, enable: 1); |
648 | if (ret) |
649 | goto failed; |
650 | card_done: |
651 | mutex_unlock(lock: &card->fw.lock); |
652 | return 0; |
653 | invalid: |
654 | ret = -EINVAL; |
655 | failed: |
656 | softing_enable_irq(card, enable: 0); |
657 | softing_reset_chip(card); |
658 | mutex_unlock(lock: &card->fw.lock); |
659 | /* bring all other interfaces down */ |
660 | for (j = 0; j < ARRAY_SIZE(card->net); ++j) { |
661 | netdev = card->net[j]; |
662 | if (!netdev) |
663 | continue; |
664 | dev_close(dev: netdev); |
665 | } |
666 | return ret; |
667 | } |
668 | |
669 | int softing_default_output(struct net_device *netdev) |
670 | { |
671 | struct softing_priv *priv = netdev_priv(dev: netdev); |
672 | struct softing *card = priv->card; |
673 | |
674 | switch (priv->chip) { |
675 | case 1000: |
676 | return (card->pdat->generation < 2) ? 0xfb : 0xfa; |
677 | case 5: |
678 | return 0x60; |
679 | default: |
680 | return 0x40; |
681 | } |
682 | } |
683 | |