From a6388b8843a8104d71b06239834c00e57af209d1 Mon Sep 17 00:00:00 2001 From: Jukka Laitinen Date: Thu, 31 Aug 2023 14:38:50 +0300 Subject: [PATCH] arch/risc-v/src/mpfs: Add ksz9477 initialization This adds initialization of the ksz9477 switch when used instead of a PHY, directly connected to SGMII Signed-off-by: Jukka Laitinen --- arch/risc-v/src/mpfs/Kconfig | 31 +++++++++++ arch/risc-v/src/mpfs/mpfs_ethernet.c | 78 ++++++++++++++++++++++++---- 2 files changed, 100 insertions(+), 9 deletions(-) diff --git a/arch/risc-v/src/mpfs/Kconfig b/arch/risc-v/src/mpfs/Kconfig index 534c1adba9..dccbbec883 100644 --- a/arch/risc-v/src/mpfs/Kconfig +++ b/arch/risc-v/src/mpfs/Kconfig @@ -652,6 +652,8 @@ config MPFS_MAC_NO_BROADCAST config MPFS_MAC_AUTONEG bool "Use autonegotiation" + depends on !MPFS_ETH0_PHY_KSZ9477 + depends on !MPFS_ETH1_PHY_KSZ9477 default y ---help--- Use PHY autonegotiation to determine speed and mode @@ -670,6 +672,34 @@ config MPFS_PHYINIT ---help--- call mpfs_phy_boardinitialize() on init +config MPFS_ETH0_PHY_KSZ9477 + bool "Use ksz9477 switch as an SGMII PHY for ETH0" + default n + select NET_KSZ9477 + ---help--- + Select to use ksz9477 connected to SGMII + +config MPFS_ETH1_PHY_KSZ9477 + bool "Use ksz9477 switch as an SGMII PHY for ETH1" + default n + select NET_KSZ9477 + ---help--- + Select to use ksz9477 connected to SGMII + +config MPFS_ETH0_PHY_KSZ9477_I2C_BUS + int "Management I2C bus number for ksz9477 switch" + depends on MPFS_ETH0_PHY_KSZ9477 + default 5 + ---help--- + The i2c port number for switch management + +config MPFS_ETH1_PHY_KSZ9477_I2C_BUS + int "Management I2C bus number for ksz9477 switch" + depends on MPFS_ETH1_PHY_KSZ9477 + default 5 + ---help--- + The i2c port number for switch management + if !MPFS_MAC_AUTONEG config MPFS_MAC_ETHFD @@ -681,6 +711,7 @@ config MPFS_MAC_ETHFD choice prompt "MAC Speed" + default MPFS_MAC_ETH1000MBPS if MPFS_ETH0_PHY_KSZ9477 || MPFS_ETH1_PHY_KSZ9477 default MPFS_MAC_ETH100MBPS ---help--- If autonegotiation is not used, then you must select the fixed speed diff --git a/arch/risc-v/src/mpfs/mpfs_ethernet.c b/arch/risc-v/src/mpfs/mpfs_ethernet.c index 816f6d8c62..1587803bee 100644 --- a/arch/risc-v/src/mpfs/mpfs_ethernet.c +++ b/arch/risc-v/src/mpfs/mpfs_ethernet.c @@ -50,10 +50,31 @@ # include #endif +#include + #include "riscv_internal.h" #include "mpfs_memorymap.h" #include "mpfs_ethernet.h" #include "mpfs_dsn.h" +#include "mpfs_i2c.h" + +#if defined(CONFIG_MPFS_ETH0_PHY_KSZ9477) ||\ + defined(CONFIG_MPFS_ETH1_PHY_KSZ9477) +# if !defined(CONFIG_MPFS_MAC_SGMII) +# error Using KSZ9477 as a PHY requires CONFIG_MPFS_MAC_SGMII to be set +# endif + +# define ETH_HAS_KSZ_SWITCH + +# ifdef CONFIG_MPFS_ETH0_PHY_KSZ9477 +# define ETH_PHY_KSZ9477_I2C_BUS CONFIG_MPFS_ETH0_PHY_KSZ9477_I2C_BUS +# else +# define ETH_PHY_KSZ9477_I2C_BUS CONFIG_MPFS_ETH1_PHY_KSZ9477_I2C_BUS +# endif + +#else +# define ETH_HAS_MDIO_PHY +#endif #if defined(CONFIG_NET) && defined(CONFIG_MPFS_ETHMAC) @@ -90,7 +111,7 @@ # endif #endif -#ifndef CONFIG_MPFS_PHYADDR +#if defined(ETH_HAS_MDIO_PHY) && !defined(CONFIG_MPFS_PHYADDR) # error "CONFIG_MPFS_PHYADDR must be defined in the NuttX configuration" #endif @@ -249,7 +270,9 @@ struct mpfs_ethmac_s irq_t mac_q_int[MPFS_MAC_QUEUE_COUNT]; /* irq numbers */ uint8_t ifup : 1; /* true:ifup false:ifdown */ uint8_t intf; /* Ethernet interface number */ +#ifdef ETH_HAS_MDIO_PHY uint8_t phyaddr; /* PHY address */ +#endif struct wdog_s txtimeout; /* TX timeout timer */ struct work_s irqwork; /* For deferring interrupt work to the work queue */ struct work_s pollwork; /* For deferring poll work to the work queue */ @@ -333,10 +356,13 @@ static int mpfs_ioctl(struct net_driver_s *dev, int cmd, unsigned long arg); /* PHY Initialization */ +static int mpfs_phyinit(struct mpfs_ethmac_s *priv); + +#ifdef ETH_HAS_MDIO_PHY + static void mpfs_enablemdio(struct mpfs_ethmac_s *priv); static void mpfs_disablemdio(struct mpfs_ethmac_s *priv); static int mpfs_phyreset(struct mpfs_ethmac_s *priv); -static int mpfs_phyinit(struct mpfs_ethmac_s *priv); static int mpfs_phyread(struct mpfs_ethmac_s *priv, uint8_t phyaddr, uint8_t regaddr, uint16_t *phyval); static int mpfs_phywrite(struct mpfs_ethmac_s *priv, uint8_t phyaddr, @@ -345,16 +371,21 @@ static int mpfs_phywait(struct mpfs_ethmac_s *priv); static int mpfs_phyfind(struct mpfs_ethmac_s *priv, uint8_t *phyaddr); #ifdef CONFIG_MPFS_MAC_AUTONEG static int mpfs_autonegotiate(struct mpfs_ethmac_s *priv); -#else -static void mpfs_linkspeed(struct mpfs_ethmac_s *priv); #endif -#if defined(CONFIG_DEBUG_NET) && defined(CONFIG_DEBUG_INFO) +#endif /* ETH_HAS_MDIO_PHY */ + +#if defined(CONFIG_DEBUG_NET) && defined(CONFIG_DEBUG_INFO) && \ + defined(ETH_HAS_MDIO_PHY) static void mpfs_phydump(struct mpfs_ethmac_s *priv); #else # define mpfs_phydump(priv) #endif +#ifndef CONFIG_MPFS_MAC_AUTONEG +static void mpfs_linkspeed(struct mpfs_ethmac_s *priv); +#endif + /* MAC/DMA Initialization */ static void mpfs_txreset(struct mpfs_ethmac_s *priv); @@ -1848,6 +1879,8 @@ static int mpfs_rmmac(struct net_driver_s *dev, const uint8_t *mac) } #endif +#ifdef ETH_HAS_MDIO_PHY + /**************************************************************************** * Function: mpfs_enablemdio * @@ -2478,6 +2511,8 @@ errout: } #endif +#endif /* ETH_HAS_MDIO_PHY */ + /**************************************************************************** * Function: mpfs_linkspeed * @@ -2493,7 +2528,7 @@ errout: * ****************************************************************************/ -#ifndef CONFIG_MPFS_MAC_AUTONEG +#if !defined(CONFIG_MPFS_MAC_AUTONEG) || !defined(ETH_HAS_MDIO_PHY) static void mpfs_linkspeed(struct mpfs_ethmac_s *priv) { uint32_t regval; @@ -2569,7 +2604,7 @@ static void mpfs_linkspeed(struct mpfs_ethmac_s *priv) #ifdef CONFIG_NETDEV_IOCTL static int mpfs_ioctl(struct net_driver_s *dev, int cmd, unsigned long arg) { -#ifdef CONFIG_NETDEV_PHY_IOCTL +#if defined(CONFIG_NETDEV_PHY_IOCTL) && defined(ETH_HAS_MDIO_PHY) struct mpfs_ethmac_s *priv = (struct mpfs_ethmac_s *)dev->d_private; #endif int ret; @@ -2577,6 +2612,7 @@ static int mpfs_ioctl(struct net_driver_s *dev, int cmd, unsigned long arg) switch (cmd) { #ifdef CONFIG_NETDEV_PHY_IOCTL +#ifdef ETH_HAS_MDIO_PHY #ifdef CONFIG_ARCH_PHY_INTERRUPT case SIOCMIINOTIFY: /* Set up for PHY event notifications */ { @@ -2640,6 +2676,7 @@ static int mpfs_ioctl(struct net_driver_s *dev, int cmd, unsigned long arg) mpfs_disablemdio(priv); } break; +#endif /* ETH_HAS_MDIO_PHY */ #endif /* CONFIG_NETDEV_PHY_IOCTL */ default: @@ -3214,6 +3251,8 @@ static int mpfs_macenable(struct mpfs_ethmac_s *priv) * ****************************************************************************/ +#ifdef ETH_HAS_MDIO_PHY + static void mpfs_mdcclock(struct mpfs_ethmac_s *priv) { uint32_t ncfgr; @@ -3268,6 +3307,8 @@ static void mpfs_mdcclock(struct mpfs_ethmac_s *priv) mac_putreg(priv, NETWORK_CONTROL, ncr); } +#endif + /**************************************************************************** * Function: mpfs_phyinit * @@ -3284,7 +3325,9 @@ static void mpfs_mdcclock(struct mpfs_ethmac_s *priv) static int mpfs_phyinit(struct mpfs_ethmac_s *priv) { - int ret; + int ret = -EINVAL; + +#ifdef ETH_HAS_MDIO_PHY /* Configure PHY clocking */ @@ -3303,7 +3346,20 @@ static int mpfs_phyinit(struct mpfs_ethmac_s *priv) /* We have a PHY address. Reset the PHY */ mpfs_phyreset(priv); - return OK; + +#elif defined(ETH_HAS_KSZ_SWITCH) + struct i2c_master_s *bus; + + bus = mpfs_i2cbus_initialize(ETH_PHY_KSZ9477_I2C_BUS); + + if (bus) + { + ret = ksz9477_i2c_init(bus, KSZ9477_PORT_SGMII); + } + +#endif + + return ret; } /**************************************************************************** @@ -3322,6 +3378,8 @@ static int mpfs_phyinit(struct mpfs_ethmac_s *priv) * ****************************************************************************/ +#ifdef ETH_HAS_MDIO_PHY + static int mpfs_phyreset(struct mpfs_ethmac_s *priv) { uint16_t mcr; @@ -3391,6 +3449,8 @@ static int mpfs_phyreset(struct mpfs_ethmac_s *priv) return ret; } +#endif + /**************************************************************************** * Function: mpfs_ethconfig *