* [RFC v2 0/7] pch_can/c_can: fix races and add PCH support to c_can
@ 2012-11-29 14:39 Wolfgang Grandegger
2012-11-29 14:39 ` [RFC v2 1/7] pch_can: add spinlocks to protect tx objects Wolfgang Grandegger
` (7 more replies)
0 siblings, 8 replies; 38+ messages in thread
From: Wolfgang Grandegger @ 2012-11-29 14:39 UTC (permalink / raw)
To: linux-can; +Cc: bhupesh.sharma, tomoya.rohm, Wolfgang Grandegger
Hello,
here is v2 of my patches for the C_CAN drivers.
For Michael I have prepared out-of-tree driver sources allowing to
easily build the drivers also for older 3.x kernel versions. More
tester are welcome.
Changes since v1:
- use init callback after renaming it from initram
- use different sets of interface registers for rx and tx (like PCH_CAN)
- use spin_[un]lock_bh to protect the tx objects
Wolfgang Grandegger (7):
pch_can: add spinlocks to protect tx objects
c_can: rename callback "initram" to "init" to more general usage
c_can: use different sets of interface registers for rx and tx
c_can_pci: introduce board specific PCI bar
c_can_pci: enable PCI bus master only for MSI
c_can_pci: add support for PCH CAN on Intel EG20T PCH
c_can: add spinlock to protect tx and objects
drivers/net/can/c_can/c_can.c | 66 +++++++++++++++++++++-----------
drivers/net/can/c_can/c_can.h | 3 +-
drivers/net/can/c_can/c_can_pci.c | 56 +++++++++++++++++++++++++--
drivers/net/can/c_can/c_can_platform.c | 2 +-
drivers/net/can/pch_can.c | 9 +++++
5 files changed, 108 insertions(+), 28 deletions(-)
--
1.7.9.5
^ permalink raw reply [flat|nested] 38+ messages in thread* [RFC v2 1/7] pch_can: add spinlocks to protect tx objects 2012-11-29 14:39 [RFC v2 0/7] pch_can/c_can: fix races and add PCH support to c_can Wolfgang Grandegger @ 2012-11-29 14:39 ` Wolfgang Grandegger 2012-11-29 14:39 ` [RFC v2 2/7] c_can: rename callback "initram" to "init" to more general usage Wolfgang Grandegger ` (6 subsequent siblings) 7 siblings, 0 replies; 38+ messages in thread From: Wolfgang Grandegger @ 2012-11-29 14:39 UTC (permalink / raw) To: linux-can; +Cc: bhupesh.sharma, tomoya.rohm, Wolfgang Grandegger Signed-off-by: Wolfgang Grandegger <wg@grandegger.com> --- drivers/net/can/pch_can.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index 48b3d62..442a04f 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c @@ -182,6 +182,7 @@ struct pch_can_priv { struct napi_struct napi; int tx_obj; /* Point next Tx Obj index */ int use_msi; + spinlock_t lock; /* to protect tx objects */ }; static const struct can_bittiming_const pch_can_bittiming_const = { @@ -724,6 +725,8 @@ static void pch_can_tx_complete(struct net_device *ndev, u32 int_stat) struct net_device_stats *stats = &(priv->ndev->stats); u32 dlc; + spin_lock_bh(&priv->lock); + can_get_echo_skb(ndev, int_stat - PCH_RX_OBJ_END - 1); iowrite32(PCH_CMASK_RX_TX_GET | PCH_CMASK_CLRINTPND, &priv->regs->ifregs[1].cmask); @@ -734,6 +737,8 @@ static void pch_can_tx_complete(struct net_device *ndev, u32 int_stat) stats->tx_packets++; if (int_stat == PCH_TX_OBJ_END) netif_wake_queue(ndev); + + spin_unlock_bh(&priv->lock); } static int pch_can_poll(struct napi_struct *napi, int quota) @@ -901,6 +906,8 @@ static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev) if (can_dropped_invalid_skb(ndev, skb)) return NETDEV_TX_OK; + spin_lock_bh(&priv->lock); + tx_obj_no = priv->tx_obj; if (priv->tx_obj == PCH_TX_OBJ_END) { if (ioread32(&priv->regs->treq2) & PCH_TREQ2_TX_MASK) @@ -911,6 +918,8 @@ static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev) priv->tx_obj++; } + spin_unlock_bh(&priv->lock); + /* Setting the CMASK register. */ pch_can_bit_set(&priv->regs->ifregs[1].cmask, PCH_CMASK_ALL); -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 38+ messages in thread
* [RFC v2 2/7] c_can: rename callback "initram" to "init" to more general usage 2012-11-29 14:39 [RFC v2 0/7] pch_can/c_can: fix races and add PCH support to c_can Wolfgang Grandegger 2012-11-29 14:39 ` [RFC v2 1/7] pch_can: add spinlocks to protect tx objects Wolfgang Grandegger @ 2012-11-29 14:39 ` Wolfgang Grandegger 2012-12-03 14:20 ` Alexander Stein 2012-11-29 14:39 ` [RFC v2 3/7] c_can: use different sets of interface registers for rx and tx Wolfgang Grandegger ` (5 subsequent siblings) 7 siblings, 1 reply; 38+ messages in thread From: Wolfgang Grandegger @ 2012-11-29 14:39 UTC (permalink / raw) To: linux-can; +Cc: bhupesh.sharma, tomoya.rohm, Wolfgang Grandegger The callback "init" is called with the argument "true" when the device is opened and with "false" when it is closed allowing for device specific initialization and cleanup, e.g. raminit or reset. Signed-off-by: Wolfgang Grandegger <wg@grandegger.com> --- drivers/net/can/c_can/c_can.c | 16 ++++++++-------- drivers/net/can/c_can/c_can.h | 2 +- drivers/net/can/c_can/c_can_platform.c | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c index 5233b8f..3ae356f 100644 --- a/drivers/net/can/c_can/c_can.c +++ b/drivers/net/can/c_can/c_can.c @@ -233,10 +233,10 @@ static inline void c_can_pm_runtime_put_sync(const struct c_can_priv *priv) pm_runtime_put_sync(priv->device); } -static inline void c_can_reset_ram(const struct c_can_priv *priv, bool enable) +static inline void c_can_init(const struct c_can_priv *priv, bool enable) { - if (priv->raminit) - priv->raminit(priv, enable); + if (priv->init) + priv->init(priv, enable); } static inline int get_tx_next_msg_obj(const struct c_can_priv *priv) @@ -1096,7 +1096,7 @@ static int c_can_open(struct net_device *dev) struct c_can_priv *priv = netdev_priv(dev); c_can_pm_runtime_get_sync(priv); - c_can_reset_ram(priv, true); + c_can_init(priv, true); /* open the can device */ err = open_candev(dev); @@ -1125,7 +1125,7 @@ static int c_can_open(struct net_device *dev) exit_irq_fail: close_candev(dev); exit_open_fail: - c_can_reset_ram(priv, false); + c_can_init(priv, false); c_can_pm_runtime_put_sync(priv); return err; } @@ -1140,7 +1140,7 @@ static int c_can_close(struct net_device *dev) free_irq(dev->irq, dev); close_candev(dev); - c_can_reset_ram(priv, false); + c_can_init(priv, false); c_can_pm_runtime_put_sync(priv); return 0; @@ -1198,7 +1198,7 @@ int c_can_power_down(struct net_device *dev) c_can_stop(dev); - c_can_reset_ram(priv, false); + c_can_init(priv, false); c_can_pm_runtime_put_sync(priv); return 0; @@ -1217,7 +1217,7 @@ int c_can_power_up(struct net_device *dev) WARN_ON(priv->type != BOSCH_D_CAN); c_can_pm_runtime_get_sync(priv); - c_can_reset_ram(priv, true); + c_can_init(priv, true); /* Clear PDR and INIT bits */ val = priv->read_reg(priv, C_CAN_CTRL_EX_REG); diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h index d2e1c21..4baf3f6 100644 --- a/drivers/net/can/c_can/c_can.h +++ b/drivers/net/can/c_can/c_can.h @@ -171,7 +171,7 @@ struct c_can_priv { enum c_can_dev_id type; u32 __iomem *raminit_ctrlreg; unsigned int instance; - void (*raminit) (const struct c_can_priv *priv, bool enable); + void (*init) (const struct c_can_priv *priv, bool enable); }; struct net_device *alloc_c_can_dev(void); diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c index 0044fd8..5619b9c 100644 --- a/drivers/net/can/c_can/c_can_platform.c +++ b/drivers/net/can/c_can/c_can_platform.c @@ -205,7 +205,7 @@ static int __devinit c_can_plat_probe(struct platform_device *pdev) if (!priv->raminit_ctrlreg || priv->instance < 0) dev_info(&pdev->dev, "control memory is not used for raminit\n"); else - priv->raminit = c_can_hw_raminit; + priv->init = c_can_hw_raminit; break; default: ret = -EINVAL; -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 38+ messages in thread
* Re: [RFC v2 2/7] c_can: rename callback "initram" to "init" to more general usage 2012-11-29 14:39 ` [RFC v2 2/7] c_can: rename callback "initram" to "init" to more general usage Wolfgang Grandegger @ 2012-12-03 14:20 ` Alexander Stein 2012-12-03 14:32 ` Wolfgang Grandegger 0 siblings, 1 reply; 38+ messages in thread From: Alexander Stein @ 2012-12-03 14:20 UTC (permalink / raw) To: Wolfgang Grandegger; +Cc: linux-can, bhupesh.sharma, tomoya.rohm Hello Wolfgang, On Thursday 29 November 2012 15:39:42, Wolfgang Grandegger wrote: > The callback "init" is called with the argument "true" when the > device is opened and with "false" when it is closed allowing for > device specific initialization and cleanup, e.g. raminit or reset. > > Signed-off-by: Wolfgang Grandegger <wg@grandegger.com> > --- > drivers/net/can/c_can/c_can.c | 16 ++++++++-------- > drivers/net/can/c_can/c_can.h | 2 +- > drivers/net/can/c_can/c_can_platform.c | 2 +- > 3 files changed, 10 insertions(+), 10 deletions(-) > > diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c > index 5233b8f..3ae356f 100644 > --- a/drivers/net/can/c_can/c_can.c > +++ b/drivers/net/can/c_can/c_can.c > @@ -233,10 +233,10 @@ static inline void c_can_pm_runtime_put_sync(const struct c_can_priv *priv) > pm_runtime_put_sync(priv->device); > } > > -static inline void c_can_reset_ram(const struct c_can_priv *priv, bool enable) Where does c_can_reset_ram come from? I can't a patch to it in Linus' tree nor in linux-can repository. Regards, Alexander ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC v2 2/7] c_can: rename callback "initram" to "init" to more general usage 2012-12-03 14:20 ` Alexander Stein @ 2012-12-03 14:32 ` Wolfgang Grandegger 0 siblings, 0 replies; 38+ messages in thread From: Wolfgang Grandegger @ 2012-12-03 14:32 UTC (permalink / raw) To: Alexander Stein; +Cc: linux-can, bhupesh.sharma, tomoya.rohm On 12/03/2012 03:20 PM, Alexander Stein wrote: > Hello Wolfgang, > > On Thursday 29 November 2012 15:39:42, Wolfgang Grandegger wrote: >> The callback "init" is called with the argument "true" when the >> device is opened and with "false" when it is closed allowing for >> device specific initialization and cleanup, e.g. raminit or reset. >> >> Signed-off-by: Wolfgang Grandegger <wg@grandegger.com> >> --- >> drivers/net/can/c_can/c_can.c | 16 ++++++++-------- >> drivers/net/can/c_can/c_can.h | 2 +- >> drivers/net/can/c_can/c_can_platform.c | 2 +- >> 3 files changed, 10 insertions(+), 10 deletions(-) >> >> diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c >> index 5233b8f..3ae356f 100644 >> --- a/drivers/net/can/c_can/c_can.c >> +++ b/drivers/net/can/c_can/c_can.c >> @@ -233,10 +233,10 @@ static inline void c_can_pm_runtime_put_sync(const struct c_can_priv *priv) >> pm_runtime_put_sync(priv->device); >> } >> >> -static inline void c_can_reset_ram(const struct c_can_priv *priv, bool enable) > > Where does c_can_reset_ram come from? I can't a patch to it in Linus' tree nor in linux-can repository. It is in the net-next tree and patches have been posted to this list. commit 52cde85acc23f61b09dd0376c61eb891125c6990 Author: AnilKumar Ch <anilkumar@ti.com> Date: Wed Nov 21 11:14:10 2012 +0530 can: c_can: Add d_can raminit support Add D_CAN raminit support to C_CAN driver to enable D_CAN RAM, which holds all the message objects during transmission or receiving of data. This initialization/de-initialization should be done in synchronous with D_CAN clock. In case of AM335X-EVM (current user of D_CAN driver) message RAM is controlled through control module register for both instances. So control module register details is required to initialization or de-initialization of message RAM according to instance number. Control module memory resource is obtained from D_CAN dt node and instance number obtained from device tree aliases node. This patch was tested on AM335x-EVM along with pinctrl data addition patch, d_can dt aliases addition and control module data addition. pinctrl data addition is not added to am335x-evm.dts (only supports CPLD profile#0) because d_can1 is supported under CPLD profile#1. Signed-off-by: AnilKumar Ch <anilkumar@ti.com> [mkl: fix instance for non DT in probe, cleaned up raminit] Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> Wolfgang. ^ permalink raw reply [flat|nested] 38+ messages in thread
* [RFC v2 3/7] c_can: use different sets of interface registers for rx and tx 2012-11-29 14:39 [RFC v2 0/7] pch_can/c_can: fix races and add PCH support to c_can Wolfgang Grandegger 2012-11-29 14:39 ` [RFC v2 1/7] pch_can: add spinlocks to protect tx objects Wolfgang Grandegger 2012-11-29 14:39 ` [RFC v2 2/7] c_can: rename callback "initram" to "init" to more general usage Wolfgang Grandegger @ 2012-11-29 14:39 ` Wolfgang Grandegger 2012-11-30 8:39 ` Marc Kleine-Budde 2012-11-29 14:39 ` [RFC v2 4/7] c_can_pci: introduce board specific PCI bar Wolfgang Grandegger ` (4 subsequent siblings) 7 siblings, 1 reply; 38+ messages in thread From: Wolfgang Grandegger @ 2012-11-29 14:39 UTC (permalink / raw) To: linux-can; +Cc: bhupesh.sharma, tomoya.rohm, Wolfgang Grandegger To avoid conflicts between CPU access to the message RAM we now use the first set of interface registers for RX and the second for TX. Signed-off-by: Wolfgang Grandegger <wg@grandegger.com> --- drivers/net/can/c_can/c_can.c | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c index 3ae356f..27e45e6 100644 --- a/drivers/net/can/c_can/c_can.c +++ b/drivers/net/can/c_can/c_can.c @@ -158,6 +158,10 @@ #define C_CAN_NEXT_MSG_OBJ_MASK (C_CAN_MSG_OBJ_TX_NUM - 1) #define RECEIVE_OBJECT_BITS 0x0000ffff +/* message interface used for rx and tx */ +#define IFACE_RX 0 +#define IFACE_TX 1 + /* status interrupt */ #define STATUS_INTERRUPT 0x8000 @@ -544,7 +548,7 @@ static netdev_tx_t c_can_start_xmit(struct sk_buff *skb, msg_obj_no = get_tx_next_msg_obj(priv); /* prepare message object for transmission */ - c_can_write_msg_object(dev, 0, frame, msg_obj_no); + c_can_write_msg_object(dev, IFACE_TX, frame, msg_obj_no); can_put_echo_skb(skb, dev, msg_obj_no - C_CAN_MSG_OBJ_TX_FIRST); /* @@ -606,16 +610,18 @@ static void c_can_configure_msg_objects(struct net_device *dev) int i; /* first invalidate all message objects */ - for (i = C_CAN_MSG_OBJ_RX_FIRST; i <= C_CAN_NO_OF_OBJECTS; i++) - c_can_inval_msg_object(dev, 0, i); + for (i = C_CAN_MSG_OBJ_RX_FIRST; i <= C_CAN_MSG_OBJ_RX_LAST; i++) + c_can_inval_msg_object(dev, IFACE_RX, i); + for (i = C_CAN_MSG_OBJ_TX_FIRST; i <= C_CAN_MSG_OBJ_TX_LAST; i++) + c_can_inval_msg_object(dev, IFACE_TX, i); /* setup receive message objects */ for (i = C_CAN_MSG_OBJ_RX_FIRST; i < C_CAN_MSG_OBJ_RX_LAST; i++) - c_can_setup_receive_object(dev, 0, i, 0, 0, + c_can_setup_receive_object(dev, IFACE_RX, i, 0, 0, (IF_MCONT_RXIE | IF_MCONT_UMASK) & ~IF_MCONT_EOB); - c_can_setup_receive_object(dev, 0, C_CAN_MSG_OBJ_RX_LAST, 0, 0, - IF_MCONT_EOB | IF_MCONT_RXIE | IF_MCONT_UMASK); + c_can_setup_receive_object(dev, IFACE_RX, C_CAN_MSG_OBJ_RX_LAST, + 0, 0, IF_MCONT_EOB | IF_MCONT_RXIE | IF_MCONT_UMASK); } /* @@ -748,10 +754,10 @@ static void c_can_do_tx(struct net_device *dev) can_get_echo_skb(dev, msg_obj_no - C_CAN_MSG_OBJ_TX_FIRST); stats->tx_bytes += priv->read_reg(priv, - C_CAN_IFACE(MSGCTRL_REG, 0)) + C_CAN_IFACE(MSGCTRL_REG, IFACE_TX)) & IF_MCONT_DLC_MASK; stats->tx_packets++; - c_can_inval_msg_object(dev, 0, msg_obj_no); + c_can_inval_msg_object(dev, IFACE_TX, msg_obj_no); } else { break; } @@ -801,16 +807,17 @@ static int c_can_do_rx_poll(struct net_device *dev, int quota) * message object n, we need to handle the same properly. */ if (val & (1 << (msg_obj - 1))) { - c_can_object_get(dev, 0, msg_obj, IF_COMM_ALL & + c_can_object_get(dev, IFACE_RX, msg_obj, IF_COMM_ALL & ~IF_COMM_TXRQST); msg_ctrl_save = priv->read_reg(priv, - C_CAN_IFACE(MSGCTRL_REG, 0)); + C_CAN_IFACE(MSGCTRL_REG, IFACE_RX)); if (msg_ctrl_save & IF_MCONT_EOB) return num_rx_pkts; if (msg_ctrl_save & IF_MCONT_MSGLST) { - c_can_handle_lost_msg_obj(dev, 0, msg_obj); + c_can_handle_lost_msg_obj(dev, IFACE_RX, + msg_obj); num_rx_pkts++; quota--; continue; @@ -820,19 +827,19 @@ static int c_can_do_rx_poll(struct net_device *dev, int quota) continue; /* read the data from the message object */ - c_can_read_msg_object(dev, 0, msg_ctrl_save); + c_can_read_msg_object(dev, IFACE_RX, msg_ctrl_save); if (msg_obj < C_CAN_MSG_RX_LOW_LAST) - c_can_mark_rx_msg_obj(dev, 0, + c_can_mark_rx_msg_obj(dev, IFACE_RX, msg_ctrl_save, msg_obj); else if (msg_obj > C_CAN_MSG_RX_LOW_LAST) /* activate this msg obj */ - c_can_activate_rx_msg_obj(dev, 0, + c_can_activate_rx_msg_obj(dev, IFACE_RX, msg_ctrl_save, msg_obj); else if (msg_obj == C_CAN_MSG_RX_LOW_LAST) /* activate all lower message objects */ c_can_activate_all_lower_rx_msg_obj(dev, - 0, msg_ctrl_save); + IFACE_RX, msg_ctrl_save); num_rx_pkts++; quota--; -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 38+ messages in thread
* Re: [RFC v2 3/7] c_can: use different sets of interface registers for rx and tx 2012-11-29 14:39 ` [RFC v2 3/7] c_can: use different sets of interface registers for rx and tx Wolfgang Grandegger @ 2012-11-30 8:39 ` Marc Kleine-Budde 2012-11-30 9:15 ` Wolfgang Grandegger 0 siblings, 1 reply; 38+ messages in thread From: Marc Kleine-Budde @ 2012-11-30 8:39 UTC (permalink / raw) To: Wolfgang Grandegger; +Cc: linux-can, bhupesh.sharma, tomoya.rohm [-- Attachment #1: Type: text/plain, Size: 4953 bytes --] On 11/29/2012 03:39 PM, Wolfgang Grandegger wrote: > To avoid conflicts between CPU access to the message RAM we now > use the first set of interface registers for RX and the second > for TX. > > Signed-off-by: Wolfgang Grandegger <wg@grandegger.com> > --- > drivers/net/can/c_can/c_can.c | 37 ++++++++++++++++++++++--------------- > 1 file changed, 22 insertions(+), 15 deletions(-) > > diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c > index 3ae356f..27e45e6 100644 > --- a/drivers/net/can/c_can/c_can.c > +++ b/drivers/net/can/c_can/c_can.c > @@ -158,6 +158,10 @@ > #define C_CAN_NEXT_MSG_OBJ_MASK (C_CAN_MSG_OBJ_TX_NUM - 1) > #define RECEIVE_OBJECT_BITS 0x0000ffff > > +/* message interface used for rx and tx */ > +#define IFACE_RX 0 > +#define IFACE_TX 1 Can you give these defines a common C_CAN_ prefix? And you can make them an enum and change the signature of the function you're changing below. Marc > + > /* status interrupt */ > #define STATUS_INTERRUPT 0x8000 > > @@ -544,7 +548,7 @@ static netdev_tx_t c_can_start_xmit(struct sk_buff *skb, > msg_obj_no = get_tx_next_msg_obj(priv); > > /* prepare message object for transmission */ > - c_can_write_msg_object(dev, 0, frame, msg_obj_no); > + c_can_write_msg_object(dev, IFACE_TX, frame, msg_obj_no); > can_put_echo_skb(skb, dev, msg_obj_no - C_CAN_MSG_OBJ_TX_FIRST); > > /* > @@ -606,16 +610,18 @@ static void c_can_configure_msg_objects(struct net_device *dev) > int i; > > /* first invalidate all message objects */ > - for (i = C_CAN_MSG_OBJ_RX_FIRST; i <= C_CAN_NO_OF_OBJECTS; i++) > - c_can_inval_msg_object(dev, 0, i); > + for (i = C_CAN_MSG_OBJ_RX_FIRST; i <= C_CAN_MSG_OBJ_RX_LAST; i++) > + c_can_inval_msg_object(dev, IFACE_RX, i); > + for (i = C_CAN_MSG_OBJ_TX_FIRST; i <= C_CAN_MSG_OBJ_TX_LAST; i++) > + c_can_inval_msg_object(dev, IFACE_TX, i); > > /* setup receive message objects */ > for (i = C_CAN_MSG_OBJ_RX_FIRST; i < C_CAN_MSG_OBJ_RX_LAST; i++) > - c_can_setup_receive_object(dev, 0, i, 0, 0, > + c_can_setup_receive_object(dev, IFACE_RX, i, 0, 0, > (IF_MCONT_RXIE | IF_MCONT_UMASK) & ~IF_MCONT_EOB); > > - c_can_setup_receive_object(dev, 0, C_CAN_MSG_OBJ_RX_LAST, 0, 0, > - IF_MCONT_EOB | IF_MCONT_RXIE | IF_MCONT_UMASK); > + c_can_setup_receive_object(dev, IFACE_RX, C_CAN_MSG_OBJ_RX_LAST, > + 0, 0, IF_MCONT_EOB | IF_MCONT_RXIE | IF_MCONT_UMASK); > } > > /* > @@ -748,10 +754,10 @@ static void c_can_do_tx(struct net_device *dev) > can_get_echo_skb(dev, > msg_obj_no - C_CAN_MSG_OBJ_TX_FIRST); > stats->tx_bytes += priv->read_reg(priv, > - C_CAN_IFACE(MSGCTRL_REG, 0)) > + C_CAN_IFACE(MSGCTRL_REG, IFACE_TX)) > & IF_MCONT_DLC_MASK; > stats->tx_packets++; > - c_can_inval_msg_object(dev, 0, msg_obj_no); > + c_can_inval_msg_object(dev, IFACE_TX, msg_obj_no); > } else { > break; > } > @@ -801,16 +807,17 @@ static int c_can_do_rx_poll(struct net_device *dev, int quota) > * message object n, we need to handle the same properly. > */ > if (val & (1 << (msg_obj - 1))) { > - c_can_object_get(dev, 0, msg_obj, IF_COMM_ALL & > + c_can_object_get(dev, IFACE_RX, msg_obj, IF_COMM_ALL & > ~IF_COMM_TXRQST); > msg_ctrl_save = priv->read_reg(priv, > - C_CAN_IFACE(MSGCTRL_REG, 0)); > + C_CAN_IFACE(MSGCTRL_REG, IFACE_RX)); > > if (msg_ctrl_save & IF_MCONT_EOB) > return num_rx_pkts; > > if (msg_ctrl_save & IF_MCONT_MSGLST) { > - c_can_handle_lost_msg_obj(dev, 0, msg_obj); > + c_can_handle_lost_msg_obj(dev, IFACE_RX, > + msg_obj); > num_rx_pkts++; > quota--; > continue; > @@ -820,19 +827,19 @@ static int c_can_do_rx_poll(struct net_device *dev, int quota) > continue; > > /* read the data from the message object */ > - c_can_read_msg_object(dev, 0, msg_ctrl_save); > + c_can_read_msg_object(dev, IFACE_RX, msg_ctrl_save); > > if (msg_obj < C_CAN_MSG_RX_LOW_LAST) > - c_can_mark_rx_msg_obj(dev, 0, > + c_can_mark_rx_msg_obj(dev, IFACE_RX, > msg_ctrl_save, msg_obj); > else if (msg_obj > C_CAN_MSG_RX_LOW_LAST) > /* activate this msg obj */ > - c_can_activate_rx_msg_obj(dev, 0, > + c_can_activate_rx_msg_obj(dev, IFACE_RX, > msg_ctrl_save, msg_obj); > else if (msg_obj == C_CAN_MSG_RX_LOW_LAST) > /* activate all lower message objects */ > c_can_activate_all_lower_rx_msg_obj(dev, > - 0, msg_ctrl_save); > + IFACE_RX, msg_ctrl_save); > > num_rx_pkts++; > quota--; > -- Pengutronix e.K. | Marc Kleine-Budde | Industrial Linux Solutions | Phone: +49-231-2826-924 | Vertretung West/Dortmund | Fax: +49-5121-206917-5555 | Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de | [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 261 bytes --] ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC v2 3/7] c_can: use different sets of interface registers for rx and tx 2012-11-30 8:39 ` Marc Kleine-Budde @ 2012-11-30 9:15 ` Wolfgang Grandegger 0 siblings, 0 replies; 38+ messages in thread From: Wolfgang Grandegger @ 2012-11-30 9:15 UTC (permalink / raw) To: Marc Kleine-Budde; +Cc: linux-can, bhupesh.sharma, tomoya.rohm On 11/30/2012 09:39 AM, Marc Kleine-Budde wrote: > On 11/29/2012 03:39 PM, Wolfgang Grandegger wrote: >> To avoid conflicts between CPU access to the message RAM we now >> use the first set of interface registers for RX and the second >> for TX. >> >> Signed-off-by: Wolfgang Grandegger <wg@grandegger.com> >> --- >> drivers/net/can/c_can/c_can.c | 37 ++++++++++++++++++++++--------------- >> 1 file changed, 22 insertions(+), 15 deletions(-) >> >> diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c >> index 3ae356f..27e45e6 100644 >> --- a/drivers/net/can/c_can/c_can.c >> +++ b/drivers/net/can/c_can/c_can.c >> @@ -158,6 +158,10 @@ >> #define C_CAN_NEXT_MSG_OBJ_MASK (C_CAN_MSG_OBJ_TX_NUM - 1) >> #define RECEIVE_OBJECT_BITS 0x0000ffff >> >> +/* message interface used for rx and tx */ >> +#define IFACE_RX 0 >> +#define IFACE_TX 1 > > Can you give these defines a common C_CAN_ prefix? And you can make them > an enum and change the signature of the function you're changing below. OK, will do with the next version. Want to be sure that the driver works as expected first. Wolfgang ^ permalink raw reply [flat|nested] 38+ messages in thread
* [RFC v2 4/7] c_can_pci: introduce board specific PCI bar 2012-11-29 14:39 [RFC v2 0/7] pch_can/c_can: fix races and add PCH support to c_can Wolfgang Grandegger ` (2 preceding siblings ...) 2012-11-29 14:39 ` [RFC v2 3/7] c_can: use different sets of interface registers for rx and tx Wolfgang Grandegger @ 2012-11-29 14:39 ` Wolfgang Grandegger 2012-11-30 8:45 ` Marc Kleine-Budde 2012-11-29 14:39 ` [RFC v2 5/7] c_can_pci: enable PCI bus master only for MSI Wolfgang Grandegger ` (3 subsequent siblings) 7 siblings, 1 reply; 38+ messages in thread From: Wolfgang Grandegger @ 2012-11-29 14:39 UTC (permalink / raw) To: linux-can; +Cc: bhupesh.sharma, tomoya.rohm, Wolfgang Grandegger Also fix minor issue with pci_iomap specifying size 0 for mapping the full range. Signed-off-by: Wolfgang Grandegger <wg@grandegger.com> --- drivers/net/can/c_can/c_can_pci.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/c_can/c_can_pci.c b/drivers/net/can/c_can/c_can_pci.c index 3d7830b..7b73f90 100644 --- a/drivers/net/can/c_can/c_can_pci.c +++ b/drivers/net/can/c_can/c_can_pci.c @@ -31,6 +31,8 @@ struct c_can_pci_data { enum c_can_pci_reg_align reg_align; /* Set the frequency */ unsigned int freq; + /* PCI bar number */ + int bar; }; /* @@ -87,7 +89,7 @@ static int __devinit c_can_pci_probe(struct pci_dev *pdev, pci_set_master(pdev); pci_enable_msi(pdev); - addr = pci_iomap(pdev, 0, pci_resource_len(pdev, 0)); + addr = pci_iomap(pdev, c_can_pci_data->bar, 0); if (!addr) { dev_err(&pdev->dev, "device has no PCI memory resources, " @@ -195,6 +197,7 @@ static struct c_can_pci_data c_can_sta2x11= { .type = BOSCH_C_CAN, .reg_align = C_CAN_REG_ALIGN_32, .freq = 52000000, /* 52 Mhz */ + .bar = 0, }; #define C_CAN_ID(_vend, _dev, _driverdata) { \ -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 38+ messages in thread
* Re: [RFC v2 4/7] c_can_pci: introduce board specific PCI bar 2012-11-29 14:39 ` [RFC v2 4/7] c_can_pci: introduce board specific PCI bar Wolfgang Grandegger @ 2012-11-30 8:45 ` Marc Kleine-Budde 2012-11-30 9:11 ` Wolfgang Grandegger 0 siblings, 1 reply; 38+ messages in thread From: Marc Kleine-Budde @ 2012-11-30 8:45 UTC (permalink / raw) To: Wolfgang Grandegger; +Cc: linux-can, bhupesh.sharma, tomoya.rohm [-- Attachment #1: Type: text/plain, Size: 1835 bytes --] On 11/29/2012 03:39 PM, Wolfgang Grandegger wrote: > Also fix minor issue with pci_iomap specifying size 0 for > mapping the full range. If I understand the code correct, using pci_resource_len(pdev, 0) for the max len (of BAR 0) instead of 0 isn't a bug, it's just more complicated than it needs to be. If it really is a bug, I think a separate patch will be good. Marc > > Signed-off-by: Wolfgang Grandegger <wg@grandegger.com> > --- > drivers/net/can/c_can/c_can_pci.c | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > > diff --git a/drivers/net/can/c_can/c_can_pci.c b/drivers/net/can/c_can/c_can_pci.c > index 3d7830b..7b73f90 100644 > --- a/drivers/net/can/c_can/c_can_pci.c > +++ b/drivers/net/can/c_can/c_can_pci.c > @@ -31,6 +31,8 @@ struct c_can_pci_data { > enum c_can_pci_reg_align reg_align; > /* Set the frequency */ > unsigned int freq; > + /* PCI bar number */ > + int bar; > }; > > /* > @@ -87,7 +89,7 @@ static int __devinit c_can_pci_probe(struct pci_dev *pdev, > pci_set_master(pdev); > pci_enable_msi(pdev); > > - addr = pci_iomap(pdev, 0, pci_resource_len(pdev, 0)); > + addr = pci_iomap(pdev, c_can_pci_data->bar, 0); > if (!addr) { > dev_err(&pdev->dev, > "device has no PCI memory resources, " > @@ -195,6 +197,7 @@ static struct c_can_pci_data c_can_sta2x11= { > .type = BOSCH_C_CAN, > .reg_align = C_CAN_REG_ALIGN_32, > .freq = 52000000, /* 52 Mhz */ > + .bar = 0, > }; > > #define C_CAN_ID(_vend, _dev, _driverdata) { \ > -- Pengutronix e.K. | Marc Kleine-Budde | Industrial Linux Solutions | Phone: +49-231-2826-924 | Vertretung West/Dortmund | Fax: +49-5121-206917-5555 | Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de | [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 261 bytes --] ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC v2 4/7] c_can_pci: introduce board specific PCI bar 2012-11-30 8:45 ` Marc Kleine-Budde @ 2012-11-30 9:11 ` Wolfgang Grandegger 2012-11-30 9:19 ` Marc Kleine-Budde 0 siblings, 1 reply; 38+ messages in thread From: Wolfgang Grandegger @ 2012-11-30 9:11 UTC (permalink / raw) To: Marc Kleine-Budde; +Cc: linux-can, bhupesh.sharma, tomoya.rohm On 11/30/2012 09:45 AM, Marc Kleine-Budde wrote: > On 11/29/2012 03:39 PM, Wolfgang Grandegger wrote: >> Also fix minor issue with pci_iomap specifying size 0 for >> mapping the full range. > > If I understand the code correct, using pci_resource_len(pdev, 0) for > the max len (of BAR 0) instead of 0 isn't a bug, it's just more > complicated than it needs to be. If it really is a bug, I think a > separate patch will be good. It's a minor issue, not a bug. Both do the same thing. See: http://lxr.linux.no/#linux+v3.6.8/lib/pci_iomap.c#L23 Wolfgang. ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC v2 4/7] c_can_pci: introduce board specific PCI bar 2012-11-30 9:11 ` Wolfgang Grandegger @ 2012-11-30 9:19 ` Marc Kleine-Budde 0 siblings, 0 replies; 38+ messages in thread From: Marc Kleine-Budde @ 2012-11-30 9:19 UTC (permalink / raw) To: Wolfgang Grandegger; +Cc: linux-can, bhupesh.sharma, tomoya.rohm [-- Attachment #1: Type: text/plain, Size: 972 bytes --] On 11/30/2012 10:11 AM, Wolfgang Grandegger wrote: > On 11/30/2012 09:45 AM, Marc Kleine-Budde wrote: >> On 11/29/2012 03:39 PM, Wolfgang Grandegger wrote: >>> Also fix minor issue with pci_iomap specifying size 0 for >>> mapping the full range. >> >> If I understand the code correct, using pci_resource_len(pdev, 0) for >> the max len (of BAR 0) instead of 0 isn't a bug, it's just more >> complicated than it needs to be. If it really is a bug, I think a >> separate patch will be good. > > It's a minor issue, not a bug. Both do the same thing. See: > > http://lxr.linux.no/#linux+v3.6.8/lib/pci_iomap.c#L23 I've looked at the code, too. Just wanted to be sure :) Marc -- Pengutronix e.K. | Marc Kleine-Budde | Industrial Linux Solutions | Phone: +49-231-2826-924 | Vertretung West/Dortmund | Fax: +49-5121-206917-5555 | Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de | [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 261 bytes --] ^ permalink raw reply [flat|nested] 38+ messages in thread
* [RFC v2 5/7] c_can_pci: enable PCI bus master only for MSI 2012-11-29 14:39 [RFC v2 0/7] pch_can/c_can: fix races and add PCH support to c_can Wolfgang Grandegger ` (3 preceding siblings ...) 2012-11-29 14:39 ` [RFC v2 4/7] c_can_pci: introduce board specific PCI bar Wolfgang Grandegger @ 2012-11-29 14:39 ` Wolfgang Grandegger 2012-11-30 8:54 ` Marc Kleine-Budde 2012-11-29 14:39 ` [RFC v2 6/7] c_can_pci: add support for PCH CAN on Intel EG20T PCH Wolfgang Grandegger ` (2 subsequent siblings) 7 siblings, 1 reply; 38+ messages in thread From: Wolfgang Grandegger @ 2012-11-29 14:39 UTC (permalink / raw) To: linux-can; +Cc: bhupesh.sharma, tomoya.rohm, Wolfgang Grandegger Signed-off-by: Wolfgang Grandegger <wg@grandegger.com> --- drivers/net/can/c_can/c_can_pci.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/can/c_can/c_can_pci.c b/drivers/net/can/c_can/c_can_pci.c index 7b73f90..320e371 100644 --- a/drivers/net/can/c_can/c_can_pci.c +++ b/drivers/net/can/c_can/c_can_pci.c @@ -86,8 +86,11 @@ static int __devinit c_can_pci_probe(struct pci_dev *pdev, goto out_disable_device; } - pci_set_master(pdev); - pci_enable_msi(pdev); + + if (!pci_enable_msi(pdev)) { + dev_info(&pdev->dev, "MSI enabled\n"); + pci_set_master(pdev); + } addr = pci_iomap(pdev, c_can_pci_data->bar, 0); if (!addr) { -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 38+ messages in thread
* Re: [RFC v2 5/7] c_can_pci: enable PCI bus master only for MSI 2012-11-29 14:39 ` [RFC v2 5/7] c_can_pci: enable PCI bus master only for MSI Wolfgang Grandegger @ 2012-11-30 8:54 ` Marc Kleine-Budde 0 siblings, 0 replies; 38+ messages in thread From: Marc Kleine-Budde @ 2012-11-30 8:54 UTC (permalink / raw) To: Wolfgang Grandegger; +Cc: linux-can, bhupesh.sharma, tomoya.rohm [-- Attachment #1: Type: text/plain, Size: 1197 bytes --] On 11/29/2012 03:39 PM, Wolfgang Grandegger wrote: > Signed-off-by: Wolfgang Grandegger <wg@grandegger.com> > --- > drivers/net/can/c_can/c_can_pci.c | 7 +++++-- > 1 file changed, 5 insertions(+), 2 deletions(-) > > diff --git a/drivers/net/can/c_can/c_can_pci.c b/drivers/net/can/c_can/c_can_pci.c > index 7b73f90..320e371 100644 > --- a/drivers/net/can/c_can/c_can_pci.c > +++ b/drivers/net/can/c_can/c_can_pci.c > @@ -86,8 +86,11 @@ static int __devinit c_can_pci_probe(struct pci_dev *pdev, > goto out_disable_device; > } > > - pci_set_master(pdev); > - pci_enable_msi(pdev); > + > + if (!pci_enable_msi(pdev)) { Can you please use an intermediate variable "ret". ret = pci_enable_msi(pdev); if (!ret) { } > + dev_info(&pdev->dev, "MSI enabled\n"); > + pci_set_master(pdev); > + } > > addr = pci_iomap(pdev, c_can_pci_data->bar, 0); > if (!addr) { > Marc -- Pengutronix e.K. | Marc Kleine-Budde | Industrial Linux Solutions | Phone: +49-231-2826-924 | Vertretung West/Dortmund | Fax: +49-5121-206917-5555 | Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de | [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 261 bytes --] ^ permalink raw reply [flat|nested] 38+ messages in thread
* [RFC v2 6/7] c_can_pci: add support for PCH CAN on Intel EG20T PCH 2012-11-29 14:39 [RFC v2 0/7] pch_can/c_can: fix races and add PCH support to c_can Wolfgang Grandegger ` (4 preceding siblings ...) 2012-11-29 14:39 ` [RFC v2 5/7] c_can_pci: enable PCI bus master only for MSI Wolfgang Grandegger @ 2012-11-29 14:39 ` Wolfgang Grandegger 2012-11-29 14:39 ` [RFC v2 7/7] c_can: add spinlock to protect tx and rx objects Wolfgang Grandegger 2012-12-05 12:09 ` [RFC v2 0/7] pch_can/c_can: fix races and add PCH support to c_can Alexander Stein 7 siblings, 0 replies; 38+ messages in thread From: Wolfgang Grandegger @ 2012-11-29 14:39 UTC (permalink / raw) To: linux-can; +Cc: bhupesh.sharma, tomoya.rohm, Wolfgang Grandegger Signed-off-by: Wolfgang Grandegger <wg@grandegger.com> --- drivers/net/can/c_can/c_can_pci.c | 46 ++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/c_can/c_can_pci.c b/drivers/net/can/c_can/c_can_pci.c index 320e371..2516ea9 100644 --- a/drivers/net/can/c_can/c_can_pci.c +++ b/drivers/net/can/c_can/c_can_pci.c @@ -19,9 +19,13 @@ #include "c_can.h" +#define PCI_DEVICE_ID_PCH_CAN 0x8818 +#define PCH_PCI_SOFT_RESET 0x01fc + enum c_can_pci_reg_align { C_CAN_REG_ALIGN_16, C_CAN_REG_ALIGN_32, + C_CAN_REG_32, }; struct c_can_pci_data { @@ -33,6 +37,8 @@ struct c_can_pci_data { unsigned int freq; /* PCI bar number */ int bar; + /* Callback for reset */ + void (*init) (const struct c_can_priv *priv, bool enable); }; /* @@ -65,6 +71,29 @@ static void c_can_pci_write_reg_aligned_to_32bit(struct c_can_priv *priv, writew(val, priv->base + 2 * priv->regs[index]); } +static u16 c_can_pci_read_reg_32bit(struct c_can_priv *priv, + enum reg index) +{ + return (u16)ioread32(priv->base + 2 * priv->regs[index]); +} + +static void c_can_pci_write_reg_32bit(struct c_can_priv *priv, + enum reg index, u16 val) +{ + iowrite32((u32)val, priv->base + 2 * priv->regs[index]); +} + +static void c_can_pci_reset_pch(const struct c_can_priv *priv, bool enable) +{ + if (enable) { + u32 __iomem *addr = priv->base + PCH_PCI_SOFT_RESET; + + /* write to sw reset register */ + iowrite32(1, addr); + iowrite32(0, addr); + } +} + static int __devinit c_can_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -86,7 +115,6 @@ static int __devinit c_can_pci_probe(struct pci_dev *pdev, goto out_disable_device; } - if (!pci_enable_msi(pdev)) { dev_info(&pdev->dev, "MSI enabled\n"); pci_set_master(pdev); @@ -147,11 +175,17 @@ static int __devinit c_can_pci_probe(struct pci_dev *pdev, priv->read_reg = c_can_pci_read_reg_aligned_to_16bit; priv->write_reg = c_can_pci_write_reg_aligned_to_16bit; break; + case C_CAN_REG_32: + priv->read_reg = c_can_pci_read_reg_32bit; + priv->write_reg = c_can_pci_write_reg_32bit; + break; default: ret = -EINVAL; goto out_free_c_can; } + priv->init = c_can_pci_data->init; + ret = register_c_can_dev(dev); if (ret) { dev_err(&pdev->dev, "registering %s failed (err=%d)\n", @@ -203,6 +237,14 @@ static struct c_can_pci_data c_can_sta2x11= { .bar = 0, }; +static struct c_can_pci_data c_can_pch = { + .type = BOSCH_C_CAN, + .reg_align = C_CAN_REG_32, + .freq = 50000000, /* 50 MHz */ + .init = c_can_pci_reset_pch, + .bar = 1, +}; + #define C_CAN_ID(_vend, _dev, _driverdata) { \ PCI_DEVICE(_vend, _dev), \ .driver_data = (unsigned long)&_driverdata, \ @@ -210,6 +252,8 @@ static struct c_can_pci_data c_can_sta2x11= { static DEFINE_PCI_DEVICE_TABLE(c_can_pci_tbl) = { C_CAN_ID(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_CAN, c_can_sta2x11), + C_CAN_ID(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PCH_CAN, + c_can_pch), {}, }; static struct pci_driver c_can_pci_driver = { -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 38+ messages in thread
* [RFC v2 7/7] c_can: add spinlock to protect tx and rx objects 2012-11-29 14:39 [RFC v2 0/7] pch_can/c_can: fix races and add PCH support to c_can Wolfgang Grandegger ` (5 preceding siblings ...) 2012-11-29 14:39 ` [RFC v2 6/7] c_can_pci: add support for PCH CAN on Intel EG20T PCH Wolfgang Grandegger @ 2012-11-29 14:39 ` Wolfgang Grandegger 2012-12-05 12:09 ` [RFC v2 0/7] pch_can/c_can: fix races and add PCH support to c_can Alexander Stein 7 siblings, 0 replies; 38+ messages in thread From: Wolfgang Grandegger @ 2012-11-29 14:39 UTC (permalink / raw) To: linux-can; +Cc: bhupesh.sharma, tomoya.rohm, Wolfgang Grandegger Signed-off-by: Wolfgang Grandegger <wg@grandegger.com> --- drivers/net/can/c_can/c_can.c | 13 +++++++++++++ drivers/net/can/c_can/c_can.h | 1 + 2 files changed, 14 insertions(+) diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c index 27e45e6..b024665 100644 --- a/drivers/net/can/c_can/c_can.c +++ b/drivers/net/can/c_can/c_can.c @@ -34,6 +34,7 @@ #include <linux/if_ether.h> #include <linux/list.h> #include <linux/io.h> +#include <linux/spinlock.h> #include <linux/pm_runtime.h> #include <linux/can.h> @@ -541,10 +542,13 @@ static netdev_tx_t c_can_start_xmit(struct sk_buff *skb, u32 msg_obj_no; struct c_can_priv *priv = netdev_priv(dev); struct can_frame *frame = (struct can_frame *)skb->data; + unsigned long flags; if (can_dropped_invalid_skb(dev, skb)) return NETDEV_TX_OK; + spin_lock_irqsave(&priv->lock, flags); + msg_obj_no = get_tx_next_msg_obj(priv); /* prepare message object for transmission */ @@ -560,6 +564,8 @@ static netdev_tx_t c_can_start_xmit(struct sk_buff *skb, (priv->tx_next & C_CAN_NEXT_MSG_OBJ_MASK) == 0) netif_stop_queue(dev); + spin_unlock_irqrestore(&priv->lock, flags); + return NETDEV_TX_OK; } @@ -746,6 +752,9 @@ static void c_can_do_tx(struct net_device *dev) u32 msg_obj_no; struct c_can_priv *priv = netdev_priv(dev); struct net_device_stats *stats = &dev->stats; + unsigned long flags; + + spin_lock_irqsave(&priv->lock, flags); for (/* nix */; (priv->tx_next - priv->tx_echo) > 0; priv->tx_echo++) { msg_obj_no = get_tx_echo_msg_obj(priv); @@ -767,6 +776,8 @@ static void c_can_do_tx(struct net_device *dev) if (((priv->tx_next & C_CAN_NEXT_MSG_OBJ_MASK) != 0) || ((priv->tx_echo & C_CAN_NEXT_MSG_OBJ_MASK) == 0)) netif_wake_queue(dev); + + spin_unlock_irqrestore(&priv->lock, flags); } /* @@ -1173,6 +1184,8 @@ struct net_device *alloc_c_can_dev(void) CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_BERR_REPORTING; + spin_lock_init(&priv->lock); + return dev; } EXPORT_SYMBOL_GPL(alloc_c_can_dev); diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h index 4baf3f6..3487d5e 100644 --- a/drivers/net/can/c_can/c_can.h +++ b/drivers/net/can/c_can/c_can.h @@ -172,6 +172,7 @@ struct c_can_priv { u32 __iomem *raminit_ctrlreg; unsigned int instance; void (*init) (const struct c_can_priv *priv, bool enable); + spinlock_t lock; /* to protect tx and rx message objects */ }; struct net_device *alloc_c_can_dev(void); -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 38+ messages in thread
* Re: [RFC v2 0/7] pch_can/c_can: fix races and add PCH support to c_can 2012-11-29 14:39 [RFC v2 0/7] pch_can/c_can: fix races and add PCH support to c_can Wolfgang Grandegger ` (6 preceding siblings ...) 2012-11-29 14:39 ` [RFC v2 7/7] c_can: add spinlock to protect tx and rx objects Wolfgang Grandegger @ 2012-12-05 12:09 ` Alexander Stein 2012-12-05 12:50 ` Wolfgang Grandegger 7 siblings, 1 reply; 38+ messages in thread From: Alexander Stein @ 2012-12-05 12:09 UTC (permalink / raw) To: Wolfgang Grandegger; +Cc: linux-can, bhupesh.sharma, tomoya.rohm Hello Wolfgang and others, On Thursday 29 November 2012 15:39:40, Wolfgang Grandegger wrote: > here is v2 of my patches for the C_CAN drivers. > > For Michael I have prepared out-of-tree driver sources allowing to > easily build the drivers also for older 3.x kernel versions. More > tester are welcome. > > Changes since v1: > > - use init callback after renaming it from initram > - use different sets of interface registers for rx and tx (like PCH_CAN) > - use spin_[un]lock_bh to protect the tx objects > > Wolfgang Grandegger (7): > pch_can: add spinlocks to protect tx objects > c_can: rename callback "initram" to "init" to more general usage > c_can: use different sets of interface registers for rx and tx > c_can_pci: introduce board specific PCI bar > c_can_pci: enable PCI bus master only for MSI > c_can_pci: add support for PCH CAN on Intel EG20T PCH > c_can: add spinlock to protect tx and objects > > drivers/net/can/c_can/c_can.c | 66 +++++++++++++++++++++----------- > drivers/net/can/c_can/c_can.h | 3 +- > drivers/net/can/c_can/c_can_pci.c | 56 +++++++++++++++++++++++++-- > drivers/net/can/c_can/c_can_platform.c | 2 +- > drivers/net/can/pch_can.c | 9 +++++ > 5 files changed, 108 insertions(+), 28 deletions(-) I backported the c_can patches incl. your patchset to v3.0.31 and tested this driver on our own custom atom board using the eg20t pch. CAN in general works, but if I run my heavy CAN load testcase I get errors sometimes. This test works as follows: I send a CAN message to 2 other CAN nodes configuring some timings (like burst length or time between each can frame) and they send 250000 messages each containing a counter. This way I can detect any missing or switched message with a high bus load. If I use the described software state alone it works, but if I run 'watch sensors' in a different ssh session, CAN start to misbehave like missing CAN frames or switched order. It seems that I2C usage on the PCH influences the CAN part also:( Even worse, if I use the following patch to check if PCI writes were successfully, I notices that some writes (or the consecutive read) don't succeed. And I also get lots of I2C timeouts waiting for a xfer complete. Does anybody have an idea what's going wrong here? Is somebody able to see the same problems on their hardware? Wolfgang: Compared to your v8 c_can drivers for Michael, I'm just missing the const bitrate table and don't use pci_register_driver, as I have cherry-picked the module_pci_driver patches. Best regards, Alexander diff --git a/drivers/net/can/c_can/c_can_pci.c b/drivers/net/can/c_can/c_can_pci.c index 2516ea9..b124ea5 100644 --- a/drivers/net/can/c_can/c_can_pci.c +++ b/drivers/net/can/c_can/c_can_pci.c @@ -80,7 +80,13 @@ static u16 c_can_pci_read_reg_32bit(struct c_can_priv *priv, static void c_can_pci_write_reg_32bit(struct c_can_priv *priv, enum reg index, u16 val) { + u16 reg; iowrite32((u32)val, priv->base + 2 * priv->regs[index]); + reg = c_can_pci_read_reg_32bit(priv, index); + if (reg != val) + { + netdev_err(priv->dev, "write 0x%x to offset 0x%x failed. got: 0x%x\n", val, 2 * priv->regs[index], reg); + } } static void c_can_pci_reset_pch(const struct c_can_priv *priv, bool enable) ^ permalink raw reply related [flat|nested] 38+ messages in thread
* Re: [RFC v2 0/7] pch_can/c_can: fix races and add PCH support to c_can 2012-12-05 12:09 ` [RFC v2 0/7] pch_can/c_can: fix races and add PCH support to c_can Alexander Stein @ 2012-12-05 12:50 ` Wolfgang Grandegger 2012-12-05 14:46 ` Alexander Stein 0 siblings, 1 reply; 38+ messages in thread From: Wolfgang Grandegger @ 2012-12-05 12:50 UTC (permalink / raw) To: Alexander Stein; +Cc: linux-can, bhupesh.sharma, tomoya.rohm Hi Alexander, thanks for testing!. Maybe we deal with more than one problem. On 12/05/2012 01:09 PM, Alexander Stein wrote: > Hello Wolfgang and others, > > On Thursday 29 November 2012 15:39:40, Wolfgang Grandegger wrote: >> here is v2 of my patches for the C_CAN drivers. >> >> For Michael I have prepared out-of-tree driver sources allowing to >> easily build the drivers also for older 3.x kernel versions. More >> tester are welcome. >> >> Changes since v1: >> >> - use init callback after renaming it from initram >> - use different sets of interface registers for rx and tx (like PCH_CAN) >> - use spin_[un]lock_bh to protect the tx objects >> >> Wolfgang Grandegger (7): >> pch_can: add spinlocks to protect tx objects >> c_can: rename callback "initram" to "init" to more general usage >> c_can: use different sets of interface registers for rx and tx >> c_can_pci: introduce board specific PCI bar >> c_can_pci: enable PCI bus master only for MSI >> c_can_pci: add support for PCH CAN on Intel EG20T PCH >> c_can: add spinlock to protect tx and objects >> >> drivers/net/can/c_can/c_can.c | 66 > +++++++++++++++++++++----------- >> drivers/net/can/c_can/c_can.h | 3 +- >> drivers/net/can/c_can/c_can_pci.c | 56 +++++++++++++++++++++++++-- >> drivers/net/can/c_can/c_can_platform.c | 2 +- >> drivers/net/can/pch_can.c | 9 +++++ >> 5 files changed, 108 insertions(+), 28 deletions(-) > > I backported the c_can patches incl. your patchset to v3.0.31 and tested this > driver on our own custom atom board using the eg20t pch. CAN in general works, The out-of-tree archive may have worked for you as well. A few general questions to understand your hardware and setup: - Is this a multi-processor system (SMP)? If not, you may not run into tx-not-working-any-more problem. Have you ever realized it? - Did you see the problems below with the old PCH_CAN driver as well. - Do the problems show up with the still existing PCH_CAN driver (including the "pch_can: add spinlocks to protect tx objects" patch)? > but if I run my heavy CAN load testcase I get errors sometimes. > This test works as follows: I send a CAN message to 2 other CAN nodes > configuring some timings (like burst length or time between each can frame) > and they send 250000 messages each containing a counter. This way I can detect > any missing or switched message with a high bus load. > If I use the described software state alone it works, but if I run 'watch > sensors' in a different ssh session, CAN start to misbehave like missing CAN > frames or switched order. It seems that I2C usage on the PCH influences the > CAN part also: - When your app sends/writes messages, does it check for errno==ENOBUFS? - The messages look still ok (not currupted, I mean)? > Even worse, if I use the following patch to check if PCI writes were > successfully, I notices that some writes (or the consecutive read) don't > succeed. And I also get lots of I2C timeouts waiting for a xfer complete. Be careful, there might be some registers changing their values after writing. Can you show the value read after writing and the register offset? The influence on the I2C bus looks more like an overload or hardware problem. What is your CAN interrupt rate? Do you see this problem with the old PCH_CAN driver as well? > Does anybody have an idea what's going wrong here? Is somebody able to see the > same problems on their hardware? At least you are the first one reporting this problem. > Wolfgang: Compared to your v8 c_can drivers for Michael, I'm just missing the > const bitrate table and don't use pci_register_driver, as I have cherry-picked > the module_pci_driver patches. What do you mean with "missing the const bitrate table"? Wolfgang. ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC v2 0/7] pch_can/c_can: fix races and add PCH support to c_can 2012-12-05 12:50 ` Wolfgang Grandegger @ 2012-12-05 14:46 ` Alexander Stein 2012-12-05 17:35 ` Wolfgang Grandegger 0 siblings, 1 reply; 38+ messages in thread From: Alexander Stein @ 2012-12-05 14:46 UTC (permalink / raw) To: Wolfgang Grandegger; +Cc: linux-can, bhupesh.sharma, tomoya.rohm Hello Wolfgang, On Wednesday 05 December 2012 13:50:46, Wolfgang Grandegger wrote: > Hi Alexander, > > thanks for testing!. Maybe we deal with more than one problem. > > On 12/05/2012 01:09 PM, Alexander Stein wrote: > > Hello Wolfgang and others, > > > > On Thursday 29 November 2012 15:39:40, Wolfgang Grandegger wrote: > >> here is v2 of my patches for the C_CAN drivers. > >> > >> For Michael I have prepared out-of-tree driver sources allowing to > >> easily build the drivers also for older 3.x kernel versions. More > >> tester are welcome. > >> > >> Changes since v1: > >> > >> - use init callback after renaming it from initram > >> - use different sets of interface registers for rx and tx (like PCH_CAN) > >> - use spin_[un]lock_bh to protect the tx objects > >> > >> Wolfgang Grandegger (7): > >> pch_can: add spinlocks to protect tx objects > >> c_can: rename callback "initram" to "init" to more general usage > >> c_can: use different sets of interface registers for rx and tx > >> c_can_pci: introduce board specific PCI bar > >> c_can_pci: enable PCI bus master only for MSI > >> c_can_pci: add support for PCH CAN on Intel EG20T PCH > >> c_can: add spinlock to protect tx and objects > >> > >> drivers/net/can/c_can/c_can.c | 66 > > +++++++++++++++++++++----------- > >> drivers/net/can/c_can/c_can.h | 3 +- > >> drivers/net/can/c_can/c_can_pci.c | 56 +++++++++++++++++++++++++-- > >> drivers/net/can/c_can/c_can_platform.c | 2 +- > >> drivers/net/can/pch_can.c | 9 +++++ > >> 5 files changed, 108 insertions(+), 28 deletions(-) > > > > I backported the c_can patches incl. your patchset to v3.0.31 and tested this > > driver on our own custom atom board using the eg20t pch. CAN in general works, > > The out-of-tree archive may have worked for you as well. > > A few general questions to understand your hardware and setup: > > - Is this a multi-processor system (SMP)? If not, you may not run into > tx-not-working-any-more problem. Have you ever realized it? This is a Intel E660 single core CPU with HT, so it is a SMP system. I'm currently not aware that tx is not working anymore. > - Did you see the problems below with the old PCH_CAN driver as well. > > - Do the problems show up with the still existing PCH_CAN driver > (including the "pch_can: add spinlocks to protect tx objects" patch)? With the current version of pch_can from Linuxs' tree and the named patch I get at least some messaged twice. > > but if I run my heavy CAN load testcase I get errors sometimes. > > This test works as follows: I send a CAN message to 2 other CAN nodes > > configuring some timings (like burst length or time between each can frame) > > and they send 250000 messages each containing a counter. This way I can detect > > any missing or switched message with a high bus load. > > If I use the described software state alone it works, but if I run 'watch > > sensors' in a different ssh session, CAN start to misbehave like missing CAN > > frames or switched order. It seems that I2C usage on the PCH influences the > > CAN part also: > > - When your app sends/writes messages, does it check for errno==ENOBUFS? My test application sends only 1 message each test run to start the other nodes. It checks ENOBUFS and returns an error in that case. Though I've never seen that. > - The messages look still ok (not currupted, I mean)? The received frames all look good (despite wrong counter sometimes due to wrong order or lost frames). > > Even worse, if I use the following patch to check if PCI writes were > > successfully, I notices that some writes (or the consecutive read) don't > > succeed. And I also get lots of I2C timeouts waiting for a xfer complete. > > Be careful, there might be some registers changing their values after > writing. Can you show the value read after writing and the register > offset? The influence on the I2C bus looks more like an overload or > hardware problem. What is your CAN interrupt rate? I get about 33 interrupts per second on i2c. On a successful run I get 366886 interrupts for 500000 messages with the c_can driver. Here are some failed writes to the CAN controller. [ 50.445695] c_can_pci 0000:02:0c.3: can0: write 0x0 to offset 0x4 failed. got: 0x10 [ 51.043027] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0x0 [... repeats several times] [ 64.046031] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0x0 [ 64.458286] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xb8 [ 64.811025] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0x0 and the last one is repeated all the time. Some times I also get the 16 of the following message: c_can_pci 0000:02:0c.3: can0: write 0x0 to offset 0x2c failed. got: 0x2000 > Do you see this problem with the old PCH_CAN driver as well? With pch_can I get about 254000 interrupts for about 283000 frames. [ 2422.198378] regs base: f8f5a000 [ 2449.197911] pch_can_bit_clear: clear bit failed: addr: f8f5a038, reg1: 0x1404, reg2: 0x8, mask 0xa000 [ 2458.302028] pch_can_bit_set: set bit failed: addr: f8f5a000, reg1: 0x80, reg2: 0x80, mask 0xe On the second line you can see that the register isn't written at all (or the read failed for some reason). > > Does anybody have an idea what's going wrong here? Is somebody able to see the > > same problems on their hardware? > > At least you are the first one reporting this problem. > > > Wolfgang: Compared to your v8 c_can drivers for Michael, I'm just missing the > > const bitrate table and don't use pci_register_driver, as I have cherry- picked > > the module_pci_driver patches. > > What do you mean with "missing the const bitrate table"? I do not have cherry-picked commit 194b9a4cb91713ddb60c9f98f7212f6d8cb8e05f. Best regards, Alexander ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC v2 0/7] pch_can/c_can: fix races and add PCH support to c_can 2012-12-05 14:46 ` Alexander Stein @ 2012-12-05 17:35 ` Wolfgang Grandegger 2012-12-05 21:52 ` Marc Kleine-Budde ` (2 more replies) 0 siblings, 3 replies; 38+ messages in thread From: Wolfgang Grandegger @ 2012-12-05 17:35 UTC (permalink / raw) To: Alexander Stein; +Cc: linux-can, bhupesh.sharma, tomoya.rohm On 12/05/2012 03:46 PM, Alexander Stein wrote: > Hello Wolfgang, > > On Wednesday 05 December 2012 13:50:46, Wolfgang Grandegger wrote: >> Hi Alexander, >> >> thanks for testing!. Maybe we deal with more than one problem. >> ... >> A few general questions to understand your hardware and setup: >> >> - Is this a multi-processor system (SMP)? If not, you may not run into >> tx-not-working-any-more problem. Have you ever realized it? > > This is a Intel E660 single core CPU with HT, so it is a SMP system. I'm > currently not aware that tx is not working anymore. OK, your send rate is very low and therefore it's unlikely that you hit that problem. >> - Did you see the problems below with the old PCH_CAN driver as well. >> >> - Do the problems show up with the still existing PCH_CAN driver >> (including the "pch_can: add spinlocks to protect tx objects" patch)? > > With the current version of pch_can from Linuxs' tree and the named patch I > get at least some messaged twice. OK, sounds better but also not good. >>> but if I run my heavy CAN load testcase I get errors sometimes. >>> This test works as follows: I send a CAN message to 2 other CAN nodes >>> configuring some timings (like burst length or time between each can > frame) >>> and they send 250000 messages each containing a counter. This way I can > detect >>> any missing or switched message with a high bus load. >>> If I use the described software state alone it works, but if I run 'watch >>> sensors' in a different ssh session, CAN start to misbehave like missing > CAN >>> frames or switched order. It seems that I2C usage on the PCH influences > the >>> CAN part also: >> >> - When your app sends/writes messages, does it check for errno==ENOBUFS? > > My test application sends only 1 message each test run to start the other > nodes. It checks ENOBUFS and returns an error in that case. Though I've never > seen that. OK, your TX rate it low. > >> - The messages look still ok (not currupted, I mean)? > > The received frames all look good (despite wrong counter sometimes due to > wrong order or lost frames). > >>> Even worse, if I use the following patch to check if PCI writes were >>> successfully, I notices that some writes (or the consecutive read) don't >>> succeed. And I also get lots of I2C timeouts waiting for a xfer complete. >> >> Be careful, there might be some registers changing their values after >> writing. Can you show the value read after writing and the register >> offset? The influence on the I2C bus looks more like an overload or >> hardware problem. What is your CAN interrupt rate? > > I get about 33 interrupts per second on i2c. On a successful run I get 366886 > interrupts for 500000 messages with the c_can driver. In what time? Is the CAN bus highly loaded. > Here are some failed writes to the CAN controller. > [ 50.445695] c_can_pci 0000:02:0c.3: can0: write 0x0 to offset 0x4 failed. > got: 0x10 > [ 51.043027] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. > got: 0x0 > [... repeats several times] > [ 64.046031] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. > got: 0x0 > [ 64.458286] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. > got: 0xb8 > [ 64.811025] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. > got: 0x0 > and the last one is repeated all the time. That's wired! Writing 0xe to offset 0x0 does re-enable the interrupts at the end of poll-rx. Disabling the interrupts in the isr does not show that symptoms. Strange. > Some times I also get the 16 of the following message: > c_can_pci 0000:02:0c.3: can0: write 0x0 to offset 0x2c failed. got: 0x2000 >> Do you see this problem with the old PCH_CAN driver as well? > > With pch_can I get about 254000 interrupts for about 283000 frames. > > [ 2422.198378] regs base: f8f5a000 > [ 2449.197911] pch_can_bit_clear: clear bit failed: addr: f8f5a038, reg1: > 0x1404, reg2: 0x8, mask 0xa000 > [ 2458.302028] pch_can_bit_set: set bit failed: addr: f8f5a000, reg1: 0x80, > reg2: 0x80, mask 0xe That's the same thing as with the c_can driver when the interrupts gets re-enabled. > On the second line you can see that the register isn't written at all (or the > read failed for some reason). I assume the latter. Could you please retry reading the register until the correct value shows up. With some timeout, of course. I checked the PCH ethernet driver and did not find anythings special accessing registers. Maybe Tomoya has an idea or could tell use somebody at OKI/LAPIS Semiconductor who could help. Tomoya? Wolfgang. ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC v2 0/7] pch_can/c_can: fix races and add PCH support to c_can 2012-12-05 17:35 ` Wolfgang Grandegger @ 2012-12-05 21:52 ` Marc Kleine-Budde 2012-12-06 7:09 ` Wolfgang Grandegger 2012-12-06 8:17 ` Wolfgang Grandegger 2012-12-06 13:38 ` Alexander Stein 2 siblings, 1 reply; 38+ messages in thread From: Marc Kleine-Budde @ 2012-12-05 21:52 UTC (permalink / raw) To: Wolfgang Grandegger Cc: Alexander Stein, linux-can, bhupesh.sharma, tomoya.rohm [-- Attachment #1: Type: text/plain, Size: 4189 bytes --] On 12/05/2012 06:35 PM, Wolfgang Grandegger wrote: > On 12/05/2012 03:46 PM, Alexander Stein wrote: >> Hello Wolfgang, >> >> On Wednesday 05 December 2012 13:50:46, Wolfgang Grandegger wrote: >>> Hi Alexander, >>> >>> thanks for testing!. Maybe we deal with more than one problem. >>> > ... >>> A few general questions to understand your hardware and setup: >>> >>> - Is this a multi-processor system (SMP)? If not, you may not run into >>> tx-not-working-any-more problem. Have you ever realized it? >> >> This is a Intel E660 single core CPU with HT, so it is a SMP system. I'm >> currently not aware that tx is not working anymore. > > OK, your send rate is very low and therefore it's unlikely that you hit > that problem. > >>> - Did you see the problems below with the old PCH_CAN driver as well. >>> >>> - Do the problems show up with the still existing PCH_CAN driver >>> (including the "pch_can: add spinlocks to protect tx objects" patch)? >> >> With the current version of pch_can from Linuxs' tree and the named patch I >> get at least some messaged twice. > > OK, sounds better but also not good. > >>>> but if I run my heavy CAN load testcase I get errors sometimes. >>>> This test works as follows: I send a CAN message to 2 other CAN nodes >>>> configuring some timings (like burst length or time between each can >> frame) >>>> and they send 250000 messages each containing a counter. This way I can >> detect >>>> any missing or switched message with a high bus load. >>>> If I use the described software state alone it works, but if I run 'watch >>>> sensors' in a different ssh session, CAN start to misbehave like missing >> CAN >>>> frames or switched order. It seems that I2C usage on the PCH influences >> the >>>> CAN part also: >>> >>> - When your app sends/writes messages, does it check for errno==ENOBUFS? >> >> My test application sends only 1 message each test run to start the other >> nodes. It checks ENOBUFS and returns an error in that case. Though I've never >> seen that. > > OK, your TX rate it low. > >> >>> - The messages look still ok (not currupted, I mean)? >> >> The received frames all look good (despite wrong counter sometimes due to >> wrong order or lost frames). >> >>>> Even worse, if I use the following patch to check if PCI writes were >>>> successfully, I notices that some writes (or the consecutive read) don't >>>> succeed. And I also get lots of I2C timeouts waiting for a xfer complete. >>> >>> Be careful, there might be some registers changing their values after >>> writing. Can you show the value read after writing and the register >>> offset? The influence on the I2C bus looks more like an overload or >>> hardware problem. What is your CAN interrupt rate? >> >> I get about 33 interrupts per second on i2c. On a successful run I get 366886 >> interrupts for 500000 messages with the c_can driver. > > In what time? Is the CAN bus highly loaded. > >> Here are some failed writes to the CAN controller. >> [ 50.445695] c_can_pci 0000:02:0c.3: can0: write 0x0 to offset 0x4 failed. >> got: 0x10 >> [ 51.043027] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. >> got: 0x0 >> [... repeats several times] >> [ 64.046031] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. >> got: 0x0 >> [ 64.458286] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. >> got: 0xb8 >> [ 64.811025] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. >> got: 0x0 >> and the last one is repeated all the time. > > That's wired! Writing 0xe to offset 0x0 does re-enable the interrupts at > the end of poll-rx. Disabling the interrupts in the isr does not show > that symptoms. Strange. The write+read check is racy. The interrupt handler might disable the interrupts again. Marc -- Pengutronix e.K. | Marc Kleine-Budde | Industrial Linux Solutions | Phone: +49-231-2826-924 | Vertretung West/Dortmund | Fax: +49-5121-206917-5555 | Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de | [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 261 bytes --] ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC v2 0/7] pch_can/c_can: fix races and add PCH support to c_can 2012-12-05 21:52 ` Marc Kleine-Budde @ 2012-12-06 7:09 ` Wolfgang Grandegger 2012-12-06 8:35 ` Marc Kleine-Budde 0 siblings, 1 reply; 38+ messages in thread From: Wolfgang Grandegger @ 2012-12-06 7:09 UTC (permalink / raw) To: Marc Kleine-Budde; +Cc: Alexander Stein, linux-can, bhupesh.sharma, tomoya.rohm On 12/05/2012 10:52 PM, Marc Kleine-Budde wrote: > On 12/05/2012 06:35 PM, Wolfgang Grandegger wrote: >> On 12/05/2012 03:46 PM, Alexander Stein wrote: >>> Hello Wolfgang, >>> >>> On Wednesday 05 December 2012 13:50:46, Wolfgang Grandegger wrote: >>>> Hi Alexander, >>>> >>>> thanks for testing!. Maybe we deal with more than one problem. >>>> >> ... >>>> A few general questions to understand your hardware and setup: >>>> >>>> - Is this a multi-processor system (SMP)? If not, you may not run into >>>> tx-not-working-any-more problem. Have you ever realized it? >>> >>> This is a Intel E660 single core CPU with HT, so it is a SMP system. I'm >>> currently not aware that tx is not working anymore. >> >> OK, your send rate is very low and therefore it's unlikely that you hit >> that problem. >> >>>> - Did you see the problems below with the old PCH_CAN driver as well. >>>> >>>> - Do the problems show up with the still existing PCH_CAN driver >>>> (including the "pch_can: add spinlocks to protect tx objects" patch)? >>> >>> With the current version of pch_can from Linuxs' tree and the named patch I >>> get at least some messaged twice. >> >> OK, sounds better but also not good. >> >>>>> but if I run my heavy CAN load testcase I get errors sometimes. >>>>> This test works as follows: I send a CAN message to 2 other CAN nodes >>>>> configuring some timings (like burst length or time between each can >>> frame) >>>>> and they send 250000 messages each containing a counter. This way I can >>> detect >>>>> any missing or switched message with a high bus load. >>>>> If I use the described software state alone it works, but if I run 'watch >>>>> sensors' in a different ssh session, CAN start to misbehave like missing >>> CAN >>>>> frames or switched order. It seems that I2C usage on the PCH influences >>> the >>>>> CAN part also: >>>> >>>> - When your app sends/writes messages, does it check for errno==ENOBUFS? >>> >>> My test application sends only 1 message each test run to start the other >>> nodes. It checks ENOBUFS and returns an error in that case. Though I've never >>> seen that. >> >> OK, your TX rate it low. >> >>> >>>> - The messages look still ok (not currupted, I mean)? >>> >>> The received frames all look good (despite wrong counter sometimes due to >>> wrong order or lost frames). >>> >>>>> Even worse, if I use the following patch to check if PCI writes were >>>>> successfully, I notices that some writes (or the consecutive read) don't >>>>> succeed. And I also get lots of I2C timeouts waiting for a xfer complete. >>>> >>>> Be careful, there might be some registers changing their values after >>>> writing. Can you show the value read after writing and the register >>>> offset? The influence on the I2C bus looks more like an overload or >>>> hardware problem. What is your CAN interrupt rate? >>> >>> I get about 33 interrupts per second on i2c. On a successful run I get 366886 >>> interrupts for 500000 messages with the c_can driver. >> >> In what time? Is the CAN bus highly loaded. >> >>> Here are some failed writes to the CAN controller. >>> [ 50.445695] c_can_pci 0000:02:0c.3: can0: write 0x0 to offset 0x4 failed. >>> got: 0x10 >>> [ 51.043027] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. >>> got: 0x0 >>> [... repeats several times] >>> [ 64.046031] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. >>> got: 0x0 >>> [ 64.458286] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. >>> got: 0xb8 >>> [ 64.811025] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. >>> got: 0x0 >>> and the last one is repeated all the time. >> >> That's wired! Writing 0xe to offset 0x0 does re-enable the interrupts at >> the end of poll-rx. Disabling the interrupts in the isr does not show >> that symptoms. Strange. > > The write+read check is racy. The interrupt handler might disable the > interrupts again. Ah, yes, of course. Nothing to worry about then. Sorry for the noise. Wolfgang. ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC v2 0/7] pch_can/c_can: fix races and add PCH support to c_can 2012-12-06 7:09 ` Wolfgang Grandegger @ 2012-12-06 8:35 ` Marc Kleine-Budde 0 siblings, 0 replies; 38+ messages in thread From: Marc Kleine-Budde @ 2012-12-06 8:35 UTC (permalink / raw) To: Wolfgang Grandegger Cc: Alexander Stein, linux-can, bhupesh.sharma, tomoya.rohm [-- Attachment #1: Type: text/plain, Size: 804 bytes --] On 12/06/2012 08:09 AM, Wolfgang Grandegger wrote: >>> That's wired! Writing 0xe to offset 0x0 does re-enable the interrupts at >>> the end of poll-rx. Disabling the interrupts in the isr does not show >>> that symptoms. Strange. >> >> The write+read check is racy. The interrupt handler might disable the >> interrupts again. > > Ah, yes, of course. Nothing to worry about then. Sorry for the noise. However we can add a spinlock around the write+read and the read function itself for debugging purpose. Marc -- Pengutronix e.K. | Marc Kleine-Budde | Industrial Linux Solutions | Phone: +49-231-2826-924 | Vertretung West/Dortmund | Fax: +49-5121-206917-5555 | Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de | [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 261 bytes --] ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC v2 0/7] pch_can/c_can: fix races and add PCH support to c_can 2012-12-05 17:35 ` Wolfgang Grandegger 2012-12-05 21:52 ` Marc Kleine-Budde @ 2012-12-06 8:17 ` Wolfgang Grandegger 2012-12-06 13:38 ` Alexander Stein 2 siblings, 0 replies; 38+ messages in thread From: Wolfgang Grandegger @ 2012-12-06 8:17 UTC (permalink / raw) To: Alexander Stein; +Cc: linux-can, bhupesh.sharma, tomoya.rohm On 12/05/2012 06:35 PM, Wolfgang Grandegger wrote: > On 12/05/2012 03:46 PM, Alexander Stein wrote: >> Hello Wolfgang, >> >> On Wednesday 05 December 2012 13:50:46, Wolfgang Grandegger wrote: >>> Hi Alexander, >>> >>> thanks for testing!. Maybe we deal with more than one problem. >>> > ... >>> A few general questions to understand your hardware and setup: >>> >>> - Is this a multi-processor system (SMP)? If not, you may not run into >>> tx-not-working-any-more problem. Have you ever realized it? >> >> This is a Intel E660 single core CPU with HT, so it is a SMP system. I'm >> currently not aware that tx is not working anymore. > > OK, your send rate is very low and therefore it's unlikely that you hit > that problem. > >>> - Did you see the problems below with the old PCH_CAN driver as well. >>> >>> - Do the problems show up with the still existing PCH_CAN driver >>> (including the "pch_can: add spinlocks to protect tx objects" patch)? >> >> With the current version of pch_can from Linuxs' tree and the named patch I >> get at least some messaged twice. > > OK, sounds better but also not good. > >>>> but if I run my heavy CAN load testcase I get errors sometimes. >>>> This test works as follows: I send a CAN message to 2 other CAN nodes >>>> configuring some timings (like burst length or time between each can >> frame) >>>> and they send 250000 messages each containing a counter. This way I can >> detect >>>> any missing or switched message with a high bus load. >>>> If I use the described software state alone it works, but if I run 'watch >>>> sensors' in a different ssh session, CAN start to misbehave like missing >> CAN >>>> frames or switched order. It seems that I2C usage on the PCH influences >> the >>>> CAN part also: >>> >>> - When your app sends/writes messages, does it check for errno==ENOBUFS? >> >> My test application sends only 1 message each test run to start the other >> nodes. It checks ENOBUFS and returns an error in that case. Though I've never >> seen that. > > OK, your TX rate it low. > >> >>> - The messages look still ok (not currupted, I mean)? >> >> The received frames all look good (despite wrong counter sometimes due to >> wrong order or lost frames). Could you show use the sequence of the lost, duplicated and out-of-order messages in the format: received-sequence number: sent-sequence-number-in-the-can-data Maybe we can see a pattern. Thanks, Wolfgang. ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC v2 0/7] pch_can/c_can: fix races and add PCH support to c_can 2012-12-05 17:35 ` Wolfgang Grandegger 2012-12-05 21:52 ` Marc Kleine-Budde 2012-12-06 8:17 ` Wolfgang Grandegger @ 2012-12-06 13:38 ` Alexander Stein 2012-12-06 14:02 ` Marc Kleine-Budde 2012-12-06 14:31 ` Wolfgang Grandegger 2 siblings, 2 replies; 38+ messages in thread From: Alexander Stein @ 2012-12-06 13:38 UTC (permalink / raw) To: Wolfgang Grandegger; +Cc: linux-can, bhupesh.sharma, tomoya.rohm Hello Wolfgang, On Wednesday 05 December 2012 18:35:25, Wolfgang Grandegger wrote: > >> - The messages look still ok (not currupted, I mean)? > > > > The received frames all look good (despite wrong counter sometimes due to > > wrong order or lost frames). > > > >>> Even worse, if I use the following patch to check if PCI writes were > >>> successfully, I notices that some writes (or the consecutive read) don't > >>> succeed. And I also get lots of I2C timeouts waiting for a xfer complete. > >> > >> Be careful, there might be some registers changing their values after > >> writing. Can you show the value read after writing and the register > >> offset? The influence on the I2C bus looks more like an overload or > >> hardware problem. What is your CAN interrupt rate? > > > > I get about 33 interrupts per second on i2c. On a successful run I get 366886 > > interrupts for 500000 messages with the c_can driver. > > In what time? Is the CAN bus highly loaded. Busload is about 14-18% according to canbusload with 1MBit. A complete sucessful run takes about 5 minutes. > > On the second line you can see that the register isn't written at all (or the > > read failed for some reason). > > I assume the latter. Could you please retry reading the register until > the correct value shows up. With some timeout, of course. I notices having all error events printed on serial console using pch_uart driver has negative effect (I guess one problem causes another one), so I setup 'dmesg -n1' to reduce serial load before the test. Running the test with just one heartbeat triggered LED set using I2C the test runs without errors. I only see Lots of 'c_can_pci 0000:02:0c.3: can0: write 0x0 to offset 0x2c failed. got: 0x2000' at the beginning. It seems this (reserved?) bit is always 1 no matter what we write. But things start to break when running the test while running 'watch sensors' (sensors queries several temperature sensors via I2C) in a seconds ssh session. First off the driver error messages (omitting the messages as written above): [ 384.466217] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xbc [ 384.466630] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xb8 [ 394.754389] c_can_pci 0000:02:0c.3: can0: write 0x0 to offset 0x0 failed. got: 0xac [ 394.754532] c_can_pci 0000:02:0c.3: can0: write 0x6 to offset 0x20 failed. got: 0x20 [ 394.754798] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x98 [ 429.851053] c_can_pci 0000:02:0c.3: can0: write 0x5 to offset 0x20 failed. got: 0x8 [ 440.129098] c_can_pci 0000:02:0c.3: can0: write 0x9404 to offset 0x38 failed. got: 0x8 [ 440.129496] c_can_pci 0000:02:0c.3: can0: write 0x1404 to offset 0x38 failed. got: 0x388 [ 440.129765] c_can_pci 0000:02:0c.3: can0: write 0x9404 to offset 0x38 failed. got: 0x8 [ 440.130441] c_can_pci 0000:02:0c.3: can0: write 0xa to offset 0x20 failed. got: 0x8 [ 460.742395] c_can_pci 0000:02:0c.3: can0: write 0x1404 to offset 0x38 failed. got: 0x8 [ 460.742662] c_can_pci 0000:02:0c.3: can0: write 0x90 to offset 0x24 failed. got: 0xa8 [ 460.742789] c_can_pci 0000:02:0c.3: can0: write 0x4 to offset 0x20 failed. got: 0x8 [ 460.742805] c_can_pci 0000:02:0c.3: can0: write 0x4 to offset 0x20 failed. got: 0x18 [ 460.744112] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xb8 [ 471.025367] c_can_pci 0000:02:0c.3: can0: write 0x9 to offset 0x20 failed. got: 0x18 [ 493.714037] c_can_pci 0000:02:0c.3: can0: write 0xa to offset 0x20 failed. got: 0x18 [ 493.714296] c_can_pci 0000:02:0c.3: can0: write 0xa to offset 0x20 failed. got: 0x8 [ 493.714976] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x28 [ 493.715788] c_can_pci 0000:02:0c.3: can0: write 0x1404 to offset 0x38 failed. got: 0x388 [ 493.716243] c_can_pci 0000:02:0c.3: can0: write 0x1404 to offset 0x38 failed. got: 0x8 [ 547.301509] c_can_pci 0000:02:0c.3: can0: write 0x1404 to offset 0x38 failed. got: 0x388 [ 547.302181] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0x88 [ 557.602229] c_can_pci 0000:02:0c.3: can0: write 0x0 to offset 0x0 failed. got: 0x88 [ 557.602501] c_can_pci 0000:02:0c.3: can0: write 0x0 to offset 0x0 failed. got: 0x28 [ 557.602773] c_can_pci 0000:02:0c.3: can0: write 0x0 to offset 0x0 failed. got: 0xa8 [ 567.901158] c_can_pci 0000:02:0c.3: can0: write 0x1404 to offset 0x38 failed. got: 0x8 [ 567.901558] c_can_pci 0000:02:0c.3: can0: write 0x1404 to offset 0x38 failed. got: 0x388 [ 567.901821] c_can_pci 0000:02:0c.3: can0: write 0xb to offset 0x20 failed. got: 0x8 [ 569.962867] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xa0 [ 572.024462] c_can_pci 0000:02:0c.3: can0: write 0x10 to offset 0x20 failed. got: 0x8 [ 572.024731] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0x28 [ 576.150457] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x88 [ 576.150730] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0x28 [ 576.151463] c_can_pci 0000:02:0c.3: can0: write 0x10 to offset 0x20 failed. got: 0x18 [ 576.151716] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x28 [ 576.151987] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0xa8 [ 578.222888] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x28 [ 578.224252] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x88 [ 580.284468] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x88 [ 580.284741] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0x28 [ 580.285969] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0xa8 [ 580.286226] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x88 [ 582.348458] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x88 [ 582.348730] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0x28 [ 582.348878] c_can_pci 0000:02:0c.3: can0: write 0x0 to offset 0x0 failed. got: 0xa0 [ 582.349494] c_can_pci 0000:02:0c.3: can0: write 0x0 to offset 0x0 failed. got: 0x88 [ 582.350354] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0x88 [ 584.410064] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x28 [ 584.410455] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x88 [ 584.410725] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0x28 [ 586.478397] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xb8 [ 586.478662] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xac [ 588.551484] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x98 [ 588.552464] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xb8 [ 588.552720] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x28 [ 588.552991] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0xa8 [ 590.624880] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x28 [ 592.695613] c_can_pci 0000:02:0c.3: can0: write 0x10 to offset 0x20 failed. got: 0x8 [ 592.696377] c_can_pci 0000:02:0c.3: can0: write 0x1 to offset 0x20 failed. got: 0x8 [ 594.759455] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x88 [ 594.759727] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0x28 [ 594.760696] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x28 [ 596.821041] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0xac [ 596.821433] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0x88 [ 596.822423] c_can_pci 0000:02:0c.3: can0: write 0x0 to offset 0x0 failed. got: 0x88 [ 596.822683] c_can_pci 0000:02:0c.3: can0: write 0x0 to offset 0x0 failed. got: 0x28 [ 598.901376] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xbc [ 598.901517] c_can_pci 0000:02:0c.3: can0: write 0x10 to offset 0x20 failed. got: 0x20 [ 600.962052] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x28 [ 600.962728] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0x28 [ 603.050703] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xb8 [ 603.050967] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xac [ 605.146593] c_can_pci 0000:02:0c.3: can0: write 0x10 to offset 0x20 failed. got: 0x18 [ 605.146855] c_can_pci 0000:02:0c.3: can0: write 0x10 to offset 0x20 failed. got: 0x8 [ 607.207808] c_can_pci 0000:02:0c.3: can0: write 0x7 to offset 0x20 failed. got: 0x8 [ 607.209239] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x88 [ 609.287327] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x98 [ 609.287589] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x28 [ 611.349466] c_can_pci 0000:02:0c.3: can0: write 0x10 to offset 0x20 failed. got: 0x18 [ 611.349721] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x28 [ 611.349993] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0xa8 [ 613.411182] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xa0 [ 613.411451] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xb8 [ 613.411714] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xac [ 613.413185] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x88 [ 615.473479] c_can_pci 0000:02:0c.3: can0: write 0x10 to offset 0x20 failed. got: 0x18 [ 615.473739] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xac [ 617.547060] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xac [ 617.547452] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x88 [ 617.547723] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0x28 [ 619.610167] c_can_pci 0000:02:0c.3: can0: write 0x1404 to offset 0x38 failed. got: 0x388 [ 619.610897] c_can_pci 0000:02:0c.3: can0: write 0x1404 to offset 0x38 failed. got: 0x84 [ 621.674433] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x28 [ 621.674827] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0x88 [ 623.736136] c_can_pci 0000:02:0c.3: can0: write 0x10 to offset 0x20 failed. got: 0x18 [ 623.736389] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x28 [ 623.736661] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0xa8 [ 625.797476] c_can_pci 0000:02:0c.3: can0: write 0x10 to offset 0x20 failed. got: 0x18 [ 625.798001] c_can_pci 0000:02:0c.3: can0: write 0x0 to offset 0x0 failed. got: 0xa8 [ 625.798721] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xbc [ 627.878566] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xb8 [ 627.878831] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xac [ 629.979482] c_can_pci 0000:02:0c.3: can0: write 0x10 to offset 0x20 failed. got: 0x18 [ 629.979735] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x28 [ 632.053216] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xa0 [ 632.053486] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xb8 [ 632.053739] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x28 [ 632.055326] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x88 [ 634.116321] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x28 [ 634.116730] c_can_pci 0000:02:0c.3: can0: write 0x1404 to offset 0x38 failed. got: 0x388 [ 638.241495] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xb8 [ 638.241757] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xac [ 638.243102] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xa8 [ 640.303328] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0xa8 [ 642.386078] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xb8 [ 642.386342] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xac [ 644.498061] c_can_pci 0000:02:0c.3: can0: write 0x10 to offset 0x20 failed. got: 0x8 [ 644.498329] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xa8 [ 644.498476] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xb8 [ 644.498729] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x28 [ 644.499000] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0xa8 [ 646.662057] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xbc [ 646.663432] c_can_pci 0000:02:0c.3: can0: write 0x0 to offset 0x0 failed. got: 0x88 [ 648.726341] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0xa8 [ 648.726475] c_can_pci 0000:02:0c.3: can0: write 0x10 to offset 0x20 failed. got: 0x18 [ 648.726742] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0x28 [ 648.728303] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x88 [ 650.900856] c_can_pci 0000:02:0c.3: can0: write 0x0 to offset 0x0 failed. got: 0x88 [ 650.901394] c_can_pci 0000:02:0c.3: can0: write 0x0 to offset 0x0 failed. got: 0xac [ 650.901538] c_can_pci 0000:02:0c.3: can0: write 0x0 to offset 0x0 failed. got: 0xa0 [ 655.024046] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x28 [ 655.024316] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xa8 [ 655.024465] c_can_pci 0000:02:0c.3: can0: write 0x10 to offset 0x20 failed. got: 0x18 [ 655.024999] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0xa8 [ 657.189061] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0x28 [ 657.189453] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0x88 [ 657.190518] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x88 [ 657.190787] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0x28 [ 659.251734] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x28 [ 659.251875] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xa0 [ 659.252407] c_can_pci 0000:02:0c.3: can0: write 0x0 to offset 0x0 failed. got: 0x88 [ 663.484251] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xb8 [ 663.484516] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xac [ 665.544773] c_can_pci 0000:02:0c.3: can0: write 0x10 to offset 0x20 failed. got: 0x18 [ 665.546173] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xa0 [ 665.546443] c_can_pci 0000:02:0c.3: can0: write 0x10 to offset 0x20 failed. got: 0x18 [ 665.546699] c_can_pci 0000:02:0c.3: can0: write 0x10 to offset 0x20 failed. got: 0x8 [ 665.546845] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0xa0 [ 667.608301] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0x28 [ 669.671155] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x88 [ 671.732041] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0x28 [ 671.732311] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0xa8 [ 671.732434] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x88 [ 671.732450] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xb8 [ 671.732708] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xbc [ 671.732978] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0xa8 [ 671.733784] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x88 [ 673.794056] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0xac [ 673.794317] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0xa8 [ 673.794441] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x88 [ 673.794457] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xb8 [ 673.794715] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xbc [ 673.794853] c_can_pci 0000:02:0c.3: can0: write 0x10 to offset 0x20 failed. got: 0x20 [ 673.796066] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x28 [ 673.796463] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0x88 [ 675.856075] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xac [ 675.856466] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x88 [ 675.856736] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0x28 [ 677.918058] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xbc [ 680.001185] c_can_pci 0000:02:0c.3: can0: write 0x10 to offset 0x20 failed. got: 0x18 [ 680.001444] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x28 [ 682.060763] c_can_pci 0000:02:0c.3: can0: write 0x0 to offset 0x0 failed. got: 0xa8 [ 682.061048] c_can_pci 0000:02:0c.3: can0: write 0x0 to offset 0x0 failed. got: 0xac [ 682.062648] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xbc [ 682.062787] c_can_pci 0000:02:0c.3: can0: write 0x10 to offset 0x20 failed. got: 0x20 [ 684.138124] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xb8 [ 686.199499] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xb8 [ 686.199895] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0xa0 [ 688.261491] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xb8 [ 688.262607] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x28 [ 688.262879] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0xa8 [ 688.263001] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x88 [ 690.323491] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xb8 [ 690.323754] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xac [ 692.384770] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x98 [ 692.386036] c_can_pci 0000:02:0c.3: can0: write 0x0 to offset 0x0 failed. got: 0xac [ 692.386445] c_can_pci 0000:02:0c.3: can0: write 0x0 to offset 0x0 failed. got: 0xa8 [ 692.386692] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0x28 [ 692.386839] c_can_pci 0000:02:0c.3: can0: write 0x0 to offset 0x0 failed. got: 0xa0 [ 694.447059] c_can_pci 0000:02:0c.3: can0: write 0x0 to offset 0x0 failed. got: 0xac [ 694.447320] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0xa8 [ 694.447443] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x88 [ 694.447459] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xb8 [ 694.447715] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x28 [ 694.447985] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0xa8 [ 694.449055] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x28 [ 694.449327] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0xa8 [ 694.449450] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0x88 [ 696.508763] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xb8 [ 696.509050] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xac [ 696.509586] c_can_pci 0000:02:0c.3: can0: write 0x0 to offset 0x0 failed. got: 0xa8 [ 696.509706] c_can_pci 0000:02:0c.3: can0: write 0x10 to offset 0x20 failed. got: 0x8 [ 696.509971] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0x28 [ 696.510954] c_can_pci 0000:02:0c.3: can0: write 0x10 to offset 0x20 failed. got: 0x8 [ 696.511223] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xa0 [ 698.571318] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0xa8 [ 698.572681] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xa8 [ 700.646608] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0x28 [ 700.647000] c_can_pci 0000:02:0c.3: can0: write 0x0 to offset 0x0 failed. got: 0x88 As you can see, sometimes it needs several write retries to succeed. Nevertheless my test application detects also some problems: > Error on MSG ID 0x252. Got counter 96480 and expected 96466 > Error on MSG ID 0x251. Got counter 96480 and expected 96466 > Error on MSG ID 0x252. Got counter 101706 and expected 101696 > Error on MSG ID 0x251. Got counter 101706 and expected 101696 Here were messages missed/dropped for both CAN-IDs. > Error on MSG ID 0x251. Got counter 108673 and expected 108672 > Error on MSG ID 0x251. Got counter 108672 and expected 108674 > Error on MSG ID 0x251. Got counter 108674 and expected 108673 ^^^^^^ Here you can see the CAN frame with counter 108673 is read before 108672. > Error on MSG ID 0x251. Got counter 117488 and expected 117487 > Error on MSG ID 0x251. Got counter 117487 and expected 117489 > Error on MSG ID 0x251. Got counter 117489 and expected 117488 ^^^^^^ Here you can see the CAN frame with counter 117488 is read before 117487. > Error on MSG ID 0x251. Got counter 142297 and expected 142296 > Error on MSG ID 0x251. Got counter 142296 and expected 142298 > Error on MSG ID 0x251. Got counter 142298 and expected 142297 Same again. > Error on MSG ID 0x251. Got counter 147932 and expected 147924 > Error on MSG ID 0x251. Got counter 147936 and expected 147933 > Error on MSG ID 0x252. Got counter 147936 and expected 147924 > Error on MSG ID 0x251. Got counter 165268 and expected 165267 > Error on MSG ID 0x251. Got counter 218560 and expected 218558 > Error on MSG ID 0x252. Got counter 218560 and expected 218558 > Error on MSG ID 0x252. Got counter 231076 and expected 231075 > Error on MSG ID 0x251. Got counter 231077 and expected 231076 > Error on MSG ID 0x251. Got counter 241959 and expected 241958 Messages missed/dropped again. Below is the patch for c_can. Best regards, Alexander diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c index d63aaa3..da9bbc0 100644 --- a/drivers/net/can/c_can/c_can.c +++ b/drivers/net/can/c_can/c_can.c @@ -1186,6 +1186,7 @@ struct net_device *alloc_c_can_dev(void) CAN_CTRLMODE_BERR_REPORTING; spin_lock_init(&priv->lock); + spin_lock_init(&priv->testlock); return dev; } diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h index 3487d5e..2b58b75 100644 --- a/drivers/net/can/c_can/c_can.h +++ b/drivers/net/can/c_can/c_can.h @@ -173,6 +173,7 @@ struct c_can_priv { unsigned int instance; void (*init) (const struct c_can_priv *priv, bool enable); spinlock_t lock; /* to protect tx and rx message objects */ + spinlock_t testlock; /* to protect tx and rx message objects */ }; struct net_device *alloc_c_can_dev(void); diff --git a/drivers/net/can/c_can/c_can_pci.c b/drivers/net/can/c_can/c_can_pci.c index 2516ea9..0ac4d43 100644 --- a/drivers/net/can/c_can/c_can_pci.c +++ b/drivers/net/can/c_can/c_can_pci.c @@ -74,13 +74,37 @@ static void c_can_pci_write_reg_aligned_to_32bit(struct c_can_priv *priv, static u16 c_can_pci_read_reg_32bit(struct c_can_priv *priv, enum reg index) { - return (u16)ioread32(priv->base + 2 * priv->regs[index]); + unsigned long flags; + u16 reg; + + spin_lock_irqsave(&priv->testlock, flags); + reg = (u16)ioread32(priv->base + 2 * priv->regs[index]); + spin_unlock_irqrestore(&priv->testlock, flags); + + return reg; } static void c_can_pci_write_reg_32bit(struct c_can_priv *priv, enum reg index, u16 val) { - iowrite32((u32)val, priv->base + 2 * priv->regs[index]); + u16 reg; + unsigned long flags; + int retries; + + retries = 0; + + spin_lock_irqsave(&priv->testlock, flags); + + do + { + iowrite32((u32)val, priv->base + 2 * priv->regs[index]); + reg = (u16)ioread32(priv->base + 2 * priv->regs[index]); + if (reg != val) + { + netdev_err(priv->dev, "write 0x%x to offset 0x%x failed. got: 0x%x\n", val, 2 * priv->regs[index], reg); + } + } while ((reg != val) && (retries++ < 20)); + spin_unlock_irqrestore(&priv->testlock, flags); } static void c_can_pci_reset_pch(const struct c_can_priv *priv, bool enable) ^ permalink raw reply related [flat|nested] 38+ messages in thread
* Re: [RFC v2 0/7] pch_can/c_can: fix races and add PCH support to c_can 2012-12-06 13:38 ` Alexander Stein @ 2012-12-06 14:02 ` Marc Kleine-Budde 2012-12-06 14:31 ` Wolfgang Grandegger 1 sibling, 0 replies; 38+ messages in thread From: Marc Kleine-Budde @ 2012-12-06 14:02 UTC (permalink / raw) To: Alexander Stein Cc: Wolfgang Grandegger, linux-can, bhupesh.sharma, tomoya.rohm [-- Attachment #1: Type: text/plain, Size: 3057 bytes --] On 12/06/2012 02:38 PM, Alexander Stein wrote: >>> On the second line you can see that the register isn't written at all (or the >>> read failed for some reason). >> >> I assume the latter. Could you please retry reading the register until >> the correct value shows up. With some timeout, of course. > > I notices having all error events printed on serial console using > pch_uart driver has negative effect (I guess one problem causes > another one), so I setup 'dmesg -n1' to reduce serial load before the > test. Running the test with just one heartbeat triggered LED set > using I2C the test runs without errors. I only see Lots of 'c_can_pci > 0000:02:0c.3: can0: write 0x0 to offset 0x2c failed. got: 0x2000' at > the beginning. It seems this (reserved?) bit is always 1 no matter > what we write. But things start to break when running the test while > running 'watch sensors' (sensors queries several temperature sensors > via I2C) in a seconds ssh session. First off the driver error > messages (omitting the messages as written above): Hmmm, maybe there is a hardware problem, that would not be the first one we've seen in CAN hardware. > [ 384.466217] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xbc [...] > [ 700.647000] c_can_pci 0000:02:0c.3: can0: write 0x0 to offset 0x0 failed. got: 0x88 Your spin lock patches look good. I think it's time to get in contact with your Intel support and try to get through to the hardware people that can look into the VHDL code. > As you can see, sometimes it needs several write retries to succeed. > Nevertheless my test application detects also some problems: >> Error on MSG ID 0x252. Got counter 96480 and expected 96466 >> Error on MSG ID 0x251. Got counter 96480 and expected 96466 >> Error on MSG ID 0x252. Got counter 101706 and expected 101696 >> Error on MSG ID 0x251. Got counter 101706 and expected 101696 > Here were messages missed/dropped for both CAN-IDs. Drops can happen at the hardware level, rx-overflow, or in the socket queueing in linux. Look in the driver if it reports rx-overflows properly and look at the stats. There also is a flag that indicates frame drop at the linux socket level, but I don't remember it. >> Error on MSG ID 0x251. Got counter 108673 and expected 108672 >> Error on MSG ID 0x251. Got counter 108672 and expected 108674 >> Error on MSG ID 0x251. Got counter 108674 and expected 108673 > ^^^^^^ > Here you can see the CAN frame with counter 108673 is read before 108672. This is a typical out-of-sequence reception with a RX-goes-into-first-free-mailbox hardware. I've implemented the algorithm used in the at91 and fixed the one for the ti_hecc. Marc -- Pengutronix e.K. | Marc Kleine-Budde | Industrial Linux Solutions | Phone: +49-231-2826-924 | Vertretung West/Dortmund | Fax: +49-5121-206917-5555 | Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de | [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 261 bytes --] ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC v2 0/7] pch_can/c_can: fix races and add PCH support to c_can 2012-12-06 13:38 ` Alexander Stein 2012-12-06 14:02 ` Marc Kleine-Budde @ 2012-12-06 14:31 ` Wolfgang Grandegger 2012-12-06 14:37 ` Marc Kleine-Budde ` (2 more replies) 1 sibling, 3 replies; 38+ messages in thread From: Wolfgang Grandegger @ 2012-12-06 14:31 UTC (permalink / raw) To: Alexander Stein; +Cc: linux-can, bhupesh.sharma, tomoya.rohm On 12/06/2012 02:38 PM, Alexander Stein wrote: > Hello Wolfgang, > > On Wednesday 05 December 2012 18:35:25, Wolfgang Grandegger wrote: >>>> - The messages look still ok (not currupted, I mean)? >>> >>> The received frames all look good (despite wrong counter sometimes due to >>> wrong order or lost frames). >>> >>>>> Even worse, if I use the following patch to check if PCI writes were >>>>> successfully, I notices that some writes (or the consecutive read) don't >>>>> succeed. And I also get lots of I2C timeouts waiting for a xfer complete. >>>> >>>> Be careful, there might be some registers changing their values after >>>> writing. Can you show the value read after writing and the register >>>> offset? The influence on the I2C bus looks more like an overload or >>>> hardware problem. What is your CAN interrupt rate? >>> >>> I get about 33 interrupts per second on i2c. On a successful run I get 366886 >>> interrupts for 500000 messages with the c_can driver. >> >> In what time? Is the CAN bus highly loaded. > > Busload is about 14-18% according to canbusload with 1MBit. A complete sucessful run takes about 5 minutes. > >>> On the second line you can see that the register isn't written at all (or the >>> read failed for some reason). >> >> I assume the latter. Could you please retry reading the register until >> the correct value shows up. With some timeout, of course. > > I notices having all error events printed on serial console using pch_uart driver has negative effect (I guess one problem causes another one), so I setup 'dmesg -n1' to reduce serial load before the test. > Running the test with just one heartbeat triggered LED set using I2C the test runs without errors. I only see > Lots of 'c_can_pci 0000:02:0c.3: can0: write 0x0 to offset 0x2c failed. got: 0x2000' at the beginning. It seems this (reserved?) bit is always 1 no matter what we write. There are reserved bit! From the manual: "Reserved: This bit is reserved for future expansion. Only “0” is accepted as the write data to the reserved bit. When “1” is written, the operation is not guaranteed." When reading the reserved bit of the IFmMASK2 register (m = 1), a “1” is read. Write a “1” for write. Well, I don't fully understand but it's clear that we always read "1!. > But things start to break when running the test while running 'watch sensors' (sensors queries several temperature sensors via I2C) in a seconds ssh session. > First off the driver error messages (omitting the messages as written above): > [ 384.466217] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xbc Hm... > [ 384.466630] c_can_pci 0000:02:0c.3: can0: write 0x73 to offset 0x24 failed. got: 0xb8 ... > [ 700.646608] c_can_pci 0000:02:0c.3: can0: write 0xe to offset 0x0 failed. got: 0x28 > [ 700.647000] c_can_pci 0000:02:0c.3: can0: write 0x0 to offset 0x0 failed. got: 0x88 > > As you can see, sometimes it needs several write retries to succeed. Nevertheless my test application detects also some problems: OK, obviously the real value needs some time to show up when there is other activity on the bus. This hardware is really special. We need to contact the hardware developers. >> Error on MSG ID 0x252. Got counter 96480 and expected 96466 >> Error on MSG ID 0x251. Got counter 96480 and expected 96466 >> Error on MSG ID 0x252. Got counter 101706 and expected 101696 >> Error on MSG ID 0x251. Got counter 101706 and expected 101696 > Here were messages missed/dropped for both CAN-IDs. It is interesting that the same number of messages are missing for both IDs... which come from different CAN nodes, right? Do you see dropped messages with "ip -d -s link show canX"? Did you check if the protocol layer did drop messages. You can use "candump -d" to find that out. >> Error on MSG ID 0x251. Got counter 108673 and expected 108672 >> Error on MSG ID 0x251. Got counter 108672 and expected 108674 >> Error on MSG ID 0x251. Got counter 108674 and expected 108673 > ^^^^^^ > Here you can see the CAN frame with counter 108673 is read before 108672. You could add some offset/mask to the counter data of MSG ID 0x252 to see if they get mixed up. >> Error on MSG ID 0x251. Got counter 117488 and expected 117487 >> Error on MSG ID 0x251. Got counter 117487 and expected 117489 >> Error on MSG ID 0x251. Got counter 117489 and expected 117488 > ^^^^^^ > Here you can see the CAN frame with counter 117488 is read before 117487. >> Error on MSG ID 0x251. Got counter 142297 and expected 142296 >> Error on MSG ID 0x251. Got counter 142296 and expected 142298 >> Error on MSG ID 0x251. Got counter 142298 and expected 142297 > Same again. >> Error on MSG ID 0x251. Got counter 147932 and expected 147924 >> Error on MSG ID 0x251. Got counter 147936 and expected 147933 >> Error on MSG ID 0x252. Got counter 147936 and expected 147924 >> Error on MSG ID 0x251. Got counter 165268 and expected 165267 >> Error on MSG ID 0x251. Got counter 218560 and expected 218558 >> Error on MSG ID 0x252. Got counter 218560 and expected 218558 >> Error on MSG ID 0x252. Got counter 231076 and expected 231075 >> Error on MSG ID 0x251. Got counter 231077 and expected 231076 >> Error on MSG ID 0x251. Got counter 241959 and expected 241958 > Messages missed/dropped again. > > Below is the patch for c_can. > > Best regards, > Alexander > > diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c > index d63aaa3..da9bbc0 100644 > --- a/drivers/net/can/c_can/c_can.c > +++ b/drivers/net/can/c_can/c_can.c > @@ -1186,6 +1186,7 @@ struct net_device *alloc_c_can_dev(void) > CAN_CTRLMODE_BERR_REPORTING; > > spin_lock_init(&priv->lock); > + spin_lock_init(&priv->testlock); > > return dev; > } > diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h > index 3487d5e..2b58b75 100644 > --- a/drivers/net/can/c_can/c_can.h > +++ b/drivers/net/can/c_can/c_can.h > @@ -173,6 +173,7 @@ struct c_can_priv { > unsigned int instance; > void (*init) (const struct c_can_priv *priv, bool enable); > spinlock_t lock; /* to protect tx and rx message objects */ > + spinlock_t testlock; /* to protect tx and rx message objects */ > }; > > struct net_device *alloc_c_can_dev(void); > diff --git a/drivers/net/can/c_can/c_can_pci.c b/drivers/net/can/c_can/c_can_pci.c > index 2516ea9..0ac4d43 100644 > --- a/drivers/net/can/c_can/c_can_pci.c > +++ b/drivers/net/can/c_can/c_can_pci.c > @@ -74,13 +74,37 @@ static void c_can_pci_write_reg_aligned_to_32bit(struct c_can_priv *priv, > static u16 c_can_pci_read_reg_32bit(struct c_can_priv *priv, > enum reg index) > { > - return (u16)ioread32(priv->base + 2 * priv->regs[index]); > + unsigned long flags; > + u16 reg; > + > + spin_lock_irqsave(&priv->testlock, flags); > + reg = (u16)ioread32(priv->base + 2 * priv->regs[index]); > + spin_unlock_irqrestore(&priv->testlock, flags); > + > + return reg; > } > > static void c_can_pci_write_reg_32bit(struct c_can_priv *priv, > enum reg index, u16 val) > { > - iowrite32((u32)val, priv->base + 2 * priv->regs[index]); > + u16 reg; > + unsigned long flags; > + int retries; > + > + retries = 0; > + > + spin_lock_irqsave(&priv->testlock, flags); > + > + do > + { > + iowrite32((u32)val, priv->base + 2 * priv->regs[index]); I think it's enough to write the message once. > + reg = (u16)ioread32(priv->base + 2 * priv->regs[index]); > + if (reg != val) > + { > + netdev_err(priv->dev, "write 0x%x to offset 0x%x failed. got: 0x%x\n", val, 2 * priv->regs[index], reg); > + } > + } while ((reg != val) && (retries++ < 20)); > + spin_unlock_irqrestore(&priv->testlock, flags); > } > > static void c_can_pci_reset_pch(const struct c_can_priv *priv, bool enable) Wolfgang. ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC v2 0/7] pch_can/c_can: fix races and add PCH support to c_can 2012-12-06 14:31 ` Wolfgang Grandegger @ 2012-12-06 14:37 ` Marc Kleine-Budde 2012-12-06 14:56 ` Alexander Stein 2012-12-06 17:14 ` Alexander Stein 2 siblings, 0 replies; 38+ messages in thread From: Marc Kleine-Budde @ 2012-12-06 14:37 UTC (permalink / raw) To: Wolfgang Grandegger Cc: Alexander Stein, linux-can, bhupesh.sharma, tomoya.rohm [-- Attachment #1: Type: text/plain, Size: 1452 bytes --] On 12/06/2012 03:31 PM, Wolfgang Grandegger wrote: >> >> static void c_can_pci_write_reg_32bit(struct c_can_priv *priv, >> enum reg index, u16 val) >> { >> - iowrite32((u32)val, priv->base + 2 * priv->regs[index]); >> + u16 reg; >> + unsigned long flags; >> + int retries; >> + >> + retries = 0; >> + >> + spin_lock_irqsave(&priv->testlock, flags); >> + >> + do >> + { >> + iowrite32((u32)val, priv->base + 2 * priv->regs[index]); > > I think it's enough to write the message once. It's a different test, but also very interesting. > >> + reg = (u16)ioread32(priv->base + 2 * priv->regs[index]); >> + if (reg != val) >> + { >> + netdev_err(priv->dev, "write 0x%x to offset 0x%x failed. got: 0x%x\n", val, 2 * priv->regs[index], reg); >> + } >> + } while ((reg != val) && (retries++ < 20)); >> + spin_unlock_irqrestore(&priv->testlock, flags); >> } >> >> static void c_can_pci_reset_pch(const struct c_can_priv *priv, bool enable)> Marc -- Pengutronix e.K. | Marc Kleine-Budde | Industrial Linux Solutions | Phone: +49-231-2826-924 | Vertretung West/Dortmund | Fax: +49-5121-206917-5555 | Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de | [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 261 bytes --] ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC v2 0/7] pch_can/c_can: fix races and add PCH support to c_can 2012-12-06 14:31 ` Wolfgang Grandegger 2012-12-06 14:37 ` Marc Kleine-Budde @ 2012-12-06 14:56 ` Alexander Stein 2012-12-06 15:15 ` Wolfgang Grandegger 2012-12-06 17:14 ` Alexander Stein 2 siblings, 1 reply; 38+ messages in thread From: Alexander Stein @ 2012-12-06 14:56 UTC (permalink / raw) To: Wolfgang Grandegger; +Cc: linux-can, bhupesh.sharma, tomoya.rohm Hello Wolfgang, On Thursday 06 December 2012 15:31:20, Wolfgang Grandegger wrote: > > diff --git a/drivers/net/can/c_can/c_can_pci.c b/drivers/net/can/c_can/c_can_pci.c > > index 2516ea9..0ac4d43 100644 > > --- a/drivers/net/can/c_can/c_can_pci.c > > +++ b/drivers/net/can/c_can/c_can_pci.c > > @@ -74,13 +74,37 @@ static void c_can_pci_write_reg_aligned_to_32bit(struct c_can_priv *priv, > > static u16 c_can_pci_read_reg_32bit(struct c_can_priv *priv, > > enum reg index) > > { > > - return (u16)ioread32(priv->base + 2 * priv->regs[index]); > > + unsigned long flags; > > + u16 reg; > > + > > + spin_lock_irqsave(&priv->testlock, flags); > > + reg = (u16)ioread32(priv->base + 2 * priv->regs[index]); > > + spin_unlock_irqrestore(&priv->testlock, flags); > > + > > + return reg; > > } > > > > static void c_can_pci_write_reg_32bit(struct c_can_priv *priv, > > enum reg index, u16 val) > > { > > - iowrite32((u32)val, priv->base + 2 * priv->regs[index]); > > + u16 reg; > > + unsigned long flags; > > + int retries; > > + > > + retries = 0; > > + > > + spin_lock_irqsave(&priv->testlock, flags); > > + > > + do > > + { > > + iowrite32((u32)val, priv->base + 2 * priv->regs[index]); > > I think it's enough to write the message once. I can reply to this one immediatly. Not it is not sufficent to write once. This was my 1st implementation (iowrite32 just above the do) and noticed in case the write doesn't succeed I won't succeed until all ioread32 have passed. IMO I must write again if it failed before. Alexander ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC v2 0/7] pch_can/c_can: fix races and add PCH support to c_can 2012-12-06 14:56 ` Alexander Stein @ 2012-12-06 15:15 ` Wolfgang Grandegger 2012-12-06 15:27 ` Wolfgang Grandegger 0 siblings, 1 reply; 38+ messages in thread From: Wolfgang Grandegger @ 2012-12-06 15:15 UTC (permalink / raw) To: Alexander Stein; +Cc: linux-can, bhupesh.sharma, tomoya.rohm On 12/06/2012 03:56 PM, Alexander Stein wrote: > Hello Wolfgang, > > On Thursday 06 December 2012 15:31:20, Wolfgang Grandegger wrote: >>> diff --git a/drivers/net/can/c_can/c_can_pci.c b/drivers/net/can/c_can/c_can_pci.c >>> index 2516ea9..0ac4d43 100644 >>> --- a/drivers/net/can/c_can/c_can_pci.c >>> +++ b/drivers/net/can/c_can/c_can_pci.c >>> @@ -74,13 +74,37 @@ static void c_can_pci_write_reg_aligned_to_32bit(struct c_can_priv *priv, >>> static u16 c_can_pci_read_reg_32bit(struct c_can_priv *priv, >>> enum reg index) >>> { >>> - return (u16)ioread32(priv->base + 2 * priv->regs[index]); >>> + unsigned long flags; >>> + u16 reg; >>> + >>> + spin_lock_irqsave(&priv->testlock, flags); >>> + reg = (u16)ioread32(priv->base + 2 * priv->regs[index]); >>> + spin_unlock_irqrestore(&priv->testlock, flags); >>> + >>> + return reg; >>> } >>> >>> static void c_can_pci_write_reg_32bit(struct c_can_priv *priv, >>> enum reg index, u16 val) >>> { >>> - iowrite32((u32)val, priv->base + 2 * priv->regs[index]); >>> + u16 reg; >>> + unsigned long flags; >>> + int retries; >>> + >>> + retries = 0; >>> + >>> + spin_lock_irqsave(&priv->testlock, flags); >>> + >>> + do >>> + { >>> + iowrite32((u32)val, priv->base + 2 * priv->regs[index]); >> >> I think it's enough to write the message once. > > I can reply to this one immediatly. Not it is not sufficent to write once. This was my 1st implementation (iowrite32 just above the do) and noticed in case the write doesn't succeed I won't succeed until all ioread32 have passed. IMO I must write again if it failed before. Puh, even worse. Then I'm really surprised that the driver continues to work more or less properly. Anyway, sometime it takes up to 500+ us for the good value to show up. If we have a real write-read sequence to the same register, everything can happen. Looks like broken hardware. Wolfgang. ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC v2 0/7] pch_can/c_can: fix races and add PCH support to c_can 2012-12-06 15:15 ` Wolfgang Grandegger @ 2012-12-06 15:27 ` Wolfgang Grandegger 2012-12-06 15:55 ` Alexander Stein 0 siblings, 1 reply; 38+ messages in thread From: Wolfgang Grandegger @ 2012-12-06 15:27 UTC (permalink / raw) To: Alexander Stein; +Cc: linux-can, bhupesh.sharma, tomoya.rohm On 12/06/2012 04:15 PM, Wolfgang Grandegger wrote: > On 12/06/2012 03:56 PM, Alexander Stein wrote: >> Hello Wolfgang, >> >> On Thursday 06 December 2012 15:31:20, Wolfgang Grandegger wrote: >>>> diff --git a/drivers/net/can/c_can/c_can_pci.c b/drivers/net/can/c_can/c_can_pci.c >>>> index 2516ea9..0ac4d43 100644 >>>> --- a/drivers/net/can/c_can/c_can_pci.c >>>> +++ b/drivers/net/can/c_can/c_can_pci.c >>>> @@ -74,13 +74,37 @@ static void c_can_pci_write_reg_aligned_to_32bit(struct c_can_priv *priv, >>>> static u16 c_can_pci_read_reg_32bit(struct c_can_priv *priv, >>>> enum reg index) >>>> { >>>> - return (u16)ioread32(priv->base + 2 * priv->regs[index]); >>>> + unsigned long flags; >>>> + u16 reg; >>>> + >>>> + spin_lock_irqsave(&priv->testlock, flags); >>>> + reg = (u16)ioread32(priv->base + 2 * priv->regs[index]); >>>> + spin_unlock_irqrestore(&priv->testlock, flags); >>>> + >>>> + return reg; >>>> } >>>> >>>> static void c_can_pci_write_reg_32bit(struct c_can_priv *priv, >>>> enum reg index, u16 val) >>>> { >>>> - iowrite32((u32)val, priv->base + 2 * priv->regs[index]); >>>> + u16 reg; >>>> + unsigned long flags; >>>> + int retries; >>>> + >>>> + retries = 0; >>>> + >>>> + spin_lock_irqsave(&priv->testlock, flags); >>>> + >>>> + do >>>> + { >>>> + iowrite32((u32)val, priv->base + 2 * priv->regs[index]); >>> >>> I think it's enough to write the message once. >> >> I can reply to this one immediatly. Not it is not sufficent to write once. This was my 1st implementation (iowrite32 just above the do) and noticed in case the write doesn't succeed I won't succeed until all ioread32 have passed. IMO I must write again if it failed before. > > Puh, even worse. Then I'm really surprised that the driver continues to > work more or less properly. Anyway, sometime it takes up to 500+ us for > the good value to show up. If we have a real write-read sequence to the > same register, everything can happen. Looks like broken hardware. Could you show the output of "lspci -vv" of your system? Wolfgang. ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC v2 0/7] pch_can/c_can: fix races and add PCH support to c_can 2012-12-06 15:27 ` Wolfgang Grandegger @ 2012-12-06 15:55 ` Alexander Stein 0 siblings, 0 replies; 38+ messages in thread From: Alexander Stein @ 2012-12-06 15:55 UTC (permalink / raw) To: Wolfgang Grandegger; +Cc: linux-can, bhupesh.sharma, tomoya.rohm Hello Wolfgang, On Thursday 06 December 2012 16:27:55, Wolfgang Grandegger wrote: > >>> I think it's enough to write the message once. > >> > >> I can reply to this one immediatly. Not it is not sufficent to write once. This was my 1st implementation (iowrite32 just above the do) and noticed in case the write doesn't succeed I won't succeed until all ioread32 have passed. IMO I must write again if it failed before. > > > > Puh, even worse. Then I'm really surprised that the driver continues to > > work more or less properly. Anyway, sometime it takes up to 500+ us for > > the good value to show up. If we have a real write-read sequence to the > > same register, everything can happen. Looks like broken hardware. > > Could you show the output of "lspci -vv" of your system? Here we go, Alexander 00:00.0 Host bridge: Intel Corporation Device 4114 (rev 05) Subsystem: Intel Corporation Device 4108 Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- Status: Cap- 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0 00:01.0 Host bridge: Intel Corporation Device 8183 (rev 02) Subsystem: Intel Corporation Device 8186 Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- Status: Cap- 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0 00:02.0 Display controller: Intel Corporation Device 4108 (rev 05) Subsystem: Intel Corporation Device 4108 Control: I/O- Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Interrupt: pin A routed to IRQ 255 Region 0: Memory at a0200000 (32-bit, non-prefetchable) [disabled] [size=1M] Region 1: I/O ports at 4008 [disabled] [size=8] Region 2: Memory at 90000000 (32-bit, non-prefetchable) [disabled] [size=256M] Region 3: Memory at a03c0000 (32-bit, non-prefetchable) [disabled] [size=256K] Capabilities: [d0] Power Management version 2 Flags: PMEClk- DSI+ D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Capabilities: [b0] Vendor Specific Information <?> Capabilities: [90] MSI: Mask- 64bit- Count=1/1 Enable- Address: 00000000 Data: 0000 00:03.0 Multimedia video controller: Intel Corporation Device 8182 (rev 02) Subsystem: Intel Corporation Device 8186 Control: I/O- Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Interrupt: pin A routed to IRQ 255 Region 0: Memory at a0300000 (32-bit, non-prefetchable) [disabled] [size=512K] Region 1: I/O ports at 4000 [disabled] [size=8] Region 2: Memory at 80000000 (32-bit, non-prefetchable) [disabled] [size=256M] Region 3: Memory at a0380000 (32-bit, non-prefetchable) [disabled] [size=256K] Capabilities: [d0] Power Management version 2 Flags: PMEClk- DSI+ D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Capabilities: [b0] Vendor Specific Information <?> Capabilities: [90] MSI: Mask- 64bit- Count=1/1 Enable- Address: 00000000 Data: 0000 00:17.0 PCI bridge: Intel Corporation Device 8184 (rev 02) (prog-if 00 [Normal decode]) Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0 Bus: primary=00, secondary=01, subordinate=02, sec-latency=0 I/O behind bridge: 00003000-00003fff Memory behind bridge: a0100000-a01fffff Prefetchable memory behind bridge: 40000000-401fffff Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- <SERR- <PERR- BridgeCtl: Parity- SERR- NoISA- VGA- MAbort- >Reset- FastB2B- PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn- Capabilities: [40] Express (v1) Root Port (Slot-), MSI 00 DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s unlimited, L1 unlimited ExtTag- RBE+ FLReset- DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported- RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop- MaxPayload 128 bytes, MaxReadReq 128 bytes DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr+ TransPend- LnkCap: Port #1, Speed 2.5GT/s, Width x1, ASPM L0s L1, Latency L0 <256ns, L1 <4us ClockPM+ Surprise- LLActRep+ BwNot- LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- Retrain- CommClk+ ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt- LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive+ BWMgmt+ ABWMgmt- RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna+ CRSVisible- RootCap: CRSVisible- RootSta: PME ReqID 0000, PMEStatus- PMEPending- Capabilities: [90] Subsystem: Intel Corporation Device 8186 Capabilities: [a0] Power Management version 2 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Capabilities: [100] Virtual Channel <?> Kernel driver in use: pcieport 00:18.0 PCI bridge: Intel Corporation Device 8185 (rev 02) (prog-if 00 [Normal decode]) Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0 Bus: primary=00, secondary=03, subordinate=03, sec-latency=0 I/O behind bridge: 00002000-00002fff Memory behind bridge: a0000000-a00fffff Prefetchable memory behind bridge: 40200000-403fffff Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- <SERR- <PERR- BridgeCtl: Parity- SERR- NoISA- VGA- MAbort- >Reset- FastB2B- PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn- Capabilities: [40] Express (v1) Root Port (Slot+), MSI 00 DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s unlimited, L1 unlimited ExtTag- RBE+ FLReset- DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported- RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop- MaxPayload 128 bytes, MaxReadReq 128 bytes DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr+ TransPend- LnkCap: Port #2, Speed 2.5GT/s, Width x1, ASPM L0s L1, Latency L0 <256ns, L1 <4us ClockPM+ Surprise- LLActRep+ BwNot- LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- Retrain- CommClk+ ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt- LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive+ BWMgmt+ ABWMgmt- SltCap: AttnBtn- PwrCtrl- MRL- AttnInd- PwrInd- HotPlug+ Surpise+ Slot # 2, PowerLimit 10.000000; Interlock- NoCompl- SltCtl: Enable: AttnBtn- PwrFlt- MRL- PresDet+ CmdCplt+ HPIrq+ LinkChg- Control: AttnInd Unknown, PwrInd Unknown, Power- Interlock- SltSta: Status: AttnBtn- PowerFlt- MRL- CmdCplt- PresDet+ Interlock- Changed: MRL- PresDet- LinkState+ RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna+ CRSVisible- RootCap: CRSVisible- RootSta: PME ReqID 0000, PMEStatus- PMEPending- Capabilities: [90] Subsystem: Intel Corporation Device 8186 Capabilities: [a0] Power Management version 2 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Capabilities: [100] Virtual Channel <?> Kernel driver in use: pcieport 00:1b.0 Audio device: Intel Corporation System Controller Hub (SCH Poulsbo) HD Audio Controller (rev 02) Subsystem: Intel Corporation Device 8186 Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0 Interrupt: pin A routed to IRQ 16 Region 0: Memory at a0400000 (64-bit, non-prefetchable) [size=16K] Capabilities: [50] Power Management version 2 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold-) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Capabilities: [70] Express (v1) Root Complex Integrated Endpoint, MSI 00 DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us ExtTag- RBE- FLReset- DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported- RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop- MaxPayload 128 bytes, MaxReadReq 128 bytes DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr- TransPend- LnkCap: Port #0, Speed unknown, Width x0, ASPM unknown, Latency L0 <64ns, L1 <1us ClockPM- Surprise- LLActRep- BwNot- LnkCtl: ASPM L0s Enabled; Disabled- Retrain- CommClk- ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt- LnkSta: Speed unknown, Width x0, TrErr- Train- SlotClk- DLActive- BWMgmt- ABWMgmt- Capabilities: [100] Virtual Channel <?> Capabilities: [130] Root Complex Link <?> Kernel driver in use: HDA Intel 00:1f.0 ISA bridge: Intel Corporation Device 8186 (rev 02) Subsystem: Intel Corporation Device 8186 Control: I/O+ Mem+ BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- Status: Cap- 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Kernel driver in use: lpc_sch 01:00.0 PCI bridge: Intel Corporation Device 8800 (rev 01) (prog-if 00 [Normal decode]) Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0 Bus: primary=01, secondary=02, subordinate=02, sec-latency=0 I/O behind bridge: 00003000-00003fff Memory behind bridge: a0100000-a01fffff Prefetchable memory behind bridge: 0000000040000000-00000000400fffff Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- <SERR- <PERR- Expansion ROM at 40100000 [disabled] [size=64K] BridgeCtl: Parity- SERR- NoISA- VGA- MAbort- >Reset- FastB2B- PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn- Capabilities: [40] Power Management version 2 Flags: PMEClk- DSI- D1+ D2- AuxCurrent=0mA PME(D0+,D1+,D2-,D3hot+,D3cold+) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Capabilities: [70] Express (v2) PCI/PCI-X Bridge, MSI 00 DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us ExtTag+ AttnBtn- AttnInd- PwrInd- RBE+ FLReset- DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported- RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop- BrConfRtry- MaxPayload 128 bytes, MaxReadReq 512 bytes DevSta: CorrErr+ UncorrErr- FatalErr- UnsuppReq+ AuxPwr+ TransPend- LnkCap: Port #0, Speed 2.5GT/s, Width x1, ASPM L0s L1, Latency L0 <512ns, L1 <64us ClockPM- Surprise- LLActRep- BwNot- LnkCtl: ASPM Disabled; Disabled- Retrain- CommClk+ ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt- LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt- DevCap2: Completion Timeout: Not Supported, TimeoutDis- DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis- LnkCtl2: Target Link Speed: 2.5GT/s, EnterCompliance- SpeedDis-, Selectable De-emphasis: -6dB Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS- Compliance De-emphasis: -6dB LnkSta2: Current De-emphasis Level: -6dB 02:00.0 Class ff00: Intel Corporation Device 8801 (rev 01) Subsystem: Intel Corporation Device 8801 Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0 Region 1: Memory at a0102000 (32-bit, non-prefetchable) [size=2K] Expansion ROM at 40000000 [disabled] [size=128K] Capabilities: [40] MSI: Mask- 64bit- Count=1/1 Enable- Address: 00000000 Data: 0000 Capabilities: [50] Power Management version 2 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Kernel driver in use: pch_phub 02:00.1 Ethernet controller: Intel Corporation Device 8802 (rev 02) Subsystem: Intel Corporation Device 8802 Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+ Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0 Interrupt: pin A routed to IRQ 55 Region 0: I/O ports at 3020 [size=32] Region 1: Memory at a0107000 (32-bit, non-prefetchable) [size=512] Capabilities: [40] MSI: Mask- 64bit- Count=1/1 Enable+ Address: fee0300c Data: 41d1 Capabilities: [50] Power Management version 2 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Kernel driver in use: pch_gbe Kernel modules: pch_gbe 02:00.2 Class ff00: Intel Corporation Device 8803 (rev 01) Subsystem: Intel Corporation Device 8803 Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+ Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0 Interrupt: pin A routed to IRQ 40 Region 1: Memory at a0114000 (32-bit, non-prefetchable) [size=64] Capabilities: [40] MSI: Mask- 64bit- Count=1/1 Enable+ Address: fee0300c Data: 4149 Capabilities: [50] Power Management version 2 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Kernel driver in use: pch_gpio 02:02.0 USB Controller: Intel Corporation Device 8804 (rev 02) (prog-if 10 [OHCI]) Subsystem: Intel Corporation Device 8804 Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0 Interrupt: pin B routed to IRQ 19 Region 0: Memory at a0113000 (32-bit, non-prefetchable) [size=256] Capabilities: [40] MSI: Mask- 64bit- Count=1/1 Enable- Address: 00000000 Data: 0000 Capabilities: [50] Power Management version 2 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Kernel driver in use: ohci_hcd 02:02.1 USB Controller: Intel Corporation Device 8805 (rev 02) (prog-if 10 [OHCI]) Subsystem: Intel Corporation Device 8805 Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0 Interrupt: pin B routed to IRQ 19 Region 0: Memory at a0112000 (32-bit, non-prefetchable) [size=256] Capabilities: [40] MSI: Mask- 64bit- Count=1/1 Enable- Address: 00000000 Data: 0000 Capabilities: [50] Power Management version 2 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Kernel driver in use: ohci_hcd 02:02.2 USB Controller: Intel Corporation Device 8806 (rev 02) (prog-if 10 [OHCI]) Subsystem: Intel Corporation Device 8806 Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0 Interrupt: pin B routed to IRQ 19 Region 0: Memory at a0111000 (32-bit, non-prefetchable) [size=256] Capabilities: [40] MSI: Mask- 64bit- Count=1/1 Enable- Address: 00000000 Data: 0000 Capabilities: [50] Power Management version 2 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Kernel driver in use: ohci_hcd 02:02.3 USB Controller: Intel Corporation Device 8807 (rev 02) (prog-if 20 [EHCI]) Subsystem: Intel Corporation Device 8807 Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0 Interrupt: pin B routed to IRQ 19 Region 0: Memory at a0110000 (32-bit, non-prefetchable) [size=256] Capabilities: [40] MSI: Mask- 64bit- Count=1/1 Enable- Address: 00000000 Data: 0000 Capabilities: [50] Power Management version 2 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Kernel driver in use: ehci_hcd 02:02.4 USB Controller: Intel Corporation Device 8808 (rev 02) (prog-if fe [USB Device]) Subsystem: Intel Corporation Device 8808 Control: I/O- Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Interrupt: pin B routed to IRQ 255 Region 1: Memory at a0100000 (32-bit, non-prefetchable) [disabled] [size=8K] Capabilities: [40] MSI: Mask- 64bit- Count=1/1 Enable- Address: 00000000 Data: 0000 Capabilities: [50] Power Management version 2 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-) Status: D0 PME-Enable- DSel=0 DScale=0 PME- 02:04.0 SD Host controller: Intel Corporation Device 8809 (rev 01) (prog-if 01) Subsystem: Intel Corporation Device 8809 Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+ Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0 Interrupt: pin C routed to IRQ 49 Region 0: Memory at a0106000 (32-bit, non-prefetchable) [size=512] Capabilities: [80] MSI: Mask- 64bit- Count=1/1 Enable+ Address: fee0300c Data: 41a1 Capabilities: [90] Power Management version 2 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Kernel driver in use: sdhci-pci 02:04.1 SD Host controller: Intel Corporation Device 880a (rev 01) (prog-if 01) Subsystem: Intel Corporation Device 880a Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+ Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0 Interrupt: pin C routed to IRQ 50 Region 0: Memory at a0105000 (32-bit, non-prefetchable) [size=512] Capabilities: [80] MSI: Mask- 64bit- Count=1/1 Enable+ Address: fee0300c Data: 41a9 Capabilities: [90] Power Management version 2 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Kernel driver in use: sdhci-pci 02:06.0 SATA controller: Intel Corporation Device 880b (rev 02) (prog-if 01 [AHCI 1.0]) Subsystem: Intel Corporation Device 880b Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+ Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0 Interrupt: pin D routed to IRQ 47 Region 4: I/O ports at 3000 [size=32] Region 5: Memory at a0103000 (32-bit, non-prefetchable) [size=1K] Expansion ROM at 40020000 [disabled] [size=128K] Capabilities: [40] MSI: Mask- 64bit- Count=1/1 Enable+ Address: fee0300c Data: 4191 Capabilities: [50] Power Management version 2 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Capabilities: [60] SATA HBA <?> Kernel driver in use: ahci 02:08.0 USB Controller: Intel Corporation Device 880c (rev 02) (prog-if 10 [OHCI]) Subsystem: Intel Corporation Device 880c Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0 Interrupt: pin A routed to IRQ 16 Region 0: Memory at a010f000 (32-bit, non-prefetchable) [size=256] Capabilities: [40] MSI: Mask- 64bit- Count=1/1 Enable- Address: 00000000 Data: 0000 Capabilities: [50] Power Management version 2 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Kernel driver in use: ohci_hcd 02:08.1 USB Controller: Intel Corporation Device 880d (rev 02) (prog-if 10 [OHCI]) Subsystem: Intel Corporation Device 880d Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0 Interrupt: pin A routed to IRQ 16 Region 0: Memory at a010e000 (32-bit, non-prefetchable) [size=256] Capabilities: [40] MSI: Mask- 64bit- Count=1/1 Enable- Address: 00000000 Data: 0000 Capabilities: [50] Power Management version 2 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Kernel driver in use: ohci_hcd 02:08.2 USB Controller: Intel Corporation Device 880e (rev 02) (prog-if 10 [OHCI]) Subsystem: Intel Corporation Device 880e Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0 Interrupt: pin A routed to IRQ 16 Region 0: Memory at a010d000 (32-bit, non-prefetchable) [size=256] Capabilities: [40] MSI: Mask- 64bit- Count=1/1 Enable- Address: 00000000 Data: 0000 Capabilities: [50] Power Management version 2 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Kernel driver in use: ohci_hcd 02:08.3 USB Controller: Intel Corporation Device 880f (rev 02) (prog-if 20 [EHCI]) Subsystem: Intel Corporation Device 880f Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0 Interrupt: pin A routed to IRQ 16 Region 0: Memory at a010c000 (32-bit, non-prefetchable) [size=256] Capabilities: [40] MSI: Mask- 64bit- Count=1/1 Enable- Address: 00000000 Data: 0000 Capabilities: [50] Power Management version 2 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Kernel driver in use: ehci_hcd 02:0a.0 Class ff00: Intel Corporation Device 8810 Subsystem: Intel Corporation Device 8810 Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+ Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0 Interrupt: pin B routed to IRQ 41 Region 1: Memory at a010b000 (32-bit, non-prefetchable) [size=256] Capabilities: [40] MSI: Mask- 64bit- Count=1/1 Enable+ Address: fee0300c Data: 4151 Capabilities: [50] Power Management version 2 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Capabilities: [60] #00 [0000] Kernel driver in use: pch-dma 02:0a.1 Serial controller: Intel Corporation Device 8811 (rev 01) (prog-if 02 [16550]) Subsystem: Intel Corporation Device 8811 Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+ Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0 Interrupt: pin B routed to IRQ 43 Region 0: I/O ports at 3058 [size=8] Region 1: Memory at a0119000 (32-bit, non-prefetchable) [size=16] Capabilities: [40] MSI: Mask- 64bit- Count=1/1 Enable+ Address: fee0300c Data: 4169 Capabilities: [50] Power Management version 2 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Kernel driver in use: pch_uart 02:0a.2 Serial controller: Intel Corporation Device 8812 (prog-if 02 [16550]) Subsystem: Intel Corporation Device 8812 Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+ Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0 Interrupt: pin B routed to IRQ 44 Region 0: I/O ports at 3050 [size=8] Region 1: Memory at a0118000 (32-bit, non-prefetchable) [size=16] Capabilities: [40] MSI: Mask- 64bit- Count=1/1 Enable+ Address: fee0300c Data: 4171 Capabilities: [50] Power Management version 2 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Kernel driver in use: pch_uart 02:0a.3 Serial controller: Intel Corporation Device 8813 (prog-if 02 [16550]) Subsystem: Intel Corporation Device 8813 Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+ Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0 Interrupt: pin B routed to IRQ 45 Region 0: I/O ports at 3048 [size=8] Region 1: Memory at a0117000 (32-bit, non-prefetchable) [size=16] Capabilities: [40] MSI: Mask- 64bit- Count=1/1 Enable+ Address: fee0300c Data: 4179 Capabilities: [50] Power Management version 2 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Kernel driver in use: pch_uart 02:0a.4 Serial controller: Intel Corporation Device 8814 (prog-if 02 [16550]) Subsystem: Intel Corporation Device 8814 Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+ Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0 Interrupt: pin B routed to IRQ 46 Region 0: I/O ports at 3040 [size=8] Region 1: Memory at a0116000 (32-bit, non-prefetchable) [size=16] Capabilities: [40] MSI: Mask- 64bit- Count=1/1 Enable+ Address: fee0300c Data: 4181 Capabilities: [50] Power Management version 2 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Kernel driver in use: pch_uart 02:0c.0 Class ff00: Intel Corporation Device 8815 Subsystem: Intel Corporation Device 8815 Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+ Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0 Interrupt: pin C routed to IRQ 42 Region 1: Memory at a010a000 (32-bit, non-prefetchable) [size=256] Capabilities: [40] MSI: Mask- 64bit- Count=1/1 Enable+ Address: fee0300c Data: 4161 Capabilities: [50] Power Management version 2 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Capabilities: [60] #00 [0000] Kernel driver in use: pch-dma 02:0c.1 Serial bus controller [0c80]: Intel Corporation Device 8816 Subsystem: Intel Corporation Device 8816 Control: I/O- Mem+ BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+ Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Interrupt: pin C routed to IRQ 48 Region 1: Memory at a0115000 (32-bit, non-prefetchable) [size=32] Capabilities: [40] MSI: Mask- 64bit- Count=1/1 Enable+ Address: fee0300c Data: 4199 Capabilities: [50] Power Management version 2 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Kernel driver in use: pch_spi 02:0c.2 Serial bus controller [0c80]: Intel Corporation Device 8817 Subsystem: Intel Corporation Device 8817 Control: I/O- Mem+ BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Interrupt: pin C routed to IRQ 18 Region 1: Memory at a0109000 (32-bit, non-prefetchable) [size=256] Capabilities: [40] MSI: Mask- 64bit- Count=1/1 Enable- Address: 00000000 Data: 0000 Capabilities: [50] Power Management version 2 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Kernel driver in use: i2c_eg20t 02:0c.3 CANBUS: Intel Corporation Device 8818 Subsystem: Intel Corporation Device 8818 Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+ Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0 Interrupt: pin C routed to IRQ 51 Region 1: Memory at a0104000 (32-bit, non-prefetchable) [size=512] Capabilities: [40] MSI: Mask- 64bit- Count=1/1 Enable+ Address: fee0300c Data: 41b1 Capabilities: [50] Power Management version 2 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Kernel driver in use: c_can_pci Kernel modules: c_can_pci 02:0c.4 Class ff00: Intel Corporation Device 8819 (rev 01) Subsystem: Intel Corporation Device 8819 Control: I/O- Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Interrupt: pin C routed to IRQ 255 Region 1: Memory at a0108000 (32-bit, non-prefetchable) [disabled] [size=256] Capabilities: [40] MSI: Mask- 64bit- Count=1/1 Enable- Address: 00000000 Data: 0000 Capabilities: [50] Power Management version 2 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-) Status: D0 PME-Enable- DSel=0 DScale=0 PME- 03:00.0 Ethernet controller: Intel Corporation 82574L Gigabit Network Connection Subsystem: Intel Corporation Device 0000 Physical Slot: 2 Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+ Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0, Cache Line Size: 64 bytes Interrupt: pin A routed to IRQ 17 Region 0: Memory at a0000000 (32-bit, non-prefetchable) [size=128K] Region 2: I/O ports at 2000 [disabled] [size=32] Region 3: Memory at a0020000 (32-bit, non-prefetchable) [size=16K] Expansion ROM at 40200000 [disabled] [size=2K] Capabilities: [c8] Power Management version 2 Flags: PMEClk- DSI+ D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+) Status: D0 PME-Enable- DSel=0 DScale=1 PME- Capabilities: [d0] MSI: Mask- 64bit+ Count=1/1 Enable- Address: 0000000000000000 Data: 0000 Capabilities: [e0] Express (v1) Endpoint, MSI 00 DevCap: MaxPayload 256 bytes, PhantFunc 0, Latency L0s <512ns, L1 <64us ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset- DevCtl: Report errors: Correctable+ Non-Fatal+ Fatal+ Unsupported+ RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop+ MaxPayload 128 bytes, MaxReadReq 512 bytes DevSta: CorrErr+ UncorrErr- FatalErr- UnsuppReq+ AuxPwr+ TransPend- LnkCap: Port #0, Speed 2.5GT/s, Width x1, ASPM L0s L1, Latency L0 <2us, L1 <64us ClockPM- Surprise- LLActRep- BwNot- LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- Retrain- CommClk+ ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt- LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt- Capabilities: [a0] MSI-X: Enable+ Mask- TabSize=5 Vector table: BAR=3 offset=00000000 PBA: BAR=3 offset=00002000 Capabilities: [100] Advanced Error Reporting UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol- UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol- UESvrt: DLP+ SDES- TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol- CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+ CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+ AERCap: First Error Pointer: 00, GenCap- CGenEn- ChkCap- ChkEn- Capabilities: [140] Device Serial Number f6-01-f8-ff-ff-c2-50-00 Kernel driver in use: e1000e Kernel modules: e1000e ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC v2 0/7] pch_can/c_can: fix races and add PCH support to c_can 2012-12-06 14:31 ` Wolfgang Grandegger 2012-12-06 14:37 ` Marc Kleine-Budde 2012-12-06 14:56 ` Alexander Stein @ 2012-12-06 17:14 ` Alexander Stein 2012-12-06 23:34 ` Marc Kleine-Budde 2 siblings, 1 reply; 38+ messages in thread From: Alexander Stein @ 2012-12-06 17:14 UTC (permalink / raw) To: Wolfgang Grandegger, Marc Kleine-Budde Cc: linux-can, bhupesh.sharma, tomoya.rohm Hello Wolfgang, On Thursday 06 December 2012 15:31:20, Wolfgang Grandegger wrote: > >> Error on MSG ID 0x252. Got counter 96480 and expected 96466 > >> Error on MSG ID 0x251. Got counter 96480 and expected 96466 > >> Error on MSG ID 0x252. Got counter 101706 and expected 101696 > >> Error on MSG ID 0x251. Got counter 101706 and expected 101696 > > Here were messages missed/dropped for both CAN-IDs. > > It is interesting that the same number of messages are missing for both > IDs... which come from different CAN nodes, right? Yep, node 1 sends 0x251 and node 2 sends 0x252. > Do you see dropped messages with "ip -d -s link show canX"? > Did you check if the protocol layer did drop messages. You can > use "candump -d" to find that out. My test application says: Error on MSG ID 0x251. Got counter 8442 and expected 8427 Error on MSG ID 0x252. Got counter 8442 and expected 8426 Error on MSG ID 0x251. Got counter 8794 and expected 8792 Error on MSG ID 0x252. Got counter 8794 and expected 8791 Message counters: 0x251: 249982, 0x252: 249980 ip -s -d link show can0: 3: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN qlen 10 link/can can state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 0 bitrate 1000000 sample-point 0.700 tq 100 prop-seg 3 phase-seg1 3 phase-seg2 3 sjw 1 c_can: tseg1 2..16 tseg2 1..8 sjw 1..4 brp 1..1024 brp-inc 1 clock 50000000 re-started bus-errors arbit-lost error-warn error-pass bus-off 0 0 0 0 0 0 RX: bytes packets errors dropped overrun mcast 1999980 501239 0 0 0 0 TX: bytes packets errors dropped carrier collsns 8 1 0 0 0 0 candump -d can0,0~0,#ffffffff didn't show anything. I used the filter to reduce the load from that ssh session. On Thursday 06 December 2012 15:02:39, Marc Kleine-Budde wrote: > >> Error on MSG ID 0x251. Got counter 108673 and expected 108672 > >> Error on MSG ID 0x251. Got counter 108672 and expected 108674 > >> Error on MSG ID 0x251. Got counter 108674 and expected 108673 > > ^^^^^^ > > Here you can see the CAN frame with counter 108673 is read before 108672. > > You could add some offset/mask to the counter data of MSG ID 0x252 to > see if they get mixed up. Yep, nice idea. But I've no idea whether I get the possibility to modify the firmware for that. > This is a typical out-of-sequence reception with a > RX-goes-into-first-free-mailbox hardware. I've implemented the algorithm > used in the at91 and fixed the one for the ti_hecc. Marc, do you mean out-of-sequence reception with such mailbox types can happen even with the algorithm used in c_can and at91? Best regards, Alexander ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC v2 0/7] pch_can/c_can: fix races and add PCH support to c_can 2012-12-06 17:14 ` Alexander Stein @ 2012-12-06 23:34 ` Marc Kleine-Budde 2012-12-07 9:26 ` Wolfgang Grandegger 0 siblings, 1 reply; 38+ messages in thread From: Marc Kleine-Budde @ 2012-12-06 23:34 UTC (permalink / raw) To: Alexander Stein Cc: Wolfgang Grandegger, linux-can, bhupesh.sharma, tomoya.rohm [-- Attachment #1: Type: text/plain, Size: 832 bytes --] On 12/06/2012 06:14 PM, Alexander Stein wrote: >> This is a typical out-of-sequence reception with a >> RX-goes-into-first-free-mailbox hardware. I've implemented the >> algorithm used in the at91 and fixed the one for the ti_hecc. > > Marc, do you mean out-of-sequence reception with such mailbox types > can happen even with the algorithm used in c_can and at91? It can happen, if the algorithm isn't implemented properly and adopted to the needs of the hardware. On the unmodified ti_hecc we see this out-of-sequence problems, too. Marc -- Pengutronix e.K. | Marc Kleine-Budde | Industrial Linux Solutions | Phone: +49-231-2826-924 | Vertretung West/Dortmund | Fax: +49-5121-206917-5555 | Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de | [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 261 bytes --] ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC v2 0/7] pch_can/c_can: fix races and add PCH support to c_can 2012-12-06 23:34 ` Marc Kleine-Budde @ 2012-12-07 9:26 ` Wolfgang Grandegger 2012-12-07 9:55 ` Marc Kleine-Budde 0 siblings, 1 reply; 38+ messages in thread From: Wolfgang Grandegger @ 2012-12-07 9:26 UTC (permalink / raw) To: Marc Kleine-Budde; +Cc: Alexander Stein, linux-can, bhupesh.sharma, tomoya.rohm On 12/07/2012 12:34 AM, Marc Kleine-Budde wrote: > On 12/06/2012 06:14 PM, Alexander Stein wrote: >>> This is a typical out-of-sequence reception with a >>> RX-goes-into-first-free-mailbox hardware. I've implemented the >>> algorithm used in the at91 and fixed the one for the ti_hecc. >> >> Marc, do you mean out-of-sequence reception with such mailbox types >> can happen even with the algorithm used in c_can and at91? > > It can happen, if the algorithm isn't implemented properly and adopted > to the needs of the hardware. On the unmodified ti_hecc we see this > out-of-sequence problems, too. Yep, that's the tricky part and the pch_can and c_can use a different approach to solve the problem. Let's concentrate on the c_can driver. Key-point is that the controller does put the message into the FIFO object with the lowest number. Here is the relevant code: /* * theory of operation: * * c_can core saves a received CAN message into the first free message * object it finds free (starting with the lowest). Bits NEWDAT and * INTPND are set for this message object indicating that a new message * has arrived. To work-around this issue, we keep two groups of message * objects whose partitioning is defined by C_CAN_MSG_OBJ_RX_SPLIT. * * To ensure in-order frame reception we use the following * approach while re-activating a message object to receive further * frames: * - if the current message object number is lower than * C_CAN_MSG_RX_LOW_LAST, do not clear the NEWDAT bit while clearing * the INTPND bit. * - if the current message object number is equal to * C_CAN_MSG_RX_LOW_LAST then clear the NEWDAT bit of all lower * receive message objects. * - if the current message object number is greater than * C_CAN_MSG_RX_LOW_LAST then clear the NEWDAT bit of * only this message object. */ static int c_can_do_rx_poll(struct net_device *dev, int quota) { u32 num_rx_pkts = 0; unsigned int msg_obj, msg_ctrl_save; struct c_can_priv *priv = netdev_priv(dev); u32 val = c_can_read_reg32(priv, C_CAN_INTPND1_REG); for (msg_obj = C_CAN_MSG_OBJ_RX_FIRST; msg_obj <= C_CAN_MSG_OBJ_RX_LAST && quota > 0; val = c_can_read_reg32(priv, C_CAN_INTPND1_REG), msg_obj++) { /* * as interrupt pending register's bit n-1 corresponds to * message object n, we need to handle the same properly. */ if (val & (1 << (msg_obj - 1))) { c_can_object_get(dev, IFACE_RX, msg_obj, IF_COMM_ALL & ~IF_COMM_TXRQST); msg_ctrl_save = priv->read_reg(priv, C_CAN_IFACE(MSGCTRL_REG, IFACE_RX)); if (msg_ctrl_save & IF_MCONT_EOB) return num_rx_pkts; if (msg_ctrl_save & IF_MCONT_MSGLST) { c_can_handle_lost_msg_obj(dev, IFACE_RX, msg_obj); num_rx_pkts++; quota--; continue; } if (!(msg_ctrl_save & IF_MCONT_NEWDAT)) continue; /* read the data from the message object */ c_can_read_msg_object(dev, IFACE_RX, msg_ctrl_save); if (msg_obj < C_CAN_MSG_RX_LOW_LAST) c_can_mark_rx_msg_obj(dev, IFACE_RX, msg_ctrl_save, msg_obj); else if (msg_obj > C_CAN_MSG_RX_LOW_LAST) /* activate this msg obj */ c_can_activate_rx_msg_obj(dev, IFACE_RX, msg_ctrl_save, msg_obj); else if (msg_obj == C_CAN_MSG_RX_LOW_LAST) /* activate all lower message objects */ c_can_activate_all_lower_rx_msg_obj(dev, IFACE_RX, msg_ctrl_save); num_rx_pkts++; quota--; } } return num_rx_pkts; } I see a problem if the current message object number is greater than C_CAN_MSG_RX_LOW_LAST, which is #8. Lets assume the FIFO filled up to message number #8 when we read INTPND1_REG. Before the we call c_can_activate_all_lower_rx_msg_obj(), another message is received into #9. Then we call c_can_activate_all_lower_rx_msg_obj() and shortly after another messages is received into #0. The next time we enter this function it will read first #1 and then #9, which is the wrong order. Wolfgang. ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC v2 0/7] pch_can/c_can: fix races and add PCH support to c_can 2012-12-07 9:26 ` Wolfgang Grandegger @ 2012-12-07 9:55 ` Marc Kleine-Budde 2012-12-07 10:00 ` Bhupesh SHARMA 0 siblings, 1 reply; 38+ messages in thread From: Marc Kleine-Budde @ 2012-12-07 9:55 UTC (permalink / raw) To: Wolfgang Grandegger Cc: Alexander Stein, linux-can, bhupesh.sharma, tomoya.rohm [-- Attachment #1: Type: text/plain, Size: 6622 bytes --] On 12/07/2012 10:26 AM, Wolfgang Grandegger wrote: > On 12/07/2012 12:34 AM, Marc Kleine-Budde wrote: >> On 12/06/2012 06:14 PM, Alexander Stein wrote: >>>> This is a typical out-of-sequence reception with a >>>> RX-goes-into-first-free-mailbox hardware. I've implemented the >>>> algorithm used in the at91 and fixed the one for the ti_hecc. >>> >>> Marc, do you mean out-of-sequence reception with such mailbox types >>> can happen even with the algorithm used in c_can and at91? >> >> It can happen, if the algorithm isn't implemented properly and adopted >> to the needs of the hardware. On the unmodified ti_hecc we see this >> out-of-sequence problems, too. > > Yep, that's the tricky part and the pch_can and c_can use a different > approach to solve the problem. Let's concentrate on the c_can driver. > Key-point is that the controller does put the message into the FIFO > object with the lowest number. Here is the relevant code: > > /* > * theory of operation: > * > * c_can core saves a received CAN message into the first free message > * object it finds free (starting with the lowest). Bits NEWDAT and > * INTPND are set for this message object indicating that a new message > * has arrived. To work-around this issue, we keep two groups of message > * objects whose partitioning is defined by C_CAN_MSG_OBJ_RX_SPLIT. > * > * To ensure in-order frame reception we use the following > * approach while re-activating a message object to receive further > * frames: > * - if the current message object number is lower than > * C_CAN_MSG_RX_LOW_LAST, do not clear the NEWDAT bit while clearing > * the INTPND bit. > * - if the current message object number is equal to > * C_CAN_MSG_RX_LOW_LAST then clear the NEWDAT bit of all lower > * receive message objects. > * - if the current message object number is greater than > * C_CAN_MSG_RX_LOW_LAST then clear the NEWDAT bit of > * only this message object. > */ > static int c_can_do_rx_poll(struct net_device *dev, int quota) > { > u32 num_rx_pkts = 0; > unsigned int msg_obj, msg_ctrl_save; > struct c_can_priv *priv = netdev_priv(dev); > u32 val = c_can_read_reg32(priv, C_CAN_INTPND1_REG); > > for (msg_obj = C_CAN_MSG_OBJ_RX_FIRST; > msg_obj <= C_CAN_MSG_OBJ_RX_LAST && quota > 0; > val = c_can_read_reg32(priv, C_CAN_INTPND1_REG), > msg_obj++) { > /* > * as interrupt pending register's bit n-1 corresponds to > * message object n, we need to handle the same properly. > */ > if (val & (1 << (msg_obj - 1))) { > c_can_object_get(dev, IFACE_RX, msg_obj, IF_COMM_ALL & > ~IF_COMM_TXRQST); > msg_ctrl_save = priv->read_reg(priv, > C_CAN_IFACE(MSGCTRL_REG, IFACE_RX)); > > if (msg_ctrl_save & IF_MCONT_EOB) > return num_rx_pkts; > > if (msg_ctrl_save & IF_MCONT_MSGLST) { > c_can_handle_lost_msg_obj(dev, IFACE_RX, > msg_obj); > num_rx_pkts++; > quota--; > continue; > } > > if (!(msg_ctrl_save & IF_MCONT_NEWDAT)) > continue; > > /* read the data from the message object */ > c_can_read_msg_object(dev, IFACE_RX, msg_ctrl_save); > > if (msg_obj < C_CAN_MSG_RX_LOW_LAST) > c_can_mark_rx_msg_obj(dev, IFACE_RX, > msg_ctrl_save, msg_obj); > else if (msg_obj > C_CAN_MSG_RX_LOW_LAST) > /* activate this msg obj */ > c_can_activate_rx_msg_obj(dev, IFACE_RX, > msg_ctrl_save, msg_obj); > else if (msg_obj == C_CAN_MSG_RX_LOW_LAST) > /* activate all lower message objects */ > c_can_activate_all_lower_rx_msg_obj(dev, > IFACE_RX, msg_ctrl_save); > > num_rx_pkts++; > quota--; > } > } > > return num_rx_pkts; > } > > > I see a problem if the current message object number is greater than > C_CAN_MSG_RX_LOW_LAST, which is #8. Lets assume the FIFO filled up to > message number #8 when we read INTPND1_REG. Before the we call > c_can_activate_all_lower_rx_msg_obj(), another message is received > into #9. Then we call c_can_activate_all_lower_rx_msg_obj() and shortly > after another messages is received into #0. The next time we enter > this function it will read first #1 and then #9, which is the wrong > order. This is the my reworked version of the ti_hecc poll loop. Note: the ti_hecc fills the mailboxes from highest number to lowest, not lowest to highest like the c_can. > do { It's not a for loop starting at the first mailbox. It always works on the the next one.... > reg_rmp = hecc_read(priv, HECC_CANRMP) & priv->rx_active; > if (!(reg_rmp & BIT(priv->rx_next))) { > /* > * Wrap around only if: > * - we are in the lower group and > * - there is a CAN frame in the first mailbox > * of the high group. > */ ...and only wraps around to the first one under certain circumstances. > if ((priv->rx_next <= HECC_RX_BUFFER_MBOX) && > (reg_rmp & BIT(HECC_RX_FIRST_MBOX))) > priv->rx_next = HECC_RX_FIRST_MBOX; > else > break; > } > mb = priv->rx_next--; > > /* disable mailbox */ > priv->rx_active &= ~BIT(mb); > > ti_hecc_rx_pkt(priv, mb); > > /* enable mailboxes */ > if (mb == HECC_RX_BUFFER_MBOX) { > hecc_write(priv, HECC_CANRMP, HECC_RX_HIGH_MBOX_MASK); > priv->rx_active |= HECC_RX_HIGH_MBOX_MASK; > } else if (mb == HECC_RX_FIRST_MBOX) { > hecc_write(priv, HECC_CANRMP, HECC_RX_LOW_MBOX_MASK); > priv->rx_active |= HECC_RX_LOW_MBOX_MASK; > } The enabling of the mailboxes is delayed compared to the original algorithm. > > received++; > quota--; > } while (quota); We have at least 3 drivers with the same algorithm. I'm thinking if it is possible to create a library helper for this. Marc -- Pengutronix e.K. | Marc Kleine-Budde | Industrial Linux Solutions | Phone: +49-231-2826-924 | Vertretung West/Dortmund | Fax: +49-5121-206917-5555 | Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de | [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 261 bytes --] ^ permalink raw reply [flat|nested] 38+ messages in thread
* RE: [RFC v2 0/7] pch_can/c_can: fix races and add PCH support to c_can 2012-12-07 9:55 ` Marc Kleine-Budde @ 2012-12-07 10:00 ` Bhupesh SHARMA 2012-12-07 10:09 ` Marc Kleine-Budde 0 siblings, 1 reply; 38+ messages in thread From: Bhupesh SHARMA @ 2012-12-07 10:00 UTC (permalink / raw) To: Marc Kleine-Budde, Wolfgang Grandegger Cc: Alexander Stein, linux-can@vger.kernel.org, tomoya.rohm@gmail.com > -----Original Message----- > From: Marc Kleine-Budde [mailto:mkl@pengutronix.de] > Sent: Friday, December 07, 2012 3:26 PM > To: Wolfgang Grandegger > Cc: Alexander Stein; linux-can@vger.kernel.org; Bhupesh SHARMA; > tomoya.rohm@gmail.com > Subject: Re: [RFC v2 0/7] pch_can/c_can: fix races and add PCH support to > c_can > > On 12/07/2012 10:26 AM, Wolfgang Grandegger wrote: > > On 12/07/2012 12:34 AM, Marc Kleine-Budde wrote: > >> On 12/06/2012 06:14 PM, Alexander Stein wrote: > >>>> This is a typical out-of-sequence reception with a > >>>> RX-goes-into-first-free-mailbox hardware. I've implemented the > >>>> algorithm used in the at91 and fixed the one for the ti_hecc. > >>> > >>> Marc, do you mean out-of-sequence reception with such mailbox types > >>> can happen even with the algorithm used in c_can and at91? > >> > >> It can happen, if the algorithm isn't implemented properly and > >> adopted to the needs of the hardware. On the unmodified ti_hecc we > >> see this out-of-sequence problems, too. > > > > Yep, that's the tricky part and the pch_can and c_can use a different > > approach to solve the problem. Let's concentrate on the c_can driver. > > Key-point is that the controller does put the message into the FIFO > > object with the lowest number. Here is the relevant code: > > > > /* > > * theory of operation: > > * > > * c_can core saves a received CAN message into the first free message > > * object it finds free (starting with the lowest). Bits NEWDAT and > > * INTPND are set for this message object indicating that a new > > message > > * has arrived. To work-around this issue, we keep two groups of > > message > > * objects whose partitioning is defined by C_CAN_MSG_OBJ_RX_SPLIT. > > * > > * To ensure in-order frame reception we use the following > > * approach while re-activating a message object to receive further > > * frames: > > * - if the current message object number is lower than > > * C_CAN_MSG_RX_LOW_LAST, do not clear the NEWDAT bit while > clearing > > * the INTPND bit. > > * - if the current message object number is equal to > > * C_CAN_MSG_RX_LOW_LAST then clear the NEWDAT bit of all lower > > * receive message objects. > > * - if the current message object number is greater than > > * C_CAN_MSG_RX_LOW_LAST then clear the NEWDAT bit of > > * only this message object. > > */ > > static int c_can_do_rx_poll(struct net_device *dev, int quota) { > > u32 num_rx_pkts = 0; > > unsigned int msg_obj, msg_ctrl_save; > > struct c_can_priv *priv = netdev_priv(dev); > > u32 val = c_can_read_reg32(priv, C_CAN_INTPND1_REG); > > > > for (msg_obj = C_CAN_MSG_OBJ_RX_FIRST; > > msg_obj <= C_CAN_MSG_OBJ_RX_LAST && quota > > 0; > > val = c_can_read_reg32(priv, > C_CAN_INTPND1_REG), > > msg_obj++) { > > /* > > * as interrupt pending register's bit n-1 corresponds to > > * message object n, we need to handle the same properly. > > */ > > if (val & (1 << (msg_obj - 1))) { > > c_can_object_get(dev, IFACE_RX, msg_obj, > IF_COMM_ALL & > > ~IF_COMM_TXRQST); > > msg_ctrl_save = priv->read_reg(priv, > > C_CAN_IFACE(MSGCTRL_REG, > IFACE_RX)); > > > > if (msg_ctrl_save & IF_MCONT_EOB) > > return num_rx_pkts; > > > > if (msg_ctrl_save & IF_MCONT_MSGLST) { > > c_can_handle_lost_msg_obj(dev, IFACE_RX, > > msg_obj); > > num_rx_pkts++; > > quota--; > > continue; > > } > > > > if (!(msg_ctrl_save & IF_MCONT_NEWDAT)) > > continue; > > > > /* read the data from the message object */ > > c_can_read_msg_object(dev, IFACE_RX, > msg_ctrl_save); > > > > if (msg_obj < C_CAN_MSG_RX_LOW_LAST) > > c_can_mark_rx_msg_obj(dev, IFACE_RX, > > msg_ctrl_save, msg_obj); > > else if (msg_obj > C_CAN_MSG_RX_LOW_LAST) > > /* activate this msg obj */ > > c_can_activate_rx_msg_obj(dev, IFACE_RX, > > msg_ctrl_save, msg_obj); > > else if (msg_obj == C_CAN_MSG_RX_LOW_LAST) > > /* activate all lower message objects */ > > c_can_activate_all_lower_rx_msg_obj(dev, > > IFACE_RX, msg_ctrl_save); > > > > num_rx_pkts++; > > quota--; > > } > > } > > > > return num_rx_pkts; > > } > > > > > > I see a problem if the current message object number is greater than > > C_CAN_MSG_RX_LOW_LAST, which is #8. Lets assume the FIFO filled up to > > message number #8 when we read INTPND1_REG. Before the we call > > c_can_activate_all_lower_rx_msg_obj(), another message is received > > into #9. Then we call c_can_activate_all_lower_rx_msg_obj() and > > shortly after another messages is received into #0. The next time we > > enter this function it will read first #1 and then #9, which is the > > wrong order. > > This is the my reworked version of the ti_hecc poll loop. > Note: the ti_hecc fills the mailboxes from highest number to lowest, not > lowest to highest like the c_can. > > > do { > > It's not a for loop starting at the first mailbox. It always works on the the next > one.... > > > reg_rmp = hecc_read(priv, HECC_CANRMP) & priv->rx_active; > > if (!(reg_rmp & BIT(priv->rx_next))) { > > /* > > * Wrap around only if: > > * - we are in the lower group and > > * - there is a CAN frame in the first mailbox > > * of the high group. > > */ > > ...and only wraps around to the first one under certain circumstances. > > > if ((priv->rx_next <= HECC_RX_BUFFER_MBOX) && > > (reg_rmp & BIT(HECC_RX_FIRST_MBOX))) > > priv->rx_next = HECC_RX_FIRST_MBOX; > > else > > break; > > } > > mb = priv->rx_next--; > > > > /* disable mailbox */ > > priv->rx_active &= ~BIT(mb); > > > > ti_hecc_rx_pkt(priv, mb); > > > > /* enable mailboxes */ > > if (mb == HECC_RX_BUFFER_MBOX) { > > hecc_write(priv, HECC_CANRMP, > HECC_RX_HIGH_MBOX_MASK); > > priv->rx_active |= HECC_RX_HIGH_MBOX_MASK; > > } else if (mb == HECC_RX_FIRST_MBOX) { > > hecc_write(priv, HECC_CANRMP, > HECC_RX_LOW_MBOX_MASK); > > priv->rx_active |= HECC_RX_LOW_MBOX_MASK; > > } > > The enabling of the mailboxes is delayed compared to the original algorithm. > > > > > received++; > > quota--; > > } while (quota); > > We have at least 3 drivers with the same algorithm. I'm thinking if it is > possible to create a library helper for this. > A library helper seems sensible, but don't forget that different cores have different priority schemes (higher to lower and lower to higher) when they service RX packets, so the library helper should also accommodate this. Regards, Bhupesh ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC v2 0/7] pch_can/c_can: fix races and add PCH support to c_can 2012-12-07 10:00 ` Bhupesh SHARMA @ 2012-12-07 10:09 ` Marc Kleine-Budde 0 siblings, 0 replies; 38+ messages in thread From: Marc Kleine-Budde @ 2012-12-07 10:09 UTC (permalink / raw) To: Bhupesh SHARMA Cc: Wolfgang Grandegger, Alexander Stein, linux-can@vger.kernel.org, tomoya.rohm@gmail.com [-- Attachment #1: Type: text/plain, Size: 816 bytes --] On 12/07/2012 11:00 AM, Bhupesh SHARMA wrote: >> We have at least 3 drivers with the same algorithm. I'm thinking if >> it is possible to create a library helper for this. >> > > A library helper seems sensible, but don't forget that different > cores have different priority schemes (higher to lower and lower to > higher) when they service RX packets, so the library helper should > also accommodate this. Sure. There are some quite sophisticated abstractions in the kernel, like irq chips, that I should look at. Marc -- Pengutronix e.K. | Marc Kleine-Budde | Industrial Linux Solutions | Phone: +49-231-2826-924 | Vertretung West/Dortmund | Fax: +49-5121-206917-5555 | Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de | [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 261 bytes --] ^ permalink raw reply [flat|nested] 38+ messages in thread
end of thread, other threads:[~2012-12-07 10:09 UTC | newest] Thread overview: 38+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-11-29 14:39 [RFC v2 0/7] pch_can/c_can: fix races and add PCH support to c_can Wolfgang Grandegger 2012-11-29 14:39 ` [RFC v2 1/7] pch_can: add spinlocks to protect tx objects Wolfgang Grandegger 2012-11-29 14:39 ` [RFC v2 2/7] c_can: rename callback "initram" to "init" to more general usage Wolfgang Grandegger 2012-12-03 14:20 ` Alexander Stein 2012-12-03 14:32 ` Wolfgang Grandegger 2012-11-29 14:39 ` [RFC v2 3/7] c_can: use different sets of interface registers for rx and tx Wolfgang Grandegger 2012-11-30 8:39 ` Marc Kleine-Budde 2012-11-30 9:15 ` Wolfgang Grandegger 2012-11-29 14:39 ` [RFC v2 4/7] c_can_pci: introduce board specific PCI bar Wolfgang Grandegger 2012-11-30 8:45 ` Marc Kleine-Budde 2012-11-30 9:11 ` Wolfgang Grandegger 2012-11-30 9:19 ` Marc Kleine-Budde 2012-11-29 14:39 ` [RFC v2 5/7] c_can_pci: enable PCI bus master only for MSI Wolfgang Grandegger 2012-11-30 8:54 ` Marc Kleine-Budde 2012-11-29 14:39 ` [RFC v2 6/7] c_can_pci: add support for PCH CAN on Intel EG20T PCH Wolfgang Grandegger 2012-11-29 14:39 ` [RFC v2 7/7] c_can: add spinlock to protect tx and rx objects Wolfgang Grandegger 2012-12-05 12:09 ` [RFC v2 0/7] pch_can/c_can: fix races and add PCH support to c_can Alexander Stein 2012-12-05 12:50 ` Wolfgang Grandegger 2012-12-05 14:46 ` Alexander Stein 2012-12-05 17:35 ` Wolfgang Grandegger 2012-12-05 21:52 ` Marc Kleine-Budde 2012-12-06 7:09 ` Wolfgang Grandegger 2012-12-06 8:35 ` Marc Kleine-Budde 2012-12-06 8:17 ` Wolfgang Grandegger 2012-12-06 13:38 ` Alexander Stein 2012-12-06 14:02 ` Marc Kleine-Budde 2012-12-06 14:31 ` Wolfgang Grandegger 2012-12-06 14:37 ` Marc Kleine-Budde 2012-12-06 14:56 ` Alexander Stein 2012-12-06 15:15 ` Wolfgang Grandegger 2012-12-06 15:27 ` Wolfgang Grandegger 2012-12-06 15:55 ` Alexander Stein 2012-12-06 17:14 ` Alexander Stein 2012-12-06 23:34 ` Marc Kleine-Budde 2012-12-07 9:26 ` Wolfgang Grandegger 2012-12-07 9:55 ` Marc Kleine-Budde 2012-12-07 10:00 ` Bhupesh SHARMA 2012-12-07 10:09 ` Marc Kleine-Budde
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).