--- /dev/null
+From 66101de10957e07a6fd0365d5af9adf650246d14 Mon Sep 17 00:00:00 2001
+From: Pavel Machek <pavel@suse.cz>
+Date: Wed, 1 Oct 2008 14:36:56 +0200
+Subject: [PATCH 14/23] Staging: add w35und wifi driver
+Patch-mainline: 2.6.28
+
+This is driver for w35und usb wifi -- also in kohjinsha
+subnotebook. It should work well enough to associate and ping, but it
+obviously needs to be rewritten two more times...
+
+OTOH worst horrors (like embedded wifi stack) should have been fixed
+already...
+
+Signed-off-by: Pavel Machek <pavel@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/staging/Kconfig | 2 +
+ drivers/staging/Makefile | 1 +
+ drivers/staging/winbond/Kconfig | 7 +
+ drivers/staging/winbond/Makefile | 18 +
+ drivers/staging/winbond/README | 10 +
+ drivers/staging/winbond/adapter.h | 23 +
+ drivers/staging/winbond/bss_f.h | 59 +
+ drivers/staging/winbond/bssdscpt.h | 156 ++
+ drivers/staging/winbond/ds_tkip.h | 33 +
+ drivers/staging/winbond/gl_80211.h | 125 ++
+ drivers/staging/winbond/ioctls.h | 678 ++++++++
+ drivers/staging/winbond/linux/common.h | 143 ++
+ drivers/staging/winbond/linux/sysdef.h | 73 +
+ drivers/staging/winbond/linux/wb35reg.c | 747 ++++++++
+ drivers/staging/winbond/linux/wb35reg_f.h | 56 +
+ drivers/staging/winbond/linux/wb35reg_s.h | 170 ++
+ drivers/staging/winbond/linux/wb35rx.c | 337 ++++
+ drivers/staging/winbond/linux/wb35rx_f.h | 17 +
+ drivers/staging/winbond/linux/wb35rx_s.h | 48 +
+ drivers/staging/winbond/linux/wb35tx.c | 313 ++++
+ drivers/staging/winbond/linux/wb35tx_f.h | 20 +
+ drivers/staging/winbond/linux/wb35tx_s.h | 47 +
+ drivers/staging/winbond/linux/wbusb.c | 404 +++++
+ drivers/staging/winbond/linux/wbusb_f.h | 34 +
+ drivers/staging/winbond/linux/wbusb_s.h | 42 +
+ drivers/staging/winbond/localpara.h | 275 +++
+ drivers/staging/winbond/mac_structures.h | 670 +++++++
+ drivers/staging/winbond/mds.c | 630 +++++++
+ drivers/staging/winbond/mds_f.h | 33 +
+ drivers/staging/winbond/mds_s.h | 183 ++
+ drivers/staging/winbond/mlme_mib.h | 84 +
+ drivers/staging/winbond/mlme_s.h | 195 +++
+ drivers/staging/winbond/mlmetxrx.c | 150 ++
+ drivers/staging/winbond/mlmetxrx_f.h | 52 +
+ drivers/staging/winbond/mto.c | 1229 +++++++++++++
+ drivers/staging/winbond/mto.h | 265 +++
+ drivers/staging/winbond/mto_f.h | 7 +
+ drivers/staging/winbond/os_common.h | 2 +
+ drivers/staging/winbond/phy_calibration.c | 1759 +++++++++++++++++++
+ drivers/staging/winbond/phy_calibration.h | 101 ++
+ drivers/staging/winbond/reg.c | 2683 +++++++++++++++++++++++++++++
+ drivers/staging/winbond/rxisr.c | 30 +
+ drivers/staging/winbond/scan_s.h | 115 ++
+ drivers/staging/winbond/sme_api.c | 13 +
+ drivers/staging/winbond/sme_api.h | 265 +++
+ drivers/staging/winbond/sme_s.h | 228 +++
+ drivers/staging/winbond/wb35_ver.h | 30 +
+ drivers/staging/winbond/wbhal.c | 878 ++++++++++
+ drivers/staging/winbond/wbhal_f.h | 122 ++
+ drivers/staging/winbond/wbhal_s.h | 615 +++++++
+ drivers/staging/winbond/wblinux.c | 277 +++
+ drivers/staging/winbond/wblinux_f.h | 23 +
+ drivers/staging/winbond/wblinux_s.h | 45 +
+ 53 files changed, 14522 insertions(+), 0 deletions(-)
+ create mode 100644 drivers/staging/winbond/Kconfig
+ create mode 100644 drivers/staging/winbond/Makefile
+ create mode 100644 drivers/staging/winbond/README
+ create mode 100644 drivers/staging/winbond/adapter.h
+ create mode 100644 drivers/staging/winbond/bss_f.h
+ create mode 100644 drivers/staging/winbond/bssdscpt.h
+ create mode 100644 drivers/staging/winbond/ds_tkip.h
+ create mode 100644 drivers/staging/winbond/gl_80211.h
+ create mode 100644 drivers/staging/winbond/ioctls.h
+ create mode 100644 drivers/staging/winbond/linux/common.h
+ create mode 100644 drivers/staging/winbond/linux/sysdef.h
+ create mode 100644 drivers/staging/winbond/linux/wb35reg.c
+ create mode 100644 drivers/staging/winbond/linux/wb35reg_f.h
+ create mode 100644 drivers/staging/winbond/linux/wb35reg_s.h
+ create mode 100644 drivers/staging/winbond/linux/wb35rx.c
+ create mode 100644 drivers/staging/winbond/linux/wb35rx_f.h
+ create mode 100644 drivers/staging/winbond/linux/wb35rx_s.h
+ create mode 100644 drivers/staging/winbond/linux/wb35tx.c
+ create mode 100644 drivers/staging/winbond/linux/wb35tx_f.h
+ create mode 100644 drivers/staging/winbond/linux/wb35tx_s.h
+ create mode 100644 drivers/staging/winbond/linux/wbusb.c
+ create mode 100644 drivers/staging/winbond/linux/wbusb_f.h
+ create mode 100644 drivers/staging/winbond/linux/wbusb_s.h
+ create mode 100644 drivers/staging/winbond/localpara.h
+ create mode 100644 drivers/staging/winbond/mac_structures.h
+ create mode 100644 drivers/staging/winbond/mds.c
+ create mode 100644 drivers/staging/winbond/mds_f.h
+ create mode 100644 drivers/staging/winbond/mds_s.h
+ create mode 100644 drivers/staging/winbond/mlme_mib.h
+ create mode 100644 drivers/staging/winbond/mlme_s.h
+ create mode 100644 drivers/staging/winbond/mlmetxrx.c
+ create mode 100644 drivers/staging/winbond/mlmetxrx_f.h
+ create mode 100644 drivers/staging/winbond/mto.c
+ create mode 100644 drivers/staging/winbond/mto.h
+ create mode 100644 drivers/staging/winbond/mto_f.h
+ create mode 100644 drivers/staging/winbond/os_common.h
+ create mode 100644 drivers/staging/winbond/phy_calibration.c
+ create mode 100644 drivers/staging/winbond/phy_calibration.h
+ create mode 100644 drivers/staging/winbond/reg.c
+ create mode 100644 drivers/staging/winbond/rxisr.c
+ create mode 100644 drivers/staging/winbond/scan_s.h
+ create mode 100644 drivers/staging/winbond/sme_api.c
+ create mode 100644 drivers/staging/winbond/sme_api.h
+ create mode 100644 drivers/staging/winbond/sme_s.h
+ create mode 100644 drivers/staging/winbond/wb35_ver.h
+ create mode 100644 drivers/staging/winbond/wbhal.c
+ create mode 100644 drivers/staging/winbond/wbhal_f.h
+ create mode 100644 drivers/staging/winbond/wbhal_s.h
+ create mode 100644 drivers/staging/winbond/wblinux.c
+ create mode 100644 drivers/staging/winbond/wblinux_f.h
+ create mode 100644 drivers/staging/winbond/wblinux_s.h
+
+diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
+index 4dbf795..fdbdf84 100644
+--- a/drivers/staging/Kconfig
++++ b/drivers/staging/Kconfig
+@@ -35,4 +35,6 @@ source "drivers/staging/go7007/Kconfig"
+
+ source "drivers/staging/usbip/Kconfig"
+
++source "drivers/staging/winbond/Kconfig"
++
+ endif # STAGING
+diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
+index be42c0d..9b576c9 100644
+--- a/drivers/staging/Makefile
++++ b/drivers/staging/Makefile
+@@ -6,3 +6,4 @@ obj-$(CONFIG_SXG) += sxg/
+ obj-$(CONFIG_ME4000) += me4000/
+ obj-$(CONFIG_VIDEO_GO7007) += go7007/
+ obj-$(CONFIG_USB_IP_COMMON) += usbip/
++obj-$(CONFIG_W35UND) += winbond/
+diff --git a/drivers/staging/winbond/Kconfig b/drivers/staging/winbond/Kconfig
+new file mode 100644
+index 0000000..10d72be
+--- /dev/null
++++ b/drivers/staging/winbond/Kconfig
+@@ -0,0 +1,7 @@
++config W35UND
++ tristate "Winbond driver"
++ depends on MAC80211 && WLAN_80211 && EXPERIMENTAL && !4KSTACKS
++ default n
++ ---help---
++ This is highly experimental driver for winbond wifi card on some Kohjinsha notebooks
++ Check http://code.google.com/p/winbondport/ for new version
+diff --git a/drivers/staging/winbond/Makefile b/drivers/staging/winbond/Makefile
+new file mode 100644
+index 0000000..29c98bf
+--- /dev/null
++++ b/drivers/staging/winbond/Makefile
+@@ -0,0 +1,18 @@
++ DRIVER_DIR=./linux
++
++w35und-objs := $(DRIVER_DIR)/wbusb.o $(DRIVER_DIR)/wb35reg.o $(DRIVER_DIR)/wb35rx.o $(DRIVER_DIR)/wb35tx.o \
++ mds.o \
++ mlmetxrx.o \
++ mto.o \
++ phy_calibration.o \
++ reg.o \
++ rxisr.o \
++ sme_api.o \
++ wbhal.o \
++ wblinux.o \
++
++
++obj-$(CONFIG_W35UND) += w35und.o
++
++
++
+diff --git a/drivers/staging/winbond/README b/drivers/staging/winbond/README
+new file mode 100644
+index 0000000..707b6b3
+--- /dev/null
++++ b/drivers/staging/winbond/README
+@@ -0,0 +1,10 @@
++TODO:
++ - sparse cleanups
++ - checkpatch cleanups
++ - kerneldoc cleanups
++ - remove typedefs
++ - remove unused ioctls
++ - use cfg80211 for regulatory stuff
++
++Please send patches to Greg Kroah-Hartman <greg@kroah.com> and
++Pavel Machek <pavel@suse.cz>
+diff --git a/drivers/staging/winbond/adapter.h b/drivers/staging/winbond/adapter.h
+new file mode 100644
+index 0000000..609701d
+--- /dev/null
++++ b/drivers/staging/winbond/adapter.h
+@@ -0,0 +1,23 @@
++//
++// ADAPTER.H -
++// Windows NDIS global variable 'Adapter' typedef
++//
++#define MAX_ANSI_STRING 40
++typedef struct WB32_ADAPTER
++{
++ u32 AdapterIndex; // 20060703.4 Add for using pAdapterContext global Adapter point
++
++ WB_LOCALDESCRIPT sLocalPara; // Myself connected parameters
++ PWB_BSSDESCRIPTION asBSSDescriptElement;
++
++ MLME_FRAME sMlmeFrame; // connect to peerSTA parameters
++
++ MTO_PARAMETERS sMtoPara; // MTO_struct ...
++ hw_data_t sHwData; //For HAL
++ MDS Mds;
++
++ WBLINUX WbLinux;
++ struct iw_statistics iw_stats;
++
++ u8 LinkName[MAX_ANSI_STRING];
++} WB32_ADAPTER, ADAPTER, *PWB32_ADAPTER, *PADAPTER;
+diff --git a/drivers/staging/winbond/bss_f.h b/drivers/staging/winbond/bss_f.h
+new file mode 100644
+index 0000000..c957bc9
+--- /dev/null
++++ b/drivers/staging/winbond/bss_f.h
+@@ -0,0 +1,59 @@
++//
++// BSS descriptor DataBase management global function
++//
++
++void vBSSdescriptionInit(PWB32_ADAPTER Adapter);
++void vBSSfoundList(PWB32_ADAPTER Adapter);
++u8 boChanFilter(PWB32_ADAPTER Adapter, u8 ChanNo);
++u16 wBSSallocateEntry(PWB32_ADAPTER Adapter);
++u16 wBSSGetEntry(PWB32_ADAPTER Adapter);
++void vSimpleHouseKeeping(PWB32_ADAPTER Adapter);
++u16 wBSShouseKeeping(PWB32_ADAPTER Adapter);
++void ClearBSSdescpt(PWB32_ADAPTER Adapter, u16 i);
++u16 wBSSfindBssID(PWB32_ADAPTER Adapter, u8 *pbBssid);
++u16 wBSSfindDedicateCandidate(PWB32_ADAPTER Adapter, struct SSID_Element *psSsid, u8 *pbBssid);
++u16 wBSSfindMACaddr(PWB32_ADAPTER Adapter, u8 *pbMacAddr);
++u16 wBSSsearchMACaddr(PWB32_ADAPTER Adapter, u8 *pbMacAddr, u8 band);
++u16 wBSSaddScanData(PWB32_ADAPTER, u16, psRXDATA);
++u16 wBSSUpdateScanData(PWB32_ADAPTER Adapter, u16 wBssIdx, psRXDATA psRcvData);
++u16 wBSScreateIBSSdata(PWB32_ADAPTER Adapter, PWB_BSSDESCRIPTION psDesData);
++void DesiredRate2BSSdescriptor(PWB32_ADAPTER Adapter, PWB_BSSDESCRIPTION psDesData,
++ u8 *pBasicRateSet, u8 BasicRateCount,
++ u8 *pOperationRateSet, u8 OperationRateCount);
++void DesiredRate2InfoElement(PWB32_ADAPTER Adapter, u8 *addr, u16 *iFildOffset,
++ u8 *pBasicRateSet, u8 BasicRateCount,
++ u8 *pOperationRateSet, u8 OperationRateCount);
++void BSSAddIBSSdata(PWB32_ADAPTER Adapter, PWB_BSSDESCRIPTION psDesData);
++unsigned char boCmpMacAddr( PUCHAR, PUCHAR );
++unsigned char boCmpSSID(struct SSID_Element *psSSID1, struct SSID_Element *psSSID2);
++u16 wBSSfindSSID(PWB32_ADAPTER Adapter, struct SSID_Element *psSsid);
++u16 wRoamingQuery(PWB32_ADAPTER Adapter);
++void vRateToBitmap(PWB32_ADAPTER Adapter, u16 index);
++u8 bRateToBitmapIndex(PWB32_ADAPTER Adapter, u8 bRate);
++u8 bBitmapToRate(u8 i);
++unsigned char boIsERPsta(PWB32_ADAPTER Adapter, u16 i);
++unsigned char boCheckConnect(PWB32_ADAPTER Adapter);
++unsigned char boCheckSignal(PWB32_ADAPTER Adapter);
++void AddIBSSIe(PWB32_ADAPTER Adapter,PWB_BSSDESCRIPTION psDesData );//added by ws for WPA_None06/01/04
++void BssScanUpToDate(PWB32_ADAPTER Adapter);
++void BssUpToDate(PWB32_ADAPTER Adapter);
++void RateSort(u8 *RateArray, u8 num, u8 mode);
++void RateReSortForSRate(PWB32_ADAPTER Adapter, u8 *RateArray, u8 num);
++void Assemble_IE(PWB32_ADAPTER Adapter, u16 wBssIdx);
++void SetMaxTxRate(PWB32_ADAPTER Adapter);
++
++void CreateWpaIE(PWB32_ADAPTER Adapter, u16* iFildOffset, PUCHAR msg, struct Management_Frame* msgHeader,
++ struct Association_Request_Frame_Body* msgBody, u16 iMSindex); //added by WS 05/14/05
++
++#ifdef _WPA2_
++void CreateRsnIE(PWB32_ADAPTER Adapter, u16* iFildOffset, PUCHAR msg, struct Management_Frame* msgHeader,
++ struct Association_Request_Frame_Body* msgBody, u16 iMSindex);//added by WS 05/14/05
++
++u16 SearchPmkid(PWB32_ADAPTER Adapter, struct Management_Frame* msgHeader,
++ struct PMKID_Information_Element * AssoReq_PMKID );
++#endif
++
++
++
++
++
+diff --git a/drivers/staging/winbond/bssdscpt.h b/drivers/staging/winbond/bssdscpt.h
+new file mode 100644
+index 0000000..97150a2
+--- /dev/null
++++ b/drivers/staging/winbond/bssdscpt.h
+@@ -0,0 +1,156 @@
++//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++// bssdscpt.c
++// BSS descriptor data base
++// history :
++//
++// Description:
++// BSS descriptor data base will store the information of the stations at the
++// surrounding environment. The first entry( psBSS(0) ) will not be used and the
++// second one( psBSS(1) ) will be used for the broadcast address.
++//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++
++//#define MAX_ACC_RSSI_COUNT 10
++#define MAX_ACC_RSSI_COUNT 6
++
++///////////////////////////////////////////////////////////////////////////
++//
++// BSS Description set Element , to store scan received Beacon information
++//
++// Our's differs slightly from the specs. The specify a PHY_Parameter_Set.
++// Since we're only doing a DS design right now, we just have a DS structure.
++//////////////////////////////////////////////////////////////////////////////
++typedef struct BSSDescriptionElement
++{
++ u32 SlotValid;
++ u32 PowerSaveMode;
++ RXLAYER1 RxLayer1;
++
++ u8 abPeerAddress[ MAC_ADDR_LENGTH + 2 ]; // peer MAC Address associated with this session. 6-OCTET value
++ u32 dwBgScanStamp; // BgScan Sequence Counter stamp, record psROAM->dwScanCounter.
++
++ u16 Beacon_Period;
++ u16 wATIM_Window;
++
++ u8 abBssID[ MAC_ADDR_LENGTH + 2 ]; // 6B
++
++ u8 bBssType;
++ u8 DTIM_Period; // 1 octet usually from TIM element, if present
++ u8 boInTimerHandler;
++ u8 boERP; // analysis ERP or (extended) supported rate element
++
++ u8 Timestamp[8];
++ u8 BasicRate[32];
++ u8 OperationalRate[32];
++ u32 dwBasicRateBitmap; //bit map, retrieve from SupportedRateSet
++ u32 dwOperationalRateBitmap; //bit map, retrieve from SupportedRateSet and
++ // ExtendedSupportedRateSet
++ // For RSSI calculating
++ u32 HalRssi[MAX_ACC_RSSI_COUNT]; // Encode. It must use MACRO of HAL to get the LNA and AGC data
++ u32 HalRssiIndex;
++
++ ////From beacon/probe response
++ struct SSID_Element SSID; // 34B
++ u8 reserved_1[ 2 ];
++
++ struct Capability_Information_Element CapabilityInformation; // 2B
++ u8 reserved_2[ 2 ];
++
++ struct CF_Parameter_Set_Element CF_Parameter_Set; // 8B
++ struct IBSS_Parameter_Set_Element IBSS_Parameter_Set; // 4B
++ struct TIM_Element TIM_Element_Set; // 256B
++
++ struct DS_Parameter_Set_Element DS_Parameter_Set; // 3B
++ u8 reserved_3;
++
++ struct ERP_Information_Element ERP_Information_Set; // 3B
++ u8 reserved_4;
++
++ struct Supported_Rates_Element SupportedRateSet; // 10B
++ u8 reserved_5[2];
++
++ struct Extended_Supported_Rates_Element ExtendedSupportedRateSet; // 257B
++ u8 reserved_6[3];
++
++ u8 band;
++ u8 reserved_7[3];
++
++ // for MLME module
++ u16 wState; // the current state of the system
++ u16 wIndex; // THIS BSS element entry index
++
++ void* psAdapter; // pointer to THIS Adapter
++ OS_TIMER nTimer; // MLME timer
++
++ // Authentication
++ u16 wAuthAlgo; // peer MAC MLME use Auth algorithm, default OPEN_AUTH
++ u16 wAuthSeqNum; // current local MAC sendout AuthReq sequence number
++
++ u8 auth_challengeText[128];
++
++ ////For XP:
++ u32 ies_len; // information element length
++ u8 ies[256]; // information element
++
++ ////For WPA
++ u8 RsnIe_Type[2]; //added by ws for distinguish WPA and WPA2 05/14/04
++ u8 RsnIe_len;
++ u8 Rsn_Num;
++
++ // to record the rsn cipher suites,addded by ws 09/05/04
++ SUITE_SELECTOR group_cipher; // 4B
++ SUITE_SELECTOR pairwise_key_cipher_suites[WLAN_MAX_PAIRWISE_CIPHER_SUITE_COUNT];
++ SUITE_SELECTOR auth_key_mgt_suites[WLAN_MAX_AUTH_KEY_MGT_SUITE_LIST_COUNT];
++
++ u16 pairwise_key_cipher_suite_count;
++ u16 auth_key_mgt_suite_count;
++
++ u8 pairwise_key_cipher_suite_selected;
++ u8 auth_key_mgt_suite_selected;
++ u8 reserved_8[2];
++
++ struct RSN_Capability_Element rsn_capabilities; // 2B
++ u8 reserved_9[2];
++
++ //to record the rsn cipher suites for WPA2
++ #ifdef _WPA2_
++ u32 pre_auth; //added by WS for distinguish for 05/04/04
++ SUITE_SELECTOR wpa2_group_cipher; // 4B
++ SUITE_SELECTOR wpa2_pairwise_key_cipher_suites[WLAN_MAX_PAIRWISE_CIPHER_SUITE_COUNT];
++ SUITE_SELECTOR wpa2_auth_key_mgt_suites[WLAN_MAX_AUTH_KEY_MGT_SUITE_LIST_COUNT];
++
++ u16 wpa2_pairwise_key_cipher_suite_count;
++ u16 wpa2_auth_key_mgt_suite_count;
++
++ u8 wpa2_pairwise_key_cipher_suite_selected;
++ u8 wpa2_auth_key_mgt_suite_selected;
++ u8 reserved_10[2];
++
++ struct RSN_Capability_Element wpa2_rsn_capabilities; // 2B
++ u8 reserved_11[2];
++ #endif //endif _WPA2_
++
++ //For Replay protection
++// u8 PairwiseTSC[6];
++// u8 GroupTSC[6];
++
++ ////For up-to-date
++ u32 ScanTimeStamp; //for the decision whether the station/AP(may exist at
++ //different channels) has left. It must be detected by
++ //scanning. Local device may connected or disconnected.
++ u32 BssTimeStamp; //Only for the decision whether the station/AP(exist in
++ //the same channel, and no scanning) if local device has
++ //connected successfully.
++
++ // 20061108 Add for storing WPS_IE. [E id][Length][OUI][Data]
++ u8 WPS_IE_Data[MAX_IE_APPEND_SIZE];
++ u16 WPS_IE_length;
++ u16 WPS_IE_length_tmp; // For verify there is an WPS_IE in Beacon or probe response
++
++} WB_BSSDESCRIPTION, *PWB_BSSDESCRIPTION;
++
++#define wBSSConnectedSTA(Adapter) \
++ ((u16)(Adapter)->sLocalPara.wConnectedSTAindex)
++
++#define psBSS(i) (&(Adapter->asBSSDescriptElement[(i)]))
++
++
+diff --git a/drivers/staging/winbond/ds_tkip.h b/drivers/staging/winbond/ds_tkip.h
+new file mode 100644
+index 0000000..29e5055
+--- /dev/null
++++ b/drivers/staging/winbond/ds_tkip.h
+@@ -0,0 +1,33 @@
++// Rotation functions on 32 bit values
++#define ROL32( A, n ) \
++ ( ((A) << (n)) | ( ((A)>>(32-(n))) & ( (1UL << (n)) - 1 ) ) )
++
++#define ROR32( A, n ) ROL32( (A), 32-(n) )
++
++
++typedef struct tkip
++{
++ u32 K0, K1; // Key
++ union
++ {
++ struct // Current state
++ {
++ u32 L;
++ u32 R;
++ };
++ u8 LR[8];
++ };
++ union
++ {
++ u32 M; // Message accumulator (single word)
++ u8 Mb[4];
++ };
++ s32 bytes_in_M; // # bytes in M
++} tkip_t;
++
++//void _append_data( PUCHAR pData, u16 size, tkip_t *p );
++void Mds_MicGet( void* Adapter, void* pRxLayer1, PUCHAR pKey, PUCHAR pMic );
++void Mds_MicFill( void* Adapter, void* pDes, PUCHAR XmitBufAddress );
++
++
++
+diff --git a/drivers/staging/winbond/gl_80211.h b/drivers/staging/winbond/gl_80211.h
+new file mode 100644
+index 0000000..1806d81
+--- /dev/null
++++ b/drivers/staging/winbond/gl_80211.h
+@@ -0,0 +1,125 @@
++
++#ifndef __GL_80211_H__
++#define __GL_80211_H__
++
++/****************** CONSTANT AND MACRO SECTION ******************************/
++
++/* BSS Type */
++enum {
++ WLAN_BSSTYPE_INFRASTRUCTURE = 0,
++ WLAN_BSSTYPE_INDEPENDENT,
++ WLAN_BSSTYPE_ANY_BSS,
++};
++
++
++
++/* Preamble_Type, see <SFS-802.11G-MIB-203> */
++typedef enum preamble_type {
++ WLAN_PREAMBLE_TYPE_SHORT,
++ WLAN_PREAMBLE_TYPE_LONG,
++} preamble_type_e;
++
++
++/* Slot_Time_Type, see <SFS-802.11G-MIB-208> */
++typedef enum slot_time_type {
++ WLAN_SLOT_TIME_TYPE_LONG,
++ WLAN_SLOT_TIME_TYPE_SHORT,
++} slot_time_type_e;
++
++/*--------------------------------------------------------------------------*/
++/* Encryption Mode */
++typedef enum {
++ WEP_DISABLE = 0,
++ WEP_64,
++ WEP_128,
++
++ ENCRYPT_DISABLE,
++ ENCRYPT_WEP,
++ ENCRYPT_WEP_NOKEY,
++ ENCRYPT_TKIP,
++ ENCRYPT_TKIP_NOKEY,
++ ENCRYPT_CCMP,
++ ENCRYPT_CCMP_NOKEY,
++} encryption_mode_e;
++
++typedef enum _WLAN_RADIO {
++ WLAN_RADIO_ON,
++ WLAN_RADIO_OFF,
++ WLAN_RADIO_MAX, // not a real type, defined as an upper bound
++} WLAN_RADIO;
++
++typedef struct _WLAN_RADIO_STATUS {
++ WLAN_RADIO HWStatus;
++ WLAN_RADIO SWStatus;
++} WLAN_RADIO_STATUS;
++
++//----------------------------------------------------------------------------
++// 20041021 1.1.81.1000 ybjiang
++// add for radio notification
++typedef
++void (*RADIO_NOTIFICATION_HANDLER)(
++ void *Data,
++ void *RadioStatusBuffer,
++ u32 RadioStatusBufferLen
++ );
++
++typedef struct _WLAN_RADIO_NOTIFICATION
++{
++ RADIO_NOTIFICATION_HANDLER RadioChangeHandler;
++ void *Data;
++} WLAN_RADIO_NOTIFICATION;
++
++//----------------------------------------------------------------------------
++// 20041102 1.1.91.1000 ybjiang
++// add for OID_802_11_CUST_REGION_CAPABILITIES and OID_802_11_OID_REGION
++typedef enum _WLAN_REGION_CODE
++{
++ WLAN_REGION_UNKNOWN,
++ WLAN_REGION_EUROPE,
++ WLAN_REGION_JAPAN,
++ WLAN_REGION_USA,
++ WLAN_REGION_FRANCE,
++ WLAN_REGION_SPAIN,
++ WLAN_REGION_ISRAEL,
++ WLAN_REGION_MAX, // not a real type, defined as an upper bound
++} WLAN_REGION_CODE;
++
++#define REGION_NAME_MAX_LENGTH 256
++
++typedef struct _WLAN_REGION_CHANNELS
++{
++ u32 Length;
++ u32 NameLength;
++ u8 Name[REGION_NAME_MAX_LENGTH];
++ WLAN_REGION_CODE Code;
++ u32 Frequency[1];
++} WLAN_REGION_CHANNELS;
++
++typedef struct _WLAN_REGION_CAPABILITIES
++{
++ u32 NumberOfItems;
++ WLAN_REGION_CHANNELS Region[1];
++} WLAN_REGION_CAPABILITIES;
++
++typedef struct _region_name_map {
++ WLAN_REGION_CODE region;
++ u8 *name;
++ u32 *channels;
++} region_name_map;
++
++/*--------------------------------------------------------------------------*/
++#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
++#define MACSTR "%02X:%02X:%02X:%02X:%02X:%02X"
++
++// TODO: 0627 kevin
++#define MIC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5], (a)[6], (a)[7]
++#define MICSTR "%02X %02X %02X %02X %02X %02X %02X %02X"
++
++#define MICKEY2STR(a) MIC2STR(a)
++#define MICKEYSTR MICSTR
++
++
++#endif /* __GL_80211_H__ */
++/*** end of file ***/
++
++
+diff --git a/drivers/staging/winbond/ioctls.h b/drivers/staging/winbond/ioctls.h
+new file mode 100644
+index 0000000..e8b35dc
+--- /dev/null
++++ b/drivers/staging/winbond/ioctls.h
+@@ -0,0 +1,678 @@
++//============================================================================
++// IOCTLS.H -
++//
++// Description:
++// Define the IOCTL codes.
++//
++// Revision history:
++// --------------------------------------------------------------------------
++//
++// Copyright (c) 2002-2004 Winbond Electronics Corp. All rights reserved.
++//=============================================================================
++
++#ifndef _IOCTLS_H
++#define _IOCTLS_H
++
++// PD43 Keep it - Used with the Win33 application
++// #include <winioctl.h>
++
++//========================================================
++// 20040108 ADD the follow for test
++//========================================================
++#define INFORMATION_LENGTH sizeof(unsigned int)
++
++#define WB32_IOCTL_INDEX 0x0900 //קďĽHŤKŹŰŽe//
++
++#define Wb32_RegisterRead CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB32_IOCTL_INDEX + 0, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++#define Wb32_RegisterWrite CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB32_IOCTL_INDEX + 1, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++#define Wb32_SendPacket CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB32_IOCTL_INDEX + 2, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++#define Wb32_QuerySendResult CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB32_IOCTL_INDEX + 3, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++#define Wb32_SetFragmentThreshold CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB32_IOCTL_INDEX + 4, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++#define Wb32_SetLinkStatus CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB32_IOCTL_INDEX + 5, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++#define Wb32_SetBulkIn CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB32_IOCTL_INDEX + 6, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++#define Wb32_LoopbackTest CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB32_IOCTL_INDEX + 7, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++#define Wb35_EEPromRead CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB32_IOCTL_INDEX + 8, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++#define Wb35_EEPromWrite CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB32_IOCTL_INDEX + 9, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++#define Wb35_FlashReadData CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB32_IOCTL_INDEX + 10, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++#define Wb35_FlashWrite CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB32_IOCTL_INDEX + 11, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++#define Wb35_FlashWriteBurst CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB32_IOCTL_INDEX + 12, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++#define Wb35_TxBurstStart CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB32_IOCTL_INDEX + 13, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++#define Wb35_TxBurstStop CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB32_IOCTL_INDEX + 14, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++#define Wb35_TxBurstStatus CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB32_IOCTL_INDEX + 15, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++// For IOCTL interface
++//================================================
++#define LINKNAME_STRING "\\DosDevices\\W35UND"
++#define NTDEVICE_STRING "\\Device\\W35UND"
++#define APPLICATION_LINK "\\\\.\\W35UND"
++
++#define WB_IOCTL_INDEX 0x0800
++#define WB_IOCTL_TS_INDEX WB_IOCTL_INDEX + 60
++#define WB_IOCTL_DUT_INDEX WB_IOCTL_TS_INDEX + 40
++
++//=============================================================================
++// IOCTLS defined for DUT (Device Under Test)
++
++// IOCTL_WB_802_11_DUT_MAC_ADDRESS
++// Query: Return the dot11StationID
++// Set : Set the dot11StationID. Demo only.
++//
++#define IOCTL_WB_802_11_DUT_MAC_ADDRESS CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_DUT_INDEX + 1, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++// IOCTL_WB_802_11_DUT_BSS_DESCRIPTION
++// Query: Return the info. of the current connected BSS.
++// Set : None.
++//
++#define IOCTL_WB_802_11_DUT_BSS_DESCRIPTION CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_DUT_INDEX + 2, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++// IOCTL_WB_802_11_DUT_TX_RATE
++// Query: Return the current transmission rate.
++// Set : Set the transmission rate of the Tx packets.
++//
++#define IOCTL_WB_802_11_DUT_TX_RATE CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_DUT_INDEX + 3, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++// IOCTL_WB_802_11_DUT_CURRENT_STA_STATE
++// Query: Return the current STA state. (WB_STASTATE type)
++// Set : None.
++//
++#define IOCTL_WB_802_11_DUT_CURRENT_STA_STATE CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_DUT_INDEX + 4, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++/////////// 10/31/02' Added /////////////////////
++
++// IOCTL_WB_802_11_DUT_START_IBSS_REQUEST
++// Query: None.
++// Set : Start a new IBSS
++//
++#define IOCTL_WB_802_11_DUT_START_IBSS_REQUEST CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_DUT_INDEX + 5, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++// IOCTL_WB_802_11_DUT_JOIN_REQUEST
++// Query: None.
++// Set : Synchronize with the selected BSS
++//
++#define IOCTL_WB_802_11_DUT_JOIN_REQUEST CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_DUT_INDEX + 6, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++// IOCTL_WB_802_11_DUT_AUTHEN_REQUEST
++// Query: None.
++// Set : Authenticate with the BSS
++//
++#define IOCTL_WB_802_11_DUT_AUTHEN_REQUEST CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_DUT_INDEX + 7, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++// IOCTL_WB_802_11_DUT_DEAUTHEN_REQUEST
++// Query: None.
++// Set : DeAuthenticate withe the BSS
++//
++#define IOCTL_WB_802_11_DUT_DEAUTHEN_REQUEST CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_DUT_INDEX + 8, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++// IOCTL_WB_802_11_DUT_ASSOC_REQUEST
++// Query: None.
++// Set : Associate withe the BSS
++//
++#define IOCTL_WB_802_11_DUT_ASSOC_REQUEST CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_DUT_INDEX + 9, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++// IOCTL_WB_802_11_DUT_REASSOC_REQUEST
++// Query: None.
++// Set : ReAssociate withe the BSS
++//
++#define IOCTL_WB_802_11_DUT_REASSOC_REQUEST CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_DUT_INDEX + 10, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++
++// IOCTL_WB_802_11_DUT_DISASSOC_REQUEST
++// Query: None.
++// Set : DisAssociate withe the BSS
++//
++#define IOCTL_WB_802_11_DUT_DISASSOC_REQUEST CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_DUT_INDEX + 11, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++// IOCTL_WB_802_11_DUT_FRAG_THRESHOLD
++// Query: Return the dot11FragmentThreshold
++// Set : Set the dot11FragmentThreshold
++//
++#define IOCTL_WB_802_11_DUT_FRAG_THRESHOLD CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_DUT_INDEX + 12, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++// IOCTL_WB_802_11_DUT_RTS_THRESHOLD
++// Query: Return the dot11RTSThreshold
++// Set : Set the dot11RTSThresold
++//
++#define IOCTL_WB_802_11_DUT_RTS_THRESHOLD CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_DUT_INDEX + 13, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++// IOCTL_WB_802_11_DUT_WEP_KEYMODE
++// Query: Get the WEP key mode.
++// Set : Set the WEP key mode: disable/64 bits/128 bits
++//
++#define IOCTL_WB_802_11_DUT_WEP_KEYMODE CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_DUT_INDEX + 14, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++// IOCTL_WB_802_11_DUT_WEP_KEYVALUE
++// Query: None.
++// Set : fill in the WEP key value
++//
++#define IOCTL_WB_802_11_DUT_WEP_KEYVALUE CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_DUT_INDEX + 15, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++// IOCTL_WB_802_11_DUT_RESET
++// Query: None.
++// Set : Reset S/W and H/W
++//
++#define IOCTL_WB_802_11_DUT_RESET CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_DUT_INDEX + 16, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++// IOCTL_WB_802_11_DUT_POWER_SAVE
++// Query: None.
++// Set : Set Power Save Mode
++//
++#define IOCTL_WB_802_11_DUT_POWER_SAVE CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_DUT_INDEX + 17, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++// IOCTL_WB_802_11_DUT_BSSID_LIST_SCAN
++// Query: None.
++// Set :
++//
++#define IOCTL_WB_802_11_DUT_BSSID_LIST_SCAN CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_DUT_INDEX + 18, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++// IOCTL_WB_802_11_DUT_BSSID_LIST
++// Query: Return the BSS info of BSSs in the last scanning process
++// Set : None.
++//
++#define IOCTL_WB_802_11_DUT_BSSID_LIST CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_DUT_INDEX + 19, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++// IOCTL_WB_802_11_DUT_STATISTICS
++// Query: Return the statistics of Tx/Rx.
++// Set : None.
++//
++#define IOCTL_WB_802_11_DUT_STATISTICS CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_DUT_INDEX + 20, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++// IOCTL_WB_802_11_DUT_ACCEPT_BEACON
++// Query: Return the current mode to accept beacon or not.
++// Set : Enable or disable allowing the HW-MAC to pass the beacon to the SW-MAC
++// Arguments: unsigned char
++//
++#define IOCTL_WB_802_11_DUT_ACCEPT_BEACON CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_DUT_INDEX + 21, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++// IOCTL_WB_802_11_DUT_ROAMING
++// Query: Return the roaming function status
++// Set : Enable/Disable the roaming function.
++#define IOCTL_WB_802_11_DUT_ROAMING CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_DUT_INDEX + 22, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++// IOCTL_WB_802_11_DUT_DTO
++// Query: Return the DTO(Data Throughput Optimization)
++// function status (TRUE or FALSE)
++// Set : Enable/Disable the DTO function.
++//
++#define IOCTL_WB_802_11_DUT_DTO CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_DUT_INDEX + 23, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++// IOCTL_WB_802_11_DUT_ANTENNA_DIVERSITY
++// Query: Return the antenna diversity status. (TRUE/ON or FALSE/OFF)
++// Set : Enable/Disable the antenna diversity.
++//
++#define IOCTL_WB_802_11_DUT_ANTENNA_DIVERSITY CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_DUT_INDEX + 24, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++//-------------- new added for a+b+g ---------------------
++// IOCTL_WB_802_11_DUT_MAC_OPERATION_MODE
++// Query: Return the MAC operation mode. (MODE_802_11_BG, MODE_802_11_A,
++// MODE_802_11_ABG, MODE_802_11_BG_IBSS)
++// Set : Set the MAC operation mode.
++//
++#define IOCTL_WB_802_11_DUT_MAC_OPERATION_MODE CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_DUT_INDEX + 25, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++// IOCTL_WB_802_11_DUT_TX_RATE_REDEFINED
++// Query: Return the current tx rate which follows the definition in spec. (for
++// example, 5.5M => 0x0b)
++// Set : None
++//
++#define IOCTL_WB_802_11_DUT_TX_RATE_REDEFINED CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_DUT_INDEX + 26, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++// IOCTL_WB_802_11_DUT_PREAMBLE_MODE
++// Query: Return the preamble mode. (auto or long)
++// Set : Set the preamble mode.
++//
++#define IOCTL_WB_802_11_DUT_PREAMBLE_MODE CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_DUT_INDEX + 27, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++// IOCTL_WB_802_11_DUT_SLOT_TIME_MODE
++// Query: Return the slot time mode. (auto or long)
++// Set : Set the slot time mode.
++//
++#define IOCTL_WB_802_11_DUT_SLOT_TIME_MODE CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_DUT_INDEX + 28, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++//------------------------------------------------------------------
++
++// IOCTL_WB_802_11_DUT_ADVANCE_STATUS
++// Query:
++// Set : NONE
++//
++#define IOCTL_WB_802_11_DUT_ADVANCE_STATUS CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_DUT_INDEX + 29, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++// IOCTL_WB_802_11_DUT_TX_RATE_MODE
++// Query: Return the tx rate mode. (RATE_AUTO, RATE_1M, .., RATE_54M, RATE_MAX)
++// Set : Set the tx rate mode. (RATE_AUTO, RATE_1M, .., RATE_54M, RATE_MAX)
++//
++#define IOCTL_WB_802_11_DUT_TX_RATE_MODE CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_DUT_INDEX + 30, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++// IOCTL_WB_802_11_DUT_DTO_PARA
++// Query: Return the DTO parameters
++// Set : Set the DTO parameters
++//
++#define IOCTL_WB_802_11_DUT_DTO_PARA CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_DUT_INDEX + 31, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++// IOCTL_WB_802_11_DUT_EVENT_LOG
++// Query: Return event log
++// Set : Reset event log
++//
++#define IOCTL_WB_802_11_DUT_EVENT_LOG CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_DUT_INDEX + 32, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++// IOCTL_WB_802_11_DUT_CWMIN
++// Query: NONE(It will be obtained by IOCTL_WB_802_11_DUT_ADVANCE_STATUS)
++// Set : Set CWMin value
++//
++#define IOCTL_WB_802_11_DUT_CWMIN CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_DUT_INDEX + 33, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++// IOCTL_WB_802_11_DUT_CWMAX
++// Query: NONE(It will be obtained by IOCTL_WB_802_11_DUT_ADVANCE_STATUS)
++// Set : Set CWMax value
++//
++#define IOCTL_WB_802_11_DUT_CWMAX CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_DUT_INDEX + 34, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++
++//==========================================================
++// IOCTLs for Testing
++
++// IOCTL_WB_802_11_TS_SET_CXX_REG
++// Query: None
++// Set : Write the value to one of Cxx register.
++//
++#define IOCTL_WB_802_11_TS_SET_CXX_REG CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_TS_INDEX + 0, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++// IOCTL_WB_802_11_TS_GET_CXX_REG
++// Query: Return the value of the Cxx register.
++// Set : Write the reg no. (0x00, 0x04, 0x08 etc)
++//
++#define IOCTL_WB_802_11_TS_GET_CXX_REG CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_TS_INDEX + 1, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++// IOCTL_WB_802_11_TS_SET_DXX_REG
++// Query: None
++// Set : Write the value to one of Dxx register.
++//
++#define IOCTL_WB_802_11_TS_SET_DXX_REG CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_TS_INDEX + 2, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++// IOCTL_WB_802_11_TS_GET_DXX_REG
++// Query: Return the value of the Dxx register.
++// Set : Write the reg no. (0x00, 0x04, 0x08 etc)
++//
++#define IOCTL_WB_802_11_TS_GET_DXX_REG CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_TS_INDEX + 3, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++//============================================================
++// [TS]
++
++#define IOCTL_WB_802_11_TS_TX_RATE CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_TS_INDEX + 4, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++#define IOCTL_WB_802_11_TS_CURRENT_CHANNEL CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_TS_INDEX + 5, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++#define IOCTL_WB_802_11_TS_ENABLE_SEQNO CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_TS_INDEX + 6, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++#define IOCTL_WB_802_11_TS_ENALBE_ACKEDPACKET CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_TS_INDEX + 7, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++#define IOCTL_WB_802_11_TS_INHIBIT_CRC CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_TS_INDEX + 8, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++#define IOCTL_WB_802_11_TS_RESET_RCV_COUNTER CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_TS_INDEX + 9, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++#define IOCTL_WB_802_11_TS_SET_TX_TRIGGER CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_TS_INDEX + 10, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++#define IOCTL_WB_802_11_TS_FAILED_TX_COUNT CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_TS_INDEX + 11, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++// [TS1]
++#define IOCTL_WB_802_11_TS_TX_POWER CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_TS_INDEX + 12, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++#define IOCTL_WB_802_11_TS_MODE_ENABLE CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_TS_INDEX + 13, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++#define IOCTL_WB_802_11_TS_MODE_DISABLE CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_TS_INDEX + 14, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++#define IOCTL_WB_802_11_TS_ANTENNA CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_TS_INDEX + 15, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++#define IOCTL_WB_802_11_TS_ADAPTER_INFO CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_TS_INDEX + 16, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++#define IOCTL_WB_802_11_TS_MAC_ADDRESS CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_TS_INDEX + 17, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++#define IOCTL_WB_802_11_TS_BSSID CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_TS_INDEX + 18, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++#define IOCTL_WB_802_11_TS_RF_PARAMETER CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_TS_INDEX + 19, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++#define IOCTL_WB_802_11_TS_FILTER CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_TS_INDEX + 20, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++#define IOCTL_WB_802_11_TS_CALIBRATION CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_TS_INDEX + 21, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++#define IOCTL_WB_802_11_TS_BSS_MODE CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_TS_INDEX + 22, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++#define IOCTL_WB_802_11_TS_SET_SSID CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_TS_INDEX + 23, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++#define IOCTL_WB_802_11_TS_IBSS_CHANNEL CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_TS_INDEX + 24, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++// set/query the slot time value(short or long slot time)
++#define IOCTL_WB_802_11_TS_SLOT_TIME CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_TS_INDEX + 25, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++#define IOCTL_WB_802_11_TS_SLOT_TIME CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_TS_INDEX + 25, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++#define IOCTL_WB_802_11_TS_RX_STATISTICS CTL_CODE( \
++ FILE_DEVICE_UNKNOWN, \
++ WB_IOCTL_TS_INDEX + 26, \
++ METHOD_BUFFERED, \
++ FILE_ANY_ACCESS)
++
++#endif // #ifndef _IOCTLS_H
++
++
+diff --git a/drivers/staging/winbond/linux/common.h b/drivers/staging/winbond/linux/common.h
+new file mode 100644
+index 0000000..6b00bad
+--- /dev/null
++++ b/drivers/staging/winbond/linux/common.h
+@@ -0,0 +1,143 @@
++//
++// common.h
++//
++// This file contains the OS dependant definition and function.
++// Every OS has this file individual.
++//
++
++#define DebugUsbdStatusInformation( _A )
++
++#ifndef COMMON_DEF
++#define COMMON_DEF
++
++#include <linux/version.h>
++#include <linux/usb.h>
++#include <linux/kernel.h> //need for kernel alert
++#include <linux/autoconf.h>
++#include <linux/sched.h>
++#include <linux/signal.h>
++#include <linux/slab.h> //memory allocate
++#include <linux/module.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/init.h>//need for init and exit modules marco
++#include <linux/ctype.h>
++#include <linux/wait.h>
++#include <linux/list.h>
++#include <linux/wireless.h>
++#include <linux/if_arp.h>
++#include <asm/uaccess.h>
++#include <net/iw_handler.h>
++#include <linux/skbuff.h>
++
++
++//#define DEBUG_ENABLED 1
++
++
++
++//===============================================================
++// Common type definition
++//===============================================================
++
++typedef u8* PUCHAR;
++typedef s8* PCHAR;
++typedef u8* PBOOLEAN;
++typedef u16* PUSHORT;
++typedef u32* PULONG;
++typedef s16* PSHORT;
++
++
++//===========================================
++#define IGNORE 2
++#define SUCCESS 1
++#define FAILURE 0
++
++
++#ifndef true
++#define true 1
++#endif
++
++#ifndef false
++#define false 0
++#endif
++
++// PD43 20021108
++#ifndef TRUE
++#define TRUE 1
++#endif
++
++#ifndef FALSE
++#define FALSE 0
++#endif
++
++#define STATUS_MEDIA_CONNECT 1
++#define STATUS_MEDIA_DISCONNECT 0
++
++#ifndef BIT
++#define BIT(x) (1 << (x))
++#endif
++
++typedef struct urb * PURB;
++
++
++
++//==================================================================================================
++// Common function definition
++//==================================================================================================
++#ifndef abs
++#define abs(_T) ((_T) < 0 ? -_T : _T)
++#endif
++#define DEBUG_ENABLED
++#define ETH_LENGTH_OF_ADDRESS 6
++#ifdef DEBUG_ENABLED
++#define WBDEBUG( _M ) printk _M
++#else
++#define WBDEBUG( _M ) 0
++#endif
++
++#define OS_DISCONNECTED 0
++#define OS_CONNECTED 1
++
++
++#define OS_EVENT_INDICATE( _A, _B, _F )
++#define OS_PMKID_STATUS_EVENT( _A )
++
++
++/* Uff, no, longs are not atomic on all architectures Linux
++ * supports. This should really use atomic_t */
++
++#define OS_ATOMIC u32
++#define OS_ATOMIC_READ( _A, _V ) _V
++#define OS_ATOMIC_INC( _A, _V ) EncapAtomicInc( _A, (void*)_V )
++#define OS_ATOMIC_DEC( _A, _V ) EncapAtomicDec( _A, (void*)_V )
++#define OS_MEMORY_CLEAR( _A, _S ) memset( (PUCHAR)_A,0,_S)
++#define OS_MEMORY_COMPARE( _A, _B, _S ) (memcmp(_A,_B,_S)? 0 : 1) // Definition is reverse with Ndis 1: the same 0: different
++
++
++#define OS_SPIN_LOCK spinlock_t
++#define OS_SPIN_LOCK_ALLOCATE( _S ) spin_lock_init( _S );
++#define OS_SPIN_LOCK_FREE( _S )
++#define OS_SPIN_LOCK_ACQUIRED( _S ) spin_lock_irq( _S )
++#define OS_SPIN_LOCK_RELEASED( _S ) spin_unlock_irq( _S );
++
++#define OS_TIMER struct timer_list
++#define OS_TIMER_INITIAL( _T, _F, _P ) \
++{ \
++ init_timer( _T ); \
++ (_T)->function = (void *)_F##_1a; \
++ (_T)->data = (unsigned long)_P; \
++}
++
++// _S : Millisecond
++// 20060420 At least 1 large than jiffies
++#define OS_TIMER_SET( _T, _S ) \
++{ \
++ (_T)->expires = jiffies + ((_S*HZ+999)/1000);\
++ add_timer( _T ); \
++}
++#define OS_TIMER_CANCEL( _T, _B ) del_timer_sync( _T )
++#define OS_TIMER_GET_SYS_TIME( _T ) (*_T=jiffies)
++
++
++#endif // COMMON_DEF
++
+diff --git a/drivers/staging/winbond/linux/sysdef.h b/drivers/staging/winbond/linux/sysdef.h
+new file mode 100644
+index 0000000..d46d63e
+--- /dev/null
++++ b/drivers/staging/winbond/linux/sysdef.h
+@@ -0,0 +1,73 @@
++
++
++//
++// Winbond WLAN System Configuration defines
++//
++
++//=====================================================================
++// Current directory is Linux
++// The definition WB_LINUX is a keyword for this OS
++//=====================================================================
++#ifndef SYS_DEF_H
++#define SYS_DEF_H
++#define WB_LINUX
++#define WB_LINUX_WPA_PSK
++
++
++//#define _IBSS_BEACON_SEQ_STICK_
++#define _USE_FALLBACK_RATE_
++//#define ANTDIV_DEFAULT_ON
++
++#define _WPA2_ // 20061122 It's needed for current Linux driver
++
++
++#ifndef _WPA_PSK_DEBUG
++#undef _WPA_PSK_DEBUG
++#endif
++
++// debug print options, mark what debug you don't need
++
++#ifdef FULL_DEBUG
++#define _PE_STATE_DUMP_
++#define _PE_TX_DUMP_
++#define _PE_RX_DUMP_
++#define _PE_OID_DUMP_
++#define _PE_DTO_DUMP_
++#define _PE_REG_DUMP_
++#define _PE_USB_INI_DUMP_
++#endif
++
++
++
++#include "common.h" // Individual file depends on OS
++
++#include "../wb35_ver.h"
++#include "../mac_structures.h"
++#include "../ds_tkip.h"
++#include "../localpara.h"
++#include "../sme_s.h"
++#include "../scan_s.h"
++#include "../mds_s.h"
++#include "../mlme_s.h"
++#include "../bssdscpt.h"
++#include "../sme_api.h"
++#include "../gl_80211.h"
++#include "../mto.h"
++#include "../wblinux_s.h"
++#include "../wbhal_s.h"
++
++
++#include "../adapter.h"
++
++#include "../mlme_mib.h"
++#include "../mds_f.h"
++#include "../bss_f.h"
++#include "../mlmetxrx_f.h"
++#include "../mto_f.h"
++#include "../wbhal_f.h"
++#include "../wblinux_f.h"
++// Kernel Timer resolution, NDIS is 10ms, 10000us
++#define MIN_TIMEOUT_VAL (10) //ms
++
++
++#endif
+diff --git a/drivers/staging/winbond/linux/wb35reg.c b/drivers/staging/winbond/linux/wb35reg.c
+new file mode 100644
+index 0000000..2c0b454
+--- /dev/null
++++ b/drivers/staging/winbond/linux/wb35reg.c
+@@ -0,0 +1,747 @@
++#include "sysdef.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, PULONG pRegisterData, u8 NumberOfData, u8 Flag)
++{
++ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
++ PURB pUrb = NULL;
++ PREG_QUEUE pRegQueue = 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(REG_QUEUE) + DataSize + sizeof(struct usb_ctrlrequest);
++ OS_MEMORY_ALLOC( (void* *)&pRegQueue, UrbSize );
++ pUrb = wb_usb_alloc_urb(0);
++ if( pUrb && pRegQueue ) {
++ pRegQueue->DIRECT = 2;// burst write register
++ pRegQueue->INDEX = RegisterNo;
++ pRegQueue->pBuffer = (PULONG)((PUCHAR)pRegQueue + sizeof(REG_QUEUE));
++ memcpy( pRegQueue->pBuffer, pRegisterData, DataSize );
++ //the function for reversing register data from little endian to big endian
++ for( i=0; i<NumberOfData ; i++ )
++ pRegQueue->pBuffer[i] = cpu_to_le32( pRegQueue->pBuffer[i] );
++
++ dr = (struct usb_ctrlrequest *)((PUCHAR)pRegQueue + sizeof(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 );
++ pRegQueue->Next = NULL;
++ pRegQueue->pUsbReq = dr;
++ pRegQueue->pUrb = pUrb;
++
++ OS_SPIN_LOCK_ACQUIRED( &pWb35Reg->EP0VM_spin_lock );
++ if (pWb35Reg->pRegFirst == NULL)
++ pWb35Reg->pRegFirst = pRegQueue;
++ else
++ pWb35Reg->pRegLast->Next = pRegQueue;
++ pWb35Reg->pRegLast = pRegQueue;
++
++ OS_SPIN_LOCK_RELEASED( &pWb35Reg->EP0VM_spin_lock );
++
++ // Start EP0VM
++ Wb35Reg_EP0VM_start(pHwData);
++
++ return TRUE;
++ } else {
++ if (pUrb)
++ usb_free_urb(pUrb);
++ if (pRegQueue)
++ kfree(pRegQueue);
++ return FALSE;
++ }
++ return FALSE;
++}
++
++void
++Wb35Reg_Update(phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue)
++{
++ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
++ switch (RegisterNo) {
++ case 0x3b0: pWb35Reg->U1B0 = RegisterValue; break;
++ case 0x3bc: pWb35Reg->U1BC_LEDConfigure = RegisterValue; break;
++ case 0x400: pWb35Reg->D00_DmaControl = RegisterValue; break;
++ case 0x800: pWb35Reg->M00_MacControl = RegisterValue; break;
++ case 0x804: pWb35Reg->M04_MulticastAddress1 = RegisterValue; break;
++ case 0x808: pWb35Reg->M08_MulticastAddress2 = RegisterValue; break;
++ case 0x824: pWb35Reg->M24_MacControl = RegisterValue; break;
++ case 0x828: pWb35Reg->M28_MacControl = RegisterValue; break;
++ case 0x82c: pWb35Reg->M2C_MacControl = RegisterValue; break;
++ case 0x838: pWb35Reg->M38_MacControl = RegisterValue; break;
++ case 0x840: pWb35Reg->M40_MacControl = RegisterValue; break;
++ case 0x844: pWb35Reg->M44_MacControl = RegisterValue; break;
++ case 0x848: pWb35Reg->M48_MacControl = RegisterValue; break;
++ case 0x84c: pWb35Reg->M4C_MacStatus = RegisterValue; break;
++ case 0x860: pWb35Reg->M60_MacControl = RegisterValue; break;
++ case 0x868: pWb35Reg->M68_MacControl = RegisterValue; break;
++ case 0x870: pWb35Reg->M70_MacControl = RegisterValue; break;
++ case 0x874: pWb35Reg->M74_MacControl = RegisterValue; break;
++ case 0x878: pWb35Reg->M78_ERPInformation = RegisterValue; break;
++ case 0x87C: pWb35Reg->M7C_MacControl = RegisterValue; break;
++ case 0x880: pWb35Reg->M80_MacControl = RegisterValue; break;
++ case 0x884: pWb35Reg->M84_MacControl = RegisterValue; break;
++ case 0x888: pWb35Reg->M88_MacControl = RegisterValue; break;
++ case 0x898: pWb35Reg->M98_MacControl = RegisterValue; break;
++ case 0x100c: pWb35Reg->BB0C = RegisterValue; break;
++ case 0x102c: pWb35Reg->BB2C = RegisterValue; break;
++ case 0x1030: pWb35Reg->BB30 = RegisterValue; break;
++ case 0x103c: pWb35Reg->BB3C = RegisterValue; break;
++ case 0x1048: pWb35Reg->BB48 = RegisterValue; break;
++ case 0x104c: pWb35Reg->BB4C = RegisterValue; break;
++ case 0x1050: pWb35Reg->BB50 = RegisterValue; break;
++ case 0x1054: pWb35Reg->BB54 = RegisterValue; break;
++ case 0x1058: pWb35Reg->BB58 = RegisterValue; break;
++ case 0x105c: pWb35Reg->BB5C = RegisterValue; break;
++ case 0x1060: pWb35Reg->BB60 = RegisterValue; break;
++ }
++}
++
++// TRUE : read command process successfully
++// FALSE : register not support
++unsigned char
++Wb35Reg_WriteSync( phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue )
++{
++ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
++ int ret = -1;
++
++ // Module shutdown
++ if (pHwData->SurpriseRemove)
++ return FALSE;
++
++ RegisterValue = cpu_to_le32(RegisterValue);
++
++ // update the register by send usb message------------------------------------
++ pWb35Reg->SyncIoPause = 1;
++
++ // 20060717.5 Wait until EP0VM stop
++ while (pWb35Reg->EP0vm_state != VM_STOP)
++ OS_SLEEP(10000);
++
++ // Sync IoCallDriver
++ pWb35Reg->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 );
++ pWb35Reg->EP0vm_state = VM_STOP;
++ pWb35Reg->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 )
++{
++ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
++ struct usb_ctrlrequest *dr;
++ PURB pUrb = NULL;
++ PREG_QUEUE pRegQueue = NULL;
++ u16 UrbSize;
++
++
++ // Module shutdown
++ if (pHwData->SurpriseRemove)
++ return FALSE;
++
++ // update the register by send urb request------------------------------------
++ UrbSize = sizeof(REG_QUEUE) + sizeof(struct usb_ctrlrequest);
++ OS_MEMORY_ALLOC( (void* *)&pRegQueue, UrbSize );
++ pUrb = wb_usb_alloc_urb(0);
++ if (pUrb && pRegQueue) {
++ pRegQueue->DIRECT = 1;// burst write register
++ pRegQueue->INDEX = RegisterNo;
++ pRegQueue->VALUE = cpu_to_le32(RegisterValue);
++ pRegQueue->RESERVED_VALID = FALSE;
++ dr = (struct usb_ctrlrequest *)((PUCHAR)pRegQueue + sizeof(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
++ pRegQueue->Next = NULL;
++ pRegQueue->pUsbReq = dr;
++ pRegQueue->pUrb = pUrb;
++
++ OS_SPIN_LOCK_ACQUIRED(&pWb35Reg->EP0VM_spin_lock );
++ if (pWb35Reg->pRegFirst == NULL)
++ pWb35Reg->pRegFirst = pRegQueue;
++ else
++ pWb35Reg->pRegLast->Next = pRegQueue;
++ pWb35Reg->pRegLast = pRegQueue;
++
++ OS_SPIN_LOCK_RELEASED( &pWb35Reg->EP0VM_spin_lock );
++
++ // Start EP0VM
++ Wb35Reg_EP0VM_start(pHwData);
++
++ return TRUE;
++ } else {
++ if (pUrb)
++ usb_free_urb(pUrb);
++ kfree(pRegQueue);
++ 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,
++ PCHAR pValue, s8 Len)
++{
++ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
++ struct usb_ctrlrequest *dr;
++ PURB pUrb = NULL;
++ PREG_QUEUE pRegQueue = NULL;
++ u16 UrbSize;
++
++ // Module shutdown
++ if (pHwData->SurpriseRemove)
++ return FALSE;
++
++ // update the register by send urb request------------------------------------
++ UrbSize = sizeof(REG_QUEUE) + sizeof(struct usb_ctrlrequest);
++ OS_MEMORY_ALLOC((void* *) &pRegQueue, UrbSize );
++ pUrb = wb_usb_alloc_urb(0);
++ if (pUrb && pRegQueue) {
++ pRegQueue->DIRECT = 1;// burst write register
++ pRegQueue->INDEX = RegisterNo;
++ pRegQueue->VALUE = cpu_to_le32(RegisterValue);
++ //NOTE : Users must guarantee the size of value will not exceed the buffer size.
++ memcpy(pRegQueue->RESERVED, pValue, Len);
++ pRegQueue->RESERVED_VALID = TRUE;
++ dr = (struct usb_ctrlrequest *)((PUCHAR)pRegQueue + sizeof(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
++ pRegQueue->Next = NULL;
++ pRegQueue->pUsbReq = dr;
++ pRegQueue->pUrb = pUrb;
++ OS_SPIN_LOCK_ACQUIRED (&pWb35Reg->EP0VM_spin_lock );
++ if( pWb35Reg->pRegFirst == NULL )
++ pWb35Reg->pRegFirst = pRegQueue;
++ else
++ pWb35Reg->pRegLast->Next = pRegQueue;
++ pWb35Reg->pRegLast = pRegQueue;
++
++ OS_SPIN_LOCK_RELEASED ( &pWb35Reg->EP0VM_spin_lock );
++
++ // Start EP0VM
++ Wb35Reg_EP0VM_start(pHwData);
++ return TRUE;
++ } else {
++ if (pUrb)
++ usb_free_urb(pUrb);
++ kfree(pRegQueue);
++ 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, PULONG pRegisterValue )
++{
++ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
++ PULONG pltmp = pRegisterValue;
++ int ret = -1;
++
++ // Module shutdown
++ if (pHwData->SurpriseRemove)
++ return FALSE;
++
++ // Read the register by send usb message------------------------------------
++
++ pWb35Reg->SyncIoPause = 1;
++
++ // 20060717.5 Wait until EP0VM stop
++ while (pWb35Reg->EP0vm_state != VM_STOP)
++ OS_SLEEP(10000);
++
++ pWb35Reg->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);
++
++ pWb35Reg->EP0vm_state = VM_STOP;
++
++ Wb35Reg_Update( pHwData, RegisterNo, *pRegisterValue );
++ pWb35Reg->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, PULONG pRegisterValue )
++{
++ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
++ struct usb_ctrlrequest * dr;
++ PURB pUrb;
++ PREG_QUEUE pRegQueue;
++ u16 UrbSize;
++
++ // Module shutdown
++ if (pHwData->SurpriseRemove)
++ return FALSE;
++
++ // update the variable by send Urb to read register ------------------------------------
++ UrbSize = sizeof(REG_QUEUE) + sizeof(struct usb_ctrlrequest);
++ OS_MEMORY_ALLOC( (void* *)&pRegQueue, UrbSize );
++ pUrb = wb_usb_alloc_urb(0);
++ if( pUrb && pRegQueue )
++ {
++ pRegQueue->DIRECT = 0;// read register
++ pRegQueue->INDEX = RegisterNo;
++ pRegQueue->pBuffer = pRegisterValue;
++ dr = (struct usb_ctrlrequest *)((PUCHAR)pRegQueue + sizeof(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
++ pRegQueue->Next = NULL;
++ pRegQueue->pUsbReq = dr;
++ pRegQueue->pUrb = pUrb;
++ OS_SPIN_LOCK_ACQUIRED ( &pWb35Reg->EP0VM_spin_lock );
++ if( pWb35Reg->pRegFirst == NULL )
++ pWb35Reg->pRegFirst = pRegQueue;
++ else
++ pWb35Reg->pRegLast->Next = pRegQueue;
++ pWb35Reg->pRegLast = pRegQueue;
++
++ OS_SPIN_LOCK_RELEASED( &pWb35Reg->EP0VM_spin_lock );
++
++ // Start EP0VM
++ Wb35Reg_EP0VM_start( pHwData );
++
++ return TRUE;
++ } else {
++ if (pUrb)
++ usb_free_urb( pUrb );
++ kfree(pRegQueue);
++ return FALSE;
++ }
++}
++
++
++void
++Wb35Reg_EP0VM_start( phw_data_t pHwData )
++{
++ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
++
++ if (OS_ATOMIC_INC( pHwData->Adapter, &pWb35Reg->RegFireCount) == 1) {
++ pWb35Reg->EP0vm_state = VM_RUNNING;
++ Wb35Reg_EP0VM(pHwData);
++ } else
++ OS_ATOMIC_DEC( pHwData->Adapter, &pWb35Reg->RegFireCount );
++}
++
++void
++Wb35Reg_EP0VM(phw_data_t pHwData )
++{
++ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
++ PURB pUrb;
++ struct usb_ctrlrequest *dr;
++ PULONG pBuffer;
++ int ret = -1;
++ PREG_QUEUE pRegQueue;
++
++
++ if (pWb35Reg->SyncIoPause)
++ goto cleanup;
++
++ if (pHwData->SurpriseRemove)
++ goto cleanup;
++
++ // Get the register data and send to USB through Irp
++ OS_SPIN_LOCK_ACQUIRED( &pWb35Reg->EP0VM_spin_lock );
++ pRegQueue = pWb35Reg->pRegFirst;
++ OS_SPIN_LOCK_RELEASED( &pWb35Reg->EP0VM_spin_lock );
++
++ if (!pRegQueue)
++ goto cleanup;
++
++ // Get an Urb, send it
++ pUrb = (PURB)pRegQueue->pUrb;
++
++ dr = pRegQueue->pUsbReq;
++ pUrb = pRegQueue->pUrb;
++ pBuffer = pRegQueue->pBuffer;
++ if (pRegQueue->DIRECT == 1) // output
++ pBuffer = &pRegQueue->VALUE;
++
++ usb_fill_control_urb( pUrb, pHwData->WbUsb.udev,
++ REG_DIRECTION(pHwData->WbUsb.udev,pRegQueue),
++ (PUCHAR)dr,pBuffer,cpu_to_le16(dr->wLength),
++ Wb35Reg_EP0VM_complete, (void*)pHwData);
++
++ pWb35Reg->EP0vm_state = VM_RUNNING;
++
++ ret = wb_usb_submit_urb( pUrb );
++
++ if (ret < 0) {
++#ifdef _PE_REG_DUMP_
++ WBDEBUG(("EP0 Irp sending error\n"));
++#endif
++ goto cleanup;
++ }
++
++ return;
++
++ cleanup:
++ pWb35Reg->EP0vm_state = VM_STOP;
++ OS_ATOMIC_DEC( pHwData->Adapter, &pWb35Reg->RegFireCount );
++}
++
++
++void
++Wb35Reg_EP0VM_complete(PURB pUrb)
++{
++ phw_data_t pHwData = (phw_data_t)pUrb->context;
++ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
++ PREG_QUEUE pRegQueue;
++
++
++ // Variable setting
++ pWb35Reg->EP0vm_state = VM_COMPLETED;
++ pWb35Reg->EP0VM_status = pUrb->status;
++
++ if (pHwData->SurpriseRemove) { // Let WbWlanHalt to handle surprise remove
++ pWb35Reg->EP0vm_state = VM_STOP;
++ OS_ATOMIC_DEC( pHwData->Adapter, &pWb35Reg->RegFireCount );
++ } else {
++ // Complete to send, remove the URB from the first
++ OS_SPIN_LOCK_ACQUIRED( &pWb35Reg->EP0VM_spin_lock );
++ pRegQueue = pWb35Reg->pRegFirst;
++ if (pRegQueue == pWb35Reg->pRegLast)
++ pWb35Reg->pRegLast = NULL;
++ pWb35Reg->pRegFirst = pWb35Reg->pRegFirst->Next;
++ OS_SPIN_LOCK_RELEASED( &pWb35Reg->EP0VM_spin_lock );
++
++ if (pWb35Reg->EP0VM_status) {
++#ifdef _PE_REG_DUMP_
++ WBDEBUG(("EP0 IoCompleteRoutine return error\n"));
++ DebugUsbdStatusInformation( pWb35Reg->EP0VM_status );
++#endif
++ pWb35Reg->EP0vm_state = VM_STOP;
++ pHwData->SurpriseRemove = 1;
++ } else {
++ // Success. Update the result
++
++ // Start the next send
++ Wb35Reg_EP0VM(pHwData);
++ }
++
++ kfree(pRegQueue);
++ }
++
++ usb_free_urb(pUrb);
++}
++
++
++void
++Wb35Reg_destroy(phw_data_t pHwData)
++{
++ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
++ PURB pUrb;
++ PREG_QUEUE pRegQueue;
++
++
++ Uxx_power_off_procedure(pHwData);
++
++ // Wait for Reg operation completed
++ do {
++ OS_SLEEP(10000); // Delay for waiting function enter 940623.1.a
++ } while (pWb35Reg->EP0vm_state != VM_STOP);
++ OS_SLEEP(10000); // Delay for waiting function enter 940623.1.b
++
++ // Release all the data in RegQueue
++ OS_SPIN_LOCK_ACQUIRED( &pWb35Reg->EP0VM_spin_lock );
++ pRegQueue = pWb35Reg->pRegFirst;
++ while (pRegQueue) {
++ if (pRegQueue == pWb35Reg->pRegLast)
++ pWb35Reg->pRegLast = NULL;
++ pWb35Reg->pRegFirst = pWb35Reg->pRegFirst->Next;
++
++ pUrb = pRegQueue->pUrb;
++ OS_SPIN_LOCK_RELEASED( &pWb35Reg->EP0VM_spin_lock );
++ if (pUrb) {
++ usb_free_urb(pUrb);
++ kfree(pRegQueue);
++ } else {
++ #ifdef _PE_REG_DUMP_
++ WBDEBUG(("EP0 queue release error\n"));
++ #endif
++ }
++ OS_SPIN_LOCK_ACQUIRED( &pWb35Reg->EP0VM_spin_lock );
++
++ pRegQueue = pWb35Reg->pRegFirst;
++ }
++ OS_SPIN_LOCK_RELEASED( &pWb35Reg->EP0VM_spin_lock );
++
++ // Free resource
++ OS_SPIN_LOCK_FREE( &pWb35Reg->EP0VM_spin_lock );
++}
++
++//====================================================================================
++// The function can be run in passive-level only.
++//====================================================================================
++unsigned char Wb35Reg_initial(phw_data_t pHwData)
++{
++ PWB35REG pWb35Reg=&pHwData->Wb35Reg;
++ u32 ltmp;
++ u32 SoftwareSet, VCO_trim, TxVga, Region_ScanInterval;
++
++ // Spin lock is acquired for read and write IRP command
++ OS_SPIN_LOCK_ALLOCATE( &pWb35Reg->EP0VM_spin_lock );
++
++ // Getting RF module type from EEPROM ------------------------------------
++ Wb35Reg_WriteSync( pHwData, 0x03b4, 0x080d0000 ); // Start EEPROM access + Read + address(0x0d)
++ Wb35Reg_ReadSync( pHwData, 0x03b4, <mp );
++
++ //Update RF module type and determine the PHY type by inf or EEPROM
++ pWb35Reg->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 (pWb35Reg->EEPROMPhyType != RF_DECIDE_BY_INF) {
++ if( (pWb35Reg->EEPROMPhyType == RF_MAXIM_2825) ||
++ (pWb35Reg->EEPROMPhyType == RF_MAXIM_2827) ||
++ (pWb35Reg->EEPROMPhyType == RF_MAXIM_2828) ||
++ (pWb35Reg->EEPROMPhyType == RF_MAXIM_2829) ||
++ (pWb35Reg->EEPROMPhyType == RF_MAXIM_V1) ||
++ (pWb35Reg->EEPROMPhyType == RF_AIROHA_2230) ||
++ (pWb35Reg->EEPROMPhyType == RF_AIROHA_2230S) ||
++ (pWb35Reg->EEPROMPhyType == RF_AIROHA_7230) ||
++ (pWb35Reg->EEPROMPhyType == RF_WB_242) ||
++ (pWb35Reg->EEPROMPhyType == RF_WB_242_1))
++ pHwData->phy_type = pWb35Reg->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;
++
++ pWb35Reg->EEPROMRegion = (u8)(Region_ScanInterval>>8); // 20060720
++ if( pWb35Reg->EEPROMRegion<1 || pWb35Reg->EEPROMRegion>6 )
++ pWb35Reg->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(PUCHAR 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 );
++ }
++}
++
++
+diff --git a/drivers/staging/winbond/linux/wb35reg_f.h b/drivers/staging/winbond/linux/wb35reg_f.h
+new file mode 100644
+index 0000000..38e2906
+--- /dev/null
++++ b/drivers/staging/winbond/linux/wb35reg_f.h
+@@ -0,0 +1,56 @@
++//====================================
++// Interface function declare
++//====================================
++unsigned char Wb35Reg_initial( phw_data_t pHwData );
++void Uxx_power_on_procedure( phw_data_t pHwData );
++void Uxx_power_off_procedure( phw_data_t pHwData );
++void Uxx_ReadEthernetAddress( phw_data_t pHwData );
++void Dxx_initial( phw_data_t pHwData );
++void Mxx_initial( phw_data_t pHwData );
++void RFSynthesizer_initial( phw_data_t pHwData );
++//void RFSynthesizer_SwitchingChannel( phw_data_t pHwData, s8 Channel );
++void RFSynthesizer_SwitchingChannel( phw_data_t pHwData, ChanInfo Channel );
++void BBProcessor_initial( phw_data_t pHwData );
++void BBProcessor_RateChanging( phw_data_t pHwData, u8 rate ); // 20060613.1
++//void RF_RateChanging( phw_data_t pHwData, u8 rate ); // 20060626.5.c Add
++u8 RFSynthesizer_SetPowerIndex( phw_data_t pHwData, u8 PowerIndex );
++u8 RFSynthesizer_SetMaxim2828_24Power( phw_data_t, u8 index );
++u8 RFSynthesizer_SetMaxim2828_50Power( phw_data_t, u8 index );
++u8 RFSynthesizer_SetMaxim2827_24Power( phw_data_t, u8 index );
++u8 RFSynthesizer_SetMaxim2827_50Power( phw_data_t, u8 index );
++u8 RFSynthesizer_SetMaxim2825Power( phw_data_t, u8 index );
++u8 RFSynthesizer_SetAiroha2230Power( phw_data_t, u8 index );
++u8 RFSynthesizer_SetAiroha7230Power( phw_data_t, u8 index );
++u8 RFSynthesizer_SetWinbond242Power( phw_data_t, u8 index );
++void GetTxVgaFromEEPROM( phw_data_t pHwData );
++void EEPROMTxVgaAdjust( phw_data_t pHwData ); // 20060619.5 Add
++
++#define RFWriteControlData( _A, _V ) Wb35Reg_Write( _A, 0x0864, _V )
++
++void Wb35Reg_destroy( phw_data_t pHwData );
++
++unsigned char Wb35Reg_Read( phw_data_t pHwData, u16 RegisterNo, PULONG pRegisterValue );
++unsigned char Wb35Reg_ReadSync( phw_data_t pHwData, u16 RegisterNo, PULONG pRegisterValue );
++unsigned char Wb35Reg_Write( phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue );
++unsigned char Wb35Reg_WriteSync( phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue );
++unsigned char Wb35Reg_WriteWithCallbackValue( phw_data_t pHwData,
++ u16 RegisterNo,
++ u32 RegisterValue,
++ PCHAR pValue,
++ s8 Len);
++unsigned char Wb35Reg_BurstWrite( phw_data_t pHwData, u16 RegisterNo, PULONG pRegisterData, u8 NumberOfData, u8 Flag );
++
++void Wb35Reg_EP0VM( phw_data_t pHwData );
++void Wb35Reg_EP0VM_start( phw_data_t pHwData );
++void Wb35Reg_EP0VM_complete( PURB pUrb );
++
++u32 BitReverse( u32 dwData, u32 DataLength);
++
++void CardGetMulticastBit( u8 Address[MAC_ADDR_LENGTH], u8 *Byte, u8 *Value );
++u32 CardComputeCrc( PUCHAR Buffer, u32 Length );
++
++void Wb35Reg_phy_calibration( phw_data_t pHwData );
++void Wb35Reg_Update( phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue );
++unsigned char adjust_TXVGA_for_iq_mag( phw_data_t pHwData );
++
++
+diff --git a/drivers/staging/winbond/linux/wb35reg_s.h b/drivers/staging/winbond/linux/wb35reg_s.h
+new file mode 100644
+index 0000000..a7595b1
+--- /dev/null
++++ b/drivers/staging/winbond/linux/wb35reg_s.h
+@@ -0,0 +1,170 @@
++//=======================================================================================
++/*
++ HAL setting function
++
++ ========================================
++ |Uxx| |Dxx| |Mxx| |BB| |RF|
++ ========================================
++ | |
++ Wb35Reg_Read Wb35Reg_Write
++
++ ----------------------------------------
++ WbUsb_CallUSBDASync supplied By WbUsb module
++*/
++//=======================================================================================
++
++#define GetBit( dwData, i) ( dwData & (0x00000001 << i))
++#define SetBit( dwData, i) ( dwData | (0x00000001 << i))
++#define ClearBit( dwData, i) ( dwData & ~(0x00000001 << i))
++
++#define IGNORE_INCREMENT 0
++#define AUTO_INCREMENT 0
++#define NO_INCREMENT 1
++#define REG_DIRECTION(_x,_y) ((_y)->DIRECT ==0 ? usb_rcvctrlpipe(_x,0) : usb_sndctrlpipe(_x,0))
++#define REG_BUF_SIZE(_x) ((_x)->bRequest== 0x04 ? cpu_to_le16((_x)->wLength) : 4)
++
++// 20060613.2 Add the follow definition
++#define BB48_DEFAULT_AL2230_11B 0x0033447c
++#define BB4C_DEFAULT_AL2230_11B 0x0A00FEFF
++#define BB48_DEFAULT_AL2230_11G 0x00332C1B
++#define BB4C_DEFAULT_AL2230_11G 0x0A00FEFF
++
++
++#define BB48_DEFAULT_WB242_11B 0x00292315 //backoff 2dB
++#define BB4C_DEFAULT_WB242_11B 0x0800FEFF //backoff 2dB
++//#define BB48_DEFAULT_WB242_11B 0x00201B11 //backoff 4dB
++//#define BB4C_DEFAULT_WB242_11B 0x0600FF00 //backoff 4dB
++#define BB48_DEFAULT_WB242_11G 0x00453B24
++#define BB4C_DEFAULT_WB242_11G 0x0E00FEFF
++
++//====================================
++// Default setting for Mxx
++//====================================
++#define DEFAULT_CWMIN 31 //(M2C) CWmin. Its value is in the range 0-31.
++#define DEFAULT_CWMAX 1023 //(M2C) CWmax. Its value is in the range 0-1023.
++#define DEFAULT_AID 1 //(M34) AID. Its value is in the range 1-2007.
++
++#ifdef _USE_FALLBACK_RATE_
++#define DEFAULT_RATE_RETRY_LIMIT 2 //(M38) as named
++#else
++#define DEFAULT_RATE_RETRY_LIMIT 7 //(M38) as named
++#endif
++
++#define DEFAULT_LONG_RETRY_LIMIT 7 //(M38) LongRetryLimit. Its value is in the range 0-15.
++#define DEFAULT_SHORT_RETRY_LIMIT 7 //(M38) ShortRetryLimit. Its value is in the range 0-15.
++#define DEFAULT_PIFST 25 //(M3C) PIFS Time. Its value is in the range 0-65535.
++#define DEFAULT_EIFST 354 //(M3C) EIFS Time. Its value is in the range 0-1048575.
++#define DEFAULT_DIFST 45 //(M3C) DIFS Time. Its value is in the range 0-65535.
++#define DEFAULT_SIFST 5 //(M3C) SIFS Time. Its value is in the range 0-65535.
++#define DEFAULT_OSIFST 10 //(M3C) Original SIFS Time. Its value is in the range 0-15.
++#define DEFAULT_ATIMWD 0 //(M40) ATIM Window. Its value is in the range 0-65535.
++#define DEFAULT_SLOT_TIME 20 //(M40) ($) SlotTime. Its value is in the range 0-255.
++#define DEFAULT_MAX_TX_MSDU_LIFE_TIME 512 //(M44) MaxTxMSDULifeTime. Its value is in the range 0-4294967295.
++#define DEFAULT_BEACON_INTERVAL 500 //(M48) Beacon Interval. Its value is in the range 0-65535.
++#define DEFAULT_PROBE_DELAY_TIME 200 //(M48) Probe Delay Time. Its value is in the range 0-65535.
++#define DEFAULT_PROTOCOL_VERSION 0 //(M4C)
++#define DEFAULT_MAC_POWER_STATE 2 //(M4C) 2: MAC at power active
++#define DEFAULT_DTIM_ALERT_TIME 0
++
++
++typedef struct _REG_QUEUE
++{
++ struct urb *pUrb;
++ void* pUsbReq;
++ void* Next;
++ union
++ {
++ u32 VALUE;
++ PULONG pBuffer;
++ };
++ u8 RESERVED[4];// space reserved for communication
++
++ u16 INDEX; // For storing the register index
++ u8 RESERVED_VALID; //Indicate whether the RESERVED space is valid at this command.
++ u8 DIRECT; // 0:In 1:Out
++
++} REG_QUEUE, *PREG_QUEUE;
++
++//====================================
++// Internal variable for module
++//====================================
++#define MAX_SQ3_FILTER_SIZE 5
++typedef struct _WB35REG
++{
++ //============================
++ // Register Bank backup
++ //============================
++ u32 U1B0; //bit16 record the h/w radio on/off status
++ u32 U1BC_LEDConfigure;
++ u32 D00_DmaControl;
++ u32 M00_MacControl;
++ union {
++ struct {
++ u32 M04_MulticastAddress1;
++ u32 M08_MulticastAddress2;
++ };
++ u8 Multicast[8]; // contents of card multicast registers
++ };
++
++ u32 M24_MacControl;
++ u32 M28_MacControl;
++ u32 M2C_MacControl;
++ u32 M38_MacControl;
++ u32 M3C_MacControl; // 20060214 backup only
++ u32 M40_MacControl;
++ u32 M44_MacControl; // 20060214 backup only
++ u32 M48_MacControl; // 20060214 backup only
++ u32 M4C_MacStatus;
++ u32 M60_MacControl; // 20060214 backup only
++ u32 M68_MacControl; // 20060214 backup only
++ u32 M70_MacControl; // 20060214 backup only
++ u32 M74_MacControl; // 20060214 backup only
++ u32 M78_ERPInformation;//930206.2.b
++ u32 M7C_MacControl; // 20060214 backup only
++ u32 M80_MacControl; // 20060214 backup only
++ u32 M84_MacControl; // 20060214 backup only
++ u32 M88_MacControl; // 20060214 backup only
++ u32 M98_MacControl; // 20060214 backup only
++
++ //[20040722 WK]
++ //Baseband register
++ u32 BB0C; // Used for LNA calculation
++ u32 BB2C; //
++ u32 BB30; //11b acquisition control register
++ u32 BB3C;
++ u32 BB48; // 20051221.1.a 20060613.1 Fix OBW issue of 11b/11g rate
++ u32 BB4C; // 20060613.1 Fix OBW issue of 11b/11g rate
++ u32 BB50; //mode control register
++ u32 BB54;
++ u32 BB58; //IQ_ALPHA
++ u32 BB5C; // For test
++ u32 BB60; // for WTO read value
++
++ //-------------------
++ // VM
++ //-------------------
++ OS_SPIN_LOCK EP0VM_spin_lock; // 4B
++ u32 EP0VM_status;//$$
++ PREG_QUEUE pRegFirst;
++ PREG_QUEUE pRegLast;
++ OS_ATOMIC RegFireCount;
++
++ // Hardware status
++ u8 EP0vm_state;
++ u8 mac_power_save;
++ u8 EEPROMPhyType; // 0 ~ 15 for Maxim (0 ĄV MAX2825, 1 ĄV MAX2827, 2 ĄV MAX2828, 3 ĄV MAX2829),
++ // 16 ~ 31 for Airoha (16 ĄV AL2230, 11 - AL7230)
++ // 32 ~ Reserved
++ // 33 ~ 47 For WB242 ( 33 - WB242, 34 - WB242 with new Txvga 0.5 db step)
++ // 48 ~ 255 ARE RESERVED.
++ u8 EEPROMRegion; //Region setting in EEPROM
++
++ u32 SyncIoPause; // If user use the Sync Io to access Hw, then pause the async access
++
++ u8 LNAValue[4]; //Table for speed up running
++ u32 SQ3_filter[MAX_SQ3_FILTER_SIZE];
++ u32 SQ3_index;
++
++} WB35REG, *PWB35REG;
++
++
+diff --git a/drivers/staging/winbond/linux/wb35rx.c b/drivers/staging/winbond/linux/wb35rx.c
+new file mode 100644
+index 0000000..26157eb
+--- /dev/null
++++ b/drivers/staging/winbond/linux/wb35rx.c
+@@ -0,0 +1,337 @@
++//============================================================================
++// Copyright (c) 1996-2002 Winbond Electronic Corporation
++//
++// Module Name:
++// Wb35Rx.c
++//
++// Abstract:
++// Processing the Rx message from down layer
++//
++//============================================================================
++#include "sysdef.h"
++
++
++void Wb35Rx_start(phw_data_t pHwData)
++{
++ PWB35RX pWb35Rx = &pHwData->Wb35Rx;
++
++ // Allow only one thread to run into the Wb35Rx() function
++ if (OS_ATOMIC_INC(pHwData->Adapter, &pWb35Rx->RxFireCounter) == 1) {
++ pWb35Rx->EP3vm_state = VM_RUNNING;
++ Wb35Rx(pHwData);
++ } else
++ OS_ATOMIC_DEC(pHwData->Adapter, &pWb35Rx->RxFireCounter);
++}
++
++// This function cannot reentrain
++void Wb35Rx( phw_data_t pHwData )
++{
++ PWB35RX pWb35Rx = &pHwData->Wb35Rx;
++ PUCHAR pRxBufferAddress;
++ PURB pUrb = (PURB)pWb35Rx->RxUrb;
++ int retv;
++ u32 RxBufferId;
++
++ //
++ // Issuing URB
++ //
++ do {
++ if (pHwData->SurpriseRemove || pHwData->HwStop)
++ break;
++
++ if (pWb35Rx->rx_halt)
++ break;
++
++ // Get RxBuffer's ID
++ RxBufferId = pWb35Rx->RxBufferId;
++ if (!pWb35Rx->RxOwner[RxBufferId]) {
++ // It's impossible to run here.
++ #ifdef _PE_RX_DUMP_
++ WBDEBUG(("Rx driver fifo unavailable\n"));
++ #endif
++ break;
++ }
++
++ // Update buffer point, then start to bulkin the data from USB
++ pWb35Rx->RxBufferId++;
++ pWb35Rx->RxBufferId %= MAX_USB_RX_BUFFER_NUMBER;
++
++ pWb35Rx->CurrentRxBufferId = RxBufferId;
++
++ if (1 != OS_MEMORY_ALLOC((void* *)&pWb35Rx->pDRx, MAX_USB_RX_BUFFER)) {
++ printk("w35und: Rx memory alloc failed\n");
++ break;
++ }
++ pRxBufferAddress = pWb35Rx->pDRx;
++
++ usb_fill_bulk_urb(pUrb, pHwData->WbUsb.udev,
++ usb_rcvbulkpipe(pHwData->WbUsb.udev, 3),
++ pRxBufferAddress, MAX_USB_RX_BUFFER,
++ Wb35Rx_Complete, pHwData);
++
++ pWb35Rx->EP3vm_state = VM_RUNNING;
++
++ retv = wb_usb_submit_urb(pUrb);
++
++ if (retv != 0) {
++ printk("Rx URB sending error\n");
++ break;
++ }
++ return;
++ } while(FALSE);
++
++ // VM stop
++ pWb35Rx->EP3vm_state = VM_STOP;
++ OS_ATOMIC_DEC( pHwData->Adapter, &pWb35Rx->RxFireCounter );
++}
++
++void Wb35Rx_Complete(PURB pUrb)
++{
++ phw_data_t pHwData = pUrb->context;
++ PWB35RX pWb35Rx = &pHwData->Wb35Rx;
++ PUCHAR pRxBufferAddress;
++ u32 SizeCheck;
++ u16 BulkLength;
++ u32 RxBufferId;
++ R00_DESCRIPTOR R00;
++
++ // Variable setting
++ pWb35Rx->EP3vm_state = VM_COMPLETED;
++ pWb35Rx->EP3VM_status = pUrb->status;//Store the last result of Irp
++
++ do {
++ RxBufferId = pWb35Rx->CurrentRxBufferId;
++
++ pRxBufferAddress = pWb35Rx->pDRx;
++ BulkLength = (u16)pUrb->actual_length;
++
++ // The IRP is completed
++ pWb35Rx->EP3vm_state = VM_COMPLETED;
++
++ if (pHwData->SurpriseRemove || pHwData->HwStop) // Must be here, or RxBufferId is invalid
++ break;
++
++ if (pWb35Rx->rx_halt)
++ break;
++
++ // Start to process the data only in successful condition
++ pWb35Rx->RxOwner[ RxBufferId ] = 0; // Set the owner to driver
++ R00.value = le32_to_cpu(*(PULONG)pRxBufferAddress);
++
++ // The URB is completed, check the result
++ if (pWb35Rx->EP3VM_status != 0) {
++ #ifdef _PE_USB_STATE_DUMP_
++ WBDEBUG(("EP3 IoCompleteRoutine return error\n"));
++ DebugUsbdStatusInformation( pWb35Rx->EP3VM_status );
++ #endif
++ pWb35Rx->EP3vm_state = VM_STOP;
++ break;
++ }
++
++ // 20060220 For recovering. check if operating in single USB mode
++ if (!HAL_USB_MODE_BURST(pHwData)) {
++ SizeCheck = R00.R00_receive_byte_count; //20060926 anson's endian
++ if ((SizeCheck & 0x03) > 0)
++ SizeCheck -= 4;
++ SizeCheck = (SizeCheck + 3) & ~0x03;
++ SizeCheck += 12; // 8 + 4 badbeef
++ if ((BulkLength > 1600) ||
++ (SizeCheck > 1600) ||
++ (BulkLength != SizeCheck) ||
++ (BulkLength == 0)) { // Add for fail Urb
++ pWb35Rx->EP3vm_state = VM_STOP;
++ pWb35Rx->Ep3ErrorCount2++;
++ }
++ }
++
++ // Indicating the receiving data
++ pWb35Rx->ByteReceived += BulkLength;
++ pWb35Rx->RxBufferSize[ RxBufferId ] = BulkLength;
++
++ if (!pWb35Rx->RxOwner[ RxBufferId ])
++ Wb35Rx_indicate(pHwData);
++
++ kfree(pWb35Rx->pDRx);
++ // Do the next receive
++ Wb35Rx(pHwData);
++ return;
++
++ } while(FALSE);
++
++ pWb35Rx->RxOwner[ RxBufferId ] = 1; // Set the owner to hardware
++ OS_ATOMIC_DEC( pHwData->Adapter, &pWb35Rx->RxFireCounter );
++ pWb35Rx->EP3vm_state = VM_STOP;
++}
++
++//=====================================================================================
++unsigned char Wb35Rx_initial(phw_data_t pHwData)
++{
++ PWB35RX pWb35Rx = &pHwData->Wb35Rx;
++
++ // Initial the Buffer Queue
++ Wb35Rx_reset_descriptor( pHwData );
++
++ pWb35Rx->RxUrb = wb_usb_alloc_urb(0);
++ return (!!pWb35Rx->RxUrb);
++}
++
++void Wb35Rx_stop(phw_data_t pHwData)
++{
++ PWB35RX pWb35Rx = &pHwData->Wb35Rx;
++
++ // Canceling the Irp if already sends it out.
++ if (pWb35Rx->EP3vm_state == VM_RUNNING) {
++ usb_unlink_urb( pWb35Rx->RxUrb ); // Only use unlink, let Wb35Rx_destroy to free them
++ #ifdef _PE_RX_DUMP_
++ WBDEBUG(("EP3 Rx stop\n"));
++ #endif
++ }
++}
++
++// Needs process context
++void Wb35Rx_destroy(phw_data_t pHwData)
++{
++ PWB35RX pWb35Rx = &pHwData->Wb35Rx;
++
++ do {
++ OS_SLEEP(10000); // Delay for waiting function enter 940623.1.a
++ } while (pWb35Rx->EP3vm_state != VM_STOP);
++ OS_SLEEP(10000); // Delay for waiting function exit 940623.1.b
++
++ if (pWb35Rx->RxUrb)
++ usb_free_urb( pWb35Rx->RxUrb );
++ #ifdef _PE_RX_DUMP_
++ WBDEBUG(("Wb35Rx_destroy OK\n"));
++ #endif
++}
++
++void Wb35Rx_reset_descriptor( phw_data_t pHwData )
++{
++ PWB35RX pWb35Rx = &pHwData->Wb35Rx;
++ u32 i;
++
++ pWb35Rx->ByteReceived = 0;
++ pWb35Rx->RxProcessIndex = 0;
++ pWb35Rx->RxBufferId = 0;
++ pWb35Rx->EP3vm_state = VM_STOP;
++ pWb35Rx->rx_halt = 0;
++
++ // Initial the Queue. The last buffer is reserved for used if the Rx resource is unavailable.
++ for( i=0; i<MAX_USB_RX_BUFFER_NUMBER; i++ )
++ pWb35Rx->RxOwner[i] = 1;
++}
++
++void Wb35Rx_adjust(PDESCRIPTOR pRxDes)
++{
++ PULONG pRxBufferAddress;
++ u32 DecryptionMethod;
++ u32 i;
++ u16 BufferSize;
++
++ DecryptionMethod = pRxDes->R01.R01_decryption_method;
++ pRxBufferAddress = pRxDes->buffer_address[0];
++ BufferSize = pRxDes->buffer_size[0];
++
++ // Adjust the last part of data. Only data left
++ BufferSize -= 4; // For CRC-32
++ if (DecryptionMethod)
++ BufferSize -= 4;
++ if (DecryptionMethod == 3) // For CCMP
++ BufferSize -= 4;
++
++ // Adjust the IV field which after 802.11 header and ICV field.
++ if (DecryptionMethod == 1) // For WEP
++ {
++ for( i=6; i>0; i-- )
++ pRxBufferAddress[i] = pRxBufferAddress[i-1];
++ pRxDes->buffer_address[0] = pRxBufferAddress + 1;
++ BufferSize -= 4; // 4 byte for IV
++ }
++ else if( DecryptionMethod ) // For TKIP and CCMP
++ {
++ for (i=7; i>1; i--)
++ pRxBufferAddress[i] = pRxBufferAddress[i-2];
++ pRxDes->buffer_address[0] = pRxBufferAddress + 2;//Update the descriptor, shift 8 byte
++ BufferSize -= 8; // 8 byte for IV + ICV
++ }
++ pRxDes->buffer_size[0] = BufferSize;
++}
++
++extern void packet_came(char *pRxBufferAddress, int PacketSize);
++
++
++u16 Wb35Rx_indicate(phw_data_t pHwData)
++{
++ DESCRIPTOR RxDes;
++ PWB35RX pWb35Rx = &pHwData->Wb35Rx;
++ PUCHAR pRxBufferAddress;
++ u16 PacketSize;
++ u16 stmp, BufferSize, stmp2 = 0;
++ u32 RxBufferId;
++
++ // Only one thread be allowed to run into the following
++ do {
++ RxBufferId = pWb35Rx->RxProcessIndex;
++ if (pWb35Rx->RxOwner[ RxBufferId ]) //Owner by VM
++ break;
++
++ pWb35Rx->RxProcessIndex++;
++ pWb35Rx->RxProcessIndex %= MAX_USB_RX_BUFFER_NUMBER;
++
++ pRxBufferAddress = pWb35Rx->pDRx;
++ BufferSize = pWb35Rx->RxBufferSize[ RxBufferId ];
++
++ // Parse the bulkin buffer
++ while (BufferSize >= 4) {
++ if ((cpu_to_le32(*(PULONG)pRxBufferAddress) & 0x0fffffff) == RX_END_TAG) //Is ending? 921002.9.a
++ break;
++
++ // Get the R00 R01 first
++ RxDes.R00.value = le32_to_cpu(*(PULONG)pRxBufferAddress);
++ PacketSize = (u16)RxDes.R00.R00_receive_byte_count;
++ RxDes.R01.value = le32_to_cpu(*((PULONG)(pRxBufferAddress+4)));
++ // For new DMA 4k
++ if ((PacketSize & 0x03) > 0)
++ PacketSize -= 4;
++
++ // Basic check for Rx length. Is length valid?
++ if (PacketSize > MAX_PACKET_SIZE) {
++ #ifdef _PE_RX_DUMP_
++ WBDEBUG(("Serious ERROR : Rx data size too long, size =%d\n", PacketSize));
++ #endif
++
++ pWb35Rx->EP3vm_state = VM_STOP;
++ pWb35Rx->Ep3ErrorCount2++;
++ break;
++ }
++
++ // Start to process Rx buffer
++// RxDes.Descriptor_ID = RxBufferId; // Due to synchronous indicate, the field doesn't necessary to use.
++ BufferSize -= 8; //subtract 8 byte for 35's USB header length
++ pRxBufferAddress += 8;
++
++ RxDes.buffer_address[0] = pRxBufferAddress;
++ RxDes.buffer_size[0] = PacketSize;
++ RxDes.buffer_number = 1;
++ RxDes.buffer_start_index = 0;
++ RxDes.buffer_total_size = RxDes.buffer_size[0];
++ Wb35Rx_adjust(&RxDes);
++
++ packet_came(pRxBufferAddress, PacketSize);
++
++ // Move RxBuffer point to the next
++ stmp = PacketSize + 3;
++ stmp &= ~0x03; // 4n alignment
++ pRxBufferAddress += stmp;
++ BufferSize -= stmp;
++ stmp2 += stmp;
++ }
++
++ // Reclaim resource
++ pWb35Rx->RxOwner[ RxBufferId ] = 1;
++ } while(TRUE);
++
++ return stmp2;
++}
++
++
+diff --git a/drivers/staging/winbond/linux/wb35rx_f.h b/drivers/staging/winbond/linux/wb35rx_f.h
+new file mode 100644
+index 0000000..daa3e73
+--- /dev/null
++++ b/drivers/staging/winbond/linux/wb35rx_f.h
+@@ -0,0 +1,17 @@
++//====================================
++// Interface function declare
++//====================================
++void Wb35Rx_reset_descriptor( phw_data_t pHwData );
++unsigned char Wb35Rx_initial( phw_data_t pHwData );
++void Wb35Rx_destroy( phw_data_t pHwData );
++void Wb35Rx_stop( phw_data_t pHwData );
++u16 Wb35Rx_indicate( phw_data_t pHwData );
++void Wb35Rx_adjust( PDESCRIPTOR pRxDes );
++void Wb35Rx_start( phw_data_t pHwData );
++
++void Wb35Rx( phw_data_t pHwData );
++void Wb35Rx_Complete( PURB pUrb );
++
++
++
++
+diff --git a/drivers/staging/winbond/linux/wb35rx_s.h b/drivers/staging/winbond/linux/wb35rx_s.h
+new file mode 100644
+index 0000000..53b831f
+--- /dev/null
++++ b/drivers/staging/winbond/linux/wb35rx_s.h
+@@ -0,0 +1,48 @@
++//============================================================================
++// wb35rx.h --
++//============================================================================
++
++// Definition for this module used
++#define MAX_USB_RX_BUFFER 4096 // This parameter must be 4096 931130.4.f
++
++#define MAX_USB_RX_BUFFER_NUMBER ETHERNET_RX_DESCRIPTORS // Maximum 254, 255 is RESERVED ID
++#define RX_INTERFACE 0 // Interface 1
++#define RX_PIPE 2 // Pipe 3
++#define MAX_PACKET_SIZE 1600 //1568 // 8 + 1532 + 4 + 24(IV EIV MIC ICV CRC) for check DMA data 931130.4.g
++#define RX_END_TAG 0x0badbeef
++
++
++//====================================
++// Internal variable for module
++//====================================
++typedef struct _WB35RX
++{
++ u32 ByteReceived;// For calculating throughput of BulkIn
++ OS_ATOMIC RxFireCounter;// Does Wb35Rx module fire?
++
++ u8 RxBuffer[ MAX_USB_RX_BUFFER_NUMBER ][ ((MAX_USB_RX_BUFFER+3) & ~0x03 ) ];
++ u16 RxBufferSize[ ((MAX_USB_RX_BUFFER_NUMBER+1) & ~0x01) ];
++ u8 RxOwner[ ((MAX_USB_RX_BUFFER_NUMBER+3) & ~0x03 ) ];//Ownership of buffer 0: SW 1:HW
++
++ u32 RxProcessIndex;//The next index to process
++ u32 RxBufferId;
++ u32 EP3vm_state;
++
++ u32 rx_halt; // For VM stopping
++
++ u16 MoreDataSize;
++ u16 PacketSize;
++
++ u32 CurrentRxBufferId; // For complete routine usage
++ u32 Rx3UrbCancel;
++
++ u32 LastR1; // For RSSI reporting
++ struct urb * RxUrb;
++ u32 Ep3ErrorCount2; // 20060625.1 Usbd for Rx DMA error count
++
++ int EP3VM_status;
++ PUCHAR pDRx;
++
++} WB35RX, *PWB35RX;
++
++
+diff --git a/drivers/staging/winbond/linux/wb35tx.c b/drivers/staging/winbond/linux/wb35tx.c
+new file mode 100644
+index 0000000..cf19c3b
+--- /dev/null
++++ b/drivers/staging/winbond/linux/wb35tx.c
+@@ -0,0 +1,313 @@
++//============================================================================
++// Copyright (c) 1996-2002 Winbond Electronic Corporation
++//
++// Module Name:
++// Wb35Tx.c
++//
++// Abstract:
++// Processing the Tx message and put into down layer
++//
++//============================================================================
++#include "sysdef.h"
++
++
++unsigned char
++Wb35Tx_get_tx_buffer(phw_data_t pHwData, PUCHAR *pBuffer )
++{
++ PWB35TX pWb35Tx = &pHwData->Wb35Tx;
++
++ *pBuffer = pWb35Tx->TxBuffer[0];
++ return TRUE;
++}
++
++void Wb35Tx_start(phw_data_t pHwData)
++{
++ PWB35TX pWb35Tx = &pHwData->Wb35Tx;
++
++ // Allow only one thread to run into function
++ if (OS_ATOMIC_INC(pHwData->Adapter, &pWb35Tx->TxFireCounter) == 1) {
++ pWb35Tx->EP4vm_state = VM_RUNNING;
++ Wb35Tx(pHwData);
++ } else
++ OS_ATOMIC_DEC( pHwData->Adapter, &pWb35Tx->TxFireCounter );
++}
++
++
++void Wb35Tx(phw_data_t pHwData)
++{
++ PWB35TX pWb35Tx = &pHwData->Wb35Tx;
++ PADAPTER Adapter = pHwData->Adapter;
++ PUCHAR pTxBufferAddress;
++ PMDS pMds = &Adapter->Mds;
++ struct urb * pUrb = (struct urb *)pWb35Tx->Tx4Urb;
++ int retv;
++ u32 SendIndex;
++
++
++ if (pHwData->SurpriseRemove || pHwData->HwStop)
++ goto cleanup;
++
++ if (pWb35Tx->tx_halt)
++ goto cleanup;
++
++ // Ownership checking
++ SendIndex = pWb35Tx->TxSendIndex;
++ if (!pMds->TxOwner[SendIndex]) //No more data need to be sent, return immediately
++ goto cleanup;
++
++ pTxBufferAddress = pWb35Tx->TxBuffer[SendIndex];
++ //
++ // Issuing URB
++ //
++ usb_fill_bulk_urb(pUrb, pHwData->WbUsb.udev,
++ usb_sndbulkpipe(pHwData->WbUsb.udev, 4),
++ pTxBufferAddress, pMds->TxBufferSize[ SendIndex ],
++ Wb35Tx_complete, pHwData);
++
++ pWb35Tx->EP4vm_state = VM_RUNNING;
++ retv = wb_usb_submit_urb( pUrb );
++ if (retv<0) {
++ printk("EP4 Tx Irp sending error\n");
++ goto cleanup;
++ }
++
++ // Check if driver needs issue Irp for EP2
++ pWb35Tx->TxFillCount += pMds->TxCountInBuffer[SendIndex];
++ if (pWb35Tx->TxFillCount > 12)
++ Wb35Tx_EP2VM_start( pHwData );
++
++ pWb35Tx->ByteTransfer += pMds->TxBufferSize[SendIndex];
++ return;
++
++ cleanup:
++ pWb35Tx->EP4vm_state = VM_STOP;
++ OS_ATOMIC_DEC( pHwData->Adapter, &pWb35Tx->TxFireCounter );
++}
++
++
++void Wb35Tx_complete(struct urb * pUrb)
++{
++ phw_data_t pHwData = pUrb->context;
++ PADAPTER Adapter = (PADAPTER)pHwData->Adapter;
++ PWB35TX pWb35Tx = &pHwData->Wb35Tx;
++ PMDS pMds = &Adapter->Mds;
++
++ printk("wb35: tx complete\n");
++ // Variable setting
++ pWb35Tx->EP4vm_state = VM_COMPLETED;
++ pWb35Tx->EP4VM_status = pUrb->status; //Store the last result of Irp
++ pMds->TxOwner[ pWb35Tx->TxSendIndex ] = 0;// Set the owner. Free the owner bit always.
++ pWb35Tx->TxSendIndex++;
++ pWb35Tx->TxSendIndex %= MAX_USB_TX_BUFFER_NUMBER;
++
++ do {
++ if (pHwData->SurpriseRemove || pHwData->HwStop) // Let WbWlanHalt to handle surprise remove
++ break;
++
++ if (pWb35Tx->tx_halt)
++ break;
++
++ // The URB is completed, check the result
++ if (pWb35Tx->EP4VM_status != 0) {
++ printk("URB submission failed\n");
++ pWb35Tx->EP4vm_state = VM_STOP;
++ break; // Exit while(FALSE);
++ }
++
++ Mds_Tx(Adapter);
++ Wb35Tx(pHwData);
++ return;
++ } while(FALSE);
++
++ OS_ATOMIC_DEC( pHwData->Adapter, &pWb35Tx->TxFireCounter );
++ pWb35Tx->EP4vm_state = VM_STOP;
++}
++
++void Wb35Tx_reset_descriptor( phw_data_t pHwData )
++{
++ PWB35TX pWb35Tx = &pHwData->Wb35Tx;
++
++ pWb35Tx->TxSendIndex = 0;
++ pWb35Tx->tx_halt = 0;
++}
++
++unsigned char Wb35Tx_initial(phw_data_t pHwData)
++{
++ PWB35TX pWb35Tx = &pHwData->Wb35Tx;
++
++ pWb35Tx->Tx4Urb = wb_usb_alloc_urb(0);
++ if (!pWb35Tx->Tx4Urb)
++ return FALSE;
++
++ pWb35Tx->Tx2Urb = wb_usb_alloc_urb(0);
++ if (!pWb35Tx->Tx2Urb)
++ {
++ usb_free_urb( pWb35Tx->Tx4Urb );
++ return FALSE;
++ }
++
++ return TRUE;
++}
++
++//======================================================
++void Wb35Tx_stop(phw_data_t pHwData)
++{
++ PWB35TX pWb35Tx = &pHwData->Wb35Tx;
++
++ // Trying to canceling the Trp of EP2
++ if (pWb35Tx->EP2vm_state == VM_RUNNING)
++ usb_unlink_urb( pWb35Tx->Tx2Urb ); // Only use unlink, let Wb35Tx_destrot to free them
++ #ifdef _PE_TX_DUMP_
++ WBDEBUG(("EP2 Tx stop\n"));
++ #endif
++
++ // Trying to canceling the Irp of EP4
++ if (pWb35Tx->EP4vm_state == VM_RUNNING)
++ usb_unlink_urb( pWb35Tx->Tx4Urb ); // Only use unlink, let Wb35Tx_destrot to free them
++ #ifdef _PE_TX_DUMP_
++ WBDEBUG(("EP4 Tx stop\n"));
++ #endif
++}
++
++//======================================================
++void Wb35Tx_destroy(phw_data_t pHwData)
++{
++ PWB35TX pWb35Tx = &pHwData->Wb35Tx;
++
++ // Wait for VM stop
++ do {
++ OS_SLEEP(10000); // Delay for waiting function enter 940623.1.a
++ } while( (pWb35Tx->EP2vm_state != VM_STOP) && (pWb35Tx->EP4vm_state != VM_STOP) );
++ OS_SLEEP(10000); // Delay for waiting function enter 940623.1.b
++
++ if (pWb35Tx->Tx4Urb)
++ usb_free_urb( pWb35Tx->Tx4Urb );
++
++ if (pWb35Tx->Tx2Urb)
++ usb_free_urb( pWb35Tx->Tx2Urb );
++
++ #ifdef _PE_TX_DUMP_
++ WBDEBUG(("Wb35Tx_destroy OK\n"));
++ #endif
++}
++
++void Wb35Tx_CurrentTime(phw_data_t pHwData, u32 TimeCount)
++{
++ PWB35TX pWb35Tx = &pHwData->Wb35Tx;
++ unsigned char Trigger = FALSE;
++
++ if (pWb35Tx->TxTimer > TimeCount)
++ Trigger = TRUE;
++ else if (TimeCount > (pWb35Tx->TxTimer+500))
++ Trigger = TRUE;
++
++ if (Trigger) {
++ pWb35Tx->TxTimer = TimeCount;
++ Wb35Tx_EP2VM_start( pHwData );
++ }
++}
++
++void Wb35Tx_EP2VM_start(phw_data_t pHwData)
++{
++ PWB35TX pWb35Tx = &pHwData->Wb35Tx;
++
++ // Allow only one thread to run into function
++ if (OS_ATOMIC_INC( pHwData->Adapter, &pWb35Tx->TxResultCount ) == 1) {
++ pWb35Tx->EP2vm_state = VM_RUNNING;
++ Wb35Tx_EP2VM( pHwData );
++ }
++ else
++ OS_ATOMIC_DEC( pHwData->Adapter, &pWb35Tx->TxResultCount );
++}
++
++
++void Wb35Tx_EP2VM(phw_data_t pHwData)
++{
++ PWB35TX pWb35Tx = &pHwData->Wb35Tx;
++ struct urb * pUrb = (struct urb *)pWb35Tx->Tx2Urb;
++ PULONG pltmp = (PULONG)pWb35Tx->EP2_buf;
++ int retv;
++
++ do {
++ if (pHwData->SurpriseRemove || pHwData->HwStop)
++ break;
++
++ if (pWb35Tx->tx_halt)
++ break;
++
++ //
++ // Issuing URB
++ //
++ usb_fill_int_urb( pUrb, pHwData->WbUsb.udev, usb_rcvintpipe(pHwData->WbUsb.udev,2),
++ pltmp, MAX_INTERRUPT_LENGTH, Wb35Tx_EP2VM_complete, pHwData, 32);
++
++ pWb35Tx->EP2vm_state = VM_RUNNING;
++ retv = wb_usb_submit_urb( pUrb );
++
++ if(retv < 0) {
++ #ifdef _PE_TX_DUMP_
++ WBDEBUG(("EP2 Tx Irp sending error\n"));
++ #endif
++ break;
++ }
++
++ return;
++
++ } while(FALSE);
++
++ pWb35Tx->EP2vm_state = VM_STOP;
++ OS_ATOMIC_DEC( pHwData->Adapter, &pWb35Tx->TxResultCount );
++}
++
++
++void Wb35Tx_EP2VM_complete(struct urb * pUrb)
++{
++ phw_data_t pHwData = pUrb->context;
++ T02_DESCRIPTOR T02, TSTATUS;
++ PADAPTER Adapter = (PADAPTER)pHwData->Adapter;
++ PWB35TX pWb35Tx = &pHwData->Wb35Tx;
++ PULONG pltmp = (PULONG)pWb35Tx->EP2_buf;
++ u32 i;
++ u16 InterruptInLength;
++
++
++ // Variable setting
++ pWb35Tx->EP2vm_state = VM_COMPLETED;
++ pWb35Tx->EP2VM_status = pUrb->status;
++
++ do {
++ // For Linux 2.4. Interrupt will always trigger
++ if( pHwData->SurpriseRemove || pHwData->HwStop ) // Let WbWlanHalt to handle surprise remove
++ break;
++
++ if( pWb35Tx->tx_halt )
++ break;
++
++ //The Urb is completed, check the result
++ if (pWb35Tx->EP2VM_status != 0) {
++ WBDEBUG(("EP2 IoCompleteRoutine return error\n"));
++ pWb35Tx->EP2vm_state= VM_STOP;
++ break; // Exit while(FALSE);
++ }
++
++ // Update the Tx result
++ InterruptInLength = pUrb->actual_length;
++ // Modify for minimum memory access and DWORD alignment.
++ T02.value = cpu_to_le32(pltmp[0]) >> 8; // [31:8] -> [24:0]
++ InterruptInLength -= 1;// 20051221.1.c Modify the follow for more stable
++ InterruptInLength >>= 2; // InterruptInLength/4
++ for (i=1; i<=InterruptInLength; i++) {
++ T02.value |= ((cpu_to_le32(pltmp[i]) & 0xff) << 24);
++
++ TSTATUS.value = T02.value; //20061009 anson's endian
++ Mds_SendComplete( Adapter, &TSTATUS );
++ T02.value = cpu_to_le32(pltmp[i]) >> 8;
++ }
++
++ return;
++ } while(FALSE);
++
++ OS_ATOMIC_DEC( pHwData->Adapter, &pWb35Tx->TxResultCount );
++ pWb35Tx->EP2vm_state = VM_STOP;
++}
++
+diff --git a/drivers/staging/winbond/linux/wb35tx_f.h b/drivers/staging/winbond/linux/wb35tx_f.h
+new file mode 100644
+index 0000000..7705a84
+--- /dev/null
++++ b/drivers/staging/winbond/linux/wb35tx_f.h
+@@ -0,0 +1,20 @@
++//====================================
++// Interface function declare
++//====================================
++unsigned char Wb35Tx_initial( phw_data_t pHwData );
++void Wb35Tx_destroy( phw_data_t pHwData );
++unsigned char Wb35Tx_get_tx_buffer( phw_data_t pHwData, PUCHAR *pBuffer );
++
++void Wb35Tx_EP2VM( phw_data_t pHwData );
++void Wb35Tx_EP2VM_start( phw_data_t pHwData );
++void Wb35Tx_EP2VM_complete( PURB purb );
++
++void Wb35Tx_start( phw_data_t pHwData );
++void Wb35Tx_stop( phw_data_t pHwData );
++void Wb35Tx( phw_data_t pHwData );
++void Wb35Tx_complete( PURB purb );
++void Wb35Tx_reset_descriptor( phw_data_t pHwData );
++
++void Wb35Tx_CurrentTime( phw_data_t pHwData, u32 TimeCount );
++
++
+diff --git a/drivers/staging/winbond/linux/wb35tx_s.h b/drivers/staging/winbond/linux/wb35tx_s.h
+new file mode 100644
+index 0000000..ac43257
+--- /dev/null
++++ b/drivers/staging/winbond/linux/wb35tx_s.h
+@@ -0,0 +1,47 @@
++//====================================
++// IS89C35 Tx related definition
++//====================================
++#define TX_INTERFACE 0 // Interface 1
++#define TX_PIPE 3 // endpoint 4
++#define TX_INTERRUPT 1 // endpoint 2
++#define MAX_INTERRUPT_LENGTH 64 // It must be 64 for EP2 hardware
++
++
++
++//====================================
++// Internal variable for module
++//====================================
++
++
++typedef struct _WB35TX
++{
++ // For Tx buffer
++ u8 TxBuffer[ MAX_USB_TX_BUFFER_NUMBER ][ MAX_USB_TX_BUFFER ];
++
++ // For Interrupt pipe
++ u8 EP2_buf[MAX_INTERRUPT_LENGTH];
++
++ OS_ATOMIC TxResultCount;// For thread control of EP2 931130.4.m
++ OS_ATOMIC TxFireCounter;// For thread control of EP4 931130.4.n
++ u32 ByteTransfer;
++
++ u32 TxSendIndex;// The next index of Mds array to be sent
++ u32 EP2vm_state; // for EP2vm state
++ u32 EP4vm_state; // for EP4vm state
++ u32 tx_halt; // Stopping VM
++
++ struct urb * Tx4Urb;
++ struct urb * Tx2Urb;
++
++ int EP2VM_status;
++ int EP4VM_status;
++
++ u32 TxFillCount; // 20060928
++ u32 TxTimer; // 20060928 Add if sending packet not great than 13
++
++} WB35TX, *PWB35TX;
++
++
++
++
++
+diff --git a/drivers/staging/winbond/linux/wbusb.c b/drivers/staging/winbond/linux/wbusb.c
+new file mode 100644
+index 0000000..cbad5fb
+--- /dev/null
++++ b/drivers/staging/winbond/linux/wbusb.c
+@@ -0,0 +1,404 @@
++/*
++ * Copyright 2008 Pavel Machek <pavel@suse.cz>
++ *
++ * Distribute under GPLv2.
++ */
++#include "sysdef.h"
++#include <net/mac80211.h>
++
++
++MODULE_AUTHOR( DRIVER_AUTHOR );
++MODULE_DESCRIPTION( DRIVER_DESC );
++MODULE_LICENSE("GPL");
++MODULE_VERSION("0.1");
++
++
++//============================================================
++// vendor ID and product ID can into here for others
++//============================================================
++static struct usb_device_id Id_Table[] =
++{
++ {USB_DEVICE( 0x0416, 0x0035 )},
++ {USB_DEVICE( 0x18E8, 0x6201 )},
++ {USB_DEVICE( 0x18E8, 0x6206 )},
++ {USB_DEVICE( 0x18E8, 0x6217 )},
++ {USB_DEVICE( 0x18E8, 0x6230 )},
++ {USB_DEVICE( 0x18E8, 0x6233 )},
++ {USB_DEVICE( 0x1131, 0x2035 )},
++ { }
++};
++
++MODULE_DEVICE_TABLE(usb, Id_Table);
++
++static struct usb_driver wb35_driver = {
++ .name = "w35und",
++ .probe = wb35_probe,
++ .disconnect = wb35_disconnect,
++ .id_table = Id_Table,
++};
++
++static const struct ieee80211_rate wbsoft_rates[] = {
++ { .bitrate = 10, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
++};
++
++static const struct ieee80211_channel wbsoft_channels[] = {
++ { .center_freq = 2412},
++};
++
++int wbsoft_enabled;
++struct ieee80211_hw *my_dev;
++PADAPTER my_adapter;
++
++static int wbsoft_add_interface(struct ieee80211_hw *dev,
++ struct ieee80211_if_init_conf *conf)
++{
++ printk("wbsoft_add interface called\n");
++ return 0;
++}
++
++static void wbsoft_remove_interface(struct ieee80211_hw *dev,
++ struct ieee80211_if_init_conf *conf)
++{
++ printk("wbsoft_remove interface called\n");
++}
++
++static int wbsoft_nop(void)
++{
++ printk("wbsoft_nop called\n");
++ return 0;
++}
++
++static void wbsoft_configure_filter(struct ieee80211_hw *dev,
++ unsigned int changed_flags,
++ unsigned int *total_flags,
++ int mc_count, struct dev_mc_list *mclist)
++{
++ unsigned int bit_nr, new_flags;
++ u32 mc_filter[2];
++ int i;
++
++ new_flags = 0;
++
++ if (*total_flags & FIF_PROMISC_IN_BSS) {
++ new_flags |= FIF_PROMISC_IN_BSS;
++ mc_filter[1] = mc_filter[0] = ~0;
++ } else if ((*total_flags & FIF_ALLMULTI) || (mc_count > 32)) {
++ new_flags |= FIF_ALLMULTI;
++ mc_filter[1] = mc_filter[0] = ~0;
++ } else {
++ mc_filter[1] = mc_filter[0] = 0;
++ for (i = 0; i < mc_count; i++) {
++ if (!mclist)
++ break;
++ printk("Should call ether_crc here\n");
++ //bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
++ bit_nr = 0;
++
++ bit_nr &= 0x3F;
++ mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
++ mclist = mclist->next;
++ }
++ }
++
++ dev->flags &= ~IEEE80211_HW_RX_INCLUDES_FCS;
++
++ *total_flags = new_flags;
++}
++
++static int wbsoft_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
++ struct ieee80211_tx_control *control)
++{
++ char *buffer = kmalloc(skb->len, GFP_ATOMIC);
++ printk("Sending frame %d bytes\n", skb->len);
++ memcpy(buffer, skb->data, skb->len);
++ if (1 == MLMESendFrame(my_adapter, buffer, skb->len, FRAME_TYPE_802_11_MANAGEMENT))
++ printk("frame sent ok (%d bytes)?\n", skb->len);
++ return NETDEV_TX_OK;
++}
++
++
++static int wbsoft_start(struct ieee80211_hw *dev)
++{
++ wbsoft_enabled = 1;
++ printk("wbsoft_start called\n");
++ return 0;
++}
++
++static int wbsoft_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
++{
++ ChanInfo ch;
++ printk("wbsoft_config called\n");
++
++ ch.band = 1;
++ ch.ChanNo = 1; /* Should use channel_num, or something, as that is already pre-translated */
++
++
++ hal_set_current_channel(&my_adapter->sHwData, ch);
++ hal_set_beacon_period(&my_adapter->sHwData, conf->beacon_int);
++// hal_set_cap_info(&my_adapter->sHwData, ?? );
++// hal_set_ssid(phw_data_t pHwData, PUCHAR pssid, u8 ssid_len); ??
++ hal_set_accept_broadcast(&my_adapter->sHwData, 1);
++ hal_set_accept_promiscuous(&my_adapter->sHwData, 1);
++ hal_set_accept_multicast(&my_adapter->sHwData, 1);
++ hal_set_accept_beacon(&my_adapter->sHwData, 1);
++ hal_set_radio_mode(&my_adapter->sHwData, 0);
++ //hal_set_antenna_number( phw_data_t pHwData, u8 number )
++ //hal_set_rf_power(phw_data_t pHwData, u8 PowerIndex)
++
++
++// hal_start_bss(&my_adapter->sHwData, WLAN_BSSTYPE_INFRASTRUCTURE); ??
++
++//void hal_set_rates(phw_data_t pHwData, PUCHAR pbss_rates,
++// u8 length, unsigned char basic_rate_set)
++
++ return 0;
++}
++
++static int wbsoft_config_interface(struct ieee80211_hw *dev,
++ struct ieee80211_vif *vif,
++ struct ieee80211_if_conf *conf)
++{
++ printk("wbsoft_config_interface called\n");
++ return 0;
++}
++
++static u64 wbsoft_get_tsf(struct ieee80211_hw *dev)
++{
++ printk("wbsoft_get_tsf called\n");
++ return 0;
++}
++
++static const struct ieee80211_ops wbsoft_ops = {
++ .tx = wbsoft_tx,
++ .start = wbsoft_start, /* Start can be pretty much empty as we do WbWLanInitialize() during probe? */
++ .stop = wbsoft_nop,
++ .add_interface = wbsoft_add_interface,
++ .remove_interface = wbsoft_remove_interface,
++ .config = wbsoft_config,
++ .config_interface = wbsoft_config_interface,
++ .configure_filter = wbsoft_configure_filter,
++ .get_stats = wbsoft_nop,
++ .get_tx_stats = wbsoft_nop,
++ .get_tsf = wbsoft_get_tsf,
++// conf_tx: hal_set_cwmin()/hal_set_cwmax;
++};
++
++struct wbsoft_priv {
++};
++
++
++int __init wb35_init(void)
++{
++ printk("[w35und]driver init\n");
++ return usb_register(&wb35_driver);
++}
++
++void __exit wb35_exit(void)
++{
++ printk("[w35und]driver exit\n");
++ usb_deregister( &wb35_driver );
++}
++
++module_init(wb35_init);
++module_exit(wb35_exit);
++
++// Usb kernel subsystem will call this function when a new device is plugged into.
++int wb35_probe(struct usb_interface *intf, const struct usb_device_id *id_table)
++{
++ PADAPTER Adapter;
++ PWBLINUX pWbLinux;
++ PWBUSB pWbUsb;
++ struct usb_host_interface *interface;
++ struct usb_endpoint_descriptor *endpoint;
++ int i, ret = -1;
++ u32 ltmp;
++ struct usb_device *udev = interface_to_usbdev(intf);
++
++ usb_get_dev(udev);
++
++ printk("[w35und]wb35_probe ->\n");
++
++ do {
++ for (i=0; i<(sizeof(Id_Table)/sizeof(struct usb_device_id)); i++ ) {
++ if ((udev->descriptor.idVendor == Id_Table[i].idVendor) &&
++ (udev->descriptor.idProduct == Id_Table[i].idProduct)) {
++ printk("[w35und]Found supported hardware\n");
++ break;
++ }
++ }
++ if ((i == (sizeof(Id_Table)/sizeof(struct usb_device_id)))) {
++ #ifdef _PE_USB_INI_DUMP_
++ WBDEBUG(("[w35und] This is not the one we are interested about\n"));
++ #endif
++ return -ENODEV;
++ }
++
++ // 20060630.2 Check the device if it already be opened
++ ret = usb_control_msg(udev, usb_rcvctrlpipe( udev, 0 ),
++ 0x01, USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_DIR_IN,
++ 0x0, 0x400, <mp, 4, HZ*100 );
++ if( ret < 0 )
++ break;
++
++ ltmp = cpu_to_le32(ltmp);
++ if (ltmp) // Is already initialized?
++ break;
++
++
++ Adapter = kzalloc(sizeof(ADAPTER), GFP_KERNEL);
++
++ my_adapter = Adapter;
++ pWbLinux = &Adapter->WbLinux;
++ pWbUsb = &Adapter->sHwData.WbUsb;
++ pWbUsb->udev = udev;
++
++ interface = intf->cur_altsetting;
++ endpoint = &interface->endpoint[0].desc;
++
++ if (endpoint[2].wMaxPacketSize == 512) {
++ printk("[w35und] Working on USB 2.0\n");
++ pWbUsb->IsUsb20 = 1;
++ }
++
++ if (!WbWLanInitialize(Adapter)) {
++ printk("[w35und]WbWLanInitialize fail\n");
++ break;
++ }
++
++ {
++ struct wbsoft_priv *priv;
++ struct ieee80211_hw *dev;
++ int res;
++
++ dev = ieee80211_alloc_hw(sizeof(*priv), &wbsoft_ops);
++
++ if (!dev) {
++ printk("w35und: ieee80211 alloc failed\n" );
++ BUG();
++ }
++
++ my_dev = dev;
++
++ SET_IEEE80211_DEV(dev, &udev->dev);
++ {
++ phw_data_t pHwData = &Adapter->sHwData;
++ unsigned char dev_addr[MAX_ADDR_LEN];
++ hal_get_permanent_address(pHwData, dev_addr);
++ SET_IEEE80211_PERM_ADDR(dev, dev_addr);
++ }
++
++
++ dev->extra_tx_headroom = 12; /* FIXME */
++ dev->flags = 0;
++
++ dev->channel_change_time = 1000;
++// dev->max_rssi = 100;
++
++ dev->queues = 1;
++
++ static struct ieee80211_supported_band band;
++
++ band.channels = wbsoft_channels;
++ band.n_channels = ARRAY_SIZE(wbsoft_channels);
++ band.bitrates = wbsoft_rates;
++ band.n_bitrates = ARRAY_SIZE(wbsoft_rates);
++
++ dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &band;
++#if 0
++ wbsoft_modes[0].num_channels = 1;
++ wbsoft_modes[0].channels = wbsoft_channels;
++ wbsoft_modes[0].mode = MODE_IEEE80211B;
++ wbsoft_modes[0].num_rates = ARRAY_SIZE(wbsoft_rates);
++ wbsoft_modes[0].rates = wbsoft_rates;
++
++ res = ieee80211_register_hwmode(dev, &wbsoft_modes[0]);
++ BUG_ON(res);
++#endif
++
++ res = ieee80211_register_hw(dev);
++ BUG_ON(res);
++ }
++
++ usb_set_intfdata( intf, Adapter );
++
++ printk("[w35und] _probe OK\n");
++ return 0;
++
++ } while(FALSE);
++
++ return -ENOMEM;
++}
++
++void packet_came(char *pRxBufferAddress, int PacketSize)
++{
++ struct sk_buff *skb;
++ struct ieee80211_rx_status rx_status = {0};
++
++ if (!wbsoft_enabled)
++ return;
++
++ skb = dev_alloc_skb(PacketSize);
++ if (!skb) {
++ printk("Not enough memory for packet, FIXME\n");
++ return;
++ }
++
++ memcpy(skb_put(skb, PacketSize),
++ pRxBufferAddress,
++ PacketSize);
++
++/*
++ rx_status.rate = 10;
++ rx_status.channel = 1;
++ rx_status.freq = 12345;
++ rx_status.phymode = MODE_IEEE80211B;
++*/
++
++ ieee80211_rx_irqsafe(my_dev, skb, &rx_status);
++}
++
++unsigned char
++WbUsb_initial(phw_data_t pHwData)
++{
++ return 1;
++}
++
++
++void
++WbUsb_destroy(phw_data_t pHwData)
++{
++}
++
++int wb35_open(struct net_device *netdev)
++{
++ PADAPTER Adapter = (PADAPTER)netdev->priv;
++ phw_data_t pHwData = &Adapter->sHwData;
++
++ netif_start_queue(netdev);
++
++ //TODO : put here temporarily
++ hal_set_accept_broadcast(pHwData, 1); // open accept broadcast
++
++ return 0;
++}
++
++int wb35_close(struct net_device *netdev)
++{
++ netif_stop_queue(netdev);
++ return 0;
++}
++
++void wb35_disconnect(struct usb_interface *intf)
++{
++ PWBLINUX pWbLinux;
++ PADAPTER Adapter = usb_get_intfdata(intf);
++ usb_set_intfdata(intf, NULL);
++
++ pWbLinux = &Adapter->WbLinux;
++
++ // Card remove
++ WbWlanHalt(Adapter);
++
++}
++
++
+diff --git a/drivers/staging/winbond/linux/wbusb_f.h b/drivers/staging/winbond/linux/wbusb_f.h
+new file mode 100644
+index 0000000..cae29e1
+--- /dev/null
++++ b/drivers/staging/winbond/linux/wbusb_f.h
+@@ -0,0 +1,34 @@
++//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++// Copyright (c) 1996-2004 Winbond Electronic Corporation
++//
++// Module Name:
++// wbusb_f.h
++//
++// Abstract:
++// Linux driver.
++//
++// Author:
++//
++//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++
++int wb35_open(struct net_device *netdev);
++int wb35_close(struct net_device *netdev);
++unsigned char WbUsb_initial(phw_data_t pHwData);
++void WbUsb_destroy(phw_data_t pHwData);
++unsigned char WbWLanInitialize(PADAPTER Adapter);
++#define WbUsb_Stop( _A )
++
++int wb35_probe(struct usb_interface *intf,const struct usb_device_id *id_table);
++void wb35_disconnect(struct usb_interface *intf);
++
++
++#define wb_usb_submit_urb(_A) usb_submit_urb(_A, GFP_ATOMIC)
++#define wb_usb_alloc_urb(_A) usb_alloc_urb(_A, GFP_ATOMIC)
++
++#define WbUsb_CheckForHang( _P )
++#define WbUsb_DetectStart( _P, _I )
++
++
++
++
++
+diff --git a/drivers/staging/winbond/linux/wbusb_s.h b/drivers/staging/winbond/linux/wbusb_s.h
+new file mode 100644
+index 0000000..d5c1d53
+--- /dev/null
++++ b/drivers/staging/winbond/linux/wbusb_s.h
+@@ -0,0 +1,42 @@
++//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++// Copyright (c) 1996-2004 Winbond Electronic Corporation
++//
++// Module Name:
++// wbusb_s.h
++//
++// Abstract:
++// Linux driver.
++//
++// Author:
++//
++//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++
++#define OS_SLEEP( _MT ) { set_current_state(TASK_INTERRUPTIBLE); \
++ schedule_timeout( _MT*HZ/1000000 ); }
++
++
++//---------------------------------------------------------------------------
++// RW_CONTEXT --
++//
++// Used to track driver-generated io irps
++//---------------------------------------------------------------------------
++typedef struct _RW_CONTEXT
++{
++ void* pHwData;
++ PURB pUrb;
++ void* pCallBackFunctionParameter;
++} RW_CONTEXT, *PRW_CONTEXT;
++
++
++
++
++#define DRIVER_AUTHOR "Original by: Jeff Lee<YY_Lee@issc.com.tw> Adapted to 2.6.x by Costantino Leandro (Rxart Desktop) <le_costantino@pixartargentina.com.ar>"
++#define DRIVER_DESC "IS89C35 802.11bg WLAN USB Driver"
++
++
++
++typedef struct _WBUSB {
++ u32 IsUsb20;
++ struct usb_device *udev;
++ u32 DetectCount;
++} WBUSB, *PWBUSB;
+diff --git a/drivers/staging/winbond/localpara.h b/drivers/staging/winbond/localpara.h
+new file mode 100644
+index 0000000..268cf91
+--- /dev/null
++++ b/drivers/staging/winbond/localpara.h
+@@ -0,0 +1,275 @@
++//=============================================================
++// LocalPara.h -
++//=============================================================
++//Define the local ability
++
++#define LOCAL_DEFAULT_BEACON_PERIOD 100 //ms
++#define LOCAL_DEFAULT_ATIM_WINDOW 0
++#define LOCAL_DEFAULT_ERP_CAPABILITY 0x0431 //0x0001: ESS
++ //0x0010: Privacy
++ //0x0020: short preamble
++ //0x0400: short slot time
++#define LOCAL_DEFAULT_LISTEN_INTERVAL 5
++
++//#define LOCAL_DEFAULT_24_CHANNEL_NUM 11 // channel 1..11
++#define LOCAL_DEFAULT_24_CHANNEL_NUM 13 // channel 1..13
++#define LOCAL_DEFAULT_5_CHANNEL_NUM 8 // channel 36..64
++
++#define LOCAL_USA_24_CHANNEL_NUM 11
++#define LOCAL_USA_5_CHANNEL_NUM 12
++#define LOCAL_EUROPE_24_CHANNEL_NUM 13
++#define LOCAL_EUROPE_5_CHANNEL_NUM 19
++#define LOCAL_JAPAN_24_CHANNEL_NUM 14
++#define LOCAL_JAPAN_5_CHANNEL_NUM 11
++#define LOCAL_UNKNOWN_24_CHANNEL_NUM 14
++#define LOCAL_UNKNOWN_5_CHANNEL_NUM 34 //not include 165
++
++
++#define psLOCAL (&(Adapter->sLocalPara))
++
++#define MODE_802_11_BG 0
++#define MODE_802_11_A 1
++#define MODE_802_11_ABG 2
++#define MODE_802_11_BG_IBSS 3
++#define MODE_802_11_B 4
++#define MODE_AUTO 255
++
++#define BAND_TYPE_DSSS 0
++#define BAND_TYPE_OFDM_24 1
++#define BAND_TYPE_OFDM_5 2
++
++//refer Bitmap2RateValue table
++#define LOCAL_ALL_SUPPORTED_RATES_BITMAP 0x130c1a66 //the bitmap value of all the H/W supported rates
++ //1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54
++#define LOCAL_OFDM_SUPPORTED_RATES_BITMAP 0x130c1240 //the bitmap value of all the H/W supported rates
++ //except to non-OFDM rates
++ //6, 9, 12, 18, 24, 36, 48, 54
++
++#define LOCAL_11B_SUPPORTED_RATE_BITMAP 0x826
++#define LOCAL_11B_BASIC_RATE_BITMAP 0x826
++#define LOCAL_11B_OPERATION_RATE_BITMAP 0x826
++#define LOCAL_11G_BASIC_RATE_BITMAP 0x826 //1, 2, 5.5, 11
++#define LOCAL_11G_OPERATION_RATE_BITMAP 0x130c1240 //6, 9, 12, 18, 24, 36, 48, 54
++#define LOCAL_11A_BASIC_RATE_BITMAP 0x01001040 //6, 12, 24
++#define LOCAL_11A_OPERATION_RATE_BITMAP 0x120c0200 //9, 18, 36, 48, 54
++
++
++
++#define PWR_ACTIVE 0
++#define PWR_SAVE 1
++#define PWR_TX_IDLE_CYCLE 6
++
++//bPreambleMode and bSlotTimeMode
++#define AUTO_MODE 0
++#define LONG_MODE 1
++
++//Region definition
++#define REGION_AUTO 0xff
++#define REGION_UNKNOWN 0
++#define REGION_EUROPE 1 //ETSI
++#define REGION_JAPAN 2 //MKK
++#define REGION_USA 3 //FCC
++#define REGION_FRANCE 4 //FRANCE
++#define REGION_SPAIN 5 //SPAIN
++#define REGION_ISRAEL 6 //ISRAEL
++//#define REGION_CANADA 7 //IC
++
++#define MAX_BSS_DESCRIPT_ELEMENT 32
++#define MAX_PMKID_CandidateList 16
++
++//High byte : Event number, low byte : reason
++//Event definition
++//-- SME/MLME event
++#define EVENT_RCV_DEAUTH 0x0100
++#define EVENT_JOIN_FAIL 0x0200
++#define EVENT_AUTH_FAIL 0x0300
++#define EVENT_ASSOC_FAIL 0x0400
++#define EVENT_LOST_SIGNAL 0x0500
++#define EVENT_BSS_DESCRIPT_LACK 0x0600
++#define EVENT_COUNTERMEASURE 0x0700
++#define EVENT_JOIN_FILTER 0x0800
++//-- TX/RX event
++#define EVENT_RX_BUFF_UNAVAILABLE 0x4100
++
++#define EVENT_CONNECT 0x8100
++#define EVENT_DISCONNECT 0x8200
++#define EVENT_SCAN_REQ 0x8300
++
++//Reason of Event
++#define EVENT_REASON_FILTER_BASIC_RATE 0x0001
++#define EVENT_REASON_FILTER_PRIVACY 0x0002
++#define EVENT_REASON_FILTER_AUTH_MODE 0x0003
++#define EVENT_REASON_TIMEOUT 0x00ff
++
++// 20061108 WPS IE buffer
++#define MAX_IE_APPEND_SIZE 256 + 4 // Due to [E id][Length][OUI][Data] may 257 bytes
++
++typedef struct _EVENTLOG
++{
++ u16 Count; //Total count from start
++ u16 index; //Buffer index, 0 ~ 63
++ u32 EventValue[64]; //BYTE 3~2 : count, BYTE 1 : Event, BYTE 0 : reason
++} Event_Log, *pEvent_Log;
++
++typedef struct _ChanInfo
++{
++ u8 band;
++ u8 ChanNo;
++} ChanInfo, *pChanInfo;
++
++typedef struct _CHAN_LIST
++{
++ u16 Count;
++ ChanInfo Channel[50]; // 100B
++} CHAN_LIST, *psCHAN_LIST;
++
++typedef struct _RadioOff
++{
++ u8 boHwRadioOff;
++ u8 boSwRadioOff;
++} RadioOff, *psRadioOff;
++
++//===========================================================================
++typedef struct LOCAL_PARA
++{
++ u8 PermanentAddress[ MAC_ADDR_LENGTH + 2 ]; // read from EPROM, manufacture set for each NetCard
++ u8 ThisMacAddress[ MAC_ADDR_LENGTH + 2 ]; // the driver will use actually.
++
++ u32 MTUsize; // Ind to Uplayer, Max transmission unit size
++
++ u8 region_INF; //region setting from INF
++ u8 region; //real region setting of the device
++ u8 Reserved_1[2];
++
++ //// power-save variables
++ u8 iPowerSaveMode; // 0 indicates it is on, 1 indicates it is off
++ u8 ShutDowned;
++ u8 ATIMmode;
++ u8 ExcludeUnencrypted;
++
++ u16 CheckCountForPS; //Unit ime count for the decision to enter PS mode
++ u8 boHasTxActivity; //tx activity has occurred
++ u8 boMacPsValid; //Power save mode obtained from H/W is valid or not
++
++ //// Rate
++ u8 TxRateMode; // Initial, input from Registry, may be updated by GUI
++ //Tx Rate Mode: auto(DTO on), max, 1M, 2M, ..
++ u8 CurrentTxRate; // The current Tx rate
++ u8 CurrentTxRateForMng; // The current Tx rate for management frames
++ // It will be decided before connection succeeds.
++ u8 CurrentTxFallbackRate;
++
++ //for Rate handler
++ u8 BRateSet[32]; //basic rate set
++ u8 SRateSet[32]; //support rate set
++
++ u8 NumOfBRate;
++ u8 NumOfSRate;
++ u8 NumOfDsssRateInSRate; //number of DSSS rates in supported rate set
++ u8 reserved1;
++
++ u32 dwBasicRateBitmap; //bit map of basic rates
++ u32 dwSupportRateBitmap; //bit map of all support rates including
++ //basic and operational rates
++
++ ////For SME/MLME handler
++ u16 wOldSTAindex; // valid when boHandover=TRUE, store old connected STA index
++ u16 wConnectedSTAindex; // Index of peerly connected AP or IBSS in
++ // the descriptionset.
++ u16 Association_ID; // The Association ID in the (Re)Association
++ // Response frame.
++ u16 ListenInterval; // The listen interval when SME invoking MLME_
++ // (Re)Associate_Request().
++
++ RadioOff RadioOffStatus;
++ u8 Reserved0[2];
++
++ u8 boMsRadioOff; // Ndis demands to be true when set Disassoc. OID and be false when set SSID OID.
++ u8 boAntennaDiversity; //TRUE/ON or FALSE/OFF
++ u8 bAntennaNo; //which antenna
++ u8 bConnectFlag; //the connect status flag for roaming task
++
++ u8 RoamStatus;
++ u8 reserved7[3];
++
++ ChanInfo CurrentChan; //Current channel no. and channel band. It may be changed by scanning.
++ u8 boHandover; // Roaming, Hnadover to other AP.
++ u8 boCCAbusy;
++
++ u16 CWMax; // It may not be the real value that H/W used
++ u8 CWMin; // 255: set according to 802.11 spec.
++ u8 reserved2;
++
++ //11G:
++ u8 bMacOperationMode; // operation in 802.11b or 802.11g
++ u8 bSlotTimeMode; //AUTO, s32
++ u8 bPreambleMode; //AUTO, s32
++ u8 boNonERPpresent;
++
++ u8 boProtectMechanism; // H/W will take the necessary action based on this variable
++ u8 boShortPreamble; // H/W will take the necessary action based on this variable
++ u8 boShortSlotTime; // H/W will take the necessary action based on this variable
++ u8 reserved_3;
++
++ u32 RSN_IE_Bitmap; //added by WS
++ u32 RSN_OUI_Type; //added by WS
++
++ //For the BSSID
++ u8 HwBssid[MAC_ADDR_LENGTH + 2];
++ u32 HwBssidValid;
++
++ //For scan list
++ u8 BssListCount; //Total count of valid descriptor indexes
++ u8 boReceiveUncorrectInfo; //important settings in beacon/probe resp. have been changed
++ u8 NoOfJoinerInIbss;
++ u8 reserved_4;
++
++ u8 BssListIndex[ (MAX_BSS_DESCRIPT_ELEMENT+3) & ~0x03 ]; //Store the valid descriptor indexes obtained from scannings
++ u8 JoinerInIbss[ (MAX_BSS_DESCRIPT_ELEMENT+3) & ~0x03 ]; //save the BssDescriptor index in this
++ //IBSS. The index 0 is local descriptor
++ //(psLOCAL->wConnectedSTAindex).
++ //If CONNECTED : NoOfJoinerInIbss >=2
++ // else : NoOfJoinerInIbss <=1
++
++ //// General Statistics, count at Rx_handler or Tx_callback interrupt handler
++ u64 GS_XMIT_OK; // Good Frames Transmitted
++ u64 GS_RCV_OK; // Good Frames Received
++ u32 GS_RCV_ERROR; // Frames received with crc error
++ u32 GS_XMIT_ERROR; // Bad Frames Transmitted
++ u32 GS_RCV_NO_BUFFER; // Receive Buffer underrun
++ u32 GS_XMIT_ONE_COLLISION; // one collision
++ u32 GS_XMIT_MORE_COLLISIONS;// more collisions
++
++ //================================================================
++ // Statistics (no matter whether it had done successfully) -wkchen
++ //================================================================
++ u32 _NumRxMSDU;
++ u32 _NumTxMSDU;
++ u32 _dot11WEPExcludedCount;
++ u32 _dot11WEPUndecryptableCount;
++ u32 _dot11FrameDuplicateCount;
++
++ ChanInfo IbssChanSetting; // 2B. Start IBSS Channel setting by registry or WWU.
++ u8 reserved_5[2]; //It may not be used after considering RF type,
++ //region and modulation type.
++
++ CHAN_LIST sSupportChanList; // 86B. It will be obtained according to RF type and region
++ u8 reserved_6[2]; //two variables are for wep key error detection added by ws 02/02/04
++
++ u32 bWepKeyError;
++ u32 bToSelfPacketReceived;
++ u32 WepKeyDetectTimerCount;
++
++ Event_Log EventLog;
++
++ u16 SignalLostTh;
++ u16 SignalRoamTh;
++
++ // 20061108 WPS IE Append
++ u8 IE_Append_data[MAX_IE_APPEND_SIZE];
++ u16 IE_Append_size;
++ u16 reserved_7;
++
++} WB_LOCALDESCRIPT, *PWB_LOCALDESCRIPT;
++
++
+diff --git a/drivers/staging/winbond/mac_structures.h b/drivers/staging/winbond/mac_structures.h
+new file mode 100644
+index 0000000..031d2cb
+--- /dev/null
++++ b/drivers/staging/winbond/mac_structures.h
+@@ -0,0 +1,670 @@
++//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++// MAC_Structures.h
++//
++// This file contains the definitions and data structures used by SW-MAC.
++//
++// Revision Histoy
++//=================
++// 0.1 2002 UN00
++// 0.2 20021004 PD43 CCLiu6
++// 20021018 PD43 CCLiu6
++// Add enum_TxRate type
++// Modify enum_STAState type
++// 0.3 20021023 PE23 CYLiu update MAC session struct
++// 20021108
++// 20021122 PD43 Austin
++// Deleted some unused.
++// 20021129 PD43 Austin
++// 20030617 increase the 802.11g definition
++//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++
++#ifndef _MAC_Structures_H_
++#define _MAC_Structures_H_
++
++
++//=========================================================
++// Some miscellaneous definitions
++//-----
++#define MAX_CHANNELS 30
++#define MAC_ADDR_LENGTH 6
++#define MAX_WEP_KEY_SIZE 16 // 128 bits
++#define MAX_802_11_FRAGMENT_NUMBER 10 // By spec
++
++//========================================================
++// 802.11 Frame define
++//-----
++#define MASK_PROTOCOL_VERSION_TYPE 0x0F
++#define MASK_FRAGMENT_NUMBER 0x000F
++#define SEQUENCE_NUMBER_SHIFT 4
++#define DIFFER_11_TO_3 18
++#define DOT_11_MAC_HEADER_SIZE 24
++#define DOT_11_SNAP_SIZE 6
++#define DOT_11_DURATION_OFFSET 2
++#define DOT_11_SEQUENCE_OFFSET 22 //Sequence control offset
++#define DOT_11_TYPE_OFFSET 30 //The start offset of 802.11 Frame//
++#define DOT_11_DATA_OFFSET 24
++#define DOT_11_DA_OFFSET 4
++#define DOT_3_TYPE_ARP 0x80F3
++#define DOT_3_TYPE_IPX 0x8137
++#define DOT_3_TYPE_OFFSET 12
++
++
++#define ETHERNET_HEADER_SIZE 14
++#define MAX_ETHERNET_PACKET_SIZE 1514
++
++
++//----- management : Type of Bits (2, 3) and Subtype of Bits (4, 5, 6, 7)
++#define MAC_SUBTYPE_MNGMNT_ASSOC_REQUEST 0x00
++#define MAC_SUBTYPE_MNGMNT_ASSOC_RESPONSE 0x10
++#define MAC_SUBTYPE_MNGMNT_REASSOC_REQUEST 0x20
++#define MAC_SUBTYPE_MNGMNT_REASSOC_RESPONSE 0x30
++#define MAC_SUBTYPE_MNGMNT_PROBE_REQUEST 0x40
++#define MAC_SUBTYPE_MNGMNT_PROBE_RESPONSE 0x50
++#define MAC_SUBTYPE_MNGMNT_BEACON 0x80
++#define MAC_SUBTYPE_MNGMNT_ATIM 0x90
++#define MAC_SUBTYPE_MNGMNT_DISASSOCIATION 0xA0
++#define MAC_SUBTYPE_MNGMNT_AUTHENTICATION 0xB0
++#define MAC_SUBTYPE_MNGMNT_DEAUTHENTICATION 0xC0
++
++//----- control : Type of Bits (2, 3) and Subtype of Bits (4, 5, 6, 7)
++#define MAC_SUBTYPE_CONTROL_PSPOLL 0xA4
++#define MAC_SUBTYPE_CONTROL_RTS 0xB4
++#define MAC_SUBTYPE_CONTROL_CTS 0xC4
++#define MAC_SUBTYPE_CONTROL_ACK 0xD4
++#define MAC_SUBTYPE_CONTROL_CFEND 0xE4
++#define MAC_SUBTYPE_CONTROL_CFEND_CFACK 0xF4
++
++//----- data : Type of Bits (2, 3) and Subtype of Bits (4, 5, 6, 7)
++#define MAC_SUBTYPE_DATA 0x08
++#define MAC_SUBTYPE_DATA_CFACK 0x18
++#define MAC_SUBTYPE_DATA_CFPOLL 0x28
++#define MAC_SUBTYPE_DATA_CFACK_CFPOLL 0x38
++#define MAC_SUBTYPE_DATA_NULL 0x48
++#define MAC_SUBTYPE_DATA_CFACK_NULL 0x58
++#define MAC_SUBTYPE_DATA_CFPOLL_NULL 0x68
++#define MAC_SUBTYPE_DATA_CFACK_CFPOLL_NULL 0x78
++
++//----- Frame Type of Bits (2, 3)
++#define MAC_TYPE_MANAGEMENT 0x00
++#define MAC_TYPE_CONTROL 0x04
++#define MAC_TYPE_DATA 0x08
++
++//----- definitions for Management Frame Element ID (1 BYTE)
++#define ELEMENT_ID_SSID 0
++#define ELEMENT_ID_SUPPORTED_RATES 1
++#define ELEMENT_ID_FH_PARAMETER_SET 2
++#define ELEMENT_ID_DS_PARAMETER_SET 3
++#define ELEMENT_ID_CF_PARAMETER_SET 4
++#define ELEMENT_ID_TIM 5
++#define ELEMENT_ID_IBSS_PARAMETER_SET 6
++// 7~15 reserverd
++#define ELEMENT_ID_CHALLENGE_TEXT 16
++// 17~31 reserved for challenge text extension
++// 32~255 reserved
++//-- 11G --
++#define ELEMENT_ID_ERP_INFORMATION 42
++#define ELEMENT_ID_EXTENDED_SUPPORTED_RATES 50
++
++//-- WPA --
++
++#define ELEMENT_ID_RSN_WPA 221
++#ifdef _WPA2_
++#define ELEMENT_ID_RSN_WPA2 48
++#endif //endif WPA2
++
++#define WLAN_MAX_PAIRWISE_CIPHER_SUITE_COUNT ((u16) 6)
++#define WLAN_MAX_AUTH_KEY_MGT_SUITE_LIST_COUNT ((u16) 2)
++
++#ifdef WB_LINUX
++#define UNALIGNED
++#endif
++
++//========================================================
++typedef enum enum_PowerManagementMode
++{
++ ACTIVE = 0,
++ POWER_SAVE
++} WB_PM_Mode, *PWB_PM_MODE;
++
++//===================================================================
++// Reason Code (Table 18): indicate the reason of DisAssoc, DeAuthen
++// length of ReasonCode is 2 Octs.
++//===================================================================
++#define REASON_REASERED 0
++#define REASON_UNSPECIDIED 1
++#define REASON_PREAUTH_INVALID 2
++#define DEAUTH_REASON_LEFT_BSS 3
++#define DISASS_REASON_AP_INACTIVE 4
++#define DISASS_REASON_AP_BUSY 5
++#define REASON_CLASS2_FRAME_FROM_NONAUTH_STA 6
++#define REASON_CLASS3_FRAME_FROM_NONASSO_STA 7
++#define DISASS_REASON_LEFT_BSS 8
++#define REASON_NOT_AUTH_YET 9
++//802.11i define
++#define REASON_INVALID_IE 13
++#define REASON_MIC_ERROR 14
++#define REASON_4WAY_HANDSHAKE_TIMEOUT 15
++#define REASON_GROUPKEY_UPDATE_TIMEOUT 16
++#define REASON_IE_DIFF_4WAY_ASSOC 17
++#define REASON_INVALID_MULTICAST_CIPHER 18
++#define REASON_INVALID_UNICAST_CIPHER 19
++#define REASON_INVALID_AKMP 20
++#define REASON_UNSUPPORTED_RSNIE_VERSION 21
++#define REASON_INVALID_RSNIE_CAPABILITY 22
++#define REASON_802_1X_AUTH_FAIL 23
++#define REASON_CIPHER_REJECT_PER_SEC_POLICY 14
++
++/*
++//===========================================================
++// enum_MMPDUResultCode --
++// Status code (2 Octs) in the MMPDU's frame body. Table.19
++//
++//===========================================================
++enum enum_MMPDUResultCode
++{
++// SUCCESS = 0, // Redefined
++ UNSPECIFIED_FAILURE = 1,
++
++ // 2 - 9 Reserved
++
++ NOT_SUPPROT_CAPABILITIES = 10,
++
++ //REASSOCIATION_DENIED
++ //
++ REASSOC_DENIED_UNABLE_CFM_ASSOC_EXIST = 11,
++
++ //ASSOCIATION_DENIED_NOT_IN_STANDARD
++ //
++ ASSOC_DENIED_REASON_NOT_IN_STANDARD = 12,
++ PEER_NOT_SUPPORT_AUTH_ALGORITHM = 13,
++ AUTH_SEQNUM_OUT_OF_EXPECT = 14,
++ AUTH_REJECT_REASON_CHALLENGE_FAIL = 15,
++ AUTH_REJECT_REASON_WAIT_TIMEOUT = 16,
++ ASSOC_DENIED_REASON_AP_BUSY = 17,
++ ASSOC_DENIED_REASON_NOT_SUPPORT_BASIC_RATE = 18
++} WB_MMPDURESULTCODE, *PWB_MMPDURESULTCODE;
++*/
++
++//===========================================================
++// enum_TxRate --
++// Define the transmission constants based on W89C32 MAC
++// target specification.
++//===========================================================
++typedef enum enum_TxRate
++{
++ TXRATE_1M = 0,
++ TXRATE_2MLONG = 2,
++ TXRATE_2MSHORT = 3,
++ TXRATE_55MLONG = 4,
++ TXRATE_55MSHORT = 5,
++ TXRATE_11MLONG = 6,
++ TXRATE_11MSHORT = 7,
++ TXRATE_AUTO = 255 // PD43 20021108
++} WB_TXRATE, *PWB_TXRATE;
++
++
++#define RATE_BITMAP_1M 1
++#define RATE_BITMAP_2M 2
++#define RATE_BITMAP_5dot5M 5
++#define RATE_BITMAP_6M 6
++#define RATE_BITMAP_9M 9
++#define RATE_BITMAP_11M 11
++#define RATE_BITMAP_12M 12
++#define RATE_BITMAP_18M 18
++#define RATE_BITMAP_22M 22
++#define RATE_BITMAP_24M 24
++#define RATE_BITMAP_33M 17
++#define RATE_BITMAP_36M 19
++#define RATE_BITMAP_48M 25
++#define RATE_BITMAP_54M 28
++
++#define RATE_AUTO 0
++#define RATE_1M 2
++#define RATE_2M 4
++#define RATE_5dot5M 11
++#define RATE_6M 12
++#define RATE_9M 18
++#define RATE_11M 22
++#define RATE_12M 24
++#define RATE_18M 36
++#define RATE_22M 44
++#define RATE_24M 48
++#define RATE_33M 66
++#define RATE_36M 72
++#define RATE_48M 96
++#define RATE_54M 108
++#define RATE_MAX 255
++
++//CAPABILITY
++#define CAPABILITY_ESS_BIT 0x0001
++#define CAPABILITY_IBSS_BIT 0x0002
++#define CAPABILITY_CF_POLL_BIT 0x0004
++#define CAPABILITY_CF_POLL_REQ_BIT 0x0008
++#define CAPABILITY_PRIVACY_BIT 0x0010
++#define CAPABILITY_SHORT_PREAMBLE_BIT 0x0020
++#define CAPABILITY_PBCC_BIT 0x0040
++#define CAPABILITY_CHAN_AGILITY_BIT 0x0080
++#define CAPABILITY_SHORT_SLOT_TIME_BIT 0x0400
++#define CAPABILITY_DSSS_OFDM_BIT 0x2000
++
++
++struct Capability_Information_Element
++{
++ union
++ {
++ u16 __attribute__ ((packed)) wValue;
++ #ifdef _BIG_ENDIAN_ //20060926 add by anson's endian
++ struct _Capability
++ {
++ //-- 11G --
++ u8 Reserved3 : 2;
++ u8 DSSS_OFDM : 1;
++ u8 Reserved2 : 2;
++ u8 Short_Slot_Time : 1;
++ u8 Reserved1 : 2;
++ u8 Channel_Agility : 1;
++ u8 PBCC : 1;
++ u8 ShortPreamble : 1;
++ u8 CF_Privacy : 1;
++ u8 CF_Poll_Request : 1;
++ u8 CF_Pollable : 1;
++ u8 IBSS : 1;
++ u8 ESS : 1;
++ } __attribute__ ((packed)) Capability;
++ #else
++ struct _Capability
++ {
++ u8 ESS : 1;
++ u8 IBSS : 1;
++ u8 CF_Pollable : 1;
++ u8 CF_Poll_Request : 1;
++ u8 CF_Privacy : 1;
++ u8 ShortPreamble : 1;
++ u8 PBCC : 1;
++ u8 Channel_Agility : 1;
++ u8 Reserved1 : 2;
++ //-- 11G --
++ u8 Short_Slot_Time : 1;
++ u8 Reserved2 : 2;
++ u8 DSSS_OFDM : 1;
++ u8 Reserved3 : 2;
++ } __attribute__ ((packed)) Capability;
++ #endif
++ }__attribute__ ((packed)) ;
++}__attribute__ ((packed));
++
++struct FH_Parameter_Set_Element
++{
++ u8 Element_ID;
++ u8 Length;
++ u8 Dwell_Time[2];
++ u8 Hop_Set;
++ u8 Hop_Pattern;
++ u8 Hop_Index;
++};
++
++struct DS_Parameter_Set_Element
++{
++ u8 Element_ID;
++ u8 Length;
++ u8 Current_Channel;
++};
++
++struct Supported_Rates_Element
++{
++ u8 Element_ID;
++ u8 Length;
++ u8 SupportedRates[8];
++}__attribute__ ((packed));
++
++struct SSID_Element
++{
++ u8 Element_ID;
++ u8 Length;
++ u8 SSID[32];
++}__attribute__ ((packed)) ;
++
++struct CF_Parameter_Set_Element
++{
++ u8 Element_ID;
++ u8 Length;
++ u8 CFP_Count;
++ u8 CFP_Period;
++ u8 CFP_MaxDuration[2]; // in Time Units
++ u8 CFP_DurRemaining[2]; // in time units
++};
++
++struct TIM_Element
++{
++ u8 Element_ID;
++ u8 Length;
++ u8 DTIM_Count;
++ u8 DTIM_Period;
++ u8 Bitmap_Control;
++ u8 Partial_Virtual_Bitmap[251];
++};
++
++struct IBSS_Parameter_Set_Element
++{
++ u8 Element_ID;
++ u8 Length;
++ u8 ATIM_Window[2];
++};
++
++struct Challenge_Text_Element
++{
++ u8 Element_ID;
++ u8 Length;
++ u8 Challenge_Text[253];
++};
++
++struct PHY_Parameter_Set_Element
++{
++// int aSlotTime;
++// int aSifsTime;
++ s32 aCCATime;
++ s32 aRxTxTurnaroundTime;
++ s32 aTxPLCPDelay;
++ s32 RxPLCPDelay;
++ s32 aRxTxSwitchTime;
++ s32 aTxRampOntime;
++ s32 aTxRampOffTime;
++ s32 aTxRFDelay;
++ s32 aRxRFDelay;
++ s32 aAirPropagationTime;
++ s32 aMACProcessingDelay;
++ s32 aPreambleLength;
++ s32 aPLCPHeaderLength;
++ s32 aMPDUDurationFactor;
++ s32 aMPDUMaxLength;
++// int aCWmin;
++// int aCWmax;
++};
++
++//-- 11G --
++struct ERP_Information_Element
++{
++ u8 Element_ID;
++ u8 Length;
++ #ifdef _BIG_ENDIAN_ //20060926 add by anson's endian
++ u8 Reserved:5; //20060926 add by anson
++ u8 Barker_Preamble_Mode:1;
++ u8 Use_Protection:1;
++ u8 NonERP_Present:1;
++ #else
++ u8 NonERP_Present:1;
++ u8 Use_Protection:1;
++ u8 Barker_Preamble_Mode:1;
++ u8 Reserved:5;
++ #endif
++};
++
++struct Extended_Supported_Rates_Element
++{
++ u8 Element_ID;
++ u8 Length;
++ u8 ExtendedSupportedRates[255];
++}__attribute__ ((packed));
++
++//WPA(802.11i draft 3.0)
++#define VERSION_WPA 1
++#ifdef _WPA2_
++#define VERSION_WPA2 1
++#endif //end def _WPA2_
++#define OUI_WPA 0x00F25000 //WPA2.0 OUI=00:50:F2, the MSB is reserved for suite type
++#ifdef _WPA2_
++#define OUI_WPA2 0x00AC0F00 // for wpa2 change to 0x00ACOF04 by Ws 26/04/04
++#endif //end def _WPA2_
++
++#define OUI_WPA_ADDITIONAL 0x01
++#define WLAN_MIN_RSN_WPA_LENGTH 6 //added by ws 09/10/04
++#ifdef _WPA2_
++#define WLAN_MIN_RSN_WPA2_LENGTH 2 // Fix to 2 09/14/05
++#endif //end def _WPA2_
++
++#define oui_wpa (u32)(OUI_WPA|OUI_WPA_ADDITIONAL)
++
++#define WPA_OUI_BIG ((u32) 0x01F25000)//added by ws 09/23/04
++#define WPA_OUI_LITTLE ((u32) 0x01F25001)//added by ws 09/23/04
++
++#define WPA_WPS_OUI cpu_to_le32(0x04F25000) // 20061108 For WPS. It's little endian. Big endian is 0x0050F204
++
++//-----WPA2-----
++#ifdef _WPA2_
++#define WPA2_OUI_BIG ((u32)0x01AC0F00)
++#define WPA2_OUI_LITTLE ((u32)0x01AC0F01)
++#endif //end def _WPA2_
++
++//Authentication suite
++#define OUI_AUTH_WPA_NONE 0x00 //for WPA_NONE
++#define OUI_AUTH_8021X 0x01
++#define OUI_AUTH_PSK 0x02
++//Cipher suite
++#define OUI_CIPHER_GROUP_KEY 0x00 //added by ws 05/21/04
++#define OUI_CIPHER_WEP_40 0x01
++#define OUI_CIPHER_TKIP 0x02
++#define OUI_CIPHER_CCMP 0x04
++#define OUI_CIPHER_WEP_104 0x05
++
++typedef struct _SUITE_SELECTOR_
++{
++ union
++ {
++ u8 Value[4];
++ struct _SUIT_
++ {
++ u8 OUI[3];
++ u8 Type;
++ }SuitSelector;
++ };
++}SUITE_SELECTOR;
++
++//-- WPA --
++struct RSN_Information_Element
++{
++ u8 Element_ID;
++ u8 Length;
++ UNALIGNED SUITE_SELECTOR OuiWPAAdditional;//WPA version 2.0 additional field, and should be 00:50:F2:01
++ u16 Version;
++ SUITE_SELECTOR GroupKeySuite;
++ u16 PairwiseKeySuiteCount;
++ SUITE_SELECTOR PairwiseKeySuite[1];
++}__attribute__ ((packed));
++struct RSN_Auth_Sub_Information_Element
++{
++ u16 AuthKeyMngtSuiteCount;
++ SUITE_SELECTOR AuthKeyMngtSuite[1];
++}__attribute__ ((packed));
++
++//-- WPA2 --
++struct RSN_Capability_Element
++{
++ union
++ {
++ u16 __attribute__ ((packed)) wValue;
++ #ifdef _BIG_ENDIAN_ //20060927 add by anson's endian
++ struct _RSN_Capability
++ {
++ u16 __attribute__ ((packed)) Reserved2 : 8; // 20051201
++ u16 __attribute__ ((packed)) Reserved1 : 2;
++ u16 __attribute__ ((packed)) GTK_Replay_Counter : 2;
++ u16 __attribute__ ((packed)) PTK_Replay_Counter : 2;
++ u16 __attribute__ ((packed)) No_Pairwise : 1;
++ u16 __attribute__ ((packed)) Pre_Auth : 1;
++ }__attribute__ ((packed)) RSN_Capability;
++ #else
++ struct _RSN_Capability
++ {
++ u16 __attribute__ ((packed)) Pre_Auth : 1;
++ u16 __attribute__ ((packed)) No_Pairwise : 1;
++ u16 __attribute__ ((packed)) PTK_Replay_Counter : 2;
++ u16 __attribute__ ((packed)) GTK_Replay_Counter : 2;
++ u16 __attribute__ ((packed)) Reserved1 : 2;
++ u16 __attribute__ ((packed)) Reserved2 : 8; // 20051201
++ }__attribute__ ((packed)) RSN_Capability;
++ #endif
++
++ }__attribute__ ((packed)) ;
++}__attribute__ ((packed)) ;
++
++#ifdef _WPA2_
++typedef struct _PMKID
++{
++ u8 pValue[16];
++}PMKID;
++
++struct WPA2_RSN_Information_Element
++{
++ u8 Element_ID;
++ u8 Length;
++ u16 Version;
++ SUITE_SELECTOR GroupKeySuite;
++ u16 PairwiseKeySuiteCount;
++ SUITE_SELECTOR PairwiseKeySuite[1];
++
++}__attribute__ ((packed));
++
++struct WPA2_RSN_Auth_Sub_Information_Element
++{
++ u16 AuthKeyMngtSuiteCount;
++ SUITE_SELECTOR AuthKeyMngtSuite[1];
++}__attribute__ ((packed));
++
++
++struct PMKID_Information_Element
++{
++ u16 PMKID_Count;
++ PMKID pmkid [16] ;
++}__attribute__ ((packed));
++
++#endif //enddef _WPA2_
++//============================================================
++// MAC Frame structure (different type) and subfield structure
++//============================================================
++struct MAC_frame_control
++{
++ u8 mac_frame_info; // a combination of the [Protocol Version, Control Type, Control Subtype]
++ #ifdef _BIG_ENDIAN_ //20060927 add by anson's endian
++ u8 order:1;
++ u8 WEP:1;
++ u8 more_data:1;
++ u8 pwr_mgt:1;
++ u8 retry:1;
++ u8 more_frag:1;
++ u8 from_ds:1;
++ u8 to_ds:1;
++ #else
++ u8 to_ds:1;
++ u8 from_ds:1;
++ u8 more_frag:1;
++ u8 retry:1;
++ u8 pwr_mgt:1;
++ u8 more_data:1;
++ u8 WEP:1;
++ u8 order:1;
++ #endif
++} __attribute__ ((packed));
++
++struct Management_Frame {
++ struct MAC_frame_control frame_control; // 2B, ToDS,FromDS,MoreFrag,MoreData,Order=0
++ u16 duration;
++ u8 DA[MAC_ADDR_LENGTH]; // Addr1
++ u8 SA[MAC_ADDR_LENGTH]; // Addr2
++ u8 BSSID[MAC_ADDR_LENGTH]; // Addr3
++ u16 Sequence_Control;
++ // Management Frame Body <= 325 bytes
++ // FCS 4 bytes
++}__attribute__ ((packed));
++
++// SW-MAC don't Tx/Rx Control-Frame, HW-MAC do it.
++struct Control_Frame {
++ struct MAC_frame_control frame_control; // ToDS,FromDS,MoreFrag,Retry,MoreData,WEP,Order=0
++ u16 duration;
++ u8 RA[MAC_ADDR_LENGTH];
++ u8 TA[MAC_ADDR_LENGTH];
++ u16 FCS;
++}__attribute__ ((packed));
++
++struct Data_Frame {
++ struct MAC_frame_control frame_control;
++ u16 duration;
++ u8 Addr1[MAC_ADDR_LENGTH];
++ u8 Addr2[MAC_ADDR_LENGTH];
++ u8 Addr3[MAC_ADDR_LENGTH];
++ u16 Sequence_Control;
++ u8 Addr4[MAC_ADDR_LENGTH]; // only exist when ToDS=FromDS=1
++ // Data Frame Body <= 2312
++ // FCS
++}__attribute__ ((packed));
++
++struct Disassociation_Frame_Body
++{
++ u16 reasonCode;
++}__attribute__ ((packed));
++
++struct Association_Request_Frame_Body
++{
++ u16 capability_information;
++ u16 listenInterval;
++ u8 Current_AP_Address[MAC_ADDR_LENGTH];//for reassociation only
++ // SSID (2+32 bytes)
++ // Supported_Rates (2+8 bytes)
++}__attribute__ ((packed));
++
++struct Association_Response_Frame_Body
++{
++ u16 capability_information;
++ u16 statusCode;
++ u16 Association_ID;
++ struct Supported_Rates_Element supportedRates;
++}__attribute__ ((packed));
++
++/*struct Reassociation_Request_Frame_Body
++{
++ u16 capability_information;
++ u16 listenInterval;
++ u8 Current_AP_Address[MAC_ADDR_LENGTH];
++ // SSID (2+32 bytes)
++ // Supported_Rates (2+8 bytes)
++};*/
++// eliminated by WS 07/22/04 comboined with associateion request frame.
++
++struct Reassociation_Response_Frame_Body
++{
++ u16 capability_information;
++ u16 statusCode;
++ u16 Association_ID;
++ struct Supported_Rates_Element supportedRates;
++}__attribute__ ((packed));
++
++struct Deauthentication_Frame_Body
++{
++ u16 reasonCode;
++}__attribute__ ((packed));
++
++
++struct Probe_Response_Frame_Body
++{
++ u16 Timestamp;
++ u16 Beacon_Interval;
++ u16 Capability_Information;
++ // SSID
++ // Supported_Rates
++ // PHY parameter Set (DS Parameters)
++ // CF parameter Set
++ // IBSS parameter Set
++}__attribute__ ((packed));
++
++struct Authentication_Frame_Body
++{
++ u16 algorithmNumber;
++ u16 sequenceNumber;
++ u16 statusCode;
++ // NB: don't include ChallengeText in this structure
++ // struct Challenge_Text_Element sChallengeTextElement; // wkchen added
++}__attribute__ ((packed));
++
++
++#endif // _MAC_Structure_H_
++
++
+diff --git a/drivers/staging/winbond/mds.c b/drivers/staging/winbond/mds.c
+new file mode 100644
+index 0000000..8ce6389
+--- /dev/null
++++ b/drivers/staging/winbond/mds.c
+@@ -0,0 +1,630 @@
++#include "os_common.h"
++
++void
++Mds_reset_descriptor(PADAPTER Adapter)
++{
++ PMDS pMds = &Adapter->Mds;
++
++ pMds->TxPause = 0;
++ pMds->TxThreadCount = 0;
++ pMds->TxFillIndex = 0;
++ pMds->TxDesIndex = 0;
++ pMds->ScanTxPause = 0;
++ memset(pMds->TxOwner, 0, ((MAX_USB_TX_BUFFER_NUMBER + 3) & ~0x03));
++}
++
++unsigned char
++Mds_initial(PADAPTER Adapter)
++{
++ PMDS pMds = &Adapter->Mds;
++
++ pMds->TxPause = FALSE;
++ pMds->TxRTSThreshold = DEFAULT_RTSThreshold;
++ pMds->TxFragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD;
++
++ vRxTimerInit(Adapter);//for WPA countermeasure
++
++ return hal_get_tx_buffer( &Adapter->sHwData, &pMds->pTxBuffer );
++}
++
++void
++Mds_Destroy(PADAPTER Adapter)
++{
++ vRxTimerStop(Adapter);
++}
++
++void
++Mds_Tx(PADAPTER Adapter)
++{
++ phw_data_t pHwData = &Adapter->sHwData;
++ PMDS pMds = &Adapter->Mds;
++ DESCRIPTOR TxDes;
++ PDESCRIPTOR pTxDes = &TxDes;
++ PUCHAR XmitBufAddress;
++ u16 XmitBufSize, PacketSize, stmp, CurrentSize, FragmentThreshold;
++ u8 FillIndex, TxDesIndex, FragmentCount, FillCount;
++ unsigned char BufferFilled = FALSE, MICAdd = 0;
++
++
++ if (pMds->TxPause)
++ return;
++ if (!hal_driver_init_OK(pHwData))
++ return;
++
++ //Only one thread can be run here
++ if (!OS_ATOMIC_INC( Adapter, &pMds->TxThreadCount) == 1)
++ goto cleanup;
++
++ // Start to fill the data
++ do {
++ FillIndex = pMds->TxFillIndex;
++ if (pMds->TxOwner[FillIndex]) { // Is owned by software 0:Yes 1:No
++#ifdef _PE_TX_DUMP_
++ WBDEBUG(("[Mds_Tx] Tx Owner is H/W.\n"));
++#endif
++ break;
++ }
++
++ XmitBufAddress = pMds->pTxBuffer + (MAX_USB_TX_BUFFER * FillIndex); //Get buffer
++ XmitBufSize = 0;
++ FillCount = 0;
++ do {
++ PacketSize = Adapter->sMlmeFrame.len;
++ if (!PacketSize)
++ break;
++
++ //For Check the buffer resource
++ FragmentThreshold = CURRENT_FRAGMENT_THRESHOLD;
++ //931130.5.b
++ FragmentCount = PacketSize/FragmentThreshold + 1;
++ stmp = PacketSize + FragmentCount*32 + 8;//931130.5.c 8:MIC
++ if ((XmitBufSize + stmp) >= MAX_USB_TX_BUFFER) {
++ printk("[Mds_Tx] Excess max tx buffer.\n");
++ break; // buffer is not enough
++ }
++
++
++ //
++ // Start transmitting
++ //
++ BufferFilled = TRUE;
++
++ /* Leaves first u8 intact */
++ memset((PUCHAR)pTxDes + 1, 0, sizeof(DESCRIPTOR) - 1);
++
++ TxDesIndex = pMds->TxDesIndex;//Get the current ID
++ pTxDes->Descriptor_ID = TxDesIndex;
++ pMds->TxDesFrom[ TxDesIndex ] = 2;//Storing the information of source comming from
++ pMds->TxDesIndex++;
++ pMds->TxDesIndex %= MAX_USB_TX_DESCRIPTOR;
++
++ MLME_GetNextPacket( Adapter, pTxDes );
++
++ // Copy header. 8byte USB + 24byte 802.11Hdr. Set TxRate, Preamble type
++ Mds_HeaderCopy( Adapter, pTxDes, XmitBufAddress );
++
++ // For speed up Key setting
++ if (pTxDes->EapFix) {
++#ifdef _PE_TX_DUMP_
++ WBDEBUG(("35: EPA 4th frame detected. Size = %d\n", PacketSize));
++#endif
++ pHwData->IsKeyPreSet = 1;
++ }
++
++ // Copy (fragment) frame body, and set USB, 802.11 hdr flag
++ CurrentSize = Mds_BodyCopy(Adapter, pTxDes, XmitBufAddress);
++
++ // Set RTS/CTS and Normal duration field into buffer
++ Mds_DurationSet(Adapter, pTxDes, XmitBufAddress);
++
++ //
++ // Calculation MIC from buffer which maybe fragment, then fill into temporary address 8 byte
++ // 931130.5.e
++ if (MICAdd)
++ Mds_MicFill( Adapter, pTxDes, XmitBufAddress );
++
++ //Shift to the next address
++ XmitBufSize += CurrentSize;
++ XmitBufAddress += CurrentSize;
++
++#ifdef _IBSS_BEACON_SEQ_STICK_
++ if ((XmitBufAddress[ DOT_11_DA_OFFSET+8 ] & 0xfc) != MAC_SUBTYPE_MNGMNT_PROBE_REQUEST) // +8 for USB hdr
++#endif
++ pMds->TxToggle = TRUE;
++
++ // Get packet to transmit completed, 1:TESTSTA 2:MLME 3: Ndis data
++ MLME_SendComplete(Adapter, 0, TRUE);
++
++ // Software TSC count 20060214
++ pMds->TxTsc++;
++ if (pMds->TxTsc == 0)
++ pMds->TxTsc_2++;
++
++ FillCount++; // 20060928
++ } while (HAL_USB_MODE_BURST(pHwData)); // End of multiple MSDU copy loop. FALSE = single TRUE = multiple sending
++
++ // Move to the next one, if necessary
++ if (BufferFilled) {
++ // size setting
++ pMds->TxBufferSize[ FillIndex ] = XmitBufSize;
++
++ // 20060928 set Tx count
++ pMds->TxCountInBuffer[FillIndex] = FillCount;
++
++ // Set owner flag
++ pMds->TxOwner[FillIndex] = 1;
++
++ pMds->TxFillIndex++;
++ pMds->TxFillIndex %= MAX_USB_TX_BUFFER_NUMBER;
++ BufferFilled = FALSE;
++ } else
++ break;
++
++ if (!PacketSize) // No more pk for transmitting
++ break;
++
++ } while(TRUE);
++
++ //
++ // Start to send by lower module
++ //
++ if (!pHwData->IsKeyPreSet)
++ Wb35Tx_start(pHwData);
++
++ cleanup:
++ OS_ATOMIC_DEC( Adapter, &pMds->TxThreadCount );
++}
++
++void
++Mds_SendComplete(PADAPTER Adapter, PT02_DESCRIPTOR pT02)
++{
++ PMDS pMds = &Adapter->Mds;
++ phw_data_t pHwData = &Adapter->sHwData;
++ u8 PacketId = (u8)pT02->T02_Tx_PktID;
++ unsigned char SendOK = TRUE;
++ u8 RetryCount, TxRate;
++
++ if (pT02->T02_IgnoreResult) // Don't care the result
++ return;
++ if (pT02->T02_IsLastMpdu) {
++ //TODO: DTO -- get the retry count and fragment count
++ // Tx rate
++ TxRate = pMds->TxRate[ PacketId ][ 0 ];
++ RetryCount = (u8)pT02->T02_MPDU_Cnt;
++ if (pT02->value & FLAG_ERROR_TX_MASK) {
++ SendOK = FALSE;
++
++ if (pT02->T02_transmit_abort || pT02->T02_out_of_MaxTxMSDULiftTime) {
++ //retry error
++ pHwData->dto_tx_retry_count += (RetryCount+1);
++ //[for tx debug]
++ if (RetryCount<7)
++ pHwData->tx_retry_count[RetryCount] += RetryCount;
++ else
++ pHwData->tx_retry_count[7] += RetryCount;
++ #ifdef _PE_STATE_DUMP_
++ WBDEBUG(("dto_tx_retry_count =%d\n", pHwData->dto_tx_retry_count));
++ #endif
++ MTO_SetTxCount(Adapter, TxRate, RetryCount);
++ }
++ pHwData->dto_tx_frag_count += (RetryCount+1);
++
++ //[for tx debug]
++ if (pT02->T02_transmit_abort_due_to_TBTT)
++ pHwData->tx_TBTT_start_count++;
++ if (pT02->T02_transmit_without_encryption_due_to_wep_on_false)
++ pHwData->tx_WepOn_false_count++;
++ if (pT02->T02_discard_due_to_null_wep_key)
++ pHwData->tx_Null_key_count++;
++ } else {
++ if (pT02->T02_effective_transmission_rate)
++ pHwData->tx_ETR_count++;
++ MTO_SetTxCount(Adapter, TxRate, RetryCount);
++ }
++
++ // Clear send result buffer
++ pMds->TxResult[ PacketId ] = 0;
++ } else
++ pMds->TxResult[ PacketId ] |= ((u16)(pT02->value & 0x0ffff));
++}
++
++void
++Mds_HeaderCopy(PADAPTER Adapter, PDESCRIPTOR pDes, PUCHAR TargetBuffer)
++{
++ PMDS pMds = &Adapter->Mds;
++ PUCHAR src_buffer = pDes->buffer_address[0];//931130.5.g
++ PT00_DESCRIPTOR pT00;
++ PT01_DESCRIPTOR pT01;
++ u16 stmp;
++ u8 i, ctmp1, ctmp2, ctmpf;
++ u16 FragmentThreshold = CURRENT_FRAGMENT_THRESHOLD;
++
++
++ stmp = pDes->buffer_total_size;
++ //
++ // Set USB header 8 byte
++ //
++ pT00 = (PT00_DESCRIPTOR)TargetBuffer;
++ TargetBuffer += 4;
++ pT01 = (PT01_DESCRIPTOR)TargetBuffer;
++ TargetBuffer += 4;
++
++ pT00->value = 0;// Clear
++ pT01->value = 0;// Clear
++
++ pT00->T00_tx_packet_id = pDes->Descriptor_ID;// Set packet ID
++ pT00->T00_header_length = 24;// Set header length
++ pT01->T01_retry_abort_ebable = 1;//921013 931130.5.h
++
++ // Key ID setup
++ pT01->T01_wep_id = 0;
++
++ FragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD; //Do not fragment
++ // Copy full data, the 1'st buffer contain all the data 931130.5.j
++ memcpy( TargetBuffer, src_buffer, DOT_11_MAC_HEADER_SIZE );// Copy header
++ pDes->buffer_address[0] = src_buffer + DOT_11_MAC_HEADER_SIZE;
++ pDes->buffer_total_size -= DOT_11_MAC_HEADER_SIZE;
++ pDes->buffer_size[0] = pDes->buffer_total_size;
++
++ // Set fragment threshold
++ FragmentThreshold -= (DOT_11_MAC_HEADER_SIZE + 4);
++ pDes->FragmentThreshold = FragmentThreshold;
++
++ // Set more frag bit
++ TargetBuffer[1] |= 0x04;// Set more frag bit
++
++ //
++ // Set tx rate
++ //
++ stmp = *(PUSHORT)(TargetBuffer+30); // 2n alignment address
++
++ //Use basic rate
++ ctmp1 = ctmpf = CURRENT_TX_RATE_FOR_MNG;
++
++ pDes->TxRate = ctmp1;
++ #ifdef _PE_TX_DUMP_
++ WBDEBUG(("Tx rate =%x\n", ctmp1));
++ #endif
++
++ pT01->T01_modulation_type = (ctmp1%3) ? 0 : 1;
++
++ for( i=0; i<2; i++ ) {
++ if( i == 1 )
++ ctmp1 = ctmpf;
++
++ pMds->TxRate[pDes->Descriptor_ID][i] = ctmp1; // backup the ta rate and fall back rate
++
++ if( ctmp1 == 108) ctmp2 = 7;
++ else if( ctmp1 == 96 ) ctmp2 = 6; // Rate convert for USB
++ else if( ctmp1 == 72 ) ctmp2 = 5;
++ else if( ctmp1 == 48 ) ctmp2 = 4;
++ else if( ctmp1 == 36 ) ctmp2 = 3;
++ else if( ctmp1 == 24 ) ctmp2 = 2;
++ else if( ctmp1 == 18 ) ctmp2 = 1;
++ else if( ctmp1 == 12 ) ctmp2 = 0;
++ else if( ctmp1 == 22 ) ctmp2 = 3;
++ else if( ctmp1 == 11 ) ctmp2 = 2;
++ else if( ctmp1 == 4 ) ctmp2 = 1;
++ else ctmp2 = 0; // if( ctmp1 == 2 ) or default
++
++ if( i == 0 )
++ pT01->T01_transmit_rate = ctmp2;
++ else
++ pT01->T01_fall_back_rate = ctmp2;
++ }
++
++ //
++ // Set preamble type
++ //
++ if ((pT01->T01_modulation_type == 0) && (pT01->T01_transmit_rate == 0)) // RATE_1M
++ pDes->PreambleMode = WLAN_PREAMBLE_TYPE_LONG;
++ else
++ pDes->PreambleMode = CURRENT_PREAMBLE_MODE;
++ pT01->T01_plcp_header_length = pDes->PreambleMode; // Set preamble
++
++}
++
++// The function return the 4n size of usb pk
++u16
++Mds_BodyCopy(PADAPTER Adapter, PDESCRIPTOR pDes, PUCHAR TargetBuffer)
++{
++ PT00_DESCRIPTOR pT00;
++ PMDS pMds = &Adapter->Mds;
++ PUCHAR buffer, src_buffer, pctmp;
++ u16 Size = 0;
++ u16 SizeLeft, CopySize, CopyLeft, stmp;
++ u8 buf_index, FragmentCount = 0;
++
++
++ // Copy fragment body
++ buffer = TargetBuffer; // shift 8B usb + 24B 802.11
++ SizeLeft = pDes->buffer_total_size;
++ buf_index = pDes->buffer_start_index;
++
++ pT00 = (PT00_DESCRIPTOR)buffer;
++ while (SizeLeft) {
++ pT00 = (PT00_DESCRIPTOR)buffer;
++ CopySize = SizeLeft;
++ if (SizeLeft > pDes->FragmentThreshold) {
++ CopySize = pDes->FragmentThreshold;
++ pT00->T00_frame_length = 24 + CopySize;//Set USB length
++ } else
++ pT00->T00_frame_length = 24 + SizeLeft;//Set USB length
++
++ SizeLeft -= CopySize;
++
++ // 1 Byte operation
++ pctmp = (PUCHAR)( buffer + 8 + DOT_11_SEQUENCE_OFFSET );
++ *pctmp &= 0xf0;
++ *pctmp |= FragmentCount;//931130.5.m
++ if( !FragmentCount )
++ pT00->T00_first_mpdu = 1;
++
++ buffer += 32; // 8B usb + 24B 802.11 header
++ Size += 32;
++
++ // Copy into buffer
++ stmp = CopySize + 3;
++ stmp &= ~0x03;//4n Alignment
++ Size += stmp;// Current 4n offset of mpdu
++
++ while (CopySize) {
++ // Copy body
++ src_buffer = pDes->buffer_address[buf_index];
++ CopyLeft = CopySize;
++ if (CopySize >= pDes->buffer_size[buf_index]) {
++ CopyLeft = pDes->buffer_size[buf_index];
++
++ // Get the next buffer of descriptor
++ buf_index++;
++ buf_index %= MAX_DESCRIPTOR_BUFFER_INDEX;
++ } else {
++ PUCHAR pctmp = pDes->buffer_address[buf_index];
++ pctmp += CopySize;
++ pDes->buffer_address[buf_index] = pctmp;
++ pDes->buffer_size[buf_index] -= CopySize;
++ }
++
++ memcpy(buffer, src_buffer, CopyLeft);
++ buffer += CopyLeft;
++ CopySize -= CopyLeft;
++ }
++
++ // 931130.5.n
++ if (pMds->MicAdd) {
++ if (!SizeLeft) {
++ pMds->MicWriteAddress[ pMds->MicWriteIndex ] = buffer - pMds->MicAdd;
++ pMds->MicWriteSize[ pMds->MicWriteIndex ] = pMds->MicAdd;
++ pMds->MicAdd = 0;
++ }
++ else if( SizeLeft < 8 ) //931130.5.p
++ {
++ pMds->MicAdd = SizeLeft;
++ pMds->MicWriteAddress[ pMds->MicWriteIndex ] = buffer - ( 8 - SizeLeft );
++ pMds->MicWriteSize[ pMds->MicWriteIndex ] = 8 - SizeLeft;
++ pMds->MicWriteIndex++;
++ }
++ }
++
++ // Does it need to generate the new header for next mpdu?
++ if (SizeLeft) {
++ buffer = TargetBuffer + Size; // Get the next 4n start address
++ memcpy( buffer, TargetBuffer, 32 );//Copy 8B USB +24B 802.11
++ pT00 = (PT00_DESCRIPTOR)buffer;
++ pT00->T00_first_mpdu = 0;
++ }
++
++ FragmentCount++;
++ }
++
++ pT00->T00_last_mpdu = 1;
++ pT00->T00_IsLastMpdu = 1;
++ buffer = (PUCHAR)pT00 + 8; // +8 for USB hdr
++ buffer[1] &= ~0x04; // Clear more frag bit of 802.11 frame control
++ pDes->FragmentCount = FragmentCount; // Update the correct fragment number
++ return Size;
++}
++
++
++void
++Mds_DurationSet( PADAPTER Adapter, PDESCRIPTOR pDes, PUCHAR buffer )
++{
++ PT00_DESCRIPTOR pT00;
++ PT01_DESCRIPTOR pT01;
++ u16 Duration, NextBodyLen, OffsetSize;
++ u8 Rate, i;
++ unsigned char CTS_on = FALSE, RTS_on = FALSE;
++ PT00_DESCRIPTOR pNextT00;
++ u16 BodyLen;
++ unsigned char boGroupAddr = FALSE;
++
++
++ OffsetSize = pDes->FragmentThreshold + 32 + 3;
++ OffsetSize &= ~0x03;
++ Rate = pDes->TxRate >> 1;
++ if (!Rate)
++ Rate = 1;
++
++ pT00 = (PT00_DESCRIPTOR)buffer;
++ pT01 = (PT01_DESCRIPTOR)(buffer+4);
++ pNextT00 = (PT00_DESCRIPTOR)(buffer+OffsetSize);
++
++ if( buffer[ DOT_11_DA_OFFSET+8 ] & 0x1 ) // +8 for USB hdr
++ boGroupAddr = TRUE;
++
++ //========================================
++ // Set RTS/CTS mechanism
++ //========================================
++ if (!boGroupAddr)
++ {
++ //NOTE : If the protection mode is enabled and the MSDU will be fragmented,
++ // the tx rates of MPDUs will all be DSSS rates. So it will not use
++ // CTS-to-self in this case. CTS-To-self will only be used when without
++ // fragmentation. -- 20050112
++ BodyLen = (u16)pT00->T00_frame_length; //include 802.11 header
++ BodyLen += 4; //CRC
++
++ if( BodyLen >= CURRENT_RTS_THRESHOLD )
++ RTS_on = TRUE; // Using RTS
++ else
++ {
++ if( pT01->T01_modulation_type ) // Is using OFDM
++ {
++ if( CURRENT_PROTECT_MECHANISM ) // Is using protect
++ CTS_on = TRUE; // Using CTS
++ }
++ }
++ }
++
++ if( RTS_on || CTS_on )
++ {
++ if( pT01->T01_modulation_type) // Is using OFDM
++ {
++ //CTS duration
++ // 2 SIFS + DATA transmit time + 1 ACK
++ // ACK Rate : 24 Mega bps
++ // ACK frame length = 14 bytes
++ Duration = 2*DEFAULT_SIFSTIME +
++ 2*PREAMBLE_PLUS_SIGNAL_PLUS_SIGNALEXTENSION +
++ ((BodyLen*8 + 22 + Rate*4 - 1)/(Rate*4))*Tsym +
++ ((112 + 22 + 95)/96)*Tsym;
++ }
++ else //DSSS
++ {
++ //CTS duration
++ // 2 SIFS + DATA transmit time + 1 ACK
++ // Rate : ?? Mega bps
++ // ACK frame length = 14 bytes
++ if( pT01->T01_plcp_header_length ) //long preamble
++ Duration = LONG_PREAMBLE_PLUS_PLCPHEADER_TIME*2;
++ else
++ Duration = SHORT_PREAMBLE_PLUS_PLCPHEADER_TIME*2;
++
++ Duration += ( ((BodyLen + 14)*8 + Rate-1) / Rate +
++ DEFAULT_SIFSTIME*2 );
++ }
++
++ if( RTS_on )
++ {
++ if( pT01->T01_modulation_type ) // Is using OFDM
++ {
++ //CTS + 1 SIFS + CTS duration
++ //CTS Rate : 24 Mega bps
++ //CTS frame length = 14 bytes
++ Duration += (DEFAULT_SIFSTIME +
++ PREAMBLE_PLUS_SIGNAL_PLUS_SIGNALEXTENSION +
++ ((112 + 22 + 95)/96)*Tsym);
++ }
++ else
++ {
++ //CTS + 1 SIFS + CTS duration
++ //CTS Rate : ?? Mega bps
++ //CTS frame length = 14 bytes
++ if( pT01->T01_plcp_header_length ) //long preamble
++ Duration += LONG_PREAMBLE_PLUS_PLCPHEADER_TIME;
++ else
++ Duration += SHORT_PREAMBLE_PLUS_PLCPHEADER_TIME;
++
++ Duration += ( ((112 + Rate-1) / Rate) + DEFAULT_SIFSTIME );
++ }
++ }
++
++ // Set the value into USB descriptor
++ pT01->T01_add_rts = RTS_on ? 1 : 0;
++ pT01->T01_add_cts = CTS_on ? 1 : 0;
++ pT01->T01_rts_cts_duration = Duration;
++ }
++
++ //=====================================
++ // Fill the more fragment descriptor
++ //=====================================
++ if( boGroupAddr )
++ Duration = 0;
++ else
++ {
++ for( i=pDes->FragmentCount-1; i>0; i-- )
++ {
++ NextBodyLen = (u16)pNextT00->T00_frame_length;
++ NextBodyLen += 4; //CRC
++
++ if( pT01->T01_modulation_type )
++ {
++ //OFDM
++ // data transmit time + 3 SIFS + 2 ACK
++ // Rate : ??Mega bps
++ // ACK frame length = 14 bytes, tx rate = 24M
++ Duration = PREAMBLE_PLUS_SIGNAL_PLUS_SIGNALEXTENSION * 3;
++ Duration += (((NextBodyLen*8 + 22 + Rate*4 - 1)/(Rate*4)) * Tsym +
++ (((2*14)*8 + 22 + 95)/96)*Tsym +
++ DEFAULT_SIFSTIME*3);
++ }
++ else
++ {
++ //DSSS
++ // data transmit time + 2 ACK + 3 SIFS
++ // Rate : ??Mega bps
++ // ACK frame length = 14 bytes
++ //TODO :
++ if( pT01->T01_plcp_header_length ) //long preamble
++ Duration = LONG_PREAMBLE_PLUS_PLCPHEADER_TIME*3;
++ else
++ Duration = SHORT_PREAMBLE_PLUS_PLCPHEADER_TIME*3;
++
++ Duration += ( ((NextBodyLen + (2*14))*8 + Rate-1) / Rate +
++ DEFAULT_SIFSTIME*3 );
++ }
++
++ ((PUSHORT)buffer)[5] = cpu_to_le16(Duration);// 4 USHOR for skip 8B USB, 2USHORT=FC + Duration
++
++ //----20061009 add by anson's endian
++ pNextT00->value = cpu_to_le32(pNextT00->value);
++ pT01->value = cpu_to_le32( pT01->value );
++ //----end 20061009 add by anson's endian
++
++ buffer += OffsetSize;
++ pT01 = (PT01_DESCRIPTOR)(buffer+4);
++ if (i != 1) //The last fragment will not have the next fragment
++ pNextT00 = (PT00_DESCRIPTOR)(buffer+OffsetSize);
++ }
++
++ //=====================================
++ // Fill the last fragment descriptor
++ //=====================================
++ if( pT01->T01_modulation_type )
++ {
++ //OFDM
++ // 1 SIFS + 1 ACK
++ // Rate : 24 Mega bps
++ // ACK frame length = 14 bytes
++ Duration = PREAMBLE_PLUS_SIGNAL_PLUS_SIGNALEXTENSION;
++ //The Tx rate of ACK use 24M
++ Duration += (((112 + 22 + 95)/96)*Tsym + DEFAULT_SIFSTIME );
++ }
++ else
++ {
++ // DSSS
++ // 1 ACK + 1 SIFS
++ // Rate : ?? Mega bps
++ // ACK frame length = 14 bytes(112 bits)
++ if( pT01->T01_plcp_header_length ) //long preamble
++ Duration = LONG_PREAMBLE_PLUS_PLCPHEADER_TIME;
++ else
++ Duration = SHORT_PREAMBLE_PLUS_PLCPHEADER_TIME;
++
++ Duration += ( (112 + Rate-1)/Rate + DEFAULT_SIFSTIME );
++ }
++ }
++
++ ((PUSHORT)buffer)[5] = cpu_to_le16(Duration);// 4 USHOR for skip 8B USB, 2USHORT=FC + Duration
++ pT00->value = cpu_to_le32(pT00->value);
++ pT01->value = cpu_to_le32(pT01->value);
++ //--end 20061009 add
++
++}
++
++void MDS_EthernetPacketReceive( PADAPTER Adapter, PRXLAYER1 pRxLayer1 )
++{
++ OS_RECEIVE_PACKET_INDICATE( Adapter, pRxLayer1 );
++}
++
++
+diff --git a/drivers/staging/winbond/mds_f.h b/drivers/staging/winbond/mds_f.h
+new file mode 100644
+index 0000000..651188b
+--- /dev/null
++++ b/drivers/staging/winbond/mds_f.h
+@@ -0,0 +1,33 @@
++unsigned char Mds_initial( PADAPTER Adapter );
++void Mds_Destroy( PADAPTER Adapter );
++void Mds_Tx( PADAPTER Adapter );
++void Mds_HeaderCopy( PADAPTER Adapter, PDESCRIPTOR pDes, PUCHAR TargetBuffer );
++u16 Mds_BodyCopy( PADAPTER Adapter, PDESCRIPTOR pDes, PUCHAR TargetBuffer );
++void Mds_DurationSet( PADAPTER Adapter, PDESCRIPTOR pDes, PUCHAR TargetBuffer );
++void Mds_SendComplete( PADAPTER Adapter, PT02_DESCRIPTOR pT02 );
++void Mds_MpduProcess( PADAPTER Adapter, PDESCRIPTOR pRxDes );
++void Mds_reset_descriptor( PADAPTER Adapter );
++extern void DataDmp(u8 *pdata, u32 len, u32 offset);
++
++
++void vRxTimerInit(PWB32_ADAPTER Adapter);
++void vRxTimerStart(PWB32_ADAPTER Adapter, int timeout_value);
++void RxTimerHandler_1a( PADAPTER Adapter);
++void vRxTimerStop(PWB32_ADAPTER Adapter);
++void RxTimerHandler( void* SystemSpecific1,
++ PWB32_ADAPTER Adapter,
++ void* SystemSpecific2,
++ void* SystemSpecific3);
++
++
++// For Asynchronous indicating. The routine collocates with USB.
++void Mds_MsduProcess( PWB32_ADAPTER Adapter, PRXLAYER1 pRxLayer1, u8 SlotIndex);
++
++// For data frame sending 20060802
++u16 MDS_GetPacketSize( PADAPTER Adapter );
++void MDS_GetNextPacket( PADAPTER Adapter, PDESCRIPTOR pDes );
++void MDS_GetNextPacketComplete( PADAPTER Adapter, PDESCRIPTOR pDes );
++void MDS_SendResult( PADAPTER Adapter, u8 PacketId, unsigned char SendOK );
++void MDS_EthernetPacketReceive( PADAPTER Adapter, PRXLAYER1 pRxLayer1 );
++
++
+diff --git a/drivers/staging/winbond/mds_s.h b/drivers/staging/winbond/mds_s.h
+new file mode 100644
+index 0000000..4738279
+--- /dev/null
++++ b/drivers/staging/winbond/mds_s.h
+@@ -0,0 +1,183 @@
++////////////////////////////////////////////////////////////////////////////////////////////////////////
++#define MAX_USB_TX_DESCRIPTOR 15 // IS89C35 ability
++#define MAX_USB_TX_BUFFER_NUMBER 4 // Virtual pre-buffer number of MAX_USB_TX_BUFFER
++#define MAX_USB_TX_BUFFER 4096 // IS89C35 ability 4n alignment is required for hardware
++
++#define MDS_EVENT_INDICATE( _A, _B, _F ) OS_EVENT_INDICATE( _A, _B, _F )
++#define AUTH_REQUEST_PAIRWISE_ERROR 0 // _F flag setting
++#define AUTH_REQUEST_GROUP_ERROR 1 // _F flag setting
++
++// For variable setting
++#define CURRENT_BSS_TYPE psBSS(psLOCAL->wConnectedSTAindex)->bBssType
++#define CURRENT_WEP_MODE psSME->_dot11PrivacyInvoked
++#define CURRENT_BSSID psBSS(psLOCAL->wConnectedSTAindex)->abBssID
++#define CURRENT_DESIRED_WPA_ENABLE ((psSME->bDesiredAuthMode==WPA_AUTH)||(psSME->bDesiredAuthMode==WPAPSK_AUTH))
++#ifdef _WPA2_
++#define CURRENT_DESIRED_WPA2_ENABLE ((psSME->bDesiredAuthMode==WPA2_AUTH)||(psSME->bDesiredAuthMode==WPA2PSK_AUTH))
++#endif //end def _WPA2_
++#define CURRENT_PAIRWISE_KEY_OK psSME->pairwise_key_ok
++//[20040712 WS]
++#define CURRENT_GROUP_KEY_OK psSME->group_key_ok
++#define CURRENT_PAIRWISE_KEY psSME->tx_mic_key
++#define CURRENT_GROUP_KEY psSME->group_tx_mic_key
++#define CURRENT_ENCRYPT_STATUS psSME->encrypt_status
++#define CURRENT_WEP_ID Adapter->sSmePara._dot11WEPDefaultKeyID
++#define CURRENT_CONTROL_PORT_BLOCK ( psSME->wpa_ok!=1 || (Adapter->Mds.boCounterMeasureBlock==1 && (CURRENT_ENCRYPT_STATUS==ENCRYPT_TKIP)) )
++#define CURRENT_FRAGMENT_THRESHOLD (Adapter->Mds.TxFragmentThreshold & ~0x1)
++#define CURRENT_PREAMBLE_MODE psLOCAL->boShortPreamble?WLAN_PREAMBLE_TYPE_SHORT:WLAN_PREAMBLE_TYPE_LONG
++#define CURRENT_LINK_ON OS_LINK_STATUS
++#define CURRENT_TX_RATE Adapter->sLocalPara.CurrentTxRate
++#define CURRENT_FALL_BACK_TX_RATE Adapter->sLocalPara.CurrentTxFallbackRate
++#define CURRENT_TX_RATE_FOR_MNG Adapter->sLocalPara.CurrentTxRateForMng
++#define CURRENT_PROTECT_MECHANISM psLOCAL->boProtectMechanism
++#define CURRENT_RTS_THRESHOLD Adapter->Mds.TxRTSThreshold
++
++#define MIB_GS_XMIT_OK_INC Adapter->sLocalPara.GS_XMIT_OK++
++#define MIB_GS_RCV_OK_INC Adapter->sLocalPara.GS_RCV_OK++
++#define MIB_GS_XMIT_ERROR_INC Adapter->sLocalPara.GS_XMIT_ERROR
++
++//---------- TX -----------------------------------
++#define ETHERNET_TX_DESCRIPTORS MAX_USB_TX_BUFFER_NUMBER
++
++//---------- RX ------------------------------------
++#define ETHERNET_RX_DESCRIPTORS 8 //It's not necessary to allocate more than 2 in sync indicate
++
++//================================================================
++// Configration default value
++//================================================================
++#define DEFAULT_MULTICASTLISTMAX 32 // standard
++#define DEFAULT_TX_BURSTLENGTH 3 // 32 Longwords
++#define DEFAULT_RX_BURSTLENGTH 3 // 32 Longwords
++#define DEFAULT_TX_THRESHOLD 0 // Full Packet
++#define DEFAULT_RX_THRESHOLD 0 // Full Packet
++#define DEFAULT_MAXTXRATE 6 // 11 Mbps (Long)
++#define DEFAULT_CHANNEL 3 // Chennel 3
++#define DEFAULT_RTSThreshold 2347 // Disable RTS
++//#define DEFAULT_PME 1 // Enable
++#define DEFAULT_PME 0 // Disable
++#define DEFAULT_SIFSTIME 10
++#define DEFAULT_ACKTIME_1ML 304 // 148+44+112 911220 by LCC
++#define DEFAULT_ACKTIME_2ML 248 // 148+44+56 911220 by LCC
++#define DEFAULT_FRAGMENT_THRESHOLD 2346 // No fragment
++#define DEFAULT_PREAMBLE_LENGTH 72
++#define DEFAULT_PLCPHEADERTIME_LENGTH 24
++
++/*------------------------------------------------------------------------
++ 0.96 sec since time unit of the R03 for the current, W89C32 is about 60ns
++ instead of 960 ns. This shall be fixed in the future W89C32
++ -------------------------------------------------------------------------*/
++#define DEFAULT_MAX_RECEIVE_TIME 16440000
++
++#define RX_BUF_SIZE 2352 // 600 // For 301 must be multiple of 8
++#define MAX_RX_DESCRIPTORS 18 // Rx Layer 2
++#define MAX_BUFFER_QUEUE 8 // The value is always equal 8 due to NDIS_PACKET's MiniportReserved field size
++
++
++// For brand-new rx system
++#define MDS_ID_IGNORE ETHERNET_RX_DESCRIPTORS
++
++// For Tx Packet status classify
++#define PACKET_FREE_TO_USE 0
++#define PACKET_COME_FROM_NDIS 0x08
++#define PACKET_COME_FROM_MLME 0x80
++#define PACKET_SEND_COMPLETE 0xff
++
++typedef struct _MDS
++{
++ // For Tx usage
++ u8 TxOwner[ ((MAX_USB_TX_BUFFER_NUMBER + 3) & ~0x03) ];
++ PUCHAR pTxBuffer;
++ u16 TxBufferSize[ ((MAX_USB_TX_BUFFER_NUMBER + 1) & ~0x01) ];
++ u8 TxDesFrom[ ((MAX_USB_TX_DESCRIPTOR + 3) & ~0x03) ];//931130.4.u // 1: MLME 2: NDIS control 3: NDIS data
++ u8 TxCountInBuffer[ ((MAX_USB_TX_DESCRIPTOR + 3) & ~0x03) ]; // 20060928
++
++ u8 TxFillIndex;//the next index of TxBuffer can be used
++ u8 TxDesIndex;//The next index of TxDes can be used
++ u8 ScanTxPause; //data Tx pause because the scanning is progressing, but probe request Tx won't.
++ u8 TxPause;//For pause the Mds_Tx modult
++
++ OS_ATOMIC TxThreadCount;//For thread counting 931130.4.v
++//950301 delete due to HW
++// OS_ATOMIC TxConcurrentCount;//931130.4.w
++
++ u16 TxResult[ ((MAX_USB_TX_DESCRIPTOR + 1) & ~0x01) ];//Collect the sending result of Mpdu
++
++ u8 MicRedundant[8]; // For tmp use
++ PUCHAR MicWriteAddress[2]; //The start address to fill the Mic, use 2 point due to Mic maybe fragment
++
++ u16 MicWriteSize[2]; //931130.4.x
++
++ u16 MicAdd; // If want to add the Mic, this variable equal to 8
++ u16 MicWriteIndex;//The number of MicWriteAddress 931130.4.y
++
++ u8 TxRate[ ((MAX_USB_TX_DESCRIPTOR+1)&~0x01) ][2]; // [0] current tx rate, [1] fall back rate
++ u8 TxInfo[ ((MAX_USB_TX_DESCRIPTOR+1)&~0x01) ]; //Store information for callback function
++
++ //WKCHEN added for scanning mechanism
++ u8 TxToggle; //It is TRUE if there are tx activities in some time interval
++ u8 Reserved_[3];
++
++ //---------- for Tx Parameter
++ u16 TxFragmentThreshold; // For frame body only
++ u16 TxRTSThreshold;
++
++ u32 MaxReceiveTime;//911220.3 Add
++
++ // depend on OS,
++ u32 MulticastListNo;
++ u32 PacketFilter; // Setting by NDIS, the current packet filter in use.
++ u8 MulticastAddressesArray[DEFAULT_MULTICASTLISTMAX][MAC_ADDR_LENGTH];
++
++ //COUNTERMEASURE
++ u8 bMICfailCount;
++ u8 boCounterMeasureBlock;
++ u8 reserved_4[2];
++
++ //NDIS_MINIPORT_TIMER nTimer;
++ OS_TIMER nTimer;
++
++ u32 TxTsc; // 20060214
++ u32 TxTsc_2; // 20060214
++
++} MDS, *PMDS;
++
++
++typedef struct _RxBuffer
++{
++ PUCHAR pBufferAddress; // Pointer the received data buffer.
++ u16 BufferSize;
++ u8 RESERVED;
++ u8 BufferIndex;// Only 1 byte
++} RXBUFFER, *PRXBUFFER;
++
++//
++// Reveive Layer 1 Format.
++//----------------------------
++typedef struct _RXLAYER1
++{
++ u16 SequenceNumber; // The sequence number of the last received packet.
++ u16 BufferTotalSize;
++
++ u32 InUsed;
++ u32 DecryptionMethod; // The desired defragment number of the next incoming packet.
++
++ u8 DeFragmentNumber;
++ u8 FrameType;
++ u8 TypeEncapsulated;
++ u8 BufferNumber;
++
++ u32 FirstFrameArrivedTime;
++
++ RXBUFFER BufferQueue[ MAX_BUFFER_QUEUE ];
++
++ u8 LastFrameType; // 20061004 for fix intel 3945 's bug
++ u8 RESERVED[3]; //@@ anson
++
++ /////////////////////////////////////////////////////////////////////////////////////////////
++ // For brand-new Rx system
++ u8 ReservedBuffer[ 2400 ];//If Buffer ID is reserved one, it must copy the data into this area
++ PUCHAR ReservedBufferPoint;// Point to the next availabe address of reserved buffer
++
++}RXLAYER1, * PRXLAYER1;
++
++
+diff --git a/drivers/staging/winbond/mlme_mib.h b/drivers/staging/winbond/mlme_mib.h
+new file mode 100644
+index 0000000..8975973
+--- /dev/null
++++ b/drivers/staging/winbond/mlme_mib.h
+@@ -0,0 +1,84 @@
++//============================================================================
++// MLMEMIB.H -
++//
++// Description:
++// Get and Set some of MLME MIB attributes.
++//
++// Revision history:
++// --------------------------------------------------------------------------
++// 20030117 PD43 Austin Liu
++// Initial release
++//
++// Copyright (c) 2003 Winbond Electronics Corp. All rights reserved.
++//============================================================================
++
++#ifndef _MLME_MIB_H
++#define _MLME_MIB_H
++
++//============================================================================
++// MLMESetExcludeUnencrypted --
++//
++// Description:
++// Set the dot11ExcludeUnencrypted value.
++//
++// Arguments:
++// Adapter - The pointer to the miniport adapter context.
++// ExUnencrypted - unsigned char type. The value to be set.
++//
++// Return values:
++// None.
++//============================================================================
++#define MLMESetExcludeUnencrypted(Adapter, ExUnencrypted) \
++{ \
++ (Adapter)->sLocalPara.ExcludeUnencrypted = ExUnencrypted; \
++}
++
++//============================================================================
++// MLMEGetExcludeUnencrypted --
++//
++// Description:
++// Get the dot11ExcludeUnencrypted value.
++//
++// Arguments:
++// Adapter - The pointer to the miniport adapter context.
++//
++// Return values:
++// unsigned char type. The current dot11ExcludeUnencrypted value.
++//============================================================================
++#define MLMEGetExcludeUnencrypted(Adapter) ((unsigned char) (Adapter)->sLocalPara.ExcludeUnencrypted)
++
++//============================================================================
++// MLMESetMaxReceiveLifeTime --
++//
++// Description:
++// Set the dot11MaxReceiveLifeTime value.
++//
++// Arguments:
++// Adapter - The pointer to the miniport adapter context.
++// ReceiveLifeTime- u32 type. The value to be set.
++//
++// Return values:
++// None.
++//============================================================================
++#define MLMESetMaxReceiveLifeTime(Adapter, ReceiveLifeTime) \
++{ \
++ (Adapter)->Mds.MaxReceiveTime = ReceiveLifeTime; \
++}
++
++//============================================================================
++// MLMESetMaxReceiveLifeTime --
++//
++// Description:
++// Get the dot11MaxReceiveLifeTime value.
++//
++// Arguments:
++// Adapter - The pointer to the miniport adapter context.
++//
++// Return values:
++// u32 type. The current dot11MaxReceiveLifeTime value.
++//============================================================================
++#define MLMEGetMaxReceiveLifeTime(Adapter) ((u32) (Adapter)->Mds.MaxReceiveTime)
++
++#endif
++
++
+diff --git a/drivers/staging/winbond/mlme_s.h b/drivers/staging/winbond/mlme_s.h
+new file mode 100644
+index 0000000..58094f6
+--- /dev/null
++++ b/drivers/staging/winbond/mlme_s.h
+@@ -0,0 +1,195 @@
++//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++// Mlme.h
++// Define the related definitions of MLME module
++// history -- 01/14/03' created
++//
++//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++
++#define AUTH_REJECT_REASON_CHALLENGE_FAIL 1
++
++//====== the state of MLME module
++#define INACTIVE 0x0
++#define IDLE_SCAN 0x1
++
++//====== the state of MLME/ESS module
++#define STATE_1 0x2
++#define AUTH_REQ 0x3
++#define AUTH_WEP 0x4
++#define STATE_2 0x5
++#define ASSOC_REQ 0x6
++#define STATE_3 0x7
++
++//====== the state of MLME/IBSS module
++#define IBSS_JOIN_SYNC 0x8
++#define IBSS_AUTH_REQ 0x9
++#define IBSS_AUTH_CHANLGE 0xa
++#define IBSS_AUTH_WEP 0xb
++#define IBSS_AUTH_IND 0xc
++#define IBSS_STATE_2 0xd
++
++
++
++//=========================================
++//depend on D5C(MAC timing control 03 register): MaxTxMSDULifeTime default 0x80000us
++#define AUTH_FAIL_TIMEOUT 550
++#define ASSOC_FAIL_TIMEOUT 550
++#define REASSOC_FAIL_TIMEOUT 550
++
++
++
++//
++// MLME task global CONSTANTS, STRUCTURE, variables
++//
++
++
++/////////////////////////////////////////////////////////////
++// enum_ResultCode --
++// Result code returned from MLME to SME.
++//
++/////////////////////////////////////////////////////////////
++// PD43 20030829 Modifiled
++//#define SUCCESS 0
++#define MLME_SUCCESS 0 //follow spec.
++#define INVALID_PARAMETERS 1 //Not following spec.
++#define NOT_SUPPPORTED 2
++#define TIMEOUT 3
++#define TOO_MANY_SIMULTANEOUS_REQUESTS 4
++#define REFUSED 5
++#define BSS_ALREADY_STARTED_OR_JOINED 6
++#define TRANSMIT_FRAME_FAIL 7
++#define NO_BSS_FOUND 8
++#define RETRY 9
++#define GIVE_UP 10
++
++
++#define OPEN_AUTH 0
++#define SHARE_AUTH 1
++#define ANY_AUTH 2
++#define WPA_AUTH 3 //for WPA
++#define WPAPSK_AUTH 4
++#define WPANONE_AUTH 5
++///////////////////////////////////////////// added by ws 04/19/04
++#ifdef _WPA2_
++#define WPA2_AUTH 6//for WPA2
++#define WPA2PSK_AUTH 7
++#endif //end def _WPA2_
++
++//////////////////////////////////////////////////////////////////
++//define the msg type of MLME module
++//////////////////////////////////////////////////////////////////
++//--------------------------------------------------------
++//from SME
++
++#define MLMEMSG_AUTH_REQ 0x0b
++#define MLMEMSG_DEAUTH_REQ 0x0c
++#define MLMEMSG_ASSOC_REQ 0x0d
++#define MLMEMSG_REASSOC_REQ 0x0e
++#define MLMEMSG_DISASSOC_REQ 0x0f
++#define MLMEMSG_START_IBSS_REQ 0x10
++#define MLMEMSG_IBSS_NET_CFM 0x11
++
++//from RX :
++#define MLMEMSG_RCV_MLMEFRAME 0x20
++#define MLMEMSG_RCV_ASSOCRSP 0x22
++#define MLMEMSG_RCV_REASSOCRSP 0x24
++#define MLMEMSG_RCV_DISASSOC 0x2b
++#define MLMEMSG_RCV_AUTH 0x2c
++#define MLMEMSG_RCV_DEAUTH 0x2d
++
++
++//from TX callback
++#define MLMEMSG_TX_CALLBACK 0x40
++#define MLMEMSG_ASSOCREQ_CALLBACK 0x41
++#define MLMEMSG_REASSOCREQ_CALLBACK 0x43
++#define MLMEMSG_DISASSOC_CALLBACK 0x4a
++#define MLMEMSG_AUTH_CALLBACK 0x4c
++#define MLMEMSG_DEAUTH_CALLBACK 0x4d
++
++//#define MLMEMSG_JOIN_FAIL 4
++//#define MLMEMSG_AUTHEN_FAIL 18
++#define MLMEMSG_TIMEOUT 0x50
++
++///////////////////////////////////////////////////////////////////////////
++//Global data structures
++#define MAX_NUM_TX_MMPDU 2
++#define MAX_MMPDU_SIZE 1512
++#define MAX_NUM_RX_MMPDU 6
++
++
++///////////////////////////////////////////////////////////////////////////
++//MACRO
++#define boMLME_InactiveState(_AA_) (_AA_->wState==INACTIVE)
++#define boMLME_IdleScanState(_BB_) (_BB_->wState==IDLE_SCAN)
++#define boMLME_FoundSTAinfo(_CC_) (_CC_->wState>=IDLE_SCAN)
++
++typedef struct _MLME_FRAME
++{
++ //NDIS_PACKET MLME_Packet;
++ PCHAR pMMPDU;
++ u16 len;
++ u8 DataType;
++ u8 IsInUsed;
++
++ OS_SPIN_LOCK MLMESpinLock;
++
++ u8 TxMMPDU[MAX_NUM_TX_MMPDU][MAX_MMPDU_SIZE];
++ u8 TxMMPDUInUse[ (MAX_NUM_TX_MMPDU+3) & ~0x03 ];
++
++ u16 wNumTxMMPDU;
++ u16 wNumTxMMPDUDiscarded;
++
++ u8 RxMMPDU[MAX_NUM_RX_MMPDU][MAX_MMPDU_SIZE];
++ u8 SaveRxBufSlotInUse[ (MAX_NUM_RX_MMPDU+3) & ~0x03 ];
++
++ u16 wNumRxMMPDU;
++ u16 wNumRxMMPDUDiscarded;
++
++ u16 wNumRxMMPDUInMLME; // Number of the Rx MMPDU
++ u16 reserved_1; // in MLME.
++ // excluding the discarded
++} MLME_FRAME, *psMLME_FRAME;
++
++typedef struct _AUTHREQ {
++
++ u8 peerMACaddr[MAC_ADDR_LENGTH];
++ u16 wAuthAlgorithm;
++
++} MLME_AUTHREQ_PARA, *psMLME_AUTHREQ_PARA;
++
++struct _Reason_Code {
++
++ u8 peerMACaddr[MAC_ADDR_LENGTH];
++ u16 wReasonCode;
++};
++typedef struct _Reason_Code MLME_DEAUTHREQ_PARA, *psMLME_DEAUTHREQ_PARA;
++typedef struct _Reason_Code MLME_DISASSOCREQ_PARA, *psMLME_DISASSOCREQ_PARA;
++
++typedef struct _ASSOCREQ {
++ u8 PeerSTAAddr[MAC_ADDR_LENGTH];
++ u16 CapabilityInfo;
++ u16 ListenInterval;
++
++}__attribute__ ((packed)) MLME_ASSOCREQ_PARA, *psMLME_ASSOCREQ_PARA;
++
++typedef struct _REASSOCREQ {
++ u8 NewAPAddr[MAC_ADDR_LENGTH];
++ u16 CapabilityInfo;
++ u16 ListenInterval;
++
++}__attribute__ ((packed)) MLME_REASSOCREQ_PARA, *psMLME_REASSOCREQ_PARA;
++
++typedef struct _MLMECALLBACK {
++
++ u8 *psFramePtr;
++ u8 bResult;
++
++} MLME_TXCALLBACK, *psMLME_TXCALLBACK;
++
++typedef struct _RXDATA
++{
++ s32 FrameLength;
++ u8 __attribute__ ((packed)) *pbFramePtr;
++
++}__attribute__ ((packed)) RXDATA, *psRXDATA;
++
++
+diff --git a/drivers/staging/winbond/mlmetxrx.c b/drivers/staging/winbond/mlmetxrx.c
+new file mode 100644
+index 0000000..46b091e
+--- /dev/null
++++ b/drivers/staging/winbond/mlmetxrx.c
+@@ -0,0 +1,150 @@
++//============================================================================
++// Module Name:
++// MLMETxRx.C
++//
++// Description:
++// The interface between MDS (MAC Data Service) and MLME.
++//
++// Revision History:
++// --------------------------------------------------------------------------
++// 200209 UN20 Jennifer Xu
++// Initial Release
++// 20021108 PD43 Austin Liu
++// 20030117 PD43 Austin Liu
++// Deleted MLMEReturnPacket and MLMEProcThread()
++//
++// Copyright (c) 1996-2002 Winbond Electronics Corp. All Rights Reserved.
++//============================================================================
++#include "os_common.h"
++
++void MLMEResetTxRx(PWB32_ADAPTER Adapter)
++{
++ s32 i;
++
++ // Reset the interface between MDS and MLME
++ for (i = 0; i < MAX_NUM_TX_MMPDU; i++)
++ Adapter->sMlmeFrame.TxMMPDUInUse[i] = FALSE;
++ for (i = 0; i < MAX_NUM_RX_MMPDU; i++)
++ Adapter->sMlmeFrame.SaveRxBufSlotInUse[i] = FALSE;
++
++ Adapter->sMlmeFrame.wNumRxMMPDUInMLME = 0;
++ Adapter->sMlmeFrame.wNumRxMMPDUDiscarded = 0;
++ Adapter->sMlmeFrame.wNumRxMMPDU = 0;
++ Adapter->sMlmeFrame.wNumTxMMPDUDiscarded = 0;
++ Adapter->sMlmeFrame.wNumTxMMPDU = 0;
++ Adapter->sLocalPara.boCCAbusy = FALSE;
++ Adapter->sLocalPara.iPowerSaveMode = PWR_ACTIVE; // Power active
++}
++
++//=============================================================================
++// Function:
++// MLMEGetMMPDUBuffer()
++//
++// Description:
++// Return the pointer to an available data buffer with
++// the size MAX_MMPDU_SIZE for a MMPDU.
++//
++// Arguments:
++// Adapter - pointer to the miniport adapter context.
++//
++// Return value:
++// NULL : No available data buffer available
++// Otherwise: Pointer to the data buffer
++//=============================================================================
++
++/* FIXME: Should this just be replaced with kmalloc() and kfree()? */
++u8 *MLMEGetMMPDUBuffer(PWB32_ADAPTER Adapter)
++{
++ s32 i;
++ u8 *returnVal;
++
++ for (i = 0; i< MAX_NUM_TX_MMPDU; i++) {
++ if (Adapter->sMlmeFrame.TxMMPDUInUse[i] == FALSE)
++ break;
++ }
++ if (i >= MAX_NUM_TX_MMPDU) return NULL;
++
++ returnVal = (u8 *)&(Adapter->sMlmeFrame.TxMMPDU[i]);
++ Adapter->sMlmeFrame.TxMMPDUInUse[i] = TRUE;
++
++ return returnVal;
++}
++
++//=============================================================================
++u8 MLMESendFrame(PWB32_ADAPTER Adapter, u8 *pMMPDU, u16 len, u8 DataType)
++/* DataType : FRAME_TYPE_802_11_MANAGEMENT, FRAME_TYPE_802_11_MANAGEMENT_CHALLENGE,
++ FRAME_TYPE_802_11_DATA */
++{
++ if (Adapter->sMlmeFrame.IsInUsed != PACKET_FREE_TO_USE) {
++ Adapter->sMlmeFrame.wNumTxMMPDUDiscarded++;
++ return FALSE;
++ }
++ Adapter->sMlmeFrame.IsInUsed = PACKET_COME_FROM_MLME;
++
++ // Keep information for sending
++ Adapter->sMlmeFrame.pMMPDU = pMMPDU;
++ Adapter->sMlmeFrame.DataType = DataType;
++ // len must be the last setting due to QUERY_SIZE_SECOND of Mds
++ Adapter->sMlmeFrame.len = len;
++ Adapter->sMlmeFrame.wNumTxMMPDU++;
++
++ // H/W will enter power save by set the register. S/W don't send null frame
++ //with PWRMgt bit enbled to enter power save now.
++
++ // Transmit NDIS packet
++ Mds_Tx(Adapter);
++ return TRUE;
++}
++
++void
++MLME_GetNextPacket(PADAPTER Adapter, PDESCRIPTOR pDes)
++{
++#define DESCRIPTOR_ADD_BUFFER( _D, _A, _S ) \
++{\
++ _D->InternalUsed = _D->buffer_start_index + _D->buffer_number; \
++ _D->InternalUsed %= MAX_DESCRIPTOR_BUFFER_INDEX; \
++ _D->buffer_address[ _D->InternalUsed ] = _A; \
++ _D->buffer_size[ _D->InternalUsed ] = _S; \
++ _D->buffer_total_size += _S; \
++ _D->buffer_number++;\
++}
++
++ DESCRIPTOR_ADD_BUFFER( pDes, Adapter->sMlmeFrame.pMMPDU, Adapter->sMlmeFrame.len );
++ pDes->Type = Adapter->sMlmeFrame.DataType;
++}
++
++void MLMEfreeMMPDUBuffer(PWB32_ADAPTER Adapter, PCHAR pData)
++{
++ int i;
++
++ // Reclaim the data buffer
++ for (i = 0; i < MAX_NUM_TX_MMPDU; i++) {
++ if (pData == (PCHAR)&(Adapter->sMlmeFrame.TxMMPDU[i]))
++ break;
++ }
++ if (Adapter->sMlmeFrame.TxMMPDUInUse[i])
++ Adapter->sMlmeFrame.TxMMPDUInUse[i] = FALSE;
++ else {
++ // Something wrong
++ // PD43 Add debug code here???
++ }
++}
++
++void
++MLME_SendComplete(PADAPTER Adapter, u8 PacketID, unsigned char SendOK)
++{
++ MLME_TXCALLBACK TxCallback;
++
++ // Reclaim the data buffer
++ Adapter->sMlmeFrame.len = 0;
++ MLMEfreeMMPDUBuffer( Adapter, Adapter->sMlmeFrame.pMMPDU );
++
++
++ TxCallback.bResult = MLME_SUCCESS;
++
++ // Return resource
++ Adapter->sMlmeFrame.IsInUsed = PACKET_FREE_TO_USE;
++}
++
++
++
+diff --git a/drivers/staging/winbond/mlmetxrx_f.h b/drivers/staging/winbond/mlmetxrx_f.h
+new file mode 100644
+index 0000000..d74e225
+--- /dev/null
++++ b/drivers/staging/winbond/mlmetxrx_f.h
+@@ -0,0 +1,52 @@
++//================================================================
++// MLMETxRx.H --
++//
++// Functions defined in MLMETxRx.c.
++//
++// Copyright (c) 2002 Winbond Electrics Corp. All Rights Reserved.
++//================================================================
++#ifndef _MLMETXRX_H
++#define _MLMETXRX_H
++
++void
++MLMEProcThread(
++ PWB32_ADAPTER Adapter
++ );
++
++void MLMEResetTxRx( PWB32_ADAPTER Adapter);
++
++u8 *
++MLMEGetMMPDUBuffer(
++ PWB32_ADAPTER Adapter
++ );
++
++void MLMEfreeMMPDUBuffer( PWB32_ADAPTER Adapter, PCHAR pData);
++
++void MLME_GetNextPacket( PADAPTER Adapter, PDESCRIPTOR pDes );
++u8 MLMESendFrame( PWB32_ADAPTER Adapter,
++ u8 *pMMPDU,
++ u16 len,
++ u8 DataType);
++
++void
++MLME_SendComplete( PWB32_ADAPTER Adapter, u8 PacketID, unsigned char SendOK );
++
++void
++MLMERcvFrame(
++ PWB32_ADAPTER Adapter,
++ PRXBUFFER pRxBufferArray,
++ u8 NumOfBuffer,
++ u8 ReturnSlotIndex
++ );
++
++void
++MLMEReturnPacket(
++ PWB32_ADAPTER Adapter,
++ PUCHAR pRxBufer
++ );
++#ifdef _IBSS_BEACON_SEQ_STICK_
++s8 SendBCNullData(PWB32_ADAPTER Adapter, u16 wIdx);
++#endif
++
++#endif
++
+diff --git a/drivers/staging/winbond/mto.c b/drivers/staging/winbond/mto.c
+new file mode 100644
+index 0000000..2ef60e5
+--- /dev/null
++++ b/drivers/staging/winbond/mto.c
+@@ -0,0 +1,1229 @@
++//============================================================================
++// MTO.C -
++//
++// Description:
++// MAC Throughput Optimization for W89C33 802.11g WLAN STA.
++//
++// The following MIB attributes or internal variables will be affected
++// while the MTO is being executed:
++// dot11FragmentationThreshold,
++// dot11RTSThreshold,
++// transmission rate and PLCP preamble type,
++// CCA mode,
++// antenna diversity.
++//
++// Revision history:
++// --------------------------------------------------------------------------
++// 20031227 UN20 Pete Chao
++// First draft
++// 20031229 Turbo copy from PD43
++// 20040210 Kevin revised
++// Copyright (c) 2003 Winbond Electronics Corp. All rights reserved.
++//============================================================================
++
++// LA20040210_DTO kevin
++#include "os_common.h"
++
++// Declare SQ3 to rate and fragmentation threshold table
++// Declare fragmentation thresholds table
++#define MTO_MAX_SQ3_LEVELS 14
++#define MTO_MAX_FRAG_TH_LEVELS 5
++#define MTO_MAX_DATA_RATE_LEVELS 12
++
++u16 MTO_Frag_Th_Tbl[MTO_MAX_FRAG_TH_LEVELS] =
++{
++ 256, 384, 512, 768, 1536
++};
++
++u8 MTO_SQ3_Level[MTO_MAX_SQ3_LEVELS] =
++{
++ 0, 26, 30, 32, 34, 35, 37, 42, 44, 46, 54, 62, 78, 81
++};
++u8 MTO_SQ3toRate[MTO_MAX_SQ3_LEVELS] =
++{
++ 0, 1, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
++};
++u8 MTO_SQ3toFrag[MTO_MAX_SQ3_LEVELS] =
++{
++ 0, 2, 2, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4
++};
++
++// One Exchange Time table
++//
++u16 MTO_One_Exchange_Time_Tbl_l[MTO_MAX_FRAG_TH_LEVELS][MTO_MAX_DATA_RATE_LEVELS] =
++{
++ { 2554, 1474, 822, 0, 0, 636, 0, 0, 0, 0, 0, 0},
++ { 3578, 1986, 1009, 0, 0, 729, 0, 0, 0, 0, 0, 0},
++ { 4602, 2498, 1195, 0, 0, 822, 0, 0, 0, 0, 0, 0},
++ { 6650, 3522, 1567, 0, 0, 1009, 0, 0, 0, 0, 0, 0},
++ {12794, 6594, 2684, 0, 0, 1567, 0, 0, 0, 0, 0, 0}
++};
++
++u16 MTO_One_Exchange_Time_Tbl_s[MTO_MAX_FRAG_TH_LEVELS][MTO_MAX_DATA_RATE_LEVELS] =
++{
++ { 0, 1282, 630, 404, 288, 444, 232, 172, 144, 116, 100, 96},
++ { 0, 1794, 817, 572, 400, 537, 316, 228, 188, 144, 124, 116},
++ { 0, 2306, 1003, 744, 516, 630, 400, 288, 228, 172, 144, 136},
++ { 0, 3330, 1375, 1084, 744, 817, 572, 400, 316, 228, 188, 172},
++ { 0, 6402, 2492, 2108, 1424, 1375, 1084, 740, 572, 400, 316, 284}
++};
++
++#define MTO_ONE_EXCHANGE_TIME(preamble_type, frag_th_lvl, data_rate_lvl) \
++ (preamble_type) ? MTO_One_Exchange_Time_Tbl_s[frag_th_lvl][data_rate_lvl] : \
++ MTO_One_Exchange_Time_Tbl_l[frag_th_lvl][data_rate_lvl]
++
++// Declare data rate table
++//The following table will be changed at anytime if the opration rate supported by AP don't
++//match the table
++u8 MTO_Data_Rate_Tbl[MTO_MAX_DATA_RATE_LEVELS] =
++{
++ 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108
++};
++
++//The Stardard_Data_Rate_Tbl and Level2PerTbl table is used to indirectly retreive PER
++//information from Rate_PER_TBL
++//The default settings is AP can support full rate set.
++static u8 Stardard_Data_Rate_Tbl[MTO_MAX_DATA_RATE_LEVELS] =
++{
++ 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108
++};
++static u8 Level2PerTbl[MTO_MAX_DATA_RATE_LEVELS] =
++{
++ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
++};
++//How many kind of tx rate can be supported by AP
++//DTO will change Rate between MTO_Data_Rate_Tbl[0] and MTO_Data_Rate_Tbl[MTO_DataRateAvailableLevel-1]
++static u8 MTO_DataRateAvailableLevel = MTO_MAX_DATA_RATE_LEVELS;
++//Smoothed PER table for each different RATE based on packet length of 1514
++static int Rate_PER_TBL[91][MTO_MAX_DATA_RATE_LEVELS] = {
++// 1M 2M 5.5M 11M 6M 9M 12M 18M 24M 36M 48M 54M
++/* 0% */{ 93, 177, 420, 538, 690, 774, 1001, 1401, 1768, 2358, 2838, 3039},
++/* 1% */{ 92, 176, 416, 533, 683, 767, 992, 1389, 1752, 2336, 2811, 3010},
++/* 2% */{ 91, 174, 412, 528, 675, 760, 983, 1376, 1735, 2313, 2783, 2979},
++/* 3% */{ 90, 172, 407, 523, 667, 753, 973, 1363, 1719, 2290, 2755, 2948},
++/* 4% */{ 90, 170, 403, 518, 659, 746, 964, 1350, 1701, 2266, 2726, 2916},
++/* 5% */{ 89, 169, 398, 512, 651, 738, 954, 1336, 1684, 2242, 2696, 2884},
++/* 6% */{ 88, 167, 394, 507, 643, 731, 944, 1322, 1666, 2217, 2665, 2851},
++/* 7% */{ 87, 165, 389, 502, 635, 723, 935, 1308, 1648, 2192, 2634, 2817},
++/* 8% */{ 86, 163, 384, 497, 626, 716, 924, 1294, 1629, 2166, 2602, 2782},
++/* 9% */{ 85, 161, 380, 491, 618, 708, 914, 1279, 1611, 2140, 2570, 2747},
++/* 10% */{ 84, 160, 375, 486, 609, 700, 904, 1265, 1591, 2113, 2537, 2711},
++/* 11% */{ 83, 158, 370, 480, 600, 692, 894, 1250, 1572, 2086, 2503, 2675},
++/* 12% */{ 82, 156, 365, 475, 592, 684, 883, 1234, 1552, 2059, 2469, 2638},
++/* 13% */{ 81, 154, 360, 469, 583, 676, 872, 1219, 1532, 2031, 2435, 2600},
++/* 14% */{ 80, 152, 355, 464, 574, 668, 862, 1204, 1512, 2003, 2400, 2562},
++/* 15% */{ 79, 150, 350, 458, 565, 660, 851, 1188, 1492, 1974, 2365, 2524},
++/* 16% */{ 78, 148, 345, 453, 556, 652, 840, 1172, 1471, 1945, 2329, 2485},
++/* 17% */{ 77, 146, 340, 447, 547, 643, 829, 1156, 1450, 1916, 2293, 2446},
++/* 18% */{ 76, 144, 335, 441, 538, 635, 818, 1140, 1429, 1887, 2256, 2406},
++/* 19% */{ 75, 143, 330, 436, 529, 627, 807, 1124, 1408, 1857, 2219, 2366},
++/* 20% */{ 74, 141, 325, 430, 520, 618, 795, 1107, 1386, 1827, 2182, 2326},
++/* 21% */{ 73, 139, 320, 424, 510, 610, 784, 1091, 1365, 1797, 2145, 2285},
++/* 22% */{ 72, 137, 314, 418, 501, 601, 772, 1074, 1343, 1766, 2107, 2244},
++/* 23% */{ 71, 135, 309, 412, 492, 592, 761, 1057, 1321, 1736, 2069, 2203},
++/* 24% */{ 70, 133, 304, 407, 482, 584, 749, 1040, 1299, 1705, 2031, 2161},
++/* 25% */{ 69, 131, 299, 401, 473, 575, 738, 1023, 1277, 1674, 1992, 2120},
++/* 26% */{ 68, 129, 293, 395, 464, 566, 726, 1006, 1254, 1642, 1953, 2078},
++/* 27% */{ 67, 127, 288, 389, 454, 557, 714, 989, 1232, 1611, 1915, 2035},
++/* 28% */{ 66, 125, 283, 383, 445, 549, 703, 972, 1209, 1579, 1876, 1993},
++/* 29% */{ 65, 123, 278, 377, 436, 540, 691, 955, 1187, 1548, 1836, 1951},
++/* 30% */{ 64, 121, 272, 371, 426, 531, 679, 937, 1164, 1516, 1797, 1908},
++/* 31% */{ 63, 119, 267, 365, 417, 522, 667, 920, 1141, 1484, 1758, 1866},
++/* 32% */{ 62, 117, 262, 359, 407, 513, 655, 902, 1118, 1453, 1719, 1823},
++/* 33% */{ 61, 115, 256, 353, 398, 504, 643, 885, 1095, 1421, 1679, 1781},
++/* 34% */{ 60, 113, 251, 347, 389, 495, 631, 867, 1072, 1389, 1640, 1738},
++/* 35% */{ 59, 111, 246, 341, 379, 486, 619, 850, 1049, 1357, 1600, 1695},
++/* 36% */{ 58, 108, 240, 335, 370, 477, 607, 832, 1027, 1325, 1561, 1653},
++/* 37% */{ 57, 106, 235, 329, 361, 468, 595, 815, 1004, 1293, 1522, 1610},
++/* 38% */{ 56, 104, 230, 323, 351, 459, 584, 797, 981, 1261, 1483, 1568},
++/* 39% */{ 55, 102, 224, 317, 342, 450, 572, 780, 958, 1230, 1443, 1526},
++/* 40% */{ 54, 100, 219, 311, 333, 441, 560, 762, 935, 1198, 1404, 1484},
++/* 41% */{ 53, 98, 214, 305, 324, 432, 548, 744, 912, 1166, 1366, 1442},
++/* 42% */{ 52, 96, 209, 299, 315, 423, 536, 727, 889, 1135, 1327, 1400},
++/* 43% */{ 51, 94, 203, 293, 306, 414, 524, 709, 866, 1104, 1289, 1358},
++/* 44% */{ 50, 92, 198, 287, 297, 405, 512, 692, 844, 1072, 1250, 1317},
++/* 45% */{ 49, 90, 193, 281, 288, 396, 500, 675, 821, 1041, 1212, 1276},
++/* 46% */{ 48, 88, 188, 275, 279, 387, 488, 657, 799, 1011, 1174, 1236},
++/* 47% */{ 47, 86, 183, 269, 271, 378, 476, 640, 777, 980, 1137, 1195},
++/* 48% */{ 46, 84, 178, 262, 262, 369, 464, 623, 754, 949, 1100, 1155},
++/* 49% */{ 45, 82, 173, 256, 254, 360, 452, 606, 732, 919, 1063, 1116},
++/* 50% */{ 44, 80, 168, 251, 245, 351, 441, 589, 710, 889, 1026, 1076},
++/* 51% */{ 43, 78, 163, 245, 237, 342, 429, 572, 689, 860, 990, 1038},
++/* 52% */{ 42, 76, 158, 239, 228, 333, 417, 555, 667, 830, 955, 999},
++/* 53% */{ 41, 74, 153, 233, 220, 324, 406, 538, 645, 801, 919, 961},
++/* 54% */{ 40, 72, 148, 227, 212, 315, 394, 522, 624, 773, 884, 924},
++/* 55% */{ 39, 70, 143, 221, 204, 307, 383, 505, 603, 744, 850, 887},
++/* 56% */{ 38, 68, 138, 215, 196, 298, 371, 489, 582, 716, 816, 851},
++/* 57% */{ 37, 67, 134, 209, 189, 289, 360, 473, 562, 688, 783, 815},
++/* 58% */{ 36, 65, 129, 203, 181, 281, 349, 457, 541, 661, 750, 780},
++/* 59% */{ 35, 63, 124, 197, 174, 272, 338, 441, 521, 634, 717, 745},
++/* 60% */{ 34, 61, 120, 192, 166, 264, 327, 425, 501, 608, 686, 712},
++/* 61% */{ 33, 59, 115, 186, 159, 255, 316, 409, 482, 582, 655, 678},
++/* 62% */{ 32, 57, 111, 180, 152, 247, 305, 394, 462, 556, 624, 646},
++/* 63% */{ 31, 55, 107, 174, 145, 238, 294, 379, 443, 531, 594, 614},
++/* 64% */{ 30, 53, 102, 169, 138, 230, 283, 364, 425, 506, 565, 583},
++/* 65% */{ 29, 52, 98, 163, 132, 222, 273, 349, 406, 482, 536, 553},
++/* 66% */{ 28, 50, 94, 158, 125, 214, 262, 334, 388, 459, 508, 523},
++/* 67% */{ 27, 48, 90, 152, 119, 206, 252, 320, 370, 436, 481, 495},
++/* 68% */{ 26, 46, 86, 147, 113, 198, 242, 306, 353, 413, 455, 467},
++/* 69% */{ 26, 44, 82, 141, 107, 190, 231, 292, 336, 391, 429, 440},
++/* 70% */{ 25, 43, 78, 136, 101, 182, 221, 278, 319, 370, 405, 414},
++/* 71% */{ 24, 41, 74, 130, 95, 174, 212, 265, 303, 350, 381, 389},
++/* 72% */{ 23, 39, 71, 125, 90, 167, 202, 252, 287, 329, 358, 365},
++/* 73% */{ 22, 37, 67, 119, 85, 159, 192, 239, 271, 310, 335, 342},
++/* 74% */{ 21, 36, 63, 114, 80, 151, 183, 226, 256, 291, 314, 320},
++/* 75% */{ 20, 34, 60, 109, 75, 144, 174, 214, 241, 273, 294, 298},
++/* 76% */{ 19, 32, 57, 104, 70, 137, 164, 202, 227, 256, 274, 278},
++/* 77% */{ 18, 31, 53, 99, 66, 130, 155, 190, 213, 239, 256, 259},
++/* 78% */{ 17, 29, 50, 94, 62, 122, 146, 178, 200, 223, 238, 241},
++/* 79% */{ 16, 28, 47, 89, 58, 115, 138, 167, 187, 208, 222, 225},
++/* 80% */{ 16, 26, 44, 84, 54, 109, 129, 156, 175, 194, 206, 209},
++/* 81% */{ 15, 24, 41, 79, 50, 102, 121, 146, 163, 180, 192, 194},
++/* 82% */{ 14, 23, 39, 74, 47, 95, 113, 136, 151, 167, 178, 181},
++/* 83% */{ 13, 21, 36, 69, 44, 89, 105, 126, 140, 155, 166, 169},
++/* 84% */{ 12, 20, 33, 64, 41, 82, 97, 116, 130, 144, 155, 158},
++/* 85% */{ 11, 19, 31, 60, 39, 76, 89, 107, 120, 134, 145, 149},
++/* 86% */{ 11, 17, 29, 55, 36, 70, 82, 98, 110, 125, 136, 140},
++/* 87% */{ 10, 16, 26, 51, 34, 64, 75, 90, 102, 116, 128, 133},
++/* 88% */{ 9, 14, 24, 46, 32, 58, 68, 81, 93, 108, 121, 128},
++/* 89% */{ 8, 13, 22, 42, 31, 52, 61, 74, 86, 102, 116, 124},
++/* 90% */{ 7, 12, 21, 37, 29, 46, 54, 66, 79, 96, 112, 121}
++};
++
++#define RSSIBUF_NUM 10
++#define RSSI2RATE_SIZE 9
++
++static TXRETRY_REC TxRateRec={MTO_MAX_DATA_RATE_LEVELS - 1, 0}; //new record=>TxRateRec
++static int TxRetryRate;
++//static int SQ3, BSS_PK_CNT, NIDLESLOT, SLOT_CNT, INTERF_CNT, GAP_CNT, DS_EVM;
++static s32 RSSIBuf[RSSIBUF_NUM]={-70, -70, -70, -70, -70, -70, -70, -70, -70, -70};
++static s32 RSSISmoothed=-700;
++static int RSSIBufIndex=0;
++static u8 max_rssi_rate;
++static int rate_tbl[13] = {0,1,2,5,11,6,9,12,18,24,36,48,54};
++//[WKCHEN]static core_data_t *pMTOcore_data=NULL;
++
++static int TotalTxPkt = 0;
++static int TotalTxPktRetry = 0;
++static int TxPktPerAnt[3] = {0,0,0};
++static int RXRSSIANT[3] ={-70,-70,-70};
++static int TxPktRetryPerAnt[3] = {0,0,0};
++//static int TxDominateFlag=FALSE;
++static u8 old_antenna[4]={1 ,0 ,1 ,0};
++static int retryrate_rec[MTO_MAX_DATA_RATE_LEVELS];//this record the retry rate at different data rate
++
++static int PeriodTotalTxPkt = 0;
++static int PeriodTotalTxPktRetry = 0;
++
++typedef struct
++{
++ s32 RSSI;
++ u8 TxRate;
++}RSSI2RATE;
++
++static RSSI2RATE RSSI2RateTbl[RSSI2RATE_SIZE] =
++{
++ {-740, 108}, // 54M
++ {-760, 96}, // 48M
++ {-820, 72}, // 36M
++ {-850, 48}, // 24M
++ {-870, 36}, // 18M
++ {-890, 24}, // 12M
++ {-900, 12}, // 6M
++ {-920, 11}, // 5.5M
++ {-950, 4}, // 2M
++};
++static u8 untogglecount;
++static u8 last_rate_ant; //this is used for antenna backoff-hh
++
++u8 boSparseTxTraffic = FALSE;
++
++void MTO_Init(MTO_FUNC_INPUT);
++void AntennaToggleInitiator(MTO_FUNC_INPUT);
++void AntennaToggleState(MTO_FUNC_INPUT);
++void TxPwrControl(MTO_FUNC_INPUT);
++void GetFreshAntennaData(MTO_FUNC_INPUT);
++void TxRateReductionCtrl(MTO_FUNC_INPUT);
++/** 1.1.31.1000 Turbo modify */
++//void MTO_SetDTORateRange(int type);
++void MTO_SetDTORateRange(MTO_FUNC_INPUT, u8 *pRateArray, u8 ArraySize);
++void MTO_SetTxCount(MTO_FUNC_INPUT, u8 t0, u8 index);
++void MTO_TxFailed(MTO_FUNC_INPUT);
++void SmoothRSSI(s32 new_rssi);
++void hal_get_dto_para(MTO_FUNC_INPUT, char *buffer);
++u8 CalcNewRate(MTO_FUNC_INPUT, u8 old_rate, u32 retry_cnt, u32 tx_frag_cnt);
++u8 GetMaxRateLevelFromRSSI(void);
++u8 MTO_GetTxFallbackRate(MTO_FUNC_INPUT);
++int Divide(int a, int b);
++void multiagc(MTO_FUNC_INPUT, u8 high_gain_mode);
++
++//===========================================================================
++// MTO_Init --
++//
++// Description:
++// Set DTO Tx Rate Scope because different AP could have different Rate set.
++// After our staion join with AP, LM core will call this function to initialize
++// Tx Rate table.
++//
++// Arguments:
++// pRateArray - The pointer to the Tx Rate Array by the following order
++// - 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108
++// - DTO won't check whether rate order is invalid or not
++// ArraySize - The array size to indicate how many tx rate we can choose
++//
++// sample code:
++// {
++// u8 RateArray[4] = {2, 4, 11, 22};
++// MTO_SetDTORateRange(RateArray, 4);
++// }
++//
++// Return Value:
++// None
++//============================================================================
++void MTO_SetDTORateRange(MTO_FUNC_INPUT,u8 *pRateArray, u8 ArraySize)
++{
++ u8 i, j=0;
++
++ for(i=0;i<ArraySize;i++)
++ {
++ if(pRateArray[i] == 22)
++ break;
++ }
++ if(i < ArraySize) //we need adjust the order of rate list because 11Mbps rate exists
++ {
++ for(;i>0;i--)
++ {
++ if(pRateArray[i-1] <= 11)
++ break;
++ pRateArray[i] = pRateArray[i-1];
++ }
++ pRateArray[i] = 22;
++ MTO_OFDM_RATE_LEVEL() = i;
++ }
++ else
++ {
++ for(i=0; i<ArraySize; i++)
++ {
++ if (pRateArray[i] >= 12)
++ break;
++ }
++ MTO_OFDM_RATE_LEVEL() = i;
++ }
++
++ for(i=0;i<ArraySize;i++)
++ {
++ MTO_Data_Rate_Tbl[i] = pRateArray[i];
++ for(;j<MTO_MAX_DATA_RATE_LEVELS;j++)
++ {
++ if(Stardard_Data_Rate_Tbl[j] == pRateArray[i])
++ break;
++ }
++ Level2PerTbl[i] = j;
++ #ifdef _PE_DTO_DUMP_
++ WBDEBUG(("[MTO]:Op Rate[%d]: %d\n",i, MTO_Data_Rate_Tbl[i]));
++ #endif
++ }
++ MTO_DataRateAvailableLevel = ArraySize;
++ if( MTO_DATA().RatePolicy ) // 0 means that no registry setting
++ {
++ if( MTO_DATA().RatePolicy == 1 )
++ TxRateRec.tx_rate = 0; //ascent
++ else
++ TxRateRec.tx_rate = MTO_DataRateAvailableLevel -1 ; //descent
++ }
++ else
++ {
++ if( MTO_INITTXRATE_MODE )
++ TxRateRec.tx_rate = 0; //ascent
++ else
++ TxRateRec.tx_rate = MTO_DataRateAvailableLevel -1 ; //descent
++ }
++ TxRateRec.tx_retry_rate = 0;
++ //set default rate for initial use
++ MTO_RATE_LEVEL() = TxRateRec.tx_rate;
++ MTO_FALLBACK_RATE_LEVEL() = MTO_RATE_LEVEL();
++}
++
++//===========================================================================
++// MTO_Init --
++//
++// Description:
++// Initialize MTO parameters.
++//
++// This function should be invoked during system initialization.
++//
++// Arguments:
++// Adapter - The pointer to the Miniport Adapter Context
++//
++// Return Value:
++// None
++//============================================================================
++void MTO_Init(MTO_FUNC_INPUT)
++{
++ int i;
++ //WBDEBUG(("[MTO] -> MTO_Init()\n"));
++ //[WKCHEN]pMTOcore_data = pcore_data;
++// 20040510 Turbo add for global variable
++ MTO_TMR_CNT() = 0;
++ MTO_TOGGLE_STATE() = TOGGLE_STATE_IDLE;
++ MTO_TX_RATE_REDUCTION_STATE() = RATE_CHGSTATE_IDLE;
++ MTO_BACKOFF_TMR() = 0;
++ MTO_LAST_RATE() = 11;
++ MTO_CO_EFFICENT() = 0;
++
++ //MTO_TH_FIXANT() = MTO_DEFAULT_TH_FIXANT;
++ MTO_TH_CNT() = MTO_DEFAULT_TH_CNT;
++ MTO_TH_SQ3() = MTO_DEFAULT_TH_SQ3;
++ MTO_TH_IDLE_SLOT() = MTO_DEFAULT_TH_IDLE_SLOT;
++ MTO_TH_PR_INTERF() = MTO_DEFAULT_TH_PR_INTERF;
++
++ MTO_TMR_AGING() = MTO_DEFAULT_TMR_AGING;
++ MTO_TMR_PERIODIC() = MTO_DEFAULT_TMR_PERIODIC;
++
++ //[WKCHEN]MTO_CCA_MODE_SETUP()= (u8) hal_get_cca_mode(MTO_HAL());
++ //[WKCHEN]MTO_CCA_MODE() = MTO_CCA_MODE_SETUP();
++
++ //MTO_PREAMBLE_TYPE() = MTO_PREAMBLE_LONG;
++ MTO_PREAMBLE_TYPE() = MTO_PREAMBLE_SHORT; // for test
++
++ MTO_ANT_SEL() = hal_get_antenna_number(MTO_HAL());
++ MTO_ANT_MAC() = MTO_ANT_SEL();
++ MTO_CNT_ANT(0) = 0;
++ MTO_CNT_ANT(1) = 0;
++ MTO_SQ_ANT(0) = 0;
++ MTO_SQ_ANT(1) = 0;
++ MTO_ANT_DIVERSITY() = MTO_ANTENNA_DIVERSITY_ON;
++ //CardSet_AntennaDiversity(Adapter, MTO_ANT_DIVERSITY());
++ //PLMESetAntennaDiversity( Adapter, MTO_ANT_DIVERSITY());
++
++ MTO_AGING_TIMEOUT() = 0;//MTO_TMR_AGING() / MTO_TMR_PERIODIC();
++
++ // The following parameters should be initialized to the values set by user
++ //
++ //MTO_RATE_LEVEL() = 10;
++ MTO_RATE_LEVEL() = 0;
++ MTO_FALLBACK_RATE_LEVEL() = MTO_RATE_LEVEL();
++ MTO_FRAG_TH_LEVEL() = 4;
++ /** 1.1.23.1000 Turbo modify from -1 to +1
++ MTO_RTS_THRESHOLD() = MTO_FRAG_TH() - 1;
++ MTO_RTS_THRESHOLD_SETUP() = MTO_FRAG_TH() - 1;
++ */
++ MTO_RTS_THRESHOLD() = MTO_FRAG_TH() + 1;
++ MTO_RTS_THRESHOLD_SETUP() = MTO_FRAG_TH() + 1;
++ // 1.1.23.1000 Turbo add for mto change preamble from 0 to 1
++ MTO_RATE_CHANGE_ENABLE() = 1;
++ MTO_FRAG_CHANGE_ENABLE() = 0; // 1.1.29.1000 Turbo add don't support frag
++ //The default valud of ANTDIV_DEFAULT_ON will be decided by EEPROM
++ //#ifdef ANTDIV_DEFAULT_ON
++ //MTO_ANT_DIVERSITY_ENABLE() = 1;
++ //#else
++ //MTO_ANT_DIVERSITY_ENABLE() = 0;
++ //#endif
++ MTO_POWER_CHANGE_ENABLE() = 1;
++ MTO_PREAMBLE_CHANGE_ENABLE()= 1;
++ MTO_RTS_CHANGE_ENABLE() = 0; // 1.1.29.1000 Turbo add don't support frag
++ // 20040512 Turbo add
++ //old_antenna[0] = 1;
++ //old_antenna[1] = 0;
++ //old_antenna[2] = 1;
++ //old_antenna[3] = 0;
++ for (i=0;i<MTO_MAX_DATA_RATE_LEVELS;i++)
++ retryrate_rec[i]=5;
++
++ MTO_TXFLOWCOUNT() = 0;
++ //--------- DTO threshold parameters -------------
++ //MTOPARA_PERIODIC_CHECK_CYCLE() = 50;
++ MTOPARA_PERIODIC_CHECK_CYCLE() = 10;
++ MTOPARA_RSSI_TH_FOR_ANTDIV() = 10;
++ MTOPARA_TXCOUNT_TH_FOR_CALC_RATE() = 50;
++ MTOPARA_TXRATE_INC_TH() = 10;
++ MTOPARA_TXRATE_DEC_TH() = 30;
++ MTOPARA_TXRATE_EQ_TH() = 40;
++ MTOPARA_TXRATE_BACKOFF() = 12;
++ MTOPARA_TXRETRYRATE_REDUCE() = 6;
++ if ( MTO_TXPOWER_FROM_EEPROM == 0xff)
++ {
++ switch( MTO_HAL()->phy_type)
++ {
++ case RF_AIROHA_2230:
++ case RF_AIROHA_2230S: // 20060420 Add this
++ MTOPARA_TXPOWER_INDEX() = 46; // MAX-8 // @@ Only for AL 2230
++ break;
++ case RF_AIROHA_7230:
++ MTOPARA_TXPOWER_INDEX() = 49;
++ break;
++ case RF_WB_242:
++ MTOPARA_TXPOWER_INDEX() = 10;
++ break;
++ case RF_WB_242_1:
++ MTOPARA_TXPOWER_INDEX() = 24; // ->10 20060316.1 modify
++ break;
++ }
++ }
++ else //follow the setting from EEPROM
++ MTOPARA_TXPOWER_INDEX() = MTO_TXPOWER_FROM_EEPROM;
++ hal_set_rf_power(MTO_HAL(), (u8)MTOPARA_TXPOWER_INDEX());
++ //------------------------------------------------
++
++ // For RSSI turning 20060808.4 Cancel load from EEPROM
++ MTO_DATA().RSSI_high = -41;
++ MTO_DATA().RSSI_low = -60;
++}
++
++//---------------------------------------------------------------------------//
++static u32 DTO_Rx_Info[13][3];
++static u32 DTO_RxCRCFail_Info[13][3];
++static u32 AntennaToggleBkoffTimer=5;
++typedef struct{
++ int RxRate;
++ int RxRatePkts;
++ int index;
++}RXRATE_ANT;
++RXRATE_ANT RxRatePeakAnt[3];
++
++#define ANT0 0
++#define ANT1 1
++#define OLD_ANT 2
++
++void SearchPeakRxRate(int index)
++{
++ int i;
++ RxRatePeakAnt[index].RxRatePkts=0;
++ //Find out the best rx rate which is used on different antenna
++ for(i=1;i<13;i++)
++ {
++ if(DTO_Rx_Info[i][index] > (u32) RxRatePeakAnt[index].RxRatePkts)
++ {
++ RxRatePeakAnt[index].RxRatePkts = DTO_Rx_Info[i][index];
++ RxRatePeakAnt[index].RxRate = rate_tbl[i];
++ RxRatePeakAnt[index].index = i;
++ }
++ }
++}
++
++void ResetDTO_RxInfo(int index, MTO_FUNC_INPUT)
++{
++ int i;
++
++ #ifdef _PE_DTO_DUMP_
++ WBDEBUG(("ResetDTOrx\n"));
++ #endif
++
++ for(i=0;i<13;i++)
++ DTO_Rx_Info[i][index] = MTO_HAL()->rx_ok_count[i];
++
++ for(i=0;i<13;i++)
++ DTO_RxCRCFail_Info[i][index] = MTO_HAL()->rx_err_count[i];
++
++ TotalTxPkt = 0;
++ TotalTxPktRetry = 0;
++}
++
++void GetDTO_RxInfo(int index, MTO_FUNC_INPUT)
++{
++ int i;
++
++ #ifdef _PE_DTO_DUMP_
++ WBDEBUG(("GetDTOrx\n"));
++ #endif
++
++ //PDEBUG(("[MTO]:DTO_Rx_Info[%d]=%d, rx_ok_count=%d\n", index, DTO_Rx_Info[0][index], phw_data->rx_ok_count[0]));
++ for(i=0;i<13;i++)
++ DTO_Rx_Info[i][index] = abs(MTO_HAL()->rx_ok_count[i] - DTO_Rx_Info[i][index]);
++ if(DTO_Rx_Info[0][index]==0) DTO_Rx_Info[0][index] = 1;
++
++ for(i=0;i<13;i++)
++ DTO_RxCRCFail_Info[i][index] = MTO_HAL()->rx_err_count[i] - DTO_RxCRCFail_Info[i][index];
++
++ TxPktPerAnt[index] = TotalTxPkt;
++ TxPktRetryPerAnt[index] = TotalTxPktRetry;
++ TotalTxPkt = 0;
++ TotalTxPktRetry = 0;
++}
++
++void OutputDebugInfo(int index1, int index2)
++{
++ #ifdef _PE_DTO_DUMP_
++ WBDEBUG(("[HHDTO]:Total Rx (%d)\t\t(%d) \n ", DTO_Rx_Info[0][index1], DTO_Rx_Info[0][index2]));
++ WBDEBUG(("[HHDTO]:RECEIVE RSSI: (%d)\t\t(%d) \n ", RXRSSIANT[index1], RXRSSIANT[index2]));
++ WBDEBUG(("[HHDTO]:TX packet correct rate: (%d)%%\t\t(%d)%% \n ",Divide(TxPktPerAnt[index1]*100,TxPktRetryPerAnt[index1]), Divide(TxPktPerAnt[index2]*100,TxPktRetryPerAnt[index2])));
++ #endif
++ {
++ int tmp1, tmp2;
++ #ifdef _PE_DTO_DUMP_
++ WBDEBUG(("[HHDTO]:Total Tx (%d)\t\t(%d) \n ", TxPktPerAnt[index1], TxPktPerAnt[index2]));
++ WBDEBUG(("[HHDTO]:Total Tx retry (%d)\t\t(%d) \n ", TxPktRetryPerAnt[index1], TxPktRetryPerAnt[index2]));
++ #endif
++ tmp1 = TxPktPerAnt[index1] + DTO_Rx_Info[0][index1];
++ tmp2 = TxPktPerAnt[index2] + DTO_Rx_Info[0][index2];
++ #ifdef _PE_DTO_DUMP_
++ WBDEBUG(("[HHDTO]:Total Tx+RX (%d)\t\t(%d) \n ", tmp1, tmp2));
++ #endif
++ }
++}
++
++unsigned char TxDominate(int index)
++{
++ int tmp;
++
++ tmp = TxPktPerAnt[index] + DTO_Rx_Info[0][index];
++
++ if(Divide(TxPktPerAnt[index]*100, tmp) > 40)
++ return TRUE;
++ else
++ return FALSE;
++}
++
++unsigned char CmpTxRetryRate(int index1, int index2)
++{
++ int tx_retry_rate1, tx_retry_rate2;
++ tx_retry_rate1 = Divide((TxPktRetryPerAnt[index1] - TxPktPerAnt[index1])*100, TxPktRetryPerAnt[index1]);
++ tx_retry_rate2 = Divide((TxPktRetryPerAnt[index2] - TxPktPerAnt[index2])*100, TxPktRetryPerAnt[index2]);
++ #ifdef _PE_DTO_DUMP_
++ WBDEBUG(("[MTO]:TxRetry Ant0: (%d%%) Ant1: (%d%%) \n ", tx_retry_rate1, tx_retry_rate2));
++ #endif
++
++ if(tx_retry_rate1 > tx_retry_rate2)
++ return TRUE;
++ else
++ return FALSE;
++}
++
++void GetFreshAntennaData(MTO_FUNC_INPUT)
++{
++ u8 x;
++
++ x = hal_get_antenna_number(MTO_HAL());
++ //hal_get_bss_pk_cnt(MTO_HAL());
++ //hal_get_est_sq3(MTO_HAL(), 1);
++ old_antenna[0] = x;
++ //if this is the function for timer
++ ResetDTO_RxInfo(x, MTO_FUNC_INPUT_DATA);
++ if(AntennaToggleBkoffTimer)
++ AntennaToggleBkoffTimer--;
++ if (abs(last_rate_ant-MTO_RATE_LEVEL())>1) //backoff timer reset
++ AntennaToggleBkoffTimer=0;
++
++ if (MTO_ANT_DIVERSITY() != MTO_ANTENNA_DIVERSITY_ON ||
++ MTO_ANT_DIVERSITY_ENABLE() != 1)
++ AntennaToggleBkoffTimer=1;
++ #ifdef _PE_DTO_DUMP_
++ WBDEBUG(("[HHDTO]:**last data rate=%d,now data rate=%d**antenna toggle timer=%d",last_rate_ant,MTO_RATE_LEVEL(),AntennaToggleBkoffTimer));
++ #endif
++ last_rate_ant=MTO_RATE_LEVEL();
++ if(AntennaToggleBkoffTimer==0)
++ {
++ MTO_TOGGLE_STATE() = TOGGLE_STATE_WAIT0;
++ #ifdef _PE_DTO_DUMP_
++ WBDEBUG(("[HHDTO]:===state is starting==for antenna toggle==="));
++ #endif
++ }
++ else
++ MTO_TOGGLE_STATE() = TOGGLE_STATE_IDLE;
++
++ if ((MTO_BACKOFF_TMR()!=0)&&(MTO_RATE_LEVEL()>MTO_DataRateAvailableLevel - 3))
++ {
++ MTO_TOGGLE_STATE() = TOGGLE_STATE_IDLE;
++ #ifdef _PE_DTO_DUMP_
++ WBDEBUG(("[HHDTO]:===the data rate is %d (good)and will not toogle ===",MTO_DATA_RATE()>>1));
++ #endif
++ }
++
++
++}
++
++int WB_PCR[2]; //packet correct rate
++
++void AntennaToggleState(MTO_FUNC_INPUT)
++{
++ int decideantflag = 0;
++ u8 x;
++ s32 rssi;
++
++ if(MTO_ANT_DIVERSITY_ENABLE() != 1)
++ return;
++ x = hal_get_antenna_number(MTO_HAL());
++ switch(MTO_TOGGLE_STATE())
++ {
++
++ //Missing.....
++ case TOGGLE_STATE_IDLE:
++ case TOGGLE_STATE_BKOFF:
++ break;;
++
++ case TOGGLE_STATE_WAIT0://========
++ GetDTO_RxInfo(x, MTO_FUNC_INPUT_DATA);
++ sme_get_rssi(MTO_FUNC_INPUT_DATA, &rssi);
++ RXRSSIANT[x] = rssi;
++ #ifdef _PE_DTO_DUMP_
++ WBDEBUG(("[HHDTO] **wait0==== Collecting Ant%d--rssi=%d\n", x,RXRSSIANT[x]));
++ #endif
++
++ //change antenna and reset the data at changed antenna
++ x = (~x) & 0x01;
++ MTO_ANT_SEL() = x;
++ hal_set_antenna_number(MTO_HAL(), MTO_ANT_SEL());
++ LOCAL_ANTENNA_NO() = x;
++
++ MTO_TOGGLE_STATE() = TOGGLE_STATE_WAIT1;//go to wait1
++ ResetDTO_RxInfo(x, MTO_FUNC_INPUT_DATA);
++ break;
++ case TOGGLE_STATE_WAIT1://=====wait1
++ //MTO_CNT_ANT(x) = hal_get_bss_pk_cnt(MTO_HAL());
++ //RXRSSIANT[x] = hal_get_rssi(MTO_HAL());
++ sme_get_rssi(MTO_FUNC_INPUT_DATA, &rssi);
++ RXRSSIANT[x] = rssi;
++ GetDTO_RxInfo(x, MTO_FUNC_INPUT_DATA);
++ #ifdef _PE_DTO_DUMP_
++ WBDEBUG(("[HHDTO] **wait1==== Collecting Ant%d--rssi=%d\n", x,RXRSSIANT[x]));
++ #endif
++ MTO_TOGGLE_STATE() = TOGGLE_STATE_MAKEDESISION;
++ break;
++ case TOGGLE_STATE_MAKEDESISION:
++ #ifdef _PE_DTO_DUMP_
++ WBDEBUG(("[HHDTO]:Ant--0-----------------1---\n"));
++ OutputDebugInfo(ANT0,ANT1);
++ #endif
++ //PDEBUG(("[HHDTO] **decision====\n "));
++
++ //=====following is the decision produrce
++ //
++ // first: compare the rssi if difference >10
++ // select the larger one
++ // ,others go to second
++ // second: comapre the tx+rx packet count if difference >100
++ // use larger total packets antenna
++ // third::compare the tx PER if packets>20
++ // if difference >5% using the bigger one
++ //
++ // fourth:compare the RX PER if packets>20
++ // if PER difference <5%
++ // using old antenna
++ //
++ //
++ if (abs(RXRSSIANT[ANT0]-RXRSSIANT[ANT1]) > MTOPARA_RSSI_TH_FOR_ANTDIV())//====rssi_th
++ {
++ if (RXRSSIANT[ANT0]>RXRSSIANT[ANT1])
++ {
++ decideantflag=1;
++ MTO_ANT_MAC() = ANT0;
++ }
++ else
++ {
++ decideantflag=1;
++ MTO_ANT_MAC() = ANT1;
++ }
++ #ifdef _PE_DTO_DUMP_
++ WBDEBUG(("Select antenna by RSSI\n"));
++ #endif
++ }
++ else if (abs(TxPktPerAnt[ANT0] + DTO_Rx_Info[0][ANT0]-TxPktPerAnt[ANT1]-DTO_Rx_Info[0][ANT1])<50)//=====total packet_th
++ {
++ #ifdef _PE_DTO_DUMP_
++ WBDEBUG(("Total tx/rx is close\n"));
++ #endif
++ if (TxDominate(ANT0) && TxDominate(ANT1))
++ {
++ if ((TxPktPerAnt[ANT0]>10) && (TxPktPerAnt[ANT1]>10))//====tx packet_th
++ {
++ WB_PCR[ANT0]=Divide(TxPktPerAnt[ANT0]*100,TxPktRetryPerAnt[ANT0]);
++ WB_PCR[ANT1]=Divide(TxPktPerAnt[ANT1]*100,TxPktRetryPerAnt[ANT1]);
++ if (abs(WB_PCR[ANT0]-WB_PCR[ANT1])>5)// tx PER_th
++ {
++ #ifdef _PE_DTO_DUMP_
++ WBDEBUG(("Decide by Tx correct rate\n"));
++ #endif
++ if (WB_PCR[ANT0]>WB_PCR[ANT1])
++ {
++ decideantflag=1;
++ MTO_ANT_MAC() = ANT0;
++ }
++ else
++ {
++ decideantflag=1;
++ MTO_ANT_MAC() = ANT1;
++ }
++ }
++ else
++ {
++ decideantflag=0;
++ untogglecount++;
++ MTO_ANT_MAC() = old_antenna[0];
++ }
++ }
++ else
++ {
++ decideantflag=0;
++ MTO_ANT_MAC() = old_antenna[0];
++ }
++ }
++ else if ((DTO_Rx_Info[0][ANT0]>10)&&(DTO_Rx_Info[0][ANT1]>10))//rx packet th
++ {
++ #ifdef _PE_DTO_DUMP_
++ WBDEBUG(("Decide by Rx\n"));
++ #endif
++ if (abs(DTO_Rx_Info[0][ANT0] - DTO_Rx_Info[0][ANT1])>50)
++ {
++ if (DTO_Rx_Info[0][ANT0] > DTO_Rx_Info[0][ANT1])
++ {
++ decideantflag=1;
++ MTO_ANT_MAC() = ANT0;
++ }
++ else
++ {
++ decideantflag=1;
++ MTO_ANT_MAC() = ANT1;
++ }
++ }
++ else
++ {
++ decideantflag=0;
++ untogglecount++;
++ MTO_ANT_MAC() = old_antenna[0];
++ }
++ }
++ else
++ {
++ decideantflag=0;
++ MTO_ANT_MAC() = old_antenna[0];
++ }
++ }
++ else if ((TxPktPerAnt[ANT0]+DTO_Rx_Info[0][ANT0])>(TxPktPerAnt[ANT1]+DTO_Rx_Info[0][ANT1]))//use more packekts
++ {
++ #ifdef _PE_DTO_DUMP_
++ WBDEBUG(("decide by total tx/rx : ANT 0\n"));
++ #endif
++
++ decideantflag=1;
++ MTO_ANT_MAC() = ANT0;
++ }
++ else
++ {
++ #ifdef _PE_DTO_DUMP_
++ WBDEBUG(("decide by total tx/rx : ANT 1\n"));
++ #endif
++ decideantflag=1;
++ MTO_ANT_MAC() = ANT1;
++
++ }
++ //this is force ant toggle
++ if (decideantflag==1)
++ untogglecount=0;
++
++ untogglecount=untogglecount%4;
++ if (untogglecount==3) //change antenna
++ MTO_ANT_MAC() = ((~old_antenna[0]) & 0x1);
++ #ifdef _PE_DTO_DUMP_
++ WBDEBUG(("[HHDTO]:==================untoggle-count=%d",untogglecount));
++ #endif
++
++
++
++
++ //PDEBUG(("[HHDTO] **********************************DTO ENABLE=%d",MTO_ANT_DIVERSITY_ENABLE()));
++ if(MTO_ANT_DIVERSITY_ENABLE() == 1)
++ {
++ MTO_ANT_SEL() = MTO_ANT_MAC();
++ hal_set_antenna_number(MTO_HAL(), MTO_ANT_SEL());
++ LOCAL_ANTENNA_NO() = MTO_ANT_SEL();
++ #ifdef _PE_DTO_DUMP_
++ WBDEBUG(("[HHDTO] ==decision==*******antflag=%d******************selected antenna=%d\n",decideantflag,MTO_ANT_SEL()));
++ #endif
++ }
++ if (decideantflag)
++ {
++ old_antenna[3]=old_antenna[2];//store antenna info
++ old_antenna[2]=old_antenna[1];
++ old_antenna[1]=old_antenna[0];
++ old_antenna[0]= MTO_ANT_MAC();
++ }
++ #ifdef _PE_DTO_DUMP_
++ WBDEBUG(("[HHDTO]:**old antenna=[%d][%d][%d][%d]\n",old_antenna[0],old_antenna[1],old_antenna[2],old_antenna[3]));
++ #endif
++ if (old_antenna[0]!=old_antenna[1])
++ AntennaToggleBkoffTimer=0;
++ else if (old_antenna[1]!=old_antenna[2])
++ AntennaToggleBkoffTimer=1;
++ else if (old_antenna[2]!=old_antenna[3])
++ AntennaToggleBkoffTimer=2;
++ else
++ AntennaToggleBkoffTimer=4;
++
++ #ifdef _PE_DTO_DUMP_
++ WBDEBUG(("[HHDTO]:**back off timer=%d",AntennaToggleBkoffTimer));
++ #endif
++
++ ResetDTO_RxInfo(MTO_ANT_MAC(), MTO_FUNC_INPUT_DATA);
++ if (AntennaToggleBkoffTimer==0 && decideantflag)
++ MTO_TOGGLE_STATE() = TOGGLE_STATE_WAIT0;
++ else
++ MTO_TOGGLE_STATE() = TOGGLE_STATE_IDLE;
++ break;
++ }
++
++}
++
++void multiagc(MTO_FUNC_INPUT, u8 high_gain_mode )
++{
++ s32 rssi;
++ hw_data_t *pHwData = MTO_HAL();
++
++ sme_get_rssi(MTO_FUNC_INPUT_DATA, &rssi);
++
++ if( (RF_WB_242 == pHwData->phy_type) ||
++ (RF_WB_242_1 == pHwData->phy_type) ) // 20060619.5 Add
++ {
++ if (high_gain_mode==1)
++ {
++ //hw_set_dxx_reg(phw_data, 0x0C, 0xf8f52230);
++ //hw_set_dxx_reg(phw_data, 0x20, 0x06C43440);
++ Wb35Reg_Write( pHwData, 0x100C, 0xF2F32232 ); // 940916 0xf8f52230 );
++ Wb35Reg_Write( pHwData, 0x1020, 0x04cb3440 ); // 940915 0x06C43440
++ }
++ else if (high_gain_mode==0)
++ {
++ //hw_set_dxx_reg(phw_data, 0x0C, 0xEEEE000D);
++ //hw_set_dxx_reg(phw_data, 0x20, 0x06c41440);
++ Wb35Reg_Write( pHwData, 0x100C, 0xEEEE000D );
++ Wb35Reg_Write( pHwData, 0x1020, 0x04cb1440 ); // 940915 0x06c41440
++ }
++ #ifdef _PE_DTO_DUMP_
++ WBDEBUG(("[HHDTOAGC] **rssi=%d, high gain mode=%d", rssi, high_gain_mode));
++ #endif
++ }
++}
++
++void TxPwrControl(MTO_FUNC_INPUT)
++{
++ s32 rssi;
++ hw_data_t *pHwData = MTO_HAL();
++
++ sme_get_rssi(MTO_FUNC_INPUT_DATA, &rssi);
++ if( (RF_WB_242 == pHwData->phy_type) ||
++ (RF_WB_242_1 == pHwData->phy_type) ) // 20060619.5 Add
++ {
++ static u8 high_gain_mode; //this is for winbond RF switch LNA
++ //using different register setting
++
++ if (high_gain_mode==1)
++ {
++ if( rssi > MTO_DATA().RSSI_high )
++ {
++ //hw_set_dxx_reg(phw_data, 0x0C, 0xf8f52230);
++ //hw_set_dxx_reg(phw_data, 0x20, 0x05541640);
++ high_gain_mode=0;
++ }
++ else
++ {
++ //hw_set_dxx_reg(phw_data, 0x0C, 0xf8f51830);
++ //hw_set_dxx_reg(phw_data, 0x20, 0x05543E40);
++ high_gain_mode=1;
++ }
++ }
++ else //if (high_gain_mode==0)
++ {
++ if( rssi < MTO_DATA().RSSI_low )
++ {
++ //hw_set_dxx_reg(phw_data, 0x0C, 0xf8f51830);
++ //hw_set_dxx_reg(phw_data, 0x20, 0x05543E40);
++ high_gain_mode=1;
++ }
++ else
++ {
++ //hw_set_dxx_reg(phw_data, 0x0C, 0xf8f52230);
++ //hw_set_dxx_reg(phw_data, 0x20, 0x05541640);
++ high_gain_mode=0;
++ }
++ }
++
++ // Always high gain 20051014. Using the initial value only.
++ multiagc(MTO_FUNC_INPUT_DATA, high_gain_mode);
++ }
++}
++
++
++u8 CalcNewRate(MTO_FUNC_INPUT, u8 old_rate, u32 retry_cnt, u32 tx_frag_cnt)
++{
++ int i;
++ u8 new_rate;
++ u32 retry_rate;
++ int TxThrouput1, TxThrouput2, TxThrouput3, BestThroupht;
++
++ if(tx_frag_cnt < MTOPARA_TXCOUNT_TH_FOR_CALC_RATE()) //too few packets transmit
++ {
++ return 0xff;
++ }
++ retry_rate = Divide(retry_cnt * 100, tx_frag_cnt);
++
++ if(retry_rate > 90) retry_rate = 90; //always truncate to 90% due to lookup table size
++ #ifdef _PE_DTO_DUMP_
++ WBDEBUG(("##### Current level =%d, Retry count =%d, Frag count =%d\n",
++ old_rate, retry_cnt, tx_frag_cnt));
++ WBDEBUG(("*##* Retry rate =%d, throughput =%d\n",
++ retry_rate, Rate_PER_TBL[retry_rate][old_rate]));
++ WBDEBUG(("TxRateRec.tx_rate =%d, Retry rate = %d, throughput = %d\n",
++ TxRateRec.tx_rate, TxRateRec.tx_retry_rate,
++ Rate_PER_TBL[TxRateRec.tx_retry_rate][Level2PerTbl[TxRateRec.tx_rate]]));
++ WBDEBUG(("old_rate-1 =%d, Retry rate = %d, throughput = %d\n",
++ old_rate-1, retryrate_rec[old_rate-1],
++ Rate_PER_TBL[retryrate_rec[old_rate-1]][old_rate-1]));
++ WBDEBUG(("old_rate+1 =%d, Retry rate = %d, throughput = %d\n",
++ old_rate+1, retryrate_rec[old_rate+1],
++ Rate_PER_TBL[retryrate_rec[old_rate+1]][old_rate+1]));
++ #endif
++
++ //following is for record the retry rate at the different data rate
++ if (abs(retry_rate-retryrate_rec[old_rate])<50)//---the per TH
++ retryrate_rec[old_rate] = retry_rate; //update retry rate
++ else
++ {
++ for (i=0;i<MTO_DataRateAvailableLevel;i++) //reset all retry rate
++ retryrate_rec[i]=0;
++ retryrate_rec[old_rate] = retry_rate;
++ #ifdef _PE_DTO_DUMP_
++ WBDEBUG(("Reset retry rate table\n"));
++ #endif
++ }
++
++ if(TxRateRec.tx_rate > old_rate) //Decrease Tx Rate
++ {
++ TxThrouput1 = Rate_PER_TBL[TxRateRec.tx_retry_rate][Level2PerTbl[TxRateRec.tx_rate]];
++ TxThrouput2 = Rate_PER_TBL[retry_rate][Level2PerTbl[old_rate]];
++ if(TxThrouput1 > TxThrouput2)
++ {
++ new_rate = TxRateRec.tx_rate;
++ BestThroupht = TxThrouput1;
++ }
++ else
++ {
++ new_rate = old_rate;
++ BestThroupht = TxThrouput2;
++ }
++ if((old_rate > 0) &&(retry_rate>MTOPARA_TXRATE_DEC_TH())) //Min Rate
++ {
++ TxThrouput3 = Rate_PER_TBL[retryrate_rec[old_rate-1]][Level2PerTbl[old_rate-1]];
++ if(BestThroupht < TxThrouput3)
++ {
++ new_rate = old_rate - 1;
++ #ifdef _PE_DTO_DUMP_
++ WBDEBUG(("--------\n"));
++ #endif
++ BestThroupht = TxThrouput3;
++ }
++ }
++ }
++ else if(TxRateRec.tx_rate < old_rate) //Increase Tx Rate
++ {
++ TxThrouput1 = Rate_PER_TBL[TxRateRec.tx_retry_rate][Level2PerTbl[TxRateRec.tx_rate]];
++ TxThrouput2 = Rate_PER_TBL[retry_rate][Level2PerTbl[old_rate]];
++ if(TxThrouput1 > TxThrouput2)
++ {
++ new_rate = TxRateRec.tx_rate;
++ BestThroupht = TxThrouput1;
++ }
++ else
++ {
++ new_rate = old_rate;
++ BestThroupht = TxThrouput2;
++ }
++ if ((old_rate < MTO_DataRateAvailableLevel - 1)&&(retry_rate<MTOPARA_TXRATE_INC_TH()))
++ {
++ //TxThrouput3 = Rate_PER_TBL[retryrate_rec[old_rate+1]][Level2PerTbl[old_rate+1]];
++ if (retryrate_rec[old_rate+1] > MTOPARA_TXRETRYRATE_REDUCE())
++ TxThrouput3 = Rate_PER_TBL[retryrate_rec[old_rate+1]-MTOPARA_TXRETRYRATE_REDUCE()][Level2PerTbl[old_rate+1]];
++ else
++ TxThrouput3 = Rate_PER_TBL[retryrate_rec[old_rate+1]][Level2PerTbl[old_rate+1]];
++ if(BestThroupht < TxThrouput3)
++ {
++ new_rate = old_rate + 1;
++ #ifdef _PE_DTO_DUMP_
++ WBDEBUG(("++++++++++\n"));
++ #endif
++ BestThroupht = TxThrouput3;
++ }
++ }
++ }
++ else //Tx Rate no change
++ {
++ TxThrouput2 = Rate_PER_TBL[retry_rate][Level2PerTbl[old_rate]];
++ new_rate = old_rate;
++ BestThroupht = TxThrouput2;
++
++ if (retry_rate <MTOPARA_TXRATE_EQ_TH()) //th for change higher rate
++ {
++ if(old_rate < MTO_DataRateAvailableLevel - 1)
++ {
++ //TxThrouput3 = Rate_PER_TBL[retryrate_rec[old_rate+1]][Level2PerTbl[old_rate+1]];
++ if (retryrate_rec[old_rate+1] > MTOPARA_TXRETRYRATE_REDUCE())
++ TxThrouput3 = Rate_PER_TBL[retryrate_rec[old_rate+1]-MTOPARA_TXRETRYRATE_REDUCE()][Level2PerTbl[old_rate+1]];
++ else
++ TxThrouput3 = Rate_PER_TBL[retryrate_rec[old_rate+1]][Level2PerTbl[old_rate+1]];
++ if(BestThroupht < TxThrouput3)
++ {
++ new_rate = old_rate + 1;
++ BestThroupht = TxThrouput3;
++ #ifdef _PE_DTO_DUMP_
++ WBDEBUG(("=++++++++++\n"));
++ #endif
++ }
++ }
++ }
++ else
++ if(old_rate > 0) //Min Rate
++ {
++ TxThrouput3 = Rate_PER_TBL[retryrate_rec[old_rate-1]][Level2PerTbl[old_rate-1]];
++ if(BestThroupht < TxThrouput3)
++ {
++ new_rate = old_rate - 1;
++ #ifdef _PE_DTO_DUMP_
++ WBDEBUG(("=--------\n"));
++ #endif
++ BestThroupht = TxThrouput3;
++ }
++ }
++ }
++
++ if (!LOCAL_IS_IBSS_MODE())
++ {
++ max_rssi_rate = GetMaxRateLevelFromRSSI();
++ #ifdef _PE_DTO_DUMP_
++ WBDEBUG(("[MTO]:RSSI2Rate=%d\n", MTO_Data_Rate_Tbl[max_rssi_rate]));
++ #endif
++ if(new_rate > max_rssi_rate)
++ new_rate = max_rssi_rate;
++ }
++
++ //save new rate;
++ TxRateRec.tx_rate = old_rate;
++ TxRateRec.tx_retry_rate = (u8) retry_rate;
++ TxRetryRate = retry_rate;
++ return new_rate;
++}
++
++void SmoothRSSI(s32 new_rssi)
++{
++ RSSISmoothed = RSSISmoothed + new_rssi - RSSIBuf[RSSIBufIndex];
++ RSSIBuf[RSSIBufIndex] = new_rssi;
++ RSSIBufIndex = (RSSIBufIndex + 1) % 10;
++}
++
++u8 GetMaxRateLevelFromRSSI(void)
++{
++ u8 i;
++ u8 TxRate;
++
++ for(i=0;i<RSSI2RATE_SIZE;i++)
++ {
++ if(RSSISmoothed > RSSI2RateTbl[i].RSSI)
++ break;
++ }
++ #ifdef _PE_DTO_DUMP_
++ WBDEBUG(("[MTO]:RSSI=%d\n", Divide(RSSISmoothed, 10)));
++ #endif
++ if(i < RSSI2RATE_SIZE)
++ TxRate = RSSI2RateTbl[i].TxRate;
++ else
++ TxRate = 2; //divided by 2 = 1Mbps
++
++ for(i=MTO_DataRateAvailableLevel-1;i>0;i--)
++ {
++ if(TxRate >=MTO_Data_Rate_Tbl[i])
++ break;
++ }
++ return i;
++}
++
++//===========================================================================
++// Description:
++// If we enable DTO, we will ignore the tx count with different tx rate from
++// DTO rate. This is because when we adjust DTO tx rate, there could be some
++// packets in the tx queue with previous tx rate
++void MTO_SetTxCount(MTO_FUNC_INPUT, u8 tx_rate, u8 index)
++{
++ MTO_TXFLOWCOUNT()++;
++ if ((MTO_ENABLE==1) && (MTO_RATE_CHANGE_ENABLE()==1))
++ {
++ if(tx_rate == MTO_DATA_RATE())
++ {
++ if (index == 0)
++ {
++ if (boSparseTxTraffic)
++ MTO_HAL()->dto_tx_frag_count += MTOPARA_PERIODIC_CHECK_CYCLE();
++ else
++ MTO_HAL()->dto_tx_frag_count += 1;
++ }
++ else
++ {
++ if (index<8)
++ {
++ MTO_HAL()->dto_tx_retry_count += index;
++ MTO_HAL()->dto_tx_frag_count += (index+1);
++ }
++ else
++ {
++ MTO_HAL()->dto_tx_retry_count += 7;
++ MTO_HAL()->dto_tx_frag_count += 7;
++ }
++ }
++ }
++ else if(MTO_DATA_RATE()>48 && tx_rate ==48)
++ {//ALFRED
++ if (index<3) //for reduciing data rate scheme ,
++ //do not calcu different data rate
++ //3 is the reducing data rate at retry
++ {
++ MTO_HAL()->dto_tx_retry_count += index;
++ MTO_HAL()->dto_tx_frag_count += (index+1);
++ }
++ else
++ {
++ MTO_HAL()->dto_tx_retry_count += 3;
++ MTO_HAL()->dto_tx_frag_count += 3;
++ }
++
++ }
++ }
++ else
++ {
++ MTO_HAL()->dto_tx_retry_count += index;
++ MTO_HAL()->dto_tx_frag_count += (index+1);
++ }
++ TotalTxPkt ++;
++ TotalTxPktRetry += (index+1);
++
++ PeriodTotalTxPkt ++;
++ PeriodTotalTxPktRetry += (index+1);
++}
++
++u8 MTO_GetTxFallbackRate(MTO_FUNC_INPUT)
++{
++ return MTO_DATA_FALLBACK_RATE();
++}
++
++
++//===========================================================================
++// MTO_TxFailed --
++//
++// Description:
++// Failure of transmitting a packet indicates that certain MTO parmeters
++// may need to be adjusted. This function is called when NIC just failed
++// to transmit a packet or when MSDULifeTime expired.
++//
++// Arguments:
++// Adapter - The pointer to the Miniport Adapter Context
++//
++// Return Value:
++// None
++//============================================================================
++void MTO_TxFailed(MTO_FUNC_INPUT)
++{
++ return;
++}
++
++int Divide(int a, int b)
++{
++ if (b==0) b=1;
++ return a/b;
++}
++
++
+diff --git a/drivers/staging/winbond/mto.h b/drivers/staging/winbond/mto.h
+new file mode 100644
+index 0000000..f47936f
+--- /dev/null
++++ b/drivers/staging/winbond/mto.h
+@@ -0,0 +1,265 @@
++//==================================================================
++// MTO.H
++//
++// Revision history
++//=================================
++// 20030110 UN20 Pete Chao
++// Initial Release
++//
++// Copyright (c) 2003 Winbond Electronics Corp. All rights reserved.
++//==================================================================
++#ifndef __MTO_H__
++#define __MTO_H__
++
++#define MTO_DEFAULT_TH_CNT 5
++#define MTO_DEFAULT_TH_SQ3 112 //OLD IS 13 reference JohnXu
++#define MTO_DEFAULT_TH_IDLE_SLOT 15
++#define MTO_DEFAULT_TH_PR_INTERF 30
++#define MTO_DEFAULT_TMR_AGING 25 // unit: slot time 10 reference JohnXu
++#define MTO_DEFAULT_TMR_PERIODIC 5 // unit: slot time
++
++#define MTO_ANTENNA_DIVERSITY_OFF 0
++#define MTO_ANTENNA_DIVERSITY_ON 1
++
++// LA20040210_DTO kevin
++//#define MTO_PREAMBLE_LONG 0
++//#define MTO_PREAMBLE_SHORT 1
++#define MTO_PREAMBLE_LONG WLAN_PREAMBLE_TYPE_LONG
++#define MTO_PREAMBLE_SHORT WLAN_PREAMBLE_TYPE_SHORT
++
++typedef enum {
++ TOGGLE_STATE_IDLE = 0,
++ TOGGLE_STATE_WAIT0 = 1,
++ TOGGLE_STATE_WAIT1 = 2,
++ TOGGLE_STATE_MAKEDESISION = 3,
++ TOGGLE_STATE_BKOFF = 4
++} TOGGLE_STATE;
++
++typedef enum {
++ RATE_CHGSTATE_IDLE = 0,
++ RATE_CHGSTATE_CALCULATE = 1,
++ RATE_CHGSTATE_BACKOFF = 2
++} TX_RATE_REDUCTION_STATE;
++
++//============================================================================
++// struct _MTOParameters --
++//
++// Defines the parameters used in the MAC Throughput Optimization algorithm
++//============================================================================
++typedef struct _MTO_PARAMETERS
++{
++ u8 Th_Fixant;
++ u8 Th_Cnt;
++ u8 Th_SQ3;
++ u8 Th_IdleSlot;
++
++ u16 Tmr_Aging;
++ u8 Th_PrInterf;
++ u8 Tmr_Periodic;
++
++ //--------- wkchen added -------------
++ u32 TxFlowCount; //to judge what kind the tx flow(sparse or busy) is
++ //------------------------------------------------
++
++ //--------- DTO threshold parameters -------------
++ u16 DTO_PeriodicCheckCycle;
++ u16 DTO_RssiThForAntDiv;
++
++ u16 DTO_TxCountThForCalcNewRate;
++ u16 DTO_TxRateIncTh;
++
++ u16 DTO_TxRateDecTh;
++ u16 DTO_TxRateEqTh;
++
++ u16 DTO_TxRateBackOff;
++ u16 DTO_TxRetryRateReduce;
++
++ u16 DTO_TxPowerIndex; //0 ~ 31
++ u16 reserved_1;
++ //------------------------------------------------
++
++ u8 PowerChangeEnable;
++ u8 AntDiversityEnable;
++ u8 Ant_mac;
++ u8 Ant_div;
++
++ u8 CCA_Mode;
++ u8 CCA_Mode_Setup;
++ u8 Preamble_Type;
++ u8 PreambleChangeEnable;
++
++ u8 DataRateLevel;
++ u8 DataRateChangeEnable;
++ u8 FragThresholdLevel;
++ u8 FragThresholdChangeEnable;
++
++ u16 RTSThreshold;
++ u16 RTSThreshold_Setup;
++
++ u32 AvgIdleSlot;
++ u32 Pr_Interf;
++ u32 AvgGapBtwnInterf;
++
++ u8 RTSChangeEnable;
++ u8 Ant_sel;
++ u8 aging_timeout;
++ u8 reserved_2;
++
++ u32 Cnt_Ant[2];
++ u32 SQ_Ant[2];
++
++// 20040510 remove from globe vairable
++ u32 TmrCnt;
++ u32 BackoffTmr;
++ TOGGLE_STATE ToggleState;
++ TX_RATE_REDUCTION_STATE TxRateReductionState;
++
++ u8 Last_Rate;
++ u8 Co_efficent;
++ u8 FallbackRateLevel;
++ u8 OfdmRateLevel;
++
++ u8 RatePolicy;
++ u8 reserved_3[3];
++
++ // For RSSI turning
++ s32 RSSI_high;
++ s32 RSSI_low;
++
++} MTO_PARAMETERS, *PMTO_PARAMETERS;
++
++
++#define MTO_FUNC_INPUT PWB32_ADAPTER Adapter
++#define MTO_FUNC_INPUT_DATA Adapter
++#define MTO_DATA() (Adapter->sMtoPara)
++#define MTO_HAL() (&Adapter->sHwData)
++#define MTO_SET_PREAMBLE_TYPE(x) // 20040511 Turbo mark LM_PREAMBLE_TYPE(&pcore_data->lm_data) = (x)
++#define MTO_ENABLE (Adapter->sLocalPara.TxRateMode == RATE_AUTO)
++#define MTO_TXPOWER_FROM_EEPROM (Adapter->sHwData.PowerIndexFromEEPROM)
++#define LOCAL_ANTENNA_NO() (Adapter->sLocalPara.bAntennaNo)
++#define LOCAL_IS_CONNECTED() (Adapter->sLocalPara.wConnectedSTAindex != 0)
++#define LOCAL_IS_IBSS_MODE() (Adapter->asBSSDescriptElement[Adapter->sLocalPara.wConnectedSTAindex].bBssType == IBSS_NET)
++#define MTO_INITTXRATE_MODE (Adapter->sHwData.SoftwareSet&0x2) //bit 1
++// 20040510 Turbo add
++#define MTO_TMR_CNT() MTO_DATA().TmrCnt
++#define MTO_TOGGLE_STATE() MTO_DATA().ToggleState
++#define MTO_TX_RATE_REDUCTION_STATE() MTO_DATA().TxRateReductionState
++#define MTO_BACKOFF_TMR() MTO_DATA().BackoffTmr
++#define MTO_LAST_RATE() MTO_DATA().Last_Rate
++#define MTO_CO_EFFICENT() MTO_DATA().Co_efficent
++
++#define MTO_TH_CNT() MTO_DATA().Th_Cnt
++#define MTO_TH_SQ3() MTO_DATA().Th_SQ3
++#define MTO_TH_IDLE_SLOT() MTO_DATA().Th_IdleSlot
++#define MTO_TH_PR_INTERF() MTO_DATA().Th_PrInterf
++
++#define MTO_TMR_AGING() MTO_DATA().Tmr_Aging
++#define MTO_TMR_PERIODIC() MTO_DATA().Tmr_Periodic
++
++#define MTO_POWER_CHANGE_ENABLE() MTO_DATA().PowerChangeEnable
++#define MTO_ANT_DIVERSITY_ENABLE() Adapter->sLocalPara.boAntennaDiversity
++#define MTO_ANT_MAC() MTO_DATA().Ant_mac
++#define MTO_ANT_DIVERSITY() MTO_DATA().Ant_div
++#define MTO_CCA_MODE() MTO_DATA().CCA_Mode
++#define MTO_CCA_MODE_SETUP() MTO_DATA().CCA_Mode_Setup
++#define MTO_PREAMBLE_TYPE() MTO_DATA().Preamble_Type
++#define MTO_PREAMBLE_CHANGE_ENABLE() MTO_DATA().PreambleChangeEnable
++
++#define MTO_RATE_LEVEL() MTO_DATA().DataRateLevel
++#define MTO_FALLBACK_RATE_LEVEL() MTO_DATA().FallbackRateLevel
++#define MTO_OFDM_RATE_LEVEL() MTO_DATA().OfdmRateLevel
++#define MTO_RATE_CHANGE_ENABLE() MTO_DATA().DataRateChangeEnable
++#define MTO_FRAG_TH_LEVEL() MTO_DATA().FragThresholdLevel
++#define MTO_FRAG_CHANGE_ENABLE() MTO_DATA().FragThresholdChangeEnable
++#define MTO_RTS_THRESHOLD() MTO_DATA().RTSThreshold
++#define MTO_RTS_CHANGE_ENABLE() MTO_DATA().RTSChangeEnable
++#define MTO_RTS_THRESHOLD_SETUP() MTO_DATA().RTSThreshold_Setup
++
++#define MTO_AVG_IDLE_SLOT() MTO_DATA().AvgIdleSlot
++#define MTO_PR_INTERF() MTO_DATA().Pr_Interf
++#define MTO_AVG_GAP_BTWN_INTERF() MTO_DATA().AvgGapBtwnInterf
++
++#define MTO_ANT_SEL() MTO_DATA().Ant_sel
++#define MTO_CNT_ANT(x) MTO_DATA().Cnt_Ant[(x)]
++#define MTO_SQ_ANT(x) MTO_DATA().SQ_Ant[(x)]
++#define MTO_AGING_TIMEOUT() MTO_DATA().aging_timeout
++
++
++#define MTO_TXFLOWCOUNT() MTO_DATA().TxFlowCount
++//--------- DTO threshold parameters -------------
++#define MTOPARA_PERIODIC_CHECK_CYCLE() MTO_DATA().DTO_PeriodicCheckCycle
++#define MTOPARA_RSSI_TH_FOR_ANTDIV() MTO_DATA().DTO_RssiThForAntDiv
++#define MTOPARA_TXCOUNT_TH_FOR_CALC_RATE() MTO_DATA().DTO_TxCountThForCalcNewRate
++#define MTOPARA_TXRATE_INC_TH() MTO_DATA().DTO_TxRateIncTh
++#define MTOPARA_TXRATE_DEC_TH() MTO_DATA().DTO_TxRateDecTh
++#define MTOPARA_TXRATE_EQ_TH() MTO_DATA().DTO_TxRateEqTh
++#define MTOPARA_TXRATE_BACKOFF() MTO_DATA().DTO_TxRateBackOff
++#define MTOPARA_TXRETRYRATE_REDUCE() MTO_DATA().DTO_TxRetryRateReduce
++#define MTOPARA_TXPOWER_INDEX() MTO_DATA().DTO_TxPowerIndex
++//------------------------------------------------
++
++
++extern u8 MTO_Data_Rate_Tbl[];
++extern u16 MTO_Frag_Th_Tbl[];
++
++#define MTO_DATA_RATE() MTO_Data_Rate_Tbl[MTO_RATE_LEVEL()]
++#define MTO_DATA_FALLBACK_RATE() MTO_Data_Rate_Tbl[MTO_FALLBACK_RATE_LEVEL()] //next level
++#define MTO_FRAG_TH() MTO_Frag_Th_Tbl[MTO_FRAG_TH_LEVEL()]
++
++typedef struct {
++ u8 tx_rate;
++ u8 tx_retry_rate;
++} TXRETRY_REC;
++
++typedef struct _STATISTICS_INFO {
++ u32 Rate54M;
++ u32 Rate48M;
++ u32 Rate36M;
++ u32 Rate24M;
++ u32 Rate18M;
++ u32 Rate12M;
++ u32 Rate9M;
++ u32 Rate6M;
++ u32 Rate11MS;
++ u32 Rate11ML;
++ u32 Rate55MS;
++ u32 Rate55ML;
++ u32 Rate2MS;
++ u32 Rate2ML;
++ u32 Rate1M;
++ u32 Rate54MOK;
++ u32 Rate48MOK;
++ u32 Rate36MOK;
++ u32 Rate24MOK;
++ u32 Rate18MOK;
++ u32 Rate12MOK;
++ u32 Rate9MOK;
++ u32 Rate6MOK;
++ u32 Rate11MSOK;
++ u32 Rate11MLOK;
++ u32 Rate55MSOK;
++ u32 Rate55MLOK;
++ u32 Rate2MSOK;
++ u32 Rate2MLOK;
++ u32 Rate1MOK;
++ u32 SQ3;
++ s32 RSSIAVG;
++ s32 RSSIMAX;
++ s32 TXRATE;
++ s32 TxRetryRate;
++ s32 BSS_PK_CNT;
++ s32 NIDLESLOT;
++ s32 SLOT_CNT;
++ s32 INTERF_CNT;
++ s32 GAP_CNT;
++ s32 DS_EVM;
++ s32 RcvBeaconNum;
++ s32 RXRATE;
++ s32 RxBytes;
++ s32 TxBytes;
++ s32 Antenna;
++} STATISTICS_INFO, *PSTATISTICS_INFO;
++
++#endif //__MTO_H__
++
++
+diff --git a/drivers/staging/winbond/mto_f.h b/drivers/staging/winbond/mto_f.h
+new file mode 100644
+index 0000000..30b3df2
+--- /dev/null
++++ b/drivers/staging/winbond/mto_f.h
+@@ -0,0 +1,7 @@
++extern void MTO_Init(PWB32_ADAPTER);
++extern void MTO_PeriodicTimerExpired(PWB32_ADAPTER);
++extern void MTO_SetDTORateRange(PWB32_ADAPTER, u8 *, u8);
++extern u8 MTO_GetTxRate(MTO_FUNC_INPUT, u32 fpdu_len);
++extern u8 MTO_GetTxFallbackRate(MTO_FUNC_INPUT);
++extern void MTO_SetTxCount(MTO_FUNC_INPUT, u8 t0, u8 index);
++
+diff --git a/drivers/staging/winbond/os_common.h b/drivers/staging/winbond/os_common.h
+new file mode 100644
+index 0000000..e24ff41
+--- /dev/null
++++ b/drivers/staging/winbond/os_common.h
+@@ -0,0 +1,2 @@
++#include "linux/sysdef.h"
++
+diff --git a/drivers/staging/winbond/phy_calibration.c b/drivers/staging/winbond/phy_calibration.c
+new file mode 100644
+index 0000000..272a650
+--- /dev/null
++++ b/drivers/staging/winbond/phy_calibration.c
+@@ -0,0 +1,1759 @@
++/*
++ * phy_302_calibration.c
++ *
++ * Copyright (C) 2002, 2005 Winbond Electronics Corp.
++ *
++ * modification history
++ * ---------------------------------------------------------------------------
++ * 0.01.001, 2003-04-16, Kevin created
++ *
++ */
++
++/****************** INCLUDE FILES SECTION ***********************************/
++#include "os_common.h"
++#include "phy_calibration.h"
++
++
++/****************** DEBUG CONSTANT AND MACRO SECTION ************************/
++
++/****************** LOCAL CONSTANT AND MACRO SECTION ************************/
++#define LOOP_TIMES 20
++#define US 1000//MICROSECOND
++
++#define AG_CONST 0.6072529350
++#define FIXED(X) ((s32)((X) * 32768.0))
++#define DEG2RAD(X) 0.017453 * (X)
++
++/****************** LOCAL TYPE DEFINITION SECTION ***************************/
++typedef s32 fixed; /* 16.16 fixed-point */
++
++static const fixed Angles[]=
++{
++ FIXED(DEG2RAD(45.0)), FIXED(DEG2RAD(26.565)), FIXED(DEG2RAD(14.0362)),
++ FIXED(DEG2RAD(7.12502)), FIXED(DEG2RAD(3.57633)), FIXED(DEG2RAD(1.78991)),
++ FIXED(DEG2RAD(0.895174)),FIXED(DEG2RAD(0.447614)),FIXED(DEG2RAD(0.223811)),
++ FIXED(DEG2RAD(0.111906)),FIXED(DEG2RAD(0.055953)),FIXED(DEG2RAD(0.027977))
++};
++
++/****************** LOCAL FUNCTION DECLARATION SECTION **********************/
++//void _phy_rf_write_delay(hw_data_t *phw_data);
++//void phy_init_rf(hw_data_t *phw_data);
++
++/****************** FUNCTION DEFINITION SECTION *****************************/
++
++s32 _s13_to_s32(u32 data)
++{
++ u32 val;
++
++ val = (data & 0x0FFF);
++
++ if ((data & BIT(12)) != 0)
++ {
++ val |= 0xFFFFF000;
++ }
++
++ return ((s32) val);
++}
++
++u32 _s32_to_s13(s32 data)
++{
++ u32 val;
++
++ if (data > 4095)
++ {
++ data = 4095;
++ }
++ else if (data < -4096)
++ {
++ data = -4096;
++ }
++
++ val = data & 0x1FFF;
++
++ return val;
++}
++
++/****************************************************************************/
++s32 _s4_to_s32(u32 data)
++{
++ s32 val;
++
++ val = (data & 0x0007);
++
++ if ((data & BIT(3)) != 0)
++ {
++ val |= 0xFFFFFFF8;
++ }
++
++ return val;
++}
++
++u32 _s32_to_s4(s32 data)
++{
++ u32 val;
++
++ if (data > 7)
++ {
++ data = 7;
++ }
++ else if (data < -8)
++ {
++ data = -8;
++ }
++
++ val = data & 0x000F;
++
++ return val;
++}
++
++/****************************************************************************/
++s32 _s5_to_s32(u32 data)
++{
++ s32 val;
++
++ val = (data & 0x000F);
++
++ if ((data & BIT(4)) != 0)
++ {
++ val |= 0xFFFFFFF0;
++ }
++
++ return val;
++}
++
++u32 _s32_to_s5(s32 data)
++{
++ u32 val;
++
++ if (data > 15)
++ {
++ data = 15;
++ }
++ else if (data < -16)
++ {
++ data = -16;
++ }
++
++ val = data & 0x001F;
++
++ return val;
++}
++
++/****************************************************************************/
++s32 _s6_to_s32(u32 data)
++{
++ s32 val;
++
++ val = (data & 0x001F);
++
++ if ((data & BIT(5)) != 0)
++ {
++ val |= 0xFFFFFFE0;
++ }
++
++ return val;
++}
++
++u32 _s32_to_s6(s32 data)
++{
++ u32 val;
++
++ if (data > 31)
++ {
++ data = 31;
++ }
++ else if (data < -32)
++ {
++ data = -32;
++ }
++
++ val = data & 0x003F;
++
++ return val;
++}
++
++/****************************************************************************/
++s32 _s9_to_s32(u32 data)
++{
++ s32 val;
++
++ val = data & 0x00FF;
++
++ if ((data & BIT(8)) != 0)
++ {
++ val |= 0xFFFFFF00;
++ }
++
++ return val;
++}
++
++u32 _s32_to_s9(s32 data)
++{
++ u32 val;
++
++ if (data > 255)
++ {
++ data = 255;
++ }
++ else if (data < -256)
++ {
++ data = -256;
++ }
++
++ val = data & 0x01FF;
++
++ return val;
++}
++
++/****************************************************************************/
++s32 _floor(s32 n)
++{
++ if (n > 0)
++ {
++ n += 5;
++ }
++ else
++ {
++ n -= 5;
++ }
++
++ return (n/10);
++}
++
++/****************************************************************************/
++// The following code is sqare-root function.
++// sqsum is the input and the output is sq_rt;
++// The maximum of sqsum = 2^27 -1;
++u32 _sqrt(u32 sqsum)
++{
++ u32 sq_rt;
++
++ int g0, g1, g2, g3, g4;
++ int seed;
++ int next;
++ int step;
++
++ g4 = sqsum / 100000000;
++ g3 = (sqsum - g4*100000000) /1000000;
++ g2 = (sqsum - g4*100000000 - g3*1000000) /10000;
++ g1 = (sqsum - g4*100000000 - g3*1000000 - g2*10000) /100;
++ g0 = (sqsum - g4*100000000 - g3*1000000 - g2*10000 - g1*100);
++
++ next = g4;
++ step = 0;
++ seed = 0;
++ while (((seed+1)*(step+1)) <= next)
++ {
++ step++;
++ seed++;
++ }
++
++ sq_rt = seed * 10000;
++ next = (next-(seed*step))*100 + g3;
++
++ step = 0;
++ seed = 2 * seed * 10;
++ while (((seed+1)*(step+1)) <= next)
++ {
++ step++;
++ seed++;
++ }
++
++ sq_rt = sq_rt + step * 1000;
++ next = (next - seed * step) * 100 + g2;
++ seed = (seed + step) * 10;
++ step = 0;
++ while (((seed+1)*(step+1)) <= next)
++ {
++ step++;
++ seed++;
++ }
++
++ sq_rt = sq_rt + step * 100;
++ next = (next - seed * step) * 100 + g1;
++ seed = (seed + step) * 10;
++ step = 0;
++
++ while (((seed+1)*(step+1)) <= next)
++ {
++ step++;
++ seed++;
++ }
++
++ sq_rt = sq_rt + step * 10;
++ next = (next - seed* step) * 100 + g0;
++ seed = (seed + step) * 10;
++ step = 0;
++
++ while (((seed+1)*(step+1)) <= next)
++ {
++ step++;
++ seed++;
++ }
++
++ sq_rt = sq_rt + step;
++
++ return sq_rt;
++}
++
++/****************************************************************************/
++void _sin_cos(s32 angle, s32 *sin, s32 *cos)
++{
++ fixed X, Y, TargetAngle, CurrAngle;
++ unsigned Step;
++
++ X=FIXED(AG_CONST); // AG_CONST * cos(0)
++ Y=0; // AG_CONST * sin(0)
++ TargetAngle=abs(angle);
++ CurrAngle=0;
++
++ for (Step=0; Step < 12; Step++)
++ {
++ fixed NewX;
++
++ if(TargetAngle > CurrAngle)
++ {
++ NewX=X - (Y >> Step);
++ Y=(X >> Step) + Y;
++ X=NewX;
++ CurrAngle += Angles[Step];
++ }
++ else
++ {
++ NewX=X + (Y >> Step);
++ Y=-(X >> Step) + Y;
++ X=NewX;
++ CurrAngle -= Angles[Step];
++ }
++ }
++
++ if (angle > 0)
++ {
++ *cos = X;
++ *sin = Y;
++ }
++ else
++ {
++ *cos = X;
++ *sin = -Y;
++ }
++}
++
++
++void _reset_rx_cal(hw_data_t *phw_data)
++{
++ u32 val;
++
++ hw_get_dxx_reg(phw_data, 0x54, &val);
++
++ if (phw_data->revision == 0x2002) // 1st-cut
++ {
++ val &= 0xFFFF0000;
++ }
++ else // 2nd-cut
++ {
++ val &= 0x000003FF;
++ }
++
++ hw_set_dxx_reg(phw_data, 0x54, val);
++}
++
++
++// ************for winbond calibration*********
++//
++
++//
++//
++// *********************************************
++void _rxadc_dc_offset_cancellation_winbond(hw_data_t *phw_data, u32 frequency)
++{
++ u32 reg_agc_ctrl3;
++ u32 reg_a_acq_ctrl;
++ u32 reg_b_acq_ctrl;
++ u32 val;
++
++ PHY_DEBUG(("[CAL] -> [1]_rxadc_dc_offset_cancellation()\n"));
++ phy_init_rf(phw_data);
++
++ // set calibration channel
++ if( (RF_WB_242 == phw_data->phy_type) ||
++ (RF_WB_242_1 == phw_data->phy_type) ) // 20060619.5 Add
++ {
++ if ((frequency >= 2412) && (frequency <= 2484))
++ {
++ // w89rf242 change frequency to 2390Mhz
++ PHY_DEBUG(("[CAL] W89RF242/11G/Channel=2390Mhz\n"));
++ phy_set_rf_data(phw_data, 3, (3<<24)|0x025586);
++
++ }
++ }
++ else
++ {
++
++ }
++
++ // reset cancel_dc_i[9:5] and cancel_dc_q[4:0] in register DC_Cancel
++ hw_get_dxx_reg(phw_data, 0x5C, &val);
++ val &= ~(0x03FF);
++ hw_set_dxx_reg(phw_data, 0x5C, val);
++
++ // reset the TX and RX IQ calibration data
++ hw_set_dxx_reg(phw_data, 0x3C, 0);
++ hw_set_dxx_reg(phw_data, 0x54, 0);
++
++ hw_set_dxx_reg(phw_data, 0x58, 0x30303030); // IQ_Alpha Changed
++
++ // a. Disable AGC
++ hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, ®_agc_ctrl3);
++ reg_agc_ctrl3 &= ~BIT(2);
++ reg_agc_ctrl3 |= (MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
++ hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
++
++ hw_get_dxx_reg(phw_data, REG_AGC_CTRL5, &val);
++ val |= MASK_AGC_FIX_GAIN;
++ hw_set_dxx_reg(phw_data, REG_AGC_CTRL5, val);
++
++ // b. Turn off BB RX
++ hw_get_dxx_reg(phw_data, REG_A_ACQ_CTRL, ®_a_acq_ctrl);
++ reg_a_acq_ctrl |= MASK_AMER_OFF_REG;
++ hw_set_dxx_reg(phw_data, REG_A_ACQ_CTRL, reg_a_acq_ctrl);
++
++ hw_get_dxx_reg(phw_data, REG_B_ACQ_CTRL, ®_b_acq_ctrl);
++ reg_b_acq_ctrl |= MASK_BMER_OFF_REG;
++ hw_set_dxx_reg(phw_data, REG_B_ACQ_CTRL, reg_b_acq_ctrl);
++
++ // c. Make sure MAC is in receiving mode
++ // d. Turn ON ADC calibration
++ // - ADC calibrator is triggered by this signal rising from 0 to 1
++ hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &val);
++ val &= ~MASK_ADC_DC_CAL_STR;
++ hw_set_dxx_reg(phw_data, REG_MODE_CTRL, val);
++
++ val |= MASK_ADC_DC_CAL_STR;
++ hw_set_dxx_reg(phw_data, REG_MODE_CTRL, val);
++ pa_stall_execution(US); // *MUST* wait for a while
++
++ // e. The result are shown in "adc_dc_cal_i[8:0] and adc_dc_cal_q[8:0]"
++#ifdef _DEBUG
++ hw_get_dxx_reg(phw_data, REG_OFFSET_READ, &val);
++ PHY_DEBUG(("[CAL] REG_OFFSET_READ = 0x%08X\n", val));
++
++ PHY_DEBUG(("[CAL] ** adc_dc_cal_i = %d (0x%04X)\n",
++ _s9_to_s32(val&0x000001FF), val&0x000001FF));
++ PHY_DEBUG(("[CAL] ** adc_dc_cal_q = %d (0x%04X)\n",
++ _s9_to_s32((val&0x0003FE00)>>9), (val&0x0003FE00)>>9));
++#endif
++
++ hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &val);
++ val &= ~MASK_ADC_DC_CAL_STR;
++ hw_set_dxx_reg(phw_data, REG_MODE_CTRL, val);
++
++ // f. Turn on BB RX
++ //hw_get_dxx_reg(phw_data, REG_A_ACQ_CTRL, ®_a_acq_ctrl);
++ reg_a_acq_ctrl &= ~MASK_AMER_OFF_REG;
++ hw_set_dxx_reg(phw_data, REG_A_ACQ_CTRL, reg_a_acq_ctrl);
++
++ //hw_get_dxx_reg(phw_data, REG_B_ACQ_CTRL, ®_b_acq_ctrl);
++ reg_b_acq_ctrl &= ~MASK_BMER_OFF_REG;
++ hw_set_dxx_reg(phw_data, REG_B_ACQ_CTRL, reg_b_acq_ctrl);
++
++ // g. Enable AGC
++ //hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &val);
++ reg_agc_ctrl3 |= BIT(2);
++ reg_agc_ctrl3 &= ~(MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
++ hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
++}
++
++////////////////////////////////////////////////////////
++void _txidac_dc_offset_cancellation_winbond(hw_data_t *phw_data)
++{
++ u32 reg_agc_ctrl3;
++ u32 reg_mode_ctrl;
++ u32 reg_dc_cancel;
++ s32 iqcal_image_i;
++ s32 iqcal_image_q;
++ u32 sqsum;
++ s32 mag_0;
++ s32 mag_1;
++ s32 fix_cancel_dc_i = 0;
++ u32 val;
++ int loop;
++
++ PHY_DEBUG(("[CAL] -> [2]_txidac_dc_offset_cancellation()\n"));
++
++ // a. Set to "TX calibration mode"
++
++ //0x01 0xEE3FC2 ; 3B8FF ; Calibration (6a). enable TX IQ calibration loop circuits
++ phy_set_rf_data(phw_data, 1, (1<<24)|0xEE3FC2);
++ //0x0B 0x1905D6 ; 06417 ; Calibration (6b). enable TX I/Q cal loop squaring circuit
++ phy_set_rf_data(phw_data, 11, (11<<24)|0x1901D6);
++ //0x05 0x24C60A ; 09318 ; Calibration (6c). setting TX-VGA gain: TXGCH=2 & GPK=110 --> to be optimized
++ phy_set_rf_data(phw_data, 5, (5<<24)|0x24C48A);
++ //0x06 0x06880C ; 01A20 ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized
++ phy_set_rf_data(phw_data, 6, (6<<24)|0x06890C);
++ //0x00 0xFDF1C0 ; 3F7C7 ; Calibration (6e). turn on IQ imbalance/Test mode
++ phy_set_rf_data(phw_data, 0, (0<<24)|0xFDF1C0);
++
++ hw_set_dxx_reg(phw_data, 0x58, 0x30303030); // IQ_Alpha Changed
++
++ // a. Disable AGC
++ hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, ®_agc_ctrl3);
++ reg_agc_ctrl3 &= ~BIT(2);
++ reg_agc_ctrl3 |= (MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
++ hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
++
++ hw_get_dxx_reg(phw_data, REG_AGC_CTRL5, &val);
++ val |= MASK_AGC_FIX_GAIN;
++ hw_set_dxx_reg(phw_data, REG_AGC_CTRL5, val);
++
++ // b. set iqcal_mode[1:0] to 0x2 and set iqcal_tone[3:2] to 0
++ hw_get_dxx_reg(phw_data, REG_MODE_CTRL, ®_mode_ctrl);
++
++ PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
++ reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE);
++
++ // mode=2, tone=0
++ //reg_mode_ctrl |= (MASK_CALIB_START|2);
++
++ // mode=2, tone=1
++ //reg_mode_ctrl |= (MASK_CALIB_START|2|(1<<2));
++
++ // mode=2, tone=2
++ reg_mode_ctrl |= (MASK_CALIB_START|2|(2<<2));
++ hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
++ PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
++ pa_stall_execution(US);
++
++ hw_get_dxx_reg(phw_data, 0x5C, ®_dc_cancel);
++ PHY_DEBUG(("[CAL] DC_CANCEL (read) = 0x%08X\n", reg_dc_cancel));
++
++ for (loop = 0; loop < LOOP_TIMES; loop++)
++ {
++ PHY_DEBUG(("[CAL] [%d.] ==================================\n", loop));
++
++ // c.
++ // reset cancel_dc_i[9:5] and cancel_dc_q[4:0] in register DC_Cancel
++ reg_dc_cancel &= ~(0x03FF);
++ PHY_DEBUG(("[CAL] DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
++ hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
++ pa_stall_execution(US);
++
++ hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val);
++ PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val));
++
++ iqcal_image_i = _s13_to_s32(val & 0x00001FFF);
++ iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13);
++ sqsum = iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q;
++ mag_0 = (s32) _sqrt(sqsum);
++ PHY_DEBUG(("[CAL] mag_0=%d (iqcal_image_i=%d, iqcal_image_q=%d)\n",
++ mag_0, iqcal_image_i, iqcal_image_q));
++
++ // d.
++ reg_dc_cancel |= (1 << CANCEL_DC_I_SHIFT);
++ PHY_DEBUG(("[CAL] DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
++ hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
++ pa_stall_execution(US);
++
++ hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val);
++ PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val));
++
++ iqcal_image_i = _s13_to_s32(val & 0x00001FFF);
++ iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13);
++ sqsum = iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q;
++ mag_1 = (s32) _sqrt(sqsum);
++ PHY_DEBUG(("[CAL] mag_1=%d (iqcal_image_i=%d, iqcal_image_q=%d)\n",
++ mag_1, iqcal_image_i, iqcal_image_q));
++
++ // e. Calculate the correct DC offset cancellation value for I
++ if (mag_0 != mag_1)
++ {
++ fix_cancel_dc_i = (mag_0*10000) / (mag_0*10000 - mag_1*10000);
++ }
++ else
++ {
++ if (mag_0 == mag_1)
++ {
++ PHY_DEBUG(("[CAL] ***** mag_0 = mag_1 !!\n"));
++ }
++
++ fix_cancel_dc_i = 0;
++ }
++
++ PHY_DEBUG(("[CAL] ** fix_cancel_dc_i = %d (0x%04X)\n",
++ fix_cancel_dc_i, _s32_to_s5(fix_cancel_dc_i)));
++
++ if ((abs(mag_1-mag_0)*6) > mag_0)
++ {
++ break;
++ }
++ }
++
++ if ( loop >= 19 )
++ fix_cancel_dc_i = 0;
++
++ reg_dc_cancel &= ~(0x03FF);
++ reg_dc_cancel |= (_s32_to_s5(fix_cancel_dc_i) << CANCEL_DC_I_SHIFT);
++ hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
++ PHY_DEBUG(("[CAL] DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
++
++ // g.
++ reg_mode_ctrl &= ~MASK_CALIB_START;
++ hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
++ PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
++ pa_stall_execution(US);
++}
++
++///////////////////////////////////////////////////////
++void _txqdac_dc_offset_cacellation_winbond(hw_data_t *phw_data)
++{
++ u32 reg_agc_ctrl3;
++ u32 reg_mode_ctrl;
++ u32 reg_dc_cancel;
++ s32 iqcal_image_i;
++ s32 iqcal_image_q;
++ u32 sqsum;
++ s32 mag_0;
++ s32 mag_1;
++ s32 fix_cancel_dc_q = 0;
++ u32 val;
++ int loop;
++
++ PHY_DEBUG(("[CAL] -> [3]_txqdac_dc_offset_cacellation()\n"));
++ //0x01 0xEE3FC2 ; 3B8FF ; Calibration (6a). enable TX IQ calibration loop circuits
++ phy_set_rf_data(phw_data, 1, (1<<24)|0xEE3FC2);
++ //0x0B 0x1905D6 ; 06417 ; Calibration (6b). enable TX I/Q cal loop squaring circuit
++ phy_set_rf_data(phw_data, 11, (11<<24)|0x1901D6);
++ //0x05 0x24C60A ; 09318 ; Calibration (6c). setting TX-VGA gain: TXGCH=2 & GPK=110 --> to be optimized
++ phy_set_rf_data(phw_data, 5, (5<<24)|0x24C48A);
++ //0x06 0x06880C ; 01A20 ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized
++ phy_set_rf_data(phw_data, 6, (6<<24)|0x06890C);
++ //0x00 0xFDF1C0 ; 3F7C7 ; Calibration (6e). turn on IQ imbalance/Test mode
++ phy_set_rf_data(phw_data, 0, (0<<24)|0xFDF1C0);
++
++ hw_set_dxx_reg(phw_data, 0x58, 0x30303030); // IQ_Alpha Changed
++
++ // a. Disable AGC
++ hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, ®_agc_ctrl3);
++ reg_agc_ctrl3 &= ~BIT(2);
++ reg_agc_ctrl3 |= (MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
++ hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
++
++ hw_get_dxx_reg(phw_data, REG_AGC_CTRL5, &val);
++ val |= MASK_AGC_FIX_GAIN;
++ hw_set_dxx_reg(phw_data, REG_AGC_CTRL5, val);
++
++ // a. set iqcal_mode[1:0] to 0x3 and set iqcal_tone[3:2] to 0
++ hw_get_dxx_reg(phw_data, REG_MODE_CTRL, ®_mode_ctrl);
++ PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
++
++ //reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE);
++ reg_mode_ctrl &= ~(MASK_IQCAL_MODE);
++ reg_mode_ctrl |= (MASK_CALIB_START|3);
++ hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
++ PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
++ pa_stall_execution(US);
++
++ hw_get_dxx_reg(phw_data, 0x5C, ®_dc_cancel);
++ PHY_DEBUG(("[CAL] DC_CANCEL (read) = 0x%08X\n", reg_dc_cancel));
++
++ for (loop = 0; loop < LOOP_TIMES; loop++)
++ {
++ PHY_DEBUG(("[CAL] [%d.] ==================================\n", loop));
++
++ // b.
++ // reset cancel_dc_q[4:0] in register DC_Cancel
++ reg_dc_cancel &= ~(0x001F);
++ PHY_DEBUG(("[CAL] DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
++ hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
++ pa_stall_execution(US);
++
++ hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val);
++ PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val));
++ pa_stall_execution(US);
++
++ iqcal_image_i = _s13_to_s32(val & 0x00001FFF);
++ iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13);
++ sqsum = iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q;
++ mag_0 = _sqrt(sqsum);
++ PHY_DEBUG(("[CAL] mag_0=%d (iqcal_image_i=%d, iqcal_image_q=%d)\n",
++ mag_0, iqcal_image_i, iqcal_image_q));
++
++ // c.
++ reg_dc_cancel |= (1 << CANCEL_DC_Q_SHIFT);
++ PHY_DEBUG(("[CAL] DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
++ hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
++ pa_stall_execution(US);
++
++ hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val);
++ PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val));
++ pa_stall_execution(US);
++
++ iqcal_image_i = _s13_to_s32(val & 0x00001FFF);
++ iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13);
++ sqsum = iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q;
++ mag_1 = _sqrt(sqsum);
++ PHY_DEBUG(("[CAL] mag_1=%d (iqcal_image_i=%d, iqcal_image_q=%d)\n",
++ mag_1, iqcal_image_i, iqcal_image_q));
++
++ // d. Calculate the correct DC offset cancellation value for I
++ if (mag_0 != mag_1)
++ {
++ fix_cancel_dc_q = (mag_0*10000) / (mag_0*10000 - mag_1*10000);
++ }
++ else
++ {
++ if (mag_0 == mag_1)
++ {
++ PHY_DEBUG(("[CAL] ***** mag_0 = mag_1 !!\n"));
++ }
++
++ fix_cancel_dc_q = 0;
++ }
++
++ PHY_DEBUG(("[CAL] ** fix_cancel_dc_q = %d (0x%04X)\n",
++ fix_cancel_dc_q, _s32_to_s5(fix_cancel_dc_q)));
++
++ if ((abs(mag_1-mag_0)*6) > mag_0)
++ {
++ break;
++ }
++ }
++
++ if ( loop >= 19 )
++ fix_cancel_dc_q = 0;
++
++ reg_dc_cancel &= ~(0x001F);
++ reg_dc_cancel |= (_s32_to_s5(fix_cancel_dc_q) << CANCEL_DC_Q_SHIFT);
++ hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
++ PHY_DEBUG(("[CAL] DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
++
++
++ // f.
++ reg_mode_ctrl &= ~MASK_CALIB_START;
++ hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
++ PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
++ pa_stall_execution(US);
++}
++
++//20060612.1.a 20060718.1 Modify
++u8 _tx_iq_calibration_loop_winbond(hw_data_t *phw_data,
++ s32 a_2_threshold,
++ s32 b_2_threshold)
++{
++ u32 reg_mode_ctrl;
++ s32 iq_mag_0_tx;
++ s32 iqcal_tone_i0;
++ s32 iqcal_tone_q0;
++ s32 iqcal_tone_i;
++ s32 iqcal_tone_q;
++ u32 sqsum;
++ s32 rot_i_b;
++ s32 rot_q_b;
++ s32 tx_cal_flt_b[4];
++ s32 tx_cal[4];
++ s32 tx_cal_reg[4];
++ s32 a_2, b_2;
++ s32 sin_b, sin_2b;
++ s32 cos_b, cos_2b;
++ s32 divisor;
++ s32 temp1, temp2;
++ u32 val;
++ u16 loop;
++ s32 iqcal_tone_i_avg,iqcal_tone_q_avg;
++ u8 verify_count;
++ int capture_time;
++
++ PHY_DEBUG(("[CAL] -> _tx_iq_calibration_loop()\n"));
++ PHY_DEBUG(("[CAL] ** a_2_threshold = %d\n", a_2_threshold));
++ PHY_DEBUG(("[CAL] ** b_2_threshold = %d\n", b_2_threshold));
++
++ verify_count = 0;
++
++ hw_get_dxx_reg(phw_data, REG_MODE_CTRL, ®_mode_ctrl);
++ PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
++
++ loop = LOOP_TIMES;
++
++ while (loop > 0)
++ {
++ PHY_DEBUG(("[CAL] [%d.] <_tx_iq_calibration_loop>\n", (LOOP_TIMES-loop+1)));
++
++ iqcal_tone_i_avg=0;
++ iqcal_tone_q_avg=0;
++ if( !hw_set_dxx_reg(phw_data, 0x3C, 0x00) ) // 20060718.1 modify
++ return 0;
++ for(capture_time=0;capture_time<10;capture_time++)
++ {
++ // a. Set iqcal_mode[1:0] to 0x2 and set "calib_start" to 0x1 to
++ // enable "IQ alibration Mode II"
++ reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE);
++ reg_mode_ctrl &= ~MASK_IQCAL_MODE;
++ reg_mode_ctrl |= (MASK_CALIB_START|0x02);
++ reg_mode_ctrl |= (MASK_CALIB_START|0x02|2<<2);
++ hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
++ PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
++ pa_stall_execution(US);
++
++ // b.
++ hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val);
++ PHY_DEBUG(("[CAL] CALIB_READ1 = 0x%08X\n", val));
++ pa_stall_execution(US);
++
++ iqcal_tone_i0 = _s13_to_s32(val & 0x00001FFF);
++ iqcal_tone_q0 = _s13_to_s32((val & 0x03FFE000) >> 13);
++ PHY_DEBUG(("[CAL] ** iqcal_tone_i0=%d, iqcal_tone_q0=%d\n",
++ iqcal_tone_i0, iqcal_tone_q0));
++
++ sqsum = iqcal_tone_i0*iqcal_tone_i0 +
++ iqcal_tone_q0*iqcal_tone_q0;
++ iq_mag_0_tx = (s32) _sqrt(sqsum);
++ PHY_DEBUG(("[CAL] ** iq_mag_0_tx=%d\n", iq_mag_0_tx));
++
++ // c. Set "calib_start" to 0x0
++ reg_mode_ctrl &= ~MASK_CALIB_START;
++ hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
++ PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
++ pa_stall_execution(US);
++
++ // d. Set iqcal_mode[1:0] to 0x3 and set "calib_start" to 0x1 to
++ // enable "IQ alibration Mode II"
++ //hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &val);
++ hw_get_dxx_reg(phw_data, REG_MODE_CTRL, ®_mode_ctrl);
++ reg_mode_ctrl &= ~MASK_IQCAL_MODE;
++ reg_mode_ctrl |= (MASK_CALIB_START|0x03);
++ hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
++ PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
++ pa_stall_execution(US);
++
++ // e.
++ hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val);
++ PHY_DEBUG(("[CAL] CALIB_READ1 = 0x%08X\n", val));
++ pa_stall_execution(US);
++
++ iqcal_tone_i = _s13_to_s32(val & 0x00001FFF);
++ iqcal_tone_q = _s13_to_s32((val & 0x03FFE000) >> 13);
++ PHY_DEBUG(("[CAL] ** iqcal_tone_i = %d, iqcal_tone_q = %d\n",
++ iqcal_tone_i, iqcal_tone_q));
++ if( capture_time == 0)
++ {
++ continue;
++ }
++ else
++ {
++ iqcal_tone_i_avg=( iqcal_tone_i_avg*(capture_time-1) +iqcal_tone_i)/capture_time;
++ iqcal_tone_q_avg=( iqcal_tone_q_avg*(capture_time-1) +iqcal_tone_q)/capture_time;
++ }
++ }
++
++ iqcal_tone_i = iqcal_tone_i_avg;
++ iqcal_tone_q = iqcal_tone_q_avg;
++
++
++ rot_i_b = (iqcal_tone_i * iqcal_tone_i0 +
++ iqcal_tone_q * iqcal_tone_q0) / 1024;
++ rot_q_b = (iqcal_tone_i * iqcal_tone_q0 * (-1) +
++ iqcal_tone_q * iqcal_tone_i0) / 1024;
++ PHY_DEBUG(("[CAL] ** rot_i_b = %d, rot_q_b = %d\n",
++ rot_i_b, rot_q_b));
++
++ // f.
++ divisor = ((iq_mag_0_tx * iq_mag_0_tx * 2)/1024 - rot_i_b) * 2;
++
++ if (divisor == 0)
++ {
++ PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> ERROR *******\n"));
++ PHY_DEBUG(("[CAL] ** divisor=0 to calculate EPS and THETA !!\n"));
++ PHY_DEBUG(("[CAL] ******************************************\n"));
++ break;
++ }
++
++ a_2 = (rot_i_b * 32768) / divisor;
++ b_2 = (rot_q_b * (-32768)) / divisor;
++ PHY_DEBUG(("[CAL] ***** EPSILON/2 = %d\n", a_2));
++ PHY_DEBUG(("[CAL] ***** THETA/2 = %d\n", b_2));
++
++ phw_data->iq_rsdl_gain_tx_d2 = a_2;
++ phw_data->iq_rsdl_phase_tx_d2 = b_2;
++
++ //if ((abs(a_2) < 150) && (abs(b_2) < 100))
++ //if ((abs(a_2) < 200) && (abs(b_2) < 200))
++ if ((abs(a_2) < a_2_threshold) && (abs(b_2) < b_2_threshold))
++ {
++ verify_count++;
++
++ PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *************\n"));
++ PHY_DEBUG(("[CAL] ** VERIFY OK # %d !!\n", verify_count));
++ PHY_DEBUG(("[CAL] ******************************************\n"));
++
++ if (verify_count > 2)
++ {
++ PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *********\n"));
++ PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION (EPS,THETA) OK !!\n"));
++ PHY_DEBUG(("[CAL] **************************************\n"));
++ return 0;
++ }
++
++ continue;
++ }
++ else
++ {
++ verify_count = 0;
++ }
++
++ _sin_cos(b_2, &sin_b, &cos_b);
++ _sin_cos(b_2*2, &sin_2b, &cos_2b);
++ PHY_DEBUG(("[CAL] ** sin(b/2)=%d, cos(b/2)=%d\n", sin_b, cos_b));
++ PHY_DEBUG(("[CAL] ** sin(b)=%d, cos(b)=%d\n", sin_2b, cos_2b));
++
++ if (cos_2b == 0)
++ {
++ PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> ERROR *******\n"));
++ PHY_DEBUG(("[CAL] ** cos(b)=0 !!\n"));
++ PHY_DEBUG(("[CAL] ******************************************\n"));
++ break;
++ }
++
++ // 1280 * 32768 = 41943040
++ temp1 = (41943040/cos_2b)*cos_b;
++
++ //temp2 = (41943040/cos_2b)*sin_b*(-1);
++ if (phw_data->revision == 0x2002) // 1st-cut
++ {
++ temp2 = (41943040/cos_2b)*sin_b*(-1);
++ }
++ else // 2nd-cut
++ {
++ temp2 = (41943040*4/cos_2b)*sin_b*(-1);
++ }
++
++ tx_cal_flt_b[0] = _floor(temp1/(32768+a_2));
++ tx_cal_flt_b[1] = _floor(temp2/(32768+a_2));
++ tx_cal_flt_b[2] = _floor(temp2/(32768-a_2));
++ tx_cal_flt_b[3] = _floor(temp1/(32768-a_2));
++ PHY_DEBUG(("[CAL] ** tx_cal_flt_b[0] = %d\n", tx_cal_flt_b[0]));
++ PHY_DEBUG(("[CAL] tx_cal_flt_b[1] = %d\n", tx_cal_flt_b[1]));
++ PHY_DEBUG(("[CAL] tx_cal_flt_b[2] = %d\n", tx_cal_flt_b[2]));
++ PHY_DEBUG(("[CAL] tx_cal_flt_b[3] = %d\n", tx_cal_flt_b[3]));
++
++ tx_cal[2] = tx_cal_flt_b[2];
++ tx_cal[2] = tx_cal[2] +3;
++ tx_cal[1] = tx_cal[2];
++ tx_cal[3] = tx_cal_flt_b[3] - 128;
++ tx_cal[0] = -tx_cal[3]+1;
++
++ PHY_DEBUG(("[CAL] tx_cal[0] = %d\n", tx_cal[0]));
++ PHY_DEBUG(("[CAL] tx_cal[1] = %d\n", tx_cal[1]));
++ PHY_DEBUG(("[CAL] tx_cal[2] = %d\n", tx_cal[2]));
++ PHY_DEBUG(("[CAL] tx_cal[3] = %d\n", tx_cal[3]));
++
++ //if ((tx_cal[0] == 0) && (tx_cal[1] == 0) &&
++ // (tx_cal[2] == 0) && (tx_cal[3] == 0))
++ //{
++ // PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *************\n"));
++ // PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION COMPLETE !!\n"));
++ // PHY_DEBUG(("[CAL] ******************************************\n"));
++ // return 0;
++ //}
++
++ // g.
++ if (phw_data->revision == 0x2002) // 1st-cut
++ {
++ hw_get_dxx_reg(phw_data, 0x54, &val);
++ PHY_DEBUG(("[CAL] ** 0x54 = 0x%08X\n", val));
++ tx_cal_reg[0] = _s4_to_s32((val & 0xF0000000) >> 28);
++ tx_cal_reg[1] = _s4_to_s32((val & 0x0F000000) >> 24);
++ tx_cal_reg[2] = _s4_to_s32((val & 0x00F00000) >> 20);
++ tx_cal_reg[3] = _s4_to_s32((val & 0x000F0000) >> 16);
++ }
++ else // 2nd-cut
++ {
++ hw_get_dxx_reg(phw_data, 0x3C, &val);
++ PHY_DEBUG(("[CAL] ** 0x3C = 0x%08X\n", val));
++ tx_cal_reg[0] = _s5_to_s32((val & 0xF8000000) >> 27);
++ tx_cal_reg[1] = _s6_to_s32((val & 0x07E00000) >> 21);
++ tx_cal_reg[2] = _s6_to_s32((val & 0x001F8000) >> 15);
++ tx_cal_reg[3] = _s5_to_s32((val & 0x00007C00) >> 10);
++
++ }
++
++ PHY_DEBUG(("[CAL] ** tx_cal_reg[0] = %d\n", tx_cal_reg[0]));
++ PHY_DEBUG(("[CAL] tx_cal_reg[1] = %d\n", tx_cal_reg[1]));
++ PHY_DEBUG(("[CAL] tx_cal_reg[2] = %d\n", tx_cal_reg[2]));
++ PHY_DEBUG(("[CAL] tx_cal_reg[3] = %d\n", tx_cal_reg[3]));
++
++ if (phw_data->revision == 0x2002) // 1st-cut
++ {
++ if (((tx_cal_reg[0]==7) || (tx_cal_reg[0]==(-8))) &&
++ ((tx_cal_reg[3]==7) || (tx_cal_reg[3]==(-8))))
++ {
++ PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *********\n"));
++ PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION SATUATION !!\n"));
++ PHY_DEBUG(("[CAL] **************************************\n"));
++ break;
++ }
++ }
++ else // 2nd-cut
++ {
++ if (((tx_cal_reg[0]==31) || (tx_cal_reg[0]==(-32))) &&
++ ((tx_cal_reg[3]==31) || (tx_cal_reg[3]==(-32))))
++ {
++ PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *********\n"));
++ PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION SATUATION !!\n"));
++ PHY_DEBUG(("[CAL] **************************************\n"));
++ break;
++ }
++ }
++
++ tx_cal[0] = tx_cal[0] + tx_cal_reg[0];
++ tx_cal[1] = tx_cal[1] + tx_cal_reg[1];
++ tx_cal[2] = tx_cal[2] + tx_cal_reg[2];
++ tx_cal[3] = tx_cal[3] + tx_cal_reg[3];
++ PHY_DEBUG(("[CAL] ** apply tx_cal[0] = %d\n", tx_cal[0]));
++ PHY_DEBUG(("[CAL] apply tx_cal[1] = %d\n", tx_cal[1]));
++ PHY_DEBUG(("[CAL] apply tx_cal[2] = %d\n", tx_cal[2]));
++ PHY_DEBUG(("[CAL] apply tx_cal[3] = %d\n", tx_cal[3]));
++
++ if (phw_data->revision == 0x2002) // 1st-cut
++ {
++ val &= 0x0000FFFF;
++ val |= ((_s32_to_s4(tx_cal[0]) << 28)|
++ (_s32_to_s4(tx_cal[1]) << 24)|
++ (_s32_to_s4(tx_cal[2]) << 20)|
++ (_s32_to_s4(tx_cal[3]) << 16));
++ hw_set_dxx_reg(phw_data, 0x54, val);
++ PHY_DEBUG(("[CAL] ** CALIB_DATA = 0x%08X\n", val));
++ return 0;
++ }
++ else // 2nd-cut
++ {
++ val &= 0x000003FF;
++ val |= ((_s32_to_s5(tx_cal[0]) << 27)|
++ (_s32_to_s6(tx_cal[1]) << 21)|
++ (_s32_to_s6(tx_cal[2]) << 15)|
++ (_s32_to_s5(tx_cal[3]) << 10));
++ hw_set_dxx_reg(phw_data, 0x3C, val);
++ PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION = 0x%08X\n", val));
++ return 0;
++ }
++
++ // i. Set "calib_start" to 0x0
++ reg_mode_ctrl &= ~MASK_CALIB_START;
++ hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
++ PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
++
++ loop--;
++ }
++
++ return 1;
++}
++
++void _tx_iq_calibration_winbond(hw_data_t *phw_data)
++{
++ u32 reg_agc_ctrl3;
++#ifdef _DEBUG
++ s32 tx_cal_reg[4];
++
++#endif
++ u32 reg_mode_ctrl;
++ u32 val;
++ u8 result;
++
++ PHY_DEBUG(("[CAL] -> [4]_tx_iq_calibration()\n"));
++
++ //0x01 0xEE3FC2 ; 3B8FF ; Calibration (6a). enable TX IQ calibration loop circuits
++ phy_set_rf_data(phw_data, 1, (1<<24)|0xEE3FC2);
++ //0x0B 0x1905D6 ; 06417 ; Calibration (6b). enable TX I/Q cal loop squaring circuit
++ phy_set_rf_data(phw_data, 11, (11<<24)|0x19BDD6); // 20060612.1.a 0x1905D6);
++ //0x05 0x24C60A ; 09318 ; Calibration (6c). setting TX-VGA gain: TXGCH=2 & GPK=110 --> to be optimized
++ phy_set_rf_data(phw_data, 5, (5<<24)|0x24C60A); //0x24C60A (high temperature)
++ //0x06 0x06880C ; 01A20 ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized
++ phy_set_rf_data(phw_data, 6, (6<<24)|0x34880C); // 20060612.1.a 0x06890C);
++ //0x00 0xFDF1C0 ; 3F7C7 ; Calibration (6e). turn on IQ imbalance/Test mode
++ phy_set_rf_data(phw_data, 0, (0<<24)|0xFDF1C0);
++ //; [BB-chip]: Calibration (6f).Send test pattern
++ //; [BB-chip]: Calibration (6g). Search RXGCL optimal value
++ //; [BB-chip]: Calibration (6h). Caculate TX-path IQ imbalance and setting TX path IQ compensation table
++ //phy_set_rf_data(phw_data, 3, (3<<24)|0x025586);
++
++ OS_SLEEP(30000); // 20060612.1.a 30ms delay. Add the follow 2 lines
++ //To adjust TXVGA to fit iq_mag_0 range from 1250 ~ 1750
++ adjust_TXVGA_for_iq_mag( phw_data );
++
++ // a. Disable AGC
++ hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, ®_agc_ctrl3);
++ reg_agc_ctrl3 &= ~BIT(2);
++ reg_agc_ctrl3 |= (MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
++ hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
++
++ hw_get_dxx_reg(phw_data, REG_AGC_CTRL5, &val);
++ val |= MASK_AGC_FIX_GAIN;
++ hw_set_dxx_reg(phw_data, REG_AGC_CTRL5, val);
++
++ result = _tx_iq_calibration_loop_winbond(phw_data, 150, 100);
++
++ if (result > 0)
++ {
++ if (phw_data->revision == 0x2002) // 1st-cut
++ {
++ hw_get_dxx_reg(phw_data, 0x54, &val);
++ val &= 0x0000FFFF;
++ hw_set_dxx_reg(phw_data, 0x54, val);
++ }
++ else // 2nd-cut
++ {
++ hw_get_dxx_reg(phw_data, 0x3C, &val);
++ val &= 0x000003FF;
++ hw_set_dxx_reg(phw_data, 0x3C, val);
++ }
++
++ result = _tx_iq_calibration_loop_winbond(phw_data, 300, 200);
++
++ if (result > 0)
++ {
++ if (phw_data->revision == 0x2002) // 1st-cut
++ {
++ hw_get_dxx_reg(phw_data, 0x54, &val);
++ val &= 0x0000FFFF;
++ hw_set_dxx_reg(phw_data, 0x54, val);
++ }
++ else // 2nd-cut
++ {
++ hw_get_dxx_reg(phw_data, 0x3C, &val);
++ val &= 0x000003FF;
++ hw_set_dxx_reg(phw_data, 0x3C, val);
++ }
++
++ result = _tx_iq_calibration_loop_winbond(phw_data, 500, 400);
++ if (result > 0)
++ {
++ if (phw_data->revision == 0x2002) // 1st-cut
++ {
++ hw_get_dxx_reg(phw_data, 0x54, &val);
++ val &= 0x0000FFFF;
++ hw_set_dxx_reg(phw_data, 0x54, val);
++ }
++ else // 2nd-cut
++ {
++ hw_get_dxx_reg(phw_data, 0x3C, &val);
++ val &= 0x000003FF;
++ hw_set_dxx_reg(phw_data, 0x3C, val);
++ }
++
++
++ result = _tx_iq_calibration_loop_winbond(phw_data, 700, 500);
++
++ if (result > 0)
++ {
++ PHY_DEBUG(("[CAL] ** <_tx_iq_calibration> **************\n"));
++ PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION FAILURE !!\n"));
++ PHY_DEBUG(("[CAL] **************************************\n"));
++
++ if (phw_data->revision == 0x2002) // 1st-cut
++ {
++ hw_get_dxx_reg(phw_data, 0x54, &val);
++ val &= 0x0000FFFF;
++ hw_set_dxx_reg(phw_data, 0x54, val);
++ }
++ else // 2nd-cut
++ {
++ hw_get_dxx_reg(phw_data, 0x3C, &val);
++ val &= 0x000003FF;
++ hw_set_dxx_reg(phw_data, 0x3C, val);
++ }
++ }
++ }
++ }
++ }
++
++ // i. Set "calib_start" to 0x0
++ hw_get_dxx_reg(phw_data, REG_MODE_CTRL, ®_mode_ctrl);
++ reg_mode_ctrl &= ~MASK_CALIB_START;
++ hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
++ PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
++
++ // g. Enable AGC
++ //hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &val);
++ reg_agc_ctrl3 |= BIT(2);
++ reg_agc_ctrl3 &= ~(MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
++ hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
++
++#ifdef _DEBUG
++ if (phw_data->revision == 0x2002) // 1st-cut
++ {
++ hw_get_dxx_reg(phw_data, 0x54, &val);
++ PHY_DEBUG(("[CAL] ** 0x54 = 0x%08X\n", val));
++ tx_cal_reg[0] = _s4_to_s32((val & 0xF0000000) >> 28);
++ tx_cal_reg[1] = _s4_to_s32((val & 0x0F000000) >> 24);
++ tx_cal_reg[2] = _s4_to_s32((val & 0x00F00000) >> 20);
++ tx_cal_reg[3] = _s4_to_s32((val & 0x000F0000) >> 16);
++ }
++ else // 2nd-cut
++ {
++ hw_get_dxx_reg(phw_data, 0x3C, &val);
++ PHY_DEBUG(("[CAL] ** 0x3C = 0x%08X\n", val));
++ tx_cal_reg[0] = _s5_to_s32((val & 0xF8000000) >> 27);
++ tx_cal_reg[1] = _s6_to_s32((val & 0x07E00000) >> 21);
++ tx_cal_reg[2] = _s6_to_s32((val & 0x001F8000) >> 15);
++ tx_cal_reg[3] = _s5_to_s32((val & 0x00007C00) >> 10);
++
++ }
++
++ PHY_DEBUG(("[CAL] ** tx_cal_reg[0] = %d\n", tx_cal_reg[0]));
++ PHY_DEBUG(("[CAL] tx_cal_reg[1] = %d\n", tx_cal_reg[1]));
++ PHY_DEBUG(("[CAL] tx_cal_reg[2] = %d\n", tx_cal_reg[2]));
++ PHY_DEBUG(("[CAL] tx_cal_reg[3] = %d\n", tx_cal_reg[3]));
++#endif
++
++
++ // for test - BEN
++ // RF Control Override
++}
++
++/////////////////////////////////////////////////////////////////////////////////////////
++u8 _rx_iq_calibration_loop_winbond(hw_data_t *phw_data, u16 factor, u32 frequency)
++{
++ u32 reg_mode_ctrl;
++ s32 iqcal_tone_i;
++ s32 iqcal_tone_q;
++ s32 iqcal_image_i;
++ s32 iqcal_image_q;
++ s32 rot_tone_i_b;
++ s32 rot_tone_q_b;
++ s32 rot_image_i_b;
++ s32 rot_image_q_b;
++ s32 rx_cal_flt_b[4];
++ s32 rx_cal[4];
++ s32 rx_cal_reg[4];
++ s32 a_2, b_2;
++ s32 sin_b, sin_2b;
++ s32 cos_b, cos_2b;
++ s32 temp1, temp2;
++ u32 val;
++ u16 loop;
++
++ u32 pwr_tone;
++ u32 pwr_image;
++ u8 verify_count;
++
++ s32 iqcal_tone_i_avg,iqcal_tone_q_avg;
++ s32 iqcal_image_i_avg,iqcal_image_q_avg;
++ u16 capture_time;
++
++ PHY_DEBUG(("[CAL] -> [5]_rx_iq_calibration_loop()\n"));
++ PHY_DEBUG(("[CAL] ** factor = %d\n", factor));
++
++
++// RF Control Override
++ hw_get_cxx_reg(phw_data, 0x80, &val);
++ val |= BIT(19);
++ hw_set_cxx_reg(phw_data, 0x80, val);
++
++// RF_Ctrl
++ hw_get_cxx_reg(phw_data, 0xE4, &val);
++ val |= BIT(0);
++ hw_set_cxx_reg(phw_data, 0xE4, val);
++ PHY_DEBUG(("[CAL] ** RF_CTRL(0xE4) = 0x%08X", val));
++
++ hw_set_dxx_reg(phw_data, 0x58, 0x44444444); // IQ_Alpha
++
++ // b.
++
++ hw_get_dxx_reg(phw_data, REG_MODE_CTRL, ®_mode_ctrl);
++ PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
++
++ verify_count = 0;
++
++ //for (loop = 0; loop < 1; loop++)
++ //for (loop = 0; loop < LOOP_TIMES; loop++)
++ loop = LOOP_TIMES;
++ while (loop > 0)
++ {
++ PHY_DEBUG(("[CAL] [%d.] <_rx_iq_calibration_loop>\n", (LOOP_TIMES-loop+1)));
++ iqcal_tone_i_avg=0;
++ iqcal_tone_q_avg=0;
++ iqcal_image_i_avg=0;
++ iqcal_image_q_avg=0;
++ capture_time=0;
++
++ for(capture_time=0; capture_time<10; capture_time++)
++ {
++ // i. Set "calib_start" to 0x0
++ reg_mode_ctrl &= ~MASK_CALIB_START;
++ if( !hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl) )//20060718.1 modify
++ return 0;
++ PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
++ pa_stall_execution(US);
++
++ reg_mode_ctrl &= ~MASK_IQCAL_MODE;
++ reg_mode_ctrl |= (MASK_CALIB_START|0x1);
++ hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
++ PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
++ pa_stall_execution(US); //Should be read out after 450us
++
++ // c.
++ hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val);
++ PHY_DEBUG(("[CAL] CALIB_READ1 = 0x%08X\n", val));
++
++ iqcal_tone_i = _s13_to_s32(val & 0x00001FFF);
++ iqcal_tone_q = _s13_to_s32((val & 0x03FFE000) >> 13);
++ PHY_DEBUG(("[CAL] ** iqcal_tone_i = %d, iqcal_tone_q = %d\n",
++ iqcal_tone_i, iqcal_tone_q));
++
++ hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val);
++ PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val));
++
++ iqcal_image_i = _s13_to_s32(val & 0x00001FFF);
++ iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13);
++ PHY_DEBUG(("[CAL] ** iqcal_image_i = %d, iqcal_image_q = %d\n",
++ iqcal_image_i, iqcal_image_q));
++ if( capture_time == 0)
++ {
++ continue;
++ }
++ else
++ {
++ iqcal_image_i_avg=( iqcal_image_i_avg*(capture_time-1) +iqcal_image_i)/capture_time;
++ iqcal_image_q_avg=( iqcal_image_q_avg*(capture_time-1) +iqcal_image_q)/capture_time;
++ iqcal_tone_i_avg=( iqcal_tone_i_avg*(capture_time-1) +iqcal_tone_i)/capture_time;
++ iqcal_tone_q_avg=( iqcal_tone_q_avg*(capture_time-1) +iqcal_tone_q)/capture_time;
++ }
++ }
++
++
++ iqcal_image_i = iqcal_image_i_avg;
++ iqcal_image_q = iqcal_image_q_avg;
++ iqcal_tone_i = iqcal_tone_i_avg;
++ iqcal_tone_q = iqcal_tone_q_avg;
++
++ // d.
++ rot_tone_i_b = (iqcal_tone_i * iqcal_tone_i +
++ iqcal_tone_q * iqcal_tone_q) / 1024;
++ rot_tone_q_b = (iqcal_tone_i * iqcal_tone_q * (-1) +
++ iqcal_tone_q * iqcal_tone_i) / 1024;
++ rot_image_i_b = (iqcal_image_i * iqcal_tone_i -
++ iqcal_image_q * iqcal_tone_q) / 1024;
++ rot_image_q_b = (iqcal_image_i * iqcal_tone_q +
++ iqcal_image_q * iqcal_tone_i) / 1024;
++
++ PHY_DEBUG(("[CAL] ** rot_tone_i_b = %d\n", rot_tone_i_b));
++ PHY_DEBUG(("[CAL] ** rot_tone_q_b = %d\n", rot_tone_q_b));
++ PHY_DEBUG(("[CAL] ** rot_image_i_b = %d\n", rot_image_i_b));
++ PHY_DEBUG(("[CAL] ** rot_image_q_b = %d\n", rot_image_q_b));
++
++ // f.
++ if (rot_tone_i_b == 0)
++ {
++ PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> ERROR *******\n"));
++ PHY_DEBUG(("[CAL] ** rot_tone_i_b=0 to calculate EPS and THETA !!\n"));
++ PHY_DEBUG(("[CAL] ******************************************\n"));
++ break;
++ }
++
++ a_2 = (rot_image_i_b * 32768) / rot_tone_i_b -
++ phw_data->iq_rsdl_gain_tx_d2;
++ b_2 = (rot_image_q_b * 32768) / rot_tone_i_b -
++ phw_data->iq_rsdl_phase_tx_d2;
++
++ PHY_DEBUG(("[CAL] ** iq_rsdl_gain_tx_d2 = %d\n", phw_data->iq_rsdl_gain_tx_d2));
++ PHY_DEBUG(("[CAL] ** iq_rsdl_phase_tx_d2= %d\n", phw_data->iq_rsdl_phase_tx_d2));
++ PHY_DEBUG(("[CAL] ***** EPSILON/2 = %d\n", a_2));
++ PHY_DEBUG(("[CAL] ***** THETA/2 = %d\n", b_2));
++
++ _sin_cos(b_2, &sin_b, &cos_b);
++ _sin_cos(b_2*2, &sin_2b, &cos_2b);
++ PHY_DEBUG(("[CAL] ** sin(b/2)=%d, cos(b/2)=%d\n", sin_b, cos_b));
++ PHY_DEBUG(("[CAL] ** sin(b)=%d, cos(b)=%d\n", sin_2b, cos_2b));
++
++ if (cos_2b == 0)
++ {
++ PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> ERROR *******\n"));
++ PHY_DEBUG(("[CAL] ** cos(b)=0 !!\n"));
++ PHY_DEBUG(("[CAL] ******************************************\n"));
++ break;
++ }
++
++ // 1280 * 32768 = 41943040
++ temp1 = (41943040/cos_2b)*cos_b;
++
++ //temp2 = (41943040/cos_2b)*sin_b*(-1);
++ if (phw_data->revision == 0x2002) // 1st-cut
++ {
++ temp2 = (41943040/cos_2b)*sin_b*(-1);
++ }
++ else // 2nd-cut
++ {
++ temp2 = (41943040*4/cos_2b)*sin_b*(-1);
++ }
++
++ rx_cal_flt_b[0] = _floor(temp1/(32768+a_2));
++ rx_cal_flt_b[1] = _floor(temp2/(32768-a_2));
++ rx_cal_flt_b[2] = _floor(temp2/(32768+a_2));
++ rx_cal_flt_b[3] = _floor(temp1/(32768-a_2));
++
++ PHY_DEBUG(("[CAL] ** rx_cal_flt_b[0] = %d\n", rx_cal_flt_b[0]));
++ PHY_DEBUG(("[CAL] rx_cal_flt_b[1] = %d\n", rx_cal_flt_b[1]));
++ PHY_DEBUG(("[CAL] rx_cal_flt_b[2] = %d\n", rx_cal_flt_b[2]));
++ PHY_DEBUG(("[CAL] rx_cal_flt_b[3] = %d\n", rx_cal_flt_b[3]));
++
++ rx_cal[0] = rx_cal_flt_b[0] - 128;
++ rx_cal[1] = rx_cal_flt_b[1];
++ rx_cal[2] = rx_cal_flt_b[2];
++ rx_cal[3] = rx_cal_flt_b[3] - 128;
++ PHY_DEBUG(("[CAL] ** rx_cal[0] = %d\n", rx_cal[0]));
++ PHY_DEBUG(("[CAL] rx_cal[1] = %d\n", rx_cal[1]));
++ PHY_DEBUG(("[CAL] rx_cal[2] = %d\n", rx_cal[2]));
++ PHY_DEBUG(("[CAL] rx_cal[3] = %d\n", rx_cal[3]));
++
++ // e.
++ pwr_tone = (iqcal_tone_i*iqcal_tone_i + iqcal_tone_q*iqcal_tone_q);
++ pwr_image = (iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q)*factor;
++
++ PHY_DEBUG(("[CAL] ** pwr_tone = %d\n", pwr_tone));
++ PHY_DEBUG(("[CAL] ** pwr_image = %d\n", pwr_image));
++
++ if (pwr_tone > pwr_image)
++ {
++ verify_count++;
++
++ PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *************\n"));
++ PHY_DEBUG(("[CAL] ** VERIFY OK # %d !!\n", verify_count));
++ PHY_DEBUG(("[CAL] ******************************************\n"));
++
++ if (verify_count > 2)
++ {
++ PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *********\n"));
++ PHY_DEBUG(("[CAL] ** RX_IQ_CALIBRATION OK !!\n"));
++ PHY_DEBUG(("[CAL] **************************************\n"));
++ return 0;
++ }
++
++ continue;
++ }
++ // g.
++ hw_get_dxx_reg(phw_data, 0x54, &val);
++ PHY_DEBUG(("[CAL] ** 0x54 = 0x%08X\n", val));
++
++ if (phw_data->revision == 0x2002) // 1st-cut
++ {
++ rx_cal_reg[0] = _s4_to_s32((val & 0x0000F000) >> 12);
++ rx_cal_reg[1] = _s4_to_s32((val & 0x00000F00) >> 8);
++ rx_cal_reg[2] = _s4_to_s32((val & 0x000000F0) >> 4);
++ rx_cal_reg[3] = _s4_to_s32((val & 0x0000000F));
++ }
++ else // 2nd-cut
++ {
++ rx_cal_reg[0] = _s5_to_s32((val & 0xF8000000) >> 27);
++ rx_cal_reg[1] = _s6_to_s32((val & 0x07E00000) >> 21);
++ rx_cal_reg[2] = _s6_to_s32((val & 0x001F8000) >> 15);
++ rx_cal_reg[3] = _s5_to_s32((val & 0x00007C00) >> 10);
++ }
++
++ PHY_DEBUG(("[CAL] ** rx_cal_reg[0] = %d\n", rx_cal_reg[0]));
++ PHY_DEBUG(("[CAL] rx_cal_reg[1] = %d\n", rx_cal_reg[1]));
++ PHY_DEBUG(("[CAL] rx_cal_reg[2] = %d\n", rx_cal_reg[2]));
++ PHY_DEBUG(("[CAL] rx_cal_reg[3] = %d\n", rx_cal_reg[3]));
++
++ if (phw_data->revision == 0x2002) // 1st-cut
++ {
++ if (((rx_cal_reg[0]==7) || (rx_cal_reg[0]==(-8))) &&
++ ((rx_cal_reg[3]==7) || (rx_cal_reg[3]==(-8))))
++ {
++ PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *********\n"));
++ PHY_DEBUG(("[CAL] ** RX_IQ_CALIBRATION SATUATION !!\n"));
++ PHY_DEBUG(("[CAL] **************************************\n"));
++ break;
++ }
++ }
++ else // 2nd-cut
++ {
++ if (((rx_cal_reg[0]==31) || (rx_cal_reg[0]==(-32))) &&
++ ((rx_cal_reg[3]==31) || (rx_cal_reg[3]==(-32))))
++ {
++ PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *********\n"));
++ PHY_DEBUG(("[CAL] ** RX_IQ_CALIBRATION SATUATION !!\n"));
++ PHY_DEBUG(("[CAL] **************************************\n"));
++ break;
++ }
++ }
++
++ rx_cal[0] = rx_cal[0] + rx_cal_reg[0];
++ rx_cal[1] = rx_cal[1] + rx_cal_reg[1];
++ rx_cal[2] = rx_cal[2] + rx_cal_reg[2];
++ rx_cal[3] = rx_cal[3] + rx_cal_reg[3];
++ PHY_DEBUG(("[CAL] ** apply rx_cal[0] = %d\n", rx_cal[0]));
++ PHY_DEBUG(("[CAL] apply rx_cal[1] = %d\n", rx_cal[1]));
++ PHY_DEBUG(("[CAL] apply rx_cal[2] = %d\n", rx_cal[2]));
++ PHY_DEBUG(("[CAL] apply rx_cal[3] = %d\n", rx_cal[3]));
++
++ hw_get_dxx_reg(phw_data, 0x54, &val);
++ if (phw_data->revision == 0x2002) // 1st-cut
++ {
++ val &= 0x0000FFFF;
++ val |= ((_s32_to_s4(rx_cal[0]) << 12)|
++ (_s32_to_s4(rx_cal[1]) << 8)|
++ (_s32_to_s4(rx_cal[2]) << 4)|
++ (_s32_to_s4(rx_cal[3])));
++ hw_set_dxx_reg(phw_data, 0x54, val);
++ }
++ else // 2nd-cut
++ {
++ val &= 0x000003FF;
++ val |= ((_s32_to_s5(rx_cal[0]) << 27)|
++ (_s32_to_s6(rx_cal[1]) << 21)|
++ (_s32_to_s6(rx_cal[2]) << 15)|
++ (_s32_to_s5(rx_cal[3]) << 10));
++ hw_set_dxx_reg(phw_data, 0x54, val);
++
++ if( loop == 3 )
++ return 0;
++ }
++ PHY_DEBUG(("[CAL] ** CALIB_DATA = 0x%08X\n", val));
++
++ loop--;
++ }
++
++ return 1;
++}
++
++//////////////////////////////////////////////////////////
++
++//////////////////////////////////////////////////////////////////////////
++void _rx_iq_calibration_winbond(hw_data_t *phw_data, u32 frequency)
++{
++// figo 20050523 marked thsi flag for can't compile for relesase
++#ifdef _DEBUG
++ s32 rx_cal_reg[4];
++ u32 val;
++#endif
++
++ u8 result;
++
++ PHY_DEBUG(("[CAL] -> [5]_rx_iq_calibration()\n"));
++// a. Set RFIC to "RX calibration mode"
++ //; ----- Calibration (7). RX path IQ imbalance calibration loop
++ // 0x01 0xFFBFC2 ; 3FEFF ; Calibration (7a). enable RX IQ calibration loop circuits
++ phy_set_rf_data(phw_data, 1, (1<<24)|0xEFBFC2);
++ // 0x0B 0x1A01D6 ; 06817 ; Calibration (7b). enable RX I/Q cal loop SW1 circuit
++ phy_set_rf_data(phw_data, 11, (11<<24)|0x1A05D6);
++ //0x05 0x24848A ; 09212 ; Calibration (7c). setting TX-VGA gain (TXGCH) to 2 --> to be optimized
++ phy_set_rf_data(phw_data, 5, (5<<24)| phw_data->txvga_setting_for_cal);
++ //0x06 0x06840C ; 01A10 ; Calibration (7d). RXGCH=00; RXGCL=010 000 (RXVGA) --> to be optimized
++ phy_set_rf_data(phw_data, 6, (6<<24)|0x06834C);
++ //0x00 0xFFF1C0 ; 3F7C7 ; Calibration (7e). turn on IQ imbalance/Test mode
++ phy_set_rf_data(phw_data, 0, (0<<24)|0xFFF1C0);
++
++ // ; [BB-chip]: Calibration (7f). Send test pattern
++ // ; [BB-chip]: Calibration (7g). Search RXGCL optimal value
++ // ; [BB-chip]: Calibration (7h). Caculate RX-path IQ imbalance and setting RX path IQ compensation table
++
++ result = _rx_iq_calibration_loop_winbond(phw_data, 12589, frequency);
++
++ if (result > 0)
++ {
++ _reset_rx_cal(phw_data);
++ result = _rx_iq_calibration_loop_winbond(phw_data, 7943, frequency);
++
++ if (result > 0)
++ {
++ _reset_rx_cal(phw_data);
++ result = _rx_iq_calibration_loop_winbond(phw_data, 5011, frequency);
++
++ if (result > 0)
++ {
++ PHY_DEBUG(("[CAL] ** <_rx_iq_calibration> **************\n"));
++ PHY_DEBUG(("[CAL] ** RX_IQ_CALIBRATION FAILURE !!\n"));
++ PHY_DEBUG(("[CAL] **************************************\n"));
++ _reset_rx_cal(phw_data);
++ }
++ }
++ }
++
++#ifdef _DEBUG
++ hw_get_dxx_reg(phw_data, 0x54, &val);
++ PHY_DEBUG(("[CAL] ** 0x54 = 0x%08X\n", val));
++
++ if (phw_data->revision == 0x2002) // 1st-cut
++ {
++ rx_cal_reg[0] = _s4_to_s32((val & 0x0000F000) >> 12);
++ rx_cal_reg[1] = _s4_to_s32((val & 0x00000F00) >> 8);
++ rx_cal_reg[2] = _s4_to_s32((val & 0x000000F0) >> 4);
++ rx_cal_reg[3] = _s4_to_s32((val & 0x0000000F));
++ }
++ else // 2nd-cut
++ {
++ rx_cal_reg[0] = _s5_to_s32((val & 0xF8000000) >> 27);
++ rx_cal_reg[1] = _s6_to_s32((val & 0x07E00000) >> 21);
++ rx_cal_reg[2] = _s6_to_s32((val & 0x001F8000) >> 15);
++ rx_cal_reg[3] = _s5_to_s32((val & 0x00007C00) >> 10);
++ }
++
++ PHY_DEBUG(("[CAL] ** rx_cal_reg[0] = %d\n", rx_cal_reg[0]));
++ PHY_DEBUG(("[CAL] rx_cal_reg[1] = %d\n", rx_cal_reg[1]));
++ PHY_DEBUG(("[CAL] rx_cal_reg[2] = %d\n", rx_cal_reg[2]));
++ PHY_DEBUG(("[CAL] rx_cal_reg[3] = %d\n", rx_cal_reg[3]));
++#endif
++
++}
++
++////////////////////////////////////////////////////////////////////////
++void phy_calibration_winbond(hw_data_t *phw_data, u32 frequency)
++{
++ u32 reg_mode_ctrl;
++ u32 iq_alpha;
++
++ PHY_DEBUG(("[CAL] -> phy_calibration_winbond()\n"));
++
++ // 20040701 1.1.25.1000 kevin
++ hw_get_cxx_reg(phw_data, 0x80, &mac_ctrl);
++ hw_get_cxx_reg(phw_data, 0xE4, &rf_ctrl);
++ hw_get_dxx_reg(phw_data, 0x58, &iq_alpha);
++
++
++
++ _rxadc_dc_offset_cancellation_winbond(phw_data, frequency);
++ //_txidac_dc_offset_cancellation_winbond(phw_data);
++ //_txqdac_dc_offset_cacellation_winbond(phw_data);
++
++ _tx_iq_calibration_winbond(phw_data);
++ _rx_iq_calibration_winbond(phw_data, frequency);
++
++ //------------------------------------------------------------------------
++ hw_get_dxx_reg(phw_data, REG_MODE_CTRL, ®_mode_ctrl);
++ reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE|MASK_CALIB_START); // set when finish
++ hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
++ PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
++
++ // i. Set RFIC to "Normal mode"
++ hw_set_cxx_reg(phw_data, 0x80, mac_ctrl);
++ hw_set_cxx_reg(phw_data, 0xE4, rf_ctrl);
++ hw_set_dxx_reg(phw_data, 0x58, iq_alpha);
++
++
++ //------------------------------------------------------------------------
++ phy_init_rf(phw_data);
++
++}
++
++//===========================
++void phy_set_rf_data( phw_data_t pHwData, u32 index, u32 value )
++{
++ u32 ltmp=0;
++
++ switch( pHwData->phy_type )
++ {
++ case RF_MAXIM_2825:
++ case RF_MAXIM_V1: // 11g Winbond 2nd BB(with Phy board (v1) + Maxim 331)
++ ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( value, 18 );
++ break;
++
++ case RF_MAXIM_2827:
++ ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( value, 18 );
++ break;
++
++ case RF_MAXIM_2828:
++ ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( value, 18 );
++ break;
++
++ case RF_MAXIM_2829:
++ ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( value, 18 );
++ break;
++
++ case RF_AIROHA_2230:
++ case RF_AIROHA_2230S: // 20060420 Add this
++ ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( value, 20 );
++ break;
++
++ case RF_AIROHA_7230:
++ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | (value&0xffffff);
++ break;
++
++ case RF_WB_242:
++ case RF_WB_242_1: // 20060619.5 Add
++ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( value, 24 );
++ break;
++ }
++
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++}
++
++// 20060717 modify as Bruce's mail
++unsigned char adjust_TXVGA_for_iq_mag(hw_data_t *phw_data)
++{
++ int init_txvga = 0;
++ u32 reg_mode_ctrl;
++ u32 val;
++ s32 iqcal_tone_i0;
++ s32 iqcal_tone_q0;
++ u32 sqsum;
++ s32 iq_mag_0_tx;
++ u8 reg_state;
++ int current_txvga;
++
++
++ reg_state = 0;
++ for( init_txvga=0; init_txvga<10; init_txvga++)
++ {
++ current_txvga = ( 0x24C40A|(init_txvga<<6) );
++ phy_set_rf_data(phw_data, 5, ((5<<24)|current_txvga) );
++ phw_data->txvga_setting_for_cal = current_txvga;
++
++ //pa_stall_execution(30000);//Sleep(30);
++ OS_SLEEP(30000); // 20060612.1.a
++
++ if( !hw_get_dxx_reg(phw_data, REG_MODE_CTRL, ®_mode_ctrl) ) // 20060718.1 modify
++ return FALSE;
++
++ PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
++
++ // a. Set iqcal_mode[1:0] to 0x2 and set "calib_start" to 0x1 to
++ // enable "IQ alibration Mode II"
++ reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE);
++ reg_mode_ctrl &= ~MASK_IQCAL_MODE;
++ reg_mode_ctrl |= (MASK_CALIB_START|0x02);
++ reg_mode_ctrl |= (MASK_CALIB_START|0x02|2<<2);
++ hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
++ PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
++
++ //pa_stall_execution(US);
++ OS_SLEEP(1); // 20060612.1.a
++
++ //pa_stall_execution(300);//Sleep(30);
++ OS_SLEEP(300); // 20060612.1.a
++
++ // b.
++ hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val);
++
++ PHY_DEBUG(("[CAL] CALIB_READ1 = 0x%08X\n", val));
++ //pa_stall_execution(US);
++ //pa_stall_execution(300);//Sleep(30);
++ OS_SLEEP(300); // 20060612.1.a
++
++ iqcal_tone_i0 = _s13_to_s32(val & 0x00001FFF);
++ iqcal_tone_q0 = _s13_to_s32((val & 0x03FFE000) >> 13);
++ PHY_DEBUG(("[CAL] ** iqcal_tone_i0=%d, iqcal_tone_q0=%d\n",
++ iqcal_tone_i0, iqcal_tone_q0));
++
++ sqsum = iqcal_tone_i0*iqcal_tone_i0 + iqcal_tone_q0*iqcal_tone_q0;
++ iq_mag_0_tx = (s32) _sqrt(sqsum);
++ PHY_DEBUG(("[CAL] ** auto_adjust_txvga_for_iq_mag_0_tx=%d\n", iq_mag_0_tx));
++
++ if( iq_mag_0_tx>=700 && iq_mag_0_tx<=1750 )
++ break;
++ else if(iq_mag_0_tx > 1750)
++ {
++ init_txvga=-2;
++ continue;
++ }
++ else
++ continue;
++
++ }
++
++ if( iq_mag_0_tx>=700 && iq_mag_0_tx<=1750 )
++ return TRUE;
++ else
++ return FALSE;
++}
++
++
++
+diff --git a/drivers/staging/winbond/phy_calibration.h b/drivers/staging/winbond/phy_calibration.h
+new file mode 100644
+index 0000000..b6a65d3
+--- /dev/null
++++ b/drivers/staging/winbond/phy_calibration.h
+@@ -0,0 +1,101 @@
++// 20031229 Turbo add
++#define REG_AGC_CTRL1 0x1000
++#define REG_AGC_CTRL2 0x1004
++#define REG_AGC_CTRL3 0x1008
++#define REG_AGC_CTRL4 0x100C
++#define REG_AGC_CTRL5 0x1010
++#define REG_AGC_CTRL6 0x1014
++#define REG_AGC_CTRL7 0x1018
++#define REG_AGC_CTRL8 0x101C
++#define REG_AGC_CTRL9 0x1020
++#define REG_AGC_CTRL10 0x1024
++#define REG_CCA_CTRL 0x1028
++#define REG_A_ACQ_CTRL 0x102C
++#define REG_B_ACQ_CTRL 0x1030
++#define REG_A_TXRX_CTRL 0x1034
++#define REG_B_TXRX_CTRL 0x1038
++#define REG_A_TX_COEF3 0x103C
++#define REG_A_TX_COEF2 0x1040
++#define REG_A_TX_COEF1 0x1044
++#define REG_B_TX_COEF2 0x1048
++#define REG_B_TX_COEF1 0x104C
++#define REG_MODE_CTRL 0x1050
++#define REG_CALIB_DATA 0x1054
++#define REG_IQ_ALPHA 0x1058
++#define REG_DC_CANCEL 0x105C
++#define REG_WTO_READ 0x1060
++#define REG_OFFSET_READ 0x1064
++#define REG_CALIB_READ1 0x1068
++#define REG_CALIB_READ2 0x106C
++#define REG_A_FREQ_EST 0x1070
++
++
++
++
++// 20031101 Turbo add
++#define MASK_AMER_OFF_REG BIT(31)
++
++#define MASK_BMER_OFF_REG BIT(31)
++
++#define MASK_LNA_FIX_GAIN (BIT(3)|BIT(4))
++#define MASK_AGC_FIX BIT(1)
++
++#define MASK_AGC_FIX_GAIN 0xFF00
++
++#define MASK_ADC_DC_CAL_STR BIT(10)
++#define MASK_CALIB_START BIT(4)
++#define MASK_IQCAL_TONE_SEL (BIT(3)|BIT(2))
++#define MASK_IQCAL_MODE (BIT(1)|BIT(0))
++
++#define MASK_TX_CAL_0 0xF0000000
++#define TX_CAL_0_SHIFT 28
++#define MASK_TX_CAL_1 0x0F000000
++#define TX_CAL_1_SHIFT 24
++#define MASK_TX_CAL_2 0x00F00000
++#define TX_CAL_2_SHIFT 20
++#define MASK_TX_CAL_3 0x000F0000
++#define TX_CAL_3_SHIFT 16
++#define MASK_RX_CAL_0 0x0000F000
++#define RX_CAL_0_SHIFT 12
++#define MASK_RX_CAL_1 0x00000F00
++#define RX_CAL_1_SHIFT 8
++#define MASK_RX_CAL_2 0x000000F0
++#define RX_CAL_2_SHIFT 4
++#define MASK_RX_CAL_3 0x0000000F
++#define RX_CAL_3_SHIFT 0
++
++#define MASK_CANCEL_DC_I 0x3E0
++#define CANCEL_DC_I_SHIFT 5
++#define MASK_CANCEL_DC_Q 0x01F
++#define CANCEL_DC_Q_SHIFT 0
++
++// LA20040210 kevin
++//#define MASK_ADC_DC_CAL_I(x) (((x)&0x1FE00)>>9)
++//#define MASK_ADC_DC_CAL_Q(x) ((x)&0x1FF)
++#define MASK_ADC_DC_CAL_I(x) (((x)&0x0003FE00)>>9)
++#define MASK_ADC_DC_CAL_Q(x) ((x)&0x000001FF)
++
++// LA20040210 kevin (Turbo has wrong definition)
++//#define MASK_IQCAL_TONE_I 0x7FFC000
++//#define SHIFT_IQCAL_TONE_I(x) ((x)>>13)
++//#define MASK_IQCAL_TONE_Q 0x1FFF
++//#define SHIFT_IQCAL_TONE_Q(x) ((x)>>0)
++#define MASK_IQCAL_TONE_I 0x00001FFF
++#define SHIFT_IQCAL_TONE_I(x) ((x)>>0)
++#define MASK_IQCAL_TONE_Q 0x03FFE000
++#define SHIFT_IQCAL_TONE_Q(x) ((x)>>13)
++
++// LA20040210 kevin (Turbo has wrong definition)
++//#define MASK_IQCAL_IMAGE_I 0x7FFC000
++//#define SHIFT_IQCAL_IMAGE_I(x) ((x)>>13)
++//#define MASK_IQCAL_IMAGE_Q 0x1FFF
++//#define SHIFT_IQCAL_IMAGE_Q(x) ((x)>>0)
++
++//#define MASK_IQCAL_IMAGE_I 0x00001FFF
++//#define SHIFT_IQCAL_IMAGE_I(x) ((x)>>0)
++//#define MASK_IQCAL_IMAGE_Q 0x03FFE000
++//#define SHIFT_IQCAL_IMAGE_Q(x) ((x)>>13)
++
++void phy_set_rf_data( phw_data_t pHwData, u32 index, u32 value );
++#define phy_init_rf( _A ) //RFSynthesizer_initial( _A )
++
+diff --git a/drivers/staging/winbond/reg.c b/drivers/staging/winbond/reg.c
+new file mode 100644
+index 0000000..b475c7a
+--- /dev/null
++++ b/drivers/staging/winbond/reg.c
+@@ -0,0 +1,2683 @@
++#include "os_common.h"
++
++///////////////////////////////////////////////////////////////////////////////////////////////////
++// Original Phy.h
++//*****************************************************************************
++
++/*****************************************************************************
++; For MAXIM2825/6/7 Ver. 331 or more
++; Edited by Tiger, Sep-17-2003
++; revised by Ben, Sep-18-2003
++
++0x00 0x000a2
++0x01 0x21cc0
++;0x02 0x13802
++0x02 0x1383a
++
++;channe1 01 ; 0x03 0x30142 ; 0x04 0x0b333;
++;channe1 02 ;0x03 0x32141 ;0x04 0x08444;
++;channe1 03 ;0x03 0x32143 ;0x04 0x0aeee;
++;channe1 04 ;0x03 0x32142 ;0x04 0x0b333;
++;channe1 05 ;0x03 0x31141 ;0x04 0x08444;
++;channe1 06 ;
++0x03 0x31143;
++0x04 0x0aeee;
++;channe1 07 ;0x03 0x31142 ;0x04 0x0b333;
++;channe1 08 ;0x03 0x33141 ;0x04 0x08444;
++;channe1 09 ;0x03 0x33143 ;0x04 0x0aeee;
++;channe1 10 ;0x03 0x33142 ;0x04 0x0b333;
++;channe1 11 ;0x03 0x30941 ;0x04 0x08444;
++;channe1 12 ;0x03 0x30943 ;0x04 0x0aeee;
++;channe1 13 ;0x03 0x30942 ;0x04 0x0b333;
++
++0x05 0x28986
++0x06 0x18008
++0x07 0x38400
++0x08 0x05100; 100 Hz DC
++;0x08 0x05900; 30 KHz DC
++0x09 0x24f08
++0x0a 0x17e00, 0x17ea0
++0x0b 0x37d80
++0x0c 0x0c900 // 0x0ca00 (lager power 9db than 0x0c000), 0x0c000
++*****************************************************************************/
++// MAX2825 (pure b/g)
++u32 max2825_rf_data[] =
++{
++ (0x00<<18)|0x000a2,
++ (0x01<<18)|0x21cc0,
++ (0x02<<18)|0x13806,
++ (0x03<<18)|0x30142,
++ (0x04<<18)|0x0b333,
++ (0x05<<18)|0x289A6,
++ (0x06<<18)|0x18008,
++ (0x07<<18)|0x38000,
++ (0x08<<18)|0x05100,
++ (0x09<<18)|0x24f08,
++ (0x0A<<18)|0x14000,
++ (0x0B<<18)|0x37d80,
++ (0x0C<<18)|0x0c100 // 11a: 0x0c300, 11g: 0x0c100
++};
++
++u32 max2825_channel_data_24[][3] =
++{
++ {(0x03<<18)|0x30142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 01
++ {(0x03<<18)|0x32141, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 02
++ {(0x03<<18)|0x32143, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 03
++ {(0x03<<18)|0x32142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 04
++ {(0x03<<18)|0x31141, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 05
++ {(0x03<<18)|0x31143, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 06
++ {(0x03<<18)|0x31142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 07
++ {(0x03<<18)|0x33141, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 08
++ {(0x03<<18)|0x33143, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 09
++ {(0x03<<18)|0x33142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 10
++ {(0x03<<18)|0x30941, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 11
++ {(0x03<<18)|0x30943, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 12
++ {(0x03<<18)|0x30942, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 13
++ {(0x03<<18)|0x32941, (0x04<<18)|0x09999, (0x05<<18)|0x289A6} // 14 (2484MHz) hhmodify
++};
++
++u32 max2825_power_data_24[] = {(0x0C<<18)|0x0c000, (0x0C<<18)|0x0c100};
++
++/****************************************************************************/
++// MAX2827 (a/b/g)
++u32 max2827_rf_data[] =
++{
++ (0x00<<18)|0x000a2,
++ (0x01<<18)|0x21cc0,
++ (0x02<<18)|0x13806,
++ (0x03<<18)|0x30142,
++ (0x04<<18)|0x0b333,
++ (0x05<<18)|0x289A6,
++ (0x06<<18)|0x18008,
++ (0x07<<18)|0x38000,
++ (0x08<<18)|0x05100,
++ (0x09<<18)|0x24f08,
++ (0x0A<<18)|0x14000,
++ (0x0B<<18)|0x37d80,
++ (0x0C<<18)|0x0c100 // 11a: 0x0c300, 11g: 0x0c100
++};
++
++u32 max2827_channel_data_24[][3] =
++{
++ {(0x03<<18)|0x30142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 01
++ {(0x03<<18)|0x32141, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 02
++ {(0x03<<18)|0x32143, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 03
++ {(0x03<<18)|0x32142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 04
++ {(0x03<<18)|0x31141, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 05
++ {(0x03<<18)|0x31143, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 06
++ {(0x03<<18)|0x31142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 07
++ {(0x03<<18)|0x33141, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 08
++ {(0x03<<18)|0x33143, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 09
++ {(0x03<<18)|0x33142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 10
++ {(0x03<<18)|0x30941, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 11
++ {(0x03<<18)|0x30943, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 12
++ {(0x03<<18)|0x30942, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 13
++ {(0x03<<18)|0x32941, (0x04<<18)|0x09999, (0x05<<18)|0x289A6} // 14 (2484MHz) hhmodify
++};
++
++u32 max2827_channel_data_50[][3] =
++{
++ {(0x03<<18)|0x33cc3, (0x04<<18)|0x08ccc, (0x05<<18)|0x2A9A6}, // channel 36
++ {(0x03<<18)|0x302c0, (0x04<<18)|0x08000, (0x05<<18)|0x2A9A6}, // channel 40
++ {(0x03<<18)|0x302c2, (0x04<<18)|0x0b333, (0x05<<18)|0x2A9A6}, // channel 44
++ {(0x03<<18)|0x322c1, (0x04<<18)|0x09999, (0x05<<18)|0x2A9A6}, // channel 48
++ {(0x03<<18)|0x312c1, (0x04<<18)|0x0a666, (0x05<<18)|0x2A9A6}, // channel 52
++ {(0x03<<18)|0x332c3, (0x04<<18)|0x08ccc, (0x05<<18)|0x2A9A6}, // channel 56
++ {(0x03<<18)|0x30ac0, (0x04<<18)|0x08000, (0x05<<18)|0x2A9A6}, // channel 60
++ {(0x03<<18)|0x30ac2, (0x04<<18)|0x0b333, (0x05<<18)|0x2A9A6} // channel 64
++};
++
++u32 max2827_power_data_24[] = {(0x0C<<18)|0x0C000, (0x0C<<18)|0x0D600, (0x0C<<18)|0x0C100};
++u32 max2827_power_data_50[] = {(0x0C<<18)|0x0C400, (0x0C<<18)|0x0D500, (0x0C<<18)|0x0C300};
++
++/****************************************************************************/
++// MAX2828 (a/b/g)
++u32 max2828_rf_data[] =
++{
++ (0x00<<18)|0x000a2,
++ (0x01<<18)|0x21cc0,
++ (0x02<<18)|0x13806,
++ (0x03<<18)|0x30142,
++ (0x04<<18)|0x0b333,
++ (0x05<<18)|0x289A6,
++ (0x06<<18)|0x18008,
++ (0x07<<18)|0x38000,
++ (0x08<<18)|0x05100,
++ (0x09<<18)|0x24f08,
++ (0x0A<<18)|0x14000,
++ (0x0B<<18)|0x37d80,
++ (0x0C<<18)|0x0c100 // 11a: 0x0c300, 11g: 0x0c100
++};
++
++u32 max2828_channel_data_24[][3] =
++{
++ {(0x03<<18)|0x30142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 01
++ {(0x03<<18)|0x32141, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 02
++ {(0x03<<18)|0x32143, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 03
++ {(0x03<<18)|0x32142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 04
++ {(0x03<<18)|0x31141, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 05
++ {(0x03<<18)|0x31143, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 06
++ {(0x03<<18)|0x31142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 07
++ {(0x03<<18)|0x33141, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 08
++ {(0x03<<18)|0x33143, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 09
++ {(0x03<<18)|0x33142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 10
++ {(0x03<<18)|0x30941, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 11
++ {(0x03<<18)|0x30943, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 12
++ {(0x03<<18)|0x30942, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 13
++ {(0x03<<18)|0x32941, (0x04<<18)|0x09999, (0x05<<18)|0x289A6} // 14 (2484MHz) hhmodify
++};
++
++u32 max2828_channel_data_50[][3] =
++{
++ {(0x03<<18)|0x33cc3, (0x04<<18)|0x08ccc, (0x05<<18)|0x289A6}, // channel 36
++ {(0x03<<18)|0x302c0, (0x04<<18)|0x08000, (0x05<<18)|0x289A6}, // channel 40
++ {(0x03<<18)|0x302c2, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channel 44
++ {(0x03<<18)|0x322c1, (0x04<<18)|0x09999, (0x05<<18)|0x289A6}, // channel 48
++ {(0x03<<18)|0x312c1, (0x04<<18)|0x0a666, (0x05<<18)|0x289A6}, // channel 52
++ {(0x03<<18)|0x332c3, (0x04<<18)|0x08ccc, (0x05<<18)|0x289A6}, // channel 56
++ {(0x03<<18)|0x30ac0, (0x04<<18)|0x08000, (0x05<<18)|0x289A6}, // channel 60
++ {(0x03<<18)|0x30ac2, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6} // channel 64
++};
++
++u32 max2828_power_data_24[] = {(0x0C<<18)|0x0c000, (0x0C<<18)|0x0c100};
++u32 max2828_power_data_50[] = {(0x0C<<18)|0x0c000, (0x0C<<18)|0x0c100};
++
++/****************************************************************************/
++// LA20040728 kevin
++// MAX2829 (a/b/g)
++u32 max2829_rf_data[] =
++{
++ (0x00<<18)|0x000a2,
++ (0x01<<18)|0x23520,
++ (0x02<<18)|0x13802,
++ (0x03<<18)|0x30142,
++ (0x04<<18)|0x0b333,
++ (0x05<<18)|0x28906,
++ (0x06<<18)|0x18008,
++ (0x07<<18)|0x3B500,
++ (0x08<<18)|0x05100,
++ (0x09<<18)|0x24f08,
++ (0x0A<<18)|0x14000,
++ (0x0B<<18)|0x37d80,
++ (0x0C<<18)|0x0F300 //TXVGA=51, (MAX-6 dB)
++};
++
++u32 max2829_channel_data_24[][3] =
++{
++ {(3<<18)|0x30142, (4<<18)|0x0b333, (5<<18)|0x289C6}, // 01 (2412MHz)
++ {(3<<18)|0x32141, (4<<18)|0x08444, (5<<18)|0x289C6}, // 02 (2417MHz)
++ {(3<<18)|0x32143, (4<<18)|0x0aeee, (5<<18)|0x289C6}, // 03 (2422MHz)
++ {(3<<18)|0x32142, (4<<18)|0x0b333, (5<<18)|0x289C6}, // 04 (2427MHz)
++ {(3<<18)|0x31141, (4<<18)|0x08444, (5<<18)|0x289C6}, // 05 (2432MHz)
++ {(3<<18)|0x31143, (4<<18)|0x0aeee, (5<<18)|0x289C6}, // 06 (2437MHz)
++ {(3<<18)|0x31142, (4<<18)|0x0b333, (5<<18)|0x289C6}, // 07 (2442MHz)
++ {(3<<18)|0x33141, (4<<18)|0x08444, (5<<18)|0x289C6}, // 08 (2447MHz)
++ {(3<<18)|0x33143, (4<<18)|0x0aeee, (5<<18)|0x289C6}, // 09 (2452MHz)
++ {(3<<18)|0x33142, (4<<18)|0x0b333, (5<<18)|0x289C6}, // 10 (2457MHz)
++ {(3<<18)|0x30941, (4<<18)|0x08444, (5<<18)|0x289C6}, // 11 (2462MHz)
++ {(3<<18)|0x30943, (4<<18)|0x0aeee, (5<<18)|0x289C6}, // 12 (2467MHz)
++ {(3<<18)|0x30942, (4<<18)|0x0b333, (5<<18)|0x289C6}, // 13 (2472MHz)
++ {(3<<18)|0x32941, (4<<18)|0x09999, (5<<18)|0x289C6}, // 14 (2484MHz) hh-modify
++};
++
++u32 max2829_channel_data_50[][4] =
++{
++ {36, (3<<18)|0x33cc3, (4<<18)|0x08ccc, (5<<18)|0x2A946}, // 36 (5.180GHz)
++ {40, (3<<18)|0x302c0, (4<<18)|0x08000, (5<<18)|0x2A946}, // 40 (5.200GHz)
++ {44, (3<<18)|0x302c2, (4<<18)|0x0b333, (5<<18)|0x2A946}, // 44 (5.220GHz)
++ {48, (3<<18)|0x322c1, (4<<18)|0x09999, (5<<18)|0x2A946}, // 48 (5.240GHz)
++ {52, (3<<18)|0x312c1, (4<<18)|0x0a666, (5<<18)|0x2A946}, // 52 (5.260GHz)
++ {56, (3<<18)|0x332c3, (4<<18)|0x08ccc, (5<<18)|0x2A946}, // 56 (5.280GHz)
++ {60, (3<<18)|0x30ac0, (4<<18)|0x08000, (5<<18)|0x2A946}, // 60 (5.300GHz)
++ {64, (3<<18)|0x30ac2, (4<<18)|0x0b333, (5<<18)|0x2A946}, // 64 (5.320GHz)
++
++ {100, (3<<18)|0x30ec0, (4<<18)|0x08000, (5<<18)|0x2A9C6}, // 100 (5.500GHz)
++ {104, (3<<18)|0x30ec2, (4<<18)|0x0b333, (5<<18)|0x2A9C6}, // 104 (5.520GHz)
++ {108, (3<<18)|0x32ec1, (4<<18)|0x09999, (5<<18)|0x2A9C6}, // 108 (5.540GHz)
++ {112, (3<<18)|0x31ec1, (4<<18)|0x0a666, (5<<18)|0x2A9C6}, // 112 (5.560GHz)
++ {116, (3<<18)|0x33ec3, (4<<18)|0x08ccc, (5<<18)|0x2A9C6}, // 116 (5.580GHz)
++ {120, (3<<18)|0x301c0, (4<<18)|0x08000, (5<<18)|0x2A9C6}, // 120 (5.600GHz)
++ {124, (3<<18)|0x301c2, (4<<18)|0x0b333, (5<<18)|0x2A9C6}, // 124 (5.620GHz)
++ {128, (3<<18)|0x321c1, (4<<18)|0x09999, (5<<18)|0x2A9C6}, // 128 (5.640GHz)
++ {132, (3<<18)|0x311c1, (4<<18)|0x0a666, (5<<18)|0x2A9C6}, // 132 (5.660GHz)
++ {136, (3<<18)|0x331c3, (4<<18)|0x08ccc, (5<<18)|0x2A9C6}, // 136 (5.680GHz)
++ {140, (3<<18)|0x309c0, (4<<18)|0x08000, (5<<18)|0x2A9C6}, // 140 (5.700GHz)
++
++ {149, (3<<18)|0x329c2, (4<<18)|0x0b333, (5<<18)|0x2A9C6}, // 149 (5.745GHz)
++ {153, (3<<18)|0x319c1, (4<<18)|0x09999, (5<<18)|0x2A9C6}, // 153 (5.765GHz)
++ {157, (3<<18)|0x339c1, (4<<18)|0x0a666, (5<<18)|0x2A9C6}, // 157 (5.785GHz)
++ {161, (3<<18)|0x305c3, (4<<18)|0x08ccc, (5<<18)|0x2A9C6}, // 161 (5.805GHz)
++
++ // Japan
++ { 184, (3<<18)|0x308c2, (4<<18)|0x0b333, (5<<18)|0x2A946}, // 184 (4.920GHz)
++ { 188, (3<<18)|0x328c1, (4<<18)|0x09999, (5<<18)|0x2A946}, // 188 (4.940GHz)
++ { 192, (3<<18)|0x318c1, (4<<18)|0x0a666, (5<<18)|0x2A946}, // 192 (4.960GHz)
++ { 196, (3<<18)|0x338c3, (4<<18)|0x08ccc, (5<<18)|0x2A946}, // 196 (4.980GHz)
++ { 8, (3<<18)|0x324c1, (4<<18)|0x09999, (5<<18)|0x2A946}, // 8 (5.040GHz)
++ { 12, (3<<18)|0x314c1, (4<<18)|0x0a666, (5<<18)|0x2A946}, // 12 (5.060GHz)
++ { 16, (3<<18)|0x334c3, (4<<18)|0x08ccc, (5<<18)|0x2A946}, // 16 (5.080GHz)
++ { 34, (3<<18)|0x31cc2, (4<<18)|0x0b333, (5<<18)|0x2A946}, // 34 (5.170GHz)
++ { 38, (3<<18)|0x33cc1, (4<<18)|0x09999, (5<<18)|0x2A946}, // 38 (5.190GHz)
++ { 42, (3<<18)|0x302c1, (4<<18)|0x0a666, (5<<18)|0x2A946}, // 42 (5.210GHz)
++ { 46, (3<<18)|0x322c3, (4<<18)|0x08ccc, (5<<18)|0x2A946}, // 46 (5.230GHz)
++};
++
++/*****************************************************************************
++; For MAXIM2825/6/7 Ver. 317 or less
++; Edited by Tiger, Sep-17-2003 for 2.4Ghz channels
++; Updated by Tiger, Sep-22-2003 for 5.0Ghz channels
++; Corrected by Tiger, Sep-23-2003, for 0x03 and 0x04 of 5.0Ghz channels
++
++0x00 0x00080
++0x01 0x214c0
++0x02 0x13802
++
++;2.4GHz Channels
++;channe1 01 (2.412GHz); 0x03 0x30143 ;0x04 0x0accc
++;channe1 02 (2.417GHz); 0x03 0x32140 ;0x04 0x09111
++;channe1 03 (2.422GHz); 0x03 0x32142 ;0x04 0x0bbbb
++;channe1 04 (2.427GHz); 0x03 0x32143 ;0x04 0x0accc
++;channe1 05 (2.432GHz); 0x03 0x31140 ;0x04 0x09111
++;channe1 06 (2.437GHz); 0x03 0x31142 ;0x04 0x0bbbb
++;channe1 07 (2.442GHz); 0x03 0x31143 ;0x04 0x0accc
++;channe1 08 (2.447GHz); 0x03 0x33140 ;0x04 0x09111
++;channe1 09 (2.452GHz); 0x03 0x33142 ;0x04 0x0bbbb
++;channe1 10 (2.457GHz); 0x03 0x33143 ;0x04 0x0accc
++;channe1 11 (2.462GHz); 0x03 0x30940 ;0x04 0x09111
++;channe1 12 (2.467GHz); 0x03 0x30942 ;0x04 0x0bbbb
++;channe1 13 (2.472GHz); 0x03 0x30943 ;0x04 0x0accc
++
++;5.0Ghz Channels
++;channel 36 (5.180GHz); 0x03 0x33cc0 ;0x04 0x0b333
++;channel 40 (5.200GHz); 0x03 0x302c0 ;0x04 0x08000
++;channel 44 (5.220GHz); 0x03 0x302c2 ;0x04 0x0b333
++;channel 48 (5.240GHz); 0x03 0x322c1 ;0x04 0x09999
++;channel 52 (5.260GHz); 0x03 0x312c1 ;0x04 0x0a666
++;channel 56 (5.280GHz); 0x03 0x332c3 ;0x04 0x08ccc
++;channel 60 (5.300GHz); 0x03 0x30ac0 ;0x04 0x08000
++;channel 64 (5.320GHz); 0x03 0x30ac2 ;0x04 0x08333
++
++;2.4GHz band ;0x05 0x28986;
++;5.0GHz band
++0x05 0x2a986
++
++0x06 0x18008
++0x07 0x38400
++0x08 0x05108
++0x09 0x27ff8
++0x0a 0x14000
++0x0b 0x37f99
++0x0c 0x0c000
++*****************************************************************************/
++u32 maxim_317_rf_data[] =
++{
++ (0x00<<18)|0x000a2,
++ (0x01<<18)|0x214c0,
++ (0x02<<18)|0x13802,
++ (0x03<<18)|0x30143,
++ (0x04<<18)|0x0accc,
++ (0x05<<18)|0x28986,
++ (0x06<<18)|0x18008,
++ (0x07<<18)|0x38400,
++ (0x08<<18)|0x05108,
++ (0x09<<18)|0x27ff8,
++ (0x0A<<18)|0x14000,
++ (0x0B<<18)|0x37f99,
++ (0x0C<<18)|0x0c000
++};
++
++u32 maxim_317_channel_data_24[][3] =
++{
++ {(0x03<<18)|0x30143, (0x04<<18)|0x0accc, (0x05<<18)|0x28986}, // channe1 01
++ {(0x03<<18)|0x32140, (0x04<<18)|0x09111, (0x05<<18)|0x28986}, // channe1 02
++ {(0x03<<18)|0x32142, (0x04<<18)|0x0bbbb, (0x05<<18)|0x28986}, // channe1 03
++ {(0x03<<18)|0x32143, (0x04<<18)|0x0accc, (0x05<<18)|0x28986}, // channe1 04
++ {(0x03<<18)|0x31140, (0x04<<18)|0x09111, (0x05<<18)|0x28986}, // channe1 05
++ {(0x03<<18)|0x31142, (0x04<<18)|0x0bbbb, (0x05<<18)|0x28986}, // channe1 06
++ {(0x03<<18)|0x31143, (0x04<<18)|0x0accc, (0x05<<18)|0x28986}, // channe1 07
++ {(0x03<<18)|0x33140, (0x04<<18)|0x09111, (0x05<<18)|0x28986}, // channe1 08
++ {(0x03<<18)|0x33142, (0x04<<18)|0x0bbbb, (0x05<<18)|0x28986}, // channe1 09
++ {(0x03<<18)|0x33143, (0x04<<18)|0x0accc, (0x05<<18)|0x28986}, // channe1 10
++ {(0x03<<18)|0x30940, (0x04<<18)|0x09111, (0x05<<18)|0x28986}, // channe1 11
++ {(0x03<<18)|0x30942, (0x04<<18)|0x0bbbb, (0x05<<18)|0x28986}, // channe1 12
++ {(0x03<<18)|0x30943, (0x04<<18)|0x0accc, (0x05<<18)|0x28986} // channe1 13
++};
++
++u32 maxim_317_channel_data_50[][3] =
++{
++ {(0x03<<18)|0x33cc0, (0x04<<18)|0x0b333, (0x05<<18)|0x2a986}, // channel 36
++ {(0x03<<18)|0x302c0, (0x04<<18)|0x08000, (0x05<<18)|0x2a986}, // channel 40
++ {(0x03<<18)|0x302c3, (0x04<<18)|0x0accc, (0x05<<18)|0x2a986}, // channel 44
++ {(0x03<<18)|0x322c1, (0x04<<18)|0x09666, (0x05<<18)|0x2a986}, // channel 48
++ {(0x03<<18)|0x312c2, (0x04<<18)|0x09999, (0x05<<18)|0x2a986}, // channel 52
++ {(0x03<<18)|0x332c0, (0x04<<18)|0x0b333, (0x05<<18)|0x2a99e}, // channel 56
++ {(0x03<<18)|0x30ac0, (0x04<<18)|0x08000, (0x05<<18)|0x2a99e}, // channel 60
++ {(0x03<<18)|0x30ac3, (0x04<<18)|0x0accc, (0x05<<18)|0x2a99e} // channel 64
++};
++
++u32 maxim_317_power_data_24[] = {(0x0C<<18)|0x0c000, (0x0C<<18)|0x0c100};
++u32 maxim_317_power_data_50[] = {(0x0C<<18)|0x0c000, (0x0C<<18)|0x0c100};
++
++/*****************************************************************************
++;;AL2230 MP (Mass Production Version)
++;;RF Registers Setting for Airoha AL2230 silicon after June 1st, 2004
++;;Updated by Tiger Huang (June 1st, 2004)
++;;20-bit length and LSB first
++
++;;Ch01 (2412MHz) ;0x00 0x09EFC ;0x01 0x8CCCC;
++;;Ch02 (2417MHz) ;0x00 0x09EFC ;0x01 0x8CCCD;
++;;Ch03 (2422MHz) ;0x00 0x09E7C ;0x01 0x8CCCC;
++;;Ch04 (2427MHz) ;0x00 0x09E7C ;0x01 0x8CCCD;
++;;Ch05 (2432MHz) ;0x00 0x05EFC ;0x01 0x8CCCC;
++;;Ch06 (2437MHz) ;0x00 0x05EFC ;0x01 0x8CCCD;
++;;Ch07 (2442MHz) ;0x00 0x05E7C ;0x01 0x8CCCC;
++;;Ch08 (2447MHz) ;0x00 0x05E7C ;0x01 0x8CCCD;
++;;Ch09 (2452MHz) ;0x00 0x0DEFC ;0x01 0x8CCCC;
++;;Ch10 (2457MHz) ;0x00 0x0DEFC ;0x01 0x8CCCD;
++;;Ch11 (2462MHz) ;0x00 0x0DE7C ;0x01 0x8CCCC;
++;;Ch12 (2467MHz) ;0x00 0x0DE7C ;0x01 0x8CCCD;
++;;Ch13 (2472MHz) ;0x00 0x03EFC ;0x01 0x8CCCC;
++;;Ch14 (2484Mhz) ;0x00 0x03E7C ;0x01 0x86666;
++
++0x02 0x401D8; RXDCOC BW 100Hz for RXHP low
++;;0x02 0x481DC; RXDCOC BW 30Khz for RXHP low
++
++0x03 0xCFFF0
++0x04 0x23800
++0x05 0xA3B72
++0x06 0x6DA01
++0x07 0xE1688
++0x08 0x11600
++0x09 0x99E02
++0x0A 0x5DDB0
++0x0B 0xD9900
++0x0C 0x3FFBD
++0x0D 0xB0000
++0x0F 0xF00A0
++
++;RF Calibration for Airoha AL2230
++;Edit by Ben Chang (01/30/04)
++;Updated by Tiger Huang (03/03/04)
++0x0f 0xf00a0 ; Initial Setting
++0x0f 0xf00b0 ; Activate TX DCC
++0x0f 0xf02a0 ; Activate Phase Calibration
++0x0f 0xf00e0 ; Activate Filter RC Calibration
++0x0f 0xf00a0 ; Restore Initial Setting
++*****************************************************************************/
++
++u32 al2230_rf_data[] =
++{
++ (0x00<<20)|0x09EFC,
++ (0x01<<20)|0x8CCCC,
++ (0x02<<20)|0x40058,// 20060627 Anson 0x401D8,
++ (0x03<<20)|0xCFFF0,
++ (0x04<<20)|0x24100,// 20060627 Anson 0x23800,
++ (0x05<<20)|0xA3B2F,// 20060627 Anson 0xA3B72
++ (0x06<<20)|0x6DA01,
++ (0x07<<20)|0xE3628,// 20060627 Anson 0xE1688,
++ (0x08<<20)|0x11600,
++ (0x09<<20)|0x9DC02,// 20060627 Anosn 0x97602,//0x99E02, //0x9AE02
++ (0x0A<<20)|0x5ddb0, // 941206 For QCOM interference 0x588b0,//0x5DDB0, 940601 adj 0x5aa30 for bluetooth
++ (0x0B<<20)|0xD9900,
++ (0x0C<<20)|0x3FFBD,
++ (0x0D<<20)|0xB0000,
++ (0x0F<<20)|0xF01A0 // 20060627 Anson 0xF00A0
++};
++
++u32 al2230s_rf_data[] =
++{
++ (0x00<<20)|0x09EFC,
++ (0x01<<20)|0x8CCCC,
++ (0x02<<20)|0x40058,// 20060419 0x401D8,
++ (0x03<<20)|0xCFFF0,
++ (0x04<<20)|0x24100,// 20060419 0x23800,
++ (0x05<<20)|0xA3B2F,// 20060419 0xA3B72,
++ (0x06<<20)|0x6DA01,
++ (0x07<<20)|0xE3628,// 20060419 0xE1688,
++ (0x08<<20)|0x11600,
++ (0x09<<20)|0x9DC02,// 20060419 0x97602,//0x99E02, //0x9AE02
++ (0x0A<<20)|0x5DDB0,// 941206 For QCOM interference 0x588b0,//0x5DDB0, 940601 adj 0x5aa30 for bluetooth
++ (0x0B<<20)|0xD9900,
++ (0x0C<<20)|0x3FFBD,
++ (0x0D<<20)|0xB0000,
++ (0x0F<<20)|0xF01A0 // 20060419 0xF00A0
++};
++
++u32 al2230_channel_data_24[][2] =
++{
++ {(0x00<<20)|0x09EFC, (0x01<<20)|0x8CCCC}, // channe1 01
++ {(0x00<<20)|0x09EFC, (0x01<<20)|0x8CCCD}, // channe1 02
++ {(0x00<<20)|0x09E7C, (0x01<<20)|0x8CCCC}, // channe1 03
++ {(0x00<<20)|0x09E7C, (0x01<<20)|0x8CCCD}, // channe1 04
++ {(0x00<<20)|0x05EFC, (0x01<<20)|0x8CCCC}, // channe1 05
++ {(0x00<<20)|0x05EFC, (0x01<<20)|0x8CCCD}, // channe1 06
++ {(0x00<<20)|0x05E7C, (0x01<<20)|0x8CCCC}, // channe1 07
++ {(0x00<<20)|0x05E7C, (0x01<<20)|0x8CCCD}, // channe1 08
++ {(0x00<<20)|0x0DEFC, (0x01<<20)|0x8CCCC}, // channe1 09
++ {(0x00<<20)|0x0DEFC, (0x01<<20)|0x8CCCD}, // channe1 10
++ {(0x00<<20)|0x0DE7C, (0x01<<20)|0x8CCCC}, // channe1 11
++ {(0x00<<20)|0x0DE7C, (0x01<<20)|0x8CCCD}, // channe1 12
++ {(0x00<<20)|0x03EFC, (0x01<<20)|0x8CCCC}, // channe1 13
++ {(0x00<<20)|0x03E7C, (0x01<<20)|0x86666} // channe1 14
++};
++
++// Current setting. u32 airoha_power_data_24[] = {(0x09<<20)|0x90202, (0x09<<20)|0x96602, (0x09<<20)|0x97602};
++#define AIROHA_TXVGA_LOW_INDEX 31 // Index for 0x90202
++#define AIROHA_TXVGA_MIDDLE_INDEX 12 // Index for 0x96602
++#define AIROHA_TXVGA_HIGH_INDEX 8 // Index for 0x97602 1.0.24.0 1.0.28.0
++/*
++u32 airoha_power_data_24[] =
++{
++ 0x9FE02, // Max - 0 dB
++ 0x9BE02, // Max - 1 dB
++ 0x9DE02, // Max - 2 dB
++ 0x99E02, // Max - 3 dB
++ 0x9EE02, // Max - 4 dB
++ 0x9AE02, // Max - 5 dB
++ 0x9CE02, // Max - 6 dB
++ 0x98E02, // Max - 7 dB
++ 0x97602, // Max - 8 dB
++ 0x93602, // Max - 9 dB
++ 0x95602, // Max - 10 dB
++ 0x91602, // Max - 11 dB
++ 0x96602, // Max - 12 dB
++ 0x92602, // Max - 13 dB
++ 0x94602, // Max - 14 dB
++ 0x90602, // Max - 15 dB
++ 0x97A02, // Max - 16 dB
++ 0x93A02, // Max - 17 dB
++ 0x95A02, // Max - 18 dB
++ 0x91A02, // Max - 19 dB
++ 0x96A02, // Max - 20 dB
++ 0x92A02, // Max - 21 dB
++ 0x94A02, // Max - 22 dB
++ 0x90A02, // Max - 23 dB
++ 0x97202, // Max - 24 dB
++ 0x93202, // Max - 25 dB
++ 0x95202, // Max - 26 dB
++ 0x91202, // Max - 27 dB
++ 0x96202, // Max - 28 dB
++ 0x92202, // Max - 29 dB
++ 0x94202, // Max - 30 dB
++ 0x90202 // Max - 31 dB
++};
++*/
++
++// 20040927 1.1.69.1000 ybjiang
++// from John
++u32 al2230_txvga_data[][2] =
++{
++ //value , index
++ {0x090202, 0},
++ {0x094202, 2},
++ {0x092202, 4},
++ {0x096202, 6},
++ {0x091202, 8},
++ {0x095202, 10},
++ {0x093202, 12},
++ {0x097202, 14},
++ {0x090A02, 16},
++ {0x094A02, 18},
++ {0x092A02, 20},
++ {0x096A02, 22},
++ {0x091A02, 24},
++ {0x095A02, 26},
++ {0x093A02, 28},
++ {0x097A02, 30},
++ {0x090602, 32},
++ {0x094602, 34},
++ {0x092602, 36},
++ {0x096602, 38},
++ {0x091602, 40},
++ {0x095602, 42},
++ {0x093602, 44},
++ {0x097602, 46},
++ {0x090E02, 48},
++ {0x098E02, 49},
++ {0x094E02, 50},
++ {0x09CE02, 51},
++ {0x092E02, 52},
++ {0x09AE02, 53},
++ {0x096E02, 54},
++ {0x09EE02, 55},
++ {0x091E02, 56},
++ {0x099E02, 57},
++ {0x095E02, 58},
++ {0x09DE02, 59},
++ {0x093E02, 60},
++ {0x09BE02, 61},
++ {0x097E02, 62},
++ {0x09FE02, 63}
++};
++
++//--------------------------------
++// For Airoha AL7230, 2.4Ghz band
++// Edit by Tiger, (March, 9, 2005)
++// 24bit, MSB first
++
++//channel independent registers:
++u32 al7230_rf_data_24[] =
++{
++ (0x00<<24)|0x003790,
++ (0x01<<24)|0x133331,
++ (0x02<<24)|0x841FF2,
++ (0x03<<24)|0x3FDFA3,
++ (0x04<<24)|0x7FD784,
++ (0x05<<24)|0x802B55,
++ (0x06<<24)|0x56AF36,
++ (0x07<<24)|0xCE0207,
++ (0x08<<24)|0x6EBC08,
++ (0x09<<24)|0x221BB9,
++ (0x0A<<24)|0xE0000A,
++ (0x0B<<24)|0x08071B,
++ (0x0C<<24)|0x000A3C,
++ (0x0D<<24)|0xFFFFFD,
++ (0x0E<<24)|0x00000E,
++ (0x0F<<24)|0x1ABA8F
++};
++
++u32 al7230_channel_data_24[][2] =
++{
++ {(0x00<<24)|0x003790, (0x01<<24)|0x133331}, // channe1 01
++ {(0x00<<24)|0x003790, (0x01<<24)|0x1B3331}, // channe1 02
++ {(0x00<<24)|0x003790, (0x01<<24)|0x033331}, // channe1 03
++ {(0x00<<24)|0x003790, (0x01<<24)|0x0B3331}, // channe1 04
++ {(0x00<<24)|0x0037A0, (0x01<<24)|0x133331}, // channe1 05
++ {(0x00<<24)|0x0037A0, (0x01<<24)|0x1B3331}, // channe1 06
++ {(0x00<<24)|0x0037A0, (0x01<<24)|0x033331}, // channe1 07
++ {(0x00<<24)|0x0037A0, (0x01<<24)|0x0B3331}, // channe1 08
++ {(0x00<<24)|0x0037B0, (0x01<<24)|0x133331}, // channe1 09
++ {(0x00<<24)|0x0037B0, (0x01<<24)|0x1B3331}, // channe1 10
++ {(0x00<<24)|0x0037B0, (0x01<<24)|0x033331}, // channe1 11
++ {(0x00<<24)|0x0037B0, (0x01<<24)|0x0B3331}, // channe1 12
++ {(0x00<<24)|0x0037C0, (0x01<<24)|0x133331}, // channe1 13
++ {(0x00<<24)|0x0037C0, (0x01<<24)|0x066661} // channel 14
++};
++
++//channel independent registers:
++u32 al7230_rf_data_50[] =
++{
++ (0x00<<24)|0x0FF520,
++ (0x01<<24)|0x000001,
++ (0x02<<24)|0x451FE2,
++ (0x03<<24)|0x5FDFA3,
++ (0x04<<24)|0x6FD784,
++ (0x05<<24)|0x853F55,
++ (0x06<<24)|0x56AF36,
++ (0x07<<24)|0xCE0207,
++ (0x08<<24)|0x6EBC08,
++ (0x09<<24)|0x221BB9,
++ (0x0A<<24)|0xE0600A,
++ (0x0B<<24)|0x08044B,
++ (0x0C<<24)|0x00143C,
++ (0x0D<<24)|0xFFFFFD,
++ (0x0E<<24)|0x00000E,
++ (0x0F<<24)|0x12BACF //5Ghz default state
++};
++
++u32 al7230_channel_data_5[][4] =
++{
++ //channel dependent registers: 0x00, 0x01 and 0x04
++ //11J ===========
++ {184, (0x00<<24)|0x0FF520, (0x01<<24)|0x000001, (0x04<<24)|0x67F784}, // channel 184
++ {188, (0x00<<24)|0x0FF520, (0x01<<24)|0x0AAAA1, (0x04<<24)|0x77F784}, // channel 188
++ {192, (0x00<<24)|0x0FF530, (0x01<<24)|0x155551, (0x04<<24)|0x77F784}, // channel 192
++ {196, (0x00<<24)|0x0FF530, (0x01<<24)|0x000001, (0x04<<24)|0x67F784}, // channel 196
++ {8, (0x00<<24)|0x0FF540, (0x01<<24)|0x000001, (0x04<<24)|0x67F784}, // channel 008
++ {12, (0x00<<24)|0x0FF540, (0x01<<24)|0x0AAAA1, (0x04<<24)|0x77F784}, // channel 012
++ {16, (0x00<<24)|0x0FF550, (0x01<<24)|0x155551, (0x04<<24)|0x77F784}, // channel 016
++ {34, (0x00<<24)|0x0FF560, (0x01<<24)|0x055551, (0x04<<24)|0x77F784}, // channel 034
++ {38, (0x00<<24)|0x0FF570, (0x01<<24)|0x100001, (0x04<<24)|0x77F784}, // channel 038
++ {42, (0x00<<24)|0x0FF570, (0x01<<24)|0x1AAAA1, (0x04<<24)|0x77F784}, // channel 042
++ {46, (0x00<<24)|0x0FF570, (0x01<<24)|0x055551, (0x04<<24)|0x77F784}, // channel 046
++ //11 A/H =========
++ {36, (0x00<<24)|0x0FF560, (0x01<<24)|0x0AAAA1, (0x04<<24)|0x77F784}, // channel 036
++ {40, (0x00<<24)|0x0FF570, (0x01<<24)|0x155551, (0x04<<24)|0x77F784}, // channel 040
++ {44, (0x00<<24)|0x0FF570, (0x01<<24)|0x000001, (0x04<<24)|0x67F784}, // channel 044
++ {48, (0x00<<24)|0x0FF570, (0x01<<24)|0x0AAAA1, (0x04<<24)|0x77F784}, // channel 048
++ {52, (0x00<<24)|0x0FF580, (0x01<<24)|0x155551, (0x04<<24)|0x77F784}, // channel 052
++ {56, (0x00<<24)|0x0FF580, (0x01<<24)|0x000001, (0x04<<24)|0x67F784}, // channel 056
++ {60, (0x00<<24)|0x0FF580, (0x01<<24)|0x0AAAA1, (0x04<<24)|0x77F784}, // channel 060
++ {64, (0x00<<24)|0x0FF590, (0x01<<24)|0x155551, (0x04<<24)|0x77F784}, // channel 064
++ {100, (0x00<<24)|0x0FF5C0, (0x01<<24)|0x155551, (0x04<<24)|0x77F784}, // channel 100
++ {104, (0x00<<24)|0x0FF5C0, (0x01<<24)|0x000001, (0x04<<24)|0x67F784}, // channel 104
++ {108, (0x00<<24)|0x0FF5C0, (0x01<<24)|0x0AAAA1, (0x04<<24)|0x77F784}, // channel 108
++ {112, (0x00<<24)|0x0FF5D0, (0x01<<24)|0x155551, (0x04<<24)|0x77F784}, // channel 112
++ {116, (0x00<<24)|0x0FF5D0, (0x01<<24)|0x000001, (0x04<<24)|0x67F784}, // channel 116
++ {120, (0x00<<24)|0x0FF5D0, (0x01<<24)|0x0AAAA1, (0x04<<24)|0x77F784}, // channel 120
++ {124, (0x00<<24)|0x0FF5E0, (0x01<<24)|0x155551, (0x04<<24)|0x77F784}, // channel 124
++ {128, (0x00<<24)|0x0FF5E0, (0x01<<24)|0x000001, (0x04<<24)|0x67F784}, // channel 128
++ {132, (0x00<<24)|0x0FF5E0, (0x01<<24)|0x0AAAA1, (0x04<<24)|0x77F784}, // channel 132
++ {136, (0x00<<24)|0x0FF5F0, (0x01<<24)|0x155551, (0x04<<24)|0x77F784}, // channel 136
++ {140, (0x00<<24)|0x0FF5F0, (0x01<<24)|0x000001, (0x04<<24)|0x67F784}, // channel 140
++ {149, (0x00<<24)|0x0FF600, (0x01<<24)|0x180001, (0x04<<24)|0x77F784}, // channel 149
++ {153, (0x00<<24)|0x0FF600, (0x01<<24)|0x02AAA1, (0x04<<24)|0x77F784}, // channel 153
++ {157, (0x00<<24)|0x0FF600, (0x01<<24)|0x0D5551, (0x04<<24)|0x77F784}, // channel 157
++ {161, (0x00<<24)|0x0FF610, (0x01<<24)|0x180001, (0x04<<24)|0x77F784}, // channel 161
++ {165, (0x00<<24)|0x0FF610, (0x01<<24)|0x02AAA1, (0x04<<24)|0x77F784} // channel 165
++};
++
++//; RF Calibration <=== Register 0x0F
++//0x0F 0x1ABA8F; start from 2.4Ghz default state
++//0x0F 0x9ABA8F; TXDC compensation
++//0x0F 0x3ABA8F; RXFIL adjustment
++//0x0F 0x1ABA8F; restore 2.4Ghz default state
++
++//;TXVGA Mapping Table <=== Register 0x0B
++u32 al7230_txvga_data[][2] =
++{
++ {0x08040B, 0}, //TXVGA=0;
++ {0x08041B, 1}, //TXVGA=1;
++ {0x08042B, 2}, //TXVGA=2;
++ {0x08043B, 3}, //TXVGA=3;
++ {0x08044B, 4}, //TXVGA=4;
++ {0x08045B, 5}, //TXVGA=5;
++ {0x08046B, 6}, //TXVGA=6;
++ {0x08047B, 7}, //TXVGA=7;
++ {0x08048B, 8}, //TXVGA=8;
++ {0x08049B, 9}, //TXVGA=9;
++ {0x0804AB, 10}, //TXVGA=10;
++ {0x0804BB, 11}, //TXVGA=11;
++ {0x0804CB, 12}, //TXVGA=12;
++ {0x0804DB, 13}, //TXVGA=13;
++ {0x0804EB, 14}, //TXVGA=14;
++ {0x0804FB, 15}, //TXVGA=15;
++ {0x08050B, 16}, //TXVGA=16;
++ {0x08051B, 17}, //TXVGA=17;
++ {0x08052B, 18}, //TXVGA=18;
++ {0x08053B, 19}, //TXVGA=19;
++ {0x08054B, 20}, //TXVGA=20;
++ {0x08055B, 21}, //TXVGA=21;
++ {0x08056B, 22}, //TXVGA=22;
++ {0x08057B, 23}, //TXVGA=23;
++ {0x08058B, 24}, //TXVGA=24;
++ {0x08059B, 25}, //TXVGA=25;
++ {0x0805AB, 26}, //TXVGA=26;
++ {0x0805BB, 27}, //TXVGA=27;
++ {0x0805CB, 28}, //TXVGA=28;
++ {0x0805DB, 29}, //TXVGA=29;
++ {0x0805EB, 30}, //TXVGA=30;
++ {0x0805FB, 31}, //TXVGA=31;
++ {0x08060B, 32}, //TXVGA=32;
++ {0x08061B, 33}, //TXVGA=33;
++ {0x08062B, 34}, //TXVGA=34;
++ {0x08063B, 35}, //TXVGA=35;
++ {0x08064B, 36}, //TXVGA=36;
++ {0x08065B, 37}, //TXVGA=37;
++ {0x08066B, 38}, //TXVGA=38;
++ {0x08067B, 39}, //TXVGA=39;
++ {0x08068B, 40}, //TXVGA=40;
++ {0x08069B, 41}, //TXVGA=41;
++ {0x0806AB, 42}, //TXVGA=42;
++ {0x0806BB, 43}, //TXVGA=43;
++ {0x0806CB, 44}, //TXVGA=44;
++ {0x0806DB, 45}, //TXVGA=45;
++ {0x0806EB, 46}, //TXVGA=46;
++ {0x0806FB, 47}, //TXVGA=47;
++ {0x08070B, 48}, //TXVGA=48;
++ {0x08071B, 49}, //TXVGA=49;
++ {0x08072B, 50}, //TXVGA=50;
++ {0x08073B, 51}, //TXVGA=51;
++ {0x08074B, 52}, //TXVGA=52;
++ {0x08075B, 53}, //TXVGA=53;
++ {0x08076B, 54}, //TXVGA=54;
++ {0x08077B, 55}, //TXVGA=55;
++ {0x08078B, 56}, //TXVGA=56;
++ {0x08079B, 57}, //TXVGA=57;
++ {0x0807AB, 58}, //TXVGA=58;
++ {0x0807BB, 59}, //TXVGA=59;
++ {0x0807CB, 60}, //TXVGA=60;
++ {0x0807DB, 61}, //TXVGA=61;
++ {0x0807EB, 62}, //TXVGA=62;
++ {0x0807FB, 63}, //TXVGA=63;
++};
++//--------------------------------
++
++
++//; W89RF242 RFIC SPI programming initial data
++//; Winbond WLAN 11g RFIC BB-SPI register -- version FA5976A rev 1.3b
++//; Update Date: Ocotber 3, 2005 by PP10 Hsiang-Te Ho
++//;
++//; Version 1.3b revision items: (Oct. 1, 2005 by HTHo) for FA5976A
++u32 w89rf242_rf_data[] =
++{
++ (0x00<<24)|0xF86100, // 20060721 0xF86100, //; 3E184; MODA (0x00) -- Normal mode ; calibration off
++ (0x01<<24)|0xEFFFC2, //; 3BFFF; MODB (0x01) -- turn off RSSI, and other circuits are turned on
++ (0x02<<24)|0x102504, //; 04094; FSET (0x02) -- default 20MHz crystal ; Icmp=1.5mA
++ (0x03<<24)|0x026286, //; 0098A; FCHN (0x03) -- default CH7, 2442MHz
++ (0x04<<24)|0x000208, // 20060612.1.a 0x0002C8, // 20050818 // 20050816 0x000388
++ //; 02008; FCAL (0x04) -- XTAL Freq Trim=001000 (socket board#1); FA5976AYG_v1.3C
++ (0x05<<24)|0x24C60A, // 20060612.1.a 0x24C58A, // 941003 0x24C48A, // 20050818.2 0x24848A, // 20050818 // 20050816 0x24C48A
++ //; 09316; GANA (0x05) -- TX VGA default (TXVGA=0x18(12)) & TXGPK=110 ; FA5976A_1.3D
++ (0x06<<24)|0x3432CC, // 941003 0x26C34C, // 20050818 0x06B40C
++ //; 0D0CB; GANB (0x06) -- RXDC(DC offset) on; LNA=11; RXVGA=001011(11) ; RXFLSW=11(010001); RXGPK=00; RXGCF=00; -50dBm input
++ (0x07<<24)|0x0C68CE, // 20050818.2 0x0C66CE, // 20050818 // 20050816 0x0C68CE
++ //; 031A3; FILT (0x07) -- TX/RX filter with auto-tuning; TFLBW=011; RFLBW=100
++ (0x08<<24)|0x100010, //; 04000; TCAL (0x08) -- //for LO
++ (0x09<<24)|0x004012, // 20060612.1.a 0x6E4012, // 0x004012,
++ //; 1B900; RCALA (0x09) -- FASTS=11; HPDE=01 (100nsec); SEHP=1 (select B0 pin=RXHP); RXHP=1 (Turn on RXHP function)(FA5976A_1.3C)
++ (0x0A<<24)|0x704014, //; 1C100; RCALB (0x0A)
++ (0x0B<<24)|0x18BDD6, // 941003 0x1805D6, // 20050818.2 0x1801D6, // 20050818 // 20050816 0x1805D6
++ //; 062F7; IQCAL (0x0B) -- Turn on LO phase tuner=0111 & RX-LO phase = 0111; FA5976A_1.3B (2005/09/29)
++ (0x0C<<24)|0x575558, // 20050818.2 0x555558, // 20050818 // 20050816 0x575558
++ //; 15D55 ; IBSA (0x0C) -- IFPre =11 ; TC5376A_v1.3A for corner
++ (0x0D<<24)|0x55545A, // 20060612.1.a 0x55555A,
++ //; 15555 ; IBSB (0x0D)
++ (0x0E<<24)|0x5557DC, // 20060612.1.a 0x55555C, // 941003 0x5557DC,
++ //; 1555F ; IBSC (0x0E) -- IRLNA & IRLNB (PTAT & Const current)=01/01; FA5976B_1.3F (2005/11/25)
++ (0x10<<24)|0x000C20, // 941003 0x000020, // 20050818
++ //; 00030 ; TMODA (0x10) -- LNA_gain_step=0011 ; LNA=15/16dB
++ (0x11<<24)|0x0C0022, // 941003 0x030022 // 20050818.2 0x030022 // 20050818 // 20050816 0x0C0022
++ //; 03000 ; TMODB (0x11) -- Turn ON RX-Q path Test Switch; To improve IQ path group delay (FA5976A_1.3C)
++ (0x12<<24)|0x000024 // 20060612.1.a 0x001824 // 941003 add
++ //; TMODC (0x12) -- Turn OFF Tempearure sensor
++};
++
++u32 w89rf242_channel_data_24[][2] =
++{
++ {(0x03<<24)|0x025B06, (0x04<<24)|0x080408}, // channe1 01
++ {(0x03<<24)|0x025C46, (0x04<<24)|0x080408}, // channe1 02
++ {(0x03<<24)|0x025D86, (0x04<<24)|0x080408}, // channe1 03
++ {(0x03<<24)|0x025EC6, (0x04<<24)|0x080408}, // channe1 04
++ {(0x03<<24)|0x026006, (0x04<<24)|0x080408}, // channe1 05
++ {(0x03<<24)|0x026146, (0x04<<24)|0x080408}, // channe1 06
++ {(0x03<<24)|0x026286, (0x04<<24)|0x080408}, // channe1 07
++ {(0x03<<24)|0x0263C6, (0x04<<24)|0x080408}, // channe1 08
++ {(0x03<<24)|0x026506, (0x04<<24)|0x080408}, // channe1 09
++ {(0x03<<24)|0x026646, (0x04<<24)|0x080408}, // channe1 10
++ {(0x03<<24)|0x026786, (0x04<<24)|0x080408}, // channe1 11
++ {(0x03<<24)|0x0268C6, (0x04<<24)|0x080408}, // channe1 12
++ {(0x03<<24)|0x026A06, (0x04<<24)|0x080408}, // channe1 13
++ {(0x03<<24)|0x026D06, (0x04<<24)|0x080408} // channe1 14
++};
++
++u32 w89rf242_power_data_24[] = {(0x05<<24)|0x24C48A, (0x05<<24)|0x24C48A, (0x05<<24)|0x24C48A};
++
++// 20060315.6 Enlarge for new scale
++// 20060316.6 20060619.2.a add mapping array
++u32 w89rf242_txvga_old_mapping[][2] =
++{
++ {0, 0} , // New <-> Old
++ {1, 1} ,
++ {2, 2} ,
++ {3, 3} ,
++ {4, 4} ,
++ {6, 5} ,
++ {8, 6 },
++ {10, 7 },
++ {12, 8 },
++ {14, 9 },
++ {16, 10},
++ {18, 11},
++ {20, 12},
++ {22, 13},
++ {24, 14},
++ {26, 15},
++ {28, 16},
++ {30, 17},
++ {32, 18},
++ {34, 19},
++
++
++};
++
++// 20060619.3 modify from Bruce's mail
++u32 w89rf242_txvga_data[][5] =
++{
++ //low gain mode
++ { (0x05<<24)|0x24C00A, 0, 0x00292315, 0x0800FEFF, 0x52523131 },// ; min gain
++ { (0x05<<24)|0x24C80A, 1, 0x00292315, 0x0800FEFF, 0x52523131 },
++ { (0x05<<24)|0x24C04A, 2, 0x00292315, 0x0800FEFF, 0x52523131 },// (default) +14dBm (ANT)
++ { (0x05<<24)|0x24C84A, 3, 0x00292315, 0x0800FEFF, 0x52523131 },
++
++ //TXVGA=0x10
++ { (0x05<<24)|0x24C40A, 4, 0x00292315, 0x0800FEFF, 0x60603838 },
++ { (0x05<<24)|0x24C40A, 5, 0x00262114, 0x0700FEFF, 0x65653B3B },
++
++ //TXVGA=0x11
++ { (0x05<<24)|0x24C44A, 6, 0x00241F13, 0x0700FFFF, 0x58583333 },
++ { (0x05<<24)|0x24C44A, 7, 0x00292315, 0x0800FEFF, 0x5E5E3737 },
++
++ //TXVGA=0x12
++ { (0x05<<24)|0x24C48A, 8, 0x00262114, 0x0700FEFF, 0x53533030 },
++ { (0x05<<24)|0x24C48A, 9, 0x00241F13, 0x0700FFFF, 0x59593434 },
++
++ //TXVGA=0x13
++ { (0x05<<24)|0x24C4CA, 10, 0x00292315, 0x0800FEFF, 0x52523030 },
++ { (0x05<<24)|0x24C4CA, 11, 0x00262114, 0x0700FEFF, 0x56563232 },
++
++ //TXVGA=0x14
++ { (0x05<<24)|0x24C50A, 12, 0x00292315, 0x0800FEFF, 0x54543131 },
++ { (0x05<<24)|0x24C50A, 13, 0x00262114, 0x0700FEFF, 0x58583434 },
++
++ //TXVGA=0x15
++ { (0x05<<24)|0x24C54A, 14, 0x00292315, 0x0800FEFF, 0x54543131 },
++ { (0x05<<24)|0x24C54A, 15, 0x00262114, 0x0700FEFF, 0x59593434 },
++
++ //TXVGA=0x16
++ { (0x05<<24)|0x24C58A, 16, 0x00292315, 0x0800FEFF, 0x55553131 },
++ { (0x05<<24)|0x24C58A, 17, 0x00292315, 0x0800FEFF, 0x5B5B3535 },
++
++ //TXVGA=0x17
++ { (0x05<<24)|0x24C5CA, 18, 0x00262114, 0x0700FEFF, 0x51512F2F },
++ { (0x05<<24)|0x24C5CA, 19, 0x00241F13, 0x0700FFFF, 0x55553131 },
++
++ //TXVGA=0x18
++ { (0x05<<24)|0x24C60A, 20, 0x00292315, 0x0800FEFF, 0x4F4F2E2E },
++ { (0x05<<24)|0x24C60A, 21, 0x00262114, 0x0700FEFF, 0x53533030 },
++
++ //TXVGA=0x19
++ { (0x05<<24)|0x24C64A, 22, 0x00292315, 0x0800FEFF, 0x4E4E2D2D },
++ { (0x05<<24)|0x24C64A, 23, 0x00262114, 0x0700FEFF, 0x53533030 },
++
++ //TXVGA=0x1A
++ { (0x05<<24)|0x24C68A, 24, 0x00292315, 0x0800FEFF, 0x50502E2E },
++ { (0x05<<24)|0x24C68A, 25, 0x00262114, 0x0700FEFF, 0x55553131 },
++
++ //TXVGA=0x1B
++ { (0x05<<24)|0x24C6CA, 26, 0x00262114, 0x0700FEFF, 0x53533030 },
++ { (0x05<<24)|0x24C6CA, 27, 0x00292315, 0x0800FEFF, 0x5A5A3434 },
++
++ //TXVGA=0x1C
++ { (0x05<<24)|0x24C70A, 28, 0x00292315, 0x0800FEFF, 0x55553131 },
++ { (0x05<<24)|0x24C70A, 29, 0x00292315, 0x0800FEFF, 0x5D5D3636 },
++
++ //TXVGA=0x1D
++ { (0x05<<24)|0x24C74A, 30, 0x00292315, 0x0800FEFF, 0x5F5F3737 },
++ { (0x05<<24)|0x24C74A, 31, 0x00262114, 0x0700FEFF, 0x65653B3B },
++
++ //TXVGA=0x1E
++ { (0x05<<24)|0x24C78A, 32, 0x00292315, 0x0800FEFF, 0x66663B3B },
++ { (0x05<<24)|0x24C78A, 33, 0x00262114, 0x0700FEFF, 0x70704141 },
++
++ //TXVGA=0x1F
++ { (0x05<<24)|0x24C7CA, 34, 0x00292315, 0x0800FEFF, 0x72724242 }
++};
++
++///////////////////////////////////////////////////////////////////////////////////////////////////
++///////////////////////////////////////////////////////////////////////////////////////////////////
++///////////////////////////////////////////////////////////////////////////////////////////////////
++
++
++
++//=============================================================================================================
++// Uxx_ReadEthernetAddress --
++//
++// Routine Description:
++// Reads in the Ethernet address from the IC.
++//
++// Arguments:
++// pHwData - The pHwData structure
++//
++// Return Value:
++//
++// The address is stored in EthernetIDAddr.
++//=============================================================================================================
++void
++Uxx_ReadEthernetAddress( phw_data_t pHwData )
++{
++ u32 ltmp;
++
++ // Reading Ethernet address from EEPROM and set into hardware due to MAC address maybe change.
++ // Only unplug and plug again can make hardware read EEPROM again. 20060727
++ Wb35Reg_WriteSync( pHwData, 0x03b4, 0x08000000 ); // Start EEPROM access + Read + address(0x0d)
++ Wb35Reg_ReadSync( pHwData, 0x03b4, <mp );
++ *(PUSHORT)pHwData->PermanentMacAddress = cpu_to_le16((u16)ltmp); //20060926 anson's endian
++ Wb35Reg_WriteSync( pHwData, 0x03b4, 0x08010000 ); // Start EEPROM access + Read + address(0x0d)
++ Wb35Reg_ReadSync( pHwData, 0x03b4, <mp );
++ *(PUSHORT)(pHwData->PermanentMacAddress + 2) = cpu_to_le16((u16)ltmp); //20060926 anson's endian
++ Wb35Reg_WriteSync( pHwData, 0x03b4, 0x08020000 ); // Start EEPROM access + Read + address(0x0d)
++ Wb35Reg_ReadSync( pHwData, 0x03b4, <mp );
++ *(PUSHORT)(pHwData->PermanentMacAddress + 4) = cpu_to_le16((u16)ltmp); //20060926 anson's endian
++ *(PUSHORT)(pHwData->PermanentMacAddress + 6) = 0;
++ Wb35Reg_WriteSync( pHwData, 0x03e8, cpu_to_le32(*(PULONG)pHwData->PermanentMacAddress) ); //20060926 anson's endian
++ Wb35Reg_WriteSync( pHwData, 0x03ec, cpu_to_le32(*(PULONG)(pHwData->PermanentMacAddress+4)) ); //20060926 anson's endian
++}
++
++
++//===============================================================================================================
++// CardGetMulticastBit --
++// Description:
++// For a given multicast address, returns the byte and bit in the card multicast registers that it hashes to.
++// Calls CardComputeCrc() to determine the CRC value.
++// Arguments:
++// Address - the address
++// Byte - the byte that it hashes to
++// Value - will have a 1 in the relevant bit
++// Return Value:
++// None.
++//==============================================================================================================
++void CardGetMulticastBit( u8 Address[ETH_LENGTH_OF_ADDRESS],
++ u8 *Byte, u8 *Value )
++{
++ u32 Crc;
++ u32 BitNumber;
++
++ // First compute the CRC.
++ Crc = CardComputeCrc(Address, ETH_LENGTH_OF_ADDRESS);
++
++ // The computed CRC is bit0~31 from left to right
++ //At first we should do right shift 25bits, and read 7bits by using '&', 2^7=128
++ BitNumber = (u32) ((Crc >> 26) & 0x3f);
++
++ *Byte = (u8) (BitNumber >> 3);// 900514 original (BitNumber / 8)
++ *Value = (u8) ((u8)1 << (BitNumber % 8));
++}
++
++void Uxx_power_on_procedure( phw_data_t pHwData )
++{
++ u32 ltmp, loop;
++
++ if( pHwData->phy_type <= RF_MAXIM_V1 )
++ Wb35Reg_WriteSync( pHwData, 0x03d4, 0xffffff38 );
++ else
++ {
++ Wb35Reg_WriteSync( pHwData, 0x03f4, 0xFF5807FF );// 20060721 For NEW IC 0xFF5807FF
++
++ // 20060511.1 Fix the following 4 steps for Rx of RF 2230 initial fail
++ Wb35Reg_WriteSync( pHwData, 0x03d4, 0x80 );// regulator on only
++ OS_SLEEP(10000); // Modify 20051221.1.b
++ Wb35Reg_WriteSync( pHwData, 0x03d4, 0xb8 );// REG_ON RF_RSTN on, and
++ OS_SLEEP(10000); // Modify 20051221.1.b
++
++ ltmp = 0x4968;
++ if( (pHwData->phy_type == RF_WB_242) ||
++ (RF_WB_242_1 == pHwData->phy_type) ) // 20060619.5 Add
++ ltmp = 0x4468;
++ Wb35Reg_WriteSync( pHwData, 0x03d0, ltmp );
++
++ Wb35Reg_WriteSync( pHwData, 0x03d4, 0xa0 );// PLL_PD REF_PD set to 0
++
++ OS_SLEEP(20000); // Modify 20051221.1.b
++ Wb35Reg_ReadSync( pHwData, 0x03d0, <mp );
++ loop = 500; // Wait for 5 second 20061101
++ while( !(ltmp & 0x20) && loop-- )
++ {
++ OS_SLEEP(10000); // Modify 20051221.1.b
++ if( !Wb35Reg_ReadSync( pHwData, 0x03d0, <mp ) )
++ break;
++ }
++
++ Wb35Reg_WriteSync( pHwData, 0x03d4, 0xe0 );// MLK_EN
++ }
++
++ Wb35Reg_WriteSync( pHwData, 0x03b0, 1 );// Reset hardware first
++ OS_SLEEP(10000); // Add this 20051221.1.b
++
++ // Set burst write delay
++ Wb35Reg_WriteSync( pHwData, 0x03f8, 0x7ff );
++}
++
++void Set_ChanIndep_RfData_al7230_24( phw_data_t pHwData, u32 *pltmp ,char number)
++{
++ u8 i;
++
++ for( i=0; i<number; i++ )
++ {
++ pHwData->phy_para[i] = al7230_rf_data_24[i];
++ pltmp[i] = (1 << 31) | (0 << 30) | (24 << 24) | (al7230_rf_data_24[i]&0xffffff);
++ }
++}
++
++void Set_ChanIndep_RfData_al7230_50( phw_data_t pHwData, u32 *pltmp, char number)
++{
++ u8 i;
++
++ for( i=0; i<number; i++ )
++ {
++ pHwData->phy_para[i] = al7230_rf_data_50[i];
++ pltmp[i] = (1 << 31) | (0 << 30) | (24 << 24) | (al7230_rf_data_50[i]&0xffffff);
++ }
++}
++
++
++//=============================================================================================================
++// RFSynthesizer_initial --
++//=============================================================================================================
++void
++RFSynthesizer_initial(phw_data_t pHwData)
++{
++ u32 altmp[32];
++ PULONG pltmp = altmp;
++ u32 ltmp;
++ u8 number=0x00; // The number of register vale
++ u8 i;
++
++ //
++ // bit[31] SPI Enable.
++ // 1=perform synthesizer program operation. This bit will
++ // cleared automatically after the operation is completed.
++ // bit[30] SPI R/W Control
++ // 0=write, 1=read
++ // bit[29:24] SPI Data Format Length
++ // bit[17:4 ] RF Data bits.
++ // bit[3 :0 ] RF address.
++ switch( pHwData->phy_type )
++ {
++ case RF_MAXIM_2825:
++ case RF_MAXIM_V1: // 11g Winbond 2nd BB(with Phy board (v1) + Maxim 331)
++ number = sizeof(max2825_rf_data)/sizeof(max2825_rf_data[0]);
++ for( i=0; i<number; i++ )
++ {
++ pHwData->phy_para[i] = max2825_rf_data[i];// Backup Rf parameter
++ pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2825_rf_data[i], 18);
++ }
++ break;
++
++ case RF_MAXIM_2827:
++ number = sizeof(max2827_rf_data)/sizeof(max2827_rf_data[0]);
++ for( i=0; i<number; i++ )
++ {
++ pHwData->phy_para[i] = max2827_rf_data[i];
++ pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2827_rf_data[i], 18);
++ }
++ break;
++
++ case RF_MAXIM_2828:
++ number = sizeof(max2828_rf_data)/sizeof(max2828_rf_data[0]);
++ for( i=0; i<number; i++ )
++ {
++ pHwData->phy_para[i] = max2828_rf_data[i];
++ pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2828_rf_data[i], 18);
++ }
++ break;
++
++ case RF_MAXIM_2829:
++ number = sizeof(max2829_rf_data)/sizeof(max2829_rf_data[0]);
++ for( i=0; i<number; i++ )
++ {
++ pHwData->phy_para[i] = max2829_rf_data[i];
++ pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2829_rf_data[i], 18);
++ }
++ break;
++
++ case RF_AIROHA_2230:
++ number = sizeof(al2230_rf_data)/sizeof(al2230_rf_data[0]);
++ for( i=0; i<number; i++ )
++ {
++ pHwData->phy_para[i] = al2230_rf_data[i];
++ pltmp[i] = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( al2230_rf_data[i], 20);
++ }
++ break;
++
++ case RF_AIROHA_2230S:
++ number = sizeof(al2230s_rf_data)/sizeof(al2230s_rf_data[0]);
++ for( i=0; i<number; i++ )
++ {
++ pHwData->phy_para[i] = al2230s_rf_data[i];
++ pltmp[i] = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( al2230s_rf_data[i], 20);
++ }
++ break;
++
++ case RF_AIROHA_7230:
++
++ //Start to fill RF parameters, PLL_ON should be pulled low.
++ Wb35Reg_WriteSync( pHwData, 0x03dc, 0x00000000 );
++#ifdef _PE_STATE_DUMP_
++ WBDEBUG(("* PLL_ON low\n"));
++#endif
++
++ number = sizeof(al7230_rf_data_24)/sizeof(al7230_rf_data_24[0]);
++ Set_ChanIndep_RfData_al7230_24(pHwData, pltmp, number);
++ break;
++
++ case RF_WB_242:
++ case RF_WB_242_1: // 20060619.5 Add
++ number = sizeof(w89rf242_rf_data)/sizeof(w89rf242_rf_data[0]);
++ for( i=0; i<number; i++ )
++ {
++ ltmp = w89rf242_rf_data[i];
++ if( i == 4 ) // Update the VCO trim from EEPROM
++ {
++ ltmp &= ~0xff0; // Mask bit4 ~bit11
++ ltmp |= pHwData->VCO_trim<<4;
++ }
++
++ pHwData->phy_para[i] = ltmp;
++ pltmp[i] = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( ltmp, 24);
++ }
++ break;
++ }
++
++ pHwData->phy_number = number;
++
++ // The 16 is the maximum capability of hardware. Here use 12
++ if( number > 12 ) {
++ //Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 12, NO_INCREMENT );
++ for( i=0; i<12; i++ ) // For Al2230
++ Wb35Reg_WriteSync( pHwData, 0x0864, pltmp[i] );
++
++ pltmp += 12;
++ number -= 12;
++ }
++
++ // Write to register. number must less and equal than 16
++ for( i=0; i<number; i++ )
++ Wb35Reg_WriteSync( pHwData, 0x864, pltmp[i] );
++
++ // 20060630.1 Calibration only 1 time
++ if( pHwData->CalOneTime )
++ return;
++ pHwData->CalOneTime = 1;
++
++ switch( pHwData->phy_type )
++ {
++ case RF_AIROHA_2230:
++
++ // 20060511.1 --- Modifying the follow step for Rx issue-----------------
++ ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( (0x07<<20)|0xE168E, 20);
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++ OS_SLEEP(10000);
++ ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( al2230_rf_data[7], 20);
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++ OS_SLEEP(10000);
++
++ case RF_AIROHA_2230S: // 20060420 Add this
++
++ // 20060511.1 --- Modifying the follow step for Rx issue-----------------
++ Wb35Reg_WriteSync( pHwData, 0x03d4, 0x80 );// regulator on only
++ OS_SLEEP(10000); // Modify 20051221.1.b
++
++ Wb35Reg_WriteSync( pHwData, 0x03d4, 0xa0 );// PLL_PD REF_PD set to 0
++ OS_SLEEP(10000); // Modify 20051221.1.b
++
++ Wb35Reg_WriteSync( pHwData, 0x03d4, 0xe0 );// MLK_EN
++ Wb35Reg_WriteSync( pHwData, 0x03b0, 1 );// Reset hardware first
++ OS_SLEEP(10000); // Add this 20051221.1.b
++ //------------------------------------------------------------------------
++
++ // The follow code doesn't use the burst-write mode
++ //phy_set_rf_data(phw_data, 0x0F, (0x0F<<20) | 0xF01A0); //Raise Initial Setting
++ ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( (0x0F<<20) | 0xF01A0, 20);
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++
++ ltmp = pHwData->Wb35Reg.BB5C & 0xfffff000;
++ Wb35Reg_WriteSync( pHwData, 0x105c, ltmp );
++ pHwData->Wb35Reg.BB50 |= 0x13;//(MASK_IQCAL_MODE|MASK_CALIB_START);//20060315.1 modify
++ Wb35Reg_WriteSync( pHwData, 0x1050, pHwData->Wb35Reg.BB50);
++ OS_SLEEP(5000);
++
++ //phy_set_rf_data(phw_data, 0x0F, (0x0F<<20) | 0xF01B0); //Activate Filter Cal.
++ ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( (0x0F<<20) | 0xF01B0, 20);
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++ OS_SLEEP(5000);
++
++ //phy_set_rf_data(phw_data, 0x0F, (0x0F<<20) | 0xF01e0); //Activate TX DCC
++ ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( (0x0F<<20) | 0xF01E0, 20);
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++ OS_SLEEP(5000);
++
++ //phy_set_rf_data(phw_data, 0x0F, (0x0F<<20) | 0xF01A0); //Resotre Initial Setting
++ ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( (0x0F<<20) | 0xF01A0, 20);
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++
++// //Force TXI(Q)P(N) to normal control
++ Wb35Reg_WriteSync( pHwData, 0x105c, pHwData->Wb35Reg.BB5C );
++ pHwData->Wb35Reg.BB50 &= ~0x13;//(MASK_IQCAL_MODE|MASK_CALIB_START);
++ Wb35Reg_WriteSync( pHwData, 0x1050, pHwData->Wb35Reg.BB50);
++ break;
++
++ case RF_AIROHA_7230:
++
++ //RF parameters have filled completely, PLL_ON should be
++ //pulled high
++ Wb35Reg_WriteSync( pHwData, 0x03dc, 0x00000080 );
++ #ifdef _PE_STATE_DUMP_
++ WBDEBUG(("* PLL_ON high\n"));
++ #endif
++
++ //2.4GHz
++ //ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x1ABA8F;
++ //Wb35Reg_WriteSync pHwData, 0x0864, ltmp );
++ //OS_SLEEP(1000); // Sleep 1 ms
++ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x9ABA8F;
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++ OS_SLEEP(5000);
++ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x3ABA8F;
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++ OS_SLEEP(5000);
++ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x1ABA8F;
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++ OS_SLEEP(5000);
++
++ //5GHz
++ Wb35Reg_WriteSync( pHwData, 0x03dc, 0x00000000 );
++ #ifdef _PE_STATE_DUMP_
++ WBDEBUG(("* PLL_ON low\n"));
++ #endif
++
++ number = sizeof(al7230_rf_data_50)/sizeof(al7230_rf_data_50[0]);
++ Set_ChanIndep_RfData_al7230_50(pHwData, pltmp, number);
++ // Write to register. number must less and equal than 16
++ for( i=0; i<number; i++ )
++ Wb35Reg_WriteSync( pHwData, 0x0864, pltmp[i] );
++ OS_SLEEP(5000);
++
++ Wb35Reg_WriteSync( pHwData, 0x03dc, 0x00000080 );
++ #ifdef _PE_STATE_DUMP_
++ WBDEBUG(("* PLL_ON high\n"));
++ #endif
++
++ //ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x12BACF;
++ //Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x9ABA8F;
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++ OS_SLEEP(5000);
++ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x3ABA8F;
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++ OS_SLEEP(5000);
++ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x12BACF;
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++ OS_SLEEP(5000);
++
++ //Wb35Reg_WriteSync( pHwData, 0x03dc, 0x00000080 );
++ //WBDEBUG(("* PLL_ON high\n"));
++ break;
++
++ case RF_WB_242:
++ case RF_WB_242_1: // 20060619.5 Add
++
++ //
++ // ; Version 1.3B revision items: for FA5976A , October 3, 2005 by HTHo
++ //
++ ltmp = pHwData->Wb35Reg.BB5C & 0xfffff000;
++ Wb35Reg_WriteSync( pHwData, 0x105c, ltmp );
++ Wb35Reg_WriteSync( pHwData, 0x1058, 0 );
++ pHwData->Wb35Reg.BB50 |= 0x3;//(MASK_IQCAL_MODE|MASK_CALIB_START);//20060630
++ Wb35Reg_WriteSync( pHwData, 0x1050, pHwData->Wb35Reg.BB50);
++
++ //----- Calibration (1). VCO frequency calibration
++ //Calibration (1a.0). Synthesizer reset (HTHo corrected 2005/05/10)
++ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x0F<<24) | 0x00101E, 24);
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++ OS_SLEEP( 5000 ); // Sleep 5ms
++ //Calibration (1a). VCO frequency calibration mode ; waiting 2msec VCO calibration time
++ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFE69c0, 24);
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++ OS_SLEEP( 2000 ); // Sleep 2ms
++
++ //----- Calibration (2). TX baseband Gm-C filter auto-tuning
++ //Calibration (2a). turn off ENCAL signal
++ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xF8EBC0, 24);
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++ //Calibration (2b.0). TX filter auto-tuning BW: TFLBW=101 (TC5376A default)
++ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x07<<24) | 0x0C68CE, 24);
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++ //Calibration (2b). send TX reset signal (HTHo corrected May 10, 2005)
++ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x0F<<24) | 0x00201E, 24);
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++ //Calibration (2c). turn-on TX Gm-C filter auto-tuning
++ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFCEBC0, 24);
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++ OS_SLEEP( 150 ); // Sleep 150 us
++ //turn off ENCAL signal
++ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xF8EBC0, 24);
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++
++ //----- Calibration (3). RX baseband Gm-C filter auto-tuning
++ //Calibration (3a). turn off ENCAL signal
++ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFAEDC0, 24);
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++ //Calibration (3b.0). RX filter auto-tuning BW: RFLBW=100 (TC5376A+corner default; July 26, 2005)
++ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x07<<24) | 0x0C68CE, 24);
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++ //Calibration (3b). send RX reset signal (HTHo corrected May 10, 2005)
++ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x0F<<24) | 0x00401E, 24);
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++ //Calibration (3c). turn-on RX Gm-C filter auto-tuning
++ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFEEDC0, 24);
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++ OS_SLEEP( 150 ); // Sleep 150 us
++ //Calibration (3e). turn off ENCAL signal
++ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFAEDC0, 24);
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++
++ //----- Calibration (4). TX LO leakage calibration
++ //Calibration (4a). TX LO leakage calibration
++ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFD6BC0, 24);
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++ OS_SLEEP( 150 ); // Sleep 150 us
++
++ //----- Calibration (5). RX DC offset calibration
++ //Calibration (5a). turn off ENCAL signal and set to RX SW DC caliration mode
++ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFAEDC0, 24);
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++ //Calibration (5b). turn off AGC servo-loop & RSSI
++ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x01<<24) | 0xEBFFC2, 24);
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++
++ //; for LNA=11 --------
++ //Calibration (5c-h). RX DC offset current bias ON; & LNA=11; RXVGA=111111
++ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x06<<24) | 0x343FCC, 24);
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++ //Calibration (5d). turn on RX DC offset cal function; and waiting 2 msec cal time
++ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFF6DC0, 24);
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++ OS_SLEEP(2000); // Sleep 2ms
++ //Calibration (5f). turn off ENCAL signal
++ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFAEDC0, 24);
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++
++ //; for LNA=10 --------
++ //Calibration (5c-m). RX DC offset current bias ON; & LNA=10; RXVGA=111111
++ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x06<<24) | 0x342FCC, 24);
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++ //Calibration (5d). turn on RX DC offset cal function; and waiting 2 msec cal time
++ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFF6DC0, 24);
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++ OS_SLEEP(2000); // Sleep 2ms
++ //Calibration (5f). turn off ENCAL signal
++ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFAEDC0, 24);
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++
++ //; for LNA=01 --------
++ //Calibration (5c-m). RX DC offset current bias ON; & LNA=01; RXVGA=111111
++ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x06<<24) | 0x341FCC, 24);
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++ //Calibration (5d). turn on RX DC offset cal function; and waiting 2 msec cal time
++ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFF6DC0, 24);
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++ OS_SLEEP(2000); // Sleep 2ms
++ //Calibration (5f). turn off ENCAL signal
++ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFAEDC0, 24);
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++
++ //; for LNA=00 --------
++ //Calibration (5c-l). RX DC offset current bias ON; & LNA=00; RXVGA=111111
++ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x06<<24) | 0x340FCC, 24);
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++ //Calibration (5d). turn on RX DC offset cal function; and waiting 2 msec cal time
++ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFF6DC0, 24);
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++ OS_SLEEP(2000); // Sleep 2ms
++ //Calibration (5f). turn off ENCAL signal
++ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFAEDC0, 24);
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++ //Calibration (5g). turn on AGC servo-loop
++ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x01<<24) | 0xEFFFC2, 24);
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++
++ //; ----- Calibration (7). Switch RF chip to normal mode
++ //0x00 0xF86100 ; 3E184 ; Switch RF chip to normal mode
++// OS_SLEEP(10000); // @@ 20060721
++ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xF86100, 24);
++ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
++ OS_SLEEP(5000); // Sleep 5 ms
++
++// //write back
++// Wb35Reg_WriteSync( pHwData, 0x105c, pHwData->Wb35Reg.BB5C );
++// pHwData->Wb35Reg.BB50 &= ~0x13;//(MASK_IQCAL_MODE|MASK_CALIB_START); // 20060315.1 fix
++// Wb35Reg_WriteSync( pHwData, 0x1050, pHwData->Wb35Reg.BB50);
++// OS_SLEEP(1000); // Sleep 1 ms
++ break;
++ }
++}
++
++void BBProcessor_AL7230_2400( phw_data_t pHwData)
++{
++ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
++ u32 pltmp[12];
++
++ pltmp[0] = 0x16A8337A; // 0x16a5215f; // 0x1000 AGC_Ctrl1
++ pltmp[1] = 0x9AFF9AA6; // 0x9aff9ca6; // 0x1004 AGC_Ctrl2
++ pltmp[2] = 0x55D00A04; // 0x55d00a04; // 0x1008 AGC_Ctrl3
++ pltmp[3] = 0xFFF72031; // 0xFfFf2138; // 0x100c AGC_Ctrl4
++ pWb35Reg->BB0C = 0xFFF72031;
++ pltmp[4] = 0x0FacDCC5; // 0x1010 AGC_Ctrl5 // 20050927 0x0FacDCB7
++ pltmp[5] = 0x00CAA333; // 0x00eaa333; // 0x1014 AGC_Ctrl6
++ pltmp[6] = 0xF2211111; // 0x11111111; // 0x1018 AGC_Ctrl7
++ pltmp[7] = 0x0FA3F0ED; // 0x101c AGC_Ctrl8
++ pltmp[8] = 0x06443440; // 0x1020 AGC_Ctrl9
++ pltmp[9] = 0xA8002A79; // 0xa9002A79; // 0x1024 AGC_Ctrl10
++ pltmp[10] = 0x40000528; // 20050927 0x40000228
++ pltmp[11] = 0x232D7F30; // 0x23457f30;// 0x102c A_ACQ_Ctrl
++ pWb35Reg->BB2C = 0x232D7F30;
++ Wb35Reg_BurstWrite( pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT );
++
++ pltmp[0] = 0x00002c54; // 0x1030 B_ACQ_Ctrl
++ pWb35Reg->BB30 = 0x00002c54;
++ pltmp[1] = 0x00C0D6C5; // 0x1034 A_TXRX_Ctrl
++ pltmp[2] = 0x5B2C8769; // 0x1038 B_TXRX_Ctrl
++ pltmp[3] = 0x00000000; // 0x103c 11a TX LS filter
++ pWb35Reg->BB3C = 0x00000000;
++ pltmp[4] = 0x00003F29; // 0x1040 11a TX LS filter
++ pltmp[5] = 0x0EFEFBFE; // 0x1044 11a TX LS filter
++ pltmp[6] = 0x00332C1B; // 0x00453B24; // 0x1048 11b TX RC filter
++ pltmp[7] = 0x0A00FEFF; // 0x0E00FEFF; // 0x104c 11b TX RC filter
++ pltmp[8] = 0x2B106208; // 0x1050 MODE_Ctrl
++ pWb35Reg->BB50 = 0x2B106208;
++ pltmp[9] = 0; // 0x1054
++ pWb35Reg->BB54 = 0x00000000;
++ pltmp[10] = 0x52524242; // 0x64645252; // 0x1058 IQ_Alpha
++ pWb35Reg->BB58 = 0x52524242;
++ pltmp[11] = 0xAA0AC000; // 0x105c DC_Cancel
++ Wb35Reg_BurstWrite( pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT );
++
++}
++
++void BBProcessor_AL7230_5000( phw_data_t pHwData)
++{
++ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
++ u32 pltmp[12];
++
++ pltmp[0] = 0x16AA6678; // 0x1000 AGC_Ctrl1
++ pltmp[1] = 0x9AFFA0B2; // 0x1004 AGC_Ctrl2
++ pltmp[2] = 0x55D00A04; // 0x1008 AGC_Ctrl3
++ pltmp[3] = 0xEFFF233E; // 0x100c AGC_Ctrl4
++ pWb35Reg->BB0C = 0xEFFF233E;
++ pltmp[4] = 0x0FacDCC5; // 0x1010 AGC_Ctrl5 // 20050927 0x0FacDCB7
++ pltmp[5] = 0x00CAA333; // 0x1014 AGC_Ctrl6
++ pltmp[6] = 0xF2432111; // 0x1018 AGC_Ctrl7
++ pltmp[7] = 0x0FA3F0ED; // 0x101c AGC_Ctrl8
++ pltmp[8] = 0x05C43440; // 0x1020 AGC_Ctrl9
++ pltmp[9] = 0x00002A79; // 0x1024 AGC_Ctrl10
++ pltmp[10] = 0x40000528; // 20050927 0x40000228
++ pltmp[11] = 0x232FDF30;// 0x102c A_ACQ_Ctrl
++ pWb35Reg->BB2C = 0x232FDF30;
++ Wb35Reg_BurstWrite( pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT );
++
++ pltmp[0] = 0x80002C7C; // 0x1030 B_ACQ_Ctrl
++ pltmp[1] = 0x00C0D6C5; // 0x1034 A_TXRX_Ctrl
++ pltmp[2] = 0x5B2C8769; // 0x1038 B_TXRX_Ctrl
++ pltmp[3] = 0x00000000; // 0x103c 11a TX LS filter
++ pWb35Reg->BB3C = 0x00000000;
++ pltmp[4] = 0x00003F29; // 0x1040 11a TX LS filter
++ pltmp[5] = 0x0EFEFBFE; // 0x1044 11a TX LS filter
++ pltmp[6] = 0x00332C1B; // 0x1048 11b TX RC filter
++ pltmp[7] = 0x0A00FEFF; // 0x104c 11b TX RC filter
++ pltmp[8] = 0x2B107208; // 0x1050 MODE_Ctrl
++ pWb35Reg->BB50 = 0x2B107208;
++ pltmp[9] = 0; // 0x1054
++ pWb35Reg->BB54 = 0x00000000;
++ pltmp[10] = 0x52524242; // 0x1058 IQ_Alpha
++ pWb35Reg->BB58 = 0x52524242;
++ pltmp[11] = 0xAA0AC000; // 0x105c DC_Cancel
++ Wb35Reg_BurstWrite( pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT );
++
++}
++
++//=============================================================================================================
++// BBProcessorPowerupInit --
++//
++// Description:
++// Initialize the Baseband processor.
++//
++// Arguments:
++// pHwData - Handle of the USB Device.
++//
++// Return values:
++// None.
++//=============================================================================================================
++void
++BBProcessor_initial( phw_data_t pHwData )
++{
++ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
++ u32 i, pltmp[12];
++
++ switch( pHwData->phy_type )
++ {
++ case RF_MAXIM_V1: // Initializng the Winbond 2nd BB(with Phy board (v1) + Maxim 331)
++
++ pltmp[0] = 0x16F47E77; // 0x1000 AGC_Ctrl1
++ pltmp[1] = 0x9AFFAEA4; // 0x1004 AGC_Ctrl2
++ pltmp[2] = 0x55D00A04; // 0x1008 AGC_Ctrl3
++ pltmp[3] = 0xEFFF1A34; // 0x100c AGC_Ctrl4
++ pWb35Reg->BB0C = 0xEFFF1A34;
++ pltmp[4] = 0x0FABE0B7; // 0x1010 AGC_Ctrl5
++ pltmp[5] = 0x00CAA332; // 0x1014 AGC_Ctrl6
++ pltmp[6] = 0xF6632111; // 0x1018 AGC_Ctrl7
++ pltmp[7] = 0x0FA3F0ED; // 0x101c AGC_Ctrl8
++ pltmp[8] = 0x04CC3640; // 0x1020 AGC_Ctrl9
++ pltmp[9] = 0x00002A79; // 0x1024 AGC_Ctrl10
++ pltmp[10] = (pHwData->phy_type==3) ? 0x40000a28 : 0x40000228; // 0x1028 MAXIM_331(b31=0) + WBRF_V1(b11=1) : MAXIM_331(b31=0) + WBRF_V2(b11=0)
++ pltmp[11] = 0x232FDF30; // 0x102c A_ACQ_Ctrl
++ pWb35Reg->BB2C = 0x232FDF30; //Modify for 33's 1.0.95.xxx version, antenna 1
++ Wb35Reg_BurstWrite( pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT );
++
++ pltmp[0] = 0x00002C54; // 0x1030 B_ACQ_Ctrl
++ pWb35Reg->BB30 = 0x00002C54;
++ pltmp[1] = 0x00C0D6C5; // 0x1034 A_TXRX_Ctrl
++ pltmp[2] = 0x5B6C8769; // 0x1038 B_TXRX_Ctrl
++ pltmp[3] = 0x00000000; // 0x103c 11a TX LS filter
++ pWb35Reg->BB3C = 0x00000000;
++ pltmp[4] = 0x00003F29; // 0x1040 11a TX LS filter
++ pltmp[5] = 0x0EFEFBFE; // 0x1044 11a TX LS filter
++ pltmp[6] = 0x00453B24; // 0x1048 11b TX RC filter
++ pltmp[7] = 0x0E00FEFF; // 0x104c 11b TX RC filter
++ pltmp[8] = 0x27106208; // 0x1050 MODE_Ctrl
++ pWb35Reg->BB50 = 0x27106208;
++ pltmp[9] = 0; // 0x1054
++ pWb35Reg->BB54 = 0x00000000;
++ pltmp[10] = 0x64646464; // 0x1058 IQ_Alpha
++ pWb35Reg->BB58 = 0x64646464;
++ pltmp[11] = 0xAA0AC000; // 0x105c DC_Cancel
++ Wb35Reg_BurstWrite( pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT );
++
++ Wb35Reg_Write( pHwData, 0x1070, 0x00000045 );
++ break;
++
++ //------------------------------------------------------------------
++ //[20040722 WK]
++ //Only for baseband version 2
++// case RF_MAXIM_317:
++ case RF_MAXIM_2825:
++ case RF_MAXIM_2827:
++ case RF_MAXIM_2828:
++
++ pltmp[0] = 0x16b47e77; // 0x1000 AGC_Ctrl1
++ pltmp[1] = 0x9affaea4; // 0x1004 AGC_Ctrl2
++ pltmp[2] = 0x55d00a04; // 0x1008 AGC_Ctrl3
++ pltmp[3] = 0xefff1a34; // 0x100c AGC_Ctrl4
++ pWb35Reg->BB0C = 0xefff1a34;
++ pltmp[4] = 0x0fabe0b7; // 0x1010 AGC_Ctrl5
++ pltmp[5] = 0x00caa332; // 0x1014 AGC_Ctrl6
++ pltmp[6] = 0xf6632111; // 0x1018 AGC_Ctrl7
++ pltmp[7] = 0x0FA3F0ED; // 0x101c AGC_Ctrl8
++ pltmp[8] = 0x04CC3640; // 0x1020 AGC_Ctrl9
++ pltmp[9] = 0x00002A79; // 0x1024 AGC_Ctrl10
++ pltmp[10] = 0x40000528; // 0x40000128; Modify for 33's 1.0.95
++ pltmp[11] = 0x232fdf30; // 0x102c A_ACQ_Ctrl
++ pWb35Reg->BB2C = 0x232fdf30; //Modify for 33's 1.0.95.xxx version, antenna 1
++ Wb35Reg_BurstWrite( pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT );
++
++ pltmp[0] = 0x00002C54; // 0x1030 B_ACQ_Ctrl
++ pWb35Reg->BB30 = 0x00002C54;
++ pltmp[1] = 0x00C0D6C5; // 0x1034 A_TXRX_Ctrl
++ pltmp[2] = 0x5B6C8769; // 0x1038 B_TXRX_Ctrl
++ pltmp[3] = 0x00000000; // 0x103c 11a TX LS filter
++ pWb35Reg->BB3C = 0x00000000;
++ pltmp[4] = 0x00003F29; // 0x1040 11a TX LS filter
++ pltmp[5] = 0x0EFEFBFE; // 0x1044 11a TX LS filter
++ pltmp[6] = 0x00453B24; // 0x1048 11b TX RC filter
++ pltmp[7] = 0x0D00FDFF; // 0x104c 11b TX RC filter
++ pltmp[8] = 0x27106208; // 0x1050 MODE_Ctrl
++ pWb35Reg->BB50 = 0x27106208;
++ pltmp[9] = 0; // 0x1054
++ pWb35Reg->BB54 = 0x00000000;
++ pltmp[10] = 0x64646464; // 0x1058 IQ_Alpha
++ pWb35Reg->BB58 = 0x64646464;
++ pltmp[11] = 0xAA28C000; // 0x105c DC_Cancel
++ Wb35Reg_BurstWrite( pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT );
++
++ Wb35Reg_Write( pHwData, 0x1070, 0x00000045 );
++ break;
++
++ case RF_MAXIM_2829:
++
++ pltmp[0] = 0x16b47e77; // 0x1000 AGC_Ctrl1
++ pltmp[1] = 0x9affaea4; // 0x1004 AGC_Ctrl2
++ pltmp[2] = 0x55d00a04; // 0x1008 AGC_Ctrl3
++ pltmp[3] = 0xf4ff1632; // 0xefff1a34; // 0x100c AGC_Ctrl4 Modify for 33's 1.0.95
++ pWb35Reg->BB0C = 0xf4ff1632; // 0xefff1a34; Modify for 33's 1.0.95
++ pltmp[4] = 0x0fabe0b7; // 0x1010 AGC_Ctrl5
++ pltmp[5] = 0x00caa332; // 0x1014 AGC_Ctrl6
++ pltmp[6] = 0xf8632112; // 0xf6632111; // 0x1018 AGC_Ctrl7 Modify for 33's 1.0.95
++ pltmp[7] = 0x0FA3F0ED; // 0x101c AGC_Ctrl8
++ pltmp[8] = 0x04CC3640; // 0x1020 AGC_Ctrl9
++ pltmp[9] = 0x00002A79; // 0x1024 AGC_Ctrl10
++ pltmp[10] = 0x40000528; // 0x40000128; modify for 33's 1.0.95
++ pltmp[11] = 0x232fdf30; // 0x102c A_ACQ_Ctrl
++ pWb35Reg->BB2C = 0x232fdf30; //Modify for 33's 1.0.95.xxx version, antenna 1
++ Wb35Reg_BurstWrite( pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT );
++
++ pltmp[0] = 0x00002C54; // 0x1030 B_ACQ_Ctrl
++ pWb35Reg->BB30 = 0x00002C54;
++ pltmp[1] = 0x00C0D6C5; // 0x1034 A_TXRX_Ctrl
++ pltmp[2] = 0x5b2c8769; // 0x5B6C8769; // 0x1038 B_TXRX_Ctrl Modify for 33's 1.0.95
++ pltmp[3] = 0x00000000; // 0x103c 11a TX LS filter
++ pWb35Reg->BB3C = 0x00000000;
++ pltmp[4] = 0x00003F29; // 0x1040 11a TX LS filter
++ pltmp[5] = 0x0EFEFBFE; // 0x1044 11a TX LS filter
++ pltmp[6] = 0x002c2617; // 0x00453B24; // 0x1048 11b TX RC filter Modify for 33's 1.0.95
++ pltmp[7] = 0x0800feff; // 0x0D00FDFF; // 0x104c 11b TX RC filter Modify for 33's 1.0.95
++ pltmp[8] = 0x27106208; // 0x1050 MODE_Ctrl
++ pWb35Reg->BB50 = 0x27106208;
++ pltmp[9] = 0; // 0x1054
++ pWb35Reg->BB54 = 0x00000000;
++ pltmp[10] = 0x64644a4a; // 0x64646464; // 0x1058 IQ_Alpha Modify for 33's 1.0.95
++ pWb35Reg->BB58 = 0x64646464;
++ pltmp[11] = 0xAA28C000; // 0x105c DC_Cancel
++ Wb35Reg_BurstWrite( pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT );
++
++ Wb35Reg_Write( pHwData, 0x1070, 0x00000045 );
++ break;
++
++ case RF_AIROHA_2230:
++
++ pltmp[0] = 0X16764A77; // 0x1000 AGC_Ctrl1 //0x16765A77
++ pltmp[1] = 0x9affafb2; // 0x1004 AGC_Ctrl2
++ pltmp[2] = 0x55d00a04; // 0x1008 AGC_Ctrl3
++ pltmp[3] = 0xFFFd203c; // 0xFFFb203a; // 0x100c AGC_Ctrl4 Modify for 33's 1.0.95.xxx version
++ pWb35Reg->BB0C = 0xFFFd203c;
++ pltmp[4] = 0X0FBFDCc5; // 0X0FBFDCA0; // 0x1010 AGC_Ctrl5 //0x0FB2E0B7 Modify for 33's 1.0.95.xxx version
++ pltmp[5] = 0x00caa332; // 0x00caa333; // 0x1014 AGC_Ctrl6 Modify for 33's 1.0.95.xxx version
++ pltmp[6] = 0XF6632111; // 0XF1632112; // 0x1018 AGC_Ctrl7 //0xf6632112 Modify for 33's 1.0.95.xxx version
++ pltmp[7] = 0x0FA3F0ED; // 0x101c AGC_Ctrl8
++ pltmp[8] = 0x04C43640; // 0x1020 AGC_Ctrl9
++ pltmp[9] = 0x00002A79; // 0x1024 AGC_Ctrl10
++ pltmp[10] = 0X40000528; //0x40000228
++ pltmp[11] = 0x232dfF30; // 0x232A9F30; // 0x102c A_ACQ_Ctrl //0x232a9730
++ pWb35Reg->BB2C = 0x232dfF30; //Modify for 33's 1.0.95.xxx version, antenna 1
++ Wb35Reg_BurstWrite( pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT );
++
++ pltmp[0] = 0x00002C54; // 0x1030 B_ACQ_Ctrl
++ pWb35Reg->BB30 = 0x00002C54;
++ pltmp[1] = 0x00C0D6C5; // 0x1034 A_TXRX_Ctrl
++ pltmp[2] = 0x5B2C8769; // 0x1038 B_TXRX_Ctrl //0x5B6C8769
++ pltmp[3] = 0x00000000; // 0x103c 11a TX LS filter
++ pWb35Reg->BB3C = 0x00000000;
++ pltmp[4] = 0x00003F29; // 0x1040 11a TX LS filter
++ pltmp[5] = 0x0EFEFBFE; // 0x1044 11a TX LS filter
++ pltmp[6] = BB48_DEFAULT_AL2230_11G; // 0x1048 11b TX RC filter 20060613.2
++ pWb35Reg->BB48 = BB48_DEFAULT_AL2230_11G; // 20051221 ch14 20060613.2
++ pltmp[7] = BB4C_DEFAULT_AL2230_11G; // 0x104c 11b TX RC filter 20060613.2
++ pWb35Reg->BB4C = BB4C_DEFAULT_AL2230_11G; // 20060613.1 20060613.2
++ pltmp[8] = 0x27106200; // 0x1050 MODE_Ctrl
++ pWb35Reg->BB50 = 0x27106200;
++ pltmp[9] = 0; // 0x1054
++ pWb35Reg->BB54 = 0x00000000;
++ pltmp[10] = 0x52524242; // 0x1058 IQ_Alpha
++ pWb35Reg->BB58 = 0x52524242;
++ pltmp[11] = 0xAA0AC000; // 0x105c DC_Cancel
++ Wb35Reg_BurstWrite( pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT );
++
++ Wb35Reg_Write( pHwData, 0x1070, 0x00000045 );
++ break;
++
++ case RF_AIROHA_2230S: // 20060420 Add this
++
++ pltmp[0] = 0X16764A77; // 0x1000 AGC_Ctrl1 //0x16765A77
++ pltmp[1] = 0x9affafb2; // 0x1004 AGC_Ctrl2
++ pltmp[2] = 0x55d00a04; // 0x1008 AGC_Ctrl3
++ pltmp[3] = 0xFFFd203c; // 0xFFFb203a; // 0x100c AGC_Ctrl4 Modify for 33's 1.0.95.xxx version
++ pWb35Reg->BB0C = 0xFFFd203c;
++ pltmp[4] = 0X0FBFDCc5; // 0X0FBFDCA0; // 0x1010 AGC_Ctrl5 //0x0FB2E0B7 Modify for 33's 1.0.95.xxx version
++ pltmp[5] = 0x00caa332; // 0x00caa333; // 0x1014 AGC_Ctrl6 Modify for 33's 1.0.95.xxx version
++ pltmp[6] = 0XF6632111; // 0XF1632112; // 0x1018 AGC_Ctrl7 //0xf6632112 Modify for 33's 1.0.95.xxx version
++ pltmp[7] = 0x0FA3F0ED; // 0x101c AGC_Ctrl8
++ pltmp[8] = 0x04C43640; // 0x1020 AGC_Ctrl9
++ pltmp[9] = 0x00002A79; // 0x1024 AGC_Ctrl10
++ pltmp[10] = 0X40000528; //0x40000228
++ pltmp[11] = 0x232dfF30; // 0x232A9F30; // 0x102c A_ACQ_Ctrl //0x232a9730
++ pWb35Reg->BB2C = 0x232dfF30; //Modify for 33's 1.0.95.xxx version, antenna 1
++ Wb35Reg_BurstWrite( pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT );
++
++ pltmp[0] = 0x00002C54; // 0x1030 B_ACQ_Ctrl
++ pWb35Reg->BB30 = 0x00002C54;
++ pltmp[1] = 0x00C0D6C5; // 0x1034 A_TXRX_Ctrl
++ pltmp[2] = 0x5B2C8769; // 0x1038 B_TXRX_Ctrl //0x5B6C8769
++ pltmp[3] = 0x00000000; // 0x103c 11a TX LS filter
++ pWb35Reg->BB3C = 0x00000000;
++ pltmp[4] = 0x00003F29; // 0x1040 11a TX LS filter
++ pltmp[5] = 0x0EFEFBFE; // 0x1044 11a TX LS filter
++ pltmp[6] = BB48_DEFAULT_AL2230_11G; // 0x1048 11b TX RC filter 20060613.2
++ pWb35Reg->BB48 = BB48_DEFAULT_AL2230_11G; // 20051221 ch14 20060613.2
++ pltmp[7] = BB4C_DEFAULT_AL2230_11G; // 0x104c 11b TX RC filter 20060613.2
++ pWb35Reg->BB4C = BB4C_DEFAULT_AL2230_11G; // 20060613.1
++ pltmp[8] = 0x27106200; // 0x1050 MODE_Ctrl
++ pWb35Reg->BB50 = 0x27106200;
++ pltmp[9] = 0; // 0x1054
++ pWb35Reg->BB54 = 0x00000000;
++ pltmp[10] = 0x52523232; // 20060419 0x52524242; // 0x1058 IQ_Alpha
++ pWb35Reg->BB58 = 0x52523232; // 20060419 0x52524242;
++ pltmp[11] = 0xAA0AC000; // 0x105c DC_Cancel
++ Wb35Reg_BurstWrite( pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT );
++
++ Wb35Reg_Write( pHwData, 0x1070, 0x00000045 );
++ break;
++
++ case RF_AIROHA_7230:
++/*
++ pltmp[0] = 0x16a84a77; // 0x1000 AGC_Ctrl1
++ pltmp[1] = 0x9affafb2; // 0x1004 AGC_Ctrl2
++ pltmp[2] = 0x55d00a04; // 0x1008 AGC_Ctrl3
++ pltmp[3] = 0xFFFb203a; // 0x100c AGC_Ctrl4
++ pWb35Reg->BB0c = 0xFFFb203a;
++ pltmp[4] = 0x0FBFDCB7; // 0x1010 AGC_Ctrl5
++ pltmp[5] = 0x00caa333; // 0x1014 AGC_Ctrl6
++ pltmp[6] = 0xf6632112; // 0x1018 AGC_Ctrl7
++ pltmp[7] = 0x0FA3F0ED; // 0x101c AGC_Ctrl8
++ pltmp[8] = 0x04C43640; // 0x1020 AGC_Ctrl9
++ pltmp[9] = 0x00002A79; // 0x1024 AGC_Ctrl10
++ pltmp[10] = 0x40000228;
++ pltmp[11] = 0x232A9F30;// 0x102c A_ACQ_Ctrl
++ pWb35Reg->BB2c = 0x232A9F30;
++ Wb35Reg_BurstWrite( pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT );
++
++ pltmp[0] = 0x00002C54; // 0x1030 B_ACQ_Ctrl
++ pWb35Reg->BB30 = 0x00002C54;
++ pltmp[1] = 0x00C0D6C5; // 0x1034 A_TXRX_Ctrl
++ pltmp[2] = 0x5B2C8769; // 0x1038 B_TXRX_Ctrl
++ pltmp[3] = 0x00000000; // 0x103c 11a TX LS filter
++ pWb35Reg->BB3c = 0x00000000;
++ pltmp[4] = 0x00003F29; // 0x1040 11a TX LS filter
++ pltmp[5] = 0x0EFEFBFE; // 0x1044 11a TX LS filter
++ pltmp[6] = 0x00453B24; // 0x1048 11b TX RC filter
++ pltmp[7] = 0x0E00FEFF; // 0x104c 11b TX RC filter
++ pltmp[8] = 0x27106200; // 0x1050 MODE_Ctrl
++ pWb35Reg->BB50 = 0x27106200;
++ pltmp[9] = 0; // 0x1054
++ pWb35Reg->BB54 = 0x00000000;
++ pltmp[10] = 0x64645252; // 0x1058 IQ_Alpha
++ pWb35Reg->BB58 = 0x64645252;
++ pltmp[11] = 0xAA0AC000; // 0x105c DC_Cancel
++ Wb35Reg_BurstWrite( pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT );
++*/
++ BBProcessor_AL7230_2400( pHwData );
++
++ Wb35Reg_Write( pHwData, 0x1070, 0x00000045 );
++ break;
++
++ case RF_WB_242:
++ case RF_WB_242_1: // 20060619.5 Add
++
++ pltmp[0] = 0x16A8525D; // 0x1000 AGC_Ctrl1
++ pltmp[1] = 0x9AFF9ABA; // 0x1004 AGC_Ctrl2
++ pltmp[2] = 0x55D00A04; // 0x1008 AGC_Ctrl3
++ pltmp[3] = 0xEEE91C32; // 0x100c AGC_Ctrl4
++ pWb35Reg->BB0C = 0xEEE91C32;
++ pltmp[4] = 0x0FACDCC5; // 0x1010 AGC_Ctrl5
++ pltmp[5] = 0x000AA344; // 0x1014 AGC_Ctrl6
++ pltmp[6] = 0x22222221; // 0x1018 AGC_Ctrl7
++ pltmp[7] = 0x0FA3F0ED; // 0x101c AGC_Ctrl8
++ pltmp[8] = 0x04CC3440; // 20051018 0x03CB3440; // 0x1020 AGC_Ctrl9 20051014 0x03C33440
++ pltmp[9] = 0xA9002A79; // 0x1024 AGC_Ctrl10
++ pltmp[10] = 0x40000528; // 0x1028
++ pltmp[11] = 0x23457F30; // 0x102c A_ACQ_Ctrl
++ pWb35Reg->BB2C = 0x23457F30;
++ Wb35Reg_BurstWrite( pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT );
++
++ pltmp[0] = 0x00002C54; // 0x1030 B_ACQ_Ctrl
++ pWb35Reg->BB30 = 0x00002C54;
++ pltmp[1] = 0x00C0D6C5; // 0x1034 A_TXRX_Ctrl
++ pltmp[2] = 0x5B2C8769; // 0x1038 B_TXRX_Ctrl
++ pltmp[3] = pHwData->BB3c_cal; // 0x103c 11a TX LS filter
++ pWb35Reg->BB3C = pHwData->BB3c_cal;
++ pltmp[4] = 0x00003F29; // 0x1040 11a TX LS filter
++ pltmp[5] = 0x0EFEFBFE; // 0x1044 11a TX LS filter
++ pltmp[6] = BB48_DEFAULT_WB242_11G; // 0x1048 11b TX RC filter 20060613.2
++ pWb35Reg->BB48 = BB48_DEFAULT_WB242_11G; // 20060613.1 20060613.2
++ pltmp[7] = BB4C_DEFAULT_WB242_11G; // 0x104c 11b TX RC filter 20060613.2
++ pWb35Reg->BB4C = BB4C_DEFAULT_WB242_11G; // 20060613.1 20060613.2
++ pltmp[8] = 0x27106208; // 0x1050 MODE_Ctrl
++ pWb35Reg->BB50 = 0x27106208;
++ pltmp[9] = pHwData->BB54_cal; // 0x1054
++ pWb35Reg->BB54 = pHwData->BB54_cal;
++ pltmp[10] = 0x52523131; // 0x1058 IQ_Alpha
++ pWb35Reg->BB58 = 0x52523131;
++ pltmp[11] = 0xAA0AC000; // 20060825 0xAA2AC000; // 0x105c DC_Cancel
++ Wb35Reg_BurstWrite( pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT );
++
++ Wb35Reg_Write( pHwData, 0x1070, 0x00000045 );
++ break;
++ }
++
++ // Fill the LNA table
++ pWb35Reg->LNAValue[0] = (u8)(pWb35Reg->BB0C & 0xff);
++ pWb35Reg->LNAValue[1] = 0;
++ pWb35Reg->LNAValue[2] = (u8)((pWb35Reg->BB0C & 0xff00)>>8);
++ pWb35Reg->LNAValue[3] = 0;
++
++ // Fill SQ3 table
++ for( i=0; i<MAX_SQ3_FILTER_SIZE; i++ )
++ pWb35Reg->SQ3_filter[i] = 0x2f; // half of Bit 0 ~ 6
++}
++
++void set_tx_power_per_channel_max2829( phw_data_t pHwData, ChanInfo Channel)
++{
++ RFSynthesizer_SetPowerIndex( pHwData, 100 ); // 20060620.1 Modify
++}
++
++void set_tx_power_per_channel_al2230( phw_data_t pHwData, ChanInfo Channel )
++{
++ u8 index = 100;
++
++ if (pHwData->TxVgaFor24[Channel.ChanNo - 1] != 0xff) // 20060620.1 Add
++ index = pHwData->TxVgaFor24[Channel.ChanNo - 1];
++
++ RFSynthesizer_SetPowerIndex( pHwData, index );
++}
++
++void set_tx_power_per_channel_al7230( phw_data_t pHwData, ChanInfo Channel)
++{
++ u8 i, index = 100;
++
++ switch ( Channel.band )
++ {
++ case BAND_TYPE_DSSS:
++ case BAND_TYPE_OFDM_24:
++ {
++ if (pHwData->TxVgaFor24[Channel.ChanNo - 1] != 0xff)
++ index = pHwData->TxVgaFor24[Channel.ChanNo - 1];
++ }
++ break;
++ case BAND_TYPE_OFDM_5:
++ {
++ for (i =0; i<35; i++)
++ {
++ if (Channel.ChanNo == pHwData->TxVgaFor50[i].ChanNo)
++ {
++ if (pHwData->TxVgaFor50[i].TxVgaValue != 0xff)
++ index = pHwData->TxVgaFor50[i].TxVgaValue;
++ break;
++ }
++ }
++ }
++ break;
++ }
++ RFSynthesizer_SetPowerIndex( pHwData, index );
++}
++
++void set_tx_power_per_channel_wb242( phw_data_t pHwData, ChanInfo Channel)
++{
++ u8 index = 100;
++
++ switch ( Channel.band )
++ {
++ case BAND_TYPE_DSSS:
++ case BAND_TYPE_OFDM_24:
++ {
++ if (pHwData->TxVgaFor24[Channel.ChanNo - 1] != 0xff)
++ index = pHwData->TxVgaFor24[Channel.ChanNo - 1];
++ }
++ break;
++ case BAND_TYPE_OFDM_5:
++ break;
++ }
++ RFSynthesizer_SetPowerIndex( pHwData, index );
++}
++
++//=============================================================================================================
++// RFSynthesizer_SwitchingChannel --
++//
++// Description:
++// Swithch the RF channel.
++//
++// Arguments:
++// pHwData - Handle of the USB Device.
++// Channel - The channel no.
++//
++// Return values:
++// None.
++//=============================================================================================================
++void
++RFSynthesizer_SwitchingChannel( phw_data_t pHwData, ChanInfo Channel )
++{
++ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
++ u32 pltmp[16]; // The 16 is the maximum capability of hardware
++ u32 count, ltmp;
++ u8 i, j, number;
++ u8 ChnlTmp;
++
++ switch( pHwData->phy_type )
++ {
++ case RF_MAXIM_2825:
++ case RF_MAXIM_V1: // 11g Winbond 2nd BB(with Phy board (v1) + Maxim 331)
++
++ if( Channel.band <= BAND_TYPE_OFDM_24 ) // channel 1 ~ 13
++ {
++ for( i=0; i<3; i++ )
++ pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2825_channel_data_24[Channel.ChanNo-1][i], 18);
++ Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 3, NO_INCREMENT );
++ }
++ RFSynthesizer_SetPowerIndex( pHwData, 100 );
++ break;
++
++ case RF_MAXIM_2827:
++
++ if( Channel.band <= BAND_TYPE_OFDM_24 ) // channel 1 ~ 13
++ {
++ for( i=0; i<3; i++ )
++ pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2827_channel_data_24[Channel.ChanNo-1][i], 18);
++ Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 3, NO_INCREMENT );
++ }
++ else if( Channel.band == BAND_TYPE_OFDM_5 ) // channel 36 ~ 64
++ {
++ ChnlTmp = (Channel.ChanNo - 36) / 4;
++ for( i=0; i<3; i++ )
++ pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2827_channel_data_50[ChnlTmp][i], 18);
++ Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 3, NO_INCREMENT );
++ }
++ RFSynthesizer_SetPowerIndex( pHwData, 100 );
++ break;
++
++ case RF_MAXIM_2828:
++
++ if( Channel.band <= BAND_TYPE_OFDM_24 ) // channel 1 ~ 13
++ {
++ for( i=0; i<3; i++ )
++ pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2828_channel_data_24[Channel.ChanNo-1][i], 18);
++ Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 3, NO_INCREMENT );
++ }
++ else if( Channel.band == BAND_TYPE_OFDM_5 ) // channel 36 ~ 64
++ {
++ ChnlTmp = (Channel.ChanNo - 36) / 4;
++ for ( i = 0; i < 3; i++)
++ pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2828_channel_data_50[ChnlTmp][i], 18);
++ Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 3, NO_INCREMENT );
++ }
++ RFSynthesizer_SetPowerIndex( pHwData, 100 );
++ break;
++
++ case RF_MAXIM_2829:
++
++ if( Channel.band <= BAND_TYPE_OFDM_24)
++ {
++ for( i=0; i<3; i++ )
++ pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2829_channel_data_24[Channel.ChanNo-1][i], 18);
++ Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 3, NO_INCREMENT );
++ }
++ else if( Channel.band == BAND_TYPE_OFDM_5 )
++ {
++ count = sizeof(max2829_channel_data_50) / sizeof(max2829_channel_data_50[0]);
++
++ for( i=0; i<count; i++ )
++ {
++ if( max2829_channel_data_50[i][0] == Channel.ChanNo )
++ {
++ for( j=0; j<3; j++ )
++ pltmp[j] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2829_channel_data_50[i][j+1], 18);
++ Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 3, NO_INCREMENT );
++
++ if( (max2829_channel_data_50[i][3] & 0x3FFFF) == 0x2A946 )
++ {
++ ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( (5<<18)|0x2A906, 18);
++ Wb35Reg_Write( pHwData, 0x0864, ltmp );
++ }
++ else // 0x2A9C6
++ {
++ ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( (5<<18)|0x2A986, 18);
++ Wb35Reg_Write( pHwData, 0x0864, ltmp );
++ }
++ }
++ }
++ }
++ set_tx_power_per_channel_max2829( pHwData, Channel );
++ break;
++
++ case RF_AIROHA_2230:
++ case RF_AIROHA_2230S: // 20060420 Add this
++
++ if( Channel.band <= BAND_TYPE_OFDM_24 ) // channel 1 ~ 14
++ {
++ for( i=0; i<2; i++ )
++ pltmp[i] = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( al2230_channel_data_24[Channel.ChanNo-1][i], 20);
++ Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 2, NO_INCREMENT );
++ }
++ set_tx_power_per_channel_al2230( pHwData, Channel );
++ break;
++
++ case RF_AIROHA_7230:
++
++ //Start to fill RF parameters, PLL_ON should be pulled low.
++ //Wb35Reg_Write( pHwData, 0x03dc, 0x00000000 );
++ //WBDEBUG(("* PLL_ON low\n"));
++
++ //Channel independent registers
++ if( Channel.band != pHwData->band)
++ {
++ if (Channel.band <= BAND_TYPE_OFDM_24)
++ {
++ //Update BB register
++ BBProcessor_AL7230_2400(pHwData);
++
++ number = sizeof(al7230_rf_data_24)/sizeof(al7230_rf_data_24[0]);
++ Set_ChanIndep_RfData_al7230_24(pHwData, pltmp, number);
++ }
++ else
++ {
++ //Update BB register
++ BBProcessor_AL7230_5000(pHwData);
++
++ number = sizeof(al7230_rf_data_50)/sizeof(al7230_rf_data_50[0]);
++ Set_ChanIndep_RfData_al7230_50(pHwData, pltmp, number);
++ }
++
++ // Write to register. number must less and equal than 16
++ Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, number, NO_INCREMENT );
++ #ifdef _PE_STATE_DUMP_
++ WBDEBUG(("Band changed\n"));
++ #endif
++ }
++
++ if( Channel.band <= BAND_TYPE_OFDM_24 ) // channel 1 ~ 14
++ {
++ for( i=0; i<2; i++ )
++ pltmp[i] = (1 << 31) | (0 << 30) | (24 << 24) | (al7230_channel_data_24[Channel.ChanNo-1][i]&0xffffff);
++ Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 2, NO_INCREMENT );
++ }
++ else if( Channel.band == BAND_TYPE_OFDM_5 )
++ {
++ //Update Reg12
++ if ((Channel.ChanNo > 64) && (Channel.ChanNo <= 165))
++ {
++ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x00143c;
++ Wb35Reg_Write( pHwData, 0x0864, ltmp );
++ }
++ else //reg12 = 0x00147c at Channel 4920 ~ 5320
++ {
++ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x00147c;
++ Wb35Reg_Write( pHwData, 0x0864, ltmp );
++ }
++
++ count = sizeof(al7230_channel_data_5) / sizeof(al7230_channel_data_5[0]);
++
++ for (i=0; i<count; i++)
++ {
++ if (al7230_channel_data_5[i][0] == Channel.ChanNo)
++ {
++ for( j=0; j<3; j++ )
++ pltmp[j] = (1 << 31) | (0 << 30) | (24 << 24) | ( al7230_channel_data_5[i][j+1]&0xffffff);
++ Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 3, NO_INCREMENT );
++ }
++ }
++ }
++ set_tx_power_per_channel_al7230(pHwData, Channel);
++ break;
++
++ case RF_WB_242:
++ case RF_WB_242_1: // 20060619.5 Add
++
++ if( Channel.band <= BAND_TYPE_OFDM_24 ) // channel 1 ~ 14
++ {
++ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( w89rf242_channel_data_24[Channel.ChanNo-1][0], 24);
++ Wb35Reg_Write( pHwData, 0x864, ltmp );
++ }
++ set_tx_power_per_channel_wb242(pHwData, Channel);
++ break;
++ }
++
++ if( Channel.band <= BAND_TYPE_OFDM_24 )
++ {
++ // BB: select 2.4 GHz, bit[12-11]=00
++ pWb35Reg->BB50 &= ~(BIT(11)|BIT(12));
++ Wb35Reg_Write( pHwData, 0x1050, pWb35Reg->BB50 ); // MODE_Ctrl
++ // MAC: select 2.4 GHz, bit[5]=0
++ pWb35Reg->M78_ERPInformation &= ~BIT(5);
++ Wb35Reg_Write( pHwData, 0x0878, pWb35Reg->M78_ERPInformation );
++ // enable 11b Baseband
++ pWb35Reg->BB30 &= ~BIT(31);
++ Wb35Reg_Write( pHwData, 0x1030, pWb35Reg->BB30 );
++ }
++ else if( (Channel.band == BAND_TYPE_OFDM_5) )
++ {
++ // BB: select 5 GHz
++ pWb35Reg->BB50 &= ~(BIT(11)|BIT(12));
++ if (Channel.ChanNo <=64 )
++ pWb35Reg->BB50 |= BIT(12); // 10-5.25GHz
++ else if ((Channel.ChanNo >= 100) && (Channel.ChanNo <= 124))
++ pWb35Reg->BB50 |= BIT(11); // 01-5.48GHz
++ else if ((Channel.ChanNo >=128) && (Channel.ChanNo <= 161))
++ pWb35Reg->BB50 |= (BIT(12)|BIT(11)); // 11-5.775GHz
++ else //Chan 184 ~ 196 will use bit[12-11] = 10 in version sh-src-1.2.25
++ pWb35Reg->BB50 |= BIT(12);
++ Wb35Reg_Write( pHwData, 0x1050, pWb35Reg->BB50 ); // MODE_Ctrl
++
++ //(1) M78 should alway use 2.4G setting when using RF_AIROHA_7230
++ //(2) BB30 has been updated previously.
++ if (pHwData->phy_type != RF_AIROHA_7230)
++ {
++ // MAC: select 5 GHz, bit[5]=1
++ pWb35Reg->M78_ERPInformation |= BIT(5);
++ Wb35Reg_Write( pHwData, 0x0878, pWb35Reg->M78_ERPInformation );
++
++ // disable 11b Baseband
++ pWb35Reg->BB30 |= BIT(31);
++ Wb35Reg_Write( pHwData, 0x1030, pWb35Reg->BB30 );
++ }
++ }
++}
++
++//Set the tx power directly from DUT GUI, not from the EEPROM. Return the current setting
++u8 RFSynthesizer_SetPowerIndex( phw_data_t pHwData, u8 PowerIndex )
++{
++ u32 Band = pHwData->band;
++ u8 index=0;
++
++ if( pHwData->power_index == PowerIndex ) // 20060620.1 Add
++ return PowerIndex;
++
++ if (RF_MAXIM_2825 == pHwData->phy_type)
++ {
++ // Channel 1 - 13
++ index = RFSynthesizer_SetMaxim2825Power( pHwData, PowerIndex );
++ }
++ else if (RF_MAXIM_2827 == pHwData->phy_type)
++ {
++ if( Band <= BAND_TYPE_OFDM_24 ) // Channel 1 - 13
++ index = RFSynthesizer_SetMaxim2827_24Power( pHwData, PowerIndex );
++ else// if( Band == BAND_TYPE_OFDM_5 ) // Channel 36 - 64
++ index = RFSynthesizer_SetMaxim2827_50Power( pHwData, PowerIndex );
++ }
++ else if (RF_MAXIM_2828 == pHwData->phy_type)
++ {
++ if( Band <= BAND_TYPE_OFDM_24 ) // Channel 1 - 13
++ index = RFSynthesizer_SetMaxim2828_24Power( pHwData, PowerIndex );
++ else// if( Band == BAND_TYPE_OFDM_5 ) // Channel 36 - 64
++ index = RFSynthesizer_SetMaxim2828_50Power( pHwData, PowerIndex );
++ }
++ else if( RF_AIROHA_2230 == pHwData->phy_type )
++ {
++ //Power index: 0 ~ 63 // Channel 1 - 14
++ index = RFSynthesizer_SetAiroha2230Power( pHwData, PowerIndex );
++ index = (u8)al2230_txvga_data[index][1];
++ }
++ else if( RF_AIROHA_2230S == pHwData->phy_type ) // 20060420 Add this
++ {
++ //Power index: 0 ~ 63 // Channel 1 - 14
++ index = RFSynthesizer_SetAiroha2230Power( pHwData, PowerIndex );
++ index = (u8)al2230_txvga_data[index][1];
++ }
++ else if( RF_AIROHA_7230 == pHwData->phy_type )
++ {
++ //Power index: 0 ~ 63
++ index = RFSynthesizer_SetAiroha7230Power( pHwData, PowerIndex );
++ index = (u8)al7230_txvga_data[index][1];
++ }
++ else if( (RF_WB_242 == pHwData->phy_type) ||
++ (RF_WB_242_1 == pHwData->phy_type) ) // 20060619.5 Add
++ {
++ //Power index: 0 ~ 19 for original. New range is 0 ~ 33
++ index = RFSynthesizer_SetWinbond242Power( pHwData, PowerIndex );
++ index = (u8)w89rf242_txvga_data[index][1];
++ }
++
++ pHwData->power_index = index; // Backup current
++ return index;
++}
++
++//-- Sub function
++u8 RFSynthesizer_SetMaxim2828_24Power( phw_data_t pHwData, u8 index )
++{
++ u32 PowerData;
++ if( index > 1 ) index = 1;
++ PowerData = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2828_power_data_24[index], 18);
++ Wb35Reg_Write( pHwData, 0x0864, PowerData );
++ return index;
++}
++//--
++u8 RFSynthesizer_SetMaxim2828_50Power( phw_data_t pHwData, u8 index )
++{
++ u32 PowerData;
++ if( index > 1 ) index = 1;
++ PowerData = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2828_power_data_50[index], 18);
++ Wb35Reg_Write( pHwData, 0x0864, PowerData );
++ return index;
++}
++//--
++u8 RFSynthesizer_SetMaxim2827_24Power( phw_data_t pHwData, u8 index )
++{
++ u32 PowerData;
++ if( index > 1 ) index = 1;
++ PowerData = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2827_power_data_24[index], 18);
++ Wb35Reg_Write( pHwData, 0x0864, PowerData );
++ return index;
++}
++//--
++u8 RFSynthesizer_SetMaxim2827_50Power( phw_data_t pHwData, u8 index )
++{
++ u32 PowerData;
++ if( index > 1 ) index = 1;
++ PowerData = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2827_power_data_50[index], 18);
++ Wb35Reg_Write( pHwData, 0x0864, PowerData );
++ return index;
++}
++//--
++u8 RFSynthesizer_SetMaxim2825Power( phw_data_t pHwData, u8 index )
++{
++ u32 PowerData;
++ if( index > 1 ) index = 1;
++ PowerData = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2825_power_data_24[index], 18);
++ Wb35Reg_Write( pHwData, 0x0864, PowerData );
++ return index;
++}
++//--
++u8 RFSynthesizer_SetAiroha2230Power( phw_data_t pHwData, u8 index )
++{
++ u32 PowerData;
++ u8 i,count;
++
++ count = sizeof(al2230_txvga_data) / sizeof(al2230_txvga_data[0]);
++ for (i=0; i<count; i++)
++ {
++ if (al2230_txvga_data[i][1] >= index)
++ break;
++ }
++ if (i == count)
++ i--;
++
++ PowerData = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( al2230_txvga_data[i][0], 20);
++ Wb35Reg_Write( pHwData, 0x0864, PowerData );
++ return i;
++}
++//--
++u8 RFSynthesizer_SetAiroha7230Power( phw_data_t pHwData, u8 index )
++{
++ u32 PowerData;
++ u8 i,count;
++
++ //PowerData = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( airoha_power_data_24[index], 20);
++ count = sizeof(al7230_txvga_data) / sizeof(al7230_txvga_data[0]);
++ for (i=0; i<count; i++)
++ {
++ if (al7230_txvga_data[i][1] >= index)
++ break;
++ }
++ if (i == count)
++ i--;
++ PowerData = (1 << 31) | (0 << 30) | (24 << 24) | (al7230_txvga_data[i][0]&0xffffff);
++ Wb35Reg_Write( pHwData, 0x0864, PowerData );
++ return i;
++}
++
++u8 RFSynthesizer_SetWinbond242Power( phw_data_t pHwData, u8 index )
++{
++ u32 PowerData;
++ u8 i,count;
++
++ count = sizeof(w89rf242_txvga_data) / sizeof(w89rf242_txvga_data[0]);
++ for (i=0; i<count; i++)
++ {
++ if (w89rf242_txvga_data[i][1] >= index)
++ break;
++ }
++ if (i == count)
++ i--;
++
++ // Set TxVga into RF
++ PowerData = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( w89rf242_txvga_data[i][0], 24);
++ Wb35Reg_Write( pHwData, 0x0864, PowerData );
++
++ // Update BB48 BB4C BB58 for high precision txvga
++ Wb35Reg_Write( pHwData, 0x1048, w89rf242_txvga_data[i][2] );
++ Wb35Reg_Write( pHwData, 0x104c, w89rf242_txvga_data[i][3] );
++ Wb35Reg_Write( pHwData, 0x1058, w89rf242_txvga_data[i][4] );
++
++// Rf vga 0 ~ 3 for temperature compensate. It will affect the scan Bss.
++// The i value equals to 8 or 7 usually. So It's not necessary to setup this RF register.
++// if( i <= 3 )
++// PowerData = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( 0x000024, 24 );
++// else
++// PowerData = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( 0x001824, 24 );
++// Wb35Reg_Write( pHwData, 0x0864, PowerData );
++ return i;
++}
++
++//===========================================================================================================
++// Dxx_initial --
++// Mxx_initial --
++ //
++// Routine Description:
++// Initial the hardware setting and module variable
++ //
++//===========================================================================================================
++void Dxx_initial( phw_data_t pHwData )
++{
++ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
++
++ // Old IC:Single mode only.
++ // New IC: operation decide by Software set bit[4]. 1:multiple 0: single
++ pWb35Reg->D00_DmaControl = 0xc0000004; //Txon, Rxon, multiple Rx for new 4k DMA
++ //Txon, Rxon, single Rx for old 8k ASIC
++ if( !HAL_USB_MODE_BURST( pHwData ) )
++ pWb35Reg->D00_DmaControl = 0xc0000000;//Txon, Rxon, single Rx for new 4k DMA
++
++ Wb35Reg_WriteSync( pHwData, 0x0400, pWb35Reg->D00_DmaControl );
++}
++
++void Mxx_initial( phw_data_t pHwData )
++{
++ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
++ u32 tmp;
++ u32 pltmp[11];
++ u16 i;
++
++
++ //======================================================
++ // Initial Mxx register
++ //======================================================
++
++ // M00 bit set
++#ifdef _IBSS_BEACON_SEQ_STICK_
++ pWb35Reg->M00_MacControl = 0; // Solve beacon sequence number stop by software
++#else
++ pWb35Reg->M00_MacControl = 0x80000000; // Solve beacon sequence number stop by hardware
++#endif
++
++ // M24 disable enter power save, BB RxOn and enable NAV attack
++ pWb35Reg->M24_MacControl = 0x08040042;
++ pltmp[0] = pWb35Reg->M24_MacControl;
++
++ pltmp[1] = 0; // Skip M28, because no initialize value is required.
++
++ // M2C CWmin and CWmax setting
++ pHwData->cwmin = DEFAULT_CWMIN;
++ pHwData->cwmax = DEFAULT_CWMAX;
++ pWb35Reg->M2C_MacControl = DEFAULT_CWMIN << 10;
++ pWb35Reg->M2C_MacControl |= DEFAULT_CWMAX;
++ pltmp[2] = pWb35Reg->M2C_MacControl;
++
++ // M30 BSSID
++ pltmp[3] = *(PULONG)pHwData->bssid;
++
++ // M34
++ pHwData->AID = DEFAULT_AID;
++ tmp = *(PUSHORT)(pHwData->bssid+4);
++ tmp |= DEFAULT_AID << 16;
++ pltmp[4] = tmp;
++
++ // M38
++ pWb35Reg->M38_MacControl = (DEFAULT_RATE_RETRY_LIMIT<<8) | (DEFAULT_LONG_RETRY_LIMIT << 4) | DEFAULT_SHORT_RETRY_LIMIT;
++ pltmp[5] = pWb35Reg->M38_MacControl;
++
++ // M3C
++ tmp = (DEFAULT_PIFST << 26) | (DEFAULT_EIFST << 16) | (DEFAULT_DIFST << 8) | (DEFAULT_SIFST << 4) | DEFAULT_OSIFST ;
++ pWb35Reg->M3C_MacControl = tmp;
++ pltmp[6] = tmp;
++
++ // M40
++ pHwData->slot_time_select = DEFAULT_SLOT_TIME;
++ tmp = (DEFAULT_ATIMWD << 16) | DEFAULT_SLOT_TIME;
++ pWb35Reg->M40_MacControl = tmp;
++ pltmp[7] = tmp;
++
++ // M44
++ tmp = DEFAULT_MAX_TX_MSDU_LIFE_TIME << 10; // *1024
++ pWb35Reg->M44_MacControl = tmp;
++ pltmp[8] = tmp;
++
++ // M48
++ pHwData->BeaconPeriod = DEFAULT_BEACON_INTERVAL;
++ pHwData->ProbeDelay = DEFAULT_PROBE_DELAY_TIME;
++ tmp = (DEFAULT_BEACON_INTERVAL << 16) | DEFAULT_PROBE_DELAY_TIME;
++ pWb35Reg->M48_MacControl = tmp;
++ pltmp[9] = tmp;
++
++ //M4C
++ pWb35Reg->M4C_MacStatus = (DEFAULT_PROTOCOL_VERSION << 30) | (DEFAULT_MAC_POWER_STATE << 28) | (DEFAULT_DTIM_ALERT_TIME << 24);
++ pltmp[10] = pWb35Reg->M4C_MacStatus;
++
++ // Burst write
++ //Wb35Reg_BurstWrite( pHwData, 0x0824, pltmp, 11, AUTO_INCREMENT );
++ for( i=0; i<11; i++ )
++ Wb35Reg_WriteSync( pHwData, 0x0824 + i*4, pltmp[i] );
++
++ // M60
++ Wb35Reg_WriteSync( pHwData, 0x0860, 0x12481248 );
++ pWb35Reg->M60_MacControl = 0x12481248;
++
++ // M68
++ Wb35Reg_WriteSync( pHwData, 0x0868, 0x00050900 ); // 20051018 0x000F0F00 ); // 940930 0x00131300
++ pWb35Reg->M68_MacControl = 0x00050900;
++
++ // M98
++ Wb35Reg_WriteSync( pHwData, 0x0898, 0xffff8888 );
++ pWb35Reg->M98_MacControl = 0xffff8888;
++}
++
++
++void Uxx_power_off_procedure( phw_data_t pHwData )
++{
++ // SW, PMU reset and turn off clock
++ Wb35Reg_WriteSync( pHwData, 0x03b0, 3 );
++ Wb35Reg_WriteSync( pHwData, 0x03f0, 0xf9 );
++}
++
++//Decide the TxVga of every channel
++void GetTxVgaFromEEPROM( phw_data_t pHwData )
++{
++ u32 i, j, ltmp;
++ u16 Value[MAX_TXVGA_EEPROM];
++ PUCHAR pctmp;
++ u8 ctmp=0;
++
++ // Get the entire TxVga setting in EEPROM
++ for( i=0; i<MAX_TXVGA_EEPROM; i++ )
++ {
++ Wb35Reg_WriteSync( pHwData, 0x03b4, 0x08100000 + 0x00010000*i );
++ Wb35Reg_ReadSync( pHwData, 0x03b4, <mp );
++ Value[i] = (u16)( ltmp & 0xffff ); // Get 16 bit available
++ Value[i] = cpu_to_le16( Value[i] ); // [7:0]2412 [7:0]2417 ....
++ }
++
++ // Adjust the filed which fills with reserved value.
++ pctmp = (PUCHAR)Value;
++ for( i=0; i<(MAX_TXVGA_EEPROM*2); i++ )
++ {
++ if( pctmp[i] != 0xff )
++ ctmp = pctmp[i];
++ else
++ pctmp[i] = ctmp;
++ }
++
++ // Adjust WB_242 to WB_242_1 TxVga scale
++ if( pHwData->phy_type == RF_WB_242 )
++ {
++ for( i=0; i<4; i++ ) // Only 2412 2437 2462 2484 case must be modified
++ {
++ for( j=0; j<(sizeof(w89rf242_txvga_old_mapping)/sizeof(w89rf242_txvga_old_mapping[0])); j++ )
++ {
++ if( pctmp[i] < (u8)w89rf242_txvga_old_mapping[j][1] )
++ {
++ pctmp[i] = (u8)w89rf242_txvga_old_mapping[j][0];
++ break;
++ }
++ }
++
++ if( j == (sizeof(w89rf242_txvga_old_mapping)/sizeof(w89rf242_txvga_old_mapping[0])) )
++ pctmp[i] = (u8)w89rf242_txvga_old_mapping[j-1][0];
++ }
++ }
++
++ // 20060621 Add
++ memcpy( pHwData->TxVgaSettingInEEPROM, pctmp, MAX_TXVGA_EEPROM*2 ); //MAX_TXVGA_EEPROM is u16 count
++ EEPROMTxVgaAdjust( pHwData );
++}
++
++// This function will affect the TxVga parameter in HAL. If hal_set_current_channel
++// or RFSynthesizer_SetPowerIndex be called, new TxVga will take effect.
++// TxVgaSettingInEEPROM of sHwData is an u8 array point to EEPROM contain for IS89C35
++// This function will use default TxVgaSettingInEEPROM data to calculate new TxVga.
++void EEPROMTxVgaAdjust( phw_data_t pHwData ) // 20060619.5 Add
++{
++ PUCHAR pTxVga = pHwData->TxVgaSettingInEEPROM;
++ s16 i, stmp;
++
++ //-- 2.4G -- 20060704.2 Request from Tiger
++ //channel 1 ~ 5
++ stmp = pTxVga[1] - pTxVga[0];
++ for( i=0; i<5; i++ )
++ pHwData->TxVgaFor24[i] = pTxVga[0] + stmp*i/4;
++ //channel 6 ~ 10
++ stmp = pTxVga[2] - pTxVga[1];
++ for( i=5; i<10; i++ )
++ pHwData->TxVgaFor24[i] = pTxVga[1] + stmp*(i-5)/4;
++ //channel 11 ~ 13
++ stmp = pTxVga[3] - pTxVga[2];
++ for( i=10; i<13; i++ )
++ pHwData->TxVgaFor24[i] = pTxVga[2] + stmp*(i-10)/2;
++ //channel 14
++ pHwData->TxVgaFor24[13] = pTxVga[3];
++
++ //-- 5G --
++ if( pHwData->phy_type == RF_AIROHA_7230 )
++ {
++ //channel 184
++ pHwData->TxVgaFor50[0].ChanNo = 184;
++ pHwData->TxVgaFor50[0].TxVgaValue = pTxVga[4];
++ //channel 196
++ pHwData->TxVgaFor50[3].ChanNo = 196;
++ pHwData->TxVgaFor50[3].TxVgaValue = pTxVga[5];
++ //interpolate
++ pHwData->TxVgaFor50[1].ChanNo = 188;
++ pHwData->TxVgaFor50[2].ChanNo = 192;
++ stmp = pTxVga[5] - pTxVga[4];
++ pHwData->TxVgaFor50[2].TxVgaValue = pTxVga[5] - stmp/3;
++ pHwData->TxVgaFor50[1].TxVgaValue = pTxVga[5] - stmp*2/3;
++
++ //channel 16
++ pHwData->TxVgaFor50[6].ChanNo = 16;
++ pHwData->TxVgaFor50[6].TxVgaValue = pTxVga[6];
++ pHwData->TxVgaFor50[4].ChanNo = 8;
++ pHwData->TxVgaFor50[4].TxVgaValue = pTxVga[6];
++ pHwData->TxVgaFor50[5].ChanNo = 12;
++ pHwData->TxVgaFor50[5].TxVgaValue = pTxVga[6];
++
++ //channel 36
++ pHwData->TxVgaFor50[8].ChanNo = 36;
++ pHwData->TxVgaFor50[8].TxVgaValue = pTxVga[7];
++ pHwData->TxVgaFor50[7].ChanNo = 34;
++ pHwData->TxVgaFor50[7].TxVgaValue = pTxVga[7];
++ pHwData->TxVgaFor50[9].ChanNo = 38;
++ pHwData->TxVgaFor50[9].TxVgaValue = pTxVga[7];
++
++ //channel 40
++ pHwData->TxVgaFor50[10].ChanNo = 40;
++ pHwData->TxVgaFor50[10].TxVgaValue = pTxVga[8];
++ //channel 48
++ pHwData->TxVgaFor50[14].ChanNo = 48;
++ pHwData->TxVgaFor50[14].TxVgaValue = pTxVga[9];
++ //interpolate
++ pHwData->TxVgaFor50[11].ChanNo = 42;
++ pHwData->TxVgaFor50[12].ChanNo = 44;
++ pHwData->TxVgaFor50[13].ChanNo = 46;
++ stmp = pTxVga[9] - pTxVga[8];
++ pHwData->TxVgaFor50[13].TxVgaValue = pTxVga[9] - stmp/4;
++ pHwData->TxVgaFor50[12].TxVgaValue = pTxVga[9] - stmp*2/4;
++ pHwData->TxVgaFor50[11].TxVgaValue = pTxVga[9] - stmp*3/4;
++
++ //channel 52
++ pHwData->TxVgaFor50[15].ChanNo = 52;
++ pHwData->TxVgaFor50[15].TxVgaValue = pTxVga[10];
++ //channel 64
++ pHwData->TxVgaFor50[18].ChanNo = 64;
++ pHwData->TxVgaFor50[18].TxVgaValue = pTxVga[11];
++ //interpolate
++ pHwData->TxVgaFor50[16].ChanNo = 56;
++ pHwData->TxVgaFor50[17].ChanNo = 60;
++ stmp = pTxVga[11] - pTxVga[10];
++ pHwData->TxVgaFor50[17].TxVgaValue = pTxVga[11] - stmp/3;
++ pHwData->TxVgaFor50[16].TxVgaValue = pTxVga[11] - stmp*2/3;
++
++ //channel 100
++ pHwData->TxVgaFor50[19].ChanNo = 100;
++ pHwData->TxVgaFor50[19].TxVgaValue = pTxVga[12];
++ //channel 112
++ pHwData->TxVgaFor50[22].ChanNo = 112;
++ pHwData->TxVgaFor50[22].TxVgaValue = pTxVga[13];
++ //interpolate
++ pHwData->TxVgaFor50[20].ChanNo = 104;
++ pHwData->TxVgaFor50[21].ChanNo = 108;
++ stmp = pTxVga[13] - pTxVga[12];
++ pHwData->TxVgaFor50[21].TxVgaValue = pTxVga[13] - stmp/3;
++ pHwData->TxVgaFor50[20].TxVgaValue = pTxVga[13] - stmp*2/3;
++
++ //channel 128
++ pHwData->TxVgaFor50[26].ChanNo = 128;
++ pHwData->TxVgaFor50[26].TxVgaValue = pTxVga[14];
++ //interpolate
++ pHwData->TxVgaFor50[23].ChanNo = 116;
++ pHwData->TxVgaFor50[24].ChanNo = 120;
++ pHwData->TxVgaFor50[25].ChanNo = 124;
++ stmp = pTxVga[14] - pTxVga[13];
++ pHwData->TxVgaFor50[25].TxVgaValue = pTxVga[14] - stmp/4;
++ pHwData->TxVgaFor50[24].TxVgaValue = pTxVga[14] - stmp*2/4;
++ pHwData->TxVgaFor50[23].TxVgaValue = pTxVga[14] - stmp*3/4;
++
++ //channel 140
++ pHwData->TxVgaFor50[29].ChanNo = 140;
++ pHwData->TxVgaFor50[29].TxVgaValue = pTxVga[15];
++ //interpolate
++ pHwData->TxVgaFor50[27].ChanNo = 132;
++ pHwData->TxVgaFor50[28].ChanNo = 136;
++ stmp = pTxVga[15] - pTxVga[14];
++ pHwData->TxVgaFor50[28].TxVgaValue = pTxVga[15] - stmp/3;
++ pHwData->TxVgaFor50[27].TxVgaValue = pTxVga[15] - stmp*2/3;
++
++ //channel 149
++ pHwData->TxVgaFor50[30].ChanNo = 149;
++ pHwData->TxVgaFor50[30].TxVgaValue = pTxVga[16];
++ //channel 165
++ pHwData->TxVgaFor50[34].ChanNo = 165;
++ pHwData->TxVgaFor50[34].TxVgaValue = pTxVga[17];
++ //interpolate
++ pHwData->TxVgaFor50[31].ChanNo = 153;
++ pHwData->TxVgaFor50[32].ChanNo = 157;
++ pHwData->TxVgaFor50[33].ChanNo = 161;
++ stmp = pTxVga[17] - pTxVga[16];
++ pHwData->TxVgaFor50[33].TxVgaValue = pTxVga[17] - stmp/4;
++ pHwData->TxVgaFor50[32].TxVgaValue = pTxVga[17] - stmp*2/4;
++ pHwData->TxVgaFor50[31].TxVgaValue = pTxVga[17] - stmp*3/4;
++ }
++
++ #ifdef _PE_STATE_DUMP_
++ WBDEBUG((" TxVgaFor24 : \n"));
++ DataDmp((u8 *)pHwData->TxVgaFor24, 14 ,0);
++ WBDEBUG((" TxVgaFor50 : \n"));
++ DataDmp((u8 *)pHwData->TxVgaFor50, 70 ,0);
++ #endif
++}
++
++void BBProcessor_RateChanging( phw_data_t pHwData, u8 rate ) // 20060613.1
++{
++ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
++ unsigned char Is11bRate;
++
++ Is11bRate = (rate % 6) ? 1 : 0;
++ switch( pHwData->phy_type )
++ {
++ case RF_AIROHA_2230:
++ case RF_AIROHA_2230S: // 20060420 Add this
++ if( Is11bRate )
++ {
++ if( (pWb35Reg->BB48 != BB48_DEFAULT_AL2230_11B) &&
++ (pWb35Reg->BB4C != BB4C_DEFAULT_AL2230_11B) )
++ {
++ Wb35Reg_Write( pHwData, 0x1048, BB48_DEFAULT_AL2230_11B );
++ Wb35Reg_Write( pHwData, 0x104c, BB4C_DEFAULT_AL2230_11B );
++ }
++ }
++ else
++ {
++ if( (pWb35Reg->BB48 != BB48_DEFAULT_AL2230_11G) &&
++ (pWb35Reg->BB4C != BB4C_DEFAULT_AL2230_11G) )
++ {
++ Wb35Reg_Write( pHwData, 0x1048, BB48_DEFAULT_AL2230_11G );
++ Wb35Reg_Write( pHwData, 0x104c, BB4C_DEFAULT_AL2230_11G );
++ }
++ }
++ break;
++
++ case RF_WB_242: // 20060623 The fix only for old TxVGA setting
++ if( Is11bRate )
++ {
++ if( (pWb35Reg->BB48 != BB48_DEFAULT_WB242_11B) &&
++ (pWb35Reg->BB4C != BB4C_DEFAULT_WB242_11B) )
++ {
++ pWb35Reg->BB48 = BB48_DEFAULT_WB242_11B;
++ pWb35Reg->BB4C = BB4C_DEFAULT_WB242_11B;
++ Wb35Reg_Write( pHwData, 0x1048, BB48_DEFAULT_WB242_11B );
++ Wb35Reg_Write( pHwData, 0x104c, BB4C_DEFAULT_WB242_11B );
++ }
++ }
++ else
++ {
++ if( (pWb35Reg->BB48 != BB48_DEFAULT_WB242_11G) &&
++ (pWb35Reg->BB4C != BB4C_DEFAULT_WB242_11G) )
++ {
++ pWb35Reg->BB48 = BB48_DEFAULT_WB242_11G;
++ pWb35Reg->BB4C = BB4C_DEFAULT_WB242_11G;
++ Wb35Reg_Write( pHwData, 0x1048, BB48_DEFAULT_WB242_11G );
++ Wb35Reg_Write( pHwData, 0x104c, BB4C_DEFAULT_WB242_11G );
++ }
++ }
++ break;
++ }
++}
++
++
++
++
++
++
++
+diff --git a/drivers/staging/winbond/rxisr.c b/drivers/staging/winbond/rxisr.c
+new file mode 100644
+index 0000000..18e942c
+--- /dev/null
++++ b/drivers/staging/winbond/rxisr.c
+@@ -0,0 +1,30 @@
++#include "os_common.h"
++
++void vRxTimerInit(PWB32_ADAPTER Adapter)
++{
++ OS_TIMER_INITIAL(&(Adapter->Mds.nTimer), (void*) RxTimerHandler, (void*) Adapter);
++}
++
++void vRxTimerStart(PWB32_ADAPTER Adapter, int timeout_value)
++{
++ if (timeout_value<MIN_TIMEOUT_VAL)
++ timeout_value=MIN_TIMEOUT_VAL;
++
++ OS_TIMER_SET( &(Adapter->Mds.nTimer), timeout_value );
++}
++
++void vRxTimerStop(PWB32_ADAPTER Adapter)
++{
++ OS_TIMER_CANCEL( &(Adapter->Mds.nTimer), 0 );
++}
++
++void RxTimerHandler_1a( PADAPTER Adapter)
++{
++ RxTimerHandler(NULL, Adapter, NULL, NULL);
++}
++
++void RxTimerHandler(void* SystemSpecific1, PWB32_ADAPTER Adapter,
++ void* SystemSpecific2, void* SystemSpecific3)
++{
++ WARN_ON(1);
++}
+diff --git a/drivers/staging/winbond/scan_s.h b/drivers/staging/winbond/scan_s.h
+new file mode 100644
+index 0000000..1d1b0c4
+--- /dev/null
++++ b/drivers/staging/winbond/scan_s.h
+@@ -0,0 +1,115 @@
++//
++// SCAN task global CONSTANTS, STRUCTURES, variables
++//
++
++//////////////////////////////////////////////////////////////////////////
++//define the msg type of SCAN module
++#define SCANMSG_SCAN_REQ 0x01
++#define SCANMSG_BEACON 0x02
++#define SCANMSG_PROBE_RESPONSE 0x03
++#define SCANMSG_TIMEOUT 0x04
++#define SCANMSG_TXPROBE_FAIL 0x05
++#define SCANMSG_ENABLE_BGSCAN 0x06
++#define SCANMSG_STOP_SCAN 0x07
++
++// BSS Type =>conform to
++// IBSS : ToDS/FromDS = 00
++// Infrastructure : ToDS/FromDS = 01
++#define IBSS_NET 0
++#define ESS_NET 1
++#define ANYBSS_NET 2
++
++// Scan Type
++#define ACTIVE_SCAN 0
++#define PASSIVE_SCAN 1
++
++///////////////////////////////////////////////////////////////////////////
++//Global data structures, Initial Scan & Background Scan
++typedef struct _SCAN_REQ_PARA //mandatory parameters for SCAN request
++{
++ u32 ScanType; //passive/active scan
++
++ CHAN_LIST sChannelList; // 86B
++ u8 reserved_1[2];
++
++ struct SSID_Element sSSID; // 34B. scan only for this SSID
++ u8 reserved_2[2];
++
++} SCAN_REQ_PARA, *psSCAN_REQ_PARA;
++
++typedef struct _SCAN_PARAMETERS
++{
++ u16 wState;
++ u16 iCurrentChannelIndex;
++
++ SCAN_REQ_PARA sScanReq;
++
++ u8 BSSID[MAC_ADDR_LENGTH + 2]; //scan only for this BSSID
++
++ u32 BssType; //scan only for this BSS type
++
++ //struct SSID_Element sSSID; //scan only for this SSID
++ u16 ProbeDelay;
++ u16 MinChannelTime;
++
++ u16 MaxChannelTime;
++ u16 reserved_1;
++
++ s32 iBgScanPeriod; // XP: 5 sec
++
++ u8 boBgScan; // Wb: enable BG scan, For XP, this value must be FALSE
++ u8 boFastScan; // Wb: reserved
++ u8 boCCAbusy; // Wb: HWMAC CCA busy status
++ u8 reserved_2;
++
++ //NDIS_MINIPORT_TIMER nTimer;
++ OS_TIMER nTimer;
++
++ u32 ScanTimeStamp; //Increase 1 per background scan(1 minute)
++ u32 BssTimeStamp; //Increase 1 per connect status check
++ u32 RxNumPerAntenna[2]; //
++
++ u8 AntennaToggle; //
++ u8 boInTimerHandler;
++ u8 boTimerActive; // Wb: reserved
++ u8 boSave;
++
++ u32 BScanEnable; // Background scan enable. Default is On
++
++} SCAN_PARAMETERS, *psSCAN_PARAMETERS;
++
++// Encapsulate 'Adapter' data structure
++#define psSCAN (&(Adapter->sScanPara))
++#define psSCANREQ (&(Adapter->sScanPara.sScanReq))
++
++//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++// scan.h
++// Define the related definitions of scan module
++// history -- 01/14/03' created
++//
++//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++
++//Define the state of scan module
++#define SCAN_INACTIVE 0
++#define WAIT_PROBE_DELAY 1
++#define WAIT_RESPONSE_MIN 2
++#define WAIT_RESPONSE_MAX_ACTIVE 3
++#define WAIT_BEACON_MAX_PASSIVE 4
++#define SCAN_COMPLETE 5
++#define BG_SCAN 6
++#define BG_SCANNING 7
++
++
++// The value will load from EEPROM
++// If 0xff is set in EEPOM, the driver will use SCAN_MAX_CHNL_TIME instead.
++// The definition is in WbHal.h
++// #define SCAN_MAX_CHNL_TIME (50)
++
++
++
++// static functions
++
++//static void ScanTimerHandler(PWB32_ADAPTER Adapter);
++//static void vScanTimerStart(PWB32_ADAPTER Adapter, int timeout_value);
++//static void vScanTimerStop(PWB32_ADAPTER Adapter);
++
+diff --git a/drivers/staging/winbond/sme_api.c b/drivers/staging/winbond/sme_api.c
+new file mode 100644
+index 0000000..40e93b7
+--- /dev/null
++++ b/drivers/staging/winbond/sme_api.c
+@@ -0,0 +1,13 @@
++//------------------------------------------------------------------------------------
++// sme_api.c
++//
++// Copyright(C) 2002 Winbond Electronics Corp.
++//
++//
++//------------------------------------------------------------------------------------
++#include "os_common.h"
++
++s8 sme_get_rssi(void *pcore_data, s32 *prssi)
++{
++ BUG();
++}
+diff --git a/drivers/staging/winbond/sme_api.h b/drivers/staging/winbond/sme_api.h
+new file mode 100644
+index 0000000..016b225
+--- /dev/null
++++ b/drivers/staging/winbond/sme_api.h
+@@ -0,0 +1,265 @@
++/*
++ * sme_api.h
++ *
++ * Copyright(C) 2002 Winbond Electronics Corp.
++ *
++ * modification history
++ * ---------------------------------------------------------------------------
++ * 1.00.001, 2003-04-21, Kevin created
++ * 1.00.002, 2003-05-14, PD43 & PE20 modified
++ *
++ */
++
++#ifndef __SME_API_H__
++#define __SME_API_H__
++
++/****************** INCLUDE FILES SECTION ***********************************/
++//#include "GL\gl_core.h"
++
++/****************** CONSTANT AND MACRO SECTION ******************************/
++#define _INLINE __inline
++
++#define MEDIA_STATE_DISCONNECTED 0
++#define MEDIA_STATE_CONNECTED 1
++
++//ARRAY CHECK
++#define MAX_POWER_TO_DB 32
++
++/****************** TYPE DEFINITION SECTION *********************************/
++
++/****************** EXPORTED FUNCTION DECLARATION SECTION *******************/
++
++// OID_802_11_BSSID
++s8 sme_get_bssid(void *pcore_data, u8 *pbssid);
++s8 sme_get_desired_bssid(void *pcore_data, u8 *pbssid);//Not use
++s8 sme_set_desired_bssid(void *pcore_data, u8 *pbssid);
++
++// OID_802_11_SSID
++s8 sme_get_ssid(void *pcore_data, u8 *pssid, u8 *pssid_len);
++s8 sme_get_desired_ssid(void *pcore_data, u8 *pssid, u8 *pssid_len);// Not use
++s8 sme_set_desired_ssid(void *pcore_data, u8 *pssid, u8 ssid_len);
++
++// OID_802_11_INFRASTRUCTURE_MODE
++s8 sme_get_bss_type(void *pcore_data, u8 *pbss_type);
++s8 sme_get_desired_bss_type(void *pcore_data, u8 *pbss_type);//Not use
++s8 sme_set_desired_bss_type(void *pcore_data, u8 bss_type);
++
++// OID_802_11_FRAGMENTATION_THRESHOLD
++s8 sme_get_fragment_threshold(void *pcore_data, u32 *pthreshold);
++s8 sme_set_fragment_threshold(void *pcore_data, u32 threshold);
++
++// OID_802_11_RTS_THRESHOLD
++s8 sme_get_rts_threshold(void *pcore_data, u32 *pthreshold);
++s8 sme_set_rts_threshold(void *pcore_data, u32 threshold);
++
++// OID_802_11_RSSI
++s8 sme_get_rssi(void *pcore_data, s32 *prssi);
++
++// OID_802_11_CONFIGURATION
++s8 sme_get_beacon_period(void *pcore_data, u16 *pbeacon_period);
++s8 sme_set_beacon_period(void *pcore_data, u16 beacon_period);
++
++s8 sme_get_atim_window(void *pcore_data, u16 *patim_window);
++s8 sme_set_atim_window(void *pcore_data, u16 atim_window);
++
++s8 sme_get_current_channel(void *pcore_data, u8 *pcurrent_channel);
++s8 sme_get_current_band(void *pcore_data, u8 *pcurrent_band);
++s8 sme_set_current_channel(void *pcore_data, u8 current_channel);
++
++// OID_802_11_BSSID_LIST
++s8 sme_get_scan_bss_count(void *pcore_data, u8 *pcount);
++s8 sme_get_scan_bss(void *pcore_data, u8 index, void **ppbss);
++
++s8 sme_get_connected_bss(void *pcore_data, void **ppbss_now);
++
++// OID_802_11_AUTHENTICATION_MODE
++s8 sme_get_auth_mode(void *pcore_data, u8 *pauth_mode);
++s8 sme_set_auth_mode(void *pcore_data, u8 auth_mode);
++
++// OID_802_11_WEP_STATUS / OID_802_11_ENCRYPTION_STATUS
++s8 sme_get_wep_mode(void *pcore_data, u8 *pwep_mode);
++s8 sme_set_wep_mode(void *pcore_data, u8 wep_mode);
++//s8 sme_get_encryption_status(void *pcore_data, u8 *pstatus);
++//s8 sme_set_encryption_status(void *pcore_data, u8 status);
++
++// ???????????????????????????????????????
++
++// OID_GEN_VENDOR_ID
++// OID_802_3_PERMANENT_ADDRESS
++s8 sme_get_permanent_mac_addr(void *pcore_data, u8 *pmac_addr);
++
++// OID_802_3_CURRENT_ADDRESS
++s8 sme_get_current_mac_addr(void *pcore_data, u8 *pmac_addr);
++
++// OID_802_11_NETWORK_TYPE_IN_USE
++s8 sme_get_network_type_in_use(void *pcore_data, u8 *ptype);
++s8 sme_set_network_type_in_use(void *pcore_data, u8 type);
++
++// OID_802_11_SUPPORTED_RATES
++s8 sme_get_supported_rate(void *pcore_data, u8 *prates);
++
++// OID_802_11_ADD_WEP
++//12/29/03' wkchen
++s8 sme_set_add_wep(void *pcore_data, u32 key_index, u32 key_len,
++ u8 *Address, u8 *key);
++
++// OID_802_11_REMOVE_WEP
++s8 sme_set_remove_wep(void *pcre_data, u32 key_index);
++
++// OID_802_11_DISASSOCIATE
++s8 sme_set_disassociate(void *pcore_data);
++
++// OID_802_11_POWER_MODE
++s8 sme_get_power_mode(void *pcore_data, u8 *pmode);
++s8 sme_set_power_mode(void *pcore_data, u8 mode);
++
++// OID_802_11_BSSID_LIST_SCAN
++s8 sme_set_bssid_list_scan(void *pcore_data, void *pscan_para);
++
++// OID_802_11_RELOAD_DEFAULTS
++s8 sme_set_reload_defaults(void *pcore_data, u8 reload_type);
++
++
++// The following SME API functions are used for WPA
++//
++// Mandatory OIDs for WPA
++//
++
++// OID_802_11_ADD_KEY
++//s8 sme_set_add_key(void *pcore_data, NDIS_802_11_KEY *pkey);
++
++// OID_802_11_REMOVE_KEY
++//s8 sme_set_remove_key(void *pcore_data, NDIS_802_11_REMOVE_KEY *pkey);
++
++// OID_802_11_ASSOCIATION_INFORMATION
++//s8 sme_set_association_information(void *pcore_data,
++// NDIS_802_11_ASSOCIATION_INFORMATION *pinfo);
++
++// OID_802_11_TEST
++//s8 sme_set_test(void *pcore_data, NDIS_802_11_TEST *ptest_data);
++
++//--------------------------------------------------------------------------//
++/*
++// The left OIDs
++
++// OID_802_11_NETWORK_TYPES_SUPPORTED
++// OID_802_11_TX_POWER_LEVEL
++// OID_802_11_RSSI_TRIGGER
++// OID_802_11_NUMBER_OF_ANTENNAS
++// OID_802_11_RX_ANTENNA_SELECTED
++// OID_802_11_TX_ANTENNA_SELECTED
++// OID_802_11_STATISTICS
++// OID_802_11_DESIRED_RATES
++// OID_802_11_PRIVACY_FILTER
++
++*/
++
++/*------------------------- none-standard ----------------------------------*/
++s8 sme_get_connect_status(void *pcore_data, u8 *pstatus);
++
++/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
++//s8 sme_get_scan_type(void *pcore_data, u8 *pscan_type);
++//s8 sme_set_scan_type(void *pcore_data, u8 scan_type);
++
++//s8 sme_get_scan_channel_list(void *pcore_data, u8 *pscan_type);
++//s8 sme_set_scan_channel_list(void *pcore_data, u8 scan_type);
++
++
++void sme_get_encryption_status(void *pcore_data, u8 *EncryptStatus);
++void sme_set_encryption_status(void *pcore_data, u8 EncryptStatus);
++s8 sme_add_key(void *pcore_data,
++ u32 key_index,
++ u8 key_len,
++ u8 key_type,
++ u8 *key_bssid,
++ //u8 *key_rsc,
++ u8 *ptx_tsc,
++ u8 *prx_tsc,
++ u8 *key_material);
++void sme_remove_default_key(void *pcore_data, int index);
++void sme_remove_mapping_key(void *pcore_data, u8 *pmac_addr);
++void sme_clear_all_mapping_key(void *pcore_data);
++void sme_clear_all_default_key(void *pcore_data);
++
++
++
++s8 sme_set_preamble_mode(void *pcore_data, u8 mode);
++s8 sme_get_preamble_mode(void *pcore_data, u8 *mode);
++s8 sme_get_preamble_type(void *pcore_data, u8 *type);
++s8 sme_set_slottime_mode(void *pcore_data, u8 mode);
++s8 sme_get_slottime_mode(void *pcore_data, u8 *mode);
++s8 sme_get_slottime_type(void *pcore_data, u8 *type);
++s8 sme_set_txrate_policy(void *pcore_data, u8 policy);
++s8 sme_get_txrate_policy(void *pcore_data, u8 *policy);
++s8 sme_get_cwmin_value(void *pcore_data, u8 *cwmin);
++s8 sme_get_cwmax_value(void *pcore_data, u16 *cwmax);
++s8 sme_get_ms_radio_mode(void *pcore_data, u8 * pMsRadioOff);
++s8 sme_set_ms_radio_mode(void *pcore_data, u8 boMsRadioOff);
++s8 sme_get_radio_mode(void *pcore_data, psRadioOff pRadioOffData);
++s8 sme_set_radio_mode(void *pcore_data, RadioOff RadioOffData);
++
++void sme_get_tx_power_level(void *pcore_data, u32 *TxPower);
++u8 sme_set_tx_power_level(void *pcore_data, u32 TxPower);
++void sme_get_antenna_count(void *pcore_data, u32 *AntennaCount);
++void sme_get_rx_antenna(void *pcore_data, u32 *RxAntenna);
++u8 sme_set_rx_antenna(void *pcore_data, u32 RxAntenna);
++void sme_get_tx_antenna(void *pcore_data, u32 *TxAntenna);
++s8 sme_set_tx_antenna(void *pcore_data, u32 TxAntenna);
++s8 sme_set_IBSS_chan(void *pcore_data, ChanInfo chan);
++
++//20061108 WPS
++s8 sme_set_IE_append(void *pcore_data, PUCHAR buffer, u16 buf_len);
++
++
++
++
++//================== Local functions ======================
++//#ifdef _HSINCHU
++//void drv_translate_rssi(); // HW RSSI bit -> NDIS RSSI representation
++//void drv_translate_bss_description(); // Local bss desc -> NDIS bss desc
++//void drv_translate_channel(u8 NetworkType, u8 ChannelNumber, u32 *freq); // channel number -> channel /freq.
++//#endif _HSINCHU
++//
++static const u32 PowerDbToMw[] =
++{
++ 56, //mW, MAX - 0, 17.5 dbm
++ 40, //mW, MAX - 1, 16.0 dbm
++ 30, //mW, MAX - 2, 14.8 dbm
++ 20, //mW, MAX - 3, 13.0 dbm
++ 15, //mW, MAX - 4, 11.8 dbm
++ 12, //mW, MAX - 5, 10.6 dbm
++ 9, //mW, MAX - 6, 9.4 dbm
++ 7, //mW, MAX - 7, 8.3 dbm
++ 5, //mW, MAX - 8, 6.4 dbm
++ 4, //mW, MAX - 9, 5.3 dbm
++ 3, //mW, MAX - 10, 4.0 dbm
++ 2, //mW, MAX - 11, ? dbm
++ 2, //mW, MAX - 12, ? dbm
++ 2, //mW, MAX - 13, ? dbm
++ 2, //mW, MAX - 14, ? dbm
++ 2, //mW, MAX - 15, ? dbm
++ 2, //mW, MAX - 16, ? dbm
++ 2, //mW, MAX - 17, ? dbm
++ 2, //mW, MAX - 18, ? dbm
++ 1, //mW, MAX - 19, ? dbm
++ 1, //mW, MAX - 20, ? dbm
++ 1, //mW, MAX - 21, ? dbm
++ 1, //mW, MAX - 22, ? dbm
++ 1, //mW, MAX - 23, ? dbm
++ 1, //mW, MAX - 24, ? dbm
++ 1, //mW, MAX - 25, ? dbm
++ 1, //mW, MAX - 26, ? dbm
++ 1, //mW, MAX - 27, ? dbm
++ 1, //mW, MAX - 28, ? dbm
++ 1, //mW, MAX - 29, ? dbm
++ 1, //mW, MAX - 30, ? dbm
++ 1 //mW, MAX - 31, ? dbm
++};
++
++
++
++
++
++#endif /* __SME_API_H__ */
++
++
+diff --git a/drivers/staging/winbond/sme_s.h b/drivers/staging/winbond/sme_s.h
+new file mode 100644
+index 0000000..dfd2fbc
+--- /dev/null
++++ b/drivers/staging/winbond/sme_s.h
+@@ -0,0 +1,228 @@
++//
++// SME_S.H -
++// SME task global CONSTANTS, STRUCTURES, variables
++//
++
++//////////////////////////////////////////////////////////////////////////
++//define the msg type of SME module
++// 0x00~0x1F : MSG from GUI dispatch
++// 0x20~0x3F : MSG from MLME
++// 0x40~0x5F : MSG from SCAN
++// 0x60~0x6F : MSG from TX/RX
++// 0x70~0x7F : MSG from ROAMING
++// 0x80~0x8F : MSG from ISR
++// 0x90 : MSG TimeOut
++
++// from GUI
++#define SMEMSG_SCAN_REQ 0x01
++//#define SMEMSG_PASSIVE_SCAN_REQ 0x02
++#define SMEMSG_JOIN_REQ 0x03
++#define SMEMSG_START_IBSS 0x04
++#define SMEMSG_DISCONNECT_REQ 0x05
++#define SMEMSG_AUTHEN_REQ 0x06
++#define SMEMSG_DEAUTHEN_REQ 0x07
++#define SMEMSG_ASSOC_REQ 0x08
++#define SMEMSG_REASSOC_REQ 0x09
++#define SMEMSG_DISASSOC_REQ 0x0a
++#define SMEMSG_POWERSAVE_REQ 0x0b
++
++
++// from MLME
++#define SMEMSG_AUTHEN_CFM 0x21
++#define SMEMSG_AUTHEN_IND 0x22
++#define SMEMSG_ASSOC_CFM 0x23
++#define SMEMSG_DEAUTHEN_IND 0x24
++#define SMEMSG_DISASSOC_IND 0x25
++// from SCAN
++#define SMEMSG_SCAN_CFM 0x41
++#define SMEMSG_START_IBSS_CFM 0x42
++// from MTO, function call to set SME parameters
++
++// 0x60~0x6F : MSG from TX/RX
++//#define SMEMSG_IBSS_JOIN_UPDATE_BSSID 0x61
++#define SMEMSG_COUNTERMEASURE_MICFAIL_TIMEOUT 0x62
++#define SMEMSG_COUNTERMEASURE_BLOCK_TIMEOUT 0x63
++// from ROAMING
++#define SMEMSG_HANDOVER_JOIN_REQ 0x71
++#define SMEMSG_END_ROAMING 0x72
++#define SMEMSG_SCAN_JOIN_REQ 0x73
++// from ISR
++#define SMEMSG_TSF_SYNC_IND 0x81
++// from TimeOut
++#define SMEMSG_TIMEOUT 0x91
++
++
++
++#define MAX_PMKID_Accunt 16
++//@added by ws 04/22/05
++#define Cipher_Disabled 0
++#define Cipher_Wep 1
++#define Cipher_Tkip 2
++#define Cipher_Ccmp 4
++
++
++///////////////////////////////////////////////////////////////////////////
++//Constants
++
++///////////////////////////////////////////////////////////////////////////
++//Global data structures
++
++#define NUMOFWEPENTRIES 64
++
++typedef enum _WEPKeyMode
++{
++ WEPKEY_DISABLED = 0,
++ WEPKEY_64 = 1,
++ WEPKEY_128 = 2
++
++} WEPKEYMODE, *pWEPKEYMODE;
++
++#ifdef _WPA2_
++
++typedef struct _BSSInfo
++{
++ u8 PreAuthBssID[6];
++ PMKID pmkid_value;
++}BSSID_Info;
++
++typedef struct _PMKID_Table //added by ws 05/05/04
++{
++ u32 Length;
++ u32 BSSIDInfoCount;
++ BSSID_Info BSSIDInfo[16];
++
++} PMKID_Table;
++
++#endif //end def _WPA2_
++
++#define MAX_BASIC_RATE_SET 15
++#define MAX_OPT_RATE_SET MAX_BASIC_RATE_SET
++
++
++typedef struct _SME_PARAMETERS
++{
++ u16 wState;
++ u8 boDUTmode;
++ u8 bDesiredPowerSave;
++
++ // SME timer and timeout value
++ //NDIS_MINIPORT_TIMER nTimer;
++ OS_TIMER nTimer;
++
++ u8 boInTimerHandler;
++ u8 boAuthRetryActive;
++ u8 reserved_0[2];
++
++ u32 AuthenRetryTimerVal; // NOTE: Assoc don't fail timeout
++ u32 JoinFailTimerVal; // 10*Beacon-Interval
++
++ //Rates
++ u8 BSSBasicRateSet[(MAX_BASIC_RATE_SET + 3) & ~0x03 ]; // BSS basic rate set
++ u8 OperationalRateSet[(MAX_OPT_RATE_SET + 3) & ~0x03 ]; // Operational rate set
++
++ u8 NumOfBSSBasicRate;
++ u8 NumOfOperationalRate;
++ u8 reserved_1[2];
++
++ u32 BasicRateBitmap;
++ u32 OpRateBitmap;
++
++ // System parameters Set by GUI
++ //-------------------- start IBSS parameter ---------------------------//
++ u32 boStartIBSS; //Start IBSS toggle
++
++ u16 wBeaconPeriod;
++ u16 wATIM_Window;
++
++ ChanInfo IbssChan; // 2B //channel setting when start IBSS
++ u8 reserved_2[2];
++
++ // Join related
++ u16 wDesiredJoinBSS; // BSS index which desire to join
++ u8 boJoinReq; //Join request toggle
++ u8 bDesiredBSSType; //for Join request
++
++ u16 wCapabilityInfo; // Used when invoking the MLME_Associate_request().
++ u16 wNonERPcapabilityInfo;
++
++ struct SSID_Element sDesiredSSID; // 34 B
++ u8 reserved_3[2];
++
++ u8 abDesiredBSSID[MAC_ADDR_LENGTH + 2];
++
++ u8 bJoinScanCount; // the time of scan-join action need to do
++ u8 bDesiredAuthMode; // AUTH_OPEN_SYSTEM or AUTH_SHARED_KEY
++ u8 reserved_4[2];
++
++ // Encryption parameters
++ u8 _dot11PrivacyInvoked;
++ u8 _dot11PrivacyOptionImplemented;
++ u8 reserved_5[2];
++
++ //@ ws added
++ u8 DesiredEncrypt;
++ u8 encrypt_status; //ENCRYPT_DISABLE, ENCRYPT_WEP, ENCRYPT_WEP_NOKEY, ENCRYPT_TKIP, ...
++ u8 key_length;
++ u8 pairwise_key_ok;
++
++ u8 group_key_ok;
++ u8 wpa_ok; // indicate the control port of 802.1x is open or close
++ u8 pairwise_key_type;
++ u8 group_key_type;
++
++ u32 _dot11WEPDefaultKeyID;
++
++ u8 tx_mic_key[8]; // TODO: 0627 kevin-TKIP
++ u8 rx_mic_key[8]; // TODO: 0627 kevin-TKIP
++ u8 group_tx_mic_key[8];
++ u8 group_rx_mic_key[8];
++
++// #ifdef _WPA_
++ u8 AssocReqVarIE[200];
++ u8 AssocRespVarIE[200];
++
++ u16 AssocReqVarLen;
++ u16 AssocRespVarLen;
++ u8 boReassoc; //use assoc. or reassoc.
++ u8 reserved_6[3];
++ u16 AssocRespCapability;
++ u16 AssocRespStatus;
++// #endif
++
++ #ifdef _WPA2_
++ u8 PmkIdTable[256];
++ u32 PmkidTableIndex;
++ #endif //end def _WPA2_
++
++} SME_PARAMETERS, *PSME_PARAMETERS;
++
++#define psSME (&(Adapter->sSmePara))
++
++#define wSMEGetCurrentSTAState(Adapter) ((u16)(Adapter)->sSmePara.wState)
++
++
++
++//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++// SmeModule.h
++// Define the related definitions of SME module
++// history -- 01/14/03' created
++//
++//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++
++//Define the state of SME module
++#define DISABLED 0
++#define INIT_SCAN 1
++#define SCAN_READY 2
++#define START_IBSS 3
++#define JOIN_PENDING 4
++#define JOIN_CFM 5
++#define AUTHENTICATE_PENDING 6
++#define AUTHENTICATED 7
++#define CONNECTED 8
++//#define EAP_STARTING 9
++//#define EAPOL_AUTHEN_PENDING 10
++//#define SECURE_CONNECTED 11
++
++
++// Static function
++
+diff --git a/drivers/staging/winbond/wb35_ver.h b/drivers/staging/winbond/wb35_ver.h
+new file mode 100644
+index 0000000..2433bc0
+--- /dev/null
++++ b/drivers/staging/winbond/wb35_ver.h
+@@ -0,0 +1,30 @@
++//
++// Only define one of follow
++//
++
++#ifdef WB_WIN
++ #define VER_FILEVERSION 1,00,47,00
++ #define VER_FILEVERSION_STR "1.00.47.00"
++ #define WB32_DRIVER_MAJOR_VERSION 0x0100
++ #define WB32_DRIVER_MINOR_VERSION 0x4700
++#endif
++
++#ifdef WB_CE
++ #define VER_FILEVERSION 2,00,47,00
++ #define VER_FILEVERSION_STR "2.00.47.00"
++ #define WB32_DRIVER_MAJOR_VERSION 0x0200
++ #define WB32_DRIVER_MINOR_VERSION 0x4700
++#endif
++
++#ifdef WB_LINUX
++ #define VER_FILEVERSION 3,00,47,00
++ #define VER_FILEVERSION_STR "3.00.47.00"
++ #define WB32_DRIVER_MAJOR_VERSION 0x0300
++ #define WB32_DRIVER_MINOR_VERSION 0x4700
++#endif
++
++
++
++
++
++
+diff --git a/drivers/staging/winbond/wbhal.c b/drivers/staging/winbond/wbhal.c
+new file mode 100644
+index 0000000..daf4422
+--- /dev/null
++++ b/drivers/staging/winbond/wbhal.c
+@@ -0,0 +1,878 @@
++#include "os_common.h"
++
++void hal_get_ethernet_address( phw_data_t pHwData, PUCHAR current_address )
++{
++ if( pHwData->SurpriseRemove ) return;
++
++ memcpy( current_address, pHwData->CurrentMacAddress, ETH_LENGTH_OF_ADDRESS );
++}
++
++void hal_set_ethernet_address( phw_data_t pHwData, PUCHAR current_address )
++{
++ u32 ltmp[2];
++
++ if( pHwData->SurpriseRemove ) return;
++
++ memcpy( pHwData->CurrentMacAddress, current_address, ETH_LENGTH_OF_ADDRESS );
++
++ ltmp[0]= cpu_to_le32( *(PULONG)pHwData->CurrentMacAddress );
++ ltmp[1]= cpu_to_le32( *(PULONG)(pHwData->CurrentMacAddress + 4) ) & 0xffff;
++
++ Wb35Reg_BurstWrite( pHwData, 0x03e8, ltmp, 2, AUTO_INCREMENT );
++}
++
++void hal_get_permanent_address( phw_data_t pHwData, PUCHAR pethernet_address )
++{
++ if( pHwData->SurpriseRemove ) return;
++
++ memcpy( pethernet_address, pHwData->PermanentMacAddress, 6 );
++}
++
++u8 hal_init_hardware(phw_data_t pHwData, PWB32_ADAPTER Adapter)
++{
++ u16 SoftwareSet;
++ pHwData->Adapter = Adapter;
++
++ // Initial the variable
++ pHwData->MaxReceiveLifeTime = DEFAULT_MSDU_LIFE_TIME; // Setting Rx maximum MSDU life time
++ pHwData->FragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD; // Setting default fragment threshold
++
++ if (WbUsb_initial(pHwData)) {
++ pHwData->InitialResource = 1;
++ if( Wb35Reg_initial(pHwData)) {
++ pHwData->InitialResource = 2;
++ if (Wb35Tx_initial(pHwData)) {
++ pHwData->InitialResource = 3;
++ if (Wb35Rx_initial(pHwData)) {
++ pHwData->InitialResource = 4;
++ OS_TIMER_INITIAL( &pHwData->LEDTimer, hal_led_control, pHwData );
++ OS_TIMER_SET( &pHwData->LEDTimer, 1000 ); // 20060623
++
++ //
++ // For restrict to vendor's hardware
++ //
++ SoftwareSet = hal_software_set( pHwData );
++
++ #ifdef Vendor2
++ // Try to make sure the EEPROM contain
++ SoftwareSet >>= 8;
++ if( SoftwareSet != 0x82 )
++ return FALSE;
++ #endif
++
++ Wb35Rx_start( pHwData );
++ Wb35Tx_EP2VM_start( pHwData );
++
++ return TRUE;
++ }
++ }
++ }
++ }
++
++ pHwData->SurpriseRemove = 1;
++ return FALSE;
++}
++
++
++void hal_halt(phw_data_t pHwData, void *ppa_data)
++{
++ switch( pHwData->InitialResource )
++ {
++ case 4:
++ case 3: OS_TIMER_CANCEL( &pHwData->LEDTimer, &cancel );
++ OS_SLEEP(100000); // Wait for Timer DPC exit 940623.2
++ Wb35Rx_destroy( pHwData ); // Release the Rx
++ case 2: Wb35Tx_destroy( pHwData ); // Release the Tx
++ case 1: Wb35Reg_destroy( pHwData ); // Release the Wb35 Regisster resources
++ WbUsb_destroy( pHwData );// Release the WbUsb
++ }
++}
++
++//---------------------------------------------------------------------------------------------------
++void hal_set_rates(phw_data_t pHwData, PUCHAR pbss_rates,
++ u8 length, unsigned char basic_rate_set)
++{
++ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
++ u32 tmp, tmp1;
++ u8 Rate[12]={ 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 };
++ u8 SupportedRate[16];
++ u8 i, j, k, Count1, Count2, Byte;
++
++ if( pHwData->SurpriseRemove ) return;
++
++ if (basic_rate_set) {
++ pWb35Reg->M28_MacControl &= ~0x000fff00;
++ tmp1 = 0x00000100;
++ } else {
++ pWb35Reg->M28_MacControl &= ~0xfff00000;
++ tmp1 = 0x00100000;
++ }
++
++ tmp = 0;
++ for (i=0; i<length; i++) {
++ Byte = pbss_rates[i] & 0x7f;
++ for (j=0; j<12; j++) {
++ if( Byte == Rate[j] )
++ break;
++ }
++
++ if (j < 12)
++ tmp |= (tmp1<<j);
++ }
++
++ pWb35Reg->M28_MacControl |= tmp;
++ Wb35Reg_Write( pHwData, 0x0828, pWb35Reg->M28_MacControl );
++
++ // 930206.2.c M78 setting
++ j = k = Count1 = Count2 = 0;
++ memset( SupportedRate, 0, 16 );
++ tmp = 0x00100000;
++ tmp1 = 0x00000100;
++ for (i=0; i<12; i++) { // Get the supported rate
++ if (tmp & pWb35Reg->M28_MacControl) {
++ SupportedRate[j] = Rate[i];
++
++ if (tmp1 & pWb35Reg->M28_MacControl)
++ SupportedRate[j] |= 0x80;
++
++ if (k)
++ Count2++;
++ else
++ Count1++;
++
++ j++;
++ }
++
++ if (i==4 && k==0) {
++ if( !(pWb35Reg->M28_MacControl & 0x000ff000) ) // if basic rate in 11g domain)
++ {
++ k = 1;
++ j = 8;
++ }
++ }
++
++ tmp <<= 1;
++ tmp1 <<= 1;
++ }
++
++ // Fill data into support rate until buffer full
++ //---20060926 add by anson's endian
++ for (i=0; i<4; i++)
++ *(PULONG)(SupportedRate+(i<<2)) = cpu_to_le32( *(PULONG)(SupportedRate+(i<<2)) );
++ //--- end 20060926 add by anson's endian
++ Wb35Reg_BurstWrite( pHwData,0x087c, (PULONG)SupportedRate, 4, AUTO_INCREMENT );
++ pWb35Reg->M7C_MacControl = ((PULONG)SupportedRate)[0];
++ pWb35Reg->M80_MacControl = ((PULONG)SupportedRate)[1];
++ pWb35Reg->M84_MacControl = ((PULONG)SupportedRate)[2];
++ pWb35Reg->M88_MacControl = ((PULONG)SupportedRate)[3];
++
++ // Fill length
++ tmp = Count1<<28 | Count2<<24;
++ pWb35Reg->M78_ERPInformation &= ~0xff000000;
++ pWb35Reg->M78_ERPInformation |= tmp;
++ Wb35Reg_Write( pHwData, 0x0878, pWb35Reg->M78_ERPInformation );
++}
++
++
++//---------------------------------------------------------------------------------------------------
++void hal_set_beacon_period( phw_data_t pHwData, u16 beacon_period )
++{
++ u32 tmp;
++
++ if( pHwData->SurpriseRemove ) return;
++
++ pHwData->BeaconPeriod = beacon_period;
++ tmp = pHwData->BeaconPeriod << 16;
++ tmp |= pHwData->ProbeDelay;
++ Wb35Reg_Write( pHwData, 0x0848, tmp );
++}
++
++
++void hal_set_current_channel_ex( phw_data_t pHwData, ChanInfo channel )
++{
++ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
++
++ if( pHwData->SurpriseRemove )
++ return;
++
++ printk("Going to channel: %d/%d\n", channel.band, channel.ChanNo);
++
++ RFSynthesizer_SwitchingChannel( pHwData, channel );// Switch channel
++ pHwData->Channel = channel.ChanNo;
++ pHwData->band = channel.band;
++ #ifdef _PE_STATE_DUMP_
++ WBDEBUG(("Set channel is %d, band =%d\n", pHwData->Channel, pHwData->band));
++ #endif
++ pWb35Reg->M28_MacControl &= ~0xff; // Clean channel information field
++ pWb35Reg->M28_MacControl |= channel.ChanNo;
++ Wb35Reg_WriteWithCallbackValue( pHwData, 0x0828, pWb35Reg->M28_MacControl,
++ (PCHAR)&channel, sizeof(ChanInfo));
++}
++//---------------------------------------------------------------------------------------------------
++void hal_set_current_channel( phw_data_t pHwData, ChanInfo channel )
++{
++ hal_set_current_channel_ex( pHwData, channel );
++}
++//---------------------------------------------------------------------------------------------------
++void hal_get_current_channel( phw_data_t pHwData, ChanInfo *channel )
++{
++ channel->ChanNo = pHwData->Channel;
++ channel->band = pHwData->band;
++}
++//---------------------------------------------------------------------------------------------------
++void hal_set_accept_broadcast( phw_data_t pHwData, u8 enable )
++{
++ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
++
++ if( pHwData->SurpriseRemove ) return;
++
++ pWb35Reg->M00_MacControl &= ~0x02000000;//The HW value
++
++ if (enable)
++ pWb35Reg->M00_MacControl |= 0x02000000;//The HW value
++
++ Wb35Reg_Write( pHwData, 0x0800, pWb35Reg->M00_MacControl );
++}
++
++//for wep key error detection, we need to accept broadcast packets to be received temporary.
++void hal_set_accept_promiscuous( phw_data_t pHwData, u8 enable)
++{
++ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
++
++ if (pHwData->SurpriseRemove) return;
++ if (enable) {
++ pWb35Reg->M00_MacControl |= 0x00400000;
++ Wb35Reg_Write( pHwData, 0x0800, pWb35Reg->M00_MacControl );
++ } else {
++ pWb35Reg->M00_MacControl&=~0x00400000;
++ Wb35Reg_Write( pHwData, 0x0800, pWb35Reg->M00_MacControl );
++ }
++}
++
++void hal_set_accept_multicast( phw_data_t pHwData, u8 enable )
++{
++ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
++
++ if( pHwData->SurpriseRemove ) return;
++
++ pWb35Reg->M00_MacControl &= ~0x01000000;//The HW value
++ if (enable) pWb35Reg->M00_MacControl |= 0x01000000;//The HW value
++ Wb35Reg_Write( pHwData, 0x0800, pWb35Reg->M00_MacControl );
++}
++
++void hal_set_accept_beacon( phw_data_t pHwData, u8 enable )
++{
++ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
++
++ if( pHwData->SurpriseRemove ) return;
++
++ // 20040108 debug
++ if( !enable )//Due to SME and MLME are not suitable for 35
++ return;
++
++ pWb35Reg->M00_MacControl &= ~0x04000000;//The HW value
++ if( enable )
++ pWb35Reg->M00_MacControl |= 0x04000000;//The HW value
++
++ Wb35Reg_Write( pHwData, 0x0800, pWb35Reg->M00_MacControl );
++}
++//---------------------------------------------------------------------------------------------------
++void hal_set_multicast_address( phw_data_t pHwData, PUCHAR address, u8 number )
++{
++ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
++ u8 Byte, Bit;
++
++ if( pHwData->SurpriseRemove ) return;
++
++ //Erases and refills the card multicast registers. Used when an address
++ // has been deleted and all bits must be recomputed.
++ pWb35Reg->M04_MulticastAddress1 = 0;
++ pWb35Reg->M08_MulticastAddress2 = 0;
++
++ while( number )
++ {
++ number--;
++ CardGetMulticastBit( (address+(number*ETH_LENGTH_OF_ADDRESS)), &Byte, &Bit);
++ pWb35Reg->Multicast[Byte] |= Bit;
++ }
++
++ // Updating register
++ Wb35Reg_BurstWrite( pHwData, 0x0804, (PULONG)pWb35Reg->Multicast, 2, AUTO_INCREMENT );
++}
++//---------------------------------------------------------------------------------------------------
++u8 hal_get_accept_beacon( phw_data_t pHwData )
++{
++ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
++
++ if( pHwData->SurpriseRemove ) return 0;
++
++ if( pWb35Reg->M00_MacControl & 0x04000000 )
++ return 1;
++ else
++ return 0;
++}
++
++unsigned char hal_reset_hardware( phw_data_t pHwData, void* ppa )
++{
++ // Not implement yet
++ return TRUE;
++}
++
++void hal_stop( phw_data_t pHwData )
++{
++ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
++
++ pHwData->Wb35Rx.rx_halt = 1;
++ Wb35Rx_stop( pHwData );
++
++ pHwData->Wb35Tx.tx_halt = 1;
++ Wb35Tx_stop( pHwData );
++
++ pWb35Reg->D00_DmaControl &= ~0xc0000000;//Tx Off, Rx Off
++ Wb35Reg_Write( pHwData, 0x0400, pWb35Reg->D00_DmaControl );
++
++ WbUsb_Stop( pHwData ); // 20051230 Add.4
++}
++
++unsigned char hal_idle(phw_data_t pHwData)
++{
++ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
++ PWBUSB pWbUsb = &pHwData->WbUsb;
++
++ if( !pHwData->SurpriseRemove && ( pWbUsb->DetectCount || pWb35Reg->EP0vm_state!=VM_STOP ) )
++ return FALSE;
++
++ return TRUE;
++}
++//---------------------------------------------------------------------------------------------------
++void hal_set_cwmin( phw_data_t pHwData, u8 cwin_min )
++{
++ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
++
++ if( pHwData->SurpriseRemove ) return;
++
++ pHwData->cwmin = cwin_min;
++ pWb35Reg->M2C_MacControl &= ~0x7c00; //bit 10 ~ 14
++ pWb35Reg->M2C_MacControl |= (pHwData->cwmin<<10);
++ Wb35Reg_Write( pHwData, 0x082c, pWb35Reg->M2C_MacControl );
++}
++
++s32 hal_get_rssi( phw_data_t pHwData, u32 *HalRssiArry, u8 Count )
++{
++ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
++ R01_DESCRIPTOR r01;
++ s32 ltmp = 0, tmp;
++ u8 i;
++
++ if( pHwData->SurpriseRemove ) return -200;
++ if( Count > MAX_ACC_RSSI_COUNT ) // Because the TS may use this funtion
++ Count = MAX_ACC_RSSI_COUNT;
++
++ // RSSI = C1 + C2 * (agc_state[7:0] + offset_map(lna_state[1:0]))
++ // C1 = -195, C2 = 0.66 = 85/128
++ for (i=0; i<Count; i++)
++ {
++ r01.value = HalRssiArry[i];
++ tmp = ((( r01.R01_AGC_state + pWb35Reg->LNAValue[r01.R01_LNA_state]) * 85 ) >>7 ) - 195;
++ ltmp += tmp;
++ }
++ ltmp /= Count;
++ if( pHwData->phy_type == RF_AIROHA_2230 ) ltmp -= 5; // 10;
++ if( pHwData->phy_type == RF_AIROHA_2230S ) ltmp -= 5; // 10; 20060420 Add this
++
++ //if( ltmp < -200 ) ltmp = -200;
++ if( ltmp < -110 ) ltmp = -110;// 1.0.24.0 For NJRC
++
++ return ltmp;
++}
++//----------------------------------------------------------------------------------------------------
++s32 hal_get_rssi_bss( phw_data_t pHwData, u16 idx, u8 Count )
++{
++ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
++ R01_DESCRIPTOR r01;
++ s32 ltmp = 0, tmp;
++ u8 i, j;
++ PADAPTER Adapter = pHwData->Adapter;
++// u32 *HalRssiArry = psBSS(idx)->HalRssi;
++
++ if( pHwData->SurpriseRemove ) return -200;
++ if( Count > MAX_ACC_RSSI_COUNT ) // Because the TS may use this funtion
++ Count = MAX_ACC_RSSI_COUNT;
++
++ // RSSI = C1 + C2 * (agc_state[7:0] + offset_map(lna_state[1:0]))
++ // C1 = -195, C2 = 0.66 = 85/128
++#if 0
++ for (i=0; i<Count; i++)
++ {
++ r01.value = HalRssiArry[i];
++ tmp = ((( r01.R01_AGC_state + pWb35Reg->LNAValue[r01.R01_LNA_state]) * 85 ) >>7 ) - 195;
++ ltmp += tmp;
++ }
++#else
++ if (psBSS(idx)->HalRssiIndex == 0)
++ psBSS(idx)->HalRssiIndex = MAX_ACC_RSSI_COUNT;
++ j = (u8)psBSS(idx)->HalRssiIndex-1;
++
++ for (i=0; i<Count; i++)
++ {
++ r01.value = psBSS(idx)->HalRssi[j];
++ tmp = ((( r01.R01_AGC_state + pWb35Reg->LNAValue[r01.R01_LNA_state]) * 85 ) >>7 ) - 195;
++ ltmp += tmp;
++ if (j == 0)
++ {
++ j = MAX_ACC_RSSI_COUNT;
++ }
++ j--;
++ }
++#endif
++ ltmp /= Count;
++ if( pHwData->phy_type == RF_AIROHA_2230 ) ltmp -= 5; // 10;
++ if( pHwData->phy_type == RF_AIROHA_2230S ) ltmp -= 5; // 10; 20060420 Add this
++
++ //if( ltmp < -200 ) ltmp = -200;
++ if( ltmp < -110 ) ltmp = -110;// 1.0.24.0 For NJRC
++
++ return ltmp;
++}
++
++//---------------------------------------------------------------------------
++void hal_led_control_1a( phw_data_t pHwData )
++{
++ hal_led_control( NULL, pHwData, NULL, NULL );
++}
++
++void hal_led_control( void* S1, phw_data_t pHwData, void* S3, void* S4 )
++{
++ PADAPTER Adapter = pHwData->Adapter;
++ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
++ u32 LEDSet = (pHwData->SoftwareSet & HAL_LED_SET_MASK) >> HAL_LED_SET_SHIFT;
++ u8 LEDgray[20] = { 0,3,4,6,8,10,11,12,13,14,15,14,13,12,11,10,8,6,4,2 };
++ u8 LEDgray2[30] = { 7,8,9,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0,0,0,0,0,15,14,13,12,11,10,9,8 };
++ u32 TimeInterval = 500, ltmp, ltmp2;
++ ltmp=0;
++
++ if( pHwData->SurpriseRemove ) return;
++
++ if( pHwData->LED_control ) {
++ ltmp2 = pHwData->LED_control & 0xff;
++ if( ltmp2 == 5 ) // 5 is WPS mode
++ {
++ TimeInterval = 100;
++ ltmp2 = (pHwData->LED_control>>8) & 0xff;
++ switch( ltmp2 )
++ {
++ case 1: // [0.2 On][0.1 Off]...
++ pHwData->LED_Blinking %= 3;
++ ltmp = 0x1010; // Led 1 & 0 Green and Red
++ if( pHwData->LED_Blinking == 2 ) // Turn off
++ ltmp = 0;
++ break;
++ case 2: // [0.1 On][0.1 Off]...
++ pHwData->LED_Blinking %= 2;
++ ltmp = 0x0010; // Led 0 red color
++ if( pHwData->LED_Blinking ) // Turn off
++ ltmp = 0;
++ break;
++ case 3: // [0.1 On][0.1 Off][0.1 On][0.1 Off][0.1 On][0.1 Off][0.1 On][0.1 Off][0.1 On][0.1 Off][0.5 Off]...
++ pHwData->LED_Blinking %= 15;
++ ltmp = 0x0010; // Led 0 red color
++ if( (pHwData->LED_Blinking >= 9) || (pHwData->LED_Blinking%2) ) // Turn off 0.6 sec
++ ltmp = 0;
++ break;
++ case 4: // [300 On][ off ]
++ ltmp = 0x1000; // Led 1 Green color
++ if( pHwData->LED_Blinking >= 3000 )
++ ltmp = 0; // led maybe on after 300sec * 32bit counter overlap.
++ break;
++ }
++ pHwData->LED_Blinking++;
++
++ pWb35Reg->U1BC_LEDConfigure = ltmp;
++ if( LEDSet != 7 ) // Only 111 mode has 2 LEDs on PCB.
++ {
++ pWb35Reg->U1BC_LEDConfigure |= (ltmp &0xff)<<8; // Copy LED result to each LED control register
++ pWb35Reg->U1BC_LEDConfigure |= (ltmp &0xff00)>>8;
++ }
++ Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure );
++ }
++ }
++ else if( pHwData->CurrentRadioSw || pHwData->CurrentRadioHw ) // If radio off
++ {
++ if( pWb35Reg->U1BC_LEDConfigure & 0x1010 )
++ {
++ pWb35Reg->U1BC_LEDConfigure &= ~0x1010;
++ Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure );
++ }
++ }
++ else
++ {
++ switch( LEDSet )
++ {
++ case 4: // [100] Only 1 Led be placed on PCB and use pin 21 of IC. Use LED_0 for showing
++ if( !pHwData->LED_LinkOn ) // Blink only if not Link On
++ {
++ // Blinking if scanning is on progress
++ if( pHwData->LED_Scanning )
++ {
++ if( pHwData->LED_Blinking == 0 )
++ {
++ pWb35Reg->U1BC_LEDConfigure |= 0x10;
++ Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_0 On
++ pHwData->LED_Blinking = 1;
++ TimeInterval = 300;
++ }
++ else
++ {
++ pWb35Reg->U1BC_LEDConfigure &= ~0x10;
++ Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_0 Off
++ pHwData->LED_Blinking = 0;
++ TimeInterval = 300;
++ }
++ }
++ else
++ {
++ //Turn Off LED_0
++ if( pWb35Reg->U1BC_LEDConfigure & 0x10 )
++ {
++ pWb35Reg->U1BC_LEDConfigure &= ~0x10;
++ Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_0 Off
++ }
++ }
++ }
++ else
++ {
++ // Turn On LED_0
++ if( (pWb35Reg->U1BC_LEDConfigure & 0x10) == 0 )
++ {
++ pWb35Reg->U1BC_LEDConfigure |= 0x10;
++ Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_0 Off
++ }
++ }
++ break;
++
++ case 6: // [110] Only 1 Led be placed on PCB and use pin 21 of IC. Use LED_0 for showing
++ if( !pHwData->LED_LinkOn ) // Blink only if not Link On
++ {
++ // Blinking if scanning is on progress
++ if( pHwData->LED_Scanning )
++ {
++ if( pHwData->LED_Blinking == 0 )
++ {
++ pWb35Reg->U1BC_LEDConfigure &= ~0xf;
++ pWb35Reg->U1BC_LEDConfigure |= 0x10;
++ Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_0 On
++ pHwData->LED_Blinking = 1;
++ TimeInterval = 300;
++ }
++ else
++ {
++ pWb35Reg->U1BC_LEDConfigure &= ~0x1f;
++ Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_0 Off
++ pHwData->LED_Blinking = 0;
++ TimeInterval = 300;
++ }
++ }
++ else
++ {
++ // 20060901 Gray blinking if in disconnect state and not scanning
++ ltmp = pWb35Reg->U1BC_LEDConfigure;
++ pWb35Reg->U1BC_LEDConfigure &= ~0x1f;
++ if( LEDgray2[(pHwData->LED_Blinking%30)] )
++ {
++ pWb35Reg->U1BC_LEDConfigure |= 0x10;
++ pWb35Reg->U1BC_LEDConfigure |= LEDgray2[ (pHwData->LED_Blinking%30) ];
++ }
++ pHwData->LED_Blinking++;
++ if( pWb35Reg->U1BC_LEDConfigure != ltmp )
++ Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_0 Off
++ TimeInterval = 100;
++ }
++ }
++ else
++ {
++ // Turn On LED_0
++ if( (pWb35Reg->U1BC_LEDConfigure & 0x10) == 0 )
++ {
++ pWb35Reg->U1BC_LEDConfigure |= 0x10;
++ Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_0 Off
++ }
++ }
++ break;
++
++ case 5: // [101] Only 1 Led be placed on PCB and use LED_1 for showing
++ if( !pHwData->LED_LinkOn ) // Blink only if not Link On
++ {
++ // Blinking if scanning is on progress
++ if( pHwData->LED_Scanning )
++ {
++ if( pHwData->LED_Blinking == 0 )
++ {
++ pWb35Reg->U1BC_LEDConfigure |= 0x1000;
++ Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_1 On
++ pHwData->LED_Blinking = 1;
++ TimeInterval = 300;
++ }
++ else
++ {
++ pWb35Reg->U1BC_LEDConfigure &= ~0x1000;
++ Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_1 Off
++ pHwData->LED_Blinking = 0;
++ TimeInterval = 300;
++ }
++ }
++ else
++ {
++ //Turn Off LED_1
++ if( pWb35Reg->U1BC_LEDConfigure & 0x1000 )
++ {
++ pWb35Reg->U1BC_LEDConfigure &= ~0x1000;
++ Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_1 Off
++ }
++ }
++ }
++ else
++ {
++ // Is transmitting/receiving ??
++ if( (OS_CURRENT_RX_BYTE( Adapter ) != pHwData->RxByteCountLast ) ||
++ (OS_CURRENT_TX_BYTE( Adapter ) != pHwData->TxByteCountLast ) )
++ {
++ if( (pWb35Reg->U1BC_LEDConfigure & 0x3000) != 0x3000 )
++ {
++ pWb35Reg->U1BC_LEDConfigure |= 0x3000;
++ Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_1 On
++ }
++
++ // Update variable
++ pHwData->RxByteCountLast = OS_CURRENT_RX_BYTE( Adapter );
++ pHwData->TxByteCountLast = OS_CURRENT_TX_BYTE( Adapter );
++ TimeInterval = 200;
++ }
++ else
++ {
++ // Turn On LED_1 and blinking if transmitting/receiving
++ if( (pWb35Reg->U1BC_LEDConfigure & 0x3000) != 0x1000 )
++ {
++ pWb35Reg->U1BC_LEDConfigure &= ~0x3000;
++ pWb35Reg->U1BC_LEDConfigure |= 0x1000;
++ Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_1 On
++ }
++ }
++ }
++ break;
++
++ default: // Default setting. 2 LED be placed on PCB. LED_0: Link On LED_1 Active
++ if( (pWb35Reg->U1BC_LEDConfigure & 0x3000) != 0x3000 )
++ {
++ pWb35Reg->U1BC_LEDConfigure |= 0x3000;// LED_1 is always on and event enable
++ Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure );
++ }
++
++ if( pHwData->LED_Blinking )
++ {
++ // Gray blinking
++ pWb35Reg->U1BC_LEDConfigure &= ~0x0f;
++ pWb35Reg->U1BC_LEDConfigure |= 0x10;
++ pWb35Reg->U1BC_LEDConfigure |= LEDgray[ (pHwData->LED_Blinking-1)%20 ];
++ Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure );
++
++ pHwData->LED_Blinking += 2;
++ if( pHwData->LED_Blinking < 40 )
++ TimeInterval = 100;
++ else
++ {
++ pHwData->LED_Blinking = 0; // Stop blinking
++ pWb35Reg->U1BC_LEDConfigure &= ~0x0f;
++ Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure );
++ }
++ break;
++ }
++
++ if( pHwData->LED_LinkOn )
++ {
++ if( !(pWb35Reg->U1BC_LEDConfigure & 0x10) ) // Check the LED_0
++ {
++ //Try to turn ON LED_0 after gray blinking
++ pWb35Reg->U1BC_LEDConfigure |= 0x10;
++ pHwData->LED_Blinking = 1; //Start blinking
++ TimeInterval = 50;
++ }
++ }
++ else
++ {
++ if( pWb35Reg->U1BC_LEDConfigure & 0x10 ) // Check the LED_0
++ {
++ pWb35Reg->U1BC_LEDConfigure &= ~0x10;
++ Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure );
++ }
++ }
++ break;
++ }
++
++ //20060828.1 Active send null packet to avoid AP disconnect
++ if( pHwData->LED_LinkOn )
++ {
++ pHwData->NullPacketCount += TimeInterval;
++ if( pHwData->NullPacketCount >= DEFAULT_NULL_PACKET_COUNT )
++ {
++ pHwData->NullPacketCount = 0;
++ }
++ }
++ }
++
++ pHwData->time_count += TimeInterval;
++ Wb35Tx_CurrentTime( pHwData, pHwData->time_count ); // 20060928 add
++ OS_TIMER_SET( &pHwData->LEDTimer, TimeInterval ); // 20060623.1
++}
++
++
++void hal_set_phy_type( phw_data_t pHwData, u8 PhyType )
++{
++ pHwData->phy_type = PhyType;
++}
++
++void hal_get_phy_type( phw_data_t pHwData, u8 *PhyType )
++{
++ *PhyType = pHwData->phy_type;
++}
++
++void hal_reset_counter( phw_data_t pHwData )
++{
++ pHwData->dto_tx_retry_count = 0;
++ pHwData->dto_tx_frag_count = 0;
++ memset( pHwData->tx_retry_count, 0, 8);
++}
++
++void hal_set_radio_mode( phw_data_t pHwData, unsigned char radio_off)
++{
++ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
++
++ if( pHwData->SurpriseRemove ) return;
++
++ if (radio_off) //disable Baseband receive off
++ {
++ pHwData->CurrentRadioSw = 1; // off
++ pWb35Reg->M24_MacControl &= 0xffffffbf;
++ }
++ else
++ {
++ pHwData->CurrentRadioSw = 0; // on
++ pWb35Reg->M24_MacControl |= 0x00000040;
++ }
++ Wb35Reg_Write( pHwData, 0x0824, pWb35Reg->M24_MacControl );
++}
++
++u8 hal_get_antenna_number( phw_data_t pHwData )
++{
++ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
++
++ if ((pWb35Reg->BB2C & BIT(11)) == 0)
++ return 0;
++ else
++ return 1;
++}
++
++void hal_set_antenna_number( phw_data_t pHwData, u8 number )
++{
++
++ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
++
++ if (number == 1) {
++ pWb35Reg->BB2C |= BIT(11);
++ } else {
++ pWb35Reg->BB2C &= ~BIT(11);
++ }
++ Wb35Reg_Write( pHwData, 0x102c, pWb35Reg->BB2C );
++#ifdef _PE_STATE_DUMP_
++ WBDEBUG(("Current antenna number : %d\n", number));
++#endif
++}
++
++//----------------------------------------------------------------------------------------------------
++//0 : radio on; 1: radio off
++u8 hal_get_hw_radio_off( phw_data_t pHwData )
++{
++ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
++
++ if( pHwData->SurpriseRemove ) return 1;
++
++ //read the bit16 of register U1B0
++ Wb35Reg_Read( pHwData, 0x3b0, &pWb35Reg->U1B0 );
++ if ((pWb35Reg->U1B0 & 0x00010000)) {
++ pHwData->CurrentRadioHw = 1;
++ return 1;
++ } else {
++ pHwData->CurrentRadioHw = 0;
++ return 0;
++ }
++}
++
++unsigned char hal_get_dxx_reg( phw_data_t pHwData, u16 number, PULONG pValue )
++{
++ if( number < 0x1000 )
++ number += 0x1000;
++ return Wb35Reg_ReadSync( pHwData, number, pValue );
++}
++
++unsigned char hal_set_dxx_reg( phw_data_t pHwData, u16 number, u32 value )
++{
++ unsigned char ret;
++
++ if( number < 0x1000 )
++ number += 0x1000;
++ ret = Wb35Reg_WriteSync( pHwData, number, value );
++ return ret;
++}
++
++void hal_scan_status_indicate(phw_data_t pHwData, unsigned char IsOnProgress)
++{
++ if( pHwData->SurpriseRemove ) return;
++ pHwData->LED_Scanning = IsOnProgress ? 1 : 0;
++}
++
++void hal_system_power_change(phw_data_t pHwData, u32 PowerState)
++{
++ if( PowerState != 0 )
++ {
++ pHwData->SurpriseRemove = 1;
++ if( pHwData->WbUsb.IsUsb20 )
++ hal_stop( pHwData );
++ }
++ else
++ {
++ if( !pHwData->WbUsb.IsUsb20 )
++ hal_stop( pHwData );
++ }
++}
++
++void hal_surprise_remove( phw_data_t pHwData )
++{
++ PADAPTER Adapter = pHwData->Adapter;
++ if (OS_ATOMIC_INC( Adapter, &pHwData->SurpriseRemoveCount ) == 1) {
++ #ifdef _PE_STATE_DUMP_
++ WBDEBUG(("Calling hal_surprise_remove\n"));
++ #endif
++ OS_STOP( Adapter );
++ }
++}
++
++void hal_rate_change( phw_data_t pHwData ) // Notify the HAL rate is changing 20060613.1
++{
++ PADAPTER Adapter = pHwData->Adapter;
++ u8 rate = CURRENT_TX_RATE;
++
++ BBProcessor_RateChanging( pHwData, rate );
++}
++
++void hal_set_rf_power(phw_data_t pHwData, u8 PowerIndex)
++{
++ RFSynthesizer_SetPowerIndex( pHwData, PowerIndex );
++}
++
++unsigned char hal_set_LED(phw_data_t pHwData, u32 Mode) // 20061108 for WPS led control
++{
++ pHwData->LED_Blinking = 0;
++ pHwData->LED_control = Mode;
++ OS_TIMER_SET( &pHwData->LEDTimer, 10 ); // 20060623
++ return TRUE;
++}
++
+diff --git a/drivers/staging/winbond/wbhal_f.h b/drivers/staging/winbond/wbhal_f.h
+new file mode 100644
+index 0000000..fe25f97
+--- /dev/null
++++ b/drivers/staging/winbond/wbhal_f.h
+@@ -0,0 +1,122 @@
++//=====================================================================
++// Device related include
++//=====================================================================
++#ifdef WB_LINUX
++ #include "linux/wbusb_f.h"
++ #include "linux/wb35reg_f.h"
++ #include "linux/wb35tx_f.h"
++ #include "linux/wb35rx_f.h"
++#else
++ #include "wbusb_f.h"
++ #include "wb35reg_f.h"
++ #include "wb35tx_f.h"
++ #include "wb35rx_f.h"
++#endif
++
++//====================================================================================
++// Function declaration
++//====================================================================================
++void hal_remove_mapping_key( phw_data_t pHwData, PUCHAR pmac_addr );
++void hal_remove_default_key( phw_data_t pHwData, u32 index );
++unsigned char hal_set_mapping_key( phw_data_t Adapter, PUCHAR pmac_addr, u8 null_key, u8 wep_on, PUCHAR ptx_tsc, PUCHAR prx_tsc, u8 key_type, u8 key_len, PUCHAR pkey_data );
++unsigned char hal_set_default_key( phw_data_t Adapter, u8 index, u8 null_key, u8 wep_on, PUCHAR ptx_tsc, PUCHAR prx_tsc, u8 key_type, u8 key_len, PUCHAR pkey_data );
++void hal_clear_all_default_key( phw_data_t pHwData );
++void hal_clear_all_group_key( phw_data_t pHwData );
++void hal_clear_all_mapping_key( phw_data_t pHwData );
++void hal_clear_all_key( phw_data_t pHwData );
++void hal_get_ethernet_address( phw_data_t pHwData, PUCHAR current_address );
++void hal_set_ethernet_address( phw_data_t pHwData, PUCHAR current_address );
++void hal_get_permanent_address( phw_data_t pHwData, PUCHAR pethernet_address );
++unsigned char hal_init_hardware( phw_data_t pHwData, PADAPTER Adapter );
++void hal_set_power_save_mode( phw_data_t pHwData, unsigned char power_save, unsigned char wakeup, unsigned char dtim );
++void hal_get_power_save_mode( phw_data_t pHwData, PBOOLEAN pin_pwr_save );
++void hal_set_slot_time( phw_data_t pHwData, u8 type );
++#define hal_set_atim_window( _A, _ATM )
++void hal_set_rates( phw_data_t pHwData, PUCHAR pbss_rates, u8 length, unsigned char basic_rate_set );
++#define hal_set_basic_rates( _A, _R, _L ) hal_set_rates( _A, _R, _L, TRUE )
++#define hal_set_op_rates( _A, _R, _L ) hal_set_rates( _A, _R, _L, FALSE )
++void hal_start_bss( phw_data_t pHwData, u8 mac_op_mode );
++void hal_join_request( phw_data_t pHwData, u8 bss_type ); // 0:BSS STA 1:IBSS STA//
++void hal_stop_sync_bss( phw_data_t pHwData );
++void hal_resume_sync_bss( phw_data_t pHwData);
++void hal_set_aid( phw_data_t pHwData, u16 aid );
++void hal_set_bssid( phw_data_t pHwData, PUCHAR pbssid );
++void hal_get_bssid( phw_data_t pHwData, PUCHAR pbssid );
++void hal_set_beacon_period( phw_data_t pHwData, u16 beacon_period );
++void hal_set_listen_interval( phw_data_t pHwData, u16 listen_interval );
++void hal_set_cap_info( phw_data_t pHwData, u16 capability_info );
++void hal_set_ssid( phw_data_t pHwData, PUCHAR pssid, u8 ssid_len );
++void hal_set_current_channel( phw_data_t pHwData, ChanInfo channel );
++void hal_set_current_channel_ex( phw_data_t pHwData, ChanInfo channel );
++void hal_get_current_channel( phw_data_t pHwData, ChanInfo *channel );
++void hal_set_accept_broadcast( phw_data_t pHwData, u8 enable );
++void hal_set_accept_multicast( phw_data_t pHwData, u8 enable );
++void hal_set_accept_beacon( phw_data_t pHwData, u8 enable );
++void hal_set_multicast_address( phw_data_t pHwData, PUCHAR address, u8 number );
++u8 hal_get_accept_beacon( phw_data_t pHwData );
++void hal_stop( phw_data_t pHwData );
++void hal_halt( phw_data_t pHwData, void *ppa_data );
++void hal_start_tx0( phw_data_t pHwData );
++void hal_set_phy_type( phw_data_t pHwData, u8 PhyType );
++void hal_get_phy_type( phw_data_t pHwData, u8 *PhyType );
++unsigned char hal_reset_hardware( phw_data_t pHwData, void* ppa );
++void hal_set_cwmin( phw_data_t pHwData, u8 cwin_min );
++#define hal_get_cwmin( _A ) ( (_A)->cwmin )
++void hal_set_cwmax( phw_data_t pHwData, u16 cwin_max );
++#define hal_get_cwmax( _A ) ( (_A)->cwmax )
++void hal_set_rsn_wpa( phw_data_t pHwData, u32 * RSN_IE_Bitmap , u32 * RSN_OUI_type , unsigned char bDesiredAuthMode);
++//s32 hal_get_rssi( phw_data_t pHwData, u32 HalRssi );
++s32 hal_get_rssi( phw_data_t pHwData, u32 *HalRssiArry, u8 Count );
++s32 hal_get_rssi_bss( phw_data_t pHwData, u16 idx, u8 Count );
++void hal_set_connect_info( phw_data_t pHwData, unsigned char boConnect );
++u8 hal_get_est_sq3( phw_data_t pHwData, u8 Count );
++void hal_led_control_1a( phw_data_t pHwData );
++void hal_led_control( void* S1, phw_data_t pHwData, void* S3, void* S4 );
++void hal_set_rf_power( phw_data_t pHwData, u8 PowerIndex ); // 20060621 Modify
++void hal_reset_counter( phw_data_t pHwData );
++void hal_set_radio_mode( phw_data_t pHwData, unsigned char boValue);
++void hal_descriptor_indicate( phw_data_t pHwData, PDESCRIPTOR pDes );
++u8 hal_get_antenna_number( phw_data_t pHwData );
++void hal_set_antenna_number( phw_data_t pHwData, u8 number );
++u32 hal_get_bss_pk_cnt( phw_data_t pHwData );
++#define hal_get_region_from_EEPROM( _A ) ( (_A)->Wb35Reg.EEPROMRegion )
++void hal_set_accept_promiscuous ( phw_data_t pHwData, u8 enable);
++#define hal_get_tx_buffer( _A, _B ) Wb35Tx_get_tx_buffer( _A, _B )
++u8 hal_get_hw_radio_off ( phw_data_t pHwData );
++#define hal_software_set( _A ) (_A->SoftwareSet)
++#define hal_driver_init_OK( _A ) (_A->IsInitOK)
++#define hal_rssi_boundary_high( _A ) (_A->RSSI_high)
++#define hal_rssi_boundary_low( _A ) (_A->RSSI_low)
++#define hal_scan_interval( _A ) (_A->Scan_Interval)
++void hal_scan_status_indicate( phw_data_t pHwData, u8 status); // 0: complete, 1: in progress
++void hal_system_power_change( phw_data_t pHwData, u32 PowerState ); // 20051230 -=D0 1=D1 ..
++void hal_surprise_remove( phw_data_t pHwData );
++
++#define PHY_DEBUG( msg, args... )
++
++
++
++void hal_rate_change( phw_data_t pHwData ); // Notify the HAL rate is changing 20060613.1
++unsigned char hal_get_dxx_reg( phw_data_t pHwData, u16 number, PULONG pValue );
++unsigned char hal_set_dxx_reg( phw_data_t pHwData, u16 number, u32 value );
++#define hal_get_time_count( _P ) (_P->time_count/10) // return 100ms count
++#define hal_detect_error( _P ) (_P->WbUsb.DetectCount)
++unsigned char hal_set_LED( phw_data_t pHwData, u32 Mode ); // 20061108 for WPS led control
++
++//-------------------------------------------------------------------------
++// The follow function is unused for IS89C35
++//-------------------------------------------------------------------------
++#define hal_disable_interrupt(_A)
++#define hal_enable_interrupt(_A)
++#define hal_get_interrupt_type( _A)
++#define hal_get_clear_interrupt(_A)
++#define hal_ibss_disconnect(_A) hal_stop_sync_bss(_A)
++#define hal_join_request_stop(_A)
++unsigned char hal_idle( phw_data_t pHwData );
++#define pa_stall_execution( _A ) //OS_SLEEP( 1 )
++#define hw_get_cxx_reg( _A, _B, _C )
++#define hw_set_cxx_reg( _A, _B, _C )
++#define hw_get_dxx_reg( _A, _B, _C ) hal_get_dxx_reg( _A, _B, (PULONG)_C )
++#define hw_set_dxx_reg( _A, _B, _C ) hal_set_dxx_reg( _A, _B, (u32)_C )
++
++
+diff --git a/drivers/staging/winbond/wbhal_s.h b/drivers/staging/winbond/wbhal_s.h
+new file mode 100644
+index 0000000..5b862ff
+--- /dev/null
++++ b/drivers/staging/winbond/wbhal_s.h
+@@ -0,0 +1,615 @@
++//[20040722 WK]
++#define HAL_LED_SET_MASK 0x001c //20060901 Extend
++#define HAL_LED_SET_SHIFT 2
++
++//supported RF type
++#define RF_MAXIM_2825 0
++#define RF_MAXIM_2827 1
++#define RF_MAXIM_2828 2
++#define RF_MAXIM_2829 3
++#define RF_MAXIM_V1 15
++#define RF_AIROHA_2230 16
++#define RF_AIROHA_7230 17
++#define RF_AIROHA_2230S 18 // 20060420 Add this
++// #define RF_RFMD_2959 32 // 20060626 Remove all about RFMD
++#define RF_WB_242 33
++#define RF_WB_242_1 34 // 20060619.5 Add
++#define RF_DECIDE_BY_INF 255
++
++//----------------------------------------------------------------
++// The follow define connect to upper layer
++// User must modify for connection between HAL and upper layer
++//----------------------------------------------------------------
++
++
++
++
++/////////////////////////////////////////////////////////////////////////////////////////////////////
++//================================================================================================
++// Common define
++//================================================================================================
++#define HAL_USB_MODE_BURST( _H ) (_H->SoftwareSet & 0x20 ) // Bit 5 20060901 Modify
++
++// Scan interval
++#define SCAN_MAX_CHNL_TIME (50)
++
++// For TxL2 Frame typr recognise
++#define FRAME_TYPE_802_3_DATA 0
++#define FRAME_TYPE_802_11_MANAGEMENT 1
++#define FRAME_TYPE_802_11_MANAGEMENT_CHALLENGE 2
++#define FRAME_TYPE_802_11_CONTROL 3
++#define FRAME_TYPE_802_11_DATA 4
++#define FRAME_TYPE_PROMISCUOUS 5
++
++// The follow definition is used for convert the frame--------------------
++#define DOT_11_SEQUENCE_OFFSET 22 //Sequence control offset
++#define DOT_3_TYPE_OFFSET 12
++#define DOT_11_MAC_HEADER_SIZE 24
++#define DOT_11_SNAP_SIZE 6
++#define DOT_11_TYPE_OFFSET 30 //The start offset of 802.11 Frame. Type encapsulatuin.
++#define DEFAULT_SIFSTIME 10
++#define DEFAULT_FRAGMENT_THRESHOLD 2346 // No fragment
++#define DEFAULT_MSDU_LIFE_TIME 0xffff
++
++#define LONG_PREAMBLE_PLUS_PLCPHEADER_TIME (144+48)
++#define SHORT_PREAMBLE_PLUS_PLCPHEADER_TIME (72+24)
++#define PREAMBLE_PLUS_SIGNAL_PLUS_SIGNALEXTENSION (16+4+6)
++#define Tsym 4
++
++// Frame Type of Bits (2, 3)---------------------------------------------
++#define MAC_TYPE_MANAGEMENT 0x00
++#define MAC_TYPE_CONTROL 0x04
++#define MAC_TYPE_DATA 0x08
++#define MASK_FRAGMENT_NUMBER 0x000F
++#define SEQUENCE_NUMBER_SHIFT 4
++
++#define HAL_WOL_TYPE_WAKEUP_FRAME 0x01
++#define HAL_WOL_TYPE_MAGIC_PACKET 0x02
++
++// 20040106 ADDED
++#define HAL_KEYTYPE_WEP40 0
++#define HAL_KEYTYPE_WEP104 1
++#define HAL_KEYTYPE_TKIP 2 // 128 bit key
++#define HAL_KEYTYPE_AES_CCMP 3 // 128 bit key
++
++// For VM state
++enum {
++ VM_STOP = 0,
++ VM_RUNNING,
++ VM_COMPLETED
++};
++
++// Be used for 802.11 mac header
++typedef struct _MAC_FRAME_CONTROL {
++ u8 mac_frame_info; // this is a combination of the protovl version, type and subtype
++ u8 to_ds:1;
++ u8 from_ds:1;
++ u8 more_frag:1;
++ u8 retry:1;
++ u8 pwr_mgt:1;
++ u8 more_data:1;
++ u8 WEP:1;
++ u8 order:1;
++} MAC_FRAME_CONTROL, *PMAC_FRAME_CONTROL;
++
++//-----------------------------------------------------
++// Normal Key table format
++//-----------------------------------------------------
++// The order of KEY index is MAPPING_KEY_START_INDEX > GROUP_KEY_START_INDEX
++#define MAX_KEY_TABLE 24 // 24 entry for storing key data
++#define GROUP_KEY_START_INDEX 4
++#define MAPPING_KEY_START_INDEX 8
++typedef struct _KEY_TABLE
++{
++ u32 DW0_Valid:1;
++ u32 DW0_NullKey:1;
++ u32 DW0_Security_Mode:2;//0:WEP 40 bit 1:WEP 104 bit 2:TKIP 128 bit 3:CCMP 128 bit
++ u32 DW0_WEPON:1;
++ u32 DW0_RESERVED:11;
++ u32 DW0_Address1:16;
++
++ u32 DW1_Address2;
++
++ u32 DW2_RxSequenceCount1;
++
++ u32 DW3_RxSequenceCount2:16;
++ u32 DW3_RESERVED:16;
++
++ u32 DW4_TxSequenceCount1;
++
++ u32 DW5_TxSequenceCount2:16;
++ u32 DW5_RESERVED:16;
++
++} KEY_TABLE, *PKEY_TABLE;
++
++//--------------------------------------------------------
++// Descriptor
++//--------------------------------------------------------
++#define MAX_DESCRIPTOR_BUFFER_INDEX 8 // Have to multiple of 2
++//#define FLAG_ERROR_TX_MASK cpu_to_le32(0x000000bf) //20061009 marked by anson's endian
++#define FLAG_ERROR_TX_MASK 0x000000bf //20061009 anson's endian
++//#define FLAG_ERROR_RX_MASK 0x00000c3f
++//#define FLAG_ERROR_RX_MASK cpu_to_le32(0x0000083f) //20061009 marked by anson's endian
++ //Don't care replay error,
++ //it is handled by S/W
++#define FLAG_ERROR_RX_MASK 0x0000083f //20060926 anson's endian
++
++#define FLAG_BAND_RX_MASK 0x10000000 //Bit 28
++
++typedef struct _R00_DESCRIPTOR
++{
++ union
++ {
++ u32 value;
++ #ifdef _BIG_ENDIAN_ //20060926 anson's endian
++ struct
++ {
++ u32 R00_packet_or_buffer_status:1;
++ u32 R00_packet_in_fifo:1;
++ u32 R00_RESERVED:2;
++ u32 R00_receive_byte_count:12;
++ u32 R00_receive_time_index:16;
++ };
++ #else
++ struct
++ {
++ u32 R00_receive_time_index:16;
++ u32 R00_receive_byte_count:12;
++ u32 R00_RESERVED:2;
++ u32 R00_packet_in_fifo:1;
++ u32 R00_packet_or_buffer_status:1;
++ };
++ #endif
++ };
++} R00_DESCRIPTOR, *PR00_DESCRIPTOR;
++
++typedef struct _T00_DESCRIPTOR
++{
++ union
++ {
++ u32 value;
++ #ifdef _BIG_ENDIAN_ //20061009 anson's endian
++ struct
++ {
++ u32 T00_first_mpdu:1; // for hardware use
++ u32 T00_last_mpdu:1; // for hardware use
++ u32 T00_IsLastMpdu:1;// 0: not 1:Yes for software used
++ u32 T00_IgnoreResult:1;// The same mechanism with T00 setting. 050111 Modify for TS
++ u32 T00_RESERVED_ID:2;//3 bit ID reserved
++ u32 T00_tx_packet_id:4;//930519.4.e 930810.3.c
++ u32 T00_RESERVED:4;
++ u32 T00_header_length:6;
++ u32 T00_frame_length:12;
++ };
++ #else
++ struct
++ {
++ u32 T00_frame_length:12;
++ u32 T00_header_length:6;
++ u32 T00_RESERVED:4;
++ u32 T00_tx_packet_id:4;//930519.4.e 930810.3.c
++ u32 T00_RESERVED_ID:2;//3 bit ID reserved
++ u32 T00_IgnoreResult:1;// The same mechanism with T00 setting. 050111 Modify for TS
++ u32 T00_IsLastMpdu:1;// 0: not 1:Yes for software used
++ u32 T00_last_mpdu:1; // for hardware use
++ u32 T00_first_mpdu:1; // for hardware use
++ };
++ #endif
++ };
++} T00_DESCRIPTOR, *PT00_DESCRIPTOR;
++
++typedef struct _R01_DESCRIPTOR
++{
++ union
++ {
++ u32 value;
++ #ifdef _BIG_ENDIAN_ //20060926 add by anson's endian
++ struct
++ {
++ u32 R01_RESERVED:3;
++ u32 R01_mod_type:1;
++ u32 R01_pre_type:1;
++ u32 R01_data_rate:3;
++ u32 R01_AGC_state:8;
++ u32 R01_LNA_state:2;
++ u32 R01_decryption_method:2;
++ u32 R01_mic_error:1;
++ u32 R01_replay:1;
++ u32 R01_broadcast_frame:1;
++ u32 R01_multicast_frame:1;
++ u32 R01_directed_frame:1;
++ u32 R01_receive_frame_antenna_selection:1;
++ u32 R01_frame_receive_during_atim_window:1;
++ u32 R01_protocol_version_error:1;
++ u32 R01_authentication_frame_icv_error:1;
++ u32 R01_null_key_to_authentication_frame:1;
++ u32 R01_icv_error:1;
++ u32 R01_crc_error:1;
++ };
++ #else
++ struct
++ {
++ u32 R01_crc_error:1;
++ u32 R01_icv_error:1;
++ u32 R01_null_key_to_authentication_frame:1;
++ u32 R01_authentication_frame_icv_error:1;
++ u32 R01_protocol_version_error:1;
++ u32 R01_frame_receive_during_atim_window:1;
++ u32 R01_receive_frame_antenna_selection:1;
++ u32 R01_directed_frame:1;
++ u32 R01_multicast_frame:1;
++ u32 R01_broadcast_frame:1;
++ u32 R01_replay:1;
++ u32 R01_mic_error:1;
++ u32 R01_decryption_method:2;
++ u32 R01_LNA_state:2;
++ u32 R01_AGC_state:8;
++ u32 R01_data_rate:3;
++ u32 R01_pre_type:1;
++ u32 R01_mod_type:1;
++ u32 R01_RESERVED:3;
++ };
++ #endif
++ };
++} R01_DESCRIPTOR, *PR01_DESCRIPTOR;
++
++typedef struct _T01_DESCRIPTOR
++{
++ union
++ {
++ u32 value;
++ #ifdef _BIG_ENDIAN_ //20061009 anson's endian
++ struct
++ {
++ u32 T01_rts_cts_duration:16;
++ u32 T01_fall_back_rate:3;
++ u32 T01_add_rts:1;
++ u32 T01_add_cts:1;
++ u32 T01_modulation_type:1;
++ u32 T01_plcp_header_length:1;
++ u32 T01_transmit_rate:3;
++ u32 T01_wep_id:2;
++ u32 T01_add_challenge_text:1;
++ u32 T01_inhibit_crc:1;
++ u32 T01_loop_back_wep_mode:1;
++ u32 T01_retry_abort_ebable:1;
++ };
++ #else
++ struct
++ {
++ u32 T01_retry_abort_ebable:1;
++ u32 T01_loop_back_wep_mode:1;
++ u32 T01_inhibit_crc:1;
++ u32 T01_add_challenge_text:1;
++ u32 T01_wep_id:2;
++ u32 T01_transmit_rate:3;
++ u32 T01_plcp_header_length:1;
++ u32 T01_modulation_type:1;
++ u32 T01_add_cts:1;
++ u32 T01_add_rts:1;
++ u32 T01_fall_back_rate:3;
++ u32 T01_rts_cts_duration:16;
++ };
++ #endif
++ };
++} T01_DESCRIPTOR, *PT01_DESCRIPTOR;
++
++typedef struct _T02_DESCRIPTOR
++{
++ union
++ {
++ u32 value;
++ #ifdef _BIG_ENDIAN_ //20061009 add by anson's endian
++ struct
++ {
++ u32 T02_IsLastMpdu:1;// The same mechanism with T00 setting
++ u32 T02_IgnoreResult:1;// The same mechanism with T00 setting. 050111 Modify for TS
++ u32 T02_RESERVED_ID:2;// The same mechanism with T00 setting
++ u32 T02_Tx_PktID:4;
++ u32 T02_MPDU_Cnt:4;
++ u32 T02_RTS_Cnt:4;
++ u32 T02_RESERVED:7;
++ u32 T02_transmit_complete:1;
++ u32 T02_transmit_abort_due_to_TBTT:1;
++ u32 T02_effective_transmission_rate:1;
++ u32 T02_transmit_without_encryption_due_to_wep_on_false:1;
++ u32 T02_discard_due_to_null_wep_key:1;
++ u32 T02_RESERVED_1:1;
++ u32 T02_out_of_MaxTxMSDULiftTime:1;
++ u32 T02_transmit_abort:1;
++ u32 T02_transmit_fail:1;
++ };
++ #else
++ struct
++ {
++ u32 T02_transmit_fail:1;
++ u32 T02_transmit_abort:1;
++ u32 T02_out_of_MaxTxMSDULiftTime:1;
++ u32 T02_RESERVED_1:1;
++ u32 T02_discard_due_to_null_wep_key:1;
++ u32 T02_transmit_without_encryption_due_to_wep_on_false:1;
++ u32 T02_effective_transmission_rate:1;
++ u32 T02_transmit_abort_due_to_TBTT:1;
++ u32 T02_transmit_complete:1;
++ u32 T02_RESERVED:7;
++ u32 T02_RTS_Cnt:4;
++ u32 T02_MPDU_Cnt:4;
++ u32 T02_Tx_PktID:4;
++ u32 T02_RESERVED_ID:2;// The same mechanism with T00 setting
++ u32 T02_IgnoreResult:1;// The same mechanism with T00 setting. 050111 Modify for TS
++ u32 T02_IsLastMpdu:1;// The same mechanism with T00 setting
++ };
++ #endif
++ };
++} T02_DESCRIPTOR, *PT02_DESCRIPTOR;
++
++typedef struct _DESCRIPTOR { // Skip length = 8 DWORD
++ // ID for descriptor ---, The field doesn't be cleard in the operation of Descriptor definition
++ u8 Descriptor_ID;
++ //----------------------The above region doesn't be cleared by DESCRIPTOR_RESET------
++ u8 RESERVED[3];
++
++ u16 FragmentThreshold;
++ u8 InternalUsed;//Only can be used by operation of descriptor definition
++ u8 Type;// 0: 802.3 1:802.11 data frame 2:802.11 management frame
++
++ u8 PreambleMode;// 0: short 1:long
++ u8 TxRate;
++ u8 FragmentCount;
++ u8 EapFix; // For speed up key install
++
++ // For R00 and T00 ----------------------------------------------
++ union
++ {
++ R00_DESCRIPTOR R00;
++ T00_DESCRIPTOR T00;
++ };
++
++ // For R01 and T01 ----------------------------------------------
++ union
++ {
++ R01_DESCRIPTOR R01;
++ T01_DESCRIPTOR T01;
++ };
++
++ // For R02 and T02 ----------------------------------------------
++ union
++ {
++ u32 R02;
++ T02_DESCRIPTOR T02;
++ };
++
++ // For R03 and T03 ----------------------------------------------
++ // For software used
++ union
++ {
++ u32 R03;
++ u32 T03;
++ struct
++ {
++ u8 buffer_number;
++ u8 buffer_start_index;
++ u16 buffer_total_size;
++ };
++ };
++
++ // For storing the buffer
++ u16 buffer_size[ MAX_DESCRIPTOR_BUFFER_INDEX ];
++ void* buffer_address[ MAX_DESCRIPTOR_BUFFER_INDEX ];//931130.4.q
++
++} DESCRIPTOR, *PDESCRIPTOR;
++
++
++#define DEFAULT_NULL_PACKET_COUNT 180000 //20060828.1 Add. 180 seconds
++
++#define MAX_TXVGA_EEPROM 9 //How many word(u16) of EEPROM will be used for TxVGA
++#define MAX_RF_PARAMETER 32
++
++typedef struct _TXVGA_FOR_50 {
++ u8 ChanNo;
++ u8 TxVgaValue;
++} TXVGA_FOR_50;
++
++
++//=====================================================================
++// Device related include
++//=====================================================================
++
++#include "linux/wbusb_s.h"
++#include "linux/wb35reg_s.h"
++#include "linux/wb35tx_s.h"
++#include "linux/wb35rx_s.h"
++
++
++// For Hal using ==================================================================
++typedef struct _HW_DATA_T
++{
++ // For compatible with 33
++ u32 revision;
++ u32 BB3c_cal; // The value for Tx calibration comes from EEPROM
++ u32 BB54_cal; // The value for Rx calibration comes from EEPROM
++
++
++ // For surprise remove
++ u32 SurpriseRemove; // 0: Normal 1: Surprise remove
++ u8 InitialResource;
++ u8 IsKeyPreSet;
++ u8 CalOneTime; // 20060630.1
++
++ u8 VCO_trim;
++
++ // For Fix 1'st DMA bug
++ u32 FragCount;
++ u32 DMAFix; //V1_DMA_FIX The variable can be removed if driver want to save mem space for V2.
++
++ //=======================================================================================
++ // For USB driver, hal need more variables. Due to
++ // 1. NDIS-WDM operation
++ // 2. The SME, MLME and OLD MDS need Adapter structure, but the driver under HAL doesn't
++ // have that parameter when receiving and indicating packet.
++ // The MDS must input the Adapter pointer as the second parameter of hal_init_hardware.
++ // The function usage is different than PCI driver.
++ //=======================================================================================
++ void* Adapter;
++
++ //===============================================
++ // Definition for MAC address
++ //===============================================
++ u8 PermanentMacAddress[ETH_LENGTH_OF_ADDRESS + 2]; // The Enthernet addr that are stored in EEPROM. + 2 to 8-byte alignment
++ u8 CurrentMacAddress[ETH_LENGTH_OF_ADDRESS + 2]; // The Enthernet addr that are in used. + 2 to 8-byte alignment
++
++ //=====================================================================
++ // Definition for 802.11
++ //=====================================================================
++ PUCHAR bssid_pointer; // Used by hal_get_bssid for return value
++ u8 bssid[8];// Only 6 byte will be used. 8 byte is required for read buffer
++ u8 ssid[32];// maximum ssid length is 32 byte
++
++ u16 AID;
++ u8 ssid_length;
++ u8 Channel;
++
++ u16 ListenInterval;
++ u16 CapabilityInformation;
++
++ u16 BeaconPeriod;
++ u16 ProbeDelay;
++
++ u8 bss_type;// 0: IBSS_NET or 1:ESS_NET
++ u8 preamble;// 0: short preamble, 1: long preamble
++ u8 slot_time_select;// 9 or 20 value
++ u8 phy_type;// Phy select
++
++ u32 phy_para[MAX_RF_PARAMETER];
++ u32 phy_number;
++
++ u32 CurrentRadioSw; // 20060320.2 0:On 1:Off
++ u32 CurrentRadioHw; // 20060825 0:On 1:Off
++
++ PUCHAR power_save_point; // Used by hal_get_power_save_mode for return value
++ u8 cwmin;
++ u8 desired_power_save;
++ u8 dtim;// Is running dtim
++ u8 mapping_key_replace_index;//In Key table, the next index be replaced 931130.4.r
++
++ u16 MaxReceiveLifeTime;
++ u16 FragmentThreshold;
++ u16 FragmentThreshold_tmp;
++ u16 cwmax;
++
++ u8 Key_slot[MAX_KEY_TABLE][8]; //Ownership record for key slot. For Alignment
++ u32 Key_content[MAX_KEY_TABLE][12]; // 10DW for each entry + 2 for burst command( Off and On valid bit)
++ u8 CurrentDefaultKeyIndex;
++ u32 CurrentDefaultKeyLength;
++
++ //========================================================================
++ // Variable for each module
++ //========================================================================
++ WBUSB WbUsb; // Need WbUsb.h
++ WB35REG Wb35Reg; // Need Wb35Reg.h
++ WB35TX Wb35Tx; // Need Wb35Tx.h
++ WB35RX Wb35Rx; // Need Wb35Rx.h
++
++ OS_TIMER LEDTimer;// For LED
++
++ u32 LEDpoint;// For LED
++
++ u32 dto_tx_retry_count; // LA20040210_DTO kevin
++ u32 dto_tx_frag_count; // LA20040210_DTO kevin
++ u32 rx_ok_count[13]; // index=0: total rx ok
++ //u32 rx_ok_bytes[13]; // index=0, total rx ok bytes
++ u32 rx_err_count[13]; // index=0: total rx err
++
++ //for Tx debug
++ u32 tx_TBTT_start_count;
++ u32 tx_ETR_count;
++ u32 tx_WepOn_false_count;
++ u32 tx_Null_key_count;
++ u32 tx_retry_count[8];
++
++ u8 PowerIndexFromEEPROM; // For 2412MHz
++ u8 power_index;
++ u8 IsWaitJoinComplete; // TRUE: set join request
++ u8 band;
++
++ u16 SoftwareSet;
++ u16 Reserved_s;
++
++ u32 IsInitOK; // 0: Driver starting 1: Driver init OK
++
++ // For Phy calibration
++ s32 iq_rsdl_gain_tx_d2;
++ s32 iq_rsdl_phase_tx_d2;
++ u32 txvga_setting_for_cal; // 20060703.1 Add
++
++ u8 TxVgaSettingInEEPROM[ (((MAX_TXVGA_EEPROM*2)+3) & ~0x03) ]; // 20060621 For backup EEPROM value
++ u8 TxVgaFor24[16]; // Max is 14, 2 for alignment
++ TXVGA_FOR_50 TxVgaFor50[36]; // 35 channels in 5G. 35x2 = 70 byte. 2 for alignments
++
++ u16 Scan_Interval;
++ u16 RESERVED6;
++
++ // LED control
++ u32 LED_control;
++ // LED_control 4 byte: Gray_Led_1[3] Gray_Led_0[2] Led[1] Led[0]
++ // Gray_Led
++ // For Led gray setting
++ // Led
++ // 0: normal control, LED behavior will decide by EEPROM setting
++ // 1: Turn off specific LED
++ // 2: Always on specific LED
++ // 3: slow blinking specific LED
++ // 4: fast blinking specific LED
++ // 5: WPS led control is set. Led0 is Red, Led1 id Green
++ // Led[1] is parameter for WPS LED mode
++ // // 1:InProgress 2: Error 3: Session overlap 4: Success 20061108 control
++
++ u32 LED_LinkOn; //Turn LED on control
++ u32 LED_Scanning; // Let LED in scan process control
++ u32 LED_Blinking; // Temp variable for shining
++ u32 RxByteCountLast;
++ u32 TxByteCountLast;
++
++ s32 SurpriseRemoveCount;
++
++ // For global timer
++ u32 time_count;//TICK_TIME_100ms 1 = 100ms
++
++ // For error recover
++ u32 HwStop;
++
++ // 20060828.1 for avoid AP disconnect
++ u32 NullPacketCount;
++
++} hw_data_t, *phw_data_t;
++
++// The mapping of Rx and Tx descriptor field
++typedef struct _HAL_RATE
++{
++ // DSSS
++ u32 RESERVED_0;
++ u32 NumRate2MS;
++ u32 NumRate55MS;
++ u32 NumRate11MS;
++
++ u32 RESERVED_1[4];
++
++ u32 NumRate1M;
++ u32 NumRate2ML;
++ u32 NumRate55ML;
++ u32 NumRate11ML;
++
++ u32 RESERVED_2[4];
++
++ // OFDM
++ u32 NumRate6M;
++ u32 NumRate9M;
++ u32 NumRate12M;
++ u32 NumRate18M;
++ u32 NumRate24M;
++ u32 NumRate36M;
++ u32 NumRate48M;
++ u32 NumRate54M;
++} HAL_RATE, *PHAL_RATE;
++
++
+diff --git a/drivers/staging/winbond/wblinux.c b/drivers/staging/winbond/wblinux.c
+new file mode 100644
+index 0000000..2eade5a
+--- /dev/null
++++ b/drivers/staging/winbond/wblinux.c
+@@ -0,0 +1,277 @@
++//============================================================================
++// Copyright (c) 1996-2005 Winbond Electronic Corporation
++//
++// Module Name:
++// wblinux.c
++//
++// Abstract:
++// Linux releated routines
++//
++//============================================================================
++#include "os_common.h"
++
++u32
++WBLINUX_MemoryAlloc(void* *VirtualAddress, u32 Length)
++{
++ *VirtualAddress = kzalloc( Length, GFP_ATOMIC ); //GFP_KERNEL is not suitable
++
++ if (*VirtualAddress == NULL)
++ return 0;
++ return 1;
++}
++
++s32
++EncapAtomicInc(PADAPTER Adapter, void* pAtomic)
++{
++ PWBLINUX pWbLinux = &Adapter->WbLinux;
++ u32 ltmp;
++ PULONG pltmp = (PULONG)pAtomic;
++ OS_SPIN_LOCK_ACQUIRED( &pWbLinux->AtomicSpinLock );
++ (*pltmp)++;
++ ltmp = (*pltmp);
++ OS_SPIN_LOCK_RELEASED( &pWbLinux->AtomicSpinLock );
++ return ltmp;
++}
++
++s32
++EncapAtomicDec(PADAPTER Adapter, void* pAtomic)
++{
++ PWBLINUX pWbLinux = &Adapter->WbLinux;
++ u32 ltmp;
++ PULONG pltmp = (PULONG)pAtomic;
++ OS_SPIN_LOCK_ACQUIRED( &pWbLinux->AtomicSpinLock );
++ (*pltmp)--;
++ ltmp = (*pltmp);
++ OS_SPIN_LOCK_RELEASED( &pWbLinux->AtomicSpinLock );
++ return ltmp;
++}
++
++unsigned char
++WBLINUX_Initial(PADAPTER Adapter)
++{
++ PWBLINUX pWbLinux = &Adapter->WbLinux;
++
++ OS_SPIN_LOCK_ALLOCATE( &pWbLinux->SpinLock );
++ OS_SPIN_LOCK_ALLOCATE( &pWbLinux->AtomicSpinLock );
++ return TRUE;
++}
++
++void
++WBLinux_ReceivePacket(PADAPTER Adapter, PRXLAYER1 pRxLayer1)
++{
++ BUG();
++}
++
++
++void
++WBLINUX_GetNextPacket(PADAPTER Adapter, PDESCRIPTOR pDes)
++{
++ BUG();
++}
++
++void
++WBLINUX_GetNextPacketCompleted(PADAPTER Adapter, PDESCRIPTOR pDes)
++{
++ BUG();
++}
++
++void
++WBLINUX_Destroy(PADAPTER Adapter)
++{
++ WBLINUX_stop( Adapter );
++ OS_SPIN_LOCK_FREE( &pWbNdis->SpinLock );
++#ifdef _PE_USB_INI_DUMP_
++ WBDEBUG(("[w35und] unregister_netdev!\n"));
++#endif
++}
++
++void
++WBLINUX_stop( PADAPTER Adapter )
++{
++ PWBLINUX pWbLinux = &Adapter->WbLinux;
++ struct sk_buff *pSkb;
++
++ if (OS_ATOMIC_INC( Adapter, &pWbLinux->ThreadCount ) == 1) {
++ // Shutdown module immediately
++ pWbLinux->shutdown = 1;
++
++ while (pWbLinux->skb_array[ pWbLinux->skb_GetIndex ]) {
++ // Trying to free the un-sending packet
++ pSkb = pWbLinux->skb_array[ pWbLinux->skb_GetIndex ];
++ pWbLinux->skb_array[ pWbLinux->skb_GetIndex ] = NULL;
++ if( in_irq() )
++ dev_kfree_skb_irq( pSkb );
++ else
++ dev_kfree_skb( pSkb );
++
++ pWbLinux->skb_GetIndex++;
++ pWbLinux->skb_GetIndex %= WBLINUX_PACKET_ARRAY_SIZE;
++ }
++
++#ifdef _PE_STATE_DUMP_
++ WBDEBUG(( "[w35und] SKB_RELEASE OK\n" ));
++#endif
++ }
++
++ OS_ATOMIC_DEC( Adapter, &pWbLinux->ThreadCount );
++}
++
++void
++WbWlanHalt( PADAPTER Adapter )
++{
++ //---------------------
++ Adapter->sLocalPara.ShutDowned = TRUE;
++
++ Mds_Destroy( Adapter );
++
++ // Turn off Rx and Tx hardware ability
++ hal_stop( &Adapter->sHwData );
++#ifdef _PE_USB_INI_DUMP_
++ WBDEBUG(("[w35und] Hal_stop O.K.\n"));
++#endif
++ OS_SLEEP(100000);// Waiting Irp completed
++
++ // Destroy the NDIS module
++ WBLINUX_Destroy( Adapter );
++
++ // Halt the HAL
++ hal_halt(&Adapter->sHwData, NULL);
++}
++
++unsigned char
++WbWLanInitialize(PADAPTER Adapter)
++{
++ phw_data_t pHwData;
++ PUCHAR pMacAddr, pMacAddr2;
++ u32 InitStep = 0;
++ u8 EEPROM_region;
++ u8 HwRadioOff;
++
++ do {
++ //
++ // Setting default value for Linux
++ //
++ Adapter->sLocalPara.region_INF = REGION_AUTO;
++ Adapter->sLocalPara.TxRateMode = RATE_AUTO;
++ psLOCAL->bMacOperationMode = MODE_802_11_BG; // B/G mode
++ Adapter->Mds.TxRTSThreshold = DEFAULT_RTSThreshold;
++ Adapter->Mds.TxFragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD;
++ hal_set_phy_type( &Adapter->sHwData, RF_WB_242_1 );
++ Adapter->sLocalPara.MTUsize = MAX_ETHERNET_PACKET_SIZE;
++ psLOCAL->bPreambleMode = AUTO_MODE;
++ Adapter->sLocalPara.RadioOffStatus.boSwRadioOff = FALSE;
++ pHwData = &Adapter->sHwData;
++ hal_set_phy_type( pHwData, RF_DECIDE_BY_INF );
++
++ //
++ // Initial each module and variable
++ //
++ if (!WBLINUX_Initial(Adapter)) {
++#ifdef _PE_USB_INI_DUMP_
++ WBDEBUG(("[w35und]WBNDIS initialization failed\n"));
++#endif
++ break;
++ }
++
++ // Initial Software variable
++ Adapter->sLocalPara.ShutDowned = FALSE;
++
++ //added by ws for wep key error detection
++ Adapter->sLocalPara.bWepKeyError= FALSE;
++ Adapter->sLocalPara.bToSelfPacketReceived = FALSE;
++ Adapter->sLocalPara.WepKeyDetectTimerCount= 2 * 100; /// 2 seconds
++
++ // Initial USB hal
++ InitStep = 1;
++ pHwData = &Adapter->sHwData;
++ if (!hal_init_hardware(pHwData, Adapter))
++ break;
++
++ EEPROM_region = hal_get_region_from_EEPROM( pHwData );
++ if (EEPROM_region != REGION_AUTO)
++ psLOCAL->region = EEPROM_region;
++ else {
++ if (psLOCAL->region_INF != REGION_AUTO)
++ psLOCAL->region = psLOCAL->region_INF;
++ else
++ psLOCAL->region = REGION_USA; //default setting
++ }
++
++ // Get Software setting flag from hal
++ Adapter->sLocalPara.boAntennaDiversity = FALSE;
++ if (hal_software_set(pHwData) & 0x00000001)
++ Adapter->sLocalPara.boAntennaDiversity = TRUE;
++
++ //
++ // For TS module
++ //
++ InitStep = 2;
++
++ // For MDS module
++ InitStep = 3;
++ Mds_initial(Adapter);
++
++ //=======================================
++ // Initialize the SME, SCAN, MLME, ROAM
++ //=======================================
++ InitStep = 4;
++ InitStep = 5;
++ InitStep = 6;
++
++ // If no user-defined address in the registry, use the addresss "burned" on the NIC instead.
++ pMacAddr = Adapter->sLocalPara.ThisMacAddress;
++ pMacAddr2 = Adapter->sLocalPara.PermanentAddress;
++ hal_get_permanent_address( pHwData, Adapter->sLocalPara.PermanentAddress );// Reading ethernet address from EEPROM
++ if (OS_MEMORY_COMPARE(pMacAddr, "\x00\x00\x00\x00\x00\x00", MAC_ADDR_LENGTH )) // Is equal
++ {
++ memcpy( pMacAddr, pMacAddr2, MAC_ADDR_LENGTH );
++ } else {
++ // Set the user define MAC address
++ hal_set_ethernet_address( pHwData, Adapter->sLocalPara.ThisMacAddress );
++ }
++
++ //get current antenna
++ psLOCAL->bAntennaNo = hal_get_antenna_number(pHwData);
++#ifdef _PE_STATE_DUMP_
++ WBDEBUG(("Driver init, antenna no = %d\n", psLOCAL->bAntennaNo));
++#endif
++ hal_get_hw_radio_off( pHwData );
++
++ // Waiting for HAL setting OK
++ while (!hal_idle(pHwData))
++ OS_SLEEP(10000);
++
++ MTO_Init(Adapter);
++
++ HwRadioOff = hal_get_hw_radio_off( pHwData );
++ psLOCAL->RadioOffStatus.boHwRadioOff = !!HwRadioOff;
++
++ hal_set_radio_mode( pHwData, (unsigned char)(psLOCAL->RadioOffStatus.boSwRadioOff || psLOCAL->RadioOffStatus.boHwRadioOff) );
++
++ hal_driver_init_OK(pHwData) = 1; // Notify hal that the driver is ready now.
++ //set a tx power for reference.....
++// sme_set_tx_power_level(Adapter, 12); FIXME?
++ return TRUE;
++ }
++ while(FALSE);
++
++ switch (InitStep) {
++ case 5:
++ case 4:
++ case 3: Mds_Destroy( Adapter );
++ case 2:
++ case 1: WBLINUX_Destroy( Adapter );
++ hal_halt( pHwData, NULL );
++ case 0: break;
++ }
++
++ return FALSE;
++}
++
++void WBLINUX_ConnectStatus(PADAPTER Adapter, u32 flag)
++{
++ PWBLINUX pWbLinux = &Adapter->WbLinux;
++
++ pWbLinux->LinkStatus = flag; // OS_DISCONNECTED or OS_CONNECTED
++}
++
+diff --git a/drivers/staging/winbond/wblinux_f.h b/drivers/staging/winbond/wblinux_f.h
+new file mode 100644
+index 0000000..68240c5
+--- /dev/null
++++ b/drivers/staging/winbond/wblinux_f.h
+@@ -0,0 +1,23 @@
++//=========================================================================
++// Copyright (c) 1996-2004 Winbond Electronic Corporation
++//
++// wblinux_f.h
++//
++u32 WBLINUX_MemoryAlloc( void* *VirtualAddress, u32 Length );
++s32 EncapAtomicInc( PADAPTER Adapter, void* pAtomic );
++s32 EncapAtomicDec( PADAPTER Adapter, void* pAtomic );
++void WBLinux_ReceivePacket( PADAPTER Adapter, PRXLAYER1 pRxLayer1 );
++unsigned char WBLINUX_Initial( PADAPTER Adapter );
++int wb35_start_xmit(struct sk_buff *skb, struct net_device *netdev );
++void WBLINUX_GetNextPacket( PADAPTER Adapter, PDESCRIPTOR pDes );
++void WBLINUX_GetNextPacketCompleted( PADAPTER Adapter, PDESCRIPTOR pDes );
++void WBLINUX_stop( PADAPTER Adapter );
++void WBLINUX_Destroy( PADAPTER Adapter );
++void wb35_set_multicast( struct net_device *netdev );
++struct net_device_stats * wb35_netdev_stats( struct net_device *netdev );
++void WBLINUX_stop( PADAPTER Adapter );
++void WbWlanHalt( PADAPTER Adapter );
++void WBLINUX_ConnectStatus( PADAPTER Adapter, u32 flag );
++
++
++
+diff --git a/drivers/staging/winbond/wblinux_s.h b/drivers/staging/winbond/wblinux_s.h
+new file mode 100644
+index 0000000..97e9167
+--- /dev/null
++++ b/drivers/staging/winbond/wblinux_s.h
+@@ -0,0 +1,45 @@
++//============================================================
++// wblinux_s.h
++//
++#define OS_MEMORY_ALLOC( _V, _S ) WBLINUX_MemoryAlloc( _V, _S )
++#define OS_LINK_STATUS (Adapter->WbLinux.LinkStatus == OS_CONNECTED)
++#define OS_SET_SHUTDOWN( _A ) _A->WbLinux.shutdown=1
++#define OS_SET_RESUME( _A ) _A->WbLinux.shutdown=0
++#define OS_CONNECT_STATUS_INDICATE( _A, _F ) WBLINUX_ConnectStatus( _A, _F )
++#define OS_DISCONNECTED 0
++#define OS_CONNECTED 1
++#define OS_STOP( _A ) WBLINUX_stop( _A )
++
++#define OS_CURRENT_RX_BYTE( _A ) _A->WbLinux.RxByteCount
++#define OS_CURRENT_TX_BYTE( _A ) _A->WbLinux.TxByteCount
++#define OS_EVENT_INDICATE( _A, _B, _F )
++#define OS_PMKID_STATUS_EVENT( _A )
++#define OS_RECEIVE_PACKET_INDICATE( _A, _D ) WBLinux_ReceivePacket( _A, _D )
++#define OS_RECEIVE_802_1X_PACKET_INDICATE( _A, _D ) EAP_ReceivePacket( _A, _D )
++#define OS_GET_PACKET( _A, _D ) WBLINUX_GetNextPacket( _A, _D )
++#define OS_GET_PACKET_COMPLETE( _A, _D ) WBLINUX_GetNextPacketCompleted( _A, _D )
++#define OS_SEND_RESULT( _A, _ID, _R )
++
++#define WBLINUX_PACKET_ARRAY_SIZE (ETHERNET_TX_DESCRIPTORS*4)
++
++typedef struct _WBLINUX
++{
++ OS_SPIN_LOCK AtomicSpinLock;
++ OS_SPIN_LOCK SpinLock;
++ u32 shutdown;
++
++ OS_ATOMIC ThreadCount;
++
++ u32 LinkStatus; // OS_DISCONNECTED or OS_CONNECTED
++
++ u32 RxByteCount;
++ u32 TxByteCount;
++
++ struct sk_buff *skb_array[ WBLINUX_PACKET_ARRAY_SIZE ];
++ struct sk_buff *packet_return;
++ s32 skb_SetIndex;
++ s32 skb_GetIndex;
++ s32 netif_state_stop; // 1: stop 0: normal
++} WBLINUX, *PWBLINUX;
++
++
+--
+1.6.0.2
+