2023-05-03 14:01:32 +03:00
/*
* eth . cpp
*
* Created on : 9 <EFBFBD> <EFBFBD> <EFBFBD> . 2023 <EFBFBD> .
* Author : sychev
*/
2023-06-26 18:22:30 +03:00
# include "free_rtos/ethernet/eth.hpp"
# include "free_rtos/ethernet/eth_vlan.h"
# include "free_rtos/ethernet/eth_ioctl.h"
2023-05-03 14:01:32 +03:00
# 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 ] ;
2023-09-22 10:59:11 +03:00
rxTaskPriority_ [ i ] = sett . rxTaskPriority [ i ] ;
rxTaskStackSize_ [ i ] = sett . rxTaskStackSize [ i ] ;
2023-05-03 14:01:32 +03:00
}
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 ;
}
2023-09-22 10:59:11 +03:00
if ( ! rx_flow_ [ i ] . open ( i , ENET_DMA_RX_CH0 + i , rxTaskPriority_ [ i ] , rxTaskStackSize_ [ i ] ) )
2023-05-03 14:01:32 +03:00
{
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 ;
}
}
2023-09-25 14:58:34 +03:00
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>
2023-05-03 14:01:32 +03:00
}
}
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 ( ) ) ;
2023-06-26 11:11:19 +03:00
if ( ! task_ [ e_taskLink ] . Create ( " LinkTask " , LINK_TASK_PRIORITY , eth_taskLinkTracking , ( void * ) this , LINK_TASK_STACK_SIZE ) )
2023-05-03 14:01:32 +03:00
{
EnetAppUtils_print ( " %s: Failed to create link task \r \n " , name_ . c_str ( ) ) ;
return false ;
}
return true ;
}