Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

can: janz-ican3: add support for CAL/CANopen firmware

In our department we are using some older Janz ICAN3-modules in our dekstop
pcs. There we have slightly different carrier boards than the janz-cmodio
supported in the kernel sources, called CAN-PCI2 with two submodules. But the
pci configuration regions are identical. So extending the supported pci devices
to the corresponding device ids is sufficient to get the drivers working.

* The old ICAN3-modules with firmware 1.28 need more then 250ms for the restart
after reset. I've increased the timeout to 500ms.
* The janz_ican3 module uses the raw can services of the Janz-firmware, this
means firmware must be ICANOS/2. Our ICAN3-modules are equipped with
CAL/CANopen-firmware, so I must use the appropriate commands for the layer
management services.

Te driver detects the firmware after module reset and selects the commands
matching the firmware. This affects the bus on/off-command
(ican3_set_bus_state) and the configuration of the bittiming
(ican3_set_bittiming). For better diagnostics the detected firmware string is
presented as sysfs attribute (fwinfo).

Signed-off-by: Andreas Gröger <andreas24groeger@gmail.com>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>

authored by

Andreas Gröger and committed by
Marc Kleine-Budde
844e0edf 0d1802ef

+101 -37
+9
Documentation/ABI/testing/sysfs-class-net-janz-ican3
··· 8 8 Default: 1 (termination active) 9 9 Reading: get actual termination state 10 10 Writing: set actual termination state (0=no termination, 1=termination active) 11 + 12 + What: /sys/class/net/<iface>/fwinfo 13 + Date: May 2015 14 + KernelVersion: 3.19 15 + Contact: Andreas Gröger <andreas24groeger@gmail.com> 16 + Description: 17 + Firmware stamp of ican3 module 18 + Read-only: 32 byte string identification of the ICAN3 module 19 + (known values: "JANZ-ICAN3 ICANOS 1.xx", "JANZ-ICAN3 CAL/CANopen 1.xx")
+4
drivers/mfd/janz-cmodio.c
··· 267 267 static const struct pci_device_id cmodio_pci_ids[] = { 268 268 { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, PCI_VENDOR_ID_JANZ, 0x0101 }, 269 269 { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, PCI_VENDOR_ID_JANZ, 0x0100 }, 270 + { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, PCI_VENDOR_ID_JANZ, 0x0201 }, 271 + { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, PCI_VENDOR_ID_JANZ, 0x0202 }, 272 + { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, PCI_VENDOR_ID_JANZ, 0x0201 }, 273 + { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, PCI_VENDOR_ID_JANZ, 0x0202 }, 270 274 { 0, } 271 275 }; 272 276 MODULE_DEVICE_TABLE(pci, cmodio_pci_ids);
+88 -37
drivers/net/can/janz-ican3.c
··· 40 40 #define MSYNC_PEER 0x00 /* ICAN only */ 41 41 #define MSYNC_LOCL 0x01 /* host only */ 42 42 #define TARGET_RUNNING 0x02 43 + #define FIRMWARE_STAMP 0x60 /* big endian firmware stamp */ 43 44 44 45 #define MSYNC_RB0 0x01 45 46 #define MSYNC_RB1 0x02 ··· 84 83 #define MSG_COFFREQ 0x42 85 84 #define MSG_CONREQ 0x43 86 85 #define MSG_CCONFREQ 0x47 86 + #define MSG_LMTS 0xb4 87 87 88 88 /* 89 89 * Janz ICAN3 CAN Inquiry Message Types ··· 167 165 /* SJA1000 Clock Input */ 168 166 #define ICAN3_CAN_CLOCK 8000000 169 167 168 + /* Janz ICAN3 firmware types */ 169 + enum ican3_fwtype { 170 + ICAN3_FWTYPE_ICANOS, 171 + ICAN3_FWTYPE_CAL_CANOPEN, 172 + }; 173 + 170 174 /* Driver Name */ 171 175 #define DRV_NAME "janz-ican3" 172 176 ··· 222 214 /* CAN bus error status registers */ 223 215 struct completion buserror_comp; 224 216 struct can_berr_counter bec; 217 + 218 + /* firmware type */ 219 + enum ican3_fwtype fwtype; 220 + char fwinfo[32]; 225 221 226 222 /* old and new style host interface */ 227 223 unsigned int iftype; ··· 762 750 */ 763 751 static int ican3_set_bus_state(struct ican3_dev *mod, bool on) 764 752 { 753 + struct can_bittiming *bt = &mod->can.bittiming; 765 754 struct ican3_msg msg; 755 + u8 btr0, btr1; 756 + int res; 766 757 767 - memset(&msg, 0, sizeof(msg)); 768 - msg.spec = on ? MSG_CONREQ : MSG_COFFREQ; 769 - msg.len = cpu_to_le16(0); 758 + /* This algorithm was stolen from drivers/net/can/sja1000/sja1000.c */ 759 + /* The bittiming register command for the ICAN3 just sets the bit timing */ 760 + /* registers on the SJA1000 chip directly */ 761 + btr0 = ((bt->brp - 1) & 0x3f) | (((bt->sjw - 1) & 0x3) << 6); 762 + btr1 = ((bt->prop_seg + bt->phase_seg1 - 1) & 0xf) | 763 + (((bt->phase_seg2 - 1) & 0x7) << 4); 764 + if (mod->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) 765 + btr1 |= 0x80; 770 766 771 - return ican3_send_msg(mod, &msg); 767 + if (mod->fwtype == ICAN3_FWTYPE_ICANOS) { 768 + if (on) { 769 + /* set bittiming */ 770 + memset(&msg, 0, sizeof(msg)); 771 + msg.spec = MSG_CBTRREQ; 772 + msg.len = cpu_to_le16(4); 773 + msg.data[0] = 0x00; 774 + msg.data[1] = 0x00; 775 + msg.data[2] = btr0; 776 + msg.data[3] = btr1; 777 + 778 + res = ican3_send_msg(mod, &msg); 779 + if (res) 780 + return res; 781 + } 782 + 783 + /* can-on/off request */ 784 + memset(&msg, 0, sizeof(msg)); 785 + msg.spec = on ? MSG_CONREQ : MSG_COFFREQ; 786 + msg.len = cpu_to_le16(0); 787 + 788 + return ican3_send_msg(mod, &msg); 789 + 790 + } else if (mod->fwtype == ICAN3_FWTYPE_CAL_CANOPEN) { 791 + memset(&msg, 0, sizeof(msg)); 792 + msg.spec = MSG_LMTS; 793 + if (on) { 794 + msg.len = cpu_to_le16(4); 795 + msg.data[0] = 0; 796 + msg.data[1] = 0; 797 + msg.data[2] = btr0; 798 + msg.data[3] = btr1; 799 + } else { 800 + msg.len = cpu_to_le16(2); 801 + msg.data[0] = 1; 802 + msg.data[1] = 0; 803 + } 804 + 805 + return ican3_send_msg(mod, &msg); 806 + } 807 + return -ENOTSUPP; 772 808 } 773 809 774 810 static int ican3_set_termination(struct ican3_dev *mod, bool on) ··· 1462 1402 return 0; 1463 1403 1464 1404 msleep(10); 1465 - } while (time_before(jiffies, start + HZ / 4)); 1405 + } while (time_before(jiffies, start + HZ / 2)); 1466 1406 1467 1407 netdev_err(mod->ndev, "failed to reset CAN module\n"); 1468 1408 return -ETIMEDOUT; ··· 1486 1426 netdev_err(mod->ndev, "unable to reset module\n"); 1487 1427 return ret; 1488 1428 } 1429 + 1430 + /* detect firmware */ 1431 + memcpy_fromio(mod->fwinfo, mod->dpm + FIRMWARE_STAMP, sizeof(mod->fwinfo) - 1); 1432 + if (strncmp(mod->fwinfo, "JANZ-ICAN3", 10)) { 1433 + netdev_err(mod->ndev, "ICAN3 not detected (found %s)\n", mod->fwinfo); 1434 + return -ENODEV; 1435 + } 1436 + if (strstr(mod->fwinfo, "CAL/CANopen")) 1437 + mod->fwtype = ICAN3_FWTYPE_CAL_CANOPEN; 1438 + else 1439 + mod->fwtype = ICAN3_FWTYPE_ICANOS; 1489 1440 1490 1441 /* re-enable interrupts so we can send messages */ 1491 1442 iowrite8(1 << mod->num, &mod->ctrl->int_enable); ··· 1686 1615 .brp_inc = 1, 1687 1616 }; 1688 1617 1689 - /* 1690 - * This routine was stolen from drivers/net/can/sja1000/sja1000.c 1691 - * 1692 - * The bittiming register command for the ICAN3 just sets the bit timing 1693 - * registers on the SJA1000 chip directly 1694 - */ 1695 - static int ican3_set_bittiming(struct net_device *ndev) 1696 - { 1697 - struct ican3_dev *mod = netdev_priv(ndev); 1698 - struct can_bittiming *bt = &mod->can.bittiming; 1699 - struct ican3_msg msg; 1700 - u8 btr0, btr1; 1701 - 1702 - btr0 = ((bt->brp - 1) & 0x3f) | (((bt->sjw - 1) & 0x3) << 6); 1703 - btr1 = ((bt->prop_seg + bt->phase_seg1 - 1) & 0xf) | 1704 - (((bt->phase_seg2 - 1) & 0x7) << 4); 1705 - if (mod->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) 1706 - btr1 |= 0x80; 1707 - 1708 - memset(&msg, 0, sizeof(msg)); 1709 - msg.spec = MSG_CBTRREQ; 1710 - msg.len = cpu_to_le16(4); 1711 - msg.data[0] = 0x00; 1712 - msg.data[1] = 0x00; 1713 - msg.data[2] = btr0; 1714 - msg.data[3] = btr1; 1715 - 1716 - return ican3_send_msg(mod, &msg); 1717 - } 1718 - 1719 1618 static int ican3_set_mode(struct net_device *ndev, enum can_mode mode) 1720 1619 { 1721 1620 struct ican3_dev *mod = netdev_priv(ndev); ··· 1771 1730 return count; 1772 1731 } 1773 1732 1733 + static ssize_t ican3_sysfs_show_fwinfo(struct device *dev, 1734 + struct device_attribute *attr, 1735 + char *buf) 1736 + { 1737 + struct ican3_dev *mod = netdev_priv(to_net_dev(dev)); 1738 + 1739 + return scnprintf(buf, PAGE_SIZE, "%s\n", mod->fwinfo); 1740 + } 1741 + 1774 1742 static DEVICE_ATTR(termination, S_IWUSR | S_IRUGO, ican3_sysfs_show_term, 1775 1743 ican3_sysfs_set_term); 1744 + static DEVICE_ATTR(fwinfo, S_IRUSR | S_IRUGO, ican3_sysfs_show_fwinfo, NULL); 1776 1745 1777 1746 static struct attribute *ican3_sysfs_attrs[] = { 1778 1747 &dev_attr_termination.attr, 1748 + &dev_attr_fwinfo.attr, 1779 1749 NULL, 1780 1750 }; 1781 1751 ··· 1846 1794 1847 1795 mod->can.clock.freq = ICAN3_CAN_CLOCK; 1848 1796 mod->can.bittiming_const = &ican3_bittiming_const; 1849 - mod->can.do_set_bittiming = ican3_set_bittiming; 1850 1797 mod->can.do_set_mode = ican3_set_mode; 1851 1798 mod->can.do_get_berr_counter = ican3_get_berr_counter; 1852 1799 mod->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES ··· 1917 1866 goto out_free_irq; 1918 1867 } 1919 1868 1920 - dev_info(dev, "module %d: registered CAN device\n", pdata->modno); 1869 + netdev_info(mod->ndev, "module %d: registered CAN device\n", pdata->modno); 1921 1870 return 0; 1922 1871 1923 1872 out_free_irq: