1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
4 * All rights reserved.
5 *
6 * Purpose: Provide functions to setup NIC operation mode
7 * Functions:
8 * s_vSafeResetTx - Rest Tx
9 * CARDvSetRSPINF - Set RSPINF
10 * CARDvUpdateBasicTopRate - Update BasicTopRate
11 * CARDbAddBasicRate - Add to BasicRateSet
12 * CARDbIsOFDMinBasicRate - Check if any OFDM rate is in BasicRateSet
13 * CARDqGetTSFOffset - Calculate TSFOffset
14 * CARDbGetCurrentTSF - Read Current NIC TSF counter
15 * CARDqGetNextTBTT - Calculate Next Beacon TSF counter
16 * CARDvSetFirstNextTBTT - Set NIC Beacon time
17 * CARDvUpdateNextTBTT - Sync. NIC Beacon time
18 * CARDbRadioPowerOff - Turn Off NIC Radio Power
19 *
20 * Revision History:
21 * 06-10-2003 Bryan YC Fan: Re-write codes to support VT3253 spec.
22 * 08-26-2003 Kyle Hsu: Modify the definition type of iobase.
23 * 09-01-2003 Bryan YC Fan: Add vUpdateIFS().
24 *
25 */
26
27 #include "tmacro.h"
28 #include "card.h"
29 #include "baseband.h"
30 #include "mac.h"
31 #include "desc.h"
32 #include "rf.h"
33 #include "power.h"
34
35 /*--------------------- Static Definitions -------------------------*/
36
37 #define C_SIFS_A 16 /* micro sec. */
38 #define C_SIFS_BG 10
39
40 #define C_EIFS 80 /* micro sec. */
41
42 #define C_SLOT_SHORT 9 /* micro sec. */
43 #define C_SLOT_LONG 20
44
45 #define C_CWMIN_A 15 /* slot time */
46 #define C_CWMIN_B 31
47
48 #define C_CWMAX 1023 /* slot time */
49
50 #define WAIT_BEACON_TX_DOWN_TMO 3 /* Times */
51
52 /*--------------------- Static Variables --------------------------*/
53
54 static const unsigned short cwRXBCNTSFOff[MAX_RATE] = {
55 17, 17, 17, 17, 34, 23, 17, 11, 8, 5, 4, 3};
56
57 /*--------------------- Static Functions --------------------------*/
58
59 static void s_vCalculateOFDMRParameter(unsigned char rate, u8 bb_type,
60 unsigned char *pbyTxRate,
61 unsigned char *pbyRsvTime);
62
63 /*--------------------- Export Functions --------------------------*/
64
65 /*
66 * Description: Calculate TxRate and RsvTime fields for RSPINF in OFDM mode.
67 *
68 * Parameters:
69 * In:
70 * wRate - Tx Rate
71 * byPktType - Tx Packet type
72 * Out:
73 * pbyTxRate - pointer to RSPINF TxRate field
74 * pbyRsvTime - pointer to RSPINF RsvTime field
75 *
76 * Return Value: none
77 */
s_vCalculateOFDMRParameter(unsigned char rate,u8 bb_type,unsigned char * pbyTxRate,unsigned char * pbyRsvTime)78 static void s_vCalculateOFDMRParameter(unsigned char rate,
79 u8 bb_type,
80 unsigned char *pbyTxRate,
81 unsigned char *pbyRsvTime)
82 {
83 switch (rate) {
84 case RATE_6M:
85 if (bb_type == BB_TYPE_11A) { /* 5GHZ */
86 *pbyTxRate = 0x9B;
87 *pbyRsvTime = 44;
88 } else {
89 *pbyTxRate = 0x8B;
90 *pbyRsvTime = 50;
91 }
92 break;
93
94 case RATE_9M:
95 if (bb_type == BB_TYPE_11A) { /* 5GHZ */
96 *pbyTxRate = 0x9F;
97 *pbyRsvTime = 36;
98 } else {
99 *pbyTxRate = 0x8F;
100 *pbyRsvTime = 42;
101 }
102 break;
103
104 case RATE_12M:
105 if (bb_type == BB_TYPE_11A) { /* 5GHZ */
106 *pbyTxRate = 0x9A;
107 *pbyRsvTime = 32;
108 } else {
109 *pbyTxRate = 0x8A;
110 *pbyRsvTime = 38;
111 }
112 break;
113
114 case RATE_18M:
115 if (bb_type == BB_TYPE_11A) { /* 5GHZ */
116 *pbyTxRate = 0x9E;
117 *pbyRsvTime = 28;
118 } else {
119 *pbyTxRate = 0x8E;
120 *pbyRsvTime = 34;
121 }
122 break;
123
124 case RATE_36M:
125 if (bb_type == BB_TYPE_11A) { /* 5GHZ */
126 *pbyTxRate = 0x9D;
127 *pbyRsvTime = 24;
128 } else {
129 *pbyTxRate = 0x8D;
130 *pbyRsvTime = 30;
131 }
132 break;
133
134 case RATE_48M:
135 if (bb_type == BB_TYPE_11A) { /* 5GHZ */
136 *pbyTxRate = 0x98;
137 *pbyRsvTime = 24;
138 } else {
139 *pbyTxRate = 0x88;
140 *pbyRsvTime = 30;
141 }
142 break;
143
144 case RATE_54M:
145 if (bb_type == BB_TYPE_11A) { /* 5GHZ */
146 *pbyTxRate = 0x9C;
147 *pbyRsvTime = 24;
148 } else {
149 *pbyTxRate = 0x8C;
150 *pbyRsvTime = 30;
151 }
152 break;
153
154 case RATE_24M:
155 default:
156 if (bb_type == BB_TYPE_11A) { /* 5GHZ */
157 *pbyTxRate = 0x99;
158 *pbyRsvTime = 28;
159 } else {
160 *pbyTxRate = 0x89;
161 *pbyRsvTime = 34;
162 }
163 break;
164 }
165 }
166
167 /*--------------------- Export Functions --------------------------*/
168
169 /*
170 * Description: Update IFS
171 *
172 * Parameters:
173 * In:
174 * priv - The adapter to be set
175 * Out:
176 * none
177 *
178 * Return Value: None.
179 */
CARDbSetPhyParameter(struct vnt_private * priv,u8 bb_type)180 bool CARDbSetPhyParameter(struct vnt_private *priv, u8 bb_type)
181 {
182 unsigned char byCWMaxMin = 0;
183 unsigned char bySlot = 0;
184 unsigned char bySIFS = 0;
185 unsigned char byDIFS = 0;
186 unsigned char byData;
187 int i;
188
189 /* Set SIFS, DIFS, EIFS, SlotTime, CwMin */
190 if (bb_type == BB_TYPE_11A) {
191 if (priv->byRFType == RF_AIROHA7230) {
192 /* AL7230 use single PAPE and connect to PAPE_2.4G */
193 MACvSetBBType(priv->port_offset, BB_TYPE_11G);
194 priv->abyBBVGA[0] = 0x20;
195 priv->abyBBVGA[2] = 0x10;
196 priv->abyBBVGA[3] = 0x10;
197 bb_read_embedded(priv, 0xE7, &byData);
198 if (byData == 0x1C)
199 bb_write_embedded(priv, 0xE7, priv->abyBBVGA[0]);
200
201 } else if (priv->byRFType == RF_UW2452) {
202 MACvSetBBType(priv->port_offset, BB_TYPE_11A);
203 priv->abyBBVGA[0] = 0x18;
204 bb_read_embedded(priv, 0xE7, &byData);
205 if (byData == 0x14) {
206 bb_write_embedded(priv, 0xE7, priv->abyBBVGA[0]);
207 bb_write_embedded(priv, 0xE1, 0x57);
208 }
209 } else {
210 MACvSetBBType(priv->port_offset, BB_TYPE_11A);
211 }
212 bb_write_embedded(priv, 0x88, 0x03);
213 bySlot = C_SLOT_SHORT;
214 bySIFS = C_SIFS_A;
215 byDIFS = C_SIFS_A + 2 * C_SLOT_SHORT;
216 byCWMaxMin = 0xA4;
217 } else if (bb_type == BB_TYPE_11B) {
218 MACvSetBBType(priv->port_offset, BB_TYPE_11B);
219 if (priv->byRFType == RF_AIROHA7230) {
220 priv->abyBBVGA[0] = 0x1C;
221 priv->abyBBVGA[2] = 0x00;
222 priv->abyBBVGA[3] = 0x00;
223 bb_read_embedded(priv, 0xE7, &byData);
224 if (byData == 0x20)
225 bb_write_embedded(priv, 0xE7, priv->abyBBVGA[0]);
226
227 } else if (priv->byRFType == RF_UW2452) {
228 priv->abyBBVGA[0] = 0x14;
229 bb_read_embedded(priv, 0xE7, &byData);
230 if (byData == 0x18) {
231 bb_write_embedded(priv, 0xE7, priv->abyBBVGA[0]);
232 bb_write_embedded(priv, 0xE1, 0xD3);
233 }
234 }
235 bb_write_embedded(priv, 0x88, 0x02);
236 bySlot = C_SLOT_LONG;
237 bySIFS = C_SIFS_BG;
238 byDIFS = C_SIFS_BG + 2 * C_SLOT_LONG;
239 byCWMaxMin = 0xA5;
240 } else { /* PK_TYPE_11GA & PK_TYPE_11GB */
241 MACvSetBBType(priv->port_offset, BB_TYPE_11G);
242 if (priv->byRFType == RF_AIROHA7230) {
243 priv->abyBBVGA[0] = 0x1C;
244 priv->abyBBVGA[2] = 0x00;
245 priv->abyBBVGA[3] = 0x00;
246 bb_read_embedded(priv, 0xE7, &byData);
247 if (byData == 0x20)
248 bb_write_embedded(priv, 0xE7, priv->abyBBVGA[0]);
249
250 } else if (priv->byRFType == RF_UW2452) {
251 priv->abyBBVGA[0] = 0x14;
252 bb_read_embedded(priv, 0xE7, &byData);
253 if (byData == 0x18) {
254 bb_write_embedded(priv, 0xE7, priv->abyBBVGA[0]);
255 bb_write_embedded(priv, 0xE1, 0xD3);
256 }
257 }
258 bb_write_embedded(priv, 0x88, 0x08);
259 bySIFS = C_SIFS_BG;
260
261 if (priv->short_slot_time) {
262 bySlot = C_SLOT_SHORT;
263 byDIFS = C_SIFS_BG + 2 * C_SLOT_SHORT;
264 } else {
265 bySlot = C_SLOT_LONG;
266 byDIFS = C_SIFS_BG + 2 * C_SLOT_LONG;
267 }
268
269 byCWMaxMin = 0xa4;
270
271 for (i = RATE_54M; i >= RATE_6M; i--) {
272 if (priv->basic_rates & ((u32)(0x1 << i))) {
273 byCWMaxMin |= 0x1;
274 break;
275 }
276 }
277 }
278
279 if (priv->byRFType == RF_RFMD2959) {
280 /*
281 * bcs TX_PE will reserve 3 us hardware's processing
282 * time here is 2 us.
283 */
284 bySIFS -= 3;
285 byDIFS -= 3;
286 /*
287 * TX_PE will reserve 3 us for MAX2829 A mode only, it is for
288 * better TX throughput; MAC will need 2 us to process, so the
289 * SIFS, DIFS can be shorter by 2 us.
290 */
291 }
292
293 if (priv->bySIFS != bySIFS) {
294 priv->bySIFS = bySIFS;
295 VNSvOutPortB(priv->port_offset + MAC_REG_SIFS, priv->bySIFS);
296 }
297 if (priv->byDIFS != byDIFS) {
298 priv->byDIFS = byDIFS;
299 VNSvOutPortB(priv->port_offset + MAC_REG_DIFS, priv->byDIFS);
300 }
301 if (priv->byEIFS != C_EIFS) {
302 priv->byEIFS = C_EIFS;
303 VNSvOutPortB(priv->port_offset + MAC_REG_EIFS, priv->byEIFS);
304 }
305 if (priv->bySlot != bySlot) {
306 priv->bySlot = bySlot;
307 VNSvOutPortB(priv->port_offset + MAC_REG_SLOT, priv->bySlot);
308
309 bb_set_short_slot_time(priv);
310 }
311 if (priv->byCWMaxMin != byCWMaxMin) {
312 priv->byCWMaxMin = byCWMaxMin;
313 VNSvOutPortB(priv->port_offset + MAC_REG_CWMAXMIN0,
314 priv->byCWMaxMin);
315 }
316
317 priv->byPacketType = CARDbyGetPktType(priv);
318
319 CARDvSetRSPINF(priv, bb_type);
320
321 return true;
322 }
323
324 /*
325 * Description: Sync. TSF counter to BSS
326 * Get TSF offset and write to HW
327 *
328 * Parameters:
329 * In:
330 * priv - The adapter to be sync.
331 * byRxRate - data rate of receive beacon
332 * qwBSSTimestamp - Rx BCN's TSF
333 * qwLocalTSF - Local TSF
334 * Out:
335 * none
336 *
337 * Return Value: none
338 */
CARDbUpdateTSF(struct vnt_private * priv,unsigned char byRxRate,u64 qwBSSTimestamp)339 bool CARDbUpdateTSF(struct vnt_private *priv, unsigned char byRxRate,
340 u64 qwBSSTimestamp)
341 {
342 u64 local_tsf;
343 u64 qwTSFOffset = 0;
344
345 CARDbGetCurrentTSF(priv, &local_tsf);
346
347 if (qwBSSTimestamp != local_tsf) {
348 qwTSFOffset = CARDqGetTSFOffset(byRxRate, qwBSSTimestamp,
349 local_tsf);
350 /* adjust TSF, HW's TSF add TSF Offset reg */
351 VNSvOutPortD(priv->port_offset + MAC_REG_TSFOFST,
352 (u32)qwTSFOffset);
353 VNSvOutPortD(priv->port_offset + MAC_REG_TSFOFST + 4,
354 (u32)(qwTSFOffset >> 32));
355 MACvRegBitsOn(priv->port_offset, MAC_REG_TFTCTL,
356 TFTCTL_TSFSYNCEN);
357 }
358 return true;
359 }
360
361 /*
362 * Description: Set NIC TSF counter for first Beacon time
363 * Get NEXTTBTT from adjusted TSF and Beacon Interval
364 *
365 * Parameters:
366 * In:
367 * priv - The adapter to be set.
368 * wBeaconInterval - Beacon Interval
369 * Out:
370 * none
371 *
372 * Return Value: true if succeed; otherwise false
373 */
CARDbSetBeaconPeriod(struct vnt_private * priv,unsigned short wBeaconInterval)374 bool CARDbSetBeaconPeriod(struct vnt_private *priv,
375 unsigned short wBeaconInterval)
376 {
377 u64 qwNextTBTT = 0;
378
379 CARDbGetCurrentTSF(priv, &qwNextTBTT); /* Get Local TSF counter */
380
381 qwNextTBTT = CARDqGetNextTBTT(qwNextTBTT, wBeaconInterval);
382
383 /* set HW beacon interval */
384 VNSvOutPortW(priv->port_offset + MAC_REG_BI, wBeaconInterval);
385 priv->wBeaconInterval = wBeaconInterval;
386 /* Set NextTBTT */
387 VNSvOutPortD(priv->port_offset + MAC_REG_NEXTTBTT, (u32)qwNextTBTT);
388 VNSvOutPortD(priv->port_offset + MAC_REG_NEXTTBTT + 4,
389 (u32)(qwNextTBTT >> 32));
390 MACvRegBitsOn(priv->port_offset, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN);
391
392 return true;
393 }
394
395 /*
396 * Description: Turn off Radio power
397 *
398 * Parameters:
399 * In:
400 * priv - The adapter to be turned off
401 * Out:
402 * none
403 *
404 */
CARDbRadioPowerOff(struct vnt_private * priv)405 void CARDbRadioPowerOff(struct vnt_private *priv)
406 {
407 if (priv->bRadioOff)
408 return;
409
410 switch (priv->byRFType) {
411 case RF_RFMD2959:
412 MACvWordRegBitsOff(priv->port_offset, MAC_REG_SOFTPWRCTL,
413 SOFTPWRCTL_TXPEINV);
414 MACvWordRegBitsOn(priv->port_offset, MAC_REG_SOFTPWRCTL,
415 SOFTPWRCTL_SWPE1);
416 break;
417
418 case RF_AIROHA:
419 case RF_AL2230S:
420 case RF_AIROHA7230:
421 MACvWordRegBitsOff(priv->port_offset, MAC_REG_SOFTPWRCTL,
422 SOFTPWRCTL_SWPE2);
423 MACvWordRegBitsOff(priv->port_offset, MAC_REG_SOFTPWRCTL,
424 SOFTPWRCTL_SWPE3);
425 break;
426 }
427
428 MACvRegBitsOff(priv->port_offset, MAC_REG_HOSTCR, HOSTCR_RXON);
429
430 bb_set_deep_sleep(priv, priv->local_id);
431
432 priv->bRadioOff = true;
433 pr_debug("chester power off\n");
434 MACvRegBitsOn(priv->port_offset, MAC_REG_GPIOCTL0,
435 LED_ACTSET); /* LED issue */
436 }
437
CARDvSafeResetTx(struct vnt_private * priv)438 void CARDvSafeResetTx(struct vnt_private *priv)
439 {
440 unsigned int uu;
441 struct vnt_tx_desc *pCurrTD;
442
443 /* initialize TD index */
444 priv->apTailTD[0] = &priv->apTD0Rings[0];
445 priv->apCurrTD[0] = &priv->apTD0Rings[0];
446
447 priv->apTailTD[1] = &priv->apTD1Rings[0];
448 priv->apCurrTD[1] = &priv->apTD1Rings[0];
449
450 for (uu = 0; uu < TYPE_MAXTD; uu++)
451 priv->iTDUsed[uu] = 0;
452
453 for (uu = 0; uu < priv->opts.tx_descs[0]; uu++) {
454 pCurrTD = &priv->apTD0Rings[uu];
455 pCurrTD->td0.owner = OWNED_BY_HOST;
456 /* init all Tx Packet pointer to NULL */
457 }
458 for (uu = 0; uu < priv->opts.tx_descs[1]; uu++) {
459 pCurrTD = &priv->apTD1Rings[uu];
460 pCurrTD->td0.owner = OWNED_BY_HOST;
461 /* init all Tx Packet pointer to NULL */
462 }
463
464 /* set MAC TD pointer */
465 MACvSetCurrTXDescAddr(TYPE_TXDMA0, priv, priv->td0_pool_dma);
466
467 MACvSetCurrTXDescAddr(TYPE_AC0DMA, priv, priv->td1_pool_dma);
468
469 /* set MAC Beacon TX pointer */
470 MACvSetCurrBCNTxDescAddr(priv->port_offset,
471 (priv->tx_beacon_dma));
472 }
473
474 /*
475 * Description:
476 * Reset Rx
477 *
478 * Parameters:
479 * In:
480 * priv - Pointer to the adapter
481 * Out:
482 * none
483 *
484 * Return Value: none
485 */
CARDvSafeResetRx(struct vnt_private * priv)486 void CARDvSafeResetRx(struct vnt_private *priv)
487 {
488 unsigned int uu;
489 struct vnt_rx_desc *pDesc;
490
491 /* initialize RD index */
492 priv->pCurrRD[0] = &priv->aRD0Ring[0];
493 priv->pCurrRD[1] = &priv->aRD1Ring[0];
494
495 /* init state, all RD is chip's */
496 for (uu = 0; uu < priv->opts.rx_descs0; uu++) {
497 pDesc = &priv->aRD0Ring[uu];
498 pDesc->rd0.res_count = cpu_to_le16(priv->rx_buf_sz);
499 pDesc->rd0.owner = OWNED_BY_NIC;
500 pDesc->rd1.req_count = cpu_to_le16(priv->rx_buf_sz);
501 }
502
503 /* init state, all RD is chip's */
504 for (uu = 0; uu < priv->opts.rx_descs1; uu++) {
505 pDesc = &priv->aRD1Ring[uu];
506 pDesc->rd0.res_count = cpu_to_le16(priv->rx_buf_sz);
507 pDesc->rd0.owner = OWNED_BY_NIC;
508 pDesc->rd1.req_count = cpu_to_le16(priv->rx_buf_sz);
509 }
510
511 /* set perPkt mode */
512 MACvRx0PerPktMode(priv->port_offset);
513 MACvRx1PerPktMode(priv->port_offset);
514 /* set MAC RD pointer */
515 MACvSetCurrRx0DescAddr(priv, priv->rd0_pool_dma);
516
517 MACvSetCurrRx1DescAddr(priv, priv->rd1_pool_dma);
518 }
519
520 /*
521 * Description: Get response Control frame rate in CCK mode
522 *
523 * Parameters:
524 * In:
525 * priv - The adapter to be set
526 * wRateIdx - Receiving data rate
527 * Out:
528 * none
529 *
530 * Return Value: response Control frame rate
531 */
CARDwGetCCKControlRate(struct vnt_private * priv,unsigned short wRateIdx)532 static unsigned short CARDwGetCCKControlRate(struct vnt_private *priv,
533 unsigned short wRateIdx)
534 {
535 unsigned int ui = (unsigned int)wRateIdx;
536
537 while (ui > RATE_1M) {
538 if (priv->basic_rates & ((u32)0x1 << ui))
539 return (unsigned short)ui;
540
541 ui--;
542 }
543 return (unsigned short)RATE_1M;
544 }
545
546 /*
547 * Description: Get response Control frame rate in OFDM mode
548 *
549 * Parameters:
550 * In:
551 * priv - The adapter to be set
552 * wRateIdx - Receiving data rate
553 * Out:
554 * none
555 *
556 * Return Value: response Control frame rate
557 */
CARDwGetOFDMControlRate(struct vnt_private * priv,unsigned short wRateIdx)558 static unsigned short CARDwGetOFDMControlRate(struct vnt_private *priv,
559 unsigned short wRateIdx)
560 {
561 unsigned int ui = (unsigned int)wRateIdx;
562
563 pr_debug("BASIC RATE: %X\n", priv->basic_rates);
564
565 if (!CARDbIsOFDMinBasicRate((void *)priv)) {
566 pr_debug("%s:(NO OFDM) %d\n", __func__, wRateIdx);
567 if (wRateIdx > RATE_24M)
568 wRateIdx = RATE_24M;
569 return wRateIdx;
570 }
571 while (ui > RATE_11M) {
572 if (priv->basic_rates & ((u32)0x1 << ui)) {
573 pr_debug("%s : %d\n", __func__, ui);
574 return (unsigned short)ui;
575 }
576 ui--;
577 }
578 pr_debug("%s: 6M\n", __func__);
579 return (unsigned short)RATE_24M;
580 }
581
582 /*
583 * Description: Set RSPINF
584 *
585 * Parameters:
586 * In:
587 * priv - The adapter to be set
588 * Out:
589 * none
590 *
591 * Return Value: None.
592 */
CARDvSetRSPINF(struct vnt_private * priv,u8 bb_type)593 void CARDvSetRSPINF(struct vnt_private *priv, u8 bb_type)
594 {
595 union vnt_phy_field_swap phy;
596 unsigned char byTxRate, byRsvTime; /* For OFDM */
597 unsigned long flags;
598
599 spin_lock_irqsave(&priv->lock, flags);
600
601 /* Set to Page1 */
602 MACvSelectPage1(priv->port_offset);
603
604 /* RSPINF_b_1 */
605 vnt_get_phy_field(priv, 14,
606 CARDwGetCCKControlRate(priv, RATE_1M),
607 PK_TYPE_11B, &phy.field_read);
608
609 /* swap over to get correct write order */
610 swap(phy.swap[0], phy.swap[1]);
611
612 VNSvOutPortD(priv->port_offset + MAC_REG_RSPINF_B_1, phy.field_write);
613
614 /* RSPINF_b_2 */
615 vnt_get_phy_field(priv, 14,
616 CARDwGetCCKControlRate(priv, RATE_2M),
617 PK_TYPE_11B, &phy.field_read);
618
619 swap(phy.swap[0], phy.swap[1]);
620
621 VNSvOutPortD(priv->port_offset + MAC_REG_RSPINF_B_2, phy.field_write);
622
623 /* RSPINF_b_5 */
624 vnt_get_phy_field(priv, 14,
625 CARDwGetCCKControlRate(priv, RATE_5M),
626 PK_TYPE_11B, &phy.field_read);
627
628 swap(phy.swap[0], phy.swap[1]);
629
630 VNSvOutPortD(priv->port_offset + MAC_REG_RSPINF_B_5, phy.field_write);
631
632 /* RSPINF_b_11 */
633 vnt_get_phy_field(priv, 14,
634 CARDwGetCCKControlRate(priv, RATE_11M),
635 PK_TYPE_11B, &phy.field_read);
636
637 swap(phy.swap[0], phy.swap[1]);
638
639 VNSvOutPortD(priv->port_offset + MAC_REG_RSPINF_B_11, phy.field_write);
640
641 /* RSPINF_a_6 */
642 s_vCalculateOFDMRParameter(RATE_6M,
643 bb_type,
644 &byTxRate,
645 &byRsvTime);
646 VNSvOutPortW(priv->port_offset + MAC_REG_RSPINF_A_6,
647 MAKEWORD(byTxRate, byRsvTime));
648 /* RSPINF_a_9 */
649 s_vCalculateOFDMRParameter(RATE_9M,
650 bb_type,
651 &byTxRate,
652 &byRsvTime);
653 VNSvOutPortW(priv->port_offset + MAC_REG_RSPINF_A_9,
654 MAKEWORD(byTxRate, byRsvTime));
655 /* RSPINF_a_12 */
656 s_vCalculateOFDMRParameter(RATE_12M,
657 bb_type,
658 &byTxRate,
659 &byRsvTime);
660 VNSvOutPortW(priv->port_offset + MAC_REG_RSPINF_A_12,
661 MAKEWORD(byTxRate, byRsvTime));
662 /* RSPINF_a_18 */
663 s_vCalculateOFDMRParameter(RATE_18M,
664 bb_type,
665 &byTxRate,
666 &byRsvTime);
667 VNSvOutPortW(priv->port_offset + MAC_REG_RSPINF_A_18,
668 MAKEWORD(byTxRate, byRsvTime));
669 /* RSPINF_a_24 */
670 s_vCalculateOFDMRParameter(RATE_24M,
671 bb_type,
672 &byTxRate,
673 &byRsvTime);
674 VNSvOutPortW(priv->port_offset + MAC_REG_RSPINF_A_24,
675 MAKEWORD(byTxRate, byRsvTime));
676 /* RSPINF_a_36 */
677 s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)priv,
678 RATE_36M),
679 bb_type,
680 &byTxRate,
681 &byRsvTime);
682 VNSvOutPortW(priv->port_offset + MAC_REG_RSPINF_A_36,
683 MAKEWORD(byTxRate, byRsvTime));
684 /* RSPINF_a_48 */
685 s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)priv,
686 RATE_48M),
687 bb_type,
688 &byTxRate,
689 &byRsvTime);
690 VNSvOutPortW(priv->port_offset + MAC_REG_RSPINF_A_48,
691 MAKEWORD(byTxRate, byRsvTime));
692 /* RSPINF_a_54 */
693 s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)priv,
694 RATE_54M),
695 bb_type,
696 &byTxRate,
697 &byRsvTime);
698 VNSvOutPortW(priv->port_offset + MAC_REG_RSPINF_A_54,
699 MAKEWORD(byTxRate, byRsvTime));
700 /* RSPINF_a_72 */
701 s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)priv,
702 RATE_54M),
703 bb_type,
704 &byTxRate,
705 &byRsvTime);
706 VNSvOutPortW(priv->port_offset + MAC_REG_RSPINF_A_72,
707 MAKEWORD(byTxRate, byRsvTime));
708 /* Set to Page0 */
709 MACvSelectPage0(priv->port_offset);
710
711 spin_unlock_irqrestore(&priv->lock, flags);
712 }
713
CARDvUpdateBasicTopRate(struct vnt_private * priv)714 void CARDvUpdateBasicTopRate(struct vnt_private *priv)
715 {
716 unsigned char byTopOFDM = RATE_24M, byTopCCK = RATE_1M;
717 unsigned char ii;
718
719 /* Determines the highest basic rate. */
720 for (ii = RATE_54M; ii >= RATE_6M; ii--) {
721 if ((priv->basic_rates) & ((u32)(1 << ii))) {
722 byTopOFDM = ii;
723 break;
724 }
725 }
726 priv->byTopOFDMBasicRate = byTopOFDM;
727
728 for (ii = RATE_11M;; ii--) {
729 if ((priv->basic_rates) & ((u32)(1 << ii))) {
730 byTopCCK = ii;
731 break;
732 }
733 if (ii == RATE_1M)
734 break;
735 }
736 priv->byTopCCKBasicRate = byTopCCK;
737 }
738
CARDbIsOFDMinBasicRate(struct vnt_private * priv)739 bool CARDbIsOFDMinBasicRate(struct vnt_private *priv)
740 {
741 int ii;
742
743 for (ii = RATE_54M; ii >= RATE_6M; ii--) {
744 if ((priv->basic_rates) & ((u32)BIT(ii)))
745 return true;
746 }
747 return false;
748 }
749
CARDbyGetPktType(struct vnt_private * priv)750 unsigned char CARDbyGetPktType(struct vnt_private *priv)
751 {
752 if (priv->byBBType == BB_TYPE_11A || priv->byBBType == BB_TYPE_11B)
753 return (unsigned char)priv->byBBType;
754 else if (CARDbIsOFDMinBasicRate((void *)priv))
755 return PK_TYPE_11GA;
756 else
757 return PK_TYPE_11GB;
758 }
759
760 /*
761 * Description: Calculate TSF offset of two TSF input
762 * Get TSF Offset from RxBCN's TSF and local TSF
763 *
764 * Parameters:
765 * In:
766 * priv - The adapter to be sync.
767 * qwTSF1 - Rx BCN's TSF
768 * qwTSF2 - Local TSF
769 * Out:
770 * none
771 *
772 * Return Value: TSF Offset value
773 */
CARDqGetTSFOffset(unsigned char byRxRate,u64 qwTSF1,u64 qwTSF2)774 u64 CARDqGetTSFOffset(unsigned char byRxRate, u64 qwTSF1, u64 qwTSF2)
775 {
776 unsigned short wRxBcnTSFOffst;
777
778 wRxBcnTSFOffst = cwRXBCNTSFOff[byRxRate % MAX_RATE];
779
780 qwTSF2 += (u64)wRxBcnTSFOffst;
781
782 return qwTSF1 - qwTSF2;
783 }
784
785 /*
786 * Description: Read NIC TSF counter
787 * Get local TSF counter
788 *
789 * Parameters:
790 * In:
791 * priv - The adapter to be read
792 * Out:
793 * qwCurrTSF - Current TSF counter
794 *
795 * Return Value: true if success; otherwise false
796 */
CARDbGetCurrentTSF(struct vnt_private * priv,u64 * pqwCurrTSF)797 bool CARDbGetCurrentTSF(struct vnt_private *priv, u64 *pqwCurrTSF)
798 {
799 void __iomem *iobase = priv->port_offset;
800 unsigned short ww;
801 unsigned char byData;
802
803 MACvRegBitsOn(iobase, MAC_REG_TFTCTL, TFTCTL_TSFCNTRRD);
804 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
805 VNSvInPortB(iobase + MAC_REG_TFTCTL, &byData);
806 if (!(byData & TFTCTL_TSFCNTRRD))
807 break;
808 }
809 if (ww == W_MAX_TIMEOUT)
810 return false;
811 VNSvInPortD(iobase + MAC_REG_TSFCNTR, (u32 *)pqwCurrTSF);
812 VNSvInPortD(iobase + MAC_REG_TSFCNTR + 4, (u32 *)pqwCurrTSF + 1);
813
814 return true;
815 }
816
817 /*
818 * Description: Read NIC TSF counter
819 * Get NEXTTBTT from adjusted TSF and Beacon Interval
820 *
821 * Parameters:
822 * In:
823 * qwTSF - Current TSF counter
824 * wbeaconInterval - Beacon Interval
825 * Out:
826 * qwCurrTSF - Current TSF counter
827 *
828 * Return Value: TSF value of next Beacon
829 */
CARDqGetNextTBTT(u64 qwTSF,unsigned short wBeaconInterval)830 u64 CARDqGetNextTBTT(u64 qwTSF, unsigned short wBeaconInterval)
831 {
832 u32 beacon_int;
833
834 beacon_int = wBeaconInterval * 1024;
835 if (beacon_int) {
836 do_div(qwTSF, beacon_int);
837 qwTSF += 1;
838 qwTSF *= beacon_int;
839 }
840
841 return qwTSF;
842 }
843
844 /*
845 * Description: Set NIC TSF counter for first Beacon time
846 * Get NEXTTBTT from adjusted TSF and Beacon Interval
847 *
848 * Parameters:
849 * In:
850 * iobase - IO Base
851 * wBeaconInterval - Beacon Interval
852 * Out:
853 * none
854 *
855 * Return Value: none
856 */
CARDvSetFirstNextTBTT(struct vnt_private * priv,unsigned short wBeaconInterval)857 void CARDvSetFirstNextTBTT(struct vnt_private *priv,
858 unsigned short wBeaconInterval)
859 {
860 void __iomem *iobase = priv->port_offset;
861 u64 qwNextTBTT = 0;
862
863 CARDbGetCurrentTSF(priv, &qwNextTBTT); /* Get Local TSF counter */
864
865 qwNextTBTT = CARDqGetNextTBTT(qwNextTBTT, wBeaconInterval);
866 /* Set NextTBTT */
867 VNSvOutPortD(iobase + MAC_REG_NEXTTBTT, (u32)qwNextTBTT);
868 VNSvOutPortD(iobase + MAC_REG_NEXTTBTT + 4, (u32)(qwNextTBTT >> 32));
869 MACvRegBitsOn(iobase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN);
870 }
871
872 /*
873 * Description: Sync NIC TSF counter for Beacon time
874 * Get NEXTTBTT and write to HW
875 *
876 * Parameters:
877 * In:
878 * priv - The adapter to be set
879 * qwTSF - Current TSF counter
880 * wBeaconInterval - Beacon Interval
881 * Out:
882 * none
883 *
884 * Return Value: none
885 */
CARDvUpdateNextTBTT(struct vnt_private * priv,u64 qwTSF,unsigned short wBeaconInterval)886 void CARDvUpdateNextTBTT(struct vnt_private *priv, u64 qwTSF,
887 unsigned short wBeaconInterval)
888 {
889 void __iomem *iobase = priv->port_offset;
890
891 qwTSF = CARDqGetNextTBTT(qwTSF, wBeaconInterval);
892 /* Set NextTBTT */
893 VNSvOutPortD(iobase + MAC_REG_NEXTTBTT, (u32)qwTSF);
894 VNSvOutPortD(iobase + MAC_REG_NEXTTBTT + 4, (u32)(qwTSF >> 32));
895 MACvRegBitsOn(iobase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN);
896 pr_debug("Card:Update Next TBTT[%8llx]\n", qwTSF);
897 }
898