1
0
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:
Benjamin Valentin 2024-04-26 18:30:59 +02:00
parent 1f5e2c7214
commit 4d1a5aa62c
3 changed files with 54 additions and 11 deletions

View File

@ -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

View File

@ -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

View File

@ -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