Zero-copy API for the MAC driver.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4984 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
gdisirio 2012-12-28 17:40:45 +00:00
parent 22dcca914b
commit 76d8262f13
5 changed files with 149 additions and 72 deletions

View File

@ -42,11 +42,18 @@
* @name MAC configuration options * @name MAC configuration options
* @{ * @{
*/ */
/**
* @brief Enables an event sources for incoming packets.
*/
#if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__)
#define MAC_USE_ZERO_COPY FALSE
#endif
/** /**
* @brief Enables an event sources for incoming packets. * @brief Enables an event sources for incoming packets.
*/ */
#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__) #if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__)
#define MAC_USE_EVENTS TRUE #define MAC_USE_EVENTS TRUE
#endif #endif
/** @} */ /** @} */
@ -102,6 +109,7 @@ typedef struct MACDriver MACDriver;
#define macGetReceiveEventSource(macp) (&(macp)->rdevent) #define macGetReceiveEventSource(macp) (&(macp)->rdevent)
#endif #endif
#if !MAC_USE_ZERO_COPY || defined(__DOXYGEN__)
/** /**
* @brief Writes to a transmit descriptor's stream. * @brief Writes to a transmit descriptor's stream.
* *
@ -132,8 +140,9 @@ typedef struct MACDriver MACDriver;
*/ */
#define macReadReceiveDescriptor(rdp, buf, size) \ #define macReadReceiveDescriptor(rdp, buf, size) \
mac_lld_read_receive_descriptor(rdp, buf, size) mac_lld_read_receive_descriptor(rdp, buf, size)
#endif /* !MAC_USE_ZERO_COPY */
#if MAC_SUPPORTS_ZERO_COPY || defined(__DOXYGEN__) #if MAC_USE_ZERO_COPY || defined(__DOXYGEN__)
/** /**
* @brief Returns a pointer to the next transmit buffer in the descriptor * @brief Returns a pointer to the next transmit buffer in the descriptor
* chain. * chain.
@ -154,7 +163,7 @@ typedef struct MACDriver MACDriver;
* @api * @api
*/ */
#define macGetNextTransmitBuffer(tdp, size, sizep) \ #define macGetNextTransmitBuffer(tdp, size, sizep) \
mac_lld_get_next_transmit_buffer(tdp, bufp) mac_lld_get_next_transmit_buffer(tdp, size, sizep)
/** /**
* @brief Returns a pointer to the next receive buffer in the descriptor * @brief Returns a pointer to the next receive buffer in the descriptor
@ -172,7 +181,7 @@ typedef struct MACDriver MACDriver;
*/ */
#define magGetNextReceiveBuffer(rdp, sizep) \ #define magGetNextReceiveBuffer(rdp, sizep) \
mac_lld_get_next_receive_buffer(rdp, sizep) mac_lld_get_next_receive_buffer(rdp, sizep)
#endif /* MAC_SUPPORTS_ZERO_COPY */ #endif /* MAC_USE_ZERO_COPY */
/** @} */ /** @} */
/*===========================================================================*/ /*===========================================================================*/

View File

@ -433,38 +433,6 @@ msg_t mac_lld_get_transmit_descriptor(MACDriver *macp,
return RDY_OK; return RDY_OK;
} }
/**
* @brief Writes to a transmit descriptor's stream.
*
* @param[in] tdp pointer to a @p MACTransmitDescriptor structure
* @param[in] buf pointer to the buffer containing the data to be
* written
* @param[in] size number of bytes to be written
* @return The number of bytes written into the descriptor's
* stream, this value can be less than the amount
* specified in the parameter @p size if the maximum
* frame size is reached.
*
* @notapi
*/
size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp,
uint8_t *buf,
size_t size) {
chDbgAssert(!(tdp->physdesc->tdes0 & STM32_TDES0_OWN),
"mac_lld_write_transmit_descriptor(), #1",
"attempt to write descriptor already owned by DMA");
if (size > tdp->size - tdp->offset)
size = tdp->size - tdp->offset;
if (size > 0) {
memcpy((uint8_t *)(tdp->physdesc->tdes2) + tdp->offset, buf, size);
tdp->offset += size;
}
return size;
}
/** /**
* @brief Releases a transmit descriptor and starts the transmission of the * @brief Releases a transmit descriptor and starts the transmission of the
* enqueued data as a single frame. * enqueued data as a single frame.
@ -546,37 +514,6 @@ msg_t mac_lld_get_receive_descriptor(MACDriver *macp,
return RDY_TIMEOUT; return RDY_TIMEOUT;
} }
/**
* @brief Reads from a receive descriptor's stream.
*
* @param[in] rdp pointer to a @p MACReceiveDescriptor structure
* @param[in] buf pointer to the buffer that will receive the read data
* @param[in] size number of bytes to be read
* @return The number of bytes read from the descriptor's
* stream, this value can be less than the amount
* specified in the parameter @p size if there are
* no more bytes to read.
*
* @notapi
*/
size_t mac_lld_read_receive_descriptor(MACReceiveDescriptor *rdp,
uint8_t *buf,
size_t size) {
chDbgAssert(!(rdp->physdesc->rdes0 & STM32_RDES0_OWN),
"mac_lld_read_receive_descriptor(), #1",
"attempt to read descriptor already owned by DMA");
if (size > rdp->size - rdp->offset)
size = rdp->size - rdp->offset;
if (size > 0) {
memcpy(buf, (uint8_t *)(rdp->physdesc->rdes2) + rdp->offset, size);
rdp->offset += size;
}
return size;
}
/** /**
* @brief Releases a receive descriptor. * @brief Releases a receive descriptor.
* @details The descriptor and its buffer are made available for more incoming * @details The descriptor and its buffer are made available for more incoming
@ -675,6 +612,119 @@ bool_t mac_lld_poll_link_status(MACDriver *macp) {
return macp->link_up = TRUE; return macp->link_up = TRUE;
} }
#if MAC_USE_ZERO_COPY || defined(__DOXYGEN__)
/**
* @brief Returns a pointer to the next transmit buffer in the descriptor
* chain.
* @note The API guarantees that enough buffers can be requested to fill
* a whole frame.
*
* @param[in] tdp pointer to a @p MACTransmitDescriptor structure
* @param[in] size size of the requested buffer. Specify the frame size
* on the first call then scale the value down subtracting
* the amount of data already copied into the previous
* buffers.
* @param[out] sizep pointer to variable receiving the real buffer size.
* The returned value can be less than the amount
* requested, this means that more buffers must be
* requested in order to fill the frame data entirely.
* @return Pointer to the returned buffer.
*
* @notapi
*/
uint8_t *mac_lld_get_next_transmit_buffer(MACTransmitDescriptor *tdp,
size_t size,
size_t *sizep) {
(void)tdp; (void)size; (void)sizep;
return NULL;
}
/**
* @brief Returns a pointer to the next receive buffer in the descriptor
* chain.
* @note The API guarantees that the descriptor chain contains a whole
* frame.
*
* @param[in] rdp pointer to a @p MACReceiveDescriptor structure
* @param[out] sizep pointer to variable receiving the buffer size, it is
* zero when the last buffer has already been returned.
* @return Pointer to the returned buffer.
* @retval NULL if the buffer chain has been entirely scanned.
*
* @notapi
*/
const uint8_t *mac_lld_get_next_receive_buffer(MACReceiveDescriptor *rdp,
size_t *sizep) {
(void)rdp; (void)sizep;
return NULL;
}
#endif /* MAC_USE_ZERO_COPY */
#if !MAC_USE_ZERO_COPY || defined(__DOXYGEN__)
/**
* @brief Writes to a transmit descriptor's stream.
*
* @param[in] tdp pointer to a @p MACTransmitDescriptor structure
* @param[in] buf pointer to the buffer containing the data to be
* written
* @param[in] size number of bytes to be written
* @return The number of bytes written into the descriptor's
* stream, this value can be less than the amount
* specified in the parameter @p size if the maximum
* frame size is reached.
*
* @notapi
*/
size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp,
uint8_t *buf,
size_t size) {
chDbgAssert(!(tdp->physdesc->tdes0 & STM32_TDES0_OWN),
"mac_lld_write_transmit_descriptor(), #1",
"attempt to write descriptor already owned by DMA");
if (size > tdp->size - tdp->offset)
size = tdp->size - tdp->offset;
if (size > 0) {
memcpy((uint8_t *)(tdp->physdesc->tdes2) + tdp->offset, buf, size);
tdp->offset += size;
}
return size;
}
/**
* @brief Reads from a receive descriptor's stream.
*
* @param[in] rdp pointer to a @p MACReceiveDescriptor structure
* @param[in] buf pointer to the buffer that will receive the read data
* @param[in] size number of bytes to be read
* @return The number of bytes read from the descriptor's
* stream, this value can be less than the amount
* specified in the parameter @p size if there are
* no more bytes to read.
*
* @notapi
*/
size_t mac_lld_read_receive_descriptor(MACReceiveDescriptor *rdp,
uint8_t *buf,
size_t size) {
chDbgAssert(!(rdp->physdesc->rdes0 & STM32_RDES0_OWN),
"mac_lld_read_receive_descriptor(), #1",
"attempt to read descriptor already owned by DMA");
if (size > rdp->size - rdp->offset)
size = rdp->size - rdp->offset;
if (size > 0) {
memcpy(buf, (uint8_t *)(rdp->physdesc->rdes2) + rdp->offset, size);
rdp->offset += size;
}
return size;
}
#endif /* !MAC_USE_ZERO_COPY */
#endif /* HAL_USE_MAC */ #endif /* HAL_USE_MAC */
/** @} */ /** @} */

