aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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: