ibm_emac_phy.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  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_core.h"
  24. #include "ibm_emac_phy.h"
  25. static inline int phy_read(struct mii_phy *phy, int reg)
  26. {
  27. return phy->mdio_read(phy->dev, phy->address, reg);
  28. }
  29. static inline void phy_write(struct mii_phy *phy, int reg, int val)
  30. {
  31. phy->mdio_write(phy->dev, phy->address, reg, val);
  32. }
  33. /*
  34. * polls MII_BMCR until BMCR_RESET bit clears or operation times out.
  35. *
  36. * returns:
  37. * >= 0 => success, value in BMCR returned to caller
  38. * -EBUSY => failure, RESET bit never cleared
  39. * otherwise => failure, lower level PHY read failed
  40. */
  41. static int mii_spin_reset_complete(struct mii_phy *phy)
  42. {
  43. int val;
  44. int limit = 10000;
  45. while (limit--) {
  46. val = phy_read(phy, MII_BMCR);
  47. if (val >= 0 && !(val & BMCR_RESET))
  48. return val; /* success */
  49. udelay(10);
  50. }
  51. if (val & BMCR_RESET)
  52. val = -EBUSY;
  53. if (net_ratelimit())
  54. printk(KERN_ERR "emac%d: PHY reset timeout (%d)\n",
  55. ((struct ocp_enet_private *)phy->dev->priv)->def->index,
  56. val);
  57. return val;
  58. }
  59. int mii_reset_phy(struct mii_phy *phy)
  60. {
  61. int val;
  62. val = phy_read(phy, MII_BMCR);
  63. val &= ~BMCR_ISOLATE;
  64. val |= BMCR_RESET;
  65. phy_write(phy, MII_BMCR, val);
  66. udelay(300);
  67. val = mii_spin_reset_complete(phy);
  68. if (val >= 0 && (val & BMCR_ISOLATE))
  69. phy_write(phy, MII_BMCR, val & ~BMCR_ISOLATE);
  70. return val < 0;
  71. }
  72. static int genmii_setup_aneg(struct mii_phy *phy, u32 advertise)
  73. {
  74. int ctl, adv;
  75. phy->autoneg = AUTONEG_ENABLE;
  76. phy->speed = SPEED_10;
  77. phy->duplex = DUPLEX_HALF;
  78. phy->pause = phy->asym_pause = 0;
  79. phy->advertising = advertise;
  80. /* Setup standard advertise */
  81. adv = phy_read(phy, MII_ADVERTISE);
  82. if (adv < 0)
  83. return adv;
  84. adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP |
  85. ADVERTISE_PAUSE_ASYM);
  86. if (advertise & ADVERTISED_10baseT_Half)
  87. adv |= ADVERTISE_10HALF;
  88. if (advertise & ADVERTISED_10baseT_Full)
  89. adv |= ADVERTISE_10FULL;
  90. if (advertise & ADVERTISED_100baseT_Half)
  91. adv |= ADVERTISE_100HALF;
  92. if (advertise & ADVERTISED_100baseT_Full)
  93. adv |= ADVERTISE_100FULL;
  94. if (advertise & ADVERTISED_Pause)
  95. adv |= ADVERTISE_PAUSE_CAP;
  96. if (advertise & ADVERTISED_Asym_Pause)
  97. adv |= ADVERTISE_PAUSE_ASYM;
  98. phy_write(phy, MII_ADVERTISE, adv);
  99. if (phy->features &
  100. (SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half)) {
  101. adv = phy_read(phy, MII_CTRL1000);
  102. if (adv < 0)
  103. return adv;
  104. adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
  105. if (advertise & ADVERTISED_1000baseT_Full)
  106. adv |= ADVERTISE_1000FULL;
  107. if (advertise & ADVERTISED_1000baseT_Half)
  108. adv |= ADVERTISE_1000HALF;
  109. phy_write(phy, MII_CTRL1000, adv);
  110. }
  111. /* Start/Restart aneg */
  112. /* on some PHYs (e.g. National DP83843) a write to MII_ADVERTISE
  113. * causes BMCR_RESET to be set on the next read of MII_BMCR, which
  114. * if not checked for causes the PHY to be reset below */
  115. ctl = mii_spin_reset_complete(phy);
  116. if (ctl < 0)
  117. return ctl;
  118. ctl |= BMCR_ANENABLE | BMCR_ANRESTART;
  119. phy_write(phy, MII_BMCR, ctl);
  120. return 0;
  121. }
  122. static int genmii_setup_forced(struct mii_phy *phy, int speed, int fd)
  123. {
  124. int ctl;
  125. phy->autoneg = AUTONEG_DISABLE;
  126. phy->speed = speed;
  127. phy->duplex = fd;
  128. phy->pause = phy->asym_pause = 0;
  129. /* First reset the PHY */
  130. mii_reset_phy(phy);
  131. ctl = phy_read(phy, MII_BMCR);
  132. if (ctl < 0)
  133. return ctl;
  134. ctl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_ANENABLE | BMCR_SPEED1000);
  135. /* Select speed & duplex */
  136. switch (speed) {
  137. case SPEED_10:
  138. break;
  139. case SPEED_100:
  140. ctl |= BMCR_SPEED100;
  141. break;
  142. case SPEED_1000:
  143. ctl |= BMCR_SPEED1000;
  144. break;
  145. default:
  146. return -EINVAL;
  147. }
  148. if (fd == DUPLEX_FULL)
  149. ctl |= BMCR_FULLDPLX;
  150. phy_write(phy, MII_BMCR, ctl);
  151. return 0;
  152. }
  153. static int genmii_poll_link(struct mii_phy *phy)
  154. {
  155. int status;
  156. /* Clear latched value with dummy read */
  157. phy_read(phy, MII_BMSR);
  158. status = phy_read(phy, MII_BMSR);
  159. if (status < 0 || (status & BMSR_LSTATUS) == 0)
  160. return 0;
  161. if (phy->autoneg == AUTONEG_ENABLE && !(status & BMSR_ANEGCOMPLETE))
  162. return 0;
  163. return 1;
  164. }
  165. static int genmii_read_link(struct mii_phy *phy)
  166. {
  167. if (phy->autoneg == AUTONEG_ENABLE) {
  168. int glpa = 0;
  169. int lpa = phy_read(phy, MII_LPA) & phy_read(phy, MII_ADVERTISE);
  170. if (lpa < 0)
  171. return lpa;
  172. if (phy->features &
  173. (SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half)) {
  174. int adv = phy_read(phy, MII_CTRL1000);
  175. glpa = phy_read(phy, MII_STAT1000);
  176. if (glpa < 0 || adv < 0)
  177. return adv;
  178. glpa &= adv << 2;
  179. }
  180. phy->speed = SPEED_10;
  181. phy->duplex = DUPLEX_HALF;
  182. phy->pause = phy->asym_pause = 0;
  183. if (glpa & (LPA_1000FULL | LPA_1000HALF)) {
  184. phy->speed = SPEED_1000;
  185. if (glpa & LPA_1000FULL)
  186. phy->duplex = DUPLEX_FULL;
  187. } else if (lpa & (LPA_100FULL | LPA_100HALF)) {
  188. phy->speed = SPEED_100;
  189. if (lpa & LPA_100FULL)
  190. phy->duplex = DUPLEX_FULL;
  191. } else if (lpa & LPA_10FULL)
  192. phy->duplex = DUPLEX_FULL;
  193. if (phy->duplex == DUPLEX_FULL) {
  194. phy->pause = lpa & LPA_PAUSE_CAP ? 1 : 0;
  195. phy->asym_pause = lpa & LPA_PAUSE_ASYM ? 1 : 0;
  196. }
  197. } else {
  198. int bmcr = phy_read(phy, MII_BMCR);
  199. if (bmcr < 0)
  200. return bmcr;
  201. if (bmcr & BMCR_FULLDPLX)
  202. phy->duplex = DUPLEX_FULL;
  203. else
  204. phy->duplex = DUPLEX_HALF;
  205. if (bmcr & BMCR_SPEED1000)
  206. phy->speed = SPEED_1000;
  207. else if (bmcr & BMCR_SPEED100)
  208. phy->speed = SPEED_100;
  209. else
  210. phy->speed = SPEED_10;
  211. phy->pause = phy->asym_pause = 0;
  212. }
  213. return 0;
  214. }
  215. /* Generic implementation for most 10/100/1000 PHYs */
  216. static struct mii_phy_ops generic_phy_ops = {
  217. .setup_aneg = genmii_setup_aneg,
  218. .setup_forced = genmii_setup_forced,
  219. .poll_link = genmii_poll_link,
  220. .read_link = genmii_read_link
  221. };
  222. static struct mii_phy_def genmii_phy_def = {
  223. .phy_id = 0x00000000,
  224. .phy_id_mask = 0x00000000,
  225. .name = "Generic MII",
  226. .ops = &generic_phy_ops
  227. };
  228. /* CIS8201 */
  229. #define MII_CIS8201_10BTCSR 0x16
  230. #define TENBTCSR_ECHO_DISABLE 0x2000
  231. #define MII_CIS8201_EPCR 0x17
  232. #define EPCR_MODE_MASK 0x3000
  233. #define EPCR_GMII_MODE 0x0000
  234. #define EPCR_RGMII_MODE 0x1000
  235. #define EPCR_TBI_MODE 0x2000
  236. #define EPCR_RTBI_MODE 0x3000
  237. #define MII_CIS8201_ACSR 0x1c
  238. #define ACSR_PIN_PRIO_SELECT 0x0004
  239. static int cis8201_init(struct mii_phy *phy)
  240. {
  241. int epcr;
  242. epcr = phy_read(phy, MII_CIS8201_EPCR);
  243. if (epcr < 0)
  244. return epcr;
  245. epcr &= ~EPCR_MODE_MASK;
  246. switch (phy->mode) {
  247. case PHY_MODE_TBI:
  248. epcr |= EPCR_TBI_MODE;
  249. break;
  250. case PHY_MODE_RTBI:
  251. epcr |= EPCR_RTBI_MODE;
  252. break;
  253. case PHY_MODE_GMII:
  254. epcr |= EPCR_GMII_MODE;
  255. break;
  256. case PHY_MODE_RGMII:
  257. default:
  258. epcr |= EPCR_RGMII_MODE;
  259. }
  260. phy_write(phy, MII_CIS8201_EPCR, epcr);
  261. /* MII regs override strap pins */
  262. phy_write(phy, MII_CIS8201_ACSR,
  263. phy_read(phy, MII_CIS8201_ACSR) | ACSR_PIN_PRIO_SELECT);
  264. /* Disable TX_EN -> CRS echo mode, otherwise 10/HDX doesn't work */
  265. phy_write(phy, MII_CIS8201_10BTCSR,
  266. phy_read(phy, MII_CIS8201_10BTCSR) | TENBTCSR_ECHO_DISABLE);
  267. return 0;
  268. }
  269. static struct mii_phy_ops cis8201_phy_ops = {
  270. .init = cis8201_init,
  271. .setup_aneg = genmii_setup_aneg,
  272. .setup_forced = genmii_setup_forced,
  273. .poll_link = genmii_poll_link,
  274. .read_link = genmii_read_link
  275. };
  276. static struct mii_phy_def cis8201_phy_def = {
  277. .phy_id = 0x000fc410,
  278. .phy_id_mask = 0x000ffff0,
  279. .name = "CIS8201 Gigabit Ethernet",
  280. .ops = &cis8201_phy_ops
  281. };
  282. static struct mii_phy_def *mii_phy_table[] = {
  283. &cis8201_phy_def,
  284. &genmii_phy_def,
  285. NULL
  286. };
  287. int mii_phy_probe(struct mii_phy *phy, int address)
  288. {
  289. struct mii_phy_def *def;
  290. int i;
  291. int id;
  292. phy->autoneg = AUTONEG_DISABLE;
  293. phy->advertising = 0;
  294. phy->address = address;
  295. phy->speed = SPEED_10;
  296. phy->duplex = DUPLEX_HALF;
  297. phy->pause = phy->asym_pause = 0;
  298. /* Take PHY out of isolate mode and reset it. */
  299. if (mii_reset_phy(phy))
  300. return -ENODEV;
  301. /* Read ID and find matching entry */
  302. id = (phy_read(phy, MII_PHYSID1) << 16) | phy_read(phy, MII_PHYSID2);
  303. if (id < 0)
  304. return -ENODEV;
  305. for (i = 0; (def = mii_phy_table[i]) != NULL; i++)
  306. if ((id & def->phy_id_mask) == def->phy_id)
  307. break;
  308. /* Should never be NULL (we have a generic entry), but... */
  309. if (!def)
  310. return -ENODEV;
  311. phy->def = def;
  312. /* Determine PHY features if needed */
  313. phy->features = def->features;
  314. if (!phy->features) {
  315. u16 bmsr = phy_read(phy, MII_BMSR);
  316. if (bmsr & BMSR_ANEGCAPABLE)
  317. phy->features |= SUPPORTED_Autoneg;
  318. if (bmsr & BMSR_10HALF)
  319. phy->features |= SUPPORTED_10baseT_Half;
  320. if (bmsr & BMSR_10FULL)
  321. phy->features |= SUPPORTED_10baseT_Full;
  322. if (bmsr & BMSR_100HALF)
  323. phy->features |= SUPPORTED_100baseT_Half;
  324. if (bmsr & BMSR_100FULL)
  325. phy->features |= SUPPORTED_100baseT_Full;
  326. if (bmsr & BMSR_ESTATEN) {
  327. u16 esr = phy_read(phy, MII_ESTATUS);
  328. if (esr & ESTATUS_1000_TFULL)
  329. phy->features |= SUPPORTED_1000baseT_Full;
  330. if (esr & ESTATUS_1000_THALF)
  331. phy->features |= SUPPORTED_1000baseT_Half;
  332. }
  333. phy->features |= SUPPORTED_MII;
  334. }
  335. /* Setup default advertising */
  336. phy->advertising = phy->features;
  337. return 0;
  338. }
  339. MODULE_LICENSE("GPL");