dpaa2-mac.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574
  1. // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
  2. /* Copyright 2019 NXP */
  3. #include <linux/acpi.h>
  4. #include <linux/pcs-lynx.h>
  5. #include <linux/phy/phy.h>
  6. #include <linux/property.h>
  7. #include "dpaa2-eth.h"
  8. #include "dpaa2-mac.h"
  9. #define phylink_to_dpaa2_mac(config) \
  10. container_of((config), struct dpaa2_mac, phylink_config)
  11. #define DPMAC_PROTOCOL_CHANGE_VER_MAJOR 4
  12. #define DPMAC_PROTOCOL_CHANGE_VER_MINOR 8
  13. #define DPAA2_MAC_FEATURE_PROTOCOL_CHANGE BIT(0)
  14. static int dpaa2_mac_cmp_ver(struct dpaa2_mac *mac,
  15. u16 ver_major, u16 ver_minor)
  16. {
  17. if (mac->ver_major == ver_major)
  18. return mac->ver_minor - ver_minor;
  19. return mac->ver_major - ver_major;
  20. }
  21. static void dpaa2_mac_detect_features(struct dpaa2_mac *mac)
  22. {
  23. mac->features = 0;
  24. if (dpaa2_mac_cmp_ver(mac, DPMAC_PROTOCOL_CHANGE_VER_MAJOR,
  25. DPMAC_PROTOCOL_CHANGE_VER_MINOR) >= 0)
  26. mac->features |= DPAA2_MAC_FEATURE_PROTOCOL_CHANGE;
  27. }
  28. static int phy_mode(enum dpmac_eth_if eth_if, phy_interface_t *if_mode)
  29. {
  30. *if_mode = PHY_INTERFACE_MODE_NA;
  31. switch (eth_if) {
  32. case DPMAC_ETH_IF_RGMII:
  33. *if_mode = PHY_INTERFACE_MODE_RGMII;
  34. break;
  35. case DPMAC_ETH_IF_USXGMII:
  36. *if_mode = PHY_INTERFACE_MODE_USXGMII;
  37. break;
  38. case DPMAC_ETH_IF_QSGMII:
  39. *if_mode = PHY_INTERFACE_MODE_QSGMII;
  40. break;
  41. case DPMAC_ETH_IF_SGMII:
  42. *if_mode = PHY_INTERFACE_MODE_SGMII;
  43. break;
  44. case DPMAC_ETH_IF_XFI:
  45. *if_mode = PHY_INTERFACE_MODE_10GBASER;
  46. break;
  47. default:
  48. return -EINVAL;
  49. }
  50. return 0;
  51. }
  52. static enum dpmac_eth_if dpmac_eth_if_mode(phy_interface_t if_mode)
  53. {
  54. switch (if_mode) {
  55. case PHY_INTERFACE_MODE_RGMII:
  56. case PHY_INTERFACE_MODE_RGMII_ID:
  57. case PHY_INTERFACE_MODE_RGMII_RXID:
  58. case PHY_INTERFACE_MODE_RGMII_TXID:
  59. return DPMAC_ETH_IF_RGMII;
  60. case PHY_INTERFACE_MODE_USXGMII:
  61. return DPMAC_ETH_IF_USXGMII;
  62. case PHY_INTERFACE_MODE_QSGMII:
  63. return DPMAC_ETH_IF_QSGMII;
  64. case PHY_INTERFACE_MODE_SGMII:
  65. return DPMAC_ETH_IF_SGMII;
  66. case PHY_INTERFACE_MODE_10GBASER:
  67. return DPMAC_ETH_IF_XFI;
  68. case PHY_INTERFACE_MODE_1000BASEX:
  69. return DPMAC_ETH_IF_1000BASEX;
  70. default:
  71. return DPMAC_ETH_IF_MII;
  72. }
  73. }
  74. static struct fwnode_handle *dpaa2_mac_get_node(struct device *dev,
  75. u16 dpmac_id)
  76. {
  77. struct fwnode_handle *fwnode, *parent = NULL, *child = NULL;
  78. struct device_node *dpmacs = NULL;
  79. int err;
  80. u32 id;
  81. fwnode = dev_fwnode(dev->parent);
  82. if (is_of_node(fwnode)) {
  83. dpmacs = of_find_node_by_name(NULL, "dpmacs");
  84. if (!dpmacs)
  85. return NULL;
  86. parent = of_fwnode_handle(dpmacs);
  87. } else if (is_acpi_node(fwnode)) {
  88. parent = fwnode;
  89. } else {
  90. /* The root dprc device didn't yet get to finalize it's probe,
  91. * thus the fwnode field is not yet set. Defer probe if we are
  92. * facing this situation.
  93. */
  94. return ERR_PTR(-EPROBE_DEFER);
  95. }
  96. fwnode_for_each_child_node(parent, child) {
  97. err = -EINVAL;
  98. if (is_acpi_device_node(child))
  99. err = acpi_get_local_address(ACPI_HANDLE_FWNODE(child), &id);
  100. else if (is_of_node(child))
  101. err = of_property_read_u32(to_of_node(child), "reg", &id);
  102. if (err)
  103. continue;
  104. if (id == dpmac_id) {
  105. of_node_put(dpmacs);
  106. return child;
  107. }
  108. }
  109. of_node_put(dpmacs);
  110. return NULL;
  111. }
  112. static int dpaa2_mac_get_if_mode(struct fwnode_handle *dpmac_node,
  113. struct dpmac_attr attr)
  114. {
  115. phy_interface_t if_mode;
  116. int err;
  117. err = fwnode_get_phy_mode(dpmac_node);
  118. if (err > 0)
  119. return err;
  120. err = phy_mode(attr.eth_if, &if_mode);
  121. if (!err)
  122. return if_mode;
  123. return err;
  124. }
  125. static struct phylink_pcs *dpaa2_mac_select_pcs(struct phylink_config *config,
  126. phy_interface_t interface)
  127. {
  128. struct dpaa2_mac *mac = phylink_to_dpaa2_mac(config);
  129. return mac->pcs;
  130. }
  131. static void dpaa2_mac_config(struct phylink_config *config, unsigned int mode,
  132. const struct phylink_link_state *state)
  133. {
  134. struct dpaa2_mac *mac = phylink_to_dpaa2_mac(config);
  135. struct dpmac_link_state *dpmac_state = &mac->state;
  136. int err;
  137. if (state->an_enabled)
  138. dpmac_state->options |= DPMAC_LINK_OPT_AUTONEG;
  139. else
  140. dpmac_state->options &= ~DPMAC_LINK_OPT_AUTONEG;
  141. err = dpmac_set_link_state(mac->mc_io, 0,
  142. mac->mc_dev->mc_handle, dpmac_state);
  143. if (err)
  144. netdev_err(mac->net_dev, "%s: dpmac_set_link_state() = %d\n",
  145. __func__, err);
  146. if (!mac->serdes_phy)
  147. return;
  148. /* This happens only if we support changing of protocol at runtime */
  149. err = dpmac_set_protocol(mac->mc_io, 0, mac->mc_dev->mc_handle,
  150. dpmac_eth_if_mode(state->interface));
  151. if (err)
  152. netdev_err(mac->net_dev, "dpmac_set_protocol() = %d\n", err);
  153. err = phy_set_mode_ext(mac->serdes_phy, PHY_MODE_ETHERNET, state->interface);
  154. if (err)
  155. netdev_err(mac->net_dev, "phy_set_mode_ext() = %d\n", err);
  156. }
  157. static void dpaa2_mac_link_up(struct phylink_config *config,
  158. struct phy_device *phy,
  159. unsigned int mode, phy_interface_t interface,
  160. int speed, int duplex,
  161. bool tx_pause, bool rx_pause)
  162. {
  163. struct dpaa2_mac *mac = phylink_to_dpaa2_mac(config);
  164. struct dpmac_link_state *dpmac_state = &mac->state;
  165. int err;
  166. dpmac_state->up = 1;
  167. dpmac_state->rate = speed;
  168. if (duplex == DUPLEX_HALF)
  169. dpmac_state->options |= DPMAC_LINK_OPT_HALF_DUPLEX;
  170. else if (duplex == DUPLEX_FULL)
  171. dpmac_state->options &= ~DPMAC_LINK_OPT_HALF_DUPLEX;
  172. if (rx_pause)
  173. dpmac_state->options |= DPMAC_LINK_OPT_PAUSE;
  174. else
  175. dpmac_state->options &= ~DPMAC_LINK_OPT_PAUSE;
  176. if (rx_pause ^ tx_pause)
  177. dpmac_state->options |= DPMAC_LINK_OPT_ASYM_PAUSE;
  178. else
  179. dpmac_state->options &= ~DPMAC_LINK_OPT_ASYM_PAUSE;
  180. err = dpmac_set_link_state(mac->mc_io, 0,
  181. mac->mc_dev->mc_handle, dpmac_state);
  182. if (err)
  183. netdev_err(mac->net_dev, "%s: dpmac_set_link_state() = %d\n",
  184. __func__, err);
  185. }
  186. static void dpaa2_mac_link_down(struct phylink_config *config,
  187. unsigned int mode,
  188. phy_interface_t interface)
  189. {
  190. struct dpaa2_mac *mac = phylink_to_dpaa2_mac(config);
  191. struct dpmac_link_state *dpmac_state = &mac->state;
  192. int err;
  193. dpmac_state->up = 0;
  194. err = dpmac_set_link_state(mac->mc_io, 0,
  195. mac->mc_dev->mc_handle, dpmac_state);
  196. if (err)
  197. netdev_err(mac->net_dev, "dpmac_set_link_state() = %d\n", err);
  198. }
  199. static const struct phylink_mac_ops dpaa2_mac_phylink_ops = {
  200. .validate = phylink_generic_validate,
  201. .mac_select_pcs = dpaa2_mac_select_pcs,
  202. .mac_config = dpaa2_mac_config,
  203. .mac_link_up = dpaa2_mac_link_up,
  204. .mac_link_down = dpaa2_mac_link_down,
  205. };
  206. static int dpaa2_pcs_create(struct dpaa2_mac *mac,
  207. struct fwnode_handle *dpmac_node,
  208. int id)
  209. {
  210. struct mdio_device *mdiodev;
  211. struct fwnode_handle *node;
  212. node = fwnode_find_reference(dpmac_node, "pcs-handle", 0);
  213. if (IS_ERR(node)) {
  214. /* do not error out on old DTS files */
  215. netdev_warn(mac->net_dev, "pcs-handle node not found\n");
  216. return 0;
  217. }
  218. if (!fwnode_device_is_available(node)) {
  219. netdev_err(mac->net_dev, "pcs-handle node not available\n");
  220. fwnode_handle_put(node);
  221. return -ENODEV;
  222. }
  223. mdiodev = fwnode_mdio_find_device(node);
  224. fwnode_handle_put(node);
  225. if (!mdiodev)
  226. return -EPROBE_DEFER;
  227. mac->pcs = lynx_pcs_create(mdiodev);
  228. if (!mac->pcs) {
  229. netdev_err(mac->net_dev, "lynx_pcs_create() failed\n");
  230. put_device(&mdiodev->dev);
  231. return -ENOMEM;
  232. }
  233. return 0;
  234. }
  235. static void dpaa2_pcs_destroy(struct dpaa2_mac *mac)
  236. {
  237. struct phylink_pcs *phylink_pcs = mac->pcs;
  238. if (phylink_pcs) {
  239. struct mdio_device *mdio = lynx_get_mdio_device(phylink_pcs);
  240. struct device *dev = &mdio->dev;
  241. lynx_pcs_destroy(phylink_pcs);
  242. put_device(dev);
  243. mac->pcs = NULL;
  244. }
  245. }
  246. static void dpaa2_mac_set_supported_interfaces(struct dpaa2_mac *mac)
  247. {
  248. int intf, err;
  249. /* We support the current interface mode, and if we have a PCS
  250. * similar interface modes that do not require the SerDes lane to be
  251. * reconfigured.
  252. */
  253. __set_bit(mac->if_mode, mac->phylink_config.supported_interfaces);
  254. if (mac->pcs) {
  255. switch (mac->if_mode) {
  256. case PHY_INTERFACE_MODE_1000BASEX:
  257. case PHY_INTERFACE_MODE_SGMII:
  258. __set_bit(PHY_INTERFACE_MODE_1000BASEX,
  259. mac->phylink_config.supported_interfaces);
  260. __set_bit(PHY_INTERFACE_MODE_SGMII,
  261. mac->phylink_config.supported_interfaces);
  262. break;
  263. default:
  264. break;
  265. }
  266. }
  267. if (!mac->serdes_phy)
  268. return;
  269. /* In case we have access to the SerDes phy/lane, then ask the SerDes
  270. * driver what interfaces are supported based on the current PLL
  271. * configuration.
  272. */
  273. for (intf = 0; intf < PHY_INTERFACE_MODE_MAX; intf++) {
  274. if (intf == PHY_INTERFACE_MODE_NA)
  275. continue;
  276. err = phy_validate(mac->serdes_phy, PHY_MODE_ETHERNET, intf, NULL);
  277. if (err)
  278. continue;
  279. __set_bit(intf, mac->phylink_config.supported_interfaces);
  280. }
  281. }
  282. void dpaa2_mac_start(struct dpaa2_mac *mac)
  283. {
  284. if (mac->serdes_phy)
  285. phy_power_on(mac->serdes_phy);
  286. }
  287. void dpaa2_mac_stop(struct dpaa2_mac *mac)
  288. {
  289. if (mac->serdes_phy)
  290. phy_power_off(mac->serdes_phy);
  291. }
  292. int dpaa2_mac_connect(struct dpaa2_mac *mac)
  293. {
  294. struct net_device *net_dev = mac->net_dev;
  295. struct fwnode_handle *dpmac_node;
  296. struct phy *serdes_phy = NULL;
  297. struct phylink *phylink;
  298. int err;
  299. mac->if_link_type = mac->attr.link_type;
  300. dpmac_node = mac->fw_node;
  301. if (!dpmac_node) {
  302. netdev_err(net_dev, "No dpmac@%d node found.\n", mac->attr.id);
  303. return -ENODEV;
  304. }
  305. err = dpaa2_mac_get_if_mode(dpmac_node, mac->attr);
  306. if (err < 0)
  307. return -EINVAL;
  308. mac->if_mode = err;
  309. if (mac->features & DPAA2_MAC_FEATURE_PROTOCOL_CHANGE &&
  310. !phy_interface_mode_is_rgmii(mac->if_mode) &&
  311. is_of_node(dpmac_node)) {
  312. serdes_phy = of_phy_get(to_of_node(dpmac_node), NULL);
  313. if (serdes_phy == ERR_PTR(-ENODEV))
  314. serdes_phy = NULL;
  315. else if (IS_ERR(serdes_phy))
  316. return PTR_ERR(serdes_phy);
  317. else
  318. phy_init(serdes_phy);
  319. }
  320. mac->serdes_phy = serdes_phy;
  321. /* The MAC does not have the capability to add RGMII delays so
  322. * error out if the interface mode requests them and there is no PHY
  323. * to act upon them
  324. */
  325. if (of_phy_is_fixed_link(to_of_node(dpmac_node)) &&
  326. (mac->if_mode == PHY_INTERFACE_MODE_RGMII_ID ||
  327. mac->if_mode == PHY_INTERFACE_MODE_RGMII_RXID ||
  328. mac->if_mode == PHY_INTERFACE_MODE_RGMII_TXID)) {
  329. netdev_err(net_dev, "RGMII delay not supported\n");
  330. return -EINVAL;
  331. }
  332. if ((mac->attr.link_type == DPMAC_LINK_TYPE_PHY &&
  333. mac->attr.eth_if != DPMAC_ETH_IF_RGMII) ||
  334. mac->attr.link_type == DPMAC_LINK_TYPE_BACKPLANE) {
  335. err = dpaa2_pcs_create(mac, dpmac_node, mac->attr.id);
  336. if (err)
  337. return err;
  338. }
  339. memset(&mac->phylink_config, 0, sizeof(mac->phylink_config));
  340. mac->phylink_config.dev = &net_dev->dev;
  341. mac->phylink_config.type = PHYLINK_NETDEV;
  342. mac->phylink_config.mac_capabilities = MAC_SYM_PAUSE | MAC_ASYM_PAUSE |
  343. MAC_10FD | MAC_100FD | MAC_1000FD | MAC_2500FD | MAC_5000FD |
  344. MAC_10000FD;
  345. dpaa2_mac_set_supported_interfaces(mac);
  346. phylink = phylink_create(&mac->phylink_config,
  347. dpmac_node, mac->if_mode,
  348. &dpaa2_mac_phylink_ops);
  349. if (IS_ERR(phylink)) {
  350. err = PTR_ERR(phylink);
  351. goto err_pcs_destroy;
  352. }
  353. mac->phylink = phylink;
  354. err = phylink_fwnode_phy_connect(mac->phylink, dpmac_node, 0);
  355. if (err) {
  356. netdev_err(net_dev, "phylink_fwnode_phy_connect() = %d\n", err);
  357. goto err_phylink_destroy;
  358. }
  359. return 0;
  360. err_phylink_destroy:
  361. phylink_destroy(mac->phylink);
  362. err_pcs_destroy:
  363. dpaa2_pcs_destroy(mac);
  364. return err;
  365. }
  366. void dpaa2_mac_disconnect(struct dpaa2_mac *mac)
  367. {
  368. if (!mac->phylink)
  369. return;
  370. phylink_disconnect_phy(mac->phylink);
  371. phylink_destroy(mac->phylink);
  372. dpaa2_pcs_destroy(mac);
  373. of_phy_put(mac->serdes_phy);
  374. mac->serdes_phy = NULL;
  375. }
  376. int dpaa2_mac_open(struct dpaa2_mac *mac)
  377. {
  378. struct fsl_mc_device *dpmac_dev = mac->mc_dev;
  379. struct net_device *net_dev = mac->net_dev;
  380. struct fwnode_handle *fw_node;
  381. int err;
  382. err = dpmac_open(mac->mc_io, 0, dpmac_dev->obj_desc.id,
  383. &dpmac_dev->mc_handle);
  384. if (err || !dpmac_dev->mc_handle) {
  385. netdev_err(net_dev, "dpmac_open() = %d\n", err);
  386. return -ENODEV;
  387. }
  388. err = dpmac_get_attributes(mac->mc_io, 0, dpmac_dev->mc_handle,
  389. &mac->attr);
  390. if (err) {
  391. netdev_err(net_dev, "dpmac_get_attributes() = %d\n", err);
  392. goto err_close_dpmac;
  393. }
  394. err = dpmac_get_api_version(mac->mc_io, 0, &mac->ver_major, &mac->ver_minor);
  395. if (err) {
  396. netdev_err(net_dev, "dpmac_get_api_version() = %d\n", err);
  397. goto err_close_dpmac;
  398. }
  399. dpaa2_mac_detect_features(mac);
  400. /* Find the device node representing the MAC device and link the device
  401. * behind the associated netdev to it.
  402. */
  403. fw_node = dpaa2_mac_get_node(&mac->mc_dev->dev, mac->attr.id);
  404. if (IS_ERR(fw_node)) {
  405. err = PTR_ERR(fw_node);
  406. goto err_close_dpmac;
  407. }
  408. mac->fw_node = fw_node;
  409. net_dev->dev.of_node = to_of_node(mac->fw_node);
  410. return 0;
  411. err_close_dpmac:
  412. dpmac_close(mac->mc_io, 0, dpmac_dev->mc_handle);
  413. return err;
  414. }
  415. void dpaa2_mac_close(struct dpaa2_mac *mac)
  416. {
  417. struct fsl_mc_device *dpmac_dev = mac->mc_dev;
  418. dpmac_close(mac->mc_io, 0, dpmac_dev->mc_handle);
  419. if (mac->fw_node)
  420. fwnode_handle_put(mac->fw_node);
  421. }
  422. static char dpaa2_mac_ethtool_stats[][ETH_GSTRING_LEN] = {
  423. [DPMAC_CNT_ING_ALL_FRAME] = "[mac] rx all frames",
  424. [DPMAC_CNT_ING_GOOD_FRAME] = "[mac] rx frames ok",
  425. [DPMAC_CNT_ING_ERR_FRAME] = "[mac] rx frame errors",
  426. [DPMAC_CNT_ING_FRAME_DISCARD] = "[mac] rx frame discards",
  427. [DPMAC_CNT_ING_UCAST_FRAME] = "[mac] rx u-cast",
  428. [DPMAC_CNT_ING_BCAST_FRAME] = "[mac] rx b-cast",
  429. [DPMAC_CNT_ING_MCAST_FRAME] = "[mac] rx m-cast",
  430. [DPMAC_CNT_ING_FRAME_64] = "[mac] rx 64 bytes",
  431. [DPMAC_CNT_ING_FRAME_127] = "[mac] rx 65-127 bytes",
  432. [DPMAC_CNT_ING_FRAME_255] = "[mac] rx 128-255 bytes",
  433. [DPMAC_CNT_ING_FRAME_511] = "[mac] rx 256-511 bytes",
  434. [DPMAC_CNT_ING_FRAME_1023] = "[mac] rx 512-1023 bytes",
  435. [DPMAC_CNT_ING_FRAME_1518] = "[mac] rx 1024-1518 bytes",
  436. [DPMAC_CNT_ING_FRAME_1519_MAX] = "[mac] rx 1519-max bytes",
  437. [DPMAC_CNT_ING_FRAG] = "[mac] rx frags",
  438. [DPMAC_CNT_ING_JABBER] = "[mac] rx jabber",
  439. [DPMAC_CNT_ING_ALIGN_ERR] = "[mac] rx align errors",
  440. [DPMAC_CNT_ING_OVERSIZED] = "[mac] rx oversized",
  441. [DPMAC_CNT_ING_VALID_PAUSE_FRAME] = "[mac] rx pause",
  442. [DPMAC_CNT_ING_BYTE] = "[mac] rx bytes",
  443. [DPMAC_CNT_EGR_GOOD_FRAME] = "[mac] tx frames ok",
  444. [DPMAC_CNT_EGR_UCAST_FRAME] = "[mac] tx u-cast",
  445. [DPMAC_CNT_EGR_MCAST_FRAME] = "[mac] tx m-cast",
  446. [DPMAC_CNT_EGR_BCAST_FRAME] = "[mac] tx b-cast",
  447. [DPMAC_CNT_EGR_ERR_FRAME] = "[mac] tx frame errors",
  448. [DPMAC_CNT_EGR_UNDERSIZED] = "[mac] tx undersized",
  449. [DPMAC_CNT_EGR_VALID_PAUSE_FRAME] = "[mac] tx b-pause",
  450. [DPMAC_CNT_EGR_BYTE] = "[mac] tx bytes",
  451. };
  452. #define DPAA2_MAC_NUM_STATS ARRAY_SIZE(dpaa2_mac_ethtool_stats)
  453. int dpaa2_mac_get_sset_count(void)
  454. {
  455. return DPAA2_MAC_NUM_STATS;
  456. }
  457. void dpaa2_mac_get_strings(u8 *data)
  458. {
  459. u8 *p = data;
  460. int i;
  461. for (i = 0; i < DPAA2_MAC_NUM_STATS; i++) {
  462. strscpy(p, dpaa2_mac_ethtool_stats[i], ETH_GSTRING_LEN);
  463. p += ETH_GSTRING_LEN;
  464. }
  465. }
  466. void dpaa2_mac_get_ethtool_stats(struct dpaa2_mac *mac, u64 *data)
  467. {
  468. struct fsl_mc_device *dpmac_dev = mac->mc_dev;
  469. int i, err;
  470. u64 value;
  471. for (i = 0; i < DPAA2_MAC_NUM_STATS; i++) {
  472. err = dpmac_get_counter(mac->mc_io, 0, dpmac_dev->mc_handle,
  473. i, &value);
  474. if (err) {
  475. netdev_err_once(mac->net_dev,
  476. "dpmac_get_counter error %d\n", err);
  477. *(data + i) = U64_MAX;
  478. continue;
  479. }
  480. *(data + i) = value;
  481. }
  482. }