683 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (C) 2008-20104 *5 * - Kurt Van Dijck, EIA Electronics6 */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 preset18 */19static 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(500, 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 53static 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, 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 65int 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(500, 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 94static 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. the111 * struct itself may be an odd address)?112 *113 * I chose to use leXX_to_cpup() since this solves both114 * endianness & alignment.115 */116 mem = *pmem;117 *ptype = le16_to_cpup((void *)&mem[0]);118 *paddr = le32_to_cpup((void *)&mem[2]);119 *plen = le16_to_cpup((void *)&mem[6]);120 *pdat = &mem[8];121 /* verify checksum */122 end = &mem[8 + *plen];123 checksum[0] = le16_to_cpup((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 133int 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, file, &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(&mem, &type, &addr, &len, &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(&mem, &type, &addr, &len, &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(buf, 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(buf, dat, 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;210failed:211 kfree(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 218int 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, file, &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(&mem, &type, &addr, &len, &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(&mem, &type, &addr, &len, &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, 1, "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, 3, "start app.");306 if (ret < 0)307 goto failed;308 ret = 0;309failed:310 release_firmware(fw);311 if (ret < 0)312 dev_info(&card->pdev->dev, "firmware %s failed\n", file);313 return ret;314}315 316static 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, 0, "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 338int softing_chip_poweron(struct softing *card)339{340 int ret;341 /* sync */342 ret = _softing_fct_cmd(card, 99, 0x55, "sync-a");343 if (ret < 0)344 goto failed;345 346 ret = _softing_fct_cmd(card, 99, 0xaa, "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, 43, "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, 12, "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;368failed:369 return ret;370}371 372static 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(0, ovf);383}384 385ktime_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(card->ts_ref, 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 409static inline int softing_error_reporting(struct net_device *netdev)410{411 struct softing_priv *priv = netdev_priv(netdev);412 413 return (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)414 ? 1 : 0;415}416 417int 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(netdev);448 449 if (dev != netdev)450 netif_stop_queue(netdev);451 452 if (netif_running(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 * already462 * but we may come here from busoff recovery too463 * in which case the echo_skb _needs_ flushing too.464 * just be sure to call open_candev() again465 */466 close_candev(netdev);467 }468 priv->can.state = CAN_STATE_STOPPED;469 }470 card->tx.pending = 0;471 472 softing_enable_irq(card, 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(card->net[0])482 != softing_error_reporting(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(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, 1, "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, 3, "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, 7, "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, 5, "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(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, 2, "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, 4, "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, 8, "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, 6, "set_output[1]");565 if (ret < 0)566 goto failed;567 }568 569 /* enable_error_frame570 *571 * Error reporting is switched off at the moment since572 * the receiving of them is not yet 100% verified573 * This should be enabled sooner or later574 */575 if (0 && error_reporting) {576 ret = softing_fct_cmd(card, 51, "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, 17, "initialize_interface");593 if (ret < 0)594 goto failed;595 /* enable_fifo */596 ret = softing_fct_cmd(card, 36, "enable_fifo");597 if (ret < 0)598 goto failed;599 /* enable fifo tx ack */600 ret = softing_fct_cmd(card, 13, "fifo_tx_ack[0]");601 if (ret < 0)602 goto failed;603 /* enable fifo tx ack2 */604 ret = softing_fct_cmd(card, 14, "fifo_tx_ack[1]");605 if (ret < 0)606 goto failed;607 /* start_chip */608 ret = softing_fct_cmd(card, 11, "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 changes623 * from here, no errors should occur, or the failed: part624 * must be reviewed625 */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(netdev);636 priv->can.state = CAN_STATE_ERROR_ACTIVE;637 open_candev(netdev);638 if (dev != netdev) {639 /* notify other buses on the restart */640 softing_netdev_rx(netdev, &msg, 0);641 ++priv->can.can_stats.restarts;642 }643 netif_wake_queue(netdev);644 }645 646 /* enable interrupts */647 ret = softing_enable_irq(card, 1);648 if (ret)649 goto failed;650card_done:651 mutex_unlock(&card->fw.lock);652 return 0;653invalid:654 ret = -EINVAL;655failed:656 softing_enable_irq(card, 0);657 softing_reset_chip(card);658 mutex_unlock(&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(netdev);665 }666 return ret;667}668 669int softing_default_output(struct net_device *netdev)670{671 struct softing_priv *priv = netdev_priv(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