drivers: eth_mcux: adding i.mx-rt support
Enables Networking hardware on i.MX-RT type drivers. Reuses the same eth_mcux driver used by Kinetis family; initialization sequence refactored to work with this board as well. Unlike Kinetis family, i.MX has a single ENET interrupt and we need to discriminate between interrupts using a status register. Signed-off-by: Andrei Gansari <andrei.gansari@nxp.com>
This commit is contained in:
parent
3aa59a6eed
commit
35ba3aadc4
2 changed files with 77 additions and 2 deletions
|
@ -33,7 +33,6 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
|||
|
||||
#include "fsl_enet.h"
|
||||
#include "fsl_phy.h"
|
||||
#include "fsl_port.h"
|
||||
|
||||
enum eth_mcux_phy_state {
|
||||
eth_mcux_phy_state_initial,
|
||||
|
@ -194,6 +193,7 @@ static void eth_mcux_phy_enter_reset(struct eth_context *context)
|
|||
|
||||
static void eth_mcux_phy_start(struct eth_context *context)
|
||||
{
|
||||
const u32_t phy_addr = 0;
|
||||
#ifdef CONFIG_ETH_MCUX_PHY_EXTRA_DEBUG
|
||||
LOG_DBG("phy_state=%s", phy_state_name(context->phy_state));
|
||||
#endif
|
||||
|
@ -203,9 +203,15 @@ static void eth_mcux_phy_start(struct eth_context *context)
|
|||
switch (context->phy_state) {
|
||||
case eth_mcux_phy_state_initial:
|
||||
ENET_ActiveRead(ENET);
|
||||
eth_mcux_phy_enter_reset(context);
|
||||
/* Reset the PHY. */
|
||||
ENET_StartSMIWrite(ENET, phy_addr, PHY_BASICCONTROL_REG,
|
||||
kENET_MiiWriteValidFrame,
|
||||
PHY_BCTL_RESET_MASK);
|
||||
context->phy_state = eth_mcux_phy_state_initial;
|
||||
break;
|
||||
case eth_mcux_phy_state_reset:
|
||||
eth_mcux_phy_enter_reset(context);
|
||||
break;
|
||||
case eth_mcux_phy_state_autoneg:
|
||||
case eth_mcux_phy_state_restart:
|
||||
case eth_mcux_phy_state_read_status:
|
||||
|
@ -260,6 +266,13 @@ static void eth_mcux_phy_event(struct eth_context *context)
|
|||
#endif
|
||||
switch (context->phy_state) {
|
||||
case eth_mcux_phy_state_initial:
|
||||
#ifdef CONFIG_SOC_SERIES_IMX_RT
|
||||
ENET_StartSMIRead(ENET, phy_addr, PHY_CONTROL2_REG,
|
||||
kENET_MiiReadValidFrame);
|
||||
ENET_StartSMIWrite(ENET, phy_addr, PHY_CONTROL2_REG,
|
||||
kENET_MiiWriteValidFrame, PHY_CTL2_REFCLK_SELECT_MASK);
|
||||
context->phy_state = eth_mcux_phy_state_reset;
|
||||
#endif
|
||||
break;
|
||||
case eth_mcux_phy_state_closing:
|
||||
if (context->enabled) {
|
||||
|
@ -754,7 +767,12 @@ static void generate_mac(u8_t *mac_addr)
|
|||
static void generate_mac(u8_t *mac_addr)
|
||||
{
|
||||
/* Trivially "hash" up to 128 bits of MCU unique identifier */
|
||||
#ifdef CONFIG_SOC_SERIES_IMX_RT
|
||||
u32_t id = OCOTP->CFG1 ^ OCOTP->CFG2;
|
||||
#endif
|
||||
#ifdef CONFIG_SOC_SERIES_KINETIS_K6X
|
||||
u32_t id = SIM->UIDH ^ SIM->UIDMH ^ SIM->UIDML ^ SIM->UIDL;
|
||||
#endif
|
||||
|
||||
mac_addr[3] = id >> 8;
|
||||
mac_addr[4] = id >> 16;
|
||||
|
@ -931,6 +949,30 @@ static void eth_mcux_ptp_isr(void *p)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(ETH_IRQ_COMMON)
|
||||
static void eth_mcux_dispacher_isr(void *p)
|
||||
{
|
||||
struct device *dev = p;
|
||||
struct eth_context *context = dev->driver_data;
|
||||
u32_t EIR = ENET_GetInterruptStatus(ENET);
|
||||
int irq_lock_key = irq_lock();
|
||||
|
||||
if (EIR & (kENET_RxBufferInterrupt | kENET_RxFrameInterrupt)) {
|
||||
ENET_ReceiveIRQHandler(ENET, &context->enet_handle);
|
||||
} else if (EIR & (kENET_TxBufferInterrupt | kENET_TxFrameInterrupt)) {
|
||||
ENET_TransmitIRQHandler(ENET, &context->enet_handle);
|
||||
} else if (EIR & ENET_EIR_MII_MASK) {
|
||||
k_work_submit(&context->phy_work);
|
||||
ENET_ClearInterruptStatus(ENET, kENET_MiiInterrupt);
|
||||
} else if (EIR) {
|
||||
ENET_ClearInterruptStatus(ENET, 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
irq_unlock(irq_lock_key);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(ETH_IRQ_RX)
|
||||
static void eth_mcux_rx_isr(void *p)
|
||||
{
|
||||
struct device *dev = p;
|
||||
|
@ -938,7 +980,9 @@ static void eth_mcux_rx_isr(void *p)
|
|||
|
||||
ENET_ReceiveIRQHandler(ENET, &context->enet_handle);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(ETH_IRQ_TX)
|
||||
static void eth_mcux_tx_isr(void *p)
|
||||
{
|
||||
struct device *dev = p;
|
||||
|
@ -946,7 +990,9 @@ static void eth_mcux_tx_isr(void *p)
|
|||
|
||||
ENET_TransmitIRQHandler(ENET, &context->enet_handle);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(ETH_IRQ_ERR_MISC)
|
||||
static void eth_mcux_error_isr(void *p)
|
||||
{
|
||||
struct device *dev = p;
|
||||
|
@ -958,6 +1004,7 @@ static void eth_mcux_error_isr(void *p)
|
|||
ENET_ClearInterruptStatus(ENET, kENET_MiiInterrupt);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct eth_context eth_0_context = {
|
||||
.phy_duplex = kPHY_FullDuplex,
|
||||
|
@ -981,17 +1028,29 @@ ETH_NET_DEVICE_INIT(eth_mcux_0, DT_ETH_MCUX_0_NAME, eth_0_init,
|
|||
|
||||
static void eth_0_config_func(void)
|
||||
{
|
||||
#if defined(ETH_IRQ_RX)
|
||||
IRQ_CONNECT(DT_IRQ_ETH_RX, DT_ETH_MCUX_0_IRQ_PRI,
|
||||
eth_mcux_rx_isr, DEVICE_GET(eth_mcux_0), 0);
|
||||
irq_enable(DT_IRQ_ETH_RX);
|
||||
#endif
|
||||
|
||||
#if defined(ETH_IRQ_TX)
|
||||
IRQ_CONNECT(DT_IRQ_ETH_TX, DT_ETH_MCUX_0_IRQ_PRI,
|
||||
eth_mcux_tx_isr, DEVICE_GET(eth_mcux_0), 0);
|
||||
irq_enable(DT_IRQ_ETH_TX);
|
||||
#endif
|
||||
|
||||
#if defined(ETH_IRQ_ERR_MISC)
|
||||
IRQ_CONNECT(DT_IRQ_ETH_ERR_MISC, DT_ETH_MCUX_0_IRQ_PRI,
|
||||
eth_mcux_error_isr, DEVICE_GET(eth_mcux_0), 0);
|
||||
irq_enable(DT_IRQ_ETH_ERR_MISC);
|
||||
#endif
|
||||
|
||||
#if defined(ETH_IRQ_COMMON)
|
||||
IRQ_CONNECT(DT_IRQ_ETH_COMMON, DT_ETH_MCUX_0_IRQ_PRI,
|
||||
eth_mcux_dispacher_isr, DEVICE_GET(eth_mcux_0), 0);
|
||||
irq_enable(DT_IRQ_ETH_COMMON);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_PTP_CLOCK_MCUX)
|
||||
IRQ_CONNECT(DT_IRQ_ETH_IEEE1588_TMR, DT_ETH_MCUX_0_IRQ_PRI,
|
||||
|
|
|
@ -234,6 +234,22 @@
|
|||
label = "UART_8";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
eth: ethernet@402d8000 {
|
||||
compatible = "nxp,kinetis-ethernet";
|
||||
reg = <0x402D8000 0x628>;
|
||||
interrupts = <114 0>;
|
||||
interrupts-names = "COMMON";
|
||||
status = "disabled";
|
||||
local-mac-address = [00 00 00 00 00 00];
|
||||
label = "ETH_0";
|
||||
ptp {
|
||||
compatible = "nxp,kinetis-ptp";
|
||||
status = "disabled";
|
||||
interrupts = <115 0>;
|
||||
interrupts-names = "IEEE1588_TMR";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue