r819xU_phy.c 56.6 KB
Newer Older
1 2 3 4 5 6 7 8 9
#include "r8192U.h"
#include "r8192U_hw.h"
#include "r819xU_phy.h"
#include "r819xU_phyreg.h"
#include "r8190_rtl8256.h"
#include "r8192U_dm.h"
#include "r819xU_firmware_img.h"

#include "dot11d.h"
10 11
#include <linux/bitops.h>

12 13
static u32 RF_CHANNEL_TABLE_ZEBRA[] = {
	0,
14 15 16 17 18 19 20 21 22 23 24 25 26 27
	0x085c, /* 2412 1  */
	0x08dc, /* 2417 2  */
	0x095c, /* 2422 3  */
	0x09dc, /* 2427 4  */
	0x0a5c, /* 2432 5  */
	0x0adc, /* 2437 6  */
	0x0b5c, /* 2442 7  */
	0x0bdc, /* 2447 8  */
	0x0c5c, /* 2452 9  */
	0x0cdc, /* 2457 10 */
	0x0d5c, /* 2462 11 */
	0x0ddc, /* 2467 12 */
	0x0e5c, /* 2472 13 */
	0x0f72, /* 2484    */
28 29 30 31 32 33 34 35 36 37 38 39 40
};


#define rtl819XPHY_REG_1T2RArray Rtl8192UsbPHY_REG_1T2RArray
#define rtl819XMACPHY_Array_PG Rtl8192UsbMACPHY_Array_PG
#define rtl819XMACPHY_Array Rtl8192UsbMACPHY_Array
#define rtl819XRadioA_Array  Rtl8192UsbRadioA_Array
#define rtl819XRadioB_Array Rtl8192UsbRadioB_Array
#define rtl819XRadioC_Array Rtl8192UsbRadioC_Array
#define rtl819XRadioD_Array Rtl8192UsbRadioD_Array
#define rtl819XAGCTAB_Array Rtl8192UsbAGCTAB_Array

/******************************************************************************
41 42 43 44 45 46 47
 * function:  This function checks different RF type to execute legal judgement.
 *            If RF Path is illegal, we will return false.
 * input:     net_device	 *dev
 *            u32		 eRFPath
 * output:    none
 * return:    0(illegal, false), 1(legal, true)
 *****************************************************************************/
48
u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device *dev, u32 eRFPath)
49 50 51
{
	u8 ret = 1;
	struct r8192_priv *priv = ieee80211_priv(dev);
52

53
	if (priv->rf_type == RF_2T4R) {
54
		ret = 0;
55
	} else if (priv->rf_type == RF_1T2R) {
56 57 58 59 60 61 62
		if (eRFPath == RF90_PATH_A || eRFPath == RF90_PATH_B)
			ret = 1;
		else if (eRFPath == RF90_PATH_C || eRFPath == RF90_PATH_D)
			ret = 0;
	}
	return ret;
}
63

64
/******************************************************************************
65 66 67 68 69 70 71 72 73
 * function:  This function sets specific bits to BB register
 * input:     net_device *dev
 *            u32        reg_addr   //target addr to be modified
 *            u32        bitmask    //taget bit pos to be modified
 *            u32        data       //value to be write
 * output:    none
 * return:    none
 * notice:
 ******************************************************************************/
74 75
void rtl8192_setBBreg(struct net_device *dev, u32 reg_addr, u32 bitmask,
		      u32 data)
76 77
{

78
	u32 reg, bitshift;
79

80
	if (bitmask != bMaskDWord) {
81
		read_nic_dword(dev, reg_addr, &reg);
82
		bitshift = ffs(bitmask) - 1;
83
		reg &= ~bitmask;
84 85
		reg |= data << bitshift;
		write_nic_dword(dev, reg_addr, reg);
86
	} else {
87
		write_nic_dword(dev, reg_addr, data);
88
	}
89
}
90

91
/******************************************************************************
92 93
 * function:  This function reads specific bits from BB register
 * input:     net_device	*dev
94 95
 *            u32		reg_addr   //target addr to be readback
 *            u32		bitmask    //taget bit pos to be readback
96
 * output:    none
97
 * return:    u32		data       //the readback register value
98 99
 * notice:
 ******************************************************************************/
100
u32 rtl8192_QueryBBReg(struct net_device *dev, u32 reg_addr, u32 bitmask)
101
{
102
	u32 reg, bitshift;
103

104
	read_nic_dword(dev, reg_addr, &reg);
105
	bitshift = ffs(bitmask) - 1;
106

107
	return (reg & bitmask) >> bitshift;
108
}
109

110
static u32 phy_FwRFSerialRead(struct net_device *dev, RF90_RADIO_PATH_E eRFPath,
111
			      u32 offset);
112

113
static void phy_FwRFSerialWrite(struct net_device *dev,
114 115
				RF90_RADIO_PATH_E eRFPath, u32  offset,
				u32  data);
116 117

/******************************************************************************
118 119 120 121 122 123 124 125 126 127 128 129 130
 * function:  This function reads register from RF chip
 * input:     net_device        *dev
 *            RF90_RADIO_PATH_E eRFPath    //radio path of A/B/C/D
 *            u32               offset     //target address to be read
 * output:    none
 * return:    u32               readback value
 * notice:    There are three types of serial operations:
 *            (1) Software serial write.
 *            (2)Hardware LSSI-Low Speed Serial Interface.
 *            (3)Hardware HSSI-High speed serial write.
 *            Driver here need to implement (1) and (2)
 *            ---need more spec for this information.
 ******************************************************************************/
131 132
static u32 rtl8192_phy_RFSerialRead(struct net_device *dev,
				    RF90_RADIO_PATH_E eRFPath, u32 offset)
133 134 135
{
	struct r8192_priv *priv = ieee80211_priv(dev);
	u32 ret = 0;
136
	u32 new_offset = 0;
137
	BB_REGISTER_DEFINITION_T *pPhyReg = &priv->PHYRegDef[eRFPath];
138

139
	rtl8192_setBBreg(dev, pPhyReg->rfLSSIReadBack, bLSSIReadBackData, 0);
140
	/* Make sure RF register offset is correct */
141
	offset &= 0x3f;
142

143
	/* Switch page for 8256 RF IC */
144
	if (priv->rf_chip == RF_8256) {
145
		if (offset >= 31) {
146
			priv->RfReg0Value[eRFPath] |= 0x140;
147
			/* Switch to Reg_Mode2 for Reg 31-45 */
148 149 150
			rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset,
					 bMaskDWord,
					 priv->RfReg0Value[eRFPath]<<16);
151
			/* Modify offset */
152 153
			new_offset = offset - 30;
		} else if (offset >= 16) {
154 155
			priv->RfReg0Value[eRFPath] |= 0x100;
			priv->RfReg0Value[eRFPath] &= (~0x40);
156
			/* Switch to Reg_Mode1 for Reg16-30 */
157 158 159
			rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset,
					 bMaskDWord,
					 priv->RfReg0Value[eRFPath]<<16);
160

161
			new_offset = offset - 15;
162
		} else {
163
			new_offset = offset;
164 165
		}
	} else {
166 167
		RT_TRACE((COMP_PHY|COMP_ERR),
			 "check RF type here, need to be 8256\n");
168
		new_offset = offset;
169
	}
170
	/* Put desired read addr to LSSI control Register */
171 172
	rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, bLSSIReadAddress,
			 new_offset);
173
	/* Issue a posedge trigger */
174 175 176 177
	rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2,  bLSSIReadEdge, 0x0);
	rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2,  bLSSIReadEdge, 0x1);


178
	/* TODO: we should not delay such a long time. Ask for help from SD3 */
179
	usleep_range(1000, 1000);
180

181 182
	ret = rtl8192_QueryBBReg(dev, pPhyReg->rfLSSIReadBack,
				 bLSSIReadBackData);
183 184


185
	/* Switch back to Reg_Mode0 */
186
	if (priv->rf_chip == RF_8256) {
187 188
		priv->RfReg0Value[eRFPath] &= 0xebf;

189 190
		rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord,
				 priv->RfReg0Value[eRFPath] << 16);
191 192 193 194 195 196
	}

	return ret;
}

/******************************************************************************
197 198 199 200 201 202 203 204 205 206
 * function:  This function writes data to RF register
 * input:     net_device        *dev
 *            RF90_RADIO_PATH_E eRFPath  //radio path of A/B/C/D
 *            u32               offset   //target address to be written
 *            u32               data	 //the new register data to be written
 * output:    none
 * return:    none
 * notice:    For RF8256 only.
 * ===========================================================================
 * Reg Mode	RegCTL[1]	RegCTL[0]		Note
207
 *		(Reg00[12])	(Reg00[10])
208 209 210 211 212
 * ===========================================================================
 * Reg_Mode0	0		x			Reg 0 ~ 15(0x0 ~ 0xf)
 * ---------------------------------------------------------------------------
 * Reg_Mode1	1		0			Reg 16 ~ 30(0x1 ~ 0xf)
 * ---------------------------------------------------------------------------
213
 * Reg_Mode2	1		1			Reg 31 ~ 45(0x1 ~ 0xf)
214 215
 * ---------------------------------------------------------------------------
 *****************************************************************************/
216 217 218
static void rtl8192_phy_RFSerialWrite(struct net_device *dev,
				      RF90_RADIO_PATH_E eRFPath, u32 offset,
				      u32 data)
