#include "rtl8195a.h" #include "build_info.h" #ifdef PLATFORM_FREERTOS #include "FreeRTOS.h" #include "task.h" #include "semphr.h" #endif #include "osdep_service.h" #include "lwip_netconf.h" #include "ethernet_api.h" #include "lwip_intf.h" #include "ethernet_mii.h" #include "platform_opts.h" #include "ethernet_ex_api.h" static _sema mii_rx_sema; static _mutex mii_tx_mutex; extern volatile u32 ethernet_unplug; extern struct netif xnetif[NET_IF_NUM]; static u8 TX_BUFFER[1536]; static u8 RX_BUFFER[1536]; static u8 *pTmpTxDesc = NULL; static u8 *pTmpRxDesc = NULL; static u8 *pTmpTxPktBuf = NULL; static u8 *pTmpRxPktBuf = NULL; int ethernet_init_done = 0; int dhcp_ethernet_mii = 1; int ethernet_if_default = 0; int link_is_up = 0; link_up_down_callback p_link_change_callback = 0; extern int lwip_init_done; static _sema mii_linkup_sema; void mii_rx_thread(void* param){ u32 len = 0; u8* pbuf = RX_BUFFER; while(1){ if (rtw_down_sema(&mii_rx_sema) == _FAIL){ DBG_8195A("%s, Take Semaphore Fail\n", __FUNCTION__); goto exit; } // continues read the rx ring until its empty while(1){ len = ethernet_receive(); if(len){ //DBG_8195A("mii_recv len = %d\n\r", len); ethernet_read(pbuf, len); // calculate the time duration ethernetif_mii_recv(&xnetif[ETHERNET_IDX], len); //__rtl_memDump_v1_00(pbuf, len, "ethernet_receive Data:"); //rtw_memset(pbuf, 0, len); }else if(len == 0){ break; } } } exit: rtw_free_sema(&mii_rx_sema); vTaskDelete(NULL); } void mii_intr_thread(void* param) { u32 dhcp_status = 0; while(1) { if (rtw_down_sema(&mii_linkup_sema) == _FAIL){ DBG_8195A("%s, Take Semaphore Fail\n", __FUNCTION__); break; } //Used to process there is no cable plugged in when power-on if(1 == ethernet_unplug){ if(p_link_change_callback) p_link_change_callback(link_is_up); } if(1 == ethernet_init_done){ if(link_is_up){ DBG_8195A("...Link up\n"); if(dhcp_ethernet_mii == 1) dhcp_status = LwIP_DHCP(ETHERNET_IDX, DHCP_START); if(DHCP_ADDRESS_ASSIGNED == dhcp_status){ if(1 == ethernet_if_default) netif_set_default(&xnetif[ETHERNET_IDX]); //Set default gw to ether netif else netif_set_default(&xnetif[WLAN_IDX]); } }else{ DBG_8195A("...Link down\n"); netif_set_default(&xnetif[WLAN_IDX]); //Set default gw to wlan netif #if CONFIG_LWIP_LAYER LwIP_ReleaseIP(ETHERNET_IDX); #endif } if(p_link_change_callback) p_link_change_callback(link_is_up); } } rtw_free_sema(&mii_linkup_sema); vTaskDelete(NULL); } void mii_intr_handler(u32 Event, u32 Data) { switch(Event) { case ETH_TXDONE: //DBG_8195A("TX Data = %d\n", Data); break; case ETH_RXDONE: //DBG_8195A("\r\nRX Data = %d\n", Data); // wake up rx thread to receive data rtw_up_sema_from_isr(&mii_rx_sema); break; case ETH_LINKUP: DBG_8195A("Link Up\n"); link_is_up = 1; rtw_up_sema_from_isr(&mii_linkup_sema); break; case ETH_LINKDOWN: DBG_8195A("Link Down\n"); link_is_up = 0; rtw_up_sema_from_isr(&mii_linkup_sema); break; default: DBG_8195A("Unknown event !!\n"); break; } } void ethernet_demo(void* param){ u8 mac[6]; /* Initilaize the LwIP stack */ // can not init twice if(!lwip_init_done) LwIP_Init(); DBG_8195A("LWIP Init done\n"); ethernet_irq_hook(mii_intr_handler); if(pTmpTxDesc) { free(pTmpTxDesc); pTmpTxDesc = NULL; } if(pTmpRxDesc) { free(pTmpRxDesc); pTmpRxDesc = NULL; } if(pTmpTxPktBuf) { free(pTmpTxPktBuf); pTmpTxPktBuf = NULL; } if(pTmpRxPktBuf) { free(pTmpRxPktBuf); pTmpRxPktBuf = NULL; } pTmpTxDesc = (u8 *)malloc(/*MII_TX_DESC_CNT*/MII_TX_DESC_NO * ETH_TX_DESC_SIZE); pTmpRxDesc = (u8 *)malloc(/*MII_RX_DESC_CNT*/MII_RX_DESC_NO * ETH_RX_DESC_SIZE); pTmpTxPktBuf = (u8 *)malloc(/*MII_TX_DESC_CNT*/MII_TX_DESC_NO * ETH_PKT_BUF_SIZE); pTmpRxPktBuf = (u8 *)malloc(/*MII_RX_DESC_CNT*/MII_RX_DESC_NO * ETH_PKT_BUF_SIZE); if(pTmpTxDesc == NULL || pTmpRxDesc == NULL || pTmpTxPktBuf == NULL || pTmpRxPktBuf == NULL) { printf("TX/RX descriptor malloc fail\n"); return; } memset(pTmpTxDesc, 0, MII_TX_DESC_NO * ETH_TX_DESC_SIZE); memset(pTmpRxDesc, 0, MII_RX_DESC_NO * ETH_RX_DESC_SIZE); memset(pTmpTxPktBuf, 0, MII_TX_DESC_NO * ETH_PKT_BUF_SIZE); memset(pTmpRxPktBuf, 0, MII_RX_DESC_NO * ETH_PKT_BUF_SIZE); //size 160 128 12288 12288 ethernet_set_descnum(MII_TX_DESC_NO, MII_RX_DESC_NO); printf("TRX descriptor number setting done\n"); ethernet_trx_pre_setting(pTmpTxDesc, pTmpRxDesc, pTmpTxPktBuf, pTmpRxPktBuf); printf("TRX pre setting done\n"); ethernet_init(); DBG_INFO_MSG_OFF(_DBG_MII_); DBG_WARN_MSG_OFF(_DBG_MII_); DBG_ERR_MSG_ON(_DBG_MII_); /*get mac*/ ethernet_address(mac); memcpy((void*)xnetif[ETHERNET_IDX].hwaddr,(void*)mac, 6); rtw_init_sema(&mii_rx_sema,0); rtw_mutex_init(&mii_tx_mutex); if(xTaskCreate(mii_rx_thread, ((const char*)"mii_rx_thread"), 1024, NULL, tskIDLE_PRIORITY+5, NULL) != pdPASS) DBG_8195A("\n\r%s xTaskCreate(mii_rx_thread) failed", __FUNCTION__); DBG_8195A("\nEthernet_mii Init done, interface %d", ETHERNET_IDX); if(dhcp_ethernet_mii == 1){ LwIP_DHCP(ETHERNET_IDX, DHCP_START); netif_set_default(&xnetif[ETHERNET_IDX]); //Set default gw to ether netif } ethernet_init_done = 1; vTaskDelete(NULL); } int ethernet_is_linked() { if((link_is_up == 1)&&(1 == ethernet_init_done)) return TRUE; else return FALSE; } int ethernet_is_unplug() { if(ethernet_unplug == 1) return TRUE; else return FALSE; } void ethernet_mii_init() { printf("\ninitializing Ethernet_mii......\n"); // set the ethernet interface as default ethernet_if_default = 1; vSemaphoreCreateBinary(mii_linkup_sema); if( xTaskCreate((TaskFunction_t)mii_intr_thread, "DHCP_START_MII", 1024, NULL, 3, NULL) != pdPASS) { DBG_8195A("Cannot create demo task\n\r"); } if( xTaskCreate((TaskFunction_t)ethernet_demo, "ETHERNET DEMO", 1024, NULL, 2, NULL) != pdPASS) { DBG_8195A("Cannot create demo task\n\r"); } #if 0 extern void ethernet_wlan_iperf_test_task(void *param); if(xTaskCreate((TaskFunction_t)ethernet_wlan_iperf_test_task, "wifi_entry_task", 1024, NULL, 2, NULL) != pdPASS){ printf("\n\r%s xTaskCreate(wifi_entry_task) failed", __FUNCTION__); } #endif } void rltk_mii_recv(struct eth_drv_sg *sg_list, int sg_len){ struct eth_drv_sg *last_sg; u8* pbuf = RX_BUFFER; for (last_sg = &sg_list[sg_len]; sg_list < last_sg; ++sg_list) { if (sg_list->buf != 0) { rtw_memcpy((void *)(sg_list->buf), pbuf, sg_list->len); pbuf+=sg_list->len; } } } s8 rltk_mii_send(struct eth_drv_sg *sg_list, int sg_len, int total_len){ int ret =0; struct eth_drv_sg *last_sg; u8* pdata = TX_BUFFER; u8 retry_cnt = 0; u32 size = 0; for (last_sg = &sg_list[sg_len]; sg_list < last_sg; ++sg_list) { rtw_memcpy(pdata, (void *)(sg_list->buf), sg_list->len); pdata += sg_list->len; size += sg_list->len; } pdata = TX_BUFFER; //DBG_8195A("mii_send len= %d\n\r", size); rtw_mutex_get(&mii_tx_mutex); while(1){ ret = ethernet_write(pdata, size); if(ret > 0){ ethernet_send(); ret = 0; break; } if(++retry_cnt > 3){ DBG_8195A("TX drop\n\r"); ret = -1; } else rtw_udelay_os(1); } rtw_mutex_put(&mii_tx_mutex); return ret; } #define ____TEST____ /* used for test */ #if 0 #include "wifi_constants.h" struct iperf_data_t{ uint64_t total_size; uint64_t bandwidth; int server_fd; int client_fd; uint32_t buf_size; uint32_t time; uint32_t report_interval; uint16_t port; uint8_t server_ip[16]; uint8_t start; uint8_t tos_value; }; /*ATWT=-c,192.168.31.111,-t,10*/ int ethernet_wlan_iperf_test() { char server_ip[] = "192.168.31.111"; u16 time = 10; struct iperf_data_t tcp_client_data; printf("\n###################ethernet wlan iperf test !!!...\n"); memset(&tcp_client_data, 0, sizeof(tcp_client_data)); strncpy(tcp_client_data.server_ip, server_ip, (strlen(server_ip)>16)?16:strlen(server_ip)); tcp_client_data.time = time; tcp_client_data.bandwidth = 268459220; tcp_client_data.buf_size = 1460; tcp_client_data.client_fd = 0; tcp_client_data.port = 5001; tcp_client_data.report_interval = -1; tcp_client_data.server_fd = 0; tcp_client_data.start = 1; tcp_client_data.tos_value = 0; tcp_client_data.total_size = 0; tcp_client_func(tcp_client_data); return 0; } void ethernet_wlan_iperf_test_task(void *param) { printf("\n#########################ethernet wlan iperf test task...\n"); /* used for test */ p_link_change_callback = (link_up_down_callback)ethernet_wlan_iperf_test; /*sys_reset is not necessary, upper layer can define p_link_change_callback on demand*/ //p_link_change_callback = (link_up_down_callback)sys_reset(); while(1) { if(((wifi_is_ready_to_transceive(RTW_STA_INTERFACE)==RTW_SUCCESS)&ðernet_is_unplug())||(ethernet_is_linked())) break; else vTaskDelay(500); } ethernet_wlan_iperf_test(); printf("\r\n[%s] task del", __func__); vTaskDelete(NULL); } #endif