diff options
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c | 44 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h | 33 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 29 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 4 |
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 | ||
947 | static 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 | |||
946 | static ssize_t iwl_dbgfs_fw_dbg_conf_read(struct file *file, | 988 | static 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); | |||
1455 | MVM_DEBUGFS_READ_WRITE_FILE_OPS(fw_dbg_conf, 8); | 1497 | MVM_DEBUGFS_READ_WRITE_FILE_OPS(fw_dbg_conf, 8); |
1456 | MVM_DEBUGFS_WRITE_FILE_OPS(fw_dbg_collect, 64); | 1498 | MVM_DEBUGFS_WRITE_FILE_OPS(fw_dbg_collect, 64); |
1457 | MVM_DEBUGFS_WRITE_FILE_OPS(cont_recording, 8); | 1499 | MVM_DEBUGFS_WRITE_FILE_OPS(cont_recording, 8); |
1500 | MVM_DEBUGFS_WRITE_FILE_OPS(indirection_tbl, 16); | ||
1458 | 1501 | ||
1459 | #ifdef CONFIG_IWLWIFI_BCAST_FILTERING | 1502 | #ifdef CONFIG_IWLWIFI_BCAST_FILTERING |
1460 | MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters, 256); | 1503 | MVM_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 | ||
365 | enum 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 | */ | ||
386 | struct 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 | ||
111 | static 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 | |||
110 | static void iwl_free_fw_paging(struct iwl_mvm *mvm) | 129 | static 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: |