summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoakim Tjernlund <joakim.tjernlund@infinera.com>2018-12-14 09:17:05 -0500
committerDavid S. Miller <davem@davemloft.net>2018-12-17 14:24:32 -0500
commitb3e5464e36c07dba70b544044a297d5819351765 (patch)
treeed694951dab275d9335067ea3e0cc64e2100fb78
parent4beaacc6fea5a5ec43c55c22a6c83c03a5ecc775 (diff)
Fixed PHY: Add fixed_phy_change_carrier()
Drivers can use this as .ndo_change_carrier() to change carrier via /sys/class/net/ethX/carrier. Signed-off-by: Joakim Tjernlund <joakim.tjernlund@infinera.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/phy/fixed_phy.c24
-rw-r--r--include/linux/phy_fixed.h5
2 files changed, 28 insertions, 1 deletions
diff --git a/drivers/net/phy/fixed_phy.c b/drivers/net/phy/fixed_phy.c
index f7fb62712cd8..72d43c88e6ff 100644
--- a/drivers/net/phy/fixed_phy.c
+++ b/drivers/net/phy/fixed_phy.c
@@ -25,6 +25,7 @@
25#include <linux/gpio.h> 25#include <linux/gpio.h>
26#include <linux/seqlock.h> 26#include <linux/seqlock.h>
27#include <linux/idr.h> 27#include <linux/idr.h>
28#include <linux/netdevice.h>
28 29
29#include "swphy.h" 30#include "swphy.h"
30 31
@@ -38,6 +39,7 @@ struct fixed_phy {
38 struct phy_device *phydev; 39 struct phy_device *phydev;
39 seqcount_t seqcount; 40 seqcount_t seqcount;
40 struct fixed_phy_status status; 41 struct fixed_phy_status status;
42 bool no_carrier;
41 int (*link_update)(struct net_device *, struct fixed_phy_status *); 43 int (*link_update)(struct net_device *, struct fixed_phy_status *);
42 struct list_head node; 44 struct list_head node;
43 int link_gpio; 45 int link_gpio;
@@ -48,9 +50,28 @@ static struct fixed_mdio_bus platform_fmb = {
48 .phys = LIST_HEAD_INIT(platform_fmb.phys), 50 .phys = LIST_HEAD_INIT(platform_fmb.phys),
49}; 51};
50 52
53int fixed_phy_change_carrier(struct net_device *dev, bool new_carrier)
54{
55 struct fixed_mdio_bus *fmb = &platform_fmb;
56 struct phy_device *phydev = dev->phydev;
57 struct fixed_phy *fp;
58
59 if (!phydev || !phydev->mdio.bus)
60 return -EINVAL;
61
62 list_for_each_entry(fp, &fmb->phys, node) {
63 if (fp->addr == phydev->mdio.addr) {
64 fp->no_carrier = !new_carrier;
65 return 0;
66 }
67 }
68 return -EINVAL;
69}
70EXPORT_SYMBOL_GPL(fixed_phy_change_carrier);
71
51static void fixed_phy_update(struct fixed_phy *fp) 72static void fixed_phy_update(struct fixed_phy *fp)
52{ 73{
53 if (gpio_is_valid(fp->link_gpio)) 74 if (!fp->no_carrier && gpio_is_valid(fp->link_gpio))
54 fp->status.link = !!gpio_get_value_cansleep(fp->link_gpio); 75 fp->status.link = !!gpio_get_value_cansleep(fp->link_gpio);
55} 76}
56 77
@@ -66,6 +87,7 @@ static int fixed_mdio_read(struct mii_bus *bus, int phy_addr, int reg_num)
66 87
67 do { 88 do {
68 s = read_seqcount_begin(&fp->seqcount); 89 s = read_seqcount_begin(&fp->seqcount);
90 fp->status.link = !fp->no_carrier;
69 /* Issue callback if user registered it. */ 91 /* Issue callback if user registered it. */
70 if (fp->link_update) { 92 if (fp->link_update) {
71 fp->link_update(fp->phydev->attached_dev, 93 fp->link_update(fp->phydev->attached_dev,
diff --git a/include/linux/phy_fixed.h b/include/linux/phy_fixed.h
index ee54453a40a0..9525567b1951 100644
--- a/include/linux/phy_fixed.h
+++ b/include/linux/phy_fixed.h
@@ -13,6 +13,7 @@ struct fixed_phy_status {
13struct device_node; 13struct device_node;
14 14
15#if IS_ENABLED(CONFIG_FIXED_PHY) 15#if IS_ENABLED(CONFIG_FIXED_PHY)
16extern int fixed_phy_change_carrier(struct net_device *dev, bool new_carrier);
16extern int fixed_phy_add(unsigned int irq, int phy_id, 17extern int fixed_phy_add(unsigned int irq, int phy_id,
17 struct fixed_phy_status *status, 18 struct fixed_phy_status *status,
18 int link_gpio); 19 int link_gpio);
@@ -47,6 +48,10 @@ static inline int fixed_phy_set_link_update(struct phy_device *phydev,
47{ 48{
48 return -ENODEV; 49 return -ENODEV;
49} 50}
51static inline int fixed_phy_change_carrier(struct net_device *dev, bool new_carrier)
52{
53 return -EINVAL;
54}
50#endif /* CONFIG_FIXED_PHY */ 55#endif /* CONFIG_FIXED_PHY */
51 56
52#endif /* __PHY_FIXED_H */ 57#endif /* __PHY_FIXED_H */