diff options
| -rw-r--r-- | drivers/net/can/Makefile | 3 | ||||
| -rw-r--r-- | drivers/net/can/cc770/cc770.c | 2 | ||||
| -rw-r--r-- | drivers/net/can/dev.c | 78 | ||||
| -rw-r--r-- | drivers/net/can/flexcan.c | 101 | ||||
| -rw-r--r-- | drivers/net/can/mscan/mscan.c | 48 | ||||
| -rw-r--r-- | drivers/net/can/sja1000/sja1000.c | 51 | ||||
| -rw-r--r-- | drivers/net/can/slcan.c | 7 | ||||
| -rw-r--r-- | drivers/net/can/vcan.c | 5 | ||||
| -rw-r--r-- | include/linux/can/dev.h | 3 | ||||
| -rw-r--r-- | include/uapi/linux/can/error.h | 1 | ||||
| -rw-r--r-- | net/can/af_can.c | 7 | ||||
| -rw-r--r-- | net/can/bcm.c | 16 | ||||
| -rw-r--r-- | net/can/gw.c | 2 | ||||
| -rw-r--r-- | net/can/raw.c | 4 |
14 files changed, 154 insertions, 174 deletions
diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile index fc9304143f44..c533c62b0f5e 100644 --- a/drivers/net/can/Makefile +++ b/drivers/net/can/Makefile | |||
| @@ -29,4 +29,5 @@ obj-$(CONFIG_CAN_GRCAN) += grcan.o | |||
| 29 | obj-$(CONFIG_CAN_RCAR) += rcar_can.o | 29 | obj-$(CONFIG_CAN_RCAR) += rcar_can.o |
| 30 | obj-$(CONFIG_CAN_XILINXCAN) += xilinx_can.o | 30 | obj-$(CONFIG_CAN_XILINXCAN) += xilinx_can.o |
| 31 | 31 | ||
| 32 | subdir-ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG | 32 | subdir-ccflags-y += -D__CHECK_ENDIAN__ |
| 33 | subdir-ccflags-$(CONFIG_CAN_DEBUG_DEVICES) += -DDEBUG | ||
diff --git a/drivers/net/can/cc770/cc770.c b/drivers/net/can/cc770/cc770.c index d8379278d648..c486fe510f37 100644 --- a/drivers/net/can/cc770/cc770.c +++ b/drivers/net/can/cc770/cc770.c | |||
| @@ -60,7 +60,7 @@ MODULE_DESCRIPTION(KBUILD_MODNAME "CAN netdevice driver"); | |||
| 60 | * | 60 | * |
| 61 | * The message objects 1..14 can be used for TX and RX while the message | 61 | * The message objects 1..14 can be used for TX and RX while the message |
| 62 | * objects 15 is optimized for RX. It has a shadow register for reliable | 62 | * objects 15 is optimized for RX. It has a shadow register for reliable |
| 63 | * data receiption under heavy bus load. Therefore it makes sense to use | 63 | * data reception under heavy bus load. Therefore it makes sense to use |
| 64 | * this message object for the needed use case. The frame type (EFF/SFF) | 64 | * this message object for the needed use case. The frame type (EFF/SFF) |
| 65 | * for the message object 15 can be defined via kernel module parameter | 65 | * for the message object 15 can be defined via kernel module parameter |
| 66 | * "msgobj15_eff". If not equal 0, it will receive 29-bit EFF frames, | 66 | * "msgobj15_eff". If not equal 0, it will receive 29-bit EFF frames, |
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index 2cfe5012e4e5..3ec8f6f25e5f 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c | |||
| @@ -273,6 +273,84 @@ static int can_get_bittiming(struct net_device *dev, struct can_bittiming *bt, | |||
| 273 | return err; | 273 | return err; |
| 274 | } | 274 | } |
| 275 | 275 | ||
| 276 | static void can_update_state_error_stats(struct net_device *dev, | ||
| 277 | enum can_state new_state) | ||
| 278 | { | ||
| 279 | struct can_priv *priv = netdev_priv(dev); | ||
| 280 | |||
| 281 | if (new_state <= priv->state) | ||
| 282 | return; | ||
| 283 | |||
| 284 | switch (new_state) { | ||
| 285 | case CAN_STATE_ERROR_WARNING: | ||
| 286 | priv->can_stats.error_warning++; | ||
| 287 | break; | ||
| 288 | case CAN_STATE_ERROR_PASSIVE: | ||
| 289 | priv->can_stats.error_passive++; | ||
| 290 | break; | ||
| 291 | case CAN_STATE_BUS_OFF: | ||
| 292 | default: | ||
| 293 | break; | ||
| 294 | }; | ||
| 295 | } | ||
| 296 | |||
| 297 | static int can_tx_state_to_frame(struct net_device *dev, enum can_state state) | ||
| 298 | { | ||
| 299 | switch (state) { | ||
| 300 | case CAN_STATE_ERROR_ACTIVE: | ||
| 301 | return CAN_ERR_CRTL_ACTIVE; | ||
| 302 | case CAN_STATE_ERROR_WARNING: | ||
| 303 | return CAN_ERR_CRTL_TX_WARNING; | ||
| 304 | case CAN_STATE_ERROR_PASSIVE: | ||
| 305 | return CAN_ERR_CRTL_TX_PASSIVE; | ||
| 306 | default: | ||
| 307 | return 0; | ||
| 308 | } | ||
| 309 | } | ||
| 310 | |||
| 311 | static int can_rx_state_to_frame(struct net_device *dev, enum can_state state) | ||
| 312 | { | ||
| 313 | switch (state) { | ||
| 314 | case CAN_STATE_ERROR_ACTIVE: | ||
| 315 | return CAN_ERR_CRTL_ACTIVE; | ||
| 316 | case CAN_STATE_ERROR_WARNING: | ||
| 317 | return CAN_ERR_CRTL_RX_WARNING; | ||
| 318 | case CAN_STATE_ERROR_PASSIVE: | ||
| 319 | return CAN_ERR_CRTL_RX_PASSIVE; | ||
| 320 | default: | ||
| 321 | return 0; | ||
| 322 | } | ||
| 323 | } | ||
| 324 | |||
| 325 | void can_change_state(struct net_device *dev, struct can_frame *cf, | ||
| 326 | enum can_state tx_state, enum can_state rx_state) | ||
| 327 | { | ||
| 328 | struct can_priv *priv = netdev_priv(dev); | ||
| 329 | enum can_state new_state = max(tx_state, rx_state); | ||
| 330 | |||
| 331 | if (unlikely(new_state == priv->state)) { | ||
| 332 | netdev_warn(dev, "%s: oops, state did not change", __func__); | ||
| 333 | return; | ||
| 334 | } | ||
| 335 | |||
| 336 | netdev_dbg(dev, "New error state: %d\n", new_state); | ||
| 337 | |||
| 338 | can_update_state_error_stats(dev, new_state); | ||
| 339 | priv->state = new_state; | ||
| 340 | |||
| 341 | if (unlikely(new_state == CAN_STATE_BUS_OFF)) { | ||
| 342 | cf->can_id |= CAN_ERR_BUSOFF; | ||
| 343 | return; | ||
| 344 | } | ||
| 345 | |||
| 346 | cf->can_id |= CAN_ERR_CRTL; | ||
| 347 | cf->data[1] |= tx_state >= rx_state ? | ||
| 348 | can_tx_state_to_frame(dev, tx_state) : 0; | ||
| 349 | cf->data[1] |= tx_state <= rx_state ? | ||
| 350 | can_rx_state_to_frame(dev, rx_state) : 0; | ||
| 351 | } | ||
| 352 | EXPORT_SYMBOL_GPL(can_change_state); | ||
| 353 | |||
| 276 | /* | 354 | /* |
| 277 | * Local echo of CAN messages | 355 | * Local echo of CAN messages |
| 278 | * | 356 | * |
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 60f86bd0434a..dde05486bc99 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c | |||
| @@ -577,98 +577,30 @@ static int flexcan_poll_bus_err(struct net_device *dev, u32 reg_esr) | |||
| 577 | return 1; | 577 | return 1; |
| 578 | } | 578 | } |
| 579 | 579 | ||
| 580 | static void do_state(struct net_device *dev, | ||
| 581 | struct can_frame *cf, enum can_state new_state) | ||
| 582 | { | ||
| 583 | struct flexcan_priv *priv = netdev_priv(dev); | ||
| 584 | struct can_berr_counter bec; | ||
| 585 | |||
| 586 | __flexcan_get_berr_counter(dev, &bec); | ||
| 587 | |||
| 588 | switch (priv->can.state) { | ||
| 589 | case CAN_STATE_ERROR_ACTIVE: | ||
| 590 | /* | ||
| 591 | * from: ERROR_ACTIVE | ||
| 592 | * to : ERROR_WARNING, ERROR_PASSIVE, BUS_OFF | ||
| 593 | * => : there was a warning int | ||
| 594 | */ | ||
| 595 | if (new_state >= CAN_STATE_ERROR_WARNING && | ||
| 596 | new_state <= CAN_STATE_BUS_OFF) { | ||
| 597 | netdev_dbg(dev, "Error Warning IRQ\n"); | ||
| 598 | priv->can.can_stats.error_warning++; | ||
| 599 | |||
| 600 | cf->can_id |= CAN_ERR_CRTL; | ||
| 601 | cf->data[1] = (bec.txerr > bec.rxerr) ? | ||
| 602 | CAN_ERR_CRTL_TX_WARNING : | ||
| 603 | CAN_ERR_CRTL_RX_WARNING; | ||
| 604 | } | ||
| 605 | case CAN_STATE_ERROR_WARNING: /* fallthrough */ | ||
| 606 | /* | ||
| 607 | * from: ERROR_ACTIVE, ERROR_WARNING | ||
| 608 | * to : ERROR_PASSIVE, BUS_OFF | ||
| 609 | * => : error passive int | ||
| 610 | */ | ||
| 611 | if (new_state >= CAN_STATE_ERROR_PASSIVE && | ||
| 612 | new_state <= CAN_STATE_BUS_OFF) { | ||
| 613 | netdev_dbg(dev, "Error Passive IRQ\n"); | ||
| 614 | priv->can.can_stats.error_passive++; | ||
| 615 | |||
| 616 | cf->can_id |= CAN_ERR_CRTL; | ||
| 617 | cf->data[1] = (bec.txerr > bec.rxerr) ? | ||
| 618 | CAN_ERR_CRTL_TX_PASSIVE : | ||
| 619 | CAN_ERR_CRTL_RX_PASSIVE; | ||
| 620 | } | ||
| 621 | break; | ||
| 622 | case CAN_STATE_BUS_OFF: | ||
| 623 | netdev_err(dev, "BUG! " | ||
| 624 | "hardware recovered automatically from BUS_OFF\n"); | ||
| 625 | break; | ||
| 626 | default: | ||
| 627 | break; | ||
| 628 | } | ||
| 629 | |||
| 630 | /* process state changes depending on the new state */ | ||
| 631 | switch (new_state) { | ||
| 632 | case CAN_STATE_ERROR_WARNING: | ||
| 633 | netdev_dbg(dev, "Error Warning\n"); | ||
| 634 | cf->can_id |= CAN_ERR_CRTL; | ||
| 635 | cf->data[1] = (bec.txerr > bec.rxerr) ? | ||
| 636 | CAN_ERR_CRTL_TX_WARNING : | ||
| 637 | CAN_ERR_CRTL_RX_WARNING; | ||
| 638 | break; | ||
| 639 | case CAN_STATE_ERROR_ACTIVE: | ||
| 640 | netdev_dbg(dev, "Error Active\n"); | ||
| 641 | cf->can_id |= CAN_ERR_PROT; | ||
| 642 | cf->data[2] = CAN_ERR_PROT_ACTIVE; | ||
| 643 | break; | ||
| 644 | case CAN_STATE_BUS_OFF: | ||
| 645 | cf->can_id |= CAN_ERR_BUSOFF; | ||
| 646 | can_bus_off(dev); | ||
| 647 | break; | ||
| 648 | default: | ||
| 649 | break; | ||
| 650 | } | ||
| 651 | } | ||
| 652 | |||
| 653 | static int flexcan_poll_state(struct net_device *dev, u32 reg_esr) | 580 | static int flexcan_poll_state(struct net_device *dev, u32 reg_esr) |
| 654 | { | 581 | { |
| 655 | struct flexcan_priv *priv = netdev_priv(dev); | 582 | struct flexcan_priv *priv = netdev_priv(dev); |
| 656 | struct sk_buff *skb; | 583 | struct sk_buff *skb; |
| 657 | struct can_frame *cf; | 584 | struct can_frame *cf; |
| 658 | enum can_state new_state; | 585 | enum can_state new_state = 0, rx_state = 0, tx_state = 0; |
| 659 | int flt; | 586 | int flt; |
| 587 | struct can_berr_counter bec; | ||
| 660 | 588 | ||
| 661 | flt = reg_esr & FLEXCAN_ESR_FLT_CONF_MASK; | 589 | flt = reg_esr & FLEXCAN_ESR_FLT_CONF_MASK; |
| 662 | if (likely(flt == FLEXCAN_ESR_FLT_CONF_ACTIVE)) { | 590 | if (likely(flt == FLEXCAN_ESR_FLT_CONF_ACTIVE)) { |
| 663 | if (likely(!(reg_esr & (FLEXCAN_ESR_TX_WRN | | 591 | tx_state = unlikely(reg_esr & FLEXCAN_ESR_TX_WRN) ? |
| 664 | FLEXCAN_ESR_RX_WRN)))) | 592 | CAN_STATE_ERROR_WARNING : CAN_STATE_ERROR_ACTIVE; |
| 665 | new_state = CAN_STATE_ERROR_ACTIVE; | 593 | rx_state = unlikely(reg_esr & FLEXCAN_ESR_RX_WRN) ? |
| 666 | else | 594 | CAN_STATE_ERROR_WARNING : CAN_STATE_ERROR_ACTIVE; |
| 667 | new_state = CAN_STATE_ERROR_WARNING; | 595 | new_state = max(tx_state, rx_state); |
| 668 | } else if (unlikely(flt == FLEXCAN_ESR_FLT_CONF_PASSIVE)) | 596 | } else if (unlikely(flt == FLEXCAN_ESR_FLT_CONF_PASSIVE)) { |
| 597 | __flexcan_get_berr_counter(dev, &bec); | ||
| 669 | new_state = CAN_STATE_ERROR_PASSIVE; | 598 | new_state = CAN_STATE_ERROR_PASSIVE; |
| 670 | else | 599 | rx_state = bec.rxerr >= bec.txerr ? new_state : 0; |
| 600 | tx_state = bec.rxerr <= bec.txerr ? new_state : 0; | ||
| 601 | } else { | ||
| 671 | new_state = CAN_STATE_BUS_OFF; | 602 | new_state = CAN_STATE_BUS_OFF; |
| 603 | } | ||
| 672 | 604 | ||
| 673 | /* state hasn't changed */ | 605 | /* state hasn't changed */ |
| 674 | if (likely(new_state == priv->can.state)) | 606 | if (likely(new_state == priv->can.state)) |
| @@ -678,8 +610,11 @@ static int flexcan_poll_state(struct net_device *dev, u32 reg_esr) | |||
| 678 | if (unlikely(!skb)) | 610 | if (unlikely(!skb)) |
| 679 | return 0; | 611 | return 0; |
| 680 | 612 | ||
| 681 | do_state(dev, cf, new_state); | 613 | can_change_state(dev, cf, tx_state, rx_state); |
| 682 | priv->can.state = new_state; | 614 | |
| 615 | if (unlikely(new_state == CAN_STATE_BUS_OFF)) | ||
| 616 | can_bus_off(dev); | ||
| 617 | |||
| 683 | netif_receive_skb(skb); | 618 | netif_receive_skb(skb); |
| 684 | 619 | ||
| 685 | dev->stats.rx_packets++; | 620 | dev->stats.rx_packets++; |
diff --git a/drivers/net/can/mscan/mscan.c b/drivers/net/can/mscan/mscan.c index e0c9be5e2ab7..e36b7400d5cc 100644 --- a/drivers/net/can/mscan/mscan.c +++ b/drivers/net/can/mscan/mscan.c | |||
| @@ -289,18 +289,15 @@ static netdev_tx_t mscan_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 289 | return NETDEV_TX_OK; | 289 | return NETDEV_TX_OK; |
| 290 | } | 290 | } |
| 291 | 291 | ||
| 292 | /* This function returns the old state to see where we came from */ | 292 | static enum can_state get_new_state(struct net_device *dev, u8 canrflg) |
| 293 | static enum can_state check_set_state(struct net_device *dev, u8 canrflg) | ||
| 294 | { | 293 | { |
| 295 | struct mscan_priv *priv = netdev_priv(dev); | 294 | struct mscan_priv *priv = netdev_priv(dev); |
| 296 | enum can_state state, old_state = priv->can.state; | ||
| 297 | 295 | ||
| 298 | if (canrflg & MSCAN_CSCIF && old_state <= CAN_STATE_BUS_OFF) { | 296 | if (unlikely(canrflg & MSCAN_CSCIF)) |
| 299 | state = state_map[max(MSCAN_STATE_RX(canrflg), | 297 | return state_map[max(MSCAN_STATE_RX(canrflg), |
| 300 | MSCAN_STATE_TX(canrflg))]; | 298 | MSCAN_STATE_TX(canrflg))]; |
| 301 | priv->can.state = state; | 299 | |
| 302 | } | 300 | return priv->can.state; |
| 303 | return old_state; | ||
| 304 | } | 301 | } |
| 305 | 302 | ||
| 306 | static void mscan_get_rx_frame(struct net_device *dev, struct can_frame *frame) | 303 | static void mscan_get_rx_frame(struct net_device *dev, struct can_frame *frame) |
| @@ -349,7 +346,7 @@ static void mscan_get_err_frame(struct net_device *dev, struct can_frame *frame, | |||
| 349 | struct mscan_priv *priv = netdev_priv(dev); | 346 | struct mscan_priv *priv = netdev_priv(dev); |
| 350 | struct mscan_regs __iomem *regs = priv->reg_base; | 347 | struct mscan_regs __iomem *regs = priv->reg_base; |
| 351 | struct net_device_stats *stats = &dev->stats; | 348 | struct net_device_stats *stats = &dev->stats; |
| 352 | enum can_state old_state; | 349 | enum can_state new_state; |
| 353 | 350 | ||
| 354 | netdev_dbg(dev, "error interrupt (canrflg=%#x)\n", canrflg); | 351 | netdev_dbg(dev, "error interrupt (canrflg=%#x)\n", canrflg); |
| 355 | frame->can_id = CAN_ERR_FLAG; | 352 | frame->can_id = CAN_ERR_FLAG; |
| @@ -363,27 +360,13 @@ static void mscan_get_err_frame(struct net_device *dev, struct can_frame *frame, | |||
| 363 | frame->data[1] = 0; | 360 | frame->data[1] = 0; |
| 364 | } | 361 | } |
| 365 | 362 | ||
| 366 | old_state = check_set_state(dev, canrflg); | 363 | new_state = get_new_state(dev, canrflg); |
| 367 | /* State changed */ | 364 | if (new_state != priv->can.state) { |
| 368 | if (old_state != priv->can.state) { | 365 | can_change_state(dev, frame, |
| 369 | switch (priv->can.state) { | 366 | state_map[MSCAN_STATE_TX(canrflg)], |
| 370 | case CAN_STATE_ERROR_WARNING: | 367 | state_map[MSCAN_STATE_RX(canrflg)]); |
| 371 | frame->can_id |= CAN_ERR_CRTL; | 368 | |
| 372 | priv->can.can_stats.error_warning++; | 369 | if (priv->can.state == CAN_STATE_BUS_OFF) { |
| 373 | if ((priv->shadow_statflg & MSCAN_RSTAT_MSK) < | ||
| 374 | (canrflg & MSCAN_RSTAT_MSK)) | ||
| 375 | frame->data[1] |= CAN_ERR_CRTL_RX_WARNING; | ||
| 376 | if ((priv->shadow_statflg & MSCAN_TSTAT_MSK) < | ||
| 377 | (canrflg & MSCAN_TSTAT_MSK)) | ||
| 378 | frame->data[1] |= CAN_ERR_CRTL_TX_WARNING; | ||
| 379 | break; | ||
| 380 | case CAN_STATE_ERROR_PASSIVE: | ||
| 381 | frame->can_id |= CAN_ERR_CRTL; | ||
| 382 | priv->can.can_stats.error_passive++; | ||
| 383 | frame->data[1] |= CAN_ERR_CRTL_RX_PASSIVE; | ||
| 384 | break; | ||
| 385 | case CAN_STATE_BUS_OFF: | ||
| 386 | frame->can_id |= CAN_ERR_BUSOFF; | ||
| 387 | /* | 370 | /* |
| 388 | * The MSCAN on the MPC5200 does recover from bus-off | 371 | * The MSCAN on the MPC5200 does recover from bus-off |
| 389 | * automatically. To avoid that we stop the chip doing | 372 | * automatically. To avoid that we stop the chip doing |
| @@ -396,9 +379,6 @@ static void mscan_get_err_frame(struct net_device *dev, struct can_frame *frame, | |||
| 396 | MSCAN_SLPRQ | MSCAN_INITRQ); | 379 | MSCAN_SLPRQ | MSCAN_INITRQ); |
| 397 | } | 380 | } |
| 398 | can_bus_off(dev); | 381 | can_bus_off(dev); |
| 399 | break; | ||
| 400 | default: | ||
| 401 | break; | ||
| 402 | } | 382 | } |
| 403 | } | 383 | } |
| 404 | priv->shadow_statflg = canrflg & MSCAN_STAT_MSK; | 384 | priv->shadow_statflg = canrflg & MSCAN_STAT_MSK; |
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c index b27ac6074afb..32bd7f451aa4 100644 --- a/drivers/net/can/sja1000/sja1000.c +++ b/drivers/net/can/sja1000/sja1000.c | |||
| @@ -392,12 +392,20 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status) | |||
| 392 | struct can_frame *cf; | 392 | struct can_frame *cf; |
| 393 | struct sk_buff *skb; | 393 | struct sk_buff *skb; |
| 394 | enum can_state state = priv->can.state; | 394 | enum can_state state = priv->can.state; |
| 395 | enum can_state rx_state, tx_state; | ||
| 396 | unsigned int rxerr, txerr; | ||
| 395 | uint8_t ecc, alc; | 397 | uint8_t ecc, alc; |
| 396 | 398 | ||
| 397 | skb = alloc_can_err_skb(dev, &cf); | 399 | skb = alloc_can_err_skb(dev, &cf); |
| 398 | if (skb == NULL) | 400 | if (skb == NULL) |
| 399 | return -ENOMEM; | 401 | return -ENOMEM; |
| 400 | 402 | ||
| 403 | txerr = priv->read_reg(priv, SJA1000_TXERR); | ||
| 404 | rxerr = priv->read_reg(priv, SJA1000_RXERR); | ||
| 405 | |||
| 406 | cf->data[6] = txerr; | ||
| 407 | cf->data[7] = rxerr; | ||
| 408 | |||
| 401 | if (isrc & IRQ_DOI) { | 409 | if (isrc & IRQ_DOI) { |
| 402 | /* data overrun interrupt */ | 410 | /* data overrun interrupt */ |
| 403 | netdev_dbg(dev, "data overrun interrupt\n"); | 411 | netdev_dbg(dev, "data overrun interrupt\n"); |
| @@ -412,13 +420,11 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status) | |||
| 412 | /* error warning interrupt */ | 420 | /* error warning interrupt */ |
| 413 | netdev_dbg(dev, "error warning interrupt\n"); | 421 | netdev_dbg(dev, "error warning interrupt\n"); |
| 414 | 422 | ||
| 415 | if (status & SR_BS) { | 423 | if (status & SR_BS) |
| 416 | state = CAN_STATE_BUS_OFF; | 424 | state = CAN_STATE_BUS_OFF; |
| 417 | cf->can_id |= CAN_ERR_BUSOFF; | 425 | else if (status & SR_ES) |
| 418 | can_bus_off(dev); | ||
| 419 | } else if (status & SR_ES) { | ||
| 420 | state = CAN_STATE_ERROR_WARNING; | 426 | state = CAN_STATE_ERROR_WARNING; |
| 421 | } else | 427 | else |
| 422 | state = CAN_STATE_ERROR_ACTIVE; | 428 | state = CAN_STATE_ERROR_ACTIVE; |
| 423 | } | 429 | } |
| 424 | if (isrc & IRQ_BEI) { | 430 | if (isrc & IRQ_BEI) { |
| @@ -452,10 +458,11 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status) | |||
| 452 | if (isrc & IRQ_EPI) { | 458 | if (isrc & IRQ_EPI) { |
| 453 | /* error passive interrupt */ | 459 | /* error passive interrupt */ |
| 454 | netdev_dbg(dev, "error passive interrupt\n"); | 460 | netdev_dbg(dev, "error passive interrupt\n"); |
| 455 | if (status & SR_ES) | 461 | |
| 456 | state = CAN_STATE_ERROR_PASSIVE; | 462 | if (state == CAN_STATE_ERROR_PASSIVE) |
| 463 | state = CAN_STATE_ERROR_WARNING; | ||
| 457 | else | 464 | else |
| 458 | state = CAN_STATE_ERROR_ACTIVE; | 465 | state = CAN_STATE_ERROR_PASSIVE; |
| 459 | } | 466 | } |
| 460 | if (isrc & IRQ_ALI) { | 467 | if (isrc & IRQ_ALI) { |
| 461 | /* arbitration lost interrupt */ | 468 | /* arbitration lost interrupt */ |
| @@ -467,27 +474,15 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status) | |||
| 467 | cf->data[0] = alc & 0x1f; | 474 | cf->data[0] = alc & 0x1f; |
| 468 | } | 475 | } |
| 469 | 476 | ||
| 470 | if (state != priv->can.state && (state == CAN_STATE_ERROR_WARNING || | 477 | if (state != priv->can.state) { |
| 471 | state == CAN_STATE_ERROR_PASSIVE)) { | 478 | tx_state = txerr >= rxerr ? state : 0; |
| 472 | uint8_t rxerr = priv->read_reg(priv, SJA1000_RXERR); | 479 | rx_state = txerr <= rxerr ? state : 0; |
| 473 | uint8_t txerr = priv->read_reg(priv, SJA1000_TXERR); | ||
| 474 | cf->can_id |= CAN_ERR_CRTL; | ||
| 475 | if (state == CAN_STATE_ERROR_WARNING) { | ||
| 476 | priv->can.can_stats.error_warning++; | ||
| 477 | cf->data[1] = (txerr > rxerr) ? | ||
| 478 | CAN_ERR_CRTL_TX_WARNING : | ||
| 479 | CAN_ERR_CRTL_RX_WARNING; | ||
| 480 | } else { | ||
| 481 | priv->can.can_stats.error_passive++; | ||
| 482 | cf->data[1] = (txerr > rxerr) ? | ||
| 483 | CAN_ERR_CRTL_TX_PASSIVE : | ||
| 484 | CAN_ERR_CRTL_RX_PASSIVE; | ||
| 485 | } | ||
| 486 | cf->data[6] = txerr; | ||
| 487 | cf->data[7] = rxerr; | ||
| 488 | } | ||
| 489 | 480 | ||
| 490 | priv->can.state = state; | 481 | can_change_state(dev, cf, tx_state, rx_state); |
| 482 | |||
| 483 | if(state == CAN_STATE_BUS_OFF) | ||
| 484 | can_bus_off(dev); | ||
| 485 | } | ||
| 491 | 486 | ||
| 492 | netif_rx(skb); | 487 | netif_rx(skb); |
| 493 | 488 | ||
diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c index acb5b92ace92..c837eb91d43e 100644 --- a/drivers/net/can/slcan.c +++ b/drivers/net/can/slcan.c | |||
| @@ -56,9 +56,6 @@ | |||
| 56 | #include <linux/can.h> | 56 | #include <linux/can.h> |
| 57 | #include <linux/can/skb.h> | 57 | #include <linux/can/skb.h> |
| 58 | 58 | ||
| 59 | static __initconst const char banner[] = | ||
| 60 | KERN_INFO "slcan: serial line CAN interface driver\n"; | ||
| 61 | |||
| 62 | MODULE_ALIAS_LDISC(N_SLCAN); | 59 | MODULE_ALIAS_LDISC(N_SLCAN); |
| 63 | MODULE_DESCRIPTION("serial line CAN interface"); | 60 | MODULE_DESCRIPTION("serial line CAN interface"); |
| 64 | MODULE_LICENSE("GPL"); | 61 | MODULE_LICENSE("GPL"); |
| @@ -702,8 +699,8 @@ static int __init slcan_init(void) | |||
| 702 | if (maxdev < 4) | 699 | if (maxdev < 4) |
| 703 | maxdev = 4; /* Sanity */ | 700 | maxdev = 4; /* Sanity */ |
| 704 | 701 | ||
| 705 | printk(banner); | 702 | pr_info("slcan: serial line CAN interface driver\n"); |
| 706 | printk(KERN_INFO "slcan: %d dynamic interface channels.\n", maxdev); | 703 | pr_info("slcan: %d dynamic interface channels.\n", maxdev); |
| 707 | 704 | ||
| 708 | slcan_devs = kzalloc(sizeof(struct net_device *)*maxdev, GFP_KERNEL); | 705 | slcan_devs = kzalloc(sizeof(struct net_device *)*maxdev, GFP_KERNEL); |
| 709 | if (!slcan_devs) | 706 | if (!slcan_devs) |
diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c index 4e94057ef5cf..674f367087c5 100644 --- a/drivers/net/can/vcan.c +++ b/drivers/net/can/vcan.c | |||
| @@ -50,9 +50,6 @@ | |||
| 50 | #include <linux/slab.h> | 50 | #include <linux/slab.h> |
| 51 | #include <net/rtnetlink.h> | 51 | #include <net/rtnetlink.h> |
| 52 | 52 | ||
| 53 | static __initconst const char banner[] = | ||
| 54 | KERN_INFO "vcan: Virtual CAN interface driver\n"; | ||
| 55 | |||
| 56 | MODULE_DESCRIPTION("virtual CAN interface"); | 53 | MODULE_DESCRIPTION("virtual CAN interface"); |
| 57 | MODULE_LICENSE("Dual BSD/GPL"); | 54 | MODULE_LICENSE("Dual BSD/GPL"); |
| 58 | MODULE_AUTHOR("Urs Thuermann <urs.thuermann@volkswagen.de>"); | 55 | MODULE_AUTHOR("Urs Thuermann <urs.thuermann@volkswagen.de>"); |
| @@ -173,7 +170,7 @@ static struct rtnl_link_ops vcan_link_ops __read_mostly = { | |||
| 173 | 170 | ||
| 174 | static __init int vcan_init_module(void) | 171 | static __init int vcan_init_module(void) |
| 175 | { | 172 | { |
| 176 | printk(banner); | 173 | pr_info("vcan: Virtual CAN interface driver\n"); |
| 177 | 174 | ||
| 178 | if (echo) | 175 | if (echo) |
| 179 | printk(KERN_INFO "vcan: enabled echo on driver level.\n"); | 176 | printk(KERN_INFO "vcan: enabled echo on driver level.\n"); |
diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h index b37ea95bc348..c05ff0f9f9a5 100644 --- a/include/linux/can/dev.h +++ b/include/linux/can/dev.h | |||
| @@ -127,6 +127,9 @@ void unregister_candev(struct net_device *dev); | |||
| 127 | int can_restart_now(struct net_device *dev); | 127 | int can_restart_now(struct net_device *dev); |
| 128 | void can_bus_off(struct net_device *dev); | 128 | void can_bus_off(struct net_device *dev); |
| 129 | 129 | ||
| 130 | void can_change_state(struct net_device *dev, struct can_frame *cf, | ||
| 131 | enum can_state tx_state, enum can_state rx_state); | ||
| 132 | |||
| 130 | void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, | 133 | void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, |
| 131 | unsigned int idx); | 134 | unsigned int idx); |
| 132 | unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx); | 135 | unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx); |
diff --git a/include/uapi/linux/can/error.h b/include/uapi/linux/can/error.h index c247446ab25a..1c508be9687f 100644 --- a/include/uapi/linux/can/error.h +++ b/include/uapi/linux/can/error.h | |||
| @@ -71,6 +71,7 @@ | |||
| 71 | #define CAN_ERR_CRTL_TX_PASSIVE 0x20 /* reached error passive status TX */ | 71 | #define CAN_ERR_CRTL_TX_PASSIVE 0x20 /* reached error passive status TX */ |
| 72 | /* (at least one error counter exceeds */ | 72 | /* (at least one error counter exceeds */ |
| 73 | /* the protocol-defined level of 127) */ | 73 | /* the protocol-defined level of 127) */ |
| 74 | #define CAN_ERR_CRTL_ACTIVE 0x40 /* recovered to error active state */ | ||
| 74 | 75 | ||
| 75 | /* error in CAN protocol (type) / data[2] */ | 76 | /* error in CAN protocol (type) / data[2] */ |
| 76 | #define CAN_ERR_PROT_UNSPEC 0x00 /* unspecified */ | 77 | #define CAN_ERR_PROT_UNSPEC 0x00 /* unspecified */ |
diff --git a/net/can/af_can.c b/net/can/af_can.c index ce82337521f6..66e08040ced7 100644 --- a/net/can/af_can.c +++ b/net/can/af_can.c | |||
| @@ -64,9 +64,6 @@ | |||
| 64 | 64 | ||
| 65 | #include "af_can.h" | 65 | #include "af_can.h" |
| 66 | 66 | ||
| 67 | static __initconst const char banner[] = KERN_INFO | ||
| 68 | "can: controller area network core (" CAN_VERSION_STRING ")\n"; | ||
| 69 | |||
| 70 | MODULE_DESCRIPTION("Controller Area Network PF_CAN core"); | 67 | MODULE_DESCRIPTION("Controller Area Network PF_CAN core"); |
| 71 | MODULE_LICENSE("Dual BSD/GPL"); | 68 | MODULE_LICENSE("Dual BSD/GPL"); |
| 72 | MODULE_AUTHOR("Urs Thuermann <urs.thuermann@volkswagen.de>, " | 69 | MODULE_AUTHOR("Urs Thuermann <urs.thuermann@volkswagen.de>, " |
| @@ -524,7 +521,7 @@ static void can_rx_delete_receiver(struct rcu_head *rp) | |||
| 524 | 521 | ||
| 525 | /** | 522 | /** |
| 526 | * can_rx_unregister - unsubscribe CAN frames from a specific interface | 523 | * can_rx_unregister - unsubscribe CAN frames from a specific interface |
| 527 | * @dev: pointer to netdevice (NULL => unsubcribe from 'all' CAN devices list) | 524 | * @dev: pointer to netdevice (NULL => unsubscribe from 'all' CAN devices list) |
| 528 | * @can_id: CAN identifier | 525 | * @can_id: CAN identifier |
| 529 | * @mask: CAN mask | 526 | * @mask: CAN mask |
| 530 | * @func: callback function on filter match | 527 | * @func: callback function on filter match |
| @@ -896,7 +893,7 @@ static __init int can_init(void) | |||
| 896 | offsetof(struct can_frame, data) != | 893 | offsetof(struct can_frame, data) != |
| 897 | offsetof(struct canfd_frame, data)); | 894 | offsetof(struct canfd_frame, data)); |
| 898 | 895 | ||
| 899 | printk(banner); | 896 | pr_info("can: controller area network core (" CAN_VERSION_STRING ")\n"); |
| 900 | 897 | ||
| 901 | memset(&can_rx_alldev_list, 0, sizeof(can_rx_alldev_list)); | 898 | memset(&can_rx_alldev_list, 0, sizeof(can_rx_alldev_list)); |
| 902 | 899 | ||
diff --git a/net/can/bcm.c b/net/can/bcm.c index 01671187e3fe..ee9ffd956552 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c | |||
| @@ -78,8 +78,6 @@ | |||
| 78 | (CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG)) | 78 | (CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG)) |
| 79 | 79 | ||
| 80 | #define CAN_BCM_VERSION CAN_VERSION | 80 | #define CAN_BCM_VERSION CAN_VERSION |
| 81 | static __initconst const char banner[] = KERN_INFO | ||
| 82 | "can: broadcast manager protocol (rev " CAN_BCM_VERSION " t)\n"; | ||
| 83 | 81 | ||
| 84 | MODULE_DESCRIPTION("PF_CAN broadcast manager protocol"); | 82 | MODULE_DESCRIPTION("PF_CAN broadcast manager protocol"); |
| 85 | MODULE_LICENSE("Dual BSD/GPL"); | 83 | MODULE_LICENSE("Dual BSD/GPL"); |
| @@ -441,7 +439,7 @@ static void bcm_rx_update_and_send(struct bcm_op *op, | |||
| 441 | /* mark as used and throttled by default */ | 439 | /* mark as used and throttled by default */ |
| 442 | lastdata->can_dlc |= (RX_RECV|RX_THR); | 440 | lastdata->can_dlc |= (RX_RECV|RX_THR); |
| 443 | 441 | ||
| 444 | /* throtteling mode inactive ? */ | 442 | /* throttling mode inactive ? */ |
| 445 | if (!op->kt_ival2.tv64) { | 443 | if (!op->kt_ival2.tv64) { |
| 446 | /* send RX_CHANGED to the user immediately */ | 444 | /* send RX_CHANGED to the user immediately */ |
| 447 | bcm_rx_changed(op, lastdata); | 445 | bcm_rx_changed(op, lastdata); |
| @@ -452,7 +450,7 @@ static void bcm_rx_update_and_send(struct bcm_op *op, | |||
| 452 | if (hrtimer_active(&op->thrtimer)) | 450 | if (hrtimer_active(&op->thrtimer)) |
| 453 | return; | 451 | return; |
| 454 | 452 | ||
| 455 | /* first receiption with enabled throttling mode */ | 453 | /* first reception with enabled throttling mode */ |
| 456 | if (!op->kt_lastmsg.tv64) | 454 | if (!op->kt_lastmsg.tv64) |
| 457 | goto rx_changed_settime; | 455 | goto rx_changed_settime; |
| 458 | 456 | ||
| @@ -480,7 +478,7 @@ static void bcm_rx_cmp_to_index(struct bcm_op *op, unsigned int index, | |||
| 480 | const struct can_frame *rxdata) | 478 | const struct can_frame *rxdata) |
| 481 | { | 479 | { |
| 482 | /* | 480 | /* |
| 483 | * no one uses the MSBs of can_dlc for comparation, | 481 | * no one uses the MSBs of can_dlc for comparison, |
| 484 | * so we use it here to detect the first time of reception | 482 | * so we use it here to detect the first time of reception |
| 485 | */ | 483 | */ |
| 486 | 484 | ||
| @@ -510,7 +508,7 @@ static void bcm_rx_cmp_to_index(struct bcm_op *op, unsigned int index, | |||
| 510 | } | 508 | } |
| 511 | 509 | ||
| 512 | /* | 510 | /* |
| 513 | * bcm_rx_starttimer - enable timeout monitoring for CAN frame receiption | 511 | * bcm_rx_starttimer - enable timeout monitoring for CAN frame reception |
| 514 | */ | 512 | */ |
| 515 | static void bcm_rx_starttimer(struct bcm_op *op) | 513 | static void bcm_rx_starttimer(struct bcm_op *op) |
| 516 | { | 514 | { |
| @@ -539,7 +537,7 @@ static void bcm_rx_timeout_tsklet(unsigned long data) | |||
| 539 | } | 537 | } |
| 540 | 538 | ||
| 541 | /* | 539 | /* |
| 542 | * bcm_rx_timeout_handler - when the (cyclic) CAN frame receiption timed out | 540 | * bcm_rx_timeout_handler - when the (cyclic) CAN frame reception timed out |
| 543 | */ | 541 | */ |
| 544 | static enum hrtimer_restart bcm_rx_timeout_handler(struct hrtimer *hrtimer) | 542 | static enum hrtimer_restart bcm_rx_timeout_handler(struct hrtimer *hrtimer) |
| 545 | { | 543 | { |
| @@ -627,7 +625,7 @@ static enum hrtimer_restart bcm_rx_thr_handler(struct hrtimer *hrtimer) | |||
| 627 | } | 625 | } |
| 628 | 626 | ||
| 629 | /* | 627 | /* |
| 630 | * bcm_rx_handler - handle a CAN frame receiption | 628 | * bcm_rx_handler - handle a CAN frame reception |
| 631 | */ | 629 | */ |
| 632 | static void bcm_rx_handler(struct sk_buff *skb, void *data) | 630 | static void bcm_rx_handler(struct sk_buff *skb, void *data) |
| 633 | { | 631 | { |
| @@ -1612,7 +1610,7 @@ static int __init bcm_module_init(void) | |||
| 1612 | { | 1610 | { |
| 1613 | int err; | 1611 | int err; |
| 1614 | 1612 | ||
| 1615 | printk(banner); | 1613 | pr_info("can: broadcast manager protocol (rev " CAN_BCM_VERSION " t)\n"); |
| 1616 | 1614 | ||
| 1617 | err = can_proto_register(&bcm_can_proto); | 1615 | err = can_proto_register(&bcm_can_proto); |
| 1618 | if (err < 0) { | 1616 | if (err < 0) { |
diff --git a/net/can/gw.c b/net/can/gw.c index 050a2110d43f..295f62e62eb3 100644 --- a/net/can/gw.c +++ b/net/can/gw.c | |||
| @@ -361,7 +361,7 @@ static void can_can_gw_rcv(struct sk_buff *skb, void *data) | |||
| 361 | * The Controller Area Network controllers only accept CAN frames with | 361 | * The Controller Area Network controllers only accept CAN frames with |
| 362 | * correct CRCs - which are not visible in the controller registers. | 362 | * correct CRCs - which are not visible in the controller registers. |
| 363 | * According to skbuff.h documentation the csum_start element for IP | 363 | * According to skbuff.h documentation the csum_start element for IP |
| 364 | * checksums is undefined/unsued when ip_summed == CHECKSUM_UNNECESSARY. | 364 | * checksums is undefined/unused when ip_summed == CHECKSUM_UNNECESSARY. |
| 365 | * Only CAN skbs can be processed here which already have this property. | 365 | * Only CAN skbs can be processed here which already have this property. |
| 366 | */ | 366 | */ |
| 367 | 367 | ||
diff --git a/net/can/raw.c b/net/can/raw.c index dfdcffbb1070..00c13ef23661 100644 --- a/net/can/raw.c +++ b/net/can/raw.c | |||
| @@ -56,8 +56,6 @@ | |||
| 56 | #include <net/net_namespace.h> | 56 | #include <net/net_namespace.h> |
| 57 | 57 | ||
| 58 | #define CAN_RAW_VERSION CAN_VERSION | 58 | #define CAN_RAW_VERSION CAN_VERSION |
| 59 | static __initconst const char banner[] = | ||
| 60 | KERN_INFO "can: raw protocol (rev " CAN_RAW_VERSION ")\n"; | ||
| 61 | 59 | ||
| 62 | MODULE_DESCRIPTION("PF_CAN raw protocol"); | 60 | MODULE_DESCRIPTION("PF_CAN raw protocol"); |
| 63 | MODULE_LICENSE("Dual BSD/GPL"); | 61 | MODULE_LICENSE("Dual BSD/GPL"); |
| @@ -810,7 +808,7 @@ static __init int raw_module_init(void) | |||
| 810 | { | 808 | { |
| 811 | int err; | 809 | int err; |
| 812 | 810 | ||
| 813 | printk(banner); | 811 | pr_info("can: raw protocol (rev " CAN_RAW_VERSION ")\n"); |
| 814 | 812 | ||
| 815 | err = can_proto_register(&raw_can_proto); | 813 | err = can_proto_register(&raw_can_proto); |
| 816 | if (err < 0) | 814 | if (err < 0) |
