Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(65)

Side by Side Diff: chromeos/compat-wireless/drivers/net/wireless/ath/ath9k/ar9003_paprd.c

Issue 5990016: ath9k: AR9380 PAPRD changes to improve tx performance (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/kernel.git@master
Patch Set: Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2010 Atheros Communications Inc. 2 * Copyright (c) 2010 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies. 6 * copyright notice and this permission notice appear in all copies.
7 * 7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17 #include "hw.h" 17 #include "hw.h"
18 #include "ar9003_phy.h" 18 #include "ar9003_phy.h"
19 19
20 void ar9003_paprd_enable(struct ath_hw *ah, bool val) 20 void ar9003_paprd_enable(struct ath_hw *ah, bool val)
21 { 21 {
22 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
23 struct ath9k_channel *chan = ah->curchan;
24
25 if (val) {
26 ah->paprd_table_write_done = true;
27
28 ah->eep_ops->set_txpower(ah, chan,
29 ath9k_regd_get_ctl(regulatory, chan),
30 chan->chan->max_antenna_gain * 2,
31 chan->chan->max_power * 2,
32 min((u32) MAX_RATE_POWER,
33 (u32) regulatory->power_limit));
34 }
35
22 REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B0, 36 REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B0,
23 AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val); 37 AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val);
24 REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B1, 38 REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B1,
25 AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val); 39 AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val);
26 REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B2, 40 REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B2,
27 AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val); 41 AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val);
28 } 42 }
29 EXPORT_SYMBOL(ar9003_paprd_enable); 43 EXPORT_SYMBOL(ar9003_paprd_enable);
30 44
31 static void ar9003_paprd_setup_single_table(struct ath_hw *ah) 45 static int ar9003_get_training_power_2g(struct ath_hw *ah)
32 { 46 {
33 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; 47 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
34 » struct ar9300_modal_eep_header *hdr; 48 » struct ar9300_modal_eep_header *hdr = &eep->modalHeader2G;
49 » unsigned int power, scale, delta;
50
51 » scale = MS(le32_to_cpu(hdr->papdRateMaskHt20), AR9300_PAPRD_SCALE_1);
52 » power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5,
53 » » » AR_PHY_POWERTX_RATE5_POWERTXHT20_0);
54
55 » delta = abs((int) ah->paprd_target_power - (int) power);
56 » if (delta > scale)
57 » » return -1;
58
59 » if (delta < 4)
60 » » power -= 4 - delta;
61
62 » return power;
63 }
64
65 static int ar9003_get_training_power_5g(struct ath_hw *ah)
66 {
67 » struct ath_common *common = ath9k_hw_common(ah);
68 » struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
69 » struct ar9300_modal_eep_header *hdr = &eep->modalHeader5G;
70 » struct ath9k_channel *chan = ah->curchan;
71 » unsigned int power, scale, delta;
72
73 » if (chan->channel >= 5700)
74 » » scale = MS(le32_to_cpu(hdr->papdRateMaskHt20),
75 » » » AR9300_PAPRD_SCALE_1);
76 » else if (chan->channel >= 5400)
77 » » scale = MS(le32_to_cpu(hdr->papdRateMaskHt40),
78 » » » AR9300_PAPRD_SCALE_2);
79 » else
80 » » scale = MS(le32_to_cpu(hdr->papdRateMaskHt40),
81 » » » AR9300_PAPRD_SCALE_1);
82
83 » if (IS_CHAN_HT40(chan))
84 » » power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE8,
85 » » » AR_PHY_POWERTX_RATE8_POWERTXHT40_5);
86 » else
87 » » power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE6,
88 » » » AR_PHY_POWERTX_RATE6_POWERTXHT20_5);
89
90 » power += scale;
91 » delta = abs((int) ah->paprd_target_power - (int) power);
92 » if (delta > scale)
93 » » return -1;
94
95 » power += 2 * get_streams(common->tx_chainmask);
96 » return power;
97 }
98
99 static int ar9003_paprd_setup_single_table(struct ath_hw *ah)
100 {
101 » struct ath_common *common = ath9k_hw_common(ah);
35 const u32 ctrl0[3] = { 102 const u32 ctrl0[3] = {
36 AR_PHY_PAPRD_CTRL0_B0, 103 AR_PHY_PAPRD_CTRL0_B0,
37 AR_PHY_PAPRD_CTRL0_B1, 104 AR_PHY_PAPRD_CTRL0_B1,
38 AR_PHY_PAPRD_CTRL0_B2 105 AR_PHY_PAPRD_CTRL0_B2
39 }; 106 };
40 const u32 ctrl1[3] = { 107 const u32 ctrl1[3] = {
41 AR_PHY_PAPRD_CTRL1_B0, 108 AR_PHY_PAPRD_CTRL1_B0,
42 AR_PHY_PAPRD_CTRL1_B1, 109 AR_PHY_PAPRD_CTRL1_B1,
43 AR_PHY_PAPRD_CTRL1_B2 110 AR_PHY_PAPRD_CTRL1_B2
44 }; 111 };
45 » u32 am_mask, ht40_mask; 112 » int training_power;
46 int i; 113 int i;
47 114
48 » if (ah->curchan && IS_CHAN_5GHZ(ah->curchan)) 115 » if (IS_CHAN_2GHZ(ah->curchan))
49 » » hdr = &eep->modalHeader5G; 116 » » training_power = ar9003_get_training_power_2g(ah);
50 else 117 else
51 » » hdr = &eep->modalHeader2G; 118 » » training_power = ar9003_get_training_power_5g(ah);
52 119
53 » am_mask = le32_to_cpu(hdr->papdRateMaskHt20); 120 » if (training_power < 0) {
54 » ht40_mask = le32_to_cpu(hdr->papdRateMaskHt40); 121 » » ath_print(common, ATH_DBG_CALIBRATE,
122 » » » "PAPRD target power delta out of range");
123 » » return -ERANGE;
124 » }
125 » ah->paprd_training_power = training_power;
126 » ath_print(common, ATH_DBG_CALIBRATE,
127 » » "Training power: %d, Target power: %d\n",
128 » » ah->paprd_training_power, ah->paprd_target_power);
55 129
56 » REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK, am_mask); 130 » REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK,
57 » REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK, am_mask); 131 » » ah->paprd_ratemask);
58 » REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK, ht40_mask); 132 » REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK,
133 » » ah->paprd_ratemask);
134 » REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK,
135 » » ah->paprd_ratemask_ht40);
59 136
60 for (i = 0; i < 3; i++) { 137 for (i = 0; i < 3; i++) {
61 REG_RMW_FIELD(ah, ctrl0[i], 138 REG_RMW_FIELD(ah, ctrl0[i],
62 AR_PHY_PAPRD_CTRL0_USE_SINGLE_TABLE_MASK, 1); 139 AR_PHY_PAPRD_CTRL0_USE_SINGLE_TABLE_MASK, 1);
63 REG_RMW_FIELD(ah, ctrl1[i], 140 REG_RMW_FIELD(ah, ctrl1[i],
64 AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2PM_ENABLE, 1); 141 AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2PM_ENABLE, 1);
65 REG_RMW_FIELD(ah, ctrl1[i], 142 REG_RMW_FIELD(ah, ctrl1[i],
66 AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2AM_ENABLE, 1); 143 AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2AM_ENABLE, 1);
67 REG_RMW_FIELD(ah, ctrl1[i], 144 REG_RMW_FIELD(ah, ctrl1[i],
68 AR_PHY_PAPRD_CTRL1_ADAPTIVE_SCALING_ENA, 0); 145 AR_PHY_PAPRD_CTRL1_ADAPTIVE_SCALING_ENA, 0);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_3_B0, 202 REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_3_B0,
126 AR_PHY_PAPRD_PRE_POST_SCALING, 220464); 203 AR_PHY_PAPRD_PRE_POST_SCALING, 220464);
127 REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_4_B0, 204 REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_4_B0,
128 AR_PHY_PAPRD_PRE_POST_SCALING, 208194); 205 AR_PHY_PAPRD_PRE_POST_SCALING, 208194);
129 REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_5_B0, 206 REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_5_B0,
130 AR_PHY_PAPRD_PRE_POST_SCALING, 196949); 207 AR_PHY_PAPRD_PRE_POST_SCALING, 196949);
131 REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_6_B0, 208 REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_6_B0,
132 AR_PHY_PAPRD_PRE_POST_SCALING, 185706); 209 AR_PHY_PAPRD_PRE_POST_SCALING, 185706);
133 REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_7_B0, 210 REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_7_B0,
134 AR_PHY_PAPRD_PRE_POST_SCALING, 175487); 211 AR_PHY_PAPRD_PRE_POST_SCALING, 175487);
212 return 0;
135 } 213 }
136 214
137 static void ar9003_paprd_get_gain_table(struct ath_hw *ah) 215 static void ar9003_paprd_get_gain_table(struct ath_hw *ah)
138 { 216 {
139 u32 *entry = ah->paprd_gain_table_entries; 217 u32 *entry = ah->paprd_gain_table_entries;
140 u8 *index = ah->paprd_gain_table_index; 218 u8 *index = ah->paprd_gain_table_index;
141 u32 reg = AR_PHY_TXGAIN_TABLE; 219 u32 reg = AR_PHY_TXGAIN_TABLE;
142 int i; 220 int i;
143 221
144 memset(entry, 0, sizeof(ah->paprd_gain_table_entries)); 222 memset(entry, 0, sizeof(ah->paprd_gain_table_entries));
(...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after
579 *gain = G_fxp; 657 *gain = G_fxp;
580 return true; 658 return true;
581 } 659 }
582 660
583 void ar9003_paprd_populate_single_table(struct ath_hw *ah, 661 void ar9003_paprd_populate_single_table(struct ath_hw *ah,
584 struct ath9k_hw_cal_data *caldata, 662 struct ath9k_hw_cal_data *caldata,
585 int chain) 663 int chain)
586 { 664 {
587 u32 *paprd_table_val = caldata->pa_table[chain]; 665 u32 *paprd_table_val = caldata->pa_table[chain];
588 u32 small_signal_gain = caldata->small_signal_gain[chain]; 666 u32 small_signal_gain = caldata->small_signal_gain[chain];
589 » u32 training_power; 667 » u32 training_power = ah->paprd_training_power;
590 u32 reg = 0; 668 u32 reg = 0;
591 int i; 669 int i;
592 670
593 training_power =
594 REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5,
595 AR_PHY_POWERTX_RATE5_POWERTXHT20_0);
596 training_power -= 4;
597
598 if (chain == 0) 671 if (chain == 0)
599 reg = AR_PHY_PAPRD_MEM_TAB_B0; 672 reg = AR_PHY_PAPRD_MEM_TAB_B0;
600 else if (chain == 1) 673 else if (chain == 1)
601 reg = AR_PHY_PAPRD_MEM_TAB_B1; 674 reg = AR_PHY_PAPRD_MEM_TAB_B1;
602 else if (chain == 2) 675 else if (chain == 2)
603 reg = AR_PHY_PAPRD_MEM_TAB_B2; 676 reg = AR_PHY_PAPRD_MEM_TAB_B2;
604 677
605 for (i = 0; i < PAPRD_TABLE_SZ; i++) { 678 for (i = 0; i < PAPRD_TABLE_SZ; i++) {
606 REG_WRITE(ah, reg, paprd_table_val[i]); 679 REG_WRITE(ah, reg, paprd_table_val[i]);
607 reg = reg + 4; 680 reg = reg + 4;
(...skipping 17 matching lines...) Expand all
625 training_power); 698 training_power);
626 699
627 REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL1_B2, 700 REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL1_B2,
628 AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL, 701 AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL,
629 training_power); 702 training_power);
630 } 703 }
631 EXPORT_SYMBOL(ar9003_paprd_populate_single_table); 704 EXPORT_SYMBOL(ar9003_paprd_populate_single_table);
632 705
633 int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain) 706 int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain)
634 { 707 {
635
636 unsigned int i, desired_gain, gain_index; 708 unsigned int i, desired_gain, gain_index;
637 » unsigned int train_power; 709 » unsigned int train_power = ah->paprd_training_power;
638
639 » train_power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5,
640 » » » » AR_PHY_POWERTX_RATE5_POWERTXHT20_0);
641
642 » train_power = train_power - 4;
643 710
644 desired_gain = ar9003_get_desired_gain(ah, chain, train_power); 711 desired_gain = ar9003_get_desired_gain(ah, chain, train_power);
645 712
646 gain_index = 0; 713 gain_index = 0;
647 for (i = 0; i < 32; i++) { 714 for (i = 0; i < 32; i++) {
648 if (ah->paprd_gain_table_index[i] >= desired_gain) 715 if (ah->paprd_gain_table_index[i] >= desired_gain)
649 break; 716 break;
650 gain_index++; 717 gain_index++;
651 } 718 }
652 719
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
698 AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE); 765 AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE);
699 766
700 kfree(buf); 767 kfree(buf);
701 768
702 return status; 769 return status;
703 } 770 }
704 EXPORT_SYMBOL(ar9003_paprd_create_curve); 771 EXPORT_SYMBOL(ar9003_paprd_create_curve);
705 772
706 int ar9003_paprd_init_table(struct ath_hw *ah) 773 int ar9003_paprd_init_table(struct ath_hw *ah)
707 { 774 {
708 » ar9003_paprd_setup_single_table(ah); 775 » int ret;
776
777 » ret = ar9003_paprd_setup_single_table(ah);
778 » if (ret < 0)
779 » return ret;
780
709 ar9003_paprd_get_gain_table(ah); 781 ar9003_paprd_get_gain_table(ah);
710 return 0; 782 return 0;
711 } 783 }
712 EXPORT_SYMBOL(ar9003_paprd_init_table); 784 EXPORT_SYMBOL(ar9003_paprd_init_table);
713 785
714 bool ar9003_paprd_is_done(struct ath_hw *ah) 786 bool ar9003_paprd_is_done(struct ath_hw *ah)
715 { 787 {
716 return !!REG_READ_FIELD(ah, AR_PHY_PAPRD_TRAINER_STAT1, 788 return !!REG_READ_FIELD(ah, AR_PHY_PAPRD_TRAINER_STAT1,
717 AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE); 789 AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE);
718 } 790 }
719 EXPORT_SYMBOL(ar9003_paprd_is_done); 791 EXPORT_SYMBOL(ar9003_paprd_is_done);
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698