Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DPAA2: properly set link state on startup #11

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions sys/conf/files.arm64
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@ dev/dpaa2/dpaa2_mac.c optional SOC_NXP_LS dpaa2
dev/dpaa2/dpaa2_con.c optional SOC_NXP_LS dpaa2
dev/dpaa2/dpaa2_mc_acpi.c optional SOC_NXP_LS dpaa2 acpi
dev/dpaa2/dpaa2_mc_fdt.c optional SOC_NXP_LS dpaa2 fdt
dev/dpaa2/memac_mdio_if.m optional SOC_NXP_LS dpaa2 acpi | SOC_NXP_LS dpaa2 fdt
dev/dpaa2/memac_mdio_acpi.c optional SOC_NXP_LS dpaa2 acpi

##
Expand Down
137 changes: 87 additions & 50 deletions sys/dev/dpaa2/dpaa2_ni.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ __FBSDID("$FreeBSD$");
#include "pci_if.h"
#include "miibus_if.h"
#include "mdio_if.h"
#include "memac_mdio_if.h"

#include "dpaa2_mc.h"
#include "dpaa2_mc_if.h"
Expand Down Expand Up @@ -449,6 +450,7 @@ static u_int dpaa2_ni_add_maddr(void *, struct sockaddr_dl *, u_int);
static void dpaa2_ni_intr(void *);

/* MII handlers */
static void dpaa2_ni_miibus_statchg(device_t);
static int dpaa2_ni_media_change(struct ifnet *);
static void dpaa2_ni_media_status(struct ifnet *, struct ifmediareq *);
static void dpaa2_ni_media_tick(void *);
Expand Down Expand Up @@ -858,21 +860,31 @@ dpaa2_ni_setup(device_t dev)
"mode\n");
error = DPAA2_MC_GET_PHY_DEV(dev,
&sc->mac.phy_dev, sc->mac.dpmac_id);
if (error == 0) {
error = MEMAC_MDIO_SET_NI_DEV(
sc->mac.phy_dev, dev);
if (error != 0)
device_printf(dev, "%s: failed "
"to set dpni dev on memac "
"mdio dev %s: error=%d\n",
__func__,
device_get_nameunit(
sc->mac.phy_dev), error);
}
if (error == 0) {
error = mii_attach(sc->mac.phy_dev,
&sc->miibus, sc->ifp,
dpaa2_ni_media_change,
dpaa2_ni_media_status,
BMSR_DEFCAPMASK, MII_PHY_ANY, 0, 0);
if (error != 0)
device_printf(dev, "%s: failed "
"to attach to miibus: "
"error=%d\n",
__func__, error);
}

