71deb5ec646eda573320ef1ab78623a2141d279c
[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 "ah.h"
37 #include "ah_internal.h"
38 #include <asf_bitmap.h>
39
40 extern struct ath_hal *ar5416Attach(a_uint32_t devid,HAL_SOFTC sc, adf_os_device_t dev,
41                                     a_uint32_t flags, HAL_STATUS *status);
42
43 struct ath_hal*
44 ath_hal_attach_tgt(a_uint32_t devid,HAL_SOFTC sc,
45                    adf_os_device_t dev,
46                    a_uint32_t flags, HAL_STATUS *error)
47 {
48         struct ath_hal *ah = AH_NULL;
49
50         devid = AR5416_DEVID_PCIE;
51         ah = ar5416Attach(devid, sc, dev, flags, error);
52
53         return ah;
54 }
55
56 HAL_STATUS
57 ath_hal_getcapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
58                       a_uint32_t capability, a_uint32_t *result)
59
60 {
61         const HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
62         switch (type) {
63         case HAL_CAP_TSF_ADJUST:
64                 return HAL_ENOTSUPP;
65         case HAL_CAP_BSSIDMASK:
66                 return pCap->halBssIdMaskSupport ? HAL_OK : HAL_ENOTSUPP;
67         case HAL_CAP_VEOL:
68                 return pCap->halVEOLSupport ? HAL_OK : HAL_ENOTSUPP;
69         default:
70                 return HAL_EINVAL;
71         }
72 }
73
74 #define CCK_SIFS_TIME        10
75 #define CCK_PREAMBLE_BITS   144
76 #define CCK_PLCP_BITS        48
77
78 #define OFDM_SIFS_TIME        16
79 #define OFDM_PREAMBLE_TIME    20
80 #define OFDM_PLCP_BITS        22
81 #define OFDM_SYMBOL_TIME       4
82
83 #define OFDM_SIFS_TIME_HALF     32
84 #define OFDM_PREAMBLE_TIME_HALF 40
85 #define OFDM_PLCP_BITS_HALF     22
86 #define OFDM_SYMBOL_TIME_HALF   8
87
88 #define OFDM_SIFS_TIME_QUARTER      64
89 #define OFDM_PREAMBLE_TIME_QUARTER  80
90 #define OFDM_PLCP_BITS_QUARTER      22
91 #define OFDM_SYMBOL_TIME_QUARTER    16
92
93 a_uint16_t
94 ath_hal_computetxtime(struct ath_hal *ah,
95                       const HAL_RATE_TABLE *rates, a_uint32_t frameLen, a_uint16_t rateix,
96                       HAL_BOOL shortPreamble)
97 {
98         a_uint32_t bitsPerSymbol, numBits, numSymbols, phyTime, txTime;
99         a_uint32_t kbps;
100
101         kbps = rates->info[rateix].rateKbps;
102
103         /*
104          * index can be invalid duting dynamic Turbo transitions.
105          */
106         if(kbps == 0) return 0;
107         switch (rates->info[rateix].phy) {
108
109         case IEEE80211_T_CCK:
110                 phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS;
111                 if (shortPreamble && rates->info[rateix].shortPreamble)
112                         phyTime >>= 1;
113                 numBits = frameLen << 3;
114                 txTime = phyTime + ((numBits * 1000)/kbps);
115                 /* TODO: make sure the same value of txTime can use in all device */
116                 if (ath_hal_getcapability(ah, HAL_CAP_HT, 0, AH_NULL) != HAL_OK)
117                         txTime = txTime + CCK_SIFS_TIME;
118                 break;
119         case IEEE80211_T_OFDM:
120                 /* full rate channel */
121                 bitsPerSymbol   = (kbps * OFDM_SYMBOL_TIME) / 1000;
122                 HALASSERT(bitsPerSymbol != 0);
123
124                 numBits = OFDM_PLCP_BITS + (frameLen << 3);
125                 numSymbols = asf_howmany(numBits, bitsPerSymbol);
126                 txTime = OFDM_PREAMBLE_TIME + (numSymbols * OFDM_SYMBOL_TIME);
127                 /* TODO: make sure the same value of txTime can use in all device */
128                 if (ath_hal_getcapability(ah, HAL_CAP_HT, 0, AH_NULL) != HAL_OK)
129                         txTime = txTime + OFDM_SIFS_TIME;
130                 break;
131         default:
132                 txTime = 0;
133                 break;
134         }
135         return txTime;
136 }
137
138 #undef CCK_SIFS_TIME
139 #undef CCK_PREAMBLE_BITS
140 #undef CCK_PLCP_BITS
141
142 #undef OFDM_SIFS_TIME
143 #undef OFDM_PREAMBLE_TIME
144 #undef OFDM_PLCP_BITS
145 #undef OFDM_SYMBOL_TIME
146
147 #ifdef MAGPIE_MERLIN
148 a_uint32_t 
149 ath_hal_get_curmode(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
150 {
151         if (!chan)
152                 return HAL_MODE_11NG;
153
154         if (IS_CHAN_NA(chan))
155                 return HAL_MODE_11NA; 
156
157         if (IS_CHAN_A(chan))
158                 return HAL_MODE_11A;
159
160         if (IS_CHAN_NG(chan))
161                 return HAL_MODE_11NG;
162
163         if (IS_CHAN_G(chan))
164                 return HAL_MODE_11G;
165
166         if (IS_CHAN_B(chan))
167                 return HAL_MODE_11B;
168
169         HALASSERT(0);
170         return HAL_MODE_11NG;
171 }
172
173 #endif
174
175 HAL_BOOL
176 ath_hal_wait(struct ath_hal *ah, a_uint32_t reg, a_uint32_t mask, a_uint32_t val)
177 {
178 #define AH_TIMEOUT_11N 100000
179 #define AH_TIMEOUT_11G  1000
180
181         a_int32_t i;
182
183         if (ath_hal_getcapability(ah, HAL_CAP_HT, 0, AH_NULL) == HAL_OK) {
184                 for (i = 0; i < AH_TIMEOUT_11N; i++) {
185                         if ((OS_REG_READ(ah, reg) & mask) == val)
186                                 return AH_TRUE;
187                         OS_DELAY(10);
188                 }
189         } else {
190                 for (i = 0; i < AH_TIMEOUT_11G; i++) {
191                         if ((OS_REG_READ(ah, reg) & mask) == val)
192                                 return AH_TRUE;
193                         OS_DELAY(10);
194                 }
195         }
196         return AH_FALSE;
197
198 #undef AH_TIMEOUT_11N
199 #undef AH_TIMEOUT_11G
200 }