aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-2000.c21
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c16
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c88
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rxon.c19
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c90
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-ucode.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c54
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c22
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h18
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h22
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-hcmd.c13
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-pci.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h19
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c47
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-testmode.h236
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.c423
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h64
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c139
23 files changed, 726 insertions, 593 deletions
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index 9a56ce546715..19150398a248 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -14,6 +14,7 @@ iwlagn-objs += iwl-6000.o
14iwlagn-objs += iwl-1000.o 14iwlagn-objs += iwl-1000.o
15iwlagn-objs += iwl-2000.o 15iwlagn-objs += iwl-2000.o
16iwlagn-objs += iwl-pci.o 16iwlagn-objs += iwl-pci.o
17iwlagn-objs += iwl-trans.o
17 18
18iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o 19iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
19iwlagn-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o 20iwlagn-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index e57fad9f1f09..cf1449df4f0b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -138,7 +138,6 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
138 138
139 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | 139 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
140 BIT(IEEE80211_BAND_5GHZ); 140 BIT(IEEE80211_BAND_5GHZ);
141 priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
142 141
143 priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant); 142 priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant);
144 if (priv->cfg->rx_with_siso_diversity) 143 if (priv->cfg->rx_with_siso_diversity)
@@ -197,7 +196,6 @@ static struct iwl_lib_ops iwl1000_lib = {
197 196
198static const struct iwl_ops iwl1000_ops = { 197static const struct iwl_ops iwl1000_ops = {
199 .lib = &iwl1000_lib, 198 .lib = &iwl1000_lib,
200 .hcmd = &iwlagn_hcmd,
201 .utils = &iwlagn_hcmd_utils, 199 .utils = &iwlagn_hcmd_utils,
202}; 200};
203 201
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c
index 64ed1f247df0..a401113c065a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-2000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-2000.c
@@ -50,11 +50,13 @@
50#define IWL2030_UCODE_API_MAX 5 50#define IWL2030_UCODE_API_MAX 5
51#define IWL2000_UCODE_API_MAX 5 51#define IWL2000_UCODE_API_MAX 5
52#define IWL105_UCODE_API_MAX 5 52#define IWL105_UCODE_API_MAX 5
53#define IWL135_UCODE_API_MAX 5
53 54
54/* Lowest firmware API version supported */ 55/* Lowest firmware API version supported */
55#define IWL2030_UCODE_API_MIN 5 56#define IWL2030_UCODE_API_MIN 5
56#define IWL2000_UCODE_API_MIN 5 57#define IWL2000_UCODE_API_MIN 5
57#define IWL105_UCODE_API_MIN 5 58#define IWL105_UCODE_API_MIN 5
59#define IWL135_UCODE_API_MIN 5
58 60
59#define IWL2030_FW_PRE "iwlwifi-2030-" 61#define IWL2030_FW_PRE "iwlwifi-2030-"
60#define IWL2030_MODULE_FIRMWARE(api) IWL2030_FW_PRE __stringify(api) ".ucode" 62#define IWL2030_MODULE_FIRMWARE(api) IWL2030_FW_PRE __stringify(api) ".ucode"
@@ -65,6 +67,9 @@
65#define IWL105_FW_PRE "iwlwifi-105-" 67#define IWL105_FW_PRE "iwlwifi-105-"
66#define IWL105_MODULE_FIRMWARE(api) IWL105_FW_PRE __stringify(api) ".ucode" 68#define IWL105_MODULE_FIRMWARE(api) IWL105_FW_PRE __stringify(api) ".ucode"
67 69
70#define IWL135_FW_PRE "iwlwifi-135-"
71#define IWL135_MODULE_FIRMWARE(api) IWL135_FW_PRE #api ".ucode"
72
68static void iwl2000_set_ct_threshold(struct iwl_priv *priv) 73static void iwl2000_set_ct_threshold(struct iwl_priv *priv)
69{ 74{
70 /* want Celsius */ 75 /* want Celsius */
@@ -131,7 +136,6 @@ static int iwl2000_hw_set_hw_params(struct iwl_priv *priv)
131 136
132 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | 137 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
133 BIT(IEEE80211_BAND_5GHZ); 138 BIT(IEEE80211_BAND_5GHZ);
134 priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
135 139
136 priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant); 140 priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant);
137 if (priv->cfg->rx_with_siso_diversity) 141 if (priv->cfg->rx_with_siso_diversity)
@@ -193,25 +197,21 @@ static struct iwl_lib_ops iwl2000_lib = {
193 197
194static const struct iwl_ops iwl2000_ops = { 198static const struct iwl_ops iwl2000_ops = {
195 .lib = &iwl2000_lib, 199 .lib = &iwl2000_lib,
196 .hcmd = &iwlagn_hcmd,
197 .utils = &iwlagn_hcmd_utils, 200 .utils = &iwlagn_hcmd_utils,
198}; 201};
199 202
200static const struct iwl_ops iwl2030_ops = { 203static const struct iwl_ops iwl2030_ops = {
201 .lib = &iwl2000_lib, 204 .lib = &iwl2000_lib,
202 .hcmd = &iwlagn_bt_hcmd,
203 .utils = &iwlagn_hcmd_utils, 205 .utils = &iwlagn_hcmd_utils,
204}; 206};
205 207
206static const struct iwl_ops iwl105_ops = { 208static const struct iwl_ops iwl105_ops = {
207 .lib = &iwl2000_lib, 209 .lib = &iwl2000_lib,
208 .hcmd = &iwlagn_hcmd,
209 .utils = &iwlagn_hcmd_utils, 210 .utils = &iwlagn_hcmd_utils,
210}; 211};
211 212
212static const struct iwl_ops iwl135_ops = { 213static const struct iwl_ops iwl135_ops = {
213 .lib = &iwl2000_lib, 214 .lib = &iwl2000_lib,
214 .hcmd = &iwlagn_bt_hcmd,
215 .utils = &iwlagn_hcmd_utils, 215 .utils = &iwlagn_hcmd_utils,
216}; 216};
217 217
@@ -344,9 +344,9 @@ struct iwl_cfg iwl105_bgn_cfg = {
344}; 344};
345 345
346#define IWL_DEVICE_135 \ 346#define IWL_DEVICE_135 \
347 .fw_name_pre = IWL105_FW_PRE, \ 347 .fw_name_pre = IWL135_FW_PRE, \
348 .ucode_api_max = IWL105_UCODE_API_MAX, \ 348 .ucode_api_max = IWL135_UCODE_API_MAX, \
349 .ucode_api_min = IWL105_UCODE_API_MIN, \ 349 .ucode_api_min = IWL135_UCODE_API_MIN, \
350 .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ 350 .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
351 .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ 351 .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
352 .ops = &iwl135_ops, \ 352 .ops = &iwl135_ops, \
@@ -359,12 +359,12 @@ struct iwl_cfg iwl105_bgn_cfg = {
359 .rx_with_siso_diversity = true \ 359 .rx_with_siso_diversity = true \
360 360
361struct iwl_cfg iwl135_bg_cfg = { 361struct iwl_cfg iwl135_bg_cfg = {
362 .name = "105 Series 1x1 BG/BT", 362 .name = "135 Series 1x1 BG/BT",
363 IWL_DEVICE_135, 363 IWL_DEVICE_135,
364}; 364};
365 365
366struct iwl_cfg iwl135_bgn_cfg = { 366struct iwl_cfg iwl135_bgn_cfg = {
367 .name = "105 Series 1x1 BGN/BT", 367 .name = "135 Series 1x1 BGN/BT",
368 IWL_DEVICE_135, 368 IWL_DEVICE_135,
369 .ht_params = &iwl2000_ht_params, 369 .ht_params = &iwl2000_ht_params,
370}; 370};
@@ -372,3 +372,4 @@ struct iwl_cfg iwl135_bgn_cfg = {
372MODULE_FIRMWARE(IWL2000_MODULE_FIRMWARE(IWL2000_UCODE_API_MAX)); 372MODULE_FIRMWARE(IWL2000_MODULE_FIRMWARE(IWL2000_UCODE_API_MAX));
373MODULE_FIRMWARE(IWL2030_MODULE_FIRMWARE(IWL2030_UCODE_API_MAX)); 373MODULE_FIRMWARE(IWL2030_MODULE_FIRMWARE(IWL2030_UCODE_API_MAX));
374MODULE_FIRMWARE(IWL105_MODULE_FIRMWARE(IWL105_UCODE_API_MAX)); 374MODULE_FIRMWARE(IWL105_MODULE_FIRMWARE(IWL105_UCODE_API_MAX));
375MODULE_FIRMWARE(IWL135_MODULE_FIRMWARE(IWL135_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 269dfdb9fe1a..c55cec853f50 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -169,7 +169,6 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
169 169
170 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | 170 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
171 BIT(IEEE80211_BAND_5GHZ); 171 BIT(IEEE80211_BAND_5GHZ);
172 priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
173 172
174 priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant); 173 priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant);
175 priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant); 174 priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant);
@@ -214,7 +213,6 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv)
214 213
215 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | 214 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
216 BIT(IEEE80211_BAND_5GHZ); 215 BIT(IEEE80211_BAND_5GHZ);
217 priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
218 216
219 priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant); 217 priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant);
220 priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant); 218 priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant);
@@ -379,13 +377,11 @@ static struct iwl_lib_ops iwl5150_lib = {
379 377
380static const struct iwl_ops iwl5000_ops = { 378static const struct iwl_ops iwl5000_ops = {
381 .lib = &iwl5000_lib, 379 .lib = &iwl5000_lib,
382 .hcmd = &iwlagn_hcmd,
383 .utils = &iwlagn_hcmd_utils, 380 .utils = &iwlagn_hcmd_utils,
384}; 381};
385 382
386static const struct iwl_ops iwl5150_ops = { 383static const struct iwl_ops iwl5150_ops = {
387 .lib = &iwl5150_lib, 384 .lib = &iwl5150_lib,
388 .hcmd = &iwlagn_hcmd,
389 .utils = &iwlagn_hcmd_utils, 385 .utils = &iwlagn_hcmd_utils,
390}; 386};
391 387
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index f1c1db76b9da..965d010794b4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -157,7 +157,6 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
157 157
158 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | 158 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
159 BIT(IEEE80211_BAND_5GHZ); 159 BIT(IEEE80211_BAND_5GHZ);
160 priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
161 160
162 priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant); 161 priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant);
163 if (priv->cfg->rx_with_siso_diversity) 162 if (priv->cfg->rx_with_siso_diversity)
@@ -328,27 +327,23 @@ static struct iwl_nic_ops iwl6150_nic_ops = {
328 327
329static const struct iwl_ops iwl6000_ops = { 328static const struct iwl_ops iwl6000_ops = {
330 .lib = &iwl6000_lib, 329 .lib = &iwl6000_lib,
331 .hcmd = &iwlagn_hcmd,
332 .utils = &iwlagn_hcmd_utils, 330 .utils = &iwlagn_hcmd_utils,
333}; 331};
334 332
335static const struct iwl_ops iwl6050_ops = { 333static const struct iwl_ops iwl6050_ops = {
336 .lib = &iwl6000_lib, 334 .lib = &iwl6000_lib,
337 .hcmd = &iwlagn_hcmd,
338 .utils = &iwlagn_hcmd_utils, 335 .utils = &iwlagn_hcmd_utils,
339 .nic = &iwl6050_nic_ops, 336 .nic = &iwl6050_nic_ops,
340}; 337};
341 338
342static const struct iwl_ops iwl6150_ops = { 339static const struct iwl_ops iwl6150_ops = {
343 .lib = &iwl6000_lib, 340 .lib = &iwl6000_lib,
344 .hcmd = &iwlagn_hcmd,
345 .utils = &iwlagn_hcmd_utils, 341 .utils = &iwlagn_hcmd_utils,
346 .nic = &iwl6150_nic_ops, 342 .nic = &iwl6150_nic_ops,
347}; 343};
348 344
349static const struct iwl_ops iwl6030_ops = { 345static const struct iwl_ops iwl6030_ops = {
350 .lib = &iwl6030_lib, 346 .lib = &iwl6030_lib,
351 .hcmd = &iwlagn_bt_hcmd,
352 .utils = &iwlagn_hcmd_utils, 347 .utils = &iwlagn_hcmd_utils,
353}; 348};
354 349
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
index ba7ed9157c92..ce7d4b56d9b2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
@@ -205,7 +205,7 @@ static int iwlagn_calc_rssi(struct iwl_priv *priv,
205 return max_rssi - agc - IWLAGN_RSSI_OFFSET; 205 return max_rssi - agc - IWLAGN_RSSI_OFFSET;
206} 206}
207 207
208static int iwlagn_set_pan_params(struct iwl_priv *priv) 208int iwlagn_set_pan_params(struct iwl_priv *priv)
209{ 209{
210 struct iwl_wipan_params_cmd cmd; 210 struct iwl_wipan_params_cmd cmd;
211 struct iwl_rxon_context *ctx_bss, *ctx_pan; 211 struct iwl_rxon_context *ctx_bss, *ctx_pan;
@@ -297,20 +297,6 @@ static int iwlagn_set_pan_params(struct iwl_priv *priv)
297 return ret; 297 return ret;
298} 298}
299 299
300struct iwl_hcmd_ops iwlagn_hcmd = {
301 .set_rxon_chain = iwlagn_set_rxon_chain,
302 .set_tx_ant = iwlagn_send_tx_ant_config,
303 .send_bt_config = iwl_send_bt_config,
304 .set_pan_params = iwlagn_set_pan_params,
305};
306
307struct iwl_hcmd_ops iwlagn_bt_hcmd = {
308 .set_rxon_chain = iwlagn_set_rxon_chain,
309 .set_tx_ant = iwlagn_send_tx_ant_config,
310 .send_bt_config = iwlagn_send_advance_bt_config,
311 .set_pan_params = iwlagn_set_pan_params,
312};
313
314struct iwl_hcmd_utils_ops iwlagn_hcmd_utils = { 300struct iwl_hcmd_utils_ops iwlagn_hcmd_utils = {
315 .build_addsta_hcmd = iwlagn_build_addsta_hcmd, 301 .build_addsta_hcmd = iwlagn_build_addsta_hcmd,
316 .gain_computation = iwlagn_gain_computation, 302 .gain_computation = iwlagn_gain_computation,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index efdab6506ae7..90d366e15d2f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -628,38 +628,6 @@ struct iwl_mod_params iwlagn_mod_params = {
628 /* the rest are 0 by default */ 628 /* the rest are 0 by default */
629}; 629};
630 630
631void iwlagn_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
632{
633 unsigned long flags;
634 int i;
635 spin_lock_irqsave(&rxq->lock, flags);
636 INIT_LIST_HEAD(&rxq->rx_free);
637 INIT_LIST_HEAD(&rxq->rx_used);
638 /* Fill the rx_used queue with _all_ of the Rx buffers */
639 for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) {
640 /* In the reset function, these buffers may have been allocated
641 * to an SKB, so we need to unmap and free potential storage */
642 if (rxq->pool[i].page != NULL) {
643 dma_unmap_page(priv->bus.dev, rxq->pool[i].page_dma,
644 PAGE_SIZE << priv->hw_params.rx_page_order,
645 DMA_FROM_DEVICE);
646 __iwl_free_pages(priv, rxq->pool[i].page);
647 rxq->pool[i].page = NULL;
648 }
649 list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
650 }
651
652 for (i = 0; i < RX_QUEUE_SIZE; i++)
653 rxq->queue[i] = NULL;
654
655 /* Set us so that we have processed and used all buffers, but have
656 * not restocked the Rx queue with fresh buffers */
657 rxq->read = rxq->write = 0;
658 rxq->write_actual = 0;
659 rxq->free_count = 0;
660 spin_unlock_irqrestore(&rxq->lock, flags);
661}
662
663int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) 631int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
664{ 632{
665 u32 rb_size; 633 u32 rb_size;
@@ -731,7 +699,6 @@ int iwlagn_hw_nic_init(struct iwl_priv *priv)
731{ 699{
732 unsigned long flags; 700 unsigned long flags;
733 struct iwl_rx_queue *rxq = &priv->rxq; 701 struct iwl_rx_queue *rxq = &priv->rxq;
734 int ret;
735 702
736 /* nic_init */ 703 /* nic_init */
737 spin_lock_irqsave(&priv->lock, flags); 704 spin_lock_irqsave(&priv->lock, flags);
@@ -747,14 +714,7 @@ int iwlagn_hw_nic_init(struct iwl_priv *priv)
747 priv->cfg->ops->lib->apm_ops.config(priv); 714 priv->cfg->ops->lib->apm_ops.config(priv);
748 715
749 /* Allocate the RX queue, or reset if it is already allocated */ 716 /* Allocate the RX queue, or reset if it is already allocated */
750 if (!rxq->bd) { 717 priv->trans.ops->rx_init(priv);
751 ret = iwl_rx_queue_alloc(priv);
752 if (ret) {
753 IWL_ERR(priv, "Unable to initialize Rx queue\n");
754 return -ENOMEM;
755 }
756 } else
757 iwlagn_rx_queue_reset(priv, rxq);
758 718
759 iwlagn_rx_replenish(priv); 719 iwlagn_rx_replenish(priv);
760 720
@@ -768,12 +728,8 @@ int iwlagn_hw_nic_init(struct iwl_priv *priv)
768 spin_unlock_irqrestore(&priv->lock, flags); 728 spin_unlock_irqrestore(&priv->lock, flags);
769 729
770 /* Allocate or reset and init all Tx and Command queues */ 730 /* Allocate or reset and init all Tx and Command queues */
771 if (!priv->txq) { 731 if (priv->trans.ops->tx_init(priv))
772 ret = iwlagn_txq_ctx_alloc(priv); 732 return -ENOMEM;
773 if (ret)
774 return ret;
775 } else
776 iwlagn_txq_ctx_reset(priv);
777 733
778 if (priv->cfg->base_params->shadow_reg_enable) { 734 if (priv->cfg->base_params->shadow_reg_enable) {
779 /* enable shadow regs in HW */ 735 /* enable shadow regs in HW */
@@ -949,33 +905,6 @@ void iwlagn_rx_replenish_now(struct iwl_priv *priv)
949 iwlagn_rx_queue_restock(priv); 905 iwlagn_rx_queue_restock(priv);
950} 906}
951 907
952/* Assumes that the skb field of the buffers in 'pool' is kept accurate.
953 * If an SKB has been detached, the POOL needs to have its SKB set to NULL
954 * This free routine walks the list of POOL entries and if SKB is set to
955 * non NULL it is unmapped and freed
956 */
957void iwlagn_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
958{
959 int i;
960 for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) {
961 if (rxq->pool[i].page != NULL) {
962 dma_unmap_page(priv->bus.dev, rxq->pool[i].page_dma,
963 PAGE_SIZE << priv->hw_params.rx_page_order,
964 DMA_FROM_DEVICE);
965 __iwl_free_pages(priv, rxq->pool[i].page);
966 rxq->pool[i].page = NULL;
967 }
968 }
969
970 dma_free_coherent(priv->bus.dev, 4 * RX_QUEUE_SIZE,
971 rxq->bd, rxq->bd_dma);
972 dma_free_coherent(priv->bus.dev,
973 sizeof(struct iwl_rb_status),
974 rxq->rb_stts, rxq->rb_stts_dma);
975 rxq->bd = NULL;
976 rxq->rb_stts = NULL;
977}
978
979int iwlagn_rxq_stop(struct iwl_priv *priv) 908int iwlagn_rxq_stop(struct iwl_priv *priv)
980{ 909{
981 910
@@ -1437,17 +1366,14 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
1437 /* set scan bit here for PAN params */ 1366 /* set scan bit here for PAN params */
1438 set_bit(STATUS_SCAN_HW, &priv->status); 1367 set_bit(STATUS_SCAN_HW, &priv->status);
1439 1368
1440 if (priv->cfg->ops->hcmd->set_pan_params) { 1369 ret = iwlagn_set_pan_params(priv);
1441 ret = priv->cfg->ops->hcmd->set_pan_params(priv); 1370 if (ret)
1442 if (ret) 1371 return ret;
1443 return ret;
1444 }
1445 1372
1446 ret = iwl_send_cmd_sync(priv, &cmd); 1373 ret = iwl_send_cmd_sync(priv, &cmd);
1447 if (ret) { 1374 if (ret) {
1448 clear_bit(STATUS_SCAN_HW, &priv->status); 1375 clear_bit(STATUS_SCAN_HW, &priv->status);
1449 if (priv->cfg->ops->hcmd->set_pan_params) 1376 iwlagn_set_pan_params(priv);
1450 priv->cfg->ops->hcmd->set_pan_params(priv);
1451 } 1377 }
1452 1378
1453 return ret; 1379 return ret;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
index 8fa43d427811..c6bb73a66d9f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
@@ -436,11 +436,9 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
436 if (ret) 436 if (ret)
437 return ret; 437 return ret;
438 438
439 if (priv->cfg->ops->hcmd->set_pan_params) { 439 ret = iwlagn_set_pan_params(priv);
440 ret = priv->cfg->ops->hcmd->set_pan_params(priv); 440 if (ret)
441 if (ret) 441 return ret;
442 return ret;
443 }
444 442
445 if (new_assoc) 443 if (new_assoc)
446 return iwlagn_rxon_connect(priv, ctx); 444 return iwlagn_rxon_connect(priv, ctx);
@@ -483,9 +481,8 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
483 * set up the SM PS mode to OFF if an HT channel is 481 * set up the SM PS mode to OFF if an HT channel is
484 * configured. 482 * configured.
485 */ 483 */
486 if (priv->cfg->ops->hcmd->set_rxon_chain) 484 for_each_context(priv, ctx)
487 for_each_context(priv, ctx) 485 iwlagn_set_rxon_chain(priv, ctx);
488 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
489 } 486 }
490 487
491 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { 488 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
@@ -741,8 +738,7 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
741 iwl_set_rxon_ht(priv, &priv->current_ht_config); 738 iwl_set_rxon_ht(priv, &priv->current_ht_config);
742 } 739 }
743 740
744 if (priv->cfg->ops->hcmd->set_rxon_chain) 741 iwlagn_set_rxon_chain(priv, ctx);
745 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
746 742
747 if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ)) 743 if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ))
748 ctx->staging.flags |= RXON_FLG_TGG_PROTECT_MSK; 744 ctx->staging.flags |= RXON_FLG_TGG_PROTECT_MSK;
@@ -821,6 +817,5 @@ void iwlagn_post_scan(struct iwl_priv *priv)
821 if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging))) 817 if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
822 iwlagn_commit_rxon(priv, ctx); 818 iwlagn_commit_rxon(priv, ctx);
823 819
824 if (priv->cfg->ops->hcmd->set_pan_params) 820 iwlagn_set_pan_params(priv);
825 priv->cfg->ops->hcmd->set_pan_params(priv);
826} 821}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index d0ac090399e9..c05a8d9fbd2e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -878,96 +878,6 @@ void iwlagn_hw_txq_ctx_free(struct iwl_priv *priv)
878} 878}
879 879
880/** 880/**
881 * iwlagn_txq_ctx_alloc - allocate TX queue context
882 * Allocate all Tx DMA structures and initialize them
883 *
884 * @param priv
885 * @return error code
886 */
887int iwlagn_txq_ctx_alloc(struct iwl_priv *priv)
888{
889 int ret;
890 int txq_id, slots_num;
891 unsigned long flags;
892
893 /* Free all tx/cmd queues and keep-warm buffer */
894 iwlagn_hw_txq_ctx_free(priv);
895
896 ret = iwlagn_alloc_dma_ptr(priv, &priv->scd_bc_tbls,
897 priv->hw_params.scd_bc_tbls_size);
898 if (ret) {
899 IWL_ERR(priv, "Scheduler BC Table allocation failed\n");
900 goto error_bc_tbls;
901 }
902 /* Alloc keep-warm buffer */
903 ret = iwlagn_alloc_dma_ptr(priv, &priv->kw, IWL_KW_SIZE);
904 if (ret) {
905 IWL_ERR(priv, "Keep Warm allocation failed\n");
906 goto error_kw;
907 }
908
909 /* allocate tx queue structure */
910 ret = iwl_alloc_txq_mem(priv);
911 if (ret)
912 goto error;
913
914 spin_lock_irqsave(&priv->lock, flags);
915
916 /* Turn off all Tx DMA fifos */
917 iwlagn_txq_set_sched(priv, 0);
918
919 /* Tell NIC where to find the "keep warm" buffer */
920 iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4);
921
922 spin_unlock_irqrestore(&priv->lock, flags);
923
924 /* Alloc and init all Tx queues, including the command queue (#4/#9) */
925 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
926 slots_num = (txq_id == priv->cmd_queue) ?
927 TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
928 ret = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num,
929 txq_id);
930 if (ret) {
931 IWL_ERR(priv, "Tx %d queue init failed\n", txq_id);
932 goto error;
933 }
934 }
935
936 return ret;
937
938 error:
939 iwlagn_hw_txq_ctx_free(priv);
940 iwlagn_free_dma_ptr(priv, &priv->kw);
941 error_kw:
942 iwlagn_free_dma_ptr(priv, &priv->scd_bc_tbls);
943 error_bc_tbls:
944 return ret;
945}
946
947void iwlagn_txq_ctx_reset(struct iwl_priv *priv)
948{
949 int txq_id, slots_num;
950 unsigned long flags;
951
952 spin_lock_irqsave(&priv->lock, flags);
953
954 /* Turn off all Tx DMA fifos */
955 iwlagn_txq_set_sched(priv, 0);
956
957 /* Tell NIC where to find the "keep warm" buffer */
958 iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4);
959
960 spin_unlock_irqrestore(&priv->lock, flags);
961
962 /* Alloc and init all Tx queues, including the command queue (#4) */
963 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
964 slots_num = txq_id == priv->cmd_queue ?
965 TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
966 iwl_tx_queue_reset(priv, &priv->txq[txq_id], slots_num, txq_id);
967 }
968}
969
970/**
971 * iwlagn_txq_ctx_stop - Stop all Tx DMA channels 881 * iwlagn_txq_ctx_stop - Stop all Tx DMA channels
972 */ 882 */
973void iwlagn_txq_ctx_stop(struct iwl_priv *priv) 883void iwlagn_txq_ctx_stop(struct iwl_priv *priv)
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
index de8277e32253..2043c8b3139b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
@@ -386,11 +386,13 @@ static int iwlagn_alive_notify(struct iwl_priv *priv)
386 spin_lock_irqsave(&priv->lock, flags); 386 spin_lock_irqsave(&priv->lock, flags);
387 387
388 priv->scd_base_addr = iwl_read_prph(priv, IWLAGN_SCD_SRAM_BASE_ADDR); 388 priv->scd_base_addr = iwl_read_prph(priv, IWLAGN_SCD_SRAM_BASE_ADDR);
389 a = priv->scd_base_addr + IWLAGN_SCD_CONTEXT_DATA_OFFSET; 389 a = priv->scd_base_addr + IWLAGN_SCD_CONTEXT_MEM_LOWER_BOUND;
390 for (; a < priv->scd_base_addr + IWLAGN_SCD_TX_STTS_BITMAP_OFFSET; 390 /* reset conext data memory */
391 for (; a < priv->scd_base_addr + IWLAGN_SCD_CONTEXT_MEM_UPPER_BOUND;
391 a += 4) 392 a += 4)
392 iwl_write_targ_mem(priv, a, 0); 393 iwl_write_targ_mem(priv, a, 0);
393 for (; a < priv->scd_base_addr + IWLAGN_SCD_TRANSLATE_TBL_OFFSET; 394 /* reset tx status memory */
395 for (; a < priv->scd_base_addr + IWLAGN_SCD_TX_STTS_MEM_UPPER_BOUND;
394 a += 4) 396 a += 4)
395 iwl_write_targ_mem(priv, a, 0); 397 iwl_write_targ_mem(priv, a, 0);
396 for (; a < priv->scd_base_addr + 398 for (; a < priv->scd_base_addr +
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index e2f6b2ab0d45..7e6c463abbdf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -56,7 +56,7 @@
56#include "iwl-agn-calib.h" 56#include "iwl-agn-calib.h"
57#include "iwl-agn.h" 57#include "iwl-agn.h"
58#include "iwl-pci.h" 58#include "iwl-pci.h"
59 59#include "iwl-trans.h"
60 60
61/****************************************************************************** 61/******************************************************************************
62 * 62 *
@@ -90,12 +90,10 @@ void iwl_update_chain_flags(struct iwl_priv *priv)
90{ 90{
91 struct iwl_rxon_context *ctx; 91 struct iwl_rxon_context *ctx;
92 92
93 if (priv->cfg->ops->hcmd->set_rxon_chain) { 93 for_each_context(priv, ctx) {
94 for_each_context(priv, ctx) { 94 iwlagn_set_rxon_chain(priv, ctx);
95 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); 95 if (ctx->active.rx_chain != ctx->staging.rx_chain)
96 if (ctx->active.rx_chain != ctx->staging.rx_chain) 96 iwlagn_commit_rxon(priv, ctx);
97 iwlagn_commit_rxon(priv, ctx);
98 }
99 } 97 }
100} 98}
101 99
@@ -260,7 +258,7 @@ static void iwl_bg_bt_runtime_config(struct work_struct *work)
260 /* dont send host command if rf-kill is on */ 258 /* dont send host command if rf-kill is on */
261 if (!iwl_is_ready_rf(priv)) 259 if (!iwl_is_ready_rf(priv))
262 return; 260 return;
263 priv->cfg->ops->hcmd->send_bt_config(priv); 261 iwlagn_send_advance_bt_config(priv);
264} 262}
265 263
266static void iwl_bg_bt_full_concurrency(struct work_struct *work) 264static void iwl_bg_bt_full_concurrency(struct work_struct *work)
@@ -287,12 +285,11 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work)
287 * to avoid 3-wire collisions 285 * to avoid 3-wire collisions
288 */ 286 */
289 for_each_context(priv, ctx) { 287 for_each_context(priv, ctx) {
290 if (priv->cfg->ops->hcmd->set_rxon_chain) 288 iwlagn_set_rxon_chain(priv, ctx);
291 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
292 iwlagn_commit_rxon(priv, ctx); 289 iwlagn_commit_rxon(priv, ctx);
293 } 290 }
294 291
295 priv->cfg->ops->hcmd->send_bt_config(priv); 292 iwlagn_send_advance_bt_config(priv);
296out: 293out:
297 mutex_unlock(&priv->mutex); 294 mutex_unlock(&priv->mutex);
298} 295}
@@ -2017,7 +2014,7 @@ int iwl_alive_start(struct iwl_priv *priv)
2017 priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK; 2014 priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK;
2018 priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT; 2015 priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT;
2019 priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT; 2016 priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT;
2020 priv->cfg->ops->hcmd->send_bt_config(priv); 2017 iwlagn_send_advance_bt_config(priv);
2021 priv->bt_valid = IWLAGN_BT_VALID_ENABLE_FLAGS; 2018 priv->bt_valid = IWLAGN_BT_VALID_ENABLE_FLAGS;
2022 iwlagn_send_prio_tbl(priv); 2019 iwlagn_send_prio_tbl(priv);
2023 2020
@@ -2030,7 +2027,13 @@ int iwl_alive_start(struct iwl_priv *priv)
2030 BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); 2027 BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
2031 if (ret) 2028 if (ret)
2032 return ret; 2029 return ret;
2030 } else {
2031 /*
2032 * default is 2-wire BT coexexistence support
2033 */
2034 iwl_send_bt_config(priv);
2033 } 2035 }
2036
2034 if (priv->hw_params.calib_rt_cfg) 2037 if (priv->hw_params.calib_rt_cfg)
2035 iwlagn_send_calib_cfg_rt(priv, priv->hw_params.calib_rt_cfg); 2038 iwlagn_send_calib_cfg_rt(priv, priv->hw_params.calib_rt_cfg);
2036 2039
@@ -2039,8 +2042,7 @@ int iwl_alive_start(struct iwl_priv *priv)
2039 priv->active_rate = IWL_RATES_MASK; 2042 priv->active_rate = IWL_RATES_MASK;
2040 2043
2041 /* Configure Tx antenna selection based on H/W config */ 2044 /* Configure Tx antenna selection based on H/W config */
2042 if (priv->cfg->ops->hcmd->set_tx_ant) 2045 iwlagn_send_tx_ant_config(priv, priv->cfg->valid_tx_ant);
2043 priv->cfg->ops->hcmd->set_tx_ant(priv, priv->cfg->valid_tx_ant);
2044 2046
2045 if (iwl_is_associated_ctx(ctx)) { 2047 if (iwl_is_associated_ctx(ctx)) {
2046 struct iwl_rxon_cmd *active_rxon = 2048 struct iwl_rxon_cmd *active_rxon =
@@ -2054,16 +2056,7 @@ int iwl_alive_start(struct iwl_priv *priv)
2054 for_each_context(priv, tmp) 2056 for_each_context(priv, tmp)
2055 iwl_connection_init_rx_config(priv, tmp); 2057 iwl_connection_init_rx_config(priv, tmp);
2056 2058
2057 if (priv->cfg->ops->hcmd->set_rxon_chain) 2059 iwlagn_set_rxon_chain(priv, ctx);
2058 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
2059 }
2060
2061 if (!priv->cfg->bt_params || (priv->cfg->bt_params &&
2062 !priv->cfg->bt_params->advanced_bt_coexist)) {
2063 /*
2064 * default is 2-wire BT coexexistence support
2065 */
2066 priv->cfg->ops->hcmd->send_bt_config(priv);
2067 } 2060 }
2068 2061
2069 iwl_reset_run_time_calib(priv); 2062 iwl_reset_run_time_calib(priv);
@@ -3288,9 +3281,7 @@ static int iwl_init_drv(struct iwl_priv *priv)
3288 priv->rx_statistics_jiffies = jiffies; 3281 priv->rx_statistics_jiffies = jiffies;
3289 3282
3290 /* Choose which receivers/antennas to use */ 3283 /* Choose which receivers/antennas to use */
3291 if (priv->cfg->ops->hcmd->set_rxon_chain) 3284 iwlagn_set_rxon_chain(priv, &priv->contexts[IWL_RXON_CTX_BSS]);
3292 priv->cfg->ops->hcmd->set_rxon_chain(priv,
3293 &priv->contexts[IWL_RXON_CTX_BSS]);
3294 3285
3295 iwl_init_scan_params(priv); 3286 iwl_init_scan_params(priv);
3296 3287
@@ -3517,6 +3508,8 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops,
3517 priv->bus.ops->set_drv_data(&priv->bus, priv); 3508 priv->bus.ops->set_drv_data(&priv->bus, priv);
3518 priv->bus.dev = priv->bus.ops->get_dev(&priv->bus); 3509 priv->bus.dev = priv->bus.ops->get_dev(&priv->bus);
3519 3510
3511 iwl_trans_register(&priv->trans);
3512
3520 /* At this point both hw and priv are allocated. */ 3513 /* At this point both hw and priv are allocated. */
3521 3514
3522 SET_IEEE80211_DEV(hw, priv->bus.dev); 3515 SET_IEEE80211_DEV(hw, priv->bus.dev);
@@ -3716,8 +3709,7 @@ void __devexit iwl_remove(struct iwl_priv * priv)
3716 3709
3717 iwl_dealloc_ucode(priv); 3710 iwl_dealloc_ucode(priv);
3718 3711
3719 if (priv->rxq.bd) 3712 priv->trans.ops->rx_free(priv);
3720 iwlagn_rx_queue_free(priv, &priv->rxq);
3721 iwlagn_hw_txq_ctx_free(priv); 3713 iwlagn_hw_txq_ctx_free(priv);
3722 3714
3723 iwl_eeprom_free(priv); 3715 iwl_eeprom_free(priv);
@@ -3820,6 +3812,10 @@ MODULE_PARM_DESC(plcp_check, "Check plcp health (default: 1 [enabled])");
3820module_param_named(ack_check, iwlagn_mod_params.ack_check, bool, S_IRUGO); 3812module_param_named(ack_check, iwlagn_mod_params.ack_check, bool, S_IRUGO);
3821MODULE_PARM_DESC(ack_check, "Check ack health (default: 0 [disabled])"); 3813MODULE_PARM_DESC(ack_check, "Check ack health (default: 0 [disabled])");
3822 3814
3815module_param_named(wd_disable, iwlagn_mod_params.wd_disable, bool, S_IRUGO);
3816MODULE_PARM_DESC(wd_disable,
3817 "Disable stuck queue watchdog timer (default: 0 [enabled])");
3818
3823/* 3819/*
3824 * set bt_coex_active to true, uCode will do kill/defer 3820 * set bt_coex_active to true, uCode will do kill/defer
3825 * every time the priority line is asserted (BT is sending signals on the 3821 * every time the priority line is asserted (BT is sending signals on the
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index dcdf2259520f..4351151e2a91 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -182,7 +182,6 @@ void iwlagn_temperature(struct iwl_priv *priv);
182u16 iwlagn_eeprom_calib_version(struct iwl_priv *priv); 182u16 iwlagn_eeprom_calib_version(struct iwl_priv *priv);
183const u8 *iwlagn_eeprom_query_addr(const struct iwl_priv *priv, 183const u8 *iwlagn_eeprom_query_addr(const struct iwl_priv *priv,
184 size_t offset); 184 size_t offset);
185void iwlagn_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
186int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq); 185int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
187int iwlagn_hw_nic_init(struct iwl_priv *priv); 186int iwlagn_hw_nic_init(struct iwl_priv *priv);
188int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv); 187int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv);
@@ -194,7 +193,6 @@ void iwlagn_rx_queue_restock(struct iwl_priv *priv);
194void iwlagn_rx_allocate(struct iwl_priv *priv, gfp_t priority); 193void iwlagn_rx_allocate(struct iwl_priv *priv, gfp_t priority);
195void iwlagn_rx_replenish(struct iwl_priv *priv); 194void iwlagn_rx_replenish(struct iwl_priv *priv);
196void iwlagn_rx_replenish_now(struct iwl_priv *priv); 195void iwlagn_rx_replenish_now(struct iwl_priv *priv);
197void iwlagn_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
198int iwlagn_rxq_stop(struct iwl_priv *priv); 196int iwlagn_rxq_stop(struct iwl_priv *priv);
199int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band); 197int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band);
200void iwl_setup_rx_handlers(struct iwl_priv *priv); 198void iwl_setup_rx_handlers(struct iwl_priv *priv);
@@ -220,8 +218,6 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
220 struct iwl_rx_mem_buffer *rxb); 218 struct iwl_rx_mem_buffer *rxb);
221int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index); 219int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index);
222void iwlagn_hw_txq_ctx_free(struct iwl_priv *priv); 220void iwlagn_hw_txq_ctx_free(struct iwl_priv *priv);
223int iwlagn_txq_ctx_alloc(struct iwl_priv *priv);
224void iwlagn_txq_ctx_reset(struct iwl_priv *priv);
225void iwlagn_txq_ctx_stop(struct iwl_priv *priv); 221void iwlagn_txq_ctx_stop(struct iwl_priv *priv);
226 222
227static inline u32 iwl_tx_status_to_mac80211(u32 status) 223static inline u32 iwl_tx_status_to_mac80211(u32 status)
@@ -260,6 +256,7 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv,
260/* hcmd */ 256/* hcmd */
261int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant); 257int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant);
262int iwlagn_send_beacon_cmd(struct iwl_priv *priv); 258int iwlagn_send_beacon_cmd(struct iwl_priv *priv);
259int iwlagn_set_pan_params(struct iwl_priv *priv);
263 260
264/* bt coex */ 261/* bt coex */
265void iwlagn_send_advance_bt_config(struct iwl_priv *priv); 262void iwlagn_send_advance_bt_config(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 7f16d1203057..f91e306c2498 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -585,8 +585,7 @@ static void _iwl_set_rxon_ht(struct iwl_priv *priv,
585 rxon->flags |= RXON_FLG_CHANNEL_MODE_LEGACY; 585 rxon->flags |= RXON_FLG_CHANNEL_MODE_LEGACY;
586 } 586 }
587 587
588 if (priv->cfg->ops->hcmd->set_rxon_chain) 588 iwlagn_set_rxon_chain(priv, ctx);
589 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
590 589
591 IWL_DEBUG_ASSOC(priv, "rxon flags 0x%X operation mode :0x%X " 590 IWL_DEBUG_ASSOC(priv, "rxon flags 0x%X operation mode :0x%X "
592 "extension channel offset 0x%x\n", 591 "extension channel offset 0x%x\n",
@@ -1216,8 +1215,7 @@ static int iwl_set_mode(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
1216{ 1215{
1217 iwl_connection_init_rx_config(priv, ctx); 1216 iwl_connection_init_rx_config(priv, ctx);
1218 1217
1219 if (priv->cfg->ops->hcmd->set_rxon_chain) 1218 iwlagn_set_rxon_chain(priv, ctx);
1220 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
1221 1219
1222 return iwlagn_commit_rxon(priv, ctx); 1220 return iwlagn_commit_rxon(priv, ctx);
1223} 1221}
@@ -1372,20 +1370,6 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
1372 1370
1373} 1371}
1374 1372
1375int iwl_alloc_txq_mem(struct iwl_priv *priv)
1376{
1377 if (!priv->txq)
1378 priv->txq = kzalloc(
1379 sizeof(struct iwl_tx_queue) *
1380 priv->cfg->base_params->num_of_queues,
1381 GFP_KERNEL);
1382 if (!priv->txq) {
1383 IWL_ERR(priv, "Not enough memory for txq\n");
1384 return -ENOMEM;
1385 }
1386 return 0;
1387}
1388
1389void iwl_free_txq_mem(struct iwl_priv *priv) 1373void iwl_free_txq_mem(struct iwl_priv *priv)
1390{ 1374{
1391 kfree(priv->txq); 1375 kfree(priv->txq);
@@ -1853,7 +1837,7 @@ void iwl_setup_watchdog(struct iwl_priv *priv)
1853{ 1837{
1854 unsigned int timeout = priv->cfg->base_params->wd_timeout; 1838 unsigned int timeout = priv->cfg->base_params->wd_timeout;
1855 1839
1856 if (timeout) 1840 if (timeout && !iwlagn_mod_params.wd_disable)
1857 mod_timer(&priv->watchdog, 1841 mod_timer(&priv->watchdog,
1858 jiffies + msecs_to_jiffies(IWL_WD_TICK(timeout))); 1842 jiffies + msecs_to_jiffies(IWL_WD_TICK(timeout)));
1859 else 1843 else
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index f881678be762..6c21de9f5b60 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -80,14 +80,6 @@ struct iwl_cmd;
80 80
81#define IWL_CMD(x) case x: return #x 81#define IWL_CMD(x) case x: return #x
82 82
83struct iwl_hcmd_ops {
84 void (*set_rxon_chain)(struct iwl_priv *priv,
85 struct iwl_rxon_context *ctx);
86 int (*set_tx_ant)(struct iwl_priv *priv, u8 valid_tx_ant);
87 void (*send_bt_config)(struct iwl_priv *priv);
88 int (*set_pan_params)(struct iwl_priv *priv);
89};
90
91struct iwl_hcmd_utils_ops { 83struct iwl_hcmd_utils_ops {
92 u16 (*build_addsta_hcmd)(const struct iwl_addsta_cmd *cmd, u8 *data); 84 u16 (*build_addsta_hcmd)(const struct iwl_addsta_cmd *cmd, u8 *data);
93 void (*gain_computation)(struct iwl_priv *priv, 85 void (*gain_computation)(struct iwl_priv *priv,
@@ -146,7 +138,6 @@ struct iwl_nic_ops {
146 138
147struct iwl_ops { 139struct iwl_ops {
148 const struct iwl_lib_ops *lib; 140 const struct iwl_lib_ops *lib;
149 const struct iwl_hcmd_ops *hcmd;
150 const struct iwl_hcmd_utils_ops *utils; 141 const struct iwl_hcmd_utils_ops *utils;
151 const struct iwl_nic_ops *nic; 142 const struct iwl_nic_ops *nic;
152}; 143};
@@ -160,6 +151,7 @@ struct iwl_mod_params {
160 int restart_fw; /* def: 1 = restart firmware */ 151 int restart_fw; /* def: 1 = restart firmware */
161 bool plcp_check; /* def: true = enable plcp health check */ 152 bool plcp_check; /* def: true = enable plcp health check */
162 bool ack_check; /* def: false = disable ack health check */ 153 bool ack_check; /* def: false = disable ack health check */
154 bool wd_disable; /* def: false = enable stuck queue check */
163 bool bt_coex_active; /* def: true = enable bt coex */ 155 bool bt_coex_active; /* def: true = enable bt coex */
164 int led_mode; /* def: 0 = system default */ 156 int led_mode; /* def: 0 = system default */
165 bool no_sleep_autoadjust; /* def: true = disable autoadjust */ 157 bool no_sleep_autoadjust; /* def: true = disable autoadjust */
@@ -336,7 +328,6 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
336int iwl_mac_change_interface(struct ieee80211_hw *hw, 328int iwl_mac_change_interface(struct ieee80211_hw *hw,
337 struct ieee80211_vif *vif, 329 struct ieee80211_vif *vif,
338 enum nl80211_iftype newtype, bool newp2p); 330 enum nl80211_iftype newtype, bool newp2p);
339int iwl_alloc_txq_mem(struct iwl_priv *priv);
340void iwl_free_txq_mem(struct iwl_priv *priv); 331void iwl_free_txq_mem(struct iwl_priv *priv);
341 332
342#ifdef CONFIG_IWLWIFI_DEBUGFS 333#ifdef CONFIG_IWLWIFI_DEBUGFS
@@ -382,7 +373,6 @@ static inline void iwl_update_stats(struct iwl_priv *priv, bool is_tx,
382******************************************************/ 373******************************************************/
383void iwl_cmd_queue_free(struct iwl_priv *priv); 374void iwl_cmd_queue_free(struct iwl_priv *priv);
384void iwl_cmd_queue_unmap(struct iwl_priv *priv); 375void iwl_cmd_queue_unmap(struct iwl_priv *priv);
385int iwl_rx_queue_alloc(struct iwl_priv *priv);
386void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, 376void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv,
387 struct iwl_rx_queue *q); 377 struct iwl_rx_queue *q);
388int iwl_rx_queue_space(const struct iwl_rx_queue *q); 378int iwl_rx_queue_space(const struct iwl_rx_queue *q);
@@ -396,11 +386,9 @@ void iwl_chswitch_done(struct iwl_priv *priv, bool is_success);
396* TX 386* TX
397******************************************************/ 387******************************************************/
398void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq); 388void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq);
399int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
400 int slots_num, u32 txq_id);
401void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq,
402 int slots_num, u32 txq_id);
403void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id); 389void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id);
390int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q,
391 int count, int slots_num, u32 id);
404void iwl_tx_queue_unmap(struct iwl_priv *priv, int txq_id); 392void iwl_tx_queue_unmap(struct iwl_priv *priv, int txq_id);
405void iwl_setup_watchdog(struct iwl_priv *priv); 393void iwl_setup_watchdog(struct iwl_priv *priv);
406/***************************************************** 394/*****************************************************
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index f1b1128ee1c4..c6560e97a62b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -666,7 +666,6 @@ struct iwl_hw_params {
666 u16 max_rxq_size; 666 u16 max_rxq_size;
667 u16 max_rxq_log; 667 u16 max_rxq_log;
668 u32 rx_page_order; 668 u32 rx_page_order;
669 u32 rx_wrt_ptr_reg;
670 u8 max_stations; 669 u8 max_stations;
671 u8 ht40_channel; 670 u8 ht40_channel;
672 u8 max_beacon_itrvl; /* in 1024 ms */ 671 u8 max_beacon_itrvl; /* in 1024 ms */
@@ -1228,6 +1227,25 @@ struct iwl_bus {
1228 unsigned int irq; 1227 unsigned int irq;
1229}; 1228};
1230 1229
1230struct iwl_trans;
1231
1232/**
1233 * struct iwl_trans_ops - transport specific operations
1234
1235 * @rx_init: inits the rx memory, allocate it if needed
1236 * @rx_free: frees the rx memory
1237 * @tx_init:inits the tx memory, allocate if needed
1238 */
1239struct iwl_trans_ops {
1240 int (*rx_init)(struct iwl_priv *priv);
1241 void (*rx_free)(struct iwl_priv *priv);
1242 int (*tx_init)(struct iwl_priv *priv);
1243};
1244
1245struct iwl_trans {
1246 const struct iwl_trans_ops *ops;
1247};
1248
1231struct iwl_priv { 1249struct iwl_priv {
1232 1250
1233 /* ieee device used by generic ieee processing code */ 1251 /* ieee device used by generic ieee processing code */
@@ -1296,13 +1314,13 @@ struct iwl_priv {
1296 struct mutex mutex; 1314 struct mutex mutex;
1297 1315
1298 struct iwl_bus bus; /* bus specific data */ 1316 struct iwl_bus bus; /* bus specific data */
1317 struct iwl_trans trans;
1299 1318
1300 /* microcode/device supports multiple contexts */ 1319 /* microcode/device supports multiple contexts */
1301 u8 valid_contexts; 1320 u8 valid_contexts;
1302 1321
1303 /* command queue number */ 1322 /* command queue number */
1304 u8 cmd_queue; 1323 u8 cmd_queue;
1305 u8 last_sync_cmd_id;
1306 1324
1307 /* max number of station keys */ 1325 /* max number of station keys */
1308 u8 sta_key_max_num; 1326 u8 sta_key_max_num;
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
index e3e5fb614178..107b38e2ee93 100644
--- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
@@ -171,6 +171,8 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
171 int cmd_idx; 171 int cmd_idx;
172 int ret; 172 int ret;
173 173
174 lockdep_assert_held(&priv->mutex);
175
174 if (WARN_ON(cmd->flags & CMD_ASYNC)) 176 if (WARN_ON(cmd->flags & CMD_ASYNC))
175 return -EINVAL; 177 return -EINVAL;
176 178
@@ -181,16 +183,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
181 IWL_DEBUG_INFO(priv, "Attempting to send sync command %s\n", 183 IWL_DEBUG_INFO(priv, "Attempting to send sync command %s\n",
182 get_cmd_string(cmd->id)); 184 get_cmd_string(cmd->id));
183 185
184 if (test_and_set_bit(STATUS_HCMD_ACTIVE, &priv->status)) { 186 set_bit(STATUS_HCMD_ACTIVE, &priv->status);
185 IWL_ERR(priv, "STATUS_HCMD_ACTIVE already set while sending %s"
186 ". Previous SYNC cmdn is %s\n",
187 get_cmd_string(cmd->id),
188 get_cmd_string(priv->last_sync_cmd_id));
189 WARN_ON(1);
190 } else {
191 priv->last_sync_cmd_id = cmd->id;
192 }
193
194 IWL_DEBUG_INFO(priv, "Setting HCMD_ACTIVE for command %s\n", 187 IWL_DEBUG_INFO(priv, "Setting HCMD_ACTIVE for command %s\n",
195 get_cmd_string(cmd->id)); 188 get_cmd_string(cmd->id));
196 189
diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c
index 3b5844b60e7c..74911348a2ee 100644
--- a/drivers/net/wireless/iwlwifi/iwl-pci.c
+++ b/drivers/net/wireless/iwlwifi/iwl-pci.c
@@ -67,6 +67,7 @@
67#include "iwl-agn.h" 67#include "iwl-agn.h"
68#include "iwl-core.h" 68#include "iwl-core.h"
69#include "iwl-io.h" 69#include "iwl-io.h"
70#include "iwl-trans.h"
70 71
71/* PCI registers */ 72/* PCI registers */
72#define PCI_CFG_RETRY_TIMEOUT 0x041 73#define PCI_CFG_RETRY_TIMEOUT 0x041
@@ -93,7 +94,7 @@ static u16 iwl_pciexp_link_ctrl(struct iwl_bus *bus)
93 u16 pci_lnk_ctl; 94 u16 pci_lnk_ctl;
94 struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus); 95 struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus);
95 96
96 pos = pci_find_capability(pci_dev, PCI_CAP_ID_EXP); 97 pos = pci_pcie_cap(pci_dev);
97 pci_read_config_word(pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl); 98 pci_read_config_word(pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl);
98 return pci_lnk_ctl; 99 return pci_lnk_ctl;
99} 100}
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index f00d188b2cfc..1cc0ed1f488c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -168,6 +168,7 @@
168 * the scheduler (especially for queue #4/#9, the command queue, otherwise 168 * the scheduler (especially for queue #4/#9, the command queue, otherwise
169 * the driver can't issue commands!): 169 * the driver can't issue commands!):
170 */ 170 */
171#define SCD_MEM_LOWER_BOUND (0x0000)
171 172
172/** 173/**
173 * Max Tx window size is the max number of contiguous TFDs that the scheduler 174 * Max Tx window size is the max number of contiguous TFDs that the scheduler
@@ -197,15 +198,23 @@
197#define IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS (16) 198#define IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS (16)
198#define IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK (0x007F0000) 199#define IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK (0x007F0000)
199 200
200#define IWLAGN_SCD_CONTEXT_DATA_OFFSET (0x600) 201/* Context Data */
201#define IWLAGN_SCD_TX_STTS_BITMAP_OFFSET (0x7B1) 202#define IWLAGN_SCD_CONTEXT_MEM_LOWER_BOUND (SCD_MEM_LOWER_BOUND + 0x600)
202#define IWLAGN_SCD_TRANSLATE_TBL_OFFSET (0x7E0) 203#define IWLAGN_SCD_CONTEXT_MEM_UPPER_BOUND (SCD_MEM_LOWER_BOUND + 0x6A0)
204
205/* Tx status */
206#define IWLAGN_SCD_TX_STTS_MEM_LOWER_BOUND (SCD_MEM_LOWER_BOUND + 0x6A0)
207#define IWLAGN_SCD_TX_STTS_MEM_UPPER_BOUND (SCD_MEM_LOWER_BOUND + 0x7E0)
208
209/* Translation Data */
210#define IWLAGN_SCD_TRANS_TBL_MEM_LOWER_BOUND (SCD_MEM_LOWER_BOUND + 0x7E0)
211#define IWLAGN_SCD_TRANS_TBL_MEM_UPPER_BOUND (SCD_MEM_LOWER_BOUND + 0x808)
203 212
204#define IWLAGN_SCD_CONTEXT_QUEUE_OFFSET(x)\ 213#define IWLAGN_SCD_CONTEXT_QUEUE_OFFSET(x)\
205 (IWLAGN_SCD_CONTEXT_DATA_OFFSET + ((x) * 8)) 214 (IWLAGN_SCD_CONTEXT_MEM_LOWER_BOUND + ((x) * 8))
206 215
207#define IWLAGN_SCD_TRANSLATE_TBL_OFFSET_QUEUE(x) \ 216#define IWLAGN_SCD_TRANSLATE_TBL_OFFSET_QUEUE(x) \
208 ((IWLAGN_SCD_TRANSLATE_TBL_OFFSET + ((x) * 2)) & 0xfffc) 217 ((IWLAGN_SCD_TRANS_TBL_MEM_LOWER_BOUND + ((x) * 2)) & 0xfffc)
209 218
210#define IWLAGN_SCD_QUEUECHAIN_SEL_ALL(priv) \ 219#define IWLAGN_SCD_QUEUECHAIN_SEL_ALL(priv) \
211 (((1<<(priv)->hw_params.max_txq_num) - 1) &\ 220 (((1<<(priv)->hw_params.max_txq_num) - 1) &\
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 3efa7066e987..87148bb3f628 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -134,7 +134,6 @@ int iwl_rx_queue_space(const struct iwl_rx_queue *q)
134void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q) 134void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q)
135{ 135{
136 unsigned long flags; 136 unsigned long flags;
137 u32 rx_wrt_ptr_reg = priv->hw_params.rx_wrt_ptr_reg;
138 u32 reg; 137 u32 reg;
139 138
140 spin_lock_irqsave(&q->lock, flags); 139 spin_lock_irqsave(&q->lock, flags);
@@ -146,7 +145,7 @@ void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q
146 /* shadow register enabled */ 145 /* shadow register enabled */
147 /* Device expects a multiple of 8 */ 146 /* Device expects a multiple of 8 */
148 q->write_actual = (q->write & ~0x7); 147 q->write_actual = (q->write & ~0x7);
149 iwl_write32(priv, rx_wrt_ptr_reg, q->write_actual); 148 iwl_write32(priv, FH_RSCSR_CHNL0_WPTR, q->write_actual);
150 } else { 149 } else {
151 /* If power-saving is in use, make sure device is awake */ 150 /* If power-saving is in use, make sure device is awake */
152 if (test_bit(STATUS_POWER_PMI, &priv->status)) { 151 if (test_bit(STATUS_POWER_PMI, &priv->status)) {
@@ -162,14 +161,14 @@ void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q
162 } 161 }
163 162
164 q->write_actual = (q->write & ~0x7); 163 q->write_actual = (q->write & ~0x7);
165 iwl_write_direct32(priv, rx_wrt_ptr_reg, 164 iwl_write_direct32(priv, FH_RSCSR_CHNL0_WPTR,
166 q->write_actual); 165 q->write_actual);
167 166
168 /* Else device is assumed to be awake */ 167 /* Else device is assumed to be awake */
169 } else { 168 } else {
170 /* Device expects a multiple of 8 */ 169 /* Device expects a multiple of 8 */
171 q->write_actual = (q->write & ~0x7); 170 q->write_actual = (q->write & ~0x7);
172 iwl_write_direct32(priv, rx_wrt_ptr_reg, 171 iwl_write_direct32(priv, FH_RSCSR_CHNL0_WPTR,
173 q->write_actual); 172 q->write_actual);
174 } 173 }
175 } 174 }
@@ -179,46 +178,6 @@ void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q
179 spin_unlock_irqrestore(&q->lock, flags); 178 spin_unlock_irqrestore(&q->lock, flags);
180} 179}
181 180
182int iwl_rx_queue_alloc(struct iwl_priv *priv)
183{
184 struct iwl_rx_queue *rxq = &priv->rxq;
185 struct device *dev = priv->bus.dev;
186 int i;
187
188 spin_lock_init(&rxq->lock);
189 INIT_LIST_HEAD(&rxq->rx_free);
190 INIT_LIST_HEAD(&rxq->rx_used);
191
192 /* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */
193 rxq->bd = dma_alloc_coherent(dev, 4 * RX_QUEUE_SIZE, &rxq->bd_dma,
194 GFP_KERNEL);
195 if (!rxq->bd)
196 goto err_bd;
197
198 rxq->rb_stts = dma_alloc_coherent(dev, sizeof(struct iwl_rb_status),
199 &rxq->rb_stts_dma, GFP_KERNEL);
200 if (!rxq->rb_stts)
201 goto err_rb;
202
203 /* Fill the rx_used queue with _all_ of the Rx buffers */
204 for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++)
205 list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
206
207 /* Set us so that we have processed and used all buffers, but have
208 * not restocked the Rx queue with fresh buffers */
209 rxq->read = rxq->write = 0;
210 rxq->write_actual = 0;
211 rxq->free_count = 0;
212 rxq->need_update = 0;
213 return 0;
214
215err_rb:
216 dma_free_coherent(dev, 4 * RX_QUEUE_SIZE, rxq->bd,
217 rxq->bd_dma);
218err_bd:
219 return -ENOMEM;
220}
221
222/****************************************************************************** 181/******************************************************************************
223 * 182 *
224 * Generic RX handler implementations 183 * Generic RX handler implementations
diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.h b/drivers/net/wireless/iwlwifi/iwl-testmode.h
index 160911a3716a..d825188e5215 100644
--- a/drivers/net/wireless/iwlwifi/iwl-testmode.h
+++ b/drivers/net/wireless/iwlwifi/iwl-testmode.h
@@ -66,116 +66,144 @@
66#include <linux/types.h> 66#include <linux/types.h>
67 67
68 68
69/* Commands from user space to kernel space(IWL_TM_CMD_ID_APP2DEV_XX) and 69/*
70 * Commands from user space to kernel space(IWL_TM_CMD_ID_APP2DEV_XX) and
70 * from and kernel space to user space(IWL_TM_CMD_ID_DEV2APP_XX). 71 * from and kernel space to user space(IWL_TM_CMD_ID_DEV2APP_XX).
71 * The command ID is carried with IWL_TM_ATTR_COMMAND. There are three types of 72 * The command ID is carried with IWL_TM_ATTR_COMMAND.
72 * of command from user space and two types of command from kernel space. 73 *
73 * See below. 74 * @IWL_TM_CMD_APP2DEV_UCODE:
75 * commands from user application to the uCode,
76 * the actual uCode host command ID is carried with
77 * IWL_TM_ATTR_UCODE_CMD_ID
78 *
79 * @IWL_TM_CMD_APP2DEV_REG_READ32:
80 * @IWL_TM_CMD_APP2DEV_REG_WRITE32:
81 * @IWL_TM_CMD_APP2DEV_REG_WRITE8:
82 * commands from user applicaiton to access register
83 *
84 * @IWL_TM_CMD_APP2DEV_GET_DEVICENAME: retrieve device name
85 * @IWL_TM_CMD_APP2DEV_LOAD_INIT_FW: load initial uCode image
86 * @IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB: perform calibration
87 * @IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW: load runtime uCode image
88 * @IWL_TM_CMD_APP2DEV_GET_EEPROM: request EEPROM data
89 * @IWL_TM_CMD_APP2DEV_FIXRATE_REQ: set fix MCS
90 * commands fom user space for pure driver level operations
91 *
92 * @IWL_TM_CMD_APP2DEV_BEGIN_TRACE:
93 * @IWL_TM_CMD_APP2DEV_END_TRACE:
94 * @IWL_TM_CMD_APP2DEV_READ_TRACE:
95 * commands fom user space for uCode trace operations
96 *
97 * @IWL_TM_CMD_DEV2APP_SYNC_RSP:
98 * commands from kernel space to carry the synchronous response
99 * to user application
100 * @IWL_TM_CMD_DEV2APP_UCODE_RX_PKT:
101 * commands from kernel space to multicast the spontaneous messages
102 * to user application
103 * @IWL_TM_CMD_DEV2APP_EEPROM_RSP:
104 * commands from kernel space to carry the eeprom response
105 * to user application
74 */ 106 */
75enum iwl_tm_cmd_t { 107enum iwl_tm_cmd_t {
76 /* commands from user application to the uCode, 108 IWL_TM_CMD_APP2DEV_UCODE = 1,
77 * the actual uCode host command ID is carried with 109 IWL_TM_CMD_APP2DEV_REG_READ32 = 2,
78 * IWL_TM_ATTR_UCODE_CMD_ID */ 110 IWL_TM_CMD_APP2DEV_REG_WRITE32 = 3,
79 IWL_TM_CMD_APP2DEV_UCODE = 1, 111 IWL_TM_CMD_APP2DEV_REG_WRITE8 = 4,
80 112 IWL_TM_CMD_APP2DEV_GET_DEVICENAME = 5,
81 /* commands from user applicaiton to access register */ 113 IWL_TM_CMD_APP2DEV_LOAD_INIT_FW = 6,
82 IWL_TM_CMD_APP2DEV_REG_READ32, 114 IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB = 7,
83 IWL_TM_CMD_APP2DEV_REG_WRITE32, 115 IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW = 8,
84 IWL_TM_CMD_APP2DEV_REG_WRITE8, 116 IWL_TM_CMD_APP2DEV_GET_EEPROM = 9,
85 117 IWL_TM_CMD_APP2DEV_FIXRATE_REQ = 10,
86 /* commands fom user space for pure driver level operations */ 118 IWL_TM_CMD_APP2DEV_BEGIN_TRACE = 11,
87 IWL_TM_CMD_APP2DEV_GET_DEVICENAME, 119 IWL_TM_CMD_APP2DEV_END_TRACE = 12,
88 IWL_TM_CMD_APP2DEV_LOAD_INIT_FW, 120 IWL_TM_CMD_APP2DEV_READ_TRACE = 13,
89 IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB, 121 IWL_TM_CMD_DEV2APP_SYNC_RSP = 14,
90 IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW, 122 IWL_TM_CMD_DEV2APP_UCODE_RX_PKT = 15,
91 IWL_TM_CMD_APP2DEV_GET_EEPROM, 123 IWL_TM_CMD_DEV2APP_EEPROM_RSP = 16,
92 IWL_TM_CMD_APP2DEV_FIXRATE_REQ, 124 IWL_TM_CMD_MAX = 17,
93 /* if there is other new command for the driver layer operation,
94 * append them here */
95
96 /* commands fom user space for uCode trace operations */
97 IWL_TM_CMD_APP2DEV_BEGIN_TRACE,
98 IWL_TM_CMD_APP2DEV_END_TRACE,
99 IWL_TM_CMD_APP2DEV_READ_TRACE,
100
101 /* commands from kernel space to carry the synchronous response
102 * to user application */
103 IWL_TM_CMD_DEV2APP_SYNC_RSP,
104
105 /* commands from kernel space to multicast the spontaneous messages
106 * to user application */
107 IWL_TM_CMD_DEV2APP_UCODE_RX_PKT,
108
109 /* commands from kernel space to carry the eeprom response
110 * to user application */
111 IWL_TM_CMD_DEV2APP_EEPROM_RSP,
112
113 IWL_TM_CMD_MAX,
114}; 125};
115 126
127/*
128 * Atrribute filed in testmode command
129 * See enum iwl_tm_cmd_t.
130 *
131 * @IWL_TM_ATTR_NOT_APPLICABLE:
132 * The attribute is not applicable or invalid
133 * @IWL_TM_ATTR_COMMAND:
134 * From user space to kernel space:
135 * the command either destines to ucode, driver, or register;
136 * From kernel space to user space:
137 * the command either carries synchronous response,
138 * or the spontaneous message multicast from the device;
139 *
140 * @IWL_TM_ATTR_UCODE_CMD_ID:
141 * @IWL_TM_ATTR_UCODE_CMD_DATA:
142 * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_UCODE,
143 * The mandatory fields are :
144 * IWL_TM_ATTR_UCODE_CMD_ID for recognizable command ID;
145 * IWL_TM_ATTR_COMMAND_FLAG for the flags of the commands;
146 * The optional fields are:
147 * IWL_TM_ATTR_UCODE_CMD_DATA for the actual command payload
148 * to the ucode
149 *
150 * @IWL_TM_ATTR_REG_OFFSET:
151 * @IWL_TM_ATTR_REG_VALUE8:
152 * @IWL_TM_ATTR_REG_VALUE32:
153 * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_REG_XXX,
154 * The mandatory fields are:
155 * IWL_TM_ATTR_REG_OFFSET for the offset of the target register;
156 * IWL_TM_ATTR_REG_VALUE8 or IWL_TM_ATTR_REG_VALUE32 for value
157 *
158 * @IWL_TM_ATTR_SYNC_RSP:
159 * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_DEV2APP_SYNC_RSP,
160 * The mandatory fields are:
161 * IWL_TM_ATTR_SYNC_RSP for the data content responding to the user
162 * application command
163 *
164 * @IWL_TM_ATTR_UCODE_RX_PKT:
165 * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_DEV2APP_UCODE_RX_PKT,
166 * The mandatory fields are:
167 * IWL_TM_ATTR_UCODE_RX_PKT for the data content multicast to the user
168 * application
169 *
170 * @IWL_TM_ATTR_EEPROM:
171 * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_DEV2APP_EEPROM,
172 * The mandatory fields are:
173 * IWL_TM_ATTR_EEPROM for the data content responging to the user
174 * application
175 *
176 * @IWL_TM_ATTR_TRACE_ADDR:
177 * @IWL_TM_ATTR_TRACE_SIZE:
178 * @IWL_TM_ATTR_TRACE_DUMP:
179 * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_XXX_TRACE,
180 * The mandatory fields are:
181 * IWL_TM_ATTR_MEM_TRACE_ADDR for the trace address
182 * IWL_TM_ATTR_MEM_TRACE_SIZE for the trace buffer size
183 * IWL_TM_ATTR_MEM_TRACE_DUMP for the trace dump
184 *
185 * @IWL_TM_ATTR_FIXRATE:
186 * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_FIXRATE_REQ,
187 * The mandatory fields are:
188 * IWL_TM_ATTR_FIXRATE for the fixed rate
189 *
190 */
116enum iwl_tm_attr_t { 191enum iwl_tm_attr_t {
117 IWL_TM_ATTR_NOT_APPLICABLE = 0, 192 IWL_TM_ATTR_NOT_APPLICABLE = 0,
118 193 IWL_TM_ATTR_COMMAND = 1,
119 /* From user space to kernel space: 194 IWL_TM_ATTR_UCODE_CMD_ID = 2,
120 * the command either destines to ucode, driver, or register; 195 IWL_TM_ATTR_UCODE_CMD_DATA = 3,
121 * See enum iwl_tm_cmd_t. 196 IWL_TM_ATTR_REG_OFFSET = 4,
122 * 197 IWL_TM_ATTR_REG_VALUE8 = 5,
123 * From kernel space to user space: 198 IWL_TM_ATTR_REG_VALUE32 = 6,
124 * the command either carries synchronous response, 199 IWL_TM_ATTR_SYNC_RSP = 7,
125 * or the spontaneous message multicast from the device; 200 IWL_TM_ATTR_UCODE_RX_PKT = 8,
126 * See enum iwl_tm_cmd_t. */ 201 IWL_TM_ATTR_EEPROM = 9,
127 IWL_TM_ATTR_COMMAND, 202 IWL_TM_ATTR_TRACE_ADDR = 10,
128 203 IWL_TM_ATTR_TRACE_SIZE = 11,
129 /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_UCODE, 204 IWL_TM_ATTR_TRACE_DUMP = 12,
130 * The mandatory fields are : 205 IWL_TM_ATTR_FIXRATE = 13,
131 * IWL_TM_ATTR_UCODE_CMD_ID for recognizable command ID; 206 IWL_TM_ATTR_MAX = 14,
132 * IWL_TM_ATTR_COMMAND_FLAG for the flags of the commands;
133 * The optional fields are:
134 * IWL_TM_ATTR_UCODE_CMD_DATA for the actual command payload
135 * to the ucode */
136 IWL_TM_ATTR_UCODE_CMD_ID,
137 IWL_TM_ATTR_UCODE_CMD_DATA,
138
139 /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_REG_XXX,
140 * The mandatory fields are:
141 * IWL_TM_ATTR_REG_OFFSET for the offset of the target register;
142 * IWL_TM_ATTR_REG_VALUE8 or IWL_TM_ATTR_REG_VALUE32 for value */
143 IWL_TM_ATTR_REG_OFFSET,
144 IWL_TM_ATTR_REG_VALUE8,
145 IWL_TM_ATTR_REG_VALUE32,
146
147 /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_DEV2APP_SYNC_RSP,
148 * The mandatory fields are:
149 * IWL_TM_ATTR_SYNC_RSP for the data content responding to the user
150 * application command */
151 IWL_TM_ATTR_SYNC_RSP,
152 /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_DEV2APP_UCODE_RX_PKT,
153 * The mandatory fields are:
154 * IWL_TM_ATTR_UCODE_RX_PKT for the data content multicast to the user
155 * application */
156 IWL_TM_ATTR_UCODE_RX_PKT,
157
158 /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_DEV2APP_EEPROM,
159 * The mandatory fields are:
160 * IWL_TM_ATTR_EEPROM for the data content responging to the user
161 * application */
162 IWL_TM_ATTR_EEPROM,
163
164 /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_XXX_TRACE,
165 * The mandatory fields are:
166 * IWL_TM_ATTR_MEM_TRACE_ADDR for the trace address
167 */
168 IWL_TM_ATTR_TRACE_ADDR,
169 IWL_TM_ATTR_TRACE_SIZE,
170 IWL_TM_ATTR_TRACE_DUMP,
171
172 /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_FIXRATE_REQ,
173 * The mandatory fields are:
174 * IWL_TM_ATTR_FIXRATE for the fixed rate
175 */
176 IWL_TM_ATTR_FIXRATE,
177
178 IWL_TM_ATTR_MAX,
179}; 207};
180 208
181/* uCode trace buffer */ 209/* uCode trace buffer */
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c
new file mode 100644
index 000000000000..7b7b97d8c2e1
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.c
@@ -0,0 +1,423 @@
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 - 2011 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 - 2011 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#include "iwl-dev.h"
64#include "iwl-trans.h"
65#include "iwl-core.h"
66#include "iwl-helpers.h"
67/*TODO remove uneeded includes when the transport layer tx_free will be here */
68#include "iwl-agn.h"
69
70static int iwl_trans_rx_alloc(struct iwl_priv *priv)
71{
72 struct iwl_rx_queue *rxq = &priv->rxq;
73 struct device *dev = priv->bus.dev;
74
75 memset(&priv->rxq, 0, sizeof(priv->rxq));
76
77 spin_lock_init(&rxq->lock);
78 INIT_LIST_HEAD(&rxq->rx_free);
79 INIT_LIST_HEAD(&rxq->rx_used);
80
81 if (WARN_ON(rxq->bd || rxq->rb_stts))
82 return -EINVAL;
83
84 /* Allocate the circular buffer of Read Buffer Descriptors (RBDs) */
85 rxq->bd = dma_alloc_coherent(dev, sizeof(__le32) * RX_QUEUE_SIZE,
86 &rxq->bd_dma, GFP_KERNEL);
87 if (!rxq->bd)
88 goto err_bd;
89 memset(rxq->bd, 0, sizeof(__le32) * RX_QUEUE_SIZE);
90
91 /*Allocate the driver's pointer to receive buffer status */
92 rxq->rb_stts = dma_alloc_coherent(dev, sizeof(*rxq->rb_stts),
93 &rxq->rb_stts_dma, GFP_KERNEL);
94 if (!rxq->rb_stts)
95 goto err_rb_stts;
96 memset(rxq->rb_stts, 0, sizeof(*rxq->rb_stts));
97
98 return 0;
99
100err_rb_stts:
101 dma_free_coherent(dev, sizeof(__le32) * RX_QUEUE_SIZE,
102 rxq->bd, rxq->bd_dma);
103 memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma));
104 rxq->bd = NULL;
105err_bd:
106 return -ENOMEM;
107}
108
109static void iwl_trans_rxq_free_rx_bufs(struct iwl_priv *priv)
110{
111 struct iwl_rx_queue *rxq = &priv->rxq;
112 int i;
113
114 /* Fill the rx_used queue with _all_ of the Rx buffers */
115 for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) {
116 /* In the reset function, these buffers may have been allocated
117 * to an SKB, so we need to unmap and free potential storage */
118 if (rxq->pool[i].page != NULL) {
119 dma_unmap_page(priv->bus.dev, rxq->pool[i].page_dma,
120 PAGE_SIZE << priv->hw_params.rx_page_order,
121 DMA_FROM_DEVICE);
122 __iwl_free_pages(priv, rxq->pool[i].page);
123 rxq->pool[i].page = NULL;
124 }
125 list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
126 }
127}
128
129static int iwl_trans_rx_init(struct iwl_priv *priv)
130{
131 struct iwl_rx_queue *rxq = &priv->rxq;
132 int i, err;
133 unsigned long flags;
134
135 if (!rxq->bd) {
136 err = iwl_trans_rx_alloc(priv);
137 if (err)
138 return err;
139 }
140
141 spin_lock_irqsave(&rxq->lock, flags);
142 INIT_LIST_HEAD(&rxq->rx_free);
143 INIT_LIST_HEAD(&rxq->rx_used);
144
145 iwl_trans_rxq_free_rx_bufs(priv);
146
147 for (i = 0; i < RX_QUEUE_SIZE; i++)
148 rxq->queue[i] = NULL;
149
150 /* Set us so that we have processed and used all buffers, but have
151 * not restocked the Rx queue with fresh buffers */
152 rxq->read = rxq->write = 0;
153 rxq->write_actual = 0;
154 rxq->free_count = 0;
155 spin_unlock_irqrestore(&rxq->lock, flags);
156
157 return 0;
158}
159
160static void iwl_trans_rx_free(struct iwl_priv *priv)
161{
162 struct iwl_rx_queue *rxq = &priv->rxq;
163 unsigned long flags;
164
165 /*if rxq->bd is NULL, it means that nothing has been allocated,
166 * exit now */
167 if (!rxq->bd) {
168 IWL_DEBUG_INFO(priv, "Free NULL rx context\n");
169 return;
170 }
171
172 spin_lock_irqsave(&rxq->lock, flags);
173 iwl_trans_rxq_free_rx_bufs(priv);
174 spin_unlock_irqrestore(&rxq->lock, flags);
175
176 dma_free_coherent(priv->bus.dev, sizeof(__le32) * RX_QUEUE_SIZE,
177 rxq->bd, rxq->bd_dma);
178 memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma));
179 rxq->bd = NULL;
180
181 if (rxq->rb_stts)
182 dma_free_coherent(priv->bus.dev,
183 sizeof(struct iwl_rb_status),
184 rxq->rb_stts, rxq->rb_stts_dma);
185 else
186 IWL_DEBUG_INFO(priv, "Free rxq->rb_stts which is NULL\n");
187 memset(&rxq->rb_stts_dma, 0, sizeof(rxq->rb_stts_dma));
188 rxq->rb_stts = NULL;
189}
190
191/* TODO:remove this code duplication */
192static inline int iwlagn_alloc_dma_ptr(struct iwl_priv *priv,
193 struct iwl_dma_ptr *ptr, size_t size)
194{
195 if (WARN_ON(ptr->addr))
196 return -EINVAL;
197
198 ptr->addr = dma_alloc_coherent(priv->bus.dev, size,
199 &ptr->dma, GFP_KERNEL);
200 if (!ptr->addr)
201 return -ENOMEM;
202 ptr->size = size;
203 return 0;
204}
205
206static int iwl_trans_txq_alloc(struct iwl_priv *priv, struct iwl_tx_queue *txq,
207 int slots_num, u32 txq_id)
208{
209 size_t tfd_sz = priv->hw_params.tfd_size * TFD_QUEUE_SIZE_MAX;
210 int i;
211
212 if (WARN_ON(txq->meta || txq->cmd || txq->txb || txq->tfds))
213 return -EINVAL;
214
215 txq->meta = kzalloc(sizeof(txq->meta[0]) * slots_num,
216 GFP_KERNEL);
217 txq->cmd = kzalloc(sizeof(txq->cmd[0]) * slots_num,
218 GFP_KERNEL);
219
220 if (!txq->meta || !txq->cmd)
221 goto error;
222
223 for (i = 0; i < slots_num; i++) {
224 txq->cmd[i] = kmalloc(sizeof(struct iwl_device_cmd),
225 GFP_KERNEL);
226 if (!txq->cmd[i])
227 goto error;
228 }
229
230 /* Alloc driver data array and TFD circular buffer */
231 /* Driver private data, only for Tx (not command) queues,
232 * not shared with device. */
233 if (txq_id != priv->cmd_queue) {
234 txq->txb = kzalloc(sizeof(txq->txb[0]) *
235 TFD_QUEUE_SIZE_MAX, GFP_KERNEL);
236 if (!txq->txb) {
237 IWL_ERR(priv, "kmalloc for auxiliary BD "
238 "structures failed\n");
239 goto error;
240 }
241 } else {
242 txq->txb = NULL;
243 }
244
245 /* Circular buffer of transmit frame descriptors (TFDs),
246 * shared with device */
247 txq->tfds = dma_alloc_coherent(priv->bus.dev, tfd_sz, &txq->q.dma_addr,
248 GFP_KERNEL);
249 if (!txq->tfds) {
250 IWL_ERR(priv, "dma_alloc_coherent(%zd) failed\n", tfd_sz);
251 goto error;
252 }
253 txq->q.id = txq_id;
254
255 return 0;
256error:
257 kfree(txq->txb);
258 txq->txb = NULL;
259 /* since txq->cmd has been zeroed,
260 * all non allocated cmd[i] will be NULL */
261 if (txq->cmd)
262 for (i = 0; i < slots_num; i++)
263 kfree(txq->cmd[i]);
264 kfree(txq->meta);
265 kfree(txq->cmd);
266 txq->meta = NULL;
267 txq->cmd = NULL;
268
269 return -ENOMEM;
270
271}
272
273static int iwl_trans_txq_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
274 int slots_num, u32 txq_id)
275{
276 int ret;
277
278 txq->need_update = 0;
279 memset(txq->meta, 0, sizeof(txq->meta[0]) * slots_num);
280
281 /*
282 * For the default queues 0-3, set up the swq_id
283 * already -- all others need to get one later
284 * (if they need one at all).
285 */
286 if (txq_id < 4)
287 iwl_set_swq_id(txq, txq_id, txq_id);
288
289 /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise
290 * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */
291 BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1));
292
293 /* Initialize queue's high/low-water marks, and head/tail indexes */
294 ret = iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num,
295 txq_id);
296 if (ret)
297 return ret;
298
299 /*
300 * Tell nic where to find circular buffer of Tx Frame Descriptors for
301 * given Tx queue, and enable the DMA channel used for that queue.
302 * Circular buffer (TFD queue in DRAM) physical base address */
303 iwl_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id),
304 txq->q.dma_addr >> 8);
305
306 return 0;
307}
308
309/**
310 * iwl_trans_tx_alloc - allocate TX context
311 * Allocate all Tx DMA structures and initialize them
312 *
313 * @param priv
314 * @return error code
315 */
316static int iwl_trans_tx_alloc(struct iwl_priv *priv)
317{
318 int ret;
319 int txq_id, slots_num;
320
321 /*It is not allowed to alloc twice, so warn when this happens.
322 * We cannot rely on the previous allocation, so free and fail */
323 if (WARN_ON(priv->txq)) {
324 ret = -EINVAL;
325 goto error;
326 }
327
328 ret = iwlagn_alloc_dma_ptr(priv, &priv->scd_bc_tbls,
329 priv->hw_params.scd_bc_tbls_size);
330 if (ret) {
331 IWL_ERR(priv, "Scheduler BC Table allocation failed\n");
332 goto error;
333 }
334
335 /* Alloc keep-warm buffer */
336 ret = iwlagn_alloc_dma_ptr(priv, &priv->kw, IWL_KW_SIZE);
337 if (ret) {
338 IWL_ERR(priv, "Keep Warm allocation failed\n");
339 goto error;
340 }
341
342 priv->txq = kzalloc(sizeof(struct iwl_tx_queue) *
343 priv->cfg->base_params->num_of_queues, GFP_KERNEL);
344 if (!priv->txq) {
345 IWL_ERR(priv, "Not enough memory for txq\n");
346 ret = ENOMEM;
347 goto error;
348 }
349
350 /* Alloc and init all Tx queues, including the command queue (#4/#9) */
351 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
352 slots_num = (txq_id == priv->cmd_queue) ?
353 TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
354 ret = iwl_trans_txq_alloc(priv, &priv->txq[txq_id], slots_num,
355 txq_id);
356 if (ret) {
357 IWL_ERR(priv, "Tx %d queue alloc failed\n", txq_id);
358 goto error;
359 }
360 }
361
362 return 0;
363
364error:
365 iwlagn_hw_txq_ctx_free(priv);
366
367 return ret;
368}
369static int iwl_trans_tx_init(struct iwl_priv *priv)
370{
371 int ret;
372 int txq_id, slots_num;
373 unsigned long flags;
374 bool alloc = false;
375
376 if (!priv->txq) {
377 ret = iwl_trans_tx_alloc(priv);
378 if (ret)
379 goto error;
380 alloc = true;
381 }
382
383 spin_lock_irqsave(&priv->lock, flags);
384
385 /* Turn off all Tx DMA fifos */
386 iwl_write_prph(priv, IWLAGN_SCD_TXFACT, 0);
387
388 /* Tell NIC where to find the "keep warm" buffer */
389 iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4);
390
391 spin_unlock_irqrestore(&priv->lock, flags);
392
393 /* Alloc and init all Tx queues, including the command queue (#4/#9) */
394 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
395 slots_num = (txq_id == priv->cmd_queue) ?
396 TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
397 ret = iwl_trans_txq_init(priv, &priv->txq[txq_id], slots_num,
398 txq_id);
399 if (ret) {
400 IWL_ERR(priv, "Tx %d queue init failed\n", txq_id);
401 goto error;
402 }
403 }
404
405 return 0;
406error:
407 /*Upon error, free only if we allocated something */
408 if (alloc)
409 iwlagn_hw_txq_ctx_free(priv);
410 return ret;
411}
412
413static const struct iwl_trans_ops trans_ops = {
414 .rx_init = iwl_trans_rx_init,
415 .rx_free = iwl_trans_rx_free,
416
417 .tx_init = iwl_trans_tx_init,
418};
419
420void iwl_trans_register(struct iwl_trans *trans)
421{
422 trans->ops = &trans_ops;
423}
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
new file mode 100644
index 000000000000..bec494c5a979
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -0,0 +1,64 @@
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 - 2011 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 - 2011 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
64void iwl_trans_register(struct iwl_trans *trans);
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index e72d2279fc5d..db5abaa2ff7e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -220,24 +220,6 @@ int iwlagn_txq_attach_buf_to_tfd(struct iwl_priv *priv,
220 return 0; 220 return 0;
221} 221}
222 222
223/*
224 * Tell nic where to find circular buffer of Tx Frame Descriptors for
225 * given Tx queue, and enable the DMA channel used for that queue.
226 *
227 * supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA
228 * channels supported in hardware.
229 */
230static int iwlagn_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq)
231{
232 int txq_id = txq->q.id;
233
234 /* Circular buffer (TFD queue in DRAM) physical base address */
235 iwl_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id),
236 txq->q.dma_addr >> 8);
237
238 return 0;
239}
240
241/** 223/**
242 * iwl_tx_queue_unmap - Unmap any remaining DMA mappings and free skb's 224 * iwl_tx_queue_unmap - Unmap any remaining DMA mappings and free skb's
243 */ 225 */
@@ -392,11 +374,10 @@ int iwl_queue_space(const struct iwl_queue *q)
392 return s; 374 return s;
393} 375}
394 376
395
396/** 377/**
397 * iwl_queue_init - Initialize queue's high/low-water and read/write indexes 378 * iwl_queue_init - Initialize queue's high/low-water and read/write indexes
398 */ 379 */
399static int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q, 380int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q,
400 int count, int slots_num, u32 id) 381 int count, int slots_num, u32 id)
401{ 382{
402 q->n_bd = count; 383 q->n_bd = count;
@@ -426,124 +407,6 @@ static int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q,
426 return 0; 407 return 0;
427} 408}
428 409
429/**
430 * iwl_tx_queue_alloc - Alloc driver data and TFD CB for one Tx/cmd queue
431 */
432static int iwl_tx_queue_alloc(struct iwl_priv *priv,
433 struct iwl_tx_queue *txq, u32 id)
434{
435 struct device *dev = priv->bus.dev;
436 size_t tfd_sz = priv->hw_params.tfd_size * TFD_QUEUE_SIZE_MAX;
437
438 /* Driver private data, only for Tx (not command) queues,
439 * not shared with device. */
440 if (id != priv->cmd_queue) {
441 txq->txb = kzalloc(sizeof(txq->txb[0]) *
442 TFD_QUEUE_SIZE_MAX, GFP_KERNEL);
443 if (!txq->txb) {
444 IWL_ERR(priv, "kmalloc for auxiliary BD "
445 "structures failed\n");
446 goto error;
447 }
448 } else {
449 txq->txb = NULL;
450 }
451
452 /* Circular buffer of transmit frame descriptors (TFDs),
453 * shared with device */
454 txq->tfds = dma_alloc_coherent(dev, tfd_sz, &txq->q.dma_addr,
455 GFP_KERNEL);
456 if (!txq->tfds) {
457 IWL_ERR(priv, "dma_alloc_coherent(%zd) failed\n", tfd_sz);
458 goto error;
459 }
460 txq->q.id = id;
461
462 return 0;
463
464 error:
465 kfree(txq->txb);
466 txq->txb = NULL;
467
468 return -ENOMEM;
469}
470
471/**
472 * iwl_tx_queue_init - Allocate and initialize one tx/cmd queue
473 */
474int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
475 int slots_num, u32 txq_id)
476{
477 int i, len;
478 int ret;
479
480 txq->meta = kzalloc(sizeof(struct iwl_cmd_meta) * slots_num,
481 GFP_KERNEL);
482 txq->cmd = kzalloc(sizeof(struct iwl_device_cmd *) * slots_num,
483 GFP_KERNEL);
484
485 if (!txq->meta || !txq->cmd)
486 goto out_free_arrays;
487
488 len = sizeof(struct iwl_device_cmd);
489 for (i = 0; i < slots_num; i++) {
490 txq->cmd[i] = kmalloc(len, GFP_KERNEL);
491 if (!txq->cmd[i])
492 goto err;
493 }
494
495 /* Alloc driver data array and TFD circular buffer */
496 ret = iwl_tx_queue_alloc(priv, txq, txq_id);
497 if (ret)
498 goto err;
499
500 txq->need_update = 0;
501
502 /*
503 * For the default queues 0-3, set up the swq_id
504 * already -- all others need to get one later
505 * (if they need one at all).
506 */
507 if (txq_id < 4)
508 iwl_set_swq_id(txq, txq_id, txq_id);
509
510 /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise
511 * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */
512 BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1));
513
514 /* Initialize queue's high/low-water marks, and head/tail indexes */
515 ret = iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
516 if (ret)
517 return ret;
518
519 /* Tell device where to find queue */
520 iwlagn_tx_queue_init(priv, txq);
521
522 return 0;
523err:
524 for (i = 0; i < slots_num; i++)
525 kfree(txq->cmd[i]);
526out_free_arrays:
527 kfree(txq->meta);
528 kfree(txq->cmd);
529
530 return -ENOMEM;
531}
532
533void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq,
534 int slots_num, u32 txq_id)
535{
536 memset(txq->meta, 0, sizeof(struct iwl_cmd_meta) * slots_num);
537
538 txq->need_update = 0;
539
540 /* Initialize queue's high/low-water marks, and head/tail indexes */
541 iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
542
543 /* Tell device where to find queue */
544 iwlagn_tx_queue_init(priv, txq);
545}
546
547/*************** HOST COMMAND QUEUE FUNCTIONS *****/ 410/*************** HOST COMMAND QUEUE FUNCTIONS *****/
548 411
549/** 412/**