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