OSDN Git Service

iwlwifi: pcie: dynamic Tx command queue size
authorShahar S Matityahu <shahar.s.matityahu@intel.com>
Sun, 30 Jul 2017 14:33:48 +0000 (17:33 +0300)
committerLuca Coelho <luciano.coelho@intel.com>
Fri, 6 Oct 2017 11:57:22 +0000 (14:57 +0300)
Devices in the A000 family can use a different size for the command queue.
To allow this, make the command queue size configurable and set the size
for A000 devices to 32.

Signed-off-by: Shahar S Matityahu <shahar.s.matityahu@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
drivers/net/wireless/intel/iwlwifi/cfg/a000.c
drivers/net/wireless/intel/iwlwifi/iwl-config.h
drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c
drivers/net/wireless/intel/iwlwifi/pcie/internal.h
drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
drivers/net/wireless/intel/iwlwifi/pcie/tx.c

index 76ba1f8..ed8bccd 100644 (file)
@@ -134,7 +134,8 @@ static const struct iwl_ht_params iwl_a000_ht_params = {
        .rf_id = true,                                                  \
        .gen2 = true,                                                   \
        .ext_nvm = true,                                                \
-       .dbgc_supported = true
+       .dbgc_supported = true,                                         \
+       .tx_cmd_queue_size = 32
 
 const struct iwl_cfg iwla000_2ac_cfg_hr = {
                .name = "Intel(R) Dual Band Wireless AC a000",
index 3e057b5..b9f3b35 100644 (file)
@@ -321,6 +321,8 @@ struct iwl_pwr_tx_backoff {
  * @gen2: a000 and on transport operation
  * @cdb: CDB support
  * @ext_nvm: extended NVM format
+ * @tx_cmd_queue_size: size of the cmd queue. If zero, use the same value as
+ *     the regular queues
  *
  * We enable the driver to be backward compatible wrt. hardware features.
  * API differences in uCode shouldn't be handled here but through TLVs
@@ -371,6 +373,7 @@ struct iwl_cfg {
            cdb:1,
            ext_nvm:1,
            dbgc_supported:1;
+       u16 tx_cmd_queue_size;
        u8 valid_tx_ant;
        u8 valid_rx_ant;
        u8 non_shared_ant;
index 3fc4343..5ef216f 100644 (file)
@@ -244,7 +244,7 @@ int iwl_pcie_ctxt_info_init(struct iwl_trans *trans,
        ctxt_info->hcmd_cfg.cmd_queue_addr =
                cpu_to_le64(trans_pcie->txq[trans_pcie->cmd_queue]->dma_addr);
        ctxt_info->hcmd_cfg.cmd_queue_size =
-               TFD_QUEUE_CB_SIZE(TFD_CMD_SLOTS);
+               TFD_QUEUE_CB_SIZE(trans_pcie->tx_cmd_queue_size);
 
        /* allocate ucode sections in dram and set addresses */
        ret = iwl_pcie_ctxt_info_init_fw_sec(trans, fw, ctxt_info);
index 4fb7647..9caff1e 100644 (file)
@@ -383,6 +383,7 @@ struct iwl_self_init_dram {
  * @hw_init_mask: initial unmasked hw causes
  * @fh_mask: current unmasked fh causes
  * @hw_mask: current unmasked hw causes
+ * @tx_cmd_queue_size: the size of the tx command queue
  */
 struct iwl_trans_pcie {
        struct iwl_rxq *rxq;
@@ -463,6 +464,7 @@ struct iwl_trans_pcie {
        u32 fh_mask;
        u32 hw_mask;
        cpumask_t affinity_mask[IWL_MAX_RX_HW_QUEUES];
+       u16 tx_cmd_queue_size;
 };
 
 static inline struct iwl_trans_pcie *
@@ -534,6 +536,7 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans,
 void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
                            struct sk_buff_head *skbs);
 void iwl_trans_pcie_tx_reset(struct iwl_trans *trans);
+void iwl_pcie_set_tx_cmd_queue_size(struct iwl_trans *trans);
 
 static inline u16 iwl_pcie_tfd_tb_get_len(struct iwl_trans *trans, void *_tfd,
                                          u8 idx)
index d74613f..79e4c73 100644 (file)
@@ -1160,6 +1160,8 @@ int iwl_pcie_gen2_tx_init(struct iwl_trans *trans)
        struct iwl_txq *cmd_queue;
        int txq_id = trans_pcie->cmd_queue, ret;
 
+       iwl_pcie_set_tx_cmd_queue_size(trans);
+
        /* alloc and init the command queue */
        if (!trans_pcie->txq[txq_id]) {
                cmd_queue = kzalloc(sizeof(*cmd_queue), GFP_KERNEL);
@@ -1168,7 +1170,8 @@ int iwl_pcie_gen2_tx_init(struct iwl_trans *trans)
                        return -ENOMEM;
                }
                trans_pcie->txq[txq_id] = cmd_queue;
-               ret = iwl_pcie_txq_alloc(trans, cmd_queue, TFD_CMD_SLOTS, true);
+               ret = iwl_pcie_txq_alloc(trans, cmd_queue,
+                                        trans_pcie->tx_cmd_queue_size, true);
                if (ret) {
                        IWL_ERR(trans, "Tx %d queue init failed\n", txq_id);
                        goto error;
@@ -1177,7 +1180,8 @@ int iwl_pcie_gen2_tx_init(struct iwl_trans *trans)
                cmd_queue = trans_pcie->txq[txq_id];
        }
 
-       ret = iwl_pcie_txq_init(trans, cmd_queue, TFD_CMD_SLOTS, true);
+       ret = iwl_pcie_txq_init(trans, cmd_queue,
+                               trans_pcie->tx_cmd_queue_size, true);
        if (ret) {
                IWL_ERR(trans, "Tx %d queue alloc failed\n", txq_id);
                goto error;
index c645d10..e93c471 100644 (file)
@@ -951,7 +951,8 @@ static int iwl_pcie_tx_alloc(struct iwl_trans *trans)
             txq_id++) {
                bool cmd_queue = (txq_id == trans_pcie->cmd_queue);
 
-               slots_num = cmd_queue ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
+               slots_num = cmd_queue ? trans_pcie->tx_cmd_queue_size :
+                       TFD_TX_CMD_SLOTS;
                trans_pcie->txq[txq_id] = &trans_pcie->txq_memory[txq_id];
                ret = iwl_pcie_txq_alloc(trans, trans_pcie->txq[txq_id],
                                         slots_num, cmd_queue);
@@ -970,6 +971,21 @@ error:
        return ret;
 }
 
+void iwl_pcie_set_tx_cmd_queue_size(struct iwl_trans *trans)
+{
+       struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+       int queue_size = TFD_CMD_SLOTS;
+
+       if (trans->cfg->tx_cmd_queue_size)
+               queue_size = trans->cfg->tx_cmd_queue_size;
+
+       if (WARN_ON(!(is_power_of_2(queue_size) &&
+                     TFD_QUEUE_CB_SIZE(queue_size) > 0)))
+               trans_pcie->tx_cmd_queue_size = TFD_CMD_SLOTS;
+       else
+               trans_pcie->tx_cmd_queue_size = queue_size;
+}
+
 int iwl_pcie_tx_init(struct iwl_trans *trans)
 {
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
@@ -977,6 +993,8 @@ int iwl_pcie_tx_init(struct iwl_trans *trans)
        int txq_id, slots_num;
        bool alloc = false;
 
+       iwl_pcie_set_tx_cmd_queue_size(trans);
+
        if (!trans_pcie->txq_memory) {
                ret = iwl_pcie_tx_alloc(trans);
                if (ret)
@@ -1000,7 +1018,8 @@ int iwl_pcie_tx_init(struct iwl_trans *trans)
             txq_id++) {
                bool cmd_queue = (txq_id == trans_pcie->cmd_queue);
 
-               slots_num = cmd_queue ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
+               slots_num = cmd_queue ? trans_pcie->tx_cmd_queue_size :
+                       TFD_TX_CMD_SLOTS;
                ret = iwl_pcie_txq_init(trans, trans_pcie->txq[txq_id],
                                        slots_num, cmd_queue);
                if (ret) {