[Previous] [Contents] [Index] [Next]

io_net_self_t

Functions in io-net that your driver can call

Synopsis:

typedef struct _io_net_self {
    u_int   nfuncs;
    void    *(*alloc) (...);
    npkt_t  *(*alloc_down_npkt) (...);
    npkt_t  *(*alloc_up_npkt) (...);
    int     (*free) (...);
    paddr_t (*mphys) (...);
    int     (*reg) (...);
    int     (*dereg) (...);
    int     (*tx_up) (...);
    int     (*tx_down) (...);
    int     (*tx_done) (...);
    int     (*reg_tx_done) (...);
    int     (*reg_byte_pat) (...);
    int     (*dereg_byte_pat) (...);
    int     (*devctl) (...);
    int     (*tx_up_start) (...);
    int     (*memcpy_from_npkt) (...);
    int     (*raw_devctl) (...);
} io_net_self_t;

Description:

The io_net_self_t pointer points to a structure that contains io-net's functions that are accessible to your driver. You should cache this pointer (passed to you in your init() function) so that you have access to those functions later.

The nfuncs member indicates how many functions are provided in the table; it's filled automatically by io-net. The functions are described below.

alloc()

The prototype is:

void *(*alloc) (size_t size,
                int flags)

This function allocates a buffer of the given size that's safe to pass to any other module.

There are currently no flags defined.

This function returns a pointer to the allocated buffer, or NULL if an error occurred.

alloc_down_npkt()

The prototype is:

npkt_t *(*alloc_down_npkt) (
              int registrant_hdl,
              size_t size,
              void **data)

This function allocates an npkt_t structure and initializes its internal members to values required for downward travel. The required tx_done array elements (slots) are allocated immediately implicitly following the npkt_t structure, in order to successfully reach any endpoint registrant this driver is currently connected to.

The arguments are:

registrant_hdl
The registrant handle that was filled in when your driver registered by calling io-net's reg() function.
size
The amount of space, in bytes, to allocate in addition to the packet and its tx_done array elements.
data
If successful, this is set to point to the extra space allocated.

This function returns a pointer to the allocated buffer, or NULL if an error occurred.

alloc_up_npkt()

The prototype is:

npkt_t *(*alloc_up_npkt) (size_t size,
                          void **data)

This function allocates an npkt_t and initializes its internal members to values required for upward travel, as follows:

