Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F147292600
D47986.id148202.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
12 KB
Referenced Files
None
Subscribers
None
D47986.id148202.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
@@ -54,10 +54,12 @@
uint8_t r92c_temp_read(struct rtwn_softc *);
/* r92c_chan.c */
+void r92c_dump_txpower(struct rtwn_softc *, int, uint8_t[RTWN_RIDX_COUNT]);
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
--- a/sys/dev/rtwn/rtl8192c/r92c_chan.c
+++ b/sys/dev/rtwn/rtl8192c/r92c_chan.c
@@ -53,6 +53,56 @@
#include <dev/rtwn/rtl8192c/r92c_reg.h>
#include <dev/rtwn/rtl8192c/r92c_var.h>
+void
+r92c_dump_txpower(struct rtwn_softc *sc, int chain,
+ uint8_t power[RTWN_RIDX_COUNT])
+{
+
+#ifdef RTWN_DEBUG
+ if (sc->sc_debug & RTWN_DEBUG_TXPWR) {
+ int i;
+
+ /* Print CCK */
+ RTWN_DPRINTF(sc, RTWN_DEBUG_TXPWR,
+ "TX [%d]: CCK: 1M: %d 2M: %d 5.5M: %d 11M: %d\n",
+ chain,
+ power[RTWN_RIDX_CCK1],
+ power[RTWN_RIDX_CCK2],
+ power[RTWN_RIDX_CCK55],
+ power[RTWN_RIDX_CCK11]);
+ /* Print OFDM */
+ RTWN_DPRINTF(sc, RTWN_DEBUG_TXPWR,
+ "TX [%d]: OFDM: 6M: %d 9M: %d 12M: %d 18M: %d 24M: %d "
+ "36M: %d 48M: %d 54M: %d\n",
+ chain,
+ power[RTWN_RIDX_OFDM6],
+ power[RTWN_RIDX_OFDM9],
+ power[RTWN_RIDX_OFDM12],
+ power[RTWN_RIDX_OFDM18],
+ power[RTWN_RIDX_OFDM24],
+ power[RTWN_RIDX_OFDM36],
+ power[RTWN_RIDX_OFDM48],
+ power[RTWN_RIDX_OFDM54]);
+ /* Print HT, 1 and 2 stream */
+ for (i = 0; i < sc->ntxchains; i++) {
+ RTWN_DPRINTF(sc, RTWN_DEBUG_TXPWR,
+ "TX [%d]: MCS%d-%d: %d %d %d %d %d %d %d %d\n",
+ chain,
+ i * 8,
+ i * 8 + 7,
+ power[RTWN_RIDX_HT_MCS(i * 8 + 0)],
+ power[RTWN_RIDX_HT_MCS(i * 8 + 1)],
+ power[RTWN_RIDX_HT_MCS(i * 8 + 2)],
+ power[RTWN_RIDX_HT_MCS(i * 8 + 3)],
+ power[RTWN_RIDX_HT_MCS(i * 8 + 4)],
+ power[RTWN_RIDX_HT_MCS(i * 8 + 5)],
+ power[RTWN_RIDX_HT_MCS(i * 8 + 6)],
+ power[RTWN_RIDX_HT_MCS(i * 8 + 7)]);
+ }
+ }
+#endif
+}
+
static int
r92c_get_power_group(struct rtwn_softc *sc, struct ieee80211_channel *c)
{
@@ -81,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;
@@ -94,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"));
@@ -149,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;
+
}
}
@@ -224,23 +284,32 @@
memset(power, 0, sizeof(power));
/* Compute per-rate Tx power values. */
rtwn_r92c_get_txpower(sc, i, c, power);
-#ifdef RTWN_DEBUG
- if (sc->sc_debug & RTWN_DEBUG_TXPWR) {
- int max_mcs, ridx;
-
- max_mcs = RTWN_RIDX_HT_MCS(sc->ntxchains * 8 - 1);
-
- /* Dump per-rate Tx power values. */
- printf("Tx power for chain %d:\n", i);
- for (ridx = RTWN_RIDX_CCK1; ridx <= max_mcs; ridx++)
- printf("Rate %d = %u\n", ridx, power[ridx]);
- }
-#endif
+ /* Optionally print out the power table */
+ r92c_dump_txpower(sc, i, power);
/* Write per-rate Tx power values to hardware. */
r92c_write_txpower(sc, i, power);
}
}
+/*
+ * 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;
+
+ pwr = power[ridx] + pwr_diff;
- for (ridx = RTWN_RIDX_OFDM6; ridx <= RTWN_RIDX_OFDM54; ridx++)
- 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 +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. */
@@ -132,15 +153,6 @@
if (power[ridx] > R92C_MAX_TX_PWR)
power[ridx] = R92C_MAX_TX_PWR;
}
-
-#ifdef RTWN_DEBUG
- if (sc->sc_debug & RTWN_DEBUG_TXPWR) {
- /* Dump per-rate Tx power values. */
- printf("Tx power for chain %d:\n", chain);
- for (ridx = RTWN_RIDX_CCK1; ridx < RTWN_RIDX_LEGACY_HT_COUNT; ridx++)
- printf("Rate %d = %u\n", ridx, power[ridx]);
- }
-#endif
}
static void
@@ -153,11 +165,26 @@
memset(power, 0, sizeof(power));
/* Compute per-rate Tx power values. */
r92e_get_txpower(sc, i, c, power);
+ /* Optionally print out the power table */
+ r92c_dump_txpower(sc, i, power);
/* Write per-rate Tx power values to hardware. */
r92c_write_txpower(sc, i, power);
}
}
+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,7 +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 = 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);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Mar 10, 6:10 PM (3 h, 38 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29504643
Default Alt Text
D47986.id148202.diff (12 KB)
Attached To
Mode
D47986: rtwn: refactor out the TX power register power dump, condense output
Attached
Detach File
Event Timeline
Log In to Comment