[Prism54-devel] Re: [PATCH] for freemac

Denis Vlasenko vda at ilport.com.ua
Wed Oct 5 12:33:12 UTC 2005


On Wednesday 05 October 2005 14:55, Sebastien wrote:
> > Hmm. PCI hw does dma writes to main memory of my PC,
> > but where does it write to in USB case?
> > To NET2280 registers?
> 
> Yes. The official firmware fills the endpoint FIFO by sending data over 
> DMA to its address (see NET2280 specs, available from www.netchip.com), 
> then it flushes the FIFO by writing to registers, making the NET2280  
> emit the URB.
> 
> > In PCI world it works (at least for my PCI card).
> > Here is a freemac+7.patch:
> >
> > FreeMAC > mw 0x20000 0x88888888 0x20
> > 0002007c
> > FreeMAC > mr 0x20000 0x20
> > 00020000: 88888888 88888888 88888888 88888888
> > 00020010: 88888888 88888888 88888888 88888888
> > 00020020: 88888888 88888888 88888888 88888888
> > 00020030: 88888888 88888888 88888888 88888888
> > 00020040: 88888888 88888888 88888888 88888888
> > 00020050: 88888888 88888888 88888888 88888888
> > 00020060: 88888888 88888888 88888888 88888888
> > 00020070: 88888888 88888888 88888888 88888888
> > FreeMAC > dmaw 4 0x10
> > dma status:00000003
> > FreeMAC > dmar 0 0x20
> > 00000000: 00000001 88888888 88888888 88888888
> 
> Why do you get 00000001 instead of 88888888 ? This looks like the same 
> problem as I have...

Because I dmaw to address 4 but then I dmar from address 0
(idea was to check/demonstrate that DMA do not touch bytes
in front of target area).
 
> > They simply did not happen for me. I saw DMA rx/tx bits set in
> > 'enable IRQ' register, but they never appeared in 'trigger IRQ'
> > reg.
> 
> Did they appear in the unmasked event register for IRQs ?

No.

> > void event_handle(unsigned events)
> > {
> >         if (events & ISL38XX_EVENT_HOST) host_interrupt_recv();
> >         if (events & ISL38XX_EVENT_TXDMA) {
> >                 event_disable(ISL38XX_EVENT_TXDMA, 1);
> >                 uartpci_sendstr_nonblock("txdma complete\r\n");
> >         }
> >         if (events & ISL38XX_EVENT_RXDMA) {
> >                 event_disable(ISL38XX_EVENT_RXDMA, 1);
> >                 uartpci_sendstr_nonblock("rxdma complete\r\n");
> >         }
> > }
> >
> > Maybe my code is suboptimal. 
> 
> We probably need to rewrite all this anyway. I think we should do 
> something like that :
> - when you receive a DATA IRQ, do a blocking DMA (in interrupt handler) 
> to retreive a small header containing the size of the frame we want to 
> handle

Yes. small header containing the size _and _address_ of the frame.

> - send a DMA RX request for the full frame, and leave interrupt handler
> - when you get the DMA IRQ for the full frame, queue it somewhere for 
> the main firmware loop to handle it (I think the addresses we must send 
> to the official firmware are related to a similar system...)
> 
> Do you have any improvements for this system ? And what's the best way 
> to "queue" frame ? Perhaps we should handle frames one by one (ie. only 
> poll for new frames once the former has been processed) ?

Like this. At init time, let freemac know where small headers are
in host mem (let's call them "tx descriptor" or txdesc_in).
IOW: give freemac address of txdesc_area:

struct txdesc_in {
	int	len;
	u32	addr;
	...(rate, modulation etc)...
};
struct txdesc_out {
	int	rate_used;
	int	retry_count_used;
	...(etc)...
};

txdesc_area_in:
	u8			gen_count_in[N*4];
	struct txdesc_in	txdesc_in[N*4];

txdesc_area_out:
	u8			gen_count_out[N*4];
	struct txdesc_out	txdesc_out[N*4];

How to tx:
* host fills txdesc_in[n] and does gen_count_in[n]++.
* host sends tx irq
* freemac reads gen_count_in.
* freemac compares each gen_count_in[i] with gen_count_out[i].
* freemac reads txdesc it needs to process, if any.
* freemac does "send a DMA RX request for the full frame..." thing.
* freemac does "when you get the DMA IRQ for the full frame, queue it
  somewhere for the main firmware loop to handle" thing.
* freemac: when main loop completes tx, it does gen_count_out[n]++,
  writes gen_count_out and corresponding txdesc_out[n] to host RAM,
  then sends tx_complete irq to host.
* host compares each gen_count_out[i] with gen_count_in[i]
  and learns which one was just processed (and can be reused).

gen_count's can be bit arrays, but for now I prefer bytes.
Harder to mess up ;)

Looks a bit complicated, but in this process there is
no RAM location which is ever written by host _and_ by freemac.
Thus you do not have any syncronization/cacheline bouncing issues.

> > However, I found prism54usb a bit too big for
> > my purposes. For one, I think we should not
> > waste time trying to implement "mgmt" stuff
> > present in official firmware. Too damn complicated
> > to do in fw. But large part of prism54usb
> > is dealing exactly with that stuff.
> 
> The "mgmt stuff" is in fact the raw reading of the serial EEPROM 
> connected to the ISL38xx chip. This EEPROM stores information about the 
> device (how to interface the radio, MAC address, ...)
> We have to implement this if we want FreeMAC to do networking.
> 
> FullMAC parses the EEPROM and the driver doesn't have to care about it 
> at all. With SoftMAC, the driver must request dumps of the EEPROM, 
> block per block, reassemble them, parse the EEPROM contents and act 
> accordingly.
> What should we do in FreeMAC ?

Same thing. Let's not parse it in freemac.

> It's also time to define protocol frames' structure.
--
vda


More information about the Prism54-devel mailing list