示例#1
0
/**************************************************************************
w89c840_disable - Turn off ethernet interface
***************************************************************************/
static void w89c840_disable ( struct nic *nic ) {

    w89c840_reset(nic);

    /* Don't know what to do to disable the board. Is this needed at all? */
    /* Yes, a live NIC can corrupt the loaded memory later [Ken] */
    /* Stop the chip's Tx and Rx processes. */
    writel(w840private.csr6 &= ~0x20FA, ioaddr + NetworkConfig);
}
示例#2
0
struct nic *w89c840_probe(struct nic *nic, unsigned short *probe_addrs, struct pci_device *p)
{
    u16 sum = 0;
    int i, j, to;
    unsigned short value;
    int options;
    int promisc;

    if (probe_addrs == 0 || probe_addrs[0] == 0)
        return 0;

    ioaddr = probe_addrs[0]; 

#if defined(W89C840_DEBUG)
    printf("winbond-840: PCI bus %hhX device function %hhX: I/O address: %hX\n", p->bus, p->devfn, ioaddr);
#endif

    ioaddr = ioaddr & ~3; 

    

    
    if (p->vendor == PCI_VENDOR_ID_WINBOND2
        && p->dev_id == PCI_DEVICE_ID_WINBOND2_89C840) {

        

    } else if ( p->vendor == PCI_VENDOR_ID_COMPEX
                && p->dev_id == PCI_DEVICE_ID_COMPEX_RL100ATX) {

        

    } else {
        
        printf("device ID : %X - is not a Compex RL100ATX NIC.\n", p->dev_id);
        return 0;
    }

    printf(" %s\n", w89c840_version);

    adjust_pci_device(p);

    
    for (j = 0, i = 0; i < 0x40; i++) {
        value = eeprom_read(ioaddr, i);
        eeprom[i] = value;
        sum += value;
    }

    for (i=0;i<ETH_ALEN;i++) {
        nic->node_addr[i] =  (eeprom[i/2] >> (8*(i&1))) & 0xff;
    }
    printf ("Ethernet addr: %!\n", nic->node_addr);

#if defined(W89C840_DEBUG)
    printf("winbond-840: EEPROM checksum %hX, got eeprom", sum);
#endif

    writel(0x00000001, ioaddr + PCIBusCfg);

    if (driver_flags & CanHaveMII) {
        int phy, phy_idx = 0;
        for (phy = 1; phy < 32 && phy_idx < 4; phy++) {
            int mii_status = mdio_read(ioaddr, phy, 1);
            if (mii_status != 0xffff  &&  mii_status != 0x0000) {
                w840private.phys[phy_idx++] = phy;
                w840private.advertising = mdio_read(ioaddr, phy, 4);

#if defined(W89C840_DEBUG)
                printf("winbond-840 : MII PHY found at address %d, status "
                       "%X advertising %hX.\n", phy, mii_status, w840private.advertising);
#endif

            }
        }

        w840private.mii_cnt = phy_idx;

        if (phy_idx == 0) {
                printf("winbond-840 : MII PHY not found -- this device may not operate correctly.\n");
        }
    }

    
    nic->reset = w89c840_reset;
    nic->poll = w89c840_poll;
    nic->transmit = w89c840_transmit;
    nic->disable = w89c840_disable;

    w89c840_reset(nic);

    return nic;
}
示例#3
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;
}
示例#4
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;
}