#include "sysdef.h"
#include "wb35reg_f.h"

#include <linux/usb.h>

extern void phy_calibration_winbond(hw_data_t *phw_data, u32 frequency);

// true  : read command process successfully
// false : register not support
// RegisterNo : start base
// pRegisterData : data point
// NumberOfData : number of register data
// Flag : AUTO_INCREMENT - RegisterNo will auto increment 4
//		  NO_INCREMENT - Function will write data into the same register
unsigned char
Wb35Reg_BurstWrite(phw_data_t pHwData, u16 RegisterNo, u32 * pRegisterData, u8 NumberOfData, u8 Flag)
{
	struct wb35_reg *reg = &pHwData->reg;
	struct urb	*urb = NULL;
	struct wb35_reg_queue *reg_queue = NULL;
	u16		UrbSize;
	struct      usb_ctrlrequest *dr;
	u16		i, DataSize = NumberOfData*4;

	// Module shutdown
	if (pHwData->SurpriseRemove)
		return false;

	// Trying to use burst write function if use new hardware
	UrbSize = sizeof(struct wb35_reg_queue) + DataSize + sizeof(struct usb_ctrlrequest);
	reg_queue = kzalloc(UrbSize, GFP_ATOMIC);
	urb = usb_alloc_urb(0, GFP_ATOMIC);
	if( urb && reg_queue ) {
		reg_queue->DIRECT = 2;// burst write register
		reg_queue->INDEX = RegisterNo;
		reg_queue->pBuffer = (u32 *)((u8 *)reg_queue + sizeof(struct wb35_reg_queue));
		memcpy( reg_queue->pBuffer, pRegisterData, DataSize );
		//the function for reversing register data from little endian to big endian
		for( i=0; i<NumberOfData ; i++ )
			reg_queue->pBuffer[i] = cpu_to_le32( reg_queue->pBuffer[i] );

		dr = (struct usb_ctrlrequest *)((u8 *)reg_queue + sizeof(struct wb35_reg_queue) + DataSize);
		dr->bRequestType = USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE;
		dr->bRequest = 0x04; // USB or vendor-defined request code, burst mode
		dr->wValue = cpu_to_le16( Flag ); // 0: Register number auto-increment, 1: No auto increment
		dr->wIndex = cpu_to_le16( RegisterNo );
		dr->wLength = cpu_to_le16( DataSize );
		reg_queue->Next = NULL;
		reg_queue->pUsbReq = dr;
		reg_queue->urb = urb;

		spin_lock_irq( &reg->EP0VM_spin_lock );
		if (reg->reg_first == NULL)
			reg->reg_first = reg_queue;
		else
			reg->reg_last->Next = reg_queue;
		reg->reg_last = reg_queue;

		spin_unlock_irq( &reg->EP0VM_spin_lock );

		// Start EP0VM
		Wb35Reg_EP0VM_start(pHwData);

		return true;
	} else {
		if (urb)
			usb_free_urb(urb);
		if (reg_queue)
			kfree(reg_queue);
		return false;
	}
   return false;
}

