Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F176257319
D60080.id189944.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D60080.id189944.diff
View Options
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
@@ -1147,10 +1147,25 @@
ring->desc = ring->desc_dma.vaddr;
/*
- * We only use rings 0 through 9 (4 EDCA + cmd) so there is no need
- * to allocate commands space for other rings.
+ * There is no need to allocate DMA buffers for unused rings.
+ * 7k/8k/9k hardware supports up to 31 Tx rings which is more
+ * than we currently need.
+ *
+ * In DQA mode we use 1 command queue + 4 DQA mgmt/data queues.
+ * The command is queue 0 (sc->txq[0]), and 4 mgmt/data frame queues
+ * are sc->tqx[IWM_DQA_MIN_MGMT_QUEUE + ac], i.e. sc->txq[5:8],
+ * in order to provide one queue per EDCA category.
+ * Tx aggregation requires additional queues, one queue per TID for
+ * which aggregation is enabled. We map TID 0-7 to sc->txq[10:17].
+ *
+ * In non-DQA mode, we use rings 0 through 9 (0-3 are EDCA, 9 is cmd),
+ * and Tx aggregation is not supported.
+ *
+ * Unfortunately, we cannot tell if DQA will be used until the
+ * firmware gets loaded later, so just allocate sufficient rings
+ * in order to satisfy both cases.
*/
- if (qid > IWM_CMD_QUEUE)
+ if (qid > IWM_LAST_AGG_TX_QUEUE)
return 0;
size = IWM_TX_RING_COUNT * sizeof(struct iwm_device_cmd);
@@ -1162,8 +1177,13 @@
}
ring->cmd = ring->cmd_dma.vaddr;
- /* FW commands may require more mapped space than packets. */
- if (qid == IWM_CMD_QUEUE) {
+ /*
+ * FW commands may require more mapped space than packets. The
+ * DQA command queue is ring 0 and we can't tell at allocation
+ * time which command queue id will be used, so give both the
+ * command-sized DMA tag.
+ */
+ if (qid == IWM_CMD_QUEUE || qid == IWM_DQA_CMD_QUEUE) {
maxsize = IWM_RBUF_SIZE;
nsegments = 1;
} else {
@@ -1227,7 +1247,7 @@
ring->queued = 0;
ring->cur = 0;
- if (ring->qid == IWM_CMD_QUEUE && sc->cmd_hold_nic_awake)
+ if (ring->qid == sc->cmdqid && sc->cmd_hold_nic_awake)
iwm_pcie_clear_cmd_in_flight(sc);
}
@@ -1692,9 +1712,11 @@
IWM_WRITE(sc, IWM_HBUS_TARG_WRPTR, qid << 8 | 0);
- if (qid == IWM_CMD_QUEUE) {
+ if (qid == sc->cmdqid) {
+#if 0
/* Disable the scheduler. */
iwm_write_prph(sc, IWM_SCD_EN_CTRL, 0);
+#endif
/* Stop the TX queue prior to configuration. */
iwm_write_prph(sc, IWM_SCD_QUEUE_STATUS_BITS(qid),
@@ -1737,7 +1759,8 @@
IWM_SCD_QUEUE_STTS_REG_MSK);
/* Enable the scheduler for this queue. */
- iwm_write_prph(sc, IWM_SCD_EN_CTRL, qmsk);
+ iwm_write_prph(sc, IWM_SCD_EN_CTRL,
+ iwm_read_prph(sc, IWM_SCD_EN_CTRL) | qmsk);
} else {
struct iwm_scd_txq_cfg_cmd cmd;
int error;
@@ -1813,7 +1836,8 @@
iwm_nic_unlock(sc);
/* enable command channel */
- error = iwm_enable_txq(sc, 0 /* unused */, IWM_CMD_QUEUE, 7);
+ error = iwm_enable_txq(sc, 0 /* unused */, sc->cmdqid,
+ IWM_TX_FIFO_CMD);
if (error)
return error;
@@ -2929,6 +2953,11 @@
sc->cur_ucode = ucode_type;
sc->ucode_loaded = FALSE;
+ if (iwm_fw_has_capa(sc, IWM_UCODE_TLV_CAPA_DQA_SUPPORT))
+ sc->cmdqid = IWM_DQA_CMD_QUEUE;
+ else
+ sc->cmdqid = IWM_CMD_QUEUE;
+
memset(&alive_data, 0, sizeof(alive_data));
iwm_init_notification_wait(sc->sc_notif_wait, &alive_wait,
alive_cmd, nitems(alive_cmd),
@@ -3672,10 +3701,10 @@
static void
iwm_cmd_done(struct iwm_softc *sc, struct iwm_rx_packet *pkt)
{
- struct iwm_tx_ring *ring = &sc->txq[IWM_CMD_QUEUE];
+ struct iwm_tx_ring *ring = &sc->txq[sc->cmdqid];
struct iwm_tx_data *data;
- if (pkt->hdr.qid != IWM_CMD_QUEUE) {
+ if (pkt->hdr.qid != sc->cmdqid) {
return; /* Not a command ack. */
}
@@ -3851,13 +3880,22 @@
int nsegs;
uint8_t tid, type;
int i, totlen, error, pad;
+ int qid;
wh = mtod(m, struct ieee80211_frame *);
hdrlen = ieee80211_anyhdrsize(wh);
type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
tid = 0;
- ring = &sc->txq[ac];
+
+ /* Map EDCA categories to Tx data queues. */
+ if (iwm_fw_has_capa(sc, IWM_UCODE_TLV_CAPA_DQA_SUPPORT))
+ qid = IWM_DQA_MIN_MGMT_QUEUE + ac;
+ else
+ qid = ac;
+
+ ring = &sc->txq[qid];
desc = &ring->desc[ring->cur];
+ memset(desc, 0, sizeof(*desc));
data = &ring->data[ring->cur];
/* Fill out iwm_tx_cmd to send to the firmware */
@@ -4767,6 +4805,17 @@
return err;
}
+static int
+iwm_send_dqa_cmd(struct iwm_softc *sc)
+{
+ struct iwm_dqa_enable_cmd dqa_cmd;
+ uint32_t cmd_id;
+
+ dqa_cmd.cmd_queue = htole32(IWM_DQA_CMD_QUEUE);
+ cmd_id = iwm_cmd_id(IWM_DQA_ENABLE_CMD, IWM_DATA_PATH_GROUP, 0);
+ return iwm_send_cmd_pdu(sc, cmd_id, 0, sizeof(dqa_cmd), &dqa_cmd);
+}
+
static int
iwm_send_temp_report_ths_cmd(struct iwm_softc *sc)
{
@@ -4907,7 +4956,7 @@
iwm_init_hw(struct iwm_softc *sc)
{
struct ieee80211com *ic = &sc->sc_ic;
- int error, i, ac;
+ int error, i, ac, qid;
sc->sf_state = IWM_SF_UNINIT;
@@ -4973,6 +5022,11 @@
goto error;
}
+ if (iwm_fw_has_capa(sc, IWM_UCODE_TLV_CAPA_DQA_SUPPORT)) {
+ if ((error = iwm_send_dqa_cmd(sc)) != 0)
+ goto error;
+ }
+
/* Add auxiliary station for scanning */
if ((error = iwm_add_aux_sta(sc)) != 0) {
device_printf(sc->sc_dev, "add_aux_sta failed\n");
@@ -5011,7 +5065,12 @@
/* Enable Tx queues. */
for (ac = 0; ac < WME_NUM_AC; ac++) {
- error = iwm_enable_txq(sc, IWM_STATION_ID, ac,
+ if (iwm_fw_has_capa(sc, IWM_UCODE_TLV_CAPA_DQA_SUPPORT))
+ qid = ac + IWM_DQA_MIN_MGMT_QUEUE;
+ else
+ qid = ac;
+
+ error = iwm_enable_txq(sc, IWM_STATION_ID, qid,
iwm_ac_to_tx_fifo[ac]);
if (error)
goto 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
@@ -162,8 +162,10 @@
if (!update) {
int ac;
for (ac = 0; ac < WME_NUM_AC; ac++) {
- add_sta_cmd.tfd_queue_msk |=
- htole32(1 << iwm_ac_to_tx_fifo[ac]);
+ int qid = ac;
+ if (iwm_fw_has_capa(sc, IWM_UCODE_TLV_CAPA_DQA_SUPPORT))
+ qid += IWM_DQA_MIN_MGMT_QUEUE;
+ add_sta_cmd.tfd_queue_msk |= htole32(1 << qid);
}
IEEE80211_ADDR_COPY(&add_sta_cmd.addr, in->in_ni.ni_bssid);
}
@@ -277,7 +279,10 @@
if (ret)
return ret;
for (ac = 0; ac < WME_NUM_AC; ac++) {
- tfd_queue_msk |= htole32(1 << iwm_ac_to_tx_fifo[ac]);
+ int qid = ac;
+ if (iwm_fw_has_capa(sc, IWM_UCODE_TLV_CAPA_DQA_SUPPORT))
+ qid += IWM_DQA_MIN_MGMT_QUEUE;
+ tfd_queue_msk |= htole32(1 << qid);
}
ret = iwm_flush_tx_path(sc, tfd_queue_msk, IWM_CMD_SYNC);
if (ret)
@@ -352,13 +357,24 @@
iwm_add_aux_sta(struct iwm_softc *sc)
{
int ret;
+ int qid;
+
+ /*
+ * Note: OpenBSD calls different TXQ setups here;
+ * + DQA calls iwm_enable_txq(), which only sends the cmd_pdu
+ * + 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))
+ qid = IWM_DQA_AUX_QUEUE;
+ else
+ qid = IWM_AUX_QUEUE;
sc->sc_aux_sta.sta_id = IWM_AUX_STA_ID;
- sc->sc_aux_sta.tfd_queue_msk = (1 << IWM_AUX_QUEUE);
+ 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, IWM_AUX_QUEUE,
- IWM_TX_FIFO_MCAST);
+ ret = iwm_enable_txq(sc, IWM_AUX_STA_ID, qid, IWM_TX_FIFO_MCAST);
if (ret)
return ret;
diff --git a/sys/dev/iwm/if_iwm_util.c b/sys/dev/iwm/if_iwm_util.c
--- a/sys/dev/iwm/if_iwm_util.c
+++ b/sys/dev/iwm/if_iwm_util.c
@@ -167,7 +167,7 @@
int
iwm_send_cmd(struct iwm_softc *sc, struct iwm_host_cmd *hcmd)
{
- struct iwm_tx_ring *ring = &sc->txq[IWM_CMD_QUEUE];
+ struct iwm_tx_ring *ring = &sc->txq[sc->cmdqid];
struct iwm_tfd *desc;
struct iwm_tx_data *txdata = NULL;
struct iwm_device_cmd *cmd;
diff --git a/sys/dev/iwm/if_iwmvar.h b/sys/dev/iwm/if_iwmvar.h
--- a/sys/dev/iwm/if_iwmvar.h
+++ b/sys/dev/iwm/if_iwmvar.h
@@ -454,6 +454,7 @@
struct iwm_tx_ring txq[IWM_MAX_QUEUES];
struct iwm_rx_ring rxq;
int qfullmsk;
+ int cmdqid;
/* ICT table. */
struct iwm_dma_info ict_dma;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Oct 18, 10:09 AM (9 h, 21 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40819264
Default Alt Text
D60080.id189944.diff (7 KB)
Attached To
Mode
D60080: iwm: add DQA (dynamic queue assignment)
Attached
Detach File
Event Timeline
Log In to Comment