diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /drivers/net/wireless/iwlwifi/iwl-5000.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-5000.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-5000.c | 548 |
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 */ |
76 | static 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 | |||
95 | int 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 */ | ||
141 | void 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 | |||
160 | int 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); | ||
196 | out: | ||
197 | |||
198 | return ret; | ||
199 | } | ||
200 | |||
201 | |||
202 | /* NIC configuration for 5000 series and up */ | ||
203 | void iwl5000_nic_config(struct iwl_priv *priv) | 77 | void 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) | |||
302 | static void iwl5000_gain_computation(struct iwl_priv *priv, | 164 | static 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 | ||
412 | static struct iwl_sensitivity_ranges iwl5150_sensitivity = { | 291 | static 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 | ||
434 | const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv, | 317 | const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv, |
@@ -460,14 +343,15 @@ static void iwl5000_set_ct_threshold(struct iwl_priv *priv) | |||
460 | static int iwl5000_set_Xtal_calib(struct iwl_priv *priv) | 343 | static 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) | |||
493 | static void iwl5000_rx_calib_result(struct iwl_priv *priv, | 377 | static 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 | */ |
541 | static int iwl5000_load_section(struct iwl_priv *priv, | 425 | static 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 | |||
579 | static 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"); | 479 | static 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 | ||
629 | int iwl5000_load_ucode(struct iwl_priv *priv) | 494 | int 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 | ||
722 | static 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 | |||
732 | int iwl5000_alive_notify(struct iwl_priv *priv) | 587 | int 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 | ||
819 | int iwl5000_hw_set_hw_params(struct iwl_priv *priv) | 686 | int 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 | ||
952 | static int iwl5000_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid, | 809 | static 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, | |||
1218 | static void iwl5000_rx_reply_tx(struct iwl_priv *priv, | 1078 | static 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 | ||
1335 | static 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) \ |
1463 | static u32 iwl5000_ucode_get_##item(const struct iwl_ucode_header *ucode,\ | 1354 | static 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); | |||
1497 | IWL5000_UCODE_GET(init_data_size); | 1388 | IWL5000_UCODE_GET(init_data_size); |
1498 | IWL5000_UCODE_GET(boot_size); | 1389 | IWL5000_UCODE_GET(boot_size); |
1499 | 1390 | ||
1391 | static 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 | |||
1500 | struct iwl_hcmd_ops iwl5000_hcmd = { | 1423 | struct 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 | ||
1506 | struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = { | 1430 | struct 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 | ||
1578 | static struct iwl_lib_ops iwl5150_lib = { | 1505 | static 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 | ||
1630 | struct iwl_ops iwl5000_ops = { | 1559 | static 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 | ||
1637 | static struct iwl_ops iwl5150_ops = { | 1567 | static 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 | ||
1644 | struct iwl_mod_params iwl50_mod_params = { | 1575 | struct 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 | ||
1670 | struct iwl_cfg iwl5100_bg_cfg = { | 1608 | struct 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 | ||
1687 | struct iwl_cfg iwl5100_abg_cfg = { | 1634 | struct 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 | ||
1704 | struct iwl_cfg iwl5100_agn_cfg = { | 1658 | struct 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 | ||
1721 | struct iwl_cfg iwl5350_agn_cfg = { | 1684 | struct 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 | ||
1738 | struct iwl_cfg iwl5150_agn_cfg = { | 1710 | struct 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 | |||
1736 | struct 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 | ||
1755 | MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX)); | 1760 | MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX)); |
1756 | MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_MAX)); | 1761 | MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_MAX)); |
1757 | 1762 | ||
1758 | module_param_named(swcrypto50, iwl50_mod_params.sw_crypto, bool, 0444); | 1763 | module_param_named(swcrypto50, iwl50_mod_params.sw_crypto, bool, S_IRUGO); |
1759 | MODULE_PARM_DESC(swcrypto50, | 1764 | MODULE_PARM_DESC(swcrypto50, |
1760 | "using software crypto engine (default 0 [hardware])\n"); | 1765 | "using software crypto engine (default 0 [hardware])\n"); |
1761 | module_param_named(queues_num50, iwl50_mod_params.num_of_queues, int, 0444); | 1766 | module_param_named(queues_num50, iwl50_mod_params.num_of_queues, int, S_IRUGO); |
1762 | MODULE_PARM_DESC(queues_num50, "number of hw queues in 50xx series"); | 1767 | MODULE_PARM_DESC(queues_num50, "number of hw queues in 50xx series"); |
1763 | module_param_named(11n_disable50, iwl50_mod_params.disable_11n, int, 0444); | 1768 | module_param_named(11n_disable50, iwl50_mod_params.disable_11n, int, S_IRUGO); |
1764 | MODULE_PARM_DESC(11n_disable50, "disable 50XX 11n functionality"); | 1769 | MODULE_PARM_DESC(11n_disable50, "disable 50XX 11n functionality"); |
1765 | module_param_named(amsdu_size_8K50, iwl50_mod_params.amsdu_size_8K, int, 0444); | 1770 | module_param_named(amsdu_size_8K50, iwl50_mod_params.amsdu_size_8K, |
1771 | int, S_IRUGO); | ||
1766 | MODULE_PARM_DESC(amsdu_size_8K50, "enable 8K amsdu size in 50XX series"); | 1772 | MODULE_PARM_DESC(amsdu_size_8K50, "enable 8K amsdu size in 50XX series"); |
1767 | module_param_named(fw_restart50, iwl50_mod_params.restart_fw, int, 0444); | 1773 | module_param_named(fw_restart50, iwl50_mod_params.restart_fw, int, S_IRUGO); |
1768 | MODULE_PARM_DESC(fw_restart50, "restart firmware in case of error"); | 1774 | MODULE_PARM_DESC(fw_restart50, "restart firmware in case of error"); |