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>
This commit is contained in:
parent
4beaacc6fe
commit
b3e5464e36
@ -25,6 +25,7 @@
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/seqlock.h>
|
||||
#include <linux/idr.h>
|
||||
#include <linux/netdevice.h>
|
||||
|
||||
#include "swphy.h"
|
||||
|
||||
@ -38,6 +39,7 @@ struct fixed_phy {
|
||||
struct phy_device *phydev;
|
||||
seqcount_t seqcount;
|
||||
struct fixed_phy_status status;
|
||||
bool no_carrier;
|
||||
int (*link_update)(struct net_device *, struct fixed_phy_status *);
|
||||
struct list_head node;
|
||||
int link_gpio;
|
||||
@ -48,9 +50,28 @@ static struct fixed_mdio_bus platform_fmb = {
|
||||
.phys = LIST_HEAD_INIT(platform_fmb.phys),
|
||||
};
|
||||
|
||||
int fixed_phy_change_carrier(struct net_device *dev, bool new_carrier)
|
||||
{
|
||||
struct fixed_mdio_bus *fmb = &platform_fmb;
|
||||
struct phy_device *phydev = dev->phydev;
|
||||
struct fixed_phy *fp;
|
||||
|
||||
if (!phydev || !phydev->mdio.bus)
|
||||
return -EINVAL;
|
||||
|
||||
list_for_each_entry(fp, &fmb->phys, node) {
|
||||
if (fp->addr == phydev->mdio.addr) {
|
||||
fp->no_carrier = !new_carrier;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(fixed_phy_change_carrier);
|
||||
|
||||
static void fixed_phy_update(struct fixed_phy *fp)
|
||||
{
|
||||
if (gpio_is_valid(fp->link_gpio))
|
||||
if (!fp->no_carrier && gpio_is_valid(fp->link_gpio))
|
||||
fp->status.link = !!gpio_get_value_cansleep(fp->link_gpio);
|
||||
}
|
||||
|
||||
@ -66,6 +87,7 @@ static int fixed_mdio_read(struct mii_bus *bus, int phy_addr, int reg_num)
|
||||
|
||||
do {
|
||||
s = read_seqcount_begin(&fp->seqcount);
|
||||
fp->status.link = !fp->no_carrier;
|
||||
/* Issue callback if user registered it. */
|
||||
if (fp->link_update) {
|
||||
fp->link_update(fp->phydev->attached_dev,
|
||||
|
@ -13,6 +13,7 @@ struct fixed_phy_status {
|
||||
struct device_node;
|
||||
|
||||
#if IS_ENABLED(CONFIG_FIXED_PHY)
|
||||
extern int fixed_phy_change_carrier(struct net_device *dev, bool new_carrier);
|
||||
extern int fixed_phy_add(unsigned int irq, int phy_id,
|
||||
struct fixed_phy_status *status,
|
||||
int link_gpio);
|
||||
@ -47,6 +48,10 @@ static inline int fixed_phy_set_link_update(struct phy_device *phydev,
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
static inline int fixed_phy_change_carrier(struct net_device *dev, bool new_carrier)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif /* CONFIG_FIXED_PHY */
|
||||
|
||||
#endif /* __PHY_FIXED_H */
|
||||
|
Loading…
Reference in New Issue
Block a user