19 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
21 #include <linux/kernel.h>
22 #include <linux/string.h>
23 #include <linux/errno.h>
28 #include <linux/netdevice.h>
32 #include <linux/module.h>
33 #include <linux/mii.h>
34 #include <linux/ethtool.h>
38 #include <linux/mdio.h>
43 #include <asm/uaccess.h>
52 pr_info(
"%s - Link is Up - %d/%s\n",
53 dev_name(&phydev->
dev),
57 pr_info(
"%s - Link is Down\n", dev_name(&phydev->
dev));
70 static int phy_clear_interrupt(
struct phy_device *phydev)
74 if (phydev->
drv->ack_interrupt)
75 err = phydev->
drv->ack_interrupt(phydev);
87 static int phy_config_interrupt(
struct phy_device *phydev,
u32 interrupts)
92 if (phydev->
drv->config_intr)
93 err = phydev->
drv->config_intr(phydev);
107 static inline int phy_aneg_done(
struct phy_device *phydev)
163 #define MAX_NUM_SETTINGS ARRAY_SIZE(settings)
175 static inline int phy_find_setting(
int speed,
int duplex)
180 (settings[idx].speed != speed ||
181 settings[idx].duplex != duplex))
213 static void phy_sanitize_settings(
struct phy_device *phydev)
222 idx = phy_find_valid(phy_find_setting(phydev->
speed, phydev->
duplex),
293 ethtool_cmd_speed_set(cmd, phydev->
speed);
363 phydev->
drv->config_init) {
365 phydev->
drv->config_init(phydev);
370 if (phydev->
drv->hwtstamp)
371 return phydev->
drv->hwtstamp(phydev, ifr);
398 phy_sanitize_settings(phydev);
400 err = phydev->
drv->config_aneg(phydev);
474 static void phy_force_reduction(
struct phy_device *phydev)
478 idx = phy_find_setting(phydev->
speed, phydev->
duplex);
482 idx = phy_find_valid(idx, phydev->
supported);
501 static void phy_error(
struct phy_device *phydev)
516 static irqreturn_t phy_interrupt(
int irq,
void *phy_dat)
539 static int phy_enable_interrupts(
struct phy_device *phydev)
543 err = phy_clear_interrupt(phydev);
557 static int phy_disable_interrupts(
struct phy_device *phydev)
568 err = phy_clear_interrupt(phydev);
602 pr_warn(
"%s: Can't get IRQ %d (PHY)\n",
603 phydev->
bus->name, phydev->
irq);
608 err = phy_enable_interrupts(phydev);
622 err = phy_disable_interrupts(phydev);
659 if (phydev->
drv->did_interrupt &&
660 !phydev->
drv->did_interrupt(phydev))
663 err = phy_disable_interrupts(phydev);
717 phy_clear_interrupt(phydev);
747 switch (phydev->
state) {
781 switch(phydev->
state) {
794 err = phy_read_status(phydev);
810 err = phy_aneg_done(phydev);
834 idx = phy_find_valid(0, phydev->
supported);
848 err = phy_read_status(phydev);
870 phy_force_reduction(phydev);
884 err = phy_read_status(phydev);
900 err = phy_config_interrupt(phydev,
912 err = phy_clear_interrupt(phydev);
917 err = phy_config_interrupt(phydev,
924 err = phy_aneg_done(phydev);
932 err = phy_read_status(phydev);
947 err = phy_read_status(phydev);
972 static inline void mmd_phy_indirect(
struct mii_bus *
bus,
int prtad,
int devad,
1000 static int phy_read_mmd_indirect(
struct mii_bus *bus,
int prtad,
int devad,
1005 mmd_phy_indirect(bus, prtad, devad, addr);
1029 static void phy_write_mmd_indirect(
struct mii_bus *bus,
int prtad,
int devad,
1032 mmd_phy_indirect(bus, prtad, devad, addr);
1060 int eee_lp, eee_cap, eee_adv;
1065 status = phy_read_status(phydev);
1075 cap = mmd_eee_cap_to_ethtool_sup_t(eee_cap);
1092 adv = mmd_eee_adv_to_ethtool_adv_t(eee_adv);
1093 lp = mmd_eee_adv_to_ethtool_adv_t(eee_lp);
1094 idx = phy_find_setting(phydev->
speed, phydev->
duplex);
1095 if ((lp & adv & settings[idx].setting))
1098 if (clk_stop_enable) {
1153 data->
supported = mmd_eee_cap_to_ethtool_sup_t(val);
1160 data->
advertised = mmd_eee_adv_to_ethtool_adv_t(val);
1184 val = ethtool_adv_to_mmd_eee_adv_t(data->
advertised);