diff options
53 files changed, 14522 insertions, 0 deletions
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 4dbf795df744..fdbdf84e3077 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -35,4 +35,6 @@ source "drivers/staging/go7007/Kconfig" source "drivers/staging/usbip/Kconfig" +source "drivers/staging/winbond/Kconfig" + endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index be42c0d4db0e..9b576c91b15e 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -6,3 +6,4 @@ obj-$(CONFIG_SXG) += sxg/ obj-$(CONFIG_ME4000) += me4000/ obj-$(CONFIG_VIDEO_GO7007) += go7007/ obj-$(CONFIG_USB_IP_COMMON) += usbip/ +obj-$(CONFIG_W35UND) += winbond/ diff --git a/drivers/staging/winbond/Kconfig b/drivers/staging/winbond/Kconfig new file mode 100644 index 000000000000..10d72bec88a9 --- /dev/null +++ b/drivers/staging/winbond/Kconfig @@ -0,0 +1,7 @@ +config W35UND + tristate "Winbond driver" + depends on MAC80211 && WLAN_80211 && EXPERIMENTAL && !4KSTACKS + default n + ---help--- + This is highly experimental driver for winbond wifi card on some Kohjinsha notebooks + Check http://code.google.com/p/winbondport/ for new version diff --git a/drivers/staging/winbond/Makefile b/drivers/staging/winbond/Makefile new file mode 100644 index 000000000000..29c98bf1bc98 --- /dev/null +++ b/drivers/staging/winbond/Makefile @@ -0,0 +1,18 @@ + DRIVER_DIR=./linux + +w35und-objs := $(DRIVER_DIR)/wbusb.o $(DRIVER_DIR)/wb35reg.o $(DRIVER_DIR)/wb35rx.o $(DRIVER_DIR)/wb35tx.o \ + mds.o \ + mlmetxrx.o \ + mto.o \ + phy_calibration.o \ + reg.o \ + rxisr.o \ + sme_api.o \ + wbhal.o \ + wblinux.o \ + + +obj-$(CONFIG_W35UND) += w35und.o + + + diff --git a/drivers/staging/winbond/README b/drivers/staging/winbond/README new file mode 100644 index 000000000000..707b6b354dc5 --- /dev/null +++ b/drivers/staging/winbond/README @@ -0,0 +1,10 @@ +TODO: + - sparse cleanups + - checkpatch cleanups + - kerneldoc cleanups + - remove typedefs + - remove unused ioctls + - use cfg80211 for regulatory stuff + +Please send patches to Greg Kroah-Hartman <greg@kroah.com> and +Pavel Machek <pavel@suse.cz> diff --git a/drivers/staging/winbond/adapter.h b/drivers/staging/winbond/adapter.h new file mode 100644 index 000000000000..609701d21cf0 --- /dev/null +++ b/drivers/staging/winbond/adapter.h @@ -0,0 +1,23 @@ +// +// ADAPTER.H - +// Windows NDIS global variable 'Adapter' typedef +// +#define MAX_ANSI_STRING 40 +typedef struct WB32_ADAPTER +{ + u32 AdapterIndex; // 20060703.4 Add for using pAdapterContext global Adapter point + + WB_LOCALDESCRIPT sLocalPara; // Myself connected parameters + PWB_BSSDESCRIPTION asBSSDescriptElement; + + MLME_FRAME sMlmeFrame; // connect to peerSTA parameters + + MTO_PARAMETERS sMtoPara; // MTO_struct ... + hw_data_t sHwData; //For HAL + MDS Mds; + + WBLINUX WbLinux; + struct iw_statistics iw_stats; + + u8 LinkName[MAX_ANSI_STRING]; +} WB32_ADAPTER, ADAPTER, *PWB32_ADAPTER, *PADAPTER; diff --git a/drivers/staging/winbond/bss_f.h b/drivers/staging/winbond/bss_f.h new file mode 100644 index 000000000000..c957bc94f08d --- /dev/null +++ b/drivers/staging/winbond/bss_f.h @@ -0,0 +1,59 @@ +// +// BSS descriptor DataBase management global function +// + +void vBSSdescriptionInit(PWB32_ADAPTER Adapter); +void vBSSfoundList(PWB32_ADAPTER Adapter); +u8 boChanFilter(PWB32_ADAPTER Adapter, u8 ChanNo); +u16 wBSSallocateEntry(PWB32_ADAPTER Adapter); +u16 wBSSGetEntry(PWB32_ADAPTER Adapter); +void vSimpleHouseKeeping(PWB32_ADAPTER Adapter); +u16 wBSShouseKeeping(PWB32_ADAPTER Adapter); +void ClearBSSdescpt(PWB32_ADAPTER Adapter, u16 i); +u16 wBSSfindBssID(PWB32_ADAPTER Adapter, u8 *pbBssid); +u16 wBSSfindDedicateCandidate(PWB32_ADAPTER Adapter, struct SSID_Element *psSsid, u8 *pbBssid); +u16 wBSSfindMACaddr(PWB32_ADAPTER Adapter, u8 *pbMacAddr); +u16 wBSSsearchMACaddr(PWB32_ADAPTER Adapter, u8 *pbMacAddr, u8 band); +u16 wBSSaddScanData(PWB32_ADAPTER, u16, psRXDATA); +u16 wBSSUpdateScanData(PWB32_ADAPTER Adapter, u16 wBssIdx, psRXDATA psRcvData); +u16 wBSScreateIBSSdata(PWB32_ADAPTER Adapter, PWB_BSSDESCRIPTION psDesData); +void DesiredRate2BSSdescriptor(PWB32_ADAPTER Adapter, PWB_BSSDESCRIPTION psDesData, + u8 *pBasicRateSet, u8 BasicRateCount, + u8 *pOperationRateSet, u8 OperationRateCount); +void DesiredRate2InfoElement(PWB32_ADAPTER Adapter, u8 *addr, u16 *iFildOffset, + u8 *pBasicRateSet, u8 BasicRateCount, + u8 *pOperationRateSet, u8 OperationRateCount); +void BSSAddIBSSdata(PWB32_ADAPTER Adapter, PWB_BSSDESCRIPTION psDesData); +unsigned char boCmpMacAddr( PUCHAR, PUCHAR ); +unsigned char boCmpSSID(struct SSID_Element *psSSID1, struct SSID_Element *psSSID2); +u16 wBSSfindSSID(PWB32_ADAPTER Adapter, struct SSID_Element *psSsid); +u16 wRoamingQuery(PWB32_ADAPTER Adapter); +void vRateToBitmap(PWB32_ADAPTER Adapter, u16 index); +u8 bRateToBitmapIndex(PWB32_ADAPTER Adapter, u8 bRate); +u8 bBitmapToRate(u8 i); +unsigned char boIsERPsta(PWB32_ADAPTER Adapter, u16 i); +unsigned char boCheckConnect(PWB32_ADAPTER Adapter); +unsigned char boCheckSignal(PWB32_ADAPTER Adapter); +void AddIBSSIe(PWB32_ADAPTER Adapter,PWB_BSSDESCRIPTION psDesData );//added by ws for WPA_None06/01/04 +void BssScanUpToDate(PWB32_ADAPTER Adapter); +void BssUpToDate(PWB32_ADAPTER Adapter); +void RateSort(u8 *RateArray, u8 num, u8 mode); +void RateReSortForSRate(PWB32_ADAPTER Adapter, u8 *RateArray, u8 num); +void Assemble_IE(PWB32_ADAPTER Adapter, u16 wBssIdx); +void SetMaxTxRate(PWB32_ADAPTER Adapter); + +void CreateWpaIE(PWB32_ADAPTER Adapter, u16* iFildOffset, PUCHAR msg, struct Management_Frame* msgHeader, + struct Association_Request_Frame_Body* msgBody, u16 iMSindex); //added by WS 05/14/05 + +#ifdef _WPA2_ +void CreateRsnIE(PWB32_ADAPTER Adapter, u16* iFildOffset, PUCHAR msg, struct Management_Frame* msgHeader, + struct Association_Request_Frame_Body* msgBody, u16 iMSindex);//added by WS 05/14/05 + +u16 SearchPmkid(PWB32_ADAPTER Adapter, struct Management_Frame* msgHeader, + struct PMKID_Information_Element * AssoReq_PMKID ); +#endif + + + + + diff --git a/drivers/staging/winbond/bssdscpt.h b/drivers/staging/winbond/bssdscpt.h new file mode 100644 index 000000000000..97150a2655fb --- /dev/null +++ b/drivers/staging/winbond/bssdscpt.h @@ -0,0 +1,156 @@ +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// bssdscpt.c +// BSS descriptor data base +// history : +// +// Description: +// BSS descriptor data base will store the information of the stations at the +// surrounding environment. The first entry( psBSS(0) ) will not be used and the +// second one( psBSS(1) ) will be used for the broadcast address. +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +//#define MAX_ACC_RSSI_COUNT 10 +#define MAX_ACC_RSSI_COUNT 6 + +/////////////////////////////////////////////////////////////////////////// +// +// BSS Description set Element , to store scan received Beacon information +// +// Our's differs slightly from the specs. The specify a PHY_Parameter_Set. +// Since we're only doing a DS design right now, we just have a DS structure. +////////////////////////////////////////////////////////////////////////////// +typedef struct BSSDescriptionElement +{ + u32 SlotValid; + u32 PowerSaveMode; + RXLAYER1 RxLayer1; + + u8 abPeerAddress[ MAC_ADDR_LENGTH + 2 ]; // peer MAC Address associated with this session. 6-OCTET value + u32 dwBgScanStamp; // BgScan Sequence Counter stamp, record psROAM->dwScanCounter. + + u16 Beacon_Period; + u16 wATIM_Window; + + u8 abBssID[ MAC_ADDR_LENGTH + 2 ]; // 6B + + u8 bBssType; + u8 DTIM_Period; // 1 octet usually from TIM element, if present + u8 boInTimerHandler; + u8 boERP; // analysis ERP or (extended) supported rate element + + u8 Timestamp[8]; + u8 BasicRate[32]; + u8 OperationalRate[32]; + u32 dwBasicRateBitmap; //bit map, retrieve from SupportedRateSet + u32 dwOperationalRateBitmap; //bit map, retrieve from SupportedRateSet and + // ExtendedSupportedRateSet + // For RSSI calculating + u32 HalRssi[MAX_ACC_RSSI_COUNT]; // Encode. It must use MACRO of HAL to get the LNA and AGC data + u32 HalRssiIndex; + + ////From beacon/probe response + struct SSID_Element SSID; // 34B + u8 reserved_1[ 2 ]; + + struct Capability_Information_Element CapabilityInformation; // 2B + u8 reserved_2[ 2 ]; + + struct CF_Parameter_Set_Element CF_Parameter_Set; // 8B + struct IBSS_Parameter_Set_Element IBSS_Parameter_Set; // 4B + struct TIM_Element TIM_Element_Set; // 256B + + struct DS_Parameter_Set_Element DS_Parameter_Set; // 3B + u8 reserved_3; + + struct ERP_Information_Element ERP_Information_Set; // 3B + u8 reserved_4; + + struct Supported_Rates_Element SupportedRateSet; // 10B + u8 reserved_5[2]; + + struct Extended_Supported_Rates_Element ExtendedSupportedRateSet; // 257B + u8 reserved_6[3]; + + u8 band; + u8 reserved_7[3]; + + // for MLME module + u16 wState; // the current state of the system + u16 wIndex; // THIS BSS element entry index + + void* psAdapter; // pointer to THIS Adapter + OS_TIMER nTimer; // MLME timer + + // Authentication + u16 wAuthAlgo; // peer MAC MLME use Auth algorithm, default OPEN_AUTH + u16 wAuthSeqNum; // current local MAC sendout AuthReq sequence number + + u8 auth_challengeText[128]; + + ////For XP: + u32 ies_len; // information element length + u8 ies[256]; // information element + + ////For WPA + u8 RsnIe_Type[2]; //added by ws for distinguish WPA and WPA2 05/14/04 + u8 RsnIe_len; + u8 Rsn_Num; + + // to record the rsn cipher suites,addded by ws 09/05/04 + SUITE_SELECTOR group_cipher; // 4B + SUITE_SELECTOR pairwise_key_cipher_suites[WLAN_MAX_PAIRWISE_CIPHER_SUITE_COUNT]; + SUITE_SELECTOR auth_key_mgt_suites[WLAN_MAX_AUTH_KEY_MGT_SUITE_LIST_COUNT]; + + u16 pairwise_key_cipher_suite_count; + u16 auth_key_mgt_suite_count; + + u8 pairwise_key_cipher_suite_selected; + u8 auth_key_mgt_suite_selected; + u8 reserved_8[2]; + + struct RSN_Capability_Element rsn_capabilities; // 2B + u8 reserved_9[2]; + + //to record the rsn cipher suites for WPA2 + #ifdef _WPA2_ + u32 pre_auth; //added by WS for distinguish for 05/04/04 + SUITE_SELECTOR wpa2_group_cipher; // 4B + SUITE_SELECTOR wpa2_pairwise_key_cipher_suites[WLAN_MAX_PAIRWISE_CIPHER_SUITE_COUNT]; + SUITE_SELECTOR wpa2_auth_key_mgt_suites[WLAN_MAX_AUTH_KEY_MGT_SUITE_LIST_COUNT]; + + u16 wpa2_pairwise_key_cipher_suite_count; + u16 wpa2_auth_key_mgt_suite_count; + + u8 wpa2_pairwise_key_cipher_suite_selected; + u8 wpa2_auth_key_mgt_suite_selected; + u8 reserved_10[2]; + + struct RSN_Capability_Element wpa2_rsn_capabilities; // 2B + u8 reserved_11[2]; + #endif //endif _WPA2_ + + //For Replay protection +// u8 PairwiseTSC[6]; +// u8 GroupTSC[6]; + + ////For up-to-date + u32 ScanTimeStamp; //for the decision whether the station/AP(may exist at + //different channels) has left. It must be detected by + //scanning. Local device may connected or disconnected. + u32 BssTimeStamp; //Only for the decision whether the station/AP(exist in + //the same channel, and no scanning) if local device has + //connected successfully. + + // 20061108 Add for storing WPS_IE. [E id][Length][OUI][Data] + u8 WPS_IE_Data[MAX_IE_APPEND_SIZE]; + u16 WPS_IE_length; + u16 WPS_IE_length_tmp; // For verify there is an WPS_IE in Beacon or probe response + +} WB_BSSDESCRIPTION, *PWB_BSSDESCRIPTION; + +#define wBSSConnectedSTA(Adapter) \ + ((u16)(Adapter)->sLocalPara.wConnectedSTAindex) + +#define psBSS(i) (&(Adapter->asBSSDescriptElement[(i)])) + + diff --git a/drivers/staging/winbond/ds_tkip.h b/drivers/staging/winbond/ds_tkip.h new file mode 100644 index 000000000000..29e5055b45a1 --- /dev/null +++ b/drivers/staging/winbond/ds_tkip.h @@ -0,0 +1,33 @@ +// Rotation functions on 32 bit values +#define ROL32( A, n ) \ + ( ((A) << (n)) | ( ((A)>>(32-(n))) & ( (1UL << (n)) - 1 ) ) ) + +#define ROR32( A, n ) ROL32( (A), 32-(n) ) + + +typedef struct tkip +{ + u32 K0, K1; // Key + union + { + struct // Current state + { + u32 L; + u32 R; + }; + u8 LR[8]; + }; + union + { + u32 M; // Message accumulator (single word) + u8 Mb[4]; + }; + s32 bytes_in_M; // # bytes in M +} tkip_t; + +//void _append_data( PUCHAR pData, u16 size, tkip_t *p ); +void Mds_MicGet( void* Adapter, void* pRxLayer1, PUCHAR pKey, PUCHAR pMic ); +void Mds_MicFill( void* Adapter, void* pDes, PUCHAR XmitBufAddress ); + + + diff --git a/drivers/staging/winbond/gl_80211.h b/drivers/staging/winbond/gl_80211.h new file mode 100644 index 000000000000..1806d817496e --- /dev/null +++ b/drivers/staging/winbond/gl_80211.h @@ -0,0 +1,125 @@ + +#ifndef __GL_80211_H__ +#define __GL_80211_H__ + +/****************** CONSTANT AND MACRO SECTION ******************************/ + +/* BSS Type */ +enum { + WLAN_BSSTYPE_INFRASTRUCTURE = 0, + WLAN_BSSTYPE_INDEPENDENT, + WLAN_BSSTYPE_ANY_BSS, +}; + + + +/* Preamble_Type, see <SFS-802.11G-MIB-203> */ +typedef enum preamble_type { + WLAN_PREAMBLE_TYPE_SHORT, + WLAN_PREAMBLE_TYPE_LONG, +} preamble_type_e; + + +/* Slot_Time_Type, see <SFS-802.11G-MIB-208> */ +typedef enum slot_time_type { + WLAN_SLOT_TIME_TYPE_LONG, + WLAN_SLOT_TIME_TYPE_SHORT, +} slot_time_type_e; + +/*--------------------------------------------------------------------------*/ +/* Encryption Mode */ +typedef enum { + WEP_DISABLE = 0, + WEP_64, + WEP_128, + + ENCRYPT_DISABLE, + ENCRYPT_WEP, + ENCRYPT_WEP_NOKEY, + ENCRYPT_TKIP, + ENCRYPT_TKIP_NOKEY, + ENCRYPT_CCMP, + ENCRYPT_CCMP_NOKEY, +} encryption_mode_e; + +typedef enum _WLAN_RADIO { + WLAN_RADIO_ON, + WLAN_RADIO_OFF, + WLAN_RADIO_MAX, // not a real type, defined as an upper bound +} WLAN_RADIO; + +typedef struct _WLAN_RADIO_STATUS { + WLAN_RADIO HWStatus; + WLAN_RADIO SWStatus; +} WLAN_RADIO_STATUS; + +//---------------------------------------------------------------------------- +// 20041021 1.1.81.1000 ybjiang +// add for radio notification +typedef +void (*RADIO_NOTIFICATION_HANDLER)( + void *Data, + void *RadioStatusBuffer, + u32 RadioStatusBufferLen + ); + +typedef struct _WLAN_RADIO_NOTIFICATION +{ + RADIO_NOTIFICATION_HANDLER RadioChangeHandler; + void *Data; +} WLAN_RADIO_NOTIFICATION; + +//---------------------------------------------------------------------------- +// 20041102 1.1.91.1000 ybjiang +// add for OID_802_11_CUST_REGION_CAPABILITIES and OID_802_11_OID_REGION +typedef enum _WLAN_REGION_CODE +{ + WLAN_REGION_UNKNOWN, + WLAN_REGION_EUROPE, + WLAN_REGION_JAPAN, + WLAN_REGION_USA, + WLAN_REGION_FRANCE, + WLAN_REGION_SPAIN, + WLAN_REGION_ISRAEL, + WLAN_REGION_MAX, // not a real type, defined as an upper bound +} WLAN_REGION_CODE; + +#define REGION_NAME_MAX_LENGTH 256 + +typedef struct _WLAN_REGION_CHANNELS +{ + u32 Length; + u32 NameLength; + u8 Name[REGION_NAME_MAX_LENGTH]; + WLAN_REGION_CODE Code; + u32 Frequency[1]; +} WLAN_REGION_CHANNELS; + +typedef struct _WLAN_REGION_CAPABILITIES +{ + u32 NumberOfItems; + WLAN_REGION_CHANNELS Region[1]; +} WLAN_REGION_CAPABILITIES; + +typedef struct _region_name_map { + WLAN_REGION_CODE region; + u8 *name; + u32 *channels; +} region_name_map; + +/*--------------------------------------------------------------------------*/ +#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] +#define MACSTR "%02X:%02X:%02X:%02X:%02X:%02X" + +// TODO: 0627 kevin +#define MIC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5], (a)[6], (a)[7] +#define MICSTR "%02X %02X %02X %02X %02X %02X %02X %02X" + +#define MICKEY2STR(a) MIC2STR(a) +#define MICKEYSTR MICSTR + + +#endif /* __GL_80211_H__ */ +/*** end of file ***/ + + diff --git a/drivers/staging/winbond/ioctls.h b/drivers/staging/winbond/ioctls.h new file mode 100644 index 000000000000..e8b35dc7e321 --- /dev/null +++ b/drivers/staging/winbond/ioctls.h @@ -0,0 +1,678 @@ +//============================================================================ +// IOCTLS.H - +// +// Description: +// Define the IOCTL codes. +// +// Revision history: +// -------------------------------------------------------------------------- +// +// Copyright (c) 2002-2004 Winbond Electronics Corp. All rights reserved. +//============================================================================= + +#ifndef _IOCTLS_H +#define _IOCTLS_H + +// PD43 Keep it - Used with the Win33 application +// #include <winioctl.h> + +//======================================================== +// 20040108 ADD the follow for test +//======================================================== +#define INFORMATION_LENGTH sizeof(unsigned int) + +#define WB32_IOCTL_INDEX 0x0900 //קďĽHŤKŹŰŽe// + +#define Wb32_RegisterRead CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB32_IOCTL_INDEX + 0, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define Wb32_RegisterWrite CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB32_IOCTL_INDEX + 1, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define Wb32_SendPacket CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB32_IOCTL_INDEX + 2, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define Wb32_QuerySendResult CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB32_IOCTL_INDEX + 3, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define Wb32_SetFragmentThreshold CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB32_IOCTL_INDEX + 4, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define Wb32_SetLinkStatus CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB32_IOCTL_INDEX + 5, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define Wb32_SetBulkIn CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB32_IOCTL_INDEX + 6, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define Wb32_LoopbackTest CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB32_IOCTL_INDEX + 7, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define Wb35_EEPromRead CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB32_IOCTL_INDEX + 8, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define Wb35_EEPromWrite CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB32_IOCTL_INDEX + 9, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define Wb35_FlashReadData CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB32_IOCTL_INDEX + 10, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define Wb35_FlashWrite CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB32_IOCTL_INDEX + 11, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define Wb35_FlashWriteBurst CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB32_IOCTL_INDEX + 12, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define Wb35_TxBurstStart CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB32_IOCTL_INDEX + 13, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define Wb35_TxBurstStop CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB32_IOCTL_INDEX + 14, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define Wb35_TxBurstStatus CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB32_IOCTL_INDEX + 15, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +// For IOCTL interface +//================================================ +#define LINKNAME_STRING "\\DosDevices\\W35UND" +#define NTDEVICE_STRING "\\Device\\W35UND" +#define APPLICATION_LINK "\\\\.\\W35UND" + +#define WB_IOCTL_INDEX 0x0800 +#define WB_IOCTL_TS_INDEX WB_IOCTL_INDEX + 60 +#define WB_IOCTL_DUT_INDEX WB_IOCTL_TS_INDEX + 40 + +//============================================================================= +// IOCTLS defined for DUT (Device Under Test) + +// IOCTL_WB_802_11_DUT_MAC_ADDRESS +// Query: Return the dot11StationID +// Set : Set the dot11StationID. Demo only. +// +#define IOCTL_WB_802_11_DUT_MAC_ADDRESS CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_DUT_INDEX + 1, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +// IOCTL_WB_802_11_DUT_BSS_DESCRIPTION +// Query: Return the info. of the current connected BSS. +// Set : None. +// +#define IOCTL_WB_802_11_DUT_BSS_DESCRIPTION CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_DUT_INDEX + 2, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +// IOCTL_WB_802_11_DUT_TX_RATE +// Query: Return the current transmission rate. +// Set : Set the transmission rate of the Tx packets. +// +#define IOCTL_WB_802_11_DUT_TX_RATE CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_DUT_INDEX + 3, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +// IOCTL_WB_802_11_DUT_CURRENT_STA_STATE +// Query: Return the current STA state. (WB_STASTATE type) +// Set : None. +// +#define IOCTL_WB_802_11_DUT_CURRENT_STA_STATE CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_DUT_INDEX + 4, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +/////////// 10/31/02' Added ///////////////////// + +// IOCTL_WB_802_11_DUT_START_IBSS_REQUEST +// Query: None. +// Set : Start a new IBSS +// +#define IOCTL_WB_802_11_DUT_START_IBSS_REQUEST CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_DUT_INDEX + 5, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +// IOCTL_WB_802_11_DUT_JOIN_REQUEST +// Query: None. +// Set : Synchronize with the selected BSS +// +#define IOCTL_WB_802_11_DUT_JOIN_REQUEST CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_DUT_INDEX + 6, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +// IOCTL_WB_802_11_DUT_AUTHEN_REQUEST +// Query: None. +// Set : Authenticate with the BSS +// +#define IOCTL_WB_802_11_DUT_AUTHEN_REQUEST CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_DUT_INDEX + 7, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +// IOCTL_WB_802_11_DUT_DEAUTHEN_REQUEST +// Query: None. +// Set : DeAuthenticate withe the BSS +// +#define IOCTL_WB_802_11_DUT_DEAUTHEN_REQUEST CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_DUT_INDEX + 8, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +// IOCTL_WB_802_11_DUT_ASSOC_REQUEST +// Query: None. +// Set : Associate withe the BSS +// +#define IOCTL_WB_802_11_DUT_ASSOC_REQUEST CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_DUT_INDEX + 9, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +// IOCTL_WB_802_11_DUT_REASSOC_REQUEST +// Query: None. +// Set : ReAssociate withe the BSS +// +#define IOCTL_WB_802_11_DUT_REASSOC_REQUEST CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_DUT_INDEX + 10, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + + +// IOCTL_WB_802_11_DUT_DISASSOC_REQUEST +// Query: None. +// Set : DisAssociate withe the BSS +// +#define IOCTL_WB_802_11_DUT_DISASSOC_REQUEST CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_DUT_INDEX + 11, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +// IOCTL_WB_802_11_DUT_FRAG_THRESHOLD +// Query: Return the dot11FragmentThreshold +// Set : Set the dot11FragmentThreshold +// +#define IOCTL_WB_802_11_DUT_FRAG_THRESHOLD CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_DUT_INDEX + 12, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +// IOCTL_WB_802_11_DUT_RTS_THRESHOLD +// Query: Return the dot11RTSThreshold +// Set : Set the dot11RTSThresold +// +#define IOCTL_WB_802_11_DUT_RTS_THRESHOLD CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_DUT_INDEX + 13, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +// IOCTL_WB_802_11_DUT_WEP_KEYMODE +// Query: Get the WEP key mode. +// Set : Set the WEP key mode: disable/64 bits/128 bits +// +#define IOCTL_WB_802_11_DUT_WEP_KEYMODE CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_DUT_INDEX + 14, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +// IOCTL_WB_802_11_DUT_WEP_KEYVALUE +// Query: None. +// Set : fill in the WEP key value +// +#define IOCTL_WB_802_11_DUT_WEP_KEYVALUE CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_DUT_INDEX + 15, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +// IOCTL_WB_802_11_DUT_RESET +// Query: None. +// Set : Reset S/W and H/W +// +#define IOCTL_WB_802_11_DUT_RESET CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_DUT_INDEX + 16, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +// IOCTL_WB_802_11_DUT_POWER_SAVE +// Query: None. +// Set : Set Power Save Mode +// +#define IOCTL_WB_802_11_DUT_POWER_SAVE CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_DUT_INDEX + 17, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +// IOCTL_WB_802_11_DUT_BSSID_LIST_SCAN +// Query: None. +// Set : +// +#define IOCTL_WB_802_11_DUT_BSSID_LIST_SCAN CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_DUT_INDEX + 18, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +// IOCTL_WB_802_11_DUT_BSSID_LIST +// Query: Return the BSS info of BSSs in the last scanning process +// Set : None. +// +#define IOCTL_WB_802_11_DUT_BSSID_LIST CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_DUT_INDEX + 19, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +// IOCTL_WB_802_11_DUT_STATISTICS +// Query: Return the statistics of Tx/Rx. +// Set : None. +// +#define IOCTL_WB_802_11_DUT_STATISTICS CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_DUT_INDEX + 20, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +// IOCTL_WB_802_11_DUT_ACCEPT_BEACON +// Query: Return the current mode to accept beacon or not. +// Set : Enable or disable allowing the HW-MAC to pass the beacon to the SW-MAC +// Arguments: unsigned char +// +#define IOCTL_WB_802_11_DUT_ACCEPT_BEACON CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_DUT_INDEX + 21, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +// IOCTL_WB_802_11_DUT_ROAMING +// Query: Return the roaming function status +// Set : Enable/Disable the roaming function. +#define IOCTL_WB_802_11_DUT_ROAMING CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_DUT_INDEX + 22, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +// IOCTL_WB_802_11_DUT_DTO +// Query: Return the DTO(Data Throughput Optimization) +// function status (TRUE or FALSE) +// Set : Enable/Disable the DTO function. +// +#define IOCTL_WB_802_11_DUT_DTO CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_DUT_INDEX + 23, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +// IOCTL_WB_802_11_DUT_ANTENNA_DIVERSITY +// Query: Return the antenna diversity status. (TRUE/ON or FALSE/OFF) +// Set : Enable/Disable the antenna diversity. +// +#define IOCTL_WB_802_11_DUT_ANTENNA_DIVERSITY CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_DUT_INDEX + 24, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +//-------------- new added for a+b+g --------------------- +// IOCTL_WB_802_11_DUT_MAC_OPERATION_MODE +// Query: Return the MAC operation mode. (MODE_802_11_BG, MODE_802_11_A, +// MODE_802_11_ABG, MODE_802_11_BG_IBSS) +// Set : Set the MAC operation mode. +// +#define IOCTL_WB_802_11_DUT_MAC_OPERATION_MODE CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_DUT_INDEX + 25, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +// IOCTL_WB_802_11_DUT_TX_RATE_REDEFINED +// Query: Return the current tx rate which follows the definition in spec. (for +// example, 5.5M => 0x0b) +// Set : None +// +#define IOCTL_WB_802_11_DUT_TX_RATE_REDEFINED CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_DUT_INDEX + 26, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +// IOCTL_WB_802_11_DUT_PREAMBLE_MODE +// Query: Return the preamble mode. (auto or long) +// Set : Set the preamble mode. +// +#define IOCTL_WB_802_11_DUT_PREAMBLE_MODE CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_DUT_INDEX + 27, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +// IOCTL_WB_802_11_DUT_SLOT_TIME_MODE +// Query: Return the slot time mode. (auto or long) +// Set : Set the slot time mode. +// +#define IOCTL_WB_802_11_DUT_SLOT_TIME_MODE CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_DUT_INDEX + 28, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) +//------------------------------------------------------------------ + +// IOCTL_WB_802_11_DUT_ADVANCE_STATUS +// Query: +// Set : NONE +// +#define IOCTL_WB_802_11_DUT_ADVANCE_STATUS CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_DUT_INDEX + 29, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +// IOCTL_WB_802_11_DUT_TX_RATE_MODE +// Query: Return the tx rate mode. (RATE_AUTO, RATE_1M, .., RATE_54M, RATE_MAX) +// Set : Set the tx rate mode. (RATE_AUTO, RATE_1M, .., RATE_54M, RATE_MAX) +// +#define IOCTL_WB_802_11_DUT_TX_RATE_MODE CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_DUT_INDEX + 30, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +// IOCTL_WB_802_11_DUT_DTO_PARA +// Query: Return the DTO parameters +// Set : Set the DTO parameters +// +#define IOCTL_WB_802_11_DUT_DTO_PARA CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_DUT_INDEX + 31, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +// IOCTL_WB_802_11_DUT_EVENT_LOG +// Query: Return event log +// Set : Reset event log +// +#define IOCTL_WB_802_11_DUT_EVENT_LOG CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_DUT_INDEX + 32, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +// IOCTL_WB_802_11_DUT_CWMIN +// Query: NONE(It will be obtained by IOCTL_WB_802_11_DUT_ADVANCE_STATUS) +// Set : Set CWMin value +// +#define IOCTL_WB_802_11_DUT_CWMIN CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_DUT_INDEX + 33, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +// IOCTL_WB_802_11_DUT_CWMAX +// Query: NONE(It will be obtained by IOCTL_WB_802_11_DUT_ADVANCE_STATUS) +// Set : Set CWMax value +// +#define IOCTL_WB_802_11_DUT_CWMAX CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_DUT_INDEX + 34, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + + +//========================================================== +// IOCTLs for Testing + +// IOCTL_WB_802_11_TS_SET_CXX_REG +// Query: None +// Set : Write the value to one of Cxx register. +// +#define IOCTL_WB_802_11_TS_SET_CXX_REG CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_TS_INDEX + 0, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +// IOCTL_WB_802_11_TS_GET_CXX_REG +// Query: Return the value of the Cxx register. +// Set : Write the reg no. (0x00, 0x04, 0x08 etc) +// +#define IOCTL_WB_802_11_TS_GET_CXX_REG CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_TS_INDEX + 1, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +// IOCTL_WB_802_11_TS_SET_DXX_REG +// Query: None +// Set : Write the value to one of Dxx register. +// +#define IOCTL_WB_802_11_TS_SET_DXX_REG CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_TS_INDEX + 2, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +// IOCTL_WB_802_11_TS_GET_DXX_REG +// Query: Return the value of the Dxx register. +// Set : Write the reg no. (0x00, 0x04, 0x08 etc) +// +#define IOCTL_WB_802_11_TS_GET_DXX_REG CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_TS_INDEX + 3, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +//============================================================ +// [TS] + +#define IOCTL_WB_802_11_TS_TX_RATE CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_TS_INDEX + 4, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define IOCTL_WB_802_11_TS_CURRENT_CHANNEL CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_TS_INDEX + 5, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define IOCTL_WB_802_11_TS_ENABLE_SEQNO CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_TS_INDEX + 6, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define IOCTL_WB_802_11_TS_ENALBE_ACKEDPACKET CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_TS_INDEX + 7, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define IOCTL_WB_802_11_TS_INHIBIT_CRC CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_TS_INDEX + 8, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define IOCTL_WB_802_11_TS_RESET_RCV_COUNTER CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_TS_INDEX + 9, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define IOCTL_WB_802_11_TS_SET_TX_TRIGGER CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_TS_INDEX + 10, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define IOCTL_WB_802_11_TS_FAILED_TX_COUNT CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_TS_INDEX + 11, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +// [TS1] +#define IOCTL_WB_802_11_TS_TX_POWER CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_TS_INDEX + 12, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define IOCTL_WB_802_11_TS_MODE_ENABLE CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_TS_INDEX + 13, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define IOCTL_WB_802_11_TS_MODE_DISABLE CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_TS_INDEX + 14, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define IOCTL_WB_802_11_TS_ANTENNA CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_TS_INDEX + 15, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define IOCTL_WB_802_11_TS_ADAPTER_INFO CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_TS_INDEX + 16, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define IOCTL_WB_802_11_TS_MAC_ADDRESS CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_TS_INDEX + 17, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define IOCTL_WB_802_11_TS_BSSID CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_TS_INDEX + 18, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define IOCTL_WB_802_11_TS_RF_PARAMETER CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_TS_INDEX + 19, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define IOCTL_WB_802_11_TS_FILTER CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_TS_INDEX + 20, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define IOCTL_WB_802_11_TS_CALIBRATION CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_TS_INDEX + 21, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define IOCTL_WB_802_11_TS_BSS_MODE CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_TS_INDEX + 22, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define IOCTL_WB_802_11_TS_SET_SSID CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_TS_INDEX + 23, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define IOCTL_WB_802_11_TS_IBSS_CHANNEL CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_TS_INDEX + 24, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +// set/query the slot time value(short or long slot time) +#define IOCTL_WB_802_11_TS_SLOT_TIME CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_TS_INDEX + 25, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define IOCTL_WB_802_11_TS_SLOT_TIME CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_TS_INDEX + 25, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define IOCTL_WB_802_11_TS_RX_STATISTICS CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + WB_IOCTL_TS_INDEX + 26, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#endif // #ifndef _IOCTLS_H + + diff --git a/drivers/staging/winbond/linux/common.h b/drivers/staging/winbond/linux/common.h new file mode 100644 index 000000000000..6b00bad74f78 --- /dev/null +++ b/drivers/staging/winbond/linux/common.h @@ -0,0 +1,143 @@ +// +// common.h +// +// This file contains the OS dependant definition and function. +// Every OS has this file individual. +// + +#define DebugUsbdStatusInformation( _A ) + +#ifndef COMMON_DEF +#define COMMON_DEF + +#include <linux/version.h> +#include <linux/usb.h> +#include <linux/kernel.h> //need for kernel alert +#include <linux/autoconf.h> +#include <linux/sched.h> +#include <linux/signal.h> +#include <linux/slab.h> //memory allocate +#include <linux/module.h> +#include <linux/netdevice.h> +#include <linux/etherdevice.h> +#include <linux/init.h>//need for init and exit modules marco +#include <linux/ctype.h> +#include <linux/wait.h> +#include <linux/list.h> +#include <linux/wireless.h> +#include <linux/if_arp.h> +#include <asm/uaccess.h> +#include <net/iw_handler.h> +#include <linux/skbuff.h> + + +//#define DEBUG_ENABLED 1 + + + +//=============================================================== +// Common type definition +//=============================================================== + +typedef u8* PUCHAR; +typedef s8* PCHAR; +typedef u8* PBOOLEAN; +typedef u16* PUSHORT; +typedef u32* PULONG; +typedef s16* PSHORT; + + +//=========================================== +#define IGNORE 2 +#define SUCCESS 1 +#define FAILURE 0 + + +#ifndef true +#define true 1 +#endif + +#ifndef false +#define false 0 +#endif + +// PD43 20021108 +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#define STATUS_MEDIA_CONNECT 1 +#define STATUS_MEDIA_DISCONNECT 0 + +#ifndef BIT +#define BIT(x) (1 << (x)) +#endif + +typedef struct urb * PURB; + + + +//================================================================================================== +// Common function definition +//================================================================================================== +#ifndef abs +#define abs(_T) ((_T) < 0 ? -_T : _T) +#endif +#define DEBUG_ENABLED +#define ETH_LENGTH_OF_ADDRESS 6 +#ifdef DEBUG_ENABLED +#define WBDEBUG( _M ) printk _M +#else +#define WBDEBUG( _M ) 0 +#endif + +#define OS_DISCONNECTED 0 +#define OS_CONNECTED 1 + + +#define OS_EVENT_INDICATE( _A, _B, _F ) +#define OS_PMKID_STATUS_EVENT( _A ) + + +/* Uff, no, longs are not atomic on all architectures Linux + * supports. This should really use atomic_t */ + +#define OS_ATOMIC u32 +#define OS_ATOMIC_READ( _A, _V ) _V +#define OS_ATOMIC_INC( _A, _V ) EncapAtomicInc( _A, (void*)_V ) +#define OS_ATOMIC_DEC( _A, _V ) EncapAtomicDec( _A, (void*)_V ) +#define OS_MEMORY_CLEAR( _A, _S ) memset( (PUCHAR)_A,0,_S) +#define OS_MEMORY_COMPARE( _A, _B, _S ) (memcmp(_A,_B,_S)? 0 : 1) // Definition is reverse with Ndis 1: the same 0: different + + +#define OS_SPIN_LOCK spinlock_t +#define OS_SPIN_LOCK_ALLOCATE( _S ) spin_lock_init( _S ); +#define OS_SPIN_LOCK_FREE( _S ) +#define OS_SPIN_LOCK_ACQUIRED( _S ) spin_lock_irq( _S ) +#define OS_SPIN_LOCK_RELEASED( _S ) spin_unlock_irq( _S ); + +#define OS_TIMER struct timer_list +#define OS_TIMER_INITIAL( _T, _F, _P ) \ +{ \ + init_timer( _T ); \ + (_T)->function = (void *)_F##_1a; \ + (_T)->data = (unsigned long)_P; \ +} + +// _S : Millisecond +// 20060420 At least 1 large than jiffies +#define OS_TIMER_SET( _T, _S ) \ +{ \ + (_T)->expires = jiffies + ((_S*HZ+999)/1000);\ + add_timer( _T ); \ +} +#define OS_TIMER_CANCEL( _T, _B ) del_timer_sync( _T ) +#define OS_TIMER_GET_SYS_TIME( _T ) (*_T=jiffies) + + +#endif // COMMON_DEF + diff --git a/drivers/staging/winbond/linux/sysdef.h b/drivers/staging/winbond/linux/sysdef.h new file mode 100644 index 000000000000..d46d63e5c673 --- /dev/null +++ b/drivers/staging/winbond/linux/sysdef.h @@ -0,0 +1,73 @@ + + +// +// Winbond WLAN System Configuration defines +// + +//===================================================================== +// Current directory is Linux +// The definition WB_LINUX is a keyword for this OS +//===================================================================== +#ifndef SYS_DEF_H +#define SYS_DEF_H +#define WB_LINUX +#define WB_LINUX_WPA_PSK + + +//#define _IBSS_BEACON_SEQ_STICK_ +#define _USE_FALLBACK_RATE_ +//#define ANTDIV_DEFAULT_ON + +#define _WPA2_ // 20061122 It's needed for current Linux driver + + +#ifndef _WPA_PSK_DEBUG +#undef _WPA_PSK_DEBUG +#endif + +// debug print options, mark what debug you don't need + +#ifdef FULL_DEBUG +#define _PE_STATE_DUMP_ +#define _PE_TX_DUMP_ +#define _PE_RX_DUMP_ +#define _PE_OID_DUMP_ +#define _PE_DTO_DUMP_ +#define _PE_REG_DUMP_ +#define _PE_USB_INI_DUMP_ +#endif + + + +#include "common.h" // Individual file depends on OS + +#include "../wb35_ver.h" +#include "../mac_structures.h" +#include "../ds_tkip.h" +#include "../localpara.h" +#include "../sme_s.h" +#include "../scan_s.h" +#include "../mds_s.h" +#include "../mlme_s.h" +#include "../bssdscpt.h" +#include "../sme_api.h" +#include "../gl_80211.h" +#include "../mto.h" +#include "../wblinux_s.h" +#include "../wbhal_s.h" + + +#include "../adapter.h" + +#include "../mlme_mib.h" +#include "../mds_f.h" +#include "../bss_f.h" +#include "../mlmetxrx_f.h" +#include "../mto_f.h" +#include "../wbhal_f.h" +#include "../wblinux_f.h" +// Kernel Timer resolution, NDIS is 10ms, 10000us +#define MIN_TIMEOUT_VAL (10) //ms + + +#endif diff --git a/drivers/staging/winbond/linux/wb35reg.c b/drivers/staging/winbond/linux/wb35reg.c new file mode 100644 index 000000000000..2c0b454e8cad --- /dev/null +++ b/drivers/staging/winbond/linux/wb35reg.c @@ -0,0 +1,747 @@ +#include "sysdef.h" + +extern void phy_calibration_winbond(hw_data_t *phw_data, u32 frequency); + +// TRUE : read command process successfully +// FALSE : register not support +// RegisterNo : start base +// pRegisterData : data point +// NumberOfData : number of register data +// Flag : AUTO_INCREMENT - RegisterNo will auto increment 4 +// NO_INCREMENT - Function will write data into the same register +unsigned char +Wb35Reg_BurstWrite(phw_data_t pHwData, u16 RegisterNo, PULONG pRegisterData, u8 NumberOfData, u8 Flag) +{ + PWB35REG pWb35Reg = &pHwData->Wb35Reg; + PURB pUrb = NULL; + PREG_QUEUE pRegQueue = NULL; + u16 UrbSize; + struct usb_ctrlrequest *dr; + u16 i, DataSize = NumberOfData*4; + + // Module shutdown + if (pHwData->SurpriseRemove) + return FALSE; + + // Trying to use burst write function if use new hardware + UrbSize = sizeof(REG_QUEUE) + DataSize + sizeof(struct usb_ctrlrequest); + OS_MEMORY_ALLOC( (void* *)&pRegQueue, UrbSize ); + pUrb = wb_usb_alloc_urb(0); + if( pUrb && pRegQueue ) { + pRegQueue->DIRECT = 2;// burst write register + pRegQueue->INDEX = RegisterNo; + pRegQueue->pBuffer = (PULONG)((PUCHAR)pRegQueue + sizeof(REG_QUEUE)); + memcpy( pRegQueue->pBuffer, pRegisterData, DataSize ); + //the function for reversing register data from little endian to big endian + for( i=0; i<NumberOfData ; i++ ) + pRegQueue->pBuffer[i] = cpu_to_le32( pRegQueue->pBuffer[i] ); + + dr = (struct usb_ctrlrequest *)((PUCHAR)pRegQueue + sizeof(REG_QUEUE) + DataSize); + dr->bRequestType = USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE; + dr->bRequest = 0x04; // USB or vendor-defined request code, burst mode + dr->wValue = cpu_to_le16( Flag ); // 0: Register number auto-increment, 1: No auto increment + dr->wIndex = cpu_to_le16( RegisterNo ); + dr->wLength = cpu_to_le16( DataSize ); + pRegQueue->Next = NULL; + pRegQueue->pUsbReq = dr; + pRegQueue->pUrb = pUrb; + + OS_SPIN_LOCK_ACQUIRED( &pWb35Reg->EP0VM_spin_lock ); + if (pWb35Reg->pRegFirst == NULL) + pWb35Reg->pRegFirst = pRegQueue; + else + pWb35Reg->pRegLast->Next = pRegQueue; + pWb35Reg->pRegLast = pRegQueue; + + OS_SPIN_LOCK_RELEASED( &pWb35Reg->EP0VM_spin_lock ); + + // Start EP0VM + Wb35Reg_EP0VM_start(pHwData); + + return TRUE; + } else { + if (pUrb) + usb_free_urb(pUrb); + if (pRegQueue) + kfree(pRegQueue); + return FALSE; + } + return FALSE; +} + +void +Wb35Reg_Update(phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue) +{ + PWB35REG pWb35Reg = &pHwData->Wb35Reg; + switch (RegisterNo) { + case 0x3b0: pWb35Reg->U1B0 = RegisterValue; break; + case 0x3bc: pWb35Reg->U1BC_LEDConfigure = RegisterValue; break; + case 0x400: pWb35Reg->D00_DmaControl = RegisterValue; break; + case 0x800: pWb35Reg->M00_MacControl = RegisterValue; break; + case 0x804: pWb35Reg->M04_MulticastAddress1 = RegisterValue; break; + case 0x808: pWb35Reg->M08_MulticastAddress2 = RegisterValue; break; + case 0x824: pWb35Reg->M24_MacControl = RegisterValue; break; + case 0x828: pWb35Reg->M28_MacControl = RegisterValue; break; + case 0x82c: pWb35Reg->M2C_MacControl = RegisterValue; break; + case 0x838: pWb35Reg->M38_MacControl = RegisterValue; break; + case 0x840: pWb35Reg->M40_MacControl = RegisterValue; break; + case 0x844: pWb35Reg->M44_MacControl = RegisterValue; break; + case 0x848: pWb35Reg->M48_MacControl = RegisterValue; break; + case 0x84c: pWb35Reg->M4C_MacStatus = RegisterValue; break; + case 0x860: pWb35Reg->M60_MacControl = RegisterValue; break; + case 0x868: pWb35Reg->M68_MacControl = RegisterValue; break; + case 0x870: pWb35Reg->M70_MacControl = RegisterValue; break; + case 0x874: pWb35Reg->M74_MacControl = RegisterValue; break; + case 0x878: pWb35Reg->M78_ERPInformation = RegisterValue; break; + case 0x87C: pWb35Reg->M7C_MacControl = RegisterValue; break; + case 0x880: pWb35Reg->M80_MacControl = RegisterValue; break; + case 0x884: pWb35Reg->M84_MacControl = RegisterValue; break; + case 0x888: pWb35Reg->M88_MacControl = RegisterValue; break; + case 0x898: pWb35Reg->M98_MacControl = RegisterValue; break; + case 0x100c: pWb35Reg->BB0C = RegisterValue; break; + case 0x102c: pWb35Reg->BB2C = RegisterValue; break; + case 0x1030: pWb35Reg->BB30 = RegisterValue; break; + case 0x103c: pWb35Reg->BB3C = RegisterValue; break; + case 0x1048: pWb35Reg->BB48 = RegisterValue; break; + case 0x104c: pWb35Reg->BB4C = RegisterValue; break; + case 0x1050: pWb35Reg->BB50 = RegisterValue; break; + case 0x1054: pWb35Reg->BB54 = RegisterValue; break; + case 0x1058: pWb35Reg->BB58 = RegisterValue; break; + case 0x105c: pWb35Reg->BB5C = RegisterValue; break; + case 0x1060: pWb35Reg->BB60 = RegisterValue; break; + } +} + +// TRUE : read command process successfully +// FALSE : register not support +unsigned char +Wb35Reg_WriteSync( phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue ) +{ + PWB35REG pWb35Reg = &pHwData->Wb35Reg; + int ret = -1; + + // Module shutdown + if (pHwData->SurpriseRemove) + return FALSE; + + RegisterValue = cpu_to_le32(RegisterValue); + + // update the register by send usb message------------------------------------ + pWb35Reg->SyncIoPause = 1; + + // 20060717.5 Wait until EP0VM stop + while (pWb35Reg->EP0vm_state != VM_STOP) + OS_SLEEP(10000); + + // Sync IoCallDriver + pWb35Reg->EP0vm_state = VM_RUNNING; + ret = usb_control_msg( pHwData->WbUsb.udev, + usb_sndctrlpipe( pHwData->WbUsb.udev, 0 ), + 0x03, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, + 0x0,RegisterNo, &RegisterValue, 4, HZ*100 ); + pWb35Reg->EP0vm_state = VM_STOP; + pWb35Reg->SyncIoPause = 0; + + Wb35Reg_EP0VM_start(pHwData); + + if (ret < 0) { + #ifdef _PE_REG_DUMP_ + WBDEBUG(("EP0 Write register usb message sending error\n")); + #endif + + pHwData->SurpriseRemove = 1; // 20060704.2 + return FALSE; + } + + return TRUE; +} + +// TRUE : read command process successfully +// FALSE : register not support +unsigned char +Wb35Reg_Write( phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue ) +{ + PWB35REG pWb35Reg = &pHwData->Wb35Reg; + struct usb_ctrlrequest *dr; + PURB pUrb = NULL; + PREG_QUEUE pRegQueue = NULL; + u16 UrbSize; + + + // Module shutdown + if (pHwData->SurpriseRemove) + return FALSE; + + // update the register by send urb request------------------------------------ + UrbSize = sizeof(REG_QUEUE) + sizeof(struct usb_ctrlrequest); + OS_MEMORY_ALLOC( (void* *)&pRegQueue, UrbSize ); + pUrb = wb_usb_alloc_urb(0); + if (pUrb && pRegQueue) { + pRegQueue->DIRECT = 1;// burst write register + pRegQueue->INDEX = RegisterNo; + pRegQueue->VALUE = cpu_to_le32(RegisterValue); + pRegQueue->RESERVED_VALID = FALSE; + dr = (struct usb_ctrlrequest *)((PUCHAR)pRegQueue + sizeof(REG_QUEUE)); + dr->bRequestType = USB_TYPE_VENDOR|USB_DIR_OUT |USB_RECIP_DEVICE; + dr->bRequest = 0x03; // USB or vendor-defined request code, burst mode + dr->wValue = cpu_to_le16(0x0); + dr->wIndex = cpu_to_le16(RegisterNo); + dr->wLength = cpu_to_le16(4); + + // Enter the sending queue + pRegQueue->Next = NULL; + pRegQueue->pUsbReq = dr; + pRegQueue->pUrb = pUrb; + + OS_SPIN_LOCK_ACQUIRED(&pWb35Reg->EP0VM_spin_lock ); + if (pWb35Reg->pRegFirst == NULL) + pWb35Reg->pRegFirst = pRegQueue; + else + pWb35Reg->pRegLast->Next = pRegQueue; + pWb35Reg->pRegLast = pRegQueue; + + OS_SPIN_LOCK_RELEASED( &pWb35Reg->EP0VM_spin_lock ); + + // Start EP0VM + Wb35Reg_EP0VM_start(pHwData); + + return TRUE; + } else { + if (pUrb) + usb_free_urb(pUrb); + kfree(pRegQueue); + return FALSE; + } +} + +//This command will be executed with a user defined value. When it completes, +//this value is useful. For example, hal_set_current_channel will use it. +// TRUE : read command process successfully +// FALSE : register not support +unsigned char +Wb35Reg_WriteWithCallbackValue( phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue, + PCHAR pValue, s8 Len) +{ + PWB35REG pWb35Reg = &pHwData->Wb35Reg; + struct usb_ctrlrequest *dr; + PURB pUrb = NULL; + PREG_QUEUE pRegQueue = NULL; + u16 UrbSize; + + // Module shutdown + if (pHwData->SurpriseRemove) + return FALSE; + + // update the register by send urb request------------------------------------ + UrbSize = sizeof(REG_QUEUE) + sizeof(struct usb_ctrlrequest); + OS_MEMORY_ALLOC((void* *) &pRegQueue, UrbSize ); + pUrb = wb_usb_alloc_urb(0); + if (pUrb && pRegQueue) { + pRegQueue->DIRECT = 1;// burst write register + pRegQueue->INDEX = RegisterNo; + pRegQueue->VALUE = cpu_to_le32(RegisterValue); + //NOTE : Users must guarantee the size of value will not exceed the buffer size. + memcpy(pRegQueue->RESERVED, pValue, Len); + pRegQueue->RESERVED_VALID = TRUE; + dr = (struct usb_ctrlrequest *)((PUCHAR)pRegQueue + sizeof(REG_QUEUE)); + dr->bRequestType = USB_TYPE_VENDOR|USB_DIR_OUT |USB_RECIP_DEVICE; + dr->bRequest = 0x03; // USB or vendor-defined request code, burst mode + dr->wValue = cpu_to_le16(0x0); + dr->wIndex = cpu_to_le16(RegisterNo); + dr->wLength = cpu_to_le16(4); + + // Enter the sending queue + pRegQueue->Next = NULL; + pRegQueue->pUsbReq = dr; + pRegQueue->pUrb = pUrb; + OS_SPIN_LOCK_ACQUIRED (&pWb35Reg->EP0VM_spin_lock ); + if( pWb35Reg->pRegFirst == NULL ) + pWb35Reg->pRegFirst = pRegQueue; + else + pWb35Reg->pRegLast->Next = pRegQueue; + pWb35Reg->pRegLast = pRegQueue; + + OS_SPIN_LOCK_RELEASED ( &pWb35Reg->EP0VM_spin_lock ); + + // Start EP0VM + Wb35Reg_EP0VM_start(pHwData); + return TRUE; + } else { + if (pUrb) + usb_free_urb(pUrb); + kfree(pRegQueue); + return FALSE; + } +} + +// TRUE : read command process successfully +// FALSE : register not support +// pRegisterValue : It must be a resident buffer due to asynchronous read register. +unsigned char +Wb35Reg_ReadSync( phw_data_t pHwData, u16 RegisterNo, PULONG pRegisterValue ) +{ + PWB35REG pWb35Reg = &pHwData->Wb35Reg; + PULONG pltmp = pRegisterValue; + int ret = -1; + + // Module shutdown + if (pHwData->SurpriseRemove) + return FALSE; + + // Read the register by send usb message------------------------------------ + + pWb35Reg->SyncIoPause = 1; + + // 20060717.5 Wait until EP0VM stop + while (pWb35Reg->EP0vm_state != VM_STOP) + OS_SLEEP(10000); + + pWb35Reg->EP0vm_state = VM_RUNNING; + ret = usb_control_msg( pHwData->WbUsb.udev, + usb_rcvctrlpipe(pHwData->WbUsb.udev, 0), + 0x01, USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_DIR_IN, + 0x0, RegisterNo, pltmp, 4, HZ*100 ); + + *pRegisterValue = cpu_to_le32(*pltmp); + + pWb35Reg->EP0vm_state = VM_STOP; + + Wb35Reg_Update( pHwData, RegisterNo, *pRegisterValue ); + pWb35Reg->SyncIoPause = 0; + + Wb35Reg_EP0VM_start( pHwData ); + + if (ret < 0) { + #ifdef _PE_REG_DUMP_ + WBDEBUG(("EP0 Read register usb message sending error\n")); + #endif + + pHwData->SurpriseRemove = 1; // 20060704.2 + return FALSE; + } + + return TRUE; +} + +// TRUE : read command process successfully +// FALSE : register not support +// pRegisterValue : It must be a resident buffer due to asynchronous read register. +unsigned char +Wb35Reg_Read(phw_data_t pHwData, u16 RegisterNo, PULONG pRegisterValue ) +{ + PWB35REG pWb35Reg = &pHwData->Wb35Reg; + struct usb_ctrlrequest * dr; + PURB pUrb; + PREG_QUEUE pRegQueue; + u16 UrbSize; + + // Module shutdown + if (pHwData->SurpriseRemove) + return FALSE; + + // update the variable by send Urb to read register ------------------------------------ + UrbSize = sizeof(REG_QUEUE) + sizeof(struct usb_ctrlrequest); + OS_MEMORY_ALLOC( (void* *)&pRegQueue, UrbSize ); + pUrb = wb_usb_alloc_urb(0); + if( pUrb && pRegQueue ) + { + pRegQueue->DIRECT = 0;// read register + pRegQueue->INDEX = RegisterNo; + pRegQueue->pBuffer = pRegisterValue; + dr = (struct usb_ctrlrequest *)((PUCHAR)pRegQueue + sizeof(REG_QUEUE)); + dr->bRequestType = USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_DIR_IN; + dr->bRequest = 0x01; // USB or vendor-defined request code, burst mode + dr->wValue = cpu_to_le16(0x0); + dr->wIndex = cpu_to_le16 (RegisterNo); + dr->wLength = cpu_to_le16 (4); + + // Enter the sending queue + pRegQueue->Next = NULL; + pRegQueue->pUsbReq = dr; + pRegQueue->pUrb = pUrb; + OS_SPIN_LOCK_ACQUIRED ( &pWb35Reg->EP0VM_spin_lock ); + if( pWb35Reg->pRegFirst == NULL ) + pWb35Reg->pRegFirst = pRegQueue; + else + pWb35Reg->pRegLast->Next = pRegQueue; + pWb35Reg->pRegLast = pRegQueue; + + OS_SPIN_LOCK_RELEASED( &pWb35Reg->EP0VM_spin_lock ); + + // Start EP0VM + Wb35Reg_EP0VM_start( pHwData ); + + return TRUE; + } else { + if (pUrb) + usb_free_urb( pUrb ); + kfree(pRegQueue); + return FALSE; + } +} + + +void +Wb35Reg_EP0VM_start( phw_data_t pHwData ) +{ + PWB35REG pWb35Reg = &pHwData->Wb35Reg; + + if (OS_ATOMIC_INC( pHwData->Adapter, &pWb35Reg->RegFireCount) == 1) { + pWb35Reg->EP0vm_state = VM_RUNNING; + Wb35Reg_EP0VM(pHwData); + } else + OS_ATOMIC_DEC( pHwData->Adapter, &pWb35Reg->RegFireCount ); +} + +void +Wb35Reg_EP0VM(phw_data_t pHwData ) +{ + PWB35REG pWb35Reg = &pHwData->Wb35Reg; + PURB pUrb; + struct usb_ctrlrequest *dr; + PULONG pBuffer; + int ret = -1; + PREG_QUEUE pRegQueue; + + + if (pWb35Reg->SyncIoPause) + goto cleanup; + + if (pHwData->SurpriseRemove) + goto cleanup; + + // Get the register data and send to USB through Irp + OS_SPIN_LOCK_ACQUIRED( &pWb35Reg->EP0VM_spin_lock ); + pRegQueue = pWb35Reg->pRegFirst; + OS_SPIN_LOCK_RELEASED( &pWb35Reg->EP0VM_spin_lock ); + + if (!pRegQueue) + goto cleanup; + + // Get an Urb, send it + pUrb = (PURB)pRegQueue->pUrb; + + dr = pRegQueue->pUsbReq; + pUrb = pRegQueue->pUrb; + pBuffer = pRegQueue->pBuffer; + if (pRegQueue->DIRECT == 1) // output + pBuffer = &pRegQueue->VALUE; + + usb_fill_control_urb( pUrb, pHwData->WbUsb.udev, + REG_DIRECTION(pHwData->WbUsb.udev,pRegQueue), + (PUCHAR)dr,pBuffer,cpu_to_le16(dr->wLength), + Wb35Reg_EP0VM_complete, (void*)pHwData); + + pWb35Reg->EP0vm_state = VM_RUNNING; + + ret = wb_usb_submit_urb( pUrb ); + + if (ret < 0) { +#ifdef _PE_REG_DUMP_ + WBDEBUG(("EP0 Irp sending error\n")); +#endif + goto cleanup; + } + + return; + + cleanup: + pWb35Reg->EP0vm_state = VM_STOP; + OS_ATOMIC_DEC( pHwData->Adapter, &pWb35Reg->RegFireCount ); +} + + +void +Wb35Reg_EP0VM_complete(PURB pUrb) +{ + phw_data_t pHwData = (phw_data_t)pUrb->context; + PWB35REG pWb35Reg = &pHwData->Wb35Reg; + PREG_QUEUE pRegQueue; + + + // Variable setting + pWb35Reg->EP0vm_state = VM_COMPLETED; + pWb35Reg->EP0VM_status = pUrb->status; + + if (pHwData->SurpriseRemove) { // Let WbWlanHalt to handle surprise remove + pWb35Reg->EP0vm_state = VM_STOP; + OS_ATOMIC_DEC( pHwData->Adapter, &pWb35Reg->RegFireCount ); + } else { + // Complete to send, remove the URB from the first + OS_SPIN_LOCK_ACQUIRED( &pWb35Reg->EP0VM_spin_lock ); + pRegQueue = pWb35Reg->pRegFirst; + if (pRegQueue == pWb35Reg->pRegLast) + pWb35Reg->pRegLast = NULL; + pWb35Reg->pRegFirst = pWb35Reg->pRegFirst->Next; + OS_SPIN_LOCK_RELEASED( &pWb35Reg->EP0VM_spin_lock ); + + if (pWb35Reg->EP0VM_status) { +#ifdef _PE_REG_DUMP_ + WBDEBUG(("EP0 IoCompleteRoutine return error\n")); + DebugUsbdStatusInformation( pWb35Reg->EP0VM_status ); +#endif + pWb35Reg->EP0vm_state = VM_STOP; + pHwData->SurpriseRemove = 1; + } else { + // Success. Update the result + + // Start the next send + Wb35Reg_EP0VM(pHwData); + } + + kfree(pRegQueue); + } + + usb_free_urb(pUrb); +} + + +void +Wb35Reg_destroy(phw_data_t pHwData) +{ + PWB35REG pWb35Reg = &pHwData->Wb35Reg; + PURB pUrb; + PREG_QUEUE pRegQueue; + + + Uxx_power_off_procedure(pHwData); + + // Wait for Reg operation completed + do { + OS_SLEEP(10000); // Delay for waiting function enter 940623.1.a + } while (pWb35Reg->EP0vm_state != VM_STOP); + OS_SLEEP(10000); // Delay for waiting function enter 940623.1.b + + // Release all the data in RegQueue + OS_SPIN_LOCK_ACQUIRED( &pWb35Reg->EP0VM_spin_lock ); + pRegQueue = pWb35Reg->pRegFirst; + while (pRegQueue) { + if (pRegQueue == pWb35Reg->pRegLast) + pWb35Reg->pRegLast = NULL; + pWb35Reg->pRegFirst = pWb35Reg->pRegFirst->Next; + + pUrb = pRegQueue->pUrb; + OS_SPIN_LOCK_RELEASED( &pWb35Reg->EP0VM_spin_lock ); + if (pUrb) { + usb_free_urb(pUrb); + kfree(pRegQueue); + } else { + #ifdef _PE_REG_DUMP_ + WBDEBUG(("EP0 queue release error\n")); + #endif + } + OS_SPIN_LOCK_ACQUIRED( &pWb35Reg->EP0VM_spin_lock ); + + pRegQueue = pWb35Reg->pRegFirst; + } + OS_SPIN_LOCK_RELEASED( &pWb35Reg->EP0VM_spin_lock ); + + // Free resource + OS_SPIN_LOCK_FREE( &pWb35Reg->EP0VM_spin_lock ); +} + +//==================================================================================== +// The function can be run in passive-level only. +//==================================================================================== +unsigned char Wb35Reg_initial(phw_data_t pHwData) +{ + PWB35REG pWb35Reg=&pHwData->Wb35Reg; + u32 ltmp; + u32 SoftwareSet, VCO_trim, TxVga, Region_ScanInterval; + + // Spin lock is acquired for read and write IRP command + OS_SPIN_LOCK_ALLOCATE( &pWb35Reg->EP0VM_spin_lock ); + + // Getting RF module type from EEPROM ------------------------------------ + Wb35Reg_WriteSync( pHwData, 0x03b4, 0x080d0000 ); // Start EEPROM access + Read + address(0x0d) + Wb35Reg_ReadSync( pHwData, 0x03b4, <mp ); + + //Update RF module type and determine the PHY type by inf or EEPROM + pWb35Reg->EEPROMPhyType = (u8)( ltmp & 0xff ); + // 0 V MAX2825, 1 V MAX2827, 2 V MAX2828, 3 V MAX2829 + // 16V AL2230, 17 - AL7230, 18 - AL2230S + // 32 Reserved + // 33 - W89RF242(TxVGA 0~19), 34 - W89RF242(TxVGA 0~34) + if (pWb35Reg->EEPROMPhyType != RF_DECIDE_BY_INF) { + if( (pWb35Reg->EEPROMPhyType == RF_MAXIM_2825) || + (pWb35Reg->EEPROMPhyType == RF_MAXIM_2827) || + (pWb35Reg->EEPROMPhyType == RF_MAXIM_2828) || + (pWb35Reg->EEPROMPhyType == RF_MAXIM_2829) || + (pWb35Reg->EEPROMPhyType == RF_MAXIM_V1) || + (pWb35Reg->EEPROMPhyType == RF_AIROHA_2230) || + (pWb35Reg->EEPROMPhyType == RF_AIROHA_2230S) || + (pWb35Reg->EEPROMPhyType == RF_AIROHA_7230) || + (pWb35Reg->EEPROMPhyType == RF_WB_242) || + (pWb35Reg->EEPROMPhyType == RF_WB_242_1)) + pHwData->phy_type = pWb35Reg->EEPROMPhyType; + } + + // Power On procedure running. The relative parameter will be set according to phy_type + Uxx_power_on_procedure( pHwData ); + + // Reading MAC address + Uxx_ReadEthernetAddress( pHwData ); + + // Read VCO trim for RF parameter + Wb35Reg_WriteSync( pHwData, 0x03b4, 0x08200000 ); + Wb35Reg_ReadSync( pHwData, 0x03b4, &VCO_trim ); + + // Read Antenna On/Off of software flag + Wb35Reg_WriteSync( pHwData, 0x03b4, 0x08210000 ); + Wb35Reg_ReadSync( pHwData, 0x03b4, &SoftwareSet ); + + // Read TXVGA + Wb35Reg_WriteSync( pHwData, 0x03b4, 0x08100000 ); + Wb35Reg_ReadSync( pHwData, 0x03b4, &TxVga ); + + // Get Scan interval setting from EEPROM offset 0x1c + Wb35Reg_WriteSync( pHwData, 0x03b4, 0x081d0000 ); + Wb35Reg_ReadSync( pHwData, 0x03b4, &Region_ScanInterval ); + + // Update Ethernet address + memcpy( pHwData->CurrentMacAddress, pHwData->PermanentMacAddress, ETH_LENGTH_OF_ADDRESS ); + + // Update software variable + pHwData->SoftwareSet = (u16)(SoftwareSet & 0xffff); + TxVga &= 0x000000ff; + pHwData->PowerIndexFromEEPROM = (u8)TxVga; + pHwData->VCO_trim = (u8)VCO_trim & 0xff; + if (pHwData->VCO_trim == 0xff) + pHwData->VCO_trim = 0x28; + + pWb35Reg->EEPROMRegion = (u8)(Region_ScanInterval>>8); // 20060720 + if( pWb35Reg->EEPROMRegion<1 || pWb35Reg->EEPROMRegion>6 ) + pWb35Reg->EEPROMRegion = REGION_AUTO; + + //For Get Tx VGA from EEPROM 20060315.5 move here + GetTxVgaFromEEPROM( pHwData ); + + // Set Scan Interval + pHwData->Scan_Interval = (u8)(Region_ScanInterval & 0xff) * 10; + if ((pHwData->Scan_Interval == 2550) || (pHwData->Scan_Interval < 10)) // Is default setting 0xff * 10 + pHwData->Scan_Interval = SCAN_MAX_CHNL_TIME; + + // Initial register + RFSynthesizer_initial(pHwData); + + BBProcessor_initial(pHwData); // Async write, must wait until complete + + Wb35Reg_phy_calibration(pHwData); + + Mxx_initial(pHwData); + Dxx_initial(pHwData); + + if (pHwData->SurpriseRemove) + return FALSE; + else + return TRUE; // Initial fail +} + +//=================================================================================== +// CardComputeCrc -- +// +// Description: +// Runs the AUTODIN II CRC algorithm on buffer Buffer of length, Length. +// +// Arguments: +// Buffer - the input buffer +// Length - the length of Buffer +// +// Return Value: +// The 32-bit CRC value. +// +// Note: +// This is adapted from the comments in the assembly language +// version in _GENREQ.ASM of the DWB NE1000/2000 driver. +//================================================================================== +u32 +CardComputeCrc(PUCHAR Buffer, u32 Length) +{ + u32 Crc, Carry; + u32 i, j; + u8 CurByte; + + Crc = 0xffffffff; + + for (i = 0; i < Length; i++) { + + CurByte = Buffer[i]; + + for (j = 0; j < 8; j++) { + + Carry = ((Crc & 0x80000000) ? 1 : 0) ^ (CurByte & 0x01); + Crc <<= 1; + CurByte >>= 1; + + if (Carry) { + Crc =(Crc ^ 0x04c11db6) | Carry; + } + } + } + + return Crc; +} + + +//================================================================== +// BitReverse -- +// Reverse the bits in the input argument, dwData, which is +// regarded as a string of bits with the length, DataLength. +// +// Arguments: +// dwData : +// DataLength : +// +// Return: +// The converted value. +//================================================================== +u32 BitReverse( u32 dwData, u32 DataLength) +{ + u32 HalfLength, i, j; + u32 BitA, BitB; + + if ( DataLength <= 0) return 0; // No conversion is done. + dwData = dwData & (0xffffffff >> (32 - DataLength)); + + HalfLength = DataLength / 2; + for ( i = 0, j = DataLength-1 ; i < HalfLength; i++, j--) + { + BitA = GetBit( dwData, i); + BitB = GetBit( dwData, j); + if (BitA && !BitB) { + dwData = ClearBit( dwData, i); + dwData = SetBit( dwData, j); + } else if (!BitA && BitB) { + dwData = SetBit( dwData, i); + dwData = ClearBit( dwData, j); + } else + { + // Do nothing since these two bits are of the save values. + } + } + + return dwData; +} + +void Wb35Reg_phy_calibration( phw_data_t pHwData ) +{ + u32 BB3c, BB54; + + if ((pHwData->phy_type == RF_WB_242) || + (pHwData->phy_type == RF_WB_242_1)) { + phy_calibration_winbond ( pHwData, 2412 ); // Sync operation + Wb35Reg_ReadSync( pHwData, 0x103c, &BB3c ); + Wb35Reg_ReadSync( pHwData, 0x1054, &BB54 ); + + pHwData->BB3c_cal = BB3c; + pHwData->BB54_cal = BB54; + + RFSynthesizer_initial(pHwData); + BBProcessor_initial(pHwData); // Async operation + + Wb35Reg_WriteSync( pHwData, 0x103c, BB3c ); + Wb35Reg_WriteSync( pHwData, 0x1054, BB54 ); + } +} + + diff --git a/drivers/staging/winbond/linux/wb35reg_f.h b/drivers/staging/winbond/linux/wb35reg_f.h new file mode 100644 index 000000000000..38e2906b51a7 --- /dev/null +++ b/drivers/staging/winbond/linux/wb35reg_f.h @@ -0,0 +1,56 @@ +//==================================== +// Interface function declare +//==================================== +unsigned char Wb35Reg_initial( phw_data_t pHwData ); +void Uxx_power_on_procedure( phw_data_t pHwData ); +void Uxx_power_off_procedure( phw_data_t pHwData ); +void Uxx_ReadEthernetAddress( phw_data_t pHwData ); +void Dxx_initial( phw_data_t pHwData ); +void Mxx_initial( phw_data_t pHwData ); +void RFSynthesizer_initial( phw_data_t pHwData ); +//void RFSynthesizer_SwitchingChannel( phw_data_t pHwData, s8 Channel ); +void RFSynthesizer_SwitchingChannel( phw_data_t pHwData, ChanInfo Channel ); +void BBProcessor_initial( phw_data_t pHwData ); +void BBProcessor_RateChanging( phw_data_t pHwData, u8 rate ); // 20060613.1 +//void RF_RateChanging( phw_data_t pHwData, u8 rate ); // 20060626.5.c Add +u8 RFSynthesizer_SetPowerIndex( phw_data_t pHwData, u8 PowerIndex ); +u8 RFSynthesizer_SetMaxim2828_24Power( phw_data_t, u8 index ); +u8 RFSynthesizer_SetMaxim2828_50Power( phw_data_t, u8 index ); +u8 RFSynthesizer_SetMaxim2827_24Power( phw_data_t, u8 index ); +u8 RFSynthesizer_SetMaxim2827_50Power( phw_data_t, u8 index ); +u8 RFSynthesizer_SetMaxim2825Power( phw_data_t, u8 index ); +u8 RFSynthesizer_SetAiroha2230Power( phw_data_t, u8 index ); +u8 RFSynthesizer_SetAiroha7230Power( phw_data_t, u8 index ); +u8 RFSynthesizer_SetWinbond242Power( phw_data_t, u8 index ); +void GetTxVgaFromEEPROM( phw_data_t pHwData ); +void EEPROMTxVgaAdjust( phw_data_t pHwData ); // 20060619.5 Add + +#define RFWriteControlData( _A, _V ) Wb35Reg_Write( _A, 0x0864, _V ) + +void Wb35Reg_destroy( phw_data_t pHwData ); + +unsigned char Wb35Reg_Read( phw_data_t pHwData, u16 RegisterNo, PULONG pRegisterValue ); +unsigned char Wb35Reg_ReadSync( phw_data_t pHwData, u16 RegisterNo, PULONG pRegisterValue ); +unsigned char Wb35Reg_Write( phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue ); +unsigned char Wb35Reg_WriteSync( phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue ); +unsigned char Wb35Reg_WriteWithCallbackValue( phw_data_t pHwData, + u16 RegisterNo, + u32 RegisterValue, + PCHAR pValue, + s8 Len); +unsigned char Wb35Reg_BurstWrite( phw_data_t pHwData, u16 RegisterNo, PULONG pRegisterData, u8 NumberOfData, u8 Flag ); + +void Wb35Reg_EP0VM( phw_data_t pHwData ); +void Wb35Reg_EP0VM_start( phw_data_t pHwData ); +void Wb35Reg_EP0VM_complete( PURB pUrb ); + +u32 BitReverse( u32 dwData, u32 DataLength); + +void CardGetMulticastBit( u8 Address[MAC_ADDR_LENGTH], u8 *Byte, u8 *Value ); +u32 CardComputeCrc( PUCHAR Buffer, u32 Length ); + +void Wb35Reg_phy_calibration( phw_data_t pHwData ); +void Wb35Reg_Update( phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue ); +unsigned char adjust_TXVGA_for_iq_mag( phw_data_t pHwData ); + + diff --git a/drivers/staging/winbond/linux/wb35reg_s.h b/drivers/staging/winbond/linux/wb35reg_s.h new file mode 100644 index 000000000000..a7595b1e7336 --- /dev/null +++ b/drivers/staging/winbond/linux/wb35reg_s.h @@ -0,0 +1,170 @@ +//======================================================================================= +/* + HAL setting function + + ======================================== + |Uxx| |Dxx| |Mxx| |BB| |RF| + ======================================== + | | + Wb35Reg_Read Wb35Reg_Write + + ---------------------------------------- + WbUsb_CallUSBDASync supplied By WbUsb module +*/ +//======================================================================================= + +#define GetBit( dwData, i) ( dwData & (0x00000001 << i)) +#define SetBit( dwData, i) ( dwData | (0x00000001 << i)) +#define ClearBit( dwData, i) ( dwData & ~(0x00000001 << i)) + +#define IGNORE_INCREMENT 0 +#define AUTO_INCREMENT 0 +#define NO_INCREMENT 1 +#define REG_DIRECTION(_x,_y) ((_y)->DIRECT ==0 ? usb_rcvctrlpipe(_x,0) : usb_sndctrlpipe(_x,0)) +#define REG_BUF_SIZE(_x) ((_x)->bRequest== 0x04 ? cpu_to_le16((_x)->wLength) : 4) + +// 20060613.2 Add the follow definition +#define BB48_DEFAULT_AL2230_11B 0x0033447c +#define BB4C_DEFAULT_AL2230_11B 0x0A00FEFF +#define BB48_DEFAULT_AL2230_11G 0x00332C1B +#define BB4C_DEFAULT_AL2230_11G 0x0A00FEFF + + +#define BB48_DEFAULT_WB242_11B 0x00292315 //backoff 2dB +#define BB4C_DEFAULT_WB242_11B 0x0800FEFF //backoff 2dB +//#define BB48_DEFAULT_WB242_11B 0x00201B11 //backoff 4dB +//#define BB4C_DEFAULT_WB242_11B 0x0600FF00 //backoff 4dB +#define BB48_DEFAULT_WB242_11G 0x00453B24 +#define BB4C_DEFAULT_WB242_11G 0x0E00FEFF + +//==================================== +// Default setting for Mxx +//==================================== +#define DEFAULT_CWMIN 31 //(M2C) CWmin. Its value is in the range 0-31. +#define DEFAULT_CWMAX 1023 //(M2C) CWmax. Its value is in the range 0-1023. +#define DEFAULT_AID 1 //(M34) AID. Its value is in the range 1-2007. + +#ifdef _USE_FALLBACK_RATE_ +#define DEFAULT_RATE_RETRY_LIMIT 2 //(M38) as named +#else +#define DEFAULT_RATE_RETRY_LIMIT 7 //(M38) as named +#endif + +#define DEFAULT_LONG_RETRY_LIMIT 7 //(M38) LongRetryLimit. Its value is in the range 0-15. +#define DEFAULT_SHORT_RETRY_LIMIT 7 //(M38) ShortRetryLimit. Its value is in the range 0-15. +#define DEFAULT_PIFST 25 //(M3C) PIFS Time. Its value is in the range 0-65535. +#define DEFAULT_EIFST 354 //(M3C) EIFS Time. Its value is in the range 0-1048575. +#define DEFAULT_DIFST 45 //(M3C) DIFS Time. Its value is in the range 0-65535. +#define DEFAULT_SIFST 5 //(M3C) SIFS Time. Its value is in the range 0-65535. +#define DEFAULT_OSIFST 10 //(M3C) Original SIFS Time. Its value is in the range 0-15. +#define DEFAULT_ATIMWD 0 //(M40) ATIM Window. Its value is in the range 0-65535. +#define DEFAULT_SLOT_TIME 20 //(M40) ($) SlotTime. Its value is in the range 0-255. +#define DEFAULT_MAX_TX_MSDU_LIFE_TIME 512 //(M44) MaxTxMSDULifeTime. Its value is in the range 0-4294967295. +#define DEFAULT_BEACON_INTERVAL 500 //(M48) Beacon Interval. Its value is in the range 0-65535. +#define DEFAULT_PROBE_DELAY_TIME 200 //(M48) Probe Delay Time. Its value is in the range 0-65535. +#define DEFAULT_PROTOCOL_VERSION 0 //(M4C) +#define DEFAULT_MAC_POWER_STATE 2 //(M4C) 2: MAC at power active +#define DEFAULT_DTIM_ALERT_TIME 0 + + +typedef struct _REG_QUEUE +{ + struct urb *pUrb; + void* pUsbReq; + void* Next; + union + { + u32 VALUE; + PULONG pBuffer; + }; + u8 RESERVED[4];// space reserved for communication + + u16 INDEX; // For storing the register index + u8 RESERVED_VALID; //Indicate whether the RESERVED space is valid at this command. + u8 DIRECT; // 0:In 1:Out + +} REG_QUEUE, *PREG_QUEUE; + +//==================================== +// Internal variable for module +//==================================== +#define MAX_SQ3_FILTER_SIZE 5 +typedef struct _WB35REG +{ + //============================ + // Register Bank backup + //============================ + u32 U1B0; //bit16 record the h/w radio on/off status + u32 U1BC_LEDConfigure; + u32 D00_DmaControl; + u32 M00_MacControl; + union { + struct { + u32 M04_MulticastAddress1; + u32 M08_MulticastAddress2; + }; + u8 Multicast[8]; // contents of card multicast registers + }; + + u32 M24_MacControl; + u32 M28_MacControl; + u32 M2C_MacControl; + u32 M38_MacControl; + u32 M3C_MacControl; // 20060214 backup only + u32 M40_MacControl; + u32 M44_MacControl; // 20060214 backup only + u32 M48_MacControl; // 20060214 backup only + u32 M4C_MacStatus; + u32 M60_MacControl; // 20060214 backup only + u32 M68_MacControl; // 20060214 backup only + u32 M70_MacControl; // 20060214 backup only + u32 M74_MacControl; // 20060214 backup only + u32 M78_ERPInformation;//930206.2.b + u32 M7C_MacControl; // 20060214 backup only + u32 M80_MacControl; // 20060214 backup only + u32 M84_MacControl; // 20060214 backup only + u32 M88_MacControl; // 20060214 backup only + u32 M98_MacControl; // 20060214 backup only + + //[20040722 WK] + //Baseband register + u32 BB0C; // Used for LNA calculation + u32 BB2C; // + u32 BB30; //11b acquisition control register + u32 BB3C; + u32 BB48; // 20051221.1.a 20060613.1 Fix OBW issue of 11b/11g rate + u32 BB4C; // 20060613.1 Fix OBW issue of 11b/11g rate + u32 BB50; //mode control register + u32 BB54; + u32 BB58; //IQ_ALPHA + u32 BB5C; // For test + u32 BB60; // for WTO read value + + //------------------- + // VM + //------------------- + OS_SPIN_LOCK EP0VM_spin_lock; // 4B + u32 EP0VM_status;//$$ + PREG_QUEUE pRegFirst; + PREG_QUEUE pRegLast; + OS_ATOMIC RegFireCount; + + // Hardware status + u8 EP0vm_state; + u8 mac_power_save; + u8 EEPROMPhyType; // 0 ~ 15 for Maxim (0 ĄV MAX2825, 1 ĄV MAX2827, 2 ĄV MAX2828, 3 ĄV MAX2829), + // 16 ~ 31 for Airoha (16 ĄV AL2230, 11 - AL7230) + // 32 ~ Reserved + // 33 ~ 47 For WB242 ( 33 - WB242, 34 - WB242 with new Txvga 0.5 db step) + // 48 ~ 255 ARE RESERVED. + u8 EEPROMRegion; //Region setting in EEPROM + + u32 SyncIoPause; // If user use the Sync Io to access Hw, then pause the async access + + u8 LNAValue[4]; //Table for speed up running + u32 SQ3_filter[MAX_SQ3_FILTER_SIZE]; + u32 SQ3_index; + +} WB35REG, *PWB35REG; + + diff --git a/drivers/staging/winbond/linux/wb35rx.c b/drivers/staging/winbond/linux/wb35rx.c new file mode 100644 index 000000000000..26157eb3d5a2 --- /dev/null +++ b/drivers/staging/winbond/linux/wb35rx.c @@ -0,0 +1,337 @@ +//============================================================================ +// Copyright (c) 1996-2002 Winbond Electronic Corporation +// +// Module Name: +// Wb35Rx.c +// +// Abstract: +// Processing the Rx message from down layer +// +//============================================================================ +#include "sysdef.h" + + +void Wb35Rx_start(phw_data_t pHwData) +{ + PWB35RX pWb35Rx = &pHwData->Wb35Rx; + + // Allow only one thread to run into the Wb35Rx() function + if (OS_ATOMIC_INC(pHwData->Adapter, &pWb35Rx->RxFireCounter) == 1) { + pWb35Rx->EP3vm_state = VM_RUNNING; + Wb35Rx(pHwData); + } else + OS_ATOMIC_DEC(pHwData->Adapter, &pWb35Rx->RxFireCounter); +} + +// This function cannot reentrain +void Wb35Rx( phw_data_t pHwData ) +{ + PWB35RX pWb35Rx = &pHwData->Wb35Rx; + PUCHAR pRxBufferAddress; + PURB pUrb = (PURB)pWb35Rx->RxUrb; + int retv; + u32 RxBufferId; + + // + // Issuing URB + // + do { + if (pHwData->SurpriseRemove || pHwData->HwStop) + break; + + if (pWb35Rx->rx_halt) + break; + + // Get RxBuffer's ID + RxBufferId = pWb35Rx->RxBufferId; + if (!pWb35Rx->RxOwner[RxBufferId]) { + // It's impossible to run here. + #ifdef _PE_RX_DUMP_ + WBDEBUG(("Rx driver fifo unavailable\n")); + #endif + break; + } + + // Update buffer point, then start to bulkin the data from USB + pWb35Rx->RxBufferId++; + pWb35Rx->RxBufferId %= MAX_USB_RX_BUFFER_NUMBER; + + pWb35Rx->CurrentRxBufferId = RxBufferId; + + if (1 != OS_MEMORY_ALLOC((void* *)&pWb35Rx->pDRx, MAX_USB_RX_BUFFER)) { + printk("w35und: Rx memory alloc failed\n"); + break; + } + pRxBufferAddress = pWb35Rx->pDRx; + + usb_fill_bulk_urb(pUrb, pHwData->WbUsb.udev, + usb_rcvbulkpipe(pHwData->WbUsb.udev, 3), + pRxBufferAddress, MAX_USB_RX_BUFFER, + Wb35Rx_Complete, pHwData); + + pWb35Rx->EP3vm_state = VM_RUNNING; + + retv = wb_usb_submit_urb(pUrb); + + if (retv != 0) { + printk("Rx URB sending error\n"); + break; + } + return; + } while(FALSE); + + // VM stop + pWb35Rx->EP3vm_state = VM_STOP; + OS_ATOMIC_DEC( pHwData->Adapter, &pWb35Rx->RxFireCounter ); +} + +void Wb35Rx_Complete(PURB pUrb) +{ + phw_data_t pHwData = pUrb->context; + PWB35RX pWb35Rx = &pHwData->Wb35Rx; + PUCHAR pRxBufferAddress; + u32 SizeCheck; + u16 BulkLength; + u32 RxBufferId; + R00_DESCRIPTOR R00; + + // Variable setting + pWb35Rx->EP3vm_state = VM_COMPLETED; + pWb35Rx->EP3VM_status = pUrb->status;//Store the last result of Irp + + do { + RxBufferId = pWb35Rx->CurrentRxBufferId; + + pRxBufferAddress = pWb35Rx->pDRx; + BulkLength = (u16)pUrb->actual_length; + + // The IRP is completed + pWb35Rx->EP3vm_state = VM_COMPLETED; + + if (pHwData->SurpriseRemove || pHwData->HwStop) // Must be here, or RxBufferId is invalid + break; + + if (pWb35Rx->rx_halt) + break; + + // Start to process the data only in successful condition + pWb35Rx->RxOwner[ RxBufferId ] = 0; // Set the owner to driver + R00.value = le32_to_cpu(*(PULONG)pRxBufferAddress); + + // The URB is completed, check the result + if (pWb35Rx->EP3VM_status != 0) { + #ifdef _PE_USB_STATE_DUMP_ + WBDEBUG(("EP3 IoCompleteRoutine return error\n")); + DebugUsbdStatusInformation( pWb35Rx->EP3VM_status ); + #endif + pWb35Rx->EP3vm_state = VM_STOP; + break; + } + + // 20060220 For recovering. check if operating in single USB mode + if (!HAL_USB_MODE_BURST(pHwData)) { + SizeCheck = R00.R00_receive_byte_count; //20060926 anson's endian + if ((SizeCheck & 0x03) > 0) + SizeCheck -= 4; + SizeCheck = (SizeCheck + 3) & ~0x03; + SizeCheck += 12; // 8 + 4 badbeef + if ((BulkLength > 1600) || + (SizeCheck > 1600) || + (BulkLength != SizeCheck) || + (BulkLength == 0)) { // Add for fail Urb + pWb35Rx->EP3vm_state = VM_STOP; + pWb35Rx->Ep3ErrorCount2++; + } + } + + // Indicating the receiving data + pWb35Rx->ByteReceived += BulkLength; + pWb35Rx->RxBufferSize[ RxBufferId ] = BulkLength; + + if (!pWb35Rx->RxOwner[ RxBufferId ]) + Wb35Rx_indicate(pHwData); + + kfree(pWb35Rx->pDRx); + // Do the next receive + Wb35Rx(pHwData); + return; + + } while(FALSE); + + pWb35Rx->RxOwner[ RxBufferId ] = 1; // Set the owner to hardware + OS_ATOMIC_DEC( pHwData->Adapter, &pWb35Rx->RxFireCounter ); + pWb35Rx->EP3vm_state = VM_STOP; +} + +//===================================================================================== +unsigned char Wb35Rx_initial(phw_data_t pHwData) +{ + PWB35RX pWb35Rx = &pHwData->Wb35Rx; + + // Initial the Buffer Queue + Wb35Rx_reset_descriptor( pHwData ); + + pWb35Rx->RxUrb = wb_usb_alloc_urb(0); + return (!!pWb35Rx->RxUrb); +} + +void Wb35Rx_stop(phw_data_t pHwData) +{ + PWB35RX pWb35Rx = &pHwData->Wb35Rx; + + // Canceling the Irp if already sends it out. + if (pWb35Rx->EP3vm_state == VM_RUNNING) { + usb_unlink_urb( pWb35Rx->RxUrb ); // Only use unlink, let Wb35Rx_destroy to free them + #ifdef _PE_RX_DUMP_ + WBDEBUG(("EP3 Rx stop\n")); + #endif + } +} + +// Needs process context +void Wb35Rx_destroy(phw_data_t pHwData) +{ + PWB35RX pWb35Rx = &pHwData->Wb35Rx; + + do { + OS_SLEEP(10000); // Delay for waiting function enter 940623.1.a + } while (pWb35Rx->EP3vm_state != VM_STOP); + OS_SLEEP(10000); // Delay for waiting function exit 940623.1.b + + if (pWb35Rx->RxUrb) + usb_free_urb( pWb35Rx->RxUrb ); + #ifdef _PE_RX_DUMP_ + WBDEBUG(("Wb35Rx_destroy OK\n")); + #endif +} + +void Wb35Rx_reset_descriptor( phw_data_t pHwData ) +{ + PWB35RX pWb35Rx = &pHwData->Wb35Rx; + u32 i; + + pWb35Rx->ByteReceived = 0; + pWb35Rx->RxProcessIndex = 0; + pWb35Rx->RxBufferId = 0; + pWb35Rx->EP3vm_state = VM_STOP; + pWb35Rx->rx_halt = 0; + + // Initial the Queue. The last buffer is reserved for used if the Rx resource is unavailable. + for( i=0; i<MAX_USB_RX_BUFFER_NUMBER; i++ ) + pWb35Rx->RxOwner[i] = 1; +} + +void Wb35Rx_adjust(PDESCRIPTOR pRxDes) +{ + PULONG pRxBufferAddress; + u32 DecryptionMethod; + u32 i; + u16 BufferSize; + + DecryptionMethod = pRxDes->R01.R01_decryption_method; + pRxBufferAddress = pRxDes->buffer_address[0]; + BufferSize = pRxDes->buffer_size[0]; + + // Adjust the last part of data. Only data left + BufferSize -= 4; // For CRC-32 + if (DecryptionMethod) + BufferSize -= 4; + if (DecryptionMethod == 3) // For CCMP + BufferSize -= 4; + + // Adjust the IV field which after 802.11 header and ICV field. + if (DecryptionMethod == 1) // For WEP + { + for( i=6; i>0; i-- ) + pRxBufferAddress[i] = pRxBufferAddress[i-1]; + pRxDes->buffer_address[0] = pRxBufferAddress + 1; + BufferSize -= 4; // 4 byte for IV + } + else if( DecryptionMethod ) // For TKIP and CCMP + { + for (i=7; i>1; i--) + pRxBufferAddress[i] = pRxBufferAddress[i-2]; + pRxDes->buffer_address[0] = pRxBufferAddress + 2;//Update the descriptor, shift 8 byte + BufferSize -= 8; // 8 byte for IV + ICV + } + pRxDes->buffer_size[0] = BufferSize; +} + +extern void packet_came(char *pRxBufferAddress, int PacketSize); + + +u16 Wb35Rx_indicate(phw_data_t pHwData) +{ + DESCRIPTOR RxDes; + PWB35RX pWb35Rx = &pHwData->Wb35Rx; + PUCHAR pRxBufferAddress; + u16 PacketSize; + u16 stmp, BufferSize, stmp2 = 0; + u32 RxBufferId; + + // Only one thread be allowed to run into the following + do { + RxBufferId = pWb35Rx->RxProcessIndex; + if (pWb35Rx->RxOwner[ RxBufferId ]) //Owner by VM + break; + + pWb35Rx->RxProcessIndex++; + pWb35Rx->RxProcessIndex %= MAX_USB_RX_BUFFER_NUMBER; + + pRxBufferAddress = pWb35Rx->pDRx; + BufferSize = pWb35Rx->RxBufferSize[ RxBufferId ]; + + // Parse the bulkin buffer + while (BufferSize >= 4) { + if ((cpu_to_le32(*(PULONG)pRxBufferAddress) & 0x0fffffff) == RX_END_TAG) //Is ending? 921002.9.a + break; + + // Get the R00 R01 first + RxDes.R00.value = le32_to_cpu(*(PULONG)pRxBufferAddress); + PacketSize = (u16)RxDes.R00.R00_receive_byte_count; + RxDes.R01.value = le32_to_cpu(*((PULONG)(pRxBufferAddress+4))); + // For new DMA 4k + if ((PacketSize & 0x03) > 0) + PacketSize -= 4; + + // Basic check for Rx length. Is length valid? + if (PacketSize > MAX_PACKET_SIZE) { + #ifdef _PE_RX_DUMP_ + WBDEBUG(("Serious ERROR : Rx data size too long, size =%d\n", PacketSize)); + #endif + + pWb35Rx->EP3vm_state = VM_STOP; + pWb35Rx->Ep3ErrorCount2++; + break; + } + + // Start to process Rx buffer +// RxDes.Descriptor_ID = RxBufferId; // Due to synchronous indicate, the field doesn't necessary to use. + BufferSize -= 8; //subtract 8 byte for 35's USB header length + pRxBufferAddress += 8; + + RxDes.buffer_address[0] = pRxBufferAddress; + RxDes.buffer_size[0] = PacketSize; + RxDes.buffer_number = 1; + RxDes.buffer_start_index = 0; + RxDes.buffer_total_size = RxDes.buffer_size[0]; + Wb35Rx_adjust(&RxDes); + + packet_came(pRxBufferAddress, PacketSize); + + // Move RxBuffer point to the next + stmp = PacketSize + 3; + stmp &= ~0x03; // 4n alignment + pRxBufferAddress += stmp; + BufferSize -= stmp; + stmp2 += stmp; + } + + // Reclaim resource + pWb35Rx->RxOwner[ RxBufferId ] = 1; + } while(TRUE); + + return stmp2; +} + + diff --git a/drivers/staging/winbond/linux/wb35rx_f.h b/drivers/staging/winbond/linux/wb35rx_f.h new file mode 100644 index 000000000000..daa3e73042bd --- /dev/null +++ b/drivers/staging/winbond/linux/wb35rx_f.h @@ -0,0 +1,17 @@ +//==================================== +// Interface function declare +//==================================== +void Wb35Rx_reset_descriptor( phw_data_t pHwData ); +unsigned char Wb35Rx_initial( phw_data_t pHwData ); +void Wb35Rx_destroy( phw_data_t pHwData ); +void Wb35Rx_stop( phw_data_t pHwData ); +u16 Wb35Rx_indicate( phw_data_t pHwData ); +void Wb35Rx_adjust( PDESCRIPTOR pRxDes ); +void Wb35Rx_start( phw_data_t pHwData ); + +void Wb35Rx( phw_data_t pHwData ); +void Wb35Rx_Complete( PURB pUrb ); + + + + diff --git a/drivers/staging/winbond/linux/wb35rx_s.h b/drivers/staging/winbond/linux/wb35rx_s.h new file mode 100644 index 000000000000..53b831fdeb78 --- /dev/null +++ b/drivers/staging/winbond/linux/wb35rx_s.h @@ -0,0 +1,48 @@ +//============================================================================ +// wb35rx.h -- +//============================================================================ + +// Definition for this module used +#define MAX_USB_RX_BUFFER 4096 // This parameter must be 4096 931130.4.f + +#define MAX_USB_RX_BUFFER_NUMBER ETHERNET_RX_DESCRIPTORS // Maximum 254, 255 is RESERVED ID +#define RX_INTERFACE 0 // Interface 1 +#define RX_PIPE 2 // Pipe 3 +#define MAX_PACKET_SIZE 1600 //1568 // 8 + 1532 + 4 + 24(IV EIV MIC ICV CRC) for check DMA data 931130.4.g +#define RX_END_TAG 0x0badbeef + + +//==================================== +// Internal variable for module +//==================================== +typedef struct _WB35RX +{ + u32 ByteReceived;// For calculating throughput of BulkIn + OS_ATOMIC RxFireCounter;// Does Wb35Rx module fire? + + u8 RxBuffer[ MAX_USB_RX_BUFFER_NUMBER ][ ((MAX_USB_RX_BUFFER+3) & ~0x03 ) ]; + u16 RxBufferSize[ ((MAX_USB_RX_BUFFER_NUMBER+1) & ~0x01) ]; + u8 RxOwner[ ((MAX_USB_RX_BUFFER_NUMBER+3) & ~0x03 ) ];//Ownership of buffer 0: SW 1:HW + + u32 RxProcessIndex;//The next index to process + u32 RxBufferId; + u32 EP3vm_state; + + u32 rx_halt; // For VM stopping + + u16 MoreDataSize; + u16 PacketSize; + + u32 CurrentRxBufferId; // For complete routine usage + u32 Rx3UrbCancel; + + u32 LastR1; // For RSSI reporting + struct urb * RxUrb; + u32 Ep3ErrorCount2; // 20060625.1 Usbd for Rx DMA error count + + int EP3VM_status; + PUCHAR pDRx; + +} WB35RX, *PWB35RX; + + diff --git a/drivers/staging/winbond/linux/wb35tx.c b/drivers/staging/winbond/linux/wb35tx.c new file mode 100644 index 000000000000..cf19c3bc524a --- /dev/null +++ b/drivers/staging/winbond/linux/wb35tx.c @@ -0,0 +1,313 @@ +//============================================================================ +// Copyright (c) 1996-2002 Winbond Electronic Corporation +// +// Module Name: +// Wb35Tx.c +// +// Abstract: +// Processing the Tx message and put into down layer +// +//============================================================================ +#include "sysdef.h" + + +unsigned char +Wb35Tx_get_tx_buffer(phw_data_t pHwData, PUCHAR *pBuffer ) +{ + PWB35TX pWb35Tx = &pHwData->Wb35Tx; + + *pBuffer = pWb35Tx->TxBuffer[0]; + return TRUE; +} + +void Wb35Tx_start(phw_data_t pHwData) +{ + PWB35TX pWb35Tx = &pHwData->Wb35Tx; + + // Allow only one thread to run into function + if (OS_ATOMIC_INC(pHwData->Adapter, &pWb35Tx->TxFireCounter) == 1) { + pWb35Tx->EP4vm_state = VM_RUNNING; + Wb35Tx(pHwData); + } else + OS_ATOMIC_DEC( pHwData->Adapter, &pWb35Tx->TxFireCounter ); +} + + +void Wb35Tx(phw_data_t pHwData) +{ + PWB35TX pWb35Tx = &pHwData->Wb35Tx; + PADAPTER Adapter = pHwData->Adapter; + PUCHAR pTxBufferAddress; + PMDS pMds = &Adapter->Mds; + struct urb * pUrb = (struct urb *)pWb35Tx->Tx4Urb; + int retv; + u32 SendIndex; + + + if (pHwData->SurpriseRemove || pHwData->HwStop) + goto cleanup; + + if (pWb35Tx->tx_halt) + goto cleanup; + + // Ownership checking + SendIndex = pWb35Tx->TxSendIndex; + if (!pMds->TxOwner[SendIndex]) //No more data need to be sent, return immediately + goto cleanup; + + pTxBufferAddress = pWb35Tx->TxBuffer[SendIndex]; + // + // Issuing URB + // + usb_fill_bulk_urb(pUrb, pHwData->WbUsb.udev, + usb_sndbulkpipe(pHwData->WbUsb.udev, 4), + pTxBufferAddress, pMds->TxBufferSize[ SendIndex ], + Wb35Tx_complete, pHwData); + + pWb35Tx->EP4vm_state = VM_RUNNING; + retv = wb_usb_submit_urb( pUrb ); + if (retv<0) { + printk("EP4 Tx Irp sending error\n"); + goto cleanup; + } + + // Check if driver needs issue Irp for EP2 + pWb35Tx->TxFillCount += pMds->TxCountInBuffer[SendIndex]; + if (pWb35Tx->TxFillCount > 12) + Wb35Tx_EP2VM_start( pHwData ); + + pWb35Tx->ByteTransfer += pMds->TxBufferSize[SendIndex]; + return; + + cleanup: + pWb35Tx->EP4vm_state = VM_STOP; + OS_ATOMIC_DEC( pHwData->Adapter, &pWb35Tx->TxFireCounter ); +} + + +void Wb35Tx_complete(struct urb * pUrb) +{ + phw_data_t pHwData = pUrb->context; + PADAPTER Adapter = (PADAPTER)pHwData->Adapter; + PWB35TX pWb35Tx = &pHwData->Wb35Tx; + PMDS pMds = &Adapter->Mds; + + printk("wb35: tx complete\n"); + // Variable setting + pWb35Tx->EP4vm_state = VM_COMPLETED; + pWb35Tx->EP4VM_status = pUrb->status; //Store the last result of Irp + pMds->TxOwner[ pWb35Tx->TxSendIndex ] = 0;// Set the owner. Free the owner bit always. + pWb35Tx->TxSendIndex++; + pWb35Tx->TxSendIndex %= MAX_USB_TX_BUFFER_NUMBER; + + do { + if (pHwData->SurpriseRemove || pHwData->HwStop) // Let WbWlanHalt to handle surprise remove + break; + + if (pWb35Tx->tx_halt) + break; + + // The URB is completed, check the result + if (pWb35Tx->EP4VM_status != 0) { + printk("URB submission failed\n"); + pWb35Tx->EP4vm_state = VM_STOP; + break; // Exit while(FALSE); + } + + Mds_Tx(Adapter); + Wb35Tx(pHwData); + return; + } while(FALSE); + + OS_ATOMIC_DEC( pHwData->Adapter, &pWb35Tx->TxFireCounter ); + pWb35Tx->EP4vm_state = VM_STOP; +} + +void Wb35Tx_reset_descriptor( phw_data_t pHwData ) +{ + PWB35TX pWb35Tx = &pHwData->Wb35Tx; + + pWb35Tx->TxSendIndex = 0; + pWb35Tx->tx_halt = 0; +} + +unsigned char Wb35Tx_initial(phw_data_t pHwData) +{ + PWB35TX pWb35Tx = &pHwData->Wb35Tx; + + pWb35Tx->Tx4Urb = wb_usb_alloc_urb(0); + if (!pWb35Tx->Tx4Urb) + return FALSE; + + pWb35Tx->Tx2Urb = wb_usb_alloc_urb(0); + if (!pWb35Tx->Tx2Urb) + { + usb_free_urb( pWb35Tx->Tx4Urb ); + return FALSE; + } + + return TRUE; +} + +//====================================================== +void Wb35Tx_stop(phw_data_t pHwData) +{ + PWB35TX pWb35Tx = &pHwData->Wb35Tx; + + // Trying to canceling the Trp of EP2 + if (pWb35Tx->EP2vm_state == VM_RUNNING) + usb_unlink_urb( pWb35Tx->Tx2Urb ); // Only use unlink, let Wb35Tx_destrot to free them + #ifdef _PE_TX_DUMP_ + WBDEBUG(("EP2 Tx stop\n")); + #endif + + // Trying to canceling the Irp of EP4 + if (pWb35Tx->EP4vm_state == VM_RUNNING) + usb_unlink_urb( pWb35Tx->Tx4Urb ); // Only use unlink, let Wb35Tx_destrot to free them + #ifdef _PE_TX_DUMP_ + WBDEBUG(("EP4 Tx stop\n")); + #endif +} + +//====================================================== +void Wb35Tx_destroy(phw_data_t pHwData) +{ + PWB35TX pWb35Tx = &pHwData->Wb35Tx; + + // Wait for VM stop + do { + OS_SLEEP(10000); // Delay for waiting function enter 940623.1.a + } while( (pWb35Tx->EP2vm_state != VM_STOP) && (pWb35Tx->EP4vm_state != VM_STOP) ); + OS_SLEEP(10000); // Delay for waiting function enter 940623.1.b + + if (pWb35Tx->Tx4Urb) + usb_free_urb( pWb35Tx->Tx4Urb ); + + if (pWb35Tx->Tx2Urb) + usb_free_urb( pWb35Tx->Tx2Urb ); + + #ifdef _PE_TX_DUMP_ + WBDEBUG(("Wb35Tx_destroy OK\n")); + #endif +} + +void Wb35Tx_CurrentTime(phw_data_t pHwData, u32 TimeCount) +{ + PWB35TX pWb35Tx = &pHwData->Wb35Tx; + unsigned char Trigger = FALSE; + + if (pWb35Tx->TxTimer > TimeCount) + Trigger = TRUE; + else if (TimeCount > (pWb35Tx->TxTimer+500)) + Trigger = TRUE; + + if (Trigger) { + pWb35Tx->TxTimer = TimeCount; + Wb35Tx_EP2VM_start( pHwData ); + } +} + +void Wb35Tx_EP2VM_start(phw_data_t pHwData) +{ + PWB35TX pWb35Tx = &pHwData->Wb35Tx; + + // Allow only one thread to run into function + if (OS_ATOMIC_INC( pHwData->Adapter, &pWb35Tx->TxResultCount ) == 1) { + pWb35Tx->EP2vm_state = VM_RUNNING; + Wb35Tx_EP2VM( pHwData ); + } + else + OS_ATOMIC_DEC( pHwData->Adapter, &pWb35Tx->TxResultCount ); +} + + +void Wb35Tx_EP2VM(phw_data_t pHwData) +{ + PWB35TX pWb35Tx = &pHwData->Wb35Tx; + struct urb * pUrb = (struct urb *)pWb35Tx->Tx2Urb; + PULONG pltmp = (PULONG)pWb35Tx->EP2_buf; + int retv; + + do { + if (pHwData->SurpriseRemove || pHwData->HwStop) + break; + + if (pWb35Tx->tx_halt) + break; + + // + // Issuing URB + // + usb_fill_int_urb( pUrb, pHwData->WbUsb.udev, usb_rcvintpipe(pHwData->WbUsb.udev,2), + pltmp, MAX_INTERRUPT_LENGTH, Wb35Tx_EP2VM_complete, pHwData, 32); + + pWb35Tx->EP2vm_state = VM_RUNNING; + retv = wb_usb_submit_urb( pUrb ); + + if(retv < 0) { + #ifdef _PE_TX_DUMP_ + WBDEBUG(("EP2 Tx Irp sending error\n")); + #endif + break; + } + + return; + + } while(FALSE); + + pWb35Tx->EP2vm_state = VM_STOP; + OS_ATOMIC_DEC( pHwData->Adapter, &pWb35Tx->TxResultCount ); +} + + +void Wb35Tx_EP2VM_complete(struct urb * pUrb) +{ + phw_data_t pHwData = pUrb->context; + T02_DESCRIPTOR T02, TSTATUS; + PADAPTER Adapter = (PADAPTER)pHwData->Adapter; + PWB35TX pWb35Tx = &pHwData->Wb35Tx; + PULONG pltmp = (PULONG)pWb35Tx->EP2_buf; + u32 i; + u16 InterruptInLength; + + + // Variable setting + pWb35Tx->EP2vm_state = VM_COMPLETED; + pWb35Tx->EP2VM_status = pUrb->status; + + do { + // For Linux 2.4. Interrupt will always trigger + if( pHwData->SurpriseRemove || pHwData->HwStop ) // Let WbWlanHalt to handle surprise remove + break; + + if( pWb35Tx->tx_halt ) + break; + + //The Urb is completed, check the result + if (pWb35Tx->EP2VM_status != 0) { + WBDEBUG(("EP2 IoCompleteRoutine return error\n")); + pWb35Tx->EP2vm_state= VM_STOP; + break; // Exit while(FALSE); + } + + // Update the Tx result + InterruptInLength = pUrb->actual_length; + // Modify for minimum memory access and DWORD alignment. + T02.value = cpu_to_le32(pltmp[0]) >> 8; // [31:8] -> [24:0] + InterruptInLength -= 1;// 20051221.1.c Modify the follow for more stable + InterruptInLength >>= 2; // InterruptInLength/4 + for (i=1; i<=InterruptInLength; i++) { + T02.value |= ((cpu_to_le32(pltmp[i]) & 0xff) << 24); + + TSTATUS.value = T02.value; //20061009 anson's endian + Mds_SendComplete( Adapter, &TSTATUS ); + T02.value = cpu_to_le32(pltmp[i]) >> 8; + } + + return; + } while(FALSE); + + OS_ATOMIC_DEC( pHwData->Adapter, &pWb35Tx->TxResultCount ); + pWb35Tx->EP2vm_state = VM_STOP; +} + diff --git a/drivers/staging/winbond/linux/wb35tx_f.h b/drivers/staging/winbond/linux/wb35tx_f.h new file mode 100644 index 000000000000..7705a8454dcb --- /dev/null +++ b/drivers/staging/winbond/linux/wb35tx_f.h @@ -0,0 +1,20 @@ +//==================================== +// Interface function declare +//==================================== +unsigned char Wb35Tx_initial( phw_data_t pHwData ); +void Wb35Tx_destroy( phw_data_t pHwData ); +unsigned char Wb35Tx_get_tx_buffer( phw_data_t pHwData, PUCHAR *pBuffer ); + +void Wb35Tx_EP2VM( phw_data_t pHwData ); +void Wb35Tx_EP2VM_start( phw_data_t pHwData ); +void Wb35Tx_EP2VM_complete( PURB purb ); + +void Wb35Tx_start( phw_data_t pHwData ); +void Wb35Tx_stop( phw_data_t pHwData ); +void Wb35Tx( phw_data_t pHwData ); +void Wb35Tx_complete( PURB purb ); +void Wb35Tx_reset_descriptor( phw_data_t pHwData ); + +void Wb35Tx_CurrentTime( phw_data_t pHwData, u32 TimeCount ); + + diff --git a/drivers/staging/winbond/linux/wb35tx_s.h b/drivers/staging/winbond/linux/wb35tx_s.h new file mode 100644 index 000000000000..ac4325736760 --- /dev/null +++ b/drivers/staging/winbond/linux/wb35tx_s.h @@ -0,0 +1,47 @@ +//==================================== +// IS89C35 Tx related definition +//==================================== +#define TX_INTERFACE 0 // Interface 1 +#define TX_PIPE 3 // endpoint 4 +#define TX_INTERRUPT 1 // endpoint 2 +#define MAX_INTERRUPT_LENGTH 64 // It must be 64 for EP2 hardware + + + +//==================================== +// Internal variable for module +//==================================== + + +typedef struct _WB35TX +{ + // For Tx buffer + u8 TxBuffer[ MAX_USB_TX_BUFFER_NUMBER ][ MAX_USB_TX_BUFFER ]; + + // For Interrupt pipe + u8 EP2_buf[MAX_INTERRUPT_LENGTH]; + + OS_ATOMIC TxResultCount;// For thread control of EP2 931130.4.m + OS_ATOMIC TxFireCounter;// For thread control of EP4 931130.4.n + u32 ByteTransfer; + + u32 TxSendIndex;// The next index of Mds array to be sent + u32 EP2vm_state; // for EP2vm state + u32 EP4vm_state; // for EP4vm state + u32 tx_halt; // Stopping VM + + struct urb * Tx4Urb; + struct urb * Tx2Urb; + + int EP2VM_status; + int EP4VM_status; + + u32 TxFillCount; // 20060928 + u32 TxTimer; // 20060928 Add if sending packet not great than 13 + +} WB35TX, *PWB35TX; + + + + + diff --git a/drivers/staging/winbond/linux/wbusb.c b/drivers/staging/winbond/linux/wbusb.c new file mode 100644 index 000000000000..cbad5fb05959 --- /dev/null +++ b/drivers/staging/winbond/linux/wbusb.c @@ -0,0 +1,404 @@ +/* + * Copyright 2008 Pavel Machek <pavel@suse.cz> + * + * Distribute under GPLv2. + */ +#include "sysdef.h" +#include <net/mac80211.h> + + +MODULE_AUTHOR( DRIVER_AUTHOR ); +MODULE_DESCRIPTION( DRIVER_DESC ); +MODULE_LICENSE("GPL"); +MODULE_VERSION("0.1"); + + +//============================================================ +// vendor ID and product ID can into here for others +//============================================================ +static struct usb_device_id Id_Table[] = +{ + {USB_DEVICE( 0x0416, 0x0035 )}, + {USB_DEVICE( 0x18E8, 0x6201 )}, + {USB_DEVICE( 0x18E8, 0x6206 )}, + {USB_DEVICE( 0x18E8, 0x6217 )}, + {USB_DEVICE( 0x18E8, 0x6230 )}, + {USB_DEVICE( 0x18E8, 0x6233 )}, + {USB_DEVICE( 0x1131, 0x2035 )}, + { } +}; + +MODULE_DEVICE_TABLE(usb, Id_Table); + +static struct usb_driver wb35_driver = { + .name = "w35und", + .probe = wb35_probe, + .disconnect = wb35_disconnect, + .id_table = Id_Table, +}; + +static const struct ieee80211_rate wbsoft_rates[] = { + { .bitrate = 10, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, +}; + +static const struct ieee80211_channel wbsoft_channels[] = { + { .center_freq = 2412}, +}; + +int wbsoft_enabled; +struct ieee80211_hw *my_dev; +PADAPTER my_adapter; + +static int wbsoft_add_interface(struct ieee80211_hw *dev, + struct ieee80211_if_init_conf *conf) +{ + printk("wbsoft_add interface called\n"); + return 0; +} + +static void wbsoft_remove_interface(struct ieee80211_hw *dev, + struct ieee80211_if_init_conf *conf) +{ + printk("wbsoft_remove interface called\n"); +} + +static int wbsoft_nop(void) +{ + printk("wbsoft_nop called\n"); + return 0; +} + +static void wbsoft_configure_filter(struct ieee80211_hw *dev, + unsigned int changed_flags, + unsigned int *total_flags, + int mc_count, struct dev_mc_list *mclist) +{ + unsigned int bit_nr, new_flags; + u32 mc_filter[2]; + int i; + + new_flags = 0; + + if (*total_flags & FIF_PROMISC_IN_BSS) { + new_flags |= FIF_PROMISC_IN_BSS; + mc_filter[1] = mc_filter[0] = ~0; + } else if ((*total_flags & FIF_ALLMULTI) || (mc_count > 32)) { + new_flags |= FIF_ALLMULTI; + mc_filter[1] = mc_filter[0] = ~0; + } else { + mc_filter[1] = mc_filter[0] = 0; + for (i = 0; i < mc_count; i++) { + if (!mclist) + break; + printk("Should call ether_crc here\n"); + //bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26; + bit_nr = 0; + + bit_nr &= 0x3F; + mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31); + mclist = mclist->next; + } + } + + dev->flags &= ~IEEE80211_HW_RX_INCLUDES_FCS; + + *total_flags = new_flags; +} + +static int wbsoft_tx(struct ieee80211_hw *dev, struct sk_buff *skb, + struct ieee80211_tx_control *control) +{ + char *buffer = kmalloc(skb->len, GFP_ATOMIC); + printk("Sending frame %d bytes\n", skb->len); + memcpy(buffer, skb->data, skb->len); + if (1 == MLMESendFrame(my_adapter, buffer, skb->len, FRAME_TYPE_802_11_MANAGEMENT)) + printk("frame sent ok (%d bytes)?\n", skb->len); + return NETDEV_TX_OK; +} + + +static int wbsoft_start(struct ieee80211_hw *dev) +{ + wbsoft_enabled = 1; + printk("wbsoft_start called\n"); + return 0; +} + +static int wbsoft_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf) +{ + ChanInfo ch; + printk("wbsoft_config called\n"); + + ch.band = 1; + ch.ChanNo = 1; /* Should use channel_num, or something, as that is already pre-translated */ + + + hal_set_current_channel(&my_adapter->sHwData, ch); + hal_set_beacon_period(&my_adapter->sHwData, conf->beacon_int); +// hal_set_cap_info(&my_adapter->sHwData, ?? ); +// hal_set_ssid(phw_data_t pHwData, PUCHAR pssid, u8 ssid_len); ?? + hal_set_accept_broadcast(&my_adapter->sHwData, 1); + hal_set_accept_promiscuous(&my_adapter->sHwData, 1); + hal_set_accept_multicast(&my_adapter->sHwData, 1); + hal_set_accept_beacon(&my_adapter->sHwData, 1); + hal_set_radio_mode(&my_adapter->sHwData, 0); + //hal_set_antenna_number( phw_data_t pHwData, u8 number ) + //hal_set_rf_power(phw_data_t pHwData, u8 PowerIndex) + + +// hal_start_bss(&my_adapter->sHwData, WLAN_BSSTYPE_INFRASTRUCTURE); ?? + +//void hal_set_rates(phw_data_t pHwData, PUCHAR pbss_rates, +// u8 length, unsigned char basic_rate_set) + + return 0; +} + +static int wbsoft_config_interface(struct ieee80211_hw *dev, + struct ieee80211_vif *vif, + struct ieee80211_if_conf *conf) +{ + printk("wbsoft_config_interface called\n"); + return 0; +} + +static u64 wbsoft_get_tsf(struct ieee80211_hw *dev) +{ + printk("wbsoft_get_tsf called\n"); + return 0; +} + +static const struct ieee80211_ops wbsoft_ops = { + .tx = wbsoft_tx, + .start = wbsoft_start, /* Start can be pretty much empty as we do WbWLanInitialize() during probe? */ + .stop = wbsoft_nop, + .add_interface = wbsoft_add_interface, + .remove_interface = wbsoft_remove_interface, + .config = wbsoft_config, + .config_interface = wbsoft_config_interface, + .configure_filter = wbsoft_configure_filter, + .get_stats = wbsoft_nop, + .get_tx_stats = wbsoft_nop, + .get_tsf = wbsoft_get_tsf, +// conf_tx: hal_set_cwmin()/hal_set_cwmax; +}; + +struct wbsoft_priv { +}; + + +int __init wb35_init(void) +{ + printk("[w35und]driver init\n"); + return usb_register(&wb35_driver); +} + +void __exit wb35_exit(void) +{ + printk("[w35und]driver exit\n"); + usb_deregister( &wb35_driver ); +} + +module_init(wb35_init); +module_exit(wb35_exit); + +// Usb kernel subsystem will call this function when a new device is plugged into. +int wb35_probe(struct usb_interface *intf, const struct usb_device_id *id_table) +{ + PADAPTER Adapter; + PWBLINUX pWbLinux; + PWBUSB pWbUsb; + struct usb_host_interface *interface; + struct usb_endpoint_descriptor *endpoint; + int i, ret = -1; + u32 ltmp; + struct usb_device *udev = interface_to_usbdev(intf); + + usb_get_dev(udev); + + printk("[w35und]wb35_probe ->\n"); + + do { + for (i=0; i<(sizeof(Id_Table)/sizeof(struct usb_device_id)); i++ ) { + if ((udev->descriptor.idVendor == Id_Table[i].idVendor) && + (udev->descriptor.idProduct == Id_Table[i].idProduct)) { + printk("[w35und]Found supported hardware\n"); + break; + } + } + if ((i == (sizeof(Id_Table)/sizeof(struct usb_device_id)))) { + #ifdef _PE_USB_INI_DUMP_ + WBDEBUG(("[w35und] This is not the one we are interested about\n")); + #endif + return -ENODEV; + } + + // 20060630.2 Check the device if it already be opened + ret = usb_control_msg(udev, usb_rcvctrlpipe( udev, 0 ), + 0x01, USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_DIR_IN, + 0x0, 0x400, <mp, 4, HZ*100 ); + if( ret < 0 ) + break; + + ltmp = cpu_to_le32(ltmp); + if (ltmp) // Is already initialized? + break; + + + Adapter = kzalloc(sizeof(ADAPTER), GFP_KERNEL); + + my_adapter = Adapter; + pWbLinux = &Adapter->WbLinux; + pWbUsb = &Adapter->sHwData.WbUsb; + pWbUsb->udev = udev; + + interface = intf->cur_altsetting; + endpoint = &interface->endpoint[0].desc; + + if (endpoint[2].wMaxPacketSize == 512) { + printk("[w35und] Working on USB 2.0\n"); + pWbUsb->IsUsb20 = 1; + } + + if (!WbWLanInitialize(Adapter)) { + printk("[w35und]WbWLanInitialize fail\n"); + break; + } + + { + struct wbsoft_priv *priv; + struct ieee80211_hw *dev; + int res; + + dev = ieee80211_alloc_hw(sizeof(*priv), &wbsoft_ops); + + if (!dev) { + printk("w35und: ieee80211 alloc failed\n" ); + BUG(); + } + + my_dev = dev; + + SET_IEEE80211_DEV(dev, &udev->dev); + { + phw_data_t pHwData = &Adapter->sHwData; + unsigned char dev_addr[MAX_ADDR_LEN]; + hal_get_permanent_address(pHwData, dev_addr); + SET_IEEE80211_PERM_ADDR(dev, dev_addr); + } + + + dev->extra_tx_headroom = 12; /* FIXME */ + dev->flags = 0; + + dev->channel_change_time = 1000; +// dev->max_rssi = 100; + + dev->queues = 1; + + static struct ieee80211_supported_band band; + + band.channels = wbsoft_channels; + band.n_channels = ARRAY_SIZE(wbsoft_channels); + band.bitrates = wbsoft_rates; + band.n_bitrates = ARRAY_SIZE(wbsoft_rates); + + dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &band; +#if 0 + wbsoft_modes[0].num_channels = 1; + wbsoft_modes[0].channels = wbsoft_channels; + wbsoft_modes[0].mode = MODE_IEEE80211B; + wbsoft_modes[0].num_rates = ARRAY_SIZE(wbsoft_rates); + wbsoft_modes[0].rates = wbsoft_rates; + + res = ieee80211_register_hwmode(dev, &wbsoft_modes[0]); + BUG_ON(res); +#endif + + res = ieee80211_register_hw(dev); + BUG_ON(res); + } + + usb_set_intfdata( intf, Adapter ); + + printk("[w35und] _probe OK\n"); + return 0; + + } while(FALSE); + + return -ENOMEM; +} + +void packet_came(char *pRxBufferAddress, int PacketSize) +{ + struct sk_buff *skb; + struct ieee80211_rx_status rx_status = {0}; + + if (!wbsoft_enabled) + return; + + skb = dev_alloc_skb(PacketSize); + if (!skb) { + printk("Not enough memory for packet, FIXME\n"); + return; + } + + memcpy(skb_put(skb, PacketSize), + pRxBufferAddress, + PacketSize); + +/* + rx_status.rate = 10; + rx_status.channel = 1; + rx_status.freq = 12345; + rx_status.phymode = MODE_IEEE80211B; +*/ + + ieee80211_rx_irqsafe(my_dev, skb, &rx_status); +} + +unsigned char +WbUsb_initial(phw_data_t pHwData) +{ + return 1; +} + + +void +WbUsb_destroy(phw_data_t pHwData) +{ +} + +int wb35_open(struct net_device *netdev) +{ + PADAPTER Adapter = (PADAPTER)netdev->priv; + phw_data_t pHwData = &Adapter->sHwData; + + netif_start_queue(netdev); + + //TODO : put here temporarily + hal_set_accept_broadcast(pHwData, 1); // open accept broadcast + + return 0; +} + +int wb35_close(struct net_device *netdev) +{ + netif_stop_queue(netdev); + return 0; +} + +void wb35_disconnect(struct usb_interface *intf) +{ + PWBLINUX pWbLinux; + PADAPTER Adapter = usb_get_intfdata(intf); + usb_set_intfdata(intf, NULL); + + pWbLinux = &Adapter->WbLinux; + + // Card remove + WbWlanHalt(Adapter); + +} + + diff --git a/drivers/staging/winbond/linux/wbusb_f.h b/drivers/staging/winbond/linux/wbusb_f.h new file mode 100644 index 000000000000..cae29e107e11 --- /dev/null +++ b/drivers/staging/winbond/linux/wbusb_f.h @@ -0,0 +1,34 @@ +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// Copyright (c) 1996-2004 Winbond Electronic Corporation +// +// Module Name: +// wbusb_f.h +// +// Abstract: +// Linux driver. +// +// Author: +// +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +int wb35_open(struct net_device *netdev); +int wb35_close(struct net_device *netdev); +unsigned char WbUsb_initial(phw_data_t pHwData); +void WbUsb_destroy(phw_data_t pHwData); +unsigned char WbWLanInitialize(PADAPTER Adapter); +#define WbUsb_Stop( _A ) + +int wb35_probe(struct usb_interface *intf,const struct usb_device_id *id_table); +void wb35_disconnect(struct usb_interface *intf); + + +#define wb_usb_submit_urb(_A) usb_submit_urb(_A, GFP_ATOMIC) +#define wb_usb_alloc_urb(_A) usb_alloc_urb(_A, GFP_ATOMIC) + +#define WbUsb_CheckForHang( _P ) +#define WbUsb_DetectStart( _P, _I ) + + + + + diff --git a/drivers/staging/winbond/linux/wbusb_s.h b/drivers/staging/winbond/linux/wbusb_s.h new file mode 100644 index 000000000000..d5c1d53de70b --- /dev/null +++ b/drivers/staging/winbond/linux/wbusb_s.h @@ -0,0 +1,42 @@ +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// Copyright (c) 1996-2004 Winbond Electronic Corporation +// +// Module Name: +// wbusb_s.h +// +// Abstract: +// Linux driver. +// +// Author: +// +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +#define OS_SLEEP( _MT ) { set_current_state(TASK_INTERRUPTIBLE); \ + schedule_timeout( _MT*HZ/1000000 ); } + + +//--------------------------------------------------------------------------- +// RW_CONTEXT -- +// +// Used to track driver-generated io irps +//--------------------------------------------------------------------------- +typedef struct _RW_CONTEXT +{ + void* pHwData; + PURB pUrb; + void* pCallBackFunctionParameter; +} RW_CONTEXT, *PRW_CONTEXT; + + + + +#define DRIVER_AUTHOR "Original by: Jeff Lee<YY_Lee@issc.com.tw> Adapted to 2.6.x by Costantino Leandro (Rxart Desktop) <le_costantino@pixartargentina.com.ar>" +#define DRIVER_DESC "IS89C35 802.11bg WLAN USB Driver" + + + +typedef struct _WBUSB { + u32 IsUsb20; + struct usb_device *udev; + u32 DetectCount; +} WBUSB, *PWBUSB; diff --git a/drivers/staging/winbond/localpara.h b/drivers/staging/winbond/localpara.h new file mode 100644 index 000000000000..268cf916ab48 --- /dev/null +++ b/drivers/staging/winbond/localpara.h @@ -0,0 +1,275 @@ +//============================================================= +// LocalPara.h - +//============================================================= +//Define the local ability + +#define LOCAL_DEFAULT_BEACON_PERIOD 100 //ms +#define LOCAL_DEFAULT_ATIM_WINDOW 0 +#define LOCAL_DEFAULT_ERP_CAPABILITY 0x0431 //0x0001: ESS + //0x0010: Privacy + //0x0020: short preamble + //0x0400: short slot time +#define LOCAL_DEFAULT_LISTEN_INTERVAL 5 + +//#define LOCAL_DEFAULT_24_CHANNEL_NUM 11 // channel 1..11 +#define LOCAL_DEFAULT_24_CHANNEL_NUM 13 // channel 1..13 +#define LOCAL_DEFAULT_5_CHANNEL_NUM 8 // channel 36..64 + +#define LOCAL_USA_24_CHANNEL_NUM 11 +#define LOCAL_USA_5_CHANNEL_NUM 12 +#define LOCAL_EUROPE_24_CHANNEL_NUM 13 +#define LOCAL_EUROPE_5_CHANNEL_NUM 19 +#define LOCAL_JAPAN_24_CHANNEL_NUM 14 +#define LOCAL_JAPAN_5_CHANNEL_NUM 11 +#define LOCAL_UNKNOWN_24_CHANNEL_NUM 14 +#define LOCAL_UNKNOWN_5_CHANNEL_NUM 34 //not include 165 + + +#define psLOCAL (&(Adapter->sLocalPara)) + +#define MODE_802_11_BG 0 +#define MODE_802_11_A 1 +#define MODE_802_11_ABG 2 +#define MODE_802_11_BG_IBSS 3 +#define MODE_802_11_B 4 +#define MODE_AUTO 255 + +#define BAND_TYPE_DSSS 0 +#define BAND_TYPE_OFDM_24 1 +#define BAND_TYPE_OFDM_5 2 + +//refer Bitmap2RateValue table +#define LOCAL_ALL_SUPPORTED_RATES_BITMAP 0x130c1a66 //the bitmap value of all the H/W supported rates + //1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54 +#define LOCAL_OFDM_SUPPORTED_RATES_BITMAP 0x130c1240 //the bitmap value of all the H/W supported rates + //except to non-OFDM rates + //6, 9, 12, 18, 24, 36, 48, 54 + +#define LOCAL_11B_SUPPORTED_RATE_BITMAP 0x826 +#define LOCAL_11B_BASIC_RATE_BITMAP 0x826 +#define LOCAL_11B_OPERATION_RATE_BITMAP 0x826 +#define LOCAL_11G_BASIC_RATE_BITMAP 0x826 //1, 2, 5.5, 11 +#define LOCAL_11G_OPERATION_RATE_BITMAP 0x130c1240 //6, 9, 12, 18, 24, 36, 48, 54 +#define LOCAL_11A_BASIC_RATE_BITMAP 0x01001040 //6, 12, 24 +#define LOCAL_11A_OPERATION_RATE_BITMAP 0x120c0200 //9, 18, 36, 48, 54 + + + +#define PWR_ACTIVE 0 +#define PWR_SAVE 1 +#define PWR_TX_IDLE_CYCLE 6 + +//bPreambleMode and bSlotTimeMode +#define AUTO_MODE 0 +#define LONG_MODE 1 + +//Region definition +#define REGION_AUTO 0xff +#define REGION_UNKNOWN 0 +#define REGION_EUROPE 1 //ETSI +#define REGION_JAPAN 2 //MKK +#define REGION_USA 3 //FCC +#define REGION_FRANCE 4 //FRANCE +#define REGION_SPAIN 5 //SPAIN +#define REGION_ISRAEL 6 //ISRAEL +//#define REGION_CANADA 7 //IC + +#define MAX_BSS_DESCRIPT_ELEMENT 32 +#define MAX_PMKID_CandidateList 16 + +//High byte : Event number, low byte : reason +//Event definition +//-- SME/MLME event +#define EVENT_RCV_DEAUTH 0x0100 +#define EVENT_JOIN_FAIL 0x0200 +#define EVENT_AUTH_FAIL 0x0300 +#define EVENT_ASSOC_FAIL 0x0400 +#define EVENT_LOST_SIGNAL 0x0500 +#define EVENT_BSS_DESCRIPT_LACK 0x0600 +#define EVENT_COUNTERMEASURE 0x0700 +#define EVENT_JOIN_FILTER 0x0800 +//-- TX/RX event +#define EVENT_RX_BUFF_UNAVAILABLE 0x4100 + +#define EVENT_CONNECT 0x8100 +#define EVENT_DISCONNECT 0x8200 +#define EVENT_SCAN_REQ 0x8300 + +//Reason of Event +#define EVENT_REASON_FILTER_BASIC_RATE 0x0001 +#define EVENT_REASON_FILTER_PRIVACY 0x0002 +#define EVENT_REASON_FILTER_AUTH_MODE 0x0003 +#define EVENT_REASON_TIMEOUT 0x00ff + +// 20061108 WPS IE buffer +#define MAX_IE_APPEND_SIZE 256 + 4 // Due to [E id][Length][OUI][Data] may 257 bytes + +typedef struct _EVENTLOG +{ + u16 Count; //Total count from start + u16 index; //Buffer index, 0 ~ 63 + u32 EventValue[64]; //BYTE 3~2 : count, BYTE 1 : Event, BYTE 0 : reason +} Event_Log, *pEvent_Log; + +typedef struct _ChanInfo +{ + u8 band; + u8 ChanNo; +} ChanInfo, *pChanInfo; + +typedef struct _CHAN_LIST +{ + u16 Count; + ChanInfo Channel[50]; // 100B +} CHAN_LIST, *psCHAN_LIST; + +typedef struct _RadioOff +{ + u8 boHwRadioOff; + u8 boSwRadioOff; +} RadioOff, *psRadioOff; + +//=========================================================================== +typedef struct LOCAL_PARA +{ + u8 PermanentAddress[ MAC_ADDR_LENGTH + 2 ]; // read from EPROM, manufacture set for each NetCard + u8 ThisMacAddress[ MAC_ADDR_LENGTH + 2 ]; // the driver will use actually. + + u32 MTUsize; // Ind to Uplayer, Max transmission unit size + + u8 region_INF; //region setting from INF + u8 region; //real region setting of the device + u8 Reserved_1[2]; + + //// power-save variables + u8 iPowerSaveMode; // 0 indicates it is on, 1 indicates it is off + u8 ShutDowned; + u8 ATIMmode; + u8 ExcludeUnencrypted; + + u16 CheckCountForPS; //Unit ime count for the decision to enter PS mode + u8 boHasTxActivity; //tx activity has occurred + u8 boMacPsValid; //Power save mode obtained from H/W is valid or not + + //// Rate + u8 TxRateMode; // Initial, input from Registry, may be updated by GUI + //Tx Rate Mode: auto(DTO on), max, 1M, 2M, .. + u8 CurrentTxRate; // The current Tx rate + u8 CurrentTxRateForMng; // The current Tx rate for management frames + // It will be decided before connection succeeds. + u8 CurrentTxFallbackRate; + + //for Rate handler + u8 BRateSet[32]; //basic rate set + u8 SRateSet[32]; //support rate set + + u8 NumOfBRate; + u8 NumOfSRate; + u8 NumOfDsssRateInSRate; //number of DSSS rates in supported rate set + u8 reserved1; + + u32 dwBasicRateBitmap; //bit map of basic rates + u32 dwSupportRateBitmap; //bit map of all support rates including + //basic and operational rates + + ////For SME/MLME handler + u16 wOldSTAindex; // valid when boHandover=TRUE, store old connected STA index + u16 wConnectedSTAindex; // Index of peerly connected AP or IBSS in + // the descriptionset. + u16 Association_ID; // The Association ID in the (Re)Association + // Response frame. + u16 ListenInterval; // The listen interval when SME invoking MLME_ + // (Re)Associate_Request(). + + RadioOff RadioOffStatus; + u8 Reserved0[2]; + + u8 boMsRadioOff; // Ndis demands to be true when set Disassoc. OID and be false when set SSID OID. + u8 boAntennaDiversity; //TRUE/ON or FALSE/OFF + u8 bAntennaNo; //which antenna + u8 bConnectFlag; //the connect status flag for roaming task + + u8 RoamStatus; + u8 reserved7[3]; + + ChanInfo CurrentChan; //Current channel no. and channel band. It may be changed by scanning. + u8 boHandover; // Roaming, Hnadover to other AP. + u8 boCCAbusy; + + u16 CWMax; // It may not be the real value that H/W used + u8 CWMin; // 255: set according to 802.11 spec. + u8 reserved2; + + //11G: + u8 bMacOperationMode; // operation in 802.11b or 802.11g + u8 bSlotTimeMode; //AUTO, s32 + u8 bPreambleMode; //AUTO, s32 + u8 boNonERPpresent; + + u8 boProtectMechanism; // H/W will take the necessary action based on this variable + u8 boShortPreamble; // H/W will take the necessary action based on this variable + u8 boShortSlotTime; // H/W will take the necessary action based on this variable + u8 reserved_3; + + u32 RSN_IE_Bitmap; //added by WS + u32 RSN_OUI_Type; //added by WS + + //For the BSSID + u8 HwBssid[MAC_ADDR_LENGTH + 2]; + u32 HwBssidValid; + + //For scan list + u8 BssListCount; //Total count of valid descriptor indexes + u8 boReceiveUncorrectInfo; //important settings in beacon/probe resp. have been changed + u8 NoOfJoinerInIbss; + u8 reserved_4; + + u8 BssListIndex[ (MAX_BSS_DESCRIPT_ELEMENT+3) & ~0x03 ]; //Store the valid descriptor indexes obtained from scannings + u8 JoinerInIbss[ (MAX_BSS_DESCRIPT_ELEMENT+3) & ~0x03 ]; //save the BssDescriptor index in this + //IBSS. The index 0 is local descriptor + //(psLOCAL->wConnectedSTAindex). + //If CONNECTED : NoOfJoinerInIbss >=2 + // else : NoOfJoinerInIbss <=1 + + //// General Statistics, count at Rx_handler or Tx_callback interrupt handler + u64 GS_XMIT_OK; // Good Frames Transmitted + u64 GS_RCV_OK; // Good Frames Received + u32 GS_RCV_ERROR; // Frames received with crc error + u32 GS_XMIT_ERROR; // Bad Frames Transmitted + u32 GS_RCV_NO_BUFFER; // Receive Buffer underrun + u32 GS_XMIT_ONE_COLLISION; // one collision + u32 GS_XMIT_MORE_COLLISIONS;// more collisions + + //================================================================ + // Statistics (no matter whether it had done successfully) -wkchen + //================================================================ + u32 _NumRxMSDU; + u32 _NumTxMSDU; + u32 _dot11WEPExcludedCount; + u32 _dot11WEPUndecryptableCount; + u32 _dot11FrameDuplicateCount; + + ChanInfo IbssChanSetting; // 2B. Start IBSS Channel setting by registry or WWU. + u8 reserved_5[2]; //It may not be used after considering RF type, + //region and modulation type. + + CHAN_LIST sSupportChanList; // 86B. It will be obtained according to RF type and region + u8 reserved_6[2]; //two variables are for wep key error detection added by ws 02/02/04 + + u32 bWepKeyError; + u32 bToSelfPacketReceived; + u32 WepKeyDetectTimerCount; + + Event_Log EventLog; + + u16 SignalLostTh; + u16 SignalRoamTh; + + // 20061108 WPS IE Append + u8 IE_Append_data[MAX_IE_APPEND_SIZE]; + u16 IE_Append_size; + u16 reserved_7; + +} WB_LOCALDESCRIPT, *PWB_LOCALDESCRIPT; + + diff --git a/drivers/staging/winbond/mac_structures.h b/drivers/staging/winbond/mac_structures.h new file mode 100644 index 000000000000..031d2cb6cd63 --- /dev/null +++ b/drivers/staging/winbond/mac_structures.h @@ -0,0 +1,670 @@ +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// MAC_Structures.h +// +// This file contains the definitions and data structures used by SW-MAC. +// +// Revision Histoy +//================= +// 0.1 2002 UN00 +// 0.2 20021004 PD43 CCLiu6 +// 20021018 PD43 CCLiu6 +// Add enum_TxRate type +// Modify enum_STAState type +// 0.3 20021023 PE23 CYLiu update MAC session struct +// 20021108 +// 20021122 PD43 Austin +// Deleted some unused. +// 20021129 PD43 Austin +// 20030617 increase the 802.11g definition +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +#ifndef _MAC_Structures_H_ +#define _MAC_Structures_H_ + + +//========================================================= +// Some miscellaneous definitions +//----- +#define MAX_CHANNELS 30 +#define MAC_ADDR_LENGTH 6 +#define MAX_WEP_KEY_SIZE 16 // 128 bits +#define MAX_802_11_FRAGMENT_NUMBER 10 // By spec + +//======================================================== +// 802.11 Frame define +//----- +#define MASK_PROTOCOL_VERSION_TYPE 0x0F +#define MASK_FRAGMENT_NUMBER 0x000F +#define SEQUENCE_NUMBER_SHIFT 4 +#define DIFFER_11_TO_3 18 +#define DOT_11_MAC_HEADER_SIZE 24 +#define DOT_11_SNAP_SIZE 6 +#define DOT_11_DURATION_OFFSET 2 +#define DOT_11_SEQUENCE_OFFSET 22 //Sequence control offset +#define DOT_11_TYPE_OFFSET 30 //The start offset of 802.11 Frame// +#define DOT_11_DATA_OFFSET 24 +#define DOT_11_DA_OFFSET 4 +#define DOT_3_TYPE_ARP 0x80F3 +#define DOT_3_TYPE_IPX 0x8137 +#define DOT_3_TYPE_OFFSET 12 + + +#define ETHERNET_HEADER_SIZE 14 +#define MAX_ETHERNET_PACKET_SIZE 1514 + + +//----- management : Type of Bits (2, 3) and Subtype of Bits (4, 5, 6, 7) +#define MAC_SUBTYPE_MNGMNT_ASSOC_REQUEST 0x00 +#define MAC_SUBTYPE_MNGMNT_ASSOC_RESPONSE 0x10 +#define MAC_SUBTYPE_MNGMNT_REASSOC_REQUEST 0x20 +#define MAC_SUBTYPE_MNGMNT_REASSOC_RESPONSE 0x30 +#define MAC_SUBTYPE_MNGMNT_PROBE_REQUEST 0x40 +#define MAC_SUBTYPE_MNGMNT_PROBE_RESPONSE 0x50 +#define MAC_SUBTYPE_MNGMNT_BEACON 0x80 +#define MAC_SUBTYPE_MNGMNT_ATIM 0x90 +#define MAC_SUBTYPE_MNGMNT_DISASSOCIATION 0xA0 +#define MAC_SUBTYPE_MNGMNT_AUTHENTICATION 0xB0 +#define MAC_SUBTYPE_MNGMNT_DEAUTHENTICATION 0xC0 + +//----- control : Type of Bits (2, 3) and Subtype of Bits (4, 5, 6, 7) +#define MAC_SUBTYPE_CONTROL_PSPOLL 0xA4 +#define MAC_SUBTYPE_CONTROL_RTS 0xB4 +#define MAC_SUBTYPE_CONTROL_CTS 0xC4 +#define MAC_SUBTYPE_CONTROL_ACK 0xD4 +#define MAC_SUBTYPE_CONTROL_CFEND 0xE4 +#define MAC_SUBTYPE_CONTROL_CFEND_CFACK 0xF4 + +//----- data : Type of Bits (2, 3) and Subtype of Bits (4, 5, 6, 7) +#define MAC_SUBTYPE_DATA 0x08 +#define MAC_SUBTYPE_DATA_CFACK 0x18 +#define MAC_SUBTYPE_DATA_CFPOLL 0x28 +#define MAC_SUBTYPE_DATA_CFACK_CFPOLL 0x38 +#define MAC_SUBTYPE_DATA_NULL 0x48 +#define MAC_SUBTYPE_DATA_CFACK_NULL 0x58 +#define MAC_SUBTYPE_DATA_CFPOLL_NULL 0x68 +#define MAC_SUBTYPE_DATA_CFACK_CFPOLL_NULL 0x78 + +//----- Frame Type of Bits (2, 3) +#define MAC_TYPE_MANAGEMENT 0x00 +#define MAC_TYPE_CONTROL 0x04 +#define MAC_TYPE_DATA 0x08 + +//----- definitions for Management Frame Element ID (1 BYTE) +#define ELEMENT_ID_SSID 0 +#define ELEMENT_ID_SUPPORTED_RATES 1 +#define ELEMENT_ID_FH_PARAMETER_SET 2 +#define ELEMENT_ID_DS_PARAMETER_SET 3 +#define ELEMENT_ID_CF_PARAMETER_SET 4 +#define ELEMENT_ID_TIM 5 +#define ELEMENT_ID_IBSS_PARAMETER_SET 6 +// 7~15 reserverd +#define ELEMENT_ID_CHALLENGE_TEXT 16 +// 17~31 reserved for challenge text extension +// 32~255 reserved +//-- 11G -- +#define ELEMENT_ID_ERP_INFORMATION 42 +#define ELEMENT_ID_EXTENDED_SUPPORTED_RATES 50 + +//-- WPA -- + +#define ELEMENT_ID_RSN_WPA 221 +#ifdef _WPA2_ +#define ELEMENT_ID_RSN_WPA2 48 +#endif //endif WPA2 + +#define WLAN_MAX_PAIRWISE_CIPHER_SUITE_COUNT ((u16) 6) +#define WLAN_MAX_AUTH_KEY_MGT_SUITE_LIST_COUNT ((u16) 2) + +#ifdef WB_LINUX +#define UNALIGNED +#endif + +//======================================================== +typedef enum enum_PowerManagementMode +{ + ACTIVE = 0, + POWER_SAVE +} WB_PM_Mode, *PWB_PM_MODE; + +//=================================================================== +// Reason Code (Table 18): indicate the reason of DisAssoc, DeAuthen +// length of ReasonCode is 2 Octs. +//=================================================================== +#define REASON_REASERED 0 +#define REASON_UNSPECIDIED 1 +#define REASON_PREAUTH_INVALID 2 +#define DEAUTH_REASON_LEFT_BSS 3 +#define DISASS_REASON_AP_INACTIVE 4 +#define DISASS_REASON_AP_BUSY 5 +#define REASON_CLASS2_FRAME_FROM_NONAUTH_STA 6 +#define REASON_CLASS3_FRAME_FROM_NONASSO_STA 7 +#define DISASS_REASON_LEFT_BSS 8 +#define REASON_NOT_AUTH_YET 9 +//802.11i define +#define REASON_INVALID_IE 13 +#define REASON_MIC_ERROR 14 +#define REASON_4WAY_HANDSHAKE_TIMEOUT 15 +#define REASON_GROUPKEY_UPDATE_TIMEOUT 16 +#define REASON_IE_DIFF_4WAY_ASSOC 17 +#define REASON_INVALID_MULTICAST_CIPHER 18 +#define REASON_INVALID_UNICAST_CIPHER 19 +#define REASON_INVALID_AKMP 20 +#define REASON_UNSUPPORTED_RSNIE_VERSION 21 +#define REASON_INVALID_RSNIE_CAPABILITY 22 +#define REASON_802_1X_AUTH_FAIL 23 +#define REASON_CIPHER_REJECT_PER_SEC_POLICY 14 + +/* +//=========================================================== +// enum_MMPDUResultCode -- +// Status code (2 Octs) in the MMPDU's frame body. Table.19 +// +//=========================================================== +enum enum_MMPDUResultCode +{ +// SUCCESS = 0, // Redefined + UNSPECIFIED_FAILURE = 1, + + // 2 - 9 Reserved + + NOT_SUPPROT_CAPABILITIES = 10, + + //REASSOCIATION_DENIED + // + REASSOC_DENIED_UNABLE_CFM_ASSOC_EXIST = 11, + + //ASSOCIATION_DENIED_NOT_IN_STANDARD + // + ASSOC_DENIED_REASON_NOT_IN_STANDARD = 12, + PEER_NOT_SUPPORT_AUTH_ALGORITHM = 13, + AUTH_SEQNUM_OUT_OF_EXPECT = 14, + AUTH_REJECT_REASON_CHALLENGE_FAIL = 15, + AUTH_REJECT_REASON_WAIT_TIMEOUT = 16, + ASSOC_DENIED_REASON_AP_BUSY = 17, + ASSOC_DENIED_REASON_NOT_SUPPORT_BASIC_RATE = 18 +} WB_MMPDURESULTCODE, *PWB_MMPDURESULTCODE; +*/ + +//=========================================================== +// enum_TxRate -- +// Define the transmission constants based on W89C32 MAC +// target specification. +//=========================================================== +typedef enum enum_TxRate +{ + TXRATE_1M = 0, + TXRATE_2MLONG = 2, + TXRATE_2MSHORT = 3, + TXRATE_55MLONG = 4, + TXRATE_55MSHORT = 5, + TXRATE_11MLONG = 6, + TXRATE_11MSHORT = 7, + TXRATE_AUTO = 255 // PD43 20021108 +} WB_TXRATE, *PWB_TXRATE; + + +#define RATE_BITMAP_1M 1 +#define RATE_BITMAP_2M 2 +#define RATE_BITMAP_5dot5M 5 +#define RATE_BITMAP_6M 6 +#define RATE_BITMAP_9M 9 +#define RATE_BITMAP_11M 11 +#define RATE_BITMAP_12M 12 +#define RATE_BITMAP_18M 18 +#define RATE_BITMAP_22M 22 +#define RATE_BITMAP_24M 24 +#define RATE_BITMAP_33M 17 +#define RATE_BITMAP_36M 19 +#define RATE_BITMAP_48M 25 +#define RATE_BITMAP_54M 28 + +#define RATE_AUTO 0 +#define RATE_1M 2 +#define RATE_2M 4 +#define RATE_5dot5M 11 +#define RATE_6M 12 +#define RATE_9M 18 +#define RATE_11M 22 +#define RATE_12M 24 +#define RATE_18M 36 +#define RATE_22M 44 +#define RATE_24M 48 +#define RATE_33M 66 +#define RATE_36M 72 +#define RATE_48M 96 +#define RATE_54M 108 +#define RATE_MAX 255 + +//CAPABILITY +#define CAPABILITY_ESS_BIT 0x0001 +#define CAPABILITY_IBSS_BIT 0x0002 +#define CAPABILITY_CF_POLL_BIT 0x0004 +#define CAPABILITY_CF_POLL_REQ_BIT 0x0008 +#define CAPABILITY_PRIVACY_BIT 0x0010 +#define CAPABILITY_SHORT_PREAMBLE_BIT 0x0020 +#define CAPABILITY_PBCC_BIT 0x0040 +#define CAPABILITY_CHAN_AGILITY_BIT 0x0080 +#define CAPABILITY_SHORT_SLOT_TIME_BIT 0x0400 +#define CAPABILITY_DSSS_OFDM_BIT 0x2000 + + +struct Capability_Information_Element +{ + union + { + u16 __attribute__ ((packed)) wValue; + #ifdef _BIG_ENDIAN_ //20060926 add by anson's endian + struct _Capability + { + //-- 11G -- + u8 Reserved3 : 2; + u8 DSSS_OFDM : 1; + u8 Reserved2 : 2; + u8 Short_Slot_Time : 1; + u8 Reserved1 : 2; + u8 Channel_Agility : 1; + u8 PBCC : 1; + u8 ShortPreamble : 1; + u8 CF_Privacy : 1; + u8 CF_Poll_Request : 1; + u8 CF_Pollable : 1; + u8 IBSS : 1; + u8 ESS : 1; + } __attribute__ ((packed)) Capability; + #else + struct _Capability + { + u8 ESS : 1; + u8 IBSS : 1; + u8 CF_Pollable : 1; + u8 CF_Poll_Request : 1; + u8 CF_Privacy : 1; + u8 ShortPreamble : 1; + u8 PBCC : 1; + u8 Channel_Agility : 1; + u8 Reserved1 : 2; + //-- 11G -- + u8 Short_Slot_Time : 1; + u8 Reserved2 : 2; + u8 DSSS_OFDM : 1; + u8 Reserved3 : 2; + } __attribute__ ((packed)) Capability; + #endif + }__attribute__ ((packed)) ; +}__attribute__ ((packed)); + +struct FH_Parameter_Set_Element +{ + u8 Element_ID; + u8 Length; + u8 Dwell_Time[2]; + u8 Hop_Set; + u8 Hop_Pattern; + u8 Hop_Index; +}; + +struct DS_Parameter_Set_Element +{ + u8 Element_ID; + u8 Length; + u8 Current_Channel; +}; + +struct Supported_Rates_Element +{ + u8 Element_ID; + u8 Length; + u8 SupportedRates[8]; +}__attribute__ ((packed)); + +struct SSID_Element +{ + u8 Element_ID; + u8 Length; + u8 SSID[32]; +}__attribute__ ((packed)) ; + +struct CF_Parameter_Set_Element +{ + u8 Element_ID; + u8 Length; + u8 CFP_Count; + u8 CFP_Period; + u8 CFP_MaxDuration[2]; // in Time Units + u8 CFP_DurRemaining[2]; // in time units +}; + +struct TIM_Element +{ + u8 Element_ID; + u8 Length; + u8 DTIM_Count; + u8 DTIM_Period; + u8 Bitmap_Control; + u8 Partial_Virtual_Bitmap[251]; +}; + +struct IBSS_Parameter_Set_Element +{ + u8 Element_ID; + u8 Length; + u8 ATIM_Window[2]; +}; + +struct Challenge_Text_Element +{ + u8 Element_ID; + u8 Length; + u8 Challenge_Text[253]; +}; + +struct PHY_Parameter_Set_Element +{ +// int aSlotTime; +// int aSifsTime; + s32 aCCATime; + s32 aRxTxTurnaroundTime; + s32 aTxPLCPDelay; + s32 RxPLCPDelay; + s32 aRxTxSwitchTime; + s32 aTxRampOntime; + s32 aTxRampOffTime; + s32 aTxRFDelay; + s32 aRxRFDelay; + s32 aAirPropagationTime; + s32 aMACProcessingDelay; + s32 aPreambleLength; + s32 aPLCPHeaderLength; + s32 aMPDUDurationFactor; + s32 aMPDUMaxLength; +// int aCWmin; +// int aCWmax; +}; + +//-- 11G -- +struct ERP_Information_Element +{ + u8 Element_ID; + u8 Length; + #ifdef _BIG_ENDIAN_ //20060926 add by anson's endian + u8 Reserved:5; //20060926 add by anson + u8 Barker_Preamble_Mode:1; + u8 Use_Protection:1; + u8 NonERP_Present:1; + #else + u8 NonERP_Present:1; + u8 Use_Protection:1; + u8 Barker_Preamble_Mode:1; + u8 Reserved:5; + #endif +}; + +struct Extended_Supported_Rates_Element +{ + u8 Element_ID; + u8 Length; + u8 ExtendedSupportedRates[255]; +}__attribute__ ((packed)); + +//WPA(802.11i draft 3.0) +#define VERSION_WPA 1 +#ifdef _WPA2_ +#define VERSION_WPA2 1 +#endif //end def _WPA2_ +#define OUI_WPA 0x00F25000 //WPA2.0 OUI=00:50:F2, the MSB is reserved for suite type +#ifdef _WPA2_ +#define OUI_WPA2 0x00AC0F00 // for wpa2 change to 0x00ACOF04 by Ws 26/04/04 +#endif //end def _WPA2_ + +#define OUI_WPA_ADDITIONAL 0x01 +#define WLAN_MIN_RSN_WPA_LENGTH 6 //added by ws 09/10/04 +#ifdef _WPA2_ +#define WLAN_MIN_RSN_WPA2_LENGTH 2 // Fix to 2 09/14/05 +#endif //end def _WPA2_ + +#define oui_wpa (u32)(OUI_WPA|OUI_WPA_ADDITIONAL) + +#define WPA_OUI_BIG ((u32) 0x01F25000)//added by ws 09/23/04 +#define WPA_OUI_LITTLE ((u32) 0x01F25001)//added by ws 09/23/04 + +#define WPA_WPS_OUI cpu_to_le32(0x04F25000) // 20061108 For WPS. It's little endian. Big endian is 0x0050F204 + +//-----WPA2----- +#ifdef _WPA2_ +#define WPA2_OUI_BIG ((u32)0x01AC0F00) +#define WPA2_OUI_LITTLE ((u32)0x01AC0F01) +#endif //end def _WPA2_ + +//Authentication suite +#define OUI_AUTH_WPA_NONE 0x00 //for WPA_NONE +#define OUI_AUTH_8021X 0x01 +#define OUI_AUTH_PSK 0x02 +//Cipher suite +#define OUI_CIPHER_GROUP_KEY 0x00 //added by ws 05/21/04 +#define OUI_CIPHER_WEP_40 0x01 +#define OUI_CIPHER_TKIP 0x02 +#define OUI_CIPHER_CCMP 0x04 +#define OUI_CIPHER_WEP_104 0x05 + +typedef struct _SUITE_SELECTOR_ +{ + union + { + u8 Value[4]; + struct _SUIT_ + { + u8 OUI[3]; + u8 Type; + }SuitSelector; + }; +}SUITE_SELECTOR; + +//-- WPA -- +struct RSN_Information_Element +{ + u8 Element_ID; + u8 Length; + UNALIGNED SUITE_SELECTOR OuiWPAAdditional;//WPA version 2.0 additional field, and should be 00:50:F2:01 + u16 Version; + SUITE_SELECTOR GroupKeySuite; + u16 PairwiseKeySuiteCount; + SUITE_SELECTOR PairwiseKeySuite[1]; +}__attribute__ ((packed)); +struct RSN_Auth_Sub_Information_Element +{ + u16 AuthKeyMngtSuiteCount; + SUITE_SELECTOR AuthKeyMngtSuite[1]; +}__attribute__ ((packed)); + +//-- WPA2 -- +struct RSN_Capability_Element +{ + union + { + u16 __attribute__ ((packed)) wValue; + #ifdef _BIG_ENDIAN_ //20060927 add by anson's endian + struct _RSN_Capability + { + u16 __attribute__ ((packed)) Reserved2 : 8; // 20051201 + u16 __attribute__ ((packed)) Reserved1 : 2; + u16 __attribute__ ((packed)) GTK_Replay_Counter : 2; + u16 __attribute__ ((packed)) PTK_Replay_Counter : 2; + u16 __attribute__ ((packed)) No_Pairwise : 1; + u16 __attribute__ ((packed)) Pre_Auth : 1; + }__attribute__ ((packed)) RSN_Capability; + #else + struct _RSN_Capability + { + u16 __attribute__ ((packed)) Pre_Auth : 1; + u16 __attribute__ ((packed)) No_Pairwise : 1; + u16 __attribute__ ((packed)) PTK_Replay_Counter : 2; + u16 __attribute__ ((packed)) GTK_Replay_Counter : 2; + u16 __attribute__ ((packed)) Reserved1 : 2; + u16 __attribute__ ((packed)) Reserved2 : 8; // 20051201 + }__attribute__ ((packed)) RSN_Capability; + #endif + + }__attribute__ ((packed)) ; +}__attribute__ ((packed)) ; + +#ifdef _WPA2_ +typedef struct _PMKID +{ + u8 pValue[16]; +}PMKID; + +struct WPA2_RSN_Information_Element +{ + u8 Element_ID; + u8 Length; + u16 Version; + SUITE_SELECTOR GroupKeySuite; + u16 PairwiseKeySuiteCount; + SUITE_SELECTOR PairwiseKeySuite[1]; + +}__attribute__ ((packed)); + +struct WPA2_RSN_Auth_Sub_Information_Element +{ + u16 AuthKeyMngtSuiteCount; + SUITE_SELECTOR AuthKeyMngtSuite[1]; +}__attribute__ ((packed)); + + +struct PMKID_Information_Element +{ + u16 PMKID_Count; + PMKID pmkid [16] ; +}__attribute__ ((packed)); + +#endif //enddef _WPA2_ +//============================================================ +// MAC Frame structure (different type) and subfield structure +//============================================================ +struct MAC_frame_control +{ + u8 mac_frame_info; // a combination of the [Protocol Version, Control Type, Control Subtype] + #ifdef _BIG_ENDIAN_ //20060927 add by anson's endian + u8 order:1; + u8 WEP:1; + u8 more_data:1; + u8 pwr_mgt:1; + u8 retry:1; + u8 more_frag:1; + u8 from_ds:1; + u8 to_ds:1; + #else + u8 to_ds:1; + u8 from_ds:1; + u8 more_frag:1; + u8 retry:1; + u8 pwr_mgt:1; + u8 more_data:1; + u8 WEP:1; + u8 order:1; + #endif +} __attribute__ ((packed)); + +struct Management_Frame { + struct MAC_frame_control frame_control; // 2B, ToDS,FromDS,MoreFrag,MoreData,Order=0 + u16 duration; + u8 DA[MAC_ADDR_LENGTH]; // Addr1 + u8 SA[MAC_ADDR_LENGTH]; // Addr2 + u8 BSSID[MAC_ADDR_LENGTH]; // Addr3 + u16 Sequence_Control; + // Management Frame Body <= 325 bytes + // FCS 4 bytes +}__attribute__ ((packed)); + +// SW-MAC don't Tx/Rx Control-Frame, HW-MAC do it. +struct Control_Frame { + struct MAC_frame_control frame_control; // ToDS,FromDS,MoreFrag,Retry,MoreData,WEP,Order=0 + u16 duration; + u8 RA[MAC_ADDR_LENGTH]; + u8 TA[MAC_ADDR_LENGTH]; + u16 FCS; +}__attribute__ ((packed)); + +struct Data_Frame { + struct MAC_frame_control frame_control; + u16 duration; + u8 Addr1[MAC_ADDR_LENGTH]; + u8 Addr2[MAC_ADDR_LENGTH]; + u8 Addr3[MAC_ADDR_LENGTH]; + u16 Sequence_Control; + u8 Addr4[MAC_ADDR_LENGTH]; // only exist when ToDS=FromDS=1 + // Data Frame Body <= 2312 + // FCS +}__attribute__ ((packed)); + +struct Disassociation_Frame_Body +{ + u16 reasonCode; +}__attribute__ ((packed)); + +struct Association_Request_Frame_Body +{ + u16 capability_information; + u16 listenInterval; + u8 Current_AP_Address[MAC_ADDR_LENGTH];//for reassociation only + // SSID (2+32 bytes) + // Supported_Rates (2+8 bytes) +}__attribute__ ((packed)); + +struct Association_Response_Frame_Body +{ + u16 capability_information; + u16 statusCode; + u16 Association_ID; + struct Supported_Rates_Element supportedRates; +}__attribute__ ((packed)); + +/*struct Reassociation_Request_Frame_Body +{ + u16 capability_information; + u16 listenInterval; + u8 Current_AP_Address[MAC_ADDR_LENGTH]; + // SSID (2+32 bytes) + // Supported_Rates (2+8 bytes) +};*/ +// eliminated by WS 07/22/04 comboined with associateion request frame. + +struct Reassociation_Response_Frame_Body +{ + u16 capability_information; + u16 statusCode; + u16 Association_ID; + struct Supported_Rates_Element supportedRates; +}__attribute__ ((packed)); + +struct Deauthentication_Frame_Body +{ + u16 reasonCode; +}__attribute__ ((packed)); + + +struct Probe_Response_Frame_Body +{ + u16 Timestamp; + u16 Beacon_Interval; + u16 Capability_Information; + // SSID + // Supported_Rates + // PHY parameter Set (DS Parameters) + // CF parameter Set + // IBSS parameter Set +}__attribute__ ((packed)); + +struct Authentication_Frame_Body +{ + u16 algorithmNumber; + u16 sequenceNumber; + u16 statusCode; + // NB: don't include ChallengeText in this structure + // struct Challenge_Text_Element sChallengeTextElement; // wkchen added +}__attribute__ ((packed)); + + +#endif // _MAC_Structure_H_ + + diff --git a/drivers/staging/winbond/mds.c b/drivers/staging/winbond/mds.c new file mode 100644 index 000000000000..8ce6389c4135 --- /dev/null +++ b/drivers/staging/winbond/mds.c @@ -0,0 +1,630 @@ +#include "os_common.h" + +void +Mds_reset_descriptor(PADAPTER Adapter) +{ + PMDS pMds = &Adapter->Mds; + + pMds->TxPause = 0; + pMds->TxThreadCount = 0; + pMds->TxFillIndex = 0; + pMds->TxDesIndex = 0; + pMds->ScanTxPause = 0; + memset(pMds->TxOwner, 0, ((MAX_USB_TX_BUFFER_NUMBER + 3) & ~0x03)); +} + +unsigned char +Mds_initial(PADAPTER Adapter) +{ + PMDS pMds = &Adapter->Mds; + + pMds->TxPause = FALSE; + pMds->TxRTSThreshold = DEFAULT_RTSThreshold; + pMds->TxFragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD; + + vRxTimerInit(Adapter);//for WPA countermeasure + + return hal_get_tx_buffer( &Adapter->sHwData, &pMds->pTxBuffer ); +} + +void +Mds_Destroy(PADAPTER Adapter) +{ + vRxTimerStop(Adapter); +} + +void +Mds_Tx(PADAPTER Adapter) +{ + phw_data_t pHwData = &Adapter->sHwData; + PMDS pMds = &Adapter->Mds; + DESCRIPTOR TxDes; + PDESCRIPTOR pTxDes = &TxDes; + PUCHAR XmitBufAddress; + u16 XmitBufSize, PacketSize, stmp, CurrentSize, FragmentThreshold; + u8 FillIndex, TxDesIndex, FragmentCount, FillCount; + unsigned char BufferFilled = FALSE, MICAdd = 0; + + + if (pMds->TxPause) + return; + if (!hal_driver_init_OK(pHwData)) + return; + + //Only one thread can be run here + if (!OS_ATOMIC_INC( Adapter, &pMds->TxThreadCount) == 1) + goto cleanup; + + // Start to fill the data + do { + FillIndex = pMds->TxFillIndex; + if (pMds->TxOwner[FillIndex]) { // Is owned by software 0:Yes 1:No +#ifdef _PE_TX_DUMP_ + WBDEBUG(("[Mds_Tx] Tx Owner is H/W.\n")); +#endif + break; + } + + XmitBufAddress = pMds->pTxBuffer + (MAX_USB_TX_BUFFER * FillIndex); //Get buffer + XmitBufSize = 0; + FillCount = 0; + do { + PacketSize = Adapter->sMlmeFrame.len; + if (!PacketSize) + break; + + //For Check the buffer resource + FragmentThreshold = CURRENT_FRAGMENT_THRESHOLD; + //931130.5.b + FragmentCount = PacketSize/FragmentThreshold + 1; + stmp = PacketSize + FragmentCount*32 + 8;//931130.5.c 8:MIC + if ((XmitBufSize + stmp) >= MAX_USB_TX_BUFFER) { + printk("[Mds_Tx] Excess max tx buffer.\n"); + break; // buffer is not enough + } + + + // + // Start transmitting + // + BufferFilled = TRUE; + + /* Leaves first u8 intact */ + memset((PUCHAR)pTxDes + 1, 0, sizeof(DESCRIPTOR) - 1); + + TxDesIndex = pMds->TxDesIndex;//Get the current ID + pTxDes->Descriptor_ID = TxDesIndex; + pMds->TxDesFrom[ TxDesIndex ] = 2;//Storing the information of source comming from + pMds->TxDesIndex++; + pMds->TxDesIndex %= MAX_USB_TX_DESCRIPTOR; + + MLME_GetNextPacket( Adapter, pTxDes ); + + // Copy header. 8byte USB + 24byte 802.11Hdr. Set TxRate, Preamble type + Mds_HeaderCopy( Adapter, pTxDes, XmitBufAddress ); + + // For speed up Key setting + if (pTxDes->EapFix) { +#ifdef _PE_TX_DUMP_ + WBDEBUG(("35: EPA 4th frame detected. Size = %d\n", PacketSize)); +#endif + pHwData->IsKeyPreSet = 1; + } + + // Copy (fragment) frame body, and set USB, 802.11 hdr flag + CurrentSize = Mds_BodyCopy(Adapter, pTxDes, XmitBufAddress); + + // Set RTS/CTS and Normal duration field into buffer + Mds_DurationSet(Adapter, pTxDes, XmitBufAddress); + + // + // Calculation MIC from buffer which maybe fragment, then fill into temporary address 8 byte + // 931130.5.e + if (MICAdd) + Mds_MicFill( Adapter, pTxDes, XmitBufAddress ); + + //Shift to the next address + XmitBufSize += CurrentSize; + XmitBufAddress += CurrentSize; + +#ifdef _IBSS_BEACON_SEQ_STICK_ + if ((XmitBufAddress[ DOT_11_DA_OFFSET+8 ] & 0xfc) != MAC_SUBTYPE_MNGMNT_PROBE_REQUEST) // +8 for USB hdr +#endif + pMds->TxToggle = TRUE; + + // Get packet to transmit completed, 1:TESTSTA 2:MLME 3: Ndis data + MLME_SendComplete(Adapter, 0, TRUE); + + // Software TSC count 20060214 + pMds->TxTsc++; + if (pMds->TxTsc == 0) + pMds->TxTsc_2++; + + FillCount++; // 20060928 + } while (HAL_USB_MODE_BURST(pHwData)); // End of multiple MSDU copy loop. FALSE = single TRUE = multiple sending + + // Move to the next one, if necessary + if (BufferFilled) { + // size setting + pMds->TxBufferSize[ FillIndex ] = XmitBufSize; + + // 20060928 set Tx count + pMds->TxCountInBuffer[FillIndex] = FillCount; + + // Set owner flag + pMds->TxOwner[FillIndex] = 1; + + pMds->TxFillIndex++; + pMds->TxFillIndex %= MAX_USB_TX_BUFFER_NUMBER; + BufferFilled = FALSE; + } else + break; + + if (!PacketSize) // No more pk for transmitting + break; + + } while(TRUE); + + // + // Start to send by lower module + // + if (!pHwData->IsKeyPreSet) + Wb35Tx_start(pHwData); + + cleanup: + OS_ATOMIC_DEC( Adapter, &pMds->TxThreadCount ); +} + +void +Mds_SendComplete(PADAPTER Adapter, PT02_DESCRIPTOR pT02) +{ + PMDS pMds = &Adapter->Mds; + phw_data_t pHwData = &Adapter->sHwData; + u8 PacketId = (u8)pT02->T02_Tx_PktID; + unsigned char SendOK = TRUE; + u8 RetryCount, TxRate; + + if (pT02->T02_IgnoreResult) // Don't care the result + return; + if (pT02->T02_IsLastMpdu) { + //TODO: DTO -- get the retry count and fragment count + // Tx rate + TxRate = pMds->TxRate[ PacketId ][ 0 ]; + RetryCount = (u8)pT02->T02_MPDU_Cnt; + if (pT02->value & FLAG_ERROR_TX_MASK) { + SendOK = FALSE; + + if (pT02->T02_transmit_abort || pT02->T02_out_of_MaxTxMSDULiftTime) { + //retry error + pHwData->dto_tx_retry_count += (RetryCount+1); + //[for tx debug] + if (RetryCount<7) + pHwData->tx_retry_count[RetryCount] += RetryCount; + else + pHwData->tx_retry_count[7] += RetryCount; + #ifdef _PE_STATE_DUMP_ + WBDEBUG(("dto_tx_retry_count =%d\n", pHwData->dto_tx_retry_count)); + #endif + MTO_SetTxCount(Adapter, TxRate, RetryCount); + } + pHwData->dto_tx_frag_count += (RetryCount+1); + + //[for tx debug] + if (pT02->T02_transmit_abort_due_to_TBTT) + pHwData->tx_TBTT_start_count++; + if (pT02->T02_transmit_without_encryption_due_to_wep_on_false) + pHwData->tx_WepOn_false_count++; + if (pT02->T02_discard_due_to_null_wep_key) + pHwData->tx_Null_key_count++; + } else { + if (pT02->T02_effective_transmission_rate) + pHwData->tx_ETR_count++; + MTO_SetTxCount(Adapter, TxRate, RetryCount); + } + + // Clear send result buffer + pMds->TxResult[ PacketId ] = 0; + } else + pMds->TxResult[ PacketId ] |= ((u16)(pT02->value & 0x0ffff)); +} + +void +Mds_HeaderCopy(PADAPTER Adapter, PDESCRIPTOR pDes, PUCHAR TargetBuffer) +{ + PMDS pMds = &Adapter->Mds; + PUCHAR src_buffer = pDes->buffer_address[0];//931130.5.g + PT00_DESCRIPTOR pT00; + PT01_DESCRIPTOR pT01; + u16 stmp; + u8 i, ctmp1, ctmp2, ctmpf; + u16 FragmentThreshold = CURRENT_FRAGMENT_THRESHOLD; + + + stmp = pDes->buffer_total_size; + // + // Set USB header 8 byte + // + pT00 = (PT00_DESCRIPTOR)TargetBuffer; + TargetBuffer += 4; + pT01 = (PT01_DESCRIPTOR)TargetBuffer; + TargetBuffer += 4; + + pT00->value = 0;// Clear + pT01->value = 0;// Clear + + pT00->T00_tx_packet_id = pDes->Descriptor_ID;// Set packet ID + pT00->T00_header_length = 24;// Set header length + pT01->T01_retry_abort_ebable = 1;//921013 931130.5.h + + // Key ID setup + pT01->T01_wep_id = 0; + + FragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD; //Do not fragment + // Copy full data, the 1'st buffer contain all the data 931130.5.j + memcpy( TargetBuffer, src_buffer, DOT_11_MAC_HEADER_SIZE );// Copy header + pDes->buffer_address[0] = src_buffer + DOT_11_MAC_HEADER_SIZE; + pDes->buffer_total_size -= DOT_11_MAC_HEADER_SIZE; + pDes->buffer_size[0] = pDes->buffer_total_size; + + // Set fragment threshold + FragmentThreshold -= (DOT_11_MAC_HEADER_SIZE + 4); + pDes->FragmentThreshold = FragmentThreshold; + + // Set more frag bit + TargetBuffer[1] |= 0x04;// Set more frag bit + + // + // Set tx rate + // + stmp = *(PUSHORT)(TargetBuffer+30); // 2n alignment address + + //Use basic rate + ctmp1 = ctmpf = CURRENT_TX_RATE_FOR_MNG; + + pDes->TxRate = ctmp1; + #ifdef _PE_TX_DUMP_ + WBDEBUG(("Tx rate =%x\n", ctmp1)); + #endif + + pT01->T01_modulation_type = (ctmp1%3) ? 0 : 1; + + for( i=0; i<2; i++ ) { + if( i == 1 ) + ctmp1 = ctmpf; + + pMds->TxRate[pDes->Descriptor_ID][i] = ctmp1; // backup the ta rate and fall back rate + + if( ctmp1 == 108) ctmp2 = 7; + else if( ctmp1 == 96 ) ctmp2 = 6; // Rate convert for USB + else if( ctmp1 == 72 ) ctmp2 = 5; + else if( ctmp1 == 48 ) ctmp2 = 4; + else if( ctmp1 == 36 ) ctmp2 = 3; + else if( ctmp1 == 24 ) ctmp2 = 2; + else if( ctmp1 == 18 ) ctmp2 = 1; + else if( ctmp1 == 12 ) ctmp2 = 0; + else if( ctmp1 == 22 ) ctmp2 = 3; + else if( ctmp1 == 11 ) ctmp2 = 2; + else if( ctmp1 == 4 ) ctmp2 = 1; + else ctmp2 = 0; // if( ctmp1 == 2 ) or default + + if( i == 0 ) + pT01->T01_transmit_rate = ctmp2; + else + pT01->T01_fall_back_rate = ctmp2; + } + + // + // Set preamble type + // + if ((pT01->T01_modulation_type == 0) && (pT01->T01_transmit_rate == 0)) // RATE_1M + pDes->PreambleMode = WLAN_PREAMBLE_TYPE_LONG; + else + pDes->PreambleMode = CURRENT_PREAMBLE_MODE; + pT01->T01_plcp_header_length = pDes->PreambleMode; // Set preamble + +} + +// The function return the 4n size of usb pk +u16 +Mds_BodyCopy(PADAPTER Adapter, PDESCRIPTOR pDes, PUCHAR TargetBuffer) +{ + PT00_DESCRIPTOR pT00; + PMDS pMds = &Adapter->Mds; + PUCHAR buffer, src_buffer, pctmp; + u16 Size = 0; + u16 SizeLeft, CopySize, CopyLeft, stmp; + u8 buf_index, FragmentCount = 0; + + + // Copy fragment body + buffer = TargetBuffer; // shift 8B usb + 24B 802.11 + SizeLeft = pDes->buffer_total_size; + buf_index = pDes->buffer_start_index; + + pT00 = (PT00_DESCRIPTOR)buffer; + while (SizeLeft) { + pT00 = (PT00_DESCRIPTOR)buffer; + CopySize = SizeLeft; + if (SizeLeft > pDes->FragmentThreshold) { + CopySize = pDes->FragmentThreshold; + pT00->T00_frame_length = 24 + CopySize;//Set USB length + } else + pT00->T00_frame_length = 24 + SizeLeft;//Set USB length + + SizeLeft -= CopySize; + + // 1 Byte operation + pctmp = (PUCHAR)( buffer + 8 + DOT_11_SEQUENCE_OFFSET ); + *pctmp &= 0xf0; + *pctmp |= FragmentCount;//931130.5.m + if( !FragmentCount ) + pT00->T00_first_mpdu = 1; + + buffer += 32; // 8B usb + 24B 802.11 header + Size += 32; + + // Copy into buffer + stmp = CopySize + 3; + stmp &= ~0x03;//4n Alignment + Size += stmp;// Current 4n offset of mpdu + + while (CopySize) { + // Copy body + src_buffer = pDes->buffer_address[buf_index]; + CopyLeft = CopySize; + if (CopySize >= pDes->buffer_size[buf_index]) { + CopyLeft = pDes->buffer_size[buf_index]; + + // Get the next buffer of descriptor + buf_index++; + buf_index %= MAX_DESCRIPTOR_BUFFER_INDEX; + } else { + PUCHAR pctmp = pDes->buffer_address[buf_index]; + pctmp += CopySize; + pDes->buffer_address[buf_index] = pctmp; + pDes->buffer_size[buf_index] -= CopySize; + } + + memcpy(buffer, src_buffer, CopyLeft); + buffer += CopyLeft; + CopySize -= CopyLeft; + } + + // 931130.5.n + if (pMds->MicAdd) { + if (!SizeLeft) { + pMds->MicWriteAddress[ pMds->MicWriteIndex ] = buffer - pMds->MicAdd; + pMds->MicWriteSize[ pMds->MicWriteIndex ] = pMds->MicAdd; + pMds->MicAdd = 0; + } + else if( SizeLeft < 8 ) //931130.5.p + { + pMds->MicAdd = SizeLeft; + pMds->MicWriteAddress[ pMds->MicWriteIndex ] = buffer - ( 8 - SizeLeft ); + pMds->MicWriteSize[ pMds->MicWriteIndex ] = 8 - SizeLeft; + pMds->MicWriteIndex++; + } + } + + // Does it need to generate the new header for next mpdu? + if (SizeLeft) { + buffer = TargetBuffer + Size; // Get the next 4n start address + memcpy( buffer, TargetBuffer, 32 );//Copy 8B USB +24B 802.11 + pT00 = (PT00_DESCRIPTOR)buffer; + pT00->T00_first_mpdu = 0; + } + + FragmentCount++; + } + + pT00->T00_last_mpdu = 1; + pT00->T00_IsLastMpdu = 1; + buffer = (PUCHAR)pT00 + 8; // +8 for USB hdr + buffer[1] &= ~0x04; // Clear more frag bit of 802.11 frame control + pDes->FragmentCount = FragmentCount; // Update the correct fragment number + return Size; +} + + +void +Mds_DurationSet( PADAPTER Adapter, PDESCRIPTOR pDes, PUCHAR buffer ) +{ + PT00_DESCRIPTOR pT00; + PT01_DESCRIPTOR pT01; + u16 Duration, NextBodyLen, OffsetSize; + u8 Rate, i; + unsigned char CTS_on = FALSE, RTS_on = FALSE; + PT00_DESCRIPTOR pNextT00; + u16 BodyLen; + unsigned char boGroupAddr = FALSE; + + + OffsetSize = pDes->FragmentThreshold + 32 + 3; + OffsetSize &= ~0x03; + Rate = pDes->TxRate >> 1; + if (!Rate) + Rate = 1; + + pT00 = (PT00_DESCRIPTOR)buffer; + pT01 = (PT01_DESCRIPTOR)(buffer+4); + pNextT00 = (PT00_DESCRIPTOR)(buffer+OffsetSize); + + if( buffer[ DOT_11_DA_OFFSET+8 ] & 0x1 ) // +8 for USB hdr + boGroupAddr = TRUE; + + //======================================== + // Set RTS/CTS mechanism + //======================================== + if (!boGroupAddr) + { + //NOTE : If the protection mode is enabled and the MSDU will be fragmented, + // the tx rates of MPDUs will all be DSSS rates. So it will not use + // CTS-to-self in this case. CTS-To-self will only be used when without + // fragmentation. -- 20050112 + BodyLen = (u16)pT00->T00_frame_length; //include 802.11 header + BodyLen += 4; //CRC + + if( BodyLen >= CURRENT_RTS_THRESHOLD ) + RTS_on = TRUE; // Using RTS + else + { + if( pT01->T01_modulation_type ) // Is using OFDM + { + if( CURRENT_PROTECT_MECHANISM ) // Is using protect + CTS_on = TRUE; // Using CTS + } + } + } + + if( RTS_on || CTS_on ) + { + if( pT01->T01_modulation_type) // Is using OFDM + { + //CTS duration + // 2 SIFS + DATA transmit time + 1 ACK + // ACK Rate : 24 Mega bps + // ACK frame length = 14 bytes + Duration = 2*DEFAULT_SIFSTIME + + 2*PREAMBLE_PLUS_SIGNAL_PLUS_SIGNALEXTENSION + + ((BodyLen*8 + 22 + Rate*4 - 1)/(Rate*4))*Tsym + + ((112 + 22 + 95)/96)*Tsym; + } + else //DSSS + { + //CTS duration + // 2 SIFS + DATA transmit time + 1 ACK + // Rate : ?? Mega bps + // ACK frame length = 14 bytes + if( pT01->T01_plcp_header_length ) //long preamble + Duration = LONG_PREAMBLE_PLUS_PLCPHEADER_TIME*2; + else + Duration = SHORT_PREAMBLE_PLUS_PLCPHEADER_TIME*2; + + Duration += ( ((BodyLen + 14)*8 + Rate-1) / Rate + + DEFAULT_SIFSTIME*2 ); + } + + if( RTS_on ) + { + if( pT01->T01_modulation_type ) // Is using OFDM + { + //CTS + 1 SIFS + CTS duration + //CTS Rate : 24 Mega bps + //CTS frame length = 14 bytes + Duration += (DEFAULT_SIFSTIME + + PREAMBLE_PLUS_SIGNAL_PLUS_SIGNALEXTENSION + + ((112 + 22 + 95)/96)*Tsym); + } + else + { + //CTS + 1 SIFS + CTS duration + //CTS Rate : ?? Mega bps + //CTS frame length = 14 bytes + if( pT01->T01_plcp_header_length ) //long preamble + Duration += LONG_PREAMBLE_PLUS_PLCPHEADER_TIME; + else + Duration += SHORT_PREAMBLE_PLUS_PLCPHEADER_TIME; + + Duration += ( ((112 + Rate-1) / Rate) + DEFAULT_SIFSTIME ); + } + } + + // Set the value into USB descriptor + pT01->T01_add_rts = RTS_on ? 1 : 0; + pT01->T01_add_cts = CTS_on ? 1 : 0; + pT01->T01_rts_cts_duration = Duration; + } + + //===================================== + // Fill the more fragment descriptor + //===================================== + if( boGroupAddr ) + Duration = 0; + else + { + for( i=pDes->FragmentCount-1; i>0; i-- ) + { + NextBodyLen = (u16)pNextT00->T00_frame_length; + NextBodyLen += 4; //CRC + + if( pT01->T01_modulation_type ) + { + //OFDM + // data transmit time + 3 SIFS + 2 ACK + // Rate : ??Mega bps + // ACK frame length = 14 bytes, tx rate = 24M + Duration = PREAMBLE_PLUS_SIGNAL_PLUS_SIGNALEXTENSION * 3; + Duration += (((NextBodyLen*8 + 22 + Rate*4 - 1)/(Rate*4)) * Tsym + + (((2*14)*8 + 22 + 95)/96)*Tsym + + DEFAULT_SIFSTIME*3); + } + else + { + //DSSS + // data transmit time + 2 ACK + 3 SIFS + // Rate : ??Mega bps + // ACK frame length = 14 bytes + //TODO : + if( pT01->T01_plcp_header_length ) //long preamble + Duration = LONG_PREAMBLE_PLUS_PLCPHEADER_TIME*3; + else + Duration = SHORT_PREAMBLE_PLUS_PLCPHEADER_TIME*3; + + Duration += ( ((NextBodyLen + (2*14))*8 + Rate-1) / Rate + + DEFAULT_SIFSTIME*3 ); + } + + ((PUSHORT)buffer)[5] = cpu_to_le16(Duration);// 4 USHOR for skip 8B USB, 2USHORT=FC + Duration + + //----20061009 add by anson's endian + pNextT00->value = cpu_to_le32(pNextT00->value); + pT01->value = cpu_to_le32( pT01->value ); + //----end 20061009 add by anson's endian + + buffer += OffsetSize; + pT01 = (PT01_DESCRIPTOR)(buffer+4); + if (i != 1) //The last fragment will not have the next fragment + pNextT00 = (PT00_DESCRIPTOR)(buffer+OffsetSize); + } + + //===================================== + // Fill the last fragment descriptor + //===================================== + if( pT01->T01_modulation_type ) + { + //OFDM + // 1 SIFS + 1 ACK + // Rate : 24 Mega bps + // ACK frame length = 14 bytes + Duration = PREAMBLE_PLUS_SIGNAL_PLUS_SIGNALEXTENSION; + //The Tx rate of ACK use 24M + Duration += (((112 + 22 + 95)/96)*Tsym + DEFAULT_SIFSTIME ); + } + else + { + // DSSS + // 1 ACK + 1 SIFS + // Rate : ?? Mega bps + // ACK frame length = 14 bytes(112 bits) + if( pT01->T01_plcp_header_length ) //long preamble + Duration = LONG_PREAMBLE_PLUS_PLCPHEADER_TIME; + else + Duration = SHORT_PREAMBLE_PLUS_PLCPHEADER_TIME; + + Duration += ( (112 + Rate-1)/Rate + DEFAULT_SIFSTIME ); + } + } + + ((PUSHORT)buffer)[5] = cpu_to_le16(Duration);// 4 USHOR for skip 8B USB, 2USHORT=FC + Duration + pT00->value = cpu_to_le32(pT00->value); + pT01->value = cpu_to_le32(pT01->value); + //--end 20061009 add + +} + +void MDS_EthernetPacketReceive( PADAPTER Adapter, PRXLAYER1 pRxLayer1 ) +{ + OS_RECEIVE_PACKET_INDICATE( Adapter, pRxLayer1 ); +} + + diff --git a/drivers/staging/winbond/mds_f.h b/drivers/staging/winbond/mds_f.h new file mode 100644 index 000000000000..651188be1065 --- /dev/null +++ b/drivers/staging/winbond/mds_f.h @@ -0,0 +1,33 @@ +unsigned char Mds_initial( PADAPTER Adapter ); +void Mds_Destroy( PADAPTER Adapter ); +void Mds_Tx( PADAPTER Adapter ); +void Mds_HeaderCopy( PADAPTER Adapter, PDESCRIPTOR pDes, PUCHAR TargetBuffer ); +u16 Mds_BodyCopy( PADAPTER Adapter, PDESCRIPTOR pDes, PUCHAR TargetBuffer ); +void Mds_DurationSet( PADAPTER Adapter, PDESCRIPTOR pDes, PUCHAR TargetBuffer ); +void Mds_SendComplete( PADAPTER Adapter, PT02_DESCRIPTOR pT02 ); +void Mds_MpduProcess( PADAPTER Adapter, PDESCRIPTOR pRxDes ); +void Mds_reset_descriptor( PADAPTER Adapter ); +extern void DataDmp(u8 *pdata, u32 len, u32 offset); + + +void vRxTimerInit(PWB32_ADAPTER Adapter); +void vRxTimerStart(PWB32_ADAPTER Adapter, int timeout_value); +void RxTimerHandler_1a( PADAPTER Adapter); +void vRxTimerStop(PWB32_ADAPTER Adapter); +void RxTimerHandler( void* SystemSpecific1, + PWB32_ADAPTER Adapter, + void* SystemSpecific2, + void* SystemSpecific3); + + +// For Asynchronous indicating. The routine collocates with USB. +void Mds_MsduProcess( PWB32_ADAPTER Adapter, PRXLAYER1 pRxLayer1, u8 SlotIndex); + +// For data frame sending 20060802 +u16 MDS_GetPacketSize( PADAPTER Adapter ); +void MDS_GetNextPacket( PADAPTER Adapter, PDESCRIPTOR pDes ); +void MDS_GetNextPacketComplete( PADAPTER Adapter, PDESCRIPTOR pDes ); +void MDS_SendResult( PADAPTER Adapter, u8 PacketId, unsigned char SendOK ); +void MDS_EthernetPacketReceive( PADAPTER Adapter, PRXLAYER1 pRxLayer1 ); + + diff --git a/drivers/staging/winbond/mds_s.h b/drivers/staging/winbond/mds_s.h new file mode 100644 index 000000000000..4738279d5f39 --- /dev/null +++ b/drivers/staging/winbond/mds_s.h @@ -0,0 +1,183 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////////// +#define MAX_USB_TX_DESCRIPTOR 15 // IS89C35 ability +#define MAX_USB_TX_BUFFER_NUMBER 4 // Virtual pre-buffer number of MAX_USB_TX_BUFFER +#define MAX_USB_TX_BUFFER 4096 // IS89C35 ability 4n alignment is required for hardware + +#define MDS_EVENT_INDICATE( _A, _B, _F ) OS_EVENT_INDICATE( _A, _B, _F ) +#define AUTH_REQUEST_PAIRWISE_ERROR 0 // _F flag setting +#define AUTH_REQUEST_GROUP_ERROR 1 // _F flag setting + +// For variable setting +#define CURRENT_BSS_TYPE psBSS(psLOCAL->wConnectedSTAindex)->bBssType +#define CURRENT_WEP_MODE psSME->_dot11PrivacyInvoked +#define CURRENT_BSSID psBSS(psLOCAL->wConnectedSTAindex)->abBssID +#define CURRENT_DESIRED_WPA_ENABLE ((psSME->bDesiredAuthMode==WPA_AUTH)||(psSME->bDesiredAuthMode==WPAPSK_AUTH)) +#ifdef _WPA2_ +#define CURRENT_DESIRED_WPA2_ENABLE ((psSME->bDesiredAuthMode==WPA2_AUTH)||(psSME->bDesiredAuthMode==WPA2PSK_AUTH)) +#endif //end def _WPA2_ +#define CURRENT_PAIRWISE_KEY_OK psSME->pairwise_key_ok +//[20040712 WS] +#define CURRENT_GROUP_KEY_OK psSME->group_key_ok +#define CURRENT_PAIRWISE_KEY psSME->tx_mic_key +#define CURRENT_GROUP_KEY psSME->group_tx_mic_key +#define CURRENT_ENCRYPT_STATUS psSME->encrypt_status +#define CURRENT_WEP_ID Adapter->sSmePara._dot11WEPDefaultKeyID +#define CURRENT_CONTROL_PORT_BLOCK ( psSME->wpa_ok!=1 || (Adapter->Mds.boCounterMeasureBlock==1 && (CURRENT_ENCRYPT_STATUS==ENCRYPT_TKIP)) ) +#define CURRENT_FRAGMENT_THRESHOLD (Adapter->Mds.TxFragmentThreshold & ~0x1) +#define CURRENT_PREAMBLE_MODE psLOCAL->boShortPreamble?WLAN_PREAMBLE_TYPE_SHORT:WLAN_PREAMBLE_TYPE_LONG +#define CURRENT_LINK_ON OS_LINK_STATUS +#define CURRENT_TX_RATE Adapter->sLocalPara.CurrentTxRate +#define CURRENT_FALL_BACK_TX_RATE Adapter->sLocalPara.CurrentTxFallbackRate +#define CURRENT_TX_RATE_FOR_MNG Adapter->sLocalPara.CurrentTxRateForMng +#define CURRENT_PROTECT_MECHANISM psLOCAL->boProtectMechanism +#define CURRENT_RTS_THRESHOLD Adapter->Mds.TxRTSThreshold + +#define MIB_GS_XMIT_OK_INC Adapter->sLocalPara.GS_XMIT_OK++ +#define MIB_GS_RCV_OK_INC Adapter->sLocalPara.GS_RCV_OK++ +#define MIB_GS_XMIT_ERROR_INC Adapter->sLocalPara.GS_XMIT_ERROR + +//---------- TX ----------------------------------- +#define ETHERNET_TX_DESCRIPTORS MAX_USB_TX_BUFFER_NUMBER + +//---------- RX ------------------------------------ +#define ETHERNET_RX_DESCRIPTORS 8 //It's not necessary to allocate more than 2 in sync indicate + +//================================================================ +// Configration default value +//================================================================ +#define DEFAULT_MULTICASTLISTMAX 32 // standard +#define DEFAULT_TX_BURSTLENGTH 3 // 32 Longwords +#define DEFAULT_RX_BURSTLENGTH 3 // 32 Longwords +#define DEFAULT_TX_THRESHOLD 0 // Full Packet +#define DEFAULT_RX_THRESHOLD 0 // Full Packet +#define DEFAULT_MAXTXRATE 6 // 11 Mbps (Long) +#define DEFAULT_CHANNEL 3 // Chennel 3 +#define DEFAULT_RTSThreshold 2347 // Disable RTS +//#define DEFAULT_PME 1 // Enable +#define DEFAULT_PME 0 // Disable +#define DEFAULT_SIFSTIME 10 +#define DEFAULT_ACKTIME_1ML 304 // 148+44+112 911220 by LCC +#define DEFAULT_ACKTIME_2ML 248 // 148+44+56 911220 by LCC +#define DEFAULT_FRAGMENT_THRESHOLD 2346 // No fragment +#define DEFAULT_PREAMBLE_LENGTH 72 +#define DEFAULT_PLCPHEADERTIME_LENGTH 24 + +/*------------------------------------------------------------------------ + 0.96 sec since time unit of the R03 for the current, W89C32 is about 60ns + instead of 960 ns. This shall be fixed in the future W89C32 + -------------------------------------------------------------------------*/ +#define DEFAULT_MAX_RECEIVE_TIME 16440000 + +#define RX_BUF_SIZE 2352 // 600 // For 301 must be multiple of 8 +#define MAX_RX_DESCRIPTORS 18 // Rx Layer 2 +#define MAX_BUFFER_QUEUE 8 // The value is always equal 8 due to NDIS_PACKET's MiniportReserved field size + + +// For brand-new rx system +#define MDS_ID_IGNORE ETHERNET_RX_DESCRIPTORS + +// For Tx Packet status classify +#define PACKET_FREE_TO_USE 0 +#define PACKET_COME_FROM_NDIS 0x08 +#define PACKET_COME_FROM_MLME 0x80 +#define PACKET_SEND_COMPLETE 0xff + +typedef struct _MDS +{ + // For Tx usage + u8 TxOwner[ ((MAX_USB_TX_BUFFER_NUMBER + 3) & ~0x03) ]; + PUCHAR pTxBuffer; + u16 TxBufferSize[ ((MAX_USB_TX_BUFFER_NUMBER + 1) & ~0x01) ]; + u8 TxDesFrom[ ((MAX_USB_TX_DESCRIPTOR + 3) & ~0x03) ];//931130.4.u // 1: MLME 2: NDIS control 3: NDIS data + u8 TxCountInBuffer[ ((MAX_USB_TX_DESCRIPTOR + 3) & ~0x03) ]; // 20060928 + + u8 TxFillIndex;//the next index of TxBuffer can be used + u8 TxDesIndex;//The next index of TxDes can be used + u8 ScanTxPause; //data Tx pause because the scanning is progressing, but probe request Tx won't. + u8 TxPause;//For pause the Mds_Tx modult + + OS_ATOMIC TxThreadCount;//For thread counting 931130.4.v +//950301 delete due to HW +// OS_ATOMIC TxConcurrentCount;//931130.4.w + + u16 TxResult[ ((MAX_USB_TX_DESCRIPTOR + 1) & ~0x01) ];//Collect the sending result of Mpdu + + u8 MicRedundant[8]; // For tmp use + PUCHAR MicWriteAddress[2]; //The start address to fill the Mic, use 2 point due to Mic maybe fragment + + u16 MicWriteSize[2]; //931130.4.x + + u16 MicAdd; // If want to add the Mic, this variable equal to 8 + u16 MicWriteIndex;//The number of MicWriteAddress 931130.4.y + + u8 TxRate[ ((MAX_USB_TX_DESCRIPTOR+1)&~0x01) ][2]; // [0] current tx rate, [1] fall back rate + u8 TxInfo[ ((MAX_USB_TX_DESCRIPTOR+1)&~0x01) ]; //Store information for callback function + + //WKCHEN added for scanning mechanism + u8 TxToggle; //It is TRUE if there are tx activities in some time interval + u8 Reserved_[3]; + + //---------- for Tx Parameter + u16 TxFragmentThreshold; // For frame body only + u16 TxRTSThreshold; + + u32 MaxReceiveTime;//911220.3 Add + + // depend on OS, + u32 MulticastListNo; + u32 PacketFilter; // Setting by NDIS, the current packet filter in use. + u8 MulticastAddressesArray[DEFAULT_MULTICASTLISTMAX][MAC_ADDR_LENGTH]; + + //COUNTERMEASURE + u8 bMICfailCount; + u8 boCounterMeasureBlock; + u8 reserved_4[2]; + + //NDIS_MINIPORT_TIMER nTimer; + OS_TIMER nTimer; + + u32 TxTsc; // 20060214 + u32 TxTsc_2; // 20060214 + +} MDS, *PMDS; + + +typedef struct _RxBuffer +{ + PUCHAR pBufferAddress; // Pointer the received data buffer. + u16 BufferSize; + u8 RESERVED; + u8 BufferIndex;// Only 1 byte +} RXBUFFER, *PRXBUFFER; + +// +// Reveive Layer 1 Format. +//---------------------------- +typedef struct _RXLAYER1 +{ + u16 SequenceNumber; // The sequence number of the last received packet. + u16 BufferTotalSize; + + u32 InUsed; + u32 DecryptionMethod; // The desired defragment number of the next incoming packet. + + u8 DeFragmentNumber; + u8 FrameType; + u8 TypeEncapsulated; + u8 BufferNumber; + + u32 FirstFrameArrivedTime; + + RXBUFFER BufferQueue[ MAX_BUFFER_QUEUE ]; + + u8 LastFrameType; // 20061004 for fix intel 3945 's bug + u8 RESERVED[3]; //@@ anson + + ///////////////////////////////////////////////////////////////////////////////////////////// + // For brand-new Rx system + u8 ReservedBuffer[ 2400 ];//If Buffer ID is reserved one, it must copy the data into this area + PUCHAR ReservedBufferPoint;// Point to the next availabe address of reserved buffer + +}RXLAYER1, * PRXLAYER1; + + diff --git a/drivers/staging/winbond/mlme_mib.h b/drivers/staging/winbond/mlme_mib.h new file mode 100644 index 000000000000..89759739cbac --- /dev/null +++ b/drivers/staging/winbond/mlme_mib.h @@ -0,0 +1,84 @@ +//============================================================================ +// MLMEMIB.H - +// +// Description: +// Get and Set some of MLME MIB attributes. +// +// Revision history: +// -------------------------------------------------------------------------- +// 20030117 PD43 Austin Liu +// Initial release +// +// Copyright (c) 2003 Winbond Electronics Corp. All rights reserved. +//============================================================================ + +#ifndef _MLME_MIB_H +#define _MLME_MIB_H + +//============================================================================ +// MLMESetExcludeUnencrypted -- +// +// Description: +// Set the dot11ExcludeUnencrypted value. +// +// Arguments: +// Adapter - The pointer to the miniport adapter context. +// ExUnencrypted - unsigned char type. The value to be set. +// +// Return values: +// None. +//============================================================================ +#define MLMESetExcludeUnencrypted(Adapter, ExUnencrypted) \ +{ \ + (Adapter)->sLocalPara.ExcludeUnencrypted = ExUnencrypted; \ +} + +//============================================================================ +// MLMEGetExcludeUnencrypted -- +// +// Description: +// Get the dot11ExcludeUnencrypted value. +// +// Arguments: +// Adapter - The pointer to the miniport adapter context. +// +// Return values: +// unsigned char type. The current dot11ExcludeUnencrypted value. +//============================================================================ +#define MLMEGetExcludeUnencrypted(Adapter) ((unsigned char) (Adapter)->sLocalPara.ExcludeUnencrypted) + +//============================================================================ +// MLMESetMaxReceiveLifeTime -- +// +// Description: +// Set the dot11MaxReceiveLifeTime value. +// +// Arguments: +// Adapter - The pointer to the miniport adapter context. +// ReceiveLifeTime- u32 type. The value to be set. +// +// Return values: +// None. +//============================================================================ +#define MLMESetMaxReceiveLifeTime(Adapter, ReceiveLifeTime) \ +{ \ + (Adapter)->Mds.MaxReceiveTime = ReceiveLifeTime; \ +} + +//============================================================================ +// MLMESetMaxReceiveLifeTime -- +// +// Description: +// Get the dot11MaxReceiveLifeTime value. +// +// Arguments: +// Adapter - The pointer to the miniport adapter context. +// +// Return values: +// u32 type. The current dot11MaxReceiveLifeTime value. +//============================================================================ +#define MLMEGetMaxReceiveLifeTime(Adapter) ((u32) (Adapter)->Mds.MaxReceiveTime) + +#endif + + diff --git a/drivers/staging/winbond/mlme_s.h b/drivers/staging/winbond/mlme_s.h new file mode 100644 index 000000000000..58094f61c032 --- /dev/null +++ b/drivers/staging/winbond/mlme_s.h @@ -0,0 +1,195 @@ +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// Mlme.h +// Define the related definitions of MLME module +// history -- 01/14/03' created +// +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +#define AUTH_REJECT_REASON_CHALLENGE_FAIL 1 + +//====== the state of MLME module +#define INACTIVE 0x0 +#define IDLE_SCAN 0x1 + +//====== the state of MLME/ESS module +#define STATE_1 0x2 +#define AUTH_REQ 0x3 +#define AUTH_WEP 0x4 +#define STATE_2 0x5 +#define ASSOC_REQ 0x6 +#define STATE_3 0x7 + +//====== the state of MLME/IBSS module +#define IBSS_JOIN_SYNC 0x8 +#define IBSS_AUTH_REQ 0x9 +#define IBSS_AUTH_CHANLGE 0xa +#define IBSS_AUTH_WEP 0xb +#define IBSS_AUTH_IND 0xc +#define IBSS_STATE_2 0xd + + + +//========================================= +//depend on D5C(MAC timing control 03 register): MaxTxMSDULifeTime default 0x80000us +#define AUTH_FAIL_TIMEOUT 550 +#define ASSOC_FAIL_TIMEOUT 550 +#define REASSOC_FAIL_TIMEOUT 550 + + + +// +// MLME task global CONSTANTS, STRUCTURE, variables +// + + +///////////////////////////////////////////////////////////// +// enum_ResultCode -- +// Result code returned from MLME to SME. +// +///////////////////////////////////////////////////////////// +// PD43 20030829 Modifiled +//#define SUCCESS 0 +#define MLME_SUCCESS 0 //follow spec. +#define INVALID_PARAMETERS 1 //Not following spec. +#define NOT_SUPPPORTED 2 +#define TIMEOUT 3 +#define TOO_MANY_SIMULTANEOUS_REQUESTS 4 +#define REFUSED 5 +#define BSS_ALREADY_STARTED_OR_JOINED 6 +#define TRANSMIT_FRAME_FAIL 7 +#define NO_BSS_FOUND 8 +#define RETRY 9 +#define GIVE_UP 10 + + +#define OPEN_AUTH 0 +#define SHARE_AUTH 1 +#define ANY_AUTH 2 +#define WPA_AUTH 3 //for WPA +#define WPAPSK_AUTH 4 +#define WPANONE_AUTH 5 +///////////////////////////////////////////// added by ws 04/19/04 +#ifdef _WPA2_ +#define WPA2_AUTH 6//for WPA2 +#define WPA2PSK_AUTH 7 +#endif //end def _WPA2_ + +////////////////////////////////////////////////////////////////// +//define the msg type of MLME module +////////////////////////////////////////////////////////////////// +//-------------------------------------------------------- +//from SME + +#define MLMEMSG_AUTH_REQ 0x0b +#define MLMEMSG_DEAUTH_REQ 0x0c +#define MLMEMSG_ASSOC_REQ 0x0d +#define MLMEMSG_REASSOC_REQ 0x0e +#define MLMEMSG_DISASSOC_REQ 0x0f +#define MLMEMSG_START_IBSS_REQ 0x10 +#define MLMEMSG_IBSS_NET_CFM 0x11 + +//from RX : +#define MLMEMSG_RCV_MLMEFRAME 0x20 +#define MLMEMSG_RCV_ASSOCRSP 0x22 +#define MLMEMSG_RCV_REASSOCRSP 0x24 +#define MLMEMSG_RCV_DISASSOC 0x2b +#define MLMEMSG_RCV_AUTH 0x2c +#define MLMEMSG_RCV_DEAUTH 0x2d + + +//from TX callback +#define MLMEMSG_TX_CALLBACK 0x40 +#define MLMEMSG_ASSOCREQ_CALLBACK 0x41 +#define MLMEMSG_REASSOCREQ_CALLBACK 0x43 +#define MLMEMSG_DISASSOC_CALLBACK 0x4a +#define MLMEMSG_AUTH_CALLBACK 0x4c +#define MLMEMSG_DEAUTH_CALLBACK 0x4d + +//#define MLMEMSG_JOIN_FAIL 4 +//#define MLMEMSG_AUTHEN_FAIL 18 +#define MLMEMSG_TIMEOUT 0x50 + +/////////////////////////////////////////////////////////////////////////// +//Global data structures +#define MAX_NUM_TX_MMPDU 2 +#define MAX_MMPDU_SIZE 1512 +#define MAX_NUM_RX_MMPDU 6 + + +/////////////////////////////////////////////////////////////////////////// +//MACRO +#define boMLME_InactiveState(_AA_) (_AA_->wState==INACTIVE) +#define boMLME_IdleScanState(_BB_) (_BB_->wState==IDLE_SCAN) +#define boMLME_FoundSTAinfo(_CC_) (_CC_->wState>=IDLE_SCAN) + +typedef struct _MLME_FRAME +{ + //NDIS_PACKET MLME_Packet; + PCHAR pMMPDU; + u16 len; + u8 DataType; + u8 IsInUsed; + + OS_SPIN_LOCK MLMESpinLock; + + u8 TxMMPDU[MAX_NUM_TX_MMPDU][MAX_MMPDU_SIZE]; + u8 TxMMPDUInUse[ (MAX_NUM_TX_MMPDU+3) & ~0x03 ]; + + u16 wNumTxMMPDU; + u16 wNumTxMMPDUDiscarded; + + u8 RxMMPDU[MAX_NUM_RX_MMPDU][MAX_MMPDU_SIZE]; + u8 SaveRxBufSlotInUse[ (MAX_NUM_RX_MMPDU+3) & ~0x03 ]; + + u16 wNumRxMMPDU; + u16 wNumRxMMPDUDiscarded; + + u16 wNumRxMMPDUInMLME; // Number of the Rx MMPDU + u16 reserved_1; // in MLME. + // excluding the discarded +} MLME_FRAME, *psMLME_FRAME; + +typedef struct _AUTHREQ { + + u8 peerMACaddr[MAC_ADDR_LENGTH]; + u16 wAuthAlgorithm; + +} MLME_AUTHREQ_PARA, *psMLME_AUTHREQ_PARA; + +struct _Reason_Code { + + u8 peerMACaddr[MAC_ADDR_LENGTH]; + u16 wReasonCode; +}; +typedef struct _Reason_Code MLME_DEAUTHREQ_PARA, *psMLME_DEAUTHREQ_PARA; +typedef struct _Reason_Code MLME_DISASSOCREQ_PARA, *psMLME_DISASSOCREQ_PARA; + +typedef struct _ASSOCREQ { + u8 PeerSTAAddr[MAC_ADDR_LENGTH]; + u16 CapabilityInfo; + u16 ListenInterval; + +}__attribute__ ((packed)) MLME_ASSOCREQ_PARA, *psMLME_ASSOCREQ_PARA; + +typedef struct _REASSOCREQ { + u8 NewAPAddr[MAC_ADDR_LENGTH]; + u16 CapabilityInfo; + u16 ListenInterval; + +}__attribute__ ((packed)) MLME_REASSOCREQ_PARA, *psMLME_REASSOCREQ_PARA; + +typedef struct _MLMECALLBACK { + + u8 *psFramePtr; + u8 bResult; + +} MLME_TXCALLBACK, *psMLME_TXCALLBACK; + +typedef struct _RXDATA +{ + s32 FrameLength; + u8 __attribute__ ((packed)) *pbFramePtr; + +}__attribute__ ((packed)) RXDATA, *psRXDATA; + + diff --git a/drivers/staging/winbond/mlmetxrx.c b/drivers/staging/winbond/mlmetxrx.c new file mode 100644 index 000000000000..46b091e96794 --- /dev/null +++ b/drivers/staging/winbond/mlmetxrx.c @@ -0,0 +1,150 @@ +//============================================================================ +// Module Name: +// MLMETxRx.C +// +// Description: +// The interface between MDS (MAC Data Service) and MLME. +// +// Revision History: +// -------------------------------------------------------------------------- +// 200209 UN20 Jennifer Xu +// Initial Release +// 20021108 PD43 Austin Liu +// 20030117 PD43 Austin Liu +// Deleted MLMEReturnPacket and MLMEProcThread() +// +// Copyright (c) 1996-2002 Winbond Electronics Corp. All Rights Reserved. +//============================================================================ +#include "os_common.h" + +void MLMEResetTxRx(PWB32_ADAPTER Adapter) +{ + s32 i; + + // Reset the interface between MDS and MLME + for (i = 0; i < MAX_NUM_TX_MMPDU; i++) + Adapter->sMlmeFrame.TxMMPDUInUse[i] = FALSE; + for (i = 0; i < MAX_NUM_RX_MMPDU; i++) + Adapter->sMlmeFrame.SaveRxBufSlotInUse[i] = FALSE; + + Adapter->sMlmeFrame.wNumRxMMPDUInMLME = 0; + Adapter->sMlmeFrame.wNumRxMMPDUDiscarded = 0; + Adapter->sMlmeFrame.wNumRxMMPDU = 0; + Adapter->sMlmeFrame.wNumTxMMPDUDiscarded = 0; + Adapter->sMlmeFrame.wNumTxMMPDU = 0; + Adapter->sLocalPara.boCCAbusy = FALSE; + Adapter->sLocalPara.iPowerSaveMode = PWR_ACTIVE; // Power active +} + +//============================================================================= +// Function: +// MLMEGetMMPDUBuffer() +// +// Description: +// Return the pointer to an available data buffer with +// the size MAX_MMPDU_SIZE for a MMPDU. +// +// Arguments: +// Adapter - pointer to the miniport adapter context. +// +// Return value: +// NULL : No available data buffer available +// Otherwise: Pointer to the data buffer +//============================================================================= + +/* FIXME: Should this just be replaced with kmalloc() and kfree()? */ +u8 *MLMEGetMMPDUBuffer(PWB32_ADAPTER Adapter) +{ + s32 i; + u8 *returnVal; + + for (i = 0; i< MAX_NUM_TX_MMPDU; i++) { + if (Adapter->sMlmeFrame.TxMMPDUInUse[i] == FALSE) + break; + } + if (i >= MAX_NUM_TX_MMPDU) return NULL; + + returnVal = (u8 *)&(Adapter->sMlmeFrame.TxMMPDU[i]); + Adapter->sMlmeFrame.TxMMPDUInUse[i] = TRUE; + + return returnVal; +} + +//============================================================================= +u8 MLMESendFrame(PWB32_ADAPTER Adapter, u8 *pMMPDU, u16 len, u8 DataType) +/* DataType : FRAME_TYPE_802_11_MANAGEMENT, FRAME_TYPE_802_11_MANAGEMENT_CHALLENGE, + FRAME_TYPE_802_11_DATA */ +{ + if (Adapter->sMlmeFrame.IsInUsed != PACKET_FREE_TO_USE) { + Adapter->sMlmeFrame.wNumTxMMPDUDiscarded++; + return FALSE; + } + Adapter->sMlmeFrame.IsInUsed = PACKET_COME_FROM_MLME; + + // Keep information for sending + Adapter->sMlmeFrame.pMMPDU = pMMPDU; + Adapter->sMlmeFrame.DataType = DataType; + // len must be the last setting due to QUERY_SIZE_SECOND of Mds + Adapter->sMlmeFrame.len = len; + Adapter->sMlmeFrame.wNumTxMMPDU++; + + // H/W will enter power save by set the register. S/W don't send null frame + //with PWRMgt bit enbled to enter power save now. + + // Transmit NDIS packet + Mds_Tx(Adapter); + return TRUE; +} + +void +MLME_GetNextPacket(PADAPTER Adapter, PDESCRIPTOR pDes) +{ +#define DESCRIPTOR_ADD_BUFFER( _D, _A, _S ) \ +{\ + _D->InternalUsed = _D->buffer_start_index + _D->buffer_number; \ + _D->InternalUsed %= MAX_DESCRIPTOR_BUFFER_INDEX; \ + _D->buffer_address[ _D->InternalUsed ] = _A; \ + _D->buffer_size[ _D->InternalUsed ] = _S; \ + _D->buffer_total_size += _S; \ + _D->buffer_number++;\ +} + + DESCRIPTOR_ADD_BUFFER( pDes, Adapter->sMlmeFrame.pMMPDU, Adapter->sMlmeFrame.len ); + pDes->Type = Adapter->sMlmeFrame.DataType; +} + +void MLMEfreeMMPDUBuffer(PWB32_ADAPTER Adapter, PCHAR pData) +{ + int i; + + // Reclaim the data buffer + for (i = 0; i < MAX_NUM_TX_MMPDU; i++) { + if (pData == (PCHAR)&(Adapter->sMlmeFrame.TxMMPDU[i])) + break; + } + if (Adapter->sMlmeFrame.TxMMPDUInUse[i]) + Adapter->sMlmeFrame.TxMMPDUInUse[i] = FALSE; + else { + // Something wrong + // PD43 Add debug code here??? + } +} + +void +MLME_SendComplete(PADAPTER Adapter, u8 PacketID, unsigned char SendOK) +{ + MLME_TXCALLBACK TxCallback; + + // Reclaim the data buffer + Adapter->sMlmeFrame.len = 0; + MLMEfreeMMPDUBuffer( Adapter, Adapter->sMlmeFrame.pMMPDU ); + + + TxCallback.bResult = MLME_SUCCESS; + + // Return resource + Adapter->sMlmeFrame.IsInUsed = PACKET_FREE_TO_USE; +} + + + diff --git a/drivers/staging/winbond/mlmetxrx_f.h b/drivers/staging/winbond/mlmetxrx_f.h new file mode 100644 index 000000000000..d74e225be215 --- /dev/null +++ b/drivers/staging/winbond/mlmetxrx_f.h @@ -0,0 +1,52 @@ +//================================================================ +// MLMETxRx.H -- +// +// Functions defined in MLMETxRx.c. +// +// Copyright (c) 2002 Winbond Electrics Corp. All Rights Reserved. +//================================================================ +#ifndef _MLMETXRX_H +#define _MLMETXRX_H + +void +MLMEProcThread( + PWB32_ADAPTER Adapter + ); + +void MLMEResetTxRx( PWB32_ADAPTER Adapter); + +u8 * +MLMEGetMMPDUBuffer( + PWB32_ADAPTER Adapter + ); + +void MLMEfreeMMPDUBuffer( PWB32_ADAPTER Adapter, PCHAR pData); + +void MLME_GetNextPacket( PADAPTER Adapter, PDESCRIPTOR pDes ); +u8 MLMESendFrame( PWB32_ADAPTER Adapter, + u8 *pMMPDU, + u16 len, + u8 DataType); + +void +MLME_SendComplete( PWB32_ADAPTER Adapter, u8 PacketID, unsigned char SendOK ); + +void +MLMERcvFrame( + PWB32_ADAPTER Adapter, + PRXBUFFER pRxBufferArray, + u8 NumOfBuffer, + u8 ReturnSlotIndex + ); + +void +MLMEReturnPacket( + PWB32_ADAPTER Adapter, + PUCHAR pRxBufer + ); +#ifdef _IBSS_BEACON_SEQ_STICK_ +s8 SendBCNullData(PWB32_ADAPTER Adapter, u16 wIdx); +#endif + +#endif + diff --git a/drivers/staging/winbond/mto.c b/drivers/staging/winbond/mto.c new file mode 100644 index 000000000000..2ef60e5120cc --- /dev/null +++ b/drivers/staging/winbond/mto.c @@ -0,0 +1,1229 @@ +//============================================================================ +// MTO.C - +// +// Description: +// MAC Throughput Optimization for W89C33 802.11g WLAN STA. +// +// The following MIB attributes or internal variables will be affected +// while the MTO is being executed: +// dot11FragmentationThreshold, +// dot11RTSThreshold, +// transmission rate and PLCP preamble type, +// CCA mode, +// antenna diversity. +// +// Revision history: +// -------------------------------------------------------------------------- +// 20031227 UN20 Pete Chao +// First draft +// 20031229 Turbo copy from PD43 +// 20040210 Kevin revised +// Copyright (c) 2003 Winbond Electronics Corp. All rights reserved. +//============================================================================ + +// LA20040210_DTO kevin +#include "os_common.h" + +// Declare SQ3 to rate and fragmentation threshold table +// Declare fragmentation thresholds table +#define MTO_MAX_SQ3_LEVELS 14 +#define MTO_MAX_FRAG_TH_LEVELS 5 +#define MTO_MAX_DATA_RATE_LEVELS 12 + +u16 MTO_Frag_Th_Tbl[MTO_MAX_FRAG_TH_LEVELS] = +{ + 256, 384, 512, 768, 1536 +}; + +u8 MTO_SQ3_Level[MTO_MAX_SQ3_LEVELS] = +{ + 0, 26, 30, 32, 34, 35, 37, 42, 44, 46, 54, 62, 78, 81 +}; +u8 MTO_SQ3toRate[MTO_MAX_SQ3_LEVELS] = +{ + 0, 1, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 +}; +u8 MTO_SQ3toFrag[MTO_MAX_SQ3_LEVELS] = +{ + 0, 2, 2, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4 +}; + +// One Exchange Time table +// +u16 MTO_One_Exchange_Time_Tbl_l[MTO_MAX_FRAG_TH_LEVELS][MTO_MAX_DATA_RATE_LEVELS] = +{ + { 2554, 1474, 822, 0, 0, 636, 0, 0, 0, 0, 0, 0}, + { 3578, 1986, 1009, 0, 0, 729, 0, 0, 0, 0, 0, 0}, + { 4602, 2498, 1195, 0, 0, 822, 0, 0, 0, 0, 0, 0}, + { 6650, 3522, 1567, 0, 0, 1009, 0, 0, 0, 0, 0, 0}, + {12794, 6594, 2684, 0, 0, 1567, 0, 0, 0, 0, 0, 0} +}; + +u16 MTO_One_Exchange_Time_Tbl_s[MTO_MAX_FRAG_TH_LEVELS][MTO_MAX_DATA_RATE_LEVELS] = +{ + { 0, 1282, 630, 404, 288, 444, 232, 172, 144, 116, 100, 96}, + { 0, 1794, 817, 572, 400, 537, 316, 228, 188, 144, 124, 116}, + { 0, 2306, 1003, 744, 516, 630, 400, 288, 228, 172, 144, 136}, + { 0, 3330, 1375, 1084, 744, 817, 572, 400, 316, 228, 188, 172}, + { 0, 6402, 2492, 2108, 1424, 1375, 1084, 740, 572, 400, 316, 284} +}; + +#define MTO_ONE_EXCHANGE_TIME(preamble_type, frag_th_lvl, data_rate_lvl) \ + (preamble_type) ? MTO_One_Exchange_Time_Tbl_s[frag_th_lvl][data_rate_lvl] : \ + MTO_One_Exchange_Time_Tbl_l[frag_th_lvl][data_rate_lvl] + +// Declare data rate table +//The following table will be changed at anytime if the opration rate supported by AP don't +//match the table +u8 MTO_Data_Rate_Tbl[MTO_MAX_DATA_RATE_LEVELS] = +{ + 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 +}; + +//The Stardard_Data_Rate_Tbl and Level2PerTbl table is used to indirectly retreive PER +//information from Rate_PER_TBL +//The default settings is AP can support full rate set. +static u8 Stardard_Data_Rate_Tbl[MTO_MAX_DATA_RATE_LEVELS] = +{ + 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 +}; +static u8 Level2PerTbl[MTO_MAX_DATA_RATE_LEVELS] = +{ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 +}; +//How many kind of tx rate can be supported by AP +//DTO will change Rate between MTO_Data_Rate_Tbl[0] and MTO_Data_Rate_Tbl[MTO_DataRateAvailableLevel-1] +static u8 MTO_DataRateAvailableLevel = MTO_MAX_DATA_RATE_LEVELS; +//Smoothed PER table for each different RATE based on packet length of 1514 +static int Rate_PER_TBL[91][MTO_MAX_DATA_RATE_LEVELS] = { +// 1M 2M 5.5M 11M 6M 9M 12M 18M 24M 36M 48M 54M +/* 0% */{ 93, 177, 420, 538, 690, 774, 1001, 1401, 1768, 2358, 2838, 3039}, +/* 1% */{ 92, 176, 416, 533, 683, 767, 992, 1389, 1752, 2336, 2811, 3010}, +/* 2% */{ 91, 174, 412, 528, 675, 760, 983, 1376, 1735, 2313, 2783, 2979}, +/* 3% */{ 90, 172, 407, 523, 667, 753, 973, 1363, 1719, 2290, 2755, 2948}, +/* 4% */{ 90, 170, 403, 518, 659, 746, 964, 1350, 1701, 2266, 2726, 2916}, +/* 5% */{ 89, 169, 398, 512, 651, 738, 954, 1336, 1684, 2242, 2696, 2884}, +/* 6% */{ 88, 167, 394, 507, 643, 731, 944, 1322, 1666, 2217, 2665, 2851}, +/* 7% */{ 87, 165, 389, 502, 635, 723, 935, 1308, 1648, 2192, 2634, 2817}, +/* 8% */{ 86, 163, 384, 497, 626, 716, 924, 1294, 1629, 2166, 2602, 2782}, +/* 9% */{ 85, 161, 380, 491, 618, 708, 914, 1279, 1611, 2140, 2570, 2747}, +/* 10% */{ 84, 160, 375, 486, 609, 700, 904, 1265, 1591, 2113, 2537, 2711}, +/* 11% */{ 83, 158, 370, 480, 600, 692, 894, 1250, 1572, 2086, 2503, 2675}, +/* 12% */{ 82, 156, 365, 475, 592, 684, 883, 1234, 1552, 2059, 2469, 2638}, +/* 13% */{ 81, 154, 360, 469, 583, 676, 872, 1219, 1532, 2031, 2435, 2600}, +/* 14% */{ 80, 152, 355, 464, 574, 668, 862, 1204, 1512, 2003, 2400, 2562}, +/* 15% */{ 79, 150, 350, 458, 565, 660, 851, 1188, 1492, 1974, 2365, 2524}, +/* 16% */{ 78, 148, 345, 453, 556, 652, 840, 1172, 1471, 1945, 2329, 2485}, +/* 17% */{ 77, 146, 340, 447, 547, 643, 829, 1156, 1450, 1916, 2293, 2446}, +/* 18% */{ 76, 144, 335, 441, 538, 635, 818, 1140, 1429, 1887, 2256, 2406}, +/* 19% */{ 75, 143, 330, 436, 529, 627, 807, 1124, 1408, 1857, 2219, 2366}, +/* 20% */{ 74, 141, 325, 430, 520, 618, 795, 1107, 1386, 1827, 2182, 2326}, +/* 21% */{ 73, 139, 320, 424, 510, 610, 784, 1091, 1365, 1797, 2145, 2285}, +/* 22% */{ 72, 137, 314, 418, 501, 601, 772, 1074, 1343, 1766, 2107, 2244}, +/* 23% */{ 71, 135, 309, 412, 492, 592, 761, 1057, 1321, 1736, 2069, 2203}, +/* 24% */{ 70, 133, 304, 407, 482, 584, 749, 1040, 1299, 1705, 2031, 2161}, +/* 25% */{ 69, 131, 299, 401, 473, 575, 738, 1023, 1277, 1674, 1992, 2120}, +/* 26% */{ 68, 129, 293, 395, 464, 566, 726, 1006, 1254, 1642, 1953, 2078}, +/* 27% */{ 67, 127, 288, 389, 454, 557, 714, 989, 1232, 1611, 1915, 2035}, +/* 28% */{ 66, 125, 283, 383, 445, 549, 703, 972, 1209, 1579, 1876, 1993}, +/* 29% */{ 65, 123, 278, 377, 436, 540, 691, 955, 1187, 1548, 1836, 1951}, +/* 30% */{ 64, 121, 272, 371, 426, 531, 679, 937, 1164, 1516, 1797, 1908}, +/* 31% */{ 63, 119, 267, 365, 417, 522, 667, 920, 1141, 1484, 1758, 1866}, +/* 32% */{ 62, 117, 262, 359, 407, 513, 655, 902, 1118, 1453, 1719, 1823}, +/* 33% */{ 61, 115, 256, 353, 398, 504, 643, 885, 1095, 1421, 1679, 1781}, +/* 34% */{ 60, 113, 251, 347, 389, 495, 631, 867, 1072, 1389, 1640, 1738}, +/* 35% */{ 59, 111, 246, 341, 379, 486, 619, 850, 1049, 1357, 1600, 1695}, +/* 36% */{ 58, 108, 240, 335, 370, 477, 607, 832, 1027, 1325, 1561, 1653}, +/* 37% */{ 57, 106, 235, 329, 361, 468, 595, 815, 1004, 1293, 1522, 1610}, +/* 38% */{ 56, 104, 230, 323, 351, 459, 584, 797, 981, 1261, 1483, 1568}, +/* 39% */{ 55, 102, 224, 317, 342, 450, 572, 780, 958, 1230, 1443, 1526}, +/* 40% */{ 54, 100, 219, 311, 333, 441, 560, 762, 935, 1198, 1404, 1484}, +/* 41% */{ 53, 98, 214, 305, 324, 432, 548, 744, 912, 1166, 1366, 1442}, +/* 42% */{ 52, 96, 209, 299, 315, 423, 536, 727, 889, 1135, 1327, 1400}, +/* 43% */{ 51, 94, 203, 293, 306, 414, 524, 709, 866, 1104, 1289, 1358}, +/* 44% */{ 50, 92, 198, 287, 297, 405, 512, 692, 844, 1072, 1250, 1317}, +/* 45% */{ 49, 90, 193, 281, 288, 396, 500, 675, 821, 1041, 1212, 1276}, +/* 46% */{ 48, 88, 188, 275, 279, 387, 488, 657, 799, 1011, 1174, 1236}, +/* 47% */{ 47, 86, 183, 269, 271, 378, 476, 640, 777, 980, 1137, 1195}, +/* 48% */{ 46, 84, 178, 262, 262, 369, 464, 623, 754, 949, 1100, 1155}, +/* 49% */{ 45, 82, 173, 256, 254, 360, 452, 606, 732, 919, 1063, 1116}, +/* 50% */{ 44, 80, 168, 251, 245, 351, 441, 589, 710, 889, 1026, 1076}, +/* 51% */{ 43, 78, 163, 245, 237, 342, 429, 572, 689, 860, 990, 1038}, +/* 52% */{ 42, 76, 158, 239, 228, 333, 417, 555, 667, 830, 955, 999}, +/* 53% */{ 41, 74, 153, 233, 220, 324, 406, 538, 645, 801, 919, 961}, +/* 54% */{ 40, 72, 148, 227, 212, 315, 394, 522, 624, 773, 884, 924}, +/* 55% */{ 39, 70, 143, 221, 204, 307, 383, 505, 603, 744, 850, 887}, +/* 56% */{ 38, 68, 138, 215, 196, 298, 371, 489, 582, 716, 816, 851}, +/* 57% */{ 37, 67, 134, 209, 189, 289, 360, 473, 562, 688, 783, 815}, +/* 58% */{ 36, 65, 129, 203, 181, 281, 349, 457, 541, 661, 750, 780}, +/* 59% */{ 35, 63, 124, 197, 174, 272, 338, 441, 521, 634, 717, 745}, +/* 60% */{ 34, 61, 120, 192, 166, 264, 327, 425, 501, 608, 686, 712}, +/* 61% */{ 33, 59, 115, 186, 159, 255, 316, 409, 482, 582, 655, 678}, +/* 62% */{ 32, 57, 111, 180, 152, 247, 305, 394, 462, 556, 624, 646}, +/* 63% */{ 31, 55, 107, 174, 145, 238, 294, 379, 443, 531, 594, 614}, +/* 64% */{ 30, 53, 102, 169, 138, 230, 283, 364, 425, 506, 565, 583}, +/* 65% */{ 29, 52, 98, 163, 132, 222, 273, 349, 406, 482, 536, 553}, +/* 66% */{ 28, 50, 94, 158, 125, 214, 262, 334, 388, 459, 508, 523}, +/* 67% */{ 27, 48, 90, 152, 119, 206, 252, 320, 370, 436, 481, 495}, +/* 68% */{ 26, 46, 86, 147, 113, 198, 242, 306, 353, 413, 455, 467}, +/* 69% */{ 26, 44, 82, 141, 107, 190, 231, 292, 336, 391, 429, 440}, +/* 70% */{ 25, 43, 78, 136, 101, 182, 221, 278, 319, 370, 405, 414}, +/* 71% */{ 24, 41, 74, 130, 95, 174, 212, 265, 303, 350, 381, 389}, +/* 72% */{ 23, 39, 71, 125, 90, 167, 202, 252, 287, 329, 358, 365}, +/* 73% */{ 22, 37, 67, 119, 85, 159, 192, 239, 271, 310, 335, 342}, +/* 74% */{ 21, 36, 63, 114, 80, 151, 183, 226, 256, 291, 314, 320}, +/* 75% */{ 20, 34, 60, 109, 75, 144, 174, 214, 241, 273, 294, 298}, +/* 76% */{ 19, 32, 57, 104, 70, 137, 164, 202, 227, 256, 274, 278}, +/* 77% */{ 18, 31, 53, 99, 66, 130, 155, 190, 213, 239, 256, 259}, +/* 78% */{ 17, 29, 50, 94, 62, 122, 146, 178, 200, 223, 238, 241}, +/* 79% */{ 16, 28, 47, 89, 58, 115, 138, 167, 187, 208, 222, 225}, +/* 80% */{ 16, 26, 44, 84, 54, 109, 129, 156, 175, 194, 206, 209}, +/* 81% */{ 15, 24, 41, 79, 50, 102, 121, 146, 163, 180, 192, 194}, +/* 82% */{ 14, 23, 39, 74, 47, 95, 113, 136, 151, 167, 178, 181}, +/* 83% */{ 13, 21, 36, 69, 44, 89, 105, 126, 140, 155, 166, 169}, +/* 84% */{ 12, 20, 33, 64, 41, 82, 97, 116, 130, 144, 155, 158}, +/* 85% */{ 11, 19, 31, 60, 39, 76, 89, 107, 120, 134, 145, 149}, +/* 86% */{ 11, 17, 29, 55, 36, 70, 82, 98, 110, 125, 136, 140}, +/* 87% */{ 10, 16, 26, 51, 34, 64, 75, 90, 102, 116, 128, 133}, +/* 88% */{ 9, 14, 24, 46, 32, 58, 68, 81, 93, 108, 121, 128}, +/* 89% */{ 8, 13, 22, 42, 31, 52, 61, 74, 86, 102, 116, 124}, +/* 90% */{ 7, 12, 21, 37, 29, 46, 54, 66, 79, 96, 112, 121} +}; + +#define RSSIBUF_NUM 10 +#define RSSI2RATE_SIZE 9 + +static TXRETRY_REC TxRateRec={MTO_MAX_DATA_RATE_LEVELS - 1, 0}; //new record=>TxRateRec +static int TxRetryRate; +//static int SQ3, BSS_PK_CNT, NIDLESLOT, SLOT_CNT, INTERF_CNT, GAP_CNT, DS_EVM; +static s32 RSSIBuf[RSSIBUF_NUM]={-70, -70, -70, -70, -70, -70, -70, -70, -70, -70}; +static s32 RSSISmoothed=-700; +static int RSSIBufIndex=0; +static u8 max_rssi_rate; +static int rate_tbl[13] = {0,1,2,5,11,6,9,12,18,24,36,48,54}; +//[WKCHEN]static core_data_t *pMTOcore_data=NULL; + +static int TotalTxPkt = 0; +static int TotalTxPktRetry = 0; +static int TxPktPerAnt[3] = {0,0,0}; +static int RXRSSIANT[3] ={-70,-70,-70}; +static int TxPktRetryPerAnt[3] = {0,0,0}; +//static int TxDominateFlag=FALSE; +static u8 old_antenna[4]={1 ,0 ,1 ,0}; +static int retryrate_rec[MTO_MAX_DATA_RATE_LEVELS];//this record the retry rate at different data rate + +static int PeriodTotalTxPkt = 0; +static int PeriodTotalTxPktRetry = 0; + +typedef struct +{ + s32 RSSI; + u8 TxRate; +}RSSI2RATE; + +static RSSI2RATE RSSI2RateTbl[RSSI2RATE_SIZE] = +{ + {-740, 108}, // 54M + {-760, 96}, // 48M + {-820, 72}, // 36M + {-850, 48}, // 24M + {-870, 36}, // 18M + {-890, 24}, // 12M + {-900, 12}, // 6M + {-920, 11}, // 5.5M + {-950, 4}, // 2M +}; +static u8 untogglecount; +static u8 last_rate_ant; //this is used for antenna backoff-hh + +u8 boSparseTxTraffic = FALSE; + +void MTO_Init(MTO_FUNC_INPUT); +void AntennaToggleInitiator(MTO_FUNC_INPUT); +void AntennaToggleState(MTO_FUNC_INPUT); +void TxPwrControl(MTO_FUNC_INPUT); +void GetFreshAntennaData(MTO_FUNC_INPUT); +void TxRateReductionCtrl(MTO_FUNC_INPUT); +/** 1.1.31.1000 Turbo modify */ +//void MTO_SetDTORateRange(int type); +void MTO_SetDTORateRange(MTO_FUNC_INPUT, u8 *pRateArray, u8 ArraySize); +void MTO_SetTxCount(MTO_FUNC_INPUT, u8 t0, u8 index); +void MTO_TxFailed(MTO_FUNC_INPUT); +void SmoothRSSI(s32 new_rssi); +void hal_get_dto_para(MTO_FUNC_INPUT, char *buffer); +u8 CalcNewRate(MTO_FUNC_INPUT, u8 old_rate, u32 retry_cnt, u32 tx_frag_cnt); +u8 GetMaxRateLevelFromRSSI(void); +u8 MTO_GetTxFallbackRate(MTO_FUNC_INPUT); +int Divide(int a, int b); +void multiagc(MTO_FUNC_INPUT, u8 high_gain_mode); + +//=========================================================================== +// MTO_Init -- +// +// Description: +// Set DTO Tx Rate Scope because different AP could have different Rate set. +// After our staion join with AP, LM core will call this function to initialize +// Tx Rate table. +// +// Arguments: +// pRateArray - The pointer to the Tx Rate Array by the following order +// - 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 +// - DTO won't check whether rate order is invalid or not +// ArraySize - The array size to indicate how many tx rate we can choose +// +// sample code: +// { +// u8 RateArray[4] = {2, 4, 11, 22}; +// MTO_SetDTORateRange(RateArray, 4); +// } +// +// Return Value: +// None +//============================================================================ +void MTO_SetDTORateRange(MTO_FUNC_INPUT,u8 *pRateArray, u8 ArraySize) +{ + u8 i, j=0; + + for(i=0;i<ArraySize;i++) + { + if(pRateArray[i] == 22) + break; + } + if(i < ArraySize) //we need adjust the order of rate list because 11Mbps rate exists + { + for(;i>0;i--) + { + if(pRateArray[i-1] <= 11) + break; + pRateArray[i] = pRateArray[i-1]; + } + pRateArray[i] = 22; + MTO_OFDM_RATE_LEVEL() = i; + } + else + { + for(i=0; i<ArraySize; i++) + { + if (pRateArray[i] >= 12) + break; + } + MTO_OFDM_RATE_LEVEL() = i; + } + + for(i=0;i<ArraySize;i++) + { + MTO_Data_Rate_Tbl[i] = pRateArray[i]; + for(;j<MTO_MAX_DATA_RATE_LEVELS;j++) + { + if(Stardard_Data_Rate_Tbl[j] == pRateArray[i]) + break; + } + Level2PerTbl[i] = j; + #ifdef _PE_DTO_DUMP_ + WBDEBUG(("[MTO]:Op Rate[%d]: %d\n",i, MTO_Data_Rate_Tbl[i])); + #endif + } + MTO_DataRateAvailableLevel = ArraySize; + if( MTO_DATA().RatePolicy ) // 0 means that no registry setting + { + if( MTO_DATA().RatePolicy == 1 ) + TxRateRec.tx_rate = 0; //ascent + else + TxRateRec.tx_rate = MTO_DataRateAvailableLevel -1 ; //descent + } + else + { + if( MTO_INITTXRATE_MODE ) + TxRateRec.tx_rate = 0; //ascent + else + TxRateRec.tx_rate = MTO_DataRateAvailableLevel -1 ; //descent + } + TxRateRec.tx_retry_rate = 0; + //set default rate for initial use + MTO_RATE_LEVEL() = TxRateRec.tx_rate; + MTO_FALLBACK_RATE_LEVEL() = MTO_RATE_LEVEL(); +} + +//=========================================================================== +// MTO_Init -- +// +// Description: +// Initialize MTO parameters. +// +// This function should be invoked during system initialization. +// +// Arguments: +// Adapter - The pointer to the Miniport Adapter Context +// +// Return Value: +// None +//============================================================================ +void MTO_Init(MTO_FUNC_INPUT) +{ + int i; + //WBDEBUG(("[MTO] -> MTO_Init()\n")); + //[WKCHEN]pMTOcore_data = pcore_data; +// 20040510 Turbo add for global variable + MTO_TMR_CNT() = 0; + MTO_TOGGLE_STATE() = TOGGLE_STATE_IDLE; + MTO_TX_RATE_REDUCTION_STATE() = RATE_CHGSTATE_IDLE; + MTO_BACKOFF_TMR() = 0; + MTO_LAST_RATE() = 11; + MTO_CO_EFFICENT() = 0; + + //MTO_TH_FIXANT() = MTO_DEFAULT_TH_FIXANT; + MTO_TH_CNT() = MTO_DEFAULT_TH_CNT; + MTO_TH_SQ3() = MTO_DEFAULT_TH_SQ3; + MTO_TH_IDLE_SLOT() = MTO_DEFAULT_TH_IDLE_SLOT; + MTO_TH_PR_INTERF() = MTO_DEFAULT_TH_PR_INTERF; + + MTO_TMR_AGING() = MTO_DEFAULT_TMR_AGING; + MTO_TMR_PERIODIC() = MTO_DEFAULT_TMR_PERIODIC; + + //[WKCHEN]MTO_CCA_MODE_SETUP()= (u8) hal_get_cca_mode(MTO_HAL()); + //[WKCHEN]MTO_CCA_MODE() = MTO_CCA_MODE_SETUP(); + + //MTO_PREAMBLE_TYPE() = MTO_PREAMBLE_LONG; + MTO_PREAMBLE_TYPE() = MTO_PREAMBLE_SHORT; // for test + + MTO_ANT_SEL() = hal_get_antenna_number(MTO_HAL()); + MTO_ANT_MAC() = MTO_ANT_SEL(); + MTO_CNT_ANT(0) = 0; + MTO_CNT_ANT(1) = 0; + MTO_SQ_ANT(0) = 0; + MTO_SQ_ANT(1) = 0; + MTO_ANT_DIVERSITY() = MTO_ANTENNA_DIVERSITY_ON; + //CardSet_AntennaDiversity(Adapter, MTO_ANT_DIVERSITY()); + //PLMESetAntennaDiversity( Adapter, MTO_ANT_DIVERSITY()); + + MTO_AGING_TIMEOUT() = 0;//MTO_TMR_AGING() / MTO_TMR_PERIODIC(); + + // The following parameters should be initialized to the values set by user + // + //MTO_RATE_LEVEL() = 10; + MTO_RATE_LEVEL() = 0; + MTO_FALLBACK_RATE_LEVEL() = MTO_RATE_LEVEL(); + MTO_FRAG_TH_LEVEL() = 4; + /** 1.1.23.1000 Turbo modify from -1 to +1 + MTO_RTS_THRESHOLD() = MTO_FRAG_TH() - 1; + MTO_RTS_THRESHOLD_SETUP() = MTO_FRAG_TH() - 1; + */ + MTO_RTS_THRESHOLD() = MTO_FRAG_TH() + 1; + MTO_RTS_THRESHOLD_SETUP() = MTO_FRAG_TH() + 1; + // 1.1.23.1000 Turbo add for mto change preamble from 0 to 1 + MTO_RATE_CHANGE_ENABLE() = 1; + MTO_FRAG_CHANGE_ENABLE() = 0; // 1.1.29.1000 Turbo add don't support frag + //The default valud of ANTDIV_DEFAULT_ON will be decided by EEPROM + //#ifdef ANTDIV_DEFAULT_ON + //MTO_ANT_DIVERSITY_ENABLE() = 1; + //#else + //MTO_ANT_DIVERSITY_ENABLE() = 0; + //#endif + MTO_POWER_CHANGE_ENABLE() = 1; + MTO_PREAMBLE_CHANGE_ENABLE()= 1; + MTO_RTS_CHANGE_ENABLE() = 0; // 1.1.29.1000 Turbo add don't support frag + // 20040512 Turbo add + //old_antenna[0] = 1; + //old_antenna[1] = 0; + //old_antenna[2] = 1; + //old_antenna[3] = 0; + for (i=0;i<MTO_MAX_DATA_RATE_LEVELS;i++) + retryrate_rec[i]=5; + + MTO_TXFLOWCOUNT() = 0; + //--------- DTO threshold parameters ------------- + //MTOPARA_PERIODIC_CHECK_CYCLE() = 50; + MTOPARA_PERIODIC_CHECK_CYCLE() = 10; + MTOPARA_RSSI_TH_FOR_ANTDIV() = 10; + MTOPARA_TXCOUNT_TH_FOR_CALC_RATE() = 50; + MTOPARA_TXRATE_INC_TH() = 10; + MTOPARA_TXRATE_DEC_TH() = 30; + MTOPARA_TXRATE_EQ_TH() = 40; + MTOPARA_TXRATE_BACKOFF() = 12; + MTOPARA_TXRETRYRATE_REDUCE() = 6; + if ( MTO_TXPOWER_FROM_EEPROM == 0xff) + { + switch( MTO_HAL()->phy_type) + { + case RF_AIROHA_2230: + case RF_AIROHA_2230S: // 20060420 Add this + MTOPARA_TXPOWER_INDEX() = 46; // MAX-8 // @@ Only for AL 2230 + break; + case RF_AIROHA_7230: + MTOPARA_TXPOWER_INDEX() = 49; + break; + case RF_WB_242: + MTOPARA_TXPOWER_INDEX() = 10; + break; + case RF_WB_242_1: + MTOPARA_TXPOWER_INDEX() = 24; // ->10 20060316.1 modify + break; + } + } + else //follow the setting from EEPROM + MTOPARA_TXPOWER_INDEX() = MTO_TXPOWER_FROM_EEPROM; + hal_set_rf_power(MTO_HAL(), (u8)MTOPARA_TXPOWER_INDEX()); + //------------------------------------------------ + + // For RSSI turning 20060808.4 Cancel load from EEPROM + MTO_DATA().RSSI_high = -41; + MTO_DATA().RSSI_low = -60; +} + +//---------------------------------------------------------------------------// +static u32 DTO_Rx_Info[13][3]; +static u32 DTO_RxCRCFail_Info[13][3]; +static u32 AntennaToggleBkoffTimer=5; +typedef struct{ + int RxRate; + int RxRatePkts; + int index; +}RXRATE_ANT; +RXRATE_ANT RxRatePeakAnt[3]; + +#define ANT0 0 +#define ANT1 1 +#define OLD_ANT 2 + +void SearchPeakRxRate(int index) +{ + int i; + RxRatePeakAnt[index].RxRatePkts=0; + //Find out the best rx rate which is used on different antenna + for(i=1;i<13;i++) + { + if(DTO_Rx_Info[i][index] > (u32) RxRatePeakAnt[index].RxRatePkts) + { + RxRatePeakAnt[index].RxRatePkts = DTO_Rx_Info[i][index]; + RxRatePeakAnt[index].RxRate = rate_tbl[i]; + RxRatePeakAnt[index].index = i; + } + } +} + +void ResetDTO_RxInfo(int index, MTO_FUNC_INPUT) +{ + int i; + + #ifdef _PE_DTO_DUMP_ + WBDEBUG(("ResetDTOrx\n")); + #endif + + for(i=0;i<13;i++) + DTO_Rx_Info[i][index] = MTO_HAL()->rx_ok_count[i]; + + for(i=0;i<13;i++) + DTO_RxCRCFail_Info[i][index] = MTO_HAL()->rx_err_count[i]; + + TotalTxPkt = 0; + TotalTxPktRetry = 0; +} + +void GetDTO_RxInfo(int index, MTO_FUNC_INPUT) +{ + int i; + + #ifdef _PE_DTO_DUMP_ + WBDEBUG(("GetDTOrx\n")); + #endif + + //PDEBUG(("[MTO]:DTO_Rx_Info[%d]=%d, rx_ok_count=%d\n", index, DTO_Rx_Info[0][index], phw_data->rx_ok_count[0])); + for(i=0;i<13;i++) + DTO_Rx_Info[i][index] = abs(MTO_HAL()->rx_ok_count[i] - DTO_Rx_Info[i][index]); + if(DTO_Rx_Info[0][index]==0) DTO_Rx_Info[0][index] = 1; + + for(i=0;i<13;i++) + DTO_RxCRCFail_Info[i][index] = MTO_HAL()->rx_err_count[i] - DTO_RxCRCFail_Info[i][index]; + + TxPktPerAnt[index] = TotalTxPkt; + TxPktRetryPerAnt[index] = TotalTxPktRetry; + TotalTxPkt = 0; + TotalTxPktRetry = 0; +} + +void OutputDebugInfo(int index1, int index2) +{ + #ifdef _PE_DTO_DUMP_ + WBDEBUG(("[HHDTO]:Total Rx (%d)\t\t(%d) \n ", DTO_Rx_Info[0][index1], DTO_Rx_Info[0][index2])); + WBDEBUG(("[HHDTO]:RECEIVE RSSI: (%d)\t\t(%d) \n ", RXRSSIANT[index1], RXRSSIANT[index2])); + WBDEBUG(("[HHDTO]:TX packet correct rate: (%d)%%\t\t(%d)%% \n ",Divide(TxPktPerAnt[index1]*100,TxPktRetryPerAnt[index1]), Divide(TxPktPerAnt[index2]*100,TxPktRetryPerAnt[index2]))); + #endif + { + int tmp1, tmp2; + #ifdef _PE_DTO_DUMP_ + WBDEBUG(("[HHDTO]:Total Tx (%d)\t\t(%d) \n ", TxPktPerAnt[index1], TxPktPerAnt[index2])); + WBDEBUG(("[HHDTO]:Total Tx retry (%d)\t\t(%d) \n ", TxPktRetryPerAnt[index1], TxPktRetryPerAnt[index2])); + #endif + tmp1 = TxPktPerAnt[index1] + DTO_Rx_Info[0][index1]; + tmp2 = TxPktPerAnt[index2] + DTO_Rx_Info[0][index2]; + #ifdef _PE_DTO_DUMP_ + WBDEBUG(("[HHDTO]:Total Tx+RX (%d)\t\t(%d) \n ", tmp1, tmp2)); + #endif + } +} + +unsigned char TxDominate(int index) +{ + int tmp; + + tmp = TxPktPerAnt[index] + DTO_Rx_Info[0][index]; + + if(Divide(TxPktPerAnt[index]*100, tmp) > 40) + return TRUE; + else + return FALSE; +} + +unsigned char CmpTxRetryRate(int index1, int index2) +{ + int tx_retry_rate1, tx_retry_rate2; + tx_retry_rate1 = Divide((TxPktRetryPerAnt[index1] - TxPktPerAnt[index1])*100, TxPktRetryPerAnt[index1]); + tx_retry_rate2 = Divide((TxPktRetryPerAnt[index2] - TxPktPerAnt[index2])*100, TxPktRetryPerAnt[index2]); + #ifdef _PE_DTO_DUMP_ + WBDEBUG(("[MTO]:TxRetry Ant0: (%d%%) Ant1: (%d%%) \n ", tx_retry_rate1, tx_retry_rate2)); + #endif + + if(tx_retry_rate1 > tx_retry_rate2) + return TRUE; + else + return FALSE; +} + +void GetFreshAntennaData(MTO_FUNC_INPUT) +{ + u8 x; + + x = hal_get_antenna_number(MTO_HAL()); + //hal_get_bss_pk_cnt(MTO_HAL()); + //hal_get_est_sq3(MTO_HAL(), 1); + old_antenna[0] = x; + //if this is the function for timer + ResetDTO_RxInfo(x, MTO_FUNC_INPUT_DATA); + if(AntennaToggleBkoffTimer) + AntennaToggleBkoffTimer--; + if (abs(last_rate_ant-MTO_RATE_LEVEL())>1) //backoff timer reset + AntennaToggleBkoffTimer=0; + + if (MTO_ANT_DIVERSITY() != MTO_ANTENNA_DIVERSITY_ON || + MTO_ANT_DIVERSITY_ENABLE() != 1) + AntennaToggleBkoffTimer=1; + #ifdef _PE_DTO_DUMP_ + WBDEBUG(("[HHDTO]:**last data rate=%d,now data rate=%d**antenna toggle timer=%d",last_rate_ant,MTO_RATE_LEVEL(),AntennaToggleBkoffTimer)); + #endif + last_rate_ant=MTO_RATE_LEVEL(); + if(AntennaToggleBkoffTimer==0) + { + MTO_TOGGLE_STATE() = TOGGLE_STATE_WAIT0; + #ifdef _PE_DTO_DUMP_ + WBDEBUG(("[HHDTO]:===state is starting==for antenna toggle===")); + #endif + } + else + MTO_TOGGLE_STATE() = TOGGLE_STATE_IDLE; + + if ((MTO_BACKOFF_TMR()!=0)&&(MTO_RATE_LEVEL()>MTO_DataRateAvailableLevel - 3)) + { + MTO_TOGGLE_STATE() = TOGGLE_STATE_IDLE; + #ifdef _PE_DTO_DUMP_ + WBDEBUG(("[HHDTO]:===the data rate is %d (good)and will not toogle ===",MTO_DATA_RATE()>>1)); + #endif + } + + +} + +int WB_PCR[2]; //packet correct rate + +void AntennaToggleState(MTO_FUNC_INPUT) +{ + int decideantflag = 0; + u8 x; + s32 rssi; + + if(MTO_ANT_DIVERSITY_ENABLE() != 1) + return; + x = hal_get_antenna_number(MTO_HAL()); + switch(MTO_TOGGLE_STATE()) + { + + //Missing..... + case TOGGLE_STATE_IDLE: + case TOGGLE_STATE_BKOFF: + break;; + + case TOGGLE_STATE_WAIT0://======== + GetDTO_RxInfo(x, MTO_FUNC_INPUT_DATA); + sme_get_rssi(MTO_FUNC_INPUT_DATA, &rssi); + RXRSSIANT[x] = rssi; + #ifdef _PE_DTO_DUMP_ + WBDEBUG(("[HHDTO] **wait0==== Collecting Ant%d--rssi=%d\n", x,RXRSSIANT[x])); + #endif + + //change antenna and reset the data at changed antenna + x = (~x) & 0x01; + MTO_ANT_SEL() = x; + hal_set_antenna_number(MTO_HAL(), MTO_ANT_SEL()); + LOCAL_ANTENNA_NO() = x; + + MTO_TOGGLE_STATE() = TOGGLE_STATE_WAIT1;//go to wait1 + ResetDTO_RxInfo(x, MTO_FUNC_INPUT_DATA); + break; + case TOGGLE_STATE_WAIT1://=====wait1 + //MTO_CNT_ANT(x) = hal_get_bss_pk_cnt(MTO_HAL()); + //RXRSSIANT[x] = hal_get_rssi(MTO_HAL()); + sme_get_rssi(MTO_FUNC_INPUT_DATA, &rssi); + RXRSSIANT[x] = rssi; + GetDTO_RxInfo(x, MTO_FUNC_INPUT_DATA); + #ifdef _PE_DTO_DUMP_ + WBDEBUG(("[HHDTO] **wait1==== Collecting Ant%d--rssi=%d\n", x,RXRSSIANT[x])); + #endif + MTO_TOGGLE_STATE() = TOGGLE_STATE_MAKEDESISION; + break; + case TOGGLE_STATE_MAKEDESISION: + #ifdef _PE_DTO_DUMP_ + WBDEBUG(("[HHDTO]:Ant--0-----------------1---\n")); + OutputDebugInfo(ANT0,ANT1); + #endif + //PDEBUG(("[HHDTO] **decision====\n ")); + + //=====following is the decision produrce + // + // first: compare the rssi if difference >10 + // select the larger one + // ,others go to second + // second: comapre the tx+rx packet count if difference >100 + // use larger total packets antenna + // third::compare the tx PER if packets>20 + // if difference >5% using the bigger one + // + // fourth:compare the RX PER if packets>20 + // if PER difference <5% + // using old antenna + // + // + if (abs(RXRSSIANT[ANT0]-RXRSSIANT[ANT1]) > MTOPARA_RSSI_TH_FOR_ANTDIV())//====rssi_th + { + if (RXRSSIANT[ANT0]>RXRSSIANT[ANT1]) + { + decideantflag=1; + MTO_ANT_MAC() = ANT0; + } + else + { + decideantflag=1; + MTO_ANT_MAC() = ANT1; + } + #ifdef _PE_DTO_DUMP_ + WBDEBUG(("Select antenna by RSSI\n")); + #endif + } + else if (abs(TxPktPerAnt[ANT0] + DTO_Rx_Info[0][ANT0]-TxPktPerAnt[ANT1]-DTO_Rx_Info[0][ANT1])<50)//=====total packet_th + { + #ifdef _PE_DTO_DUMP_ + WBDEBUG(("Total tx/rx is close\n")); + #endif + if (TxDominate(ANT0) && TxDominate(ANT1)) + { + if ((TxPktPerAnt[ANT0]>10) && (TxPktPerAnt[ANT1]>10))//====tx packet_th + { + WB_PCR[ANT0]=Divide(TxPktPerAnt[ANT0]*100,TxPktRetryPerAnt[ANT0]); + WB_PCR[ANT1]=Divide(TxPktPerAnt[ANT1]*100,TxPktRetryPerAnt[ANT1]); + if (abs(WB_PCR[ANT0]-WB_PCR[ANT1])>5)// tx PER_th + { + #ifdef _PE_DTO_DUMP_ + WBDEBUG(("Decide by Tx correct rate\n")); + #endif + if (WB_PCR[ANT0]>WB_PCR[ANT1]) + { + decideantflag=1; + MTO_ANT_MAC() = ANT0; + } + else + { + decideantflag=1; + MTO_ANT_MAC() = ANT1; + } + } + else + { + decideantflag=0; + untogglecount++; + MTO_ANT_MAC() = old_antenna[0]; + } + } + else + { + decideantflag=0; + MTO_ANT_MAC() = old_antenna[0]; + } + } + else if ((DTO_Rx_Info[0][ANT0]>10)&&(DTO_Rx_Info[0][ANT1]>10))//rx packet th + { + #ifdef _PE_DTO_DUMP_ + WBDEBUG(("Decide by Rx\n")); + #endif + if (abs(DTO_Rx_Info[0][ANT0] - DTO_Rx_Info[0][ANT1])>50) + { + if (DTO_Rx_Info[0][ANT0] > DTO_Rx_Info[0][ANT1]) + { + decideantflag=1; + MTO_ANT_MAC() = ANT0; + } + else + { + decideantflag=1; + MTO_ANT_MAC() = ANT1; + } + } + else + { + decideantflag=0; + untogglecount++; + MTO_ANT_MAC() = old_antenna[0]; + } + } + else + { + decideantflag=0; + MTO_ANT_MAC() = old_antenna[0]; + } + } + else if ((TxPktPerAnt[ANT0]+DTO_Rx_Info[0][ANT0])>(TxPktPerAnt[ANT1]+DTO_Rx_Info[0][ANT1]))//use more packekts + { + #ifdef _PE_DTO_DUMP_ + WBDEBUG(("decide by total tx/rx : ANT 0\n")); + #endif + + decideantflag=1; + MTO_ANT_MAC() = ANT0; + } + else + { + #ifdef _PE_DTO_DUMP_ + WBDEBUG(("decide by total tx/rx : ANT 1\n")); + #endif + decideantflag=1; + MTO_ANT_MAC() = ANT1; + + } + //this is force ant toggle + if (decideantflag==1) + untogglecount=0; + + untogglecount=untogglecount%4; + if (untogglecount==3) //change antenna + MTO_ANT_MAC() = ((~old_antenna[0]) & 0x1); + #ifdef _PE_DTO_DUMP_ + WBDEBUG(("[HHDTO]:==================untoggle-count=%d",untogglecount)); + #endif + + + + + //PDEBUG(("[HHDTO] **********************************DTO ENABLE=%d",MTO_ANT_DIVERSITY_ENABLE())); + if(MTO_ANT_DIVERSITY_ENABLE() == 1) + { + MTO_ANT_SEL() = MTO_ANT_MAC(); + hal_set_antenna_number(MTO_HAL(), MTO_ANT_SEL()); + LOCAL_ANTENNA_NO() = MTO_ANT_SEL(); + #ifdef _PE_DTO_DUMP_ + WBDEBUG(("[HHDTO] ==decision==*******antflag=%d******************selected antenna=%d\n",decideantflag,MTO_ANT_SEL())); + #endif + } + if (decideantflag) + { + old_antenna[3]=old_antenna[2];//store antenna info + old_antenna[2]=old_antenna[1]; + old_antenna[1]=old_antenna[0]; + old_antenna[0]= MTO_ANT_MAC(); + } + #ifdef _PE_DTO_DUMP_ + WBDEBUG(("[HHDTO]:**old antenna=[%d][%d][%d][%d]\n",old_antenna[0],old_antenna[1],old_antenna[2],old_antenna[3])); + #endif + if (old_antenna[0]!=old_antenna[1]) + AntennaToggleBkoffTimer=0; + else if (old_antenna[1]!=old_antenna[2]) + AntennaToggleBkoffTimer=1; + else if (old_antenna[2]!=old_antenna[3]) + AntennaToggleBkoffTimer=2; + else + AntennaToggleBkoffTimer=4; + + #ifdef _PE_DTO_DUMP_ + WBDEBUG(("[HHDTO]:**back off timer=%d",AntennaToggleBkoffTimer)); + #endif + + ResetDTO_RxInfo(MTO_ANT_MAC(), MTO_FUNC_INPUT_DATA); + if (AntennaToggleBkoffTimer==0 && decideantflag) + MTO_TOGGLE_STATE() = TOGGLE_STATE_WAIT0; + else + MTO_TOGGLE_STATE() = TOGGLE_STATE_IDLE; + break; + } + +} + +void multiagc(MTO_FUNC_INPUT, u8 high_gain_mode ) +{ + s32 rssi; + hw_data_t *pHwData = MTO_HAL(); + + sme_get_rssi(MTO_FUNC_INPUT_DATA, &rssi); + + if( (RF_WB_242 == pHwData->phy_type) || + (RF_WB_242_1 == pHwData->phy_type) ) // 20060619.5 Add + { + if (high_gain_mode==1) + { + //hw_set_dxx_reg(phw_data, 0x0C, 0xf8f52230); + //hw_set_dxx_reg(phw_data, 0x20, 0x06C43440); + Wb35Reg_Write( pHwData, 0x100C, 0xF2F32232 ); // 940916 0xf8f52230 ); + Wb35Reg_Write( pHwData, 0x1020, 0x04cb3440 ); // 940915 0x06C43440 + } + else if (high_gain_mode==0) + { + //hw_set_dxx_reg(phw_data, 0x0C, 0xEEEE000D); + //hw_set_dxx_reg(phw_data, 0x20, 0x06c41440); + Wb35Reg_Write( pHwData, 0x100C, 0xEEEE000D ); + Wb35Reg_Write( pHwData, 0x1020, 0x04cb1440 ); // 940915 0x06c41440 + } + #ifdef _PE_DTO_DUMP_ + WBDEBUG(("[HHDTOAGC] **rssi=%d, high gain mode=%d", rssi, high_gain_mode)); + #endif + } +} + +void TxPwrControl(MTO_FUNC_INPUT) +{ + s32 rssi; + hw_data_t *pHwData = MTO_HAL(); + + sme_get_rssi(MTO_FUNC_INPUT_DATA, &rssi); + if( (RF_WB_242 == pHwData->phy_type) || + (RF_WB_242_1 == pHwData->phy_type) ) // 20060619.5 Add + { + static u8 high_gain_mode; //this is for winbond RF switch LNA + //using different register setting + + if (high_gain_mode==1) + { + if( rssi > MTO_DATA().RSSI_high ) + { + //hw_set_dxx_reg(phw_data, 0x0C, 0xf8f52230); + //hw_set_dxx_reg(phw_data, 0x20, 0x05541640); + high_gain_mode=0; + } + else + { + //hw_set_dxx_reg(phw_data, 0x0C, 0xf8f51830); + //hw_set_dxx_reg(phw_data, 0x20, 0x05543E40); + high_gain_mode=1; + } + } + else //if (high_gain_mode==0) + { + if( rssi < MTO_DATA().RSSI_low ) + { + //hw_set_dxx_reg(phw_data, 0x0C, 0xf8f51830); + //hw_set_dxx_reg(phw_data, 0x20, 0x05543E40); + high_gain_mode=1; + } + else + { + //hw_set_dxx_reg(phw_data, 0x0C, 0xf8f52230); + //hw_set_dxx_reg(phw_data, 0x20, 0x05541640); + high_gain_mode=0; + } + } + + // Always high gain 20051014. Using the initial value only. + multiagc(MTO_FUNC_INPUT_DATA, high_gain_mode); + } +} + + +u8 CalcNewRate(MTO_FUNC_INPUT, u8 old_rate, u32 retry_cnt, u32 tx_frag_cnt) +{ + int i; + u8 new_rate; + u32 retry_rate; + int TxThrouput1, TxThrouput2, TxThrouput3, BestThroupht; + + if(tx_frag_cnt < MTOPARA_TXCOUNT_TH_FOR_CALC_RATE()) //too few packets transmit + { + return 0xff; + } + retry_rate = Divide(retry_cnt * 100, tx_frag_cnt); + + if(retry_rate > 90) retry_rate = 90; //always truncate to 90% due to lookup table size + #ifdef _PE_DTO_DUMP_ + WBDEBUG(("##### Current level =%d, Retry count =%d, Frag count =%d\n", + old_rate, retry_cnt, tx_frag_cnt)); + WBDEBUG(("*##* Retry rate =%d, throughput =%d\n", + retry_rate, Rate_PER_TBL[retry_rate][old_rate])); + WBDEBUG(("TxRateRec.tx_rate =%d, Retry rate = %d, throughput = %d\n", + TxRateRec.tx_rate, TxRateRec.tx_retry_rate, + Rate_PER_TBL[TxRateRec.tx_retry_rate][Level2PerTbl[TxRateRec.tx_rate]])); + WBDEBUG(("old_rate-1 =%d, Retry rate = %d, throughput = %d\n", + old_rate-1, retryrate_rec[old_rate-1], + Rate_PER_TBL[retryrate_rec[old_rate-1]][old_rate-1])); + WBDEBUG(("old_rate+1 =%d, Retry rate = %d, throughput = %d\n", + old_rate+1, retryrate_rec[old_rate+1], + Rate_PER_TBL[retryrate_rec[old_rate+1]][old_rate+1])); + #endif + + //following is for record the retry rate at the different data rate + if (abs(retry_rate-retryrate_rec[old_rate])<50)//---the per TH + retryrate_rec[old_rate] = retry_rate; //update retry rate + else + { + for (i=0;i<MTO_DataRateAvailableLevel;i++) //reset all retry rate + retryrate_rec[i]=0; + retryrate_rec[old_rate] = retry_rate; + #ifdef _PE_DTO_DUMP_ + WBDEBUG(("Reset retry rate table\n")); + #endif + } + + if(TxRateRec.tx_rate > old_rate) //Decrease Tx Rate + { + TxThrouput1 = Rate_PER_TBL[TxRateRec.tx_retry_rate][Level2PerTbl[TxRateRec.tx_rate]]; + TxThrouput2 = Rate_PER_TBL[retry_rate][Level2PerTbl[old_rate]]; + if(TxThrouput1 > TxThrouput2) + { + new_rate = TxRateRec.tx_rate; + BestThroupht = TxThrouput1; + } + else + { + new_rate = old_rate; + BestThroupht = TxThrouput2; + } + if((old_rate > 0) &&(retry_rate>MTOPARA_TXRATE_DEC_TH())) //Min Rate + { + TxThrouput3 = Rate_PER_TBL[retryrate_rec[old_rate-1]][Level2PerTbl[old_rate-1]]; + if(BestThroupht < TxThrouput3) + { + new_rate = old_rate - 1; + #ifdef _PE_DTO_DUMP_ + WBDEBUG(("--------\n")); + #endif + BestThroupht = TxThrouput3; + } + } + } + else if(TxRateRec.tx_rate < old_rate) //Increase Tx Rate + { + TxThrouput1 = Rate_PER_TBL[TxRateRec.tx_retry_rate][Level2PerTbl[TxRateRec.tx_rate]]; + TxThrouput2 = Rate_PER_TBL[retry_rate][Level2PerTbl[old_rate]]; + if(TxThrouput1 > TxThrouput2) + { + new_rate = TxRateRec.tx_rate; + BestThroupht = TxThrouput1; + } + else + { + new_rate = old_rate; + BestThroupht = TxThrouput2; + } + if ((old_rate < MTO_DataRateAvailableLevel - 1)&&(retry_rate<MTOPARA_TXRATE_INC_TH())) + { + //TxThrouput3 = Rate_PER_TBL[retryrate_rec[old_rate+1]][Level2PerTbl[old_rate+1]]; + if (retryrate_rec[old_rate+1] > MTOPARA_TXRETRYRATE_REDUCE()) + TxThrouput3 = Rate_PER_TBL[retryrate_rec[old_rate+1]-MTOPARA_TXRETRYRATE_REDUCE()][Level2PerTbl[old_rate+1]]; + else + TxThrouput3 = Rate_PER_TBL[retryrate_rec[old_rate+1]][Level2PerTbl[old_rate+1]]; + if(BestThroupht < TxThrouput3) + { + new_rate = old_rate + 1; + #ifdef _PE_DTO_DUMP_ + WBDEBUG(("++++++++++\n")); + #endif + BestThroupht = TxThrouput3; + } + } + } + else //Tx Rate no change + { + TxThrouput2 = Rate_PER_TBL[retry_rate][Level2PerTbl[old_rate]]; + new_rate = old_rate; + BestThroupht = TxThrouput2; + + if (retry_rate <MTOPARA_TXRATE_EQ_TH()) //th for change higher rate + { + if(old_rate < MTO_DataRateAvailableLevel - 1) + { + //TxThrouput3 = Rate_PER_TBL[retryrate_rec[old_rate+1]][Level2PerTbl[old_rate+1]]; + if (retryrate_rec[old_rate+1] > MTOPARA_TXRETRYRATE_REDUCE()) + TxThrouput3 = Rate_PER_TBL[retryrate_rec[old_rate+1]-MTOPARA_TXRETRYRATE_REDUCE()][Level2PerTbl[old_rate+1]]; + else + TxThrouput3 = Rate_PER_TBL[retryrate_rec[old_rate+1]][Level2PerTbl[old_rate+1]]; + if(BestThroupht < TxThrouput3) + { + new_rate = old_rate + 1; + BestThroupht = TxThrouput3; + #ifdef _PE_DTO_DUMP_ + WBDEBUG(("=++++++++++\n")); + #endif + } + } + } + else + if(old_rate > 0) //Min Rate + { + TxThrouput3 = Rate_PER_TBL[retryrate_rec[old_rate-1]][Level2PerTbl[old_rate-1]]; + if(BestThroupht < TxThrouput3) + { + new_rate = old_rate - 1; + #ifdef _PE_DTO_DUMP_ + WBDEBUG(("=--------\n")); + #endif + BestThroupht = TxThrouput3; + } + } + } + + if (!LOCAL_IS_IBSS_MODE()) + { + max_rssi_rate = GetMaxRateLevelFromRSSI(); + #ifdef _PE_DTO_DUMP_ + WBDEBUG(("[MTO]:RSSI2Rate=%d\n", MTO_Data_Rate_Tbl[max_rssi_rate])); + #endif + if(new_rate > max_rssi_rate) + new_rate = max_rssi_rate; + } + + //save new rate; + TxRateRec.tx_rate = old_rate; + TxRateRec.tx_retry_rate = (u8) retry_rate; + TxRetryRate = retry_rate; + return new_rate; +} + +void SmoothRSSI(s32 new_rssi) +{ + RSSISmoothed = RSSISmoothed + new_rssi - RSSIBuf[RSSIBufIndex]; + RSSIBuf[RSSIBufIndex] = new_rssi; + RSSIBufIndex = (RSSIBufIndex + 1) % 10; +} + +u8 GetMaxRateLevelFromRSSI(void) +{ + u8 i; + u8 TxRate; + + for(i=0;i<RSSI2RATE_SIZE;i++) + { + if(RSSISmoothed > RSSI2RateTbl[i].RSSI) + break; + } + #ifdef _PE_DTO_DUMP_ + WBDEBUG(("[MTO]:RSSI=%d\n", Divide(RSSISmoothed, 10))); + #endif + if(i < RSSI2RATE_SIZE) + TxRate = RSSI2RateTbl[i].TxRate; + else + TxRate = 2; //divided by 2 = 1Mbps + + for(i=MTO_DataRateAvailableLevel-1;i>0;i--) + { + if(TxRate >=MTO_Data_Rate_Tbl[i]) + break; + } + return i; +} + +//=========================================================================== +// Description: +// If we enable DTO, we will ignore the tx count with different tx rate from +// DTO rate. This is because when we adjust DTO tx rate, there could be some +// packets in the tx queue with previous tx rate +void MTO_SetTxCount(MTO_FUNC_INPUT, u8 tx_rate, u8 index) +{ + MTO_TXFLOWCOUNT()++; + if ((MTO_ENABLE==1) && (MTO_RATE_CHANGE_ENABLE()==1)) + { + if(tx_rate == MTO_DATA_RATE()) + { + if (index == 0) + { + if (boSparseTxTraffic) + MTO_HAL()->dto_tx_frag_count += MTOPARA_PERIODIC_CHECK_CYCLE(); + else + MTO_HAL()->dto_tx_frag_count += 1; + } + else + { + if (index<8) + { + MTO_HAL()->dto_tx_retry_count += index; + MTO_HAL()->dto_tx_frag_count += (index+1); + } + else + { + MTO_HAL()->dto_tx_retry_count += 7; + MTO_HAL()->dto_tx_frag_count += 7; + } + } + } + else if(MTO_DATA_RATE()>48 && tx_rate ==48) + {//ALFRED + if (index<3) //for reduciing data rate scheme , + //do not calcu different data rate + //3 is the reducing data rate at retry + { + MTO_HAL()->dto_tx_retry_count += index; + MTO_HAL()->dto_tx_frag_count += (index+1); + } + else + { + MTO_HAL()->dto_tx_retry_count += 3; + MTO_HAL()->dto_tx_frag_count += 3; + } + + } + } + else + { + MTO_HAL()->dto_tx_retry_count += index; + MTO_HAL()->dto_tx_frag_count += (index+1); + } + TotalTxPkt ++; + TotalTxPktRetry += (index+1); + + PeriodTotalTxPkt ++; + PeriodTotalTxPktRetry += (index+1); +} + +u8 MTO_GetTxFallbackRate(MTO_FUNC_INPUT) +{ + return MTO_DATA_FALLBACK_RATE(); +} + + +//=========================================================================== +// MTO_TxFailed -- +// +// Description: +// Failure of transmitting a packet indicates that certain MTO parmeters +// may need to be adjusted. This function is called when NIC just failed +// to transmit a packet or when MSDULifeTime expired. +// +// Arguments: +// Adapter - The pointer to the Miniport Adapter Context +// +// Return Value: +// None +//============================================================================ +void MTO_TxFailed(MTO_FUNC_INPUT) +{ + return; +} + +int Divide(int a, int b) +{ + if (b==0) b=1; + return a/b; +} + + diff --git a/drivers/staging/winbond/mto.h b/drivers/staging/winbond/mto.h new file mode 100644 index 000000000000..f47936f46d1e --- /dev/null +++ b/drivers/staging/winbond/mto.h @@ -0,0 +1,265 @@ +//================================================================== +// MTO.H +// +// Revision history +//================================= +// 20030110 UN20 Pete Chao +// Initial Release +// +// Copyright (c) 2003 Winbond Electronics Corp. All rights reserved. +//================================================================== +#ifndef __MTO_H__ +#define __MTO_H__ + +#define MTO_DEFAULT_TH_CNT 5 +#define MTO_DEFAULT_TH_SQ3 112 //OLD IS 13 reference JohnXu +#define MTO_DEFAULT_TH_IDLE_SLOT 15 +#define MTO_DEFAULT_TH_PR_INTERF 30 +#define MTO_DEFAULT_TMR_AGING 25 // unit: slot time 10 reference JohnXu +#define MTO_DEFAULT_TMR_PERIODIC 5 // unit: slot time + +#define MTO_ANTENNA_DIVERSITY_OFF 0 +#define MTO_ANTENNA_DIVERSITY_ON 1 + +// LA20040210_DTO kevin +//#define MTO_PREAMBLE_LONG 0 +//#define MTO_PREAMBLE_SHORT 1 +#define MTO_PREAMBLE_LONG WLAN_PREAMBLE_TYPE_LONG +#define MTO_PREAMBLE_SHORT WLAN_PREAMBLE_TYPE_SHORT + +typedef enum { + TOGGLE_STATE_IDLE = 0, + TOGGLE_STATE_WAIT0 = 1, + TOGGLE_STATE_WAIT1 = 2, + TOGGLE_STATE_MAKEDESISION = 3, + TOGGLE_STATE_BKOFF = 4 +} TOGGLE_STATE; + +typedef enum { + RATE_CHGSTATE_IDLE = 0, + RATE_CHGSTATE_CALCULATE = 1, + RATE_CHGSTATE_BACKOFF = 2 +} TX_RATE_REDUCTION_STATE; + +//============================================================================ +// struct _MTOParameters -- +// +// Defines the parameters used in the MAC Throughput Optimization algorithm +//============================================================================ +typedef struct _MTO_PARAMETERS +{ + u8 Th_Fixant; + u8 Th_Cnt; + u8 Th_SQ3; + u8 Th_IdleSlot; + + u16 Tmr_Aging; + u8 Th_PrInterf; + u8 Tmr_Periodic; + + //--------- wkchen added ------------- + u32 TxFlowCount; //to judge what kind the tx flow(sparse or busy) is + //------------------------------------------------ + + //--------- DTO threshold parameters ------------- + u16 DTO_PeriodicCheckCycle; + u16 DTO_RssiThForAntDiv; + + u16 DTO_TxCountThForCalcNewRate; + u16 DTO_TxRateIncTh; + + u16 DTO_TxRateDecTh; + u16 DTO_TxRateEqTh; + + u16 DTO_TxRateBackOff; + u16 DTO_TxRetryRateReduce; + + u16 DTO_TxPowerIndex; //0 ~ 31 + u16 reserved_1; + //------------------------------------------------ + + u8 PowerChangeEnable; + u8 AntDiversityEnable; + u8 Ant_mac; + u8 Ant_div; + + u8 CCA_Mode; + u8 CCA_Mode_Setup; + u8 Preamble_Type; + u8 PreambleChangeEnable; + + u8 DataRateLevel; + u8 DataRateChangeEnable; + u8 FragThresholdLevel; + u8 FragThresholdChangeEnable; + + u16 RTSThreshold; + u16 RTSThreshold_Setup; + + u32 AvgIdleSlot; + u32 Pr_Interf; + u32 AvgGapBtwnInterf; + + u8 RTSChangeEnable; + u8 Ant_sel; + u8 aging_timeout; + u8 reserved_2; + + u32 Cnt_Ant[2]; + u32 SQ_Ant[2]; + +// 20040510 remove from globe vairable + u32 TmrCnt; + u32 BackoffTmr; + TOGGLE_STATE ToggleState; + TX_RATE_REDUCTION_STATE TxRateReductionState; + + u8 Last_Rate; + u8 Co_efficent; + u8 FallbackRateLevel; + u8 OfdmRateLevel; + + u8 RatePolicy; + u8 reserved_3[3]; + + // For RSSI turning + s32 RSSI_high; + s32 RSSI_low; + +} MTO_PARAMETERS, *PMTO_PARAMETERS; + + +#define MTO_FUNC_INPUT PWB32_ADAPTER Adapter +#define MTO_FUNC_INPUT_DATA Adapter +#define MTO_DATA() (Adapter->sMtoPara) +#define MTO_HAL() (&Adapter->sHwData) +#define MTO_SET_PREAMBLE_TYPE(x) // 20040511 Turbo mark LM_PREAMBLE_TYPE(&pcore_data->lm_data) = (x) +#define MTO_ENABLE (Adapter->sLocalPara.TxRateMode == RATE_AUTO) +#define MTO_TXPOWER_FROM_EEPROM (Adapter->sHwData.PowerIndexFromEEPROM) +#define LOCAL_ANTENNA_NO() (Adapter->sLocalPara.bAntennaNo) +#define LOCAL_IS_CONNECTED() (Adapter->sLocalPara.wConnectedSTAindex != 0) +#define LOCAL_IS_IBSS_MODE() (Adapter->asBSSDescriptElement[Adapter->sLocalPara.wConnectedSTAindex].bBssType == IBSS_NET) +#define MTO_INITTXRATE_MODE (Adapter->sHwData.SoftwareSet&0x2) //bit 1 +// 20040510 Turbo add +#define MTO_TMR_CNT() MTO_DATA().TmrCnt +#define MTO_TOGGLE_STATE() MTO_DATA().ToggleState +#define MTO_TX_RATE_REDUCTION_STATE() MTO_DATA().TxRateReductionState +#define MTO_BACKOFF_TMR() MTO_DATA().BackoffTmr +#define MTO_LAST_RATE() MTO_DATA().Last_Rate +#define MTO_CO_EFFICENT() MTO_DATA().Co_efficent + +#define MTO_TH_CNT() MTO_DATA().Th_Cnt +#define MTO_TH_SQ3() MTO_DATA().Th_SQ3 +#define MTO_TH_IDLE_SLOT() MTO_DATA().Th_IdleSlot +#define MTO_TH_PR_INTERF() MTO_DATA().Th_PrInterf + +#define MTO_TMR_AGING() MTO_DATA().Tmr_Aging +#define MTO_TMR_PERIODIC() MTO_DATA().Tmr_Periodic + +#define MTO_POWER_CHANGE_ENABLE() MTO_DATA().PowerChangeEnable +#define MTO_ANT_DIVERSITY_ENABLE() Adapter->sLocalPara.boAntennaDiversity +#define MTO_ANT_MAC() MTO_DATA().Ant_mac +#define MTO_ANT_DIVERSITY() MTO_DATA().Ant_div +#define MTO_CCA_MODE() MTO_DATA().CCA_Mode +#define MTO_CCA_MODE_SETUP() MTO_DATA().CCA_Mode_Setup +#define MTO_PREAMBLE_TYPE() MTO_DATA().Preamble_Type +#define MTO_PREAMBLE_CHANGE_ENABLE() MTO_DATA().PreambleChangeEnable + +#define MTO_RATE_LEVEL() MTO_DATA().DataRateLevel +#define MTO_FALLBACK_RATE_LEVEL() MTO_DATA().FallbackRateLevel +#define MTO_OFDM_RATE_LEVEL() MTO_DATA().OfdmRateLevel +#define MTO_RATE_CHANGE_ENABLE() MTO_DATA().DataRateChangeEnable +#define MTO_FRAG_TH_LEVEL() MTO_DATA().FragThresholdLevel +#define MTO_FRAG_CHANGE_ENABLE() MTO_DATA().FragThresholdChangeEnable +#define MTO_RTS_THRESHOLD() MTO_DATA().RTSThreshold +#define MTO_RTS_CHANGE_ENABLE() MTO_DATA().RTSChangeEnable +#define MTO_RTS_THRESHOLD_SETUP() MTO_DATA().RTSThreshold_Setup + +#define MTO_AVG_IDLE_SLOT() MTO_DATA().AvgIdleSlot +#define MTO_PR_INTERF() MTO_DATA().Pr_Interf +#define MTO_AVG_GAP_BTWN_INTERF() MTO_DATA().AvgGapBtwnInterf + +#define MTO_ANT_SEL() MTO_DATA().Ant_sel +#define MTO_CNT_ANT(x) MTO_DATA().Cnt_Ant[(x)] +#define MTO_SQ_ANT(x) MTO_DATA().SQ_Ant[(x)] +#define MTO_AGING_TIMEOUT() MTO_DATA().aging_timeout + + +#define MTO_TXFLOWCOUNT() MTO_DATA().TxFlowCount +//--------- DTO threshold parameters ------------- +#define MTOPARA_PERIODIC_CHECK_CYCLE() MTO_DATA().DTO_PeriodicCheckCycle +#define MTOPARA_RSSI_TH_FOR_ANTDIV() MTO_DATA().DTO_RssiThForAntDiv +#define MTOPARA_TXCOUNT_TH_FOR_CALC_RATE() MTO_DATA().DTO_TxCountThForCalcNewRate +#define MTOPARA_TXRATE_INC_TH() MTO_DATA().DTO_TxRateIncTh +#define MTOPARA_TXRATE_DEC_TH() MTO_DATA().DTO_TxRateDecTh +#define MTOPARA_TXRATE_EQ_TH() MTO_DATA().DTO_TxRateEqTh +#define MTOPARA_TXRATE_BACKOFF() MTO_DATA().DTO_TxRateBackOff +#define MTOPARA_TXRETRYRATE_REDUCE() MTO_DATA().DTO_TxRetryRateReduce +#define MTOPARA_TXPOWER_INDEX() MTO_DATA().DTO_TxPowerIndex +//------------------------------------------------ + + +extern u8 MTO_Data_Rate_Tbl[]; +extern u16 MTO_Frag_Th_Tbl[]; + +#define MTO_DATA_RATE() MTO_Data_Rate_Tbl[MTO_RATE_LEVEL()] +#define MTO_DATA_FALLBACK_RATE() MTO_Data_Rate_Tbl[MTO_FALLBACK_RATE_LEVEL()] //next level +#define MTO_FRAG_TH() MTO_Frag_Th_Tbl[MTO_FRAG_TH_LEVEL()] + +typedef struct { + u8 tx_rate; + u8 tx_retry_rate; +} TXRETRY_REC; + +typedef struct _STATISTICS_INFO { + u32 Rate54M; + u32 Rate48M; + u32 Rate36M; + u32 Rate24M; + u32 Rate18M; + u32 Rate12M; + u32 Rate9M; + u32 Rate6M; + u32 Rate11MS; + u32 Rate11ML; + u32 Rate55MS; + u32 Rate55ML; + u32 Rate2MS; + u32 Rate2ML; + u32 Rate1M; + u32 Rate54MOK; + u32 Rate48MOK; + u32 Rate36MOK; + u32 Rate24MOK; + u32 Rate18MOK; + u32 Rate12MOK; + u32 Rate9MOK; + u32 Rate6MOK; + u32 Rate11MSOK; + u32 Rate11MLOK; + u32 Rate55MSOK; + u32 Rate55MLOK; + u32 Rate2MSOK; + u32 Rate2MLOK; + u32 Rate1MOK; + u32 SQ3; + s32 RSSIAVG; + s32 RSSIMAX; + s32 TXRATE; + s32 TxRetryRate; + s32 BSS_PK_CNT; + s32 NIDLESLOT; + s32 SLOT_CNT; + s32 INTERF_CNT; + s32 GAP_CNT; + s32 DS_EVM; + s32 RcvBeaconNum; + s32 RXRATE; + s32 RxBytes; + s32 TxBytes; + s32 Antenna; +} STATISTICS_INFO, *PSTATISTICS_INFO; + +#endif //__MTO_H__ + + diff --git a/drivers/staging/winbond/mto_f.h b/drivers/staging/winbond/mto_f.h new file mode 100644 index 000000000000..30b3df2ccb3c --- /dev/null +++ b/drivers/staging/winbond/mto_f.h @@ -0,0 +1,7 @@ +extern void MTO_Init(PWB32_ADAPTER); +extern void MTO_PeriodicTimerExpired(PWB32_ADAPTER); +extern void MTO_SetDTORateRange(PWB32_ADAPTER, u8 *, u8); +extern u8 MTO_GetTxRate(MTO_FUNC_INPUT, u32 fpdu_len); +extern u8 MTO_GetTxFallbackRate(MTO_FUNC_INPUT); +extern void MTO_SetTxCount(MTO_FUNC_INPUT, u8 t0, u8 index); + diff --git a/drivers/staging/winbond/os_common.h b/drivers/staging/winbond/os_common.h new file mode 100644 index 000000000000..e24ff41e871e --- /dev/null +++ b/drivers/staging/winbond/os_common.h @@ -0,0 +1,2 @@ +#include "linux/sysdef.h" + diff --git a/drivers/staging/winbond/phy_calibration.c b/drivers/staging/winbond/phy_calibration.c new file mode 100644 index 000000000000..272a65066aba --- /dev/null +++ b/drivers/staging/winbond/phy_calibration.c @@ -0,0 +1,1759 @@ +/* + * phy_302_calibration.c + * + * Copyright (C) 2002, 2005 Winbond Electronics Corp. + * + * modification history + * --------------------------------------------------------------------------- + * 0.01.001, 2003-04-16, Kevin created + * + */ + +/****************** INCLUDE FILES SECTION ***********************************/ +#include "os_common.h" +#include "phy_calibration.h" + + +/****************** DEBUG CONSTANT AND MACRO SECTION ************************/ + +/****************** LOCAL CONSTANT AND MACRO SECTION ************************/ +#define LOOP_TIMES 20 +#define US 1000//MICROSECOND + +#define AG_CONST 0.6072529350 +#define FIXED(X) ((s32)((X) * 32768.0)) +#define DEG2RAD(X) 0.017453 * (X) + +/****************** LOCAL TYPE DEFINITION SECTION ***************************/ +typedef s32 fixed; /* 16.16 fixed-point */ + +static const fixed Angles[]= +{ + FIXED(DEG2RAD(45.0)), FIXED(DEG2RAD(26.565)), FIXED(DEG2RAD(14.0362)), + FIXED(DEG2RAD(7.12502)), FIXED(DEG2RAD(3.57633)), FIXED(DEG2RAD(1.78991)), + FIXED(DEG2RAD(0.895174)),FIXED(DEG2RAD(0.447614)),FIXED(DEG2RAD(0.223811)), + FIXED(DEG2RAD(0.111906)),FIXED(DEG2RAD(0.055953)),FIXED(DEG2RAD(0.027977)) +}; + +/****************** LOCAL FUNCTION DECLARATION SECTION **********************/ +//void _phy_rf_write_delay(hw_data_t *phw_data); +//void phy_init_rf(hw_data_t *phw_data); + +/****************** FUNCTION DEFINITION SECTION *****************************/ + +s32 _s13_to_s32(u32 data) +{ + u32 val; + + val = (data & 0x0FFF); + + if ((data & BIT(12)) != 0) + { + val |= 0xFFFFF000; + } + + return ((s32) val); +} + +u32 _s32_to_s13(s32 data) +{ + u32 val; + + if (data > 4095) + { + data = 4095; + } + else if (data < -4096) + { + data = -4096; + } + + val = data & 0x1FFF; + + return val; +} + +/****************************************************************************/ +s32 _s4_to_s32(u32 data) +{ + s32 val; + + val = (data & 0x0007); + + if ((data & BIT(3)) != 0) + { + val |= 0xFFFFFFF8; + } + + return val; +} + +u32 _s32_to_s4(s32 data) +{ + u32 val; + + if (data > 7) + { + data = 7; + } + else if (data < -8) + { + data = -8; + } + + val = data & 0x000F; + + return val; +} + +/****************************************************************************/ +s32 _s5_to_s32(u32 data) +{ + s32 val; + + val = (data & 0x000F); + + if ((data & BIT(4)) != 0) + { + val |= 0xFFFFFFF0; + } + + return val; +} + +u32 _s32_to_s5(s32 data) +{ + u32 val; + + if (data > 15) + { + data = 15; + } + else if (data < -16) + { + data = -16; + } + + val = data & 0x001F; + + return val; +} + +/****************************************************************************/ +s32 _s6_to_s32(u32 data) +{ + s32 val; + + val = (data & 0x001F); + + if ((data & BIT(5)) != 0) + { + val |= 0xFFFFFFE0; + } + + return val; +} + +u32 _s32_to_s6(s32 data) +{ + u32 val; + + if (data > 31) + { + data = 31; + } + else if (data < -32) + { + data = -32; + } + + val = data & 0x003F; + + return val; +} + +/****************************************************************************/ +s32 _s9_to_s32(u32 data) +{ + s32 val; + + val = data & 0x00FF; + + if ((data & BIT(8)) != 0) + { + val |= 0xFFFFFF00; + } + + return val; +} + +u32 _s32_to_s9(s32 data) +{ + u32 val; + + if (data > 255) + { + data = 255; + } + else if (data < -256) + { + data = -256; + } + + val = data & 0x01FF; + + return val; +} + +/****************************************************************************/ +s32 _floor(s32 n) +{ + if (n > 0) + { + n += 5; + } + else + { + n -= 5; + } + + return (n/10); +} + +/****************************************************************************/ +// The following code is sqare-root function. +// sqsum is the input and the output is sq_rt; +// The maximum of sqsum = 2^27 -1; +u32 _sqrt(u32 sqsum) +{ + u32 sq_rt; + + int g0, g1, g2, g3, g4; + int seed; + int next; + int step; + + g4 = sqsum / 100000000; + g3 = (sqsum - g4*100000000) /1000000; + g2 = (sqsum - g4*100000000 - g3*1000000) /10000; + g1 = (sqsum - g4*100000000 - g3*1000000 - g2*10000) /100; + g0 = (sqsum - g4*100000000 - g3*1000000 - g2*10000 - g1*100); + + next = g4; + step = 0; + seed = 0; + while (((seed+1)*(step+1)) <= next) + { + step++; + seed++; + } + + sq_rt = seed * 10000; + next = (next-(seed*step))*100 + g3; + + step = 0; + seed = 2 * seed * 10; + while (((seed+1)*(step+1)) <= next) + { + step++; + seed++; + } + + sq_rt = sq_rt + step * 1000; + next = (next - seed * step) * 100 + g2; + seed = (seed + step) * 10; + step = 0; + while (((seed+1)*(step+1)) <= next) + { + step++; + seed++; + } + + sq_rt = sq_rt + step * 100; + next = (next - seed * step) * 100 + g1; + seed = (seed + step) * 10; + step = 0; + + while (((seed+1)*(step+1)) <= next) + { + step++; + seed++; + } + + sq_rt = sq_rt + step * 10; + next = (next - seed* step) * 100 + g0; + seed = (seed + step) * 10; + step = 0; + + while (((seed+1)*(step+1)) <= next) + { + step++; + seed++; + } + + sq_rt = sq_rt + step; + + return sq_rt; +} + +/****************************************************************************/ +void _sin_cos(s32 angle, s32 *sin, s32 *cos) +{ + fixed X, Y, TargetAngle, CurrAngle; + unsigned Step; + + X=FIXED(AG_CONST); // AG_CONST * cos(0) + Y=0; // AG_CONST * sin(0) + TargetAngle=abs(angle); + CurrAngle=0; + + for (Step=0; Step < 12; Step++) + { + fixed NewX; + + if(TargetAngle > CurrAngle) + { + NewX=X - (Y >> Step); + Y=(X >> Step) + Y; + X=NewX; + CurrAngle += Angles[Step]; + } + else + { + NewX=X + (Y >> Step); + Y=-(X >> Step) + Y; + X=NewX; + CurrAngle -= Angles[Step]; + } + } + + if (angle > 0) + { + *cos = X; + *sin = Y; + } + else + { + *cos = X; + *sin = -Y; + } +} + + +void _reset_rx_cal(hw_data_t *phw_data) +{ + u32 val; + + hw_get_dxx_reg(phw_data, 0x54, &val); + + if (phw_data->revision == 0x2002) // 1st-cut + { + val &= 0xFFFF0000; + } + else // 2nd-cut + { + val &= 0x000003FF; + } + + hw_set_dxx_reg(phw_data, 0x54, val); +} + + +// ************for winbond calibration********* +// + +// +// +// ********************************************* +void _rxadc_dc_offset_cancellation_winbond(hw_data_t *phw_data, u32 frequency) +{ + u32 reg_agc_ctrl3; + u32 reg_a_acq_ctrl; + u32 reg_b_acq_ctrl; + u32 val; + + PHY_DEBUG(("[CAL] -> [1]_rxadc_dc_offset_cancellation()\n")); + phy_init_rf(phw_data); + + // set calibration channel + if( (RF_WB_242 == phw_data->phy_type) || + (RF_WB_242_1 == phw_data->phy_type) ) // 20060619.5 Add + { + if ((frequency >= 2412) && (frequency <= 2484)) + { + // w89rf242 change frequency to 2390Mhz + PHY_DEBUG(("[CAL] W89RF242/11G/Channel=2390Mhz\n")); + phy_set_rf_data(phw_data, 3, (3<<24)|0x025586); + + } + } + else + { + + } + + // reset cancel_dc_i[9:5] and cancel_dc_q[4:0] in register DC_Cancel + hw_get_dxx_reg(phw_data, 0x5C, &val); + val &= ~(0x03FF); + hw_set_dxx_reg(phw_data, 0x5C, val); + + // reset the TX and RX IQ calibration data + hw_set_dxx_reg(phw_data, 0x3C, 0); + hw_set_dxx_reg(phw_data, 0x54, 0); + + hw_set_dxx_reg(phw_data, 0x58, 0x30303030); // IQ_Alpha Changed + + // a. Disable AGC + hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, ®_agc_ctrl3); + reg_agc_ctrl3 &= ~BIT(2); + reg_agc_ctrl3 |= (MASK_LNA_FIX_GAIN|MASK_AGC_FIX); + hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3); + + hw_get_dxx_reg(phw_data, REG_AGC_CTRL5, &val); + val |= MASK_AGC_FIX_GAIN; + hw_set_dxx_reg(phw_data, REG_AGC_CTRL5, val); + + // b. Turn off BB RX + hw_get_dxx_reg(phw_data, REG_A_ACQ_CTRL, ®_a_acq_ctrl); + reg_a_acq_ctrl |= MASK_AMER_OFF_REG; + hw_set_dxx_reg(phw_data, REG_A_ACQ_CTRL, reg_a_acq_ctrl); + + hw_get_dxx_reg(phw_data, REG_B_ACQ_CTRL, ®_b_acq_ctrl); + reg_b_acq_ctrl |= MASK_BMER_OFF_REG; + hw_set_dxx_reg(phw_data, REG_B_ACQ_CTRL, reg_b_acq_ctrl); + + // c. Make sure MAC is in receiving mode + // d. Turn ON ADC calibration + // - ADC calibrator is triggered by this signal rising from 0 to 1 + hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &val); + val &= ~MASK_ADC_DC_CAL_STR; + hw_set_dxx_reg(phw_data, REG_MODE_CTRL, val); + + val |= MASK_ADC_DC_CAL_STR; + hw_set_dxx_reg(phw_data, REG_MODE_CTRL, val); + pa_stall_execution(US); // *MUST* wait for a while + + // e. The result are shown in "adc_dc_cal_i[8:0] and adc_dc_cal_q[8:0]" +#ifdef _DEBUG + hw_get_dxx_reg(phw_data, REG_OFFSET_READ, &val); + PHY_DEBUG(("[CAL] REG_OFFSET_READ = 0x%08X\n", val)); + + PHY_DEBUG(("[CAL] ** adc_dc_cal_i = %d (0x%04X)\n", + _s9_to_s32(val&0x000001FF), val&0x000001FF)); + PHY_DEBUG(("[CAL] ** adc_dc_cal_q = %d (0x%04X)\n", + _s9_to_s32((val&0x0003FE00)>>9), (val&0x0003FE00)>>9)); +#endif + + hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &val); + val &= ~MASK_ADC_DC_CAL_STR; + hw_set_dxx_reg(phw_data, REG_MODE_CTRL, val); + + // f. Turn on BB RX + //hw_get_dxx_reg(phw_data, REG_A_ACQ_CTRL, ®_a_acq_ctrl); + reg_a_acq_ctrl &= ~MASK_AMER_OFF_REG; + hw_set_dxx_reg(phw_data, REG_A_ACQ_CTRL, reg_a_acq_ctrl); + + //hw_get_dxx_reg(phw_data, REG_B_ACQ_CTRL, ®_b_acq_ctrl); + reg_b_acq_ctrl &= ~MASK_BMER_OFF_REG; + hw_set_dxx_reg(phw_data, REG_B_ACQ_CTRL, reg_b_acq_ctrl); + + // g. Enable AGC + //hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &val); + reg_agc_ctrl3 |= BIT(2); + reg_agc_ctrl3 &= ~(MASK_LNA_FIX_GAIN|MASK_AGC_FIX); + hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3); +} + +//////////////////////////////////////////////////////// +void _txidac_dc_offset_cancellation_winbond(hw_data_t *phw_data) +{ + u32 reg_agc_ctrl3; + u32 reg_mode_ctrl; + u32 reg_dc_cancel; + s32 iqcal_image_i; + s32 iqcal_image_q; + u32 sqsum; + s32 mag_0; + s32 mag_1; + s32 fix_cancel_dc_i = 0; + u32 val; + int loop; + + PHY_DEBUG(("[CAL] -> [2]_txidac_dc_offset_cancellation()\n")); + + // a. Set to "TX calibration mode" + + //0x01 0xEE3FC2 ; 3B8FF ; Calibration (6a). enable TX IQ calibration loop circuits + phy_set_rf_data(phw_data, 1, (1<<24)|0xEE3FC2); + //0x0B 0x1905D6 ; 06417 ; Calibration (6b). enable TX I/Q cal loop squaring circuit + phy_set_rf_data(phw_data, 11, (11<<24)|0x1901D6); + //0x05 0x24C60A ; 09318 ; Calibration (6c). setting TX-VGA gain: TXGCH=2 & GPK=110 --> to be optimized + phy_set_rf_data(phw_data, 5, (5<<24)|0x24C48A); + //0x06 0x06880C ; 01A20 ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized + phy_set_rf_data(phw_data, 6, (6<<24)|0x06890C); + //0x00 0xFDF1C0 ; 3F7C7 ; Calibration (6e). turn on IQ imbalance/Test mode + phy_set_rf_data(phw_data, 0, (0<<24)|0xFDF1C0); + + hw_set_dxx_reg(phw_data, 0x58, 0x30303030); // IQ_Alpha Changed + + // a. Disable AGC + hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, ®_agc_ctrl3); + reg_agc_ctrl3 &= ~BIT(2); + reg_agc_ctrl3 |= (MASK_LNA_FIX_GAIN|MASK_AGC_FIX); + hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3); + + hw_get_dxx_reg(phw_data, REG_AGC_CTRL5, &val); + val |= MASK_AGC_FIX_GAIN; + hw_set_dxx_reg(phw_data, REG_AGC_CTRL5, val); + + // b. set iqcal_mode[1:0] to 0x2 and set iqcal_tone[3:2] to 0 + hw_get_dxx_reg(phw_data, REG_MODE_CTRL, ®_mode_ctrl); + + PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl)); + reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE); + + // mode=2, tone=0 + //reg_mode_ctrl |= (MASK_CALIB_START|2); + + // mode=2, tone=1 + //reg_mode_ctrl |= (MASK_CALIB_START|2|(1<<2)); + + // mode=2, tone=2 + reg_mode_ctrl |= (MASK_CALIB_START|2|(2<<2)); + hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl); + PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl)); + pa_stall_execution(US); + + hw_get_dxx_reg(phw_data, 0x5C, ®_dc_cancel); + PHY_DEBUG(("[CAL] DC_CANCEL (read) = 0x%08X\n", reg_dc_cancel)); + + for (loop = 0; loop < LOOP_TIMES; loop++) + { + PHY_DEBUG(("[CAL] [%d.] ==================================\n", loop)); + + // c. + // reset cancel_dc_i[9:5] and cancel_dc_q[4:0] in register DC_Cancel + reg_dc_cancel &= ~(0x03FF); + PHY_DEBUG(("[CAL] DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel)); + hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel); + pa_stall_execution(US); + + hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val); + PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val)); + + iqcal_image_i = _s13_to_s32(val & 0x00001FFF); + iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13); + sqsum = iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q; + mag_0 = (s32) _sqrt(sqsum); + PHY_DEBUG(("[CAL] mag_0=%d (iqcal_image_i=%d, iqcal_image_q=%d)\n", + mag_0, iqcal_image_i, iqcal_image_q)); + + // d. + reg_dc_cancel |= (1 << CANCEL_DC_I_SHIFT); + PHY_DEBUG(("[CAL] DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel)); + hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel); + pa_stall_execution(US); + + hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val); + PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val)); + + iqcal_image_i = _s13_to_s32(val & 0x00001FFF); + iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13); + sqsum = iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q; + mag_1 = (s32) _sqrt(sqsum); + PHY_DEBUG(("[CAL] mag_1=%d (iqcal_image_i=%d, iqcal_image_q=%d)\n", + mag_1, iqcal_image_i, iqcal_image_q)); + + // e. Calculate the correct DC offset cancellation value for I + if (mag_0 != mag_1) + { + fix_cancel_dc_i = (mag_0*10000) / (mag_0*10000 - mag_1*10000); + } + else + { + if (mag_0 == mag_1) + { + PHY_DEBUG(("[CAL] ***** mag_0 = mag_1 !!\n")); + } + + fix_cancel_dc_i = 0; + } + + PHY_DEBUG(("[CAL] ** fix_cancel_dc_i = %d (0x%04X)\n", + fix_cancel_dc_i, _s32_to_s5(fix_cancel_dc_i))); + + if ((abs(mag_1-mag_0)*6) > mag_0) + { + break; + } + } + + if ( loop >= 19 ) + fix_cancel_dc_i = 0; + + reg_dc_cancel &= ~(0x03FF); + reg_dc_cancel |= (_s32_to_s5(fix_cancel_dc_i) << CANCEL_DC_I_SHIFT); + hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel); + PHY_DEBUG(("[CAL] DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel)); + + // g. + reg_mode_ctrl &= ~MASK_CALIB_START; + hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl); + PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl)); + pa_stall_execution(US); +} + +/////////////////////////////////////////////////////// +void _txqdac_dc_offset_cacellation_winbond(hw_data_t *phw_data) +{ + u32 reg_agc_ctrl3; + u32 reg_mode_ctrl; + u32 reg_dc_cancel; + s32 iqcal_image_i; + s32 iqcal_image_q; + u32 sqsum; + s32 mag_0; + s32 mag_1; + s32 fix_cancel_dc_q = 0; + u32 val; + int loop; + + PHY_DEBUG(("[CAL] -> [3]_txqdac_dc_offset_cacellation()\n")); + //0x01 0xEE3FC2 ; 3B8FF ; Calibration (6a). enable TX IQ calibration loop circuits + phy_set_rf_data(phw_data, 1, (1<<24)|0xEE3FC2); + //0x0B 0x1905D6 ; 06417 ; Calibration (6b). enable TX I/Q cal loop squaring circuit + phy_set_rf_data(phw_data, 11, (11<<24)|0x1901D6); + //0x05 0x24C60A ; 09318 ; Calibration (6c). setting TX-VGA gain: TXGCH=2 & GPK=110 --> to be optimized + phy_set_rf_data(phw_data, 5, (5<<24)|0x24C48A); + //0x06 0x06880C ; 01A20 ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized + phy_set_rf_data(phw_data, 6, (6<<24)|0x06890C); + //0x00 0xFDF1C0 ; 3F7C7 ; Calibration (6e). turn on IQ imbalance/Test mode + phy_set_rf_data(phw_data, 0, (0<<24)|0xFDF1C0); + + hw_set_dxx_reg(phw_data, 0x58, 0x30303030); // IQ_Alpha Changed + + // a. Disable AGC + hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, ®_agc_ctrl3); + reg_agc_ctrl3 &= ~BIT(2); + reg_agc_ctrl3 |= (MASK_LNA_FIX_GAIN|MASK_AGC_FIX); + hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3); + + hw_get_dxx_reg(phw_data, REG_AGC_CTRL5, &val); + val |= MASK_AGC_FIX_GAIN; + hw_set_dxx_reg(phw_data, REG_AGC_CTRL5, val); + + // a. set iqcal_mode[1:0] to 0x3 and set iqcal_tone[3:2] to 0 + hw_get_dxx_reg(phw_data, REG_MODE_CTRL, ®_mode_ctrl); + PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl)); + + //reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE); + reg_mode_ctrl &= ~(MASK_IQCAL_MODE); + reg_mode_ctrl |= (MASK_CALIB_START|3); + hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl); + PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl)); + pa_stall_execution(US); + + hw_get_dxx_reg(phw_data, 0x5C, ®_dc_cancel); + PHY_DEBUG(("[CAL] DC_CANCEL (read) = 0x%08X\n", reg_dc_cancel)); + + for (loop = 0; loop < LOOP_TIMES; loop++) + { + PHY_DEBUG(("[CAL] [%d.] ==================================\n", loop)); + + // b. + // reset cancel_dc_q[4:0] in register DC_Cancel + reg_dc_cancel &= ~(0x001F); + PHY_DEBUG(("[CAL] DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel)); + hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel); + pa_stall_execution(US); + + hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val); + PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val)); + pa_stall_execution(US); + + iqcal_image_i = _s13_to_s32(val & 0x00001FFF); + iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13); + sqsum = iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q; + mag_0 = _sqrt(sqsum); + PHY_DEBUG(("[CAL] mag_0=%d (iqcal_image_i=%d, iqcal_image_q=%d)\n", + mag_0, iqcal_image_i, iqcal_image_q)); + + // c. + reg_dc_cancel |= (1 << CANCEL_DC_Q_SHIFT); + PHY_DEBUG(("[CAL] DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel)); + hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel); + pa_stall_execution(US); + + hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val); + PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val)); + pa_stall_execution(US); + + iqcal_image_i = _s13_to_s32(val & 0x00001FFF); + iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13); + sqsum = iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q; + mag_1 = _sqrt(sqsum); + PHY_DEBUG(("[CAL] mag_1=%d (iqcal_image_i=%d, iqcal_image_q=%d)\n", + mag_1, iqcal_image_i, iqcal_image_q)); + + // d. Calculate the correct DC offset cancellation value for I + if (mag_0 != mag_1) + { + fix_cancel_dc_q = (mag_0*10000) / (mag_0*10000 - mag_1*10000); + } + else + { + if (mag_0 == mag_1) + { + PHY_DEBUG(("[CAL] ***** mag_0 = mag_1 !!\n")); + } + + fix_cancel_dc_q = 0; + } + + PHY_DEBUG(("[CAL] ** fix_cancel_dc_q = %d (0x%04X)\n", + fix_cancel_dc_q, _s32_to_s5(fix_cancel_dc_q))); + + if ((abs(mag_1-mag_0)*6) > mag_0) + { + break; + } + } + + if ( loop >= 19 ) + fix_cancel_dc_q = 0; + + reg_dc_cancel &= ~(0x001F); + reg_dc_cancel |= (_s32_to_s5(fix_cancel_dc_q) << CANCEL_DC_Q_SHIFT); + hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel); + PHY_DEBUG(("[CAL] DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel)); + + + // f. + reg_mode_ctrl &= ~MASK_CALIB_START; + hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl); + PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl)); + pa_stall_execution(US); +} + +//20060612.1.a 20060718.1 Modify +u8 _tx_iq_calibration_loop_winbond(hw_data_t *phw_data, + s32 a_2_threshold, + s32 b_2_threshold) +{ + u32 reg_mode_ctrl; + s32 iq_mag_0_tx; + s32 iqcal_tone_i0; + s32 iqcal_tone_q0; + s32 iqcal_tone_i; + s32 iqcal_tone_q; + u32 sqsum; + s32 rot_i_b; + s32 rot_q_b; + s32 tx_cal_flt_b[4]; + s32 tx_cal[4]; + s32 tx_cal_reg[4]; + s32 a_2, b_2; + s32 sin_b, sin_2b; + s32 cos_b, cos_2b; + s32 divisor; + s32 temp1, temp2; + u32 val; + u16 loop; + s32 iqcal_tone_i_avg,iqcal_tone_q_avg; + u8 verify_count; + int capture_time; + + PHY_DEBUG(("[CAL] -> _tx_iq_calibration_loop()\n")); + PHY_DEBUG(("[CAL] ** a_2_threshold = %d\n", a_2_threshold)); + PHY_DEBUG(("[CAL] ** b_2_threshold = %d\n", b_2_threshold)); + + verify_count = 0; + + hw_get_dxx_reg(phw_data, REG_MODE_CTRL, ®_mode_ctrl); + PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl)); + + loop = LOOP_TIMES; + + while (loop > 0) + { + PHY_DEBUG(("[CAL] [%d.] <_tx_iq_calibration_loop>\n", (LOOP_TIMES-loop+1))); + + iqcal_tone_i_avg=0; + iqcal_tone_q_avg=0; + if( !hw_set_dxx_reg(phw_data, 0x3C, 0x00) ) // 20060718.1 modify + return 0; + for(capture_time=0;capture_time<10;capture_time++) + { + // a. Set iqcal_mode[1:0] to 0x2 and set "calib_start" to 0x1 to + // enable "IQ alibration Mode II" + reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE); + reg_mode_ctrl &= ~MASK_IQCAL_MODE; + reg_mode_ctrl |= (MASK_CALIB_START|0x02); + reg_mode_ctrl |= (MASK_CALIB_START|0x02|2<<2); + hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl); + PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl)); + pa_stall_execution(US); + + // b. + hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val); + PHY_DEBUG(("[CAL] CALIB_READ1 = 0x%08X\n", val)); + pa_stall_execution(US); + + iqcal_tone_i0 = _s13_to_s32(val & 0x00001FFF); + iqcal_tone_q0 = _s13_to_s32((val & 0x03FFE000) >> 13); + PHY_DEBUG(("[CAL] ** iqcal_tone_i0=%d, iqcal_tone_q0=%d\n", + iqcal_tone_i0, iqcal_tone_q0)); + + sqsum = iqcal_tone_i0*iqcal_tone_i0 + + iqcal_tone_q0*iqcal_tone_q0; + iq_mag_0_tx = (s32) _sqrt(sqsum); + PHY_DEBUG(("[CAL] ** iq_mag_0_tx=%d\n", iq_mag_0_tx)); + + // c. Set "calib_start" to 0x0 + reg_mode_ctrl &= ~MASK_CALIB_START; + hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl); + PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl)); + pa_stall_execution(US); + + // d. Set iqcal_mode[1:0] to 0x3 and set "calib_start" to 0x1 to + // enable "IQ alibration Mode II" + //hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &val); + hw_get_dxx_reg(phw_data, REG_MODE_CTRL, ®_mode_ctrl); + reg_mode_ctrl &= ~MASK_IQCAL_MODE; + reg_mode_ctrl |= (MASK_CALIB_START|0x03); + hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl); + PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl)); + pa_stall_execution(US); + + // e. + hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val); + PHY_DEBUG(("[CAL] CALIB_READ1 = 0x%08X\n", val)); + pa_stall_execution(US); + + iqcal_tone_i = _s13_to_s32(val & 0x00001FFF); + iqcal_tone_q = _s13_to_s32((val & 0x03FFE000) >> 13); + PHY_DEBUG(("[CAL] ** iqcal_tone_i = %d, iqcal_tone_q = %d\n", + iqcal_tone_i, iqcal_tone_q)); + if( capture_time == 0) + { + continue; + } + else + { + iqcal_tone_i_avg=( iqcal_tone_i_avg*(capture_time-1) +iqcal_tone_i)/capture_time; + iqcal_tone_q_avg=( iqcal_tone_q_avg*(capture_time-1) +iqcal_tone_q)/capture_time; + } + } + + iqcal_tone_i = iqcal_tone_i_avg; + iqcal_tone_q = iqcal_tone_q_avg; + + + rot_i_b = (iqcal_tone_i * iqcal_tone_i0 + + iqcal_tone_q * iqcal_tone_q0) / 1024; + rot_q_b = (iqcal_tone_i * iqcal_tone_q0 * (-1) + + iqcal_tone_q * iqcal_tone_i0) / 1024; + PHY_DEBUG(("[CAL] ** rot_i_b = %d, rot_q_b = %d\n", + rot_i_b, rot_q_b)); + + // f. + divisor = ((iq_mag_0_tx * iq_mag_0_tx * 2)/1024 - rot_i_b) * 2; + + if (divisor == 0) + { + PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> ERROR *******\n")); + PHY_DEBUG(("[CAL] ** divisor=0 to calculate EPS and THETA !!\n")); + PHY_DEBUG(("[CAL] ******************************************\n")); + break; + } + + a_2 = (rot_i_b * 32768) / divisor; + b_2 = (rot_q_b * (-32768)) / divisor; + PHY_DEBUG(("[CAL] ***** EPSILON/2 = %d\n", a_2)); + PHY_DEBUG(("[CAL] ***** THETA/2 = %d\n", b_2)); + + phw_data->iq_rsdl_gain_tx_d2 = a_2; + phw_data->iq_rsdl_phase_tx_d2 = b_2; + + //if ((abs(a_2) < 150) && (abs(b_2) < 100)) + //if ((abs(a_2) < 200) && (abs(b_2) < 200)) + if ((abs(a_2) < a_2_threshold) && (abs(b_2) < b_2_threshold)) + { + verify_count++; + + PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *************\n")); + PHY_DEBUG(("[CAL] ** VERIFY OK # %d !!\n", verify_count)); + PHY_DEBUG(("[CAL] ******************************************\n")); + + if (verify_count > 2) + { + PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *********\n")); + PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION (EPS,THETA) OK !!\n")); + PHY_DEBUG(("[CAL] **************************************\n")); + return 0; + } + + continue; + } + else + { + verify_count = 0; + } + + _sin_cos(b_2, &sin_b, &cos_b); + _sin_cos(b_2*2, &sin_2b, &cos_2b); + PHY_DEBUG(("[CAL] ** sin(b/2)=%d, cos(b/2)=%d\n", sin_b, cos_b)); + PHY_DEBUG(("[CAL] ** sin(b)=%d, cos(b)=%d\n", sin_2b, cos_2b)); + + if (cos_2b == 0) + { + PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> ERROR *******\n")); + PHY_DEBUG(("[CAL] ** cos(b)=0 !!\n")); + PHY_DEBUG(("[CAL] ******************************************\n")); + break; + } + + // 1280 * 32768 = 41943040 + temp1 = (41943040/cos_2b)*cos_b; + + //temp2 = (41943040/cos_2b)*sin_b*(-1); + if (phw_data->revision == 0x2002) // 1st-cut + { + temp2 = (41943040/cos_2b)*sin_b*(-1); + } + else // 2nd-cut + { + temp2 = (41943040*4/cos_2b)*sin_b*(-1); + } + + tx_cal_flt_b[0] = _floor(temp1/(32768+a_2)); + tx_cal_flt_b[1] = _floor(temp2/(32768+a_2)); + tx_cal_flt_b[2] = _floor(temp2/(32768-a_2)); + tx_cal_flt_b[3] = _floor(temp1/(32768-a_2)); + PHY_DEBUG(("[CAL] ** tx_cal_flt_b[0] = %d\n", tx_cal_flt_b[0])); + PHY_DEBUG(("[CAL] tx_cal_flt_b[1] = %d\n", tx_cal_flt_b[1])); + PHY_DEBUG(("[CAL] tx_cal_flt_b[2] = %d\n", tx_cal_flt_b[2])); + PHY_DEBUG(("[CAL] tx_cal_flt_b[3] = %d\n", tx_cal_flt_b[3])); + + tx_cal[2] = tx_cal_flt_b[2]; + tx_cal[2] = tx_cal[2] +3; + tx_cal[1] = tx_cal[2]; + tx_cal[3] = tx_cal_flt_b[3] - 128; + tx_cal[0] = -tx_cal[3]+1; + + PHY_DEBUG(("[CAL] tx_cal[0] = %d\n", tx_cal[0])); + PHY_DEBUG(("[CAL] tx_cal[1] = %d\n", tx_cal[1])); + PHY_DEBUG(("[CAL] tx_cal[2] = %d\n", tx_cal[2])); + PHY_DEBUG(("[CAL] tx_cal[3] = %d\n", tx_cal[3])); + + //if ((tx_cal[0] == 0) && (tx_cal[1] == 0) && + // (tx_cal[2] == 0) && (tx_cal[3] == 0)) + //{ + // PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *************\n")); + // PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION COMPLETE !!\n")); + // PHY_DEBUG(("[CAL] ******************************************\n")); + // return 0; + //} + + // g. + if (phw_data->revision == 0x2002) // 1st-cut + { + hw_get_dxx_reg(phw_data, 0x54, &val); + PHY_DEBUG(("[CAL] ** 0x54 = 0x%08X\n", val)); + tx_cal_reg[0] = _s4_to_s32((val & 0xF0000000) >> 28); + tx_cal_reg[1] = _s4_to_s32((val & 0x0F000000) >> 24); + tx_cal_reg[2] = _s4_to_s32((val & 0x00F00000) >> 20); + tx_cal_reg[3] = _s4_to_s32((val & 0x000F0000) >> 16); + } + else // 2nd-cut + { + hw_get_dxx_reg(phw_data, 0x3C, &val); + PHY_DEBUG(("[CAL] ** 0x3C = 0x%08X\n", val)); + tx_cal_reg[0] = _s5_to_s32((val & 0xF8000000) >> 27); + tx_cal_reg[1] = _s6_to_s32((val & 0x07E00000) >> 21); + tx_cal_reg[2] = _s6_to_s32((val & 0x001F8000) >> 15); + tx_cal_reg[3] = _s5_to_s32((val & 0x00007C00) >> 10); + + } + + PHY_DEBUG(("[CAL] ** tx_cal_reg[0] = %d\n", tx_cal_reg[0])); + PHY_DEBUG(("[CAL] tx_cal_reg[1] = %d\n", tx_cal_reg[1])); + PHY_DEBUG(("[CAL] tx_cal_reg[2] = %d\n", tx_cal_reg[2])); + PHY_DEBUG(("[CAL] tx_cal_reg[3] = %d\n", tx_cal_reg[3])); + + if (phw_data->revision == 0x2002) // 1st-cut + { + if (((tx_cal_reg[0]==7) || (tx_cal_reg[0]==(-8))) && + ((tx_cal_reg[3]==7) || (tx_cal_reg[3]==(-8)))) + { + PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *********\n")); + PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION SATUATION !!\n")); + PHY_DEBUG(("[CAL] **************************************\n")); + break; + } + } + else // 2nd-cut + { + if (((tx_cal_reg[0]==31) || (tx_cal_reg[0]==(-32))) && + ((tx_cal_reg[3]==31) || (tx_cal_reg[3]==(-32)))) + { + PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *********\n")); + PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION SATUATION !!\n")); + PHY_DEBUG(("[CAL] **************************************\n")); + break; + } + } + + tx_cal[0] = tx_cal[0] + tx_cal_reg[0]; + tx_cal[1] = tx_cal[1] + tx_cal_reg[1]; + tx_cal[2] = tx_cal[2] + tx_cal_reg[2]; + tx_cal[3] = tx_cal[3] + tx_cal_reg[3]; + PHY_DEBUG(("[CAL] ** apply tx_cal[0] = %d\n", tx_cal[0])); + PHY_DEBUG(("[CAL] apply tx_cal[1] = %d\n", tx_cal[1])); + PHY_DEBUG(("[CAL] apply tx_cal[2] = %d\n", tx_cal[2])); + PHY_DEBUG(("[CAL] apply tx_cal[3] = %d\n", tx_cal[3])); + + if (phw_data->revision == 0x2002) // 1st-cut + { + val &= 0x0000FFFF; + val |= ((_s32_to_s4(tx_cal[0]) << 28)| + (_s32_to_s4(tx_cal[1]) << 24)| + (_s32_to_s4(tx_cal[2]) << 20)| + (_s32_to_s4(tx_cal[3]) << 16)); + hw_set_dxx_reg(phw_data, 0x54, val); + PHY_DEBUG(("[CAL] ** CALIB_DATA = 0x%08X\n", val)); + return 0; + } + else // 2nd-cut + { + val &= 0x000003FF; + val |= ((_s32_to_s5(tx_cal[0]) << 27)| + (_s32_to_s6(tx_cal[1]) << 21)| + (_s32_to_s6(tx_cal[2]) << 15)| + (_s32_to_s5(tx_cal[3]) << 10)); + hw_set_dxx_reg(phw_data, 0x3C, val); + PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION = 0x%08X\n", val)); + return 0; + } + + // i. Set "calib_start" to 0x0 + reg_mode_ctrl &= ~MASK_CALIB_START; + hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl); + PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl)); + + loop--; + } + + return 1; +} + +void _tx_iq_calibration_winbond(hw_data_t *phw_data) +{ + u32 reg_agc_ctrl3; +#ifdef _DEBUG + s32 tx_cal_reg[4]; + +#endif + u32 reg_mode_ctrl; + u32 val; + u8 result; + + PHY_DEBUG(("[CAL] -> [4]_tx_iq_calibration()\n")); + + //0x01 0xEE3FC2 ; 3B8FF ; Calibration (6a). enable TX IQ calibration loop circuits + phy_set_rf_data(phw_data, 1, (1<<24)|0xEE3FC2); + //0x0B 0x1905D6 ; 06417 ; Calibration (6b). enable TX I/Q cal loop squaring circuit + phy_set_rf_data(phw_data, 11, (11<<24)|0x19BDD6); // 20060612.1.a 0x1905D6); + //0x05 0x24C60A ; 09318 ; Calibration (6c). setting TX-VGA gain: TXGCH=2 & GPK=110 --> to be optimized + phy_set_rf_data(phw_data, 5, (5<<24)|0x24C60A); //0x24C60A (high temperature) + //0x06 0x06880C ; 01A20 ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized + phy_set_rf_data(phw_data, 6, (6<<24)|0x34880C); // 20060612.1.a 0x06890C); + //0x00 0xFDF1C0 ; 3F7C7 ; Calibration (6e). turn on IQ imbalance/Test mode + phy_set_rf_data(phw_data, 0, (0<<24)|0xFDF1C0); + //; [BB-chip]: Calibration (6f).Send test pattern + //; [BB-chip]: Calibration (6g). Search RXGCL optimal value + //; [BB-chip]: Calibration (6h). Caculate TX-path IQ imbalance and setting TX path IQ compensation table + //phy_set_rf_data(phw_data, 3, (3<<24)|0x025586); + + OS_SLEEP(30000); // 20060612.1.a 30ms delay. Add the follow 2 lines + //To adjust TXVGA to fit iq_mag_0 range from 1250 ~ 1750 + adjust_TXVGA_for_iq_mag( phw_data ); + + // a. Disable AGC + hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, ®_agc_ctrl3); + reg_agc_ctrl3 &= ~BIT(2); + reg_agc_ctrl3 |= (MASK_LNA_FIX_GAIN|MASK_AGC_FIX); + hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3); + + hw_get_dxx_reg(phw_data, REG_AGC_CTRL5, &val); + val |= MASK_AGC_FIX_GAIN; + hw_set_dxx_reg(phw_data, REG_AGC_CTRL5, val); + + result = _tx_iq_calibration_loop_winbond(phw_data, 150, 100); + + if (result > 0) + { + if (phw_data->revision == 0x2002) // 1st-cut + { + hw_get_dxx_reg(phw_data, 0x54, &val); + val &= 0x0000FFFF; + hw_set_dxx_reg(phw_data, 0x54, val); + } + else // 2nd-cut + { + hw_get_dxx_reg(phw_data, 0x3C, &val); + val &= 0x000003FF; + hw_set_dxx_reg(phw_data, 0x3C, val); + } + + result = _tx_iq_calibration_loop_winbond(phw_data, 300, 200); + + if (result > 0) + { + if (phw_data->revision == 0x2002) // 1st-cut + { + hw_get_dxx_reg(phw_data, 0x54, &val); + val &= 0x0000FFFF; + hw_set_dxx_reg(phw_data, 0x54, val); + } + else // 2nd-cut + { + hw_get_dxx_reg(phw_data, 0x3C, &val); + val &= 0x000003FF; + hw_set_dxx_reg(phw_data, 0x3C, val); + } + + result = _tx_iq_calibration_loop_winbond(phw_data, 500, 400); + if (result > 0) + { + if (phw_data->revision == 0x2002) // 1st-cut + { + hw_get_dxx_reg(phw_data, 0x54, &val); + val &= 0x0000FFFF; + hw_set_dxx_reg(phw_data, 0x54, val); + } + else // 2nd-cut + { + hw_get_dxx_reg(phw_data, 0x3C, &val); + val &= 0x000003FF; + hw_set_dxx_reg(phw_data, 0x3C, val); + } + + + result = _tx_iq_calibration_loop_winbond(phw_data, 700, 500); + + if (result > 0) + { + PHY_DEBUG(("[CAL] ** <_tx_iq_calibration> **************\n")); + PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION FAILURE !!\n")); + PHY_DEBUG(("[CAL] **************************************\n")); + + if (phw_data->revision == 0x2002) // 1st-cut + { + hw_get_dxx_reg(phw_data, 0x54, &val); + val &= 0x0000FFFF; + hw_set_dxx_reg(phw_data, 0x54, val); + } + else // 2nd-cut + { + hw_get_dxx_reg(phw_data, 0x3C, &val); + val &= 0x000003FF; + hw_set_dxx_reg(phw_data, 0x3C, val); + } + } + } + } + } + + // i. Set "calib_start" to 0x0 + hw_get_dxx_reg(phw_data, REG_MODE_CTRL, ®_mode_ctrl); + reg_mode_ctrl &= ~MASK_CALIB_START; + hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl); + PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl)); + + // g. Enable AGC + //hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &val); + reg_agc_ctrl3 |= BIT(2); + reg_agc_ctrl3 &= ~(MASK_LNA_FIX_GAIN|MASK_AGC_FIX); + hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3); + +#ifdef _DEBUG + if (phw_data->revision == 0x2002) // 1st-cut + { + hw_get_dxx_reg(phw_data, 0x54, &val); + PHY_DEBUG(("[CAL] ** 0x54 = 0x%08X\n", val)); + tx_cal_reg[0] = _s4_to_s32((val & 0xF0000000) >> 28); + tx_cal_reg[1] = _s4_to_s32((val & 0x0F000000) >> 24); + tx_cal_reg[2] = _s4_to_s32((val & 0x00F00000) >> 20); + tx_cal_reg[3] = _s4_to_s32((val & 0x000F0000) >> 16); + } + else // 2nd-cut + { + hw_get_dxx_reg(phw_data, 0x3C, &val); + PHY_DEBUG(("[CAL] ** 0x3C = 0x%08X\n", val)); + tx_cal_reg[0] = _s5_to_s32((val & 0xF8000000) >> 27); + tx_cal_reg[1] = _s6_to_s32((val & 0x07E00000) >> 21); + tx_cal_reg[2] = _s6_to_s32((val & 0x001F8000) >> 15); + tx_cal_reg[3] = _s5_to_s32((val & 0x00007C00) >> 10); + + } + + PHY_DEBUG(("[CAL] ** tx_cal_reg[0] = %d\n", tx_cal_reg[0])); + PHY_DEBUG(("[CAL] tx_cal_reg[1] = %d\n", tx_cal_reg[1])); + PHY_DEBUG(("[CAL] tx_cal_reg[2] = %d\n", tx_cal_reg[2])); + PHY_DEBUG(("[CAL] tx_cal_reg[3] = %d\n", tx_cal_reg[3])); +#endif + + + // for test - BEN + // RF Control Override +} + +///////////////////////////////////////////////////////////////////////////////////////// +u8 _rx_iq_calibration_loop_winbond(hw_data_t *phw_data, u16 factor, u32 frequency) +{ + u32 reg_mode_ctrl; + s32 iqcal_tone_i; + s32 iqcal_tone_q; + s32 iqcal_image_i; + s32 iqcal_image_q; + s32 rot_tone_i_b; + s32 rot_tone_q_b; + s32 rot_image_i_b; + s32 rot_image_q_b; + s32 rx_cal_flt_b[4]; + s32 rx_cal[4]; + s32 rx_cal_reg[4]; + s32 a_2, b_2; + s32 sin_b, sin_2b; + s32 cos_b, cos_2b; + s32 temp1, temp2; + u32 val; + u16 loop; + + u32 pwr_tone; + u32 pwr_image; + u8 verify_count; + + s32 iqcal_tone_i_avg,iqcal_tone_q_avg; + s32 iqcal_image_i_avg,iqcal_image_q_avg; + u16 capture_time; + + PHY_DEBUG(("[CAL] -> [5]_rx_iq_calibration_loop()\n")); + PHY_DEBUG(("[CAL] ** factor = %d\n", factor)); + + +// RF Control Override + hw_get_cxx_reg(phw_data, 0x80, &val); + val |= BIT(19); + hw_set_cxx_reg(phw_data, 0x80, val); + +// RF_Ctrl + hw_get_cxx_reg(phw_data, 0xE4, &val); + val |= BIT(0); + hw_set_cxx_reg(phw_data, 0xE4, val); + PHY_DEBUG(("[CAL] ** RF_CTRL(0xE4) = 0x%08X", val)); + + hw_set_dxx_reg(phw_data, 0x58, 0x44444444); // IQ_Alpha + + // b. + + hw_get_dxx_reg(phw_data, REG_MODE_CTRL, ®_mode_ctrl); + PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl)); + + verify_count = 0; + + //for (loop = 0; loop < 1; loop++) + //for (loop = 0; loop < LOOP_TIMES; loop++) + loop = LOOP_TIMES; + while (loop > 0) + { + PHY_DEBUG(("[CAL] [%d.] <_rx_iq_calibration_loop>\n", (LOOP_TIMES-loop+1))); + iqcal_tone_i_avg=0; + iqcal_tone_q_avg=0; + iqcal_image_i_avg=0; + iqcal_image_q_avg=0; + capture_time=0; + + for(capture_time=0; capture_time<10; capture_time++) + { + // i. Set "calib_start" to 0x0 + reg_mode_ctrl &= ~MASK_CALIB_START; + if( !hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl) )//20060718.1 modify + return 0; + PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl)); + pa_stall_execution(US); + + reg_mode_ctrl &= ~MASK_IQCAL_MODE; + reg_mode_ctrl |= (MASK_CALIB_START|0x1); + hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl); + PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl)); + pa_stall_execution(US); //Should be read out after 450us + + // c. + hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val); + PHY_DEBUG(("[CAL] CALIB_READ1 = 0x%08X\n", val)); + + iqcal_tone_i = _s13_to_s32(val & 0x00001FFF); + iqcal_tone_q = _s13_to_s32((val & 0x03FFE000) >> 13); + PHY_DEBUG(("[CAL] ** iqcal_tone_i = %d, iqcal_tone_q = %d\n", + iqcal_tone_i, iqcal_tone_q)); + + hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val); + PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val)); + + iqcal_image_i = _s13_to_s32(val & 0x00001FFF); + iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13); + PHY_DEBUG(("[CAL] ** iqcal_image_i = %d, iqcal_image_q = %d\n", + iqcal_image_i, iqcal_image_q)); + if( capture_time == 0) + { + continue; + } + else + { + iqcal_image_i_avg=( iqcal_image_i_avg*(capture_time-1) +iqcal_image_i)/capture_time; + iqcal_image_q_avg=( iqcal_image_q_avg*(capture_time-1) +iqcal_image_q)/capture_time; + iqcal_tone_i_avg=( iqcal_tone_i_avg*(capture_time-1) +iqcal_tone_i)/capture_time; + iqcal_tone_q_avg=( iqcal_tone_q_avg*(capture_time-1) +iqcal_tone_q)/capture_time; + } + } + + + iqcal_image_i = iqcal_image_i_avg; + iqcal_image_q = iqcal_image_q_avg; + iqcal_tone_i = iqcal_tone_i_avg; + iqcal_tone_q = iqcal_tone_q_avg; + + // d. + rot_tone_i_b = (iqcal_tone_i * iqcal_tone_i + + iqcal_tone_q * iqcal_tone_q) / 1024; + rot_tone_q_b = (iqcal_tone_i * iqcal_tone_q * (-1) + + iqcal_tone_q * iqcal_tone_i) / 1024; + rot_image_i_b = (iqcal_image_i * iqcal_tone_i - + iqcal_image_q * iqcal_tone_q) / 1024; + rot_image_q_b = (iqcal_image_i * iqcal_tone_q + + iqcal_image_q * iqcal_tone_i) / 1024; + + PHY_DEBUG(("[CAL] ** rot_tone_i_b = %d\n", rot_tone_i_b)); + PHY_DEBUG(("[CAL] ** rot_tone_q_b = %d\n", rot_tone_q_b)); + PHY_DEBUG(("[CAL] ** rot_image_i_b = %d\n", rot_image_i_b)); + PHY_DEBUG(("[CAL] ** rot_image_q_b = %d\n", rot_image_q_b)); + + // f. + if (rot_tone_i_b == 0) + { + PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> ERROR *******\n")); + PHY_DEBUG(("[CAL] ** rot_tone_i_b=0 to calculate EPS and THETA !!\n")); + PHY_DEBUG(("[CAL] ******************************************\n")); + break; + } + + a_2 = (rot_image_i_b * 32768) / rot_tone_i_b - + phw_data->iq_rsdl_gain_tx_d2; + b_2 = (rot_image_q_b * 32768) / rot_tone_i_b - + phw_data->iq_rsdl_phase_tx_d2; + + PHY_DEBUG(("[CAL] ** iq_rsdl_gain_tx_d2 = %d\n", phw_data->iq_rsdl_gain_tx_d2)); + PHY_DEBUG(("[CAL] ** iq_rsdl_phase_tx_d2= %d\n", phw_data->iq_rsdl_phase_tx_d2)); + PHY_DEBUG(("[CAL] ***** EPSILON/2 = %d\n", a_2)); + PHY_DEBUG(("[CAL] ***** THETA/2 = %d\n", b_2)); + + _sin_cos(b_2, &sin_b, &cos_b); + _sin_cos(b_2*2, &sin_2b, &cos_2b); + PHY_DEBUG(("[CAL] ** sin(b/2)=%d, cos(b/2)=%d\n", sin_b, cos_b)); + PHY_DEBUG(("[CAL] ** sin(b)=%d, cos(b)=%d\n", sin_2b, cos_2b)); + + if (cos_2b == 0) + { + PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> ERROR *******\n")); + PHY_DEBUG(("[CAL] ** cos(b)=0 !!\n")); + PHY_DEBUG(("[CAL] ******************************************\n")); + break; + } + + // 1280 * 32768 = 41943040 + temp1 = (41943040/cos_2b)*cos_b; + + //temp2 = (41943040/cos_2b)*sin_b*(-1); + if (phw_data->revision == 0x2002) // 1st-cut + { + temp2 = (41943040/cos_2b)*sin_b*(-1); + } + else // 2nd-cut + { + temp2 = (41943040*4/cos_2b)*sin_b*(-1); + } + + rx_cal_flt_b[0] = _floor(temp1/(32768+a_2)); + rx_cal_flt_b[1] = _floor(temp2/(32768-a_2)); + rx_cal_flt_b[2] = _floor(temp2/(32768+a_2)); + rx_cal_flt_b[3] = _floor(temp1/(32768-a_2)); + + PHY_DEBUG(("[CAL] ** rx_cal_flt_b[0] = %d\n", rx_cal_flt_b[0])); + PHY_DEBUG(("[CAL] rx_cal_flt_b[1] = %d\n", rx_cal_flt_b[1])); + PHY_DEBUG(("[CAL] rx_cal_flt_b[2] = %d\n", rx_cal_flt_b[2])); + PHY_DEBUG(("[CAL] rx_cal_flt_b[3] = %d\n", rx_cal_flt_b[3])); + + rx_cal[0] = rx_cal_flt_b[0] - 128; + rx_cal[1] = rx_cal_flt_b[1]; + rx_cal[2] = rx_cal_flt_b[2]; + rx_cal[3] = rx_cal_flt_b[3] - 128; + PHY_DEBUG(("[CAL] ** rx_cal[0] = %d\n", rx_cal[0])); + PHY_DEBUG(("[CAL] rx_cal[1] = %d\n", rx_cal[1])); + PHY_DEBUG(("[CAL] rx_cal[2] = %d\n", rx_cal[2])); + PHY_DEBUG(("[CAL] rx_cal[3] = %d\n", rx_cal[3])); + + // e. + pwr_tone = (iqcal_tone_i*iqcal_tone_i + iqcal_tone_q*iqcal_tone_q); + pwr_image = (iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q)*factor; + + PHY_DEBUG(("[CAL] ** pwr_tone = %d\n", pwr_tone)); + PHY_DEBUG(("[CAL] ** pwr_image = %d\n", pwr_image)); + + if (pwr_tone > pwr_image) + { + verify_count++; + + PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *************\n")); + PHY_DEBUG(("[CAL] ** VERIFY OK # %d !!\n", verify_count)); + PHY_DEBUG(("[CAL] ******************************************\n")); + + if (verify_count > 2) + { + PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *********\n")); + PHY_DEBUG(("[CAL] ** RX_IQ_CALIBRATION OK !!\n")); + PHY_DEBUG(("[CAL] **************************************\n")); + return 0; + } + + continue; + } + // g. + hw_get_dxx_reg(phw_data, 0x54, &val); + PHY_DEBUG(("[CAL] ** 0x54 = 0x%08X\n", val)); + + if (phw_data->revision == 0x2002) // 1st-cut + { + rx_cal_reg[0] = _s4_to_s32((val & 0x0000F000) >> 12); + rx_cal_reg[1] = _s4_to_s32((val & 0x00000F00) >> 8); + rx_cal_reg[2] = _s4_to_s32((val & 0x000000F0) >> 4); + rx_cal_reg[3] = _s4_to_s32((val & 0x0000000F)); + } + else // 2nd-cut + { + rx_cal_reg[0] = _s5_to_s32((val & 0xF8000000) >> 27); + rx_cal_reg[1] = _s6_to_s32((val & 0x07E00000) >> 21); + rx_cal_reg[2] = _s6_to_s32((val & 0x001F8000) >> 15); + rx_cal_reg[3] = _s5_to_s32((val & 0x00007C00) >> 10); + } + + PHY_DEBUG(("[CAL] ** rx_cal_reg[0] = %d\n", rx_cal_reg[0])); + PHY_DEBUG(("[CAL] rx_cal_reg[1] = %d\n", rx_cal_reg[1])); + PHY_DEBUG(("[CAL] rx_cal_reg[2] = %d\n", rx_cal_reg[2])); + PHY_DEBUG(("[CAL] rx_cal_reg[3] = %d\n", rx_cal_reg[3])); + + if (phw_data->revision == 0x2002) // 1st-cut + { + if (((rx_cal_reg[0]==7) || (rx_cal_reg[0]==(-8))) && + ((rx_cal_reg[3]==7) || (rx_cal_reg[3]==(-8)))) + { + PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *********\n")); + PHY_DEBUG(("[CAL] ** RX_IQ_CALIBRATION SATUATION !!\n")); + PHY_DEBUG(("[CAL] **************************************\n")); + break; + } + } + else // 2nd-cut + { + if (((rx_cal_reg[0]==31) || (rx_cal_reg[0]==(-32))) && + ((rx_cal_reg[3]==31) || (rx_cal_reg[3]==(-32)))) + { + PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *********\n")); + PHY_DEBUG(("[CAL] ** RX_IQ_CALIBRATION SATUATION !!\n")); + PHY_DEBUG(("[CAL] **************************************\n")); + break; + } + } + + rx_cal[0] = rx_cal[0] + rx_cal_reg[0]; + rx_cal[1] = rx_cal[1] + rx_cal_reg[1]; + rx_cal[2] = rx_cal[2] + rx_cal_reg[2]; + rx_cal[3] = rx_cal[3] + rx_cal_reg[3]; + PHY_DEBUG(("[CAL] ** apply rx_cal[0] = %d\n", rx_cal[0])); + PHY_DEBUG(("[CAL] apply rx_cal[1] = %d\n", rx_cal[1])); + PHY_DEBUG(("[CAL] apply rx_cal[2] = %d\n", rx_cal[2])); + PHY_DEBUG(("[CAL] apply rx_cal[3] = %d\n", rx_cal[3])); + + hw_get_dxx_reg(phw_data, 0x54, &val); + if (phw_data->revision == 0x2002) // 1st-cut + { + val &= 0x0000FFFF; + val |= ((_s32_to_s4(rx_cal[0]) << 12)| + (_s32_to_s4(rx_cal[1]) << 8)| + (_s32_to_s4(rx_cal[2]) << 4)| + (_s32_to_s4(rx_cal[3]))); + hw_set_dxx_reg(phw_data, 0x54, val); + } + else // 2nd-cut + { + val &= 0x000003FF; + val |= ((_s32_to_s5(rx_cal[0]) << 27)| + (_s32_to_s6(rx_cal[1]) << 21)| + (_s32_to_s6(rx_cal[2]) << 15)| + (_s32_to_s5(rx_cal[3]) << 10)); + hw_set_dxx_reg(phw_data, 0x54, val); + + if( loop == 3 ) + return 0; + } + PHY_DEBUG(("[CAL] ** CALIB_DATA = 0x%08X\n", val)); + + loop--; + } + + return 1; +} + +////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////// +void _rx_iq_calibration_winbond(hw_data_t *phw_data, u32 frequency) +{ +// figo 20050523 marked thsi flag for can't compile for relesase +#ifdef _DEBUG + s32 rx_cal_reg[4]; + u32 val; +#endif + + u8 result; + + PHY_DEBUG(("[CAL] -> [5]_rx_iq_calibration()\n")); +// a. Set RFIC to "RX calibration mode" + //; ----- Calibration (7). RX path IQ imbalance calibration loop + // 0x01 0xFFBFC2 ; 3FEFF ; Calibration (7a). enable RX IQ calibration loop circuits + phy_set_rf_data(phw_data, 1, (1<<24)|0xEFBFC2); + // 0x0B 0x1A01D6 ; 06817 ; Calibration (7b). enable RX I/Q cal loop SW1 circuit + phy_set_rf_data(phw_data, 11, (11<<24)|0x1A05D6); + //0x05 0x24848A ; 09212 ; Calibration (7c). setting TX-VGA gain (TXGCH) to 2 --> to be optimized + phy_set_rf_data(phw_data, 5, (5<<24)| phw_data->txvga_setting_for_cal); + //0x06 0x06840C ; 01A10 ; Calibration (7d). RXGCH=00; RXGCL=010 000 (RXVGA) --> to be optimized + phy_set_rf_data(phw_data, 6, (6<<24)|0x06834C); + //0x00 0xFFF1C0 ; 3F7C7 ; Calibration (7e). turn on IQ imbalance/Test mode + phy_set_rf_data(phw_data, 0, (0<<24)|0xFFF1C0); + + // ; [BB-chip]: Calibration (7f). Send test pattern + // ; [BB-chip]: Calibration (7g). Search RXGCL optimal value + // ; [BB-chip]: Calibration (7h). Caculate RX-path IQ imbalance and setting RX path IQ compensation table + + result = _rx_iq_calibration_loop_winbond(phw_data, 12589, frequency); + + if (result > 0) + { + _reset_rx_cal(phw_data); + result = _rx_iq_calibration_loop_winbond(phw_data, 7943, frequency); + + if (result > 0) + { + _reset_rx_cal(phw_data); + result = _rx_iq_calibration_loop_winbond(phw_data, 5011, frequency); + + if (result > 0) + { + PHY_DEBUG(("[CAL] ** <_rx_iq_calibration> **************\n")); + PHY_DEBUG(("[CAL] ** RX_IQ_CALIBRATION FAILURE !!\n")); + PHY_DEBUG(("[CAL] **************************************\n")); + _reset_rx_cal(phw_data); + } + } + } + +#ifdef _DEBUG + hw_get_dxx_reg(phw_data, 0x54, &val); + PHY_DEBUG(("[CAL] ** 0x54 = 0x%08X\n", val)); + + if (phw_data->revision == 0x2002) // 1st-cut + { + rx_cal_reg[0] = _s4_to_s32((val & 0x0000F000) >> 12); + rx_cal_reg[1] = _s4_to_s32((val & 0x00000F00) >> 8); + rx_cal_reg[2] = _s4_to_s32((val & 0x000000F0) >> 4); + rx_cal_reg[3] = _s4_to_s32((val & 0x0000000F)); + } + else // 2nd-cut + { + rx_cal_reg[0] = _s5_to_s32((val & 0xF8000000) >> 27); + rx_cal_reg[1] = _s6_to_s32((val & 0x07E00000) >> 21); + rx_cal_reg[2] = _s6_to_s32((val & 0x001F8000) >> 15); + rx_cal_reg[3] = _s5_to_s32((val & 0x00007C00) >> 10); + } + + PHY_DEBUG(("[CAL] ** rx_cal_reg[0] = %d\n", rx_cal_reg[0])); + PHY_DEBUG(("[CAL] rx_cal_reg[1] = %d\n", rx_cal_reg[1])); + PHY_DEBUG(("[CAL] rx_cal_reg[2] = %d\n", rx_cal_reg[2])); + PHY_DEBUG(("[CAL] rx_cal_reg[3] = %d\n", rx_cal_reg[3])); +#endif + +} + +//////////////////////////////////////////////////////////////////////// +void phy_calibration_winbond(hw_data_t *phw_data, u32 frequency) +{ + u32 reg_mode_ctrl; + u32 iq_alpha; + + PHY_DEBUG(("[CAL] -> phy_calibration_winbond()\n")); + + // 20040701 1.1.25.1000 kevin + hw_get_cxx_reg(phw_data, 0x80, &mac_ctrl); + hw_get_cxx_reg(phw_data, 0xE4, &rf_ctrl); + hw_get_dxx_reg(phw_data, 0x58, &iq_alpha); + + + + _rxadc_dc_offset_cancellation_winbond(phw_data, frequency); + //_txidac_dc_offset_cancellation_winbond(phw_data); + //_txqdac_dc_offset_cacellation_winbond(phw_data); + + _tx_iq_calibration_winbond(phw_data); + _rx_iq_calibration_winbond(phw_data, frequency); + + //------------------------------------------------------------------------ + hw_get_dxx_reg(phw_data, REG_MODE_CTRL, ®_mode_ctrl); + reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE|MASK_CALIB_START); // set when finish + hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl); + PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl)); + + // i. Set RFIC to "Normal mode" + hw_set_cxx_reg(phw_data, 0x80, mac_ctrl); + hw_set_cxx_reg(phw_data, 0xE4, rf_ctrl); + hw_set_dxx_reg(phw_data, 0x58, iq_alpha); + + + //------------------------------------------------------------------------ + phy_init_rf(phw_data); + +} + +//=========================== +void phy_set_rf_data( phw_data_t pHwData, u32 index, u32 value ) +{ + u32 ltmp=0; + + switch( pHwData->phy_type ) + { + case RF_MAXIM_2825: + case RF_MAXIM_V1: // 11g Winbond 2nd BB(with Phy board (v1) + Maxim 331) + ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( value, 18 ); + break; + + case RF_MAXIM_2827: + ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( value, 18 ); + break; + + case RF_MAXIM_2828: + ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( value, 18 ); + break; + + case RF_MAXIM_2829: + ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( value, 18 ); + break; + + case RF_AIROHA_2230: + case RF_AIROHA_2230S: // 20060420 Add this + ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( value, 20 ); + break; + + case RF_AIROHA_7230: + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | (value&0xffffff); + break; + + case RF_WB_242: + case RF_WB_242_1: // 20060619.5 Add + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( value, 24 ); + break; + } + + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); +} + +// 20060717 modify as Bruce's mail +unsigned char adjust_TXVGA_for_iq_mag(hw_data_t *phw_data) +{ + int init_txvga = 0; + u32 reg_mode_ctrl; + u32 val; + s32 iqcal_tone_i0; + s32 iqcal_tone_q0; + u32 sqsum; + s32 iq_mag_0_tx; + u8 reg_state; + int current_txvga; + + + reg_state = 0; + for( init_txvga=0; init_txvga<10; init_txvga++) + { + current_txvga = ( 0x24C40A|(init_txvga<<6) ); + phy_set_rf_data(phw_data, 5, ((5<<24)|current_txvga) ); + phw_data->txvga_setting_for_cal = current_txvga; + + //pa_stall_execution(30000);//Sleep(30); + OS_SLEEP(30000); // 20060612.1.a + + if( !hw_get_dxx_reg(phw_data, REG_MODE_CTRL, ®_mode_ctrl) ) // 20060718.1 modify + return FALSE; + + PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl)); + + // a. Set iqcal_mode[1:0] to 0x2 and set "calib_start" to 0x1 to + // enable "IQ alibration Mode II" + reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE); + reg_mode_ctrl &= ~MASK_IQCAL_MODE; + reg_mode_ctrl |= (MASK_CALIB_START|0x02); + reg_mode_ctrl |= (MASK_CALIB_START|0x02|2<<2); + hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl); + PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl)); + + //pa_stall_execution(US); + OS_SLEEP(1); // 20060612.1.a + + //pa_stall_execution(300);//Sleep(30); + OS_SLEEP(300); // 20060612.1.a + + // b. + hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val); + + PHY_DEBUG(("[CAL] CALIB_READ1 = 0x%08X\n", val)); + //pa_stall_execution(US); + //pa_stall_execution(300);//Sleep(30); + OS_SLEEP(300); // 20060612.1.a + + iqcal_tone_i0 = _s13_to_s32(val & 0x00001FFF); + iqcal_tone_q0 = _s13_to_s32((val & 0x03FFE000) >> 13); + PHY_DEBUG(("[CAL] ** iqcal_tone_i0=%d, iqcal_tone_q0=%d\n", + iqcal_tone_i0, iqcal_tone_q0)); + + sqsum = iqcal_tone_i0*iqcal_tone_i0 + iqcal_tone_q0*iqcal_tone_q0; + iq_mag_0_tx = (s32) _sqrt(sqsum); + PHY_DEBUG(("[CAL] ** auto_adjust_txvga_for_iq_mag_0_tx=%d\n", iq_mag_0_tx)); + + if( iq_mag_0_tx>=700 && iq_mag_0_tx<=1750 ) + break; + else if(iq_mag_0_tx > 1750) + { + init_txvga=-2; + continue; + } + else + continue; + + } + + if( iq_mag_0_tx>=700 && iq_mag_0_tx<=1750 ) + return TRUE; + else + return FALSE; +} + + + diff --git a/drivers/staging/winbond/phy_calibration.h b/drivers/staging/winbond/phy_calibration.h new file mode 100644 index 000000000000..b6a65d313019 --- /dev/null +++ b/drivers/staging/winbond/phy_calibration.h @@ -0,0 +1,101 @@ +// 20031229 Turbo add +#define REG_AGC_CTRL1 0x1000 +#define REG_AGC_CTRL2 0x1004 +#define REG_AGC_CTRL3 0x1008 +#define REG_AGC_CTRL4 0x100C +#define REG_AGC_CTRL5 0x1010 +#define REG_AGC_CTRL6 0x1014 +#define REG_AGC_CTRL7 0x1018 +#define REG_AGC_CTRL8 0x101C +#define REG_AGC_CTRL9 0x1020 +#define REG_AGC_CTRL10 0x1024 +#define REG_CCA_CTRL 0x1028 +#define REG_A_ACQ_CTRL 0x102C +#define REG_B_ACQ_CTRL 0x1030 +#define REG_A_TXRX_CTRL 0x1034 +#define REG_B_TXRX_CTRL 0x1038 +#define REG_A_TX_COEF3 0x103C +#define REG_A_TX_COEF2 0x1040 +#define REG_A_TX_COEF1 0x1044 +#define REG_B_TX_COEF2 0x1048 +#define REG_B_TX_COEF1 0x104C +#define REG_MODE_CTRL 0x1050 +#define REG_CALIB_DATA 0x1054 +#define REG_IQ_ALPHA 0x1058 +#define REG_DC_CANCEL 0x105C +#define REG_WTO_READ 0x1060 +#define REG_OFFSET_READ 0x1064 +#define REG_CALIB_READ1 0x1068 +#define REG_CALIB_READ2 0x106C +#define REG_A_FREQ_EST 0x1070 + + + + +// 20031101 Turbo add +#define MASK_AMER_OFF_REG BIT(31) + +#define MASK_BMER_OFF_REG BIT(31) + +#define MASK_LNA_FIX_GAIN (BIT(3)|BIT(4)) +#define MASK_AGC_FIX BIT(1) + +#define MASK_AGC_FIX_GAIN 0xFF00 + +#define MASK_ADC_DC_CAL_STR BIT(10) +#define MASK_CALIB_START BIT(4) +#define MASK_IQCAL_TONE_SEL (BIT(3)|BIT(2)) +#define MASK_IQCAL_MODE (BIT(1)|BIT(0)) + +#define MASK_TX_CAL_0 0xF0000000 +#define TX_CAL_0_SHIFT 28 +#define MASK_TX_CAL_1 0x0F000000 +#define TX_CAL_1_SHIFT 24 +#define MASK_TX_CAL_2 0x00F00000 +#define TX_CAL_2_SHIFT 20 +#define MASK_TX_CAL_3 0x000F0000 +#define TX_CAL_3_SHIFT 16 +#define MASK_RX_CAL_0 0x0000F000 +#define RX_CAL_0_SHIFT 12 +#define MASK_RX_CAL_1 0x00000F00 +#define RX_CAL_1_SHIFT 8 +#define MASK_RX_CAL_2 0x000000F0 +#define RX_CAL_2_SHIFT 4 +#define MASK_RX_CAL_3 0x0000000F +#define RX_CAL_3_SHIFT 0 + +#define MASK_CANCEL_DC_I 0x3E0 +#define CANCEL_DC_I_SHIFT 5 +#define MASK_CANCEL_DC_Q 0x01F +#define CANCEL_DC_Q_SHIFT 0 + +// LA20040210 kevin +//#define MASK_ADC_DC_CAL_I(x) (((x)&0x1FE00)>>9) +//#define MASK_ADC_DC_CAL_Q(x) ((x)&0x1FF) +#define MASK_ADC_DC_CAL_I(x) (((x)&0x0003FE00)>>9) +#define MASK_ADC_DC_CAL_Q(x) ((x)&0x000001FF) + +// LA20040210 kevin (Turbo has wrong definition) +//#define MASK_IQCAL_TONE_I 0x7FFC000 +//#define SHIFT_IQCAL_TONE_I(x) ((x)>>13) +//#define MASK_IQCAL_TONE_Q 0x1FFF +//#define SHIFT_IQCAL_TONE_Q(x) ((x)>>0) +#define MASK_IQCAL_TONE_I 0x00001FFF +#define SHIFT_IQCAL_TONE_I(x) ((x)>>0) +#define MASK_IQCAL_TONE_Q 0x03FFE000 +#define SHIFT_IQCAL_TONE_Q(x) ((x)>>13) + +// LA20040210 kevin (Turbo has wrong definition) +//#define MASK_IQCAL_IMAGE_I 0x7FFC000 +//#define SHIFT_IQCAL_IMAGE_I(x) ((x)>>13) +//#define MASK_IQCAL_IMAGE_Q 0x1FFF +//#define SHIFT_IQCAL_IMAGE_Q(x) ((x)>>0) + +//#define MASK_IQCAL_IMAGE_I 0x00001FFF +//#define SHIFT_IQCAL_IMAGE_I(x) ((x)>>0) +//#define MASK_IQCAL_IMAGE_Q 0x03FFE000 +//#define SHIFT_IQCAL_IMAGE_Q(x) ((x)>>13) + +void phy_set_rf_data( phw_data_t pHwData, u32 index, u32 value ); +#define phy_init_rf( _A ) //RFSynthesizer_initial( _A ) + diff --git a/drivers/staging/winbond/reg.c b/drivers/staging/winbond/reg.c new file mode 100644 index 000000000000..b475c7a7c424 --- /dev/null +++ b/drivers/staging/winbond/reg.c @@ -0,0 +1,2683 @@ +#include "os_common.h" + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Original Phy.h +//***************************************************************************** + +/***************************************************************************** +; For MAXIM2825/6/7 Ver. 331 or more +; Edited by Tiger, Sep-17-2003 +; revised by Ben, Sep-18-2003 + +0x00 0x000a2 +0x01 0x21cc0 +;0x02 0x13802 +0x02 0x1383a + +;channe1 01 ; 0x03 0x30142 ; 0x04 0x0b333; +;channe1 02 ;0x03 0x32141 ;0x04 0x08444; +;channe1 03 ;0x03 0x32143 ;0x04 0x0aeee; +;channe1 04 ;0x03 0x32142 ;0x04 0x0b333; +;channe1 05 ;0x03 0x31141 ;0x04 0x08444; +;channe1 06 ; +0x03 0x31143; +0x04 0x0aeee; +;channe1 07 ;0x03 0x31142 ;0x04 0x0b333; +;channe1 08 ;0x03 0x33141 ;0x04 0x08444; +;channe1 09 ;0x03 0x33143 ;0x04 0x0aeee; +;channe1 10 ;0x03 0x33142 ;0x04 0x0b333; +;channe1 11 ;0x03 0x30941 ;0x04 0x08444; +;channe1 12 ;0x03 0x30943 ;0x04 0x0aeee; +;channe1 13 ;0x03 0x30942 ;0x04 0x0b333; + +0x05 0x28986 +0x06 0x18008 +0x07 0x38400 +0x08 0x05100; 100 Hz DC +;0x08 0x05900; 30 KHz DC +0x09 0x24f08 +0x0a 0x17e00, 0x17ea0 +0x0b 0x37d80 +0x0c 0x0c900 // 0x0ca00 (lager power 9db than 0x0c000), 0x0c000 +*****************************************************************************/ +// MAX2825 (pure b/g) +u32 max2825_rf_data[] = +{ + (0x00<<18)|0x000a2, + (0x01<<18)|0x21cc0, + (0x02<<18)|0x13806, + (0x03<<18)|0x30142, + (0x04<<18)|0x0b333, + (0x05<<18)|0x289A6, + (0x06<<18)|0x18008, + (0x07<<18)|0x38000, + (0x08<<18)|0x05100, + (0x09<<18)|0x24f08, + (0x0A<<18)|0x14000, + (0x0B<<18)|0x37d80, + (0x0C<<18)|0x0c100 // 11a: 0x0c300, 11g: 0x0c100 +}; + +u32 max2825_channel_data_24[][3] = +{ + {(0x03<<18)|0x30142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 01 + {(0x03<<18)|0x32141, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 02 + {(0x03<<18)|0x32143, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 03 + {(0x03<<18)|0x32142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 04 + {(0x03<<18)|0x31141, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 05 + {(0x03<<18)|0x31143, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 06 + {(0x03<<18)|0x31142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 07 + {(0x03<<18)|0x33141, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 08 + {(0x03<<18)|0x33143, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 09 + {(0x03<<18)|0x33142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 10 + {(0x03<<18)|0x30941, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 11 + {(0x03<<18)|0x30943, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 12 + {(0x03<<18)|0x30942, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 13 + {(0x03<<18)|0x32941, (0x04<<18)|0x09999, (0x05<<18)|0x289A6} // 14 (2484MHz) hhmodify +}; + +u32 max2825_power_data_24[] = {(0x0C<<18)|0x0c000, (0x0C<<18)|0x0c100}; + +/****************************************************************************/ +// MAX2827 (a/b/g) +u32 max2827_rf_data[] = +{ + (0x00<<18)|0x000a2, + (0x01<<18)|0x21cc0, + (0x02<<18)|0x13806, + (0x03<<18)|0x30142, + (0x04<<18)|0x0b333, + (0x05<<18)|0x289A6, + (0x06<<18)|0x18008, + (0x07<<18)|0x38000, + (0x08<<18)|0x05100, + (0x09<<18)|0x24f08, + (0x0A<<18)|0x14000, + (0x0B<<18)|0x37d80, + (0x0C<<18)|0x0c100 // 11a: 0x0c300, 11g: 0x0c100 +}; + +u32 max2827_channel_data_24[][3] = +{ + {(0x03<<18)|0x30142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 01 + {(0x03<<18)|0x32141, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 02 + {(0x03<<18)|0x32143, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 03 + {(0x03<<18)|0x32142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 04 + {(0x03<<18)|0x31141, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 05 + {(0x03<<18)|0x31143, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 06 + {(0x03<<18)|0x31142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 07 + {(0x03<<18)|0x33141, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 08 + {(0x03<<18)|0x33143, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 09 + {(0x03<<18)|0x33142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 10 + {(0x03<<18)|0x30941, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 11 + {(0x03<<18)|0x30943, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 12 + {(0x03<<18)|0x30942, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 13 + {(0x03<<18)|0x32941, (0x04<<18)|0x09999, (0x05<<18)|0x289A6} // 14 (2484MHz) hhmodify +}; + +u32 max2827_channel_data_50[][3] = +{ + {(0x03<<18)|0x33cc3, (0x04<<18)|0x08ccc, (0x05<<18)|0x2A9A6}, // channel 36 + {(0x03<<18)|0x302c0, (0x04<<18)|0x08000, (0x05<<18)|0x2A9A6}, // channel 40 + {(0x03<<18)|0x302c2, (0x04<<18)|0x0b333, (0x05<<18)|0x2A9A6}, // channel 44 + {(0x03<<18)|0x322c1, (0x04<<18)|0x09999, (0x05<<18)|0x2A9A6}, // channel 48 + {(0x03<<18)|0x312c1, (0x04<<18)|0x0a666, (0x05<<18)|0x2A9A6}, // channel 52 + {(0x03<<18)|0x332c3, (0x04<<18)|0x08ccc, (0x05<<18)|0x2A9A6}, // channel 56 + {(0x03<<18)|0x30ac0, (0x04<<18)|0x08000, (0x05<<18)|0x2A9A6}, // channel 60 + {(0x03<<18)|0x30ac2, (0x04<<18)|0x0b333, (0x05<<18)|0x2A9A6} // channel 64 +}; + +u32 max2827_power_data_24[] = {(0x0C<<18)|0x0C000, (0x0C<<18)|0x0D600, (0x0C<<18)|0x0C100}; +u32 max2827_power_data_50[] = {(0x0C<<18)|0x0C400, (0x0C<<18)|0x0D500, (0x0C<<18)|0x0C300}; + +/****************************************************************************/ +// MAX2828 (a/b/g) +u32 max2828_rf_data[] = +{ + (0x00<<18)|0x000a2, + (0x01<<18)|0x21cc0, + (0x02<<18)|0x13806, + (0x03<<18)|0x30142, + (0x04<<18)|0x0b333, + (0x05<<18)|0x289A6, + (0x06<<18)|0x18008, + (0x07<<18)|0x38000, + (0x08<<18)|0x05100, + (0x09<<18)|0x24f08, + (0x0A<<18)|0x14000, + (0x0B<<18)|0x37d80, + (0x0C<<18)|0x0c100 // 11a: 0x0c300, 11g: 0x0c100 +}; + +u32 max2828_channel_data_24[][3] = +{ + {(0x03<<18)|0x30142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 01 + {(0x03<<18)|0x32141, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 02 + {(0x03<<18)|0x32143, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 03 + {(0x03<<18)|0x32142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 04 + {(0x03<<18)|0x31141, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 05 + {(0x03<<18)|0x31143, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 06 + {(0x03<<18)|0x31142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 07 + {(0x03<<18)|0x33141, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 08 + {(0x03<<18)|0x33143, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 09 + {(0x03<<18)|0x33142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 10 + {(0x03<<18)|0x30941, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 11 + {(0x03<<18)|0x30943, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 12 + {(0x03<<18)|0x30942, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 13 + {(0x03<<18)|0x32941, (0x04<<18)|0x09999, (0x05<<18)|0x289A6} // 14 (2484MHz) hhmodify +}; + +u32 max2828_channel_data_50[][3] = +{ + {(0x03<<18)|0x33cc3, (0x04<<18)|0x08ccc, (0x05<<18)|0x289A6}, // channel 36 + {(0x03<<18)|0x302c0, (0x04<<18)|0x08000, (0x05<<18)|0x289A6}, // channel 40 + {(0x03<<18)|0x302c2, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channel 44 + {(0x03<<18)|0x322c1, (0x04<<18)|0x09999, (0x05<<18)|0x289A6}, // channel 48 + {(0x03<<18)|0x312c1, (0x04<<18)|0x0a666, (0x05<<18)|0x289A6}, // channel 52 + {(0x03<<18)|0x332c3, (0x04<<18)|0x08ccc, (0x05<<18)|0x289A6}, // channel 56 + {(0x03<<18)|0x30ac0, (0x04<<18)|0x08000, (0x05<<18)|0x289A6}, // channel 60 + {(0x03<<18)|0x30ac2, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6} // channel 64 +}; + +u32 max2828_power_data_24[] = {(0x0C<<18)|0x0c000, (0x0C<<18)|0x0c100}; +u32 max2828_power_data_50[] = {(0x0C<<18)|0x0c000, (0x0C<<18)|0x0c100}; + +/****************************************************************************/ +// LA20040728 kevin +// MAX2829 (a/b/g) +u32 max2829_rf_data[] = +{ + (0x00<<18)|0x000a2, + (0x01<<18)|0x23520, + (0x02<<18)|0x13802, + (0x03<<18)|0x30142, + (0x04<<18)|0x0b333, + (0x05<<18)|0x28906, + (0x06<<18)|0x18008, + (0x07<<18)|0x3B500, + (0x08<<18)|0x05100, + (0x09<<18)|0x24f08, + (0x0A<<18)|0x14000, + (0x0B<<18)|0x37d80, + (0x0C<<18)|0x0F300 //TXVGA=51, (MAX-6 dB) +}; + +u32 max2829_channel_data_24[][3] = +{ + {(3<<18)|0x30142, (4<<18)|0x0b333, (5<<18)|0x289C6}, // 01 (2412MHz) + {(3<<18)|0x32141, (4<<18)|0x08444, (5<<18)|0x289C6}, // 02 (2417MHz) + {(3<<18)|0x32143, (4<<18)|0x0aeee, (5<<18)|0x289C6}, // 03 (2422MHz) + {(3<<18)|0x32142, (4<<18)|0x0b333, (5<<18)|0x289C6}, // 04 (2427MHz) + {(3<<18)|0x31141, (4<<18)|0x08444, (5<<18)|0x289C6}, // 05 (2432MHz) + {(3<<18)|0x31143, (4<<18)|0x0aeee, (5<<18)|0x289C6}, // 06 (2437MHz) + {(3<<18)|0x31142, (4<<18)|0x0b333, (5<<18)|0x289C6}, // 07 (2442MHz) + {(3<<18)|0x33141, (4<<18)|0x08444, (5<<18)|0x289C6}, // 08 (2447MHz) + {(3<<18)|0x33143, (4<<18)|0x0aeee, (5<<18)|0x289C6}, // 09 (2452MHz) + {(3<<18)|0x33142, (4<<18)|0x0b333, (5<<18)|0x289C6}, // 10 (2457MHz) + {(3<<18)|0x30941, (4<<18)|0x08444, (5<<18)|0x289C6}, // 11 (2462MHz) + {(3<<18)|0x30943, (4<<18)|0x0aeee, (5<<18)|0x289C6}, // 12 (2467MHz) + {(3<<18)|0x30942, (4<<18)|0x0b333, (5<<18)|0x289C6}, // 13 (2472MHz) + {(3<<18)|0x32941, (4<<18)|0x09999, (5<<18)|0x289C6}, // 14 (2484MHz) hh-modify +}; + +u32 max2829_channel_data_50[][4] = +{ + {36, (3<<18)|0x33cc3, (4<<18)|0x08ccc, (5<<18)|0x2A946}, // 36 (5.180GHz) + {40, (3<<18)|0x302c0, (4<<18)|0x08000, (5<<18)|0x2A946}, // 40 (5.200GHz) + {44, (3<<18)|0x302c2, (4<<18)|0x0b333, (5<<18)|0x2A946}, // 44 (5.220GHz) + {48, (3<<18)|0x322c1, (4<<18)|0x09999, (5<<18)|0x2A946}, // 48 (5.240GHz) + {52, (3<<18)|0x312c1, (4<<18)|0x0a666, (5<<18)|0x2A946}, // 52 (5.260GHz) + {56, (3<<18)|0x332c3, (4<<18)|0x08ccc, (5<<18)|0x2A946}, // 56 (5.280GHz) + {60, (3<<18)|0x30ac0, (4<<18)|0x08000, (5<<18)|0x2A946}, // 60 (5.300GHz) + {64, (3<<18)|0x30ac2, (4<<18)|0x0b333, (5<<18)|0x2A946}, // 64 (5.320GHz) + + {100, (3<<18)|0x30ec0, (4<<18)|0x08000, (5<<18)|0x2A9C6}, // 100 (5.500GHz) + {104, (3<<18)|0x30ec2, (4<<18)|0x0b333, (5<<18)|0x2A9C6}, // 104 (5.520GHz) + {108, (3<<18)|0x32ec1, (4<<18)|0x09999, (5<<18)|0x2A9C6}, // 108 (5.540GHz) + {112, (3<<18)|0x31ec1, (4<<18)|0x0a666, (5<<18)|0x2A9C6}, // 112 (5.560GHz) + {116, (3<<18)|0x33ec3, (4<<18)|0x08ccc, (5<<18)|0x2A9C6}, // 116 (5.580GHz) + {120, (3<<18)|0x301c0, (4<<18)|0x08000, (5<<18)|0x2A9C6}, // 120 (5.600GHz) + {124, (3<<18)|0x301c2, (4<<18)|0x0b333, (5<<18)|0x2A9C6}, // 124 (5.620GHz) + {128, (3<<18)|0x321c1, (4<<18)|0x09999, (5<<18)|0x2A9C6}, // 128 (5.640GHz) + {132, (3<<18)|0x311c1, (4<<18)|0x0a666, (5<<18)|0x2A9C6}, // 132 (5.660GHz) + {136, (3<<18)|0x331c3, (4<<18)|0x08ccc, (5<<18)|0x2A9C6}, // 136 (5.680GHz) + {140, (3<<18)|0x309c0, (4<<18)|0x08000, (5<<18)|0x2A9C6}, // 140 (5.700GHz) + + {149, (3<<18)|0x329c2, (4<<18)|0x0b333, (5<<18)|0x2A9C6}, // 149 (5.745GHz) + {153, (3<<18)|0x319c1, (4<<18)|0x09999, (5<<18)|0x2A9C6}, // 153 (5.765GHz) + {157, (3<<18)|0x339c1, (4<<18)|0x0a666, (5<<18)|0x2A9C6}, // 157 (5.785GHz) + {161, (3<<18)|0x305c3, (4<<18)|0x08ccc, (5<<18)|0x2A9C6}, // 161 (5.805GHz) + + // Japan + { 184, (3<<18)|0x308c2, (4<<18)|0x0b333, (5<<18)|0x2A946}, // 184 (4.920GHz) + { 188, (3<<18)|0x328c1, (4<<18)|0x09999, (5<<18)|0x2A946}, // 188 (4.940GHz) + { 192, (3<<18)|0x318c1, (4<<18)|0x0a666, (5<<18)|0x2A946}, // 192 (4.960GHz) + { 196, (3<<18)|0x338c3, (4<<18)|0x08ccc, (5<<18)|0x2A946}, // 196 (4.980GHz) + { 8, (3<<18)|0x324c1, (4<<18)|0x09999, (5<<18)|0x2A946}, // 8 (5.040GHz) + { 12, (3<<18)|0x314c1, (4<<18)|0x0a666, (5<<18)|0x2A946}, // 12 (5.060GHz) + { 16, (3<<18)|0x334c3, (4<<18)|0x08ccc, (5<<18)|0x2A946}, // 16 (5.080GHz) + { 34, (3<<18)|0x31cc2, (4<<18)|0x0b333, (5<<18)|0x2A946}, // 34 (5.170GHz) + { 38, (3<<18)|0x33cc1, (4<<18)|0x09999, (5<<18)|0x2A946}, // 38 (5.190GHz) + { 42, (3<<18)|0x302c1, (4<<18)|0x0a666, (5<<18)|0x2A946}, // 42 (5.210GHz) + { 46, (3<<18)|0x322c3, (4<<18)|0x08ccc, (5<<18)|0x2A946}, // 46 (5.230GHz) +}; + +/***************************************************************************** +; For MAXIM2825/6/7 Ver. 317 or less +; Edited by Tiger, Sep-17-2003 for 2.4Ghz channels +; Updated by Tiger, Sep-22-2003 for 5.0Ghz channels +; Corrected by Tiger, Sep-23-2003, for 0x03 and 0x04 of 5.0Ghz channels + +0x00 0x00080 +0x01 0x214c0 +0x02 0x13802 + +;2.4GHz Channels +;channe1 01 (2.412GHz); 0x03 0x30143 ;0x04 0x0accc +;channe1 02 (2.417GHz); 0x03 0x32140 ;0x04 0x09111 +;channe1 03 (2.422GHz); 0x03 0x32142 ;0x04 0x0bbbb +;channe1 04 (2.427GHz); 0x03 0x32143 ;0x04 0x0accc +;channe1 05 (2.432GHz); 0x03 0x31140 ;0x04 0x09111 +;channe1 06 (2.437GHz); 0x03 0x31142 ;0x04 0x0bbbb +;channe1 07 (2.442GHz); 0x03 0x31143 ;0x04 0x0accc +;channe1 08 (2.447GHz); 0x03 0x33140 ;0x04 0x09111 +;channe1 09 (2.452GHz); 0x03 0x33142 ;0x04 0x0bbbb +;channe1 10 (2.457GHz); 0x03 0x33143 ;0x04 0x0accc +;channe1 11 (2.462GHz); 0x03 0x30940 ;0x04 0x09111 +;channe1 12 (2.467GHz); 0x03 0x30942 ;0x04 0x0bbbb +;channe1 13 (2.472GHz); 0x03 0x30943 ;0x04 0x0accc + +;5.0Ghz Channels +;channel 36 (5.180GHz); 0x03 0x33cc0 ;0x04 0x0b333 +;channel 40 (5.200GHz); 0x03 0x302c0 ;0x04 0x08000 +;channel 44 (5.220GHz); 0x03 0x302c2 ;0x04 0x0b333 +;channel 48 (5.240GHz); 0x03 0x322c1 ;0x04 0x09999 +;channel 52 (5.260GHz); 0x03 0x312c1 ;0x04 0x0a666 +;channel 56 (5.280GHz); 0x03 0x332c3 ;0x04 0x08ccc +;channel 60 (5.300GHz); 0x03 0x30ac0 ;0x04 0x08000 +;channel 64 (5.320GHz); 0x03 0x30ac2 ;0x04 0x08333 + +;2.4GHz band ;0x05 0x28986; +;5.0GHz band +0x05 0x2a986 + +0x06 0x18008 +0x07 0x38400 +0x08 0x05108 +0x09 0x27ff8 +0x0a 0x14000 +0x0b 0x37f99 +0x0c 0x0c000 +*****************************************************************************/ +u32 maxim_317_rf_data[] = +{ + (0x00<<18)|0x000a2, + (0x01<<18)|0x214c0, + (0x02<<18)|0x13802, + (0x03<<18)|0x30143, + (0x04<<18)|0x0accc, + (0x05<<18)|0x28986, + (0x06<<18)|0x18008, + (0x07<<18)|0x38400, + (0x08<<18)|0x05108, + (0x09<<18)|0x27ff8, + (0x0A<<18)|0x14000, + (0x0B<<18)|0x37f99, + (0x0C<<18)|0x0c000 +}; + +u32 maxim_317_channel_data_24[][3] = +{ + {(0x03<<18)|0x30143, (0x04<<18)|0x0accc, (0x05<<18)|0x28986}, // channe1 01 + {(0x03<<18)|0x32140, (0x04<<18)|0x09111, (0x05<<18)|0x28986}, // channe1 02 + {(0x03<<18)|0x32142, (0x04<<18)|0x0bbbb, (0x05<<18)|0x28986}, // channe1 03 + {(0x03<<18)|0x32143, (0x04<<18)|0x0accc, (0x05<<18)|0x28986}, // channe1 04 + {(0x03<<18)|0x31140, (0x04<<18)|0x09111, (0x05<<18)|0x28986}, // channe1 05 + {(0x03<<18)|0x31142, (0x04<<18)|0x0bbbb, (0x05<<18)|0x28986}, // channe1 06 + {(0x03<<18)|0x31143, (0x04<<18)|0x0accc, (0x05<<18)|0x28986}, // channe1 07 + {(0x03<<18)|0x33140, (0x04<<18)|0x09111, (0x05<<18)|0x28986}, // channe1 08 + {(0x03<<18)|0x33142, (0x04<<18)|0x0bbbb, (0x05<<18)|0x28986}, // channe1 09 + {(0x03<<18)|0x33143, (0x04<<18)|0x0accc, (0x05<<18)|0x28986}, // channe1 10 + {(0x03<<18)|0x30940, (0x04<<18)|0x09111, (0x05<<18)|0x28986}, // channe1 11 + {(0x03<<18)|0x30942, (0x04<<18)|0x0bbbb, (0x05<<18)|0x28986}, // channe1 12 + {(0x03<<18)|0x30943, (0x04<<18)|0x0accc, (0x05<<18)|0x28986} // channe1 13 +}; + +u32 maxim_317_channel_data_50[][3] = +{ + {(0x03<<18)|0x33cc0, (0x04<<18)|0x0b333, (0x05<<18)|0x2a986}, // channel 36 + {(0x03<<18)|0x302c0, (0x04<<18)|0x08000, (0x05<<18)|0x2a986}, // channel 40 + {(0x03<<18)|0x302c3, (0x04<<18)|0x0accc, (0x05<<18)|0x2a986}, // channel 44 + {(0x03<<18)|0x322c1, (0x04<<18)|0x09666, (0x05<<18)|0x2a986}, // channel 48 + {(0x03<<18)|0x312c2, (0x04<<18)|0x09999, (0x05<<18)|0x2a986}, // channel 52 + {(0x03<<18)|0x332c0, (0x04<<18)|0x0b333, (0x05<<18)|0x2a99e}, // channel 56 + {(0x03<<18)|0x30ac0, (0x04<<18)|0x08000, (0x05<<18)|0x2a99e}, // channel 60 + {(0x03<<18)|0x30ac3, (0x04<<18)|0x0accc, (0x05<<18)|0x2a99e} // channel 64 +}; + +u32 maxim_317_power_data_24[] = {(0x0C<<18)|0x0c000, (0x0C<<18)|0x0c100}; +u32 maxim_317_power_data_50[] = {(0x0C<<18)|0x0c000, (0x0C<<18)|0x0c100}; + +/***************************************************************************** +;;AL2230 MP (Mass Production Version) +;;RF Registers Setting for Airoha AL2230 silicon after June 1st, 2004 +;;Updated by Tiger Huang (June 1st, 2004) +;;20-bit length and LSB first + +;;Ch01 (2412MHz) ;0x00 0x09EFC ;0x01 0x8CCCC; +;;Ch02 (2417MHz) ;0x00 0x09EFC ;0x01 0x8CCCD; +;;Ch03 (2422MHz) ;0x00 0x09E7C ;0x01 0x8CCCC; +;;Ch04 (2427MHz) ;0x00 0x09E7C ;0x01 0x8CCCD; +;;Ch05 (2432MHz) ;0x00 0x05EFC ;0x01 0x8CCCC; +;;Ch06 (2437MHz) ;0x00 0x05EFC ;0x01 0x8CCCD; +;;Ch07 (2442MHz) ;0x00 0x05E7C ;0x01 0x8CCCC; +;;Ch08 (2447MHz) ;0x00 0x05E7C ;0x01 0x8CCCD; +;;Ch09 (2452MHz) ;0x00 0x0DEFC ;0x01 0x8CCCC; +;;Ch10 (2457MHz) ;0x00 0x0DEFC ;0x01 0x8CCCD; +;;Ch11 (2462MHz) ;0x00 0x0DE7C ;0x01 0x8CCCC; +;;Ch12 (2467MHz) ;0x00 0x0DE7C ;0x01 0x8CCCD; +;;Ch13 (2472MHz) ;0x00 0x03EFC ;0x01 0x8CCCC; +;;Ch14 (2484Mhz) ;0x00 0x03E7C ;0x01 0x86666; + +0x02 0x401D8; RXDCOC BW 100Hz for RXHP low +;;0x02 0x481DC; RXDCOC BW 30Khz for RXHP low + +0x03 0xCFFF0 +0x04 0x23800 +0x05 0xA3B72 +0x06 0x6DA01 +0x07 0xE1688 +0x08 0x11600 +0x09 0x99E02 +0x0A 0x5DDB0 +0x0B 0xD9900 +0x0C 0x3FFBD +0x0D 0xB0000 +0x0F 0xF00A0 + +;RF Calibration for Airoha AL2230 +;Edit by Ben Chang (01/30/04) +;Updated by Tiger Huang (03/03/04) +0x0f 0xf00a0 ; Initial Setting +0x0f 0xf00b0 ; Activate TX DCC +0x0f 0xf02a0 ; Activate Phase Calibration +0x0f 0xf00e0 ; Activate Filter RC Calibration +0x0f 0xf00a0 ; Restore Initial Setting +*****************************************************************************/ + +u32 al2230_rf_data[] = +{ + (0x00<<20)|0x09EFC, + (0x01<<20)|0x8CCCC, + (0x02<<20)|0x40058,// 20060627 Anson 0x401D8, + (0x03<<20)|0xCFFF0, + (0x04<<20)|0x24100,// 20060627 Anson 0x23800, + (0x05<<20)|0xA3B2F,// 20060627 Anson 0xA3B72 + (0x06<<20)|0x6DA01, + (0x07<<20)|0xE3628,// 20060627 Anson 0xE1688, + (0x08<<20)|0x11600, + (0x09<<20)|0x9DC02,// 20060627 Anosn 0x97602,//0x99E02, //0x9AE02 + (0x0A<<20)|0x5ddb0, // 941206 For QCOM interference 0x588b0,//0x5DDB0, 940601 adj 0x5aa30 for bluetooth + (0x0B<<20)|0xD9900, + (0x0C<<20)|0x3FFBD, + (0x0D<<20)|0xB0000, + (0x0F<<20)|0xF01A0 // 20060627 Anson 0xF00A0 +}; + +u32 al2230s_rf_data[] = +{ + (0x00<<20)|0x09EFC, + (0x01<<20)|0x8CCCC, + (0x02<<20)|0x40058,// 20060419 0x401D8, + (0x03<<20)|0xCFFF0, + (0x04<<20)|0x24100,// 20060419 0x23800, + (0x05<<20)|0xA3B2F,// 20060419 0xA3B72, + (0x06<<20)|0x6DA01, + (0x07<<20)|0xE3628,// 20060419 0xE1688, + (0x08<<20)|0x11600, + (0x09<<20)|0x9DC02,// 20060419 0x97602,//0x99E02, //0x9AE02 + (0x0A<<20)|0x5DDB0,// 941206 For QCOM interference 0x588b0,//0x5DDB0, 940601 adj 0x5aa30 for bluetooth + (0x0B<<20)|0xD9900, + (0x0C<<20)|0x3FFBD, + (0x0D<<20)|0xB0000, + (0x0F<<20)|0xF01A0 // 20060419 0xF00A0 +}; + +u32 al2230_channel_data_24[][2] = +{ + {(0x00<<20)|0x09EFC, (0x01<<20)|0x8CCCC}, // channe1 01 + {(0x00<<20)|0x09EFC, (0x01<<20)|0x8CCCD}, // channe1 02 + {(0x00<<20)|0x09E7C, (0x01<<20)|0x8CCCC}, // channe1 03 + {(0x00<<20)|0x09E7C, (0x01<<20)|0x8CCCD}, // channe1 04 + {(0x00<<20)|0x05EFC, (0x01<<20)|0x8CCCC}, // channe1 05 + {(0x00<<20)|0x05EFC, (0x01<<20)|0x8CCCD}, // channe1 06 + {(0x00<<20)|0x05E7C, (0x01<<20)|0x8CCCC}, // channe1 07 + {(0x00<<20)|0x05E7C, (0x01<<20)|0x8CCCD}, // channe1 08 + {(0x00<<20)|0x0DEFC, (0x01<<20)|0x8CCCC}, // channe1 09 + {(0x00<<20)|0x0DEFC, (0x01<<20)|0x8CCCD}, // channe1 10 + {(0x00<<20)|0x0DE7C, (0x01<<20)|0x8CCCC}, // channe1 11 + {(0x00<<20)|0x0DE7C, (0x01<<20)|0x8CCCD}, // channe1 12 + {(0x00<<20)|0x03EFC, (0x01<<20)|0x8CCCC}, // channe1 13 + {(0x00<<20)|0x03E7C, (0x01<<20)|0x86666} // channe1 14 +}; + +// Current setting. u32 airoha_power_data_24[] = {(0x09<<20)|0x90202, (0x09<<20)|0x96602, (0x09<<20)|0x97602}; +#define AIROHA_TXVGA_LOW_INDEX 31 // Index for 0x90202 +#define AIROHA_TXVGA_MIDDLE_INDEX 12 // Index for 0x96602 +#define AIROHA_TXVGA_HIGH_INDEX 8 // Index for 0x97602 1.0.24.0 1.0.28.0 +/* +u32 airoha_power_data_24[] = +{ + 0x9FE02, // Max - 0 dB + 0x9BE02, // Max - 1 dB + 0x9DE02, // Max - 2 dB + 0x99E02, // Max - 3 dB + 0x9EE02, // Max - 4 dB + 0x9AE02, // Max - 5 dB + 0x9CE02, // Max - 6 dB + 0x98E02, // Max - 7 dB + 0x97602, // Max - 8 dB + 0x93602, // Max - 9 dB + 0x95602, // Max - 10 dB + 0x91602, // Max - 11 dB + 0x96602, // Max - 12 dB + 0x92602, // Max - 13 dB + 0x94602, // Max - 14 dB + 0x90602, // Max - 15 dB + 0x97A02, // Max - 16 dB + 0x93A02, // Max - 17 dB + 0x95A02, // Max - 18 dB + 0x91A02, // Max - 19 dB + 0x96A02, // Max - 20 dB + 0x92A02, // Max - 21 dB + 0x94A02, // Max - 22 dB + 0x90A02, // Max - 23 dB + 0x97202, // Max - 24 dB + 0x93202, // Max - 25 dB + 0x95202, // Max - 26 dB + 0x91202, // Max - 27 dB + 0x96202, // Max - 28 dB + 0x92202, // Max - 29 dB + 0x94202, // Max - 30 dB + 0x90202 // Max - 31 dB +}; +*/ + +// 20040927 1.1.69.1000 ybjiang +// from John +u32 al2230_txvga_data[][2] = +{ + //value , index + {0x090202, 0}, + {0x094202, 2}, + {0x092202, 4}, + {0x096202, 6}, + {0x091202, 8}, + {0x095202, 10}, + {0x093202, 12}, + {0x097202, 14}, + {0x090A02, 16}, + {0x094A02, 18}, + {0x092A02, 20}, + {0x096A02, 22}, + {0x091A02, 24}, + {0x095A02, 26}, + {0x093A02, 28}, + {0x097A02, 30}, + {0x090602, 32}, + {0x094602, 34}, + {0x092602, 36}, + {0x096602, 38}, + {0x091602, 40}, + {0x095602, 42}, + {0x093602, 44}, + {0x097602, 46}, + {0x090E02, 48}, + {0x098E02, 49}, + {0x094E02, 50}, + {0x09CE02, 51}, + {0x092E02, 52}, + {0x09AE02, 53}, + {0x096E02, 54}, + {0x09EE02, 55}, + {0x091E02, 56}, + {0x099E02, 57}, + {0x095E02, 58}, + {0x09DE02, 59}, + {0x093E02, 60}, + {0x09BE02, 61}, + {0x097E02, 62}, + {0x09FE02, 63} +}; + +//-------------------------------- +// For Airoha AL7230, 2.4Ghz band +// Edit by Tiger, (March, 9, 2005) +// 24bit, MSB first + +//channel independent registers: +u32 al7230_rf_data_24[] = +{ + (0x00<<24)|0x003790, + (0x01<<24)|0x133331, + (0x02<<24)|0x841FF2, + (0x03<<24)|0x3FDFA3, + (0x04<<24)|0x7FD784, + (0x05<<24)|0x802B55, + (0x06<<24)|0x56AF36, + (0x07<<24)|0xCE0207, + (0x08<<24)|0x6EBC08, + (0x09<<24)|0x221BB9, + (0x0A<<24)|0xE0000A, + (0x0B<<24)|0x08071B, + (0x0C<<24)|0x000A3C, + (0x0D<<24)|0xFFFFFD, + (0x0E<<24)|0x00000E, + (0x0F<<24)|0x1ABA8F +}; + +u32 al7230_channel_data_24[][2] = +{ + {(0x00<<24)|0x003790, (0x01<<24)|0x133331}, // channe1 01 + {(0x00<<24)|0x003790, (0x01<<24)|0x1B3331}, // channe1 02 + {(0x00<<24)|0x003790, (0x01<<24)|0x033331}, // channe1 03 + {(0x00<<24)|0x003790, (0x01<<24)|0x0B3331}, // channe1 04 + {(0x00<<24)|0x0037A0, (0x01<<24)|0x133331}, // channe1 05 + {(0x00<<24)|0x0037A0, (0x01<<24)|0x1B3331}, // channe1 06 + {(0x00<<24)|0x0037A0, (0x01<<24)|0x033331}, // channe1 07 + {(0x00<<24)|0x0037A0, (0x01<<24)|0x0B3331}, // channe1 08 + {(0x00<<24)|0x0037B0, (0x01<<24)|0x133331}, // channe1 09 + {(0x00<<24)|0x0037B0, (0x01<<24)|0x1B3331}, // channe1 10 + {(0x00<<24)|0x0037B0, (0x01<<24)|0x033331}, // channe1 11 + {(0x00<<24)|0x0037B0, (0x01<<24)|0x0B3331}, // channe1 12 + {(0x00<<24)|0x0037C0, (0x01<<24)|0x133331}, // channe1 13 + {(0x00<<24)|0x0037C0, (0x01<<24)|0x066661} // channel 14 +}; + +//channel independent registers: +u32 al7230_rf_data_50[] = +{ + (0x00<<24)|0x0FF520, + (0x01<<24)|0x000001, + (0x02<<24)|0x451FE2, + (0x03<<24)|0x5FDFA3, + (0x04<<24)|0x6FD784, + (0x05<<24)|0x853F55, + (0x06<<24)|0x56AF36, + (0x07<<24)|0xCE0207, + (0x08<<24)|0x6EBC08, + (0x09<<24)|0x221BB9, + (0x0A<<24)|0xE0600A, + (0x0B<<24)|0x08044B, + (0x0C<<24)|0x00143C, + (0x0D<<24)|0xFFFFFD, + (0x0E<<24)|0x00000E, + (0x0F<<24)|0x12BACF //5Ghz default state +}; + +u32 al7230_channel_data_5[][4] = +{ + //channel dependent registers: 0x00, 0x01 and 0x04 + //11J =========== + {184, (0x00<<24)|0x0FF520, (0x01<<24)|0x000001, (0x04<<24)|0x67F784}, // channel 184 + {188, (0x00<<24)|0x0FF520, (0x01<<24)|0x0AAAA1, (0x04<<24)|0x77F784}, // channel 188 + {192, (0x00<<24)|0x0FF530, (0x01<<24)|0x155551, (0x04<<24)|0x77F784}, // channel 192 + {196, (0x00<<24)|0x0FF530, (0x01<<24)|0x000001, (0x04<<24)|0x67F784}, // channel 196 + {8, (0x00<<24)|0x0FF540, (0x01<<24)|0x000001, (0x04<<24)|0x67F784}, // channel 008 + {12, (0x00<<24)|0x0FF540, (0x01<<24)|0x0AAAA1, (0x04<<24)|0x77F784}, // channel 012 + {16, (0x00<<24)|0x0FF550, (0x01<<24)|0x155551, (0x04<<24)|0x77F784}, // channel 016 + {34, (0x00<<24)|0x0FF560, (0x01<<24)|0x055551, (0x04<<24)|0x77F784}, // channel 034 + {38, (0x00<<24)|0x0FF570, (0x01<<24)|0x100001, (0x04<<24)|0x77F784}, // channel 038 + {42, (0x00<<24)|0x0FF570, (0x01<<24)|0x1AAAA1, (0x04<<24)|0x77F784}, // channel 042 + {46, (0x00<<24)|0x0FF570, (0x01<<24)|0x055551, (0x04<<24)|0x77F784}, // channel 046 + //11 A/H ========= + {36, (0x00<<24)|0x0FF560, (0x01<<24)|0x0AAAA1, (0x04<<24)|0x77F784}, // channel 036 + {40, (0x00<<24)|0x0FF570, (0x01<<24)|0x155551, (0x04<<24)|0x77F784}, // channel 040 + {44, (0x00<<24)|0x0FF570, (0x01<<24)|0x000001, (0x04<<24)|0x67F784}, // channel 044 + {48, (0x00<<24)|0x0FF570, (0x01<<24)|0x0AAAA1, (0x04<<24)|0x77F784}, // channel 048 + {52, (0x00<<24)|0x0FF580, (0x01<<24)|0x155551, (0x04<<24)|0x77F784}, // channel 052 + {56, (0x00<<24)|0x0FF580, (0x01<<24)|0x000001, (0x04<<24)|0x67F784}, // channel 056 + {60, (0x00<<24)|0x0FF580, (0x01<<24)|0x0AAAA1, (0x04<<24)|0x77F784}, // channel 060 + {64, (0x00<<24)|0x0FF590, (0x01<<24)|0x155551, (0x04<<24)|0x77F784}, // channel 064 + {100, (0x00<<24)|0x0FF5C0, (0x01<<24)|0x155551, (0x04<<24)|0x77F784}, // channel 100 + {104, (0x00<<24)|0x0FF5C0, (0x01<<24)|0x000001, (0x04<<24)|0x67F784}, // channel 104 + {108, (0x00<<24)|0x0FF5C0, (0x01<<24)|0x0AAAA1, (0x04<<24)|0x77F784}, // channel 108 + {112, (0x00<<24)|0x0FF5D0, (0x01<<24)|0x155551, (0x04<<24)|0x77F784}, // channel 112 + {116, (0x00<<24)|0x0FF5D0, (0x01<<24)|0x000001, (0x04<<24)|0x67F784}, // channel 116 + {120, (0x00<<24)|0x0FF5D0, (0x01<<24)|0x0AAAA1, (0x04<<24)|0x77F784}, // channel 120 + {124, (0x00<<24)|0x0FF5E0, (0x01<<24)|0x155551, (0x04<<24)|0x77F784}, // channel 124 + {128, (0x00<<24)|0x0FF5E0, (0x01<<24)|0x000001, (0x04<<24)|0x67F784}, // channel 128 + {132, (0x00<<24)|0x0FF5E0, (0x01<<24)|0x0AAAA1, (0x04<<24)|0x77F784}, // channel 132 + {136, (0x00<<24)|0x0FF5F0, (0x01<<24)|0x155551, (0x04<<24)|0x77F784}, // channel 136 + {140, (0x00<<24)|0x0FF5F0, (0x01<<24)|0x000001, (0x04<<24)|0x67F784}, // channel 140 + {149, (0x00<<24)|0x0FF600, (0x01<<24)|0x180001, (0x04<<24)|0x77F784}, // channel 149 + {153, (0x00<<24)|0x0FF600, (0x01<<24)|0x02AAA1, (0x04<<24)|0x77F784}, // channel 153 + {157, (0x00<<24)|0x0FF600, (0x01<<24)|0x0D5551, (0x04<<24)|0x77F784}, // channel 157 + {161, (0x00<<24)|0x0FF610, (0x01<<24)|0x180001, (0x04<<24)|0x77F784}, // channel 161 + {165, (0x00<<24)|0x0FF610, (0x01<<24)|0x02AAA1, (0x04<<24)|0x77F784} // channel 165 +}; + +//; RF Calibration <=== Register 0x0F +//0x0F 0x1ABA8F; start from 2.4Ghz default state +//0x0F 0x9ABA8F; TXDC compensation +//0x0F 0x3ABA8F; RXFIL adjustment +//0x0F 0x1ABA8F; restore 2.4Ghz default state + +//;TXVGA Mapping Table <=== Register 0x0B +u32 al7230_txvga_data[][2] = +{ + {0x08040B, 0}, //TXVGA=0; + {0x08041B, 1}, //TXVGA=1; + {0x08042B, 2}, //TXVGA=2; + {0x08043B, 3}, //TXVGA=3; + {0x08044B, 4}, //TXVGA=4; + {0x08045B, 5}, //TXVGA=5; + {0x08046B, 6}, //TXVGA=6; + {0x08047B, 7}, //TXVGA=7; + {0x08048B, 8}, //TXVGA=8; + {0x08049B, 9}, //TXVGA=9; + {0x0804AB, 10}, //TXVGA=10; + {0x0804BB, 11}, //TXVGA=11; + {0x0804CB, 12}, //TXVGA=12; + {0x0804DB, 13}, //TXVGA=13; + {0x0804EB, 14}, //TXVGA=14; + {0x0804FB, 15}, //TXVGA=15; + {0x08050B, 16}, //TXVGA=16; + {0x08051B, 17}, //TXVGA=17; + {0x08052B, 18}, //TXVGA=18; + {0x08053B, 19}, //TXVGA=19; + {0x08054B, 20}, //TXVGA=20; + {0x08055B, 21}, //TXVGA=21; + {0x08056B, 22}, //TXVGA=22; + {0x08057B, 23}, //TXVGA=23; + {0x08058B, 24}, //TXVGA=24; + {0x08059B, 25}, //TXVGA=25; + {0x0805AB, 26}, //TXVGA=26; + {0x0805BB, 27}, //TXVGA=27; + {0x0805CB, 28}, //TXVGA=28; + {0x0805DB, 29}, //TXVGA=29; + {0x0805EB, 30}, //TXVGA=30; + {0x0805FB, 31}, //TXVGA=31; + {0x08060B, 32}, //TXVGA=32; + {0x08061B, 33}, //TXVGA=33; + {0x08062B, 34}, //TXVGA=34; + {0x08063B, 35}, //TXVGA=35; + {0x08064B, 36}, //TXVGA=36; + {0x08065B, 37}, //TXVGA=37; + {0x08066B, 38}, //TXVGA=38; + {0x08067B, 39}, //TXVGA=39; + {0x08068B, 40}, //TXVGA=40; + {0x08069B, 41}, //TXVGA=41; + {0x0806AB, 42}, //TXVGA=42; + {0x0806BB, 43}, //TXVGA=43; + {0x0806CB, 44}, //TXVGA=44; + {0x0806DB, 45}, //TXVGA=45; + {0x0806EB, 46}, //TXVGA=46; + {0x0806FB, 47}, //TXVGA=47; + {0x08070B, 48}, //TXVGA=48; + {0x08071B, 49}, //TXVGA=49; + {0x08072B, 50}, //TXVGA=50; + {0x08073B, 51}, //TXVGA=51; + {0x08074B, 52}, //TXVGA=52; + {0x08075B, 53}, //TXVGA=53; + {0x08076B, 54}, //TXVGA=54; + {0x08077B, 55}, //TXVGA=55; + {0x08078B, 56}, //TXVGA=56; + {0x08079B, 57}, //TXVGA=57; + {0x0807AB, 58}, //TXVGA=58; + {0x0807BB, 59}, //TXVGA=59; + {0x0807CB, 60}, //TXVGA=60; + {0x0807DB, 61}, //TXVGA=61; + {0x0807EB, 62}, //TXVGA=62; + {0x0807FB, 63}, //TXVGA=63; +}; +//-------------------------------- + + +//; W89RF242 RFIC SPI programming initial data +//; Winbond WLAN 11g RFIC BB-SPI register -- version FA5976A rev 1.3b +//; Update Date: Ocotber 3, 2005 by PP10 Hsiang-Te Ho +//; +//; Version 1.3b revision items: (Oct. 1, 2005 by HTHo) for FA5976A +u32 w89rf242_rf_data[] = +{ + (0x00<<24)|0xF86100, // 20060721 0xF86100, //; 3E184; MODA (0x00) -- Normal mode ; calibration off + (0x01<<24)|0xEFFFC2, //; 3BFFF; MODB (0x01) -- turn off RSSI, and other circuits are turned on + (0x02<<24)|0x102504, //; 04094; FSET (0x02) -- default 20MHz crystal ; Icmp=1.5mA + (0x03<<24)|0x026286, //; 0098A; FCHN (0x03) -- default CH7, 2442MHz + (0x04<<24)|0x000208, // 20060612.1.a 0x0002C8, // 20050818 // 20050816 0x000388 + //; 02008; FCAL (0x04) -- XTAL Freq Trim=001000 (socket board#1); FA5976AYG_v1.3C + (0x05<<24)|0x24C60A, // 20060612.1.a 0x24C58A, // 941003 0x24C48A, // 20050818.2 0x24848A, // 20050818 // 20050816 0x24C48A + //; 09316; GANA (0x05) -- TX VGA default (TXVGA=0x18(12)) & TXGPK=110 ; FA5976A_1.3D + (0x06<<24)|0x3432CC, // 941003 0x26C34C, // 20050818 0x06B40C + //; 0D0CB; GANB (0x06) -- RXDC(DC offset) on; LNA=11; RXVGA=001011(11) ; RXFLSW=11(010001); RXGPK=00; RXGCF=00; -50dBm input + (0x07<<24)|0x0C68CE, // 20050818.2 0x0C66CE, // 20050818 // 20050816 0x0C68CE + //; 031A3; FILT (0x07) -- TX/RX filter with auto-tuning; TFLBW=011; RFLBW=100 + (0x08<<24)|0x100010, //; 04000; TCAL (0x08) -- //for LO + (0x09<<24)|0x004012, // 20060612.1.a 0x6E4012, // 0x004012, + //; 1B900; RCALA (0x09) -- FASTS=11; HPDE=01 (100nsec); SEHP=1 (select B0 pin=RXHP); RXHP=1 (Turn on RXHP function)(FA5976A_1.3C) + (0x0A<<24)|0x704014, //; 1C100; RCALB (0x0A) + (0x0B<<24)|0x18BDD6, // 941003 0x1805D6, // 20050818.2 0x1801D6, // 20050818 // 20050816 0x1805D6 + //; 062F7; IQCAL (0x0B) -- Turn on LO phase tuner=0111 & RX-LO phase = 0111; FA5976A_1.3B (2005/09/29) + (0x0C<<24)|0x575558, // 20050818.2 0x555558, // 20050818 // 20050816 0x575558 + //; 15D55 ; IBSA (0x0C) -- IFPre =11 ; TC5376A_v1.3A for corner + (0x0D<<24)|0x55545A, // 20060612.1.a 0x55555A, + //; 15555 ; IBSB (0x0D) + (0x0E<<24)|0x5557DC, // 20060612.1.a 0x55555C, // 941003 0x5557DC, + //; 1555F ; IBSC (0x0E) -- IRLNA & IRLNB (PTAT & Const current)=01/01; FA5976B_1.3F (2005/11/25) + (0x10<<24)|0x000C20, // 941003 0x000020, // 20050818 + //; 00030 ; TMODA (0x10) -- LNA_gain_step=0011 ; LNA=15/16dB + (0x11<<24)|0x0C0022, // 941003 0x030022 // 20050818.2 0x030022 // 20050818 // 20050816 0x0C0022 + //; 03000 ; TMODB (0x11) -- Turn ON RX-Q path Test Switch; To improve IQ path group delay (FA5976A_1.3C) + (0x12<<24)|0x000024 // 20060612.1.a 0x001824 // 941003 add + //; TMODC (0x12) -- Turn OFF Tempearure sensor +}; + +u32 w89rf242_channel_data_24[][2] = +{ + {(0x03<<24)|0x025B06, (0x04<<24)|0x080408}, // channe1 01 + {(0x03<<24)|0x025C46, (0x04<<24)|0x080408}, // channe1 02 + {(0x03<<24)|0x025D86, (0x04<<24)|0x080408}, // channe1 03 + {(0x03<<24)|0x025EC6, (0x04<<24)|0x080408}, // channe1 04 + {(0x03<<24)|0x026006, (0x04<<24)|0x080408}, // channe1 05 + {(0x03<<24)|0x026146, (0x04<<24)|0x080408}, // channe1 06 + {(0x03<<24)|0x026286, (0x04<<24)|0x080408}, // channe1 07 + {(0x03<<24)|0x0263C6, (0x04<<24)|0x080408}, // channe1 08 + {(0x03<<24)|0x026506, (0x04<<24)|0x080408}, // channe1 09 + {(0x03<<24)|0x026646, (0x04<<24)|0x080408}, // channe1 10 + {(0x03<<24)|0x026786, (0x04<<24)|0x080408}, // channe1 11 + {(0x03<<24)|0x0268C6, (0x04<<24)|0x080408}, // channe1 12 + {(0x03<<24)|0x026A06, (0x04<<24)|0x080408}, // channe1 13 + {(0x03<<24)|0x026D06, (0x04<<24)|0x080408} // channe1 14 +}; + +u32 w89rf242_power_data_24[] = {(0x05<<24)|0x24C48A, (0x05<<24)|0x24C48A, (0x05<<24)|0x24C48A}; + +// 20060315.6 Enlarge for new scale +// 20060316.6 20060619.2.a add mapping array +u32 w89rf242_txvga_old_mapping[][2] = +{ + {0, 0} , // New <-> Old + {1, 1} , + {2, 2} , + {3, 3} , + {4, 4} , + {6, 5} , + {8, 6 }, + {10, 7 }, + {12, 8 }, + {14, 9 }, + {16, 10}, + {18, 11}, + {20, 12}, + {22, 13}, + {24, 14}, + {26, 15}, + {28, 16}, + {30, 17}, + {32, 18}, + {34, 19}, + + +}; + +// 20060619.3 modify from Bruce's mail +u32 w89rf242_txvga_data[][5] = +{ + //low gain mode + { (0x05<<24)|0x24C00A, 0, 0x00292315, 0x0800FEFF, 0x52523131 },// ; min gain + { (0x05<<24)|0x24C80A, 1, 0x00292315, 0x0800FEFF, 0x52523131 }, + { (0x05<<24)|0x24C04A, 2, 0x00292315, 0x0800FEFF, 0x52523131 },// (default) +14dBm (ANT) + { (0x05<<24)|0x24C84A, 3, 0x00292315, 0x0800FEFF, 0x52523131 }, + + //TXVGA=0x10 + { (0x05<<24)|0x24C40A, 4, 0x00292315, 0x0800FEFF, 0x60603838 }, + { (0x05<<24)|0x24C40A, 5, 0x00262114, 0x0700FEFF, 0x65653B3B }, + + //TXVGA=0x11 + { (0x05<<24)|0x24C44A, 6, 0x00241F13, 0x0700FFFF, 0x58583333 }, + { (0x05<<24)|0x24C44A, 7, 0x00292315, 0x0800FEFF, 0x5E5E3737 }, + + //TXVGA=0x12 + { (0x05<<24)|0x24C48A, 8, 0x00262114, 0x0700FEFF, 0x53533030 }, + { (0x05<<24)|0x24C48A, 9, 0x00241F13, 0x0700FFFF, 0x59593434 }, + + //TXVGA=0x13 + { (0x05<<24)|0x24C4CA, 10, 0x00292315, 0x0800FEFF, 0x52523030 }, + { (0x05<<24)|0x24C4CA, 11, 0x00262114, 0x0700FEFF, 0x56563232 }, + + //TXVGA=0x14 + { (0x05<<24)|0x24C50A, 12, 0x00292315, 0x0800FEFF, 0x54543131 }, + { (0x05<<24)|0x24C50A, 13, 0x00262114, 0x0700FEFF, 0x58583434 }, + + //TXVGA=0x15 + { (0x05<<24)|0x24C54A, 14, 0x00292315, 0x0800FEFF, 0x54543131 }, + { (0x05<<24)|0x24C54A, 15, 0x00262114, 0x0700FEFF, 0x59593434 }, + + //TXVGA=0x16 + { (0x05<<24)|0x24C58A, 16, 0x00292315, 0x0800FEFF, 0x55553131 }, + { (0x05<<24)|0x24C58A, 17, 0x00292315, 0x0800FEFF, 0x5B5B3535 }, + + //TXVGA=0x17 + { (0x05<<24)|0x24C5CA, 18, 0x00262114, 0x0700FEFF, 0x51512F2F }, + { (0x05<<24)|0x24C5CA, 19, 0x00241F13, 0x0700FFFF, 0x55553131 }, + + //TXVGA=0x18 + { (0x05<<24)|0x24C60A, 20, 0x00292315, 0x0800FEFF, 0x4F4F2E2E }, + { (0x05<<24)|0x24C60A, 21, 0x00262114, 0x0700FEFF, 0x53533030 }, + + //TXVGA=0x19 + { (0x05<<24)|0x24C64A, 22, 0x00292315, 0x0800FEFF, 0x4E4E2D2D }, + { (0x05<<24)|0x24C64A, 23, 0x00262114, 0x0700FEFF, 0x53533030 }, + + //TXVGA=0x1A + { (0x05<<24)|0x24C68A, 24, 0x00292315, 0x0800FEFF, 0x50502E2E }, + { (0x05<<24)|0x24C68A, 25, 0x00262114, 0x0700FEFF, 0x55553131 }, + + //TXVGA=0x1B + { (0x05<<24)|0x24C6CA, 26, 0x00262114, 0x0700FEFF, 0x53533030 }, + { (0x05<<24)|0x24C6CA, 27, 0x00292315, 0x0800FEFF, 0x5A5A3434 }, + + //TXVGA=0x1C + { (0x05<<24)|0x24C70A, 28, 0x00292315, 0x0800FEFF, 0x55553131 }, + { (0x05<<24)|0x24C70A, 29, 0x00292315, 0x0800FEFF, 0x5D5D3636 }, + + //TXVGA=0x1D + { (0x05<<24)|0x24C74A, 30, 0x00292315, 0x0800FEFF, 0x5F5F3737 }, + { (0x05<<24)|0x24C74A, 31, 0x00262114, 0x0700FEFF, 0x65653B3B }, + + //TXVGA=0x1E + { (0x05<<24)|0x24C78A, 32, 0x00292315, 0x0800FEFF, 0x66663B3B }, + { (0x05<<24)|0x24C78A, 33, 0x00262114, 0x0700FEFF, 0x70704141 }, + + //TXVGA=0x1F + { (0x05<<24)|0x24C7CA, 34, 0x00292315, 0x0800FEFF, 0x72724242 } +}; + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// + + + +//============================================================================================================= +// Uxx_ReadEthernetAddress -- +// +// Routine Description: +// Reads in the Ethernet address from the IC. +// +// Arguments: +// pHwData - The pHwData structure +// +// Return Value: +// +// The address is stored in EthernetIDAddr. +//============================================================================================================= +void +Uxx_ReadEthernetAddress( phw_data_t pHwData ) +{ + u32 ltmp; + + // Reading Ethernet address from EEPROM and set into hardware due to MAC address maybe change. + // Only unplug and plug again can make hardware read EEPROM again. 20060727 + Wb35Reg_WriteSync( pHwData, 0x03b4, 0x08000000 ); // Start EEPROM access + Read + address(0x0d) + Wb35Reg_ReadSync( pHwData, 0x03b4, <mp ); + *(PUSHORT)pHwData->PermanentMacAddress = cpu_to_le16((u16)ltmp); //20060926 anson's endian + Wb35Reg_WriteSync( pHwData, 0x03b4, 0x08010000 ); // Start EEPROM access + Read + address(0x0d) + Wb35Reg_ReadSync( pHwData, 0x03b4, <mp ); + *(PUSHORT)(pHwData->PermanentMacAddress + 2) = cpu_to_le16((u16)ltmp); //20060926 anson's endian + Wb35Reg_WriteSync( pHwData, 0x03b4, 0x08020000 ); // Start EEPROM access + Read + address(0x0d) + Wb35Reg_ReadSync( pHwData, 0x03b4, <mp ); + *(PUSHORT)(pHwData->PermanentMacAddress + 4) = cpu_to_le16((u16)ltmp); //20060926 anson's endian + *(PUSHORT)(pHwData->PermanentMacAddress + 6) = 0; + Wb35Reg_WriteSync( pHwData, 0x03e8, cpu_to_le32(*(PULONG)pHwData->PermanentMacAddress) ); //20060926 anson's endian + Wb35Reg_WriteSync( pHwData, 0x03ec, cpu_to_le32(*(PULONG)(pHwData->PermanentMacAddress+4)) ); //20060926 anson's endian +} + + +//=============================================================================================================== +// CardGetMulticastBit -- +// Description: +// For a given multicast address, returns the byte and bit in the card multicast registers that it hashes to. +// Calls CardComputeCrc() to determine the CRC value. +// Arguments: +// Address - the address +// Byte - the byte that it hashes to +// Value - will have a 1 in the relevant bit +// Return Value: +// None. +//============================================================================================================== +void CardGetMulticastBit( u8 Address[ETH_LENGTH_OF_ADDRESS], + u8 *Byte, u8 *Value ) +{ + u32 Crc; + u32 BitNumber; + + // First compute the CRC. + Crc = CardComputeCrc(Address, ETH_LENGTH_OF_ADDRESS); + + // The computed CRC is bit0~31 from left to right + //At first we should do right shift 25bits, and read 7bits by using '&', 2^7=128 + BitNumber = (u32) ((Crc >> 26) & 0x3f); + + *Byte = (u8) (BitNumber >> 3);// 900514 original (BitNumber / 8) + *Value = (u8) ((u8)1 << (BitNumber % 8)); +} + +void Uxx_power_on_procedure( phw_data_t pHwData ) +{ + u32 ltmp, loop; + + if( pHwData->phy_type <= RF_MAXIM_V1 ) + Wb35Reg_WriteSync( pHwData, 0x03d4, 0xffffff38 ); + else + { + Wb35Reg_WriteSync( pHwData, 0x03f4, 0xFF5807FF );// 20060721 For NEW IC 0xFF5807FF + + // 20060511.1 Fix the following 4 steps for Rx of RF 2230 initial fail + Wb35Reg_WriteSync( pHwData, 0x03d4, 0x80 );// regulator on only + OS_SLEEP(10000); // Modify 20051221.1.b + Wb35Reg_WriteSync( pHwData, 0x03d4, 0xb8 );// REG_ON RF_RSTN on, and + OS_SLEEP(10000); // Modify 20051221.1.b + + ltmp = 0x4968; + if( (pHwData->phy_type == RF_WB_242) || + (RF_WB_242_1 == pHwData->phy_type) ) // 20060619.5 Add + ltmp = 0x4468; + Wb35Reg_WriteSync( pHwData, 0x03d0, ltmp ); + + Wb35Reg_WriteSync( pHwData, 0x03d4, 0xa0 );// PLL_PD REF_PD set to 0 + + OS_SLEEP(20000); // Modify 20051221.1.b + Wb35Reg_ReadSync( pHwData, 0x03d0, <mp ); + loop = 500; // Wait for 5 second 20061101 + while( !(ltmp & 0x20) && loop-- ) + { + OS_SLEEP(10000); // Modify 20051221.1.b + if( !Wb35Reg_ReadSync( pHwData, 0x03d0, <mp ) ) + break; + } + + Wb35Reg_WriteSync( pHwData, 0x03d4, 0xe0 );// MLK_EN + } + + Wb35Reg_WriteSync( pHwData, 0x03b0, 1 );// Reset hardware first + OS_SLEEP(10000); // Add this 20051221.1.b + + // Set burst write delay + Wb35Reg_WriteSync( pHwData, 0x03f8, 0x7ff ); +} + +void Set_ChanIndep_RfData_al7230_24( phw_data_t pHwData, u32 *pltmp ,char number) +{ + u8 i; + + for( i=0; i<number; i++ ) + { + pHwData->phy_para[i] = al7230_rf_data_24[i]; + pltmp[i] = (1 << 31) | (0 << 30) | (24 << 24) | (al7230_rf_data_24[i]&0xffffff); + } +} + +void Set_ChanIndep_RfData_al7230_50( phw_data_t pHwData, u32 *pltmp, char number) +{ + u8 i; + + for( i=0; i<number; i++ ) + { + pHwData->phy_para[i] = al7230_rf_data_50[i]; + pltmp[i] = (1 << 31) | (0 << 30) | (24 << 24) | (al7230_rf_data_50[i]&0xffffff); + } +} + + +//============================================================================================================= +// RFSynthesizer_initial -- +//============================================================================================================= +void +RFSynthesizer_initial(phw_data_t pHwData) +{ + u32 altmp[32]; + PULONG pltmp = altmp; + u32 ltmp; + u8 number=0x00; // The number of register vale + u8 i; + + // + // bit[31] SPI Enable. + // 1=perform synthesizer program operation. This bit will + // cleared automatically after the operation is completed. + // bit[30] SPI R/W Control + // 0=write, 1=read + // bit[29:24] SPI Data Format Length + // bit[17:4 ] RF Data bits. + // bit[3 :0 ] RF address. + switch( pHwData->phy_type ) + { + case RF_MAXIM_2825: + case RF_MAXIM_V1: // 11g Winbond 2nd BB(with Phy board (v1) + Maxim 331) + number = sizeof(max2825_rf_data)/sizeof(max2825_rf_data[0]); + for( i=0; i<number; i++ ) + { + pHwData->phy_para[i] = max2825_rf_data[i];// Backup Rf parameter + pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2825_rf_data[i], 18); + } + break; + + case RF_MAXIM_2827: + number = sizeof(max2827_rf_data)/sizeof(max2827_rf_data[0]); + for( i=0; i<number; i++ ) + { + pHwData->phy_para[i] = max2827_rf_data[i]; + pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2827_rf_data[i], 18); + } + break; + + case RF_MAXIM_2828: + number = sizeof(max2828_rf_data)/sizeof(max2828_rf_data[0]); + for( i=0; i<number; i++ ) + { + pHwData->phy_para[i] = max2828_rf_data[i]; + pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2828_rf_data[i], 18); + } + break; + + case RF_MAXIM_2829: + number = sizeof(max2829_rf_data)/sizeof(max2829_rf_data[0]); + for( i=0; i<number; i++ ) + { + pHwData->phy_para[i] = max2829_rf_data[i]; + pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2829_rf_data[i], 18); + } + break; + + case RF_AIROHA_2230: + number = sizeof(al2230_rf_data)/sizeof(al2230_rf_data[0]); + for( i=0; i<number; i++ ) + { + pHwData->phy_para[i] = al2230_rf_data[i]; + pltmp[i] = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( al2230_rf_data[i], 20); + } + break; + + case RF_AIROHA_2230S: + number = sizeof(al2230s_rf_data)/sizeof(al2230s_rf_data[0]); + for( i=0; i<number; i++ ) + { + pHwData->phy_para[i] = al2230s_rf_data[i]; + pltmp[i] = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( al2230s_rf_data[i], 20); + } + break; + + case RF_AIROHA_7230: + + //Start to fill RF parameters, PLL_ON should be pulled low. + Wb35Reg_WriteSync( pHwData, 0x03dc, 0x00000000 ); +#ifdef _PE_STATE_DUMP_ + WBDEBUG(("* PLL_ON low\n")); +#endif + + number = sizeof(al7230_rf_data_24)/sizeof(al7230_rf_data_24[0]); + Set_ChanIndep_RfData_al7230_24(pHwData, pltmp, number); + break; + + case RF_WB_242: + case RF_WB_242_1: // 20060619.5 Add + number = sizeof(w89rf242_rf_data)/sizeof(w89rf242_rf_data[0]); + for( i=0; i<number; i++ ) + { + ltmp = w89rf242_rf_data[i]; + if( i == 4 ) // Update the VCO trim from EEPROM + { + ltmp &= ~0xff0; // Mask bit4 ~bit11 + ltmp |= pHwData->VCO_trim<<4; + } + + pHwData->phy_para[i] = ltmp; + pltmp[i] = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( ltmp, 24); + } + break; + } + + pHwData->phy_number = number; + + // The 16 is the maximum capability of hardware. Here use 12 + if( number > 12 ) { + //Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 12, NO_INCREMENT ); + for( i=0; i<12; i++ ) // For Al2230 + Wb35Reg_WriteSync( pHwData, 0x0864, pltmp[i] ); + + pltmp += 12; + number -= 12; + } + + // Write to register. number must less and equal than 16 + for( i=0; i<number; i++ ) + Wb35Reg_WriteSync( pHwData, 0x864, pltmp[i] ); + + // 20060630.1 Calibration only 1 time + if( pHwData->CalOneTime ) + return; + pHwData->CalOneTime = 1; + + switch( pHwData->phy_type ) + { + case RF_AIROHA_2230: + + // 20060511.1 --- Modifying the follow step for Rx issue----------------- + ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( (0x07<<20)|0xE168E, 20); + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + OS_SLEEP(10000); + ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( al2230_rf_data[7], 20); + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + OS_SLEEP(10000); + + case RF_AIROHA_2230S: // 20060420 Add this + + // 20060511.1 --- Modifying the follow step for Rx issue----------------- + Wb35Reg_WriteSync( pHwData, 0x03d4, 0x80 );// regulator on only + OS_SLEEP(10000); // Modify 20051221.1.b + + Wb35Reg_WriteSync( pHwData, 0x03d4, 0xa0 );// PLL_PD REF_PD set to 0 + OS_SLEEP(10000); // Modify 20051221.1.b + + Wb35Reg_WriteSync( pHwData, 0x03d4, 0xe0 );// MLK_EN + Wb35Reg_WriteSync( pHwData, 0x03b0, 1 );// Reset hardware first + OS_SLEEP(10000); // Add this 20051221.1.b + //------------------------------------------------------------------------ + + // The follow code doesn't use the burst-write mode + //phy_set_rf_data(phw_data, 0x0F, (0x0F<<20) | 0xF01A0); //Raise Initial Setting + ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( (0x0F<<20) | 0xF01A0, 20); + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + + ltmp = pHwData->Wb35Reg.BB5C & 0xfffff000; + Wb35Reg_WriteSync( pHwData, 0x105c, ltmp ); + pHwData->Wb35Reg.BB50 |= 0x13;//(MASK_IQCAL_MODE|MASK_CALIB_START);//20060315.1 modify + Wb35Reg_WriteSync( pHwData, 0x1050, pHwData->Wb35Reg.BB50); + OS_SLEEP(5000); + + //phy_set_rf_data(phw_data, 0x0F, (0x0F<<20) | 0xF01B0); //Activate Filter Cal. + ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( (0x0F<<20) | 0xF01B0, 20); + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + OS_SLEEP(5000); + + //phy_set_rf_data(phw_data, 0x0F, (0x0F<<20) | 0xF01e0); //Activate TX DCC + ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( (0x0F<<20) | 0xF01E0, 20); + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + OS_SLEEP(5000); + + //phy_set_rf_data(phw_data, 0x0F, (0x0F<<20) | 0xF01A0); //Resotre Initial Setting + ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( (0x0F<<20) | 0xF01A0, 20); + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + +// //Force TXI(Q)P(N) to normal control + Wb35Reg_WriteSync( pHwData, 0x105c, pHwData->Wb35Reg.BB5C ); + pHwData->Wb35Reg.BB50 &= ~0x13;//(MASK_IQCAL_MODE|MASK_CALIB_START); + Wb35Reg_WriteSync( pHwData, 0x1050, pHwData->Wb35Reg.BB50); + break; + + case RF_AIROHA_7230: + + //RF parameters have filled completely, PLL_ON should be + //pulled high + Wb35Reg_WriteSync( pHwData, 0x03dc, 0x00000080 ); + #ifdef _PE_STATE_DUMP_ + WBDEBUG(("* PLL_ON high\n")); + #endif + + //2.4GHz + //ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x1ABA8F; + //Wb35Reg_WriteSync pHwData, 0x0864, ltmp ); + //OS_SLEEP(1000); // Sleep 1 ms + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x9ABA8F; + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + OS_SLEEP(5000); + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x3ABA8F; + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + OS_SLEEP(5000); + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x1ABA8F; + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + OS_SLEEP(5000); + + //5GHz + Wb35Reg_WriteSync( pHwData, 0x03dc, 0x00000000 ); + #ifdef _PE_STATE_DUMP_ + WBDEBUG(("* PLL_ON low\n")); + #endif + + number = sizeof(al7230_rf_data_50)/sizeof(al7230_rf_data_50[0]); + Set_ChanIndep_RfData_al7230_50(pHwData, pltmp, number); + // Write to register. number must less and equal than 16 + for( i=0; i<number; i++ ) + Wb35Reg_WriteSync( pHwData, 0x0864, pltmp[i] ); + OS_SLEEP(5000); + + Wb35Reg_WriteSync( pHwData, 0x03dc, 0x00000080 ); + #ifdef _PE_STATE_DUMP_ + WBDEBUG(("* PLL_ON high\n")); + #endif + + //ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x12BACF; + //Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x9ABA8F; + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + OS_SLEEP(5000); + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x3ABA8F; + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + OS_SLEEP(5000); + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x12BACF; + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + OS_SLEEP(5000); + + //Wb35Reg_WriteSync( pHwData, 0x03dc, 0x00000080 ); + //WBDEBUG(("* PLL_ON high\n")); + break; + + case RF_WB_242: + case RF_WB_242_1: // 20060619.5 Add + + // + // ; Version 1.3B revision items: for FA5976A , October 3, 2005 by HTHo + // + ltmp = pHwData->Wb35Reg.BB5C & 0xfffff000; + Wb35Reg_WriteSync( pHwData, 0x105c, ltmp ); + Wb35Reg_WriteSync( pHwData, 0x1058, 0 ); + pHwData->Wb35Reg.BB50 |= 0x3;//(MASK_IQCAL_MODE|MASK_CALIB_START);//20060630 + Wb35Reg_WriteSync( pHwData, 0x1050, pHwData->Wb35Reg.BB50); + + //----- Calibration (1). VCO frequency calibration + //Calibration (1a.0). Synthesizer reset (HTHo corrected 2005/05/10) + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x0F<<24) | 0x00101E, 24); + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + OS_SLEEP( 5000 ); // Sleep 5ms + //Calibration (1a). VCO frequency calibration mode ; waiting 2msec VCO calibration time + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFE69c0, 24); + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + OS_SLEEP( 2000 ); // Sleep 2ms + + //----- Calibration (2). TX baseband Gm-C filter auto-tuning + //Calibration (2a). turn off ENCAL signal + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xF8EBC0, 24); + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + //Calibration (2b.0). TX filter auto-tuning BW: TFLBW=101 (TC5376A default) + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x07<<24) | 0x0C68CE, 24); + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + //Calibration (2b). send TX reset signal (HTHo corrected May 10, 2005) + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x0F<<24) | 0x00201E, 24); + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + //Calibration (2c). turn-on TX Gm-C filter auto-tuning + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFCEBC0, 24); + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + OS_SLEEP( 150 ); // Sleep 150 us + //turn off ENCAL signal + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xF8EBC0, 24); + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + + //----- Calibration (3). RX baseband Gm-C filter auto-tuning + //Calibration (3a). turn off ENCAL signal + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFAEDC0, 24); + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + //Calibration (3b.0). RX filter auto-tuning BW: RFLBW=100 (TC5376A+corner default; July 26, 2005) + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x07<<24) | 0x0C68CE, 24); + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + //Calibration (3b). send RX reset signal (HTHo corrected May 10, 2005) + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x0F<<24) | 0x00401E, 24); + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + //Calibration (3c). turn-on RX Gm-C filter auto-tuning + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFEEDC0, 24); + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + OS_SLEEP( 150 ); // Sleep 150 us + //Calibration (3e). turn off ENCAL signal + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFAEDC0, 24); + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + + //----- Calibration (4). TX LO leakage calibration + //Calibration (4a). TX LO leakage calibration + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFD6BC0, 24); + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + OS_SLEEP( 150 ); // Sleep 150 us + + //----- Calibration (5). RX DC offset calibration + //Calibration (5a). turn off ENCAL signal and set to RX SW DC caliration mode + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFAEDC0, 24); + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + //Calibration (5b). turn off AGC servo-loop & RSSI + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x01<<24) | 0xEBFFC2, 24); + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + + //; for LNA=11 -------- + //Calibration (5c-h). RX DC offset current bias ON; & LNA=11; RXVGA=111111 + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x06<<24) | 0x343FCC, 24); + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + //Calibration (5d). turn on RX DC offset cal function; and waiting 2 msec cal time + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFF6DC0, 24); + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + OS_SLEEP(2000); // Sleep 2ms + //Calibration (5f). turn off ENCAL signal + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFAEDC0, 24); + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + + //; for LNA=10 -------- + //Calibration (5c-m). RX DC offset current bias ON; & LNA=10; RXVGA=111111 + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x06<<24) | 0x342FCC, 24); + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + //Calibration (5d). turn on RX DC offset cal function; and waiting 2 msec cal time + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFF6DC0, 24); + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + OS_SLEEP(2000); // Sleep 2ms + //Calibration (5f). turn off ENCAL signal + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFAEDC0, 24); + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + + //; for LNA=01 -------- + //Calibration (5c-m). RX DC offset current bias ON; & LNA=01; RXVGA=111111 + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x06<<24) | 0x341FCC, 24); + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + //Calibration (5d). turn on RX DC offset cal function; and waiting 2 msec cal time + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFF6DC0, 24); + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + OS_SLEEP(2000); // Sleep 2ms + //Calibration (5f). turn off ENCAL signal + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFAEDC0, 24); + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + + //; for LNA=00 -------- + //Calibration (5c-l). RX DC offset current bias ON; & LNA=00; RXVGA=111111 + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x06<<24) | 0x340FCC, 24); + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + //Calibration (5d). turn on RX DC offset cal function; and waiting 2 msec cal time + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFF6DC0, 24); + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + OS_SLEEP(2000); // Sleep 2ms + //Calibration (5f). turn off ENCAL signal + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFAEDC0, 24); + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + //Calibration (5g). turn on AGC servo-loop + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x01<<24) | 0xEFFFC2, 24); + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + + //; ----- Calibration (7). Switch RF chip to normal mode + //0x00 0xF86100 ; 3E184 ; Switch RF chip to normal mode +// OS_SLEEP(10000); // @@ 20060721 + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xF86100, 24); + Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); + OS_SLEEP(5000); // Sleep 5 ms + +// //write back +// Wb35Reg_WriteSync( pHwData, 0x105c, pHwData->Wb35Reg.BB5C ); +// pHwData->Wb35Reg.BB50 &= ~0x13;//(MASK_IQCAL_MODE|MASK_CALIB_START); // 20060315.1 fix +// Wb35Reg_WriteSync( pHwData, 0x1050, pHwData->Wb35Reg.BB50); +// OS_SLEEP(1000); // Sleep 1 ms + break; + } +} + +void BBProcessor_AL7230_2400( phw_data_t pHwData) +{ + PWB35REG pWb35Reg = &pHwData->Wb35Reg; + u32 pltmp[12]; + + pltmp[0] = 0x16A8337A; // 0x16a5215f; // 0x1000 AGC_Ctrl1 + pltmp[1] = 0x9AFF9AA6; // 0x9aff9ca6; // 0x1004 AGC_Ctrl2 + pltmp[2] = 0x55D00A04; // 0x55d00a04; // 0x1008 AGC_Ctrl3 + pltmp[3] = 0xFFF72031; // 0xFfFf2138; // 0x100c AGC_Ctrl4 + pWb35Reg->BB0C = 0xFFF72031; + pltmp[4] = 0x0FacDCC5; // 0x1010 AGC_Ctrl5 // 20050927 0x0FacDCB7 + pltmp[5] = 0x00CAA333; // 0x00eaa333; // 0x1014 AGC_Ctrl6 + pltmp[6] = 0xF2211111; // 0x11111111; // 0x1018 AGC_Ctrl7 + pltmp[7] = 0x0FA3F0ED; // 0x101c AGC_Ctrl8 + pltmp[8] = 0x06443440; // 0x1020 AGC_Ctrl9 + pltmp[9] = 0xA8002A79; // 0xa9002A79; // 0x1024 AGC_Ctrl10 + pltmp[10] = 0x40000528; // 20050927 0x40000228 + pltmp[11] = 0x232D7F30; // 0x23457f30;// 0x102c A_ACQ_Ctrl + pWb35Reg->BB2C = 0x232D7F30; + Wb35Reg_BurstWrite( pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT ); + + pltmp[0] = 0x00002c54; // 0x1030 B_ACQ_Ctrl + pWb35Reg->BB30 = 0x00002c54; + pltmp[1] = 0x00C0D6C5; // 0x1034 A_TXRX_Ctrl + pltmp[2] = 0x5B2C8769; // 0x1038 B_TXRX_Ctrl + pltmp[3] = 0x00000000; // 0x103c 11a TX LS filter + pWb35Reg->BB3C = 0x00000000; + pltmp[4] = 0x00003F29; // 0x1040 11a TX LS filter + pltmp[5] = 0x0EFEFBFE; // 0x1044 11a TX LS filter + pltmp[6] = 0x00332C1B; // 0x00453B24; // 0x1048 11b TX RC filter + pltmp[7] = 0x0A00FEFF; // 0x0E00FEFF; // 0x104c 11b TX RC filter + pltmp[8] = 0x2B106208; // 0x1050 MODE_Ctrl + pWb35Reg->BB50 = 0x2B106208; + pltmp[9] = 0; // 0x1054 + pWb35Reg->BB54 = 0x00000000; + pltmp[10] = 0x52524242; // 0x64645252; // 0x1058 IQ_Alpha + pWb35Reg->BB58 = 0x52524242; + pltmp[11] = 0xAA0AC000; // 0x105c DC_Cancel + Wb35Reg_BurstWrite( pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT ); + +} + +void BBProcessor_AL7230_5000( phw_data_t pHwData) +{ + PWB35REG pWb35Reg = &pHwData->Wb35Reg; + u32 pltmp[12]; + + pltmp[0] = 0x16AA6678; // 0x1000 AGC_Ctrl1 + pltmp[1] = 0x9AFFA0B2; // 0x1004 AGC_Ctrl2 + pltmp[2] = 0x55D00A04; // 0x1008 AGC_Ctrl3 + pltmp[3] = 0xEFFF233E; // 0x100c AGC_Ctrl4 + pWb35Reg->BB0C = 0xEFFF233E; + pltmp[4] = 0x0FacDCC5; // 0x1010 AGC_Ctrl5 // 20050927 0x0FacDCB7 + pltmp[5] = 0x00CAA333; // 0x1014 AGC_Ctrl6 + pltmp[6] = 0xF2432111; // 0x1018 AGC_Ctrl7 + pltmp[7] = 0x0FA3F0ED; // 0x101c AGC_Ctrl8 + pltmp[8] = 0x05C43440; // 0x1020 AGC_Ctrl9 + pltmp[9] = 0x00002A79; // 0x1024 AGC_Ctrl10 + pltmp[10] = 0x40000528; // 20050927 0x40000228 + pltmp[11] = 0x232FDF30;// 0x102c A_ACQ_Ctrl + pWb35Reg->BB2C = 0x232FDF30; + Wb35Reg_BurstWrite( pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT ); + + pltmp[0] = 0x80002C7C; // 0x1030 B_ACQ_Ctrl + pltmp[1] = 0x00C0D6C5; // 0x1034 A_TXRX_Ctrl + pltmp[2] = 0x5B2C8769; // 0x1038 B_TXRX_Ctrl + pltmp[3] = 0x00000000; // 0x103c 11a TX LS filter + pWb35Reg->BB3C = 0x00000000; + pltmp[4] = 0x00003F29; // 0x1040 11a TX LS filter + pltmp[5] = 0x0EFEFBFE; // 0x1044 11a TX LS filter + pltmp[6] = 0x00332C1B; // 0x1048 11b TX RC filter + pltmp[7] = 0x0A00FEFF; // 0x104c 11b TX RC filter + pltmp[8] = 0x2B107208; // 0x1050 MODE_Ctrl + pWb35Reg->BB50 = 0x2B107208; + pltmp[9] = 0; // 0x1054 + pWb35Reg->BB54 = 0x00000000; + pltmp[10] = 0x52524242; // 0x1058 IQ_Alpha + pWb35Reg->BB58 = 0x52524242; + pltmp[11] = 0xAA0AC000; // 0x105c DC_Cancel + Wb35Reg_BurstWrite( pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT ); + +} + +//============================================================================================================= +// BBProcessorPowerupInit -- +// +// Description: +// Initialize the Baseband processor. +// +// Arguments: +// pHwData - Handle of the USB Device. +// +// Return values: +// None. +//============================================================================================================= +void +BBProcessor_initial( phw_data_t pHwData ) +{ + PWB35REG pWb35Reg = &pHwData->Wb35Reg; + u32 i, pltmp[12]; + + switch( pHwData->phy_type ) + { + case RF_MAXIM_V1: // Initializng the Winbond 2nd BB(with Phy board (v1) + Maxim 331) + + pltmp[0] = 0x16F47E77; // 0x1000 AGC_Ctrl1 + pltmp[1] = 0x9AFFAEA4; // 0x1004 AGC_Ctrl2 + pltmp[2] = 0x55D00A04; // 0x1008 AGC_Ctrl3 + pltmp[3] = 0xEFFF1A34; // 0x100c AGC_Ctrl4 + pWb35Reg->BB0C = 0xEFFF1A34; + pltmp[4] = 0x0FABE0B7; // 0x1010 AGC_Ctrl5 + pltmp[5] = 0x00CAA332; // 0x1014 AGC_Ctrl6 + pltmp[6] = 0xF6632111; // 0x1018 AGC_Ctrl7 + pltmp[7] = 0x0FA3F0ED; // 0x101c AGC_Ctrl8 + pltmp[8] = 0x04CC3640; // 0x1020 AGC_Ctrl9 + pltmp[9] = 0x00002A79; // 0x1024 AGC_Ctrl10 + pltmp[10] = (pHwData->phy_type==3) ? 0x40000a28 : 0x40000228; // 0x1028 MAXIM_331(b31=0) + WBRF_V1(b11=1) : MAXIM_331(b31=0) + WBRF_V2(b11=0) + pltmp[11] = 0x232FDF30; // 0x102c A_ACQ_Ctrl + pWb35Reg->BB2C = 0x232FDF30; //Modify for 33's 1.0.95.xxx version, antenna 1 + Wb35Reg_BurstWrite( pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT ); + + pltmp[0] = 0x00002C54; // 0x1030 B_ACQ_Ctrl + pWb35Reg->BB30 = 0x00002C54; + pltmp[1] = 0x00C0D6C5; // 0x1034 A_TXRX_Ctrl + pltmp[2] = 0x5B6C8769; // 0x1038 B_TXRX_Ctrl + pltmp[3] = 0x00000000; // 0x103c 11a TX LS filter + pWb35Reg->BB3C = 0x00000000; + pltmp[4] = 0x00003F29; // 0x1040 11a TX LS filter + pltmp[5] = 0x0EFEFBFE; // 0x1044 11a TX LS filter + pltmp[6] = 0x00453B24; // 0x1048 11b TX RC filter + pltmp[7] = 0x0E00FEFF; // 0x104c 11b TX RC filter + pltmp[8] = 0x27106208; // 0x1050 MODE_Ctrl + pWb35Reg->BB50 = 0x27106208; + pltmp[9] = 0; // 0x1054 + pWb35Reg->BB54 = 0x00000000; + pltmp[10] = 0x64646464; // 0x1058 IQ_Alpha + pWb35Reg->BB58 = 0x64646464; + pltmp[11] = 0xAA0AC000; // 0x105c DC_Cancel + Wb35Reg_BurstWrite( pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT ); + + Wb35Reg_Write( pHwData, 0x1070, 0x00000045 ); + break; + + //------------------------------------------------------------------ + //[20040722 WK] + //Only for baseband version 2 +// case RF_MAXIM_317: + case RF_MAXIM_2825: + case RF_MAXIM_2827: + case RF_MAXIM_2828: + + pltmp[0] = 0x16b47e77; // 0x1000 AGC_Ctrl1 + pltmp[1] = 0x9affaea4; // 0x1004 AGC_Ctrl2 + pltmp[2] = 0x55d00a04; // 0x1008 AGC_Ctrl3 + pltmp[3] = 0xefff1a34; // 0x100c AGC_Ctrl4 + pWb35Reg->BB0C = 0xefff1a34; + pltmp[4] = 0x0fabe0b7; // 0x1010 AGC_Ctrl5 + pltmp[5] = 0x00caa332; // 0x1014 AGC_Ctrl6 + pltmp[6] = 0xf6632111; // 0x1018 AGC_Ctrl7 + pltmp[7] = 0x0FA3F0ED; // 0x101c AGC_Ctrl8 + pltmp[8] = 0x04CC3640; // 0x1020 AGC_Ctrl9 + pltmp[9] = 0x00002A79; // 0x1024 AGC_Ctrl10 + pltmp[10] = 0x40000528; // 0x40000128; Modify for 33's 1.0.95 + pltmp[11] = 0x232fdf30; // 0x102c A_ACQ_Ctrl + pWb35Reg->BB2C = 0x232fdf30; //Modify for 33's 1.0.95.xxx version, antenna 1 + Wb35Reg_BurstWrite( pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT ); + + pltmp[0] = 0x00002C54; // 0x1030 B_ACQ_Ctrl + pWb35Reg->BB30 = 0x00002C54; + pltmp[1] = 0x00C0D6C5; // 0x1034 A_TXRX_Ctrl + pltmp[2] = 0x5B6C8769; // 0x1038 B_TXRX_Ctrl + pltmp[3] = 0x00000000; // 0x103c 11a TX LS filter + pWb35Reg->BB3C = 0x00000000; + pltmp[4] = 0x00003F29; // 0x1040 11a TX LS filter + pltmp[5] = 0x0EFEFBFE; // 0x1044 11a TX LS filter + pltmp[6] = 0x00453B24; // 0x1048 11b TX RC filter + pltmp[7] = 0x0D00FDFF; // 0x104c 11b TX RC filter + pltmp[8] = 0x27106208; // 0x1050 MODE_Ctrl + pWb35Reg->BB50 = 0x27106208; + pltmp[9] = 0; // 0x1054 + pWb35Reg->BB54 = 0x00000000; + pltmp[10] = 0x64646464; // 0x1058 IQ_Alpha + pWb35Reg->BB58 = 0x64646464; + pltmp[11] = 0xAA28C000; // 0x105c DC_Cancel + Wb35Reg_BurstWrite( pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT ); + + Wb35Reg_Write( pHwData, 0x1070, 0x00000045 ); + break; + + case RF_MAXIM_2829: + + pltmp[0] = 0x16b47e77; // 0x1000 AGC_Ctrl1 + pltmp[1] = 0x9affaea4; // 0x1004 AGC_Ctrl2 + pltmp[2] = 0x55d00a04; // 0x1008 AGC_Ctrl3 + pltmp[3] = 0xf4ff1632; // 0xefff1a34; // 0x100c AGC_Ctrl4 Modify for 33's 1.0.95 + pWb35Reg->BB0C = 0xf4ff1632; // 0xefff1a34; Modify for 33's 1.0.95 + pltmp[4] = 0x0fabe0b7; // 0x1010 AGC_Ctrl5 + pltmp[5] = 0x00caa332; // 0x1014 AGC_Ctrl6 + pltmp[6] = 0xf8632112; // 0xf6632111; // 0x1018 AGC_Ctrl7 Modify for 33's 1.0.95 + pltmp[7] = 0x0FA3F0ED; // 0x101c AGC_Ctrl8 + pltmp[8] = 0x04CC3640; // 0x1020 AGC_Ctrl9 + pltmp[9] = 0x00002A79; // 0x1024 AGC_Ctrl10 + pltmp[10] = 0x40000528; // 0x40000128; modify for 33's 1.0.95 + pltmp[11] = 0x232fdf30; // 0x102c A_ACQ_Ctrl + pWb35Reg->BB2C = 0x232fdf30; //Modify for 33's 1.0.95.xxx version, antenna 1 + Wb35Reg_BurstWrite( pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT ); + + pltmp[0] = 0x00002C54; // 0x1030 B_ACQ_Ctrl + pWb35Reg->BB30 = 0x00002C54; + pltmp[1] = 0x00C0D6C5; // 0x1034 A_TXRX_Ctrl + pltmp[2] = 0x5b2c8769; // 0x5B6C8769; // 0x1038 B_TXRX_Ctrl Modify for 33's 1.0.95 + pltmp[3] = 0x00000000; // 0x103c 11a TX LS filter + pWb35Reg->BB3C = 0x00000000; + pltmp[4] = 0x00003F29; // 0x1040 11a TX LS filter + pltmp[5] = 0x0EFEFBFE; // 0x1044 11a TX LS filter + pltmp[6] = 0x002c2617; // 0x00453B24; // 0x1048 11b TX RC filter Modify for 33's 1.0.95 + pltmp[7] = 0x0800feff; // 0x0D00FDFF; // 0x104c 11b TX RC filter Modify for 33's 1.0.95 + pltmp[8] = 0x27106208; // 0x1050 MODE_Ctrl + pWb35Reg->BB50 = 0x27106208; + pltmp[9] = 0; // 0x1054 + pWb35Reg->BB54 = 0x00000000; + pltmp[10] = 0x64644a4a; // 0x64646464; // 0x1058 IQ_Alpha Modify for 33's 1.0.95 + pWb35Reg->BB58 = 0x64646464; + pltmp[11] = 0xAA28C000; // 0x105c DC_Cancel + Wb35Reg_BurstWrite( pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT ); + + Wb35Reg_Write( pHwData, 0x1070, 0x00000045 ); + break; + + case RF_AIROHA_2230: + + pltmp[0] = 0X16764A77; // 0x1000 AGC_Ctrl1 //0x16765A77 + pltmp[1] = 0x9affafb2; // 0x1004 AGC_Ctrl2 + pltmp[2] = 0x55d00a04; // 0x1008 AGC_Ctrl3 + pltmp[3] = 0xFFFd203c; // 0xFFFb203a; // 0x100c AGC_Ctrl4 Modify for 33's 1.0.95.xxx version + pWb35Reg->BB0C = 0xFFFd203c; + pltmp[4] = 0X0FBFDCc5; // 0X0FBFDCA0; // 0x1010 AGC_Ctrl5 //0x0FB2E0B7 Modify for 33's 1.0.95.xxx version + pltmp[5] = 0x00caa332; // 0x00caa333; // 0x1014 AGC_Ctrl6 Modify for 33's 1.0.95.xxx version + pltmp[6] = 0XF6632111; // 0XF1632112; // 0x1018 AGC_Ctrl7 //0xf6632112 Modify for 33's 1.0.95.xxx version + pltmp[7] = 0x0FA3F0ED; // 0x101c AGC_Ctrl8 + pltmp[8] = 0x04C43640; // 0x1020 AGC_Ctrl9 + pltmp[9] = 0x00002A79; // 0x1024 AGC_Ctrl10 + pltmp[10] = 0X40000528; //0x40000228 + pltmp[11] = 0x232dfF30; // 0x232A9F30; // 0x102c A_ACQ_Ctrl //0x232a9730 + pWb35Reg->BB2C = 0x232dfF30; //Modify for 33's 1.0.95.xxx version, antenna 1 + Wb35Reg_BurstWrite( pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT ); + + pltmp[0] = 0x00002C54; // 0x1030 B_ACQ_Ctrl + pWb35Reg->BB30 = 0x00002C54; + pltmp[1] = 0x00C0D6C5; // 0x1034 A_TXRX_Ctrl + pltmp[2] = 0x5B2C8769; // 0x1038 B_TXRX_Ctrl //0x5B6C8769 + pltmp[3] = 0x00000000; // 0x103c 11a TX LS filter + pWb35Reg->BB3C = 0x00000000; + pltmp[4] = 0x00003F29; // 0x1040 11a TX LS filter + pltmp[5] = 0x0EFEFBFE; // 0x1044 11a TX LS filter + pltmp[6] = BB48_DEFAULT_AL2230_11G; // 0x1048 11b TX RC filter 20060613.2 + pWb35Reg->BB48 = BB48_DEFAULT_AL2230_11G; // 20051221 ch14 20060613.2 + pltmp[7] = BB4C_DEFAULT_AL2230_11G; // 0x104c 11b TX RC filter 20060613.2 + pWb35Reg->BB4C = BB4C_DEFAULT_AL2230_11G; // 20060613.1 20060613.2 + pltmp[8] = 0x27106200; // 0x1050 MODE_Ctrl + pWb35Reg->BB50 = 0x27106200; + pltmp[9] = 0; // 0x1054 + pWb35Reg->BB54 = 0x00000000; + pltmp[10] = 0x52524242; // 0x1058 IQ_Alpha + pWb35Reg->BB58 = 0x52524242; + pltmp[11] = 0xAA0AC000; // 0x105c DC_Cancel + Wb35Reg_BurstWrite( pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT ); + + Wb35Reg_Write( pHwData, 0x1070, 0x00000045 ); + break; + + case RF_AIROHA_2230S: // 20060420 Add this + + pltmp[0] = 0X16764A77; // 0x1000 AGC_Ctrl1 //0x16765A77 + pltmp[1] = 0x9affafb2; // 0x1004 AGC_Ctrl2 + pltmp[2] = 0x55d00a04; // 0x1008 AGC_Ctrl3 + pltmp[3] = 0xFFFd203c; // 0xFFFb203a; // 0x100c AGC_Ctrl4 Modify for 33's 1.0.95.xxx version + pWb35Reg->BB0C = 0xFFFd203c; + pltmp[4] = 0X0FBFDCc5; // 0X0FBFDCA0; // 0x1010 AGC_Ctrl5 //0x0FB2E0B7 Modify for 33's 1.0.95.xxx version + pltmp[5] = 0x00caa332; // 0x00caa333; // 0x1014 AGC_Ctrl6 Modify for 33's 1.0.95.xxx version + pltmp[6] = 0XF6632111; // 0XF1632112; // 0x1018 AGC_Ctrl7 //0xf6632112 Modify for 33's 1.0.95.xxx version + pltmp[7] = 0x0FA3F0ED; // 0x101c AGC_Ctrl8 + pltmp[8] = 0x04C43640; // 0x1020 AGC_Ctrl9 + pltmp[9] = 0x00002A79; // 0x1024 AGC_Ctrl10 + pltmp[10] = 0X40000528; //0x40000228 + pltmp[11] = 0x232dfF30; // 0x232A9F30; // 0x102c A_ACQ_Ctrl //0x232a9730 + pWb35Reg->BB2C = 0x232dfF30; //Modify for 33's 1.0.95.xxx version, antenna 1 + Wb35Reg_BurstWrite( pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT ); + + pltmp[0] = 0x00002C54; // 0x1030 B_ACQ_Ctrl + pWb35Reg->BB30 = 0x00002C54; + pltmp[1] = 0x00C0D6C5; // 0x1034 A_TXRX_Ctrl + pltmp[2] = 0x5B2C8769; // 0x1038 B_TXRX_Ctrl //0x5B6C8769 + pltmp[3] = 0x00000000; // 0x103c 11a TX LS filter + pWb35Reg->BB3C = 0x00000000; + pltmp[4] = 0x00003F29; // 0x1040 11a TX LS filter + pltmp[5] = 0x0EFEFBFE; // 0x1044 11a TX LS filter + pltmp[6] = BB48_DEFAULT_AL2230_11G; // 0x1048 11b TX RC filter 20060613.2 + pWb35Reg->BB48 = BB48_DEFAULT_AL2230_11G; // 20051221 ch14 20060613.2 + pltmp[7] = BB4C_DEFAULT_AL2230_11G; // 0x104c 11b TX RC filter 20060613.2 + pWb35Reg->BB4C = BB4C_DEFAULT_AL2230_11G; // 20060613.1 + pltmp[8] = 0x27106200; // 0x1050 MODE_Ctrl + pWb35Reg->BB50 = 0x27106200; + pltmp[9] = 0; // 0x1054 + pWb35Reg->BB54 = 0x00000000; + pltmp[10] = 0x52523232; // 20060419 0x52524242; // 0x1058 IQ_Alpha + pWb35Reg->BB58 = 0x52523232; // 20060419 0x52524242; + pltmp[11] = 0xAA0AC000; // 0x105c DC_Cancel + Wb35Reg_BurstWrite( pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT ); + + Wb35Reg_Write( pHwData, 0x1070, 0x00000045 ); + break; + + case RF_AIROHA_7230: +/* + pltmp[0] = 0x16a84a77; // 0x1000 AGC_Ctrl1 + pltmp[1] = 0x9affafb2; // 0x1004 AGC_Ctrl2 + pltmp[2] = 0x55d00a04; // 0x1008 AGC_Ctrl3 + pltmp[3] = 0xFFFb203a; // 0x100c AGC_Ctrl4 + pWb35Reg->BB0c = 0xFFFb203a; + pltmp[4] = 0x0FBFDCB7; // 0x1010 AGC_Ctrl5 + pltmp[5] = 0x00caa333; // 0x1014 AGC_Ctrl6 + pltmp[6] = 0xf6632112; // 0x1018 AGC_Ctrl7 + pltmp[7] = 0x0FA3F0ED; // 0x101c AGC_Ctrl8 + pltmp[8] = 0x04C43640; // 0x1020 AGC_Ctrl9 + pltmp[9] = 0x00002A79; // 0x1024 AGC_Ctrl10 + pltmp[10] = 0x40000228; + pltmp[11] = 0x232A9F30;// 0x102c A_ACQ_Ctrl + pWb35Reg->BB2c = 0x232A9F30; + Wb35Reg_BurstWrite( pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT ); + + pltmp[0] = 0x00002C54; // 0x1030 B_ACQ_Ctrl + pWb35Reg->BB30 = 0x00002C54; + pltmp[1] = 0x00C0D6C5; // 0x1034 A_TXRX_Ctrl + pltmp[2] = 0x5B2C8769; // 0x1038 B_TXRX_Ctrl + pltmp[3] = 0x00000000; // 0x103c 11a TX LS filter + pWb35Reg->BB3c = 0x00000000; + pltmp[4] = 0x00003F29; // 0x1040 11a TX LS filter + pltmp[5] = 0x0EFEFBFE; // 0x1044 11a TX LS filter + pltmp[6] = 0x00453B24; // 0x1048 11b TX RC filter + pltmp[7] = 0x0E00FEFF; // 0x104c 11b TX RC filter + pltmp[8] = 0x27106200; // 0x1050 MODE_Ctrl + pWb35Reg->BB50 = 0x27106200; + pltmp[9] = 0; // 0x1054 + pWb35Reg->BB54 = 0x00000000; + pltmp[10] = 0x64645252; // 0x1058 IQ_Alpha + pWb35Reg->BB58 = 0x64645252; + pltmp[11] = 0xAA0AC000; // 0x105c DC_Cancel + Wb35Reg_BurstWrite( pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT ); +*/ + BBProcessor_AL7230_2400( pHwData ); + + Wb35Reg_Write( pHwData, 0x1070, 0x00000045 ); + break; + + case RF_WB_242: + case RF_WB_242_1: // 20060619.5 Add + + pltmp[0] = 0x16A8525D; // 0x1000 AGC_Ctrl1 + pltmp[1] = 0x9AFF9ABA; // 0x1004 AGC_Ctrl2 + pltmp[2] = 0x55D00A04; // 0x1008 AGC_Ctrl3 + pltmp[3] = 0xEEE91C32; // 0x100c AGC_Ctrl4 + pWb35Reg->BB0C = 0xEEE91C32; + pltmp[4] = 0x0FACDCC5; // 0x1010 AGC_Ctrl5 + pltmp[5] = 0x000AA344; // 0x1014 AGC_Ctrl6 + pltmp[6] = 0x22222221; // 0x1018 AGC_Ctrl7 + pltmp[7] = 0x0FA3F0ED; // 0x101c AGC_Ctrl8 + pltmp[8] = 0x04CC3440; // 20051018 0x03CB3440; // 0x1020 AGC_Ctrl9 20051014 0x03C33440 + pltmp[9] = 0xA9002A79; // 0x1024 AGC_Ctrl10 + pltmp[10] = 0x40000528; // 0x1028 + pltmp[11] = 0x23457F30; // 0x102c A_ACQ_Ctrl + pWb35Reg->BB2C = 0x23457F30; + Wb35Reg_BurstWrite( pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT ); + + pltmp[0] = 0x00002C54; // 0x1030 B_ACQ_Ctrl + pWb35Reg->BB30 = 0x00002C54; + pltmp[1] = 0x00C0D6C5; // 0x1034 A_TXRX_Ctrl + pltmp[2] = 0x5B2C8769; // 0x1038 B_TXRX_Ctrl + pltmp[3] = pHwData->BB3c_cal; // 0x103c 11a TX LS filter + pWb35Reg->BB3C = pHwData->BB3c_cal; + pltmp[4] = 0x00003F29; // 0x1040 11a TX LS filter + pltmp[5] = 0x0EFEFBFE; // 0x1044 11a TX LS filter + pltmp[6] = BB48_DEFAULT_WB242_11G; // 0x1048 11b TX RC filter 20060613.2 + pWb35Reg->BB48 = BB48_DEFAULT_WB242_11G; // 20060613.1 20060613.2 + pltmp[7] = BB4C_DEFAULT_WB242_11G; // 0x104c 11b TX RC filter 20060613.2 + pWb35Reg->BB4C = BB4C_DEFAULT_WB242_11G; // 20060613.1 20060613.2 + pltmp[8] = 0x27106208; // 0x1050 MODE_Ctrl + pWb35Reg->BB50 = 0x27106208; + pltmp[9] = pHwData->BB54_cal; // 0x1054 + pWb35Reg->BB54 = pHwData->BB54_cal; + pltmp[10] = 0x52523131; // 0x1058 IQ_Alpha + pWb35Reg->BB58 = 0x52523131; + pltmp[11] = 0xAA0AC000; // 20060825 0xAA2AC000; // 0x105c DC_Cancel + Wb35Reg_BurstWrite( pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT ); + + Wb35Reg_Write( pHwData, 0x1070, 0x00000045 ); + break; + } + + // Fill the LNA table + pWb35Reg->LNAValue[0] = (u8)(pWb35Reg->BB0C & 0xff); + pWb35Reg->LNAValue[1] = 0; + pWb35Reg->LNAValue[2] = (u8)((pWb35Reg->BB0C & 0xff00)>>8); + pWb35Reg->LNAValue[3] = 0; + + // Fill SQ3 table + for( i=0; i<MAX_SQ3_FILTER_SIZE; i++ ) + pWb35Reg->SQ3_filter[i] = 0x2f; // half of Bit 0 ~ 6 +} + +void set_tx_power_per_channel_max2829( phw_data_t pHwData, ChanInfo Channel) +{ + RFSynthesizer_SetPowerIndex( pHwData, 100 ); // 20060620.1 Modify +} + +void set_tx_power_per_channel_al2230( phw_data_t pHwData, ChanInfo Channel ) +{ + u8 index = 100; + + if (pHwData->TxVgaFor24[Channel.ChanNo - 1] != 0xff) // 20060620.1 Add + index = pHwData->TxVgaFor24[Channel.ChanNo - 1]; + + RFSynthesizer_SetPowerIndex( pHwData, index ); +} + +void set_tx_power_per_channel_al7230( phw_data_t pHwData, ChanInfo Channel) +{ + u8 i, index = 100; + + switch ( Channel.band ) + { + case BAND_TYPE_DSSS: + case BAND_TYPE_OFDM_24: + { + if (pHwData->TxVgaFor24[Channel.ChanNo - 1] != 0xff) + index = pHwData->TxVgaFor24[Channel.ChanNo - 1]; + } + break; + case BAND_TYPE_OFDM_5: + { + for (i =0; i<35; i++) + { + if (Channel.ChanNo == pHwData->TxVgaFor50[i].ChanNo) + { + if (pHwData->TxVgaFor50[i].TxVgaValue != 0xff) + index = pHwData->TxVgaFor50[i].TxVgaValue; + break; + } + } + } + break; + } + RFSynthesizer_SetPowerIndex( pHwData, index ); +} + +void set_tx_power_per_channel_wb242( phw_data_t pHwData, ChanInfo Channel) +{ + u8 index = 100; + + switch ( Channel.band ) + { + case BAND_TYPE_DSSS: + case BAND_TYPE_OFDM_24: + { + if (pHwData->TxVgaFor24[Channel.ChanNo - 1] != 0xff) + index = pHwData->TxVgaFor24[Channel.ChanNo - 1]; + } + break; + case BAND_TYPE_OFDM_5: + break; + } + RFSynthesizer_SetPowerIndex( pHwData, index ); +} + +//============================================================================================================= +// RFSynthesizer_SwitchingChannel -- +// +// Description: +// Swithch the RF channel. +// +// Arguments: +// pHwData - Handle of the USB Device. +// Channel - The channel no. +// +// Return values: +// None. +//============================================================================================================= +void +RFSynthesizer_SwitchingChannel( phw_data_t pHwData, ChanInfo Channel ) +{ + PWB35REG pWb35Reg = &pHwData->Wb35Reg; + u32 pltmp[16]; // The 16 is the maximum capability of hardware + u32 count, ltmp; + u8 i, j, number; + u8 ChnlTmp; + + switch( pHwData->phy_type ) + { + case RF_MAXIM_2825: + case RF_MAXIM_V1: // 11g Winbond 2nd BB(with Phy board (v1) + Maxim 331) + + if( Channel.band <= BAND_TYPE_OFDM_24 ) // channel 1 ~ 13 + { + for( i=0; i<3; i++ ) + pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2825_channel_data_24[Channel.ChanNo-1][i], 18); + Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 3, NO_INCREMENT ); + } + RFSynthesizer_SetPowerIndex( pHwData, 100 ); + break; + + case RF_MAXIM_2827: + + if( Channel.band <= BAND_TYPE_OFDM_24 ) // channel 1 ~ 13 + { + for( i=0; i<3; i++ ) + pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2827_channel_data_24[Channel.ChanNo-1][i], 18); + Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 3, NO_INCREMENT ); + } + else if( Channel.band == BAND_TYPE_OFDM_5 ) // channel 36 ~ 64 + { + ChnlTmp = (Channel.ChanNo - 36) / 4; + for( i=0; i<3; i++ ) + pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2827_channel_data_50[ChnlTmp][i], 18); + Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 3, NO_INCREMENT ); + } + RFSynthesizer_SetPowerIndex( pHwData, 100 ); + break; + + case RF_MAXIM_2828: + + if( Channel.band <= BAND_TYPE_OFDM_24 ) // channel 1 ~ 13 + { + for( i=0; i<3; i++ ) + pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2828_channel_data_24[Channel.ChanNo-1][i], 18); + Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 3, NO_INCREMENT ); + } + else if( Channel.band == BAND_TYPE_OFDM_5 ) // channel 36 ~ 64 + { + ChnlTmp = (Channel.ChanNo - 36) / 4; + for ( i = 0; i < 3; i++) + pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2828_channel_data_50[ChnlTmp][i], 18); + Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 3, NO_INCREMENT ); + } + RFSynthesizer_SetPowerIndex( pHwData, 100 ); + break; + + case RF_MAXIM_2829: + + if( Channel.band <= BAND_TYPE_OFDM_24) + { + for( i=0; i<3; i++ ) + pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2829_channel_data_24[Channel.ChanNo-1][i], 18); + Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 3, NO_INCREMENT ); + } + else if( Channel.band == BAND_TYPE_OFDM_5 ) + { + count = sizeof(max2829_channel_data_50) / sizeof(max2829_channel_data_50[0]); + + for( i=0; i<count; i++ ) + { + if( max2829_channel_data_50[i][0] == Channel.ChanNo ) + { + for( j=0; j<3; j++ ) + pltmp[j] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2829_channel_data_50[i][j+1], 18); + Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 3, NO_INCREMENT ); + + if( (max2829_channel_data_50[i][3] & 0x3FFFF) == 0x2A946 ) + { + ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( (5<<18)|0x2A906, 18); + Wb35Reg_Write( pHwData, 0x0864, ltmp ); + } + else // 0x2A9C6 + { + ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( (5<<18)|0x2A986, 18); + Wb35Reg_Write( pHwData, 0x0864, ltmp ); + } + } + } + } + set_tx_power_per_channel_max2829( pHwData, Channel ); + break; + + case RF_AIROHA_2230: + case RF_AIROHA_2230S: // 20060420 Add this + + if( Channel.band <= BAND_TYPE_OFDM_24 ) // channel 1 ~ 14 + { + for( i=0; i<2; i++ ) + pltmp[i] = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( al2230_channel_data_24[Channel.ChanNo-1][i], 20); + Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 2, NO_INCREMENT ); + } + set_tx_power_per_channel_al2230( pHwData, Channel ); + break; + + case RF_AIROHA_7230: + + //Start to fill RF parameters, PLL_ON should be pulled low. + //Wb35Reg_Write( pHwData, 0x03dc, 0x00000000 ); + //WBDEBUG(("* PLL_ON low\n")); + + //Channel independent registers + if( Channel.band != pHwData->band) + { + if (Channel.band <= BAND_TYPE_OFDM_24) + { + //Update BB register + BBProcessor_AL7230_2400(pHwData); + + number = sizeof(al7230_rf_data_24)/sizeof(al7230_rf_data_24[0]); + Set_ChanIndep_RfData_al7230_24(pHwData, pltmp, number); + } + else + { + //Update BB register + BBProcessor_AL7230_5000(pHwData); + + number = sizeof(al7230_rf_data_50)/sizeof(al7230_rf_data_50[0]); + Set_ChanIndep_RfData_al7230_50(pHwData, pltmp, number); + } + + // Write to register. number must less and equal than 16 + Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, number, NO_INCREMENT ); + #ifdef _PE_STATE_DUMP_ + WBDEBUG(("Band changed\n")); + #endif + } + + if( Channel.band <= BAND_TYPE_OFDM_24 ) // channel 1 ~ 14 + { + for( i=0; i<2; i++ ) + pltmp[i] = (1 << 31) | (0 << 30) | (24 << 24) | (al7230_channel_data_24[Channel.ChanNo-1][i]&0xffffff); + Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 2, NO_INCREMENT ); + } + else if( Channel.band == BAND_TYPE_OFDM_5 ) + { + //Update Reg12 + if ((Channel.ChanNo > 64) && (Channel.ChanNo <= 165)) + { + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x00143c; + Wb35Reg_Write( pHwData, 0x0864, ltmp ); + } + else //reg12 = 0x00147c at Channel 4920 ~ 5320 + { + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x00147c; + Wb35Reg_Write( pHwData, 0x0864, ltmp ); + } + + count = sizeof(al7230_channel_data_5) / sizeof(al7230_channel_data_5[0]); + + for (i=0; i<count; i++) + { + if (al7230_channel_data_5[i][0] == Channel.ChanNo) + { + for( j=0; j<3; j++ ) + pltmp[j] = (1 << 31) | (0 << 30) | (24 << 24) | ( al7230_channel_data_5[i][j+1]&0xffffff); + Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 3, NO_INCREMENT ); + } + } + } + set_tx_power_per_channel_al7230(pHwData, Channel); + break; + + case RF_WB_242: + case RF_WB_242_1: // 20060619.5 Add + + if( Channel.band <= BAND_TYPE_OFDM_24 ) // channel 1 ~ 14 + { + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( w89rf242_channel_data_24[Channel.ChanNo-1][0], 24); + Wb35Reg_Write( pHwData, 0x864, ltmp ); + } + set_tx_power_per_channel_wb242(pHwData, Channel); + break; + } + + if( Channel.band <= BAND_TYPE_OFDM_24 ) + { + // BB: select 2.4 GHz, bit[12-11]=00 + pWb35Reg->BB50 &= ~(BIT(11)|BIT(12)); + Wb35Reg_Write( pHwData, 0x1050, pWb35Reg->BB50 ); // MODE_Ctrl + // MAC: select 2.4 GHz, bit[5]=0 + pWb35Reg->M78_ERPInformation &= ~BIT(5); + Wb35Reg_Write( pHwData, 0x0878, pWb35Reg->M78_ERPInformation ); + // enable 11b Baseband + pWb35Reg->BB30 &= ~BIT(31); + Wb35Reg_Write( pHwData, 0x1030, pWb35Reg->BB30 ); + } + else if( (Channel.band == BAND_TYPE_OFDM_5) ) + { + // BB: select 5 GHz + pWb35Reg->BB50 &= ~(BIT(11)|BIT(12)); + if (Channel.ChanNo <=64 ) + pWb35Reg->BB50 |= BIT(12); // 10-5.25GHz + else if ((Channel.ChanNo >= 100) && (Channel.ChanNo <= 124)) + pWb35Reg->BB50 |= BIT(11); // 01-5.48GHz + else if ((Channel.ChanNo >=128) && (Channel.ChanNo <= 161)) + pWb35Reg->BB50 |= (BIT(12)|BIT(11)); // 11-5.775GHz + else //Chan 184 ~ 196 will use bit[12-11] = 10 in version sh-src-1.2.25 + pWb35Reg->BB50 |= BIT(12); + Wb35Reg_Write( pHwData, 0x1050, pWb35Reg->BB50 ); // MODE_Ctrl + + //(1) M78 should alway use 2.4G setting when using RF_AIROHA_7230 + //(2) BB30 has been updated previously. + if (pHwData->phy_type != RF_AIROHA_7230) + { + // MAC: select 5 GHz, bit[5]=1 + pWb35Reg->M78_ERPInformation |= BIT(5); + Wb35Reg_Write( pHwData, 0x0878, pWb35Reg->M78_ERPInformation ); + + // disable 11b Baseband + pWb35Reg->BB30 |= BIT(31); + Wb35Reg_Write( pHwData, 0x1030, pWb35Reg->BB30 ); + } + } +} + +//Set the tx power directly from DUT GUI, not from the EEPROM. Return the current setting +u8 RFSynthesizer_SetPowerIndex( phw_data_t pHwData, u8 PowerIndex ) +{ + u32 Band = pHwData->band; + u8 index=0; + + if( pHwData->power_index == PowerIndex ) // 20060620.1 Add + return PowerIndex; + + if (RF_MAXIM_2825 == pHwData->phy_type) + { + // Channel 1 - 13 + index = RFSynthesizer_SetMaxim2825Power( pHwData, PowerIndex ); + } + else if (RF_MAXIM_2827 == pHwData->phy_type) + { + if( Band <= BAND_TYPE_OFDM_24 ) // Channel 1 - 13 + index = RFSynthesizer_SetMaxim2827_24Power( pHwData, PowerIndex ); + else// if( Band == BAND_TYPE_OFDM_5 ) // Channel 36 - 64 + index = RFSynthesizer_SetMaxim2827_50Power( pHwData, PowerIndex ); + } + else if (RF_MAXIM_2828 == pHwData->phy_type) + { + if( Band <= BAND_TYPE_OFDM_24 ) // Channel 1 - 13 + index = RFSynthesizer_SetMaxim2828_24Power( pHwData, PowerIndex ); + else// if( Band == BAND_TYPE_OFDM_5 ) // Channel 36 - 64 + index = RFSynthesizer_SetMaxim2828_50Power( pHwData, PowerIndex ); + } + else if( RF_AIROHA_2230 == pHwData->phy_type ) + { + //Power index: 0 ~ 63 // Channel 1 - 14 + index = RFSynthesizer_SetAiroha2230Power( pHwData, PowerIndex ); + index = (u8)al2230_txvga_data[index][1]; + } + else if( RF_AIROHA_2230S == pHwData->phy_type ) // 20060420 Add this + { + //Power index: 0 ~ 63 // Channel 1 - 14 + index = RFSynthesizer_SetAiroha2230Power( pHwData, PowerIndex ); + index = (u8)al2230_txvga_data[index][1]; + } + else if( RF_AIROHA_7230 == pHwData->phy_type ) + { + //Power index: 0 ~ 63 + index = RFSynthesizer_SetAiroha7230Power( pHwData, PowerIndex ); + index = (u8)al7230_txvga_data[index][1]; + } + else if( (RF_WB_242 == pHwData->phy_type) || + (RF_WB_242_1 == pHwData->phy_type) ) // 20060619.5 Add + { + //Power index: 0 ~ 19 for original. New range is 0 ~ 33 + index = RFSynthesizer_SetWinbond242Power( pHwData, PowerIndex ); + index = (u8)w89rf242_txvga_data[index][1]; + } + + pHwData->power_index = index; // Backup current + return index; +} + +//-- Sub function +u8 RFSynthesizer_SetMaxim2828_24Power( phw_data_t pHwData, u8 index ) +{ + u32 PowerData; + if( index > 1 ) index = 1; + PowerData = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2828_power_data_24[index], 18); + Wb35Reg_Write( pHwData, 0x0864, PowerData ); + return index; +} +//-- +u8 RFSynthesizer_SetMaxim2828_50Power( phw_data_t pHwData, u8 index ) +{ + u32 PowerData; + if( index > 1 ) index = 1; + PowerData = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2828_power_data_50[index], 18); + Wb35Reg_Write( pHwData, 0x0864, PowerData ); + return index; +} +//-- +u8 RFSynthesizer_SetMaxim2827_24Power( phw_data_t pHwData, u8 index ) +{ + u32 PowerData; + if( index > 1 ) index = 1; + PowerData = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2827_power_data_24[index], 18); + Wb35Reg_Write( pHwData, 0x0864, PowerData ); + return index; +} +//-- +u8 RFSynthesizer_SetMaxim2827_50Power( phw_data_t pHwData, u8 index ) +{ + u32 PowerData; + if( index > 1 ) index = 1; + PowerData = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2827_power_data_50[index], 18); + Wb35Reg_Write( pHwData, 0x0864, PowerData ); + return index; +} +//-- +u8 RFSynthesizer_SetMaxim2825Power( phw_data_t pHwData, u8 index ) +{ + u32 PowerData; + if( index > 1 ) index = 1; + PowerData = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2825_power_data_24[index], 18); + Wb35Reg_Write( pHwData, 0x0864, PowerData ); + return index; +} +//-- +u8 RFSynthesizer_SetAiroha2230Power( phw_data_t pHwData, u8 index ) +{ + u32 PowerData; + u8 i,count; + + count = sizeof(al2230_txvga_data) / sizeof(al2230_txvga_data[0]); + for (i=0; i<count; i++) + { + if (al2230_txvga_data[i][1] >= index) + break; + } + if (i == count) + i--; + + PowerData = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( al2230_txvga_data[i][0], 20); + Wb35Reg_Write( pHwData, 0x0864, PowerData ); + return i; +} +//-- +u8 RFSynthesizer_SetAiroha7230Power( phw_data_t pHwData, u8 index ) +{ + u32 PowerData; + u8 i,count; + + //PowerData = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( airoha_power_data_24[index], 20); + count = sizeof(al7230_txvga_data) / sizeof(al7230_txvga_data[0]); + for (i=0; i<count; i++) + { + if (al7230_txvga_data[i][1] >= index) + break; + } + if (i == count) + i--; + PowerData = (1 << 31) | (0 << 30) | (24 << 24) | (al7230_txvga_data[i][0]&0xffffff); + Wb35Reg_Write( pHwData, 0x0864, PowerData ); + return i; +} + +u8 RFSynthesizer_SetWinbond242Power( phw_data_t pHwData, u8 index ) +{ + u32 PowerData; + u8 i,count; + + count = sizeof(w89rf242_txvga_data) / sizeof(w89rf242_txvga_data[0]); + for (i=0; i<count; i++) + { + if (w89rf242_txvga_data[i][1] >= index) + break; + } + if (i == count) + i--; + + // Set TxVga into RF + PowerData = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( w89rf242_txvga_data[i][0], 24); + Wb35Reg_Write( pHwData, 0x0864, PowerData ); + + // Update BB48 BB4C BB58 for high precision txvga + Wb35Reg_Write( pHwData, 0x1048, w89rf242_txvga_data[i][2] ); + Wb35Reg_Write( pHwData, 0x104c, w89rf242_txvga_data[i][3] ); + Wb35Reg_Write( pHwData, 0x1058, w89rf242_txvga_data[i][4] ); + +// Rf vga 0 ~ 3 for temperature compensate. It will affect the scan Bss. +// The i value equals to 8 or 7 usually. So It's not necessary to setup this RF register. +// if( i <= 3 ) +// PowerData = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( 0x000024, 24 ); +// else +// PowerData = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( 0x001824, 24 ); +// Wb35Reg_Write( pHwData, 0x0864, PowerData ); + return i; +} + +//=========================================================================================================== +// Dxx_initial -- +// Mxx_initial -- + // +// Routine Description: +// Initial the hardware setting and module variable + // +//=========================================================================================================== +void Dxx_initial( phw_data_t pHwData ) +{ + PWB35REG pWb35Reg = &pHwData->Wb35Reg; + + // Old IC:Single mode only. + // New IC: operation decide by Software set bit[4]. 1:multiple 0: single + pWb35Reg->D00_DmaControl = 0xc0000004; //Txon, Rxon, multiple Rx for new 4k DMA + //Txon, Rxon, single Rx for old 8k ASIC + if( !HAL_USB_MODE_BURST( pHwData ) ) + pWb35Reg->D00_DmaControl = 0xc0000000;//Txon, Rxon, single Rx for new 4k DMA + + Wb35Reg_WriteSync( pHwData, 0x0400, pWb35Reg->D00_DmaControl ); +} + +void Mxx_initial( phw_data_t pHwData ) +{ + PWB35REG pWb35Reg = &pHwData->Wb35Reg; + u32 tmp; + u32 pltmp[11]; + u16 i; + + + //====================================================== + // Initial Mxx register + //====================================================== + + // M00 bit set +#ifdef _IBSS_BEACON_SEQ_STICK_ + pWb35Reg->M00_MacControl = 0; // Solve beacon sequence number stop by software +#else + pWb35Reg->M00_MacControl = 0x80000000; // Solve beacon sequence number stop by hardware +#endif + + // M24 disable enter power save, BB RxOn and enable NAV attack + pWb35Reg->M24_MacControl = 0x08040042; + pltmp[0] = pWb35Reg->M24_MacControl; + + pltmp[1] = 0; // Skip M28, because no initialize value is required. + + // M2C CWmin and CWmax setting + pHwData->cwmin = DEFAULT_CWMIN; + pHwData->cwmax = DEFAULT_CWMAX; + pWb35Reg->M2C_MacControl = DEFAULT_CWMIN << 10; + pWb35Reg->M2C_MacControl |= DEFAULT_CWMAX; + pltmp[2] = pWb35Reg->M2C_MacControl; + + // M30 BSSID + pltmp[3] = *(PULONG)pHwData->bssid; + + // M34 + pHwData->AID = DEFAULT_AID; + tmp = *(PUSHORT)(pHwData->bssid+4); + tmp |= DEFAULT_AID << 16; + pltmp[4] = tmp; + + // M38 + pWb35Reg->M38_MacControl = (DEFAULT_RATE_RETRY_LIMIT<<8) | (DEFAULT_LONG_RETRY_LIMIT << 4) | DEFAULT_SHORT_RETRY_LIMIT; + pltmp[5] = pWb35Reg->M38_MacControl; + + // M3C + tmp = (DEFAULT_PIFST << 26) | (DEFAULT_EIFST << 16) | (DEFAULT_DIFST << 8) | (DEFAULT_SIFST << 4) | DEFAULT_OSIFST ; + pWb35Reg->M3C_MacControl = tmp; + pltmp[6] = tmp; + + // M40 + pHwData->slot_time_select = DEFAULT_SLOT_TIME; + tmp = (DEFAULT_ATIMWD << 16) | DEFAULT_SLOT_TIME; + pWb35Reg->M40_MacControl = tmp; + pltmp[7] = tmp; + + // M44 + tmp = DEFAULT_MAX_TX_MSDU_LIFE_TIME << 10; // *1024 + pWb35Reg->M44_MacControl = tmp; + pltmp[8] = tmp; + + // M48 + pHwData->BeaconPeriod = DEFAULT_BEACON_INTERVAL; + pHwData->ProbeDelay = DEFAULT_PROBE_DELAY_TIME; + tmp = (DEFAULT_BEACON_INTERVAL << 16) | DEFAULT_PROBE_DELAY_TIME; + pWb35Reg->M48_MacControl = tmp; + pltmp[9] = tmp; + + //M4C + pWb35Reg->M4C_MacStatus = (DEFAULT_PROTOCOL_VERSION << 30) | (DEFAULT_MAC_POWER_STATE << 28) | (DEFAULT_DTIM_ALERT_TIME << 24); + pltmp[10] = pWb35Reg->M4C_MacStatus; + + // Burst write + //Wb35Reg_BurstWrite( pHwData, 0x0824, pltmp, 11, AUTO_INCREMENT ); + for( i=0; i<11; i++ ) + Wb35Reg_WriteSync( pHwData, 0x0824 + i*4, pltmp[i] ); + + // M60 + Wb35Reg_WriteSync( pHwData, 0x0860, 0x12481248 ); + pWb35Reg->M60_MacControl = 0x12481248; + + // M68 + Wb35Reg_WriteSync( pHwData, 0x0868, 0x00050900 ); // 20051018 0x000F0F00 ); // 940930 0x00131300 + pWb35Reg->M68_MacControl = 0x00050900; + + // M98 + Wb35Reg_WriteSync( pHwData, 0x0898, 0xffff8888 ); + pWb35Reg->M98_MacControl = 0xffff8888; +} + + +void Uxx_power_off_procedure( phw_data_t pHwData ) +{ + // SW, PMU reset and turn off clock + Wb35Reg_WriteSync( pHwData, 0x03b0, 3 ); + Wb35Reg_WriteSync( pHwData, 0x03f0, 0xf9 ); +} + +//Decide the TxVga of every channel +void GetTxVgaFromEEPROM( phw_data_t pHwData ) +{ + u32 i, j, ltmp; + u16 Value[MAX_TXVGA_EEPROM]; + PUCHAR pctmp; + u8 ctmp=0; + + // Get the entire TxVga setting in EEPROM + for( i=0; i<MAX_TXVGA_EEPROM; i++ ) + { + Wb35Reg_WriteSync( pHwData, 0x03b4, 0x08100000 + 0x00010000*i ); + Wb35Reg_ReadSync( pHwData, 0x03b4, <mp ); + Value[i] = (u16)( ltmp & 0xffff ); // Get 16 bit available + Value[i] = cpu_to_le16( Value[i] ); // [7:0]2412 [7:0]2417 .... + } + + // Adjust the filed which fills with reserved value. + pctmp = (PUCHAR)Value; + for( i=0; i<(MAX_TXVGA_EEPROM*2); i++ ) + { + if( pctmp[i] != 0xff ) + ctmp = pctmp[i]; + else + pctmp[i] = ctmp; + } + + // Adjust WB_242 to WB_242_1 TxVga scale + if( pHwData->phy_type == RF_WB_242 ) + { + for( i=0; i<4; i++ ) // Only 2412 2437 2462 2484 case must be modified + { + for( j=0; j<(sizeof(w89rf242_txvga_old_mapping)/sizeof(w89rf242_txvga_old_mapping[0])); j++ ) + { + if( pctmp[i] < (u8)w89rf242_txvga_old_mapping[j][1] ) + { + pctmp[i] = (u8)w89rf242_txvga_old_mapping[j][0]; + break; + } + } + + if( j == (sizeof(w89rf242_txvga_old_mapping)/sizeof(w89rf242_txvga_old_mapping[0])) ) + pctmp[i] = (u8)w89rf242_txvga_old_mapping[j-1][0]; + } + } + + // 20060621 Add + memcpy( pHwData->TxVgaSettingInEEPROM, pctmp, MAX_TXVGA_EEPROM*2 ); //MAX_TXVGA_EEPROM is u16 count + EEPROMTxVgaAdjust( pHwData ); +} + +// This function will affect the TxVga parameter in HAL. If hal_set_current_channel +// or RFSynthesizer_SetPowerIndex be called, new TxVga will take effect. +// TxVgaSettingInEEPROM of sHwData is an u8 array point to EEPROM contain for IS89C35 +// This function will use default TxVgaSettingInEEPROM data to calculate new TxVga. +void EEPROMTxVgaAdjust( phw_data_t pHwData ) // 20060619.5 Add +{ + PUCHAR pTxVga = pHwData->TxVgaSettingInEEPROM; + s16 i, stmp; + + //-- 2.4G -- 20060704.2 Request from Tiger + //channel 1 ~ 5 + stmp = pTxVga[1] - pTxVga[0]; + for( i=0; i<5; i++ ) + pHwData->TxVgaFor24[i] = pTxVga[0] + stmp*i/4; + //channel 6 ~ 10 + stmp = pTxVga[2] - pTxVga[1]; + for( i=5; i<10; i++ ) + pHwData->TxVgaFor24[i] = pTxVga[1] + stmp*(i-5)/4; + //channel 11 ~ 13 + stmp = pTxVga[3] - pTxVga[2]; + for( i=10; i<13; i++ ) + pHwData->TxVgaFor24[i] = pTxVga[2] + stmp*(i-10)/2; + //channel 14 + pHwData->TxVgaFor24[13] = pTxVga[3]; + + //-- 5G -- + if( pHwData->phy_type == RF_AIROHA_7230 ) + { + //channel 184 + pHwData->TxVgaFor50[0].ChanNo = 184; + pHwData->TxVgaFor50[0].TxVgaValue = pTxVga[4]; + //channel 196 + pHwData->TxVgaFor50[3].ChanNo = 196; + pHwData->TxVgaFor50[3].TxVgaValue = pTxVga[5]; + //interpolate + pHwData->TxVgaFor50[1].ChanNo = 188; + pHwData->TxVgaFor50[2].ChanNo = 192; + stmp = pTxVga[5] - pTxVga[4]; + pHwData->TxVgaFor50[2].TxVgaValue = pTxVga[5] - stmp/3; + pHwData->TxVgaFor50[1].TxVgaValue = pTxVga[5] - stmp*2/3; + + //channel 16 + pHwData->TxVgaFor50[6].ChanNo = 16; + pHwData->TxVgaFor50[6].TxVgaValue = pTxVga[6]; + pHwData->TxVgaFor50[4].ChanNo = 8; + pHwData->TxVgaFor50[4].TxVgaValue = pTxVga[6]; + pHwData->TxVgaFor50[5].ChanNo = 12; + pHwData->TxVgaFor50[5].TxVgaValue = pTxVga[6]; + + //channel 36 + pHwData->TxVgaFor50[8].ChanNo = 36; + pHwData->TxVgaFor50[8].TxVgaValue = pTxVga[7]; + pHwData->TxVgaFor50[7].ChanNo = 34; + pHwData->TxVgaFor50[7].TxVgaValue = pTxVga[7]; + pHwData->TxVgaFor50[9].ChanNo = 38; + pHwData->TxVgaFor50[9].TxVgaValue = pTxVga[7]; + + //channel 40 + pHwData->TxVgaFor50[10].ChanNo = 40; + pHwData->TxVgaFor50[10].TxVgaValue = pTxVga[8]; + //channel 48 + pHwData->TxVgaFor50[14].ChanNo = 48; + pHwData->TxVgaFor50[14].TxVgaValue = pTxVga[9]; + //interpolate + pHwData->TxVgaFor50[11].ChanNo = 42; + pHwData->TxVgaFor50[12].ChanNo = 44; + pHwData->TxVgaFor50[13].ChanNo = 46; + stmp = pTxVga[9] - pTxVga[8]; + pHwData->TxVgaFor50[13].TxVgaValue = pTxVga[9] - stmp/4; + pHwData->TxVgaFor50[12].TxVgaValue = pTxVga[9] - stmp*2/4; + pHwData->TxVgaFor50[11].TxVgaValue = pTxVga[9] - stmp*3/4; + + //channel 52 + pHwData->TxVgaFor50[15].ChanNo = 52; + pHwData->TxVgaFor50[15].TxVgaValue = pTxVga[10]; + //channel 64 + pHwData->TxVgaFor50[18].ChanNo = 64; + pHwData->TxVgaFor50[18].TxVgaValue = pTxVga[11]; + //interpolate + pHwData->TxVgaFor50[16].ChanNo = 56; + pHwData->TxVgaFor50[17].ChanNo = 60; + stmp = pTxVga[11] - pTxVga[10]; + pHwData->TxVgaFor50[17].TxVgaValue = pTxVga[11] - stmp/3; + pHwData->TxVgaFor50[16].TxVgaValue = pTxVga[11] - stmp*2/3; + + //channel 100 + pHwData->TxVgaFor50[19].ChanNo = 100; + pHwData->TxVgaFor50[19].TxVgaValue = pTxVga[12]; + //channel 112 + pHwData->TxVgaFor50[22].ChanNo = 112; + pHwData->TxVgaFor50[22].TxVgaValue = pTxVga[13]; + //interpolate + pHwData->TxVgaFor50[20].ChanNo = 104; + pHwData->TxVgaFor50[21].ChanNo = 108; + stmp = pTxVga[13] - pTxVga[12]; + pHwData->TxVgaFor50[21].TxVgaValue = pTxVga[13] - stmp/3; + pHwData->TxVgaFor50[20].TxVgaValue = pTxVga[13] - stmp*2/3; + + //channel 128 + pHwData->TxVgaFor50[26].ChanNo = 128; + pHwData->TxVgaFor50[26].TxVgaValue = pTxVga[14]; + //interpolate + pHwData->TxVgaFor50[23].ChanNo = 116; + pHwData->TxVgaFor50[24].ChanNo = 120; + pHwData->TxVgaFor50[25].ChanNo = 124; + stmp = pTxVga[14] - pTxVga[13]; + pHwData->TxVgaFor50[25].TxVgaValue = pTxVga[14] - stmp/4; + pHwData->TxVgaFor50[24].TxVgaValue = pTxVga[14] - stmp*2/4; + pHwData->TxVgaFor50[23].TxVgaValue = pTxVga[14] - stmp*3/4; + + //channel 140 + pHwData->TxVgaFor50[29].ChanNo = 140; + pHwData->TxVgaFor50[29].TxVgaValue = pTxVga[15]; + //interpolate + pHwData->TxVgaFor50[27].ChanNo = 132; + pHwData->TxVgaFor50[28].ChanNo = 136; + stmp = pTxVga[15] - pTxVga[14]; + pHwData->TxVgaFor50[28].TxVgaValue = pTxVga[15] - stmp/3; + pHwData->TxVgaFor50[27].TxVgaValue = pTxVga[15] - stmp*2/3; + + //channel 149 + pHwData->TxVgaFor50[30].ChanNo = 149; + pHwData->TxVgaFor50[30].TxVgaValue = pTxVga[16]; + //channel 165 + pHwData->TxVgaFor50[34].ChanNo = 165; + pHwData->TxVgaFor50[34].TxVgaValue = pTxVga[17]; + //interpolate + pHwData->TxVgaFor50[31].ChanNo = 153; + pHwData->TxVgaFor50[32].ChanNo = 157; + pHwData->TxVgaFor50[33].ChanNo = 161; + stmp = pTxVga[17] - pTxVga[16]; + pHwData->TxVgaFor50[33].TxVgaValue = pTxVga[17] - stmp/4; + pHwData->TxVgaFor50[32].TxVgaValue = pTxVga[17] - stmp*2/4; + pHwData->TxVgaFor50[31].TxVgaValue = pTxVga[17] - stmp*3/4; + } + + #ifdef _PE_STATE_DUMP_ + WBDEBUG((" TxVgaFor24 : \n")); + DataDmp((u8 *)pHwData->TxVgaFor24, 14 ,0); + WBDEBUG((" TxVgaFor50 : \n")); + DataDmp((u8 *)pHwData->TxVgaFor50, 70 ,0); + #endif +} + +void BBProcessor_RateChanging( phw_data_t pHwData, u8 rate ) // 20060613.1 +{ + PWB35REG pWb35Reg = &pHwData->Wb35Reg; + unsigned char Is11bRate; + + Is11bRate = (rate % 6) ? 1 : 0; + switch( pHwData->phy_type ) + { + case RF_AIROHA_2230: + case RF_AIROHA_2230S: // 20060420 Add this + if( Is11bRate ) + { + if( (pWb35Reg->BB48 != BB48_DEFAULT_AL2230_11B) && + (pWb35Reg->BB4C != BB4C_DEFAULT_AL2230_11B) ) + { + Wb35Reg_Write( pHwData, 0x1048, BB48_DEFAULT_AL2230_11B ); + Wb35Reg_Write( pHwData, 0x104c, BB4C_DEFAULT_AL2230_11B ); + } + } + else + { + if( (pWb35Reg->BB48 != BB48_DEFAULT_AL2230_11G) && + (pWb35Reg->BB4C != BB4C_DEFAULT_AL2230_11G) ) + { + Wb35Reg_Write( pHwData, 0x1048, BB48_DEFAULT_AL2230_11G ); + Wb35Reg_Write( pHwData, 0x104c, BB4C_DEFAULT_AL2230_11G ); + } + } + break; + + case RF_WB_242: // 20060623 The fix only for old TxVGA setting + if( Is11bRate ) + { + if( (pWb35Reg->BB48 != BB48_DEFAULT_WB242_11B) && + (pWb35Reg->BB4C != BB4C_DEFAULT_WB242_11B) ) + { + pWb35Reg->BB48 = BB48_DEFAULT_WB242_11B; + pWb35Reg->BB4C = BB4C_DEFAULT_WB242_11B; + Wb35Reg_Write( pHwData, 0x1048, BB48_DEFAULT_WB242_11B ); + Wb35Reg_Write( pHwData, 0x104c, BB4C_DEFAULT_WB242_11B ); + } + } + else + { + if( (pWb35Reg->BB48 != BB48_DEFAULT_WB242_11G) && + (pWb35Reg->BB4C != BB4C_DEFAULT_WB242_11G) ) + { + pWb35Reg->BB48 = BB48_DEFAULT_WB242_11G; + pWb35Reg->BB4C = BB4C_DEFAULT_WB242_11G; + Wb35Reg_Write( pHwData, 0x1048, BB48_DEFAULT_WB242_11G ); + Wb35Reg_Write( pHwData, 0x104c, BB4C_DEFAULT_WB242_11G ); + } + } + break; + } +} + + + + + + + diff --git a/drivers/staging/winbond/rxisr.c b/drivers/staging/winbond/rxisr.c new file mode 100644 index 000000000000..18e942c9b821 --- /dev/null +++ b/drivers/staging/winbond/rxisr.c @@ -0,0 +1,30 @@ +#include "os_common.h" + +void vRxTimerInit(PWB32_ADAPTER Adapter) +{ + OS_TIMER_INITIAL(&(Adapter->Mds.nTimer), (void*) RxTimerHandler, (void*) Adapter); +} + +void vRxTimerStart(PWB32_ADAPTER Adapter, int timeout_value) +{ + if (timeout_value<MIN_TIMEOUT_VAL) + timeout_value=MIN_TIMEOUT_VAL; + + OS_TIMER_SET( &(Adapter->Mds.nTimer), timeout_value ); +} + +void vRxTimerStop(PWB32_ADAPTER Adapter) +{ + OS_TIMER_CANCEL( &(Adapter->Mds.nTimer), 0 ); +} + +void RxTimerHandler_1a( PADAPTER Adapter) +{ + RxTimerHandler(NULL, Adapter, NULL, NULL); +} + +void RxTimerHandler(void* SystemSpecific1, PWB32_ADAPTER Adapter, + void* SystemSpecific2, void* SystemSpecific3) +{ + WARN_ON(1); +} diff --git a/drivers/staging/winbond/scan_s.h b/drivers/staging/winbond/scan_s.h new file mode 100644 index 000000000000..1d1b0c4fec17 --- /dev/null +++ b/drivers/staging/winbond/scan_s.h @@ -0,0 +1,115 @@ +// +// SCAN task global CONSTANTS, STRUCTURES, variables +// + +////////////////////////////////////////////////////////////////////////// +//define the msg type of SCAN module +#define SCANMSG_SCAN_REQ 0x01 +#define SCANMSG_BEACON 0x02 +#define SCANMSG_PROBE_RESPONSE 0x03 +#define SCANMSG_TIMEOUT 0x04 +#define SCANMSG_TXPROBE_FAIL 0x05 +#define SCANMSG_ENABLE_BGSCAN 0x06 +#define SCANMSG_STOP_SCAN 0x07 + +// BSS Type =>conform to +// IBSS : ToDS/FromDS = 00 +// Infrastructure : ToDS/FromDS = 01 +#define IBSS_NET 0 +#define ESS_NET 1 +#define ANYBSS_NET 2 + +// Scan Type +#define ACTIVE_SCAN 0 +#define PASSIVE_SCAN 1 + +/////////////////////////////////////////////////////////////////////////// +//Global data structures, Initial Scan & Background Scan +typedef struct _SCAN_REQ_PARA //mandatory parameters for SCAN request +{ + u32 ScanType; //passive/active scan + + CHAN_LIST sChannelList; // 86B + u8 reserved_1[2]; + + struct SSID_Element sSSID; // 34B. scan only for this SSID + u8 reserved_2[2]; + +} SCAN_REQ_PARA, *psSCAN_REQ_PARA; + +typedef struct _SCAN_PARAMETERS +{ + u16 wState; + u16 iCurrentChannelIndex; + + SCAN_REQ_PARA sScanReq; + + u8 BSSID[MAC_ADDR_LENGTH + 2]; //scan only for this BSSID + + u32 BssType; //scan only for this BSS type + + //struct SSID_Element sSSID; //scan only for this SSID + u16 ProbeDelay; + u16 MinChannelTime; + + u16 MaxChannelTime; + u16 reserved_1; + + s32 iBgScanPeriod; // XP: 5 sec + + u8 boBgScan; // Wb: enable BG scan, For XP, this value must be FALSE + u8 boFastScan; // Wb: reserved + u8 boCCAbusy; // Wb: HWMAC CCA busy status + u8 reserved_2; + + //NDIS_MINIPORT_TIMER nTimer; + OS_TIMER nTimer; + + u32 ScanTimeStamp; //Increase 1 per background scan(1 minute) + u32 BssTimeStamp; //Increase 1 per connect status check + u32 RxNumPerAntenna[2]; // + + u8 AntennaToggle; // + u8 boInTimerHandler; + u8 boTimerActive; // Wb: reserved + u8 boSave; + + u32 BScanEnable; // Background scan enable. Default is On + +} SCAN_PARAMETERS, *psSCAN_PARAMETERS; + +// Encapsulate 'Adapter' data structure +#define psSCAN (&(Adapter->sScanPara)) +#define psSCANREQ (&(Adapter->sScanPara.sScanReq)) + +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// scan.h +// Define the related definitions of scan module +// history -- 01/14/03' created +// +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +//Define the state of scan module +#define SCAN_INACTIVE 0 +#define WAIT_PROBE_DELAY 1 +#define WAIT_RESPONSE_MIN 2 +#define WAIT_RESPONSE_MAX_ACTIVE 3 +#define WAIT_BEACON_MAX_PASSIVE 4 +#define SCAN_COMPLETE 5 +#define BG_SCAN 6 +#define BG_SCANNING 7 + + +// The value will load from EEPROM +// If 0xff is set in EEPOM, the driver will use SCAN_MAX_CHNL_TIME instead. +// The definition is in WbHal.h +// #define SCAN_MAX_CHNL_TIME (50) + + + +// static functions + +//static void ScanTimerHandler(PWB32_ADAPTER Adapter); +//static void vScanTimerStart(PWB32_ADAPTER Adapter, int timeout_value); +//static void vScanTimerStop(PWB32_ADAPTER Adapter); + diff --git a/drivers/staging/winbond/sme_api.c b/drivers/staging/winbond/sme_api.c new file mode 100644 index 000000000000..40e93b7600eb --- /dev/null +++ b/drivers/staging/winbond/sme_api.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------------ +// sme_api.c +// +// Copyright(C) 2002 Winbond Electronics Corp. +// +// +//------------------------------------------------------------------------------------ +#include "os_common.h" + +s8 sme_get_rssi(void *pcore_data, s32 *prssi) +{ + BUG(); +} diff --git a/drivers/staging/winbond/sme_api.h b/drivers/staging/winbond/sme_api.h new file mode 100644 index 000000000000..016b225ca4a4 --- /dev/null +++ b/drivers/staging/winbond/sme_api.h @@ -0,0 +1,265 @@ +/* + * sme_api.h + * + * Copyright(C) 2002 Winbond Electronics Corp. + * + * modification history + * --------------------------------------------------------------------------- + * 1.00.001, 2003-04-21, Kevin created + * 1.00.002, 2003-05-14, PD43 & PE20 modified + * + */ + +#ifndef __SME_API_H__ +#define __SME_API_H__ + +/****************** INCLUDE FILES SECTION ***********************************/ +//#include "GL\gl_core.h" + +/****************** CONSTANT AND MACRO SECTION ******************************/ +#define _INLINE __inline + +#define MEDIA_STATE_DISCONNECTED 0 +#define MEDIA_STATE_CONNECTED 1 + +//ARRAY CHECK +#define MAX_POWER_TO_DB 32 + +/****************** TYPE DEFINITION SECTION *********************************/ + +/****************** EXPORTED FUNCTION DECLARATION SECTION *******************/ + +// OID_802_11_BSSID +s8 sme_get_bssid(void *pcore_data, u8 *pbssid); +s8 sme_get_desired_bssid(void *pcore_data, u8 *pbssid);//Not use +s8 sme_set_desired_bssid(void *pcore_data, u8 *pbssid); + +// OID_802_11_SSID +s8 sme_get_ssid(void *pcore_data, u8 *pssid, u8 *pssid_len); +s8 sme_get_desired_ssid(void *pcore_data, u8 *pssid, u8 *pssid_len);// Not use +s8 sme_set_desired_ssid(void *pcore_data, u8 *pssid, u8 ssid_len); + +// OID_802_11_INFRASTRUCTURE_MODE +s8 sme_get_bss_type(void *pcore_data, u8 *pbss_type); +s8 sme_get_desired_bss_type(void *pcore_data, u8 *pbss_type);//Not use +s8 sme_set_desired_bss_type(void *pcore_data, u8 bss_type); + +// OID_802_11_FRAGMENTATION_THRESHOLD +s8 sme_get_fragment_threshold(void *pcore_data, u32 *pthreshold); +s8 sme_set_fragment_threshold(void *pcore_data, u32 threshold); + +// OID_802_11_RTS_THRESHOLD +s8 sme_get_rts_threshold(void *pcore_data, u32 *pthreshold); +s8 sme_set_rts_threshold(void *pcore_data, u32 threshold); + +// OID_802_11_RSSI +s8 sme_get_rssi(void *pcore_data, s32 *prssi); + +// OID_802_11_CONFIGURATION +s8 sme_get_beacon_period(void *pcore_data, u16 *pbeacon_period); +s8 sme_set_beacon_period(void *pcore_data, u16 beacon_period); + +s8 sme_get_atim_window(void *pcore_data, u16 *patim_window); +s8 sme_set_atim_window(void *pcore_data, u16 atim_window); + +s8 sme_get_current_channel(void *pcore_data, u8 *pcurrent_channel); +s8 sme_get_current_band(void *pcore_data, u8 *pcurrent_band); +s8 sme_set_current_channel(void *pcore_data, u8 current_channel); + +// OID_802_11_BSSID_LIST +s8 sme_get_scan_bss_count(void *pcore_data, u8 *pcount); +s8 sme_get_scan_bss(void *pcore_data, u8 index, void **ppbss); + +s8 sme_get_connected_bss(void *pcore_data, void **ppbss_now); + +// OID_802_11_AUTHENTICATION_MODE +s8 sme_get_auth_mode(void *pcore_data, u8 *pauth_mode); +s8 sme_set_auth_mode(void *pcore_data, u8 auth_mode); + +// OID_802_11_WEP_STATUS / OID_802_11_ENCRYPTION_STATUS +s8 sme_get_wep_mode(void *pcore_data, u8 *pwep_mode); +s8 sme_set_wep_mode(void *pcore_data, u8 wep_mode); +//s8 sme_get_encryption_status(void *pcore_data, u8 *pstatus); +//s8 sme_set_encryption_status(void *pcore_data, u8 status); + +// ??????????????????????????????????????? + +// OID_GEN_VENDOR_ID +// OID_802_3_PERMANENT_ADDRESS +s8 sme_get_permanent_mac_addr(void *pcore_data, u8 *pmac_addr); + +// OID_802_3_CURRENT_ADDRESS +s8 sme_get_current_mac_addr(void *pcore_data, u8 *pmac_addr); + +// OID_802_11_NETWORK_TYPE_IN_USE +s8 sme_get_network_type_in_use(void *pcore_data, u8 *ptype); +s8 sme_set_network_type_in_use(void *pcore_data, u8 type); + +// OID_802_11_SUPPORTED_RATES +s8 sme_get_supported_rate(void *pcore_data, u8 *prates); + +// OID_802_11_ADD_WEP +//12/29/03' wkchen +s8 sme_set_add_wep(void *pcore_data, u32 key_index, u32 key_len, + u8 *Address, u8 *key); + +// OID_802_11_REMOVE_WEP +s8 sme_set_remove_wep(void *pcre_data, u32 key_index); + +// OID_802_11_DISASSOCIATE +s8 sme_set_disassociate(void *pcore_data); + +// OID_802_11_POWER_MODE +s8 sme_get_power_mode(void *pcore_data, u8 *pmode); +s8 sme_set_power_mode(void *pcore_data, u8 mode); + +// OID_802_11_BSSID_LIST_SCAN +s8 sme_set_bssid_list_scan(void *pcore_data, void *pscan_para); + +// OID_802_11_RELOAD_DEFAULTS +s8 sme_set_reload_defaults(void *pcore_data, u8 reload_type); + + +// The following SME API functions are used for WPA +// +// Mandatory OIDs for WPA +// + +// OID_802_11_ADD_KEY +//s8 sme_set_add_key(void *pcore_data, NDIS_802_11_KEY *pkey); + +// OID_802_11_REMOVE_KEY +//s8 sme_set_remove_key(void *pcore_data, NDIS_802_11_REMOVE_KEY *pkey); + +// OID_802_11_ASSOCIATION_INFORMATION +//s8 sme_set_association_information(void *pcore_data, +// NDIS_802_11_ASSOCIATION_INFORMATION *pinfo); + +// OID_802_11_TEST +//s8 sme_set_test(void *pcore_data, NDIS_802_11_TEST *ptest_data); + +//--------------------------------------------------------------------------// +/* +// The left OIDs + +// OID_802_11_NETWORK_TYPES_SUPPORTED +// OID_802_11_TX_POWER_LEVEL +// OID_802_11_RSSI_TRIGGER +// OID_802_11_NUMBER_OF_ANTENNAS +// OID_802_11_RX_ANTENNA_SELECTED +// OID_802_11_TX_ANTENNA_SELECTED +// OID_802_11_STATISTICS +// OID_802_11_DESIRED_RATES +// OID_802_11_PRIVACY_FILTER + +*/ + +/*------------------------- none-standard ----------------------------------*/ +s8 sme_get_connect_status(void *pcore_data, u8 *pstatus); + +/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +//s8 sme_get_scan_type(void *pcore_data, u8 *pscan_type); +//s8 sme_set_scan_type(void *pcore_data, u8 scan_type); + +//s8 sme_get_scan_channel_list(void *pcore_data, u8 *pscan_type); +//s8 sme_set_scan_channel_list(void *pcore_data, u8 scan_type); + + +void sme_get_encryption_status(void *pcore_data, u8 *EncryptStatus); +void sme_set_encryption_status(void *pcore_data, u8 EncryptStatus); +s8 sme_add_key(void *pcore_data, + u32 key_index, + u8 key_len, + u8 key_type, + u8 *key_bssid, + //u8 *key_rsc, + u8 *ptx_tsc, + u8 *prx_tsc, + u8 *key_material); +void sme_remove_default_key(void *pcore_data, int index); +void sme_remove_mapping_key(void *pcore_data, u8 *pmac_addr); +void sme_clear_all_mapping_key(void *pcore_data); +void sme_clear_all_default_key(void *pcore_data); + + + +s8 sme_set_preamble_mode(void *pcore_data, u8 mode); +s8 sme_get_preamble_mode(void *pcore_data, u8 *mode); +s8 sme_get_preamble_type(void *pcore_data, u8 *type); +s8 sme_set_slottime_mode(void *pcore_data, u8 mode); +s8 sme_get_slottime_mode(void *pcore_data, u8 *mode); +s8 sme_get_slottime_type(void *pcore_data, u8 *type); +s8 sme_set_txrate_policy(void *pcore_data, u8 policy); +s8 sme_get_txrate_policy(void *pcore_data, u8 *policy); +s8 sme_get_cwmin_value(void *pcore_data, u8 *cwmin); +s8 sme_get_cwmax_value(void *pcore_data, u16 *cwmax); +s8 sme_get_ms_radio_mode(void *pcore_data, u8 * pMsRadioOff); +s8 sme_set_ms_radio_mode(void *pcore_data, u8 boMsRadioOff); +s8 sme_get_radio_mode(void *pcore_data, psRadioOff pRadioOffData); +s8 sme_set_radio_mode(void *pcore_data, RadioOff RadioOffData); + +void sme_get_tx_power_level(void *pcore_data, u32 *TxPower); +u8 sme_set_tx_power_level(void *pcore_data, u32 TxPower); +void sme_get_antenna_count(void *pcore_data, u32 *AntennaCount); +void sme_get_rx_antenna(void *pcore_data, u32 *RxAntenna); +u8 sme_set_rx_antenna(void *pcore_data, u32 RxAntenna); +void sme_get_tx_antenna(void *pcore_data, u32 *TxAntenna); +s8 sme_set_tx_antenna(void *pcore_data, u32 TxAntenna); +s8 sme_set_IBSS_chan(void *pcore_data, ChanInfo chan); + +//20061108 WPS +s8 sme_set_IE_append(void *pcore_data, PUCHAR buffer, u16 buf_len); + + + + +//================== Local functions ====================== +//#ifdef _HSINCHU +//void drv_translate_rssi(); // HW RSSI bit -> NDIS RSSI representation +//void drv_translate_bss_description(); // Local bss desc -> NDIS bss desc +//void drv_translate_channel(u8 NetworkType, u8 ChannelNumber, u32 *freq); // channel number -> channel /freq. +//#endif _HSINCHU +// +static const u32 PowerDbToMw[] = +{ + 56, //mW, MAX - 0, 17.5 dbm + 40, //mW, MAX - 1, 16.0 dbm + 30, //mW, MAX - 2, 14.8 dbm + 20, //mW, MAX - 3, 13.0 dbm + 15, //mW, MAX - 4, 11.8 dbm + 12, //mW, MAX - 5, 10.6 dbm + 9, //mW, MAX - 6, 9.4 dbm + 7, //mW, MAX - 7, 8.3 dbm + 5, //mW, MAX - 8, 6.4 dbm + 4, //mW, MAX - 9, 5.3 dbm + 3, //mW, MAX - 10, 4.0 dbm + 2, //mW, MAX - 11, ? dbm + 2, //mW, MAX - 12, ? dbm + 2, //mW, MAX - 13, ? dbm + 2, //mW, MAX - 14, ? dbm + 2, //mW, MAX - 15, ? dbm + 2, //mW, MAX - 16, ? dbm + 2, //mW, MAX - 17, ? dbm + 2, //mW, MAX - 18, ? dbm + 1, //mW, MAX - 19, ? dbm + 1, //mW, MAX - 20, ? dbm + 1, //mW, MAX - 21, ? dbm + 1, //mW, MAX - 22, ? dbm + 1, //mW, MAX - 23, ? dbm + 1, //mW, MAX - 24, ? dbm + 1, //mW, MAX - 25, ? dbm + 1, //mW, MAX - 26, ? dbm + 1, //mW, MAX - 27, ? dbm + 1, //mW, MAX - 28, ? dbm + 1, //mW, MAX - 29, ? dbm + 1, //mW, MAX - 30, ? dbm + 1 //mW, MAX - 31, ? dbm +}; + + + + + +#endif /* __SME_API_H__ */ + + diff --git a/drivers/staging/winbond/sme_s.h b/drivers/staging/winbond/sme_s.h new file mode 100644 index 000000000000..dfd2fbc4edef --- /dev/null +++ b/drivers/staging/winbond/sme_s.h @@ -0,0 +1,228 @@ +// +// SME_S.H - +// SME task global CONSTANTS, STRUCTURES, variables +// + +////////////////////////////////////////////////////////////////////////// +//define the msg type of SME module +// 0x00~0x1F : MSG from GUI dispatch +// 0x20~0x3F : MSG from MLME +// 0x40~0x5F : MSG from SCAN +// 0x60~0x6F : MSG from TX/RX +// 0x70~0x7F : MSG from ROAMING +// 0x80~0x8F : MSG from ISR +// 0x90 : MSG TimeOut + +// from GUI +#define SMEMSG_SCAN_REQ 0x01 +//#define SMEMSG_PASSIVE_SCAN_REQ 0x02 +#define SMEMSG_JOIN_REQ 0x03 +#define SMEMSG_START_IBSS 0x04 +#define SMEMSG_DISCONNECT_REQ 0x05 +#define SMEMSG_AUTHEN_REQ 0x06 +#define SMEMSG_DEAUTHEN_REQ 0x07 +#define SMEMSG_ASSOC_REQ 0x08 +#define SMEMSG_REASSOC_REQ 0x09 +#define SMEMSG_DISASSOC_REQ 0x0a +#define SMEMSG_POWERSAVE_REQ 0x0b + + +// from MLME +#define SMEMSG_AUTHEN_CFM 0x21 +#define SMEMSG_AUTHEN_IND 0x22 +#define SMEMSG_ASSOC_CFM 0x23 +#define SMEMSG_DEAUTHEN_IND 0x24 +#define SMEMSG_DISASSOC_IND 0x25 +// from SCAN +#define SMEMSG_SCAN_CFM 0x41 +#define SMEMSG_START_IBSS_CFM 0x42 +// from MTO, function call to set SME parameters + +// 0x60~0x6F : MSG from TX/RX +//#define SMEMSG_IBSS_JOIN_UPDATE_BSSID 0x61 +#define SMEMSG_COUNTERMEASURE_MICFAIL_TIMEOUT 0x62 +#define SMEMSG_COUNTERMEASURE_BLOCK_TIMEOUT 0x63 +// from ROAMING +#define SMEMSG_HANDOVER_JOIN_REQ 0x71 +#define SMEMSG_END_ROAMING 0x72 +#define SMEMSG_SCAN_JOIN_REQ 0x73 +// from ISR +#define SMEMSG_TSF_SYNC_IND 0x81 +// from TimeOut +#define SMEMSG_TIMEOUT 0x91 + + + +#define MAX_PMKID_Accunt 16 +//@added by ws 04/22/05 +#define Cipher_Disabled 0 +#define Cipher_Wep 1 +#define Cipher_Tkip 2 +#define Cipher_Ccmp 4 + + +/////////////////////////////////////////////////////////////////////////// +//Constants + +/////////////////////////////////////////////////////////////////////////// +//Global data structures + +#define NUMOFWEPENTRIES 64 + +typedef enum _WEPKeyMode +{ + WEPKEY_DISABLED = 0, + WEPKEY_64 = 1, + WEPKEY_128 = 2 + +} WEPKEYMODE, *pWEPKEYMODE; + +#ifdef _WPA2_ + +typedef struct _BSSInfo +{ + u8 PreAuthBssID[6]; + PMKID pmkid_value; +}BSSID_Info; + +typedef struct _PMKID_Table //added by ws 05/05/04 +{ + u32 Length; + u32 BSSIDInfoCount; + BSSID_Info BSSIDInfo[16]; + +} PMKID_Table; + +#endif //end def _WPA2_ + +#define MAX_BASIC_RATE_SET 15 +#define MAX_OPT_RATE_SET MAX_BASIC_RATE_SET + + +typedef struct _SME_PARAMETERS +{ + u16 wState; + u8 boDUTmode; + u8 bDesiredPowerSave; + + // SME timer and timeout value + //NDIS_MINIPORT_TIMER nTimer; + OS_TIMER nTimer; + + u8 boInTimerHandler; + u8 boAuthRetryActive; + u8 reserved_0[2]; + + u32 AuthenRetryTimerVal; // NOTE: Assoc don't fail timeout + u32 JoinFailTimerVal; // 10*Beacon-Interval + + //Rates + u8 BSSBasicRateSet[(MAX_BASIC_RATE_SET + 3) & ~0x03 ]; // BSS basic rate set + u8 OperationalRateSet[(MAX_OPT_RATE_SET + 3) & ~0x03 ]; // Operational rate set + + u8 NumOfBSSBasicRate; + u8 NumOfOperationalRate; + u8 reserved_1[2]; + + u32 BasicRateBitmap; + u32 OpRateBitmap; + + // System parameters Set by GUI + //-------------------- start IBSS parameter ---------------------------// + u32 boStartIBSS; //Start IBSS toggle + + u16 wBeaconPeriod; + u16 wATIM_Window; + + ChanInfo IbssChan; // 2B //channel setting when start IBSS + u8 reserved_2[2]; + + // Join related + u16 wDesiredJoinBSS; // BSS index which desire to join + u8 boJoinReq; //Join request toggle + u8 bDesiredBSSType; //for Join request + + u16 wCapabilityInfo; // Used when invoking the MLME_Associate_request(). + u16 wNonERPcapabilityInfo; + + struct SSID_Element sDesiredSSID; // 34 B + u8 reserved_3[2]; + + u8 abDesiredBSSID[MAC_ADDR_LENGTH + 2]; + + u8 bJoinScanCount; // the time of scan-join action need to do + u8 bDesiredAuthMode; // AUTH_OPEN_SYSTEM or AUTH_SHARED_KEY + u8 reserved_4[2]; + + // Encryption parameters + u8 _dot11PrivacyInvoked; + u8 _dot11PrivacyOptionImplemented; + u8 reserved_5[2]; + + //@ ws added + u8 DesiredEncrypt; + u8 encrypt_status; //ENCRYPT_DISABLE, ENCRYPT_WEP, ENCRYPT_WEP_NOKEY, ENCRYPT_TKIP, ... + u8 key_length; + u8 pairwise_key_ok; + + u8 group_key_ok; + u8 wpa_ok; // indicate the control port of 802.1x is open or close + u8 pairwise_key_type; + u8 group_key_type; + + u32 _dot11WEPDefaultKeyID; + + u8 tx_mic_key[8]; // TODO: 0627 kevin-TKIP + u8 rx_mic_key[8]; // TODO: 0627 kevin-TKIP + u8 group_tx_mic_key[8]; + u8 group_rx_mic_key[8]; + +// #ifdef _WPA_ + u8 AssocReqVarIE[200]; + u8 AssocRespVarIE[200]; + + u16 AssocReqVarLen; + u16 AssocRespVarLen; + u8 boReassoc; //use assoc. or reassoc. + u8 reserved_6[3]; + u16 AssocRespCapability; + u16 AssocRespStatus; +// #endif + + #ifdef _WPA2_ + u8 PmkIdTable[256]; + u32 PmkidTableIndex; + #endif //end def _WPA2_ + +} SME_PARAMETERS, *PSME_PARAMETERS; + +#define psSME (&(Adapter->sSmePara)) + +#define wSMEGetCurrentSTAState(Adapter) ((u16)(Adapter)->sSmePara.wState) + + + +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// SmeModule.h +// Define the related definitions of SME module +// history -- 01/14/03' created +// +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +//Define the state of SME module +#define DISABLED 0 +#define INIT_SCAN 1 +#define SCAN_READY 2 +#define START_IBSS 3 +#define JOIN_PENDING 4 +#define JOIN_CFM 5 +#define AUTHENTICATE_PENDING 6 +#define AUTHENTICATED 7 +#define CONNECTED 8 +//#define EAP_STARTING 9 +//#define EAPOL_AUTHEN_PENDING 10 +//#define SECURE_CONNECTED 11 + + +// Static function + diff --git a/drivers/staging/winbond/wb35_ver.h b/drivers/staging/winbond/wb35_ver.h new file mode 100644 index 000000000000..2433bc073004 --- /dev/null +++ b/drivers/staging/winbond/wb35_ver.h @@ -0,0 +1,30 @@ +// +// Only define one of follow +// + +#ifdef WB_WIN + #define VER_FILEVERSION 1,00,47,00 + #define VER_FILEVERSION_STR "1.00.47.00" + #define WB32_DRIVER_MAJOR_VERSION 0x0100 + #define WB32_DRIVER_MINOR_VERSION 0x4700 +#endif + +#ifdef WB_CE + #define VER_FILEVERSION 2,00,47,00 + #define VER_FILEVERSION_STR "2.00.47.00" + #define WB32_DRIVER_MAJOR_VERSION 0x0200 + #define WB32_DRIVER_MINOR_VERSION 0x4700 +#endif + +#ifdef WB_LINUX + #define VER_FILEVERSION 3,00,47,00 + #define VER_FILEVERSION_STR "3.00.47.00" + #define WB32_DRIVER_MAJOR_VERSION 0x0300 + #define WB32_DRIVER_MINOR_VERSION 0x4700 +#endif + + + + + + diff --git a/drivers/staging/winbond/wbhal.c b/drivers/staging/winbond/wbhal.c new file mode 100644 index 000000000000..daf442247558 --- /dev/null +++ b/drivers/staging/winbond/wbhal.c @@ -0,0 +1,878 @@ +#include "os_common.h" + +void hal_get_ethernet_address( phw_data_t pHwData, PUCHAR current_address ) +{ + if( pHwData->SurpriseRemove ) return; + + memcpy( current_address, pHwData->CurrentMacAddress, ETH_LENGTH_OF_ADDRESS ); +} + +void hal_set_ethernet_address( phw_data_t pHwData, PUCHAR current_address ) +{ + u32 ltmp[2]; + + if( pHwData->SurpriseRemove ) return; + + memcpy( pHwData->CurrentMacAddress, current_address, ETH_LENGTH_OF_ADDRESS ); + + ltmp[0]= cpu_to_le32( *(PULONG)pHwData->CurrentMacAddress ); + ltmp[1]= cpu_to_le32( *(PULONG)(pHwData->CurrentMacAddress + 4) ) & 0xffff; + + Wb35Reg_BurstWrite( pHwData, 0x03e8, ltmp, 2, AUTO_INCREMENT ); +} + +void hal_get_permanent_address( phw_data_t pHwData, PUCHAR pethernet_address ) +{ + if( pHwData->SurpriseRemove ) return; + + memcpy( pethernet_address, pHwData->PermanentMacAddress, 6 ); +} + +u8 hal_init_hardware(phw_data_t pHwData, PWB32_ADAPTER Adapter) +{ + u16 SoftwareSet; + pHwData->Adapter = Adapter; + + // Initial the variable + pHwData->MaxReceiveLifeTime = DEFAULT_MSDU_LIFE_TIME; // Setting Rx maximum MSDU life time + pHwData->FragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD; // Setting default fragment threshold + + if (WbUsb_initial(pHwData)) { + pHwData->InitialResource = 1; + if( Wb35Reg_initial(pHwData)) { + pHwData->InitialResource = 2; + if (Wb35Tx_initial(pHwData)) { + pHwData->InitialResource = 3; + if (Wb35Rx_initial(pHwData)) { + pHwData->InitialResource = 4; + OS_TIMER_INITIAL( &pHwData->LEDTimer, hal_led_control, pHwData ); + OS_TIMER_SET( &pHwData->LEDTimer, 1000 ); // 20060623 + + // + // For restrict to vendor's hardware + // + SoftwareSet = hal_software_set( pHwData ); + + #ifdef Vendor2 + // Try to make sure the EEPROM contain + SoftwareSet >>= 8; + if( SoftwareSet != 0x82 ) + return FALSE; + #endif + + Wb35Rx_start( pHwData ); + Wb35Tx_EP2VM_start( pHwData ); + + return TRUE; + } + } + } + } + + pHwData->SurpriseRemove = 1; + return FALSE; +} + + +void hal_halt(phw_data_t pHwData, void *ppa_data) +{ + switch( pHwData->InitialResource ) + { + case 4: + case 3: OS_TIMER_CANCEL( &pHwData->LEDTimer, &cancel ); + OS_SLEEP(100000); // Wait for Timer DPC exit 940623.2 + Wb35Rx_destroy( pHwData ); // Release the Rx + case 2: Wb35Tx_destroy( pHwData ); // Release the Tx + case 1: Wb35Reg_destroy( pHwData ); // Release the Wb35 Regisster resources + WbUsb_destroy( pHwData );// Release the WbUsb + } +} + +//--------------------------------------------------------------------------------------------------- +void hal_set_rates(phw_data_t pHwData, PUCHAR pbss_rates, + u8 length, unsigned char basic_rate_set) +{ + PWB35REG pWb35Reg = &pHwData->Wb35Reg; + u32 tmp, tmp1; + u8 Rate[12]={ 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 }; + u8 SupportedRate[16]; + u8 i, j, k, Count1, Count2, Byte; + + if( pHwData->SurpriseRemove ) return; + + if (basic_rate_set) { + pWb35Reg->M28_MacControl &= ~0x000fff00; + tmp1 = 0x00000100; + } else { + pWb35Reg->M28_MacControl &= ~0xfff00000; + tmp1 = 0x00100000; + } + + tmp = 0; + for (i=0; i<length; i++) { + Byte = pbss_rates[i] & 0x7f; + for (j=0; j<12; j++) { + if( Byte == Rate[j] ) + break; + } + + if (j < 12) + tmp |= (tmp1<<j); + } + + pWb35Reg->M28_MacControl |= tmp; + Wb35Reg_Write( pHwData, 0x0828, pWb35Reg->M28_MacControl ); + + // 930206.2.c M78 setting + j = k = Count1 = Count2 = 0; + memset( SupportedRate, 0, 16 ); + tmp = 0x00100000; + tmp1 = 0x00000100; + for (i=0; i<12; i++) { // Get the supported rate + if (tmp & pWb35Reg->M28_MacControl) { + SupportedRate[j] = Rate[i]; + + if (tmp1 & pWb35Reg->M28_MacControl) + SupportedRate[j] |= 0x80; + + if (k) + Count2++; + else + Count1++; + + j++; + } + + if (i==4 && k==0) { + if( !(pWb35Reg->M28_MacControl & 0x000ff000) ) // if basic rate in 11g domain) + { + k = 1; + j = 8; + } + } + + tmp <<= 1; + tmp1 <<= 1; + } + + // Fill data into support rate until buffer full + //---20060926 add by anson's endian + for (i=0; i<4; i++) + *(PULONG)(SupportedRate+(i<<2)) = cpu_to_le32( *(PULONG)(SupportedRate+(i<<2)) ); + //--- end 20060926 add by anson's endian + Wb35Reg_BurstWrite( pHwData,0x087c, (PULONG)SupportedRate, 4, AUTO_INCREMENT ); + pWb35Reg->M7C_MacControl = ((PULONG)SupportedRate)[0]; + pWb35Reg->M80_MacControl = ((PULONG)SupportedRate)[1]; + pWb35Reg->M84_MacControl = ((PULONG)SupportedRate)[2]; + pWb35Reg->M88_MacControl = ((PULONG)SupportedRate)[3]; + + // Fill length + tmp = Count1<<28 | Count2<<24; + pWb35Reg->M78_ERPInformation &= ~0xff000000; + pWb35Reg->M78_ERPInformation |= tmp; + Wb35Reg_Write( pHwData, 0x0878, pWb35Reg->M78_ERPInformation ); +} + + +//--------------------------------------------------------------------------------------------------- +void hal_set_beacon_period( phw_data_t pHwData, u16 beacon_period ) +{ + u32 tmp; + + if( pHwData->SurpriseRemove ) return; + + pHwData->BeaconPeriod = beacon_period; + tmp = pHwData->BeaconPeriod << 16; + tmp |= pHwData->ProbeDelay; + Wb35Reg_Write( pHwData, 0x0848, tmp ); +} + + +void hal_set_current_channel_ex( phw_data_t pHwData, ChanInfo channel ) +{ + PWB35REG pWb35Reg = &pHwData->Wb35Reg; + + if( pHwData->SurpriseRemove ) + return; + + printk("Going to channel: %d/%d\n", channel.band, channel.ChanNo); + + RFSynthesizer_SwitchingChannel( pHwData, channel );// Switch channel + pHwData->Channel = channel.ChanNo; + pHwData->band = channel.band; + #ifdef _PE_STATE_DUMP_ + WBDEBUG(("Set channel is %d, band =%d\n", pHwData->Channel, pHwData->band)); + #endif + pWb35Reg->M28_MacControl &= ~0xff; // Clean channel information field + pWb35Reg->M28_MacControl |= channel.ChanNo; + Wb35Reg_WriteWithCallbackValue( pHwData, 0x0828, pWb35Reg->M28_MacControl, + (PCHAR)&channel, sizeof(ChanInfo)); +} +//--------------------------------------------------------------------------------------------------- +void hal_set_current_channel( phw_data_t pHwData, ChanInfo channel ) +{ + hal_set_current_channel_ex( pHwData, channel ); +} +//--------------------------------------------------------------------------------------------------- +void hal_get_current_channel( phw_data_t pHwData, ChanInfo *channel ) +{ + channel->ChanNo = pHwData->Channel; + channel->band = pHwData->band; +} +//--------------------------------------------------------------------------------------------------- +void hal_set_accept_broadcast( phw_data_t pHwData, u8 enable ) +{ + PWB35REG pWb35Reg = &pHwData->Wb35Reg; + + if( pHwData->SurpriseRemove ) return; + + pWb35Reg->M00_MacControl &= ~0x02000000;//The HW value + + if (enable) + pWb35Reg->M00_MacControl |= 0x02000000;//The HW value + + Wb35Reg_Write( pHwData, 0x0800, pWb35Reg->M00_MacControl ); +} + +//for wep key error detection, we need to accept broadcast packets to be received temporary. +void hal_set_accept_promiscuous( phw_data_t pHwData, u8 enable) +{ + PWB35REG pWb35Reg = &pHwData->Wb35Reg; + + if (pHwData->SurpriseRemove) return; + if (enable) { + pWb35Reg->M00_MacControl |= 0x00400000; + Wb35Reg_Write( pHwData, 0x0800, pWb35Reg->M00_MacControl ); + } else { + pWb35Reg->M00_MacControl&=~0x00400000; + Wb35Reg_Write( pHwData, 0x0800, pWb35Reg->M00_MacControl ); + } +} + +void hal_set_accept_multicast( phw_data_t pHwData, u8 enable ) +{ + PWB35REG pWb35Reg = &pHwData->Wb35Reg; + + if( pHwData->SurpriseRemove ) return; + + pWb35Reg->M00_MacControl &= ~0x01000000;//The HW value + if (enable) pWb35Reg->M00_MacControl |= 0x01000000;//The HW value + Wb35Reg_Write( pHwData, 0x0800, pWb35Reg->M00_MacControl ); +} + +void hal_set_accept_beacon( phw_data_t pHwData, u8 enable ) +{ + PWB35REG pWb35Reg = &pHwData->Wb35Reg; + + if( pHwData->SurpriseRemove ) return; + + // 20040108 debug + if( !enable )//Due to SME and MLME are not suitable for 35 + return; + + pWb35Reg->M00_MacControl &= ~0x04000000;//The HW value + if( enable ) + pWb35Reg->M00_MacControl |= 0x04000000;//The HW value + + Wb35Reg_Write( pHwData, 0x0800, pWb35Reg->M00_MacControl ); +} +//--------------------------------------------------------------------------------------------------- +void hal_set_multicast_address( phw_data_t pHwData, PUCHAR address, u8 number ) +{ + PWB35REG pWb35Reg = &pHwData->Wb35Reg; + u8 Byte, Bit; + + if( pHwData->SurpriseRemove ) return; + + //Erases and refills the card multicast registers. Used when an address + // has been deleted and all bits must be recomputed. + pWb35Reg->M04_MulticastAddress1 = 0; + pWb35Reg->M08_MulticastAddress2 = 0; + + while( number ) + { + number--; + CardGetMulticastBit( (address+(number*ETH_LENGTH_OF_ADDRESS)), &Byte, &Bit); + pWb35Reg->Multicast[Byte] |= Bit; + } + + // Updating register + Wb35Reg_BurstWrite( pHwData, 0x0804, (PULONG)pWb35Reg->Multicast, 2, AUTO_INCREMENT ); +} +//--------------------------------------------------------------------------------------------------- +u8 hal_get_accept_beacon( phw_data_t pHwData ) +{ + PWB35REG pWb35Reg = &pHwData->Wb35Reg; + + if( pHwData->SurpriseRemove ) return 0; + + if( pWb35Reg->M00_MacControl & 0x04000000 ) + return 1; + else + return 0; +} + +unsigned char hal_reset_hardware( phw_data_t pHwData, void* ppa ) +{ + // Not implement yet + return TRUE; +} + +void hal_stop( phw_data_t pHwData ) +{ + PWB35REG pWb35Reg = &pHwData->Wb35Reg; + + pHwData->Wb35Rx.rx_halt = 1; + Wb35Rx_stop( pHwData ); + + pHwData->Wb35Tx.tx_halt = 1; + Wb35Tx_stop( pHwData ); + + pWb35Reg->D00_DmaControl &= ~0xc0000000;//Tx Off, Rx Off + Wb35Reg_Write( pHwData, 0x0400, pWb35Reg->D00_DmaControl ); + + WbUsb_Stop( pHwData ); // 20051230 Add.4 +} + +unsigned char hal_idle(phw_data_t pHwData) +{ + PWB35REG pWb35Reg = &pHwData->Wb35Reg; + PWBUSB pWbUsb = &pHwData->WbUsb; + + if( !pHwData->SurpriseRemove && ( pWbUsb->DetectCount || pWb35Reg->EP0vm_state!=VM_STOP ) ) + return FALSE; + + return TRUE; +} +//--------------------------------------------------------------------------------------------------- +void hal_set_cwmin( phw_data_t pHwData, u8 cwin_min ) +{ + PWB35REG pWb35Reg = &pHwData->Wb35Reg; + + if( pHwData->SurpriseRemove ) return; + + pHwData->cwmin = cwin_min; + pWb35Reg->M2C_MacControl &= ~0x7c00; //bit 10 ~ 14 + pWb35Reg->M2C_MacControl |= (pHwData->cwmin<<10); + Wb35Reg_Write( pHwData, 0x082c, pWb35Reg->M2C_MacControl ); +} + +s32 hal_get_rssi( phw_data_t pHwData, u32 *HalRssiArry, u8 Count ) +{ + PWB35REG pWb35Reg = &pHwData->Wb35Reg; + R01_DESCRIPTOR r01; + s32 ltmp = 0, tmp; + u8 i; + + if( pHwData->SurpriseRemove ) return -200; + if( Count > MAX_ACC_RSSI_COUNT ) // Because the TS may use this funtion + Count = MAX_ACC_RSSI_COUNT; + + // RSSI = C1 + C2 * (agc_state[7:0] + offset_map(lna_state[1:0])) + // C1 = -195, C2 = 0.66 = 85/128 + for (i=0; i<Count; i++) + { + r01.value = HalRssiArry[i]; + tmp = ((( r01.R01_AGC_state + pWb35Reg->LNAValue[r01.R01_LNA_state]) * 85 ) >>7 ) - 195; + ltmp += tmp; + } + ltmp /= Count; + if( pHwData->phy_type == RF_AIROHA_2230 ) ltmp -= 5; // 10; + if( pHwData->phy_type == RF_AIROHA_2230S ) ltmp -= 5; // 10; 20060420 Add this + + //if( ltmp < -200 ) ltmp = -200; + if( ltmp < -110 ) ltmp = -110;// 1.0.24.0 For NJRC + + return ltmp; +} +//---------------------------------------------------------------------------------------------------- +s32 hal_get_rssi_bss( phw_data_t pHwData, u16 idx, u8 Count ) +{ + PWB35REG pWb35Reg = &pHwData->Wb35Reg; + R01_DESCRIPTOR r01; + s32 ltmp = 0, tmp; + u8 i, j; + PADAPTER Adapter = pHwData->Adapter; +// u32 *HalRssiArry = psBSS(idx)->HalRssi; + + if( pHwData->SurpriseRemove ) return -200; + if( Count > MAX_ACC_RSSI_COUNT ) // Because the TS may use this funtion + Count = MAX_ACC_RSSI_COUNT; + + // RSSI = C1 + C2 * (agc_state[7:0] + offset_map(lna_state[1:0])) + // C1 = -195, C2 = 0.66 = 85/128 +#if 0 + for (i=0; i<Count; i++) + { + r01.value = HalRssiArry[i]; + tmp = ((( r01.R01_AGC_state + pWb35Reg->LNAValue[r01.R01_LNA_state]) * 85 ) >>7 ) - 195; + ltmp += tmp; + } +#else + if (psBSS(idx)->HalRssiIndex == 0) + psBSS(idx)->HalRssiIndex = MAX_ACC_RSSI_COUNT; + j = (u8)psBSS(idx)->HalRssiIndex-1; + + for (i=0; i<Count; i++) + { + r01.value = psBSS(idx)->HalRssi[j]; + tmp = ((( r01.R01_AGC_state + pWb35Reg->LNAValue[r01.R01_LNA_state]) * 85 ) >>7 ) - 195; + ltmp += tmp; + if (j == 0) + { + j = MAX_ACC_RSSI_COUNT; + } + j--; + } +#endif + ltmp /= Count; + if( pHwData->phy_type == RF_AIROHA_2230 ) ltmp -= 5; // 10; + if( pHwData->phy_type == RF_AIROHA_2230S ) ltmp -= 5; // 10; 20060420 Add this + + //if( ltmp < -200 ) ltmp = -200; + if( ltmp < -110 ) ltmp = -110;// 1.0.24.0 For NJRC + + return ltmp; +} + +//--------------------------------------------------------------------------- +void hal_led_control_1a( phw_data_t pHwData ) +{ + hal_led_control( NULL, pHwData, NULL, NULL ); +} + +void hal_led_control( void* S1, phw_data_t pHwData, void* S3, void* S4 ) +{ + PADAPTER Adapter = pHwData->Adapter; + PWB35REG pWb35Reg = &pHwData->Wb35Reg; + u32 LEDSet = (pHwData->SoftwareSet & HAL_LED_SET_MASK) >> HAL_LED_SET_SHIFT; + u8 LEDgray[20] = { 0,3,4,6,8,10,11,12,13,14,15,14,13,12,11,10,8,6,4,2 }; + u8 LEDgray2[30] = { 7,8,9,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0,0,0,0,0,15,14,13,12,11,10,9,8 }; + u32 TimeInterval = 500, ltmp, ltmp2; + ltmp=0; + + if( pHwData->SurpriseRemove ) return; + + if( pHwData->LED_control ) { + ltmp2 = pHwData->LED_control & 0xff; + if( ltmp2 == 5 ) // 5 is WPS mode + { + TimeInterval = 100; + ltmp2 = (pHwData->LED_control>>8) & 0xff; + switch( ltmp2 ) + { + case 1: // [0.2 On][0.1 Off]... + pHwData->LED_Blinking %= 3; + ltmp = 0x1010; // Led 1 & 0 Green and Red + if( pHwData->LED_Blinking == 2 ) // Turn off + ltmp = 0; + break; + case 2: // [0.1 On][0.1 Off]... + pHwData->LED_Blinking %= 2; + ltmp = 0x0010; // Led 0 red color + if( pHwData->LED_Blinking ) // Turn off + ltmp = 0; + break; + case 3: // [0.1 On][0.1 Off][0.1 On][0.1 Off][0.1 On][0.1 Off][0.1 On][0.1 Off][0.1 On][0.1 Off][0.5 Off]... + pHwData->LED_Blinking %= 15; + ltmp = 0x0010; // Led 0 red color + if( (pHwData->LED_Blinking >= 9) || (pHwData->LED_Blinking%2) ) // Turn off 0.6 sec + ltmp = 0; + break; + case 4: // [300 On][ off ] + ltmp = 0x1000; // Led 1 Green color + if( pHwData->LED_Blinking >= 3000 ) + ltmp = 0; // led maybe on after 300sec * 32bit counter overlap. + break; + } + pHwData->LED_Blinking++; + + pWb35Reg->U1BC_LEDConfigure = ltmp; + if( LEDSet != 7 ) // Only 111 mode has 2 LEDs on PCB. + { + pWb35Reg->U1BC_LEDConfigure |= (ltmp &0xff)<<8; // Copy LED result to each LED control register + pWb35Reg->U1BC_LEDConfigure |= (ltmp &0xff00)>>8; + } + Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); + } + } + else if( pHwData->CurrentRadioSw || pHwData->CurrentRadioHw ) // If radio off + { + if( pWb35Reg->U1BC_LEDConfigure & 0x1010 ) + { + pWb35Reg->U1BC_LEDConfigure &= ~0x1010; + Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); + } + } + else + { + switch( LEDSet ) + { + case 4: // [100] Only 1 Led be placed on PCB and use pin 21 of IC. Use LED_0 for showing + if( !pHwData->LED_LinkOn ) // Blink only if not Link On + { + // Blinking if scanning is on progress + if( pHwData->LED_Scanning ) + { + if( pHwData->LED_Blinking == 0 ) + { + pWb35Reg->U1BC_LEDConfigure |= 0x10; + Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_0 On + pHwData->LED_Blinking = 1; + TimeInterval = 300; + } + else + { + pWb35Reg->U1BC_LEDConfigure &= ~0x10; + Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_0 Off + pHwData->LED_Blinking = 0; + TimeInterval = 300; + } + } + else + { + //Turn Off LED_0 + if( pWb35Reg->U1BC_LEDConfigure & 0x10 ) + { + pWb35Reg->U1BC_LEDConfigure &= ~0x10; + Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_0 Off + } + } + } + else + { + // Turn On LED_0 + if( (pWb35Reg->U1BC_LEDConfigure & 0x10) == 0 ) + { + pWb35Reg->U1BC_LEDConfigure |= 0x10; + Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_0 Off + } + } + break; + + case 6: // [110] Only 1 Led be placed on PCB and use pin 21 of IC. Use LED_0 for showing + if( !pHwData->LED_LinkOn ) // Blink only if not Link On + { + // Blinking if scanning is on progress + if( pHwData->LED_Scanning ) + { + if( pHwData->LED_Blinking == 0 ) + { + pWb35Reg->U1BC_LEDConfigure &= ~0xf; + pWb35Reg->U1BC_LEDConfigure |= 0x10; + Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_0 On + pHwData->LED_Blinking = 1; + TimeInterval = 300; + } + else + { + pWb35Reg->U1BC_LEDConfigure &= ~0x1f; + Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_0 Off + pHwData->LED_Blinking = 0; + TimeInterval = 300; + } + } + else + { + // 20060901 Gray blinking if in disconnect state and not scanning + ltmp = pWb35Reg->U1BC_LEDConfigure; + pWb35Reg->U1BC_LEDConfigure &= ~0x1f; + if( LEDgray2[(pHwData->LED_Blinking%30)] ) + { + pWb35Reg->U1BC_LEDConfigure |= 0x10; + pWb35Reg->U1BC_LEDConfigure |= LEDgray2[ (pHwData->LED_Blinking%30) ]; + } + pHwData->LED_Blinking++; + if( pWb35Reg->U1BC_LEDConfigure != ltmp ) + Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_0 Off + TimeInterval = 100; + } + } + else + { + // Turn On LED_0 + if( (pWb35Reg->U1BC_LEDConfigure & 0x10) == 0 ) + { + pWb35Reg->U1BC_LEDConfigure |= 0x10; + Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_0 Off + } + } + break; + + case 5: // [101] Only 1 Led be placed on PCB and use LED_1 for showing + if( !pHwData->LED_LinkOn ) // Blink only if not Link On + { + // Blinking if scanning is on progress + if( pHwData->LED_Scanning ) + { + if( pHwData->LED_Blinking == 0 ) + { + pWb35Reg->U1BC_LEDConfigure |= 0x1000; + Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_1 On + pHwData->LED_Blinking = 1; + TimeInterval = 300; + } + else + { + pWb35Reg->U1BC_LEDConfigure &= ~0x1000; + Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_1 Off + pHwData->LED_Blinking = 0; + TimeInterval = 300; + } + } + else + { + //Turn Off LED_1 + if( pWb35Reg->U1BC_LEDConfigure & 0x1000 ) + { + pWb35Reg->U1BC_LEDConfigure &= ~0x1000; + Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_1 Off + } + } + } + else + { + // Is transmitting/receiving ?? + if( (OS_CURRENT_RX_BYTE( Adapter ) != pHwData->RxByteCountLast ) || + (OS_CURRENT_TX_BYTE( Adapter ) != pHwData->TxByteCountLast ) ) + { + if( (pWb35Reg->U1BC_LEDConfigure & 0x3000) != 0x3000 ) + { + pWb35Reg->U1BC_LEDConfigure |= 0x3000; + Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_1 On + } + + // Update variable + pHwData->RxByteCountLast = OS_CURRENT_RX_BYTE( Adapter ); + pHwData->TxByteCountLast = OS_CURRENT_TX_BYTE( Adapter ); + TimeInterval = 200; + } + else + { + // Turn On LED_1 and blinking if transmitting/receiving + if( (pWb35Reg->U1BC_LEDConfigure & 0x3000) != 0x1000 ) + { + pWb35Reg->U1BC_LEDConfigure &= ~0x3000; + pWb35Reg->U1BC_LEDConfigure |= 0x1000; + Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_1 On + } + } + } + break; + + default: // Default setting. 2 LED be placed on PCB. LED_0: Link On LED_1 Active + if( (pWb35Reg->U1BC_LEDConfigure & 0x3000) != 0x3000 ) + { + pWb35Reg->U1BC_LEDConfigure |= 0x3000;// LED_1 is always on and event enable + Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); + } + + if( pHwData->LED_Blinking ) + { + // Gray blinking + pWb35Reg->U1BC_LEDConfigure &= ~0x0f; + pWb35Reg->U1BC_LEDConfigure |= 0x10; + pWb35Reg->U1BC_LEDConfigure |= LEDgray[ (pHwData->LED_Blinking-1)%20 ]; + Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); + + pHwData->LED_Blinking += 2; + if( pHwData->LED_Blinking < 40 ) + TimeInterval = 100; + else + { + pHwData->LED_Blinking = 0; // Stop blinking + pWb35Reg->U1BC_LEDConfigure &= ~0x0f; + Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); + } + break; + } + + if( pHwData->LED_LinkOn ) + { + if( !(pWb35Reg->U1BC_LEDConfigure & 0x10) ) // Check the LED_0 + { + //Try to turn ON LED_0 after gray blinking + pWb35Reg->U1BC_LEDConfigure |= 0x10; + pHwData->LED_Blinking = 1; //Start blinking + TimeInterval = 50; + } + } + else + { + if( pWb35Reg->U1BC_LEDConfigure & 0x10 ) // Check the LED_0 + { + pWb35Reg->U1BC_LEDConfigure &= ~0x10; + Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); + } + } + break; + } + + //20060828.1 Active send null packet to avoid AP disconnect + if( pHwData->LED_LinkOn ) + { + pHwData->NullPacketCount += TimeInterval; + if( pHwData->NullPacketCount >= DEFAULT_NULL_PACKET_COUNT ) + { + pHwData->NullPacketCount = 0; + } + } + } + + pHwData->time_count += TimeInterval; + Wb35Tx_CurrentTime( pHwData, pHwData->time_count ); // 20060928 add + OS_TIMER_SET( &pHwData->LEDTimer, TimeInterval ); // 20060623.1 +} + + +void hal_set_phy_type( phw_data_t pHwData, u8 PhyType ) +{ + pHwData->phy_type = PhyType; +} + +void hal_get_phy_type( phw_data_t pHwData, u8 *PhyType ) +{ + *PhyType = pHwData->phy_type; +} + +void hal_reset_counter( phw_data_t pHwData ) +{ + pHwData->dto_tx_retry_count = 0; + pHwData->dto_tx_frag_count = 0; + memset( pHwData->tx_retry_count, 0, 8); +} + +void hal_set_radio_mode( phw_data_t pHwData, unsigned char radio_off) +{ + PWB35REG pWb35Reg = &pHwData->Wb35Reg; + + if( pHwData->SurpriseRemove ) return; + + if (radio_off) //disable Baseband receive off + { + pHwData->CurrentRadioSw = 1; // off + pWb35Reg->M24_MacControl &= 0xffffffbf; + } + else + { + pHwData->CurrentRadioSw = 0; // on + pWb35Reg->M24_MacControl |= 0x00000040; + } + Wb35Reg_Write( pHwData, 0x0824, pWb35Reg->M24_MacControl ); +} + +u8 hal_get_antenna_number( phw_data_t pHwData ) +{ + PWB35REG pWb35Reg = &pHwData->Wb35Reg; + + if ((pWb35Reg->BB2C & BIT(11)) == 0) + return 0; + else + return 1; +} + +void hal_set_antenna_number( phw_data_t pHwData, u8 number ) +{ + + PWB35REG pWb35Reg = &pHwData->Wb35Reg; + + if (number == 1) { + pWb35Reg->BB2C |= BIT(11); + } else { + pWb35Reg->BB2C &= ~BIT(11); + } + Wb35Reg_Write( pHwData, 0x102c, pWb35Reg->BB2C ); +#ifdef _PE_STATE_DUMP_ + WBDEBUG(("Current antenna number : %d\n", number)); +#endif +} + +//---------------------------------------------------------------------------------------------------- +//0 : radio on; 1: radio off +u8 hal_get_hw_radio_off( phw_data_t pHwData ) +{ + PWB35REG pWb35Reg = &pHwData->Wb35Reg; + + if( pHwData->SurpriseRemove ) return 1; + + //read the bit16 of register U1B0 + Wb35Reg_Read( pHwData, 0x3b0, &pWb35Reg->U1B0 ); + if ((pWb35Reg->U1B0 & 0x00010000)) { + pHwData->CurrentRadioHw = 1; + return 1; + } else { + pHwData->CurrentRadioHw = 0; + return 0; + } +} + +unsigned char hal_get_dxx_reg( phw_data_t pHwData, u16 number, PULONG pValue ) +{ + if( number < 0x1000 ) + number += 0x1000; + return Wb35Reg_ReadSync( pHwData, number, pValue ); +} + +unsigned char hal_set_dxx_reg( phw_data_t pHwData, u16 number, u32 value ) +{ + unsigned char ret; + + if( number < 0x1000 ) + number += 0x1000; + ret = Wb35Reg_WriteSync( pHwData, number, value ); + return ret; +} + +void hal_scan_status_indicate(phw_data_t pHwData, unsigned char IsOnProgress) +{ + if( pHwData->SurpriseRemove ) return; + pHwData->LED_Scanning = IsOnProgress ? 1 : 0; +} + +void hal_system_power_change(phw_data_t pHwData, u32 PowerState) +{ + if( PowerState != 0 ) + { + pHwData->SurpriseRemove = 1; + if( pHwData->WbUsb.IsUsb20 ) + hal_stop( pHwData ); + } + else + { + if( !pHwData->WbUsb.IsUsb20 ) + hal_stop( pHwData ); + } +} + +void hal_surprise_remove( phw_data_t pHwData ) +{ + PADAPTER Adapter = pHwData->Adapter; + if (OS_ATOMIC_INC( Adapter, &pHwData->SurpriseRemoveCount ) == 1) { + #ifdef _PE_STATE_DUMP_ + WBDEBUG(("Calling hal_surprise_remove\n")); + #endif + OS_STOP( Adapter ); + } +} + +void hal_rate_change( phw_data_t pHwData ) // Notify the HAL rate is changing 20060613.1 +{ + PADAPTER Adapter = pHwData->Adapter; + u8 rate = CURRENT_TX_RATE; + + BBProcessor_RateChanging( pHwData, rate ); +} + +void hal_set_rf_power(phw_data_t pHwData, u8 PowerIndex) +{ + RFSynthesizer_SetPowerIndex( pHwData, PowerIndex ); +} + +unsigned char hal_set_LED(phw_data_t pHwData, u32 Mode) // 20061108 for WPS led control +{ + pHwData->LED_Blinking = 0; + pHwData->LED_control = Mode; + OS_TIMER_SET( &pHwData->LEDTimer, 10 ); // 20060623 + return TRUE; +} + diff --git a/drivers/staging/winbond/wbhal_f.h b/drivers/staging/winbond/wbhal_f.h new file mode 100644 index 000000000000..fe25f97af724 --- /dev/null +++ b/drivers/staging/winbond/wbhal_f.h @@ -0,0 +1,122 @@ +//===================================================================== +// Device related include +//===================================================================== +#ifdef WB_LINUX + #include "linux/wbusb_f.h" + #include "linux/wb35reg_f.h" + #include "linux/wb35tx_f.h" + #include "linux/wb35rx_f.h" +#else + #include "wbusb_f.h" + #include "wb35reg_f.h" + #include "wb35tx_f.h" + #include "wb35rx_f.h" +#endif + +//==================================================================================== +// Function declaration +//==================================================================================== +void hal_remove_mapping_key( phw_data_t pHwData, PUCHAR pmac_addr ); +void hal_remove_default_key( phw_data_t pHwData, u32 index ); +unsigned char hal_set_mapping_key( phw_data_t Adapter, PUCHAR pmac_addr, u8 null_key, u8 wep_on, PUCHAR ptx_tsc, PUCHAR prx_tsc, u8 key_type, u8 key_len, PUCHAR pkey_data ); +unsigned char hal_set_default_key( phw_data_t Adapter, u8 index, u8 null_key, u8 wep_on, PUCHAR ptx_tsc, PUCHAR prx_tsc, u8 key_type, u8 key_len, PUCHAR pkey_data ); +void hal_clear_all_default_key( phw_data_t pHwData ); +void hal_clear_all_group_key( phw_data_t pHwData ); +void hal_clear_all_mapping_key( phw_data_t pHwData ); +void hal_clear_all_key( phw_data_t pHwData ); +void hal_get_ethernet_address( phw_data_t pHwData, PUCHAR current_address ); +void hal_set_ethernet_address( phw_data_t pHwData, PUCHAR current_address ); +void hal_get_permanent_address( phw_data_t pHwData, PUCHAR pethernet_address ); +unsigned char hal_init_hardware( phw_data_t pHwData, PADAPTER Adapter ); +void hal_set_power_save_mode( phw_data_t pHwData, unsigned char power_save, unsigned char wakeup, unsigned char dtim ); +void hal_get_power_save_mode( phw_data_t pHwData, PBOOLEAN pin_pwr_save ); +void hal_set_slot_time( phw_data_t pHwData, u8 type ); +#define hal_set_atim_window( _A, _ATM ) +void hal_set_rates( phw_data_t pHwData, PUCHAR pbss_rates, u8 length, unsigned char basic_rate_set ); +#define hal_set_basic_rates( _A, _R, _L ) hal_set_rates( _A, _R, _L, TRUE ) +#define hal_set_op_rates( _A, _R, _L ) hal_set_rates( _A, _R, _L, FALSE ) +void hal_start_bss( phw_data_t pHwData, u8 mac_op_mode ); +void hal_join_request( phw_data_t pHwData, u8 bss_type ); // 0:BSS STA 1:IBSS STA// +void hal_stop_sync_bss( phw_data_t pHwData ); +void hal_resume_sync_bss( phw_data_t pHwData); +void hal_set_aid( phw_data_t pHwData, u16 aid ); +void hal_set_bssid( phw_data_t pHwData, PUCHAR pbssid ); +void hal_get_bssid( phw_data_t pHwData, PUCHAR pbssid ); +void hal_set_beacon_period( phw_data_t pHwData, u16 beacon_period ); +void hal_set_listen_interval( phw_data_t pHwData, u16 listen_interval ); +void hal_set_cap_info( phw_data_t pHwData, u16 capability_info ); +void hal_set_ssid( phw_data_t pHwData, PUCHAR pssid, u8 ssid_len ); +void hal_set_current_channel( phw_data_t pHwData, ChanInfo channel ); +void hal_set_current_channel_ex( phw_data_t pHwData, ChanInfo channel ); +void hal_get_current_channel( phw_data_t pHwData, ChanInfo *channel ); +void hal_set_accept_broadcast( phw_data_t pHwData, u8 enable ); +void hal_set_accept_multicast( phw_data_t pHwData, u8 enable ); +void hal_set_accept_beacon( phw_data_t pHwData, u8 enable ); +void hal_set_multicast_address( phw_data_t pHwData, PUCHAR address, u8 number ); +u8 hal_get_accept_beacon( phw_data_t pHwData ); +void hal_stop( phw_data_t pHwData ); +void hal_halt( phw_data_t pHwData, void *ppa_data ); +void hal_start_tx0( phw_data_t pHwData ); +void hal_set_phy_type( phw_data_t pHwData, u8 PhyType ); +void hal_get_phy_type( phw_data_t pHwData, u8 *PhyType ); +unsigned char hal_reset_hardware( phw_data_t pHwData, void* ppa ); +void hal_set_cwmin( phw_data_t pHwData, u8 cwin_min ); +#define hal_get_cwmin( _A ) ( (_A)->cwmin ) +void hal_set_cwmax( phw_data_t pHwData, u16 cwin_max ); +#define hal_get_cwmax( _A ) ( (_A)->cwmax ) +void hal_set_rsn_wpa( phw_data_t pHwData, u32 * RSN_IE_Bitmap , u32 * RSN_OUI_type , unsigned char bDesiredAuthMode); +//s32 hal_get_rssi( phw_data_t pHwData, u32 HalRssi ); +s32 hal_get_rssi( phw_data_t pHwData, u32 *HalRssiArry, u8 Count ); +s32 hal_get_rssi_bss( phw_data_t pHwData, u16 idx, u8 Count ); +void hal_set_connect_info( phw_data_t pHwData, unsigned char boConnect ); +u8 hal_get_est_sq3( phw_data_t pHwData, u8 Count ); +void hal_led_control_1a( phw_data_t pHwData ); +void hal_led_control( void* S1, phw_data_t pHwData, void* S3, void* S4 ); +void hal_set_rf_power( phw_data_t pHwData, u8 PowerIndex ); // 20060621 Modify +void hal_reset_counter( phw_data_t pHwData ); +void hal_set_radio_mode( phw_data_t pHwData, unsigned char boValue); +void hal_descriptor_indicate( phw_data_t pHwData, PDESCRIPTOR pDes ); +u8 hal_get_antenna_number( phw_data_t pHwData ); +void hal_set_antenna_number( phw_data_t pHwData, u8 number ); +u32 hal_get_bss_pk_cnt( phw_data_t pHwData ); +#define hal_get_region_from_EEPROM( _A ) ( (_A)->Wb35Reg.EEPROMRegion ) +void hal_set_accept_promiscuous ( phw_data_t pHwData, u8 enable); +#define hal_get_tx_buffer( _A, _B ) Wb35Tx_get_tx_buffer( _A, _B ) +u8 hal_get_hw_radio_off ( phw_data_t pHwData ); +#define hal_software_set( _A ) (_A->SoftwareSet) +#define hal_driver_init_OK( _A ) (_A->IsInitOK) +#define hal_rssi_boundary_high( _A ) (_A->RSSI_high) +#define hal_rssi_boundary_low( _A ) (_A->RSSI_low) +#define hal_scan_interval( _A ) (_A->Scan_Interval) +void hal_scan_status_indicate( phw_data_t pHwData, u8 status); // 0: complete, 1: in progress +void hal_system_power_change( phw_data_t pHwData, u32 PowerState ); // 20051230 -=D0 1=D1 .. +void hal_surprise_remove( phw_data_t pHwData ); + +#define PHY_DEBUG( msg, args... ) + + + +void hal_rate_change( phw_data_t pHwData ); // Notify the HAL rate is changing 20060613.1 +unsigned char hal_get_dxx_reg( phw_data_t pHwData, u16 number, PULONG pValue ); +unsigned char hal_set_dxx_reg( phw_data_t pHwData, u16 number, u32 value ); +#define hal_get_time_count( _P ) (_P->time_count/10) // return 100ms count +#define hal_detect_error( _P ) (_P->WbUsb.DetectCount) +unsigned char hal_set_LED( phw_data_t pHwData, u32 Mode ); // 20061108 for WPS led control + +//------------------------------------------------------------------------- +// The follow function is unused for IS89C35 +//------------------------------------------------------------------------- +#define hal_disable_interrupt(_A) +#define hal_enable_interrupt(_A) +#define hal_get_interrupt_type( _A) +#define hal_get_clear_interrupt(_A) +#define hal_ibss_disconnect(_A) hal_stop_sync_bss(_A) +#define hal_join_request_stop(_A) +unsigned char hal_idle( phw_data_t pHwData ); +#define pa_stall_execution( _A ) //OS_SLEEP( 1 ) +#define hw_get_cxx_reg( _A, _B, _C ) +#define hw_set_cxx_reg( _A, _B, _C ) +#define hw_get_dxx_reg( _A, _B, _C ) hal_get_dxx_reg( _A, _B, (PULONG)_C ) +#define hw_set_dxx_reg( _A, _B, _C ) hal_set_dxx_reg( _A, _B, (u32)_C ) + + diff --git a/drivers/staging/winbond/wbhal_s.h b/drivers/staging/winbond/wbhal_s.h new file mode 100644 index 000000000000..5b862ff357bd --- /dev/null +++ b/drivers/staging/winbond/wbhal_s.h @@ -0,0 +1,615 @@ +//[20040722 WK] +#define HAL_LED_SET_MASK 0x001c //20060901 Extend +#define HAL_LED_SET_SHIFT 2 + +//supported RF type +#define RF_MAXIM_2825 0 +#define RF_MAXIM_2827 1 +#define RF_MAXIM_2828 2 +#define RF_MAXIM_2829 3 +#define RF_MAXIM_V1 15 +#define RF_AIROHA_2230 16 +#define RF_AIROHA_7230 17 +#define RF_AIROHA_2230S 18 // 20060420 Add this +// #define RF_RFMD_2959 32 // 20060626 Remove all about RFMD +#define RF_WB_242 33 +#define RF_WB_242_1 34 // 20060619.5 Add +#define RF_DECIDE_BY_INF 255 + +//---------------------------------------------------------------- +// The follow define connect to upper layer +// User must modify for connection between HAL and upper layer +//---------------------------------------------------------------- + + + + +///////////////////////////////////////////////////////////////////////////////////////////////////// +//================================================================================================ +// Common define +//================================================================================================ +#define HAL_USB_MODE_BURST( _H ) (_H->SoftwareSet & 0x20 ) // Bit 5 20060901 Modify + +// Scan interval +#define SCAN_MAX_CHNL_TIME (50) + +// For TxL2 Frame typr recognise +#define FRAME_TYPE_802_3_DATA 0 +#define FRAME_TYPE_802_11_MANAGEMENT 1 +#define FRAME_TYPE_802_11_MANAGEMENT_CHALLENGE 2 +#define FRAME_TYPE_802_11_CONTROL 3 +#define FRAME_TYPE_802_11_DATA 4 +#define FRAME_TYPE_PROMISCUOUS 5 + +// The follow definition is used for convert the frame-------------------- +#define DOT_11_SEQUENCE_OFFSET 22 //Sequence control offset +#define DOT_3_TYPE_OFFSET 12 +#define DOT_11_MAC_HEADER_SIZE 24 +#define DOT_11_SNAP_SIZE 6 +#define DOT_11_TYPE_OFFSET 30 //The start offset of 802.11 Frame. Type encapsulatuin. +#define DEFAULT_SIFSTIME 10 +#define DEFAULT_FRAGMENT_THRESHOLD 2346 // No fragment +#define DEFAULT_MSDU_LIFE_TIME 0xffff + +#define LONG_PREAMBLE_PLUS_PLCPHEADER_TIME (144+48) +#define SHORT_PREAMBLE_PLUS_PLCPHEADER_TIME (72+24) +#define PREAMBLE_PLUS_SIGNAL_PLUS_SIGNALEXTENSION (16+4+6) +#define Tsym 4 + +// Frame Type of Bits (2, 3)--------------------------------------------- +#define MAC_TYPE_MANAGEMENT 0x00 +#define MAC_TYPE_CONTROL 0x04 +#define MAC_TYPE_DATA 0x08 +#define MASK_FRAGMENT_NUMBER 0x000F +#define SEQUENCE_NUMBER_SHIFT 4 + +#define HAL_WOL_TYPE_WAKEUP_FRAME 0x01 +#define HAL_WOL_TYPE_MAGIC_PACKET 0x02 + +// 20040106 ADDED +#define HAL_KEYTYPE_WEP40 0 +#define HAL_KEYTYPE_WEP104 1 +#define HAL_KEYTYPE_TKIP 2 // 128 bit key +#define HAL_KEYTYPE_AES_CCMP 3 // 128 bit key + +// For VM state +enum { + VM_STOP = 0, + VM_RUNNING, + VM_COMPLETED +}; + +// Be used for 802.11 mac header +typedef struct _MAC_FRAME_CONTROL { + u8 mac_frame_info; // this is a combination of the protovl version, type and subtype + u8 to_ds:1; + u8 from_ds:1; + u8 more_frag:1; + u8 retry:1; + u8 pwr_mgt:1; + u8 more_data:1; + u8 WEP:1; + u8 order:1; +} MAC_FRAME_CONTROL, *PMAC_FRAME_CONTROL; + +//----------------------------------------------------- +// Normal Key table format +//----------------------------------------------------- +// The order of KEY index is MAPPING_KEY_START_INDEX > GROUP_KEY_START_INDEX +#define MAX_KEY_TABLE 24 // 24 entry for storing key data +#define GROUP_KEY_START_INDEX 4 +#define MAPPING_KEY_START_INDEX 8 +typedef struct _KEY_TABLE +{ + u32 DW0_Valid:1; + u32 DW0_NullKey:1; + u32 DW0_Security_Mode:2;//0:WEP 40 bit 1:WEP 104 bit 2:TKIP 128 bit 3:CCMP 128 bit + u32 DW0_WEPON:1; + u32 DW0_RESERVED:11; + u32 DW0_Address1:16; + + u32 DW1_Address2; + + u32 DW2_RxSequenceCount1; + + u32 DW3_RxSequenceCount2:16; + u32 DW3_RESERVED:16; + + u32 DW4_TxSequenceCount1; + + u32 DW5_TxSequenceCount2:16; + u32 DW5_RESERVED:16; + +} KEY_TABLE, *PKEY_TABLE; + +//-------------------------------------------------------- +// Descriptor +//-------------------------------------------------------- +#define MAX_DESCRIPTOR_BUFFER_INDEX 8 // Have to multiple of 2 +//#define FLAG_ERROR_TX_MASK cpu_to_le32(0x000000bf) //20061009 marked by anson's endian +#define FLAG_ERROR_TX_MASK 0x000000bf //20061009 anson's endian +//#define FLAG_ERROR_RX_MASK 0x00000c3f +//#define FLAG_ERROR_RX_MASK cpu_to_le32(0x0000083f) //20061009 marked by anson's endian + //Don't care replay error, + //it is handled by S/W +#define FLAG_ERROR_RX_MASK 0x0000083f //20060926 anson's endian + +#define FLAG_BAND_RX_MASK 0x10000000 //Bit 28 + +typedef struct _R00_DESCRIPTOR +{ + union + { + u32 value; + #ifdef _BIG_ENDIAN_ //20060926 anson's endian + struct + { + u32 R00_packet_or_buffer_status:1; + u32 R00_packet_in_fifo:1; + u32 R00_RESERVED:2; + u32 R00_receive_byte_count:12; + u32 R00_receive_time_index:16; + }; + #else + struct + { + u32 R00_receive_time_index:16; + u32 R00_receive_byte_count:12; + u32 R00_RESERVED:2; + u32 R00_packet_in_fifo:1; + u32 R00_packet_or_buffer_status:1; + }; + #endif + }; +} R00_DESCRIPTOR, *PR00_DESCRIPTOR; + +typedef struct _T00_DESCRIPTOR +{ + union + { + u32 value; + #ifdef _BIG_ENDIAN_ //20061009 anson's endian + struct + { + u32 T00_first_mpdu:1; // for hardware use + u32 T00_last_mpdu:1; // for hardware use + u32 T00_IsLastMpdu:1;// 0: not 1:Yes for software used + u32 T00_IgnoreResult:1;// The same mechanism with T00 setting. 050111 Modify for TS + u32 T00_RESERVED_ID:2;//3 bit ID reserved + u32 T00_tx_packet_id:4;//930519.4.e 930810.3.c + u32 T00_RESERVED:4; + u32 T00_header_length:6; + u32 T00_frame_length:12; + }; + #else + struct + { + u32 T00_frame_length:12; + u32 T00_header_length:6; + u32 T00_RESERVED:4; + u32 T00_tx_packet_id:4;//930519.4.e 930810.3.c + u32 T00_RESERVED_ID:2;//3 bit ID reserved + u32 T00_IgnoreResult:1;// The same mechanism with T00 setting. 050111 Modify for TS + u32 T00_IsLastMpdu:1;// 0: not 1:Yes for software used + u32 T00_last_mpdu:1; // for hardware use + u32 T00_first_mpdu:1; // for hardware use + }; + #endif + }; +} T00_DESCRIPTOR, *PT00_DESCRIPTOR; + +typedef struct _R01_DESCRIPTOR +{ + union + { + u32 value; + #ifdef _BIG_ENDIAN_ //20060926 add by anson's endian + struct + { + u32 R01_RESERVED:3; + u32 R01_mod_type:1; + u32 R01_pre_type:1; + u32 R01_data_rate:3; + u32 R01_AGC_state:8; + u32 R01_LNA_state:2; + u32 R01_decryption_method:2; + u32 R01_mic_error:1; + u32 R01_replay:1; + u32 R01_broadcast_frame:1; + u32 R01_multicast_frame:1; + u32 R01_directed_frame:1; + u32 R01_receive_frame_antenna_selection:1; + u32 R01_frame_receive_during_atim_window:1; + u32 R01_protocol_version_error:1; + u32 R01_authentication_frame_icv_error:1; + u32 R01_null_key_to_authentication_frame:1; + u32 R01_icv_error:1; + u32 R01_crc_error:1; + }; + #else + struct + { + u32 R01_crc_error:1; + u32 R01_icv_error:1; + u32 R01_null_key_to_authentication_frame:1; + u32 R01_authentication_frame_icv_error:1; + u32 R01_protocol_version_error:1; + u32 R01_frame_receive_during_atim_window:1; + u32 R01_receive_frame_antenna_selection:1; + u32 R01_directed_frame:1; + u32 R01_multicast_frame:1; + u32 R01_broadcast_frame:1; + u32 R01_replay:1; + u32 R01_mic_error:1; + u32 R01_decryption_method:2; + u32 R01_LNA_state:2; + u32 R01_AGC_state:8; + u32 R01_data_rate:3; + u32 R01_pre_type:1; + u32 R01_mod_type:1; + u32 R01_RESERVED:3; + }; + #endif + }; +} R01_DESCRIPTOR, *PR01_DESCRIPTOR; + +typedef struct _T01_DESCRIPTOR +{ + union + { + u32 value; + #ifdef _BIG_ENDIAN_ //20061009 anson's endian + struct + { + u32 T01_rts_cts_duration:16; + u32 T01_fall_back_rate:3; + u32 T01_add_rts:1; + u32 T01_add_cts:1; + u32 T01_modulation_type:1; + u32 T01_plcp_header_length:1; + u32 T01_transmit_rate:3; + u32 T01_wep_id:2; + u32 T01_add_challenge_text:1; + u32 T01_inhibit_crc:1; + u32 T01_loop_back_wep_mode:1; + u32 T01_retry_abort_ebable:1; + }; + #else + struct + { + u32 T01_retry_abort_ebable:1; + u32 T01_loop_back_wep_mode:1; + u32 T01_inhibit_crc:1; + u32 T01_add_challenge_text:1; + u32 T01_wep_id:2; + u32 T01_transmit_rate:3; + u32 T01_plcp_header_length:1; + u32 T01_modulation_type:1; + u32 T01_add_cts:1; + u32 T01_add_rts:1; + u32 T01_fall_back_rate:3; + u32 T01_rts_cts_duration:16; + }; + #endif + }; +} T01_DESCRIPTOR, *PT01_DESCRIPTOR; + +typedef struct _T02_DESCRIPTOR +{ + union + { + u32 value; + #ifdef _BIG_ENDIAN_ //20061009 add by anson's endian + struct + { + u32 T02_IsLastMpdu:1;// The same mechanism with T00 setting + u32 T02_IgnoreResult:1;// The same mechanism with T00 setting. 050111 Modify for TS + u32 T02_RESERVED_ID:2;// The same mechanism with T00 setting + u32 T02_Tx_PktID:4; + u32 T02_MPDU_Cnt:4; + u32 T02_RTS_Cnt:4; + u32 T02_RESERVED:7; + u32 T02_transmit_complete:1; + u32 T02_transmit_abort_due_to_TBTT:1; + u32 T02_effective_transmission_rate:1; + u32 T02_transmit_without_encryption_due_to_wep_on_false:1; + u32 T02_discard_due_to_null_wep_key:1; + u32 T02_RESERVED_1:1; + u32 T02_out_of_MaxTxMSDULiftTime:1; + u32 T02_transmit_abort:1; + u32 T02_transmit_fail:1; + }; + #else + struct + { + u32 T02_transmit_fail:1; + u32 T02_transmit_abort:1; + u32 T02_out_of_MaxTxMSDULiftTime:1; + u32 T02_RESERVED_1:1; + u32 T02_discard_due_to_null_wep_key:1; + u32 T02_transmit_without_encryption_due_to_wep_on_false:1; + u32 T02_effective_transmission_rate:1; + u32 T02_transmit_abort_due_to_TBTT:1; + u32 T02_transmit_complete:1; + u32 T02_RESERVED:7; + u32 T02_RTS_Cnt:4; + u32 T02_MPDU_Cnt:4; + u32 T02_Tx_PktID:4; + u32 T02_RESERVED_ID:2;// The same mechanism with T00 setting + u32 T02_IgnoreResult:1;// The same mechanism with T00 setting. 050111 Modify for TS + u32 T02_IsLastMpdu:1;// The same mechanism with T00 setting + }; + #endif + }; +} T02_DESCRIPTOR, *PT02_DESCRIPTOR; + +typedef struct _DESCRIPTOR { // Skip length = 8 DWORD + // ID for descriptor ---, The field doesn't be cleard in the operation of Descriptor definition + u8 Descriptor_ID; + //----------------------The above region doesn't be cleared by DESCRIPTOR_RESET------ + u8 RESERVED[3]; + + u16 FragmentThreshold; + u8 InternalUsed;//Only can be used by operation of descriptor definition + u8 Type;// 0: 802.3 1:802.11 data frame 2:802.11 management frame + + u8 PreambleMode;// 0: short 1:long + u8 TxRate; + u8 FragmentCount; + u8 EapFix; // For speed up key install + + // For R00 and T00 ---------------------------------------------- + union + { + R00_DESCRIPTOR R00; + T00_DESCRIPTOR T00; + }; + + // For R01 and T01 ---------------------------------------------- + union + { + R01_DESCRIPTOR R01; + T01_DESCRIPTOR T01; + }; + + // For R02 and T02 ---------------------------------------------- + union + { + u32 R02; + T02_DESCRIPTOR T02; + }; + + // For R03 and T03 ---------------------------------------------- + // For software used + union + { + u32 R03; + u32 T03; + struct + { + u8 buffer_number; + u8 buffer_start_index; + u16 buffer_total_size; + }; + }; + + // For storing the buffer + u16 buffer_size[ MAX_DESCRIPTOR_BUFFER_INDEX ]; + void* buffer_address[ MAX_DESCRIPTOR_BUFFER_INDEX ];//931130.4.q + +} DESCRIPTOR, *PDESCRIPTOR; + + +#define DEFAULT_NULL_PACKET_COUNT 180000 //20060828.1 Add. 180 seconds + +#define MAX_TXVGA_EEPROM 9 //How many word(u16) of EEPROM will be used for TxVGA +#define MAX_RF_PARAMETER 32 + +typedef struct _TXVGA_FOR_50 { + u8 ChanNo; + u8 TxVgaValue; +} TXVGA_FOR_50; + + +//===================================================================== +// Device related include +//===================================================================== + +#include "linux/wbusb_s.h" +#include "linux/wb35reg_s.h" +#include "linux/wb35tx_s.h" +#include "linux/wb35rx_s.h" + + +// For Hal using ================================================================== +typedef struct _HW_DATA_T +{ + // For compatible with 33 + u32 revision; + u32 BB3c_cal; // The value for Tx calibration comes from EEPROM + u32 BB54_cal; // The value for Rx calibration comes from EEPROM + + + // For surprise remove + u32 SurpriseRemove; // 0: Normal 1: Surprise remove + u8 InitialResource; + u8 IsKeyPreSet; + u8 CalOneTime; // 20060630.1 + + u8 VCO_trim; + + // For Fix 1'st DMA bug + u32 FragCount; + u32 DMAFix; //V1_DMA_FIX The variable can be removed if driver want to save mem space for V2. + + //======================================================================================= + // For USB driver, hal need more variables. Due to + // 1. NDIS-WDM operation + // 2. The SME, MLME and OLD MDS need Adapter structure, but the driver under HAL doesn't + // have that parameter when receiving and indicating packet. + // The MDS must input the Adapter pointer as the second parameter of hal_init_hardware. + // The function usage is different than PCI driver. + //======================================================================================= + void* Adapter; + + //=============================================== + // Definition for MAC address + //=============================================== + u8 PermanentMacAddress[ETH_LENGTH_OF_ADDRESS + 2]; // The Enthernet addr that are stored in EEPROM. + 2 to 8-byte alignment + u8 CurrentMacAddress[ETH_LENGTH_OF_ADDRESS + 2]; // The Enthernet addr that are in used. + 2 to 8-byte alignment + + //===================================================================== + // Definition for 802.11 + //===================================================================== + PUCHAR bssid_pointer; // Used by hal_get_bssid for return value + u8 bssid[8];// Only 6 byte will be used. 8 byte is required for read buffer + u8 ssid[32];// maximum ssid length is 32 byte + + u16 AID; + u8 ssid_length; + u8 Channel; + + u16 ListenInterval; + u16 CapabilityInformation; + + u16 BeaconPeriod; + u16 ProbeDelay; + + u8 bss_type;// 0: IBSS_NET or 1:ESS_NET + u8 preamble;// 0: short preamble, 1: long preamble + u8 slot_time_select;// 9 or 20 value + u8 phy_type;// Phy select + + u32 phy_para[MAX_RF_PARAMETER]; + u32 phy_number; + + u32 CurrentRadioSw; // 20060320.2 0:On 1:Off + u32 CurrentRadioHw; // 20060825 0:On 1:Off + + PUCHAR power_save_point; // Used by hal_get_power_save_mode for return value + u8 cwmin; + u8 desired_power_save; + u8 dtim;// Is running dtim + u8 mapping_key_replace_index;//In Key table, the next index be replaced 931130.4.r + + u16 MaxReceiveLifeTime; + u16 FragmentThreshold; + u16 FragmentThreshold_tmp; + u16 cwmax; + + u8 Key_slot[MAX_KEY_TABLE][8]; //Ownership record for key slot. For Alignment + u32 Key_content[MAX_KEY_TABLE][12]; // 10DW for each entry + 2 for burst command( Off and On valid bit) + u8 CurrentDefaultKeyIndex; + u32 CurrentDefaultKeyLength; + + //======================================================================== + // Variable for each module + //======================================================================== + WBUSB WbUsb; // Need WbUsb.h + WB35REG Wb35Reg; // Need Wb35Reg.h + WB35TX Wb35Tx; // Need Wb35Tx.h + WB35RX Wb35Rx; // Need Wb35Rx.h + + OS_TIMER LEDTimer;// For LED + + u32 LEDpoint;// For LED + + u32 dto_tx_retry_count; // LA20040210_DTO kevin + u32 dto_tx_frag_count; // LA20040210_DTO kevin + u32 rx_ok_count[13]; // index=0: total rx ok + //u32 rx_ok_bytes[13]; // index=0, total rx ok bytes + u32 rx_err_count[13]; // index=0: total rx err + + //for Tx debug + u32 tx_TBTT_start_count; + u32 tx_ETR_count; + u32 tx_WepOn_false_count; + u32 tx_Null_key_count; + u32 tx_retry_count[8]; + + u8 PowerIndexFromEEPROM; // For 2412MHz + u8 power_index; + u8 IsWaitJoinComplete; // TRUE: set join request + u8 band; + + u16 SoftwareSet; + u16 Reserved_s; + + u32 IsInitOK; // 0: Driver starting 1: Driver init OK + + // For Phy calibration + s32 iq_rsdl_gain_tx_d2; + s32 iq_rsdl_phase_tx_d2; + u32 txvga_setting_for_cal; // 20060703.1 Add + + u8 TxVgaSettingInEEPROM[ (((MAX_TXVGA_EEPROM*2)+3) & ~0x03) ]; // 20060621 For backup EEPROM value + u8 TxVgaFor24[16]; // Max is 14, 2 for alignment + TXVGA_FOR_50 TxVgaFor50[36]; // 35 channels in 5G. 35x2 = 70 byte. 2 for alignments + + u16 Scan_Interval; + u16 RESERVED6; + + // LED control + u32 LED_control; + // LED_control 4 byte: Gray_Led_1[3] Gray_Led_0[2] Led[1] Led[0] + // Gray_Led + // For Led gray setting + // Led + // 0: normal control, LED behavior will decide by EEPROM setting + // 1: Turn off specific LED + // 2: Always on specific LED + // 3: slow blinking specific LED + // 4: fast blinking specific LED + // 5: WPS led control is set. Led0 is Red, Led1 id Green + // Led[1] is parameter for WPS LED mode + // // 1:InProgress 2: Error 3: Session overlap 4: Success 20061108 control + + u32 LED_LinkOn; //Turn LED on control + u32 LED_Scanning; // Let LED in scan process control + u32 LED_Blinking; // Temp variable for shining + u32 RxByteCountLast; + u32 TxByteCountLast; + + s32 SurpriseRemoveCount; + + // For global timer + u32 time_count;//TICK_TIME_100ms 1 = 100ms + + // For error recover + u32 HwStop; + + // 20060828.1 for avoid AP disconnect + u32 NullPacketCount; + +} hw_data_t, *phw_data_t; + +// The mapping of Rx and Tx descriptor field +typedef struct _HAL_RATE +{ + // DSSS + u32 RESERVED_0; + u32 NumRate2MS; + u32 NumRate55MS; + u32 NumRate11MS; + + u32 RESERVED_1[4]; + + u32 NumRate1M; + u32 NumRate2ML; + u32 NumRate55ML; + u32 NumRate11ML; + + u32 RESERVED_2[4]; + + // OFDM + u32 NumRate6M; + u32 NumRate9M; + u32 NumRate12M; + u32 NumRate18M; + u32 NumRate24M; + u32 NumRate36M; + u32 NumRate48M; + u32 NumRate54M; +} HAL_RATE, *PHAL_RATE; + + diff --git a/drivers/staging/winbond/wblinux.c b/drivers/staging/winbond/wblinux.c new file mode 100644 index 000000000000..2eade5a47b19 --- /dev/null +++ b/drivers/staging/winbond/wblinux.c @@ -0,0 +1,277 @@ +//============================================================================ +// Copyright (c) 1996-2005 Winbond Electronic Corporation +// +// Module Name: +// wblinux.c +// +// Abstract: +// Linux releated routines +// +//============================================================================ +#include "os_common.h" + +u32 +WBLINUX_MemoryAlloc(void* *VirtualAddress, u32 Length) +{ + *VirtualAddress = kzalloc( Length, GFP_ATOMIC ); //GFP_KERNEL is not suitable + + if (*VirtualAddress == NULL) + return 0; + return 1; +} + +s32 +EncapAtomicInc(PADAPTER Adapter, void* pAtomic) +{ + PWBLINUX pWbLinux = &Adapter->WbLinux; + u32 ltmp; + PULONG pltmp = (PULONG)pAtomic; + OS_SPIN_LOCK_ACQUIRED( &pWbLinux->AtomicSpinLock ); + (*pltmp)++; + ltmp = (*pltmp); + OS_SPIN_LOCK_RELEASED( &pWbLinux->AtomicSpinLock ); + return ltmp; +} + +s32 +EncapAtomicDec(PADAPTER Adapter, void* pAtomic) +{ + PWBLINUX pWbLinux = &Adapter->WbLinux; + u32 ltmp; + PULONG pltmp = (PULONG)pAtomic; + OS_SPIN_LOCK_ACQUIRED( &pWbLinux->AtomicSpinLock ); + (*pltmp)--; + ltmp = (*pltmp); + OS_SPIN_LOCK_RELEASED( &pWbLinux->AtomicSpinLock ); + return ltmp; +} + +unsigned char +WBLINUX_Initial(PADAPTER Adapter) +{ + PWBLINUX pWbLinux = &Adapter->WbLinux; + + OS_SPIN_LOCK_ALLOCATE( &pWbLinux->SpinLock ); + OS_SPIN_LOCK_ALLOCATE( &pWbLinux->AtomicSpinLock ); + return TRUE; +} + +void +WBLinux_ReceivePacket(PADAPTER Adapter, PRXLAYER1 pRxLayer1) +{ + BUG(); +} + + +void +WBLINUX_GetNextPacket(PADAPTER Adapter, PDESCRIPTOR pDes) +{ + BUG(); +} + +void +WBLINUX_GetNextPacketCompleted(PADAPTER Adapter, PDESCRIPTOR pDes) +{ + BUG(); +} + +void +WBLINUX_Destroy(PADAPTER Adapter) +{ + WBLINUX_stop( Adapter ); + OS_SPIN_LOCK_FREE( &pWbNdis->SpinLock ); +#ifdef _PE_USB_INI_DUMP_ + WBDEBUG(("[w35und] unregister_netdev!\n")); +#endif +} + +void +WBLINUX_stop( PADAPTER Adapter ) +{ + PWBLINUX pWbLinux = &Adapter->WbLinux; + struct sk_buff *pSkb; + + if (OS_ATOMIC_INC( Adapter, &pWbLinux->ThreadCount ) == 1) { + // Shutdown module immediately + pWbLinux->shutdown = 1; + + while (pWbLinux->skb_array[ pWbLinux->skb_GetIndex ]) { + // Trying to free the un-sending packet + pSkb = pWbLinux->skb_array[ pWbLinux->skb_GetIndex ]; + pWbLinux->skb_array[ pWbLinux->skb_GetIndex ] = NULL; + if( in_irq() ) + dev_kfree_skb_irq( pSkb ); + else + dev_kfree_skb( pSkb ); + + pWbLinux->skb_GetIndex++; + pWbLinux->skb_GetIndex %= WBLINUX_PACKET_ARRAY_SIZE; + } + +#ifdef _PE_STATE_DUMP_ + WBDEBUG(( "[w35und] SKB_RELEASE OK\n" )); +#endif + } + + OS_ATOMIC_DEC( Adapter, &pWbLinux->ThreadCount ); +} + +void +WbWlanHalt( PADAPTER Adapter ) +{ + //--------------------- + Adapter->sLocalPara.ShutDowned = TRUE; + + Mds_Destroy( Adapter ); + + // Turn off Rx and Tx hardware ability + hal_stop( &Adapter->sHwData ); +#ifdef _PE_USB_INI_DUMP_ + WBDEBUG(("[w35und] Hal_stop O.K.\n")); +#endif + OS_SLEEP(100000);// Waiting Irp completed + + // Destroy the NDIS module + WBLINUX_Destroy( Adapter ); + + // Halt the HAL + hal_halt(&Adapter->sHwData, NULL); +} + +unsigned char +WbWLanInitialize(PADAPTER Adapter) +{ + phw_data_t pHwData; + PUCHAR pMacAddr, pMacAddr2; + u32 InitStep = 0; + u8 EEPROM_region; + u8 HwRadioOff; + + do { + // + // Setting default value for Linux + // + Adapter->sLocalPara.region_INF = REGION_AUTO; + Adapter->sLocalPara.TxRateMode = RATE_AUTO; + psLOCAL->bMacOperationMode = MODE_802_11_BG; // B/G mode + Adapter->Mds.TxRTSThreshold = DEFAULT_RTSThreshold; + Adapter->Mds.TxFragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD; + hal_set_phy_type( &Adapter->sHwData, RF_WB_242_1 ); + Adapter->sLocalPara.MTUsize = MAX_ETHERNET_PACKET_SIZE; + psLOCAL->bPreambleMode = AUTO_MODE; + Adapter->sLocalPara.RadioOffStatus.boSwRadioOff = FALSE; + pHwData = &Adapter->sHwData; + hal_set_phy_type( pHwData, RF_DECIDE_BY_INF ); + + // + // Initial each module and variable + // + if (!WBLINUX_Initial(Adapter)) { +#ifdef _PE_USB_INI_DUMP_ + WBDEBUG(("[w35und]WBNDIS initialization failed\n")); +#endif + break; + } + + // Initial Software variable + Adapter->sLocalPara.ShutDowned = FALSE; + + //added by ws for wep key error detection + Adapter->sLocalPara.bWepKeyError= FALSE; + Adapter->sLocalPara.bToSelfPacketReceived = FALSE; + Adapter->sLocalPara.WepKeyDetectTimerCount= 2 * 100; /// 2 seconds + + // Initial USB hal + InitStep = 1; + pHwData = &Adapter->sHwData; + if (!hal_init_hardware(pHwData, Adapter)) + break; + + EEPROM_region = hal_get_region_from_EEPROM( pHwData ); + if (EEPROM_region != REGION_AUTO) + psLOCAL->region = EEPROM_region; + else { + if (psLOCAL->region_INF != REGION_AUTO) + psLOCAL->region = psLOCAL->region_INF; + else + psLOCAL->region = REGION_USA; //default setting + } + + // Get Software setting flag from hal + Adapter->sLocalPara.boAntennaDiversity = FALSE; + if (hal_software_set(pHwData) & 0x00000001) + Adapter->sLocalPara.boAntennaDiversity = TRUE; + + // + // For TS module + // + InitStep = 2; + + // For MDS module + InitStep = 3; + Mds_initial(Adapter); + + //======================================= + // Initialize the SME, SCAN, MLME, ROAM + //======================================= + InitStep = 4; + InitStep = 5; + InitStep = 6; + + // If no user-defined address in the registry, use the addresss "burned" on the NIC instead. + pMacAddr = Adapter->sLocalPara.ThisMacAddress; + pMacAddr2 = Adapter->sLocalPara.PermanentAddress; + hal_get_permanent_address( pHwData, Adapter->sLocalPara.PermanentAddress );// Reading ethernet address from EEPROM + if (OS_MEMORY_COMPARE(pMacAddr, "\x00\x00\x00\x00\x00\x00", MAC_ADDR_LENGTH )) // Is equal + { + memcpy( pMacAddr, pMacAddr2, MAC_ADDR_LENGTH ); + } else { + // Set the user define MAC address + hal_set_ethernet_address( pHwData, Adapter->sLocalPara.ThisMacAddress ); + } + + //get current antenna + psLOCAL->bAntennaNo = hal_get_antenna_number(pHwData); +#ifdef _PE_STATE_DUMP_ + WBDEBUG(("Driver init, antenna no = %d\n", psLOCAL->bAntennaNo)); +#endif + hal_get_hw_radio_off( pHwData ); + + // Waiting for HAL setting OK + while (!hal_idle(pHwData)) + OS_SLEEP(10000); + + MTO_Init(Adapter); + + HwRadioOff = hal_get_hw_radio_off( pHwData ); + psLOCAL->RadioOffStatus.boHwRadioOff = !!HwRadioOff; + + hal_set_radio_mode( pHwData, (unsigned char)(psLOCAL->RadioOffStatus.boSwRadioOff || psLOCAL->RadioOffStatus.boHwRadioOff) ); + + hal_driver_init_OK(pHwData) = 1; // Notify hal that the driver is ready now. + //set a tx power for reference..... +// sme_set_tx_power_level(Adapter, 12); FIXME? + return TRUE; + } + while(FALSE); + + switch (InitStep) { + case 5: + case 4: + case 3: Mds_Destroy( Adapter ); + case 2: + case 1: WBLINUX_Destroy( Adapter ); + hal_halt( pHwData, NULL ); + case 0: break; + } + + return FALSE; +} + +void WBLINUX_ConnectStatus(PADAPTER Adapter, u32 flag) +{ + PWBLINUX pWbLinux = &Adapter->WbLinux; + + pWbLinux->LinkStatus = flag; // OS_DISCONNECTED or OS_CONNECTED +} + diff --git a/drivers/staging/winbond/wblinux_f.h b/drivers/staging/winbond/wblinux_f.h new file mode 100644 index 000000000000..68240c5fc80d --- /dev/null +++ b/drivers/staging/winbond/wblinux_f.h @@ -0,0 +1,23 @@ +//========================================================================= +// Copyright (c) 1996-2004 Winbond Electronic Corporation +// +// wblinux_f.h +// +u32 WBLINUX_MemoryAlloc( void* *VirtualAddress, u32 Length ); +s32 EncapAtomicInc( PADAPTER Adapter, void* pAtomic ); +s32 EncapAtomicDec( PADAPTER Adapter, void* pAtomic ); +void WBLinux_ReceivePacket( PADAPTER Adapter, PRXLAYER1 pRxLayer1 ); +unsigned char WBLINUX_Initial( PADAPTER Adapter ); +int wb35_start_xmit(struct sk_buff *skb, struct net_device *netdev ); +void WBLINUX_GetNextPacket( PADAPTER Adapter, PDESCRIPTOR pDes ); +void WBLINUX_GetNextPacketCompleted( PADAPTER Adapter, PDESCRIPTOR pDes ); +void WBLINUX_stop( PADAPTER Adapter ); +void WBLINUX_Destroy( PADAPTER Adapter ); +void wb35_set_multicast( struct net_device *netdev ); +struct net_device_stats * wb35_netdev_stats( struct net_device *netdev ); +void WBLINUX_stop( PADAPTER Adapter ); +void WbWlanHalt( PADAPTER Adapter ); +void WBLINUX_ConnectStatus( PADAPTER Adapter, u32 flag ); + + + diff --git a/drivers/staging/winbond/wblinux_s.h b/drivers/staging/winbond/wblinux_s.h new file mode 100644 index 000000000000..97e9167ab839 --- /dev/null +++ b/drivers/staging/winbond/wblinux_s.h @@ -0,0 +1,45 @@ +//============================================================ +// wblinux_s.h +// +#define OS_MEMORY_ALLOC( _V, _S ) WBLINUX_MemoryAlloc( _V, _S ) +#define OS_LINK_STATUS (Adapter->WbLinux.LinkStatus == OS_CONNECTED) +#define OS_SET_SHUTDOWN( _A ) _A->WbLinux.shutdown=1 +#define OS_SET_RESUME( _A ) _A->WbLinux.shutdown=0 +#define OS_CONNECT_STATUS_INDICATE( _A, _F ) WBLINUX_ConnectStatus( _A, _F ) +#define OS_DISCONNECTED 0 +#define OS_CONNECTED 1 +#define OS_STOP( _A ) WBLINUX_stop( _A ) + +#define OS_CURRENT_RX_BYTE( _A ) _A->WbLinux.RxByteCount +#define OS_CURRENT_TX_BYTE( _A ) _A->WbLinux.TxByteCount +#define OS_EVENT_INDICATE( _A, _B, _F ) +#define OS_PMKID_STATUS_EVENT( _A ) +#define OS_RECEIVE_PACKET_INDICATE( _A, _D ) WBLinux_ReceivePacket( _A, _D ) +#define OS_RECEIVE_802_1X_PACKET_INDICATE( _A, _D ) EAP_ReceivePacket( _A, _D ) +#define OS_GET_PACKET( _A, _D ) WBLINUX_GetNextPacket( _A, _D ) +#define OS_GET_PACKET_COMPLETE( _A, _D ) WBLINUX_GetNextPacketCompleted( _A, _D ) +#define OS_SEND_RESULT( _A, _ID, _R ) + +#define WBLINUX_PACKET_ARRAY_SIZE (ETHERNET_TX_DESCRIPTORS*4) + +typedef struct _WBLINUX +{ + OS_SPIN_LOCK AtomicSpinLock; + OS_SPIN_LOCK SpinLock; + u32 shutdown; + + OS_ATOMIC ThreadCount; + + u32 LinkStatus; // OS_DISCONNECTED or OS_CONNECTED + + u32 RxByteCount; + u32 TxByteCount; + + struct sk_buff *skb_array[ WBLINUX_PACKET_ARRAY_SIZE ]; + struct sk_buff *packet_return; + s32 skb_SetIndex; + s32 skb_GetIndex; + s32 netif_state_stop; // 1: stop 0: normal +} WBLINUX, *PWBLINUX; + + |