219 220
{
	struct r8192_priv *priv = ieee80211_priv(dev);
221
	u32 DataAndAddr = 0, new_offset = 0;
222 223
	BB_REGISTER_DEFINITION_T	*pPhyReg = &priv->PHYRegDef[eRFPath];

224
	offset &= 0x3f;
225
	if (priv->rf_chip == RF_8256) {
226

227
		if (offset >= 31) {
228
			priv->RfReg0Value[eRFPath] |= 0x140;
229 230 231
			rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset,
					 bMaskDWord,
					 priv->RfReg0Value[eRFPath] << 16);
232 233
			new_offset = offset - 30;
		} else if (offset >= 16) {
234 235
			priv->RfReg0Value[eRFPath] |= 0x100;
			priv->RfReg0Value[eRFPath] &= (~0x40);
236 237 238
			rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset,
					 bMaskDWord,
					 priv->RfReg0Value[eRFPath]<<16);
239
			new_offset = offset - 15;
240
		} else {
241
			new_offset = offset;
242 243
		}
	} else {
244 245
		RT_TRACE((COMP_PHY|COMP_ERR),
			 "check RF type here, need to be 8256\n");
246
		new_offset = offset;
247 248
	}

249
	/* Put write addr in [5:0] and write data in [31:16] */
250
	DataAndAddr = (data<<16) | (new_offset&0x3f);
251

252
	/* Write operation */
253 254 255
	rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, DataAndAddr);


256 257
	if (offset == 0x0)
		priv->RfReg0Value[eRFPath] = data;
258

259
	/* Switch back to Reg_Mode0 */
260
	if (priv->rf_chip == RF_8256) {
261
		if (offset != 0) {
262
			priv->RfReg0Value[eRFPath] &= 0xebf;
263 264 265
			rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset,
					 bMaskDWord,
					 priv->RfReg0Value[eRFPath] << 16);
266 267 268 269 270
		}
	}
}

/******************************************************************************
271 272 273 274 275 276 277 278 279 280
 * function:  This function set specific bits to RF register
 * input:     net_device        dev
 *            RF90_RADIO_PATH_E eRFPath  //radio path of A/B/C/D
 *            u32               reg_addr //target addr to be modified
 *            u32               bitmask  //taget bit pos to be modified
 *            u32               data     //value to be written
 * output:    none
 * return:    none
 * notice:
 *****************************************************************************/
281
void rtl8192_phy_SetRFReg(struct net_device *dev, RF90_RADIO_PATH_E eRFPath,
282
			  u32 reg_addr, u32 bitmask, u32 data)
283 284
{
	struct r8192_priv *priv = ieee80211_priv(dev);
285
	u32 reg, bitshift;
286 287 288 289

	if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath))
		return;

290
	if (priv->Rf_Mode == RF_OP_By_FW) {
291 292
		if (bitmask != bMask12Bits) {
			/* RF data is 12 bits only */
293
			reg = phy_FwRFSerialRead(dev, eRFPath, reg_addr);
294
			bitshift =  ffs(bitmask) - 1;
295
			reg &= ~bitmask;
296
			reg |= data << bitshift;
297

298
			phy_FwRFSerialWrite(dev, eRFPath, reg_addr, reg);
299
		} else {
300
			phy_FwRFSerialWrite(dev, eRFPath, reg_addr, data);
301
		}
302 303 304

		udelay(200);

305
	} else {
306 307
		if (bitmask != bMask12Bits) {
			/* RF data is 12 bits only */
308
			reg = rtl8192_phy_RFSerialRead(dev, eRFPath, reg_addr);
309
			bitshift =  ffs(bitmask) - 1;
310
			reg &= ~bitmask;
311
			reg |= data << bitshift;
312

313
			rtl8192_phy_RFSerialWrite(dev, eRFPath, reg_addr, reg);
314
		} else {
315
			rtl8192_phy_RFSerialWrite(dev, eRFPath, reg_addr, data);
316
		}
317 318 319 320
	}
}

/******************************************************************************
321 322 323 324 325 326 327 328
 * function:  This function reads specific bits from RF register
 * input:     net_device        *dev
 *            u32               reg_addr //target addr to be readback
 *            u32               bitmask  //taget bit pos to be readback
 * output:    none
 * return:    u32               data     //the readback register value
 * notice:
 *****************************************************************************/
329
u32 rtl8192_phy_QueryRFReg(struct net_device *dev, RF90_RADIO_PATH_E eRFPath,
330
			   u32 reg_addr, u32 bitmask)
331
{
332
	u32 reg, bitshift;
333 334 335 336 337
	struct r8192_priv *priv = ieee80211_priv(dev);


	if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath))
		return 0;
338
	if (priv->Rf_Mode == RF_OP_By_FW) {
339
		reg = phy_FwRFSerialRead(dev, eRFPath, reg_addr);
340
		udelay(200);
341
	} else {
342
		reg = rtl8192_phy_RFSerialRead(dev, eRFPath, reg_addr);
343
	}
344
	bitshift =  ffs(bitmask) - 1;
345 346 347
	reg = (reg & bitmask) >> bitshift;
	return reg;

348
}
349

350
/******************************************************************************
351 352 353 354 355 356 357 358
 * function:  We support firmware to execute RF-R/W.
 * input:     net_device        *dev
 *            RF90_RADIO_PATH_E eRFPath
 *            u32               offset
 * output:    none
 * return:    u32
 * notice:
 ****************************************************************************/
359
static u32 phy_FwRFSerialRead(struct net_device *dev, RF90_RADIO_PATH_E eRFPath,
360
			      u32 offset)
361
{
362
	u32		reg = 0;
363
	u32		data = 0;
364
	u8		time = 0;
365
	u32		tmp;
366

367 368 369 370 371 372
	/* Firmware RF Write control.
	 * We can not execute the scheme in the initial step.
	 * Otherwise, RF-R/W will waste much time.
	 * This is only for site survey. */
	/* 1. Read operation need not insert data. bit 0-11 */
	/* 2. Write RF register address. bit 12-19 */
373
	data |= ((offset&0xFF)<<12);
374
	/* 3. Write RF path.  bit 20-21 */
375
	data |= ((eRFPath&0x3)<<20);
376 377
	/* 4. Set RF read indicator. bit 22=0 */
	/* 5. Trigger Fw to operate the command. bit 31 */
378
	data |= 0x80000000;
379
	/* 6. We can not execute read operation if bit 31 is 1. */
380
	read_nic_dword(dev, QPNR, &tmp);
381
	while (tmp & 0x80000000) {
382 383
		/* If FW can not finish RF-R/W for more than ?? times.
		   We must reset FW. */
384
		if (time++ < 100) {
385
			udelay(10);
386
			read_nic_dword(dev, QPNR, &tmp);
387
		} else {
388
			break;
389
		}
390
	}
391
	/* 7. Execute read operation. */
392
	write_nic_dword(dev, QPNR, data);
393
	/* 8. Check if firmware send back RF content. */
394
	read_nic_dword(dev, QPNR, &tmp);
395
	while (tmp & 0x80000000) {
396 397
		/* If FW can not finish RF-R/W for more than ?? times.
		   We must reset FW. */
398
		if (time++ < 100) {
399
			udelay(10);
400
			read_nic_dword(dev, QPNR, &tmp);
401
		} else {
402
			return 0;
403
		}
404
	}
405
	read_nic_dword(dev, RF_DATA, &reg);
406

407
	return reg;
408
}
409 410

/******************************************************************************
411 412 413 414 415 416 417 418 419
 * function:  We support firmware to execute RF-R/W.
 * input:     net_device        *dev
 *            RF90_RADIO_PATH_E eRFPath
 *            u32               offset
 *            u32               data
 * output:    none
 * return:    none
 * notice:
 ****************************************************************************/
420
static void phy_FwRFSerialWrite(struct net_device *dev,
421
				RF90_RADIO_PATH_E eRFPath, u32 offset, u32 data)
422 423
{
	u8	time = 0;
424
	u32	tmp;
425

426 427 428 429
	/* Firmware RF Write control.
	 * We can not execute the scheme in the initial step.
	 * Otherwise, RF-R/W will waste much time.
	 * This is only for site survey. */
430

431 432
	/* 1. Set driver write bit and 12 bit data. bit 0-11 */
	/* 2. Write RF register address. bit 12-19 */
433
	data |= ((offset&0xFF)<<12);
434
	/* 3. Write RF path.  bit 20-21 */
435
	data |= ((eRFPath&0x3)<<20);
436
	/* 4. Set RF write indicator. bit 22=1 */
437
	data |= 0x400000;
438
	/* 5. Trigger Fw to operate the command. bit 31=1 */
439
	data |= 0x80000000;
440

441
	/* 6. Write operation. We can not write if bit 31 is 1. */
442
	read_nic_dword(dev, QPNR, &tmp);
443
	while (tmp & 0x80000000) {
444 445
		/* If FW can not finish RF-R/W for more than ?? times.
		   We must reset FW. */
446
		if (time++ < 100) {
447
			udelay(10);
448
			read_nic_dword(dev, QPNR, &tmp);
449
		} else {
450
			break;
451
		}
452
	}
453 454
	/* 7. No matter check bit. We always force the write.
	   Because FW will not accept the command. */
455
	write_nic_dword(dev, QPNR, data);
456
	/* According to test, we must delay 20us to wait firmware
457
	   to finish RF write operation. */
458 459
	/* We support delay in firmware side now. */
}
460 461

/******************************************************************************
462 463
 * function:  This function reads BB parameters from header file we generate,
 *            and do register read/write
464
 * input:     net_device	*dev
465 466 467 468 469
 * output:    none
 * return:    none
 * notice:    BB parameters may change all the time, so please make
 *            sure it has been synced with the newest.
 *****************************************************************************/
