summaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/pci')
-rw-r--r--sys/dev/pci/if_iwn.c135
-rw-r--r--sys/dev/pci/if_iwnreg.h39
-rw-r--r--sys/dev/pci/if_iwnvar.h3
-rw-r--r--sys/dev/pci/if_wpi.c137
-rw-r--r--sys/dev/pci/if_wpireg.h52
-rw-r--r--sys/dev/pci/if_wpivar.h3
6 files changed, 175 insertions, 194 deletions
diff --git a/sys/dev/pci/if_iwn.c b/sys/dev/pci/if_iwn.c
index ec64696a45a..ece39020c5e 100644
--- a/sys/dev/pci/if_iwn.c
+++ b/sys/dev/pci/if_iwn.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_iwn.c,v 1.31 2008/11/08 18:42:50 damien Exp $ */
+/* $OpenBSD: if_iwn.c,v 1.32 2008/11/09 10:00:17 damien Exp $ */
/*-
* Copyright (c) 2007, 2008
@@ -144,7 +144,6 @@ void iwn4965_update_sched(struct iwn_softc *, int, int, uint8_t,
void iwn5000_update_sched(struct iwn_softc *, int, int, uint8_t,
uint16_t);
void iwn5000_reset_sched(struct iwn_softc *, int, int);
-uint8_t iwn_plcp_signal(int);
int iwn_tx(struct iwn_softc *, struct mbuf *,
struct ieee80211_node *);
void iwn_start(struct ifnet *);
@@ -1334,15 +1333,23 @@ void
iwn_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni, int isnew)
{
struct iwn_softc *sc = ic->ic_if.if_softc;
- int i;
+ struct iwn_node *wn = (void *)ni;
+ uint8_t rate;
+ int ridx, i;
- ieee80211_amrr_node_init(&sc->amrr, &((struct iwn_node *)ni)->amn);
+ ieee80211_amrr_node_init(&sc->amrr, &wn->amn);
- /* Set rate to some reasonable initial value. */
- for (i = ni->ni_rates.rs_nrates - 1;
- i > 0 && (ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL) > 72;
- i--);
- ni->ni_txrate = i;
+ for (i = 0; i < ni->ni_rates.rs_nrates; i++) {
+ rate = ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL;
+ /* Map 802.11 rate to HW rate index. */
+ for (ridx = 0; ridx <= IWN_RIDX_MAX; ridx++)
+ if (iwn_rates[ridx].rate == rate)
+ break;
+ wn->ridx[i] = ridx;
+ /* Initial TX rate <= 24Mbps. */
+ if (rate <= 48)
+ ni->ni_txrate = i;
+ }
}
int
@@ -2221,54 +2228,27 @@ iwn5000_reset_sched(struct iwn_softc *sc, int qid, int idx)
*(w + IWN_TX_RING_COUNT) = *w;
}
-uint8_t
-iwn_plcp_signal(int rate)
-{
- switch (rate) {
- /* CCK rates (returned values are device-dependent.) */
- case 2: return 10;
- case 4: return 20;
- case 11: return 55;
- case 22: return 110;
-
- /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80.) */
- /* R1-R4, (u)ral is R4-R1 */
- case 12: return 0xd;
- case 18: return 0xf;
- case 24: return 0x5;
- case 36: return 0x7;
- case 48: return 0x9;
- case 72: return 0xb;
- case 96: return 0x1;
- case 108: return 0x3;
- case 120: return 0x3;
- }
- /* Unknown rate (should not get there.) */
- return 0;
-}
-
-/* Determine if a given rate is CCK or OFDM. */
-#define IWN_RATE_IS_OFDM(rate) ((rate) >= 12 && (rate) != 22)
-
int
iwn_tx(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
{
const struct iwn_hal *hal = sc->sc_hal;
struct ieee80211com *ic = &sc->sc_ic;
+ struct iwn_node *wn = (void *)ni;
struct iwn_tx_ring *ring;
struct iwn_tx_desc *desc;
struct iwn_tx_data *data;
struct iwn_tx_cmd *cmd;
struct iwn_cmd_data *tx;
+ const struct iwn_rate *rinfo;
struct ieee80211_frame *wh;
struct ieee80211_key *k = NULL;
enum ieee80211_edca_ac ac;
struct mbuf *m1;
uint32_t flags;
uint16_t qos;
- uint8_t *ivp, tid, txant, type;
u_int hdrlen;
- int i, totlen, hasqos, rate, error, pad;
+ uint8_t *ivp, tid, ridx, txant, type;
+ int i, totlen, hasqos, error, pad;
wh = mtod(m, struct ieee80211_frame *);
hdrlen = ieee80211_get_hdrlen(wh);
@@ -2288,16 +2268,14 @@ iwn_tx(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
desc = &ring->desc[ring->cur];
data = &ring->data[ring->cur];
- /* Chose a TX rate. */
+ /* Chose a TX rate index. */
if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
type != IEEE80211_FC0_TYPE_DATA) {
- rate = ni->ni_rates.rs_rates[0];
- } else if (ic->ic_fixed_rate != -1) {
- rate = ic->ic_sup_rates[ic->ic_curmode].
- rs_rates[ic->ic_fixed_rate];
+ ridx = (ic->ic_curmode == IEEE80211_MODE_11A) ?
+ IWN_RIDX_OFDM6 : IWN_RIDX_CCK1;
} else
- rate = ni->ni_rates.rs_rates[ni->ni_txrate];
- rate &= IEEE80211_RATE_VAL;
+ ridx = wn->ridx[ni->ni_txrate];
+ rinfo = &iwn_rates[ridx];
#if NBPFILTER > 0
if (sc->sc_drvbpf != NULL) {
@@ -2307,7 +2285,7 @@ iwn_tx(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
tap->wt_flags = 0;
tap->wt_chan_freq = htole16(ni->ni_chan->ic_freq);
tap->wt_chan_flags = htole16(ni->ni_chan->ic_flags);
- tap->wt_rate = rate;
+ tap->wt_rate = rinfo->rate;
tap->wt_hwqueue = ac;
if ((ic->ic_flags & IEEE80211_F_WEPON) &&
(wh->i_fc[1] & IEEE80211_FC1_PROTECTED))
@@ -2374,7 +2352,7 @@ iwn_tx(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
if (totlen + IEEE80211_CRC_LEN > ic->ic_rtsthreshold) {
flags |= IWN_TX_NEED_RTS;
} else if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
- IWN_RATE_IS_OFDM(rate)) {
+ ridx >= IWN_RIDX_OFDM6) {
if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
flags |= IWN_TX_NEED_CTS;
else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
@@ -2394,7 +2372,7 @@ iwn_tx(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
type != IEEE80211_FC0_TYPE_DATA)
tx->id = hal->broadcast_id;
else
- tx->id = ((struct iwn_node *)ni)->id;
+ tx->id = wn->id;
if (type == IEEE80211_FC0_TYPE_MGT) {
uint8_t subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
@@ -2424,20 +2402,17 @@ iwn_tx(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
tx->rts_ntries = 60;
tx->data_ntries = 15;
tx->lifetime = htole32(IWN_LIFETIME_INFINITE);
- tx->rate = iwn_plcp_signal(rate);
- tx->rflags = 0;
- if (!IWN_RATE_IS_OFDM(rate))
- tx->rflags |= IWN_RFLAG_CCK;
+ tx->plcp = rinfo->plcp;
+ tx->rflags = rinfo->flags;
if (tx->id == hal->broadcast_id) {
/* Group or management frame. */
- tx->ridx = IWN_MAX_TX_RETRIES - 1;
+ tx->linkq = 0;
/* XXX Alternate between antenna A and B? */
txant = IWN_LSB(sc->txantmsk);
tx->rflags |= IWN_RFLAG_ANT(txant);
} else {
- tx->ridx = ni->ni_rates.rs_nrates - ni->ni_txrate - 1;
- /* Tell adapter to ignore rflags. */
- flags |= IWN_TX_MRR_INDEX;
+ tx->linkq = ni->ni_rates.rs_nrates - ni->ni_txrate - 1;
+ flags |= IWN_TX_LINKQ; /* enable MRR */
}
/* Set physical address of "scratch area". */
tx->loaddr = htole32(data->scratch_paddr);
@@ -2785,8 +2760,9 @@ iwn_set_link_quality(struct iwn_softc *sc, struct ieee80211_node *ni)
struct iwn_node *wn = (void *)ni;
struct ieee80211_rateset *rs = &ni->ni_rates;
struct iwn_cmd_link_quality linkq;
+ const struct iwn_rate *rinfo;
uint8_t txant, rate;
- int i, ridx;
+ int i, txrate;
/* Use the first valid TX antenna. */
txant = IWN_LSB(sc->txantmsk);
@@ -2800,17 +2776,16 @@ iwn_set_link_quality(struct iwn_softc *sc, struct ieee80211_node *ni)
linkq.ampdu_limit = htole16(4000); /* 4ms */
/* Start at highest available bit-rate. */
- ridx = rs->rs_nrates - 1;
+ txrate = rs->rs_nrates - 1;
for (i = 0; i < IWN_MAX_TX_RETRIES; i++) {
- rate = rs->rs_rates[ridx] & IEEE80211_RATE_VAL;
- DPRINTF(("retry %d, rate %d\n", i, rate));
- linkq.retry[i].rate = iwn_plcp_signal(rate);
- linkq.retry[i].rflags = IWN_RFLAG_ANT(txant);
- if (!IWN_RATE_IS_OFDM(rate))
- linkq.retry[i].rflags |= IWN_RFLAG_CCK;
+ rate = rs->rs_rates[txrate] & IEEE80211_RATE_VAL;
+ rinfo = &iwn_rates[wn->ridx[txrate]];
+ linkq.retry[i].plcp = rinfo->plcp;
+ linkq.retry[i].rflags = rinfo->flags;
+ linkq.retry[i].rflags |= IWN_RFLAG_ANT(txant);
/* Next retry at immediate lower bit-rate. */
- if (ridx > 0)
- ridx--;
+ if (txrate > 0)
+ txrate--;
}
return iwn_cmd(sc, IWN_CMD_LINK_QUALITY, &linkq, sizeof linkq, 1);
}
@@ -2824,6 +2799,7 @@ iwn_add_broadcast_node(struct iwn_softc *sc, int async)
const struct iwn_hal *hal = sc->sc_hal;
struct iwn_node_info node;
struct iwn_cmd_link_quality linkq;
+ const struct iwn_rate *rinfo;
uint8_t txant;
int i, error;
@@ -2846,15 +2822,14 @@ iwn_add_broadcast_node(struct iwn_softc *sc, int async)
linkq.ampdu_limit = htole16(4000); /* 4ms */
/* Use lowest mandatory bit-rate. */
- if (sc->sc_ic.ic_curmode != IEEE80211_MODE_11A) {
- linkq.retry[0].rate = iwn_ridx_to_plcp[IWN_CCK1];
- linkq.retry[0].rflags = IWN_RFLAG_CCK;
- } else
- linkq.retry[0].rate = iwn_ridx_to_plcp[IWN_OFDM6];
+ rinfo = (sc->sc_ic.ic_curmode != IEEE80211_MODE_11A) ?
+ &iwn_rates[IWN_RIDX_CCK1] : &iwn_rates[IWN_RIDX_OFDM6];
+ linkq.retry[0].plcp = rinfo->plcp;
+ linkq.retry[0].rflags = rinfo->flags;
linkq.retry[0].rflags |= IWN_RFLAG_ANT(txant);
/* Use same bit-rate for all TX retries. */
for (i = 1; i < IWN_MAX_TX_RETRIES; i++) {
- linkq.retry[i].rate = linkq.retry[0].rate;
+ linkq.retry[i].plcp = linkq.retry[0].plcp;
linkq.retry[i].rflags = linkq.retry[0].rflags;
}
return iwn_cmd(sc, IWN_CMD_LINK_QUALITY, &linkq, sizeof linkq, async);
@@ -3752,12 +3727,12 @@ iwn_scan(struct iwn_softc *sc, uint16_t flags)
if (flags & IEEE80211_CHAN_5GHZ) {
hdr->crc_threshold = htole16(1);
/* Send probe requests at 6Mbps. */
- tx->rate = iwn_ridx_to_plcp[IWN_OFDM6];
+ tx->plcp = iwn_rates[IWN_RIDX_OFDM6].plcp;
rs = &ic->ic_sup_rates[IEEE80211_MODE_11A];
} else {
hdr->flags = htole32(IWN_RXON_24GHZ | IWN_RXON_AUTO);
/* Send probe requests at 1Mbps. */
- tx->rate = iwn_ridx_to_plcp[IWN_CCK1];
+ tx->plcp = iwn_rates[IWN_RIDX_CCK1].plcp;
tx->rflags = IWN_RFLAG_CCK;
rs = &ic->ic_sup_rates[IEEE80211_MODE_11G];
}
@@ -3928,8 +3903,11 @@ iwn_run(struct iwn_softc *sc)
return error;
}
- /* Add BSS node. */
+ /* Fake a join to initialize the TX rate. */
((struct iwn_node *)ni)->id = IWN_ID_BSS;
+ iwn_newassoc(ic, ni, 1);
+
+ /* Add BSS node. */
memset(&node, 0, sizeof node);
IEEE80211_ADDR_COPY(node.macaddr, ni->ni_macaddr);
node.id = IWN_ID_BSS;
@@ -3950,9 +3928,6 @@ iwn_run(struct iwn_softc *sc)
return error;
}
- /* Fake a join to initialize the TX rate. */
- iwn_newassoc(ic, ni, 1);
-
if ((error = iwn_init_sensitivity(sc)) != 0) {
printf("%s: could not set sensitivity\n",
sc->sc_dev.dv_xname);
diff --git a/sys/dev/pci/if_iwnreg.h b/sys/dev/pci/if_iwnreg.h
index 3915d5cf3b9..509e44ed979 100644
--- a/sys/dev/pci/if_iwnreg.h
+++ b/sys/dev/pci/if_iwnreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_iwnreg.h,v 1.14 2008/11/08 11:05:36 damien Exp $ */
+/* $OpenBSD: if_iwnreg.h,v 1.15 2008/11/09 10:00:17 damien Exp $ */
/*-
* Copyright (c) 2007, 2008
@@ -586,7 +586,7 @@ struct iwn_cmd_data {
#define IWN_TX_NEED_RTS (1 << 1)
#define IWN_TX_NEED_CTS (1 << 2)
#define IWN_TX_NEED_ACK (1 << 3)
-#define IWN_TX_MRR_INDEX (1 << 4)
+#define IWN_TX_LINKQ (1 << 4)
#define IWN_TX_IMM_BA (1 << 6)
#define IWN_TX_FULL_TXOP (1 << 7)
#define IWN_TX_BT_DISABLE (1 << 12) /* bluetooth coexistence */
@@ -596,7 +596,7 @@ struct iwn_cmd_data {
#define IWN_TX_NEED_PADDING (1 << 20)
uint32_t scratch;
- uint8_t rate;
+ uint8_t plcp;
uint8_t rflags;
uint16_t xrflags;
@@ -607,7 +607,7 @@ struct iwn_cmd_data {
#define IWN_CIPHER_TKIP 3
#define IWN_CIPHER_WEP104 9
- uint8_t ridx;
+ uint8_t linkq;
uint8_t reserved2;
uint8_t key[16];
uint16_t fnext;
@@ -640,13 +640,9 @@ struct iwn_cmd_link_quality {
uint8_t ampdu_max;
uint32_t reserved2;
struct {
- uint8_t rate;
+ uint8_t plcp;
uint8_t rflags;
uint16_t xrflags;
-#define IWN_CCK1 0
-#define IWN_CCK11 3
-#define IWN_OFDM6 4
-#define IWN_OFDM54 11
} __packed retry[IWN_MAX_TX_RETRIES];
uint32_t reserved3;
} __packed;
@@ -1299,9 +1295,28 @@ static const struct iwn_chan_band {
{ 11, { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157 } }
};
-static const uint8_t iwn_ridx_to_plcp[] = {
- 10, 20, 55, 110, /* CCK */
- 0xd, 0xf, 0x5, 0x7, 0x9, 0xb, 0x1, 0x3, 0x3 /* OFDM R1-R4 */
+/* HW rate indices. */
+#define IWN_RIDX_CCK1 0
+#define IWN_RIDX_OFDM6 4
+
+static const struct iwn_rate {
+ uint8_t rate;
+ uint8_t plcp;
+ uint8_t flags;
+} iwn_rates[IWN_RIDX_MAX + 1] = {
+ { 2, 10, IWN_RFLAG_CCK },
+ { 4, 20, IWN_RFLAG_CCK },
+ { 11, 55, IWN_RFLAG_CCK },
+ { 22, 110, IWN_RFLAG_CCK },
+ { 12, 0xd, 0 },
+ { 18, 0xf, 0 },
+ { 24, 0x5, 0 },
+ { 36, 0x7, 0 },
+ { 48, 0x9, 0 },
+ { 72, 0xb, 0 },
+ { 96, 0x1, 0 },
+ { 108, 0x3, 0 },
+ { 120, 0x3, 0 }
};
#define IWN4965_MAX_PWR_INDEX 107
diff --git a/sys/dev/pci/if_iwnvar.h b/sys/dev/pci/if_iwnvar.h
index 70c155f02ea..c7e5996a50e 100644
--- a/sys/dev/pci/if_iwnvar.h
+++ b/sys/dev/pci/if_iwnvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_iwnvar.h,v 1.4 2008/10/22 06:25:07 damien Exp $ */
+/* $OpenBSD: if_iwnvar.h,v 1.5 2008/11/09 10:00:17 damien Exp $ */
/*-
* Copyright (c) 2007, 2008
@@ -111,6 +111,7 @@ struct iwn_node {
struct ieee80211_amrr_node amn;
uint16_t disable_tid;
uint8_t id;
+ uint8_t ridx[IEEE80211_RATE_MAXSIZE];
};
struct iwn_calib_state {
diff --git a/sys/dev/pci/if_wpi.c b/sys/dev/pci/if_wpi.c
index 8f329f6a1ad..7129ca1f9d3 100644
--- a/sys/dev/pci/if_wpi.c
+++ b/sys/dev/pci/if_wpi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_wpi.c,v 1.70 2008/11/09 09:55:42 chl Exp $ */
+/* $OpenBSD: if_wpi.c,v 1.71 2008/11/09 10:00:17 damien Exp $ */
/*-
* Copyright (c) 2006-2008
@@ -118,7 +118,6 @@ void wpi_cmd_done(struct wpi_softc *, struct wpi_rx_desc *);
void wpi_notif_intr(struct wpi_softc *);
void wpi_fatal_intr(struct wpi_softc *);
int wpi_intr(void *);
-uint8_t wpi_plcp_signal(int);
int wpi_tx(struct wpi_softc *, struct mbuf *,
struct ieee80211_node *);
void wpi_start(struct ifnet *);
@@ -1008,15 +1007,23 @@ void
wpi_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni, int isnew)
{
struct wpi_softc *sc = ic->ic_if.if_softc;
- int i;
+ struct wpi_node *wn = (void *)ni;
+ uint8_t rate;
+ int ridx, i;
- ieee80211_amrr_node_init(&sc->amrr, &((struct wpi_node *)ni)->amn);
+ ieee80211_amrr_node_init(&sc->amrr, &wn->amn);
- /* Set rate to some reasonable initial value. */
- for (i = ni->ni_rates.rs_nrates - 1;
- i > 0 && (ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL) > 72;
- i--);
- ni->ni_txrate = i;
+ for (i = 0; i < ni->ni_rates.rs_nrates; i++) {
+ rate = ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL;
+ /* Map 802.11 rate to HW rate index. */
+ for (ridx = 0; ridx <= WPI_RIDX_MAX; ridx++)
+ if (wpi_rates[ridx].rate == rate)
+ break;
+ wn->ridx[i] = ridx;
+ /* Initial TX rate <= 24Mbps. */
+ if (rate <= 48)
+ ni->ni_txrate = i;
+ }
}
int
@@ -1617,53 +1624,26 @@ wpi_intr(void *arg)
return 1;
}
-uint8_t
-wpi_plcp_signal(int rate)
-{
- switch (rate) {
- /* CCK rates (returned values are device-dependent) */
- case 2: return 10;
- case 4: return 20;
- case 11: return 55;
- case 22: return 110;
-
- /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
- /* R1-R4, (u)ral is R4-R1 */
- case 12: return 0xd;
- case 18: return 0xf;
- case 24: return 0x5;
- case 36: return 0x7;
- case 48: return 0x9;
- case 72: return 0xb;
- case 96: return 0x1;
- case 108: return 0x3;
-
- /* Unsupported rates (should not get there.) */
- default: return 0;
- }
-}
-
-/* Determine if a given rate is CCK or OFDM. */
-#define WPI_RATE_IS_OFDM(rate) ((rate) >= 12 && (rate) != 22)
-
int
wpi_tx(struct wpi_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
{
struct ieee80211com *ic = &sc->sc_ic;
+ struct wpi_node *wn = (void *)ni;
struct wpi_tx_ring *ring;
struct wpi_tx_desc *desc;
struct wpi_tx_data *data;
struct wpi_tx_cmd *cmd;
struct wpi_cmd_data *tx;
+ const struct wpi_rate *rinfo;
struct ieee80211_frame *wh;
struct ieee80211_key *k = NULL;
enum ieee80211_edca_ac ac;
struct mbuf *m1;
uint32_t flags;
uint16_t qos;
- uint8_t *ivp, tid, type;
u_int hdrlen;
- int i, totlen, hasqos, rate, error;
+ uint8_t *ivp, tid, ridx, type;
+ int i, totlen, hasqos, error;
wh = mtod(m, struct ieee80211_frame *);
hdrlen = ieee80211_get_hdrlen(wh);
@@ -1683,16 +1663,14 @@ wpi_tx(struct wpi_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
desc = &ring->desc[ring->cur];
data = &ring->data[ring->cur];
- /* Chose a TX rate. */
+ /* Chose a TX rate index. */
if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
type != IEEE80211_FC0_TYPE_DATA) {
- rate = ni->ni_rates.rs_rates[0];
- } else if (ic->ic_fixed_rate != -1) {
- rate = ic->ic_sup_rates[ic->ic_curmode].
- rs_rates[ic->ic_fixed_rate];
+ ridx = (ic->ic_curmode == IEEE80211_MODE_11A) ?
+ WPI_RIDX_OFDM6 : WPI_RIDX_CCK1;
} else
- rate = ni->ni_rates.rs_rates[ni->ni_txrate];
- rate &= IEEE80211_RATE_VAL;
+ ridx = wn->ridx[ni->ni_txrate];
+ rinfo = &wpi_rates[ridx];
#if NBPFILTER > 0
if (sc->sc_drvbpf != NULL) {
@@ -1702,7 +1680,7 @@ wpi_tx(struct wpi_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
tap->wt_flags = 0;
tap->wt_chan_freq = htole16(ni->ni_chan->ic_freq);
tap->wt_chan_flags = htole16(ni->ni_chan->ic_flags);
- tap->wt_rate = rate;
+ tap->wt_rate = rinfo->rate;
tap->wt_hwqueue = ac;
if ((ic->ic_flags & IEEE80211_F_WEPON) &&
(wh->i_fc[1] & IEEE80211_FC1_PROTECTED))
@@ -1761,7 +1739,7 @@ wpi_tx(struct wpi_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
if (totlen + IEEE80211_CRC_LEN > ic->ic_rtsthreshold) {
flags |= WPI_TX_NEED_RTS | WPI_TX_FULL_TXOP;
} else if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
- WPI_RATE_IS_OFDM(rate)) {
+ ridx <= WPI_RIDX_OFDM54) {
if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
flags |= WPI_TX_NEED_CTS | WPI_TX_FULL_TXOP;
else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
@@ -1773,7 +1751,7 @@ wpi_tx(struct wpi_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
type != IEEE80211_FC0_TYPE_DATA)
tx->id = WPI_ID_BROADCAST;
else
- tx->id = ((struct wpi_node *)ni)->id;
+ tx->id = wn->id;
if (type == IEEE80211_FC0_TYPE_MGT) {
uint8_t subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
@@ -1798,7 +1776,7 @@ wpi_tx(struct wpi_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
tx->ofdm_mask = 0xff;
tx->cck_mask = 0x0f;
tx->lifetime = htole32(WPI_LIFETIME_INFINITE);
- tx->rate = wpi_plcp_signal(rate);
+ tx->plcp = rinfo->plcp;
/* Copy 802.11 header in TX command. */
memcpy((uint8_t *)(tx + 1), wh, hdrlen);
@@ -2116,23 +2094,24 @@ wpi_mrr_setup(struct wpi_softc *sc)
int i, error;
/* CCK rates (not used with 802.11a). */
- for (i = WPI_CCK1; i <= WPI_CCK11; i++) {
+ for (i = WPI_RIDX_CCK1; i <= WPI_RIDX_CCK11; i++) {
mrr.rates[i].flags = 0;
- mrr.rates[i].plcp = wpi_ridx_to_plcp[i];
+ mrr.rates[i].plcp = wpi_rates[i].plcp;
/* Fallback to the immediate lower CCK rate (if any.) */
- mrr.rates[i].next = (i == WPI_CCK1) ? WPI_CCK1 : i - 1;
+ mrr.rates[i].next =
+ (i == WPI_RIDX_CCK1) ? WPI_RIDX_CCK1 : i - 1;
/* Try one time at this rate before falling back to "next". */
mrr.rates[i].ntries = 1;
}
/* OFDM rates (not used with 802.11b). */
- for (i = WPI_OFDM6; i <= WPI_OFDM54; i++) {
+ for (i = WPI_RIDX_OFDM6; i <= WPI_RIDX_OFDM54; i++) {
mrr.rates[i].flags = 0;
- mrr.rates[i].plcp = wpi_ridx_to_plcp[i];
+ mrr.rates[i].plcp = wpi_rates[i].plcp;
/* Fallback to the immediate lower rate (if any.) */
/* We allow fallback from OFDM/6 to CCK/2 in 11b/g mode. */
- mrr.rates[i].next = (i == WPI_OFDM6) ?
+ mrr.rates[i].next = (i == WPI_RIDX_OFDM6) ?
((ic->ic_curmode == IEEE80211_MODE_11A) ?
- WPI_OFDM6 : WPI_CCK2) :
+ WPI_RIDX_OFDM6 : WPI_RIDX_CCK2) :
i - 1;
/* Try one time at this rate before falling back to "next". */
mrr.rates[i].ntries = 1;
@@ -2266,11 +2245,11 @@ wpi_set_txpower(struct wpi_softc *sc, int async)
cmd.chan = htole16(chan);
/* Set TX power for all OFDM and CCK rates. */
- for (i = 0; i <= 11 ; i++) {
+ for (i = 0; i <= WPI_RIDX_MAX ; i++) {
/* Retrieve TX power for this channel/rate. */
- idx = wpi_get_power_index(sc, group, ch, wpi_ridx_to_rate[i]);
+ idx = wpi_get_power_index(sc, group, ch, i);
- cmd.rates[i].plcp = wpi_ridx_to_plcp[i];
+ cmd.rates[i].plcp = wpi_rates[i].plcp;
if (IEEE80211_IS_CHAN_5GHZ(ch)) {
cmd.rates[i].rf_gain = wpi_rf_gain_5ghz[idx];
@@ -2280,7 +2259,7 @@ wpi_set_txpower(struct wpi_softc *sc, int async)
cmd.rates[i].dsp_gain = wpi_dsp_gain_2ghz[idx];
}
DPRINTF(("chan %d/rate %d: power index %d\n", chan,
- wpi_ridx_to_rate[i], idx));
+ wpi_rates[i].rate, idx));
}
return wpi_cmd(sc, WPI_CMD_TXPOWER, &cmd, sizeof cmd, async);
}
@@ -2292,7 +2271,7 @@ wpi_set_txpower(struct wpi_softc *sc, int async)
*/
int
wpi_get_power_index(struct wpi_softc *sc, struct wpi_power_group *group,
- struct ieee80211_channel *c, int rate)
+ struct ieee80211_channel *c, int ridx)
{
/* Fixed-point arithmetic division using a n-bit fractional part. */
#define fdivround(a, b, n) \
@@ -2314,14 +2293,14 @@ wpi_get_power_index(struct wpi_softc *sc, struct wpi_power_group *group,
pwr = group->maxpwr / 2;
/* Decrease TX power for highest OFDM rates to reduce distortion. */
- switch (rate) {
- case 72: /* OFDM36 */
+ switch (ridx) {
+ case WPI_RIDX_OFDM36:
pwr -= IEEE80211_IS_CHAN_2GHZ(c) ? 0 : 5;
break;
- case 96: /* OFDM48 */
+ case WPI_RIDX_OFDM48:
pwr -= IEEE80211_IS_CHAN_2GHZ(c) ? 7 : 10;
break;
- case 108: /* OFDM54 */
+ case WPI_RIDX_OFDM54:
pwr -= IEEE80211_IS_CHAN_2GHZ(c) ? 9 : 12;
break;
}
@@ -2345,7 +2324,7 @@ wpi_get_power_index(struct wpi_softc *sc, struct wpi_power_group *group,
idx -= (sc->temp - group->temp) * 11 / 100;
/* Decrease TX power for CCK rates (-5dB). */
- if (!WPI_RATE_IS_OFDM(rate))
+ if (ridx >= WPI_RIDX_CCK1)
idx += 10;
/* Make sure idx stays in a valid range. */
@@ -2480,7 +2459,7 @@ wpi_config(struct wpi_softc *sc)
memset(&node, 0, sizeof node);
IEEE80211_ADDR_COPY(node.macaddr, etherbroadcastaddr);
node.id = WPI_ID_BROADCAST;
- node.rate = wpi_ridx_to_plcp[WPI_CCK1];
+ node.plcp = wpi_rates[WPI_RIDX_CCK1].plcp;
node.action = htole32(WPI_ACTION_SET_RATE);
node.antenna = WPI_ANTENNA_BOTH;
error = wpi_cmd(sc, WPI_CMD_ADD_NODE, &node, sizeof node, 0);
@@ -2533,12 +2512,12 @@ wpi_scan(struct wpi_softc *sc, uint16_t flags)
if (flags & IEEE80211_CHAN_5GHZ) {
hdr->crc_threshold = htole16(1);
/* Send probe requests at 6Mbps. */
- tx->rate = wpi_ridx_to_plcp[WPI_OFDM6];
+ tx->plcp = wpi_rates[WPI_RIDX_OFDM6].plcp;
rs = &ic->ic_sup_rates[IEEE80211_MODE_11A];
} else {
hdr->flags = htole32(WPI_RXON_24GHZ | WPI_RXON_AUTO);
/* Send probe requests at 1Mbps. */
- tx->rate = wpi_ridx_to_plcp[WPI_CCK1];
+ tx->plcp = wpi_rates[WPI_RIDX_CCK1].plcp;
rs = &ic->ic_sup_rates[IEEE80211_MODE_11G];
}
@@ -2659,8 +2638,8 @@ wpi_auth(struct wpi_softc *sc)
memset(&node, 0, sizeof node);
IEEE80211_ADDR_COPY(node.macaddr, etherbroadcastaddr);
node.id = WPI_ID_BROADCAST;
- node.rate = (ic->ic_curmode == IEEE80211_MODE_11A) ?
- wpi_ridx_to_plcp[WPI_OFDM6] : wpi_ridx_to_plcp[WPI_CCK1];
+ node.plcp = (ic->ic_curmode == IEEE80211_MODE_11A) ?
+ wpi_rates[WPI_RIDX_OFDM6].plcp : wpi_rates[WPI_RIDX_CCK1].plcp;
node.action = htole32(WPI_ACTION_SET_RATE);
node.antenna = WPI_ANTENNA_BOTH;
error = wpi_cmd(sc, WPI_CMD_ADD_NODE, &node, sizeof node, 1);
@@ -2714,13 +2693,16 @@ wpi_run(struct wpi_softc *sc)
return error;
}
- /* Add BSS node. */
+ /* Fake a join to init the TX rate. */
((struct wpi_node *)ni)->id = WPI_ID_BSS;
+ wpi_newassoc(ic, ni, 1);
+
+ /* Add BSS node. */
memset(&node, 0, sizeof node);
IEEE80211_ADDR_COPY(node.macaddr, ni->ni_bssid);
node.id = WPI_ID_BSS;
- node.rate = (ic->ic_curmode == IEEE80211_MODE_11A) ?
- wpi_ridx_to_plcp[WPI_OFDM6] : wpi_ridx_to_plcp[WPI_CCK1];
+ node.plcp = (ic->ic_curmode == IEEE80211_MODE_11A) ?
+ wpi_rates[WPI_RIDX_OFDM6].plcp : wpi_rates[WPI_RIDX_CCK1].plcp;
node.action = htole32(WPI_ACTION_SET_RATE);
node.antenna = WPI_ANTENNA_BOTH;
DPRINTF(("adding BSS node\n"));
@@ -2730,9 +2712,6 @@ wpi_run(struct wpi_softc *sc)
return error;
}
- /* Fake a join to init the TX rate. */
- wpi_newassoc(ic, ni, 1);
-
/* Start periodic calibration timer. */
sc->calib_cnt = 0;
timeout_add(&sc->calib_to, hz / 2);
diff --git a/sys/dev/pci/if_wpireg.h b/sys/dev/pci/if_wpireg.h
index f2e4415edba..b5f8ce53b8f 100644
--- a/sys/dev/pci/if_wpireg.h
+++ b/sys/dev/pci/if_wpireg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_wpireg.h,v 1.21 2008/11/08 11:02:09 damien Exp $ */
+/* $OpenBSD: if_wpireg.h,v 1.22 2008/11/09 10:00:17 damien Exp $ */
/*-
* Copyright (c) 2006-2008
@@ -376,7 +376,7 @@ struct wpi_node_info {
uint32_t mask;
uint16_t tid;
- uint8_t rate;
+ uint8_t plcp;
uint8_t antenna;
#define WPI_ANTENNA_A (1 << 6)
#define WPI_ANTENNA_B (1 << 7)
@@ -400,7 +400,7 @@ struct wpi_cmd_data {
#define WPI_TX_AUTO_SEQ (1 << 13)
#define WPI_TX_INSERT_TSTAMP (1 << 16)
- uint8_t rate;
+ uint8_t plcp;
uint8_t id;
uint8_t tid;
uint8_t security;
@@ -424,6 +424,7 @@ struct wpi_cmd_data {
} __packed;
/* Structure for command WPI_CMD_MRR_SETUP. */
+#define WPI_RIDX_MAX 11
struct wpi_mrr_setup {
uint32_t which;
#define WPI_MRR_CTL 0
@@ -434,13 +435,7 @@ struct wpi_mrr_setup {
uint8_t flags;
uint8_t ntries;
uint8_t next;
-#define WPI_OFDM6 0
-#define WPI_OFDM54 7
-#define WPI_CCK1 8
-#define WPI_CCK2 9
-#define WPI_CCK11 11
-
- } __packed rates[WPI_CCK11 + 1];
+ } __packed rates[WPI_RIDX_MAX + 1];
} __packed;
/* Structure for command WPI_CMD_SET_LED. */
@@ -521,7 +516,7 @@ struct wpi_cmd_txpower {
uint8_t rf_gain;
uint8_t dsp_gain;
uint8_t reserved;
- } __packed rates[WPI_CCK11 + 1];
+ } __packed rates[WPI_RIDX_MAX + 1];
} __packed;
/* Structure for command WPI_CMD_BT_COEX. */
@@ -692,16 +687,31 @@ static const struct wpi_chan_band {
{ 145, 149, 153, 157, 161, 165 } }
};
-/* Convert rate index (device view) into rate in 500Kbps unit. */
-static const uint8_t wpi_ridx_to_rate[] = {
- 12, 18, 24, 36, 48, 72, 96, 108, /* OFDM */
- 2, 4, 11, 22 /* CCK */
-};
-
-/* Convert rate index (device view) into PLCP code. */
-static const uint8_t wpi_ridx_to_plcp[] = {
- 0xd, 0xf, 0x5, 0x7, 0x9, 0xb, 0x1, 0x3, /* OFDM R1-R4 */
- 10, 20, 55, 110 /* CCK */
+/* HW rate indices. */
+#define WPI_RIDX_OFDM6 0
+#define WPI_RIDX_OFDM36 5
+#define WPI_RIDX_OFDM48 6
+#define WPI_RIDX_OFDM54 7
+#define WPI_RIDX_CCK1 8
+#define WPI_RIDX_CCK2 9
+#define WPI_RIDX_CCK11 11
+
+static const struct wpi_rate {
+ uint8_t rate;
+ uint8_t plcp;
+} wpi_rates[WPI_RIDX_MAX + 1] = {
+ { 12, 0xd },
+ { 18, 0xf },
+ { 24, 0x5 },
+ { 36, 0x7 },
+ { 48, 0x9 },
+ { 72, 0xb },
+ { 96, 0x1 },
+ { 108, 0x3 },
+ { 2, 10 },
+ { 4, 20 },
+ { 11, 55 },
+ { 22, 110 }
};
#define WPI_MAX_PWR_INDEX 77
diff --git a/sys/dev/pci/if_wpivar.h b/sys/dev/pci/if_wpivar.h
index f8e481fa91b..6fcdfff220b 100644
--- a/sys/dev/pci/if_wpivar.h
+++ b/sys/dev/pci/if_wpivar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_wpivar.h,v 1.16 2008/11/08 11:02:09 damien Exp $ */
+/* $OpenBSD: if_wpivar.h,v 1.17 2008/11/09 10:00:17 damien Exp $ */
/*-
* Copyright (c) 2006-2008
@@ -109,6 +109,7 @@ struct wpi_node {
struct ieee80211_node ni; /* must be the first */
struct ieee80211_amrr_node amn;
uint8_t id;
+ uint8_t ridx[IEEE80211_RATE_MAXSIZE];
};
struct wpi_power_sample {