Skip to content

Commit 9ea4d31

Browse files
moore-brosdavem330
authored andcommitted
net: ethernet: mediatek: add the whole ethernet reset into the reset process
1) original driver only resets DMA used by descriptor rings which can't guarantee it can recover all various kinds of fatal errors, so the patch tries to reset the underlying hardware resource from scratch on Mediatek SoC required for ethernet running, including power, pin mux control, clock and internal circuits on the ethernet in order to restore into the initial state which the rebooted machine gives. 2) add state variable inside structure mtk_eth to help distinguish mtk_hw_init is called between the initialization during boot time or re-initialization during the reset process. 3) add ge_mode variable inside structure mtk_mac for restoring the interface mode of the current setup for the target MAC. 4) remove __init attribute from mtk_hw_init definition Signed-off-by: Sean Wang <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 26a2ad8 commit 9ea4d31

File tree

2 files changed

+51
-8
lines changed

2 files changed

+51
-8
lines changed

drivers/net/ethernet/mediatek/mtk_eth_soc.c

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ static int mtk_phy_connect(struct mtk_mac *mac)
231231
{
232232
struct mtk_eth *eth = mac->hw;
233233
struct device_node *np;
234-
u32 val, ge_mode;
234+
u32 val;
235235

236236
np = of_parse_phandle(mac->of_node, "phy-handle", 0);
237237
if (!np && of_phy_is_fixed_link(mac->of_node))
@@ -245,18 +245,18 @@ static int mtk_phy_connect(struct mtk_mac *mac)
245245
case PHY_INTERFACE_MODE_RGMII_RXID:
246246
case PHY_INTERFACE_MODE_RGMII_ID:
247247
case PHY_INTERFACE_MODE_RGMII:
248-
ge_mode = 0;
248+
mac->ge_mode = 0;
249249
break;
250250
case PHY_INTERFACE_MODE_MII:
251-
ge_mode = 1;
251+
mac->ge_mode = 1;
252252
break;
253253
case PHY_INTERFACE_MODE_REVMII:
254-
ge_mode = 2;
254+
mac->ge_mode = 2;
255255
break;
256256
case PHY_INTERFACE_MODE_RMII:
257257
if (!mac->id)
258258
goto err_phy;
259-
ge_mode = 3;
259+
mac->ge_mode = 3;
260260
break;
261261
default:
262262
goto err_phy;
@@ -265,7 +265,7 @@ static int mtk_phy_connect(struct mtk_mac *mac)
265265
/* put the gmac into the right mode */
266266
regmap_read(eth->ethsys, ETHSYS_SYSCFG0, &val);
267267
val &= ~SYSCFG0_GE_MODE(SYSCFG0_GE_MASK, mac->id);
268-
val |= SYSCFG0_GE_MODE(ge_mode, mac->id);
268+
val |= SYSCFG0_GE_MODE(mac->ge_mode, mac->id);
269269
regmap_write(eth->ethsys, ETHSYS_SYSCFG0, val);
270270

271271
mtk_phy_connect_node(eth, mac, np);
@@ -1414,9 +1414,12 @@ static int mtk_stop(struct net_device *dev)
14141414
return 0;
14151415
}
14161416

