1bc267145ec7f6184a0e856e4cc3280d3e8affd6
[openwrt/svn-archive/archive.git] / target / linux / bcm53xx / patches-3.10 / 203-bgmac-register-phy.patch
1 From a145c561b9ba9ef402fbc3aa295b31521aa8591d Mon Sep 17 00:00:00 2001
2 From: Hauke Mehrtens <hauke@hauke-m.de>
3 Date: Sun, 14 Jul 2013 00:04:21 +0200
4 Subject: [PATCH 18/18] bgmac: register phy
5
6 Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
7 ---
8 drivers/net/ethernet/broadcom/bgmac.c | 137 ++++++++++++++++-----------------
9 drivers/net/ethernet/broadcom/bgmac.h | 3 +
10 2 files changed, 71 insertions(+), 69 deletions(-)
11
12 --- a/drivers/net/ethernet/broadcom/bgmac.c
13 +++ b/drivers/net/ethernet/broadcom/bgmac.c
14 @@ -1205,27 +1205,14 @@ static int bgmac_set_mac_address(struct
15 static int bgmac_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd)
16 {
17 struct bgmac *bgmac = netdev_priv(net_dev);
18 - struct mii_ioctl_data *data = if_mii(ifr);
19
20 - switch (cmd) {
21 - case SIOCGMIIPHY:
22 - data->phy_id = bgmac->phyaddr;
23 - /* fallthru */
24 - case SIOCGMIIREG:
25 - if (!netif_running(net_dev))
26 - return -EAGAIN;
27 - data->val_out = bgmac_phy_read(bgmac, data->phy_id,
28 - data->reg_num & 0x1f);
29 - return 0;
30 - case SIOCSMIIREG:
31 - if (!netif_running(net_dev))
32 - return -EAGAIN;
33 - bgmac_phy_write(bgmac, data->phy_id, data->reg_num & 0x1f,
34 - data->val_in);
35 - return 0;
36 - default:
37 - return -EOPNOTSUPP;
38 - }
39 + if (!netif_running(net_dev))
40 + return -EINVAL;
41 +
42 + if (!bgmac->phydev)
43 + return -EINVAL;
44 +
45 + return phy_mii_ioctl(bgmac->phydev, ifr, cmd);
46 }
47
48 static const struct net_device_ops bgmac_netdev_ops = {
49 @@ -1247,61 +1234,18 @@ static int bgmac_get_settings(struct net
50 {
51 struct bgmac *bgmac = netdev_priv(net_dev);
52
53 - cmd->supported = SUPPORTED_10baseT_Half |
54 - SUPPORTED_10baseT_Full |
55 - SUPPORTED_100baseT_Half |
56 - SUPPORTED_100baseT_Full |
57 - SUPPORTED_1000baseT_Half |
58 - SUPPORTED_1000baseT_Full |
59 - SUPPORTED_Autoneg;
60 -
61 - if (bgmac->autoneg) {
62 - WARN_ON(cmd->advertising);
63 - if (bgmac->full_duplex) {
64 - if (bgmac->speed & BGMAC_SPEED_10)
65 - cmd->advertising |= ADVERTISED_10baseT_Full;
66 - if (bgmac->speed & BGMAC_SPEED_100)
67 - cmd->advertising |= ADVERTISED_100baseT_Full;
68 - if (bgmac->speed & BGMAC_SPEED_1000)
69 - cmd->advertising |= ADVERTISED_1000baseT_Full;
70 - } else {
71 - if (bgmac->speed & BGMAC_SPEED_10)
72 - cmd->advertising |= ADVERTISED_10baseT_Half;
73 - if (bgmac->speed & BGMAC_SPEED_100)
74 - cmd->advertising |= ADVERTISED_100baseT_Half;
75 - if (bgmac->speed & BGMAC_SPEED_1000)
76 - cmd->advertising |= ADVERTISED_1000baseT_Half;
77 - }
78 - } else {
79 - switch (bgmac->speed) {
80 - case BGMAC_SPEED_10:
81 - ethtool_cmd_speed_set(cmd, SPEED_10);
82 - break;
83 - case BGMAC_SPEED_100:
84 - ethtool_cmd_speed_set(cmd, SPEED_100);
85 - break;
86 - case BGMAC_SPEED_1000:
87 - ethtool_cmd_speed_set(cmd, SPEED_1000);
88 - break;
89 - }
90 - }
91 -
92 - cmd->duplex = bgmac->full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
93 -
94 - cmd->autoneg = bgmac->autoneg;
95 -
96 - return 0;
97 + return phy_ethtool_gset(bgmac->phydev, cmd);
98 }
99
100 -#if 0
101 +
102 static int bgmac_set_settings(struct net_device *net_dev,
103 struct ethtool_cmd *cmd)
104 {
105 struct bgmac *bgmac = netdev_priv(net_dev);
106
107 - return -1;
108 + return phy_ethtool_sset(bgmac->phydev, cmd);
109 }
110 -#endif
111 +
112
113 static void bgmac_get_drvinfo(struct net_device *net_dev,
114 struct ethtool_drvinfo *info)
115 @@ -1312,6 +1256,7 @@ static void bgmac_get_drvinfo(struct net
116
117 static const struct ethtool_ops bgmac_ethtool_ops = {
118 .get_settings = bgmac_get_settings,
119 + .set_settings = bgmac_set_settings,
120 .get_drvinfo = bgmac_get_drvinfo,
121 };
122
123 @@ -1330,10 +1275,42 @@ static int bgmac_mii_write(struct mii_bu
124 return bgmac_phy_write(bus->priv, mii_id, regnum, value);
125 }
126
127 +static void bgmac_adjust_link(struct net_device *dev)
128 +{
129 + struct bgmac *bgmac = netdev_priv(dev);
130 + struct phy_device *phydev = bgmac->phydev;
131 + int status_changed = 0;
132 +
133 + BUG_ON(!phydev);
134 +
135 + if (bgmac->old_link != phydev->link) {
136 + status_changed = 1;
137 + bgmac->old_link = phydev->link;
138 + }
139 +
140 + /* reflect duplex change */
141 + if (phydev->link && (bgmac->old_duplex != phydev->duplex)) {
142 + status_changed = 1;
143 + bgmac->old_duplex = phydev->duplex;
144 + }
145 +
146 + if (status_changed) {
147 + pr_info("%s: link %s", dev->name, phydev->link ?
148 + "UP" : "DOWN");
149 + if (phydev->link)
150 + pr_cont(" - %d/%s", phydev->speed,
151 + phydev->duplex == DUPLEX_FULL ? "full" : "half");
152 + pr_cont("\n");
153 + }
154 +}
155 +
156 static int bgmac_mii_register(struct bgmac *bgmac)
157 {
158 struct mii_bus *mii_bus;
159 int i, err = 0;
160 + struct phy_device *phydev = NULL;
161 + char phy_id[MII_BUS_ID_SIZE + 3];
162 + struct net_device *net_dev = bgmac->net_dev;
163
164 mii_bus = mdiobus_alloc();
165 if (!mii_bus)
166 @@ -1364,7 +1341,29 @@ static int bgmac_mii_register(struct bgm
167
168 bgmac->mii_bus = mii_bus;
169
170 - return err;
171 + /* connect to PHY */
172 + snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT,
173 + mii_bus->id, bgmac->phyaddr);
174 +
175 + phydev = phy_connect(net_dev, phy_id, &bgmac_adjust_link,
176 + PHY_INTERFACE_MODE_MII);
177 +
178 + if (IS_ERR(phydev)) {
179 + netdev_err(net_dev, "could not attach PHY: %s", phy_id);
180 + bgmac->phyaddr = BGMAC_PHY_NOREGS;
181 + return PTR_ERR(phydev);
182 + }
183 +
184 + bgmac->phydev = phydev;
185 + bgmac->old_link = 0;
186 + bgmac->old_duplex = -1;
187 + bgmac->phyaddr = phydev->addr;
188 +
189 + netdev_info(net_dev, "attached PHY driver [%s] "
190 + "(mii_bus:phy_addr=%s)\n",
191 + phydev->drv->name, dev_name(&phydev->dev));
192 +
193 + return 0;
194
195 err_free_irq:
196 kfree(mii_bus->irq);
197 --- a/drivers/net/ethernet/broadcom/bgmac.h
198 +++ b/drivers/net/ethernet/broadcom/bgmac.h
199 @@ -399,7 +399,10 @@ struct bgmac {
200 struct bcma_device *cmn; /* Reference to CMN core for BCM4706 */
201 struct net_device *net_dev;
202 struct napi_struct napi;
203 + struct phy_device *phydev;
204 struct mii_bus *mii_bus;
205 + int old_link;
206 + int old_duplex;
207
208 /* DMA */
209 struct bgmac_dma_ring tx_ring[BGMAC_MAX_TX_RINGS];