diff options
author | Golan Ben Ami <golan.ben.ami@intel.com> | 2018-04-03 11:37:51 -0400 |
---|---|---|
committer | Luca Coelho <luciano.coelho@intel.com> | 2018-08-31 04:38:41 -0400 |
commit | 1169310fa9a8d8a1fc94e406643444cac30ad8b1 (patch) | |
tree | b40eb5cf1246001db291b05b37d0a0f037ed40f4 /drivers/net/wireless | |
parent | 764f9de5027149518b1633e5846b21b9fb882363 (diff) |
iwlwifi: refactor txq_alloc for supporting more command type
Support more txq_alloc command types by moving the command declaration
to the gen specific area. While at it, move some of the code segments
to a common place for re-use.
Signed-off-by: Golan Ben Ami <golan.ben.ami@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/iwl-trans.h | 7 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/utils.c | 14 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/pcie/internal.h | 10 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c | 91 |
4 files changed, 82 insertions, 40 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h index 0a6c8759b911..388793b89856 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h | |||
@@ -562,7 +562,7 @@ struct iwl_trans_ops { | |||
562 | bool configure_scd); | 562 | bool configure_scd); |
563 | /* 22000 functions */ | 563 | /* 22000 functions */ |
564 | int (*txq_alloc)(struct iwl_trans *trans, | 564 | int (*txq_alloc)(struct iwl_trans *trans, |
565 | struct iwl_tx_queue_cfg_cmd *cmd, | 565 | __le16 flags, u8 sta_id, u8 tid, |
566 | int cmd_id, int size, | 566 | int cmd_id, int size, |
567 | unsigned int queue_wdg_timeout); | 567 | unsigned int queue_wdg_timeout); |
568 | void (*txq_free)(struct iwl_trans *trans, int queue); | 568 | void (*txq_free)(struct iwl_trans *trans, int queue); |
@@ -970,7 +970,7 @@ iwl_trans_txq_free(struct iwl_trans *trans, int queue) | |||
970 | 970 | ||
971 | static inline int | 971 | static inline int |
972 | iwl_trans_txq_alloc(struct iwl_trans *trans, | 972 | iwl_trans_txq_alloc(struct iwl_trans *trans, |
973 | struct iwl_tx_queue_cfg_cmd *cmd, | 973 | __le16 flags, u8 sta_id, u8 tid, |
974 | int cmd_id, int size, | 974 | int cmd_id, int size, |
975 | unsigned int wdg_timeout) | 975 | unsigned int wdg_timeout) |
976 | { | 976 | { |
@@ -984,7 +984,8 @@ iwl_trans_txq_alloc(struct iwl_trans *trans, | |||
984 | return -EIO; | 984 | return -EIO; |
985 | } | 985 | } |
986 | 986 | ||
987 | return trans->ops->txq_alloc(trans, cmd, cmd_id, size, wdg_timeout); | 987 | return trans->ops->txq_alloc(trans, flags, sta_id, tid, |
988 | cmd_id, size, wdg_timeout); | ||
988 | } | 989 | } |
989 | 990 | ||
990 | static inline void iwl_trans_txq_set_shared_mode(struct iwl_trans *trans, | 991 | static inline void iwl_trans_txq_set_shared_mode(struct iwl_trans *trans, |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c index f5a9e4026094..99a872769e90 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c | |||
@@ -720,19 +720,15 @@ static bool iwl_mvm_update_txq_mapping(struct iwl_mvm *mvm, int queue, | |||
720 | int iwl_mvm_tvqm_enable_txq(struct iwl_mvm *mvm, int mac80211_queue, | 720 | int iwl_mvm_tvqm_enable_txq(struct iwl_mvm *mvm, int mac80211_queue, |
721 | u8 sta_id, u8 tid, unsigned int timeout) | 721 | u8 sta_id, u8 tid, unsigned int timeout) |
722 | { | 722 | { |
723 | struct iwl_tx_queue_cfg_cmd cmd = { | ||
724 | .flags = cpu_to_le16(TX_QUEUE_CFG_ENABLE_QUEUE), | ||
725 | .sta_id = sta_id, | ||
726 | .tid = tid, | ||
727 | }; | ||
728 | int queue, size = IWL_DEFAULT_QUEUE_SIZE; | 723 | int queue, size = IWL_DEFAULT_QUEUE_SIZE; |
729 | 724 | ||
730 | if (cmd.tid == IWL_MAX_TID_COUNT) { | 725 | if (tid == IWL_MAX_TID_COUNT) { |
731 | cmd.tid = IWL_MGMT_TID; | 726 | tid = IWL_MGMT_TID; |
732 | size = IWL_MGMT_QUEUE_SIZE; | 727 | size = IWL_MGMT_QUEUE_SIZE; |
733 | } | 728 | } |
734 | queue = iwl_trans_txq_alloc(mvm->trans, (void *)&cmd, | 729 | queue = iwl_trans_txq_alloc(mvm->trans, |
735 | SCD_QUEUE_CFG, size, timeout); | 730 | cpu_to_le16(TX_QUEUE_CFG_ENABLE_QUEUE), |
731 | sta_id, tid, SCD_QUEUE_CFG, size, timeout); | ||
736 | 732 | ||
737 | if (queue < 0) { | 733 | if (queue < 0) { |
738 | IWL_DEBUG_TX_QUEUES(mvm, | 734 | IWL_DEBUG_TX_QUEUES(mvm, |
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h index 98d8da03ccfc..769b7354fabe 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h | |||
@@ -1036,8 +1036,16 @@ void iwl_pcie_alloc_fw_monitor(struct iwl_trans *trans, u8 max_power); | |||
1036 | int iwl_trans_pcie_gen2_start_fw(struct iwl_trans *trans, | 1036 | int iwl_trans_pcie_gen2_start_fw(struct iwl_trans *trans, |
1037 | const struct fw_img *fw, bool run_in_rfkill); | 1037 | const struct fw_img *fw, bool run_in_rfkill); |
1038 | void iwl_trans_pcie_gen2_fw_alive(struct iwl_trans *trans, u32 scd_addr); | 1038 | void iwl_trans_pcie_gen2_fw_alive(struct iwl_trans *trans, u32 scd_addr); |
1039 | void iwl_pcie_gen2_txq_free_memory(struct iwl_trans *trans, | ||
1040 | struct iwl_txq *txq); | ||
1041 | int iwl_trans_pcie_dyn_txq_alloc_dma(struct iwl_trans *trans, | ||
1042 | struct iwl_txq **intxq, int size, | ||
1043 | unsigned int timeout); | ||
1044 | int iwl_trans_pcie_txq_alloc_response(struct iwl_trans *trans, | ||
1045 | struct iwl_txq *txq, | ||
1046 | struct iwl_host_cmd *hcmd); | ||
1039 | int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans, | 1047 | int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans, |
1040 | struct iwl_tx_queue_cfg_cmd *cmd, | 1048 | __le16 flags, u8 sta_id, u8 tid, |
1041 | int cmd_id, int size, | 1049 | int cmd_id, int size, |
1042 | unsigned int timeout); | 1050 | unsigned int timeout); |
1043 | void iwl_trans_pcie_dyn_txq_free(struct iwl_trans *trans, int queue); | 1051 | void iwl_trans_pcie_dyn_txq_free(struct iwl_trans *trans, int queue); |
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c index 4a08f4eab1a5..a33fb335849e 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c | |||
@@ -1065,8 +1065,8 @@ void iwl_pcie_gen2_txq_unmap(struct iwl_trans *trans, int txq_id) | |||
1065 | iwl_wake_queue(trans, txq); | 1065 | iwl_wake_queue(trans, txq); |
1066 | } | 1066 | } |
1067 | 1067 | ||
1068 | static void iwl_pcie_gen2_txq_free_memory(struct iwl_trans *trans, | 1068 | void iwl_pcie_gen2_txq_free_memory(struct iwl_trans *trans, |
1069 | struct iwl_txq *txq) | 1069 | struct iwl_txq *txq) |
1070 | { | 1070 | { |
1071 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1071 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
1072 | struct device *dev = trans->dev; | 1072 | struct device *dev = trans->dev; |
@@ -1120,23 +1120,13 @@ static void iwl_pcie_gen2_txq_free(struct iwl_trans *trans, int txq_id) | |||
1120 | clear_bit(txq_id, trans_pcie->queue_used); | 1120 | clear_bit(txq_id, trans_pcie->queue_used); |
1121 | } | 1121 | } |
1122 | 1122 | ||
1123 | int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans, | 1123 | int iwl_trans_pcie_dyn_txq_alloc_dma(struct iwl_trans *trans, |
1124 | struct iwl_tx_queue_cfg_cmd *cmd, | 1124 | struct iwl_txq **intxq, int size, |
1125 | int cmd_id, int size, | 1125 | unsigned int timeout) |
1126 | unsigned int timeout) | ||
1127 | { | 1126 | { |
1128 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1127 | int ret; |
1129 | struct iwl_tx_queue_cfg_rsp *rsp; | ||
1130 | struct iwl_txq *txq; | ||
1131 | struct iwl_host_cmd hcmd = { | ||
1132 | .id = cmd_id, | ||
1133 | .len = { sizeof(*cmd) }, | ||
1134 | .data = { cmd, }, | ||
1135 | .flags = CMD_WANT_SKB, | ||
1136 | }; | ||
1137 | int ret, qid; | ||
1138 | u32 wr_ptr; | ||
1139 | 1128 | ||
1129 | struct iwl_txq *txq; | ||
1140 | txq = kzalloc(sizeof(*txq), GFP_KERNEL); | 1130 | txq = kzalloc(sizeof(*txq), GFP_KERNEL); |
1141 | if (!txq) | 1131 | if (!txq) |
1142 | return -ENOMEM; | 1132 | return -ENOMEM; |
@@ -1164,20 +1154,30 @@ int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans, | |||
1164 | 1154 | ||
1165 | txq->wd_timeout = msecs_to_jiffies(timeout); | 1155 | txq->wd_timeout = msecs_to_jiffies(timeout); |
1166 | 1156 | ||
1167 | cmd->tfdq_addr = cpu_to_le64(txq->dma_addr); | 1157 | *intxq = txq; |
1168 | cmd->byte_cnt_addr = cpu_to_le64(txq->bc_tbl.dma); | 1158 | return 0; |
1169 | cmd->cb_size = cpu_to_le32(TFD_QUEUE_CB_SIZE(size)); | ||
1170 | 1159 | ||
1171 | ret = iwl_trans_send_cmd(trans, &hcmd); | 1160 | error: |
1172 | if (ret) | 1161 | iwl_pcie_gen2_txq_free_memory(trans, txq); |
1173 | goto error; | 1162 | return ret; |
1163 | } | ||
1164 | |||
1165 | int iwl_trans_pcie_txq_alloc_response(struct iwl_trans *trans, | ||
1166 | struct iwl_txq *txq, | ||
1167 | struct iwl_host_cmd *hcmd) | ||
1168 | { | ||
1169 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
1170 | struct iwl_tx_queue_cfg_rsp *rsp; | ||
1171 | int ret, qid; | ||
1172 | u32 wr_ptr; | ||
1174 | 1173 | ||
1175 | if (WARN_ON(iwl_rx_packet_payload_len(hcmd.resp_pkt) != sizeof(*rsp))) { | 1174 | if (WARN_ON(iwl_rx_packet_payload_len(hcmd->resp_pkt) != |
1175 | sizeof(*rsp))) { | ||
1176 | ret = -EINVAL; | 1176 | ret = -EINVAL; |
1177 | goto error_free_resp; | 1177 | goto error_free_resp; |
1178 | } | 1178 | } |
1179 | 1179 | ||
1180 | rsp = (void *)hcmd.resp_pkt->data; | 1180 | rsp = (void *)hcmd->resp_pkt->data; |
1181 | qid = le16_to_cpu(rsp->queue_number); | 1181 | qid = le16_to_cpu(rsp->queue_number); |
1182 | wr_ptr = le16_to_cpu(rsp->write_pointer); | 1182 | wr_ptr = le16_to_cpu(rsp->write_pointer); |
1183 | 1183 | ||
@@ -1204,11 +1204,48 @@ int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans, | |||
1204 | (txq->write_ptr) | (qid << 16)); | 1204 | (txq->write_ptr) | (qid << 16)); |
1205 | IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d\n", qid); | 1205 | IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d\n", qid); |
1206 | 1206 | ||
1207 | iwl_free_resp(&hcmd); | 1207 | iwl_free_resp(hcmd); |
1208 | return qid; | 1208 | return qid; |
1209 | 1209 | ||
1210 | error_free_resp: | 1210 | error_free_resp: |
1211 | iwl_free_resp(&hcmd); | 1211 | iwl_free_resp(hcmd); |
1212 | iwl_pcie_gen2_txq_free_memory(trans, txq); | ||
1213 | return ret; | ||
1214 | } | ||
1215 | |||
1216 | int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans, | ||
1217 | __le16 flags, u8 sta_id, u8 tid, | ||
1218 | int cmd_id, int size, | ||
1219 | unsigned int timeout) | ||
1220 | { | ||
1221 | struct iwl_txq *txq = NULL; | ||
1222 | struct iwl_tx_queue_cfg_cmd cmd = { | ||
1223 | .flags = flags, | ||
1224 | .sta_id = sta_id, | ||
1225 | .tid = tid, | ||
1226 | }; | ||
1227 | struct iwl_host_cmd hcmd = { | ||
1228 | .id = cmd_id, | ||
1229 | .len = { sizeof(cmd) }, | ||
1230 | .data = { &cmd, }, | ||
1231 | .flags = CMD_WANT_SKB, | ||
1232 | }; | ||
1233 | int ret; | ||
1234 | |||
1235 | ret = iwl_trans_pcie_dyn_txq_alloc_dma(trans, &txq, size, timeout); | ||
1236 | if (ret) | ||
1237 | return ret; | ||
1238 | |||
1239 | cmd.tfdq_addr = cpu_to_le64(txq->dma_addr); | ||
1240 | cmd.byte_cnt_addr = cpu_to_le64(txq->bc_tbl.dma); | ||
1241 | cmd.cb_size = cpu_to_le32(TFD_QUEUE_CB_SIZE(size)); | ||
1242 | |||
1243 | ret = iwl_trans_send_cmd(trans, &hcmd); | ||
1244 | if (ret) | ||
1245 | goto error; | ||
1246 | |||
1247 | return iwl_trans_pcie_txq_alloc_response(trans, txq, &hcmd); | ||
1248 | |||
1212 | error: | 1249 | error: |
1213 | iwl_pcie_gen2_txq_free_memory(trans, txq); | 1250 | iwl_pcie_gen2_txq_free_memory(trans, txq); |
1214 | return ret; | 1251 | return ret; |