/** * __mxl86110_write_extended_reg() - write to a PHY's extended register * @phydev: pointer to the PHY device structure * @regnum: register number to write * @val: value to write to @regnum * * Unlocked version of mxl86110_write_extended_reg * * Note: This function assumes the caller already holds the MDIO bus lock * or otherwise has exclusive access to the PHY. * * Return: 0 or negative error code
*/ staticint __mxl86110_write_extended_reg(struct phy_device *phydev,
u16 regnum, u16 val)
{ int ret;
ret = __phy_write(phydev, MXL86110_EXTD_REG_ADDR_OFFSET, regnum); if (ret < 0) return ret;
/** * __mxl86110_read_extended_reg - Read a PHY's extended register * @phydev: pointer to the PHY device structure * @regnum: extended register number to read (address written to reg 30) * * Unlocked version of mxl86110_read_extended_reg * * Reads the content of a PHY extended register using the MaxLinear * 2-step access mechanism: write the register address to reg 30 (0x1E), * then read the value from reg 31 (0x1F). * * Note: This function assumes the caller already holds the MDIO bus lock * or otherwise has exclusive access to the PHY. * * Return: 16-bit register value on success, or negative errno code on failure.
*/ staticint __mxl86110_read_extended_reg(struct phy_device *phydev, u16 regnum)
{ int ret;
ret = __phy_write(phydev, MXL86110_EXTD_REG_ADDR_OFFSET, regnum); if (ret < 0) return ret; return __phy_read(phydev, MXL86110_EXTD_REG_ADDR_DATA);
}
/** * __mxl86110_modify_extended_reg() - modify bits of a PHY's extended register * @phydev: pointer to the PHY device structure * @regnum: register number to write * @mask: bit mask of bits to clear * @set: bit mask of bits to set * * Note: register value = (old register value & ~mask) | set. * This function assumes the caller already holds the MDIO bus lock * or otherwise has exclusive access to the PHY. * * Return: 0 or negative error code
*/ staticint __mxl86110_modify_extended_reg(struct phy_device *phydev,
u16 regnum, u16 mask, u16 set)
{ int ret;
ret = __phy_write(phydev, MXL86110_EXTD_REG_ADDR_OFFSET, regnum); if (ret < 0) return ret;
/** * mxl86110_write_extended_reg() - Write to a PHY's extended register * @phydev: pointer to the PHY device structure * @regnum: register number to write * @val: value to write to @regnum * * This function writes to an extended register of the PHY using the * MaxLinear two-step access method (reg 0x1E/0x1F). It handles acquiring * and releasing the MDIO bus lock internally. * * Return: 0 or negative error code
*/ staticint mxl86110_write_extended_reg(struct phy_device *phydev,
u16 regnum, u16 val)
{ int ret;
phy_lock_mdio_bus(phydev);
ret = __mxl86110_write_extended_reg(phydev, regnum, val);
phy_unlock_mdio_bus(phydev);
return ret;
}
/** * mxl86110_read_extended_reg() - Read a PHY's extended register * @phydev: pointer to the PHY device structure * @regnum: extended register number to read * * This function reads from an extended register of the PHY using the * MaxLinear two-step access method (reg 0x1E/0x1F). It handles acquiring * and releasing the MDIO bus lock internally. * * Return: 16-bit register value on success, or negative errno code on failure
*/ staticint mxl86110_read_extended_reg(struct phy_device *phydev, u16 regnum)
{ int ret;
phy_lock_mdio_bus(phydev);
ret = __mxl86110_read_extended_reg(phydev, regnum);
phy_unlock_mdio_bus(phydev);
return ret;
}
/** * mxl86110_get_wol() - report if wake-on-lan is enabled * @phydev: pointer to the phy_device * @wol: a pointer to a &struct ethtool_wolinfo
*/ staticvoid mxl86110_get_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol)
{ int val;
/** * mxl86110_set_wol() - enable/disable wake-on-lan * @phydev: pointer to the phy_device * @wol: a pointer to a &struct ethtool_wolinfo * * Configures the WOL Magic Packet MAC * * Return: 0 or negative errno code
*/ staticint mxl86110_set_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol)
{ struct net_device *netdev; constunsignedchar *mac; int ret = 0;
phy_lock_mdio_bus(phydev);
if (wol->wolopts & WAKE_MAGIC) {
netdev = phydev->attached_dev; if (!netdev) {
ret = -ENODEV; goto out;
}
/* Configure the MAC address of the WOL magic packet */
mac = netdev->dev_addr;
ret = __mxl86110_write_extended_reg(phydev,
MXL86110_EXT_MAC_ADDR_CFG1,
((mac[0] << 8) | mac[1])); if (ret < 0) goto out;
ret = __mxl86110_write_extended_reg(phydev,
MXL86110_EXT_MAC_ADDR_CFG2,
((mac[2] << 8) | mac[3])); if (ret < 0) goto out;
ret = __mxl86110_write_extended_reg(phydev,
MXL86110_EXT_MAC_ADDR_CFG3,
((mac[4] << 8) | mac[5])); if (ret < 0) goto out;
ret = __mxl86110_modify_extended_reg(phydev,
MXL86110_EXT_WOL_CFG_REG,
MXL86110_WOL_CFG_WOL_MASK,
MXL86110_WOL_CFG_WOL_MASK); if (ret < 0) goto out;
/* Enables Wake-on-LAN interrupt in the PHY. */
ret = __phy_modify(phydev, PHY_IRQ_ENABLE_REG, 0,
PHY_IRQ_ENABLE_REG_WOL); if (ret < 0) goto out;
phydev_dbg(phydev, "%s, MAC Addr: %02X:%02X:%02X:%02X:%02X:%02X\n",
__func__,
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
} else {
ret = __mxl86110_modify_extended_reg(phydev,
MXL86110_EXT_WOL_CFG_REG,
MXL86110_WOL_CFG_WOL_MASK,
0); if (ret < 0) goto out;
/* Disables Wake-on-LAN interrupt in the PHY. */
ret = __phy_modify(phydev, PHY_IRQ_ENABLE_REG,
PHY_IRQ_ENABLE_REG_WOL, 0);
}
/** * mxl86110_synce_clk_cfg() - applies syncE/clk output configuration * @phydev: pointer to the phy_device * * Note: This function assumes the caller already holds the MDIO bus lock * or otherwise has exclusive access to the PHY. * * Return: 0 or negative errno code
*/ staticint mxl86110_synce_clk_cfg(struct phy_device *phydev)
{
u16 mask = 0, val = 0;
/* * Configures the clock output to its default * setting as per the datasheet. * This results in a 25MHz clock output being selected in the * COM_EXT_SYNCE_CFG register for SyncE configuration.
*/
val = MXL86110_EXT_SYNCE_CFG_EN_SYNC_E |
FIELD_PREP(MXL86110_EXT_SYNCE_CFG_CLK_SRC_SEL_MASK,
MXL86110_EXT_SYNCE_CFG_CLK_SRC_SEL_25M);
mask = MXL86110_EXT_SYNCE_CFG_EN_SYNC_E |
MXL86110_EXT_SYNCE_CFG_CLK_SRC_SEL_MASK |
MXL86110_EXT_SYNCE_CFG_CLK_FRE_SEL;
/** * mxl86110_broadcast_cfg - Configure MDIO broadcast setting for PHY * @phydev: Pointer to the PHY device structure * * This function configures the MDIO broadcast behavior of the MxL86110 PHY. * Currently, broadcast mode is explicitly disabled by clearing the EPA0 bit * in the RGMII_MDIO_CFG extended register. * * Note: This function assumes the caller already holds the MDIO bus lock * or otherwise has exclusive access to the PHY. * * Return: 0 on success or a negative errno code on failure.
*/ staticint mxl86110_broadcast_cfg(struct phy_device *phydev)
{ return __mxl86110_modify_extended_reg(phydev,
MXL86110_EXT_RGMII_MDIO_CFG,
MXL86110_RGMII_MDIO_CFG_EPA0_MASK,
0);
}
/** * mxl86110_enable_led_activity_blink - Enable LEDs activity blink on PHY * @phydev: Pointer to the PHY device structure * * Configure all PHY LEDs to blink on traffic activity regardless of whether * they are ON or OFF. This behavior allows each LED to serve as a pure activity * indicator, independently of its use as a link status indicator. * * By default, each LED blinks only when it is also in the ON state. * This function modifies the appropriate registers (LABx fields) * to enable blinking even when the LEDs are OFF, to allow the LED to be used * as a traffic indicator without requiring it to also serve * as a link status LED. * * Note: Any further LED customization can be performed via the * /sys/class/leds interface; the functions led_hw_is_supported, * led_hw_control_get, and led_hw_control_set are used * to support this mechanism. * * This function assumes the caller already holds the MDIO bus lock * or otherwise has exclusive access to the PHY. * * Return: 0 on success or a negative errno code on failure.
*/ staticint mxl86110_enable_led_activity_blink(struct phy_device *phydev)
{ int i, ret = 0;
for (i = 0; i < MXL86110_MAX_LEDS; i++) {
ret = __mxl86110_modify_extended_reg(phydev,
MXL86110_LED0_CFG_REG + i,
0,
MXL86110_LEDX_CFG_BLINK); if (ret < 0) break;
}
return ret;
}
/** * mxl86110_config_init() - initialize the PHY * @phydev: pointer to the phy_device * * Return: 0 or negative errno code
*/ staticint mxl86110_config_init(struct phy_device *phydev)
{
u16 val = 0; int ret;
phy_lock_mdio_bus(phydev);
/* configure syncE / clk output */
ret = mxl86110_synce_clk_cfg(phydev); if (ret < 0) goto out;
switch (phydev->interface) { case PHY_INTERFACE_MODE_RGMII:
val = 0; break; case PHY_INTERFACE_MODE_RGMII_RXID:
val = MXL86110_EXT_RGMII_CFG1_RX_DELAY_1950PS; break; case PHY_INTERFACE_MODE_RGMII_TXID:
val = MXL86110_EXT_RGMII_CFG1_TX_1G_DELAY_1950PS |
MXL86110_EXT_RGMII_CFG1_TX_10MB_100MB_DELAY_1950PS; break; case PHY_INTERFACE_MODE_RGMII_ID:
val = MXL86110_EXT_RGMII_CFG1_TX_1G_DELAY_1950PS |
MXL86110_EXT_RGMII_CFG1_TX_10MB_100MB_DELAY_1950PS |
MXL86110_EXT_RGMII_CFG1_RX_DELAY_1950PS; break; default:
ret = -EINVAL; goto out;
}
ret = __mxl86110_modify_extended_reg(phydev,
MXL86110_EXT_RGMII_CFG1_REG,
MXL86110_EXT_RGMII_CFG1_FULL_MASK,
val); if (ret < 0) goto out;
/* Configure RXDLY (RGMII Rx Clock Delay) to disable * the default additional delay value on RX_CLK * (2 ns for 125 MHz, 8 ns for 25 MHz/2.5 MHz) * and use just the digital one selected before
*/
ret = __mxl86110_modify_extended_reg(phydev,
MXL86110_EXT_CHIP_CFG_REG,
MXL86110_EXT_CHIP_CFG_RXDLY_ENABLE,
0); if (ret < 0) goto out;
ret = mxl86110_enable_led_activity_blink(phydev); if (ret < 0) goto out;
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.12Bemerkung:
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.