aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSara Sharon <sara.sharon@intel.com>2015-12-31 04:49:18 -0500
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2016-02-01 09:40:27 -0500
commit43413a975d06e5e34016751fac27e29ec3d4d10f (patch)
tree51101d8db582b28565d83cfea3dafb277533fa76
parent6ad6c01fa74f649722eeca7308dc1fc4e43235cd (diff)
iwlwifi: mvm: support rss queues configuration command
9000 series supports multi-queue rx. The hardware needs to be configured with the hash functions to perform and indirection table that maps hash results to the relevant CPUs\queues. Support this configuration. Add debugfs hook to configure the indirection table in order to enable performance analysis. The configuration is stateless, receives a partial or full pattern and sends the command to the firmware. Signed-off-by: Sara Sharon <sara.sharon@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c44
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h33
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/fw.c29
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mvm.h1
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/ops.c4
6 files changed, 111 insertions, 2 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
index 5c0f93997b7b..005cc09757d2 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
@@ -7,6 +7,7 @@
7 * 7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
10 * Copyright(c) 2016 Intel Deutschland GmbH
10 * 11 *
11 * This program is free software; you can redistribute it and/or modify 12 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of version 2 of the GNU General Public License as 13 * it under the terms of version 2 of the GNU General Public License as
@@ -943,6 +944,47 @@ iwl_dbgfs_scan_ant_rxchain_write(struct iwl_mvm *mvm, char *buf,
943 return count; 944 return count;
944} 945}
945 946
947static ssize_t iwl_dbgfs_indirection_tbl_write(struct iwl_mvm *mvm,
948 char *buf, size_t count,
949 loff_t *ppos)
950{
951 struct iwl_rss_config_cmd cmd = {
952 .flags = cpu_to_le32(IWL_RSS_ENABLE),
953 .hash_mask = IWL_RSS_HASH_TYPE_IPV4_TCP |
954 IWL_RSS_HASH_TYPE_IPV4_PAYLOAD |
955 IWL_RSS_HASH_TYPE_IPV6_TCP |
956 IWL_RSS_HASH_TYPE_IPV6_PAYLOAD,
957 };
958 int ret, i, num_repeats, nbytes = count / 2;
959
960 ret = hex2bin(cmd.indirection_table, buf, nbytes);
961 if (ret)
962 return ret;
963
964 /*
965 * The input is the redirection table, partial or full.
966 * Repeat the pattern if needed.
967 * For example, input of 01020F will be repeated 42 times,
968 * indirecting RSS hash results to queues 1, 2, 15 (skipping
969 * queues 3 - 14).
970 */
971 num_repeats = ARRAY_SIZE(cmd.indirection_table) / nbytes;
972 for (i = 1; i < num_repeats; i++)
973 memcpy(&cmd.indirection_table[i * nbytes],
974 cmd.indirection_table, nbytes);
975 /* handle cut in the middle pattern for the last places */
976 memcpy(&cmd.indirection_table[i * nbytes], cmd.indirection_table,
977 ARRAY_SIZE(cmd.indirection_table) % nbytes);
978
979 memcpy(cmd.secret_key, mvm->secret_key, ARRAY_SIZE(cmd.secret_key));
980
981 mutex_lock(&mvm->mutex);
982 ret = iwl_mvm_send_cmd_pdu(mvm, RSS_CONFIG_CMD, 0, sizeof(cmd), &cmd);
983 mutex_unlock(&mvm->mutex);
984
985 return ret ?: count;
986}
987
946static ssize_t iwl_dbgfs_fw_dbg_conf_read(struct file *file, 988static ssize_t iwl_dbgfs_fw_dbg_conf_read(struct file *file,
947 char __user *user_buf, 989 char __user *user_buf,
948 size_t count, loff_t *ppos) 990 size_t count, loff_t *ppos)
@@ -1455,6 +1497,7 @@ MVM_DEBUGFS_READ_WRITE_FILE_OPS(d0i3_refs, 8);
1455MVM_DEBUGFS_READ_WRITE_FILE_OPS(fw_dbg_conf, 8); 1497MVM_DEBUGFS_READ_WRITE_FILE_OPS(fw_dbg_conf, 8);
1456MVM_DEBUGFS_WRITE_FILE_OPS(fw_dbg_collect, 64); 1498MVM_DEBUGFS_WRITE_FILE_OPS(fw_dbg_collect, 64);
1457MVM_DEBUGFS_WRITE_FILE_OPS(cont_recording, 8); 1499MVM_DEBUGFS_WRITE_FILE_OPS(cont_recording, 8);
1500MVM_DEBUGFS_WRITE_FILE_OPS(indirection_tbl, 16);
1458 1501
1459#ifdef CONFIG_IWLWIFI_BCAST_FILTERING 1502#ifdef CONFIG_IWLWIFI_BCAST_FILTERING
1460MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters, 256); 1503MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters, 256);
@@ -1499,6 +1542,7 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
1499 MVM_DEBUGFS_ADD_FILE(fw_dbg_collect, mvm->debugfs_dir, S_IWUSR); 1542 MVM_DEBUGFS_ADD_FILE(fw_dbg_collect, mvm->debugfs_dir, S_IWUSR);
1500 MVM_DEBUGFS_ADD_FILE(send_echo_cmd, mvm->debugfs_dir, S_IWUSR); 1543 MVM_DEBUGFS_ADD_FILE(send_echo_cmd, mvm->debugfs_dir, S_IWUSR);
1501 MVM_DEBUGFS_ADD_FILE(cont_recording, mvm->debugfs_dir, S_IWUSR); 1544 MVM_DEBUGFS_ADD_FILE(cont_recording, mvm->debugfs_dir, S_IWUSR);
1545 MVM_DEBUGFS_ADD_FILE(indirection_tbl, mvm->debugfs_dir, S_IWUSR);
1502 if (!debugfs_create_bool("enable_scan_iteration_notif", 1546 if (!debugfs_create_bool("enable_scan_iteration_notif",
1503 S_IRUSR | S_IWUSR, 1547 S_IRUSR | S_IWUSR,
1504 mvm->debugfs_dir, 1548 mvm->debugfs_dir,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h
index ab467cb9b97c..b45c61e1f45c 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h
@@ -7,7 +7,7 @@
7 * 7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
10 * Copyright(c) 2015 Intel Deutschland GmbH 10 * Copyright(c) 2015 - 2016 Intel Deutschland GmbH
11 * 11 *
12 * This program is free software; you can redistribute it and/or modify 12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of version 2 of the GNU General Public License as 13 * it under the terms of version 2 of the GNU General Public License as
@@ -34,7 +34,7 @@
34 * 34 *
35 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 35 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
36 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 36 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
37 * Copyright(c) 2015 Intel Deutschland GmbH 37 * Copyright(c) 2015 - 2016 Intel Deutschland GmbH
38 * All rights reserved. 38 * All rights reserved.
39 * 39 *
40 * Redistribution and use in source and binary forms, with or without 40 * Redistribution and use in source and binary forms, with or without
@@ -362,4 +362,33 @@ struct iwl_frame_release {
362 __le16 nssn; 362 __le16 nssn;
363}; 363};
364 364
365enum iwl_rss_hash_func_en {
366 IWL_RSS_HASH_TYPE_IPV4_TCP,
367 IWL_RSS_HASH_TYPE_IPV4_UDP,
368 IWL_RSS_HASH_TYPE_IPV4_PAYLOAD,
369 IWL_RSS_HASH_TYPE_IPV6_TCP,
370 IWL_RSS_HASH_TYPE_IPV6_UDP,
371 IWL_RSS_HASH_TYPE_IPV6_PAYLOAD,
372};
373
374#define IWL_RSS_HASH_KEY_CNT 10
375#define IWL_RSS_INDIRECTION_TABLE_SIZE 128
376#define IWL_RSS_ENABLE 1
377
378/**
379 * struct iwl_rss_config_cmd - RSS (Receive Side Scaling) configuration
380 *
381 * @flags: 1 - enable, 0 - disable
382 * @hash_mask: Type of RSS to use. Values are from %iwl_rss_hash_func_en
383 * @secret_key: 320 bit input of random key configuration from driver
384 * @indirection_table: indirection table
385 */
386struct iwl_rss_config_cmd {
387 __le32 flags;
388 u8 hash_mask;
389 u8 reserved[3];
390 __le32 secret_key[IWL_RSS_HASH_KEY_CNT];
391 u8 indirection_table[IWL_RSS_INDIRECTION_TABLE_SIZE];
392} __packed; /* RSS_CONFIG_CMD_API_S_VER_1 */
393
365#endif /* __fw_api_rx_h__ */ 394#endif /* __fw_api_rx_h__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
index b6b57273b8ba..f332497e29d1 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
@@ -213,6 +213,8 @@ enum {
213 213
214 MFUART_LOAD_NOTIFICATION = 0xb1, 214 MFUART_LOAD_NOTIFICATION = 0xb1,
215 215
216 RSS_CONFIG_CMD = 0xb3,
217
216 REPLY_RX_PHY_CMD = 0xc0, 218 REPLY_RX_PHY_CMD = 0xc0,
217 REPLY_RX_MPDU_CMD = 0xc1, 219 REPLY_RX_MPDU_CMD = 0xc1,
218 FRAME_RELEASE = 0xc3, 220 FRAME_RELEASE = 0xc3,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index 4ed5180c547b..070e2af05ca2 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -7,6 +7,7 @@
7 * 7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
10 * Copyright(c) 2016 Intel Deutschland GmbH
10 * 11 *
11 * This program is free software; you can redistribute it and/or modify 12 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of version 2 of the GNU General Public License as 13 * it under the terms of version 2 of the GNU General Public License as
@@ -107,6 +108,24 @@ static int iwl_send_tx_ant_cfg(struct iwl_mvm *mvm, u8 valid_tx_ant)
107 sizeof(tx_ant_cmd), &tx_ant_cmd); 108 sizeof(tx_ant_cmd), &tx_ant_cmd);
108} 109}
109 110
111static int iwl_send_rss_cfg_cmd(struct iwl_mvm *mvm)
112{
113 int i;
114 struct iwl_rss_config_cmd cmd = {
115 .flags = cpu_to_le32(IWL_RSS_ENABLE),
116 .hash_mask = IWL_RSS_HASH_TYPE_IPV4_TCP |
117 IWL_RSS_HASH_TYPE_IPV4_PAYLOAD |
118 IWL_RSS_HASH_TYPE_IPV6_TCP |
119 IWL_RSS_HASH_TYPE_IPV6_PAYLOAD,
120 };
121
122 for (i = 0; i < ARRAY_SIZE(cmd.indirection_table); i++)
123 cmd.indirection_table[i] = i % mvm->trans->num_rx_queues;
124 memcpy(cmd.secret_key, mvm->secret_key, ARRAY_SIZE(cmd.secret_key));
125
126 return iwl_mvm_send_cmd_pdu(mvm, RSS_CONFIG_CMD, 0, sizeof(cmd), &cmd);
127}
128
110static void iwl_free_fw_paging(struct iwl_mvm *mvm) 129static void iwl_free_fw_paging(struct iwl_mvm *mvm)
111{ 130{
112 int i; 131 int i;
@@ -894,6 +913,16 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
894 if (ret) 913 if (ret)
895 goto error; 914 goto error;
896 915
916 /* Init RSS configuration */
917 if (iwl_mvm_has_new_rx_api(mvm)) {
918 ret = iwl_send_rss_cfg_cmd(mvm);
919 if (ret) {
920 IWL_ERR(mvm, "Failed to configure RSS queues: %d\n",
921 ret);
922 goto error;
923 }
924 }
925
897 /* init the fw <-> mac80211 STA mapping */ 926 /* init the fw <-> mac80211 STA mapping */
898 for (i = 0; i < IWL_MVM_STATION_COUNT; i++) 927 for (i = 0; i < IWL_MVM_STATION_COUNT; i++)
899 RCU_INIT_POINTER(mvm->fw_id_to_mac_id[i], NULL); 928 RCU_INIT_POINTER(mvm->fw_id_to_mac_id[i], NULL);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index f87aa972fdce..747f7eb80f47 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -647,6 +647,7 @@ struct iwl_mvm {
647 atomic_t pending_frames[IWL_MVM_STATION_COUNT]; 647 atomic_t pending_frames[IWL_MVM_STATION_COUNT];
648 u32 tfd_drained[IWL_MVM_STATION_COUNT]; 648 u32 tfd_drained[IWL_MVM_STATION_COUNT];
649 u8 rx_ba_sessions; 649 u8 rx_ba_sessions;
650 u32 secret_key[IWL_RSS_HASH_KEY_CNT];
650 651
651 /* configured by mac80211 */ 652 /* configured by mac80211 */
652 u32 rts_threshold; 653 u32 rts_threshold;
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index 3c869ad6aaec..325ff8aa33f5 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -347,6 +347,7 @@ static const struct iwl_hcmd_names iwl_mvm_legacy_names[] = {
347 HCMD_NAME(MAC_PM_POWER_TABLE), 347 HCMD_NAME(MAC_PM_POWER_TABLE),
348 HCMD_NAME(TDLS_CHANNEL_SWITCH_NOTIFICATION), 348 HCMD_NAME(TDLS_CHANNEL_SWITCH_NOTIFICATION),
349 HCMD_NAME(MFUART_LOAD_NOTIFICATION), 349 HCMD_NAME(MFUART_LOAD_NOTIFICATION),
350 HCMD_NAME(RSS_CONFIG_CMD),
350 HCMD_NAME(SCAN_ITERATION_COMPLETE_UMAC), 351 HCMD_NAME(SCAN_ITERATION_COMPLETE_UMAC),
351 HCMD_NAME(REPLY_RX_PHY_CMD), 352 HCMD_NAME(REPLY_RX_PHY_CMD),
352 HCMD_NAME(REPLY_RX_MPDU_CMD), 353 HCMD_NAME(REPLY_RX_MPDU_CMD),
@@ -651,6 +652,9 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
651 652
652 iwl_mvm_tof_init(mvm); 653 iwl_mvm_tof_init(mvm);
653 654
655 /* init RSS hash key */
656 get_random_bytes(mvm->secret_key, ARRAY_SIZE(mvm->secret_key));
657
654 return op_mode; 658 return op_mode;
655 659
656 out_unregister: 660 out_unregister: