phy.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  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. * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
  12. * <benh@kernel.crashing.org>
  13. *
  14. * Based on the arch/ppc version of the driver:
  15. *
  16. * (c) 2003, Benjamin Herrenscmidt (benh@kernel.crashing.org)
  17. * (c) 2004-2005, Eugene Surovegin <ebs@ebshome.net>
  18. *
  19. */
  20. #include <linux/module.h>
  21. #include <linux/kernel.h>
  22. #include <linux/types.h>
  23. #include <linux/netdevice.h>
  24. #include <linux/mii.h>
  25. #include <linux/ethtool.h>
  26. #include <linux/delay.h>
  27. #include "emac.h"
  28. #include "phy.h"
  29. static inline int phy_read(struct mii_phy *phy, int reg)
  30. {
  31. return phy->mdio_read(phy->dev, phy->address, reg);
  32. }
  33. static inline void phy_write(struct mii_phy *phy, int reg, int val)
  34. {
  35. phy->mdio_write(phy->dev, phy->address, reg, val);
  36. }
  37. static inline int gpcs_phy_read(struct mii_phy *phy, int reg)
  38. {
  39. return phy->mdio_read(phy->dev, phy->gpcs_address, reg);
  40. }
  41. static inline void gpcs_phy_write(struct mii_phy *phy, int reg, int val)
  42. {
  43. phy->mdio_write(phy->dev, phy->gpcs_address, reg, val);
  44. }
  45. int emac_mii_reset_phy(struct mii_phy *phy)
  46. {
  47. int val;
  48. int limit = 10000;
  49. val = phy_read(phy, MII_BMCR);
  50. val &= ~(BMCR_ISOLATE | BMCR_ANENABLE);
  51. val |= BMCR_RESET;
  52. phy_write(phy, MII_BMCR, val);
  53. udelay(300);
  54. while (--limit) {
  55. val = phy_read(phy, MII_BMCR);
  56. if (val >= 0 && (val & BMCR_RESET) == 0)
  57. break;
  58. udelay(10);
  59. }
  60. if ((val & BMCR_ISOLATE) && limit > 0)
  61. phy_write(phy, MII_BMCR, val & ~BMCR_ISOLATE);
  62. return limit <= 0;
  63. }
  64. int emac_mii_reset_gpcs(struct mii_phy *phy)
  65. {
  66. int val;
  67. int limit = 10000;
  68. val = gpcs_phy_read(phy, MII_BMCR);
  69. val &= ~(BMCR_ISOLATE | BMCR_ANENABLE);
  70. val |= BMCR_RESET;
  71. gpcs_phy_write(phy, MII_BMCR, val);
  72. udelay(300);
  73. while (--limit) {
  74. val = gpcs_phy_read(phy, MII_BMCR);
  75. if (val >= 0 && (val & BMCR_RESET) == 0)
  76. break;
  77. udelay(10);
  78. }
  79. if ((val & BMCR_ISOLATE) && limit > 0)
  80. gpcs_phy_write(phy, MII_BMCR, val & ~BMCR_ISOLATE);
  81. if (limit > 0 && phy->mode == PHY_MODE_SGMII) {
  82. /* Configure GPCS interface to recommended setting for SGMII */
  83. gpcs_phy_write(phy, 0x04, 0x8120); /* AsymPause, FDX */
  84. gpcs_phy_write(phy, 0x07, 0x2801); /* msg_pg, toggle */
  85. gpcs_phy_write(phy, 0x00, 0x0140); /* 1Gbps, FDX */
  86. }
  87. return limit <= 0;
  88. }
  89. static int genmii_setup_aneg(struct mii_phy *phy, u32 advertise)
  90. {
  91. int ctl, adv;
  92. phy->autoneg = AUTONEG_ENABLE;
  93. phy->speed = SPEED_10;
  94. phy->duplex = DUPLEX_HALF;
  95. phy->pause = phy->asym_pause = 0;
  96. phy->advertising = advertise;
  97. ctl = phy_read(phy, MII_BMCR);
  98. if (ctl < 0)
  99. return ctl;
  100. ctl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_SPEED1000 | BMCR_ANENABLE);
  101. /* First clear the PHY */
  102. phy_write(phy, MII_BMCR, ctl);
  103. /* Setup standard advertise */
  104. adv = phy_read(phy, MII_ADVERTISE);
  105. if (adv < 0)
  106. return adv;
  107. adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP |
  108. ADVERTISE_PAUSE_ASYM);
  109. if (advertise & ADVERTISED_10baseT_Half)
  110. adv |= ADVERTISE_10HALF;
  111. if (advertise & ADVERTISED_10baseT_Full)
  112. adv |= ADVERTISE_10FULL;
  113. if (advertise & ADVERTISED_100baseT_Half)
  114. adv |= ADVERTISE_100HALF;
  115. if (advertise & ADVERTISED_100baseT_Full)
  116. adv |= ADVERTISE_100FULL;
  117. if (advertise & ADVERTISED_Pause)
  118. adv |= ADVERTISE_PAUSE_CAP;
  119. if (advertise & ADVERTISED_Asym_Pause)
  120. adv |= ADVERTISE_PAUSE_ASYM;
  121. phy_write(phy, MII_ADVERTISE, adv);
  122. if (phy->features &
  123. (SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half)) {
  124. adv = phy_read(phy, MII_CTRL1000);
  125. if (adv < 0)
  126. return adv;
  127. adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
  128. if (advertise & ADVERTISED_1000baseT_Full)
  129. adv |= ADVERTISE_1000FULL;
  130. if (advertise & ADVERTISED_1000baseT_Half)
  131. adv |= ADVERTISE_1000HALF;
  132. phy_write(phy, MII_CTRL1000, adv);
  133. }
  134. /* Start/Restart aneg */
  135. ctl = phy_read(phy, MII_BMCR);
  136. ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
  137. phy_write(phy, MII_BMCR, ctl);
  138. return 0;
  139. }
  140. static int genmii_setup_forced(struct mii_phy *phy, int speed, int fd)
  141. {
  142. int ctl;
  143. phy->autoneg = AUTONEG_DISABLE;
  144. phy->speed = speed;
  145. phy->duplex = fd;
  146. phy->pause = phy->asym_pause = 0;
  147. ctl = phy_read(phy, MII_BMCR);
  148. if (ctl < 0)
  149. return ctl;
  150. ctl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_SPEED1000 | BMCR_ANENABLE);
  151. /* First clear the PHY */
  152. phy_write(phy, MII_BMCR, ctl | BMCR_RESET);
  153. /* Select speed & duplex */
  154. switch (speed) {
  155. case SPEED_10:
  156. break;
  157. case SPEED_100:
  158. ctl |= BMCR_SPEED100;
  159. break;
  160. case SPEED_1000:
  161. ctl |= BMCR_SPEED1000;
  162. break;
  163. default:
  164. return -EINVAL;
  165. }
  166. if (fd == DUPLEX_FULL)
  167. ctl |= BMCR_FULLDPLX;
  168. phy_write(phy, MII_BMCR, ctl);
  169. return 0;
  170. }
  171. static int genmii_poll_link(struct mii_phy *phy)
  172. {
  173. int status;
  174. /* Clear latched value with dummy read */
  175. phy_read(phy, MII_BMSR);
  176. status = phy_read(phy, MII_BMSR);
  177. if (status < 0 || (status & BMSR_LSTATUS) == 0)
  178. return 0;
  179. if (phy->autoneg == AUTONEG_ENABLE && !(status & BMSR_ANEGCOMPLETE))
  180. return 0;
  181. return 1;
  182. }
  183. static int genmii_read_link(struct mii_phy *phy)
  184. {
  185. if (phy->autoneg == AUTONEG_ENABLE) {
  186. int glpa = 0;
  187. int lpa = phy_read(phy, MII_LPA) & phy_read(phy, MII_ADVERTISE);
  188. if (lpa < 0)
  189. return lpa;
  190. if (phy->features &
  191. (SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half)) {
  192. int adv = phy_read(phy, MII_CTRL1000);
  193. glpa = phy_read(phy, MII_STAT1000);
  194. if (glpa < 0 || adv < 0)
  195. return adv;
  196. glpa &= adv << 2;
  197. }
  198. phy->speed = SPEED_10;
  199. phy->duplex = DUPLEX_HALF;
  200. phy->pause = phy->asym_pause = 0;
  201. if (glpa & (LPA_1000FULL | LPA_1000HALF)) {
  202. phy->speed = SPEED_1000;
  203. if (glpa & LPA_1000FULL)
  204. phy->duplex = DUPLEX_FULL;
  205. } else if (lpa & (LPA_100FULL | LPA_100HALF)) {
  206. phy->speed = SPEED_100;
  207. if (lpa & LPA_100FULL)
  208. phy->duplex = DUPLEX_FULL;
  209. } else if (lpa & LPA_10FULL)
  210. phy->duplex = DUPLEX_FULL;
  211. if (phy->duplex == DUPLEX_FULL) {
  212. phy->pause = lpa & LPA_PAUSE_CAP ? 1 : 0;
  213. phy->asym_pause = lpa & LPA_PAUSE_ASYM ? 1 : 0;
  214. }
  215. } else {
  216. int bmcr = phy_read(phy, MII_BMCR);
  217. if (bmcr < 0)
  218. return bmcr;
  219. if (bmcr & BMCR_FULLDPLX)
  220. phy->duplex = DUPLEX_FULL;
  221. else
  222. phy->duplex = DUPLEX_HALF;
  223. if (bmcr & BMCR_SPEED1000)
  224. phy->speed = SPEED_1000;
  225. else if (bmcr & BMCR_SPEED100)
  226. phy->speed = SPEED_100;
  227. else
  228. phy->speed = SPEED_10;
  229. phy->pause = phy->asym_pause = 0;
  230. }
  231. return 0;
  232. }
  233. /* Generic implementation for most 10/100/1000 PHYs */
  234. static struct mii_phy_ops generic_phy_ops = {
  235. .setup_aneg = genmii_setup_aneg,
  236. .setup_forced = genmii_setup_forced,
  237. .poll_link = genmii_poll_link,
  238. .read_link = genmii_read_link
  239. };
  240. static struct mii_phy_def genmii_phy_def = {
  241. .phy_id = 0x00000000,
  242. .phy_id_mask = 0x00000000,
  243. .name = "Generic MII",
  244. .ops = &generic_phy_ops
  245. };
  246. /* CIS8201 */
  247. #define MII_CIS8201_10BTCSR 0x16
  248. #define TENBTCSR_ECHO_DISABLE 0x2000
  249. #define MII_CIS8201_EPCR 0x17
  250. #define EPCR_MODE_MASK 0x3000
  251. #define EPCR_GMII_MODE 0x0000
  252. #define EPCR_RGMII_MODE 0x1000
  253. #define EPCR_TBI_MODE 0x2000
  254. #define EPCR_RTBI_MODE 0x3000
  255. #define MII_CIS8201_ACSR 0x1c
  256. #define ACSR_PIN_PRIO_SELECT 0x0004
  257. static int cis8201_init(struct mii_phy *phy)
  258. {
  259. int epcr;
  260. epcr = phy_read(phy, MII_CIS8201_EPCR);
  261. if (epcr < 0)
  262. return epcr;
  263. epcr &= ~EPCR_MODE_MASK;
  264. switch (phy->mode) {
  265. case PHY_MODE_TBI:
  266. epcr |= EPCR_TBI_MODE;
  267. break;
  268. case PHY_MODE_RTBI:
  269. epcr |= EPCR_RTBI_MODE;
  270. break;
  271. case PHY_MODE_GMII:
  272. epcr |= EPCR_GMII_MODE;
  273. break;
  274. case PHY_MODE_RGMII:
  275. default:
  276. epcr |= EPCR_RGMII_MODE;
  277. }
  278. phy_write(phy, MII_CIS8201_EPCR, epcr);
  279. /* MII regs override strap pins */
  280. phy_write(phy, MII_CIS8201_ACSR,
  281. phy_read(phy, MII_CIS8201_ACSR) | ACSR_PIN_PRIO_SELECT);
  282. /* Disable TX_EN -> CRS echo mode, otherwise 10/HDX doesn't work */
  283. phy_write(phy, MII_CIS8201_10BTCSR,
  284. phy_read(phy, MII_CIS8201_10BTCSR) | TENBTCSR_ECHO_DISABLE);
  285. return 0;
  286. }
  287. static struct mii_phy_ops cis8201_phy_ops = {
  288. .init = cis8201_init,
  289. .setup_aneg = genmii_setup_aneg,
  290. .setup_forced = genmii_setup_forced,
  291. .poll_link = genmii_poll_link,
  292. .read_link = genmii_read_link
  293. };
  294. static struct mii_phy_def cis8201_phy_def = {
  295. .phy_id = 0x000fc410,
  296. .phy_id_mask = 0x000ffff0,
  297. .name = "CIS8201 Gigabit Ethernet",
  298. .ops = &cis8201_phy_ops
  299. };
  300. static struct mii_phy_def bcm5248_phy_def = {
  301. .phy_id = 0x0143bc00,
  302. .phy_id_mask = 0x0ffffff0,
  303. .name = "BCM5248 10/100 SMII Ethernet",
  304. .ops = &generic_phy_ops
  305. };
  306. static int m88e1111_init(struct mii_phy *phy)
  307. {
  308. pr_debug("%s: Marvell 88E1111 Ethernet\n", __func__);
  309. phy_write(phy, 0x14, 0x0ce3);
  310. phy_write(phy, 0x18, 0x4101);
  311. phy_write(phy, 0x09, 0x0e00);
  312. phy_write(phy, 0x04, 0x01e1);
  313. phy_write(phy, 0x00, 0x9140);
  314. phy_write(phy, 0x00, 0x1140);
  315. return 0;
  316. }
  317. static int m88e1112_init(struct mii_phy *phy)
  318. {
  319. /*
  320. * Marvell 88E1112 PHY needs to have the SGMII MAC
  321. * interace (page 2) properly configured to
  322. * communicate with the 460EX/GT GPCS interface.
  323. */
  324. u16 reg_short;
  325. pr_debug("%s: Marvell 88E1112 Ethernet\n", __func__);
  326. /* Set access to Page 2 */
  327. phy_write(phy, 0x16, 0x0002);
  328. phy_write(phy, 0x00, 0x0040); /* 1Gbps */
  329. reg_short = (u16)(phy_read(phy, 0x1a));
  330. reg_short |= 0x8000; /* bypass Auto-Negotiation */
  331. phy_write(phy, 0x1a, reg_short);
  332. emac_mii_reset_phy(phy); /* reset MAC interface */
  333. /* Reset access to Page 0 */
  334. phy_write(phy, 0x16, 0x0000);
  335. return 0;
  336. }
  337. static int et1011c_init(struct mii_phy *phy)
  338. {
  339. u16 reg_short;
  340. reg_short = (u16)(phy_read(phy, 0x16));
  341. reg_short &= ~(0x7);
  342. reg_short |= 0x6; /* RGMII Trace Delay*/
  343. phy_write(phy, 0x16, reg_short);
  344. reg_short = (u16)(phy_read(phy, 0x17));
  345. reg_short &= ~(0x40);
  346. phy_write(phy, 0x17, reg_short);
  347. phy_write(phy, 0x1c, 0x74f0);
  348. return 0;
  349. }
  350. static struct mii_phy_ops et1011c_phy_ops = {
  351. .init = et1011c_init,
  352. .setup_aneg = genmii_setup_aneg,
  353. .setup_forced = genmii_setup_forced,
  354. .poll_link = genmii_poll_link,
  355. .read_link = genmii_read_link
  356. };
  357. static struct mii_phy_def et1011c_phy_def = {
  358. .phy_id = 0x0282f000,
  359. .phy_id_mask = 0x0fffff00,
  360. .name = "ET1011C Gigabit Ethernet",
  361. .ops = &et1011c_phy_ops
  362. };
  363. static struct mii_phy_ops m88e1111_phy_ops = {
  364. .init = m88e1111_init,
  365. .setup_aneg = genmii_setup_aneg,
  366. .setup_forced = genmii_setup_forced,
  367. .poll_link = genmii_poll_link,
  368. .read_link = genmii_read_link
  369. };
  370. static struct mii_phy_def m88e1111_phy_def = {
  371. .phy_id = 0x01410CC0,
  372. .phy_id_mask = 0x0ffffff0,
  373. .name = "Marvell 88E1111 Ethernet",
  374. .ops = &m88e1111_phy_ops,
  375. };
  376. static struct mii_phy_ops m88e1112_phy_ops = {
  377. .init = m88e1112_init,
  378. .setup_aneg = genmii_setup_aneg,
  379. .setup_forced = genmii_setup_forced,
  380. .poll_link = genmii_poll_link,
  381. .read_link = genmii_read_link
  382. };
  383. static struct mii_phy_def m88e1112_phy_def = {
  384. .phy_id = 0x01410C90,
  385. .phy_id_mask = 0x0ffffff0,
  386. .name = "Marvell 88E1112 Ethernet",
  387. .ops = &m88e1112_phy_ops,
  388. };
  389. static struct mii_phy_def *mii_phy_table[] = {
  390. &et1011c_phy_def,
  391. &cis8201_phy_def,
  392. &bcm5248_phy_def,
  393. &m88e1111_phy_def,
  394. &m88e1112_phy_def,
  395. &genmii_phy_def,
  396. NULL
  397. };
  398. int emac_mii_phy_probe(struct mii_phy *phy, int address)
  399. {
  400. struct mii_phy_def *def;
  401. int i;
  402. u32 id;
  403. phy->autoneg = AUTONEG_DISABLE;
  404. phy->advertising = 0;
  405. phy->address = address;
  406. phy->speed = SPEED_10;
  407. phy->duplex = DUPLEX_HALF;
  408. phy->pause = phy->asym_pause = 0;
  409. /* Take PHY out of isolate mode and reset it. */
  410. if (emac_mii_reset_phy(phy))
  411. return -ENODEV;
  412. /* Read ID and find matching entry */
  413. id = (phy_read(phy, MII_PHYSID1) << 16) | phy_read(phy, MII_PHYSID2);
  414. for (i = 0; (def = mii_phy_table[i]) != NULL; i++)
  415. if ((id & def->phy_id_mask) == def->phy_id)
  416. break;
  417. /* Should never be NULL (we have a generic entry), but... */
  418. if (!def)
  419. return -ENODEV;
  420. phy->def = def;
  421. /* Determine PHY features if needed */
  422. phy->features = def->features;
  423. if (!phy->features) {
  424. u16 bmsr = phy_read(phy, MII_BMSR);
  425. if (bmsr & BMSR_ANEGCAPABLE)
  426. phy->features |= SUPPORTED_Autoneg;
  427. if (bmsr & BMSR_10HALF)
  428. phy->features |= SUPPORTED_10baseT_Half;
  429. if (bmsr & BMSR_10FULL)
  430. phy->features |= SUPPORTED_10baseT_Full;
  431. if (bmsr & BMSR_100HALF)
  432. phy->features |= SUPPORTED_100baseT_Half;
  433. if (bmsr & BMSR_100FULL)
  434. phy->features |= SUPPORTED_100baseT_Full;
  435. if (bmsr & BMSR_ESTATEN) {
  436. u16 esr = phy_read(phy, MII_ESTATUS);
  437. if (esr & ESTATUS_1000_TFULL)
  438. phy->features |= SUPPORTED_1000baseT_Full;
  439. if (esr & ESTATUS_1000_THALF)
  440. phy->features |= SUPPORTED_1000baseT_Half;
  441. }
  442. phy->features |= SUPPORTED_MII;
  443. }
  444. /* Setup default advertising */
  445. phy->advertising = phy->features;
  446. return 0;
  447. }
  448. MODULE_LICENSE("GPL");