if (error != 0) {
device_printf(dev, "%s: failed to "
"attach miibus: error=%d\n",
__func__, error);
} else {
if (error == 0)
sc->mii = device_get_softc(sc->miibus);
}
} else {
device_printf(dev, "%s: DPMAC link type is not "
"supported\n", __func__);
Expand Down Expand Up @@ -2108,47 +2120,29 @@ dpaa2_ni_set_mac_addr(device_t dev, struct dpaa2_cmd *cmd, uint16_t rc_token,
return (0);
}

/**
* @brief Callback function to process media change request.
*/
static int
dpaa2_ni_media_change(struct ifnet *ifp)
{
struct dpaa2_ni_softc *sc = ifp->if_softc;

DPNI_LOCK(sc);
if (sc->mii) {
mii_mediachg(sc->mii);
sc->media_status = sc->mii->mii_media.ifm_media;
} else if (sc->fixed_link) {
if_printf(ifp, "%s: can't change media in fixed mode\n",
__func__);
}
DPNI_UNLOCK(sc);

return (0);
}

/**
* @brief Callback function to process media status request.
*/
static void
dpaa2_ni_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
dpaa2_ni_miibus_statchg(device_t dev)
{
struct dpaa2_ni_softc *sc = ifp->if_softc;
struct dpaa2_mac_link_state mac_link = {0};
device_t child = sc->dev;
struct dpaa2_ni_softc *sc;
device_t child;
struct dpaa2_mac_link_state mac_link = { 0 };
uint16_t mac_token;
int link_state = ifp->if_link_state;
int error;
int error, link_state;

DPNI_LOCK(sc);
if (sc->mii) {
mii_pollstat(sc->mii);
ifmr->ifm_active = sc->mii->mii_media_active;
ifmr->ifm_status = sc->mii->mii_media_status;
}
DPNI_UNLOCK(sc);
sc = device_get_softc(dev);
child = sc->dev;

/*
* Note: ifp link state will only be changed AFTER we are called so we
* cannot rely on ifp->if_linkstate here.
*/
if (sc->mii->mii_media_status & IFM_AVALID) {
if (sc->mii->mii_media_status & IFM_ACTIVE)
link_state = LINK_STATE_UP;
else
link_state = LINK_STATE_DOWN;
} else
link_state = LINK_STATE_UNKNOWN;

if (link_state != sc->link_state) {
sc->link_state = link_state;
Expand All @@ -2159,19 +2153,19 @@ dpaa2_ni_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
device_printf(sc->dev, "%s: failed to open DPMAC: "
"id=%d, error=%d\n", __func__, sc->mac.dpmac_id,
error);
goto err_exit;
return;
}

if (link_state == LINK_STATE_UP ||
link_state == LINK_STATE_DOWN) {
/* Update DPMAC link state. */
mac_link.supported = sc->mii->mii_media.ifm_media;
mac_link.advert = sc->mii->mii_media.ifm_media;
mac_link.rate = 1000; /* TODO: Where to get from? */
mac_link.rate = 1000; /* TODO: Where to get from? */ /* ifmedia_baudrate? */
mac_link.options =
DPAA2_MAC_LINK_OPT_AUTONEG |
DPAA2_MAC_LINK_OPT_PAUSE;
mac_link.up = link_state == LINK_STATE_UP ? true : false;
mac_link.up = (link_state == LINK_STATE_UP) ? true : false;
mac_link.state_valid = true;

/* Inform DPMAC about link state. */
Expand All @@ -2189,10 +2183,46 @@ dpaa2_ni_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
}
return;

err_close_mac:
err_close_mac:
DPAA2_CMD_MAC_CLOSE(sc->dev, child, dpaa2_mcp_tk(sc->cmd, mac_token));
err_exit:
return;
}

/**
* @brief Callback function to process media change request.
*/
static int
dpaa2_ni_media_change(struct ifnet *ifp)
{
struct dpaa2_ni_softc *sc = ifp->if_softc;

DPNI_LOCK(sc);
if (sc->mii) {
mii_mediachg(sc->mii);
sc->media_status = sc->mii->mii_media.ifm_media;
} else if (sc->fixed_link) {
if_printf(ifp, "%s: can't change media in fixed mode\n",
__func__);
}
DPNI_UNLOCK(sc);

return (0);
}

/**
* @brief Callback function to process media status request.
*/
static void
dpaa2_ni_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
{
struct dpaa2_ni_softc *sc = ifp->if_softc;

DPNI_LOCK(sc);
if (sc->mii) {
mii_pollstat(sc->mii);
ifmr->ifm_active = sc->mii->mii_media_active;
ifmr->ifm_status = sc->mii->mii_media_status;
}
DPNI_UNLOCK(sc);
}

/**
Expand Down Expand Up @@ -2248,6 +2278,9 @@ dpaa2_ni_init(void *arg)
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
DPNI_UNLOCK(sc);

/* Force link-state update to initilize things. */
dpaa2_ni_miibus_statchg(dev);

return;
}

Expand Down Expand Up @@ -3409,6 +3442,9 @@ static device_method_t dpaa2_ni_methods[] = {
DEVMETHOD(device_attach, dpaa2_ni_attach),
DEVMETHOD(device_detach, dpaa2_ni_detach),

/* mii via memac_mdio */
DEVMETHOD(miibus_statchg, dpaa2_ni_miibus_statchg),

DEVMETHOD_END
};

Expand All @@ -3422,3 +3458,4 @@ DRIVER_MODULE(miibus, dpaa2_ni, miibus_driver, 0, 0);
DRIVER_MODULE(dpaa2_ni, dpaa2_rc, dpaa2_ni_driver, 0, 0);

