Re: [PATCH 09/11] can: c_can: support 64 message objects for D_CAN

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 12/17/19 2:53 PM, Kurt Van Dijck wrote:
> From: Andrejs Cainikovs <Andrejs.Cainikovs@xxxxxxxxxxxxx>
> 
> 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.cainikovs@xxxxxxxxxxxxx>
> Signed-off-by: Marc Kleine-Budde <mkl@xxxxxxxxxxxxxx>
> Signed-off-by: Kurt Van Dijck <dev.kurt@xxxxxxxxxxxxxxxxxxxxxx>
> ---
>  drivers/net/can/c_can/Kconfig |  1 +
>  drivers/net/can/c_can/c_can.c | 34 ++++++++++++++--------------------
>  drivers/net/can/c_can/c_can.h | 20 ++++++++++++++++----
>  3 files changed, 31 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/net/can/c_can/Kconfig b/drivers/net/can/c_can/Kconfig
> index b0f206d3..9cd8523 100644
> --- a/drivers/net/can/c_can/Kconfig
> +++ b/drivers/net/can/c_can/Kconfig
> @@ -21,4 +21,5 @@ config CAN_C_CAN_PCI
>  	---help---
>  	  This driver adds support for the C_CAN/D_CAN chips connected
>  	  to the PCI bus.
> +
>  endif
> diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c
> index cf2d47e..848cc77 100644
> --- a/drivers/net/can/c_can/c_can.c
> +++ b/drivers/net/can/c_can/c_can.c
> @@ -357,15 +357,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)
>  {
> @@ -737,7 +728,12 @@ static void c_can_do_tx(struct net_device *dev)
>  	struct sk_buff *skb;
>  	u8 len;
>  
> -	clr = pend = priv->read_reg(priv, C_CAN_INTPND2_REG);
> +	if (priv->type == BOSCH_D_CAN) {
> +		pend = priv->read_reg32(priv, C_CAN_INTPND3_REG);
> +	} else {
> +		pend = priv->read_reg(priv, C_CAN_INTPND2_REG);
> +	}
> +	clr = pend;
>  
>  	while ((idx = ffs(pend))) {
>  		idx--;
> @@ -847,7 +843,13 @@ 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;
> +
> +	if (priv->type == BOSCH_D_CAN) {
> +		pend = priv->read_reg32(priv, C_CAN_NEWDAT1_REG);
> +	} else {
> +		pend = priv->read_reg(priv, C_CAN_NEWDAT1_REG);
> +	}
>  
>  	return pend;
>  }
> @@ -858,8 +860,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.
>   *
> @@ -870,13 +871,6 @@ static int c_can_do_rx_poll(struct net_device *dev)
>  	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");
> -
>  	for (;;) {
>  		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 8387b3f..24128e7 100644
> --- a/drivers/net/can/c_can/c_can.h
> +++ b/drivers/net/can/c_can/c_can.h
> @@ -25,9 +25,15 @@
>  #include <linux/can/rx-offload.h>
>  
>  /* message object split */
> +
> +#ifdef CONFIG_CAN_C_CAN_DCAN_64_MSG_OBJECTS

There's an ifdef left.

> +#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 + \
> @@ -37,9 +43,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,
> @@ -78,6 +86,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,
> @@ -139,6 +149,8 @@ enum reg {
>  	[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,
> 

Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde           |
Embedded Linux                   | https://www.pengutronix.de  |
Vertretung West/Dortmund         | Phone: +49-231-2826-924     |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-5555 |

Attachment: signature.asc
Description: OpenPGP digital signature


[Index of Archives]     [Automotive Discussions]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]     [CAN Bus]

  Powered by Linux