1417-
static int __init mtk_hw_init(struct mtk_eth *eth)
1417+
static int mtk_hw_init(struct mtk_eth *eth)
14181418
{
1419-
int i;
1419+
int i, val;
1420+
1421+
if (test_and_set_bit(MTK_HW_INIT, &eth->state))
1422+
return 0;
14201423

14211424
pm_runtime_enable(eth->dev);
14221425
pm_runtime_get_sync(eth->dev);
@@ -1432,6 +1435,15 @@ static int __init mtk_hw_init(struct mtk_eth *eth)
14321435
reset_control_deassert(eth->rstc);
14331436
usleep_range(10, 20);
14341437

1438+
regmap_read(eth->ethsys, ETHSYS_SYSCFG0, &val);
1439+
for (i = 0; i < MTK_MAC_COUNT; i++) {
1440+
if (!eth->mac[i])
1441+
continue;
1442+
val &= ~SYSCFG0_GE_MODE(SYSCFG0_GE_MASK, eth->mac[i]->id);
1443+
val |= SYSCFG0_GE_MODE(eth->mac[i]->ge_mode, eth->mac[i]->id);
1444+
}
1445+
regmap_write(eth->ethsys, ETHSYS_SYSCFG0, val);
1446+
14351447
/* Set GE2 driving and slew rate */
14361448
regmap_write(eth->pctl, GPIO_DRV_SEL10, 0xa00);
14371449

@@ -1483,6 +1495,9 @@ static int __init mtk_hw_init(struct mtk_eth *eth)
14831495

14841496
static int mtk_hw_deinit(struct mtk_eth *eth)
14851497
{
1498+
if (!test_and_clear_bit(MTK_HW_INIT, &eth->state))
1499+
return 0;
1500+
14861501
clk_disable_unprepare(eth->clks[MTK_CLK_GP2]);
14871502
clk_disable_unprepare(eth->clks[MTK_CLK_GP1]);
14881503
clk_disable_unprepare(eth->clks[MTK_CLK_ESW]);
@@ -1560,6 +1575,26 @@ static void mtk_pending_work(struct work_struct *work)
15601575
__set_bit(i, &restart);
15611576
}
15621577

1578+
/* restart underlying hardware such as power, clock, pin mux
1579+
* and the connected phy
1580+
*/
1581+
mtk_hw_deinit(eth);
1582+
1583+
if (eth->dev->pins)
1584+
pinctrl_select_state(eth->dev->pins->p,
1585+
eth->dev->pins->default_state);
1586+
mtk_hw_init(eth);
1587+
1588+
for (i = 0; i < MTK_MAC_COUNT; i++) {
1589+
if (!eth->mac[i] ||
1590+
of_phy_is_fixed_link(eth->mac[i]->of_node))
1591+
continue;
1592+
err = phy_init_hw(eth->mac[i]->phy_dev);
1593+
if (err)
1594+
dev_err(eth->dev, "%s: PHY init failed.\n",
1595+
eth->netdev[i]->name);
1596+
}
1597+
15631598
/* restart DMA and enable IRQs */
15641599
for (i = 0; i < MTK_MAC_COUNT; i++) {
15651600
if (!test_bit(i, &restart))

drivers/net/ethernet/mediatek/mtk_eth_soc.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,10 @@ enum mtk_clks_map {
330330
MTK_CLK_MAX
331331
};
332332

333+
enum mtk_dev_state {
334+
MTK_HW_INIT
335+
};
336+
333337
/* struct mtk_tx_buf - This struct holds the pointers to the memory pointed at
334338
* by the TX descriptor s
335339
* @skb: The SKB pointer of the packet being sent
@@ -413,6 +417,7 @@ struct mtk_rx_ring {
413417
* @clks: clock array for all clocks required
414418
* @mii_bus: If there is a bus we need to create an instance for it
415419
* @pending_work: The workqueue used to reset the dma ring
420+
* @state Initialization and runtime state of the device.
416421
*/
417422

418423
struct mtk_eth {
@@ -441,18 +446,21 @@ struct mtk_eth {
441446

442447
struct mii_bus *mii_bus;
443448
struct work_struct pending_work;
449+
unsigned long state;
444450
};
445451

446452
/* struct mtk_mac - the structure that holds the info about the MACs of the
447453
* SoC
448454
* @id: The number of the MAC
455+
* @ge_mode: Interface mode kept for setup restoring
449456
* @of_node: Our devicetree node
450457
* @hw: Backpointer to our main datastruture
451458
* @hw_stats: Packet statistics counter
452459
* @phy_dev: The attached PHY if available
453460
*/
454461
struct mtk_mac {
455462
int id;
463+
int ge_mode;
456464
struct device_node *of_node;
457465
struct mtk_eth *hw;
458466
struct mtk_hw_stats *hw_stats;

0 commit comments

Comments
 (0)