The real problem is that some driver misuse ifm_media as the current active
media. struct mii_data has the current active media(mii_media_active). If a
driver use mii(4), it can be use mii->mii_media_active for this purpose.
struct ifmedia has no entry for this purpose. Some drivers have an entry
in their own softc to keep the value, but some other's don't have it and
they mistakenly use ifm_media.
We might add a new entry to struct ifmedia in future to avoid this confusion
and for simplify.
word but the current "active" media.
The user-set media word is one of the ifmedia_entry's ifm_media(A) that
ifm_cur points to (e.g. IFM_AUTO). It can be taken as ifmediareq's ifm_current
entry. The current active media word is the ifm_media(B) entry of struct
ifmedia (e.g 1000baseTX-FDX as the result of auto negotiation). It can be
taken as ifmediareq's ifm_active entry.
struct ifmedia_entry {
TAILQ_ENTRY(ifmedia_entry) ifm_list;
u_int ifm_media; /* IFMWD: description of this media */ /* A */
u_int ifm_data; /* for driver-specific use */
void *ifm_aux; /* for driver-specific use */
};
struct ifmedia {
u_int ifm_mask; /* IFMWD: mask of changes we don't care */
u_int ifm_media; /* IFMWD: current active media word */ /* B */
struct ifmedia_entry *ifm_cur; /* current user-selected media */
TAILQ_HEAD(, ifmedia_entry) ifm_list; /* list of all supported media */
ifm_change_cb_t ifm_change; /* media change driver callback */
ifm_stat_cb_t ifm_status; /* media status driver callback */
};
So:
in kernel SIOCGIFMEDIA(ifmediareq)
-----------------------------------------------------------------
user-setting: ifm->ifm_cur->ifm_media ifm_current
current active: ifm->ifm_media ifm_active
It would be good to rename some members to make those meaning clear.
We currently use use it up to 30. We should extend the limit to be able to use
more than 10Gbps speeds. Our ifmedia(4) is inconvenience and have some problem
so we should redesign the interface, but it's too late for netbsd-9 to do it.
So, we keep the data structure size and modify the structure a bit. The
strategy is almost the same as FreeBSD. Many bits of IFM_OMASK for Ethernet
have not used, so use some of them for Ethernet's subtype.
The differences against FreeBSD are:
- We use NetBSD style compat code (i.e. no SIOCGIFXMEDIA).
- FreeBSD's IFM_ETH_XTYPE's bit location is from 11 to "14" even though
IFM_OMASK is from 8 to "15". We use _IFM_ETH_XTMASK from bit 13 to "15".
- FreeBSD changed the meaning of IFM_TYPE_MATCH(). I think we should
not do it. We keep it not changing and added new IFM_TYPE_SUBTYPE_MATCH()
macro for matching both TYPE and SUBTYPE.
- Added up to 400GBASE-SR16.
New layout of the media word is as follows (from ifmedia_h):
* if_media Options word:
* Bits Use
* ---- -------
* 0-4 Media subtype MAX SUBTYPE == 255 for ETH and 31 for others
* 5-7 Media type
* 8-15 Type specific options
* 16-18 Mode (for multi-mode devices)
* 19 (Reserved for Future Use)
* 20-27 Shared (global) options
* 28-31 Instance
*
* 3 2 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-------+---------------+-+-----+---------------+-----+---------+
* | | |R| | | | |
* | IMASK | GMASK |F|MMASK+-----+ OMASK |NMASK| TMASK |
* | | |U| |XTMSK| | | |
* +-------+---------------+-+-----+-----+---------+-----+---------+
* <-----> <---> <--->
* IFM_INST() IFM_MODE() IFM_TYPE()
*
* IFM_SUBTYPE(other than ETH)<------->
*
* <---> IFM_SUBTYPE(ETH)<------->
*
*
* <-------------> <------------->
* IFM_OPTIONS()
For the convinience, ifconfig without "mediaopt fullduplex" sets IFM_FDX
automatically for those medias. Without this change, "ifconfig xxN mediaopt
10Gbase-T" (without "mediaopt fullduplex") returns EINVAL if a
driver doesn't call ifmedia_add() without IFM_FDX because ifmedia_match()
returns NULL.
- Relocate definitions in the following order to be easy to understand.
0) IFM_*MASK
1) macros to extract various bits of information from the media word.
2) Media type.
3) Shared media sub-type.
4) Status bits.
5) Shared (global) options
6) Media dependent definitions.
7) kernel function declarations.
7) userland function declarations.
- Add comments.
This change makes me realize that:
0) RFU bit have never used.
1) bit 1..0 are shared between Shared media sub-type and Status bits.
It's little dangerous.
2) No. 5 of Media type is not used (hole).
3) Only IEEE80211 uses IFM_MMASK(IFM_MODE()) bits.
4) IFM_TOKEN's OMASK bits doesn't start from 0x00000100 but starts from
0x00000200. Is this for BSD/OS compatibility?
<kml@patheticgeek.net>.
This patch does NOT add monitor mode support for the Lucent radios.
awi(4) was only modified for compatibility with the new mediaopt.
It does NOT support monitor mode.
Tested by Kevin, Daniel Carosone, and I.