Page MenuHomeFreeBSD

D60696.id189704.diff
No OneTemporary

D60696.id189704.diff

diff --git a/sys/dev/iwm/if_iwm.c b/sys/dev/iwm/if_iwm.c
--- a/sys/dev/iwm/if_iwm.c
+++ b/sys/dev/iwm/if_iwm.c
@@ -1701,6 +1701,55 @@
return 0;
}
+int
+iwm_enable_ac_txq(struct iwm_softc *sc, int qid, int fifo)
+{
+ int err;
+
+ if (!sc->cmd_hold_nic_awake) {
+ device_printf(sc->sc_dev, "%s: NIC not awake\n", __func__);
+ return (ENXIO);
+ }
+
+ IWM_WRITE(sc, IWM_HBUS_TARG_WRPTR, qid << 8 | 0);
+
+ iwm_write_prph(sc, IWM_SCD_QUEUE_STATUS_BITS(qid),
+ (0 << IWM_SCD_QUEUE_STTS_REG_POS_ACTIVE)
+ | (1 << IWM_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
+
+ err = iwm_clear_bits_prph(sc, IWM_SCD_AGGR_SEL, (1 << qid));
+ if (err) {
+ return err;
+ }
+
+ iwm_write_prph(sc, IWM_SCD_QUEUE_RDPTR(qid), 0);
+
+ iwm_write_mem32(sc,
+ sc->scd_base_addr + IWM_SCD_CONTEXT_QUEUE_OFFSET(qid), 0);
+
+ /* Set scheduler window size and frame limit. */
+ iwm_write_mem32(sc,
+ sc->scd_base_addr + IWM_SCD_CONTEXT_QUEUE_OFFSET(qid) +
+ sizeof(uint32_t),
+ ((IWM_FRAME_LIMIT << IWM_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
+ IWM_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
+ ((IWM_FRAME_LIMIT
+ << IWM_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
+ IWM_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
+
+ iwm_write_prph(sc, IWM_SCD_QUEUE_STATUS_BITS(qid),
+ (1 << IWM_SCD_QUEUE_STTS_REG_POS_ACTIVE) |
+ (fifo << IWM_SCD_QUEUE_STTS_REG_POS_TXF) |
+ (1 << IWM_SCD_QUEUE_STTS_REG_POS_WSL) |
+ IWM_SCD_QUEUE_STTS_REG_MSK);
+
+ if (qid == sc->cmdqid)
+ iwm_write_prph(sc, IWM_SCD_EN_CTRL,
+ iwm_read_prph(sc, IWM_SCD_EN_CTRL) | (1 << qid));
+
+ return 0;
+}
+
int
iwm_enable_txq(struct iwm_softc *sc, int sta_id, int qid, int fifo)
{
@@ -1841,8 +1890,7 @@
iwm_nic_unlock(sc);
/* enable command channel */
- error = iwm_enable_txq(sc, 0 /* unused */, sc->cmdqid,
- IWM_TX_FIFO_CMD);
+ error = iwm_enable_ac_txq(sc, sc->cmdqid, IWM_TX_FIFO_CMD);
if (error)
return error;
diff --git a/sys/dev/iwm/if_iwm_sta.c b/sys/dev/iwm/if_iwm_sta.c
--- a/sys/dev/iwm/if_iwm_sta.c
+++ b/sys/dev/iwm/if_iwm_sta.c
@@ -365,18 +365,21 @@
* + non-DQA calls iwm_enable_ac_txq(), which does similar stuff to
* command setup but not the command scheduler
*/
- if (iwm_fw_has_capa(sc, IWM_UCODE_TLV_CAPA_DQA_SUPPORT))
+ if (iwm_fw_has_capa(sc, IWM_UCODE_TLV_CAPA_DQA_SUPPORT)) {
qid = IWM_DQA_AUX_QUEUE;
- else
+ ret = iwm_enable_txq(sc, IWM_AUX_STA_ID, qid,
+ IWM_TX_FIFO_MCAST);
+ } else {
qid = IWM_AUX_QUEUE;
+ ret = iwm_enable_ac_txq(sc, qid, IWM_TX_FIFO_MCAST);
+ }
+ if (ret)
+ return ret;
sc->sc_aux_sta.sta_id = IWM_AUX_STA_ID;
sc->sc_aux_sta.tfd_queue_msk = (1 << qid);
/* Map Aux queue to fifo - needs to happen before adding Aux station */
- ret = iwm_enable_txq(sc, IWM_AUX_STA_ID, qid, IWM_TX_FIFO_MCAST);
- if (ret)
- return ret;
ret = iwm_add_int_sta_common(sc, &sc->sc_aux_sta, NULL,
IWM_MAC_INDEX_AUX, 0);
diff --git a/sys/dev/iwm/if_iwm_util.h b/sys/dev/iwm/if_iwm_util.h
--- a/sys/dev/iwm/if_iwm_util.h
+++ b/sys/dev/iwm/if_iwm_util.h
@@ -125,6 +125,7 @@
extern boolean_t iwm_rx_diversity_allowed(struct iwm_softc *sc);
extern uint8_t iwm_ridx2rate(struct ieee80211_rateset *rs, int ridx);
+extern int iwm_enable_ac_txq(struct iwm_softc *sc, int qid, int fifo);
extern int iwm_enable_txq(struct iwm_softc *sc, int sta_id, int qid, int fifo);
extern int iwm_flush_tx_path(struct iwm_softc *sc, uint32_t tfd_msk,
uint32_t flags);

File Metadata

Mime Type
text/plain
Expires
Tue, Oct 20, 8:40 PM (17 h, 41 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40903236
Default Alt Text
D60696.id189704.diff (3 KB)

Event Timeline