[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