xref: /openbmc/linux/drivers/staging/vt6655/card.c (revision 64288aa9)
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  */
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  */
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 data;
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, &data);
198 			if (data == 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, &data);
205 			if (data == 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, &data);
224 			if (data == 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, &data);
230 			if (data == 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, &data);
247 			if (data == 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, &data);
253 			if (data == 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  */
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  */
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  */
405 void CARDbRadioPowerOff(struct vnt_private *priv)
406 {
407 	if (priv->radio_off)
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->radio_off = true;
433 	pr_debug("chester power off\n");
434 	MACvRegBitsOn(priv->port_offset, MAC_REG_GPIOCTL0,
435 		      LED_ACTSET);  /* LED issue */
436 }
437 
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  */
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  */
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  */
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  */
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 
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 
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 
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  */
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  */
797 bool CARDbGetCurrentTSF(struct vnt_private *priv, u64 *pqwCurrTSF)
798 {
799 	void __iomem *iobase = priv->port_offset;
800 	unsigned short ww;
801 	unsigned char data;
802 
803 	MACvRegBitsOn(iobase, MAC_REG_TFTCTL, TFTCTL_TSFCNTRRD);
804 	for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
805 		VNSvInPortB(iobase + MAC_REG_TFTCTL, &data);
806 		if (!(data & 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  */
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  */
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  */
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