View File

@ -35,6 +35,11 @@
/* Driver constants. */ /* Driver constants. */
/*===========================================================================*/ /*===========================================================================*/
/**
* @brief This implementation supports the zero-copy mode API.
*/
#define MAC_SUPPORTS_ZERO_COPY TRUE
/** /**
* @name RDES0 constants * @name RDES0 constants
* @{ * @{
@ -332,17 +337,25 @@ extern "C" {
void mac_lld_stop(MACDriver *macp); void mac_lld_stop(MACDriver *macp);
msg_t mac_lld_get_transmit_descriptor(MACDriver *macp, msg_t mac_lld_get_transmit_descriptor(MACDriver *macp,
MACTransmitDescriptor *tdp); MACTransmitDescriptor *tdp);
size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp,
uint8_t *buf,
size_t size);
void mac_lld_release_transmit_descriptor(MACTransmitDescriptor *tdp); void mac_lld_release_transmit_descriptor(MACTransmitDescriptor *tdp);
msg_t mac_lld_get_receive_descriptor(MACDriver *macp, msg_t mac_lld_get_receive_descriptor(MACDriver *macp,
MACReceiveDescriptor *rdp); MACReceiveDescriptor *rdp);
void mac_lld_release_receive_descriptor(MACReceiveDescriptor *rdp);
bool_t mac_lld_poll_link_status(MACDriver *macp);
#if MAC_USE_ZERO_COPY
uint8_t *mac_lld_get_next_transmit_buffer(MACTransmitDescriptor *tdp,
size_t size,
size_t *sizep);
const uint8_t *mac_lld_get_next_receive_buffer(MACReceiveDescriptor *rdp,
size_t *sizep);
#else /* !MAC_USE_ZERO_COPY */
size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp,
uint8_t *buf,
size_t size);
size_t mac_lld_read_receive_descriptor(MACReceiveDescriptor *rdp, size_t mac_lld_read_receive_descriptor(MACReceiveDescriptor *rdp,
uint8_t *buf, uint8_t *buf,
size_t size); size_t size);
void mac_lld_release_receive_descriptor(MACReceiveDescriptor *rdp); #endif /* !MAC_USE_ZERO_COPY */
bool_t mac_lld_poll_link_status(MACDriver *macp);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -35,6 +35,10 @@
/* Driver local definitions. */ /* Driver local definitions. */
/*===========================================================================*/ /*===========================================================================*/
#if MAC_USE_ZERO_COPY && !MAC_SUPPORTS_ZERO_COPY
#error "MAC_USE_ZERO_COPY not supported by this implementation"
#endif
/*===========================================================================*/ /*===========================================================================*/
/* Driver exported variables. */ /* Driver exported variables. */
/*===========================================================================*/ /*===========================================================================*/

View File

@ -90,6 +90,7 @@
(backported to 2.4.3). (backported to 2.4.3).
- FIX: Fixed wrong SPI path in platform_f105_f107.mk (bug 3598151). - FIX: Fixed wrong SPI path in platform_f105_f107.mk (bug 3598151).
- FIX: Fixed PHY powerdown issues not fixed (bug 3596911). - FIX: Fixed PHY powerdown issues not fixed (bug 3596911).
- NEW: Added an optional zero-copy mode API to the MAC driver model.
- NEW: Added EXT driver to the STM32F3xx platform. - NEW: Added EXT driver to the STM32F3xx platform.
- NEW: Improved the STM32 EXT driver to support more than 32 channels. - NEW: Improved the STM32 EXT driver to support more than 32 channels.
- NEW: Added support for Olimex board STM32-LCD. - NEW: Added support for Olimex board STM32-LCD.