diff options
author | Florian Fainelli <f.fainelli@gmail.com> | 2013-05-22 21:11:12 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-05-28 01:42:50 -0400 |
commit | 4284b6a535a9aab33e5f3c37929143508dd2ee60 (patch) | |
tree | 8535656632c49ece1d66d97c9e591d07f3eaff13 | |
parent | 7ec872114251b618adf5a2688de0ca00de63635d (diff) |
phy: allow drivers to flag a PHY device as internal
libphy currently always reports a PHY as an external transceiver from
the ethtool output. This is inaccurate, because some drivers should be
able to tell that a PHY device is an internal transceiver of an Ethernet
MAC. Add a new flag (PHY_IS_INTERNAL) which can be set by PHY drivers
just like other flags, and a corresponding helper: phy_is_internal()
which can be used by networking drivers to query if a given
PHY device is internal.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/phy/phy.c | 3 | ||||
-rw-r--r-- | drivers/net/phy/phy_device.c | 3 | ||||
-rw-r--r-- | include/linux/phy.h | 12 |
3 files changed, 17 insertions, 1 deletions
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 2d28a0ef4572..b2a94e436ed8 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c | |||
@@ -294,7 +294,8 @@ int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd) | |||
294 | cmd->duplex = phydev->duplex; | 294 | cmd->duplex = phydev->duplex; |
295 | cmd->port = PORT_MII; | 295 | cmd->port = PORT_MII; |
296 | cmd->phy_address = phydev->addr; | 296 | cmd->phy_address = phydev->addr; |
297 | cmd->transceiver = XCVR_EXTERNAL; | 297 | cmd->transceiver = phy_is_internal(phydev) ? |
298 | XCVR_INTERNAL : XCVR_EXTERNAL; | ||
298 | cmd->autoneg = phydev->autoneg; | 299 | cmd->autoneg = phydev->autoneg; |
299 | 300 | ||
300 | return 0; | 301 | return 0; |
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index b55aa33a5b8b..74630e94fa3b 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c | |||
@@ -1017,6 +1017,9 @@ static int phy_probe(struct device *dev) | |||
1017 | phy_interrupt_is_valid(phydev)) | 1017 | phy_interrupt_is_valid(phydev)) |
1018 | phydev->irq = PHY_POLL; | 1018 | phydev->irq = PHY_POLL; |
1019 | 1019 | ||
1020 | if (phydrv->flags & PHY_IS_INTERNAL) | ||
1021 | phydev->is_internal = true; | ||
1022 | |||
1020 | mutex_lock(&phydev->lock); | 1023 | mutex_lock(&phydev->lock); |
1021 | 1024 | ||
1022 | /* Start out supporting everything. Eventually, | 1025 | /* Start out supporting everything. Eventually, |
diff --git a/include/linux/phy.h b/include/linux/phy.h index fdfa11542974..ee411b0eef5d 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h | |||
@@ -49,6 +49,7 @@ | |||
49 | 49 | ||
50 | #define PHY_HAS_INTERRUPT 0x00000001 | 50 | #define PHY_HAS_INTERRUPT 0x00000001 |
51 | #define PHY_HAS_MAGICANEG 0x00000002 | 51 | #define PHY_HAS_MAGICANEG 0x00000002 |
52 | #define PHY_IS_INTERNAL 0x00000004 | ||
52 | 53 | ||
53 | /* Interface Mode definitions */ | 54 | /* Interface Mode definitions */ |
54 | typedef enum { | 55 | typedef enum { |
@@ -261,6 +262,7 @@ struct phy_c45_device_ids { | |||
261 | * phy_id: UID for this device found during discovery | 262 | * phy_id: UID for this device found during discovery |
262 | * c45_ids: 802.3-c45 Device Identifers if is_c45. | 263 | * c45_ids: 802.3-c45 Device Identifers if is_c45. |
263 | * is_c45: Set to true if this phy uses clause 45 addressing. | 264 | * is_c45: Set to true if this phy uses clause 45 addressing. |
265 | * is_internal: Set to true if this phy is internal to a MAC. | ||
264 | * state: state of the PHY for management purposes | 266 | * state: state of the PHY for management purposes |
265 | * dev_flags: Device-specific flags used by the PHY driver. | 267 | * dev_flags: Device-specific flags used by the PHY driver. |
266 | * addr: Bus address of PHY | 268 | * addr: Bus address of PHY |
@@ -298,6 +300,7 @@ struct phy_device { | |||
298 | 300 | ||
299 | struct phy_c45_device_ids c45_ids; | 301 | struct phy_c45_device_ids c45_ids; |
300 | bool is_c45; | 302 | bool is_c45; |
303 | bool is_internal; | ||
301 | 304 | ||
302 | enum phy_state state; | 305 | enum phy_state state; |
303 | 306 | ||
@@ -520,6 +523,15 @@ static inline bool phy_interrupt_is_valid(struct phy_device *phydev) | |||
520 | return phydev->irq != PHY_POLL && phydev->irq != PHY_IGNORE_INTERRUPT; | 523 | return phydev->irq != PHY_POLL && phydev->irq != PHY_IGNORE_INTERRUPT; |
521 | } | 524 | } |
522 | 525 | ||
526 | /** | ||
527 | * phy_is_internal - Convenience function for testing if a PHY is internal | ||
528 | * @phydev: the phy_device struct | ||
529 | */ | ||
530 | static inline bool phy_is_internal(struct phy_device *phydev) | ||
531 | { | ||
532 | return phydev->is_internal; | ||
533 | } | ||
534 | |||
523 | struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id, | 535 | struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id, |
524 | bool is_c45, struct phy_c45_device_ids *c45_ids); | 536 | bool is_c45, struct phy_c45_device_ids *c45_ids); |
525 | struct phy_device *get_phy_device(struct mii_bus *bus, int addr, bool is_c45); | 537 | struct phy_device *get_phy_device(struct mii_bus *bus, int addr, bool is_c45); |