diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-4965.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965.c | 251 |
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 @@ | |||
48 | static int iwl4965_send_tx_power(struct iwl_priv *priv); | 48 | static int iwl4965_send_tx_power(struct iwl_priv *priv); |
49 | static int iwl4965_hw_get_temperature(const struct iwl_priv *priv); | 49 | static 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 */ |
59 | static struct iwl_mod_params iwl4965_mod_params = { | 63 | static 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 | 324 | static u16 iwl4965_eeprom_calib_version(struct iwl_priv *priv) | |
322 | static 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; | ||
336 | err: | ||
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 | */ |
348 | static void iwl4965_txq_set_sched(struct iwl_priv *priv, u32 mask) | 333 | static 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 | ||
443 | static int iwl4965_apm_stop_master(struct iwl_priv *priv) | 427 | static 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 | ||
459 | out: | ||
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 | ||
466 | static void iwl4965_apm_stop(struct iwl_priv *priv) | 445 | static 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, | |||
619 | static void iwl4965_rts_tx_cmd_flag(struct ieee80211_tx_info *info, | 596 | static 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[] = { | |||
709 | static int iwl4965_alive_notify(struct iwl_priv *priv) | 686 | static 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 | ||
1653 | static 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 | |||
1659 | static 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 | |||
1674 | static 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 | */ |
2042 | static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv, | 2003 | static 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 | ||
2329 | static struct iwl_lib_ops iwl4965_lib = { | 2284 | static 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 | ||
2379 | struct iwl_cfg iwl4965_agn_cfg = { | 2331 | struct 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 */ |
2389 | MODULE_FIRMWARE("iwlwifi-4965" IWL4965_UCODE_API ".ucode"); | 2345 | MODULE_FIRMWARE(IWL4965_MODULE_FIRMWARE(IWL4965_UCODE_API_MAX)); |
2390 | 2346 | ||
2391 | module_param_named(antenna, iwl4965_mod_params.antenna, int, 0444); | 2347 | module_param_named(antenna, iwl4965_mod_params.antenna, int, 0444); |
2392 | MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])"); | 2348 | MODULE_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); | |||
2394 | MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])"); | 2350 | MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])"); |
2395 | module_param_named(swcrypto, iwl4965_mod_params.sw_crypto, int, 0444); | 2351 | module_param_named(swcrypto, iwl4965_mod_params.sw_crypto, int, 0444); |
2396 | MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])"); | 2352 | MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])"); |
2397 | module_param_named(debug, iwl4965_mod_params.debug, int, 0444); | 2353 | module_param_named(debug, iwl4965_mod_params.debug, uint, 0444); |
2398 | MODULE_PARM_DESC(debug, "debug output mask"); | 2354 | MODULE_PARM_DESC(debug, "debug output mask"); |
2399 | module_param_named( | 2355 | module_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 | ||
2403 | module_param_named(queues_num, iwl4965_mod_params.num_of_queues, int, 0444); | 2359 | module_param_named(queues_num, iwl4965_mod_params.num_of_queues, int, 0444); |
2404 | MODULE_PARM_DESC(queues_num, "number of hw queues."); | 2360 | MODULE_PARM_DESC(queues_num, "number of hw queues."); |
2405 | /* QoS */ | ||
2406 | module_param_named(qos_enable, iwl4965_mod_params.enable_qos, int, 0444); | ||
2407 | MODULE_PARM_DESC(qos_enable, "enable all QoS functionality"); | ||
2408 | /* 11n */ | 2361 | /* 11n */ |
2409 | module_param_named(11n_disable, iwl4965_mod_params.disable_11n, int, 0444); | 2362 | module_param_named(11n_disable, iwl4965_mod_params.disable_11n, int, 0444); |
2410 | MODULE_PARM_DESC(11n_disable, "disable 11n functionality"); | 2363 | MODULE_PARM_DESC(11n_disable, "disable 11n functionality"); |