OpenWrt – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | From 28baa5e2635285b178326b301f534ed95c65dd01 Mon Sep 17 00:00:00 2001 |
2 | From: Jonas Gorski <jonas.gorski@gmail.com> |
||
3 | Date: Thu, 29 Sep 2016 11:44:39 +0200 |
||
4 | Subject: [PATCH] sfp: retry phy probe if unsuccessful |
||
5 | |||
6 | Some phys seem to take longer than 50 ms to come out of reset, so retry |
||
7 | until we find a phy. |
||
8 | |||
9 | Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> |
||
10 | --- |
||
11 | drivers/net/phy/sfp.c | 38 +++++++++++++++++++++++++------------- |
||
12 | 1 file changed, 25 insertions(+), 13 deletions(-) |
||
13 | |||
14 | --- a/drivers/net/phy/sfp.c |
||
15 | +++ b/drivers/net/phy/sfp.c |
||
16 | @@ -488,7 +488,7 @@ static void sfp_sm_phy_detach(struct sfp |
||
17 | sfp->mod_phy = NULL; |
||
18 | } |
||
19 | |||
20 | -static void sfp_sm_probe_phy(struct sfp *sfp) |
||
21 | +static int sfp_sm_probe_phy(struct sfp *sfp) |
||
22 | { |
||
23 | struct phy_device *phy; |
||
24 | int err; |
||
25 | @@ -498,11 +498,11 @@ static void sfp_sm_probe_phy(struct sfp |
||
26 | phy = mdiobus_scan(sfp->i2c_mii, SFP_PHY_ADDR); |
||
27 | if (phy == ERR_PTR(-ENODEV)) { |
||
28 | dev_info(sfp->dev, "no PHY detected\n"); |
||
29 | - return; |
||
30 | + return -EAGAIN; |
||
31 | } |
||
32 | if (IS_ERR(phy)) { |
||
33 | dev_err(sfp->dev, "mdiobus scan returned %ld\n", PTR_ERR(phy)); |
||
34 | - return; |
||
35 | + return PTR_ERR(phy); |
||
36 | } |
||
37 | |||
38 | err = sfp_add_phy(sfp->sfp_bus, phy); |
||
39 | @@ -510,11 +510,13 @@ static void sfp_sm_probe_phy(struct sfp |
||
40 | phy_device_remove(phy); |
||
41 | phy_device_free(phy); |
||
42 | dev_err(sfp->dev, "sfp_add_phy failed: %d\n", err); |
||
43 | - return; |
||
44 | + return err; |
||
45 | } |
||
46 | |||
47 | sfp->mod_phy = phy; |
||
48 | phy_start(phy); |
||
49 | + |
||
50 | + return 0; |
||
51 | } |
||
52 | |||
53 | static void sfp_sm_link_up(struct sfp *sfp) |
||
54 | @@ -560,14 +562,9 @@ static void sfp_sm_fault(struct sfp *sfp |
||
55 | |||
56 | static void sfp_sm_mod_init(struct sfp *sfp) |
||
57 | { |
||
58 | - sfp_module_tx_enable(sfp); |
||
59 | + int ret = 0; |
||
60 | |||
61 | - /* Wait t_init before indicating that the link is up, provided the |
||
62 | - * current state indicates no TX_FAULT. If TX_FAULT clears before |
||
63 | - * this time, that's fine too. |
||
64 | - */ |
||
65 | - sfp_sm_next(sfp, SFP_S_INIT, T_INIT_JIFFIES); |
||
66 | - sfp->sm_retries = 5; |
||
67 | + sfp_module_tx_enable(sfp); |
||
68 | |||
69 | /* Setting the serdes link mode is guesswork: there's no |
||
70 | * field in the EEPROM which indicates what mode should |
||
71 | @@ -581,7 +578,22 @@ static void sfp_sm_mod_init(struct sfp * |
||
72 | if (sfp->id.base.e1000_base_t || |
||
73 | sfp->id.base.e100_base_lx || |
||
74 | sfp->id.base.e100_base_fx) |
||
75 | - sfp_sm_probe_phy(sfp); |
||
76 | + ret = sfp_sm_probe_phy(sfp); |
||
77 | + |
||
78 | + if (!ret) { |
||
79 | + /* Wait t_init before indicating that the link is up, provided |
||
80 | + * the current state indicates no TX_FAULT. If TX_FAULT clears |
||
81 | + * this time, that's fine too. |
||
82 | + */ |
||
83 | + sfp_sm_next(sfp, SFP_S_INIT, T_INIT_JIFFIES); |
||
84 | + sfp->sm_retries = 5; |
||
85 | + return; |
||
86 | + } |
||
87 | + |
||
88 | + if (ret == -EAGAIN) |
||
89 | + sfp_sm_set_timer(sfp, T_PROBE_RETRY); |
||
90 | + else |
||
91 | + sfp_sm_next(sfp, SFP_S_TX_DISABLE, 0); |
||
92 | } |
||
93 | |||
94 | static int sfp_sm_mod_probe(struct sfp *sfp) |