Comtrol eCos User Manual
Page 602

Chapter 46. Generic Ethernet Device Driver
struct arpcom
sc_arpcom; /* ethernet common */
};
Note: If you have two instances of the same hardware, you only need one struct eth_hwr_funs shared between
them.
There is another structure which is used to communicate with the rest of the stack:
struct eth_drv_funs {
// Logical driver - initialization
void (*init)(struct eth_drv_sc *sc,
unsigned char *enaddr);
// Logical driver - incoming packet notifier
void (*recv)(struct eth_drv_sc *sc,
int total_len);
// Logical driver - outgoing packet notifier
void (*tx_done)(struct eth_drv_sc *sc,
CYG_ADDRESS key,
int status);
};
Your driver does not create an instance of this structure. It is provided for driver code to use in the eth_drv member
of the function record. Its usage is described below in
the Section called Upper Layer Functions
One more function completes the API with which your driver communicates with the rest of the stack:
extern void eth_drv_dsr(cyg_vector_t vector,
cyg_ucount32 count,
cyg_addrword_t data);
This function is designed so that it can be registered as the DSR for your interrupt handler. It will awaken the
“Network Delivery Thread” to call your deliver routine. See
the Section called Deliver function
You create an instance of struct eth_drv_sc using the
ETH_DRV_SC()
macro which sets up the structure, including
the prototypes for the functions, etc. By doing things this way, if the internal design of the ethernet drivers changes
(e.g. we need to add a new low-level implementation function), existing drivers will no longer compile until up-
dated. This is much better than to have all of the definitions in the low-level drivers themselves and have them be
(quietly) broken if the interfaces change.
The “magic” which gets the drivers started (and indeed, linked) is similar to what is used for the I/O subsystem.
This is done using the
NETDEVTAB_ENTRY()
macro, which defines an initialization function and the basic data
structures for the low-level driver.
typedef struct cyg_netdevtab_entry {
const char
*name;
bool
(*init)(struct cyg_netdevtab_entry *tab);
void
*device_instance;
unsigned long
status;
} cyg_netdevtab_entry_t;
498