302 lines
9.4 KiB
C++
302 lines
9.4 KiB
C++
|
|
/*
|
|||
|
|
* eth.cpp
|
|||
|
|
*
|
|||
|
|
* Created on: 9 <EFBFBD><EFBFBD><EFBFBD>. 2023 <EFBFBD>.
|
|||
|
|
* Author: sychev
|
|||
|
|
*/
|
|||
|
|
#include "ethernet/eth.hpp"
|
|||
|
|
#include "ethernet/eth_vlan.h"
|
|||
|
|
#include "ethernet/eth_ioctl.h"
|
|||
|
|
|
|||
|
|
#include <networking/enet/core/include/core/enet_ioctl.h>
|
|||
|
|
#include <kernel/dpl/DebugP.h>
|
|||
|
|
#include <kernel/dpl/ClockP.h>
|
|||
|
|
#include <cstring>
|
|||
|
|
|
|||
|
|
/*----------------------------------------------------------------------*/
|
|||
|
|
/**
|
|||
|
|
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> sysconfig.
|
|||
|
|
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <build_name>/syscfg
|
|||
|
|
*/
|
|||
|
|
#include "ti_enet_config.h"
|
|||
|
|
|
|||
|
|
#ifdef __cplusplus
|
|||
|
|
extern "C" {
|
|||
|
|
#endif
|
|||
|
|
#include "ti_enet_open_close.h"
|
|||
|
|
#ifdef __cplusplus
|
|||
|
|
}
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
/*----------------------------------------------------------------------*/
|
|||
|
|
|
|||
|
|
using namespace free_rtos;
|
|||
|
|
|
|||
|
|
free_rtos::Eth::Eth() :
|
|||
|
|
rx_flow_{{hostMacAddr_, eth_stack_}, {hostMacAddr_, eth_stack_}},
|
|||
|
|
sem_{Semaphore(Semaphore::e_semTypeCounting, 0, 10)},
|
|||
|
|
eth_stack_{tx_flow_}
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool free_rtos::Eth::Init(Settings& sett)
|
|||
|
|
{
|
|||
|
|
id_ = sett.id;
|
|||
|
|
name_ = sett.name;
|
|||
|
|
enetType_ = sett.enetType;
|
|||
|
|
instId_ = sett.instId;
|
|||
|
|
macPortNum_ = sett.macPortNum;
|
|||
|
|
vlan_id_ = sett.vlan_id;
|
|||
|
|
|
|||
|
|
if (instId_ != e_ethInstSwitch) {
|
|||
|
|
EnetAppUtils_print("%s: Unsupported instId value: %u. Only %d(e_ethInstSwitch) instance id supported\r\n", name_.c_str(), instId_, e_ethInstSwitch);
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (enetType_ != ENET_ICSSG_SWITCH) {
|
|||
|
|
EnetAppUtils_print("%s: Unsupported enetType value: %u. Only %d(ENET_ICSSG_SWITCH) enet type supported\r\n", name_.c_str(), enetType_, ENET_ICSSG_SWITCH);
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (sett.macPortNum != e_ethMacTotal) {
|
|||
|
|
EnetAppUtils_print("%s: Invalid mac port number: %u. In SWITCH mode mac port number must be 2, current value: %u\r\n", name_.c_str(), macPortNum_);
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for (int i = 0; i < macPortNum_; ++i) {
|
|||
|
|
linkUp_[i] = false;
|
|||
|
|
macPort_[i] = sett.macPort[i];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
core_id_ = EnetSoc_getCoreId();
|
|||
|
|
|
|||
|
|
host_ready_ = false;
|
|||
|
|
|
|||
|
|
eth_stack_.init(sett.eth_stack_sett);
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// Callback <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ioctl
|
|||
|
|
static void eth_asyncIoctlCb(Enet_Event evt,
|
|||
|
|
uint32_t evtNum,
|
|||
|
|
void *evtCbArgs,
|
|||
|
|
void *arg1,
|
|||
|
|
void *arg2)
|
|||
|
|
{
|
|||
|
|
Eth * eth = (Eth *)evtCbArgs;
|
|||
|
|
|
|||
|
|
if (eth != nullptr) {
|
|||
|
|
eth->ioctl_callback();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void free_rtos::Eth::ioctl_callback()
|
|||
|
|
{
|
|||
|
|
sem_[e_signalIoctl].post();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static void eth_taskLinkTracking(void *args) {
|
|||
|
|
Eth * eth = (Eth *)args;
|
|||
|
|
|
|||
|
|
if (eth != nullptr) {
|
|||
|
|
eth->link_task();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool free_rtos::Eth::host_init()
|
|||
|
|
{
|
|||
|
|
if (host_ready_) {
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Enet_IoctlPrms prms;
|
|||
|
|
int32_t status = ENET_SOK;
|
|||
|
|
uint16_t vlanId = (uint16_t)vlan_id_;
|
|||
|
|
|
|||
|
|
if (enetType_ != ENET_ICSSG_SWITCH)
|
|||
|
|
{
|
|||
|
|
EnetAppUtils_print("%s: unsupported enet type: %u. Only %u(ENET_ICSSG_SWITCH) type supported\n\r",
|
|||
|
|
name_.c_str(), enetType_, ENET_ICSSG_SWITCH);
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
EnetAppUtils_print("%s: Host initialisation\n\r", name_.c_str());
|
|||
|
|
EnetAppUtils_print("%s: Set MAC addr: ", name_.c_str());
|
|||
|
|
EnetAppUtils_printMacAddr(&hostMacAddr_.bytes[0U]);
|
|||
|
|
|
|||
|
|
Icssg_MacAddr addr; // FIXME Icssg_MacAddr type
|
|||
|
|
|
|||
|
|
/* Set host port's MAC address */
|
|||
|
|
EnetUtils_copyMacAddr(&addr.macAddr[0U], &hostMacAddr_.bytes[0U]);
|
|||
|
|
|
|||
|
|
ENET_IOCTL_SET_IN_ARGS(&prms, &addr);
|
|||
|
|
|
|||
|
|
status = eth_ioctl(handleInfo_.hEnet, core_id_, ICSSG_HOSTPORT_IOCTL_SET_MACADDR, &prms);
|
|||
|
|
|
|||
|
|
if (ENET_SOK != status)
|
|||
|
|
{
|
|||
|
|
EnetAppUtils_print("%s: ERROR: Host initialisation failure\n\r", name_.c_str());
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
status = eth_vlan_init(handleInfo_.hEnet, core_id_, vlanId, enetType_);
|
|||
|
|
|
|||
|
|
if (ENET_SOK != status)
|
|||
|
|
{
|
|||
|
|
EnetAppUtils_print("%s: ERROR: Host initialisation failure\n\r", name_.c_str());
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
host_ready_ = true;
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
void free_rtos::Eth::link_task()
|
|||
|
|
{
|
|||
|
|
bool linkUp;
|
|||
|
|
Enet_MacPort macPort;
|
|||
|
|
Enet_IoctlPrms prms;
|
|||
|
|
IcssgMacPort_SetPortStateInArgs setPortStateInArgs;
|
|||
|
|
|
|||
|
|
int32_t status = ENET_SOK;
|
|||
|
|
while(1)
|
|||
|
|
{
|
|||
|
|
for (int i = 0; i < macPortNum_; ++i)
|
|||
|
|
{
|
|||
|
|
macPort = macPort_[i];
|
|||
|
|
linkUp = false;
|
|||
|
|
|
|||
|
|
ENET_IOCTL_SET_INOUT_ARGS(&prms, &macPort, &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);
|
|||
|
|
linkUp = false;
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
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");
|
|||
|
|
if (linkUp)
|
|||
|
|
{
|
|||
|
|
EnetAppUtils_print("link_task: %s: Set port state to 'Forward'\r\n", name_.c_str());
|
|||
|
|
setPortStateInArgs.macPort = macPort;
|
|||
|
|
setPortStateInArgs.portState = ICSSG_PORT_STATE_FORWARD;
|
|||
|
|
|
|||
|
|
ENET_IOCTL_SET_IN_ARGS(&prms, &setPortStateInArgs);
|
|||
|
|
status = eth_ioctl(handleInfo_.hEnet, core_id_, ICSSG_PER_IOCTL_SET_PORT_STATE, &prms);
|
|||
|
|
|
|||
|
|
if (status == ENET_SINPROGRESS)
|
|||
|
|
{
|
|||
|
|
/* Wait for asyc ioctl to complete */
|
|||
|
|
do
|
|||
|
|
{
|
|||
|
|
Enet_poll(handleInfo_.hEnet, ENET_EVT_ASYNC_CMD_RESP, NULL, 0U);
|
|||
|
|
status = sem_[e_signalIoctl].pend();
|
|||
|
|
} while(status != SystemP_SUCCESS);
|
|||
|
|
|
|||
|
|
status = ENET_SOK;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
EnetAppUtils_print("link_task: %s: Failed to set port state: %d\n", name_.c_str(), status);
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD> SWITCH)
|
|||
|
|
if (!tx_flow_.open(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))
|
|||
|
|
{
|
|||
|
|
EnetAppUtils_print("link_task: %s: Failed to open rx flow: %u\n", name_.c_str(), i);
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// e_ethMac0
|
|||
|
|
if (i == e_ethMac0)
|
|||
|
|
{
|
|||
|
|
if (!host_init()) {
|
|||
|
|
EnetAppUtils_print("link_task: %s: Failed to init host\r\n", name_.c_str());
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else if (i == e_ethMac1) {
|
|||
|
|
//rx_flow_[i].set_passive(); /// <20><><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
tx_flow_.enable((TEthMacPorts)i);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
tx_flow_.disable((TEthMacPorts)i);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
linkUp_[i] = linkUp;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
ClockP_usleep(100000); // 100ms /// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 10<31><30> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool free_rtos::Eth::Open()
|
|||
|
|
{
|
|||
|
|
int32_t status;
|
|||
|
|
|
|||
|
|
EnetAppUtils_print("%s: Init peripheral clocks\r\n", name_.c_str());
|
|||
|
|
EnetAppUtils_enableClocks(enetType_, instId_);
|
|||
|
|
|
|||
|
|
EnetAppUtils_print("%s: Open enet driver\r\n", name_.c_str());
|
|||
|
|
|
|||
|
|
status = EnetApp_driverOpen(enetType_, instId_);
|
|||
|
|
if (ENET_SOK != status) {
|
|||
|
|
EnetAppUtils_print("%s: fail to open enet driver\r\n", name_.c_str());
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
EnetAppUtils_print("%s: Init handle info\r\n", name_.c_str());
|
|||
|
|
EnetApp_acquireHandleInfo(enetType_, instId_, &handleInfo_);
|
|||
|
|
|
|||
|
|
EnetAppUtils_print("%s: Open peripherals\r\n", name_.c_str());
|
|||
|
|
|
|||
|
|
if (Enet_isIcssFamily(enetType_))
|
|||
|
|
{
|
|||
|
|
EnetAppUtils_print("%s: Register async IOCTL callback\r\n", name_.c_str());
|
|||
|
|
Enet_registerEventCb(handleInfo_.hEnet,
|
|||
|
|
ENET_EVT_ASYNC_CMD_RESP,
|
|||
|
|
0U,
|
|||
|
|
eth_asyncIoctlCb,
|
|||
|
|
(void *)this);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
EnetAppUtils_print("Error: the %s subsystem doesn't relates to Icss family\r\n", name_.c_str());
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
EnetAppUtils_print("%s: Attach core id %u on peripherals\r\n", name_.c_str(), core_id_);
|
|||
|
|
EnetApp_coreAttach(enetType_, instId_, core_id_, &attachInfo_);
|
|||
|
|
|
|||
|
|
EnetAppUtils_print("%s: Create link tracking tasks\r\n", name_.c_str());
|
|||
|
|
|
|||
|
|
if (!task_[e_taskLink].Create("LinkTask", e_linkTaskPriority, eth_taskLinkTracking, (void*)this, (10U * 1024U)))
|
|||
|
|
{
|
|||
|
|
EnetAppUtils_print("%s: Failed to create link task\r\n", name_.c_str());
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|