OpenWrt – Blame information for rev 2
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /* |
2 | * Atheros AR71xx built-in ethernet mac driver |
||
3 | * |
||
4 | * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> |
||
5 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> |
||
6 | * |
||
7 | * Based on Atheros' AG7100 driver |
||
8 | * |
||
9 | * This program is free software; you can redistribute it and/or modify it |
||
10 | * under the terms of the GNU General Public License version 2 as published |
||
11 | * by the Free Software Foundation. |
||
12 | */ |
||
13 | |||
14 | #include <linux/of_mdio.h> |
||
15 | #include "ag71xx.h" |
||
16 | |||
17 | static void ag71xx_phy_link_adjust(struct net_device *dev) |
||
18 | { |
||
19 | struct ag71xx *ag = netdev_priv(dev); |
||
20 | struct phy_device *phydev = ag->phy_dev; |
||
21 | unsigned long flags; |
||
22 | int status_change = 0; |
||
23 | |||
24 | spin_lock_irqsave(&ag->lock, flags); |
||
25 | |||
26 | if (phydev->link) { |
||
27 | if (ag->duplex != phydev->duplex |
||
28 | || ag->speed != phydev->speed) { |
||
29 | status_change = 1; |
||
30 | } |
||
31 | } |
||
32 | |||
33 | if (phydev->link != ag->link) |
||
34 | status_change = 1; |
||
35 | |||
36 | ag->link = phydev->link; |
||
37 | ag->duplex = phydev->duplex; |
||
38 | ag->speed = phydev->speed; |
||
39 | |||
40 | if (status_change) |
||
41 | ag71xx_link_adjust(ag); |
||
42 | |||
43 | spin_unlock_irqrestore(&ag->lock, flags); |
||
44 | } |
||
45 | |||
46 | int ag71xx_phy_connect(struct ag71xx *ag) |
||
47 | { |
||
48 | struct device_node *np = ag->pdev->dev.of_node; |
||
49 | struct device_node *phy_node; |
||
50 | int ret; |
||
51 | |||
52 | if (of_phy_is_fixed_link(np)) { |
||
53 | ret = of_phy_register_fixed_link(np); |
||
54 | if (ret < 0) { |
||
55 | dev_err(&ag->pdev->dev, |
||
56 | "Failed to register fixed PHY link: %d\n", ret); |
||
57 | return ret; |
||
58 | } |
||
59 | |||
60 | phy_node = of_node_get(np); |
||
61 | } else { |
||
62 | phy_node = of_parse_phandle(np, "phy-handle", 0); |
||
63 | } |
||
64 | |||
65 | if (!phy_node) { |
||
66 | dev_err(&ag->pdev->dev, |
||
67 | "Could not find valid phy node\n"); |
||
68 | return -ENODEV; |
||
69 | } |
||
70 | |||
71 | ag->phy_dev = of_phy_connect(ag->dev, phy_node, ag71xx_phy_link_adjust, |
||
72 | 0, ag->phy_if_mode); |
||
73 | |||
74 | of_node_put(phy_node); |
||
75 | |||
76 | if (!ag->phy_dev) { |
||
77 | dev_err(&ag->pdev->dev, |
||
78 | "Could not connect to PHY device\n"); |
||
79 | return -ENODEV; |
||
80 | } |
||
81 | |||
82 | dev_info(&ag->pdev->dev, "connected to PHY at %s [uid=%08x, driver=%s]\n", |
||
83 | phydev_name(ag->phy_dev), |
||
84 | ag->phy_dev->phy_id, ag->phy_dev->drv->name); |
||
85 | |||
86 | return 0; |
||
87 | } |
||
88 | |||
89 | void ag71xx_phy_disconnect(struct ag71xx *ag) |
||
90 | { |
||
91 | phy_disconnect(ag->phy_dev); |
||
92 | } |