Merge branch 'linux-2.6.31.y' of git://git.kernel.org/pub/scm/linux/kernel/git/inaky...
[linux-2.6] / 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_1G_CTRL      = 0xc400,
47         AQ_ANEG_STAT    = 0xc800,
48
49         /* MDIO_DEV_VEND1 registers */
50         AQ_FW_VERSION   = 0x0020,
51         AQ_IFLAG_GLOBAL = 0xfc00,
52         AQ_IMASK_GLOBAL = 0xff00,
53 };
54
55 enum {
56         IMASK_PMA       = 1 << 2,
57         IMASK_GLOBAL    = 1 << 15,
58         ADV_1G_FULL     = 1 << 15,
59         ADV_1G_HALF     = 1 << 14,
60         ADV_10G_FULL    = 1 << 12,
61         AQ_RESET        = (1 << 14) | (1 << 15),
62         AQ_LOWPOWER     = 1 << 12,
63 };
64
65 static int aq100x_reset(struct cphy *phy, int wait)
66 {
67         /*
68          * Ignore the caller specified wait time; always wait for the reset to
69          * complete. Can take up to 3s.
70          */
71         int err = t3_phy_reset(phy, MDIO_MMD_VEND1, 3000);
72
73         if (err)
74                 CH_WARN(phy->adapter, "PHY%d: reset failed (0x%x).\n",
75                         phy->mdio.prtad, err);
76
77         return err;
78 }
79
80 static int aq100x_intr_enable(struct cphy *phy)
81 {
82         int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AQ_IMASK_PMA, IMASK_PMA);
83         if (err)
84                 return err;
85
86         err = t3_mdio_write(phy, MDIO_MMD_VEND1, AQ_IMASK_GLOBAL, IMASK_GLOBAL);
87         return err;
88 }
89
90 static int aq100x_intr_disable(struct cphy *phy)
91 {
92         return t3_mdio_write(phy, MDIO_MMD_VEND1, AQ_IMASK_GLOBAL, 0);
93 }
94
95 static int aq100x_intr_clear(struct cphy *phy)
96 {
97         unsigned int v;
98
99         t3_mdio_read(phy, MDIO_MMD_VEND1, AQ_IFLAG_GLOBAL, &v);
100         t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_STAT1, &v);
101
102         return 0;
103 }
104
105 static int aq100x_intr_handler(struct cphy *phy)
106 {
107         int err;
108         unsigned int cause, v;
109
110         err = t3_mdio_read(phy, MDIO_MMD_VEND1, AQ_IFLAG_GLOBAL, &cause);
111         if (err)
112                 return err;
113
114         /* Read (and reset) the latching version of the status */
115         t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_STAT1, &v);
116
117         return cphy_cause_link_change;
118 }
119
120 static int aq100x_power_down(struct cphy *phy, int off)
121 {
122         return mdio_set_flag(&phy->mdio, phy->mdio.prtad,
123                              MDIO_MMD_PMAPMD, MDIO_CTRL1,
124                              MDIO_CTRL1_LPOWER, off);
125 }
126
127 static int aq100x_autoneg_enable(struct cphy *phy)
128 {
129         int err;
130
131         err = aq100x_power_down(phy, 0);
132         if (!err)
133                 err = mdio_set_flag(&phy->mdio, phy->mdio.prtad,
134                                     MDIO_MMD_AN, MDIO_CTRL1,
135                                     BMCR_ANENABLE | BMCR_ANRESTART, 1);
136
137         return err;
138 }
139
140 static int aq100x_autoneg_restart(struct cphy *phy)
141 {
142         int err;
143
144         err = aq100x_power_down(phy, 0);
145         if (!err)
146                 err = mdio_set_flag(&phy->mdio, phy->mdio.prtad,
147                                     MDIO_MMD_AN, MDIO_CTRL1,
148                                     BMCR_ANENABLE | BMCR_ANRESTART, 1);
149
150         return err;
151 }
152
153 static int aq100x_advertise(struct cphy *phy, unsigned int advertise_map)
154 {
155         unsigned int adv;
156         int err;
157
158         /* 10G advertisement */
159         adv = 0;
160         if (advertise_map & ADVERTISED_10000baseT_Full)
161                 adv |= ADV_10G_FULL;
162         err = t3_mdio_change_bits(phy, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
163                                   ADV_10G_FULL, adv);
164         if (err)
165                 return err;
166
167         /* 1G advertisement */
168         adv = 0;
169         if (advertise_map & ADVERTISED_1000baseT_Full)
170                 adv |= ADV_1G_FULL;
171         if (advertise_map & ADVERTISED_1000baseT_Half)
172                 adv |= ADV_1G_HALF;
173         err = t3_mdio_change_bits(phy, MDIO_MMD_AN, AQ_1G_CTRL,
174                                   ADV_1G_FULL | ADV_1G_HALF, adv);
175         if (err)
176                 return err;
177
178         /* 100M, pause advertisement */
179         adv = 0;
180         if (advertise_map & ADVERTISED_100baseT_Half)
181                 adv |= ADVERTISE_100HALF;
182         if (advertise_map & ADVERTISED_100baseT_Full)
183                 adv |= ADVERTISE_100FULL;
184         if (advertise_map & ADVERTISED_Pause)
185                 adv |= ADVERTISE_PAUSE_CAP;
186         if (advertise_map & ADVERTISED_Asym_Pause)
187                 adv |= ADVERTISE_PAUSE_ASYM;
188         err = t3_mdio_change_bits(phy, MDIO_MMD_AN, MDIO_AN_ADVERTISE,
189                                   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 }