rtl8139 NIC IRQ is 0 on m758lmr+ mainboard

Steve M. Gehlbach steve at nexpath.com
Wed Feb 12 22:59:01 CET 2003


> eth1: RTL8139 Interrupt line blocked, status 1.
>
> Could you give me some advice to resolve them?
>
>
> riskin

You can delete the route table stuff as it is not used in 2.2 and will work
as per standard linuxbios (irq_tables.c) in 2.4.  The forced routing was
only necessary for the stpc which the Linux kernel does not support.

As for INTA/B/C/D, this is strictly a motherboard wiring issue.  Each PCI
plug-in card connects to an interrupt line (if it uses one),  these are
called in the pci spec as PIRQA,B,C,D. The plug in card usually only uses
one, typically. That line is wired from the slot on the motherboard to a
corresponding INT line of the bridge (ie, the sis630), these are called
INTA,B,C,D. For example, on the Sis630, INTA is pin K5, INTB is pin J5, etc.
The wiring is cycled around on the motherboard and the slots to equalize the
use of the interrupts.  Which PIRQ the card hooks to depends on the card
design.  You need to program the sis630 to tell it which INTA,B,C,D should
be hooked to which conventional interrupt line, irq 10,11, etc (this is
calling routing).  Further, you need to inform the Linux driver which irq to
use as well.

Reading the INTERRUPT_PIN PCI register (of the plug-in card) reports which
PIRQ is being used by the card, if it is non-zero.  You then program the
INTERRUPT_LINE register (on the card), based on the motherboard wiring, and
router programming, to indicate which IRQ this PIRQ ultimately leads to.  It
appears to me that the INTERRUPT_LINE register as programmed for 2.2 is
simply informational to the Linux driver, and not actually used by the card.
I may have that wrong, though, I am not an expert on PCI.  But it does not
seem to be used on 2.4 at all.

I think the problem is you have programmed the RTL8139 PCI register, but you
have not programmed the routing of PIRQ->interrupt in the bridge, and you
really don't know the motherboard wiring.  So the driver gets the IRQ, but
it doesn't actually work (not routed).  You are not sure whether it is
INTA,B,C or D.  You could figure this out by running 2.4 and getting the
routing table, but you could also experiment and figure it out.  Net cards
are perfect for this experiment since they simply won't work without an IRQ
but yet they don't seem to hang or crash Linux otherwise.

The bridge can be programmed as detailed in the 2.4 kernel, in
arch/i386/kernel/pci_irq.c, for the sis chip.  The vendor id is 1039H and
the device id is 0008H, known as the LPC Bridge portion of the sis630, and
the registers are 0x41-44 corresponding to INTA-D.

The 2.4 code relevant to the sis is pretty short, and is quoted below.  I
think the comment about values 1-4 is how the BIOS routing table is written,
and has nothing to do with the sis bridge.

/*
 *      PIRQ routing for SiS 85C503 router used in several SiS chipsets
 *      According to the SiS 5595 datasheet (preliminary V1.0, 12/24/1997)
 *      the related registers work as follows:
 *
 *      general: one byte per re-routable IRQ,
 *               bit 7      IRQ mapping enabled (0) or disabled (1)
 *               bits [6:4] reserved
 *               bits [3:0] IRQ to map to
 *                   allowed: 3-7, 9-12, 14-15
 *                   reserved: 0, 1, 2, 8, 13
 *
 *      individual registers in device config space:
 *
 *      0x41/0x42/0x43/0x44:    PCI INT A/B/C/D - bits as in general case
 *
 *      0x61:                   IDEIRQ: bits as in general case - but:
 *                              bits [6:5] must be written 01
 *                              bit 4 channel-select primary (0), secondary
(1)
 *
 *      0x62:                   USBIRQ: bits as in general case - but:
 *                              bit 4 OHCI function disabled (0), enabled
(1)
 *
 *      0x6a:                   ACPI/SCI IRQ - bits as in general case
 *
 *      0x7e:                   Data Acq. Module IRQ - bits as in general
case
 *
 *      Apparently there are systems implementing PCI routing table using
both
 *      link values 0x01-0x04 and 0x41-0x44 for PCI INTA..D, but register
offsets
 *      like 0x62 as link values for USBIRQ e.g. So there is no simple
 *      "register = offset + pirq" relation.
 *      Currently we support PCI INTA..D and USBIRQ and try our best to
handle
 *      both link mappings.
 *      IDE/ACPI/DAQ mapping is currently unsupported (left untouched as set
by BIOS).
 */
static int pirq_sis_set(struct pci_dev *router, struct pci_dev *dev, int
pirq, int irq)
{
        u8 x;
        int reg = pirq;

        switch(pirq) {
                case 0x01:
                case 0x02:
                case 0x03:
                case 0x04:
                        reg += 0x40;
                case 0x41:
                case 0x42:
                case 0x43:
                case 0x44:
                case 0x62:
                        x = (irq&0x0f) ? (irq&0x0f) : 0x80;
                        if (reg != 0x62)
                                break;
                        /* always mark OHCI enabled, as nothing else knows
about this */
                        x |= 0x40;
                        break;
                case 0x61:
                case 0x6a:
                case 0x7e:
                        printk(KERN_INFO "advanced SiS pirq mapping not yet
implemented\n");
                        return 0;
                default:
                        printk(KERN_INFO "SiS router pirq escape (%d)\n",
pirq);
                        return 0;
        }
        pci_write_config_byte(router, reg, x);

        return 1;
}

Hope I got all this right, I am sure if I didn't someone will point it out.

Basically, set INTA-D to irq11, program irq11 on the card, and it should
work.  Or, set A to 9, B to 10, etc., and then try setting the irqs on the
card one at a time until it works.  Do this on all slots and you can get the
wiring.  Very tedious, though.

-Steve




More information about the coreboot mailing list