sitara_depot/components/free_rtos/ethernet/eth_rx_flow.cpp

226 lines
8.5 KiB
C++
Raw Blame History

/*
* eth_rx_flow.cpp
*
* Created on: 7 <20><><EFBFBD>. 2023 <20>.
* Author: sychev
*/
#include "ethernet/eth_rx_flow.hpp"
#include <networking/enet/core/include/core/enet_soc.h>
#include <networking/enet/core/include/core/enet_queue.h>
#include <networking/enet/utils/include/enet_board.h>
#include <networking/enet/utils/include/enet_appmemutils.h>
#include <networking/enet/utils/include/enet_appmemutils_cfg.h>
#include <networking/enet/utils/include/enet_apputils.h>
/*----------------------------------------------------------------------*/
/**
* <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> sysconfig.
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD> <build_name>/syscfg
*/
#include "ti_enet_config.h"
/*----------------------------------------------------------------------*/
using namespace free_rtos;
/**
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
void free_rtos::rxIsrHandler(void *appData)
{
EthRxFlow * rx_flow = (EthRxFlow *)appData;
if (rx_flow != nullptr) {
rx_flow->sem_[EthRxFlow::e_signalRxPkt].post();
}
}
void free_rtos::rxTaskHandler(void *appData)
{
EthRxFlow * rx_flow = (EthRxFlow *)appData;
if (rx_flow != nullptr) {
rx_flow->rxProcessPktTask();
}
}
static void eth_initRxReadyPktQ(EnetDma_RxChHandle hRxCh, void * appPriv)
{
EnetDma_PktQ rxReadyQ;
EnetDma_PktQ rxFreeQ;
EnetDma_Pkt *pPktInfo;
uint32_t i;
int32_t status;
EnetQueue_initQ(&rxFreeQ);
for (i = 0U; i < (ENET_SYSCFG_TOTAL_NUM_RX_PKT/2); ++i)
{
pPktInfo = EnetMem_allocEthPkt(appPriv,
ENET_MEM_LARGE_POOL_PKT_SIZE,
ENETDMA_CACHELINE_ALIGNMENT);
EnetAppUtils_assert(pPktInfo != NULL);
ENET_UTILS_SET_PKT_APP_STATE(&pPktInfo->pktState, ENET_PKTSTATE_APP_WITH_FREEQ);
EnetQueue_enq(&rxFreeQ, &pPktInfo->node);
}
/* Retrieve any packets which are ready */
EnetQueue_initQ(&rxReadyQ);
status = EnetDma_retrieveRxPktQ(hRxCh, &rxReadyQ);
EnetAppUtils_assert(status == ENET_SOK);
/* There should not be any packet with DMA during init */
EnetAppUtils_assert(EnetQueue_getQCount(&rxReadyQ) == 0U);
EnetAppUtils_validatePacketState(&rxFreeQ,
ENET_PKTSTATE_APP_WITH_FREEQ,
ENET_PKTSTATE_APP_WITH_DRIVER);
EnetDma_submitRxPktQ(hRxCh, &rxFreeQ);
/* 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(EnetQueue_getQCount(&rxFreeQ) == 0U);
}
free_rtos::EthRxFlow::EthRxFlow(TEthFrameMacAddr& mac_addr, EthStackIface& eth_stack) :
mac_addr_{mac_addr},
eth_stack_{eth_stack},
passive_mode_{false}
{
}
void free_rtos::EthRxFlow::rxProcessPktTask()
{
EnetDma_PktQ rxReadyQ; /// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
EnetDma_PktQ rxFreeQ; /// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
EnetDma_Pkt* rxPktInfo; /// <20><><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int32_t status;
while(1)
{
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
sem_[e_signalRxPkt].pend();
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
EnetQueue_initQ(&rxReadyQ);
EnetQueue_initQ(&rxFreeQ);
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> rxReadyQ
status = EnetDma_retrieveRxPktQ(dma_handle_, &rxReadyQ);
EnetAppUtils_assert(status == ENET_SOK);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
rxPktInfo = (EnetDma_Pkt *)EnetQueue_deq(&rxReadyQ);
while(rxPktInfo != nullptr)
{
/// <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (!passive_mode_)
{
/// <20> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
for (int j = 0 ; j < rxPktInfo->sgList.numScatterSegments; ++j)
{
eth_stack_.rx_handler(rxPktInfo->sgList.list[j].bufPtr, rxPktInfo->sgList.list[j].segmentFilledLen);
}
}
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
EnetDma_checkPktState(&rxPktInfo->pktState,
ENET_PKTSTATE_MODULE_APP,
ENET_PKTSTATE_APP_WITH_DRIVER,
ENET_PKTSTATE_APP_WITH_FREEQ);
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
EnetQueue_enq(&rxFreeQ, &rxPktInfo->node);
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
rxPktInfo = (EnetDma_Pkt *)EnetQueue_deq(&rxReadyQ);
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
++rx_pkt_counter_;
}
/**
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ENET_PKTSTATE_APP_WITH_FREEQ)
* <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><> ENET_PKTSTATE_APP_WITH_DRIVER. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD>
* <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> EnetDma_checkPktState.
*/
EnetAppUtils_validatePacketState(&rxFreeQ,
ENET_PKTSTATE_APP_WITH_FREEQ,
ENET_PKTSTATE_APP_WITH_DRIVER);
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
EnetDma_submitRxPktQ(dma_handle_, &rxFreeQ);
}
}
bool free_rtos::EthRxFlow::open(uint32_t id, int32_t enetDmaRxChId)
{
EnetApp_GetDmaHandleInArgs rxInArgs;
EnetApp_GetRxDmaHandleOutArgs rxChInfo;
EnetAppUtils_print("rx_flow %u: opening flow...\r\n", id);
rx_pkt_counter_ = 0;
if (open_) {
EnetAppUtils_print("rx_flow %u: rx flow is already open. Do nothing.\r\n", id_);
return true;
}
if (!rx_task.Create("rx_task", RX_TASK_PRIORITY, rxTaskHandler, this, RX_TASK_STACK_SIZE))
{
EnetAppUtils_print("rx_flow %u: failed to create rx task.\r\n", id_);
return false;
}
id_ = id;
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
rxInArgs.notifyCb = rxIsrHandler; /// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
rxInArgs.cbArg = this; /// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
EnetApp_getRxDmaHandle(enetDmaRxChId, &rxInArgs, &rxChInfo);
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
rx_start_flow_idx_ = rxChInfo.rxFlowStartIdx;
rx_flow_idx_ = rxChInfo.rxFlowIdx;
dma_handle_ = rxChInfo.hRxCh;
if (rxChInfo.macAddressValid)
{
EnetUtils_copyMacAddr(mac_addr_.bytes, rxChInfo.macAddr);
mac_addr_.addr&= ETH_FRAME_MAC_ADDR_MASK;
eth_stack_.set_mac_address(mac_addr_.addr);
}
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
EnetAppUtils_assert(rxChInfo.useGlobalEvt == true);
EnetAppUtils_assert(rxChInfo.sizeThreshEn == 0U);
EnetAppUtils_assert(rxChInfo.maxNumRxPkts >= (ENET_SYSCFG_TOTAL_NUM_RX_PKT/2U));
EnetAppUtils_assert(rxChInfo.chIdx == 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_assert(dma_handle_ != nullptr);
return false;
}
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
eth_initRxReadyPktQ(dma_handle_, this);
open_ = true;
EnetAppUtils_print("rx_flow %u: rx flow open successfully\r\n", id);
return true;
}