num_complete
The value 1 to indicate that it has room for one tx_done (i.e. the originator's) array element immediately implicitly following the structure.
req_complete
The value 0 to indicate the single slot hasn't been used yet.
ref_cnt
The value 1 as the reference count (in use by only one module at this point).
flags
The bits _NPKT_UP and _NPKT_NOT_TXED are on, indicating it's an upward-bound packet and that packet wasn't actually transmitted.
buffers
Initialized to an empty TAILQ queue structure.

On successful completion, data points to a buffer of size bytes in length.

This function returns a pointer to the allocated buffer, or NULL if an error occurred.

free()

The prototype is:

int (*free) (void *ptr)

This function frees a buffer, pointed to by ptr, that was allocated by any of the above methods (alloc(), alloc_down_npkt(), and alloc_up_npkt()).

This function returns:

0
Success.
-1
An error occurred; errno is set.

mphys()

The prototype is:

paddr_t (*mphys) (void *ptr)

This function does a quick lookup of the physical address of the buffer, pointed to by ptr, that was allocated by any of the above methods (alloc(), alloc_down_npkt(), and alloc_up_npkt()).

This function returns the physical address of the buffer on success, or -1 if an error occurred (errno is set).

reg()

This call binds your driver to io-net. The prototype is:

int (*reg) (void *dll_hdl,
            io_net_registrant_t *registrant,
            int *reg_hdlp,
            uint16_t *cell,
            uint16_t *endpoint)

The arguments are:

dll_hdl
The handle that io-net passed to your driver's init() function (from the io_net_dll_entry_t data type that you provided).
registrant
A pointer to an io_net_registrant_t structure that describes what your driver is registering as.
reg_hdlp
On success, this is filled in, and should be used as the registrant_hdl parameter to subsequent calls into io_net.
cell and endpoint
These are also filled in, and indicate the registrant's place to other registrants (see tx_up(), below).

This function returns:

0
Success.
-1
An error occurred; errno is set.

dereg()

The prototype is:

int (*dereg) (int registrant_hdl)

Deregister from io-net. Note that if a shared object has registered multiple times, its main shared object shutdown function (defined in the io_net_dll_entry_t structure) isn't called until after all registrants have deregistered.

The registrant_hdl argument is the registrant handle that was filled in when your driver registered by calling io-net's reg() function.

This function returns EOK on success, or an error code.

tx_up()

The prototype is:

int (*tx_up) (int registrant_hdl,
              npkt_t *npkt,
              int off,
              int framlen_sub,
              uint16_t cell,
              uint16_t endpoint,
              uint16_t iface)

This function sends a packet to the layer above you. The arguments are:

registrant_hdl
The registrant handle that was filled in when your driver registered by calling io-net's reg() function.
npkt
A pointer to the packet to be sent to the layer above.
off
Indicates to the layer above at which offset into the packet the type your layer presents starts.
framelen_sub
How many bytes on the end of the packet aren't your type. The off and framelen_sub arguments let a packet be "decapsulated" without the need to perform a copy operation.
cell, endpoint, and iface
Indicate to the layers above who this packet came from. The cell and endpoint are supplied by io-net when you registered above.

The iface is for internal use and lets a single registrant present multiple interfaces of the same type to upper modules. It should start at 0 and increase sequentially. In the case of a driver talking to hardware (a simple up producer with no modules below it), it's actually more flexible to register multiple times if multiple interfaces are present (once for each interface). In this case, the iface parameter is always 0.

On success, tx_up() returns the number of modules above the calling module that took the packet (which could be 0). If an error occurred, tx_up() returns -1, and errno is set.

tx_down()

The prototype is:

int (*tx_down) (int registrant_hdl,
                npkt_t *npkt)

This function sends a packet, pointed to by npkt, down to the layer below you. The registrant_hdl argument is the registrant handle that was filled in when your driver registered by calling io-net's reg() function. The destination that you're trying to reach is stored in the cell, endpoint, and iface members of npkt.

This function returns:

TX_DOWN_OK
Success.
TX_DOWN_FAILED
An error occurred; errno is set.
TX_DOWN_AGAIN
A lower layer wants you to try again.

tx_done()

The prototype is:

int (*tx_done) (int registrant_hdl,
                 npkt_t *npkt)

For downward-headed packets, this function is called once by the module that consumes the packet. This causes the chain of tx_done() functions stored in npkt to be called in LIFO order (see the reg_tx_done() function, below).

The registrant_hdl argument is the registrant handle that was filled in when your driver registered by calling io-net's reg() function.

For upward-headed packets, this function is called by each module (including the originator) when finished with the packet. The single tx_done() stored in the packet is called when the ref_cnt member goes to zero.

This function returns:

0
Success.
-1
An error occurred; errno is set.

reg_tx_done()

The prototype is:

int (*reg_tx_done) (int registrant_hdl, 
                    npkt_t *npkt,
                    void *done_hdl)

This function is used to store a tx_done() callback in a packet. It's called once by the originator for upward-headed packets, and called by every module that adds to the npkt buffer chain for downward-headed packets. You must call this function rather than stuffing the value directly because io-net keeps track of how many tx_done() functions a module has outstanding (used for unmounting the module).

The arguments are:

registrant_hdl
The registrant handle that was filled in when your driver registered by calling io-net's reg() function.
npkt
A pointer to the packet.
done_hdl
A pointer to data to be passed to a module's tx_done() function. See the description of io_net_registrant_funcs_t.

This function returns:

0
Success.
-1
An error occurred; errno is set.

reg_byte_pat()

The prototype is:

int (*reg_byte_pat) (int registrant_hdl,
                     unsigned off,
                     unsigned len,
                     unsigned char *pat,
                     unsigned flags)

Before a module will receive any upward-headed packets, it must register with io-net to indicate what subtype it wants. This is in place to allow packet filtering, so that the module isn't getting packets that it won't be dealing with. The module already specified its bottom type when it registered (e.g. en to specify Ethernet subtypes 0x0800 and 0x0806 (for ARP), or the IP protocol type PROT_QNET for qnet).

The arguments are:

registrant_hdl
The registrant handle that was filled in when your driver registered by calling io-net's reg() function.
off
The offset into the packet at which to look for the pattern.
len
The length of the byte pattern.
pat
A pointer to the byte pattern.
flags
Set this argument to _BYTE_PAT_ALL if your driver wants to get all subtypes. If this bit is set, the off, len, and pat arguments are ignored.

Note: Your module must register for some kind of byte pattern, or it won't get any up-headed packets.

This function returns:

0
Success.
-1
An error occurred; errno is set.

dereg_byte_pat()

The prototype is:

int (*dereg_byte_pat) (int registrant_hdl,
                       unsigned off,
                       unsigned len,
                       unsigned char *pat,
                       unsigned flags)

This function deregisters a byte pattern from io-net.

The arguments are:

registrant_hdl
The registrant handle that was filled in when your driver registered by calling io-net's reg() function.
off
The offset into the packet at which to look for the pattern.
len
The length of the byte pattern.
pat
A pointer to the byte pattern.
flags
Set this argument to _BYTE_PAT_ALL if your driver wants to deregister for all subtypes. If this bit is set, the off, len, and pat arguments are ignored.

This function returns:

0
Success.
-1
An error occurred; errno is set.

devctl()

The prototype is:

int (*devctl) (int registrant_hdl,
               int dcmd,
               void *data,
               size_t size,
               int *ret)

Send a devctl() command to io-net.

The arguments are:

registrant_hdl
The registrant handle that was filled in when your driver registered by calling io-net's reg() function.
dcmd
The command being sent to your driver.
data
A pointer to data to be passed to the driver, filled in by the driver, or both, depending on the command.
size
The maximum amount of data to be sent to the driver or filled in by the driver. If size is 0, an unspecified amount of data is transferred.
ret
A pointer to additional device data to be returned.

This function returns EOK on success, or an error code.

tx_up_start()

The prototype is:

npkt_t *(*tx_up_start) (int registrant_hdl,
                        nptk_t *npkt,
                        int off,
                        int framelen_sub,
                        uint16_t cell,
                        uint16_t endpoint,
                        uint16_t iface,
                        void *done_hdl)

A utility function for use by originators of up-headed packets.

This function efficiently combines io-net's reg_tx_done(), tx_up() and tx_done() functions (three common operations for originators of up-packets) as follows:

reg_tx_done (reg_hdl, npkt, done_hdl);
tx_up       (reg_hdl, npkt, off, framelen_sub, cell, 
             endpoint, iface);
tx_done     (reg_hdl, nptk);

The arguments are:

registrant_hdl
The registrant handle that was filled in when your driver registered by calling io-net's reg() function.
npkt
Unlike the rest of the functions provided by io-net, this argument can be a linked list of packets rather than a single entity. The processing described above is done for all npkts in the linked list.
off
Indicates to the layer above at which offset into the packet the type your layer presents starts.
framelen_sub
How many bytes on the end of the packet should be ignored by modules at higher levels. The off and framelen_sub arguments let a packet be "decapsulated" without the need to perform a copy operation.
cell, endpoint, and iface
Indicate to the layers above who this packet came from. The cell and endpoint are supplied by io-net when you registered above.

The iface argument is for internal use and lets a single registrant present multiple interfaces of the same type to upper modules. It should start at 0 and increase sequentially. In the case of a driver talking to hardware (a simple up producer with no modules below it), it's actually more flexible to register multiple times if multiple interfaces are present (once for each interface). In this case, the iface parameter is always 0.

done_hdl
A pointer to data to be passed to a module's tx_done() function. See the description of io_net_registrant_funcs_t.

This function returns a linked list of npkt structures for which a tx_done() callback couldn't be registered (i.e. for which reg_tx_done() failed. If this is non-NULL, errno is set.

memcpy_from_npkt()

The prototype is:

int (*memcpy_from_npkt) (const iov_t *dst,
                         int dparts,
                         int doff,
                         const npkt_t *snpkt,
                         int soff,
                         int smax_len)

This utility function is generally useful for copying data from packets. It's similar to memcpyv(). The arguments are:

dst
A pointer to the destination of the copy operation.
dparts
The number of iov parts in the destination.
doff
The offset in the destination at which to copy the data.
snpkt
A pointer to the packet that's the source of the data.
soff
The offset into the packet from which to start copying the data.
smax_len
The maximum length of data to copy.

The return value is the number of bytes copied.

raw_devctl()

This function is used when writing a _REG_FILTER_ABOVE module that sits above, say, all Ethernet registrants, and is passed all open() calls so it can then handle all read()s, write()s, etc., to that device. The only I/O message that io-net is concerned about is the message corresponding to the devctl() function call, so if the filter gets a devctl() that it can't handle, it calls this function. The prototype is:

int (*raw_devctl) (resmgr_context_t *ctp,
                   io_devctl_t *m,
                   io_net_iofunc_attr_t *attr)

This function returns EOK on success, or an error code on failure.

Classification:

QNX

See also:

io_net_dll_entry_t, npkt_t


[Previous] [Contents] [Index] [Next]