Skip to content

Commit 7e99010

Browse files
Weiguo Hurkhuangtao
authored andcommitted
net: phy: rockchip: do phy reset once in no link status
This solve failed to linkup for very few chip This can reduce udp package lost rate sometimes Change-Id: I684d9ea974e56478e7906c6e79c4c8505c042823 Signed-off-by: Weiguo Hu <hwg@rock-chips.com>
1 parent 921df26 commit 7e99010

1 file changed

Lines changed: 36 additions & 29 deletions

File tree

drivers/net/phy/rockchip.c

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,17 @@
5757

5858
#define PHY_ABNORMAL_THRESHOLD 15
5959

60+
#define ENABLE_PHY_FIXUP_RESET
61+
6062
struct rk_int_phy_priv {
6163
int restore_reg0;
6264
int restore_a3_config;
6365
int force_10m_full_mode;
6466
int a3_config_set;
6567
int txrx_counters_done_count;
6668
int last_speed;
69+
int last_state;
70+
int reset;
6771
};
6872

6973
static int rockchip_integrated_phy_init_tstmode(struct phy_device *phydev)
@@ -192,42 +196,15 @@ static int rockchip_integrated_phy_adjust_a3_config(struct phy_device *phydev,
192196
static
193197
void rockchip_integrated_phy_link_change_notify(struct phy_device *phydev)
194198
{
195-
int speed = SPEED_10;
196199
struct rk_int_phy_priv *priv = phydev->priv;
197200

198-
if (phydev->autoneg == AUTONEG_ENABLE) {
199-
int reg = phy_read(phydev, MII_SPECIAL_CONTROL_STATUS);
200-
201-
if (reg < 0) {
202-
phydev_err(phydev, "phy_read err: %d.\n", reg);
203-
return;
204-
}
205-
206-
if (reg & MII_SPEED_100)
207-
speed = SPEED_100;
208-
else if (reg & MII_SPEED_10)
209-
speed = SPEED_10;
210-
} else {
211-
int bmcr = phy_read(phydev, MII_BMCR);
212-
213-
if (bmcr < 0) {
214-
phydev_err(phydev, "phy_read err: %d.\n", bmcr);
215-
return;
216-
}
217-
218-
if (bmcr & BMCR_SPEED100)
219-
speed = SPEED_100;
220-
else
221-
speed = SPEED_10;
222-
}
223-
224201
/*
225202
* If mode switch happens from 10BT to 100BT, all DSP/AFE
226203
* registers are set to default values. So any AFE/DSP
227204
* registers have to be re-initialized in this case.
228205
*/
229206
if (phydev->link &&
230-
speed == SPEED_100 &&
207+
phydev->speed == SPEED_100 &&
231208
priv->last_speed == SPEED_10) {
232209
int ret = rockchip_integrated_phy_analog_init(phydev);
233210

@@ -237,7 +214,7 @@ void rockchip_integrated_phy_link_change_notify(struct phy_device *phydev)
237214
}
238215

239216
if (phydev->link)
240-
priv->last_speed = speed;
217+
priv->last_speed = phydev->speed;
241218
}
242219

243220
static int rockchip_set_polarity(struct phy_device *phydev, int polarity)
@@ -398,6 +375,30 @@ static int rockchip_integrated_phy_fixup_100M(struct phy_device *phydev)
398375
return 0;
399376
}
400377

378+
#ifdef ENABLE_PHY_FIXUP_RESET
379+
static int rockchip_integrated_phy_fixup_reset(struct phy_device *phydev)
380+
{
381+
int ret;
382+
struct rk_int_phy_priv *priv = phydev->priv;
383+
384+
/* reset phy once
385+
* solve failed to linkup for very few chip
386+
* reduce udp package lost rate sometimes
387+
*/
388+
if (priv->last_state == PHY_NOLINK && phydev->state == PHY_NOLINK) {
389+
if (++priv->reset == 2) {
390+
phydev_dbg(phydev, "%s\n", __func__);
391+
ret = genphy_soft_reset(phydev);
392+
if (ret < 0)
393+
return ret;
394+
}
395+
}
396+
397+
priv->last_state = phydev->state;
398+
return 0;
399+
}
400+
#endif
401+
401402
static int rockchip_integrated_phy_read_status(struct phy_device *phydev)
402403
{
403404
int ret;
@@ -414,6 +415,12 @@ static int rockchip_integrated_phy_read_status(struct phy_device *phydev)
414415
if (ret)
415416
return ret;
416417

418+
#ifdef ENABLE_PHY_FIXUP_RESET
419+
ret = rockchip_integrated_phy_fixup_reset(phydev);
420+
if (ret)
421+
return ret;
422+
#endif
423+
417424
return 0;
418425
}
419426

0 commit comments

Comments
 (0)