Lines Matching refs:phydev
52 static void phy_link_up(struct phy_device *phydev) in phy_link_up() argument
54 phydev->phy_link_change(phydev, true, true); in phy_link_up()
55 phy_led_trigger_change_speed(phydev); in phy_link_up()
58 static void phy_link_down(struct phy_device *phydev, bool do_carrier) in phy_link_down() argument
60 phydev->phy_link_change(phydev, false, do_carrier); in phy_link_down()
61 phy_led_trigger_change_speed(phydev); in phy_link_down()
64 static const char *phy_pause_str(struct phy_device *phydev) in phy_pause_str() argument
68 if (phydev->autoneg == AUTONEG_DISABLE) in phy_pause_str()
72 phydev->advertising); in phy_pause_str()
74 phydev->advertising); in phy_pause_str()
76 if (local_pause && phydev->pause) in phy_pause_str()
79 if (local_asym_pause && phydev->asym_pause) { in phy_pause_str()
82 if (phydev->pause) in phy_pause_str()
94 void phy_print_status(struct phy_device *phydev) in phy_print_status() argument
96 if (phydev->link) { in phy_print_status()
97 netdev_info(phydev->attached_dev, in phy_print_status()
99 phy_speed_to_str(phydev->speed), in phy_print_status()
100 phy_duplex_to_str(phydev->duplex), in phy_print_status()
101 phy_pause_str(phydev)); in phy_print_status()
103 netdev_info(phydev->attached_dev, "Link is Down\n"); in phy_print_status()
117 static int phy_clear_interrupt(struct phy_device *phydev) in phy_clear_interrupt() argument
119 if (phydev->drv->ack_interrupt) in phy_clear_interrupt()
120 return phydev->drv->ack_interrupt(phydev); in phy_clear_interrupt()
132 static int phy_config_interrupt(struct phy_device *phydev, bool interrupts) in phy_config_interrupt() argument
134 phydev->interrupts = interrupts ? 1 : 0; in phy_config_interrupt()
135 if (phydev->drv->config_intr) in phy_config_interrupt()
136 return phydev->drv->config_intr(phydev); in phy_config_interrupt()
148 int phy_restart_aneg(struct phy_device *phydev) in phy_restart_aneg() argument
152 if (phydev->is_c45 && !(phydev->c45_ids.devices_in_package & BIT(0))) in phy_restart_aneg()
153 ret = genphy_c45_restart_aneg(phydev); in phy_restart_aneg()
155 ret = genphy_restart_aneg(phydev); in phy_restart_aneg()
169 int phy_aneg_done(struct phy_device *phydev) in phy_aneg_done() argument
171 if (phydev->drv && phydev->drv->aneg_done) in phy_aneg_done()
172 return phydev->drv->aneg_done(phydev); in phy_aneg_done()
173 else if (phydev->is_c45) in phy_aneg_done()
174 return genphy_c45_aneg_done(phydev); in phy_aneg_done()
176 return genphy_aneg_done(phydev); in phy_aneg_done()
239 static void phy_sanitize_settings(struct phy_device *phydev) in phy_sanitize_settings() argument
243 setting = phy_find_valid(phydev->speed, phydev->duplex, in phy_sanitize_settings()
244 phydev->supported); in phy_sanitize_settings()
246 phydev->speed = setting->speed; in phy_sanitize_settings()
247 phydev->duplex = setting->duplex; in phy_sanitize_settings()
250 phydev->speed = SPEED_UNKNOWN; in phy_sanitize_settings()
251 phydev->duplex = DUPLEX_UNKNOWN; in phy_sanitize_settings()
268 int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd) in phy_ethtool_sset() argument
273 if (cmd->phy_address != phydev->mdio.addr) in phy_ethtool_sset()
278 linkmode_and(advertising, advertising, phydev->supported); in phy_ethtool_sset()
295 phydev->autoneg = cmd->autoneg; in phy_ethtool_sset()
297 phydev->speed = speed; in phy_ethtool_sset()
299 linkmode_copy(phydev->advertising, advertising); in phy_ethtool_sset()
302 phydev->advertising, AUTONEG_ENABLE == cmd->autoneg); in phy_ethtool_sset()
304 phydev->duplex = cmd->duplex; in phy_ethtool_sset()
306 phydev->mdix_ctrl = cmd->eth_tp_mdix_ctrl; in phy_ethtool_sset()
309 phy_start_aneg(phydev); in phy_ethtool_sset()
315 int phy_ethtool_ksettings_set(struct phy_device *phydev, in phy_ethtool_ksettings_set() argument
323 if (cmd->base.phy_address != phydev->mdio.addr) in phy_ethtool_ksettings_set()
329 linkmode_and(advertising, advertising, phydev->supported); in phy_ethtool_ksettings_set()
346 phydev->autoneg = autoneg; in phy_ethtool_ksettings_set()
348 phydev->speed = speed; in phy_ethtool_ksettings_set()
350 linkmode_copy(phydev->advertising, advertising); in phy_ethtool_ksettings_set()
353 phydev->advertising, autoneg == AUTONEG_ENABLE); in phy_ethtool_ksettings_set()
355 phydev->duplex = duplex; in phy_ethtool_ksettings_set()
357 phydev->mdix_ctrl = cmd->base.eth_tp_mdix_ctrl; in phy_ethtool_ksettings_set()
360 phy_start_aneg(phydev); in phy_ethtool_ksettings_set()
366 void phy_ethtool_ksettings_get(struct phy_device *phydev, in phy_ethtool_ksettings_get() argument
369 linkmode_copy(cmd->link_modes.supported, phydev->supported); in phy_ethtool_ksettings_get()
370 linkmode_copy(cmd->link_modes.advertising, phydev->advertising); in phy_ethtool_ksettings_get()
371 linkmode_copy(cmd->link_modes.lp_advertising, phydev->lp_advertising); in phy_ethtool_ksettings_get()
373 cmd->base.speed = phydev->speed; in phy_ethtool_ksettings_get()
374 cmd->base.duplex = phydev->duplex; in phy_ethtool_ksettings_get()
375 if (phydev->interface == PHY_INTERFACE_MODE_MOCA) in phy_ethtool_ksettings_get()
379 cmd->base.transceiver = phy_is_internal(phydev) ? in phy_ethtool_ksettings_get()
381 cmd->base.phy_address = phydev->mdio.addr; in phy_ethtool_ksettings_get()
382 cmd->base.autoneg = phydev->autoneg; in phy_ethtool_ksettings_get()
383 cmd->base.eth_tp_mdix_ctrl = phydev->mdix_ctrl; in phy_ethtool_ksettings_get()
384 cmd->base.eth_tp_mdix = phydev->mdix; in phy_ethtool_ksettings_get()
398 int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd) in phy_mii_ioctl() argument
407 mii_data->phy_id = phydev->mdio.addr; in phy_mii_ioctl()
419 mii_data->val_out = mdiobus_read(phydev->mdio.bus, prtad, in phy_mii_ioctl()
432 if (prtad == phydev->mdio.addr) { in phy_mii_ioctl()
436 if (phydev->autoneg == AUTONEG_ENABLE) in phy_mii_ioctl()
438 phydev->autoneg = AUTONEG_DISABLE; in phy_mii_ioctl()
440 phydev->duplex = DUPLEX_FULL; in phy_mii_ioctl()
442 phydev->duplex = DUPLEX_HALF; in phy_mii_ioctl()
444 phydev->speed = SPEED_1000; in phy_mii_ioctl()
446 phydev->speed = SPEED_100; in phy_mii_ioctl()
447 else phydev->speed = SPEED_10; in phy_mii_ioctl()
450 if (phydev->autoneg == AUTONEG_DISABLE) in phy_mii_ioctl()
452 phydev->autoneg = AUTONEG_ENABLE; in phy_mii_ioctl()
456 mii_adv_mod_linkmode_adv_t(phydev->advertising, in phy_mii_ioctl()
461 mii_ctrl1000_mod_linkmode_adv_t(phydev->advertising, in phy_mii_ioctl()
471 mdiobus_write(phydev->mdio.bus, prtad, devad, val); in phy_mii_ioctl()
473 if (prtad == phydev->mdio.addr && in phy_mii_ioctl()
476 return phy_init_hw(phydev); in phy_mii_ioctl()
479 return phy_start_aneg(phydev); in phy_mii_ioctl()
484 if (phydev->drv && phydev->drv->hwtstamp) in phy_mii_ioctl()
485 return phydev->drv->hwtstamp(phydev, ifr); in phy_mii_ioctl()
494 void phy_queue_state_machine(struct phy_device *phydev, unsigned long jiffies) in phy_queue_state_machine() argument
496 mod_delayed_work(system_power_efficient_wq, &phydev->state_queue, in phy_queue_state_machine()
501 static void phy_trigger_machine(struct phy_device *phydev) in phy_trigger_machine() argument
503 phy_queue_state_machine(phydev, 0); in phy_trigger_machine()
506 static int phy_config_aneg(struct phy_device *phydev) in phy_config_aneg() argument
508 if (phydev->drv->config_aneg) in phy_config_aneg()
509 return phydev->drv->config_aneg(phydev); in phy_config_aneg()
514 if (phydev->is_c45 && !(phydev->c45_ids.devices_in_package & BIT(0))) in phy_config_aneg()
515 return genphy_c45_config_aneg(phydev); in phy_config_aneg()
517 return genphy_config_aneg(phydev); in phy_config_aneg()
527 static int phy_check_link_status(struct phy_device *phydev) in phy_check_link_status() argument
531 WARN_ON(!mutex_is_locked(&phydev->lock)); in phy_check_link_status()
536 if (phydev->loopback_enabled) in phy_check_link_status()
539 err = phy_read_status(phydev); in phy_check_link_status()
543 if (phydev->link && phydev->state != PHY_RUNNING) { in phy_check_link_status()
544 phydev->state = PHY_RUNNING; in phy_check_link_status()
545 phy_link_up(phydev); in phy_check_link_status()
546 } else if (!phydev->link && phydev->state != PHY_NOLINK) { in phy_check_link_status()
547 phydev->state = PHY_NOLINK; in phy_check_link_status()
548 phy_link_down(phydev, true); in phy_check_link_status()
563 int phy_start_aneg(struct phy_device *phydev) in phy_start_aneg() argument
567 if (!phydev->drv) in phy_start_aneg()
570 mutex_lock(&phydev->lock); in phy_start_aneg()
572 if (AUTONEG_DISABLE == phydev->autoneg) in phy_start_aneg()
573 phy_sanitize_settings(phydev); in phy_start_aneg()
575 err = phy_config_aneg(phydev); in phy_start_aneg()
579 if (phy_is_started(phydev)) in phy_start_aneg()
580 err = phy_check_link_status(phydev); in phy_start_aneg()
582 mutex_unlock(&phydev->lock); in phy_start_aneg()
588 static int phy_poll_aneg_done(struct phy_device *phydev) in phy_poll_aneg_done() argument
595 ret = phy_aneg_done(phydev); in phy_poll_aneg_done()
617 int phy_speed_down(struct phy_device *phydev, bool sync) in phy_speed_down() argument
622 if (phydev->autoneg != AUTONEG_ENABLE) in phy_speed_down()
625 linkmode_copy(adv_tmp, phydev->advertising); in phy_speed_down()
627 ret = phy_speed_down_core(phydev); in phy_speed_down()
631 linkmode_copy(phydev->adv_old, adv_tmp); in phy_speed_down()
633 if (linkmode_equal(phydev->advertising, adv_tmp)) in phy_speed_down()
636 ret = phy_config_aneg(phydev); in phy_speed_down()
640 return sync ? phy_poll_aneg_done(phydev) : 0; in phy_speed_down()
650 int phy_speed_up(struct phy_device *phydev) in phy_speed_up() argument
654 if (phydev->autoneg != AUTONEG_ENABLE) in phy_speed_up()
657 if (linkmode_empty(phydev->adv_old)) in phy_speed_up()
660 linkmode_copy(adv_tmp, phydev->advertising); in phy_speed_up()
661 linkmode_copy(phydev->advertising, phydev->adv_old); in phy_speed_up()
662 linkmode_zero(phydev->adv_old); in phy_speed_up()
664 if (linkmode_equal(phydev->advertising, adv_tmp)) in phy_speed_up()
667 return phy_config_aneg(phydev); in phy_speed_up()
681 void phy_start_machine(struct phy_device *phydev) in phy_start_machine() argument
683 phy_trigger_machine(phydev); in phy_start_machine()
695 void phy_stop_machine(struct phy_device *phydev) in phy_stop_machine() argument
697 cancel_delayed_work_sync(&phydev->state_queue); in phy_stop_machine()
699 mutex_lock(&phydev->lock); in phy_stop_machine()
700 if (phy_is_started(phydev)) in phy_stop_machine()
701 phydev->state = PHY_UP; in phy_stop_machine()
702 mutex_unlock(&phydev->lock); in phy_stop_machine()
714 static void phy_error(struct phy_device *phydev) in phy_error() argument
718 mutex_lock(&phydev->lock); in phy_error()
719 phydev->state = PHY_HALTED; in phy_error()
720 mutex_unlock(&phydev->lock); in phy_error()
722 phy_trigger_machine(phydev); in phy_error()
729 static int phy_disable_interrupts(struct phy_device *phydev) in phy_disable_interrupts() argument
734 err = phy_config_interrupt(phydev, PHY_INTERRUPT_DISABLED); in phy_disable_interrupts()
739 return phy_clear_interrupt(phydev); in phy_disable_interrupts()
751 struct phy_device *phydev = phy_dat; in phy_interrupt() local
753 if (phydev->drv->did_interrupt && !phydev->drv->did_interrupt(phydev)) in phy_interrupt()
756 if (phydev->drv->handle_interrupt) { in phy_interrupt()
757 if (phydev->drv->handle_interrupt(phydev)) in phy_interrupt()
761 phy_trigger_machine(phydev); in phy_interrupt()
764 if (phy_clear_interrupt(phydev)) in phy_interrupt()
769 phy_error(phydev); in phy_interrupt()
777 static int phy_enable_interrupts(struct phy_device *phydev) in phy_enable_interrupts() argument
779 int err = phy_clear_interrupt(phydev); in phy_enable_interrupts()
784 return phy_config_interrupt(phydev, PHY_INTERRUPT_ENABLED); in phy_enable_interrupts()
795 void phy_request_interrupt(struct phy_device *phydev) in phy_request_interrupt() argument
799 err = request_threaded_irq(phydev->irq, NULL, phy_interrupt, in phy_request_interrupt()
801 phydev_name(phydev), phydev); in phy_request_interrupt()
803 phydev_warn(phydev, "Error %d requesting IRQ %d, falling back to polling\n", in phy_request_interrupt()
804 err, phydev->irq); in phy_request_interrupt()
805 phydev->irq = PHY_POLL; in phy_request_interrupt()
807 if (phy_enable_interrupts(phydev)) { in phy_request_interrupt()
808 phydev_warn(phydev, "Can't enable interrupt, falling back to polling\n"); in phy_request_interrupt()
809 phy_free_interrupt(phydev); in phy_request_interrupt()
810 phydev->irq = PHY_POLL; in phy_request_interrupt()
823 void phy_free_interrupt(struct phy_device *phydev) in phy_free_interrupt() argument
825 phy_disable_interrupts(phydev); in phy_free_interrupt()
826 free_irq(phydev->irq, phydev); in phy_free_interrupt()
834 void phy_stop(struct phy_device *phydev) in phy_stop() argument
836 if (!phy_is_started(phydev)) { in phy_stop()
838 phy_state_to_str(phydev->state)); in phy_stop()
842 mutex_lock(&phydev->lock); in phy_stop()
844 phydev->state = PHY_HALTED; in phy_stop()
846 mutex_unlock(&phydev->lock); in phy_stop()
848 phy_state_machine(&phydev->state_queue.work); in phy_stop()
849 phy_stop_machine(phydev); in phy_stop()
868 void phy_start(struct phy_device *phydev) in phy_start() argument
870 mutex_lock(&phydev->lock); in phy_start()
872 if (phydev->state != PHY_READY && phydev->state != PHY_HALTED) { in phy_start()
874 phy_state_to_str(phydev->state)); in phy_start()
879 __phy_resume(phydev); in phy_start()
881 phydev->state = PHY_UP; in phy_start()
883 phy_start_machine(phydev); in phy_start()
885 mutex_unlock(&phydev->lock); in phy_start()
896 struct phy_device *phydev = in phy_state_machine() local
902 mutex_lock(&phydev->lock); in phy_state_machine()
904 old_state = phydev->state; in phy_state_machine()
906 switch (phydev->state) { in phy_state_machine()
916 err = phy_check_link_status(phydev); in phy_state_machine()
919 if (phydev->link) { in phy_state_machine()
920 phydev->link = 0; in phy_state_machine()
921 phy_link_down(phydev, true); in phy_state_machine()
927 mutex_unlock(&phydev->lock); in phy_state_machine()
930 err = phy_start_aneg(phydev); in phy_state_machine()
932 phy_suspend(phydev); in phy_state_machine()
935 phy_error(phydev); in phy_state_machine()
937 if (old_state != phydev->state) { in phy_state_machine()
938 phydev_dbg(phydev, "PHY state change %s -> %s\n", in phy_state_machine()
940 phy_state_to_str(phydev->state)); in phy_state_machine()
941 if (phydev->drv && phydev->drv->link_change_notify) in phy_state_machine()
942 phydev->drv->link_change_notify(phydev); in phy_state_machine()
953 mutex_lock(&phydev->lock); in phy_state_machine()
954 if (phy_polling_mode(phydev) && phy_is_started(phydev)) in phy_state_machine()
955 phy_queue_state_machine(phydev, PHY_STATE_TIME); in phy_state_machine()
956 mutex_unlock(&phydev->lock); in phy_state_machine()
966 void phy_mac_interrupt(struct phy_device *phydev) in phy_mac_interrupt() argument
969 phy_trigger_machine(phydev); in phy_mac_interrupt()
1007 int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable) in phy_init_eee() argument
1009 if (!phydev->drv) in phy_init_eee()
1014 if (phydev->duplex == DUPLEX_FULL) { in phy_init_eee()
1023 status = phy_read_status(phydev); in phy_init_eee()
1028 eee_cap = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE); in phy_init_eee()
1039 eee_lp = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_LPABLE); in phy_init_eee()
1043 eee_adv = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV); in phy_init_eee()
1051 if (!phy_check_valid(phydev->speed, phydev->duplex, common)) in phy_init_eee()
1058 phy_set_bits_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1, in phy_init_eee()
1075 int phy_get_eee_err(struct phy_device *phydev) in phy_get_eee_err() argument
1077 if (!phydev->drv) in phy_get_eee_err()
1080 return phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_PCS_EEE_WK_ERR); in phy_get_eee_err()
1092 int phy_ethtool_get_eee(struct phy_device *phydev, struct ethtool_eee *data) in phy_ethtool_get_eee() argument
1096 if (!phydev->drv) in phy_ethtool_get_eee()
1100 val = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE); in phy_ethtool_get_eee()
1106 val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV); in phy_ethtool_get_eee()
1113 val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_LPABLE); in phy_ethtool_get_eee()
1131 int phy_ethtool_set_eee(struct phy_device *phydev, struct ethtool_eee *data) in phy_ethtool_set_eee() argument
1135 if (!phydev->drv) in phy_ethtool_set_eee()
1139 cap = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE); in phy_ethtool_set_eee()
1143 old_adv = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV); in phy_ethtool_set_eee()
1151 adv &= ~phydev->eee_broken_modes; in phy_ethtool_set_eee()
1155 ret = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, adv); in phy_ethtool_set_eee()
1162 ret = phy_restart_aneg(phydev); in phy_ethtool_set_eee()
1171 int phy_ethtool_set_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol) in phy_ethtool_set_wol() argument
1173 if (phydev->drv && phydev->drv->set_wol) in phy_ethtool_set_wol()
1174 return phydev->drv->set_wol(phydev, wol); in phy_ethtool_set_wol()
1180 void phy_ethtool_get_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol) in phy_ethtool_get_wol() argument
1182 if (phydev->drv && phydev->drv->get_wol) in phy_ethtool_get_wol()
1183 phydev->drv->get_wol(phydev, wol); in phy_ethtool_get_wol()
1190 struct phy_device *phydev = ndev->phydev; in phy_ethtool_get_link_ksettings() local
1192 if (!phydev) in phy_ethtool_get_link_ksettings()
1195 phy_ethtool_ksettings_get(phydev, cmd); in phy_ethtool_get_link_ksettings()
1204 struct phy_device *phydev = ndev->phydev; in phy_ethtool_set_link_ksettings() local
1206 if (!phydev) in phy_ethtool_set_link_ksettings()
1209 return phy_ethtool_ksettings_set(phydev, cmd); in phy_ethtool_set_link_ksettings()
1215 struct phy_device *phydev = ndev->phydev; in phy_ethtool_nway_reset() local
1217 if (!phydev) in phy_ethtool_nway_reset()
1220 if (!phydev->drv) in phy_ethtool_nway_reset()
1223 return phy_restart_aneg(phydev); in phy_ethtool_nway_reset()