hns_mdio.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586
  1. /*
  2. * Copyright (c) 2014-2015 Hisilicon Limited.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. */
  9. #include <linux/acpi.h>
  10. #include <linux/errno.h>
  11. #include <linux/etherdevice.h>
  12. #include <linux/init.h>
  13. #include <linux/kernel.h>
  14. #include <linux/mfd/syscon.h>
  15. #include <linux/module.h>
  16. #include <linux/mutex.h>
  17. #include <linux/netdevice.h>
  18. #include <linux/of_address.h>
  19. #include <linux/of.h>
  20. #include <linux/of_mdio.h>
  21. #include <linux/of_platform.h>
  22. #include <linux/phy.h>
  23. #include <linux/platform_device.h>
  24. #include <linux/regmap.h>
  25. #define MDIO_DRV_NAME "Hi-HNS_MDIO"
  26. #define MDIO_BUS_NAME "Hisilicon MII Bus"
  27. #define MDIO_TIMEOUT 1000000
  28. struct hns_mdio_sc_reg {
  29. u16 mdio_clk_en;
  30. u16 mdio_clk_dis;
  31. u16 mdio_reset_req;
  32. u16 mdio_reset_dreq;
  33. u16 mdio_clk_st;
  34. u16 mdio_reset_st;
  35. };
  36. struct hns_mdio_device {
  37. void *vbase; /* mdio reg base address */
  38. struct regmap *subctrl_vbase;
  39. struct hns_mdio_sc_reg sc_reg;
  40. };
  41. /* mdio reg */
  42. #define MDIO_COMMAND_REG 0x0
  43. #define MDIO_ADDR_REG 0x4
  44. #define MDIO_WDATA_REG 0x8
  45. #define MDIO_RDATA_REG 0xc
  46. #define MDIO_STA_REG 0x10
  47. /* cfg phy bit map */
  48. #define MDIO_CMD_DEVAD_M 0x1f
  49. #define MDIO_CMD_DEVAD_S 0
  50. #define MDIO_CMD_PRTAD_M 0x1f
  51. #define MDIO_CMD_PRTAD_S 5
  52. #define MDIO_CMD_OP_S 10
  53. #define MDIO_CMD_ST_S 12
  54. #define MDIO_CMD_START_B 14
  55. #define MDIO_ADDR_DATA_M 0xffff
  56. #define MDIO_ADDR_DATA_S 0
  57. #define MDIO_WDATA_DATA_M 0xffff
  58. #define MDIO_WDATA_DATA_S 0
  59. #define MDIO_RDATA_DATA_M 0xffff
  60. #define MDIO_RDATA_DATA_S 0
  61. #define MDIO_STATE_STA_B 0
  62. enum mdio_st_clause {
  63. MDIO_ST_CLAUSE_45 = 0,
  64. MDIO_ST_CLAUSE_22
  65. };
  66. enum mdio_c22_op_seq {
  67. MDIO_C22_WRITE = 1,
  68. MDIO_C22_READ = 2
  69. };
  70. enum mdio_c45_op_seq {
  71. MDIO_C45_WRITE_ADDR = 0,
  72. MDIO_C45_WRITE_DATA,
  73. MDIO_C45_READ_INCREMENT,
  74. MDIO_C45_READ
  75. };
  76. /* peri subctrl reg */
  77. #define MDIO_SC_CLK_EN 0x338
  78. #define MDIO_SC_CLK_DIS 0x33C
  79. #define MDIO_SC_RESET_REQ 0xA38
  80. #define MDIO_SC_RESET_DREQ 0xA3C
  81. #define MDIO_SC_CLK_ST 0x531C
  82. #define MDIO_SC_RESET_ST 0x5A1C
  83. static void mdio_write_reg(void *base, u32 reg, u32 value)
  84. {
  85. u8 __iomem *reg_addr = (u8 __iomem *)base;
  86. writel_relaxed(value, reg_addr + reg);
  87. }
  88. #define MDIO_WRITE_REG(a, reg, value) \
  89. mdio_write_reg((a)->vbase, (reg), (value))
  90. static u32 mdio_read_reg(void *base, u32 reg)
  91. {
  92. u8 __iomem *reg_addr = (u8 __iomem *)base;
  93. return readl_relaxed(reg_addr + reg);
  94. }
  95. #define mdio_set_field(origin, mask, shift, val) \
  96. do { \
  97. (origin) &= (~((mask) << (shift))); \
  98. (origin) |= (((val) & (mask)) << (shift)); \
  99. } while (0)
  100. #define mdio_get_field(origin, mask, shift) (((origin) >> (shift)) & (mask))
  101. static void mdio_set_reg_field(void *base, u32 reg, u32 mask, u32 shift,
  102. u32 val)
  103. {
  104. u32 origin = mdio_read_reg(base, reg);
  105. mdio_set_field(origin, mask, shift, val);
  106. mdio_write_reg(base, reg, origin);
  107. }
  108. #define MDIO_SET_REG_FIELD(dev, reg, mask, shift, val) \
  109. mdio_set_reg_field((dev)->vbase, (reg), (mask), (shift), (val))
  110. static u32 mdio_get_reg_field(void *base, u32 reg, u32 mask, u32 shift)
  111. {
  112. u32 origin;
  113. origin = mdio_read_reg(base, reg);
  114. return mdio_get_field(origin, mask, shift);
  115. }
  116. #define MDIO_GET_REG_FIELD(dev, reg, mask, shift) \
  117. mdio_get_reg_field((dev)->vbase, (reg), (mask), (shift))
  118. #define MDIO_GET_REG_BIT(dev, reg, bit) \
  119. mdio_get_reg_field((dev)->vbase, (reg), 0x1ull, (bit))
  120. #define MDIO_CHECK_SET_ST 1
  121. #define MDIO_CHECK_CLR_ST 0
  122. static int mdio_sc_cfg_reg_write(struct hns_mdio_device *mdio_dev,
  123. u32 cfg_reg, u32 set_val,
  124. u32 st_reg, u32 st_msk, u8 check_st)
  125. {
  126. u32 time_cnt;
  127. u32 reg_value;
  128. int ret;
  129. regmap_write(mdio_dev->subctrl_vbase, cfg_reg, set_val);
  130. for (time_cnt = MDIO_TIMEOUT; time_cnt; time_cnt--) {
  131. ret = regmap_read(mdio_dev->subctrl_vbase, st_reg, &reg_value);
  132. if (ret)
  133. return ret;
  134. reg_value &= st_msk;
  135. if ((!!check_st) == (!!reg_value))
  136. break;
  137. }
  138. if ((!!check_st) != (!!reg_value))
  139. return -EBUSY;
  140. return 0;
  141. }
  142. static int hns_mdio_wait_ready(struct mii_bus *bus)
  143. {
  144. struct hns_mdio_device *mdio_dev = bus->priv;
  145. u32 cmd_reg_value;
  146. int i;
  147. /* waitting for MDIO_COMMAND_REG 's mdio_start==0 */
  148. /* after that can do read or write*/
  149. for (i = 0; i < MDIO_TIMEOUT; i++) {
  150. cmd_reg_value = MDIO_GET_REG_BIT(mdio_dev,
  151. MDIO_COMMAND_REG,
  152. MDIO_CMD_START_B);
  153. if (!cmd_reg_value)
  154. break;
  155. }
  156. if ((i == MDIO_TIMEOUT) && cmd_reg_value)
  157. return -ETIMEDOUT;
  158. return 0;
  159. }
  160. static void hns_mdio_cmd_write(struct hns_mdio_device *mdio_dev,
  161. u8 is_c45, u8 op, u8 phy_id, u16 cmd)
  162. {
  163. u32 cmd_reg_value;
  164. u8 st = is_c45 ? MDIO_ST_CLAUSE_45 : MDIO_ST_CLAUSE_22;
  165. cmd_reg_value = st << MDIO_CMD_ST_S;
  166. cmd_reg_value |= op << MDIO_CMD_OP_S;
  167. cmd_reg_value |=
  168. (phy_id & MDIO_CMD_PRTAD_M) << MDIO_CMD_PRTAD_S;
  169. cmd_reg_value |= (cmd & MDIO_CMD_DEVAD_M) << MDIO_CMD_DEVAD_S;
  170. cmd_reg_value |= 1 << MDIO_CMD_START_B;
  171. MDIO_WRITE_REG(mdio_dev, MDIO_COMMAND_REG, cmd_reg_value);
  172. }
  173. /**
  174. * hns_mdio_write - access phy register
  175. * @bus: mdio bus
  176. * @phy_id: phy id
  177. * @regnum: register num
  178. * @value: register value
  179. *
  180. * Return 0 on success, negative on failure
  181. */
  182. static int hns_mdio_write(struct mii_bus *bus,
  183. int phy_id, int regnum, u16 data)
  184. {
  185. int ret;
  186. struct hns_mdio_device *mdio_dev = (struct hns_mdio_device *)bus->priv;
  187. u8 devad = ((regnum >> 16) & 0x1f);
  188. u8 is_c45 = !!(regnum & MII_ADDR_C45);
  189. u16 reg = (u16)(regnum & 0xffff);
  190. u8 op;
  191. u16 cmd_reg_cfg;
  192. dev_dbg(&bus->dev, "mdio write %s,base is %p\n",
  193. bus->id, mdio_dev->vbase);
  194. dev_dbg(&bus->dev, "phy id=%d, is_c45=%d, devad=%d, reg=%#x, write data=%d\n",
  195. phy_id, is_c45, devad, reg, data);
  196. /* wait for ready */
  197. ret = hns_mdio_wait_ready(bus);
  198. if (ret) {
  199. dev_err(&bus->dev, "MDIO bus is busy\n");
  200. return ret;
  201. }
  202. if (!is_c45) {
  203. cmd_reg_cfg = reg;
  204. op = MDIO_C22_WRITE;
  205. } else {
  206. /* config the cmd-reg to write addr*/
  207. MDIO_SET_REG_FIELD(mdio_dev, MDIO_ADDR_REG, MDIO_ADDR_DATA_M,
  208. MDIO_ADDR_DATA_S, reg);
  209. hns_mdio_cmd_write(mdio_dev, is_c45,
  210. MDIO_C45_WRITE_ADDR, phy_id, devad);
  211. /* check for read or write opt is finished */
  212. ret = hns_mdio_wait_ready(bus);
  213. if (ret) {
  214. dev_err(&bus->dev, "MDIO bus is busy\n");
  215. return ret;
  216. }
  217. /* config the data needed writing */
  218. cmd_reg_cfg = devad;
  219. op = MDIO_C45_WRITE_DATA;
  220. }
  221. MDIO_SET_REG_FIELD(mdio_dev, MDIO_WDATA_REG, MDIO_WDATA_DATA_M,
  222. MDIO_WDATA_DATA_S, data);
  223. hns_mdio_cmd_write(mdio_dev, is_c45, op, phy_id, cmd_reg_cfg);
  224. return 0;
  225. }
  226. /**
  227. * hns_mdio_read - access phy register
  228. * @bus: mdio bus
  229. * @phy_id: phy id
  230. * @regnum: register num
  231. * @value: register value
  232. *
  233. * Return phy register value
  234. */
  235. static int hns_mdio_read(struct mii_bus *bus, int phy_id, int regnum)
  236. {
  237. int ret;
  238. u16 reg_val = 0;
  239. u8 devad = ((regnum >> 16) & 0x1f);
  240. u8 is_c45 = !!(regnum & MII_ADDR_C45);
  241. u16 reg = (u16)(regnum & 0xffff);
  242. struct hns_mdio_device *mdio_dev = (struct hns_mdio_device *)bus->priv;
  243. dev_dbg(&bus->dev, "mdio read %s,base is %p\n",
  244. bus->id, mdio_dev->vbase);
  245. dev_dbg(&bus->dev, "phy id=%d, is_c45=%d, devad=%d, reg=%#x!\n",
  246. phy_id, is_c45, devad, reg);
  247. /* Step 1: wait for ready */
  248. ret = hns_mdio_wait_ready(bus);
  249. if (ret) {
  250. dev_err(&bus->dev, "MDIO bus is busy\n");
  251. return ret;
  252. }
  253. if (!is_c45) {
  254. hns_mdio_cmd_write(mdio_dev, is_c45,
  255. MDIO_C22_READ, phy_id, reg);
  256. } else {
  257. MDIO_SET_REG_FIELD(mdio_dev, MDIO_ADDR_REG, MDIO_ADDR_DATA_M,
  258. MDIO_ADDR_DATA_S, reg);
  259. /* Step 2; config the cmd-reg to write addr*/
  260. hns_mdio_cmd_write(mdio_dev, is_c45,
  261. MDIO_C45_WRITE_ADDR, phy_id, devad);
  262. /* Step 3: check for read or write opt is finished */
  263. ret = hns_mdio_wait_ready(bus);
  264. if (ret) {
  265. dev_err(&bus->dev, "MDIO bus is busy\n");
  266. return ret;
  267. }
  268. hns_mdio_cmd_write(mdio_dev, is_c45,
  269. MDIO_C45_READ, phy_id, devad);
  270. }
  271. /* Step 5: waitting for MDIO_COMMAND_REG 's mdio_start==0,*/
  272. /* check for read or write opt is finished */
  273. ret = hns_mdio_wait_ready(bus);
  274. if (ret) {
  275. dev_err(&bus->dev, "MDIO bus is busy\n");
  276. return ret;
  277. }
  278. reg_val = MDIO_GET_REG_BIT(mdio_dev, MDIO_STA_REG, MDIO_STATE_STA_B);
  279. if (reg_val) {
  280. dev_err(&bus->dev, " ERROR! MDIO Read failed!\n");
  281. return -EBUSY;
  282. }
  283. /* Step 6; get out data*/
  284. reg_val = (u16)MDIO_GET_REG_FIELD(mdio_dev, MDIO_RDATA_REG,
  285. MDIO_RDATA_DATA_M, MDIO_RDATA_DATA_S);
  286. return reg_val;
  287. }
  288. /**
  289. * hns_mdio_reset - reset mdio bus
  290. * @bus: mdio bus
  291. *
  292. * Return 0 on success, negative on failure
  293. */
  294. static int hns_mdio_reset(struct mii_bus *bus)
  295. {
  296. struct hns_mdio_device *mdio_dev = (struct hns_mdio_device *)bus->priv;
  297. const struct hns_mdio_sc_reg *sc_reg;
  298. int ret;
  299. if (dev_of_node(bus->parent)) {
  300. if (!mdio_dev->subctrl_vbase) {
  301. dev_err(&bus->dev, "mdio sys ctl reg has not maped\n");
  302. return -ENODEV;
  303. }
  304. sc_reg = &mdio_dev->sc_reg;
  305. /* 1. reset req, and read reset st check */
  306. ret = mdio_sc_cfg_reg_write(mdio_dev, sc_reg->mdio_reset_req,
  307. 0x1, sc_reg->mdio_reset_st, 0x1,
  308. MDIO_CHECK_SET_ST);
  309. if (ret) {
  310. dev_err(&bus->dev, "MDIO reset fail\n");
  311. return ret;
  312. }
  313. /* 2. dis clk, and read clk st check */
  314. ret = mdio_sc_cfg_reg_write(mdio_dev, sc_reg->mdio_clk_dis,
  315. 0x1, sc_reg->mdio_clk_st, 0x1,
  316. MDIO_CHECK_CLR_ST);
  317. if (ret) {
  318. dev_err(&bus->dev, "MDIO dis clk fail\n");
  319. return ret;
  320. }
  321. /* 3. reset dreq, and read reset st check */
  322. ret = mdio_sc_cfg_reg_write(mdio_dev, sc_reg->mdio_reset_dreq,
  323. 0x1, sc_reg->mdio_reset_st, 0x1,
  324. MDIO_CHECK_CLR_ST);
  325. if (ret) {
  326. dev_err(&bus->dev, "MDIO dis clk fail\n");
  327. return ret;
  328. }
  329. /* 4. en clk, and read clk st check */
  330. ret = mdio_sc_cfg_reg_write(mdio_dev, sc_reg->mdio_clk_en,
  331. 0x1, sc_reg->mdio_clk_st, 0x1,
  332. MDIO_CHECK_SET_ST);
  333. if (ret)
  334. dev_err(&bus->dev, "MDIO en clk fail\n");
  335. } else if (is_acpi_node(bus->parent->fwnode)) {
  336. acpi_status s;
  337. s = acpi_evaluate_object(ACPI_HANDLE(bus->parent),
  338. "_RST", NULL, NULL);
  339. if (ACPI_FAILURE(s)) {
  340. dev_err(&bus->dev, "Reset failed, return:%#x\n", s);
  341. ret = -EBUSY;
  342. } else {
  343. ret = 0;
  344. }
  345. } else {
  346. dev_err(&bus->dev, "Can not get cfg data from DT or ACPI\n");
  347. ret = -ENXIO;
  348. }
  349. return ret;
  350. }
  351. /**
  352. * hns_mdio_probe - probe mdio device
  353. * @pdev: mdio platform device
  354. *
  355. * Return 0 on success, negative on failure
  356. */
  357. static int hns_mdio_probe(struct platform_device *pdev)
  358. {
  359. struct hns_mdio_device *mdio_dev;
  360. struct mii_bus *new_bus;
  361. struct resource *res;
  362. int ret = -ENODEV;
  363. if (!pdev) {
  364. dev_err(NULL, "pdev is NULL!\r\n");
  365. return -ENODEV;
  366. }
  367. mdio_dev = devm_kzalloc(&pdev->dev, sizeof(*mdio_dev), GFP_KERNEL);
  368. if (!mdio_dev)
  369. return -ENOMEM;
  370. new_bus = devm_mdiobus_alloc(&pdev->dev);
  371. if (!new_bus) {
  372. dev_err(&pdev->dev, "mdiobus_alloc fail!\n");
  373. return -ENOMEM;
  374. }
  375. new_bus->name = MDIO_BUS_NAME;
  376. new_bus->read = hns_mdio_read;
  377. new_bus->write = hns_mdio_write;
  378. new_bus->reset = hns_mdio_reset;
  379. new_bus->priv = mdio_dev;
  380. new_bus->parent = &pdev->dev;
  381. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  382. mdio_dev->vbase = devm_ioremap_resource(&pdev->dev, res);
  383. if (IS_ERR(mdio_dev->vbase)) {
  384. ret = PTR_ERR(mdio_dev->vbase);
  385. return ret;
  386. }
  387. platform_set_drvdata(pdev, new_bus);
  388. snprintf(new_bus->id, MII_BUS_ID_SIZE, "%s-%s", "Mii",
  389. dev_name(&pdev->dev));
  390. if (dev_of_node(&pdev->dev)) {
  391. struct of_phandle_args reg_args;
  392. ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
  393. "subctrl-vbase",
  394. 4,
  395. 0,
  396. &reg_args);
  397. if (!ret) {
  398. mdio_dev->subctrl_vbase =
  399. syscon_node_to_regmap(reg_args.np);
  400. if (IS_ERR(mdio_dev->subctrl_vbase)) {
  401. dev_warn(&pdev->dev, "syscon_node_to_regmap error\n");
  402. mdio_dev->subctrl_vbase = NULL;
  403. } else {
  404. if (reg_args.args_count == 4) {
  405. mdio_dev->sc_reg.mdio_clk_en =
  406. (u16)reg_args.args[0];
  407. mdio_dev->sc_reg.mdio_clk_dis =
  408. (u16)reg_args.args[0] + 4;
  409. mdio_dev->sc_reg.mdio_reset_req =
  410. (u16)reg_args.args[1];
  411. mdio_dev->sc_reg.mdio_reset_dreq =
  412. (u16)reg_args.args[1] + 4;
  413. mdio_dev->sc_reg.mdio_clk_st =
  414. (u16)reg_args.args[2];
  415. mdio_dev->sc_reg.mdio_reset_st =
  416. (u16)reg_args.args[3];
  417. } else {
  418. /* for compatible */
  419. mdio_dev->sc_reg.mdio_clk_en =
  420. MDIO_SC_CLK_EN;
  421. mdio_dev->sc_reg.mdio_clk_dis =
  422. MDIO_SC_CLK_DIS;
  423. mdio_dev->sc_reg.mdio_reset_req =
  424. MDIO_SC_RESET_REQ;
  425. mdio_dev->sc_reg.mdio_reset_dreq =
  426. MDIO_SC_RESET_DREQ;
  427. mdio_dev->sc_reg.mdio_clk_st =
  428. MDIO_SC_CLK_ST;
  429. mdio_dev->sc_reg.mdio_reset_st =
  430. MDIO_SC_RESET_ST;
  431. }
  432. }
  433. } else {
  434. dev_warn(&pdev->dev, "find syscon ret = %#x\n", ret);
  435. mdio_dev->subctrl_vbase = NULL;
  436. }
  437. ret = of_mdiobus_register(new_bus, pdev->dev.of_node);
  438. } else if (is_acpi_node(pdev->dev.fwnode)) {
  439. /* Clear all the IRQ properties */
  440. memset(new_bus->irq, PHY_POLL, 4 * PHY_MAX_ADDR);
  441. /* Mask out all PHYs from auto probing. */
  442. new_bus->phy_mask = ~0;
  443. /* Register the MDIO bus */
  444. ret = mdiobus_register(new_bus);
  445. } else {
  446. dev_err(&pdev->dev, "Can not get cfg data from DT or ACPI\n");
  447. ret = -ENXIO;
  448. }
  449. if (ret) {
  450. dev_err(&pdev->dev, "Cannot register as MDIO bus!\n");
  451. platform_set_drvdata(pdev, NULL);
  452. return ret;
  453. }
  454. return 0;
  455. }
  456. /**
  457. * hns_mdio_remove - remove mdio device
  458. * @pdev: mdio platform device
  459. *
  460. * Return 0 on success, negative on failure
  461. */
  462. static int hns_mdio_remove(struct platform_device *pdev)
  463. {
  464. struct mii_bus *bus;
  465. bus = platform_get_drvdata(pdev);
  466. mdiobus_unregister(bus);
  467. platform_set_drvdata(pdev, NULL);
  468. return 0;
  469. }
  470. static const struct of_device_id hns_mdio_match[] = {
  471. {.compatible = "hisilicon,mdio"},
  472. {.compatible = "hisilicon,hns-mdio"},
  473. {}
  474. };
  475. MODULE_DEVICE_TABLE(of, hns_mdio_match);
  476. static const struct acpi_device_id hns_mdio_acpi_match[] = {
  477. { "HISI0141", 0 },
  478. { },
  479. };
  480. MODULE_DEVICE_TABLE(acpi, hns_mdio_acpi_match);
  481. static struct platform_driver hns_mdio_driver = {
  482. .probe = hns_mdio_probe,
  483. .remove = hns_mdio_remove,
  484. .driver = {
  485. .name = MDIO_DRV_NAME,
  486. .of_match_table = hns_mdio_match,
  487. .acpi_match_table = ACPI_PTR(hns_mdio_acpi_match),
  488. },
  489. };
  490. module_platform_driver(hns_mdio_driver);
  491. MODULE_LICENSE("GPL");
  492. MODULE_AUTHOR("Huawei Tech. Co., Ltd.");
  493. MODULE_DESCRIPTION("Hisilicon HNS MDIO driver");
  494. MODULE_ALIAS("platform:" MDIO_DRV_NAME);