Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
aq100x.c
Go to the documentation of this file.
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,
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,
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,
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;
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;
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;
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,
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,
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,
275  "1000/10GBASE-T");
276 
277  /*
278  * The PHY has been out of reset ever since the system powered up. So
279  * we do a hard reset over here.
280  */
281  gpio = phy_addr ? F_GPIO10_OUT_VAL : F_GPIO6_OUT_VAL;
282  t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, gpio, 0);
283  msleep(1);
284  t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, gpio, gpio);
285 
286  /*
287  * Give it enough time to load the firmware and get ready for mdio.
288  */
289  msleep(1000);
290  wait = 500; /* in 10ms increments */
291  do {
292  err = t3_mdio_read(phy, MDIO_MMD_VEND1, MDIO_CTRL1, &v);
293  if (err || v == 0xffff) {
294 
295  /* Allow prep_adapter to succeed when ffff is read */
296 
297  CH_WARN(adapter, "PHY%d: reset failed (0x%x, 0x%x).\n",
298  phy_addr, err, v);
299  goto done;
300  }
301 
302  v &= AQ_RESET;
303  if (v)
304  msleep(10);
305  } while (v && --wait);
306  if (v) {
307  CH_WARN(adapter, "PHY%d: reset timed out (0x%x).\n",
308  phy_addr, v);
309 
310  goto done; /* let prep_adapter succeed */
311  }
312 
313  /* Datasheet says 3s max but this has been observed */
314  wait = (500 - wait) * 10 + 1000;
315  if (wait > 3000)
316  CH_WARN(adapter, "PHY%d: reset took %ums\n", phy_addr, wait);
317 
318  /* Firmware version check. */
319  t3_mdio_read(phy, MDIO_MMD_VEND1, AQ_FW_VERSION, &v);
320  if (v != 101)
321  CH_WARN(adapter, "PHY%d: unsupported firmware %d\n",
322  phy_addr, v);
323 
324  /*
325  * The PHY should start in really-low-power mode. Prepare it for normal
326  * operations.
327  */
328  err = t3_mdio_read(phy, MDIO_MMD_VEND1, MDIO_CTRL1, &v);
329  if (err)
330  return err;
331  if (v & AQ_LOWPOWER) {
333  AQ_LOWPOWER, 0);
334  if (err)
335  return err;
336  msleep(10);
337  } else
338  CH_WARN(adapter, "PHY%d does not start in low power mode.\n",
339  phy_addr);
340 
341  /*
342  * Verify XAUI settings, but let prep succeed no matter what.
343  */
344  v = v2 = 0;
345  t3_mdio_read(phy, MDIO_MMD_PHYXS, AQ_XAUI_RX_CFG, &v);
346  t3_mdio_read(phy, MDIO_MMD_PHYXS, AQ_XAUI_TX_CFG, &v2);
347  if (v != 0x1b || v2 != 0x1b)
348  CH_WARN(adapter,
349  "PHY%d: incorrect XAUI settings (0x%x, 0x%x).\n",
350  phy_addr, v, v2);
351 
352 done:
353  return err;
354 }