Subject: Re: How do I allocate physically contiguous RAM?
To: Dave Huang <khym@bga.com>
From: Jason Thorpe <thorpej@nas.nasa.gov>
List: tech-kern
Date: 10/29/1997 16:24:39
On Wed, 29 Oct 97 12:37:28 WET 
 Dave Huang <khym@bga.com> wrote:

 > I'm trying to write an ethernet driver, and would like to get a 32K
 > chunk or so of page-aligned, physically contiguous memory (for DMA
 > porpoises). Is there an easy way to do this? I took a look at the
 > bus_dma stuff, but it looks like it's unimplemented on mac68k. I doubt
 > if I have the skills to implement the bus_dma interface, so I'm
 > looking for another way :)

You _really_ ought to implement bus_dma... For the mac68k port, you can
probably steal the i386 _bus_dma_* functions (the ones that don't implement
bounce buffers) and frob them only slightly.  If you want help with this,
I would be more than happy to answer any questions you might have.

I'm encouraging you to do this because the interfaces to do what you
want already exist, vm_page_alloc_memory() to allocate the raw unmapped
memory, and kmem_alloc_pageable() and pmap_enter() to map it into virtual
address space.  But, if you implemented this for your driver, you will
have nearly implemented what bus_dma does!

 > Also, where should I look for info on writing a network device driver?
 > In particular, I'm looking for info on these "mbuf chain" things, and
 > what the IFF_OACTIVE bit is supposed to mean, exactly. Any other
 > useful info would help though :)

IFF_OACTIVE means "output is active on the interface".  I.e. do not try
and transmit any more.  This is used as a signal to upper layers that
the interface is busy.  It's also used in various places within a driver
to keep from stomping on a busy interface.

The trick is knowing when to use it :-)  He're the general idea: if your
interface can only handle transmitting one packet at a time, you start
that packet transmitting, and then set IFF_OACTIVE.  However, some
interfaces can queue up multiple packets for transmission.  In this case,
you'd queue up packets until the queue is full, and then set IFF_OACTIVE
once you can't queue up any more.  In pretty much all cases, you clear
IFF_OACTIVE when you receive a "transmit complete" interrupt (or, more
generally, when more resources with which to queue packets become
available).

Mbuf chains are linked lists of buffers that make up a packet.  They're
linked together, and typically small, to make prepending and appending things
onto the packet easier.

There are several good examples of network drivers in the tree.  Some
of them are complicated, some are simple.  I'd suggest looking at the
simple ones to get a feel for how things work.  The canonical driver is
the LANCE driver, in sys/dev/ic/am7990.c.  I've done a bit of work on
the SMC91c9x driver that's in sys/dev/ic/smc91cxx.c, so I can answer
questions based on it, as well.  There's also sys/dev/ic/dp8390.c.

Jason R. Thorpe                                       thorpej@nas.nasa.gov
NASA Ames Research Center                            Home: +1 408 866 1912
NAS: M/S 258-6                                       Work: +1 650 604 0935
Moffett Field, CA 94035                             Pager: +1 415 428 6939