81f8de52fa3e69cee2f9de193365a0dcb2f38957
[openwrt.git] / package / mac80211 / patches / 530-ath9k_otp_rom.patch
1 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
2 +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
3 @@ -3104,6 +3104,36 @@ error:
4         return false;
5  }
6  
7 +static bool ar9300_otp_read_word(struct ath_hw *ah, int addr, u32 *data)
8 +{
9 +       REG_READ(ah, AR9300_OTP_BASE + (4 * addr));
10 +
11 +       if (!ath9k_hw_wait(ah, AR9300_OTP_STATUS, AR9300_OTP_STATUS_TYPE,
12 +                          AR9300_OTP_STATUS_VALID, 1000))
13 +               return false;
14 +
15 +       *data = REG_READ(ah, AR9300_OTP_READ_DATA);
16 +       return true;
17 +}
18 +
19 +static bool ar9300_read_otp(struct ath_hw *ah, int address, u8 *buffer,
20 +                           int count)
21 +{
22 +       u32 data;
23 +       int i;
24 +
25 +       for (i = 0; i < count; i++) {
26 +               int offset = 8 * ((address - i) % 4);
27 +               if (!ar9300_otp_read_word(ah, (address - i) / 4, &data))
28 +                       return false;
29 +
30 +               buffer[i] = (data >> offset) & 0xff;
31 +       }
32 +
33 +       return true;
34 +}
35 +
36 +
37  static void ar9300_comp_hdr_unpack(u8 *best, int *code, int *reference,
38                                    int *length, int *major, int *minor)
39  {
40 @@ -3221,6 +3251,26 @@ static int ar9300_compress_decision(stru
41         return 0;
42  }
43  
44 +typedef bool (*eeprom_read_op)(struct ath_hw *ah, int address, u8 *buffer,
45 +                              int count);
46 +
47 +static bool ar9300_check_header(void *data)
48 +{
49 +       u32 *word = data;
50 +       return !(*word == 0 || *word == ~0);
51 +}
52 +
53 +static bool ar9300_check_eeprom_header(struct ath_hw *ah, eeprom_read_op read,
54 +                                      int base_addr)
55 +{
56 +       u8 header[4];
57 +
58 +       if (!read(ah, base_addr, header, 4))
59 +               return false;
60 +
61 +       return ar9300_check_header(header);
62 +}
63 +
64  /*
65   * Read the configuration data from the eeprom.
66   * The data can be put in any specified memory buffer.
67 @@ -3241,6 +3291,7 @@ static int ar9300_eeprom_restore_interna
68         int it;
69         u16 checksum, mchecksum;
70         struct ath_common *common = ath9k_hw_common(ah);
71 +       eeprom_read_op read;
72  
73         word = kzalloc(2048, GFP_KERNEL);
74         if (!word)
75 @@ -3248,14 +3299,42 @@ static int ar9300_eeprom_restore_interna
76  
77         memcpy(mptr, &ar9300_default, mdata_size);
78  
79 +       read = ar9300_read_eeprom;
80         cptr = AR9300_BASE_ADDR;
81 +       ath_print(common, ATH_DBG_EEPROM,
82 +               "Trying EEPROM accesss at Address 0x%04x\n", cptr);
83 +       if (ar9300_check_eeprom_header(ah, read, cptr))
84 +               goto found;
85 +
86 +       cptr = AR9300_BASE_ADDR_512;
87 +       ath_print(common, ATH_DBG_EEPROM,
88 +               "Trying EEPROM accesss at Address 0x%04x\n", cptr);
89 +       if (ar9300_check_eeprom_header(ah, read, cptr))
90 +               goto found;
91 +
92 +       read = ar9300_read_otp;
93 +       cptr = AR9300_BASE_ADDR;
94 +       ath_print(common, ATH_DBG_EEPROM,
95 +               "Trying OTP accesss at Address 0x%04x\n", cptr);
96 +       if (ar9300_check_eeprom_header(ah, read, cptr))
97 +               goto found;
98 +
99 +       cptr = AR9300_BASE_ADDR_512;
100 +       ath_print(common, ATH_DBG_EEPROM,
101 +               "Trying OTP accesss at Address 0x%04x\n", cptr);
102 +       if (ar9300_check_eeprom_header(ah, read, cptr))
103 +               goto found;
104 +
105 +       goto fail;
106 +
107 +found:
108 +       ath_print(common, ATH_DBG_EEPROM, "Found valid EEPROM data");
109 +
110         for (it = 0; it < MSTATE; it++) {
111 -               if (!ar9300_read_eeprom(ah, cptr, word, COMP_HDR_LEN))
112 +               if (!read(ah, cptr, word, COMP_HDR_LEN))
113                         goto fail;
114  
115 -               if ((word[0] == 0 && word[1] == 0 && word[2] == 0 &&
116 -                    word[3] == 0) || (word[0] == 0xff && word[1] == 0xff
117 -                                      && word[2] == 0xff && word[3] == 0xff))
118 +               if (!ar9300_check_header(word))
119                         break;
120  
121                 ar9300_comp_hdr_unpack(word, &code, &reference,
122 @@ -3272,8 +3351,7 @@ static int ar9300_eeprom_restore_interna
123                 }
124  
125                 osize = length;
126 -               ar9300_read_eeprom(ah, cptr, word,
127 -                                  COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
128 +               read(ah, cptr, word, COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
129                 checksum = ar9300_comp_cksum(&word[COMP_HDR_LEN], length);
130                 mchecksum = word[COMP_HDR_LEN + osize] |
131                     (word[COMP_HDR_LEN + osize + 1] << 8);
132 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
133 +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
134 @@ -79,6 +79,15 @@
135  #define FIXED_CCA_THRESHOLD 15
136  
137  #define AR9300_BASE_ADDR 0x3ff
138 +#define AR9300_BASE_ADDR_512 0x1ff
139 +
140 +#define AR9300_OTP_BASE                        0x14000
141 +#define AR9300_OTP_STATUS              0x15f18
142 +#define AR9300_OTP_STATUS_TYPE         0x7
143 +#define AR9300_OTP_STATUS_VALID                0x4
144 +#define AR9300_OTP_STATUS_ACCESS_BUSY  0x2
145 +#define AR9300_OTP_STATUS_SM_BUSY      0x1
146 +#define AR9300_OTP_READ_DATA           0x15f1c
147  
148  enum targetPowerHTRates {
149         HT_TARGET_RATE_0_8_16,