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

📄 lan9118.c

📁 2410平台vxworks下的lan9118驱动。
💻 C
📖 第 1 页 / 共 4 页
字号:
    /* check chip id. */    temp_u32 = lan9118_reg_read(LAN9118_REG_OFFSET_ID_REV);    if ((temp_u32 & LAN9118_REG_ID_REV_ID_MASK)        != LAN9118_REG_ID_REV_VALUE) {        printf("Failed to read the ID of the lan9118 when open it!!!!\n");        return -1;    }    /* check chip power mode, wait for chip ready. */    temp_u32 = lan9118_reg_read(LAN9118_REG_OFFSET_PMT_CTRL);    if ((temp_u32&0x00003000) != 0) {        lan9118_reg_write(LAN9118_REG_OFFSET_BYTE_TEST, (U32)0); /* wake up. */        lan9118_local_delay(click/100); /* delay 10ms. */        temp_int = LAN9118_PHY_TIMEOUT;        temp_u32 = lan9118_reg_read(LAN9118_REG_OFFSET_PMT_CTRL);        while (temp_int--) {            temp_u32 = lan9118_reg_read(LAN9118_REG_OFFSET_PMT_CTRL);            if (temp_u32 & 1) {                /* ready. */                break;            }            lan9118_local_delay(click/1000); /* delay 1ms. */            temp_int--;        }        temp_u32 = lan9118_reg_read(LAN9118_REG_OFFSET_PMT_CTRL);        if ((temp_u32&1) == 0) {            printf("lan9118 PHY not ready!!\n");            return -1;        }    }    temp_u32 = lan9118_reg_read(LAN9118_REG_OFFSET_PMT_CTRL);    if ((temp_u32&1) == 0) {        printf("lan9118 PHY not ready!!\n");        return -1;    }    /* initialize the tx/rx buffer */    /* set the TX FIFO size. */    /*lan9118_reg_write(LAN9118_REG_OFFSET_HW_CFG, 0x00040000);*/ /* 4Kbytes. */    /* setup automatic flow control. */    lan9118_reg_write(LAN9118_REG_OFFSET_AFC_CFG, 0x8c4601);    /* enable LED. */    lan9118_reg_write(LAN9118_REG_OFFSET_GPIO_CFG, 0x70000000);    /* disable interrupt. */    lan9118_reg_write(LAN9118_REG_OFFSET_INT_EN, 0);    lan9118_reg_write(LAN9118_REG_OFFSET_INT_STS, 0xffffffff);    /* enable flow control. */    lan9118_mac_reg_write(LAN9118_REG_SUBOFFSET_FLOW, 0xffff0002);    /* setup mac address. 00-40-45-1b-d2-0d */    lan9118_mac_reg_write(LAN9118_REG_SUBOFFSET_ADDRH, 0x00000dd2);    lan9118_mac_reg_write(LAN9118_REG_SUBOFFSET_ADDRL, 0x1b454000);    /* dump t/rx data. */    lan9118_reg_write(LAN9118_REG_OFFSET_TX_CFG, 0x0000c000);    lan9118_reg_write(LAN9118_REG_OFFSET_RX_CFG, 0x00008000);    /* setup parameters. */    /* TX: */    temp_u32 = lan9118_reg_read(LAN9118_REG_OFFSET_HW_CFG);    temp_u32 &= 0x000f0000;    temp_u32 |= 0x00100000;    lan9118_reg_write(LAN9118_REG_OFFSET_HW_CFG, temp_u32);    temp_u32 = lan9118_reg_read(LAN9118_REG_OFFSET_INT_EN);    temp_u32 |= 0x00002000;    lan9118_reg_write(LAN9118_REG_OFFSET_INT_EN, temp_u32);    temp_u32 = lan9118_mac_reg_read(LAN9118_REG_SUBOFFSET_MAC_CR);    temp_u32 = 0x80000008;    /* temp_u32 |= 0x00000800; reject broadcast frame. */    lan9118_mac_reg_write(LAN9118_REG_SUBOFFSET_MAC_CR, temp_u32);    /* RX: */    lan9118_reg_write(LAN9118_REG_OFFSET_RX_CFG, 0);    temp_u32 = lan9118_mac_reg_read(LAN9118_REG_SUBOFFSET_MAC_CR);    temp_u32 |= 0x00000004;    lan9118_mac_reg_write(LAN9118_REG_SUBOFFSET_MAC_CR, temp_u32);    temp_u32 = lan9118_reg_read(LAN9118_REG_OFFSET_FIFO_INT);    temp_u32 &= 0xffff0000;    lan9118_reg_write(LAN9118_REG_OFFSET_FIFO_INT, temp_u32);    temp_u32 = lan9118_reg_read(LAN9118_REG_OFFSET_INT_EN);    temp_u32 |= 0x00004008;    lan9118_reg_write(LAN9118_REG_OFFSET_INT_EN, temp_u32);    /* PHY: */    temp_u32 = ((((U32)(lan9118_phy_reg_read(LAN9118_REG_SUBOFFSET_PHY_Identifier2)))<<16)&0xffff0000);    temp_u32 |= (((U32)(lan9118_phy_reg_read(LAN9118_REG_SUBOFFSET_PHY_Identifier1)))&0x0000ffff);    if (temp_u32 == 0xc0d10007) {        /* reset physical. */        lan9118_phy_reg_write(LAN9118_REG_SUBOFFSET_Basic_Control_Register, 0x8000);        lan9118_local_delay(click/10); /* wait 100ms. */        temp_int = LAN9118_PHY_TIMEOUT;        while (temp_int) {            if (lan9118_phy_reg_read(LAN9118_REG_SUBOFFSET_Basic_Control_Register) & 0x8000) {                temp_int -= 1;            } else {                break;            }        }        if (temp_int == 0) {            return -1; /* reset incomplete with timeout. */        }        /* setup&start automatic negotiation. */        temp_u16 = lan9118_phy_reg_read(LAN9118_REG_SUBOFFSET_Auto_Negotiation_Advertisement_Register);        temp_u16 &= ~0x0c00;    /* no pause. */        temp_u16 |= 0x0c00;     /* both symmetric and asymmetric pause. */        temp_u16 |= 0x01e0;     /* 10/100M and Half/Full duplex. */        lan9118_phy_reg_write(LAN9118_REG_SUBOFFSET_Auto_Negotiation_Advertisement_Register, temp_u16);        lan9118_local_delay(click/100); /* delay 10ms. */        temp_u16 = lan9118_phy_reg_read(LAN9118_REG_SUBOFFSET_Basic_Control_Register);        temp_u16 |= 0x2100;     /* 2:100M, 1:full-duplex. */        lan9118_phy_reg_write(LAN9118_REG_SUBOFFSET_Basic_Control_Register, temp_u16);        lan9118_local_delay(click/100); /* delay 10ms. */        temp_u16 = lan9118_phy_reg_read(LAN9118_REG_SUBOFFSET_Basic_Control_Register);        temp_u16 |= 0x1200;     /* 1:enable auto negotiation, 2:restart negotiation. */        lan9118_phy_reg_write(LAN9118_REG_SUBOFFSET_Basic_Control_Register, temp_u16);        lan9118_local_delay(click/100); /* delay 10ms. */        temp_int = 10*3;    /* 3s */        while (temp_int) {   /* whether the negotiation complete? */            temp_int -= 1;            lan9118_local_delay(click/10);            temp_u16 = lan9118_phy_reg_read(LAN9118_REG_SUBOFFSET_Basic_Status_Register);            if (temp_u16 & 0x0020) {                break;  /* complete. */            }        }        temp_u16 = lan9118_phy_reg_read(LAN9118_REG_SUBOFFSET_Basic_Status_Register);        if ((temp_u16 & 0x0020) == 0) {            printf("Negotiation timeout!!!\n");            return -1;        }        temp_u16 = lan9118_phy_reg_read(LAN9118_REG_SUBOFFSET_Basic_Status_Register);        if ((temp_u16 & 0x0004) == 0) {            printf("Warning, link down!!!\nPlease plug.");        } else {            temp_u16 = lan9118_phy_reg_read(LAN9118_REG_SUBOFFSET_PHY_Special_Control_Status_Register);            temp_u16 = temp_u16 >> 2;            temp_u16 &= 0x0007;            switch (temp_u16) {            case 0x01:                printf("Auto-negotiation complete, 10Base-T, half duplex.\n");                break;            case 0x02:                printf("Auto-negotiation complete, 100Base-TX, half duplex.\n");                break;            case 0x05:                printf("Auto-negotiation complete, 10Base-T, full duplex.\n");                break;            case 0x06:                printf("Auto-negotiation complete, 100Base-TX, full duplex.\n");                break;            default:                printf("Auto-negotiation complete, unknown!!\n");;            }        }        /* If full duplex, the enable full duplex in MAC. */        temp_u16 = lan9118_phy_reg_read(LAN9118_REG_SUBOFFSET_Auto_Negotiation_Advertisement_Register);        temp_u16 &= lan9118_phy_reg_read(LAN9118_REG_SUBOFFSET_Auto_Negotiation_Link_Partner_Ability_Register);        if (temp_u16 & 0x0140) {            temp_u32 = lan9118_mac_reg_read(LAN9118_REG_SUBOFFSET_MAC_CR);            temp_u32 |= 0x00100000;            lan9118_mac_reg_write(LAN9118_REG_SUBOFFSET_MAC_CR, temp_u32);        }    } else {        printf("Unknown PHY-ID: 0x%x", temp_u32);        return -1;    }    return 0;}/* lan9118_send - send array via lan9118 with interrupt. */int tx_package_tag = 0;int transmit_busy_wait_time = 2000;int lan9118_send(U32 * p_src, int length){    int i;    union_tx_command_a tx_command_a;    union_tx_command_b tx_command_b;    union_tx_status tx_status;    U32 temp_u32;        tx_status.data = lan9118_reg_read(LAN9118_REG_OFFSET_TX_STATUS);    if (dt) {        if (tx_status.bits.error_status) {            printf("tx error: \n");            if (tx_status.bits.loss_of_carrier) {                printf("\tloss of carrier!!!\n");            }            if (tx_status.bits.no_carrier) {                printf("\tno carrier!!!\n");            }            if (tx_status.bits.late_collision) {                printf("\tlate_collision!!!\n");            }            if (tx_status.bits.excessive_collision) {                printf("\texcessive collision!!!\n");            }            if (tx_status.bits.excessive_deferral) {                printf("\texcessive deferral!!!\n");            }            if (tx_status.bits.underrun_error) {                printf("\tunderrun error!!!\n");            }        }    }    temp_u32 = lan9118_reg_read(LAN9118_REG_OFFSET_TX_FIFO_INF);    i = transmit_busy_wait_time;    while ((temp_u32 & 0x0000ffff) < (length + 16)) {        if (i == 0) {            printf("LAN9118 TX buffer: %d\n", temp_u32 & 0x0000ffff);            printf("vxWorks want: %d", length + 16);            return 0;        }        i--;        temp_u32 = lan9118_reg_read(LAN9118_REG_OFFSET_TX_FIFO_INF);    }    tx_command_a.data = 0;    tx_command_b.data = 0;    if (length > END_BUFSIZ) {        length = END_BUFSIZ;    }    tx_package_tag += 1;    tx_command_a.bits.interrupt_on_completion = 0;    tx_command_a.bits.buffer_size = length;    tx_command_a.bits.first_segment = 1;    tx_command_a.bits.last_segment = 1;    tx_command_a.bits.data_start_offset = ((U32)p_src)&0x3;  /* align, 0,1,2,3 */    tx_command_b.bits.package_tag = tx_package_tag;    tx_command_b.bits.package_length = length;    lan9118_reg_write(LAN9118_REG_OFFSET_TX_DATA, tx_command_a.data);    lan9118_reg_write(LAN9118_REG_OFFSET_TX_DATA, tx_command_b.data);    for(i = (length+3)/4; i > 0; i--) {        lan9118_reg_write(LAN9118_REG_OFFSET_TX_DATA, *p_src);        p_src++;    }    /* set the TX_ON of TX_CFG. */    lan9118_reg_write(LAN9118_REG_OFFSET_TX_CFG, 0x00000002);    if (dt) {        printf("tx %d.", length);    }    return length;}/* lan9118_receive - get any package from buffer. */int lan_recv_garbage = 4;int miss_rx_overflow_count = 0;int get_rx = 0;int lan9118_receive(END_DEVICE * pDrvCtrl){    U32 rx_fifo_inf = 0;    U8 rxsused = 0;    union_rx_status rx_status;    int i, length, temp_int;    U32 * p_u32;    U16 * p_u16;    U8 p_char[END_BUFSIZ];    STATUS temp_status;    pDrvCtrl->do_rx = 0;    while(1) {        /* get receive fifo information. */        rx_fifo_inf = lan9118_reg_read(LAN9118_REG_OFFSET_RX_FIFO_INF);        rxsused = (U8)((rx_fifo_inf>>16)&0x000000ff);        if (rxsused) { /* there're any package in the buffer. */            rx_status.data = lan9118_reg_read(LAN9118_REG_OFFSET_RX_STATUS);            length = (int)(rx_status.bits.package_length);            if (length > END_BUFSIZ) {                printf("Error, package large than 1520!!!\n Reset the net.\n");                lan9118Reset(pDrvCtrl);                return -1;            }            /* receive data from lan9118 rx fifo. */            temp_int = end_rx_frame_put(length);            if (temp_int == -1) {                printf("Error, netLibBuf overflow!!!\n");                return -1;            } else {                pDrvCtrl->do_rx += 1;                get_rx += 1;            }            /* display. */            if (drcc) {                display_rx_frame = 1;            } else {                display_rx_frame = 0;            }            if (drc) {                if ((p_u32[0] == 0x1b454000) && ((p_u32[1]&0xffff) == 0xdd2)) {                    display_rx_frame = 1;                } else {                    display_rx_frame = 0;                }            }            if (display_rx_frame) {                p_u16 = (U16 *)p_u32;                printf("\n");                for (i = 1; i <= length; i++) {                    printf("0x%02x ", p_char[i-1]);                    if (!(i%16))                        printf("\n");                }            	printf("\n");            }            if (dr) {                printf("rx %d\n", length);            }            /* error info. */            if (rx_status.bits.filtering_fail) {                printf("Error: net-rx filtering fail!!!\n");            }            if (rx_status.bits.error_status) {                if (rx_status.bits.runt_frame) {                    printf("Error: net-rx runt frame!!!\n");                }                if (rx_status.bits.frame_too_long) {                    printf("Error: net-rx frame too long!!!\n");                }                if (rx_status.bits.collision_seen) {                    printf("Error: net-rx collision seen!!!\n");                }                if (rx_status.bits.crc_error) {                    printf("Error: net-rx crc error!!!\n");                }            }            if (rx_status.bits.broadcast_frame) {                /* printf("Info: receive broadcast frame.\n"); */            }            if (rx_status.bits.length_error) {                printf("Error: net-rx length error!!!\n");            }            if (rx_status.bits.multicast_frame) {                /*printf("Info: receive multicast frame.\n"); */            }            if (rx_status.bits.frame_type) {               /* printf("Info: receive ethernet frame.\n"); */            } else {                /* printf("Info: receive 802.3 frame.\n"); */            }            if (rx_status.bits.receive_watchdog_time_out) {                printf("Error: net-rx receive watchdog time out!!!\n");            }            if (rx_status.bits.mii_error) {                printf("Error: net-rx mii error!!!\n");            }            if (rx_status.bits.dribbling_bit) {                printf("Error: net-rx dribbling bit!!!\n");            }            /* printf("Receive %d bytes.\n\n", rx_status.bits.package_length); */        } else { /* There's nothing in the buffer. */            break;        }    }    if (pDrvCtrl->do_rx) {        netJobAdd ((FUNCPTR)lan9118RecvInt,                        (int)pDrvCtrl,                        pDrvCtrl->do_rx,                        0,0,0);    }    return length;}/* * lan9118Load - initialize the driver and device * * This routine initializes the driver and the device to the operational state. * All of the device specific parameters are passed in the initString. * * The string contains the target specific parameters like this: * * "register addr:int vector:int level:shmem addr:shmem size:shmem width" * * This routine can be called in two modes.  If it is called with an empty but * allocated string, it places the name of this device into the <initString> * and returns 0. * * If the string is allocated and not empty, the routine attempts to load * the driver using the values specified in the string. * * RETURNS: An END object pointer, or NULL on error, or 0 and the name of the * device if the <initString> was empty. */END_OBJ * lan9118Load	(		char* initString,		/* String to be parsed by the driver. */		void* p_v	){    END_DEVICE * pDrvCtrl;    if(initString == NULL) {        return NULL;

⌨️ 快捷键说明

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