xgbe-mdio.c 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642
  1. /*
  2. * AMD 10Gb Ethernet driver
  3. *
  4. * This file is available to you under your choice of the following two
  5. * licenses:
  6. *
  7. * License 1: GPLv2
  8. *
  9. * Copyright (c) 2014-2016 Advanced Micro Devices, Inc.
  10. *
  11. * This file is free software; you may copy, redistribute and/or modify
  12. * it under the terms of the GNU General Public License as published by
  13. * the Free Software Foundation, either version 2 of the License, or (at
  14. * your option) any later version.
  15. *
  16. * This file is distributed in the hope that it will be useful, but
  17. * WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  19. * General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  23. *
  24. * This file incorporates work covered by the following copyright and
  25. * permission notice:
  26. * The Synopsys DWC ETHER XGMAC Software Driver and documentation
  27. * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
  28. * Inc. unless otherwise expressly agreed to in writing between Synopsys
  29. * and you.
  30. *
  31. * The Software IS NOT an item of Licensed Software or Licensed Product
  32. * under any End User Software License Agreement or Agreement for Licensed
  33. * Product with Synopsys or any supplement thereto. Permission is hereby
  34. * granted, free of charge, to any person obtaining a copy of this software
  35. * annotated with this license and the Software, to deal in the Software
  36. * without restriction, including without limitation the rights to use,
  37. * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
  38. * of the Software, and to permit persons to whom the Software is furnished
  39. * to do so, subject to the following conditions:
  40. *
  41. * The above copyright notice and this permission notice shall be included
  42. * in all copies or substantial portions of the Software.
  43. *
  44. * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
  45. * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  46. * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  47. * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
  48. * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  49. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  50. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  51. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  52. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  53. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  54. * THE POSSIBILITY OF SUCH DAMAGE.
  55. *
  56. *
  57. * License 2: Modified BSD
  58. *
  59. * Copyright (c) 2014-2016 Advanced Micro Devices, Inc.
  60. * All rights reserved.
  61. *
  62. * Redistribution and use in source and binary forms, with or without
  63. * modification, are permitted provided that the following conditions are met:
  64. * * Redistributions of source code must retain the above copyright
  65. * notice, this list of conditions and the following disclaimer.
  66. * * Redistributions in binary form must reproduce the above copyright
  67. * notice, this list of conditions and the following disclaimer in the
  68. * documentation and/or other materials provided with the distribution.
  69. * * Neither the name of Advanced Micro Devices, Inc. nor the
  70. * names of its contributors may be used to endorse or promote products
  71. * derived from this software without specific prior written permission.
  72. *
  73. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  74. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  75. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  76. * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
  77. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  78. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  79. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  80. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  81. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  82. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  83. *
  84. * This file incorporates work covered by the following copyright and
  85. * permission notice:
  86. * The Synopsys DWC ETHER XGMAC Software Driver and documentation
  87. * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
  88. * Inc. unless otherwise expressly agreed to in writing between Synopsys
  89. * and you.
  90. *
  91. * The Software IS NOT an item of Licensed Software or Licensed Product
  92. * under any End User Software License Agreement or Agreement for Licensed
  93. * Product with Synopsys or any supplement thereto. Permission is hereby
  94. * granted, free of charge, to any person obtaining a copy of this software
  95. * annotated with this license and the Software, to deal in the Software
  96. * without restriction, including without limitation the rights to use,
  97. * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
  98. * of the Software, and to permit persons to whom the Software is furnished
  99. * to do so, subject to the following conditions:
  100. *
  101. * The above copyright notice and this permission notice shall be included
  102. * in all copies or substantial portions of the Software.
  103. *
  104. * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
  105. * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  106. * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  107. * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
  108. * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  109. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  110. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  111. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  112. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  113. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  114. * THE POSSIBILITY OF SUCH DAMAGE.
  115. */
  116. #include <linux/interrupt.h>
  117. #include <linux/module.h>
  118. #include <linux/kmod.h>
  119. #include <linux/mdio.h>
  120. #include <linux/phy.h>
  121. #include <linux/of.h>
  122. #include <linux/bitops.h>
  123. #include <linux/jiffies.h>
  124. #include "xgbe.h"
  125. #include "xgbe-common.h"
  126. static void xgbe_an37_clear_interrupts(struct xgbe_prv_data *pdata)
  127. {
  128. int reg;
  129. reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_STAT);
  130. reg &= ~XGBE_AN_CL37_INT_MASK;
  131. XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_STAT, reg);
  132. }
  133. static void xgbe_an37_disable_interrupts(struct xgbe_prv_data *pdata)
  134. {
  135. int reg;
  136. reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_CTRL);
  137. reg &= ~XGBE_AN_CL37_INT_MASK;
  138. XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_CTRL, reg);
  139. reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_PCS_DIG_CTRL);
  140. reg &= ~XGBE_PCS_CL37_BP;
  141. XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_PCS_DIG_CTRL, reg);
  142. }
  143. static void xgbe_an37_enable_interrupts(struct xgbe_prv_data *pdata)
  144. {
  145. int reg;
  146. reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_PCS_DIG_CTRL);
  147. reg |= XGBE_PCS_CL37_BP;
  148. XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_PCS_DIG_CTRL, reg);
  149. reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_CTRL);
  150. reg |= XGBE_AN_CL37_INT_MASK;
  151. XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_CTRL, reg);
  152. }
  153. static void xgbe_an73_clear_interrupts(struct xgbe_prv_data *pdata)
  154. {
  155. XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, 0);
  156. }
  157. static void xgbe_an73_disable_interrupts(struct xgbe_prv_data *pdata)
  158. {
  159. XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, 0);
  160. }
  161. static void xgbe_an73_enable_interrupts(struct xgbe_prv_data *pdata)
  162. {
  163. XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, XGBE_AN_CL73_INT_MASK);
  164. }
  165. static void xgbe_an_enable_interrupts(struct xgbe_prv_data *pdata)
  166. {
  167. switch (pdata->an_mode) {
  168. case XGBE_AN_MODE_CL73:
  169. case XGBE_AN_MODE_CL73_REDRV:
  170. xgbe_an73_enable_interrupts(pdata);
  171. break;
  172. case XGBE_AN_MODE_CL37:
  173. case XGBE_AN_MODE_CL37_SGMII:
  174. xgbe_an37_enable_interrupts(pdata);
  175. break;
  176. default:
  177. break;
  178. }
  179. }
  180. static void xgbe_an_clear_interrupts_all(struct xgbe_prv_data *pdata)
  181. {
  182. xgbe_an73_clear_interrupts(pdata);
  183. xgbe_an37_clear_interrupts(pdata);
  184. }
  185. static void xgbe_an73_enable_kr_training(struct xgbe_prv_data *pdata)
  186. {
  187. unsigned int reg;
  188. reg = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL);
  189. reg |= XGBE_KR_TRAINING_ENABLE;
  190. XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL, reg);
  191. }
  192. static void xgbe_an73_disable_kr_training(struct xgbe_prv_data *pdata)
  193. {
  194. unsigned int reg;
  195. reg = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL);
  196. reg &= ~XGBE_KR_TRAINING_ENABLE;
  197. XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL, reg);
  198. }
  199. static void xgbe_kr_mode(struct xgbe_prv_data *pdata)
  200. {
  201. /* Enable KR training */
  202. xgbe_an73_enable_kr_training(pdata);
  203. /* Set MAC to 10G speed */
  204. pdata->hw_if.set_speed(pdata, SPEED_10000);
  205. /* Call PHY implementation support to complete rate change */
  206. pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_KR);
  207. }
  208. static void xgbe_kx_2500_mode(struct xgbe_prv_data *pdata)
  209. {
  210. /* Disable KR training */
  211. xgbe_an73_disable_kr_training(pdata);
  212. /* Set MAC to 2.5G speed */
  213. pdata->hw_if.set_speed(pdata, SPEED_2500);
  214. /* Call PHY implementation support to complete rate change */
  215. pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_KX_2500);
  216. }
  217. static void xgbe_kx_1000_mode(struct xgbe_prv_data *pdata)
  218. {
  219. /* Disable KR training */
  220. xgbe_an73_disable_kr_training(pdata);
  221. /* Set MAC to 1G speed */
  222. pdata->hw_if.set_speed(pdata, SPEED_1000);
  223. /* Call PHY implementation support to complete rate change */
  224. pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_KX_1000);
  225. }
  226. static void xgbe_sfi_mode(struct xgbe_prv_data *pdata)
  227. {
  228. /* If a KR re-driver is present, change to KR mode instead */
  229. if (pdata->kr_redrv)
  230. return xgbe_kr_mode(pdata);
  231. /* Disable KR training */
  232. xgbe_an73_disable_kr_training(pdata);
  233. /* Set MAC to 10G speed */
  234. pdata->hw_if.set_speed(pdata, SPEED_10000);
  235. /* Call PHY implementation support to complete rate change */
  236. pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_SFI);
  237. }
  238. static void xgbe_x_mode(struct xgbe_prv_data *pdata)
  239. {
  240. /* Disable KR training */
  241. xgbe_an73_disable_kr_training(pdata);
  242. /* Set MAC to 1G speed */
  243. pdata->hw_if.set_speed(pdata, SPEED_1000);
  244. /* Call PHY implementation support to complete rate change */
  245. pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_X);
  246. }
  247. static void xgbe_sgmii_1000_mode(struct xgbe_prv_data *pdata)
  248. {
  249. /* Disable KR training */
  250. xgbe_an73_disable_kr_training(pdata);
  251. /* Set MAC to 1G speed */
  252. pdata->hw_if.set_speed(pdata, SPEED_1000);
  253. /* Call PHY implementation support to complete rate change */
  254. pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_SGMII_1000);
  255. }
  256. static void xgbe_sgmii_100_mode(struct xgbe_prv_data *pdata)
  257. {
  258. /* Disable KR training */
  259. xgbe_an73_disable_kr_training(pdata);
  260. /* Set MAC to 1G speed */
  261. pdata->hw_if.set_speed(pdata, SPEED_1000);
  262. /* Call PHY implementation support to complete rate change */
  263. pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_SGMII_100);
  264. }
  265. static enum xgbe_mode xgbe_cur_mode(struct xgbe_prv_data *pdata)
  266. {
  267. return pdata->phy_if.phy_impl.cur_mode(pdata);
  268. }
  269. static bool xgbe_in_kr_mode(struct xgbe_prv_data *pdata)
  270. {
  271. return (xgbe_cur_mode(pdata) == XGBE_MODE_KR);
  272. }
  273. static void xgbe_change_mode(struct xgbe_prv_data *pdata,
  274. enum xgbe_mode mode)
  275. {
  276. switch (mode) {
  277. case XGBE_MODE_KX_1000:
  278. xgbe_kx_1000_mode(pdata);
  279. break;
  280. case XGBE_MODE_KX_2500:
  281. xgbe_kx_2500_mode(pdata);
  282. break;
  283. case XGBE_MODE_KR:
  284. xgbe_kr_mode(pdata);
  285. break;
  286. case XGBE_MODE_SGMII_100:
  287. xgbe_sgmii_100_mode(pdata);
  288. break;
  289. case XGBE_MODE_SGMII_1000:
  290. xgbe_sgmii_1000_mode(pdata);
  291. break;
  292. case XGBE_MODE_X:
  293. xgbe_x_mode(pdata);
  294. break;
  295. case XGBE_MODE_SFI:
  296. xgbe_sfi_mode(pdata);
  297. break;
  298. case XGBE_MODE_UNKNOWN:
  299. break;
  300. default:
  301. netif_dbg(pdata, link, pdata->netdev,
  302. "invalid operation mode requested (%u)\n", mode);
  303. }
  304. }
  305. static void xgbe_switch_mode(struct xgbe_prv_data *pdata)
  306. {
  307. xgbe_change_mode(pdata, pdata->phy_if.phy_impl.switch_mode(pdata));
  308. }
  309. static void xgbe_set_mode(struct xgbe_prv_data *pdata,
  310. enum xgbe_mode mode)
  311. {
  312. if (mode == xgbe_cur_mode(pdata))
  313. return;
  314. xgbe_change_mode(pdata, mode);
  315. }
  316. static bool xgbe_use_mode(struct xgbe_prv_data *pdata,
  317. enum xgbe_mode mode)
  318. {
  319. return pdata->phy_if.phy_impl.use_mode(pdata, mode);
  320. }
  321. static void xgbe_an37_set(struct xgbe_prv_data *pdata, bool enable,
  322. bool restart)
  323. {
  324. unsigned int reg;
  325. reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_CTRL1);
  326. reg &= ~MDIO_VEND2_CTRL1_AN_ENABLE;
  327. if (enable)
  328. reg |= MDIO_VEND2_CTRL1_AN_ENABLE;
  329. if (restart)
  330. reg |= MDIO_VEND2_CTRL1_AN_RESTART;
  331. XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_CTRL1, reg);
  332. }
  333. static void xgbe_an37_restart(struct xgbe_prv_data *pdata)
  334. {
  335. xgbe_an37_enable_interrupts(pdata);
  336. xgbe_an37_set(pdata, true, true);
  337. netif_dbg(pdata, link, pdata->netdev, "CL37 AN enabled/restarted\n");
  338. }
  339. static void xgbe_an37_disable(struct xgbe_prv_data *pdata)
  340. {
  341. xgbe_an37_set(pdata, false, false);
  342. xgbe_an37_disable_interrupts(pdata);
  343. netif_dbg(pdata, link, pdata->netdev, "CL37 AN disabled\n");
  344. }
  345. static void xgbe_an73_set(struct xgbe_prv_data *pdata, bool enable,
  346. bool restart)
  347. {
  348. unsigned int reg;
  349. reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_CTRL1);
  350. reg &= ~MDIO_AN_CTRL1_ENABLE;
  351. if (enable)
  352. reg |= MDIO_AN_CTRL1_ENABLE;
  353. if (restart)
  354. reg |= MDIO_AN_CTRL1_RESTART;
  355. XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_CTRL1, reg);
  356. }
  357. static void xgbe_an73_restart(struct xgbe_prv_data *pdata)
  358. {
  359. xgbe_an73_enable_interrupts(pdata);
  360. xgbe_an73_set(pdata, true, true);
  361. netif_dbg(pdata, link, pdata->netdev, "CL73 AN enabled/restarted\n");
  362. }
  363. static void xgbe_an73_disable(struct xgbe_prv_data *pdata)
  364. {
  365. xgbe_an73_set(pdata, false, false);
  366. xgbe_an73_disable_interrupts(pdata);
  367. pdata->an_start = 0;
  368. netif_dbg(pdata, link, pdata->netdev, "CL73 AN disabled\n");
  369. }
  370. static void xgbe_an_restart(struct xgbe_prv_data *pdata)
  371. {
  372. if (pdata->phy_if.phy_impl.an_pre)
  373. pdata->phy_if.phy_impl.an_pre(pdata);
  374. switch (pdata->an_mode) {
  375. case XGBE_AN_MODE_CL73:
  376. case XGBE_AN_MODE_CL73_REDRV:
  377. xgbe_an73_restart(pdata);
  378. break;
  379. case XGBE_AN_MODE_CL37:
  380. case XGBE_AN_MODE_CL37_SGMII:
  381. xgbe_an37_restart(pdata);
  382. break;
  383. default:
  384. break;
  385. }
  386. }
  387. static void xgbe_an_disable(struct xgbe_prv_data *pdata)
  388. {
  389. if (pdata->phy_if.phy_impl.an_post)
  390. pdata->phy_if.phy_impl.an_post(pdata);
  391. switch (pdata->an_mode) {
  392. case XGBE_AN_MODE_CL73:
  393. case XGBE_AN_MODE_CL73_REDRV:
  394. xgbe_an73_disable(pdata);
  395. break;
  396. case XGBE_AN_MODE_CL37:
  397. case XGBE_AN_MODE_CL37_SGMII:
  398. xgbe_an37_disable(pdata);
  399. break;
  400. default:
  401. break;
  402. }
  403. }
  404. static void xgbe_an_disable_all(struct xgbe_prv_data *pdata)
  405. {
  406. xgbe_an73_disable(pdata);
  407. xgbe_an37_disable(pdata);
  408. }
  409. static enum xgbe_an xgbe_an73_tx_training(struct xgbe_prv_data *pdata,
  410. enum xgbe_rx *state)
  411. {
  412. unsigned int ad_reg, lp_reg, reg;
  413. *state = XGBE_RX_COMPLETE;
  414. /* If we're not in KR mode then we're done */
  415. if (!xgbe_in_kr_mode(pdata))
  416. return XGBE_AN_PAGE_RECEIVED;
  417. /* Enable/Disable FEC */
  418. ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2);
  419. lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 2);
  420. reg = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_FECCTRL);
  421. reg &= ~(MDIO_PMA_10GBR_FECABLE_ABLE | MDIO_PMA_10GBR_FECABLE_ERRABLE);
  422. if ((ad_reg & 0xc000) && (lp_reg & 0xc000))
  423. reg |= pdata->fec_ability;
  424. XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_FECCTRL, reg);
  425. /* Start KR training */
  426. reg = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL);
  427. if (reg & XGBE_KR_TRAINING_ENABLE) {
  428. if (pdata->phy_if.phy_impl.kr_training_pre)
  429. pdata->phy_if.phy_impl.kr_training_pre(pdata);
  430. reg |= XGBE_KR_TRAINING_START;
  431. XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL,
  432. reg);
  433. netif_dbg(pdata, link, pdata->netdev,
  434. "KR training initiated\n");
  435. if (pdata->phy_if.phy_impl.kr_training_post)
  436. pdata->phy_if.phy_impl.kr_training_post(pdata);
  437. }
  438. return XGBE_AN_PAGE_RECEIVED;
  439. }
  440. static enum xgbe_an xgbe_an73_tx_xnp(struct xgbe_prv_data *pdata,
  441. enum xgbe_rx *state)
  442. {
  443. u16 msg;
  444. *state = XGBE_RX_XNP;
  445. msg = XGBE_XNP_MCF_NULL_MESSAGE;
  446. msg |= XGBE_XNP_MP_FORMATTED;
  447. XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_XNP + 2, 0);
  448. XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_XNP + 1, 0);
  449. XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_XNP, msg);
  450. return XGBE_AN_PAGE_RECEIVED;
  451. }
  452. static enum xgbe_an xgbe_an73_rx_bpa(struct xgbe_prv_data *pdata,
  453. enum xgbe_rx *state)
  454. {
  455. unsigned int link_support;
  456. unsigned int reg, ad_reg, lp_reg;
  457. /* Read Base Ability register 2 first */
  458. reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 1);
  459. /* Check for a supported mode, otherwise restart in a different one */
  460. link_support = xgbe_in_kr_mode(pdata) ? 0x80 : 0x20;
  461. if (!(reg & link_support))
  462. return XGBE_AN_INCOMPAT_LINK;
  463. /* Check Extended Next Page support */
  464. ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE);
  465. lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA);
  466. return ((ad_reg & XGBE_XNP_NP_EXCHANGE) ||
  467. (lp_reg & XGBE_XNP_NP_EXCHANGE))
  468. ? xgbe_an73_tx_xnp(pdata, state)
  469. : xgbe_an73_tx_training(pdata, state);
  470. }
  471. static enum xgbe_an xgbe_an73_rx_xnp(struct xgbe_prv_data *pdata,
  472. enum xgbe_rx *state)
  473. {
  474. unsigned int ad_reg, lp_reg;
  475. /* Check Extended Next Page support */
  476. ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_XNP);
  477. lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPX);
  478. return ((ad_reg & XGBE_XNP_NP_EXCHANGE) ||
  479. (lp_reg & XGBE_XNP_NP_EXCHANGE))
  480. ? xgbe_an73_tx_xnp(pdata, state)
  481. : xgbe_an73_tx_training(pdata, state);
  482. }
  483. static enum xgbe_an xgbe_an73_page_received(struct xgbe_prv_data *pdata)
  484. {
  485. enum xgbe_rx *state;
  486. unsigned long an_timeout;
  487. enum xgbe_an ret;
  488. if (!pdata->an_start) {
  489. pdata->an_start = jiffies;
  490. } else {
  491. an_timeout = pdata->an_start +
  492. msecs_to_jiffies(XGBE_AN_MS_TIMEOUT);
  493. if (time_after(jiffies, an_timeout)) {
  494. /* Auto-negotiation timed out, reset state */
  495. pdata->kr_state = XGBE_RX_BPA;
  496. pdata->kx_state = XGBE_RX_BPA;
  497. pdata->an_start = jiffies;
  498. netif_dbg(pdata, link, pdata->netdev,
  499. "CL73 AN timed out, resetting state\n");
  500. }
  501. }
  502. state = xgbe_in_kr_mode(pdata) ? &pdata->kr_state
  503. : &pdata->kx_state;
  504. switch (*state) {
  505. case XGBE_RX_BPA:
  506. ret = xgbe_an73_rx_bpa(pdata, state);
  507. break;
  508. case XGBE_RX_XNP:
  509. ret = xgbe_an73_rx_xnp(pdata, state);
  510. break;
  511. default:
  512. ret = XGBE_AN_ERROR;
  513. }
  514. return ret;
  515. }
  516. static enum xgbe_an xgbe_an73_incompat_link(struct xgbe_prv_data *pdata)
  517. {
  518. struct ethtool_link_ksettings *lks = &pdata->phy.lks;
  519. /* Be sure we aren't looping trying to negotiate */
  520. if (xgbe_in_kr_mode(pdata)) {
  521. pdata->kr_state = XGBE_RX_ERROR;
  522. if (!XGBE_ADV(lks, 1000baseKX_Full) &&
  523. !XGBE_ADV(lks, 2500baseX_Full))
  524. return XGBE_AN_NO_LINK;
  525. if (pdata->kx_state != XGBE_RX_BPA)
  526. return XGBE_AN_NO_LINK;
  527. } else {
  528. pdata->kx_state = XGBE_RX_ERROR;
  529. if (!XGBE_ADV(lks, 10000baseKR_Full))
  530. return XGBE_AN_NO_LINK;
  531. if (pdata->kr_state != XGBE_RX_BPA)
  532. return XGBE_AN_NO_LINK;
  533. }
  534. xgbe_an_disable(pdata);
  535. xgbe_switch_mode(pdata);
  536. xgbe_an_restart(pdata);
  537. return XGBE_AN_INCOMPAT_LINK;
  538. }
  539. static void xgbe_an37_isr(struct xgbe_prv_data *pdata)
  540. {
  541. unsigned int reg;
  542. /* Disable AN interrupts */
  543. xgbe_an37_disable_interrupts(pdata);
  544. /* Save the interrupt(s) that fired */
  545. reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_STAT);
  546. pdata->an_int = reg & XGBE_AN_CL37_INT_MASK;
  547. pdata->an_status = reg & ~XGBE_AN_CL37_INT_MASK;
  548. if (pdata->an_int) {
  549. /* Clear the interrupt(s) that fired and process them */
  550. reg &= ~XGBE_AN_CL37_INT_MASK;
  551. XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_STAT, reg);
  552. queue_work(pdata->an_workqueue, &pdata->an_irq_work);
  553. } else {
  554. /* Enable AN interrupts */
  555. xgbe_an37_enable_interrupts(pdata);
  556. /* Reissue interrupt if status is not clear */
  557. if (pdata->vdata->irq_reissue_support)
  558. XP_IOWRITE(pdata, XP_INT_REISSUE_EN, 1 << 3);
  559. }
  560. }
  561. static void xgbe_an73_isr(struct xgbe_prv_data *pdata)
  562. {
  563. /* Disable AN interrupts */
  564. xgbe_an73_disable_interrupts(pdata);
  565. /* Save the interrupt(s) that fired */
  566. pdata->an_int = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_INT);
  567. if (pdata->an_int) {
  568. /* Clear the interrupt(s) that fired and process them */
  569. XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, ~pdata->an_int);
  570. queue_work(pdata->an_workqueue, &pdata->an_irq_work);
  571. } else {
  572. /* Enable AN interrupts */
  573. xgbe_an73_enable_interrupts(pdata);
  574. /* Reissue interrupt if status is not clear */
  575. if (pdata->vdata->irq_reissue_support)
  576. XP_IOWRITE(pdata, XP_INT_REISSUE_EN, 1 << 3);
  577. }
  578. }
  579. static void xgbe_an_isr_task(unsigned long data)
  580. {
  581. struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)data;
  582. netif_dbg(pdata, intr, pdata->netdev, "AN interrupt received\n");
  583. switch (pdata->an_mode) {
  584. case XGBE_AN_MODE_CL73:
  585. case XGBE_AN_MODE_CL73_REDRV:
  586. xgbe_an73_isr(pdata);
  587. break;
  588. case XGBE_AN_MODE_CL37:
  589. case XGBE_AN_MODE_CL37_SGMII:
  590. xgbe_an37_isr(pdata);
  591. break;
  592. default:
  593. break;
  594. }
  595. }
  596. static irqreturn_t xgbe_an_isr(int irq, void *data)
  597. {
  598. struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)data;
  599. if (pdata->isr_as_tasklet)
  600. tasklet_schedule(&pdata->tasklet_an);
  601. else
  602. xgbe_an_isr_task((unsigned long)pdata);
  603. return IRQ_HANDLED;
  604. }
  605. static irqreturn_t xgbe_an_combined_isr(struct xgbe_prv_data *pdata)
  606. {
  607. xgbe_an_isr_task((unsigned long)pdata);
  608. return IRQ_HANDLED;
  609. }
  610. static void xgbe_an_irq_work(struct work_struct *work)
  611. {
  612. struct xgbe_prv_data *pdata = container_of(work,
  613. struct xgbe_prv_data,
  614. an_irq_work);
  615. /* Avoid a race between enabling the IRQ and exiting the work by
  616. * waiting for the work to finish and then queueing it
  617. */
  618. flush_work(&pdata->an_work);
  619. queue_work(pdata->an_workqueue, &pdata->an_work);
  620. }
  621. static const char *xgbe_state_as_string(enum xgbe_an state)
  622. {
  623. switch (state) {
  624. case XGBE_AN_READY:
  625. return "Ready";
  626. case XGBE_AN_PAGE_RECEIVED:
  627. return "Page-Received";
  628. case XGBE_AN_INCOMPAT_LINK:
  629. return "Incompatible-Link";
  630. case XGBE_AN_COMPLETE:
  631. return "Complete";
  632. case XGBE_AN_NO_LINK:
  633. return "No-Link";
  634. case XGBE_AN_ERROR:
  635. return "Error";
  636. default:
  637. return "Undefined";
  638. }
  639. }
  640. static void xgbe_an37_state_machine(struct xgbe_prv_data *pdata)
  641. {
  642. enum xgbe_an cur_state = pdata->an_state;
  643. if (!pdata->an_int)
  644. return;
  645. if (pdata->an_int & XGBE_AN_CL37_INT_CMPLT) {
  646. pdata->an_state = XGBE_AN_COMPLETE;
  647. pdata->an_int &= ~XGBE_AN_CL37_INT_CMPLT;
  648. /* If SGMII is enabled, check the link status */
  649. if ((pdata->an_mode == XGBE_AN_MODE_CL37_SGMII) &&
  650. !(pdata->an_status & XGBE_SGMII_AN_LINK_STATUS))
  651. pdata->an_state = XGBE_AN_NO_LINK;
  652. }
  653. netif_dbg(pdata, link, pdata->netdev, "CL37 AN %s\n",
  654. xgbe_state_as_string(pdata->an_state));
  655. cur_state = pdata->an_state;
  656. switch (pdata->an_state) {
  657. case XGBE_AN_READY:
  658. break;
  659. case XGBE_AN_COMPLETE:
  660. netif_dbg(pdata, link, pdata->netdev,
  661. "Auto negotiation successful\n");
  662. break;
  663. case XGBE_AN_NO_LINK:
  664. break;
  665. default:
  666. pdata->an_state = XGBE_AN_ERROR;
  667. }
  668. if (pdata->an_state == XGBE_AN_ERROR) {
  669. netdev_err(pdata->netdev,
  670. "error during auto-negotiation, state=%u\n",
  671. cur_state);
  672. pdata->an_int = 0;
  673. xgbe_an37_clear_interrupts(pdata);
  674. }
  675. if (pdata->an_state >= XGBE_AN_COMPLETE) {
  676. pdata->an_result = pdata->an_state;
  677. pdata->an_state = XGBE_AN_READY;
  678. if (pdata->phy_if.phy_impl.an_post)
  679. pdata->phy_if.phy_impl.an_post(pdata);
  680. netif_dbg(pdata, link, pdata->netdev, "CL37 AN result: %s\n",
  681. xgbe_state_as_string(pdata->an_result));
  682. }
  683. xgbe_an37_enable_interrupts(pdata);
  684. }
  685. static void xgbe_an73_state_machine(struct xgbe_prv_data *pdata)
  686. {
  687. enum xgbe_an cur_state = pdata->an_state;
  688. if (!pdata->an_int)
  689. return;
  690. next_int:
  691. if (pdata->an_int & XGBE_AN_CL73_PG_RCV) {
  692. pdata->an_state = XGBE_AN_PAGE_RECEIVED;
  693. pdata->an_int &= ~XGBE_AN_CL73_PG_RCV;
  694. } else if (pdata->an_int & XGBE_AN_CL73_INC_LINK) {
  695. pdata->an_state = XGBE_AN_INCOMPAT_LINK;
  696. pdata->an_int &= ~XGBE_AN_CL73_INC_LINK;
  697. } else if (pdata->an_int & XGBE_AN_CL73_INT_CMPLT) {
  698. pdata->an_state = XGBE_AN_COMPLETE;
  699. pdata->an_int &= ~XGBE_AN_CL73_INT_CMPLT;
  700. } else {
  701. pdata->an_state = XGBE_AN_ERROR;
  702. }
  703. again:
  704. netif_dbg(pdata, link, pdata->netdev, "CL73 AN %s\n",
  705. xgbe_state_as_string(pdata->an_state));
  706. cur_state = pdata->an_state;
  707. switch (pdata->an_state) {
  708. case XGBE_AN_READY:
  709. pdata->an_supported = 0;
  710. break;
  711. case XGBE_AN_PAGE_RECEIVED:
  712. pdata->an_state = xgbe_an73_page_received(pdata);
  713. pdata->an_supported++;
  714. break;
  715. case XGBE_AN_INCOMPAT_LINK:
  716. pdata->an_supported = 0;
  717. pdata->parallel_detect = 0;
  718. pdata->an_state = xgbe_an73_incompat_link(pdata);
  719. break;
  720. case XGBE_AN_COMPLETE:
  721. pdata->parallel_detect = pdata->an_supported ? 0 : 1;
  722. netif_dbg(pdata, link, pdata->netdev, "%s successful\n",
  723. pdata->an_supported ? "Auto negotiation"
  724. : "Parallel detection");
  725. break;
  726. case XGBE_AN_NO_LINK:
  727. break;
  728. default:
  729. pdata->an_state = XGBE_AN_ERROR;
  730. }
  731. if (pdata->an_state == XGBE_AN_NO_LINK) {
  732. pdata->an_int = 0;
  733. xgbe_an73_clear_interrupts(pdata);
  734. } else if (pdata->an_state == XGBE_AN_ERROR) {
  735. netdev_err(pdata->netdev,
  736. "error during auto-negotiation, state=%u\n",
  737. cur_state);
  738. pdata->an_int = 0;
  739. xgbe_an73_clear_interrupts(pdata);
  740. }
  741. if (pdata->an_state >= XGBE_AN_COMPLETE) {
  742. pdata->an_result = pdata->an_state;
  743. pdata->an_state = XGBE_AN_READY;
  744. pdata->kr_state = XGBE_RX_BPA;
  745. pdata->kx_state = XGBE_RX_BPA;
  746. pdata->an_start = 0;
  747. if (pdata->phy_if.phy_impl.an_post)
  748. pdata->phy_if.phy_impl.an_post(pdata);
  749. netif_dbg(pdata, link, pdata->netdev, "CL73 AN result: %s\n",
  750. xgbe_state_as_string(pdata->an_result));
  751. }
  752. if (cur_state != pdata->an_state)
  753. goto again;
  754. if (pdata->an_int)
  755. goto next_int;
  756. xgbe_an73_enable_interrupts(pdata);
  757. }
  758. static void xgbe_an_state_machine(struct work_struct *work)
  759. {
  760. struct xgbe_prv_data *pdata = container_of(work,
  761. struct xgbe_prv_data,
  762. an_work);
  763. mutex_lock(&pdata->an_mutex);
  764. switch (pdata->an_mode) {
  765. case XGBE_AN_MODE_CL73:
  766. case XGBE_AN_MODE_CL73_REDRV:
  767. xgbe_an73_state_machine(pdata);
  768. break;
  769. case XGBE_AN_MODE_CL37:
  770. case XGBE_AN_MODE_CL37_SGMII:
  771. xgbe_an37_state_machine(pdata);
  772. break;
  773. default:
  774. break;
  775. }
  776. /* Reissue interrupt if status is not clear */
  777. if (pdata->vdata->irq_reissue_support)
  778. XP_IOWRITE(pdata, XP_INT_REISSUE_EN, 1 << 3);
  779. mutex_unlock(&pdata->an_mutex);
  780. }
  781. static void xgbe_an37_init(struct xgbe_prv_data *pdata)
  782. {
  783. struct ethtool_link_ksettings lks;
  784. unsigned int reg;
  785. pdata->phy_if.phy_impl.an_advertising(pdata, &lks);
  786. /* Set up Advertisement register */
  787. reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_ADVERTISE);
  788. if (XGBE_ADV(&lks, Pause))
  789. reg |= 0x100;
  790. else
  791. reg &= ~0x100;
  792. if (XGBE_ADV(&lks, Asym_Pause))
  793. reg |= 0x80;
  794. else
  795. reg &= ~0x80;
  796. /* Full duplex, but not half */
  797. reg |= XGBE_AN_CL37_FD_MASK;
  798. reg &= ~XGBE_AN_CL37_HD_MASK;
  799. XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_ADVERTISE, reg);
  800. /* Set up the Control register */
  801. reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_CTRL);
  802. reg &= ~XGBE_AN_CL37_TX_CONFIG_MASK;
  803. reg &= ~XGBE_AN_CL37_PCS_MODE_MASK;
  804. switch (pdata->an_mode) {
  805. case XGBE_AN_MODE_CL37:
  806. reg |= XGBE_AN_CL37_PCS_MODE_BASEX;
  807. break;
  808. case XGBE_AN_MODE_CL37_SGMII:
  809. reg |= XGBE_AN_CL37_PCS_MODE_SGMII;
  810. break;
  811. default:
  812. break;
  813. }
  814. reg |= XGBE_AN_CL37_MII_CTRL_8BIT;
  815. XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_CTRL, reg);
  816. netif_dbg(pdata, link, pdata->netdev, "CL37 AN (%s) initialized\n",
  817. (pdata->an_mode == XGBE_AN_MODE_CL37) ? "BaseX" : "SGMII");
  818. }
  819. static void xgbe_an73_init(struct xgbe_prv_data *pdata)
  820. {
  821. struct ethtool_link_ksettings lks;
  822. unsigned int reg;
  823. pdata->phy_if.phy_impl.an_advertising(pdata, &lks);
  824. /* Set up Advertisement register 3 first */
  825. reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2);
  826. if (XGBE_ADV(&lks, 10000baseR_FEC))
  827. reg |= 0xc000;
  828. else
  829. reg &= ~0xc000;
  830. XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2, reg);
  831. /* Set up Advertisement register 2 next */
  832. reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1);
  833. if (XGBE_ADV(&lks, 10000baseKR_Full))
  834. reg |= 0x80;
  835. else
  836. reg &= ~0x80;
  837. if (XGBE_ADV(&lks, 1000baseKX_Full) ||
  838. XGBE_ADV(&lks, 2500baseX_Full))
  839. reg |= 0x20;
  840. else
  841. reg &= ~0x20;
  842. XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1, reg);
  843. /* Set up Advertisement register 1 last */
  844. reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE);
  845. if (XGBE_ADV(&lks, Pause))
  846. reg |= 0x400;
  847. else
  848. reg &= ~0x400;
  849. if (XGBE_ADV(&lks, Asym_Pause))
  850. reg |= 0x800;
  851. else
  852. reg &= ~0x800;
  853. /* We don't intend to perform XNP */
  854. reg &= ~XGBE_XNP_NP_EXCHANGE;
  855. XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE, reg);
  856. netif_dbg(pdata, link, pdata->netdev, "CL73 AN initialized\n");
  857. }
  858. static void xgbe_an_init(struct xgbe_prv_data *pdata)
  859. {
  860. /* Set up advertisement registers based on current settings */
  861. pdata->an_mode = pdata->phy_if.phy_impl.an_mode(pdata);
  862. switch (pdata->an_mode) {
  863. case XGBE_AN_MODE_CL73:
  864. case XGBE_AN_MODE_CL73_REDRV:
  865. xgbe_an73_init(pdata);
  866. break;
  867. case XGBE_AN_MODE_CL37:
  868. case XGBE_AN_MODE_CL37_SGMII:
  869. xgbe_an37_init(pdata);
  870. break;
  871. default:
  872. break;
  873. }
  874. }
  875. static const char *xgbe_phy_fc_string(struct xgbe_prv_data *pdata)
  876. {
  877. if (pdata->tx_pause && pdata->rx_pause)
  878. return "rx/tx";
  879. else if (pdata->rx_pause)
  880. return "rx";
  881. else if (pdata->tx_pause)
  882. return "tx";
  883. else
  884. return "off";
  885. }
  886. static const char *xgbe_phy_speed_string(int speed)
  887. {
  888. switch (speed) {
  889. case SPEED_100:
  890. return "100Mbps";
  891. case SPEED_1000:
  892. return "1Gbps";
  893. case SPEED_2500:
  894. return "2.5Gbps";
  895. case SPEED_10000:
  896. return "10Gbps";
  897. case SPEED_UNKNOWN:
  898. return "Unknown";
  899. default:
  900. return "Unsupported";
  901. }
  902. }
  903. static void xgbe_phy_print_status(struct xgbe_prv_data *pdata)
  904. {
  905. if (pdata->phy.link)
  906. netdev_info(pdata->netdev,
  907. "Link is Up - %s/%s - flow control %s\n",
  908. xgbe_phy_speed_string(pdata->phy.speed),
  909. pdata->phy.duplex == DUPLEX_FULL ? "Full" : "Half",
  910. xgbe_phy_fc_string(pdata));
  911. else
  912. netdev_info(pdata->netdev, "Link is Down\n");
  913. }
  914. static void xgbe_phy_adjust_link(struct xgbe_prv_data *pdata)
  915. {
  916. int new_state = 0;
  917. if (pdata->phy.link) {
  918. /* Flow control support */
  919. pdata->pause_autoneg = pdata->phy.pause_autoneg;
  920. if (pdata->tx_pause != pdata->phy.tx_pause) {
  921. new_state = 1;
  922. pdata->hw_if.config_tx_flow_control(pdata);
  923. pdata->tx_pause = pdata->phy.tx_pause;
  924. }
  925. if (pdata->rx_pause != pdata->phy.rx_pause) {
  926. new_state = 1;
  927. pdata->hw_if.config_rx_flow_control(pdata);
  928. pdata->rx_pause = pdata->phy.rx_pause;
  929. }
  930. /* Speed support */
  931. if (pdata->phy_speed != pdata->phy.speed) {
  932. new_state = 1;
  933. pdata->phy_speed = pdata->phy.speed;
  934. }
  935. if (pdata->phy_link != pdata->phy.link) {
  936. new_state = 1;
  937. pdata->phy_link = pdata->phy.link;
  938. }
  939. } else if (pdata->phy_link) {
  940. new_state = 1;
  941. pdata->phy_link = 0;
  942. pdata->phy_speed = SPEED_UNKNOWN;
  943. }
  944. if (new_state && netif_msg_link(pdata))
  945. xgbe_phy_print_status(pdata);
  946. }
  947. static bool xgbe_phy_valid_speed(struct xgbe_prv_data *pdata, int speed)
  948. {
  949. return pdata->phy_if.phy_impl.valid_speed(pdata, speed);
  950. }
  951. static int xgbe_phy_config_fixed(struct xgbe_prv_data *pdata)
  952. {
  953. enum xgbe_mode mode;
  954. netif_dbg(pdata, link, pdata->netdev, "fixed PHY configuration\n");
  955. /* Disable auto-negotiation */
  956. xgbe_an_disable(pdata);
  957. /* Set specified mode for specified speed */
  958. mode = pdata->phy_if.phy_impl.get_mode(pdata, pdata->phy.speed);
  959. switch (mode) {
  960. case XGBE_MODE_KX_1000:
  961. case XGBE_MODE_KX_2500:
  962. case XGBE_MODE_KR:
  963. case XGBE_MODE_SGMII_100:
  964. case XGBE_MODE_SGMII_1000:
  965. case XGBE_MODE_X:
  966. case XGBE_MODE_SFI:
  967. break;
  968. case XGBE_MODE_UNKNOWN:
  969. default:
  970. return -EINVAL;
  971. }
  972. /* Validate duplex mode */
  973. if (pdata->phy.duplex != DUPLEX_FULL)
  974. return -EINVAL;
  975. xgbe_set_mode(pdata, mode);
  976. return 0;
  977. }
  978. static int __xgbe_phy_config_aneg(struct xgbe_prv_data *pdata)
  979. {
  980. int ret;
  981. set_bit(XGBE_LINK_INIT, &pdata->dev_state);
  982. pdata->link_check = jiffies;
  983. ret = pdata->phy_if.phy_impl.an_config(pdata);
  984. if (ret)
  985. return ret;
  986. if (pdata->phy.autoneg != AUTONEG_ENABLE) {
  987. ret = xgbe_phy_config_fixed(pdata);
  988. if (ret || !pdata->kr_redrv)
  989. return ret;
  990. netif_dbg(pdata, link, pdata->netdev, "AN redriver support\n");
  991. } else {
  992. netif_dbg(pdata, link, pdata->netdev, "AN PHY configuration\n");
  993. }
  994. /* Disable auto-negotiation interrupt */
  995. disable_irq(pdata->an_irq);
  996. /* Start auto-negotiation in a supported mode */
  997. if (xgbe_use_mode(pdata, XGBE_MODE_KR)) {
  998. xgbe_set_mode(pdata, XGBE_MODE_KR);
  999. } else if (xgbe_use_mode(pdata, XGBE_MODE_KX_2500)) {
  1000. xgbe_set_mode(pdata, XGBE_MODE_KX_2500);
  1001. } else if (xgbe_use_mode(pdata, XGBE_MODE_KX_1000)) {
  1002. xgbe_set_mode(pdata, XGBE_MODE_KX_1000);
  1003. } else if (xgbe_use_mode(pdata, XGBE_MODE_SFI)) {
  1004. xgbe_set_mode(pdata, XGBE_MODE_SFI);
  1005. } else if (xgbe_use_mode(pdata, XGBE_MODE_X)) {
  1006. xgbe_set_mode(pdata, XGBE_MODE_X);
  1007. } else if (xgbe_use_mode(pdata, XGBE_MODE_SGMII_1000)) {
  1008. xgbe_set_mode(pdata, XGBE_MODE_SGMII_1000);
  1009. } else if (xgbe_use_mode(pdata, XGBE_MODE_SGMII_100)) {
  1010. xgbe_set_mode(pdata, XGBE_MODE_SGMII_100);
  1011. } else {
  1012. enable_irq(pdata->an_irq);
  1013. return -EINVAL;
  1014. }
  1015. /* Disable and stop any in progress auto-negotiation */
  1016. xgbe_an_disable_all(pdata);
  1017. /* Clear any auto-negotitation interrupts */
  1018. xgbe_an_clear_interrupts_all(pdata);
  1019. pdata->an_result = XGBE_AN_READY;
  1020. pdata->an_state = XGBE_AN_READY;
  1021. pdata->kr_state = XGBE_RX_BPA;
  1022. pdata->kx_state = XGBE_RX_BPA;
  1023. /* Re-enable auto-negotiation interrupt */
  1024. enable_irq(pdata->an_irq);
  1025. xgbe_an_init(pdata);
  1026. xgbe_an_restart(pdata);
  1027. return 0;
  1028. }
  1029. static int xgbe_phy_config_aneg(struct xgbe_prv_data *pdata)
  1030. {
  1031. int ret;
  1032. mutex_lock(&pdata->an_mutex);
  1033. ret = __xgbe_phy_config_aneg(pdata);
  1034. if (ret)
  1035. set_bit(XGBE_LINK_ERR, &pdata->dev_state);
  1036. else
  1037. clear_bit(XGBE_LINK_ERR, &pdata->dev_state);
  1038. mutex_unlock(&pdata->an_mutex);
  1039. return ret;
  1040. }
  1041. static bool xgbe_phy_aneg_done(struct xgbe_prv_data *pdata)
  1042. {
  1043. return (pdata->an_result == XGBE_AN_COMPLETE);
  1044. }
  1045. static void xgbe_check_link_timeout(struct xgbe_prv_data *pdata)
  1046. {
  1047. unsigned long link_timeout;
  1048. link_timeout = pdata->link_check + (XGBE_LINK_TIMEOUT * HZ);
  1049. if (time_after(jiffies, link_timeout)) {
  1050. netif_dbg(pdata, link, pdata->netdev, "AN link timeout\n");
  1051. xgbe_phy_config_aneg(pdata);
  1052. }
  1053. }
  1054. static enum xgbe_mode xgbe_phy_status_aneg(struct xgbe_prv_data *pdata)
  1055. {
  1056. return pdata->phy_if.phy_impl.an_outcome(pdata);
  1057. }
  1058. static void xgbe_phy_status_result(struct xgbe_prv_data *pdata)
  1059. {
  1060. struct ethtool_link_ksettings *lks = &pdata->phy.lks;
  1061. enum xgbe_mode mode;
  1062. XGBE_ZERO_LP_ADV(lks);
  1063. if ((pdata->phy.autoneg != AUTONEG_ENABLE) || pdata->parallel_detect)
  1064. mode = xgbe_cur_mode(pdata);
  1065. else
  1066. mode = xgbe_phy_status_aneg(pdata);
  1067. switch (mode) {
  1068. case XGBE_MODE_SGMII_100:
  1069. pdata->phy.speed = SPEED_100;
  1070. break;
  1071. case XGBE_MODE_X:
  1072. case XGBE_MODE_KX_1000:
  1073. case XGBE_MODE_SGMII_1000:
  1074. pdata->phy.speed = SPEED_1000;
  1075. break;
  1076. case XGBE_MODE_KX_2500:
  1077. pdata->phy.speed = SPEED_2500;
  1078. break;
  1079. case XGBE_MODE_KR:
  1080. case XGBE_MODE_SFI:
  1081. pdata->phy.speed = SPEED_10000;
  1082. break;
  1083. case XGBE_MODE_UNKNOWN:
  1084. default:
  1085. pdata->phy.speed = SPEED_UNKNOWN;
  1086. }
  1087. pdata->phy.duplex = DUPLEX_FULL;
  1088. xgbe_set_mode(pdata, mode);
  1089. }
  1090. static void xgbe_phy_status(struct xgbe_prv_data *pdata)
  1091. {
  1092. unsigned int link_aneg;
  1093. int an_restart;
  1094. if (test_bit(XGBE_LINK_ERR, &pdata->dev_state)) {
  1095. netif_carrier_off(pdata->netdev);
  1096. pdata->phy.link = 0;
  1097. goto adjust_link;
  1098. }
  1099. link_aneg = (pdata->phy.autoneg == AUTONEG_ENABLE);
  1100. pdata->phy.link = pdata->phy_if.phy_impl.link_status(pdata,
  1101. &an_restart);
  1102. if (an_restart) {
  1103. xgbe_phy_config_aneg(pdata);
  1104. return;
  1105. }
  1106. if (pdata->phy.link) {
  1107. if (link_aneg && !xgbe_phy_aneg_done(pdata)) {
  1108. xgbe_check_link_timeout(pdata);
  1109. return;
  1110. }
  1111. xgbe_phy_status_result(pdata);
  1112. if (test_bit(XGBE_LINK_INIT, &pdata->dev_state))
  1113. clear_bit(XGBE_LINK_INIT, &pdata->dev_state);
  1114. netif_carrier_on(pdata->netdev);
  1115. } else {
  1116. if (test_bit(XGBE_LINK_INIT, &pdata->dev_state)) {
  1117. xgbe_check_link_timeout(pdata);
  1118. if (link_aneg)
  1119. return;
  1120. }
  1121. xgbe_phy_status_result(pdata);
  1122. netif_carrier_off(pdata->netdev);
  1123. }
  1124. adjust_link:
  1125. xgbe_phy_adjust_link(pdata);
  1126. }
  1127. static void xgbe_phy_stop(struct xgbe_prv_data *pdata)
  1128. {
  1129. netif_dbg(pdata, link, pdata->netdev, "stopping PHY\n");
  1130. if (!pdata->phy_started)
  1131. return;
  1132. /* Indicate the PHY is down */
  1133. pdata->phy_started = 0;
  1134. /* Disable auto-negotiation */
  1135. xgbe_an_disable_all(pdata);
  1136. if (pdata->dev_irq != pdata->an_irq)
  1137. devm_free_irq(pdata->dev, pdata->an_irq, pdata);
  1138. pdata->phy_if.phy_impl.stop(pdata);
  1139. pdata->phy.link = 0;
  1140. netif_carrier_off(pdata->netdev);
  1141. xgbe_phy_adjust_link(pdata);
  1142. }
  1143. static int xgbe_phy_start(struct xgbe_prv_data *pdata)
  1144. {
  1145. struct net_device *netdev = pdata->netdev;
  1146. int ret;
  1147. netif_dbg(pdata, link, pdata->netdev, "starting PHY\n");
  1148. ret = pdata->phy_if.phy_impl.start(pdata);
  1149. if (ret)
  1150. return ret;
  1151. /* If we have a separate AN irq, enable it */
  1152. if (pdata->dev_irq != pdata->an_irq) {
  1153. tasklet_init(&pdata->tasklet_an, xgbe_an_isr_task,
  1154. (unsigned long)pdata);
  1155. ret = devm_request_irq(pdata->dev, pdata->an_irq,
  1156. xgbe_an_isr, 0, pdata->an_name,
  1157. pdata);
  1158. if (ret) {
  1159. netdev_err(netdev, "phy irq request failed\n");
  1160. goto err_stop;
  1161. }
  1162. }
  1163. /* Set initial mode - call the mode setting routines
  1164. * directly to insure we are properly configured
  1165. */
  1166. if (xgbe_use_mode(pdata, XGBE_MODE_KR)) {
  1167. xgbe_kr_mode(pdata);
  1168. } else if (xgbe_use_mode(pdata, XGBE_MODE_KX_2500)) {
  1169. xgbe_kx_2500_mode(pdata);
  1170. } else if (xgbe_use_mode(pdata, XGBE_MODE_KX_1000)) {
  1171. xgbe_kx_1000_mode(pdata);
  1172. } else if (xgbe_use_mode(pdata, XGBE_MODE_SFI)) {
  1173. xgbe_sfi_mode(pdata);
  1174. } else if (xgbe_use_mode(pdata, XGBE_MODE_X)) {
  1175. xgbe_x_mode(pdata);
  1176. } else if (xgbe_use_mode(pdata, XGBE_MODE_SGMII_1000)) {
  1177. xgbe_sgmii_1000_mode(pdata);
  1178. } else if (xgbe_use_mode(pdata, XGBE_MODE_SGMII_100)) {
  1179. xgbe_sgmii_100_mode(pdata);
  1180. } else {
  1181. ret = -EINVAL;
  1182. goto err_irq;
  1183. }
  1184. /* Indicate the PHY is up and running */
  1185. pdata->phy_started = 1;
  1186. xgbe_an_init(pdata);
  1187. xgbe_an_enable_interrupts(pdata);
  1188. return xgbe_phy_config_aneg(pdata);
  1189. err_irq:
  1190. if (pdata->dev_irq != pdata->an_irq)
  1191. devm_free_irq(pdata->dev, pdata->an_irq, pdata);
  1192. err_stop:
  1193. pdata->phy_if.phy_impl.stop(pdata);
  1194. return ret;
  1195. }
  1196. static int xgbe_phy_reset(struct xgbe_prv_data *pdata)
  1197. {
  1198. int ret;
  1199. ret = pdata->phy_if.phy_impl.reset(pdata);
  1200. if (ret)
  1201. return ret;
  1202. /* Disable auto-negotiation for now */
  1203. xgbe_an_disable_all(pdata);
  1204. /* Clear auto-negotiation interrupts */
  1205. xgbe_an_clear_interrupts_all(pdata);
  1206. return 0;
  1207. }
  1208. static void xgbe_dump_phy_registers(struct xgbe_prv_data *pdata)
  1209. {
  1210. struct device *dev = pdata->dev;
  1211. dev_dbg(dev, "\n************* PHY Reg dump **********************\n");
  1212. dev_dbg(dev, "PCS Control Reg (%#06x) = %#06x\n", MDIO_CTRL1,
  1213. XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1));
  1214. dev_dbg(dev, "PCS Status Reg (%#06x) = %#06x\n", MDIO_STAT1,
  1215. XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1));
  1216. dev_dbg(dev, "Phy Id (PHYS ID 1 %#06x)= %#06x\n", MDIO_DEVID1,
  1217. XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_DEVID1));
  1218. dev_dbg(dev, "Phy Id (PHYS ID 2 %#06x)= %#06x\n", MDIO_DEVID2,
  1219. XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_DEVID2));
  1220. dev_dbg(dev, "Devices in Package (%#06x)= %#06x\n", MDIO_DEVS1,
  1221. XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_DEVS1));
  1222. dev_dbg(dev, "Devices in Package (%#06x)= %#06x\n", MDIO_DEVS2,
  1223. XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_DEVS2));
  1224. dev_dbg(dev, "Auto-Neg Control Reg (%#06x) = %#06x\n", MDIO_CTRL1,
  1225. XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_CTRL1));
  1226. dev_dbg(dev, "Auto-Neg Status Reg (%#06x) = %#06x\n", MDIO_STAT1,
  1227. XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_STAT1));
  1228. dev_dbg(dev, "Auto-Neg Ad Reg 1 (%#06x) = %#06x\n",
  1229. MDIO_AN_ADVERTISE,
  1230. XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE));
  1231. dev_dbg(dev, "Auto-Neg Ad Reg 2 (%#06x) = %#06x\n",
  1232. MDIO_AN_ADVERTISE + 1,
  1233. XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1));
  1234. dev_dbg(dev, "Auto-Neg Ad Reg 3 (%#06x) = %#06x\n",
  1235. MDIO_AN_ADVERTISE + 2,
  1236. XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2));
  1237. dev_dbg(dev, "Auto-Neg Completion Reg (%#06x) = %#06x\n",
  1238. MDIO_AN_COMP_STAT,
  1239. XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_COMP_STAT));
  1240. dev_dbg(dev, "\n*************************************************\n");
  1241. }
  1242. static int xgbe_phy_best_advertised_speed(struct xgbe_prv_data *pdata)
  1243. {
  1244. struct ethtool_link_ksettings *lks = &pdata->phy.lks;
  1245. if (XGBE_ADV(lks, 10000baseKR_Full))
  1246. return SPEED_10000;
  1247. else if (XGBE_ADV(lks, 10000baseT_Full))
  1248. return SPEED_10000;
  1249. else if (XGBE_ADV(lks, 2500baseX_Full))
  1250. return SPEED_2500;
  1251. else if (XGBE_ADV(lks, 2500baseT_Full))
  1252. return SPEED_2500;
  1253. else if (XGBE_ADV(lks, 1000baseKX_Full))
  1254. return SPEED_1000;
  1255. else if (XGBE_ADV(lks, 1000baseT_Full))
  1256. return SPEED_1000;
  1257. else if (XGBE_ADV(lks, 100baseT_Full))
  1258. return SPEED_100;
  1259. return SPEED_UNKNOWN;
  1260. }
  1261. static void xgbe_phy_exit(struct xgbe_prv_data *pdata)
  1262. {
  1263. pdata->phy_if.phy_impl.exit(pdata);
  1264. }
  1265. static int xgbe_phy_init(struct xgbe_prv_data *pdata)
  1266. {
  1267. struct ethtool_link_ksettings *lks = &pdata->phy.lks;
  1268. int ret;
  1269. mutex_init(&pdata->an_mutex);
  1270. INIT_WORK(&pdata->an_irq_work, xgbe_an_irq_work);
  1271. INIT_WORK(&pdata->an_work, xgbe_an_state_machine);
  1272. pdata->mdio_mmd = MDIO_MMD_PCS;
  1273. /* Check for FEC support */
  1274. pdata->fec_ability = XMDIO_READ(pdata, MDIO_MMD_PMAPMD,
  1275. MDIO_PMA_10GBR_FECABLE);
  1276. pdata->fec_ability &= (MDIO_PMA_10GBR_FECABLE_ABLE |
  1277. MDIO_PMA_10GBR_FECABLE_ERRABLE);
  1278. /* Setup the phy (including supported features) */
  1279. ret = pdata->phy_if.phy_impl.init(pdata);
  1280. if (ret)
  1281. return ret;
  1282. /* Copy supported link modes to advertising link modes */
  1283. XGBE_LM_COPY(lks, advertising, lks, supported);
  1284. pdata->phy.address = 0;
  1285. if (XGBE_ADV(lks, Autoneg)) {
  1286. pdata->phy.autoneg = AUTONEG_ENABLE;
  1287. pdata->phy.speed = SPEED_UNKNOWN;
  1288. pdata->phy.duplex = DUPLEX_UNKNOWN;
  1289. } else {
  1290. pdata->phy.autoneg = AUTONEG_DISABLE;
  1291. pdata->phy.speed = xgbe_phy_best_advertised_speed(pdata);
  1292. pdata->phy.duplex = DUPLEX_FULL;
  1293. }
  1294. pdata->phy.link = 0;
  1295. pdata->phy.pause_autoneg = pdata->pause_autoneg;
  1296. pdata->phy.tx_pause = pdata->tx_pause;
  1297. pdata->phy.rx_pause = pdata->rx_pause;
  1298. /* Fix up Flow Control advertising */
  1299. XGBE_CLR_ADV(lks, Pause);
  1300. XGBE_CLR_ADV(lks, Asym_Pause);
  1301. if (pdata->rx_pause) {
  1302. XGBE_SET_ADV(lks, Pause);
  1303. XGBE_SET_ADV(lks, Asym_Pause);
  1304. }
  1305. if (pdata->tx_pause) {
  1306. /* Equivalent to XOR of Asym_Pause */
  1307. if (XGBE_ADV(lks, Asym_Pause))
  1308. XGBE_CLR_ADV(lks, Asym_Pause);
  1309. else
  1310. XGBE_SET_ADV(lks, Asym_Pause);
  1311. }
  1312. if (netif_msg_drv(pdata))
  1313. xgbe_dump_phy_registers(pdata);
  1314. return 0;
  1315. }
  1316. void xgbe_init_function_ptrs_phy(struct xgbe_phy_if *phy_if)
  1317. {
  1318. phy_if->phy_init = xgbe_phy_init;
  1319. phy_if->phy_exit = xgbe_phy_exit;
  1320. phy_if->phy_reset = xgbe_phy_reset;
  1321. phy_if->phy_start = xgbe_phy_start;
  1322. phy_if->phy_stop = xgbe_phy_stop;
  1323. phy_if->phy_status = xgbe_phy_status;
  1324. phy_if->phy_config_aneg = xgbe_phy_config_aneg;
  1325. phy_if->phy_valid_speed = xgbe_phy_valid_speed;
  1326. phy_if->an_isr = xgbe_an_combined_isr;
  1327. }