MODULE_DEPEND(dpaa2_ni, miibus, 1, 1, 1);
MODULE_DEPEND(dpaa2_ni, memac_mdio, 1, 1, 1);
51 changes: 31 additions & 20 deletions sys/dev/dpaa2/memac_mdio_acpi.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2021 Bjoern A. Zeeb
* Copyright (c) 2021-2022 Bjoern A. Zeeb
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
Expand Down Expand Up @@ -50,15 +50,17 @@ __FBSDID("$FreeBSD$");
#include <dev/mii/mii.h>
#include <dev/mii/miivar.h>

#include "memac_mdio_if.h"
#include "acpi_bus_if.h"
#include "miibus_if.h"

/* -------------------------------------------------------------------------- */

struct memacphy_softc {
int uid;
uint64_t phy_channel;
char compatible[64];
int uid;
uint64_t phy_channel;
char compatible[64];
device_t dpnidev;
};

static int
Expand Down Expand Up @@ -100,26 +102,40 @@ memacphy_acpi_attach(device_t dev)
static int
memacphy_miibus_readreg(device_t dev, int phy, int reg)
{
#if 0
device_printf(dev, "phy read %d:%d\n", phy, reg);
#endif

return (MIIBUS_READREG(device_get_parent(dev), phy, reg));
}

static int
memacphy_miibus_writereg(device_t dev, int phy, int reg, int data)
{
#if 0
device_printf(dev, "phy write %d:%d\n", phy, reg);
#endif

return (MIIBUS_WRITEREG(device_get_parent(dev), phy, reg, data));
}

static void
memacphy_miibus_statchg(device_t dev)
{
device_printf(dev, "statchg\n");
MIIBUS_STATCHG(device_get_parent(dev));
struct memacphy_softc *sc;

sc = device_get_softc(dev);

if (sc->dpnidev != NULL)
MIIBUS_STATCHG(sc->dpnidev);
}

static int
memac_mdio_set_ni_dev(device_t dev, device_t nidev)
{
struct memacphy_softc *sc;

sc = device_get_softc(dev);

if (sc->dpnidev != NULL)
return (EBUSY);

sc->dpnidev = nidev;
return (0);
}

static device_method_t memacphy_acpi_methods[] = {
Expand All @@ -133,6 +149,9 @@ static device_method_t memacphy_acpi_methods[] = {
DEVMETHOD(miibus_writereg, memacphy_miibus_writereg),
DEVMETHOD(miibus_statchg, memacphy_miibus_statchg),

/* memac */
DEVMETHOD(memac_mdio_set_ni_dev, memac_mdio_set_ni_dev),

DEVMETHOD_END
};

Expand Down Expand Up @@ -403,12 +422,6 @@ memac_miibus_writereg(device_t dev, int phy, int reg, int data)
return (0);
}

static void
memac_miibus_statchg(device_t dev)
{
device_printf(dev, "statchg\n");
}

static ssize_t
memac_mdio_get_property(device_t dev, device_t child, const char *propname,
void *propvalue, size_t size, device_property_type_t type)
Expand All @@ -424,7 +437,6 @@ memac_mdio_acpi_read_ivar(device_t dev, device_t child, int index, uintptr_t *re
return (acpi_read_ivar(dev, child, index, result));
}


static device_method_t memac_mdio_acpi_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, memac_mdio_acpi_probe),
Expand All @@ -434,7 +446,6 @@ static device_method_t memac_mdio_acpi_methods[] = {
/* MII interface */
DEVMETHOD(miibus_readreg, memac_miibus_readreg),
DEVMETHOD(miibus_writereg, memac_miibus_writereg),
DEVMETHOD(miibus_statchg, memac_miibus_statchg),

/* .. */
DEVMETHOD(bus_add_child, bus_generic_add_child),
Expand Down
37 changes: 37 additions & 0 deletions sys/dev/dpaa2/memac_mdio_if.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#-
# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2022, Bjoern A. Zeeb
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# $FreeBSD$
#

#include <machine/bus.h>

INTERFACE memac_mdio;

METHOD int set_ni_dev {
device_t dev;
device_t nidev;
};
3 changes: 2 additions & 1 deletion sys/modules/dpaa2/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ SRCS+= dpaa2_mc_fdt.c \

MFILES= dev/dpaa2/dpaa2_cmd_if.m \
dev/dpaa2/dpaa2_swp_if.m \
dev/dpaa2/dpaa2_mc_if.m
dev/dpaa2/dpaa2_mc_if.m \
dev/dpaa2/memac_mdio_if.m

.include <bsd.kmod.mk>