mirror of
https://github.com/apache/nuttx.git
synced 2026-10-10 07:40:27 +00:00
arch/mips/pic32mz: add PHY ioctls and link interrupts to the Ethernet driver.
The driver had no d_ioctl, so CONFIG_NETDEV_PHY_IOCTL had no effect. Implement SIOCGMIIPHY, SIOCGMIIREG and SIOCSMIIREG and, with CONFIG_ARCH_PHY_INTERRUPT, SIOCMIINOTIFY. SIOCMIINOTIFY subscribes through phy_notify_subscribe() (the board provides arch_phy_irq()) and enables the PHY link down and auto-negotiation complete interrupts. This is what CONFIG_NETINIT_MONITOR needs. The PHY interrupt is implemented for the LAN8720 and LAN8740; add their interrupt source/mask register bits to mii.h. Assisted-by: Claude Code:claude-opus-5-5 Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
This commit is contained in:
parent
ea65363d57
commit
81f3d7443d
2 changed files with 152 additions and 0 deletions
|
|
@ -46,6 +46,10 @@
|
|||
#include <nuttx/net/ip.h>
|
||||
#include <nuttx/net/netdev.h>
|
||||
|
||||
#if defined(CONFIG_NETDEV_PHY_IOCTL) && defined(CONFIG_ARCH_PHY_INTERRUPT)
|
||||
# include <nuttx/net/phy.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_PKT
|
||||
# include <nuttx/net/pkt.h>
|
||||
#endif
|
||||
|
|
@ -284,6 +288,16 @@
|
|||
# undef PIC32MZ_HAVE_PHY
|
||||
#endif
|
||||
|
||||
/* PHY interrupt source/mask registers and the link up/down events */
|
||||
|
||||
#if defined(CONFIG_ETH0_PHY_LAN8720) || defined(CONFIG_ETH0_PHY_LAN8740) || \
|
||||
defined(CONFIG_ETH0_PHY_LAN8740A)
|
||||
# define PIC32MZ_PHY_ISR MII_LAN8720_ISR
|
||||
# define PIC32MZ_PHY_IMR MII_LAN8720_IMR
|
||||
# define PIC32MZ_PHY_INTEN (MII_LAN8720_INT_LINKDOWN | \
|
||||
MII_LAN8720_INT_ANCOMPLETE)
|
||||
#endif
|
||||
|
||||
/* These definitions are used to remember the speed/duplex settings */
|
||||
|
||||
#define PIC32MZ_SPEED_MASK 0x01
|
||||
|
|
@ -471,6 +485,10 @@ static int pic32mz_txavail(struct net_driver_s *dev);
|
|||
static int pic32mz_addmac(struct net_driver_s *dev, const uint8_t *mac);
|
||||
static int pic32mz_rmmac(struct net_driver_s *dev, const uint8_t *mac);
|
||||
#endif
|
||||
#if defined(CONFIG_NETDEV_IOCTL) && defined(PIC32MZ_HAVE_PHY)
|
||||
static int pic32mz_ioctl(struct net_driver_s *dev, int cmd,
|
||||
unsigned long arg);
|
||||
#endif
|
||||
|
||||
/* PHY initialization functions */
|
||||
|
||||
|
|
@ -492,6 +510,9 @@ static inline int pic32mz_phyautoneg(uint8_t phyaddr);
|
|||
static int pic32mz_phymode(uint8_t phyaddr, uint8_t mode);
|
||||
# endif
|
||||
static inline int pic32mz_phyinit(struct pic32mz_driver_s *priv);
|
||||
# if defined(CONFIG_NETDEV_PHY_IOCTL) && defined(CONFIG_ARCH_PHY_INTERRUPT)
|
||||
static int pic32mz_phyintenable(struct pic32mz_driver_s *priv);
|
||||
# endif
|
||||
#else
|
||||
# define pic32mz_phyinit(priv)
|
||||
#endif
|
||||
|
|
@ -2556,6 +2577,94 @@ static int pic32mz_rmmac(struct net_driver_s *dev, const uint8_t *mac)
|
|||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: pic32mz_ioctl
|
||||
*
|
||||
* Description:
|
||||
* Handle network IOCTL commands directed to this device.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - Reference to the NuttX driver state structure
|
||||
* cmd - The IOCTL command
|
||||
* arg - The argument for the IOCTL command
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success; Negated errno on failure.
|
||||
*
|
||||
* Assumptions:
|
||||
* The network device is locked.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_NETDEV_IOCTL) && defined(PIC32MZ_HAVE_PHY)
|
||||
static int pic32mz_ioctl(struct net_driver_s *dev, int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
#ifdef CONFIG_NETDEV_PHY_IOCTL
|
||||
struct pic32mz_driver_s *priv = (struct pic32mz_driver_s *)dev->d_private;
|
||||
#endif
|
||||
int ret;
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
#ifdef CONFIG_NETDEV_PHY_IOCTL
|
||||
#ifdef CONFIG_ARCH_PHY_INTERRUPT
|
||||
case SIOCMIINOTIFY: /* Set up for PHY event notifications */
|
||||
{
|
||||
struct mii_ioctl_notify_s *req =
|
||||
(struct mii_ioctl_notify_s *)((uintptr_t)arg);
|
||||
|
||||
ret = phy_notify_subscribe(dev->d_ifname, req->pid, &req->event);
|
||||
if (ret == OK)
|
||||
{
|
||||
/* Enable PHY link up/down interrupts */
|
||||
|
||||
ret = pic32mz_phyintenable(priv);
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case SIOCGMIIPHY: /* Get MII PHY address */
|
||||
{
|
||||
struct mii_ioctl_data_s *req =
|
||||
(struct mii_ioctl_data_s *)((uintptr_t)arg);
|
||||
|
||||
req->phy_id = priv->pd_phyaddr;
|
||||
ret = OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case SIOCGMIIREG: /* Get register from MII PHY */
|
||||
{
|
||||
struct mii_ioctl_data_s *req =
|
||||
(struct mii_ioctl_data_s *)((uintptr_t)arg);
|
||||
|
||||
req->val_out = pic32mz_phyread(req->phy_id, req->reg_num);
|
||||
ret = OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case SIOCSMIIREG: /* Set register in MII PHY */
|
||||
{
|
||||
struct mii_ioctl_data_s *req =
|
||||
(struct mii_ioctl_data_s *)((uintptr_t)arg);
|
||||
|
||||
pic32mz_phywrite(req->phy_id, req->reg_num, req->val_in);
|
||||
ret = OK;
|
||||
}
|
||||
break;
|
||||
#endif /* CONFIG_NETDEV_PHY_IOCTL */
|
||||
|
||||
default:
|
||||
ret = -ENOTTY;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pic32mz_showmii
|
||||
*
|
||||
|
|
@ -2587,6 +2696,36 @@ static void pic32mz_showmii(uint8_t phyaddr, const char *msg)
|
|||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: pic32mz_phyintenable
|
||||
*
|
||||
* Description:
|
||||
* Enable the PHY link up/down interrupts. Reading the interrupt source
|
||||
* register clears any pending event, so the PHY interrupt output is
|
||||
* released before the new events are enabled.
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - A reference to the private driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success; -ENOSYS if the PHY interrupts are not supported.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(PIC32MZ_HAVE_PHY) && defined(CONFIG_NETDEV_PHY_IOCTL) && \
|
||||
defined(CONFIG_ARCH_PHY_INTERRUPT)
|
||||
static int pic32mz_phyintenable(struct pic32mz_driver_s *priv)
|
||||
{
|
||||
#ifdef PIC32MZ_PHY_INTEN
|
||||
pic32mz_phyread(priv->pd_phyaddr, PIC32MZ_PHY_ISR);
|
||||
pic32mz_phywrite(priv->pd_phyaddr, PIC32MZ_PHY_IMR, PIC32MZ_PHY_INTEN);
|
||||
return OK;
|
||||
#else
|
||||
return -ENOSYS;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: pic32mz_phybusywait
|
||||
*
|
||||
|
|
@ -3395,6 +3534,9 @@ static inline int pic32mz_ethinitialize(int intf)
|
|||
#ifdef CONFIG_NET_MCASTGROUP
|
||||
priv->pd_dev.d_addmac = pic32mz_addmac; /* Add multicast MAC address */
|
||||
priv->pd_dev.d_rmmac = pic32mz_rmmac; /* Remove multicast MAC address */
|
||||
#endif
|
||||
#if defined(CONFIG_NETDEV_IOCTL) && defined(PIC32MZ_HAVE_PHY)
|
||||
priv->pd_dev.d_ioctl = pic32mz_ioctl; /* Support PHY ioctl() calls */
|
||||
#endif
|
||||
priv->pd_dev.d_private = priv; /* Used to recover private state from dev */
|
||||
|
||||
|
|
|
|||
|
|
@ -468,6 +468,16 @@
|
|||
#define MII_LAN8720_SPSCR_GPIO1 (1 << 8) /* Bit 8: GPIO1 */
|
||||
#define MII_LAN8720_SPSCR_GPIO2 (1 << 9) /* Bit 9: GPIO2 */
|
||||
/* Bit 10-11: Reserved */
|
||||
|
||||
/* SMSC LAN8720 ISR and IMR register bits (same layout on the LAN8740) */
|
||||
|
||||
#define MII_LAN8720_INT_ANPAGE (1 << 1) /* Bit 1: Auto-negotiation page received */
|
||||
#define MII_LAN8720_INT_PDFAULT (1 << 2) /* Bit 2: Parallel detection fault */
|
||||
#define MII_LAN8720_INT_ANLPACK (1 << 3) /* Bit 3: Auto-negotiation LP acknowledge */
|
||||
#define MII_LAN8720_INT_LINKDOWN (1 << 4) /* Bit 4: Link down */
|
||||
#define MII_LAN8720_INT_REMFAULT (1 << 5) /* Bit 5: Remote fault detected */
|
||||
#define MII_LAN8720_INT_ANCOMPLETE (1 << 6) /* Bit 6: Auto-negotiation complete */
|
||||
#define MII_LAN8720_INT_ENERGYON (1 << 7) /* Bit 7: ENERGYON generated */
|
||||
#define MII_LAN8720_SPSCR_ANEGDONE (1 << 12) /* Bit 12: Autonegotiation complete */
|
||||
/* Bits 13-15: Reserved */
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue