ibm_emac_phy.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. /*
  2. * drivers/net/ibm_emac/ibm_emac_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 <asm/ocp.h>
  23. #include "ibm_emac_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 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;
  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. /* Setup standard advertise */
  60. adv = phy_read(phy, MII_ADVERTISE);
  61. if (adv < 0)
  62. return adv;
  63. adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP |
  64. ADVERTISE_PAUSE_ASYM);
  65. if (advertise & ADVERTISED_10baseT_Half)
  66. adv |= ADVERTISE_10HALF;
  67. if (advertise & ADVERTISED_10baseT_Full)
  68. adv |= ADVERTISE_10FULL;
  69. if (advertise & ADVERTISED_100baseT_Half)
  70. adv |= ADVERTISE_100HALF;
  71. if (advertise & ADVERTISED_100baseT_Full)
  72. adv |= ADVERTISE_100FULL;
  73. if (advertise & ADVERTISED_Pause)
  74. adv |= ADVERTISE_PAUSE_CAP;
  75. if (advertise & ADVERTISED_Asym_Pause)
  76. adv |= ADVERTISE_PAUSE_ASYM;
  77. phy_write(phy, MII_ADVERTISE, adv);
  78. if (phy->features &
  79. (SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half)) {
  80. adv = phy_read(phy, MII_CTRL1000);
  81. if (adv < 0)
  82. return adv;
  83. adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
  84. if (advertise & ADVERTISED_1000baseT_Full)
  85. adv |= ADVERTISE_1000FULL;
  86. if (advertise & ADVERTISED_1000baseT_Half)
  87. adv |= ADVERTISE_1000HALF;
  88. phy_write(phy, MII_CTRL1000, adv);
  89. }
  90. /* Start/Restart aneg */
  91. ctl = phy_read(phy, MII_BMCR);
  92. ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
  93. phy_write(phy, MII_BMCR, ctl);
  94. return 0;
  95. }
  96. static int genmii_setup_forced(struct mii_phy *phy, int speed, int fd)
  97. {
  98. int ctl;
  99. phy->autoneg = AUTONEG_DISABLE;
  100. phy->speed = speed;
  101. phy->duplex = fd;
  102. phy->pause = phy->asym_pause = 0;
  103. ctl = phy_read(phy, MII_BMCR);
  104. if (ctl < 0)
  105. return ctl;
  106. ctl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_ANENABLE);
  107. /* First reset the PHY */
  108. phy_write(phy, MII_BMCR, ctl | BMCR_RESET);
  109. /* Select speed & duplex */
  110. switch (speed) {
  111. case SPEED_10:
  112. break;
  113. case SPEED_100:
  114. ctl |= BMCR_SPEED100;
  115. break;
  116. case SPEED_1000:
  117. ctl |= BMCR_SPEED1000;
  118. break;
  119. default:
  120. return -EINVAL;
  121. }
  122. if (fd == DUPLEX_FULL)
  123. ctl |= BMCR_FULLDPLX;
  124. phy_write(phy, MII_BMCR, ctl);
  125. return 0;
  126. }
  127. static int genmii_poll_link(struct mii_phy *phy)
  128. {
  129. int status;
  130. /* Clear latched value with dummy read */
  131. phy_read(phy, MII_BMSR);
  132. status = phy_read(phy, MII_BMSR);
  133. if (status < 0 || (status & BMSR_LSTATUS) == 0)
  134. return 0;
  135. if (phy->autoneg == AUTONEG_ENABLE && !(status & BMSR_ANEGCOMPLETE))
  136. return 0;
  137. return 1;
  138. }
  139. static int genmii_read_link(struct mii_phy *phy)
  140. {
  141. if (phy->autoneg == AUTONEG_ENABLE) {
  142. int glpa = 0;
  143. int lpa = phy_read(phy, MII_LPA) & phy_read(phy, MII_ADVERTISE);
  144. if (lpa < 0)
  145. return lpa;
  146. if (phy->features &
  147. (SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half)) {
  148. int adv = phy_read(phy, MII_CTRL1000);
  149. glpa = phy_read(phy, MII_STAT1000);
  150. if (glpa < 0 || adv < 0)
  151. return adv;
  152. glpa &= adv << 2;
  153. }
  154. phy->speed = SPEED_10;
  155. phy->duplex = DUPLEX_HALF;
  156. phy->pause = phy->asym_pause = 0;
  157. if (glpa & (LPA_1000FULL | LPA_1000HALF)) {
  158. phy->speed = SPEED_1000;
  159. if (glpa & LPA_1000FULL)
  160. phy->duplex = DUPLEX_FULL;
  161. } else if (lpa & (LPA_100FULL | LPA_100HALF)) {
  162. phy->speed = SPEED_100;
  163. if (lpa & LPA_100FULL)
  164. phy->duplex = DUPLEX_FULL;
  165. } else if (lpa & LPA_10FULL)
  166. phy->duplex = DUPLEX_FULL;
  167. if (phy->duplex == DUPLEX_FULL) {
  168. phy->pause = lpa & LPA_PAUSE_CAP ? 1 : 0;
  169. phy->asym_pause = lpa & LPA_PAUSE_ASYM ? 1 : 0;
  170. }
  171. } else {
  172. int bmcr = phy_read(phy, MII_BMCR);
  173. if (bmcr < 0)
  174. return bmcr;
  175. if (bmcr & BMCR_FULLDPLX)
  176. phy->duplex = DUPLEX_FULL;
  177. else
  178. phy->duplex = DUPLEX_HALF;
  179. if (bmcr & BMCR_SPEED1000)
  180. phy->speed = SPEED_1000;
  181. else if (bmcr & BMCR_SPEED100)
  182. phy->speed = SPEED_100;
  183. else
  184. phy->speed = SPEED_10;
  185. phy->pause = phy->asym_pause = 0;
  186. }
  187. return 0;
  188. }
  189. /* Generic implementation for most 10/100/1000 PHYs */
  190. static struct mii_phy_ops generic_phy_ops = {
  191. .setup_aneg = genmii_setup_aneg,
  192. .setup_forced = genmii_setup_forced,
  193. .poll_link = genmii_poll_link,
  194. .read_link = genmii_read_link
  195. };
  196. static struct mii_phy_def genmii_phy_def = {
  197. .phy_id = 0x00000000,
  198. .phy_id_mask = 0x00000000,
  199. .name = "Generic MII",
  200. .ops = &generic_phy_ops
  201. };
  202. /* CIS8201 */
  203. #define MII_CIS8201_10BTCSR 0x16
  204. #define TENBTCSR_ECHO_DISABLE 0x2000
  205. #define MII_CIS8201_EPCR 0x17
  206. #define EPCR_MODE_MASK 0x3000
  207. #define EPCR_GMII_MODE 0x0000
  208. #define EPCR_RGMII_MODE 0x1000
  209. #define EPCR_TBI_MODE 0x2000
  210. #define EPCR_RTBI_MODE 0x3000
  211. #define MII_CIS8201_ACSR 0x1c
  212. #define ACSR_PIN_PRIO_SELECT 0x0004
  213. static int cis8201_init(struct mii_phy *phy)
  214. {
  215. int epcr;
  216. epcr = phy_read(phy, MII_CIS8201_EPCR);
  217. if (epcr < 0)
  218. return epcr;
  219. epcr &= ~EPCR_MODE_MASK;
  220. switch (phy->mode) {
  221. case PHY_MODE_TBI:
  222. epcr |= EPCR_TBI_MODE;
  223. break;
  224. case PHY_MODE_RTBI:
  225. epcr |= EPCR_RTBI_MODE;
  226. break;
  227. case PHY_MODE_GMII:
  228. epcr |= EPCR_GMII_MODE;
  229. break;
  230. case PHY_MODE_RGMII:
  231. default:
  232. epcr |= EPCR_RGMII_MODE;
  233. }
  234. phy_write(phy, MII_CIS8201_EPCR, epcr);
  235. /* MII regs override strap pins */
  236. phy_write(phy, MII_CIS8201_ACSR,
  237. phy_read(phy, MII_CIS8201_ACSR) | ACSR_PIN_PRIO_SELECT);
  238. /* Disable TX_EN -> CRS echo mode, otherwise 10/HDX doesn't work */
  239. phy_write(phy, MII_CIS8201_10BTCSR,
  240. phy_read(phy, MII_CIS8201_10BTCSR) | TENBTCSR_ECHO_DISABLE);
  241. return 0;
  242. }
  243. static struct mii_phy_ops cis8201_phy_ops = {
  244. .init = cis8201_init,
  245. .setup_aneg = genmii_setup_aneg,
  246. .setup_forced = genmii_setup_forced,
  247. .poll_link = genmii_poll_link,
  248. .read_link = genmii_read_link
  249. };
  250. static struct mii_phy_def cis8201_phy_def = {
  251. .phy_id = 0x000fc410,
  252. .phy_id_mask = 0x000ffff0,
  253. .name = "CIS8201 Gigabit Ethernet",
  254. .ops = &cis8201_phy_ops
  255. };
  256. static struct mii_phy_def *mii_phy_table[] = {
  257. &cis8201_phy_def,
  258. &genmii_phy_def,
  259. NULL
  260. };
  261. int mii_phy_probe(struct mii_phy *phy, int address)
  262. {
  263. struct mii_phy_def *def;
  264. int i;
  265. int id;
  266. phy->autoneg = AUTONEG_DISABLE;
  267. phy->advertising = 0;
  268. phy->address = address;
  269. phy->speed = SPEED_10;
  270. phy->duplex = DUPLEX_HALF;
  271. phy->pause = phy->asym_pause = 0;
  272. /* Take PHY out of isolate mode and reset it. */
  273. if (mii_reset_phy(phy))
  274. return -ENODEV;
  275. /* Read ID and find matching entry */
  276. id = (phy_read(phy, MII_PHYSID1) << 16) | phy_read(phy, MII_PHYSID2);
  277. if (id < 0)
  278. return -ENODEV;
  279. for (i = 0; (def = mii_phy_table[i]) != NULL; i++)
  280. if ((id & def->phy_id_mask) == def->phy_id)
  281. break;
  282. /* Should never be NULL (we have a generic entry), but... */
  283. if (!def)
  284. return -ENODEV;
  285. phy->def = def;
  286. /* Determine PHY features if needed */
  287. phy->features = def->features;
  288. if (!phy->features) {
  289. u16 bmsr = phy_read(phy, MII_BMSR);
  290. if (bmsr & BMSR_ANEGCAPABLE)
  291. phy->features |= SUPPORTED_Autoneg;
  292. if (bmsr & BMSR_10HALF)
  293. phy->features |= SUPPORTED_10baseT_Half;
  294. if (bmsr & BMSR_10FULL)
  295. phy->features |= SUPPORTED_10baseT_Full;
  296. if (bmsr & BMSR_100HALF)
  297. phy->features |= SUPPORTED_100baseT_Half;
  298. if (bmsr & BMSR_100FULL)
  299. phy->features |= SUPPORTED_100baseT_Full;
  300. if (bmsr & BMSR_ESTATEN) {
  301. u16 esr = phy_read(phy, MII_ESTATUS);
  302. if (esr & ESTATUS_1000_TFULL)
  303. phy->features |= SUPPORTED_1000baseT_Full;
  304. if (esr & ESTATUS_1000_THALF)
  305. phy->features |= SUPPORTED_1000baseT_Half;
  306. }
  307. phy->features |= SUPPORTED_MII;
  308. }
  309. /* Setup default advertising */
  310. phy->advertising = phy->features;
  311. return 0;
  312. }
  313. MODULE_LICENSE("GPL");