phy.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. /*
  2. * drivers/net/ibm_newemac/phy.c
  3. *
  4. * Driver for PowerPC 4xx on-chip ethernet controller, PHY support.
  5. * Borrowed from sungem_phy.c, though I only kept the generic MII
  6. * driver for now.
  7. *
  8. * This file should be shared with other drivers or eventually
  9. * merged as the "low level" part of miilib
  10. *
  11. * (c) 2003, Benjamin Herrenscmidt (benh@kernel.crashing.org)
  12. * (c) 2004-2005, Eugene Surovegin <ebs@ebshome.net>
  13. *
  14. */
  15. #include <linux/module.h>
  16. #include <linux/kernel.h>
  17. #include <linux/types.h>
  18. #include <linux/netdevice.h>
  19. #include <linux/mii.h>
  20. #include <linux/ethtool.h>
  21. #include <linux/delay.h>
  22. #include "emac.h"
  23. #include "phy.h"
  24. static inline int phy_read(struct mii_phy *phy, int reg)
  25. {
  26. return phy->mdio_read(phy->dev, phy->address, reg);
  27. }
  28. static inline void phy_write(struct mii_phy *phy, int reg, int val)
  29. {
  30. phy->mdio_write(phy->dev, phy->address, reg, val);
  31. }
  32. int emac_mii_reset_phy(struct mii_phy *phy)
  33. {
  34. int val;
  35. int limit = 10000;
  36. val = phy_read(phy, MII_BMCR);
  37. val &= ~(BMCR_ISOLATE | BMCR_ANENABLE);
  38. val |= BMCR_RESET;
  39. phy_write(phy, MII_BMCR, val);
  40. udelay(300);
  41. while (limit--) {
  42. val = phy_read(phy, MII_BMCR);
  43. if (val >= 0 && (val & BMCR_RESET) == 0)
  44. break;
  45. udelay(10);
  46. }
  47. if ((val & BMCR_ISOLATE) && limit > 0)
  48. phy_write(phy, MII_BMCR, val & ~BMCR_ISOLATE);
  49. return limit <= 0;
  50. }
  51. static int genmii_setup_aneg(struct mii_phy *phy, u32 advertise)
  52. {
  53. int ctl, adv;
  54. phy->autoneg = AUTONEG_ENABLE;
  55. phy->speed = SPEED_10;
  56. phy->duplex = DUPLEX_HALF;
  57. phy->pause = phy->asym_pause = 0;
  58. phy->advertising = advertise;
  59. ctl = phy_read(phy, MII_BMCR);
  60. if (ctl < 0)
  61. return ctl;
  62. ctl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_SPEED1000 | BMCR_ANENABLE);
  63. /* First clear the PHY */
  64. phy_write(phy, MII_BMCR, ctl);
  65. /* Setup standard advertise */
  66. adv = phy_read(phy, MII_ADVERTISE);
  67. if (adv < 0)
  68. return adv;
  69. adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP |
  70. ADVERTISE_PAUSE_ASYM);
  71. if (advertise & ADVERTISED_10baseT_Half)
  72. adv |= ADVERTISE_10HALF;
  73. if (advertise & ADVERTISED_10baseT_Full)
  74. adv |= ADVERTISE_10FULL;
  75. if (advertise & ADVERTISED_100baseT_Half)
  76. adv |= ADVERTISE_100HALF;
  77. if (advertise & ADVERTISED_100baseT_Full)
  78. adv |= ADVERTISE_100FULL;
  79. if (advertise & ADVERTISED_Pause)
  80. adv |= ADVERTISE_PAUSE_CAP;
  81. if (advertise & ADVERTISED_Asym_Pause)
  82. adv |= ADVERTISE_PAUSE_ASYM;
  83. phy_write(phy, MII_ADVERTISE, adv);
  84. if (phy->features &
  85. (SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half)) {
  86. adv = phy_read(phy, MII_CTRL1000);
  87. if (adv < 0)
  88. return adv;
  89. adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
  90. if (advertise & ADVERTISED_1000baseT_Full)
  91. adv |= ADVERTISE_1000FULL;
  92. if (advertise & ADVERTISED_1000baseT_Half)
  93. adv |= ADVERTISE_1000HALF;
  94. phy_write(phy, MII_CTRL1000, adv);
  95. }
  96. /* Start/Restart aneg */
  97. ctl = phy_read(phy, MII_BMCR);
  98. ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
  99. phy_write(phy, MII_BMCR, ctl);
  100. return 0;
  101. }
  102. static int genmii_setup_forced(struct mii_phy *phy, int speed, int fd)
  103. {
  104. int ctl;
  105. phy->autoneg = AUTONEG_DISABLE;
  106. phy->speed = speed;
  107. phy->duplex = fd;
  108. phy->pause = phy->asym_pause = 0;
  109. ctl = phy_read(phy, MII_BMCR);
  110. if (ctl < 0)
  111. return ctl;
  112. ctl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_SPEED1000 | BMCR_ANENABLE);
  113. /* First clear the PHY */
  114. phy_write(phy, MII_BMCR, ctl | BMCR_RESET);
  115. /* Select speed & duplex */
  116. switch (speed) {
  117. case SPEED_10:
  118. break;
  119. case SPEED_100:
  120. ctl |= BMCR_SPEED100;
  121. break;
  122. case SPEED_1000:
  123. ctl |= BMCR_SPEED1000;
  124. break;
  125. default:
  126. return -EINVAL;
  127. }
  128. if (fd == DUPLEX_FULL)
  129. ctl |= BMCR_FULLDPLX;
  130. phy_write(phy, MII_BMCR, ctl);
  131. return 0;
  132. }
  133. static int genmii_poll_link(struct mii_phy *phy)
  134. {
  135. int status;
  136. /* Clear latched value with dummy read */
  137. phy_read(phy, MII_BMSR);
  138. status = phy_read(phy, MII_BMSR);
  139. if (status < 0 || (status & BMSR_LSTATUS) == 0)
  140. return 0;
  141. if (phy->autoneg == AUTONEG_ENABLE && !(status & BMSR_ANEGCOMPLETE))
  142. return 0;
  143. return 1;
  144. }
  145. static int genmii_read_link(struct mii_phy *phy)
  146. {
  147. if (phy->autoneg == AUTONEG_ENABLE) {
  148. int glpa = 0;
  149. int lpa = phy_read(phy, MII_LPA) & phy_read(phy, MII_ADVERTISE);
  150. if (lpa < 0)
  151. return lpa;
  152. if (phy->features &
  153. (SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half)) {
  154. int adv = phy_read(phy, MII_CTRL1000);
  155. glpa = phy_read(phy, MII_STAT1000);
  156. if (glpa < 0 || adv < 0)
  157. return adv;
  158. glpa &= adv << 2;
  159. }
  160. phy->speed = SPEED_10;
  161. phy->duplex = DUPLEX_HALF;
  162. phy->pause = phy->asym_pause = 0;
  163. if (glpa & (LPA_1000FULL | LPA_1000HALF)) {
  164. phy->speed = SPEED_1000;
  165. if (glpa & LPA_1000FULL)
  166. phy->duplex = DUPLEX_FULL;
  167. } else if (lpa & (LPA_100FULL | LPA_100HALF)) {
  168. phy->speed = SPEED_100;
  169. if (lpa & LPA_100FULL)
  170. phy->duplex = DUPLEX_FULL;
  171. } else if (lpa & LPA_10FULL)
  172. phy->duplex = DUPLEX_FULL;
  173. if (phy->duplex == DUPLEX_FULL) {
  174. phy->pause = lpa & LPA_PAUSE_CAP ? 1 : 0;
  175. phy->asym_pause = lpa & LPA_PAUSE_ASYM ? 1 : 0;
  176. }
  177. } else {
  178. int bmcr = phy_read(phy, MII_BMCR);
  179. if (bmcr < 0)
  180. return bmcr;
  181. if (bmcr & BMCR_FULLDPLX)
  182. phy->duplex = DUPLEX_FULL;
  183. else
  184. phy->duplex = DUPLEX_HALF;
  185. if (bmcr & BMCR_SPEED1000)
  186. phy->speed = SPEED_1000;
  187. else if (bmcr & BMCR_SPEED100)
  188. phy->speed = SPEED_100;
  189. else
  190. phy->speed = SPEED_10;
  191. phy->pause = phy->asym_pause = 0;
  192. }
  193. return 0;
  194. }
  195. /* Generic implementation for most 10/100/1000 PHYs */
  196. static struct mii_phy_ops generic_phy_ops = {
  197. .setup_aneg = genmii_setup_aneg,
  198. .setup_forced = genmii_setup_forced,
  199. .poll_link = genmii_poll_link,
  200. .read_link = genmii_read_link
  201. };
  202. static struct mii_phy_def genmii_phy_def = {
  203. .phy_id = 0x00000000,
  204. .phy_id_mask = 0x00000000,
  205. .name = "Generic MII",
  206. .ops = &generic_phy_ops
  207. };
  208. /* CIS8201 */
  209. #define MII_CIS8201_10BTCSR 0x16
  210. #define TENBTCSR_ECHO_DISABLE 0x2000
  211. #define MII_CIS8201_EPCR 0x17
  212. #define EPCR_MODE_MASK 0x3000
  213. #define EPCR_GMII_MODE 0x0000
  214. #define EPCR_RGMII_MODE 0x1000
  215. #define EPCR_TBI_MODE 0x2000
  216. #define EPCR_RTBI_MODE 0x3000
  217. #define MII_CIS8201_ACSR 0x1c
  218. #define ACSR_PIN_PRIO_SELECT 0x0004
  219. static int cis8201_init(struct mii_phy *phy)
  220. {
  221. int epcr;
  222. epcr = phy_read(phy, MII_CIS8201_EPCR);
  223. if (epcr < 0)
  224. return epcr;
  225. epcr &= ~EPCR_MODE_MASK;
  226. switch (phy->mode) {
  227. case PHY_MODE_TBI:
  228. epcr |= EPCR_TBI_MODE;
  229. break;
  230. case PHY_MODE_RTBI:
  231. epcr |= EPCR_RTBI_MODE;
  232. break;
  233. case PHY_MODE_GMII:
  234. epcr |= EPCR_GMII_MODE;
  235. break;
  236. case PHY_MODE_RGMII:
  237. default:
  238. epcr |= EPCR_RGMII_MODE;
  239. }
  240. phy_write(phy, MII_CIS8201_EPCR, epcr);
  241. /* MII regs override strap pins */
  242. phy_write(phy, MII_CIS8201_ACSR,
  243. phy_read(phy, MII_CIS8201_ACSR) | ACSR_PIN_PRIO_SELECT);
  244. /* Disable TX_EN -> CRS echo mode, otherwise 10/HDX doesn't work */
  245. phy_write(phy, MII_CIS8201_10BTCSR,
  246. phy_read(phy, MII_CIS8201_10BTCSR) | TENBTCSR_ECHO_DISABLE);
  247. return 0;
  248. }
  249. static struct mii_phy_ops cis8201_phy_ops = {
  250. .init = cis8201_init,
  251. .setup_aneg = genmii_setup_aneg,
  252. .setup_forced = genmii_setup_forced,
  253. .poll_link = genmii_poll_link,
  254. .read_link = genmii_read_link
  255. };
  256. static struct mii_phy_def cis8201_phy_def = {
  257. .phy_id = 0x000fc410,
  258. .phy_id_mask = 0x000ffff0,
  259. .name = "CIS8201 Gigabit Ethernet",
  260. .ops = &cis8201_phy_ops
  261. };
  262. static struct mii_phy_def *mii_phy_table[] = {
  263. &cis8201_phy_def,
  264. &genmii_phy_def,
  265. NULL
  266. };
  267. int emac_mii_phy_probe(struct mii_phy *phy, int address)
  268. {
  269. struct mii_phy_def *def;
  270. int i;
  271. u32 id;
  272. phy->autoneg = AUTONEG_DISABLE;
  273. phy->advertising = 0;
  274. phy->address = address;
  275. phy->speed = SPEED_10;
  276. phy->duplex = DUPLEX_HALF;
  277. phy->pause = phy->asym_pause = 0;
  278. /* Take PHY out of isolate mode and reset it. */
  279. if (emac_mii_reset_phy(phy))
  280. return -ENODEV;
  281. /* Read ID and find matching entry */
  282. id = (phy_read(phy, MII_PHYSID1) << 16) | phy_read(phy, MII_PHYSID2);
  283. for (i = 0; (def = mii_phy_table[i]) != NULL; i++)
  284. if ((id & def->phy_id_mask) == def->phy_id)
  285. break;
  286. /* Should never be NULL (we have a generic entry), but... */
  287. if (!def)
  288. return -ENODEV;
  289. phy->def = def;
  290. /* Determine PHY features if needed */
  291. phy->features = def->features;
  292. if (!phy->features) {
  293. u16 bmsr = phy_read(phy, MII_BMSR);
  294. if (bmsr & BMSR_ANEGCAPABLE)
  295. phy->features |= SUPPORTED_Autoneg;
  296. if (bmsr & BMSR_10HALF)
  297. phy->features |= SUPPORTED_10baseT_Half;
  298. if (bmsr & BMSR_10FULL)
  299. phy->features |= SUPPORTED_10baseT_Full;
  300. if (bmsr & BMSR_100HALF)
  301. phy->features |= SUPPORTED_100baseT_Half;
  302. if (bmsr & BMSR_100FULL)
  303. phy->features |= SUPPORTED_100baseT_Full;
  304. if (bmsr & BMSR_ESTATEN) {
  305. u16 esr = phy_read(phy, MII_ESTATUS);
  306. if (esr & ESTATUS_1000_TFULL)
  307. phy->features |= SUPPORTED_1000baseT_Full;
  308. if (esr & ESTATUS_1000_THALF)
  309. phy->features |= SUPPORTED_1000baseT_Half;
  310. }
  311. phy->features |= SUPPORTED_MII;
  312. }
  313. /* Setup default advertising */
  314. phy->advertising = phy->features;
  315. return 0;
  316. }
  317. MODULE_LICENSE("GPL");