Remigiusz Kołłątaj | 51f3baa | 2017-04-14 20:32:28 +0200 | [diff] [blame] | 1 | /* SocketCAN driver for Microchip CAN BUS Analyzer Tool |
| 2 | * |
| 3 | * Copyright (C) 2017 Mobica Limited |
| 4 | * |
| 5 | * This program is free software; you can redistribute it and/or modify it |
| 6 | * under the terms of the GNU General Public License as published |
| 7 | * by the Free Software Foundation; version 2 of the License. |
| 8 | * |
| 9 | * This program is distributed in the hope that it will be useful, but |
| 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 12 | * General Public License for more details. |
| 13 | * |
| 14 | * You should have received a copy of the GNU General Public License along |
| 15 | * with this program. |
| 16 | * |
| 17 | * This driver is inspired by the 4.6.2 version of net/can/usb/usb_8dev.c |
| 18 | */ |
| 19 | |
| 20 | #include <asm/unaligned.h> |
| 21 | #include <linux/can.h> |
| 22 | #include <linux/can/dev.h> |
| 23 | #include <linux/can/error.h> |
| 24 | #include <linux/can/led.h> |
| 25 | #include <linux/module.h> |
| 26 | #include <linux/netdevice.h> |
| 27 | #include <linux/signal.h> |
| 28 | #include <linux/slab.h> |
| 29 | #include <linux/usb.h> |
| 30 | |
| 31 | /* vendor and product id */ |
| 32 | #define MCBA_MODULE_NAME "mcba_usb" |
| 33 | #define MCBA_VENDOR_ID 0x04d8 |
| 34 | #define MCBA_PRODUCT_ID 0x0a30 |
| 35 | |
| 36 | /* driver constants */ |
| 37 | #define MCBA_MAX_RX_URBS 20 |
| 38 | #define MCBA_MAX_TX_URBS 20 |
| 39 | #define MCBA_CTX_FREE MCBA_MAX_TX_URBS |
| 40 | |
| 41 | /* RX buffer must be bigger than msg size since at the |
| 42 | * beggining USB messages are stacked. |
| 43 | */ |
| 44 | #define MCBA_USB_RX_BUFF_SIZE 64 |
| 45 | #define MCBA_USB_TX_BUFF_SIZE (sizeof(struct mcba_usb_msg)) |
| 46 | |
| 47 | /* MCBA endpoint numbers */ |
| 48 | #define MCBA_USB_EP_IN 1 |
| 49 | #define MCBA_USB_EP_OUT 1 |
| 50 | |
| 51 | /* Microchip command id */ |
| 52 | #define MBCA_CMD_RECEIVE_MESSAGE 0xE3 |
| 53 | #define MBCA_CMD_I_AM_ALIVE_FROM_CAN 0xF5 |
| 54 | #define MBCA_CMD_I_AM_ALIVE_FROM_USB 0xF7 |
| 55 | #define MBCA_CMD_CHANGE_BIT_RATE 0xA1 |
| 56 | #define MBCA_CMD_TRANSMIT_MESSAGE_EV 0xA3 |
| 57 | #define MBCA_CMD_SETUP_TERMINATION_RESISTANCE 0xA8 |
| 58 | #define MBCA_CMD_READ_FW_VERSION 0xA9 |
| 59 | #define MBCA_CMD_NOTHING_TO_SEND 0xFF |
| 60 | #define MBCA_CMD_TRANSMIT_MESSAGE_RSP 0xE2 |
| 61 | |
| 62 | #define MCBA_VER_REQ_USB 1 |
| 63 | #define MCBA_VER_REQ_CAN 2 |
| 64 | |
| 65 | #define MCBA_SIDL_EXID_MASK 0x8 |
| 66 | #define MCBA_DLC_MASK 0xf |
| 67 | #define MCBA_DLC_RTR_MASK 0x40 |
| 68 | |
| 69 | #define MCBA_CAN_STATE_WRN_TH 95 |
| 70 | #define MCBA_CAN_STATE_ERR_PSV_TH 127 |
| 71 | |
| 72 | #define MCBA_TERMINATION_DISABLED CAN_TERMINATION_DISABLED |
| 73 | #define MCBA_TERMINATION_ENABLED 120 |
| 74 | |
| 75 | struct mcba_usb_ctx { |
| 76 | struct mcba_priv *priv; |
| 77 | u32 ndx; |
| 78 | u8 dlc; |
| 79 | bool can; |
| 80 | }; |
| 81 | |
| 82 | /* Structure to hold all of our device specific stuff */ |
| 83 | struct mcba_priv { |
| 84 | struct can_priv can; /* must be the first member */ |
| 85 | struct sk_buff *echo_skb[MCBA_MAX_TX_URBS]; |
| 86 | struct mcba_usb_ctx tx_context[MCBA_MAX_TX_URBS]; |
| 87 | struct usb_device *udev; |
| 88 | struct net_device *netdev; |
| 89 | struct usb_anchor tx_submitted; |
| 90 | struct usb_anchor rx_submitted; |
| 91 | struct can_berr_counter bec; |
| 92 | bool usb_ka_first_pass; |
| 93 | bool can_ka_first_pass; |
| 94 | bool can_speed_check; |
| 95 | atomic_t free_ctx_cnt; |
| 96 | }; |
| 97 | |
| 98 | /* CAN frame */ |
| 99 | struct __packed mcba_usb_msg_can { |
| 100 | u8 cmd_id; |
| 101 | __be16 eid; |
| 102 | __be16 sid; |
| 103 | u8 dlc; |
| 104 | u8 data[8]; |
| 105 | u8 timestamp[4]; |
| 106 | u8 checksum; |
| 107 | }; |
| 108 | |
| 109 | /* command frame */ |
| 110 | struct __packed mcba_usb_msg { |
| 111 | u8 cmd_id; |
| 112 | u8 unused[18]; |
| 113 | }; |
| 114 | |
| 115 | struct __packed mcba_usb_msg_ka_usb { |
| 116 | u8 cmd_id; |
| 117 | u8 termination_state; |
| 118 | u8 soft_ver_major; |
| 119 | u8 soft_ver_minor; |
| 120 | u8 unused[15]; |
| 121 | }; |
| 122 | |
| 123 | struct __packed mcba_usb_msg_ka_can { |
| 124 | u8 cmd_id; |
| 125 | u8 tx_err_cnt; |
| 126 | u8 rx_err_cnt; |
| 127 | u8 rx_buff_ovfl; |
| 128 | u8 tx_bus_off; |
| 129 | __be16 can_bitrate; |
| 130 | __le16 rx_lost; |
| 131 | u8 can_stat; |
| 132 | u8 soft_ver_major; |
| 133 | u8 soft_ver_minor; |
| 134 | u8 debug_mode; |
| 135 | u8 test_complete; |
| 136 | u8 test_result; |
| 137 | u8 unused[4]; |
| 138 | }; |
| 139 | |
| 140 | struct __packed mcba_usb_msg_change_bitrate { |
| 141 | u8 cmd_id; |
| 142 | __be16 bitrate; |
| 143 | u8 unused[16]; |
| 144 | }; |
| 145 | |
| 146 | struct __packed mcba_usb_msg_termination { |
| 147 | u8 cmd_id; |
| 148 | u8 termination; |
| 149 | u8 unused[17]; |
| 150 | }; |
| 151 | |
| 152 | struct __packed mcba_usb_msg_fw_ver { |
| 153 | u8 cmd_id; |
| 154 | u8 pic; |
| 155 | u8 unused[17]; |
| 156 | }; |
| 157 | |
| 158 | static const struct usb_device_id mcba_usb_table[] = { |
| 159 | { USB_DEVICE(MCBA_VENDOR_ID, MCBA_PRODUCT_ID) }, |
| 160 | {} /* Terminating entry */ |
| 161 | }; |
| 162 | |
| 163 | MODULE_DEVICE_TABLE(usb, mcba_usb_table); |
| 164 | |
| 165 | static const u16 mcba_termination[] = { MCBA_TERMINATION_DISABLED, |
| 166 | MCBA_TERMINATION_ENABLED }; |
| 167 | |
| 168 | static const u32 mcba_bitrate[] = { 20000, 33333, 50000, 80000, 83333, |
| 169 | 100000, 125000, 150000, 175000, 200000, |
| 170 | 225000, 250000, 275000, 300000, 500000, |
| 171 | 625000, 800000, 1000000 }; |
| 172 | |
| 173 | static inline void mcba_init_ctx(struct mcba_priv *priv) |
| 174 | { |
| 175 | int i = 0; |
| 176 | |
| 177 | for (i = 0; i < MCBA_MAX_TX_URBS; i++) { |
| 178 | priv->tx_context[i].ndx = MCBA_CTX_FREE; |
| 179 | priv->tx_context[i].priv = priv; |
| 180 | } |
| 181 | |
| 182 | atomic_set(&priv->free_ctx_cnt, ARRAY_SIZE(priv->tx_context)); |
| 183 | } |
| 184 | |
| 185 | static inline struct mcba_usb_ctx *mcba_usb_get_free_ctx(struct mcba_priv *priv, |
| 186 | struct can_frame *cf) |
| 187 | { |
| 188 | int i = 0; |
| 189 | struct mcba_usb_ctx *ctx = NULL; |
| 190 | |
| 191 | for (i = 0; i < MCBA_MAX_TX_URBS; i++) { |
| 192 | if (priv->tx_context[i].ndx == MCBA_CTX_FREE) { |
| 193 | ctx = &priv->tx_context[i]; |
| 194 | ctx->ndx = i; |
| 195 | |
| 196 | if (cf) { |
| 197 | ctx->can = true; |
| 198 | ctx->dlc = cf->can_dlc; |
| 199 | } else { |
| 200 | ctx->can = false; |
| 201 | ctx->dlc = 0; |
| 202 | } |
| 203 | |
| 204 | atomic_dec(&priv->free_ctx_cnt); |
| 205 | break; |
| 206 | } |
| 207 | } |
| 208 | |
| 209 | if (!atomic_read(&priv->free_ctx_cnt)) |
| 210 | /* That was the last free ctx. Slow down tx path */ |
| 211 | netif_stop_queue(priv->netdev); |
| 212 | |
| 213 | return ctx; |
| 214 | } |
| 215 | |
| 216 | /* mcba_usb_free_ctx and mcba_usb_get_free_ctx are executed by different |
| 217 | * threads. The order of execution in below function is important. |
| 218 | */ |
| 219 | static inline void mcba_usb_free_ctx(struct mcba_usb_ctx *ctx) |
| 220 | { |
| 221 | /* Increase number of free ctxs before freeing ctx */ |
| 222 | atomic_inc(&ctx->priv->free_ctx_cnt); |
| 223 | |
| 224 | ctx->ndx = MCBA_CTX_FREE; |
| 225 | |
| 226 | /* Wake up the queue once ctx is marked free */ |
| 227 | netif_wake_queue(ctx->priv->netdev); |
| 228 | } |
| 229 | |
| 230 | static void mcba_usb_write_bulk_callback(struct urb *urb) |
| 231 | { |
| 232 | struct mcba_usb_ctx *ctx = urb->context; |
| 233 | struct net_device *netdev; |
| 234 | |
| 235 | WARN_ON(!ctx); |
| 236 | |
| 237 | netdev = ctx->priv->netdev; |
| 238 | |
| 239 | /* free up our allocated buffer */ |
| 240 | usb_free_coherent(urb->dev, urb->transfer_buffer_length, |
| 241 | urb->transfer_buffer, urb->transfer_dma); |
| 242 | |
| 243 | if (ctx->can) { |
| 244 | if (!netif_device_present(netdev)) |
| 245 | return; |
| 246 | |
| 247 | netdev->stats.tx_packets++; |
| 248 | netdev->stats.tx_bytes += ctx->dlc; |
| 249 | |
| 250 | can_led_event(netdev, CAN_LED_EVENT_TX); |
| 251 | can_get_echo_skb(netdev, ctx->ndx); |
| 252 | } |
| 253 | |
| 254 | if (urb->status) |
| 255 | netdev_info(netdev, "Tx URB aborted (%d)\n", urb->status); |
| 256 | |
| 257 | /* Release the context */ |
| 258 | mcba_usb_free_ctx(ctx); |
| 259 | } |
| 260 | |
| 261 | /* Send data to device */ |
| 262 | static netdev_tx_t mcba_usb_xmit(struct mcba_priv *priv, |
| 263 | struct mcba_usb_msg *usb_msg, |
| 264 | struct mcba_usb_ctx *ctx) |
| 265 | { |
| 266 | struct urb *urb; |
| 267 | u8 *buf; |
| 268 | int err; |
| 269 | |
| 270 | /* create a URB, and a buffer for it, and copy the data to the URB */ |
| 271 | urb = usb_alloc_urb(0, GFP_ATOMIC); |
| 272 | if (!urb) |
| 273 | return -ENOMEM; |
| 274 | |
| 275 | buf = usb_alloc_coherent(priv->udev, MCBA_USB_TX_BUFF_SIZE, GFP_ATOMIC, |
| 276 | &urb->transfer_dma); |
| 277 | if (!buf) { |
| 278 | err = -ENOMEM; |
| 279 | goto nomembuf; |
| 280 | } |
| 281 | |
| 282 | memcpy(buf, usb_msg, MCBA_USB_TX_BUFF_SIZE); |
| 283 | |
| 284 | usb_fill_bulk_urb(urb, priv->udev, |
| 285 | usb_sndbulkpipe(priv->udev, MCBA_USB_EP_OUT), buf, |
| 286 | MCBA_USB_TX_BUFF_SIZE, mcba_usb_write_bulk_callback, |
| 287 | ctx); |
| 288 | |
| 289 | urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
| 290 | usb_anchor_urb(urb, &priv->tx_submitted); |
| 291 | |
| 292 | err = usb_submit_urb(urb, GFP_ATOMIC); |
| 293 | if (unlikely(err)) |
| 294 | goto failed; |
| 295 | |
| 296 | /* Release our reference to this URB, the USB core will eventually free |
| 297 | * it entirely. |
| 298 | */ |
| 299 | usb_free_urb(urb); |
| 300 | |
| 301 | return 0; |
| 302 | |
| 303 | failed: |
| 304 | usb_unanchor_urb(urb); |
| 305 | usb_free_coherent(priv->udev, MCBA_USB_TX_BUFF_SIZE, buf, |
| 306 | urb->transfer_dma); |
| 307 | |
| 308 | if (err == -ENODEV) |
| 309 | netif_device_detach(priv->netdev); |
| 310 | else |
| 311 | netdev_warn(priv->netdev, "failed tx_urb %d\n", err); |
| 312 | |
| 313 | nomembuf: |
| 314 | usb_free_urb(urb); |
| 315 | |
| 316 | return err; |
| 317 | } |
| 318 | |
| 319 | /* Send data to device */ |
| 320 | static netdev_tx_t mcba_usb_start_xmit(struct sk_buff *skb, |
| 321 | struct net_device *netdev) |
| 322 | { |
| 323 | struct mcba_priv *priv = netdev_priv(netdev); |
| 324 | struct can_frame *cf = (struct can_frame *)skb->data; |
| 325 | struct mcba_usb_ctx *ctx = NULL; |
| 326 | struct net_device_stats *stats = &priv->netdev->stats; |
| 327 | u16 sid; |
| 328 | int err; |
| 329 | struct mcba_usb_msg_can usb_msg = { |
| 330 | .cmd_id = MBCA_CMD_TRANSMIT_MESSAGE_EV |
| 331 | }; |
| 332 | |
| 333 | if (can_dropped_invalid_skb(netdev, skb)) |
| 334 | return NETDEV_TX_OK; |
| 335 | |
| 336 | ctx = mcba_usb_get_free_ctx(priv, cf); |
| 337 | if (!ctx) |
| 338 | return NETDEV_TX_BUSY; |
| 339 | |
| 340 | can_put_echo_skb(skb, priv->netdev, ctx->ndx); |
| 341 | |
| 342 | if (cf->can_id & CAN_EFF_FLAG) { |
| 343 | /* SIDH | SIDL | EIDH | EIDL |
| 344 | * 28 - 21 | 20 19 18 x x x 17 16 | 15 - 8 | 7 - 0 |
| 345 | */ |
| 346 | sid = MCBA_SIDL_EXID_MASK; |
| 347 | /* store 28-18 bits */ |
| 348 | sid |= (cf->can_id & 0x1ffc0000) >> 13; |
| 349 | /* store 17-16 bits */ |
| 350 | sid |= (cf->can_id & 0x30000) >> 16; |
| 351 | put_unaligned_be16(sid, &usb_msg.sid); |
| 352 | |
| 353 | /* store 15-0 bits */ |
| 354 | put_unaligned_be16(cf->can_id & 0xffff, &usb_msg.eid); |
| 355 | } else { |
| 356 | /* SIDH | SIDL |
| 357 | * 10 - 3 | 2 1 0 x x x x x |
| 358 | */ |
| 359 | put_unaligned_be16((cf->can_id & CAN_SFF_MASK) << 5, |
| 360 | &usb_msg.sid); |
| 361 | usb_msg.eid = 0; |
| 362 | } |
| 363 | |
| 364 | usb_msg.dlc = cf->can_dlc; |
| 365 | |
| 366 | memcpy(usb_msg.data, cf->data, usb_msg.dlc); |
| 367 | |
| 368 | if (cf->can_id & CAN_RTR_FLAG) |
| 369 | usb_msg.dlc |= MCBA_DLC_RTR_MASK; |
| 370 | |
| 371 | err = mcba_usb_xmit(priv, (struct mcba_usb_msg *)&usb_msg, ctx); |
| 372 | if (err) |
| 373 | goto xmit_failed; |
| 374 | |
| 375 | return NETDEV_TX_OK; |
| 376 | |
| 377 | xmit_failed: |
| 378 | can_free_echo_skb(priv->netdev, ctx->ndx); |
| 379 | mcba_usb_free_ctx(ctx); |
| 380 | dev_kfree_skb(skb); |
| 381 | stats->tx_dropped++; |
| 382 | |
| 383 | return NETDEV_TX_OK; |
| 384 | } |
| 385 | |
| 386 | /* Send cmd to device */ |
| 387 | static void mcba_usb_xmit_cmd(struct mcba_priv *priv, |
| 388 | struct mcba_usb_msg *usb_msg) |
| 389 | { |
| 390 | struct mcba_usb_ctx *ctx = NULL; |
| 391 | int err; |
| 392 | |
| 393 | ctx = mcba_usb_get_free_ctx(priv, NULL); |
| 394 | if (!ctx) { |
| 395 | netdev_err(priv->netdev, |
| 396 | "Lack of free ctx. Sending (%d) cmd aborted", |
| 397 | usb_msg->cmd_id); |
| 398 | |
| 399 | return; |
| 400 | } |
| 401 | |
| 402 | err = mcba_usb_xmit(priv, usb_msg, ctx); |
| 403 | if (err) |
| 404 | netdev_err(priv->netdev, "Failed to send cmd (%d)", |
| 405 | usb_msg->cmd_id); |
| 406 | } |
| 407 | |
| 408 | static void mcba_usb_xmit_change_bitrate(struct mcba_priv *priv, u16 bitrate) |
| 409 | { |
| 410 | struct mcba_usb_msg_change_bitrate usb_msg = { |
| 411 | .cmd_id = MBCA_CMD_CHANGE_BIT_RATE |
| 412 | }; |
| 413 | |
| 414 | put_unaligned_be16(bitrate, &usb_msg.bitrate); |
| 415 | |
| 416 | mcba_usb_xmit_cmd(priv, (struct mcba_usb_msg *)&usb_msg); |
| 417 | } |
| 418 | |
| 419 | static void mcba_usb_xmit_read_fw_ver(struct mcba_priv *priv, u8 pic) |
| 420 | { |
| 421 | struct mcba_usb_msg_fw_ver usb_msg = { |
| 422 | .cmd_id = MBCA_CMD_READ_FW_VERSION, |
| 423 | .pic = pic |
| 424 | }; |
| 425 | |
| 426 | mcba_usb_xmit_cmd(priv, (struct mcba_usb_msg *)&usb_msg); |
| 427 | } |
| 428 | |
| 429 | static void mcba_usb_process_can(struct mcba_priv *priv, |
| 430 | struct mcba_usb_msg_can *msg) |
| 431 | { |
| 432 | struct can_frame *cf; |
| 433 | struct sk_buff *skb; |
| 434 | struct net_device_stats *stats = &priv->netdev->stats; |
| 435 | u16 sid; |
| 436 | |
| 437 | skb = alloc_can_skb(priv->netdev, &cf); |
| 438 | if (!skb) |
| 439 | return; |
| 440 | |
| 441 | sid = get_unaligned_be16(&msg->sid); |
| 442 | |
| 443 | if (sid & MCBA_SIDL_EXID_MASK) { |
| 444 | /* SIDH | SIDL | EIDH | EIDL |
| 445 | * 28 - 21 | 20 19 18 x x x 17 16 | 15 - 8 | 7 - 0 |
| 446 | */ |
| 447 | cf->can_id = CAN_EFF_FLAG; |
| 448 | |
| 449 | /* store 28-18 bits */ |
| 450 | cf->can_id |= (sid & 0xffe0) << 13; |
| 451 | /* store 17-16 bits */ |
| 452 | cf->can_id |= (sid & 3) << 16; |
| 453 | /* store 15-0 bits */ |
| 454 | cf->can_id |= get_unaligned_be16(&msg->eid); |
| 455 | } else { |
| 456 | /* SIDH | SIDL |
| 457 | * 10 - 3 | 2 1 0 x x x x x |
| 458 | */ |
| 459 | cf->can_id = (sid & 0xffe0) >> 5; |
| 460 | } |
| 461 | |
| 462 | if (msg->dlc & MCBA_DLC_RTR_MASK) |
| 463 | cf->can_id |= CAN_RTR_FLAG; |
| 464 | |
| 465 | cf->can_dlc = get_can_dlc(msg->dlc & MCBA_DLC_MASK); |
| 466 | |
| 467 | memcpy(cf->data, msg->data, cf->can_dlc); |
| 468 | |
| 469 | stats->rx_packets++; |
| 470 | stats->rx_bytes += cf->can_dlc; |
| 471 | |
| 472 | can_led_event(priv->netdev, CAN_LED_EVENT_RX); |
| 473 | netif_rx(skb); |
| 474 | } |
| 475 | |
| 476 | static void mcba_usb_process_ka_usb(struct mcba_priv *priv, |
| 477 | struct mcba_usb_msg_ka_usb *msg) |
| 478 | { |
| 479 | if (unlikely(priv->usb_ka_first_pass)) { |
| 480 | netdev_info(priv->netdev, "PIC USB version %hhu.%hhu\n", |
| 481 | msg->soft_ver_major, msg->soft_ver_minor); |
| 482 | |
| 483 | priv->usb_ka_first_pass = false; |
| 484 | } |
| 485 | |
| 486 | if (msg->termination_state) |
| 487 | priv->can.termination = MCBA_TERMINATION_ENABLED; |
| 488 | else |
| 489 | priv->can.termination = MCBA_TERMINATION_DISABLED; |
| 490 | } |
| 491 | |
| 492 | static u32 convert_can2host_bitrate(struct mcba_usb_msg_ka_can *msg) |
| 493 | { |
| 494 | const u32 bitrate = get_unaligned_be16(&msg->can_bitrate); |
| 495 | |
| 496 | if ((bitrate == 33) || (bitrate == 83)) |
| 497 | return bitrate * 1000 + 333; |
| 498 | else |
| 499 | return bitrate * 1000; |
| 500 | } |
| 501 | |
| 502 | static void mcba_usb_process_ka_can(struct mcba_priv *priv, |
| 503 | struct mcba_usb_msg_ka_can *msg) |
| 504 | { |
| 505 | if (unlikely(priv->can_ka_first_pass)) { |
| 506 | netdev_info(priv->netdev, "PIC CAN version %hhu.%hhu\n", |
| 507 | msg->soft_ver_major, msg->soft_ver_minor); |
| 508 | |
| 509 | priv->can_ka_first_pass = false; |
| 510 | } |
| 511 | |
| 512 | if (unlikely(priv->can_speed_check)) { |
| 513 | const u32 bitrate = convert_can2host_bitrate(msg); |
| 514 | |
| 515 | priv->can_speed_check = false; |
| 516 | |
| 517 | if (bitrate != priv->can.bittiming.bitrate) |
| 518 | netdev_err( |
| 519 | priv->netdev, |
| 520 | "Wrong bitrate reported by the device (%u). Expected %u", |
| 521 | bitrate, priv->can.bittiming.bitrate); |
| 522 | } |
| 523 | |
| 524 | priv->bec.txerr = msg->tx_err_cnt; |
| 525 | priv->bec.rxerr = msg->rx_err_cnt; |
| 526 | |
| 527 | if (msg->tx_bus_off) |
| 528 | priv->can.state = CAN_STATE_BUS_OFF; |
| 529 | |
| 530 | else if ((priv->bec.txerr > MCBA_CAN_STATE_ERR_PSV_TH) || |
| 531 | (priv->bec.rxerr > MCBA_CAN_STATE_ERR_PSV_TH)) |
| 532 | priv->can.state = CAN_STATE_ERROR_PASSIVE; |
| 533 | |
| 534 | else if ((priv->bec.txerr > MCBA_CAN_STATE_WRN_TH) || |
| 535 | (priv->bec.rxerr > MCBA_CAN_STATE_WRN_TH)) |
| 536 | priv->can.state = CAN_STATE_ERROR_WARNING; |
| 537 | } |
| 538 | |
| 539 | static void mcba_usb_process_rx(struct mcba_priv *priv, |
| 540 | struct mcba_usb_msg *msg) |
| 541 | { |
| 542 | switch (msg->cmd_id) { |
| 543 | case MBCA_CMD_I_AM_ALIVE_FROM_CAN: |
| 544 | mcba_usb_process_ka_can(priv, |
| 545 | (struct mcba_usb_msg_ka_can *)msg); |
| 546 | break; |
| 547 | |
| 548 | case MBCA_CMD_I_AM_ALIVE_FROM_USB: |
| 549 | mcba_usb_process_ka_usb(priv, |
| 550 | (struct mcba_usb_msg_ka_usb *)msg); |
| 551 | break; |
| 552 | |
| 553 | case MBCA_CMD_RECEIVE_MESSAGE: |
| 554 | mcba_usb_process_can(priv, (struct mcba_usb_msg_can *)msg); |
| 555 | break; |
| 556 | |
| 557 | case MBCA_CMD_NOTHING_TO_SEND: |
| 558 | /* Side effect of communication between PIC_USB and PIC_CAN. |
| 559 | * PIC_CAN is telling us that it has nothing to send |
| 560 | */ |
| 561 | break; |
| 562 | |
| 563 | case MBCA_CMD_TRANSMIT_MESSAGE_RSP: |
| 564 | /* Transmission response from the device containing timestamp */ |
| 565 | break; |
| 566 | |
| 567 | default: |
| 568 | netdev_warn(priv->netdev, "Unsupported msg (0x%hhX)", |
| 569 | msg->cmd_id); |
| 570 | break; |
| 571 | } |
| 572 | } |
| 573 | |
| 574 | /* Callback for reading data from device |
| 575 | * |
| 576 | * Check urb status, call read function and resubmit urb read operation. |
| 577 | */ |
| 578 | static void mcba_usb_read_bulk_callback(struct urb *urb) |
| 579 | { |
| 580 | struct mcba_priv *priv = urb->context; |
| 581 | struct net_device *netdev; |
| 582 | int retval; |
| 583 | int pos = 0; |
| 584 | |
| 585 | netdev = priv->netdev; |
| 586 | |
| 587 | if (!netif_device_present(netdev)) |
| 588 | return; |
| 589 | |
| 590 | switch (urb->status) { |
| 591 | case 0: /* success */ |
| 592 | break; |
| 593 | |
| 594 | case -ENOENT: |
| 595 | case -ESHUTDOWN: |
| 596 | return; |
| 597 | |
| 598 | default: |
| 599 | netdev_info(netdev, "Rx URB aborted (%d)\n", urb->status); |
| 600 | |
| 601 | goto resubmit_urb; |
| 602 | } |
| 603 | |
| 604 | while (pos < urb->actual_length) { |
| 605 | struct mcba_usb_msg *msg; |
| 606 | |
| 607 | if (pos + sizeof(struct mcba_usb_msg) > urb->actual_length) { |
| 608 | netdev_err(priv->netdev, "format error\n"); |
| 609 | break; |
| 610 | } |
| 611 | |
| 612 | msg = (struct mcba_usb_msg *)(urb->transfer_buffer + pos); |
| 613 | mcba_usb_process_rx(priv, msg); |
| 614 | |
| 615 | pos += sizeof(struct mcba_usb_msg); |
| 616 | } |
| 617 | |
| 618 | resubmit_urb: |
| 619 | |
| 620 | usb_fill_bulk_urb(urb, priv->udev, |
| 621 | usb_rcvbulkpipe(priv->udev, MCBA_USB_EP_OUT), |
| 622 | urb->transfer_buffer, MCBA_USB_RX_BUFF_SIZE, |
| 623 | mcba_usb_read_bulk_callback, priv); |
| 624 | |
| 625 | retval = usb_submit_urb(urb, GFP_ATOMIC); |
| 626 | |
| 627 | if (retval == -ENODEV) |
| 628 | netif_device_detach(netdev); |
| 629 | else if (retval) |
| 630 | netdev_err(netdev, "failed resubmitting read bulk urb: %d\n", |
| 631 | retval); |
| 632 | } |
| 633 | |
| 634 | /* Start USB device */ |
| 635 | static int mcba_usb_start(struct mcba_priv *priv) |
| 636 | { |
| 637 | struct net_device *netdev = priv->netdev; |
| 638 | int err, i; |
| 639 | |
| 640 | mcba_init_ctx(priv); |
| 641 | |
| 642 | for (i = 0; i < MCBA_MAX_RX_URBS; i++) { |
| 643 | struct urb *urb = NULL; |
| 644 | u8 *buf; |
| 645 | |
| 646 | /* create a URB, and a buffer for it */ |
| 647 | urb = usb_alloc_urb(0, GFP_KERNEL); |
| 648 | if (!urb) { |
| 649 | err = -ENOMEM; |
| 650 | break; |
| 651 | } |
| 652 | |
| 653 | buf = usb_alloc_coherent(priv->udev, MCBA_USB_RX_BUFF_SIZE, |
| 654 | GFP_KERNEL, &urb->transfer_dma); |
| 655 | if (!buf) { |
| 656 | netdev_err(netdev, "No memory left for USB buffer\n"); |
| 657 | usb_free_urb(urb); |
| 658 | err = -ENOMEM; |
| 659 | break; |
| 660 | } |
| 661 | |
| 662 | usb_fill_bulk_urb(urb, priv->udev, |
| 663 | usb_rcvbulkpipe(priv->udev, MCBA_USB_EP_IN), |
| 664 | buf, MCBA_USB_RX_BUFF_SIZE, |
| 665 | mcba_usb_read_bulk_callback, priv); |
| 666 | urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
| 667 | usb_anchor_urb(urb, &priv->rx_submitted); |
| 668 | |
| 669 | err = usb_submit_urb(urb, GFP_KERNEL); |
| 670 | if (err) { |
| 671 | usb_unanchor_urb(urb); |
| 672 | usb_free_coherent(priv->udev, MCBA_USB_RX_BUFF_SIZE, |
| 673 | buf, urb->transfer_dma); |
| 674 | usb_free_urb(urb); |
| 675 | break; |
| 676 | } |
| 677 | |
| 678 | /* Drop reference, USB core will take care of freeing it */ |
| 679 | usb_free_urb(urb); |
| 680 | } |
| 681 | |
| 682 | /* Did we submit any URBs */ |
| 683 | if (i == 0) { |
| 684 | netdev_warn(netdev, "couldn't setup read URBs\n"); |
| 685 | return err; |
| 686 | } |
| 687 | |
| 688 | /* Warn if we've couldn't transmit all the URBs */ |
| 689 | if (i < MCBA_MAX_RX_URBS) |
| 690 | netdev_warn(netdev, "rx performance may be slow\n"); |
| 691 | |
| 692 | mcba_usb_xmit_read_fw_ver(priv, MCBA_VER_REQ_USB); |
| 693 | mcba_usb_xmit_read_fw_ver(priv, MCBA_VER_REQ_CAN); |
| 694 | |
| 695 | return err; |
| 696 | } |
| 697 | |
| 698 | /* Open USB device */ |
| 699 | static int mcba_usb_open(struct net_device *netdev) |
| 700 | { |
| 701 | struct mcba_priv *priv = netdev_priv(netdev); |
| 702 | int err; |
| 703 | |
| 704 | /* common open */ |
| 705 | err = open_candev(netdev); |
| 706 | if (err) |
| 707 | return err; |
| 708 | |
| 709 | priv->can_speed_check = true; |
| 710 | priv->can.state = CAN_STATE_ERROR_ACTIVE; |
| 711 | |
| 712 | can_led_event(netdev, CAN_LED_EVENT_OPEN); |
| 713 | netif_start_queue(netdev); |
| 714 | |
| 715 | return 0; |
| 716 | } |
| 717 | |
| 718 | static void mcba_urb_unlink(struct mcba_priv *priv) |
| 719 | { |
| 720 | usb_kill_anchored_urbs(&priv->rx_submitted); |
| 721 | usb_kill_anchored_urbs(&priv->tx_submitted); |
| 722 | } |
| 723 | |
| 724 | /* Close USB device */ |
| 725 | static int mcba_usb_close(struct net_device *netdev) |
| 726 | { |
| 727 | struct mcba_priv *priv = netdev_priv(netdev); |
| 728 | |
| 729 | priv->can.state = CAN_STATE_STOPPED; |
| 730 | |
| 731 | netif_stop_queue(netdev); |
| 732 | |
| 733 | /* Stop polling */ |
| 734 | mcba_urb_unlink(priv); |
| 735 | |
| 736 | close_candev(netdev); |
| 737 | can_led_event(netdev, CAN_LED_EVENT_STOP); |
| 738 | |
| 739 | return 0; |
| 740 | } |
| 741 | |
| 742 | /* Set network device mode |
| 743 | * |
| 744 | * Maybe we should leave this function empty, because the device |
| 745 | * set mode variable with open command. |
| 746 | */ |
| 747 | static int mcba_net_set_mode(struct net_device *netdev, enum can_mode mode) |
| 748 | { |
| 749 | return 0; |
| 750 | } |
| 751 | |
| 752 | static int mcba_net_get_berr_counter(const struct net_device *netdev, |
| 753 | struct can_berr_counter *bec) |
| 754 | { |
| 755 | struct mcba_priv *priv = netdev_priv(netdev); |
| 756 | |
| 757 | bec->txerr = priv->bec.txerr; |
| 758 | bec->rxerr = priv->bec.rxerr; |
| 759 | |
| 760 | return 0; |
| 761 | } |
| 762 | |
| 763 | static const struct net_device_ops mcba_netdev_ops = { |
| 764 | .ndo_open = mcba_usb_open, |
| 765 | .ndo_stop = mcba_usb_close, |
| 766 | .ndo_start_xmit = mcba_usb_start_xmit, |
| 767 | }; |
| 768 | |
| 769 | /* Microchip CANBUS has hardcoded bittiming values by default. |
| 770 | * This function sends request via USB to change the speed and align bittiming |
| 771 | * values for presentation purposes only |
| 772 | */ |
| 773 | static int mcba_net_set_bittiming(struct net_device *netdev) |
| 774 | { |
| 775 | struct mcba_priv *priv = netdev_priv(netdev); |
| 776 | const u16 bitrate_kbps = priv->can.bittiming.bitrate / 1000; |
| 777 | |
| 778 | mcba_usb_xmit_change_bitrate(priv, bitrate_kbps); |
| 779 | |
| 780 | return 0; |
| 781 | } |
| 782 | |
| 783 | static int mcba_set_termination(struct net_device *netdev, u16 term) |
| 784 | { |
| 785 | struct mcba_priv *priv = netdev_priv(netdev); |
| 786 | struct mcba_usb_msg_termination usb_msg = { |
| 787 | .cmd_id = MBCA_CMD_SETUP_TERMINATION_RESISTANCE |
| 788 | }; |
| 789 | |
| 790 | if (term == MCBA_TERMINATION_ENABLED) |
| 791 | usb_msg.termination = 1; |
| 792 | else |
| 793 | usb_msg.termination = 0; |
| 794 | |
| 795 | mcba_usb_xmit_cmd(priv, (struct mcba_usb_msg *)&usb_msg); |
| 796 | |
| 797 | return 0; |
| 798 | } |
| 799 | |
| 800 | static int mcba_usb_probe(struct usb_interface *intf, |
| 801 | const struct usb_device_id *id) |
| 802 | { |
| 803 | struct net_device *netdev; |
| 804 | struct mcba_priv *priv; |
| 805 | int err = -ENOMEM; |
| 806 | struct usb_device *usbdev = interface_to_usbdev(intf); |
| 807 | |
| 808 | netdev = alloc_candev(sizeof(struct mcba_priv), MCBA_MAX_TX_URBS); |
| 809 | if (!netdev) { |
| 810 | dev_err(&intf->dev, "Couldn't alloc candev\n"); |
| 811 | return -ENOMEM; |
| 812 | } |
| 813 | |
| 814 | priv = netdev_priv(netdev); |
| 815 | |
| 816 | priv->udev = usbdev; |
| 817 | priv->netdev = netdev; |
| 818 | priv->usb_ka_first_pass = true; |
| 819 | priv->can_ka_first_pass = true; |
| 820 | priv->can_speed_check = false; |
| 821 | |
| 822 | init_usb_anchor(&priv->rx_submitted); |
| 823 | init_usb_anchor(&priv->tx_submitted); |
| 824 | |
| 825 | usb_set_intfdata(intf, priv); |
| 826 | |
| 827 | /* Init CAN device */ |
| 828 | priv->can.state = CAN_STATE_STOPPED; |
| 829 | priv->can.termination_const = mcba_termination; |
| 830 | priv->can.termination_const_cnt = ARRAY_SIZE(mcba_termination); |
| 831 | priv->can.bitrate_const = mcba_bitrate; |
| 832 | priv->can.bitrate_const_cnt = ARRAY_SIZE(mcba_bitrate); |
| 833 | |
| 834 | priv->can.do_set_termination = mcba_set_termination; |
| 835 | priv->can.do_set_mode = mcba_net_set_mode; |
| 836 | priv->can.do_get_berr_counter = mcba_net_get_berr_counter; |
| 837 | priv->can.do_set_bittiming = mcba_net_set_bittiming; |
| 838 | |
| 839 | netdev->netdev_ops = &mcba_netdev_ops; |
| 840 | |
| 841 | netdev->flags |= IFF_ECHO; /* we support local echo */ |
| 842 | |
| 843 | SET_NETDEV_DEV(netdev, &intf->dev); |
| 844 | |
| 845 | err = register_candev(netdev); |
| 846 | if (err) { |
| 847 | netdev_err(netdev, "couldn't register CAN device: %d\n", err); |
| 848 | |
| 849 | goto cleanup_free_candev; |
| 850 | } |
| 851 | |
| 852 | devm_can_led_init(netdev); |
| 853 | |
| 854 | /* Start USB dev only if we have successfully registered CAN device */ |
| 855 | err = mcba_usb_start(priv); |
| 856 | if (err) { |
| 857 | if (err == -ENODEV) |
| 858 | netif_device_detach(priv->netdev); |
| 859 | |
| 860 | netdev_warn(netdev, "couldn't start device: %d\n", err); |
| 861 | |
| 862 | goto cleanup_unregister_candev; |
| 863 | } |
| 864 | |
| 865 | dev_info(&intf->dev, "Microchip CAN BUS analizer connected\n"); |
| 866 | |
| 867 | return 0; |
| 868 | |
| 869 | cleanup_unregister_candev: |
| 870 | unregister_candev(priv->netdev); |
| 871 | |
| 872 | cleanup_free_candev: |
| 873 | free_candev(netdev); |
| 874 | |
| 875 | return err; |
| 876 | } |
| 877 | |
| 878 | /* Called by the usb core when driver is unloaded or device is removed */ |
| 879 | static void mcba_usb_disconnect(struct usb_interface *intf) |
| 880 | { |
| 881 | struct mcba_priv *priv = usb_get_intfdata(intf); |
| 882 | |
| 883 | usb_set_intfdata(intf, NULL); |
| 884 | |
| 885 | netdev_info(priv->netdev, "device disconnected\n"); |
| 886 | |
| 887 | unregister_candev(priv->netdev); |
| 888 | free_candev(priv->netdev); |
| 889 | |
| 890 | mcba_urb_unlink(priv); |
| 891 | } |
| 892 | |
| 893 | static struct usb_driver mcba_usb_driver = { |
| 894 | .name = MCBA_MODULE_NAME, |
| 895 | .probe = mcba_usb_probe, |
| 896 | .disconnect = mcba_usb_disconnect, |
| 897 | .id_table = mcba_usb_table, |
| 898 | }; |
| 899 | |
| 900 | module_usb_driver(mcba_usb_driver); |
| 901 | |
| 902 | MODULE_AUTHOR("Remigiusz Kołłątaj <remigiusz.kollataj@mobica.com>"); |
| 903 | MODULE_DESCRIPTION("SocketCAN driver for Microchip CAN BUS Analyzer Tool"); |
| 904 | MODULE_LICENSE("GPL v2"); |