From 66101de10957e07a6fd0365d5af9adf650246d14 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Wed, 1 Oct 2008 14:36:56 +0200 Subject: [PATCH] Staging: add w35und wifi driver This is driver for w35und usb wifi -- also in kohjinsha subnotebook. It should work well enough to associate and ping, but it obviously needs to be rewritten two more times... OTOH worst horrors (like embedded wifi stack) should have been fixed already... Signed-off-by: Pavel Machek Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 + drivers/staging/Makefile | 1 + drivers/staging/winbond/Kconfig | 7 + drivers/staging/winbond/Makefile | 18 + drivers/staging/winbond/README | 10 + drivers/staging/winbond/adapter.h | 23 + drivers/staging/winbond/bss_f.h | 59 + drivers/staging/winbond/bssdscpt.h | 156 ++ drivers/staging/winbond/ds_tkip.h | 33 + drivers/staging/winbond/gl_80211.h | 125 + drivers/staging/winbond/ioctls.h | 678 ++++++ drivers/staging/winbond/linux/common.h | 143 ++ drivers/staging/winbond/linux/sysdef.h | 73 + drivers/staging/winbond/linux/wb35reg.c | 747 ++++++ drivers/staging/winbond/linux/wb35reg_f.h | 56 + drivers/staging/winbond/linux/wb35reg_s.h | 170 ++ drivers/staging/winbond/linux/wb35rx.c | 337 +++ drivers/staging/winbond/linux/wb35rx_f.h | 17 + drivers/staging/winbond/linux/wb35rx_s.h | 48 + drivers/staging/winbond/linux/wb35tx.c | 313 +++ drivers/staging/winbond/linux/wb35tx_f.h | 20 + drivers/staging/winbond/linux/wb35tx_s.h | 47 + drivers/staging/winbond/linux/wbusb.c | 404 ++++ drivers/staging/winbond/linux/wbusb_f.h | 34 + drivers/staging/winbond/linux/wbusb_s.h | 42 + drivers/staging/winbond/localpara.h | 275 +++ drivers/staging/winbond/mac_structures.h | 670 +++++ drivers/staging/winbond/mds.c | 630 +++++ drivers/staging/winbond/mds_f.h | 33 + drivers/staging/winbond/mds_s.h | 183 ++ drivers/staging/winbond/mlme_mib.h | 84 + drivers/staging/winbond/mlme_s.h | 195 ++ drivers/staging/winbond/mlmetxrx.c | 150 ++ drivers/staging/winbond/mlmetxrx_f.h | 52 + drivers/staging/winbond/mto.c | 1229 ++++++++++ drivers/staging/winbond/mto.h | 265 ++ drivers/staging/winbond/mto_f.h | 7 + drivers/staging/winbond/os_common.h | 2 + drivers/staging/winbond/phy_calibration.c | 1759 ++++++++++++++ drivers/staging/winbond/phy_calibration.h | 101 + drivers/staging/winbond/reg.c | 2683 +++++++++++++++++++++ drivers/staging/winbond/rxisr.c | 30 + drivers/staging/winbond/scan_s.h | 115 + drivers/staging/winbond/sme_api.c | 13 + drivers/staging/winbond/sme_api.h | 265 ++ drivers/staging/winbond/sme_s.h | 228 ++ drivers/staging/winbond/wb35_ver.h | 30 + drivers/staging/winbond/wbhal.c | 878 +++++++ drivers/staging/winbond/wbhal_f.h | 122 + drivers/staging/winbond/wbhal_s.h | 615 +++++ drivers/staging/winbond/wblinux.c | 277 +++ drivers/staging/winbond/wblinux_f.h | 23 + drivers/staging/winbond/wblinux_s.h | 45 + 53 files changed, 14522 insertions(+) create mode 100644 drivers/staging/winbond/Kconfig create mode 100644 drivers/staging/winbond/Makefile create mode 100644 drivers/staging/winbond/README create mode 100644 drivers/staging/winbond/adapter.h create mode 100644 drivers/staging/winbond/bss_f.h create mode 100644 drivers/staging/winbond/bssdscpt.h create mode 100644 drivers/staging/winbond/ds_tkip.h create mode 100644 drivers/staging/winbond/gl_80211.h create mode 100644 drivers/staging/winbond/ioctls.h create mode 100644 drivers/staging/winbond/linux/common.h create mode 100644 drivers/staging/winbond/linux/sysdef.h create mode 100644 drivers/staging/winbond/linux/wb35reg.c create mode 100644 drivers/staging/winbond/linux/wb35reg_f.h create mode 100644 drivers/staging/winbond/linux/wb35reg_s.h create mode 100644 drivers/staging/winbond/linux/wb35rx.c create mode 100644 drivers/staging/winbond/linux/wb35rx_f.h create mode 100644 drivers/staging/winbond/linux/wb35rx_s.h create mode 100644 drivers/staging/winbond/linux/wb35tx.c create mode 100644 drivers/staging/winbond/linux/wb35tx_f.h create mode 100644 drivers/staging/winbond/linux/wb35tx_s.h create mode 100644 drivers/staging/winbond/linux/wbusb.c create mode 100644 drivers/staging/winbond/linux/wbusb_f.h create mode 100644 drivers/staging/winbond/linux/wbusb_s.h create mode 100644 drivers/staging/winbond/localpara.h create mode 100644 drivers/staging/winbond/mac_structures.h create mode 100644 drivers/staging/winbond/mds.c create mode 100644 drivers/staging/winbond/mds_f.h create mode 100644 drivers/staging/winbond/mds_s.h create mode 100644 drivers/staging/winbond/mlme_mib.h create mode 100644 drivers/staging/winbond/mlme_s.h create mode 100644 drivers/staging/winbond/mlmetxrx.c create mode 100644 drivers/staging/winbond/mlmetxrx_f.h create mode 100644 drivers/staging/winbond/mto.c create mode 100644 drivers/staging/winbond/mto.h create mode 100644 drivers/staging/winbond/mto_f.h create mode 100644 drivers/staging/winbond/os_common.h create mode 100644 drivers/staging/winbond/phy_calibration.c create mode 100644 drivers/staging/winbond/phy_calibration.h create mode 100644 drivers/staging/winbond/reg.c create mode 100644 drivers/staging/winbond/rxisr.c create mode 100644 drivers/staging/winbond/scan_s.h create mode 100644 drivers/staging/winbond/sme_api.c create mode 100644 drivers/staging/winbond/sme_api.h create mode 100644 drivers/staging/winbond/sme_s.h create mode 100644 drivers/staging/winbond/wb35_ver.h create mode 100644 drivers/staging/winbond/wbhal.c create mode 100644 drivers/staging/winbond/wbhal_f.h create mode 100644 drivers/staging/winbond/wbhal_s.h create mode 100644 drivers/staging/winbond/wblinux.c create mode 100644 drivers/staging/winbond/wblinux_f.h create mode 100644 drivers/staging/winbond/wblinux_s.h diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 4dbf795df74..fdbdf84e307 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 be42c0d4db0..9b576c91b15 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 00000000000..10d72bec88a --- /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 00000000000..29c98bf1bc9 --- /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 00000000000..707b6b354dc --- /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 and +Pavel Machek diff --git a/drivers/staging/winbond/adapter.h b/drivers/staging/winbond/adapter.h new file mode 100644 index 00000000000..609701d21cf --- /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 00000000000..c957bc94f08 --- /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 00000000000..97150a2655f --- /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 00000000000..29e5055b45a --- /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 00000000000..1806d817496 --- /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 */ +typedef enum preamble_type { + WLAN_PREAMBLE_TYPE_SHORT, + WLAN_PREAMBLE_TYPE_LONG, +} preamble_type_e; + + +/* Slot_Time_Type, see */ +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 00000000000..e8b35dc7e32 --- /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 + +//======================================================== +// 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 00000000000..6b00bad74f7 --- /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 +#include +#include //need for kernel alert +#include +#include +#include +#include //memory allocate +#include +#include +#include +#include //need for init and exit modules marco +#include +#include +#include +#include +#include +#include +#include +#include + + +//#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 00000000000..d46d63e5c67 --- /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 00000000000..2c0b454e8ca --- /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; ipBuffer[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 00000000000..38e2906b51a --- /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 00000000000..a7595b1e733 --- /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 00000000000..26157eb3d5a --- /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; iRxOwner[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 00000000000..daa3e73042b --- /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 00000000000..53b831fdeb7 --- /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 00000000000..cf19c3bc524 --- /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 00000000000..7705a8454dc --- /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 00000000000..ac432573676 --- /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 00000000000..cbad5fb0595 --- /dev/null +++ b/drivers/staging/winbond/linux/wbusb.c @@ -0,0 +1,404 @@ +/* + * Copyright 2008 Pavel Machek + * + * Distribute under GPLv2. + */ +#include "sysdef.h" +#include + + +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 00000000000..cae29e107e1 --- /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 00000000000..d5c1d53de70 --- /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 Adapted to 2.6.x by Costantino Leandro (Rxart Desktop) " +#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 00000000000..268cf916ab4 --- /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 00000000000..031d2cb6cd6 --- /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 00000000000..8ce6389c413 --- /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 00000000000..651188be106 --- /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 00000000000..4738279d5f3 --- /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 00000000000..89759739cba --- /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 00000000000..58094f61c03 --- /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 00000000000..46b091e9679 --- /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 00000000000..d74e225be21 --- /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 00000000000..2ef60e5120c --- /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;i0;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= 12) + break; + } + MTO_OFDM_RATE_LEVEL() = i; + } + + for(i=0;i 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;iphy_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 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_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_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 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 00000000000..f47936f46d1 --- /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 00000000000..30b3df2ccb3 --- /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 00000000000..e24ff41e871 --- /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 00000000000..272a65066ab --- /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 00000000000..b6a65d31301 --- /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 00000000000..b475c7a7c42 --- /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; iphy_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; iphy_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; iphy_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; iphy_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; iphy_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; iphy_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; iphy_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; iphy_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; iVCO_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; iCalOneTime ) + 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; iWb35Reg.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; iSQ3_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; iband) + { + 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; iBB50 &= ~(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= 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= 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= 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; iphy_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 00000000000..18e942c9b82 --- /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_valueMds.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 00000000000..1d1b0c4fec1 --- /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 00000000000..40e93b7600e --- /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 00000000000..016b225ca4a --- /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 00000000000..dfd2fbc4ede --- /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 00000000000..2433bc07300 --- /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 00000000000..daf44224755 --- /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; iM28_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; iLNAValue[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; iLNAValue[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; iHalRssi[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 00000000000..fe25f97af72 --- /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 00000000000..5b862ff357b --- /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 00000000000..2eade5a47b1 --- /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 00000000000..68240c5fc80 --- /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 00000000000..97e9167ab83 --- /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; + + -- 2.41.1