mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
cpu/sam0_common: eth: port to new netdev API
This commit is contained in:
parent
1f5e2c7214
commit
4d1a5aa62c
@ -20,7 +20,7 @@ USEMODULE += sam0_common_periph
|
||||
ifneq (,$(filter sam0_eth,$(USEMODULE)))
|
||||
USEMODULE += iolist
|
||||
USEMODULE += netdev_eth
|
||||
USEMODULE += netdev_legacy_api
|
||||
USEMODULE += netdev_new_api
|
||||
USEMODULE += netopt
|
||||
FEATURES_REQUIRED += periph_eth
|
||||
FEATURES_REQUIRED += periph_gpio_irq
|
||||
|
@ -237,14 +237,16 @@ int sam0_eth_send(const struct iolist *iolist)
|
||||
}
|
||||
if (len == tx_len) {
|
||||
/* Clear and set the frame size */
|
||||
tx_curr->status &= ~DESC_TX_STATUS_LEN_MASK;
|
||||
tx_curr->status |= (len & DESC_TX_STATUS_LEN_MASK);
|
||||
tx_curr->status = (len & DESC_TX_STATUS_LEN_MASK)
|
||||
/* Indicate this is the last buffer and the frame is ready */
|
||||
tx_curr->status |= DESC_TX_STATUS_LAST_BUF | DESC_TX_STATUS_USED;
|
||||
| DESC_TX_STATUS_LAST_BUF;
|
||||
/* Prepare next buffer index */
|
||||
tx_idx = (tx_idx < ETH_TX_BUFFER_COUNT-1) ? tx_idx+1 : 0;
|
||||
__DSB();
|
||||
tx_curr->status &= ~DESC_TX_STATUS_USED;
|
||||
if (++tx_idx == ETH_TX_BUFFER_COUNT) {
|
||||
/* Set WRAP flag to indicate last buffer */
|
||||
tx_curr->status |= DESC_TX_STATUS_WRAP;
|
||||
tx_idx = 0;
|
||||
}
|
||||
__DMB();
|
||||
/* Start transmission */
|
||||
GMAC->NCR.reg |= GMAC_NCR_TSTART;
|
||||
/* Set the next buffer */
|
||||
@ -256,6 +258,12 @@ int sam0_eth_send(const struct iolist *iolist)
|
||||
return len;
|
||||
}
|
||||
|
||||
unsigned _sam0_eth_get_last_len(void)
|
||||
{
|
||||
unsigned idx = tx_idx ? tx_idx - 1 : ETH_TX_BUFFER_COUNT - 1;
|
||||
return tx_desc[idx].status & DESC_TX_STATUS_LEN_MASK;
|
||||
}
|
||||
|
||||
static int _try_receive(char* data, unsigned max_len, int block)
|
||||
{
|
||||
(void)block;
|
||||
@ -382,8 +390,10 @@ int sam0_eth_init(void)
|
||||
GMAC->IDR.reg = 0xFFFFFFFF;
|
||||
/* clear flags */
|
||||
GMAC->RSR.reg = GMAC_RSR_HNO | GMAC_RSR_RXOVR | GMAC_RSR_REC | GMAC_RSR_BNA;
|
||||
GMAC->TSR.reg = 0xFFFF;
|
||||
/* Enable needed interrupts */
|
||||
GMAC->IER.reg = GMAC_IER_RCOMP;
|
||||
GMAC->IER.reg = GMAC_IER_RCOMP
|
||||
| GMAC_IER_TCOMP | GMAC_IER_TFC | GMAC_IER_RLEX;
|
||||
|
||||
GMAC->NCFGR.reg = GMAC_NCFGR_MTIHEN
|
||||
| GMAC_NCFGR_RXCOEN | GMAC_NCFGR_MAXFS | GMAC_NCFGR_CAF
|
||||
|
@ -205,10 +205,36 @@ static int _sam0_eth_send(netdev_t *netdev, const iolist_t *iolist)
|
||||
/* TODO: use a specific netdev callback here ? */
|
||||
return -EOVERFLOW;
|
||||
}
|
||||
netdev->event_callback(netdev, NETDEV_EVENT_TX_COMPLETE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int _sam0_eth_confirm_send(netdev_t *netdev, void *info)
|
||||
{
|
||||
(void)netdev;
|
||||
(void)info;
|
||||
|
||||
uint32_t tsr = GMAC->TSR.reg;
|
||||
GMAC->TSR.reg = tsr; /* clear flags */
|
||||
|
||||
/* transmit is active */
|
||||
if (tsr & GMAC_TSR_TXGO) {
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
/* Retry Limit Exceeded */
|
||||
if (tsr & GMAC_TSR_RLE) {
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/* Transmit Frame Corruption, Collision Occurred */
|
||||
if (tsr & (GMAC_TSR_TFC | GMAC_TSR_COL)) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
extern unsigned _sam0_eth_get_last_len(void);
|
||||
return _sam0_eth_get_last_len();
|
||||
}
|
||||
|
||||
static int _sam0_eth_get(netdev_t *netdev, netopt_t opt, void *val, size_t max_len)
|
||||
{
|
||||
int res = -1;
|
||||
@ -278,6 +304,7 @@ static int _sam0_eth_set(netdev_t *netdev, netopt_t opt, const void *val, size_t
|
||||
static const netdev_driver_t _sam0_eth_driver =
|
||||
{
|
||||
.send = _sam0_eth_send,
|
||||
.confirm_send = _sam0_eth_confirm_send,
|
||||
.recv = _sam0_eth_recv,
|
||||
.init = _sam0_eth_init,
|
||||
.isr = _sam0_eth_isr,
|
||||
@ -301,15 +328,21 @@ void isr_gmac(void)
|
||||
{
|
||||
uint32_t isr;
|
||||
uint32_t rsr;
|
||||
netdev_t* netdev = _sam0_eth_dev.netdev;
|
||||
|
||||
isr = GMAC->ISR.reg;
|
||||
rsr = GMAC->RSR.reg;
|
||||
(void)isr;
|
||||
|
||||
/* TX done, signal it to netdev */
|
||||
if (isr & GMAC_ISR_TCOMP) {
|
||||
netdev->event_callback(netdev, NETDEV_EVENT_TX_COMPLETE);
|
||||
}
|
||||
|
||||
/* New frame received, signal it to netdev */
|
||||
if (rsr & GMAC_RSR_REC) {
|
||||
netdev_trigger_event_isr(_sam0_eth_dev.netdev);
|
||||
netdev_trigger_event_isr(netdev);
|
||||
}
|
||||
|
||||
/* Buffers Not Available, this can occur if there is a heavy traffic
|
||||
on the network. In this case, disable the GMAC reception, flush
|
||||
our internal buffers and re-enable the reception. This will drop
|
||||
|
Loading…
Reference in New Issue
Block a user