* 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).