mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-17 05:32:45 +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)))
|
ifneq (,$(filter sam0_eth,$(USEMODULE)))
|
||||||
USEMODULE += iolist
|
USEMODULE += iolist
|
||||||
USEMODULE += netdev_eth
|
USEMODULE += netdev_eth
|
||||||
USEMODULE += netdev_legacy_api
|
USEMODULE += netdev_new_api
|
||||||
USEMODULE += netopt
|
USEMODULE += netopt
|
||||||
FEATURES_REQUIRED += periph_eth
|
FEATURES_REQUIRED += periph_eth
|
||||||
FEATURES_REQUIRED += periph_gpio_irq
|
FEATURES_REQUIRED += periph_gpio_irq
|
||||||
|
@ -237,14 +237,16 @@ int sam0_eth_send(const struct iolist *iolist)
|
|||||||
}
|
}
|
||||||
if (len == tx_len) {
|
if (len == tx_len) {
|
||||||
/* Clear and set the frame size */
|
/* 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 */
|
/* 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 */
|
/* Prepare next buffer index */
|
||||||
tx_idx = (tx_idx < ETH_TX_BUFFER_COUNT-1) ? tx_idx+1 : 0;
|
if (++tx_idx == ETH_TX_BUFFER_COUNT) {
|
||||||
__DSB();
|
/* Set WRAP flag to indicate last buffer */
|
||||||
tx_curr->status &= ~DESC_TX_STATUS_USED;
|
tx_curr->status |= DESC_TX_STATUS_WRAP;
|
||||||
|
tx_idx = 0;
|
||||||
|
}
|
||||||
|
__DMB();
|
||||||
/* Start transmission */
|
/* Start transmission */
|
||||||
GMAC->NCR.reg |= GMAC_NCR_TSTART;
|
GMAC->NCR.reg |= GMAC_NCR_TSTART;
|
||||||
/* Set the next buffer */
|
/* Set the next buffer */
|
||||||
@ -256,6 +258,12 @@ int sam0_eth_send(const struct iolist *iolist)
|
|||||||
return len;
|
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)
|
static int _try_receive(char* data, unsigned max_len, int block)
|
||||||
{
|
{
|
||||||
(void)block;
|
(void)block;
|
||||||
@ -382,8 +390,10 @@ int sam0_eth_init(void)
|
|||||||
GMAC->IDR.reg = 0xFFFFFFFF;
|
GMAC->IDR.reg = 0xFFFFFFFF;
|
||||||
/* clear flags */
|
/* clear flags */
|
||||||
GMAC->RSR.reg = GMAC_RSR_HNO | GMAC_RSR_RXOVR | GMAC_RSR_REC | GMAC_RSR_BNA;
|
GMAC->RSR.reg = GMAC_RSR_HNO | GMAC_RSR_RXOVR | GMAC_RSR_REC | GMAC_RSR_BNA;
|
||||||
|
GMAC->TSR.reg = 0xFFFF;
|
||||||
/* Enable needed interrupts */
|
/* 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.reg = GMAC_NCFGR_MTIHEN
|
||||||
| GMAC_NCFGR_RXCOEN | GMAC_NCFGR_MAXFS | GMAC_NCFGR_CAF
|
| 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 ? */
|
/* TODO: use a specific netdev callback here ? */
|
||||||
return -EOVERFLOW;
|
return -EOVERFLOW;
|
||||||
}
|
}
|
||||||
netdev->event_callback(netdev, NETDEV_EVENT_TX_COMPLETE);
|
|
||||||
return ret;
|
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)
|
static int _sam0_eth_get(netdev_t *netdev, netopt_t opt, void *val, size_t max_len)
|
||||||
{
|
{
|
||||||
int res = -1;
|
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 =
|
static const netdev_driver_t _sam0_eth_driver =
|
||||||
{
|
{
|
||||||
.send = _sam0_eth_send,
|
.send = _sam0_eth_send,
|
||||||
|
.confirm_send = _sam0_eth_confirm_send,
|
||||||
.recv = _sam0_eth_recv,
|
.recv = _sam0_eth_recv,
|
||||||
.init = _sam0_eth_init,
|
.init = _sam0_eth_init,
|
||||||
.isr = _sam0_eth_isr,
|
.isr = _sam0_eth_isr,
|
||||||
@ -301,15 +328,21 @@ void isr_gmac(void)
|
|||||||
{
|
{
|
||||||
uint32_t isr;
|
uint32_t isr;
|
||||||
uint32_t rsr;
|
uint32_t rsr;
|
||||||
|
netdev_t* netdev = _sam0_eth_dev.netdev;
|
||||||
|
|
||||||
isr = GMAC->ISR.reg;
|
isr = GMAC->ISR.reg;
|
||||||
rsr = GMAC->RSR.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 */
|
/* New frame received, signal it to netdev */
|
||||||
if (rsr & GMAC_RSR_REC) {
|
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
|
/* Buffers Not Available, this can occur if there is a heavy traffic
|
||||||
on the network. In this case, disable the GMAC reception, flush
|
on the network. In this case, disable the GMAC reception, flush
|
||||||
our internal buffers and re-enable the reception. This will drop
|
our internal buffers and re-enable the reception. This will drop
|
||||||
|
Loading…
Reference in New Issue
Block a user