mdio_10g.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. /****************************************************************************
  2. * Driver for Solarflare Solarstorm network controllers and boards
  3. * Copyright 2006-2008 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. * Useful functions for working with MDIO clause 45 PHYs
  11. */
  12. #include <linux/types.h>
  13. #include <linux/ethtool.h>
  14. #include <linux/delay.h>
  15. #include "net_driver.h"
  16. #include "mdio_10g.h"
  17. #include "boards.h"
  18. int mdio_clause45_reset_mmd(struct efx_nic *port, int mmd,
  19. int spins, int spintime)
  20. {
  21. u32 ctrl;
  22. int phy_id = port->mii.phy_id;
  23. /* Catch callers passing values in the wrong units (or just silly) */
  24. EFX_BUG_ON_PARANOID(spins * spintime >= 5000);
  25. mdio_clause45_write(port, phy_id, mmd, MDIO_MMDREG_CTRL1,
  26. (1 << MDIO_MMDREG_CTRL1_RESET_LBN));
  27. /* Wait for the reset bit to clear. */
  28. do {
  29. msleep(spintime);
  30. ctrl = mdio_clause45_read(port, phy_id, mmd, MDIO_MMDREG_CTRL1);
  31. spins--;
  32. } while (spins && (ctrl & (1 << MDIO_MMDREG_CTRL1_RESET_LBN)));
  33. return spins ? spins : -ETIMEDOUT;
  34. }
  35. static int mdio_clause45_check_mmd(struct efx_nic *efx, int mmd,
  36. int fault_fatal)
  37. {
  38. int status;
  39. int phy_id = efx->mii.phy_id;
  40. /* Read MMD STATUS2 to check it is responding. */
  41. status = mdio_clause45_read(efx, phy_id, mmd, MDIO_MMDREG_STAT2);
  42. if (((status >> MDIO_MMDREG_STAT2_PRESENT_LBN) &
  43. ((1 << MDIO_MMDREG_STAT2_PRESENT_WIDTH) - 1)) !=
  44. MDIO_MMDREG_STAT2_PRESENT_VAL) {
  45. EFX_ERR(efx, "PHY MMD %d not responding.\n", mmd);
  46. return -EIO;
  47. }
  48. /* Read MMD STATUS 1 to check for fault. */
  49. status = mdio_clause45_read(efx, phy_id, mmd, MDIO_MMDREG_STAT1);
  50. if ((status & (1 << MDIO_MMDREG_STAT1_FAULT_LBN)) != 0) {
  51. if (fault_fatal) {
  52. EFX_ERR(efx, "PHY MMD %d reporting fatal"
  53. " fault: status %x\n", mmd, status);
  54. return -EIO;
  55. } else {
  56. EFX_LOG(efx, "PHY MMD %d reporting status"
  57. " %x (expected)\n", mmd, status);
  58. }
  59. }
  60. return 0;
  61. }
  62. /* This ought to be ridiculous overkill. We expect it to fail rarely */
  63. #define MDIO45_RESET_TIME 1000 /* ms */
  64. #define MDIO45_RESET_ITERS 100
  65. int mdio_clause45_wait_reset_mmds(struct efx_nic *efx,
  66. unsigned int mmd_mask)
  67. {
  68. const int spintime = MDIO45_RESET_TIME / MDIO45_RESET_ITERS;
  69. int tries = MDIO45_RESET_ITERS;
  70. int rc = 0;
  71. int in_reset;
  72. while (tries) {
  73. int mask = mmd_mask;
  74. int mmd = 0;
  75. int stat;
  76. in_reset = 0;
  77. while (mask) {
  78. if (mask & 1) {
  79. stat = mdio_clause45_read(efx,
  80. efx->mii.phy_id,
  81. mmd,
  82. MDIO_MMDREG_CTRL1);
  83. if (stat < 0) {
  84. EFX_ERR(efx, "failed to read status of"
  85. " MMD %d\n", mmd);
  86. return -EIO;
  87. }
  88. if (stat & (1 << MDIO_MMDREG_CTRL1_RESET_LBN))
  89. in_reset |= (1 << mmd);
  90. }
  91. mask = mask >> 1;
  92. mmd++;
  93. }
  94. if (!in_reset)
  95. break;
  96. tries--;
  97. msleep(spintime);
  98. }
  99. if (in_reset != 0) {
  100. EFX_ERR(efx, "not all MMDs came out of reset in time."
  101. " MMDs still in reset: %x\n", in_reset);
  102. rc = -ETIMEDOUT;
  103. }
  104. return rc;
  105. }
  106. int mdio_clause45_check_mmds(struct efx_nic *efx,
  107. unsigned int mmd_mask, unsigned int fatal_mask)
  108. {
  109. int devices, mmd = 0;
  110. int probe_mmd;
  111. /* Historically we have probed the PHYXS to find out what devices are
  112. * present,but that doesn't work so well if the PHYXS isn't expected
  113. * to exist, if so just find the first item in the list supplied. */
  114. probe_mmd = (mmd_mask & MDIO_MMDREG_DEVS0_PHYXS) ? MDIO_MMD_PHYXS :
  115. __ffs(mmd_mask);
  116. devices = mdio_clause45_read(efx, efx->mii.phy_id,
  117. probe_mmd, MDIO_MMDREG_DEVS0);
  118. /* Check all the expected MMDs are present */
  119. if (devices < 0) {
  120. EFX_ERR(efx, "failed to read devices present\n");
  121. return -EIO;
  122. }
  123. if ((devices & mmd_mask) != mmd_mask) {
  124. EFX_ERR(efx, "required MMDs not present: got %x, "
  125. "wanted %x\n", devices, mmd_mask);
  126. return -ENODEV;
  127. }
  128. EFX_TRACE(efx, "Devices present: %x\n", devices);
  129. /* Check all required MMDs are responding and happy. */
  130. while (mmd_mask) {
  131. if (mmd_mask & 1) {
  132. int fault_fatal = fatal_mask & 1;
  133. if (mdio_clause45_check_mmd(efx, mmd, fault_fatal))
  134. return -EIO;
  135. }
  136. mmd_mask = mmd_mask >> 1;
  137. fatal_mask = fatal_mask >> 1;
  138. mmd++;
  139. }
  140. return 0;
  141. }
  142. int mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask)
  143. {
  144. int phy_id = efx->mii.phy_id;
  145. int status;
  146. int ok = 1;
  147. int mmd = 0;
  148. int good;
  149. while (mmd_mask) {
  150. if (mmd_mask & 1) {
  151. /* Double reads because link state is latched, and a
  152. * read moves the current state into the register */
  153. status = mdio_clause45_read(efx, phy_id,
  154. mmd, MDIO_MMDREG_STAT1);
  155. status = mdio_clause45_read(efx, phy_id,
  156. mmd, MDIO_MMDREG_STAT1);
  157. good = status & (1 << MDIO_MMDREG_STAT1_LINK_LBN);
  158. ok = ok && good;
  159. }
  160. mmd_mask = (mmd_mask >> 1);
  161. mmd++;
  162. }
  163. return ok;
  164. }
  165. /**
  166. * mdio_clause45_get_settings - Read (some of) the PHY settings over MDIO.
  167. * @efx: Efx NIC
  168. * @ecmd: Buffer for settings
  169. *
  170. * On return the 'port', 'speed', 'supported' and 'advertising' fields of
  171. * ecmd have been filled out based on the PMA type.
  172. */
  173. void mdio_clause45_get_settings(struct efx_nic *efx,
  174. struct ethtool_cmd *ecmd)
  175. {
  176. int pma_type;
  177. /* If no PMA is present we are presumably talking something XAUI-ish
  178. * like CX4. Which we report as FIBRE (see below) */
  179. if ((efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_PMAPMD)) == 0) {
  180. ecmd->speed = SPEED_10000;
  181. ecmd->port = PORT_FIBRE;
  182. ecmd->supported = SUPPORTED_FIBRE;
  183. ecmd->advertising = ADVERTISED_FIBRE;
  184. return;
  185. }
  186. pma_type = mdio_clause45_read(efx, efx->mii.phy_id,
  187. MDIO_MMD_PMAPMD, MDIO_MMDREG_CTRL2);
  188. pma_type &= MDIO_PMAPMD_CTRL2_TYPE_MASK;
  189. switch (pma_type) {
  190. /* We represent CX4 as fibre in the absence of anything
  191. better. */
  192. case MDIO_PMAPMD_CTRL2_10G_CX4:
  193. ecmd->speed = SPEED_10000;
  194. ecmd->port = PORT_FIBRE;
  195. ecmd->supported = SUPPORTED_FIBRE;
  196. ecmd->advertising = ADVERTISED_FIBRE;
  197. break;
  198. /* 10G Base-T */
  199. case MDIO_PMAPMD_CTRL2_10G_BT:
  200. ecmd->speed = SPEED_10000;
  201. ecmd->port = PORT_TP;
  202. ecmd->supported = SUPPORTED_TP | SUPPORTED_10000baseT_Full;
  203. ecmd->advertising = (ADVERTISED_FIBRE
  204. | ADVERTISED_10000baseT_Full);
  205. break;
  206. case MDIO_PMAPMD_CTRL2_1G_BT:
  207. ecmd->speed = SPEED_1000;
  208. ecmd->port = PORT_TP;
  209. ecmd->supported = SUPPORTED_TP | SUPPORTED_1000baseT_Full;
  210. ecmd->advertising = (ADVERTISED_FIBRE
  211. | ADVERTISED_1000baseT_Full);
  212. break;
  213. case MDIO_PMAPMD_CTRL2_100_BT:
  214. ecmd->speed = SPEED_100;
  215. ecmd->port = PORT_TP;
  216. ecmd->supported = SUPPORTED_TP | SUPPORTED_100baseT_Full;
  217. ecmd->advertising = (ADVERTISED_FIBRE
  218. | ADVERTISED_100baseT_Full);
  219. break;
  220. case MDIO_PMAPMD_CTRL2_10_BT:
  221. ecmd->speed = SPEED_10;
  222. ecmd->port = PORT_TP;
  223. ecmd->supported = SUPPORTED_TP | SUPPORTED_10baseT_Full;
  224. ecmd->advertising = ADVERTISED_FIBRE | ADVERTISED_10baseT_Full;
  225. break;
  226. /* All the other defined modes are flavours of
  227. * 10G optical */
  228. default:
  229. ecmd->speed = SPEED_10000;
  230. ecmd->port = PORT_FIBRE;
  231. ecmd->supported = SUPPORTED_FIBRE;
  232. ecmd->advertising = ADVERTISED_FIBRE;
  233. break;
  234. }
  235. }
  236. /**
  237. * mdio_clause45_set_settings - Set (some of) the PHY settings over MDIO.
  238. * @efx: Efx NIC
  239. * @ecmd: New settings
  240. *
  241. * Currently this just enforces that we are _not_ changing the
  242. * 'port', 'speed', 'supported' or 'advertising' settings as these
  243. * cannot be changed on any currently supported PHY.
  244. */
  245. int mdio_clause45_set_settings(struct efx_nic *efx,
  246. struct ethtool_cmd *ecmd)
  247. {
  248. struct ethtool_cmd tmpcmd;
  249. mdio_clause45_get_settings(efx, &tmpcmd);
  250. /* None of the current PHYs support more than one mode
  251. * of operation (and only 10GBT ever will), so keep things
  252. * simple for now */
  253. if ((ecmd->speed == tmpcmd.speed) && (ecmd->port == tmpcmd.port) &&
  254. (ecmd->supported == tmpcmd.supported) &&
  255. (ecmd->advertising == tmpcmd.advertising))
  256. return 0;
  257. return -EOPNOTSUPP;
  258. }