ethernet: malloc hal together with driver context

This commit is contained in:
suda-morris 2019-07-11 10:47:17 +08:00
parent 606c6c867c
commit af78311975
3 changed files with 39 additions and 44 deletions

View file

@ -46,7 +46,7 @@ static const char *TAG = "emac_esp32";
typedef struct {
esp_eth_mac_t parent;
esp_eth_mediator_t *eth;
emac_hal_context_t *hal;
emac_hal_context_t hal;
intr_handle_t intr_hdl;
SemaphoreHandle_t rx_counting_sem;
TaskHandle_t rx_task_hdl;
@ -72,15 +72,15 @@ static esp_err_t emac_esp32_write_phy_reg(esp_eth_mac_t *mac, uint32_t phy_addr,
{
esp_err_t ret = ESP_OK;
emac_esp32_t *emac = __containerof(mac, emac_esp32_t, parent);
MAC_CHECK(!emac_hal_is_mii_busy(emac->hal), "phy is busy", err, ESP_ERR_INVALID_STATE);
emac_hal_set_phy_data(emac->hal, reg_value);
emac_hal_set_phy_cmd(emac->hal, phy_addr, phy_reg, true);
MAC_CHECK(!emac_hal_is_mii_busy(&emac->hal), "phy is busy", err, ESP_ERR_INVALID_STATE);
emac_hal_set_phy_data(&emac->hal, reg_value);
emac_hal_set_phy_cmd(&emac->hal, phy_addr, phy_reg, true);
/* polling the busy flag */
uint32_t to = 0;
bool busy = true;
do {
ets_delay_us(100);
busy = emac_hal_is_mii_busy(emac->hal);
busy = emac_hal_is_mii_busy(&emac->hal);
to += 100;
} while (busy && to < PHY_OPERATION_TIMEOUT_US);
MAC_CHECK(!busy, "phy is busy", err, ESP_ERR_TIMEOUT);
@ -94,19 +94,19 @@ static esp_err_t emac_esp32_read_phy_reg(esp_eth_mac_t *mac, uint32_t phy_addr,
esp_err_t ret = ESP_OK;
MAC_CHECK(reg_value, "can't set reg_value to null", err, ESP_ERR_INVALID_ARG);
emac_esp32_t *emac = __containerof(mac, emac_esp32_t, parent);
MAC_CHECK(!emac_hal_is_mii_busy(emac->hal), "phy is busy", err, ESP_ERR_INVALID_STATE);
emac_hal_set_phy_cmd(emac->hal, phy_addr, phy_reg, false);
MAC_CHECK(!emac_hal_is_mii_busy(&emac->hal), "phy is busy", err, ESP_ERR_INVALID_STATE);
emac_hal_set_phy_cmd(&emac->hal, phy_addr, phy_reg, false);
/* polling the busy flag */
uint32_t to = 0;
bool busy = true;
do {
ets_delay_us(100);
busy = emac_hal_is_mii_busy(emac->hal);
busy = emac_hal_is_mii_busy(&emac->hal);
to += 100;
} while (busy && to < PHY_OPERATION_TIMEOUT_US);
MAC_CHECK(!busy, "phy is busy", err, ESP_ERR_TIMEOUT);
/* Store value */
*reg_value = emac_hal_get_phy_data(emac->hal);
*reg_value = emac_hal_get_phy_data(&emac->hal);
return ESP_OK;
err:
return ret;
@ -118,7 +118,7 @@ static esp_err_t emac_esp32_set_addr(esp_eth_mac_t *mac, uint8_t *addr)
MAC_CHECK(addr, "can't set mac addr to null", err, ESP_ERR_INVALID_ARG);
emac_esp32_t *emac = __containerof(mac, emac_esp32_t, parent);
memcpy(emac->addr, addr, 6);
emac_hal_set_address(emac->hal, emac->addr);
emac_hal_set_address(&emac->hal, emac->addr);
return ESP_OK;
err:
return ret;
@ -142,11 +142,11 @@ static esp_err_t emac_esp32_set_link(esp_eth_mac_t *mac, eth_link_t link)
switch (link) {
case ETH_LINK_UP:
MAC_CHECK(esp_intr_enable(emac->intr_hdl) == ESP_OK, "enable interrupt failed", err, ESP_FAIL);
emac_hal_start(emac->hal);
emac_hal_start(&emac->hal);
break;
case ETH_LINK_DOWN:
MAC_CHECK(esp_intr_disable(emac->intr_hdl) == ESP_OK, "disable interrupt failed", err, ESP_FAIL);
emac_hal_stop(emac->hal);
emac_hal_stop(&emac->hal);
break;
default:
MAC_CHECK(false, "unknown link status", err, ESP_ERR_INVALID_ARG);
@ -163,10 +163,10 @@ static esp_err_t emac_esp32_set_speed(esp_eth_mac_t *mac, eth_speed_t speed)
emac_esp32_t *emac = __containerof(mac, emac_esp32_t, parent);
switch (speed) {
case ETH_SPEED_10M:
emac_hal_set_speed(emac->hal, EMAC_SPEED_10M);
emac_hal_set_speed(&emac->hal, EMAC_SPEED_10M);
break;
case ETH_SPEED_100M:
emac_hal_set_speed(emac->hal, EMAC_SPEED_100M);
emac_hal_set_speed(&emac->hal, EMAC_SPEED_100M);
break;
default:
MAC_CHECK(false, "unknown speed", err, ESP_ERR_INVALID_ARG);
@ -183,10 +183,10 @@ static esp_err_t emac_esp32_set_duplex(esp_eth_mac_t *mac, eth_duplex_t duplex)
emac_esp32_t *emac = __containerof(mac, emac_esp32_t, parent);
switch (duplex) {
case ETH_DUPLEX_HALF:
emac_hal_set_duplex(emac->hal, EMAC_DUPLEX_HALF);
emac_hal_set_duplex(&emac->hal, EMAC_DUPLEX_HALF);
break;
case ETH_DUPLEX_FULL:
emac_hal_set_duplex(emac->hal, EMAC_DUPLEX_FULL);
emac_hal_set_duplex(&emac->hal, EMAC_DUPLEX_FULL);
break;
default:
MAC_CHECK(false, "unknown duplex", err, ESP_ERR_INVALID_ARG);
@ -200,7 +200,7 @@ err:
static esp_err_t emac_esp32_set_promiscuous(esp_eth_mac_t *mac, bool enable)
{
emac_esp32_t *emac = __containerof(mac, emac_esp32_t, parent);
emac_hal_set_promiscuous(emac->hal, enable);
emac_hal_set_promiscuous(&emac->hal, enable);
return ESP_OK;
}
@ -211,9 +211,9 @@ static esp_err_t emac_esp32_transmit(esp_eth_mac_t *mac, uint8_t *buf, uint32_t
MAC_CHECK(buf, "can't set buf to null", err, ESP_ERR_INVALID_ARG);
MAC_CHECK(length, "buf length can't be zero", err, ESP_ERR_INVALID_ARG);
/* Check if the descriptor is owned by the Ethernet DMA (when 1) or CPU (when 0) */
MAC_CHECK(emac_hal_get_tx_desc_owner(emac->hal) == EMAC_DMADESC_OWNER_CPU,
MAC_CHECK(emac_hal_get_tx_desc_owner(&emac->hal) == EMAC_DMADESC_OWNER_CPU,
"CPU doesn't own the Tx Descriptor", err, ESP_ERR_INVALID_STATE);
emac_hal_transmit_frame(emac->hal, buf, length);
emac_hal_transmit_frame(&emac->hal, buf, length);
return ESP_OK;
err:
return ret;
@ -224,7 +224,7 @@ static esp_err_t emac_esp32_receive(esp_eth_mac_t *mac, uint8_t *buf, uint32_t *
esp_err_t ret = ESP_OK;
emac_esp32_t *emac = __containerof(mac, emac_esp32_t, parent);
MAC_CHECK(buf && length, "can't set buf and length to null", err, ESP_ERR_INVALID_ARG);
*length = emac_hal_receive_frame(emac->hal, buf, &emac->frames_remain);
*length = emac_hal_receive_frame(&emac->hal, buf, &emac->frames_remain);
return ESP_OK;
err:
return ret;
@ -274,7 +274,7 @@ static esp_err_t emac_esp32_init(esp_eth_mac_t *mac)
/* enable peripheral clock */
periph_module_enable(PERIPH_EMAC_MODULE);
/* enable clock, config gpio, etc */
emac_hal_lowlevel_init(emac->hal);
emac_hal_lowlevel_init(&emac->hal);
/* init gpio used by gpio */
emac_esp32_init_smi_gpio();
#if CONFIG_ETH_PHY_USE_RST
@ -284,27 +284,27 @@ static esp_err_t emac_esp32_init(esp_eth_mac_t *mac)
#endif
MAC_CHECK(eth->on_state_changed(eth, ETH_STATE_LLINIT, NULL) == ESP_OK, "lowlevel init failed", err, ESP_FAIL);
/* software reset */
emac_hal_reset(emac->hal);
emac_hal_reset(&emac->hal);
uint32_t to = 0;
for (to = 0; to < emac->sw_reset_timeout_ms / 10; to++) {
if (emac_hal_is_reset_done(emac->hal)) {
if (emac_hal_is_reset_done(&emac->hal)) {
break;
}
vTaskDelay(pdMS_TO_TICKS(10));
}
MAC_CHECK(to < emac->sw_reset_timeout_ms / 10, "reset timeout", err, ESP_ERR_TIMEOUT);
/* set smi clock */
emac_hal_set_csr_clock_range(emac->hal);
emac_hal_set_csr_clock_range(&emac->hal);
/* reset descriptor chain */
emac_hal_reset_desc_chain(emac->hal);
emac_hal_reset_desc_chain(&emac->hal);
/* init mac registers by default */
emac_hal_init_mac_default(emac->hal);
emac_hal_init_mac_default(&emac->hal);
/* init dma registers by default */
emac_hal_init_dma_default(emac->hal);
emac_hal_init_dma_default(&emac->hal);
/* get emac address from efuse */
MAC_CHECK(esp_read_mac(emac->addr, ESP_MAC_ETH) == ESP_OK, "fetch ethernet mac address failed", err, ESP_FAIL);
/* set MAC address to emac register */
emac_hal_set_address(emac->hal, emac->addr);
emac_hal_set_address(&emac->hal, emac->addr);
return ESP_OK;
err:
eth->on_state_changed(eth, ETH_STATE_DEINIT, NULL);
@ -319,7 +319,7 @@ static esp_err_t emac_esp32_deinit(esp_eth_mac_t *mac)
#if CONFIG_ETH_PHY_USE_RST
gpio_set_level(CONFIG_ETH_PHY_RST_GPIO, 0);
#endif
emac_hal_stop(emac->hal);
emac_hal_stop(&emac->hal);
eth->on_state_changed(eth, ETH_STATE_DEINIT, NULL);
periph_module_disable(PERIPH_EMAC_MODULE);
return ESP_OK;
@ -333,13 +333,12 @@ static esp_err_t emac_esp32_del(esp_eth_mac_t *mac)
vSemaphoreDelete(emac->rx_counting_sem);
int i = 0;
for (i = 0; i < CONFIG_ETH_DMA_RX_BUFFER_NUM; i++) {
free(emac->hal->rx_buf[i]);
free(emac->hal.rx_buf[i]);
}
for (i = 0; i < CONFIG_ETH_DMA_TX_BUFFER_NUM; i++) {
free(emac->hal->tx_buf[i]);
free(emac->hal.tx_buf[i]);
}
free(emac->hal->descriptors);
free(emac->hal);
free(emac->hal.descriptors);
free(emac);
return ESP_OK;
}
@ -355,8 +354,6 @@ esp_eth_mac_t *esp_eth_mac_new_esp32(const eth_mac_config_t *config)
CONFIG_ETH_DMA_TX_BUFFER_NUM * sizeof(eth_dma_tx_descriptor_t);
void *descriptors = heap_caps_calloc(1, desc_size, MALLOC_CAP_DMA);
MAC_CHECK(descriptors, "calloc descriptors failed", err_desc, NULL);
emac->hal = (emac_hal_context_t *)calloc(1, sizeof(emac_hal_context_t));
MAC_CHECK(emac->hal, "calloc emac hal failed", err_hal, NULL);
int i = 0;
/* alloc memory for ethernet dma buffer */
for (i = 0; i < CONFIG_ETH_DMA_RX_BUFFER_NUM; i++) {
@ -387,7 +384,7 @@ esp_eth_mac_t *esp_eth_mac_new_esp32(const eth_mac_config_t *config)
goto err_buffer;
}
/* initialize hal layer driver */
emac_hal_init(emac->hal, descriptors, emac->rx_buf, emac->tx_buf);
emac_hal_init(&emac->hal, descriptors, emac->rx_buf, emac->tx_buf);
emac->sw_reset_timeout_ms = config->sw_reset_timeout_ms;
emac->parent.set_mediator = emac_esp32_set_mediator;
emac->parent.init = emac_esp32_init;
@ -427,8 +424,6 @@ err_intr:
free(emac->rx_buf[i]);
}
err_buffer:
free(emac->hal);
err_hal:
free(descriptors);
err_desc:
free(emac);
@ -438,8 +433,8 @@ err:
void emac_hal_rx_complete_cb(void *arg)
{
emac_hal_context_t **hal_addr = (emac_hal_context_t **)arg;
emac_esp32_t *emac = __containerof(hal_addr, emac_esp32_t, hal);
emac_hal_context_t *hal = (emac_hal_context_t *)arg;
emac_esp32_t *emac = __containerof(hal, emac_esp32_t, hal);
BaseType_t high_task_wakeup;
/* send message to rx thread */
xSemaphoreGiveFromISR(emac->rx_counting_sem, &high_task_wakeup);
@ -450,8 +445,8 @@ void emac_hal_rx_complete_cb(void *arg)
void emac_hal_rx_unavail_cb(void *arg)
{
emac_hal_context_t **hal_addr = (emac_hal_context_t **)arg;
emac_esp32_t *emac = __containerof(hal_addr, emac_esp32_t, hal);
emac_hal_context_t *hal = (emac_hal_context_t *)arg;
emac_esp32_t *emac = __containerof(hal, emac_esp32_t, hal);
BaseType_t high_task_wakeup;
/* send message to rx thread */
xSemaphoreGiveFromISR(emac->rx_counting_sem, &high_task_wakeup);

View file

@ -76,7 +76,7 @@ TEST_CASE("esp32 emac io test", "[ethernet][ignore]")
TEST_CASE("ethernet tcpip_adapter", "[ethernet][ignore]")
{
tcpip_adapter_init();
test_case_uses_tcpip();
TEST_ESP_OK(esp_event_loop_create_default());
TEST_ESP_OK(tcpip_adapter_set_default_eth_handlers());
TEST_ESP_OK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, NULL));

View file

@ -521,7 +521,7 @@ uint32_t emac_hal_receive_frame(emac_hal_context_t *hal, uint8_t *buf, uint32_t
void emac_hal_isr(void *arg)
{
emac_hal_context_t *hal = *(emac_hal_context_t **)arg;
emac_hal_context_t *hal = (emac_hal_context_t *)arg;
typeof(hal->dma_regs->dmastatus) dma_status = hal->dma_regs->dmastatus;
/* DMA Normal Interrupt */
if (dma_status.norm_int_summ) {