aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/pcie
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2013-03-08 15:53:47 -0500
committerJohn W. Linville <linville@tuxdriver.com>2013-03-08 15:53:47 -0500
commitcd309ab39351cfd5d0a310bd3d0eb76d0b31f66d (patch)
tree0a9bccc45ca1a02597ab35caca8c2fe92889f0b2 /drivers/net/wireless/iwlwifi/pcie
parent3d5c203272b25c4391397247cdb0059a04fccddf (diff)
parent25b9ea5c797b5d78f8ceced9ad9c7a7daf0db19c (diff)
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next
Diffstat (limited to 'drivers/net/wireless/iwlwifi/pcie')
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/1000.c141
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/2000.c243
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/5000.c180
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/6000.c403
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/7000.c111
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/cfg.h115
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/drv.c4
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/internal.h35
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/rx.c14
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c25
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c299
11 files changed, 199 insertions, 1371 deletions
diff --git a/drivers/net/wireless/iwlwifi/pcie/1000.c b/drivers/net/wireless/iwlwifi/pcie/1000.c
deleted file mode 100644
index ff3389757281..000000000000
--- a/drivers/net/wireless/iwlwifi/pcie/1000.c
+++ /dev/null
@@ -1,141 +0,0 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * Intel Linux Wireless <ilw@linux.intel.com>
23 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24 *
25 *****************************************************************************/
26
27#include <linux/module.h>
28#include <linux/stringify.h>
29#include "iwl-config.h"
30#include "iwl-csr.h"
31#include "iwl-agn-hw.h"
32#include "cfg.h"
33
34/* Highest firmware API version supported */
35#define IWL1000_UCODE_API_MAX 5
36#define IWL100_UCODE_API_MAX 5
37
38/* Oldest version we won't warn about */
39#define IWL1000_UCODE_API_OK 5
40#define IWL100_UCODE_API_OK 5
41
42/* Lowest firmware API version supported */
43#define IWL1000_UCODE_API_MIN 1
44#define IWL100_UCODE_API_MIN 5
45
46/* EEPROM version */
47#define EEPROM_1000_TX_POWER_VERSION (4)
48#define EEPROM_1000_EEPROM_VERSION (0x15C)
49
50#define IWL1000_FW_PRE "iwlwifi-1000-"
51#define IWL1000_MODULE_FIRMWARE(api) IWL1000_FW_PRE __stringify(api) ".ucode"
52
53#define IWL100_FW_PRE "iwlwifi-100-"
54#define IWL100_MODULE_FIRMWARE(api) IWL100_FW_PRE __stringify(api) ".ucode"
55
56
57static const struct iwl_base_params iwl1000_base_params = {
58 .num_of_queues = IWLAGN_NUM_QUEUES,
59 .eeprom_size = OTP_LOW_IMAGE_SIZE,
60 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
61 .max_ll_items = OTP_MAX_LL_ITEMS_1000,
62 .shadow_ram_support = false,
63 .led_compensation = 51,
64 .support_ct_kill_exit = true,
65 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF,
66 .chain_noise_scale = 1000,
67 .wd_timeout = IWL_WATCHDOG_DISABLED,
68 .max_event_log_size = 128,
69};
70
71static const struct iwl_ht_params iwl1000_ht_params = {
72 .ht_greenfield_support = true,
73 .use_rts_for_aggregation = true, /* use rts/cts protection */
74 .ht40_bands = BIT(IEEE80211_BAND_2GHZ),
75};
76
77static const struct iwl_eeprom_params iwl1000_eeprom_params = {
78 .regulatory_bands = {
79 EEPROM_REG_BAND_1_CHANNELS,
80 EEPROM_REG_BAND_2_CHANNELS,
81 EEPROM_REG_BAND_3_CHANNELS,
82 EEPROM_REG_BAND_4_CHANNELS,
83 EEPROM_REG_BAND_5_CHANNELS,
84 EEPROM_REG_BAND_24_HT40_CHANNELS,
85 EEPROM_REGULATORY_BAND_NO_HT40,
86 }
87};
88
89#define IWL_DEVICE_1000 \
90 .fw_name_pre = IWL1000_FW_PRE, \
91 .ucode_api_max = IWL1000_UCODE_API_MAX, \
92 .ucode_api_ok = IWL1000_UCODE_API_OK, \
93 .ucode_api_min = IWL1000_UCODE_API_MIN, \
94 .device_family = IWL_DEVICE_FAMILY_1000, \
95 .max_inst_size = IWLAGN_RTC_INST_SIZE, \
96 .max_data_size = IWLAGN_RTC_DATA_SIZE, \
97 .nvm_ver = EEPROM_1000_EEPROM_VERSION, \
98 .nvm_calib_ver = EEPROM_1000_TX_POWER_VERSION, \
99 .base_params = &iwl1000_base_params, \
100 .eeprom_params = &iwl1000_eeprom_params, \
101 .led_mode = IWL_LED_BLINK
102
103const struct iwl_cfg iwl1000_bgn_cfg = {
104 .name = "Intel(R) Centrino(R) Wireless-N 1000 BGN",
105 IWL_DEVICE_1000,
106 .ht_params = &iwl1000_ht_params,
107};
108
109const struct iwl_cfg iwl1000_bg_cfg = {
110 .name = "Intel(R) Centrino(R) Wireless-N 1000 BG",
111 IWL_DEVICE_1000,
112};
113
114#define IWL_DEVICE_100 \
115 .fw_name_pre = IWL100_FW_PRE, \
116 .ucode_api_max = IWL100_UCODE_API_MAX, \
117 .ucode_api_ok = IWL100_UCODE_API_OK, \
118 .ucode_api_min = IWL100_UCODE_API_MIN, \
119 .device_family = IWL_DEVICE_FAMILY_100, \
120 .max_inst_size = IWLAGN_RTC_INST_SIZE, \
121 .max_data_size = IWLAGN_RTC_DATA_SIZE, \
122 .nvm_ver = EEPROM_1000_EEPROM_VERSION, \
123 .nvm_calib_ver = EEPROM_1000_TX_POWER_VERSION, \
124 .base_params = &iwl1000_base_params, \
125 .eeprom_params = &iwl1000_eeprom_params, \
126 .led_mode = IWL_LED_RF_STATE, \
127 .rx_with_siso_diversity = true
128
129const struct iwl_cfg iwl100_bgn_cfg = {
130 .name = "Intel(R) Centrino(R) Wireless-N 100 BGN",
131 IWL_DEVICE_100,
132 .ht_params = &iwl1000_ht_params,
133};
134
135const struct iwl_cfg iwl100_bg_cfg = {
136 .name = "Intel(R) Centrino(R) Wireless-N 100 BG",
137 IWL_DEVICE_100,
138};
139
140MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_OK));
141MODULE_FIRMWARE(IWL100_MODULE_FIRMWARE(IWL100_UCODE_API_OK));
diff --git a/drivers/net/wireless/iwlwifi/pcie/2000.c b/drivers/net/wireless/iwlwifi/pcie/2000.c
deleted file mode 100644
index e7de33128b16..000000000000
--- a/drivers/net/wireless/iwlwifi/pcie/2000.c
+++ /dev/null
@@ -1,243 +0,0 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * Intel Linux Wireless <ilw@linux.intel.com>
23 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24 *
25 *****************************************************************************/
26
27#include <linux/module.h>
28#include <linux/stringify.h>
29#include "iwl-config.h"
30#include "iwl-agn-hw.h"
31#include "cfg.h"
32#include "dvm/commands.h" /* needed for BT for now */
33
34/* Highest firmware API version supported */
35#define IWL2030_UCODE_API_MAX 6
36#define IWL2000_UCODE_API_MAX 6
37#define IWL105_UCODE_API_MAX 6
38#define IWL135_UCODE_API_MAX 6
39
40/* Oldest version we won't warn about */
41#define IWL2030_UCODE_API_OK 6
42#define IWL2000_UCODE_API_OK 6
43#define IWL105_UCODE_API_OK 6
44#define IWL135_UCODE_API_OK 6
45
46/* Lowest firmware API version supported */
47#define IWL2030_UCODE_API_MIN 5
48#define IWL2000_UCODE_API_MIN 5
49#define IWL105_UCODE_API_MIN 5
50#define IWL135_UCODE_API_MIN 5
51
52/* EEPROM version */
53#define EEPROM_2000_TX_POWER_VERSION (6)
54#define EEPROM_2000_EEPROM_VERSION (0x805)
55
56
57#define IWL2030_FW_PRE "iwlwifi-2030-"
58#define IWL2030_MODULE_FIRMWARE(api) IWL2030_FW_PRE __stringify(api) ".ucode"
59
60#define IWL2000_FW_PRE "iwlwifi-2000-"
61#define IWL2000_MODULE_FIRMWARE(api) IWL2000_FW_PRE __stringify(api) ".ucode"
62
63#define IWL105_FW_PRE "iwlwifi-105-"
64#define IWL105_MODULE_FIRMWARE(api) IWL105_FW_PRE __stringify(api) ".ucode"
65
66#define IWL135_FW_PRE "iwlwifi-135-"
67#define IWL135_MODULE_FIRMWARE(api) IWL135_FW_PRE __stringify(api) ".ucode"
68
69static const struct iwl_base_params iwl2000_base_params = {
70 .eeprom_size = OTP_LOW_IMAGE_SIZE,
71 .num_of_queues = IWLAGN_NUM_QUEUES,
72 .pll_cfg_val = 0,
73 .max_ll_items = OTP_MAX_LL_ITEMS_2x00,
74 .shadow_ram_support = true,
75 .led_compensation = 51,
76 .adv_thermal_throttle = true,
77 .support_ct_kill_exit = true,
78 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
79 .chain_noise_scale = 1000,
80 .wd_timeout = IWL_DEF_WD_TIMEOUT,
81 .max_event_log_size = 512,
82 .shadow_reg_enable = false, /* TODO: fix bugs using this feature */
83 .hd_v2 = true,
84};
85
86
87static const struct iwl_base_params iwl2030_base_params = {
88 .eeprom_size = OTP_LOW_IMAGE_SIZE,
89 .num_of_queues = IWLAGN_NUM_QUEUES,
90 .pll_cfg_val = 0,
91 .max_ll_items = OTP_MAX_LL_ITEMS_2x00,
92 .shadow_ram_support = true,
93 .led_compensation = 57,
94 .adv_thermal_throttle = true,
95 .support_ct_kill_exit = true,
96 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
97 .chain_noise_scale = 1000,
98 .wd_timeout = IWL_LONG_WD_TIMEOUT,
99 .max_event_log_size = 512,
100 .shadow_reg_enable = false, /* TODO: fix bugs using this feature */
101 .hd_v2 = true,
102};
103
104static const struct iwl_ht_params iwl2000_ht_params = {
105 .ht_greenfield_support = true,
106 .use_rts_for_aggregation = true, /* use rts/cts protection */
107 .ht40_bands = BIT(IEEE80211_BAND_2GHZ),
108};
109
110static const struct iwl_bt_params iwl2030_bt_params = {
111 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
112 .advanced_bt_coexist = true,
113 .agg_time_limit = BT_AGG_THRESHOLD_DEF,
114 .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
115 .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT32,
116 .bt_sco_disable = true,
117 .bt_session_2 = true,
118};
119
120static const struct iwl_eeprom_params iwl20x0_eeprom_params = {
121 .regulatory_bands = {
122 EEPROM_REG_BAND_1_CHANNELS,
123 EEPROM_REG_BAND_2_CHANNELS,
124 EEPROM_REG_BAND_3_CHANNELS,
125 EEPROM_REG_BAND_4_CHANNELS,
126 EEPROM_REG_BAND_5_CHANNELS,
127 EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
128 EEPROM_REGULATORY_BAND_NO_HT40,
129 },
130 .enhanced_txpower = true,
131};
132
133#define IWL_DEVICE_2000 \
134 .fw_name_pre = IWL2000_FW_PRE, \
135 .ucode_api_max = IWL2000_UCODE_API_MAX, \
136 .ucode_api_ok = IWL2000_UCODE_API_OK, \
137 .ucode_api_min = IWL2000_UCODE_API_MIN, \
138 .device_family = IWL_DEVICE_FAMILY_2000, \
139 .max_inst_size = IWL60_RTC_INST_SIZE, \
140 .max_data_size = IWL60_RTC_DATA_SIZE, \
141 .nvm_ver = EEPROM_2000_EEPROM_VERSION, \
142 .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
143 .base_params = &iwl2000_base_params, \
144 .eeprom_params = &iwl20x0_eeprom_params, \
145 .need_temp_offset_calib = true, \
146 .temp_offset_v2 = true, \
147 .led_mode = IWL_LED_RF_STATE
148
149const struct iwl_cfg iwl2000_2bgn_cfg = {
150 .name = "Intel(R) Centrino(R) Wireless-N 2200 BGN",
151 IWL_DEVICE_2000,
152 .ht_params = &iwl2000_ht_params,
153};
154
155const struct iwl_cfg iwl2000_2bgn_d_cfg = {
156 .name = "Intel(R) Centrino(R) Wireless-N 2200D BGN",
157 IWL_DEVICE_2000,
158 .ht_params = &iwl2000_ht_params,
159};
160
161#define IWL_DEVICE_2030 \
162 .fw_name_pre = IWL2030_FW_PRE, \
163 .ucode_api_max = IWL2030_UCODE_API_MAX, \
164 .ucode_api_ok = IWL2030_UCODE_API_OK, \
165 .ucode_api_min = IWL2030_UCODE_API_MIN, \
166 .device_family = IWL_DEVICE_FAMILY_2030, \
167 .max_inst_size = IWL60_RTC_INST_SIZE, \
168 .max_data_size = IWL60_RTC_DATA_SIZE, \
169 .nvm_ver = EEPROM_2000_EEPROM_VERSION, \
170 .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
171 .base_params = &iwl2030_base_params, \
172 .bt_params = &iwl2030_bt_params, \
173 .eeprom_params = &iwl20x0_eeprom_params, \
174 .need_temp_offset_calib = true, \
175 .temp_offset_v2 = true, \
176 .led_mode = IWL_LED_RF_STATE, \
177 .adv_pm = true
178
179const struct iwl_cfg iwl2030_2bgn_cfg = {
180 .name = "Intel(R) Centrino(R) Wireless-N 2230 BGN",
181 IWL_DEVICE_2030,
182 .ht_params = &iwl2000_ht_params,
183};
184
185#define IWL_DEVICE_105 \
186 .fw_name_pre = IWL105_FW_PRE, \
187 .ucode_api_max = IWL105_UCODE_API_MAX, \
188 .ucode_api_ok = IWL105_UCODE_API_OK, \
189 .ucode_api_min = IWL105_UCODE_API_MIN, \
190 .device_family = IWL_DEVICE_FAMILY_105, \
191 .max_inst_size = IWL60_RTC_INST_SIZE, \
192 .max_data_size = IWL60_RTC_DATA_SIZE, \
193 .nvm_ver = EEPROM_2000_EEPROM_VERSION, \
194 .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
195 .base_params = &iwl2000_base_params, \
196 .eeprom_params = &iwl20x0_eeprom_params, \
197 .need_temp_offset_calib = true, \
198 .temp_offset_v2 = true, \
199 .led_mode = IWL_LED_RF_STATE, \
200 .adv_pm = true, \
201 .rx_with_siso_diversity = true
202
203const struct iwl_cfg iwl105_bgn_cfg = {
204 .name = "Intel(R) Centrino(R) Wireless-N 105 BGN",
205 IWL_DEVICE_105,
206 .ht_params = &iwl2000_ht_params,
207};
208
209const struct iwl_cfg iwl105_bgn_d_cfg = {
210 .name = "Intel(R) Centrino(R) Wireless-N 105D BGN",
211 IWL_DEVICE_105,
212 .ht_params = &iwl2000_ht_params,
213};
214
215#define IWL_DEVICE_135 \
216 .fw_name_pre = IWL135_FW_PRE, \
217 .ucode_api_max = IWL135_UCODE_API_MAX, \
218 .ucode_api_ok = IWL135_UCODE_API_OK, \
219 .ucode_api_min = IWL135_UCODE_API_MIN, \
220 .device_family = IWL_DEVICE_FAMILY_135, \
221 .max_inst_size = IWL60_RTC_INST_SIZE, \
222 .max_data_size = IWL60_RTC_DATA_SIZE, \
223 .nvm_ver = EEPROM_2000_EEPROM_VERSION, \
224 .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
225 .base_params = &iwl2030_base_params, \
226 .bt_params = &iwl2030_bt_params, \
227 .eeprom_params = &iwl20x0_eeprom_params, \
228 .need_temp_offset_calib = true, \
229 .temp_offset_v2 = true, \
230 .led_mode = IWL_LED_RF_STATE, \
231 .adv_pm = true, \
232 .rx_with_siso_diversity = true
233
234const struct iwl_cfg iwl135_bgn_cfg = {
235 .name = "Intel(R) Centrino(R) Wireless-N 135 BGN",
236 IWL_DEVICE_135,
237 .ht_params = &iwl2000_ht_params,
238};
239
240MODULE_FIRMWARE(IWL2000_MODULE_FIRMWARE(IWL2000_UCODE_API_OK));
241MODULE_FIRMWARE(IWL2030_MODULE_FIRMWARE(IWL2030_UCODE_API_OK));
242MODULE_FIRMWARE(IWL105_MODULE_FIRMWARE(IWL105_UCODE_API_OK));
243MODULE_FIRMWARE(IWL135_MODULE_FIRMWARE(IWL135_UCODE_API_OK));
diff --git a/drivers/net/wireless/iwlwifi/pcie/5000.c b/drivers/net/wireless/iwlwifi/pcie/5000.c
deleted file mode 100644
index 5096f7c96ab6..000000000000
--- a/drivers/net/wireless/iwlwifi/pcie/5000.c
+++ /dev/null
@@ -1,180 +0,0 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * Intel Linux Wireless <ilw@linux.intel.com>
23 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24 *
25 *****************************************************************************/
26
27#include <linux/module.h>
28#include <linux/stringify.h>
29#include "iwl-config.h"
30#include "iwl-agn-hw.h"
31#include "iwl-csr.h"
32#include "cfg.h"
33
34/* Highest firmware API version supported */
35#define IWL5000_UCODE_API_MAX 5
36#define IWL5150_UCODE_API_MAX 2
37
38/* Oldest version we won't warn about */
39#define IWL5000_UCODE_API_OK 5
40#define IWL5150_UCODE_API_OK 2
41
42/* Lowest firmware API version supported */
43#define IWL5000_UCODE_API_MIN 1
44#define IWL5150_UCODE_API_MIN 1
45
46/* EEPROM versions */
47#define EEPROM_5000_TX_POWER_VERSION (4)
48#define EEPROM_5000_EEPROM_VERSION (0x11A)
49#define EEPROM_5050_TX_POWER_VERSION (4)
50#define EEPROM_5050_EEPROM_VERSION (0x21E)
51
52#define IWL5000_FW_PRE "iwlwifi-5000-"
53#define IWL5000_MODULE_FIRMWARE(api) IWL5000_FW_PRE __stringify(api) ".ucode"
54
55#define IWL5150_FW_PRE "iwlwifi-5150-"
56#define IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE __stringify(api) ".ucode"
57
58static const struct iwl_base_params iwl5000_base_params = {
59 .eeprom_size = IWLAGN_EEPROM_IMG_SIZE,
60 .num_of_queues = IWLAGN_NUM_QUEUES,
61 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
62 .led_compensation = 51,
63 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
64 .chain_noise_scale = 1000,
65 .wd_timeout = IWL_WATCHDOG_DISABLED,
66 .max_event_log_size = 512,
67 .no_idle_support = true,
68};
69
70static const struct iwl_ht_params iwl5000_ht_params = {
71 .ht_greenfield_support = true,
72 .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ),
73};
74
75static const struct iwl_eeprom_params iwl5000_eeprom_params = {
76 .regulatory_bands = {
77 EEPROM_REG_BAND_1_CHANNELS,
78 EEPROM_REG_BAND_2_CHANNELS,
79 EEPROM_REG_BAND_3_CHANNELS,
80 EEPROM_REG_BAND_4_CHANNELS,
81 EEPROM_REG_BAND_5_CHANNELS,
82 EEPROM_REG_BAND_24_HT40_CHANNELS,
83 EEPROM_REG_BAND_52_HT40_CHANNELS
84 },
85};
86
87#define IWL_DEVICE_5000 \
88 .fw_name_pre = IWL5000_FW_PRE, \
89 .ucode_api_max = IWL5000_UCODE_API_MAX, \
90 .ucode_api_ok = IWL5000_UCODE_API_OK, \
91 .ucode_api_min = IWL5000_UCODE_API_MIN, \
92 .device_family = IWL_DEVICE_FAMILY_5000, \
93 .max_inst_size = IWLAGN_RTC_INST_SIZE, \
94 .max_data_size = IWLAGN_RTC_DATA_SIZE, \
95 .nvm_ver = EEPROM_5000_EEPROM_VERSION, \
96 .nvm_calib_ver = EEPROM_5000_TX_POWER_VERSION, \
97 .base_params = &iwl5000_base_params, \
98 .eeprom_params = &iwl5000_eeprom_params, \
99 .led_mode = IWL_LED_BLINK
100
101const struct iwl_cfg iwl5300_agn_cfg = {
102 .name = "Intel(R) Ultimate N WiFi Link 5300 AGN",
103 IWL_DEVICE_5000,
104 /* at least EEPROM 0x11A has wrong info */
105 .valid_tx_ant = ANT_ABC, /* .cfg overwrite */
106 .valid_rx_ant = ANT_ABC, /* .cfg overwrite */
107 .ht_params = &iwl5000_ht_params,
108};
109
110const struct iwl_cfg iwl5100_bgn_cfg = {
111 .name = "Intel(R) WiFi Link 5100 BGN",
112 IWL_DEVICE_5000,
113 .valid_tx_ant = ANT_B, /* .cfg overwrite */
114 .valid_rx_ant = ANT_AB, /* .cfg overwrite */
115 .ht_params = &iwl5000_ht_params,
116};
117
118const struct iwl_cfg iwl5100_abg_cfg = {
119 .name = "Intel(R) WiFi Link 5100 ABG",
120 IWL_DEVICE_5000,
121 .valid_tx_ant = ANT_B, /* .cfg overwrite */
122 .valid_rx_ant = ANT_AB, /* .cfg overwrite */
123};
124
125const struct iwl_cfg iwl5100_agn_cfg = {
126 .name = "Intel(R) WiFi Link 5100 AGN",
127 IWL_DEVICE_5000,
128 .valid_tx_ant = ANT_B, /* .cfg overwrite */
129 .valid_rx_ant = ANT_AB, /* .cfg overwrite */
130 .ht_params = &iwl5000_ht_params,
131};
132
133const struct iwl_cfg iwl5350_agn_cfg = {
134 .name = "Intel(R) WiMAX/WiFi Link 5350 AGN",
135 .fw_name_pre = IWL5000_FW_PRE,
136 .ucode_api_max = IWL5000_UCODE_API_MAX,
137 .ucode_api_ok = IWL5000_UCODE_API_OK,
138 .ucode_api_min = IWL5000_UCODE_API_MIN,
139 .device_family = IWL_DEVICE_FAMILY_5000,
140 .max_inst_size = IWLAGN_RTC_INST_SIZE,
141 .max_data_size = IWLAGN_RTC_DATA_SIZE,
142 .nvm_ver = EEPROM_5050_EEPROM_VERSION,
143 .nvm_calib_ver = EEPROM_5050_TX_POWER_VERSION,
144 .base_params = &iwl5000_base_params,
145 .eeprom_params = &iwl5000_eeprom_params,
146 .ht_params = &iwl5000_ht_params,
147 .led_mode = IWL_LED_BLINK,
148 .internal_wimax_coex = true,
149};
150
151#define IWL_DEVICE_5150 \
152 .fw_name_pre = IWL5150_FW_PRE, \
153 .ucode_api_max = IWL5150_UCODE_API_MAX, \
154 .ucode_api_ok = IWL5150_UCODE_API_OK, \
155 .ucode_api_min = IWL5150_UCODE_API_MIN, \
156 .device_family = IWL_DEVICE_FAMILY_5150, \
157 .max_inst_size = IWLAGN_RTC_INST_SIZE, \
158 .max_data_size = IWLAGN_RTC_DATA_SIZE, \
159 .nvm_ver = EEPROM_5050_EEPROM_VERSION, \
160 .nvm_calib_ver = EEPROM_5050_TX_POWER_VERSION, \
161 .base_params = &iwl5000_base_params, \
162 .eeprom_params = &iwl5000_eeprom_params, \
163 .no_xtal_calib = true, \
164 .led_mode = IWL_LED_BLINK, \
165 .internal_wimax_coex = true
166
167const struct iwl_cfg iwl5150_agn_cfg = {
168 .name = "Intel(R) WiMAX/WiFi Link 5150 AGN",
169 IWL_DEVICE_5150,
170 .ht_params = &iwl5000_ht_params,
171
172};
173
174const struct iwl_cfg iwl5150_abg_cfg = {
175 .name = "Intel(R) WiMAX/WiFi Link 5150 ABG",
176 IWL_DEVICE_5150,
177};
178
179MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_OK));
180MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_OK));
diff --git a/drivers/net/wireless/iwlwifi/pcie/6000.c b/drivers/net/wireless/iwlwifi/pcie/6000.c
deleted file mode 100644
index 801ff49796dd..000000000000
--- a/drivers/net/wireless/iwlwifi/pcie/6000.c
+++ /dev/null
@@ -1,403 +0,0 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * Intel Linux Wireless <ilw@linux.intel.com>
23 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24 *
25 *****************************************************************************/
26
27#include <linux/module.h>
28#include <linux/stringify.h>
29#include "iwl-config.h"
30#include "iwl-agn-hw.h"
31#include "cfg.h"
32#include "dvm/commands.h" /* needed for BT for now */
33
34/* Highest firmware API version supported */
35#define IWL6000_UCODE_API_MAX 6
36#define IWL6050_UCODE_API_MAX 5
37#define IWL6000G2_UCODE_API_MAX 6
38#define IWL6035_UCODE_API_MAX 6
39
40/* Oldest version we won't warn about */
41#define IWL6000_UCODE_API_OK 4
42#define IWL6000G2_UCODE_API_OK 5
43#define IWL6050_UCODE_API_OK 5
44#define IWL6000G2B_UCODE_API_OK 6
45#define IWL6035_UCODE_API_OK 6
46
47/* Lowest firmware API version supported */
48#define IWL6000_UCODE_API_MIN 4
49#define IWL6050_UCODE_API_MIN 4
50#define IWL6000G2_UCODE_API_MIN 5
51#define IWL6035_UCODE_API_MIN 6
52
53/* EEPROM versions */
54#define EEPROM_6000_TX_POWER_VERSION (4)
55#define EEPROM_6000_EEPROM_VERSION (0x423)
56#define EEPROM_6050_TX_POWER_VERSION (4)
57#define EEPROM_6050_EEPROM_VERSION (0x532)
58#define EEPROM_6150_TX_POWER_VERSION (6)
59#define EEPROM_6150_EEPROM_VERSION (0x553)
60#define EEPROM_6005_TX_POWER_VERSION (6)
61#define EEPROM_6005_EEPROM_VERSION (0x709)
62#define EEPROM_6030_TX_POWER_VERSION (6)
63#define EEPROM_6030_EEPROM_VERSION (0x709)
64#define EEPROM_6035_TX_POWER_VERSION (6)
65#define EEPROM_6035_EEPROM_VERSION (0x753)
66
67#define IWL6000_FW_PRE "iwlwifi-6000-"
68#define IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE __stringify(api) ".ucode"
69
70#define IWL6050_FW_PRE "iwlwifi-6050-"
71#define IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE __stringify(api) ".ucode"
72
73#define IWL6005_FW_PRE "iwlwifi-6000g2a-"
74#define IWL6005_MODULE_FIRMWARE(api) IWL6005_FW_PRE __stringify(api) ".ucode"
75
76#define IWL6030_FW_PRE "iwlwifi-6000g2b-"
77#define IWL6030_MODULE_FIRMWARE(api) IWL6030_FW_PRE __stringify(api) ".ucode"
78
79static const struct iwl_base_params iwl6000_base_params = {
80 .eeprom_size = OTP_LOW_IMAGE_SIZE,
81 .num_of_queues = IWLAGN_NUM_QUEUES,
82 .pll_cfg_val = 0,
83 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
84 .shadow_ram_support = true,
85 .led_compensation = 51,
86 .adv_thermal_throttle = true,
87 .support_ct_kill_exit = true,
88 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
89 .chain_noise_scale = 1000,
90 .wd_timeout = IWL_DEF_WD_TIMEOUT,
91 .max_event_log_size = 512,
92 .shadow_reg_enable = false, /* TODO: fix bugs using this feature */
93};
94
95static const struct iwl_base_params iwl6050_base_params = {
96 .eeprom_size = OTP_LOW_IMAGE_SIZE,
97 .num_of_queues = IWLAGN_NUM_QUEUES,
98 .pll_cfg_val = 0,
99 .max_ll_items = OTP_MAX_LL_ITEMS_6x50,
100 .shadow_ram_support = true,
101 .led_compensation = 51,
102 .adv_thermal_throttle = true,
103 .support_ct_kill_exit = true,
104 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
105 .chain_noise_scale = 1500,
106 .wd_timeout = IWL_DEF_WD_TIMEOUT,
107 .max_event_log_size = 1024,
108 .shadow_reg_enable = false, /* TODO: fix bugs using this feature */
109};
110
111static const struct iwl_base_params iwl6000_g2_base_params = {
112 .eeprom_size = OTP_LOW_IMAGE_SIZE,
113 .num_of_queues = IWLAGN_NUM_QUEUES,
114 .pll_cfg_val = 0,
115 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
116 .shadow_ram_support = true,
117 .led_compensation = 57,
118 .adv_thermal_throttle = true,
119 .support_ct_kill_exit = true,
120 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
121 .chain_noise_scale = 1000,
122 .wd_timeout = IWL_LONG_WD_TIMEOUT,
123 .max_event_log_size = 512,
124 .shadow_reg_enable = false, /* TODO: fix bugs using this feature */
125};
126
127static const struct iwl_ht_params iwl6000_ht_params = {
128 .ht_greenfield_support = true,
129 .use_rts_for_aggregation = true, /* use rts/cts protection */
130 .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ),
131};
132
133static const struct iwl_bt_params iwl6000_bt_params = {
134 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
135 .advanced_bt_coexist = true,
136 .agg_time_limit = BT_AGG_THRESHOLD_DEF,
137 .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
138 .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT,
139 .bt_sco_disable = true,
140};
141
142static const struct iwl_eeprom_params iwl6000_eeprom_params = {
143 .regulatory_bands = {
144 EEPROM_REG_BAND_1_CHANNELS,
145 EEPROM_REG_BAND_2_CHANNELS,
146 EEPROM_REG_BAND_3_CHANNELS,
147 EEPROM_REG_BAND_4_CHANNELS,
148 EEPROM_REG_BAND_5_CHANNELS,
149 EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
150 EEPROM_REG_BAND_52_HT40_CHANNELS
151 },
152 .enhanced_txpower = true,
153};
154
155#define IWL_DEVICE_6005 \
156 .fw_name_pre = IWL6005_FW_PRE, \
157 .ucode_api_max = IWL6000G2_UCODE_API_MAX, \
158 .ucode_api_ok = IWL6000G2_UCODE_API_OK, \
159 .ucode_api_min = IWL6000G2_UCODE_API_MIN, \
160 .device_family = IWL_DEVICE_FAMILY_6005, \
161 .max_inst_size = IWL60_RTC_INST_SIZE, \
162 .max_data_size = IWL60_RTC_DATA_SIZE, \
163 .nvm_ver = EEPROM_6005_EEPROM_VERSION, \
164 .nvm_calib_ver = EEPROM_6005_TX_POWER_VERSION, \
165 .base_params = &iwl6000_g2_base_params, \
166 .eeprom_params = &iwl6000_eeprom_params, \
167 .need_temp_offset_calib = true, \
168 .led_mode = IWL_LED_RF_STATE
169
170const struct iwl_cfg iwl6005_2agn_cfg = {
171 .name = "Intel(R) Centrino(R) Advanced-N 6205 AGN",
172 IWL_DEVICE_6005,
173 .ht_params = &iwl6000_ht_params,
174};
175
176const struct iwl_cfg iwl6005_2abg_cfg = {
177 .name = "Intel(R) Centrino(R) Advanced-N 6205 ABG",
178 IWL_DEVICE_6005,
179};
180
181const struct iwl_cfg iwl6005_2bg_cfg = {
182 .name = "Intel(R) Centrino(R) Advanced-N 6205 BG",
183 IWL_DEVICE_6005,
184};
185
186const struct iwl_cfg iwl6005_2agn_sff_cfg = {
187 .name = "Intel(R) Centrino(R) Advanced-N 6205S AGN",
188 IWL_DEVICE_6005,
189 .ht_params = &iwl6000_ht_params,
190};
191
192const struct iwl_cfg iwl6005_2agn_d_cfg = {
193 .name = "Intel(R) Centrino(R) Advanced-N 6205D AGN",
194 IWL_DEVICE_6005,
195 .ht_params = &iwl6000_ht_params,
196};
197
198const struct iwl_cfg iwl6005_2agn_mow1_cfg = {
199 .name = "Intel(R) Centrino(R) Advanced-N 6206 AGN",
200 IWL_DEVICE_6005,
201 .ht_params = &iwl6000_ht_params,
202};
203
204const struct iwl_cfg iwl6005_2agn_mow2_cfg = {
205 .name = "Intel(R) Centrino(R) Advanced-N 6207 AGN",
206 IWL_DEVICE_6005,
207 .ht_params = &iwl6000_ht_params,
208};
209
210#define IWL_DEVICE_6030 \
211 .fw_name_pre = IWL6030_FW_PRE, \
212 .ucode_api_max = IWL6000G2_UCODE_API_MAX, \
213 .ucode_api_ok = IWL6000G2B_UCODE_API_OK, \
214 .ucode_api_min = IWL6000G2_UCODE_API_MIN, \
215 .device_family = IWL_DEVICE_FAMILY_6030, \
216 .max_inst_size = IWL60_RTC_INST_SIZE, \
217 .max_data_size = IWL60_RTC_DATA_SIZE, \
218 .nvm_ver = EEPROM_6030_EEPROM_VERSION, \
219 .nvm_calib_ver = EEPROM_6030_TX_POWER_VERSION, \
220 .base_params = &iwl6000_g2_base_params, \
221 .bt_params = &iwl6000_bt_params, \
222 .eeprom_params = &iwl6000_eeprom_params, \
223 .need_temp_offset_calib = true, \
224 .led_mode = IWL_LED_RF_STATE, \
225 .adv_pm = true \
226
227const struct iwl_cfg iwl6030_2agn_cfg = {
228 .name = "Intel(R) Centrino(R) Advanced-N 6230 AGN",
229 IWL_DEVICE_6030,
230 .ht_params = &iwl6000_ht_params,
231};
232
233const struct iwl_cfg iwl6030_2abg_cfg = {
234 .name = "Intel(R) Centrino(R) Advanced-N 6230 ABG",
235 IWL_DEVICE_6030,
236};
237
238const struct iwl_cfg iwl6030_2bgn_cfg = {
239 .name = "Intel(R) Centrino(R) Advanced-N 6230 BGN",
240 IWL_DEVICE_6030,
241 .ht_params = &iwl6000_ht_params,
242};
243
244const struct iwl_cfg iwl6030_2bg_cfg = {
245 .name = "Intel(R) Centrino(R) Advanced-N 6230 BG",
246 IWL_DEVICE_6030,
247};
248
249#define IWL_DEVICE_6035 \
250 .fw_name_pre = IWL6030_FW_PRE, \
251 .ucode_api_max = IWL6035_UCODE_API_MAX, \
252 .ucode_api_ok = IWL6035_UCODE_API_OK, \
253 .ucode_api_min = IWL6035_UCODE_API_MIN, \
254 .device_family = IWL_DEVICE_FAMILY_6030, \
255 .max_inst_size = IWL60_RTC_INST_SIZE, \
256 .max_data_size = IWL60_RTC_DATA_SIZE, \
257 .nvm_ver = EEPROM_6030_EEPROM_VERSION, \
258 .nvm_calib_ver = EEPROM_6030_TX_POWER_VERSION, \
259 .base_params = &iwl6000_g2_base_params, \
260 .bt_params = &iwl6000_bt_params, \
261 .eeprom_params = &iwl6000_eeprom_params, \
262 .need_temp_offset_calib = true, \
263 .led_mode = IWL_LED_RF_STATE, \
264 .adv_pm = true
265
266const struct iwl_cfg iwl6035_2agn_cfg = {
267 .name = "Intel(R) Centrino(R) Advanced-N 6235 AGN",
268 IWL_DEVICE_6035,
269 .ht_params = &iwl6000_ht_params,
270};
271
272const struct iwl_cfg iwl1030_bgn_cfg = {
273 .name = "Intel(R) Centrino(R) Wireless-N 1030 BGN",
274 IWL_DEVICE_6030,
275 .ht_params = &iwl6000_ht_params,
276};
277
278const struct iwl_cfg iwl1030_bg_cfg = {
279 .name = "Intel(R) Centrino(R) Wireless-N 1030 BG",
280 IWL_DEVICE_6030,
281};
282
283const struct iwl_cfg iwl130_bgn_cfg = {
284 .name = "Intel(R) Centrino(R) Wireless-N 130 BGN",
285 IWL_DEVICE_6030,
286 .ht_params = &iwl6000_ht_params,
287 .rx_with_siso_diversity = true,
288};
289
290const struct iwl_cfg iwl130_bg_cfg = {
291 .name = "Intel(R) Centrino(R) Wireless-N 130 BG",
292 IWL_DEVICE_6030,
293 .rx_with_siso_diversity = true,
294};
295
296/*
297 * "i": Internal configuration, use internal Power Amplifier
298 */
299#define IWL_DEVICE_6000i \
300 .fw_name_pre = IWL6000_FW_PRE, \
301 .ucode_api_max = IWL6000_UCODE_API_MAX, \
302 .ucode_api_ok = IWL6000_UCODE_API_OK, \
303 .ucode_api_min = IWL6000_UCODE_API_MIN, \
304 .device_family = IWL_DEVICE_FAMILY_6000i, \
305 .max_inst_size = IWL60_RTC_INST_SIZE, \
306 .max_data_size = IWL60_RTC_DATA_SIZE, \
307 .valid_tx_ant = ANT_BC, /* .cfg overwrite */ \
308 .valid_rx_ant = ANT_BC, /* .cfg overwrite */ \
309 .nvm_ver = EEPROM_6000_EEPROM_VERSION, \
310 .nvm_calib_ver = EEPROM_6000_TX_POWER_VERSION, \
311 .base_params = &iwl6000_base_params, \
312 .eeprom_params = &iwl6000_eeprom_params, \
313 .led_mode = IWL_LED_BLINK
314
315const struct iwl_cfg iwl6000i_2agn_cfg = {
316 .name = "Intel(R) Centrino(R) Advanced-N 6200 AGN",
317 IWL_DEVICE_6000i,
318 .ht_params = &iwl6000_ht_params,
319};
320
321const struct iwl_cfg iwl6000i_2abg_cfg = {
322 .name = "Intel(R) Centrino(R) Advanced-N 6200 ABG",
323 IWL_DEVICE_6000i,
324};
325
326const struct iwl_cfg iwl6000i_2bg_cfg = {
327 .name = "Intel(R) Centrino(R) Advanced-N 6200 BG",
328 IWL_DEVICE_6000i,
329};
330
331#define IWL_DEVICE_6050 \
332 .fw_name_pre = IWL6050_FW_PRE, \
333 .ucode_api_max = IWL6050_UCODE_API_MAX, \
334 .ucode_api_min = IWL6050_UCODE_API_MIN, \
335 .device_family = IWL_DEVICE_FAMILY_6050, \
336 .max_inst_size = IWL60_RTC_INST_SIZE, \
337 .max_data_size = IWL60_RTC_DATA_SIZE, \
338 .valid_tx_ant = ANT_AB, /* .cfg overwrite */ \
339 .valid_rx_ant = ANT_AB, /* .cfg overwrite */ \
340 .nvm_ver = EEPROM_6050_EEPROM_VERSION, \
341 .nvm_calib_ver = EEPROM_6050_TX_POWER_VERSION, \
342 .base_params = &iwl6050_base_params, \
343 .eeprom_params = &iwl6000_eeprom_params, \
344 .led_mode = IWL_LED_BLINK, \
345 .internal_wimax_coex = true
346
347const struct iwl_cfg iwl6050_2agn_cfg = {
348 .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 AGN",
349 IWL_DEVICE_6050,
350 .ht_params = &iwl6000_ht_params,
351};
352
353const struct iwl_cfg iwl6050_2abg_cfg = {
354 .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 ABG",
355 IWL_DEVICE_6050,
356};
357
358#define IWL_DEVICE_6150 \
359 .fw_name_pre = IWL6050_FW_PRE, \
360 .ucode_api_max = IWL6050_UCODE_API_MAX, \
361 .ucode_api_min = IWL6050_UCODE_API_MIN, \
362 .device_family = IWL_DEVICE_FAMILY_6150, \
363 .max_inst_size = IWL60_RTC_INST_SIZE, \
364 .max_data_size = IWL60_RTC_DATA_SIZE, \
365 .nvm_ver = EEPROM_6150_EEPROM_VERSION, \
366 .nvm_calib_ver = EEPROM_6150_TX_POWER_VERSION, \
367 .base_params = &iwl6050_base_params, \
368 .eeprom_params = &iwl6000_eeprom_params, \
369 .led_mode = IWL_LED_BLINK, \
370 .internal_wimax_coex = true
371
372const struct iwl_cfg iwl6150_bgn_cfg = {
373 .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BGN",
374 IWL_DEVICE_6150,
375 .ht_params = &iwl6000_ht_params,
376};
377
378const struct iwl_cfg iwl6150_bg_cfg = {
379 .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BG",
380 IWL_DEVICE_6150,
381};
382
383const struct iwl_cfg iwl6000_3agn_cfg = {
384 .name = "Intel(R) Centrino(R) Ultimate-N 6300 AGN",
385 .fw_name_pre = IWL6000_FW_PRE,
386 .ucode_api_max = IWL6000_UCODE_API_MAX,
387 .ucode_api_ok = IWL6000_UCODE_API_OK,
388 .ucode_api_min = IWL6000_UCODE_API_MIN,
389 .device_family = IWL_DEVICE_FAMILY_6000,
390 .max_inst_size = IWL60_RTC_INST_SIZE,
391 .max_data_size = IWL60_RTC_DATA_SIZE,
392 .nvm_ver = EEPROM_6000_EEPROM_VERSION,
393 .nvm_calib_ver = EEPROM_6000_TX_POWER_VERSION,
394 .base_params = &iwl6000_base_params,
395 .eeprom_params = &iwl6000_eeprom_params,
396 .ht_params = &iwl6000_ht_params,
397 .led_mode = IWL_LED_BLINK,
398};
399
400MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_OK));
401MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_OK));
402MODULE_FIRMWARE(IWL6005_MODULE_FIRMWARE(IWL6000G2_UCODE_API_OK));
403MODULE_FIRMWARE(IWL6030_MODULE_FIRMWARE(IWL6000G2B_UCODE_API_OK));
diff --git a/drivers/net/wireless/iwlwifi/pcie/7000.c b/drivers/net/wireless/iwlwifi/pcie/7000.c
deleted file mode 100644
index 6e35b2b72332..000000000000
--- a/drivers/net/wireless/iwlwifi/pcie/7000.c
+++ /dev/null
@@ -1,111 +0,0 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * Intel Linux Wireless <ilw@linux.intel.com>
23 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24 *
25 *****************************************************************************/
26
27#include <linux/module.h>
28#include <linux/stringify.h>
29#include "iwl-config.h"
30#include "iwl-agn-hw.h"
31#include "cfg.h"
32
33/* Highest firmware API version supported */
34#define IWL7260_UCODE_API_MAX 6
35#define IWL3160_UCODE_API_MAX 6
36
37/* Oldest version we won't warn about */
38#define IWL7260_UCODE_API_OK 6
39#define IWL3160_UCODE_API_OK 6
40
41/* Lowest firmware API version supported */
42#define IWL7260_UCODE_API_MIN 6
43#define IWL3160_UCODE_API_MIN 6
44
45/* NVM versions */
46#define IWL7260_NVM_VERSION 0x0a1d
47#define IWL7260_TX_POWER_VERSION 0xffff /* meaningless */
48#define IWL3160_NVM_VERSION 0x709
49#define IWL3160_TX_POWER_VERSION 0xffff /* meaningless */
50
51#define IWL7260_FW_PRE "iwlwifi-7260-"
52#define IWL7260_MODULE_FIRMWARE(api) IWL7260_FW_PRE __stringify(api) ".ucode"
53
54#define IWL3160_FW_PRE "iwlwifi-3160-"
55#define IWL3160_MODULE_FIRMWARE(api) IWL3160_FW_PRE __stringify(api) ".ucode"
56
57static const struct iwl_base_params iwl7000_base_params = {
58 .eeprom_size = OTP_LOW_IMAGE_SIZE,
59 .num_of_queues = IWLAGN_NUM_QUEUES,
60 .pll_cfg_val = 0,
61 .shadow_ram_support = true,
62 .led_compensation = 57,
63 .adv_thermal_throttle = true,
64 .support_ct_kill_exit = true,
65 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
66 .chain_noise_scale = 1000,
67 .wd_timeout = IWL_LONG_WD_TIMEOUT,
68 .max_event_log_size = 512,
69 .shadow_reg_enable = false, /* TODO: fix bugs using this feature */
70};
71
72static const struct iwl_ht_params iwl7000_ht_params = {
73 .ht_greenfield_support = true,
74 .use_rts_for_aggregation = true, /* use rts/cts protection */
75 .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ),
76};
77
78#define IWL_DEVICE_7000 \
79 .ucode_api_max = IWL7260_UCODE_API_MAX, \
80 .ucode_api_ok = IWL7260_UCODE_API_OK, \
81 .ucode_api_min = IWL7260_UCODE_API_MIN, \
82 .device_family = IWL_DEVICE_FAMILY_7000, \
83 .max_inst_size = IWL60_RTC_INST_SIZE, \
84 .max_data_size = IWL60_RTC_DATA_SIZE, \
85 .base_params = &iwl7000_base_params, \
86 /* TODO: .bt_params? */ \
87 .need_temp_offset_calib = true, \
88 .led_mode = IWL_LED_RF_STATE, \
89 .adv_pm = true \
90
91
92const struct iwl_cfg iwl7260_2ac_cfg = {
93 .name = "Intel(R) Dual Band Wireless AC7260",
94 .fw_name_pre = IWL7260_FW_PRE,
95 IWL_DEVICE_7000,
96 .ht_params = &iwl7000_ht_params,
97 .nvm_ver = IWL7260_NVM_VERSION,
98 .nvm_calib_ver = IWL7260_TX_POWER_VERSION,
99};
100
101const struct iwl_cfg iwl3160_ac_cfg = {
102 .name = "Intel(R) Dual Band Wireless AC3160",
103 .fw_name_pre = IWL3160_FW_PRE,
104 IWL_DEVICE_7000,
105 .ht_params = &iwl7000_ht_params,
106 .nvm_ver = IWL3160_NVM_VERSION,
107 .nvm_calib_ver = IWL3160_TX_POWER_VERSION,
108};
109
110MODULE_FIRMWARE(IWL7260_MODULE_FIRMWARE(IWL7260_UCODE_API_OK));
111MODULE_FIRMWARE(IWL3160_MODULE_FIRMWARE(IWL3160_UCODE_API_OK));
diff --git a/drivers/net/wireless/iwlwifi/pcie/cfg.h b/drivers/net/wireless/iwlwifi/pcie/cfg.h
deleted file mode 100644
index c6f8e83c3551..000000000000
--- a/drivers/net/wireless/iwlwifi/pcie/cfg.h
+++ /dev/null
@@ -1,115 +0,0 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63#ifndef __iwl_pci_h__
64#define __iwl_pci_h__
65
66
67/*
68 * This file declares the config structures for all devices.
69 */
70
71extern const struct iwl_cfg iwl5300_agn_cfg;
72extern const struct iwl_cfg iwl5100_agn_cfg;
73extern const struct iwl_cfg iwl5350_agn_cfg;
74extern const struct iwl_cfg iwl5100_bgn_cfg;
75extern const struct iwl_cfg iwl5100_abg_cfg;
76extern const struct iwl_cfg iwl5150_agn_cfg;
77extern const struct iwl_cfg iwl5150_abg_cfg;
78extern const struct iwl_cfg iwl6005_2agn_cfg;
79extern const struct iwl_cfg iwl6005_2abg_cfg;
80extern const struct iwl_cfg iwl6005_2bg_cfg;
81extern const struct iwl_cfg iwl6005_2agn_sff_cfg;
82extern const struct iwl_cfg iwl6005_2agn_d_cfg;
83extern const struct iwl_cfg iwl6005_2agn_mow1_cfg;
84extern const struct iwl_cfg iwl6005_2agn_mow2_cfg;
85extern const struct iwl_cfg iwl1030_bgn_cfg;
86extern const struct iwl_cfg iwl1030_bg_cfg;
87extern const struct iwl_cfg iwl6030_2agn_cfg;
88extern const struct iwl_cfg iwl6030_2abg_cfg;
89extern const struct iwl_cfg iwl6030_2bgn_cfg;
90extern const struct iwl_cfg iwl6030_2bg_cfg;
91extern const struct iwl_cfg iwl6000i_2agn_cfg;
92extern const struct iwl_cfg iwl6000i_2abg_cfg;
93extern const struct iwl_cfg iwl6000i_2bg_cfg;
94extern const struct iwl_cfg iwl6000_3agn_cfg;
95extern const struct iwl_cfg iwl6050_2agn_cfg;
96extern const struct iwl_cfg iwl6050_2abg_cfg;
97extern const struct iwl_cfg iwl6150_bgn_cfg;
98extern const struct iwl_cfg iwl6150_bg_cfg;
99extern const struct iwl_cfg iwl1000_bgn_cfg;
100extern const struct iwl_cfg iwl1000_bg_cfg;
101extern const struct iwl_cfg iwl100_bgn_cfg;
102extern const struct iwl_cfg iwl100_bg_cfg;
103extern const struct iwl_cfg iwl130_bgn_cfg;
104extern const struct iwl_cfg iwl130_bg_cfg;
105extern const struct iwl_cfg iwl2000_2bgn_cfg;
106extern const struct iwl_cfg iwl2000_2bgn_d_cfg;
107extern const struct iwl_cfg iwl2030_2bgn_cfg;
108extern const struct iwl_cfg iwl6035_2agn_cfg;
109extern const struct iwl_cfg iwl105_bgn_cfg;
110extern const struct iwl_cfg iwl105_bgn_d_cfg;
111extern const struct iwl_cfg iwl135_bgn_cfg;
112extern const struct iwl_cfg iwl7260_2ac_cfg;
113extern const struct iwl_cfg iwl3160_ac_cfg;
114
115#endif /* __iwl_pci_h__ */
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c
index 7bc0fb9128dd..46ca91f77c9c 100644
--- a/drivers/net/wireless/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/iwlwifi/pcie/drv.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -69,8 +69,6 @@
69 69
70#include "iwl-trans.h" 70#include "iwl-trans.h"
71#include "iwl-drv.h" 71#include "iwl-drv.h"
72
73#include "cfg.h"
74#include "internal.h" 72#include "internal.h"
75 73
76#define IWL_PCI_DEVICE(dev, subdev, cfg) \ 74#define IWL_PCI_DEVICE(dev, subdev, cfg) \
diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h
index aa2a39a637dd..148843e7f34f 100644
--- a/drivers/net/wireless/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/iwlwifi/pcie/internal.h
@@ -137,10 +137,6 @@ static inline int iwl_queue_dec_wrap(int index, int n_bd)
137struct iwl_cmd_meta { 137struct iwl_cmd_meta {
138 /* only for SYNC commands, iff the reply skb is wanted */ 138 /* only for SYNC commands, iff the reply skb is wanted */
139 struct iwl_host_cmd *source; 139 struct iwl_host_cmd *source;
140
141 DEFINE_DMA_UNMAP_ADDR(mapping);
142 DEFINE_DMA_UNMAP_LEN(len);
143
144 u32 flags; 140 u32 flags;
145}; 141};
146 142
@@ -182,19 +178,39 @@ struct iwl_queue {
182#define TFD_TX_CMD_SLOTS 256 178#define TFD_TX_CMD_SLOTS 256
183#define TFD_CMD_SLOTS 32 179#define TFD_CMD_SLOTS 32
184 180
181/*
182 * The FH will write back to the first TB only, so we need
183 * to copy some data into the buffer regardless of whether
184 * it should be mapped or not. This indicates how big the
185 * first TB must be to include the scratch buffer. Since
186 * the scratch is 4 bytes at offset 12, it's 16 now. If we
187 * make it bigger then allocations will be bigger and copy
188 * slower, so that's probably not useful.
189 */
190#define IWL_HCMD_SCRATCHBUF_SIZE 16
191
185struct iwl_pcie_txq_entry { 192struct iwl_pcie_txq_entry {
186 struct iwl_device_cmd *cmd; 193 struct iwl_device_cmd *cmd;
187 struct iwl_device_cmd *copy_cmd;
188 struct sk_buff *skb; 194 struct sk_buff *skb;
189 /* buffer to free after command completes */ 195 /* buffer to free after command completes */
190 const void *free_buf; 196 const void *free_buf;
191 struct iwl_cmd_meta meta; 197 struct iwl_cmd_meta meta;
192}; 198};
193 199
200struct iwl_pcie_txq_scratch_buf {
201 struct iwl_cmd_header hdr;
202 u8 buf[8];
203 __le32 scratch;
204};
205
194/** 206/**
195 * struct iwl_txq - Tx Queue for DMA 207 * struct iwl_txq - Tx Queue for DMA
196 * @q: generic Rx/Tx queue descriptor 208 * @q: generic Rx/Tx queue descriptor
197 * @tfds: transmit frame descriptors (DMA memory) 209 * @tfds: transmit frame descriptors (DMA memory)
210 * @scratchbufs: start of command headers, including scratch buffers, for
211 * the writeback -- this is DMA memory and an array holding one buffer
212 * for each command on the queue
213 * @scratchbufs_dma: DMA address for the scratchbufs start
198 * @entries: transmit entries (driver state) 214 * @entries: transmit entries (driver state)
199 * @lock: queue lock 215 * @lock: queue lock
200 * @stuck_timer: timer that fires if queue gets stuck 216 * @stuck_timer: timer that fires if queue gets stuck
@@ -208,6 +224,8 @@ struct iwl_pcie_txq_entry {
208struct iwl_txq { 224struct iwl_txq {
209 struct iwl_queue q; 225 struct iwl_queue q;
210 struct iwl_tfd *tfds; 226 struct iwl_tfd *tfds;
227 struct iwl_pcie_txq_scratch_buf *scratchbufs;
228 dma_addr_t scratchbufs_dma;
211 struct iwl_pcie_txq_entry *entries; 229 struct iwl_pcie_txq_entry *entries;
212 spinlock_t lock; 230 spinlock_t lock;
213 struct timer_list stuck_timer; 231 struct timer_list stuck_timer;
@@ -216,6 +234,13 @@ struct iwl_txq {
216 u8 active; 234 u8 active;
217}; 235};
218 236
237static inline dma_addr_t
238iwl_pcie_get_scratchbuf_dma(struct iwl_txq *txq, int idx)
239{
240 return txq->scratchbufs_dma +
241 sizeof(struct iwl_pcie_txq_scratch_buf) * idx;
242}
243
219/** 244/**
220 * struct iwl_trans_pcie - PCIe transport specific data 245 * struct iwl_trans_pcie - PCIe transport specific data
221 * @rxq: all the RX queue data 246 * @rxq: all the RX queue data
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c
index b0ae06d2456f..567e67ad1f61 100644
--- a/drivers/net/wireless/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/rx.c
@@ -637,22 +637,14 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans,
637 index = SEQ_TO_INDEX(sequence); 637 index = SEQ_TO_INDEX(sequence);
638 cmd_index = get_cmd_index(&txq->q, index); 638 cmd_index = get_cmd_index(&txq->q, index);
639 639
640 if (reclaim) { 640 if (reclaim)
641 struct iwl_pcie_txq_entry *ent; 641 cmd = txq->entries[cmd_index].cmd;
642 ent = &txq->entries[cmd_index]; 642 else
643 cmd = ent->copy_cmd;
644 WARN_ON_ONCE(!cmd && ent->meta.flags & CMD_WANT_HCMD);
645 } else {
646 cmd = NULL; 643 cmd = NULL;
647 }
648 644
649 err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd); 645 err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd);
650 646
651 if (reclaim) { 647 if (reclaim) {
652 /* The original command isn't needed any more */
653 kfree(txq->entries[cmd_index].copy_cmd);
654 txq->entries[cmd_index].copy_cmd = NULL;
655 /* nor is the duplicated part of the command */
656 kfree(txq->entries[cmd_index].free_buf); 648 kfree(txq->entries[cmd_index].free_buf);
657 txq->entries[cmd_index].free_buf = NULL; 649 txq->entries[cmd_index].free_buf = NULL;
658 } 650 }
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index 17bedc50e753..6649e377e9cd 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -715,7 +715,8 @@ static u32 iwl_trans_pcie_read32(struct iwl_trans *trans, u32 ofs)
715 715
716static u32 iwl_trans_pcie_read_prph(struct iwl_trans *trans, u32 reg) 716static u32 iwl_trans_pcie_read_prph(struct iwl_trans *trans, u32 reg)
717{ 717{
718 iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_RADDR, reg | (3 << 24)); 718 iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_RADDR,
719 ((reg & 0x000FFFFF) | (3 << 24)));
719 return iwl_trans_pcie_read32(trans, HBUS_TARG_PRPH_RDAT); 720 return iwl_trans_pcie_read32(trans, HBUS_TARG_PRPH_RDAT);
720} 721}
721 722
@@ -723,7 +724,7 @@ static void iwl_trans_pcie_write_prph(struct iwl_trans *trans, u32 addr,
723 u32 val) 724 u32 val)
724{ 725{
725 iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_WADDR, 726 iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_WADDR,
726 ((addr & 0x0000FFFF) | (3 << 24))); 727 ((addr & 0x000FFFFF) | (3 << 24)));
727 iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_WDAT, val); 728 iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_WDAT, val);
728} 729}
729 730
@@ -1370,28 +1371,11 @@ static ssize_t iwl_dbgfs_fh_reg_read(struct file *file,
1370 return ret; 1371 return ret;
1371} 1372}
1372 1373
1373static ssize_t iwl_dbgfs_fw_restart_write(struct file *file,
1374 const char __user *user_buf,
1375 size_t count, loff_t *ppos)
1376{
1377 struct iwl_trans *trans = file->private_data;
1378
1379 if (!trans->op_mode)
1380 return -EAGAIN;
1381
1382 local_bh_disable();
1383 iwl_op_mode_nic_error(trans->op_mode);
1384 local_bh_enable();
1385
1386 return count;
1387}
1388
1389DEBUGFS_READ_WRITE_FILE_OPS(interrupt); 1374DEBUGFS_READ_WRITE_FILE_OPS(interrupt);
1390DEBUGFS_READ_FILE_OPS(fh_reg); 1375DEBUGFS_READ_FILE_OPS(fh_reg);
1391DEBUGFS_READ_FILE_OPS(rx_queue); 1376DEBUGFS_READ_FILE_OPS(rx_queue);
1392DEBUGFS_READ_FILE_OPS(tx_queue); 1377DEBUGFS_READ_FILE_OPS(tx_queue);
1393DEBUGFS_WRITE_FILE_OPS(csr); 1378DEBUGFS_WRITE_FILE_OPS(csr);
1394DEBUGFS_WRITE_FILE_OPS(fw_restart);
1395 1379
1396/* 1380/*
1397 * Create the debugfs files and directories 1381 * Create the debugfs files and directories
@@ -1405,7 +1389,6 @@ static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans,
1405 DEBUGFS_ADD_FILE(interrupt, dir, S_IWUSR | S_IRUSR); 1389 DEBUGFS_ADD_FILE(interrupt, dir, S_IWUSR | S_IRUSR);
1406 DEBUGFS_ADD_FILE(csr, dir, S_IWUSR); 1390 DEBUGFS_ADD_FILE(csr, dir, S_IWUSR);
1407 DEBUGFS_ADD_FILE(fh_reg, dir, S_IRUSR); 1391 DEBUGFS_ADD_FILE(fh_reg, dir, S_IRUSR);
1408 DEBUGFS_ADD_FILE(fw_restart, dir, S_IWUSR);
1409 return 0; 1392 return 0;
1410 1393
1411err: 1394err:
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index ad7441dfa6fb..84f4634634bc 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -191,12 +191,9 @@ static void iwl_pcie_txq_stuck_timer(unsigned long data)
191 } 191 }
192 192
193 for (i = q->read_ptr; i != q->write_ptr; 193 for (i = q->read_ptr; i != q->write_ptr;
194 i = iwl_queue_inc_wrap(i, q->n_bd)) { 194 i = iwl_queue_inc_wrap(i, q->n_bd))
195 struct iwl_tx_cmd *tx_cmd =
196 (struct iwl_tx_cmd *)txq->entries[i].cmd->payload;
197 IWL_ERR(trans, "scratch %d = 0x%08x\n", i, 195 IWL_ERR(trans, "scratch %d = 0x%08x\n", i,
198 get_unaligned_le32(&tx_cmd->scratch)); 196 le32_to_cpu(txq->scratchbufs[i].scratch));
199 }
200 197
201 iwl_op_mode_nic_error(trans->op_mode); 198 iwl_op_mode_nic_error(trans->op_mode);
202} 199}
@@ -367,8 +364,8 @@ static inline u8 iwl_pcie_tfd_get_num_tbs(struct iwl_tfd *tfd)
367} 364}
368 365
369static void iwl_pcie_tfd_unmap(struct iwl_trans *trans, 366static void iwl_pcie_tfd_unmap(struct iwl_trans *trans,
370 struct iwl_cmd_meta *meta, struct iwl_tfd *tfd, 367 struct iwl_cmd_meta *meta,
371 enum dma_data_direction dma_dir) 368 struct iwl_tfd *tfd)
372{ 369{
373 int i; 370 int i;
374 int num_tbs; 371 int num_tbs;
@@ -382,17 +379,12 @@ static void iwl_pcie_tfd_unmap(struct iwl_trans *trans,
382 return; 379 return;
383 } 380 }
384 381
385 /* Unmap tx_cmd */ 382 /* first TB is never freed - it's the scratchbuf data */
386 if (num_tbs)
387 dma_unmap_single(trans->dev,
388 dma_unmap_addr(meta, mapping),
389 dma_unmap_len(meta, len),
390 DMA_BIDIRECTIONAL);
391 383
392 /* Unmap chunks, if any. */
393 for (i = 1; i < num_tbs; i++) 384 for (i = 1; i < num_tbs; i++)
394 dma_unmap_single(trans->dev, iwl_pcie_tfd_tb_get_addr(tfd, i), 385 dma_unmap_single(trans->dev, iwl_pcie_tfd_tb_get_addr(tfd, i),
395 iwl_pcie_tfd_tb_get_len(tfd, i), dma_dir); 386 iwl_pcie_tfd_tb_get_len(tfd, i),
387 DMA_TO_DEVICE);
396 388
397 tfd->num_tbs = 0; 389 tfd->num_tbs = 0;
398} 390}
@@ -406,8 +398,7 @@ static void iwl_pcie_tfd_unmap(struct iwl_trans *trans,
406 * Does NOT advance any TFD circular buffer read/write indexes 398 * Does NOT advance any TFD circular buffer read/write indexes
407 * Does NOT free the TFD itself (which is within circular buffer) 399 * Does NOT free the TFD itself (which is within circular buffer)
408 */ 400 */
409static void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq, 401static void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq)
410 enum dma_data_direction dma_dir)
411{ 402{
412 struct iwl_tfd *tfd_tmp = txq->tfds; 403 struct iwl_tfd *tfd_tmp = txq->tfds;
413 404
@@ -418,8 +409,7 @@ static void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq,
418 lockdep_assert_held(&txq->lock); 409 lockdep_assert_held(&txq->lock);
419 410
420 /* We have only q->n_window txq->entries, but we use q->n_bd tfds */ 411 /* We have only q->n_window txq->entries, but we use q->n_bd tfds */
421 iwl_pcie_tfd_unmap(trans, &txq->entries[idx].meta, &tfd_tmp[rd_ptr], 412 iwl_pcie_tfd_unmap(trans, &txq->entries[idx].meta, &tfd_tmp[rd_ptr]);
422 dma_dir);
423 413
424 /* free SKB */ 414 /* free SKB */
425 if (txq->entries) { 415 if (txq->entries) {
@@ -479,6 +469,7 @@ static int iwl_pcie_txq_alloc(struct iwl_trans *trans,
479{ 469{
480 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 470 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
481 size_t tfd_sz = sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX; 471 size_t tfd_sz = sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX;
472 size_t scratchbuf_sz;
482 int i; 473 int i;
483 474
484 if (WARN_ON(txq->entries || txq->tfds)) 475 if (WARN_ON(txq->entries || txq->tfds))
@@ -514,9 +505,25 @@ static int iwl_pcie_txq_alloc(struct iwl_trans *trans,
514 IWL_ERR(trans, "dma_alloc_coherent(%zd) failed\n", tfd_sz); 505 IWL_ERR(trans, "dma_alloc_coherent(%zd) failed\n", tfd_sz);
515 goto error; 506 goto error;
516 } 507 }
508
509 BUILD_BUG_ON(IWL_HCMD_SCRATCHBUF_SIZE != sizeof(*txq->scratchbufs));
510 BUILD_BUG_ON(offsetof(struct iwl_pcie_txq_scratch_buf, scratch) !=
511 sizeof(struct iwl_cmd_header) +
512 offsetof(struct iwl_tx_cmd, scratch));
513
514 scratchbuf_sz = sizeof(*txq->scratchbufs) * slots_num;
515
516 txq->scratchbufs = dma_alloc_coherent(trans->dev, scratchbuf_sz,
517 &txq->scratchbufs_dma,
518 GFP_KERNEL);
519 if (!txq->scratchbufs)
520 goto err_free_tfds;
521
517 txq->q.id = txq_id; 522 txq->q.id = txq_id;
518 523
519 return 0; 524 return 0;
525err_free_tfds:
526 dma_free_coherent(trans->dev, tfd_sz, txq->tfds, txq->q.dma_addr);
520error: 527error:
521 if (txq->entries && txq_id == trans_pcie->cmd_queue) 528 if (txq->entries && txq_id == trans_pcie->cmd_queue)
522 for (i = 0; i < slots_num; i++) 529 for (i = 0; i < slots_num; i++)
@@ -565,22 +572,13 @@ static void iwl_pcie_txq_unmap(struct iwl_trans *trans, int txq_id)
565 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 572 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
566 struct iwl_txq *txq = &trans_pcie->txq[txq_id]; 573 struct iwl_txq *txq = &trans_pcie->txq[txq_id];
567 struct iwl_queue *q = &txq->q; 574 struct iwl_queue *q = &txq->q;
568 enum dma_data_direction dma_dir;
569 575
570 if (!q->n_bd) 576 if (!q->n_bd)
571 return; 577 return;
572 578
573 /* In the command queue, all the TBs are mapped as BIDI
574 * so unmap them as such.
575 */
576 if (txq_id == trans_pcie->cmd_queue)
577 dma_dir = DMA_BIDIRECTIONAL;
578 else
579 dma_dir = DMA_TO_DEVICE;
580
581 spin_lock_bh(&txq->lock); 579 spin_lock_bh(&txq->lock);
582 while (q->write_ptr != q->read_ptr) { 580 while (q->write_ptr != q->read_ptr) {
583 iwl_pcie_txq_free_tfd(trans, txq, dma_dir); 581 iwl_pcie_txq_free_tfd(trans, txq);
584 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); 582 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
585 } 583 }
586 spin_unlock_bh(&txq->lock); 584 spin_unlock_bh(&txq->lock);
@@ -610,7 +608,6 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id)
610 if (txq_id == trans_pcie->cmd_queue) 608 if (txq_id == trans_pcie->cmd_queue)
611 for (i = 0; i < txq->q.n_window; i++) { 609 for (i = 0; i < txq->q.n_window; i++) {
612 kfree(txq->entries[i].cmd); 610 kfree(txq->entries[i].cmd);
613 kfree(txq->entries[i].copy_cmd);
614 kfree(txq->entries[i].free_buf); 611 kfree(txq->entries[i].free_buf);
615 } 612 }
616 613
@@ -619,6 +616,10 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id)
619 dma_free_coherent(dev, sizeof(struct iwl_tfd) * 616 dma_free_coherent(dev, sizeof(struct iwl_tfd) *
620 txq->q.n_bd, txq->tfds, txq->q.dma_addr); 617 txq->q.n_bd, txq->tfds, txq->q.dma_addr);
621 txq->q.dma_addr = 0; 618 txq->q.dma_addr = 0;
619
620 dma_free_coherent(dev,
621 sizeof(*txq->scratchbufs) * txq->q.n_window,
622 txq->scratchbufs, txq->scratchbufs_dma);
622 } 623 }
623 624
624 kfree(txq->entries); 625 kfree(txq->entries);
@@ -962,7 +963,7 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
962 963
963 iwl_pcie_txq_inval_byte_cnt_tbl(trans, txq); 964 iwl_pcie_txq_inval_byte_cnt_tbl(trans, txq);
964 965
965 iwl_pcie_txq_free_tfd(trans, txq, DMA_TO_DEVICE); 966 iwl_pcie_txq_free_tfd(trans, txq);
966 } 967 }
967 968
968 iwl_pcie_txq_progress(trans_pcie, txq); 969 iwl_pcie_txq_progress(trans_pcie, txq);
@@ -1152,20 +1153,37 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
1152 void *dup_buf = NULL; 1153 void *dup_buf = NULL;
1153 dma_addr_t phys_addr; 1154 dma_addr_t phys_addr;
1154 int idx; 1155 int idx;
1155 u16 copy_size, cmd_size; 1156 u16 copy_size, cmd_size, scratch_size;
1156 bool had_nocopy = false; 1157 bool had_nocopy = false;
1157 int i; 1158 int i;
1158 u32 cmd_pos; 1159 u32 cmd_pos;
1160 const u8 *cmddata[IWL_MAX_CMD_TBS_PER_TFD];
1161 u16 cmdlen[IWL_MAX_CMD_TBS_PER_TFD];
1159 1162
1160 copy_size = sizeof(out_cmd->hdr); 1163 copy_size = sizeof(out_cmd->hdr);
1161 cmd_size = sizeof(out_cmd->hdr); 1164 cmd_size = sizeof(out_cmd->hdr);
1162 1165
1163 /* need one for the header if the first is NOCOPY */ 1166 /* need one for the header if the first is NOCOPY */
1164 BUILD_BUG_ON(IWL_MAX_CMD_TFDS > IWL_NUM_OF_TBS - 1); 1167 BUILD_BUG_ON(IWL_MAX_CMD_TBS_PER_TFD > IWL_NUM_OF_TBS - 1);
1168
1169 for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) {
1170 cmddata[i] = cmd->data[i];
1171 cmdlen[i] = cmd->len[i];
1165 1172
1166 for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
1167 if (!cmd->len[i]) 1173 if (!cmd->len[i])
1168 continue; 1174 continue;
1175
1176 /* need at least IWL_HCMD_SCRATCHBUF_SIZE copied */
1177 if (copy_size < IWL_HCMD_SCRATCHBUF_SIZE) {
1178 int copy = IWL_HCMD_SCRATCHBUF_SIZE - copy_size;
1179
1180 if (copy > cmdlen[i])
1181 copy = cmdlen[i];
1182 cmdlen[i] -= copy;
1183 cmddata[i] += copy;
1184 copy_size += copy;
1185 }
1186
1169 if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) { 1187 if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) {
1170 had_nocopy = true; 1188 had_nocopy = true;
1171 if (WARN_ON(cmd->dataflags[i] & IWL_HCMD_DFL_DUP)) { 1189 if (WARN_ON(cmd->dataflags[i] & IWL_HCMD_DFL_DUP)) {
@@ -1185,7 +1203,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
1185 goto free_dup_buf; 1203 goto free_dup_buf;
1186 } 1204 }
1187 1205
1188 dup_buf = kmemdup(cmd->data[i], cmd->len[i], 1206 dup_buf = kmemdup(cmddata[i], cmdlen[i],
1189 GFP_ATOMIC); 1207 GFP_ATOMIC);
1190 if (!dup_buf) 1208 if (!dup_buf)
1191 return -ENOMEM; 1209 return -ENOMEM;
@@ -1195,7 +1213,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
1195 idx = -EINVAL; 1213 idx = -EINVAL;
1196 goto free_dup_buf; 1214 goto free_dup_buf;
1197 } 1215 }
1198 copy_size += cmd->len[i]; 1216 copy_size += cmdlen[i];
1199 } 1217 }
1200 cmd_size += cmd->len[i]; 1218 cmd_size += cmd->len[i];
1201 } 1219 }
@@ -1242,30 +1260,30 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
1242 1260
1243 /* and copy the data that needs to be copied */ 1261 /* and copy the data that needs to be copied */
1244 cmd_pos = offsetof(struct iwl_device_cmd, payload); 1262 cmd_pos = offsetof(struct iwl_device_cmd, payload);
1245 for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { 1263 copy_size = sizeof(out_cmd->hdr);
1246 if (!cmd->len[i]) 1264 for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) {
1265 int copy = 0;
1266
1267 if (!cmd->len)
1247 continue; 1268 continue;
1248 if (cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY |
1249 IWL_HCMD_DFL_DUP))
1250 break;
1251 memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], cmd->len[i]);
1252 cmd_pos += cmd->len[i];
1253 }
1254 1269
1255 WARN_ON_ONCE(txq->entries[idx].copy_cmd); 1270 /* need at least IWL_HCMD_SCRATCHBUF_SIZE copied */
1271 if (copy_size < IWL_HCMD_SCRATCHBUF_SIZE) {
1272 copy = IWL_HCMD_SCRATCHBUF_SIZE - copy_size;
1256 1273
1257 /* 1274 if (copy > cmd->len[i])
1258 * since out_cmd will be the source address of the FH, it will write 1275 copy = cmd->len[i];
1259 * the retry count there. So when the user needs to receivce the HCMD 1276 }
1260 * that corresponds to the response in the response handler, it needs 1277
1261 * to set CMD_WANT_HCMD. 1278 /* copy everything if not nocopy/dup */
1262 */ 1279 if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY |
1263 if (cmd->flags & CMD_WANT_HCMD) { 1280 IWL_HCMD_DFL_DUP)))
1264 txq->entries[idx].copy_cmd = 1281 copy = cmd->len[i];
1265 kmemdup(out_cmd, cmd_pos, GFP_ATOMIC); 1282
1266 if (unlikely(!txq->entries[idx].copy_cmd)) { 1283 if (copy) {
1267 idx = -ENOMEM; 1284 memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], copy);
1268 goto out; 1285 cmd_pos += copy;
1286 copy_size += copy;
1269 } 1287 }
1270 } 1288 }
1271 1289
@@ -1275,22 +1293,35 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
1275 out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence), 1293 out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence),
1276 cmd_size, q->write_ptr, idx, trans_pcie->cmd_queue); 1294 cmd_size, q->write_ptr, idx, trans_pcie->cmd_queue);
1277 1295
1278 phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, copy_size, 1296 /* start the TFD with the scratchbuf */
1279 DMA_BIDIRECTIONAL); 1297 scratch_size = min_t(int, copy_size, IWL_HCMD_SCRATCHBUF_SIZE);
1280 if (unlikely(dma_mapping_error(trans->dev, phys_addr))) { 1298 memcpy(&txq->scratchbufs[q->write_ptr], &out_cmd->hdr, scratch_size);
1281 idx = -ENOMEM; 1299 iwl_pcie_txq_build_tfd(trans, txq,
1282 goto out; 1300 iwl_pcie_get_scratchbuf_dma(txq, q->write_ptr),
1283 } 1301 scratch_size, 1);
1284 1302
1285 dma_unmap_addr_set(out_meta, mapping, phys_addr); 1303 /* map first command fragment, if any remains */
1286 dma_unmap_len_set(out_meta, len, copy_size); 1304 if (copy_size > scratch_size) {
1305 phys_addr = dma_map_single(trans->dev,
1306 ((u8 *)&out_cmd->hdr) + scratch_size,
1307 copy_size - scratch_size,
1308 DMA_TO_DEVICE);
1309 if (dma_mapping_error(trans->dev, phys_addr)) {
1310 iwl_pcie_tfd_unmap(trans, out_meta,
1311 &txq->tfds[q->write_ptr]);
1312 idx = -ENOMEM;
1313 goto out;
1314 }
1287 1315
1288 iwl_pcie_txq_build_tfd(trans, txq, phys_addr, copy_size, 1); 1316 iwl_pcie_txq_build_tfd(trans, txq, phys_addr,
1317 copy_size - scratch_size, 0);
1318 }
1289 1319
1290 for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { 1320 /* map the remaining (adjusted) nocopy/dup fragments */
1291 const void *data = cmd->data[i]; 1321 for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) {
1322 const void *data = cmddata[i];
1292 1323
1293 if (!cmd->len[i]) 1324 if (!cmdlen[i])
1294 continue; 1325 continue;
1295 if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY | 1326 if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY |
1296 IWL_HCMD_DFL_DUP))) 1327 IWL_HCMD_DFL_DUP)))
@@ -1298,16 +1329,15 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
1298 if (cmd->dataflags[i] & IWL_HCMD_DFL_DUP) 1329 if (cmd->dataflags[i] & IWL_HCMD_DFL_DUP)
1299 data = dup_buf; 1330 data = dup_buf;
1300 phys_addr = dma_map_single(trans->dev, (void *)data, 1331 phys_addr = dma_map_single(trans->dev, (void *)data,
1301 cmd->len[i], DMA_BIDIRECTIONAL); 1332 cmdlen[i], DMA_TO_DEVICE);
1302 if (dma_mapping_error(trans->dev, phys_addr)) { 1333 if (dma_mapping_error(trans->dev, phys_addr)) {
1303 iwl_pcie_tfd_unmap(trans, out_meta, 1334 iwl_pcie_tfd_unmap(trans, out_meta,
1304 &txq->tfds[q->write_ptr], 1335 &txq->tfds[q->write_ptr]);
1305 DMA_BIDIRECTIONAL);
1306 idx = -ENOMEM; 1336 idx = -ENOMEM;
1307 goto out; 1337 goto out;
1308 } 1338 }
1309 1339
1310 iwl_pcie_txq_build_tfd(trans, txq, phys_addr, cmd->len[i], 0); 1340 iwl_pcie_txq_build_tfd(trans, txq, phys_addr, cmdlen[i], 0);
1311 } 1341 }
1312 1342
1313 out_meta->flags = cmd->flags; 1343 out_meta->flags = cmd->flags;
@@ -1317,8 +1347,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
1317 1347
1318 txq->need_update = 1; 1348 txq->need_update = 1;
1319 1349
1320 trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size, 1350 trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size, &out_cmd->hdr);
1321 &out_cmd->hdr, copy_size);
1322 1351
1323 /* start timer if queue currently empty */ 1352 /* start timer if queue currently empty */
1324 if (q->read_ptr == q->write_ptr && trans_pcie->wd_timeout) 1353 if (q->read_ptr == q->write_ptr && trans_pcie->wd_timeout)
@@ -1377,7 +1406,7 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans,
1377 cmd = txq->entries[cmd_index].cmd; 1406 cmd = txq->entries[cmd_index].cmd;
1378 meta = &txq->entries[cmd_index].meta; 1407 meta = &txq->entries[cmd_index].meta;
1379 1408
1380 iwl_pcie_tfd_unmap(trans, meta, &txq->tfds[index], DMA_BIDIRECTIONAL); 1409 iwl_pcie_tfd_unmap(trans, meta, &txq->tfds[index]);
1381 1410
1382 /* Input error checking is done when commands are added to queue. */ 1411 /* Input error checking is done when commands are added to queue. */
1383 if (meta->flags & CMD_WANT_SKB) { 1412 if (meta->flags & CMD_WANT_SKB) {
@@ -1556,10 +1585,9 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
1556 struct iwl_cmd_meta *out_meta; 1585 struct iwl_cmd_meta *out_meta;
1557 struct iwl_txq *txq; 1586 struct iwl_txq *txq;
1558 struct iwl_queue *q; 1587 struct iwl_queue *q;
1559 dma_addr_t phys_addr = 0; 1588 dma_addr_t tb0_phys, tb1_phys, scratch_phys;
1560 dma_addr_t txcmd_phys; 1589 void *tb1_addr;
1561 dma_addr_t scratch_phys; 1590 u16 len, tb1_len, tb2_len;
1562 u16 len, firstlen, secondlen;
1563 u8 wait_write_ptr = 0; 1591 u8 wait_write_ptr = 0;
1564 __le16 fc = hdr->frame_control; 1592 __le16 fc = hdr->frame_control;
1565 u8 hdr_len = ieee80211_hdrlen(fc); 1593 u8 hdr_len = ieee80211_hdrlen(fc);
@@ -1597,85 +1625,80 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
1597 cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) | 1625 cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) |
1598 INDEX_TO_SEQ(q->write_ptr))); 1626 INDEX_TO_SEQ(q->write_ptr)));
1599 1627
1628 tb0_phys = iwl_pcie_get_scratchbuf_dma(txq, q->write_ptr);
1629 scratch_phys = tb0_phys + sizeof(struct iwl_cmd_header) +
1630 offsetof(struct iwl_tx_cmd, scratch);
1631
1632 tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys);
1633 tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys);
1634
1600 /* Set up first empty entry in queue's array of Tx/cmd buffers */ 1635 /* Set up first empty entry in queue's array of Tx/cmd buffers */
1601 out_meta = &txq->entries[q->write_ptr].meta; 1636 out_meta = &txq->entries[q->write_ptr].meta;
1602 1637
1603 /* 1638 /*
1604 * Use the first empty entry in this queue's command buffer array 1639 * The second TB (tb1) points to the remainder of the TX command
1605 * to contain the Tx command and MAC header concatenated together 1640 * and the 802.11 header - dword aligned size
1606 * (payload data will be in another buffer). 1641 * (This calculation modifies the TX command, so do it before the
1607 * Size of this varies, due to varying MAC header length. 1642 * setup of the first TB)
1608 * If end is not dword aligned, we'll have 2 extra bytes at the end
1609 * of the MAC header (device reads on dword boundaries).
1610 * We'll tell device about this padding later.
1611 */ 1643 */
1612 len = sizeof(struct iwl_tx_cmd) + 1644 len = sizeof(struct iwl_tx_cmd) + sizeof(struct iwl_cmd_header) +
1613 sizeof(struct iwl_cmd_header) + hdr_len; 1645 hdr_len - IWL_HCMD_SCRATCHBUF_SIZE;
1614 firstlen = (len + 3) & ~3; 1646 tb1_len = (len + 3) & ~3;
1615 1647
1616 /* Tell NIC about any 2-byte padding after MAC header */ 1648 /* Tell NIC about any 2-byte padding after MAC header */
1617 if (firstlen != len) 1649 if (tb1_len != len)
1618 tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK; 1650 tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK;
1619 1651
1620 /* Physical address of this Tx command's header (not MAC header!), 1652 /* The first TB points to the scratchbuf data - min_copy bytes */
1621 * within command buffer array. */ 1653 memcpy(&txq->scratchbufs[q->write_ptr], &dev_cmd->hdr,
1622 txcmd_phys = dma_map_single(trans->dev, 1654 IWL_HCMD_SCRATCHBUF_SIZE);
1623 &dev_cmd->hdr, firstlen, 1655 iwl_pcie_txq_build_tfd(trans, txq, tb0_phys,
1624 DMA_BIDIRECTIONAL); 1656 IWL_HCMD_SCRATCHBUF_SIZE, 1);
1625 if (unlikely(dma_mapping_error(trans->dev, txcmd_phys)))
1626 goto out_err;
1627 dma_unmap_addr_set(out_meta, mapping, txcmd_phys);
1628 dma_unmap_len_set(out_meta, len, firstlen);
1629 1657
1630 if (!ieee80211_has_morefrags(fc)) { 1658 /* there must be data left over for TB1 or this code must be changed */
1631 txq->need_update = 1; 1659 BUILD_BUG_ON(sizeof(struct iwl_tx_cmd) < IWL_HCMD_SCRATCHBUF_SIZE);
1632 } else { 1660
1633 wait_write_ptr = 1; 1661 /* map the data for TB1 */
1634 txq->need_update = 0; 1662 tb1_addr = ((u8 *)&dev_cmd->hdr) + IWL_HCMD_SCRATCHBUF_SIZE;
1635 } 1663 tb1_phys = dma_map_single(trans->dev, tb1_addr, tb1_len, DMA_TO_DEVICE);
1664 if (unlikely(dma_mapping_error(trans->dev, tb1_phys)))
1665 goto out_err;
1666 iwl_pcie_txq_build_tfd(trans, txq, tb1_phys, tb1_len, 0);
1636 1667
1637 /* Set up TFD's 2nd entry to point directly to remainder of skb, 1668 /*
1638 * if any (802.11 null frames have no payload). */ 1669 * Set up TFD's third entry to point directly to remainder
1639 secondlen = skb->len - hdr_len; 1670 * of skb, if any (802.11 null frames have no payload).
1640 if (secondlen > 0) { 1671 */
1641 phys_addr = dma_map_single(trans->dev, skb->data + hdr_len, 1672 tb2_len = skb->len - hdr_len;
1642 secondlen, DMA_TO_DEVICE); 1673 if (tb2_len > 0) {
1643 if (unlikely(dma_mapping_error(trans->dev, phys_addr))) { 1674 dma_addr_t tb2_phys = dma_map_single(trans->dev,
1644 dma_unmap_single(trans->dev, 1675 skb->data + hdr_len,
1645 dma_unmap_addr(out_meta, mapping), 1676 tb2_len, DMA_TO_DEVICE);
1646 dma_unmap_len(out_meta, len), 1677 if (unlikely(dma_mapping_error(trans->dev, tb2_phys))) {
1647 DMA_BIDIRECTIONAL); 1678 iwl_pcie_tfd_unmap(trans, out_meta,
1679 &txq->tfds[q->write_ptr]);
1648 goto out_err; 1680 goto out_err;
1649 } 1681 }
1682 iwl_pcie_txq_build_tfd(trans, txq, tb2_phys, tb2_len, 0);
1650 } 1683 }
1651 1684
1652 /* Attach buffers to TFD */
1653 iwl_pcie_txq_build_tfd(trans, txq, txcmd_phys, firstlen, 1);
1654 if (secondlen > 0)
1655 iwl_pcie_txq_build_tfd(trans, txq, phys_addr, secondlen, 0);
1656
1657 scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) +
1658 offsetof(struct iwl_tx_cmd, scratch);
1659
1660 /* take back ownership of DMA buffer to enable update */
1661 dma_sync_single_for_cpu(trans->dev, txcmd_phys, firstlen,
1662 DMA_BIDIRECTIONAL);
1663 tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys);
1664 tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys);
1665
1666 /* Set up entry for this TFD in Tx byte-count array */ 1685 /* Set up entry for this TFD in Tx byte-count array */
1667 iwl_pcie_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len)); 1686 iwl_pcie_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len));
1668 1687
1669 dma_sync_single_for_device(trans->dev, txcmd_phys, firstlen,
1670 DMA_BIDIRECTIONAL);
1671
1672 trace_iwlwifi_dev_tx(trans->dev, skb, 1688 trace_iwlwifi_dev_tx(trans->dev, skb,
1673 &txq->tfds[txq->q.write_ptr], 1689 &txq->tfds[txq->q.write_ptr],
1674 sizeof(struct iwl_tfd), 1690 sizeof(struct iwl_tfd),
1675 &dev_cmd->hdr, firstlen, 1691 &dev_cmd->hdr, IWL_HCMD_SCRATCHBUF_SIZE + tb1_len,
1676 skb->data + hdr_len, secondlen); 1692 skb->data + hdr_len, tb2_len);
1677 trace_iwlwifi_dev_tx_data(trans->dev, skb, 1693 trace_iwlwifi_dev_tx_data(trans->dev, skb,
1678 skb->data + hdr_len, secondlen); 1694 skb->data + hdr_len, tb2_len);
1695
1696 if (!ieee80211_has_morefrags(fc)) {
1697 txq->need_update = 1;
1698 } else {
1699 wait_write_ptr = 1;
1700 txq->need_update = 0;
1701 }
1679 1702
1680 /* start timer if queue currently empty */ 1703 /* start timer if queue currently empty */
1681 if (txq->need_update && q->read_ptr == q->write_ptr && 1704 if (txq->need_update && q->read_ptr == q->write_ptr &&