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

can: Add Nuvoton NCT6694 CANFD support

This driver supports Socket CANFD functionality for NCT6694 MFD
device based on USB interface.

Reviewed-by: Marc Kleine-Budde <mkl@pengutronix.de>
Reviewed-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
Signed-off-by: Ming Yu <a0282524688@gmail.com>
Link: https://lore.kernel.org/r/20250912091952.1169369-5-a0282524688@gmail.com
Signed-off-by: Lee Jones <lee@kernel.org>

authored by

Ming Yu and committed by
Lee Jones
8a204684 c5cf27db

+845
+1
MAINTAINERS
··· 18088 18088 F: drivers/gpio/gpio-nct6694.c 18089 18089 F: drivers/i2c/busses/i2c-nct6694.c 18090 18090 F: drivers/mfd/nct6694.c 18091 + F: drivers/net/can/usb/nct6694_canfd.c 18091 18092 F: include/linux/mfd/nct6694.h 18092 18093 18093 18094 NUVOTON NCT7201 IIO DRIVER
+11
drivers/net/can/usb/Kconfig
··· 134 134 This driver supports the CAN BUS Analyzer interface 135 135 from Microchip (http://www.microchip.com/development-tools/). 136 136 137 + config CAN_NCT6694 138 + tristate "Nuvoton NCT6694 Socket CANfd support" 139 + depends on MFD_NCT6694 140 + select CAN_RX_OFFLOAD 141 + help 142 + If you say yes to this option, support will be included for Nuvoton 143 + NCT6694, a USB device to socket CANfd controller. 144 + 145 + This driver can also be built as a module. If so, the module will 146 + be called nct6694_canfd. 147 + 137 148 config CAN_PEAK_USB 138 149 tristate "PEAK PCAN-USB/USB Pro interfaces for CAN 2.0b/CAN-FD" 139 150 help
+1
drivers/net/can/usb/Makefile
··· 11 11 obj-$(CONFIG_CAN_GS_USB) += gs_usb.o 12 12 obj-$(CONFIG_CAN_KVASER_USB) += kvaser_usb/ 13 13 obj-$(CONFIG_CAN_MCBA_USB) += mcba_usb.o 14 + obj-$(CONFIG_CAN_NCT6694) += nct6694_canfd.o 14 15 obj-$(CONFIG_CAN_PEAK_USB) += peak_usb/ 15 16 obj-$(CONFIG_CAN_UCAN) += ucan.o
+832
drivers/net/can/usb/nct6694_canfd.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Nuvoton NCT6694 Socket CANfd driver based on USB interface. 3 + * 4 + * Copyright (C) 2025 Nuvoton Technology Corp. 5 + */ 6 + 7 + #include <linux/bitfield.h> 8 + #include <linux/can/dev.h> 9 + #include <linux/can/rx-offload.h> 10 + #include <linux/ethtool.h> 11 + #include <linux/idr.h> 12 + #include <linux/irqdomain.h> 13 + #include <linux/kernel.h> 14 + #include <linux/mfd/nct6694.h> 15 + #include <linux/module.h> 16 + #include <linux/netdevice.h> 17 + #include <linux/platform_device.h> 18 + 19 + #define DEVICE_NAME "nct6694-canfd" 20 + 21 + /* USB command module type for NCT6694 CANfd controller. 22 + * This defines the module type used for communication with the NCT6694 23 + * CANfd controller over the USB interface. 24 + */ 25 + #define NCT6694_CANFD_MOD 0x05 26 + 27 + /* Command 00h - CAN Setting and Initialization */ 28 + #define NCT6694_CANFD_SETTING 0x00 29 + #define NCT6694_CANFD_SETTING_ACTIVE_CTRL1 BIT(0) 30 + #define NCT6694_CANFD_SETTING_ACTIVE_CTRL2 BIT(1) 31 + #define NCT6694_CANFD_SETTING_ACTIVE_NBTP_DBTP BIT(2) 32 + #define NCT6694_CANFD_SETTING_CTRL1_MON BIT(0) 33 + #define NCT6694_CANFD_SETTING_CTRL1_NISO BIT(1) 34 + #define NCT6694_CANFD_SETTING_CTRL1_LBCK BIT(2) 35 + #define NCT6694_CANFD_SETTING_NBTP_NTSEG2 GENMASK(6, 0) 36 + #define NCT6694_CANFD_SETTING_NBTP_NTSEG1 GENMASK(15, 8) 37 + #define NCT6694_CANFD_SETTING_NBTP_NBRP GENMASK(24, 16) 38 + #define NCT6694_CANFD_SETTING_NBTP_NSJW GENMASK(31, 25) 39 + #define NCT6694_CANFD_SETTING_DBTP_DSJW GENMASK(3, 0) 40 + #define NCT6694_CANFD_SETTING_DBTP_DTSEG2 GENMASK(7, 4) 41 + #define NCT6694_CANFD_SETTING_DBTP_DTSEG1 GENMASK(12, 8) 42 + #define NCT6694_CANFD_SETTING_DBTP_DBRP GENMASK(20, 16) 43 + #define NCT6694_CANFD_SETTING_DBTP_TDC BIT(23) 44 + 45 + /* Command 01h - CAN Information */ 46 + #define NCT6694_CANFD_INFORMATION 0x01 47 + #define NCT6694_CANFD_INFORMATION_SEL 0x00 48 + 49 + /* Command 02h - CAN Event */ 50 + #define NCT6694_CANFD_EVENT 0x02 51 + #define NCT6694_CANFD_EVENT_SEL(idx, mask) \ 52 + ((idx ? 0x80 : 0x00) | ((mask) & 0x7F)) 53 + 54 + #define NCT6694_CANFD_EVENT_MASK GENMASK(5, 0) 55 + #define NCT6694_CANFD_EVT_TX_FIFO_EMPTY BIT(7) /* Read-clear */ 56 + #define NCT6694_CANFD_EVT_RX_DATA_LOST BIT(5) /* Read-clear */ 57 + #define NCT6694_CANFD_EVT_RX_DATA_IN BIT(7) /* Read-clear */ 58 + 59 + /* Command 10h - CAN Deliver */ 60 + #define NCT6694_CANFD_DELIVER 0x10 61 + #define NCT6694_CANFD_DELIVER_SEL(buf_cnt) \ 62 + ((buf_cnt) & 0xFF) 63 + 64 + /* Command 11h - CAN Receive */ 65 + #define NCT6694_CANFD_RECEIVE 0x11 66 + #define NCT6694_CANFD_RECEIVE_SEL(idx, buf_cnt) \ 67 + ((idx ? 0x80 : 0x00) | ((buf_cnt) & 0x7F)) 68 + 69 + #define NCT6694_CANFD_FRAME_TAG(idx) (0xC0 | (idx)) 70 + #define NCT6694_CANFD_FRAME_FLAG_EFF BIT(0) 71 + #define NCT6694_CANFD_FRAME_FLAG_RTR BIT(1) 72 + #define NCT6694_CANFD_FRAME_FLAG_FD BIT(2) 73 + #define NCT6694_CANFD_FRAME_FLAG_BRS BIT(3) 74 + #define NCT6694_CANFD_FRAME_FLAG_ERR BIT(4) 75 + 76 + #define NCT6694_NAPI_WEIGHT 32 77 + 78 + enum nct6694_event_err { 79 + NCT6694_CANFD_EVT_ERR_NO_ERROR = 0, 80 + NCT6694_CANFD_EVT_ERR_CRC_ERROR, 81 + NCT6694_CANFD_EVT_ERR_STUFF_ERROR, 82 + NCT6694_CANFD_EVT_ERR_ACK_ERROR, 83 + NCT6694_CANFD_EVT_ERR_FORM_ERROR, 84 + NCT6694_CANFD_EVT_ERR_BIT_ERROR, 85 + NCT6694_CANFD_EVT_ERR_TIMEOUT_ERROR, 86 + NCT6694_CANFD_EVT_ERR_UNKNOWN_ERROR, 87 + }; 88 + 89 + enum nct6694_event_status { 90 + NCT6694_CANFD_EVT_STS_ERROR_ACTIVE = 0, 91 + NCT6694_CANFD_EVT_STS_ERROR_PASSIVE, 92 + NCT6694_CANFD_EVT_STS_BUS_OFF, 93 + NCT6694_CANFD_EVT_STS_WARNING, 94 + }; 95 + 96 + struct __packed nct6694_canfd_setting { 97 + __le32 nbr; 98 + __le32 dbr; 99 + u8 active; 100 + u8 reserved[3]; 101 + __le16 ctrl1; 102 + __le16 ctrl2; 103 + __le32 nbtp; 104 + __le32 dbtp; 105 + }; 106 + 107 + struct __packed nct6694_canfd_information { 108 + u8 tx_fifo_cnt; 109 + u8 rx_fifo_cnt; 110 + u8 reserved[2]; 111 + __le32 can_clk; 112 + }; 113 + 114 + struct __packed nct6694_canfd_event { 115 + u8 err; 116 + u8 status; 117 + u8 tx_evt; 118 + u8 rx_evt; 119 + u8 rec; 120 + u8 tec; 121 + u8 reserved[2]; 122 + }; 123 + 124 + struct __packed nct6694_canfd_frame { 125 + u8 tag; 126 + u8 flag; 127 + u8 reserved; 128 + u8 length; 129 + __le32 id; 130 + u8 data[CANFD_MAX_DLEN]; 131 + }; 132 + 133 + struct nct6694_canfd_priv { 134 + struct can_priv can; /* must be the first member */ 135 + struct can_rx_offload offload; 136 + struct net_device *ndev; 137 + struct nct6694 *nct6694; 138 + struct workqueue_struct *wq; 139 + struct work_struct tx_work; 140 + struct nct6694_canfd_frame tx; 141 + struct nct6694_canfd_frame rx; 142 + struct nct6694_canfd_event event[2]; 143 + struct can_berr_counter bec; 144 + }; 145 + 146 + static inline struct nct6694_canfd_priv *rx_offload_to_priv(struct can_rx_offload *offload) 147 + { 148 + return container_of(offload, struct nct6694_canfd_priv, offload); 149 + } 150 + 151 + static const struct can_bittiming_const nct6694_canfd_bittiming_nominal_const = { 152 + .name = DEVICE_NAME, 153 + .tseg1_min = 1, 154 + .tseg1_max = 256, 155 + .tseg2_min = 1, 156 + .tseg2_max = 128, 157 + .sjw_max = 128, 158 + .brp_min = 1, 159 + .brp_max = 512, 160 + .brp_inc = 1, 161 + }; 162 + 163 + static const struct can_bittiming_const nct6694_canfd_bittiming_data_const = { 164 + .name = DEVICE_NAME, 165 + .tseg1_min = 1, 166 + .tseg1_max = 32, 167 + .tseg2_min = 1, 168 + .tseg2_max = 16, 169 + .sjw_max = 16, 170 + .brp_min = 1, 171 + .brp_max = 32, 172 + .brp_inc = 1, 173 + }; 174 + 175 + static void nct6694_canfd_rx_offload(struct can_rx_offload *offload, 176 + struct sk_buff *skb) 177 + { 178 + struct nct6694_canfd_priv *priv = rx_offload_to_priv(offload); 179 + int ret; 180 + 181 + ret = can_rx_offload_queue_tail(offload, skb); 182 + if (ret) 183 + priv->ndev->stats.rx_fifo_errors++; 184 + } 185 + 186 + static void nct6694_canfd_handle_lost_msg(struct net_device *ndev) 187 + { 188 + struct nct6694_canfd_priv *priv = netdev_priv(ndev); 189 + struct net_device_stats *stats = &ndev->stats; 190 + struct can_frame *cf; 191 + struct sk_buff *skb; 192 + 193 + netdev_dbg(ndev, "RX FIFO overflow, message(s) lost.\n"); 194 + 195 + stats->rx_errors++; 196 + stats->rx_over_errors++; 197 + 198 + skb = alloc_can_err_skb(ndev, &cf); 199 + if (!skb) 200 + return; 201 + 202 + cf->can_id |= CAN_ERR_CRTL; 203 + cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; 204 + 205 + nct6694_canfd_rx_offload(&priv->offload, skb); 206 + } 207 + 208 + static void nct6694_canfd_handle_rx(struct net_device *ndev, u8 rx_evt) 209 + { 210 + struct net_device_stats *stats = &ndev->stats; 211 + struct nct6694_canfd_priv *priv = netdev_priv(ndev); 212 + struct nct6694_canfd_frame *frame = &priv->rx; 213 + const struct nct6694_cmd_header cmd_hd = { 214 + .mod = NCT6694_CANFD_MOD, 215 + .cmd = NCT6694_CANFD_RECEIVE, 216 + .sel = NCT6694_CANFD_RECEIVE_SEL(ndev->dev_port, 1), 217 + .len = cpu_to_le16(sizeof(*frame)) 218 + }; 219 + struct sk_buff *skb; 220 + int ret; 221 + 222 + ret = nct6694_read_msg(priv->nct6694, &cmd_hd, frame); 223 + if (ret) 224 + return; 225 + 226 + if (frame->flag & NCT6694_CANFD_FRAME_FLAG_FD) { 227 + struct canfd_frame *cfd; 228 + 229 + skb = alloc_canfd_skb(priv->ndev, &cfd); 230 + if (!skb) { 231 + stats->rx_dropped++; 232 + return; 233 + } 234 + 235 + cfd->can_id = le32_to_cpu(frame->id); 236 + cfd->len = canfd_sanitize_len(frame->length); 237 + if (frame->flag & NCT6694_CANFD_FRAME_FLAG_EFF) 238 + cfd->can_id |= CAN_EFF_FLAG; 239 + if (frame->flag & NCT6694_CANFD_FRAME_FLAG_BRS) 240 + cfd->flags |= CANFD_BRS; 241 + if (frame->flag & NCT6694_CANFD_FRAME_FLAG_ERR) 242 + cfd->flags |= CANFD_ESI; 243 + 244 + memcpy(cfd->data, frame->data, cfd->len); 245 + } else { 246 + struct can_frame *cf; 247 + 248 + skb = alloc_can_skb(priv->ndev, &cf); 249 + if (!skb) { 250 + stats->rx_dropped++; 251 + return; 252 + } 253 + 254 + cf->can_id = le32_to_cpu(frame->id); 255 + cf->len = can_cc_dlc2len(frame->length); 256 + if (frame->flag & NCT6694_CANFD_FRAME_FLAG_EFF) 257 + cf->can_id |= CAN_EFF_FLAG; 258 + 259 + if (frame->flag & NCT6694_CANFD_FRAME_FLAG_RTR) 260 + cf->can_id |= CAN_RTR_FLAG; 261 + else 262 + memcpy(cf->data, frame->data, cf->len); 263 + } 264 + 265 + nct6694_canfd_rx_offload(&priv->offload, skb); 266 + } 267 + 268 + static int nct6694_canfd_get_berr_counter(const struct net_device *ndev, 269 + struct can_berr_counter *bec) 270 + { 271 + struct nct6694_canfd_priv *priv = netdev_priv(ndev); 272 + 273 + *bec = priv->bec; 274 + 275 + return 0; 276 + } 277 + 278 + static void nct6694_canfd_handle_state_change(struct net_device *ndev, u8 status) 279 + { 280 + struct nct6694_canfd_priv *priv = netdev_priv(ndev); 281 + enum can_state new_state, rx_state, tx_state; 282 + struct can_berr_counter bec; 283 + struct can_frame *cf; 284 + struct sk_buff *skb; 285 + 286 + nct6694_canfd_get_berr_counter(ndev, &bec); 287 + can_state_get_by_berr_counter(ndev, &bec, &tx_state, &rx_state); 288 + 289 + new_state = max(tx_state, rx_state); 290 + 291 + /* state hasn't changed */ 292 + if (new_state == priv->can.state) 293 + return; 294 + 295 + skb = alloc_can_err_skb(ndev, &cf); 296 + 297 + can_change_state(ndev, cf, tx_state, rx_state); 298 + 299 + if (new_state == CAN_STATE_BUS_OFF) { 300 + can_bus_off(ndev); 301 + } else if (cf) { 302 + cf->can_id |= CAN_ERR_CNT; 303 + cf->data[6] = bec.txerr; 304 + cf->data[7] = bec.rxerr; 305 + } 306 + 307 + if (skb) 308 + nct6694_canfd_rx_offload(&priv->offload, skb); 309 + } 310 + 311 + static void nct6694_canfd_handle_bus_err(struct net_device *ndev, u8 bus_err) 312 + { 313 + struct nct6694_canfd_priv *priv = netdev_priv(ndev); 314 + struct can_frame *cf; 315 + struct sk_buff *skb; 316 + 317 + priv->can.can_stats.bus_error++; 318 + 319 + skb = alloc_can_err_skb(ndev, &cf); 320 + if (cf) 321 + cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; 322 + 323 + switch (bus_err) { 324 + case NCT6694_CANFD_EVT_ERR_CRC_ERROR: 325 + netdev_dbg(ndev, "CRC error\n"); 326 + ndev->stats.rx_errors++; 327 + if (cf) 328 + cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ; 329 + break; 330 + 331 + case NCT6694_CANFD_EVT_ERR_STUFF_ERROR: 332 + netdev_dbg(ndev, "Stuff error\n"); 333 + ndev->stats.rx_errors++; 334 + if (cf) 335 + cf->data[2] |= CAN_ERR_PROT_STUFF; 336 + break; 337 + 338 + case NCT6694_CANFD_EVT_ERR_ACK_ERROR: 339 + netdev_dbg(ndev, "Ack error\n"); 340 + ndev->stats.tx_errors++; 341 + if (cf) { 342 + cf->can_id |= CAN_ERR_ACK; 343 + cf->data[2] |= CAN_ERR_PROT_TX; 344 + } 345 + break; 346 + 347 + case NCT6694_CANFD_EVT_ERR_FORM_ERROR: 348 + netdev_dbg(ndev, "Form error\n"); 349 + ndev->stats.rx_errors++; 350 + if (cf) 351 + cf->data[2] |= CAN_ERR_PROT_FORM; 352 + break; 353 + 354 + case NCT6694_CANFD_EVT_ERR_BIT_ERROR: 355 + netdev_dbg(ndev, "Bit error\n"); 356 + ndev->stats.tx_errors++; 357 + if (cf) 358 + cf->data[2] |= CAN_ERR_PROT_TX | CAN_ERR_PROT_BIT; 359 + break; 360 + 361 + default: 362 + break; 363 + } 364 + 365 + if (skb) 366 + nct6694_canfd_rx_offload(&priv->offload, skb); 367 + } 368 + 369 + static void nct6694_canfd_handle_tx(struct net_device *ndev) 370 + { 371 + struct nct6694_canfd_priv *priv = netdev_priv(ndev); 372 + struct net_device_stats *stats = &ndev->stats; 373 + 374 + stats->tx_bytes += can_rx_offload_get_echo_skb_queue_tail(&priv->offload, 375 + 0, NULL); 376 + stats->tx_packets++; 377 + netif_wake_queue(ndev); 378 + } 379 + 380 + static irqreturn_t nct6694_canfd_irq(int irq, void *data) 381 + { 382 + struct net_device *ndev = data; 383 + struct nct6694_canfd_priv *priv = netdev_priv(ndev); 384 + struct nct6694_canfd_event *event = &priv->event[ndev->dev_port]; 385 + const struct nct6694_cmd_header cmd_hd = { 386 + .mod = NCT6694_CANFD_MOD, 387 + .cmd = NCT6694_CANFD_EVENT, 388 + .sel = NCT6694_CANFD_EVENT_SEL(ndev->dev_port, NCT6694_CANFD_EVENT_MASK), 389 + .len = cpu_to_le16(sizeof(priv->event)) 390 + }; 391 + irqreturn_t handled = IRQ_NONE; 392 + int ret; 393 + 394 + ret = nct6694_read_msg(priv->nct6694, &cmd_hd, priv->event); 395 + if (ret < 0) 396 + return handled; 397 + 398 + if (event->rx_evt & NCT6694_CANFD_EVT_RX_DATA_IN) { 399 + nct6694_canfd_handle_rx(ndev, event->rx_evt); 400 + handled = IRQ_HANDLED; 401 + } 402 + 403 + if (event->rx_evt & NCT6694_CANFD_EVT_RX_DATA_LOST) { 404 + nct6694_canfd_handle_lost_msg(ndev); 405 + handled = IRQ_HANDLED; 406 + } 407 + 408 + if (event->status) { 409 + nct6694_canfd_handle_state_change(ndev, event->status); 410 + handled = IRQ_HANDLED; 411 + } 412 + 413 + if (event->err != NCT6694_CANFD_EVT_ERR_NO_ERROR) { 414 + if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) 415 + nct6694_canfd_handle_bus_err(ndev, event->err); 416 + handled = IRQ_HANDLED; 417 + } 418 + 419 + if (event->tx_evt & NCT6694_CANFD_EVT_TX_FIFO_EMPTY) { 420 + nct6694_canfd_handle_tx(ndev); 421 + handled = IRQ_HANDLED; 422 + } 423 + 424 + if (handled) 425 + can_rx_offload_threaded_irq_finish(&priv->offload); 426 + 427 + priv->bec.rxerr = event->rec; 428 + priv->bec.txerr = event->tec; 429 + 430 + return handled; 431 + } 432 + 433 + static void nct6694_canfd_tx_work(struct work_struct *work) 434 + { 435 + struct nct6694_canfd_priv *priv = container_of(work, 436 + struct nct6694_canfd_priv, 437 + tx_work); 438 + struct nct6694_canfd_frame *frame = &priv->tx; 439 + struct net_device *ndev = priv->ndev; 440 + struct net_device_stats *stats = &ndev->stats; 441 + struct sk_buff *skb = priv->can.echo_skb[0]; 442 + static const struct nct6694_cmd_header cmd_hd = { 443 + .mod = NCT6694_CANFD_MOD, 444 + .cmd = NCT6694_CANFD_DELIVER, 445 + .sel = NCT6694_CANFD_DELIVER_SEL(1), 446 + .len = cpu_to_le16(sizeof(*frame)) 447 + }; 448 + u32 txid; 449 + int err; 450 + 451 + memset(frame, 0, sizeof(*frame)); 452 + 453 + frame->tag = NCT6694_CANFD_FRAME_TAG(ndev->dev_port); 454 + 455 + if (can_is_canfd_skb(skb)) { 456 + struct canfd_frame *cfd = (struct canfd_frame *)skb->data; 457 + 458 + if (cfd->flags & CANFD_BRS) 459 + frame->flag |= NCT6694_CANFD_FRAME_FLAG_BRS; 460 + 461 + if (cfd->can_id & CAN_EFF_FLAG) { 462 + txid = cfd->can_id & CAN_EFF_MASK; 463 + frame->flag |= NCT6694_CANFD_FRAME_FLAG_EFF; 464 + } else { 465 + txid = cfd->can_id & CAN_SFF_MASK; 466 + } 467 + frame->flag |= NCT6694_CANFD_FRAME_FLAG_FD; 468 + frame->id = cpu_to_le32(txid); 469 + frame->length = canfd_sanitize_len(cfd->len); 470 + 471 + memcpy(frame->data, cfd->data, frame->length); 472 + } else { 473 + struct can_frame *cf = (struct can_frame *)skb->data; 474 + 475 + if (cf->can_id & CAN_EFF_FLAG) { 476 + txid = cf->can_id & CAN_EFF_MASK; 477 + frame->flag |= NCT6694_CANFD_FRAME_FLAG_EFF; 478 + } else { 479 + txid = cf->can_id & CAN_SFF_MASK; 480 + } 481 + 482 + if (cf->can_id & CAN_RTR_FLAG) 483 + frame->flag |= NCT6694_CANFD_FRAME_FLAG_RTR; 484 + else 485 + memcpy(frame->data, cf->data, cf->len); 486 + 487 + frame->id = cpu_to_le32(txid); 488 + frame->length = cf->len; 489 + } 490 + 491 + err = nct6694_write_msg(priv->nct6694, &cmd_hd, frame); 492 + if (err) { 493 + can_free_echo_skb(ndev, 0, NULL); 494 + stats->tx_dropped++; 495 + stats->tx_errors++; 496 + netif_wake_queue(ndev); 497 + } 498 + } 499 + 500 + static netdev_tx_t nct6694_canfd_start_xmit(struct sk_buff *skb, 501 + struct net_device *ndev) 502 + { 503 + struct nct6694_canfd_priv *priv = netdev_priv(ndev); 504 + 505 + if (can_dev_dropped_skb(ndev, skb)) 506 + return NETDEV_TX_OK; 507 + 508 + netif_stop_queue(ndev); 509 + can_put_echo_skb(skb, ndev, 0, 0); 510 + queue_work(priv->wq, &priv->tx_work); 511 + 512 + return NETDEV_TX_OK; 513 + } 514 + 515 + static int nct6694_canfd_start(struct net_device *ndev) 516 + { 517 + struct nct6694_canfd_priv *priv = netdev_priv(ndev); 518 + const struct can_bittiming *n_bt = &priv->can.bittiming; 519 + const struct can_bittiming *d_bt = &priv->can.fd.data_bittiming; 520 + struct nct6694_canfd_setting *setting __free(kfree) = NULL; 521 + const struct nct6694_cmd_header cmd_hd = { 522 + .mod = NCT6694_CANFD_MOD, 523 + .cmd = NCT6694_CANFD_SETTING, 524 + .sel = ndev->dev_port, 525 + .len = cpu_to_le16(sizeof(*setting)) 526 + }; 527 + u32 en_tdc; 528 + int ret; 529 + 530 + setting = kzalloc(sizeof(*setting), GFP_KERNEL); 531 + if (!setting) 532 + return -ENOMEM; 533 + 534 + if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) 535 + setting->ctrl1 |= cpu_to_le16(NCT6694_CANFD_SETTING_CTRL1_MON); 536 + 537 + if (priv->can.ctrlmode & CAN_CTRLMODE_FD_NON_ISO) 538 + setting->ctrl1 |= cpu_to_le16(NCT6694_CANFD_SETTING_CTRL1_NISO); 539 + 540 + if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) 541 + setting->ctrl1 |= cpu_to_le16(NCT6694_CANFD_SETTING_CTRL1_LBCK); 542 + 543 + /* Disable clock divider */ 544 + setting->ctrl2 = 0; 545 + 546 + setting->nbtp = cpu_to_le32(FIELD_PREP(NCT6694_CANFD_SETTING_NBTP_NSJW, 547 + n_bt->sjw - 1) | 548 + FIELD_PREP(NCT6694_CANFD_SETTING_NBTP_NBRP, 549 + n_bt->brp - 1) | 550 + FIELD_PREP(NCT6694_CANFD_SETTING_NBTP_NTSEG2, 551 + n_bt->phase_seg2 - 1) | 552 + FIELD_PREP(NCT6694_CANFD_SETTING_NBTP_NTSEG1, 553 + n_bt->prop_seg + n_bt->phase_seg1 - 1)); 554 + 555 + if (d_bt->brp <= 2) 556 + en_tdc = NCT6694_CANFD_SETTING_DBTP_TDC; 557 + else 558 + en_tdc = 0; 559 + 560 + setting->dbtp = cpu_to_le32(FIELD_PREP(NCT6694_CANFD_SETTING_DBTP_DSJW, 561 + d_bt->sjw - 1) | 562 + FIELD_PREP(NCT6694_CANFD_SETTING_DBTP_DBRP, 563 + d_bt->brp - 1) | 564 + FIELD_PREP(NCT6694_CANFD_SETTING_DBTP_DTSEG2, 565 + d_bt->phase_seg2 - 1) | 566 + FIELD_PREP(NCT6694_CANFD_SETTING_DBTP_DTSEG1, 567 + d_bt->prop_seg + d_bt->phase_seg1 - 1) | 568 + en_tdc); 569 + 570 + setting->active = NCT6694_CANFD_SETTING_ACTIVE_CTRL1 | 571 + NCT6694_CANFD_SETTING_ACTIVE_CTRL2 | 572 + NCT6694_CANFD_SETTING_ACTIVE_NBTP_DBTP; 573 + 574 + ret = nct6694_write_msg(priv->nct6694, &cmd_hd, setting); 575 + if (ret) 576 + return ret; 577 + 578 + priv->can.state = CAN_STATE_ERROR_ACTIVE; 579 + 580 + return 0; 581 + } 582 + 583 + static void nct6694_canfd_stop(struct net_device *ndev) 584 + { 585 + struct nct6694_canfd_priv *priv = netdev_priv(ndev); 586 + struct nct6694_canfd_setting *setting __free(kfree) = NULL; 587 + const struct nct6694_cmd_header cmd_hd = { 588 + .mod = NCT6694_CANFD_MOD, 589 + .cmd = NCT6694_CANFD_SETTING, 590 + .sel = ndev->dev_port, 591 + .len = cpu_to_le16(sizeof(*setting)) 592 + }; 593 + 594 + /* The NCT6694 cannot be stopped. To ensure safe operation and avoid 595 + * interference, the control mode is set to Listen-Only mode. This 596 + * mode allows the device to monitor bus activity without actively 597 + * participating in communication. 598 + */ 599 + setting = kzalloc(sizeof(*setting), GFP_KERNEL); 600 + if (!setting) 601 + return; 602 + 603 + nct6694_read_msg(priv->nct6694, &cmd_hd, setting); 604 + setting->ctrl1 = cpu_to_le16(NCT6694_CANFD_SETTING_CTRL1_MON); 605 + setting->active = NCT6694_CANFD_SETTING_ACTIVE_CTRL1; 606 + nct6694_write_msg(priv->nct6694, &cmd_hd, setting); 607 + 608 + priv->can.state = CAN_STATE_STOPPED; 609 + } 610 + 611 + static int nct6694_canfd_close(struct net_device *ndev) 612 + { 613 + struct nct6694_canfd_priv *priv = netdev_priv(ndev); 614 + 615 + netif_stop_queue(ndev); 616 + nct6694_canfd_stop(ndev); 617 + destroy_workqueue(priv->wq); 618 + free_irq(ndev->irq, ndev); 619 + can_rx_offload_disable(&priv->offload); 620 + close_candev(ndev); 621 + return 0; 622 + } 623 + 624 + static int nct6694_canfd_set_mode(struct net_device *ndev, enum can_mode mode) 625 + { 626 + int ret; 627 + 628 + switch (mode) { 629 + case CAN_MODE_START: 630 + ret = nct6694_canfd_start(ndev); 631 + if (ret) 632 + return ret; 633 + 634 + netif_wake_queue(ndev); 635 + break; 636 + 637 + default: 638 + return -EOPNOTSUPP; 639 + } 640 + 641 + return ret; 642 + } 643 + 644 + static int nct6694_canfd_open(struct net_device *ndev) 645 + { 646 + struct nct6694_canfd_priv *priv = netdev_priv(ndev); 647 + int ret; 648 + 649 + ret = open_candev(ndev); 650 + if (ret) 651 + return ret; 652 + 653 + can_rx_offload_enable(&priv->offload); 654 + 655 + ret = request_threaded_irq(ndev->irq, NULL, 656 + nct6694_canfd_irq, IRQF_ONESHOT, 657 + "nct6694_canfd", ndev); 658 + if (ret) { 659 + netdev_err(ndev, "Failed to request IRQ\n"); 660 + goto can_rx_offload_disable; 661 + } 662 + 663 + priv->wq = alloc_ordered_workqueue("%s-nct6694_wq", 664 + WQ_FREEZABLE | WQ_MEM_RECLAIM, 665 + ndev->name); 666 + if (!priv->wq) { 667 + ret = -ENOMEM; 668 + goto free_irq; 669 + } 670 + 671 + ret = nct6694_canfd_start(ndev); 672 + if (ret) 673 + goto destroy_wq; 674 + 675 + netif_start_queue(ndev); 676 + 677 + return 0; 678 + 679 + destroy_wq: 680 + destroy_workqueue(priv->wq); 681 + free_irq: 682 + free_irq(ndev->irq, ndev); 683 + can_rx_offload_disable: 684 + can_rx_offload_disable(&priv->offload); 685 + close_candev(ndev); 686 + return ret; 687 + } 688 + 689 + static const struct net_device_ops nct6694_canfd_netdev_ops = { 690 + .ndo_open = nct6694_canfd_open, 691 + .ndo_stop = nct6694_canfd_close, 692 + .ndo_start_xmit = nct6694_canfd_start_xmit, 693 + .ndo_change_mtu = can_change_mtu, 694 + }; 695 + 696 + static const struct ethtool_ops nct6694_canfd_ethtool_ops = { 697 + .get_ts_info = ethtool_op_get_ts_info, 698 + }; 699 + 700 + static int nct6694_canfd_get_clock(struct nct6694_canfd_priv *priv) 701 + { 702 + struct nct6694_canfd_information *info __free(kfree) = NULL; 703 + static const struct nct6694_cmd_header cmd_hd = { 704 + .mod = NCT6694_CANFD_MOD, 705 + .cmd = NCT6694_CANFD_INFORMATION, 706 + .sel = NCT6694_CANFD_INFORMATION_SEL, 707 + .len = cpu_to_le16(sizeof(*info)) 708 + }; 709 + int ret; 710 + 711 + info = kzalloc(sizeof(*info), GFP_KERNEL); 712 + if (!info) 713 + return -ENOMEM; 714 + 715 + ret = nct6694_read_msg(priv->nct6694, &cmd_hd, info); 716 + if (ret) 717 + return ret; 718 + 719 + return le32_to_cpu(info->can_clk); 720 + } 721 + 722 + static int nct6694_canfd_probe(struct platform_device *pdev) 723 + { 724 + struct nct6694 *nct6694 = dev_get_drvdata(pdev->dev.parent); 725 + struct nct6694_canfd_priv *priv; 726 + struct net_device *ndev; 727 + int port, irq, ret, can_clk; 728 + 729 + port = ida_alloc(&nct6694->canfd_ida, GFP_KERNEL); 730 + if (port < 0) 731 + return port; 732 + 733 + irq = irq_create_mapping(nct6694->domain, 734 + NCT6694_IRQ_CAN0 + port); 735 + if (!irq) { 736 + ret = -EINVAL; 737 + goto free_ida; 738 + } 739 + 740 + ndev = alloc_candev(sizeof(struct nct6694_canfd_priv), 1); 741 + if (!ndev) { 742 + ret = -ENOMEM; 743 + goto dispose_irq; 744 + } 745 + 746 + ndev->irq = irq; 747 + ndev->flags |= IFF_ECHO; 748 + ndev->dev_port = port; 749 + ndev->netdev_ops = &nct6694_canfd_netdev_ops; 750 + ndev->ethtool_ops = &nct6694_canfd_ethtool_ops; 751 + 752 + priv = netdev_priv(ndev); 753 + priv->nct6694 = nct6694; 754 + priv->ndev = ndev; 755 + 756 + can_clk = nct6694_canfd_get_clock(priv); 757 + if (can_clk < 0) { 758 + ret = dev_err_probe(&pdev->dev, can_clk, 759 + "Failed to get clock\n"); 760 + goto free_candev; 761 + } 762 + 763 + INIT_WORK(&priv->tx_work, nct6694_canfd_tx_work); 764 + 765 + priv->can.clock.freq = can_clk; 766 + priv->can.bittiming_const = &nct6694_canfd_bittiming_nominal_const; 767 + priv->can.fd.data_bittiming_const = &nct6694_canfd_bittiming_data_const; 768 + priv->can.do_set_mode = nct6694_canfd_set_mode; 769 + priv->can.do_get_berr_counter = nct6694_canfd_get_berr_counter; 770 + priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK | 771 + CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_BERR_REPORTING | 772 + CAN_CTRLMODE_FD_NON_ISO; 773 + 774 + ret = can_set_static_ctrlmode(ndev, CAN_CTRLMODE_FD); 775 + if (ret) 776 + goto free_candev; 777 + 778 + ret = can_rx_offload_add_manual(ndev, &priv->offload, 779 + NCT6694_NAPI_WEIGHT); 780 + if (ret) { 781 + dev_err_probe(&pdev->dev, ret, "Failed to add rx_offload\n"); 782 + goto free_candev; 783 + } 784 + 785 + platform_set_drvdata(pdev, priv); 786 + SET_NETDEV_DEV(priv->ndev, &pdev->dev); 787 + 788 + ret = register_candev(priv->ndev); 789 + if (ret) 790 + goto rx_offload_del; 791 + 792 + return 0; 793 + 794 + rx_offload_del: 795 + can_rx_offload_del(&priv->offload); 796 + free_candev: 797 + free_candev(ndev); 798 + dispose_irq: 799 + irq_dispose_mapping(irq); 800 + free_ida: 801 + ida_free(&nct6694->canfd_ida, port); 802 + return ret; 803 + } 804 + 805 + static void nct6694_canfd_remove(struct platform_device *pdev) 806 + { 807 + struct nct6694_canfd_priv *priv = platform_get_drvdata(pdev); 808 + struct nct6694 *nct6694 = priv->nct6694; 809 + struct net_device *ndev = priv->ndev; 810 + int port = ndev->dev_port; 811 + int irq = ndev->irq; 812 + 813 + unregister_candev(ndev); 814 + can_rx_offload_del(&priv->offload); 815 + free_candev(ndev); 816 + irq_dispose_mapping(irq); 817 + ida_free(&nct6694->canfd_ida, port); 818 + } 819 + 820 + static struct platform_driver nct6694_canfd_driver = { 821 + .driver = { 822 + .name = DEVICE_NAME, 823 + }, 824 + .probe = nct6694_canfd_probe, 825 + .remove = nct6694_canfd_remove, 826 + }; 827 + 828 + module_platform_driver(nct6694_canfd_driver); 829 + 830 + MODULE_DESCRIPTION("USB-CAN FD driver for NCT6694"); 831 + MODULE_AUTHOR("Ming Yu <tmyu0@nuvoton.com>"); 832 + MODULE_LICENSE("GPL");