MC_TX(9E)                    Driver Entry Points                   MC_TX(9E)
NAME
     mc_tx, 
mri_tx - transmit a message block chain
SYNOPSIS
     #include <sys/mac_provider.h>     mblk_t *     prefix_m_tx(
void *driver, 
mblk_t *mp_chain);     
mblk_t *     prefix_ring_tx(
void *driver_rh, 
mblk_t *mp_chain);
INTERFACE LEVEL
     illumos DDI specific
     The 
mri_tx() entry point is 
Uncommitted - API and ABI stability is not
     guaranteed.
PARAMETERS
     driver        A pointer to the driver's private data that was passed in
                   via the 
m_pdata member of the 
mac_register(9S) structure
                   to the 
mac_register(9F) function.     
driver_rh     A pointer to the driver's private data for the ring that
                   was passed in via the 
mri_driver member of the                   
mac_ring_info(9S) structure.  This is initialized by the
                   driver when its 
mr_rget(9E) is called by MAC.     
mp_chain      A series of 
mblk(9S) structures that may have multiple
                   independent packets linked together on their 
b_next                   member.
DESCRIPTION
     The 
mc_tx() entry point is called when the system requires a device
     driver to transmit data.  The device driver will receive a chain of
     message blocks.  The 
mp_chain argument represents the first frame.  The
     frame may be spread out across one or more 
mblk(9S) structures that are
     linked together by the 
b_cont member.  There may be multiple frames,
     linked together by the 
b_next pointer of the 
mblk(9S).
     For each frame, the driver should allocate the required resources and
     prepare it for being transmitted on the wire.  The driver may opt to
     copy those resources to a DMA buffer or it may bind them.  For more
     information on these options, see the 
MBLKS AND DMA section of 
mac(9E).
     As it processes each frame in the chain, if the device driver has
     advertised either of the MAC_CAPAB_HCKSUM or MAC_CAPAB_LSO flags, it
     must check whether either apply for the given frame using the     
mac_hcksum_get(9F) and 
mac_lso_get(9F) functions respectively.  If
     either is enabled for the given frame, the hardware must arrange for
     that to be taken care of.
     For each frame that the device driver processes it is responsible for
     doing one of three things with it:
     1.   Transmit the frame.
     2.   Drop the frame by calling 
freemsg(9F) on the individual mblk_t.
     3.   Return the frames to indicate that resources are not available.
     The device driver is in charge of the memory associated with 
mp_chain.
     If the device driver does not return the message blocks to the MAC
     framework, then it must call 
freemsg(9F) on the frames.  If it does
     not, the memory associated with them will be leaked.  When a frame is
     being transmitted, if the device driver performed DMA binding, it
     should not free the message block until after it is guaranteed that the
     frame has been transmitted.  If the message block was copied to a DMA
     buffer, then it is allowed to call 
freemsg(9F) at any point.
     In general, the device driver should not drop frames without
     transmitting them unless it has no other choice.  Times when this
     happens may include the device driver being in a state where it can't
     transmit, an error was found in the frame while trying to establish the
     checksum or LSO state, or some other kind of error that represents an
     issue with the passed frame.
     The device driver should not free the chain when it does not have
     enough resources.  For example, if entries in a device's descriptor
     ring fill up, then it should not drop those frames and instead should
     return all of the frames that were not transmitted.  This indicates to
     the stack that the device is full and that flow control should be
     asserted.  Back pressure will be applied to the rest of the stack,
     allowing most systems to behave better.
     Once a device driver has returned unprocessed frames from its 
mc_tx()
     entry point, then the device driver will not receive any additional
     calls to its 
mc_tx() entry point until it calls the 
mac_tx_update(9F)     function to indicate that resources are available again.  Note that
     because it is the device driver that is calling this function to
     indicate resources are available, it is very important that it only
     return frames in cases where the device driver itself will be notified
     that resources are available again.  For example, when it receives an
     interrupt indicating that the data that it transmitted has been
     completed so it can use entries in its descriptor ring or other data
     structures again.
     The device driver can obtain access to its soft state through the     
driver member.  It should cast it to the appropriate structure.  The
     device driver should employ any necessary locking to access the
     transmit related data structures.  Note that the device driver should
     expect that it may have its transmit endpoints called into from other
     threads while it's servicing device interrupts related to them.
     The 
mri_tx() entry point is similar to the 
mc_tx() entry point, except
     that it is used by device drivers that have negotiated the
     MAC_CAPAB_RINGS capability with transmit rings.  The driver should
     follow all of the same rules described earlier, except that it will
     access a ring-specific data structure through 
driver_rh and when it
     needs to update that there is additional space available, it must use     
mac_tx_ring_update(9F) and not 
mac_tx_update(9F).
     When the 
mri_tx() entry point is called, the ring that should be used
     has been specified.  The driver must not attempt to use any other ring
     than the one specified by 
driver_rh for any reason, including a lack of
     resources or an attempt to perform its own hashing.
CONTEXT
     The 
mc_tx() entry point may be called from 
kernel or 
interrupt context.
RETURN VALUES
     Upon successful completion, the device driver should return NULL.
     Otherwise, it should return all unprocessed message blocks and ensure
     that it calls either 
mac_tx_update(9F) or 
mac_tx_ring_update(9F) some
     time in the future.
SEE ALSO
     mac(9E), 
mac_capab_rings(9E), 
mr_rget(9E), 
freemsg(9F),     
mac_hcksum_get(9F), 
mac_lso_get(9F), 
mac_register(9F),     
mac_tx_ring_update(9F), 
mac_tx_update(9F), 
mac_register(9S),     
mac_ring_info(9S), 
mblk(9S)illumos                       December 11, 2022                      illumos