Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
0002 /* Copyright 2019 NXP */
0003 
0004 #include <linux/acpi.h>
0005 #include <linux/pcs-lynx.h>
0006 #include <linux/phy/phy.h>
0007 #include <linux/property.h>
0008 
0009 #include "dpaa2-eth.h"
0010 #include "dpaa2-mac.h"
0011 
0012 #define phylink_to_dpaa2_mac(config) \
0013     container_of((config), struct dpaa2_mac, phylink_config)
0014 
0015 #define DPMAC_PROTOCOL_CHANGE_VER_MAJOR     4
0016 #define DPMAC_PROTOCOL_CHANGE_VER_MINOR     8
0017 
0018 #define DPAA2_MAC_FEATURE_PROTOCOL_CHANGE   BIT(0)
0019 
0020 static int dpaa2_mac_cmp_ver(struct dpaa2_mac *mac,
0021                  u16 ver_major, u16 ver_minor)
0022 {
0023     if (mac->ver_major == ver_major)
0024         return mac->ver_minor - ver_minor;
0025     return mac->ver_major - ver_major;
0026 }
0027 
0028 static void dpaa2_mac_detect_features(struct dpaa2_mac *mac)
0029 {
0030     mac->features = 0;
0031 
0032     if (dpaa2_mac_cmp_ver(mac, DPMAC_PROTOCOL_CHANGE_VER_MAJOR,
0033                   DPMAC_PROTOCOL_CHANGE_VER_MINOR) >= 0)
0034         mac->features |= DPAA2_MAC_FEATURE_PROTOCOL_CHANGE;
0035 }
0036 
0037 static int phy_mode(enum dpmac_eth_if eth_if, phy_interface_t *if_mode)
0038 {
0039     *if_mode = PHY_INTERFACE_MODE_NA;
0040 
0041     switch (eth_if) {
0042     case DPMAC_ETH_IF_RGMII:
0043         *if_mode = PHY_INTERFACE_MODE_RGMII;
0044         break;
0045     case DPMAC_ETH_IF_USXGMII:
0046         *if_mode = PHY_INTERFACE_MODE_USXGMII;
0047         break;
0048     case DPMAC_ETH_IF_QSGMII:
0049         *if_mode = PHY_INTERFACE_MODE_QSGMII;
0050         break;
0051     case DPMAC_ETH_IF_SGMII:
0052         *if_mode = PHY_INTERFACE_MODE_SGMII;
0053         break;
0054     case DPMAC_ETH_IF_XFI:
0055         *if_mode = PHY_INTERFACE_MODE_10GBASER;
0056         break;
0057     default:
0058         return -EINVAL;
0059     }
0060 
0061     return 0;
0062 }
0063 
0064 static enum dpmac_eth_if dpmac_eth_if_mode(phy_interface_t if_mode)
0065 {
0066     switch (if_mode) {
0067     case PHY_INTERFACE_MODE_RGMII:
0068     case PHY_INTERFACE_MODE_RGMII_ID:
0069     case PHY_INTERFACE_MODE_RGMII_RXID:
0070     case PHY_INTERFACE_MODE_RGMII_TXID:
0071         return DPMAC_ETH_IF_RGMII;
0072     case PHY_INTERFACE_MODE_USXGMII:
0073         return DPMAC_ETH_IF_USXGMII;
0074     case PHY_INTERFACE_MODE_QSGMII:
0075         return DPMAC_ETH_IF_QSGMII;
0076     case PHY_INTERFACE_MODE_SGMII:
0077         return DPMAC_ETH_IF_SGMII;
0078     case PHY_INTERFACE_MODE_10GBASER:
0079         return DPMAC_ETH_IF_XFI;
0080     case PHY_INTERFACE_MODE_1000BASEX:
0081         return DPMAC_ETH_IF_1000BASEX;
0082     default:
0083         return DPMAC_ETH_IF_MII;
0084     }
0085 }
0086 
0087 static struct fwnode_handle *dpaa2_mac_get_node(struct device *dev,
0088                         u16 dpmac_id)
0089 {
0090     struct fwnode_handle *fwnode, *parent = NULL, *child  = NULL;
0091     struct device_node *dpmacs = NULL;
0092     int err;
0093     u32 id;
0094 
0095     fwnode = dev_fwnode(dev->parent);
0096     if (is_of_node(fwnode)) {
0097         dpmacs = of_find_node_by_name(NULL, "dpmacs");
0098         if (!dpmacs)
0099             return NULL;
0100         parent = of_fwnode_handle(dpmacs);
0101     } else if (is_acpi_node(fwnode)) {
0102         parent = fwnode;
0103     } else {
0104         /* The root dprc device didn't yet get to finalize it's probe,
0105          * thus the fwnode field is not yet set. Defer probe if we are
0106          * facing this situation.
0107          */
0108         return ERR_PTR(-EPROBE_DEFER);
0109     }
0110 
0111     fwnode_for_each_child_node(parent, child) {
0112         err = -EINVAL;
0113         if (is_acpi_device_node(child))
0114             err = acpi_get_local_address(ACPI_HANDLE_FWNODE(child), &id);
0115         else if (is_of_node(child))
0116             err = of_property_read_u32(to_of_node(child), "reg", &id);
0117         if (err)
0118             continue;
0119 
0120         if (id == dpmac_id) {
0121             of_node_put(dpmacs);
0122             return child;
0123         }
0124     }
0125     of_node_put(dpmacs);
0126     return NULL;
0127 }
0128 
0129 static int dpaa2_mac_get_if_mode(struct fwnode_handle *dpmac_node,
0130                  struct dpmac_attr attr)
0131 {
0132     phy_interface_t if_mode;
0133     int err;
0134 
0135     err = fwnode_get_phy_mode(dpmac_node);
0136     if (err > 0)
0137         return err;
0138 
0139     err = phy_mode(attr.eth_if, &if_mode);
0140     if (!err)
0141         return if_mode;
0142 
0143     return err;
0144 }
0145 
0146 static struct phylink_pcs *dpaa2_mac_select_pcs(struct phylink_config *config,
0147                         phy_interface_t interface)
0148 {
0149     struct dpaa2_mac *mac = phylink_to_dpaa2_mac(config);
0150 
0151     return mac->pcs;
0152 }
0153 
0154 static void dpaa2_mac_config(struct phylink_config *config, unsigned int mode,
0155                  const struct phylink_link_state *state)
0156 {
0157     struct dpaa2_mac *mac = phylink_to_dpaa2_mac(config);
0158     struct dpmac_link_state *dpmac_state = &mac->state;
0159     int err;
0160 
0161     if (state->an_enabled)
0162         dpmac_state->options |= DPMAC_LINK_OPT_AUTONEG;
0163     else
0164         dpmac_state->options &= ~DPMAC_LINK_OPT_AUTONEG;
0165 
0166     err = dpmac_set_link_state(mac->mc_io, 0,
0167                    mac->mc_dev->mc_handle, dpmac_state);
0168     if (err)
0169         netdev_err(mac->net_dev, "%s: dpmac_set_link_state() = %d\n",
0170                __func__, err);
0171 
0172     if (!mac->serdes_phy)
0173         return;
0174 
0175     /* This happens only if we support changing of protocol at runtime */
0176     err = dpmac_set_protocol(mac->mc_io, 0, mac->mc_dev->mc_handle,
0177                  dpmac_eth_if_mode(state->interface));
0178     if (err)
0179         netdev_err(mac->net_dev,  "dpmac_set_protocol() = %d\n", err);
0180 
0181     err = phy_set_mode_ext(mac->serdes_phy, PHY_MODE_ETHERNET, state->interface);
0182     if (err)
0183         netdev_err(mac->net_dev, "phy_set_mode_ext() = %d\n", err);
0184 }
0185 
0186 static void dpaa2_mac_link_up(struct phylink_config *config,
0187                   struct phy_device *phy,
0188                   unsigned int mode, phy_interface_t interface,
0189                   int speed, int duplex,
0190                   bool tx_pause, bool rx_pause)
0191 {
0192     struct dpaa2_mac *mac = phylink_to_dpaa2_mac(config);
0193     struct dpmac_link_state *dpmac_state = &mac->state;
0194     int err;
0195 
0196     dpmac_state->up = 1;
0197 
0198     dpmac_state->rate = speed;
0199 
0200     if (duplex == DUPLEX_HALF)
0201         dpmac_state->options |= DPMAC_LINK_OPT_HALF_DUPLEX;
0202     else if (duplex == DUPLEX_FULL)
0203         dpmac_state->options &= ~DPMAC_LINK_OPT_HALF_DUPLEX;
0204 
0205     if (rx_pause)
0206         dpmac_state->options |= DPMAC_LINK_OPT_PAUSE;
0207     else
0208         dpmac_state->options &= ~DPMAC_LINK_OPT_PAUSE;
0209 
0210     if (rx_pause ^ tx_pause)
0211         dpmac_state->options |= DPMAC_LINK_OPT_ASYM_PAUSE;
0212     else
0213         dpmac_state->options &= ~DPMAC_LINK_OPT_ASYM_PAUSE;
0214 
0215     err = dpmac_set_link_state(mac->mc_io, 0,
0216                    mac->mc_dev->mc_handle, dpmac_state);
0217     if (err)
0218         netdev_err(mac->net_dev, "%s: dpmac_set_link_state() = %d\n",
0219                __func__, err);
0220 }
0221 
0222 static void dpaa2_mac_link_down(struct phylink_config *config,
0223                 unsigned int mode,
0224                 phy_interface_t interface)
0225 {
0226     struct dpaa2_mac *mac = phylink_to_dpaa2_mac(config);
0227     struct dpmac_link_state *dpmac_state = &mac->state;
0228     int err;
0229 
0230     dpmac_state->up = 0;
0231     err = dpmac_set_link_state(mac->mc_io, 0,
0232                    mac->mc_dev->mc_handle, dpmac_state);
0233     if (err)
0234         netdev_err(mac->net_dev, "dpmac_set_link_state() = %d\n", err);
0235 }
0236 
0237 static const struct phylink_mac_ops dpaa2_mac_phylink_ops = {
0238     .validate = phylink_generic_validate,
0239     .mac_select_pcs = dpaa2_mac_select_pcs,
0240     .mac_config = dpaa2_mac_config,
0241     .mac_link_up = dpaa2_mac_link_up,
0242     .mac_link_down = dpaa2_mac_link_down,
0243 };
0244 
0245 static int dpaa2_pcs_create(struct dpaa2_mac *mac,
0246                 struct fwnode_handle *dpmac_node,
0247                 int id)
0248 {
0249     struct mdio_device *mdiodev;
0250     struct fwnode_handle *node;
0251 
0252     node = fwnode_find_reference(dpmac_node, "pcs-handle", 0);
0253     if (IS_ERR(node)) {
0254         /* do not error out on old DTS files */
0255         netdev_warn(mac->net_dev, "pcs-handle node not found\n");
0256         return 0;
0257     }
0258 
0259     if (!fwnode_device_is_available(node)) {
0260         netdev_err(mac->net_dev, "pcs-handle node not available\n");
0261         fwnode_handle_put(node);
0262         return -ENODEV;
0263     }
0264 
0265     mdiodev = fwnode_mdio_find_device(node);
0266     fwnode_handle_put(node);
0267     if (!mdiodev)
0268         return -EPROBE_DEFER;
0269 
0270     mac->pcs = lynx_pcs_create(mdiodev);
0271     if (!mac->pcs) {
0272         netdev_err(mac->net_dev, "lynx_pcs_create() failed\n");
0273         put_device(&mdiodev->dev);
0274         return -ENOMEM;
0275     }
0276 
0277     return 0;
0278 }
0279 
0280 static void dpaa2_pcs_destroy(struct dpaa2_mac *mac)
0281 {
0282     struct phylink_pcs *phylink_pcs = mac->pcs;
0283 
0284     if (phylink_pcs) {
0285         struct mdio_device *mdio = lynx_get_mdio_device(phylink_pcs);
0286         struct device *dev = &mdio->dev;
0287 
0288         lynx_pcs_destroy(phylink_pcs);
0289         put_device(dev);
0290         mac->pcs = NULL;
0291     }
0292 }
0293 
0294 static void dpaa2_mac_set_supported_interfaces(struct dpaa2_mac *mac)
0295 {
0296     int intf, err;
0297 
0298     /* We support the current interface mode, and if we have a PCS
0299      * similar interface modes that do not require the SerDes lane to be
0300      * reconfigured.
0301      */
0302     __set_bit(mac->if_mode, mac->phylink_config.supported_interfaces);
0303     if (mac->pcs) {
0304         switch (mac->if_mode) {
0305         case PHY_INTERFACE_MODE_1000BASEX:
0306         case PHY_INTERFACE_MODE_SGMII:
0307             __set_bit(PHY_INTERFACE_MODE_1000BASEX,
0308                   mac->phylink_config.supported_interfaces);
0309             __set_bit(PHY_INTERFACE_MODE_SGMII,
0310                   mac->phylink_config.supported_interfaces);
0311             break;
0312 
0313         default:
0314             break;
0315         }
0316     }
0317 
0318     if (!mac->serdes_phy)
0319         return;
0320 
0321     /* In case we have access to the SerDes phy/lane, then ask the SerDes
0322      * driver what interfaces are supported based on the current PLL
0323      * configuration.
0324      */
0325     for (intf = 0; intf < PHY_INTERFACE_MODE_MAX; intf++) {
0326         if (intf == PHY_INTERFACE_MODE_NA)
0327             continue;
0328 
0329         err = phy_validate(mac->serdes_phy, PHY_MODE_ETHERNET, intf, NULL);
0330         if (err)
0331             continue;
0332 
0333         __set_bit(intf, mac->phylink_config.supported_interfaces);
0334     }
0335 }
0336 
0337 void dpaa2_mac_start(struct dpaa2_mac *mac)
0338 {
0339     if (mac->serdes_phy)
0340         phy_power_on(mac->serdes_phy);
0341 }
0342 
0343 void dpaa2_mac_stop(struct dpaa2_mac *mac)
0344 {
0345     if (mac->serdes_phy)
0346         phy_power_off(mac->serdes_phy);
0347 }
0348 
0349 int dpaa2_mac_connect(struct dpaa2_mac *mac)
0350 {
0351     struct net_device *net_dev = mac->net_dev;
0352     struct fwnode_handle *dpmac_node;
0353     struct phy *serdes_phy = NULL;
0354     struct phylink *phylink;
0355     int err;
0356 
0357     mac->if_link_type = mac->attr.link_type;
0358 
0359     dpmac_node = mac->fw_node;
0360     if (!dpmac_node) {
0361         netdev_err(net_dev, "No dpmac@%d node found.\n", mac->attr.id);
0362         return -ENODEV;
0363     }
0364 
0365     err = dpaa2_mac_get_if_mode(dpmac_node, mac->attr);
0366     if (err < 0)
0367         return -EINVAL;
0368     mac->if_mode = err;
0369 
0370     if (mac->features & DPAA2_MAC_FEATURE_PROTOCOL_CHANGE &&
0371         !phy_interface_mode_is_rgmii(mac->if_mode) &&
0372         is_of_node(dpmac_node)) {
0373         serdes_phy = of_phy_get(to_of_node(dpmac_node), NULL);
0374 
0375         if (serdes_phy == ERR_PTR(-ENODEV))
0376             serdes_phy = NULL;
0377         else if (IS_ERR(serdes_phy))
0378             return PTR_ERR(serdes_phy);
0379         else
0380             phy_init(serdes_phy);
0381     }
0382     mac->serdes_phy = serdes_phy;
0383 
0384     /* The MAC does not have the capability to add RGMII delays so
0385      * error out if the interface mode requests them and there is no PHY
0386      * to act upon them
0387      */
0388     if (of_phy_is_fixed_link(to_of_node(dpmac_node)) &&
0389         (mac->if_mode == PHY_INTERFACE_MODE_RGMII_ID ||
0390          mac->if_mode == PHY_INTERFACE_MODE_RGMII_RXID ||
0391          mac->if_mode == PHY_INTERFACE_MODE_RGMII_TXID)) {
0392         netdev_err(net_dev, "RGMII delay not supported\n");
0393         return -EINVAL;
0394     }
0395 
0396     if ((mac->attr.link_type == DPMAC_LINK_TYPE_PHY &&
0397          mac->attr.eth_if != DPMAC_ETH_IF_RGMII) ||
0398         mac->attr.link_type == DPMAC_LINK_TYPE_BACKPLANE) {
0399         err = dpaa2_pcs_create(mac, dpmac_node, mac->attr.id);
0400         if (err)
0401             return err;
0402     }
0403 
0404     memset(&mac->phylink_config, 0, sizeof(mac->phylink_config));
0405     mac->phylink_config.dev = &net_dev->dev;
0406     mac->phylink_config.type = PHYLINK_NETDEV;
0407 
0408     mac->phylink_config.mac_capabilities = MAC_SYM_PAUSE | MAC_ASYM_PAUSE |
0409         MAC_10FD | MAC_100FD | MAC_1000FD | MAC_2500FD | MAC_5000FD |
0410         MAC_10000FD;
0411 
0412     dpaa2_mac_set_supported_interfaces(mac);
0413 
0414     phylink = phylink_create(&mac->phylink_config,
0415                  dpmac_node, mac->if_mode,
0416                  &dpaa2_mac_phylink_ops);
0417     if (IS_ERR(phylink)) {
0418         err = PTR_ERR(phylink);
0419         goto err_pcs_destroy;
0420     }
0421     mac->phylink = phylink;
0422 
0423     err = phylink_fwnode_phy_connect(mac->phylink, dpmac_node, 0);
0424     if (err) {
0425         netdev_err(net_dev, "phylink_fwnode_phy_connect() = %d\n", err);
0426         goto err_phylink_destroy;
0427     }
0428 
0429     return 0;
0430 
0431 err_phylink_destroy:
0432     phylink_destroy(mac->phylink);
0433 err_pcs_destroy:
0434     dpaa2_pcs_destroy(mac);
0435 
0436     return err;
0437 }
0438 
0439 void dpaa2_mac_disconnect(struct dpaa2_mac *mac)
0440 {
0441     if (!mac->phylink)
0442         return;
0443 
0444     phylink_disconnect_phy(mac->phylink);
0445     phylink_destroy(mac->phylink);
0446     dpaa2_pcs_destroy(mac);
0447     of_phy_put(mac->serdes_phy);
0448     mac->serdes_phy = NULL;
0449 }
0450 
0451 int dpaa2_mac_open(struct dpaa2_mac *mac)
0452 {
0453     struct fsl_mc_device *dpmac_dev = mac->mc_dev;
0454     struct net_device *net_dev = mac->net_dev;
0455     struct fwnode_handle *fw_node;
0456     int err;
0457 
0458     err = dpmac_open(mac->mc_io, 0, dpmac_dev->obj_desc.id,
0459              &dpmac_dev->mc_handle);
0460     if (err || !dpmac_dev->mc_handle) {
0461         netdev_err(net_dev, "dpmac_open() = %d\n", err);
0462         return -ENODEV;
0463     }
0464 
0465     err = dpmac_get_attributes(mac->mc_io, 0, dpmac_dev->mc_handle,
0466                    &mac->attr);
0467     if (err) {
0468         netdev_err(net_dev, "dpmac_get_attributes() = %d\n", err);
0469         goto err_close_dpmac;
0470     }
0471 
0472     err = dpmac_get_api_version(mac->mc_io, 0, &mac->ver_major, &mac->ver_minor);
0473     if (err) {
0474         netdev_err(net_dev, "dpmac_get_api_version() = %d\n", err);
0475         goto err_close_dpmac;
0476     }
0477 
0478     dpaa2_mac_detect_features(mac);
0479 
0480     /* Find the device node representing the MAC device and link the device
0481      * behind the associated netdev to it.
0482      */
0483     fw_node = dpaa2_mac_get_node(&mac->mc_dev->dev, mac->attr.id);
0484     if (IS_ERR(fw_node)) {
0485         err = PTR_ERR(fw_node);
0486         goto err_close_dpmac;
0487     }
0488 
0489     mac->fw_node = fw_node;
0490     net_dev->dev.of_node = to_of_node(mac->fw_node);
0491 
0492     return 0;
0493 
0494 err_close_dpmac:
0495     dpmac_close(mac->mc_io, 0, dpmac_dev->mc_handle);
0496     return err;
0497 }
0498 
0499 void dpaa2_mac_close(struct dpaa2_mac *mac)
0500 {
0501     struct fsl_mc_device *dpmac_dev = mac->mc_dev;
0502 
0503     dpmac_close(mac->mc_io, 0, dpmac_dev->mc_handle);
0504     if (mac->fw_node)
0505         fwnode_handle_put(mac->fw_node);
0506 }
0507 
0508 static char dpaa2_mac_ethtool_stats[][ETH_GSTRING_LEN] = {
0509     [DPMAC_CNT_ING_ALL_FRAME]       = "[mac] rx all frames",
0510     [DPMAC_CNT_ING_GOOD_FRAME]      = "[mac] rx frames ok",
0511     [DPMAC_CNT_ING_ERR_FRAME]       = "[mac] rx frame errors",
0512     [DPMAC_CNT_ING_FRAME_DISCARD]       = "[mac] rx frame discards",
0513     [DPMAC_CNT_ING_UCAST_FRAME]     = "[mac] rx u-cast",
0514     [DPMAC_CNT_ING_BCAST_FRAME]     = "[mac] rx b-cast",
0515     [DPMAC_CNT_ING_MCAST_FRAME]     = "[mac] rx m-cast",
0516     [DPMAC_CNT_ING_FRAME_64]        = "[mac] rx 64 bytes",
0517     [DPMAC_CNT_ING_FRAME_127]       = "[mac] rx 65-127 bytes",
0518     [DPMAC_CNT_ING_FRAME_255]       = "[mac] rx 128-255 bytes",
0519     [DPMAC_CNT_ING_FRAME_511]       = "[mac] rx 256-511 bytes",
0520     [DPMAC_CNT_ING_FRAME_1023]      = "[mac] rx 512-1023 bytes",
0521     [DPMAC_CNT_ING_FRAME_1518]      = "[mac] rx 1024-1518 bytes",
0522     [DPMAC_CNT_ING_FRAME_1519_MAX]      = "[mac] rx 1519-max bytes",
0523     [DPMAC_CNT_ING_FRAG]            = "[mac] rx frags",
0524     [DPMAC_CNT_ING_JABBER]          = "[mac] rx jabber",
0525     [DPMAC_CNT_ING_ALIGN_ERR]       = "[mac] rx align errors",
0526     [DPMAC_CNT_ING_OVERSIZED]       = "[mac] rx oversized",
0527     [DPMAC_CNT_ING_VALID_PAUSE_FRAME]   = "[mac] rx pause",
0528     [DPMAC_CNT_ING_BYTE]            = "[mac] rx bytes",
0529     [DPMAC_CNT_EGR_GOOD_FRAME]      = "[mac] tx frames ok",
0530     [DPMAC_CNT_EGR_UCAST_FRAME]     = "[mac] tx u-cast",
0531     [DPMAC_CNT_EGR_MCAST_FRAME]     = "[mac] tx m-cast",
0532     [DPMAC_CNT_EGR_BCAST_FRAME]     = "[mac] tx b-cast",
0533     [DPMAC_CNT_EGR_ERR_FRAME]       = "[mac] tx frame errors",
0534     [DPMAC_CNT_EGR_UNDERSIZED]      = "[mac] tx undersized",
0535     [DPMAC_CNT_EGR_VALID_PAUSE_FRAME]   = "[mac] tx b-pause",
0536     [DPMAC_CNT_EGR_BYTE]            = "[mac] tx bytes",
0537 };
0538 
0539 #define DPAA2_MAC_NUM_STATS ARRAY_SIZE(dpaa2_mac_ethtool_stats)
0540 
0541 int dpaa2_mac_get_sset_count(void)
0542 {
0543     return DPAA2_MAC_NUM_STATS;
0544 }
0545 
0546 void dpaa2_mac_get_strings(u8 *data)
0547 {
0548     u8 *p = data;
0549     int i;
0550 
0551     for (i = 0; i < DPAA2_MAC_NUM_STATS; i++) {
0552         strlcpy(p, dpaa2_mac_ethtool_stats[i], ETH_GSTRING_LEN);
0553         p += ETH_GSTRING_LEN;
0554     }
0555 }
0556 
0557 void dpaa2_mac_get_ethtool_stats(struct dpaa2_mac *mac, u64 *data)
0558 {
0559     struct fsl_mc_device *dpmac_dev = mac->mc_dev;
0560     int i, err;
0561     u64 value;
0562 
0563     for (i = 0; i < DPAA2_MAC_NUM_STATS; i++) {
0564         err = dpmac_get_counter(mac->mc_io, 0, dpmac_dev->mc_handle,
0565                     i, &value);
0566         if (err) {
0567             netdev_err_once(mac->net_dev,
0568                     "dpmac_get_counter error %d\n", err);
0569             *(data + i) = U64_MAX;
0570             continue;
0571         }
0572         *(data + i) = value;
0573     }
0574 }