iwl-5000.c revision dbb983b70a4696666112591572ed49c48c58da26
1/****************************************************************************** 2 * 3 * Copyright(c) 2007-2008 Intel Corporation. All rights reserved. 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of version 2 of the GNU General Public License as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 * more details. 13 * 14 * You should have received a copy of the GNU General Public License along with 15 * this program; if not, write to the Free Software Foundation, Inc., 16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 17 * 18 * The full GNU General Public License is included in this distribution in the 19 * file called LICENSE. 20 * 21 * Contact Information: 22 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 23 * 24 *****************************************************************************/ 25 26#include <linux/kernel.h> 27#include <linux/module.h> 28#include <linux/version.h> 29#include <linux/init.h> 30#include <linux/pci.h> 31#include <linux/dma-mapping.h> 32#include <linux/delay.h> 33#include <linux/skbuff.h> 34#include <linux/netdevice.h> 35#include <linux/wireless.h> 36#include <net/mac80211.h> 37#include <linux/etherdevice.h> 38#include <asm/unaligned.h> 39 40#include "iwl-eeprom.h" 41#include "iwl-dev.h" 42#include "iwl-core.h" 43#include "iwl-io.h" 44#include "iwl-helpers.h" 45#include "iwl-5000-hw.h" 46 47#define IWL5000_UCODE_API "-1" 48 49static int iwl5000_apm_init(struct iwl_priv *priv) 50{ 51 int ret = 0; 52 53 iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS, 54 CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); 55 56 iwl_set_bit(priv, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL); 57 58 /* set "initialization complete" bit to move adapter 59 * D0U* --> D0A* state */ 60 iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); 61 62 /* wait for clock stabilization */ 63 ret = iwl_poll_bit(priv, CSR_GP_CNTRL, 64 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 65 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); 66 if (ret < 0) { 67 IWL_DEBUG_INFO("Failed to init the card\n"); 68 return ret; 69 } 70 71 ret = iwl_grab_nic_access(priv); 72 if (ret) 73 return ret; 74 75 /* enable DMA */ 76 iwl_write_prph(priv, APMG_CLK_EN_REG, 77 APMG_CLK_VAL_DMA_CLK_RQT); 78 79 udelay(20); 80 81 iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG, 82 APMG_PCIDEV_STT_VAL_L1_ACT_DIS); 83 84 iwl_release_nic_access(priv); 85 86 return ret; 87} 88 89static void iwl5000_nic_config(struct iwl_priv *priv) 90{ 91 unsigned long flags; 92 u16 radio_cfg; 93 u8 val_link; 94 95 spin_lock_irqsave(&priv->lock, flags); 96 97 pci_read_config_byte(priv->pci_dev, PCI_LINK_CTRL, &val_link); 98 99 /* disable L1 entry -- workaround for pre-B1 */ 100 pci_write_config_byte(priv->pci_dev, PCI_LINK_CTRL, val_link & ~0x02); 101 102 radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG); 103 104 /* write radio config values to register */ 105 if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) < EEPROM_5000_RF_CFG_TYPE_MAX) 106 iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, 107 EEPROM_RF_CFG_TYPE_MSK(radio_cfg) | 108 EEPROM_RF_CFG_STEP_MSK(radio_cfg) | 109 EEPROM_RF_CFG_DASH_MSK(radio_cfg)); 110 111 /* set CSR_HW_CONFIG_REG for uCode use */ 112 iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, 113 CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | 114 CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); 115 116 spin_unlock_irqrestore(&priv->lock, flags); 117} 118 119 120 121/* 122 * EEPROM 123 */ 124static u32 eeprom_indirect_address(const struct iwl_priv *priv, u32 address) 125{ 126 u16 offset = 0; 127 128 if ((address & INDIRECT_ADDRESS) == 0) 129 return address; 130 131 switch (address & INDIRECT_TYPE_MSK) { 132 case INDIRECT_HOST: 133 offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_HOST); 134 break; 135 case INDIRECT_GENERAL: 136 offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_GENERAL); 137 break; 138 case INDIRECT_REGULATORY: 139 offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_REGULATORY); 140 break; 141 case INDIRECT_CALIBRATION: 142 offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_CALIBRATION); 143 break; 144 case INDIRECT_PROCESS_ADJST: 145 offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_PROCESS_ADJST); 146 break; 147 case INDIRECT_OTHERS: 148 offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_OTHERS); 149 break; 150 default: 151 IWL_ERROR("illegal indirect type: 0x%X\n", 152 address & INDIRECT_TYPE_MSK); 153 break; 154 } 155 156 /* translate the offset from words to byte */ 157 return (address & ADDRESS_MSK) + (offset << 1); 158} 159 160static int iwl5000_eeprom_check_version(struct iwl_priv *priv) 161{ 162 u16 eeprom_ver; 163 struct iwl_eeprom_calib_hdr { 164 u8 version; 165 u8 pa_type; 166 u16 voltage; 167 } *hdr; 168 169 eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION); 170 171 hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(priv, 172 EEPROM_5000_CALIB_ALL); 173 174 if (eeprom_ver < EEPROM_5000_EEPROM_VERSION || 175 hdr->version < EEPROM_5000_TX_POWER_VERSION) 176 goto err; 177 178 return 0; 179err: 180 IWL_ERROR("Unsuported EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n", 181 eeprom_ver, EEPROM_5000_EEPROM_VERSION, 182 hdr->version, EEPROM_5000_TX_POWER_VERSION); 183 return -EINVAL; 184 185} 186 187#ifdef CONFIG_IWL5000_RUN_TIME_CALIB 188 189static void iwl5000_gain_computation(struct iwl_priv *priv, 190 u32 average_noise[NUM_RX_CHAINS], 191 u16 min_average_noise_antenna_i, 192 u32 min_average_noise) 193{ 194 int i; 195 s32 delta_g; 196 struct iwl_chain_noise_data *data = &priv->chain_noise_data; 197 198 /* Find Gain Code for the antennas B and C */ 199 for (i = 1; i < NUM_RX_CHAINS; i++) { 200 if ((data->disconn_array[i])) { 201 data->delta_gain_code[i] = 0; 202 continue; 203 } 204 delta_g = (1000 * ((s32)average_noise[0] - 205 (s32)average_noise[i])) / 1500; 206 /* bound gain by 2 bits value max, 3rd bit is sign */ 207 data->delta_gain_code[i] = 208 min(abs(delta_g), CHAIN_NOISE_MAX_DELTA_GAIN_CODE); 209 210 if (delta_g < 0) 211 /* set negative sign */ 212 data->delta_gain_code[i] |= (1 << 2); 213 } 214 215 IWL_DEBUG_CALIB("Delta gains: ANT_B = %d ANT_C = %d\n", 216 data->delta_gain_code[1], data->delta_gain_code[2]); 217 218 if (!data->radio_write) { 219 struct iwl5000_calibration_chain_noise_gain_cmd cmd; 220 memset(&cmd, 0, sizeof(cmd)); 221 222 cmd.op_code = IWL5000_PHY_CALIBRATE_CHAIN_NOISE_GAIN_CMD; 223 cmd.delta_gain_1 = data->delta_gain_code[1]; 224 cmd.delta_gain_2 = data->delta_gain_code[2]; 225 iwl_send_cmd_pdu_async(priv, REPLY_PHY_CALIBRATION_CMD, 226 sizeof(cmd), &cmd, NULL); 227 228 data->radio_write = 1; 229 data->state = IWL_CHAIN_NOISE_CALIBRATED; 230 } 231 232 data->chain_noise_a = 0; 233 data->chain_noise_b = 0; 234 data->chain_noise_c = 0; 235 data->chain_signal_a = 0; 236 data->chain_signal_b = 0; 237 data->chain_signal_c = 0; 238 data->beacon_count = 0; 239} 240 241 242static void iwl5000_chain_noise_reset(struct iwl_priv *priv) 243{ 244 struct iwl_chain_noise_data *data = &priv->chain_noise_data; 245 246 if ((data->state == IWL_CHAIN_NOISE_ALIVE) && iwl_is_associated(priv)) { 247 struct iwl5000_calibration_chain_noise_reset_cmd cmd; 248 249 memset(&cmd, 0, sizeof(cmd)); 250 cmd.op_code = IWL5000_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD; 251 if (iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD, 252 sizeof(cmd), &cmd)) 253 IWL_ERROR("Could not send REPLY_PHY_CALIBRATION_CMD\n"); 254 data->state = IWL_CHAIN_NOISE_ACCUMULATE; 255 IWL_DEBUG_CALIB("Run chain_noise_calibrate\n"); 256 } 257} 258 259static struct iwl_sensitivity_ranges iwl5000_sensitivity = { 260 .min_nrg_cck = 95, 261 .max_nrg_cck = 0, 262 .auto_corr_min_ofdm = 90, 263 .auto_corr_min_ofdm_mrc = 170, 264 .auto_corr_min_ofdm_x1 = 120, 265 .auto_corr_min_ofdm_mrc_x1 = 240, 266 267 .auto_corr_max_ofdm = 120, 268 .auto_corr_max_ofdm_mrc = 210, 269 .auto_corr_max_ofdm_x1 = 155, 270 .auto_corr_max_ofdm_mrc_x1 = 290, 271 272 .auto_corr_min_cck = 125, 273 .auto_corr_max_cck = 200, 274 .auto_corr_min_cck_mrc = 170, 275 .auto_corr_max_cck_mrc = 400, 276 .nrg_th_cck = 95, 277 .nrg_th_ofdm = 95, 278}; 279 280#endif /* CONFIG_IWL5000_RUN_TIME_CALIB */ 281 282static const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv, 283 size_t offset) 284{ 285 u32 address = eeprom_indirect_address(priv, offset); 286 BUG_ON(address >= priv->cfg->eeprom_size); 287 return &priv->eeprom[address]; 288} 289 290/* 291 * ucode 292 */ 293static int iwl5000_load_section(struct iwl_priv *priv, 294 struct fw_desc *image, 295 u32 dst_addr) 296{ 297 int ret = 0; 298 unsigned long flags; 299 300 dma_addr_t phy_addr = image->p_addr; 301 u32 byte_cnt = image->len; 302 303 spin_lock_irqsave(&priv->lock, flags); 304 ret = iwl_grab_nic_access(priv); 305 if (ret) { 306 spin_unlock_irqrestore(&priv->lock, flags); 307 return ret; 308 } 309 310 iwl_write_direct32(priv, 311 FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), 312 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE); 313 314 iwl_write_direct32(priv, 315 FH_SRVC_CHNL_SRAM_ADDR_REG(FH_SRVC_CHNL), dst_addr); 316 317 iwl_write_direct32(priv, 318 FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL), 319 phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK); 320 321 /* FIME: write the MSB of the phy_addr in CTRL1 322 * iwl_write_direct32(priv, 323 IWL_FH_TFDIB_CTRL1_REG(IWL_FH_SRVC_CHNL), 324 ((phy_addr & MSB_MSK) 325 << FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_count); 326 */ 327 iwl_write_direct32(priv, 328 FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL), byte_cnt); 329 iwl_write_direct32(priv, 330 FH_TCSR_CHNL_TX_BUF_STS_REG(FH_SRVC_CHNL), 331 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM | 332 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX | 333 FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID); 334 335 iwl_write_direct32(priv, 336 FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), 337 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | 338 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE_VAL | 339 FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); 340 341 iwl_release_nic_access(priv); 342 spin_unlock_irqrestore(&priv->lock, flags); 343 return 0; 344} 345 346static int iwl5000_load_given_ucode(struct iwl_priv *priv, 347 struct fw_desc *inst_image, 348 struct fw_desc *data_image) 349{ 350 int ret = 0; 351 352 ret = iwl5000_load_section( 353 priv, inst_image, RTC_INST_LOWER_BOUND); 354 if (ret) 355 return ret; 356 357 IWL_DEBUG_INFO("INST uCode section being loaded...\n"); 358 ret = wait_event_interruptible_timeout(priv->wait_command_queue, 359 priv->ucode_write_complete, 5 * HZ); 360 if (ret == -ERESTARTSYS) { 361 IWL_ERROR("Could not load the INST uCode section due " 362 "to interrupt\n"); 363 return ret; 364 } 365 if (!ret) { 366 IWL_ERROR("Could not load the INST uCode section\n"); 367 return -ETIMEDOUT; 368 } 369 370 priv->ucode_write_complete = 0; 371 372 ret = iwl5000_load_section( 373 priv, data_image, RTC_DATA_LOWER_BOUND); 374 if (ret) 375 return ret; 376 377 IWL_DEBUG_INFO("DATA uCode section being loaded...\n"); 378 379 ret = wait_event_interruptible_timeout(priv->wait_command_queue, 380 priv->ucode_write_complete, 5 * HZ); 381 if (ret == -ERESTARTSYS) { 382 IWL_ERROR("Could not load the INST uCode section due " 383 "to interrupt\n"); 384 return ret; 385 } else if (!ret) { 386 IWL_ERROR("Could not load the DATA uCode section\n"); 387 return -ETIMEDOUT; 388 } else 389 ret = 0; 390 391 priv->ucode_write_complete = 0; 392 393 return ret; 394} 395 396static int iwl5000_load_ucode(struct iwl_priv *priv) 397{ 398 int ret = 0; 399 400 /* check whether init ucode should be loaded, or rather runtime ucode */ 401 if (priv->ucode_init.len && (priv->ucode_type == UCODE_NONE)) { 402 IWL_DEBUG_INFO("Init ucode found. Loading init ucode...\n"); 403 ret = iwl5000_load_given_ucode(priv, 404 &priv->ucode_init, &priv->ucode_init_data); 405 if (!ret) { 406 IWL_DEBUG_INFO("Init ucode load complete.\n"); 407 priv->ucode_type = UCODE_INIT; 408 } 409 } else { 410 IWL_DEBUG_INFO("Init ucode not found, or already loaded. " 411 "Loading runtime ucode...\n"); 412 ret = iwl5000_load_given_ucode(priv, 413 &priv->ucode_code, &priv->ucode_data); 414 if (!ret) { 415 IWL_DEBUG_INFO("Runtime ucode load complete.\n"); 416 priv->ucode_type = UCODE_RT; 417 } 418 } 419 420 return ret; 421} 422 423static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) 424{ 425 if ((priv->cfg->mod_params->num_of_queues > IWL50_NUM_QUEUES) || 426 (priv->cfg->mod_params->num_of_queues < IWL_MIN_NUM_QUEUES)) { 427 IWL_ERROR("invalid queues_num, should be between %d and %d\n", 428 IWL_MIN_NUM_QUEUES, IWL50_NUM_QUEUES); 429 return -EINVAL; 430 } 431 432 priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues; 433 priv->hw_params.sw_crypto = priv->cfg->mod_params->sw_crypto; 434 priv->hw_params.max_rxq_size = RX_QUEUE_SIZE; 435 priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG; 436 if (priv->cfg->mod_params->amsdu_size_8K) 437 priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_8K; 438 else 439 priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_4K; 440 priv->hw_params.max_pkt_size = priv->hw_params.rx_buf_size - 256; 441 priv->hw_params.max_stations = IWL5000_STATION_COUNT; 442 priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID; 443 priv->hw_params.max_data_size = IWL50_RTC_DATA_SIZE; 444 priv->hw_params.max_inst_size = IWL50_RTC_INST_SIZE; 445 priv->hw_params.max_bsm_size = BSM_SRAM_SIZE; 446 priv->hw_params.fat_channel = BIT(IEEE80211_BAND_2GHZ) | 447 BIT(IEEE80211_BAND_5GHZ); 448#ifdef CONFIG_IWL5000_RUN_TIME_CALIB 449 priv->hw_params.sens = &iwl5000_sensitivity; 450#endif 451 452 switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) { 453 case CSR_HW_REV_TYPE_5100: 454 case CSR_HW_REV_TYPE_5150: 455 priv->hw_params.tx_chains_num = 1; 456 priv->hw_params.rx_chains_num = 2; 457 /* FIXME: move to ANT_A, ANT_B, ANT_C enum */ 458 priv->hw_params.valid_tx_ant = ANT_A; 459 priv->hw_params.valid_rx_ant = ANT_AB; 460 break; 461 case CSR_HW_REV_TYPE_5300: 462 case CSR_HW_REV_TYPE_5350: 463 priv->hw_params.tx_chains_num = 3; 464 priv->hw_params.rx_chains_num = 3; 465 priv->hw_params.valid_tx_ant = ANT_ABC; 466 priv->hw_params.valid_rx_ant = ANT_ABC; 467 break; 468 } 469 470 switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) { 471 case CSR_HW_REV_TYPE_5100: 472 case CSR_HW_REV_TYPE_5300: 473 /* 5X00 wants in Celsius */ 474 priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD; 475 break; 476 case CSR_HW_REV_TYPE_5150: 477 case CSR_HW_REV_TYPE_5350: 478 /* 5X50 wants in Kelvin */ 479 priv->hw_params.ct_kill_threshold = 480 CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD); 481 break; 482 } 483 484 return 0; 485} 486 487static int iwl5000_alloc_shared_mem(struct iwl_priv *priv) 488{ 489 priv->shared_virt = pci_alloc_consistent(priv->pci_dev, 490 sizeof(struct iwl5000_shared), 491 &priv->shared_phys); 492 if (!priv->shared_virt) 493 return -ENOMEM; 494 495 memset(priv->shared_virt, 0, sizeof(struct iwl5000_shared)); 496 497 priv->rb_closed_offset = offsetof(struct iwl5000_shared, rb_closed); 498 499 return 0; 500} 501 502static void iwl5000_free_shared_mem(struct iwl_priv *priv) 503{ 504 if (priv->shared_virt) 505 pci_free_consistent(priv->pci_dev, 506 sizeof(struct iwl5000_shared), 507 priv->shared_virt, 508 priv->shared_phys); 509} 510 511static int iwl5000_shared_mem_rx_idx(struct iwl_priv *priv) 512{ 513 struct iwl5000_shared *s = priv->shared_virt; 514 return le32_to_cpu(s->rb_closed) & 0xFFF; 515} 516 517/** 518 * iwl5000_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array 519 */ 520static void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv, 521 struct iwl_tx_queue *txq, 522 u16 byte_cnt) 523{ 524 struct iwl5000_shared *shared_data = priv->shared_virt; 525 int txq_id = txq->q.id; 526 u8 sec_ctl = 0; 527 u8 sta = 0; 528 int len; 529 530 len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE; 531 532 if (txq_id != IWL_CMD_QUEUE_NUM) { 533 sta = txq->cmd[txq->q.write_ptr].cmd.tx.sta_id; 534 sec_ctl = txq->cmd[txq->q.write_ptr].cmd.tx.sec_ctl; 535 536 switch (sec_ctl & TX_CMD_SEC_MSK) { 537 case TX_CMD_SEC_CCM: 538 len += CCMP_MIC_LEN; 539 break; 540 case TX_CMD_SEC_TKIP: 541 len += TKIP_ICV_LEN; 542 break; 543 case TX_CMD_SEC_WEP: 544 len += WEP_IV_LEN + WEP_ICV_LEN; 545 break; 546 } 547 } 548 549 IWL_SET_BITS16(shared_data->queues_byte_cnt_tbls[txq_id]. 550 tfd_offset[txq->q.write_ptr], byte_cnt, len); 551 552 IWL_SET_BITS16(shared_data->queues_byte_cnt_tbls[txq_id]. 553 tfd_offset[txq->q.write_ptr], sta_id, sta); 554 555 if (txq->q.write_ptr < IWL50_MAX_WIN_SIZE) { 556 IWL_SET_BITS16(shared_data->queues_byte_cnt_tbls[txq_id]. 557 tfd_offset[IWL50_QUEUE_SIZE + txq->q.write_ptr], 558 byte_cnt, len); 559 IWL_SET_BITS16(shared_data->queues_byte_cnt_tbls[txq_id]. 560 tfd_offset[IWL50_QUEUE_SIZE + txq->q.write_ptr], 561 sta_id, sta); 562 } 563} 564 565static u16 iwl5000_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) 566{ 567 u16 size = (u16)sizeof(struct iwl_addsta_cmd); 568 memcpy(data, cmd, size); 569 return size; 570} 571 572 573static int iwl5000_disable_tx_fifo(struct iwl_priv *priv) 574{ 575 unsigned long flags; 576 int ret; 577 578 spin_lock_irqsave(&priv->lock, flags); 579 580 ret = iwl_grab_nic_access(priv); 581 if (unlikely(ret)) { 582 IWL_ERROR("Tx fifo reset failed"); 583 spin_unlock_irqrestore(&priv->lock, flags); 584 return ret; 585 } 586 587 iwl_write_prph(priv, IWL50_SCD_TXFACT, 0); 588 iwl_release_nic_access(priv); 589 spin_unlock_irqrestore(&priv->lock, flags); 590 591 return 0; 592} 593 594/* Currently 5000 is the supperset of everything */ 595static u16 iwl5000_get_hcmd_size(u8 cmd_id, u16 len) 596{ 597 return len; 598} 599 600static void iwl5000_rx_handler_setup(struct iwl_priv *priv) 601{ 602} 603 604static struct iwl_hcmd_ops iwl5000_hcmd = { 605}; 606 607static struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = { 608 .get_hcmd_size = iwl5000_get_hcmd_size, 609 .build_addsta_hcmd = iwl5000_build_addsta_hcmd, 610#ifdef CONFIG_IWL5000_RUN_TIME_CALIB 611 .gain_computation = iwl5000_gain_computation, 612 .chain_noise_reset = iwl5000_chain_noise_reset, 613#endif 614}; 615 616static struct iwl_lib_ops iwl5000_lib = { 617 .set_hw_params = iwl5000_hw_set_hw_params, 618 .alloc_shared_mem = iwl5000_alloc_shared_mem, 619 .free_shared_mem = iwl5000_free_shared_mem, 620 .shared_mem_rx_idx = iwl5000_shared_mem_rx_idx, 621 .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl, 622 .disable_tx_fifo = iwl5000_disable_tx_fifo, 623 .rx_handler_setup = iwl5000_rx_handler_setup, 624 .load_ucode = iwl5000_load_ucode, 625 .apm_ops = { 626 .init = iwl5000_apm_init, 627 .config = iwl5000_nic_config, 628 .set_pwr_src = iwl4965_set_pwr_src, 629 }, 630 .eeprom_ops = { 631 .regulatory_bands = { 632 EEPROM_5000_REG_BAND_1_CHANNELS, 633 EEPROM_5000_REG_BAND_2_CHANNELS, 634 EEPROM_5000_REG_BAND_3_CHANNELS, 635 EEPROM_5000_REG_BAND_4_CHANNELS, 636 EEPROM_5000_REG_BAND_5_CHANNELS, 637 EEPROM_5000_REG_BAND_24_FAT_CHANNELS, 638 EEPROM_5000_REG_BAND_52_FAT_CHANNELS 639 }, 640 .verify_signature = iwlcore_eeprom_verify_signature, 641 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, 642 .release_semaphore = iwlcore_eeprom_release_semaphore, 643 .check_version = iwl5000_eeprom_check_version, 644 .query_addr = iwl5000_eeprom_query_addr, 645 }, 646}; 647 648static struct iwl_ops iwl5000_ops = { 649 .lib = &iwl5000_lib, 650 .hcmd = &iwl5000_hcmd, 651 .utils = &iwl5000_hcmd_utils, 652}; 653 654static struct iwl_mod_params iwl50_mod_params = { 655 .num_of_queues = IWL50_NUM_QUEUES, 656 .enable_qos = 1, 657 .amsdu_size_8K = 1, 658 .restart_fw = 1, 659 /* the rest are 0 by default */ 660}; 661 662 663struct iwl_cfg iwl5300_agn_cfg = { 664 .name = "5300AGN", 665 .fw_name = "iwlwifi-5000" IWL5000_UCODE_API ".ucode", 666 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, 667 .ops = &iwl5000_ops, 668 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 669 .mod_params = &iwl50_mod_params, 670}; 671 672struct iwl_cfg iwl5100_agn_cfg = { 673 .name = "5100AGN", 674 .fw_name = "iwlwifi-5000" IWL5000_UCODE_API ".ucode", 675 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, 676 .ops = &iwl5000_ops, 677 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 678 .mod_params = &iwl50_mod_params, 679}; 680 681struct iwl_cfg iwl5350_agn_cfg = { 682 .name = "5350AGN", 683 .fw_name = "iwlwifi-5000" IWL5000_UCODE_API ".ucode", 684 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, 685 .ops = &iwl5000_ops, 686 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 687 .mod_params = &iwl50_mod_params, 688}; 689 690module_param_named(disable50, iwl50_mod_params.disable, int, 0444); 691MODULE_PARM_DESC(disable50, 692 "manually disable the 50XX radio (default 0 [radio on])"); 693module_param_named(swcrypto50, iwl50_mod_params.sw_crypto, bool, 0444); 694MODULE_PARM_DESC(swcrypto50, 695 "using software crypto engine (default 0 [hardware])\n"); 696module_param_named(debug50, iwl50_mod_params.debug, int, 0444); 697MODULE_PARM_DESC(debug50, "50XX debug output mask"); 698module_param_named(queues_num50, iwl50_mod_params.num_of_queues, int, 0444); 699MODULE_PARM_DESC(queues_num50, "number of hw queues in 50xx series"); 700module_param_named(qos_enable50, iwl50_mod_params.enable_qos, int, 0444); 701MODULE_PARM_DESC(qos_enable50, "enable all 50XX QoS functionality"); 702module_param_named(amsdu_size_8K50, iwl50_mod_params.amsdu_size_8K, int, 0444); 703MODULE_PARM_DESC(amsdu_size_8K50, "enable 8K amsdu size in 50XX series"); 704module_param_named(fw_restart50, iwl50_mod_params.restart_fw, int, 0444); 705MODULE_PARM_DESC(fw_restart50, "restart firmware in case of error"); 706