linux-can.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Re: [PATCH 00/16] Support for Eberspächer Flexcard DCAN function
       [not found] <1378711513-2548-1-git-send-email-b.spranger@linutronix.de>
@ 2013-09-09  7:54 ` Marc Kleine-Budde
       [not found] ` <1378711513-2548-2-git-send-email-b.spranger@linutronix.de>
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 17+ messages in thread
From: Marc Kleine-Budde @ 2013-09-09  7:54 UTC (permalink / raw)
  To: Benedikt Spranger
  Cc: netdev, Alexander Frank, Sebastian Andrzej Siewior,
	Holger Dengler, linux-can@vger.kernel.org

[-- Attachment #1: Type: text/plain, Size: 737 bytes --]

Hey Bene,

On 09/09/2013 09:24 AM, Benedikt Spranger wrote:
> The Eberspächer Flexcard is a multifunctional PCI Mezzanine Card. This
> patch-series adds support for the DCAN function. The Flexcard supports
> up too 8 CAN devices and has some CAN related special features:
> - own FIFO per device
> - DMA for receiving CAN frames
> - Firmware tracks CAN echo packets

Please include linux-can@vger.kernel.org when posting CAN related patches.

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


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 01/16] c_can_platform: add FlexCard D-CAN support
       [not found] ` <1378711513-2548-2-git-send-email-b.spranger@linutronix.de>
@ 2013-09-09  8:22   ` Marc Kleine-Budde
  0 siblings, 0 replies; 17+ messages in thread
From: Marc Kleine-Budde @ 2013-09-09  8:22 UTC (permalink / raw)
  To: Benedikt Spranger
  Cc: netdev, Alexander Frank, Sebastian Andrzej Siewior,
	Holger Dengler

