static int dpaa2_eth_get_link_ksettings(struct net_device *net_dev, struct ethtool_link_ksettings *link_settings) { struct dpni_link_state state = {0}; int err = 0; struct dpaa2_eth_priv *priv = netdev_priv(net_dev); err = dpni_get_link_state(priv->mc_io, 0, priv->mc_token, &state); if (err) { netdev_err(net_dev, "ERROR %d getting link state\n", err); goto out; } /* At the moment, we have no way of interrogating the DPMAC * from the DPNI side - and for that matter there may exist * no DPMAC at all. So for now we just don't report anything * beyond the DPNI attributes. */ if (state.options & DPNI_LINK_OPT_AUTONEG) link_settings->base.autoneg = AUTONEG_ENABLE; if (!(state.options & DPNI_LINK_OPT_HALF_DUPLEX)) link_settings->base.duplex = DUPLEX_FULL; link_settings->base.speed = state.rate; out: return err; }
static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd) { struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; struct dpni_queue_attr rx_queue_attr; struct dpmac_link_state dpmac_link_state = { 0 }; #ifdef DEBUG struct dpni_link_state link_state; #endif int err; if (net_dev->state == ETH_STATE_ACTIVE) return 0; if (get_mc_boot_status() != 0) { printf("ERROR (MC is not booted)\n"); return -ENODEV; } if (get_dpl_apply_status() == 0) { printf("ERROR (DPL is deployed. No device available)\n"); return -ENODEV; } /* DPMAC initialization */ err = ldpaa_dpmac_setup(priv); if (err < 0) goto err_dpmac_setup; /* DPMAC binding DPNI */ err = ldpaa_dpmac_bind(priv); if (err) goto err_dpamc_bind; /* DPNI initialization */ err = ldpaa_dpni_setup(priv); if (err < 0) goto err_dpni_setup; err = ldpaa_dpbp_setup(); if (err < 0) goto err_dpbp_setup; /* DPNI binding DPBP */ err = ldpaa_dpni_bind(priv); if (err) goto err_dpni_bind; err = dpni_add_mac_addr(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle, net_dev->enetaddr); if (err) { printf("dpni_add_mac_addr() failed\n"); return err; } #ifdef CONFIG_PHYLIB /* TODO Check this path */ err = phy_startup(priv->phydev); if (err) { printf("%s: Could not initialize\n", priv->phydev->dev->name); return err; } #else priv->phydev->speed = SPEED_1000; priv->phydev->link = 1; priv->phydev->duplex = DUPLEX_FULL; #endif err = dpni_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); if (err < 0) { printf("dpni_enable() failed\n"); return err; } dpmac_link_state.rate = SPEED_1000; dpmac_link_state.options = DPMAC_LINK_OPT_AUTONEG; dpmac_link_state.up = 1; err = dpmac_set_link_state(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle, &dpmac_link_state); if (err < 0) { printf("dpmac_set_link_state() failed\n"); return err; } #ifdef DEBUG err = dpni_get_link_state(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle, &link_state); if (err < 0) { printf("dpni_get_link_state() failed\n"); return err; } printf("link status: %d - ", link_state.up); link_state.up == 0 ? printf("down\n") : link_state.up == 1 ? printf("up\n") : printf("error state\n"); #endif /* TODO: support multiple Rx flows */ err = dpni_get_rx_flow(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle, 0, 0, &rx_queue_attr); if (err) { printf("dpni_get_rx_flow() failed\n"); goto err_rx_flow; } priv->rx_dflt_fqid = rx_queue_attr.fqid; err = dpni_get_qdid(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle, &priv->tx_qdid); if (err) { printf("dpni_get_qdid() failed\n"); goto err_qdid; } if (!priv->phydev->link) printf("%s: No link.\n", priv->phydev->dev->name); return priv->phydev->link ? 0 : -1; err_qdid: err_rx_flow: dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); err_dpni_bind: ldpaa_dpbp_free(); err_dpbp_setup: err_dpamc_bind: dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); err_dpni_setup: err_dpmac_setup: return err; }
static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd) { struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; struct dpni_queue_attr rx_queue_attr; struct dpmac_link_state dpmac_link_state = { 0 }; #ifdef DEBUG struct dpni_link_state link_state; #endif int err = 0; struct mii_dev *bus; phy_interface_t enet_if; if (net_dev->state == ETH_STATE_ACTIVE) return 0; if (get_mc_boot_status() != 0) { printf("ERROR (MC is not booted)\n"); return -ENODEV; } if (get_dpl_apply_status() == 0) { printf("ERROR (DPL is deployed. No device available)\n"); return -ENODEV; } /* DPMAC initialization */ err = ldpaa_dpmac_setup(priv); if (err < 0) goto err_dpmac_setup; #ifdef CONFIG_PHYLIB if (priv->phydev) err = phy_startup(priv->phydev); if (err) { printf("%s: Could not initialize\n", priv->phydev->dev->name); goto err_dpamc_bind; } #else priv->phydev = (struct phy_device *)malloc(sizeof(struct phy_device)); memset(priv->phydev, 0, sizeof(struct phy_device)); priv->phydev->speed = SPEED_1000; priv->phydev->link = 1; priv->phydev->duplex = DUPLEX_FULL; #endif bus = wriop_get_mdio(priv->dpmac_id); enet_if = wriop_get_enet_if(priv->dpmac_id); if ((bus == NULL) && (enet_if == PHY_INTERFACE_MODE_XGMII)) { priv->phydev = (struct phy_device *) malloc(sizeof(struct phy_device)); memset(priv->phydev, 0, sizeof(struct phy_device)); priv->phydev->speed = SPEED_10000; priv->phydev->link = 1; priv->phydev->duplex = DUPLEX_FULL; } if (!priv->phydev->link) { printf("%s: No link.\n", priv->phydev->dev->name); err = -1; goto err_dpamc_bind; } /* DPMAC binding DPNI */ err = ldpaa_dpmac_bind(priv); if (err) goto err_dpamc_bind; /* DPNI initialization */ err = ldpaa_dpni_setup(priv); if (err < 0) goto err_dpni_setup; err = ldpaa_dpbp_setup(); if (err < 0) goto err_dpbp_setup; /* DPNI binding DPBP */ err = ldpaa_dpni_bind(priv); if (err) goto err_dpni_bind; err = dpni_add_mac_addr(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle, net_dev->enetaddr); if (err) { printf("dpni_add_mac_addr() failed\n"); return err; } err = dpni_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); if (err < 0) { printf("dpni_enable() failed\n"); return err; } dpmac_link_state.rate = priv->phydev->speed; if (priv->phydev->autoneg == AUTONEG_DISABLE) dpmac_link_state.options &= ~DPMAC_LINK_OPT_AUTONEG; else dpmac_link_state.options |= DPMAC_LINK_OPT_AUTONEG; if (priv->phydev->duplex == DUPLEX_HALF) dpmac_link_state.options |= DPMAC_LINK_OPT_HALF_DUPLEX; dpmac_link_state.up = priv->phydev->link; err = dpmac_set_link_state(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle, &dpmac_link_state); if (err < 0) { printf("dpmac_set_link_state() failed\n"); return err; } #ifdef DEBUG err = dpni_get_link_state(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle, &link_state); if (err < 0) { printf("dpni_get_link_state() failed\n"); return err; } printf("link status: %d - ", link_state.up); link_state.up == 0 ? printf("down\n") : link_state.up == 1 ? printf("up\n") : printf("error state\n"); #endif /* TODO: support multiple Rx flows */ err = dpni_get_rx_flow(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle, 0, 0, &rx_queue_attr); if (err) { printf("dpni_get_rx_flow() failed\n"); goto err_rx_flow; } priv->rx_dflt_fqid = rx_queue_attr.fqid; err = dpni_get_qdid(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle, &priv->tx_qdid); if (err) { printf("dpni_get_qdid() failed\n"); goto err_qdid; } return priv->phydev->link; err_qdid: err_rx_flow: dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); err_dpni_bind: ldpaa_dpbp_free(); err_dpbp_setup: dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); err_dpni_setup: err_dpamc_bind: dpmac_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle); err_dpmac_setup: return err; }