Lines 218-224
Link Here
|
218 |
static void wpi_power_calibration(struct wpi_softc *); |
218 |
static void wpi_power_calibration(struct wpi_softc *); |
219 |
static int wpi_set_txpower(struct wpi_softc *, int); |
219 |
static int wpi_set_txpower(struct wpi_softc *, int); |
220 |
static int wpi_get_power_index(struct wpi_softc *, |
220 |
static int wpi_get_power_index(struct wpi_softc *, |
221 |
struct wpi_power_group *, struct ieee80211_channel *, int); |
221 |
struct wpi_power_group *, uint8_t, int, int); |
222 |
static int wpi_set_pslevel(struct wpi_softc *, uint8_t, int, int); |
222 |
static int wpi_set_pslevel(struct wpi_softc *, uint8_t, int, int); |
223 |
static int wpi_send_btcoex(struct wpi_softc *); |
223 |
static int wpi_send_btcoex(struct wpi_softc *); |
224 |
static int wpi_send_rxon(struct wpi_softc *, int, int); |
224 |
static int wpi_send_rxon(struct wpi_softc *, int, int); |
Lines 3455-3473
Link Here
|
3455 |
static int |
3455 |
static int |
3456 |
wpi_set_txpower(struct wpi_softc *sc, int async) |
3456 |
wpi_set_txpower(struct wpi_softc *sc, int async) |
3457 |
{ |
3457 |
{ |
3458 |
struct ieee80211com *ic = sc->sc_ifp->if_l2com; |
|
|
3459 |
struct ieee80211_channel *ch; |
3460 |
struct wpi_power_group *group; |
3458 |
struct wpi_power_group *group; |
3461 |
struct wpi_cmd_txpower cmd; |
3459 |
struct wpi_cmd_txpower cmd; |
3462 |
uint8_t chan; |
3460 |
uint8_t chan; |
3463 |
int idx, i; |
3461 |
int idx, is_chan_5ghz, i; |
3464 |
|
3462 |
|
3465 |
/* Retrieve current channel from last RXON. */ |
3463 |
/* Retrieve current channel from last RXON. */ |
3466 |
chan = sc->rxon.chan; |
3464 |
chan = sc->rxon.chan; |
3467 |
ch = &ic->ic_channels[chan]; |
3465 |
is_chan_5ghz = (sc->rxon.flags & htole32(WPI_RXON_24GHZ)) == 0; |
3468 |
|
3466 |
|
3469 |
/* Find the TX power group to which this channel belongs. */ |
3467 |
/* Find the TX power group to which this channel belongs. */ |
3470 |
if (IEEE80211_IS_CHAN_5GHZ(ch)) { |
3468 |
if (is_chan_5ghz) { |
3471 |
for (group = &sc->groups[1]; group < &sc->groups[4]; group++) |
3469 |
for (group = &sc->groups[1]; group < &sc->groups[4]; group++) |
3472 |
if (chan <= group->chan) |
3470 |
if (chan <= group->chan) |
3473 |
break; |
3471 |
break; |
Lines 3475-3491
Link Here
|
3475 |
group = &sc->groups[0]; |
3473 |
group = &sc->groups[0]; |
3476 |
|
3474 |
|
3477 |
memset(&cmd, 0, sizeof cmd); |
3475 |
memset(&cmd, 0, sizeof cmd); |
3478 |
cmd.band = IEEE80211_IS_CHAN_5GHZ(ch) ? 0 : 1; |
3476 |
cmd.band = is_chan_5ghz ? WPI_BAND_5GHZ : WPI_BAND_2GHZ; |
3479 |
cmd.chan = htole16(chan); |
3477 |
cmd.chan = htole16(chan); |
3480 |
|
3478 |
|
3481 |
/* Set TX power for all OFDM and CCK rates. */ |
3479 |
/* Set TX power for all OFDM and CCK rates. */ |
3482 |
for (i = 0; i <= WPI_RIDX_MAX ; i++) { |
3480 |
for (i = 0; i <= WPI_RIDX_MAX ; i++) { |
3483 |
/* Retrieve TX power for this channel/rate. */ |
3481 |
/* Retrieve TX power for this channel/rate. */ |
3484 |
idx = wpi_get_power_index(sc, group, ch, i); |
3482 |
idx = wpi_get_power_index(sc, group, chan, is_chan_5ghz, i); |
3485 |
|
3483 |
|
3486 |
cmd.rates[i].plcp = wpi_ridx_to_plcp[i]; |
3484 |
cmd.rates[i].plcp = wpi_ridx_to_plcp[i]; |
3487 |
|
3485 |
|
3488 |
if (IEEE80211_IS_CHAN_5GHZ(ch)) { |
3486 |
if (is_chan_5ghz) { |
3489 |
cmd.rates[i].rf_gain = wpi_rf_gain_5ghz[idx]; |
3487 |
cmd.rates[i].rf_gain = wpi_rf_gain_5ghz[idx]; |
3490 |
cmd.rates[i].dsp_gain = wpi_dsp_gain_5ghz[idx]; |
3488 |
cmd.rates[i].dsp_gain = wpi_dsp_gain_5ghz[idx]; |
3491 |
} else { |
3489 |
} else { |
Lines 3506-3512
Link Here
|
3506 |
*/ |
3504 |
*/ |
3507 |
static int |
3505 |
static int |
3508 |
wpi_get_power_index(struct wpi_softc *sc, struct wpi_power_group *group, |
3506 |
wpi_get_power_index(struct wpi_softc *sc, struct wpi_power_group *group, |
3509 |
struct ieee80211_channel *c, int ridx) |
3507 |
uint8_t chan, int is_chan_5ghz, int ridx) |
3510 |
{ |
3508 |
{ |
3511 |
/* Fixed-point arithmetic division using a n-bit fractional part. */ |
3509 |
/* Fixed-point arithmetic division using a n-bit fractional part. */ |
3512 |
#define fdivround(a, b, n) \ |
3510 |
#define fdivround(a, b, n) \ |
Lines 3516-3529
Link Here
|
3516 |
#define interpolate(x, x1, y1, x2, y2, n) \ |
3514 |
#define interpolate(x, x1, y1, x2, y2, n) \ |
3517 |
((y1) + fdivround(((x) - (x1)) * ((y2) - (y1)), (x2) - (x1), n)) |
3515 |
((y1) + fdivround(((x) - (x1)) * ((y2) - (y1)), (x2) - (x1), n)) |
3518 |
|
3516 |
|
3519 |
struct ieee80211com *ic = sc->sc_ifp->if_l2com; |
|
|
3520 |
struct wpi_power_sample *sample; |
3517 |
struct wpi_power_sample *sample; |
3521 |
int pwr, idx; |
3518 |
int pwr, idx; |
3522 |
u_int chan; |
|
|
3523 |
|
3519 |
|
3524 |
/* Get channel number. */ |
|
|
3525 |
chan = ieee80211_chan2ieee(ic, c); |
3526 |
|
3527 |
/* Default TX power is group maximum TX power minus 3dB. */ |
3520 |
/* Default TX power is group maximum TX power minus 3dB. */ |
3528 |
pwr = group->maxpwr / 2; |
3521 |
pwr = group->maxpwr / 2; |
3529 |
|
3522 |
|
Lines 3530-3542
Link Here
|
3530 |
/* Decrease TX power for highest OFDM rates to reduce distortion. */ |
3523 |
/* Decrease TX power for highest OFDM rates to reduce distortion. */ |
3531 |
switch (ridx) { |
3524 |
switch (ridx) { |
3532 |
case WPI_RIDX_OFDM36: |
3525 |
case WPI_RIDX_OFDM36: |
3533 |
pwr -= IEEE80211_IS_CHAN_2GHZ(c) ? 0 : 5; |
3526 |
pwr -= is_chan_5ghz ? 5 : 0; |
3534 |
break; |
3527 |
break; |
3535 |
case WPI_RIDX_OFDM48: |
3528 |
case WPI_RIDX_OFDM48: |
3536 |
pwr -= IEEE80211_IS_CHAN_2GHZ(c) ? 7 : 10; |
3529 |
pwr -= is_chan_5ghz ? 10 : 7; |
3537 |
break; |
3530 |
break; |
3538 |
case WPI_RIDX_OFDM54: |
3531 |
case WPI_RIDX_OFDM54: |
3539 |
pwr -= IEEE80211_IS_CHAN_2GHZ(c) ? 9 : 12; |
3532 |
pwr -= is_chan_5ghz ? 12 : 9; |
3540 |
break; |
3533 |
break; |
3541 |
} |
3534 |
} |
3542 |
|
3535 |
|