⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dec21143.c

📁 嵌入式操作系统Nucleus Plus下的以太网驱动模板
💻 C
📖 第 1 页 / 共 5 页
字号:
/*                                                                          */
/*    NU_SUCCESS is returned if no errors occur, otherwise -1 is returned.  */
/*                                                                          */
/* HISTORY                                                                  */
/*                                                                          */
/*       NAME                 DATE            REMARKS                       */
/*                                                                          */
/*  Uriah T. Pollock        01/12/99      Created initial version 1.0       */
/*                                                                          */
/****************************************************************************/
STATUS DEC21143_Open (UINT8 *ether_addr, DV_DEVICE_ENTRY *device)
{
    NET_BUFFER          *setup_frame;
    STATUS              ret_status;
    VOID                *pointer;
    UINT8               eeprom_data[128];
    UINT8               x;
    UINT32              csr6_val;
    DEC21143_XDATA      *dec_data;
    VOID                (*DEC21143_old_vect_routine)(INT);
    static INT          open_count = 0;

    /* Point at the DEC21143 xtended data. */
    dec_data = (DEC21143_XDATA *)device->user_defined_1;

    /* Collect some SNMP data */
    SNMP_ifDescr(device->dev_index, "DEC21143 Ethernet: Software revision 1.0");
    SNMP_ifType(device->dev_index, 6);
    SNMP_ifMtu(device->dev_index, device->dev_mtu);

    /* First thing, find the card and store off its PCI ID. */
    dec_data->DEC21143_PCI_ID = DEC21143_Find_PCI_ID (open_count);

    /* Make sure the card was found. */
    if (dec_data->DEC21143_PCI_ID == DEC21143_INVALID_ID)
    {
        /* Log the error and get out. */
        NU_Tcp_Log_Error (DRV_RESOURCE_ALLOCATION_ERROR, TCP_FATAL, __FILE__, __LINE__);

        return (-1);
    }


    /* Read the chip revision. Step 2.A */
    dec_data->DEC21143_Revision =
                    DEC21143_Read_PCI (dec_data->DEC21143_PCI_ID, PCI_CFRV);

    /* Read the interrupt line that will be use by this card. Step 2.B */
    device->dev_irq = (CFIT_GET_INTERRUPT_LINE &
                        DEC21143_Read_PCI (dec_data->DEC21143_PCI_ID, PCI_CFIT));

    /* Associate the device with a vector number. Compute the vector based
       on the IRQ line read from the chip. */

#ifdef PROTECTED_MODE

    if (device->dev_irq < 8)
        device->dev_vect = 0x78 + device->dev_irq;
    else
        device->dev_vect = 0x70 + (device->dev_irq - 8);

#else

    switch(device -> dev_irq)
    {
        case 3:
            device->dev_vect = IRQ_3_VECTOR;
            break;
        case 4:
            device->dev_vect = IRQ_4_VECTOR;
            break;
        case 5:
            device->dev_vect = IRQ_5_VECTOR;
            break;
        case 9:
            device->dev_vect = IRQ_9_VECTOR;
            break;
        case 10:
            device->dev_vect = IRQ_10_VECTOR;
            break;
        case 11:
            device->dev_vect = IRQ_11_VECTOR;
            break;
        case 12:
            device->dev_vect = IRQ_12_VECTOR;
            break;
        case 15:
            device->dev_vect = IRQ_15_VECTOR;
            break;
        default:
            return(-1);
    }

#endif /* defined PROTECTED_MODE */


    /* read old, load new */
    NU_Register_LISR (device->dev_vect, DEC21143_LISR,
                        &DEC21143_old_vect_routine);

    /*  The HISR can be shared by all DEC21143 devices. So only create one. */
    if (open_count++ == 0)
    {
#ifdef PROTECTED_MODE

        /* Install LISRs to handle the 77 and 7f interrupts. These
           occur during high traffic. All the LISR does is reset the
           interrupt. */
        NU_Register_LISR(IRQ_15_VECTOR, Unknown_Int_LISR, &DEC21143_old_vect_routine);
        NU_Register_LISR(UNKNOWN_INT, Unknown_Int_LISR, &DEC21143_old_vect_routine);
#endif

        /* create the HISR for handling the interrupt from the Ethernet card */
        ret_status = NU_Allocate_Memory (&System_Memory, &pointer, 2000,
                                        NU_NO_SUSPEND);
        if (ret_status != NU_SUCCESS)
        {
            NU_Tcp_Log_Error (TCP_SESS_MEM, TCP_FATAL, __FILE__, __LINE__);
            return (-1);
        }

        pointer = normalize_ptr(pointer);

        ret_status = NU_Create_HISR (&DEC21143_RX_HISR_CB, "ETHER_RX",
                                    DEC21143_RX_HISR,
                                    0, pointer, 2000);
        if (ret_status != NU_SUCCESS)
        {
            NU_Tcp_Log_Error (TCP_HRDWR_INIT, TCP_FATAL, __FILE__, __LINE__);
            return (-1);
        }

        /* create the HISR for transmitting packets */
        if (NU_Allocate_Memory (&System_Memory, &pointer, 2000,
                                NU_NO_SUSPEND) != NU_SUCCESS)
        {
            NU_Tcp_Log_Error (TCP_SESS_MEM, TCP_FATAL, __FILE__, __LINE__);
            return (-1);
        }

        pointer = normalize_ptr(pointer);

        if (NU_Create_HISR (&DEC21143_TX_HISR_CB, "ETHER_TX",
                            DEC21143_TX_HISR, 0, pointer, 2000) != NU_SUCCESS)
        {
            NU_Tcp_Log_Error (TCP_HRDWR_INIT, TCP_FATAL, __FILE__, __LINE__);
            return (-1);
        }

        /* create the HISR for renegotiating the link */
        if (NU_Allocate_Memory (&System_Memory, &pointer, 2000,
                                NU_NO_SUSPEND) != NU_SUCCESS)
        {
            NU_Tcp_Log_Error (TCP_SESS_MEM, TCP_FATAL, __FILE__, __LINE__);
            return (-1);
        }

        pointer = normalize_ptr(pointer);

        if (NU_Create_HISR (&DEC21143_Negotiate_Link_HISR_CB, "ETHER_NL",
                            DEC21143_Negotiate_Link_HISR, 0, pointer, 2000) != NU_SUCCESS)
        {
            NU_Tcp_Log_Error (TCP_HRDWR_INIT, TCP_FATAL, __FILE__, __LINE__);
            return (-1);
        }

    }

    /* Now get the base IO address, be sure to clear bit 0, this is not
       part of the address. Step 2.C */
    device->dev_io_addr = DEC21143_Read_PCI (dec_data->DEC21143_PCI_ID, PCI_CBIO);
    DEC21143_Write_PCI (dec_data->DEC21143_PCI_ID, PCI_CBIO, device->dev_io_addr);
    device->dev_io_addr &= ~0x00000003;

    /* Read in the entire EEPROM */
    for (x = 0; x < (sizeof (eeprom_data) / 2); x++)
        ((UINT16 *)eeprom_data) [x] = DEC21143_Read_EEPROM
                                    (device->dev_io_addr, x);

    /* Get the physical address from the EEPROM data just read in
       and store it in the device structure. */
    DEC21143_Get_Address(eeprom_data, ether_addr);

    /* Disable all interrupts from the DEC chip. */
    OUTDW (device->dev_io_addr + CSR7, CLEAR_ALL);

    /* Select the port before chip reset */

    /* Read the register. */
    csr6_val = INDW (device->dev_io_addr + CSR6);

    /* Turn off the transmitter and receiver and port select. */
    csr6_val &= ~(CSR6_START_TX | CSR6_START_RX | CSR6_PORT_SELECT);

    /* Write it to the register. */
    OUTDW (device->dev_io_addr + CSR6, csr6_val);

    /* Software reset of the chip, this does not reset the port
       select done above. */
    OUTDW (device->dev_io_addr + CSR0, CLEAR_ALL);
    DEC21143_Delay();
    OUTDW (device->dev_io_addr + CSR0, CSR0_SOFTWARE_RESET);
    DEC21143_Delay();
    OUTDW (device->dev_io_addr + CSR0, CLEAR_ALL);
    DEC21143_Delay();

    /* Now make sure there aren't any other bits set that we do not want. */
    csr6_val = INDW (device->dev_io_addr + CSR6);

    csr6_val &= (~(CSR6_PASS_BAD_FRAMES | CSR6_PASS_ALL_MULTICAST |
                    CSR6_FORCE_COLLISION_MODE | CSR6_IGNORE_DST_ADDRESS_MSB |
                    CSR6_RX_ALL | CSR6_TX_THRESHOLD_MODE |
                    CSR6_PROMISCUOUS_MODE));

    /* Write it to the register. */
    OUTDW (device->dev_io_addr + CSR6, csr6_val);

    /* After the reset wake the chip up. */
    DEC21143_Write_PCI (dec_data->DEC21143_PCI_ID, PCI_CFDD, CLEAR_ALL);

    /* Set the chip to accept register accesses and to have the ability
       to take master operation of the PCI bus. Step 2.D */
    DEC21143_Write_PCI (dec_data->DEC21143_PCI_ID, PCI_CFCS,
                                        (CFCS_IO_SPACE_ACCESS       |
                                            CFCS_MASTER_OPERATION   |
                                            CFCS_PARITY_ERROR_RESPONSE));

    /* Set the cache line size to zero and the latency timer to max,
       0xFF. Step 2.E */
    DEC21143_Write_PCI (dec_data->DEC21143_PCI_ID, PCI_CFLT, CFLT_INITIALIZE);

    /* Set the cache alignment and burst length and reset all other
       bits. Step 3 */
    OUTDW (device->dev_io_addr + CSR0, (CSR0_CACHE_ALIGNMENT_16 |
                                        CSR0_BURST_LENGTH_16));

    /* Turn on the interrupts that we want to handle and mask those
       that we don't. Step 4*/
    OUTDW (device->dev_io_addr + CSR7, DEC21143_INTERRUPTS);

    /* Initialize the RX buffer descriptor and set its base address.
       Step 5 */
    dec_data->DEC21143_First_RX_Descriptor =
    dec_data->DEC21143_Current_RX_Descriptor =
                    DEC21143_Allocate_Descriptor (DEC21143_MAX_RX_DESCRIPTORS,
                                                    &System_Memory,
                                                    NU_TRUE);

    /* Make sure the allocation worked. */
    if (dec_data->DEC21143_First_RX_Descriptor)

        /* Store the base address. */
        OUTDW (device->dev_io_addr + CSR3, (UINT32) (dec_data->DEC21143_First_RX_Descriptor));
    else
    {
        /* Log the error and get out. */
        NU_Tcp_Log_Error (DRV_RESOURCE_ALLOCATION_ERROR, TCP_FATAL, __FILE__, __LINE__);

        return (-1);
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -