drivers: ethernet: phy: only use one worker

only use one worker for monitoring and
autoneg.

Signed-off-by: Fin Maaß <f.maass@vogl-electronic.com>
This commit is contained in:
Fin Maaß 2025-06-11 16:53:49 +02:00 committed by Dan Kalowsky
commit c481fedc5b

View file

@ -38,9 +38,9 @@ struct phy_mii_dev_data {
struct k_sem sem;
#if ANY_DYNAMIC_LINK
struct k_work_delayable monitor_work;
struct k_work_delayable autoneg_work;
bool gigabit_supported;
bool restart_autoneg;
bool autoneg_in_progress;
k_timepoint_t autoneg_timeout;
#endif
};
@ -310,65 +310,27 @@ static void monitor_work_handler(struct k_work *work)
const struct device *dev = data->dev;
int rc;
if (k_sem_take(&data->sem, K_NO_WAIT) != 0) {
/* Try again soon */
k_work_reschedule(&data->monitor_work,
K_MSEC(MII_AUTONEG_POLL_INTERVAL_MS));
return;
if (k_sem_take(&data->sem, K_NO_WAIT) == 0) {
if (data->autoneg_in_progress) {
rc = check_autonegotiation_completion(dev);
} else {
/* If autonegotiation is not in progress, just update the link state */
rc = update_link_state(dev);
}
data->autoneg_in_progress = (rc == -EINPROGRESS);
k_sem_give(&data->sem);
/* If link state has changed and a callback is set, invoke callback */
if (rc == 0) {
invoke_link_cb(dev);
}
}
rc = update_link_state(dev);
k_sem_give(&data->sem);
/* If link state has changed and a callback is set, invoke callback */
if (rc == 0) {
invoke_link_cb(dev);
}
if (rc == -EINPROGRESS) {
/* Check for autonegotiation completion */
k_work_reschedule(&data->autoneg_work,
K_MSEC(MII_AUTONEG_POLL_INTERVAL_MS));
} else {
/* Submit delayed work */
k_work_reschedule(&data->monitor_work, K_MSEC(CONFIG_PHY_MONITOR_PERIOD));
}
}
static void autoneg_work_handler(struct k_work *work)
{
struct k_work_delayable *dwork = k_work_delayable_from_work(work);
struct phy_mii_dev_data *const data =
CONTAINER_OF(dwork, struct phy_mii_dev_data, autoneg_work);
const struct device *dev = data->dev;
int rc;
if (k_sem_take(&data->sem, K_NO_WAIT) != 0) {
/* Try again soon */
k_work_reschedule(&data->autoneg_work,
K_MSEC(MII_AUTONEG_POLL_INTERVAL_MS));
return;
}
rc = check_autonegotiation_completion(dev);
k_sem_give(&data->sem);
/* If link state has changed and a callback is set, invoke callback */
if (rc == 0) {
invoke_link_cb(dev);
}
if (rc == -EINPROGRESS) {
/* Check again soon */
k_work_reschedule(&data->autoneg_work,
K_MSEC(MII_AUTONEG_POLL_INTERVAL_MS));
} else {
/* Schedule the next monitoring call */
k_work_reschedule(&data->monitor_work,
K_MSEC(CONFIG_PHY_MONITOR_PERIOD));
}
k_work_reschedule(&data->monitor_work, data->autoneg_in_progress
? K_MSEC(MII_AUTONEG_POLL_INTERVAL_MS)
: K_MSEC(CONFIG_PHY_MONITOR_PERIOD));
}
static int phy_mii_read(const struct device *dev, uint16_t reg_addr,
@ -490,7 +452,6 @@ static int phy_mii_cfg_link(const struct device *dev,
}
if (data->restart_autoneg && data->state.is_up) {
k_work_cancel_delayable(&data->autoneg_work);
k_work_reschedule(&data->monitor_work, K_NO_WAIT);
}
@ -609,7 +570,6 @@ static int phy_mii_initialize_dynamic_link(const struct device *dev)
data->gigabit_supported = is_gigabit_supported(dev);
k_work_init_delayable(&data->monitor_work, monitor_work_handler);
k_work_init_delayable(&data->autoneg_work, autoneg_work_handler);
/* Advertise default speeds */
phy_mii_cfg_link(dev, cfg->default_speeds);