aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-4965.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-12-28 15:49:40 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2008-12-28 15:49:40 -0500
commit0191b625ca5a46206d2fb862bb08f36f2fcb3b31 (patch)
tree454d1842b1833d976da62abcbd5c47521ebe9bd7 /drivers/net/wireless/iwlwifi/iwl-4965.c
parent54a696bd07c14d3b1192d03ce7269bc59b45209a (diff)
parenteb56092fc168bf5af199d47af50c0d84a96db898 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1429 commits) net: Allow dependancies of FDDI & Tokenring to be modular. igb: Fix build warning when DCA is disabled. net: Fix warning fallout from recent NAPI interface changes. gro: Fix potential use after free sfc: If AN is enabled, always read speed/duplex from the AN advertising bits sfc: When disabling the NIC, close the device rather than unregistering it sfc: SFT9001: Add cable diagnostics sfc: Add support for multiple PHY self-tests sfc: Merge top-level functions for self-tests sfc: Clean up PHY mode management in loopback self-test sfc: Fix unreliable link detection in some loopback modes sfc: Generate unique names for per-NIC workqueues 802.3ad: use standard ethhdr instead of ad_header 802.3ad: generalize out mac address initializer 802.3ad: initialize ports LACPDU from const initializer 802.3ad: remove typedef around ad_system 802.3ad: turn ports is_individual into a bool 802.3ad: turn ports is_enabled into a bool 802.3ad: make ntt bool ixgbe: Fix set_ringparam in ixgbe to use the same memory pools. ... Fixed trivial IPv4/6 address printing conflicts in fs/cifs/connect.c due to the conversion to %pI (in this networking merge) and the addition of doing IPv6 addresses (from the earlier merge of CIFS).
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-4965.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c251
1 files changed, 102 insertions, 149 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 9838de5f4369..5a72bc0377de 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -19,7 +19,7 @@
19 * file called LICENSE. 19 * file called LICENSE.
20 * 20 *
21 * Contact Information: 21 * Contact Information:
22 * James P. Ketrenos <ipw2100-admin@linux.intel.com> 22 * Intel Linux Wireless <ilw@linux.intel.com>
23 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 23 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24 * 24 *
25 *****************************************************************************/ 25 *****************************************************************************/
@@ -48,18 +48,21 @@
48static int iwl4965_send_tx_power(struct iwl_priv *priv); 48static int iwl4965_send_tx_power(struct iwl_priv *priv);
49static int iwl4965_hw_get_temperature(const struct iwl_priv *priv); 49static int iwl4965_hw_get_temperature(const struct iwl_priv *priv);
50 50
51/* Change firmware file name, using "-" and incrementing number, 51/* Highest firmware API version supported */
52 * *only* when uCode interface or architecture changes so that it 52#define IWL4965_UCODE_API_MAX 2
53 * is not compatible with earlier drivers. 53
54 * This number will also appear in << 8 position of 1st dword of uCode file */ 54/* Lowest firmware API version supported */
55#define IWL4965_UCODE_API "-2" 55#define IWL4965_UCODE_API_MIN 2
56
57#define IWL4965_FW_PRE "iwlwifi-4965-"
58#define _IWL4965_MODULE_FIRMWARE(api) IWL4965_FW_PRE #api ".ucode"
59#define IWL4965_MODULE_FIRMWARE(api) _IWL4965_MODULE_FIRMWARE(api)
56 60
57 61
58/* module parameters */ 62/* module parameters */
59static struct iwl_mod_params iwl4965_mod_params = { 63static struct iwl_mod_params iwl4965_mod_params = {
60 .num_of_queues = IWL49_NUM_QUEUES, 64 .num_of_queues = IWL49_NUM_QUEUES,
61 .num_of_ampdu_queues = IWL49_NUM_AMPDU_QUEUES, 65 .num_of_ampdu_queues = IWL49_NUM_AMPDU_QUEUES,
62 .enable_qos = 1,
63 .amsdu_size_8K = 1, 66 .amsdu_size_8K = 1,
64 .restart_fw = 1, 67 .restart_fw = 1,
65 /* the rest are 0 by default */ 68 /* the rest are 0 by default */
@@ -246,7 +249,7 @@ static int iwl4965_set_ucode_ptrs(struct iwl_priv *priv)
246 iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, 249 iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG,
247 priv->ucode_data.len); 250 priv->ucode_data.len);
248 251
249 /* Inst bytecount must be last to set up, bit 31 signals uCode 252 /* Inst byte count must be last to set up, bit 31 signals uCode
250 * that all new ptr/size info is in place */ 253 * that all new ptr/size info is in place */
251 iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, 254 iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG,
252 priv->ucode_code.len | BSM_DRAM_INST_LOAD); 255 priv->ucode_code.len | BSM_DRAM_INST_LOAD);
@@ -318,31 +321,13 @@ static int is_fat_channel(__le32 rxon_flags)
318/* 321/*
319 * EEPROM handlers 322 * EEPROM handlers
320 */ 323 */
321 324static u16 iwl4965_eeprom_calib_version(struct iwl_priv *priv)
322static int iwl4965_eeprom_check_version(struct iwl_priv *priv)
323{ 325{
324 u16 eeprom_ver; 326 return iwl_eeprom_query16(priv, EEPROM_4965_CALIB_VERSION_OFFSET);
325 u16 calib_ver;
326
327 eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
328
329 calib_ver = iwl_eeprom_query16(priv, EEPROM_4965_CALIB_VERSION_OFFSET);
330
331 if (eeprom_ver < EEPROM_4965_EEPROM_VERSION ||
332 calib_ver < EEPROM_4965_TX_POWER_VERSION)
333 goto err;
334
335 return 0;
336err:
337 IWL_ERROR("Unsuported EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n",
338 eeprom_ver, EEPROM_4965_EEPROM_VERSION,
339 calib_ver, EEPROM_4965_TX_POWER_VERSION);
340 return -EINVAL;
341
342} 327}
343 328
344/* 329/*
345 * Activate/Deactivat Tx DMA/FIFO channels according tx fifos mask 330 * Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask
346 * must be called under priv->lock and mac access 331 * must be called under priv->lock and mac access
347 */ 332 */
348static void iwl4965_txq_set_sched(struct iwl_priv *priv, u32 mask) 333static void iwl4965_txq_set_sched(struct iwl_priv *priv, u32 mask)
@@ -366,9 +351,8 @@ static int iwl4965_apm_init(struct iwl_priv *priv)
366 iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); 351 iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
367 352
368 /* wait for clock stabilization */ 353 /* wait for clock stabilization */
369 ret = iwl_poll_bit(priv, CSR_GP_CNTRL, 354 ret = iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
370 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 355 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
371 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
372 if (ret < 0) { 356 if (ret < 0) {
373 IWL_DEBUG_INFO("Failed to init the card\n"); 357 IWL_DEBUG_INFO("Failed to init the card\n");
374 goto out; 358 goto out;
@@ -414,7 +398,7 @@ static void iwl4965_nic_config(struct iwl_priv *priv)
414 398
415 /* L1 is enabled by BIOS */ 399 /* L1 is enabled by BIOS */
416 if ((link & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN) 400 if ((link & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN)
417 /* diable L0S disabled L1A enabled */ 401 /* disable L0S disabled L1A enabled */
418 iwl_set_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); 402 iwl_set_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
419 else 403 else
420 /* L0S enabled L1A disabled */ 404 /* L0S enabled L1A disabled */
@@ -442,7 +426,6 @@ static void iwl4965_nic_config(struct iwl_priv *priv)
442 426
443static int iwl4965_apm_stop_master(struct iwl_priv *priv) 427static int iwl4965_apm_stop_master(struct iwl_priv *priv)
444{ 428{
445 int ret = 0;
446 unsigned long flags; 429 unsigned long flags;
447 430
448 spin_lock_irqsave(&priv->lock, flags); 431 spin_lock_irqsave(&priv->lock, flags);
@@ -450,17 +433,13 @@ static int iwl4965_apm_stop_master(struct iwl_priv *priv)
450 /* set stop master bit */ 433 /* set stop master bit */
451 iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER); 434 iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
452 435
453 ret = iwl_poll_bit(priv, CSR_RESET, 436 iwl_poll_direct_bit(priv, CSR_RESET,
454 CSR_RESET_REG_FLAG_MASTER_DISABLED, 437 CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
455 CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
456 if (ret < 0)
457 goto out;
458 438
459out:
460 spin_unlock_irqrestore(&priv->lock, flags); 439 spin_unlock_irqrestore(&priv->lock, flags);
461 IWL_DEBUG_INFO("stop master\n"); 440 IWL_DEBUG_INFO("stop master\n");
462 441
463 return ret; 442 return 0;
464} 443}
465 444
466static void iwl4965_apm_stop(struct iwl_priv *priv) 445static void iwl4965_apm_stop(struct iwl_priv *priv)
@@ -496,11 +475,9 @@ static int iwl4965_apm_reset(struct iwl_priv *priv)
496 475
497 iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); 476 iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
498 477
499 ret = iwl_poll_bit(priv, CSR_RESET, 478 ret = iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
500 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 479 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
501 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25); 480 if (ret < 0)
502
503 if (ret)
504 goto out; 481 goto out;
505 482
506 udelay(10); 483 udelay(10);
@@ -537,10 +514,10 @@ static void iwl4965_chain_noise_reset(struct iwl_priv *priv)
537 struct iwl_chain_noise_data *data = &(priv->chain_noise_data); 514 struct iwl_chain_noise_data *data = &(priv->chain_noise_data);
538 515
539 if ((data->state == IWL_CHAIN_NOISE_ALIVE) && iwl_is_associated(priv)) { 516 if ((data->state == IWL_CHAIN_NOISE_ALIVE) && iwl_is_associated(priv)) {
540 struct iwl4965_calibration_cmd cmd; 517 struct iwl_calib_diff_gain_cmd cmd;
541 518
542 memset(&cmd, 0, sizeof(cmd)); 519 memset(&cmd, 0, sizeof(cmd));
543 cmd.opCode = PHY_CALIBRATE_DIFF_GAIN_CMD; 520 cmd.hdr.op_code = IWL_PHY_CALIBRATE_DIFF_GAIN_CMD;
544 cmd.diff_gain_a = 0; 521 cmd.diff_gain_a = 0;
545 cmd.diff_gain_b = 0; 522 cmd.diff_gain_b = 0;
546 cmd.diff_gain_c = 0; 523 cmd.diff_gain_c = 0;
@@ -587,11 +564,11 @@ static void iwl4965_gain_computation(struct iwl_priv *priv,
587 564
588 /* Differential gain gets sent to uCode only once */ 565 /* Differential gain gets sent to uCode only once */
589 if (!data->radio_write) { 566 if (!data->radio_write) {
590 struct iwl4965_calibration_cmd cmd; 567 struct iwl_calib_diff_gain_cmd cmd;
591 data->radio_write = 1; 568 data->radio_write = 1;
592 569
593 memset(&cmd, 0, sizeof(cmd)); 570 memset(&cmd, 0, sizeof(cmd));
594 cmd.opCode = PHY_CALIBRATE_DIFF_GAIN_CMD; 571 cmd.hdr.op_code = IWL_PHY_CALIBRATE_DIFF_GAIN_CMD;
595 cmd.diff_gain_a = data->delta_gain_code[0]; 572 cmd.diff_gain_a = data->delta_gain_code[0];
596 cmd.diff_gain_b = data->delta_gain_code[1]; 573 cmd.diff_gain_b = data->delta_gain_code[1];
597 cmd.diff_gain_c = data->delta_gain_code[2]; 574 cmd.diff_gain_c = data->delta_gain_code[2];
@@ -619,10 +596,10 @@ static void iwl4965_gain_computation(struct iwl_priv *priv,
619static void iwl4965_rts_tx_cmd_flag(struct ieee80211_tx_info *info, 596static void iwl4965_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
620 __le32 *tx_flags) 597 __le32 *tx_flags)
621{ 598{
622 if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) { 599 if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) {
623 *tx_flags |= TX_CMD_FLG_RTS_MSK; 600 *tx_flags |= TX_CMD_FLG_RTS_MSK;
624 *tx_flags &= ~TX_CMD_FLG_CTS_MSK; 601 *tx_flags &= ~TX_CMD_FLG_CTS_MSK;
625 } else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) { 602 } else if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
626 *tx_flags &= ~TX_CMD_FLG_RTS_MSK; 603 *tx_flags &= ~TX_CMD_FLG_RTS_MSK;
627 *tx_flags |= TX_CMD_FLG_CTS_MSK; 604 *tx_flags |= TX_CMD_FLG_CTS_MSK;
628 } 605 }
@@ -643,7 +620,7 @@ static void iwl4965_bg_txpower_work(struct work_struct *work)
643 620
644 mutex_lock(&priv->mutex); 621 mutex_lock(&priv->mutex);
645 622
646 /* Regardless of if we are assocaited, we must reconfigure the 623 /* Regardless of if we are associated, we must reconfigure the
647 * TX power since frames can be sent on non-radar channels while 624 * TX power since frames can be sent on non-radar channels while
648 * not associated */ 625 * not associated */
649 iwl4965_send_tx_power(priv); 626 iwl4965_send_tx_power(priv);
@@ -679,7 +656,7 @@ static void iwl4965_tx_queue_set_status(struct iwl_priv *priv,
679 int txq_id = txq->q.id; 656 int txq_id = txq->q.id;
680 657
681 /* Find out whether to activate Tx queue */ 658 /* Find out whether to activate Tx queue */
682 int active = test_bit(txq_id, &priv->txq_ctx_active_msk)?1:0; 659 int active = test_bit(txq_id, &priv->txq_ctx_active_msk) ? 1 : 0;
683 660
684 /* Set up and activate */ 661 /* Set up and activate */
685 iwl_write_prph(priv, IWL49_SCD_QUEUE_STATUS_BITS(txq_id), 662 iwl_write_prph(priv, IWL49_SCD_QUEUE_STATUS_BITS(txq_id),
@@ -709,9 +686,10 @@ static const u16 default_queue_to_tx_fifo[] = {
709static int iwl4965_alive_notify(struct iwl_priv *priv) 686static int iwl4965_alive_notify(struct iwl_priv *priv)
710{ 687{
711 u32 a; 688 u32 a;
712 int i = 0;
713 unsigned long flags; 689 unsigned long flags;
714 int ret; 690 int ret;
691 int i, chan;
692 u32 reg_val;
715 693
716 spin_lock_irqsave(&priv->lock, flags); 694 spin_lock_irqsave(&priv->lock, flags);
717 695
@@ -733,8 +711,18 @@ static int iwl4965_alive_notify(struct iwl_priv *priv)
733 711
734 /* Tel 4965 where to find Tx byte count tables */ 712 /* Tel 4965 where to find Tx byte count tables */
735 iwl_write_prph(priv, IWL49_SCD_DRAM_BASE_ADDR, 713 iwl_write_prph(priv, IWL49_SCD_DRAM_BASE_ADDR,
736 (priv->shared_phys + 714 priv->scd_bc_tbls.dma >> 10);
737 offsetof(struct iwl4965_shared, queues_byte_cnt_tbls)) >> 10); 715
716 /* Enable DMA channel */
717 for (chan = 0; chan < FH49_TCSR_CHNL_NUM ; chan++)
718 iwl_write_direct32(priv, FH_TCSR_CHNL_TX_CONFIG_REG(chan),
719 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
720 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE);
721
722 /* Update FH chicken bits */
723 reg_val = iwl_read_direct32(priv, FH_TX_CHICKEN_BITS_REG);
724 iwl_write_direct32(priv, FH_TX_CHICKEN_BITS_REG,
725 reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN);
738 726
739 /* Disable chain mode for all queues */ 727 /* Disable chain mode for all queues */
740 iwl_write_prph(priv, IWL49_SCD_QUEUECHAIN_SEL, 0); 728 iwl_write_prph(priv, IWL49_SCD_QUEUECHAIN_SEL, 0);
@@ -766,7 +754,7 @@ static int iwl4965_alive_notify(struct iwl_priv *priv)
766 (1 << priv->hw_params.max_txq_num) - 1); 754 (1 << priv->hw_params.max_txq_num) - 1);
767 755
768 /* Activate all Tx DMA/FIFO channels */ 756 /* Activate all Tx DMA/FIFO channels */
769 priv->cfg->ops->lib->txq_set_sched(priv, IWL_MASK(0, 7)); 757 priv->cfg->ops->lib->txq_set_sched(priv, IWL_MASK(0, 6));
770 758
771 iwl4965_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0); 759 iwl4965_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0);
772 760
@@ -822,7 +810,9 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
822 } 810 }
823 811
824 priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues; 812 priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues;
825 priv->hw_params.first_ampdu_q = IWL49_FIRST_AMPDU_QUEUE; 813 priv->hw_params.dma_chnl_num = FH49_TCSR_CHNL_NUM;
814 priv->hw_params.scd_bc_tbls_size =
815 IWL49_NUM_QUEUES * sizeof(struct iwl4965_scd_bc_tbl);
826 priv->hw_params.max_stations = IWL4965_STATION_COUNT; 816 priv->hw_params.max_stations = IWL4965_STATION_COUNT;
827 priv->hw_params.bcast_sta_id = IWL4965_BROADCAST_ID; 817 priv->hw_params.bcast_sta_id = IWL4965_BROADCAST_ID;
828 priv->hw_params.max_data_size = IWL49_RTC_DATA_SIZE; 818 priv->hw_params.max_data_size = IWL49_RTC_DATA_SIZE;
@@ -1650,36 +1640,6 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel)
1650} 1640}
1651#endif 1641#endif
1652 1642
1653static int iwl4965_shared_mem_rx_idx(struct iwl_priv *priv)
1654{
1655 struct iwl4965_shared *s = priv->shared_virt;
1656 return le32_to_cpu(s->rb_closed) & 0xFFF;
1657}
1658
1659static int iwl4965_alloc_shared_mem(struct iwl_priv *priv)
1660{
1661 priv->shared_virt = pci_alloc_consistent(priv->pci_dev,
1662 sizeof(struct iwl4965_shared),
1663 &priv->shared_phys);
1664 if (!priv->shared_virt)
1665 return -ENOMEM;
1666
1667 memset(priv->shared_virt, 0, sizeof(struct iwl4965_shared));
1668
1669 priv->rb_closed_offset = offsetof(struct iwl4965_shared, rb_closed);
1670
1671 return 0;
1672}
1673
1674static void iwl4965_free_shared_mem(struct iwl_priv *priv)
1675{
1676 if (priv->shared_virt)
1677 pci_free_consistent(priv->pci_dev,
1678 sizeof(struct iwl4965_shared),
1679 priv->shared_virt,
1680 priv->shared_phys);
1681}
1682
1683/** 1643/**
1684 * iwl4965_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array 1644 * iwl4965_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array
1685 */ 1645 */
@@ -1687,21 +1647,22 @@ static void iwl4965_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
1687 struct iwl_tx_queue *txq, 1647 struct iwl_tx_queue *txq,
1688 u16 byte_cnt) 1648 u16 byte_cnt)
1689{ 1649{
1690 int len; 1650 struct iwl4965_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr;
1691 int txq_id = txq->q.id; 1651 int txq_id = txq->q.id;
1692 struct iwl4965_shared *shared_data = priv->shared_virt; 1652 int write_ptr = txq->q.write_ptr;
1653 int len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE;
1654 __le16 bc_ent;
1693 1655
1694 len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE; 1656 WARN_ON(len > 0xFFF || write_ptr >= TFD_QUEUE_SIZE_MAX);
1695 1657
1658 bc_ent = cpu_to_le16(len & 0xFFF);
1696 /* Set up byte count within first 256 entries */ 1659 /* Set up byte count within first 256 entries */
1697 IWL_SET_BITS16(shared_data->queues_byte_cnt_tbls[txq_id]. 1660 scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent;
1698 tfd_offset[txq->q.write_ptr], byte_cnt, len);
1699 1661
1700 /* If within first 64 entries, duplicate at end */ 1662 /* If within first 64 entries, duplicate at end */
1701 if (txq->q.write_ptr < IWL49_MAX_WIN_SIZE) 1663 if (write_ptr < TFD_QUEUE_SIZE_BC_DUP)
1702 IWL_SET_BITS16(shared_data->queues_byte_cnt_tbls[txq_id]. 1664 scd_bc_tbl[txq_id].
1703 tfd_offset[IWL49_QUEUE_SIZE + txq->q.write_ptr], 1665 tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent;
1704 byte_cnt, len);
1705} 1666}
1706 1667
1707/** 1668/**
@@ -1956,7 +1917,7 @@ static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id,
1956 ra_tid = BUILD_RAxTID(sta_id, tid); 1917 ra_tid = BUILD_RAxTID(sta_id, tid);
1957 1918
1958 /* Modify device's station table to Tx this TID */ 1919 /* Modify device's station table to Tx this TID */
1959 iwl_sta_modify_enable_tid_tx(priv, sta_id, tid); 1920 iwl_sta_tx_modify_enable_tid(priv, sta_id, tid);
1960 1921
1961 spin_lock_irqsave(&priv->lock, flags); 1922 spin_lock_irqsave(&priv->lock, flags);
1962 ret = iwl_grab_nic_access(priv); 1923 ret = iwl_grab_nic_access(priv);
@@ -2037,7 +1998,7 @@ static inline u32 iwl4965_get_scd_ssn(struct iwl4965_tx_resp *tx_resp)
2037} 1998}
2038 1999
2039/** 2000/**
2040 * iwl4965_tx_status_reply_tx - Handle Tx rspnse for frames in aggregation queue 2001 * iwl4965_tx_status_reply_tx - Handle Tx response for frames in aggregation queue
2041 */ 2002 */
2042static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv, 2003static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
2043 struct iwl_ht_agg *agg, 2004 struct iwl_ht_agg *agg,
@@ -2059,7 +2020,7 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
2059 agg->rate_n_flags = rate_n_flags; 2020 agg->rate_n_flags = rate_n_flags;
2060 agg->bitmap = 0; 2021 agg->bitmap = 0;
2061 2022
2062 /* # frames attempted by Tx command */ 2023 /* num frames attempted by Tx command */
2063 if (agg->frame_count == 1) { 2024 if (agg->frame_count == 1) {
2064 /* Only one frame was attempted; no block-ack will arrive */ 2025 /* Only one frame was attempted; no block-ack will arrive */
2065 status = le16_to_cpu(frame_status[0].status); 2026 status = le16_to_cpu(frame_status[0].status);
@@ -2070,9 +2031,9 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
2070 agg->frame_count, agg->start_idx, idx); 2031 agg->frame_count, agg->start_idx, idx);
2071 2032
2072 info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb[0]); 2033 info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb[0]);
2073 info->status.retry_count = tx_resp->failure_frame; 2034 info->status.rates[0].count = tx_resp->failure_frame + 1;
2074 info->flags &= ~IEEE80211_TX_CTL_AMPDU; 2035 info->flags &= ~IEEE80211_TX_CTL_AMPDU;
2075 info->flags |= iwl_is_tx_success(status)? 2036 info->flags |= iwl_is_tx_success(status) ?
2076 IEEE80211_TX_STAT_ACK : 0; 2037 IEEE80211_TX_STAT_ACK : 0;
2077 iwl_hwrate_to_tx_control(priv, rate_n_flags, info); 2038 iwl_hwrate_to_tx_control(priv, rate_n_flags, info);
2078 /* FIXME: code repetition end */ 2039 /* FIXME: code repetition end */
@@ -2158,12 +2119,13 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
2158 int txq_id = SEQ_TO_QUEUE(sequence); 2119 int txq_id = SEQ_TO_QUEUE(sequence);
2159 int index = SEQ_TO_INDEX(sequence); 2120 int index = SEQ_TO_INDEX(sequence);
2160 struct iwl_tx_queue *txq = &priv->txq[txq_id]; 2121 struct iwl_tx_queue *txq = &priv->txq[txq_id];
2122 struct ieee80211_hdr *hdr;
2161 struct ieee80211_tx_info *info; 2123 struct ieee80211_tx_info *info;
2162 struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; 2124 struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
2163 u32 status = le32_to_cpu(tx_resp->u.status); 2125 u32 status = le32_to_cpu(tx_resp->u.status);
2164 int tid = MAX_TID_COUNT, sta_id = IWL_INVALID_STATION; 2126 int tid = MAX_TID_COUNT;
2165 __le16 fc; 2127 int sta_id;
2166 struct ieee80211_hdr *hdr; 2128 int freed;
2167 u8 *qc = NULL; 2129 u8 *qc = NULL;
2168 2130
2169 if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) { 2131 if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
@@ -2178,8 +2140,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
2178 memset(&info->status, 0, sizeof(info->status)); 2140 memset(&info->status, 0, sizeof(info->status));
2179 2141
2180 hdr = iwl_tx_queue_get_hdr(priv, txq_id, index); 2142 hdr = iwl_tx_queue_get_hdr(priv, txq_id, index);
2181 fc = hdr->frame_control; 2143 if (ieee80211_is_data_qos(hdr->frame_control)) {
2182 if (ieee80211_is_data_qos(fc)) {
2183 qc = ieee80211_get_qos_ctl(hdr); 2144 qc = ieee80211_get_qos_ctl(hdr);
2184 tid = qc[0] & 0xf; 2145 tid = qc[0] & 0xf;
2185 } 2146 }
@@ -2194,8 +2155,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
2194 const u32 scd_ssn = iwl4965_get_scd_ssn(tx_resp); 2155 const u32 scd_ssn = iwl4965_get_scd_ssn(tx_resp);
2195 struct iwl_ht_agg *agg = NULL; 2156 struct iwl_ht_agg *agg = NULL;
2196 2157
2197 if (!qc) 2158 WARN_ON(!qc);
2198 return;
2199 2159
2200 agg = &priv->stations[sta_id].tid[tid].agg; 2160 agg = &priv->stations[sta_id].tid[tid].agg;
2201 2161
@@ -2206,54 +2166,49 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
2206 info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; 2166 info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
2207 2167
2208 if (txq->q.read_ptr != (scd_ssn & 0xff)) { 2168 if (txq->q.read_ptr != (scd_ssn & 0xff)) {
2209 int freed, ampdu_q;
2210 index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd); 2169 index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd);
2211 IWL_DEBUG_TX_REPLY("Retry scheduler reclaim scd_ssn " 2170 IWL_DEBUG_TX_REPLY("Retry scheduler reclaim scd_ssn "
2212 "%d index %d\n", scd_ssn , index); 2171 "%d index %d\n", scd_ssn , index);
2213 freed = iwl_tx_queue_reclaim(priv, txq_id, index); 2172 freed = iwl_tx_queue_reclaim(priv, txq_id, index);
2214 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; 2173 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
2215 2174
2216 if (iwl_queue_space(&txq->q) > txq->q.low_mark && 2175 if (priv->mac80211_registered &&
2217 txq_id >= 0 && priv->mac80211_registered && 2176 (iwl_queue_space(&txq->q) > txq->q.low_mark) &&
2218 agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) { 2177 (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) {
2219 /* calculate mac80211 ampdu sw queue to wake */
2220 ampdu_q = txq_id - IWL49_FIRST_AMPDU_QUEUE +
2221 priv->hw->queues;
2222 if (agg->state == IWL_AGG_OFF) 2178 if (agg->state == IWL_AGG_OFF)
2223 ieee80211_wake_queue(priv->hw, txq_id); 2179 ieee80211_wake_queue(priv->hw, txq_id);
2224 else 2180 else
2225 ieee80211_wake_queue(priv->hw, ampdu_q); 2181 ieee80211_wake_queue(priv->hw,
2182 txq->swq_id);
2226 } 2183 }
2227 iwl_txq_check_empty(priv, sta_id, tid, txq_id);
2228 } 2184 }
2229 } else { 2185 } else {
2230 info->status.retry_count = tx_resp->failure_frame; 2186 info->status.rates[0].count = tx_resp->failure_frame + 1;
2231 info->flags |= 2187 info->flags |= iwl_is_tx_success(status) ?
2232 iwl_is_tx_success(status) ? IEEE80211_TX_STAT_ACK : 0; 2188 IEEE80211_TX_STAT_ACK : 0;
2233 iwl_hwrate_to_tx_control(priv, 2189 iwl_hwrate_to_tx_control(priv,
2234 le32_to_cpu(tx_resp->rate_n_flags), 2190 le32_to_cpu(tx_resp->rate_n_flags),
2235 info); 2191 info);
2236 2192
2237 IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags " 2193 IWL_DEBUG_TX_REPLY("TXQ %d status %s (0x%08x) "
2238 "0x%x retries %d\n", txq_id, 2194 "rate_n_flags 0x%x retries %d\n",
2239 iwl_get_tx_fail_reason(status), 2195 txq_id,
2240 status, le32_to_cpu(tx_resp->rate_n_flags), 2196 iwl_get_tx_fail_reason(status), status,
2241 tx_resp->failure_frame); 2197 le32_to_cpu(tx_resp->rate_n_flags),
2198 tx_resp->failure_frame);
2242 2199
2243 IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index); 2200 freed = iwl_tx_queue_reclaim(priv, txq_id, index);
2244 2201 if (qc && likely(sta_id != IWL_INVALID_STATION))
2245 if (index != -1) {
2246 int freed = iwl_tx_queue_reclaim(priv, txq_id, index);
2247 if (tid != MAX_TID_COUNT)
2248 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; 2202 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
2249 if (iwl_queue_space(&txq->q) > txq->q.low_mark && 2203
2250 (txq_id >= 0) && priv->mac80211_registered) 2204 if (priv->mac80211_registered &&
2205 (iwl_queue_space(&txq->q) > txq->q.low_mark))
2251 ieee80211_wake_queue(priv->hw, txq_id); 2206 ieee80211_wake_queue(priv->hw, txq_id);
2252 if (tid != MAX_TID_COUNT)
2253 iwl_txq_check_empty(priv, sta_id, tid, txq_id);
2254 }
2255 } 2207 }
2256 2208
2209 if (qc && likely(sta_id != IWL_INVALID_STATION))
2210 iwl_txq_check_empty(priv, sta_id, tid, txq_id);
2211
2257 if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) 2212 if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
2258 IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n"); 2213 IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n");
2259} 2214}
@@ -2328,9 +2283,6 @@ static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
2328 2283
2329static struct iwl_lib_ops iwl4965_lib = { 2284static struct iwl_lib_ops iwl4965_lib = {
2330 .set_hw_params = iwl4965_hw_set_hw_params, 2285 .set_hw_params = iwl4965_hw_set_hw_params,
2331 .alloc_shared_mem = iwl4965_alloc_shared_mem,
2332 .free_shared_mem = iwl4965_free_shared_mem,
2333 .shared_mem_rx_idx = iwl4965_shared_mem_rx_idx,
2334 .txq_update_byte_cnt_tbl = iwl4965_txq_update_byte_cnt_tbl, 2286 .txq_update_byte_cnt_tbl = iwl4965_txq_update_byte_cnt_tbl,
2335 .txq_set_sched = iwl4965_txq_set_sched, 2287 .txq_set_sched = iwl4965_txq_set_sched,
2336 .txq_agg_enable = iwl4965_txq_agg_enable, 2288 .txq_agg_enable = iwl4965_txq_agg_enable,
@@ -2347,7 +2299,7 @@ static struct iwl_lib_ops iwl4965_lib = {
2347 .reset = iwl4965_apm_reset, 2299 .reset = iwl4965_apm_reset,
2348 .stop = iwl4965_apm_stop, 2300 .stop = iwl4965_apm_stop,
2349 .config = iwl4965_nic_config, 2301 .config = iwl4965_nic_config,
2350 .set_pwr_src = iwl4965_set_pwr_src, 2302 .set_pwr_src = iwl_set_pwr_src,
2351 }, 2303 },
2352 .eeprom_ops = { 2304 .eeprom_ops = {
2353 .regulatory_bands = { 2305 .regulatory_bands = {
@@ -2362,11 +2314,11 @@ static struct iwl_lib_ops iwl4965_lib = {
2362 .verify_signature = iwlcore_eeprom_verify_signature, 2314 .verify_signature = iwlcore_eeprom_verify_signature,
2363 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, 2315 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
2364 .release_semaphore = iwlcore_eeprom_release_semaphore, 2316 .release_semaphore = iwlcore_eeprom_release_semaphore,
2365 .check_version = iwl4965_eeprom_check_version, 2317 .calib_version = iwl4965_eeprom_calib_version,
2366 .query_addr = iwlcore_eeprom_query_addr, 2318 .query_addr = iwlcore_eeprom_query_addr,
2367 }, 2319 },
2368 .send_tx_power = iwl4965_send_tx_power, 2320 .send_tx_power = iwl4965_send_tx_power,
2369 .update_chain_flags = iwl4965_update_chain_flags, 2321 .update_chain_flags = iwl_update_chain_flags,
2370 .temperature = iwl4965_temperature_calib, 2322 .temperature = iwl4965_temperature_calib,
2371}; 2323};
2372 2324
@@ -2378,15 +2330,19 @@ static struct iwl_ops iwl4965_ops = {
2378 2330
2379struct iwl_cfg iwl4965_agn_cfg = { 2331struct iwl_cfg iwl4965_agn_cfg = {
2380 .name = "4965AGN", 2332 .name = "4965AGN",
2381 .fw_name = "iwlwifi-4965" IWL4965_UCODE_API ".ucode", 2333 .fw_name_pre = IWL4965_FW_PRE,
2334 .ucode_api_max = IWL4965_UCODE_API_MAX,
2335 .ucode_api_min = IWL4965_UCODE_API_MIN,
2382 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, 2336 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
2383 .eeprom_size = IWL4965_EEPROM_IMG_SIZE, 2337 .eeprom_size = IWL4965_EEPROM_IMG_SIZE,
2338 .eeprom_ver = EEPROM_4965_EEPROM_VERSION,
2339 .eeprom_calib_ver = EEPROM_4965_TX_POWER_VERSION,
2384 .ops = &iwl4965_ops, 2340 .ops = &iwl4965_ops,
2385 .mod_params = &iwl4965_mod_params, 2341 .mod_params = &iwl4965_mod_params,
2386}; 2342};
2387 2343
2388/* Module firmware */ 2344/* Module firmware */
2389MODULE_FIRMWARE("iwlwifi-4965" IWL4965_UCODE_API ".ucode"); 2345MODULE_FIRMWARE(IWL4965_MODULE_FIRMWARE(IWL4965_UCODE_API_MAX));
2390 2346
2391module_param_named(antenna, iwl4965_mod_params.antenna, int, 0444); 2347module_param_named(antenna, iwl4965_mod_params.antenna, int, 0444);
2392MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])"); 2348MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])");
@@ -2394,7 +2350,7 @@ module_param_named(disable, iwl4965_mod_params.disable, int, 0444);
2394MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])"); 2350MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])");
2395module_param_named(swcrypto, iwl4965_mod_params.sw_crypto, int, 0444); 2351module_param_named(swcrypto, iwl4965_mod_params.sw_crypto, int, 0444);
2396MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])"); 2352MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])");
2397module_param_named(debug, iwl4965_mod_params.debug, int, 0444); 2353module_param_named(debug, iwl4965_mod_params.debug, uint, 0444);
2398MODULE_PARM_DESC(debug, "debug output mask"); 2354MODULE_PARM_DESC(debug, "debug output mask");
2399module_param_named( 2355module_param_named(
2400 disable_hw_scan, iwl4965_mod_params.disable_hw_scan, int, 0444); 2356 disable_hw_scan, iwl4965_mod_params.disable_hw_scan, int, 0444);
@@ -2402,9 +2358,6 @@ MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)");
2402 2358
2403module_param_named(queues_num, iwl4965_mod_params.num_of_queues, int, 0444); 2359module_param_named(queues_num, iwl4965_mod_params.num_of_queues, int, 0444);
2404MODULE_PARM_DESC(queues_num, "number of hw queues."); 2360MODULE_PARM_DESC(queues_num, "number of hw queues.");
2405/* QoS */
2406module_param_named(qos_enable, iwl4965_mod_params.enable_qos, int, 0444);
2407MODULE_PARM_DESC(qos_enable, "enable all QoS functionality");
2408/* 11n */ 2361/* 11n */
2409module_param_named(11n_disable, iwl4965_mod_params.disable_11n, int, 0444); 2362module_param_named(11n_disable, iwl4965_mod_params.disable_11n, int, 0444);
2410MODULE_PARM_DESC(11n_disable, "disable 11n functionality"); 2363MODULE_PARM_DESC(11n_disable, "disable 11n functionality");