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