Commit | Line | Data |
---|---|---|
92b96797 FB |
1 | /* |
2 | * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. | |
3 | * All rights reserved. | |
4 | * | |
5 | * This program is free software; you can redistribute it and/or modify | |
6 | * it under the terms of the GNU General Public License as published by | |
7 | * the Free Software Foundation; either version 2 of the License, or | |
8 | * (at your option) any later version. | |
9 | * | |
10 | * This program is distributed in the hope that it will be useful, | |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | * GNU General Public License for more details. | |
14 | * | |
15 | * You should have received a copy of the GNU General Public License along | |
16 | * with this program; if not, write to the Free Software Foundation, Inc., | |
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 | * | |
19 | * File: card.c | |
20 | * Purpose: Provide functions to setup NIC operation mode | |
21 | * Functions: | |
22 | * s_vSafeResetTx - Rest Tx | |
1a792943 | 23 | * vnt_set_rspinf - Set RSPINF |
c7ee9eeb | 24 | * vnt_update_ifs - Update slotTime,SIFS,DIFS, and EIFS |
47203c49 | 25 | * vnt_update_top_rates - Update BasicTopRate |
9a2cffd4 | 26 | * vnt_add_basic_rate - Add to BasicRateSet |
92b96797 | 27 | * CARDbSetBasicRate - Set Basic Tx Rate |
cfa4d8d2 | 28 | * vnt_ofdm_min_rate - Check if any OFDM rate is in BasicRateSet |
92b96797 FB |
29 | * CARDvSetLoopbackMode - Set Loopback mode |
30 | * CARDbSoftwareReset - Sortware reset NIC | |
ecbc0a1e | 31 | * vnt_get_tsf_offset - Calculate TSFOffset |
4a9f4c65 | 32 | * vnt_get_current_tsf - Read Current NIC TSF counter |
75ef1b51 | 33 | * vnt_get_next_tbtt - Calculate Next Beacon TSF counter |
6964cd12 | 34 | * vnt_reset_next_tbtt - Set NIC Beacon time |
88ec2f7e | 35 | * vnt_update_next_tbtt - Sync. NIC Beacon time |
fa26e0bd | 36 | * vnt_radio_power_off - Turn Off NIC Radio Power |
8a5e6c8c | 37 | * vnt_radio_power_on - Turn On NIC Radio Power |
92b96797 FB |
38 | * CARDbSetWEPMode - Set NIC Wep mode |
39 | * CARDbSetTxPower - Set NIC tx power | |
40 | * | |
41 | * Revision History: | |
42 | * 06-10-2003 Bryan YC Fan: Re-write codes to support VT3253 spec. | |
a0a1f61a | 43 | * 08-26-2003 Kyle Hsu: Modify the definition type of dwIoBase. |
c7ee9eeb | 44 | * 09-01-2003 Bryan YC Fan: Add vnt_update_ifs(). |
92b96797 FB |
45 | * |
46 | */ | |
47 | ||
dd0a774f | 48 | #include "device.h" |
92b96797 | 49 | #include "card.h" |
92b96797 | 50 | #include "baseband.h" |
92b96797 | 51 | #include "mac.h" |
92b96797 | 52 | #include "desc.h" |
92b96797 | 53 | #include "rf.h" |
92b96797 | 54 | #include "power.h" |
92b96797 | 55 | #include "key.h" |
62c8526d | 56 | #include "usbpipe.h" |
92b96797 | 57 | |
618d7d07 PST |
58 | /* const u16 cwRXBCNTSFOff[MAX_RATE] = |
59 | {17, 34, 96, 192, 34, 23, 17, 11, 8, 5, 4, 3}; */ | |
92b96797 | 60 | |
42b138d9 PST |
61 | static const u16 cwRXBCNTSFOff[MAX_RATE] = { |
62 | 192, 96, 34, 17, 34, 23, 17, 11, 8, 5, 4, 3 | |
63 | }; | |
92b96797 | 64 | |
92b96797 FB |
65 | /* |
66 | * Description: Set NIC media channel | |
67 | * | |
68 | * Parameters: | |
69 | * In: | |
70 | * pDevice - The adapter to be set | |
7387f438 | 71 | * connection_channel - Channel to be set |
92b96797 FB |
72 | * Out: |
73 | * none | |
92b96797 | 74 | */ |
084fc8f3 | 75 | void vnt_set_channel(struct vnt_private *priv, u32 connection_channel) |
92b96797 | 76 | { |
92b96797 | 77 | |
04f2ff16 MP |
78 | if (connection_channel > CB_MAX_CHANNEL || !connection_channel) |
79 | return; | |
92b96797 | 80 | |
7387f438 | 81 | /* clear NAV */ |
36957537 | 82 | vnt_mac_reg_bits_on(priv, MAC_REG_MACCR, MACCR_CLRNAV); |
7387f438 MP |
83 | |
84 | /* Set Channel[7] = 0 to tell H/W channel is changing now. */ | |
a9bed1df | 85 | vnt_mac_reg_bits_off(priv, MAC_REG_CHANNEL, 0xb0); |
7387f438 | 86 | |
1390b02a | 87 | vnt_control_out(priv, MESSAGE_TYPE_SELECT_CHANNLE, |
7387f438 MP |
88 | connection_channel, 0, 0, NULL); |
89 | ||
285d58c4 | 90 | vnt_control_out_u8(priv, MESSAGE_REQUEST_MACREG, MAC_REG_CHANNEL, |
7387f438 | 91 | (u8)(connection_channel|0x80)); |
92b96797 FB |
92 | } |
93 | ||
94 | /* | |
95 | * Description: Get CCK mode basic rate | |
96 | * | |
97 | * Parameters: | |
98 | * In: | |
3d2988c7 MP |
99 | * priv - The adapter to be set |
100 | * rate_idx - Receiving data rate | |
92b96797 FB |
101 | * Out: |
102 | * none | |
103 | * | |
104 | * Return Value: response Control frame rate | |
105 | * | |
106 | */ | |
073d02eb | 107 | static u16 vnt_get_cck_rate(struct vnt_private *priv, u16 rate_idx) |
92b96797 | 108 | { |
3d2988c7 | 109 | u16 ui = rate_idx; |
dd0a774f MP |
110 | |
111 | while (ui > RATE_1M) { | |
3d2988c7 | 112 | if (priv->wBasicRate & (1 << ui)) |
dd0a774f MP |
113 | return ui; |
114 | ui--; | |
115 | } | |
116 | ||
117 | return RATE_1M; | |
92b96797 FB |
118 | } |
119 | ||
120 | /* | |
121 | * Description: Get OFDM mode basic rate | |
122 | * | |
123 | * Parameters: | |
124 | * In: | |
a5a7c439 MP |
125 | * priv - The adapter to be set |
126 | * rate_idx - Receiving data rate | |
92b96797 FB |
127 | * Out: |
128 | * none | |
129 | * | |
130 | * Return Value: response Control frame rate | |
131 | * | |
132 | */ | |
15fa7ce2 | 133 | static u16 vnt_get_ofdm_rate(struct vnt_private *priv, u16 rate_idx) |
92b96797 | 134 | { |
a5a7c439 | 135 | u16 ui = rate_idx; |
dd0a774f | 136 | |
842e3ecc MP |
137 | dev_dbg(&priv->usb->dev, "%s basic rate: %d\n", |
138 | __func__, priv->wBasicRate); | |
dd0a774f | 139 | |
cfa4d8d2 | 140 | if (!vnt_ofdm_min_rate(priv)) { |
842e3ecc MP |
141 | dev_dbg(&priv->usb->dev, "%s (NO OFDM) %d\n", |
142 | __func__, rate_idx); | |
a5a7c439 MP |
143 | if (rate_idx > RATE_24M) |
144 | rate_idx = RATE_24M; | |
145 | return rate_idx; | |
dd0a774f MP |
146 | } |
147 | ||
148 | while (ui > RATE_11M) { | |
a5a7c439 | 149 | if (priv->wBasicRate & (1 << ui)) { |
842e3ecc MP |
150 | dev_dbg(&priv->usb->dev, "%s rate: %d\n", |
151 | __func__, ui); | |
dd0a774f MP |
152 | return ui; |
153 | } | |
154 | ui--; | |
155 | } | |
156 | ||
842e3ecc | 157 | dev_dbg(&priv->usb->dev, "%s basic rate: 24M\n", __func__); |
dd0a774f MP |
158 | |
159 | return RATE_24M; | |
92b96797 FB |
160 | } |
161 | ||
162 | /* | |
a0a1f61a | 163 | * Description: Calculate TxRate and RsvTime fields for RSPINF in OFDM mode. |
92b96797 FB |
164 | * |
165 | * Parameters: | |
3605f84e MP |
166 | * In: |
167 | * rate - Tx Rate | |
168 | * bb_type - Tx Packet type | |
169 | * Out: | |
170 | * tx_rate - pointer to RSPINF TxRate field | |
171 | * rsv_time- pointer to RSPINF RsvTime field | |
92b96797 FB |
172 | * |
173 | * Return Value: none | |
174 | * | |
175 | */ | |
c9a04877 | 176 | static void vnt_calculate_ofdm_rate(u16 rate, u8 bb_type, |
3605f84e | 177 | u8 *tx_rate, u8 *rsv_time) |
92b96797 | 178 | { |
92b96797 | 179 | |
3605f84e MP |
180 | switch (rate) { |
181 | case RATE_6M: | |
182 | if (bb_type == BB_TYPE_11A) { | |
183 | *tx_rate = 0x9b; | |
184 | *rsv_time = 24; | |
185 | } else { | |
186 | *tx_rate = 0x8b; | |
187 | *rsv_time = 30; | |
188 | } | |
189 | break; | |
190 | case RATE_9M: | |
191 | if (bb_type == BB_TYPE_11A) { | |
192 | *tx_rate = 0x9f; | |
193 | *rsv_time = 16; | |
194 | } else { | |
195 | *tx_rate = 0x8f; | |
196 | *rsv_time = 22; | |
197 | } | |
198 | break; | |
199 | case RATE_12M: | |
200 | if (bb_type == BB_TYPE_11A) { | |
201 | *tx_rate = 0x9a; | |
202 | *rsv_time = 12; | |
203 | } else { | |
204 | *tx_rate = 0x8a; | |
205 | *rsv_time = 18; | |
206 | } | |
207 | break; | |
208 | case RATE_18M: | |
209 | if (bb_type == BB_TYPE_11A) { | |
210 | *tx_rate = 0x9e; | |
211 | *rsv_time = 8; | |
212 | } else { | |
213 | *tx_rate = 0x8e; | |
214 | *rsv_time = 14; | |
215 | } | |
216 | break; | |
217 | case RATE_36M: | |
218 | if (bb_type == BB_TYPE_11A) { | |
219 | *tx_rate = 0x9d; | |
220 | *rsv_time = 4; | |
221 | } else { | |
222 | *tx_rate = 0x8d; | |
223 | *rsv_time = 10; | |
224 | } | |
225 | break; | |
226 | case RATE_48M: | |
227 | if (bb_type == BB_TYPE_11A) { | |
228 | *tx_rate = 0x98; | |
229 | *rsv_time = 4; | |
230 | } else { | |
231 | *tx_rate = 0x88; | |
fd4859f6 | 232 | *rsv_time = 10; |
3605f84e MP |
233 | } |
234 | break; | |
235 | case RATE_54M: | |
236 | if (bb_type == BB_TYPE_11A) { | |
237 | *tx_rate = 0x9c; | |
238 | *rsv_time = 4; | |
239 | } else { | |
240 | *tx_rate = 0x8c; | |
241 | *rsv_time = 10; | |
242 | } | |
243 | break; | |
244 | case RATE_24M: | |
245 | default: | |
246 | if (bb_type == BB_TYPE_11A) { | |
247 | *tx_rate = 0x99; | |
248 | *rsv_time = 8; | |
249 | } else { | |
250 | *tx_rate = 0x89; | |
251 | *rsv_time = 14; | |
252 | } | |
253 | break; | |
254 | } | |
92b96797 FB |
255 | } |
256 | ||
257 | /* | |
258 | * Description: Set RSPINF | |
259 | * | |
260 | * Parameters: | |
261 | * In: | |
262 | * pDevice - The adapter to be set | |
263 | * Out: | |
264 | * none | |
265 | * | |
266 | * Return Value: None. | |
267 | * | |
268 | */ | |
652d0f00 | 269 | |
1a792943 | 270 | void vnt_set_rspinf(struct vnt_private *priv, u8 bb_type) |
92b96797 | 271 | { |
aed387c7 | 272 | struct vnt_phy_field phy[4]; |
652d0f00 MP |
273 | u8 tx_rate[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; /* For OFDM */ |
274 | u8 rsv_time[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; | |
275 | u8 data[34]; | |
dd0a774f | 276 | int i; |
92b96797 | 277 | |
652d0f00 | 278 | /*RSPINF_b_1*/ |
205056f3 | 279 | vnt_get_phy_field(priv, 14, |
073d02eb | 280 | vnt_get_cck_rate(priv, RATE_1M), PK_TYPE_11B, &phy[0]); |
652d0f00 MP |
281 | |
282 | /*RSPINF_b_2*/ | |
205056f3 | 283 | vnt_get_phy_field(priv, 14, |
073d02eb | 284 | vnt_get_cck_rate(priv, RATE_2M), PK_TYPE_11B, &phy[1]); |
652d0f00 MP |
285 | |
286 | /*RSPINF_b_5*/ | |
205056f3 | 287 | vnt_get_phy_field(priv, 14, |
073d02eb | 288 | vnt_get_cck_rate(priv, RATE_5M), PK_TYPE_11B, &phy[2]); |
652d0f00 MP |
289 | |
290 | /*RSPINF_b_11*/ | |
205056f3 | 291 | vnt_get_phy_field(priv, 14, |
073d02eb | 292 | vnt_get_cck_rate(priv, RATE_11M), PK_TYPE_11B, &phy[3]); |
652d0f00 MP |
293 | |
294 | ||
295 | /*RSPINF_a_6*/ | |
c9a04877 | 296 | vnt_calculate_ofdm_rate(RATE_6M, bb_type, &tx_rate[0], &rsv_time[0]); |
652d0f00 MP |
297 | |
298 | /*RSPINF_a_9*/ | |
c9a04877 | 299 | vnt_calculate_ofdm_rate(RATE_9M, bb_type, &tx_rate[1], &rsv_time[1]); |
652d0f00 MP |
300 | |
301 | /*RSPINF_a_12*/ | |
c9a04877 | 302 | vnt_calculate_ofdm_rate(RATE_12M, bb_type, &tx_rate[2], &rsv_time[2]); |
652d0f00 MP |
303 | |
304 | /*RSPINF_a_18*/ | |
c9a04877 | 305 | vnt_calculate_ofdm_rate(RATE_18M, bb_type, &tx_rate[3], &rsv_time[3]); |
92b96797 | 306 | |
652d0f00 | 307 | /*RSPINF_a_24*/ |
c9a04877 | 308 | vnt_calculate_ofdm_rate(RATE_24M, bb_type, &tx_rate[4], &rsv_time[4]); |
652d0f00 MP |
309 | |
310 | /*RSPINF_a_36*/ | |
c9a04877 | 311 | vnt_calculate_ofdm_rate(vnt_get_ofdm_rate(priv, RATE_36M), |
652d0f00 MP |
312 | bb_type, &tx_rate[5], &rsv_time[5]); |
313 | ||
314 | /*RSPINF_a_48*/ | |
c9a04877 | 315 | vnt_calculate_ofdm_rate(vnt_get_ofdm_rate(priv, RATE_48M), |
652d0f00 MP |
316 | bb_type, &tx_rate[6], &rsv_time[6]); |
317 | ||
318 | /*RSPINF_a_54*/ | |
c9a04877 | 319 | vnt_calculate_ofdm_rate(vnt_get_ofdm_rate(priv, RATE_54M), |
652d0f00 MP |
320 | bb_type, &tx_rate[7], &rsv_time[7]); |
321 | ||
322 | /*RSPINF_a_72*/ | |
c9a04877 | 323 | vnt_calculate_ofdm_rate(vnt_get_ofdm_rate(priv, RATE_54M), |
652d0f00 MP |
324 | bb_type, &tx_rate[8], &rsv_time[8]); |
325 | ||
326 | put_unaligned(phy[0].len, (u16 *)&data[0]); | |
327 | data[2] = phy[0].signal; | |
328 | data[3] = phy[0].service; | |
329 | ||
330 | put_unaligned(phy[1].len, (u16 *)&data[4]); | |
331 | data[6] = phy[1].signal; | |
332 | data[7] = phy[1].service; | |
333 | ||
334 | put_unaligned(phy[2].len, (u16 *)&data[8]); | |
335 | data[10] = phy[2].signal; | |
336 | data[11] = phy[2].service; | |
337 | ||
338 | put_unaligned(phy[3].len, (u16 *)&data[12]); | |
339 | data[14] = phy[3].signal; | |
340 | data[15] = phy[3].service; | |
341 | ||
342 | for (i = 0; i < 9; i++) { | |
343 | data[16 + i * 2] = tx_rate[i]; | |
344 | data[16 + i * 2 + 1] = rsv_time[i]; | |
345 | } | |
92b96797 | 346 | |
1390b02a | 347 | vnt_control_out(priv, MESSAGE_TYPE_WRITE, |
652d0f00 | 348 | MAC_REG_RSPINF_B_1, MESSAGE_REQUEST_MACREG, 34, &data[0]); |
92b96797 FB |
349 | } |
350 | ||
351 | /* | |
352 | * Description: Update IFS | |
353 | * | |
354 | * Parameters: | |
355 | * In: | |
5ebc46d6 MP |
356 | * priv - The adapter to be set |
357 | * Out: | |
358 | * none | |
92b96797 FB |
359 | * |
360 | * Return Value: None. | |
361 | * | |
362 | */ | |
c7ee9eeb | 363 | void vnt_update_ifs(struct vnt_private *priv) |
92b96797 | 364 | { |
5ebc46d6 MP |
365 | u8 max_min = 0; |
366 | u8 data[4]; | |
367 | ||
368 | if (priv->byPacketType == PK_TYPE_11A) { | |
369 | priv->uSlot = C_SLOT_SHORT; | |
370 | priv->uSIFS = C_SIFS_A; | |
371 | priv->uDIFS = C_SIFS_A + 2 * C_SLOT_SHORT; | |
372 | priv->uCwMin = C_CWMIN_A; | |
373 | max_min = 4; | |
374 | } else if (priv->byPacketType == PK_TYPE_11B) { | |
375 | priv->uSlot = C_SLOT_LONG; | |
376 | priv->uSIFS = C_SIFS_BG; | |
377 | priv->uDIFS = C_SIFS_BG + 2 * C_SLOT_LONG; | |
378 | priv->uCwMin = C_CWMIN_B; | |
379 | max_min = 5; | |
380 | } else {/* PK_TYPE_11GA & PK_TYPE_11GB */ | |
5ebc46d6 MP |
381 | bool ofdm_rate = false; |
382 | unsigned int ii = 0; | |
5ebc46d6 MP |
383 | |
384 | priv->uSIFS = C_SIFS_BG; | |
385 | ||
386 | if (priv->bShortSlotTime) | |
387 | priv->uSlot = C_SLOT_SHORT; | |
388 | else | |
389 | priv->uSlot = C_SLOT_LONG; | |
390 | ||
391 | priv->uDIFS = C_SIFS_BG + 2 * priv->uSlot; | |
392 | ||
ee61fde2 MP |
393 | for (ii = RATE_54M; ii >= RATE_6M; ii--) { |
394 | if (priv->wBasicRate & ((u32)(0x1 << ii))) { | |
5ebc46d6 MP |
395 | ofdm_rate = true; |
396 | break; | |
397 | } | |
398 | } | |
399 | ||
5ebc46d6 MP |
400 | if (ofdm_rate == true) { |
401 | priv->uCwMin = C_CWMIN_A; | |
402 | max_min = 4; | |
403 | } else { | |
404 | priv->uCwMin = C_CWMIN_B; | |
405 | max_min = 5; | |
406 | } | |
407 | } | |
408 | ||
409 | priv->uCwMax = C_CWMAX; | |
410 | priv->uEIFS = C_EIFS; | |
411 | ||
9fe109c1 MP |
412 | switch (priv->byRFType) { |
413 | case RF_VT3226D0: | |
414 | if (priv->byBBType != BB_TYPE_11B) { | |
415 | priv->uSIFS -= 1; | |
416 | priv->uDIFS -= 1; | |
417 | break; | |
418 | } | |
419 | case RF_AIROHA7230: | |
420 | case RF_AL2230: | |
421 | case RF_AL2230S: | |
422 | if (priv->byBBType != BB_TYPE_11B) | |
423 | break; | |
424 | case RF_RFMD2959: | |
425 | case RF_VT3226: | |
426 | case RF_VT3342A0: | |
427 | priv->uSIFS -= 3; | |
428 | priv->uDIFS -= 3; | |
429 | break; | |
430 | case RF_MAXIM2829: | |
431 | if (priv->byBBType == BB_TYPE_11A) { | |
432 | priv->uSIFS -= 5; | |
433 | priv->uDIFS -= 5; | |
434 | } else { | |
435 | priv->uSIFS -= 2; | |
436 | priv->uDIFS -= 2; | |
437 | } | |
438 | ||
439 | break; | |
440 | } | |
441 | ||
5ebc46d6 MP |
442 | data[0] = (u8)priv->uSIFS; |
443 | data[1] = (u8)priv->uDIFS; | |
444 | data[2] = (u8)priv->uEIFS; | |
445 | data[3] = (u8)priv->uSlot; | |
446 | ||
1390b02a | 447 | vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_SIFS, |
5ebc46d6 MP |
448 | MESSAGE_REQUEST_MACREG, 4, &data[0]); |
449 | ||
450 | max_min |= 0xa0; | |
451 | ||
1390b02a | 452 | vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_CWMAXMIN0, |
5ebc46d6 | 453 | MESSAGE_REQUEST_MACREG, 1, &max_min); |
92b96797 FB |
454 | } |
455 | ||
47203c49 | 456 | void vnt_update_top_rates(struct vnt_private *priv) |
92b96797 | 457 | { |
dcce9e0b MP |
458 | u8 top_ofdm = RATE_24M, top_cck = RATE_1M; |
459 | u8 i; | |
460 | ||
461 | /*Determines the highest basic rate.*/ | |
462 | for (i = RATE_54M; i >= RATE_6M; i--) { | |
463 | if (priv->wBasicRate & (u16)(1 << i)) { | |
464 | top_ofdm = i; | |
465 | break; | |
466 | } | |
467 | } | |
468 | ||
469 | priv->byTopOFDMBasicRate = top_ofdm; | |
470 | ||
471 | for (i = RATE_11M;; i--) { | |
472 | if (priv->wBasicRate & (u16)(1 << i)) { | |
473 | top_cck = i; | |
474 | break; | |
475 | } | |
476 | if (i == RATE_1M) | |
477 | break; | |
478 | } | |
479 | ||
480 | priv->byTopCCKBasicRate = top_cck; | |
42b138d9 | 481 | } |
92b96797 | 482 | |
cfa4d8d2 | 483 | int vnt_ofdm_min_rate(struct vnt_private *priv) |
92b96797 | 484 | { |
dd0a774f | 485 | int ii; |
92b96797 | 486 | |
de0eb9ef MP |
487 | for (ii = RATE_54M; ii >= RATE_6M; ii--) { |
488 | if ((priv->wBasicRate) & ((u16)(1 << ii))) | |
489 | return true; | |
490 | } | |
491 | ||
492 | return false; | |
92b96797 FB |
493 | } |
494 | ||
e809c96e | 495 | u8 vnt_get_pkt_type(struct vnt_private *priv) |
92b96797 | 496 | { |
92b96797 | 497 | |
1f44238f MP |
498 | if (priv->byBBType == BB_TYPE_11A || priv->byBBType == BB_TYPE_11B) |
499 | return (u8)priv->byBBType; | |
cfa4d8d2 | 500 | else if (vnt_ofdm_min_rate(priv)) |
1f44238f MP |
501 | return PK_TYPE_11GA; |
502 | else | |
503 | return PK_TYPE_11GB; | |
92b96797 FB |
504 | } |
505 | ||
92b96797 | 506 | /* |
a0a1f61a | 507 | * Description: Calculate TSF offset of two TSF input |
92b96797 FB |
508 | * Get TSF Offset from RxBCN's TSF and local TSF |
509 | * | |
510 | * Parameters: | |
511 | * In: | |
3fd2a69c MP |
512 | * rx_rate - rx rate. |
513 | * tsf1 - Rx BCN's TSF | |
514 | * tsf2 - Local TSF | |
92b96797 FB |
515 | * Out: |
516 | * none | |
517 | * | |
518 | * Return Value: TSF Offset value | |
519 | * | |
520 | */ | |
ecbc0a1e | 521 | u64 vnt_get_tsf_offset(u8 rx_rate, u64 tsf1, u64 tsf2) |
92b96797 | 522 | { |
3fd2a69c MP |
523 | u64 tsf_offset = 0; |
524 | u16 rx_bcn_offset = 0; | |
92b96797 | 525 | |
3fd2a69c | 526 | rx_bcn_offset = cwRXBCNTSFOff[rx_rate % MAX_RATE]; |
92b96797 | 527 | |
3fd2a69c | 528 | tsf2 += (u64)rx_bcn_offset; |
7c65fa2a | 529 | |
3fd2a69c | 530 | tsf_offset = tsf1 - tsf2; |
7c65fa2a | 531 | |
3fd2a69c | 532 | return tsf_offset; |
92b96797 FB |
533 | } |
534 | ||
92b96797 FB |
535 | /* |
536 | * Description: Sync. TSF counter to BSS | |
537 | * Get TSF offset and write to HW | |
538 | * | |
539 | * Parameters: | |
540 | * In: | |
302361d4 MP |
541 | * priv - The adapter to be sync. |
542 | * time_stamp - Rx BCN's TSF | |
543 | * local_tsf - Local TSF | |
92b96797 FB |
544 | * Out: |
545 | * none | |
546 | * | |
547 | * Return Value: none | |
548 | * | |
549 | */ | |
14c68c56 | 550 | void vnt_adjust_tsf(struct vnt_private *priv, u8 rx_rate, |
302361d4 | 551 | u64 time_stamp, u64 local_tsf) |
92b96797 | 552 | { |
302361d4 MP |
553 | u64 tsf_offset = 0; |
554 | u8 data[8]; | |
555 | ||
ecbc0a1e | 556 | tsf_offset = vnt_get_tsf_offset(rx_rate, time_stamp, local_tsf); |
302361d4 MP |
557 | |
558 | data[0] = (u8)tsf_offset; | |
559 | data[1] = (u8)(tsf_offset >> 8); | |
560 | data[2] = (u8)(tsf_offset >> 16); | |
561 | data[3] = (u8)(tsf_offset >> 24); | |
562 | data[4] = (u8)(tsf_offset >> 32); | |
563 | data[5] = (u8)(tsf_offset >> 40); | |
564 | data[6] = (u8)(tsf_offset >> 48); | |
565 | data[7] = (u8)(tsf_offset >> 56); | |
92b96797 | 566 | |
1390b02a | 567 | vnt_control_out(priv, MESSAGE_TYPE_SET_TSFTBTT, |
302361d4 | 568 | MESSAGE_REQUEST_TSF, 0, 8, data); |
92b96797 FB |
569 | } |
570 | /* | |
571 | * Description: Read NIC TSF counter | |
572 | * Get local TSF counter | |
573 | * | |
574 | * Parameters: | |
575 | * In: | |
2092dfa4 | 576 | * priv - The adapter to be read |
92b96797 | 577 | * Out: |
2092dfa4 | 578 | * current_tsf - Current TSF counter |
92b96797 | 579 | * |
4e9b5e2b | 580 | * Return Value: true if success; otherwise false |
92b96797 FB |
581 | * |
582 | */ | |
4a9f4c65 | 583 | bool vnt_get_current_tsf(struct vnt_private *priv, u64 *current_tsf) |
92b96797 | 584 | { |
92b96797 | 585 | |
2092dfa4 | 586 | *current_tsf = priv->qwCurrTSF; |
92b96797 | 587 | |
4e9b5e2b | 588 | return true; |
92b96797 FB |
589 | } |
590 | ||
92b96797 FB |
591 | /* |
592 | * Description: Clear NIC TSF counter | |
593 | * Clear local TSF counter | |
594 | * | |
595 | * Parameters: | |
596 | * In: | |
e151e478 | 597 | * priv - The adapter to be read |
92b96797 | 598 | * |
4e9b5e2b | 599 | * Return Value: true if success; otherwise false |
92b96797 FB |
600 | * |
601 | */ | |
dba066e9 | 602 | bool vnt_clear_current_tsf(struct vnt_private *priv) |
92b96797 | 603 | { |
92b96797 | 604 | |
36957537 | 605 | vnt_mac_reg_bits_on(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTRST); |
92b96797 | 606 | |
e151e478 | 607 | priv->qwCurrTSF = 0; |
92b96797 | 608 | |
4e9b5e2b | 609 | return true; |
92b96797 FB |
610 | } |
611 | ||
612 | /* | |
613 | * Description: Read NIC TSF counter | |
614 | * Get NEXTTBTT from adjusted TSF and Beacon Interval | |
615 | * | |
616 | * Parameters: | |
617 | * In: | |
5f4dfb66 MP |
618 | * tsf - Current TSF counter |
619 | * beacon_interval - Beacon Interval | |
92b96797 | 620 | * Out: |
5f4dfb66 | 621 | * tsf - Current TSF counter |
92b96797 FB |
622 | * |
623 | * Return Value: TSF value of next Beacon | |
624 | * | |
625 | */ | |
75ef1b51 | 626 | u64 vnt_get_next_tbtt(u64 tsf, u16 beacon_interval) |
92b96797 | 627 | { |
5f4dfb66 | 628 | u32 beacon_int; |
92b96797 | 629 | |
5f4dfb66 | 630 | beacon_int = beacon_interval * 1024; |
92b96797 | 631 | |
6e28024e MP |
632 | /* Next TBTT = |
633 | * ((local_current_TSF / beacon_interval) + 1) * beacon_interval | |
634 | */ | |
5f4dfb66 MP |
635 | if (beacon_int) { |
636 | do_div(tsf, beacon_int); | |
637 | tsf += 1; | |
638 | tsf *= beacon_int; | |
6e28024e | 639 | } |
92b96797 | 640 | |
5f4dfb66 | 641 | return tsf; |
92b96797 FB |
642 | } |
643 | ||
92b96797 FB |
644 | /* |
645 | * Description: Set NIC TSF counter for first Beacon time | |
646 | * Get NEXTTBTT from adjusted TSF and Beacon Interval | |
647 | * | |
648 | * Parameters: | |
649 | * In: | |
650 | * dwIoBase - IO Base | |
414475f6 | 651 | * beacon_interval - Beacon Interval |
92b96797 FB |
652 | * Out: |
653 | * none | |
654 | * | |
655 | * Return Value: none | |
656 | * | |
657 | */ | |
6964cd12 | 658 | void vnt_reset_next_tbtt(struct vnt_private *priv, u16 beacon_interval) |
92b96797 | 659 | { |
414475f6 MP |
660 | u64 next_tbtt = 0; |
661 | u8 data[8]; | |
662 | ||
dba066e9 | 663 | vnt_clear_current_tsf(priv); |
414475f6 | 664 | |
75ef1b51 | 665 | next_tbtt = vnt_get_next_tbtt(next_tbtt, beacon_interval); |
414475f6 MP |
666 | |
667 | data[0] = (u8)next_tbtt; | |
668 | data[1] = (u8)(next_tbtt >> 8); | |
669 | data[2] = (u8)(next_tbtt >> 16); | |
670 | data[3] = (u8)(next_tbtt >> 24); | |
671 | data[4] = (u8)(next_tbtt >> 32); | |
672 | data[5] = (u8)(next_tbtt >> 40); | |
673 | data[6] = (u8)(next_tbtt >> 48); | |
674 | data[7] = (u8)(next_tbtt >> 56); | |
675 | ||
1390b02a | 676 | vnt_control_out(priv, MESSAGE_TYPE_SET_TSFTBTT, |
414475f6 | 677 | MESSAGE_REQUEST_TBTT, 0, 8, data); |
92b96797 | 678 | |
414475f6 | 679 | return; |
92b96797 FB |
680 | } |
681 | ||
92b96797 FB |
682 | /* |
683 | * Description: Sync NIC TSF counter for Beacon time | |
684 | * Get NEXTTBTT and write to HW | |
685 | * | |
686 | * Parameters: | |
687 | * In: | |
8b515de7 MP |
688 | * priv - The adapter to be set |
689 | * tsf - Current TSF counter | |
690 | * beacon_interval - Beacon Interval | |
92b96797 FB |
691 | * Out: |
692 | * none | |
693 | * | |
694 | * Return Value: none | |
695 | * | |
696 | */ | |
88ec2f7e | 697 | void vnt_update_next_tbtt(struct vnt_private *priv, u64 tsf, |
8b515de7 | 698 | u16 beacon_interval) |
92b96797 | 699 | { |
8b515de7 | 700 | u8 data[8]; |
92b96797 | 701 | |
75ef1b51 | 702 | tsf = vnt_get_next_tbtt(tsf, beacon_interval); |
7c65fa2a | 703 | |
8b515de7 MP |
704 | data[0] = (u8)tsf; |
705 | data[1] = (u8)(tsf >> 8); | |
706 | data[2] = (u8)(tsf >> 16); | |
707 | data[3] = (u8)(tsf >> 24); | |
708 | data[4] = (u8)(tsf >> 32); | |
709 | data[5] = (u8)(tsf >> 40); | |
710 | data[6] = (u8)(tsf >> 48); | |
711 | data[7] = (u8)(tsf >> 56); | |
92b96797 | 712 | |
1390b02a | 713 | vnt_control_out(priv, MESSAGE_TYPE_SET_TSFTBTT, |
42b138d9 | 714 | MESSAGE_REQUEST_TBTT, 0, 8, data); |
92b96797 | 715 | |
842e3ecc | 716 | dev_dbg(&priv->usb->dev, "%s TBTT: %8llx\n", __func__, tsf); |
92b96797 | 717 | |
8b515de7 | 718 | return; |
92b96797 FB |
719 | } |
720 | ||
721 | /* | |
722 | * Description: Turn off Radio power | |
723 | * | |
724 | * Parameters: | |
725 | * In: | |
07deb710 | 726 | * priv - The adapter to be turned off |
92b96797 FB |
727 | * Out: |
728 | * none | |
729 | * | |
4e9b5e2b | 730 | * Return Value: true if success; otherwise false |
92b96797 FB |
731 | * |
732 | */ | |
fa26e0bd | 733 | int vnt_radio_power_off(struct vnt_private *priv) |
92b96797 | 734 | { |
07deb710 MP |
735 | int ret = true; |
736 | ||
737 | priv->bRadioOff = true; | |
738 | ||
739 | switch (priv->byRFType) { | |
740 | case RF_AL2230: | |
741 | case RF_AL2230S: | |
742 | case RF_AIROHA7230: | |
743 | case RF_VT3226: | |
744 | case RF_VT3226D0: | |
745 | case RF_VT3342A0: | |
a9bed1df | 746 | vnt_mac_reg_bits_off(priv, MAC_REG_SOFTPWRCTL, |
07deb710 MP |
747 | (SOFTPWRCTL_SWPE2 | SOFTPWRCTL_SWPE3)); |
748 | break; | |
749 | } | |
92b96797 | 750 | |
a9bed1df | 751 | vnt_mac_reg_bits_off(priv, MAC_REG_HOSTCR, HOSTCR_RXON); |
92b96797 | 752 | |
07deb710 | 753 | BBvSetDeepSleep(priv); |
92b96797 | 754 | |
07deb710 | 755 | return ret; |
92b96797 FB |
756 | } |
757 | ||
92b96797 FB |
758 | /* |
759 | * Description: Turn on Radio power | |
760 | * | |
761 | * Parameters: | |
762 | * In: | |
f3203144 | 763 | * priv - The adapter to be turned on |
92b96797 FB |
764 | * Out: |
765 | * none | |
766 | * | |
4e9b5e2b | 767 | * Return Value: true if success; otherwise false |
92b96797 FB |
768 | * |
769 | */ | |
8a5e6c8c | 770 | int vnt_radio_power_on(struct vnt_private *priv) |
92b96797 | 771 | { |
f3203144 | 772 | int ret = true; |
92b96797 | 773 | |
f3203144 MP |
774 | if (priv->bHWRadioOff == true || priv->bRadioControlOff == true) |
775 | return false; | |
92b96797 | 776 | |
f3203144 | 777 | priv->bRadioOff = false; |
92b96797 | 778 | |
f3203144 | 779 | BBvExitDeepSleep(priv); |
92b96797 | 780 | |
36957537 | 781 | vnt_mac_reg_bits_on(priv, MAC_REG_HOSTCR, HOSTCR_RXON); |
92b96797 | 782 | |
f3203144 MP |
783 | switch (priv->byRFType) { |
784 | case RF_AL2230: | |
785 | case RF_AL2230S: | |
786 | case RF_AIROHA7230: | |
787 | case RF_VT3226: | |
788 | case RF_VT3226D0: | |
789 | case RF_VT3342A0: | |
36957537 | 790 | vnt_mac_reg_bits_on(priv, MAC_REG_SOFTPWRCTL, |
f3203144 MP |
791 | (SOFTPWRCTL_SWPE2 | SOFTPWRCTL_SWPE3)); |
792 | break; | |
793 | } | |
92b96797 | 794 | |
f3203144 | 795 | return ret; |
92b96797 FB |
796 | } |
797 | ||
bc240f54 | 798 | void vnt_set_bss_mode(struct vnt_private *priv) |
92b96797 | 799 | { |
1efb8fac | 800 | if (priv->byRFType == RF_AIROHA7230 && priv->byBBType == BB_TYPE_11A) |
05089fbc | 801 | vnt_mac_set_bb_type(priv, BB_TYPE_11G); |
1efb8fac | 802 | else |
05089fbc | 803 | vnt_mac_set_bb_type(priv, priv->byBBType); |
1efb8fac | 804 | |
e809c96e | 805 | priv->byPacketType = vnt_get_pkt_type(priv); |
1efb8fac MP |
806 | |
807 | if (priv->byBBType == BB_TYPE_11A) | |
285d58c4 | 808 | vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x88, 0x03); |
1efb8fac | 809 | else if (priv->byBBType == BB_TYPE_11B) |
285d58c4 | 810 | vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x88, 0x02); |
1efb8fac | 811 | else if (priv->byBBType == BB_TYPE_11G) |
285d58c4 | 812 | vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x88, 0x08); |
1efb8fac | 813 | |
c7ee9eeb | 814 | vnt_update_ifs(priv); |
1a792943 | 815 | vnt_set_rspinf(priv, (u8)priv->byBBType); |
1efb8fac MP |
816 | |
817 | if (priv->byBBType == BB_TYPE_11A) { | |
818 | if (priv->byRFType == RF_AIROHA7230) { | |
819 | priv->abyBBVGA[0] = 0x20; | |
820 | ||
285d58c4 | 821 | vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, |
1efb8fac MP |
822 | 0xe7, priv->abyBBVGA[0]); |
823 | } | |
824 | ||
825 | priv->abyBBVGA[2] = 0x10; | |
826 | priv->abyBBVGA[3] = 0x10; | |
827 | } else { | |
828 | if (priv->byRFType == RF_AIROHA7230) { | |
829 | priv->abyBBVGA[0] = 0x1c; | |
830 | ||
285d58c4 | 831 | vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, |
1efb8fac MP |
832 | 0xe7, priv->abyBBVGA[0]); |
833 | } | |
834 | ||
835 | priv->abyBBVGA[2] = 0x0; | |
836 | priv->abyBBVGA[3] = 0x0; | |
837 | } | |
d3584775 MP |
838 | |
839 | BBvSetVGAGainOffset(priv, priv->abyBBVGA[0]); | |
92b96797 | 840 | } |