diff --git a/sys/net80211/ieee80211_ioctl.h b/sys/net80211/ieee80211_ioctl.h --- a/sys/net80211/ieee80211_ioctl.h +++ b/sys/net80211/ieee80211_ioctl.h @@ -568,6 +568,34 @@ #define IEEE80211_DEVCAPS_SPACE(_dc) \ IEEE80211_DEVCAPS_SIZE((_dc)->dc_chaninfo.ic_nchans) +/* + * Get driver capabilities (new). + * Driver, hardware/software crypto, radio capabilities + * in various modes. + */ + +#define IEEE80211_DEVCAPS2_VERSION_1 0x00000001 + +struct ieee80211_devcaps2_req_version_1 { + uint32_t dc_version; /* Must be IEEE80211_DEVCAPS2_VERSION_1 */ + uint32_t dc_size; /* Must be IEEE80211_DEVCAPS2_SIZE_VERSION_1 */ + + uint32_t dc_nchans; /* Number of channels in full list */ + uint32_t dc_padding0; + + uint64_t dc_ciphercaps; /* hardware/software cipher support */ + uint64_t dc_keymgmtcaps; /* supported key management suites */ + uint64_t dc_drivercaps; /* driver capabilities */ + + uint64_t dc_htcaps; /* 11n capabilities */ + uint64_t dc_vhtcaps; /* 11ac capabilities */ + uint64_t dc_ehtcaps; /* 11be capabilities */ + uint64_t dc_hecaps; /* 11ax capabilities */ + uint64_t dc_uhrcaps; /* 11bn capabilities */ +}; +#define IEEE80211_DEVCAPS2_VERSION_1_SIZE \ + (sizeof(struct ieee80211_devcaps2_req_version_1)) + struct ieee80211_chanswitch_req { struct ieee80211_channel csa_chan; /* new channel */ int csa_mode; /* CSA mode */ @@ -690,7 +718,7 @@ #define IEEE80211_IOC_APPIE 95 /* application IE's */ #define IEEE80211_IOC_WPS 96 /* WPS operation */ #define IEEE80211_IOC_TSN 97 /* TSN operation */ -#define IEEE80211_IOC_DEVCAPS 98 /* driver+device capabilities */ +#define IEEE80211_IOC_DEVCAPS 98 /* old driver+device capabilities */ #define IEEE80211_IOC_CHANSWITCH 99 /* start 11h channel switch */ #define IEEE80211_IOC_DFS 100 /* DFS (on, off) */ #define IEEE80211_IOC_DOTD 101 /* 802.11d (on, off) */ @@ -709,6 +737,7 @@ #define IEEE80211_IOC_LDPC 114 /* LDPC Tx/RX (on, off) */ #define IEEE80211_IOC_UAPSD 115 /* UAPSD (on, off) */ #define IEEE80211_IOC_UAPSD_INFO 116 /* UAPSD (SP, per-AC enable) */ +#define IEEE80211_IOC_DEVCAPS2 117 /* new driver+device capabilities */ /* VHT */ #define IEEE80211_IOC_VHTCONF 130 /* VHT config (off, on; widths) */ diff --git a/sys/net80211/ieee80211_ioctl.c b/sys/net80211/ieee80211_ioctl.c --- a/sys/net80211/ieee80211_ioctl.c +++ b/sys/net80211/ieee80211_ioctl.c @@ -726,6 +726,57 @@ return error; } +static int +ieee80211_ioctl_getdevcaps2_version_1(struct ieee80211com *ic, + struct ieee80211req *ireq) +{ + struct ieee80211_devcaps2_req_version_1 *dc; + int error; + + if (ireq->i_len < IEEE80211_DEVCAPS2_VERSION_1_SIZE) + return EINVAL; + + dc = (struct ieee80211_devcaps2_req_version_1 *) + IEEE80211_MALLOC(IEEE80211_DEVCAPS2_VERSION_1_SIZE, M_TEMP, + IEEE80211_M_NOWAIT | IEEE80211_M_ZERO); + if (dc == NULL) + return ENOMEM; + + /* ioctl reply i_val is also a version value */ + ireq->i_val = IEEE80211_DEVCAPS2_VERSION_1; + + /* Version */ + dc->dc_version = IEEE80211_DEVCAPS2_VERSION_1; + /* Size of entire reply */ + dc->dc_size = IEEE80211_DEVCAPS2_VERSION_1_SIZE; + /* Number of channels in full list */ + dc->dc_nchans = ic->ic_nchans; + + /* Base driver capabilities */ + dc->dc_drivercaps = ic->ic_caps; + + /* Announce the set of both hardware and software ciphers */ + dc->dc_ciphercaps = ic->ic_cryptocaps | ic->ic_sw_cryptocaps; + + /* Announce the supported software key management */ + dc->dc_keymgmtcaps = ic->ic_sw_keymgmtcaps; + + /* 11n capabilities */ + dc->dc_htcaps = ic->ic_htcaps; + /* 11ac capabilities */ + dc->dc_vhtcaps = ic->ic_vht_cap.vht_cap_info; + /* 11be capabilities */ + dc->dc_ehtcaps = 0; + /* 11ax capabilities */ + dc->dc_hecaps = 0; + /* 11bn capabilities */ + dc->dc_uhrcaps = 0; + + error = copyout(dc, ireq->i_data, IEEE80211_DEVCAPS2_VERSION_1_SIZE); + IEEE80211_FREE(dc, M_TEMP); + return error; +} + static int ieee80211_ioctl_getstavlan(struct ieee80211vap *vap, struct ieee80211req *ireq) { @@ -1159,6 +1210,16 @@ if (vap->iv_flags_ext & IEEE80211_FEXT_UAPSD) ireq->i_val = 1; break; + case IEEE80211_IOC_DEVCAPS2: + if (ireq->i_val == IEEE80211_DEVCAPS2_VERSION_1) { + /* Version 1 devcaps responses */ + error = ieee80211_ioctl_getdevcaps2_version_1(ic, + ireq); + } else { + error = EOPNOTSUPP; /* Not supported */ + } + break; + case IEEE80211_IOC_VHTCONF: ireq->i_val = vap->iv_vht_flags & IEEE80211_FVHT_MASK; break;