iwlwifi: mvm: configure multi RX queue
authorSara Sharon <sara.sharon@intel.com>
Mon, 5 Feb 2018 10:42:44 +0000 (12:42 +0200)
committerLuca Coelho <luciano.coelho@intel.com>
Thu, 2 Aug 2018 07:50:07 +0000 (10:50 +0300)
Currently multi-queue is disabled for 22000 devices.

This was since driver isn't supposed to write to prph
registers anymore, and FW needs to configure the RFH.

Now that FW added support for the API - use it and remove
the 22000 multi RX queue disablement.

Bump min API version to avoid compatibility issues.

Signed-off-by: Sara Sharon <sara.sharon@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
drivers/net/wireless/intel/iwlwifi/cfg/22000.c
drivers/net/wireless/intel/iwlwifi/fw/api/datapath.h
drivers/net/wireless/intel/iwlwifi/fw/api/rx.h
drivers/net/wireless/intel/iwlwifi/mvm/fw.c
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
drivers/net/wireless/intel/iwlwifi/mvm/ops.c

index e5d5578f8b92167d51d1e5bf5df56b68d53d66b1..91ca77c7571cebb2a6dd3265b1713fb6d3202bda 100644 (file)
@@ -59,7 +59,7 @@
 #define IWL_22000_UCODE_API_MAX        38
 
 /* Lowest firmware API version supported */
-#define IWL_22000_UCODE_API_MIN        24
+#define IWL_22000_UCODE_API_MIN        39
 
 /* NVM versions */
 #define IWL_22000_NVM_VERSION          0x0a1d
index c1bf3898f8b672c07d638176ce481b987c6544a4..59b3c6e8f37b609cf269c8915cdbe3bf7867079b 100644 (file)
@@ -8,6 +8,7 @@
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
+ * Copyright (C) 2018 Intel Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,6 +31,7 @@
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
+ * Copyright (C) 2018 Intel Corporation
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -87,6 +89,11 @@ enum iwl_data_path_subcmd_ids {
         */
        STA_HE_CTXT_CMD = 0x7,
 
+       /**
+        * @RFH_QUEUE_CONFIG_CMD: &struct iwl_rfh_queue_config
+        */
+       RFH_QUEUE_CONFIG_CMD = 0xD,
+
        /**
         * @TLC_MNG_CONFIG_CMD: &struct iwl_tlc_config_cmd
         */
index 565343f7e61fc1fe8c60fbc0ab7a5a9ae82a95b1..2f599353c8856b4c9604e4953722771c7fef4837 100644 (file)
@@ -715,4 +715,36 @@ struct iwl_ba_window_status_notif {
        __le16 mpdu_rx_count[BA_WINDOW_STREAMS_MAX];
 } __packed; /* BA_WINDOW_STATUS_NTFY_API_S_VER_1 */
 
+/**
+ * struct iwl_rfh_queue_config - RX queue configuration
+ * @q_num: Q num
+ * @enable: enable queue
+ * @reserved: alignment
+ * @urbd_stts_wrptr: DMA address of urbd_stts_wrptr
+ * @fr_bd_cb: DMA address of freeRB table
+ * @ur_bd_cb: DMA address of used RB table
+ * @fr_bd_wid: Initial index of the free table
+ */
+struct iwl_rfh_queue_data {
+       u8 q_num;
+       u8 enable;
+       __le16 reserved;
+       __le64 urbd_stts_wrptr;
+       __le64 fr_bd_cb;
+       __le64 ur_bd_cb;
+       __le32 fr_bd_wid;
+} __packed; /* RFH_QUEUE_CONFIG_S_VER_1 */
+
+/**
+ * struct iwl_rfh_queue_config - RX queue configuration
+ * @num_queues: number of queues configured
+ * @reserved: alignment
+ * @data: DMA addresses per-queue
+ */
+struct iwl_rfh_queue_config {
+       u8 num_queues;
+       u8 reserved[3];
+       struct iwl_rfh_queue_data data[];
+} __packed; /* RFH_QUEUE_CONFIG_API_S_VER_1 */
+
 #endif /* __iwl_fw_api_rx_h__ */
index 5fe2b460234b74e689f51a0aea7d6dd5cb2916b3..6bb1a99a197a22981f29962ab487cccb76dd0eb8 100644 (file)
@@ -130,6 +130,41 @@ static int iwl_send_rss_cfg_cmd(struct iwl_mvm *mvm)
        return iwl_mvm_send_cmd_pdu(mvm, RSS_CONFIG_CMD, 0, sizeof(cmd), &cmd);
 }
 
