On Wed, Feb 10, 2010 at 10:09:34AM +0100, Kurt Van Dijck wrote:
> On Tue, Feb 09, 2010 at 04:05:00PM -0800, Ira W. Snyder wrote:
> > Hello all,
> >
> > I posted last week asking about a driver for boards running on a PLX
> > chip. It turns out that these are passive boards. I have been looking
> > for a driver for the Janz CMOD-IO board CAN interfaces.
> >
> > I finally found the datasheets and took the time to write a driver. This
> > board is an intelligent CAN interface: it has onboard microprocessors to
> > help process CAN traffic.
> >
> > This is a very rough first try at a CAN driver. I'm sure it still has
> > problems, and I would appreciate if you can take a look and help me add
> > what is needed. I'm am not extremely knowledgeable about the CAN bus.
> >
> > The things that are known to be wrong:
> >
> > - bus-on / bus-off handling
> >
> > I did this straight in the network device open()/stop() methods. I don't
> > handle the condition where we get too many bus errors and the bus goes
> > into bus-off state. What should I be doing here?
> What you call 'bus-off' is indeed the stop() method. the CAN busoff
> (which is something different)
> comes via interrupt (bus-state-change), indicating the
> can-chip cut itself from the bus. In such case, a special 'struct
> can_frame' must be emitted to userspace.
Ok. The way I read this: the netdevice open()/stop() methods should put
the device into "CAN buson" and "CAN busoff" state. In addition, when
the device has an error, it will go into "CAN busoff" state eventually.
In this case, I should generate a special CAN frame and send it to
userspace. Is that right?
> >
> > - state changes, bit timing, etc.
> the bittiming looks exactly as SJA1000 (especially the resulting
> register values). please take a look there.
This isn't too surprising: the module uses an SJA1000 chip for the
actual CAN communications.
> >
> > I'm not at all sure how this is supposed to work. Perhaps someone that
> > knows CAN bus better that I do can help.
> The bittiming is calculated (in drivers/net/can/dev.c) from the
> constants you provide. again, sja1000 is a 'reference'.
> opening/closing:
> from userspace, the open() gets called somehow. You will activate the
> can chip (what you called 'bus-on', which is a strange terminology IMHO).
> can messages come & go now. When there are distortions on the CAN bus,
> the CAN chip will raise some errors (via interrupts). At a certain
> point, distortions get so bad and the can chip cuts itself from the
> bus (accompanied by an interrupt, as mentioned above).
> You are not supposed to call close() there.
Ok. By "bus-on" and "bus-off", I was referring to "CAN bus-on" and "CAN
bus-off". I'm well aware of how a Linux network device works. :)
So the controller may go "CAN busoff" due to errors, but not stop the
network device. This makes sense. In this case I generate an error
frame.
> >
> > - CAN bus termination
> >
> > This board supports optionally terminating the CAN bus. In order to test
> > this driver, I connected both CAN modules on a single board together. To
> > get this to work, I needed to turn on termination on both modules.
> >
> > Is this wrong?
> A bus must have both ends terminated (although a labo setup will do with
> 1 termination too). The idea is that not every 'node' in the
> middle must terminate the bus, only the endpoints.
> What you did seems right.
> > Is there a way to enable/disable termination via the "ip"
> > tool?
> There is at this point no such thing yet. Such properties may be enabled
> via sysfs IMHO.
> >
> > - module probing
> >
> > This board is really a MODULbus carrier board, into which plugs 4
> > daughterboards. These can be CAN modules, or others. On my board, I have
> > 2x CAN modules and 1x TTL GPIO module. I need support for both of these
> > for my application. For the time being, I *did not* add support for the
> > TTL module. That will come once the CAN part is finished.
> >
> > Also, there is no way I am aware of to determine what type of board is
> > plugged into which MODULbus slot on the carrier board. My CAN modules
> > support identification, but the TTL module does not.
> >
> > I hard-coded the module layout into the driver itself. This is
> > sufficient for my purposes, but probably is not sufficient for mainline
> > Linux :'(. Any ideas or suggestions?
> I would (but I'm not authoring this) construct a PCI driver for the
> carrier board, with 4 platform devices. During probe of the PCI drivers,
> you can tweak the ID's of the platform devices.
> Next, you create seperate drivers: CAN, TTL, ....
> in drivers/mfd, you'll find some examples of what I try to explain.
>
> You will have to provide some access methods for the platform_devices.
> That's where you will link daughterboards to carrier board.
>
> And to make life simpler, you can create bigger structs for the
> platform_device, as in:
>
> struct janz_device {
> struct platform_device pdev;
> struct pci_device *carrier;
> int (*reg_rd)(struct janz_device *, etc ...);
> void (*reg_wr)(struct janz_device *, etc ...);
> ....
> };
> #defien platform_to_janz(x) container_of(x, struct janz_device, pdev)
>
> As such, a clean seperation can be made between the carrier board & the
> differen daughter boards.
>
That sounds great. I'll try and follow the drivers/mfd example you
mention.
> > Any review will be much appreciated!
> Did not get there in detail :-)
Thanks for what you have done! I'll have another version soon, with your
comments addressed.
Ira
_______________________________________________
Socketcan-core mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/socketcan-core