aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2012-12-28 17:40:45 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2012-12-28 17:40:45 +0000
commit76d8262f134d41c05adda7edb27d9868ca847941 (patch)
tree799f56b1b9fe756a4c41fdd750e5caf7c2401817
parent22dcca914b67892038958a03b527ca9df25ac916 (diff)
downloadChibiOS-76d8262f134d41c05adda7edb27d9868ca847941.tar.gz
ChibiOS-76d8262f134d41c05adda7edb27d9868ca847941.tar.bz2
ChibiOS-76d8262f134d41c05adda7edb27d9868ca847941.zip
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
-rw-r--r--os/hal/include/mac.h17
-rw-r--r--os/hal/platforms/STM32/mac_lld.c176
-rw-r--r--os/hal/platforms/STM32/mac_lld.h23
-rw-r--r--os/hal/src/mac.c4
-rw-r--r--readme.txt1
5 files changed, 149 insertions, 72 deletions
diff --git a/os/hal/include/mac.h b/os/hal/include/mac.h
index 2903bd07c..763bc373e 100644
--- a/os/hal/include/mac.h
+++ b/os/hal/include/mac.h
@@ -45,8 +45,15 @@
/**
* @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.
+ */
#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__)
-#define MAC_USE_EVENTS TRUE
+#define MAC_USE_EVENTS TRUE
#endif
/** @} */
@@ -102,6 +109,7 @@ typedef struct MACDriver MACDriver;
#define macGetReceiveEventSource(macp) (&(macp)->rdevent)
#endif
+#if !MAC_USE_ZERO_COPY || defined(__DOXYGEN__)
/**
* @brief Writes to a transmit descriptor's stream.
*
@@ -132,8 +140,9 @@ typedef struct MACDriver MACDriver;
*/
#define macReadReceiveDescriptor(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
* chain.
@@ -154,7 +163,7 @@ typedef struct MACDriver MACDriver;
* @api
*/
#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
@@ -172,7 +181,7 @@ typedef struct MACDriver MACDriver;
*/
#define magGetNextReceiveBuffer(rdp, sizep) \
mac_lld_get_next_receive_buffer(rdp, sizep)
-#endif /* MAC_SUPPORTS_ZERO_COPY */
+#endif /* MAC_USE_ZERO_COPY */
/** @} */
/*===========================================================================*/
diff --git a/os/hal/platforms/STM32/mac_lld.c b/os/hal/platforms/STM32/mac_lld.c
index 3721670f9..25a5155ee 100644
--- a/os/hal/platforms/STM32/mac_lld.c
+++ b/os/hal/platforms/STM32/mac_lld.c
@@ -434,38 +434,6 @@ msg_t mac_lld_get_transmit_descriptor(MACDriver *macp,
}
/**
- * @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
* enqueued data as a single frame.
*
@@ -547,37 +515,6 @@ msg_t mac_lld_get_receive_descriptor(MACDriver *macp,
}
/**
- * @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.
* @details The descriptor and its buffer are made available for more incoming
* frames.
@@ -675,6 +612,119 @@ bool_t mac_lld_poll_link_status(MACDriver *macp) {
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 */
/** @} */
diff --git a/os/hal/platforms/STM32/mac_lld.h b/os/hal/platforms/STM32/mac_lld.h
index 76241cd52..59c39ac17 100644
--- a/os/hal/platforms/STM32/mac_lld.h
+++ b/os/hal/platforms/STM32/mac_lld.h
@@ -36,6 +36,11 @@
/*===========================================================================*/
/**
+ * @brief This implementation supports the zero-copy mode API.
+ */
+#define MAC_SUPPORTS_ZERO_COPY TRUE
+
+/**
* @name RDES0 constants
* @{
*/
@@ -332,17 +337,25 @@ extern "C" {
void mac_lld_stop(MACDriver *macp);
msg_t mac_lld_get_transmit_descriptor(MACDriver *macp,
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);
msg_t mac_lld_get_receive_descriptor(MACDriver *macp,
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,
uint8_t *buf,
size_t size);
- void mac_lld_release_receive_descriptor(MACReceiveDescriptor *rdp);
- bool_t mac_lld_poll_link_status(MACDriver *macp);
+#endif /* !MAC_USE_ZERO_COPY */
#ifdef __cplusplus
}
#endif
diff --git a/os/hal/src/mac.c b/os/hal/src/mac.c
index e052e0945..130c81caf 100644
--- a/os/hal/src/mac.c
+++ b/os/hal/src/mac.c
@@ -35,6 +35,10 @@
/* 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. */
/*===========================================================================*/
diff --git a/readme.txt b/readme.txt
index e369346ff..259825234 100644
--- a/readme.txt
+++ b/readme.txt
@@ -90,6 +90,7 @@
(backported to 2.4.3).
- FIX: Fixed wrong SPI path in platform_f105_f107.mk (bug 3598151).
- 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: Improved the STM32 EXT driver to support more than 32 channels.
- NEW: Added support for Olimex board STM32-LCD.