pastebin - collaborative debugging tool
eckelmann.kpaste.net RSS


Heuhaufen flexcan problem i.mx25
Posted by Anonymous on Fri 4th Jan 2019 08:25
raw | new post

  1. *** platform-eag-ci4000/build-target/linux-4.19/drivers/net/can/flexcan.c       2019-01-04 09:16:47.673270748 +0100
  2. --- /home/schenk/projects/tmp/OSELAS.BSP-Eckelmann/platform-eag-ci4000/build-target/linux-4.19-rc5/drivers/net/can/flexcan.c    2018-09-23 19:15:18.000000000 +0200
  3. ***************
  4. *** 135,146 ****
  5.  
  6.   /* FLEXCAN interrupt flag register (IFLAG) bits */
  7.   /* Errata ERR005829 step7: Reserve first valid MB */
  8. ! #define FLEXCAN_TX_MB_RESERVED_OFF_FIFO               8
  9.   #define FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP  0
  10. ! #define FLEXCAN_TX_MB                         63
  11. ! #define FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST     (FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP + 1)
  12. ! #define FLEXCAN_RX_MB_OFF_TIMESTAMP_LAST      (FLEXCAN_TX_MB - 1)
  13. ! #define FLEXCAN_IFLAG_MB(x)           BIT(x & 0x1f)
  14.   #define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW        BIT(7)
  15.   #define FLEXCAN_IFLAG_RX_FIFO_WARN    BIT(6)
  16.   #define FLEXCAN_IFLAG_RX_FIFO_AVAILABLE       BIT(5)
  17. --- 135,147 ----
  18.  
  19.   /* FLEXCAN interrupt flag register (IFLAG) bits */
  20.   /* Errata ERR005829 step7: Reserve first valid MB */
  21. ! #define FLEXCAN_TX_MB_RESERVED_OFF_FIFO       8
  22. ! #define FLEXCAN_TX_MB_OFF_FIFO                9
  23.   #define FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP  0
  24. ! #define FLEXCAN_TX_MB_OFF_TIMESTAMP           1
  25. ! #define FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST     (FLEXCAN_TX_MB_OFF_TIMESTAMP + 1)
  26. ! #define FLEXCAN_RX_MB_OFF_TIMESTAMP_LAST      63
  27. ! #define FLEXCAN_IFLAG_MB(x)           BIT(x)
  28.   #define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW        BIT(7)
  29.   #define FLEXCAN_IFLAG_RX_FIFO_WARN    BIT(6)
  30.   #define FLEXCAN_IFLAG_RX_FIFO_AVAILABLE       BIT(5)
  31. *************** struct flexcan_priv {
  32. *** 258,264 ****
  33. --- 259,267 ----
  34.         struct can_rx_offload offload;
  35.  
  36.         struct flexcan_regs __iomem *regs;
  37. +       struct flexcan_mb __iomem *tx_mb;
  38.         struct flexcan_mb __iomem *tx_mb_reserved;
  39. +       u8 tx_mb_idx;
  40.         u32 reg_ctrl_default;
  41.         u32 reg_imask1_default;
  42.         u32 reg_imask2_default;
  43. *************** static int flexcan_get_berr_counter(cons
  44. *** 512,518 ****
  45.   static netdev_tx_t flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev)
  46.   {
  47.         const struct flexcan_priv *priv = netdev_priv(dev);
  48. -       struct flexcan_regs __iomem *regs = priv->regs;
  49.         struct can_frame *cf = (struct can_frame *)skb->data;
  50.         u32 can_id;
  51.         u32 data;
  52. --- 515,520 ----
  53. *************** static netdev_tx_t flexcan_start_xmit(st
  54. *** 535,551 ****
  55.  
  56.         if (cf->can_dlc > 0) {
  57.                 data = be32_to_cpup((__be32 *)&cf->data[0]);
  58. !               priv->write(data, &regs->mb[FLEXCAN_TX_MB].data[0]);
  59.         }
  60.         if (cf->can_dlc > 4) {
  61.                 data = be32_to_cpup((__be32 *)&cf->data[4]);
  62. !               priv->write(data, &regs->mb[FLEXCAN_TX_MB].data[1]);
  63.         }
  64.  
  65.         can_put_echo_skb(skb, dev, 0);
  66.  
  67. !       priv->write(can_id, &regs->mb[FLEXCAN_TX_MB].can_id);
  68. !       priv->write(ctrl, &regs->mb[FLEXCAN_TX_MB].can_ctrl);
  69.  
  70.         /* Errata ERR005829 step8:
  71.          * Write twice INACTIVE(0x8) code to first MB.
  72. --- 537,553 ----
  73.  
  74.         if (cf->can_dlc > 0) {
  75.                 data = be32_to_cpup((__be32 *)&cf->data[0]);
  76. !               priv->write(data, &priv->tx_mb->data[0]);
  77.         }
  78.         if (cf->can_dlc > 4) {
  79.                 data = be32_to_cpup((__be32 *)&cf->data[4]);
  80. !               priv->write(data, &priv->tx_mb->data[1]);
  81.         }
  82.  
  83.         can_put_echo_skb(skb, dev, 0);
  84.  
  85. !       priv->write(can_id, &priv->tx_mb->can_id);
  86. !       priv->write(ctrl, &priv->tx_mb->can_ctrl);
  87.  
  88.         /* Errata ERR005829 step8:
  89.          * Write twice INACTIVE(0x8) code to first MB.
  90. *************** static netdev_tx_t flexcan_start_xmit(st
  91. *** 561,573 ****
  92.   static void flexcan_irq_bus_err(struct net_device *dev, u32 reg_esr)
  93.   {
  94.         struct flexcan_priv *priv = netdev_priv(dev);
  95. -       struct flexcan_regs __iomem *regs = priv->regs;
  96.         struct sk_buff *skb;
  97.         struct can_frame *cf;
  98.         bool rx_errors = false, tx_errors = false;
  99. -       u32 timestamp;
  100. -
  101. -       timestamp = priv->read(&regs->timer) << 16;
  102.  
  103.         skb = alloc_can_err_skb(dev, &cf);
  104.         if (unlikely(!skb))
  105. --- 563,571 ----
  106. *************** static void flexcan_irq_bus_err(struct n
  107. *** 614,634 ****
  108.         if (tx_errors)
  109.                 dev->stats.tx_errors++;
  110.  
  111. !       can_rx_offload_queue_sorted(&priv->offload, skb, timestamp);
  112.   }
  113.  
  114.   static void flexcan_irq_state(struct net_device *dev, u32 reg_esr)
  115.   {
  116.         struct flexcan_priv *priv = netdev_priv(dev);
  117. -       struct flexcan_regs __iomem *regs = priv->regs;
  118.         struct sk_buff *skb;
  119.         struct can_frame *cf;
  120.         enum can_state new_state, rx_state, tx_state;
  121.         int flt;
  122.         struct can_berr_counter bec;
  123. -       u32 timestamp;
  124. -
  125. -       timestamp = priv->read(&regs->timer) << 16;
  126.  
  127.         flt = reg_esr & FLEXCAN_ESR_FLT_CONF_MASK;
  128.         if (likely(flt == FLEXCAN_ESR_FLT_CONF_ACTIVE)) {
  129. --- 612,628 ----
  130.         if (tx_errors)
  131.                 dev->stats.tx_errors++;
  132.  
  133. !       can_rx_offload_irq_queue_err_skb(&priv->offload, skb);
  134.   }
  135.  
  136.   static void flexcan_irq_state(struct net_device *dev, u32 reg_esr)
  137.   {
  138.         struct flexcan_priv *priv = netdev_priv(dev);
  139.         struct sk_buff *skb;
  140.         struct can_frame *cf;
  141.         enum can_state new_state, rx_state, tx_state;
  142.         int flt;
  143.         struct can_berr_counter bec;
  144.  
  145.         flt = reg_esr & FLEXCAN_ESR_FLT_CONF_MASK;
  146.         if (likely(flt == FLEXCAN_ESR_FLT_CONF_ACTIVE)) {
  147. *************** static void flexcan_irq_state(struct net
  148. *** 658,664 ****
  149.         if (unlikely(new_state == CAN_STATE_BUS_OFF))
  150.                 can_bus_off(dev);
  151.  
  152. !       can_rx_offload_queue_sorted(&priv->offload, skb, timestamp);
  153.   }
  154.  
  155.   static inline struct flexcan_priv *rx_offload_to_priv(struct can_rx_offload *offload)
  156. --- 652,658 ----
  157.         if (unlikely(new_state == CAN_STATE_BUS_OFF))
  158.                 can_bus_off(dev);
  159.  
  160. !       can_rx_offload_irq_queue_err_skb(&priv->offload, skb);
  161.   }
  162.  
  163.   static inline struct flexcan_priv *rx_offload_to_priv(struct can_rx_offload *offload)
  164. *************** static unsigned int flexcan_mailbox_read
  165. *** 726,739 ****
  166.                         priv->write(BIT(n - 32), &regs->iflag2);
  167.         } else {
  168.                 priv->write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, &regs->iflag1);
  169.         }
  170.  
  171. -       /* Read the Free Running Timer. It is optional but recommended
  172. -        * to unlock Mailbox as soon as possible and make it available
  173. -        * for reception.
  174. -        */
  175. -       priv->read(&regs->timer);
  176. -
  177.         return 1;
  178.   }
  179.  
  180. --- 720,728 ----
  181.                         priv->write(BIT(n - 32), &regs->iflag2);
  182.         } else {
  183.                 priv->write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, &regs->iflag1);
  184. +               priv->read(&regs->timer);
  185.         }
  186.  
  187.         return 1;
  188.   }
  189.  
  190. *************** static inline u64 flexcan_read_reg_iflag
  191. *** 743,751 ****
  192.         struct flexcan_regs __iomem *regs = priv->regs;
  193.         u32 iflag1, iflag2;
  194.  
  195. !       iflag2 = priv->read(&regs->iflag2) & priv->reg_imask2_default &
  196. !               ~FLEXCAN_IFLAG_MB(FLEXCAN_TX_MB);
  197. !       iflag1 = priv->read(&regs->iflag1) & priv->reg_imask1_default;
  198.  
  199.         return (u64)iflag2 << 32 | iflag1;
  200.   }
  201. --- 732,740 ----
  202.         struct flexcan_regs __iomem *regs = priv->regs;
  203.         u32 iflag1, iflag2;
  204.  
  205. !       iflag2 = priv->read(&regs->iflag2) & priv->reg_imask2_default;
  206. !       iflag1 = priv->read(&regs->iflag1) & priv->reg_imask1_default &
  207. !               ~FLEXCAN_IFLAG_MB(priv->tx_mb_idx);
  208.  
  209.         return (u64)iflag2 << 32 | iflag1;
  210.   }
  211. *************** static irqreturn_t flexcan_irq(int irq,
  212. *** 757,765 ****
  213.         struct flexcan_priv *priv = netdev_priv(dev);
  214.         struct flexcan_regs __iomem *regs = priv->regs;
  215.         irqreturn_t handled = IRQ_NONE;
  216. !       u32 reg_iflag2, reg_esr;
  217.         enum can_state last_state = priv->can.state;
  218.  
  219.         /* reception interrupt */
  220.         if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
  221.                 u64 reg_iflag;
  222. --- 746,756 ----
  223.         struct flexcan_priv *priv = netdev_priv(dev);
  224.         struct flexcan_regs __iomem *regs = priv->regs;
  225.         irqreturn_t handled = IRQ_NONE;
  226. !       u32 reg_iflag1, reg_esr;
  227.         enum can_state last_state = priv->can.state;
  228.  
  229. +       reg_iflag1 = priv->read(&regs->iflag1);
  230. +
  231.         /* reception interrupt */
  232.         if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
  233.                 u64 reg_iflag;
  234. *************** static irqreturn_t flexcan_irq(int irq,
  235. *** 773,781 ****
  236.                                 break;
  237.                 }
  238.         } else {
  239. -               u32 reg_iflag1;
  240. -
  241. -               reg_iflag1 = priv->read(&regs->iflag1);
  242.                 if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE) {
  243.                         handled = IRQ_HANDLED;
  244.                         can_rx_offload_irq_offload_fifo(&priv->offload);
  245. --- 764,769 ----
  246. *************** static irqreturn_t flexcan_irq(int irq,
  247. *** 791,812 ****
  248.                 }
  249.         }
  250.  
  251. -       reg_iflag2 = priv->read(&regs->iflag2);
  252. -
  253.         /* transmission complete interrupt */
  254. !       if (reg_iflag2 & FLEXCAN_IFLAG_MB(FLEXCAN_TX_MB)) {
  255. !               u32 reg_ctrl = priv->read(&regs->mb[FLEXCAN_TX_MB].can_ctrl);
  256. !
  257.                 handled = IRQ_HANDLED;
  258. !               stats->tx_bytes += can_rx_offload_get_echo_skb(&priv->offload,
  259. !                                                              0, reg_ctrl << 16);
  260.                 stats->tx_packets++;
  261.                 can_led_event(dev, CAN_LED_EVENT_TX);
  262.  
  263.                 /* after sending a RTR frame MB is in RX mode */
  264.                 priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
  265. !                           &regs->mb[FLEXCAN_TX_MB].can_ctrl);
  266. !               priv->write(FLEXCAN_IFLAG_MB(FLEXCAN_TX_MB), &regs->iflag2);
  267.                 netif_wake_queue(dev);
  268.         }
  269.  
  270. --- 779,795 ----
  271.                 }
  272.         }
  273.  
  274.         /* transmission complete interrupt */
  275. !       if (reg_iflag1 & FLEXCAN_IFLAG_MB(priv->tx_mb_idx)) {
  276.                 handled = IRQ_HANDLED;
  277. !               stats->tx_bytes += can_get_echo_skb(dev, 0);
  278.                 stats->tx_packets++;
  279.                 can_led_event(dev, CAN_LED_EVENT_TX);
  280.  
  281.                 /* after sending a RTR frame MB is in RX mode */
  282.                 priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
  283. !                           &priv->tx_mb->can_ctrl);
  284. !               priv->write(FLEXCAN_IFLAG_MB(priv->tx_mb_idx), &regs->iflag1);
  285.                 netif_wake_queue(dev);
  286.         }
  287.  
  288. *************** static int flexcan_chip_start(struct net
  289. *** 948,960 ****
  290.         reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff);
  291.         reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV |
  292.                 FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_SRX_DIS | FLEXCAN_MCR_IRMQ |
  293. !               FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_MAXMB(FLEXCAN_TX_MB);
  294.  
  295. !       if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP)
  296.                 reg_mcr &= ~FLEXCAN_MCR_FEN;
  297. !       else
  298. !               reg_mcr |= FLEXCAN_MCR_FEN;
  299. !
  300.         netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr);
  301.         priv->write(reg_mcr, &regs->mcr);
  302.  
  303. --- 931,945 ----
  304.         reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff);
  305.         reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV |
  306.                 FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_SRX_DIS | FLEXCAN_MCR_IRMQ |
  307. !               FLEXCAN_MCR_IDAM_C;
  308.  
  309. !       if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
  310.                 reg_mcr &= ~FLEXCAN_MCR_FEN;
  311. !               reg_mcr |= FLEXCAN_MCR_MAXMB(priv->offload.mb_last);
  312. !       } else {
  313. !               reg_mcr |= FLEXCAN_MCR_FEN |
  314. !                       FLEXCAN_MCR_MAXMB(priv->tx_mb_idx);
  315. !       }
  316.         netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr);
  317.         priv->write(reg_mcr, &regs->mcr);
  318.  
  319. *************** static int flexcan_chip_start(struct net
  320. *** 997,1013 ****
  321.                 priv->write(reg_ctrl2, &regs->ctrl2);
  322.         }
  323.  
  324.         if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
  325. !               for (i = priv->offload.mb_first; i <= priv->offload.mb_last; i++) {
  326.                         priv->write(FLEXCAN_MB_CODE_RX_EMPTY,
  327.                                     &regs->mb[i].can_ctrl);
  328. -               }
  329. -       } else {
  330. -               /* clear and invalidate unused mailboxes first */
  331. -               for (i = FLEXCAN_TX_MB_RESERVED_OFF_FIFO; i <= ARRAY_SIZE(regs->mb); i++) {
  332. -                       priv->write(FLEXCAN_MB_CODE_RX_INACTIVE,
  333. -                                   &regs->mb[i].can_ctrl);
  334. -               }
  335.         }
  336.  
  337.         /* Errata ERR005829: mark first TX mailbox as INACTIVE */
  338. --- 982,997 ----
  339.                 priv->write(reg_ctrl2, &regs->ctrl2);
  340.         }
  341.  
  342. +       /* clear and invalidate all mailboxes first */
  343. +       for (i = priv->tx_mb_idx; i < ARRAY_SIZE(regs->mb); i++) {
  344. +               priv->write(FLEXCAN_MB_CODE_RX_INACTIVE,
  345. +                           &regs->mb[i].can_ctrl);
  346. +       }
  347. +
  348.         if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
  349. !               for (i = priv->offload.mb_first; i <= priv->offload.mb_last; i++)
  350.                         priv->write(FLEXCAN_MB_CODE_RX_EMPTY,
  351.                                     &regs->mb[i].can_ctrl);
  352.         }
  353.  
  354.         /* Errata ERR005829: mark first TX mailbox as INACTIVE */
  355. *************** static int flexcan_chip_start(struct net
  356. *** 1016,1022 ****
  357.  
  358.         /* mark TX mailbox as INACTIVE */
  359.         priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
  360. !                   &regs->mb[FLEXCAN_TX_MB].can_ctrl);
  361.  
  362.         /* acceptance mask/acceptance code (accept everything) */
  363.         priv->write(0x0, &regs->rxgmask);
  364. --- 1000,1006 ----
  365.  
  366.         /* mark TX mailbox as INACTIVE */
  367.         priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
  368. !                   &priv->tx_mb->can_ctrl);
  369.  
  370.         /* acceptance mask/acceptance code (accept everything) */
  371.         priv->write(0x0, &regs->rxgmask);
  372. *************** static int flexcan_probe(struct platform
  373. *** 1371,1383 ****
  374.         priv->devtype_data = devtype_data;
  375.         priv->reg_xceiver = reg_xceiver;
  376.  
  377. !       if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP)
  378.                 priv->tx_mb_reserved = &regs->mb[FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP];
  379. !       else
  380.                 priv->tx_mb_reserved = &regs->mb[FLEXCAN_TX_MB_RESERVED_OFF_FIFO];
  381.  
  382. !       priv->reg_imask1_default = 0;
  383. !       priv->reg_imask2_default = FLEXCAN_IFLAG_MB(FLEXCAN_TX_MB);
  384.  
  385.         priv->offload.mailbox_read = flexcan_mailbox_read;
  386.  
  387. --- 1355,1371 ----
  388.         priv->devtype_data = devtype_data;
  389.         priv->reg_xceiver = reg_xceiver;
  390.  
  391. !       if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
  392. !               priv->tx_mb_idx = FLEXCAN_TX_MB_OFF_TIMESTAMP;
  393.                 priv->tx_mb_reserved = &regs->mb[FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP];
  394. !       } else {
  395. !               priv->tx_mb_idx = FLEXCAN_TX_MB_OFF_FIFO;
  396.                 priv->tx_mb_reserved = &regs->mb[FLEXCAN_TX_MB_RESERVED_OFF_FIFO];
  397. +       }
  398. +       priv->tx_mb = &regs->mb[priv->tx_mb_idx];
  399.  
  400. !       priv->reg_imask1_default = FLEXCAN_IFLAG_MB(priv->tx_mb_idx);
  401. !       priv->reg_imask2_default = 0;
  402.  
  403.         priv->offload.mailbox_read = flexcan_mailbox_read;

Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:

To highlight particular lines, prefix each line with {%HIGHLIGHT}





All content is user-submitted.
The administrators of this site (kpaste.net) are not responsible for their content.
Abuse reports should be emailed to us at