D_CAN supports up to 128 message objects, comparing to 32 on C_CAN.
However, some CPUs with D_CAN controller have their own limits:
TI AM335x Sitara CPU, for example, supports max of 64 message objects.

This patch extends max D_CAN message objects up to 64.

Signed-off-by: Andrejs Cainikovs <andrejs.cainik...@netmodule.com>
---
 drivers/net/can/c_can/Kconfig | 12 ++++++++++++
 drivers/net/can/c_can/c_can.c | 42 ++++++++++++++++++++++--------------------
 drivers/net/can/c_can/c_can.h | 20 ++++++++++++++++----
 3 files changed, 50 insertions(+), 24 deletions(-)

diff --git a/drivers/net/can/c_can/Kconfig b/drivers/net/can/c_can/Kconfig
index 61ffc12d8fd8..6c1ada7291df 100644
--- a/drivers/net/can/c_can/Kconfig
+++ b/drivers/net/can/c_can/Kconfig
@@ -20,4 +20,16 @@ config CAN_C_CAN_PCI
        ---help---
          This driver adds support for the C_CAN/D_CAN chips connected
          to the PCI bus.
+
+config CAN_C_CAN_DCAN_64_MSG_OBJECTS
+       bool "Use 64 message objects for D_CAN"
+       default n
+       ---help---
+         D_CAN supports up to 128 message objects, comparing to 32 on
+         C_CAN. However, some CPUs with D_CAN controller have their
+         own limits: TI AM335x Sitara CPU, for example, supports max
+         of 64 message objects.
+         Enabling this option extends max D_CAN message objects up to
+         64.
+
 endif
diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c
index 606b7d8ffe13..5d695b89b459 100644
--- a/drivers/net/can/c_can/c_can.c
+++ b/drivers/net/can/c_can/c_can.c
@@ -352,15 +352,6 @@ static void c_can_setup_tx_object(struct net_device *dev, 
int iface,
        }
 }
 
