diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-tx.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-tx.c | 111 |
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, | |||
566 | static void iwl_tx_cmd_build_rate(struct iwl_priv *priv, | 566 | static 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 | /* |