Esempio n. 1
0
/**************************************************************************
w89c840_poll - Wait for a frame
***************************************************************************/
static int w89c840_poll(struct nic *nic, int retrieve)
{
    /* return true if there's an ethernet packet ready to read */
    /* nic->packet should contain data on return */
    /* nic->packetlen should contain length of data */
    int packet_received = 0;

#if defined(W89C840_DEBUG)
    u32 intr_status = readl(ioaddr + IntrStatus);
#endif

    do {
        /* Code from netdev_rx(dev) */

        int entry = w840private.cur_rx % RX_RING_SIZE;

        struct w840_rx_desc *desc = w840private.rx_head_desc;
        s32 status = desc->status;

        if (status & DescOwn) {
            /* DescOwn bit is still set, we should wait for RX to complete */
            packet_received = 0;
            break;
        }

        if ( !retrieve ) {
            packet_received = 1;
            break;
        }

        if ((status & 0x38008300) != 0x0300) {
            if ((status & 0x38000300) != 0x0300) {
                /* Ingore earlier buffers. */
                if ((status & 0xffff) != 0x7fff) {
                    printf("winbond-840 : Oversized Ethernet frame spanned "
                           "multiple buffers, entry %d status %X !\n",
                           w840private.cur_rx, (unsigned int) status);
                }
            } else if (status & 0x8000) {
                /* There was a fatal error. */
#if defined(W89C840_DEBUG)
                printf("winbond-840 : Receive error, Rx status %X :", status);
                if (status & 0x0890) {
                    printf(" RXLEN_ERROR");
                }
                if (status & 0x004C) {
                    printf(", FRAME_ERROR");
                }
                if (status & 0x0002) {
                    printf(", CRC_ERROR");
                }
                printf("\n");
#endif

                /* Simpy do a reset now... */
                w89c840_reset(nic);

                packet_received = 0;
                break;
            }
        } else {
            /* Omit the four octet CRC from the length. */
            int pkt_len = ((status >> 16) & 0x7ff) - 4;

#if defined(W89C840_DEBUG)
            printf(" netdev_rx() normal Rx pkt ring %d length %d status %X\n", entry, pkt_len, status);
#endif

            nic->packetlen = pkt_len;

            /* Check if the packet is long enough to accept without copying
               to a minimally-sized skbuff. */

            memcpy(nic->packet, le32desc_to_virt(w840private.rx_ring[entry].buffer1), pkt_len);
            packet_received = 1;

            /* Release buffer to NIC */
            w840private.rx_ring[entry].status = DescOwn;

#if defined(W89C840_DEBUG)
            /* You will want this info for the initial debug. */
            printf("  Rx data %hhX:%hhX:%hhX:%hhX:%hhX:"
                   "%hhX %hhX:%hhX:%hhX:%hhX:%hhX:%hhX %hhX%hhX "
                   "%hhX.%hhX.%hhX.%hhX.\n",
                   nic->packet[0],  nic->packet[1],  nic->packet[2], nic->packet[3],
                   nic->packet[4],  nic->packet[5],  nic->packet[6], nic->packet[7],
                   nic->packet[8],  nic->packet[9],  nic->packet[10],
                   nic->packet[11], nic->packet[12], nic->packet[13],
                   nic->packet[14], nic->packet[15], nic->packet[16],
                   nic->packet[17]);
#endif

        }

        entry = (++w840private.cur_rx) % RX_RING_SIZE;
        w840private.rx_head_desc = &w840private.rx_ring[entry];
    } while (0);
    
    return packet_received;
}
Esempio n. 2
0
static int w89c840_poll(struct nic *nic)
{
    
    
    
    int packet_received = 0;

    u32 intr_status = readl(ioaddr + IntrStatus);
     

    do {
        

        int entry = w840private.cur_rx % RX_RING_SIZE;

        struct w840_rx_desc *desc = w840private.rx_head_desc;
        s32 status = desc->status;

        if (status & DescOwn) {
            
            packet_received = 0;
            break;
        }

        if ((status & 0x38008300) != 0x0300) {
            if ((status & 0x38000300) != 0x0300) {
                
                if ((status & 0xffff) != 0x7fff) {
                    printf("winbond-840 : Oversized Ethernet frame spanned "
                           "multiple buffers, entry %d status %X !\n",
                           w840private.cur_rx, status);
                }
            } else if (status & 0x8000) {
                
#if defined(W89C840_DEBUG)
                printf("winbond-840 : Receive error, Rx status %X :", status);
                if (status & 0x0890) {
                    printf(" RXLEN_ERROR");
                }
                if (status & 0x004C) {
                    printf(", FRAME_ERROR");
                }
                if (status & 0x0002) {
                    printf(", CRC_ERROR");
                }
                printf("\n");
#endif

                
                w89c840_reset(nic);

                packet_received = 0;
                break;
            }
        } else {
            
            int pkt_len = ((status >> 16) & 0x7ff) - 4;

#if defined(W89C840_DEBUG)
            printf(" netdev_rx() normal Rx pkt ring %d length %d status %X\n", entry, pkt_len, status);
#endif

            nic->packetlen = pkt_len;


            memcpy(nic->packet, le32desc_to_virt(w840private.rx_ring[entry].buffer1), pkt_len);
            packet_received = 1;

            
            w840private.rx_ring[entry].status = DescOwn;

#if defined(W89C840_DEBUG)
            
            printf("  Rx data %hhX:%hhX:%hhX:%hhX:%hhX:"
                   "%hhX %hhX:%hhX:%hhX:%hhX:%hhX:%hhX %hhX%hhX "
                   "%hhX.%hhX.%hhX.%hhX.\n",
                   nic->packet[0],  nic->packet[1],  nic->packet[2], nic->packet[3],
                   nic->packet[4],  nic->packet[5],  nic->packet[6], nic->packet[7],
                   nic->packet[8],  nic->packet[9],  nic->packet[10],
                   nic->packet[11], nic->packet[12], nic->packet[13],
                   nic->packet[14], nic->packet[15], nic->packet[16],
                   nic->packet[17]);
#endif

        }

        entry = (++w840private.cur_rx) % RX_RING_SIZE;
        w840private.rx_head_desc = &w840private.rx_ring[entry];
    } while (0);

    if (intr_status & (AbnormalIntr | TxFIFOUnderflow | IntrPCIErr |TimerInt | IntrTxStopped)) {
        handle_intr(intr_status);
    }

    return packet_received;
}