aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-5000.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-5000.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c548
1 files changed, 277 insertions, 271 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 6e6f516ba404..e476acb53aa7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 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 6 * under the terms of version 2 of the GNU General Public License as
@@ -43,6 +43,7 @@
43#include "iwl-io.h" 43#include "iwl-io.h"
44#include "iwl-sta.h" 44#include "iwl-sta.h"
45#include "iwl-helpers.h" 45#include "iwl-helpers.h"
46#include "iwl-agn-led.h"
46#include "iwl-5000-hw.h" 47#include "iwl-5000-hw.h"
47#include "iwl-6000-hw.h" 48#include "iwl-6000-hw.h"
48 49
@@ -72,157 +73,18 @@ static const u16 iwl5000_default_queue_to_tx_fifo[] = {
72 IWL_TX_FIFO_HCCA_2 73 IWL_TX_FIFO_HCCA_2
73}; 74};
74 75
75/* FIXME: same implementation as 4965 */ 76/* NIC configuration for 5000 series */
76static int iwl5000_apm_stop_master(struct iwl_priv *priv)
77{
78 unsigned long flags;
79
80 spin_lock_irqsave(&priv->lock, flags);
81
82 /* set stop master bit */
83 iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
84
85 iwl_poll_direct_bit(priv, CSR_RESET,
86 CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
87
88 spin_unlock_irqrestore(&priv->lock, flags);
89 IWL_DEBUG_INFO(priv, "stop master\n");
90
91 return 0;
92}
93
94
95int iwl5000_apm_init(struct iwl_priv *priv)
96{
97 int ret = 0;
98
99 iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
100 CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
101
102 /* disable L0s without affecting L1 :don't wait for ICH L0s bug W/A) */
103 iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
104 CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
105
106 /* Set FH wait threshold to maximum (HW error during stress W/A) */
107 iwl_set_bit(priv, CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL);
108
109 /* enable HAP INTA to move device L1a -> L0s */
110 iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
111 CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
112
113 if (priv->cfg->need_pll_cfg)
114 iwl_set_bit(priv, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL);
115
116 /* set "initialization complete" bit to move adapter
117 * D0U* --> D0A* state */
118 iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
119
120 /* wait for clock stabilization */
121 ret = iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
122 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
123 if (ret < 0) {
124 IWL_DEBUG_INFO(priv, "Failed to init the card\n");
125 return ret;
126 }
127
128 /* enable DMA */
129 iwl_write_prph(priv, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT);
130
131 udelay(20);
132
133 /* disable L1-Active */
134 iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
135 APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
136
137 return ret;
138}
139
140/* FIXME: this is identical to 4965 */
141void iwl5000_apm_stop(struct iwl_priv *priv)
142{
143 unsigned long flags;
144
145 iwl5000_apm_stop_master(priv);
146
147 spin_lock_irqsave(&priv->lock, flags);
148
149 iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
150
151 udelay(10);
152
153 /* clear "init complete" move adapter D0A* --> D0U state */
154 iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
155
156 spin_unlock_irqrestore(&priv->lock, flags);
157}
158
159
160int iwl5000_apm_reset(struct iwl_priv *priv)
161{
162 int ret = 0;
163
164 iwl5000_apm_stop_master(priv);
165
166 iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
167
168 udelay(10);
169
170
171 /* FIXME: put here L1A -L0S w/a */
172
173 if (priv->cfg->need_pll_cfg)
174 iwl_set_bit(priv, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL);
175
176 /* set "initialization complete" bit to move adapter
177 * D0U* --> D0A* state */
178 iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
179
180 /* wait for clock stabilization */
181 ret = iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
182 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
183 if (ret < 0) {
184 IWL_DEBUG_INFO(priv, "Failed to init the card\n");
185 goto out;
186 }
187
188 /* enable DMA */
189 iwl_write_prph(priv, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT);
190
191 udelay(20);
192
193 /* disable L1-Active */
194 iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
195 APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
196out:
197
198 return ret;
199}
200
201
202/* NIC configuration for 5000 series and up */
203void iwl5000_nic_config(struct iwl_priv *priv) 77void iwl5000_nic_config(struct iwl_priv *priv)
204{ 78{
205 unsigned long flags; 79 unsigned long flags;
206 u16 radio_cfg; 80 u16 radio_cfg;
207 u16 lctl;
208 81
209 spin_lock_irqsave(&priv->lock, flags); 82 spin_lock_irqsave(&priv->lock, flags);
210 83
211 lctl = iwl_pcie_link_ctl(priv);
212
213 /* HW bug W/A */
214 /* L1-ASPM is enabled by BIOS */
215 if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN)
216 /* L1-APSM enabled: disable L0S */
217 iwl_set_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
218 else
219 /* L1-ASPM disabled: enable L0S */
220 iwl_clear_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
221
222 radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG); 84 radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG);
223 85
224 /* write radio config values to register */ 86 /* write radio config values to register */
225 if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) < EEPROM_5000_RF_CFG_TYPE_MAX) 87 if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) < EEPROM_RF_CONFIG_TYPE_MAX)
226 iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, 88 iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
227 EEPROM_RF_CFG_TYPE_MSK(radio_cfg) | 89 EEPROM_RF_CFG_TYPE_MSK(radio_cfg) |
228 EEPROM_RF_CFG_STEP_MSK(radio_cfg) | 90 EEPROM_RF_CFG_STEP_MSK(radio_cfg) |
@@ -302,26 +164,39 @@ u16 iwl5000_eeprom_calib_version(struct iwl_priv *priv)
302static void iwl5000_gain_computation(struct iwl_priv *priv, 164static void iwl5000_gain_computation(struct iwl_priv *priv,
303 u32 average_noise[NUM_RX_CHAINS], 165 u32 average_noise[NUM_RX_CHAINS],
304 u16 min_average_noise_antenna_i, 166 u16 min_average_noise_antenna_i,
305 u32 min_average_noise) 167 u32 min_average_noise,
168 u8 default_chain)
306{ 169{
307 int i; 170 int i;
308 s32 delta_g; 171 s32 delta_g;
309 struct iwl_chain_noise_data *data = &priv->chain_noise_data; 172 struct iwl_chain_noise_data *data = &priv->chain_noise_data;
310 173
311 /* Find Gain Code for the antennas B and C */ 174 /*
312 for (i = 1; i < NUM_RX_CHAINS; i++) { 175 * Find Gain Code for the chains based on "default chain"
176 */
177 for (i = default_chain + 1; i < NUM_RX_CHAINS; i++) {
313 if ((data->disconn_array[i])) { 178 if ((data->disconn_array[i])) {
314 data->delta_gain_code[i] = 0; 179 data->delta_gain_code[i] = 0;
315 continue; 180 continue;
316 } 181 }
317 delta_g = (1000 * ((s32)average_noise[0] - 182
183 delta_g = (priv->cfg->chain_noise_scale *
184 ((s32)average_noise[default_chain] -
318 (s32)average_noise[i])) / 1500; 185 (s32)average_noise[i])) / 1500;
186
319 /* bound gain by 2 bits value max, 3rd bit is sign */ 187 /* bound gain by 2 bits value max, 3rd bit is sign */
320 data->delta_gain_code[i] = 188 data->delta_gain_code[i] =
321 min(abs(delta_g), (long) CHAIN_NOISE_MAX_DELTA_GAIN_CODE); 189 min(abs(delta_g), (long) CHAIN_NOISE_MAX_DELTA_GAIN_CODE);
322 190
323 if (delta_g < 0) 191 if (delta_g < 0)
324 /* set negative sign */ 192 /*
193 * set negative sign ...
194 * note to Intel developers: This is uCode API format,
195 * not the format of any internal device registers.
196 * Do not change this format for e.g. 6050 or similar
197 * devices. Change format only if more resolution
198 * (i.e. more than 2 bits magnitude) is needed.
199 */
325 data->delta_gain_code[i] |= (1 << 2); 200 data->delta_gain_code[i] |= (1 << 2);
326 } 201 }
327 202
@@ -398,8 +273,8 @@ static struct iwl_sensitivity_ranges iwl5000_sensitivity = {
398 273
399 .auto_corr_max_ofdm = 120, 274 .auto_corr_max_ofdm = 120,
400 .auto_corr_max_ofdm_mrc = 210, 275 .auto_corr_max_ofdm_mrc = 210,
401 .auto_corr_max_ofdm_x1 = 155, 276 .auto_corr_max_ofdm_x1 = 120,
402 .auto_corr_max_ofdm_mrc_x1 = 290, 277 .auto_corr_max_ofdm_mrc_x1 = 240,
403 278
404 .auto_corr_min_cck = 125, 279 .auto_corr_min_cck = 125,
405 .auto_corr_max_cck = 200, 280 .auto_corr_max_cck = 200,
@@ -407,6 +282,10 @@ static struct iwl_sensitivity_ranges iwl5000_sensitivity = {
407 .auto_corr_max_cck_mrc = 400, 282 .auto_corr_max_cck_mrc = 400,
408 .nrg_th_cck = 95, 283 .nrg_th_cck = 95,
409 .nrg_th_ofdm = 95, 284 .nrg_th_ofdm = 95,
285
286 .barker_corr_th_min = 190,
287 .barker_corr_th_min_mrc = 390,
288 .nrg_th_cca = 62,
410}; 289};
411 290
412static struct iwl_sensitivity_ranges iwl5150_sensitivity = { 291static struct iwl_sensitivity_ranges iwl5150_sensitivity = {
@@ -429,6 +308,10 @@ static struct iwl_sensitivity_ranges iwl5150_sensitivity = {
429 .auto_corr_max_cck_mrc = 400, 308 .auto_corr_max_cck_mrc = 400,
430 .nrg_th_cck = 95, 309 .nrg_th_cck = 95,
431 .nrg_th_ofdm = 95, 310 .nrg_th_ofdm = 95,
311
312 .barker_corr_th_min = 190,
313 .barker_corr_th_min_mrc = 390,
314 .nrg_th_cca = 62,
432}; 315};
433 316
434const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv, 317const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv,
@@ -460,14 +343,15 @@ static void iwl5000_set_ct_threshold(struct iwl_priv *priv)
460static int iwl5000_set_Xtal_calib(struct iwl_priv *priv) 343static int iwl5000_set_Xtal_calib(struct iwl_priv *priv)
461{ 344{
462 struct iwl_calib_xtal_freq_cmd cmd; 345 struct iwl_calib_xtal_freq_cmd cmd;
463 u16 *xtal_calib = (u16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_XTAL); 346 __le16 *xtal_calib =
347 (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_XTAL);
464 348
465 cmd.hdr.op_code = IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD; 349 cmd.hdr.op_code = IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD;
466 cmd.hdr.first_group = 0; 350 cmd.hdr.first_group = 0;
467 cmd.hdr.groups_num = 1; 351 cmd.hdr.groups_num = 1;
468 cmd.hdr.data_valid = 1; 352 cmd.hdr.data_valid = 1;
469 cmd.cap_pin1 = (u8)xtal_calib[0]; 353 cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]);
470 cmd.cap_pin2 = (u8)xtal_calib[1]; 354 cmd.cap_pin2 = le16_to_cpu(xtal_calib[1]);
471 return iwl_calib_set(&priv->calib_results[IWL_CALIB_XTAL], 355 return iwl_calib_set(&priv->calib_results[IWL_CALIB_XTAL],
472 (u8 *)&cmd, sizeof(cmd)); 356 (u8 *)&cmd, sizeof(cmd));
473} 357}
@@ -493,7 +377,7 @@ static int iwl5000_send_calib_cfg(struct iwl_priv *priv)
493static void iwl5000_rx_calib_result(struct iwl_priv *priv, 377static void iwl5000_rx_calib_result(struct iwl_priv *priv,
494 struct iwl_rx_mem_buffer *rxb) 378 struct iwl_rx_mem_buffer *rxb)
495{ 379{
496 struct iwl_rx_packet *pkt = (void *)rxb->skb->data; 380 struct iwl_rx_packet *pkt = rxb_addr(rxb);
497 struct iwl_calib_hdr *hdr = (struct iwl_calib_hdr *)pkt->u.raw; 381 struct iwl_calib_hdr *hdr = (struct iwl_calib_hdr *)pkt->u.raw;
498 int len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; 382 int len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
499 int index; 383 int index;
@@ -538,12 +422,14 @@ static void iwl5000_rx_calib_complete(struct iwl_priv *priv,
538/* 422/*
539 * ucode 423 * ucode
540 */ 424 */
541static int iwl5000_load_section(struct iwl_priv *priv, 425static int iwl5000_load_section(struct iwl_priv *priv, const char *name,
542 struct fw_desc *image, 426 struct fw_desc *image, u32 dst_addr)
543 u32 dst_addr)
544{ 427{
545 dma_addr_t phy_addr = image->p_addr; 428 dma_addr_t phy_addr = image->p_addr;
546 u32 byte_cnt = image->len; 429 u32 byte_cnt = image->len;
430 int ret;
431
432 priv->ucode_write_complete = 0;
547 433
548 iwl_write_direct32(priv, 434 iwl_write_direct32(priv,
549 FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), 435 FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL),
@@ -573,57 +459,36 @@ static int iwl5000_load_section(struct iwl_priv *priv,
573 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE | 459 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE |
574 FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); 460 FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD);
575 461
576 return 0; 462 IWL_DEBUG_INFO(priv, "%s uCode section being loaded...\n", name);
577}
578
579static int iwl5000_load_given_ucode(struct iwl_priv *priv,
580 struct fw_desc *inst_image,
581 struct fw_desc *data_image)
582{
583 int ret = 0;
584
585 ret = iwl5000_load_section(priv, inst_image,
586 IWL50_RTC_INST_LOWER_BOUND);
587 if (ret)
588 return ret;
589
590 IWL_DEBUG_INFO(priv, "INST uCode section being loaded...\n");
591 ret = wait_event_interruptible_timeout(priv->wait_command_queue, 463 ret = wait_event_interruptible_timeout(priv->wait_command_queue,
592 priv->ucode_write_complete, 5 * HZ); 464 priv->ucode_write_complete, 5 * HZ);
593 if (ret == -ERESTARTSYS) { 465 if (ret == -ERESTARTSYS) {
594 IWL_ERR(priv, "Could not load the INST uCode section due " 466 IWL_ERR(priv, "Could not load the %s uCode section due "
595 "to interrupt\n"); 467 "to interrupt\n", name);
596 return ret; 468 return ret;
597 } 469 }
598 if (!ret) { 470 if (!ret) {
599 IWL_ERR(priv, "Could not load the INST uCode section\n"); 471 IWL_ERR(priv, "Could not load the %s uCode section\n",
472 name);
600 return -ETIMEDOUT; 473 return -ETIMEDOUT;
601 } 474 }
602 475
603 priv->ucode_write_complete = 0; 476 return 0;
604 477}
605 ret = iwl5000_load_section(
606 priv, data_image, IWL50_RTC_DATA_LOWER_BOUND);
607 if (ret)
608 return ret;
609 478
610 IWL_DEBUG_INFO(priv, "DATA uCode section being loaded...\n"); 479static int iwl5000_load_given_ucode(struct iwl_priv *priv,
480 struct fw_desc *inst_image,
481 struct fw_desc *data_image)
482{
483 int ret = 0;
611 484
612 ret = wait_event_interruptible_timeout(priv->wait_command_queue, 485 ret = iwl5000_load_section(priv, "INST", inst_image,
613 priv->ucode_write_complete, 5 * HZ); 486 IWL50_RTC_INST_LOWER_BOUND);
614 if (ret == -ERESTARTSYS) { 487 if (ret)
615 IWL_ERR(priv, "Could not load the INST uCode section due "
616 "to interrupt\n");
617 return ret; 488 return ret;
618 } else if (!ret) {
619 IWL_ERR(priv, "Could not load the DATA uCode section\n");
620 return -ETIMEDOUT;
621 } else
622 ret = 0;
623
624 priv->ucode_write_complete = 0;
625 489
626 return ret; 490 return iwl5000_load_section(priv, "DATA", data_image,
491 IWL50_RTC_DATA_LOWER_BOUND);
627} 492}
628 493
629int iwl5000_load_ucode(struct iwl_priv *priv) 494int iwl5000_load_ucode(struct iwl_priv *priv)
@@ -719,16 +584,6 @@ static void iwl5000_tx_queue_set_status(struct iwl_priv *priv,
719 scd_retry ? "BA" : "AC", txq_id, tx_fifo_id); 584 scd_retry ? "BA" : "AC", txq_id, tx_fifo_id);
720} 585}
721 586
722static int iwl5000_send_wimax_coex(struct iwl_priv *priv)
723{
724 struct iwl_wimax_coex_cmd coex_cmd;
725
726 memset(&coex_cmd, 0, sizeof(coex_cmd));
727
728 return iwl_send_cmd_pdu(priv, COEX_PRIORITY_TABLE_CMD,
729 sizeof(coex_cmd), &coex_cmd);
730}
731
732int iwl5000_alive_notify(struct iwl_priv *priv) 587int iwl5000_alive_notify(struct iwl_priv *priv)
733{ 588{
734 u32 a; 589 u32 a;
@@ -746,7 +601,8 @@ int iwl5000_alive_notify(struct iwl_priv *priv)
746 for (; a < priv->scd_base_addr + IWL50_SCD_TRANSLATE_TBL_OFFSET; 601 for (; a < priv->scd_base_addr + IWL50_SCD_TRANSLATE_TBL_OFFSET;
747 a += 4) 602 a += 4)
748 iwl_write_targ_mem(priv, a, 0); 603 iwl_write_targ_mem(priv, a, 0);
749 for (; a < sizeof(u16) * priv->hw_params.max_txq_num; a += 4) 604 for (; a < priv->scd_base_addr +
605 IWL50_SCD_TRANSLATE_TBL_OFFSET_QUEUE(priv->hw_params.max_txq_num); a += 4)
750 iwl_write_targ_mem(priv, a, 0); 606 iwl_write_targ_mem(priv, a, 0);
751 607
752 iwl_write_prph(priv, IWL50_SCD_DRAM_BASE_ADDR, 608 iwl_write_prph(priv, IWL50_SCD_DRAM_BASE_ADDR,
@@ -792,15 +648,26 @@ int iwl5000_alive_notify(struct iwl_priv *priv)
792 648
793 iwl5000_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0); 649 iwl5000_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0);
794 650
651 /* make sure all queue are not stopped */
652 memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped));
653 for (i = 0; i < 4; i++)
654 atomic_set(&priv->queue_stop_count[i], 0);
655
656 /* reset to 0 to enable all the queue first */
657 priv->txq_ctx_active_msk = 0;
795 /* map qos queues to fifos one-to-one */ 658 /* map qos queues to fifos one-to-one */
796 for (i = 0; i < ARRAY_SIZE(iwl5000_default_queue_to_tx_fifo); i++) { 659 for (i = 0; i < ARRAY_SIZE(iwl5000_default_queue_to_tx_fifo); i++) {
797 int ac = iwl5000_default_queue_to_tx_fifo[i]; 660 int ac = iwl5000_default_queue_to_tx_fifo[i];
798 iwl_txq_ctx_activate(priv, i); 661 iwl_txq_ctx_activate(priv, i);
799 iwl5000_tx_queue_set_status(priv, &priv->txq[i], ac, 0); 662 iwl5000_tx_queue_set_status(priv, &priv->txq[i], ac, 0);
800 } 663 }
801 /* TODO - need to initialize those FIFOs inside the loop above, 664
802 * not only mark them as active */ 665 /*
803 iwl_txq_ctx_activate(priv, 4); 666 * TODO - need to initialize these queues and map them to FIFOs
667 * in the loop above, not only mark them as active. We do this
668 * because we want the first aggregation queue to be queue #10,
669 * but do not use 8 or 9 otherwise yet.
670 */
804 iwl_txq_ctx_activate(priv, 7); 671 iwl_txq_ctx_activate(priv, 7);
805 iwl_txq_ctx_activate(priv, 8); 672 iwl_txq_ctx_activate(priv, 8);
806 iwl_txq_ctx_activate(priv, 9); 673 iwl_txq_ctx_activate(priv, 9);
@@ -808,7 +675,7 @@ int iwl5000_alive_notify(struct iwl_priv *priv)
808 spin_unlock_irqrestore(&priv->lock, flags); 675 spin_unlock_irqrestore(&priv->lock, flags);
809 676
810 677
811 iwl5000_send_wimax_coex(priv); 678 iwl_send_wimax_coex(priv);
812 679
813 iwl5000_set_Xtal_calib(priv); 680 iwl5000_set_Xtal_calib(priv);
814 iwl_send_calib_results(priv); 681 iwl_send_calib_results(priv);
@@ -818,32 +685,22 @@ int iwl5000_alive_notify(struct iwl_priv *priv)
818 685
819int iwl5000_hw_set_hw_params(struct iwl_priv *priv) 686int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
820{ 687{
821 if ((priv->cfg->mod_params->num_of_queues > IWL50_NUM_QUEUES) || 688 if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
822 (priv->cfg->mod_params->num_of_queues < IWL_MIN_NUM_QUEUES)) { 689 priv->cfg->mod_params->num_of_queues <= IWL50_NUM_QUEUES)
823 IWL_ERR(priv, 690 priv->cfg->num_of_queues =
824 "invalid queues_num, should be between %d and %d\n", 691 priv->cfg->mod_params->num_of_queues;
825 IWL_MIN_NUM_QUEUES, IWL50_NUM_QUEUES);
826 return -EINVAL;
827 }
828 692
829 priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues; 693 priv->hw_params.max_txq_num = priv->cfg->num_of_queues;
830 priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; 694 priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
831 priv->hw_params.scd_bc_tbls_size = 695 priv->hw_params.scd_bc_tbls_size =
832 IWL50_NUM_QUEUES * sizeof(struct iwl5000_scd_bc_tbl); 696 priv->cfg->num_of_queues *
697 sizeof(struct iwl5000_scd_bc_tbl);
833 priv->hw_params.tfd_size = sizeof(struct iwl_tfd); 698 priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
834 priv->hw_params.max_stations = IWL5000_STATION_COUNT; 699 priv->hw_params.max_stations = IWL5000_STATION_COUNT;
835 priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID; 700 priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
836 701
837 switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) { 702 priv->hw_params.max_data_size = IWL50_RTC_DATA_SIZE;
838 case CSR_HW_REV_TYPE_6x00: 703 priv->hw_params.max_inst_size = IWL50_RTC_INST_SIZE;
839 case CSR_HW_REV_TYPE_6x50:
840 priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE;
841 priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE;
842 break;
843 default:
844 priv->hw_params.max_data_size = IWL50_RTC_DATA_SIZE;
845 priv->hw_params.max_inst_size = IWL50_RTC_INST_SIZE;
846 }
847 704
848 priv->hw_params.max_bsm_size = 0; 705 priv->hw_params.max_bsm_size = 0;
849 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | 706 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
@@ -922,7 +779,7 @@ void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
922 779
923 scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent; 780 scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent;
924 781
925 if (txq->q.write_ptr < TFD_QUEUE_SIZE_BC_DUP) 782 if (write_ptr < TFD_QUEUE_SIZE_BC_DUP)
926 scd_bc_tbl[txq_id]. 783 scd_bc_tbl[txq_id].
927 tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent; 784 tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent;
928} 785}
@@ -941,12 +798,12 @@ void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
941 if (txq_id != IWL_CMD_QUEUE_NUM) 798 if (txq_id != IWL_CMD_QUEUE_NUM)
942 sta_id = txq->cmd[read_ptr]->cmd.tx.sta_id; 799 sta_id = txq->cmd[read_ptr]->cmd.tx.sta_id;
943 800
944 bc_ent = cpu_to_le16(1 | (sta_id << 12)); 801 bc_ent = cpu_to_le16(1 | (sta_id << 12));
945 scd_bc_tbl[txq_id].tfd_offset[read_ptr] = bc_ent; 802 scd_bc_tbl[txq_id].tfd_offset[read_ptr] = bc_ent;
946 803
947 if (txq->q.write_ptr < TFD_QUEUE_SIZE_BC_DUP) 804 if (read_ptr < TFD_QUEUE_SIZE_BC_DUP)
948 scd_bc_tbl[txq_id]. 805 scd_bc_tbl[txq_id].
949 tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] = bc_ent; 806 tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] = bc_ent;
950} 807}
951 808
952static int iwl5000_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid, 809static int iwl5000_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid,
@@ -989,11 +846,13 @@ int iwl5000_txq_agg_enable(struct iwl_priv *priv, int txq_id,
989 u16 ra_tid; 846 u16 ra_tid;
990 847
991 if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) || 848 if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) ||
992 (IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES <= txq_id)) { 849 (IWL50_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues
850 <= txq_id)) {
993 IWL_WARN(priv, 851 IWL_WARN(priv,
994 "queue number out of range: %d, must be %d to %d\n", 852 "queue number out of range: %d, must be %d to %d\n",
995 txq_id, IWL50_FIRST_AMPDU_QUEUE, 853 txq_id, IWL50_FIRST_AMPDU_QUEUE,
996 IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES - 1); 854 IWL50_FIRST_AMPDU_QUEUE +
855 priv->cfg->num_of_ampdu_queues - 1);
997 return -EINVAL; 856 return -EINVAL;
998 } 857 }
999 858
@@ -1047,11 +906,13 @@ int iwl5000_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
1047 u16 ssn_idx, u8 tx_fifo) 906 u16 ssn_idx, u8 tx_fifo)
1048{ 907{
1049 if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) || 908 if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) ||
1050 (IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES <= txq_id)) { 909 (IWL50_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues
910 <= txq_id)) {
1051 IWL_ERR(priv, 911 IWL_ERR(priv,
1052 "queue number out of range: %d, must be %d to %d\n", 912 "queue number out of range: %d, must be %d to %d\n",
1053 txq_id, IWL50_FIRST_AMPDU_QUEUE, 913 txq_id, IWL50_FIRST_AMPDU_QUEUE,
1054 IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES - 1); 914 IWL50_FIRST_AMPDU_QUEUE +
915 priv->cfg->num_of_ampdu_queues - 1);
1055 return -EINVAL; 916 return -EINVAL;
1056 } 917 }
1057 918
@@ -1132,8 +993,7 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,
1132 info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb[0]); 993 info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb[0]);
1133 info->status.rates[0].count = tx_resp->failure_frame + 1; 994 info->status.rates[0].count = tx_resp->failure_frame + 1;
1134 info->flags &= ~IEEE80211_TX_CTL_AMPDU; 995 info->flags &= ~IEEE80211_TX_CTL_AMPDU;
1135 info->flags |= iwl_is_tx_success(status) ? 996 info->flags |= iwl_tx_status_to_mac80211(status);
1136 IEEE80211_TX_STAT_ACK : 0;
1137 iwl_hwrate_to_tx_control(priv, rate_n_flags, info); 997 iwl_hwrate_to_tx_control(priv, rate_n_flags, info);
1138 998
1139 /* FIXME: code repetition end */ 999 /* FIXME: code repetition end */
@@ -1218,7 +1078,7 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,
1218static void iwl5000_rx_reply_tx(struct iwl_priv *priv, 1078static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
1219 struct iwl_rx_mem_buffer *rxb) 1079 struct iwl_rx_mem_buffer *rxb)
1220{ 1080{
1221 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; 1081 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1222 u16 sequence = le16_to_cpu(pkt->hdr.sequence); 1082 u16 sequence = le16_to_cpu(pkt->hdr.sequence);
1223 int txq_id = SEQ_TO_QUEUE(sequence); 1083 int txq_id = SEQ_TO_QUEUE(sequence);
1224 int index = SEQ_TO_INDEX(sequence); 1084 int index = SEQ_TO_INDEX(sequence);
@@ -1263,7 +1123,7 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
1263 scd_ssn , index, txq_id, txq->swq_id); 1123 scd_ssn , index, txq_id, txq->swq_id);
1264 1124
1265 freed = iwl_tx_queue_reclaim(priv, txq_id, index); 1125 freed = iwl_tx_queue_reclaim(priv, txq_id, index);
1266 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; 1126 iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
1267 1127
1268 if (priv->mac80211_registered && 1128 if (priv->mac80211_registered &&
1269 (iwl_queue_space(&txq->q) > txq->q.low_mark) && 1129 (iwl_queue_space(&txq->q) > txq->q.low_mark) &&
@@ -1278,8 +1138,7 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
1278 BUG_ON(txq_id != txq->swq_id); 1138 BUG_ON(txq_id != txq->swq_id);
1279 1139
1280 info->status.rates[0].count = tx_resp->failure_frame + 1; 1140 info->status.rates[0].count = tx_resp->failure_frame + 1;
1281 info->flags |= iwl_is_tx_success(status) ? 1141 info->flags |= iwl_tx_status_to_mac80211(status);
1282 IEEE80211_TX_STAT_ACK : 0;
1283 iwl_hwrate_to_tx_control(priv, 1142 iwl_hwrate_to_tx_control(priv,
1284 le32_to_cpu(tx_resp->rate_n_flags), 1143 le32_to_cpu(tx_resp->rate_n_flags),
1285 info); 1144 info);
@@ -1292,16 +1151,14 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
1292 tx_resp->failure_frame); 1151 tx_resp->failure_frame);
1293 1152
1294 freed = iwl_tx_queue_reclaim(priv, txq_id, index); 1153 freed = iwl_tx_queue_reclaim(priv, txq_id, index);
1295 if (ieee80211_is_data_qos(tx_resp->frame_ctrl)) 1154 iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
1296 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
1297 1155
1298 if (priv->mac80211_registered && 1156 if (priv->mac80211_registered &&
1299 (iwl_queue_space(&txq->q) > txq->q.low_mark)) 1157 (iwl_queue_space(&txq->q) > txq->q.low_mark))
1300 iwl_wake_queue(priv, txq_id); 1158 iwl_wake_queue(priv, txq_id);
1301 } 1159 }
1302 1160
1303 if (ieee80211_is_data_qos(tx_resp->frame_ctrl)) 1161 iwl_txq_check_empty(priv, sta_id, tid, txq_id);
1304 iwl_txq_check_empty(priv, sta_id, tid, txq_id);
1305 1162
1306 if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) 1163 if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
1307 IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n"); 1164 IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n");
@@ -1389,6 +1246,22 @@ int iwl5000_send_tx_power(struct iwl_priv *priv)
1389 1246
1390 /* half dBm need to multiply */ 1247 /* half dBm need to multiply */
1391 tx_power_cmd.global_lmt = (s8)(2 * priv->tx_power_user_lmt); 1248 tx_power_cmd.global_lmt = (s8)(2 * priv->tx_power_user_lmt);
1249
1250 if (priv->tx_power_lmt_in_half_dbm &&
1251 priv->tx_power_lmt_in_half_dbm < tx_power_cmd.global_lmt) {
1252 /*
1253 * For the newer devices which using enhanced/extend tx power
1254 * table in EEPROM, the format is in half dBm. driver need to
1255 * convert to dBm format before report to mac80211.
1256 * By doing so, there is a possibility of 1/2 dBm resolution
1257 * lost. driver will perform "round-up" operation before
1258 * reporting, but it will cause 1/2 dBm tx power over the
1259 * regulatory limit. Perform the checking here, if the
1260 * "tx_power_user_lmt" is higher than EEPROM value (in
1261 * half-dBm format), lower the tx power based on EEPROM
1262 */
1263 tx_power_cmd.global_lmt = priv->tx_power_lmt_in_half_dbm;
1264 }
1392 tx_power_cmd.flags = IWL50_TX_POWER_NO_CLOSED; 1265 tx_power_cmd.flags = IWL50_TX_POWER_NO_CLOSED;
1393 tx_power_cmd.srv_chan_lmt = IWL50_TX_POWER_AUTO; 1266 tx_power_cmd.srv_chan_lmt = IWL50_TX_POWER_AUTO;
1394 1267
@@ -1459,6 +1332,24 @@ int iwl5000_calc_rssi(struct iwl_priv *priv,
1459 return max_rssi - agc - IWL49_RSSI_OFFSET; 1332 return max_rssi - agc - IWL49_RSSI_OFFSET;
1460} 1333}
1461 1334
1335static int iwl5000_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant)
1336{
1337 struct iwl_tx_ant_config_cmd tx_ant_cmd = {
1338 .valid = cpu_to_le32(valid_tx_ant),
1339 };
1340
1341 if (IWL_UCODE_API(priv->ucode_ver) > 1) {
1342 IWL_DEBUG_HC(priv, "select valid tx ant: %u\n", valid_tx_ant);
1343 return iwl_send_cmd_pdu(priv, TX_ANT_CONFIGURATION_CMD,
1344 sizeof(struct iwl_tx_ant_config_cmd),
1345 &tx_ant_cmd);
1346 } else {
1347 IWL_DEBUG_HC(priv, "TX_ANT_CONFIGURATION_CMD not supported\n");
1348 return -EOPNOTSUPP;
1349 }
1350}
1351
1352
1462#define IWL5000_UCODE_GET(item) \ 1353#define IWL5000_UCODE_GET(item) \
1463static u32 iwl5000_ucode_get_##item(const struct iwl_ucode_header *ucode,\ 1354static u32 iwl5000_ucode_get_##item(const struct iwl_ucode_header *ucode,\
1464 u32 api_ver) \ 1355 u32 api_ver) \
@@ -1497,10 +1388,43 @@ IWL5000_UCODE_GET(init_size);
1497IWL5000_UCODE_GET(init_data_size); 1388IWL5000_UCODE_GET(init_data_size);
1498IWL5000_UCODE_GET(boot_size); 1389IWL5000_UCODE_GET(boot_size);
1499 1390
1391static int iwl5000_hw_channel_switch(struct iwl_priv *priv, u16 channel)
1392{
1393 struct iwl5000_channel_switch_cmd cmd;
1394 const struct iwl_channel_info *ch_info;
1395 struct iwl_host_cmd hcmd = {
1396 .id = REPLY_CHANNEL_SWITCH,
1397 .len = sizeof(cmd),
1398 .flags = CMD_SIZE_HUGE,
1399 .data = &cmd,
1400 };
1401
1402 IWL_DEBUG_11H(priv, "channel switch from %d to %d\n",
1403 priv->active_rxon.channel, channel);
1404 cmd.band = priv->band == IEEE80211_BAND_2GHZ;
1405 cmd.channel = cpu_to_le16(channel);
1406 cmd.rxon_flags = priv->staging_rxon.flags;
1407 cmd.rxon_filter_flags = priv->staging_rxon.filter_flags;
1408 cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time);
1409 ch_info = iwl_get_channel_info(priv, priv->band, channel);
1410 if (ch_info)
1411 cmd.expect_beacon = is_channel_radar(ch_info);
1412 else {
1413 IWL_ERR(priv, "invalid channel switch from %u to %u\n",
1414 priv->active_rxon.channel, channel);
1415 return -EFAULT;
1416 }
1417 priv->switch_rxon.channel = cpu_to_le16(channel);
1418 priv->switch_rxon.switch_in_progress = true;
1419
1420 return iwl_send_cmd_sync(priv, &hcmd);
1421}
1422
1500struct iwl_hcmd_ops iwl5000_hcmd = { 1423struct iwl_hcmd_ops iwl5000_hcmd = {
1501 .rxon_assoc = iwl5000_send_rxon_assoc, 1424 .rxon_assoc = iwl5000_send_rxon_assoc,
1502 .commit_rxon = iwl_commit_rxon, 1425 .commit_rxon = iwl_commit_rxon,
1503 .set_rxon_chain = iwl_set_rxon_chain, 1426 .set_rxon_chain = iwl_set_rxon_chain,
1427 .set_tx_ant = iwl5000_send_tx_ant_config,
1504}; 1428};
1505 1429
1506struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = { 1430struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = {
@@ -1538,15 +1462,17 @@ struct iwl_lib_ops iwl5000_lib = {
1538 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr, 1462 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr,
1539 .dump_nic_event_log = iwl_dump_nic_event_log, 1463 .dump_nic_event_log = iwl_dump_nic_event_log,
1540 .dump_nic_error_log = iwl_dump_nic_error_log, 1464 .dump_nic_error_log = iwl_dump_nic_error_log,
1465 .dump_csr = iwl_dump_csr,
1466 .dump_fh = iwl_dump_fh,
1541 .load_ucode = iwl5000_load_ucode, 1467 .load_ucode = iwl5000_load_ucode,
1542 .init_alive_start = iwl5000_init_alive_start, 1468 .init_alive_start = iwl5000_init_alive_start,
1543 .alive_notify = iwl5000_alive_notify, 1469 .alive_notify = iwl5000_alive_notify,
1544 .send_tx_power = iwl5000_send_tx_power, 1470 .send_tx_power = iwl5000_send_tx_power,
1545 .update_chain_flags = iwl_update_chain_flags, 1471 .update_chain_flags = iwl_update_chain_flags,
1472 .set_channel_switch = iwl5000_hw_channel_switch,
1546 .apm_ops = { 1473 .apm_ops = {
1547 .init = iwl5000_apm_init, 1474 .init = iwl_apm_init,
1548 .reset = iwl5000_apm_reset, 1475 .stop = iwl_apm_stop,
1549 .stop = iwl5000_apm_stop,
1550 .config = iwl5000_nic_config, 1476 .config = iwl5000_nic_config,
1551 .set_pwr_src = iwl_set_pwr_src, 1477 .set_pwr_src = iwl_set_pwr_src,
1552 }, 1478 },
@@ -1573,6 +1499,7 @@ struct iwl_lib_ops iwl5000_lib = {
1573 .temperature = iwl5000_temperature, 1499 .temperature = iwl5000_temperature,
1574 .set_ct_kill = iwl5000_set_ct_threshold, 1500 .set_ct_kill = iwl5000_set_ct_threshold,
1575 }, 1501 },
1502 .add_bcast_station = iwl_add_bcast_station,
1576}; 1503};
1577 1504
1578static struct iwl_lib_ops iwl5150_lib = { 1505static struct iwl_lib_ops iwl5150_lib = {
@@ -1590,15 +1517,16 @@ static struct iwl_lib_ops iwl5150_lib = {
1590 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr, 1517 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr,
1591 .dump_nic_event_log = iwl_dump_nic_event_log, 1518 .dump_nic_event_log = iwl_dump_nic_event_log,
1592 .dump_nic_error_log = iwl_dump_nic_error_log, 1519 .dump_nic_error_log = iwl_dump_nic_error_log,
1520 .dump_csr = iwl_dump_csr,
1593 .load_ucode = iwl5000_load_ucode, 1521 .load_ucode = iwl5000_load_ucode,
1594 .init_alive_start = iwl5000_init_alive_start, 1522 .init_alive_start = iwl5000_init_alive_start,
1595 .alive_notify = iwl5000_alive_notify, 1523 .alive_notify = iwl5000_alive_notify,
1596 .send_tx_power = iwl5000_send_tx_power, 1524 .send_tx_power = iwl5000_send_tx_power,
1597 .update_chain_flags = iwl_update_chain_flags, 1525 .update_chain_flags = iwl_update_chain_flags,
1526 .set_channel_switch = iwl5000_hw_channel_switch,
1598 .apm_ops = { 1527 .apm_ops = {
1599 .init = iwl5000_apm_init, 1528 .init = iwl_apm_init,
1600 .reset = iwl5000_apm_reset, 1529 .stop = iwl_apm_stop,
1601 .stop = iwl5000_apm_stop,
1602 .config = iwl5000_nic_config, 1530 .config = iwl5000_nic_config,
1603 .set_pwr_src = iwl_set_pwr_src, 1531 .set_pwr_src = iwl_set_pwr_src,
1604 }, 1532 },
@@ -1625,25 +1553,26 @@ static struct iwl_lib_ops iwl5150_lib = {
1625 .temperature = iwl5150_temperature, 1553 .temperature = iwl5150_temperature,
1626 .set_ct_kill = iwl5150_set_ct_threshold, 1554 .set_ct_kill = iwl5150_set_ct_threshold,
1627 }, 1555 },
1556 .add_bcast_station = iwl_add_bcast_station,
1628}; 1557};
1629 1558
1630struct iwl_ops iwl5000_ops = { 1559static const struct iwl_ops iwl5000_ops = {
1631 .ucode = &iwl5000_ucode, 1560 .ucode = &iwl5000_ucode,
1632 .lib = &iwl5000_lib, 1561 .lib = &iwl5000_lib,
1633 .hcmd = &iwl5000_hcmd, 1562 .hcmd = &iwl5000_hcmd,
1634 .utils = &iwl5000_hcmd_utils, 1563 .utils = &iwl5000_hcmd_utils,
1564 .led = &iwlagn_led_ops,
1635}; 1565};
1636 1566
1637static struct iwl_ops iwl5150_ops = { 1567static const struct iwl_ops iwl5150_ops = {
1638 .ucode = &iwl5000_ucode, 1568 .ucode = &iwl5000_ucode,
1639 .lib = &iwl5150_lib, 1569 .lib = &iwl5150_lib,
1640 .hcmd = &iwl5000_hcmd, 1570 .hcmd = &iwl5000_hcmd,
1641 .utils = &iwl5000_hcmd_utils, 1571 .utils = &iwl5000_hcmd_utils,
1572 .led = &iwlagn_led_ops,
1642}; 1573};
1643 1574
1644struct iwl_mod_params iwl50_mod_params = { 1575struct iwl_mod_params iwl50_mod_params = {
1645 .num_of_queues = IWL50_NUM_QUEUES,
1646 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
1647 .amsdu_size_8K = 1, 1576 .amsdu_size_8K = 1,
1648 .restart_fw = 1, 1577 .restart_fw = 1,
1649 /* the rest are 0 by default */ 1578 /* the rest are 0 by default */
@@ -1660,28 +1589,46 @@ struct iwl_cfg iwl5300_agn_cfg = {
1660 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 1589 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
1661 .eeprom_ver = EEPROM_5000_EEPROM_VERSION, 1590 .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
1662 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 1591 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
1592 .num_of_queues = IWL50_NUM_QUEUES,
1593 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
1663 .mod_params = &iwl50_mod_params, 1594 .mod_params = &iwl50_mod_params,
1664 .valid_tx_ant = ANT_ABC, 1595 .valid_tx_ant = ANT_ABC,
1665 .valid_rx_ant = ANT_ABC, 1596 .valid_rx_ant = ANT_ABC,
1666 .need_pll_cfg = true, 1597 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
1598 .set_l0s = true,
1599 .use_bsm = false,
1667 .ht_greenfield_support = true, 1600 .ht_greenfield_support = true,
1601 .led_compensation = 51,
1602 .use_rts_for_ht = true, /* use rts/cts protection */
1603 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1604 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1605 .chain_noise_scale = 1000,
1668}; 1606};
1669 1607
1670struct iwl_cfg iwl5100_bg_cfg = { 1608struct iwl_cfg iwl5100_bgn_cfg = {
1671 .name = "5100BG", 1609 .name = "5100BGN",
1672 .fw_name_pre = IWL5000_FW_PRE, 1610 .fw_name_pre = IWL5000_FW_PRE,
1673 .ucode_api_max = IWL5000_UCODE_API_MAX, 1611 .ucode_api_max = IWL5000_UCODE_API_MAX,
1674 .ucode_api_min = IWL5000_UCODE_API_MIN, 1612 .ucode_api_min = IWL5000_UCODE_API_MIN,
1675 .sku = IWL_SKU_G, 1613 .sku = IWL_SKU_G|IWL_SKU_N,
1676 .ops = &iwl5000_ops, 1614 .ops = &iwl5000_ops,
1677 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 1615 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
1678 .eeprom_ver = EEPROM_5000_EEPROM_VERSION, 1616 .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
1679 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 1617 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
1618 .num_of_queues = IWL50_NUM_QUEUES,
1619 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
1680 .mod_params = &iwl50_mod_params, 1620 .mod_params = &iwl50_mod_params,
1681 .valid_tx_ant = ANT_B, 1621 .valid_tx_ant = ANT_B,
1682 .valid_rx_ant = ANT_AB, 1622 .valid_rx_ant = ANT_AB,
1683 .need_pll_cfg = true, 1623 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
1624 .set_l0s = true,
1625 .use_bsm = false,
1684 .ht_greenfield_support = true, 1626 .ht_greenfield_support = true,
1627 .led_compensation = 51,
1628 .use_rts_for_ht = true, /* use rts/cts protection */
1629 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1630 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1631 .chain_noise_scale = 1000,
1685}; 1632};
1686 1633
1687struct iwl_cfg iwl5100_abg_cfg = { 1634struct iwl_cfg iwl5100_abg_cfg = {
@@ -1694,11 +1641,18 @@ struct iwl_cfg iwl5100_abg_cfg = {
1694 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 1641 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
1695 .eeprom_ver = EEPROM_5000_EEPROM_VERSION, 1642 .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
1696 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 1643 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
1644 .num_of_queues = IWL50_NUM_QUEUES,
1645 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
1697 .mod_params = &iwl50_mod_params, 1646 .mod_params = &iwl50_mod_params,
1698 .valid_tx_ant = ANT_B, 1647 .valid_tx_ant = ANT_B,
1699 .valid_rx_ant = ANT_AB, 1648 .valid_rx_ant = ANT_AB,
1700 .need_pll_cfg = true, 1649 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
1701 .ht_greenfield_support = true, 1650 .set_l0s = true,
1651 .use_bsm = false,
1652 .led_compensation = 51,
1653 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1654 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1655 .chain_noise_scale = 1000,
1702}; 1656};
1703 1657
1704struct iwl_cfg iwl5100_agn_cfg = { 1658struct iwl_cfg iwl5100_agn_cfg = {
@@ -1711,11 +1665,20 @@ struct iwl_cfg iwl5100_agn_cfg = {
1711 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 1665 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
1712 .eeprom_ver = EEPROM_5000_EEPROM_VERSION, 1666 .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
1713 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 1667 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
1668 .num_of_queues = IWL50_NUM_QUEUES,
1669 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
1714 .mod_params = &iwl50_mod_params, 1670 .mod_params = &iwl50_mod_params,
1715 .valid_tx_ant = ANT_B, 1671 .valid_tx_ant = ANT_B,
1716 .valid_rx_ant = ANT_AB, 1672 .valid_rx_ant = ANT_AB,
1717 .need_pll_cfg = true, 1673 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
1674 .set_l0s = true,
1675 .use_bsm = false,
1718 .ht_greenfield_support = true, 1676 .ht_greenfield_support = true,
1677 .led_compensation = 51,
1678 .use_rts_for_ht = true, /* use rts/cts protection */
1679 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1680 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1681 .chain_noise_scale = 1000,
1719}; 1682};
1720 1683
1721struct iwl_cfg iwl5350_agn_cfg = { 1684struct iwl_cfg iwl5350_agn_cfg = {
@@ -1728,11 +1691,20 @@ struct iwl_cfg iwl5350_agn_cfg = {
1728 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 1691 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
1729 .eeprom_ver = EEPROM_5050_EEPROM_VERSION, 1692 .eeprom_ver = EEPROM_5050_EEPROM_VERSION,
1730 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, 1693 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
1694 .num_of_queues = IWL50_NUM_QUEUES,
1695 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
1731 .mod_params = &iwl50_mod_params, 1696 .mod_params = &iwl50_mod_params,
1732 .valid_tx_ant = ANT_ABC, 1697 .valid_tx_ant = ANT_ABC,
1733 .valid_rx_ant = ANT_ABC, 1698 .valid_rx_ant = ANT_ABC,
1734 .need_pll_cfg = true, 1699 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
1700 .set_l0s = true,
1701 .use_bsm = false,
1735 .ht_greenfield_support = true, 1702 .ht_greenfield_support = true,
1703 .led_compensation = 51,
1704 .use_rts_for_ht = true, /* use rts/cts protection */
1705 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1706 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1707 .chain_noise_scale = 1000,
1736}; 1708};
1737 1709
1738struct iwl_cfg iwl5150_agn_cfg = { 1710struct iwl_cfg iwl5150_agn_cfg = {
@@ -1745,24 +1717,58 @@ struct iwl_cfg iwl5150_agn_cfg = {
1745 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 1717 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
1746 .eeprom_ver = EEPROM_5050_EEPROM_VERSION, 1718 .eeprom_ver = EEPROM_5050_EEPROM_VERSION,
1747 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, 1719 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
1720 .num_of_queues = IWL50_NUM_QUEUES,
1721 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
1748 .mod_params = &iwl50_mod_params, 1722 .mod_params = &iwl50_mod_params,
1749 .valid_tx_ant = ANT_A, 1723 .valid_tx_ant = ANT_A,
1750 .valid_rx_ant = ANT_AB, 1724 .valid_rx_ant = ANT_AB,
1751 .need_pll_cfg = true, 1725 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
1726 .set_l0s = true,
1727 .use_bsm = false,
1752 .ht_greenfield_support = true, 1728 .ht_greenfield_support = true,
1729 .led_compensation = 51,
1730 .use_rts_for_ht = true, /* use rts/cts protection */
1731 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1732 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1733 .chain_noise_scale = 1000,
1734};
1735
1736struct iwl_cfg iwl5150_abg_cfg = {
1737 .name = "5150ABG",
1738 .fw_name_pre = IWL5150_FW_PRE,
1739 .ucode_api_max = IWL5150_UCODE_API_MAX,
1740 .ucode_api_min = IWL5150_UCODE_API_MIN,
1741 .sku = IWL_SKU_A|IWL_SKU_G,
1742 .ops = &iwl5150_ops,
1743 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
1744 .eeprom_ver = EEPROM_5050_EEPROM_VERSION,
1745 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
1746 .num_of_queues = IWL50_NUM_QUEUES,
1747 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
1748 .mod_params = &iwl50_mod_params,
1749 .valid_tx_ant = ANT_A,
1750 .valid_rx_ant = ANT_AB,
1751 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
1752 .set_l0s = true,
1753 .use_bsm = false,
1754 .led_compensation = 51,
1755 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1756 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1757 .chain_noise_scale = 1000,
1753}; 1758};
1754 1759
1755MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX)); 1760MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX));
1756MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_MAX)); 1761MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_MAX));
1757 1762
1758module_param_named(swcrypto50, iwl50_mod_params.sw_crypto, bool, 0444); 1763module_param_named(swcrypto50, iwl50_mod_params.sw_crypto, bool, S_IRUGO);
1759MODULE_PARM_DESC(swcrypto50, 1764MODULE_PARM_DESC(swcrypto50,
1760 "using software crypto engine (default 0 [hardware])\n"); 1765 "using software crypto engine (default 0 [hardware])\n");
1761module_param_named(queues_num50, iwl50_mod_params.num_of_queues, int, 0444); 1766module_param_named(queues_num50, iwl50_mod_params.num_of_queues, int, S_IRUGO);
1762MODULE_PARM_DESC(queues_num50, "number of hw queues in 50xx series"); 1767MODULE_PARM_DESC(queues_num50, "number of hw queues in 50xx series");
1763module_param_named(11n_disable50, iwl50_mod_params.disable_11n, int, 0444); 1768module_param_named(11n_disable50, iwl50_mod_params.disable_11n, int, S_IRUGO);
1764MODULE_PARM_DESC(11n_disable50, "disable 50XX 11n functionality"); 1769MODULE_PARM_DESC(11n_disable50, "disable 50XX 11n functionality");
1765module_param_named(amsdu_size_8K50, iwl50_mod_params.amsdu_size_8K, int, 0444); 1770module_param_named(amsdu_size_8K50, iwl50_mod_params.amsdu_size_8K,
1771 int, S_IRUGO);
1766MODULE_PARM_DESC(amsdu_size_8K50, "enable 8K amsdu size in 50XX series"); 1772MODULE_PARM_DESC(amsdu_size_8K50, "enable 8K amsdu size in 50XX series");
1767module_param_named(fw_restart50, iwl50_mod_params.restart_fw, int, 0444); 1773module_param_named(fw_restart50, iwl50_mod_params.restart_fw, int, S_IRUGO);
1768MODULE_PARM_DESC(fw_restart50, "restart firmware in case of error"); 1774MODULE_PARM_DESC(fw_restart50, "restart firmware in case of error");