470
void rtl8192_phy_configmac(struct net_device *dev)
471 472
{
	u32 dwArrayLen = 0, i;
473
	u32 *pdwArray = NULL;
474 475
	struct r8192_priv *priv = ieee80211_priv(dev);

476
	if (priv->btxpowerdata_readfromEEPORM) {
477 478 479 480
		RT_TRACE(COMP_PHY, "Rtl819XMACPHY_Array_PG\n");
		dwArrayLen = MACPHY_Array_PGLength;
		pdwArray = rtl819XMACPHY_Array_PG;

481
	} else {
482 483 484 485
		RT_TRACE(COMP_PHY, "Rtl819XMACPHY_Array\n");
		dwArrayLen = MACPHY_ArrayLength;
		pdwArray = rtl819XMACPHY_Array;
	}
486
	for (i = 0; i < dwArrayLen; i = i+3) {
487
		if (pdwArray[i] == 0x318)
488 489
			pdwArray[i+2] = 0x00000800;

490 491 492 493 494
		RT_TRACE(COMP_DBG,
			 "Rtl8190MACPHY_Array[0]=%x Rtl8190MACPHY_Array[1]=%x Rtl8190MACPHY_Array[2]=%x\n",
			 pdwArray[i], pdwArray[i+1], pdwArray[i+2]);
		rtl8192_setBBreg(dev, pdwArray[i], pdwArray[i+1],
				 pdwArray[i+2]);
495 496 497 498
	}
}

/******************************************************************************
499 500 501 502 503 504 505 506
 * function:  This function does dirty work
 * input:     net_device	*dev
 *            u8                ConfigType
 * output:    none
 * return:    none
 * notice:    BB parameters may change all the time, so please make
 *            sure it has been synced with the newest.
 *****************************************************************************/
507
void rtl8192_phyConfigBB(struct net_device *dev, u8 ConfigType)
508 509 510 511 512
{
	u32 i;

#ifdef TO_DO_LIST
	u32 *rtl8192PhyRegArrayTable = NULL, *rtl8192AgcTabArrayTable = NULL;
513

514
	if (Adapter->bInHctTest) {
515 516 517 518 519 520
		PHY_REGArrayLen = PHY_REGArrayLengthDTM;
		AGCTAB_ArrayLen = AGCTAB_ArrayLengthDTM;
		Rtl8190PHY_REGArray_Table = Rtl819XPHY_REGArrayDTM;
		Rtl8190AGCTAB_Array_Table = Rtl819XAGCTAB_ArrayDTM;
	}
#endif
521
	if (ConfigType == BaseBand_Config_PHY_REG) {
522
		for (i = 0; i < PHY_REG_1T2RArrayLength; i += 2) {
523 524 525 526 527 528 529
			rtl8192_setBBreg(dev, rtl819XPHY_REG_1T2RArray[i],
					 bMaskDWord,
					 rtl819XPHY_REG_1T2RArray[i+1]);
			RT_TRACE(COMP_DBG,
				 "i: %x, Rtl819xUsbPHY_REGArray[0]=%x Rtl819xUsbPHY_REGArray[1]=%x\n",
				 i, rtl819XPHY_REG_1T2RArray[i],
				 rtl819XPHY_REG_1T2RArray[i+1]);
530
		}
531
	} else if (ConfigType == BaseBand_Config_AGC_TAB) {
532
		for (i = 0; i < AGCTAB_ArrayLength; i += 2) {
533 534 535 536 537 538
			rtl8192_setBBreg(dev, rtl819XAGCTAB_Array[i],
					 bMaskDWord, rtl819XAGCTAB_Array[i+1]);
			RT_TRACE(COMP_DBG,
				 "i: %x, rtl819XAGCTAB_Array[0]=%x rtl819XAGCTAB_Array[1]=%x\n",
				 i, rtl819XAGCTAB_Array[i],
				 rtl819XAGCTAB_Array[i+1]);
539 540 541
		}
	}
}
542

543
/******************************************************************************
544 545 546 547 548 549 550 551
 * function:  This function initializes Register definition offset for
 *            Radio Path A/B/C/D
 * input:     net_device	*dev
 * output:    none
 * return:    none
 * notice:    Initialization value here is constant and it should never
 *            be changed
 *****************************************************************************/
552
static void rtl8192_InitBBRFRegDef(struct net_device *dev)
553 554
{
	struct r8192_priv *priv = ieee80211_priv(dev);
555

556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597
	/* RF Interface Software Control */
	/* 16 LSBs if read 32-bit from 0x870 */
	priv->PHYRegDef[RF90_PATH_A].rfintfs = rFPGA0_XAB_RFInterfaceSW;
	/* 16 MSBs if read 32-bit from 0x870 (16-bit for 0x872) */
	priv->PHYRegDef[RF90_PATH_B].rfintfs = rFPGA0_XAB_RFInterfaceSW;
	/* 16 LSBs if read 32-bit from 0x874 */
	priv->PHYRegDef[RF90_PATH_C].rfintfs = rFPGA0_XCD_RFInterfaceSW;
	/* 16 MSBs if read 32-bit from 0x874 (16-bit for 0x876) */
	priv->PHYRegDef[RF90_PATH_D].rfintfs = rFPGA0_XCD_RFInterfaceSW;

	/* RF Interface Readback Value */
	/* 16 LSBs if read 32-bit from 0x8E0 */
	priv->PHYRegDef[RF90_PATH_A].rfintfi = rFPGA0_XAB_RFInterfaceRB;
	/* 16 MSBs if read 32-bit from 0x8E0 (16-bit for 0x8E2) */
	priv->PHYRegDef[RF90_PATH_B].rfintfi = rFPGA0_XAB_RFInterfaceRB;
	/* 16 LSBs if read 32-bit from 0x8E4 */
	priv->PHYRegDef[RF90_PATH_C].rfintfi = rFPGA0_XCD_RFInterfaceRB;
	/* 16 MSBs if read 32-bit from 0x8E4 (16-bit for 0x8E6) */
	priv->PHYRegDef[RF90_PATH_D].rfintfi = rFPGA0_XCD_RFInterfaceRB;

	/* RF Interface Output (and Enable) */
	/* 16 LSBs if read 32-bit from 0x860 */
	priv->PHYRegDef[RF90_PATH_A].rfintfo = rFPGA0_XA_RFInterfaceOE;
	/* 16 LSBs if read 32-bit from 0x864 */
	priv->PHYRegDef[RF90_PATH_B].rfintfo = rFPGA0_XB_RFInterfaceOE;
	/* 16 LSBs if read 32-bit from 0x868 */
	priv->PHYRegDef[RF90_PATH_C].rfintfo = rFPGA0_XC_RFInterfaceOE;
	/* 16 LSBs if read 32-bit from 0x86C */
	priv->PHYRegDef[RF90_PATH_D].rfintfo = rFPGA0_XD_RFInterfaceOE;

	/* RF Interface (Output and) Enable */
	/* 16 MSBs if read 32-bit from 0x860 (16-bit for 0x862) */
	priv->PHYRegDef[RF90_PATH_A].rfintfe = rFPGA0_XA_RFInterfaceOE;
	/* 16 MSBs if read 32-bit from 0x864 (16-bit for 0x866) */
	priv->PHYRegDef[RF90_PATH_B].rfintfe = rFPGA0_XB_RFInterfaceOE;
	/* 16 MSBs if read 32-bit from 0x86A (16-bit for 0x86A) */
	priv->PHYRegDef[RF90_PATH_C].rfintfe = rFPGA0_XC_RFInterfaceOE;
	/* 16 MSBs if read 32-bit from 0x86C (16-bit for 0x86E) */
	priv->PHYRegDef[RF90_PATH_D].rfintfe = rFPGA0_XD_RFInterfaceOE;

	/* Addr of LSSI. Write RF register by driver */
	priv->PHYRegDef[RF90_PATH_A].rf3wireOffset = rFPGA0_XA_LSSIParameter;
598 599 600 601
	priv->PHYRegDef[RF90_PATH_B].rf3wireOffset = rFPGA0_XB_LSSIParameter;
	priv->PHYRegDef[RF90_PATH_C].rf3wireOffset = rFPGA0_XC_LSSIParameter;
	priv->PHYRegDef[RF90_PATH_D].rf3wireOffset = rFPGA0_XD_LSSIParameter;

602 603 604
	/* RF parameter */
	/* BB Band Select */
	priv->PHYRegDef[RF90_PATH_A].rfLSSI_Select = rFPGA0_XAB_RFParameter;
605 606 607 608
	priv->PHYRegDef[RF90_PATH_B].rfLSSI_Select = rFPGA0_XAB_RFParameter;
	priv->PHYRegDef[RF90_PATH_C].rfLSSI_Select = rFPGA0_XCD_RFParameter;
	priv->PHYRegDef[RF90_PATH_D].rfLSSI_Select = rFPGA0_XCD_RFParameter;

609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631
	/* Tx AGC Gain Stage (same for all path. Should we remove this?) */
	priv->PHYRegDef[RF90_PATH_A].rfTxGainStage = rFPGA0_TxGainStage;
	priv->PHYRegDef[RF90_PATH_B].rfTxGainStage = rFPGA0_TxGainStage;
	priv->PHYRegDef[RF90_PATH_C].rfTxGainStage = rFPGA0_TxGainStage;
	priv->PHYRegDef[RF90_PATH_D].rfTxGainStage = rFPGA0_TxGainStage;

	/* Tranceiver A~D HSSI Parameter-1 */
	/* wire control parameter1 */
	priv->PHYRegDef[RF90_PATH_A].rfHSSIPara1 = rFPGA0_XA_HSSIParameter1;
	priv->PHYRegDef[RF90_PATH_B].rfHSSIPara1 = rFPGA0_XB_HSSIParameter1;
	priv->PHYRegDef[RF90_PATH_C].rfHSSIPara1 = rFPGA0_XC_HSSIParameter1;
	priv->PHYRegDef[RF90_PATH_D].rfHSSIPara1 = rFPGA0_XD_HSSIParameter1;

	/* Tranceiver A~D HSSI Parameter-2 */
	/* wire control parameter2 */
	priv->PHYRegDef[RF90_PATH_A].rfHSSIPara2 = rFPGA0_XA_HSSIParameter2;
	priv->PHYRegDef[RF90_PATH_B].rfHSSIPara2 = rFPGA0_XB_HSSIParameter2;
	priv->PHYRegDef[RF90_PATH_C].rfHSSIPara2 = rFPGA0_XC_HSSIParameter2;
	priv->PHYRegDef[RF90_PATH_D].rfHSSIPara2 = rFPGA0_XD_HSSIParameter2;

	/* RF Switch Control */
	/* TR/Ant switch control */
	priv->PHYRegDef[RF90_PATH_A].rfSwitchControl = rFPGA0_XAB_SwitchControl;
632 633 634 635
	priv->PHYRegDef[RF90_PATH_B].rfSwitchControl = rFPGA0_XAB_SwitchControl;
	priv->PHYRegDef[RF90_PATH_C].rfSwitchControl = rFPGA0_XCD_SwitchControl;
	priv->PHYRegDef[RF90_PATH_D].rfSwitchControl = rFPGA0_XCD_SwitchControl;

636
	/* AGC control 1 */
637 638 639 640 641
	priv->PHYRegDef[RF90_PATH_A].rfAGCControl1 = rOFDM0_XAAGCCore1;
	priv->PHYRegDef[RF90_PATH_B].rfAGCControl1 = rOFDM0_XBAGCCore1;
	priv->PHYRegDef[RF90_PATH_C].rfAGCControl1 = rOFDM0_XCAGCCore1;
	priv->PHYRegDef[RF90_PATH_D].rfAGCControl1 = rOFDM0_XDAGCCore1;

642
	/* AGC control 2 */
643 644 645 646 647
	priv->PHYRegDef[RF90_PATH_A].rfAGCControl2 = rOFDM0_XAAGCCore2;
	priv->PHYRegDef[RF90_PATH_B].rfAGCControl2 = rOFDM0_XBAGCCore2;
	priv->PHYRegDef[RF90_PATH_C].rfAGCControl2 = rOFDM0_XCAGCCore2;
	priv->PHYRegDef[RF90_PATH_D].rfAGCControl2 = rOFDM0_XDAGCCore2;

648
	/* RX AFE control 1 */
649 650 651 652 653
	priv->PHYRegDef[RF90_PATH_A].rfRxIQImbalance = rOFDM0_XARxIQImbalance;
	priv->PHYRegDef[RF90_PATH_B].rfRxIQImbalance = rOFDM0_XBRxIQImbalance;
	priv->PHYRegDef[RF90_PATH_C].rfRxIQImbalance = rOFDM0_XCRxIQImbalance;
	priv->PHYRegDef[RF90_PATH_D].rfRxIQImbalance = rOFDM0_XDRxIQImbalance;

654
	/* RX AFE control 1 */
655 656 657 658 659
	priv->PHYRegDef[RF90_PATH_A].rfRxAFE = rOFDM0_XARxAFE;
	priv->PHYRegDef[RF90_PATH_B].rfRxAFE = rOFDM0_XBRxAFE;
	priv->PHYRegDef[RF90_PATH_C].rfRxAFE = rOFDM0_XCRxAFE;
	priv->PHYRegDef[RF90_PATH_D].rfRxAFE = rOFDM0_XDRxAFE;

660
	/* Tx AFE control 1 */
661 662 663 664 665
	priv->PHYRegDef[RF90_PATH_A].rfTxIQImbalance = rOFDM0_XATxIQImbalance;
	priv->PHYRegDef[RF90_PATH_B].rfTxIQImbalance = rOFDM0_XBTxIQImbalance;
	priv->PHYRegDef[RF90_PATH_C].rfTxIQImbalance = rOFDM0_XCTxIQImbalance;
	priv->PHYRegDef[RF90_PATH_D].rfTxIQImbalance = rOFDM0_XDTxIQImbalance;

666
	/* Tx AFE control 2 */
667 668 669 670 671
	priv->PHYRegDef[RF90_PATH_A].rfTxAFE = rOFDM0_XATxAFE;
	priv->PHYRegDef[RF90_PATH_B].rfTxAFE = rOFDM0_XBTxAFE;
	priv->PHYRegDef[RF90_PATH_C].rfTxAFE = rOFDM0_XCTxAFE;
	priv->PHYRegDef[RF90_PATH_D].rfTxAFE = rOFDM0_XDTxAFE;

672
	/* Tranceiver LSSI Readback */
673 674 675 676 677
	priv->PHYRegDef[RF90_PATH_A].rfLSSIReadBack = rFPGA0_XA_LSSIReadBack;
	priv->PHYRegDef[RF90_PATH_B].rfLSSIReadBack = rFPGA0_XB_LSSIReadBack;
	priv->PHYRegDef[RF90_PATH_C].rfLSSIReadBack = rFPGA0_XC_LSSIReadBack;
	priv->PHYRegDef[RF90_PATH_D].rfLSSIReadBack = rFPGA0_XD_LSSIReadBack;
}
678

