Loading arch/arm/configs/mdm-perf_defconfig +2 −0 Original line number Original line Diff line number Diff line Loading @@ -213,6 +213,8 @@ CONFIG_RNDIS_IPA=y # CONFIG_NET_VENDOR_SEEQ is not set # CONFIG_NET_VENDOR_SEEQ is not set # CONFIG_NET_VENDOR_SMSC is not set # CONFIG_NET_VENDOR_SMSC is not set # CONFIG_NET_VENDOR_STMICRO is not set # CONFIG_NET_VENDOR_STMICRO is not set CONFIG_MICREL_PHY=y CONFIG_NXP_TJA110X_PHY=y CONFIG_PPP=y CONFIG_PPP=y CONFIG_PPPOL2TP=y CONFIG_PPPOL2TP=y CONFIG_PPP_ASYNC=y CONFIG_PPP_ASYNC=y Loading arch/arm/configs/mdm_defconfig +2 −0 Original line number Original line Diff line number Diff line Loading @@ -213,6 +213,8 @@ CONFIG_RNDIS_IPA=y # CONFIG_NET_VENDOR_SEEQ is not set # CONFIG_NET_VENDOR_SEEQ is not set # CONFIG_NET_VENDOR_SMSC is not set # CONFIG_NET_VENDOR_SMSC is not set # CONFIG_NET_VENDOR_STMICRO is not set # CONFIG_NET_VENDOR_STMICRO is not set CONFIG_MICREL_PHY=y CONFIG_NXP_TJA110X_PHY=y CONFIG_PPP=y CONFIG_PPP=y CONFIG_PPPOL2TP=y CONFIG_PPPOL2TP=y CONFIG_PPP_ASYNC=y CONFIG_PPP_ASYNC=y Loading drivers/net/phy/Makefile +1 −0 Original line number Original line Diff line number Diff line Loading @@ -37,3 +37,4 @@ obj-$(CONFIG_AMD_XGBE_PHY) += amd-xgbe-phy.o obj-$(CONFIG_MDIO_BCM_UNIMAC) += mdio-bcm-unimac.o obj-$(CONFIG_MDIO_BCM_UNIMAC) += mdio-bcm-unimac.o obj-$(CONFIG_QCA8337_SWITCH) += qca8337.o obj-$(CONFIG_QCA8337_SWITCH) += qca8337.o obj-$(CONFIG_NXP_TJA1100_PHY) += nxp/ obj-$(CONFIG_NXP_TJA1100_PHY) += nxp/ obj-$(CONFIG_NXP_TJA110X_PHY) += nxp/ drivers/net/phy/nxp/nxp.c +144 −49 Original line number Original line Diff line number Diff line /* /* * Copyright (c) 2017 NXP * Copyright 2017 NXP * * * This program is free software; you can redistribute it and/or modify it * 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 * under the terms of the GNU General Public License as published by the Loading @@ -18,6 +18,14 @@ #include "nxp.h" #include "nxp.h" /* Variable can be modified via parameter passed at load time * A nonzero value indicates that we should operate in managed mode */ static int managed_mode; /* Permission: do not show up in sysfs */ module_param(managed_mode, int, 0000); MODULE_PARM_DESC(managed_mode, "Use PHY in managed or autonomous mode"); /* Called to initialize the PHY, /* Called to initialize the PHY, * including after a reset * including after a reset */ */ Loading Loading @@ -171,7 +179,7 @@ static int nxp_probe(struct phy_device *phydev) int err; int err; struct nxp_specific_data *nxp_specific; struct nxp_specific_data *nxp_specific; nxp_specific = kzalloc(sizeof(*nxp_specific_data), GFP_KERNEL); nxp_specific = kzalloc(sizeof(*nxp_specific), GFP_KERNEL); if (!nxp_specific) if (!nxp_specific) goto phy_allocation_error; goto phy_allocation_error; Loading Loading @@ -287,6 +295,21 @@ phy_write_error: return err; return err; } } /* handler for link changes * if interrupts would be used, this would be handled by phy_change() */ static inline void handle_link_changes(struct phy_device *phydev) { mutex_lock(&phydev->lock); if ((PHY_RUNNING == phydev->state) || (PHY_NOLINK == phydev->state)) phydev->state = PHY_CHANGELINK; mutex_unlock(&phydev->lock); /* reschedule state queue work to run as soon as possible */ cancel_delayed_work_sync(&phydev->state_queue); queue_delayed_work(system_power_efficient_wq, &phydev->state_queue, 0); } /* interrupt handler for pwon interrupts */ /* interrupt handler for pwon interrupts */ static inline void handle_pwon_interrupt(struct phy_device *phydev) static inline void handle_pwon_interrupt(struct phy_device *phydev) { { Loading Loading @@ -348,6 +371,7 @@ static void poll(struct work_struct *work) * - reinitialize after power down * - reinitialize after power down * - resume PHY after an external WAKEUP was received * - resume PHY after an external WAKEUP was received * - resume PHY after an undervoltage recovery * - resume PHY after an undervoltage recovery * - adjust state on link changes * - check for some PHY errors * - check for some PHY errors */ */ Loading @@ -360,6 +384,11 @@ static void poll(struct work_struct *work) else if (interrupts & INTERRUPT_WAKEUP) else if (interrupts & INTERRUPT_WAKEUP) phydev->drv->resume(phydev); phydev->drv->resume(phydev); /* link changes */ if (interrupts & INTERRUPT_LINK_STATUS_FAIL || interrupts & INTERRUPT_LINK_STATUS_UP) handle_link_changes(phydev); /* warnings */ /* warnings */ if (interrupts & INTERRUPT_PHY_INIT_FAIL) if (interrupts & INTERRUPT_PHY_INIT_FAIL) dev_err(&phydev->dev, "PHY initialization failed\n"); dev_err(&phydev->dev, "PHY initialization failed\n"); Loading @@ -385,10 +414,8 @@ static void poll(struct work_struct *work) /* helper function, waits until a given condition is met /* helper function, waits until a given condition is met * * * The function delays until the part of the register at reg_addr, * The function delays until the part of the register at reg_addr, * defined by reg_mask equals cond, or a timeout (timeout*DELAY_LENGTH) * defined by reg_mask equals cond, or a timeout (timeout*DELAY_LENGTH) occurs. * occurs. * @return 0 if condition is met, <0 if timeout or read error occurred * @return 0 if condition is met, <0 if timeout or read * error occurred */ */ static int wait_on_condition(struct phy_device *phydev, int reg_addr, static int wait_on_condition(struct phy_device *phydev, int reg_addr, int reg_mask, int cond, int timeout) int reg_mask, int cond, int timeout) Loading @@ -409,7 +436,7 @@ static int wait_on_condition(struct phy_device *phydev, int reg_addr, } } /* helper function, enables or disables link control */ /* helper function, enables or disables link control */ void set_link_control(struct phy_device *phydev, int enable_link_control) static void set_link_control(struct phy_device *phydev, int enable_link_control) { { int err; int err; Loading @@ -422,6 +449,7 @@ void set_link_control(struct phy_device *phydev, int enable_link_control) phy_configure_error: phy_configure_error: dev_err(&phydev->dev, "phy r/w error: setting link control failed\n"); dev_err(&phydev->dev, "phy r/w error: setting link control failed\n"); return; } } /* Helper function, configures phy as master or slave /* Helper function, configures phy as master or slave Loading @@ -430,7 +458,7 @@ phy_configure_error: * !=0: set to master * !=0: set to master * @return 0 on success, error code on failure * @return 0 on success, error code on failure */ */ int set_master_cfg(struct phy_device *phydev, int setMaster) static int set_master_cfg(struct phy_device *phydev, int setMaster) { { int err; int err; Loading Loading @@ -459,7 +487,7 @@ phy_configure_error: * @return ==0: is slave * @return ==0: is slave * !=0: is master * !=0: is master */ */ int get_master_cfg(struct phy_device *phydev) static int get_master_cfg(struct phy_device *phydev) { { int reg_val; int reg_val; Loading Loading @@ -546,7 +574,7 @@ phy_transition_error: } } /* wakes up the phy from sleep mode */ /* wakes up the phy from sleep mode */ static int nxp_wakeup(struct phy_device *phydev) static int wakeup_from_sleep(struct phy_device *phydev) { { int err; int err; unsigned long wakeup_delay; unsigned long wakeup_delay; Loading @@ -554,10 +582,6 @@ static int nxp_wakeup(struct phy_device *phydev) if (!managed_mode) if (!managed_mode) goto phy_auto_op_error; goto phy_auto_op_error; /* TJA1100 cannot be woken up via SMI */ if ((phydev->phy_id & NXP_PHY_ID_MASK) == NXP_PHY_ID_TJA1100) goto phy_no_SMI_wakeup; /* set power mode bits to standby mode */ /* set power mode bits to standby mode */ err = phy_configure_bits(phydev, MII_ECTRL, ECTRL_POWER_MODE, err = phy_configure_bits(phydev, MII_ECTRL, ECTRL_POWER_MODE, POWER_MODE_STANDBY); POWER_MODE_STANDBY); Loading @@ -581,7 +605,6 @@ static int nxp_wakeup(struct phy_device *phydev) GENSTAT_PLL_LOCKED, POWER_MODE_TIMEOUT); GENSTAT_PLL_LOCKED, POWER_MODE_TIMEOUT); if (err < 0) if (err < 0) goto phy_transition_error; goto phy_transition_error; /* if phy is configured as slave, also send a wakeup request /* if phy is configured as slave, also send a wakeup request * to master * to master */ */ Loading Loading @@ -636,15 +659,77 @@ phy_transition_error: dev_err(&phydev->dev, "power mode transition failed\n"); dev_err(&phydev->dev, "power mode transition failed\n"); return err; return err; phy_no_SMI_wakeup: dev_err(&phydev->dev, "cannot be woken up via SMI command\n"); return 0; unsupported_phy_error: unsupported_phy_error: dev_err(&phydev->dev, "unsupported phy, wakeup failed\n"); dev_err(&phydev->dev, "unsupported phy, wakeup failed\n"); return -1; return -1; } } /* send a wakeup request to the link partner */ static int wakeup_from_normal(struct phy_device *phydev) { int err; /* start sending bus wakeup signal */ err = phy_configure_bit(phydev, MII_ECTRL, ECTRL_WAKE_REQUEST, 1); if (err < 0) goto phy_configure_error; /* stop sending bus wakeup signal */ err = phy_configure_bit(phydev, MII_ECTRL, ECTRL_WAKE_REQUEST, 0); if (err < 0) goto phy_configure_error; return 0; /* error handling */ phy_configure_error: dev_err(&phydev->dev, "phy r/w error: wakeup_from_normal failed\n"); return err; } /* wake up phy if is in sleep mode, send wakeup request if in normal mode */ static int nxp_wakeup(struct phy_device *phydev) { int reg_val; int err = 0; reg_val = phy_read(phydev, MII_ECTRL); if (reg_val < 0) goto phy_read_error; reg_val &= ECTRL_POWER_MODE; switch (reg_val) { case POWER_MODE_NORMAL: err = wakeup_from_normal(phydev); break; case POWER_MODE_SLEEP: err = wakeup_from_sleep(phydev); break; case 0xffff & ECTRL_POWER_MODE: /* TJA1100 disables SMI during sleep */ goto phy_SMI_disabled; default: break; } if (err < 0) goto phy_configure_error; return 0; /* error handling */ phy_read_error: dev_err(&phydev->dev, "read error: nxp_wakeup failed\n"); return reg_val; phy_SMI_disabled: dev_err(&phydev->dev, "SMI interface disabled, cannot be woken up\n"); return 0; phy_configure_error: dev_err(&phydev->dev, "phy r/w error: wakeup_from_normal failed\n"); return err; } /* power mode transition to standby */ /* power mode transition to standby */ static int nxp_suspend(struct phy_device *phydev) static int nxp_suspend(struct phy_device *phydev) { { Loading Loading @@ -783,8 +868,7 @@ phy_configure_error: } } /* helper function, enables or disables loopback mode /* helper function, enables or disables loopback mode * @return 0 if loopback mode was configured, <0 on read or * @return 0 if loopback mode was configured, <0 on read or write error * write error */ */ static int set_loopback(struct phy_device *phydev, int enable_loopback) static int set_loopback(struct phy_device *phydev, int enable_loopback) { { Loading @@ -804,8 +888,7 @@ phy_configure_error: } } /* helper function, enters the loopback mode specified by lmode /* helper function, enters the loopback mode specified by lmode * @return 0 if loopback mode was entered, <0 on read or * @return 0 if loopback mode was entered, <0 on read or write error * write error */ */ static int enter_loopback_mode(struct phy_device *phydev, static int enter_loopback_mode(struct phy_device *phydev, enum loopback_mode lmode) enum loopback_mode lmode) Loading Loading @@ -916,7 +999,8 @@ phy_configure_error: return err; return err; } } /* This function handles read accesses to the node 'master_cfg' in sysfs /* This function handles read accesses to the node 'master_cfg' in * sysfs. * Depending on current configuration of the phy, the node reads * Depending on current configuration of the phy, the node reads * 'master' or 'slave' * 'master' or 'slave' */ */ Loading @@ -933,7 +1017,7 @@ static ssize_t sysfs_get_master_cfg(struct device *dev, is_master ? "master" : "slave"); is_master ? "master" : "slave"); } } /* This function handles write accesses to the node 'master_cfg' in sysfs /* This function handles write accesses to the node 'master_cfg' in sysfs. * Depending on the value written to it, the phy is configured as * Depending on the value written to it, the phy is configured as * master or slave * master or slave */ */ Loading Loading @@ -970,7 +1054,7 @@ phy_cfg_error: return err; return err; } } /* This function handles read accesses to the node 'power_cfg' in sysfs /* This function handles read accesses to the node 'power_cfg' in sysfs. * Reading the node returns the current power state * Reading the node returns the current power state */ */ static ssize_t sysfs_get_power_cfg(struct device *dev, static ssize_t sysfs_get_power_cfg(struct device *dev, Loading Loading @@ -1019,7 +1103,8 @@ phy_read_error: return reg_val; return reg_val; } } /* This function handles write accesses to the node 'power_cfg' in sysfs. /* This function handles write accesses to the node 'power_cfg' in * sysfs. * Depending on the value written to it, the phy enters a certain * Depending on the value written to it, the phy enters a certain * power state. * power state. */ */ Loading Loading @@ -1049,6 +1134,8 @@ static ssize_t sysfs_set_power_cfg(struct device *dev, case 3: case 3: err = nxp_wakeup(phydev); err = nxp_wakeup(phydev); break; break; default: break; } } if (err) if (err) Loading Loading @@ -1150,6 +1237,8 @@ static ssize_t sysfs_set_loopback_cfg(struct device *dev, case 3: case 3: err = enter_loopback_mode(phydev, REMOTE_LMODE); err = enter_loopback_mode(phydev, REMOTE_LMODE); break; break; default: break; } } if (err) if (err) Loading Loading @@ -1342,6 +1431,8 @@ static ssize_t sysfs_set_test_mode(struct device *dev, set_link_control(phydev, 0); set_link_control(phydev, 0); err = enter_test_mode(phydev, TMODE6); err = enter_test_mode(phydev, TMODE6); break; break; default: break; } } if (err) if (err) Loading @@ -1363,7 +1454,7 @@ phy_tmode_transit_error: return err; return err; } } /* This function handles read accesses to the node 'led_cfg' in sysfs /* This function handles read accesses to the node 'led_cfg' in sysfs. * Reading the node returns the current led configuration * Reading the node returns the current led configuration */ */ static ssize_t sysfs_get_led_cfg(struct device *dev, static ssize_t sysfs_get_led_cfg(struct device *dev, Loading Loading @@ -1413,7 +1504,7 @@ phy_read_error: return reg_val; return reg_val; } } /* This function handles write accesses to the node 'led_cfg' in sysfs. /* This function handles write accesses to the node 'led_cfg' in sysfs * Depending on the value written to it, the led mode is configured * Depending on the value written to it, the led mode is configured * accordingly. * accordingly. */ */ Loading Loading @@ -1446,6 +1537,8 @@ static ssize_t sysfs_set_led_cfg(struct device *dev, case 4: case 4: err = enter_led_mode(phydev, CRSSIG_LED_MODE); err = enter_led_mode(phydev, CRSSIG_LED_MODE); break; break; default: break; } } if (err) if (err) Loading Loading @@ -1523,12 +1616,13 @@ static ssize_t sysfs_get_wakeup_cfg(struct device *dev, if (reg_val < 0) if (reg_val < 0) goto phy_read_error; goto phy_read_error; if (reg_val & TJA1100_CFG1_LED_EN) if (reg_val & TJA1100_CFG1_LED_EN) { locwuphy_en = 0; locwuphy_en = 0; fwdphyrem_en = 0; fwdphyrem_en = 0; else } else { locwuphy_en = 1; locwuphy_en = 1; fwdphyrem_en = 1; fwdphyrem_en = 1; } } else { } else { goto unsupported_phy_error; goto unsupported_phy_error; } } Loading Loading @@ -1607,7 +1701,7 @@ static ssize_t sysfs_set_wakeup_cfg(struct device *dev, (wakeup_cfg & SYSFS_FWDPHYREM)) || (wakeup_cfg & SYSFS_FWDPHYREM)) || wakeup_cfg & SYSFS_FWDPHYLOC || wakeup_cfg & SYSFS_FWDPHYLOC || !(wakeup_cfg & SYSFS_REMWUPHY)) { !(wakeup_cfg & SYSFS_REMWUPHY)) { dev_alert("Invalid configuration\n"); dev_alert(&phydev->dev, "Invalid configuration\n"); } else if (wakeup_cfg & SYSFS_LOCWUPHY && } else if (wakeup_cfg & SYSFS_LOCWUPHY && wakeup_cfg & SYSFS_FWDPHYREM) { wakeup_cfg & SYSFS_FWDPHYREM) { err = enter_led_mode(phydev, NO_LED_MODE); err = enter_led_mode(phydev, NO_LED_MODE); Loading Loading @@ -1670,10 +1764,10 @@ static struct attribute_group nxp_attribute_group = { * The function sets the bit of register reg_name, * The function sets the bit of register reg_name, * defined by bit_mask to 0 if (bit_value == 0), else to 1 * defined by bit_mask to 0 if (bit_value == 0), else to 1 * @return 0 if configuration completed, <0 if read/write * @return 0 if configuration completed, <0 if read/write error occurred * error occurred */ */ static inline int phy_configure_bit(struct phy_device *phydev, static inline int phy_configure_bit(struct phy_device *phydev, int reg_name, int reg_name, int bit_mask, int bit_value) int bit_mask, int bit_value) { { int reg_val, err; int reg_val, err; Loading Loading @@ -1707,10 +1801,10 @@ phy_write_error: * The function sets the bits of register reg_name, * The function sets the bits of register reg_name, * defined by bit_mask to bit_value * defined by bit_mask to bit_value * @return 0 if configuration completed, <0 if read/write * @return 0 if configuration completed, <0 if read/write error occurred * error occurred */ */ static inline int phy_configure_bits(struct phy_device *phydev, static inline int phy_configure_bits(struct phy_device *phydev, int reg_name, int reg_name, int bit_mask, int bit_value) int bit_mask, int bit_value) { { int reg_val, err; int reg_val, err; Loading Loading @@ -1853,7 +1947,8 @@ static struct phy_device *search_mdio_by_id(struct mii_bus *bus, int phy_id) if (bus->phy_map[addr]) { if (bus->phy_map[addr]) { phydev = bus->phy_map[addr]; phydev = bus->phy_map[addr]; if ((phydev->phy_id & NXP_PHY_ID_MASK) == phy_id) { if ((phydev->phy_id & NXP_PHY_ID_MASK) == phy_id) { dev_alert("found the given phy\n"); pr_alert("found the given phy\n"); return phydev; return phydev; } } } } Loading Loading @@ -1904,13 +1999,13 @@ static int TJA1102p1_fixup_register(void) /* check if the fixup drv is already loaded */ /* check if the fixup drv is already loaded */ drv = driver_find("TJA1102_p1", phydev->dev.bus); drv = driver_find("TJA1102_p1", phydev->dev.bus); if (drv) { if (drv) { dev_alert("fixup driver already loaded\n"); dev_alert(&phydev->dev, "fixup driver already loaded\n"); } else { } else { err = phy_driver_register(&nxp_TJA1102p1_fixup_driver); err = phy_driver_register(&nxp_TJA1102p1_fixup_driver); if (err) if (err) goto drv_registration_error; goto drv_registration_error; dev_alert("Successfully registered fixup: %s\n", pr_alert("Successfully registered fixup: %s\n", nxp_TJA1102p1_fixup_driver.name); nxp_TJA1102p1_fixup_driver.name); } } Loading Loading @@ -1938,7 +2033,7 @@ static void unregister_TJA1102p1_fixup(void) /* check if the fixup drv was previously loaded */ /* check if the fixup drv was previously loaded */ drv = driver_find("TJA1102_p1", phydev->dev.bus); drv = driver_find("TJA1102_p1", phydev->dev.bus); if (drv) { if (drv) { dev_alert("unloading fixup driver\n"); dev_alert(&phydev->dev, "unloading fixup driver\n"); phy_driver_unregister(&nxp_TJA1102p1_fixup_driver); phy_driver_unregister(&nxp_TJA1102p1_fixup_driver); } } } } Loading @@ -1948,7 +2043,7 @@ static int __init nxp_init(void) { { int err; int err; dev_alert("loading NXP PHY driver: [%s]\n", pr_alert("loading NXP PHY driver: [%s]\n", (managed_mode ? "managed mode" : "autonomous mode")); (managed_mode ? "managed mode" : "autonomous mode")); err = phy_drivers_register(nxp_drivers, ARRAY_SIZE(nxp_drivers)); err = phy_drivers_register(nxp_drivers, ARRAY_SIZE(nxp_drivers)); Loading @@ -1963,7 +2058,7 @@ static int __init nxp_init(void) /* error handling */ /* error handling */ drv_registration_error: drv_registration_error: dev_err("NXP PHY: driver registration failed\n"); pr_err("NXP PHY: driver registration failed\n"); return err; return err; } } Loading @@ -1972,7 +2067,7 @@ module_init(nxp_init); /* module exit function */ /* module exit function */ static void __exit nxp_exit(void) static void __exit nxp_exit(void) { { dev_alert("unloading NXP PHY driver\n"); pr_alert("unloading NXP PHY driver\n"); unregister_TJA1102p1_fixup(); unregister_TJA1102p1_fixup(); phy_drivers_unregister(nxp_drivers, ARRAY_SIZE(nxp_drivers)); phy_drivers_unregister(nxp_drivers, ARRAY_SIZE(nxp_drivers)); } } Loading drivers/net/phy/nxp/nxp.h +6 −13 Original line number Original line Diff line number Diff line /* /* * Copyright (c) 2017 NXP * Copyright 2017 NXP * * * This program is free software; you can redistribute it and/or modify it * 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 * under the terms of the GNU General Public License as published by the Loading Loading @@ -156,7 +156,7 @@ #define EXTSTAT_OPEN_DETECT BIT(7) #define EXTSTAT_OPEN_DETECT BIT(7) #define EXTSTAT_SHORT_DETECT BIT(8) #define EXTSTAT_SHORT_DETECT BIT(8) /** /* * Indicator for BRR support in ESTATUS register * Indicator for BRR support in ESTATUS register * and in phydev->supported member. * and in phydev->supported member. * Not yet present in include/uapi/linux/mii.h and * Not yet present in include/uapi/linux/mii.h and Loading Loading @@ -235,22 +235,15 @@ struct nxp_specific_data { int poll_setup; int poll_setup; }; }; /* Variable can be modified via parameter passed at load time * A nonzero value indicates that we should operate in managed mode */ static int managed_mode; /* Permission: do not show up in sysfs */ module_param(managed_mode, int, 0000); MODULE_PARM_DESC(managed_mode, "Use PHY in managed or autonomous mode"); /* Helper Function prototypes */ /* Helper Function prototypes */ int set_master_cfg(struct phy_device *phydev, int setMaster); static int set_master_cfg(struct phy_device *phydev, int setMaster); int get_master_cfg(struct phy_device *phydev); static int get_master_cfg(struct phy_device *phydev); static struct phy_device *search_phy_by_id(int phy_id); static struct phy_device *search_phy_by_id(int phy_id); static struct phy_device *search_phy_by_addr(int phy_id); static struct phy_device *search_phy_by_addr(int phy_id); static int wait_on_condition(struct phy_device *phydev, int reg_addr, static int wait_on_condition(struct phy_device *phydev, int reg_addr, int reg_mask, int cond, int timeout); int reg_mask, int cond, int timeout); void set_link_control(struct phy_device *phydev, int enable_link_control); static void set_link_control(struct phy_device *phydev, int enable_link_control); static inline int phy_configure_bit(struct phy_device *phydev, static inline int phy_configure_bit(struct phy_device *phydev, int reg_name, int bit_mask, int reg_name, int bit_mask, int bit_value); int bit_value); Loading Loading
arch/arm/configs/mdm-perf_defconfig +2 −0 Original line number Original line Diff line number Diff line Loading @@ -213,6 +213,8 @@ CONFIG_RNDIS_IPA=y # CONFIG_NET_VENDOR_SEEQ is not set # CONFIG_NET_VENDOR_SEEQ is not set # CONFIG_NET_VENDOR_SMSC is not set # CONFIG_NET_VENDOR_SMSC is not set # CONFIG_NET_VENDOR_STMICRO is not set # CONFIG_NET_VENDOR_STMICRO is not set CONFIG_MICREL_PHY=y CONFIG_NXP_TJA110X_PHY=y CONFIG_PPP=y CONFIG_PPP=y CONFIG_PPPOL2TP=y CONFIG_PPPOL2TP=y CONFIG_PPP_ASYNC=y CONFIG_PPP_ASYNC=y Loading
arch/arm/configs/mdm_defconfig +2 −0 Original line number Original line Diff line number Diff line Loading @@ -213,6 +213,8 @@ CONFIG_RNDIS_IPA=y # CONFIG_NET_VENDOR_SEEQ is not set # CONFIG_NET_VENDOR_SEEQ is not set # CONFIG_NET_VENDOR_SMSC is not set # CONFIG_NET_VENDOR_SMSC is not set # CONFIG_NET_VENDOR_STMICRO is not set # CONFIG_NET_VENDOR_STMICRO is not set CONFIG_MICREL_PHY=y CONFIG_NXP_TJA110X_PHY=y CONFIG_PPP=y CONFIG_PPP=y CONFIG_PPPOL2TP=y CONFIG_PPPOL2TP=y CONFIG_PPP_ASYNC=y CONFIG_PPP_ASYNC=y Loading
drivers/net/phy/Makefile +1 −0 Original line number Original line Diff line number Diff line Loading @@ -37,3 +37,4 @@ obj-$(CONFIG_AMD_XGBE_PHY) += amd-xgbe-phy.o obj-$(CONFIG_MDIO_BCM_UNIMAC) += mdio-bcm-unimac.o obj-$(CONFIG_MDIO_BCM_UNIMAC) += mdio-bcm-unimac.o obj-$(CONFIG_QCA8337_SWITCH) += qca8337.o obj-$(CONFIG_QCA8337_SWITCH) += qca8337.o obj-$(CONFIG_NXP_TJA1100_PHY) += nxp/ obj-$(CONFIG_NXP_TJA1100_PHY) += nxp/ obj-$(CONFIG_NXP_TJA110X_PHY) += nxp/
drivers/net/phy/nxp/nxp.c +144 −49 Original line number Original line Diff line number Diff line /* /* * Copyright (c) 2017 NXP * Copyright 2017 NXP * * * This program is free software; you can redistribute it and/or modify it * 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 * under the terms of the GNU General Public License as published by the Loading @@ -18,6 +18,14 @@ #include "nxp.h" #include "nxp.h" /* Variable can be modified via parameter passed at load time * A nonzero value indicates that we should operate in managed mode */ static int managed_mode; /* Permission: do not show up in sysfs */ module_param(managed_mode, int, 0000); MODULE_PARM_DESC(managed_mode, "Use PHY in managed or autonomous mode"); /* Called to initialize the PHY, /* Called to initialize the PHY, * including after a reset * including after a reset */ */ Loading Loading @@ -171,7 +179,7 @@ static int nxp_probe(struct phy_device *phydev) int err; int err; struct nxp_specific_data *nxp_specific; struct nxp_specific_data *nxp_specific; nxp_specific = kzalloc(sizeof(*nxp_specific_data), GFP_KERNEL); nxp_specific = kzalloc(sizeof(*nxp_specific), GFP_KERNEL); if (!nxp_specific) if (!nxp_specific) goto phy_allocation_error; goto phy_allocation_error; Loading Loading @@ -287,6 +295,21 @@ phy_write_error: return err; return err; } } /* handler for link changes * if interrupts would be used, this would be handled by phy_change() */ static inline void handle_link_changes(struct phy_device *phydev) { mutex_lock(&phydev->lock); if ((PHY_RUNNING == phydev->state) || (PHY_NOLINK == phydev->state)) phydev->state = PHY_CHANGELINK; mutex_unlock(&phydev->lock); /* reschedule state queue work to run as soon as possible */ cancel_delayed_work_sync(&phydev->state_queue); queue_delayed_work(system_power_efficient_wq, &phydev->state_queue, 0); } /* interrupt handler for pwon interrupts */ /* interrupt handler for pwon interrupts */ static inline void handle_pwon_interrupt(struct phy_device *phydev) static inline void handle_pwon_interrupt(struct phy_device *phydev) { { Loading Loading @@ -348,6 +371,7 @@ static void poll(struct work_struct *work) * - reinitialize after power down * - reinitialize after power down * - resume PHY after an external WAKEUP was received * - resume PHY after an external WAKEUP was received * - resume PHY after an undervoltage recovery * - resume PHY after an undervoltage recovery * - adjust state on link changes * - check for some PHY errors * - check for some PHY errors */ */ Loading @@ -360,6 +384,11 @@ static void poll(struct work_struct *work) else if (interrupts & INTERRUPT_WAKEUP) else if (interrupts & INTERRUPT_WAKEUP) phydev->drv->resume(phydev); phydev->drv->resume(phydev); /* link changes */ if (interrupts & INTERRUPT_LINK_STATUS_FAIL || interrupts & INTERRUPT_LINK_STATUS_UP) handle_link_changes(phydev); /* warnings */ /* warnings */ if (interrupts & INTERRUPT_PHY_INIT_FAIL) if (interrupts & INTERRUPT_PHY_INIT_FAIL) dev_err(&phydev->dev, "PHY initialization failed\n"); dev_err(&phydev->dev, "PHY initialization failed\n"); Loading @@ -385,10 +414,8 @@ static void poll(struct work_struct *work) /* helper function, waits until a given condition is met /* helper function, waits until a given condition is met * * * The function delays until the part of the register at reg_addr, * The function delays until the part of the register at reg_addr, * defined by reg_mask equals cond, or a timeout (timeout*DELAY_LENGTH) * defined by reg_mask equals cond, or a timeout (timeout*DELAY_LENGTH) occurs. * occurs. * @return 0 if condition is met, <0 if timeout or read error occurred * @return 0 if condition is met, <0 if timeout or read * error occurred */ */ static int wait_on_condition(struct phy_device *phydev, int reg_addr, static int wait_on_condition(struct phy_device *phydev, int reg_addr, int reg_mask, int cond, int timeout) int reg_mask, int cond, int timeout) Loading @@ -409,7 +436,7 @@ static int wait_on_condition(struct phy_device *phydev, int reg_addr, } } /* helper function, enables or disables link control */ /* helper function, enables or disables link control */ void set_link_control(struct phy_device *phydev, int enable_link_control) static void set_link_control(struct phy_device *phydev, int enable_link_control) { { int err; int err; Loading @@ -422,6 +449,7 @@ void set_link_control(struct phy_device *phydev, int enable_link_control) phy_configure_error: phy_configure_error: dev_err(&phydev->dev, "phy r/w error: setting link control failed\n"); dev_err(&phydev->dev, "phy r/w error: setting link control failed\n"); return; } } /* Helper function, configures phy as master or slave /* Helper function, configures phy as master or slave Loading @@ -430,7 +458,7 @@ phy_configure_error: * !=0: set to master * !=0: set to master * @return 0 on success, error code on failure * @return 0 on success, error code on failure */ */ int set_master_cfg(struct phy_device *phydev, int setMaster) static int set_master_cfg(struct phy_device *phydev, int setMaster) { { int err; int err; Loading Loading @@ -459,7 +487,7 @@ phy_configure_error: * @return ==0: is slave * @return ==0: is slave * !=0: is master * !=0: is master */ */ int get_master_cfg(struct phy_device *phydev) static int get_master_cfg(struct phy_device *phydev) { { int reg_val; int reg_val; Loading Loading @@ -546,7 +574,7 @@ phy_transition_error: } } /* wakes up the phy from sleep mode */ /* wakes up the phy from sleep mode */ static int nxp_wakeup(struct phy_device *phydev) static int wakeup_from_sleep(struct phy_device *phydev) { { int err; int err; unsigned long wakeup_delay; unsigned long wakeup_delay; Loading @@ -554,10 +582,6 @@ static int nxp_wakeup(struct phy_device *phydev) if (!managed_mode) if (!managed_mode) goto phy_auto_op_error; goto phy_auto_op_error; /* TJA1100 cannot be woken up via SMI */ if ((phydev->phy_id & NXP_PHY_ID_MASK) == NXP_PHY_ID_TJA1100) goto phy_no_SMI_wakeup; /* set power mode bits to standby mode */ /* set power mode bits to standby mode */ err = phy_configure_bits(phydev, MII_ECTRL, ECTRL_POWER_MODE, err = phy_configure_bits(phydev, MII_ECTRL, ECTRL_POWER_MODE, POWER_MODE_STANDBY); POWER_MODE_STANDBY); Loading @@ -581,7 +605,6 @@ static int nxp_wakeup(struct phy_device *phydev) GENSTAT_PLL_LOCKED, POWER_MODE_TIMEOUT); GENSTAT_PLL_LOCKED, POWER_MODE_TIMEOUT); if (err < 0) if (err < 0) goto phy_transition_error; goto phy_transition_error; /* if phy is configured as slave, also send a wakeup request /* if phy is configured as slave, also send a wakeup request * to master * to master */ */ Loading Loading @@ -636,15 +659,77 @@ phy_transition_error: dev_err(&phydev->dev, "power mode transition failed\n"); dev_err(&phydev->dev, "power mode transition failed\n"); return err; return err; phy_no_SMI_wakeup: dev_err(&phydev->dev, "cannot be woken up via SMI command\n"); return 0; unsupported_phy_error: unsupported_phy_error: dev_err(&phydev->dev, "unsupported phy, wakeup failed\n"); dev_err(&phydev->dev, "unsupported phy, wakeup failed\n"); return -1; return -1; } } /* send a wakeup request to the link partner */ static int wakeup_from_normal(struct phy_device *phydev) { int err; /* start sending bus wakeup signal */ err = phy_configure_bit(phydev, MII_ECTRL, ECTRL_WAKE_REQUEST, 1); if (err < 0) goto phy_configure_error; /* stop sending bus wakeup signal */ err = phy_configure_bit(phydev, MII_ECTRL, ECTRL_WAKE_REQUEST, 0); if (err < 0) goto phy_configure_error; return 0; /* error handling */ phy_configure_error: dev_err(&phydev->dev, "phy r/w error: wakeup_from_normal failed\n"); return err; } /* wake up phy if is in sleep mode, send wakeup request if in normal mode */ static int nxp_wakeup(struct phy_device *phydev) { int reg_val; int err = 0; reg_val = phy_read(phydev, MII_ECTRL); if (reg_val < 0) goto phy_read_error; reg_val &= ECTRL_POWER_MODE; switch (reg_val) { case POWER_MODE_NORMAL: err = wakeup_from_normal(phydev); break; case POWER_MODE_SLEEP: err = wakeup_from_sleep(phydev); break; case 0xffff & ECTRL_POWER_MODE: /* TJA1100 disables SMI during sleep */ goto phy_SMI_disabled; default: break; } if (err < 0) goto phy_configure_error; return 0; /* error handling */ phy_read_error: dev_err(&phydev->dev, "read error: nxp_wakeup failed\n"); return reg_val; phy_SMI_disabled: dev_err(&phydev->dev, "SMI interface disabled, cannot be woken up\n"); return 0; phy_configure_error: dev_err(&phydev->dev, "phy r/w error: wakeup_from_normal failed\n"); return err; } /* power mode transition to standby */ /* power mode transition to standby */ static int nxp_suspend(struct phy_device *phydev) static int nxp_suspend(struct phy_device *phydev) { { Loading Loading @@ -783,8 +868,7 @@ phy_configure_error: } } /* helper function, enables or disables loopback mode /* helper function, enables or disables loopback mode * @return 0 if loopback mode was configured, <0 on read or * @return 0 if loopback mode was configured, <0 on read or write error * write error */ */ static int set_loopback(struct phy_device *phydev, int enable_loopback) static int set_loopback(struct phy_device *phydev, int enable_loopback) { { Loading @@ -804,8 +888,7 @@ phy_configure_error: } } /* helper function, enters the loopback mode specified by lmode /* helper function, enters the loopback mode specified by lmode * @return 0 if loopback mode was entered, <0 on read or * @return 0 if loopback mode was entered, <0 on read or write error * write error */ */ static int enter_loopback_mode(struct phy_device *phydev, static int enter_loopback_mode(struct phy_device *phydev, enum loopback_mode lmode) enum loopback_mode lmode) Loading Loading @@ -916,7 +999,8 @@ phy_configure_error: return err; return err; } } /* This function handles read accesses to the node 'master_cfg' in sysfs /* This function handles read accesses to the node 'master_cfg' in * sysfs. * Depending on current configuration of the phy, the node reads * Depending on current configuration of the phy, the node reads * 'master' or 'slave' * 'master' or 'slave' */ */ Loading @@ -933,7 +1017,7 @@ static ssize_t sysfs_get_master_cfg(struct device *dev, is_master ? "master" : "slave"); is_master ? "master" : "slave"); } } /* This function handles write accesses to the node 'master_cfg' in sysfs /* This function handles write accesses to the node 'master_cfg' in sysfs. * Depending on the value written to it, the phy is configured as * Depending on the value written to it, the phy is configured as * master or slave * master or slave */ */ Loading Loading @@ -970,7 +1054,7 @@ phy_cfg_error: return err; return err; } } /* This function handles read accesses to the node 'power_cfg' in sysfs /* This function handles read accesses to the node 'power_cfg' in sysfs. * Reading the node returns the current power state * Reading the node returns the current power state */ */ static ssize_t sysfs_get_power_cfg(struct device *dev, static ssize_t sysfs_get_power_cfg(struct device *dev, Loading Loading @@ -1019,7 +1103,8 @@ phy_read_error: return reg_val; return reg_val; } } /* This function handles write accesses to the node 'power_cfg' in sysfs. /* This function handles write accesses to the node 'power_cfg' in * sysfs. * Depending on the value written to it, the phy enters a certain * Depending on the value written to it, the phy enters a certain * power state. * power state. */ */ Loading Loading @@ -1049,6 +1134,8 @@ static ssize_t sysfs_set_power_cfg(struct device *dev, case 3: case 3: err = nxp_wakeup(phydev); err = nxp_wakeup(phydev); break; break; default: break; } } if (err) if (err) Loading Loading @@ -1150,6 +1237,8 @@ static ssize_t sysfs_set_loopback_cfg(struct device *dev, case 3: case 3: err = enter_loopback_mode(phydev, REMOTE_LMODE); err = enter_loopback_mode(phydev, REMOTE_LMODE); break; break; default: break; } } if (err) if (err) Loading Loading @@ -1342,6 +1431,8 @@ static ssize_t sysfs_set_test_mode(struct device *dev, set_link_control(phydev, 0); set_link_control(phydev, 0); err = enter_test_mode(phydev, TMODE6); err = enter_test_mode(phydev, TMODE6); break; break; default: break; } } if (err) if (err) Loading @@ -1363,7 +1454,7 @@ phy_tmode_transit_error: return err; return err; } } /* This function handles read accesses to the node 'led_cfg' in sysfs /* This function handles read accesses to the node 'led_cfg' in sysfs. * Reading the node returns the current led configuration * Reading the node returns the current led configuration */ */ static ssize_t sysfs_get_led_cfg(struct device *dev, static ssize_t sysfs_get_led_cfg(struct device *dev, Loading Loading @@ -1413,7 +1504,7 @@ phy_read_error: return reg_val; return reg_val; } } /* This function handles write accesses to the node 'led_cfg' in sysfs. /* This function handles write accesses to the node 'led_cfg' in sysfs * Depending on the value written to it, the led mode is configured * Depending on the value written to it, the led mode is configured * accordingly. * accordingly. */ */ Loading Loading @@ -1446,6 +1537,8 @@ static ssize_t sysfs_set_led_cfg(struct device *dev, case 4: case 4: err = enter_led_mode(phydev, CRSSIG_LED_MODE); err = enter_led_mode(phydev, CRSSIG_LED_MODE); break; break; default: break; } } if (err) if (err) Loading Loading @@ -1523,12 +1616,13 @@ static ssize_t sysfs_get_wakeup_cfg(struct device *dev, if (reg_val < 0) if (reg_val < 0) goto phy_read_error; goto phy_read_error; if (reg_val & TJA1100_CFG1_LED_EN) if (reg_val & TJA1100_CFG1_LED_EN) { locwuphy_en = 0; locwuphy_en = 0; fwdphyrem_en = 0; fwdphyrem_en = 0; else } else { locwuphy_en = 1; locwuphy_en = 1; fwdphyrem_en = 1; fwdphyrem_en = 1; } } else { } else { goto unsupported_phy_error; goto unsupported_phy_error; } } Loading Loading @@ -1607,7 +1701,7 @@ static ssize_t sysfs_set_wakeup_cfg(struct device *dev, (wakeup_cfg & SYSFS_FWDPHYREM)) || (wakeup_cfg & SYSFS_FWDPHYREM)) || wakeup_cfg & SYSFS_FWDPHYLOC || wakeup_cfg & SYSFS_FWDPHYLOC || !(wakeup_cfg & SYSFS_REMWUPHY)) { !(wakeup_cfg & SYSFS_REMWUPHY)) { dev_alert("Invalid configuration\n"); dev_alert(&phydev->dev, "Invalid configuration\n"); } else if (wakeup_cfg & SYSFS_LOCWUPHY && } else if (wakeup_cfg & SYSFS_LOCWUPHY && wakeup_cfg & SYSFS_FWDPHYREM) { wakeup_cfg & SYSFS_FWDPHYREM) { err = enter_led_mode(phydev, NO_LED_MODE); err = enter_led_mode(phydev, NO_LED_MODE); Loading Loading @@ -1670,10 +1764,10 @@ static struct attribute_group nxp_attribute_group = { * The function sets the bit of register reg_name, * The function sets the bit of register reg_name, * defined by bit_mask to 0 if (bit_value == 0), else to 1 * defined by bit_mask to 0 if (bit_value == 0), else to 1 * @return 0 if configuration completed, <0 if read/write * @return 0 if configuration completed, <0 if read/write error occurred * error occurred */ */ static inline int phy_configure_bit(struct phy_device *phydev, static inline int phy_configure_bit(struct phy_device *phydev, int reg_name, int reg_name, int bit_mask, int bit_value) int bit_mask, int bit_value) { { int reg_val, err; int reg_val, err; Loading Loading @@ -1707,10 +1801,10 @@ phy_write_error: * The function sets the bits of register reg_name, * The function sets the bits of register reg_name, * defined by bit_mask to bit_value * defined by bit_mask to bit_value * @return 0 if configuration completed, <0 if read/write * @return 0 if configuration completed, <0 if read/write error occurred * error occurred */ */ static inline int phy_configure_bits(struct phy_device *phydev, static inline int phy_configure_bits(struct phy_device *phydev, int reg_name, int reg_name, int bit_mask, int bit_value) int bit_mask, int bit_value) { { int reg_val, err; int reg_val, err; Loading Loading @@ -1853,7 +1947,8 @@ static struct phy_device *search_mdio_by_id(struct mii_bus *bus, int phy_id) if (bus->phy_map[addr]) { if (bus->phy_map[addr]) { phydev = bus->phy_map[addr]; phydev = bus->phy_map[addr]; if ((phydev->phy_id & NXP_PHY_ID_MASK) == phy_id) { if ((phydev->phy_id & NXP_PHY_ID_MASK) == phy_id) { dev_alert("found the given phy\n"); pr_alert("found the given phy\n"); return phydev; return phydev; } } } } Loading Loading @@ -1904,13 +1999,13 @@ static int TJA1102p1_fixup_register(void) /* check if the fixup drv is already loaded */ /* check if the fixup drv is already loaded */ drv = driver_find("TJA1102_p1", phydev->dev.bus); drv = driver_find("TJA1102_p1", phydev->dev.bus); if (drv) { if (drv) { dev_alert("fixup driver already loaded\n"); dev_alert(&phydev->dev, "fixup driver already loaded\n"); } else { } else { err = phy_driver_register(&nxp_TJA1102p1_fixup_driver); err = phy_driver_register(&nxp_TJA1102p1_fixup_driver); if (err) if (err) goto drv_registration_error; goto drv_registration_error; dev_alert("Successfully registered fixup: %s\n", pr_alert("Successfully registered fixup: %s\n", nxp_TJA1102p1_fixup_driver.name); nxp_TJA1102p1_fixup_driver.name); } } Loading Loading @@ -1938,7 +2033,7 @@ static void unregister_TJA1102p1_fixup(void) /* check if the fixup drv was previously loaded */ /* check if the fixup drv was previously loaded */ drv = driver_find("TJA1102_p1", phydev->dev.bus); drv = driver_find("TJA1102_p1", phydev->dev.bus); if (drv) { if (drv) { dev_alert("unloading fixup driver\n"); dev_alert(&phydev->dev, "unloading fixup driver\n"); phy_driver_unregister(&nxp_TJA1102p1_fixup_driver); phy_driver_unregister(&nxp_TJA1102p1_fixup_driver); } } } } Loading @@ -1948,7 +2043,7 @@ static int __init nxp_init(void) { { int err; int err; dev_alert("loading NXP PHY driver: [%s]\n", pr_alert("loading NXP PHY driver: [%s]\n", (managed_mode ? "managed mode" : "autonomous mode")); (managed_mode ? "managed mode" : "autonomous mode")); err = phy_drivers_register(nxp_drivers, ARRAY_SIZE(nxp_drivers)); err = phy_drivers_register(nxp_drivers, ARRAY_SIZE(nxp_drivers)); Loading @@ -1963,7 +2058,7 @@ static int __init nxp_init(void) /* error handling */ /* error handling */ drv_registration_error: drv_registration_error: dev_err("NXP PHY: driver registration failed\n"); pr_err("NXP PHY: driver registration failed\n"); return err; return err; } } Loading @@ -1972,7 +2067,7 @@ module_init(nxp_init); /* module exit function */ /* module exit function */ static void __exit nxp_exit(void) static void __exit nxp_exit(void) { { dev_alert("unloading NXP PHY driver\n"); pr_alert("unloading NXP PHY driver\n"); unregister_TJA1102p1_fixup(); unregister_TJA1102p1_fixup(); phy_drivers_unregister(nxp_drivers, ARRAY_SIZE(nxp_drivers)); phy_drivers_unregister(nxp_drivers, ARRAY_SIZE(nxp_drivers)); } } Loading
drivers/net/phy/nxp/nxp.h +6 −13 Original line number Original line Diff line number Diff line /* /* * Copyright (c) 2017 NXP * Copyright 2017 NXP * * * This program is free software; you can redistribute it and/or modify it * 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 * under the terms of the GNU General Public License as published by the Loading Loading @@ -156,7 +156,7 @@ #define EXTSTAT_OPEN_DETECT BIT(7) #define EXTSTAT_OPEN_DETECT BIT(7) #define EXTSTAT_SHORT_DETECT BIT(8) #define EXTSTAT_SHORT_DETECT BIT(8) /** /* * Indicator for BRR support in ESTATUS register * Indicator for BRR support in ESTATUS register * and in phydev->supported member. * and in phydev->supported member. * Not yet present in include/uapi/linux/mii.h and * Not yet present in include/uapi/linux/mii.h and Loading Loading @@ -235,22 +235,15 @@ struct nxp_specific_data { int poll_setup; int poll_setup; }; }; /* Variable can be modified via parameter passed at load time * A nonzero value indicates that we should operate in managed mode */ static int managed_mode; /* Permission: do not show up in sysfs */ module_param(managed_mode, int, 0000); MODULE_PARM_DESC(managed_mode, "Use PHY in managed or autonomous mode"); /* Helper Function prototypes */ /* Helper Function prototypes */ int set_master_cfg(struct phy_device *phydev, int setMaster); static int set_master_cfg(struct phy_device *phydev, int setMaster); int get_master_cfg(struct phy_device *phydev); static int get_master_cfg(struct phy_device *phydev); static struct phy_device *search_phy_by_id(int phy_id); static struct phy_device *search_phy_by_id(int phy_id); static struct phy_device *search_phy_by_addr(int phy_id); static struct phy_device *search_phy_by_addr(int phy_id); static int wait_on_condition(struct phy_device *phydev, int reg_addr, static int wait_on_condition(struct phy_device *phydev, int reg_addr, int reg_mask, int cond, int timeout); int reg_mask, int cond, int timeout); void set_link_control(struct phy_device *phydev, int enable_link_control); static void set_link_control(struct phy_device *phydev, int enable_link_control); static inline int phy_configure_bit(struct phy_device *phydev, static inline int phy_configure_bit(struct phy_device *phydev, int reg_name, int bit_mask, int reg_name, int bit_mask, int bit_value); int bit_value); Loading