Mark files without an existing BSD licence as having a QCA ClearBSD
[open-ath9k-htc-firmware.git] / target_firmware / wlan / ah.c
1 /*
2  * Copyright (c) 2013 Qualcomm Atheros, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted (subject to the limitations in the
7  * disclaimer below) provided that the following conditions are met:
8  *
9  *  * Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  *  * Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the
15  *    distribution.
16  *
17  *  * Neither the name of Qualcomm Atheros nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific prior written permission.
20  *
21  * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
22  * GRANTED BY THIS LICENSE.  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
23  * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
24  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
30  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
32  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
33  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35
36 #include "opt_ah.h"
37 #include "ah.h"
38 #include "ah_internal.h"
39 #include <asf_bitmap.h>
40
41 extern struct ath_hal *ar5416Attach(a_uint32_t devid,HAL_SOFTC sc, adf_os_device_t dev,
42                                     HAL_BUS_HANDLE sh, a_uint32_t flags, HAL_STATUS *status);
43
44 struct ath_hal*
45 ath_hal_attach_tgt(a_uint32_t devid,HAL_SOFTC sc,
46                    adf_os_device_t dev, HAL_BUS_HANDLE sh,
47                    a_uint32_t flags, HAL_STATUS *error)
48 {
49         struct ath_hal *ah = AH_NULL;
50
51         devid = AR5416_DEVID_PCIE;
52         ah = ar5416Attach(devid, sc, dev, sh, flags, error);
53
54         return ah;
55 }
56
57 HAL_STATUS
58 ath_hal_getcapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
59                       a_uint32_t capability, a_uint32_t *result)
60
61 {
62         const HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
63         switch (type) {
64         case HAL_CAP_TSF_ADJUST:
65                 return HAL_ENOTSUPP;
66         case HAL_CAP_BSSIDMASK:
67                 return pCap->halBssIdMaskSupport ? HAL_OK : HAL_ENOTSUPP;
68         case HAL_CAP_VEOL:
69                 return pCap->halVEOLSupport ? HAL_OK : HAL_ENOTSUPP;
70 #ifdef MAGPIE_MERLIN
71         case HAL_CAP_RX_STBC:
72                 return HAL_ENOTSUPP;
73         case HAL_CAP_TX_STBC:
74                 return HAL_ENOTSUPP;
75 #endif
76         default:
77                 return HAL_EINVAL;
78         }
79 }
80
81 void
82 ath_hal_setupratetable(struct ath_hal *ah, HAL_RATE_TABLE *rt)
83 {
84         a_int32_t i;
85
86         if (rt->rateCodeToIndex[0] != 0)
87                 return;
88
89         for (i = 0; i < 32; i++)
90                 rt->rateCodeToIndex[i] = (a_uint8_t) -1;
91         for (i = 0; i < rt->rateCount; i++) {
92                 a_uint8_t code = rt->info[i].rateCode;
93                 a_uint8_t cix = rt->info[i].controlRate;
94
95                 rt->rateCodeToIndex[code] = i;
96                 rt->rateCodeToIndex[code | rt->info[i].shortPreamble] = i;
97                 rt->info[i].lpAckDuration = ath_hal_computetxtime(ah, rt,
98                                           WLAN_CTRL_FRAME_SIZE, cix, AH_FALSE);
99                 rt->info[i].spAckDuration = ath_hal_computetxtime(ah, rt,
100                                           WLAN_CTRL_FRAME_SIZE, cix, AH_TRUE);
101         }
102 }
103
104 #define CCK_SIFS_TIME        10
105 #define CCK_PREAMBLE_BITS   144
106 #define CCK_PLCP_BITS        48
107
108 #define OFDM_SIFS_TIME        16
109 #define OFDM_PREAMBLE_TIME    20
110 #define OFDM_PLCP_BITS        22
111 #define OFDM_SYMBOL_TIME       4
112
113 #define OFDM_SIFS_TIME_HALF     32
114 #define OFDM_PREAMBLE_TIME_HALF 40
115 #define OFDM_PLCP_BITS_HALF     22
116 #define OFDM_SYMBOL_TIME_HALF   8
117
118 #define OFDM_SIFS_TIME_QUARTER      64
119 #define OFDM_PREAMBLE_TIME_QUARTER  80
120 #define OFDM_PLCP_BITS_QUARTER      22
121 #define OFDM_SYMBOL_TIME_QUARTER    16
122
123 a_uint16_t
124 ath_hal_computetxtime(struct ath_hal *ah,
125                       const HAL_RATE_TABLE *rates, a_uint32_t frameLen, a_uint16_t rateix,
126                       HAL_BOOL shortPreamble)
127 {
128         a_uint32_t bitsPerSymbol, numBits, numSymbols, phyTime, txTime;
129         a_uint32_t kbps;
130
131         kbps = rates->info[rateix].rateKbps;
132
133         /*
134          * index can be invalid duting dynamic Turbo transitions.
135          */
136         if(kbps == 0) return 0;
137         switch (rates->info[rateix].phy) {
138
139         case IEEE80211_T_CCK:
140                 phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS;
141                 if (shortPreamble && rates->info[rateix].shortPreamble)
142                         phyTime >>= 1;
143                 numBits = frameLen << 3;
144                 txTime = phyTime + ((numBits * 1000)/kbps);
145                 /* TODO: make sure the same value of txTime can use in all device */
146                 if (ath_hal_getcapability(ah, HAL_CAP_HT, 0, AH_NULL) != HAL_OK)
147                         txTime = txTime + CCK_SIFS_TIME;
148                 break;
149         case IEEE80211_T_OFDM:
150                 /* full rate channel */
151                 bitsPerSymbol   = (kbps * OFDM_SYMBOL_TIME) / 1000;
152                 HALASSERT(bitsPerSymbol != 0);
153
154                 numBits = OFDM_PLCP_BITS + (frameLen << 3);
155                 numSymbols = asf_howmany(numBits, bitsPerSymbol);
156                 txTime = OFDM_PREAMBLE_TIME + (numSymbols * OFDM_SYMBOL_TIME);
157                 /* TODO: make sure the same value of txTime can use in all device */
158                 if (ath_hal_getcapability(ah, HAL_CAP_HT, 0, AH_NULL) != HAL_OK)
159                         txTime = txTime + OFDM_SIFS_TIME;
160                 break;
161         default:
162                 txTime = 0;
163                 break;
164         }
165         return txTime;
166 }
167
168 #undef CCK_SIFS_TIME
169 #undef CCK_PREAMBLE_BITS
170 #undef CCK_PLCP_BITS
171
172 #undef OFDM_SIFS_TIME
173 #undef OFDM_PREAMBLE_TIME
174 #undef OFDM_PLCP_BITS
175 #undef OFDM_SYMBOL_TIME
176
177 #ifdef MAGPIE_MERLIN
178 a_uint32_t 
179 ath_hal_get_curmode(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
180 {
181         if (!chan)
182                 return HAL_MODE_11NG;
183
184         if (IS_CHAN_NA(chan))
185                 return HAL_MODE_11NA; 
186
187         if (IS_CHAN_A(chan))
188                 return HAL_MODE_11A;
189
190         if (IS_CHAN_NG(chan))
191                 return HAL_MODE_11NG;
192
193         if (IS_CHAN_G(chan))
194                 return HAL_MODE_11G;
195
196         if (IS_CHAN_B(chan))
197                 return HAL_MODE_11B;
198
199         HALASSERT(0);
200         return HAL_MODE_11NG;
201 }
202
203 #endif
204
205 HAL_BOOL
206 ath_hal_wait(struct ath_hal *ah, a_uint32_t reg, a_uint32_t mask, a_uint32_t val)
207 {
208 #define AH_TIMEOUT_11N 100000
209 #define AH_TIMEOUT_11G  1000
210
211         a_int32_t i;
212
213         if (ath_hal_getcapability(ah, HAL_CAP_HT, 0, AH_NULL) == HAL_OK) {
214                 for (i = 0; i < AH_TIMEOUT_11N; i++) {
215                         if ((OS_REG_READ(ah, reg) & mask) == val)
216                                 return AH_TRUE;
217                         OS_DELAY(10);
218                 }
219         } else {
220                 for (i = 0; i < AH_TIMEOUT_11G; i++) {
221                         if ((OS_REG_READ(ah, reg) & mask) == val)
222                                 return AH_TRUE;
223                         OS_DELAY(10);
224                 }
225         }
226         return AH_FALSE;
227
228 #undef AH_TIMEOUT_11N
229 #undef AH_TIMEOUT_11G
230 }