diff options
author | Johannes Berg <johannes.berg@intel.com> | 2014-08-01 06:17:40 -0400 |
---|---|---|
committer | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2014-09-03 15:49:05 -0400 |
commit | d4578ea810ce468fdb8e1b7014818c31db9be5e2 (patch) | |
tree | af2b99803e49a976ccc17bf21506e379087a0c3e /drivers/net/wireless/iwlwifi/pcie/tx.c | |
parent | 0ade579cce06806353e5f601ff3285a0a7d1e398 (diff) |
iwlwifi: trans: allow skipping scheduler hardware config
In a later patch, the hardware configuration will be moved to
firmware. Prepare for this by allowing hardware configuration
in the transport to be skipped by not passing a configuration
on enable and passing configure_scd=false on disable.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/pcie/tx.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/pcie/tx.c | 99 |
1 files changed, 56 insertions, 43 deletions
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 5c95386c72bf..eb39e584cc6d 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c | |||
@@ -1070,37 +1070,41 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn, | |||
1070 | const struct iwl_trans_txq_scd_cfg *cfg) | 1070 | const struct iwl_trans_txq_scd_cfg *cfg) |
1071 | { | 1071 | { |
1072 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1072 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
1073 | u8 frame_limit = cfg->frame_limit; | 1073 | int fifo = -1; |
1074 | 1074 | ||
1075 | if (test_and_set_bit(txq_id, trans_pcie->queue_used)) | 1075 | if (test_and_set_bit(txq_id, trans_pcie->queue_used)) |
1076 | WARN_ONCE(1, "queue %d already used - expect issues", txq_id); | 1076 | WARN_ONCE(1, "queue %d already used - expect issues", txq_id); |
1077 | 1077 | ||
1078 | /* Stop this Tx queue before configuring it */ | 1078 | if (cfg) { |
1079 | iwl_scd_txq_set_inactive(trans, txq_id); | 1079 | fifo = cfg->fifo; |
1080 | 1080 | ||
1081 | /* Set this queue as a chain-building queue unless it is CMD queue */ | 1081 | /* Stop this Tx queue before configuring it */ |
1082 | if (txq_id != trans_pcie->cmd_queue) | 1082 | iwl_scd_txq_set_inactive(trans, txq_id); |
1083 | iwl_scd_txq_set_chain(trans, txq_id); | ||
1084 | 1083 | ||
1085 | /* If this queue is mapped to a certain station: it is an AGG queue */ | 1084 | /* Set this queue as a chain-building queue unless it is CMD */ |
1086 | if (cfg->sta_id >= 0) { | 1085 | if (txq_id != trans_pcie->cmd_queue) |
1087 | u16 ra_tid = BUILD_RAxTID(cfg->sta_id, cfg->tid); | 1086 | iwl_scd_txq_set_chain(trans, txq_id); |
1088 | 1087 | ||
1089 | /* Map receiver-address / traffic-ID to this queue */ | 1088 | /* If this queue is mapped to a certain station: it is an AGG */ |
1090 | iwl_pcie_txq_set_ratid_map(trans, ra_tid, txq_id); | 1089 | if (cfg->sta_id >= 0) { |
1090 | u16 ra_tid = BUILD_RAxTID(cfg->sta_id, cfg->tid); | ||
1091 | 1091 | ||
1092 | /* enable aggregations for the queue */ | 1092 | /* Map receiver-address / traffic-ID to this queue */ |
1093 | iwl_scd_txq_enable_agg(trans, txq_id); | 1093 | iwl_pcie_txq_set_ratid_map(trans, ra_tid, txq_id); |
1094 | trans_pcie->txq[txq_id].ampdu = true; | 1094 | |
1095 | } else { | 1095 | /* enable aggregations for the queue */ |
1096 | /* | 1096 | iwl_scd_txq_enable_agg(trans, txq_id); |
1097 | * disable aggregations for the queue, this will also make the | 1097 | trans_pcie->txq[txq_id].ampdu = true; |
1098 | * ra_tid mapping configuration irrelevant since it is now a | 1098 | } else { |
1099 | * non-AGG queue. | 1099 | /* |
1100 | */ | 1100 | * disable aggregations for the queue, this will also |
1101 | iwl_scd_txq_disable_agg(trans, txq_id); | 1101 | * make the ra_tid mapping configuration irrelevant |
1102 | * since it is now a non-AGG queue. | ||
1103 | */ | ||
1104 | iwl_scd_txq_disable_agg(trans, txq_id); | ||
1102 | 1105 | ||
1103 | ssn = trans_pcie->txq[txq_id].q.read_ptr; | 1106 | ssn = trans_pcie->txq[txq_id].q.read_ptr; |
1107 | } | ||
1104 | } | 1108 | } |
1105 | 1109 | ||
1106 | /* Place first TFD at index corresponding to start sequence number. | 1110 | /* Place first TFD at index corresponding to start sequence number. |
@@ -1108,32 +1112,39 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn, | |||
1108 | trans_pcie->txq[txq_id].q.read_ptr = (ssn & 0xff); | 1112 | trans_pcie->txq[txq_id].q.read_ptr = (ssn & 0xff); |
1109 | trans_pcie->txq[txq_id].q.write_ptr = (ssn & 0xff); | 1113 | trans_pcie->txq[txq_id].q.write_ptr = (ssn & 0xff); |
1110 | 1114 | ||
1111 | iwl_write_direct32(trans, HBUS_TARG_WRPTR, | 1115 | if (cfg) { |
1112 | (ssn & 0xff) | (txq_id << 8)); | 1116 | u8 frame_limit = cfg->frame_limit; |
1113 | iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), ssn); | 1117 | |
1118 | iwl_write_direct32(trans, HBUS_TARG_WRPTR, | ||
1119 | (ssn & 0xff) | (txq_id << 8)); | ||
1120 | iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), ssn); | ||
1114 | 1121 | ||
1115 | /* Set up Tx window size and frame limit for this queue */ | 1122 | /* Set up Tx window size and frame limit for this queue */ |
1116 | iwl_trans_write_mem32(trans, trans_pcie->scd_base_addr + | 1123 | iwl_trans_write_mem32(trans, trans_pcie->scd_base_addr + |
1117 | SCD_CONTEXT_QUEUE_OFFSET(txq_id), 0); | 1124 | SCD_CONTEXT_QUEUE_OFFSET(txq_id), 0); |
1118 | iwl_trans_write_mem32(trans, trans_pcie->scd_base_addr + | 1125 | iwl_trans_write_mem32(trans, |
1126 | trans_pcie->scd_base_addr + | ||
1119 | SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32), | 1127 | SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32), |
1120 | ((frame_limit << SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) & | 1128 | ((frame_limit << SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) & |
1121 | SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) | | 1129 | SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) | |
1122 | ((frame_limit << SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & | 1130 | ((frame_limit << SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & |
1123 | SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); | 1131 | SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); |
1124 | 1132 | ||
1125 | /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */ | 1133 | /* Set up status area in SRAM, map to Tx DMA/FIFO, activate */ |
1126 | iwl_write_prph(trans, SCD_QUEUE_STATUS_BITS(txq_id), | 1134 | iwl_write_prph(trans, SCD_QUEUE_STATUS_BITS(txq_id), |
1127 | (1 << SCD_QUEUE_STTS_REG_POS_ACTIVE) | | 1135 | (1 << SCD_QUEUE_STTS_REG_POS_ACTIVE) | |
1128 | (cfg->fifo << SCD_QUEUE_STTS_REG_POS_TXF) | | 1136 | (cfg->fifo << SCD_QUEUE_STTS_REG_POS_TXF) | |
1129 | (1 << SCD_QUEUE_STTS_REG_POS_WSL) | | 1137 | (1 << SCD_QUEUE_STTS_REG_POS_WSL) | |
1130 | SCD_QUEUE_STTS_REG_MSK); | 1138 | SCD_QUEUE_STTS_REG_MSK); |
1139 | } | ||
1140 | |||
1131 | trans_pcie->txq[txq_id].active = true; | 1141 | trans_pcie->txq[txq_id].active = true; |
1132 | IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d on FIFO %d WrPtr: %d\n", | 1142 | IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d on FIFO %d WrPtr: %d\n", |
1133 | txq_id, cfg->fifo, ssn & 0xff); | 1143 | txq_id, fifo, ssn & 0xff); |
1134 | } | 1144 | } |
1135 | 1145 | ||
1136 | void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) | 1146 | void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id, |
1147 | bool configure_scd) | ||
1137 | { | 1148 | { |
1138 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1149 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
1139 | u32 stts_addr = trans_pcie->scd_base_addr + | 1150 | u32 stts_addr = trans_pcie->scd_base_addr + |
@@ -1152,10 +1163,12 @@ void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) | |||
1152 | return; | 1163 | return; |
1153 | } | 1164 | } |
1154 | 1165 | ||
1155 | iwl_scd_txq_set_inactive(trans, txq_id); | 1166 | if (configure_scd) { |
1167 | iwl_scd_txq_set_inactive(trans, txq_id); | ||
1156 | 1168 | ||
1157 | iwl_trans_write_mem(trans, stts_addr, (void *)zero_val, | 1169 | iwl_trans_write_mem(trans, stts_addr, (void *)zero_val, |
1158 | ARRAY_SIZE(zero_val)); | 1170 | ARRAY_SIZE(zero_val)); |
1171 | } | ||
1159 | 1172 | ||
1160 | iwl_pcie_txq_unmap(trans, txq_id); | 1173 | iwl_pcie_txq_unmap(trans, txq_id); |
1161 | trans_pcie->txq[txq_id].ampdu = false; | 1174 | trans_pcie->txq[txq_id].ampdu = false; |