2 * drivers/net/can/softing/softing_fw.c
6 * - Kurt Van Dijck, EIA Electronics
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the version 2 of the GNU General Public License
10 * as published by the Free Software Foundation
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include <linux/module.h>
23 #include <linux/init.h>
24 #include <linux/device.h>
25 #include <linux/firmware.h>
26 #include <linux/interrupt.h>
27 #include <linux/mutex.h>
32 #define fw_dir "softing-4.6/"
34 const struct can_bittiming_const softing_btr_const = {
39 .sjw_max = 4, /* overruled */
41 .brp_max = 32, /* overruled */
45 static const struct softing_desc carddescs[] = {
48 .manf = 0x0168, .prod = 0x001,
50 .freq = 16, .max_brp = 32, .max_sjw = 4,
52 .boot = {0x0000, 0x000000, fw_dir "bcard.bin",},
53 .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",},
54 .app = {0x0010, 0x0d0000, fw_dir "cancard.bin",},
56 .name = "CANcard-NEC",
57 .manf = 0x0168, .prod = 0x002,
59 .freq = 16, .max_brp = 32, .max_sjw = 4,
61 .boot = {0x0000, 0x000000, fw_dir "bcard.bin",},
62 .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",},
63 .app = {0x0010, 0x0d0000, fw_dir "cancard.bin",},
65 .name = "CANcard-SJA",
66 .manf = 0x0168, .prod = 0x004,
68 .freq = 20, .max_brp = 32, .max_sjw = 4,
70 .boot = {0x0000, 0x000000, fw_dir "bcard.bin",},
71 .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",},
72 .app = {0x0010, 0x0d0000, fw_dir "cansja.bin",},
75 .manf = 0x0168, .prod = 0x005,
77 .freq = 24, .max_brp = 64, .max_sjw = 4,
79 .boot = {0x0000, 0x000000, fw_dir "bcard2.bin",},
80 .load = {0x0120, 0x00f600, fw_dir "ldcard2.bin",},
81 .app = {0x0010, 0x0d0000, fw_dir "cancrd2.bin",},
83 .name = "Vector-CANcard",
84 .manf = 0x0168, .prod = 0x081,
86 .freq = 16, .max_brp = 64, .max_sjw = 4,
88 .boot = {0x0000, 0x000000, fw_dir "bcard.bin",},
89 .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",},
90 .app = {0x0010, 0x0d0000, fw_dir "cancard.bin",},
92 .name = "Vector-CANcard-SJA",
93 .manf = 0x0168, .prod = 0x084,
95 .freq = 20, .max_brp = 32, .max_sjw = 4,
97 .boot = {0x0000, 0x000000, fw_dir "bcard.bin",},
98 .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",},
99 .app = {0x0010, 0x0d0000, fw_dir "cansja.bin",},
101 .name = "Vector-CANcard-2",
102 .manf = 0x0168, .prod = 0x085,
104 .freq = 24, .max_brp = 64, .max_sjw = 4,
105 .dpram_size = 0x0800,
106 .boot = {0x0000, 0x000000, fw_dir "bcard2.bin",},
107 .load = {0x0120, 0x00f600, fw_dir "ldcard2.bin",},
108 .app = {0x0010, 0x0d0000, fw_dir "cancrd2.bin",},
110 .name = "EDICcard-NEC",
111 .manf = 0x0168, .prod = 0x102,
113 .freq = 16, .max_brp = 64, .max_sjw = 4,
114 .dpram_size = 0x0800,
115 .boot = {0x0000, 0x000000, fw_dir "bcard.bin",},
116 .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",},
117 .app = {0x0010, 0x0d0000, fw_dir "cancard.bin",},
119 .name = "EDICcard-2",
120 .manf = 0x0168, .prod = 0x105,
122 .freq = 24, .max_brp = 64, .max_sjw = 4,
123 .dpram_size = 0x0800,
124 .boot = {0x0000, 0x000000, fw_dir "bcard2.bin",},
125 .load = {0x0120, 0x00f600, fw_dir "ldcard2.bin",},
126 .app = {0x0010, 0x0d0000, fw_dir "cancrd2.bin",},
129 /* never tested, but taken from original softing */
130 { .name = "CAN-AC2-104",
131 .manf = 0x0000, .prod = 0x009,
133 .freq = 25, .max_brp = 64, .max_sjw = 4,
134 .dpram_size = 0x1000,
135 .boot = {0x0000, 0x000000, fw_dir "boot104.bin",},
136 .load = {0x0800, 0x035000, fw_dir "ld104.bin",},
137 .app = {0x0010, 0x120000, fw_dir "canpc104.bin",},
142 const struct softing_desc *softing_lookup_desc
143 (unsigned int manf, unsigned int prod)
145 const struct softing_desc *lp = carddescs;
146 for (; lp->name; ++lp) {
147 if ((lp->manf == manf) && (lp->prod == prod))
152 EXPORT_SYMBOL(softing_lookup_desc);
154 int softing_fct_cmd(struct softing *card, int cmd, int vector, const char *msg)
158 if (vector == RES_OK)
160 card->dpram.fct->param[0] = cmd;
161 card->dpram.fct->host_access = vector;
162 /* be sure to flush this to the card */
167 ret = card->dpram.fct->host_access;
168 /* don't have any cached variables */
171 /*don't read return-value now */
172 ret = card->dpram.fct->returned;
174 mod_alert("%s returned %u", msg, ret);
177 if ((jiffies - stamp) >= 1 * HZ)
180 /* go as fast as possible */
182 /* process context => relax */
184 } while (!signal_pending(current));
186 if (ret == RES_NONE) {
187 mod_alert("%s, no response from card on %u/0x%02x"
191 mod_alert("%s, bad response from card on %u/0x%02x, 0x%04x"
192 , msg, cmd, vector, ret);
193 /*make sure to return something not 0 */
194 return ret ? ret : 1;
198 int softing_bootloader_command(struct softing *card
199 , int command, const char *msg)
203 card->dpram.receipt[0] = RES_NONE;
204 card->dpram.command[0] = command;
205 /* be sure to flush this to the card */
210 ret = card->dpram.receipt[0];
211 /* don't have any cached variables */
215 if ((jiffies - stamp) >= (3 * HZ))
218 } while (!signal_pending(current));
222 mod_alert("%s: no response from card", msg);
225 mod_alert("%s: response from card nok", msg);
228 mod_alert("%s: command 0x%04x unknown", msg, command);
231 mod_alert("%s: bad response from card (%u)]", msg, ret);
234 return ret ? ret : 1;
242 const unsigned char *base;
243 } __attribute__ ((packed));
245 static int fw_parse(const unsigned char **pmem, struct fw_hdr *hdr)
248 const unsigned char *mem;
249 const unsigned char *end;
251 hdr->type = (mem[0] << 0) | (mem[1] << 8);
252 hdr->addr = (mem[2] << 0) | (mem[3] << 8)
253 | (mem[4] << 16) | (mem[5] << 24);
254 hdr->len = (mem[6] << 0) | (mem[7] << 8);
257 (hdr->base[hdr->len] << 0) | (hdr->base[hdr->len + 1] << 8);
258 for (tmp = 0, mem = *pmem, end = &hdr->base[hdr->len]; mem < end; ++mem)
260 if (tmp != hdr->checksum)
262 *pmem += 10 + hdr->len;
266 int softing_load_fw(const char *file, struct softing *card,
267 unsigned char *virt, unsigned int size, int offset)
269 const struct firmware *fw;
270 const unsigned char *mem;
271 const unsigned char *end;
276 unsigned char buf[256];
278 ret = request_firmware(&fw, file, card->dev);
280 mod_alert("request_firmware(%s) got %i", file, ret);
283 mod_trace("%s, firmware(%s) got %u bytes, offset %c0x%04x"
284 , card->id.name, file, (unsigned int)fw->size,
285 (offset >= 0) ? '+' : '-', abs(offset));
286 /* parse the firmware */
288 end = &mem[fw->size];
289 /* look for header record */
290 if (fw_parse(&mem, &rec))
292 if (rec.type != 0xffff) {
293 mod_alert("firware starts with type 0x%04x", rec.type);
296 if (strncmp("Structured Binary Format, Softing GmbH"
297 , rec.base, rec.len)) {
298 mod_info("firware string '%.*s'", rec.len, rec.base);
302 /* ok, we had a header */
304 if (fw_parse(&mem, &rec))
308 start_addr = rec.addr;
311 } else if (rec.type == 1) {
315 } else if (rec.type != 0) {
316 mod_alert("unknown record type 0x%04x", rec.type);
320 if ((rec.addr + rec.len + offset) > size) {
321 mod_alert("firmware out of range (0x%08x / 0x%08x)"
322 , (rec.addr + rec.len + offset), size);
325 memcpy_toio(&virt[rec.addr + offset],
327 /* be sure to flush caches from IO space */
329 if (rec.len > sizeof(buf)) {
330 mod_info("record is big (%u bytes), not verifying"
334 /* verify record data */
335 memcpy_fromio(buf, &virt[rec.addr + offset], rec.len);
336 if (!memcmp(buf, rec.base, rec.len))
339 mod_alert("0x%08x:0x%03x at 0x%p failed", rec.addr, rec.len
340 , &virt[rec.addr + offset]);
344 release_firmware(fw);
345 if (0x5 == (ok & 0x5)) {
353 int softing_load_app_fw(const char *file, struct softing *card)
355 const struct firmware *fw;
356 const unsigned char *mem;
357 const unsigned char *end;
364 const unsigned char *mem_lp;
365 const unsigned char *mem_end;
371 } __attribute__((packed)) *pcpy =
372 (struct cpy *)&card->dpram.command[1];
374 ret = request_firmware(&fw, file, card->dev);
376 mod_alert("request_firmware(%s) got %i", file, ret);
379 mod_trace("%s, firmware(%s) got %lu bytes", card->id.name, file,
380 (unsigned long)fw->size);
381 /* parse the firmware */
383 end = &mem[fw->size];
384 /* look for header record */
385 if (fw_parse(&mem, &rec))
387 if (rec.type != 0xffff) {
388 mod_alert("firware starts with type 0x%04x", rec.type);
391 if (strncmp("Structured Binary Format, Softing GmbH"
392 , rec.base, rec.len)) {
393 mod_info("firware string '%.*s'", rec.len, rec.base);
397 /* ok, we had a header */
399 if (fw_parse(&mem, &rec))
404 start_addr = rec.addr;
407 } else if (rec.type == 1) {
411 } else if (rec.type != 0) {
412 mod_alert("unknown record type 0x%04x", rec.type);
416 for (sum = 0, mem_lp = rec.base, mem_end = &mem_lp[rec.len];
417 mem_lp < mem_end; ++mem_lp)
420 memcpy_toio(&card->dpram. virt[card->desc->app.offs],
422 pcpy->src = card->desc->app.offs + card->desc->app.addr;
423 pcpy->dst = rec.addr;
426 if (softing_bootloader_command(card, 1, "loading app."))
429 rx_sum = card->dpram.receipt[1];
430 if (rx_sum != (sum & 0xffff)) {
431 mod_alert("SRAM seems to be damaged"
432 ", wanted 0x%04x, got 0x%04x", sum, rx_sum);
437 release_firmware(fw);
439 /*got start, start_addr, & eof */
443 } *pcmd = (struct cmd *)&card->dpram.command[1];
444 pcmd->start = start_addr;
445 pcmd->autorestart = 1;
446 if (!softing_bootloader_command(card, 3, "start app.")) {
447 mod_trace("%s: card app. run at 0x%06x"
448 , card->id.name, start_addr);
456 int softing_reset_chip(struct softing *card)
458 mod_trace("%s", card->id.name);
461 card->dpram.info->reset_rcv_fifo = 0;
462 card->dpram.info->reset = 1;
463 if (!softing_fct_cmd(card, 0, 0, "reset_chip"))
465 if (signal_pending(current))
468 if (softing_fct_cmd(card, 99, 0x55, "sync-a"))
470 if (softing_fct_cmd(card, 99, 0xaa, "sync-a"))
473 card->tx.pending = 0;
479 int softing_reinit(struct softing *card, int bus0, int bus1)
482 int restarted_bus = -1;
483 mod_trace("%s", card->id.name);
487 bus0 = (card->bus[0]->netdev->flags & IFF_UP) ? 1 : 0;
490 } else if (bus1 < 0) {
491 bus1 = (card->bus[1]->netdev->flags & IFF_UP) ? 1 : 0;
497 card->bus[0]->can.state = CAN_STATE_STOPPED;
498 softing_flush_echo_skb(card->bus[0]);
501 card->bus[1]->can.state = CAN_STATE_STOPPED;
502 softing_flush_echo_skb(card->bus[1]);
506 if (!bus0 && !bus1) {
507 softing_card_irq(card, 0);
508 softing_reset_chip(card);
510 netif_carrier_off(card->bus[0]->netdev);
512 netif_carrier_off(card->bus[1]->netdev);
515 ret = softing_reset_chip(card);
517 softing_card_irq(card, 0);
522 card->dpram.fct->param[1] = card->bus[0]->can.bittiming.brp;
523 card->dpram.fct->param[2] = card->bus[0]->can.bittiming.sjw;
524 card->dpram.fct->param[3] =
525 card->bus[0]->can.bittiming.phase_seg1 +
526 card->bus[0]->can.bittiming.prop_seg;
527 card->dpram.fct->param[4] =
528 card->bus[0]->can.bittiming.phase_seg2;
529 card->dpram.fct->param[5] = (card->bus[0]->can.ctrlmode &
530 CAN_CTRLMODE_3_SAMPLES)?1:0;
531 if (softing_fct_cmd(card, 1, 0, "initialize_chip[0]"))
534 card->dpram.fct->param[1] = 0;
535 card->dpram.fct->param[2] = 0;
536 if (softing_fct_cmd(card, 3, 0, "set_mode[0]"))
539 card->dpram.fct->param[1] = 0x0000;/*card->bus[0].s.msg; */
540 card->dpram.fct->param[2] = 0x07ff;/*card->bus[0].s.msk; */
541 card->dpram.fct->param[3] = 0x0000;/*card->bus[0].l.msg; */
542 card->dpram.fct->param[4] = 0xffff;/*card->bus[0].l.msk; */
543 card->dpram.fct->param[5] = 0x0000;/*card->bus[0].l.msg >> 16;*/
544 card->dpram.fct->param[6] = 0x1fff;/*card->bus[0].l.msk >> 16;*/
545 if (softing_fct_cmd(card, 7, 0, "set_filter[0]"))
547 /*set output control */
548 card->dpram.fct->param[1] = card->bus[0]->output;
549 if (softing_fct_cmd(card, 5, 0, "set_output[0]"))
554 card->dpram.fct->param[1] = card->bus[1]->can.bittiming.brp;
555 card->dpram.fct->param[2] = card->bus[1]->can.bittiming.sjw;
556 card->dpram.fct->param[3] =
557 card->bus[1]->can.bittiming.phase_seg1 +
558 card->bus[1]->can.bittiming.prop_seg;
559 card->dpram.fct->param[4] =
560 card->bus[1]->can.bittiming.phase_seg2;
561 card->dpram.fct->param[5] = (card->bus[1]->can.ctrlmode &
562 CAN_CTRLMODE_3_SAMPLES)?1:0;
563 if (softing_fct_cmd(card, 2, 0, "initialize_chip[1]"))
566 card->dpram.fct->param[1] = 0;
567 card->dpram.fct->param[2] = 0;
568 if (softing_fct_cmd(card, 4, 0, "set_mode[1]"))
571 card->dpram.fct->param[1] = 0x0000;/*card->bus[1].s.msg; */
572 card->dpram.fct->param[2] = 0x07ff;/*card->bus[1].s.msk; */
573 card->dpram.fct->param[3] = 0x0000;/*card->bus[1].l.msg; */
574 card->dpram.fct->param[4] = 0xffff;/*card->bus[1].l.msk; */
575 card->dpram.fct->param[5] = 0x0000;/*card->bus[1].l.msg >> 16;*/
576 card->dpram.fct->param[6] = 0x1fff;/*card->bus[1].l.msk >> 16;*/
577 if (softing_fct_cmd(card, 8, 0, "set_filter[1]"))
579 /*set output control2 */
580 card->dpram.fct->param[1] = card->bus[1]->output;
581 if (softing_fct_cmd(card, 6, 0, "set_output[1]"))
585 /*enable_error_frame */
586 if (softing_fct_cmd(card, 51, 0, "enable_error_frame"))
588 /*initialize interface */
589 card->dpram.fct->param[1] = 1;
590 card->dpram.fct->param[2] = 1;
591 card->dpram.fct->param[3] = 1;
592 card->dpram.fct->param[4] = 1;
593 card->dpram.fct->param[5] = 1;
594 card->dpram.fct->param[6] = 1;
595 card->dpram.fct->param[7] = 1;
596 card->dpram.fct->param[8] = 1;
597 card->dpram.fct->param[9] = 1;
598 card->dpram.fct->param[10] = 1;
599 if (softing_fct_cmd(card, 17, 0, "initialize_interface"))
602 if (softing_fct_cmd(card, 36, 0, "enable_fifo"))
604 /*enable fifo tx ack */
605 if (softing_fct_cmd(card, 13, 0, "fifo_tx_ack[0]"))
607 /*enable fifo tx ack2 */
608 if (softing_fct_cmd(card, 14, 0, "fifo_tx_ack[1]"))
610 /*enable timestamps */
611 /*is default, no code found */
613 if (softing_fct_cmd(card, 11, 0, "start_chip"))
615 card->dpram.info->bus_state = 0;
616 card->dpram.info->bus_state2 = 0;
617 mod_info("ok for %s, %s/%s\n", card->bus[0]->netdev->name,
618 card->bus[1]->netdev->name, card->id.name);
619 if (card->desc->generation < 2) {
620 card->dpram.irq->to_host = 0;
621 /* flush the DPRAM caches */
625 /*the bottom halve will start flushing the tx-queue too */
626 tasklet_schedule(&card->irq.bh);
628 ret = softing_card_irq(card, 1);
632 /*TODO: generate RESTARTED messages */
634 if (card->bus[0] && bus0) {
635 card->bus[0]->can.state = CAN_STATE_ACTIVE;
636 netif_carrier_on(card->bus[0]->netdev);
638 if (card->bus[1] && bus1) {
639 card->bus[1]->can.state = CAN_STATE_ACTIVE;
640 netif_carrier_on(card->bus[1]->netdev);
644 softing_card_irq(card, 0);
645 softing_reset_chip(card);
647 netif_carrier_off(card->bus[0]->netdev);
649 netif_carrier_off(card->bus[1]->netdev);
654 int softing_default_output(struct softing *card, struct softing_priv *priv)
656 switch (priv->chip) {
658 if (card->desc->generation < 2)
668 u32 softing_time2usec(struct softing *card, u32 raw)
670 /*TODO : don't loose higher order bits in computation */
671 switch (card->desc->freq) {
677 return raw * 16 / 25;