679
/******************************************************************************
680 681 682 683 684 685 686 687 688 689
 * function:  This function is to write register and then readback to make
 *            sure whether BB and RF is OK
 * input:     net_device        *dev
 *            HW90_BLOCK_E      CheckBlock
 *            RF90_RADIO_PATH_E eRFPath  //only used when checkblock is
 *                                       //HW90_BLOCK_RF
 * output:    none
 * return:    return whether BB and RF is ok (0:OK, 1:Fail)
 * notice:    This function may be removed in the ASIC
 ******************************************************************************/
690 691
u8 rtl8192_phy_checkBBAndRF(struct net_device *dev, HW90_BLOCK_E CheckBlock,
			    RF90_RADIO_PATH_E eRFPath)
692 693
{
	u8 ret = 0;
694
	u32 i, CheckTimes = 4, reg = 0;
695 696
	u32 WriteAddr[4];
	u32 WriteData[] = {0xfffff027, 0xaa55a02f, 0x00000027, 0x55aa502f};
697

698
	/* Initialize register address offset to be checked */
699 700 701 702
	WriteAddr[HW90_BLOCK_MAC] = 0x100;
	WriteAddr[HW90_BLOCK_PHY0] = 0x900;
	WriteAddr[HW90_BLOCK_PHY1] = 0x800;
	WriteAddr[HW90_BLOCK_RF] = 0x3;
703
	RT_TRACE(COMP_PHY, "%s(), CheckBlock: %d\n", __func__, CheckBlock);
704
	for (i = 0; i < CheckTimes; i++) {
705

706
		/* Write data to register and readback */
707
		switch (CheckBlock) {
708
		case HW90_BLOCK_MAC:
709
			RT_TRACE(COMP_ERR,
710
				 "PHY_CheckBBRFOK(): Never Write 0x100 here!\n");
711 712 713 714
			break;

		case HW90_BLOCK_PHY0:
		case HW90_BLOCK_PHY1:
715 716
			write_nic_dword(dev, WriteAddr[CheckBlock],
					WriteData[i]);
717
			read_nic_dword(dev, WriteAddr[CheckBlock], &reg);
718 719 720 721
			break;

		case HW90_BLOCK_RF:
			WriteData[i] &= 0xfff;
722 723 724
			rtl8192_phy_SetRFReg(dev, eRFPath,
					     WriteAddr[HW90_BLOCK_RF],
					     bMask12Bits, WriteData[i]);
725 726
			/* TODO: we should not delay for such a long time.
			   Ask SD3 */
727
			usleep_range(1000, 1000);
728 729 730
			reg = rtl8192_phy_QueryRFReg(dev, eRFPath,
						     WriteAddr[HW90_BLOCK_RF],
						     bMask12Bits);
731
			usleep_range(1000, 1000);
732 733 734 735 736 737 738 739
			break;

		default:
			ret = 1;
			break;
		}


740
		/* Check whether readback data is correct */
741
		if (reg != WriteData[i]) {
742
			RT_TRACE((COMP_PHY|COMP_ERR),
743 744
				 "error reg: %x, WriteData: %x\n",
				 reg, WriteData[i]);
745 746 747 748 749 750 751 752 753
			ret = 1;
			break;
		}
	}

	return ret;
}

/******************************************************************************
754 755 756 757 758 759 760
 * function:  This function initializes BB&RF
 * input:     net_device	*dev
 * output:    none
 * return:    none
 * notice:    Initialization value may change all the time, so please make
 *            sure it has been synced with the newest.
 ******************************************************************************/
761
static void rtl8192_BB_Config_ParaFile(struct net_device *dev)
762 763
{
	struct r8192_priv *priv = ieee80211_priv(dev);
764
	u8 reg_u8 = 0, eCheckItem = 0, status = 0;
765
	u32 reg_u32 = 0;
766

767
	/**************************************
768 769
	 * <1> Initialize BaseBand
	 *************************************/
770

771
	/* --set BB Global Reset-- */
772
	read_nic_byte(dev, BB_GLOBAL_RESET, &reg_u8);
773
	write_nic_byte(dev, BB_GLOBAL_RESET, (reg_u8|BB_GLOBAL_RESET_BIT));
774
	mdelay(50);
775
	/* ---set BB reset Active--- */
776 777
	read_nic_dword(dev, CPU_GEN, &reg_u32);
	write_nic_dword(dev, CPU_GEN, (reg_u32&(~CPU_GEN_BB_RST)));
778

779 780
	/* ----Ckeck FPGAPHY0 and PHY1 board is OK---- */
	/* TODO: this function should be removed on ASIC */
781 782 783
	for (eCheckItem = (HW90_BLOCK_E)HW90_BLOCK_PHY0;
	     eCheckItem <= HW90_BLOCK_PHY1; eCheckItem++) {
		/* don't care RF path */
784 785 786
		status = rtl8192_phy_checkBBAndRF(dev, (HW90_BLOCK_E)eCheckItem,
						  (RF90_RADIO_PATH_E)0);
		if (status != 0) {
787 788 789
			RT_TRACE((COMP_ERR | COMP_PHY),
				 "PHY_RF8256_Config(): Check PHY%d Fail!!\n",
				 eCheckItem-1);
790
			return;
791 792
		}
	}
793
	/* ---- Set CCK and OFDM Block "OFF"---- */
794
	rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn|bOFDMEn, 0x0);
