arch: imx6: Apply the latest imxrt/imxrt_enet.c to imx6/imx_enet.c

Summary:
- Since imx_enet.c is based on imxrt_enet.c and still under debugging,
  the differences should be minimum to keep tracking the changes

Impact:
- None

Testing:
- Tested with sabre-6quad:netnsh with QEMU

Signed-off-by: Masayuki Ishikawa <Masayuki.Ishikawa@jp.sony.com>
This commit is contained in:
Masayuki Ishikawa 2021-01-28 15:54:44 +09:00 committed by Xiang Xiao
parent 0f2b774dec
commit 977367ce04

View File

@ -24,6 +24,7 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#include <inttypes.h>
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <unistd.h> #include <unistd.h>
@ -108,6 +109,27 @@
#define NENET_NBUFFERS \ #define NENET_NBUFFERS \
(CONFIG_IMX_ENET_NTXBUFFERS + CONFIG_IMX_ENET_NRXBUFFERS) (CONFIG_IMX_ENET_NTXBUFFERS + CONFIG_IMX_ENET_NRXBUFFERS)
/* Normally you would clean the cache after writing new values to the DMA
* memory so assure that the dirty cache lines are flushed to memory
* before the DMA occurs. And you would invalid the cache after a data is
* received via DMA so that you fetch the actual content of the data from
* the cache.
*
* These conditions are not fully supported here. If the write-throuch
* D-Cache is enabled, however, then many of these issues go away: The
* cache clean operation does nothing (because there are not dirty cache
* lines) and the cache invalid operation is innocuous (because there are
* never dirty cache lines to be lost; valid data will always be reloaded).
*
* At present, we simply insist that write through cache be enabled.
*/
#if 0
#if defined(CONFIG_ARMV7M_DCACHE) && !defined(CONFIG_ARMV7M_DCACHE_WRITETHROUGH)
# error Write back D-Cache not yet supported
#endif
#endif
/* TX poll delay = 1 seconds. CLK_TCK is the number of clock ticks per /* TX poll delay = 1 seconds. CLK_TCK is the number of clock ticks per
* second. * second.
*/ */
@ -155,6 +177,11 @@
* 7. BOARD_PHY_ISDUPLEX: A macro that can convert the status register * 7. BOARD_PHY_ISDUPLEX: A macro that can convert the status register
* value into a boolean: true=duplex mode, false=half-duplex mode * value into a boolean: true=duplex mode, false=half-duplex mode
* *
* The imxrt1050-evk board uses a KSZ8081 PHY
* The Versiboard2 uses a LAN8720 PHY
* The Teensy-4.1 board uses a DP83825I PHY
*
* ...and further PHY descriptions here.
*/ */
/* TODO: /* TODO:
@ -180,6 +207,15 @@
# define BOARD_PHY_10BASET(s) (((s)&MII_LAN8720_SPSCR_10MBPS) != 0) # define BOARD_PHY_10BASET(s) (((s)&MII_LAN8720_SPSCR_10MBPS) != 0)
# define BOARD_PHY_100BASET(s) (((s)&MII_LAN8720_SPSCR_100MBPS) != 0) # define BOARD_PHY_100BASET(s) (((s)&MII_LAN8720_SPSCR_100MBPS) != 0)
# define BOARD_PHY_ISDUPLEX(s) (((s)&MII_LAN8720_SPSCR_DUPLEX) != 0) # define BOARD_PHY_ISDUPLEX(s) (((s)&MII_LAN8720_SPSCR_DUPLEX) != 0)
#elif defined(CONFIG_ETH0_PHY_DP83825I)
# define BOARD_PHY_NAME "DP83825I"
# define BOARD_PHYID1 MII_PHYID1_DP83825I
# define BOARD_PHYID2 MII_PHYID2_DP83825I
# define BOARD_PHY_STATUS MII_DP83825I_PHYSTS
# define BOARD_PHY_ADDR (0)
# define BOARD_PHY_10BASET(s) (((s) & MII_DP83825I_PHYSTS_SPEED) != 0)
# define BOARD_PHY_100BASET(s) (((s) & MII_DP83825I_PHYSTS_SPEED) == 0)
# define BOARD_PHY_ISDUPLEX(s) (((s) & MII_DP83825I_PHYSTS_DUPLEX) != 0)
#else #else
# error "Unrecognized or missing PHY selection" # error "Unrecognized or missing PHY selection"
#endif #endif
@ -361,6 +397,52 @@ static void imx_reset(struct imx_driver_s *priv);
* Private Functions * Private Functions
****************************************************************************/ ****************************************************************************/
/****************************************************************************
* Function: imx_swap16/32
*
* Description:
* The descriptors are represented by structures Unfortunately, when the
* structures are overlaid on the data, the bytes are reversed because
* the underlying hardware writes the data in big-endian byte order.
*
* Input Parameters:
* value - The value to be byte swapped
*
* Returned Value:
* The byte swapped value
*
****************************************************************************/
#if 0 /* Use builtins if the compiler supports them */
#ifndef CONFIG_ENDIAN_BIG
static inline uint32_t imx_swap32(uint32_t value)
{
uint32_t result = 0;
__asm__ __volatile__
(
"rev %0, %1"
:"=r" (result)
: "r"(value)
);
return result;
}
static inline uint16_t imx_swap16(uint16_t value)
{
uint16_t result = 0;
__asm__ __volatile__
(
"revsh %0, %1"
:"=r" (result)
: "r"(value)
);
return result;
}
#endif
#endif
/**************************************************************************** /****************************************************************************
* Function: imx_txringfull * Function: imx_txringfull
* *
@ -615,7 +697,7 @@ static inline void imx_dispatch(FAR struct imx_driver_s *priv)
NETDEV_RXPACKETS(&priv->dev); NETDEV_RXPACKETS(&priv->dev);
#ifdef CONFIG_NET_PKT #ifdef CONFIG_NET_PKT
/* When packet sockets are enabled, feed the frame into the packet tap */ /* When packet sockets are enabled, feed the frame into the tap */
pkt_input(&priv->dev); pkt_input(&priv->dev);
#endif #endif
@ -636,7 +718,7 @@ static inline void imx_dispatch(FAR struct imx_driver_s *priv)
ipv4_input(&priv->dev); ipv4_input(&priv->dev);
/* If the above function invocation resulted in data that should be /* If the above function invocation resulted in data that should be
* sent out on the network, the field d_len will set to a value > 0. * sent out on the network, d_len field will set to a value > 0.
*/ */
if (priv->dev.d_len > 0) if (priv->dev.d_len > 0)
@ -668,7 +750,7 @@ static inline void imx_dispatch(FAR struct imx_driver_s *priv)
if (BUF->type == HTONS(ETHTYPE_IP6)) if (BUF->type == HTONS(ETHTYPE_IP6))
{ {
ninfo("Iv6 frame\n"); ninfo("IPv6 frame\n");
NETDEV_RXIPV6(&priv->dev); NETDEV_RXIPV6(&priv->dev);
/* Give the IPv6 packet to the network layer */ /* Give the IPv6 packet to the network layer */
@ -676,7 +758,7 @@ static inline void imx_dispatch(FAR struct imx_driver_s *priv)
ipv6_input(&priv->dev); ipv6_input(&priv->dev);
/* If the above function invocation resulted in data that should be /* If the above function invocation resulted in data that should be
* sent out on the network, the field d_len will set to a value > 0. * sent out on the network, d_len field will set to a value > 0.
*/ */
if (priv->dev.d_len > 0) if (priv->dev.d_len > 0)
@ -945,7 +1027,7 @@ static void imx_enet_interrupt_work(FAR void *arg)
NETDEV_ERRORS(&priv->dev); NETDEV_ERRORS(&priv->dev);
nerr("ERROR: Network interface error occurred (0x%08X)\n", nerr("ERROR: Network interface error occurred (0x%08" PRIX32 ")\n",
(pending & ERROR_INTERRUPTS)); (pending & ERROR_INTERRUPTS));
} }
@ -1020,7 +1102,7 @@ static void imx_enet_interrupt_work(FAR void *arg)
* Function: imx_enet_interrupt * Function: imx_enet_interrupt
* *
* Description: * Description:
* Three interrupt sources will vector this this function: * Three interrupt sources will vector to this function:
* 1. Ethernet MAC transmit interrupt handler * 1. Ethernet MAC transmit interrupt handler
* 2. Ethernet MAC receive interrupt handler * 2. Ethernet MAC receive interrupt handler
* 3. * 3.
@ -1101,8 +1183,7 @@ static void imx_txtimeout_work(FAR void *arg)
* The last TX never completed. Reset the hardware and start again. * The last TX never completed. Reset the hardware and start again.
* *
* Input Parameters: * Input Parameters:
* argc - The number of available arguments * arg - The argument
* arg - The first argument
* *
* Returned Value: * Returned Value:
* None * None
@ -1181,8 +1262,7 @@ static void imx_poll_work(FAR void *arg)
* Periodic timer handler. Called from the timer interrupt handler. * Periodic timer handler. Called from the timer interrupt handler.
* *
* Input Parameters: * Input Parameters:
* argc - The number of available arguments * arg - The argument
* arg - The first argument
* *
* Returned Value: * Returned Value:
* None * None
@ -1231,10 +1311,10 @@ static int imx_ifup_action(struct net_driver_s *dev, bool resetphy)
int ret; int ret;
ninfo("Bringing up: %d.%d.%d.%d\n", ninfo("Bringing up: %d.%d.%d.%d\n",
(int)dev->d_ipaddr & 0xff, (int)(dev->d_ipaddr & 0xff),
(int)(dev->d_ipaddr >> 8) & 0xff, (int)((dev->d_ipaddr >> 8) & 0xff),
(int)(dev->d_ipaddr >> 16) & 0xff, (int)((dev->d_ipaddr >> 16) & 0xff),
(int)dev->d_ipaddr >> 24); (int)(dev->d_ipaddr >> 24));
/* Initialize ENET buffers */ /* Initialize ENET buffers */
@ -2086,6 +2166,13 @@ static inline int imx_initphy(struct imx_driver_s *priv, bool renogphy)
imx_writemii(priv, phyaddr, MII_KSZ8081_PHYCTRL2, imx_writemii(priv, phyaddr, MII_KSZ8081_PHYCTRL2,
(phydata | (1 << 4))); (phydata | (1 << 4)));
imx_writemii(priv, phyaddr, MII_ADVERTISE,
MII_ADVERTISE_100BASETXFULL |
MII_ADVERTISE_100BASETXHALF |
MII_ADVERTISE_10BASETXFULL |
MII_ADVERTISE_10BASETXHALF |
MII_ADVERTISE_CSMA);
#elif defined (CONFIG_ETH0_PHY_LAN8720) #elif defined (CONFIG_ETH0_PHY_LAN8720)
/* Make sure that PHY comes up in correct mode when it's reset */ /* Make sure that PHY comes up in correct mode when it's reset */
@ -2096,6 +2183,25 @@ static inline int imx_initphy(struct imx_driver_s *priv, bool renogphy)
/* ...and reset PHY */ /* ...and reset PHY */
imx_writemii(priv, phyaddr, MII_MCR, MII_MCR_RESET); imx_writemii(priv, phyaddr, MII_MCR, MII_MCR_RESET);
#elif defined (CONFIG_ETH0_PHY_DP83825I)
/* Reset PHY */
imx_writemii(priv, phyaddr, MII_MCR, MII_MCR_RESET);
/* Set RMII mode and Indicate 50MHz clock */
imx_writemii(priv, phyaddr, MII_DP83825I_RCSR,
MII_DP83825I_RCSC_ELAST_2 | MII_DP83825I_RCSC_RMIICS);
imx_writemii(priv, phyaddr, MII_ADVERTISE,
MII_ADVERTISE_100BASETXFULL |
MII_ADVERTISE_100BASETXHALF |
MII_ADVERTISE_10BASETXFULL |
MII_ADVERTISE_10BASETXHALF |
MII_ADVERTISE_CSMA);
#endif #endif
/* Start auto negotiation */ /* Start auto negotiation */