Marc Kleine-Budde says: ==================== pull-request: can-next 2015-05-06 this is a pull request of a seven patches for net-next/master. Andreas Gröger contributes two patches for the janz-ican3 driver. In the first patch, the documentation for already existing sysfs entries is added, the second patch adds support for another module/firmware variant. A patch by Shawn Landden makes the padding in the struct can_frame explicit. The next 4 patches target the flexcan driver, the first one is by David Jander adding some documentation, the reaming three by me add more documentation and two small code cleanups. ====================
Unified · Split
| @@ -0,0 +1,8 @@ | |||
| 1 | What: /sys/bus/pci/drivers/janz-cmodio/.../modulbus_number | ||
| 2 | Date: May 2010 | ||
| 3 | KernelVersion: 2.6.35 | ||
| 4 | Contact: Ira W. Snyder <ira.snyder@gmail.com> | ||
| 5 | Description: | ||
| 6 | Value representing the HEX switch S2 of the janz carrier board CMOD-IO or CAN-PCI2 | ||
| 7 | |||
| 8 | Read-only: value of the configuration switch (0..15) | ||
| @@ -0,0 +1,19 @@ | |||
| 1 | What: /sys/class/net/<iface>/termination | ||
| 2 | Date: May 2010 | ||
| 3 | KernelVersion: 2.6.35 | ||
| 4 | Contact: Ira W. Snyder <ira.snyder@gmail.com> | ||
| 5 | Description: | ||
| 6 | Value representing the can bus termination | ||
| 7 | |||
| 8 | Default: 1 (termination active) | ||
| 9 | Reading: get actual termination state | ||
| 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") | ||
| @@ -268,6 +268,9 @@ solution for a couple of reasons: · 267 unmodified lines | |||
| 268 | struct can_frame { | 268 | struct can_frame { |
| 269 | canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */ | 269 | canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */ |
| 270 | __u8 can_dlc; /* frame payload length in byte (0 .. 8) */ | 270 | __u8 can_dlc; /* frame payload length in byte (0 .. 8) */ |
| 271 | __u8 __pad; /* padding */ | ||
| 272 | __u8 __res0; /* reserved / padding */ | ||
| 273 | __u8 __res1; /* reserved / padding */ | ||
| 271 | __u8 data[8] __attribute__((aligned(8))); | 274 | __u8 data[8] __attribute__((aligned(8))); |
| 272 | }; | 275 | }; |
| 273 | 276 | ||
| @@ -267,6 +267,10 @@ static void cmodio_pci_remove(struct pci_dev *dev) · 266 unmodified lines | |||
| 267 | static const struct pci_device_id cmodio_pci_ids[] = { | 267 | static const struct pci_device_id cmodio_pci_ids[] = { |
| 268 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, PCI_VENDOR_ID_JANZ, 0x0101 }, | 268 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, PCI_VENDOR_ID_JANZ, 0x0101 }, |
| 269 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, PCI_VENDOR_ID_JANZ, 0x0100 }, | 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 | { 0, } | 274 | { 0, } |
| 271 | }; | 275 | }; |
| 272 | MODULE_DEVICE_TABLE(pci, cmodio_pci_ids); | 276 | MODULE_DEVICE_TABLE(pci, cmodio_pci_ids); |
| @@ -93,13 +93,13 @@ · 92 unmodified lines | |||
| 93 | (FLEXCAN_CTRL_ERR_BUS | FLEXCAN_CTRL_ERR_STATE) | 93 | (FLEXCAN_CTRL_ERR_BUS | FLEXCAN_CTRL_ERR_STATE) |
| 94 | 94 | ||
| 95 | /* FLEXCAN control register 2 (CTRL2) bits */ | 95 | /* FLEXCAN control register 2 (CTRL2) bits */ |
| 96 | #define FLEXCAN_CRL2_ECRWRE BIT(29) | 96 | #define FLEXCAN_CTRL2_ECRWRE BIT(29) |
| 97 | #define FLEXCAN_CRL2_WRMFRZ BIT(28) | 97 | #define FLEXCAN_CTRL2_WRMFRZ BIT(28) |
| 98 | #define FLEXCAN_CRL2_RFFN(x) (((x) & 0x0f) << 24) | 98 | #define FLEXCAN_CTRL2_RFFN(x) (((x) & 0x0f) << 24) |
| 99 | #define FLEXCAN_CRL2_TASD(x) (((x) & 0x1f) << 19) | 99 | #define FLEXCAN_CTRL2_TASD(x) (((x) & 0x1f) << 19) |
| 100 | #define FLEXCAN_CRL2_MRP BIT(18) | 100 | #define FLEXCAN_CTRL2_MRP BIT(18) |
| 101 | #define FLEXCAN_CRL2_RRS BIT(17) | 101 | #define FLEXCAN_CTRL2_RRS BIT(17) |
| 102 | #define FLEXCAN_CRL2_EACEN BIT(16) | 102 | #define FLEXCAN_CTRL2_EACEN BIT(16) |
| 103 | 103 | ||
| 104 | /* FLEXCAN memory error control register (MECR) bits */ | 104 | /* FLEXCAN memory error control register (MECR) bits */ |
| 105 | #define FLEXCAN_MECR_ECRWRDIS BIT(31) | 105 | #define FLEXCAN_MECR_ECRWRDIS BIT(31) |
| @@ -158,7 +158,6 @@ · 52 unmodified lines | |||
| 158 | FLEXCAN_IFLAG_BUF(FLEXCAN_TX_BUF_ID)) | 158 | FLEXCAN_IFLAG_BUF(FLEXCAN_TX_BUF_ID)) |
| 159 | 159 | ||
| 160 | /* FLEXCAN message buffers */ | 160 | /* FLEXCAN message buffers */ |
| 161 | #define FLEXCAN_MB_CNT_CODE(x) (((x) & 0xf) << 24) | ||
| 162 | #define FLEXCAN_MB_CODE_RX_INACTIVE (0x0 << 24) | 161 | #define FLEXCAN_MB_CODE_RX_INACTIVE (0x0 << 24) |
| 163 | #define FLEXCAN_MB_CODE_RX_EMPTY (0x4 << 24) | 162 | #define FLEXCAN_MB_CODE_RX_EMPTY (0x4 << 24) |
| 164 | #define FLEXCAN_MB_CODE_RX_FULL (0x2 << 24) | 163 | #define FLEXCAN_MB_CODE_RX_FULL (0x2 << 24) |
| @@ -184,14 +183,14 @@ · 19 unmodified lines | |||
| 184 | * FLEXCAN hardware feature flags | 183 | * FLEXCAN hardware feature flags |
| 185 | * | 184 | * |
| 186 | * Below is some version info we got: | 185 | * Below is some version info we got: |
| 187 | * SOC Version IP-Version Glitch- [TR]WRN_INT Memory err | 186 | * SOC Version IP-Version Glitch- [TR]WRN_INT Memory err RTR re- |
| 188 | * Filter? connected? detection | 187 | * Filter? connected? detection ception in MB |
| 189 | * MX25 FlexCAN2 03.00.00.00 no no no | 188 | * MX25 FlexCAN2 03.00.00.00 no no no no |
| 190 | * MX28 FlexCAN2 03.00.04.00 yes yes no | 189 | * MX28 FlexCAN2 03.00.04.00 yes yes no no |
| 191 | * MX35 FlexCAN2 03.00.00.00 no no no | 190 | * MX35 FlexCAN2 03.00.00.00 no no no no |
| 192 | * MX53 FlexCAN2 03.00.00.00 yes no no | 191 | * MX53 FlexCAN2 03.00.00.00 yes no no no |
| 193 | * MX6s FlexCAN3 10.00.12.00 yes yes no | 192 | * MX6s FlexCAN3 10.00.12.00 yes yes no yes |
| 194 | * VF610 FlexCAN3 ? no yes yes | 193 | * VF610 FlexCAN3 ? no yes yes yes? |
| 195 | * | 194 | * |
| 196 | * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected. | 195 | * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected. |
| 197 | */ | 196 | */ |
| @@ -221,7 +220,7 @@ struct flexcan_regs { · 23 unmodified lines | |||
| 221 | u32 imask1; /* 0x28 */ | 220 | u32 imask1; /* 0x28 */ |
| 222 | u32 iflag2; /* 0x2c */ | 221 | u32 iflag2; /* 0x2c */ |
| 223 | u32 iflag1; /* 0x30 */ | 222 | u32 iflag1; /* 0x30 */ |
| 224 | u32 crl2; /* 0x34 */ | 223 | u32 ctrl2; /* 0x34 */ |
| 225 | u32 esr2; /* 0x38 */ | 224 | u32 esr2; /* 0x38 */ |
| 226 | u32 imeur; /* 0x3c */ | 225 | u32 imeur; /* 0x3c */ |
| 227 | u32 lrfr; /* 0x40 */ | 226 | u32 lrfr; /* 0x40 */ |
| @@ -230,6 +229,16 @@ struct flexcan_regs { · 2 unmodified lines | |||
| 230 | u32 rxfir; /* 0x4c */ | 229 | u32 rxfir; /* 0x4c */ |
| 231 | u32 _reserved3[12]; /* 0x50 */ | 230 | u32 _reserved3[12]; /* 0x50 */ |
| 232 | struct flexcan_mb cantxfg[64]; /* 0x80 */ | 231 | struct flexcan_mb cantxfg[64]; /* 0x80 */ |
| 232 | /* FIFO-mode: | ||
| 233 | * MB | ||
| 234 | * 0x080...0x08f 0 RX message buffer | ||
| 235 | * 0x090...0x0df 1-5 reserverd | ||
| 236 | * 0x0e0...0x0ff 6-7 8 entry ID table | ||
| 237 | * (mx25, mx28, mx35, mx53) | ||
| 238 | * 0x0e0...0x2df 6-7..37 8..128 entry ID table | ||
| 239 | * size conf'ed via ctrl2::RFFN | ||
| 240 | * (mx6, vf610) | ||
| 241 | */ | ||
| 233 | u32 _reserved4[408]; | 242 | u32 _reserved4[408]; |
| 234 | u32 mecr; /* 0xae0 */ | 243 | u32 mecr; /* 0xae0 */ |
| 235 | u32 erriar; /* 0xae4 */ | 244 | u32 erriar; /* 0xae4 */ |
| @@ -468,7 +477,7 @@ static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev) · 232 unmodified lines | |||
| 468 | struct flexcan_regs __iomem *regs = priv->base; | 477 | struct flexcan_regs __iomem *regs = priv->base; |
| 469 | struct can_frame *cf = (struct can_frame *)skb->data; | 478 | struct can_frame *cf = (struct can_frame *)skb->data; |
| 470 | u32 can_id; | 479 | u32 can_id; |
| 471 | u32 ctrl = FLEXCAN_MB_CNT_CODE(0xc) | (cf->can_dlc << 16); | 480 | u32 ctrl = FLEXCAN_MB_CODE_TX_DATA | (cf->can_dlc << 16); |
| 472 | 481 | ||
| 473 | if (can_dropped_invalid_skb(dev, skb)) | 482 | if (can_dropped_invalid_skb(dev, skb)) |
| 474 | return NETDEV_TX_OK; | 483 | return NETDEV_TX_OK; |
| @@ -815,7 +824,7 @@ static int flexcan_chip_start(struct net_device *dev) · 340 unmodified lines | |||
| 815 | { | 824 | { |
| 816 | struct flexcan_priv *priv = netdev_priv(dev); | 825 | struct flexcan_priv *priv = netdev_priv(dev); |
| 817 | struct flexcan_regs __iomem *regs = priv->base; | 826 | struct flexcan_regs __iomem *regs = priv->base; |
| 818 | u32 reg_mcr, reg_ctrl, reg_crl2, reg_mecr; | 827 | u32 reg_mcr, reg_ctrl, reg_ctrl2, reg_mecr; |
| 819 | int err, i; | 828 | int err, i; |
| 820 | 829 | ||
| 821 | /* enable module */ | 830 | /* enable module */ |
| @@ -918,9 +927,9 @@ static int flexcan_chip_start(struct net_device *dev) · 96 unmodified lines | |||
| 918 | * and Correction of Memory Errors" to write to | 927 | * and Correction of Memory Errors" to write to |
| 919 | * MECR register | 928 | * MECR register |
| 920 | */ | 929 | */ |
| 921 | reg_crl2 = flexcan_read(®s->crl2); | 930 | reg_ctrl2 = flexcan_read(®s->ctrl2); |
| 922 | reg_crl2 |= FLEXCAN_CRL2_ECRWRE; | 931 | reg_ctrl2 |= FLEXCAN_CTRL2_ECRWRE; |
| 923 | flexcan_write(reg_crl2, ®s->crl2); | 932 | flexcan_write(reg_ctrl2, ®s->ctrl2); |
| 924 | 933 | ||
| 925 | reg_mecr = flexcan_read(®s->mecr); | 934 | reg_mecr = flexcan_read(®s->mecr); |
| 926 | reg_mecr &= ~FLEXCAN_MECR_ECRWRDIS; | 935 | reg_mecr &= ~FLEXCAN_MECR_ECRWRDIS; |
| @@ -40,6 +40,7 @@ · 39 unmodified lines | |||
| 40 | #define MSYNC_PEER 0x00 /* ICAN only */ | 40 | #define MSYNC_PEER 0x00 /* ICAN only */ |
| 41 | #define MSYNC_LOCL 0x01 /* host only */ | 41 | #define MSYNC_LOCL 0x01 /* host only */ |
| 42 | #define TARGET_RUNNING 0x02 | 42 | #define TARGET_RUNNING 0x02 |
| 43 | #define FIRMWARE_STAMP 0x60 /* big endian firmware stamp */ | ||
| 43 | 44 | ||
| 44 | #define MSYNC_RB0 0x01 | 45 | #define MSYNC_RB0 0x01 |
| 45 | #define MSYNC_RB1 0x02 | 46 | #define MSYNC_RB1 0x02 |
| @@ -83,6 +84,7 @@ · 37 unmodified lines | |||
| 83 | #define MSG_COFFREQ 0x42 | 84 | #define MSG_COFFREQ 0x42 |
| 84 | #define MSG_CONREQ 0x43 | 85 | #define MSG_CONREQ 0x43 |
| 85 | #define MSG_CCONFREQ 0x47 | 86 | #define MSG_CCONFREQ 0x47 |
| 87 | #define MSG_LMTS 0xb4 | ||
| 86 | 88 | ||
| 87 | /* | 89 | /* |
| 88 | * Janz ICAN3 CAN Inquiry Message Types | 90 | * Janz ICAN3 CAN Inquiry Message Types |
| @@ -165,6 +167,12 @@ · 76 unmodified lines | |||
| 165 | /* SJA1000 Clock Input */ | 167 | /* SJA1000 Clock Input */ |
| 166 | #define ICAN3_CAN_CLOCK 8000000 | 168 | #define ICAN3_CAN_CLOCK 8000000 |
| 167 | 169 | ||
| 170 | /* Janz ICAN3 firmware types */ | ||
| 171 | enum ican3_fwtype { | ||
| 172 | ICAN3_FWTYPE_ICANOS, | ||
| 173 | ICAN3_FWTYPE_CAL_CANOPEN, | ||
| 174 | }; | ||
| 175 | |||
| 168 | /* Driver Name */ | 176 | /* Driver Name */ |
| 169 | #define DRV_NAME "janz-ican3" | 177 | #define DRV_NAME "janz-ican3" |
| 170 | 178 | ||
| @@ -215,6 +223,10 @@ struct ican3_dev { · 44 unmodified lines | |||
| 215 | struct completion buserror_comp; | 223 | struct completion buserror_comp; |
| 216 | struct can_berr_counter bec; | 224 | struct can_berr_counter bec; |
| 217 | 225 | ||
| 226 | /* firmware type */ | ||
| 227 | enum ican3_fwtype fwtype; | ||
| 228 | char fwinfo[32]; | ||
| 229 | |||
| 218 | /* old and new style host interface */ | 230 | /* old and new style host interface */ |
| 219 | unsigned int iftype; | 231 | unsigned int iftype; |
| 220 | 232 | ||
| @@ -750,13 +762,61 @@ static int ican3_set_id_filter(struct ican3_dev *mod, bool accept) · 529 unmodified lines | |||
| 750 | */ | 762 | */ |
| 751 | static int ican3_set_bus_state(struct ican3_dev *mod, bool on) | 763 | static int ican3_set_bus_state(struct ican3_dev *mod, bool on) |
| 752 | { | 764 | { |
| 765 | struct can_bittiming *bt = &mod->can.bittiming; | ||
| 753 | struct ican3_msg msg; | 766 | struct ican3_msg msg; |
| 767 | u8 btr0, btr1; | ||
| 768 | int res; | ||
| 754 | 769 | ||
| 755 | memset(&msg, 0, sizeof(msg)); | 770 | /* This algorithm was stolen from drivers/net/can/sja1000/sja1000.c */ |
| 756 | msg.spec = on ? MSG_CONREQ : MSG_COFFREQ; | 771 | /* The bittiming register command for the ICAN3 just sets the bit timing */ |
| 757 | msg.len = cpu_to_le16(0); | 772 | /* registers on the SJA1000 chip directly */ |
| 773 | btr0 = ((bt->brp - 1) & 0x3f) | (((bt->sjw - 1) & 0x3) << 6); | ||
| 774 | btr1 = ((bt->prop_seg + bt->phase_seg1 - 1) & 0xf) | | ||
| 775 | (((bt->phase_seg2 - 1) & 0x7) << 4); | ||
| 776 | if (mod->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) | ||
| 777 | btr1 |= 0x80; | ||
| 758 | 778 | ||
| 759 | return ican3_send_msg(mod, &msg); | 779 | if (mod->fwtype == ICAN3_FWTYPE_ICANOS) { |
| 780 | if (on) { | ||
| 781 | /* set bittiming */ | ||
| 782 | memset(&msg, 0, sizeof(msg)); | ||
| 783 | msg.spec = MSG_CBTRREQ; | ||
| 784 | msg.len = cpu_to_le16(4); | ||
| 785 | msg.data[0] = 0x00; | ||
| 786 | msg.data[1] = 0x00; | ||
| 787 | msg.data[2] = btr0; | ||
| 788 | msg.data[3] = btr1; | ||
| 789 | |||
| 790 | res = ican3_send_msg(mod, &msg); | ||
| 791 | if (res) | ||
| 792 | return res; | ||
| 793 | } | ||
| 794 | |||
| 795 | /* can-on/off request */ | ||
| 796 | memset(&msg, 0, sizeof(msg)); | ||
| 797 | msg.spec = on ? MSG_CONREQ : MSG_COFFREQ; | ||
| 798 | msg.len = cpu_to_le16(0); | ||
| 799 | |||
| 800 | return ican3_send_msg(mod, &msg); | ||
| 801 | |||
| 802 | } else if (mod->fwtype == ICAN3_FWTYPE_CAL_CANOPEN) { | ||
| 803 | memset(&msg, 0, sizeof(msg)); | ||
| 804 | msg.spec = MSG_LMTS; | ||
| 805 | if (on) { | ||
| 806 | msg.len = cpu_to_le16(4); | ||
| 807 | msg.data[0] = 0; | ||
| 808 | msg.data[1] = 0; | ||
| 809 | msg.data[2] = btr0; | ||
| 810 | msg.data[3] = btr1; | ||
| 811 | } else { | ||
| 812 | msg.len = cpu_to_le16(2); | ||
| 813 | msg.data[0] = 1; | ||
| 814 | msg.data[1] = 0; | ||
| 815 | } | ||
| 816 | |||
| 817 | return ican3_send_msg(mod, &msg); | ||
| 818 | } | ||
| 819 | return -ENOTSUPP; | ||
| 760 | } | 820 | } |
| 761 | 821 | ||
| 762 | static int ican3_set_termination(struct ican3_dev *mod, bool on) | 822 | static int ican3_set_termination(struct ican3_dev *mod, bool on) |
| @@ -1402,7 +1462,7 @@ static int ican3_reset_module(struct ican3_dev *mod) · 639 unmodified lines | |||
| 1402 | return 0; | 1462 | return 0; |
| 1403 | 1463 | ||
| 1404 | msleep(10); | 1464 | msleep(10); |
| 1405 | } while (time_before(jiffies, start + HZ / 4)); | 1465 | } while (time_before(jiffies, start + HZ / 2)); |
| 1406 | 1466 | ||
| 1407 | netdev_err(mod->ndev, "failed to reset CAN module\n"); | 1467 | netdev_err(mod->ndev, "failed to reset CAN module\n"); |
| 1408 | return -ETIMEDOUT; | 1468 | return -ETIMEDOUT; |
| @@ -1427,6 +1487,17 @@ static int ican3_startup_module(struct ican3_dev *mod) · 18 unmodified lines | |||
| 1427 | return ret; | 1487 | return ret; |
| 1428 | } | 1488 | } |
| 1429 | 1489 | ||
| 1490 | /* detect firmware */ | ||
| 1491 | memcpy_fromio(mod->fwinfo, mod->dpm + FIRMWARE_STAMP, sizeof(mod->fwinfo) - 1); | ||
| 1492 | if (strncmp(mod->fwinfo, "JANZ-ICAN3", 10)) { | ||
| 1493 | netdev_err(mod->ndev, "ICAN3 not detected (found %s)\n", mod->fwinfo); | ||
| 1494 | return -ENODEV; | ||
| 1495 | } | ||
| 1496 | if (strstr(mod->fwinfo, "CAL/CANopen")) | ||
| 1497 | mod->fwtype = ICAN3_FWTYPE_CAL_CANOPEN; | ||
| 1498 | else | ||
| 1499 | mod->fwtype = ICAN3_FWTYPE_ICANOS; | ||
| 1500 | |||
| 1430 | /* re-enable interrupts so we can send messages */ | 1501 | /* re-enable interrupts so we can send messages */ |
| 1431 | iowrite8(1 << mod->num, &mod->ctrl->int_enable); | 1502 | iowrite8(1 << mod->num, &mod->ctrl->int_enable); |
| 1432 | 1503 | ||
| @@ -1615,36 +1686,6 @@ static const struct can_bittiming_const ican3_bittiming_const = { · 182 unmodified lines | |||
| 1615 | .brp_inc = 1, | 1686 | .brp_inc = 1, |
| 1616 | }; | 1687 | }; |
| 1617 | 1688 | ||
| 1618 | /* | ||
| 1619 | * This routine was stolen from drivers/net/can/sja1000/sja1000.c | ||
| 1620 | * | ||
| 1621 | * The bittiming register command for the ICAN3 just sets the bit timing | ||
| 1622 | * registers on the SJA1000 chip directly | ||
| 1623 | */ | ||
| 1624 | static int ican3_set_bittiming(struct net_device *ndev) | ||
| 1625 | { | ||
| 1626 | struct ican3_dev *mod = netdev_priv(ndev); | ||
| 1627 | struct can_bittiming *bt = &mod->can.bittiming; | ||
| 1628 | struct ican3_msg msg; | ||
| 1629 | u8 btr0, btr1; | ||
| 1630 | |||
| 1631 | btr0 = ((bt->brp - 1) & 0x3f) | (((bt->sjw - 1) & 0x3) << 6); | ||
| 1632 | btr1 = ((bt->prop_seg + bt->phase_seg1 - 1) & 0xf) | | ||
| 1633 | (((bt->phase_seg2 - 1) & 0x7) << 4); | ||
| 1634 | if (mod->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) | ||
| 1635 | btr1 |= 0x80; | ||
| 1636 | |||
| 1637 | memset(&msg, 0, sizeof(msg)); | ||
| 1638 | msg.spec = MSG_CBTRREQ; | ||
| 1639 | msg.len = cpu_to_le16(4); | ||
| 1640 | msg.data[0] = 0x00; | ||
| 1641 | msg.data[1] = 0x00; | ||
| 1642 | msg.data[2] = btr0; | ||
| 1643 | msg.data[3] = btr1; | ||
| 1644 | |||
| 1645 | return ican3_send_msg(mod, &msg); | ||
| 1646 | } | ||
| 1647 | |||
| 1648 | static int ican3_set_mode(struct net_device *ndev, enum can_mode mode) | 1689 | static int ican3_set_mode(struct net_device *ndev, enum can_mode mode) |
| 1649 | { | 1690 | { |
| 1650 | struct ican3_dev *mod = netdev_priv(ndev); | 1691 | struct ican3_dev *mod = netdev_priv(ndev); |
| @@ -1730,11 +1771,22 @@ static ssize_t ican3_sysfs_set_term(struct device *dev, · 79 unmodified lines | |||
| 1730 | return count; | 1771 | return count; |
| 1731 | } | 1772 | } |
| 1732 | 1773 | ||
| 1774 | static ssize_t ican3_sysfs_show_fwinfo(struct device *dev, | ||
| 1775 | struct device_attribute *attr, | ||
| 1776 | char *buf) | ||
| 1777 | { | ||
| 1778 | struct ican3_dev *mod = netdev_priv(to_net_dev(dev)); | ||
| 1779 | |||
| 1780 | return scnprintf(buf, PAGE_SIZE, "%s\n", mod->fwinfo); | ||
| 1781 | } | ||
| 1782 | |||
| 1733 | static DEVICE_ATTR(termination, S_IWUSR | S_IRUGO, ican3_sysfs_show_term, | 1783 | static DEVICE_ATTR(termination, S_IWUSR | S_IRUGO, ican3_sysfs_show_term, |
| 1734 | ican3_sysfs_set_term); | 1784 | ican3_sysfs_set_term); |
| 1785 | static DEVICE_ATTR(fwinfo, S_IRUSR | S_IRUGO, ican3_sysfs_show_fwinfo, NULL); | ||
| 1735 | 1786 | ||
| 1736 | static struct attribute *ican3_sysfs_attrs[] = { | 1787 | static struct attribute *ican3_sysfs_attrs[] = { |
| 1737 | &dev_attr_termination.attr, | 1788 | &dev_attr_termination.attr, |
| 1789 | &dev_attr_fwinfo.attr, | ||
| 1738 | NULL, | 1790 | NULL, |
| 1739 | }; | 1791 | }; |
| 1740 | 1792 | ||
| @@ -1794,7 +1846,6 @@ static int ican3_probe(struct platform_device *pdev) · 53 unmodified lines | |||
| 1794 | 1846 | ||
| 1795 | mod->can.clock.freq = ICAN3_CAN_CLOCK; | 1847 | mod->can.clock.freq = ICAN3_CAN_CLOCK; |
| 1796 | mod->can.bittiming_const = &ican3_bittiming_const; | 1848 | mod->can.bittiming_const = &ican3_bittiming_const; |
| 1797 | mod->can.do_set_bittiming = ican3_set_bittiming; | ||
| 1798 | mod->can.do_set_mode = ican3_set_mode; | 1849 | mod->can.do_set_mode = ican3_set_mode; |
| 1799 | mod->can.do_get_berr_counter = ican3_get_berr_counter; | 1850 | mod->can.do_get_berr_counter = ican3_get_berr_counter; |
| 1800 | mod->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES | 1851 | mod->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES |
| @@ -1866,7 +1917,7 @@ static int ican3_probe(struct platform_device *pdev) · 65 unmodified lines | |||
| 1866 | goto out_free_irq; | 1917 | goto out_free_irq; |
| 1867 | } | 1918 | } |
| 1868 | 1919 | ||
| 1869 | dev_info(dev, "module %d: registered CAN device\n", pdata->modno); | 1920 | netdev_info(mod->ndev, "module %d: registered CAN device\n", pdata->modno); |
| 1870 | return 0; | 1921 | return 0; |
| 1871 | 1922 | ||
| 1872 | out_free_irq: | 1923 | out_free_irq: |
| @@ -95,11 +95,17 @@ typedef __u32 can_err_mask_t; · 94 unmodified lines | |||
| 95 | * @can_dlc: frame payload length in byte (0 .. 8) aka data length code | 95 | * @can_dlc: frame payload length in byte (0 .. 8) aka data length code |
| 96 | * N.B. the DLC field from ISO 11898-1 Chapter 8.4.2.3 has a 1:1 | 96 | * N.B. the DLC field from ISO 11898-1 Chapter 8.4.2.3 has a 1:1 |
| 97 | * mapping of the 'data length code' to the real payload length | 97 | * mapping of the 'data length code' to the real payload length |
| 98 | * @__pad: padding | ||
| 99 | * @__res0: reserved / padding | ||
| 100 | * @__res1: reserved / padding | ||
| 98 | * @data: CAN frame payload (up to 8 byte) | 101 | * @data: CAN frame payload (up to 8 byte) |
| 99 | */ | 102 | */ |
| 100 | struct can_frame { | 103 | struct can_frame { |
| 101 | canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */ | 104 | canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */ |
| 102 | __u8 can_dlc; /* frame payload length in byte (0 .. CAN_MAX_DLEN) */ | 105 | __u8 can_dlc; /* frame payload length in byte (0 .. CAN_MAX_DLEN) */ |
| 106 | __u8 __pad; /* padding */ | ||
| 107 | __u8 __res0; /* reserved / padding */ | ||
| 108 | __u8 __res1; /* reserved / padding */ | ||
| 103 | __u8 data[CAN_MAX_DLEN] __attribute__((aligned(8))); | 109 | __u8 data[CAN_MAX_DLEN] __attribute__((aligned(8))); |
| 104 | }; | 110 | }; |
| 105 | 111 | ||