iwlwifi: support new tx api
authorGolan Ben Ami <golan.ben.ami@intel.com>
Sun, 4 Feb 2018 13:46:17 +0000 (15:46 +0200)
committerLuca Coelho <luciano.coelho@intel.com>
Thu, 26 Jul 2018 10:16:17 +0000 (13:16 +0300)
22560 devices use a new tx cmd api. Update the code to use
the new api.

Signed-off-by: Golan Ben Ami <golan.ben.ami@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
drivers/net/wireless/intel/iwlwifi/fw/api/tx.h
drivers/net/wireless/intel/iwlwifi/mvm/tx.c
drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c

index f285bacc8726523b8b3b38b44da3d019f8c61435..d71a6a837ec5ecb3b257da3534f66e3f9838cc10 100644 (file)
@@ -193,7 +193,8 @@ enum iwl_legacy_cmds {
        FW_GET_ITEM_CMD = 0x1a,
 
        /**
-        * @TX_CMD: uses &struct iwl_tx_cmd or &struct iwl_tx_cmd_gen2,
+        * @TX_CMD: uses &struct iwl_tx_cmd or &struct iwl_tx_cmd_gen2 or
+        *      &struct iwl_tx_cmd_gen3,
         *      response in &struct iwl_mvm_tx_resp or
         *      &struct iwl_mvm_tx_resp_v3
         */
index a2a40b515a3c8301848462275cb79a5caba3c95b..514b86123d3d366fd368e9d49f7d10222f77bae5 100644 (file)
@@ -7,6 +7,7 @@
  *
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * 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
@@ -28,6 +29,7 @@
  *
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * 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
@@ -320,6 +322,29 @@ struct iwl_tx_cmd_gen2 {
        struct ieee80211_hdr hdr[0];
 } __packed; /* TX_CMD_API_S_VER_7 */
 
+/**
+ * struct iwl_tx_cmd_gen3 - TX command struct to FW for 22560 devices
+ * ( TX_CMD = 0x1c )
+ * @len: in bytes of the payload, see below for details
+ * @flags: combination of &enum iwl_tx_cmd_flags
+ * @offload_assist: TX offload configuration
+ * @dram_info: FW internal DRAM storage
+ * @rate_n_flags: rate for *all* Tx attempts, if TX_CMD_FLG_STA_RATE_MSK is
+ *     cleared. Combination of RATE_MCS_*
+ * @ttl: time to live - packet lifetime limit. The FW should drop if
+ *     passed.
+ * @hdr: 802.11 header
+ */
+struct iwl_tx_cmd_gen3 {
+       __le16 len;
+       __le16 flags;
+       __le32 offload_assist;
+       struct iwl_dram_sec_info dram_info;
+       __le32 rate_n_flags;
+       __le64 ttl;
+       struct ieee80211_hdr hdr[0];
+} __packed; /* TX_CMD_API_S_VER_8 */
+
 /*
  * TX response related data
  */
index cf2591f2ac236ad9d03f54bffab350391750c21c..ff193dca2020c99987ca91df4a2d07ef6f58dbfd 100644 (file)
@@ -484,13 +484,15 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb,
 
        /* Make sure we zero enough of dev_cmd */
        BUILD_BUG_ON(sizeof(struct iwl_tx_cmd_gen2) > sizeof(*tx_cmd));
+       BUILD_BUG_ON(sizeof(struct iwl_tx_cmd_gen3) > sizeof(*tx_cmd));
 
        memset(dev_cmd, 0, sizeof(dev_cmd->hdr) + sizeof(*tx_cmd));
        dev_cmd->hdr.cmd = TX_CMD;
 
        if (iwl_mvm_has_new_tx_api(mvm)) {
-               struct iwl_tx_cmd_gen2 *cmd = (void *)dev_cmd->payload;
                u16 offload_assist = 0;
+               u32 rate_n_flags = 0;
+               u16 flags = 0;
 
                if (ieee80211_is_data_qos(hdr->frame_control)) {
                        u8 *qc = ieee80211_get_qos_ctl(hdr);
@@ -507,25 +509,43 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb,
                    !(offload_assist & BIT(TX_CMD_OFFLD_AMSDU)))
                        offload_assist |= BIT(TX_CMD_OFFLD_PAD);
 
-               cmd->offload_assist |= cpu_to_le16(offload_assist);
+               if (!info->control.hw_key)
+                       flags |= IWL_TX_FLAGS_ENCRYPT_DIS;
 
-               /* Total # bytes to be transmitted */
-               cmd->len = cpu_to_le16((u16)skb->len);
+               /* For data packets rate info comes from the fw */
+               if (!(ieee80211_is_data(hdr->frame_control) && sta)) {
+                       flags |= IWL_TX_FLAGS_CMD_RATE;
+                       rate_n_flags = iwl_mvm_get_tx_rate(mvm, info, sta);
+               }
 
-               /* Copy MAC header from skb into command buffer */
-               memcpy(cmd->hdr, hdr, hdrlen);
+               if (mvm->trans->cfg->device_family >=
+                   IWL_DEVICE_FAMILY_22560) {
+                       struct iwl_tx_cmd_gen3 *cmd = (void *)dev_cmd->payload;
 
-               if (!info->control.hw_key)
-                       cmd->flags |= cpu_to_le32(IWL_TX_FLAGS_ENCRYPT_DIS);
+                       cmd->offload_assist |= cpu_to_le32(offload_assist);
 
-               /* For data packets rate info comes from the fw */
-               if (ieee80211_is_data(hdr->frame_control) && sta)
-                       goto out;
+                       /* Total # bytes to be transmitted */
+                       cmd->len = cpu_to_le16((u16)skb->len);
 
-               cmd->flags |= cpu_to_le32(IWL_TX_FLAGS_CMD_RATE);
-               cmd->rate_n_flags =
-                       cpu_to_le32(iwl_mvm_get_tx_rate(mvm, info, sta));
+                       /* Copy MAC header from skb into command buffer */
+                       memcpy(cmd->hdr, hdr, hdrlen);
 
+                       cmd->flags = cpu_to_le16(flags);
+                       cmd->rate_n_flags = cpu_to_le32(rate_n_flags);
+               } else {
+                       struct iwl_tx_cmd_gen2 *cmd = (void *)dev_cmd->payload;
+
+                       cmd->offload_assist |= cpu_to_le16(offload_assist);
+
+                       /* Total # bytes to be transmitted */
+                       cmd->len = cpu_to_le16((u16)skb->len);
+
+                       /* Copy MAC header from skb into command buffer */
+                       memcpy(cmd->hdr, hdr, hdrlen);
+
+                       cmd->flags = cpu_to_le32(flags);
+                       cmd->rate_n_flags = cpu_to_le32(rate_n_flags);
+               }
                goto out;
        }
 
index 70dfa80b3d60d5d5dc6e81bead19eca7f44bc571..e3ae7f91206be4ef3a07121b2cca2be2790eaa51 100644 (file)
@@ -402,8 +402,14 @@ struct iwl_tfh_tfd *iwl_pcie_gen2_build_tfd(struct iwl_trans *trans,
         * (This calculation modifies the TX command, so do it before the
         * setup of the first TB)
         */
-       len = sizeof(struct iwl_tx_cmd_gen2) + sizeof(struct iwl_cmd_header) +
-             ieee80211_hdrlen(hdr->frame_control) - IWL_FIRST_TB_SIZE;
+       if (trans->cfg->device_family < IWL_DEVICE_FAMILY_22560)
+               len = sizeof(struct iwl_tx_cmd_gen2);
+       else
+               len = sizeof(struct iwl_tx_cmd_gen3);
+
+       len += sizeof(struct iwl_cmd_header) +
+               ieee80211_hdrlen(hdr->frame_control) -
+               IWL_FIRST_TB_SIZE;
 
        /* do not align A-MSDU to dword as the subframe header aligns it */
        if (amsdu)
@@ -480,9 +486,9 @@ int iwl_trans_pcie_gen2_tx(struct iwl_trans *trans, struct sk_buff *skb,
                           struct iwl_device_cmd *dev_cmd, int txq_id)
 {
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
-       struct iwl_tx_cmd_gen2 *tx_cmd = (void *)dev_cmd->payload;
        struct iwl_cmd_meta *out_meta;
        struct iwl_txq *txq = trans_pcie->txq[txq_id];
+       u16 cmd_len;
        int idx;
        void *tfd;
 
@@ -497,6 +503,18 @@ int iwl_trans_pcie_gen2_tx(struct iwl_trans *trans, struct sk_buff *skb,
 
        spin_lock(&txq->lock);
 
+       if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
+               struct iwl_tx_cmd_gen3 *tx_cmd_gen3 =
+                       (void *)dev_cmd->payload;
+
+               cmd_len = le16_to_cpu(tx_cmd_gen3->len);
+       } else {
+               struct iwl_tx_cmd_gen2 *tx_cmd_gen2 =
+                       (void *)dev_cmd->payload;
+
+               cmd_len = le16_to_cpu(tx_cmd_gen2->len);
+       }
+
        if (iwl_queue_space(trans, txq) < txq->high_mark) {
                iwl_stop_queue(trans, txq);
 
@@ -535,7 +553,7 @@ int iwl_trans_pcie_gen2_tx(struct iwl_trans *trans, struct sk_buff *skb,
        }
 
        /* Set up entry for this TFD in Tx byte-count array */
-       iwl_pcie_gen2_update_byte_tbl(trans_pcie, txq, le16_to_cpu(tx_cmd->len),
+       iwl_pcie_gen2_update_byte_tbl(trans_pcie, txq, cmd_len,
                                      iwl_pcie_gen2_get_num_tbs(trans, tfd));
 
        /* start timer if queue currently empty */