void
Wb35Reg_Update(phw_data_t pHwData,  u16 RegisterNo,  u32 RegisterValue)
{
	struct wb35_reg *reg = &pHwData->reg;
	switch (RegisterNo) {
	case 0x3b0: reg->U1B0 = RegisterValue; break;
	case 0x3bc: reg->U1BC_LEDConfigure = RegisterValue; break;
	case 0x400: reg->D00_DmaControl = RegisterValue; break;
	case 0x800: reg->M00_MacControl = RegisterValue; break;
	case 0x804: reg->M04_MulticastAddress1 = RegisterValue; break;
	case 0x808: reg->M08_MulticastAddress2 = RegisterValue; break;
	case 0x824: reg->M24_MacControl = RegisterValue; break;
	case 0x828: reg->M28_MacControl = RegisterValue; break;
	case 0x82c: reg->M2C_MacControl = RegisterValue; break;
	case 0x838: reg->M38_MacControl = RegisterValue; break;
	case 0x840: reg->M40_MacControl = RegisterValue; break;
	case 0x844: reg->M44_MacControl = RegisterValue; break;
	case 0x848: reg->M48_MacControl = RegisterValue; break;
	case 0x84c: reg->M4C_MacStatus = RegisterValue; break;
	case 0x860: reg->M60_MacControl = RegisterValue; break;
	case 0x868: reg->M68_MacControl = RegisterValue; break;
	case 0x870: reg->M70_MacControl = RegisterValue; break;
	case 0x874: reg->M74_MacControl = RegisterValue; break;
	case 0x878: reg->M78_ERPInformation = RegisterValue; break;
	case 0x87C: reg->M7C_MacControl = RegisterValue; break;
	case 0x880: reg->M80_MacControl = RegisterValue; break;
	case 0x884: reg->M84_MacControl = RegisterValue; break;
	case 0x888: reg->M88_MacControl = RegisterValue; break;
	case 0x898: reg->M98_MacControl = RegisterValue; break;
	case 0x100c: reg->BB0C = RegisterValue; break;
	case 0x102c: reg->BB2C = RegisterValue; break;
	case 0x1030: reg->BB30 = RegisterValue; break;
	case 0x103c: reg->BB3C = RegisterValue; break;
	case 0x1048: reg->BB48 = RegisterValue; break;
	case 0x104c: reg->BB4C = RegisterValue; break;
	case 0x1050: reg->BB50 = RegisterValue; break;
	case 0x1054: reg->BB54 = RegisterValue; break;
	case 0x1058: reg->BB58 = RegisterValue; break;
	case 0x105c: reg->BB5C = RegisterValue; break;
	case 0x1060: reg->BB60 = RegisterValue; break;
	}
}

// true  : read command process successfully
// false : register not support
unsigned char
Wb35Reg_WriteSync(  phw_data_t pHwData,  u16 RegisterNo,  u32 RegisterValue )
{
	struct wb35_reg *reg = &pHwData->reg;
	int ret = -1;

	// Module shutdown
	if (pHwData->SurpriseRemove)
		return false;

	RegisterValue = cpu_to_le32(RegisterValue);

	// update the register by send usb message------------------------------------
	reg->SyncIoPause = 1;

	// 20060717.5 Wait until EP0VM stop
	while (reg->EP0vm_state != VM_STOP)
		msleep(10);

	// Sync IoCallDriver
	reg->EP0vm_state = VM_RUNNING;
	ret = usb_control_msg( pHwData->WbUsb.udev,
			       usb_sndctrlpipe( pHwData->WbUsb.udev, 0 ),
			       0x03, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
			       0x0,RegisterNo, &RegisterValue, 4, HZ*100 );
	reg->EP0vm_state = VM_STOP;
	reg->SyncIoPause = 0;

	Wb35Reg_EP0VM_start(pHwData);

	if (ret < 0) {
		#ifdef _PE_REG_DUMP_
		WBDEBUG(("EP0 Write register usb message sending error\n"));
		#endif

		pHwData->SurpriseRemove = 1; // 20060704.2
		return false;
	}

	return true;
}

