aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath9k/rc.c
diff options
context:
space:
mode:
authorSujith <Sujith.Manoharan@atheros.com>2009-01-30 03:59:28 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-02-09 15:03:44 -0500
commitc89424df441ea8d794682b9c5620d8e8b0315438 (patch)
tree1638bf3e6e8bf0bace48f99ac9884df71683fad4 /drivers/net/wireless/ath9k/rc.c
parent3900898c7a3d563d14a1288f483f8a589bd38299 (diff)
ath9k: Handle mac80211's RC flags for MCS rates
mac80211 notifies the RC algorithm if RTS/CTS and short preamble are needed. The RC flags for MCS rates are currently not handled by mac80211, and ath9k's RC doesn't set the flags either. Fix this. Also, set the rts_cts_rate_idx inside the RC algorithm. Signed-off-by: Sujith <Sujith.Manoharan@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath9k/rc.c')
-rw-r--r--drivers/net/wireless/ath9k/rc.c82
1 files changed, 71 insertions, 11 deletions
diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c
index 8bc7bb50c7fc..a8c4f9757eb1 100644
--- a/drivers/net/wireless/ath9k/rc.c
+++ b/drivers/net/wireless/ath9k/rc.c
@@ -747,14 +747,17 @@ static u8 ath_rc_ratefind_ht(struct ath_softc *sc,
747 return rate; 747 return rate;
748} 748}
749 749
750static void ath_rc_rate_set_series(struct ath_rate_table *rate_table , 750static void ath_rc_rate_set_series(struct ath_rate_table *rate_table,
751 struct ieee80211_tx_rate *rate, 751 struct ieee80211_tx_rate *rate,
752 struct ieee80211_tx_rate_control *txrc,
752 u8 tries, u8 rix, int rtsctsenable) 753 u8 tries, u8 rix, int rtsctsenable)
753{ 754{
754 rate->count = tries; 755 rate->count = tries;
755 rate->idx = rix; 756 rate->idx = rix;
756 757
757 if (rtsctsenable) 758 if (txrc->short_preamble)
759 rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE;
760 if (txrc->rts || rtsctsenable)
758 rate->flags |= IEEE80211_TX_RC_USE_RTS_CTS; 761 rate->flags |= IEEE80211_TX_RC_USE_RTS_CTS;
759 if (WLAN_RC_PHY_40(rate_table->info[rix].phy)) 762 if (WLAN_RC_PHY_40(rate_table->info[rix].phy))
760 rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; 763 rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
@@ -764,6 +767,43 @@ static void ath_rc_rate_set_series(struct ath_rate_table *rate_table ,
764 rate->flags |= IEEE80211_TX_RC_MCS; 767 rate->flags |= IEEE80211_TX_RC_MCS;
765} 768}
766 769
770static void ath_rc_rate_set_rtscts(struct ath_softc *sc,
771 struct ath_rate_table *rate_table,
772 struct ieee80211_tx_info *tx_info)
773{
774 struct ieee80211_tx_rate *rates = tx_info->control.rates;
775 int i = 0, rix = 0, cix, enable_g_protection = 0;
776
777 /* get the cix for the lowest valid rix */
778 for (i = 3; i >= 0; i--) {
779 if (rates[i].count && (rates[i].idx >= 0)) {
780 rix = rates[i].idx;
781 break;
782 }
783 }
784 cix = rate_table->info[rix].ctrl_rate;
785
786 /* All protection frames are transmited at 2Mb/s for 802.11g,
787 * otherwise we transmit them at 1Mb/s */
788 if (sc->hw->conf.channel->band == IEEE80211_BAND_2GHZ &&
789 !conf_is_ht(&sc->hw->conf))
790 enable_g_protection = 1;
791
792 /*
793 * If 802.11g protection is enabled, determine whether to use RTS/CTS or
794 * just CTS. Note that this is only done for OFDM/HT unicast frames.
795 */
796 if ((sc->sc_flags & SC_OP_PROTECT_ENABLE) &&
797 !(tx_info->flags & IEEE80211_TX_CTL_NO_ACK) &&
798 (rate_table->info[rix].phy == WLAN_RC_PHY_OFDM ||
799 WLAN_RC_PHY_HT(rate_table->info[rix].phy))) {
800 rates[0].flags |= IEEE80211_TX_RC_USE_CTS_PROTECT;
801 cix = rate_table->info[enable_g_protection].ctrl_rate;
802 }
803
804 tx_info->control.rts_cts_rate_idx = cix;
805}
806
767static u8 ath_rc_rate_getidx(struct ath_softc *sc, 807static u8 ath_rc_rate_getidx(struct ath_softc *sc,
768 struct ath_rate_priv *ath_rc_priv, 808 struct ath_rate_priv *ath_rc_priv,
769 struct ath_rate_table *rate_table, 809 struct ath_rate_table *rate_table,
@@ -801,6 +841,8 @@ static void ath_rc_ratefind(struct ath_softc *sc,
801 struct sk_buff *skb = txrc->skb; 841 struct sk_buff *skb = txrc->skb;
802 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 842 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
803 struct ieee80211_tx_rate *rates = tx_info->control.rates; 843 struct ieee80211_tx_rate *rates = tx_info->control.rates;
844 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
845 __le16 fc = hdr->frame_control;
804 u8 try_per_rate = 0, i = 0, rix, nrix; 846 u8 try_per_rate = 0, i = 0, rix, nrix;
805 int is_probe = 0; 847 int is_probe = 0;
806 848
@@ -811,7 +853,7 @@ static void ath_rc_ratefind(struct ath_softc *sc,
811 if (is_probe) { 853 if (is_probe) {
812 /* set one try for probe rates. For the 854 /* set one try for probe rates. For the
813 * probes don't enable rts */ 855 * probes don't enable rts */
814 ath_rc_rate_set_series(rate_table, &rates[i++], 856 ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
815 1, nrix, 0); 857 1, nrix, 0);
816 858
817 try_per_rate = (ATH_11N_TXMAXTRY/4); 859 try_per_rate = (ATH_11N_TXMAXTRY/4);
@@ -820,12 +862,12 @@ static void ath_rc_ratefind(struct ath_softc *sc,
820 */ 862 */
821 nrix = ath_rc_rate_getidx(sc, ath_rc_priv, 863 nrix = ath_rc_rate_getidx(sc, ath_rc_priv,
822 rate_table, nrix, 1, 0); 864 rate_table, nrix, 1, 0);
823 ath_rc_rate_set_series(rate_table, &rates[i++], 865 ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
824 try_per_rate, nrix, 0); 866 try_per_rate, nrix, 0);
825 } else { 867 } else {
826 try_per_rate = (ATH_11N_TXMAXTRY/4); 868 try_per_rate = (ATH_11N_TXMAXTRY/4);
827 /* Set the choosen rate. No RTS for first series entry. */ 869 /* Set the choosen rate. No RTS for first series entry. */
828 ath_rc_rate_set_series(rate_table, &rates[i++], 870 ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
829 try_per_rate, nrix, 0); 871 try_per_rate, nrix, 0);
830 } 872 }
831 873
@@ -841,7 +883,7 @@ static void ath_rc_ratefind(struct ath_softc *sc,
841 nrix = ath_rc_rate_getidx(sc, ath_rc_priv, 883 nrix = ath_rc_rate_getidx(sc, ath_rc_priv,
842 rate_table, nrix, 1, min_rate); 884 rate_table, nrix, 1, min_rate);
843 /* All other rates in the series have RTS enabled */ 885 /* All other rates in the series have RTS enabled */
844 ath_rc_rate_set_series(rate_table, &rates[i], 886 ath_rc_rate_set_series(rate_table, &rates[i], txrc,
845 try_num, nrix, 1); 887 try_num, nrix, 1);
846 } 888 }
847 889
@@ -871,6 +913,24 @@ static void ath_rc_ratefind(struct ath_softc *sc,
871 rates[3].flags = rates[2].flags; 913 rates[3].flags = rates[2].flags;
872 } 914 }
873 } 915 }
916
917 /*
918 * Force hardware to use computed duration for next
919 * fragment by disabling multi-rate retry, which
920 * updates duration based on the multi-rate duration table.
921 *
922 * FIXME: Fix duration
923 */
924 if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK) &&
925 (ieee80211_has_morefrags(fc) ||
926 (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG))) {
927 rates[1].count = rates[2].count = rates[3].count = 0;
928 rates[1].idx = rates[2].idx = rates[3].idx = 0;
929 rates[0].count = ATH_TXMAXTRY;
930 }
931
932 /* Setup RTS/CTS */
933 ath_rc_rate_set_rtscts(sc, rate_table, tx_info);
874} 934}
875 935
876static bool ath_rc_update_per(struct ath_softc *sc, 936static bool ath_rc_update_per(struct ath_softc *sc,
@@ -1385,16 +1445,16 @@ static void ath_rc_init(struct ath_softc *sc,
1385 if (!rateset->rs_nrates) { 1445 if (!rateset->rs_nrates) {
1386 /* No working rate, just initialize valid rates */ 1446 /* No working rate, just initialize valid rates */
1387 hi = ath_rc_init_validrates(ath_rc_priv, rate_table, 1447 hi = ath_rc_init_validrates(ath_rc_priv, rate_table,
1388 ath_rc_priv->ht_cap); 1448 ath_rc_priv->ht_cap);
1389 } else { 1449 } else {
1390 /* Use intersection of working rates and valid rates */ 1450 /* Use intersection of working rates and valid rates */
1391 hi = ath_rc_setvalid_rates(ath_rc_priv, rate_table, 1451 hi = ath_rc_setvalid_rates(ath_rc_priv, rate_table,
1392 rateset, ath_rc_priv->ht_cap); 1452 rateset, ath_rc_priv->ht_cap);
1393 if (ath_rc_priv->ht_cap & WLAN_RC_HT_FLAG) { 1453 if (ath_rc_priv->ht_cap & WLAN_RC_HT_FLAG) {
1394 hthi = ath_rc_setvalid_htrates(ath_rc_priv, 1454 hthi = ath_rc_setvalid_htrates(ath_rc_priv,
1395 rate_table, 1455 rate_table,
1396 ht_mcs, 1456 ht_mcs,
1397 ath_rc_priv->ht_cap); 1457 ath_rc_priv->ht_cap);
1398 } 1458 }
1399 hi = A_MAX(hi, hthi); 1459 hi = A_MAX(hi, hthi);
1400 } 1460 }