795 796
	/* ----BB Register Initilazation---- */
	/* ==m==>Set PHY REG From Header<==m== */
797 798
	rtl8192_phyConfigBB(dev, BaseBand_Config_PHY_REG);

799
	/* ----Set BB reset de-Active---- */
800 801
	read_nic_dword(dev, CPU_GEN, &reg_u32);
	write_nic_dword(dev, CPU_GEN, (reg_u32|CPU_GEN_BB_RST));
802

803 804
	/* ----BB AGC table Initialization---- */
	/* ==m==>Set PHY REG From Header<==m== */
805 806
	rtl8192_phyConfigBB(dev, BaseBand_Config_AGC_TAB);

807
	/* ----Enable XSTAL ---- */
808
	write_nic_byte_E(dev, 0x5e, 0x00);
809
	if (priv->card_8192_version == (u8)VERSION_819xU_A) {
810
		/* Antenna gain offset from B/C/D to A */
811 812
		reg_u32 = priv->AntennaTxPwDiff[1]<<4 |
			   priv->AntennaTxPwDiff[0];
813 814
		rtl8192_setBBreg(dev, rFPGA0_TxGainStage, (bXBTxAGC|bXCTxAGC),
				 reg_u32);
815

816
		/* XSTALLCap */
817
		reg_u32 = priv->CrystalCap & 0xf;
818 819
		rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, bXtalCap,
				 reg_u32);
820 821
	}

822 823
	/* Check if the CCK HighPower is turned ON.
	   This is used to calculate PWDB. */
824 825 826
	priv->bCckHighPower = (u8)rtl8192_QueryBBReg(dev,
						     rFPGA0_XA_HSSIParameter2,
						     0x200);
827
}
828

829
/******************************************************************************
830 831 832 833 834 835 836
 * function:  This function initializes BB&RF
 * input:     net_device	*dev
 * output:    none
 * return:    none
 * notice:    Initialization value may change all the time, so please make
 *            sure it has been synced with the newest.
 *****************************************************************************/
837
void rtl8192_BBConfig(struct net_device *dev)
838 839
{
	rtl8192_InitBBRFRegDef(dev);
840 841 842
	/* config BB&RF. As hardCode based initialization has not been well
	 * implemented, so use file first.
	 * FIXME: should implement it for hardcode? */
843 844 845
	rtl8192_BB_Config_ParaFile(dev);
}

846

847
/******************************************************************************
848 849 850 851 852 853
 * function:  This function obtains the initialization value of Tx power Level
 *            offset
 * input:     net_device	*dev
 * output:    none
 * return:    none
 *****************************************************************************/
854
void rtl8192_phy_getTxPower(struct net_device *dev)
855 856
{
	struct r8192_priv *priv = ieee80211_priv(dev);
857
	u8 tmp;
858

859 860 861 862 863 864 865 866 867 868 869 870
	read_nic_dword(dev, rTxAGC_Rate18_06,
		       &priv->MCSTxPowerLevelOriginalOffset[0]);
	read_nic_dword(dev, rTxAGC_Rate54_24,
		       &priv->MCSTxPowerLevelOriginalOffset[1]);
	read_nic_dword(dev, rTxAGC_Mcs03_Mcs00,
		       &priv->MCSTxPowerLevelOriginalOffset[2]);
	read_nic_dword(dev, rTxAGC_Mcs07_Mcs04,
		       &priv->MCSTxPowerLevelOriginalOffset[3]);
	read_nic_dword(dev, rTxAGC_Mcs11_Mcs08,
		       &priv->MCSTxPowerLevelOriginalOffset[4]);
	read_nic_dword(dev, rTxAGC_Mcs15_Mcs12,
		       &priv->MCSTxPowerLevelOriginalOffset[5]);
871

872
	/* Read rx initial gain */
873 874 875 876
	read_nic_byte(dev, rOFDM0_XAAGCCore1, &priv->DefaultInitialGain[0]);
	read_nic_byte(dev, rOFDM0_XBAGCCore1, &priv->DefaultInitialGain[1]);
	read_nic_byte(dev, rOFDM0_XCAGCCore1, &priv->DefaultInitialGain[2]);
	read_nic_byte(dev, rOFDM0_XDAGCCore1, &priv->DefaultInitialGain[3]);
877 878 879 880
	RT_TRACE(COMP_INIT,
		 "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x)\n",
		 priv->DefaultInitialGain[0], priv->DefaultInitialGain[1],
		 priv->DefaultInitialGain[2], priv->DefaultInitialGain[3]);
881

882
	/* Read framesync */
883 884 885
	read_nic_byte(dev, rOFDM0_RxDetector3, &priv->framesync);
	read_nic_byte(dev, rOFDM0_RxDetector2, &tmp);
	priv->framesyncC34 = tmp;
886
	RT_TRACE(COMP_INIT, "Default framesync (0x%x) = 0x%x\n",
887 888
		rOFDM0_RxDetector3, priv->framesync);

889
	/* Read SIFS (save the value read fome MACPHY_REG.txt) */
890
	read_nic_word(dev, SIFS, &priv->SifsTime);
891 892 893
}

/******************************************************************************
894 895 896 897 898 899 900
 * function:  This function sets the initialization value of Tx power Level
 *            offset
 * input:     net_device        *dev
 *            u8                channel
 * output:    none
 * return:    none
 ******************************************************************************/
901
void rtl8192_phy_setTxPower(struct net_device *dev, u8 channel)
902 903 904 905 906
{
	struct r8192_priv *priv = ieee80211_priv(dev);
	u8	powerlevel = priv->TxPowerLevelCCK[channel-1];
	u8	powerlevelOFDM24G = priv->TxPowerLevelOFDM24G[channel-1];

907
	switch (priv->rf_chip) {
908
	case RF_8256:
909 910
		/* need further implement */
		PHY_SetRF8256CCKTxPower(dev, powerlevel);
911 912 913
		PHY_SetRF8256OFDMTxPower(dev, powerlevelOFDM24G);
		break;
	default:
914 915
		RT_TRACE((COMP_PHY|COMP_ERR),
			 "error RF chipID(8225 or 8258) in function %s()\n",
916
			 __func__);
917 918 919 920 921
		break;
	}
}

/******************************************************************************
922 923 924 925 926
 * function:  This function checks Rf chip to do RF config
 * input:     net_device	*dev
 * output:    none
 * return:    only 8256 is supported
 ******************************************************************************/
927
void rtl8192_phy_RFConfig(struct net_device *dev)
928 929 930
{
	struct r8192_priv *priv = ieee80211_priv(dev);

931
	switch (priv->rf_chip) {
932 933 934 935 936 937
	case RF_8256:
		PHY_RF8256_Config(dev);
		break;
	default:
		RT_TRACE(COMP_ERR, "error chip id\n");
		break;
938 939 940 941
	}
}

/******************************************************************************
942 943 944 945 946
 * function:  This function updates Initial gain
 * input:     net_device	*dev
 * output:    none
 * return:    As Windows has not implemented this, wait for complement
 ******************************************************************************/
947
void rtl8192_phy_updateInitGain(struct net_device *dev)
948 949 950 951
{
}

/******************************************************************************
952 953 954 955 956 957 958 959
 * function:  This function read RF parameters from general head file,
 *            and do RF 3-wire
 * input:     net_device	*dev
 *            RF90_RADIO_PATH_E eRFPath
 * output:    none
 * return:    return code show if RF configuration is successful(0:pass, 1:fail)
 * notice:    Delay may be required for RF configuration
 *****************************************************************************/
960 961
u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device *dev,
				      RF90_RADIO_PATH_E	eRFPath)
962 963 964 965
{

	int i;

966
	switch (eRFPath) {
967
	case RF90_PATH_A:
968
		for (i = 0; i < RadioA_ArrayLength; i = i+2) {
969

970
			if (rtl819XRadioA_Array[i] == 0xfe) {
971 972
				mdelay(100);
				continue;
973
			}
974 975 976 977
			rtl8192_phy_SetRFReg(dev, eRFPath,
					     rtl819XRadioA_Array[i],
					     bMask12Bits,
					     rtl819XRadioA_Array[i+1]);
978
			mdelay(1);
979

980 981 982
		}
		break;
	case RF90_PATH_B:
983
		for (i = 0; i < RadioB_ArrayLength; i = i+2) {
984

985
			if (rtl819XRadioB_Array[i] == 0xfe) {
986 987
				mdelay(100);
				continue;
988
			}
989 990 991 992
			rtl8192_phy_SetRFReg(dev, eRFPath,
					     rtl819XRadioB_Array[i],
					     bMask12Bits,
					     rtl819XRadioB_Array[i+1]);
993
			mdelay(1);
994

995 996 997
		}
		break;
	case RF90_PATH_C:
998
		for (i = 0; i < RadioC_ArrayLength; i = i+2) {
999

1000
			if (rtl819XRadioC_Array[i] == 0xfe) {
1001 1002
				mdelay(100);
				continue;
1003
			}
1004 1005 1006 1007
			rtl8192_phy_SetRFReg(dev, eRFPath,
					     rtl819XRadioC_Array[i],
					     bMask12Bits,
					     rtl819XRadioC_Array[i+1]);
1008
			mdelay(1);
1009

1010 1011 1012
		}
		break;
	case RF90_PATH_D:
1013
		for (i = 0; i < RadioD_ArrayLength; i = i+2) {
1014

1015
			if (rtl819XRadioD_Array[i] == 0xfe) {
1016 1017
				mdelay(100);
				continue;
1018
			}
1019 1020 1021 1022
			rtl8192_phy_SetRFReg(dev, eRFPath,
					     rtl819XRadioD_Array[i],
					     bMask12Bits,
					     rtl819XRadioD_Array[i+1]);
1023 1024 1025 1026 1027 1028
			mdelay(1);

		}
		break;
	default:
		break;
1029 1030
	}

1031
	return 0;
1032 1033

}
1034