// true  : read command process successfully
// false : register not support
unsigned char
Wb35Reg_Write(  phw_data_t pHwData,  u16 RegisterNo,  u32 RegisterValue )
{
	struct wb35_reg *reg = &pHwData->reg;
	struct usb_ctrlrequest *dr;
	struct urb	*urb = NULL;
	struct wb35_reg_queue *reg_queue = NULL;
	u16		UrbSize;


	// Module shutdown
	if (pHwData->SurpriseRemove)
		return false;

	// update the register by send urb request------------------------------------
	UrbSize = sizeof(struct wb35_reg_queue) + sizeof(struct usb_ctrlrequest);
	reg_queue = kzalloc(UrbSize, GFP_ATOMIC);
	urb = usb_alloc_urb(0, GFP_ATOMIC);
	if (urb && reg_queue) {
		reg_queue->DIRECT = 1;// burst write register
		reg_queue->INDEX = RegisterNo;
		reg_queue->VALUE = cpu_to_le32(RegisterValue);
		reg_queue->RESERVED_VALID = false;
		dr = (struct usb_ctrlrequest *)((u8 *)reg_queue + sizeof(struct wb35_reg_queue));
		dr->bRequestType = USB_TYPE_VENDOR|USB_DIR_OUT |USB_RECIP_DEVICE;
		dr->bRequest = 0x03; // USB or vendor-defined request code, burst mode
		dr->wValue = cpu_to_le16(0x0);
		dr->wIndex = cpu_to_le16(RegisterNo);
		dr->wLength = cpu_to_le16(4);

		// Enter the sending queue
		reg_queue->Next = NULL;
		reg_queue->pUsbReq = dr;
		reg_queue->urb = urb;

		spin_lock_irq(&reg->EP0VM_spin_lock );
		if (reg->reg_first == NULL)
			reg->reg_first = reg_queue;
		else
			reg->reg_last->Next = reg_queue;
		reg->reg_last = reg_queue;

		spin_unlock_irq( &reg->EP0VM_spin_lock );

		// Start EP0VM
		Wb35Reg_EP0VM_start(pHwData);

		return true;
	} else {
		if (urb)
			usb_free_urb(urb);
		kfree(reg_queue);
		return false;
	}
}

//This command will be executed with a user defined value. When it completes,
//this value is useful. For example, hal_set_current_channel will use it.
// true  : read command process successfully
// false : register not support
unsigned char
Wb35Reg_WriteWithCallbackValue( phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue,
				s8 *pValue, s8 Len)
{
	struct wb35_reg *reg = &pHwData->reg;
	struct usb_ctrlrequest *dr;
	struct urb	*urb = NULL;
	struct wb35_reg_queue *reg_queue = NULL;
	u16		UrbSize;

	// Module shutdown
	if (pHwData->SurpriseRemove)
		return false;

	// update the register by send urb request------------------------------------
	UrbSize = sizeof(struct wb35_reg_queue) + sizeof(struct usb_ctrlrequest);
	reg_queue = kzalloc(UrbSize, GFP_ATOMIC);
	urb = usb_alloc_urb(0, GFP_ATOMIC);
	if (urb && reg_queue) {
		reg_queue->DIRECT = 1;// burst write register
		reg_queue->INDEX = RegisterNo;
		reg_queue->VALUE = cpu_to_le32(RegisterValue);
		//NOTE : Users must guarantee the size of value will not exceed the buffer size.
		memcpy(reg_queue->RESERVED, pValue, Len);
		reg_queue->RESERVED_VALID = true;
		dr = (struct usb_ctrlrequest *)((u8 *)reg_queue + sizeof(struct wb35_reg_queue));
		dr->bRequestType = USB_TYPE_VENDOR|USB_DIR_OUT |USB_RECIP_DEVICE;
		dr->bRequest = 0x03; // USB or vendor-defined request code, burst mode
		dr->wValue = cpu_to_le16(0x0);
		dr->wIndex = cpu_to_le16(RegisterNo);
		dr->wLength = cpu_to_le16(4);

		// Enter the sending queue
		reg_queue->Next = NULL;
		reg_queue->pUsbReq = dr;
		reg_queue->urb = urb;
		spin_lock_irq (&reg->EP0VM_spin_lock );
		if( reg->reg_first == NULL )
			reg->reg_first = reg_queue;
		else
			reg->reg_last->Next = reg_queue;
		reg->reg_last = reg_queue;

		spin_unlock_irq ( &reg->EP0VM_spin_lock );

		// Start EP0VM
		Wb35Reg_EP0VM_start(pHwData);
		return true;
	} else {
		if (urb)
			usb_free_urb(urb);
		kfree(reg_queue);
		return false;
	}
}

