aq100x.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  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. #include "common.h"
  33. #include "regs.h"
  34. enum {
  35. /* MDIO_DEV_PMA_PMD registers */
  36. AQ_LINK_STAT = 0xe800,
  37. AQ_IMASK_PMA = 0xf000,
  38. /* MDIO_DEV_XGXS registers */
  39. AQ_XAUI_RX_CFG = 0xc400,
  40. AQ_XAUI_TX_CFG = 0xe400,
  41. /* MDIO_DEV_ANEG registers */
  42. AQ_1G_CTRL = 0xc400,
  43. AQ_ANEG_STAT = 0xc800,
  44. /* MDIO_DEV_VEND1 registers */
  45. AQ_FW_VERSION = 0x0020,
  46. AQ_IFLAG_GLOBAL = 0xfc00,
  47. AQ_IMASK_GLOBAL = 0xff00,
  48. };
  49. enum {
  50. IMASK_PMA = 1 << 2,
  51. IMASK_GLOBAL = 1 << 15,
  52. ADV_1G_FULL = 1 << 15,
  53. ADV_1G_HALF = 1 << 14,
  54. ADV_10G_FULL = 1 << 12,
  55. AQ_RESET = (1 << 14) | (1 << 15),
  56. AQ_LOWPOWER = 1 << 12,
  57. };
  58. static int aq100x_reset(struct cphy *phy, int wait)
  59. {
  60. /*
  61. * Ignore the caller specified wait time; always wait for the reset to
  62. * complete. Can take up to 3s.
  63. */
  64. int err = t3_phy_reset(phy, MDIO_MMD_VEND1, 3000);
  65. if (err)
  66. CH_WARN(phy->adapter, "PHY%d: reset failed (0x%x).\n",
  67. phy->mdio.prtad, err);
  68. return err;
  69. }
  70. static int aq100x_intr_enable(struct cphy *phy)
  71. {
  72. int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AQ_IMASK_PMA, IMASK_PMA);
  73. if (err)
  74. return err;
  75. err = t3_mdio_write(phy, MDIO_MMD_VEND1, AQ_IMASK_GLOBAL, IMASK_GLOBAL);
  76. return err;
  77. }
  78. static int aq100x_intr_disable(struct cphy *phy)
  79. {
  80. return t3_mdio_write(phy, MDIO_MMD_VEND1, AQ_IMASK_GLOBAL, 0);
  81. }
  82. static int aq100x_intr_clear(struct cphy *phy)
  83. {
  84. unsigned int v;
  85. t3_mdio_read(phy, MDIO_MMD_VEND1, AQ_IFLAG_GLOBAL, &v);
  86. t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_STAT1, &v);
  87. return 0;
  88. }
  89. static int aq100x_intr_handler(struct cphy *phy)
  90. {
  91. int err;
  92. unsigned int cause, v;
  93. err = t3_mdio_read(phy, MDIO_MMD_VEND1, AQ_IFLAG_GLOBAL, &cause);
  94. if (err)
  95. return err;
  96. /* Read (and reset) the latching version of the status */
  97. t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_STAT1, &v);
  98. return cphy_cause_link_change;
  99. }
  100. static int aq100x_power_down(struct cphy *phy, int off)
  101. {
  102. return mdio_set_flag(&phy->mdio, phy->mdio.prtad,
  103. MDIO_MMD_PMAPMD, MDIO_CTRL1,
  104. MDIO_CTRL1_LPOWER, off);
  105. }
  106. static int aq100x_autoneg_enable(struct cphy *phy)
  107. {
  108. int err;
  109. err = aq100x_power_down(phy, 0);
  110. if (!err)
  111. err = mdio_set_flag(&phy->mdio, phy->mdio.prtad,
  112. MDIO_MMD_AN, MDIO_CTRL1,
  113. BMCR_ANENABLE | BMCR_ANRESTART, 1);
  114. return err;
  115. }
  116. static int aq100x_autoneg_restart(struct cphy *phy)
  117. {
  118. int err;
  119. err = aq100x_power_down(phy, 0);
  120. if (!err)
  121. err = mdio_set_flag(&phy->mdio, phy->mdio.prtad,
  122. MDIO_MMD_AN, MDIO_CTRL1,
  123. BMCR_ANENABLE | BMCR_ANRESTART, 1);
  124. return err;
  125. }
  126. static int aq100x_advertise(struct cphy *phy, unsigned int advertise_map)
  127. {
  128. unsigned int adv;
  129. int err;
  130. /* 10G advertisement */
  131. adv = 0;
  132. if (advertise_map & ADVERTISED_10000baseT_Full)
  133. adv |= ADV_10G_FULL;
  134. err = t3_mdio_change_bits(phy, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
  135. ADV_10G_FULL, adv);
  136. if (err)
  137. return err;
  138. /* 1G advertisement */
  139. adv = 0;
  140. if (advertise_map & ADVERTISED_1000baseT_Full)
  141. adv |= ADV_1G_FULL;
  142. if (advertise_map & ADVERTISED_1000baseT_Half)
  143. adv |= ADV_1G_HALF;
  144. err = t3_mdio_change_bits(phy, MDIO_MMD_AN, AQ_1G_CTRL,
  145. ADV_1G_FULL | ADV_1G_HALF, adv);
  146. if (err)
  147. return err;
  148. /* 100M, pause advertisement */
  149. adv = 0;
  150. if (advertise_map & ADVERTISED_100baseT_Half)
  151. adv |= ADVERTISE_100HALF;
  152. if (advertise_map & ADVERTISED_100baseT_Full)
  153. adv |= ADVERTISE_100FULL;
  154. if (advertise_map & ADVERTISED_Pause)
  155. adv |= ADVERTISE_PAUSE_CAP;
  156. if (advertise_map & ADVERTISED_Asym_Pause)
  157. adv |= ADVERTISE_PAUSE_ASYM;
  158. err = t3_mdio_change_bits(phy, MDIO_MMD_AN, MDIO_AN_ADVERTISE,
  159. 0xfe0, adv);
  160. return err;
  161. }
  162. static int aq100x_set_loopback(struct cphy *phy, int mmd, int dir, int enable)
  163. {
  164. return mdio_set_flag(&phy->mdio, phy->mdio.prtad,
  165. MDIO_MMD_PMAPMD, MDIO_CTRL1,
  166. BMCR_LOOPBACK, enable);
  167. }
  168. static int aq100x_set_speed_duplex(struct cphy *phy, int speed, int duplex)
  169. {
  170. /* no can do */
  171. return -1;
  172. }
  173. static int aq100x_get_link_status(struct cphy *phy, int *link_ok,
  174. int *speed, int *duplex, int *fc)
  175. {
  176. int err;
  177. unsigned int v;
  178. if (link_ok) {
  179. err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AQ_LINK_STAT, &v);
  180. if (err)
  181. return err;
  182. *link_ok = v & 1;
  183. if (!*link_ok)
  184. return 0;
  185. }
  186. err = t3_mdio_read(phy, MDIO_MMD_AN, AQ_ANEG_STAT, &v);
  187. if (err)
  188. return err;
  189. if (speed) {
  190. switch (v & 0x6) {
  191. case 0x6:
  192. *speed = SPEED_10000;
  193. break;
  194. case 0x4:
  195. *speed = SPEED_1000;
  196. break;
  197. case 0x2:
  198. *speed = SPEED_100;
  199. break;
  200. case 0x0:
  201. *speed = SPEED_10;
  202. break;
  203. }
  204. }
  205. if (duplex)
  206. *duplex = v & 1 ? DUPLEX_FULL : DUPLEX_HALF;
  207. return 0;
  208. }
  209. static struct cphy_ops aq100x_ops = {
  210. .reset = aq100x_reset,
  211. .intr_enable = aq100x_intr_enable,
  212. .intr_disable = aq100x_intr_disable,
  213. .intr_clear = aq100x_intr_clear,
  214. .intr_handler = aq100x_intr_handler,
  215. .autoneg_enable = aq100x_autoneg_enable,
  216. .autoneg_restart = aq100x_autoneg_restart,
  217. .advertise = aq100x_advertise,
  218. .set_loopback = aq100x_set_loopback,
  219. .set_speed_duplex = aq100x_set_speed_duplex,
  220. .get_link_status = aq100x_get_link_status,
  221. .power_down = aq100x_power_down,
  222. .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS,
  223. };
  224. int t3_aq100x_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr,
  225. const struct mdio_ops *mdio_ops)
  226. {
  227. unsigned int v, v2, gpio, wait;
  228. int err;
  229. cphy_init(phy, adapter, phy_addr, &aq100x_ops, mdio_ops,
  230. SUPPORTED_1000baseT_Full | SUPPORTED_10000baseT_Full |
  231. SUPPORTED_TP | SUPPORTED_Autoneg | SUPPORTED_AUI,
  232. "1000/10GBASE-T");
  233. /*
  234. * The PHY has been out of reset ever since the system powered up. So
  235. * we do a hard reset over here.
  236. */
  237. gpio = phy_addr ? F_GPIO10_OUT_VAL : F_GPIO6_OUT_VAL;
  238. t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, gpio, 0);
  239. msleep(1);
  240. t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, gpio, gpio);
  241. /*
  242. * Give it enough time to load the firmware and get ready for mdio.
  243. */
  244. msleep(1000);
  245. wait = 500; /* in 10ms increments */
  246. do {
  247. err = t3_mdio_read(phy, MDIO_MMD_VEND1, MDIO_CTRL1, &v);
  248. if (err || v == 0xffff) {
  249. /* Allow prep_adapter to succeed when ffff is read */
  250. CH_WARN(adapter, "PHY%d: reset failed (0x%x, 0x%x).\n",
  251. phy_addr, err, v);
  252. goto done;
  253. }
  254. v &= AQ_RESET;
  255. if (v)
  256. msleep(10);
  257. } while (v && --wait);
  258. if (v) {
  259. CH_WARN(adapter, "PHY%d: reset timed out (0x%x).\n",
  260. phy_addr, v);
  261. goto done; /* let prep_adapter succeed */
  262. }
  263. /* Datasheet says 3s max but this has been observed */
  264. wait = (500 - wait) * 10 + 1000;
  265. if (wait > 3000)
  266. CH_WARN(adapter, "PHY%d: reset took %ums\n", phy_addr, wait);
  267. /* Firmware version check. */
  268. t3_mdio_read(phy, MDIO_MMD_VEND1, AQ_FW_VERSION, &v);
  269. if (v != 101)
  270. CH_WARN(adapter, "PHY%d: unsupported firmware %d\n",
  271. phy_addr, v);
  272. /*
  273. * The PHY should start in really-low-power mode. Prepare it for normal
  274. * operations.
  275. */
  276. err = t3_mdio_read(phy, MDIO_MMD_VEND1, MDIO_CTRL1, &v);
  277. if (err)
  278. return err;
  279. if (v & AQ_LOWPOWER) {
  280. err = t3_mdio_change_bits(phy, MDIO_MMD_VEND1, MDIO_CTRL1,
  281. AQ_LOWPOWER, 0);
  282. if (err)
  283. return err;
  284. msleep(10);
  285. } else
  286. CH_WARN(adapter, "PHY%d does not start in low power mode.\n",
  287. phy_addr);
  288. /*
  289. * Verify XAUI settings, but let prep succeed no matter what.
  290. */
  291. v = v2 = 0;
  292. t3_mdio_read(phy, MDIO_MMD_PHYXS, AQ_XAUI_RX_CFG, &v);
  293. t3_mdio_read(phy, MDIO_MMD_PHYXS, AQ_XAUI_TX_CFG, &v2);
  294. if (v != 0x1b || v2 != 0x1b)
  295. CH_WARN(adapter,
  296. "PHY%d: incorrect XAUI settings (0x%x, 0x%x).\n",
  297. phy_addr, v, v2);
  298. done:
  299. return err;
  300. }