From: Jouni Malinen (jkmaline_at_cc.hut.fi)
Date: 2002-07-20 08:38:50 UTC
On Fri, Jul 19, 2002 at 04:12:49PM -0700, Jun Sun wrote:
> On one of my systems, I found host ap driver caused many spurious
I haven't noticed this on any of the systems I'm using (though, I haven't really looked for it either). Is there anything special about the system that sees this?
Before using very much energy on this issue, I would first check whether it causes any real problems. I'm assuming you are using default driver configuration (i.e., compile it with cmd completion events for transmit command). In this case normal TX and RX paths do not use hfa384x_cmd() at all. In other words, hfa384x_cmd() is used only for configuration reads/writes and having few extra interrupts with these should not be a problems.
However, there is an exception for this: if you have stations using power saving, TIM bit needs to be set for every TX to that station and this will currently use hfa384x_cmd() (though, I have planned on doing a TIM set queue that would work somewhat like transmit command handling, i.e., without busy waiting command completion).
> The problem is at the end of hfa384x_cmd() function in prism2.c file:
> HFA384X_OUTW(HFA384X_EV_CMD, HFA384X_EVACK_OFF);
> spin_unlock_irqrestore(&local->cmdlock, flags);
> It appears HFA384X_OUTW() would do an interrupt acknowledgement, followed
> by immediately opening interrupts again. What might have happened is
> that interrupt acknowledge does not propagrate fast enough. So when
> interrupts are opened again, CPU still sees a pending interrupt.
> When we actually take the interrupt, the irq ack propagates to CPU
> and we found no IRQ.
Yes, this sounds possible. I don't know how long it takes for the card to remove pending interrupt indication after an individual event is ACKed, but it may well be enough for the CPU to be interrupted after spin_unlock_irqrestore.
> If this is true, is there any way we can shuffle the code around so that
> the IRQ ack happens a little earlier than the intr re-opening?
With current hfa384x_cmd() this is not really doable (apart from using extra delay which is not that nice), since it busy waits for the command completion event and then reads the response and status. These registers have to be read before ACKing the event and since there is nothing more to do in hfa384x_cmd(), interrupts will be re-enabled quite soon.
Some minor changes can be done by first reading resp0 and status to local variables and then ACK EV_CMD. After this, do res = local_resp0 & (bits) and the #ifndef final_version block before spin_unlock_irqrestore. However, this will have only a tiny delay between ACK and irq restore and might not help at all. How long delay you used to get rid of those extra interrupts?
I have planned on experimenting with quite a bit different driver structure as far as command completion is concerned, but this would change the driver quite a bit. The commands could be queued in a host-side list and then performed without busy waiting the command completion event. Interrupt handler would get the command completions and it would then issue the next pending command if one is in the queue. The interrupt handler would also call whatever code would be needed to finish handling the completed command.
Current driver does this for the transmit command, but it could be extented also for other commands. This would make the transmit command handling cleaner, but there are some problems with doing all commands without busy waiting.
Things like RID reads from code that must not sleep or return immediately would require busy waiting for the interrupt handler to get the event (and this could take a while, if the pending command queue had many entries). In addition, this would be impossible if the command would need to be done in a situation where the interrupts are disabled and an old command is being completed. Although, I do not remember whether such situations are used in the current driver code.
Changing the command completion handling completely will certainly require quite a bit of planning and testing, so it won't happen immediately. The minor changes in hfa384x_cmd() can be done (and I will probably do them even if they don't show any noticeable help since they will anyway make the interrupts disabled time a bit smaller).
-- Jouni Malinen PGP id EFC895FA