/******************************************************************************
 * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * The full GNU General Public License is included in this distribution in the
 * file called LICENSE.
 *
 * Contact Information:
 * wlanfae <wlanfae@realtek.com>
 *****************************************************************************/

#include "rtl_core.h"
#include "r8192E_phyreg.h"
#include "r8192E_phy.h"
#include "r8190P_rtl8256.h"

void rtl92e_set_bandwidth(struct net_device *dev,
			  enum ht_channel_width Bandwidth)
{
	u8	eRFPath;
	struct r8192_priv *priv = rtllib_priv(dev);

	if (priv->card_8192_version != VERSION_8190_BD &&
	    priv->card_8192_version != VERSION_8190_BE) {
		netdev_warn(dev, "%s(): Unknown HW version.\n", __func__);
		return;
	}

	for (eRFPath = 0; eRFPath < priv->NumTotalRFPath; eRFPath++) {
		if (!rtl92e_is_legal_rf_path(dev, eRFPath))
			continue;

		switch (Bandwidth) {
		case HT_CHANNEL_WIDTH_20:
			rtl92e_set_rf_reg(dev, (enum rf90_radio_path)eRFPath,
					  0x0b, bMask12Bits, 0x100);
			rtl92e_set_rf_reg(dev, (enum rf90_radio_path)eRFPath,
					  0x2c, bMask12Bits, 0x3d7);
			rtl92e_set_rf_reg(dev, (enum rf90_radio_path)eRFPath,
					  0x0e, bMask12Bits, 0x021);
			break;
		case HT_CHANNEL_WIDTH_20_40:
			rtl92e_set_rf_reg(dev, (enum rf90_radio_path)eRFPath,
					  0x0b, bMask12Bits, 0x300);
			rtl92e_set_rf_reg(dev, (enum rf90_radio_path)eRFPath,
					  0x2c, bMask12Bits, 0x3ff);
			rtl92e_set_rf_reg(dev, (enum rf90_radio_path)eRFPath,
					  0x0e, bMask12Bits, 0x0e1);
			break;
		default:
			netdev_err(dev, "%s(): Unknown bandwidth: %#X\n",
				   __func__, Bandwidth);
			break;

		}
	}
}

bool rtl92e_config_rf(struct net_device *dev)
{
	u32	u4RegValue = 0;
	u8	eRFPath;
	bool rtStatus = true;
	struct bb_reg_definition *pPhyReg;
	struct r8192_priv *priv = rtllib_priv(dev);
	u32	RegOffSetToBeCheck = 0x3;
	u32	RegValueToBeCheck = 0x7f1;
	u32	RF3_Final_Value = 0;
	u8	ConstRetryTimes = 5, RetryTimes = 5;
	u8 ret = 0;

	priv->NumTotalRFPath = RTL819X_TOTAL_RF_PATH;

	for (eRFPath = (enum rf90_radio_path)RF90_PATH_A;
	     eRFPath < priv->NumTotalRFPath; eRFPath++) {
		if (!rtl92e_is_legal_rf_path(dev, eRFPath))
			continue;

		pPhyReg = &priv->PHYRegDef[eRFPath];


		switch (eRFPath) {
		case RF90_PATH_A:
		case RF90_PATH_C:
			u4RegValue = rtl92e_get_bb_reg(dev, pPhyReg->rfintfs,
						       bRFSI_RFENV);
			break;
		case RF90_PATH_B:
		case RF90_PATH_D:
			u4RegValue = rtl92e_get_bb_reg(dev, pPhyReg->rfintfs,
						       bRFSI_RFENV<<16);
			break;
		}

		rtl92e_set_bb_reg(dev, pPhyReg->rfintfe, bRFSI_RFENV<<16, 0x1);

		rtl92e_set_bb_reg(dev, pPhyReg->rfintfo, bRFSI_RFENV, 0x1);

		rtl92e_set_bb_reg(dev, pPhyReg->rfHSSIPara2,
				  b3WireAddressLength, 0x0);
		rtl92e_set_bb_reg(dev, pPhyReg->rfHSSIPara2,
				  b3WireDataLength, 0x0);

		rtl92e_set_rf_reg(dev, (enum rf90_radio_path)eRFPath, 0x0,
				  bMask12Bits, 0xbf);

		rtStatus = rtl92e_check_bb_and_rf(dev, HW90_BLOCK_RF,
						  (enum rf90_radio_path)eRFPath);
		if (!rtStatus) {
			netdev_err(dev, "%s(): Failed to check RF Path %d.\n",
				   __func__, eRFPath);
			goto fail;
		}

		RetryTimes = ConstRetryTimes;
		RF3_Final_Value = 0;
		while (RF3_Final_Value != RegValueToBeCheck &&
		       RetryTimes != 0) {
			ret = rtl92e_config_rf_path(dev,
						(enum rf90_radio_path)eRFPath);
			RF3_Final_Value = rtl92e_get_rf_reg(dev,
						(enum rf90_radio_path)eRFPath,
						RegOffSetToBeCheck,
						bMask12Bits);
			RT_TRACE(COMP_RF,
				 "RF %d %d register final value: %x\n",
				 eRFPath, RegOffSetToBeCheck,
				 RF3_Final_Value);
			RetryTimes--;
		}

		switch (eRFPath) {
		case RF90_PATH_A:
		case RF90_PATH_C:
			rtl92e_set_bb_reg(dev, pPhyReg->rfintfs, bRFSI_RFENV,
					  u4RegValue);
			break;
		case RF90_PATH_B:
		case RF90_PATH_D:
			rtl92e_set_bb_reg(dev, pPhyReg->rfintfs,
					  bRFSI_RFENV<<16, u4RegValue);
			break;
		}

		if (ret) {
			netdev_err(dev,
				   "%s(): Failed to initialize RF Path %d.\n",
				   __func__, eRFPath);
			goto fail;
		}

	}

	RT_TRACE(COMP_PHY, "PHY Initialization Success\n");
	return true;

fail:
	return false;
}

