Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144343102
D47987.id147697.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
D47987.id147697.diff
View Options
diff --git a/sys/dev/rtwn/rtl8188e/pci/r88ee_attach.c b/sys/dev/rtwn/rtl8188e/pci/r88ee_attach.c
--- a/sys/dev/rtwn/rtl8188e/pci/r88ee_attach.c
+++ b/sys/dev/rtwn/rtl8188e/pci/r88ee_attach.c
@@ -191,7 +191,7 @@
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
--- a/sys/dev/rtwn/rtl8188e/r88e_chan.c
+++ b/sys/dev/rtwn/rtl8188e/r88e_chan.c
@@ -84,6 +84,7 @@
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 @@
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 @@
/* 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
--- a/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c
+++ b/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c
@@ -184,7 +184,7 @@
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
--- a/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c
+++ b/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c
@@ -221,7 +221,7 @@
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
--- a/sys/dev/rtwn/rtl8192c/r92c.h
+++ b/sys/dev/rtwn/rtl8192c/r92c.h
@@ -59,6 +59,7 @@
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
--- a/sys/dev/rtwn/rtl8192c/r92c_chan.c
+++ b/sys/dev/rtwn/rtl8192c/r92c_chan.c
@@ -131,6 +131,7 @@
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 @@
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 @@
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 @@
}
}
+/*
+ * 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
--- a/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c
+++ b/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c
@@ -213,7 +213,7 @@
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
--- a/sys/dev/rtwn/rtl8192e/r92e.h
+++ b/sys/dev/rtwn/rtl8192e/r92e.h
@@ -46,6 +46,7 @@
/* 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
--- a/sys/dev/rtwn/rtl8192e/r92e_chan.c
+++ b/sys/dev/rtwn/rtl8192e/r92e_chan.c
@@ -90,6 +90,7 @@
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,34 @@
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_diff = rs->ofdm_tx_pwr_diff_2g[chain][0];
+ 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] + pwr_diff;
+
+ 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 +139,13 @@
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 +172,19 @@
}
}
+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
--- a/sys/dev/rtwn/rtl8192e/usb/r92eu_attach.c
+++ b/sys/dev/rtwn/rtl8192e/usb/r92eu_attach.c
@@ -164,6 +164,7 @@
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 = r92e_set_tx_power;
sc->mac_prog = &rtl8192eu_mac[0];
sc->mac_size = nitems(rtl8192eu_mac);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Feb 8, 11:07 PM (32 m, 24 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28508159
Default Alt Text
D47987.id147697.diff (9 KB)
Attached To
Mode
D47987: rtwn: try enforcing net80211 regulatory / txpower limits for 11n chips
Attached
Detach File
Event Timeline
Log In to Comment