diff --git a/components/free_rtos/ethernet/eth.cpp b/components/free_rtos/ethernet/eth.cpp index 7e7df87..f562936 100644 --- a/components/free_rtos/ethernet/eth.cpp +++ b/components/free_rtos/ethernet/eth.cpp @@ -161,7 +161,6 @@ bool free_rtos::Eth::host_init() void free_rtos::Eth::link_task() { bool linkUp; - Enet_MacPort macPort; Enet_IoctlPrms prms; IcssgMacPort_SetPortStateInArgs setPortStateInArgs; @@ -170,16 +169,15 @@ void free_rtos::Eth::link_task() { for (int i = 0; i < macPortNum_; ++i) { - macPort = macPort_[i]; linkUp = false; - ENET_IOCTL_SET_INOUT_ARGS(&prms, &macPort, &linkUp); + ENET_IOCTL_SET_INOUT_ARGS(&prms, &macPort_[i], &linkUp); status = eth_ioctl(handleInfo_.hEnet, core_id_, ENET_PER_IOCTL_IS_PORT_LINK_UP, &prms); if (status != ENET_SOK) { EnetAppUtils_print("link_task: %s: Failed to get port %u link status: %d\r\n", - name_.c_str(), ENET_MACPORT_ID(macPort), status); + name_.c_str(), ENET_MACPORT_ID(macPort_[i]), status); linkUp = false; continue; } @@ -187,11 +185,11 @@ void free_rtos::Eth::link_task() if (linkUp_[i] != linkUp) { EnetAppUtils_print("link_task: %s: Port %u link is %s\r\n", - name_.c_str(), ENET_MACPORT_ID(macPort), linkUp ? "up" : "down"); + name_.c_str(), ENET_MACPORT_ID(macPort_[i]), linkUp ? "up" : "down"); if (linkUp) { EnetAppUtils_print("link_task: %s: Set port state to 'Forward'\r\n", name_.c_str()); - setPortStateInArgs.macPort = macPort; + setPortStateInArgs.macPort = macPort_[i]; setPortStateInArgs.portState = ICSSG_PORT_STATE_FORWARD; ENET_IOCTL_SET_IN_ARGS(&prms, &setPortStateInArgs); @@ -215,34 +213,34 @@ void free_rtos::Eth::link_task() } /// ����� �������� ������ ����(����� SWITCH) - if (!tx_flow_.open(i, ENET_DMA_TX_CH0)) + if (!tx_flow_.open((TEthMacPorts)macPort_[i], ENET_DMA_TX_CH0)) { EnetAppUtils_print("link_task: %s: Failed to open tx flow\n", name_.c_str()); continue; } - if (!rx_flow_[i].open(i, ENET_DMA_RX_CH0 + i, rxTaskPriority_[i], rxTaskStackSize_[i])) + if (!rx_flow_[i].open((TEthMacPorts)macPort_[i], ENET_DMA_RX_CH0 + i, rxTaskPriority_[i], rxTaskStackSize_[i])) { EnetAppUtils_print("link_task: %s: Failed to open rx flow: %u\n", name_.c_str(), i); continue; } /// e_ethMac0 - if (i == e_ethMac0) + if (macPort_[i] == ENET_MAC_PORT_1) { if (!host_init()) { EnetAppUtils_print("link_task: %s: Failed to init host\r\n", name_.c_str()); continue; } } - else if (i == e_ethMac1) { + else if (macPort_[i] == ENET_MAC_PORT_2) { //rx_flow_[i].set_passive(); /// ���� � �������� ���������� �� - ���������, �� ������������ ������ } - tx_flow_.enable((TEthMacPorts)i); + tx_flow_.enable((TEthMacPorts)macPort_[i]); } else { - tx_flow_.disable((TEthMacPorts)i); + tx_flow_.disable((TEthMacPorts)macPort_[i]); } linkUp_[i] = linkUp; diff --git a/components/free_rtos/ethernet/eth_rx_flow.cpp b/components/free_rtos/ethernet/eth_rx_flow.cpp index c227793..fd06a8b 100644 --- a/components/free_rtos/ethernet/eth_rx_flow.cpp +++ b/components/free_rtos/ethernet/eth_rx_flow.cpp @@ -34,6 +34,7 @@ void free_rtos::rxIsrHandler(void *appData) return; } + rx_flow->retrieveReadyRxPktQ(); rx_flow->sem_[EthRxFlow::e_signalRxPkt].post(); } @@ -50,7 +51,7 @@ free_rtos::EthRxFlow::EthRxFlow(TEthFrameMacAddr& mac_addr, EthStackIface& eth_s eth_stack_{eth_stack}, passive_mode_{false} { - EnetQueue_initQ(&rx_free_pktq_); + EnetQueue_initQ(&rx_ready_pktq_); } void free_rtos::EthRxFlow::initRxFreePktQ(void * appPriv, EnetDma_PktQ * p_packet_queue, uint32_t qCount) @@ -82,30 +83,24 @@ void free_rtos::EthRxFlow::initRxFreePktQ(void * appPriv, EnetDma_PktQ * p_packe EnetAppUtils_assert(EnetQueue_getQCount(&rxReadyQ) == 0U); } -void free_rtos::EthRxFlow::submitFreeRxPkts(uint32_t qCount) +void free_rtos::EthRxFlow::retrieveReadyRxPktQ() { + int32_t status = EnetDma_retrieveRxPktQ(dma_handle_, &rx_ready_pktq_); + EnetAppUtils_assert(status == ENET_SOK); +} + +void free_rtos::EthRxFlow::submitFreeRxPktQ(EnetDma_PktQ * p_packet_queue) { - EnetDma_PktQ rxSubmitQ; - EnetDma_Pkt* rxPktInfo = (EnetDma_Pkt *)EnetQueue_deq(&rx_free_pktq_); int32_t status; + uint32_t qCount; - EnetQueue_initQ(&rxSubmitQ); - - while((qCount > 0) && (rxPktInfo != nullptr)) - { - EnetQueue_enq(&rxSubmitQ, &rxPktInfo->node); - - rxPktInfo = (EnetDma_Pkt *)EnetQueue_deq(&rx_free_pktq_); - qCount--; - } - - EnetAppUtils_validatePacketState(&rxSubmitQ, + EnetAppUtils_validatePacketState(p_packet_queue, ENET_PKTSTATE_APP_WITH_FREEQ, ENET_PKTSTATE_APP_WITH_DRIVER); - status = EnetDma_submitRxPktQ(dma_handle_, &rxSubmitQ); + status = EnetDma_submitRxPktQ(dma_handle_, p_packet_queue); EnetAppUtils_assert(status == ENET_SOK); - qCount = EnetQueue_getQCount(&rxSubmitQ); + qCount = EnetQueue_getQCount(p_packet_queue); /* Assert here, as during init, the number of DMA descriptors should be equal to * the number of free Ethernet buffers available with app */ EnetAppUtils_assert(qCount == 0U); @@ -113,87 +108,64 @@ void free_rtos::EthRxFlow::submitFreeRxPkts(uint32_t qCount) void free_rtos::EthRxFlow::rxProcessPktTask() { - EnetDma_Pkt* rxPktInfo; /// ����� � ������� - EnetDma_PktQ rxReadyQ; - uint32_t readyQCount; + EnetDma_Pkt* rxPktInfo; + EnetDma_PktQ rxFreeQ; int32_t status; while(1) { - if(enetDmaRxChId_ != ENET_DMA_RX_CH0) { - status = sem_[e_signalRxPkt].pend(); - } else { - status = sem_[e_signalRxPkt].pend(semaphore_timeout_ticks_); - } + status = sem_[e_signalRxPkt].pend(); if(status != SystemP_SUCCESS) { - EnetAppUtils_print("RX Timeout "); - continue; } - do { - EnetDma_PktQ rxFreeQ; + EnetQueue_initQ(&rxFreeQ); + rxPktInfo = (EnetDma_Pkt *)EnetQueue_deq(&rx_ready_pktq_); - EnetQueue_initQ(&rxFreeQ); + while(rxPktInfo != nullptr) { + //if (!passive_mode_) { + for (int j = 0 ; j < rxPktInfo->sgList.numScatterSegments; ++j) + { + eth_stack_.rx_handler(rxPktInfo->sgList.list[j].bufPtr, rxPktInfo->sgList.list[j].segmentFilledLen); + } + //} - status = EnetDma_retrieveRxPktQ(dma_handle_, &rxReadyQ); - EnetAppUtils_assert(status == ENET_SOK); + EnetDma_checkPktState( &rxPktInfo->pktState, + ENET_PKTSTATE_MODULE_APP, + ENET_PKTSTATE_APP_WITH_DRIVER, + ENET_PKTSTATE_APP_WITH_FREEQ); - readyQCount = EnetQueue_getQCount(&rxReadyQ); + EnetQueue_enq(&rxFreeQ, &rxPktInfo->node); - if(readyQCount == 0) { - break; - } + rxPktInfo = (EnetDma_Pkt *)EnetQueue_deq(&rx_ready_pktq_); + } - // Reload DMA with a new rx free queue as fast as possible - submitFreeRxPkts(readyQCount); - - rxPktInfo = (EnetDma_Pkt *)EnetQueue_deq(&rxReadyQ); - - while(rxPktInfo != nullptr) { - //if (!passive_mode_) { - for (int j = 0 ; j < rxPktInfo->sgList.numScatterSegments; ++j) - { - eth_stack_.rx_handler(rxPktInfo->sgList.list[j].bufPtr, rxPktInfo->sgList.list[j].segmentFilledLen); - } - //} - - EnetQueue_enq(&rxFreeQ, &rxPktInfo->node); - - rxPktInfo = (EnetDma_Pkt *)EnetQueue_deq(&rxReadyQ); - } - - EnetAppUtils_validatePacketState(&rxFreeQ, - ENET_PKTSTATE_APP_WITH_DRIVER, - ENET_PKTSTATE_APP_WITH_FREEQ); - - EnetQueue_append(&rx_free_pktq_, &rxFreeQ); - } while(readyQCount > 0); + submitFreeRxPktQ(&rxFreeQ); } } -bool free_rtos::EthRxFlow::open(uint32_t id, int32_t enetDmaRxChId, UBaseType_t task_priority, UBaseType_t task_stack_size) +bool free_rtos::EthRxFlow::open(TEthMacPorts port_id, int32_t enetDmaRxChId, UBaseType_t task_priority, UBaseType_t task_stack_size) { EnetApp_GetDmaHandleInArgs rxInArgs; EnetApp_GetRxDmaHandleOutArgs rxChInfo; constexpr uint32_t numPkts[2] = {ENET_DMA_RX_CH0_NUM_PKTS, ENET_DMA_RX_CH1_NUM_PKTS}; - EnetAppUtils_print("rx_flow %u: opening flow...\r\n", id); + EnetAppUtils_print("rx_flow %u: opening flow...\r\n", port_id); if (open_) { - EnetAppUtils_print("rx_flow %u: rx flow is already open. Do nothing.\r\n", id_); + EnetAppUtils_print("rx_flow %u: rx flow is already open. Do nothing.\r\n", port_id); return true; } if (!rx_task.Create("rx_task", task_priority, rxTaskHandler, this, task_stack_size)) { - EnetAppUtils_print("rx_flow %u: failed to create rx task.\r\n", id_); + EnetAppUtils_print("rx_flow %u: failed to create rx task.\r\n", port_id); return false; } - id_ = id; + default_port_id_ = port_id; enetDmaRxChId_ = enetDmaRxChId; /// ������������ ���������� �� ������ ������ @@ -219,23 +191,26 @@ bool free_rtos::EthRxFlow::open(uint32_t id, int32_t enetDmaRxChId, UBaseType_t EnetAppUtils_assert(rxChInfo.useGlobalEvt == true); EnetAppUtils_assert(rxChInfo.sizeThreshEn == 0U); EnetAppUtils_assert(rxChInfo.maxNumRxPkts >= numPkts[enetDmaRxChId]); - EnetAppUtils_assert(rxChInfo.chIdx == id_); + EnetAppUtils_assert(rxChInfo.chIdx == port_id); EnetAppUtils_assert(rxChInfo.useDefaultFlow == true); if (dma_handle_ == nullptr) { - EnetAppUtils_print("rx_flow %u: failed to open rx dma flow\r\n", id_); + EnetAppUtils_print("rx_flow %u: failed to open rx dma flow\r\n", port_id); EnetAppUtils_assert(dma_handle_ != nullptr); return false; } - /// ������������� ������� ������� - initRxFreePktQ(this, &rx_free_pktq_, numPkts[enetDmaRxChId]); - submitFreeRxPkts(numPkts[enetDmaRxChId]/2); + EnetDma_PktQ rxFreeQ; + + EnetQueue_initQ(&rxFreeQ); + + initRxFreePktQ(this, &rxFreeQ, numPkts[enetDmaRxChId]); + submitFreeRxPktQ(&rxFreeQ); open_ = true; - EnetAppUtils_print("rx_flow %u: rx flow open successfully\r\n", id); + EnetAppUtils_print("rx_flow %u: rx flow open successfully\r\n", port_id); return true; } diff --git a/components/free_rtos/ethernet/eth_rx_flow.hpp b/components/free_rtos/ethernet/eth_rx_flow.hpp index 584fab6..d39519a 100644 --- a/components/free_rtos/ethernet/eth_rx_flow.hpp +++ b/components/free_rtos/ethernet/eth_rx_flow.hpp @@ -28,7 +28,7 @@ class EthRxFlow { public: EthRxFlow(TEthFrameMacAddr& mac_addr, EthStackIface& eth_stack); - bool open(uint32_t id, int32_t enetDmaRxChId, UBaseType_t task_priority, UBaseType_t task_stack_size); + bool open(TEthMacPorts port_id, int32_t enetDmaRxChId, UBaseType_t task_priority, UBaseType_t task_stack_size); bool is_open() {return open_;} @@ -41,7 +41,8 @@ private: friend void rxTaskHandler(void *appData); ///������ ��������� �������� ������� void initRxFreePktQ(void * appPriv, EnetDma_PktQ * p_packet_queue, uint32_t qCount); - void submitFreeRxPkts(uint32_t qCount); + void retrieveReadyRxPktQ(); + void submitFreeRxPktQ(EnetDma_PktQ * p_packet_queue); void rxProcessPktTask(); ///������� ��������� �������� ������� @@ -51,9 +52,7 @@ private: e_signalTotal }; - static constexpr uint32_t semaphore_timeout_ticks_ = 900; - - uint32_t id_; /// ������������� ������ + TEthMacPorts default_port_id_; /// ������������� ������ int32_t enetDmaRxChId_; bool open_; /// ���� ����, ��� dma ����� ��� ������ @@ -68,7 +67,7 @@ private: uint32_t rx_start_flow_idx_; uint32_t rx_flow_idx_; EnetDma_RxChHandle dma_handle_; - EnetDma_PktQ rx_free_pktq_; + EnetDma_PktQ rx_ready_pktq_; bool passive_mode_; /// ��������� �����, ������ �����������, �� �� ���������� � ���� ��������� }; diff --git a/components/free_rtos/ethernet/eth_tx_flow.cpp b/components/free_rtos/ethernet/eth_tx_flow.cpp index 77d6cfc..1ce1155 100644 --- a/components/free_rtos/ethernet/eth_tx_flow.cpp +++ b/components/free_rtos/ethernet/eth_tx_flow.cpp @@ -51,75 +51,51 @@ static void eth_initTxFreePktQ(void * appPriv, EnetDma_PktQ * p_packet_queue, ui EnetQueue_getQCount(p_packet_queue)); } -static uint32_t eth_retrieveFreeTxPkts(EnetDma_TxChHandle * p_handle, EnetDma_PktQ * p_queque) +void free_rtos::txIsrHandler(void *appData) { - EnetDma_PktQ txFreeQ; - EnetDma_Pkt *pktInfo; - uint32_t txFreeQCnt = 0U; - int32_t status; + EthTxFlow * tx_flow = (EthTxFlow *)appData; - EnetQueue_initQ(&txFreeQ); - - /// ��������� ������ ������� ���� ������� �������� �� ������� ���������� �������� - status = EnetDma_retrieveTxPktQ(*p_handle, &txFreeQ); - if (status == ENET_SOK) - { - /// ���������� ������� � ������� - txFreeQCnt = EnetQueue_getQCount(&txFreeQ); - - pktInfo = (EnetDma_Pkt *)EnetQueue_deq(&txFreeQ); - while (NULL != pktInfo) - { - EnetDma_checkPktState(&pktInfo->pktState, - ENET_PKTSTATE_MODULE_APP, - ENET_PKTSTATE_APP_WITH_DRIVER, - ENET_PKTSTATE_APP_WITH_FREEQ); - - /// �������� ����� � ������� ��������� ������� txFreePktInfoQ - EnetQueue_enq(p_queque, &pktInfo->node); - pktInfo = (EnetDma_Pkt *)EnetQueue_deq(&txFreeQ); /// ����� ��������� ��������� ����� - } - } - else - { - EnetAppUtils_print("retrieveFreeTxPkts() failed to retrieve pkts: %d\r\n", status); + if(tx_flow == nullptr) { + return; } - return txFreeQCnt; /// ���������� ��������� ������� + tx_flow->retrieveFreeTxPktQ(); + tx_flow->sem_[EthTxFlow::e_signalTxPkt].post(); } free_rtos::EthTxFlow::EthTxFlow() : - id_{0}, + default_port_id_{e_ethMac0}, open_{false}, tx_ch_num_{0} { EnetQueue_initQ(&tx_free_pktq_); } -bool free_rtos::EthTxFlow::open(uint32_t id, int32_t enetDmaTxChId) +bool free_rtos::EthTxFlow::open(TEthMacPorts port_id, int32_t enetDmaTxChId) { - if (id >= e_ethMacTotal) { + if (port_id >= e_ethMacTotal) { return false; } EnetApp_GetDmaHandleInArgs txInArgs; EnetApp_GetTxDmaHandleOutArgs txChInfo; - EnetAppUtils_print("tx_flow %u: opening flow...\r\n", id); + EnetAppUtils_print("tx_flow %u: opening flow...\r\n", port_id); - port_data_[id].tx_pkt_counter = 0; + port_data_[port_id].tx_pkt_counter = 0; if (open_) { - EnetAppUtils_print("tx_flow %u: tx flow is already open. Do nothing.\r\n", id_); + EnetAppUtils_print("tx_flow %u: tx flow is already open. Do nothing.\r\n", port_id); return true; } /* Open the TX channel */ - txInArgs.notifyCb = nullptr; - txInArgs.cbArg = nullptr; + txInArgs.notifyCb = txIsrHandler; + txInArgs.cbArg = this; EnetApp_getTxDmaHandle(enetDmaTxChId, &txInArgs, &txChInfo); + default_port_id_ = port_id; tx_ch_num_ = txChInfo.txChNum; dma_handle_ = txChInfo.hTxCh; @@ -128,7 +104,7 @@ bool free_rtos::EthTxFlow::open(uint32_t id, int32_t enetDmaTxChId) if (dma_handle_ == nullptr) { - EnetAppUtils_print("tx_flow %u: failed to open tx dma flow\r\n", id_); + EnetAppUtils_print("tx_flow %u: failed to open tx dma flow\r\n", port_id); EnetAppUtils_assert(dma_handle_ != nullptr); return false; } @@ -137,7 +113,7 @@ bool free_rtos::EthTxFlow::open(uint32_t id, int32_t enetDmaTxChId) open_= true; - EnetAppUtils_print("tx_flow %u: tx flow open successfully\r\n", id_); + EnetAppUtils_print("tx_flow %u: tx flow open successfully\r\n", port_id); return true; } @@ -158,6 +134,43 @@ void free_rtos::EthTxFlow::disable(TEthMacPorts port_id) { port_data_[port_id].tx_enable = false; } +void free_rtos::EthTxFlow::retrieveFreeTxPktQ() +{ + EnetDma_PktQ txFreeQ; + EnetDma_Pkt *pktInfo; + int32_t status; + + EnetQueue_initQ(&txFreeQ); + + status = EnetDma_retrieveTxPktQ(dma_handle_, &txFreeQ); + + if (status != ENET_SOK) + { + EnetAppUtils_print("retrieveFreeTxPktQ() failed to retrieve pkts: %d\r\n", status); + + return; + } + + EnetAppUtils_validatePacketState( &txFreeQ, + ENET_PKTSTATE_APP_WITH_DRIVER, + ENET_PKTSTATE_APP_WITH_FREEQ); + + EnetQueue_append(&tx_free_pktq_, &txFreeQ); +} + +EnetDma_Pkt* free_rtos::EthTxFlow::getTxPktInfo() +{ + EnetDma_Pkt *txPktInfo = (EnetDma_Pkt *)EnetQueue_deq(&tx_free_pktq_); + + while(txPktInfo == NULL) + { + sem_[EthTxFlow::e_signalTxPkt].pend(); + txPktInfo = (EnetDma_Pkt *)EnetQueue_deq(&tx_free_pktq_); + } + + return txPktInfo; +} + bool free_rtos::EthTxFlow::send(TEthMacPorts port_id, uint8_t * p_data, uint32_t len) { if (port_id >= e_ethMacTotal) { @@ -176,65 +189,57 @@ bool free_rtos::EthTxFlow::send(TEthMacPorts port_id, uint8_t * p_data, uint32_t EnetQueue_initQ(&txSubmitQ); - eth_retrieveFreeTxPkts(&dma_handle_, &tx_free_pktq_); + txPktInfo = getTxPktInfo(); - txPktInfo = (EnetDma_Pkt *)EnetQueue_deq(&tx_free_pktq_); - - while(txPktInfo == NULL) + if (txPktInfo == NULL) { - txPktInfo = (EnetDma_Pkt *)EnetQueue_deq(&tx_free_pktq_); - } + EnetAppUtils_print("tx_flow %u: Drop due to TX pkt not available\r\n", port_id); - if (txPktInfo != NULL) - { - ///�������� ������ ������ � ����� - memcpy(txPktInfo->sgList.list[0].bufPtr, p_data, len); - - txPktInfo->sgList.list[0].segmentFilledLen = len; - txPktInfo->sgList.numScatterSegments = 1; - txPktInfo->chkSumInfo = 0U; - txPktInfo->appPriv = nullptr; - txPktInfo->tsInfo.txPktSeqId = 0; - txPktInfo->txPktTc = 0; /// Traffic class ����� ��� IPv6 - txPktInfo->tsInfo.enableHostTxTs = false; - txPktInfo->txPortNum = (Enet_MacPort)port_id; - - EnetDma_checkPktState(&txPktInfo->pktState, - ENET_PKTSTATE_MODULE_APP, - ENET_PKTSTATE_APP_WITH_FREEQ, - ENET_PKTSTATE_APP_WITH_DRIVER); - - /// ������ ����� txPktInfo � ������� txSubmitQ - EnetQueue_enq(&txSubmitQ, &txPktInfo->node); - } - else - { - EnetAppUtils_print("tx_flow %u: Drop due to TX pkt not available\r\n", id_); return false; } - /// ������ ������� � ������� DMA + memcpy(txPktInfo->sgList.list[0].bufPtr, p_data, len); + + txPktInfo->sgList.list[0].segmentFilledLen = len; + txPktInfo->sgList.numScatterSegments = 1; + txPktInfo->chkSumInfo = 0U; + txPktInfo->appPriv = nullptr; + txPktInfo->tsInfo.txPktSeqId = 0; + txPktInfo->txPktTc = 0; /// Traffic class IPv6 + txPktInfo->tsInfo.enableHostTxTs = false; + txPktInfo->txPortNum = (Enet_MacPort)port_id; + + EnetDma_checkPktState( &txPktInfo->pktState, + ENET_PKTSTATE_MODULE_APP, + ENET_PKTSTATE_APP_WITH_FREEQ, + ENET_PKTSTATE_APP_WITH_DRIVER); + + EnetQueue_enq(&txSubmitQ, &txPktInfo->node); + status = EnetDma_submitTxPktQ(dma_handle_, &txSubmitQ); + if (status != ENET_SOK) { - EnetAppUtils_print("tx_flow %u: Failed to submit TX pkt queue: %d\r\n", id_, status); + EnetAppUtils_print("tx_flow %u: Failed to submit TX pkt queue: %d\r\n", port_id, status); return false; } - ++port_data_[port_id].tx_pkt_counter; /// ������� ���������� ������� + ++port_data_[port_id].tx_pkt_counter; return true; } bool free_rtos::EthTxFlow::send(TxFlowHandlerArgs& handlerArgs, uint32_t numScatterSegments) { - if (handlerArgs.port_id >= e_ethMacTotal) { + TEthMacPorts port_id = handlerArgs.port_id; + + if (port_id >= e_ethMacTotal) { EnetAppUtils_print("Wrong port id\r\n"); return false; } - if (port_data_[handlerArgs.port_id].tx_enable == false) { + if (port_data_[port_id].tx_enable == false) { return false; } @@ -244,52 +249,45 @@ bool free_rtos::EthTxFlow::send(TxFlowHandlerArgs& handlerArgs, uint32_t numScat EnetQueue_initQ(&txSubmitQ); - eth_retrieveFreeTxPkts(&dma_handle_, &tx_free_pktq_); + txPktInfo = getTxPktInfo(); - txPktInfo = (EnetDma_Pkt *)EnetQueue_deq(&tx_free_pktq_); - - while(txPktInfo == NULL) + if (txPktInfo == NULL) { - txPktInfo = (EnetDma_Pkt *)EnetQueue_deq(&tx_free_pktq_); - } + EnetAppUtils_print("tx_flow %u: Drop due to TX pkt not available\r\n", port_id); - if (txPktInfo != NULL) - { - for(size_t scatter_segment = 0; scatter_segment < numScatterSegments; scatter_segment++) - { - handlerArgs.buffer = txPktInfo->sgList.list[scatter_segment].bufPtr; - txPktInfo->sgList.list[scatter_segment].segmentFilledLen = handlerArgs.stack_handler->Sender(handlerArgs, scatter_segment); - } - - txPktInfo->sgList.numScatterSegments = numScatterSegments; - txPktInfo->chkSumInfo = 0U; - txPktInfo->appPriv = nullptr; - txPktInfo->tsInfo.txPktSeqId = 0; - txPktInfo->txPktTc = 0; /// Traffic class IPv6 - txPktInfo->tsInfo.enableHostTxTs = false; - txPktInfo->txPortNum = (Enet_MacPort)handlerArgs.port_id; - - EnetDma_checkPktState(&txPktInfo->pktState, - ENET_PKTSTATE_MODULE_APP, - ENET_PKTSTATE_APP_WITH_FREEQ, - ENET_PKTSTATE_APP_WITH_DRIVER); - - EnetQueue_enq(&txSubmitQ, &txPktInfo->node); - } - else - { - EnetAppUtils_print("tx_flow %u: Drop due to TX pkt not available\r\n", id_); return false; } + for(size_t scatter_segment = 0; scatter_segment < numScatterSegments; scatter_segment++) + { + handlerArgs.buffer = txPktInfo->sgList.list[scatter_segment].bufPtr; + txPktInfo->sgList.list[scatter_segment].segmentFilledLen = handlerArgs.stack_handler->Sender(handlerArgs, scatter_segment); + } + + txPktInfo->sgList.numScatterSegments = numScatterSegments; + txPktInfo->chkSumInfo = 0U; + txPktInfo->appPriv = nullptr; + txPktInfo->tsInfo.txPktSeqId = 0; + txPktInfo->txPktTc = 0; /// Traffic class IPv6 + txPktInfo->tsInfo.enableHostTxTs = false; + txPktInfo->txPortNum = (Enet_MacPort)port_id; + + EnetDma_checkPktState( &txPktInfo->pktState, + ENET_PKTSTATE_MODULE_APP, + ENET_PKTSTATE_APP_WITH_FREEQ, + ENET_PKTSTATE_APP_WITH_DRIVER); + + EnetQueue_enq(&txSubmitQ, &txPktInfo->node); + status = EnetDma_submitTxPktQ(dma_handle_, &txSubmitQ); + if (status != ENET_SOK) { - EnetAppUtils_print("tx_flow %u: Failed to submit TX pkt queue: %d\r\n", id_, status); + EnetAppUtils_print("tx_flow %u: Failed to submit TX pkt queue: %d\r\n", port_id, status); return false; } - ++port_data_[handlerArgs.port_id].tx_pkt_counter; /// ������� ���������� ������� + ++port_data_[handlerArgs.port_id].tx_pkt_counter; return true; } diff --git a/components/free_rtos/ethernet/eth_tx_flow.hpp b/components/free_rtos/ethernet/eth_tx_flow.hpp index 6d9e511..6a04627 100644 --- a/components/free_rtos/ethernet/eth_tx_flow.hpp +++ b/components/free_rtos/ethernet/eth_tx_flow.hpp @@ -13,6 +13,7 @@ #include "free_rtos/ethernet/eth_tx_flow_iface.hpp" #include "free_rtos/handler_store/handler_store.hpp" +#include "free_rtos/semaphore/semaphore.hpp" namespace free_rtos { @@ -20,7 +21,7 @@ class EthTxFlow : public EthTxFlowIface { public: EthTxFlow(); - bool open(uint32_t id, int32_t enetDmaTxChId); + bool open(TEthMacPorts port_id, int32_t enetDmaTxChId); bool is_open() {return open_;} @@ -31,20 +32,32 @@ public: virtual bool send(TEthMacPorts port_id, uint8_t * p_data, uint32_t len) override; virtual bool send(TxFlowHandlerArgs& handlerArgs, uint32_t numScatterSegments) override; private: + friend void txIsrHandler(void *appData); + + enum SignalsId { + e_signalTxPkt, + e_signalTotal + }; + struct PortData { bool tx_enable; uint32_t tx_pkt_counter; }; - uint32_t id_; + TEthMacPorts default_port_id_; bool open_; + Semaphore sem_[e_signalTotal]; + //------------------------------------------------- uint32_t tx_ch_num_; EnetDma_TxChHandle dma_handle_; /// ���������� ����� DMA EnetDma_PktQ tx_free_pktq_; /// ������� ��������� ������� PortData port_data_[e_ethMacTotal]; + + void retrieveFreeTxPktQ(); + EnetDma_Pkt* getTxPktInfo(); };