git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1193 35acf78f-673a-0410-8e92-d51de3d6d3f4

master
gdisirio 2009-09-29 19:29:59 +00:00
parent c9bfcaa15e
commit ea9916ae79
8 changed files with 375 additions and 262 deletions

View File

@ -5,7 +5,7 @@
# Compiler options here. # Compiler options here.
ifeq ($(USE_OPT),) ifeq ($(USE_OPT),)
USE_OPT = -O2 -ggdb -fomit-frame-pointer -mabi=apcs-gnu USE_OPT = -O0 -ggdb -fomit-frame-pointer -mabi=apcs-gnu
endif endif
# C++ specific options here (added to USE_OPT). # C++ specific options here (added to USE_OPT).

View File

@ -47,21 +47,18 @@ static const struct uip_eth_addr macaddr = {
*/ */
static void network_device_send(void) { static void network_device_send(void) {
int i; int i;
MACTransmitDescriptor *tdp; MACTransmitDescriptor td;
for (i = 0; i < SEND_RETRY_MAX; i++) { for (i = 0; i < SEND_RETRY_MAX; i++) {
if ((tdp = macWaitTransmitDescriptor(&MAC1, uip_len, TIME_IMMEDIATE)) != NULL) { if (macWaitTransmitDescriptor(&ETH1, &td, TIME_IMMEDIATE) == RDY_OK) {
uint8_t *bp = macGetTransmitBuffer(tdp);
if(uip_len <= UIP_LLH_LEN + UIP_TCPIP_HLEN) if(uip_len <= UIP_LLH_LEN + UIP_TCPIP_HLEN)
memcpy(bp, &uip_buf[0], uip_len); macWriteTransmitDescriptor(&td, uip_buf, uip_len);
else { else {
memcpy(bp, &uip_buf[0], UIP_LLH_LEN + UIP_TCPIP_HLEN); macWriteTransmitDescriptor(&td, uip_buf, UIP_LLH_LEN + UIP_TCPIP_HLEN);
memcpy(bp + UIP_LLH_LEN + UIP_TCPIP_HLEN, macWriteTransmitDescriptor(&td, uip_appdata,
uip_appdata, uip_len - (UIP_LLH_LEN + UIP_TCPIP_HLEN));
uip_len - (UIP_LLH_LEN + UIP_TCPIP_HLEN));
} }
macReleaseTransmitDescriptor(&MAC1, tdp); macReleaseTransmitDescriptor(&td);
return; return;
} }
chThdSleep(SEND_RETRY_INTERVAL); chThdSleep(SEND_RETRY_INTERVAL);
@ -73,15 +70,14 @@ static void network_device_send(void) {
* uIP receive function wrapping the EMAC function. * uIP receive function wrapping the EMAC function.
*/ */
static size_t network_device_read(void) { static size_t network_device_read(void) {
MACReceiveDescriptor *rdp; MACReceiveDescriptor rd;
size_t size; size_t size;
uint8_t *bp;
if ((rdp = macWaitReceiveDescriptor(&MAC1, &size, TIME_IMMEDIATE)) == NULL) if (macWaitReceiveDescriptor(&ETH1, &rd, TIME_IMMEDIATE) != RDY_OK)
return 0; return 0;
bp = macGetReceiveBuffer(rdp); size = rd.rd_size;
memcpy(&uip_buf[0], bp, size); macReadReceiveDescriptor(&rd, uip_buf, size);
macReleaseReceiveDescriptor(&MAC1, rdp); macReleaseReceiveDescriptor(&rd);
return size; return size;
} }
@ -113,7 +109,7 @@ static void PeriodicTimerHandler(eventid_t id) {
static void ARPTimerHandler(eventid_t id) { static void ARPTimerHandler(eventid_t id) {
uip_arp_timer(); uip_arp_timer();
(void)macPollLinkStatus(&MAC1); (void)macPollLinkStatus(&ETH1);
} }
/* /*
@ -156,7 +152,7 @@ msg_t WebThread(void *p) {
/* /*
* Event sources setup. * Event sources setup.
*/ */
chEvtRegister(macGetReceiveEventSource(&MAC1), &el0, FRAME_RECEIVED_ID); chEvtRegister(macGetReceiveEventSource(&ETH1), &el0, FRAME_RECEIVED_ID);
chEvtPend(EVENT_MASK(FRAME_RECEIVED_ID)); /* In case some frames are already buffered */ chEvtPend(EVENT_MASK(FRAME_RECEIVED_ID)); /* In case some frames are already buffered */
evtInit(&evt1, MS2ST(500)); evtInit(&evt1, MS2ST(500));
@ -170,8 +166,8 @@ msg_t WebThread(void *p) {
/* /*
* EMAC settings. * EMAC settings.
*/ */
macSetAddress(&MAC1, &macaddr.addr[0]); macSetAddress(&ETH1, &macaddr.addr[0]);
(void)macPollLinkStatus(&MAC1); (void)macPollLinkStatus(&ETH1);
/* /*
* uIP initialization. * uIP initialization.

View File

@ -77,33 +77,32 @@ void macSetAddress(MACDriver *macp, const uint8_t *p) {
* invoking thread is queued until one is freed. * invoking thread is queued until one is freed.
* *
* @param[in] macp pointer to the @p MACDriver object * @param[in] macp pointer to the @p MACDriver object
* @param[in] size size of the frame to be transmitted * @param[out] tdp pointer to a @p MACTransmitDescriptor structure
* @param[in] time the number of ticks before the operation timeouts, * @param[in] time the number of ticks before the operation timeouts,
* the following special values are allowed: * the following special values are allowed:
* - @a TIME_IMMEDIATE immediate timeout. * - @a TIME_IMMEDIATE immediate timeout.
* - @a TIME_INFINITE no timeout. * - @a TIME_INFINITE no timeout.
* . * .
* @return A pointer to a @p MACTransmitDescriptor structure or @p NULL if * @return The operation status.
* the operation timed out. * @retval RDY_OK the descriptor was obtained.
* @retval RDY_TIMEOUT the operation timed out, descriptor not initialized.
*/ */
MACTransmitDescriptor *macWaitTransmitDescriptor(MACDriver *macp, msg_t macWaitTransmitDescriptor(MACDriver *macp,
size_t size, MACTransmitDescriptor *tdp,
systime_t time) { systime_t time) {
MACTransmitDescriptor *tdp; msg_t msg;
while (((tdp = max_lld_get_transmit_descriptor(macp, size)) == NULL) && while (((msg = max_lld_get_transmit_descriptor(macp, tdp)) != RDY_OK) &&
(time > 0)) { (time > 0)) {
chSysLock(); chSysLock();
systime_t now = chTimeNow(); systime_t now = chTimeNow();
if (chSemWaitTimeoutS(&tdsem, time) == RDY_TIMEOUT) { if ((msg = chSemWaitTimeoutS(&tdsem, time)) == RDY_TIMEOUT)
tdp = NULL;
break; break;
}
if (time != TIME_INFINITE) if (time != TIME_INFINITE)
time -= (chTimeNow() - now); time -= (chTimeNow() - now);
chSysUnlock(); chSysUnlock();
} }
return tdp; return msg;
} }
/** /**
@ -113,10 +112,9 @@ MACTransmitDescriptor *macWaitTransmitDescriptor(MACDriver *macp,
* @param[in] macp pointer to the @p MACDriver object * @param[in] macp pointer to the @p MACDriver object
* @param[in] tdp the pointer to the @p MACTransmitDescriptor structure * @param[in] tdp the pointer to the @p MACTransmitDescriptor structure
*/ */
void macReleaseTransmitDescriptor(MACDriver *macp, void macReleaseTransmitDescriptor(MACTransmitDescriptor *tdp) {
MACTransmitDescriptor *tdp) {
mac_lld_release_transmit_descriptor(macp, tdp); mac_lld_release_transmit_descriptor(tdp);
} }
/** /**
@ -126,47 +124,45 @@ void macReleaseTransmitDescriptor(MACDriver *macp,
* until one is received. * until one is received.
* *
* @param[in] macp pointer to the @p MACDriver object * @param[in] macp pointer to the @p MACDriver object
* @param[out szp size of the received frame * @param[out] rdp pointer to a @p MACReceiveDescriptor structure
* @param[in] time the number of ticks before the operation timeouts, * @param[in] time the number of ticks before the operation timeouts,
* the following special values are allowed: * the following special values are allowed:
* - @a TIME_IMMEDIATE immediate timeout. * - @a TIME_IMMEDIATE immediate timeout.
* - @a TIME_INFINITE no timeout. * - @a TIME_INFINITE no timeout.
* . * .
* @return A pointer to a @p MACReceiveDescriptor structure or @p NULL if * @return The operation status.
* the operation timed out or some transient error happened. * @retval RDY_OK the descriptor was obtained.
* @retval RDY_TIMEOUT the operation timed out, descriptor not initialized.
*/ */
MACReceiveDescriptor *macWaitReceiveDescriptor(MACDriver *macp, msg_t macWaitReceiveDescriptor(MACDriver *macp,
size_t *szp, MACReceiveDescriptor *rdp,
systime_t time) { systime_t time) {
MACReceiveDescriptor *rdp; msg_t msg;
while (((rdp = max_lld_get_receive_descriptor(macp, szp)) == NULL) && while (((msg = max_lld_get_receive_descriptor(macp, rdp)) != RDY_OK) &&
(time > 0)) { (time > 0)) {
chSysLock(); chSysLock();
systime_t now = chTimeNow(); systime_t now = chTimeNow();
if (chSemWaitTimeoutS(&rdsem, time) == RDY_TIMEOUT) { if ((msg = chSemWaitTimeoutS(&rdsem, time)) == RDY_TIMEOUT)
rdp = NULL;
break; break;
}
if (time != TIME_INFINITE) if (time != TIME_INFINITE)
time -= (chTimeNow() - now); time -= (chTimeNow() - now);
chSysUnlock(); chSysUnlock();
} }
return rdp; return msg;
} }
/** /**
* @brief Releases a receive descriptor. * @brief Releases a receive descriptor.
* @details The descriptor and its buffer is made available for more incoming * @details The descriptor and its buffer are made available for more incoming
* frames. * frames.
* *
* @param[in] macp pointer to the @p MACDriver object * @param[in] macp pointer to the @p MACDriver object
* @param[in] rdp the pointer to the @p MACReceiveDescriptor structure * @param[in] rdp the pointer to the @p MACReceiveDescriptor structure
*/ */
void macReleaseReceiveDescriptor(MACDriver *macp, void macReleaseReceiveDescriptor(MACReceiveDescriptor *rdp) {
MACReceiveDescriptor *rdp) {
mac_lld_release_receive_descriptor(macp, rdp); mac_lld_release_receive_descriptor(rdp);
} }
/** /**

View File

@ -30,23 +30,7 @@
#include "mac_lld.h" #include "mac_lld.h"
/** /**
* @brief Returns the buffer associated to a @p MACTransmitDescriptor. * @brief Returns the received frames event source.
*
* @param[in] tdp the pointer to the @p MACTransmitDescriptor structure
* @return The pointer to the transmit buffer.
*/
#define macGetTransmitBuffer(tdp) mac_lld_get_transmit_buffer(tdp)
/**
* @brief Returns the buffer associated to a @p MACReceiveDescriptor.
*
* @param[in] rdp the pointer to the @p MACReceiveDescriptor structure
* @return The pointer to the receive buffer.
*/
#define macGetReceiveBuffer(rdp) mac_lld_get_receive_buffer(rdp)
/**
* @bief Returns the received frames event source.
* *
* @param[in] macp pointer to the @p MACDriver object * @param[in] macp pointer to the @p MACDriver object
* @return The pointer to the @p EventSource structure. * @return The pointer to the @p EventSource structure.
@ -55,24 +39,46 @@
#define macGetReceiveEventSource(macp) (&(macp)->md_rdevent) #define macGetReceiveEventSource(macp) (&(macp)->md_rdevent)
#endif #endif
/**
* @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.
*/
#define macWriteTransmitDescriptor(tdp, buf, size) \
mac_lld_write_transmit_descriptor(tdp, buf, 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.
*/
#define macReadReceiveDescriptor(rdp, buf, size) \
mac_lld_read_receive_descriptor(rdp, buf, size)
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
void macInit(void); void macInit(void);
void macObjectInit(MACDriver *macp); void macObjectInit(MACDriver *macp);
void macSetAddress(MACDriver *macp, const uint8_t *p); void macSetAddress(MACDriver *macp, const uint8_t *p);
void macStart(MACDriver *macp); msg_t macWaitTransmitDescriptor(MACDriver *macp,
void macStop(MACDriver *macp); MACTransmitDescriptor *tdp,
MACTransmitDescriptor *macWaitTransmitDescriptor(MACDriver *macp, systime_t time);
size_t size, void macReleaseTransmitDescriptor(MACTransmitDescriptor *tdp);
systime_t time); msg_t macWaitReceiveDescriptor(MACDriver *macp,
void macReleaseTransmitDescriptor(MACDriver *macp, MACReceiveDescriptor *rdp,
MACTransmitDescriptor *tdp); systime_t time);
MACReceiveDescriptor *macWaitReceiveDescriptor(MACDriver *macp, void macReleaseReceiveDescriptor(MACReceiveDescriptor *rdp);
size_t *szp,
systime_t time);
void macReleaseReceiveDescriptor(MACDriver *macp,
MACReceiveDescriptor *rdp);
bool_t macPollLinkStatus(MACDriver *macp); bool_t macPollLinkStatus(MACDriver *macp);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -24,6 +24,8 @@
* @{ * @{
*/ */
#include <string.h>
#include <ch.h> #include <ch.h>
#include <mac.h> #include <mac.h>
#include <phy.h> #include <phy.h>
@ -32,9 +34,9 @@
#include "at91lib/aic.h" #include "at91lib/aic.h"
/** /**
* @brief EMAC object. * @brief Ethernet driver 1.
*/ */
MACDriver MAC1; MACDriver ETH1;
#define EMAC_PIN_MASK (AT91C_PB0_ETXCK_EREFCK | AT91C_PB1_ETXEN | \ #define EMAC_PIN_MASK (AT91C_PB0_ETXCK_EREFCK | AT91C_PB1_ETXEN | \
AT91C_PB2_ETX0 | AT91C_PB3_ETX1 | \ AT91C_PB2_ETX0 | AT91C_PB3_ETX1 | \
@ -56,13 +58,16 @@ static bool_t link_up;
static uint8_t default_mac[] = {0xAA, 0x55, 0x13, 0x37, 0x01, 0x10}; static uint8_t default_mac[] = {0xAA, 0x55, 0x13, 0x37, 0x01, 0x10};
static MACReceiveDescriptor rd[EMAC_RECEIVE_BUFFERS] __attribute__((aligned(8))); static EMACDescriptor *rxptr;
static uint8_t rb[EMAC_RECEIVE_BUFFERS * EMAC_RECEIVE_BUFFERS_SIZE] __attribute__((aligned(8))); static EMACDescriptor *txptr;
static MACReceiveDescriptor *rxptr; static EMACDescriptor rd[EMAC_RECEIVE_DESCRIPTORS]
__attribute__((aligned(8)));
static MACTransmitDescriptor td[EMAC_TRANSMIT_BUFFERS] __attribute__((aligned(8))); static EMACDescriptor td[EMAC_TRANSMIT_DESCRIPTORS]
static uint8_t tb[EMAC_TRANSMIT_BUFFERS * EMAC_TRANSMIT_BUFFERS_SIZE] __attribute__((aligned(8))); __attribute__((aligned(8)));
static MACTransmitDescriptor *txptr; static uint8_t rb[EMAC_RECEIVE_DESCRIPTORS * EMAC_RECEIVE_BUFFERS_SIZE]
__attribute__((aligned(8)));
static uint8_t tb[EMAC_TRANSMIT_DESCRIPTORS * EMAC_TRANSMIT_BUFFERS_SIZE]
__attribute__((aligned(8)));
#endif #endif
/** /**
@ -82,9 +87,9 @@ static void serve_interrupt(void) {
if ((isr & AT91C_EMAC_RCOMP) || (rsr & RSR_BITS)) { if ((isr & AT91C_EMAC_RCOMP) || (rsr & RSR_BITS)) {
if (rsr & AT91C_EMAC_REC) { if (rsr & AT91C_EMAC_REC) {
chSysLockFromIsr(); chSysLockFromIsr();
chSemResetI(&MAC1.md_rdsem, 0); chSemResetI(&ETH1.md_rdsem, 0);
#if CH_USE_EVENTS #if CH_USE_EVENTS
chEvtBroadcastI(&MAC1.md_rdevent); chEvtBroadcastI(&ETH1.md_rdevent);
#endif #endif
chSysUnlockFromIsr(); chSysUnlockFromIsr();
} }
@ -94,7 +99,7 @@ static void serve_interrupt(void) {
if ((isr & AT91C_EMAC_TCOMP) || (tsr & TSR_BITS)) { if ((isr & AT91C_EMAC_TCOMP) || (tsr & TSR_BITS)) {
if (tsr & AT91C_EMAC_COMP) { if (tsr & AT91C_EMAC_COMP) {
chSysLockFromIsr(); chSysLockFromIsr();
chSemResetI(&MAC1.md_tdsem, 0); chSemResetI(&ETH1.md_tdsem, 0);
chSysUnlockFromIsr(); chSysUnlockFromIsr();
} }
AT91C_BASE_EMAC->EMAC_TSR = TSR_BITS; AT91C_BASE_EMAC->EMAC_TSR = TSR_BITS;
@ -121,28 +126,28 @@ void mac_lld_init(void) {
unsigned i; unsigned i;
phyInit(); phyInit();
macObjectInit(&MAC1); macObjectInit(&ETH1);
/* /*
* Buffers initialization. * Buffers initialization.
*/ */
for (i = 0; i < EMAC_RECEIVE_BUFFERS; i++) { for (i = 0; i < EMAC_RECEIVE_DESCRIPTORS; i++) {
rd[i].w1 = (uint32_t)&rb[i * EMAC_RECEIVE_BUFFERS_SIZE]; rd[i].w1 = (uint32_t)&rb[i * EMAC_RECEIVE_BUFFERS_SIZE];
rd[i].w2 = 0; rd[i].w2 = 0;
} }
rd[EMAC_RECEIVE_BUFFERS - 1].w1 |= W1_R_WRAP; rd[EMAC_RECEIVE_DESCRIPTORS - 1].w1 |= W1_R_WRAP;
rxptr = rd; rxptr = rd;
for (i = 0; i < EMAC_TRANSMIT_BUFFERS; i++) { for (i = 0; i < EMAC_TRANSMIT_DESCRIPTORS; i++) {
td[i].w1 = (uint32_t)&tb[i * EMAC_TRANSMIT_BUFFERS_SIZE]; td[i].w1 = (uint32_t)&tb[i * EMAC_TRANSMIT_BUFFERS_SIZE];
td[i].w2 = EMAC_TRANSMIT_BUFFERS_SIZE | W2_T_LAST_BUFFER | W2_T_USED; td[i].w2 = EMAC_TRANSMIT_BUFFERS_SIZE | W2_T_LAST_BUFFER | W2_T_USED;
} }
td[EMAC_TRANSMIT_BUFFERS - 1].w2 |= W2_T_WRAP; td[EMAC_TRANSMIT_DESCRIPTORS - 1].w2 |= W2_T_WRAP;
txptr = td; txptr = td;
/* /*
* Associated PHY initialization. * Associated PHY initialization.
*/ */
phyReset(&MAC1); phyReset(&ETH1);
/* /*
* EMAC pins setup and clock enable. Note, PB18 is not included because it is * EMAC pins setup and clock enable. Note, PB18 is not included because it is
@ -168,15 +173,15 @@ void mac_lld_init(void) {
AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_TE | AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_TE |
AT91C_EMAC_RE | AT91C_EMAC_RE |
AT91C_EMAC_CLRSTAT;/* Initial NCR settings.*/ AT91C_EMAC_CLRSTAT;/* Initial NCR settings.*/
mac_lld_set_address(&MAC1, default_mac); mac_lld_set_address(&ETH1, default_mac);
#if PHY_HARDWARE == PHY_MICREL_KS8721 #if PHY_HARDWARE == PHY_MICREL_KS8721
/* /*
* PHY device identification. * PHY device identification.
*/ */
AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_MPE; AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_MPE;
if ((phyGet(&MAC1, MII_PHYSID1) != (MII_KS8721_ID >> 16)) || if ((phyGet(&ETH1, MII_PHYSID1) != (MII_KS8721_ID >> 16)) ||
((phyGet(&MAC1, MII_PHYSID2) & 0xFFF0) != (MII_KS8721_ID & 0xFFF0))) ((phyGet(&ETH1, MII_PHYSID2) & 0xFFF0) != (MII_KS8721_ID & 0xFFF0)))
chSysHalt(); chSysHalt();
AT91C_BASE_EMAC->EMAC_NCR &= ~AT91C_EMAC_MPE; AT91C_BASE_EMAC->EMAC_NCR &= ~AT91C_EMAC_MPE;
#endif #endif
@ -213,91 +218,104 @@ void mac_lld_set_address(MACDriver *macp, const uint8_t *p) {
* returned. * returned.
* *
* @param[in] macp pointer to the @p MACDriver object * @param[in] macp pointer to the @p MACDriver object
* @param[in] size size of the frame to be transmitted * @param[out] tdp pointer to a @p MACTransmitDescriptor structure
* @return A pointer to a @p MACTransmitDescriptor structure or @p NULL if * @return The operation status.
* a descriptor is not available. * @retval RDY_OK the descriptor was obtained.
* @retval RDY_TIMEOUT descriptor not available.
*/ */
MACTransmitDescriptor *max_lld_get_transmit_descriptor(MACDriver *macp, msg_t max_lld_get_transmit_descriptor(MACDriver *macp,
size_t size) { MACTransmitDescriptor *tdp) {
MACTransmitDescriptor *tdp; EMACDescriptor *edp;
chDbgAssert(size <= EMAC_TRANSMIT_BUFFERS_SIZE,
"max_lld_get_transmit_descriptor(), #1",
"unexpected size");
if (!link_up) if (!link_up)
return NULL; return RDY_TIMEOUT;
chSysLock(); chSysLock();
tdp = txptr; edp = txptr;
chDbgAssert((tdp->w2 & W2_T_USED) && !(tdp->w2 & W2_T_LOCKED), if (!(edp->w2 & W2_T_USED) || (edp->w2 & W2_T_LOCKED)) {
"max_lld_get_transmit_descriptor(), #2", "buffer not available");
if (!(tdp->w2 & W2_T_USED) || (tdp->w2 & W2_T_LOCKED)) {
chSysUnlock(); chSysUnlock();
return NULL; return RDY_TIMEOUT;
} }
/* /*
* Set the buffer size and configuration, the buffer is also marked * Set the buffer size and configuration, the buffer is also marked
* as locked. * as locked.
*/ */
tdp->w2 = size | W2_T_LOCKED | W2_T_USED | W2_T_LAST_BUFFER; if (++txptr >= &td[EMAC_TRANSMIT_DESCRIPTORS]) {
if (++txptr >= &td[EMAC_TRANSMIT_BUFFERS]) { edp->w2 = W2_T_LOCKED | W2_T_USED | W2_T_LAST_BUFFER | W2_T_WRAP;
tdp->w2 |= W2_T_WRAP;
txptr = td; txptr = td;
} }
else
edp->w2 = W2_T_LOCKED | W2_T_USED | W2_T_LAST_BUFFER;
chSysUnlock(); chSysUnlock();
return tdp; tdp->td_offset = 0;
tdp->td_size = EMAC_TRANSMIT_BUFFERS_SIZE;
tdp->td_physdesc = edp;
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 cointaining 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.
*/
size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp,
uint8_t *buf,
size_t size) {
if (size > tdp->td_size - tdp->td_offset)
size = tdp->td_size - tdp->td_offset;
if (size > 0) {
memcpy((uint8_t *)(tdp->td_physdesc->w1 & W1_T_ADDRESS_MASK) +
tdp->td_offset,
buf, size);
tdp->td_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.
* *
* @param[in] macp pointer to the @p MACDriver object
* @param[in] tdp the pointer to the @p MACTransmitDescriptor structure * @param[in] tdp the pointer to the @p MACTransmitDescriptor structure
* @param[in]
*/ */
void mac_lld_release_transmit_descriptor(MACDriver *macp, void mac_lld_release_transmit_descriptor(MACTransmitDescriptor *tdp) {
MACTransmitDescriptor *tdp) {
chSysLock(); chSysLock();
tdp->w2 &= ~(W2_T_LOCKED | W2_T_USED); tdp->td_physdesc->w2 = (tdp->td_physdesc->w2 &
~(W2_T_LOCKED | W2_T_USED | W2_T_LENGTH_MASK)) |
tdp->td_offset;
AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_TSTART; AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_TSTART;
chSysUnlock(); chSysUnlock();
} }
/** /**
* @brief Returns the buffer associated to a @p MACTransmitDescriptor. * @brief Returns a receive descriptor.
*
* @param[in] tdp the pointer to the @p MACTransmitDescriptor structure
* @return The pointer to the transmit buffer.
*/
uint8_t *mac_lld_get_transmit_buffer(MACTransmitDescriptor *tdp) {
return (uint8_t *)(tdp->w1 & W1_T_ADDRESS_MASK);
}
/**
* @brief Returns a received frame.
* *
* @param[in] macp pointer to the @p MACDriver object * @param[in] macp pointer to the @p MACDriver object
* @param[out szp size of the received frame * @param[out] rdp pointer to a @p MACReceiveDescriptor structure
* @return A pointer to a @p MACReceiveDescriptor structure or @p NULL if * @return The operation status.
* the operation timed out or some transient error happened. * @retval RDY_OK the descriptor was obtained.
* @retval RDY_TIMEOUT descriptor not available.
*/ */
MACReceiveDescriptor *max_lld_get_receive_descriptor(MACDriver *macp, msg_t max_lld_get_receive_descriptor(MACDriver *macp,
size_t *szp) { MACReceiveDescriptor *rdp) {
unsigned n; unsigned n;
MACReceiveDescriptor *rdp; EMACDescriptor *edp;
n = EMAC_RECEIVE_BUFFERS; n = EMAC_RECEIVE_DESCRIPTORS;
/* /*
* Skips unused buffers, if any. * Skips unused buffers, if any.
*/ */
skip: skip:
while ((n > 0) && !(rxptr->w1 & W1_R_OWNERSHIP)) { while ((n > 0) && !(rxptr->w1 & W1_R_OWNERSHIP)) {
if (++rxptr >= &rd[EMAC_RECEIVE_BUFFERS]) if (++rxptr >= &rd[EMAC_RECEIVE_DESCRIPTORS])
rxptr = rd; rxptr = rd;
n--; n--;
} }
@ -308,7 +326,7 @@ skip:
while ((n > 0) && (rxptr->w1 & W1_R_OWNERSHIP) && while ((n > 0) && (rxptr->w1 & W1_R_OWNERSHIP) &&
!(rxptr->w2 & W2_R_FRAME_START)) { !(rxptr->w2 & W2_R_FRAME_START)) {
rxptr->w1 &= ~W1_R_OWNERSHIP; rxptr->w1 &= ~W1_R_OWNERSHIP;
if (++rxptr >= &rd[EMAC_RECEIVE_BUFFERS]) if (++rxptr >= &rd[EMAC_RECEIVE_DESCRIPTORS])
rxptr = rd; rxptr = rd;
n--; n--;
} }
@ -318,7 +336,7 @@ skip:
* or holes... * or holes...
*/ */
restart: restart:
rdp = rxptr; edp = rxptr;
while (n > 0) { while (n > 0) {
if (!(rxptr->w1 & W1_R_OWNERSHIP)) if (!(rxptr->w1 & W1_R_OWNERSHIP))
goto skip; /* Empty buffer for some reason... */ goto skip; /* Empty buffer for some reason... */
@ -327,58 +345,88 @@ restart:
* End Of Frame found. * End Of Frame found.
*/ */
if (rxptr->w2 & W2_R_FRAME_END) { if (rxptr->w2 & W2_R_FRAME_END) {
*szp = rxptr->w2 & W2_T_LENGTH_MASK; rdp->rd_offset = 0;
return rdp; rdp->rd_size = rxptr->w2 & W2_T_LENGTH_MASK;
rdp->rd_physdesc = edp;
return RDY_OK;
} }
if ((rdp != rxptr) && (rxptr->w2 & W2_R_FRAME_START)) { if ((edp != rxptr) && (rxptr->w2 & W2_R_FRAME_START)) {
/* Found another start... cleaning up the incomplete frame.*/ /* Found another start... cleaning up the incomplete frame.*/
do { do {
rdp->w1 &= ~W1_R_OWNERSHIP; edp->w1 &= ~W1_R_OWNERSHIP;
if (++rdp >= &rd[EMAC_RECEIVE_BUFFERS]) if (++edp >= &rd[EMAC_RECEIVE_DESCRIPTORS])
rdp = rd; edp = rd;
} }
while (rdp != rxptr); while (edp != rxptr);
goto restart; /* Another start buffer for some reason... */ goto restart; /* Another start buffer for some reason... */
} }
if (++rxptr >= &rd[EMAC_RECEIVE_BUFFERS]) if (++rxptr >= &rd[EMAC_RECEIVE_DESCRIPTORS])
rxptr = rd; rxptr = rd;
n--; n--;
} }
return NULL; 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.
*/
size_t mac_lld_read_receive_descriptor(MACReceiveDescriptor *rdp,
uint8_t *buf,
size_t size) {
if (size > rdp->rd_size - rdp->rd_offset)
size = rdp->rd_size - rdp->rd_offset;
if (size > 0) {
uint8_t *src = (uint8_t *)(rdp->rd_physdesc->w1 & W1_R_ADDRESS_MASK) +
rdp->rd_offset;
uint8_t *limit = &rb[EMAC_RECEIVE_DESCRIPTORS * EMAC_RECEIVE_BUFFERS_SIZE];
if (src + size > limit ) {
memcpy(buf, src, (size_t)(limit - src));
memcpy(buf, rb, (size_t)(src + size - limit));
}
else
memcpy(buf, src, size);
rdp->rd_offset += size;
}
return size;
} }
/** /**
* @brief Releases a receive descriptor. * @brief Releases a receive descriptor.
* @details The descriptor and its buffer is made available for more incoming * @details The descriptor and its buffer are made available for more incoming
* frames. * frames.
* *
* @param[in] macp pointer to the @p MACDriver object
* @param[in] rdp the pointer to the @p MACReceiveDescriptor structure * @param[in] rdp the pointer to the @p MACReceiveDescriptor structure
*/ */
void mac_lld_release_receive_descriptor(MACDriver *macp, void mac_lld_release_receive_descriptor(MACReceiveDescriptor *rdp) {
MACReceiveDescriptor *rdp) { bool_t done;
EMACDescriptor *edp = rdp->rd_physdesc;
unsigned n = EMAC_RECEIVE_BUFFERS; unsigned n = EMAC_RECEIVE_DESCRIPTORS;
do { do {
rdp->w1 &= ~W1_R_OWNERSHIP; done = ((edp->w2 & W2_R_FRAME_END) != 0);
if (++rdp >= &rd[EMAC_RECEIVE_BUFFERS]) chDbgAssert(edp->w1 & W1_R_OWNERSHIP,
rdp = rd; "mac_lld_release_receive_descriptor(), #1",
"found not owned descriptor");
edp->w1 &= ~(W1_R_OWNERSHIP | W2_R_FRAME_START | W2_R_FRAME_END);
if (++edp >= &rd[EMAC_RECEIVE_DESCRIPTORS])
edp = rd;
n--; n--;
} }
while ((n > 0) || !(rxptr->w2 & W2_R_FRAME_END)); while ((n > 0) && !done);
} /*
* Make rxptr point to the descriptor where the next frame will most
/** * likely appear.
* @brief Returns the buffer associated to a @p MACTransmitDescriptor. */
* rxptr = edp;
* @param[in] tdp the pointer to the @p MACTransmitDescriptor structure
* @return The pointer to the transmit buffer.
*/
uint8_t *mac_lld_get_receive_buffer(MACReceiveDescriptor *rdp) {
return (uint8_t *)(rdp->w1 & W1_R_ADDRESS_MASK);
} }
/** /**

View File

@ -32,14 +32,28 @@
/*===========================================================================*/ /*===========================================================================*/
/** /**
* @brief Number of available descriptors/buffers. * @brief Number of available transmit buffers.
*/ */
#if !defined(MAC_TRANSMIT_DESCRIPTORS) || defined(__DOXYGEN__) #if !defined(MAC_TRANSMIT_BUFFERS) || defined(__DOXYGEN__)
#define MAC_TRANSMIT_DESCRIPTORS 2 #define MAC_TRANSMIT_BUFFERS 2
#endif
/**
* @brief Number of available receive buffers.
*/
#if !defined(MAC_RECEIVE_BUFFERS) || defined(__DOXYGEN__)
#define MAC_RECEIVE_BUFFERS 2
#endif
/**
* @brief Maximum supported frame size.
*/
#if !defined(MAC_BUFFERS_SIZE) || defined(__DOXYGEN__)
#define MAC_BUFFERS_SIZE 1518
#endif #endif
/*===========================================================================*/ /*===========================================================================*/
/* EMAC specific constants and settings. */ /* EMAC specific settings. */
/*===========================================================================*/ /*===========================================================================*/
/** /**
@ -49,10 +63,16 @@
#define EMAC_INTERRUPT_PRIORITY (AT91C_AIC_PRIOR_HIGHEST - 3) #define EMAC_INTERRUPT_PRIORITY (AT91C_AIC_PRIOR_HIGHEST - 3)
#endif #endif
#define EMAC_RECEIVE_BUFFERS 24 /*===========================================================================*/
/* EMAC specific constants. */
/*===========================================================================*/
#define EMAC_RECEIVE_BUFFERS_SIZE 128 /* Do not modify */ #define EMAC_RECEIVE_BUFFERS_SIZE 128 /* Do not modify */
#define EMAC_TRANSMIT_BUFFERS MAC_TRANSMIT_DESCRIPTORS #define EMAC_TRANSMIT_BUFFERS_SIZE MAC_BUFFERS_SIZE
#define EMAC_TRANSMIT_BUFFERS_SIZE 1518 #define EMAC_RECEIVE_DESCRIPTORS \
(((((MAC_BUFFERS_SIZE - 1) | (EMAC_RECEIVE_BUFFERS_SIZE - 1)) + 1) \
/ EMAC_RECEIVE_BUFFERS_SIZE) * MAC_RECEIVE_BUFFERS)
#define EMAC_TRANSMIT_DESCRIPTORS MAC_TRANSMIT_BUFFERS
#define W1_R_OWNERSHIP 0x00000001 #define W1_R_OWNERSHIP 0x00000001
#define W1_R_WRAP 0x00000002 #define W1_R_WRAP 0x00000002
@ -94,33 +114,47 @@
/* Driver data structures and types. */ /* Driver data structures and types. */
/*===========================================================================*/ /*===========================================================================*/
/**
* @brief Structure representing a buffer physical descriptor.
* @note It represents both descriptor types.
*/
typedef struct {
uint32_t w1;
uint32_t w2;
} EMACDescriptor;
/** /**
* @brief Structure representing a MAC driver. * @brief Structure representing a MAC driver.
*/ */
typedef struct { typedef struct {
Semaphore md_tdsem; /**< Transmit semaphore.*/ Semaphore md_tdsem; /**< Transmit semaphore. */
Semaphore md_rdsem; /**< Receive semaphore.*/ Semaphore md_rdsem; /**< Receive semaphore. */
#if CH_USE_EVENTS #if CH_USE_EVENTS
EventSource md_rdevent; /**< Receive event source.*/ EventSource md_rdevent; /**< Receive event source. */
#endif #endif
/* End of the mandatory fields.*/
} MACDriver; } MACDriver;
/** /**
* @brief Structure representing a transmission descriptor. * @brief Structure representing a transmit descriptor.
*/ */
typedef struct { typedef struct {
size_t td_offset; /**< Current write offset. */
uint32_t w1; size_t td_size; /**< Available space size. */
uint32_t w2; /* End of the mandatory fields.*/
EMACDescriptor *td_physdesc; /**< Pointer to the physical
descriptor. */
} MACTransmitDescriptor; } MACTransmitDescriptor;
/** /**
* @brief Structure representing a receive descriptor. * @brief Structure representing a receive descriptor.
*/ */
typedef struct { typedef struct {
size_t rd_offset; /**< Current read offset. */
uint32_t w1; size_t rd_size; /**< Available data size. */
uint32_t w2; /* End of the mandatory fields.*/
EMACDescriptor *rd_physdesc; /**< Pointer to the first descriptor
of the buffers chain. */
} MACReceiveDescriptor; } MACReceiveDescriptor;
/*===========================================================================*/ /*===========================================================================*/
@ -128,23 +162,25 @@ typedef struct {
/*===========================================================================*/ /*===========================================================================*/
/** @cond never*/ /** @cond never*/
extern MACDriver MAC1; extern MACDriver ETH1;
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
void mac_lld_init(void); void mac_lld_init(void);
void mac_lld_set_address(MACDriver *macp, const uint8_t *p); void mac_lld_set_address(MACDriver *macp, const uint8_t *p);
MACTransmitDescriptor *max_lld_get_transmit_descriptor(MACDriver *macp, msg_t max_lld_get_transmit_descriptor(MACDriver *macp,
size_t size); MACTransmitDescriptor *tdp);
void mac_lld_release_transmit_descriptor(MACDriver *macp, size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp,
MACTransmitDescriptor *tdp); uint8_t *buf,
uint8_t *mac_lld_get_transmit_buffer(MACTransmitDescriptor *tdp); size_t size);
MACReceiveDescriptor *max_lld_get_receive_descriptor(MACDriver *macp, void mac_lld_release_transmit_descriptor(MACTransmitDescriptor *tdp);
size_t *szp); msg_t max_lld_get_receive_descriptor(MACDriver *macp,
void mac_lld_release_receive_descriptor(MACDriver *macp, MACReceiveDescriptor *rdp);
MACReceiveDescriptor *rdp); size_t mac_lld_read_receive_descriptor(MACReceiveDescriptor *rdp,
uint8_t *mac_lld_get_receive_buffer(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); bool_t mac_lld_poll_link_status(MACDriver *macp);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -52,77 +52,87 @@ void mac_lld_set_address(MACDriver *macp, const uint8_t *p) {
* returned. * returned.
* *
* @param[in] macp pointer to the @p MACDriver object * @param[in] macp pointer to the @p MACDriver object
* @param[in] size size of the frame to be transmitted * @param[out] tdp pointer to a @p MACTransmitDescriptor structure
* @return A pointer to a @p MACTransmitDescriptor structure or @p NULL if * @return The operation status.
* a descriptor is not available. * @retval RDY_OK the descriptor was obtained.
* @retval RDY_TIMEOUT descriptor not available.
*/ */
MACTransmitDescriptor *max_lld_get_transmit_descriptor(MACDriver *macp, msg_t max_lld_get_transmit_descriptor(MACDriver *macp,
size_t size) { MACTransmitDescriptor *tdp) {
return NULL; 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 cointaining 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.
*/
size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp,
uint8_t *buf,
size_t size) {
return 0;
} }
/** /**
* @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.
* *
* @param[in] macp pointer to the @p MACDriver object
* @param[in] tdp the pointer to the @p MACTransmitDescriptor structure * @param[in] tdp the pointer to the @p MACTransmitDescriptor structure
*/ */
void mac_lld_release_transmit_descriptor(MACDriver *macp, void mac_lld_release_transmit_descriptor(MACTransmitDescriptor *tdp) {
MACTransmitDescriptor *tdp) {
} }
/** /**
* @brief Returns the buffer associated to a @p MACTransmitDescriptor. * @brief Returns a receive descriptor.
* *
* @param[in] tdp the pointer to the @p MACTransmitDescriptor structure * @param[in] macp pointer to the @p MACDriver object
* @return The pointer to the transmit buffer. * @param[out] rdp pointer to a @p MACReceiveDescriptor structure
* @return The operation status.
* @retval RDY_OK the descriptor was obtained.
* @retval RDY_TIMEOUT descriptor not available.
*/ */
uint8_t *mac_lld_get_transmit_buffer(MACTransmitDescriptor *tdp) { msg_t max_lld_get_receive_descriptor(MACDriver *macp,
MACReceiveDescriptor *rdp) {
return NULL; return RDY_OK;
} }
/** /**
* @brief Returns a received frame. * @brief Reads from a receive descriptor's stream.
* *
* @param[in] macp pointer to the @p MACDriver object * @param[in] rdp pointer to a @p MACReceiveDescriptor structure
* @param[out szp size of the received frame * @param[in] buf pointer to the buffer that will receive the read data
* @return A pointer to a @p MACReceiveDescriptor structure or @p NULL if * @param[in] size number of bytes to be read
* the operation timed out or some transient error happened. * @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.
*/ */
MACReceiveDescriptor *max_lld_get_receive_descriptor(MACDriver *macp, size_t mac_lld_read_receive_descriptor(MACReceiveDescriptor *rdp,
size_t *szp) { uint8_t *buf,
size_t size) {
return NULL; return 0;
} }
/** /**
* @brief Releases a receive descriptor. * @brief Releases a receive descriptor.
* @details The descriptor and its buffer is made available for more incoming * @details The descriptor and its buffer are made available for more incoming
* frames. * frames.
* *
* @param[in] macp pointer to the @p MACDriver object
* @param[in] rdp the pointer to the @p MACReceiveDescriptor structure * @param[in] rdp the pointer to the @p MACReceiveDescriptor structure
*/ */
void mac_lld_release_receive_descriptor(MACDriver *macp, void mac_lld_release_receive_descriptor(MACReceiveDescriptor *rdp) {
MACReceiveDescriptor *rdp) {
} }
/**
* @brief Returns the buffer associated to a @p MACTransmitDescriptor.
*
* @param[in] tdp the pointer to the @p MACTransmitDescriptor structure
* @return The pointer to the transmit buffer.
*/
uint8_t *mac_lld_get_receive_buffer(MACReceiveDescriptor *rdp) {
return NULL;
}
/** /**
* @brief Updates and returns the link status. * @brief Updates and returns the link status.
* *

View File

@ -32,10 +32,24 @@
/*===========================================================================*/ /*===========================================================================*/
/** /**
* @brief Number of available descriptors/buffers. * @brief Number of available transmit buffers.
*/ */
#if !defined(MAC_TRANSMIT_DESCRIPTORS) || defined(__DOXYGEN__) #if !defined(MAC_TRANSMIT_BUFFERS) || defined(__DOXYGEN__)
#define MAC_TRANSMIT_DESCRIPTORS 2 #define MAC_TRANSMIT_BUFFERS 2
#endif
/**
* @brief Number of available receive buffers.
*/
#if !defined(MAC_RECEIVE_BUFFERS) || defined(__DOXYGEN__)
#define MAC_RECEIVE_BUFFERS 2
#endif
/**
* @brief Maximum supported frame size.
*/
#if !defined(MAC_BUFFERS_SIZE) || defined(__DOXYGEN__)
#define MAC_BUFFERS_SIZE 1518
#endif #endif
/*===========================================================================*/ /*===========================================================================*/
@ -46,25 +60,30 @@
* @brief Structure representing a MAC driver. * @brief Structure representing a MAC driver.
*/ */
typedef struct { typedef struct {
Semaphore md_tdsem; /**< Transmit semaphore.*/ Semaphore md_tdsem; /**< Transmit semaphore. */
Semaphore md_rdsem; /**< Receive semaphore.*/ Semaphore md_rdsem; /**< Receive semaphore. */
#if CH_USE_EVENTS #if CH_USE_EVENTS
EventSource md_rdevent; /**< Receive event source.*/ EventSource md_rdevent; /**< Receive event source. */
#endif #endif
/* End of the mandatory fields.*/
} MACDriver; } MACDriver;
/** /**
* @brief Structure representing a transmission descriptor. * @brief Structure representing a transmit descriptor.
*/ */
typedef struct { typedef struct {
size_t td_offset; /**< Current write offset. */
size_t td_size; /**< Available space size. */
/* End of the mandatory fields.*/
} MACTransmitDescriptor; } MACTransmitDescriptor;
/** /**
* @brief Structure representing a receive descriptor. * @brief Structure representing a receive descriptor.
*/ */
typedef struct { typedef struct {
size_t rd_offset; /**< Current read offset. */
size_t rd_size; /**< Available data size. */
/* End of the mandatory fields.*/
} MACReceiveDescriptor; } MACReceiveDescriptor;
/*===========================================================================*/ /*===========================================================================*/
@ -76,16 +95,18 @@ extern "C" {
#endif #endif
void mac_lld_init(void); void mac_lld_init(void);
void mac_lld_set_address(MACDriver *macp, const uint8_t *p); void mac_lld_set_address(MACDriver *macp, const uint8_t *p);
MACTransmitDescriptor *max_lld_get_transmit_descriptor(MACDriver *macp, msg_t max_lld_get_transmit_descriptor(MACDriver *macp,
size_t size); MACTransmitDescriptor *tdp);
void mac_lld_release_transmit_descriptor(MACDriver *macp, size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp,
MACTransmitDescriptor *tdp); uint8_t *buf,
uint8_t *mac_lld_get_transmit_buffer(MACTransmitDescriptor *tdp); size_t size);
MACReceiveDescriptor *max_lld_get_receive_descriptor(MACDriver *macp, void mac_lld_release_transmit_descriptor(MACTransmitDescriptor *tdp);
size_t *szp); msg_t max_lld_get_receive_descriptor(MACDriver *macp,
void mac_lld_release_receive_descriptor(MACDriver *macp, MACReceiveDescriptor *rdp);
MACReceiveDescriptor *rdp); size_t mac_lld_read_receive_descriptor(MACReceiveDescriptor *rdp,
uint8_t *mac_lld_get_receive_buffer(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); bool_t mac_lld_poll_link_status(MACDriver *macp);
#ifdef __cplusplus #ifdef __cplusplus
} }