drivers: ethernet: litex: use tx interrupt
use tx interrupt to check, if we can send something, instead of checking the register periodically. Signed-off-by: Fin Maaß <f.maass@vogl-electronic.com>
This commit is contained in:
parent
e1d2f09898
commit
86a52d9254
1 changed files with 19 additions and 15 deletions
|
@ -27,7 +27,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
||||||
|
|
||||||
#include "eth.h"
|
#include "eth.h"
|
||||||
|
|
||||||
#define MAX_TX_FAILURE 100
|
#define MAX_TX_FAILURE K_MSEC(100)
|
||||||
|
|
||||||
#define ETH_LITEX_SLOT_SIZE 0x0800
|
#define ETH_LITEX_SLOT_SIZE 0x0800
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@ struct eth_litex_dev_data {
|
||||||
uint8_t mac_addr[6];
|
uint8_t mac_addr[6];
|
||||||
uint8_t txslot;
|
uint8_t txslot;
|
||||||
struct k_mutex tx_mutex;
|
struct k_mutex tx_mutex;
|
||||||
|
struct k_sem sem_tx_ready;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct eth_litex_config {
|
struct eth_litex_config {
|
||||||
|
@ -64,12 +65,10 @@ static int eth_initialize(const struct device *dev)
|
||||||
struct eth_litex_dev_data *context = dev->data;
|
struct eth_litex_dev_data *context = dev->data;
|
||||||
|
|
||||||
k_mutex_init(&context->tx_mutex);
|
k_mutex_init(&context->tx_mutex);
|
||||||
|
k_sem_init(&context->sem_tx_ready, 1, 1);
|
||||||
|
|
||||||
config->config_func(dev);
|
config->config_func(dev);
|
||||||
|
|
||||||
/* TX event is disabled because it isn't used by this driver */
|
|
||||||
litex_write8(0, config->tx_ev_enable_addr);
|
|
||||||
|
|
||||||
if (config->random_mac_address) {
|
if (config->random_mac_address) {
|
||||||
/* generate random MAC address */
|
/* generate random MAC address */
|
||||||
gen_random_mac(context->mac_addr, 0x10, 0xe2, 0xd5);
|
gen_random_mac(context->mac_addr, 0x10, 0xe2, 0xd5);
|
||||||
|
@ -83,7 +82,7 @@ static int eth_tx(const struct device *dev, struct net_pkt *pkt)
|
||||||
uint16_t len;
|
uint16_t len;
|
||||||
struct eth_litex_dev_data *context = dev->data;
|
struct eth_litex_dev_data *context = dev->data;
|
||||||
const struct eth_litex_config *config = dev->config;
|
const struct eth_litex_config *config = dev->config;
|
||||||
int attempts = 0;
|
int ret;
|
||||||
|
|
||||||
k_mutex_lock(&context->tx_mutex, K_FOREVER);
|
k_mutex_lock(&context->tx_mutex, K_FOREVER);
|
||||||
|
|
||||||
|
@ -97,13 +96,10 @@ static int eth_tx(const struct device *dev, struct net_pkt *pkt)
|
||||||
litex_write16(len, config->tx_length_addr);
|
litex_write16(len, config->tx_length_addr);
|
||||||
|
|
||||||
/* wait for the device to be ready to transmit */
|
/* wait for the device to be ready to transmit */
|
||||||
while (litex_read8(config->tx_ready_addr) == 0) {
|
ret = k_sem_take(&context->sem_tx_ready, MAX_TX_FAILURE);
|
||||||
if (attempts++ == MAX_TX_FAILURE) {
|
if (ret < 0) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
};
|
||||||
k_sleep(K_MSEC(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* start transmitting */
|
/* start transmitting */
|
||||||
litex_write8(1, config->tx_start_addr);
|
litex_write8(1, config->tx_start_addr);
|
||||||
|
|
||||||
|
@ -166,12 +162,13 @@ static void eth_rx(const struct device *port)
|
||||||
|
|
||||||
static void eth_irq_handler(const struct device *port)
|
static void eth_irq_handler(const struct device *port)
|
||||||
{
|
{
|
||||||
|
struct eth_litex_dev_data *context = port->data;
|
||||||
const struct eth_litex_config *config = port->config;
|
const struct eth_litex_config *config = port->config;
|
||||||
/* check sram reader events (tx) */
|
/* check sram reader events (tx) */
|
||||||
if (litex_read8(config->tx_ev_pending_addr) & BIT(0)) {
|
if (litex_read8(config->tx_ev_pending_addr) & BIT(0)) {
|
||||||
/* TX event is not enabled nor used by this driver; ack just
|
k_sem_give(&context->sem_tx_ready);
|
||||||
* in case if some rogue TX event appeared
|
|
||||||
*/
|
/* ack reader irq */
|
||||||
litex_write8(BIT(0), config->tx_ev_pending_addr);
|
litex_write8(BIT(0), config->tx_ev_pending_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,8 +202,14 @@ static int eth_set_config(const struct device *dev, enum ethernet_config_type ty
|
||||||
|
|
||||||
static int eth_start(const struct device *dev)
|
static int eth_start(const struct device *dev)
|
||||||
{
|
{
|
||||||
|
struct eth_litex_dev_data *context = dev->data;
|
||||||
const struct eth_litex_config *config = dev->config;
|
const struct eth_litex_config *config = dev->config;
|
||||||
|
|
||||||
|
if (litex_read8(config->tx_ready_addr)) {
|
||||||
|
k_sem_give(&context->sem_tx_ready);
|
||||||
|
}
|
||||||
|
|
||||||
|
litex_write8(1, config->tx_ev_enable_addr);
|
||||||
litex_write8(1, config->rx_ev_enable_addr);
|
litex_write8(1, config->rx_ev_enable_addr);
|
||||||
|
|
||||||
litex_write8(BIT(0), config->tx_ev_pending_addr);
|
litex_write8(BIT(0), config->tx_ev_pending_addr);
|
||||||
|
@ -219,6 +222,7 @@ static int eth_stop(const struct device *dev)
|
||||||
{
|
{
|
||||||
const struct eth_litex_config *config = dev->config;
|
const struct eth_litex_config *config = dev->config;
|
||||||
|
|
||||||
|
litex_write8(0, config->tx_ev_enable_addr);
|
||||||
litex_write8(0, config->rx_ev_enable_addr);
|
litex_write8(0, config->rx_ev_enable_addr);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue