summaryrefslogtreecommitdiff
path: root/drivers/staging/winbond/wb35reg.c
diff options
context:
space:
mode:
authorPekka Enberg <penberg@cs.helsinki.fi>2008-10-30 13:05:42 +0200
committerGreg Kroah-Hartman <gregkh@suse.de>2009-01-06 13:51:47 -0800
commit9ce922fde7fb44a8690aa37d3c7f4f0cf5d921ca (patch)
tree7b03091ffe4ed1732f982dc44a875e2c5349c6e1 /drivers/staging/winbond/wb35reg.c
parent8421513d9ab4e510136d0b3042bd838d08129012 (diff)
Staging: w35und: move source files to one directory
As we're trying to get rid of the "compatability layer" in the driver, move everything under one directory. Keeping some of the files under drivers/staging/winbond/linux is a major pain in the ass whenever you're cleaning up the driver. Acked-by: Pavel Machek <pavel@suse.cz> Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/winbond/wb35reg.c')
-rw-r--r--drivers/staging/winbond/wb35reg.c747
1 files changed, 747 insertions, 0 deletions
diff --git a/drivers/staging/winbond/wb35reg.c b/drivers/staging/winbond/wb35reg.c
new file mode 100644
index 000000000000..c74b3fdcbda0
--- /dev/null
+++ b/drivers/staging/winbond/wb35reg.c
@@ -0,0 +1,747 @@
+#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"));
+ DebugUsbdStatusInformation( reg->EP0VM_status );
+#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_LENGTH_OF_ADDRESS );
+
+ // 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 );
+ }
+}
+
+