EthInterface: notifications
- queues have been replaced by OS queues - serving plain interrupts is replaced by queuing events
This commit is contained in:
parent
903258a796
commit
754b43c51a
@ -4,9 +4,16 @@
|
|||||||
|
|
||||||
#include "eth_interface.h"
|
#include "eth_interface.h"
|
||||||
#include "dynmem.h"
|
#include "dynmem.h"
|
||||||
#include "utils.h"
|
|
||||||
#include "etherlib_options.h"
|
|
||||||
#include "etherlib/prefab/conn_blocks/ethernet_connblock.h"
|
#include "etherlib/prefab/conn_blocks/ethernet_connblock.h"
|
||||||
|
#include "etherlib_options.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
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) {
|
static int ethintf_llrecv(EthIODef *io, const RawPckt *pckt) {
|
||||||
ethinf_receive((EthInterface *)io->tag, pckt);
|
ethinf_receive((EthInterface *)io->tag, pckt);
|
||||||
@ -14,23 +21,12 @@ static int ethintf_llrecv(EthIODef * io, const RawPckt * pckt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int ethintf_llrxnotify(EthIODef *io) {
|
static int ethintf_llrxnotify(EthIODef *io) {
|
||||||
ethinf_notify((EthInterface *) io->tag);
|
ethinf_push_notification((EthInterface *)io->tag, ETH_IIE_RECV_NOTIFY, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ethinf_lllinkchg(EthIODef *io, int ls) {
|
static int ethinf_lllinkchg(EthIODef *io, int ls) {
|
||||||
EthInterface * intf = (EthInterface *) io->tag;
|
ethinf_push_notification((EthInterface *)io->tag, ETH_IIE_LINK_CHG_NOTIFY, (uint16_t)ls);
|
||||||
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);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,7 +54,9 @@ EthInterface *ethintf_new(EthIODef * io) {
|
|||||||
|
|
||||||
ethIntf->txQ = mq_create(ETHLIB_DEF_MQ_SIZE);
|
ethIntf->txQ = mq_create(ETHLIB_DEF_MQ_SIZE);
|
||||||
ethIntf->rxQ = 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_DEFINE(task_ethintf, osPriorityHigh, 512, ethIntf);
|
||||||
ETHLIB_OS_THREAD_CREATE(task_ethintf, ethIntf);
|
ETHLIB_OS_THREAD_CREATE(task_ethintf, ethIntf);
|
||||||
|
|
||||||
@ -78,13 +76,43 @@ EthInterface *ethintf_new(EthIODef * io) {
|
|||||||
static ThreadReturnType task_ethintf(ThreadParamType param) {
|
static ThreadReturnType task_ethintf(ThreadParamType param) {
|
||||||
EthInterface *intf = (EthInterface *)param;
|
EthInterface *intf = (EthInterface *)param;
|
||||||
while (true) {
|
while (true) {
|
||||||
ETHLIB_OS_SEM_WAIT(&intf->rxSem);
|
// 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
|
intf->ioDef->llRxRead(intf->ioDef); // read packets, will invoke RxStore
|
||||||
while (mq_avail(intf->rxQ) > 0) {
|
while (mq_avail(intf->rxQ) > 0) {
|
||||||
RawPckt rawPckt = mq_top(intf->rxQ);
|
RawPckt rawPckt = mq_top(intf->rxQ);
|
||||||
mq_pop(intf->rxQ);
|
mq_pop(intf->rxQ);
|
||||||
packsieve_input(&intf->sieve, &rawPckt);
|
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) {
|
void ethinf_transmit(EthInterface *intf, const RawPckt *rawPckt) {
|
||||||
mq_push(intf->txQ, rawPckt); // push packet onto the message queue
|
mq_push(intf->txQ, rawPckt); // push packet onto the message queue
|
||||||
|
ethinf_push_notification(intf, ETH_IIE_TRANSMIT_NOTIFY, 0); // notify processing thread of the peding transmit
|
||||||
intf->ioDef->llTxTrigger(intf->ioDef, intf->txQ);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ethinf_notify(EthInterface *intf) {
|
void ethinf_push_notification(EthInterface *intf, uint16_t event_code, uint16_t event_data) {
|
||||||
ETHLIB_OS_SEM_POST(&intf->rxSem);
|
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) {
|
void ethinf_set_capabilities(EthInterface *intf, uint32_t cap) {
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "arp_cache.h"
|
#include "arp_cache.h"
|
||||||
#include "connection_block.h"
|
#include "connection_block.h"
|
||||||
#include "msg_queue.h"
|
#include "msg_queue.h"
|
||||||
|
#include "gen_queue.h"
|
||||||
#include "prefab/conn_blocks/ipv4/ip_assembler.h"
|
#include "prefab/conn_blocks/ipv4/ip_assembler.h"
|
||||||
#include "prefab/packet_parsers/dhcp.h"
|
#include "prefab/packet_parsers/dhcp.h"
|
||||||
|
|
||||||
@ -48,7 +49,7 @@ typedef void (*EthIntfEvtCb)(struct EthInterface_ * intf);
|
|||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ETH_EVT_LINK_CHANGE = 0,
|
ETH_EVT_LINK_CHANGE = 0,
|
||||||
ETH_EVT_IP_CHANGE = 1
|
ETH_EVT_IP_CHANGE = 1,
|
||||||
} EthIntfEvIndex;
|
} EthIntfEvIndex;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -76,7 +77,8 @@ typedef struct EthInterface_ {
|
|||||||
ConnBlock arpCb; ///< ARP connection block
|
ConnBlock arpCb; ///< ARP connection block
|
||||||
MsgQueue * txQ; ///< Transmit queue
|
MsgQueue * txQ; ///< Transmit queue
|
||||||
MsgQueue * rxQ; ///< Receive 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
|
IPv4Assembler * ipra; ///< IPv4 reassembler
|
||||||
EthIntfEventCbTable evtCbTable; ///< Event callback table
|
EthIntfEventCbTable evtCbTable; ///< Event callback table
|
||||||
bool linkState; ///< Interface link state
|
bool linkState; ///< Interface link state
|
||||||
@ -96,11 +98,21 @@ EthInterface *ethintf_new(EthIODef * io);
|
|||||||
void ethinf_receive(EthInterface *intf, const RawPckt *rawPckt);
|
void ethinf_receive(EthInterface *intf, const RawPckt *rawPckt);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notify interface of a received, buffered packet, which needs transferred
|
* Notify interface of some event occured (e.g. a received, buffered packet, which needs to get
|
||||||
* from the low level Ethernet-driver.
|
* transferred from the low level Ethernet-driver, a link change occured etc.)
|
||||||
* @param intf Pointer to Ethernet-interface
|
* @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.
|
* Transmit packet.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user