1035
/******************************************************************************
1036 1037 1038 1039 1040 1041 1042
 * function:  This function sets Tx Power of the channel
 * input:     net_device        *dev
 *            u8                channel
 * output:    none
 * return:    none
 * notice:
 ******************************************************************************/
1043
static void rtl8192_SetTxPowerLevel(struct net_device *dev, u8 channel)
1044 1045 1046 1047 1048
{
	struct r8192_priv *priv = ieee80211_priv(dev);
	u8	powerlevel = priv->TxPowerLevelCCK[channel-1];
	u8	powerlevelOFDM24G = priv->TxPowerLevelOFDM24G[channel-1];

1049
	switch (priv->rf_chip) {
1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064
	case RF_8225:
#ifdef TO_DO_LIST
		PHY_SetRF8225CckTxPower(Adapter, powerlevel);
		PHY_SetRF8225OfdmTxPower(Adapter, powerlevelOFDM24G);
#endif
		break;

	case RF_8256:
		PHY_SetRF8256CCKTxPower(dev, powerlevel);
		PHY_SetRF8256OFDMTxPower(dev, powerlevelOFDM24G);
		break;

	case RF_8258:
		break;
	default:
1065
		RT_TRACE(COMP_ERR, "unknown rf chip ID in %s()\n", __func__);
1066 1067 1068 1069 1070
		break;
	}
}

/******************************************************************************
1071 1072 1073 1074 1075 1076 1077
 * function:  This function sets RF state on or off
 * input:     net_device         *dev
 *            RT_RF_POWER_STATE  eRFPowerState  //Power State to set
 * output:    none
 * return:    none
 * notice:
 *****************************************************************************/
1078 1079
bool rtl8192_SetRFPowerState(struct net_device *dev,
			     RT_RF_POWER_STATE eRFPowerState)
1080 1081 1082 1083
{
	bool				bResult = true;
	struct r8192_priv *priv = ieee80211_priv(dev);

1084
	if (eRFPowerState == priv->ieee80211->eRFPowerState)
1085 1086
		return false;

1087
	if (priv->SetRFPowerStateInProgress)
1088 1089 1090 1091
		return false;

	priv->SetRFPowerStateInProgress = true;

1092
	switch (priv->rf_chip) {
1093
	case RF_8256:
1094
		switch (eRFPowerState) {
1095 1096 1097
		case eRfOn:
			/* RF-A, RF-B */
			/* enable RF-Chip A/B - 0x860[4] */
A
Anish Bhatt 已提交
1098
			rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT(4),
1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112
					 0x1);
			/* analog to digital on - 0x88c[9:8] */
			rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300,
					 0x3);
			/* digital to analog on - 0x880[4:3] */
			rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x18,
					 0x3);
			/* rx antenna on - 0xc04[1:0] */
			rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x3, 0x3);
			/* rx antenna on - 0xd04[1:0] */
			rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x3, 0x3);
			/* analog to digital part2 on - 0x880[6:5] */
			rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60,
					 0x3);
1113

1114
			break;
1115

1116
		case eRfSleep:
1117

1118
			break;
1119

1120 1121 1122
		case eRfOff:
			/* RF-A, RF-B */
			/* disable RF-Chip A/B - 0x860[4] */
A
Anish Bhatt 已提交
1123
			rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT(4),
1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137
					 0x0);
			/* analog to digital off, for power save */
			rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00,
					 0x0); /* 0x88c[11:8] */
			/* digital to analog off, for power save - 0x880[4:3] */
			rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x18,
					 0x0);
			/* rx antenna off - 0xc04[3:0] */
			rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0xf, 0x0);
			/* rx antenna off - 0xd04[3:0] */
			rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0xf, 0x0);
			/* analog to digital part2 off, for power save */
			rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60,
					 0x0); /* 0x880[6:5] */
1138 1139

			break;
1140

1141
		default:
1142 1143 1144
			bResult = false;
			RT_TRACE(COMP_ERR, "%s(): unknown state to set: 0x%X\n",
				 __func__, eRFPowerState);
1145
			break;
1146 1147 1148 1149 1150
		}
		break;
	default:
		RT_TRACE(COMP_ERR, "Not support rf_chip(%x)\n", priv->rf_chip);
		break;
1151 1152
	}
#ifdef TO_DO_LIST
1153
	if (bResult) {
1154
		/* Update current RF state variable. */
1155
		pHalData->eRFPowerState = eRFPowerState;
1156
		switch (pHalData->RFChipID) {
1157 1158 1159 1160 1161 1162 1163 1164 1165 1166
		case RF_8256:
			switch (pHalData->eRFPowerState) {
			case eRfOff:
				/* If Rf off reason is from IPS,
				   LED should blink with no link */
				if (pMgntInfo->RfOffReason == RF_CHANGE_BY_IPS)
					Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_NO_LINK);
				else
					/* Turn off LED if RF is not ON. */
					Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_POWER_OFF);
1167 1168
				break;

1169 1170 1171 1172
			case eRfOn:
				/* Turn on RF we are still linked, which might
				   happen when we quickly turn off and on HW RF.
				 */
1173
				if (pMgntInfo->bMediaConnect)
1174 1175 1176 1177 1178 1179 1180 1181
					Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_LINK);
				else
					/* Turn off LED if RF is not ON. */
					Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_NO_LINK);
				break;

			default:
				break;
1182
			}
1183 1184 1185 1186 1187 1188 1189
			break;

		default:
			RT_TRACE(COMP_RF, DBG_LOUD, "%s(): Unknown RF type\n",
				 __func__);
			break;
		}
1190 1191 1192 1193 1194 1195 1196 1197

	}
#endif
	priv->SetRFPowerStateInProgress = false;

	return bResult;
}

1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210
/******************************************************************************
 * function:  This function sets command table variable (struct SwChnlCmd).
 * input:     SwChnlCmd      *CmdTable    //table to be set
 *            u32            CmdTableIdx  //variable index in table to be set
 *            u32            CmdTableSz   //table size
 *            SwChnlCmdID    CmdID        //command ID to set
 *            u32            Para1
 *            u32            Para2
 *            u32            msDelay
 * output:
 * return:    true if finished, false otherwise
 * notice:
 ******************************************************************************/
1211 1212 1213
static u8 rtl8192_phy_SetSwChnlCmdArray(SwChnlCmd *CmdTable, u32 CmdTableIdx,
					u32 CmdTableSz, SwChnlCmdID CmdID,
					u32 Para1, u32 Para2, u32 msDelay)
1214
{
1215
	SwChnlCmd *pCmd;
1216

1217
	if (CmdTable == NULL) {
1218
		RT_TRACE(COMP_ERR, "%s(): CmdTable cannot be NULL\n", __func__);
1219 1220
		return false;
	}
1221
	if (CmdTableIdx >= CmdTableSz) {
1222 1223
		RT_TRACE(COMP_ERR, "%s(): Access invalid index, please check size of the table, CmdTableIdx:%d, CmdTableSz:%d\n",
			 __func__, CmdTableIdx, CmdTableSz);
1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234
		return false;
	}

	pCmd = CmdTable + CmdTableIdx;
	pCmd->CmdID = CmdID;
	pCmd->Para1 = Para1;
	pCmd->Para2 = Para2;
	pCmd->msDelay = msDelay;

	return true;
}
1235

1236
/******************************************************************************
1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247
 * function:  This function sets channel step by step
 * input:     net_device        *dev
 *            u8                channel
 *            u8                *stage   //3 stages
 *            u8                *step
 *            u32               *delay   //whether need to delay
 * output:    store new stage, step and delay for next step
 *            (combine with function above)
 * return:    true if finished, false otherwise
 * notice:    Wait for simpler function to replace it
 *****************************************************************************/
1248 1249
static u8 rtl8192_phy_SwChnlStepByStep(struct net_device *dev, u8 channel,
				       u8 *stage, u8 *step, u32 *delay)
1250 1251
{
	struct r8192_priv *priv = ieee80211_priv(dev);
1252 1253 1254 1255 1256 1257 1258
	SwChnlCmd	PreCommonCmd[MAX_PRECMD_CNT];
	u32		PreCommonCmdCnt;
	SwChnlCmd	PostCommonCmd[MAX_POSTCMD_CNT];
	u32		PostCommonCmdCnt;
	SwChnlCmd	RfDependCmd[MAX_RFDEPENDCMD_CNT];
	u32		RfDependCmdCnt;
	SwChnlCmd	*CurrentCmd = NULL;
1259 1260
	u8		eRFPath;

1261
	RT_TRACE(COMP_CH, "%s() stage: %d, step: %d, channel: %d\n",
1262
		 __func__, *stage, *step, channel);
1263
	if (!IsLegalChannel(priv->ieee80211, channel)) {
1264
		RT_TRACE(COMP_ERR, "set to illegal channel: %d\n", channel);
1265 1266 1267
		/* return true to tell upper caller function this channel
		   setting is finished! Or it will in while loop. */
		return true;
1268
	}
1269
	/* FIXME: need to check whether channel is legal or not here */
1270 1271


1272 1273 1274 1275 1276 1277 1278
	/* <1> Fill up pre common command. */
	PreCommonCmdCnt = 0;
	rtl8192_phy_SetSwChnlCmdArray(PreCommonCmd, PreCommonCmdCnt++,
				      MAX_PRECMD_CNT, CmdID_SetTxPowerLevel,
				      0, 0, 0);
	rtl8192_phy_SetSwChnlCmdArray(PreCommonCmd, PreCommonCmdCnt++,
				      MAX_PRECMD_CNT, CmdID_End, 0, 0, 0);
1279

1280 1281
	/* <2> Fill up post common command. */
	PostCommonCmdCnt = 0;
1282

1283 1284
	rtl8192_phy_SetSwChnlCmdArray(PostCommonCmd, PostCommonCmdCnt++,
				      MAX_POSTCMD_CNT, CmdID_End, 0, 0, 0);
1285

1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305
	/* <3> Fill up RF dependent command. */
	RfDependCmdCnt = 0;
	switch (priv->rf_chip) {
	case RF_8225:
		if (!(channel >= 1 && channel <= 14)) {
			RT_TRACE(COMP_ERR,
				 "illegal channel for Zebra 8225: %d\n",
				 channel);
			return true;
		}
		rtl8192_phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++,
					      MAX_RFDEPENDCMD_CNT,
					      CmdID_RF_WriteReg,
					      rZebra1_Channel,
					      RF_CHANNEL_TABLE_ZEBRA[channel],
					      10);
		rtl8192_phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++,
					      MAX_RFDEPENDCMD_CNT,
					      CmdID_End, 0, 0, 0);
		break;