// true  : read command process successfully
// false : register not support
// pRegisterValue : It must be a resident buffer due to asynchronous read register.
unsigned char
Wb35Reg_ReadSync(  phw_data_t pHwData,  u16 RegisterNo,   u32 * pRegisterValue )
{
	struct wb35_reg *reg = &pHwData->reg;
	u32 *	pltmp = pRegisterValue;
	int ret = -1;

	// Module shutdown
	if (pHwData->SurpriseRemove)
		return false;

	// Read the register by send usb message------------------------------------

	reg->SyncIoPause = 1;

	// 20060717.5 Wait until EP0VM stop
	while (reg->EP0vm_state != VM_STOP)
		msleep(10);

	reg->EP0vm_state = VM_RUNNING;
	ret = usb_control_msg( pHwData->WbUsb.udev,
			       usb_rcvctrlpipe(pHwData->WbUsb.udev, 0),
			       0x01, USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_DIR_IN,
			       0x0, RegisterNo, pltmp, 4, HZ*100 );

	*pRegisterValue = cpu_to_le32(*pltmp);

	reg->EP0vm_state = VM_STOP;

	Wb35Reg_Update( pHwData, RegisterNo, *pRegisterValue );
	reg->SyncIoPause = 0;

	Wb35Reg_EP0VM_start( pHwData );

	if (ret < 0) {
		#ifdef _PE_REG_DUMP_
		WBDEBUG(("EP0 Read register usb message sending error\n"));
		#endif

		pHwData->SurpriseRemove = 1; // 20060704.2
		return false;
	}

	return true;
}

// true  : read command process successfully
// false : register not support
// pRegisterValue : It must be a resident buffer due to asynchronous read register.
unsigned char
Wb35Reg_Read(phw_data_t pHwData, u16 RegisterNo,  u32 * pRegisterValue )
{
	struct wb35_reg *reg = &pHwData->reg;
	struct usb_ctrlrequest * dr;
	struct urb	*urb;
	struct wb35_reg_queue *reg_queue;
	u16		UrbSize;

	// Module shutdown
	if (pHwData->SurpriseRemove)
		return false;

	// update the variable by send Urb to read register ------------------------------------
	UrbSize = sizeof(struct wb35_reg_queue) + sizeof(struct usb_ctrlrequest);
	reg_queue = kzalloc(UrbSize, GFP_ATOMIC);
	urb = usb_alloc_urb(0, GFP_ATOMIC);
	if( urb && reg_queue )
	{
		reg_queue->DIRECT = 0;// read register
		reg_queue->INDEX = RegisterNo;
		reg_queue->pBuffer = pRegisterValue;
		dr = (struct usb_ctrlrequest *)((u8 *)reg_queue + sizeof(struct wb35_reg_queue));
		dr->bRequestType = USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_DIR_IN;
		dr->bRequest = 0x01; // USB or vendor-defined request code, burst mode
		dr->wValue = cpu_to_le16(0x0);
		dr->wIndex = cpu_to_le16 (RegisterNo);
		dr->wLength = cpu_to_le16 (4);

		// Enter the sending queue
		reg_queue->Next = NULL;
		reg_queue->pUsbReq = dr;
		reg_queue->urb = urb;
		spin_lock_irq ( &reg->EP0VM_spin_lock );
		if( reg->reg_first == NULL )
			reg->reg_first = reg_queue;
		else
			reg->reg_last->Next = reg_queue;
		reg->reg_last = reg_queue;

		spin_unlock_irq( &reg->EP0VM_spin_lock );

		// Start EP0VM
		Wb35Reg_EP0VM_start( pHwData );

		return true;
	} else {
		if (urb)
			usb_free_urb( urb );
		kfree(reg_queue);
		return false;
	}
}


void
Wb35Reg_EP0VM_start(  phw_data_t pHwData )
{
	struct wb35_reg *reg = &pHwData->reg;

	if (atomic_inc_return(&reg->RegFireCount) == 1) {
		reg->EP0vm_state = VM_RUNNING;
		Wb35Reg_EP0VM(pHwData);
	} else
		atomic_dec(&reg->RegFireCount);
}

void
Wb35Reg_EP0VM(phw_data_t pHwData )
{
	struct wb35_reg *reg = &pHwData->reg;
	struct urb	*urb;
	struct usb_ctrlrequest *dr;
	u32 *		pBuffer;
	int			ret = -1;
	struct wb35_reg_queue *reg_queue;


	if (reg->SyncIoPause)
		goto cleanup;

	if (pHwData->SurpriseRemove)
		goto cleanup;

	// Get the register data and send to USB through Irp
	spin_lock_irq( &reg->EP0VM_spin_lock );
	reg_queue = reg->reg_first;
	spin_unlock_irq( &reg->EP0VM_spin_lock );

	if (!reg_queue)
		goto cleanup;

	// Get an Urb, send it
	urb = (struct urb *)reg_queue->urb;

	dr = reg_queue->pUsbReq;
	urb = reg_queue->urb;
	pBuffer = reg_queue->pBuffer;
	if (reg_queue->DIRECT == 1) // output
		pBuffer = &reg_queue->VALUE;

	usb_fill_control_urb( urb, pHwData->WbUsb.udev,
			      REG_DIRECTION(pHwData->WbUsb.udev,reg_queue),
			      (u8 *)dr,pBuffer,cpu_to_le16(dr->wLength),
			      Wb35Reg_EP0VM_complete, (void*)pHwData);

	reg->EP0vm_state = VM_RUNNING;

	ret = usb_submit_urb(urb, GFP_ATOMIC);

	if (ret < 0) {
#ifdef _PE_REG_DUMP_
		WBDEBUG(("EP0 Irp sending error\n"));
#endif
		goto cleanup;
	}

	return;

 cleanup:
	reg->EP0vm_state = VM_STOP;
	atomic_dec(&reg->RegFireCount);
}


void
Wb35Reg_EP0VM_complete(struct urb *urb)
{
	phw_data_t  pHwData = (phw_data_t)urb->context;
	struct wb35_reg *reg = &pHwData->reg;
	struct wb35_reg_queue *reg_queue;


	// Variable setting
	reg->EP0vm_state = VM_COMPLETED;
	reg->EP0VM_status = urb->status;

	if (pHwData->SurpriseRemove) { // Let WbWlanHalt to handle surprise remove
		reg->EP0vm_state = VM_STOP;
		atomic_dec(&reg->RegFireCount);
	} else {
		// Complete to send, remove the URB from the first
		spin_lock_irq( &reg->EP0VM_spin_lock );
		reg_queue = reg->reg_first;
		if (reg_queue == reg->reg_last)
			reg->reg_last = NULL;
		reg->reg_first = reg->reg_first->Next;
		spin_unlock_irq( &reg->EP0VM_spin_lock );

		if (reg->EP0VM_status) {
#ifdef _PE_REG_DUMP_
			WBDEBUG(("EP0 IoCompleteRoutine return error\n"));
#endif
			reg->EP0vm_state = VM_STOP;
			pHwData->SurpriseRemove = 1;
		} else {
			// Success. Update the result

			// Start the next send
			Wb35Reg_EP0VM(pHwData);
		}

   		kfree(reg_queue);
	}

	usb_free_urb(urb);
}


void
Wb35Reg_destroy(phw_data_t pHwData)
{
	struct wb35_reg *reg = &pHwData->reg;
	struct urb	*urb;
	struct wb35_reg_queue *reg_queue;


	Uxx_power_off_procedure(pHwData);

	// Wait for Reg operation completed
	do {
		msleep(10); // Delay for waiting function enter 940623.1.a
	} while (reg->EP0vm_state != VM_STOP);
	msleep(10);  // Delay for waiting function enter 940623.1.b

	// Release all the data in RegQueue
	spin_lock_irq( &reg->EP0VM_spin_lock );
	reg_queue = reg->reg_first;
	while (reg_queue) {
		if (reg_queue == reg->reg_last)
			reg->reg_last = NULL;
		reg->reg_first = reg->reg_first->Next;

		urb = reg_queue->urb;
		spin_unlock_irq( &reg->EP0VM_spin_lock );
		if (urb) {
			usb_free_urb(urb);
			kfree(reg_queue);
		} else {
			#ifdef _PE_REG_DUMP_
			WBDEBUG(("EP0 queue release error\n"));
			#endif
		}
		spin_lock_irq( &reg->EP0VM_spin_lock );

		reg_queue = reg->reg_first;
	}
	spin_unlock_irq( &reg->EP0VM_spin_lock );
}

