mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-22 15:02:32 +00:00
26099a3c23
SVN-Revision: 16224
248 lines
9.1 KiB
Diff
248 lines
9.1 KiB
Diff
--- a/net80211/ieee80211.c
|
|
+++ b/net80211/ieee80211.c
|
|
@@ -270,6 +270,7 @@ ieee80211_ifattach(struct ieee80211com *
|
|
("invalid number of channels specified: %u", ic->ic_nchans));
|
|
memset(ic->ic_chan_avail, 0, sizeof(ic->ic_chan_avail));
|
|
ic->ic_modecaps |= 1 << IEEE80211_MODE_AUTO;
|
|
+ ic->ic_max_txpower = IEEE80211_TXPOWER_MIN;
|
|
|
|
for (i = 0; i < ic->ic_nchans; i++) {
|
|
c = &ic->ic_channels[i];
|
|
@@ -277,6 +278,7 @@ ieee80211_ifattach(struct ieee80211com *
|
|
KASSERT(c->ic_ieee < IEEE80211_CHAN_MAX,
|
|
("channel with bogus ieee number %u", c->ic_ieee));
|
|
setbit(ic->ic_chan_avail, c->ic_ieee);
|
|
+ ic->ic_max_txpower = max(ic->ic_max_txpower, (u16) c->ic_maxpower * 2);
|
|
|
|
if (c->ic_scanflags & IEEE80211_NOSCAN_DEFAULT)
|
|
c->ic_scanflags |= IEEE80211_NOSCAN_SET;
|
|
@@ -346,8 +348,6 @@ ieee80211_ifattach(struct ieee80211com *
|
|
TAILQ_INIT(&ic->ic_vaps);
|
|
|
|
ic->ic_txpowlimit = IEEE80211_TXPOWER_MAX;
|
|
- ic->ic_txpowlimit = IEEE80211_TXPOWER_MIN;
|
|
- ic->ic_newtxpowlimit = IEEE80211_TXPOWER_MAX;
|
|
|
|
init_timer(&ic->ic_dfs_excl_timer);
|
|
ic->ic_dfs_excl_timer.function =
|
|
--- a/net80211/ieee80211_node.c
|
|
+++ b/net80211/ieee80211_node.c
|
|
@@ -1125,7 +1125,7 @@ ieee80211_alloc_node(struct ieee80211vap
|
|
|
|
ni->ni_chan = IEEE80211_CHAN_ANYC;
|
|
ni->ni_authmode = IEEE80211_AUTH_OPEN;
|
|
- ni->ni_txpower = ic->ic_txpowlimit;
|
|
+ ni->ni_txpower = IEEE80211_TXPOWER_MAX;
|
|
|
|
ieee80211_crypto_resetkey(vap, &ni->ni_ucastkey,
|
|
IEEE80211_KEYIX_NONE);
|
|
--- a/net80211/ieee80211_var.h
|
|
+++ b/net80211/ieee80211_var.h
|
|
@@ -343,8 +343,9 @@ struct ieee80211com {
|
|
u_int16_t ic_holdover; /* PM hold over duration */
|
|
u_int16_t ic_bmissthreshold; /* beacon miss threshold (# beacons) */
|
|
unsigned long ic_bmiss_guard; /* when to cease ignoring bmiss (jiffies) */
|
|
- u_int16_t ic_txpowlimit; /* global tx power limit (in 0.5 dBm) */
|
|
- u_int16_t ic_newtxpowlimit; /* tx power limit to change to (in 0.5 dBm) */
|
|
+ u_int16_t ic_txpowlimit; /* configured global tx power limit (in 0.5 dBm) */
|
|
+ u_int16_t ic_max_txpower; /* global hardware tx power limit */
|
|
+ u_int16_t ic_cur_txpower; /* current tx power */
|
|
u_int16_t ic_uapsdmaxtriggers; /* max triggers that could arrive */
|
|
u_int8_t ic_coverageclass; /* coverage class */
|
|
u_int8_t ic_protmode_rssi; /* rssi threshold for protection mode */
|
|
--- a/net80211/ieee80211_wireless.c
|
|
+++ b/net80211/ieee80211_wireless.c
|
|
@@ -920,17 +920,23 @@ ieee80211_ioctl_giwrange(struct net_devi
|
|
u_int8_t reported[IEEE80211_CHAN_BYTES]; /* XXX stack usage? */
|
|
int i, r;
|
|
int step = 0;
|
|
+ u_int16_t power;
|
|
|
|
data->length = sizeof(struct iw_range);
|
|
memset(range, 0, sizeof(struct iw_range));
|
|
|
|
+ power = ic->ic_max_txpower;
|
|
+ if (ic->ic_bsschan && (ic->ic_bsschan != IEEE80211_CHAN_ANYC))
|
|
+ power = min(power, (u_int16_t) ic->ic_bsschan->ic_maxpower);
|
|
+
|
|
/* txpower (128 values, but will print out only IW_MAX_TXPOWER) */
|
|
- range->num_txpower = (ic->ic_txpowlimit >= 8) ? IW_MAX_TXPOWER : ic->ic_txpowlimit;
|
|
- step = ic->ic_txpowlimit / (2 * (IW_MAX_TXPOWER - 1));
|
|
+ power /= 2; /* Unit: 0.5 dBm */
|
|
+ range->num_txpower = (power >= 8) ? IW_MAX_TXPOWER : power;
|
|
+ step = power / (IW_MAX_TXPOWER - 1);
|
|
|
|
range->txpower[0] = 0;
|
|
for (i = 1; i < IW_MAX_TXPOWER; i++)
|
|
- range->txpower[i] = (ic->ic_txpowlimit/2)
|
|
+ range->txpower[i] = power
|
|
- (IW_MAX_TXPOWER - i - 1) * step;
|
|
|
|
range->txpower_capa = IW_TXPOW_DBM;
|
|
@@ -1379,13 +1385,11 @@ ieee80211_ioctl_siwtxpow(struct net_devi
|
|
int fixed, disabled;
|
|
|
|
fixed = (ic->ic_flags & IEEE80211_F_TXPOW_FIXED);
|
|
- disabled = (fixed && vap->iv_bss->ni_txpower == 0);
|
|
+ disabled = (fixed && ic->ic_txpowlimit == 0);
|
|
if (rrq->disabled) {
|
|
if (!disabled) {
|
|
- if ((ic->ic_caps & IEEE80211_C_TXPMGT) == 0)
|
|
- return -EOPNOTSUPP;
|
|
ic->ic_flags |= IEEE80211_F_TXPOW_FIXED;
|
|
- vap->iv_bss->ni_txpower = 0;
|
|
+ ic->ic_txpowlimit = 0;
|
|
goto done;
|
|
}
|
|
return 0;
|
|
@@ -1396,30 +1400,12 @@ ieee80211_ioctl_siwtxpow(struct net_devi
|
|
return -EOPNOTSUPP;
|
|
if (rrq->flags != IW_TXPOW_DBM)
|
|
return -EINVAL;
|
|
- if (ic->ic_bsschan != IEEE80211_CHAN_ANYC) {
|
|
- if ((ic->ic_bsschan->ic_maxregpower >= rrq->value) &&
|
|
- (ic->ic_txpowlimit/2 >= rrq->value)) {
|
|
- vap->iv_bss->ni_txpower = 2 * rrq->value;
|
|
- ic->ic_newtxpowlimit = 2 * rrq->value;
|
|
- ic->ic_flags |= IEEE80211_F_TXPOW_FIXED;
|
|
- } else
|
|
- return -EINVAL;
|
|
- } else {
|
|
- /*
|
|
- * No channel set yet
|
|
- */
|
|
- if (ic->ic_txpowlimit/2 >= rrq->value) {
|
|
- vap->iv_bss->ni_txpower = 2 * rrq->value;
|
|
- ic->ic_newtxpowlimit = 2 * rrq->value;
|
|
- ic->ic_flags |= IEEE80211_F_TXPOW_FIXED;
|
|
- }
|
|
- else
|
|
- return -EINVAL;
|
|
- }
|
|
+ ic->ic_txpowlimit = 2 * rrq->value;
|
|
+ ic->ic_flags |= IEEE80211_F_TXPOW_FIXED;
|
|
} else {
|
|
if (!fixed) /* no change */
|
|
return 0;
|
|
- ic->ic_newtxpowlimit = IEEE80211_TXPOWER_MAX;
|
|
+ ic->ic_txpowlimit = IEEE80211_TXPOWER_MAX;
|
|
ic->ic_flags &= ~IEEE80211_F_TXPOW_FIXED;
|
|
}
|
|
done:
|
|
@@ -1588,9 +1574,22 @@ ieee80211_ioctl_giwtxpow(struct net_devi
|
|
{
|
|
struct ieee80211vap *vap = dev->priv;
|
|
struct ieee80211com *ic = vap->iv_ic;
|
|
-
|
|
- rrq->value = vap->iv_bss->ni_txpower / 2;
|
|
- rrq->fixed = (ic->ic_flags & IEEE80211_F_TXPOW_FIXED) != 0;
|
|
+ unsigned int power = ic->ic_txpowlimit;
|
|
+ struct ieee80211_channel *c;
|
|
+ u_int16_t txp = ic->ic_max_txpower;
|
|
+
|
|
+ if (ic->ic_bsschan && (ic->ic_bsschan != IEEE80211_CHAN_ANYC)) {
|
|
+ txp = min(txp, (u16) ic->ic_bsschan->ic_maxpower);
|
|
+ } else if (ic->ic_cur_txpower > 0) {
|
|
+ txp = min(txp, ic->ic_cur_txpower);
|
|
+ }
|
|
+ if (ic->ic_flags & IEEE80211_F_TXPOW_FIXED) {
|
|
+ txp = min(txp, ic->ic_txpowlimit);
|
|
+ rrq->fixed = 1;
|
|
+ } else {
|
|
+ rrq->fixed = 0;
|
|
+ }
|
|
+ rrq->value = txp / 2;
|
|
rrq->disabled = (rrq->fixed && rrq->value == 0);
|
|
rrq->flags = IW_TXPOW_DBM;
|
|
return 0;
|
|
--- a/ath/if_ath.c
|
|
+++ b/ath/if_ath.c
|
|
@@ -380,7 +380,6 @@ static unsigned int ath_dump_hal_map(str
|
|
static u_int32_t ath_get_clamped_maxtxpower(struct ath_softc *sc);
|
|
static u_int32_t ath_set_clamped_maxtxpower(struct ath_softc *sc,
|
|
u_int32_t new_clamped_maxtxpower);
|
|
-static u_int32_t ath_get_real_maxtxpower(struct ath_softc *sc);
|
|
|
|
static void ath_poll_disable(struct net_device *dev);
|
|
static void ath_poll_enable(struct net_device *dev);
|
|
@@ -3168,7 +3167,7 @@ ath_tx_startraw(struct net_device *dev,
|
|
try0 = ph->try0;
|
|
rt = sc->sc_currates;
|
|
txrate = dot11_to_ratecode(sc, rt, ph->rate0);
|
|
- power = ph->power > 60 ? 60 : ph->power;
|
|
+ power = ph->power > 63 ? 63 : ph->power;
|
|
hdrlen = ieee80211_anyhdrsize(wh);
|
|
pktlen = skb->len + IEEE80211_CRC_LEN;
|
|
|
|
@@ -8390,7 +8389,7 @@ ath_tx_start(struct net_device *dev, str
|
|
pktlen, /* packet length */
|
|
hdrlen, /* header length */
|
|
atype, /* Atheros packet type */
|
|
- MIN(ni->ni_txpower, 60), /* txpower */
|
|
+ MIN(ni->ni_txpower, 63), /* txpower */
|
|
txrate, try0, /* series 0 rate/tries */
|
|
keyix, /* key cache index */
|
|
antenna, /* antenna mode */
|
|
@@ -10383,59 +10382,16 @@ ath_get_clamped_maxtxpower(struct ath_so
|
|
|
|
/* XXX: this function needs some locking to avoid being called
|
|
* twice/interrupted */
|
|
-/* 1. Save the currently specified maximum txpower (as clamped by madwifi)
|
|
- * 2. Determine the real maximum txpower the card can support by
|
|
- * setting a value that exceeds the maximum range (by one) and
|
|
- * finding out what it limits us to.
|
|
- * 3. Restore the saved maxtxpower value we had previously specified */
|
|
-static u_int32_t
|
|
-ath_get_real_maxtxpower(struct ath_softc *sc)
|
|
-{
|
|
- u_int32_t saved_clamped_maxtxpower;
|
|
- u_int32_t real_maxtxpower;
|
|
-
|
|
- saved_clamped_maxtxpower = ath_get_clamped_maxtxpower(sc);
|
|
- real_maxtxpower =
|
|
- ath_set_clamped_maxtxpower(sc, IEEE80211_TXPOWER_MAX + 1);
|
|
- ath_set_clamped_maxtxpower(sc, saved_clamped_maxtxpower);
|
|
- return real_maxtxpower;
|
|
-}
|
|
-
|
|
-
|
|
-/* XXX: this function needs some locking to avoid being called
|
|
- * twice/interrupted */
|
|
static void
|
|
ath_update_txpow(struct ath_softc *sc)
|
|
{
|
|
struct ieee80211com *ic = &sc->sc_ic;
|
|
struct ieee80211vap *vap = NULL;
|
|
struct ath_hal *ah = sc->sc_ah;
|
|
- u_int32_t prev_clamped_maxtxpower = 0;
|
|
- u_int32_t new_clamped_maxtxpower = 0;
|
|
|
|
/* Determine the previous value of maxtxpower */
|
|
- prev_clamped_maxtxpower = ath_get_clamped_maxtxpower(sc);
|
|
- /* Determine the real maximum txpower the card can support */
|
|
- ic->ic_txpowlimit = ath_get_real_maxtxpower(sc);
|
|
- /* Grab the new maxtxpower setting (which may have changed) */
|
|
- new_clamped_maxtxpower = ic->ic_newtxpowlimit;
|
|
- /* Make sure the change is within limits, clamp it otherwise */
|
|
- if (ic->ic_newtxpowlimit > ic->ic_txpowlimit)
|
|
- new_clamped_maxtxpower = ic->ic_txpowlimit;
|
|
- /* Search for the VAP that needs a txpow change, if any */
|
|
- TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
|
|
- if (!tpc || ic->ic_newtxpowlimit != vap->iv_bss->ni_txpower) {
|
|
- vap->iv_bss->ni_txpower = new_clamped_maxtxpower;
|
|
- ieee80211_iterate_nodes(&vap->iv_ic->ic_sta,
|
|
- set_node_txpower,
|
|
- &new_clamped_maxtxpower);
|
|
- }
|
|
- }
|
|
-
|
|
- /* Store the assigned (clamped) maximum txpower and update the HAL */
|
|
- sc->sc_curtxpow = new_clamped_maxtxpower;
|
|
- if (new_clamped_maxtxpower != prev_clamped_maxtxpower)
|
|
- ath_hal_settxpowlimit(ah, new_clamped_maxtxpower);
|
|
+ ath_set_clamped_maxtxpower(sc, ic->ic_txpowlimit);
|
|
+ ic->ic_cur_txpower = ath_get_clamped_maxtxpower(sc);
|
|
}
|
|
|
|
#ifdef ATH_SUPERG_XR
|