12722ac98SDario Binacchi /*
22722ac98SDario Binacchi * CAN bus driver for Bosch C_CAN controller
32722ac98SDario Binacchi *
42722ac98SDario Binacchi * Copyright (C) 2010 ST Microelectronics
52722ac98SDario Binacchi * Bhupesh Sharma <bhupesh.sharma@st.com>
62722ac98SDario Binacchi *
72722ac98SDario Binacchi * Borrowed heavily from the C_CAN driver originally written by:
82722ac98SDario Binacchi * Copyright (C) 2007
92722ac98SDario Binacchi * - Sascha Hauer, Marc Kleine-Budde, Pengutronix <s.hauer@pengutronix.de>
102722ac98SDario Binacchi * - Simon Kallweit, intefo AG <simon.kallweit@intefo.ch>
112722ac98SDario Binacchi *
122722ac98SDario Binacchi * TX and RX NAPI implementation has been borrowed from at91 CAN driver
132722ac98SDario Binacchi * written by:
142722ac98SDario Binacchi * Copyright
152722ac98SDario Binacchi * (C) 2007 by Hans J. Koch <hjk@hansjkoch.de>
162722ac98SDario Binacchi * (C) 2008, 2009 by Marc Kleine-Budde <kernel@pengutronix.de>
172722ac98SDario Binacchi *
182722ac98SDario Binacchi * Bosch C_CAN controller is compliant to CAN protocol version 2.0 part A and B.
192722ac98SDario Binacchi * Bosch C_CAN user manual can be obtained from:
202722ac98SDario Binacchi * http://www.semiconductors.bosch.de/media/en/pdf/ipmodules_1/c_can/
212722ac98SDario Binacchi * users_manual_c_can.pdf
222722ac98SDario Binacchi *
232722ac98SDario Binacchi * This file is licensed under the terms of the GNU General Public
242722ac98SDario Binacchi * License version 2. This program is licensed "as is" without any
252722ac98SDario Binacchi * warranty of any kind, whether express or implied.
262722ac98SDario Binacchi */
272722ac98SDario Binacchi
282722ac98SDario Binacchi #include <linux/kernel.h>
292722ac98SDario Binacchi #include <linux/module.h>
302722ac98SDario Binacchi #include <linux/interrupt.h>
312722ac98SDario Binacchi #include <linux/delay.h>
322722ac98SDario Binacchi #include <linux/netdevice.h>
332722ac98SDario Binacchi #include <linux/if_arp.h>
342722ac98SDario Binacchi #include <linux/if_ether.h>
352722ac98SDario Binacchi #include <linux/list.h>
362722ac98SDario Binacchi #include <linux/io.h>
372722ac98SDario Binacchi #include <linux/pm_runtime.h>
382722ac98SDario Binacchi #include <linux/pinctrl/consumer.h>
392722ac98SDario Binacchi
402722ac98SDario Binacchi #include <linux/can.h>
412722ac98SDario Binacchi #include <linux/can/dev.h>
422722ac98SDario Binacchi #include <linux/can/error.h>
432722ac98SDario Binacchi
442722ac98SDario Binacchi #include "c_can.h"
452722ac98SDario Binacchi
462722ac98SDario Binacchi /* Number of interface registers */
472722ac98SDario Binacchi #define IF_ENUM_REG_LEN 11
482722ac98SDario Binacchi #define C_CAN_IFACE(reg, iface) (C_CAN_IF1_##reg + (iface) * IF_ENUM_REG_LEN)
492722ac98SDario Binacchi
502722ac98SDario Binacchi /* control extension register D_CAN specific */
512722ac98SDario Binacchi #define CONTROL_EX_PDR BIT(8)
522722ac98SDario Binacchi
532722ac98SDario Binacchi /* control register */
542722ac98SDario Binacchi #define CONTROL_SWR BIT(15)
552722ac98SDario Binacchi #define CONTROL_TEST BIT(7)
562722ac98SDario Binacchi #define CONTROL_CCE BIT(6)
572722ac98SDario Binacchi #define CONTROL_DISABLE_AR BIT(5)
582722ac98SDario Binacchi #define CONTROL_ENABLE_AR (0 << 5)
592722ac98SDario Binacchi #define CONTROL_EIE BIT(3)
602722ac98SDario Binacchi #define CONTROL_SIE BIT(2)
612722ac98SDario Binacchi #define CONTROL_IE BIT(1)
622722ac98SDario Binacchi #define CONTROL_INIT BIT(0)
632722ac98SDario Binacchi
642722ac98SDario Binacchi #define CONTROL_IRQMSK (CONTROL_EIE | CONTROL_IE | CONTROL_SIE)
652722ac98SDario Binacchi
662722ac98SDario Binacchi /* test register */
672722ac98SDario Binacchi #define TEST_RX BIT(7)
682722ac98SDario Binacchi #define TEST_TX1 BIT(6)
692722ac98SDario Binacchi #define TEST_TX2 BIT(5)
702722ac98SDario Binacchi #define TEST_LBACK BIT(4)
712722ac98SDario Binacchi #define TEST_SILENT BIT(3)
722722ac98SDario Binacchi #define TEST_BASIC BIT(2)
732722ac98SDario Binacchi
742722ac98SDario Binacchi /* status register */
752722ac98SDario Binacchi #define STATUS_PDA BIT(10)
762722ac98SDario Binacchi #define STATUS_BOFF BIT(7)
772722ac98SDario Binacchi #define STATUS_EWARN BIT(6)
782722ac98SDario Binacchi #define STATUS_EPASS BIT(5)
792722ac98SDario Binacchi #define STATUS_RXOK BIT(4)
802722ac98SDario Binacchi #define STATUS_TXOK BIT(3)
812722ac98SDario Binacchi
822722ac98SDario Binacchi /* error counter register */
832722ac98SDario Binacchi #define ERR_CNT_TEC_MASK 0xff
842722ac98SDario Binacchi #define ERR_CNT_TEC_SHIFT 0
852722ac98SDario Binacchi #define ERR_CNT_REC_SHIFT 8
862722ac98SDario Binacchi #define ERR_CNT_REC_MASK (0x7f << ERR_CNT_REC_SHIFT)
872722ac98SDario Binacchi #define ERR_CNT_RP_SHIFT 15
882722ac98SDario Binacchi #define ERR_CNT_RP_MASK (0x1 << ERR_CNT_RP_SHIFT)
892722ac98SDario Binacchi
902722ac98SDario Binacchi /* bit-timing register */
912722ac98SDario Binacchi #define BTR_BRP_MASK 0x3f
922722ac98SDario Binacchi #define BTR_BRP_SHIFT 0
932722ac98SDario Binacchi #define BTR_SJW_SHIFT 6
942722ac98SDario Binacchi #define BTR_SJW_MASK (0x3 << BTR_SJW_SHIFT)
952722ac98SDario Binacchi #define BTR_TSEG1_SHIFT 8
962722ac98SDario Binacchi #define BTR_TSEG1_MASK (0xf << BTR_TSEG1_SHIFT)
972722ac98SDario Binacchi #define BTR_TSEG2_SHIFT 12
982722ac98SDario Binacchi #define BTR_TSEG2_MASK (0x7 << BTR_TSEG2_SHIFT)
992722ac98SDario Binacchi
1002722ac98SDario Binacchi /* interrupt register */
1012722ac98SDario Binacchi #define INT_STS_PENDING 0x8000
1022722ac98SDario Binacchi
1032722ac98SDario Binacchi /* brp extension register */
1042722ac98SDario Binacchi #define BRP_EXT_BRPE_MASK 0x0f
1052722ac98SDario Binacchi #define BRP_EXT_BRPE_SHIFT 0
1062722ac98SDario Binacchi
1072722ac98SDario Binacchi /* IFx command request */
1082722ac98SDario Binacchi #define IF_COMR_BUSY BIT(15)
1092722ac98SDario Binacchi
1102722ac98SDario Binacchi /* IFx command mask */
1112722ac98SDario Binacchi #define IF_COMM_WR BIT(7)
1122722ac98SDario Binacchi #define IF_COMM_MASK BIT(6)
1132722ac98SDario Binacchi #define IF_COMM_ARB BIT(5)
1142722ac98SDario Binacchi #define IF_COMM_CONTROL BIT(4)
1152722ac98SDario Binacchi #define IF_COMM_CLR_INT_PND BIT(3)
1162722ac98SDario Binacchi #define IF_COMM_TXRQST BIT(2)
1172722ac98SDario Binacchi #define IF_COMM_CLR_NEWDAT IF_COMM_TXRQST
1182722ac98SDario Binacchi #define IF_COMM_DATAA BIT(1)
1192722ac98SDario Binacchi #define IF_COMM_DATAB BIT(0)
1202722ac98SDario Binacchi
1212722ac98SDario Binacchi /* TX buffer setup */
1222722ac98SDario Binacchi #define IF_COMM_TX (IF_COMM_ARB | IF_COMM_CONTROL | \
1232722ac98SDario Binacchi IF_COMM_TXRQST | \
1242722ac98SDario Binacchi IF_COMM_DATAA | IF_COMM_DATAB)
1252722ac98SDario Binacchi
1262722ac98SDario Binacchi /* For the low buffers we clear the interrupt bit, but keep newdat */
1272722ac98SDario Binacchi #define IF_COMM_RCV_LOW (IF_COMM_MASK | IF_COMM_ARB | \
1282722ac98SDario Binacchi IF_COMM_CONTROL | IF_COMM_CLR_INT_PND | \
1292722ac98SDario Binacchi IF_COMM_DATAA | IF_COMM_DATAB)
1302722ac98SDario Binacchi
1312722ac98SDario Binacchi /* For the high buffers we clear the interrupt bit and newdat */
1322722ac98SDario Binacchi #define IF_COMM_RCV_HIGH (IF_COMM_RCV_LOW | IF_COMM_CLR_NEWDAT)
1332722ac98SDario Binacchi
1342722ac98SDario Binacchi /* Receive setup of message objects */
1352722ac98SDario Binacchi #define IF_COMM_RCV_SETUP (IF_COMM_MASK | IF_COMM_ARB | IF_COMM_CONTROL)
1362722ac98SDario Binacchi
1372722ac98SDario Binacchi /* Invalidation of message objects */
1382722ac98SDario Binacchi #define IF_COMM_INVAL (IF_COMM_ARB | IF_COMM_CONTROL)
1392722ac98SDario Binacchi
1402722ac98SDario Binacchi /* IFx arbitration */
1412722ac98SDario Binacchi #define IF_ARB_MSGVAL BIT(31)
1422722ac98SDario Binacchi #define IF_ARB_MSGXTD BIT(30)
1432722ac98SDario Binacchi #define IF_ARB_TRANSMIT BIT(29)
1442722ac98SDario Binacchi
1452722ac98SDario Binacchi /* IFx message control */
1462722ac98SDario Binacchi #define IF_MCONT_NEWDAT BIT(15)
1472722ac98SDario Binacchi #define IF_MCONT_MSGLST BIT(14)
1482722ac98SDario Binacchi #define IF_MCONT_INTPND BIT(13)
1492722ac98SDario Binacchi #define IF_MCONT_UMASK BIT(12)
1502722ac98SDario Binacchi #define IF_MCONT_TXIE BIT(11)
1512722ac98SDario Binacchi #define IF_MCONT_RXIE BIT(10)
1522722ac98SDario Binacchi #define IF_MCONT_RMTEN BIT(9)
1532722ac98SDario Binacchi #define IF_MCONT_TXRQST BIT(8)
1542722ac98SDario Binacchi #define IF_MCONT_EOB BIT(7)
1552722ac98SDario Binacchi #define IF_MCONT_DLC_MASK 0xf
1562722ac98SDario Binacchi
1572722ac98SDario Binacchi #define IF_MCONT_RCV (IF_MCONT_RXIE | IF_MCONT_UMASK)
1582722ac98SDario Binacchi #define IF_MCONT_RCV_EOB (IF_MCONT_RCV | IF_MCONT_EOB)
1592722ac98SDario Binacchi
1602722ac98SDario Binacchi #define IF_MCONT_TX (IF_MCONT_TXIE | IF_MCONT_EOB)
1612722ac98SDario Binacchi
16205cb2ba4SMarc Kleine-Budde /* Use IF1 in NAPI path and IF2 in TX path */
16305cb2ba4SMarc Kleine-Budde #define IF_NAPI 0
1642722ac98SDario Binacchi #define IF_TX 1
1652722ac98SDario Binacchi
1662722ac98SDario Binacchi /* minimum timeout for checking BUSY status */
1672722ac98SDario Binacchi #define MIN_TIMEOUT_VALUE 6
1682722ac98SDario Binacchi
1692722ac98SDario Binacchi /* Wait for ~1 sec for INIT bit */
1702722ac98SDario Binacchi #define INIT_WAIT_MS 1000
1712722ac98SDario Binacchi
1722722ac98SDario Binacchi /* c_can lec values */
1732722ac98SDario Binacchi enum c_can_lec_type {
1742722ac98SDario Binacchi LEC_NO_ERROR = 0,
1752722ac98SDario Binacchi LEC_STUFF_ERROR,
1762722ac98SDario Binacchi LEC_FORM_ERROR,
1772722ac98SDario Binacchi LEC_ACK_ERROR,
1782722ac98SDario Binacchi LEC_BIT1_ERROR,
1792722ac98SDario Binacchi LEC_BIT0_ERROR,
1802722ac98SDario Binacchi LEC_CRC_ERROR,
1812722ac98SDario Binacchi LEC_UNUSED,
1822722ac98SDario Binacchi LEC_MASK = LEC_UNUSED,
1832722ac98SDario Binacchi };
1842722ac98SDario Binacchi
1852722ac98SDario Binacchi /* c_can error types:
1862722ac98SDario Binacchi * Bus errors (BUS_OFF, ERROR_WARNING, ERROR_PASSIVE) are supported
1872722ac98SDario Binacchi */
1882722ac98SDario Binacchi enum c_can_bus_error_types {
1892722ac98SDario Binacchi C_CAN_NO_ERROR = 0,
1902722ac98SDario Binacchi C_CAN_BUS_OFF,
1912722ac98SDario Binacchi C_CAN_ERROR_WARNING,
1922722ac98SDario Binacchi C_CAN_ERROR_PASSIVE,
1932722ac98SDario Binacchi };
1942722ac98SDario Binacchi
1952722ac98SDario Binacchi static const struct can_bittiming_const c_can_bittiming_const = {
1962722ac98SDario Binacchi .name = KBUILD_MODNAME,
1972722ac98SDario Binacchi .tseg1_min = 2, /* Time segment 1 = prop_seg + phase_seg1 */
1982722ac98SDario Binacchi .tseg1_max = 16,
1992722ac98SDario Binacchi .tseg2_min = 1, /* Time segment 2 = phase_seg2 */
2002722ac98SDario Binacchi .tseg2_max = 8,
2012722ac98SDario Binacchi .sjw_max = 4,
2022722ac98SDario Binacchi .brp_min = 1,
2032722ac98SDario Binacchi .brp_max = 1024, /* 6-bit BRP field + 4-bit BRPE field*/
2042722ac98SDario Binacchi .brp_inc = 1,
2052722ac98SDario Binacchi };
2062722ac98SDario Binacchi
c_can_pm_runtime_get_sync(const struct c_can_priv * priv)2072722ac98SDario Binacchi static inline void c_can_pm_runtime_get_sync(const struct c_can_priv *priv)
2082722ac98SDario Binacchi {
2092722ac98SDario Binacchi if (priv->device)
2102722ac98SDario Binacchi pm_runtime_get_sync(priv->device);
2112722ac98SDario Binacchi }
2122722ac98SDario Binacchi
c_can_pm_runtime_put_sync(const struct c_can_priv * priv)2132722ac98SDario Binacchi static inline void c_can_pm_runtime_put_sync(const struct c_can_priv *priv)
2142722ac98SDario Binacchi {
2152722ac98SDario Binacchi if (priv->device)
2162722ac98SDario Binacchi pm_runtime_put_sync(priv->device);
2172722ac98SDario Binacchi }
2182722ac98SDario Binacchi
c_can_reset_ram(const struct c_can_priv * priv,bool enable)2192722ac98SDario Binacchi static inline void c_can_reset_ram(const struct c_can_priv *priv, bool enable)
2202722ac98SDario Binacchi {
2212722ac98SDario Binacchi if (priv->raminit)
2222722ac98SDario Binacchi priv->raminit(priv, enable);
2232722ac98SDario Binacchi }
2242722ac98SDario Binacchi
c_can_irq_control(struct c_can_priv * priv,bool enable)2252722ac98SDario Binacchi static void c_can_irq_control(struct c_can_priv *priv, bool enable)
2262722ac98SDario Binacchi {
2272722ac98SDario Binacchi u32 ctrl = priv->read_reg(priv, C_CAN_CTRL_REG) & ~CONTROL_IRQMSK;
2282722ac98SDario Binacchi
2292722ac98SDario Binacchi if (enable)
2302722ac98SDario Binacchi ctrl |= CONTROL_IRQMSK;
2312722ac98SDario Binacchi
2322722ac98SDario Binacchi priv->write_reg(priv, C_CAN_CTRL_REG, ctrl);
2332722ac98SDario Binacchi }
2342722ac98SDario Binacchi
c_can_obj_update(struct net_device * dev,int iface,u32 cmd,u32 obj)2352722ac98SDario Binacchi static void c_can_obj_update(struct net_device *dev, int iface, u32 cmd, u32 obj)
2362722ac98SDario Binacchi {
2372722ac98SDario Binacchi struct c_can_priv *priv = netdev_priv(dev);
2382722ac98SDario Binacchi int cnt, reg = C_CAN_IFACE(COMREQ_REG, iface);
2392722ac98SDario Binacchi
2402722ac98SDario Binacchi priv->write_reg32(priv, reg, (cmd << 16) | obj);
2412722ac98SDario Binacchi
2422722ac98SDario Binacchi for (cnt = MIN_TIMEOUT_VALUE; cnt; cnt--) {
2432722ac98SDario Binacchi if (!(priv->read_reg(priv, reg) & IF_COMR_BUSY))
2442722ac98SDario Binacchi return;
2452722ac98SDario Binacchi udelay(1);
2462722ac98SDario Binacchi }
2472722ac98SDario Binacchi netdev_err(dev, "Updating object timed out\n");
2482722ac98SDario Binacchi }
2492722ac98SDario Binacchi
c_can_object_get(struct net_device * dev,int iface,u32 obj,u32 cmd)2502722ac98SDario Binacchi static inline void c_can_object_get(struct net_device *dev, int iface,
2512722ac98SDario Binacchi u32 obj, u32 cmd)
2522722ac98SDario Binacchi {
2532722ac98SDario Binacchi c_can_obj_update(dev, iface, cmd, obj);
2542722ac98SDario Binacchi }
2552722ac98SDario Binacchi
c_can_object_put(struct net_device * dev,int iface,u32 obj,u32 cmd)2562722ac98SDario Binacchi static inline void c_can_object_put(struct net_device *dev, int iface,
2572722ac98SDario Binacchi u32 obj, u32 cmd)
2582722ac98SDario Binacchi {
2592722ac98SDario Binacchi c_can_obj_update(dev, iface, cmd | IF_COMM_WR, obj);
2602722ac98SDario Binacchi }
2612722ac98SDario Binacchi
2622722ac98SDario Binacchi /* Note: According to documentation clearing TXIE while MSGVAL is set
2632722ac98SDario Binacchi * is not allowed, but works nicely on C/DCAN. And that lowers the I/O
2642722ac98SDario Binacchi * load significantly.
2652722ac98SDario Binacchi */
c_can_inval_tx_object(struct net_device * dev,int iface,int obj)2662722ac98SDario Binacchi static void c_can_inval_tx_object(struct net_device *dev, int iface, int obj)
2672722ac98SDario Binacchi {
2682722ac98SDario Binacchi struct c_can_priv *priv = netdev_priv(dev);
2692722ac98SDario Binacchi
2702722ac98SDario Binacchi priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), 0);
2712722ac98SDario Binacchi c_can_object_put(dev, iface, obj, IF_COMM_INVAL);
2722722ac98SDario Binacchi }
2732722ac98SDario Binacchi
c_can_inval_msg_object(struct net_device * dev,int iface,int obj)2742722ac98SDario Binacchi static void c_can_inval_msg_object(struct net_device *dev, int iface, int obj)
2752722ac98SDario Binacchi {
2762722ac98SDario Binacchi struct c_can_priv *priv = netdev_priv(dev);
2772722ac98SDario Binacchi
2782722ac98SDario Binacchi priv->write_reg32(priv, C_CAN_IFACE(ARB1_REG, iface), 0);
2792722ac98SDario Binacchi c_can_inval_tx_object(dev, iface, obj);
2802722ac98SDario Binacchi }
2812722ac98SDario Binacchi
c_can_setup_tx_object(struct net_device * dev,int iface,struct can_frame * frame,int idx)2822722ac98SDario Binacchi static void c_can_setup_tx_object(struct net_device *dev, int iface,
2832722ac98SDario Binacchi struct can_frame *frame, int idx)
2842722ac98SDario Binacchi {
2852722ac98SDario Binacchi struct c_can_priv *priv = netdev_priv(dev);
2862722ac98SDario Binacchi u16 ctrl = IF_MCONT_TX | frame->len;
2872722ac98SDario Binacchi bool rtr = frame->can_id & CAN_RTR_FLAG;
2882722ac98SDario Binacchi u32 arb = IF_ARB_MSGVAL;
2892722ac98SDario Binacchi int i;
2902722ac98SDario Binacchi
2912722ac98SDario Binacchi if (frame->can_id & CAN_EFF_FLAG) {
2922722ac98SDario Binacchi arb |= frame->can_id & CAN_EFF_MASK;
2932722ac98SDario Binacchi arb |= IF_ARB_MSGXTD;
2942722ac98SDario Binacchi } else {
2952722ac98SDario Binacchi arb |= (frame->can_id & CAN_SFF_MASK) << 18;
2962722ac98SDario Binacchi }
2972722ac98SDario Binacchi
2982722ac98SDario Binacchi if (!rtr)
2992722ac98SDario Binacchi arb |= IF_ARB_TRANSMIT;
3002722ac98SDario Binacchi
3012722ac98SDario Binacchi /* If we change the DIR bit, we need to invalidate the buffer
3022722ac98SDario Binacchi * first, i.e. clear the MSGVAL flag in the arbiter.
3032722ac98SDario Binacchi */
3042722ac98SDario Binacchi if (rtr != (bool)test_bit(idx, &priv->tx_dir)) {
3052722ac98SDario Binacchi u32 obj = idx + priv->msg_obj_tx_first;
3062722ac98SDario Binacchi
3072722ac98SDario Binacchi c_can_inval_msg_object(dev, iface, obj);
3082722ac98SDario Binacchi change_bit(idx, &priv->tx_dir);
3092722ac98SDario Binacchi }
3102722ac98SDario Binacchi
3112722ac98SDario Binacchi priv->write_reg32(priv, C_CAN_IFACE(ARB1_REG, iface), arb);
3122722ac98SDario Binacchi
3132722ac98SDario Binacchi priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), ctrl);
3142722ac98SDario Binacchi
3152722ac98SDario Binacchi if (priv->type == BOSCH_D_CAN) {
3162722ac98SDario Binacchi u32 data = 0, dreg = C_CAN_IFACE(DATA1_REG, iface);
3172722ac98SDario Binacchi
3182722ac98SDario Binacchi for (i = 0; i < frame->len; i += 4, dreg += 2) {
3192722ac98SDario Binacchi data = (u32)frame->data[i];
3202722ac98SDario Binacchi data |= (u32)frame->data[i + 1] << 8;
3212722ac98SDario Binacchi data |= (u32)frame->data[i + 2] << 16;
3222722ac98SDario Binacchi data |= (u32)frame->data[i + 3] << 24;
3232722ac98SDario Binacchi priv->write_reg32(priv, dreg, data);
3242722ac98SDario Binacchi }
3252722ac98SDario Binacchi } else {
3262722ac98SDario Binacchi for (i = 0; i < frame->len; i += 2) {
3272722ac98SDario Binacchi priv->write_reg(priv,
3282722ac98SDario Binacchi C_CAN_IFACE(DATA1_REG, iface) + i / 2,
3292722ac98SDario Binacchi frame->data[i] |
3302722ac98SDario Binacchi (frame->data[i + 1] << 8));
3312722ac98SDario Binacchi }
3322722ac98SDario Binacchi }
3332722ac98SDario Binacchi }
3342722ac98SDario Binacchi
c_can_handle_lost_msg_obj(struct net_device * dev,int iface,int objno,u32 ctrl)3352722ac98SDario Binacchi static int c_can_handle_lost_msg_obj(struct net_device *dev,
3362722ac98SDario Binacchi int iface, int objno, u32 ctrl)
3372722ac98SDario Binacchi {
3382722ac98SDario Binacchi struct net_device_stats *stats = &dev->stats;
3392722ac98SDario Binacchi struct c_can_priv *priv = netdev_priv(dev);
3402722ac98SDario Binacchi struct can_frame *frame;
3412722ac98SDario Binacchi struct sk_buff *skb;
3422722ac98SDario Binacchi
3432722ac98SDario Binacchi ctrl &= ~(IF_MCONT_MSGLST | IF_MCONT_INTPND | IF_MCONT_NEWDAT);
3442722ac98SDario Binacchi priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), ctrl);
3452722ac98SDario Binacchi c_can_object_put(dev, iface, objno, IF_COMM_CONTROL);
3462722ac98SDario Binacchi
3472722ac98SDario Binacchi stats->rx_errors++;
3482722ac98SDario Binacchi stats->rx_over_errors++;
3492722ac98SDario Binacchi
3502722ac98SDario Binacchi /* create an error msg */
3512722ac98SDario Binacchi skb = alloc_can_err_skb(dev, &frame);
3522722ac98SDario Binacchi if (unlikely(!skb))
3532722ac98SDario Binacchi return 0;
3542722ac98SDario Binacchi
3552722ac98SDario Binacchi frame->can_id |= CAN_ERR_CRTL;
3562722ac98SDario Binacchi frame->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
3572722ac98SDario Binacchi
3582722ac98SDario Binacchi netif_receive_skb(skb);
3592722ac98SDario Binacchi return 1;
3602722ac98SDario Binacchi }
3612722ac98SDario Binacchi
c_can_read_msg_object(struct net_device * dev,int iface,u32 ctrl)3622722ac98SDario Binacchi static int c_can_read_msg_object(struct net_device *dev, int iface, u32 ctrl)
3632722ac98SDario Binacchi {
3642722ac98SDario Binacchi struct net_device_stats *stats = &dev->stats;
3652722ac98SDario Binacchi struct c_can_priv *priv = netdev_priv(dev);
3662722ac98SDario Binacchi struct can_frame *frame;
3672722ac98SDario Binacchi struct sk_buff *skb;
3682722ac98SDario Binacchi u32 arb, data;
3692722ac98SDario Binacchi
3702722ac98SDario Binacchi skb = alloc_can_skb(dev, &frame);
3712722ac98SDario Binacchi if (!skb) {
3722722ac98SDario Binacchi stats->rx_dropped++;
3732722ac98SDario Binacchi return -ENOMEM;
3742722ac98SDario Binacchi }
3752722ac98SDario Binacchi
3762722ac98SDario Binacchi frame->len = can_cc_dlc2len(ctrl & 0x0F);
3772722ac98SDario Binacchi
3782722ac98SDario Binacchi arb = priv->read_reg32(priv, C_CAN_IFACE(ARB1_REG, iface));
3792722ac98SDario Binacchi
3802722ac98SDario Binacchi if (arb & IF_ARB_MSGXTD)
3812722ac98SDario Binacchi frame->can_id = (arb & CAN_EFF_MASK) | CAN_EFF_FLAG;
3822722ac98SDario Binacchi else
3832722ac98SDario Binacchi frame->can_id = (arb >> 18) & CAN_SFF_MASK;
3842722ac98SDario Binacchi
3852722ac98SDario Binacchi if (arb & IF_ARB_TRANSMIT) {
3862722ac98SDario Binacchi frame->can_id |= CAN_RTR_FLAG;
3872722ac98SDario Binacchi } else {
3882722ac98SDario Binacchi int i, dreg = C_CAN_IFACE(DATA1_REG, iface);
3892722ac98SDario Binacchi
3902722ac98SDario Binacchi if (priv->type == BOSCH_D_CAN) {
3912722ac98SDario Binacchi for (i = 0; i < frame->len; i += 4, dreg += 2) {
3922722ac98SDario Binacchi data = priv->read_reg32(priv, dreg);
3932722ac98SDario Binacchi frame->data[i] = data;
3942722ac98SDario Binacchi frame->data[i + 1] = data >> 8;
3952722ac98SDario Binacchi frame->data[i + 2] = data >> 16;
3962722ac98SDario Binacchi frame->data[i + 3] = data >> 24;
3972722ac98SDario Binacchi }
3982722ac98SDario Binacchi } else {
3992722ac98SDario Binacchi for (i = 0; i < frame->len; i += 2, dreg++) {
4002722ac98SDario Binacchi data = priv->read_reg(priv, dreg);
4012722ac98SDario Binacchi frame->data[i] = data;
4022722ac98SDario Binacchi frame->data[i + 1] = data >> 8;
4032722ac98SDario Binacchi }
4042722ac98SDario Binacchi }
4052722ac98SDario Binacchi
4062722ac98SDario Binacchi stats->rx_bytes += frame->len;
4078e674ca7SVincent Mailhol }
4088e674ca7SVincent Mailhol stats->rx_packets++;
4092722ac98SDario Binacchi
4102722ac98SDario Binacchi netif_receive_skb(skb);
4112722ac98SDario Binacchi return 0;
4122722ac98SDario Binacchi }
4132722ac98SDario Binacchi
c_can_setup_receive_object(struct net_device * dev,int iface,u32 obj,u32 mask,u32 id,u32 mcont)4142722ac98SDario Binacchi static void c_can_setup_receive_object(struct net_device *dev, int iface,
4152722ac98SDario Binacchi u32 obj, u32 mask, u32 id, u32 mcont)
4162722ac98SDario Binacchi {
4172722ac98SDario Binacchi struct c_can_priv *priv = netdev_priv(dev);
4182722ac98SDario Binacchi
4192722ac98SDario Binacchi mask |= BIT(29);
4202722ac98SDario Binacchi priv->write_reg32(priv, C_CAN_IFACE(MASK1_REG, iface), mask);
4212722ac98SDario Binacchi
4222722ac98SDario Binacchi id |= IF_ARB_MSGVAL;
4232722ac98SDario Binacchi priv->write_reg32(priv, C_CAN_IFACE(ARB1_REG, iface), id);
4242722ac98SDario Binacchi
4252722ac98SDario Binacchi priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), mcont);
4262722ac98SDario Binacchi c_can_object_put(dev, iface, obj, IF_COMM_RCV_SETUP);
4272722ac98SDario Binacchi }
4282722ac98SDario Binacchi
c_can_tx_busy(const struct c_can_priv * priv,const struct c_can_tx_ring * tx_ring)42928e86e9aSDario Binacchi static bool c_can_tx_busy(const struct c_can_priv *priv,
43028e86e9aSDario Binacchi const struct c_can_tx_ring *tx_ring)
43128e86e9aSDario Binacchi {
43281d192c2SMarc Kleine-Budde if (c_can_get_tx_free(priv, tx_ring) > 0)
43328e86e9aSDario Binacchi return false;
43428e86e9aSDario Binacchi
43528e86e9aSDario Binacchi netif_stop_queue(priv->dev);
43628e86e9aSDario Binacchi
43728e86e9aSDario Binacchi /* Memory barrier before checking tx_free (head and tail) */
43828e86e9aSDario Binacchi smp_mb();
43928e86e9aSDario Binacchi
44081d192c2SMarc Kleine-Budde if (c_can_get_tx_free(priv, tx_ring) == 0) {
44128e86e9aSDario Binacchi netdev_dbg(priv->dev,
44228e86e9aSDario Binacchi "Stopping tx-queue (tx_head=0x%08x, tx_tail=0x%08x, len=%d).\n",
44328e86e9aSDario Binacchi tx_ring->head, tx_ring->tail,
44428e86e9aSDario Binacchi tx_ring->head - tx_ring->tail);
44528e86e9aSDario Binacchi return true;
44628e86e9aSDario Binacchi }
44728e86e9aSDario Binacchi
44828e86e9aSDario Binacchi netif_start_queue(priv->dev);
44928e86e9aSDario Binacchi return false;
45028e86e9aSDario Binacchi }
45128e86e9aSDario Binacchi
c_can_start_xmit(struct sk_buff * skb,struct net_device * dev)4522722ac98SDario Binacchi static netdev_tx_t c_can_start_xmit(struct sk_buff *skb,
4532722ac98SDario Binacchi struct net_device *dev)
4542722ac98SDario Binacchi {
4552722ac98SDario Binacchi struct can_frame *frame = (struct can_frame *)skb->data;
4562722ac98SDario Binacchi struct c_can_priv *priv = netdev_priv(dev);
45728e86e9aSDario Binacchi struct c_can_tx_ring *tx_ring = &priv->tx;
458387da6bcSDario Binacchi u32 idx, obj, cmd = IF_COMM_TX;
4592722ac98SDario Binacchi
460ae64438bSOliver Hartkopp if (can_dev_dropped_skb(dev, skb))
4612722ac98SDario Binacchi return NETDEV_TX_OK;
46228e86e9aSDario Binacchi
46328e86e9aSDario Binacchi if (c_can_tx_busy(priv, tx_ring))
46428e86e9aSDario Binacchi return NETDEV_TX_BUSY;
46528e86e9aSDario Binacchi
46628e86e9aSDario Binacchi idx = c_can_get_tx_head(tx_ring);
46728e86e9aSDario Binacchi tx_ring->head++;
46881d192c2SMarc Kleine-Budde if (c_can_get_tx_free(priv, tx_ring) == 0)
46928e86e9aSDario Binacchi netif_stop_queue(dev);
47028e86e9aSDario Binacchi
471387da6bcSDario Binacchi if (idx < c_can_get_tx_tail(tx_ring))
472387da6bcSDario Binacchi cmd &= ~IF_COMM_TXRQST; /* Cache the message */
4732722ac98SDario Binacchi
4742722ac98SDario Binacchi /* Store the message in the interface so we can call
4752722ac98SDario Binacchi * can_put_echo_skb(). We must do this before we enable
4762722ac98SDario Binacchi * transmit as we might race against do_tx().
4772722ac98SDario Binacchi */
4782722ac98SDario Binacchi c_can_setup_tx_object(dev, IF_TX, frame, idx);
4792722ac98SDario Binacchi can_put_echo_skb(skb, dev, idx, 0);
480387da6bcSDario Binacchi obj = idx + priv->msg_obj_tx_first;
481387da6bcSDario Binacchi c_can_object_put(dev, IF_TX, obj, cmd);
4822722ac98SDario Binacchi
4832722ac98SDario Binacchi return NETDEV_TX_OK;
4842722ac98SDario Binacchi }
4852722ac98SDario Binacchi
c_can_wait_for_ctrl_init(struct net_device * dev,struct c_can_priv * priv,u32 init)4862722ac98SDario Binacchi static int c_can_wait_for_ctrl_init(struct net_device *dev,
4872722ac98SDario Binacchi struct c_can_priv *priv, u32 init)
4882722ac98SDario Binacchi {
4892722ac98SDario Binacchi int retry = 0;
4902722ac98SDario Binacchi
4912722ac98SDario Binacchi while (init != (priv->read_reg(priv, C_CAN_CTRL_REG) & CONTROL_INIT)) {
4922722ac98SDario Binacchi udelay(10);
4932722ac98SDario Binacchi if (retry++ > 1000) {
4942722ac98SDario Binacchi netdev_err(dev, "CCTRL: set CONTROL_INIT failed\n");
4952722ac98SDario Binacchi return -EIO;
4962722ac98SDario Binacchi }
4972722ac98SDario Binacchi }
4982722ac98SDario Binacchi return 0;
4992722ac98SDario Binacchi }
5002722ac98SDario Binacchi
c_can_set_bittiming(struct net_device * dev)5012722ac98SDario Binacchi static int c_can_set_bittiming(struct net_device *dev)
5022722ac98SDario Binacchi {
5032722ac98SDario Binacchi unsigned int reg_btr, reg_brpe, ctrl_save;
5042722ac98SDario Binacchi u8 brp, brpe, sjw, tseg1, tseg2;
5052722ac98SDario Binacchi u32 ten_bit_brp;
5062722ac98SDario Binacchi struct c_can_priv *priv = netdev_priv(dev);
5072722ac98SDario Binacchi const struct can_bittiming *bt = &priv->can.bittiming;
5082722ac98SDario Binacchi int res;
5092722ac98SDario Binacchi
5102722ac98SDario Binacchi /* c_can provides a 6-bit brp and 4-bit brpe fields */
5112722ac98SDario Binacchi ten_bit_brp = bt->brp - 1;
5122722ac98SDario Binacchi brp = ten_bit_brp & BTR_BRP_MASK;
5132722ac98SDario Binacchi brpe = ten_bit_brp >> 6;
5142722ac98SDario Binacchi
5152722ac98SDario Binacchi sjw = bt->sjw - 1;
5162722ac98SDario Binacchi tseg1 = bt->prop_seg + bt->phase_seg1 - 1;
5172722ac98SDario Binacchi tseg2 = bt->phase_seg2 - 1;
5182722ac98SDario Binacchi reg_btr = brp | (sjw << BTR_SJW_SHIFT) | (tseg1 << BTR_TSEG1_SHIFT) |
5192722ac98SDario Binacchi (tseg2 << BTR_TSEG2_SHIFT);
5202722ac98SDario Binacchi reg_brpe = brpe & BRP_EXT_BRPE_MASK;
5212722ac98SDario Binacchi
5222722ac98SDario Binacchi netdev_info(dev,
5232722ac98SDario Binacchi "setting BTR=%04x BRPE=%04x\n", reg_btr, reg_brpe);
5242722ac98SDario Binacchi
5252722ac98SDario Binacchi ctrl_save = priv->read_reg(priv, C_CAN_CTRL_REG);
5262722ac98SDario Binacchi ctrl_save &= ~CONTROL_INIT;
5272722ac98SDario Binacchi priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_CCE | CONTROL_INIT);
5282722ac98SDario Binacchi res = c_can_wait_for_ctrl_init(dev, priv, CONTROL_INIT);
5292722ac98SDario Binacchi if (res)
5302722ac98SDario Binacchi return res;
5312722ac98SDario Binacchi
5322722ac98SDario Binacchi priv->write_reg(priv, C_CAN_BTR_REG, reg_btr);
5332722ac98SDario Binacchi priv->write_reg(priv, C_CAN_BRPEXT_REG, reg_brpe);
5342722ac98SDario Binacchi priv->write_reg(priv, C_CAN_CTRL_REG, ctrl_save);
5352722ac98SDario Binacchi
5362722ac98SDario Binacchi return c_can_wait_for_ctrl_init(dev, priv, 0);
5372722ac98SDario Binacchi }
5382722ac98SDario Binacchi
5392722ac98SDario Binacchi /* Configure C_CAN message objects for Tx and Rx purposes:
5402722ac98SDario Binacchi * C_CAN provides a total of 32 message objects that can be configured
5412722ac98SDario Binacchi * either for Tx or Rx purposes. Here the first 16 message objects are used as
5422722ac98SDario Binacchi * a reception FIFO. The end of reception FIFO is signified by the EoB bit
5432722ac98SDario Binacchi * being SET. The remaining 16 message objects are kept aside for Tx purposes.
5442722ac98SDario Binacchi * See user guide document for further details on configuring message
5452722ac98SDario Binacchi * objects.
5462722ac98SDario Binacchi */
c_can_configure_msg_objects(struct net_device * dev)5472722ac98SDario Binacchi static void c_can_configure_msg_objects(struct net_device *dev)
5482722ac98SDario Binacchi {
5492722ac98SDario Binacchi struct c_can_priv *priv = netdev_priv(dev);
5502722ac98SDario Binacchi int i;
5512722ac98SDario Binacchi
5522722ac98SDario Binacchi /* first invalidate all message objects */
5532722ac98SDario Binacchi for (i = priv->msg_obj_rx_first; i <= priv->msg_obj_num; i++)
55405cb2ba4SMarc Kleine-Budde c_can_inval_msg_object(dev, IF_NAPI, i);
5552722ac98SDario Binacchi
5562722ac98SDario Binacchi /* setup receive message objects */
5572722ac98SDario Binacchi for (i = priv->msg_obj_rx_first; i < priv->msg_obj_rx_last; i++)
55805cb2ba4SMarc Kleine-Budde c_can_setup_receive_object(dev, IF_NAPI, i, 0, 0, IF_MCONT_RCV);
5592722ac98SDario Binacchi
56005cb2ba4SMarc Kleine-Budde c_can_setup_receive_object(dev, IF_NAPI, priv->msg_obj_rx_last, 0, 0,
5612722ac98SDario Binacchi IF_MCONT_RCV_EOB);
5622722ac98SDario Binacchi }
5632722ac98SDario Binacchi
c_can_software_reset(struct net_device * dev)5642722ac98SDario Binacchi static int c_can_software_reset(struct net_device *dev)
5652722ac98SDario Binacchi {
5662722ac98SDario Binacchi struct c_can_priv *priv = netdev_priv(dev);
5672722ac98SDario Binacchi int retry = 0;
5682722ac98SDario Binacchi
5692722ac98SDario Binacchi if (priv->type != BOSCH_D_CAN)
5702722ac98SDario Binacchi return 0;
5712722ac98SDario Binacchi
5722722ac98SDario Binacchi priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_SWR | CONTROL_INIT);
5732722ac98SDario Binacchi while (priv->read_reg(priv, C_CAN_CTRL_REG) & CONTROL_SWR) {
5742722ac98SDario Binacchi msleep(20);
5752722ac98SDario Binacchi if (retry++ > 100) {
5762722ac98SDario Binacchi netdev_err(dev, "CCTRL: software reset failed\n");
5772722ac98SDario Binacchi return -EIO;
5782722ac98SDario Binacchi }
5792722ac98SDario Binacchi }
5802722ac98SDario Binacchi
5812722ac98SDario Binacchi return 0;
5822722ac98SDario Binacchi }
5832722ac98SDario Binacchi
5842722ac98SDario Binacchi /* Configure C_CAN chip:
5852722ac98SDario Binacchi * - enable/disable auto-retransmission
5862722ac98SDario Binacchi * - set operating mode
5872722ac98SDario Binacchi * - configure message objects
5882722ac98SDario Binacchi */
c_can_chip_config(struct net_device * dev)5892722ac98SDario Binacchi static int c_can_chip_config(struct net_device *dev)
5902722ac98SDario Binacchi {
5912722ac98SDario Binacchi struct c_can_priv *priv = netdev_priv(dev);
59228e86e9aSDario Binacchi struct c_can_tx_ring *tx_ring = &priv->tx;
5932722ac98SDario Binacchi int err;
5942722ac98SDario Binacchi
5952722ac98SDario Binacchi err = c_can_software_reset(dev);
5962722ac98SDario Binacchi if (err)
5972722ac98SDario Binacchi return err;
5982722ac98SDario Binacchi
5992722ac98SDario Binacchi /* enable automatic retransmission */
6002722ac98SDario Binacchi priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_ENABLE_AR);
6012722ac98SDario Binacchi
6022722ac98SDario Binacchi if ((priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) &&
6032722ac98SDario Binacchi (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)) {
6042722ac98SDario Binacchi /* loopback + silent mode : useful for hot self-test */
6052722ac98SDario Binacchi priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_TEST);
6062722ac98SDario Binacchi priv->write_reg(priv, C_CAN_TEST_REG, TEST_LBACK | TEST_SILENT);
6072722ac98SDario Binacchi } else if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) {
6082722ac98SDario Binacchi /* loopback mode : useful for self-test function */
6092722ac98SDario Binacchi priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_TEST);
6102722ac98SDario Binacchi priv->write_reg(priv, C_CAN_TEST_REG, TEST_LBACK);
6112722ac98SDario Binacchi } else if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) {
6122722ac98SDario Binacchi /* silent mode : bus-monitoring mode */
6132722ac98SDario Binacchi priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_TEST);
6142722ac98SDario Binacchi priv->write_reg(priv, C_CAN_TEST_REG, TEST_SILENT);
6152722ac98SDario Binacchi }
6162722ac98SDario Binacchi
6172722ac98SDario Binacchi /* configure message objects */
6182722ac98SDario Binacchi c_can_configure_msg_objects(dev);
6192722ac98SDario Binacchi
6202722ac98SDario Binacchi /* set a `lec` value so that we can check for updates later */
6212722ac98SDario Binacchi priv->write_reg(priv, C_CAN_STS_REG, LEC_UNUSED);
6222722ac98SDario Binacchi
6232722ac98SDario Binacchi /* Clear all internal status */
62428e86e9aSDario Binacchi tx_ring->head = 0;
62528e86e9aSDario Binacchi tx_ring->tail = 0;
6262722ac98SDario Binacchi priv->tx_dir = 0;
6272722ac98SDario Binacchi
6282722ac98SDario Binacchi /* set bittiming params */
6292722ac98SDario Binacchi return c_can_set_bittiming(dev);
6302722ac98SDario Binacchi }
6312722ac98SDario Binacchi
c_can_start(struct net_device * dev)6322722ac98SDario Binacchi static int c_can_start(struct net_device *dev)
6332722ac98SDario Binacchi {
6342722ac98SDario Binacchi struct c_can_priv *priv = netdev_priv(dev);
6352722ac98SDario Binacchi int err;
6362722ac98SDario Binacchi struct pinctrl *p;
6372722ac98SDario Binacchi
6382722ac98SDario Binacchi /* basic c_can configuration */
6392722ac98SDario Binacchi err = c_can_chip_config(dev);
6402722ac98SDario Binacchi if (err)
6412722ac98SDario Binacchi return err;
6422722ac98SDario Binacchi
6432722ac98SDario Binacchi /* Setup the command for new messages */
6442722ac98SDario Binacchi priv->comm_rcv_high = priv->type != BOSCH_D_CAN ?
6452722ac98SDario Binacchi IF_COMM_RCV_LOW : IF_COMM_RCV_HIGH;
6462722ac98SDario Binacchi
6472722ac98SDario Binacchi priv->can.state = CAN_STATE_ERROR_ACTIVE;
6482722ac98SDario Binacchi
6492722ac98SDario Binacchi /* Attempt to use "active" if available else use "default" */
6502722ac98SDario Binacchi p = pinctrl_get_select(priv->device, "active");
6512722ac98SDario Binacchi if (!IS_ERR(p))
6522722ac98SDario Binacchi pinctrl_put(p);
6532722ac98SDario Binacchi else
6542722ac98SDario Binacchi pinctrl_pm_select_default_state(priv->device);
6552722ac98SDario Binacchi
6562722ac98SDario Binacchi return 0;
6572722ac98SDario Binacchi }
6582722ac98SDario Binacchi
c_can_stop(struct net_device * dev)6592722ac98SDario Binacchi static void c_can_stop(struct net_device *dev)
6602722ac98SDario Binacchi {
6612722ac98SDario Binacchi struct c_can_priv *priv = netdev_priv(dev);
6622722ac98SDario Binacchi
6632722ac98SDario Binacchi c_can_irq_control(priv, false);
6642722ac98SDario Binacchi
6652722ac98SDario Binacchi /* put ctrl to init on stop to end ongoing transmission */
6662722ac98SDario Binacchi priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_INIT);
6672722ac98SDario Binacchi
6682722ac98SDario Binacchi /* deactivate pins */
6692722ac98SDario Binacchi pinctrl_pm_select_sleep_state(dev->dev.parent);
6702722ac98SDario Binacchi priv->can.state = CAN_STATE_STOPPED;
6712722ac98SDario Binacchi }
6722722ac98SDario Binacchi
c_can_set_mode(struct net_device * dev,enum can_mode mode)6732722ac98SDario Binacchi static int c_can_set_mode(struct net_device *dev, enum can_mode mode)
6742722ac98SDario Binacchi {
6752722ac98SDario Binacchi struct c_can_priv *priv = netdev_priv(dev);
6762722ac98SDario Binacchi int err;
6772722ac98SDario Binacchi
6782722ac98SDario Binacchi switch (mode) {
6792722ac98SDario Binacchi case CAN_MODE_START:
6802722ac98SDario Binacchi err = c_can_start(dev);
6812722ac98SDario Binacchi if (err)
6822722ac98SDario Binacchi return err;
6832722ac98SDario Binacchi netif_wake_queue(dev);
6842722ac98SDario Binacchi c_can_irq_control(priv, true);
6852722ac98SDario Binacchi break;
6862722ac98SDario Binacchi default:
6872722ac98SDario Binacchi return -EOPNOTSUPP;
6882722ac98SDario Binacchi }
6892722ac98SDario Binacchi
6902722ac98SDario Binacchi return 0;
6912722ac98SDario Binacchi }
6922722ac98SDario Binacchi
__c_can_get_berr_counter(const struct net_device * dev,struct can_berr_counter * bec)6932722ac98SDario Binacchi static int __c_can_get_berr_counter(const struct net_device *dev,
6942722ac98SDario Binacchi struct can_berr_counter *bec)
6952722ac98SDario Binacchi {
6962722ac98SDario Binacchi unsigned int reg_err_counter;
6972722ac98SDario Binacchi struct c_can_priv *priv = netdev_priv(dev);
6982722ac98SDario Binacchi
6992722ac98SDario Binacchi reg_err_counter = priv->read_reg(priv, C_CAN_ERR_CNT_REG);
7002722ac98SDario Binacchi bec->rxerr = (reg_err_counter & ERR_CNT_REC_MASK) >>
7012722ac98SDario Binacchi ERR_CNT_REC_SHIFT;
7022722ac98SDario Binacchi bec->txerr = reg_err_counter & ERR_CNT_TEC_MASK;
7032722ac98SDario Binacchi
7042722ac98SDario Binacchi return 0;
7052722ac98SDario Binacchi }
7062722ac98SDario Binacchi
c_can_get_berr_counter(const struct net_device * dev,struct can_berr_counter * bec)7072722ac98SDario Binacchi static int c_can_get_berr_counter(const struct net_device *dev,
7082722ac98SDario Binacchi struct can_berr_counter *bec)
7092722ac98SDario Binacchi {
7102722ac98SDario Binacchi struct c_can_priv *priv = netdev_priv(dev);
7112722ac98SDario Binacchi int err;
7122722ac98SDario Binacchi
7132722ac98SDario Binacchi c_can_pm_runtime_get_sync(priv);
7142722ac98SDario Binacchi err = __c_can_get_berr_counter(dev, bec);
7152722ac98SDario Binacchi c_can_pm_runtime_put_sync(priv);
7162722ac98SDario Binacchi
7172722ac98SDario Binacchi return err;
7182722ac98SDario Binacchi }
7192722ac98SDario Binacchi
c_can_do_tx(struct net_device * dev)7202722ac98SDario Binacchi static void c_can_do_tx(struct net_device *dev)
7212722ac98SDario Binacchi {
7222722ac98SDario Binacchi struct c_can_priv *priv = netdev_priv(dev);
72328e86e9aSDario Binacchi struct c_can_tx_ring *tx_ring = &priv->tx;
7242722ac98SDario Binacchi struct net_device_stats *stats = &dev->stats;
72528e86e9aSDario Binacchi u32 idx, obj, pkts = 0, bytes = 0, pend;
726387da6bcSDario Binacchi u8 tail;
7272722ac98SDario Binacchi
7282722ac98SDario Binacchi if (priv->msg_obj_tx_last > 32)
7292722ac98SDario Binacchi pend = priv->read_reg32(priv, C_CAN_INTPND3_REG);
7302722ac98SDario Binacchi else
7312722ac98SDario Binacchi pend = priv->read_reg(priv, C_CAN_INTPND2_REG);
7322722ac98SDario Binacchi
7332722ac98SDario Binacchi while ((idx = ffs(pend))) {
7342722ac98SDario Binacchi idx--;
7352722ac98SDario Binacchi pend &= ~BIT(idx);
7362722ac98SDario Binacchi obj = idx + priv->msg_obj_tx_first;
7372722ac98SDario Binacchi
73805cb2ba4SMarc Kleine-Budde /* We use IF_NAPI interface instead of IF_TX because we
7392722ac98SDario Binacchi * are called from c_can_poll(), which runs inside
740236de85fSMarc Kleine-Budde * NAPI. We are not transmitting.
7412722ac98SDario Binacchi */
74205cb2ba4SMarc Kleine-Budde c_can_inval_tx_object(dev, IF_NAPI, obj);
743cc4b08c3SVincent Mailhol bytes += can_get_echo_skb(dev, idx, NULL);
7442722ac98SDario Binacchi pkts++;
7452722ac98SDario Binacchi }
7462722ac98SDario Binacchi
747a54cdbbaSDario Binacchi if (!pkts)
748a54cdbbaSDario Binacchi return;
749a54cdbbaSDario Binacchi
75028e86e9aSDario Binacchi tx_ring->tail += pkts;
75181d192c2SMarc Kleine-Budde if (c_can_get_tx_free(priv, tx_ring)) {
75228e86e9aSDario Binacchi /* Make sure that anybody stopping the queue after
75328e86e9aSDario Binacchi * this sees the new tx_ring->tail.
75428e86e9aSDario Binacchi */
75528e86e9aSDario Binacchi smp_mb();
75628e86e9aSDario Binacchi netif_wake_queue(priv->dev);
75728e86e9aSDario Binacchi }
7582722ac98SDario Binacchi
7592722ac98SDario Binacchi stats->tx_bytes += bytes;
7602722ac98SDario Binacchi stats->tx_packets += pkts;
761387da6bcSDario Binacchi
762387da6bcSDario Binacchi tail = c_can_get_tx_tail(tx_ring);
76381d192c2SMarc Kleine-Budde if (priv->type == BOSCH_D_CAN && tail == 0) {
764387da6bcSDario Binacchi u8 head = c_can_get_tx_head(tx_ring);
765387da6bcSDario Binacchi
766387da6bcSDario Binacchi /* Start transmission for all cached messages */
767387da6bcSDario Binacchi for (idx = tail; idx < head; idx++) {
768387da6bcSDario Binacchi obj = idx + priv->msg_obj_tx_first;
769387da6bcSDario Binacchi c_can_object_put(dev, IF_NAPI, obj, IF_COMM_TXRQST);
770387da6bcSDario Binacchi }
771387da6bcSDario Binacchi }
7722722ac98SDario Binacchi }
7732722ac98SDario Binacchi
7742722ac98SDario Binacchi /* If we have a gap in the pending bits, that means we either
7752722ac98SDario Binacchi * raced with the hardware or failed to readout all upper
7762722ac98SDario Binacchi * objects in the last run due to quota limit.
7772722ac98SDario Binacchi */
c_can_adjust_pending(u32 pend,u32 rx_mask)7782722ac98SDario Binacchi static u32 c_can_adjust_pending(u32 pend, u32 rx_mask)
7792722ac98SDario Binacchi {
7802722ac98SDario Binacchi u32 weight, lasts;
7812722ac98SDario Binacchi
7822722ac98SDario Binacchi if (pend == rx_mask)
7832722ac98SDario Binacchi return pend;
7842722ac98SDario Binacchi
7852722ac98SDario Binacchi /* If the last set bit is larger than the number of pending
7862722ac98SDario Binacchi * bits we have a gap.
7872722ac98SDario Binacchi */
7882722ac98SDario Binacchi weight = hweight32(pend);
7892722ac98SDario Binacchi lasts = fls(pend);
7902722ac98SDario Binacchi
7912722ac98SDario Binacchi /* If the bits are linear, nothing to do */
7922722ac98SDario Binacchi if (lasts == weight)
7932722ac98SDario Binacchi return pend;
7942722ac98SDario Binacchi
7952722ac98SDario Binacchi /* Find the first set bit after the gap. We walk backwards
7962722ac98SDario Binacchi * from the last set bit.
7972722ac98SDario Binacchi */
7982722ac98SDario Binacchi for (lasts--; pend & BIT(lasts - 1); lasts--)
7992722ac98SDario Binacchi ;
8002722ac98SDario Binacchi
8012722ac98SDario Binacchi return pend & ~GENMASK(lasts - 1, 0);
8022722ac98SDario Binacchi }
8032722ac98SDario Binacchi
c_can_rx_object_get(struct net_device * dev,struct c_can_priv * priv,u32 obj)8042722ac98SDario Binacchi static inline void c_can_rx_object_get(struct net_device *dev,
8052722ac98SDario Binacchi struct c_can_priv *priv, u32 obj)
8062722ac98SDario Binacchi {
80705cb2ba4SMarc Kleine-Budde c_can_object_get(dev, IF_NAPI, obj, priv->comm_rcv_high);
8082722ac98SDario Binacchi }
8092722ac98SDario Binacchi
c_can_rx_finalize(struct net_device * dev,struct c_can_priv * priv,u32 obj)8102722ac98SDario Binacchi static inline void c_can_rx_finalize(struct net_device *dev,
8112722ac98SDario Binacchi struct c_can_priv *priv, u32 obj)
8122722ac98SDario Binacchi {
8132722ac98SDario Binacchi if (priv->type != BOSCH_D_CAN)
81405cb2ba4SMarc Kleine-Budde c_can_object_get(dev, IF_NAPI, obj, IF_COMM_CLR_NEWDAT);
8152722ac98SDario Binacchi }
8162722ac98SDario Binacchi
c_can_read_objects(struct net_device * dev,struct c_can_priv * priv,u32 pend,int quota)8172722ac98SDario Binacchi static int c_can_read_objects(struct net_device *dev, struct c_can_priv *priv,
8182722ac98SDario Binacchi u32 pend, int quota)
8192722ac98SDario Binacchi {
8202722ac98SDario Binacchi u32 pkts = 0, ctrl, obj;
8212722ac98SDario Binacchi
8222722ac98SDario Binacchi while ((obj = ffs(pend)) && quota > 0) {
8232722ac98SDario Binacchi pend &= ~BIT(obj - 1);
8242722ac98SDario Binacchi
8252722ac98SDario Binacchi c_can_rx_object_get(dev, priv, obj);
82605cb2ba4SMarc Kleine-Budde ctrl = priv->read_reg(priv, C_CAN_IFACE(MSGCTRL_REG, IF_NAPI));
8272722ac98SDario Binacchi
8282722ac98SDario Binacchi if (ctrl & IF_MCONT_MSGLST) {
82905cb2ba4SMarc Kleine-Budde int n;
83005cb2ba4SMarc Kleine-Budde
83105cb2ba4SMarc Kleine-Budde n = c_can_handle_lost_msg_obj(dev, IF_NAPI, obj, ctrl);
8322722ac98SDario Binacchi
8332722ac98SDario Binacchi pkts += n;
8342722ac98SDario Binacchi quota -= n;
8352722ac98SDario Binacchi continue;
8362722ac98SDario Binacchi }
8372722ac98SDario Binacchi
8382722ac98SDario Binacchi /* This really should not happen, but this covers some
8392722ac98SDario Binacchi * odd HW behaviour. Do not remove that unless you
8402722ac98SDario Binacchi * want to brick your machine.
8412722ac98SDario Binacchi */
8422722ac98SDario Binacchi if (!(ctrl & IF_MCONT_NEWDAT))
8432722ac98SDario Binacchi continue;
8442722ac98SDario Binacchi
8452722ac98SDario Binacchi /* read the data from the message object */
84605cb2ba4SMarc Kleine-Budde c_can_read_msg_object(dev, IF_NAPI, ctrl);
8472722ac98SDario Binacchi
8482722ac98SDario Binacchi c_can_rx_finalize(dev, priv, obj);
8492722ac98SDario Binacchi
8502722ac98SDario Binacchi pkts++;
8512722ac98SDario Binacchi quota--;
8522722ac98SDario Binacchi }
8532722ac98SDario Binacchi
8542722ac98SDario Binacchi return pkts;
8552722ac98SDario Binacchi }
8562722ac98SDario Binacchi
c_can_get_pending(struct c_can_priv * priv)8572722ac98SDario Binacchi static inline u32 c_can_get_pending(struct c_can_priv *priv)
8582722ac98SDario Binacchi {
8592722ac98SDario Binacchi u32 pend;
8602722ac98SDario Binacchi
8612722ac98SDario Binacchi if (priv->msg_obj_rx_last > 16)
8622722ac98SDario Binacchi pend = priv->read_reg32(priv, C_CAN_NEWDAT1_REG);
8632722ac98SDario Binacchi else
8642722ac98SDario Binacchi pend = priv->read_reg(priv, C_CAN_NEWDAT1_REG);
8652722ac98SDario Binacchi
8662722ac98SDario Binacchi return pend;
8672722ac98SDario Binacchi }
8682722ac98SDario Binacchi
8692722ac98SDario Binacchi /* theory of operation:
8702722ac98SDario Binacchi *
8712722ac98SDario Binacchi * c_can core saves a received CAN message into the first free message
8722722ac98SDario Binacchi * object it finds free (starting with the lowest). Bits NEWDAT and
8732722ac98SDario Binacchi * INTPND are set for this message object indicating that a new message
8742722ac98SDario Binacchi * has arrived.
8752722ac98SDario Binacchi *
8762722ac98SDario Binacchi * We clear the newdat bit right away.
8772722ac98SDario Binacchi *
8782722ac98SDario Binacchi * This can result in packet reordering when the readout is slow.
8792722ac98SDario Binacchi */
c_can_do_rx_poll(struct net_device * dev,int quota)8802722ac98SDario Binacchi static int c_can_do_rx_poll(struct net_device *dev, int quota)
8812722ac98SDario Binacchi {
8822722ac98SDario Binacchi struct c_can_priv *priv = netdev_priv(dev);
8832722ac98SDario Binacchi u32 pkts = 0, pend = 0, toread, n;
8842722ac98SDario Binacchi
8852722ac98SDario Binacchi while (quota > 0) {
8862722ac98SDario Binacchi if (!pend) {
8872722ac98SDario Binacchi pend = c_can_get_pending(priv);
8882722ac98SDario Binacchi if (!pend)
8892722ac98SDario Binacchi break;
8902722ac98SDario Binacchi /* If the pending field has a gap, handle the
8912722ac98SDario Binacchi * bits above the gap first.
8922722ac98SDario Binacchi */
8932722ac98SDario Binacchi toread = c_can_adjust_pending(pend,
8942722ac98SDario Binacchi priv->msg_obj_rx_mask);
8952722ac98SDario Binacchi } else {
8962722ac98SDario Binacchi toread = pend;
8972722ac98SDario Binacchi }
8982722ac98SDario Binacchi /* Remove the bits from pend */
8992722ac98SDario Binacchi pend &= ~toread;
9002722ac98SDario Binacchi /* Read the objects */
9012722ac98SDario Binacchi n = c_can_read_objects(dev, priv, toread, quota);
9022722ac98SDario Binacchi pkts += n;
9032722ac98SDario Binacchi quota -= n;
9042722ac98SDario Binacchi }
9052722ac98SDario Binacchi
9062722ac98SDario Binacchi return pkts;
9072722ac98SDario Binacchi }
9082722ac98SDario Binacchi
c_can_handle_state_change(struct net_device * dev,enum c_can_bus_error_types error_type)9092722ac98SDario Binacchi static int c_can_handle_state_change(struct net_device *dev,
9102722ac98SDario Binacchi enum c_can_bus_error_types error_type)
9112722ac98SDario Binacchi {
9122722ac98SDario Binacchi unsigned int reg_err_counter;
9132722ac98SDario Binacchi unsigned int rx_err_passive;
9142722ac98SDario Binacchi struct c_can_priv *priv = netdev_priv(dev);
9152722ac98SDario Binacchi struct can_frame *cf;
9162722ac98SDario Binacchi struct sk_buff *skb;
9172722ac98SDario Binacchi struct can_berr_counter bec;
9182722ac98SDario Binacchi
9192722ac98SDario Binacchi switch (error_type) {
9202722ac98SDario Binacchi case C_CAN_NO_ERROR:
9212722ac98SDario Binacchi priv->can.state = CAN_STATE_ERROR_ACTIVE;
9222722ac98SDario Binacchi break;
9232722ac98SDario Binacchi case C_CAN_ERROR_WARNING:
9242722ac98SDario Binacchi /* error warning state */
9252722ac98SDario Binacchi priv->can.can_stats.error_warning++;
9262722ac98SDario Binacchi priv->can.state = CAN_STATE_ERROR_WARNING;
9272722ac98SDario Binacchi break;
9282722ac98SDario Binacchi case C_CAN_ERROR_PASSIVE:
9292722ac98SDario Binacchi /* error passive state */
9302722ac98SDario Binacchi priv->can.can_stats.error_passive++;
9312722ac98SDario Binacchi priv->can.state = CAN_STATE_ERROR_PASSIVE;
9322722ac98SDario Binacchi break;
9332722ac98SDario Binacchi case C_CAN_BUS_OFF:
9342722ac98SDario Binacchi /* bus-off state */
9352722ac98SDario Binacchi priv->can.state = CAN_STATE_BUS_OFF;
9362722ac98SDario Binacchi priv->can.can_stats.bus_off++;
9372722ac98SDario Binacchi break;
9382722ac98SDario Binacchi default:
9392722ac98SDario Binacchi break;
9402722ac98SDario Binacchi }
9412722ac98SDario Binacchi
9422722ac98SDario Binacchi /* propagate the error condition to the CAN stack */
9432722ac98SDario Binacchi skb = alloc_can_err_skb(dev, &cf);
9442722ac98SDario Binacchi if (unlikely(!skb))
9452722ac98SDario Binacchi return 0;
9462722ac98SDario Binacchi
9472722ac98SDario Binacchi __c_can_get_berr_counter(dev, &bec);
9482722ac98SDario Binacchi reg_err_counter = priv->read_reg(priv, C_CAN_ERR_CNT_REG);
9492722ac98SDario Binacchi rx_err_passive = (reg_err_counter & ERR_CNT_RP_MASK) >>
9502722ac98SDario Binacchi ERR_CNT_RP_SHIFT;
9512722ac98SDario Binacchi
9522722ac98SDario Binacchi switch (error_type) {
9532722ac98SDario Binacchi case C_CAN_NO_ERROR:
9543e5c291cSVincent Mailhol cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
9552722ac98SDario Binacchi cf->data[1] = CAN_ERR_CRTL_ACTIVE;
9562722ac98SDario Binacchi cf->data[6] = bec.txerr;
9572722ac98SDario Binacchi cf->data[7] = bec.rxerr;
9582722ac98SDario Binacchi break;
9592722ac98SDario Binacchi case C_CAN_ERROR_WARNING:
9602722ac98SDario Binacchi /* error warning state */
9613e5c291cSVincent Mailhol cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
9622722ac98SDario Binacchi cf->data[1] = (bec.txerr > bec.rxerr) ?
9632722ac98SDario Binacchi CAN_ERR_CRTL_TX_WARNING :
9642722ac98SDario Binacchi CAN_ERR_CRTL_RX_WARNING;
9652722ac98SDario Binacchi cf->data[6] = bec.txerr;
9662722ac98SDario Binacchi cf->data[7] = bec.rxerr;
9672722ac98SDario Binacchi
9682722ac98SDario Binacchi break;
9692722ac98SDario Binacchi case C_CAN_ERROR_PASSIVE:
9702722ac98SDario Binacchi /* error passive state */
9713e5c291cSVincent Mailhol cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
9722722ac98SDario Binacchi if (rx_err_passive)
9732722ac98SDario Binacchi cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
9742722ac98SDario Binacchi if (bec.txerr > 127)
9752722ac98SDario Binacchi cf->data[1] |= CAN_ERR_CRTL_TX_PASSIVE;
9762722ac98SDario Binacchi
9772722ac98SDario Binacchi cf->data[6] = bec.txerr;
9782722ac98SDario Binacchi cf->data[7] = bec.rxerr;
9792722ac98SDario Binacchi break;
9802722ac98SDario Binacchi case C_CAN_BUS_OFF:
9812722ac98SDario Binacchi /* bus-off state */
9822722ac98SDario Binacchi cf->can_id |= CAN_ERR_BUSOFF;
9832722ac98SDario Binacchi can_bus_off(dev);
9842722ac98SDario Binacchi break;
9852722ac98SDario Binacchi default:
9862722ac98SDario Binacchi break;
9872722ac98SDario Binacchi }
9882722ac98SDario Binacchi
9892722ac98SDario Binacchi netif_receive_skb(skb);
9902722ac98SDario Binacchi
9912722ac98SDario Binacchi return 1;
9922722ac98SDario Binacchi }
9932722ac98SDario Binacchi
c_can_handle_bus_err(struct net_device * dev,enum c_can_lec_type lec_type)9942722ac98SDario Binacchi static int c_can_handle_bus_err(struct net_device *dev,
9952722ac98SDario Binacchi enum c_can_lec_type lec_type)
9962722ac98SDario Binacchi {
9972722ac98SDario Binacchi struct c_can_priv *priv = netdev_priv(dev);
9982722ac98SDario Binacchi struct net_device_stats *stats = &dev->stats;
9992722ac98SDario Binacchi struct can_frame *cf;
10002722ac98SDario Binacchi struct sk_buff *skb;
10012722ac98SDario Binacchi
10022722ac98SDario Binacchi /* early exit if no lec update or no error.
10032722ac98SDario Binacchi * no lec update means that no CAN bus event has been detected
10042722ac98SDario Binacchi * since CPU wrote 0x7 value to status reg.
10052722ac98SDario Binacchi */
10062722ac98SDario Binacchi if (lec_type == LEC_UNUSED || lec_type == LEC_NO_ERROR)
10072722ac98SDario Binacchi return 0;
10082722ac98SDario Binacchi
10092722ac98SDario Binacchi if (!(priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING))
10102722ac98SDario Binacchi return 0;
10112722ac98SDario Binacchi
10122722ac98SDario Binacchi /* common for all type of bus errors */
10132722ac98SDario Binacchi priv->can.can_stats.bus_error++;
10142722ac98SDario Binacchi
10152722ac98SDario Binacchi /* propagate the error condition to the CAN stack */
10162722ac98SDario Binacchi skb = alloc_can_err_skb(dev, &cf);
10172722ac98SDario Binacchi
10182722ac98SDario Binacchi /* check for 'last error code' which tells us the
10192722ac98SDario Binacchi * type of the last error to occur on the CAN bus
10202722ac98SDario Binacchi */
1021*c146df82SDario Binacchi if (likely(skb))
10222722ac98SDario Binacchi cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
10232722ac98SDario Binacchi
10242722ac98SDario Binacchi switch (lec_type) {
10252722ac98SDario Binacchi case LEC_STUFF_ERROR:
10262722ac98SDario Binacchi netdev_dbg(dev, "stuff error\n");
1027*c146df82SDario Binacchi if (likely(skb))
10282722ac98SDario Binacchi cf->data[2] |= CAN_ERR_PROT_STUFF;
1029f32fc3beSDario Binacchi stats->rx_errors++;
10302722ac98SDario Binacchi break;
10312722ac98SDario Binacchi case LEC_FORM_ERROR:
10322722ac98SDario Binacchi netdev_dbg(dev, "form error\n");
1033*c146df82SDario Binacchi if (likely(skb))
10342722ac98SDario Binacchi cf->data[2] |= CAN_ERR_PROT_FORM;
1035f32fc3beSDario Binacchi stats->rx_errors++;
10362722ac98SDario Binacchi break;
10372722ac98SDario Binacchi case LEC_ACK_ERROR:
10382722ac98SDario Binacchi netdev_dbg(dev, "ack error\n");
1039*c146df82SDario Binacchi if (likely(skb))
10402722ac98SDario Binacchi cf->data[3] = CAN_ERR_PROT_LOC_ACK;
1041f32fc3beSDario Binacchi stats->tx_errors++;
10422722ac98SDario Binacchi break;
10432722ac98SDario Binacchi case LEC_BIT1_ERROR:
10442722ac98SDario Binacchi netdev_dbg(dev, "bit1 error\n");
1045*c146df82SDario Binacchi if (likely(skb))
10462722ac98SDario Binacchi cf->data[2] |= CAN_ERR_PROT_BIT1;
1047f32fc3beSDario Binacchi stats->tx_errors++;
10482722ac98SDario Binacchi break;
10492722ac98SDario Binacchi case LEC_BIT0_ERROR:
10502722ac98SDario Binacchi netdev_dbg(dev, "bit0 error\n");
1051*c146df82SDario Binacchi if (likely(skb))
10522722ac98SDario Binacchi cf->data[2] |= CAN_ERR_PROT_BIT0;
1053f32fc3beSDario Binacchi stats->tx_errors++;
10542722ac98SDario Binacchi break;
10552722ac98SDario Binacchi case LEC_CRC_ERROR:
10562722ac98SDario Binacchi netdev_dbg(dev, "CRC error\n");
1057*c146df82SDario Binacchi if (likely(skb))
10582722ac98SDario Binacchi cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
1059f32fc3beSDario Binacchi stats->rx_errors++;
10602722ac98SDario Binacchi break;
10612722ac98SDario Binacchi default:
10622722ac98SDario Binacchi break;
10632722ac98SDario Binacchi }
10642722ac98SDario Binacchi
1065*c146df82SDario Binacchi if (unlikely(!skb))
1066*c146df82SDario Binacchi return 0;
1067*c146df82SDario Binacchi
10682722ac98SDario Binacchi netif_receive_skb(skb);
10692722ac98SDario Binacchi return 1;
10702722ac98SDario Binacchi }
10712722ac98SDario Binacchi
c_can_poll(struct napi_struct * napi,int quota)10722722ac98SDario Binacchi static int c_can_poll(struct napi_struct *napi, int quota)
10732722ac98SDario Binacchi {
10742722ac98SDario Binacchi struct net_device *dev = napi->dev;
10752722ac98SDario Binacchi struct c_can_priv *priv = netdev_priv(dev);
10762722ac98SDario Binacchi u16 curr, last = priv->last_status;
10772722ac98SDario Binacchi int work_done = 0;
10782722ac98SDario Binacchi
10792722ac98SDario Binacchi /* Only read the status register if a status interrupt was pending */
10802722ac98SDario Binacchi if (atomic_xchg(&priv->sie_pending, 0)) {
10812722ac98SDario Binacchi priv->last_status = priv->read_reg(priv, C_CAN_STS_REG);
10822722ac98SDario Binacchi curr = priv->last_status;
10832722ac98SDario Binacchi /* Ack status on C_CAN. D_CAN is self clearing */
10842722ac98SDario Binacchi if (priv->type != BOSCH_D_CAN)
10852722ac98SDario Binacchi priv->write_reg(priv, C_CAN_STS_REG, LEC_UNUSED);
10862722ac98SDario Binacchi } else {
10872722ac98SDario Binacchi /* no change detected ... */
10882722ac98SDario Binacchi curr = last;
10892722ac98SDario Binacchi }
10902722ac98SDario Binacchi
10912722ac98SDario Binacchi /* handle state changes */
10922722ac98SDario Binacchi if ((curr & STATUS_EWARN) && (!(last & STATUS_EWARN))) {
10932722ac98SDario Binacchi netdev_dbg(dev, "entered error warning state\n");
10942722ac98SDario Binacchi work_done += c_can_handle_state_change(dev, C_CAN_ERROR_WARNING);
10952722ac98SDario Binacchi }
10962722ac98SDario Binacchi
10972722ac98SDario Binacchi if ((curr & STATUS_EPASS) && (!(last & STATUS_EPASS))) {
10982722ac98SDario Binacchi netdev_dbg(dev, "entered error passive state\n");
10992722ac98SDario Binacchi work_done += c_can_handle_state_change(dev, C_CAN_ERROR_PASSIVE);
11002722ac98SDario Binacchi }
11012722ac98SDario Binacchi
11022722ac98SDario Binacchi if ((curr & STATUS_BOFF) && (!(last & STATUS_BOFF))) {
11032722ac98SDario Binacchi netdev_dbg(dev, "entered bus off state\n");
11042722ac98SDario Binacchi work_done += c_can_handle_state_change(dev, C_CAN_BUS_OFF);
11052722ac98SDario Binacchi goto end;
11062722ac98SDario Binacchi }
11072722ac98SDario Binacchi
11082722ac98SDario Binacchi /* handle bus recovery events */
11092722ac98SDario Binacchi if ((!(curr & STATUS_BOFF)) && (last & STATUS_BOFF)) {
11102722ac98SDario Binacchi netdev_dbg(dev, "left bus off state\n");
11112722ac98SDario Binacchi work_done += c_can_handle_state_change(dev, C_CAN_ERROR_PASSIVE);
11122722ac98SDario Binacchi }
11132722ac98SDario Binacchi
11142722ac98SDario Binacchi if ((!(curr & STATUS_EPASS)) && (last & STATUS_EPASS)) {
11152722ac98SDario Binacchi netdev_dbg(dev, "left error passive state\n");
11162722ac98SDario Binacchi work_done += c_can_handle_state_change(dev, C_CAN_ERROR_WARNING);
11172722ac98SDario Binacchi }
11182722ac98SDario Binacchi
11192722ac98SDario Binacchi if ((!(curr & STATUS_EWARN)) && (last & STATUS_EWARN)) {
11202722ac98SDario Binacchi netdev_dbg(dev, "left error warning state\n");
11212722ac98SDario Binacchi work_done += c_can_handle_state_change(dev, C_CAN_NO_ERROR);
11222722ac98SDario Binacchi }
11232722ac98SDario Binacchi
11242722ac98SDario Binacchi /* handle lec errors on the bus */
11252722ac98SDario Binacchi work_done += c_can_handle_bus_err(dev, curr & LEC_MASK);
11262722ac98SDario Binacchi
11272722ac98SDario Binacchi /* Handle Tx/Rx events. We do this unconditionally */
11282722ac98SDario Binacchi work_done += c_can_do_rx_poll(dev, (quota - work_done));
11292722ac98SDario Binacchi c_can_do_tx(dev);
11302722ac98SDario Binacchi
11312722ac98SDario Binacchi end:
11322722ac98SDario Binacchi if (work_done < quota) {
11332722ac98SDario Binacchi napi_complete_done(napi, work_done);
11342722ac98SDario Binacchi /* enable all IRQs if we are not in bus off state */
11352722ac98SDario Binacchi if (priv->can.state != CAN_STATE_BUS_OFF)
11362722ac98SDario Binacchi c_can_irq_control(priv, true);
11372722ac98SDario Binacchi }
11382722ac98SDario Binacchi
11392722ac98SDario Binacchi return work_done;
11402722ac98SDario Binacchi }
11412722ac98SDario Binacchi
c_can_isr(int irq,void * dev_id)11422722ac98SDario Binacchi static irqreturn_t c_can_isr(int irq, void *dev_id)
11432722ac98SDario Binacchi {
11442722ac98SDario Binacchi struct net_device *dev = (struct net_device *)dev_id;
11452722ac98SDario Binacchi struct c_can_priv *priv = netdev_priv(dev);
11462722ac98SDario Binacchi int reg_int;
11472722ac98SDario Binacchi
11482722ac98SDario Binacchi reg_int = priv->read_reg(priv, C_CAN_INT_REG);
11492722ac98SDario Binacchi if (!reg_int)
11502722ac98SDario Binacchi return IRQ_NONE;
11512722ac98SDario Binacchi
11522722ac98SDario Binacchi /* save for later use */
11532722ac98SDario Binacchi if (reg_int & INT_STS_PENDING)
11542722ac98SDario Binacchi atomic_set(&priv->sie_pending, 1);
11552722ac98SDario Binacchi
11562722ac98SDario Binacchi /* disable all interrupts and schedule the NAPI */
11572722ac98SDario Binacchi c_can_irq_control(priv, false);
11582722ac98SDario Binacchi napi_schedule(&priv->napi);
11592722ac98SDario Binacchi
11602722ac98SDario Binacchi return IRQ_HANDLED;
11612722ac98SDario Binacchi }
11622722ac98SDario Binacchi
c_can_open(struct net_device * dev)11632722ac98SDario Binacchi static int c_can_open(struct net_device *dev)
11642722ac98SDario Binacchi {
11652722ac98SDario Binacchi int err;
11662722ac98SDario Binacchi struct c_can_priv *priv = netdev_priv(dev);
11672722ac98SDario Binacchi
11682722ac98SDario Binacchi c_can_pm_runtime_get_sync(priv);
11692722ac98SDario Binacchi c_can_reset_ram(priv, true);
11702722ac98SDario Binacchi
11712722ac98SDario Binacchi /* open the can device */
11722722ac98SDario Binacchi err = open_candev(dev);
11732722ac98SDario Binacchi if (err) {
11742722ac98SDario Binacchi netdev_err(dev, "failed to open can device\n");
11752722ac98SDario Binacchi goto exit_open_fail;
11762722ac98SDario Binacchi }
11772722ac98SDario Binacchi
11782722ac98SDario Binacchi /* register interrupt handler */
11792722ac98SDario Binacchi err = request_irq(dev->irq, &c_can_isr, IRQF_SHARED, dev->name,
11802722ac98SDario Binacchi dev);
11812722ac98SDario Binacchi if (err < 0) {
11822722ac98SDario Binacchi netdev_err(dev, "failed to request interrupt\n");
11832722ac98SDario Binacchi goto exit_irq_fail;
11842722ac98SDario Binacchi }
11852722ac98SDario Binacchi
11862722ac98SDario Binacchi /* start the c_can controller */
11872722ac98SDario Binacchi err = c_can_start(dev);
11882722ac98SDario Binacchi if (err)
11892722ac98SDario Binacchi goto exit_start_fail;
11902722ac98SDario Binacchi
11912722ac98SDario Binacchi napi_enable(&priv->napi);
11922722ac98SDario Binacchi /* enable status change, error and module interrupts */
11932722ac98SDario Binacchi c_can_irq_control(priv, true);
11942722ac98SDario Binacchi netif_start_queue(dev);
11952722ac98SDario Binacchi
11962722ac98SDario Binacchi return 0;
11972722ac98SDario Binacchi
11982722ac98SDario Binacchi exit_start_fail:
11992722ac98SDario Binacchi free_irq(dev->irq, dev);
12002722ac98SDario Binacchi exit_irq_fail:
12012722ac98SDario Binacchi close_candev(dev);
12022722ac98SDario Binacchi exit_open_fail:
12032722ac98SDario Binacchi c_can_reset_ram(priv, false);
12042722ac98SDario Binacchi c_can_pm_runtime_put_sync(priv);
12052722ac98SDario Binacchi return err;
12062722ac98SDario Binacchi }
12072722ac98SDario Binacchi
c_can_close(struct net_device * dev)12082722ac98SDario Binacchi static int c_can_close(struct net_device *dev)
12092722ac98SDario Binacchi {
12102722ac98SDario Binacchi struct c_can_priv *priv = netdev_priv(dev);
12112722ac98SDario Binacchi
12122722ac98SDario Binacchi netif_stop_queue(dev);
12132722ac98SDario Binacchi napi_disable(&priv->napi);
12142722ac98SDario Binacchi c_can_stop(dev);
12152722ac98SDario Binacchi free_irq(dev->irq, dev);
12162722ac98SDario Binacchi close_candev(dev);
12172722ac98SDario Binacchi
12182722ac98SDario Binacchi c_can_reset_ram(priv, false);
12192722ac98SDario Binacchi c_can_pm_runtime_put_sync(priv);
12202722ac98SDario Binacchi
12212722ac98SDario Binacchi return 0;
12222722ac98SDario Binacchi }
12232722ac98SDario Binacchi
alloc_c_can_dev(int msg_obj_num)12242722ac98SDario Binacchi struct net_device *alloc_c_can_dev(int msg_obj_num)
12252722ac98SDario Binacchi {
12262722ac98SDario Binacchi struct net_device *dev;
12272722ac98SDario Binacchi struct c_can_priv *priv;
12282722ac98SDario Binacchi int msg_obj_tx_num = msg_obj_num / 2;
12292722ac98SDario Binacchi
1230cc4b08c3SVincent Mailhol dev = alloc_candev(sizeof(*priv), msg_obj_tx_num);
12312722ac98SDario Binacchi if (!dev)
12322722ac98SDario Binacchi return NULL;
12332722ac98SDario Binacchi
12342722ac98SDario Binacchi priv = netdev_priv(dev);
12352722ac98SDario Binacchi priv->msg_obj_num = msg_obj_num;
12362722ac98SDario Binacchi priv->msg_obj_rx_num = msg_obj_num - msg_obj_tx_num;
12372722ac98SDario Binacchi priv->msg_obj_rx_first = 1;
12382722ac98SDario Binacchi priv->msg_obj_rx_last =
12392722ac98SDario Binacchi priv->msg_obj_rx_first + priv->msg_obj_rx_num - 1;
12402722ac98SDario Binacchi priv->msg_obj_rx_mask = GENMASK(priv->msg_obj_rx_num - 1, 0);
12412722ac98SDario Binacchi
12422722ac98SDario Binacchi priv->msg_obj_tx_num = msg_obj_tx_num;
12432722ac98SDario Binacchi priv->msg_obj_tx_first = priv->msg_obj_rx_last + 1;
12442722ac98SDario Binacchi priv->msg_obj_tx_last =
12452722ac98SDario Binacchi priv->msg_obj_tx_first + priv->msg_obj_tx_num - 1;
12462722ac98SDario Binacchi
124728e86e9aSDario Binacchi priv->tx.head = 0;
124828e86e9aSDario Binacchi priv->tx.tail = 0;
124928e86e9aSDario Binacchi priv->tx.obj_num = msg_obj_tx_num;
125028e86e9aSDario Binacchi
1251caf6b7f8SJakub Kicinski netif_napi_add_weight(dev, &priv->napi, c_can_poll,
1252caf6b7f8SJakub Kicinski priv->msg_obj_rx_num);
12532722ac98SDario Binacchi
12542722ac98SDario Binacchi priv->dev = dev;
12552722ac98SDario Binacchi priv->can.bittiming_const = &c_can_bittiming_const;
12562722ac98SDario Binacchi priv->can.do_set_mode = c_can_set_mode;
12572722ac98SDario Binacchi priv->can.do_get_berr_counter = c_can_get_berr_counter;
12582722ac98SDario Binacchi priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK |
12592722ac98SDario Binacchi CAN_CTRLMODE_LISTENONLY |
12602722ac98SDario Binacchi CAN_CTRLMODE_BERR_REPORTING;
12612722ac98SDario Binacchi
12622722ac98SDario Binacchi return dev;
12632722ac98SDario Binacchi }
12642722ac98SDario Binacchi EXPORT_SYMBOL_GPL(alloc_c_can_dev);
12652722ac98SDario Binacchi
12662722ac98SDario Binacchi #ifdef CONFIG_PM
c_can_power_down(struct net_device * dev)12672722ac98SDario Binacchi int c_can_power_down(struct net_device *dev)
12682722ac98SDario Binacchi {
12692722ac98SDario Binacchi u32 val;
12702722ac98SDario Binacchi unsigned long time_out;
12712722ac98SDario Binacchi struct c_can_priv *priv = netdev_priv(dev);
12722722ac98SDario Binacchi
12732722ac98SDario Binacchi if (!(dev->flags & IFF_UP))
12742722ac98SDario Binacchi return 0;
12752722ac98SDario Binacchi
12762722ac98SDario Binacchi WARN_ON(priv->type != BOSCH_D_CAN);
12772722ac98SDario Binacchi
12782722ac98SDario Binacchi /* set PDR value so the device goes to power down mode */
12792722ac98SDario Binacchi val = priv->read_reg(priv, C_CAN_CTRL_EX_REG);
12802722ac98SDario Binacchi val |= CONTROL_EX_PDR;
12812722ac98SDario Binacchi priv->write_reg(priv, C_CAN_CTRL_EX_REG, val);
12822722ac98SDario Binacchi
12832722ac98SDario Binacchi /* Wait for the PDA bit to get set */
12842722ac98SDario Binacchi time_out = jiffies + msecs_to_jiffies(INIT_WAIT_MS);
12852722ac98SDario Binacchi while (!(priv->read_reg(priv, C_CAN_STS_REG) & STATUS_PDA) &&
12862722ac98SDario Binacchi time_after(time_out, jiffies))
12872722ac98SDario Binacchi cpu_relax();
12882722ac98SDario Binacchi
12892722ac98SDario Binacchi if (time_after(jiffies, time_out))
12902722ac98SDario Binacchi return -ETIMEDOUT;
12912722ac98SDario Binacchi
12922722ac98SDario Binacchi c_can_stop(dev);
12932722ac98SDario Binacchi
12942722ac98SDario Binacchi c_can_reset_ram(priv, false);
12952722ac98SDario Binacchi c_can_pm_runtime_put_sync(priv);
12962722ac98SDario Binacchi
12972722ac98SDario Binacchi return 0;
12982722ac98SDario Binacchi }
12992722ac98SDario Binacchi EXPORT_SYMBOL_GPL(c_can_power_down);
13002722ac98SDario Binacchi
c_can_power_up(struct net_device * dev)13012722ac98SDario Binacchi int c_can_power_up(struct net_device *dev)
13022722ac98SDario Binacchi {
13032722ac98SDario Binacchi u32 val;
13042722ac98SDario Binacchi unsigned long time_out;
13052722ac98SDario Binacchi struct c_can_priv *priv = netdev_priv(dev);
13062722ac98SDario Binacchi int ret;
13072722ac98SDario Binacchi
13082722ac98SDario Binacchi if (!(dev->flags & IFF_UP))
13092722ac98SDario Binacchi return 0;
13102722ac98SDario Binacchi
13112722ac98SDario Binacchi WARN_ON(priv->type != BOSCH_D_CAN);
13122722ac98SDario Binacchi
13132722ac98SDario Binacchi c_can_pm_runtime_get_sync(priv);
13142722ac98SDario Binacchi c_can_reset_ram(priv, true);
13152722ac98SDario Binacchi
13162722ac98SDario Binacchi /* Clear PDR and INIT bits */
13172722ac98SDario Binacchi val = priv->read_reg(priv, C_CAN_CTRL_EX_REG);
13182722ac98SDario Binacchi val &= ~CONTROL_EX_PDR;
13192722ac98SDario Binacchi priv->write_reg(priv, C_CAN_CTRL_EX_REG, val);
13202722ac98SDario Binacchi val = priv->read_reg(priv, C_CAN_CTRL_REG);
13212722ac98SDario Binacchi val &= ~CONTROL_INIT;
13222722ac98SDario Binacchi priv->write_reg(priv, C_CAN_CTRL_REG, val);
13232722ac98SDario Binacchi
13242722ac98SDario Binacchi /* Wait for the PDA bit to get clear */
13252722ac98SDario Binacchi time_out = jiffies + msecs_to_jiffies(INIT_WAIT_MS);
13262722ac98SDario Binacchi while ((priv->read_reg(priv, C_CAN_STS_REG) & STATUS_PDA) &&
13272722ac98SDario Binacchi time_after(time_out, jiffies))
13282722ac98SDario Binacchi cpu_relax();
13292722ac98SDario Binacchi
13302722ac98SDario Binacchi if (time_after(jiffies, time_out)) {
13312722ac98SDario Binacchi ret = -ETIMEDOUT;
13322722ac98SDario Binacchi goto err_out;
13332722ac98SDario Binacchi }
13342722ac98SDario Binacchi
13352722ac98SDario Binacchi ret = c_can_start(dev);
13362722ac98SDario Binacchi if (ret)
13372722ac98SDario Binacchi goto err_out;
13382722ac98SDario Binacchi
13392722ac98SDario Binacchi c_can_irq_control(priv, true);
13402722ac98SDario Binacchi
13412722ac98SDario Binacchi return 0;
13422722ac98SDario Binacchi
13432722ac98SDario Binacchi err_out:
13442722ac98SDario Binacchi c_can_reset_ram(priv, false);
13452722ac98SDario Binacchi c_can_pm_runtime_put_sync(priv);
13462722ac98SDario Binacchi
13472722ac98SDario Binacchi return ret;
13482722ac98SDario Binacchi }
13492722ac98SDario Binacchi EXPORT_SYMBOL_GPL(c_can_power_up);
13502722ac98SDario Binacchi #endif
13512722ac98SDario Binacchi
free_c_can_dev(struct net_device * dev)13522722ac98SDario Binacchi void free_c_can_dev(struct net_device *dev)
13532722ac98SDario Binacchi {
13542722ac98SDario Binacchi struct c_can_priv *priv = netdev_priv(dev);
13552722ac98SDario Binacchi
13562722ac98SDario Binacchi netif_napi_del(&priv->napi);
13572722ac98SDario Binacchi free_candev(dev);
13582722ac98SDario Binacchi }
13592722ac98SDario Binacchi EXPORT_SYMBOL_GPL(free_c_can_dev);
13602722ac98SDario Binacchi
13612722ac98SDario Binacchi static const struct net_device_ops c_can_netdev_ops = {
13622722ac98SDario Binacchi .ndo_open = c_can_open,
13632722ac98SDario Binacchi .ndo_stop = c_can_close,
13642722ac98SDario Binacchi .ndo_start_xmit = c_can_start_xmit,
13652722ac98SDario Binacchi .ndo_change_mtu = can_change_mtu,
13662722ac98SDario Binacchi };
13672722ac98SDario Binacchi
register_c_can_dev(struct net_device * dev)13682722ac98SDario Binacchi int register_c_can_dev(struct net_device *dev)
13692722ac98SDario Binacchi {
13702722ac98SDario Binacchi /* Deactivate pins to prevent DRA7 DCAN IP from being
13712722ac98SDario Binacchi * stuck in transition when module is disabled.
13722722ac98SDario Binacchi * Pins are activated in c_can_start() and deactivated
13732722ac98SDario Binacchi * in c_can_stop()
13742722ac98SDario Binacchi */
13752722ac98SDario Binacchi pinctrl_pm_select_sleep_state(dev->dev.parent);
13762722ac98SDario Binacchi
13772722ac98SDario Binacchi dev->flags |= IFF_ECHO; /* we support local echo */
13782722ac98SDario Binacchi dev->netdev_ops = &c_can_netdev_ops;
13790ccb3e0bSVincent Mailhol dev->ethtool_ops = &c_can_ethtool_ops;
13802722ac98SDario Binacchi
13816c1e423aSOliver Hartkopp return register_candev(dev);
13822722ac98SDario Binacchi }
13832722ac98SDario Binacchi EXPORT_SYMBOL_GPL(register_c_can_dev);
13842722ac98SDario Binacchi
unregister_c_can_dev(struct net_device * dev)13852722ac98SDario Binacchi void unregister_c_can_dev(struct net_device *dev)
13862722ac98SDario Binacchi {
13872722ac98SDario Binacchi unregister_candev(dev);
13882722ac98SDario Binacchi }
13892722ac98SDario Binacchi EXPORT_SYMBOL_GPL(unregister_c_can_dev);
13902722ac98SDario Binacchi
13912722ac98SDario Binacchi MODULE_AUTHOR("Bhupesh Sharma <bhupesh.sharma@st.com>");
13922722ac98SDario Binacchi MODULE_LICENSE("GPL v2");
13932722ac98SDario Binacchi MODULE_DESCRIPTION("CAN bus driver for Bosch C_CAN controller");
1394