//====================================================================================
// The function can be run in passive-level only.
//====================================================================================
unsigned char Wb35Reg_initial(phw_data_t pHwData)
{
	struct wb35_reg *reg=&pHwData->reg;
	u32 ltmp;
	u32 SoftwareSet, VCO_trim, TxVga, Region_ScanInterval;

	// Spin lock is acquired for read and write IRP command
	spin_lock_init( &reg->EP0VM_spin_lock );

	// Getting RF module type from EEPROM ------------------------------------
	Wb35Reg_WriteSync( pHwData, 0x03b4, 0x080d0000 ); // Start EEPROM access + Read + address(0x0d)
	Wb35Reg_ReadSync( pHwData, 0x03b4, &ltmp );

	//Update RF module type and determine the PHY type by inf or EEPROM
	reg->EEPROMPhyType = (u8)( ltmp & 0xff );
	// 0 V MAX2825, 1 V MAX2827, 2 V MAX2828, 3 V MAX2829
	// 16V AL2230, 17 - AL7230, 18 - AL2230S
	// 32 Reserved
	// 33 - W89RF242(TxVGA 0~19), 34 - W89RF242(TxVGA 0~34)
	if (reg->EEPROMPhyType != RF_DECIDE_BY_INF) {
		if( (reg->EEPROMPhyType == RF_MAXIM_2825)	||
			(reg->EEPROMPhyType == RF_MAXIM_2827)	||
			(reg->EEPROMPhyType == RF_MAXIM_2828)	||
			(reg->EEPROMPhyType == RF_MAXIM_2829)	||
			(reg->EEPROMPhyType == RF_MAXIM_V1)	||
			(reg->EEPROMPhyType == RF_AIROHA_2230)	||
			(reg->EEPROMPhyType == RF_AIROHA_2230S)    ||
			(reg->EEPROMPhyType == RF_AIROHA_7230)	||
			(reg->EEPROMPhyType == RF_WB_242)		||
			(reg->EEPROMPhyType == RF_WB_242_1))
			pHwData->phy_type = reg->EEPROMPhyType;
	}

	// Power On procedure running. The relative parameter will be set according to phy_type
	Uxx_power_on_procedure( pHwData );

	// Reading MAC address
	Uxx_ReadEthernetAddress( pHwData );

	// Read VCO trim for RF parameter
	Wb35Reg_WriteSync( pHwData, 0x03b4, 0x08200000 );
	Wb35Reg_ReadSync( pHwData, 0x03b4, &VCO_trim );

	// Read Antenna On/Off of software flag
	Wb35Reg_WriteSync( pHwData, 0x03b4, 0x08210000 );
	Wb35Reg_ReadSync( pHwData, 0x03b4, &SoftwareSet );

	// Read TXVGA
	Wb35Reg_WriteSync( pHwData, 0x03b4, 0x08100000 );
	Wb35Reg_ReadSync( pHwData, 0x03b4, &TxVga );

	// Get Scan interval setting from EEPROM offset 0x1c
	Wb35Reg_WriteSync( pHwData, 0x03b4, 0x081d0000 );
	Wb35Reg_ReadSync( pHwData, 0x03b4, &Region_ScanInterval );

	// Update Ethernet address
	memcpy( pHwData->CurrentMacAddress, pHwData->PermanentMacAddress, ETH_ALEN );

	// Update software variable
	pHwData->SoftwareSet = (u16)(SoftwareSet & 0xffff);
	TxVga &= 0x000000ff;
	pHwData->PowerIndexFromEEPROM = (u8)TxVga;
	pHwData->VCO_trim = (u8)VCO_trim & 0xff;
	if (pHwData->VCO_trim == 0xff)
		pHwData->VCO_trim = 0x28;

	reg->EEPROMRegion = (u8)(Region_ScanInterval>>8); // 20060720
	if( reg->EEPROMRegion<1 || reg->EEPROMRegion>6 )
		reg->EEPROMRegion = REGION_AUTO;

	//For Get Tx VGA from EEPROM 20060315.5 move here
	GetTxVgaFromEEPROM( pHwData );

	// Set Scan Interval
	pHwData->Scan_Interval = (u8)(Region_ScanInterval & 0xff) * 10;
	if ((pHwData->Scan_Interval == 2550) || (pHwData->Scan_Interval < 10)) // Is default setting 0xff * 10
		pHwData->Scan_Interval = SCAN_MAX_CHNL_TIME;

	// Initial register
	RFSynthesizer_initial(pHwData);

	BBProcessor_initial(pHwData); // Async write, must wait until complete

	Wb35Reg_phy_calibration(pHwData);

	Mxx_initial(pHwData);
	Dxx_initial(pHwData);

	if (pHwData->SurpriseRemove)
		return false;
	else
		return true; // Initial fail
}