1306

1307 1308 1309 1310 1311 1312
	case RF_8256:
		/* TEST!! This is not the table for 8256!! */
		if (!(channel >= 1 && channel <= 14)) {
			RT_TRACE(COMP_ERR,
				 "illegal channel for Zebra 8256: %d\n",
				 channel);
1313 1314
			return true;
		}
1315 1316 1317 1318 1319 1320 1321 1322
		rtl8192_phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++,
					      MAX_RFDEPENDCMD_CNT,
					      CmdID_RF_WriteReg,
					      rZebra1_Channel, channel, 10);
		rtl8192_phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++,
					      MAX_RFDEPENDCMD_CNT,
					      CmdID_End, 0, 0, 0);
		break;
1323

1324 1325
	case RF_8258:
		break;
1326

1327 1328 1329 1330
	default:
		RT_TRACE(COMP_ERR, "Unknown RFChipID: %d\n", priv->rf_chip);
		return true;
	}
1331 1332


1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349
	do {
		switch (*stage) {
		case 0:
			CurrentCmd = &PreCommonCmd[*step];
			break;
		case 1:
			CurrentCmd = &RfDependCmd[*step];
			break;
		case 2:
			CurrentCmd = &PostCommonCmd[*step];
			break;
		}

		if (CurrentCmd->CmdID == CmdID_End) {
			if ((*stage) == 2) {
				(*delay) = CurrentCmd->msDelay;
				return true;
1350
			}
1351 1352 1353
			(*stage)++;
			(*step) = 0;
			continue;
1354
		}
1355

1356 1357 1358 1359 1360
		switch (CurrentCmd->CmdID) {
		case CmdID_SetTxPowerLevel:
			if (priv->card_8192_version == (u8)VERSION_819xU_A)
				/* consider it later! */
				rtl8192_SetTxPowerLevel(dev, channel);
1361
			break;
1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388
		case CmdID_WritePortUlong:
			write_nic_dword(dev, CurrentCmd->Para1,
					CurrentCmd->Para2);
			break;
		case CmdID_WritePortUshort:
			write_nic_word(dev, CurrentCmd->Para1,
				       (u16)CurrentCmd->Para2);
			break;
		case CmdID_WritePortUchar:
			write_nic_byte(dev, CurrentCmd->Para1,
				       (u8)CurrentCmd->Para2);
			break;
		case CmdID_RF_WriteReg:
			for (eRFPath = 0; eRFPath < RF90_PATH_MAX; eRFPath++) {
				rtl8192_phy_SetRFReg(dev,
						     (RF90_RADIO_PATH_E)eRFPath,
						     CurrentCmd->Para1,
						     bZebra1_ChannelNum,
						     CurrentCmd->Para2);
			}
			break;
		default:
			break;
		}

		break;
	} while (true);
1389

1390
	(*delay) = CurrentCmd->msDelay;
1391 1392 1393 1394 1395
	(*step)++;
	return false;
}

/******************************************************************************
1396 1397 1398 1399 1400 1401 1402
 * function:  This function does actually set channel work
 * input:     net_device        *dev
 *            u8                channel
 * output:    none
 * return:    none
 * notice:    We should not call this function directly
 *****************************************************************************/
1403
static void rtl8192_phy_FinishSwChnlNow(struct net_device *dev, u8 channel)
1404 1405 1406 1407
{
	struct r8192_priv *priv = ieee80211_priv(dev);
	u32	delay = 0;

1408 1409
	while (!rtl8192_phy_SwChnlStepByStep(dev, channel, &priv->SwChnlStage,
					     &priv->SwChnlStep, &delay)) {
1410
		if (!priv->up)
1411 1412 1413
			break;
	}
}
1414

1415
/******************************************************************************
1416 1417
 * function:  Callback routine of the work item for switch channel.
 * input:     net_device	*dev
1418
 *
1419 1420 1421
 * output:    none
 * return:    none
 *****************************************************************************/
1422 1423 1424 1425 1426
void rtl8192_SwChnl_WorkItem(struct net_device *dev)
{

	struct r8192_priv *priv = ieee80211_priv(dev);

1427 1428
	RT_TRACE(COMP_CH, "==> SwChnlCallback819xUsbWorkItem(), chan:%d\n",
		 priv->chan);
1429 1430


1431
	rtl8192_phy_FinishSwChnlNow(dev, priv->chan);
1432 1433 1434 1435 1436

	RT_TRACE(COMP_CH, "<== SwChnlCallback819xUsbWorkItem()\n");
}

/******************************************************************************
1437 1438 1439 1440 1441 1442 1443
 * function:  This function scheduled actual work item to set channel
 * input:     net_device        *dev
 *            u8                channel   //channel to set
 * output:    none
 * return:    return code show if workitem is scheduled (1:pass, 0:fail)
 * notice:    Delay may be required for RF configuration
 ******************************************************************************/
1444
u8 rtl8192_phy_SwChnl(struct net_device *dev, u8 channel)
1445 1446
{
	struct r8192_priv *priv = ieee80211_priv(dev);
1447

1448
	RT_TRACE(COMP_CH, "%s(), SwChnlInProgress: %d\n", __func__,
1449
		 priv->SwChnlInProgress);
1450
	if (!priv->up)
1451
		return false;
1452
	if (priv->SwChnlInProgress)
1453 1454
		return false;

1455
	/* -------------------------------------------- */
1456
	switch (priv->ieee80211->mode) {
1457 1458
	case WIRELESS_MODE_A:
	case WIRELESS_MODE_N_5G:
1459
		if (channel <= 14) {
1460
			RT_TRACE(COMP_ERR, "WIRELESS_MODE_A but channel<=14\n");
1461 1462 1463 1464
			return false;
		}
		break;
	case WIRELESS_MODE_B:
1465
		if (channel > 14) {
1466
			RT_TRACE(COMP_ERR, "WIRELESS_MODE_B but channel>14\n");
1467 1468 1469 1470 1471
			return false;
		}
		break;
	case WIRELESS_MODE_G:
	case WIRELESS_MODE_N_24G:
1472
		if (channel > 14) {
1473
			RT_TRACE(COMP_ERR, "WIRELESS_MODE_G but channel>14\n");
1474 1475 1476 1477
			return false;
		}
		break;
	}
1478
	/* -------------------------------------------- */
1479 1480

	priv->SwChnlInProgress = true;
1481
	if (channel == 0)
1482 1483
		channel = 1;

1484
	priv->chan = channel;
1485

1486 1487
	priv->SwChnlStage = 0;
	priv->SwChnlStep = 0;
1488
	if (priv->up)
1489
		rtl8192_SwChnl_WorkItem(dev);
1490 1491 1492 1493 1494 1495

	priv->SwChnlInProgress = false;
	return true;
}

/******************************************************************************
1496 1497 1498 1499 1500 1501 1502
 * function:  Callback routine of the work item for set bandwidth mode.
 * input:     net_device	 *dev
 * output:    none
 * return:    none
 * notice:    I doubt whether SetBWModeInProgress flag is necessary as we can
 *            test whether current work in the queue or not.//do I?
 *****************************************************************************/
1503 1504 1505 1506 1507 1508
void rtl8192_SetBWModeWorkItem(struct net_device *dev)
{

	struct r8192_priv *priv = ieee80211_priv(dev);
	u8 regBwOpMode;

1509
	RT_TRACE(COMP_SWBW, "%s()  Switch to %s bandwidth\n", __func__,
1510
		 priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20?"20MHz":"40MHz");
1511 1512


1513
	if (priv->rf_chip == RF_PSEUDO_11N) {
1514
		priv->SetBWModeInProgress = false;
1515 1516 1517
		return;
	}

1518
	/* <1> Set MAC register */
1519
	read_nic_byte(dev, BW_OPMODE, &regBwOpMode);
1520

1521
	switch (priv->CurrentChannelBW) {
1522 1523 1524 1525 1526
	case HT_CHANNEL_WIDTH_20:
		regBwOpMode |= BW_OPMODE_20MHZ;
		/* We have not verify whether this register works */
		write_nic_byte(dev, BW_OPMODE, regBwOpMode);
		break;
1527

1528 1529 1530 1531 1532
	case HT_CHANNEL_WIDTH_20_40:
		regBwOpMode &= ~BW_OPMODE_20MHZ;
		/* We have not verify whether this register works */
		write_nic_byte(dev, BW_OPMODE, regBwOpMode);
		break;
1533

1534 1535 1536 1537 1538
	default:
		RT_TRACE(COMP_ERR,
			 "SetChannelBandwidth819xUsb(): unknown Bandwidth: %#X\n",
			 priv->CurrentChannelBW);
		break;
1539 1540
	}

1541
	/* <2> Set PHY related register */
1542
	switch (priv->CurrentChannelBW) {
1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562
	case HT_CHANNEL_WIDTH_20:
		rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x0);
		rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x0);
		rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1,
				 0x00100000, 1);

		/* Correct the tx power for CCK rate in 20M. */
		priv->cck_present_attentuation =
			priv->cck_present_attentuation_20Mdefault +
			priv->cck_present_attentuation_difference;

		if (priv->cck_present_attentuation > 22)
			priv->cck_present_attentuation = 22;
		if (priv->cck_present_attentuation < 0)
			priv->cck_present_attentuation = 0;
		RT_TRACE(COMP_INIT,
			 "20M, pHalData->CCKPresentAttentuation = %d\n",
			 priv->cck_present_attentuation);

		if (priv->chan == 14 && !priv->bcck_in_ch14) {
1563
			priv->bcck_in_ch14 = true;
1564 1565
			dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
		} else if (priv->chan != 14 && priv->bcck_in_ch14) {
1566
			priv->bcck_in_ch14 = false;
1567 1568 1569 1570
			dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
		} else {
			dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
		}
