1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-01-18 12:52:44 +01:00

Merge pull request #17886 from benpicco/cpu/sam0_eth-sleep

cpu/sam0_eth: implement SLEEP state
This commit is contained in:
Dylan Laduranty 2022-04-01 09:18:41 +02:00 committed by GitHub
commit c568d273ea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 54 additions and 7 deletions

View File

@ -92,6 +92,8 @@ static uint8_t rx_buf[ETH_RX_BUFFER_COUNT][ETH_RX_BUFFER_SIZE] __attribute__((a
static uint8_t tx_buf[ETH_TX_BUFFER_COUNT][ETH_TX_BUFFER_SIZE] __attribute__((aligned(GMAC_BUF_ALIGNMENT)));
extern sam0_eth_netdev_t _sam0_eth_dev;
static bool _is_sleeping;
/* Flush our reception buffers and reset reception internal mechanism,
this function may be call from ISR context */
void sam0_clear_rx_buffers(void)
@ -104,6 +106,33 @@ void sam0_clear_rx_buffers(void)
GMAC->RBQB.reg = (uint32_t) rx_desc;
}
static void _enable_clock(void)
{
/* Enable GMAC clocks */
MCLK->AHBMASK.reg |= MCLK_AHBMASK_GMAC;
MCLK->APBCMASK.reg |= MCLK_APBCMASK_GMAC;
}
static void _disable_clock(void)
{
/* Disable GMAC clocks */
MCLK->AHBMASK.reg &= ~MCLK_AHBMASK_GMAC;
MCLK->APBCMASK.reg &= ~MCLK_APBCMASK_GMAC;
}
void sam0_eth_poweron(void)
{
_enable_clock();
sam0_clear_rx_buffers();
_is_sleeping = false;
}
void sam0_eth_poweroff(void)
{
_is_sleeping = true;
_disable_clock();
}
static void _init_desc_buf(void)
{
int i;
@ -175,6 +204,10 @@ int sam0_eth_send(const struct iolist *iolist)
unsigned tx_len = 0;
tx_curr = &tx_desc[tx_idx];
if (_is_sleeping) {
return -ENOTSUP;
}
/* load packet data into TX buffer */
for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) {
if (tx_len + iol->iol_len > ETHERNET_MAX_LEN) {
@ -290,13 +323,6 @@ int sam0_eth_receive_blocking(char *data, unsigned max_len)
return _try_receive(data, max_len, 1);
}
static void _enable_clock(void)
{
/* Enable GMAC clocks */
MCLK->AHBMASK.reg |= MCLK_AHBMASK_GMAC;
MCLK->APBCMASK.reg |= MCLK_APBCMASK_GMAC;
}
int sam0_eth_init(void)
{
/* Enable clocks */

View File

@ -36,6 +36,8 @@
/* Internal helpers */
extern int sam0_eth_init(void);
extern void sam0_eth_poweron(void);
extern void sam0_eth_poweroff(void);
extern int sam0_eth_send(const struct iolist *iolist);
extern int sam0_eth_receive_blocking(char *data, unsigned max_len);
extern void sam0_eth_set_mac(const eui48_t *mac);
@ -101,6 +103,22 @@ static int _sam0_eth_get(netdev_t *netdev, netopt_t opt, void *val, size_t max_l
return res;
}
static int _set_state(netopt_state_t state)
{
switch (state) {
case NETOPT_STATE_SLEEP:
sam0_eth_poweroff();
break;
case NETOPT_STATE_IDLE:
sam0_eth_poweron();
break;
default:
return -ENOTSUP;
}
return sizeof(netopt_state_t);
}
static int _sam0_eth_set(netdev_t *netdev, netopt_t opt, const void *val, size_t max_len)
{
int res = -1;
@ -111,6 +129,9 @@ static int _sam0_eth_set(netdev_t *netdev, netopt_t opt, const void *val, size_t
sam0_eth_set_mac((eui48_t *)val);
res = ETHERNET_ADDR_LEN;
break;
case NETOPT_STATE:
assert(max_len <= sizeof(netopt_state_t));
return _set_state(*((const netopt_state_t *)val));
default:
res = netdev_eth_set(netdev, opt, val, max_len);
break;