-static inline void c_can_activate_all_lower_rx_msg_obj(struct net_device *dev,
-                                                      int iface)
-{
-       int i;
-
-       for (i = C_CAN_MSG_OBJ_RX_FIRST; i <= C_CAN_MSG_RX_LOW_LAST; i++)
-               c_can_object_get(dev, iface, i, IF_COMM_CLR_NEWDAT);
-}
-
 static int c_can_handle_lost_msg_obj(struct net_device *dev,
                                     int iface, int objno, u32 ctrl)
 {
@@ -706,7 +697,16 @@ static void c_can_do_tx(struct net_device *dev)
        struct net_device_stats *stats = &dev->stats;
        u32 idx, obj, pkts = 0, bytes = 0, pend, clr;
 
-       clr = pend = priv->read_reg(priv, C_CAN_INTPND2_REG);
+#ifdef CONFIG_CAN_C_CAN_DCAN_64_MSG_OBJECTS
+       if (priv->type == BOSCH_D_CAN) {
+               pend = priv->read_reg32(priv, C_CAN_INTPND3_REG);
+       } else {
+#endif
+               pend = priv->read_reg(priv, C_CAN_INTPND2_REG);
+#ifdef CONFIG_CAN_C_CAN_DCAN_64_MSG_OBJECTS
+       }
+#endif
+       clr = pend;
 
        while ((idx = ffs(pend))) {
                idx--;
@@ -817,7 +817,17 @@ static int c_can_read_objects(struct net_device *dev, 
struct c_can_priv *priv,
 
 static inline u32 c_can_get_pending(struct c_can_priv *priv)
 {
-       u32 pend = priv->read_reg(priv, C_CAN_NEWDAT1_REG);
+       u32 pend;
+
+#ifdef CONFIG_CAN_C_CAN_DCAN_64_MSG_OBJECTS
+       if (priv->type == BOSCH_D_CAN) {
+               pend = priv->read_reg32(priv, C_CAN_NEWDAT1_REG);
+       } else {
+#endif
+               pend = priv->read_reg(priv, C_CAN_NEWDAT1_REG);
+#ifdef CONFIG_CAN_C_CAN_DCAN_64_MSG_OBJECTS
+       }
+#endif
 
        return pend;
 }
@@ -828,8 +838,7 @@ static inline u32 c_can_get_pending(struct c_can_priv *priv)
  * c_can core saves a received CAN message into the first free message
  * object it finds free (starting with the lowest). Bits NEWDAT and
  * INTPND are set for this message object indicating that a new message
- * has arrived. To work-around this issue, we keep two groups of message
- * objects whose partitioning is defined by C_CAN_MSG_OBJ_RX_SPLIT.
+ * has arrived.
  *
  * We clear the newdat bit right away.
  *
@@ -840,13 +849,6 @@ static int c_can_do_rx_poll(struct net_device *dev, int 
quota)
        struct c_can_priv *priv = netdev_priv(dev);
        u32 pkts = 0, pend = 0, toread, n;
 
-       /*
-        * It is faster to read only one 16bit register. This is only possible
-        * for a maximum number of 16 objects.
-        */
-       BUILD_BUG_ON_MSG(C_CAN_MSG_OBJ_RX_LAST > 16,
-                       "Implementation does not support more message objects 
than 16");
-
        while (quota > 0) {
                if (!pend) {
                        pend = c_can_get_pending(priv);
diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h
index 8acdc7fa4792..e44b686a70a2 100644
--- a/drivers/net/can/c_can/c_can.h
+++ b/drivers/net/can/c_can/c_can.h
@@ -23,9 +23,15 @@
 #define C_CAN_H
 
 /* message object split */
+
+#ifdef CONFIG_CAN_C_CAN_DCAN_64_MSG_OBJECTS
+#define C_CAN_NO_OF_OBJECTS    64
+#else
 #define C_CAN_NO_OF_OBJECTS    32
-#define C_CAN_MSG_OBJ_RX_NUM   16
-#define C_CAN_MSG_OBJ_TX_NUM   16
+#endif
+
+#define C_CAN_MSG_OBJ_TX_NUM   (C_CAN_NO_OF_OBJECTS >> 1)
+#define C_CAN_MSG_OBJ_RX_NUM   (C_CAN_NO_OF_OBJECTS - C_CAN_MSG_OBJ_TX_NUM)
 
 #define C_CAN_MSG_OBJ_RX_FIRST 1
 #define C_CAN_MSG_OBJ_RX_LAST  (C_CAN_MSG_OBJ_RX_FIRST + \
@@ -35,9 +41,11 @@
 #define C_CAN_MSG_OBJ_TX_LAST  (C_CAN_MSG_OBJ_TX_FIRST + \
                                C_CAN_MSG_OBJ_TX_NUM - 1)
 
-#define C_CAN_MSG_OBJ_RX_SPLIT 9
-#define C_CAN_MSG_RX_LOW_LAST  (C_CAN_MSG_OBJ_RX_SPLIT - 1)
+#ifdef CONFIG_CAN_C_CAN_DCAN_64_MSG_OBJECTS
+#define RECEIVE_OBJECT_BITS    0xffffffff
+#else
 #define RECEIVE_OBJECT_BITS    0x0000ffff
+#endif
 
 enum reg {
        C_CAN_CTRL_REG = 0,
@@ -76,6 +84,8 @@ enum reg {
        C_CAN_NEWDAT2_REG,
        C_CAN_INTPND1_REG,
        C_CAN_INTPND2_REG,
+       C_CAN_INTPND3_REG,
+       C_CAN_INTPND4_REG,
        C_CAN_MSGVAL1_REG,
        C_CAN_MSGVAL2_REG,
        C_CAN_FUNCTION_REG,
@@ -137,6 +147,8 @@ static const u16 reg_map_d_can[] = {
        [C_CAN_NEWDAT2_REG]     = 0x9E,
        [C_CAN_INTPND1_REG]     = 0xB0,
        [C_CAN_INTPND2_REG]     = 0xB2,
+       [C_CAN_INTPND3_REG]     = 0xB4,
+       [C_CAN_INTPND4_REG]     = 0xB6,
        [C_CAN_MSGVAL1_REG]     = 0xC4,
        [C_CAN_MSGVAL2_REG]     = 0xC6,
        [C_CAN_IF1_COMREQ_REG]  = 0x100,
-- 
2.11.0

Reply via email to