Add support for a network device IOCTL to access PHY registers. Ioctls only implemented for STM32. From Lazlo
This commit is contained in:
parent
c716c463d5
commit
f183632aab
@ -665,6 +665,9 @@ static void stm32_rxdescinit(FAR struct stm32_ethmac_s *priv);
|
|||||||
|
|
||||||
/* PHY Initialization */
|
/* PHY Initialization */
|
||||||
|
|
||||||
|
#ifdef CONFIG_NETDEV_PHY_IOCTL
|
||||||
|
static int stm32_ioctl(int cmd, struct mii_ioctl_data *req);
|
||||||
|
#endif
|
||||||
static int stm32_phyread(uint16_t phydevaddr, uint16_t phyregaddr, uint16_t *value);
|
static int stm32_phyread(uint16_t phydevaddr, uint16_t phyregaddr, uint16_t *value);
|
||||||
static int stm32_phywrite(uint16_t phydevaddr, uint16_t phyregaddr, uint16_t value);
|
static int stm32_phywrite(uint16_t phydevaddr, uint16_t phyregaddr, uint16_t value);
|
||||||
#ifdef CONFIG_ETH0_PHY_DM9161
|
#ifdef CONFIG_ETH0_PHY_DM9161
|
||||||
@ -2475,6 +2478,63 @@ static void stm32_rxdescinit(FAR struct stm32_ethmac_s *priv)
|
|||||||
stm32_putreg((uint32_t)priv->rxtable, STM32_ETH_DMARDLAR);
|
stm32_putreg((uint32_t)priv->rxtable, STM32_ETH_DMARDLAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Function: stm32_ioctl
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Executes the SIOCxMIIxxx command and responds using the request struct
|
||||||
|
* that must be provided as its 2nd parameter.
|
||||||
|
*
|
||||||
|
* When called with SIOCGMIIPHY it will get the PHY address for the device
|
||||||
|
* and write it to the req->phy_id field of the request struct.
|
||||||
|
*
|
||||||
|
* When called with SIOCGMIIREG it will read a register of the PHY that is
|
||||||
|
* specified using the req->reg_no struct field and then write its output
|
||||||
|
* to the req->val_out field.
|
||||||
|
*
|
||||||
|
* When called with SIOCSMIIREG it will write to a register of the PHY that
|
||||||
|
* is specified using the req->reg_no struct field and use req->val_in as
|
||||||
|
* its input.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* cmd - SIOCxMIIxxx command code
|
||||||
|
* req - request structure also used to return values
|
||||||
|
*
|
||||||
|
* Returned Value: Negated errno on failure.
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_NETDEV_PHY_IOCTL
|
||||||
|
static int stm32_ioctl(int cmd, struct mii_ioctl_data *req)
|
||||||
|
{
|
||||||
|
int ret = -ENOTTY;
|
||||||
|
|
||||||
|
switch (cmd)
|
||||||
|
{
|
||||||
|
case SIOCGMIIPHY: /* Get MII PHY address */
|
||||||
|
req->phy_id = CONFIG_STM32_PHYADDR;
|
||||||
|
ret = OK;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIOCGMIIREG: /* Get register from MII PHY */
|
||||||
|
ret = stm32_phyread(req->phy_id, req->reg_num, &req->val_out);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIOCSMIIREG: /* Set register in MII PHY */
|
||||||
|
ret = stm32_phywrite(req->phy_id, req->reg_num, req->val_in);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ret = -EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_NETDEV_PHY_IOCTL */
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Function: stm32_phyread
|
* Function: stm32_phyread
|
||||||
*
|
*
|
||||||
@ -3460,6 +3520,9 @@ int stm32_ethinitialize(int intf)
|
|||||||
#ifdef CONFIG_NET_IGMP
|
#ifdef CONFIG_NET_IGMP
|
||||||
priv->dev.d_addmac = stm32_addmac; /* Add multicast MAC address */
|
priv->dev.d_addmac = stm32_addmac; /* Add multicast MAC address */
|
||||||
priv->dev.d_rmmac = stm32_rmmac; /* Remove multicast MAC address */
|
priv->dev.d_rmmac = stm32_rmmac; /* Remove multicast MAC address */
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_NETDEV_PHY_IOCTL
|
||||||
|
priv->dev.d_ioctl = stm32_ioctl; /* Support PHY ioctl() calls */
|
||||||
#endif
|
#endif
|
||||||
priv->dev.d_private = (void*)g_stm32ethmac; /* Used to recover private state from dev */
|
priv->dev.d_private = (void*)g_stm32ethmac; /* Used to recover private state from dev */
|
||||||
|
|
||||||
|
@ -57,11 +57,22 @@
|
|||||||
#define IFF_RUNNING (1 << 2)
|
#define IFF_RUNNING (1 << 2)
|
||||||
#define IFF_NOARP (1 << 7)
|
#define IFF_NOARP (1 << 7)
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************************
|
/*******************************************************************************************
|
||||||
* Public Type Definitions
|
* Public Type Definitions
|
||||||
*******************************************************************************************/
|
*******************************************************************************************/
|
||||||
|
|
||||||
|
/* Part of the I/F request used to read from or write to the MII/PHY management
|
||||||
|
* interface when SIOCxMIIREG ioctl was called.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct mii_ioctl_data
|
||||||
|
{
|
||||||
|
uint16_t phy_id; /* PHY device address */
|
||||||
|
uint16_t reg_num; /* PHY register address */
|
||||||
|
uint16_t val_in; /* PHY input data */
|
||||||
|
uint16_t val_out; /* PHY output data */
|
||||||
|
};
|
||||||
|
|
||||||
/* This is the newer form if the I/F request structure that can be used with both IPv4
|
/* This is the newer form if the I/F request structure that can be used with both IPv4
|
||||||
* and IPv6.
|
* and IPv6.
|
||||||
*/
|
*/
|
||||||
@ -79,6 +90,7 @@ struct lifreq
|
|||||||
int lifru_count; /* Number of devices */
|
int lifru_count; /* Number of devices */
|
||||||
int lifru_mtu; /* MTU size */
|
int lifru_mtu; /* MTU size */
|
||||||
uint8_t lifru_flags; /* Interface flags */
|
uint8_t lifru_flags; /* Interface flags */
|
||||||
|
struct mii_ioctl_data lifru_mii_data; /* MII request data */
|
||||||
} lifr_ifru;
|
} lifr_ifru;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -90,6 +102,10 @@ struct lifreq
|
|||||||
#define lifr_mtu lifr_ifru.lifru_mtu /* MTU */
|
#define lifr_mtu lifr_ifru.lifru_mtu /* MTU */
|
||||||
#define lifr_count lifr_ifru.lifru_count /* Number of devices */
|
#define lifr_count lifr_ifru.lifru_count /* Number of devices */
|
||||||
#define lifr_flags lifr_ifru.lifru_flags /* interface flags */
|
#define lifr_flags lifr_ifru.lifru_flags /* interface flags */
|
||||||
|
#define lifr_mii_phy_id lifr_ifru.lifru_mii_data.phy_id /* PHY device address */
|
||||||
|
#define lifr_mii_reg_num lifr_ifru.lifru_mii_data.reg_num /* PHY register address */
|
||||||
|
#define lifr_mii_val_in lifr_ifru.lifru_mii_data.val_in /* PHY input data */
|
||||||
|
#define lifr_mii_val_out lifr_ifru.lifru_mii_data.val_out /* PHY output data */
|
||||||
|
|
||||||
/* This is the older I/F request that should only be used with IPv4. However, since
|
/* This is the older I/F request that should only be used with IPv4. However, since
|
||||||
* NuttX only supports IPv4 or 6 (not both), we can force the older structure to
|
* NuttX only supports IPv4 or 6 (not both), we can force the older structure to
|
||||||
@ -110,6 +126,7 @@ struct ifreq
|
|||||||
int ifru_count; /* Number of devices */
|
int ifru_count; /* Number of devices */
|
||||||
int ifru_mtu; /* MTU size */
|
int ifru_mtu; /* MTU size */
|
||||||
uint8_t ifru_flags; /* Interface flags */
|
uint8_t ifru_flags; /* Interface flags */
|
||||||
|
struct mii_ioctl_data ifru_mii_data; /* MII request data */
|
||||||
} ifr_ifru;
|
} ifr_ifru;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -121,6 +138,10 @@ struct ifreq
|
|||||||
#define ifr_mtu ifr_ifru.ifru_mtu /* MTU */
|
#define ifr_mtu ifr_ifru.ifru_mtu /* MTU */
|
||||||
#define ifr_count ifr_ifru.ifru_count /* Number of devices */
|
#define ifr_count ifr_ifru.ifru_count /* Number of devices */
|
||||||
#define ifr_flags ifr_ifru.ifru_flags /* interface flags */
|
#define ifr_flags ifr_ifru.ifru_flags /* interface flags */
|
||||||
|
#define ifr_mii_phy_id ifr_ifru.ifru_mii_data.phy_id /* PHY device address */
|
||||||
|
#define ifr_mii_reg_num ifr_ifru.ifru_mii_data.reg_num /* PHY register address */
|
||||||
|
#define ifr_mii_val_in ifr_ifru.ifru_mii_data.val_in /* PHY input data */
|
||||||
|
#define ifr_mii_val_out ifr_ifru.ifru_mii_data.val_out /* PHY output data */
|
||||||
|
|
||||||
#else /* CONFIG_NET_IPv6 */
|
#else /* CONFIG_NET_IPv6 */
|
||||||
|
|
||||||
@ -134,6 +155,10 @@ struct ifreq
|
|||||||
#define ifr_mtu lifr_ifru.lifru_mtu /* MTU */
|
#define ifr_mtu lifr_ifru.lifru_mtu /* MTU */
|
||||||
#define ifr_count lifr_ifru.lifru_count /* Number of devices */
|
#define ifr_count lifr_ifru.lifru_count /* Number of devices */
|
||||||
#define ifr_flags lifr_ifru.lifru_flags /* interface flags */
|
#define ifr_flags lifr_ifru.lifru_flags /* interface flags */
|
||||||
|
#define ifr_mii_phy_id lifr_ifru.lifru_mii_data.phy_id /* PHY device address */
|
||||||
|
#define ifr_mii_reg_num lifr_ifru.lifru_mii_data.reg_num /* PHY register address */
|
||||||
|
#define ifr_mii_val_in lifr_ifru.lifru_mii_data.val_in /* PHY input data */
|
||||||
|
#define ifr_mii_val_out lifr_ifru.lifru_mii_data.val_out /* PHY output data */
|
||||||
|
|
||||||
#endif /* CONFIG_NET_IPv6 */
|
#endif /* CONFIG_NET_IPv6 */
|
||||||
|
|
||||||
|
@ -160,6 +160,12 @@
|
|||||||
|
|
||||||
#define SIOCSIWPMKSA _SIOC(0x0041) /* PMKSA cache operation */
|
#define SIOCSIWPMKSA _SIOC(0x0041) /* PMKSA cache operation */
|
||||||
|
|
||||||
|
/* MDIO/MCD *****************************************************************/
|
||||||
|
|
||||||
|
#define SIOCGMIIPHY _SIOC(0x0042) /* Get address of MII PHY in use */
|
||||||
|
#define SIOCGMIIREG _SIOC(0x0043) /* Get a MII register via MDIO */
|
||||||
|
#define SIOCSMIIREG _SIOC(0x0044) /* Set a MII register via MDIO */
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Type Definitions
|
* Type Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -187,6 +187,9 @@ struct uip_driver_s
|
|||||||
int (*d_addmac)(struct uip_driver_s *dev, FAR const uint8_t *mac);
|
int (*d_addmac)(struct uip_driver_s *dev, FAR const uint8_t *mac);
|
||||||
int (*d_rmmac)(struct uip_driver_s *dev, FAR const uint8_t *mac);
|
int (*d_rmmac)(struct uip_driver_s *dev, FAR const uint8_t *mac);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_NETDEV_PHY_IOCTL
|
||||||
|
int (*d_ioctl)(int cmd, struct mii_ioctl_data *req);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Drivers may attached device-specific, private information */
|
/* Drivers may attached device-specific, private information */
|
||||||
|
|
||||||
|
@ -73,6 +73,12 @@ config NET_SOCKOPTS
|
|||||||
---help---
|
---help---
|
||||||
Enable or disable support for socket options
|
Enable or disable support for socket options
|
||||||
|
|
||||||
|
config NETDEV_PHY_IOCTL
|
||||||
|
bool "Enable PHY ioctl()"
|
||||||
|
default n
|
||||||
|
---help---
|
||||||
|
Enable support for ioctl() commands to access PHY registers"
|
||||||
|
|
||||||
if NET_SOCKOPTS
|
if NET_SOCKOPTS
|
||||||
|
|
||||||
config NET_SOLINGER
|
config NET_SOLINGER
|
||||||
|
@ -422,6 +422,21 @@ static int netdev_ifrioctl(FAR struct socket *psock, int cmd,
|
|||||||
# error "IOCTL Commands not implemented"
|
# error "IOCTL Commands not implemented"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_NETDEV_PHY_IOCTL
|
||||||
|
case SIOCGMIIPHY: /* Get address of MII PHY in use */
|
||||||
|
case SIOCGMIIREG: /* Get MII register via MDIO */
|
||||||
|
case SIOCSMIIREG: /* Set MII register via MDIO */
|
||||||
|
{
|
||||||
|
dev = netdev_ifrdev(req);
|
||||||
|
if (dev && dev->d_ioctl)
|
||||||
|
{
|
||||||
|
struct mii_ioctl_data *mii_data = &req->ifr_ifru.ifru_mii_data;
|
||||||
|
ret = dev->d_ioctl(cmd, mii_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
ret = -ENOTTY;
|
ret = -ENOTTY;
|
||||||
|
Loading…
Reference in New Issue
Block a user