From: "Ira W. Snyder" <ira.snyder@gmail.com>
To: Marc Kleine-Budde <mkl@pengutronix.de>
Cc: "Andreas Gröger" <andreas24groeger@gmail.com>,
linux-can@vger.kernel.org, iws@ovro.caltech.edu
Subject: Re: [PATCH] can: janz-ican3: add support for CAL/CANopen firmware
Date: Sat, 2 May 2015 09:40:51 -0700 [thread overview]
Message-ID: <20150502164049.GB31242@gmail.com> (raw)
In-Reply-To: <5543E065.6060000@pengutronix.de>
On Fri, May 01, 2015 at 10:21:57PM +0200, Marc Kleine-Budde wrote:
> On 05/01/2015 08:31 PM, Andreas Gröger wrote:
> > in our department we are using some older Janz ICAN3-modules in our
> > dekstop pcs. There we have slightly different carrier boards than the
> > janz-cmodio supported in the kernel sources, called CAN-PCI2 with two
> > submodules. But the pci configuration regions are identical. So
> > extending the supported pci devices to the corresponding device ids
> > is sufficient to get the drivers working. Great.
> >
> > I have two minor issues:
> > * The old ICAN3-modules with firmware 1.28 need more then 250ms for
> > the restart after reset. I've increased the timeout to 500ms.
>
> Should be no problem, as it's a timeout.
>
> > * The janz_ican3 module uses the raw can services of the
> > Janz-firmware, this means firmware must be ICANOS/2. Our
> > ICAN3-modules are equipped with CAL/CANopen-firmware, so I must use
> > the appropriate commands for the layer management services.
> > My proposal: the driver detects the firmware after module reset and
> > selects the commands matching the firmware. This affects the bus
> > on/off-command (ican3_set_bus_state) and the configuration of the
> > bittiming (ican3_set_bittiming). For better diagnostics the detected
>
> Is it possible to move the set_bittiming for both firmwares into the
> ican3_set_bus_state() function? For various reasons I don't like the
> fact that the bitrate is written into the hardware while the interface
> is down.
>
> > firmware string is presented as sysfs attribute (fwinfo).
>
> Please document the new sysfs entry, see
> Documentation/ABI/testing/sysfs-platform-at91 as an example. Please be
> so kind and document the already existing termination attribute, too.
>
> > Currently my system works great. Are there any possibilities to get
> > my changes into the linux kernel? Here are my changes based on a
> > linux-3.19.6 vanilla kernel. Is this the right place for my request,
> > is there any maintainer I can ask? I would be grateful for any help.
>
> Ira, can you have a look at the changes and give your Acked-by?
>
Hi Andreas, Hi Marc,
The changes look great to me. I no longer work for Caltech, and so I
don't have access to the hardware to test the changes. They are very
self contained, and so are unlikely to cause any problems.
I have one more nitpick in addition to Marc's, which I added inline
below. Great job on your first patch!
Acked-by: Ira W. Snyder <ira.snyder@gmail.com>
Thanks,
Ira
> The changes look quite good, some minor nitpicks inline. In the next
> patch iteration add add your S-o-b, see [1].
>
> [1]
> http://lxr.free-electrons.com/source/Documentation/SubmittingPatches#L407
>
> > ---
> > drivers/mfd/janz-cmodio.c | 4 +
> > drivers/net/can/janz-ican3.c | 97 +++++++++++++++++++++++++++++++++++--------
> > 2 files changed, 84 insertions(+), 17 deletions(-)
> >
> > diff -uNr -X linux-3.19.me/Documentation/dontdiff linux-3.19.6/drivers/mfd/janz-cmodio.c linux-3.19.me/drivers/mfd/janz-cmodio.c
> > --- linux-3.19.6/drivers/mfd/janz-cmodio.c 2015-04-29 10:30:26.000000000 +0200
> > +++ linux-3.19.me/drivers/mfd/janz-cmodio.c 2015-04-30 19:24:44.729193534 +0200
> > @@ -267,6 +267,10 @@
> > static const struct pci_device_id cmodio_pci_ids[] = {
> > { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, PCI_VENDOR_ID_JANZ, 0x0101 },
> > { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, PCI_VENDOR_ID_JANZ, 0x0100 },
> > + { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, PCI_VENDOR_ID_JANZ, 0x0201 },
> > + { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, PCI_VENDOR_ID_JANZ, 0x0202 },
> > + { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, PCI_VENDOR_ID_JANZ, 0x0201 },
> > + { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, PCI_VENDOR_ID_JANZ, 0x0202 },
> > { 0, }
> > };
> > MODULE_DEVICE_TABLE(pci, cmodio_pci_ids);
> > diff -uNr -X linux-3.19.me/Documentation/dontdiff linux-3.19.6/drivers/net/can/janz-ican3.c linux-3.19.me/drivers/net/can/janz-ican3.c
> > --- linux-3.19.6/drivers/net/can/janz-ican3.c 2015-04-29 10:30:26.000000000 +0200
> > +++ linux-3.19.me/drivers/net/can/janz-ican3.c 2015-04-30 19:54:20.223146411 +0200
> > @@ -83,6 +83,7 @@
> > #define MSG_COFFREQ 0x42
> > #define MSG_CONREQ 0x43
> > #define MSG_CCONFREQ 0x47
> > +#define MSG_LMTS 0xb4
> >
> > /*
> > * Janz ICAN3 CAN Inquiry Message Types
> > @@ -215,6 +216,10 @@
> > struct completion buserror_comp;
> > struct can_berr_counter bec;
> >
> > + /* firmware type: 0=ICANOS, 1=CAN/CALopen */
> > + unsigned int fwtype;
>
> please create an enum, make it readable, so that you don't need the
> comments anymore :) Something like this:
>
> enum ican3_fwtype {
> ICAN3_FWTYPE_ICANOS, // or RAW
> ICAN3_FWTYPE_CALOPEN,
> };
>
> > + char fwinfo[0x20];
>
> Nitpick, I'd prefer a plain decimal 32 instead. Where does the length
> come from?
>
> > +
> > /* old and new style host interface */
> > unsigned int iftype;
> >
> > @@ -270,6 +275,26 @@
> > }
> >
> > /*
> > + * This routine was stolen from drivers/net/can/sja1000/sja1000.c
> > + *
> > + * The bittiming register command for the ICAN3 just sets the bit timing
> > + * registers on the SJA1000 chip directly
> > + */
> > +static inline void ican3_calc_bittiming(struct ican3_dev *mod, u8 *btr0, u8 *btr1)
> > +{
> > + struct can_bittiming *bt = &mod->can.bittiming;
> > +
> > + if (!btr0 || !btr1)
> > + return;
> > +
> > + *btr0 = ((bt->brp - 1) & 0x3f) | (((bt->sjw - 1) & 0x3) << 6);
> > + *btr1 = ((bt->prop_seg + bt->phase_seg1 - 1) & 0xf) |
> > + (((bt->phase_seg2 - 1) & 0x7) << 4);
> > + if (mod->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
> > + *btr1 |= 0x80;
> > +}
> > +
> > +/*
> > * ICAN3 "old-style" host interface
> > */
> >
> > @@ -751,12 +776,37 @@
> > static int ican3_set_bus_state(struct ican3_dev *mod, bool on)
> > {
> > struct ican3_msg msg;
> > + u8 btr0, btr1;
> >
> > memset(&msg, 0, sizeof(msg));
> > - msg.spec = on ? MSG_CONREQ : MSG_COFFREQ;
> > - msg.len = cpu_to_le16(0);
> >
> > - return ican3_send_msg(mod, &msg);
> > + /* raw CAN firmware */
> make use of the enum
> > + if (mod->fwtype == 0) {
> > + msg.spec = on ? MSG_CONREQ : MSG_COFFREQ;
> > + msg.len = cpu_to_le16(0);
> > +
> > + return ican3_send_msg(mod, &msg);
> > + }
> > +
> > + /* CAL firmware */
> > + if (mod->fwtype == 1) {
>
> else if + use enum
>
> > + msg.spec = MSG_LMTS;
> > + if (on) {
> > + ican3_calc_bittiming(mod, &btr0, &btr1);
> > + msg.len = cpu_to_le16(4);
> > + msg.data[0] = 0;
> > + msg.data[1] = 0;
> > + msg.data[2] = btr0;
> > + msg.data[3] = btr1;
> > + } else {
> > + msg.len = cpu_to_le16(2);
> > + msg.data[0] = 1;
> > + msg.data[1] = 0;
> > + }
> > +
> > + return ican3_send_msg(mod, &msg);
> > + }
> > + return -ENOTSUPP;
> > }
> >
> > static int ican3_set_termination(struct ican3_dev *mod, bool on)
> > @@ -1401,7 +1451,7 @@
> > return 0;
> >
> > msleep(10);
> > - } while (time_before(jiffies, start + HZ / 4));
> > + } while (time_before(jiffies, start + HZ / 2));
> >
> > netdev_err(mod->ndev, "failed to reset CAN module\n");
> > return -ETIMEDOUT;
> > @@ -1426,6 +1476,15 @@
> > return ret;
> > }
> >
> > + /* detect firmware */
> > + memcpy_fromio(mod->fwinfo, mod->dpm + 0x60, sizeof(mod->fwinfo) - 1);
Please create a #define for the 0x60 here. Using the name from the
manual is fine. Look at MSYNC_PEER, MSYNC_LOCL, etc. for examples.
> > + if (strncmp(mod->fwinfo, "JANZ-ICAN3", 10)) {
> > + netdev_err(mod->ndev, "ICAN3 not detected (found %s)\n", mod->fwinfo);
> > + return -ENODEV;
> > + }
> > + if (strstr(mod->fwinfo, "CAL/CANopen"))
> > + mod->fwtype = 1;
> > +
>
> Is there a saner way of identifying one or the other card than doing
> these string comparisons?
>
> > /* re-enable interrupts so we can send messages */
> > iowrite8(1 << mod->num, &mod->ctrl->int_enable);
> >
> > @@ -1614,24 +1673,17 @@
> > .brp_inc = 1,
> > };
> >
> > -/*
> > - * This routine was stolen from drivers/net/can/sja1000/sja1000.c
> > - *
> > - * The bittiming register command for the ICAN3 just sets the bit timing
> > - * registers on the SJA1000 chip directly
> > - */
> > static int ican3_set_bittiming(struct net_device *ndev)
> > {
> > struct ican3_dev *mod = netdev_priv(ndev);
> > - struct can_bittiming *bt = &mod->can.bittiming;
> > struct ican3_msg msg;
> > u8 btr0, btr1;
> >
> > - btr0 = ((bt->brp - 1) & 0x3f) | (((bt->sjw - 1) & 0x3) << 6);
> > - btr1 = ((bt->prop_seg + bt->phase_seg1 - 1) & 0xf) |
> > - (((bt->phase_seg2 - 1) & 0x7) << 4);
> > - if (mod->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
> > - btr1 |= 0x80;
> > + /* with CAL firmware bittiming is set in ican3_set_bus_state */
> > + if (mod->fwtype == 1)
> > + return 0;
> > +
> > + ican3_calc_bittiming(mod, &btr0, &btr1);
> >
> > memset(&msg, 0, sizeof(msg));
> > msg.spec = MSG_CBTRREQ;
> > @@ -1731,11 +1783,22 @@
> > return count;
> > }
> >
> > +static ssize_t ican3_sysfs_show_fwinfo(struct device *dev,
> > + struct device_attribute *attr,
> > + char *buf)
> > +{
> > + struct ican3_dev *mod = netdev_priv(to_net_dev(dev));
> > +
> > + return scnprintf(buf, PAGE_SIZE, "%s\n", mod->fwinfo);
> > +}
> > +
> > static DEVICE_ATTR(termination, S_IWUSR | S_IRUGO, ican3_sysfs_show_term,
> > ican3_sysfs_set_term);
> > +static DEVICE_ATTR(fwinfo, S_IRUSR | S_IRUGO, ican3_sysfs_show_fwinfo, NULL);
> >
> > static struct attribute *ican3_sysfs_attrs[] = {
> > &dev_attr_termination.attr,
> > + &dev_attr_fwinfo.attr,
> > NULL,
> > };
> >
> > @@ -1867,7 +1930,7 @@
> > goto out_free_irq;
> > }
> >
> > - dev_info(dev, "module %d: registered CAN device\n", pdata->modno);
> > + netdev_info(mod->ndev, "module %d: registered CAN device\n", pdata->modno);
> > return 0;
> >
> > out_free_irq:
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-can" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at http://vger.kernel.org/majordomo-info.html
> >
>
> 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 |
>
next prev parent reply other threads:[~2015-05-02 16:40 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-05-01 18:31 [PATCH] can: janz-ican3: add support for CAL/CANopen firmware Andreas Gröger
2015-05-01 20:21 ` Marc Kleine-Budde
2015-05-02 16:40 ` Ira W. Snyder [this message]
2015-05-02 16:42 ` Marc Kleine-Budde
2015-05-04 17:40 ` Andreas Gröger
2015-05-05 18:08 ` Andreas Gröger
2015-05-06 6:01 ` Marc Kleine-Budde
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20150502164049.GB31242@gmail.com \
--to=ira.snyder@gmail.com \
--cc=andreas24groeger@gmail.com \
--cc=iws@ovro.caltech.edu \
--cc=linux-can@vger.kernel.org \
--cc=mkl@pengutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).