Commit 9b97b84e authored by David S. Miller's avatar David S. Miller
parents d7ce8a5f d6e640f9
...@@ -232,16 +232,16 @@ solution for a couple of reasons: ...@@ -232,16 +232,16 @@ solution for a couple of reasons:
arbitration problems and error frames caused by the different arbitration problems and error frames caused by the different
ECUs. The occurrence of detected errors are important for diagnosis ECUs. The occurrence of detected errors are important for diagnosis
and have to be logged together with the exact timestamp. For this and have to be logged together with the exact timestamp. For this
reason the CAN interface driver can generate so called Error Frames reason the CAN interface driver can generate so called Error Message
that can optionally be passed to the user application in the same Frames that can optionally be passed to the user application in the
way as other CAN frames. Whenever an error on the physical layer same way as other CAN frames. Whenever an error on the physical layer
or the MAC layer is detected (e.g. by the CAN controller) the driver or the MAC layer is detected (e.g. by the CAN controller) the driver
creates an appropriate error frame. Error frames can be requested by creates an appropriate error message frame. Error messages frames can
the user application using the common CAN filter mechanisms. Inside be requested by the user application using the common CAN filter
this filter definition the (interested) type of errors may be mechanisms. Inside this filter definition the (interested) type of
selected. The reception of error frames is disabled by default. errors may be selected. The reception of error messages is disabled
The format of the CAN error frame is briefly described in the Linux by default. The format of the CAN error message frame is briefly
header file "include/linux/can/error.h". described in the Linux header file "include/linux/can/error.h".
4. How to use Socket CAN 4. How to use Socket CAN
------------------------ ------------------------
...@@ -383,7 +383,7 @@ solution for a couple of reasons: ...@@ -383,7 +383,7 @@ solution for a couple of reasons:
defaults are set at RAW socket binding time: defaults are set at RAW socket binding time:
- The filters are set to exactly one filter receiving everything - The filters are set to exactly one filter receiving everything
- The socket only receives valid data frames (=> no error frames) - The socket only receives valid data frames (=> no error message frames)
- The loopback of sent CAN frames is enabled (see chapter 3.2) - The loopback of sent CAN frames is enabled (see chapter 3.2)
- The socket does not receive its own sent frames (in loopback mode) - The socket does not receive its own sent frames (in loopback mode)
...@@ -434,7 +434,7 @@ solution for a couple of reasons: ...@@ -434,7 +434,7 @@ solution for a couple of reasons:
4.1.2 RAW socket option CAN_RAW_ERR_FILTER 4.1.2 RAW socket option CAN_RAW_ERR_FILTER
As described in chapter 3.4 the CAN interface driver can generate so As described in chapter 3.4 the CAN interface driver can generate so
called Error Frames that can optionally be passed to the user called Error Message Frames that can optionally be passed to the user
application in the same way as other CAN frames. The possible application in the same way as other CAN frames. The possible
errors are divided into different error classes that may be filtered errors are divided into different error classes that may be filtered
using the appropriate error mask. To register for every possible using the appropriate error mask. To register for every possible
...@@ -527,7 +527,7 @@ solution for a couple of reasons: ...@@ -527,7 +527,7 @@ solution for a couple of reasons:
rcvlist_all - list for unfiltered entries (no filter operations) rcvlist_all - list for unfiltered entries (no filter operations)
rcvlist_eff - list for single extended frame (EFF) entries rcvlist_eff - list for single extended frame (EFF) entries
rcvlist_err - list for error frames masks rcvlist_err - list for error message frames masks
rcvlist_fil - list for mask/value filters rcvlist_fil - list for mask/value filters
rcvlist_inv - list for mask/value filters (inverse semantic) rcvlist_inv - list for mask/value filters (inverse semantic)
rcvlist_sff - list for single standard frame (SFF) entries rcvlist_sff - list for single standard frame (SFF) entries
...@@ -784,13 +784,13 @@ solution for a couple of reasons: ...@@ -784,13 +784,13 @@ solution for a couple of reasons:
$ ip link set canX type can restart-ms 100 $ ip link set canX type can restart-ms 100
Alternatively, the application may realize the "bus-off" condition Alternatively, the application may realize the "bus-off" condition
by monitoring CAN error frames and do a restart when appropriate with by monitoring CAN error message frames and do a restart when
the command: appropriate with the command:
$ ip link set canX type can restart $ ip link set canX type can restart
Note that a restart will also create a CAN error frame (see also Note that a restart will also create a CAN error message frame (see
chapter 3.4). also chapter 3.4).
6.6 Supported CAN hardware 6.6 Supported CAN hardware
......
...@@ -1056,6 +1056,42 @@ static struct of_device_id flexcan_of_match[] = { ...@@ -1056,6 +1056,42 @@ static struct of_device_id flexcan_of_match[] = {
{}, {},
}; };
#ifdef CONFIG_PM
static int flexcan_suspend(struct platform_device *pdev, pm_message_t state)
{
struct net_device *dev = platform_get_drvdata(pdev);
struct flexcan_priv *priv = netdev_priv(dev);
flexcan_chip_disable(priv);
if (netif_running(dev)) {
netif_stop_queue(dev);
netif_device_detach(dev);
}
priv->can.state = CAN_STATE_SLEEPING;
return 0;
}
static int flexcan_resume(struct platform_device *pdev)
{
struct net_device *dev = platform_get_drvdata(pdev);
struct flexcan_priv *priv = netdev_priv(dev);
priv->can.state = CAN_STATE_ERROR_ACTIVE;
if (netif_running(dev)) {
netif_device_attach(dev);
netif_start_queue(dev);
}
flexcan_chip_enable(priv);
return 0;
}
#else
#define flexcan_suspend NULL
#define flexcan_resume NULL
#endif
static struct platform_driver flexcan_driver = { static struct platform_driver flexcan_driver = {
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,
...@@ -1064,6 +1100,8 @@ static struct platform_driver flexcan_driver = { ...@@ -1064,6 +1100,8 @@ static struct platform_driver flexcan_driver = {
}, },
.probe = flexcan_probe, .probe = flexcan_probe,
.remove = __devexit_p(flexcan_remove), .remove = __devexit_p(flexcan_remove),
.suspend = flexcan_suspend,
.resume = flexcan_resume,
}; };
module_platform_driver(flexcan_driver); module_platform_driver(flexcan_driver);
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
/* special address description flags for the CAN_ID */ /* special address description flags for the CAN_ID */
#define CAN_EFF_FLAG 0x80000000U /* EFF/SFF is set in the MSB */ #define CAN_EFF_FLAG 0x80000000U /* EFF/SFF is set in the MSB */
#define CAN_RTR_FLAG 0x40000000U /* remote transmission request */ #define CAN_RTR_FLAG 0x40000000U /* remote transmission request */
#define CAN_ERR_FLAG 0x20000000U /* error frame */ #define CAN_ERR_FLAG 0x20000000U /* error message frame */
/* valid bits in CAN ID for frame formats */ /* valid bits in CAN ID for frame formats */
#define CAN_SFF_MASK 0x000007FFU /* standard frame format (SFF) */ #define CAN_SFF_MASK 0x000007FFU /* standard frame format (SFF) */
...@@ -32,14 +32,14 @@ ...@@ -32,14 +32,14 @@
* Controller Area Network Identifier structure * Controller Area Network Identifier structure
* *
* bit 0-28 : CAN identifier (11/29 bit) * bit 0-28 : CAN identifier (11/29 bit)
* bit 29 : error frame flag (0 = data frame, 1 = error frame) * bit 29 : error message frame flag (0 = data frame, 1 = error message)
* bit 30 : remote transmission request flag (1 = rtr frame) * bit 30 : remote transmission request flag (1 = rtr frame)
* bit 31 : frame format flag (0 = standard 11 bit, 1 = extended 29 bit) * bit 31 : frame format flag (0 = standard 11 bit, 1 = extended 29 bit)
*/ */
typedef __u32 canid_t; typedef __u32 canid_t;
/* /*
* Controller Area Network Error Frame Mask structure * Controller Area Network Error Message Frame Mask structure
* *
* bit 0-28 : error class mask (see include/linux/can/error.h) * bit 0-28 : error class mask (see include/linux/can/error.h)
* bit 29-31 : set to zero * bit 29-31 : set to zero
...@@ -97,7 +97,7 @@ struct sockaddr_can { ...@@ -97,7 +97,7 @@ struct sockaddr_can {
* <received_can_id> & mask == can_id & mask * <received_can_id> & mask == can_id & mask
* *
* The filter can be inverted (CAN_INV_FILTER bit set in can_id) or it can * The filter can be inverted (CAN_INV_FILTER bit set in can_id) or it can
* filter for error frames (CAN_ERR_FLAG bit set in mask). * filter for error message frames (CAN_ERR_FLAG bit set in mask).
*/ */
struct can_filter { struct can_filter {
canid_t can_id; canid_t can_id;
......
/* /*
* linux/can/error.h * linux/can/error.h
* *
* Definitions of the CAN error frame to be filtered and passed to the user. * Definitions of the CAN error messages to be filtered and passed to the user.
* *
* Author: Oliver Hartkopp <oliver.hartkopp@volkswagen.de> * Author: Oliver Hartkopp <oliver.hartkopp@volkswagen.de>
* Copyright (c) 2002-2007 Volkswagen Group Electronic Research * Copyright (c) 2002-2007 Volkswagen Group Electronic Research
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
#ifndef CAN_ERROR_H #ifndef CAN_ERROR_H
#define CAN_ERROR_H #define CAN_ERROR_H
#define CAN_ERR_DLC 8 /* dlc for error frames */ #define CAN_ERR_DLC 8 /* dlc for error message frames */
/* error class (mask) in can_id */ /* error class (mask) in can_id */
#define CAN_ERR_TX_TIMEOUT 0x00000001U /* TX timeout (by netdevice driver) */ #define CAN_ERR_TX_TIMEOUT 0x00000001U /* TX timeout (by netdevice driver) */
......
...@@ -334,8 +334,8 @@ static struct dev_rcv_lists *find_dev_rcv_lists(struct net_device *dev) ...@@ -334,8 +334,8 @@ static struct dev_rcv_lists *find_dev_rcv_lists(struct net_device *dev)
* relevant bits for the filter. * relevant bits for the filter.
* *
* The filter can be inverted (CAN_INV_FILTER bit set in can_id) or it can * The filter can be inverted (CAN_INV_FILTER bit set in can_id) or it can
* filter for error frames (CAN_ERR_FLAG bit set in mask). For error frames * filter for error messages (CAN_ERR_FLAG bit set in mask). For error msg
* there is a special filterlist and a special rx path filter handling. * frames there is a special filterlist and a special rx path filter handling.
* *
* Return: * Return:
* Pointer to optimal filterlist for the given can_id/mask pair. * Pointer to optimal filterlist for the given can_id/mask pair.
...@@ -347,7 +347,7 @@ static struct hlist_head *find_rcv_list(canid_t *can_id, canid_t *mask, ...@@ -347,7 +347,7 @@ static struct hlist_head *find_rcv_list(canid_t *can_id, canid_t *mask,
{ {
canid_t inv = *can_id & CAN_INV_FILTER; /* save flag before masking */ canid_t inv = *can_id & CAN_INV_FILTER; /* save flag before masking */
/* filter for error frames in extra filterlist */ /* filter for error message frames in extra filterlist */
if (*mask & CAN_ERR_FLAG) { if (*mask & CAN_ERR_FLAG) {
/* clear CAN_ERR_FLAG in filter entry */ /* clear CAN_ERR_FLAG in filter entry */
*mask &= CAN_ERR_MASK; *mask &= CAN_ERR_MASK;
...@@ -408,7 +408,7 @@ static struct hlist_head *find_rcv_list(canid_t *can_id, canid_t *mask, ...@@ -408,7 +408,7 @@ static struct hlist_head *find_rcv_list(canid_t *can_id, canid_t *mask,
* <received_can_id> & mask == can_id & mask * <received_can_id> & mask == can_id & mask
* *
* The filter can be inverted (CAN_INV_FILTER bit set in can_id) or it can * The filter can be inverted (CAN_INV_FILTER bit set in can_id) or it can
* filter for error frames (CAN_ERR_FLAG bit set in mask). * filter for error message frames (CAN_ERR_FLAG bit set in mask).
* *
* The provided pointer to the sk_buff is guaranteed to be valid as long as * The provided pointer to the sk_buff is guaranteed to be valid as long as
* the callback function is running. The callback function must *not* free * the callback function is running. The callback function must *not* free
...@@ -578,7 +578,7 @@ static int can_rcv_filter(struct dev_rcv_lists *d, struct sk_buff *skb) ...@@ -578,7 +578,7 @@ static int can_rcv_filter(struct dev_rcv_lists *d, struct sk_buff *skb)
return 0; return 0;
if (can_id & CAN_ERR_FLAG) { if (can_id & CAN_ERR_FLAG) {
/* check for error frame entries only */ /* check for error message frame entries only */
hlist_for_each_entry_rcu(r, n, &d->rx[RX_ERR], list) { hlist_for_each_entry_rcu(r, n, &d->rx[RX_ERR], list) {
if (can_id & r->mask) { if (can_id & r->mask) {
deliver(skb, r); deliver(skb, r);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment