Staging: add w35und wifi driver
authorPavel Machek <pavel@suse.cz>
Wed, 1 Oct 2008 12:36:56 +0000 (14:36 +0200)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 10 Oct 2008 22:31:09 +0000 (15:31 -0700)
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>
53 files changed:
drivers/staging/Kconfig
drivers/staging/Makefile
drivers/staging/winbond/Kconfig [new file with mode: 0644]
drivers/staging/winbond/Makefile [new file with mode: 0644]
drivers/staging/winbond/README [new file with mode: 0644]
drivers/staging/winbond/adapter.h [new file with mode: 0644]
drivers/staging/winbond/bss_f.h [new file with mode: 0644]
drivers/staging/winbond/bssdscpt.h [new file with mode: 0644]
drivers/staging/winbond/ds_tkip.h [new file with mode: 0644]
drivers/staging/winbond/gl_80211.h [new file with mode: 0644]
drivers/staging/winbond/ioctls.h [new file with mode: 0644]
drivers/staging/winbond/linux/common.h [new file with mode: 0644]
drivers/staging/winbond/linux/sysdef.h [new file with mode: 0644]
drivers/staging/winbond/linux/wb35reg.c [new file with mode: 0644]
drivers/staging/winbond/linux/wb35reg_f.h [new file with mode: 0644]
drivers/staging/winbond/linux/wb35reg_s.h [new file with mode: 0644]
drivers/staging/winbond/linux/wb35rx.c [new file with mode: 0644]
drivers/staging/winbond/linux/wb35rx_f.h [new file with mode: 0644]
drivers/staging/winbond/linux/wb35rx_s.h [new file with mode: 0644]
drivers/staging/winbond/linux/wb35tx.c [new file with mode: 0644]
drivers/staging/winbond/linux/wb35tx_f.h [new file with mode: 0644]
drivers/staging/winbond/linux/wb35tx_s.h [new file with mode: 0644]
drivers/staging/winbond/linux/wbusb.c [new file with mode: 0644]
drivers/staging/winbond/linux/wbusb_f.h [new file with mode: 0644]
drivers/staging/winbond/linux/wbusb_s.h [new file with mode: 0644]
drivers/staging/winbond/localpara.h [new file with mode: 0644]
drivers/staging/winbond/mac_structures.h [new file with mode: 0644]
drivers/staging/winbond/mds.c [new file with mode: 0644]
drivers/staging/winbond/mds_f.h [new file with mode: 0644]
drivers/staging/winbond/mds_s.h [new file with mode: 0644]
drivers/staging/winbond/mlme_mib.h [new file with mode: 0644]
drivers/staging/winbond/mlme_s.h [new file with mode: 0644]
drivers/staging/winbond/mlmetxrx.c [new file with mode: 0644]
drivers/staging/winbond/mlmetxrx_f.h [new file with mode: 0644]
drivers/staging/winbond/mto.c [new file with mode: 0644]
drivers/staging/winbond/mto.h [new file with mode: 0644]
drivers/staging/winbond/mto_f.h [new file with mode: 0644]
drivers/staging/winbond/os_common.h [new file with mode: 0644]
drivers/staging/winbond/phy_calibration.c [new file with mode: 0644]
drivers/staging/winbond/phy_calibration.h [new file with mode: 0644]
drivers/staging/winbond/reg.c [new file with mode: 0644]
drivers/staging/winbond/rxisr.c [new file with mode: 0644]
drivers/staging/winbond/scan_s.h [new file with mode: 0644]
drivers/staging/winbond/sme_api.c [new file with mode: 0644]
drivers/staging/winbond/sme_api.h [new file with mode: 0644]
drivers/staging/winbond/sme_s.h [new file with mode: 0644]
drivers/staging/winbond/wb35_ver.h [new file with mode: 0644]
drivers/staging/winbond/wbhal.c [new file with mode: 0644]
drivers/staging/winbond/wbhal_f.h [new file with mode: 0644]
drivers/staging/winbond/wbhal_s.h [new file with mode: 0644]
drivers/staging/winbond/wblinux.c [new file with mode: 0644]
drivers/staging/winbond/wblinux_f.h [new file with mode: 0644]
drivers/staging/winbond/wblinux_s.h [new file with mode: 0644]

index 4dbf795..fdbdf84 100644 (file)
@@ -35,4 +35,6 @@ source "drivers/staging/go7007/Kconfig"
 
 source "drivers/staging/usbip/Kconfig"
 
+source "drivers/staging/winbond/Kconfig"
+
 endif # STAGING
index be42c0d..9b576c9 100644 (file)
@@ -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 (file)
index 0000000..10d72be
--- /dev/null
@@ -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 (file)
index 0000000..29c98bf
--- /dev/null
@@ -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 (file)
index 0000000..707b6b3
--- /dev/null
@@ -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 (file)
index 0000000..609701d
--- /dev/null
@@ -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 (file)
index 0000000..c957bc9
--- /dev/null
@@ -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 (file)
index 0000000..97150a2
--- /dev/null
@@ -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 (file)
index 0000000..29e5055
--- /dev/null
@@ -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 (file)
index 0000000..1806d81
--- /dev/null
@@ -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 (file)
index 0000000..e8b35dc
--- /dev/null
@@ -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 (file)
index 0000000..6b00bad
--- /dev/null
@@ -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 (file)
index 0000000..d46d63e
--- /dev/null
@@ -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 (file)
index 0000000..2c0b454
--- /dev/null
@@ -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, &ltmp );
+
+       //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 (file)
index 0000000..38e2906
--- /dev/null
@@ -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 (file)
index 0000000..a7595b1
--- /dev/null
@@ -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 (file)
index 0000000..26157eb
--- /dev/null
@@ -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 (file)
index 0000000..daa3e73
--- /dev/null
@@ -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 (file)
index 0000000..53b831f
--- /dev/null
@@ -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 (file)
index 0000000..cf19c3b
--- /dev/null
@@ -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 (file)
index 0000000..7705a84
--- /dev/null
@@ -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 (file)
index 0000000..ac43257
--- /dev/null
@@ -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 (file)
index 0000000..cbad5fb
--- /dev/null
@@ -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, &ltmp, 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 (file)
index 0000000..cae29e1
--- /dev/null
@@ -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 (file)
index 0000000..d5c1d53
--- /dev/null
@@ -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 (file)
index 0000000..268cf91
--- /dev/null
@@ -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 (file)
index 0000000..031d2cb
--- /dev/null
@@ -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 (file)
index 0000000..8ce6389
--- /dev/null
@@ -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 (file)
index 0000000..651188b
--- /dev/null
@@ -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 (file)
index 0000000..4738279
--- /dev/null
@@ -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 (file)
index 0000000..8975973
--- /dev/null
@@ -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 (file)
index 0000000..58094f6
--- /dev/null
@@ -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 (file)
index 0000000..46b091e
--- /dev/null
@@ -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 (file)
index 0000000..d74e225
--- /dev/null
@@ -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 (file)
index 0000000..2ef60e5
--- /dev/null
@@ -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 (file)
index 0000000..f47936f
--- /dev/null
@@ -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 (file)
index 0000000..30b3df2
--- /dev/null
@@ -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 (file)
index 0000000..e24ff41
--- /dev/null
@@ -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 (file)
index 0000000..272a650
--- /dev/null
@@ -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, &reg_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, &reg_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, &reg_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, &reg_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, &reg_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, &reg_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, &reg_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, &reg_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, &reg_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, &reg_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, &reg_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, &reg_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, &reg_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, &reg_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, &reg_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, &reg_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, &reg_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, &reg_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 (file)
index 0000000..b6a65d3
--- /dev/null
@@ -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 (file)
index 0000000..b475c7a
--- /dev/null
@@ -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, &ltmp );
+       *(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, &ltmp );
+       *(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, &ltmp );
+       *(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, &ltmp );
+               loop = 500; // Wait for 5 second 20061101
+               while( !(ltmp & 0x20) && loop-- )
+               {
+                       OS_SLEEP(10000); // Modify 20051221.1.b
+                       if( !Wb35Reg_ReadSync( pHwData, 0x03d0, &ltmp ) )
+                               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, &ltmp );
+               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 (file)
index 0000000..18e942c
--- /dev/null
@@ -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 (file)
index 0000000..1d1b0c4
--- /dev/null
@@ -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 (file)
index 0000000..40e93b7
--- /dev/null
@@ -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 (file)
index 0000000..016b225
--- /dev/null
@@ -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 (file)
index 0000000..dfd2fbc
--- /dev/null
@@ -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 (file)
index 0000000..2433bc0
--- /dev/null
@@ -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 (file)
index 0000000..daf4422
--- /dev/null
@@ -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 (file)
index 0000000..fe25f97
--- /dev/null
@@ -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 (file)
index 0000000..5b862ff
--- /dev/null
@@ -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 (file)
index 0000000..2eade5a
--- /dev/null
@@ -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 (file)
index 0000000..68240c5
--- /dev/null
@@ -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 (file)
index 0000000..97e9167
--- /dev/null
@@ -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;
+
+