From 19769773c64d0371031c65dee2917cfb9ac803d7 Mon Sep 17 00:00:00 2001 From: "Lojewski, Evan" Date: Sat, 11 May 2019 08:33:02 -0600 Subject: Refactor network tx/rx code to allow a port structure allowing more ports than just the first to be used. --- ape/main.c | 5 +-- libs/Network/include/Network.h | 41 +++++++++++++++--- libs/Network/init.c | 96 +++++++++++++++++++++++++++++++----------- libs/Network/rx.c | 30 ++++++------- libs/Network/tx.c | 58 ++++++++++++------------- simulator/CMakeLists.txt | 22 +++++++--- simulator/HAL.cpp | 36 +++++++++++++--- 7 files changed, 200 insertions(+), 88 deletions(-) diff --git a/ape/main.c b/ape/main.c index 2264791..5f3a34d 100644 --- a/ape/main.c +++ b/ape/main.c @@ -46,7 +46,6 @@ #include #include -#include #include #include #include @@ -136,7 +135,7 @@ void handleBMCPacket(void) else { // Pass through to network - Network_TX_transmitPassthroughPacket(bytes); + Network_TX_transmitPassthroughPacket(bytes, &gPort0); } } } @@ -151,7 +150,7 @@ void __attribute__((noreturn)) loaderLoop(void) for (;;) { handleBMCPacket(); - Network_PassthroughRxPatcket(); + Network_PassthroughRxPatcket(&gPort0); handleCommand(); } } diff --git a/libs/Network/include/Network.h b/libs/Network/include/Network.h index 06bd57f..92074b4 100644 --- a/libs/Network/include/Network.h +++ b/libs/Network/include/Network.h @@ -45,25 +45,54 @@ #ifndef NETWORK_H #define NETWORK_H +#include #include +#include +#include +#include +#include +#include +#include +#include +#include #include #include +typedef struct { + /* TX Registers */ + volatile RegAPETxToNetPoolModeStatus_t *tx_mode; + volatile TX_PORT_t * tx_port; + volatile RegAPETxToNetBufferAllocator_t *tx_allocator; + volatile RegAPETxToNetDoorbell_t *tx_doorbell; + + /* RX Registers */ + volatile RegAPERxPoolModeStatus_t *rx_mode; + volatile RX_PORT_t *rx_port; + volatile RegAPERxbufoffset_t *rx_offset; + volatile RegAPERxPoolRetire_t *rx_retire; +} NetworkPort_t; + + +extern NetworkPort_t gPort0; +extern NetworkPort_t gPort1; +extern NetworkPort_t gPort2; +extern NetworkPort_t gPort3; + void Network_InitTxRx(void); uint32_t Network_TX_numBlocksNeeded(uint32_t frame_size); -int32_t Network_TX_allocateBlock(void); +int32_t Network_TX_allocateBlock(NetworkPort_t *port); -void Network_TX_transmitBePacket(uint8_t *packet, uint32_t length); -void Network_TX_transmitLePacket(uint8_t *packet, uint32_t length); +void Network_TX_transmitBePacket(uint8_t *packet, uint32_t length, NetworkPort_t *port); +void Network_TX_transmitLePacket(uint8_t *packet, uint32_t length, NetworkPort_t *port); -void Network_TX_transmitPassthroughPacket(uint32_t length); +void Network_TX_transmitPassthroughPacket(uint32_t length, NetworkPort_t* port); // void Network_TX_transmitPassthroughPacket(RegAPE_PERIBmcToNcRxStatus_t // rx_status); -bool Network_RxLePatcket(uint32_t *buffer, uint32_t *length); -bool Network_PassthroughRxPatcket(void); +bool Network_RxLePatcket(uint32_t *buffer, uint32_t *length, NetworkPort_t *port); +bool Network_PassthroughRxPatcket(NetworkPort_t *port); void Network_SetMACAddr(uint16_t high, uint32_t low, uint32_t index, bool enabled); diff --git a/libs/Network/init.c b/libs/Network/init.c index e50cdba..bab401f 100644 --- a/libs/Network/init.c +++ b/libs/Network/init.c @@ -641,6 +641,71 @@ static const FilterRuleInit_t gRuleInit[32] = { }, }; +NetworkPort_t gPort0 = { + .tx_port = &TX_PORT0, + .tx_allocator = &APE.TxToNetBufferAllocator0, + .tx_doorbell = &APE.TxToNetDoorbellFunc0, + + .rx_port = &RX_PORT0, + .rx_offset = &APE.RxbufoffsetFunc0, + .rx_retire = &APE.RxPoolRetire0, +}; + +NetworkPort_t gPort1 = { + .tx_port = &TX_PORT1, + .tx_allocator = &APE.TxToNetBufferAllocator1, + .tx_doorbell = &APE.TxToNetDoorbellFunc1, + + .rx_port = &RX_PORT1, + .rx_offset = &APE.RxbufoffsetFunc1, + .rx_retire = &APE.RxPoolRetire1, +}; + +NetworkPort_t gPort2 = { + .tx_port = &TX_PORT2, + .tx_allocator = &APE.TxToNetBufferAllocator2, + .tx_doorbell = &APE.TxToNetDoorbellFunc2, + + .rx_port = &RX_PORT2, + .rx_offset = &APE.RxbufoffsetFunc2, + .rx_retire = &APE.RxPoolRetire2, +}; + +NetworkPort_t gPort3 = { + .tx_port = &TX_PORT3, + .tx_allocator = &APE.TxToNetBufferAllocator3, + .tx_doorbell = &APE.TxToNetDoorbellFunc3, + + .rx_port = &RX_PORT3, + .rx_offset = &APE.RxbufoffsetFunc3, + .rx_retire = &APE.RxPoolRetire3, +}; + + +void Network_InitPort(NetworkPort_t *port) +{ + // Enable RX + RegAPERxPoolModeStatus_t rxMode; + rxMode.r32 = 0; + rxMode.bits.Reset = 1; + *(port->rx_mode) = rxMode; + + rxMode.bits.Reset = 0; + rxMode.bits.Enable = 1; + *(port->rx_mode) = rxMode; + + // Enable TX + RegAPETxToNetPoolModeStatus_t txMode; + txMode.r32 = 0; + txMode.bits.Reset = 1; + *(port->tx_mode) = txMode; + + txMode.bits.Reset = 0; + txMode.bits.Enable = 1; + *(port->tx_mode) = txMode; + +} + void Network_InitTxRx(void) { for(int i = 0; i < 32; i++) @@ -683,35 +748,18 @@ void Network_InitTxRx(void) // Ensure REG_EMAC_MODE__ENABLE_APE_{TX,RX}_PATH are set. // *** NOTE: Both bits are set in rmu.c ***/ - // Enable APE channel 0/0 + // Enable APE channel 0, 1, 2, 3 RegAPEMode_t mode; mode = APE.Mode; mode.bits.Event1 = 1; mode.bits.Channel0Enable = 1; + mode.bits.Channel1Enable = 1; mode.bits.Channel2Enable = 1; + mode.bits.Channel3Enable = 1; APE.Mode = mode; - - - - // Enable RX for funciton 0 - RegAPERxPoolModeStatus0_t rxMode; - rxMode.r32 = 0; - rxMode.bits.Reset = 1; - APE.RxPoolModeStatus0 = rxMode; - - rxMode.bits.Reset = 0; - rxMode.bits.Enable = 1; - APE.RxPoolModeStatus0 = rxMode; - - // Enable TX for function 0 - RegAPETxToNetPoolModeStatus0_t txMode; - txMode.r32 = 0; - txMode.bits.Reset = 1; - APE.TxToNetPoolModeStatus0 = txMode; - - txMode.bits.Reset = 0; - txMode.bits.Enable = 1; - APE.TxToNetPoolModeStatus0 = txMode; - + Network_InitPort(&gPort0); + Network_InitPort(&gPort1); + Network_InitPort(&gPort2); + Network_InitPort(&gPort3); } diff --git a/libs/Network/rx.c b/libs/Network/rx.c index fd6e883..81cb718 100644 --- a/libs/Network/rx.c +++ b/libs/Network/rx.c @@ -44,7 +44,7 @@ #include #include -#include +#include #include #include #include @@ -54,10 +54,10 @@ #include #endif -bool Network_RxLePatcket(uint32_t *buffer, uint32_t *bytes) +bool Network_RxLePatcket(uint32_t *buffer, uint32_t *bytes, NetworkPort_t *port) { - RegAPERxbufoffsetFunc0_t rxbuf; - rxbuf = APE.RxbufoffsetFunc0; + RegAPERxbufoffset_t rxbuf; + rxbuf = *((RegAPERxbufoffset_t*)port->rx_offset); if ((int)rxbuf.bits.Valid) { uint32_t rx_bytes = 0; @@ -80,7 +80,7 @@ bool Network_RxLePatcket(uint32_t *buffer, uint32_t *bytes) do { // printf("Block at %x\n", blockid); - RegRX_PORTIn_t *block = (RegRX_PORTIn_t *)&RX_PORT.In[RX_PORT_IN_ALL_BLOCK_WORDS * blockid]; + RegRX_PORTIn_t *block = (RegRX_PORTIn_t *)&port->rx_port->In[RX_PORT_IN_ALL_BLOCK_WORDS * blockid]; // printf("Control %x\n", (uint32_t)block[0].r32); control.r32 = block[0].r32; // printf(" Payload Len %d\n", control.bits.payload_length); @@ -114,16 +114,16 @@ bool Network_RxLePatcket(uint32_t *buffer, uint32_t *bytes) // disableNCSIHandling(); // enableNCSIHandling(); - RegAPERxPoolRetire0_t retire; + RegAPERxPoolRetire_t retire; retire.r32 = 0; retire.bits.Head = rxbuf.bits.Head; retire.bits.Tail = rxbuf.bits.Tail; retire.bits.Count = rxbuf.bits.Count; retire.bits.Retire = 1; - APE.RxPoolRetire0 = retire; + *((RegAPERxPoolRetire_t*)port->rx_retire) = retire; rxbuf.bits.Finished = 1; - APE.RxbufoffsetFunc0 = rxbuf; + *((RegAPERxbufoffset_t*)port->rx_offset) = rxbuf; *bytes = rx_bytes; @@ -135,10 +135,10 @@ bool Network_RxLePatcket(uint32_t *buffer, uint32_t *bytes) } } -bool Network_PassthroughRxPatcket(void) +bool Network_PassthroughRxPatcket(NetworkPort_t *port) { - RegAPERxbufoffsetFunc0_t rxbuf; - rxbuf = APE.RxbufoffsetFunc0; + RegAPERxbufoffset_t rxbuf; + rxbuf = *((RegAPERxbufoffset_t*)port->rx_offset); if ((int)rxbuf.bits.Valid) { #if CXX_SIMULATOR @@ -161,7 +161,7 @@ bool Network_PassthroughRxPatcket(void) while (count--) { // printf("Block at %x\n", blockid); - RegRX_PORTIn_t *block = (RegRX_PORTIn_t *)&RX_PORT.In[RX_PORT_IN_ALL_BLOCK_WORDS * blockid]; + RegRX_PORTIn_t *block = (RegRX_PORTIn_t *)&port->rx_port->In[RX_PORT_IN_ALL_BLOCK_WORDS * blockid]; // printf("Control %x\n", (uint32_t)block[0].r32); control.r32 = block[0].r32; // printf(" Payload Len %d\n", control.bits.payload_length); @@ -218,19 +218,19 @@ bool Network_PassthroughRxPatcket(void) } // Retire this block. - RegAPERxPoolRetire0_t retire; + RegAPERxPoolRetire_t retire; retire.r32 = (1 << 24); retire.bits.Head = blockid; retire.bits.Tail = blockid; retire.bits.Count = 1; - APE.RxPoolRetire0 = retire; + *((RegAPERxPoolRetire_t*)port->rx_retire) = retire; blockid = control.bits.next_block; } // Mark the frame as read. rxbuf.bits.Finished = 1; - APE.RxbufoffsetFunc0 = rxbuf; + *((RegAPERxbufoffset_t*)port->rx_offset) = rxbuf; return true; } diff --git a/libs/Network/tx.c b/libs/Network/tx.c index a2e998f..7625586 100644 --- a/libs/Network/tx.c +++ b/libs/Network/tx.c @@ -43,7 +43,7 @@ //////////////////////////////////////////////////////////////////////////////// #include -#include +#include #include #include #include @@ -97,24 +97,24 @@ uint32_t Network_TX_numBlocksNeeded(uint32_t frame_size) return blocks; } -int32_t __attribute__((noinline)) Network_TX_allocateBlock(void) +int32_t __attribute__((noinline)) Network_TX_allocateBlock(NetworkPort_t* port) { int32_t block; // Set the alloc bit. - RegAPETxToNetBufferAllocator0_t alloc; + RegAPETxToNetBufferAllocator_t alloc; alloc.r32 = 0; alloc.bits.RequestAllocation = 1; - APE.TxToNetBufferAllocator0 = alloc; + *((RegAPETxToNetBufferAllocator_t*)port->tx_allocator) = alloc; // Wait for state machine to finish - RegAPETxToNetBufferAllocator0_t status; + RegAPETxToNetBufferAllocator_t status; do { - status = APE.TxToNetBufferAllocator0; - } while (APE_TX_TO_NET_BUFFER_ALLOCATOR_0_STATE_PROCESSING == status.bits.State); + status = *((RegAPETxToNetBufferAllocator_t*)port->tx_allocator); + } while (APE_TX_TO_NET_BUFFER_ALLOCATOR_STATE_PROCESSING == status.bits.State); - if (APE_TX_TO_NET_BUFFER_ALLOCATOR_0_STATE_ALLOCATION_OK != status.bits.State) + if (APE_TX_TO_NET_BUFFER_ALLOCATOR_STATE_ALLOCATION_OK != status.bits.State) { block = -1; #if CXX_SIMULATOR @@ -265,7 +265,8 @@ static uint32_t inline Network_TX_initAdditionalBlock(RegTX_PORTOut_t *block, static inline void Network_TX_transmitPacket_internal(uint8_t *packet, uint32_t length, - bool big_endian) + bool big_endian, + NetworkPort_t *port) { if (!length) { @@ -280,7 +281,7 @@ static inline void Network_TX_transmitPacket_internal(uint8_t *packet, // First block int32_t tail; - int32_t first = tail = Network_TX_allocateBlock(); + int32_t first = tail = Network_TX_allocateBlock(port); if (first <= 0) { // Error @@ -289,9 +290,9 @@ static inline void Network_TX_transmitPacket_internal(uint8_t *packet, int32_t next_block = -1; if (blocks > 1) { - next_block = Network_TX_allocateBlock(); + next_block = Network_TX_allocateBlock(port); } - RegTX_PORTOut_t *block = (RegTX_PORTOut_t *)&TX_PORT.Out[TX_PORT_OUT_ALL_BLOCK_WORDS * first]; + RegTX_PORTOut_t *block = (RegTX_PORTOut_t *)&port->tx_port->Out[TX_PORT_OUT_ALL_BLOCK_WORDS * first]; consumed += Network_TX_initFirstBlock(block, length, blocks, next_block, &packet_32[consumed / 4], big_endian); @@ -299,11 +300,10 @@ static inline void Network_TX_transmitPacket_internal(uint8_t *packet, while (blocks--) { - block = (RegTX_PORTOut_t *)&TX_PORT - .Out[TX_PORT_OUT_ALL_BLOCK_WORDS * next_block]; + block = (RegTX_PORTOut_t *)&port->tx_port->Out[TX_PORT_OUT_ALL_BLOCK_WORDS * next_block]; if (blocks) { - next_block = Network_TX_allocateBlock(); + next_block = Network_TX_allocateBlock(port); consumed += Network_TX_initAdditionalBlock( block, next_block, length - consumed, &packet_32[consumed / 4], big_endian); @@ -318,23 +318,23 @@ static inline void Network_TX_transmitPacket_internal(uint8_t *packet, tail = next_block; } - RegAPETxToNetDoorbellFunc0_t doorbell; + RegAPETxToNetDoorbell_t doorbell; doorbell.r32 = 0; doorbell.bits.Head = first; doorbell.bits.Tail = tail; doorbell.bits.Length = total_blocks; - APE.TxToNetDoorbellFunc0 = doorbell; + *((RegAPETxToNetDoorbell_t*)port->tx_doorbell) = doorbell; } -void Network_TX_transmitBePacket(uint8_t *packet, uint32_t length) +void Network_TX_transmitBePacket(uint8_t *packet, uint32_t length, NetworkPort_t* port) { - Network_TX_transmitPacket_internal(packet, length, true); + Network_TX_transmitPacket_internal(packet, length, true, port); } -void Network_TX_transmitLePacket(uint8_t *packet, uint32_t length) +void Network_TX_transmitLePacket(uint8_t *packet, uint32_t length, NetworkPort_t* port) { - Network_TX_transmitPacket_internal(packet, length, false); + Network_TX_transmitPacket_internal(packet, length, false, port); } static uint32_t inline Network_TX_initFirstPassthroughBlock( @@ -441,7 +441,7 @@ static uint32_t inline Network_TX_initAdditionalPassthroughBlock( return control.bits.payload_length; } -void Network_TX_transmitPassthroughPacket(uint32_t length) +void Network_TX_transmitPassthroughPacket(uint32_t length, NetworkPort_t *port) { if (!length) { @@ -452,7 +452,7 @@ void Network_TX_transmitPassthroughPacket(uint32_t length) length -= 4; int32_t tail; - int32_t first = tail = Network_TX_allocateBlock(); + int32_t first = tail = Network_TX_allocateBlock(port); int32_t next_block = -1; uint32_t blocks = Network_TX_numBlocksNeeded(length); int total_blocks = blocks; @@ -460,19 +460,19 @@ void Network_TX_transmitPassthroughPacket(uint32_t length) if (blocks > 1) { - next_block = Network_TX_allocateBlock(); + next_block = Network_TX_allocateBlock(port); } - RegTX_PORTOut_t *block = (RegTX_PORTOut_t *)&TX_PORT.Out[TX_PORT_OUT_ALL_BLOCK_WORDS * first]; + RegTX_PORTOut_t *block = (RegTX_PORTOut_t *)&port->tx_port->Out[TX_PORT_OUT_ALL_BLOCK_WORDS * first]; length -= Network_TX_initFirstPassthroughBlock(block, length, blocks, next_block); blocks -= 1; while (blocks--) { - block = (RegTX_PORTOut_t *)&TX_PORT.Out[TX_PORT_OUT_ALL_BLOCK_WORDS * next_block]; + block = (RegTX_PORTOut_t *)&port->tx_port->Out[TX_PORT_OUT_ALL_BLOCK_WORDS * next_block]; if (blocks) { - next_block = Network_TX_allocateBlock(); + next_block = Network_TX_allocateBlock(port); length -= Network_TX_initAdditionalPassthroughBlock( block, next_block, length); } @@ -484,13 +484,13 @@ void Network_TX_transmitPassthroughPacket(uint32_t length) tail = next_block; } - RegAPETxToNetDoorbellFunc0_t doorbell; + RegAPETxToNetDoorbell_t doorbell; doorbell.r32 = 0; doorbell.bits.Head = first; doorbell.bits.Tail = tail; doorbell.bits.Length = total_blocks; - APE.TxToNetDoorbellFunc0 = doorbell; + *((RegAPETxToNetDoorbell_t*)port->tx_doorbell) = doorbell; // Read last RX word (FCS) to clear the buffer uint32_t data = APE_PERI.BmcToNcReadBuffer.r32; diff --git a/simulator/CMakeLists.txt b/simulator/CMakeLists.txt index 57e500b..0d0d7b1 100644 --- a/simulator/CMakeLists.txt +++ b/simulator/CMakeLists.txt @@ -32,11 +32,23 @@ simulator_add_library(${PROJECT_NAME} STATIC APE_NVIC.cpp APE_NVIC_sim.cpp - APE_TX_PORT.cpp - APE_TX_PORT_sim.cpp - - APE_RX_PORT.cpp - APE_RX_PORT_sim.cpp + APE_TX_PORT0.cpp + APE_TX_PORT0_sim.cpp + APE_TX_PORT1.cpp + APE_TX_PORT1_sim.cpp + APE_TX_PORT2.cpp + APE_TX_PORT2_sim.cpp + APE_TX_PORT3.cpp + APE_TX_PORT3_sim.cpp + + APE_RX_PORT0.cpp + APE_RX_PORT0_sim.cpp + APE_RX_PORT1.cpp + APE_RX_PORT1_sim.cpp + APE_RX_PORT2.cpp + APE_RX_PORT2_sim.cpp + APE_RX_PORT3.cpp + APE_RX_PORT3_sim.cpp ) diff --git a/simulator/HAL.cpp b/simulator/HAL.cpp index 01f9032..e2f5161 100644 --- a/simulator/HAL.cpp +++ b/simulator/HAL.cpp @@ -12,8 +12,14 @@ #include #include #include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include @@ -286,11 +292,29 @@ bool initHAL(const char *pci_path, int wanted_function) init_APE_NVIC(); init_APE_NVIC_sim(NULL); - init_APE_TX_PORT(); - init_APE_TX_PORT_sim(NULL); + init_APE_TX_PORT0(); + init_APE_TX_PORT0_sim(NULL); - init_APE_RX_PORT(); - init_APE_RX_PORT_sim(NULL); + init_APE_RX_PORT0(); + init_APE_RX_PORT0_sim(NULL); + + init_APE_TX_PORT1(); + init_APE_TX_PORT1_sim(NULL); + + init_APE_RX_PORT1(); + init_APE_RX_PORT1_sim(NULL); + + init_APE_TX_PORT2(); + init_APE_TX_PORT2_sim(NULL); + + init_APE_RX_PORT2(); + init_APE_RX_PORT2_sim(NULL); + + init_APE_TX_PORT3(); + init_APE_TX_PORT3_sim(NULL); + + init_APE_RX_PORT3(); + init_APE_RX_PORT3_sim(NULL); return true; } -- cgit v1.2.1