Example #1
0
static void handle_intr(u32 intr_stat)
{
    if ((intr_stat & (NormalIntr|AbnormalIntr)) == 0) {
        /* we are polling, do not return now */
        /*return 0;*/
    } else {
        /* Acknowledge all of the current interrupt sources ASAP. */
        writel(intr_stat & 0x001ffff, ioaddr + IntrStatus);
    }

    if (intr_stat & AbnormalIntr) {
        /* There was an abnormal interrupt */
        printf("\n-=- Abnormal interrupt.\n");

#if defined(W89C840_DEBUG)
        decode_interrupt(intr_stat);
#endif

        if (intr_stat & RxNoBuf) {
            /* There was an interrupt */
            printf("-=- <=> No receive buffers available.\n");
            writel(0, ioaddr + RxStartDemand);
        }
    }
}
Example #2
0
static void handle_intr(u32 intr_stat)
{
    if ((intr_stat & (NormalIntr|AbnormalIntr)) == 0) {
        
        
    } else {
        
        writel(intr_stat & 0x001ffff, ioaddr + IntrStatus);
    }

    if (intr_stat & AbnormalIntr) {
        
        printf("\n-=- Abnormal interrupt.\n");

#if defined (W89C840_DEBUG)
        decode_interrupt(intr_stat);
#endif

        if (intr_stat & RxNoBuf) {
            
            printf("-=- <=> No receive buffers available.\n");
            writel(0, ioaddr + RxStartDemand);
        }
    }
}
Example #3
0
static void w89c840_transmit(
    struct nic *nic,
    const char *d,            /* Destination */
    unsigned int t,            /* Type */
    unsigned int s,            /* size */
    const char *p)            /* Packet */
{
    /* send the packet to destination */
    unsigned entry;
    int transmit_status;
    unsigned long ct;

    /* Caution: the write order is important here, set the field
       with the "ownership" bits last. */

    /* Fill in our transmit buffer */
    entry = w840private.cur_tx % TX_RING_SIZE;

    memcpy (w89c840_buf.tx_packet, d, ETH_ALEN);    /* dst */
    memcpy (w89c840_buf.tx_packet + ETH_ALEN, nic->node_addr, ETH_ALEN);/*src*/

    *((char *) w89c840_buf.tx_packet + 12) = t >> 8;    /* type */
    *((char *) w89c840_buf.tx_packet + 13) = t;

    memcpy (w89c840_buf.tx_packet + ETH_HLEN, p, s);
    s += ETH_HLEN;

    while (s < ETH_ZLEN)
    *((char *) w89c840_buf.tx_packet + ETH_HLEN + (s++)) = 0;

    w840private.tx_ring[entry].buffer1
	    = virt_to_le32desc(w89c840_buf.tx_packet);

    w840private.tx_ring[entry].length = (DescWholePkt | (u32) s);
    if (entry >= TX_RING_SIZE-1)         /* Wrap ring */
        w840private.tx_ring[entry].length |= (DescIntr | DescEndRing);
    w840private.tx_ring[entry].status = (DescOwn);
    w840private.cur_tx++;

    w840private.tx_q_bytes = (u16) s;
    writel(0, ioaddr + TxStartDemand);

    /* Work around horrible bug in the chip by marking the queue as full
       when we do not have FIFO room for a maximum sized packet. */

    if ((w840private.drv_flags & HasBrokenTx) && w840private.tx_q_bytes > TX_BUG_FIFO_LIMIT) {
        /* Actually this is left to help finding error tails later in debugging...
         * See Linux kernel driver in winbond-840.c for details.
         */
        w840private.tx_full = 1;
    }

#if defined(W89C840_DEBUG)
    printf("winbond-840 : Transmit frame # %d size %d queued in slot %d.\n", w840private.cur_tx, s, entry);
#endif

    /* Now wait for TX to complete. */
    transmit_status = w840private.tx_ring[entry].status;

    ct = currticks();
    {
#if defined W89C840_DEBUG
        u32 intr_stat = 0;
#endif
        while (1) {

#if defined(W89C840_DEBUG)
	      decode_interrupt(intr_stat);
#endif

                while ( (transmit_status & DescOwn) && ct + TX_TIMEOUT < currticks()) {

                    transmit_status = w840private.tx_ring[entry].status;
                }

                break;
        }
    }

    if ((transmit_status & DescOwn) == 0) {

#if defined(W89C840_DEBUG)
        printf("winbond-840 : transmission complete after wait loop iterations, status %X\n",
                w840private.tx_ring[entry].status);
#endif

        return;
    }

    /* Transmit timed out... */

    printf("winbond-840 : transmission TIMEOUT : status %X\n", 
	   (unsigned int) w840private.tx_ring[entry].status);

    return;
}
Example #4
0
static void w89c840_transmit(
    struct nic *nic,
    const char *d,            
    unsigned int t,            
    unsigned int s,            
    const char *p)            
{
    
    unsigned entry;
    int transmit_status;


    
    entry = w840private.cur_tx % TX_RING_SIZE;

    memcpy (tx_packet, d, ETH_ALEN);    
    memcpy (tx_packet + ETH_ALEN, nic->node_addr, ETH_ALEN);

    *((char *) tx_packet + 12) = t >> 8;    
    *((char *) tx_packet + 13) = t;

    memcpy (tx_packet + ETH_HLEN, p, s);
    s += ETH_HLEN;

    while (s < ETH_ZLEN)
    *((char *) tx_packet + ETH_HLEN + (s++)) = 0;

    w840private.tx_ring[entry].buffer1 = virt_to_le32desc(tx_packet);

    w840private.tx_ring[entry].length = (DescWholePkt | s);
    if (entry >= TX_RING_SIZE-1)         
        w840private.tx_ring[entry].length |= (DescIntr | DescEndRing);
    w840private.tx_ring[entry].status = (DescOwn);
    w840private.cur_tx++;

    w840private.tx_q_bytes += s;
    writel(0, ioaddr + TxStartDemand);


    if ((w840private.drv_flags & HasBrokenTx) && w840private.tx_q_bytes > TX_BUG_FIFO_LIMIT) {
        w840private.tx_full = 1;
    }

#if defined(W89C840_DEBUG)
    printf("winbond-840 : Transmit frame # %d size %d queued in slot %d.\n", w840private.cur_tx, s, entry);
#endif

    
    transmit_status = w840private.tx_ring[entry].status;

    load_timer2(TX_TIMEOUT);

    {
        u32 intr_stat = 0;

        while (1) {

            intr_stat = readl(ioaddr + IntrStatus);
#if defined(W89C840_DEBUG)
            decode_interrupt(intr_stat);
#endif

            if (intr_stat & (NormalIntr | IntrTxDone)) {

                while ( (transmit_status & DescOwn) && timer2_running()) {

                    transmit_status = w840private.tx_ring[entry].status;
                }

                writel(intr_stat & 0x0001ffff, ioaddr + IntrStatus);
                break;
            }
        }
    }

    if ((transmit_status & DescOwn) == 0) {

#if defined(W89C840_DEBUG)
        printf("winbond-840 : transmission complete after %d wait loop iterations, status %X\n",
               TX_LOOP_COUNT - transmit_loop_counter, w840private.tx_ring[entry].status);
#endif

        return;
    }

    

    printf("winbond-840 : transmission TIMEOUT : status %X\n", w840private.tx_ring[entry].status);

    return;
}