cxgb3: add support for the Aquantia 10G-BT phy
[linux-drm-fsl-dcu.git] / drivers / net / cxgb3 / aq100x.c
1 /*
2  * Copyright (c) 2005-2008 Chelsio, Inc. All rights reserved.
3  *
4  * This software is available to you under a choice of one of two
5  * licenses.  You may choose to be licensed under the terms of the GNU
6  * General Public License (GPL) Version 2, available from the file
7  * COPYING in the main directory of this source tree, or the
8  * OpenIB.org BSD license below:
9  *
10  *     Redistribution and use in source and binary forms, with or
11  *     without modification, are permitted provided that the following
12  *     conditions are met:
13  *
14  *      - Redistributions of source code must retain the above
15  *        copyright notice, this list of conditions and the following
16  *        disclaimer.
17  *
18  *      - Redistributions in binary form must reproduce the above
19  *        copyright notice, this list of conditions and the following
20  *        disclaimer in the documentation and/or other materials
21  *        provided with the distribution.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30  * SOFTWARE.
31  */
32
33 #include "common.h"
34 #include "regs.h"
35
36 enum {
37         /* MDIO_DEV_PMA_PMD registers */
38         AQ_LINK_STAT    = 0xe800,
39         AQ_IMASK_PMA    = 0xf000,
40
41         /* MDIO_DEV_XGXS registers */
42         AQ_XAUI_RX_CFG  = 0xc400,
43         AQ_XAUI_TX_CFG  = 0xe400,
44
45         /* MDIO_DEV_ANEG registers */
46         AQ_100M_CTRL    = 0x0010,
47         AQ_10G_CTRL     = 0x0020,
48         AQ_1G_CTRL      = 0xc400,
49         AQ_ANEG_STAT    = 0xc800,
50
51         /* MDIO_DEV_VEND1 registers */
52         AQ_FW_VERSION   = 0x0020,
53         AQ_IFLAG_GLOBAL = 0xfc00,
54         AQ_IMASK_GLOBAL = 0xff00,
55 };
56
57 #define AQBIT(x)        (1 << (x))
58 #define IMASK_PMA       AQBIT(0x2)
59 #define IMASK_GLOBAL    AQBIT(0xf)
60 #define ADV_1G_FULL     AQBIT(0xf)
61 #define ADV_1G_HALF     AQBIT(0xe)
62 #define ADV_10G_FULL    AQBIT(0xc)
63 #define AQ_RESET        (AQBIT(0xe) | AQBIT(0xf))
64 #define AQ_LOWPOWER     AQBIT(0xb)
65
66 static int aq100x_reset(struct cphy *phy, int wait)
67 {
68         /*
69          * Ignore the caller specified wait time; always wait for the reset to
70          * complete. Can take up to 3s.
71          */
72         int err = t3_phy_reset(phy, MDIO_MMD_VEND1, 3000);
73
74         if (err)
75                 CH_WARN(phy->adapter, "PHY%d: reset failed (0x%x).\n",
76                         phy->mdio.prtad, err);
77
78         return err;
79 }
80
81 static int aq100x_intr_enable(struct cphy *phy)
82 {
83         int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AQ_IMASK_PMA, IMASK_PMA);
84         if (err)
85                 return err;
86
87         err = t3_mdio_write(phy, MDIO_MMD_VEND1, AQ_IMASK_GLOBAL, IMASK_GLOBAL);
88         return err;
89 }
90
91 static int aq100x_intr_disable(struct cphy *phy)
92 {
93         return t3_mdio_write(phy, MDIO_MMD_VEND1, AQ_IMASK_GLOBAL, 0);
94 }
95
96 static int aq100x_intr_clear(struct cphy *phy)
97 {
98         unsigned int v;
99
100         t3_mdio_read(phy, MDIO_MMD_VEND1, AQ_IFLAG_GLOBAL, &v);
101         t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_STAT1, &v);
102
103         return 0;
104 }
105
106 static int aq100x_intr_handler(struct cphy *phy)
107 {
108         int err;
109         unsigned int cause, v;
110
111         err = t3_mdio_read(phy, MDIO_MMD_VEND1, AQ_IFLAG_GLOBAL, &cause);
112         if (err)
113                 return err;
114
115         /* Read (and reset) the latching version of the status */
116         t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_STAT1, &v);
117
118         return cphy_cause_link_change;
119 }
120
121 static int aq100x_power_down(struct cphy *phy, int off)
122 {
123         return mdio_set_flag(&phy->mdio, phy->mdio.prtad,
124                              MDIO_MMD_PMAPMD, MDIO_CTRL1,
125                              MDIO_CTRL1_LPOWER, off);
126 }
127
128 static int aq100x_autoneg_enable(struct cphy *phy)
129 {
130         int err;
131
132         err = aq100x_power_down(phy, 0);
133         if (!err)
134                 err = mdio_set_flag(&phy->mdio, phy->mdio.prtad,
135                                     MDIO_MMD_AN, MDIO_CTRL1,
136                                     BMCR_ANENABLE | BMCR_ANRESTART, 1);
137
138         return err;
139 }
140
141 static int aq100x_autoneg_restart(struct cphy *phy)
142 {
143         int err;
144
145         err = aq100x_power_down(phy, 0);
146         if (!err)
147                 err = mdio_set_flag(&phy->mdio, phy->mdio.prtad,
148                                     MDIO_MMD_AN, MDIO_CTRL1,
149                                     BMCR_ANENABLE | BMCR_ANRESTART, 1);
150
151         return err;
152 }
153
154 static int aq100x_advertise(struct cphy *phy, unsigned int advertise_map)
155 {
156         unsigned int adv;
157         int err;
158
159         /* 10G advertisement */
160         adv = 0;
161         if (advertise_map & ADVERTISED_10000baseT_Full)
162                 adv |= ADV_10G_FULL;
163         err = t3_mdio_change_bits(phy, MDIO_MMD_AN, AQ_10G_CTRL,
164                                   ADV_10G_FULL, adv);
165         if (err)
166                 return err;
167
168         /* 1G advertisement */
169         adv = 0;
170         if (advertise_map & ADVERTISED_1000baseT_Full)
171                 adv |= ADV_1G_FULL;
172         if (advertise_map & ADVERTISED_1000baseT_Half)
173                 adv |= ADV_1G_HALF;
174         err = t3_mdio_change_bits(phy, MDIO_MMD_AN, AQ_1G_CTRL,
175                                   ADV_1G_FULL | ADV_1G_HALF, adv);
176         if (err)
177                 return err;
178
179         /* 100M, pause advertisement */
180         adv = 0;
181         if (advertise_map & ADVERTISED_100baseT_Half)
182                 adv |= ADVERTISE_100HALF;
183         if (advertise_map & ADVERTISED_100baseT_Full)
184                 adv |= ADVERTISE_100FULL;
185         if (advertise_map & ADVERTISED_Pause)
186                 adv |= ADVERTISE_PAUSE_CAP;
187         if (advertise_map & ADVERTISED_Asym_Pause)
188                 adv |= ADVERTISE_PAUSE_ASYM;
189         err = t3_mdio_change_bits(phy, MDIO_MMD_AN, AQ_100M_CTRL, 0xfe0, adv);
190
191         return err;
192 }
193
194 static int aq100x_set_loopback(struct cphy *phy, int mmd, int dir, int enable)
195 {
196         return mdio_set_flag(&phy->mdio, phy->mdio.prtad,
197                              MDIO_MMD_PMAPMD, MDIO_CTRL1,
198                              BMCR_LOOPBACK, enable);
199 }
200
201 static int aq100x_set_speed_duplex(struct cphy *phy, int speed, int duplex)
202 {
203         /* no can do */
204         return -1;
205 }
206
207 static int aq100x_get_link_status(struct cphy *phy, int *link_ok,
208                                   int *speed, int *duplex, int *fc)
209 {
210         int err;
211         unsigned int v;
212
213         if (link_ok) {
214                 err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AQ_LINK_STAT, &v);
215                 if (err)
216                         return err;
217
218                 *link_ok = v & 1;
219                 if (!*link_ok)
220                         return 0;
221         }
222
223         err = t3_mdio_read(phy, MDIO_MMD_AN, AQ_ANEG_STAT, &v);
224         if (err)
225                 return err;
226
227         if (speed) {
228                 switch (v & 0x6) {
229                 case 0x6:
230                         *speed = SPEED_10000;
231                         break;
232                 case 0x4:
233                         *speed = SPEED_1000;
234                         break;
235                 case 0x2:
236                         *speed = SPEED_100;
237                         break;
238                 case 0x0:
239                         *speed = SPEED_10;
240                         break;
241                 }
242         }
243
244         if (duplex)
245                 *duplex = v & 1 ? DUPLEX_FULL : DUPLEX_HALF;
246
247         return 0;
248 }
249
250 static struct cphy_ops aq100x_ops = {
251         .reset             = aq100x_reset,
252         .intr_enable       = aq100x_intr_enable,
253         .intr_disable      = aq100x_intr_disable,
254         .intr_clear        = aq100x_intr_clear,
255         .intr_handler      = aq100x_intr_handler,
256         .autoneg_enable    = aq100x_autoneg_enable,
257         .autoneg_restart   = aq100x_autoneg_restart,
258         .advertise         = aq100x_advertise,
259         .set_loopback      = aq100x_set_loopback,
260         .set_speed_duplex  = aq100x_set_speed_duplex,
261         .get_link_status   = aq100x_get_link_status,
262         .power_down        = aq100x_power_down,
263         .mmds              = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS,
264 };
265
266 int t3_aq100x_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr,
267                        const struct mdio_ops *mdio_ops)
268 {
269         unsigned int v, v2, gpio, wait;
270         int err;
271
272         cphy_init(phy, adapter, phy_addr, &aq100x_ops, mdio_ops,
273                   SUPPORTED_1000baseT_Full | SUPPORTED_10000baseT_Full |
274                   SUPPORTED_Autoneg | SUPPORTED_AUI, "1000/10GBASE-T");
275
276         /*
277          * The PHY has been out of reset ever since the system powered up.  So
278          * we do a hard reset over here.
279          */
280         gpio = phy_addr ? F_GPIO10_OUT_VAL : F_GPIO6_OUT_VAL;
281         t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, gpio, 0);
282         msleep(1);
283         t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, gpio, gpio);
284
285         /*
286          * Give it enough time to load the firmware and get ready for mdio.
287          */
288         msleep(1000);
289         wait = 500; /* in 10ms increments */
290         do {
291                 err = t3_mdio_read(phy, MDIO_MMD_VEND1, MDIO_CTRL1, &v);
292                 if (err || v == 0xffff) {
293
294                         /* Allow prep_adapter to succeed when ffff is read */
295
296                         CH_WARN(adapter, "PHY%d: reset failed (0x%x, 0x%x).\n",
297                                 phy_addr, err, v);
298                         goto done;
299                 }
300
301                 v &= AQ_RESET;
302                 if (v)
303                         msleep(10);
304         } while (v && --wait);
305         if (v) {
306                 CH_WARN(adapter, "PHY%d: reset timed out (0x%x).\n",
307                         phy_addr, v);
308
309                 goto done; /* let prep_adapter succeed */
310         }
311
312         /* Datasheet says 3s max but this has been observed */
313         wait = (500 - wait) * 10 + 1000;
314         if (wait > 3000)
315                 CH_WARN(adapter, "PHY%d: reset took %ums\n", phy_addr, wait);
316
317         /* Firmware version check. */
318         t3_mdio_read(phy, MDIO_MMD_VEND1, AQ_FW_VERSION, &v);
319         if (v != 30) {
320                 CH_WARN(adapter, "PHY%d: unsupported firmware %d\n",
321                         phy_addr, v);
322                 return 0; /* allow t3_prep_adapter to succeed */
323         }
324
325         /*
326          * The PHY should start in really-low-power mode.  Prepare it for normal
327          * operations.
328          */
329         err = t3_mdio_read(phy, MDIO_MMD_VEND1, MDIO_CTRL1, &v);
330         if (err)
331                 return err;
332         if (v & AQ_LOWPOWER) {
333                 err = t3_mdio_change_bits(phy, MDIO_MMD_VEND1, MDIO_CTRL1,
334                                           AQ_LOWPOWER, 0);
335                 if (err)
336                         return err;
337                 msleep(10);
338         } else
339                 CH_WARN(adapter, "PHY%d does not start in low power mode.\n",
340                         phy_addr);
341
342         /*
343          * Verify XAUI settings, but let prep succeed no matter what.
344          */
345         v = v2 = 0;
346         t3_mdio_read(phy, MDIO_MMD_PHYXS, AQ_XAUI_RX_CFG, &v);
347         t3_mdio_read(phy, MDIO_MMD_PHYXS, AQ_XAUI_TX_CFG, &v2);
348         if (v != 0x1b || v2 != 0x1b)
349                 CH_WARN(adapter,
350                         "PHY%d: incorrect XAUI settings (0x%x, 0x%x).\n",
351                         phy_addr, v, v2);
352
353 done:
354         return err;
355 }