Title: eth_port_t / osdep_eth_port_t


Each ethernet card on a system will have one eth_port_t associated with it. In other words, if there is only a single ethernet card on a system, eth_port_table[] will have only a single element. eth_port_t minus the osdep_eth_port_t field is the OS independent portion of the ethernet configuration.

typedef struct eth_port

{
int etp_flags;
ether_addr_t etp_ethaddr;
acc_t *etp_wr_pack, *etp_rd_pack;
struct eth_fd *etp_type_any;
struct eth_fd *etp_type[ETH_TYPE_HASH_NR];
event_t etp_sendev;

osdep_eth_port_t etp_osdep;
} eth_port_t;
The OS dependent (= osdep) part of the ethernet port configuration is osdep_eth_port_t. In other words, if you were to port this network service to another OS, you'd need to create an osdep_eth_port_t that matched your OS.

typedef struct osdep_eth_port

{
int etp_task;
int etp_port;
int etp_recvconf;
iovec_t etp_wr_iovec[IOVEC_NR];
iovec_t etp_rd_iovec[RD_IOVEC];
event_t etp_recvev;
message etp_sendrepl;
message etp_recvrepl;

} osdep_eth_port_t;
int etp_flags:

Initialized to EPF_ENABLED in osdep_eth_init(). In setup_read(), if data has not been received by the ethernet task, etp_flags is set to EPF_READ_IP (although I don't know why yet. If the ethernet task has not delivered a packet yet and another packet is also waiting to be delivered, the EPF_MORE2WRITE flag is set.


ether_addr_t etp_ethaddr:

The ethernet address of the port. This will be a 6 octet number like 00-E0-81-00-29-F6 (the ethernet address of my system). The address of the ethernet port is obtained by querying the ethernet task and disassembling its response. This ethernet address is generally used as the source address for outgoing packets. However, if an ethernet file descriptor is in promiscuous mode, the file descriptor not only accepts any packet regardless of destination ethernet address but can also send out packets with any source ethernet address (not just the ethernet card's address).


typedef struct ether_addr 

{
u8_t ea_addr[6];
} ether_addr_t;
acc_t *etp_wr_pack:

The queueing for ethernet packets being sent out by the ethernet task is somewhat convoluted. If no ethernet packets are waiting to be sent out by the ethernet task (driver),
eth_write_port() stores an ethernet packet in the etp_wr_pack field until the packet is sent off by the ethernet task. After the ethernet task successfully sends the packet off, this field is set to NULL (either by eth_write_port() or write_int(). If the ethernet task cannot immediately send the ethernet packet off, the packet remains in etp_wr_pack. If another packet arrives for an ip port to send off to the ethernet port, the ip port encapsulates the ip packet and the resulting ethernet packet is placed in the dl_eth.de_frame field of the ip port. If an ip port then has additional packets that it wishes to send out, the packets are placed in the dl_eth.de_q_head/dl_eth.de_q_tail queue until the ethernet packets in etp_wr_pack and dl_eth.de_frame are sent out.

It's important to note that neither etp_wr_pack nor dl_eth.de_frame are linked lists (i.e., queues). They each hold only a single ethernet packet.


acc_t *etp_rd_pack:

The read queue for the ethernet port. If a read request message was sent to the ethernet driver and an ethernet packet was not already received, this is an empty buffer waiting to be filled by a packet received later.

struct eth_fd *etp_type_any:
struct eth_fd *etp_type[ETH_TYPE_HASH_NR]:


When an ethernet file descriptor is configured, either the NWEO_TYPESPEC flag or the NWEO_TYPEANY flag is set for the ef_flags field of the ethernet file descriptor (
eth_fd). If NWEO_TYPEANY is set, any type of packet is accepted by the file descriptor. If NWEO_TYPESPEC if set, nweo_type is set to one of the following:

#define ETH_RARP_PROTO 0x8035
#define ETH_ARP_PROTO 0x806
#define ETH_IP_PROTO 0x800

After this configuration is done, hash_fd() is called to place the file descriptor in either the etp_type_any linked list (if the NWEO_TYPEANY flag is set) or in one of the linked lists in etp_type[] (there is a single linked list for each of the types shown above). The figure below shows an example of an etp_type[] linked list with three ethernet file descriptors.




event_t etp_sendev:

After sending out an ethernet packet for an ethernet port, the ethernet driver sends a message back to the ethernet port indicating completion. etp_sendev is the event queue that contains the notification event in case the message could not be immediately delivered.


int etp_task:

etp_task is determined by calling sys_findproc() and passing in the name of the task. In the following same configuration:

eth0 DP8390 0 { default; };
psip1;

the task would be "DP8390" for the ethernet device.


int etp_port:

The port number of the ethernet device as determined by the configuration file. For the following inet.conf file for a system with two DP8390 ethernet cards:

eth0 DP8390 0 { default; };
psip1;
eth2 DP8390 1;


the ethernet port associated with eth0 will have an etp_port field equal to 0 and the ethernet port associated with eth2 will have an etp_port field equal to 1.


int etp_recvconf:

etp_recvconf is the "receive configuration" and is set by eth_set_rec_conf(). The receive configuration reflects whether an ethernet port is receiving broadcast and multicast packets and whether the port is in promiscuous mode.


iovec_t etp_wr_iovec[IOVEC_NR]:
iovec_t etp_rd_iovec[RD_IOVEC]:


The buffers that the ethernet code uses to write/read data to/from the ethernet device. For example, on lines 10419-10438 of setup_read(), the message to the ethernet task requesting any data read by the task is set up and sent.




event_t etp_recvev:

etp_recvev is the event queue for the ethernet port.


message etp_sendrepl, message etp_recvrepl:

When a message arrives from the ethernet driver indicating that a packet has been sent or received and the message cannot be immediately processed, the message is placed here. An event (with function eth_recvev() or eth_sendev()) is also added to the event queue. When an event for a received packet is processed, eth_recvev() determines from the DL_COUNT field how many bytes have been received. If the event is for a completed write operation, the fields in the message are not of any significance.