diff options
Diffstat (limited to 'include/linux/phy.h')
-rw-r--r-- | include/linux/phy.h | 151 |
1 files changed, 127 insertions, 24 deletions
diff --git a/include/linux/phy.h b/include/linux/phy.h index a4cda3e28d..7da4f94e0e 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -1,15 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * Copyright (c) 2009-2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> * * Author: Andy Fleming * * Copyright (c) 2004 Freescale Semiconductor, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * */ #ifndef __PHY_H @@ -41,7 +36,46 @@ #define PHY_GBIT_FEATURES (PHY_BASIC_FEATURES | \ PHY_1000BT_FEATURES) -/* Interface Mode definitions */ +/** + * enum phy_interface_t - Interface Mode definitions + * + * @PHY_INTERFACE_MODE_NA: Not Applicable - don't touch + * @PHY_INTERFACE_MODE_INTERNAL: No interface, MAC and PHY combined + * @PHY_INTERFACE_MODE_MII: Media-independent interface + * @PHY_INTERFACE_MODE_GMII: Gigabit media-independent interface + * @PHY_INTERFACE_MODE_SGMII: Serial gigabit media-independent interface + * @PHY_INTERFACE_MODE_TBI: Ten Bit Interface + * @PHY_INTERFACE_MODE_REVMII: Reverse Media Independent Interface + * @PHY_INTERFACE_MODE_RMII: Reduced Media Independent Interface + * @PHY_INTERFACE_MODE_REVRMII: Reduced Media Independent Interface in PHY role + * @PHY_INTERFACE_MODE_RGMII: Reduced gigabit media-independent interface + * @PHY_INTERFACE_MODE_RGMII_ID: RGMII with Internal RX+TX delay + * @PHY_INTERFACE_MODE_RGMII_RXID: RGMII with Internal RX delay + * @PHY_INTERFACE_MODE_RGMII_TXID: RGMII with Internal RX delay + * @PHY_INTERFACE_MODE_RTBI: Reduced TBI + * @PHY_INTERFACE_MODE_SMII: Serial MII + * @PHY_INTERFACE_MODE_XGMII: 10 gigabit media-independent interface + * @PHY_INTERFACE_MODE_XLGMII:40 gigabit media-independent interface + * @PHY_INTERFACE_MODE_MOCA: Multimedia over Coax + * @PHY_INTERFACE_MODE_PSGMII: Penta SGMII + * @PHY_INTERFACE_MODE_QSGMII: Quad SGMII + * @PHY_INTERFACE_MODE_TRGMII: Turbo RGMII + * @PHY_INTERFACE_MODE_100BASEX: 100 BaseX + * @PHY_INTERFACE_MODE_1000BASEX: 1000 BaseX + * @PHY_INTERFACE_MODE_2500BASEX: 2500 BaseX + * @PHY_INTERFACE_MODE_5GBASER: 5G BaseR + * @PHY_INTERFACE_MODE_RXAUI: Reduced XAUI + * @PHY_INTERFACE_MODE_XAUI: 10 Gigabit Attachment Unit Interface + * @PHY_INTERFACE_MODE_10GBASER: 10G BaseR + * @PHY_INTERFACE_MODE_25GBASER: 25G BaseR + * @PHY_INTERFACE_MODE_USXGMII: Universal Serial 10GE MII + * @PHY_INTERFACE_MODE_10GKR: 10GBASE-KR - with Clause 73 AN + * @PHY_INTERFACE_MODE_QUSGMII: Quad Universal SGMII + * @PHY_INTERFACE_MODE_1000BASEKX: 1000Base-KX - with Clause 73 AN + * @PHY_INTERFACE_MODE_MAX: Book keeping + * + * Describes the interface between the MAC and PHY. + */ typedef enum { PHY_INTERFACE_MODE_NA, PHY_INTERFACE_MODE_INTERNAL, @@ -51,6 +85,7 @@ typedef enum { PHY_INTERFACE_MODE_TBI, PHY_INTERFACE_MODE_REVMII, PHY_INTERFACE_MODE_RMII, + PHY_INTERFACE_MODE_REVRMII, PHY_INTERFACE_MODE_RGMII, PHY_INTERFACE_MODE_RGMII_ID, PHY_INTERFACE_MODE_RGMII_RXID, @@ -58,17 +93,25 @@ typedef enum { PHY_INTERFACE_MODE_RTBI, PHY_INTERFACE_MODE_SMII, PHY_INTERFACE_MODE_XGMII, + PHY_INTERFACE_MODE_XLGMII, PHY_INTERFACE_MODE_MOCA, + PHY_INTERFACE_MODE_PSGMII, PHY_INTERFACE_MODE_QSGMII, PHY_INTERFACE_MODE_TRGMII, + PHY_INTERFACE_MODE_100BASEX, PHY_INTERFACE_MODE_1000BASEX, PHY_INTERFACE_MODE_2500BASEX, + PHY_INTERFACE_MODE_5GBASER, PHY_INTERFACE_MODE_RXAUI, PHY_INTERFACE_MODE_XAUI, - /* 10GBASE-KR, XFI, SFI - single lane 10G Serdes */ + /* 10GBASE-R, XFI, SFI - single lane 10G Serdes */ + PHY_INTERFACE_MODE_10GBASER, + PHY_INTERFACE_MODE_25GBASER, + PHY_INTERFACE_MODE_USXGMII, + /* 10GBASE-KR - with Clause 73 AN */ PHY_INTERFACE_MODE_10GKR, - PHY_INTERFACE_MODE_SGMII_2500, - PHY_INTERFACE_MODE_NONE, + PHY_INTERFACE_MODE_QUSGMII, + PHY_INTERFACE_MODE_1000BASEKX, PHY_INTERFACE_MODE_MAX, } phy_interface_t; @@ -104,9 +147,9 @@ struct mii_bus { int (*write)(struct mii_bus *bus, int phy_id, int regnum, u16 val); int (*reset)(struct mii_bus *bus); - struct device_d *parent; + struct device *parent; - struct device_d dev; + struct device dev; /* list of all PHYs on bus */ struct phy_device *phy_map[PHY_MAX_ADDR]; @@ -133,7 +176,7 @@ struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr); extern struct list_head mii_bus_list; -int mdiobus_detect(struct device_d *dev); +int mdiobus_detect(struct device *dev); #define for_each_mii_bus(mii) \ list_for_each_entry(mii, &mii_bus_list, list) @@ -147,12 +190,13 @@ int mdiobus_write(struct mii_bus *bus, int addr, u32 regnum, u16 val); /* phy_device: An instance of a PHY * - * bus: Pointer to the bus this PHY is on - * dev: driver model device structure for this PHY - * phy_id: UID for this device found during discovery - * dev_flags: Device-specific flags used by the PHY driver. - * addr: Bus address of PHY - * attached_dev: The attached enet driver's device instance ptr + * @bus: Pointer to the bus this PHY is on + * @dev: driver model device structure for this PHY + * @phy_id: UID for this device found during discovery + * @c45_ids: 802.3-c45 Device Identifiers if is_c45. + * @dev_flags: Device-specific flags used by the PHY driver. + * @addr: Bus address of PHY + * @attached_dev: The attached enet driver's device instance ptr * * speed, duplex, pause, supported, advertising, and * autoneg are used like in mii_if_info @@ -160,10 +204,12 @@ int mdiobus_write(struct mii_bus *bus, int addr, u32 regnum, u16 val); struct phy_device { struct mii_bus *bus; - struct device_d dev; + struct device dev; u32 phy_id; + unsigned is_c45:1; + u32 dev_flags; phy_interface_t interface; @@ -206,12 +252,13 @@ struct phy_device { /* struct phy_driver: Driver structure for a particular PHY type * - * phy_id: The result of reading the UID registers of this PHY + * @phy_id: The result of reading the UID registers of this PHY * type, and ANDing them with the phy_id_mask. This driver * only works for PHYs with IDs which match this field - * phy_id_mask: Defines the important bits of the phy_id - * features: A list of features (speed, duplex, etc) supported + * @phy_id_mask: Defines the important bits of the phy_id + * @features: A list of features (speed, duplex, etc) supported * by this PHY + * @driver_data: Static driver data * * The drivers must implement config_aneg and read_status. All * other functions are optional. Note that none of these @@ -225,6 +272,8 @@ struct phy_driver { u32 phy_id; unsigned int phy_id_mask; u32 features; + const void *driver_data; + bool is_phy; /* * Called to initialize the PHY, @@ -258,7 +307,7 @@ struct phy_driver { int (*read_page)(struct phy_device *phydev); int (*write_page)(struct phy_device *phydev, int page); - struct driver_d drv; + struct driver drv; }; #define to_phy_driver(d) ((d) ? container_of(d, struct phy_driver, drv) : NULL) @@ -283,6 +332,8 @@ int phy_drivers_register(struct phy_driver *new_driver, int n); struct phy_device *get_phy_device(struct mii_bus *bus, int addr); int phy_init(void); int phy_init_hw(struct phy_device *phydev); +struct phy_device *of_phy_register_fixed_link(struct device_node *np, + struct eth_device *edev); #define phy_register_drivers_macro(level, drvs) \ static int __init drvs##_register(void) \ @@ -408,12 +459,64 @@ int phy_scan_fixups(struct phy_device *phydev); int phy_read_mmd_indirect(struct phy_device *phydev, int prtad, int devad); void phy_write_mmd_indirect(struct phy_device *phydev, int prtad, int devad, u16 data); +int phy_modify_mmd_indirect(struct phy_device *phydev, int prtad, int devad, + u16 mask, u16 set); + +int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum); +int phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val); +int phy_modify_mmd(struct phy_device *phydev, int devad, u32 regnum, + u16 mask, u16 set); +int phy_modify_mmd_changed(struct phy_device *phydev, int devad, u32 regnum, + u16 mask, u16 set); + +/** + * phy_set_bits_mmd - Convenience function for setting bits in a register + * on MMD + * @phydev: the phy_device struct + * @devad: the MMD containing register to modify + * @regnum: register number to modify + * @val: bits to set + */ +static inline int phy_set_bits_mmd(struct phy_device *phydev, int devad, + u32 regnum, u16 val) +{ + return phy_modify_mmd(phydev, devad, regnum, 0, val); +} + +/** + * phy_clear_bits_mmd - Convenience function for clearing bits in a register + * on MMD + * @phydev: the phy_device struct + * @devad: the MMD containing register to modify + * @regnum: register number to modify + * @val: bits to clear + */ +static inline int phy_clear_bits_mmd(struct phy_device *phydev, int devad, + u32 regnum, u16 val) +{ + return phy_modify_mmd(phydev, devad, regnum, val, 0); +} static inline bool phy_acquired(struct phy_device *phydev) { return phydev && phydev->bus && slice_acquired(&phydev->bus->slice); } +#define phydev_err(_phydev, format, args...) \ + dev_err(&_phydev->dev, format, ##args) + +#define phydev_err_probe(_phydev, err, format, args...) \ + dev_err_probe(&_phydev->dev, err, format, ##args) + +#define phydev_info(_phydev, format, args...) \ + dev_info(&_phydev->dev, format, ##args) + +#define phydev_warn(_phydev, format, args...) \ + dev_warn(&_phydev->dev, format, ##args) + +#define phydev_dbg(_phydev, format, args...) \ + dev_dbg(&_phydev->dev, format, ##args) + #ifdef CONFIG_PHYLIB int phy_register_fixup_for_uid(u32 phy_uid, u32 phy_uid_mask, int (*run)(struct phy_device *)); |