diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-trans-pcie.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 6172651d7e25..8170133d8173 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | |||
@@ -78,6 +78,10 @@ | |||
78 | 78 | ||
79 | #define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo)))) | 79 | #define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo)))) |
80 | 80 | ||
81 | #define SCD_QUEUECHAIN_SEL_ALL(trans, trans_pcie) \ | ||
82 | (((1<<cfg(trans)->base_params->num_of_queues) - 1) &\ | ||
83 | (~(1<<(trans_pcie)->cmd_queue))) | ||
84 | |||
81 | static int iwl_trans_rx_alloc(struct iwl_trans *trans) | 85 | static int iwl_trans_rx_alloc(struct iwl_trans *trans) |
82 | { | 86 | { |
83 | struct iwl_trans_pcie *trans_pcie = | 87 | struct iwl_trans_pcie *trans_pcie = |
@@ -301,6 +305,7 @@ static int iwl_trans_txq_alloc(struct iwl_trans *trans, | |||
301 | { | 305 | { |
302 | size_t tfd_sz = sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX; | 306 | size_t tfd_sz = sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX; |
303 | int i; | 307 | int i; |
308 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
304 | 309 | ||
305 | if (WARN_ON(txq->meta || txq->cmd || txq->skbs || txq->tfds)) | 310 | if (WARN_ON(txq->meta || txq->cmd || txq->skbs || txq->tfds)) |
306 | return -EINVAL; | 311 | return -EINVAL; |
@@ -313,7 +318,7 @@ static int iwl_trans_txq_alloc(struct iwl_trans *trans, | |||
313 | if (!txq->meta || !txq->cmd) | 318 | if (!txq->meta || !txq->cmd) |
314 | goto error; | 319 | goto error; |
315 | 320 | ||
316 | if (txq_id == trans->shrd->cmd_queue) | 321 | if (txq_id == trans_pcie->cmd_queue) |
317 | for (i = 0; i < slots_num; i++) { | 322 | for (i = 0; i < slots_num; i++) { |
318 | txq->cmd[i] = kmalloc(sizeof(struct iwl_device_cmd), | 323 | txq->cmd[i] = kmalloc(sizeof(struct iwl_device_cmd), |
319 | GFP_KERNEL); | 324 | GFP_KERNEL); |
@@ -324,7 +329,7 @@ static int iwl_trans_txq_alloc(struct iwl_trans *trans, | |||
324 | /* Alloc driver data array and TFD circular buffer */ | 329 | /* Alloc driver data array and TFD circular buffer */ |
325 | /* Driver private data, only for Tx (not command) queues, | 330 | /* Driver private data, only for Tx (not command) queues, |
326 | * not shared with device. */ | 331 | * not shared with device. */ |
327 | if (txq_id != trans->shrd->cmd_queue) { | 332 | if (txq_id != trans_pcie->cmd_queue) { |
328 | txq->skbs = kcalloc(TFD_QUEUE_SIZE_MAX, sizeof(txq->skbs[0]), | 333 | txq->skbs = kcalloc(TFD_QUEUE_SIZE_MAX, sizeof(txq->skbs[0]), |
329 | GFP_KERNEL); | 334 | GFP_KERNEL); |
330 | if (!txq->skbs) { | 335 | if (!txq->skbs) { |
@@ -352,7 +357,7 @@ error: | |||
352 | txq->skbs = NULL; | 357 | txq->skbs = NULL; |
353 | /* since txq->cmd has been zeroed, | 358 | /* since txq->cmd has been zeroed, |
354 | * all non allocated cmd[i] will be NULL */ | 359 | * all non allocated cmd[i] will be NULL */ |
355 | if (txq->cmd && txq_id == trans->shrd->cmd_queue) | 360 | if (txq->cmd && txq_id == trans_pcie->cmd_queue) |
356 | for (i = 0; i < slots_num; i++) | 361 | for (i = 0; i < slots_num; i++) |
357 | kfree(txq->cmd[i]); | 362 | kfree(txq->cmd[i]); |
358 | kfree(txq->meta); | 363 | kfree(txq->meta); |
@@ -418,7 +423,7 @@ static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id) | |||
418 | /* In the command queue, all the TBs are mapped as BIDI | 423 | /* In the command queue, all the TBs are mapped as BIDI |
419 | * so unmap them as such. | 424 | * so unmap them as such. |
420 | */ | 425 | */ |
421 | if (txq_id == trans->shrd->cmd_queue) | 426 | if (txq_id == trans_pcie->cmd_queue) |
422 | dma_dir = DMA_BIDIRECTIONAL; | 427 | dma_dir = DMA_BIDIRECTIONAL; |
423 | else | 428 | else |
424 | dma_dir = DMA_TO_DEVICE; | 429 | dma_dir = DMA_TO_DEVICE; |
@@ -454,7 +459,7 @@ static void iwl_tx_queue_free(struct iwl_trans *trans, int txq_id) | |||
454 | 459 | ||
455 | /* De-alloc array of command/tx buffers */ | 460 | /* De-alloc array of command/tx buffers */ |
456 | 461 | ||
457 | if (txq_id == trans->shrd->cmd_queue) | 462 | if (txq_id == trans_pcie->cmd_queue) |
458 | for (i = 0; i < txq->q.n_window; i++) | 463 | for (i = 0; i < txq->q.n_window; i++) |
459 | kfree(txq->cmd[i]); | 464 | kfree(txq->cmd[i]); |
460 | 465 | ||
@@ -551,7 +556,7 @@ static int iwl_trans_tx_alloc(struct iwl_trans *trans) | |||
551 | 556 | ||
552 | /* Alloc and init all Tx queues, including the command queue (#4/#9) */ | 557 | /* Alloc and init all Tx queues, including the command queue (#4/#9) */ |
553 | for (txq_id = 0; txq_id < hw_params(trans).max_txq_num; txq_id++) { | 558 | for (txq_id = 0; txq_id < hw_params(trans).max_txq_num; txq_id++) { |
554 | slots_num = (txq_id == trans->shrd->cmd_queue) ? | 559 | slots_num = (txq_id == trans->cmd_queue) ? |
555 | TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; | 560 | TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; |
556 | ret = iwl_trans_txq_alloc(trans, &trans_pcie->txq[txq_id], | 561 | ret = iwl_trans_txq_alloc(trans, &trans_pcie->txq[txq_id], |
557 | slots_num, txq_id); | 562 | slots_num, txq_id); |
@@ -596,7 +601,7 @@ static int iwl_tx_init(struct iwl_trans *trans) | |||
596 | 601 | ||
597 | /* Alloc and init all Tx queues, including the command queue (#4/#9) */ | 602 | /* Alloc and init all Tx queues, including the command queue (#4/#9) */ |
598 | for (txq_id = 0; txq_id < hw_params(trans).max_txq_num; txq_id++) { | 603 | for (txq_id = 0; txq_id < hw_params(trans).max_txq_num; txq_id++) { |
599 | slots_num = (txq_id == trans->shrd->cmd_queue) ? | 604 | slots_num = (txq_id == trans->cmd_queue) ? |
600 | TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; | 605 | TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; |
601 | ret = iwl_trans_txq_init(trans, &trans_pcie->txq[txq_id], | 606 | ret = iwl_trans_txq_init(trans, &trans_pcie->txq[txq_id], |
602 | slots_num, txq_id); | 607 | slots_num, txq_id); |
@@ -1130,7 +1135,7 @@ static void iwl_tx_start(struct iwl_trans *trans) | |||
1130 | reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN); | 1135 | reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN); |
1131 | 1136 | ||
1132 | iwl_write_prph(trans, SCD_QUEUECHAIN_SEL, | 1137 | iwl_write_prph(trans, SCD_QUEUECHAIN_SEL, |
1133 | SCD_QUEUECHAIN_SEL_ALL(trans)); | 1138 | SCD_QUEUECHAIN_SEL_ALL(trans, trans_pcie)); |
1134 | iwl_write_prph(trans, SCD_AGGR_SEL, 0); | 1139 | iwl_write_prph(trans, SCD_AGGR_SEL, 0); |
1135 | 1140 | ||
1136 | /* initiate the queues */ | 1141 | /* initiate the queues */ |
@@ -1162,7 +1167,7 @@ static void iwl_tx_start(struct iwl_trans *trans) | |||
1162 | else | 1167 | else |
1163 | queue_to_fifo = iwlagn_default_queue_to_tx_fifo; | 1168 | queue_to_fifo = iwlagn_default_queue_to_tx_fifo; |
1164 | 1169 | ||
1165 | iwl_trans_set_wr_ptrs(trans, trans->shrd->cmd_queue, 0); | 1170 | iwl_trans_set_wr_ptrs(trans, trans_pcie->cmd_queue, 0); |
1166 | 1171 | ||
1167 | /* make sure all queue are not stopped */ | 1172 | /* make sure all queue are not stopped */ |
1168 | memset(&trans_pcie->queue_stopped[0], 0, | 1173 | memset(&trans_pcie->queue_stopped[0], 0, |
@@ -1613,6 +1618,14 @@ static u32 iwl_trans_pcie_read32(struct iwl_trans *trans, u32 ofs) | |||
1613 | return readl(IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs); | 1618 | return readl(IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs); |
1614 | } | 1619 | } |
1615 | 1620 | ||
1621 | static void iwl_trans_pcie_configure(struct iwl_trans *trans, | ||
1622 | const struct iwl_trans_config *trans_cfg) | ||
1623 | { | ||
1624 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
1625 | |||
1626 | trans_pcie->cmd_queue = trans_cfg->cmd_queue; | ||
1627 | } | ||
1628 | |||
1616 | static void iwl_trans_pcie_free(struct iwl_trans *trans) | 1629 | static void iwl_trans_pcie_free(struct iwl_trans *trans) |
1617 | { | 1630 | { |
1618 | struct iwl_trans_pcie *trans_pcie = | 1631 | struct iwl_trans_pcie *trans_pcie = |
@@ -1673,7 +1686,7 @@ static int iwl_trans_pcie_wait_tx_queue_empty(struct iwl_trans *trans) | |||
1673 | 1686 | ||
1674 | /* waiting for all the tx frames complete might take a while */ | 1687 | /* waiting for all the tx frames complete might take a while */ |
1675 | for (cnt = 0; cnt < hw_params(trans).max_txq_num; cnt++) { | 1688 | for (cnt = 0; cnt < hw_params(trans).max_txq_num; cnt++) { |
1676 | if (cnt == trans->shrd->cmd_queue) | 1689 | if (cnt == trans->cmd_queue) |
1677 | continue; | 1690 | continue; |
1678 | txq = &trans_pcie->txq[cnt]; | 1691 | txq = &trans_pcie->txq[cnt]; |
1679 | q = &txq->q; | 1692 | q = &txq->q; |
@@ -2202,6 +2215,7 @@ const struct iwl_trans_ops trans_ops_pcie = { | |||
2202 | .write8 = iwl_trans_pcie_write8, | 2215 | .write8 = iwl_trans_pcie_write8, |
2203 | .write32 = iwl_trans_pcie_write32, | 2216 | .write32 = iwl_trans_pcie_write32, |
2204 | .read32 = iwl_trans_pcie_read32, | 2217 | .read32 = iwl_trans_pcie_read32, |
2218 | .configure = iwl_trans_pcie_configure, | ||
2205 | }; | 2219 | }; |
2206 | 2220 | ||
2207 | struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, | 2221 | struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, |