diff options
Diffstat (limited to 'sys/dev/pci')
-rw-r--r-- | sys/dev/pci/if_iwn.c | 135 | ||||
-rw-r--r-- | sys/dev/pci/if_iwnreg.h | 39 | ||||
-rw-r--r-- | sys/dev/pci/if_iwnvar.h | 3 | ||||
-rw-r--r-- | sys/dev/pci/if_wpi.c | 137 | ||||
-rw-r--r-- | sys/dev/pci/if_wpireg.h | 52 | ||||
-rw-r--r-- | sys/dev/pci/if_wpivar.h | 3 |
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 { |