> On Wed, Aug 23, 2006 at 12:53:49PM -0700, David Christensen wrote: > D> This "lost interrupt" type of problem is addressed by the > use of the > D> status_tag > D> field in the status block. (Listed as bge_rsvd0 in the > bge_status_block > D> structure). > D> Everytime the status block is updated a new tag value is > written to the > D> status block. > D> When the ISR starts the driver should record the > status_tag value. At > D> the end > D> of the ISR, the driver should compare the current > status_tag value is > D> the status > D> block with the value recorded on entry to the ISR. If the > values are > D> the same > D> then no additional status block updates have occurred so > there shouldn't > D> be > D> any packets hanging around. If the values are different > then additional > D> packets > D> or completions are waiting around so the ISR should loop > around again. > D> At the > D> end of the ISR the driver will write the status_tag value it last > D> handled to a > D> mailbox register, letting the hardware know the last > status block update > D> handled. > D> If necessary the hardware will generate a new interrupt > and start the > D> process over > D> again. > D> > D> This entire process should be included in the Linux > driver, I don't see > D> it being > D> used in the bge driver (bge_intr()). > > In the Linux driver for the not tag capable controllers there > is a following > comment and code: > > /* In INTx mode, it is possible for the interrupt to arrive at > * the CPU before the status block posted prior to > the interrupt. > * Reading the PCI State register will confirm whether the > * interrupt is ours and will flush the status block. > */ > if ((sblk->status & SD_STATUS_UPDATED) || > !(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) { > > So, I tried to add (void)pci_read_config(sc->bge_dev, > BGE_PCI_PCISTATE, 4) > to the bge_intr(). Unfortunately, this didn't help. >
This fix is really designed to handle bridges that haven't posted the status block memory write ahead of the PCI interrupt and I wouldn't expect it to resolve the reported problem. A better solution would be to try and minimize the time between the last status block check and the time the interrupt is re-enabled. Unfortunately I don't think the problem can be completely eliminated with even the most creative coding solutions but I'd be happy to be proven wrong. Dave _______________________________________________ freebsd-net@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-net To unsubscribe, send any mail to "[EMAIL PROTECTED]"