On Fri, Jul 22, 2022 at 06:13:04PM +0200, Alexander Bluhm wrote:
> But I am fine with committing ifmedia, gem(4) and bge(4) now. Then
> we can decide on a per driver basis. As long kernel lock is not
> removed from the ifmedia layer, this diff is not strictly necessary.
> I want to commit it anyway to show how MP in ifmedia should work.
This is the part for gem(4) and bge(4). I have tested them.
ifmedia_current() is MP safe and provides the data which all the
drivers need.
After commiting this, I can look for more hardware to test.
ok?
bluhm
Index: dev/ic/gem.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/dev/ic/gem.c,v
retrieving revision 1.127
diff -u -p -r1.127 gem.c
--- dev/ic/gem.c 12 Jul 2022 22:08:17 -0000 1.127
+++ dev/ic/gem.c 26 Jul 2022 09:14:10 -0000
@@ -1348,16 +1348,18 @@ void
gem_mii_statchg(struct device *dev)
{
struct gem_softc *sc = (void *)dev;
-#ifdef GEM_DEBUG
- uint64_t instance = IFM_INST(sc->sc_mii.mii_media.ifm_cur->ifm_media);
-#endif
bus_space_tag_t t = sc->sc_bustag;
bus_space_handle_t mac = sc->sc_h1;
u_int32_t v;
#ifdef GEM_DEBUG
- if (sc->sc_debug)
- printf("gem_mii_statchg: status change: phy = %lld\n",
instance);
+ if (sc->sc_debug) {
+ uint64_t media;
+
+ ifmedia_current(&sc->sc_mii.mii_media, &media, NULL);
+ printf("%s: status change: phy = %lld\n",
+ __func__, IFM_INST(media));
+ }
#endif
/* Set tx full duplex options */
Index: dev/pci/if_bge.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/dev/pci/if_bge.c,v
retrieving revision 1.398
diff -u -p -r1.398 if_bge.c
--- dev/pci/if_bge.c 11 Mar 2022 18:00:45 -0000 1.398
+++ dev/pci/if_bge.c 26 Jul 2022 09:14:10 -0000
@@ -1054,12 +1054,15 @@ bge_miibus_statchg(struct device *dev)
{
struct bge_softc *sc = (struct bge_softc *)dev;
struct mii_data *mii = &sc->bge_mii;
+ uint64_t media;
u_int32_t mac_mode, rx_mode, tx_mode;
+ ifmedia_current(&mii->mii_media, &media, NULL);
+
/*
* Get flow control negotiation result.
*/
- if (IFM_SUBTYPE(mii->mii_media.ifm_cur->ifm_media) == IFM_AUTO &&
+ if (IFM_SUBTYPE(media) == IFM_AUTO &&
(mii->mii_media_active & IFM_ETH_FMASK) != sc->bge_flowflags)
sc->bge_flowflags = mii->mii_media_active & IFM_ETH_FMASK;
@@ -3095,7 +3098,8 @@ bge_attach(struct device *parent, struct
0, NULL);
ifmedia_add(&sc->bge_ifmedia, IFM_ETHER|IFM_AUTO, 0, NULL);
ifmedia_set(&sc->bge_ifmedia, IFM_ETHER|IFM_AUTO);
- sc->bge_ifmedia.ifm_media = sc->bge_ifmedia.ifm_cur->ifm_media;
+ ifmedia_current(&sc->bge_ifmedia, &sc->bge_ifmedia.ifm_media,
+ NULL);
} else {
int mii_flags;
Index: net/if_media.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/net/if_media.c,v
retrieving revision 1.36
diff -u -p -r1.36 if_media.c
--- net/if_media.c 14 Jul 2022 13:46:25 -0000 1.36
+++ net/if_media.c 26 Jul 2022 09:14:10 -0000
@@ -430,6 +430,21 @@ ifmedia_get(struct ifmedia *ifm, uint64_
return (match);
}
+void
+ifmedia_current(struct ifmedia *ifm, uint64_t *media, u_int *data)
+{
+ struct ifmedia_entry *ife;
+
+ mtx_enter(&ifmedia_mtx);
+ ife = ifm->ifm_cur;
+ KASSERT(ife != NULL);
+ if (media != NULL)
+ *media = ife->ifm_media;
+ if (data != NULL)
+ *data = ife->ifm_data;
+ mtx_leave(&ifmedia_mtx);
+}
+
/*
* Delete all media for a given instance.
*/
Index: net/if_media.h
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/net/if_media.h,v
retrieving revision 1.45
diff -u -p -r1.45 if_media.h
--- net/if_media.h 14 Jul 2022 13:46:25 -0000 1.45
+++ net/if_media.h 26 Jul 2022 09:14:10 -0000
@@ -131,6 +131,9 @@ int ifmedia_ioctl(struct ifnet *, struct
/* Locate a media entry */
int ifmedia_match(struct ifmedia *, uint64_t, uint64_t);
+/* Get current media and data */
+void ifmedia_current(struct ifmedia *, uint64_t *, u_int *);
+
/* Delete all media for a given media instance */
void ifmedia_delete_instance(struct ifmedia *, uint64_t);