ael1002.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218
  1. /*
  2. * Copyright (c) 2005-2008 Chelsio, Inc. All rights reserved.
  3. *
  4. * This software is available to you under a choice of one of two
  5. * licenses. You may choose to be licensed under the terms of the GNU
  6. * General Public License (GPL) Version 2, available from the file
  7. * COPYING in the main directory of this source tree, or the
  8. * OpenIB.org BSD license below:
  9. *
  10. * Redistribution and use in source and binary forms, with or
  11. * without modification, are permitted provided that the following
  12. * conditions are met:
  13. *
  14. * - Redistributions of source code must retain the above
  15. * copyright notice, this list of conditions and the following
  16. * disclaimer.
  17. *
  18. * - Redistributions in binary form must reproduce the above
  19. * copyright notice, this list of conditions and the following
  20. * disclaimer in the documentation and/or other materials
  21. * provided with the distribution.
  22. *
  23. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  24. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  25. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  26. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  27. * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  28. * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  29. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  30. * SOFTWARE.
  31. */
  32. #include "common.h"
  33. #include "regs.h"
  34. enum {
  35. PMD_RSD = 10, /* PMA/PMD receive signal detect register */
  36. PCS_STAT1_X = 24, /* 10GBASE-X PCS status 1 register */
  37. PCS_STAT1_R = 32, /* 10GBASE-R PCS status 1 register */
  38. XS_LN_STAT = 24 /* XS lane status register */
  39. };
  40. enum {
  41. AEL100X_TX_DISABLE = 9,
  42. AEL100X_TX_CONFIG1 = 0xc002,
  43. AEL1002_PWR_DOWN_HI = 0xc011,
  44. AEL1002_PWR_DOWN_LO = 0xc012,
  45. AEL1002_XFI_EQL = 0xc015,
  46. AEL1002_LB_EN = 0xc017,
  47. AEL_OPT_SETTINGS = 0xc017,
  48. AEL_I2C_CTRL = 0xc30a,
  49. AEL_I2C_DATA = 0xc30b,
  50. AEL_I2C_STAT = 0xc30c,
  51. AEL2005_GPIO_CTRL = 0xc214,
  52. AEL2005_GPIO_STAT = 0xc215,
  53. };
  54. enum { edc_none, edc_sr, edc_twinax };
  55. /* PHY module I2C device address */
  56. #define MODULE_DEV_ADDR 0xa0
  57. #define AEL2005_MODDET_IRQ 4
  58. struct reg_val {
  59. unsigned short mmd_addr;
  60. unsigned short reg_addr;
  61. unsigned short clear_bits;
  62. unsigned short set_bits;
  63. };
  64. static int set_phy_regs(struct cphy *phy, const struct reg_val *rv)
  65. {
  66. int err;
  67. for (err = 0; rv->mmd_addr && !err; rv++) {
  68. if (rv->clear_bits == 0xffff)
  69. err = mdio_write(phy, rv->mmd_addr, rv->reg_addr,
  70. rv->set_bits);
  71. else
  72. err = t3_mdio_change_bits(phy, rv->mmd_addr,
  73. rv->reg_addr, rv->clear_bits,
  74. rv->set_bits);
  75. }
  76. return err;
  77. }
  78. static void ael100x_txon(struct cphy *phy)
  79. {
  80. int tx_on_gpio = phy->addr == 0 ? F_GPIO7_OUT_VAL : F_GPIO2_OUT_VAL;
  81. msleep(100);
  82. t3_set_reg_field(phy->adapter, A_T3DBG_GPIO_EN, 0, tx_on_gpio);
  83. msleep(30);
  84. }
  85. static int ael1002_power_down(struct cphy *phy, int enable)
  86. {
  87. int err;
  88. err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL100X_TX_DISABLE, !!enable);
  89. if (!err)
  90. err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR,
  91. BMCR_PDOWN, enable ? BMCR_PDOWN : 0);
  92. return err;
  93. }
  94. static int ael1002_reset(struct cphy *phy, int wait)
  95. {
  96. int err;
  97. if ((err = ael1002_power_down(phy, 0)) ||
  98. (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL100X_TX_CONFIG1, 1)) ||
  99. (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_PWR_DOWN_HI, 0)) ||
  100. (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_PWR_DOWN_LO, 0)) ||
  101. (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_XFI_EQL, 0x18)) ||
  102. (err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL1002_LB_EN,
  103. 0, 1 << 5)))
  104. return err;
  105. return 0;
  106. }
  107. static int ael1002_intr_noop(struct cphy *phy)
  108. {
  109. return 0;
  110. }
  111. /*
  112. * Get link status for a 10GBASE-R device.
  113. */
  114. static int get_link_status_r(struct cphy *phy, int *link_ok, int *speed,
  115. int *duplex, int *fc)
  116. {
  117. if (link_ok) {
  118. unsigned int stat0, stat1, stat2;
  119. int err = mdio_read(phy, MDIO_DEV_PMA_PMD, PMD_RSD, &stat0);
  120. if (!err)
  121. err = mdio_read(phy, MDIO_DEV_PCS, PCS_STAT1_R, &stat1);
  122. if (!err)
  123. err = mdio_read(phy, MDIO_DEV_XGXS, XS_LN_STAT, &stat2);
  124. if (err)
  125. return err;
  126. *link_ok = (stat0 & stat1 & (stat2 >> 12)) & 1;
  127. }
  128. if (speed)
  129. *speed = SPEED_10000;
  130. if (duplex)
  131. *duplex = DUPLEX_FULL;
  132. return 0;
  133. }
  134. static struct cphy_ops ael1002_ops = {
  135. .reset = ael1002_reset,
  136. .intr_enable = ael1002_intr_noop,
  137. .intr_disable = ael1002_intr_noop,
  138. .intr_clear = ael1002_intr_noop,
  139. .intr_handler = ael1002_intr_noop,
  140. .get_link_status = get_link_status_r,
  141. .power_down = ael1002_power_down,
  142. };
  143. int t3_ael1002_phy_prep(struct cphy *phy, struct adapter *adapter,
  144. int phy_addr, const struct mdio_ops *mdio_ops)
  145. {
  146. cphy_init(phy, adapter, phy_addr, &ael1002_ops, mdio_ops,
  147. SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE,
  148. "10GBASE-R");
  149. ael100x_txon(phy);
  150. return 0;
  151. }
  152. static int ael1006_reset(struct cphy *phy, int wait)
  153. {
  154. return t3_phy_reset(phy, MDIO_DEV_PMA_PMD, wait);
  155. }
  156. static int ael1006_power_down(struct cphy *phy, int enable)
  157. {
  158. return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR,
  159. BMCR_PDOWN, enable ? BMCR_PDOWN : 0);
  160. }
  161. static struct cphy_ops ael1006_ops = {
  162. .reset = ael1006_reset,
  163. .intr_enable = t3_phy_lasi_intr_enable,
  164. .intr_disable = t3_phy_lasi_intr_disable,
  165. .intr_clear = t3_phy_lasi_intr_clear,
  166. .intr_handler = t3_phy_lasi_intr_handler,
  167. .get_link_status = get_link_status_r,
  168. .power_down = ael1006_power_down,
  169. };
  170. int t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter,
  171. int phy_addr, const struct mdio_ops *mdio_ops)
  172. {
  173. cphy_init(phy, adapter, phy_addr, &ael1006_ops, mdio_ops,
  174. SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE,
  175. "10GBASE-SR");
  176. ael100x_txon(phy);
  177. return 0;
  178. }
  179. static int ael2005_setup_sr_edc(struct cphy *phy)
  180. {
  181. static struct reg_val regs[] = {
  182. { MDIO_DEV_PMA_PMD, 0xc003, 0xffff, 0x181 },
  183. { MDIO_DEV_PMA_PMD, 0xc010, 0xffff, 0x448a },
  184. { MDIO_DEV_PMA_PMD, 0xc04a, 0xffff, 0x5200 },
  185. { 0, 0, 0, 0 }
  186. };
  187. static u16 sr_edc[] = {
  188. 0xcc00, 0x2ff4,
  189. 0xcc01, 0x3cd4,
  190. 0xcc02, 0x2015,
  191. 0xcc03, 0x3105,
  192. 0xcc04, 0x6524,
  193. 0xcc05, 0x27ff,
  194. 0xcc06, 0x300f,
  195. 0xcc07, 0x2c8b,
  196. 0xcc08, 0x300b,
  197. 0xcc09, 0x4009,
  198. 0xcc0a, 0x400e,
  199. 0xcc0b, 0x2f72,
  200. 0xcc0c, 0x3002,
  201. 0xcc0d, 0x1002,
  202. 0xcc0e, 0x2172,
  203. 0xcc0f, 0x3012,
  204. 0xcc10, 0x1002,
  205. 0xcc11, 0x25d2,
  206. 0xcc12, 0x3012,
  207. 0xcc13, 0x1002,
  208. 0xcc14, 0xd01e,
  209. 0xcc15, 0x27d2,
  210. 0xcc16, 0x3012,
  211. 0xcc17, 0x1002,
  212. 0xcc18, 0x2004,
  213. 0xcc19, 0x3c84,
  214. 0xcc1a, 0x6436,
  215. 0xcc1b, 0x2007,
  216. 0xcc1c, 0x3f87,
  217. 0xcc1d, 0x8676,
  218. 0xcc1e, 0x40b7,
  219. 0xcc1f, 0xa746,
  220. 0xcc20, 0x4047,
  221. 0xcc21, 0x5673,
  222. 0xcc22, 0x2982,
  223. 0xcc23, 0x3002,
  224. 0xcc24, 0x13d2,
  225. 0xcc25, 0x8bbd,
  226. 0xcc26, 0x2862,
  227. 0xcc27, 0x3012,
  228. 0xcc28, 0x1002,
  229. 0xcc29, 0x2092,
  230. 0xcc2a, 0x3012,
  231. 0xcc2b, 0x1002,
  232. 0xcc2c, 0x5cc3,
  233. 0xcc2d, 0x314,
  234. 0xcc2e, 0x2942,
  235. 0xcc2f, 0x3002,
  236. 0xcc30, 0x1002,
  237. 0xcc31, 0xd019,
  238. 0xcc32, 0x2032,
  239. 0xcc33, 0x3012,
  240. 0xcc34, 0x1002,
  241. 0xcc35, 0x2a04,
  242. 0xcc36, 0x3c74,
  243. 0xcc37, 0x6435,
  244. 0xcc38, 0x2fa4,
  245. 0xcc39, 0x3cd4,
  246. 0xcc3a, 0x6624,
  247. 0xcc3b, 0x5563,
  248. 0xcc3c, 0x2d42,
  249. 0xcc3d, 0x3002,
  250. 0xcc3e, 0x13d2,
  251. 0xcc3f, 0x464d,
  252. 0xcc40, 0x2862,
  253. 0xcc41, 0x3012,
  254. 0xcc42, 0x1002,
  255. 0xcc43, 0x2032,
  256. 0xcc44, 0x3012,
  257. 0xcc45, 0x1002,
  258. 0xcc46, 0x2fb4,
  259. 0xcc47, 0x3cd4,
  260. 0xcc48, 0x6624,
  261. 0xcc49, 0x5563,
  262. 0xcc4a, 0x2d42,
  263. 0xcc4b, 0x3002,
  264. 0xcc4c, 0x13d2,
  265. 0xcc4d, 0x2ed2,
  266. 0xcc4e, 0x3002,
  267. 0xcc4f, 0x1002,
  268. 0xcc50, 0x2fd2,
  269. 0xcc51, 0x3002,
  270. 0xcc52, 0x1002,
  271. 0xcc53, 0x004,
  272. 0xcc54, 0x2942,
  273. 0xcc55, 0x3002,
  274. 0xcc56, 0x1002,
  275. 0xcc57, 0x2092,
  276. 0xcc58, 0x3012,
  277. 0xcc59, 0x1002,
  278. 0xcc5a, 0x5cc3,
  279. 0xcc5b, 0x317,
  280. 0xcc5c, 0x2f72,
  281. 0xcc5d, 0x3002,
  282. 0xcc5e, 0x1002,
  283. 0xcc5f, 0x2942,
  284. 0xcc60, 0x3002,
  285. 0xcc61, 0x1002,
  286. 0xcc62, 0x22cd,
  287. 0xcc63, 0x301d,
  288. 0xcc64, 0x2862,
  289. 0xcc65, 0x3012,
  290. 0xcc66, 0x1002,
  291. 0xcc67, 0x2ed2,
  292. 0xcc68, 0x3002,
  293. 0xcc69, 0x1002,
  294. 0xcc6a, 0x2d72,
  295. 0xcc6b, 0x3002,
  296. 0xcc6c, 0x1002,
  297. 0xcc6d, 0x628f,
  298. 0xcc6e, 0x2112,
  299. 0xcc6f, 0x3012,
  300. 0xcc70, 0x1002,
  301. 0xcc71, 0x5aa3,
  302. 0xcc72, 0x2dc2,
  303. 0xcc73, 0x3002,
  304. 0xcc74, 0x1312,
  305. 0xcc75, 0x6f72,
  306. 0xcc76, 0x1002,
  307. 0xcc77, 0x2807,
  308. 0xcc78, 0x31a7,
  309. 0xcc79, 0x20c4,
  310. 0xcc7a, 0x3c24,
  311. 0xcc7b, 0x6724,
  312. 0xcc7c, 0x1002,
  313. 0xcc7d, 0x2807,
  314. 0xcc7e, 0x3187,
  315. 0xcc7f, 0x20c4,
  316. 0xcc80, 0x3c24,
  317. 0xcc81, 0x6724,
  318. 0xcc82, 0x1002,
  319. 0xcc83, 0x2514,
  320. 0xcc84, 0x3c64,
  321. 0xcc85, 0x6436,
  322. 0xcc86, 0xdff4,
  323. 0xcc87, 0x6436,
  324. 0xcc88, 0x1002,
  325. 0xcc89, 0x40a4,
  326. 0xcc8a, 0x643c,
  327. 0xcc8b, 0x4016,
  328. 0xcc8c, 0x8c6c,
  329. 0xcc8d, 0x2b24,
  330. 0xcc8e, 0x3c24,
  331. 0xcc8f, 0x6435,
  332. 0xcc90, 0x1002,
  333. 0xcc91, 0x2b24,
  334. 0xcc92, 0x3c24,
  335. 0xcc93, 0x643a,
  336. 0xcc94, 0x4025,
  337. 0xcc95, 0x8a5a,
  338. 0xcc96, 0x1002,
  339. 0xcc97, 0x2731,
  340. 0xcc98, 0x3011,
  341. 0xcc99, 0x1001,
  342. 0xcc9a, 0xc7a0,
  343. 0xcc9b, 0x100,
  344. 0xcc9c, 0xc502,
  345. 0xcc9d, 0x53ac,
  346. 0xcc9e, 0xc503,
  347. 0xcc9f, 0xd5d5,
  348. 0xcca0, 0xc600,
  349. 0xcca1, 0x2a6d,
  350. 0xcca2, 0xc601,
  351. 0xcca3, 0x2a4c,
  352. 0xcca4, 0xc602,
  353. 0xcca5, 0x111,
  354. 0xcca6, 0xc60c,
  355. 0xcca7, 0x5900,
  356. 0xcca8, 0xc710,
  357. 0xcca9, 0x700,
  358. 0xccaa, 0xc718,
  359. 0xccab, 0x700,
  360. 0xccac, 0xc720,
  361. 0xccad, 0x4700,
  362. 0xccae, 0xc801,
  363. 0xccaf, 0x7f50,
  364. 0xccb0, 0xc802,
  365. 0xccb1, 0x7760,
  366. 0xccb2, 0xc803,
  367. 0xccb3, 0x7fce,
  368. 0xccb4, 0xc804,
  369. 0xccb5, 0x5700,
  370. 0xccb6, 0xc805,
  371. 0xccb7, 0x5f11,
  372. 0xccb8, 0xc806,
  373. 0xccb9, 0x4751,
  374. 0xccba, 0xc807,
  375. 0xccbb, 0x57e1,
  376. 0xccbc, 0xc808,
  377. 0xccbd, 0x2700,
  378. 0xccbe, 0xc809,
  379. 0xccbf, 0x000,
  380. 0xccc0, 0xc821,
  381. 0xccc1, 0x002,
  382. 0xccc2, 0xc822,
  383. 0xccc3, 0x014,
  384. 0xccc4, 0xc832,
  385. 0xccc5, 0x1186,
  386. 0xccc6, 0xc847,
  387. 0xccc7, 0x1e02,
  388. 0xccc8, 0xc013,
  389. 0xccc9, 0xf341,
  390. 0xccca, 0xc01a,
  391. 0xcccb, 0x446,
  392. 0xcccc, 0xc024,
  393. 0xcccd, 0x1000,
  394. 0xccce, 0xc025,
  395. 0xcccf, 0xa00,
  396. 0xccd0, 0xc026,
  397. 0xccd1, 0xc0c,
  398. 0xccd2, 0xc027,
  399. 0xccd3, 0xc0c,
  400. 0xccd4, 0xc029,
  401. 0xccd5, 0x0a0,
  402. 0xccd6, 0xc030,
  403. 0xccd7, 0xa00,
  404. 0xccd8, 0xc03c,
  405. 0xccd9, 0x01c,
  406. 0xccda, 0xc005,
  407. 0xccdb, 0x7a06,
  408. 0xccdc, 0x000,
  409. 0xccdd, 0x2731,
  410. 0xccde, 0x3011,
  411. 0xccdf, 0x1001,
  412. 0xcce0, 0xc620,
  413. 0xcce1, 0x000,
  414. 0xcce2, 0xc621,
  415. 0xcce3, 0x03f,
  416. 0xcce4, 0xc622,
  417. 0xcce5, 0x000,
  418. 0xcce6, 0xc623,
  419. 0xcce7, 0x000,
  420. 0xcce8, 0xc624,
  421. 0xcce9, 0x000,
  422. 0xccea, 0xc625,
  423. 0xcceb, 0x000,
  424. 0xccec, 0xc627,
  425. 0xcced, 0x000,
  426. 0xccee, 0xc628,
  427. 0xccef, 0x000,
  428. 0xccf0, 0xc62c,
  429. 0xccf1, 0x000,
  430. 0xccf2, 0x000,
  431. 0xccf3, 0x2806,
  432. 0xccf4, 0x3cb6,
  433. 0xccf5, 0xc161,
  434. 0xccf6, 0x6134,
  435. 0xccf7, 0x6135,
  436. 0xccf8, 0x5443,
  437. 0xccf9, 0x303,
  438. 0xccfa, 0x6524,
  439. 0xccfb, 0x00b,
  440. 0xccfc, 0x1002,
  441. 0xccfd, 0x2104,
  442. 0xccfe, 0x3c24,
  443. 0xccff, 0x2105,
  444. 0xcd00, 0x3805,
  445. 0xcd01, 0x6524,
  446. 0xcd02, 0xdff4,
  447. 0xcd03, 0x4005,
  448. 0xcd04, 0x6524,
  449. 0xcd05, 0x1002,
  450. 0xcd06, 0x5dd3,
  451. 0xcd07, 0x306,
  452. 0xcd08, 0x2ff7,
  453. 0xcd09, 0x38f7,
  454. 0xcd0a, 0x60b7,
  455. 0xcd0b, 0xdffd,
  456. 0xcd0c, 0x00a,
  457. 0xcd0d, 0x1002,
  458. 0xcd0e, 0
  459. };
  460. int i, err;
  461. err = set_phy_regs(phy, regs);
  462. if (err)
  463. return err;
  464. msleep(50);
  465. for (i = 0; i < ARRAY_SIZE(sr_edc) && !err; i += 2)
  466. err = mdio_write(phy, MDIO_DEV_PMA_PMD, sr_edc[i],
  467. sr_edc[i + 1]);
  468. if (!err)
  469. phy->priv = edc_sr;
  470. return err;
  471. }
  472. static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype)
  473. {
  474. static struct reg_val regs[] = {
  475. { MDIO_DEV_PMA_PMD, 0xc04a, 0xffff, 0x5a00 },
  476. { 0, 0, 0, 0 }
  477. };
  478. static struct reg_val preemphasis[] = {
  479. { MDIO_DEV_PMA_PMD, 0xc014, 0xffff, 0xfe16 },
  480. { MDIO_DEV_PMA_PMD, 0xc015, 0xffff, 0xa000 },
  481. { 0, 0, 0, 0 }
  482. };
  483. static u16 twinax_edc[] = {
  484. 0xcc00, 0x4009,
  485. 0xcc01, 0x27ff,
  486. 0xcc02, 0x300f,
  487. 0xcc03, 0x40aa,
  488. 0xcc04, 0x401c,
  489. 0xcc05, 0x401e,
  490. 0xcc06, 0x2ff4,
  491. 0xcc07, 0x3cd4,
  492. 0xcc08, 0x2035,
  493. 0xcc09, 0x3145,
  494. 0xcc0a, 0x6524,
  495. 0xcc0b, 0x26a2,
  496. 0xcc0c, 0x3012,
  497. 0xcc0d, 0x1002,
  498. 0xcc0e, 0x29c2,
  499. 0xcc0f, 0x3002,
  500. 0xcc10, 0x1002,
  501. 0xcc11, 0x2072,
  502. 0xcc12, 0x3012,
  503. 0xcc13, 0x1002,
  504. 0xcc14, 0x22cd,
  505. 0xcc15, 0x301d,
  506. 0xcc16, 0x2e52,
  507. 0xcc17, 0x3012,
  508. 0xcc18, 0x1002,
  509. 0xcc19, 0x28e2,
  510. 0xcc1a, 0x3002,
  511. 0xcc1b, 0x1002,
  512. 0xcc1c, 0x628f,
  513. 0xcc1d, 0x2ac2,
  514. 0xcc1e, 0x3012,
  515. 0xcc1f, 0x1002,
  516. 0xcc20, 0x5553,
  517. 0xcc21, 0x2ae2,
  518. 0xcc22, 0x3002,
  519. 0xcc23, 0x1302,
  520. 0xcc24, 0x401e,
  521. 0xcc25, 0x2be2,
  522. 0xcc26, 0x3012,
  523. 0xcc27, 0x1002,
  524. 0xcc28, 0x2da2,
  525. 0xcc29, 0x3012,
  526. 0xcc2a, 0x1002,
  527. 0xcc2b, 0x2ba2,
  528. 0xcc2c, 0x3002,
  529. 0xcc2d, 0x1002,
  530. 0xcc2e, 0x5ee3,
  531. 0xcc2f, 0x305,
  532. 0xcc30, 0x400e,
  533. 0xcc31, 0x2bc2,
  534. 0xcc32, 0x3002,
  535. 0xcc33, 0x1002,
  536. 0xcc34, 0x2b82,
  537. 0xcc35, 0x3012,
  538. 0xcc36, 0x1002,
  539. 0xcc37, 0x5663,
  540. 0xcc38, 0x302,
  541. 0xcc39, 0x401e,
  542. 0xcc3a, 0x6f72,
  543. 0xcc3b, 0x1002,
  544. 0xcc3c, 0x628f,
  545. 0xcc3d, 0x2be2,
  546. 0xcc3e, 0x3012,
  547. 0xcc3f, 0x1002,
  548. 0xcc40, 0x22cd,
  549. 0xcc41, 0x301d,
  550. 0xcc42, 0x2e52,
  551. 0xcc43, 0x3012,
  552. 0xcc44, 0x1002,
  553. 0xcc45, 0x2522,
  554. 0xcc46, 0x3012,
  555. 0xcc47, 0x1002,
  556. 0xcc48, 0x2da2,
  557. 0xcc49, 0x3012,
  558. 0xcc4a, 0x1002,
  559. 0xcc4b, 0x2ca2,
  560. 0xcc4c, 0x3012,
  561. 0xcc4d, 0x1002,
  562. 0xcc4e, 0x2fa4,
  563. 0xcc4f, 0x3cd4,
  564. 0xcc50, 0x6624,
  565. 0xcc51, 0x410b,
  566. 0xcc52, 0x56b3,
  567. 0xcc53, 0x3c4,
  568. 0xcc54, 0x2fb2,
  569. 0xcc55, 0x3002,
  570. 0xcc56, 0x1002,
  571. 0xcc57, 0x220b,
  572. 0xcc58, 0x303b,
  573. 0xcc59, 0x56b3,
  574. 0xcc5a, 0x3c3,
  575. 0xcc5b, 0x866b,
  576. 0xcc5c, 0x400c,
  577. 0xcc5d, 0x23a2,
  578. 0xcc5e, 0x3012,
  579. 0xcc5f, 0x1002,
  580. 0xcc60, 0x2da2,
  581. 0xcc61, 0x3012,
  582. 0xcc62, 0x1002,
  583. 0xcc63, 0x2ca2,
  584. 0xcc64, 0x3012,
  585. 0xcc65, 0x1002,
  586. 0xcc66, 0x2fb4,
  587. 0xcc67, 0x3cd4,
  588. 0xcc68, 0x6624,
  589. 0xcc69, 0x56b3,
  590. 0xcc6a, 0x3c3,
  591. 0xcc6b, 0x866b,
  592. 0xcc6c, 0x401c,
  593. 0xcc6d, 0x2205,
  594. 0xcc6e, 0x3035,
  595. 0xcc6f, 0x5b53,
  596. 0xcc70, 0x2c52,
  597. 0xcc71, 0x3002,
  598. 0xcc72, 0x13c2,
  599. 0xcc73, 0x5cc3,
  600. 0xcc74, 0x317,
  601. 0xcc75, 0x2522,
  602. 0xcc76, 0x3012,
  603. 0xcc77, 0x1002,
  604. 0xcc78, 0x2da2,
  605. 0xcc79, 0x3012,
  606. 0xcc7a, 0x1002,
  607. 0xcc7b, 0x2b82,
  608. 0xcc7c, 0x3012,
  609. 0xcc7d, 0x1002,
  610. 0xcc7e, 0x5663,
  611. 0xcc7f, 0x303,
  612. 0xcc80, 0x401e,
  613. 0xcc81, 0x004,
  614. 0xcc82, 0x2c42,
  615. 0xcc83, 0x3012,
  616. 0xcc84, 0x1002,
  617. 0xcc85, 0x6f72,
  618. 0xcc86, 0x1002,
  619. 0xcc87, 0x628f,
  620. 0xcc88, 0x2304,
  621. 0xcc89, 0x3c84,
  622. 0xcc8a, 0x6436,
  623. 0xcc8b, 0xdff4,
  624. 0xcc8c, 0x6436,
  625. 0xcc8d, 0x2ff5,
  626. 0xcc8e, 0x3005,
  627. 0xcc8f, 0x8656,
  628. 0xcc90, 0xdfba,
  629. 0xcc91, 0x56a3,
  630. 0xcc92, 0xd05a,
  631. 0xcc93, 0x21c2,
  632. 0xcc94, 0x3012,
  633. 0xcc95, 0x1392,
  634. 0xcc96, 0xd05a,
  635. 0xcc97, 0x56a3,
  636. 0xcc98, 0xdfba,
  637. 0xcc99, 0x383,
  638. 0xcc9a, 0x6f72,
  639. 0xcc9b, 0x1002,
  640. 0xcc9c, 0x28c5,
  641. 0xcc9d, 0x3005,
  642. 0xcc9e, 0x4178,
  643. 0xcc9f, 0x5653,
  644. 0xcca0, 0x384,
  645. 0xcca1, 0x22b2,
  646. 0xcca2, 0x3012,
  647. 0xcca3, 0x1002,
  648. 0xcca4, 0x2be5,
  649. 0xcca5, 0x3005,
  650. 0xcca6, 0x41e8,
  651. 0xcca7, 0x5653,
  652. 0xcca8, 0x382,
  653. 0xcca9, 0x002,
  654. 0xccaa, 0x4258,
  655. 0xccab, 0x2474,
  656. 0xccac, 0x3c84,
  657. 0xccad, 0x6437,
  658. 0xccae, 0xdff4,
  659. 0xccaf, 0x6437,
  660. 0xccb0, 0x2ff5,
  661. 0xccb1, 0x3c05,
  662. 0xccb2, 0x8757,
  663. 0xccb3, 0xb888,
  664. 0xccb4, 0x9787,
  665. 0xccb5, 0xdff4,
  666. 0xccb6, 0x6724,
  667. 0xccb7, 0x866a,
  668. 0xccb8, 0x6f72,
  669. 0xccb9, 0x1002,
  670. 0xccba, 0x2d01,
  671. 0xccbb, 0x3011,
  672. 0xccbc, 0x1001,
  673. 0xccbd, 0xc620,
  674. 0xccbe, 0x14e5,
  675. 0xccbf, 0xc621,
  676. 0xccc0, 0xc53d,
  677. 0xccc1, 0xc622,
  678. 0xccc2, 0x3cbe,
  679. 0xccc3, 0xc623,
  680. 0xccc4, 0x4452,
  681. 0xccc5, 0xc624,
  682. 0xccc6, 0xc5c5,
  683. 0xccc7, 0xc625,
  684. 0xccc8, 0xe01e,
  685. 0xccc9, 0xc627,
  686. 0xccca, 0x000,
  687. 0xcccb, 0xc628,
  688. 0xcccc, 0x000,
  689. 0xcccd, 0xc62b,
  690. 0xccce, 0x000,
  691. 0xcccf, 0xc62c,
  692. 0xccd0, 0x000,
  693. 0xccd1, 0x000,
  694. 0xccd2, 0x2d01,
  695. 0xccd3, 0x3011,
  696. 0xccd4, 0x1001,
  697. 0xccd5, 0xc620,
  698. 0xccd6, 0x000,
  699. 0xccd7, 0xc621,
  700. 0xccd8, 0x000,
  701. 0xccd9, 0xc622,
  702. 0xccda, 0x0ce,
  703. 0xccdb, 0xc623,
  704. 0xccdc, 0x07f,
  705. 0xccdd, 0xc624,
  706. 0xccde, 0x032,
  707. 0xccdf, 0xc625,
  708. 0xcce0, 0x000,
  709. 0xcce1, 0xc627,
  710. 0xcce2, 0x000,
  711. 0xcce3, 0xc628,
  712. 0xcce4, 0x000,
  713. 0xcce5, 0xc62b,
  714. 0xcce6, 0x000,
  715. 0xcce7, 0xc62c,
  716. 0xcce8, 0x000,
  717. 0xcce9, 0x000,
  718. 0xccea, 0x2d01,
  719. 0xcceb, 0x3011,
  720. 0xccec, 0x1001,
  721. 0xcced, 0xc502,
  722. 0xccee, 0x609f,
  723. 0xccef, 0xc600,
  724. 0xccf0, 0x2a6e,
  725. 0xccf1, 0xc601,
  726. 0xccf2, 0x2a2c,
  727. 0xccf3, 0xc60c,
  728. 0xccf4, 0x5400,
  729. 0xccf5, 0xc710,
  730. 0xccf6, 0x700,
  731. 0xccf7, 0xc718,
  732. 0xccf8, 0x700,
  733. 0xccf9, 0xc720,
  734. 0xccfa, 0x4700,
  735. 0xccfb, 0xc728,
  736. 0xccfc, 0x700,
  737. 0xccfd, 0xc729,
  738. 0xccfe, 0x1207,
  739. 0xccff, 0xc801,
  740. 0xcd00, 0x7f50,
  741. 0xcd01, 0xc802,
  742. 0xcd02, 0x7760,
  743. 0xcd03, 0xc803,
  744. 0xcd04, 0x7fce,
  745. 0xcd05, 0xc804,
  746. 0xcd06, 0x520e,
  747. 0xcd07, 0xc805,
  748. 0xcd08, 0x5c11,
  749. 0xcd09, 0xc806,
  750. 0xcd0a, 0x3c51,
  751. 0xcd0b, 0xc807,
  752. 0xcd0c, 0x4061,
  753. 0xcd0d, 0xc808,
  754. 0xcd0e, 0x49c1,
  755. 0xcd0f, 0xc809,
  756. 0xcd10, 0x3840,
  757. 0xcd11, 0xc80a,
  758. 0xcd12, 0x000,
  759. 0xcd13, 0xc821,
  760. 0xcd14, 0x002,
  761. 0xcd15, 0xc822,
  762. 0xcd16, 0x046,
  763. 0xcd17, 0xc844,
  764. 0xcd18, 0x182f,
  765. 0xcd19, 0xc013,
  766. 0xcd1a, 0xf341,
  767. 0xcd1b, 0xc01a,
  768. 0xcd1c, 0x446,
  769. 0xcd1d, 0xc024,
  770. 0xcd1e, 0x1000,
  771. 0xcd1f, 0xc025,
  772. 0xcd20, 0xa00,
  773. 0xcd21, 0xc026,
  774. 0xcd22, 0xc0c,
  775. 0xcd23, 0xc027,
  776. 0xcd24, 0xc0c,
  777. 0xcd25, 0xc029,
  778. 0xcd26, 0x0a0,
  779. 0xcd27, 0xc030,
  780. 0xcd28, 0xa00,
  781. 0xcd29, 0xc03c,
  782. 0xcd2a, 0x01c,
  783. 0xcd2b, 0x000,
  784. 0xcd2c, 0x2b84,
  785. 0xcd2d, 0x3c74,
  786. 0xcd2e, 0x6435,
  787. 0xcd2f, 0xdff4,
  788. 0xcd30, 0x6435,
  789. 0xcd31, 0x2806,
  790. 0xcd32, 0x3006,
  791. 0xcd33, 0x8565,
  792. 0xcd34, 0x2b24,
  793. 0xcd35, 0x3c24,
  794. 0xcd36, 0x6436,
  795. 0xcd37, 0x1002,
  796. 0xcd38, 0x2b24,
  797. 0xcd39, 0x3c24,
  798. 0xcd3a, 0x6436,
  799. 0xcd3b, 0x4045,
  800. 0xcd3c, 0x8656,
  801. 0xcd3d, 0x1002,
  802. 0xcd3e, 0x2807,
  803. 0xcd3f, 0x31a7,
  804. 0xcd40, 0x20c4,
  805. 0xcd41, 0x3c24,
  806. 0xcd42, 0x6724,
  807. 0xcd43, 0x1002,
  808. 0xcd44, 0x2807,
  809. 0xcd45, 0x3187,
  810. 0xcd46, 0x20c4,
  811. 0xcd47, 0x3c24,
  812. 0xcd48, 0x6724,
  813. 0xcd49, 0x1002,
  814. 0xcd4a, 0x2514,
  815. 0xcd4b, 0x3c64,
  816. 0xcd4c, 0x6436,
  817. 0xcd4d, 0xdff4,
  818. 0xcd4e, 0x6436,
  819. 0xcd4f, 0x1002,
  820. 0xcd50, 0x2806,
  821. 0xcd51, 0x3cb6,
  822. 0xcd52, 0xc161,
  823. 0xcd53, 0x6134,
  824. 0xcd54, 0x6135,
  825. 0xcd55, 0x5443,
  826. 0xcd56, 0x303,
  827. 0xcd57, 0x6524,
  828. 0xcd58, 0x00b,
  829. 0xcd59, 0x1002,
  830. 0xcd5a, 0xd019,
  831. 0xcd5b, 0x2104,
  832. 0xcd5c, 0x3c24,
  833. 0xcd5d, 0x2105,
  834. 0xcd5e, 0x3805,
  835. 0xcd5f, 0x6524,
  836. 0xcd60, 0xdff4,
  837. 0xcd61, 0x4005,
  838. 0xcd62, 0x6524,
  839. 0xcd63, 0x2e8d,
  840. 0xcd64, 0x303d,
  841. 0xcd65, 0x5dd3,
  842. 0xcd66, 0x306,
  843. 0xcd67, 0x2ff7,
  844. 0xcd68, 0x38f7,
  845. 0xcd69, 0x60b7,
  846. 0xcd6a, 0xdffd,
  847. 0xcd6b, 0x00a,
  848. 0xcd6c, 0x1002,
  849. 0xcd6d, 0
  850. };
  851. int i, err;
  852. err = set_phy_regs(phy, regs);
  853. if (!err && modtype == phy_modtype_twinax_long)
  854. err = set_phy_regs(phy, preemphasis);
  855. if (err)
  856. return err;
  857. msleep(50);
  858. for (i = 0; i < ARRAY_SIZE(twinax_edc) && !err; i += 2)
  859. err = mdio_write(phy, MDIO_DEV_PMA_PMD, twinax_edc[i],
  860. twinax_edc[i + 1]);
  861. if (!err)
  862. phy->priv = edc_twinax;
  863. return err;
  864. }
  865. static int ael2005_i2c_rd(struct cphy *phy, int dev_addr, int word_addr)
  866. {
  867. int i, err;
  868. unsigned int stat, data;
  869. err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL_I2C_CTRL,
  870. (dev_addr << 8) | (1 << 8) | word_addr);
  871. if (err)
  872. return err;
  873. for (i = 0; i < 5; i++) {
  874. msleep(1);
  875. err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_STAT, &stat);
  876. if (err)
  877. return err;
  878. if ((stat & 3) == 1) {
  879. err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_DATA,
  880. &data);
  881. if (err)
  882. return err;
  883. return data >> 8;
  884. }
  885. }
  886. CH_WARN(phy->adapter, "PHY %u I2C read of addr %u timed out\n",
  887. phy->addr, word_addr);
  888. return -ETIMEDOUT;
  889. }
  890. static int get_module_type(struct cphy *phy, int delay_ms)
  891. {
  892. int v;
  893. unsigned int stat;
  894. v = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, &stat);
  895. if (v)
  896. return v;
  897. if (stat & (1 << 8)) /* module absent */
  898. return phy_modtype_none;
  899. if (delay_ms)
  900. msleep(delay_ms);
  901. /* see SFF-8472 for below */
  902. v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 3);
  903. if (v < 0)
  904. return v;
  905. if (v == 0x10)
  906. return phy_modtype_sr;
  907. if (v == 0x20)
  908. return phy_modtype_lr;
  909. if (v == 0x40)
  910. return phy_modtype_lrm;
  911. v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 6);
  912. if (v < 0)
  913. return v;
  914. if (v != 4)
  915. goto unknown;
  916. v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 10);
  917. if (v < 0)
  918. return v;
  919. if (v & 0x80) {
  920. v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 0x12);
  921. if (v < 0)
  922. return v;
  923. return v > 10 ? phy_modtype_twinax_long : phy_modtype_twinax;
  924. }
  925. unknown:
  926. return phy_modtype_unknown;
  927. }
  928. static int ael2005_intr_enable(struct cphy *phy)
  929. {
  930. int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0x200);
  931. return err ? err : t3_phy_lasi_intr_enable(phy);
  932. }
  933. static int ael2005_intr_disable(struct cphy *phy)
  934. {
  935. int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0x100);
  936. return err ? err : t3_phy_lasi_intr_disable(phy);
  937. }
  938. static int ael2005_intr_clear(struct cphy *phy)
  939. {
  940. int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0xd00);
  941. return err ? err : t3_phy_lasi_intr_clear(phy);
  942. }
  943. static int ael2005_reset(struct cphy *phy, int wait)
  944. {
  945. static struct reg_val regs0[] = {
  946. { MDIO_DEV_PMA_PMD, 0xc001, 0, 1 << 5 },
  947. { MDIO_DEV_PMA_PMD, 0xc017, 0, 1 << 5 },
  948. { MDIO_DEV_PMA_PMD, 0xc013, 0xffff, 0xf341 },
  949. { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8000 },
  950. { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8100 },
  951. { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8000 },
  952. { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0 },
  953. { 0, 0, 0, 0 }
  954. };
  955. static struct reg_val regs1[] = {
  956. { MDIO_DEV_PMA_PMD, 0xca00, 0xffff, 0x0080 },
  957. { MDIO_DEV_PMA_PMD, 0xca12, 0xffff, 0 },
  958. { 0, 0, 0, 0 }
  959. };
  960. int err;
  961. unsigned int lasi_ctrl;
  962. err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, &lasi_ctrl);
  963. if (err)
  964. return err;
  965. err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, 0);
  966. if (err)
  967. return err;
  968. msleep(125);
  969. phy->priv = edc_none;
  970. err = set_phy_regs(phy, regs0);
  971. if (err)
  972. return err;
  973. msleep(50);
  974. err = get_module_type(phy, 0);
  975. if (err < 0)
  976. return err;
  977. phy->modtype = err;
  978. if (err == phy_modtype_twinax || err == phy_modtype_twinax_long)
  979. err = ael2005_setup_twinax_edc(phy, err);
  980. else
  981. err = ael2005_setup_sr_edc(phy);
  982. if (err)
  983. return err;
  984. err = set_phy_regs(phy, regs1);
  985. if (err)
  986. return err;
  987. /* reset wipes out interrupts, reenable them if they were on */
  988. if (lasi_ctrl & 1)
  989. err = ael2005_intr_enable(phy);
  990. return err;
  991. }
  992. static int ael2005_intr_handler(struct cphy *phy)
  993. {
  994. unsigned int stat;
  995. int ret, edc_needed, cause = 0;
  996. ret = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_STAT, &stat);
  997. if (ret)
  998. return ret;
  999. if (stat & AEL2005_MODDET_IRQ) {
  1000. ret = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL,
  1001. 0xd00);
  1002. if (ret)
  1003. return ret;
  1004. /* modules have max 300 ms init time after hot plug */
  1005. ret = get_module_type(phy, 300);
  1006. if (ret < 0)
  1007. return ret;
  1008. phy->modtype = ret;
  1009. if (ret == phy_modtype_none)
  1010. edc_needed = phy->priv; /* on unplug retain EDC */
  1011. else if (ret == phy_modtype_twinax ||
  1012. ret == phy_modtype_twinax_long)
  1013. edc_needed = edc_twinax;
  1014. else
  1015. edc_needed = edc_sr;
  1016. if (edc_needed != phy->priv) {
  1017. ret = ael2005_reset(phy, 0);
  1018. return ret ? ret : cphy_cause_module_change;
  1019. }
  1020. cause = cphy_cause_module_change;
  1021. }
  1022. ret = t3_phy_lasi_intr_handler(phy);
  1023. if (ret < 0)
  1024. return ret;
  1025. ret |= cause;
  1026. return ret ? ret : cphy_cause_link_change;
  1027. }
  1028. static struct cphy_ops ael2005_ops = {
  1029. .reset = ael2005_reset,
  1030. .intr_enable = ael2005_intr_enable,
  1031. .intr_disable = ael2005_intr_disable,
  1032. .intr_clear = ael2005_intr_clear,
  1033. .intr_handler = ael2005_intr_handler,
  1034. .get_link_status = get_link_status_r,
  1035. .power_down = ael1002_power_down,
  1036. };
  1037. int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter,
  1038. int phy_addr, const struct mdio_ops *mdio_ops)
  1039. {
  1040. cphy_init(phy, adapter, phy_addr, &ael2005_ops, mdio_ops,
  1041. SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE |
  1042. SUPPORTED_IRQ, "10GBASE-R");
  1043. msleep(125);
  1044. return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL_OPT_SETTINGS, 0,
  1045. 1 << 5);
  1046. }
  1047. /*
  1048. * Get link status for a 10GBASE-X device.
  1049. */
  1050. static int get_link_status_x(struct cphy *phy, int *link_ok, int *speed,
  1051. int *duplex, int *fc)
  1052. {
  1053. if (link_ok) {
  1054. unsigned int stat0, stat1, stat2;
  1055. int err = mdio_read(phy, MDIO_DEV_PMA_PMD, PMD_RSD, &stat0);
  1056. if (!err)
  1057. err = mdio_read(phy, MDIO_DEV_PCS, PCS_STAT1_X, &stat1);
  1058. if (!err)
  1059. err = mdio_read(phy, MDIO_DEV_XGXS, XS_LN_STAT, &stat2);
  1060. if (err)
  1061. return err;
  1062. *link_ok = (stat0 & (stat1 >> 12) & (stat2 >> 12)) & 1;
  1063. }
  1064. if (speed)
  1065. *speed = SPEED_10000;
  1066. if (duplex)
  1067. *duplex = DUPLEX_FULL;
  1068. return 0;
  1069. }
  1070. static struct cphy_ops qt2045_ops = {
  1071. .reset = ael1006_reset,
  1072. .intr_enable = t3_phy_lasi_intr_enable,
  1073. .intr_disable = t3_phy_lasi_intr_disable,
  1074. .intr_clear = t3_phy_lasi_intr_clear,
  1075. .intr_handler = t3_phy_lasi_intr_handler,
  1076. .get_link_status = get_link_status_x,
  1077. .power_down = ael1006_power_down,
  1078. };
  1079. int t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter,
  1080. int phy_addr, const struct mdio_ops *mdio_ops)
  1081. {
  1082. unsigned int stat;
  1083. cphy_init(phy, adapter, phy_addr, &qt2045_ops, mdio_ops,
  1084. SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP,
  1085. "10GBASE-CX4");
  1086. /*
  1087. * Some cards where the PHY is supposed to be at address 0 actually
  1088. * have it at 1.
  1089. */
  1090. if (!phy_addr && !mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMSR, &stat) &&
  1091. stat == 0xffff)
  1092. phy->addr = 1;
  1093. return 0;
  1094. }
  1095. static int xaui_direct_reset(struct cphy *phy, int wait)
  1096. {
  1097. return 0;
  1098. }
  1099. static int xaui_direct_get_link_status(struct cphy *phy, int *link_ok,
  1100. int *speed, int *duplex, int *fc)
  1101. {
  1102. if (link_ok) {
  1103. unsigned int status;
  1104. status = t3_read_reg(phy->adapter,
  1105. XGM_REG(A_XGM_SERDES_STAT0, phy->addr)) |
  1106. t3_read_reg(phy->adapter,
  1107. XGM_REG(A_XGM_SERDES_STAT1, phy->addr)) |
  1108. t3_read_reg(phy->adapter,
  1109. XGM_REG(A_XGM_SERDES_STAT2, phy->addr)) |
  1110. t3_read_reg(phy->adapter,
  1111. XGM_REG(A_XGM_SERDES_STAT3, phy->addr));
  1112. *link_ok = !(status & F_LOWSIG0);
  1113. }
  1114. if (speed)
  1115. *speed = SPEED_10000;
  1116. if (duplex)
  1117. *duplex = DUPLEX_FULL;
  1118. return 0;
  1119. }
  1120. static int xaui_direct_power_down(struct cphy *phy, int enable)
  1121. {
  1122. return 0;
  1123. }
  1124. static struct cphy_ops xaui_direct_ops = {
  1125. .reset = xaui_direct_reset,
  1126. .intr_enable = ael1002_intr_noop,
  1127. .intr_disable = ael1002_intr_noop,
  1128. .intr_clear = ael1002_intr_noop,
  1129. .intr_handler = ael1002_intr_noop,
  1130. .get_link_status = xaui_direct_get_link_status,
  1131. .power_down = xaui_direct_power_down,
  1132. };
  1133. int t3_xaui_direct_phy_prep(struct cphy *phy, struct adapter *adapter,
  1134. int phy_addr, const struct mdio_ops *mdio_ops)
  1135. {
  1136. cphy_init(phy, adapter, phy_addr, &xaui_direct_ops, mdio_ops,
  1137. SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP,
  1138. "10GBASE-CX4");
  1139. return 0;
  1140. }