diff options
author | damien <damien@FreeBSD.org> | 2005-08-20 16:49:03 +0000 |
---|---|---|
committer | damien <damien@FreeBSD.org> | 2005-08-20 16:49:03 +0000 |
commit | d3d084c7ccf7e8a7827e5530641bf9335d33eedc (patch) | |
tree | c1c2821a54a54c2307ac3859f09f5eb676c73237 /sys/dev | |
parent | 78a1b1beb47866d8c70bf7e8efd8007e2f6eacf8 (diff) | |
download | FreeBSD-src-d3d084c7ccf7e8a7827e5530641bf9335d33eedc.zip FreeBSD-src-d3d084c7ccf7e8a7827e5530641bf9335d33eedc.tar.gz |
Add some necessary bits for upcoming 802.11e support:
o management of multiple tx rings (up to 4)
o setting of WME IE in association requests
Some features are still missing though, like the possibility to override
the default cwmin/cwmax/asfn values of each tx queues.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/iwi/if_iwi.c | 227 | ||||
-rw-r--r-- | sys/dev/iwi/if_iwireg.h | 16 | ||||
-rw-r--r-- | sys/dev/iwi/if_iwivar.h | 4 |
3 files changed, 183 insertions, 64 deletions
diff --git a/sys/dev/iwi/if_iwi.c b/sys/dev/iwi/if_iwi.c index a124201..0eb7b7c 100644 --- a/sys/dev/iwi/if_iwi.c +++ b/sys/dev/iwi/if_iwi.c @@ -109,7 +109,7 @@ static int iwi_alloc_cmd_ring(struct iwi_softc *, struct iwi_cmd_ring *, static void iwi_reset_cmd_ring(struct iwi_softc *, struct iwi_cmd_ring *); static void iwi_free_cmd_ring(struct iwi_softc *, struct iwi_cmd_ring *); static int iwi_alloc_tx_ring(struct iwi_softc *, struct iwi_tx_ring *, - int); + int, bus_addr_t, bus_addr_t); static void iwi_reset_tx_ring(struct iwi_softc *, struct iwi_tx_ring *); static void iwi_free_tx_ring(struct iwi_softc *, struct iwi_tx_ring *); static int iwi_alloc_rx_ring(struct iwi_softc *, struct iwi_rx_ring *, @@ -119,13 +119,14 @@ static void iwi_free_rx_ring(struct iwi_softc *, struct iwi_rx_ring *); static int iwi_media_change(struct ifnet *); static void iwi_media_status(struct ifnet *, struct ifmediareq *); static int iwi_newstate(struct ieee80211com *, enum ieee80211_state, int); +static int iwi_wme_update(struct ieee80211com *); static uint16_t iwi_read_prom_word(struct iwi_softc *, uint8_t); static void iwi_fix_channel(struct ieee80211com *, struct mbuf *); static void iwi_frame_intr(struct iwi_softc *, struct iwi_rx_data *, int, struct iwi_frame *); static void iwi_notification_intr(struct iwi_softc *, struct iwi_notif *); static void iwi_rx_intr(struct iwi_softc *); -static void iwi_tx_intr(struct iwi_softc *); +static void iwi_tx_intr(struct iwi_softc *, struct iwi_tx_ring *); static void iwi_intr(void *); static int iwi_cmd(struct iwi_softc *, uint8_t, void *, uint8_t, int); static int iwi_tx_start(struct ifnet *, struct mbuf *, @@ -278,8 +279,31 @@ iwi_attach(device_t dev) goto fail; } - if (iwi_alloc_tx_ring(sc, &sc->txq, IWI_TX_RING_COUNT) != 0) { - device_printf(dev, "could not allocate Tx ring\n"); + error = iwi_alloc_tx_ring(sc, &sc->txq[0], IWI_TX_RING_COUNT, + IWI_CSR_TX1_RIDX, IWI_CSR_TX1_WIDX); + if (error != 0) { + device_printf(dev, "could not allocate Tx ring 1\n"); + goto fail; + } + + error = iwi_alloc_tx_ring(sc, &sc->txq[1], IWI_TX_RING_COUNT, + IWI_CSR_TX2_RIDX, IWI_CSR_TX2_WIDX); + if (error != 0) { + device_printf(dev, "could not allocate Tx ring 2\n"); + goto fail; + } + + error = iwi_alloc_tx_ring(sc, &sc->txq[2], IWI_TX_RING_COUNT, + IWI_CSR_TX3_RIDX, IWI_CSR_TX3_WIDX); + if (error != 0) { + device_printf(dev, "could not allocate Tx ring 3\n"); + goto fail; + } + + error = iwi_alloc_tx_ring(sc, &sc->txq[3], IWI_TX_RING_COUNT, + IWI_CSR_TX4_RIDX, IWI_CSR_TX4_WIDX); + if (error != 0) { + device_printf(dev, "could not allocate Tx ring 4\n"); goto fail; } @@ -306,13 +330,18 @@ iwi_attach(device_t dev) IFQ_SET_READY(&ifp->if_snd); ic->ic_ifp = ifp; + ic->ic_wme.wme_update = iwi_wme_update; ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */ ic->ic_state = IEEE80211_S_INIT; /* set device capabilities */ - ic->ic_caps = IEEE80211_C_WPA | IEEE80211_C_PMGT | IEEE80211_C_TXPMGT | - IEEE80211_C_SHPREAMBLE | IEEE80211_C_MONITOR; + ic->ic_caps = + IEEE80211_C_MONITOR | /* monitor mode supported */ + IEEE80211_C_TXPMGT | /* tx power management */ + IEEE80211_C_SHPREAMBLE | /* short preamble supported */ + IEEE80211_C_WPA | /* 802.11i */ + IEEE80211_C_WME; /* 802.11e */ /* read MAC address from EEPROM */ val = iwi_read_prom_word(sc, IWI_EEPROM_MAC + 0); @@ -441,7 +470,10 @@ iwi_detach(device_t dev) if_free(ifp); iwi_free_cmd_ring(sc, &sc->cmdq); - iwi_free_tx_ring(sc, &sc->txq); + iwi_free_tx_ring(sc, &sc->txq[0]); + iwi_free_tx_ring(sc, &sc->txq[1]); + iwi_free_tx_ring(sc, &sc->txq[2]); + iwi_free_tx_ring(sc, &sc->txq[3]); iwi_free_rx_ring(sc, &sc->rxq); if (sc->irq != NULL) { @@ -527,13 +559,16 @@ iwi_free_cmd_ring(struct iwi_softc *sc, struct iwi_cmd_ring *ring) } static int -iwi_alloc_tx_ring(struct iwi_softc *sc, struct iwi_tx_ring *ring, int count) +iwi_alloc_tx_ring(struct iwi_softc *sc, struct iwi_tx_ring *ring, int count, + bus_addr_t csr_ridx, bus_addr_t csr_widx) { int i, error; ring->count = count; ring->queued = 0; ring->cur = ring->next = 0; + ring->csr_ridx = csr_ridx; + ring->csr_widx = csr_widx; error = bus_dma_tag_create(NULL, 4, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, count * IWI_TX_DESC_SIZE, 1, @@ -918,6 +953,14 @@ iwi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) return 0; } +static int +iwi_wme_update(struct ieee80211com *ic) +{ + /* XXX: we should send a IWI_CMD_SET_WME_PARAMS command here */ + + return 0; +} + /* * Read 16 bits at address 'addr' from the serial EEPROM. */ @@ -1214,32 +1257,32 @@ iwi_rx_intr(struct iwi_softc *sc) } static void -iwi_tx_intr(struct iwi_softc *sc) +iwi_tx_intr(struct iwi_softc *sc, struct iwi_tx_ring *txq) { struct ieee80211com *ic = &sc->sc_ic; struct ifnet *ifp = ic->ic_ifp; struct iwi_tx_data *data; uint32_t hw; - hw = CSR_READ_4(sc, IWI_CSR_TX1_RIDX); + hw = CSR_READ_4(sc, txq->csr_ridx); - for (; sc->txq.next != hw;) { - data = &sc->txq.data[sc->txq.next]; + for (; txq->next != hw;) { + data = &txq->data[txq->next]; - bus_dmamap_sync(sc->txq.data_dmat, data->map, + bus_dmamap_sync(txq->data_dmat, data->map, BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(sc->txq.data_dmat, data->map); + bus_dmamap_unload(txq->data_dmat, data->map); m_freem(data->m); data->m = NULL; ieee80211_free_node(data->ni); data->ni = NULL; - DPRINTFN(15, ("tx done idx=%u\n", sc->txq.next)); + DPRINTFN(15, ("tx done idx=%u\n", txq->next)); ifp->if_opackets++; - sc->txq.queued--; - sc->txq.next = (sc->txq.next + 1) % IWI_TX_RING_COUNT; + txq->queued--; + txq->next = (txq->next + 1) % IWI_TX_RING_COUNT; } sc->sc_tx_timer = 0; @@ -1280,14 +1323,23 @@ iwi_intr(void *arg) iwi_stop(sc); } - if (r & IWI_INTR_RX_DONE) - iwi_rx_intr(sc); - if (r & IWI_INTR_CMD_DONE) wakeup(sc); if (r & IWI_INTR_TX1_DONE) - iwi_tx_intr(sc); + iwi_tx_intr(sc, &sc->txq[0]); + + if (r & IWI_INTR_TX2_DONE) + iwi_tx_intr(sc, &sc->txq[1]); + + if (r & IWI_INTR_TX3_DONE) + iwi_tx_intr(sc, &sc->txq[2]); + + if (r & IWI_INTR_TX4_DONE) + iwi_tx_intr(sc, &sc->txq[3]); + + if (r & IWI_INTR_RX_DONE) + iwi_rx_intr(sc); /* acknowledge interrupts */ CSR_WRITE_4(sc, IWI_CSR_INTR, r); @@ -1328,21 +1380,48 @@ iwi_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni) { struct iwi_softc *sc = ifp->if_softc; struct ieee80211com *ic = &sc->sc_ic; - struct ieee80211_frame wh; + struct ieee80211_frame *wh; struct ieee80211_key *k; + const struct chanAccParams *cap; + struct iwi_tx_ring *txq; struct iwi_tx_data *data; struct iwi_tx_desc *desc; struct mbuf *mnew; bus_dma_segment_t segs[IWI_MAX_NSEG]; - int nsegs, error, i; + int error, nsegs, hdrlen, ac, i, noack = 0; + + wh = mtod(m0, struct ieee80211_frame *); + + if (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_QOS) { + hdrlen = sizeof (struct ieee80211_qosframe); + ac = M_WME_GETAC(m0); + cap = &ic->ic_wme.wme_chanParams; + noack = cap->cap_wmeParams[ac].wmep_noackPolicy; + } else { + hdrlen = sizeof (struct ieee80211_frame); + ac = WME_AC_BE; + } + + txq = &sc->txq[ac]; + if (txq->queued >= IWI_TX_RING_COUNT - 4) { + /* + * There is no place left in this ring. Perhaps in 802.11e, + * we should try to fallback to a lowest priority ring? + */ + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + m_freem(m0); + return 0; + } - bcopy(mtod(m0, struct ieee80211_frame *), &wh, sizeof (struct ieee80211_frame)); - if (wh.i_fc[1] & IEEE80211_FC1_WEP) { + if (wh->i_fc[1] & IEEE80211_FC1_WEP) { k = ieee80211_crypto_encap(ic, ni, m0); if (k == NULL) { m_freem(m0); return ENOBUFS; } + + /* packet header may have moved, reset our local pointer */ + wh = mtod(m0, struct ieee80211_frame *); } if (sc->sc_drvbpf != NULL) { @@ -1355,13 +1434,14 @@ iwi_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni) bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0); } - data = &sc->txq.data[sc->txq.cur]; - desc = &sc->txq.desc[sc->txq.cur]; + data = &txq->data[txq->cur]; + desc = &txq->desc[txq->cur]; - /* trim IEEE802.11 header */ - m_adj(m0, sizeof (struct ieee80211_frame)); + /* save and trim IEEE802.11 header */ + m_copydata(m0, 0, hdrlen, (caddr_t)&desc->wh); + m_adj(m0, hdrlen); - error = bus_dmamap_load_mbuf_sg(sc->txq.data_dmat, data->map, m0, segs, + error = bus_dmamap_load_mbuf_sg(txq->data_dmat, data->map, m0, segs, &nsegs, 0); if (error != 0 && error != EFBIG) { device_printf(sc->sc_dev, "could not map mbuf (error %d)\n", @@ -1379,7 +1459,7 @@ iwi_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni) } m0 = mnew; - error = bus_dmamap_load_mbuf_sg(sc->txq.data_dmat, data->map, + error = bus_dmamap_load_mbuf_sg(txq->data_dmat, data->map, m0, segs, &nsegs, 0); if (error != 0) { device_printf(sc->sc_dev, @@ -1396,15 +1476,15 @@ iwi_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni) desc->hdr.flags = IWI_HDR_FLAG_IRQ; desc->cmd = IWI_DATA_CMD_TX; desc->len = htole16(m0->m_pkthdr.len); - memcpy(&desc->wh, &wh, sizeof (struct ieee80211_frame)); desc->flags = 0; + desc->xflags = 0; - if (!IEEE80211_IS_MULTICAST(wh.i_addr1)) + if (!noack && !IEEE80211_IS_MULTICAST(desc->wh.i_addr1)) desc->flags |= IWI_DATA_FLAG_NEED_ACK; #if 0 if (ic->ic_flags & IEEE80211_F_PRIVACY) { - wh.i_fc[1] |= IEEE80211_FC1_WEP; + desc->wh.i_fc[1] |= IEEE80211_FC1_WEP; desc->wep_txkey = ic->ic_crypto.cs_def_txkey; } else #endif @@ -1413,22 +1493,24 @@ iwi_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni) if (ic->ic_flags & IEEE80211_F_SHPREAMBLE) desc->flags |= IWI_DATA_FLAG_SHPREAMBLE; + if (desc->wh.i_fc[0] & IEEE80211_FC0_SUBTYPE_QOS) + desc->xflags |= IWI_DATA_XFLAG_QOS; + desc->nseg = htole32(nsegs); for (i = 0; i < nsegs; i++) { desc->seg_addr[i] = htole32(segs[i].ds_addr); desc->seg_len[i] = htole32(segs[i].ds_len); } - bus_dmamap_sync(sc->txq.data_dmat, data->map, BUS_DMASYNC_PREWRITE); - bus_dmamap_sync(sc->txq.desc_dmat, sc->txq.desc_map, - BUS_DMASYNC_PREWRITE); + bus_dmamap_sync(txq->data_dmat, data->map, BUS_DMASYNC_PREWRITE); + bus_dmamap_sync(txq->desc_dmat, txq->desc_map, BUS_DMASYNC_PREWRITE); - DPRINTFN(5, ("sending data frame idx=%u len=%u nseg=%u\n", sc->txq.cur, - desc->len, desc->nseg)); + DPRINTFN(5, ("sending data frame txq=%u idx=%u len=%u nseg=%u\n", + ac, txq->cur, desc->len, desc->nseg)); - sc->txq.queued++; - sc->txq.cur = (sc->txq.cur + 1) % IWI_TX_RING_COUNT; - CSR_WRITE_4(sc, IWI_CSR_TX1_WIDX, sc->txq.cur); + txq->queued++; + txq->cur = (txq->cur + 1) % IWI_TX_RING_COUNT; + CSR_WRITE_4(sc, txq->csr_widx, txq->cur); return 0; } @@ -1454,12 +1536,6 @@ iwi_start(struct ifnet *ifp) if (m0 == NULL) break; - if (sc->txq.queued >= IWI_TX_RING_COUNT - 4) { - IFQ_DRV_PREPEND(&ifp->if_snd, m0); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - break; - } - if (m0->m_len < sizeof (struct ether_header) && (m0 = m_pullup(m0, sizeof (struct ether_header))) == NULL) continue; @@ -1470,6 +1546,10 @@ iwi_start(struct ifnet *ifp) m_freem(m0); continue; } + if (ieee80211_classify(ic, m0, ni) != 0) { + m_freem(m0); + continue; + } BPF_MTAP(ifp, m0); m0 = ieee80211_encap(ic, m0, ni); @@ -2095,6 +2175,7 @@ iwi_auth_and_assoc(struct iwi_softc *sc) struct ieee80211com *ic = &sc->sc_ic; struct ifnet *ifp = ic->ic_ifp; struct ieee80211_node *ni = ic->ic_bss; + struct ieee80211_wme_info wme; struct iwi_configuration config; struct iwi_associate assoc; struct iwi_rateset rs; @@ -2141,6 +2222,23 @@ iwi_auth_and_assoc(struct iwi_softc *sc) if (error != 0) return error; + if ((ic->ic_flags & IEEE80211_F_WME) && ni->ni_wme_ie != NULL) { + wme.wme_id = IEEE80211_ELEMID_VENDOR; + wme.wme_len = sizeof (struct ieee80211_wme_info) - 2; + wme.wme_oui[0] = 0x00; + wme.wme_oui[1] = 0x50; + wme.wme_oui[2] = 0xf2; + wme.wme_type = WME_OUI_TYPE; + wme.wme_subtype = WME_INFO_OUI_SUBTYPE; + wme.wme_version = WME_VERSION; + wme.wme_info = 0; + + DPRINTF(("Setting WME IE (len=%u)\n", wme.wme_len)); + error = iwi_cmd(sc, IWI_CMD_SET_WMEIE, &wme, sizeof wme, 1); + if (error != 0) + return error; + } + if (ic->ic_opt_ie != NULL) { DPRINTF(("Setting optional IE (len=%u)\n", ic->ic_opt_ie_len)); error = iwi_cmd(sc, IWI_CMD_SET_OPTIE, ic->ic_opt_ie, @@ -2161,8 +2259,10 @@ iwi_auth_and_assoc(struct iwi_softc *sc) assoc.chan = ieee80211_chan2ieee(ic, ni->ni_chan); if (ni->ni_authmode == IEEE80211_AUTH_SHARED) assoc.auth = ic->ic_crypto.cs_def_txkey << 4 | IWI_AUTH_SHARED; + if ((ic->ic_flags & IEEE80211_F_WME) && ni->ni_wme_ie != NULL) + assoc.policy |= htole16(IWI_POLICY_WME); if (ic->ic_opt_ie != NULL) - assoc.policy |= htole16(IWI_POLICY_OPTIE); + assoc.policy |= htole16(IWI_POLICY_WPA); memcpy(assoc.tstamp, ni->ni_tstamp.data, 8); if (ic->ic_opmode == IEEE80211_M_IBSS) @@ -2233,21 +2333,21 @@ iwi_init(void *priv) CSR_WRITE_4(sc, IWI_CSR_CMD_SIZE, sc->cmdq.count); CSR_WRITE_4(sc, IWI_CSR_CMD_WIDX, sc->cmdq.cur); - CSR_WRITE_4(sc, IWI_CSR_TX1_BASE, sc->txq.physaddr); - CSR_WRITE_4(sc, IWI_CSR_TX1_SIZE, sc->txq.count); - CSR_WRITE_4(sc, IWI_CSR_TX1_WIDX, sc->txq.cur); + CSR_WRITE_4(sc, IWI_CSR_TX1_BASE, sc->txq[0].physaddr); + CSR_WRITE_4(sc, IWI_CSR_TX1_SIZE, sc->txq[0].count); + CSR_WRITE_4(sc, IWI_CSR_TX1_WIDX, sc->txq[0].cur); - CSR_WRITE_4(sc, IWI_CSR_TX2_BASE, sc->txq.physaddr); - CSR_WRITE_4(sc, IWI_CSR_TX2_SIZE, sc->txq.count); - CSR_WRITE_4(sc, IWI_CSR_TX2_WIDX, sc->txq.cur); + CSR_WRITE_4(sc, IWI_CSR_TX2_BASE, sc->txq[1].physaddr); + CSR_WRITE_4(sc, IWI_CSR_TX2_SIZE, sc->txq[1].count); + CSR_WRITE_4(sc, IWI_CSR_TX2_WIDX, sc->txq[1].cur); - CSR_WRITE_4(sc, IWI_CSR_TX3_BASE, sc->txq.physaddr); - CSR_WRITE_4(sc, IWI_CSR_TX3_SIZE, sc->txq.count); - CSR_WRITE_4(sc, IWI_CSR_TX3_WIDX, sc->txq.cur); + CSR_WRITE_4(sc, IWI_CSR_TX3_BASE, sc->txq[2].physaddr); + CSR_WRITE_4(sc, IWI_CSR_TX3_SIZE, sc->txq[2].count); + CSR_WRITE_4(sc, IWI_CSR_TX3_WIDX, sc->txq[2].cur); - CSR_WRITE_4(sc, IWI_CSR_TX4_BASE, sc->txq.physaddr); - CSR_WRITE_4(sc, IWI_CSR_TX4_SIZE, sc->txq.count); - CSR_WRITE_4(sc, IWI_CSR_TX4_WIDX, sc->txq.cur); + CSR_WRITE_4(sc, IWI_CSR_TX4_BASE, sc->txq[3].physaddr); + CSR_WRITE_4(sc, IWI_CSR_TX4_SIZE, sc->txq[3].count); + CSR_WRITE_4(sc, IWI_CSR_TX4_WIDX, sc->txq[3].cur); for (i = 0; i < sc->rxq.count; i++) { data = &sc->rxq.data[i]; @@ -2296,7 +2396,10 @@ iwi_stop(void *priv) /* reset rings */ iwi_reset_cmd_ring(sc, &sc->cmdq); - iwi_reset_tx_ring(sc, &sc->txq); + iwi_reset_tx_ring(sc, &sc->txq[0]); + iwi_reset_tx_ring(sc, &sc->txq[1]); + iwi_reset_tx_ring(sc, &sc->txq[2]); + iwi_reset_tx_ring(sc, &sc->txq[3]); iwi_reset_rx_ring(sc, &sc->rxq); sc->sc_tx_timer = 0; diff --git a/sys/dev/iwi/if_iwireg.h b/sys/dev/iwi/if_iwireg.h index daba524..f86e2b5 100644 --- a/sys/dev/iwi/if_iwireg.h +++ b/sys/dev/iwi/if_iwireg.h @@ -223,6 +223,8 @@ struct iwi_tx_desc { #define IWI_DATA_FLAG_NEED_ACK 0x80 uint8_t xflags; +#define IWI_DATA_XFLAG_QOS 0x10 + uint8_t wep_txkey; uint8_t wepkey[IEEE80211_KEYBUF_SIZE]; uint8_t rate; @@ -254,11 +256,13 @@ struct iwi_cmd_desc { #define IWI_CMD_ASSOCIATE 21 #define IWI_CMD_SET_RATES 22 #define IWI_CMD_ABORT_SCAN 23 +#define IWI_CMD_SET_WME_PARAMS 25 #define IWI_CMD_SET_OPTIE 31 #define IWI_CMD_DISABLE 33 #define IWI_CMD_SET_IV 34 #define IWI_CMD_SET_TX_POWER 35 #define IWI_CMD_SET_SENSITIVITY 42 +#define IWI_CMD_SET_WMEIE 84 uint8_t len; uint16_t reserved; @@ -308,7 +312,8 @@ struct iwi_associate { uint8_t type; uint8_t reserved1; uint16_t policy; -#define IWI_POLICY_OPTIE 2 +#define IWI_POLICY_WME 1 +#define IWI_POLICY_WPA 2 uint8_t plen; uint8_t mode; @@ -371,6 +376,15 @@ struct iwi_wep_key { uint8_t key[IEEE80211_KEYBUF_SIZE]; } __packed; +/* structure for command IWI_CMD_SET_WME_PARAMS */ +struct iwi_wme_params { + uint16_t logcwmin[WME_NUM_AC]; + uint16_t logcwmax[WME_NUM_AC]; + uint8_t aifsn[WME_NUM_AC]; + uint8_t acm[WME_NUM_AC]; + uint16_t txopLimit[WME_NUM_AC]; +} __packed; + #define IWI_MEM_EEPROM_CTL 0x00300040 #define IWI_EEPROM_MAC 0x21 diff --git a/sys/dev/iwi/if_iwivar.h b/sys/dev/iwi/if_iwivar.h index 2e8bcab..ff9d9b3 100644 --- a/sys/dev/iwi/if_iwivar.h +++ b/sys/dev/iwi/if_iwivar.h @@ -86,6 +86,8 @@ struct iwi_tx_ring { bus_dma_tag_t data_dmat; bus_dmamap_t desc_map; bus_addr_t physaddr; + bus_addr_t csr_ridx; + bus_addr_t csr_widx; struct iwi_tx_desc *desc; struct iwi_tx_data *data; int count; @@ -125,7 +127,7 @@ struct iwi_softc { #define IWI_FLAG_SCANNING (1 << 3) struct iwi_cmd_ring cmdq; - struct iwi_tx_ring txq; + struct iwi_tx_ring txq[WME_NUM_AC]; struct iwi_rx_ring rxq; struct resource *irq; |