+static int iwl_configure_rxq(struct iwl_mvm *mvm)
+{
+       int i, num_queues, size;
+       struct iwl_rfh_queue_config *cmd;
+
+       /* Do not configure default queue, it is configured via context info */
+       num_queues = mvm->trans->num_rx_queues - 1;
+
+       size = sizeof(*cmd) + num_queues * sizeof(struct iwl_rfh_queue_data);
+
+       cmd = kzalloc(size, GFP_KERNEL);
+       if (!cmd)
+               return -ENOMEM;
+
+       cmd->num_queues = num_queues;
+
+       for (i = 0; i < num_queues; i++) {
+               struct iwl_trans_rxq_dma_data data;
+
+               cmd->data[i].q_num = i + 1;
+               iwl_trans_get_rxq_dma_data(mvm->trans, i + 1, &data);
+
+               cmd->data[i].fr_bd_cb = cpu_to_le64(data.fr_bd_cb);
+               cmd->data[i].urbd_stts_wrptr =
+                       cpu_to_le64(data.urbd_stts_wrptr);
+               cmd->data[i].ur_bd_cb = cpu_to_le64(data.ur_bd_cb);
+               cmd->data[i].fr_bd_wid = cpu_to_le32(data.fr_bd_wid);
+       }
+
+       return iwl_mvm_send_cmd_pdu(mvm,
+                                   WIDE_ID(DATA_PATH_GROUP,
+                                           RFH_QUEUE_CONFIG_CMD),
+                                   0, size, cmd);
+}
+
 static int iwl_mvm_send_dqa_cmd(struct iwl_mvm *mvm)
 {
        struct iwl_dqa_enable_cmd dqa_cmd = {
@@ -1007,9 +1042,16 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
                goto error;
 
        /* Init RSS configuration */
-       /* TODO - remove 22000 disablement when we have RXQ config API */
-       if (iwl_mvm_has_new_rx_api(mvm) &&
-           mvm->trans->cfg->device_family < IWL_DEVICE_FAMILY_22000) {
+       if (mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22000) {
+               ret = iwl_configure_rxq(mvm);
+               if (ret) {
+                       IWL_ERR(mvm, "Failed to configure RX queues: %d\n",
+                               ret);
+                       goto error;
+               }
+       }
+
+       if (iwl_mvm_has_new_rx_api(mvm)) {
                ret = iwl_send_rss_cfg_cmd(mvm);
                if (ret) {
                        IWL_ERR(mvm, "Failed to configure RSS queues: %d\n",
index a3b634ae3838739af5461d0ae5c1439721864a95..b15b0d84bb7ea18a06933d455e495248c7bcd32c 100644 (file)
@@ -4558,13 +4558,6 @@ void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm,
                atomic_set(&mvm->queue_sync_counter,
                           mvm->trans->num_rx_queues);
 
-       /* TODO - remove this when we have RXQ config API */
-       if (mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22000) {
-               qmask = BIT(0);
-               if (notif->sync)
-                       atomic_set(&mvm->queue_sync_counter, 1);
-       }
-
        ret = iwl_mvm_notify_rx_queue(mvm, qmask, (u8 *)notif, size);
        if (ret) {
                IWL_ERR(mvm, "Failed to trigger RX queues sync (%d)\n", ret);
index 99c086048aea1cd9418308c388c6891ed48f15d9..06298356df6d0246fbf9c57567b7f538f7894ede 100644 (file)
@@ -449,6 +449,7 @@ static const struct iwl_hcmd_names iwl_mvm_data_path_names[] = {
        HCMD_NAME(UPDATE_MU_GROUPS_CMD),
        HCMD_NAME(TRIGGER_RX_QUEUES_NOTIF_CMD),
        HCMD_NAME(STA_HE_CTXT_CMD),
+       HCMD_NAME(RFH_QUEUE_CONFIG_CMD),
        HCMD_NAME(STA_PM_NOTIF),
        HCMD_NAME(MU_GROUP_MGMT_NOTIF),
        HCMD_NAME(RX_QUEUES_NOTIFICATION),