diff options
author | Johannes Berg <johannes.berg@intel.com> | 2015-05-22 07:41:07 -0400 |
---|---|---|
committer | Luca Coelho <luciano.coelho@intel.com> | 2015-10-05 07:34:51 -0400 |
commit | 0316d30ea3e66379cd30ed70a114bc282159bb4c (patch) | |
tree | 9e5971e275ad18534805cf34986ce15db43bc80e | |
parent | d3f555f493b037eb688adda6d8a682e9b69211ed (diff) |
iwlwifi: mvm: add minimal multi-RXQ infrastructure
Since the new multi-queue capability depends on a new firmware API,
we can already add some code for it. If the new API is present, a
new opmode ops struct is used that handles the new rx_rss method.
For now, only restructure the RX handling to distinguish between
the two. Future patches will convert the new infrastructure to
actually use the new RX descriptor layout.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/mvm.h | 6 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/ops.c | 104 |
2 files changed, 83 insertions, 27 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index f4e22f5a29d1..0d3aff1b4bad 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h | |||
@@ -970,6 +970,12 @@ static inline bool iwl_mvm_is_csum_supported(struct iwl_mvm *mvm) | |||
970 | IWL_UCODE_TLV_CAPA_CSUM_SUPPORT); | 970 | IWL_UCODE_TLV_CAPA_CSUM_SUPPORT); |
971 | } | 971 | } |
972 | 972 | ||
973 | static inline bool iwl_mvm_has_new_rx_api(struct iwl_mvm *mvm) | ||
974 | { | ||
975 | /* firmware flag isn't defined yet */ | ||
976 | return false; | ||
977 | } | ||
978 | |||
973 | extern const u8 iwl_mvm_ac_to_tx_fifo[]; | 979 | extern const u8 iwl_mvm_ac_to_tx_fifo[]; |
974 | 980 | ||
975 | struct iwl_rate_info { | 981 | struct iwl_rate_info { |
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index 0e8166fb31e9..064c100e45fe 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c | |||
@@ -89,6 +89,7 @@ MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); | |||
89 | MODULE_LICENSE("GPL"); | 89 | MODULE_LICENSE("GPL"); |
90 | 90 | ||
91 | static const struct iwl_op_mode_ops iwl_mvm_ops; | 91 | static const struct iwl_op_mode_ops iwl_mvm_ops; |
92 | static const struct iwl_op_mode_ops iwl_mvm_ops_mq; | ||
92 | 93 | ||
93 | struct iwl_mvm_mod_params iwlmvm_mod_params = { | 94 | struct iwl_mvm_mod_params iwlmvm_mod_params = { |
94 | .power_scheme = IWL_POWER_SCHEME_BPS, | 95 | .power_scheme = IWL_POWER_SCHEME_BPS, |
@@ -424,7 +425,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, | |||
424 | hw->max_tx_aggregation_subframes = cfg->max_tx_agg_size; | 425 | hw->max_tx_aggregation_subframes = cfg->max_tx_agg_size; |
425 | 426 | ||
426 | op_mode = hw->priv; | 427 | op_mode = hw->priv; |
427 | op_mode->ops = &iwl_mvm_ops; | ||
428 | 428 | ||
429 | mvm = IWL_OP_MODE_GET_MVM(op_mode); | 429 | mvm = IWL_OP_MODE_GET_MVM(op_mode); |
430 | mvm->dev = trans->dev; | 430 | mvm->dev = trans->dev; |
@@ -433,6 +433,15 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, | |||
433 | mvm->fw = fw; | 433 | mvm->fw = fw; |
434 | mvm->hw = hw; | 434 | mvm->hw = hw; |
435 | 435 | ||
436 | if (iwl_mvm_has_new_rx_api(mvm)) { | ||
437 | op_mode->ops = &iwl_mvm_ops_mq; | ||
438 | } else { | ||
439 | op_mode->ops = &iwl_mvm_ops; | ||
440 | |||
441 | if (WARN_ON(trans->num_rx_queues > 1)) | ||
442 | goto out_free; | ||
443 | } | ||
444 | |||
436 | mvm->restart_fw = iwlwifi_mod_params.restart_fw ? -1 : 0; | 445 | mvm->restart_fw = iwlwifi_mod_params.restart_fw ? -1 : 0; |
437 | 446 | ||
438 | mvm->aux_queue = 15; | 447 | mvm->aux_queue = 15; |
@@ -719,21 +728,11 @@ static inline void iwl_mvm_rx_check_trigger(struct iwl_mvm *mvm, | |||
719 | } | 728 | } |
720 | } | 729 | } |
721 | 730 | ||
722 | static void iwl_mvm_rx_dispatch(struct iwl_op_mode *op_mode, | 731 | static void iwl_mvm_rx_common(struct iwl_mvm *mvm, |
723 | struct napi_struct *napi, | 732 | struct iwl_rx_cmd_buffer *rxb, |
724 | struct iwl_rx_cmd_buffer *rxb) | 733 | struct iwl_rx_packet *pkt) |
725 | { | 734 | { |
726 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 735 | int i; |
727 | struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); | ||
728 | u8 i; | ||
729 | |||
730 | if (likely(pkt->hdr.cmd == REPLY_RX_MPDU_CMD)) { | ||
731 | iwl_mvm_rx_rx_mpdu(mvm, napi, rxb); | ||
732 | return; | ||
733 | } else if (pkt->hdr.cmd == REPLY_RX_PHY_CMD) { | ||
734 | iwl_mvm_rx_rx_phy_cmd(mvm, rxb); | ||
735 | return; | ||
736 | } | ||
737 | 736 | ||
738 | iwl_mvm_rx_check_trigger(mvm, pkt); | 737 | iwl_mvm_rx_check_trigger(mvm, pkt); |
739 | 738 | ||
@@ -773,6 +772,36 @@ static void iwl_mvm_rx_dispatch(struct iwl_op_mode *op_mode, | |||
773 | } | 772 | } |
774 | } | 773 | } |
775 | 774 | ||
775 | static void iwl_mvm_rx(struct iwl_op_mode *op_mode, | ||
776 | struct napi_struct *napi, | ||
777 | struct iwl_rx_cmd_buffer *rxb) | ||
778 | { | ||
779 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | ||
780 | struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); | ||
781 | |||
782 | if (likely(pkt->hdr.cmd == REPLY_RX_MPDU_CMD)) | ||
783 | iwl_mvm_rx_rx_mpdu(mvm, napi, rxb); | ||
784 | else if (pkt->hdr.cmd == REPLY_RX_PHY_CMD) | ||
785 | iwl_mvm_rx_rx_phy_cmd(mvm, rxb); | ||
786 | else | ||
787 | iwl_mvm_rx_common(mvm, rxb, pkt); | ||
788 | } | ||
789 | |||
790 | static void iwl_mvm_rx_mq(struct iwl_op_mode *op_mode, | ||
791 | struct napi_struct *napi, | ||
792 | struct iwl_rx_cmd_buffer *rxb) | ||
793 | { | ||
794 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | ||
795 | struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); | ||
796 | |||
797 | if (likely(pkt->hdr.cmd == REPLY_RX_MPDU_CMD)) | ||
798 | iwl_mvm_rx_rx_mpdu(mvm, napi, rxb); | ||
799 | else if (pkt->hdr.cmd == REPLY_RX_PHY_CMD) | ||
800 | iwl_mvm_rx_rx_phy_cmd(mvm, rxb); | ||
801 | else | ||
802 | iwl_mvm_rx_common(mvm, rxb, pkt); | ||
803 | } | ||
804 | |||
776 | static void iwl_mvm_stop_sw_queue(struct iwl_op_mode *op_mode, int queue) | 805 | static void iwl_mvm_stop_sw_queue(struct iwl_op_mode *op_mode, int queue) |
777 | { | 806 | { |
778 | struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); | 807 | struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); |
@@ -1366,17 +1395,38 @@ int iwl_mvm_exit_d0i3(struct iwl_op_mode *op_mode) | |||
1366 | return _iwl_mvm_exit_d0i3(mvm); | 1395 | return _iwl_mvm_exit_d0i3(mvm); |
1367 | } | 1396 | } |
1368 | 1397 | ||
1398 | #define IWL_MVM_COMMON_OPS \ | ||
1399 | /* these could be differentiated */ \ | ||
1400 | .queue_full = iwl_mvm_stop_sw_queue, \ | ||
1401 | .queue_not_full = iwl_mvm_wake_sw_queue, \ | ||
1402 | .hw_rf_kill = iwl_mvm_set_hw_rfkill_state, \ | ||
1403 | .free_skb = iwl_mvm_free_skb, \ | ||
1404 | .nic_error = iwl_mvm_nic_error, \ | ||
1405 | .cmd_queue_full = iwl_mvm_cmd_queue_full, \ | ||
1406 | .nic_config = iwl_mvm_nic_config, \ | ||
1407 | .enter_d0i3 = iwl_mvm_enter_d0i3, \ | ||
1408 | .exit_d0i3 = iwl_mvm_exit_d0i3, \ | ||
1409 | /* as we only register one, these MUST be common! */ \ | ||
1410 | .start = iwl_op_mode_mvm_start, \ | ||
1411 | .stop = iwl_op_mode_mvm_stop | ||
1412 | |||
1369 | static const struct iwl_op_mode_ops iwl_mvm_ops = { | 1413 | static const struct iwl_op_mode_ops iwl_mvm_ops = { |
1370 | .start = iwl_op_mode_mvm_start, | 1414 | IWL_MVM_COMMON_OPS, |
1371 | .stop = iwl_op_mode_mvm_stop, | 1415 | .rx = iwl_mvm_rx, |
1372 | .rx = iwl_mvm_rx_dispatch, | 1416 | }; |
1373 | .queue_full = iwl_mvm_stop_sw_queue, | 1417 | |
1374 | .queue_not_full = iwl_mvm_wake_sw_queue, | 1418 | static void iwl_mvm_rx_mq_rss(struct iwl_op_mode *op_mode, |
1375 | .hw_rf_kill = iwl_mvm_set_hw_rfkill_state, | 1419 | struct napi_struct *napi, |
1376 | .free_skb = iwl_mvm_free_skb, | 1420 | struct iwl_rx_cmd_buffer *rxb, |
1377 | .nic_error = iwl_mvm_nic_error, | 1421 | unsigned int queue) |
1378 | .cmd_queue_full = iwl_mvm_cmd_queue_full, | 1422 | { |
1379 | .nic_config = iwl_mvm_nic_config, | 1423 | struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); |
1380 | .enter_d0i3 = iwl_mvm_enter_d0i3, | 1424 | |
1381 | .exit_d0i3 = iwl_mvm_exit_d0i3, | 1425 | iwl_mvm_rx_rx_mpdu(mvm, napi, rxb); |
1426 | } | ||
1427 | |||
1428 | static const struct iwl_op_mode_ops iwl_mvm_ops_mq = { | ||
1429 | IWL_MVM_COMMON_OPS, | ||
1430 | .rx = iwl_mvm_rx_mq, | ||
1431 | .rx_rss = iwl_mvm_rx_mq_rss, | ||
1382 | }; | 1432 | }; |