[-- Attachment #1: Type: text/plain, Size: 8463 bytes --]

On 09/09/2013 09:24 AM, Benedikt Spranger wrote:
> FlexCard supports up to 8 D-CAN devices with a shared DMA-capable receive
> function. Add support for FlexCard D-CAN.
> 
> Signed-off-by: Benedikt Spranger <b.spranger@linutronix.de>

What are the prerequisites for this series? This doesn't compile against
current net-next/master (e7d33bb lockref: add ability to mark lockrefs
"dead").

More Comments inline.
Marc

> ---
>  drivers/net/can/c_can/c_can.h          |   1 +
>  drivers/net/can/c_can/c_can_platform.c | 149 ++++++++++++++++++++++++++++++++-
>  2 files changed, 148 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h
> index d2e1c21..d2e2d20 100644
> --- a/drivers/net/can/c_can/c_can.h
> +++ b/drivers/net/can/c_can/c_can.h
> @@ -148,6 +148,7 @@ enum c_can_dev_id {
>  	BOSCH_C_CAN_PLATFORM,
>  	BOSCH_C_CAN,
>  	BOSCH_D_CAN,
> +	BOSCH_D_CAN_FLEXCARD,
>  };
>  
>  /* c_can private data structure */
> diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c
> index c6f838d..43a3e3f 100644
> --- a/drivers/net/can/c_can/c_can_platform.c
> +++ b/drivers/net/can/c_can/c_can_platform.c
> @@ -32,6 +32,7 @@
>  #include <linux/clk.h>
>  #include <linux/of.h>
>  #include <linux/of_device.h>
> +#include <linux/flexcard.h>
>  
>  #include <linux/can/dev.h>
>  
> @@ -81,6 +82,112 @@ static void c_can_hw_raminit(const struct c_can_priv *priv, bool enable)
>  	writel(val, priv->raminit_ctrlreg);
>  }
>  
> +static int c_can_rx_pkt(void *p, void *data, size_t len)
> +{

Why are the first two arguments a void *, why do we have len, that's
never used? Has the length already been checked, is it guaranteed >=
sizeof(struct fc_packet_buf)?

> +	struct net_device *dev = p;
> +	struct net_device_stats *stats = &dev->stats;
> +	struct fc_packet_buf *pb = data;
> +	union fc_packet_types *pt = &pb->packet;
> +	struct can_frame *frame;
> +	struct sk_buff *skb;
> +	u32 flags, id, state, type;
> +
> +	switch (le32_to_cpu(pb->header.type)) {
> +	case fc_packet_type_can:
> +		skb = alloc_can_skb(dev, &frame);
> +		if (!skb) {
> +			stats->rx_dropped++;
> +			return -ENOMEM;
> +		}
> +
> +		id = le32_to_cpu(pt->can_packet.id);
> +		flags = le32_to_cpu(pt->can_packet.flags);
> +
> +		if (id & BIT(29))
> +			frame->can_id = (id & CAN_EFF_MASK) | CAN_EFF_FLAG;
> +		else
> +			frame->can_id = id & CAN_SFF_MASK;
> +
> +		if (flags & BIT(13))
> +			frame->can_id |= CAN_RTR_FLAG;
> +		frame->can_dlc = (flags >> 8) & 0xf;

please use get_can_dlc((flags >> 8) & 0xf)

> +		memcpy(frame->data, pt->can_packet.data, frame->can_dlc);

Please don't copy data if you receive an RTR frame. What about the
endianess of the data?

> +		netif_receive_skb(skb);
> +
> +		stats->rx_packets++;
> +		stats->rx_bytes += frame->can_dlc;
> +		break;
> +
> +	case fc_packet_type_can_error:
> +		stats->rx_errors++;
> +
> +		skb = alloc_can_err_skb(dev, &frame);
> +		if (!skb)
> +			return -ENOMEM;
> +
> +		type = le32_to_cpu(pt->can_error_packet.type);
> +		state = le32_to_cpu(pt->can_error_packet.state);
> +
> +		switch (state) {
> +		case fc_can_state_warning:
> +			frame->data[1] |= CAN_ERR_CRTL_RX_WARNING;
> +			frame->data[1] |= CAN_ERR_CRTL_TX_WARNING;
> +			frame->can_id |= CAN_ERR_CRTL;
> +			break;
> +		case fc_can_state_error_passive:
> +			frame->data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
> +			frame->data[1] |= CAN_ERR_CRTL_TX_PASSIVE;
> +			frame->can_id |= CAN_ERR_CRTL;
> +			break;
> +		case fc_can_state_bus_off:
> +			frame->can_id |= CAN_ERR_BUSOFF;
> +			break;
> +		}
> +
> +		switch (type) {
> +		case fc_can_error_stuff:
> +			frame->data[2] |= CAN_ERR_PROT_STUFF;
> +			frame->can_id |= CAN_ERR_PROT;
> +			break;
> +		case fc_can_error_form:
> +			frame->data[2] |= CAN_ERR_PROT_FORM;
> +			frame->can_id |= CAN_ERR_PROT;
> +			break;
> +		case fc_can_error_acknowledge:
> +			frame->can_id |= CAN_ERR_ACK;
> +			break;
> +		case fc_can_error_bit1:
> +			frame->data[2] |= CAN_ERR_PROT_BIT1;
> +			frame->can_id |= CAN_ERR_PROT;
> +			break;
> +		case fc_can_error_bit0:
> +			frame->data[2] |= CAN_ERR_PROT_BIT0;
> +			frame->can_id |= CAN_ERR_PROT;
> +			break;
> +		case fc_can_error_crc:
> +			frame->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ;
> +			frame->can_id |= CAN_ERR_PROT;
> +			break;
> +		case fc_can_error_parity:
> +			frame->data[1] |= CAN_ERR_PROT_UNSPEC;
> +			frame->can_id |= CAN_ERR_CRTL;
> +			break;
> +		}
> +		frame->data[5] = pt->can_error_packet.rx_error_counter;
> +		frame->data[6] = pt->can_error_packet.tx_error_counter;
> +
> +		stats->rx_bytes += frame->can_dlc;
> +		stats->rx_packets++;
> +
> +		netif_receive_skb(skb);
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
>  static struct platform_device_id c_can_id_table[] = {
>  	[BOSCH_C_CAN_PLATFORM] = {
>  		.name = KBUILD_MODNAME,
> @@ -93,6 +200,10 @@ static struct platform_device_id c_can_id_table[] = {
>  	[BOSCH_D_CAN] = {
>  		.name = "d_can",
>  		.driver_data = BOSCH_D_CAN,
> +	},
> +	[BOSCH_D_CAN_FLEXCARD] = {
> +		.name = "flexcard-d_can",
> +		.driver_data = BOSCH_D_CAN_FLEXCARD,
>  	}, {
>  	}
>  };
> @@ -108,7 +219,7 @@ MODULE_DEVICE_TABLE(of, c_can_of_table);
>  static int c_can_plat_probe(struct platform_device *pdev)
>  {
>  	int ret;
> -	void __iomem *addr;
> +	void __iomem *addr, *reset_reg;
>  	struct net_device *dev;
>  	struct c_can_priv *priv;
>  	const struct of_device_id *match;
> @@ -167,6 +278,8 @@ static int c_can_plat_probe(struct platform_device *pdev)
>  	}
>  
>  	priv = netdev_priv(dev);
> +	priv->can.clock.freq = clk_get_rate(clk);
> +
>  	switch (id->driver_data) {
>  	case BOSCH_C_CAN:
>  		priv->regs = reg_map_c_can;
> @@ -199,7 +312,26 @@ static int c_can_plat_probe(struct platform_device *pdev)
>  			dev_info(&pdev->dev, "control memory is not used for raminit\n");
>  		else
>  			priv->raminit = c_can_hw_raminit;
> +

Please remove

>  		break;
> +	case BOSCH_D_CAN_FLEXCARD:
> +		priv->regs = reg_map_d_can;
> +		priv->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES;
> +		priv->read_reg = c_can_plat_read_reg_aligned_to_16bit;
> +		priv->write_reg = c_can_plat_write_reg_aligned_to_16bit;
> +		priv->instance = pdev->id;
> +
> +		res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> +		reset_reg = ioremap(res->start, resource_size(res));
> +		if (!reset_reg || priv->instance < 0) {

priv->instance in unsinged

> +			dev_info(&pdev->dev, "Can't reset device.\n");
> +		} else {
> +			writel(1 << (4 + priv->instance), addr);
> +			udelay(100);
> +		}
> +		iounmap(reset_reg);
> +		priv->can.clock.freq = 16000000;
> +
>  	default:
>  		ret = -EINVAL;
>  		goto exit_free_device;
> @@ -208,7 +340,6 @@ static int c_can_plat_probe(struct platform_device *pdev)
>  	dev->irq = irq;
>  	priv->base = addr;
>  	priv->device = &pdev->dev;
> -	priv->can.clock.freq = clk_get_rate(clk);
>  	priv->priv = clk;
>  	priv->type = id->driver_data;
>  
> @@ -222,10 +353,22 @@ static int c_can_plat_probe(struct platform_device *pdev)
>  		goto exit_free_device;
>  	}
>  
> +	if (id->driver_data == BOSCH_D_CAN_FLEXCARD) {
> +		ret = fc_register_rx_pkt(FC_CANIF_OFFSET + pdev->id,
> +				dev, c_can_rx_pkt);
> +		if (ret) {
> +			dev_err(&pdev->dev,
> +					"registering RX-CB failed %d\n", ret);
> +			goto exit_unregister_device;
> +		}
> +	}
> +
>  	dev_info(&pdev->dev, "%s device registered (regs=%p, irq=%d)\n",
>  		 KBUILD_MODNAME, priv->base, dev->irq);
>  	return 0;
>  
> +exit_unregister_device:
> +	unregister_c_can_dev(dev);
>  exit_free_device:
>  	free_c_can_dev(dev);
>  exit_iounmap:
> @@ -246,6 +389,8 @@ static int c_can_plat_remove(struct platform_device *pdev)
>  	struct c_can_priv *priv = netdev_priv(dev);
>  	struct resource *mem;
>  
> +	if (priv->type == BOSCH_D_CAN_FLEXCARD)
> +		fc_unregister_rx_pkt(FC_CANIF_OFFSET + priv->instance);
>  	unregister_c_can_dev(dev);
>  
>  	free_c_can_dev(dev);
> 

Marc

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


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 02/16] c_can: add generic D-CAN RAM initialization support
       [not found] ` <1378711513-2548-3-git-send-email-b.spranger@linutronix.de>
@ 2013-09-09  8:34   ` Marc Kleine-Budde
  0 siblings, 0 replies; 17+ messages in thread
From: Marc Kleine-Budde @ 2013-09-09  8:34 UTC (permalink / raw)
  To: Benedikt Spranger
  Cc: netdev, Alexander Frank, Sebastian Andrzej Siewior,
	Holger Dengler, AnilKumar Ch, linux-can@vger.kernel.org

[-- Attachment #1: Type: text/plain, Size: 3760 bytes --]

On 09/09/2013 09:24 AM, Benedikt Spranger wrote:
> D-CAN provides an automatic RAM initialization. The initialization can be
> executed while D-CAN is in the init state.
> 
> It should be checked if this is compatible with TI's d_can implementation
> which does not have or does not use this bit which is here according to the
> d_can specification.

Added AnilKumar Ch to the loop, who contributed the d_can support for
TI. Bene please collect a Tested-by for this patch.

Marc

> Signed-off-by: Benedikt Spranger <b.spranger@linutronix.de>
> ---
>  drivers/net/can/c_can/c_can.c | 38 ++++++++++++++++++++++++++++++++++++--
>  drivers/net/can/c_can/c_can.h |  2 ++
>  2 files changed, 38 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c
> index a668cd4..081620b 100644
> --- a/drivers/net/can/c_can/c_can.c
> +++ b/drivers/net/can/c_can/c_can.c
> @@ -68,6 +68,8 @@
>  #define TEST_SILENT		BIT(3)
>  #define TEST_BASIC		BIT(2)
>  
> +#define FUNC_RAMINIT		BIT(3)
> +
>  /* status register */
>  #define STATUS_PDA		BIT(10)
>  #define STATUS_BOFF		BIT(7)
> @@ -573,6 +575,7 @@ static int c_can_set_bittiming(struct net_device *dev)
>  	u32 ten_bit_brp;
>  	struct c_can_priv *priv = netdev_priv(dev);
>  	const struct can_bittiming *bt = &priv->can.bittiming;
> +	int retry;
>  
>  	/* c_can provides a 6-bit brp and 4-bit brpe fields */
>  	ten_bit_brp = bt->brp - 1;
> @@ -590,11 +593,42 @@ static int c_can_set_bittiming(struct net_device *dev)
>  		"setting BTR=%04x BRPE=%04x\n", reg_btr, reg_brpe);
>  
>  	ctrl_save = priv->read_reg(priv, C_CAN_CTRL_REG);
> -	priv->write_reg(priv, C_CAN_CTRL_REG,
> -			ctrl_save | CONTROL_CCE | CONTROL_INIT);
> +	ctrl_save &= ~CONTROL_INIT;
> +
> +	priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_CCE | CONTROL_INIT);
> +	retry = 1000;
> +	while (!(priv->read_reg(priv, C_CAN_CTRL_REG) & CONTROL_INIT)) {
> +		if (!retry) {
> +			netdev_info(dev, "CCTRL: set CONTROL_INIT failed\n");
> +			return -EIO;
> +		}
> +		udelay(10);
> +		retry--;
> +	}
>  	priv->write_reg(priv, C_CAN_BTR_REG, reg_btr);
>  	priv->write_reg(priv, C_CAN_BRPEXT_REG, reg_brpe);
> +
> +	priv->write_reg(priv, C_CAN_FUNC_REG, FUNC_RAMINIT);
> +	retry = 1000;
> +	while (priv->read_reg(priv, C_CAN_FUNC_REG) & FUNC_RAMINIT) {
> +		if (!retry) {
> +			netdev_info(dev, "CFR: FUNC_RAMINIT failed\n");
> +			return -EIO;
> +		}
> +		udelay(10);
> +		retry--;
> +	}
> +
>  	priv->write_reg(priv, C_CAN_CTRL_REG, ctrl_save);
> +	retry = 1000;
> +	while (priv->read_reg(priv, C_CAN_CTRL_REG) & CONTROL_INIT) {
> +		if (!retry) {
> +			netdev_info(dev, "CCTRL: clear CONTROL_INIT failed\n");
> +			return -EIO;
> +		}
> +		udelay(10);
> +		retry--;
> +	}
>  
>  	return 0;
>  }
> diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h
> index d2e2d20..9f0eda8 100644
> --- a/drivers/net/can/c_can/c_can.h
> +++ b/drivers/net/can/c_can/c_can.h
> @@ -61,6 +61,7 @@ enum reg {
>  	C_CAN_INTPND2_REG,
>  	C_CAN_MSGVAL1_REG,
>  	C_CAN_MSGVAL2_REG,
> +	C_CAN_FUNC_REG,
>  };
>  
>  static const u16 reg_map_c_can[] = {
> @@ -112,6 +113,7 @@ static const u16 reg_map_d_can[] = {
>  	[C_CAN_BRPEXT_REG]	= 0x0E,
>  	[C_CAN_INT_REG]		= 0x10,
>  	[C_CAN_TEST_REG]	= 0x14,
> +	[C_CAN_FUNC_REG]	= 0x18,
>  	[C_CAN_TXRQST1_REG]	= 0x88,
>  	[C_CAN_TXRQST2_REG]	= 0x8A,
>  	[C_CAN_NEWDAT1_REG]	= 0x9C,
> 


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


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 03/16] c_can: simplify arbitration register handling
       [not found] ` <1378711513-2548-4-git-send-email-b.spranger@linutronix.de>
@ 2013-09-09  9:16   ` Marc Kleine-Budde
  0 siblings, 0 replies; 17+ messages in thread
From: Marc Kleine-Budde @ 2013-09-09  9:16 UTC (permalink / raw)
  To: Benedikt Spranger
  Cc: netdev, Alexander Frank, Sebastian Andrzej Siewior,
	Holger Dengler

[-- Attachment #1: Type: text/plain, Size: 4042 bytes --]

On 09/09/2013 09:25 AM, Benedikt Spranger wrote:
> The IF1/2 Arbitration register of the C_CAN/D_CAN ip core is internaly
> a 32bit register. Do not use two different 16bit variables to handle
> the IF1/2 Arbitration register.
> 
> Signed-off-by: Benedikt Spranger <b.spranger@linutronix.de>

Looks good, nitpit inline.

Marc
> ---
>  drivers/net/can/c_can/c_can.c | 27 ++++++++++++++-------------
>  1 file changed, 14 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c
> index 081620b..bdb7bcd 100644
> --- a/drivers/net/can/c_can/c_can.c
> +++ b/drivers/net/can/c_can/c_can.c
> @@ -117,9 +117,9 @@
>  				IF_COMM_DATAA | IF_COMM_DATAB)
>  
>  /* IFx arbitration */
> -#define IF_ARB_MSGVAL		BIT(15)
> -#define IF_ARB_MSGXTD		BIT(14)
> -#define IF_ARB_TRANSMIT		BIT(13)
> +#define IF_ARB_MSGVAL		BIT(31)
> +#define IF_ARB_MSGXTD		BIT(30)
> +#define IF_ARB_TRANSMIT		BIT(29)
>  
>  /* IFx message control */
>  #define IF_MCONT_NEWDAT		BIT(15)
> @@ -133,6 +133,7 @@
>  #define IF_MCONT_TXRQST		BIT(8)
>  #define IF_MCONT_EOB		BIT(7)
>  #define IF_MCONT_DLC_MASK	0xf
> +#define IF_MCONT_DLC_MAX	8

It's not used, is it?

>  
>  /*
>   * IFx register masks:
> @@ -336,7 +337,7 @@ static void c_can_write_msg_object(struct net_device *dev,
>  			int iface, struct can_frame *frame, int objno)
>  {
>  	int i;
> -	u16 flags = 0;
> +	u32 flags = IF_ARB_MSGVAL;
>  	unsigned int id;
>  	struct c_can_priv *priv = netdev_priv(dev);
>  
> @@ -349,11 +350,11 @@ static void c_can_write_msg_object(struct net_device *dev,
>  	} else
>  		id = ((frame->can_id & CAN_SFF_MASK) << 18);
>  
> -	flags |= IF_ARB_MSGVAL;
> +	id |= flags;
>  
>  	priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface),
>  				IFX_WRITE_LOW_16BIT(id));
> -	priv->write_reg(priv, C_CAN_IFACE(ARB2_REG, iface), flags |
> +	priv->write_reg(priv, C_CAN_IFACE(ARB2_REG, iface),
>  				IFX_WRITE_HIGH_16BIT(id));
>  
>  	for (i = 0; i < frame->can_dlc; i += 2) {
> @@ -439,7 +440,7 @@ static void c_can_handle_lost_msg_obj(struct net_device *dev,
>  
>  static int c_can_read_msg_object(struct net_device *dev, int iface, int ctrl)
>  {
> -	u16 flags, data;
> +	u16 data;
>  	int i;
>  	unsigned int val;
>  	struct c_can_priv *priv = netdev_priv(dev);
> @@ -455,16 +456,15 @@ static int c_can_read_msg_object(struct net_device *dev, int iface, int ctrl)
>  
>  	frame->can_dlc = get_can_dlc(ctrl & 0x0F);
>  
> -	flags =	priv->read_reg(priv, C_CAN_IFACE(ARB2_REG, iface));
> -	val = priv->read_reg(priv, C_CAN_IFACE(ARB1_REG, iface)) |
> -		(flags << 16);
> +	val = (priv->read_reg(priv, C_CAN_IFACE(ARB2_REG, iface)) << 16);
> +	val |= priv->read_reg(priv, C_CAN_IFACE(ARB1_REG, iface));
>  
> -	if (flags & IF_ARB_MSGXTD)
> +	if (val & IF_ARB_MSGXTD)
>  		frame->can_id = (val & CAN_EFF_MASK) | CAN_EFF_FLAG;
>  	else
>  		frame->can_id = (val >> 18) & CAN_SFF_MASK;
>  
> -	if (flags & IF_ARB_TRANSMIT)
> +	if (val & IF_ARB_TRANSMIT)
>  		frame->can_id |= CAN_RTR_FLAG;
>  	else {
>  		for (i = 0; i < frame->can_dlc; i += 2) {
> @@ -500,10 +500,11 @@ static void c_can_setup_receive_object(struct net_device *dev, int iface,
>  	priv->write_reg(priv, C_CAN_IFACE(MASK2_REG, iface),
>  			IFX_WRITE_HIGH_16BIT(mask) | BIT(13));
>  
> +	id |= IF_ARB_MSGVAL;
>  	priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface),
>  			IFX_WRITE_LOW_16BIT(id));
>  	priv->write_reg(priv, C_CAN_IFACE(ARB2_REG, iface),
> -			(IF_ARB_MSGVAL | IFX_WRITE_HIGH_16BIT(id)));
> +			(IFX_WRITE_HIGH_16BIT(id)));
>  
>  	priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), mcont);
>  	c_can_object_put(dev, iface, objno, IF_COMM_ALL & ~IF_COMM_TXRQST);
> 


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


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 05/16] c_can: use 32 bit access for D_CAN
       [not found] ` <1378711513-2548-6-git-send-email-b.spranger@linutronix.de>
@ 2013-09-09  9:37   ` Marc Kleine-Budde
  0 siblings, 0 replies; 17+ messages in thread
From: Marc Kleine-Budde @ 2013-09-09  9:37 UTC (permalink / raw)
  To: Benedikt Spranger
  Cc: netdev, Alexander Frank, Sebastian Andrzej Siewior,
	Holger Dengler, linux-can@vger.kernel.org

[-- Attachment #1: Type: text/plain, Size: 5047 bytes --]

On 09/09/2013 09:25 AM, Benedikt Spranger wrote:
> Other than the C_CAN 16 bit memory interface the D_CAN uses a 32bit memory
> interface. This causes some trouble while accessing the IFxCMR register in
> two 16bit chunks. Use 32bit access on D_CAN.
> 
> Signed-off-by: Benedikt Spranger <b.spranger@linutronix.de>
> ---
>  drivers/net/can/c_can/c_can.c | 56 +++++++++++++++++++++++++++----------------
>  1 file changed, 35 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c
> index 886163f..b3cfb85 100644
> --- a/drivers/net/can/c_can/c_can.c
> +++ b/drivers/net/can/c_can/c_can.c
> @@ -262,11 +262,32 @@ static inline int get_tx_echo_msg_obj(const struct c_can_priv *priv)
>  
>  static u32 c_can_read_reg32(struct c_can_priv *priv, enum reg index)

What about introducing priv->{read,write}_reg32 function pointers?

>  {
> -	u32 val = priv->read_reg(priv, index);
> -	val |= ((u32) priv->read_reg(priv, index + 1)) << 16;
> +	u32 val;
> +
> +	if (priv->type == BOSCH_D_CAN || priv->type == BOSCH_D_CAN_FLEXCARD) {
> +		val = readl(priv->base + priv->regs[index]);
> +	} else {
> +		val = priv->read_reg(priv, index);
> +		val |= ((u32) priv->read_reg(priv, index + 1)) << 16;
> +	}
>  	return val;
>  }
>  
> +static void c_can_writereg32(struct c_can_priv *priv, enum reg index,
> +		u16 high, u16 low)
> +{

If we decide not to introduce read/write 32 bit function pointers,
please rename your function to c_can_write_reg32() to match the pattern
of the read_reg32() function.

As you have converted some of the potential users of write_reg32() to
work with a single 32 bit value instead of two 16 bits, I think it's
better to call this function with a single 32 bite value.

> +	u32 val;
> +
> +	if (priv->type == BOSCH_D_CAN || priv->type == BOSCH_D_CAN_FLEXCARD) {
> +		val = high << 16;
> +		val |= low;
> +		writel(val, priv->base + priv->regs[index]);
> +	} else {
> +		priv->write_reg(priv, index + 1, high);
> +		priv->write_reg(priv, index, low);
> +	}
> +}
> +
>  static void c_can_enable_all_interrupts(struct c_can_priv *priv,
>  						int enable)
>  {
> @@ -309,10 +330,8 @@ static inline void c_can_object_get(struct net_device *dev,
>  	 * register and message RAM must be complete in 6 CAN-CLK
>  	 * period.
>  	 */
> -	priv->write_reg(priv, C_CAN_IFACE(COMMSK_REG, iface),
> -			IFX_WRITE_LOW_16BIT(mask));
> -	priv->write_reg(priv, C_CAN_IFACE(COMREQ_REG, iface),
> -			IFX_WRITE_LOW_16BIT(objno));
> +	c_can_writereg32(priv, C_CAN_IFACE(COMREQ_REG, iface),
> +			IFX_WRITE_LOW_16BIT(mask), IFX_WRITE_LOW_16BIT(objno));
>  
>  	if (c_can_msg_obj_is_busy(priv, iface))
>  		netdev_err(dev, "timed out in object get\n");
> @@ -329,9 +348,8 @@ static inline void c_can_object_put(struct net_device *dev,
>  	 * register and message RAM must be complete in 6 CAN-CLK
>  	 * period.
>  	 */
> -	priv->write_reg(priv, C_CAN_IFACE(COMMSK_REG, iface),
> -			(IF_COMM_WR | IFX_WRITE_LOW_16BIT(mask)));
> -	priv->write_reg(priv, C_CAN_IFACE(COMREQ_REG, iface),
> +	c_can_writereg32(priv, C_CAN_IFACE(COMREQ_REG, iface),
> +			IF_COMM_WR | IFX_WRITE_LOW_16BIT(mask),
>  			IFX_WRITE_LOW_16BIT(objno));
>  
>  	if (c_can_msg_obj_is_busy(priv, iface))
> @@ -496,23 +514,19 @@ static void c_can_setup_receive_object(struct net_device *dev, int iface,
>  {
>  	struct c_can_priv *priv = netdev_priv(dev);
>  
> -	priv->write_reg(priv, C_CAN_IFACE(MASK1_REG, iface),
> -			IFX_WRITE_LOW_16BIT(mask));
> -
>  	/* According to C_CAN documentation, the reserved bit
>  	 * in IFx_MASK2 register is fixed 1
>  	 */
> -	priv->write_reg(priv, C_CAN_IFACE(MASK2_REG, iface),
> -			IFX_WRITE_HIGH_16BIT(mask) | BIT(13));
> -
> +	c_can_writereg32(priv, C_CAN_IFACE(MASK1_REG, iface),
> +			IFX_WRITE_HIGH_16BIT(mask) | BIT(13),
> +			IFX_WRITE_LOW_16BIT(mask));
>  	id |= IF_ARB_MSGVAL;
> -	priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface),
> -			IFX_WRITE_LOW_16BIT(id));
> -	priv->write_reg(priv, C_CAN_IFACE(ARB2_REG, iface),
> -			(IFX_WRITE_HIGH_16BIT(id)));
> +	c_can_writereg32(priv, C_CAN_IFACE(ARB1_REG, iface),
> +			IFX_WRITE_HIGH_16BIT(id), IFX_WRITE_LOW_16BIT(id));
> +	c_can_writereg32(priv, C_CAN_IFACE(MSGCTRL_REG, iface), 0, mcont);
>  
> -	priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), mcont);
> -	c_can_object_put(dev, iface, objno, IF_COMM_ALL & ~IF_COMM_TXRQST);
> +	c_can_object_put(dev, iface, objno, IF_COMM_WR | IF_COMM_MASK |
> +			 IF_COMM_ARB | IF_COMM_CONTROL | IF_COMM_CLR_INT_PND);

I think the last change is unrelated.

>  
>  	netdev_dbg(dev, "obj no:%d, msgval:0x%08x\n", objno,
>  			c_can_read_reg32(priv, C_CAN_MSGVAL1_REG));
> 

Marc

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


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 06/16] c_can: consider set bittiming may fail
       [not found] ` <1378711513-2548-7-git-send-email-b.spranger@linutronix.de>
@ 2013-09-09  9:39   ` Marc Kleine-Budde
  0 siblings, 0 replies; 17+ messages in thread
From: Marc Kleine-Budde @ 2013-09-09  9:39 UTC (permalink / raw)
  To: Benedikt Spranger
  Cc: netdev, Alexander Frank, Sebastian Andrzej Siewior,
	Holger Dengler

[-- Attachment #1: Type: text/plain, Size: 2682 bytes --]

On 09/09/2013 09:25 AM, Benedikt Spranger wrote:
> While setting the bittiming the C_CAN/D_CAN may fail. Do not bring up the
> CAN interface in this case.
> 
> Signed-off-by: Benedikt Spranger <b.spranger@linutronix.de>
> ---
>  drivers/net/can/c_can/c_can.c | 25 ++++++++++++++++++++-----
>  1 file changed, 20 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c
> index b3cfb85..3fa5347 100644
> --- a/drivers/net/can/c_can/c_can.c
> +++ b/drivers/net/can/c_can/c_can.c
> @@ -689,9 +689,10 @@ static void c_can_configure_msg_objects(struct net_device *dev)
>   * - set operating mode
>   * - configure message objects
>   */
> -static void c_can_chip_config(struct net_device *dev)
> +static int c_can_chip_config(struct net_device *dev)
>  {
>  	struct c_can_priv *priv = netdev_priv(dev);
> +	int ret;
>  
>  	/* enable automatic retransmission */
>  	priv->write_reg(priv, C_CAN_CTRL_REG,
> @@ -726,15 +727,20 @@ static void c_can_chip_config(struct net_device *dev)
>  	priv->write_reg(priv, C_CAN_STS_REG, LEC_UNUSED);
>  
>  	/* set bittiming params */
> -	c_can_set_bittiming(dev);
> +	ret = c_can_set_bittiming(dev);
> +
> +	return ret;

Maybe just:
	return c_can_set_bittiming(dev);
>  }
>  
> -static void c_can_start(struct net_device *dev)
> +static int c_can_start(struct net_device *dev)
>  {
>  	struct c_can_priv *priv = netdev_priv(dev);
> +	int ret;
>  
>  	/* basic c_can configuration */
> -	c_can_chip_config(dev);
> +	ret = c_can_chip_config(dev);
> +	if (ret)
> +		goto out;

No need for a goto here, IMHO.

>  
>  	priv->can.state = CAN_STATE_ERROR_ACTIVE;
>  
> @@ -743,6 +749,9 @@ static void c_can_start(struct net_device *dev)
>  
>  	/* enable status change, error and module interrupts */
>  	c_can_enable_all_interrupts(priv, ENABLE_ALL_INTERRUPTS);
> +
> +out:
> +	return ret;
>  }
>  
>  static void c_can_stop(struct net_device *dev)
> @@ -758,9 +767,15 @@ static void c_can_stop(struct net_device *dev)
>  
>  static int c_can_set_mode(struct net_device *dev, enum can_mode mode)
>  {
> +	int ret;
> +
>  	switch (mode) {
>  	case CAN_MODE_START:
> -		c_can_start(dev);
> +		ret = c_can_start(dev);
> +		if (ret) {
> +			c_can_stop(dev);
> +			return ret;
> +		}
>  		netif_wake_queue(dev);
>  		break;
>  	default:
> 

Marc

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


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 08/16] c_can: Add FlexCard CAN TX fifo support
       [not found] ` <1378711513-2548-9-git-send-email-b.spranger@linutronix.de>
@ 2013-09-09  9:47   ` Marc Kleine-Budde
  0 siblings, 0 replies; 17+ messages in thread
From: Marc Kleine-Budde @ 2013-09-09  9:47 UTC (permalink / raw)
  To: Benedikt Spranger
  Cc: netdev, Alexander Frank, Sebastian Andrzej Siewior,
	Holger Dengler, linux-can@vger.kernel.org

[-- Attachment #1: Type: text/plain, Size: 5416 bytes --]

On 09/09/2013 09:25 AM, Benedikt Spranger wrote:
> The FlexCard DCAN implementation contains a specialized TX fifo function.
> Add the TX support for this function.

This patch looks a bit fishy. Is this compatible with existing
c_can/d_can hardware. It looks like you "use" frame->dlc to transport
some information.

> Signed-off-by: Benedikt Spranger <b.spranger@linutronix.de>
> ---
>  drivers/net/can/c_can/c_can.c | 77 ++++++++++++++++++++++++++++++++++++-------
>  1 file changed, 65 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c
> index 39e2bb0..4b94f2d 100644
> --- a/drivers/net/can/c_can/c_can.c
> +++ b/drivers/net/can/c_can/c_can.c
> @@ -41,6 +41,7 @@
>  #include <linux/can/error.h>
>  #include <linux/can/led.h>
>  
> +#include <linux/flexcard.h>
>  #include "c_can.h"
>  
>  /* Number of interface registers */
> @@ -566,24 +567,60 @@ static netdev_tx_t c_can_start_xmit(struct sk_buff *skb,
>  	u32 msg_obj_no;
>  	struct c_can_priv *priv = netdev_priv(dev);
>  	struct can_frame *frame = (struct can_frame *)skb->data;
> +	int tx_fifo;
>  
>  	if (can_dropped_invalid_skb(dev, skb))
>  		return NETDEV_TX_OK;
>  
> -	msg_obj_no = get_tx_next_msg_obj(priv);
> +	tx_fifo = frame->can_dlc & FC_TXFIFO_FLAG;

Can you describe what you have encoded into to frame->can_dlc?

> +	frame->can_dlc &= FC_TXFIFO_DLC_MASK;
>  
> -	/* prepare message object for transmission */
> -	c_can_write_msg_object(dev, 0, frame, msg_obj_no);
> -	can_put_echo_skb(skb, dev, msg_obj_no - C_CAN_MSG_OBJ_TX_FIRST);
> +	if (tx_fifo) {
> +		u32 id, *data, ctrl;
>  
> -	/*
> -	 * we have to stop the queue in case of a wrap around or
> -	 * if the next TX message object is still in use
> -	 */
> -	priv->tx_next++;
> -	if (c_can_is_next_tx_obj_busy(priv, get_tx_next_msg_obj(priv)) ||
> -			(priv->tx_next & C_CAN_NEXT_MSG_OBJ_MASK) == 0)
> -		netif_stop_queue(dev);
> +		if (readl(priv->base + FC_TXFIFO_STAT) &
> +				FC_TXFIFO_STAT_FULL) {
> +			netif_stop_queue(dev);
> +			return NETDEV_TX_BUSY;
> +		}
> +
> +		if (frame->can_id & CAN_EFF_FLAG) {
> +			id = frame->can_id & CAN_EFF_MASK;
> +			id |= FC_TXFIFO_MSGID_EXT;
> +		} else {
> +			id = frame->can_id & CAN_SFF_MASK;
> +			/* StdID is left alligned */
> +			id <<= FC_TXFIFO_MSGID_STDID_SHIFT;
> +		}
> +
> +		writel(id, priv->base + FC_TXFIFO_MSGID);
> +		writel(frame->can_dlc, priv->base + FC_TXFIFO_MSGCTRL);
> +
> +		if (frame->can_dlc) {
> +			data = (u32 *) frame->data;
> +			writel(data[0], priv->base + FC_TXFIFO_MSGDA);
> +			writel(data[1], priv->base + FC_TXFIFO_MSGDB);
> +		}
> +
> +		ctrl = readl(priv->base + FC_TXFIFO_CTRL);
> +		ctrl |= FC_TXFIFO_CTRL_REQ;
> +		writel(ctrl, priv->base + FC_TXFIFO_CTRL);
> +		kfree_skb(skb);
> +	} else {
> +		msg_obj_no = get_tx_next_msg_obj(priv);
> +
> +		/* prepare message object for transmission */
> +		c_can_write_msg_object(dev, 0, frame, msg_obj_no);
> +		priv->tx_next++;
> +
> +		can_put_echo_skb(skb, dev, msg_obj_no - C_CAN_MSG_OBJ_TX_FIRST);
> +		/* we have to stop the queue in case of a wrap around or
> +		 * if the next TX message object is still in use
> +		 */
> +		if (c_can_is_next_tx_obj_busy(priv, get_tx_next_msg_obj(priv))
> +			|| ((priv->tx_next & C_CAN_NEXT_MSG_OBJ_MASK) == 0))
> +			netif_stop_queue(dev);
> +	}
>  
>  	return NETDEV_TX_OK;
>  }
> @@ -683,6 +720,8 @@ static void c_can_configure_msg_objects(struct net_device *dev, int invalidate)
>  				   IF_MASK_MDIR | IF_MASK_RES, 0,
>  				   IF_MCONT_UMASK | IF_MCONT_EOB |
>  				   IF_MCONT_RXIE | IF_MCONT_DLC_MAX);
> +
> +	c_can_inval_msg_object(dev, 0, FC_TXFIFO_MO);
>  }
>  
>  /*
> @@ -740,8 +779,13 @@ static int c_can_chip_config(struct net_device *dev)
>  static int c_can_start(struct net_device *dev)
>  {
>  	struct c_can_priv *priv = netdev_priv(dev);
> +	u32 conf;
>  	int ret;
>  
> +	conf = readl(priv->base + FC_TXFIFO_CONF);
> +	conf |= FC_TXFIFO_CONF_EN;
> +	writel(conf, priv->base + FC_TXFIFO_CONF);
> +
>  	/* basic c_can configuration */
>  	ret = c_can_chip_config(dev);
>  	if (ret)
> @@ -762,6 +806,11 @@ out:
>  static void c_can_stop(struct net_device *dev)
>  {
>  	struct c_can_priv *priv = netdev_priv(dev);
> +	u32 conf;
> +
> +	conf = readl(priv->base + FC_TXFIFO_CONF);
> +	conf &= ~FC_TXFIFO_CONF_EN;
> +	writel(conf, priv->base + FC_TXFIFO_CONF);
>  
>  	/* disable all interrupts */
>  	c_can_enable_all_interrupts(priv, DISABLE_ALL_INTERRUPTS);
> @@ -1350,6 +1399,8 @@ int register_c_can_dev(struct net_device *dev)
>  	struct c_can_priv *priv = netdev_priv(dev);
>  	int err;
>  
> +	writel(0, priv->base + FC_TXFIFO_CONF);
> +
>  	c_can_pm_runtime_enable(priv);
>  
>  	dev->flags |= IFF_ECHO;	/* we support local echo */
> @@ -1369,6 +1420,8 @@ void unregister_c_can_dev(struct net_device *dev)
>  {
>  	struct c_can_priv *priv = netdev_priv(dev);
>  
> +	writel(0, priv->base + FC_TXFIFO_CONF);
> +
>  	unregister_candev(dev);
>  
>  	c_can_pm_runtime_disable(priv);
> 

Marc

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


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 10/16] c_can: add 16bit align 32bit access functions
       [not found] ` <1378711513-2548-11-git-send-email-b.spranger@linutronix.de>
@ 2013-09-09  9:57   ` Marc Kleine-Budde
  0 siblings, 0 replies; 17+ messages in thread
From: Marc Kleine-Budde @ 2013-09-09  9:57 UTC (permalink / raw)
  To: Benedikt Spranger
  Cc: netdev, Alexander Frank, Sebastian Andrzej Siewior,
	Holger Dengler, linux-can@vger.kernel.org

[-- Attachment #1: Type: text/plain, Size: 3941 bytes --]

On 09/09/2013 09:25 AM, Benedikt Spranger wrote:
> The FlexCard only allows 32bit access to DCAN registers, otherwise the
> register value can be wraped up. Add a new helper function to access
> registers 16bit aligned but 32bit access.

You are modifying code you have previously added. You should shuffle
your patches that this is not necessary.

> Signed-off-by: Benedikt Spranger <b.spranger@linutronix.de>
> ---
>  drivers/net/can/c_can/c_can.c          |  1 +
>  drivers/net/can/c_can/c_can.h          |  1 +
>  drivers/net/can/c_can/c_can_platform.c | 38 ++++++++++++++++++++++++++++++++--
>  3 files changed, 38 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c
> index c573399..46d741d 100644
> --- a/drivers/net/can/c_can/c_can.c
> +++ b/drivers/net/can/c_can/c_can.c
> @@ -1305,6 +1305,7 @@ struct net_device *alloc_c_can_dev(void)
>  	priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK |
>  					CAN_CTRLMODE_LISTENONLY |
>  					CAN_CTRLMODE_BERR_REPORTING;
> +	spin_lock_init(&priv->lock);
>  
>  	return dev;
>  }
> diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h
> index 9f0eda8..beea437 100644
> --- a/drivers/net/can/c_can/c_can.h
> +++ b/drivers/net/can/c_can/c_can.h
> @@ -175,6 +175,7 @@ struct c_can_priv {
>  	u32 __iomem *raminit_ctrlreg;
>  	unsigned int instance;
>  	void (*raminit) (const struct c_can_priv *priv, bool enable);
> +	spinlock_t lock;
>  };
>  
>  struct net_device *alloc_c_can_dev(void);
> diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c
> index 43a3e3f..c6c1eb4 100644
> --- a/drivers/net/can/c_can/c_can_platform.c
> +++ b/drivers/net/can/c_can/c_can_platform.c
> @@ -58,6 +58,40 @@ static void c_can_plat_write_reg_aligned_to_16bit(struct c_can_priv *priv,
>  	writew(val, priv->base + priv->regs[index]);
>  }
>  
> +#define ALIGN_DOWN(p, a)	((typeof(p))round_down((unsigned long)(p), (a)))
> +
> +static u16 c_can_plat_read_16bit_align_32bit_access(struct c_can_priv *priv,
> +						    enum reg index)
> +{
> +	void *addr = priv->base + priv->regs[index];

Please compile with C=2. Should be void __iomem *.

> +	u32 reg;
> +	reg = readl(ALIGN_DOWN(addr, 4));
> +
> +	return IS_ALIGNED((unsigned long)addr, 4) ?
> +			reg & 0xffff :
> +			reg >> 16;
> +}
> +
> +static void c_can_plat_write_16bit_align_32bit_access(struct c_can_priv *priv,
> +						      enum reg index, u16 val)
> +{
> +	unsigned long flags;
> +	void *addr = priv->base + priv->regs[index];

dito

> +	u32 reg;
> +
> +	spin_lock_irqsave(&priv->lock, flags);
> +	reg = readl(ALIGN_DOWN(addr, 4));
> +	if (IS_ALIGNED((unsigned long)addr, 4)) {
> +		reg &= 0xffff0000;
> +		reg |= val;
> +	} else {
> +		reg &= 0xffff;
> +		reg |= val << 16;
> +	}
> +	writel(reg, ALIGN_DOWN(addr, 4));
> +	spin_unlock_irqrestore(&priv->lock, flags);
> +}
> +
>  static u16 c_can_plat_read_reg_aligned_to_32bit(struct c_can_priv *priv,
>  						enum reg index)
>  {
> @@ -317,8 +351,8 @@ static int c_can_plat_probe(struct platform_device *pdev)
>  	case BOSCH_D_CAN_FLEXCARD:
>  		priv->regs = reg_map_d_can;
>  		priv->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES;
> -		priv->read_reg = c_can_plat_read_reg_aligned_to_16bit;
> -		priv->write_reg = c_can_plat_write_reg_aligned_to_16bit;
> +		priv->read_reg = c_can_plat_read_16bit_align_32bit_access;
> +		priv->write_reg = c_can_plat_write_16bit_align_32bit_access;
>  		priv->instance = pdev->id;
>  
>  		res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> 

Marc

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


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 11/16] c_can: stop netqueue if hardware is busy
       [not found] ` <1378711513-2548-12-git-send-email-b.spranger@linutronix.de>
@ 2013-09-09 10:05   ` Marc Kleine-Budde
  2013-09-09 10:21   ` Marc Kleine-Budde
  1 sibling, 0 replies; 17+ messages in thread
From: Marc Kleine-Budde @ 2013-09-09 10:05 UTC (permalink / raw)
  To: Benedikt Spranger
  Cc: netdev, Alexander Frank, Sebastian Andrzej Siewior,
	Holger Dengler, linux-can@vger.kernel.org

[-- Attachment #1: Type: text/plain, Size: 4985 bytes --]

On 09/09/2013 09:25 AM, Benedikt Spranger wrote:
> Unlike other network devices the FlexCard do not support interrupts on TX.
> Emulate the TX interrupt by polling the MOTRX registers and restart the
> netqueue if one or more message object is available for transtition of CAN
> frames.
> 
> Signed-off-by: Benedikt Spranger <b.spranger@linutronix.de>
> ---
>  drivers/net/can/c_can/c_can.c | 61 ++++++++++++++++++++++++++++++++++++++++---
>  drivers/net/can/c_can/c_can.h |  4 +++
>  2 files changed, 62 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c
> index 46d741d..02f7c89 100644
> --- a/drivers/net/can/c_can/c_can.c
> +++ b/drivers/net/can/c_can/c_can.c
> @@ -550,18 +550,66 @@ static void c_can_inval_msg_object(struct net_device *dev, int iface, int objno)
>  
>  static inline int c_can_is_next_tx_obj_busy(struct c_can_priv *priv, int objno)
>  {
> -	int val = c_can_read_reg32(priv, C_CAN_TXRQST1_REG);
> +	int val = c_can_read_reg32(priv, C_CAN_TXRQST1_REG + (objno / 32) * 4);
>  
>  	/*
>  	 * as transmission request register's bit n-1 corresponds to
>  	 * message object n, we need to handle the same properly.
>  	 */
> -	if (val & (1 << (objno - 1)))
> +	if (val & (1 << ((objno % 32) - 1)))
>  		return 1;
>  
>  	return 0;
>  }
>  
> +static void c_can_motrx_add_timer(struct net_device *dev)
> +{
> +	struct c_can_priv *priv = netdev_priv(dev);
> +
> +	priv->timer.expires = round_jiffies_relative(1);
> +	add_timer(&priv->timer);
> +}
> +
> +static void c_can_motrx_poll(unsigned long data)
> +{
> +	struct net_device *dev = (struct net_device *)data;
> +	struct c_can_priv *priv = netdev_priv(dev);
> +	u32 val, empty = 0;
> +	int i;
> +
> +	for (i = 0; i < C_CAN_MOTRX_NR; i++) {
> +		val = c_can_read_reg32(priv, C_CAN_TXRQST1_REG + i * 4);
> +
> +		if (val < priv->motrx[i]) {
> +			netif_wake_queue(dev);
> +			return;
> +		}
> +
> +		empty |= val;
> +	}
> +
> +	if (!empty) {
> +		netif_wake_queue(dev);
> +		return;
> +	}
> +
> +	c_can_motrx_add_timer(dev);
> +}
> +
> +static void c_can_motrx_monitor(struct net_device *dev)
> +{
> +	struct c_can_priv *priv = netdev_priv(dev);
> +	int i;
> +
> +	if (priv->type != BOSCH_D_CAN_FLEXCARD)
> +		return;
> +
> +	for (i = 0; i < C_CAN_MOTRX_NR; i++)
> +		priv->motrx[i] = c_can_read_reg32(priv,
> +				C_CAN_TXRQST1_REG + i * 4);
> +	c_can_motrx_add_timer(dev);
> +}
> +
>  static netdev_tx_t c_can_start_xmit(struct sk_buff *skb,
>  					struct net_device *dev)
>  {
> @@ -582,6 +630,7 @@ static netdev_tx_t c_can_start_xmit(struct sk_buff *skb,
>  		if (readl(priv->base + FC_TXFIFO_STAT) &
>  				FC_TXFIFO_STAT_FULL) {
>  			netif_stop_queue(dev);
> +			c_can_motrx_monitor(dev);
>  			return NETDEV_TX_BUSY;
>  		}
>  
> @@ -619,8 +668,10 @@ static netdev_tx_t c_can_start_xmit(struct sk_buff *skb,
>  		 * if the next TX message object is still in use
>  		 */
>  		if (c_can_is_next_tx_obj_busy(priv, get_tx_next_msg_obj(priv))
> -			|| ((priv->tx_next & C_CAN_NEXT_MSG_OBJ_MASK) == 0))
> +			|| ((priv->tx_next & C_CAN_NEXT_MSG_OBJ_MASK) == 0)) {
>  			netif_stop_queue(dev);
> +			c_can_motrx_monitor(dev);
> +		}
>  	}
>  
>  	return NETDEV_TX_OK;
> @@ -1272,6 +1323,7 @@ static int c_can_close(struct net_device *dev)
>  {
>  	struct c_can_priv *priv = netdev_priv(dev);
>  
> +	del_timer_sync(&priv->timer);
>  	netif_stop_queue(dev);
>  	napi_disable(&priv->napi);
>  	c_can_stop(dev);
> @@ -1306,6 +1358,9 @@ struct net_device *alloc_c_can_dev(void)
>  					CAN_CTRLMODE_LISTENONLY |
>  					CAN_CTRLMODE_BERR_REPORTING;
>  	spin_lock_init(&priv->lock);
> +	priv->timer.function = c_can_motrx_poll;
> +	priv->timer.data = (unsigned long) dev;
> +	init_timer_deferrable(&priv->timer);
>  
>  	return dev;
>  }
> diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h
> index beea437..6d0f805 100644
> --- a/drivers/net/can/c_can/c_can.h
> +++ b/drivers/net/can/c_can/c_can.h
> @@ -153,6 +153,8 @@ enum c_can_dev_id {
>  	BOSCH_D_CAN_FLEXCARD,
>  };
>  
> +#define C_CAN_MOTRX_NR	1

Are there reasons to have C_CAN_MOTRX_NR != 1? If not, please remove the
array and make code more clean.

>  /* c_can private data structure */
>  struct c_can_priv {
>  	struct can_priv can;	/* must be the first member */
> @@ -176,6 +178,8 @@ struct c_can_priv {
>  	unsigned int instance;
>  	void (*raminit) (const struct c_can_priv *priv, bool enable);
>  	spinlock_t lock;
> +	struct timer_list timer;
> +	u32 motrx[C_CAN_MOTRX_NR];
>  };
>  
>  struct net_device *alloc_c_can_dev(void);
> 

Marc

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


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 11/16] c_can: stop netqueue if hardware is busy
       [not found] ` <1378711513-2548-12-git-send-email-b.spranger@linutronix.de>
  2013-09-09 10:05   ` [PATCH 11/16] c_can: stop netqueue if hardware is busy Marc Kleine-Budde
@ 2013-09-09 10:21   ` Marc Kleine-Budde
  1 sibling, 0 replies; 17+ messages in thread
From: Marc Kleine-Budde @ 2013-09-09 10:21 UTC (permalink / raw)
  To: Benedikt Spranger
  Cc: netdev, Alexander Frank, Sebastian Andrzej Siewior,
	Holger Dengler, linux-can@vger.kernel.org

[-- Attachment #1: Type: text/plain, Size: 796 bytes --]

On 09/09/2013 09:25 AM, Benedikt Spranger wrote:
> Unlike other network devices the FlexCard do not support interrupts on TX.
> Emulate the TX interrupt by polling the MOTRX registers and restart the
> netqueue if one or more message object is available for transtition of CAN
> frames.
> 
> Signed-off-by: Benedikt Spranger <b.spranger@linutronix.de>

It's not onlynetif_wake_queue() that you have to call on TX-complete.
Have a look at c_can_do_tx(), better call it, or trigger napi from your
timer.

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


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 12/16] c_can: Add flag to disable automatic retransmission of CAN frames
       [not found] ` <1378711513-2548-13-git-send-email-b.spranger@linutronix.de>
@ 2013-09-09 10:21   ` Marc Kleine-Budde
  2013-09-09 10:34     ` Marc Kleine-Budde
  0 siblings, 1 reply; 17+ messages in thread
From: Marc Kleine-Budde @ 2013-09-09 10:21 UTC (permalink / raw)
  To: Benedikt Spranger
  Cc: netdev, Alexander Frank, Sebastian Andrzej Siewior,
	Holger Dengler, linux-can@vger.kernel.org

[-- Attachment #1: Type: text/plain, Size: 3408 bytes --]

On 09/09/2013 09:25 AM, Benedikt Spranger wrote:
> The C_CAN/D_CAN controler can automatic retransmit CAN after arbitration loss.
> Add a flag to CAN ctrlmode set the appropiate behaivior of this feature.

We already have this flag, it's called CAN_CTRLMODE_ONE_SHOT.

Marc

> Signed-off-by: Benedikt Spranger <b.spranger@linutronix.de>
> ---
>  drivers/net/can/c_can/c_can.c    | 16 +++++++++-------
>  include/uapi/linux/can/netlink.h |  2 ++
>  2 files changed, 11 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c
> index 02f7c89..51ca2a6 100644
> --- a/drivers/net/can/c_can/c_can.c
> +++ b/drivers/net/can/c_can/c_can.c
> @@ -785,33 +785,35 @@ static void c_can_configure_msg_objects(struct net_device *dev, int invalidate)
>  static int c_can_chip_config(struct net_device *dev)
>  {
>  	struct c_can_priv *priv = netdev_priv(dev);
> +	u16 reg;
>  	int ret;
>  
> -	/* enable automatic retransmission */
> -	priv->write_reg(priv, C_CAN_CTRL_REG,
> -			CONTROL_ENABLE_AR);
> +	if (priv->can.ctrlmode & CAN_CTRLMODE_DAR)
> +		reg = CONTROL_DISABLE_AR;
> +	else
> +		reg = CONTROL_ENABLE_AR;
>  
>  	if ((priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) &&
>  	    (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)) {
>  		/* loopback + silent mode : useful for hot self-test */
>  		priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_EIE |
> -				CONTROL_SIE | CONTROL_IE | CONTROL_TEST);
> +				reg | CONTROL_SIE | CONTROL_IE | CONTROL_TEST);
>  		priv->write_reg(priv, C_CAN_TEST_REG,
>  				TEST_LBACK | TEST_SILENT);
>  	} else if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) {
>  		/* loopback mode : useful for self-test function */
>  		priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_EIE |
> -				CONTROL_SIE | CONTROL_IE | CONTROL_TEST);
> +				reg | CONTROL_SIE | CONTROL_IE | CONTROL_TEST);
>  		priv->write_reg(priv, C_CAN_TEST_REG, TEST_LBACK);
>  	} else if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) {
>  		/* silent mode : bus-monitoring mode */
>  		priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_EIE |
> -				CONTROL_SIE | CONTROL_IE | CONTROL_TEST);
> +				reg | CONTROL_SIE | CONTROL_IE | CONTROL_TEST);
>  		priv->write_reg(priv, C_CAN_TEST_REG, TEST_SILENT);
>  	} else
>  		/* normal mode*/
>  		priv->write_reg(priv, C_CAN_CTRL_REG,
> -				CONTROL_EIE | CONTROL_SIE | CONTROL_IE);
> +				reg | CONTROL_EIE | CONTROL_SIE | CONTROL_IE);
>  
>  	/* configure message objects */
>  	c_can_configure_msg_objects(dev, 1);
> diff --git a/include/uapi/linux/can/netlink.h b/include/uapi/linux/can/netlink.h
> index 14966dd..fdce5af 100644
> --- a/include/uapi/linux/can/netlink.h
> +++ b/include/uapi/linux/can/netlink.h
> @@ -88,6 +88,8 @@ struct can_ctrlmode {
>  #define CAN_CTRLMODE_3_SAMPLES		0x04	/* Triple sampling mode */
>  #define CAN_CTRLMODE_ONE_SHOT		0x08	/* One-Shot mode */
>  #define CAN_CTRLMODE_BERR_REPORTING	0x10	/* Bus-error reporting */
> +#define CAN_CTRLMODE_DAR		0x20	/* Disable Automatic
> +						 * Retransmission */
>  
>  /*
>   * CAN device statistics
> 


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


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 13/16] c_can: flexcard: add ioctl to reset FIFO message object
       [not found] ` <1378711513-2548-14-git-send-email-b.spranger@linutronix.de>
@ 2013-09-09 10:24   ` Marc Kleine-Budde
  0 siblings, 0 replies; 17+ messages in thread
From: Marc Kleine-Budde @ 2013-09-09 10:24 UTC (permalink / raw)
  To: Benedikt Spranger
  Cc: netdev, Alexander Frank, Sebastian Andrzej Siewior,
	Holger Dengler, linux-can@vger.kernel.org

[-- Attachment #1: Type: text/plain, Size: 1638 bytes --]

On 09/09/2013 09:25 AM, Benedikt Spranger wrote:
> The FlexCard FIFO reset implementation did not reset the FIFO message object.
> Since the FIFO configuration is done from userspace a function to reset the
> FIFO message object is needed. Add an ioctl to reset the FIFO message object
> from userspace.

Can you elaborate this a bit.

> Signed-off-by: Benedikt Spranger <b.spranger@linutronix.de>
>
> ---
>  drivers/net/can/c_can/c_can.c | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c
> index 51ca2a6..670a6b1 100644
> --- a/drivers/net/can/c_can/c_can.c
> +++ b/drivers/net/can/c_can/c_can.c
> @@ -1447,7 +1447,21 @@ void free_c_can_dev(struct net_device *dev)
>  }
>  EXPORT_SYMBOL_GPL(free_c_can_dev);
>  
> +static int c_can_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
> +{
> +	switch (cmd) {
> +	case SIOCDEVPRIVATE:
> +		c_can_inval_msg_object(dev, 0, FC_TXFIFO_MO);
> +		break;

What happens if you call this ioctl on non flexcard HW?

> +	default:
> +		return -ENOIOCTLCMD;
> +	}
> +
> +	return 0;
> +}
> +
>  static const struct net_device_ops c_can_netdev_ops = {
> +	.ndo_do_ioctl = c_can_ioctl,
>  	.ndo_open = c_can_open,
>  	.ndo_stop = c_can_close,
>  	.ndo_start_xmit = c_can_start_xmit,
> 

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


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 15/16] flexcard: can: Configure CAN loopback packages (TXACK)
       [not found] ` <1378711513-2548-16-git-send-email-b.spranger@linutronix.de>
@ 2013-09-09 10:29   ` Marc Kleine-Budde
  0 siblings, 0 replies; 17+ messages in thread
From: Marc Kleine-Budde @ 2013-09-09 10:29 UTC (permalink / raw)
  To: Benedikt Spranger
  Cc: netdev, Alexander Frank, Sebastian Andrzej Siewior,
	Holger Dengler, linux-can@vger.kernel.org

[-- Attachment #1: Type: text/plain, Size: 3416 bytes --]

On 09/09/2013 09:25 AM, Benedikt Spranger wrote:
> Signed-off-by: Holger Dengler <dengler@linutronix.de>

I'm missing your S-o-b and a patch description. I'm finding some
uncommon use of frame->can_dlc.

Marc

> ---
>  drivers/net/can/c_can/c_can.c | 23 ++++++++++++++++-------
>  1 file changed, 16 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c
> index 670a6b1..92c1444 100644
> --- a/drivers/net/can/c_can/c_can.c
> +++ b/drivers/net/can/c_can/c_can.c
> @@ -358,11 +358,13 @@ static inline void c_can_object_put(struct net_device *dev,
>  }
>  
>  static void c_can_write_msg_object(struct net_device *dev,
> -			int iface, struct can_frame *frame, int objno)
> +			int iface, struct can_frame *frame, int objno,
> +			int txie_off)
>  {
>  	u32 flags = IF_ARB_MSGVAL;
>  	unsigned int id;
>  	struct c_can_priv *priv = netdev_priv(dev);
> +	u32 int_en;
>  
>  	if (!(frame->can_id & CAN_RTR_FLAG))
>  		flags |= IF_ARB_TRANSMIT;
> @@ -388,9 +390,10 @@ static void c_can_write_msg_object(struct net_device *dev,
>  			 frame->data[4] | frame->data[5] << 8);
>  
>  	/* enable interrupt for this message object */
> -	priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface),
> -			IF_MCONT_TXIE | IF_MCONT_TXRQST | IF_MCONT_EOB |
> -			frame->can_dlc);
> +	int_en = frame->can_dlc;
> +	if (!txie_off)
> +		int_en |= IF_MCONT_TXIE | IF_MCONT_TXRQST | IF_MCONT_EOB;
> +	priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), int_en);
>  	c_can_object_put(dev, iface, objno, IF_COMM_ALL);
>  }
>  
> @@ -616,16 +619,17 @@ static netdev_tx_t c_can_start_xmit(struct sk_buff *skb,
>  	u32 msg_obj_no;
>  	struct c_can_priv *priv = netdev_priv(dev);
>  	struct can_frame *frame = (struct can_frame *)skb->data;
> -	int tx_fifo;
> +	int tx_fifo, txie_off;
>  
>  	if (can_dropped_invalid_skb(dev, skb))
>  		return NETDEV_TX_OK;
>  
>  	tx_fifo = frame->can_dlc & FC_TXFIFO_FLAG;
> +	txie_off = frame->can_dlc & FC_TXACKOFF_FLAG;
>  	frame->can_dlc &= FC_TXFIFO_DLC_MASK;
>  
>  	if (tx_fifo) {
> -		u32 id, *data, ctrl;
> +		u32 id, *data, ctrl, conf;
>  
>  		if (readl(priv->base + FC_TXFIFO_STAT) &
>  				FC_TXFIFO_STAT_FULL) {
> @@ -652,6 +656,11 @@ static netdev_tx_t c_can_start_xmit(struct sk_buff *skb,
>  			writel(data[1], priv->base + FC_TXFIFO_MSGDB);
>  		}
>  
> +		conf = readl(priv->base + FC_TXFIFO_CONF);
> +		conf &= ~FC_TXFIFO_CONF_TXACK;
> +		conf |= (txie_off ? 0 : FC_TXFIFO_CONF_TXACK);
> +		writel(conf, priv->base + FC_TXFIFO_CONF);
> +
>  		ctrl = readl(priv->base + FC_TXFIFO_CTRL);
>  		ctrl |= FC_TXFIFO_CTRL_REQ;
>  		writel(ctrl, priv->base + FC_TXFIFO_CTRL);
> @@ -660,7 +669,7 @@ static netdev_tx_t c_can_start_xmit(struct sk_buff *skb,
>  		msg_obj_no = get_tx_next_msg_obj(priv);
>  
>  		/* prepare message object for transmission */
> -		c_can_write_msg_object(dev, 0, frame, msg_obj_no);
> +		c_can_write_msg_object(dev, 0, frame, msg_obj_no, txie_off);
>  		priv->tx_next++;
>  
>  		can_put_echo_skb(skb, dev, msg_obj_no - C_CAN_MSG_OBJ_TX_FIRST);
> 


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


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 16/16] c_can: fix TX packet accounting
       [not found] ` <1378711513-2548-17-git-send-email-b.spranger@linutronix.de>
@ 2013-09-09 10:31   ` Marc Kleine-Budde
  0 siblings, 0 replies; 17+ messages in thread
From: Marc Kleine-Budde @ 2013-09-09 10:31 UTC (permalink / raw)
  To: Benedikt Spranger
  Cc: netdev, Alexander Frank, Sebastian Andrzej Siewior,
	Holger Dengler, linux-can@vger.kernel.org

[-- Attachment #1: Type: text/plain, Size: 1980 bytes --]

On 09/09/2013 09:25 AM, Benedikt Spranger wrote:
> Due to the integration of the FlexCard support the TX stats accounting got
> lost. Readd the accounting.

Please squash into the appropriate patch.

Marc

> Signed-off-by: Benedikt Spranger <b.spranger@linutronix.de>
> ---
>  drivers/net/can/c_can/c_can.c | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c
> index 92c1444..b409cf2 100644
> --- a/drivers/net/can/c_can/c_can.c
> +++ b/drivers/net/can/c_can/c_can.c
> @@ -619,6 +619,7 @@ static netdev_tx_t c_can_start_xmit(struct sk_buff *skb,
>  	u32 msg_obj_no;
>  	struct c_can_priv *priv = netdev_priv(dev);
>  	struct can_frame *frame = (struct can_frame *)skb->data;
> +	struct net_device_stats *stats = &dev->stats;
>  	int tx_fifo, txie_off;
>  
>  	if (can_dropped_invalid_skb(dev, skb))
> @@ -664,6 +665,9 @@ static netdev_tx_t c_can_start_xmit(struct sk_buff *skb,
>  		ctrl = readl(priv->base + FC_TXFIFO_CTRL);
>  		ctrl |= FC_TXFIFO_CTRL_REQ;
>  		writel(ctrl, priv->base + FC_TXFIFO_CTRL);
> +
> +		stats->tx_bytes += frame->can_dlc;
> +		stats->tx_packets++;
>  		kfree_skb(skb);
>  	} else {
>  		msg_obj_no = get_tx_next_msg_obj(priv);
> @@ -672,6 +676,8 @@ static netdev_tx_t c_can_start_xmit(struct sk_buff *skb,
>  		c_can_write_msg_object(dev, 0, frame, msg_obj_no, txie_off);
>  		priv->tx_next++;
>  
> +		stats->tx_bytes += frame->can_dlc;
> +		stats->tx_packets++;
>  		can_put_echo_skb(skb, dev, msg_obj_no - C_CAN_MSG_OBJ_TX_FIRST);
>  		/* we have to stop the queue in case of a wrap around or
>  		 * if the next TX message object is still in use
> 


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


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 12/16] c_can: Add flag to disable automatic retransmission of CAN frames
  2013-09-09 10:21   ` [PATCH 12/16] c_can: Add flag to disable automatic retransmission of CAN frames Marc Kleine-Budde
@ 2013-09-09 10:34     ` Marc Kleine-Budde
  0 siblings, 0 replies; 17+ messages in thread
From: Marc Kleine-Budde @ 2013-09-09 10:34 UTC (permalink / raw)
  To: Benedikt Spranger
  Cc: netdev, Alexander Frank, Sebastian Andrzej Siewior,
	Holger Dengler, linux-can@vger.kernel.org

[-- Attachment #1: Type: text/plain, Size: 718 bytes --]

On 09/09/2013 12:21 PM, Marc Kleine-Budde wrote:
> On 09/09/2013 09:25 AM, Benedikt Spranger wrote:
>> The C_CAN/D_CAN controler can automatic retransmit CAN after arbitration loss.
>> Add a flag to CAN ctrlmode set the appropiate behaivior of this feature.
> 
> We already have this flag, it's called CAN_CTRLMODE_ONE_SHOT.

BTW: Have a look at commit:

    ee6f098 can: c_can: disable one shot mode until driver is fixed

Marc

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


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 04/16] c_can: fix receive buffer configuration
       [not found] ` <1378711513-2548-5-git-send-email-b.spranger@linutronix.de>
@ 2013-09-09 10:51   ` Marc Kleine-Budde
  0 siblings, 0 replies; 17+ messages in thread
From: Marc Kleine-Budde @ 2013-09-09 10:51 UTC (permalink / raw)
  To: Benedikt Spranger
  Cc: netdev, Alexander Frank, Sebastian Andrzej Siewior,
	Holger Dengler, linux-can@vger.kernel.org

[-- Attachment #1: Type: text/plain, Size: 2132 bytes --]

On 09/09/2013 09:25 AM, Benedikt Spranger wrote:
> The former implementation lacks some initialization of receive buffer.
> First the maximal buffer length was 0. The Buffer direction was not set
> and the mask register a reserverd flag was cleared.
> 
> Signed-off-by: Benedikt Spranger <b.spranger@linutronix.de>
> ---
>  drivers/net/can/c_can/c_can.c | 19 ++++++++++++++-----
>  1 file changed, 14 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c
> index bdb7bcd..886163f 100644
> --- a/drivers/net/can/c_can/c_can.c
> +++ b/drivers/net/can/c_can/c_can.c
> @@ -116,6 +116,11 @@
>  				IF_COMM_CONTROL | IF_COMM_TXRQST | \
>  				IF_COMM_DATAA | IF_COMM_DATAB)
>  
> +/* IFx mask */
> +#define IF_MASK_MXTD		BIT(31)
> +#define IF_MASK_MDIR		BIT(30)
> +#define IF_MASK_RES		BIT(29)
> +
>  /* IFx arbitration */
>  #define IF_ARB_MSGVAL		BIT(31)
>  #define IF_ARB_MSGXTD		BIT(30)
> @@ -653,11 +658,15 @@ static void c_can_configure_msg_objects(struct net_device *dev)
>  
>  	/* setup receive message objects */
>  	for (i = C_CAN_MSG_OBJ_RX_FIRST; i < C_CAN_MSG_OBJ_RX_LAST; i++)
> -		c_can_setup_receive_object(dev, 0, i, 0, 0,
> -			(IF_MCONT_RXIE | IF_MCONT_UMASK) & ~IF_MCONT_EOB);
> -
> -	c_can_setup_receive_object(dev, 0, C_CAN_MSG_OBJ_RX_LAST, 0, 0,
> -			IF_MCONT_EOB | IF_MCONT_RXIE | IF_MCONT_UMASK);
> +		c_can_setup_receive_object(dev, 0, i,
> +					   IF_MASK_MDIR | IF_MASK_RES, 0,
> +					   IF_MCONT_UMASK | IF_MCONT_RXIE |
> +					   IF_MCONT_DLC_MAX);

DLC_MAX should be added in this patch. not in 3.

> +
> +	c_can_setup_receive_object(dev, 0, C_CAN_MSG_OBJ_RX_LAST,
> +				   IF_MASK_MDIR | IF_MASK_RES, 0,
> +				   IF_MCONT_UMASK | IF_MCONT_EOB |
> +				   IF_MCONT_RXIE | IF_MCONT_DLC_MAX);
>  }
>  
>  /*
> 

Marc

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


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 09/16] c_can: expicit 32bit access on D_CAN to message buffer data register
       [not found] ` <1378711513-2548-10-git-send-email-b.spranger@linutronix.de>
@ 2013-09-09 11:20   ` Marc Kleine-Budde
  0 siblings, 0 replies; 17+ messages in thread
From: Marc Kleine-Budde @ 2013-09-09 11:20 UTC (permalink / raw)
  To: Benedikt Spranger
  Cc: netdev, Alexander Frank, Sebastian Andrzej Siewior,
	Holger Dengler, linux-can@vger.kernel.org

[-- Attachment #1: Type: text/plain, Size: 2170 bytes --]

On 09/09/2013 09:25 AM, Benedikt Spranger wrote:
> change the 16bit access of ARB1_REG and DATA1/2_REG to a 32bit access.
> 
> Signed-off-by: Benedikt Spranger <b.spranger@linutronix.de>
> ---
>  drivers/net/can/c_can/c_can.c | 19 ++++++++++---------
>  1 file changed, 10 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c
> index 4b94f2d..c573399 100644
> --- a/drivers/net/can/c_can/c_can.c
> +++ b/drivers/net/can/c_can/c_can.c
> @@ -360,7 +360,6 @@ static inline void c_can_object_put(struct net_device *dev,
>  static void c_can_write_msg_object(struct net_device *dev,
>  			int iface, struct can_frame *frame, int objno)
>  {
> -	int i;
>  	u32 flags = IF_ARB_MSGVAL;
>  	unsigned int id;
>  	struct c_can_priv *priv = netdev_priv(dev);
> @@ -376,15 +375,17 @@ static void c_can_write_msg_object(struct net_device *dev,
>  
>  	id |= flags;
>  
> -	priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface),
> -				IFX_WRITE_LOW_16BIT(id));
> -	priv->write_reg(priv, C_CAN_IFACE(ARB2_REG, iface),
> -				IFX_WRITE_HIGH_16BIT(id));
> +	c_can_writereg32(priv, C_CAN_IFACE(ARB1_REG, iface),
> +			IFX_WRITE_HIGH_16BIT(id),
> +			IFX_WRITE_LOW_16BIT(id));
> +
> +	c_can_writereg32(priv, C_CAN_IFACE(DATA1_REG, iface),
> +			 frame->data[2] | frame->data[3] << 8,
> +			 frame->data[0] | frame->data[1] << 8);

You can use something like beXX_to_cpup((__be32 *)&cf->data[0]) here.

>  
> -	for (i = 0; i < frame->can_dlc; i += 2) {
> -		priv->write_reg(priv, C_CAN_IFACE(DATA1_REG, iface) + i / 2,
> -				frame->data[i] | (frame->data[i + 1] << 8));
> -	}
> +	c_can_writereg32(priv, C_CAN_IFACE(DATA3_REG, iface),
> +			 frame->data[6] | frame->data[7] << 8,
> +			 frame->data[4] | frame->data[5] << 8);

You write here the upper 32 bit unconditionally, the original code doesn't.

Marc

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


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2013-09-09 11:20 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <1378711513-2548-1-git-send-email-b.spranger@linutronix.de>
2013-09-09  7:54 ` [PATCH 00/16] Support for Eberspächer Flexcard DCAN function Marc Kleine-Budde
     [not found] ` <1378711513-2548-2-git-send-email-b.spranger@linutronix.de>
2013-09-09  8:22   ` [PATCH 01/16] c_can_platform: add FlexCard D-CAN support Marc Kleine-Budde
     [not found] ` <1378711513-2548-3-git-send-email-b.spranger@linutronix.de>
2013-09-09  8:34   ` [PATCH 02/16] c_can: add generic D-CAN RAM initialization support Marc Kleine-Budde
     [not found] ` <1378711513-2548-4-git-send-email-b.spranger@linutronix.de>
2013-09-09  9:16   ` [PATCH 03/16] c_can: simplify arbitration register handling Marc Kleine-Budde
     [not found] ` <1378711513-2548-6-git-send-email-b.spranger@linutronix.de>
2013-09-09  9:37   ` [PATCH 05/16] c_can: use 32 bit access for D_CAN Marc Kleine-Budde
     [not found] ` <1378711513-2548-7-git-send-email-b.spranger@linutronix.de>
2013-09-09  9:39   ` [PATCH 06/16] c_can: consider set bittiming may fail Marc Kleine-Budde
     [not found] ` <1378711513-2548-9-git-send-email-b.spranger@linutronix.de>
2013-09-09  9:47   ` [PATCH 08/16] c_can: Add FlexCard CAN TX fifo support Marc Kleine-Budde
     [not found] ` <1378711513-2548-11-git-send-email-b.spranger@linutronix.de>
2013-09-09  9:57   ` [PATCH 10/16] c_can: add 16bit align 32bit access functions Marc Kleine-Budde
     [not found] ` <1378711513-2548-12-git-send-email-b.spranger@linutronix.de>
2013-09-09 10:05   ` [PATCH 11/16] c_can: stop netqueue if hardware is busy Marc Kleine-Budde
2013-09-09 10:21   ` Marc Kleine-Budde
     [not found] ` <1378711513-2548-13-git-send-email-b.spranger@linutronix.de>
2013-09-09 10:21   ` [PATCH 12/16] c_can: Add flag to disable automatic retransmission of CAN frames Marc Kleine-Budde
2013-09-09 10:34     ` Marc Kleine-Budde
     [not found] ` <1378711513-2548-14-git-send-email-b.spranger@linutronix.de>
2013-09-09 10:24   ` [PATCH 13/16] c_can: flexcard: add ioctl to reset FIFO message object Marc Kleine-Budde
     [not found] ` <1378711513-2548-16-git-send-email-b.spranger@linutronix.de>
2013-09-09 10:29   ` [PATCH 15/16] flexcard: can: Configure CAN loopback packages (TXACK) Marc Kleine-Budde
     [not found] ` <1378711513-2548-17-git-send-email-b.spranger@linutronix.de>
2013-09-09 10:31   ` [PATCH 16/16] c_can: fix TX packet accounting Marc Kleine-Budde
     [not found] ` <1378711513-2548-5-git-send-email-b.spranger@linutronix.de>
2013-09-09 10:51   ` [PATCH 04/16] c_can: fix receive buffer configuration Marc Kleine-Budde
     [not found] ` <1378711513-2548-10-git-send-email-b.spranger@linutronix.de>
2013-09-09 11:20   ` [PATCH 09/16] c_can: expicit 32bit access on D_CAN to message buffer data register Marc Kleine-Budde

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).