From 754b43c51a18e4eccc09ca3deadcc69ebbd70c89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wiesner=20Andr=C3=A1s?= Date: Tue, 31 Oct 2023 12:01:34 +0100 Subject: [PATCH] EthInterface: notifications - queues have been replaced by OS queues - serving plain interrupts is replaced by queuing events --- eth_interface.c | 111 ++++++++++++++++++++++++++++++++---------------- eth_interface.h | 22 +++++++--- 2 files changed, 92 insertions(+), 41 deletions(-) diff --git a/eth_interface.c b/eth_interface.c index 318f10b..17827de 100644 --- a/eth_interface.c +++ b/eth_interface.c @@ -4,37 +4,33 @@ #include "eth_interface.h" #include "dynmem.h" -#include "utils.h" -#include "etherlib_options.h" #include "etherlib/prefab/conn_blocks/ethernet_connblock.h" +#include "etherlib_options.h" +#include "utils.h" -static int ethintf_llrecv(EthIODef * io, const RawPckt * pckt) { - ethinf_receive((EthInterface *) io->tag, pckt); +typedef enum { + ETH_IIE_RECV_NOTIFY = 0, + ETH_IIE_LINK_CHG_NOTIFY, + ETH_IIE_TRANSMIT_NOTIFY, + ETH_IIE_UNKNOWN = 0xFFFF +} EthIntfInternalEvent; + +static int ethintf_llrecv(EthIODef *io, const RawPckt *pckt) { + ethinf_receive((EthInterface *)io->tag, pckt); return 0; } -static int ethintf_llrxnotify(EthIODef * io) { - ethinf_notify((EthInterface *) io->tag); +static int ethintf_llrxnotify(EthIODef *io) { + ethinf_push_notification((EthInterface *)io->tag, ETH_IIE_RECV_NOTIFY, 0); return 0; } -static int ethinf_lllinkchg(EthIODef * io, int ls) { - EthInterface * intf = (EthInterface *) io->tag; - ethinf_set_link_state(intf, ls); - - if (intf->dhcp != NULL) { - if (ls) { // if link is on - dhcp_start(intf->dhcp); - } else { // if link is off - dhcp_stop(intf->dhcp); - } - } - - MSG("Link state: %d\n", ls); +static int ethinf_lllinkchg(EthIODef *io, int ls) { + ethinf_push_notification((EthInterface *)io->tag, ETH_IIE_LINK_CHG_NOTIFY, (uint16_t)ls); return 0; } -static void ethintf_register(EthInterface * intf) { +static void ethintf_register(EthInterface *intf) { intf->ioDef->tag = intf; intf->ioDef->llRxStore = ethintf_llrecv; intf->ioDef->llRxNotify = ethintf_llrxnotify; @@ -42,10 +38,10 @@ static void ethintf_register(EthInterface * intf) { } // interface processing thread -static ThreadReturnType task_ethintf (ThreadParamType param); +static ThreadReturnType task_ethintf(ThreadParamType param); -EthInterface *ethintf_new(EthIODef * io) { - EthInterface * ethIntf = (EthInterface *)dynmem_alloc(sizeof(EthInterface)); +EthInterface *ethintf_new(EthIODef *io) { + EthInterface *ethIntf = (EthInterface *)dynmem_alloc(sizeof(EthInterface)); ASSERT_NULL(ethIntf); memset(ðIntf->sieve.layer0, 0, sizeof(PcktSieveLayer)); ethIntf->sieve.intf = ethIntf; @@ -58,7 +54,9 @@ EthInterface *ethintf_new(EthIODef * io) { ethIntf->txQ = mq_create(ETHLIB_DEF_MQ_SIZE); ethIntf->rxQ = mq_create(ETHLIB_DEF_MQ_SIZE); - ETHLIB_OS_SEM_CREATE(ðIntf->rxSem, ETHLIB_DEF_MQ_SIZE); + + ETHLIB_OS_QUEUE_CREATE(ethIntf->eventQ, ETHLIB_DEF_MQ_SIZE, uint32_t); + // ETHLIB_OS_SEM_CREATE(ðIntf->eventSem, ETHLIB_DEF_MQ_SIZE); ETHLIB_OS_THREAD_DEFINE(task_ethintf, osPriorityHigh, 512, ethIntf); ETHLIB_OS_THREAD_CREATE(task_ethintf, ethIntf); @@ -75,15 +73,45 @@ EthInterface *ethintf_new(EthIODef * io) { return ethIntf; } -static ThreadReturnType task_ethintf (ThreadParamType param) { - EthInterface * intf = (EthInterface *) param; +static ThreadReturnType task_ethintf(ThreadParamType param) { + EthInterface *intf = (EthInterface *)param; while (true) { - ETHLIB_OS_SEM_WAIT(&intf->rxSem); - intf->ioDef->llRxRead(intf->ioDef); // read packets, will invoke RxStore - while (mq_avail(intf->rxQ) > 0) { - RawPckt rawPckt = mq_top(intf->rxQ); - mq_pop(intf->rxQ); - packsieve_input(&intf->sieve, &rawPckt); + // fetch notification + uint16_t event_code = ETH_IIE_UNKNOWN; + uint16_t event_data; + ethinf_pull_notification(intf, &event_code, &event_data); + + // act accordingly... + switch (event_code) { + case ETH_IIE_RECV_NOTIFY: { + intf->ioDef->llRxRead(intf->ioDef); // read packets, will invoke RxStore + while (mq_avail(intf->rxQ) > 0) { + RawPckt rawPckt = mq_top(intf->rxQ); + mq_pop(intf->rxQ); + packsieve_input(&intf->sieve, &rawPckt); + } + + } break; + case ETH_IIE_LINK_CHG_NOTIFY: { + bool ls = event_data; + ethinf_set_link_state(intf, ls); + + if (intf->dhcp != NULL) { + if (ls) { // if link is on + dhcp_start(intf->dhcp); + } else { // if link is off + dhcp_stop(intf->dhcp); + } + } + + MSG("Link state: %d\n", ls); + } break; + case ETH_IIE_TRANSMIT_NOTIFY: { + intf->ioDef->llTxTrigger(intf->ioDef, intf->txQ); + } break; + default: + MSG("UNKNOWN event!\n"); + break; } } } @@ -98,12 +126,23 @@ void ethinf_receive(EthInterface *intf, const RawPckt *rawPckt) { void ethinf_transmit(EthInterface *intf, const RawPckt *rawPckt) { mq_push(intf->txQ, rawPckt); // push packet onto the message queue - - intf->ioDef->llTxTrigger(intf->ioDef, intf->txQ); + ethinf_push_notification(intf, ETH_IIE_TRANSMIT_NOTIFY, 0); // notify processing thread of the peding transmit } -void ethinf_notify(EthInterface *intf) { - ETHLIB_OS_SEM_POST(&intf->rxSem); +void ethinf_push_notification(EthInterface *intf, uint16_t event_code, uint16_t event_data) { + uint32_t cpd = (event_data << 16) | event_code; // create event compound + ETHLIB_OS_QUEUE_PUSH(intf->eventQ, cpd); +} + +void ethinf_pull_notification(EthInterface *intf, uint16_t *event_code, uint16_t *event_data) { + uint32_t cpd; + cpd = ETHLIB_OS_QUEUE_POP(intf->eventQ); // wait for event semaphore + + // retrieve event code and data + *event_code = cpd & 0xFFFF; + *event_data = (cpd >> 16) & 0xFFFF; + + //MSG("EC: %d\n", *event_code); } void ethinf_set_capabilities(EthInterface *intf, uint32_t cap) { diff --git a/eth_interface.h b/eth_interface.h index 39d5d97..703631a 100644 --- a/eth_interface.h +++ b/eth_interface.h @@ -9,6 +9,7 @@ #include "arp_cache.h" #include "connection_block.h" #include "msg_queue.h" +#include "gen_queue.h" #include "prefab/conn_blocks/ipv4/ip_assembler.h" #include "prefab/packet_parsers/dhcp.h" @@ -48,7 +49,7 @@ typedef void (*EthIntfEvtCb)(struct EthInterface_ * intf); typedef enum { ETH_EVT_LINK_CHANGE = 0, - ETH_EVT_IP_CHANGE = 1 + ETH_EVT_IP_CHANGE = 1, } EthIntfEvIndex; /** @@ -76,7 +77,8 @@ typedef struct EthInterface_ { ConnBlock arpCb; ///< ARP connection block MsgQueue * txQ; ///< Transmit queue MsgQueue * rxQ; ///< Receive queue - ETHLIB_OS_SEM_TYPE rxSem; ///< Receive queue semaphore + ETHLIB_OS_QUEUE_TYPE eventQ; ///< Event queue + //ETHLIB_OS_SEM_TYPE eventSem; ///< Event queue semaphore IPv4Assembler * ipra; ///< IPv4 reassembler EthIntfEventCbTable evtCbTable; ///< Event callback table bool linkState; ///< Interface link state @@ -96,11 +98,21 @@ EthInterface *ethintf_new(EthIODef * io); void ethinf_receive(EthInterface *intf, const RawPckt *rawPckt); /** - * Notify interface of a received, buffered packet, which needs transferred - * from the low level Ethernet-driver. + * Notify interface of some event occured (e.g. a received, buffered packet, which needs to get + * transferred from the low level Ethernet-driver, a link change occured etc.) * @param intf Pointer to Ethernet-interface + * @param event_code Event code + * @param event_data Event data */ -void ethinf_notify(EthInterface *intf); +void ethinf_push_notification(EthInterface *intf, uint16_t event_code, uint16_t event_data); + +/** + * Pull formerly pushed notification from the event queue. + * @param intf Pointer to Ethernet-interface + * @param event_code pointer to event code + * @param event_data pointer to event data + */ +void ethinf_pull_notification(EthInterface *intf, uint16_t * event_code, uint16_t * event_data); /** * Transmit packet.