]> rtime.felk.cvut.cz Git - socketcan-devel.git/blob - kernel/2.6/drivers/net/can/softing/softing_fw.c
net/can bugfix: use after free bug in can protocol drivers
[socketcan-devel.git] / kernel / 2.6 / drivers / net / can / softing / softing_fw.c
1 /*
2 * drivers/net/can/softing/softing_fw.c
3 *
4 * Copyright (C) 2008
5 *
6 * - Kurt Van Dijck, EIA Electronics
7 *
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
11 *
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.
16 *
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
20 */
21
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>
28 #include <linux/io.h>
29
30 #include "softing.h"
31
32 #define fw_dir "softing-4.6/"
33
34 const struct can_bittiming_const softing_btr_const = {
35         .tseg1_min = 1,
36         .tseg1_max = 16,
37         .tseg2_min = 1,
38         .tseg2_max = 8,
39         .sjw_max = 4, /* overruled */
40         .brp_min = 1,
41         .brp_max = 32, /* overruled */
42         .brp_inc = 1,
43 };
44
45 static const struct softing_desc carddescs[] = {
46 {
47         .name = "CANcard",
48         .manf = 0x0168, .prod = 0x001,
49         .generation = 1,
50         .freq = 16, .max_brp = 32, .max_sjw = 4,
51         .dpram_size = 0x0800,
52         .boot = {0x0000, 0x000000, fw_dir "bcard.bin",},
53         .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",},
54         .app = {0x0010, 0x0d0000, fw_dir "cancard.bin",},
55 }, {
56         .name = "CANcard-NEC",
57         .manf = 0x0168, .prod = 0x002,
58         .generation = 1,
59         .freq = 16, .max_brp = 32, .max_sjw = 4,
60         .dpram_size = 0x0800,
61         .boot = {0x0000, 0x000000, fw_dir "bcard.bin",},
62         .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",},
63         .app = {0x0010, 0x0d0000, fw_dir "cancard.bin",},
64 }, {
65         .name = "CANcard-SJA",
66         .manf = 0x0168, .prod = 0x004,
67         .generation = 1,
68         .freq = 20, .max_brp = 32, .max_sjw = 4,
69         .dpram_size = 0x0800,
70         .boot = {0x0000, 0x000000, fw_dir "bcard.bin",},
71         .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",},
72         .app = {0x0010, 0x0d0000, fw_dir "cansja.bin",},
73 }, {
74         .name = "CANcard-2",
75         .manf = 0x0168, .prod = 0x005,
76         .generation = 2,
77         .freq = 24, .max_brp = 64, .max_sjw = 4,
78         .dpram_size = 0x0800,
79         .boot = {0x0000, 0x000000, fw_dir "bcard2.bin",},
80         .load = {0x0120, 0x00f600, fw_dir "ldcard2.bin",},
81         .app = {0x0010, 0x0d0000, fw_dir "cancrd2.bin",},
82 }, {
83         .name = "Vector-CANcard",
84         .manf = 0x0168, .prod = 0x081,
85         .generation = 1,
86         .freq = 16, .max_brp = 64, .max_sjw = 4,
87         .dpram_size = 0x0800,
88         .boot = {0x0000, 0x000000, fw_dir "bcard.bin",},
89         .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",},
90         .app = {0x0010, 0x0d0000, fw_dir "cancard.bin",},
91 }, {
92         .name = "Vector-CANcard-SJA",
93         .manf = 0x0168, .prod = 0x084,
94         .generation = 1,
95         .freq = 20, .max_brp = 32, .max_sjw = 4,
96         .dpram_size = 0x0800,
97         .boot = {0x0000, 0x000000, fw_dir "bcard.bin",},
98         .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",},
99         .app = {0x0010, 0x0d0000, fw_dir "cansja.bin",},
100 }, {
101         .name = "Vector-CANcard-2",
102         .manf = 0x0168, .prod = 0x085,
103         .generation = 2,
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",},
109 }, {
110         .name = "EDICcard-NEC",
111         .manf = 0x0168, .prod = 0x102,
112         .generation = 1,
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",},
118 }, {
119         .name = "EDICcard-2",
120         .manf = 0x0168, .prod = 0x105,
121         .generation = 2,
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",},
127         },
128
129 /* never tested, but taken from original softing */
130 {       .name = "CAN-AC2-104",
131         .manf = 0x0000, .prod = 0x009,
132         .generation = 1,
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",},
138         },
139 {0, 0,},
140 };
141
142 const struct softing_desc *softing_lookup_desc
143                                         (unsigned int manf, unsigned int prod)
144 {
145         const struct softing_desc *lp = carddescs;
146         for (; lp->name; ++lp) {
147                 if ((lp->manf == manf) && (lp->prod == prod))
148                         return lp;
149         }
150         return 0;
151 }
152 EXPORT_SYMBOL(softing_lookup_desc);
153
154 int softing_fct_cmd(struct softing *card, int cmd, int vector, const char *msg)
155 {
156         int ret;
157         unsigned long stamp;
158         if (vector == RES_OK)
159                 vector = RES_NONE;
160         card->dpram.fct->param[0] = cmd;
161         card->dpram.fct->host_access = vector;
162         /* be sure to flush this to the card */
163         wmb();
164         stamp = jiffies;
165         /*wait for card */
166         do {
167                 ret = card->dpram.fct->host_access;
168                 /* don't have any cached variables */
169                 rmb();
170                 if (ret == RES_OK) {
171                         /*don't read return-value now */
172                         ret = card->dpram.fct->returned;
173                         if (ret)
174                                 mod_alert("%s returned %u", msg, ret);
175                         return 0;
176                 }
177                 if ((jiffies - stamp) >= 1 * HZ)
178                         break;
179                 if (in_interrupt())
180                         /* go as fast as possible */
181                         continue;
182                 /* process context => relax */
183                 schedule();
184         } while (!signal_pending(current));
185
186         if (ret == RES_NONE) {
187                 mod_alert("%s, no response from card on %u/0x%02x"
188                         , msg, cmd, vector);
189                 return 1;
190         } else {
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;
195         }
196 }
197
198 int softing_bootloader_command(struct softing *card
199                 , int command, const char *msg)
200 {
201         int ret;
202         unsigned long stamp;
203         card->dpram.receipt[0] = RES_NONE;
204         card->dpram.command[0] = command;
205         /* be sure to flush this to the card */
206         wmb();
207         stamp = jiffies;
208         /*wait for card */
209         do {
210                 ret = card->dpram.receipt[0];
211                 /* don't have any cached variables */
212                 rmb();
213                 if (ret == RES_OK)
214                         return 0;
215                 if ((jiffies - stamp) >= (3 * HZ))
216                         break;
217                 schedule();
218         } while (!signal_pending(current));
219
220         switch (ret) {
221         case RES_NONE:
222                 mod_alert("%s: no response from card", msg);
223                 break;
224         case RES_NOK:
225                 mod_alert("%s: response from card nok", msg);
226                 break;
227         case RES_UNKNOWN:
228                 mod_alert("%s: command 0x%04x unknown", msg, command);
229                 break;
230         default:
231                 mod_alert("%s: bad response from card (%u)]", msg, ret);
232                 break;
233         }
234         return ret ? ret : 1;
235 }
236
237 struct fw_hdr {
238         u16 type;
239         u32 addr;
240         u16 len;
241         u16 checksum;
242         const unsigned char *base;
243 } __attribute__ ((packed));
244
245 static int fw_parse(const unsigned char **pmem, struct fw_hdr *hdr)
246 {
247         u16 tmp;
248         const unsigned char *mem;
249         const unsigned char *end;
250         mem = *pmem;
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);
255         hdr->base = &mem[8];
256         hdr->checksum =
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)
259                 tmp += *mem;
260         if (tmp != hdr->checksum)
261                 return EINVAL;
262         *pmem += 10 + hdr->len;
263         return 0;
264 }
265
266 int softing_load_fw(const char *file, struct softing *card,
267                         unsigned char *virt, unsigned int size, int offset)
268 {
269         const struct firmware *fw;
270         const unsigned char *mem;
271         const unsigned char *end;
272         int ret;
273         u32 start_addr;
274         struct fw_hdr rec;
275         int ok = 0;
276         unsigned char buf[256];
277
278         ret = request_firmware(&fw, file, card->dev);
279         if (ret) {
280                 mod_alert("request_firmware(%s) got %i", file, ret);
281                 return ret;
282         }
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 */
287         mem = fw->data;
288         end = &mem[fw->size];
289         /* look for header record */
290         if (fw_parse(&mem, &rec))
291                 goto fw_end;
292         if (rec.type != 0xffff) {
293                 mod_alert("firware starts with type 0x%04x", rec.type);
294                 goto fw_end;
295         }
296         if (strncmp("Structured Binary Format, Softing GmbH"
297                         , rec.base, rec.len)) {
298                 mod_info("firware string '%.*s'", rec.len, rec.base);
299                 goto fw_end;
300         }
301         ok |= 1;
302         /* ok, we had a header */
303         while (mem < end) {
304                 if (fw_parse(&mem, &rec))
305                         break;
306                 if (rec.type == 3) {
307                         /*start address */
308                         start_addr = rec.addr;
309                         ok |= 2;
310                         continue;
311                 } else if (rec.type == 1) {
312                         /*eof */
313                         ok |= 4;
314                         goto fw_end;
315                 } else if (rec.type != 0) {
316                         mod_alert("unknown record type 0x%04x", rec.type);
317                         break;
318                 }
319
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);
323                         goto fw_end;
324                 }
325                 memcpy_toio(&virt[rec.addr + offset],
326                                  rec.base, rec.len);
327                 /* be sure to flush caches from IO space */
328                 mb();
329                 if (rec.len > sizeof(buf)) {
330                         mod_info("record is big (%u bytes), not verifying"
331                                 , rec.len);
332                         continue;
333                 }
334                 /* verify record data */
335                 memcpy_fromio(buf, &virt[rec.addr + offset], rec.len);
336                 if (!memcmp(buf, rec.base, rec.len))
337                         /* is ok */
338                         continue;
339                 mod_alert("0x%08x:0x%03x at 0x%p failed", rec.addr, rec.len
340                         , &virt[rec.addr + offset]);
341                 goto fw_end;
342         }
343 fw_end:
344         release_firmware(fw);
345         if (0x5 == (ok & 0x5)) {
346                 /*got eof & start */
347                 return 0;
348         }
349         mod_alert("failed");
350         return EINVAL;
351 }
352
353 int softing_load_app_fw(const char *file, struct softing *card)
354 {
355         const struct firmware *fw;
356         const unsigned char *mem;
357         const unsigned char *end;
358         int ret;
359         struct fw_hdr rec;
360         int ok = 0;
361         u32 start_addr = 0;
362         u16 rx_sum;
363         unsigned int sum;
364         const unsigned char *mem_lp;
365         const unsigned char *mem_end;
366         struct cpy {
367                 u32 src;
368                 u32 dst;
369                 u16 len;
370                 u8 do_cs;
371         } __attribute__((packed)) *pcpy =
372                  (struct cpy *)&card->dpram.command[1];
373
374         ret = request_firmware(&fw, file, card->dev);
375         if (ret) {
376                 mod_alert("request_firmware(%s) got %i", file, ret);
377                 return ret;
378         }
379         mod_trace("%s, firmware(%s) got %lu bytes", card->id.name, file,
380                   (unsigned long)fw->size);
381         /* parse the firmware */
382         mem = fw->data;
383         end = &mem[fw->size];
384         /* look for header record */
385         if (fw_parse(&mem, &rec))
386                 goto fw_end;
387         if (rec.type != 0xffff) {
388                 mod_alert("firware starts with type 0x%04x", rec.type);
389                 goto fw_end;
390         }
391         if (strncmp("Structured Binary Format, Softing GmbH"
392                 , rec.base, rec.len)) {
393                 mod_info("firware string '%.*s'", rec.len, rec.base);
394                 goto fw_end;
395         }
396         ok |= 1;
397         /* ok, we had a header */
398         while (mem < end) {
399                 if (fw_parse(&mem, &rec))
400                         break;
401
402                 if (rec.type == 3) {
403                         /*start address */
404                         start_addr = rec.addr;
405                         ok |= 2;
406                         continue;
407                 } else if (rec.type == 1) {
408                         /*eof */
409                         ok |= 4;
410                         goto fw_end;
411                 } else if (rec.type != 0) {
412                         mod_alert("unknown record type 0x%04x", rec.type);
413                         break;
414                 }
415                 /* regualar data */
416                 for (sum = 0, mem_lp = rec.base, mem_end = &mem_lp[rec.len];
417                         mem_lp < mem_end; ++mem_lp)
418                         sum += *mem_lp;
419
420                 memcpy_toio(&card->dpram. virt[card->desc->app.offs],
421                                  rec.base, rec.len);
422                 pcpy->src = card->desc->app.offs + card->desc->app.addr;
423                 pcpy->dst = rec.addr;
424                 pcpy->len = rec.len;
425                 pcpy->do_cs = 1;
426                 if (softing_bootloader_command(card, 1, "loading app."))
427                         goto fw_end;
428                 /*verify checksum */
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);
433                         goto fw_end;
434                 }
435         }
436 fw_end:
437         release_firmware(fw);
438         if (ok == 7) {
439                 /*got start, start_addr, & eof */
440                 struct cmd {
441                         u32 start;
442                         u8 autorestart;
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);
449                         return 0;
450                 }
451         }
452         mod_alert("failed");
453         return EINVAL;
454 }
455
456 int softing_reset_chip(struct softing *card)
457 {
458         mod_trace("%s", card->id.name);
459         do {
460                 /*reset chip */
461                 card->dpram.info->reset_rcv_fifo = 0;
462                 card->dpram.info->reset = 1;
463                 if (!softing_fct_cmd(card, 0, 0, "reset_chip"))
464                         break;
465                 if (signal_pending(current))
466                         goto failed;
467                 /*sync */
468                 if (softing_fct_cmd(card, 99, 0x55, "sync-a"))
469                         goto failed;
470                 if (softing_fct_cmd(card, 99, 0xaa, "sync-a"))
471                         goto failed;
472         } while (1);
473         card->tx.pending = 0;
474         return 0;
475 failed:
476         return -EIO;
477 }
478
479 int softing_reinit(struct softing *card, int bus0, int bus1)
480 {
481         int ret;
482         int restarted_bus = -1;
483         mod_trace("%s", card->id.name);
484         if (!card->fw.up)
485                 return -EIO;
486         if (bus0 < 0) {
487                 bus0 = (card->bus[0]->netdev->flags & IFF_UP) ? 1 : 0;
488                 if (bus0)
489                         restarted_bus = 0;
490         } else if (bus1 < 0) {
491                 bus1 = (card->bus[1]->netdev->flags & IFF_UP) ? 1 : 0;
492                 if (bus1)
493                         restarted_bus = 1;
494         }
495         /* collect info */
496         if (card->bus[0]) {
497                 card->bus[0]->can.state = CAN_STATE_STOPPED;
498                 softing_flush_echo_skb(card->bus[0]);
499         }
500         if (card->bus[1]) {
501                 card->bus[1]->can.state = CAN_STATE_STOPPED;
502                 softing_flush_echo_skb(card->bus[1]);
503         }
504
505         /* start acting */
506         if (!bus0 && !bus1) {
507                 softing_card_irq(card, 0);
508                 softing_reset_chip(card);
509                 if (card->bus[0])
510                         netif_carrier_off(card->bus[0]->netdev);
511                 if (card->bus[1])
512                         netif_carrier_off(card->bus[1]->netdev);
513                 return 0;
514         }
515         ret = softing_reset_chip(card);
516         if (ret) {
517                 softing_card_irq(card, 0);
518                 return ret;
519         }
520         if (bus0) {
521                 /*init chip */
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]"))
532                         goto failed;
533                 /*set mode */
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]"))
537                         goto failed;
538                 /*set filter */
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]"))
546                         goto failed;
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]"))
550                         goto failed;
551         }
552         if (bus1) {
553                 /*init chip2 */
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]"))
564                         goto failed;
565                 /*set mode2 */
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]"))
569                         goto failed;
570                 /*set filter2 */
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]"))
578                         goto failed;
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]"))
582                         goto failed;
583         }
584         /*set interrupt */
585         /*enable_error_frame */
586         if (softing_fct_cmd(card, 51, 0, "enable_error_frame"))
587                 goto failed;
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"))
600                 goto failed;
601         /*enable_fifo */
602         if (softing_fct_cmd(card, 36, 0, "enable_fifo"))
603                 goto failed;
604         /*enable fifo tx ack */
605         if (softing_fct_cmd(card, 13, 0, "fifo_tx_ack[0]"))
606                 goto failed;
607         /*enable fifo tx ack2 */
608         if (softing_fct_cmd(card, 14, 0, "fifo_tx_ack[1]"))
609                 goto failed;
610         /*enable timestamps */
611         /*is default, no code found */
612         /*start_chip */
613         if (softing_fct_cmd(card, 11, 0, "start_chip"))
614                 goto failed;
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 */
622                 wmb();
623         }
624         /*run once */
625         /*the bottom halve will start flushing the tx-queue too */
626         tasklet_schedule(&card->irq.bh);
627
628         ret = softing_card_irq(card, 1);
629         if (ret)
630                 goto failed;
631
632         /*TODO: generate RESTARTED messages */
633
634         if (card->bus[0] && bus0) {
635                 card->bus[0]->can.state = CAN_STATE_ACTIVE;
636                 netif_carrier_on(card->bus[0]->netdev);
637         }
638         if (card->bus[1] && bus1) {
639                 card->bus[1]->can.state = CAN_STATE_ACTIVE;
640                 netif_carrier_on(card->bus[1]->netdev);
641         }
642         return 0;
643 failed:
644         softing_card_irq(card, 0);
645         softing_reset_chip(card);
646         if (card->bus[0])
647                 netif_carrier_off(card->bus[0]->netdev);
648         if (card->bus[1])
649                 netif_carrier_off(card->bus[1]->netdev);
650         return -EIO;
651 }
652
653
654 int softing_default_output(struct softing *card, struct softing_priv *priv)
655 {
656         switch (priv->chip) {
657         case 1000:
658                 if (card->desc->generation < 2)
659                         return 0xfb;
660                 return 0xfa;
661         case 5:
662                 return 0x60;
663         default:
664                 return 0x40;
665         }
666 }
667
668 u32 softing_time2usec(struct softing *card, u32 raw)
669 {
670         /*TODO : don't loose higher order bits in computation */
671         switch (card->desc->freq) {
672         case 20:
673                 return raw * 4 / 5;
674         case 24:
675                 return raw * 2 / 3;
676         case 25:
677                 return raw * 16 / 25;
678         case 0:
679         case 16:
680         default:
681                 return raw;
682         }
683 }
684
685