void rtl92e_set_cck_tx_power(struct net_device *dev, u8 powerlevel)
{
	u32	TxAGC = 0;
	struct r8192_priv *priv = rtllib_priv(dev);

	TxAGC = powerlevel;
	if (priv->bDynamicTxLowPower) {
		if (priv->CustomerID == RT_CID_819x_Netcore)
			TxAGC = 0x22;
		else
			TxAGC += priv->CckPwEnl;
	}
	if (TxAGC > 0x24)
		TxAGC = 0x24;
	rtl92e_set_bb_reg(dev, rTxAGC_CCK_Mcs32, bTxAGCRateCCK, TxAGC);
}


void rtl92e_set_ofdm_tx_power(struct net_device *dev, u8 powerlevel)
{
	struct r8192_priv *priv = rtllib_priv(dev);
	u32 writeVal, powerBase0, powerBase1, writeVal_tmp;
	u8 index = 0;
	u16 RegOffset[6] = {0xe00, 0xe04, 0xe10, 0xe14, 0xe18, 0xe1c};
	u8 byte0, byte1, byte2, byte3;

	powerBase0 = powerlevel + priv->LegacyHTTxPowerDiff;
	powerBase0 = (powerBase0 << 24) | (powerBase0 << 16) |
		     (powerBase0 << 8) | powerBase0;
	powerBase1 = powerlevel;
	powerBase1 = (powerBase1 << 24) | (powerBase1 << 16) |
		     (powerBase1 << 8) | powerBase1;

	for (index = 0; index < 6; index++) {
		writeVal = (u32)(priv->MCSTxPowerLevelOriginalOffset[index] +
			   ((index < 2) ? powerBase0 : powerBase1));
		byte0 = (u8)(writeVal & 0x7f);
		byte1 = (u8)((writeVal & 0x7f00)>>8);
		byte2 = (u8)((writeVal & 0x7f0000)>>16);
		byte3 = (u8)((writeVal & 0x7f000000)>>24);
		if (byte0 > 0x24)
			byte0 = 0x24;
		if (byte1 > 0x24)
			byte1 = 0x24;
		if (byte2 > 0x24)
			byte2 = 0x24;
		if (byte3 > 0x24)
			byte3 = 0x24;

		if (index == 3) {
			writeVal_tmp = (byte3 << 24) | (byte2 << 16) |
				       (byte1 << 8) | byte0;
			priv->Pwr_Track = writeVal_tmp;
		}

		if (priv->bDynamicTxHighPower)
			writeVal = 0x03030303;
		else
			writeVal = (byte3 << 24) | (byte2 << 16) |
				   (byte1 << 8) | byte0;
		rtl92e_set_bb_reg(dev, RegOffset[index], 0x7f7f7f7f, writeVal);
	}

}
