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