.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* Xilinx CAN device driver |
---|
2 | 3 | * |
---|
3 | 4 | * Copyright (C) 2012 - 2014 Xilinx, Inc. |
---|
.. | .. |
---|
6 | 7 | * |
---|
7 | 8 | * Description: |
---|
8 | 9 | * This driver is developed for Axi CAN IP and for Zynq CANPS Controller. |
---|
9 | | - * This program is free software: you can redistribute it and/or modify |
---|
10 | | - * it under the terms of the GNU General Public License as published by |
---|
11 | | - * the Free Software Foundation, either version 2 of the License, or |
---|
12 | | - * (at your option) any later version. |
---|
13 | | - * |
---|
14 | | - * This program is distributed in the hope that it will be useful, |
---|
15 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
16 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
17 | | - * GNU General Public License for more details. |
---|
18 | 10 | */ |
---|
19 | 11 | |
---|
20 | 12 | #include <linux/clk.h> |
---|
.. | .. |
---|
58 | 50 | XCAN_AFR_OFFSET = 0x60, /* Acceptance Filter */ |
---|
59 | 51 | |
---|
60 | 52 | /* only on CAN FD cores */ |
---|
| 53 | + XCAN_F_BRPR_OFFSET = 0x088, /* Data Phase Baud Rate |
---|
| 54 | + * Prescalar |
---|
| 55 | + */ |
---|
| 56 | + XCAN_F_BTR_OFFSET = 0x08C, /* Data Phase Bit Timing */ |
---|
61 | 57 | XCAN_TRR_OFFSET = 0x0090, /* TX Buffer Ready Request */ |
---|
62 | 58 | XCAN_AFR_EXT_OFFSET = 0x00E0, /* Acceptance Filter */ |
---|
63 | 59 | XCAN_FSR_OFFSET = 0x00E8, /* RX FIFO Status */ |
---|
64 | 60 | XCAN_TXMSG_BASE_OFFSET = 0x0100, /* TX Message Space */ |
---|
65 | 61 | XCAN_RXMSG_BASE_OFFSET = 0x1100, /* RX Message Space */ |
---|
| 62 | + XCAN_RXMSG_2_BASE_OFFSET = 0x2100, /* RX Message Space */ |
---|
| 63 | + XCAN_AFR_2_MASK_OFFSET = 0x0A00, /* Acceptance Filter MASK */ |
---|
| 64 | + XCAN_AFR_2_ID_OFFSET = 0x0A04, /* Acceptance Filter ID */ |
---|
66 | 65 | }; |
---|
67 | 66 | |
---|
68 | 67 | #define XCAN_FRAME_ID_OFFSET(frame_base) ((frame_base) + 0x00) |
---|
69 | 68 | #define XCAN_FRAME_DLC_OFFSET(frame_base) ((frame_base) + 0x04) |
---|
70 | 69 | #define XCAN_FRAME_DW1_OFFSET(frame_base) ((frame_base) + 0x08) |
---|
71 | 70 | #define XCAN_FRAME_DW2_OFFSET(frame_base) ((frame_base) + 0x0C) |
---|
| 71 | +#define XCANFD_FRAME_DW_OFFSET(frame_base) ((frame_base) + 0x08) |
---|
72 | 72 | |
---|
73 | 73 | #define XCAN_CANFD_FRAME_SIZE 0x48 |
---|
74 | 74 | #define XCAN_TXMSG_FRAME_OFFSET(n) (XCAN_TXMSG_BASE_OFFSET + \ |
---|
75 | 75 | XCAN_CANFD_FRAME_SIZE * (n)) |
---|
76 | 76 | #define XCAN_RXMSG_FRAME_OFFSET(n) (XCAN_RXMSG_BASE_OFFSET + \ |
---|
| 77 | + XCAN_CANFD_FRAME_SIZE * (n)) |
---|
| 78 | +#define XCAN_RXMSG_2_FRAME_OFFSET(n) (XCAN_RXMSG_2_BASE_OFFSET + \ |
---|
77 | 79 | XCAN_CANFD_FRAME_SIZE * (n)) |
---|
78 | 80 | |
---|
79 | 81 | /* the single TX mailbox used by this driver on CAN FD HW */ |
---|
.. | .. |
---|
123 | 125 | #define XCAN_IDR_RTR_MASK 0x00000001 /* Remote TX request */ |
---|
124 | 126 | #define XCAN_DLCR_DLC_MASK 0xF0000000 /* Data length code */ |
---|
125 | 127 | #define XCAN_FSR_FL_MASK 0x00003F00 /* RX Fill Level */ |
---|
| 128 | +#define XCAN_2_FSR_FL_MASK 0x00007F00 /* RX Fill Level */ |
---|
126 | 129 | #define XCAN_FSR_IRI_MASK 0x00000080 /* RX Increment Read Index */ |
---|
127 | 130 | #define XCAN_FSR_RI_MASK 0x0000001F /* RX Read Index */ |
---|
| 131 | +#define XCAN_2_FSR_RI_MASK 0x0000003F /* RX Read Index */ |
---|
| 132 | +#define XCAN_DLCR_EDL_MASK 0x08000000 /* EDL Mask in DLC */ |
---|
| 133 | +#define XCAN_DLCR_BRS_MASK 0x04000000 /* BRS Mask in DLC */ |
---|
128 | 134 | |
---|
129 | 135 | /* CAN register bit shift - XCAN_<REG>_<BIT>_SHIFT */ |
---|
130 | 136 | #define XCAN_BTR_SJW_SHIFT 7 /* Synchronous jump width */ |
---|
.. | .. |
---|
138 | 144 | |
---|
139 | 145 | /* CAN frame length constants */ |
---|
140 | 146 | #define XCAN_FRAME_MAX_DATA_LEN 8 |
---|
| 147 | +#define XCANFD_DW_BYTES 4 |
---|
141 | 148 | #define XCAN_TIMEOUT (1 * HZ) |
---|
142 | 149 | |
---|
143 | 150 | /* TX-FIFO-empty interrupt available */ |
---|
.. | .. |
---|
152 | 159 | * instead of the regular FIFO at 0x50 |
---|
153 | 160 | */ |
---|
154 | 161 | #define XCAN_FLAG_RX_FIFO_MULTI 0x0010 |
---|
| 162 | +#define XCAN_FLAG_CANFD_2 0x0020 |
---|
| 163 | + |
---|
| 164 | +enum xcan_ip_type { |
---|
| 165 | + XAXI_CAN = 0, |
---|
| 166 | + XZYNQ_CANPS, |
---|
| 167 | + XAXI_CANFD, |
---|
| 168 | + XAXI_CANFD_2_0, |
---|
| 169 | +}; |
---|
155 | 170 | |
---|
156 | 171 | struct xcan_devtype_data { |
---|
| 172 | + enum xcan_ip_type cantype; |
---|
157 | 173 | unsigned int flags; |
---|
158 | 174 | const struct can_bittiming_const *bittiming_const; |
---|
159 | 175 | const char *bus_clk_name; |
---|
.. | .. |
---|
180 | 196 | */ |
---|
181 | 197 | struct xcan_priv { |
---|
182 | 198 | struct can_priv can; |
---|
183 | | - spinlock_t tx_lock; |
---|
| 199 | + spinlock_t tx_lock; /* Lock for synchronizing TX interrupt handling */ |
---|
184 | 200 | unsigned int tx_head; |
---|
185 | 201 | unsigned int tx_tail; |
---|
186 | 202 | unsigned int tx_max; |
---|
187 | 203 | struct napi_struct napi; |
---|
188 | 204 | u32 (*read_reg)(const struct xcan_priv *priv, enum xcan_reg reg); |
---|
189 | 205 | void (*write_reg)(const struct xcan_priv *priv, enum xcan_reg reg, |
---|
190 | | - u32 val); |
---|
| 206 | + u32 val); |
---|
191 | 207 | struct device *dev; |
---|
192 | 208 | void __iomem *reg_base; |
---|
193 | 209 | unsigned long irq_flags; |
---|
.. | .. |
---|
209 | 225 | .brp_inc = 1, |
---|
210 | 226 | }; |
---|
211 | 227 | |
---|
| 228 | +/* AXI CANFD Arbitration Bittiming constants as per AXI CANFD 1.0 spec */ |
---|
212 | 229 | static const struct can_bittiming_const xcan_bittiming_const_canfd = { |
---|
213 | 230 | .name = DRIVER_NAME, |
---|
214 | 231 | .tseg1_min = 1, |
---|
215 | 232 | .tseg1_max = 64, |
---|
| 233 | + .tseg2_min = 1, |
---|
| 234 | + .tseg2_max = 16, |
---|
| 235 | + .sjw_max = 16, |
---|
| 236 | + .brp_min = 1, |
---|
| 237 | + .brp_max = 256, |
---|
| 238 | + .brp_inc = 1, |
---|
| 239 | +}; |
---|
| 240 | + |
---|
| 241 | +/* AXI CANFD Data Bittiming constants as per AXI CANFD 1.0 specs */ |
---|
| 242 | +static const struct can_bittiming_const xcan_data_bittiming_const_canfd = { |
---|
| 243 | + .name = DRIVER_NAME, |
---|
| 244 | + .tseg1_min = 1, |
---|
| 245 | + .tseg1_max = 16, |
---|
| 246 | + .tseg2_min = 1, |
---|
| 247 | + .tseg2_max = 8, |
---|
| 248 | + .sjw_max = 8, |
---|
| 249 | + .brp_min = 1, |
---|
| 250 | + .brp_max = 256, |
---|
| 251 | + .brp_inc = 1, |
---|
| 252 | +}; |
---|
| 253 | + |
---|
| 254 | +/* AXI CANFD 2.0 Arbitration Bittiming constants as per AXI CANFD 2.0 spec */ |
---|
| 255 | +static const struct can_bittiming_const xcan_bittiming_const_canfd2 = { |
---|
| 256 | + .name = DRIVER_NAME, |
---|
| 257 | + .tseg1_min = 1, |
---|
| 258 | + .tseg1_max = 256, |
---|
| 259 | + .tseg2_min = 1, |
---|
| 260 | + .tseg2_max = 128, |
---|
| 261 | + .sjw_max = 128, |
---|
| 262 | + .brp_min = 1, |
---|
| 263 | + .brp_max = 256, |
---|
| 264 | + .brp_inc = 1, |
---|
| 265 | +}; |
---|
| 266 | + |
---|
| 267 | +/* AXI CANFD 2.0 Data Bittiming constants as per AXI CANFD 2.0 spec */ |
---|
| 268 | +static const struct can_bittiming_const xcan_data_bittiming_const_canfd2 = { |
---|
| 269 | + .name = DRIVER_NAME, |
---|
| 270 | + .tseg1_min = 1, |
---|
| 271 | + .tseg1_max = 32, |
---|
216 | 272 | .tseg2_min = 1, |
---|
217 | 273 | .tseg2_max = 16, |
---|
218 | 274 | .sjw_max = 16, |
---|
.. | .. |
---|
230 | 286 | * Write data to the paricular CAN register |
---|
231 | 287 | */ |
---|
232 | 288 | static void xcan_write_reg_le(const struct xcan_priv *priv, enum xcan_reg reg, |
---|
233 | | - u32 val) |
---|
| 289 | + u32 val) |
---|
234 | 290 | { |
---|
235 | 291 | iowrite32(val, priv->reg_base + reg); |
---|
236 | 292 | } |
---|
.. | .. |
---|
257 | 313 | * Write data to the paricular CAN register |
---|
258 | 314 | */ |
---|
259 | 315 | static void xcan_write_reg_be(const struct xcan_priv *priv, enum xcan_reg reg, |
---|
260 | | - u32 val) |
---|
| 316 | + u32 val) |
---|
261 | 317 | { |
---|
262 | 318 | iowrite32be(val, priv->reg_base + reg); |
---|
263 | 319 | } |
---|
.. | .. |
---|
335 | 391 | { |
---|
336 | 392 | struct xcan_priv *priv = netdev_priv(ndev); |
---|
337 | 393 | struct can_bittiming *bt = &priv->can.bittiming; |
---|
| 394 | + struct can_bittiming *dbt = &priv->can.data_bittiming; |
---|
338 | 395 | u32 btr0, btr1; |
---|
339 | 396 | u32 is_config_mode; |
---|
340 | 397 | |
---|
.. | .. |
---|
345 | 402 | XCAN_SR_CONFIG_MASK; |
---|
346 | 403 | if (!is_config_mode) { |
---|
347 | 404 | netdev_alert(ndev, |
---|
348 | | - "BUG! Cannot set bittiming - CAN is not in config mode\n"); |
---|
| 405 | + "BUG! Cannot set bittiming - CAN is not in config mode\n"); |
---|
349 | 406 | return -EPERM; |
---|
350 | 407 | } |
---|
351 | 408 | |
---|
.. | .. |
---|
364 | 421 | priv->write_reg(priv, XCAN_BRPR_OFFSET, btr0); |
---|
365 | 422 | priv->write_reg(priv, XCAN_BTR_OFFSET, btr1); |
---|
366 | 423 | |
---|
| 424 | + if (priv->devtype.cantype == XAXI_CANFD || |
---|
| 425 | + priv->devtype.cantype == XAXI_CANFD_2_0) { |
---|
| 426 | + /* Setting Baud Rate prescalar value in F_BRPR Register */ |
---|
| 427 | + btr0 = dbt->brp - 1; |
---|
| 428 | + |
---|
| 429 | + /* Setting Time Segment 1 in BTR Register */ |
---|
| 430 | + btr1 = dbt->prop_seg + dbt->phase_seg1 - 1; |
---|
| 431 | + |
---|
| 432 | + /* Setting Time Segment 2 in BTR Register */ |
---|
| 433 | + btr1 |= (dbt->phase_seg2 - 1) << priv->devtype.btr_ts2_shift; |
---|
| 434 | + |
---|
| 435 | + /* Setting Synchronous jump width in BTR Register */ |
---|
| 436 | + btr1 |= (dbt->sjw - 1) << priv->devtype.btr_sjw_shift; |
---|
| 437 | + |
---|
| 438 | + priv->write_reg(priv, XCAN_F_BRPR_OFFSET, btr0); |
---|
| 439 | + priv->write_reg(priv, XCAN_F_BTR_OFFSET, btr1); |
---|
| 440 | + } |
---|
| 441 | + |
---|
367 | 442 | netdev_dbg(ndev, "BRPR=0x%08x, BTR=0x%08x\n", |
---|
368 | | - priv->read_reg(priv, XCAN_BRPR_OFFSET), |
---|
369 | | - priv->read_reg(priv, XCAN_BTR_OFFSET)); |
---|
| 443 | + priv->read_reg(priv, XCAN_BRPR_OFFSET), |
---|
| 444 | + priv->read_reg(priv, XCAN_BTR_OFFSET)); |
---|
370 | 445 | |
---|
371 | 446 | return 0; |
---|
372 | 447 | } |
---|
.. | .. |
---|
384 | 459 | static int xcan_chip_start(struct net_device *ndev) |
---|
385 | 460 | { |
---|
386 | 461 | struct xcan_priv *priv = netdev_priv(ndev); |
---|
387 | | - u32 reg_msr, reg_sr_mask; |
---|
| 462 | + u32 reg_msr; |
---|
388 | 463 | int err; |
---|
389 | | - unsigned long timeout; |
---|
390 | 464 | u32 ier; |
---|
391 | 465 | |
---|
392 | 466 | /* Check if it is in reset mode */ |
---|
.. | .. |
---|
398 | 472 | if (err < 0) |
---|
399 | 473 | return err; |
---|
400 | 474 | |
---|
401 | | - /* Enable interrupts */ |
---|
| 475 | + /* Enable interrupts |
---|
| 476 | + * |
---|
| 477 | + * We enable the ERROR interrupt even with |
---|
| 478 | + * CAN_CTRLMODE_BERR_REPORTING disabled as there is no |
---|
| 479 | + * dedicated interrupt for a state change to |
---|
| 480 | + * ERROR_WARNING/ERROR_PASSIVE. |
---|
| 481 | + */ |
---|
402 | 482 | ier = XCAN_IXR_TXOK_MASK | XCAN_IXR_BSOFF_MASK | |
---|
403 | 483 | XCAN_IXR_WKUP_MASK | XCAN_IXR_SLP_MASK | |
---|
404 | 484 | XCAN_IXR_ERROR_MASK | XCAN_IXR_RXOFLW_MASK | |
---|
.. | .. |
---|
410 | 490 | priv->write_reg(priv, XCAN_IER_OFFSET, ier); |
---|
411 | 491 | |
---|
412 | 492 | /* Check whether it is loopback mode or normal mode */ |
---|
413 | | - if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) { |
---|
| 493 | + if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) |
---|
414 | 494 | reg_msr = XCAN_MSR_LBACK_MASK; |
---|
415 | | - reg_sr_mask = XCAN_SR_LBACK_MASK; |
---|
416 | | - } else { |
---|
| 495 | + else |
---|
417 | 496 | reg_msr = 0x0; |
---|
418 | | - reg_sr_mask = XCAN_SR_NORMAL_MASK; |
---|
419 | | - } |
---|
420 | 497 | |
---|
421 | 498 | /* enable the first extended filter, if any, as cores with extended |
---|
422 | 499 | * filtering default to non-receipt if all filters are disabled |
---|
.. | .. |
---|
427 | 504 | priv->write_reg(priv, XCAN_MSR_OFFSET, reg_msr); |
---|
428 | 505 | priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_CEN_MASK); |
---|
429 | 506 | |
---|
430 | | - timeout = jiffies + XCAN_TIMEOUT; |
---|
431 | | - while (!(priv->read_reg(priv, XCAN_SR_OFFSET) & reg_sr_mask)) { |
---|
432 | | - if (time_after(jiffies, timeout)) { |
---|
433 | | - netdev_warn(ndev, |
---|
434 | | - "timed out for correct mode\n"); |
---|
435 | | - return -ETIMEDOUT; |
---|
436 | | - } |
---|
437 | | - } |
---|
438 | 507 | netdev_dbg(ndev, "status:#x%08x\n", |
---|
439 | | - priv->read_reg(priv, XCAN_SR_OFFSET)); |
---|
| 508 | + priv->read_reg(priv, XCAN_SR_OFFSET)); |
---|
440 | 509 | |
---|
441 | 510 | priv->can.state = CAN_STATE_ERROR_ACTIVE; |
---|
442 | 511 | return 0; |
---|
.. | .. |
---|
475 | 544 | |
---|
476 | 545 | /** |
---|
477 | 546 | * xcan_write_frame - Write a frame to HW |
---|
| 547 | + * @ndev: Pointer to net_device structure |
---|
478 | 548 | * @skb: sk_buff pointer that contains data to be Txed |
---|
479 | 549 | * @frame_offset: Register offset to write the frame to |
---|
480 | 550 | */ |
---|
481 | | -static void xcan_write_frame(struct xcan_priv *priv, struct sk_buff *skb, |
---|
| 551 | +static void xcan_write_frame(struct net_device *ndev, struct sk_buff *skb, |
---|
482 | 552 | int frame_offset) |
---|
483 | 553 | { |
---|
484 | 554 | u32 id, dlc, data[2] = {0, 0}; |
---|
485 | | - struct can_frame *cf = (struct can_frame *)skb->data; |
---|
| 555 | + struct canfd_frame *cf = (struct canfd_frame *)skb->data; |
---|
| 556 | + u32 ramoff, dwindex = 0, i; |
---|
| 557 | + struct xcan_priv *priv = netdev_priv(ndev); |
---|
486 | 558 | |
---|
487 | 559 | /* Watch carefully on the bit sequence */ |
---|
488 | 560 | if (cf->can_id & CAN_EFF_FLAG) { |
---|
.. | .. |
---|
490 | 562 | id = ((cf->can_id & CAN_EFF_MASK) << XCAN_IDR_ID2_SHIFT) & |
---|
491 | 563 | XCAN_IDR_ID2_MASK; |
---|
492 | 564 | id |= (((cf->can_id & CAN_EFF_MASK) >> |
---|
493 | | - (CAN_EFF_ID_BITS-CAN_SFF_ID_BITS)) << |
---|
| 565 | + (CAN_EFF_ID_BITS - CAN_SFF_ID_BITS)) << |
---|
494 | 566 | XCAN_IDR_ID1_SHIFT) & XCAN_IDR_ID1_MASK; |
---|
495 | 567 | |
---|
496 | 568 | /* The substibute remote TX request bit should be "1" |
---|
.. | .. |
---|
511 | 583 | id |= XCAN_IDR_SRR_MASK; |
---|
512 | 584 | } |
---|
513 | 585 | |
---|
514 | | - dlc = cf->can_dlc << XCAN_DLCR_DLC_SHIFT; |
---|
| 586 | + dlc = can_len2dlc(cf->len) << XCAN_DLCR_DLC_SHIFT; |
---|
| 587 | + if (can_is_canfd_skb(skb)) { |
---|
| 588 | + if (cf->flags & CANFD_BRS) |
---|
| 589 | + dlc |= XCAN_DLCR_BRS_MASK; |
---|
| 590 | + dlc |= XCAN_DLCR_EDL_MASK; |
---|
| 591 | + } |
---|
515 | 592 | |
---|
516 | | - if (cf->can_dlc > 0) |
---|
517 | | - data[0] = be32_to_cpup((__be32 *)(cf->data + 0)); |
---|
518 | | - if (cf->can_dlc > 4) |
---|
519 | | - data[1] = be32_to_cpup((__be32 *)(cf->data + 4)); |
---|
| 593 | + if (!(priv->devtype.flags & XCAN_FLAG_TX_MAILBOXES) && |
---|
| 594 | + (priv->devtype.flags & XCAN_FLAG_TXFEMP)) |
---|
| 595 | + can_put_echo_skb(skb, ndev, priv->tx_head % priv->tx_max); |
---|
| 596 | + else |
---|
| 597 | + can_put_echo_skb(skb, ndev, 0); |
---|
| 598 | + |
---|
| 599 | + priv->tx_head++; |
---|
520 | 600 | |
---|
521 | 601 | priv->write_reg(priv, XCAN_FRAME_ID_OFFSET(frame_offset), id); |
---|
522 | 602 | /* If the CAN frame is RTR frame this write triggers transmission |
---|
523 | 603 | * (not on CAN FD) |
---|
524 | 604 | */ |
---|
525 | 605 | priv->write_reg(priv, XCAN_FRAME_DLC_OFFSET(frame_offset), dlc); |
---|
526 | | - if (!(cf->can_id & CAN_RTR_FLAG)) { |
---|
527 | | - priv->write_reg(priv, XCAN_FRAME_DW1_OFFSET(frame_offset), |
---|
528 | | - data[0]); |
---|
529 | | - /* If the CAN frame is Standard/Extended frame this |
---|
530 | | - * write triggers transmission (not on CAN FD) |
---|
531 | | - */ |
---|
532 | | - priv->write_reg(priv, XCAN_FRAME_DW2_OFFSET(frame_offset), |
---|
533 | | - data[1]); |
---|
| 606 | + if (priv->devtype.cantype == XAXI_CANFD || |
---|
| 607 | + priv->devtype.cantype == XAXI_CANFD_2_0) { |
---|
| 608 | + for (i = 0; i < cf->len; i += 4) { |
---|
| 609 | + ramoff = XCANFD_FRAME_DW_OFFSET(frame_offset) + |
---|
| 610 | + (dwindex * XCANFD_DW_BYTES); |
---|
| 611 | + priv->write_reg(priv, ramoff, |
---|
| 612 | + be32_to_cpup((__be32 *)(cf->data + i))); |
---|
| 613 | + dwindex++; |
---|
| 614 | + } |
---|
| 615 | + } else { |
---|
| 616 | + if (cf->len > 0) |
---|
| 617 | + data[0] = be32_to_cpup((__be32 *)(cf->data + 0)); |
---|
| 618 | + if (cf->len > 4) |
---|
| 619 | + data[1] = be32_to_cpup((__be32 *)(cf->data + 4)); |
---|
| 620 | + |
---|
| 621 | + if (!(cf->can_id & CAN_RTR_FLAG)) { |
---|
| 622 | + priv->write_reg(priv, |
---|
| 623 | + XCAN_FRAME_DW1_OFFSET(frame_offset), |
---|
| 624 | + data[0]); |
---|
| 625 | + /* If the CAN frame is Standard/Extended frame this |
---|
| 626 | + * write triggers transmission (not on CAN FD) |
---|
| 627 | + */ |
---|
| 628 | + priv->write_reg(priv, |
---|
| 629 | + XCAN_FRAME_DW2_OFFSET(frame_offset), |
---|
| 630 | + data[1]); |
---|
| 631 | + } |
---|
534 | 632 | } |
---|
535 | 633 | } |
---|
536 | 634 | |
---|
537 | 635 | /** |
---|
538 | 636 | * xcan_start_xmit_fifo - Starts the transmission (FIFO mode) |
---|
| 637 | + * @skb: sk_buff pointer that contains data to be Txed |
---|
| 638 | + * @ndev: Pointer to net_device structure |
---|
539 | 639 | * |
---|
540 | 640 | * Return: 0 on success, -ENOSPC if FIFO is full. |
---|
541 | 641 | */ |
---|
.. | .. |
---|
549 | 649 | XCAN_SR_TXFLL_MASK)) |
---|
550 | 650 | return -ENOSPC; |
---|
551 | 651 | |
---|
552 | | - can_put_echo_skb(skb, ndev, priv->tx_head % priv->tx_max); |
---|
553 | | - |
---|
554 | 652 | spin_lock_irqsave(&priv->tx_lock, flags); |
---|
555 | 653 | |
---|
556 | | - priv->tx_head++; |
---|
557 | | - |
---|
558 | | - xcan_write_frame(priv, skb, XCAN_TXFIFO_OFFSET); |
---|
| 654 | + xcan_write_frame(ndev, skb, XCAN_TXFIFO_OFFSET); |
---|
559 | 655 | |
---|
560 | 656 | /* Clear TX-FIFO-empty interrupt for xcan_tx_interrupt() */ |
---|
561 | 657 | if (priv->tx_max > 1) |
---|
.. | .. |
---|
572 | 668 | |
---|
573 | 669 | /** |
---|
574 | 670 | * xcan_start_xmit_mailbox - Starts the transmission (mailbox mode) |
---|
| 671 | + * @skb: sk_buff pointer that contains data to be Txed |
---|
| 672 | + * @ndev: Pointer to net_device structure |
---|
575 | 673 | * |
---|
576 | 674 | * Return: 0 on success, -ENOSPC if there is no space |
---|
577 | 675 | */ |
---|
.. | .. |
---|
584 | 682 | BIT(XCAN_TX_MAILBOX_IDX))) |
---|
585 | 683 | return -ENOSPC; |
---|
586 | 684 | |
---|
587 | | - can_put_echo_skb(skb, ndev, 0); |
---|
588 | | - |
---|
589 | 685 | spin_lock_irqsave(&priv->tx_lock, flags); |
---|
590 | 686 | |
---|
591 | | - priv->tx_head++; |
---|
592 | | - |
---|
593 | | - xcan_write_frame(priv, skb, |
---|
| 687 | + xcan_write_frame(ndev, skb, |
---|
594 | 688 | XCAN_TXMSG_FRAME_OFFSET(XCAN_TX_MAILBOX_IDX)); |
---|
595 | 689 | |
---|
596 | 690 | /* Mark buffer as ready for transmit */ |
---|
.. | .. |
---|
697 | 791 | } |
---|
698 | 792 | |
---|
699 | 793 | stats->rx_bytes += cf->can_dlc; |
---|
| 794 | + stats->rx_packets++; |
---|
| 795 | + netif_receive_skb(skb); |
---|
| 796 | + |
---|
| 797 | + return 1; |
---|
| 798 | +} |
---|
| 799 | + |
---|
| 800 | +/** |
---|
| 801 | + * xcanfd_rx - Is called from CAN isr to complete the received |
---|
| 802 | + * frame processing |
---|
| 803 | + * @ndev: Pointer to net_device structure |
---|
| 804 | + * @frame_base: Register offset to the frame to be read |
---|
| 805 | + * |
---|
| 806 | + * This function is invoked from the CAN isr(poll) to process the Rx frames. It |
---|
| 807 | + * does minimal processing and invokes "netif_receive_skb" to complete further |
---|
| 808 | + * processing. |
---|
| 809 | + * Return: 1 on success and 0 on failure. |
---|
| 810 | + */ |
---|
| 811 | +static int xcanfd_rx(struct net_device *ndev, int frame_base) |
---|
| 812 | +{ |
---|
| 813 | + struct xcan_priv *priv = netdev_priv(ndev); |
---|
| 814 | + struct net_device_stats *stats = &ndev->stats; |
---|
| 815 | + struct canfd_frame *cf; |
---|
| 816 | + struct sk_buff *skb; |
---|
| 817 | + u32 id_xcan, dlc, data[2] = {0, 0}, dwindex = 0, i, dw_offset; |
---|
| 818 | + |
---|
| 819 | + id_xcan = priv->read_reg(priv, XCAN_FRAME_ID_OFFSET(frame_base)); |
---|
| 820 | + dlc = priv->read_reg(priv, XCAN_FRAME_DLC_OFFSET(frame_base)); |
---|
| 821 | + if (dlc & XCAN_DLCR_EDL_MASK) |
---|
| 822 | + skb = alloc_canfd_skb(ndev, &cf); |
---|
| 823 | + else |
---|
| 824 | + skb = alloc_can_skb(ndev, (struct can_frame **)&cf); |
---|
| 825 | + |
---|
| 826 | + if (unlikely(!skb)) { |
---|
| 827 | + stats->rx_dropped++; |
---|
| 828 | + return 0; |
---|
| 829 | + } |
---|
| 830 | + |
---|
| 831 | + /* Change Xilinx CANFD data length format to socketCAN data |
---|
| 832 | + * format |
---|
| 833 | + */ |
---|
| 834 | + if (dlc & XCAN_DLCR_EDL_MASK) |
---|
| 835 | + cf->len = can_dlc2len((dlc & XCAN_DLCR_DLC_MASK) >> |
---|
| 836 | + XCAN_DLCR_DLC_SHIFT); |
---|
| 837 | + else |
---|
| 838 | + cf->len = get_can_dlc((dlc & XCAN_DLCR_DLC_MASK) >> |
---|
| 839 | + XCAN_DLCR_DLC_SHIFT); |
---|
| 840 | + |
---|
| 841 | + /* Change Xilinx CAN ID format to socketCAN ID format */ |
---|
| 842 | + if (id_xcan & XCAN_IDR_IDE_MASK) { |
---|
| 843 | + /* The received frame is an Extended format frame */ |
---|
| 844 | + cf->can_id = (id_xcan & XCAN_IDR_ID1_MASK) >> 3; |
---|
| 845 | + cf->can_id |= (id_xcan & XCAN_IDR_ID2_MASK) >> |
---|
| 846 | + XCAN_IDR_ID2_SHIFT; |
---|
| 847 | + cf->can_id |= CAN_EFF_FLAG; |
---|
| 848 | + if (id_xcan & XCAN_IDR_RTR_MASK) |
---|
| 849 | + cf->can_id |= CAN_RTR_FLAG; |
---|
| 850 | + } else { |
---|
| 851 | + /* The received frame is a standard format frame */ |
---|
| 852 | + cf->can_id = (id_xcan & XCAN_IDR_ID1_MASK) >> |
---|
| 853 | + XCAN_IDR_ID1_SHIFT; |
---|
| 854 | + if (!(dlc & XCAN_DLCR_EDL_MASK) && (id_xcan & |
---|
| 855 | + XCAN_IDR_SRR_MASK)) |
---|
| 856 | + cf->can_id |= CAN_RTR_FLAG; |
---|
| 857 | + } |
---|
| 858 | + |
---|
| 859 | + /* Check the frame received is FD or not*/ |
---|
| 860 | + if (dlc & XCAN_DLCR_EDL_MASK) { |
---|
| 861 | + for (i = 0; i < cf->len; i += 4) { |
---|
| 862 | + dw_offset = XCANFD_FRAME_DW_OFFSET(frame_base) + |
---|
| 863 | + (dwindex * XCANFD_DW_BYTES); |
---|
| 864 | + data[0] = priv->read_reg(priv, dw_offset); |
---|
| 865 | + *(__be32 *)(cf->data + i) = cpu_to_be32(data[0]); |
---|
| 866 | + dwindex++; |
---|
| 867 | + } |
---|
| 868 | + } else { |
---|
| 869 | + for (i = 0; i < cf->len; i += 4) { |
---|
| 870 | + dw_offset = XCANFD_FRAME_DW_OFFSET(frame_base); |
---|
| 871 | + data[0] = priv->read_reg(priv, dw_offset + i); |
---|
| 872 | + *(__be32 *)(cf->data + i) = cpu_to_be32(data[0]); |
---|
| 873 | + } |
---|
| 874 | + } |
---|
| 875 | + stats->rx_bytes += cf->len; |
---|
700 | 876 | stats->rx_packets++; |
---|
701 | 877 | netif_receive_skb(skb); |
---|
702 | 878 | |
---|
.. | .. |
---|
813 | 989 | { |
---|
814 | 990 | struct xcan_priv *priv = netdev_priv(ndev); |
---|
815 | 991 | struct net_device_stats *stats = &ndev->stats; |
---|
816 | | - struct can_frame *cf; |
---|
817 | | - struct sk_buff *skb; |
---|
| 992 | + struct can_frame cf = { }; |
---|
818 | 993 | u32 err_status; |
---|
819 | | - |
---|
820 | | - skb = alloc_can_err_skb(ndev, &cf); |
---|
821 | 994 | |
---|
822 | 995 | err_status = priv->read_reg(priv, XCAN_ESR_OFFSET); |
---|
823 | 996 | priv->write_reg(priv, XCAN_ESR_OFFSET, err_status); |
---|
.. | .. |
---|
828 | 1001 | /* Leave device in Config Mode in bus-off state */ |
---|
829 | 1002 | priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_RESET_MASK); |
---|
830 | 1003 | can_bus_off(ndev); |
---|
831 | | - if (skb) |
---|
832 | | - cf->can_id |= CAN_ERR_BUSOFF; |
---|
| 1004 | + cf.can_id |= CAN_ERR_BUSOFF; |
---|
833 | 1005 | } else { |
---|
834 | 1006 | enum can_state new_state = xcan_current_error_state(ndev); |
---|
835 | 1007 | |
---|
836 | 1008 | if (new_state != priv->can.state) |
---|
837 | | - xcan_set_error_state(ndev, new_state, skb ? cf : NULL); |
---|
| 1009 | + xcan_set_error_state(ndev, new_state, &cf); |
---|
838 | 1010 | } |
---|
839 | 1011 | |
---|
840 | 1012 | /* Check for Arbitration lost interrupt */ |
---|
841 | 1013 | if (isr & XCAN_IXR_ARBLST_MASK) { |
---|
842 | 1014 | priv->can.can_stats.arbitration_lost++; |
---|
843 | | - if (skb) { |
---|
844 | | - cf->can_id |= CAN_ERR_LOSTARB; |
---|
845 | | - cf->data[0] = CAN_ERR_LOSTARB_UNSPEC; |
---|
846 | | - } |
---|
| 1015 | + cf.can_id |= CAN_ERR_LOSTARB; |
---|
| 1016 | + cf.data[0] = CAN_ERR_LOSTARB_UNSPEC; |
---|
847 | 1017 | } |
---|
848 | 1018 | |
---|
849 | 1019 | /* Check for RX FIFO Overflow interrupt */ |
---|
850 | 1020 | if (isr & XCAN_IXR_RXOFLW_MASK) { |
---|
851 | 1021 | stats->rx_over_errors++; |
---|
852 | 1022 | stats->rx_errors++; |
---|
853 | | - if (skb) { |
---|
854 | | - cf->can_id |= CAN_ERR_CRTL; |
---|
855 | | - cf->data[1] |= CAN_ERR_CRTL_RX_OVERFLOW; |
---|
856 | | - } |
---|
| 1023 | + cf.can_id |= CAN_ERR_CRTL; |
---|
| 1024 | + cf.data[1] |= CAN_ERR_CRTL_RX_OVERFLOW; |
---|
857 | 1025 | } |
---|
858 | 1026 | |
---|
859 | 1027 | /* Check for RX Match Not Finished interrupt */ |
---|
.. | .. |
---|
861 | 1029 | stats->rx_dropped++; |
---|
862 | 1030 | stats->rx_errors++; |
---|
863 | 1031 | netdev_err(ndev, "RX match not finished, frame discarded\n"); |
---|
864 | | - if (skb) { |
---|
865 | | - cf->can_id |= CAN_ERR_CRTL; |
---|
866 | | - cf->data[1] |= CAN_ERR_CRTL_UNSPEC; |
---|
867 | | - } |
---|
| 1032 | + cf.can_id |= CAN_ERR_CRTL; |
---|
| 1033 | + cf.data[1] |= CAN_ERR_CRTL_UNSPEC; |
---|
868 | 1034 | } |
---|
869 | 1035 | |
---|
870 | 1036 | /* Check for error interrupt */ |
---|
871 | 1037 | if (isr & XCAN_IXR_ERROR_MASK) { |
---|
872 | | - if (skb) |
---|
873 | | - cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; |
---|
| 1038 | + bool berr_reporting = false; |
---|
| 1039 | + |
---|
| 1040 | + if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) { |
---|
| 1041 | + berr_reporting = true; |
---|
| 1042 | + cf.can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; |
---|
| 1043 | + } |
---|
874 | 1044 | |
---|
875 | 1045 | /* Check for Ack error interrupt */ |
---|
876 | 1046 | if (err_status & XCAN_ESR_ACKER_MASK) { |
---|
877 | 1047 | stats->tx_errors++; |
---|
878 | | - if (skb) { |
---|
879 | | - cf->can_id |= CAN_ERR_ACK; |
---|
880 | | - cf->data[3] = CAN_ERR_PROT_LOC_ACK; |
---|
| 1048 | + if (berr_reporting) { |
---|
| 1049 | + cf.can_id |= CAN_ERR_ACK; |
---|
| 1050 | + cf.data[3] = CAN_ERR_PROT_LOC_ACK; |
---|
881 | 1051 | } |
---|
882 | 1052 | } |
---|
883 | 1053 | |
---|
884 | 1054 | /* Check for Bit error interrupt */ |
---|
885 | 1055 | if (err_status & XCAN_ESR_BERR_MASK) { |
---|
886 | 1056 | stats->tx_errors++; |
---|
887 | | - if (skb) { |
---|
888 | | - cf->can_id |= CAN_ERR_PROT; |
---|
889 | | - cf->data[2] = CAN_ERR_PROT_BIT; |
---|
| 1057 | + if (berr_reporting) { |
---|
| 1058 | + cf.can_id |= CAN_ERR_PROT; |
---|
| 1059 | + cf.data[2] = CAN_ERR_PROT_BIT; |
---|
890 | 1060 | } |
---|
891 | 1061 | } |
---|
892 | 1062 | |
---|
893 | 1063 | /* Check for Stuff error interrupt */ |
---|
894 | 1064 | if (err_status & XCAN_ESR_STER_MASK) { |
---|
895 | 1065 | stats->rx_errors++; |
---|
896 | | - if (skb) { |
---|
897 | | - cf->can_id |= CAN_ERR_PROT; |
---|
898 | | - cf->data[2] = CAN_ERR_PROT_STUFF; |
---|
| 1066 | + if (berr_reporting) { |
---|
| 1067 | + cf.can_id |= CAN_ERR_PROT; |
---|
| 1068 | + cf.data[2] = CAN_ERR_PROT_STUFF; |
---|
899 | 1069 | } |
---|
900 | 1070 | } |
---|
901 | 1071 | |
---|
902 | 1072 | /* Check for Form error interrupt */ |
---|
903 | 1073 | if (err_status & XCAN_ESR_FMER_MASK) { |
---|
904 | 1074 | stats->rx_errors++; |
---|
905 | | - if (skb) { |
---|
906 | | - cf->can_id |= CAN_ERR_PROT; |
---|
907 | | - cf->data[2] = CAN_ERR_PROT_FORM; |
---|
| 1075 | + if (berr_reporting) { |
---|
| 1076 | + cf.can_id |= CAN_ERR_PROT; |
---|
| 1077 | + cf.data[2] = CAN_ERR_PROT_FORM; |
---|
908 | 1078 | } |
---|
909 | 1079 | } |
---|
910 | 1080 | |
---|
911 | 1081 | /* Check for CRC error interrupt */ |
---|
912 | 1082 | if (err_status & XCAN_ESR_CRCER_MASK) { |
---|
913 | 1083 | stats->rx_errors++; |
---|
914 | | - if (skb) { |
---|
915 | | - cf->can_id |= CAN_ERR_PROT; |
---|
916 | | - cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ; |
---|
| 1084 | + if (berr_reporting) { |
---|
| 1085 | + cf.can_id |= CAN_ERR_PROT; |
---|
| 1086 | + cf.data[3] = CAN_ERR_PROT_LOC_CRC_SEQ; |
---|
917 | 1087 | } |
---|
918 | 1088 | } |
---|
919 | | - priv->can.can_stats.bus_error++; |
---|
| 1089 | + priv->can.can_stats.bus_error++; |
---|
920 | 1090 | } |
---|
921 | 1091 | |
---|
922 | | - if (skb) { |
---|
923 | | - stats->rx_packets++; |
---|
924 | | - stats->rx_bytes += cf->can_dlc; |
---|
925 | | - netif_rx(skb); |
---|
| 1092 | + if (cf.can_id) { |
---|
| 1093 | + struct can_frame *skb_cf; |
---|
| 1094 | + struct sk_buff *skb = alloc_can_err_skb(ndev, &skb_cf); |
---|
| 1095 | + |
---|
| 1096 | + if (skb) { |
---|
| 1097 | + skb_cf->can_id |= cf.can_id; |
---|
| 1098 | + memcpy(skb_cf->data, cf.data, CAN_ERR_DLC); |
---|
| 1099 | + stats->rx_packets++; |
---|
| 1100 | + stats->rx_bytes += CAN_ERR_DLC; |
---|
| 1101 | + netif_rx(skb); |
---|
| 1102 | + } |
---|
926 | 1103 | } |
---|
927 | 1104 | |
---|
928 | 1105 | netdev_dbg(ndev, "%s: error status register:0x%x\n", |
---|
929 | | - __func__, priv->read_reg(priv, XCAN_ESR_OFFSET)); |
---|
| 1106 | + __func__, priv->read_reg(priv, XCAN_ESR_OFFSET)); |
---|
930 | 1107 | } |
---|
931 | 1108 | |
---|
932 | 1109 | /** |
---|
.. | .. |
---|
952 | 1129 | |
---|
953 | 1130 | /** |
---|
954 | 1131 | * xcan_rx_fifo_get_next_frame - Get register offset of next RX frame |
---|
| 1132 | + * @priv: Driver private data structure |
---|
955 | 1133 | * |
---|
956 | 1134 | * Return: Register offset of the next frame in RX FIFO. |
---|
957 | 1135 | */ |
---|
.. | .. |
---|
960 | 1138 | int offset; |
---|
961 | 1139 | |
---|
962 | 1140 | if (priv->devtype.flags & XCAN_FLAG_RX_FIFO_MULTI) { |
---|
963 | | - u32 fsr; |
---|
| 1141 | + u32 fsr, mask; |
---|
964 | 1142 | |
---|
965 | 1143 | /* clear RXOK before the is-empty check so that any newly |
---|
966 | 1144 | * received frame will reassert it without a race |
---|
.. | .. |
---|
970 | 1148 | fsr = priv->read_reg(priv, XCAN_FSR_OFFSET); |
---|
971 | 1149 | |
---|
972 | 1150 | /* check if RX FIFO is empty */ |
---|
973 | | - if (!(fsr & XCAN_FSR_FL_MASK)) |
---|
| 1151 | + if (priv->devtype.flags & XCAN_FLAG_CANFD_2) |
---|
| 1152 | + mask = XCAN_2_FSR_FL_MASK; |
---|
| 1153 | + else |
---|
| 1154 | + mask = XCAN_FSR_FL_MASK; |
---|
| 1155 | + |
---|
| 1156 | + if (!(fsr & mask)) |
---|
974 | 1157 | return -ENOENT; |
---|
975 | 1158 | |
---|
976 | | - offset = XCAN_RXMSG_FRAME_OFFSET(fsr & XCAN_FSR_RI_MASK); |
---|
| 1159 | + if (priv->devtype.flags & XCAN_FLAG_CANFD_2) |
---|
| 1160 | + offset = |
---|
| 1161 | + XCAN_RXMSG_2_FRAME_OFFSET(fsr & XCAN_2_FSR_RI_MASK); |
---|
| 1162 | + else |
---|
| 1163 | + offset = |
---|
| 1164 | + XCAN_RXMSG_FRAME_OFFSET(fsr & XCAN_FSR_RI_MASK); |
---|
977 | 1165 | |
---|
978 | 1166 | } else { |
---|
979 | 1167 | /* check if RX FIFO is empty */ |
---|
.. | .. |
---|
1008 | 1196 | |
---|
1009 | 1197 | while ((frame_offset = xcan_rx_fifo_get_next_frame(priv)) >= 0 && |
---|
1010 | 1198 | (work_done < quota)) { |
---|
1011 | | - work_done += xcan_rx(ndev, frame_offset); |
---|
| 1199 | + if (xcan_rx_int_mask(priv) & XCAN_IXR_RXOK_MASK) |
---|
| 1200 | + work_done += xcanfd_rx(ndev, frame_offset); |
---|
| 1201 | + else |
---|
| 1202 | + work_done += xcan_rx(ndev, frame_offset); |
---|
1012 | 1203 | |
---|
1013 | 1204 | if (priv->devtype.flags & XCAN_FLAG_RX_FIFO_MULTI) |
---|
1014 | 1205 | /* increment read index */ |
---|
.. | .. |
---|
1083 | 1274 | * via TXFEMP handling as we read TXFEMP *after* TXOK |
---|
1084 | 1275 | * clear to satisfy (1). |
---|
1085 | 1276 | */ |
---|
1086 | | - while ((isr & XCAN_IXR_TXOK_MASK) && !WARN_ON(++retries == 100)) { |
---|
1087 | | - priv->write_reg(priv, XCAN_ICR_OFFSET, XCAN_IXR_TXOK_MASK); |
---|
| 1277 | + while ((isr & XCAN_IXR_TXOK_MASK) && |
---|
| 1278 | + !WARN_ON(++retries == 100)) { |
---|
| 1279 | + priv->write_reg(priv, XCAN_ICR_OFFSET, |
---|
| 1280 | + XCAN_IXR_TXOK_MASK); |
---|
1088 | 1281 | isr = priv->read_reg(priv, XCAN_ISR_OFFSET); |
---|
1089 | 1282 | } |
---|
1090 | 1283 | |
---|
.. | .. |
---|
1115 | 1308 | /** |
---|
1116 | 1309 | * xcan_interrupt - CAN Isr |
---|
1117 | 1310 | * @irq: irq number |
---|
1118 | | - * @dev_id: device id poniter |
---|
| 1311 | + * @dev_id: device id pointer |
---|
1119 | 1312 | * |
---|
1120 | 1313 | * This is the xilinx CAN Isr. It checks for the type of interrupt |
---|
1121 | 1314 | * and invokes the corresponding ISR. |
---|
.. | .. |
---|
1176 | 1369 | static void xcan_chip_stop(struct net_device *ndev) |
---|
1177 | 1370 | { |
---|
1178 | 1371 | struct xcan_priv *priv = netdev_priv(ndev); |
---|
| 1372 | + int ret; |
---|
1179 | 1373 | |
---|
1180 | 1374 | /* Disable interrupts and leave the can in configuration mode */ |
---|
1181 | | - set_reset_mode(ndev); |
---|
| 1375 | + ret = set_reset_mode(ndev); |
---|
| 1376 | + if (ret < 0) |
---|
| 1377 | + netdev_dbg(ndev, "set_reset_mode() Failed\n"); |
---|
| 1378 | + |
---|
1182 | 1379 | priv->can.state = CAN_STATE_STOPPED; |
---|
1183 | 1380 | } |
---|
1184 | 1381 | |
---|
.. | .. |
---|
1197 | 1394 | ret = pm_runtime_get_sync(priv->dev); |
---|
1198 | 1395 | if (ret < 0) { |
---|
1199 | 1396 | netdev_err(ndev, "%s: pm_runtime_get failed(%d)\n", |
---|
1200 | | - __func__, ret); |
---|
1201 | | - return ret; |
---|
| 1397 | + __func__, ret); |
---|
| 1398 | + goto err; |
---|
1202 | 1399 | } |
---|
1203 | 1400 | |
---|
1204 | 1401 | ret = request_irq(ndev->irq, xcan_interrupt, priv->irq_flags, |
---|
1205 | | - ndev->name, ndev); |
---|
| 1402 | + ndev->name, ndev); |
---|
1206 | 1403 | if (ret < 0) { |
---|
1207 | 1404 | netdev_err(ndev, "irq allocation for CAN failed\n"); |
---|
1208 | 1405 | goto err; |
---|
.. | .. |
---|
1273 | 1470 | * Return: 0 on success and failure value on error |
---|
1274 | 1471 | */ |
---|
1275 | 1472 | static int xcan_get_berr_counter(const struct net_device *ndev, |
---|
1276 | | - struct can_berr_counter *bec) |
---|
| 1473 | + struct can_berr_counter *bec) |
---|
1277 | 1474 | { |
---|
1278 | 1475 | struct xcan_priv *priv = netdev_priv(ndev); |
---|
1279 | 1476 | int ret; |
---|
.. | .. |
---|
1281 | 1478 | ret = pm_runtime_get_sync(priv->dev); |
---|
1282 | 1479 | if (ret < 0) { |
---|
1283 | 1480 | netdev_err(ndev, "%s: pm_runtime_get failed(%d)\n", |
---|
1284 | | - __func__, ret); |
---|
| 1481 | + __func__, ret); |
---|
| 1482 | + pm_runtime_put(priv->dev); |
---|
1285 | 1483 | return ret; |
---|
1286 | 1484 | } |
---|
1287 | 1485 | |
---|
.. | .. |
---|
1293 | 1491 | |
---|
1294 | 1492 | return 0; |
---|
1295 | 1493 | } |
---|
1296 | | - |
---|
1297 | 1494 | |
---|
1298 | 1495 | static const struct net_device_ops xcan_netdev_ops = { |
---|
1299 | 1496 | .ndo_open = xcan_open, |
---|
.. | .. |
---|
1406 | 1603 | }; |
---|
1407 | 1604 | |
---|
1408 | 1605 | static const struct xcan_devtype_data xcan_zynq_data = { |
---|
| 1606 | + .cantype = XZYNQ_CANPS, |
---|
| 1607 | + .flags = XCAN_FLAG_TXFEMP, |
---|
1409 | 1608 | .bittiming_const = &xcan_bittiming_const, |
---|
1410 | 1609 | .btr_ts2_shift = XCAN_BTR_TS2_SHIFT, |
---|
1411 | 1610 | .btr_sjw_shift = XCAN_BTR_SJW_SHIFT, |
---|
.. | .. |
---|
1413 | 1612 | }; |
---|
1414 | 1613 | |
---|
1415 | 1614 | static const struct xcan_devtype_data xcan_axi_data = { |
---|
| 1615 | + .cantype = XAXI_CAN, |
---|
1416 | 1616 | .bittiming_const = &xcan_bittiming_const, |
---|
1417 | 1617 | .btr_ts2_shift = XCAN_BTR_TS2_SHIFT, |
---|
1418 | 1618 | .btr_sjw_shift = XCAN_BTR_SJW_SHIFT, |
---|
.. | .. |
---|
1420 | 1620 | }; |
---|
1421 | 1621 | |
---|
1422 | 1622 | static const struct xcan_devtype_data xcan_canfd_data = { |
---|
| 1623 | + .cantype = XAXI_CANFD, |
---|
1423 | 1624 | .flags = XCAN_FLAG_EXT_FILTERS | |
---|
1424 | 1625 | XCAN_FLAG_RXMNF | |
---|
1425 | 1626 | XCAN_FLAG_TX_MAILBOXES | |
---|
.. | .. |
---|
1430 | 1631 | .bus_clk_name = "s_axi_aclk", |
---|
1431 | 1632 | }; |
---|
1432 | 1633 | |
---|
| 1634 | +static const struct xcan_devtype_data xcan_canfd2_data = { |
---|
| 1635 | + .cantype = XAXI_CANFD_2_0, |
---|
| 1636 | + .flags = XCAN_FLAG_EXT_FILTERS | |
---|
| 1637 | + XCAN_FLAG_RXMNF | |
---|
| 1638 | + XCAN_FLAG_TX_MAILBOXES | |
---|
| 1639 | + XCAN_FLAG_CANFD_2 | |
---|
| 1640 | + XCAN_FLAG_RX_FIFO_MULTI, |
---|
| 1641 | + .bittiming_const = &xcan_bittiming_const_canfd2, |
---|
| 1642 | + .btr_ts2_shift = XCAN_BTR_TS2_SHIFT_CANFD, |
---|
| 1643 | + .btr_sjw_shift = XCAN_BTR_SJW_SHIFT_CANFD, |
---|
| 1644 | + .bus_clk_name = "s_axi_aclk", |
---|
| 1645 | +}; |
---|
| 1646 | + |
---|
1433 | 1647 | /* Match table for OF platform binding */ |
---|
1434 | 1648 | static const struct of_device_id xcan_of_match[] = { |
---|
1435 | 1649 | { .compatible = "xlnx,zynq-can-1.0", .data = &xcan_zynq_data }, |
---|
1436 | 1650 | { .compatible = "xlnx,axi-can-1.00.a", .data = &xcan_axi_data }, |
---|
1437 | 1651 | { .compatible = "xlnx,canfd-1.0", .data = &xcan_canfd_data }, |
---|
| 1652 | + { .compatible = "xlnx,canfd-2.0", .data = &xcan_canfd2_data }, |
---|
1438 | 1653 | { /* end of list */ }, |
---|
1439 | 1654 | }; |
---|
1440 | 1655 | MODULE_DEVICE_TABLE(of, xcan_of_match); |
---|
.. | .. |
---|
1450 | 1665 | */ |
---|
1451 | 1666 | static int xcan_probe(struct platform_device *pdev) |
---|
1452 | 1667 | { |
---|
1453 | | - struct resource *res; /* IO mem resources */ |
---|
1454 | 1668 | struct net_device *ndev; |
---|
1455 | 1669 | struct xcan_priv *priv; |
---|
1456 | 1670 | const struct of_device_id *of_id; |
---|
.. | .. |
---|
1458 | 1672 | void __iomem *addr; |
---|
1459 | 1673 | int ret; |
---|
1460 | 1674 | int rx_max, tx_max; |
---|
1461 | | - int hw_tx_max, hw_rx_max; |
---|
| 1675 | + u32 hw_tx_max = 0, hw_rx_max = 0; |
---|
1462 | 1676 | const char *hw_tx_max_property; |
---|
1463 | 1677 | |
---|
1464 | 1678 | /* Get the virtual base address for the device */ |
---|
1465 | | - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
---|
1466 | | - addr = devm_ioremap_resource(&pdev->dev, res); |
---|
| 1679 | + addr = devm_platform_ioremap_resource(pdev, 0); |
---|
1467 | 1680 | if (IS_ERR(addr)) { |
---|
1468 | 1681 | ret = PTR_ERR(addr); |
---|
1469 | 1682 | goto err; |
---|
.. | .. |
---|
1512 | 1725 | */ |
---|
1513 | 1726 | if (!(devtype->flags & XCAN_FLAG_TX_MAILBOXES) && |
---|
1514 | 1727 | (devtype->flags & XCAN_FLAG_TXFEMP)) |
---|
1515 | | - tx_max = min(hw_tx_max, 2); |
---|
| 1728 | + tx_max = min(hw_tx_max, 2U); |
---|
1516 | 1729 | else |
---|
1517 | 1730 | tx_max = 1; |
---|
1518 | 1731 | |
---|
.. | .. |
---|
1530 | 1743 | priv->can.do_get_berr_counter = xcan_get_berr_counter; |
---|
1531 | 1744 | priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK | |
---|
1532 | 1745 | CAN_CTRLMODE_BERR_REPORTING; |
---|
| 1746 | + |
---|
| 1747 | + if (devtype->cantype == XAXI_CANFD) |
---|
| 1748 | + priv->can.data_bittiming_const = |
---|
| 1749 | + &xcan_data_bittiming_const_canfd; |
---|
| 1750 | + |
---|
| 1751 | + if (devtype->cantype == XAXI_CANFD_2_0) |
---|
| 1752 | + priv->can.data_bittiming_const = |
---|
| 1753 | + &xcan_data_bittiming_const_canfd2; |
---|
| 1754 | + |
---|
| 1755 | + if (devtype->cantype == XAXI_CANFD || |
---|
| 1756 | + devtype->cantype == XAXI_CANFD_2_0) |
---|
| 1757 | + priv->can.ctrlmode_supported |= CAN_CTRLMODE_FD; |
---|
| 1758 | + |
---|
1533 | 1759 | priv->reg_base = addr; |
---|
1534 | 1760 | priv->tx_max = tx_max; |
---|
1535 | 1761 | priv->devtype = *devtype; |
---|
.. | .. |
---|
1551 | 1777 | /* Getting the CAN can_clk info */ |
---|
1552 | 1778 | priv->can_clk = devm_clk_get(&pdev->dev, "can_clk"); |
---|
1553 | 1779 | if (IS_ERR(priv->can_clk)) { |
---|
1554 | | - dev_err(&pdev->dev, "Device clock not found.\n"); |
---|
| 1780 | + if (PTR_ERR(priv->can_clk) != -EPROBE_DEFER) |
---|
| 1781 | + dev_err(&pdev->dev, "Device clock not found.\n"); |
---|
1555 | 1782 | ret = PTR_ERR(priv->can_clk); |
---|
1556 | 1783 | goto err_free; |
---|
1557 | 1784 | } |
---|
1558 | 1785 | |
---|
1559 | 1786 | priv->bus_clk = devm_clk_get(&pdev->dev, devtype->bus_clk_name); |
---|
1560 | 1787 | if (IS_ERR(priv->bus_clk)) { |
---|
1561 | | - dev_err(&pdev->dev, "bus clock not found\n"); |
---|
| 1788 | + if (PTR_ERR(priv->bus_clk) != -EPROBE_DEFER) |
---|
| 1789 | + dev_err(&pdev->dev, "bus clock not found\n"); |
---|
1562 | 1790 | ret = PTR_ERR(priv->bus_clk); |
---|
1563 | 1791 | goto err_free; |
---|
1564 | 1792 | } |
---|
.. | .. |
---|
1570 | 1798 | ret = pm_runtime_get_sync(&pdev->dev); |
---|
1571 | 1799 | if (ret < 0) { |
---|
1572 | 1800 | netdev_err(ndev, "%s: pm_runtime_get failed(%d)\n", |
---|
1573 | | - __func__, ret); |
---|
1574 | | - goto err_pmdisable; |
---|
| 1801 | + __func__, ret); |
---|
| 1802 | + goto err_disableclks; |
---|
1575 | 1803 | } |
---|
1576 | 1804 | |
---|
1577 | 1805 | if (priv->read_reg(priv, XCAN_SR_OFFSET) != XCAN_SR_CONFIG_MASK) { |
---|
.. | .. |
---|
1593 | 1821 | |
---|
1594 | 1822 | pm_runtime_put(&pdev->dev); |
---|
1595 | 1823 | |
---|
| 1824 | + if (priv->devtype.flags & XCAN_FLAG_CANFD_2) { |
---|
| 1825 | + priv->write_reg(priv, XCAN_AFR_2_ID_OFFSET, 0x00000000); |
---|
| 1826 | + priv->write_reg(priv, XCAN_AFR_2_MASK_OFFSET, 0x00000000); |
---|
| 1827 | + } |
---|
| 1828 | + |
---|
1596 | 1829 | netdev_dbg(ndev, "reg_base=0x%p irq=%d clock=%d, tx buffers: actual %d, using %d\n", |
---|
1597 | 1830 | priv->reg_base, ndev->irq, priv->can.clock.freq, |
---|
1598 | 1831 | hw_tx_max, priv->tx_max); |
---|
.. | .. |
---|
1601 | 1834 | |
---|
1602 | 1835 | err_disableclks: |
---|
1603 | 1836 | pm_runtime_put(priv->dev); |
---|
1604 | | -err_pmdisable: |
---|
1605 | 1837 | pm_runtime_disable(&pdev->dev); |
---|
1606 | 1838 | err_free: |
---|
1607 | 1839 | free_candev(ndev); |
---|