1571

1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601
		break;
	case HT_CHANNEL_WIDTH_20_40:
		rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x1);
		rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x1);
		rtl8192_setBBreg(dev, rCCK0_System, bCCKSideBand,
				 priv->nCur40MhzPrimeSC>>1);
		rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x00100000, 0);
		rtl8192_setBBreg(dev, rOFDM1_LSTF, 0xC00,
				 priv->nCur40MhzPrimeSC);
		priv->cck_present_attentuation =
			priv->cck_present_attentuation_40Mdefault +
			priv->cck_present_attentuation_difference;

		if (priv->cck_present_attentuation > 22)
			priv->cck_present_attentuation = 22;
		if (priv->cck_present_attentuation < 0)
			priv->cck_present_attentuation = 0;

		RT_TRACE(COMP_INIT,
			 "40M, pHalData->CCKPresentAttentuation = %d\n",
			 priv->cck_present_attentuation);
		if (priv->chan == 14 && !priv->bcck_in_ch14) {
			priv->bcck_in_ch14 = true;
			dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
		} else if (priv->chan != 14 && priv->bcck_in_ch14) {
			priv->bcck_in_ch14 = false;
			dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
		} else {
			dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
		}
1602

1603 1604 1605 1606 1607 1608
		break;
	default:
		RT_TRACE(COMP_ERR,
			 "SetChannelBandwidth819xUsb(): unknown Bandwidth: %#X\n",
			 priv->CurrentChannelBW);
		break;
1609 1610

	}
1611 1612
	/* Skip over setting of J-mode in BB register here.
	   Default value is "None J mode". */
1613

1614
	/* <3> Set RF related register */
1615
	switch (priv->rf_chip) {
1616
	case RF_8225:
1617
#ifdef TO_DO_LIST
1618
		PHY_SetRF8225Bandwidth(Adapter, pHalData->CurrentChannelBW);
1619
#endif
1620
		break;
1621

1622 1623 1624
	case RF_8256:
		PHY_SetRF8256Bandwidth(dev, priv->CurrentChannelBW);
		break;
1625

1626 1627
	case RF_8258:
		break;
1628

1629 1630
	case RF_PSEUDO_11N:
		break;
1631

1632 1633 1634
	default:
		RT_TRACE(COMP_ERR, "Unknown RFChipID: %d\n", priv->rf_chip);
		break;
1635
	}
1636
	priv->SetBWModeInProgress = false;
1637

1638
	RT_TRACE(COMP_SWBW, "<==SetBWMode819xUsb(), %d\n",
1639
		 atomic_read(&priv->ieee80211->atm_swbw));
1640 1641 1642
}

/******************************************************************************
1643 1644 1645 1646 1647 1648 1649 1650 1651
 * function:  This function schedules bandwidth switch work.
 * input:     struct net_deviceq   *dev
 *            HT_CHANNEL_WIDTH     bandwidth  //20M or 40M
 *            HT_EXTCHNL_OFFSET    offset     //Upper, Lower, or Don't care
 * output:    none
 * return:    none
 * notice:    I doubt whether SetBWModeInProgress flag is necessary as we can
 *	      test whether current work in the queue or not.//do I?
 *****************************************************************************/
1652 1653
void rtl8192_SetBWMode(struct net_device *dev, HT_CHANNEL_WIDTH bandwidth,
		       HT_EXTCHNL_OFFSET offset)
1654 1655 1656
{
	struct r8192_priv *priv = ieee80211_priv(dev);

1657
	if (priv->SetBWModeInProgress)
1658
		return;
1659
	priv->SetBWModeInProgress = true;
1660

1661
	priv->CurrentChannelBW = bandwidth;
1662

1663
	if (offset == HT_EXTCHNL_OFFSET_LOWER)
1664
		priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_UPPER;
1665
	else if (offset == HT_EXTCHNL_OFFSET_UPPER)
1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679
		priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_LOWER;
	else
		priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_DONT_CARE;

	rtl8192_SetBWModeWorkItem(dev);

}

void InitialGain819xUsb(struct net_device *dev,	u8 Operation)
{
	struct r8192_priv *priv = ieee80211_priv(dev);

	priv->InitialGainOperateType = Operation;

1680
	if (priv->up)
1681
		queue_delayed_work(priv->priv_wq, &priv->initialgain_operate_wq, 0);
1682 1683
}

1684
void InitialGainOperateWorkItemCallBack(struct work_struct *work)
1685
{
1686 1687 1688 1689 1690
	struct delayed_work *dwork = container_of(work, struct delayed_work,
						  work);
	struct r8192_priv *priv = container_of(dwork, struct r8192_priv,
					       initialgain_operate_wq);
	struct net_device *dev = priv->ieee80211->dev;
1691 1692
#define SCAN_RX_INITIAL_GAIN	0x17
#define POWER_DETECTION_TH	0x08
1693
	u32	bitmask;
1694 1695 1696 1697 1698
	u8	initial_gain;
	u8	Operation;

	Operation = priv->InitialGainOperateType;

1699
	switch (Operation) {
1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729
	case IG_Backup:
		RT_TRACE(COMP_SCAN, "IG_Backup, backup the initial gain.\n");
		initial_gain = SCAN_RX_INITIAL_GAIN;
		bitmask = bMaskByte0;
		if (dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
			/* FW DIG OFF */
			rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);
		priv->initgain_backup.xaagccore1 =
			(u8)rtl8192_QueryBBReg(dev, rOFDM0_XAAGCCore1, bitmask);
		priv->initgain_backup.xbagccore1 =
			(u8)rtl8192_QueryBBReg(dev, rOFDM0_XBAGCCore1, bitmask);
		priv->initgain_backup.xcagccore1 =
			(u8)rtl8192_QueryBBReg(dev, rOFDM0_XCAGCCore1, bitmask);
		priv->initgain_backup.xdagccore1 =
			(u8)rtl8192_QueryBBReg(dev, rOFDM0_XDAGCCore1, bitmask);
		bitmask = bMaskByte2;
		priv->initgain_backup.cca =
			(u8)rtl8192_QueryBBReg(dev, rCCK0_CCA, bitmask);

		RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc50 is %x\n",
			 priv->initgain_backup.xaagccore1);
		RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc58 is %x\n",
			 priv->initgain_backup.xbagccore1);
		RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc60 is %x\n",
			 priv->initgain_backup.xcagccore1);
		RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc68 is %x\n",
			 priv->initgain_backup.xdagccore1);
		RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xa0a is %x\n",
			 priv->initgain_backup.cca);

1730
		RT_TRACE(COMP_SCAN, "Write scan initial gain = 0x%x\n",
1731 1732 1733 1734 1735
			 initial_gain);
		write_nic_byte(dev, rOFDM0_XAAGCCore1, initial_gain);
		write_nic_byte(dev, rOFDM0_XBAGCCore1, initial_gain);
		write_nic_byte(dev, rOFDM0_XCAGCCore1, initial_gain);
		write_nic_byte(dev, rOFDM0_XDAGCCore1, initial_gain);
1736
		RT_TRACE(COMP_SCAN, "Write scan 0xa0a = 0x%x\n",
1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768
			 POWER_DETECTION_TH);
		write_nic_byte(dev, 0xa0a, POWER_DETECTION_TH);
		break;
	case IG_Restore:
		RT_TRACE(COMP_SCAN, "IG_Restore, restore the initial gain.\n");
		bitmask = 0x7f; /* Bit0 ~ Bit6 */
		if (dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
			/* FW DIG OFF */
			rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);

		rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, bitmask,
				 (u32)priv->initgain_backup.xaagccore1);
		rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, bitmask,
				 (u32)priv->initgain_backup.xbagccore1);
		rtl8192_setBBreg(dev, rOFDM0_XCAGCCore1, bitmask,
				 (u32)priv->initgain_backup.xcagccore1);
		rtl8192_setBBreg(dev, rOFDM0_XDAGCCore1, bitmask,
				 (u32)priv->initgain_backup.xdagccore1);
		bitmask  = bMaskByte2;
		rtl8192_setBBreg(dev, rCCK0_CCA, bitmask,
				 (u32)priv->initgain_backup.cca);

		RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc50 is %x\n",
			 priv->initgain_backup.xaagccore1);
		RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc58 is %x\n",
			 priv->initgain_backup.xbagccore1);
		RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc60 is %x\n",
			 priv->initgain_backup.xcagccore1);
		RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc68 is %x\n",
			 priv->initgain_backup.xdagccore1);
		RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xa0a is %x\n",
			 priv->initgain_backup.cca);
1769

1770
		rtl8192_phy_setTxPower(dev, priv->ieee80211->current_network.channel);
1771

1772 1773 1774 1775 1776
		if (dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
			/* FW DIG ON */
			rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1);
		break;
	default:
1777
		RT_TRACE(COMP_SCAN, "Unknown IG Operation.\n");
1778
		break;
1779 1780
	}
}