//===================================================================================
//  CardComputeCrc --
//
//  Description:
//    Runs the AUTODIN II CRC algorithm on buffer Buffer of length, Length.
//
//  Arguments:
//    Buffer - the input buffer
//    Length - the length of Buffer
//
//  Return Value:
//    The 32-bit CRC value.
//
//  Note:
//    This is adapted from the comments in the assembly language
//    version in _GENREQ.ASM of the DWB NE1000/2000 driver.
//==================================================================================
u32
CardComputeCrc(u8 * Buffer, u32 Length)
{
    u32 Crc, Carry;
    u32  i, j;
    u8 CurByte;

    Crc = 0xffffffff;

    for (i = 0; i < Length; i++) {

        CurByte = Buffer[i];

        for (j = 0; j < 8; j++) {

            Carry     = ((Crc & 0x80000000) ? 1 : 0) ^ (CurByte & 0x01);
            Crc     <<= 1;
            CurByte >>= 1;

            if (Carry) {
                Crc =(Crc ^ 0x04c11db6) | Carry;
            }
        }
    }

    return Crc;
}


//==================================================================
// BitReverse --
//   Reverse the bits in the input argument, dwData, which is
//   regarded as a string of bits with the length, DataLength.
//
// Arguments:
//   dwData     :
//   DataLength :
//
// Return:
//   The converted value.
//==================================================================
u32 BitReverse( u32 dwData, u32 DataLength)
{
	u32   HalfLength, i, j;
	u32   BitA, BitB;

	if ( DataLength <= 0)       return 0;   // No conversion is done.
	dwData = dwData & (0xffffffff >> (32 - DataLength));

	HalfLength = DataLength / 2;
	for ( i = 0, j = DataLength-1 ; i < HalfLength; i++, j--)
	{
		BitA = GetBit( dwData, i);
		BitB = GetBit( dwData, j);
		if (BitA && !BitB) {
			dwData = ClearBit( dwData, i);
			dwData = SetBit( dwData, j);
		} else if (!BitA && BitB) {
			dwData = SetBit( dwData, i);
			dwData = ClearBit( dwData, j);
		} else
		{
			// Do nothing since these two bits are of the save values.
		}
	}

	return dwData;
}

void Wb35Reg_phy_calibration(  phw_data_t pHwData )
{
	u32 BB3c, BB54;

	if ((pHwData->phy_type == RF_WB_242) ||
		(pHwData->phy_type == RF_WB_242_1)) {
		phy_calibration_winbond ( pHwData, 2412 ); // Sync operation
		Wb35Reg_ReadSync( pHwData, 0x103c, &BB3c );
		Wb35Reg_ReadSync( pHwData, 0x1054, &BB54 );

		pHwData->BB3c_cal = BB3c;
		pHwData->BB54_cal = BB54;

		RFSynthesizer_initial(pHwData);
		BBProcessor_initial(pHwData); // Async operation

		Wb35Reg_WriteSync( pHwData, 0x103c, BB3c );
		Wb35Reg_WriteSync( pHwData, 0x1054, BB54 );
	}
}


