Marcelo Coelho wrote:
>> Please clean up your patches before you post. Means: no unrelated
>> changes, no uncommented old code, no unused function argument
>> (ioaddr...), etc.
> Sorry, I'm a little under pressure and sometimes I forget somethings...
> 
> This patch already has the kernel's interrupt handler routine, kind of a mix 
> between the kernel version and RTnet's one.
> But it still gives me a problem: it looks like I don't transmit anything to 
> the network, don't know why.
> 
> I'll keep on working on this. If someone finds a problem here, please let me 
> know ASAP.
> 
> 
> 
> Thanks for the help!
> Marcelo
> 
> 
> 
> 
> 
> ------------------------------------------------------------------------
> 
> Index: drivers/rt_8139too.c
> ===================================================================
> --- drivers/rt_8139too.c      (revision 1106)
> +++ drivers/rt_8139too.c      (working copy)
> @@ -379,7 +379,7 @@
>  
>  
>  /* Twister tuning parameters from RealTek.
> -   Completely undocumented, but required to tune bad links. */
> +   Completely undocumented, but required to tune bad links on some boards. */
>  enum CSCRBits {
>          CSCR_LinkOKBit = 0x0400,
>          CSCR_LinkChangeBit = 0x0800,
> @@ -595,11 +595,37 @@
>          PCIErr | PCSTimeout | RxUnderrun | RxOverflow | RxFIFOOver |
>          TxErr | TxOK | RxErr | RxOK;
>  
> +static const u16 rtl8139_norx_intr_mask =
> +        PCIErr | PCSTimeout | RxUnderrun |
> +        TxErr | TxOK | RxErr ;
> +
> +#if RX_BUF_LEN_IDX == 0
>  static const unsigned int rtl8139_rx_config =
> +        RxCfgRcv8K | RxNoWrap |
> +        (RX_FIFO_THRESH << RxCfgFIFOShift) |
> +        (RX_DMA_BURST << RxCfgDMAShift);
> +#elif RX_BUF_LEN_IDX == 1
> +static const unsigned int rtl8139_rx_config =
> +        RxCfgRcv16K | RxNoWrap |
> +        (RX_FIFO_THRESH << RxCfgFIFOShift) |
> +        (RX_DMA_BURST << RxCfgDMAShift);
> +#elif RX_BUF_LEN_IDX == 2
> +static const unsigned int rtl8139_rx_config =
>          RxCfgRcv32K | RxNoWrap |
>          (RX_FIFO_THRESH << RxCfgFIFOShift) |
>          (RX_DMA_BURST << RxCfgDMAShift);
> +#elif RX_BUF_LEN_IDX == 3
> +static const unsigned int rtl8139_rx_config =
> +        RxCfgRcv64K |
> +        (RX_FIFO_THRESH << RxCfgFIFOShift) |
> +        (RX_DMA_BURST << RxCfgDMAShift);
> +#else
> +#error "Invalid configuration for 8139_RX_BUF_LEN_IDX"
> +#endif

Can those changes be safely broken out into a separate patch? Would help
to test things independently.

>  
> +
> +
> +
>  static const unsigned int rtl8139_tx_config =
>          TxIFG96 | (TX_DMA_BURST << TxDMAShift) | (TX_RETRY << TxRetryShift);
>  
> @@ -1155,7 +1181,7 @@
>          rt_stack_connect(rtdev, &STACK_manager);
>  
>          retval = rtdm_irq_request(&tp->irq_handle, rtdev->irq,
> -                                  rtl8139_interrupt, 0, rtdev->name, rtdev);
> +                                  rtl8139_interrupt, RTDM_IRQTYPE_SHARED, 
> rtdev->name, rtdev);
>          if (retval)
>                  return retval;
>  
> @@ -1656,6 +1682,7 @@
>          }
>  }
>  
> +
>  /* The interrupt handler does all of the Rx thread work and cleans up
>     after the Tx thread. */
>  static int rtl8139_interrupt(rtdm_irq_t *irq_handle)
> @@ -1665,80 +1692,82 @@
>          struct rtnet_device *rtdev = rtdm_irq_get_arg(irq_handle, struct 
> rtnet_device);
>          struct rtl8139_private *tp = rtdev->priv;
>  
> -        int boguscnt = max_interrupt_work;
>          void *ioaddr = tp->mmio_addr;
>  
>          int ackstat;
>          int status;
>          int link_changed = 0; /* avoid bogus "uninit" warning */
>  
> -        int saved_status = 0;
> +        int handled = 0;
>  
> +
>          rtdm_lock_get(&tp->lock);
>  
> -        do {
> -                status = RTL_R16 (IntrStatus);
> +        status = RTL_R16 (IntrStatus);
>  
> -                /* h/w no longer present (hotplug?) or major error, bail */
> -                if (status == 0xFFFF)
> -                        break;
> +        /* shared irq? */
> +        if (unlikely((status & rtl8139_intr_mask) == 0))
> +                goto out;
>  
> -                if ((status &
> -                     (PCIErr | PCSTimeout | RxUnderrun | RxOverflow | 
> RxFIFOOver | TxErr | TxOK | RxErr | RxOK)) == 0)
> -                        break;
> +        handled = 1;
>  
> -                /* Acknowledge all of the current interrupt sources ASAP, but
> -                   an first get an additional status bit from CSCR. */
> -                if (status & RxUnderrun)
> -                        link_changed = RTL_R16 (CSCR) & CSCR_LinkChangeBit;
> +        /* h/w no longer present (hotplug?) or major error, bail */
> +        if (status == 0xFFFF)
> +                goto out;
>  
> -                /* The chip takes special action when we clear RxAckBits,
> -                 * so we clear them later in rtl8139_rx_interrupt
> -                 */
> -                ackstat = status & ~(RxAckBits | TxErr);
> -                RTL_W16 (IntrStatus, ackstat);
>  
> -                if (rtnetif_running (rtdev) && (status & RxAckBits)) {
> -                        saved_status |= RxAckBits;
> -                        rtl8139_rx_interrupt (rtdev, tp, ioaddr, 
> &time_stamp);
> -                }
> +        /* close possible race's with dev_close */
> +        if (!rtnetif_running(rtdev)) {
> +                RTL_W16 (IntrMask, 0);
> +                goto out;
> +        }

Hmm, that points to an existing issue of our rtl8139_close: the IRQ is
released too early. But that's "only" unrelated cleanup stuff, will fix
later.

>  
> -                /* Check uncommon events with one test. */
> -                if (status & (PCIErr | PCSTimeout | RxUnderrun | RxOverflow 
> | RxFIFOOver | RxErr)) {
> -                        rtl8139_weird_interrupt (rtdev, tp, ioaddr, status, 
> link_changed);
> -                }
>  
> -                if (rtnetif_running (rtdev) && (status & TxOK)) {
> -                        rtl8139_tx_interrupt (rtdev, tp, ioaddr);
> -                        if (status & TxErr)
> -                                RTL_W16 (IntrStatus, TxErr);
> -                        rtnetif_tx(rtdev);
> -                }
> +        /* Acknowledge all of the current interrupt sources ASAP, but
> +        an first get an additional status bit from CSCR. */
> +        if (status & RxUnderrun)
> +                link_changed = RTL_R16 (CSCR) & CSCR_LinkChangeBit;
>  
> -                if (rtnetif_running (rtdev) && (status & TxErr)) {
> -                        saved_status|=TxErr;
> -                }
> +        ackstat = status & ~(RxAckBits | TxErr);
> +        /*if (ackstat)
> +                */RTL_W16 (IntrStatus, ackstat);

???

>  
> -                boguscnt--;
> -        } while (boguscnt > 0);
> -        if (boguscnt <= 0) {
> -                rtdm_printk(KERN_WARNING "%s: Too much work at interrupt, "
> -                           "IntrStatus=0x%4.4x.\n", rtdev->name, status);
> -                /* Clear all interrupt sources. */
> -                RTL_W16 (IntrStatus, 0xffff);
> -        }
> +        /* Receive packets are processed by poll routine.
> +        If not running start it now. */
> +        if (rtnetif_running (rtdev) && (status & RxAckBits)){
> +                rtl8139_rx_interrupt (rtdev, tp, ioaddr, &time_stamp);
>  
> -        rtdm_lock_put(&tp->lock);

Again: don't move this.

>  
> -        if (saved_status & RxAckBits) {
> +                //RTL_W16_F (IntrMask, rtl8139_norx_intr_mask);

Tss, tss.

>                  rt_mark_stack_mgr(rtdev);
>          }
>  
> -        if (saved_status & TxErr) {
> -                rtnetif_err_tx(rtdev);
> +        /* Check uncommon events with one test. */
> +        if (unlikely(status & (PCIErr | PCSTimeout | RxUnderrun | RxOverflow 
> | RxFIFOOver | RxErr)))
> +                rtl8139_weird_interrupt (rtdev, tp, ioaddr,
> +                                        status, link_changed);
> +
> +        if (status & (TxOK | TxErr)) {
> +                rtl8139_tx_interrupt (rtdev, tp, ioaddr);
> +                if (status & TxErr)
> +                        RTL_W16 (IntrStatus, TxErr);
> +                rtnetif_tx(rtdev);
>          }
> +        if (rtnetif_running (rtdev) && (status & TxErr)) {
> +                        rtnetif_err_tx(rtdev);
> +        }
>  
> -        return RTDM_IRQ_HANDLED;
> +        /* This wasn't in the kernel driver, but it was in the previous rtnet
> +        driver so i put it here. */
> +        RTL_W16(IntrStatus, 0xffff);

That's from the "Too much work" error path. You don't check for this
anymore, so this clearing has to go (we may loose events otherwise).

> +        out:
> +        spin_unlock (&tp->lock);

Wrong locking primitive (recent I-pipe will bark at you). Put the
ordering like this:
- check for rx
- check for weird
- check for tx
- unlock
- if there was rx, rt_mark_stack_mgr

> +
> +
> +        if( handled == 1 )
> +                return RTDM_IRQ_HANDLED;
> +        else
> +                return RTDM_IRQ_NONE;

Save the return value directly in a local variable, saves one comparison
here.

Jan

Attachment: signature.asc
Description: OpenPGP digital signature

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier.
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
RTnet-developers mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/rtnet-developers

Reply via email to