diff options
| -rw-r--r-- | Documentation/networking/can.txt | 6 | ||||
| -rw-r--r-- | drivers/net/can/flexcan.c | 172 | ||||
| -rw-r--r-- | net/can/raw.c | 26 |
3 files changed, 136 insertions, 68 deletions
diff --git a/Documentation/networking/can.txt b/Documentation/networking/can.txt index f3089d423515..0cbe6ec22d6f 100644 --- a/Documentation/networking/can.txt +++ b/Documentation/networking/can.txt | |||
| @@ -554,12 +554,6 @@ solution for a couple of reasons: | |||
| 554 | not specified in the struct can_frame and therefore it is only valid in | 554 | not specified in the struct can_frame and therefore it is only valid in |
| 555 | CANFD_MTU sized CAN FD frames. | 555 | CANFD_MTU sized CAN FD frames. |
| 556 | 556 | ||
| 557 | As long as the payload length is <=8 the received CAN frames from CAN FD | ||
| 558 | capable CAN devices can be received and read by legacy sockets too. When | ||
| 559 | user-generated CAN FD frames have a payload length <=8 these can be send | ||
| 560 | by legacy CAN network interfaces too. Sending CAN FD frames with payload | ||
| 561 | length > 8 to a legacy CAN network interface returns an -EMSGSIZE error. | ||
| 562 | |||
| 563 | Implementation hint for new CAN applications: | 557 | Implementation hint for new CAN applications: |
| 564 | 558 | ||
| 565 | To build a CAN FD aware application use struct canfd_frame as basic CAN | 559 | To build a CAN FD aware application use struct canfd_frame as basic CAN |
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 320bef2dba42..61376abdab39 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c | |||
| @@ -144,6 +144,8 @@ | |||
| 144 | 144 | ||
| 145 | #define FLEXCAN_MB_CODE_MASK (0xf0ffffff) | 145 | #define FLEXCAN_MB_CODE_MASK (0xf0ffffff) |
| 146 | 146 | ||
| 147 | #define FLEXCAN_TIMEOUT_US (50) | ||
| 148 | |||
| 147 | /* | 149 | /* |
| 148 | * FLEXCAN hardware feature flags | 150 | * FLEXCAN hardware feature flags |
| 149 | * | 151 | * |
| @@ -262,6 +264,22 @@ static inline void flexcan_write(u32 val, void __iomem *addr) | |||
| 262 | } | 264 | } |
| 263 | #endif | 265 | #endif |
| 264 | 266 | ||
| 267 | static inline int flexcan_transceiver_enable(const struct flexcan_priv *priv) | ||
| 268 | { | ||
| 269 | if (!priv->reg_xceiver) | ||
| 270 | return 0; | ||
| 271 | |||
| 272 | return regulator_enable(priv->reg_xceiver); | ||
| 273 | } | ||
| 274 | |||
| 275 | static inline int flexcan_transceiver_disable(const struct flexcan_priv *priv) | ||
| 276 | { | ||
| 277 | if (!priv->reg_xceiver) | ||
| 278 | return 0; | ||
| 279 | |||
| 280 | return regulator_disable(priv->reg_xceiver); | ||
| 281 | } | ||
| 282 | |||
| 265 | static inline int flexcan_has_and_handle_berr(const struct flexcan_priv *priv, | 283 | static inline int flexcan_has_and_handle_berr(const struct flexcan_priv *priv, |
| 266 | u32 reg_esr) | 284 | u32 reg_esr) |
| 267 | { | 285 | { |
| @@ -269,26 +287,95 @@ static inline int flexcan_has_and_handle_berr(const struct flexcan_priv *priv, | |||
| 269 | (reg_esr & FLEXCAN_ESR_ERR_BUS); | 287 | (reg_esr & FLEXCAN_ESR_ERR_BUS); |
| 270 | } | 288 | } |
| 271 | 289 | ||
| 272 | static inline void flexcan_chip_enable(struct flexcan_priv *priv) | 290 | static int flexcan_chip_enable(struct flexcan_priv *priv) |
| 273 | { | 291 | { |
| 274 | struct flexcan_regs __iomem *regs = priv->base; | 292 | struct flexcan_regs __iomem *regs = priv->base; |
| 293 | unsigned int timeout = FLEXCAN_TIMEOUT_US / 10; | ||
| 275 | u32 reg; | 294 | u32 reg; |
| 276 | 295 | ||
| 277 | reg = flexcan_read(®s->mcr); | 296 | reg = flexcan_read(®s->mcr); |
| 278 | reg &= ~FLEXCAN_MCR_MDIS; | 297 | reg &= ~FLEXCAN_MCR_MDIS; |
| 279 | flexcan_write(reg, ®s->mcr); | 298 | flexcan_write(reg, ®s->mcr); |
| 280 | 299 | ||
| 281 | udelay(10); | 300 | while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)) |
| 301 | usleep_range(10, 20); | ||
| 302 | |||
| 303 | if (flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK) | ||
| 304 | return -ETIMEDOUT; | ||
| 305 | |||
| 306 | return 0; | ||
| 282 | } | 307 | } |
| 283 | 308 | ||
| 284 | static inline void flexcan_chip_disable(struct flexcan_priv *priv) | 309 | static int flexcan_chip_disable(struct flexcan_priv *priv) |
| 285 | { | 310 | { |
| 286 | struct flexcan_regs __iomem *regs = priv->base; | 311 | struct flexcan_regs __iomem *regs = priv->base; |
| 312 | unsigned int timeout = FLEXCAN_TIMEOUT_US / 10; | ||
| 287 | u32 reg; | 313 | u32 reg; |
| 288 | 314 | ||
| 289 | reg = flexcan_read(®s->mcr); | 315 | reg = flexcan_read(®s->mcr); |
| 290 | reg |= FLEXCAN_MCR_MDIS; | 316 | reg |= FLEXCAN_MCR_MDIS; |
| 291 | flexcan_write(reg, ®s->mcr); | 317 | flexcan_write(reg, ®s->mcr); |
| 318 | |||
| 319 | while (timeout-- && !(flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)) | ||
| 320 | usleep_range(10, 20); | ||
| 321 | |||
| 322 | if (!(flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)) | ||
| 323 | return -ETIMEDOUT; | ||
| 324 | |||
| 325 | return 0; | ||
| 326 | } | ||
| 327 | |||
| 328 | static int flexcan_chip_freeze(struct flexcan_priv *priv) | ||
| 329 | { | ||
| 330 | struct flexcan_regs __iomem *regs = priv->base; | ||
| 331 | unsigned int timeout = 1000 * 1000 * 10 / priv->can.bittiming.bitrate; | ||
| 332 | u32 reg; | ||
| 333 | |||
| 334 | reg = flexcan_read(®s->mcr); | ||
| 335 | reg |= FLEXCAN_MCR_HALT; | ||
| 336 | flexcan_write(reg, ®s->mcr); | ||
| 337 | |||
| 338 | while (timeout-- && !(flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK)) | ||
| 339 | usleep_range(100, 200); | ||
| 340 | |||
| 341 | if (!(flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK)) | ||
| 342 | return -ETIMEDOUT; | ||
| 343 | |||
| 344 | return 0; | ||
| 345 | } | ||
| 346 | |||
| 347 | static int flexcan_chip_unfreeze(struct flexcan_priv *priv) | ||
| 348 | { | ||
| 349 | struct flexcan_regs __iomem *regs = priv->base; | ||
| 350 | unsigned int timeout = FLEXCAN_TIMEOUT_US / 10; | ||
| 351 | u32 reg; | ||
| 352 | |||
| 353 | reg = flexcan_read(®s->mcr); | ||
| 354 | reg &= ~FLEXCAN_MCR_HALT; | ||
| 355 | flexcan_write(reg, ®s->mcr); | ||
| 356 | |||
| 357 | while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK)) | ||
| 358 | usleep_range(10, 20); | ||
| 359 | |||
| 360 | if (flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK) | ||
| 361 | return -ETIMEDOUT; | ||
| 362 | |||
| 363 | return 0; | ||
| 364 | } | ||
| 365 | |||
| 366 | static int flexcan_chip_softreset(struct flexcan_priv *priv) | ||
| 367 | { | ||
| 368 | struct flexcan_regs __iomem *regs = priv->base; | ||
| 369 | unsigned int timeout = FLEXCAN_TIMEOUT_US / 10; | ||
| 370 | |||
| 371 | flexcan_write(FLEXCAN_MCR_SOFTRST, ®s->mcr); | ||
| 372 | while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_SOFTRST)) | ||
| 373 | usleep_range(10, 20); | ||
| 374 | |||
| 375 | if (flexcan_read(®s->mcr) & FLEXCAN_MCR_SOFTRST) | ||
| 376 | return -ETIMEDOUT; | ||
| 377 | |||
| 378 | return 0; | ||
| 292 | } | 379 | } |
| 293 | 380 | ||
| 294 | static int flexcan_get_berr_counter(const struct net_device *dev, | 381 | static int flexcan_get_berr_counter(const struct net_device *dev, |
| @@ -709,19 +796,14 @@ static int flexcan_chip_start(struct net_device *dev) | |||
| 709 | u32 reg_mcr, reg_ctrl; | 796 | u32 reg_mcr, reg_ctrl; |
| 710 | 797 | ||
| 711 | /* enable module */ | 798 | /* enable module */ |
| 712 | flexcan_chip_enable(priv); | 799 | err = flexcan_chip_enable(priv); |
| 800 | if (err) | ||
| 801 | return err; | ||
| 713 | 802 | ||
| 714 | /* soft reset */ | 803 | /* soft reset */ |
| 715 | flexcan_write(FLEXCAN_MCR_SOFTRST, ®s->mcr); | 804 | err = flexcan_chip_softreset(priv); |
| 716 | udelay(10); | 805 | if (err) |
| 717 | 806 | goto out_chip_disable; | |
| 718 | reg_mcr = flexcan_read(®s->mcr); | ||
| 719 | if (reg_mcr & FLEXCAN_MCR_SOFTRST) { | ||
| 720 | netdev_err(dev, "Failed to softreset can module (mcr=0x%08x)\n", | ||
| 721 | reg_mcr); | ||
| 722 | err = -ENODEV; | ||
| 723 | goto out; | ||
| 724 | } | ||
| 725 | 807 | ||
| 726 | flexcan_set_bittiming(dev); | 808 | flexcan_set_bittiming(dev); |
| 727 | 809 | ||
| @@ -788,16 +870,14 @@ static int flexcan_chip_start(struct net_device *dev) | |||
| 788 | if (priv->devtype_data->features & FLEXCAN_HAS_V10_FEATURES) | 870 | if (priv->devtype_data->features & FLEXCAN_HAS_V10_FEATURES) |
| 789 | flexcan_write(0x0, ®s->rxfgmask); | 871 | flexcan_write(0x0, ®s->rxfgmask); |
| 790 | 872 | ||
| 791 | if (priv->reg_xceiver) { | 873 | err = flexcan_transceiver_enable(priv); |
| 792 | err = regulator_enable(priv->reg_xceiver); | 874 | if (err) |
| 793 | if (err) | 875 | goto out_chip_disable; |
| 794 | goto out; | ||
| 795 | } | ||
| 796 | 876 | ||
| 797 | /* synchronize with the can bus */ | 877 | /* synchronize with the can bus */ |
| 798 | reg_mcr = flexcan_read(®s->mcr); | 878 | err = flexcan_chip_unfreeze(priv); |
| 799 | reg_mcr &= ~FLEXCAN_MCR_HALT; | 879 | if (err) |
| 800 | flexcan_write(reg_mcr, ®s->mcr); | 880 | goto out_transceiver_disable; |
| 801 | 881 | ||
| 802 | priv->can.state = CAN_STATE_ERROR_ACTIVE; | 882 | priv->can.state = CAN_STATE_ERROR_ACTIVE; |
| 803 | 883 | ||
| @@ -810,7 +890,9 @@ static int flexcan_chip_start(struct net_device *dev) | |||
| 810 | 890 | ||
| 811 | return 0; | 891 | return 0; |
| 812 | 892 | ||
| 813 | out: | 893 | out_transceiver_disable: |
| 894 | flexcan_transceiver_disable(priv); | ||
| 895 | out_chip_disable: | ||
| 814 | flexcan_chip_disable(priv); | 896 | flexcan_chip_disable(priv); |
| 815 | return err; | 897 | return err; |
| 816 | } | 898 | } |
| @@ -825,18 +907,17 @@ static void flexcan_chip_stop(struct net_device *dev) | |||
| 825 | { | 907 | { |
| 826 | struct flexcan_priv *priv = netdev_priv(dev); | 908 | struct flexcan_priv *priv = netdev_priv(dev); |
| 827 | struct flexcan_regs __iomem *regs = priv->base; | 909 | struct flexcan_regs __iomem *regs = priv->base; |
| 828 | u32 reg; | 910 | |
| 911 | /* freeze + disable module */ | ||
| 912 | flexcan_chip_freeze(priv); | ||
| 913 | flexcan_chip_disable(priv); | ||
| 829 | 914 | ||
| 830 | /* Disable all interrupts */ | 915 | /* Disable all interrupts */ |
| 831 | flexcan_write(0, ®s->imask1); | 916 | flexcan_write(0, ®s->imask1); |
| 917 | flexcan_write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL, | ||
| 918 | ®s->ctrl); | ||
| 832 | 919 | ||
| 833 | /* Disable + halt module */ | 920 | flexcan_transceiver_disable(priv); |
| 834 | reg = flexcan_read(®s->mcr); | ||
| 835 | reg |= FLEXCAN_MCR_MDIS | FLEXCAN_MCR_HALT; | ||
| 836 | flexcan_write(reg, ®s->mcr); | ||
| 837 | |||
| 838 | if (priv->reg_xceiver) | ||
| 839 | regulator_disable(priv->reg_xceiver); | ||
| 840 | priv->can.state = CAN_STATE_STOPPED; | 921 | priv->can.state = CAN_STATE_STOPPED; |
| 841 | 922 | ||
| 842 | return; | 923 | return; |
| @@ -866,7 +947,7 @@ static int flexcan_open(struct net_device *dev) | |||
| 866 | /* start chip and queuing */ | 947 | /* start chip and queuing */ |
| 867 | err = flexcan_chip_start(dev); | 948 | err = flexcan_chip_start(dev); |
| 868 | if (err) | 949 | if (err) |
| 869 | goto out_close; | 950 | goto out_free_irq; |
| 870 | 951 | ||
| 871 | can_led_event(dev, CAN_LED_EVENT_OPEN); | 952 | can_led_event(dev, CAN_LED_EVENT_OPEN); |
| 872 | 953 | ||
| @@ -875,6 +956,8 @@ static int flexcan_open(struct net_device *dev) | |||
| 875 | 956 | ||
| 876 | return 0; | 957 | return 0; |
| 877 | 958 | ||
| 959 | out_free_irq: | ||
| 960 | free_irq(dev->irq, dev); | ||
| 878 | out_close: | 961 | out_close: |
| 879 | close_candev(dev); | 962 | close_candev(dev); |
| 880 | out_disable_per: | 963 | out_disable_per: |
| @@ -945,12 +1028,16 @@ static int register_flexcandev(struct net_device *dev) | |||
| 945 | goto out_disable_ipg; | 1028 | goto out_disable_ipg; |
| 946 | 1029 | ||
| 947 | /* select "bus clock", chip must be disabled */ | 1030 | /* select "bus clock", chip must be disabled */ |
| 948 | flexcan_chip_disable(priv); | 1031 | err = flexcan_chip_disable(priv); |
| 1032 | if (err) | ||
| 1033 | goto out_disable_per; | ||
| 949 | reg = flexcan_read(®s->ctrl); | 1034 | reg = flexcan_read(®s->ctrl); |
| 950 | reg |= FLEXCAN_CTRL_CLK_SRC; | 1035 | reg |= FLEXCAN_CTRL_CLK_SRC; |
| 951 | flexcan_write(reg, ®s->ctrl); | 1036 | flexcan_write(reg, ®s->ctrl); |
| 952 | 1037 | ||
| 953 | flexcan_chip_enable(priv); | 1038 | err = flexcan_chip_enable(priv); |
| 1039 | if (err) | ||
| 1040 | goto out_chip_disable; | ||
| 954 | 1041 | ||
| 955 | /* set freeze, halt and activate FIFO, restrict register access */ | 1042 | /* set freeze, halt and activate FIFO, restrict register access */ |
| 956 | reg = flexcan_read(®s->mcr); | 1043 | reg = flexcan_read(®s->mcr); |
| @@ -967,14 +1054,15 @@ static int register_flexcandev(struct net_device *dev) | |||
| 967 | if (!(reg & FLEXCAN_MCR_FEN)) { | 1054 | if (!(reg & FLEXCAN_MCR_FEN)) { |
| 968 | netdev_err(dev, "Could not enable RX FIFO, unsupported core\n"); | 1055 | netdev_err(dev, "Could not enable RX FIFO, unsupported core\n"); |
| 969 | err = -ENODEV; | 1056 | err = -ENODEV; |
| 970 | goto out_disable_per; | 1057 | goto out_chip_disable; |
| 971 | } | 1058 | } |
| 972 | 1059 | ||
| 973 | err = register_candev(dev); | 1060 | err = register_candev(dev); |
| 974 | 1061 | ||
| 975 | out_disable_per: | ||
| 976 | /* disable core and turn off clocks */ | 1062 | /* disable core and turn off clocks */ |
| 1063 | out_chip_disable: | ||
| 977 | flexcan_chip_disable(priv); | 1064 | flexcan_chip_disable(priv); |
| 1065 | out_disable_per: | ||
| 978 | clk_disable_unprepare(priv->clk_per); | 1066 | clk_disable_unprepare(priv->clk_per); |
| 979 | out_disable_ipg: | 1067 | out_disable_ipg: |
| 980 | clk_disable_unprepare(priv->clk_ipg); | 1068 | clk_disable_unprepare(priv->clk_ipg); |
| @@ -1104,9 +1192,10 @@ static int flexcan_probe(struct platform_device *pdev) | |||
| 1104 | static int flexcan_remove(struct platform_device *pdev) | 1192 | static int flexcan_remove(struct platform_device *pdev) |
| 1105 | { | 1193 | { |
| 1106 | struct net_device *dev = platform_get_drvdata(pdev); | 1194 | struct net_device *dev = platform_get_drvdata(pdev); |
| 1195 | struct flexcan_priv *priv = netdev_priv(dev); | ||
| 1107 | 1196 | ||
| 1108 | unregister_flexcandev(dev); | 1197 | unregister_flexcandev(dev); |
| 1109 | 1198 | netif_napi_del(&priv->napi); | |
| 1110 | free_candev(dev); | 1199 | free_candev(dev); |
| 1111 | 1200 | ||
| 1112 | return 0; | 1201 | return 0; |
| @@ -1117,8 +1206,11 @@ static int flexcan_suspend(struct device *device) | |||
| 1117 | { | 1206 | { |
| 1118 | struct net_device *dev = dev_get_drvdata(device); | 1207 | struct net_device *dev = dev_get_drvdata(device); |
| 1119 | struct flexcan_priv *priv = netdev_priv(dev); | 1208 | struct flexcan_priv *priv = netdev_priv(dev); |
| 1209 | int err; | ||
| 1120 | 1210 | ||
| 1121 | flexcan_chip_disable(priv); | 1211 | err = flexcan_chip_disable(priv); |
| 1212 | if (err) | ||
| 1213 | return err; | ||
| 1122 | 1214 | ||
| 1123 | if (netif_running(dev)) { | 1215 | if (netif_running(dev)) { |
| 1124 | netif_stop_queue(dev); | 1216 | netif_stop_queue(dev); |
| @@ -1139,9 +1231,7 @@ static int flexcan_resume(struct device *device) | |||
| 1139 | netif_device_attach(dev); | 1231 | netif_device_attach(dev); |
| 1140 | netif_start_queue(dev); | 1232 | netif_start_queue(dev); |
| 1141 | } | 1233 | } |
| 1142 | flexcan_chip_enable(priv); | 1234 | return flexcan_chip_enable(priv); |
| 1143 | |||
| 1144 | return 0; | ||
| 1145 | } | 1235 | } |
| 1146 | #endif /* CONFIG_PM_SLEEP */ | 1236 | #endif /* CONFIG_PM_SLEEP */ |
| 1147 | 1237 | ||
diff --git a/net/can/raw.c b/net/can/raw.c index 8be757cca2ec..081e81fd017f 100644 --- a/net/can/raw.c +++ b/net/can/raw.c | |||
| @@ -121,13 +121,9 @@ static void raw_rcv(struct sk_buff *oskb, void *data) | |||
| 121 | if (!ro->recv_own_msgs && oskb->sk == sk) | 121 | if (!ro->recv_own_msgs && oskb->sk == sk) |
| 122 | return; | 122 | return; |
| 123 | 123 | ||
| 124 | /* do not pass frames with DLC > 8 to a legacy socket */ | 124 | /* do not pass non-CAN2.0 frames to a legacy socket */ |
| 125 | if (!ro->fd_frames) { | 125 | if (!ro->fd_frames && oskb->len != CAN_MTU) |
| 126 | struct canfd_frame *cfd = (struct canfd_frame *)oskb->data; | 126 | return; |
| 127 | |||
| 128 | if (unlikely(cfd->len > CAN_MAX_DLEN)) | ||
| 129 | return; | ||
| 130 | } | ||
| 131 | 127 | ||
| 132 | /* clone the given skb to be able to enqueue it into the rcv queue */ | 128 | /* clone the given skb to be able to enqueue it into the rcv queue */ |
| 133 | skb = skb_clone(oskb, GFP_ATOMIC); | 129 | skb = skb_clone(oskb, GFP_ATOMIC); |
| @@ -738,9 +734,7 @@ static int raw_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 738 | struct msghdr *msg, size_t size, int flags) | 734 | struct msghdr *msg, size_t size, int flags) |
| 739 | { | 735 | { |
| 740 | struct sock *sk = sock->sk; | 736 | struct sock *sk = sock->sk; |
| 741 | struct raw_sock *ro = raw_sk(sk); | ||
| 742 | struct sk_buff *skb; | 737 | struct sk_buff *skb; |
| 743 | int rxmtu; | ||
| 744 | int err = 0; | 738 | int err = 0; |
| 745 | int noblock; | 739 | int noblock; |
| 746 | 740 | ||
| @@ -751,20 +745,10 @@ static int raw_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 751 | if (!skb) | 745 | if (!skb) |
| 752 | return err; | 746 | return err; |
| 753 | 747 | ||
| 754 | /* | 748 | if (size < skb->len) |
| 755 | * when serving a legacy socket the DLC <= 8 is already checked inside | ||
| 756 | * raw_rcv(). Now check if we need to pass a canfd_frame to a legacy | ||
| 757 | * socket and cut the possible CANFD_MTU/CAN_MTU length to CAN_MTU | ||
| 758 | */ | ||
| 759 | if (!ro->fd_frames) | ||
| 760 | rxmtu = CAN_MTU; | ||
| 761 | else | ||
| 762 | rxmtu = skb->len; | ||
| 763 | |||
| 764 | if (size < rxmtu) | ||
| 765 | msg->msg_flags |= MSG_TRUNC; | 749 | msg->msg_flags |= MSG_TRUNC; |
| 766 | else | 750 | else |
| 767 | size = rxmtu; | 751 | size = skb->len; |
| 768 | 752 | ||
| 769 | err = memcpy_toiovec(msg->msg_iov, skb->data, size); | 753 | err = memcpy_toiovec(msg->msg_iov, skb->data, size); |
| 770 | if (err < 0) { | 754 | if (err < 0) { |
