Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F177015098
D61079.1793730001.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
9 KB
Referenced Files
None
Subscribers
None
D61079.1793730001.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D61079: dpaa2: Avoid DPMAC link toggling
Attached
Detach File
Event Timeline