Page MenuHomeFreeBSD

D61079.1793730001.diff
No OneTemporary

Authored By
Unknown
Size
9 KB
Referenced Files
None
Subscribers
None

D61079.1793730001.diff

diff --git a/sys/dev/dpaa2/dpaa2_mac.h b/sys/dev/dpaa2/dpaa2_mac.h
--- a/sys/dev/dpaa2/dpaa2_mac.h
+++ b/sys/dev/dpaa2/dpaa2_mac.h
@@ -40,12 +40,21 @@
#define DPAA2_MAC_MAX_RESOURCES 1 /* Maximum resources per DPMAC: 1 DPMCP. */
#define DPAA2_MAC_MSI_COUNT 1 /* MSIs per DPMAC */
-/* DPMAC link configuration options. */
+/* DPMAC link configuration options */
#define DPAA2_MAC_LINK_OPT_AUTONEG ((uint64_t) 0x01u)
#define DPAA2_MAC_LINK_OPT_HALF_DUPLEX ((uint64_t) 0x02u)
#define DPAA2_MAC_LINK_OPT_PAUSE ((uint64_t) 0x04u)
#define DPAA2_MAC_LINK_OPT_ASYM_PAUSE ((uint64_t) 0x08u)
+/* Advertised link speeds */
+#define DPAA2_MAC_ADV_10BASET ((uint64_t) 0x01u)
+#define DPAA2_MAC_ADV_100BASET ((uint64_t) 0x02u)
+#define DPAA2_MAC_ADV_1000BASET ((uint64_t) 0x04u)
+/* Advertise auto-negotiation enabled */
+#define DPAA2_MAC_ADV_AUTONEG ((uint64_t) 0x08u)
+#define DPAA2_MAC_ADV_10000BASET ((uint64_t) 0x10u)
+#define DPAA2_MAC_ADV_2500BASEX ((uint64_t) 0x20u)
+
enum dpaa2_mac_eth_if {
DPAA2_MAC_ETH_IF_MII,
DPAA2_MAC_ETH_IF_RMII,
diff --git a/sys/dev/dpaa2/dpaa2_ni.h b/sys/dev/dpaa2/dpaa2_ni.h
--- a/sys/dev/dpaa2/dpaa2_ni.h
+++ b/sys/dev/dpaa2/dpaa2_ni.h
@@ -449,14 +449,13 @@
*/
struct dpaa2_ni_softc {
device_t dev;
- struct resource *res[DPAA2_NI_MAX_RESOURCES];
+ struct resource *res[DPAA2_NI_MAX_RESOURCES];
uint16_t api_major;
uint16_t api_minor;
uint64_t rx_hash_fields;
uint16_t tx_data_off;
uint16_t tx_qdid;
uint32_t link_options;
- int link_state;
uint16_t buf_align;
uint16_t buf_sz;
@@ -509,6 +508,7 @@
struct taskqueue *bp_taskq;
struct callout mii_callout;
+ struct callout statchg_callout;
struct {
uint32_t dpmac_id;
diff --git a/sys/dev/dpaa2/dpaa2_ni.c b/sys/dev/dpaa2/dpaa2_ni.c
--- a/sys/dev/dpaa2/dpaa2_ni.c
+++ b/sys/dev/dpaa2/dpaa2_ni.c
@@ -456,6 +456,7 @@
static int dpaa2_ni_media_change(if_t );
static void dpaa2_ni_media_status(if_t , struct ifmediareq *);
static void dpaa2_ni_media_tick(void *);
+static void dpaa2_ni_media_statchg(void *);
/* Tx/Rx routines. */
static int dpaa2_ni_rx_cleanup(struct dpaa2_channel *, const int budget);
@@ -515,7 +516,6 @@
sc->mii = NULL;
sc->media_status = 0;
sc->if_flags = 0;
- sc->link_state = LINK_STATE_UNKNOWN;
sc->buf_align = 0;
/* For debug purposes only! */
@@ -654,6 +654,7 @@
ether_ifattach(sc->ifp, sc->mac.addr);
callout_init(&sc->mii_callout, 0);
+ callout_init(&sc->statchg_callout, 0);
return (0);
@@ -2308,97 +2309,11 @@
static void
dpaa2_ni_miibus_statchg(device_t dev)
{
- device_t pdev = device_get_parent(dev);
- device_t child = dev;
- struct dpaa2_ni_softc *sc = device_get_softc(dev);
- struct dpaa2_mac_link_state mac_link = { 0 };
- struct dpaa2_devinfo *rcinfo = device_get_ivars(pdev);
- struct dpaa2_cmd cmd;
- uint16_t rc_token, mac_token;
- int error, link_state;
-
- if (sc->fixed_link || sc->mii == NULL) {
- return;
- }
- if ((if_getdrvflags(sc->ifp) & IFF_DRV_RUNNING) == 0) {
- /*
- * We will receive calls and adjust the changes but
- * not have setup everything (called before dpaa2_ni_init()
- * really). This will then setup the link and internal
- * sc->link_state and not trigger the update once needed,
- * so basically dpmac never knows about it.
- */
- return;
- }
-
- /*
- * 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;
-
- DPAA2_CMD_INIT(&cmd);
-
- error = DPAA2_CMD_RC_OPEN(dev, child, &cmd, rcinfo->id,
- &rc_token);
- if (error) {
- device_printf(dev, "%s: failed to open resource "
- "container: id=%d, error=%d\n", __func__, rcinfo->id,
- error);
- goto err_exit;
- }
- error = DPAA2_CMD_MAC_OPEN(dev, child, &cmd, sc->mac.dpmac_id,
- &mac_token);
- if (error) {
- device_printf(sc->dev, "%s: failed to open DPMAC: "
- "id=%d, error=%d\n", __func__, sc->mac.dpmac_id,
- error);
- goto close_rc;
- }
-
- 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? */ /* 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.state_valid = true;
-
- /* Inform DPMAC about link state. */
- error = DPAA2_CMD_MAC_SET_LINK_STATE(dev, child, &cmd,
- &mac_link);
- if (error) {
- device_printf(sc->dev, "%s: failed to set DPMAC "
- "link state: id=%d, error=%d\n", __func__,
- sc->mac.dpmac_id, error);
- }
- }
- (void)DPAA2_CMD_MAC_CLOSE(dev, child, &cmd);
- (void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd,
- rc_token));
- }
-
- return;
+ struct dpaa2_ni_softc *sc;
-close_rc:
- (void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token));
-err_exit:
- return;
+ sc = device_get_softc(dev);
+ /* Postpone the media state update to avoid DPMAC link toggling. */
+ callout_reset(&sc->statchg_callout, 2*hz, dpaa2_ni_media_statchg, sc);
}
/**
@@ -2471,6 +2386,152 @@
callout_reset(&sc->mii_callout, hz, dpaa2_ni_media_tick, sc);
}
+/**
+ * @brief Callout function to update the media status after the PHY driver
+ * notification.
+ */
+static void
+dpaa2_ni_media_statchg(void *arg)
+{
+ device_t dev, pdev, child;
+ struct dpaa2_ni_softc *sc;
+ struct dpaa2_mac_link_state mac_link = {0};
+ struct dpaa2_devinfo *rcinfo;
+ struct dpaa2_cmd cmd;
+ uint16_t rc_token, mac_token;
+ u_int mstat, mact;
+ int error, ifm_media;
+
+ sc = (struct dpaa2_ni_softc *) arg;
+ dev = sc->dev;
+ pdev = device_get_parent(dev);
+ child = dev;
+ rcinfo = device_get_ivars(pdev);
+
+ DPNI_LOCK(sc);
+ if (sc->fixed_link || sc->mii == NULL) {
+ DPNI_UNLOCK(sc);
+ return;
+ }
+ if ((if_getdrvflags(sc->ifp) & IFF_DRV_RUNNING) == 0) {
+ /*
+ * We will receive calls and adjust the changes but
+ * not have setup everything (called before dpaa2_ni_init()
+ * really). This will then setup the link and internal
+ * sc->link_state and not trigger the update once needed,
+ * so basically dpmac never knows about it.
+ */
+ DPNI_UNLOCK(sc);
+ return;
+ }
+ mstat = sc->mii->mii_media_status;
+ mact = sc->mii->mii_media_active;
+ ifm_media = sc->mii->mii_media.ifm_media;
+ DPNI_UNLOCK(sc);
+
+ if (bootverbose)
+ device_printf(dev, "%s:\n"
+ "mii_media_status=%x, \n"
+ "mii_media_active=%x, \n"
+ "ifm_media=%x\n",
+ __func__, mstat, mact, ifm_media);
+
+ /*
+ * Note: ifp link state will only be changed AFTER we are called so we
+ * cannot rely on ifp->if_linkstate here.
+ */
+ mac_link.up = true;
+ if ((mstat & IFM_AVALID) != 0) {
+ switch (IFM_SUBTYPE(mact)) {
+ case IFM_10_T:
+ mac_link.advert |=
+ DPAA2_MAC_ADV_10BASET |
+ DPAA2_MAC_ADV_AUTONEG;
+ mac_link.rate = 10u;
+ break;
+ case IFM_100_TX:
+ mac_link.advert |=
+ DPAA2_MAC_ADV_10BASET |
+ DPAA2_MAC_ADV_100BASET |
+ DPAA2_MAC_ADV_AUTONEG;
+ mac_link.rate = 100u;
+ break;
+ case IFM_1000_T:
+ mac_link.advert |=
+ DPAA2_MAC_ADV_10BASET |
+ DPAA2_MAC_ADV_100BASET |
+ DPAA2_MAC_ADV_1000BASET |
+ DPAA2_MAC_ADV_AUTONEG;
+ mac_link.rate = 1000u;
+ break;
+ case IFM_10G_T:
+ mac_link.advert |=
+ DPAA2_MAC_ADV_10BASET |
+ DPAA2_MAC_ADV_100BASET |
+ DPAA2_MAC_ADV_1000BASET |
+ DPAA2_MAC_ADV_10000BASET |
+ DPAA2_MAC_ADV_AUTONEG;
+ mac_link.rate = 10000u;
+ break;
+#ifdef __notyet__
+ case IFM_2500_X:
+ mac_link.advert |=
+ DPAA2_MAC_ADV_2500BASEX |
+ DPAA2_MAC_ADV_AUTONEG;
+ mac_link.rate = 2500u;
+ break;
+#endif
+ default:
+ mac_link.advert = 0u;
+ mac_link.rate = 0u;
+ mac_link.up = false;
+ break;
+ }
+ }
+
+ DPAA2_CMD_INIT(&cmd);
+
+ error = DPAA2_CMD_RC_OPEN(dev, child, &cmd, rcinfo->id, &rc_token);
+ if (error) {
+ device_printf(dev, "%s: failed to open resource "
+ "container: id=%d, error=%d\n", __func__, rcinfo->id,
+ error);
+ goto err_exit;
+ }
+ error = DPAA2_CMD_MAC_OPEN(dev, child, &cmd, sc->mac.dpmac_id,
+ &mac_token);
+ if (error) {
+ device_printf(sc->dev, "%s: failed to open DPMAC: "
+ "id=%d, error=%d\n", __func__, sc->mac.dpmac_id,
+ error);
+ goto close_rc;
+ }
+
+ mac_link.supported = mac_link.advert;
+ mac_link.options =
+ DPAA2_MAC_LINK_OPT_AUTONEG |
+ DPAA2_MAC_LINK_OPT_PAUSE;
+ mac_link.state_valid = true;
+
+ error = DPAA2_CMD_MAC_SET_LINK_STATE(dev, child, &cmd,
+ &mac_link);
+ if (error) {
+ device_printf(sc->dev, "%s: failed to set DPMAC "
+ "link state: id=%d, error=%d\n", __func__,
+ sc->mac.dpmac_id, error);
+ }
+
+ (void)DPAA2_CMD_MAC_CLOSE(dev, child, &cmd);
+ (void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token));
+
+ return;
+
+close_rc:
+ (void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token));
+err_exit:
+ return;
+}
+
static void
dpaa2_ni_init(void *arg)
{

File Metadata

Mime Type
text/plain
Expires
Tue, Nov 3, 6:20 PM (3 h, 9 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41363741
Default Alt Text
D61079.1793730001.diff (9 KB)

Event Timeline