From nobody Wed Dec 18 23:48:59 2024 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4YD9PS3vYmz5h7hS; Wed, 18 Dec 2024 23:49:00 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R10" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4YD9PS1kkQz45Dn; Wed, 18 Dec 2024 23:49:00 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1734565740; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=7bEcCSIKLNJ/3a3cRx9SCuiw33gxVyus1eLmUiTjQeQ=; b=jNeaEewsxTI+2PmkNadf14KYplH5aMQ2IQP7PigPjQLNq5tQjSfvKuAqr1mLd3ta2BWFB3 gJpTrlb4nS9WiMXbH/3qM9TV5qo8EhQBFk0AiTC+BTqKyoRcPu8k++QkjLTf6Vmh5ZofI3 wk+CXW/Ag2ws87KICgx/A13YwvW0bwd04YEZOeik6Y+Go8sI9CTV1CQy35HEJb00E6y9Xg 2boJxnZwN84VDJ0gRAFrbkuFHf+ripdSDTi2N0EzGDDgrYvt4FV4G9ua5YQaDfTC6Hqrie jfvvKewd+Htwhg9YwF4lCgyHsYvmuBf8ymJjJbfJrFr7yVkTJHf2FkoaDO3KLQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1734565740; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=7bEcCSIKLNJ/3a3cRx9SCuiw33gxVyus1eLmUiTjQeQ=; b=xOdxTX8lm0bPnnMxZ8YlkTgG9SUVPszpbElbG4aqgZ+fWZ3yhiPDgcgEahzq9linXAM2EY vlGZbN985jelTTVpJbIhfUA69tmNTectugFhgJAgKnAgBGl/z6CDWeb8VLr/YL/ILHiXcN EWA/oDahs4O/Y3h0u1E018erFg4XKyLAanBadv/aksYuu6TZ7ffFBrcjcpjleNh4weaq7B 39rN9pJrLp4BjHpjPLspr4XxJLCK6jgfnKH7y+8SabXmdylp77is7L5W1vp3t7ahZbG8lN QKftmjYCrDuOcQbj7oa/LCGI6dLzQlK63mXr08buAmEm5MqBXdcVrJXrBSpqww== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1734565740; a=rsa-sha256; cv=none; b=O3Sowa2ZJDVUt1DCxCRGHaGIpEAaHljSu1w+ealv1v9BqCoiF/FvDCmwks38W94x/bqC/C 3G3dj5Nwi+HvZeIAHmSZaRBONiPF2lOlpcruRaunZMtxhwAojKxiYFeG/Uue55Z0Hw/7Mc hL7BgnhQ3NlkwRMqHtT1AF7wFnx6Ko8R3ulX71A6Uer0/kYOb3+Iy1DiYSaLBXUx746HUt OAQNxAettW2hDgTbW83gQSsyreQ9ehV5mA6B5TGofEeuGulDMGtUbXtxXJscU+cytQmXY7 RavJ4elbTBScmRBOQo69uIuDS9/DQgF6zwBJlJdl/ibmKOYNQweod6c6gbe+oA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4YD9PR6k80zTLc; Wed, 18 Dec 2024 23:48:59 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 4BINmx4W038132; Wed, 18 Dec 2024 23:48:59 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 4BINmxT1038129; Wed, 18 Dec 2024 23:48:59 GMT (envelope-from git) Date: Wed, 18 Dec 2024 23:48:59 GMT Message-Id: <202412182348.4BINmxT1038129@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Adrian Chadd Subject: git: 0ea7f8ca66f3 - main - rtwn: try enforcing net80211 regulatory / txpower limits for 11n chips List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: adrian X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 0ea7f8ca66f34299727aacecc335de4dfe7e1f94 Auto-Submitted: auto-generated The branch main has been updated by adrian: URL: https://cgit.FreeBSD.org/src/commit/?id=0ea7f8ca66f34299727aacecc335de4dfe7e1f94 commit 0ea7f8ca66f34299727aacecc335de4dfe7e1f94 Author: Adrian Chadd AuthorDate: 2024-12-08 15:51:42 +0000 Commit: Adrian Chadd CommitDate: 2024-12-18 23:46:15 +0000 rtwn: try enforcing net80211 regulatory / txpower limits for 11n chips This is an attempt to reverse engineer what the actual transmit power calculations are doing and apply net80211 limits on them. It doesn't look as simple as just applying the check at the end - there are plenty of places where offsets are calculated between different PHY modes and 1 / 2 antenna MCS transmit rates. There are also some places where the offset being added is negative, so handle the potential underflow so when things hit 0, they don't just wrap and cause the maximum transmit power into the registers. This is being done to aide in power/performance debugging - if there are issues with the transmit power being wrongly calculated and are too high, the output waveform will be distorted and it will effect performance. Being able to drop the transmit power by a few dB here and there can quickly identify if this is happening (because suddenly higher MCS rates / OFDM rates suddenly work better!) I've tested each NIC through the transmit power values from 0 dBm to 30dBm via ifconfig (and they're all capped far before that, normally around 20-25dBm) and they're not underflowing. Locally tested: * RTL8192CU, STA * RTL8192EU, STA * RTL8188EU, STA Differential Revision: https://reviews.freebsd.org/D47987 Reviewed by: bz, imp --- sys/dev/rtwn/rtl8188e/pci/r88ee_attach.c | 2 +- sys/dev/rtwn/rtl8188e/r88e_chan.c | 34 +++++++++++++++++++--- sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c | 2 +- sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c | 2 +- sys/dev/rtwn/rtl8192c/r92c.h | 1 + sys/dev/rtwn/rtl8192c/r92c_chan.c | 31 ++++++++++++++++++++- sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c | 2 +- sys/dev/rtwn/rtl8192e/r92e.h | 1 + sys/dev/rtwn/rtl8192e/r92e_chan.c | 48 ++++++++++++++++++++++++++------ sys/dev/rtwn/rtl8192e/usb/r92eu_attach.c | 2 +- 10 files changed, 107 insertions(+), 18 deletions(-) diff --git a/sys/dev/rtwn/rtl8188e/pci/r88ee_attach.c b/sys/dev/rtwn/rtl8188e/pci/r88ee_attach.c index e4c0027c39a5..d8c0a98e43a3 100644 --- a/sys/dev/rtwn/rtl8188e/pci/r88ee_attach.c +++ b/sys/dev/rtwn/rtl8188e/pci/r88ee_attach.c @@ -191,7 +191,7 @@ r88ee_attach(struct rtwn_pci_softc *pc) sc->sc_init_antsel = rtwn_nop_softc; sc->sc_post_init = r88ee_post_init; sc->sc_init_bcnq1_boundary = rtwn_nop_int_softc; - sc->sc_set_tx_power = rtwn_nop_int_softc_vap; + sc->sc_set_tx_power = r92c_set_tx_power; sc->mac_prog = &rtl8188e_mac[0]; sc->mac_size = nitems(rtl8188e_mac); diff --git a/sys/dev/rtwn/rtl8188e/r88e_chan.c b/sys/dev/rtwn/rtl8188e/r88e_chan.c index 51474bc1b819..f91862720639 100644 --- a/sys/dev/rtwn/rtl8188e/r88e_chan.c +++ b/sys/dev/rtwn/rtl8188e/r88e_chan.c @@ -84,6 +84,7 @@ void r88e_get_txpower(struct rtwn_softc *sc, int chain, struct ieee80211_channel *c, uint8_t power[RTWN_RIDX_COUNT]) { + const struct ieee80211com *ic = &sc->sc_ic; struct r92c_softc *rs = sc->sc_priv; const struct rtwn_r88e_txpwr *rt = rs->rs_txpwr; uint8_t cckpow, ofdmpow, bw20pow, htpow = 0; @@ -96,15 +97,36 @@ r88e_get_txpower(struct rtwn_softc *sc, int chain, return; } - /* XXX net80211 regulatory */ + /* + * Treat the entries in 1/2 dBm resolution where 0 = 0dBm. + * Apply the adjustments afterwards; assume that the vendor + * driver is applying offsets to make up for the actual + * target power in dBm. + */ max_mcs = RTWN_RIDX_HT_MCS(sc->ntxchains * 8 - 1); KASSERT(max_mcs <= RTWN_RIDX_LEGACY_HT_COUNT, ("increase ridx limit\n")); /* Compute per-CCK rate Tx power. */ - cckpow = rt->cck_tx_pwr[group]; for (ridx = RTWN_RIDX_CCK1; ridx <= RTWN_RIDX_CCK11; ridx++) { - power[ridx] = (ridx == RTWN_RIDX_CCK2) ? cckpow - 9 : cckpow; + /* + * Note: the regulatory limit is applied to cckpow before + * it's subtracted for CCK2. + */ + cckpow = rt->cck_tx_pwr[group]; + if (cckpow > ic->ic_txpowlimit) + cckpow = ic->ic_txpowlimit; + + /* + * If it's CCK2 then we subtract the 9 (4.5dB?) offset + * and make sure we aren't going to underflow. + */ + if (ridx == RTWN_RIDX_CCK2 && cckpow < 9) + cckpow = 0; + else if (ridx == RTWN_RIDX_CCK2) + cckpow = cckpow - 9; + + power[ridx] = cckpow; } if (group < 5) @@ -112,14 +134,18 @@ r88e_get_txpower(struct rtwn_softc *sc, int chain, /* Compute per-OFDM rate Tx power. */ ofdmpow = htpow + rt->ofdm_tx_pwr_diff; + if (ofdmpow > ic->ic_txpowlimit) + ofdmpow = ic->ic_txpowlimit; for (ridx = RTWN_RIDX_OFDM6; ridx <= RTWN_RIDX_OFDM54; ridx++) power[ridx] = ofdmpow; bw20pow = htpow + rt->bw20_tx_pwr_diff; + if (bw20pow > ic->ic_txpowlimit) + bw20pow = ic->ic_txpowlimit; for (ridx = RTWN_RIDX_HT_MCS(0); ridx <= max_mcs; ridx++) power[ridx] = bw20pow; - /* Apply max limit. */ + /* Apply max limit */ for (ridx = RTWN_RIDX_CCK1; ridx <= max_mcs; ridx++) { if (power[ridx] > R92C_MAX_TX_PWR) power[ridx] = R92C_MAX_TX_PWR; diff --git a/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c b/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c index 400c0a148f35..752761415bce 100644 --- a/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c +++ b/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c @@ -184,7 +184,7 @@ r88eu_attach(struct rtwn_usb_softc *uc) sc->sc_init_antsel = rtwn_nop_softc; sc->sc_post_init = r88eu_post_init; sc->sc_init_bcnq1_boundary = rtwn_nop_int_softc; - sc->sc_set_tx_power = rtwn_nop_int_softc_vap; + sc->sc_set_tx_power = r92c_set_tx_power; sc->mac_prog = &rtl8188e_mac[0]; sc->mac_size = nitems(rtl8188e_mac); diff --git a/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c b/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c index e992f1c50f26..ddb9fa9ae8c1 100644 --- a/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c +++ b/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c @@ -221,7 +221,7 @@ r92ce_attach(struct rtwn_pci_softc *pc) sc->sc_init_antsel = rtwn_nop_softc; sc->sc_post_init = r92ce_post_init; sc->sc_init_bcnq1_boundary = rtwn_nop_int_softc; - sc->sc_set_tx_power = rtwn_nop_int_softc_vap; + sc->sc_set_tx_power = r92c_set_tx_power; sc->mac_prog = &rtl8192ce_mac[0]; sc->mac_size = nitems(rtl8192ce_mac); diff --git a/sys/dev/rtwn/rtl8192c/r92c.h b/sys/dev/rtwn/rtl8192c/r92c.h index 759a946dac3c..c602f314825a 100644 --- a/sys/dev/rtwn/rtl8192c/r92c.h +++ b/sys/dev/rtwn/rtl8192c/r92c.h @@ -59,6 +59,7 @@ void r92c_get_txpower(struct rtwn_softc *, int, struct ieee80211_channel *, uint8_t[RTWN_RIDX_COUNT]); void r92c_write_txpower(struct rtwn_softc *, int, uint8_t power[RTWN_RIDX_COUNT]); +int r92c_set_tx_power(struct rtwn_softc *, struct ieee80211vap *); void r92c_set_bw20(struct rtwn_softc *, uint8_t); void r92c_set_chan(struct rtwn_softc *, struct ieee80211_channel *); void r92c_set_gain(struct rtwn_softc *, uint8_t); diff --git a/sys/dev/rtwn/rtl8192c/r92c_chan.c b/sys/dev/rtwn/rtl8192c/r92c_chan.c index 5404ad4a81bf..f93159a3c94e 100644 --- a/sys/dev/rtwn/rtl8192c/r92c_chan.c +++ b/sys/dev/rtwn/rtl8192c/r92c_chan.c @@ -131,6 +131,7 @@ void r92c_get_txpower(struct rtwn_softc *sc, int chain, struct ieee80211_channel *c, uint8_t power[RTWN_RIDX_COUNT]) { + const struct ieee80211com *ic = &sc->sc_ic; struct r92c_softc *rs = sc->sc_priv; struct rtwn_r92c_txpwr *rt = rs->rs_txpwr; const struct rtwn_r92c_txagc *base = rs->rs_txagc; @@ -144,7 +145,12 @@ r92c_get_txpower(struct rtwn_softc *sc, int chain, return; } - /* XXX net80211 regulatory */ + /* + * Treat the entries in 1/2 dBm resolution where 0 = 0dBm. + * Apply the adjustments afterwards; assume that the vendor + * driver is applying offsets to make up for the actual + * target power in dBm. + */ max_mcs = RTWN_RIDX_HT_MCS(sc->ntxchains * 8 - 1); KASSERT(max_mcs <= RTWN_RIDX_LEGACY_HT_COUNT, ("increase ridx limit\n")); @@ -199,6 +205,10 @@ r92c_get_txpower(struct rtwn_softc *sc, int chain, for (ridx = RTWN_RIDX_CCK1; ridx <= max_mcs; ridx++) { if (power[ridx] > R92C_MAX_TX_PWR) power[ridx] = R92C_MAX_TX_PWR; + /* Apply net80211 limits */ + if (power[ridx] > ic->ic_txpowlimit) + power[ridx] = ic->ic_txpowlimit; + } } @@ -281,6 +291,25 @@ r92c_set_txpower(struct rtwn_softc *sc, struct ieee80211_channel *c) } } +/* + * Only reconfigure the transmit power if there's a valid BSS node and + * channel. Otherwise just let the next call to r92c_set_chan() + * configure the transmit power. + */ +int +r92c_set_tx_power(struct rtwn_softc *sc, struct ieee80211vap *vap) +{ + if (vap->iv_bss == NULL) + return (EINVAL); + if (vap->iv_bss->ni_chan == IEEE80211_CHAN_ANYC) + return (EINVAL); + + /* Set it for the current channel */ + r92c_set_txpower(sc, vap->iv_bss->ni_chan); + + return (0); +} + static void r92c_set_bw40(struct rtwn_softc *sc, uint8_t chan, int prichlo) { diff --git a/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c b/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c index 6482c933eec2..8e9c4987a359 100644 --- a/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c +++ b/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c @@ -213,7 +213,7 @@ r92cu_attach(struct rtwn_usb_softc *uc) sc->sc_init_antsel = r92c_init_antsel; sc->sc_post_init = r92cu_post_init; sc->sc_init_bcnq1_boundary = rtwn_nop_int_softc; - sc->sc_set_tx_power = rtwn_nop_int_softc_vap; + sc->sc_set_tx_power = r92c_set_tx_power; sc->mac_prog = &rtl8192cu_mac[0]; sc->mac_size = nitems(rtl8192cu_mac); diff --git a/sys/dev/rtwn/rtl8192e/r92e.h b/sys/dev/rtwn/rtl8192e/r92e.h index 331750c48726..280cc1464ac6 100644 --- a/sys/dev/rtwn/rtl8192e/r92e.h +++ b/sys/dev/rtwn/rtl8192e/r92e.h @@ -46,6 +46,7 @@ void r92e_detach_private(struct rtwn_softc *); /* r92e_chan.c */ void r92e_set_chan(struct rtwn_softc *, struct ieee80211_channel *); +int r92e_set_tx_power(struct rtwn_softc *sc, struct ieee80211vap *vap); /* r92e_fw.c */ #ifndef RTWN_WITHOUT_UCODE diff --git a/sys/dev/rtwn/rtl8192e/r92e_chan.c b/sys/dev/rtwn/rtl8192e/r92e_chan.c index 4c761f61809d..4c7121a80c89 100644 --- a/sys/dev/rtwn/rtl8192e/r92e_chan.c +++ b/sys/dev/rtwn/rtl8192e/r92e_chan.c @@ -90,6 +90,7 @@ static void r92e_get_txpower(struct rtwn_softc *sc, int chain, struct ieee80211_channel *c, uint8_t power[RTWN_RIDX_COUNT]) { + const struct ieee80211com *ic = &sc->sc_ic; struct r92e_softc *rs = sc->sc_priv; int i, ridx, group, max_mcs; @@ -103,19 +104,32 @@ r92e_get_txpower(struct rtwn_softc *sc, int chain, struct ieee80211_channel *c, max_mcs = RTWN_RIDX_HT_MCS(sc->ntxchains * 8 - 1); /* XXX regulatory */ - /* XXX net80211 regulatory */ - for (ridx = RTWN_RIDX_CCK1; ridx <= RTWN_RIDX_CCK11; ridx++) + for (ridx = RTWN_RIDX_CCK1; ridx <= RTWN_RIDX_CCK11; ridx++) { power[ridx] = rs->cck_tx_pwr[chain][group]; - for (ridx = RTWN_RIDX_OFDM6; ridx <= max_mcs; ridx++) + if (power[ridx] > ic->ic_txpowlimit) + power[ridx] = ic->ic_txpowlimit; + } + for (ridx = RTWN_RIDX_OFDM6; ridx <= max_mcs; ridx++) { power[ridx] = rs->ht40_tx_pwr_2g[chain][group]; + if (power[ridx] > ic->ic_txpowlimit) + power[ridx] = ic->ic_txpowlimit; + } + + for (ridx = RTWN_RIDX_OFDM6; ridx <= RTWN_RIDX_OFDM54; ridx++) { + /* Ensure we don't underflow if the power delta is -ve */ + int8_t pwr; - for (ridx = RTWN_RIDX_OFDM6; ridx <= RTWN_RIDX_OFDM54; ridx++) - power[ridx] += rs->ofdm_tx_pwr_diff_2g[chain][0]; + pwr = power[ridx] + rs->ofdm_tx_pwr_diff_2g[chain][0]; + if (pwr < 0) + pwr = 0; + + power[ridx] = pwr; + } for (i = 0; i < sc->ntxchains; i++) { uint8_t min_mcs; - uint8_t pwr_diff; + int8_t pwr_diff, pwr; if (IEEE80211_IS_CHAN_HT40(c)) pwr_diff = rs->bw40_tx_pwr_diff_2g[chain][i]; @@ -123,8 +137,13 @@ r92e_get_txpower(struct rtwn_softc *sc, int chain, struct ieee80211_channel *c, pwr_diff = rs->bw20_tx_pwr_diff_2g[chain][i]; min_mcs = RTWN_RIDX_HT_MCS(i * 8); - for (ridx = min_mcs; ridx <= max_mcs; ridx++) - power[ridx] += pwr_diff; + for (ridx = min_mcs; ridx <= max_mcs; ridx++) { + /* Ensure we don't underflow */ + pwr = power[ridx] + pwr_diff; + if (pwr < 0) + pwr = 0; + power[ridx] = pwr; + } } /* Apply max limit. */ @@ -151,6 +170,19 @@ r92e_set_txpower(struct rtwn_softc *sc, struct ieee80211_channel *c) } } +int +r92e_set_tx_power(struct rtwn_softc *sc, struct ieee80211vap *vap) +{ + + if (vap->iv_bss == NULL) + return (EINVAL); + if (vap->iv_bss->ni_chan == IEEE80211_CHAN_ANYC) + return (EINVAL); + + r92e_set_txpower(sc, vap->iv_bss->ni_chan); + return (0); +} + static void r92e_set_bw40(struct rtwn_softc *sc, uint8_t chan, int prichlo) { diff --git a/sys/dev/rtwn/rtl8192e/usb/r92eu_attach.c b/sys/dev/rtwn/rtl8192e/usb/r92eu_attach.c index c134ba22a430..35ff5cb65853 100644 --- a/sys/dev/rtwn/rtl8192e/usb/r92eu_attach.c +++ b/sys/dev/rtwn/rtl8192e/usb/r92eu_attach.c @@ -164,7 +164,7 @@ r92eu_attach(struct rtwn_usb_softc *uc) sc->sc_init_antsel = rtwn_nop_softc; sc->sc_post_init = r92eu_post_init; sc->sc_init_bcnq1_boundary = rtwn_nop_int_softc; - sc->sc_set_tx_power = rtwn_nop_int_softc_vap; + sc->sc_set_tx_power = r92e_set_tx_power; sc->mac_prog = &rtl8192eu_mac[0]; sc->mac_size = nitems(rtl8192eu_mac);