aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2015-05-22 07:41:07 -0400
committerLuca Coelho <luciano.coelho@intel.com>2015-10-05 07:34:51 -0400
commit0316d30ea3e66379cd30ed70a114bc282159bb4c (patch)
tree9e5971e275ad18534805cf34986ce15db43bc80e
parentd3f555f493b037eb688adda6d8a682e9b69211ed (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.h6
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c104
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
973static 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
973extern const u8 iwl_mvm_ac_to_tx_fifo[]; 979extern const u8 iwl_mvm_ac_to_tx_fifo[];
974 980
975struct iwl_rate_info { 981struct 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);
89MODULE_LICENSE("GPL"); 89MODULE_LICENSE("GPL");
90 90
91static const struct iwl_op_mode_ops iwl_mvm_ops; 91static const struct iwl_op_mode_ops iwl_mvm_ops;
92static const struct iwl_op_mode_ops iwl_mvm_ops_mq;
92 93
93struct iwl_mvm_mod_params iwlmvm_mod_params = { 94struct 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
722static void iwl_mvm_rx_dispatch(struct iwl_op_mode *op_mode, 731static 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
775static 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
790static 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
776static void iwl_mvm_stop_sw_queue(struct iwl_op_mode *op_mode, int queue) 805static 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
1369static const struct iwl_op_mode_ops iwl_mvm_ops = { 1413static 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, 1418static 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
1428static 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};