qt202x_phy.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  1. /****************************************************************************
  2. * Driver for Solarflare Solarstorm network controllers and boards
  3. * Copyright 2006-2009 Solarflare Communications Inc.
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of the GNU General Public License version 2 as published
  7. * by the Free Software Foundation, incorporated herein by reference.
  8. */
  9. /*
  10. * Driver for AMCC QT202x SFP+ and XFP adapters; see www.amcc.com for details
  11. */
  12. #include <linux/timer.h>
  13. #include <linux/delay.h>
  14. #include "efx.h"
  15. #include "mdio_10g.h"
  16. #include "phy.h"
  17. #include "nic.h"
  18. #define QT202X_REQUIRED_DEVS (MDIO_DEVS_PCS | \
  19. MDIO_DEVS_PMAPMD | \
  20. MDIO_DEVS_PHYXS)
  21. #define QT202X_LOOPBACKS ((1 << LOOPBACK_PCS) | \
  22. (1 << LOOPBACK_PMAPMD) | \
  23. (1 << LOOPBACK_PHYXS_WS))
  24. /****************************************************************************/
  25. /* Quake-specific MDIO registers */
  26. #define MDIO_QUAKE_LED0_REG (0xD006)
  27. /* QT2025C only */
  28. #define PCS_FW_HEARTBEAT_REG 0xd7ee
  29. #define PCS_FW_HEARTB_LBN 0
  30. #define PCS_FW_HEARTB_WIDTH 8
  31. #define PCS_FW_PRODUCT_CODE_1 0xd7f0
  32. #define PCS_FW_VERSION_1 0xd7f3
  33. #define PCS_FW_BUILD_1 0xd7f6
  34. #define PCS_UC8051_STATUS_REG 0xd7fd
  35. #define PCS_UC_STATUS_LBN 0
  36. #define PCS_UC_STATUS_WIDTH 8
  37. #define PCS_UC_STATUS_FW_SAVE 0x20
  38. #define PMA_PMD_FTX_CTRL2_REG 0xc309
  39. #define PMA_PMD_FTX_STATIC_LBN 13
  40. #define PMA_PMD_VEND1_REG 0xc001
  41. #define PMA_PMD_VEND1_LBTXD_LBN 15
  42. #define PCS_VEND1_REG 0xc000
  43. #define PCS_VEND1_LBTXD_LBN 5
  44. void falcon_qt202x_set_led(struct efx_nic *p, int led, int mode)
  45. {
  46. int addr = MDIO_QUAKE_LED0_REG + led;
  47. efx_mdio_write(p, MDIO_MMD_PMAPMD, addr, mode);
  48. }
  49. struct qt202x_phy_data {
  50. enum efx_phy_mode phy_mode;
  51. bool bug17190_in_bad_state;
  52. unsigned long bug17190_timer;
  53. u32 firmware_ver;
  54. };
  55. #define QT2022C2_MAX_RESET_TIME 500
  56. #define QT2022C2_RESET_WAIT 10
  57. #define QT2025C_MAX_HEARTB_TIME (5 * HZ)
  58. #define QT2025C_HEARTB_WAIT 100
  59. #define QT2025C_MAX_FWSTART_TIME (25 * HZ / 10)
  60. #define QT2025C_FWSTART_WAIT 100
  61. #define BUG17190_INTERVAL (2 * HZ)
  62. static int qt2025c_wait_heartbeat(struct efx_nic *efx)
  63. {
  64. unsigned long timeout = jiffies + QT2025C_MAX_HEARTB_TIME;
  65. int reg, old_counter = 0;
  66. /* Wait for firmware heartbeat to start */
  67. for (;;) {
  68. int counter;
  69. reg = efx_mdio_read(efx, MDIO_MMD_PCS, PCS_FW_HEARTBEAT_REG);
  70. if (reg < 0)
  71. return reg;
  72. counter = ((reg >> PCS_FW_HEARTB_LBN) &
  73. ((1 << PCS_FW_HEARTB_WIDTH) - 1));
  74. if (old_counter == 0)
  75. old_counter = counter;
  76. else if (counter != old_counter)
  77. break;
  78. if (time_after(jiffies, timeout)) {
  79. /* Some cables have EEPROMs that conflict with the
  80. * PHY's on-board EEPROM so it cannot load firmware */
  81. EFX_ERR(efx, "If an SFP+ direct attach cable is"
  82. " connected, please check that it complies"
  83. " with the SFP+ specification\n");
  84. return -ETIMEDOUT;
  85. }
  86. msleep(QT2025C_HEARTB_WAIT);
  87. }
  88. return 0;
  89. }
  90. static int qt2025c_wait_fw_status_good(struct efx_nic *efx)
  91. {
  92. unsigned long timeout = jiffies + QT2025C_MAX_FWSTART_TIME;
  93. int reg;
  94. /* Wait for firmware status to look good */
  95. for (;;) {
  96. reg = efx_mdio_read(efx, MDIO_MMD_PCS, PCS_UC8051_STATUS_REG);
  97. if (reg < 0)
  98. return reg;
  99. if ((reg &
  100. ((1 << PCS_UC_STATUS_WIDTH) - 1) << PCS_UC_STATUS_LBN) >=
  101. PCS_UC_STATUS_FW_SAVE)
  102. break;
  103. if (time_after(jiffies, timeout))
  104. return -ETIMEDOUT;
  105. msleep(QT2025C_FWSTART_WAIT);
  106. }
  107. return 0;
  108. }
  109. static void qt2025c_restart_firmware(struct efx_nic *efx)
  110. {
  111. /* Restart microcontroller execution of firmware from RAM */
  112. efx_mdio_write(efx, 3, 0xe854, 0x00c0);
  113. efx_mdio_write(efx, 3, 0xe854, 0x0040);
  114. msleep(50);
  115. }
  116. static int qt2025c_wait_reset(struct efx_nic *efx)
  117. {
  118. int rc;
  119. rc = qt2025c_wait_heartbeat(efx);
  120. if (rc != 0)
  121. return rc;
  122. rc = qt2025c_wait_fw_status_good(efx);
  123. if (rc == -ETIMEDOUT) {
  124. /* Bug 17689: occasionally heartbeat starts but firmware status
  125. * code never progresses beyond 0x00. Try again, once, after
  126. * restarting execution of the firmware image. */
  127. EFX_LOG(efx, "bashing QT2025C microcontroller\n");
  128. qt2025c_restart_firmware(efx);
  129. rc = qt2025c_wait_heartbeat(efx);
  130. if (rc != 0)
  131. return rc;
  132. rc = qt2025c_wait_fw_status_good(efx);
  133. }
  134. return rc;
  135. }
  136. static void qt2025c_firmware_id(struct efx_nic *efx)
  137. {
  138. struct qt202x_phy_data *phy_data = efx->phy_data;
  139. u8 firmware_id[9];
  140. size_t i;
  141. for (i = 0; i < sizeof(firmware_id); i++)
  142. firmware_id[i] = efx_mdio_read(efx, MDIO_MMD_PCS,
  143. PCS_FW_PRODUCT_CODE_1 + i);
  144. EFX_INFO(efx, "QT2025C firmware %xr%d v%d.%d.%d.%d [20%02d-%02d-%02d]\n",
  145. (firmware_id[0] << 8) | firmware_id[1], firmware_id[2],
  146. firmware_id[3] >> 4, firmware_id[3] & 0xf,
  147. firmware_id[4], firmware_id[5],
  148. firmware_id[6], firmware_id[7], firmware_id[8]);
  149. phy_data->firmware_ver = ((firmware_id[3] & 0xf0) << 20) |
  150. ((firmware_id[3] & 0x0f) << 16) |
  151. (firmware_id[4] << 8) | firmware_id[5];
  152. }
  153. static void qt2025c_bug17190_workaround(struct efx_nic *efx)
  154. {
  155. struct qt202x_phy_data *phy_data = efx->phy_data;
  156. /* The PHY can get stuck in a state where it reports PHY_XS and PMA/PMD
  157. * layers up, but PCS down (no block_lock). If we notice this state
  158. * persisting for a couple of seconds, we switch PMA/PMD loopback
  159. * briefly on and then off again, which is normally sufficient to
  160. * recover it.
  161. */
  162. if (efx->link_state.up ||
  163. !efx_mdio_links_ok(efx, MDIO_DEVS_PMAPMD | MDIO_DEVS_PHYXS)) {
  164. phy_data->bug17190_in_bad_state = false;
  165. return;
  166. }
  167. if (!phy_data->bug17190_in_bad_state) {
  168. phy_data->bug17190_in_bad_state = true;
  169. phy_data->bug17190_timer = jiffies + BUG17190_INTERVAL;
  170. return;
  171. }
  172. if (time_after_eq(jiffies, phy_data->bug17190_timer)) {
  173. EFX_LOG(efx, "bashing QT2025C PMA/PMD\n");
  174. efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, MDIO_CTRL1,
  175. MDIO_PMA_CTRL1_LOOPBACK, true);
  176. msleep(100);
  177. efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, MDIO_CTRL1,
  178. MDIO_PMA_CTRL1_LOOPBACK, false);
  179. phy_data->bug17190_timer = jiffies + BUG17190_INTERVAL;
  180. }
  181. }
  182. static int qt2025c_select_phy_mode(struct efx_nic *efx)
  183. {
  184. struct qt202x_phy_data *phy_data = efx->phy_data;
  185. struct falcon_board *board = falcon_board(efx);
  186. int reg, rc, i;
  187. uint16_t phy_op_mode;
  188. /* Only 2.0.1.0+ PHY firmware supports the more optimal SFP+
  189. * Self-Configure mode. Don't attempt any switching if we encounter
  190. * older firmware. */
  191. if (phy_data->firmware_ver < 0x02000100)
  192. return 0;
  193. /* In general we will get optimal behaviour in "SFP+ Self-Configure"
  194. * mode; however, that powers down most of the PHY when no module is
  195. * present, so we must use a different mode (any fixed mode will do)
  196. * to be sure that loopbacks will work. */
  197. phy_op_mode = (efx->loopback_mode == LOOPBACK_NONE) ? 0x0038 : 0x0020;
  198. /* Only change mode if really necessary */
  199. reg = efx_mdio_read(efx, 1, 0xc319);
  200. if ((reg & 0x0038) == phy_op_mode)
  201. return 0;
  202. EFX_LOG(efx, "Switching PHY to mode 0x%04x\n", phy_op_mode);
  203. /* This sequence replicates the register writes configured in the boot
  204. * EEPROM (including the differences between board revisions), except
  205. * that the operating mode is changed, and the PHY is prevented from
  206. * unnecessarily reloading the main firmware image again. */
  207. efx_mdio_write(efx, 1, 0xc300, 0x0000);
  208. /* (Note: this portion of the boot EEPROM sequence, which bit-bashes 9
  209. * STOPs onto the firmware/module I2C bus to reset it, varies across
  210. * board revisions, as the bus is connected to different GPIO/LED
  211. * outputs on the PHY.) */
  212. if (board->major == 0 && board->minor < 2) {
  213. efx_mdio_write(efx, 1, 0xc303, 0x4498);
  214. for (i = 0; i < 9; i++) {
  215. efx_mdio_write(efx, 1, 0xc303, 0x4488);
  216. efx_mdio_write(efx, 1, 0xc303, 0x4480);
  217. efx_mdio_write(efx, 1, 0xc303, 0x4490);
  218. efx_mdio_write(efx, 1, 0xc303, 0x4498);
  219. }
  220. } else {
  221. efx_mdio_write(efx, 1, 0xc303, 0x0920);
  222. efx_mdio_write(efx, 1, 0xd008, 0x0004);
  223. for (i = 0; i < 9; i++) {
  224. efx_mdio_write(efx, 1, 0xc303, 0x0900);
  225. efx_mdio_write(efx, 1, 0xd008, 0x0005);
  226. efx_mdio_write(efx, 1, 0xc303, 0x0920);
  227. efx_mdio_write(efx, 1, 0xd008, 0x0004);
  228. }
  229. efx_mdio_write(efx, 1, 0xc303, 0x4900);
  230. }
  231. efx_mdio_write(efx, 1, 0xc303, 0x4900);
  232. efx_mdio_write(efx, 1, 0xc302, 0x0004);
  233. efx_mdio_write(efx, 1, 0xc316, 0x0013);
  234. efx_mdio_write(efx, 1, 0xc318, 0x0054);
  235. efx_mdio_write(efx, 1, 0xc319, phy_op_mode);
  236. efx_mdio_write(efx, 1, 0xc31a, 0x0098);
  237. efx_mdio_write(efx, 3, 0x0026, 0x0e00);
  238. efx_mdio_write(efx, 3, 0x0027, 0x0013);
  239. efx_mdio_write(efx, 3, 0x0028, 0xa528);
  240. efx_mdio_write(efx, 1, 0xd006, 0x000a);
  241. efx_mdio_write(efx, 1, 0xd007, 0x0009);
  242. efx_mdio_write(efx, 1, 0xd008, 0x0004);
  243. /* This additional write is not present in the boot EEPROM. It
  244. * prevents the PHY's internal boot ROM doing another pointless (and
  245. * slow) reload of the firmware image (the microcontroller's code
  246. * memory is not affected by the microcontroller reset). */
  247. efx_mdio_write(efx, 1, 0xc317, 0x00ff);
  248. efx_mdio_write(efx, 1, 0xc300, 0x0002);
  249. msleep(20);
  250. /* Restart microcontroller execution of firmware from RAM */
  251. qt2025c_restart_firmware(efx);
  252. /* Wait for the microcontroller to be ready again */
  253. rc = qt2025c_wait_reset(efx);
  254. if (rc < 0) {
  255. EFX_ERR(efx, "PHY microcontroller reset during mode switch "
  256. "timed out\n");
  257. return rc;
  258. }
  259. return 0;
  260. }
  261. static int qt202x_reset_phy(struct efx_nic *efx)
  262. {
  263. int rc;
  264. if (efx->phy_type == PHY_TYPE_QT2025C) {
  265. /* Wait for the reset triggered by falcon_reset_hw()
  266. * to complete */
  267. rc = qt2025c_wait_reset(efx);
  268. if (rc < 0)
  269. goto fail;
  270. } else {
  271. /* Reset the PHYXS MMD. This is documented as doing
  272. * a complete soft reset. */
  273. rc = efx_mdio_reset_mmd(efx, MDIO_MMD_PHYXS,
  274. QT2022C2_MAX_RESET_TIME /
  275. QT2022C2_RESET_WAIT,
  276. QT2022C2_RESET_WAIT);
  277. if (rc < 0)
  278. goto fail;
  279. }
  280. /* Wait 250ms for the PHY to complete bootup */
  281. msleep(250);
  282. /* Check that all the MMDs we expect are present and responding. We
  283. * expect faults on some if the link is down, but not on the PHY XS */
  284. rc = efx_mdio_check_mmds(efx, QT202X_REQUIRED_DEVS, MDIO_DEVS_PHYXS);
  285. if (rc < 0)
  286. goto fail;
  287. falcon_board(efx)->type->init_phy(efx);
  288. return rc;
  289. fail:
  290. EFX_ERR(efx, "PHY reset timed out\n");
  291. return rc;
  292. }
  293. static int qt202x_phy_probe(struct efx_nic *efx)
  294. {
  295. struct qt202x_phy_data *phy_data;
  296. phy_data = kzalloc(sizeof(struct qt202x_phy_data), GFP_KERNEL);
  297. if (!phy_data)
  298. return -ENOMEM;
  299. efx->phy_data = phy_data;
  300. phy_data->phy_mode = efx->phy_mode;
  301. phy_data->bug17190_in_bad_state = false;
  302. phy_data->bug17190_timer = 0;
  303. efx->mdio.mmds = QT202X_REQUIRED_DEVS;
  304. efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22;
  305. efx->loopback_modes = QT202X_LOOPBACKS | FALCON_XMAC_LOOPBACKS;
  306. return 0;
  307. }
  308. static int qt202x_phy_init(struct efx_nic *efx)
  309. {
  310. u32 devid;
  311. int rc;
  312. rc = qt202x_reset_phy(efx);
  313. if (rc) {
  314. EFX_ERR(efx, "PHY init failed\n");
  315. return rc;
  316. }
  317. devid = efx_mdio_read_id(efx, MDIO_MMD_PHYXS);
  318. EFX_INFO(efx, "PHY ID reg %x (OUI %06x model %02x revision %x)\n",
  319. devid, efx_mdio_id_oui(devid), efx_mdio_id_model(devid),
  320. efx_mdio_id_rev(devid));
  321. if (efx->phy_type == PHY_TYPE_QT2025C)
  322. qt2025c_firmware_id(efx);
  323. return 0;
  324. }
  325. static int qt202x_link_ok(struct efx_nic *efx)
  326. {
  327. return efx_mdio_links_ok(efx, QT202X_REQUIRED_DEVS);
  328. }
  329. static bool qt202x_phy_poll(struct efx_nic *efx)
  330. {
  331. bool was_up = efx->link_state.up;
  332. efx->link_state.up = qt202x_link_ok(efx);
  333. efx->link_state.speed = 10000;
  334. efx->link_state.fd = true;
  335. efx->link_state.fc = efx->wanted_fc;
  336. if (efx->phy_type == PHY_TYPE_QT2025C)
  337. qt2025c_bug17190_workaround(efx);
  338. return efx->link_state.up != was_up;
  339. }
  340. static int qt202x_phy_reconfigure(struct efx_nic *efx)
  341. {
  342. struct qt202x_phy_data *phy_data = efx->phy_data;
  343. if (efx->phy_type == PHY_TYPE_QT2025C) {
  344. int rc = qt2025c_select_phy_mode(efx);
  345. if (rc)
  346. return rc;
  347. /* There are several different register bits which can
  348. * disable TX (and save power) on direct-attach cables
  349. * or optical transceivers, varying somewhat between
  350. * firmware versions. Only 'static mode' appears to
  351. * cover everything. */
  352. mdio_set_flag(
  353. &efx->mdio, efx->mdio.prtad, MDIO_MMD_PMAPMD,
  354. PMA_PMD_FTX_CTRL2_REG, 1 << PMA_PMD_FTX_STATIC_LBN,
  355. efx->phy_mode & PHY_MODE_TX_DISABLED ||
  356. efx->phy_mode & PHY_MODE_LOW_POWER ||
  357. efx->loopback_mode == LOOPBACK_PCS ||
  358. efx->loopback_mode == LOOPBACK_PMAPMD);
  359. } else {
  360. /* Reset the PHY when moving from tx off to tx on */
  361. if (!(efx->phy_mode & PHY_MODE_TX_DISABLED) &&
  362. (phy_data->phy_mode & PHY_MODE_TX_DISABLED))
  363. qt202x_reset_phy(efx);
  364. efx_mdio_transmit_disable(efx);
  365. }
  366. efx_mdio_phy_reconfigure(efx);
  367. phy_data->phy_mode = efx->phy_mode;
  368. return 0;
  369. }
  370. static void qt202x_phy_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
  371. {
  372. mdio45_ethtool_gset(&efx->mdio, ecmd);
  373. }
  374. static void qt202x_phy_remove(struct efx_nic *efx)
  375. {
  376. /* Free the context block */
  377. kfree(efx->phy_data);
  378. efx->phy_data = NULL;
  379. }
  380. struct efx_phy_operations falcon_qt202x_phy_ops = {
  381. .probe = qt202x_phy_probe,
  382. .init = qt202x_phy_init,
  383. .reconfigure = qt202x_phy_reconfigure,
  384. .poll = qt202x_phy_poll,
  385. .fini = efx_port_dummy_op_void,
  386. .remove = qt202x_phy_remove,
  387. .get_settings = qt202x_phy_get_settings,
  388. .set_settings = efx_mdio_set_settings,
  389. };