aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-tx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-tx.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c111
1 files changed, 62 insertions, 49 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 7bc9c0039f79..a7422e52d883 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -566,62 +566,81 @@ static void iwl_tx_cmd_build_basic(struct iwl_priv *priv,
566static void iwl_tx_cmd_build_rate(struct iwl_priv *priv, 566static void iwl_tx_cmd_build_rate(struct iwl_priv *priv,
567 struct iwl_tx_cmd *tx_cmd, 567 struct iwl_tx_cmd *tx_cmd,
568 struct ieee80211_tx_info *info, 568 struct ieee80211_tx_info *info,
569 __le16 fc, int sta_id, 569 __le16 fc, int is_hcca)
570 int is_hcca)
571{ 570{
572 u32 rate_flags = 0; 571 u32 rate_flags;
573 int rate_idx; 572 int rate_idx;
574 u8 rts_retry_limit = 0; 573 u8 rts_retry_limit;
575 u8 data_retry_limit = 0; 574 u8 data_retry_limit;
576 u8 rate_plcp; 575 u8 rate_plcp;
577 576
578 rate_idx = min(ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xffff, 577 /* Set retry limit on DATA packets and Probe Responses*/
579 IWL_RATE_COUNT - 1);
580
581 rate_plcp = iwl_rates[rate_idx].plcp;
582
583 rts_retry_limit = (is_hcca) ?
584 RTS_HCCA_RETRY_LIMIT : RTS_DFAULT_RETRY_LIMIT;
585
586 if ((rate_idx >= IWL_FIRST_CCK_RATE) && (rate_idx <= IWL_LAST_CCK_RATE))
587 rate_flags |= RATE_MCS_CCK_MSK;
588
589
590 if (ieee80211_is_probe_resp(fc)) {
591 data_retry_limit = 3;
592 if (data_retry_limit < rts_retry_limit)
593 rts_retry_limit = data_retry_limit;
594 } else
595 data_retry_limit = IWL_DEFAULT_TX_RETRY;
596
597 if (priv->data_retry_limit != -1) 578 if (priv->data_retry_limit != -1)
598 data_retry_limit = priv->data_retry_limit; 579 data_retry_limit = priv->data_retry_limit;
580 else if (ieee80211_is_probe_resp(fc))
581 data_retry_limit = 3;
582 else
583 data_retry_limit = IWL_DEFAULT_TX_RETRY;
584 tx_cmd->data_retry_limit = data_retry_limit;
599 585
586 /* Set retry limit on RTS packets */
587 rts_retry_limit = (is_hcca) ? RTS_HCCA_RETRY_LIMIT :
588 RTS_DFAULT_RETRY_LIMIT;
589 if (data_retry_limit < rts_retry_limit)
590 rts_retry_limit = data_retry_limit;
591 tx_cmd->rts_retry_limit = rts_retry_limit;
600 592
593 /* DATA packets will use the uCode station table for rate/antenna
594 * selection */
601 if (ieee80211_is_data(fc)) { 595 if (ieee80211_is_data(fc)) {
602 tx_cmd->initial_rate_index = 0; 596 tx_cmd->initial_rate_index = 0;
603 tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK; 597 tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK;
604 } else { 598 return;
605 switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) { 599 }
606 case cpu_to_le16(IEEE80211_STYPE_AUTH): 600
607 case cpu_to_le16(IEEE80211_STYPE_DEAUTH): 601 /**
608 case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ): 602 * If the current TX rate stored in mac80211 has the MCS bit set, it's
609 case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ): 603 * not really a TX rate. Thus, we use the lowest supported rate for
610 if (tx_cmd->tx_flags & TX_CMD_FLG_RTS_MSK) { 604 * this band. Also use the lowest supported rate if the stored rate
611 tx_cmd->tx_flags &= ~TX_CMD_FLG_RTS_MSK; 605 * index is invalid.
612 tx_cmd->tx_flags |= TX_CMD_FLG_CTS_MSK; 606 */
613 } 607 rate_idx = info->control.rates[0].idx;
614 break; 608 if (info->control.rates[0].flags & IEEE80211_TX_RC_MCS ||
615 default: 609 (rate_idx < 0) || (rate_idx > IWL_RATE_COUNT_LEGACY))
616 break; 610 rate_idx = rate_lowest_index(&priv->bands[info->band],
617 } 611 info->control.sta);
612 /* For 5 GHZ band, remap mac80211 rate indices into driver indices */
613 if (info->band == IEEE80211_BAND_5GHZ)
614 rate_idx += IWL_FIRST_OFDM_RATE;
615 /* Get PLCP rate for tx_cmd->rate_n_flags */
616 rate_plcp = iwl_rates[rate_idx].plcp;
617 /* Zero out flags for this packet */
618 rate_flags = 0;
618 619
619 priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant); 620 /* Set CCK flag as needed */
620 rate_flags |= iwl_ant_idx_to_flags(priv->mgmt_tx_ant); 621 if ((rate_idx >= IWL_FIRST_CCK_RATE) && (rate_idx <= IWL_LAST_CCK_RATE))
622 rate_flags |= RATE_MCS_CCK_MSK;
623
624 /* Set up RTS and CTS flags for certain packets */
625 switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
626 case cpu_to_le16(IEEE80211_STYPE_AUTH):
627 case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
628 case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ):
629 case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ):
630 if (tx_cmd->tx_flags & TX_CMD_FLG_RTS_MSK) {
631 tx_cmd->tx_flags &= ~TX_CMD_FLG_RTS_MSK;
632 tx_cmd->tx_flags |= TX_CMD_FLG_CTS_MSK;
633 }
634 break;
635 default:
636 break;
621 } 637 }
622 638
623 tx_cmd->rts_retry_limit = rts_retry_limit; 639 /* Set up antennas */
624 tx_cmd->data_retry_limit = data_retry_limit; 640 priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant);
641 rate_flags |= iwl_ant_idx_to_flags(priv->mgmt_tx_ant);
642
643 /* Set the rate in the TX cmd */
625 tx_cmd->rate_n_flags = iwl_hw_set_rate_n_flags(rate_plcp, rate_flags); 644 tx_cmd->rate_n_flags = iwl_hw_set_rate_n_flags(rate_plcp, rate_flags);
626} 645}
627 646
@@ -701,12 +720,6 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
701 goto drop_unlock; 720 goto drop_unlock;
702 } 721 }
703 722
704 if ((ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xFF) ==
705 IWL_INVALID_RATE) {
706 IWL_ERR(priv, "ERROR: No TX rate available.\n");
707 goto drop_unlock;
708 }
709
710 fc = hdr->frame_control; 723 fc = hdr->frame_control;
711 724
712#ifdef CONFIG_IWLWIFI_DEBUG 725#ifdef CONFIG_IWLWIFI_DEBUG
@@ -807,7 +820,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
807 iwl_dbg_log_tx_data_frame(priv, len, hdr); 820 iwl_dbg_log_tx_data_frame(priv, len, hdr);
808 821
809 /* set is_hcca to 0; it probably will never be implemented */ 822 /* set is_hcca to 0; it probably will never be implemented */
810 iwl_tx_cmd_build_rate(priv, tx_cmd, info, fc, sta_id, 0); 823 iwl_tx_cmd_build_rate(priv, tx_cmd, info, fc, 0);
811 824
812 iwl_update_stats(priv, true, fc, len); 825 iwl_update_stats(priv, true, fc, len);
813 /* 826 /*