Staging: add rt3090 wireless driver

This is the vendor driver for the Ralink RT3090 chipset.

It should be later cleaned and ported to use the existing rt2x00
infrastructure or just replaced by the proper version.

[ Unfortunately since it follows the same design/implementation like
  rt{286,287,307}0 drivers (already present in the staging tree)
  it is highly unlikely that it will see much love from the wireless
  development community.. ]

However since the development of the cleaner/proper version can take
significant time lets give distros (i.e. openSUSE seems to already
have the package with the original vendor driver) and users "something"
to use in the meantime.

I forward ported it to 2.6.31-rc1, ported to the Linux build system
and did some initial cleanups.  More fixes/cleanups to come later
(it seems that the driver can be made to share most of its code with
the other Ralink drivers already present in the staging tree).

Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
Bartlomiej Zolnierkiewicz 2009-06-25 15:40:31 +02:00 committed by Greg Kroah-Hartman
parent fd882783ab
commit 36c7928c3e
112 changed files with 104961 additions and 0 deletions

View file

@ -75,6 +75,8 @@ source "drivers/staging/rt2870/Kconfig"
source "drivers/staging/rt3070/Kconfig"
source "drivers/staging/rt3090/Kconfig"
source "drivers/staging/comedi/Kconfig"
source "drivers/staging/asus_oled/Kconfig"

View file

@ -20,6 +20,7 @@ obj-$(CONFIG_OTUS) += otus/
obj-$(CONFIG_RT2860) += rt2860/
obj-$(CONFIG_RT2870) += rt2870/
obj-$(CONFIG_RT3070) += rt3070/
obj-$(CONFIG_RT3090) += rt3090/
obj-$(CONFIG_COMEDI) += comedi/
obj-$(CONFIG_ASUS_OLED) += asus_oled/
obj-$(CONFIG_PANEL) += panel/

View file

@ -0,0 +1,5 @@
config RT3090
tristate "Ralink 3090 wireless support"
depends on PCI && X86 && WLAN_80211
---help---
This is an experimental driver for the Ralink 3090 wireless chip.

View file

@ -0,0 +1,80 @@
obj-$(CONFIG_RT3090) += rt3090sta.o
include drivers/staging/rt3090/config.mk
rt3090sta-objs := \
common/crypt_md5.o \
common/crypt_sha2.o \
common/crypt_hmac.o \
common/mlme.o \
common/cmm_wep.o \
common/action.o \
common/cmm_data.o \
common/rtmp_init.o \
common/cmm_tkip.o \
common/cmm_aes.o \
common/cmm_sync.o \
common/eeprom.o \
common/cmm_sanity.o \
common/cmm_info.o \
common/cmm_cfg.o \
common/cmm_wpa.o \
common/dfs.o \
common/spectrum.o \
common/rtmp_timer.o \
common/rt_channel.o \
common/cmm_profile.o \
common/cmm_asic.o \
sta/assoc.o \
sta/auth.o \
sta/auth_rsp.o \
sta/sync.o \
sta/sanity.o \
sta/rtmp_data.o \
sta/connect.o \
sta/wpa.o \
rt_linux.o \
rt_profile.o \
rt_main_dev.o \
sta_ioctl.o
#ifdef DOT11_N_SUPPORT
ifeq ($(HAS_DOT11_N_SUPPORT),y)
rt3090sta-objs += \
common/ba_action.o
endif
#endif // DOT11_N_SUPPORT //
#ifdef ETH_CONVERT
ifeq ($(HAS_ETH_CONVERT_SUPPORT), y)
rt3090sta-objs += \
common/cmm_mat.o \
common/cmm_mat_iparp.o \
common/cmm_mat_pppoe.o \
common/cmm_mat_ipv6.o
endif
#endif // ETH_CONVERT //
ifeq ($(HAS_BLOCK_NET_IF),y)
rt3090sta-objs += common/netif_block.o
endif
ifeq ($(HAS_QOS_DLS_SUPPORT),y)
rt3090sta-objs += sta/dls.o
endif
rt3090sta-objs += \
pci_main_dev.o \
rt_pci_rbus.o \
common/cmm_mac_pci.o \
common/cmm_data_pci.o \
common/ee_prom.o \
common/ee_efuse.o \
common/rtmp_mcu.o \
chips/rt30xx.o \
common/rt_rf.o \
chips/rt3090.o
ifeq ($(HAS_ATE),y)
rt3090sta-objs += rt_ate.o
endif

View file

@ -0,0 +1,66 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
aironet.h
Abstract:
Revision History:
Who When What
-------- ---------- ----------------------------------------------
Name Date Modification logs
Paul Lin 04-06-15 Initial
*/
#ifndef __ACTION_H__
#define __ACTION_H__
typedef struct PACKED __HT_INFO_OCTET
{
#ifdef RT_BIG_ENDIAN
UCHAR Reserved:5;
UCHAR STA_Channel_Width:1;
UCHAR Forty_MHz_Intolerant:1;
UCHAR Request:1;
#else
UCHAR Request:1;
UCHAR Forty_MHz_Intolerant:1;
UCHAR STA_Channel_Width:1;
UCHAR Reserved:5;
#endif
} HT_INFORMATION_OCTET;
typedef struct PACKED __FRAME_HT_INFO
{
HEADER_802_11 Hdr;
UCHAR Category;
UCHAR Action;
HT_INFORMATION_OCTET HT_Info;
} FRAME_HT_INFO, *PFRAME_HT_INFO;
#endif /* __ACTION_H__ */

512
drivers/staging/rt3090/ap.h Normal file
View file

@ -0,0 +1,512 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
ap.h
Abstract:
Miniport generic portion header file
Revision History:
Who When What
-------- ---------- ----------------------------------------------
Paul Lin 08-01-2002 created
James Tan 09-06-2002 modified (Revise NTCRegTable)
John Chang 12-22-2004 modified for RT2561/2661. merge with STA driver
*/
#ifndef __AP_H__
#define __AP_H__
// =============================================================
// Function Prototypes
// =============================================================
// ap_data.c
BOOLEAN APBridgeToWirelessSta(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pHeader,
IN UINT HdrLen,
IN PUCHAR pData,
IN UINT DataLen,
IN ULONG fromwdsidx);
VOID APSendPackets(
IN NDIS_HANDLE MiniportAdapterContext,
IN PPNDIS_PACKET ppPacketArray,
IN UINT NumberOfPackets);
NDIS_STATUS APSendPacket(
IN PRTMP_ADAPTER pAd,
IN PNDIS_PACKET pPacket);
NDIS_STATUS APHardTransmit(
IN PRTMP_ADAPTER pAd,
IN TX_BLK *pTxBlk,
IN UCHAR QueIdx);
VOID APRxEAPOLFrameIndicate(
IN PRTMP_ADAPTER pAd,
IN MAC_TABLE_ENTRY *pEntry,
IN RX_BLK *pRxBlk,
IN UCHAR FromWhichBSSID);
NDIS_STATUS APCheckRxError(
IN PRTMP_ADAPTER pAd,
IN PRT28XX_RXD_STRUC pRxD,
IN UCHAR Wcid);
BOOLEAN APCheckClass2Class3Error(
IN PRTMP_ADAPTER pAd,
IN ULONG Wcid,
IN PHEADER_802_11 pHeader);
VOID APHandleRxPsPoll(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pAddr,
IN USHORT Aid,
IN BOOLEAN isActive);
VOID RTMPDescriptorEndianChange(
IN PUCHAR pData,
IN ULONG DescriptorType);
VOID RTMPFrameEndianChange(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pData,
IN ULONG Dir,
IN BOOLEAN FromRxDoneInt);
// ap_assoc.c
VOID APAssocStateMachineInit(
IN PRTMP_ADAPTER pAd,
IN STATE_MACHINE *S,
OUT STATE_MACHINE_FUNC Trans[]);
VOID APPeerAssocReqAction(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem);
VOID APPeerReassocReqAction(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem);
VOID APPeerDisassocReqAction(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem);
VOID MbssKickOutStas(
IN PRTMP_ADAPTER pAd,
IN INT apidx,
IN USHORT Reason);
VOID APMlmeKickOutSta(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pStaAddr,
IN UCHAR Wcid,
IN USHORT Reason);
VOID APMlmeDisassocReqAction(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem);
VOID APCls3errAction(
IN PRTMP_ADAPTER pAd,
IN ULONG Wcid,
IN PHEADER_802_11 pHeader);
USHORT APBuildAssociation(
IN PRTMP_ADAPTER pAd,
IN MAC_TABLE_ENTRY *pEntry,
IN USHORT CapabilityInfo,
IN UCHAR MaxSupportedRateIn500Kbps,
IN UCHAR *RSN,
IN UCHAR *pRSNLen,
IN BOOLEAN bWmmCapable,
IN ULONG RalinkIe,
#ifdef DOT11N_DRAFT3
IN EXT_CAP_INFO_ELEMENT ExtCapInfo,
#endif // DOT11N_DRAFT3 //
IN HT_CAPABILITY_IE *pHtCapability,
IN UCHAR HtCapabilityLen,
OUT USHORT *pAid);
/*
VOID RTMPAddClientSec(
IN PRTMP_ADAPTER pAd,
IN UCHAR BssIdx,
IN UCHAR KeyIdx,
IN UCHAR CipherAlg,
IN PUCHAR pKey,
IN PUCHAR pTxMic,
IN PUCHAR pRxMic,
IN MAC_TABLE_ENTRY *pEntry);
*/
// ap_auth.c
void APAuthStateMachineInit(
IN PRTMP_ADAPTER pAd,
IN STATE_MACHINE *Sm,
OUT STATE_MACHINE_FUNC Trans[]);
VOID APCls2errAction(
IN PRTMP_ADAPTER pAd,
IN ULONG Wcid,
IN PHEADER_802_11 pHeader);
// ap_connect.c
VOID APMakeBssBeacon(
IN PRTMP_ADAPTER pAd,
IN INT apidx);
VOID APUpdateBeaconFrame(
IN PRTMP_ADAPTER pAd,
IN INT apidx);
VOID APMakeAllBssBeacon(
IN PRTMP_ADAPTER pAd);
VOID APUpdateAllBeaconFrame(
IN PRTMP_ADAPTER pAd);
// ap_sync.c
VOID APSyncStateMachineInit(
IN PRTMP_ADAPTER pAd,
IN STATE_MACHINE *Sm,
OUT STATE_MACHINE_FUNC Trans[]);
VOID APScanTimeout(
IN PVOID SystemSpecific1,
IN PVOID FunctionContext,
IN PVOID SystemSpecific2,
IN PVOID SystemSpecific3);
VOID APInvalidStateWhenScan(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem);
VOID APScanTimeoutAction(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem);
VOID APPeerProbeReqAction(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem);
VOID APPeerBeaconAction(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem);
VOID APMlmeScanReqAction(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem);
VOID APPeerBeaconAtScanAction(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem);
VOID APScanCnclAction(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem);
VOID ApSiteSurvey(
IN PRTMP_ADAPTER pAd,
IN PNDIS_802_11_SSID pSsid,
IN UCHAR ScanType);
VOID SupportRate(
IN PUCHAR SupRate,
IN UCHAR SupRateLen,
IN PUCHAR ExtRate,
IN UCHAR ExtRateLen,
OUT PUCHAR *Rates,
OUT PUCHAR RatesLen,
OUT PUCHAR pMaxSupportRate);
BOOLEAN ApScanRunning(
IN PRTMP_ADAPTER pAd);
#ifdef DOT11N_DRAFT3
VOID APOverlappingBSSScan(
IN RTMP_ADAPTER *pAd);
#endif // DOT11N_DRAFT3 //
// ap_wpa.c
VOID WpaStateMachineInit(
IN PRTMP_ADAPTER pAd,
IN STATE_MACHINE *Sm,
OUT STATE_MACHINE_FUNC Trans[]);
// ap_mlme.c
VOID APMlmePeriodicExec(
IN PRTMP_ADAPTER pAd);
VOID APMlmeSelectTxRateTable(
IN PRTMP_ADAPTER pAd,
IN PMAC_TABLE_ENTRY pEntry,
IN PUCHAR *ppTable,
IN PUCHAR pTableSize,
IN PUCHAR pInitTxRateIdx);
VOID APMlmeSetTxRate(
IN PRTMP_ADAPTER pAd,
IN PMAC_TABLE_ENTRY pEntry,
IN PRTMP_TX_RATE_SWITCH pTxRate);
VOID APMlmeDynamicTxRateSwitching(
IN PRTMP_ADAPTER pAd);
VOID APQuickResponeForRateUpExec(
IN PVOID SystemSpecific1,
IN PVOID FunctionContext,
IN PVOID SystemSpecific2,
IN PVOID SystemSpecific3);
BOOLEAN APMsgTypeSubst(
IN PRTMP_ADAPTER pAd,
IN PFRAME_802_11 pFrame,
OUT INT *Machine,
OUT INT *MsgType);
VOID APQuickResponeForRateUpExec(
IN PVOID SystemSpecific1,
IN PVOID FunctionContext,
IN PVOID SystemSpecific2,
IN PVOID SystemSpecific3);
VOID RTMPSetPiggyBack(
IN PRTMP_ADAPTER pAd,
IN BOOLEAN bPiggyBack);
VOID APAsicEvaluateRxAnt(
IN PRTMP_ADAPTER pAd);
VOID APAsicRxAntEvalTimeout(
IN PRTMP_ADAPTER pAd);
// ap.c
VOID APSwitchChannel(
IN PRTMP_ADAPTER pAd,
IN INT Channel);
NDIS_STATUS APInitialize(
IN PRTMP_ADAPTER pAd);
VOID APShutdown(
IN PRTMP_ADAPTER pAd);
VOID APStartUp(
IN PRTMP_ADAPTER pAd);
VOID APStop(
IN PRTMP_ADAPTER pAd);
VOID APCleanupPsQueue(
IN PRTMP_ADAPTER pAd,
IN PQUEUE_HEADER pQueue);
VOID MacTableReset(
IN PRTMP_ADAPTER pAd);
MAC_TABLE_ENTRY *MacTableInsertEntry(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pAddr,
IN UCHAR apidx,
IN BOOLEAN CleanAll);
BOOLEAN MacTableDeleteEntry(
IN PRTMP_ADAPTER pAd,
IN USHORT wcid,
IN PUCHAR pAddr);
MAC_TABLE_ENTRY *MacTableLookup(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pAddr);
VOID MacTableMaintenance(
IN PRTMP_ADAPTER pAd);
UINT32 MacTableAssocStaNumGet(
IN PRTMP_ADAPTER pAd);
MAC_TABLE_ENTRY *APSsPsInquiry(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pAddr,
OUT SST *Sst,
OUT USHORT *Aid,
OUT UCHAR *PsMode,
OUT UCHAR *Rate);
BOOLEAN APPsIndicate(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pAddr,
IN ULONG Wcid,
IN UCHAR Psm);
VOID ApLogEvent(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pAddr,
IN USHORT Event);
#ifdef DOT11_N_SUPPORT
VOID APUpdateOperationMode(
IN PRTMP_ADAPTER pAd);
#endif // DOT11_N_SUPPORT //
VOID APUpdateCapabilityAndErpIe(
IN PRTMP_ADAPTER pAd);
BOOLEAN ApCheckAccessControlList(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pAddr,
IN UCHAR Apidx);
VOID ApUpdateAccessControlList(
IN PRTMP_ADAPTER pAd,
IN UCHAR Apidx);
VOID ApEnqueueNullFrame(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pAddr,
IN UCHAR TxRate,
IN UCHAR PID,
IN UCHAR apidx,
IN BOOLEAN bQosNull,
IN BOOLEAN bEOSP,
IN UCHAR OldUP);
VOID ApSendFrame(
IN PRTMP_ADAPTER pAd,
IN PVOID pBuffer,
IN ULONG Length,
IN UCHAR TxRate,
IN UCHAR PID);
VOID ApEnqueueAckFrame(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pAddr,
IN UCHAR TxRate,
IN UCHAR apidx);
// ap_sanity.c
BOOLEAN PeerAssocReqCmmSanity(
IN PRTMP_ADAPTER pAd,
IN BOOLEAN isRessoc,
IN VOID *Msg,
IN ULONG MsgLen,
OUT PUCHAR pAddr2,
OUT USHORT *pCapabilityInfo,
OUT USHORT *pListenInterval,
OUT PUCHAR pApAddr,
OUT UCHAR *pSsidLen,
OUT char *Ssid,
OUT UCHAR *pRatesLen,
OUT UCHAR Rates[],
OUT UCHAR *RSN,
OUT UCHAR *pRSNLen,
OUT BOOLEAN *pbWmmCapable,
OUT ULONG *pRalinkIe,
#ifdef DOT11N_DRAFT3
OUT EXT_CAP_INFO_ELEMENT *pExtCapInfo,
#endif // DOT11N_DRAFT3 //
OUT UCHAR *pHtCapabilityLen,
OUT HT_CAPABILITY_IE *pHtCapability);
BOOLEAN PeerDisassocReqSanity(
IN PRTMP_ADAPTER pAd,
IN VOID *Msg,
IN ULONG MsgLen,
OUT PUCHAR pAddr2,
OUT USHORT *Reason);
BOOLEAN PeerDeauthReqSanity(
IN PRTMP_ADAPTER pAd,
IN VOID *Msg,
IN ULONG MsgLen,
OUT PUCHAR pAddr2,
OUT USHORT *Reason);
BOOLEAN APPeerAuthSanity(
IN PRTMP_ADAPTER pAd,
IN VOID *Msg,
IN ULONG MsgLen,
OUT PUCHAR pAddr1,
OUT PUCHAR pAddr2,
OUT USHORT *Alg,
OUT USHORT *Seq,
OUT USHORT *Status,
OUT CHAR *ChlgText
);
BOOLEAN APPeerProbeReqSanity(
IN PRTMP_ADAPTER pAd,
IN VOID *Msg,
IN ULONG MsgLen,
OUT PUCHAR pAddr2,
OUT CHAR Ssid[],
OUT UCHAR *SsidLen);
BOOLEAN APPeerBeaconAndProbeRspSanity(
IN PRTMP_ADAPTER pAd,
IN VOID *Msg,
IN ULONG MsgLen,
OUT PUCHAR pAddr2,
OUT PUCHAR pBssid,
OUT CHAR Ssid[],
OUT UCHAR *SsidLen,
OUT UCHAR *BssType,
OUT USHORT *BeaconPeriod,
OUT UCHAR *Channel,
OUT LARGE_INTEGER *Timestamp,
OUT USHORT *CapabilityInfo,
OUT UCHAR Rate[],
OUT UCHAR *RateLen,
OUT BOOLEAN *ExtendedRateIeExist,
OUT UCHAR *Erp);
#if defined(RT30xx) || defined(RT305x)
VOID EnableAPMIMOPS(
IN PRTMP_ADAPTER pAd);
VOID DisableAPMIMOPS(
IN PRTMP_ADAPTER pAd);
#endif
#endif // __AP_H__

View file

@ -0,0 +1,276 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
ap_apcli.h
Abstract:
Miniport generic portion header file
Revision History:
Who When What
-------- ---------- ----------------------------------------------
Shiang, Fonchi 02-13-2007 created
*/
#ifndef _AP_APCLI_H_
#define _AP_APCLI_H_
#ifdef APCLI_SUPPORT
#include "rtmp.h"
#define AUTH_TIMEOUT 300 // unit: msec
#define ASSOC_TIMEOUT 300 // unit: msec
//#define JOIN_TIMEOUT 2000 // unit: msec // not used in Ap-client mode, remove it
#define PROBE_TIMEOUT 1000 // unit: msec
#define APCLI_ROOT_BSSID_GET(pAd, wcid) ((pAd)->MacTab.Content[(wcid)].Addr)
#define APCLI_IF_UP_CHECK(pAd, ifidx) ((pAd)->ApCfg.ApCliTab[(ifidx)].dev->flags & IFF_UP)
/* sanity check for apidx */
#define APCLI_MR_APIDX_SANITY_CHECK(idx) \
{ \
if ((idx) >= MAX_APCLI_NUM) \
{ \
(idx) = 0; \
DBGPRINT(RT_DEBUG_ERROR, ("%s> Error! apcli-idx > MAX_APCLI_NUM!\n", __FUNCTION__)); \
} \
}
typedef struct _APCLI_MLME_JOIN_REQ_STRUCT {
UCHAR Bssid[MAC_ADDR_LEN];
UCHAR SsidLen;
UCHAR Ssid[MAX_LEN_OF_SSID];
} APCLI_MLME_JOIN_REQ_STRUCT;
typedef struct _STA_CTRL_JOIN_REQ_STRUCT {
USHORT Status;
} APCLI_CTRL_MSG_STRUCT, *PSTA_CTRL_MSG_STRUCT;
BOOLEAN isValidApCliIf(
SHORT ifIndex);
//
// Private routines in apcli_ctrl.c
//
VOID ApCliCtrlStateMachineInit(
IN PRTMP_ADAPTER pAd,
IN STATE_MACHINE_EX *Sm,
OUT STATE_MACHINE_FUNC_EX Trans[]);
//
// Private routines in apcli_sync.c
//
VOID ApCliSyncStateMachineInit(
IN PRTMP_ADAPTER pAd,
IN STATE_MACHINE_EX *Sm,
OUT STATE_MACHINE_FUNC_EX Trans[]);
//
// Private routines in apcli_auth.c
//
VOID ApCliAuthStateMachineInit(
IN PRTMP_ADAPTER pAd,
IN STATE_MACHINE_EX *Sm,
OUT STATE_MACHINE_FUNC_EX Trans[]);
//
// Private routines in apcli_assoc.c
//
VOID ApCliAssocStateMachineInit(
IN PRTMP_ADAPTER pAd,
IN STATE_MACHINE_EX *Sm,
OUT STATE_MACHINE_FUNC_EX Trans[]);
MAC_TABLE_ENTRY *ApCliTableLookUpByWcid(
IN PRTMP_ADAPTER pAd,
IN UCHAR wcid,
IN PUCHAR pAddrs);
BOOLEAN ApCliAllowToSendPacket(
IN RTMP_ADAPTER *pAd,
IN PNDIS_PACKET pPacket,
OUT UCHAR *pWcid);
BOOLEAN ApCliValidateRSNIE(
IN PRTMP_ADAPTER pAd,
IN PEID_STRUCT pEid_ptr,
IN USHORT eid_len,
IN USHORT idx);
VOID RT28xx_ApCli_Init(
IN PRTMP_ADAPTER pAd,
IN PNET_DEV pPhyNetDev);
VOID RT28xx_ApCli_Close(
IN PRTMP_ADAPTER pAd);
VOID RT28xx_ApCli_Remove(
IN PRTMP_ADAPTER pAd);
VOID RT28xx_ApCli_Remove(
IN PRTMP_ADAPTER ad_p);
INT ApCliIfLookUp(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pAddr);
INT ApCli_VirtualIF_Open(
IN PNET_DEV dev_p);
INT ApCli_VirtualIF_Close(
IN PNET_DEV dev_p);
INT ApCli_VirtualIF_PacketSend(
IN PNDIS_PACKET skb_p,
IN PNET_DEV dev_p);
INT ApCli_VirtualIF_Ioctl(
IN PNET_DEV dev_p,
IN OUT struct ifreq *rq_p,
IN INT cmd);
VOID ApCliMgtMacHeaderInit(
IN PRTMP_ADAPTER pAd,
IN OUT PHEADER_802_11 pHdr80211,
IN UCHAR SubType,
IN UCHAR ToDs,
IN PUCHAR pDA,
IN PUCHAR pBssid,
IN USHORT ifIndex);
#ifdef DOT11_N_SUPPORT
BOOLEAN ApCliCheckHt(
IN PRTMP_ADAPTER pAd,
IN USHORT IfIndex,
IN OUT HT_CAPABILITY_IE *pHtCapability,
IN OUT ADD_HT_INFO_IE *pAddHtInfo);
#endif // DOT11_N_SUPPORT //
BOOLEAN ApCliLinkUp(
IN PRTMP_ADAPTER pAd,
IN UCHAR ifIndex);
VOID ApCliLinkDown(
IN PRTMP_ADAPTER pAd,
IN UCHAR ifIndex);
VOID ApCliIfUp(
IN PRTMP_ADAPTER pAd);
VOID ApCliIfDown(
IN PRTMP_ADAPTER pAd);
VOID ApCliIfMonitor(
IN PRTMP_ADAPTER pAd);
BOOLEAN ApCliMsgTypeSubst(
IN PRTMP_ADAPTER pAd,
IN PFRAME_802_11 pFrame,
OUT INT *Machine,
OUT INT *MsgType);
BOOLEAN preCheckMsgTypeSubset(
IN PRTMP_ADAPTER pAd,
IN PFRAME_802_11 pFrame,
OUT INT *Machine,
OUT INT *MsgType);
BOOLEAN ApCliPeerAssocRspSanity(
IN PRTMP_ADAPTER pAd,
IN VOID *pMsg,
IN ULONG MsgLen,
OUT PUCHAR pAddr2,
OUT USHORT *pCapabilityInfo,
OUT USHORT *pStatus,
OUT USHORT *pAid,
OUT UCHAR SupRate[],
OUT UCHAR *pSupRateLen,
OUT UCHAR ExtRate[],
OUT UCHAR *pExtRateLen,
OUT HT_CAPABILITY_IE *pHtCapability,
OUT ADD_HT_INFO_IE *pAddHtInfo, // AP might use this additional ht info IE
OUT UCHAR *pHtCapabilityLen,
OUT UCHAR *pAddHtInfoLen,
OUT UCHAR *pNewExtChannelOffset,
OUT PEDCA_PARM pEdcaParm,
OUT UCHAR *pCkipFlag);
VOID ApCliPeerPairMsg1Action(
IN PRTMP_ADAPTER pAd,
IN MAC_TABLE_ENTRY *pEntry,
IN MLME_QUEUE_ELEM *Elem);
VOID ApCliPeerPairMsg3Action(
IN PRTMP_ADAPTER pAd,
IN MAC_TABLE_ENTRY *pEntry,
IN MLME_QUEUE_ELEM *Elem);
VOID ApCliPeerGroupMsg1Action(
IN PRTMP_ADAPTER pAd,
IN MAC_TABLE_ENTRY *pEntry,
IN MLME_QUEUE_ELEM *Elem);
BOOLEAN ApCliCheckRSNIE(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pData,
IN UCHAR DataLen,
IN MAC_TABLE_ENTRY *pEntry,
OUT UCHAR *Offset);
BOOLEAN ApCliParseKeyData(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pKeyData,
IN UCHAR KeyDataLen,
IN MAC_TABLE_ENTRY *pEntry,
IN UCHAR IfIdx,
IN UCHAR bPairewise);
BOOLEAN ApCliHandleRxBroadcastFrame(
IN PRTMP_ADAPTER pAd,
IN RX_BLK *pRxBlk,
IN MAC_TABLE_ENTRY *pEntry,
IN UCHAR FromWhichBSSID);
VOID APCliUpdatePairwiseKeyTable(
IN PRTMP_ADAPTER pAd,
IN UCHAR *KeyRsc,
IN MAC_TABLE_ENTRY *pEntry);
BOOLEAN APCliUpdateSharedKeyTable(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pKey,
IN UCHAR KeyLen,
IN UCHAR DefaultKeyIdx,
IN MAC_TABLE_ENTRY *pEntry);
#endif // APCLI_SUPPORT //
#endif /* _AP_APCLI_H_ */

View file

@ -0,0 +1,79 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
ap_autoChSel.h
Abstract:
Miniport generic portion header file
Revision History:
Who When What
-------- ---------- ----------------------------------------------
*/
#include "ap_autoChSel_cmm.h"
#ifndef __AUTOCHSELECT_H__
#define __AUTOCHSELECT_H__
#ifdef AUTO_CH_SELECT_ENHANCE
#define AP_AUTO_CH_SEL(__P, __O) New_APAutoSelectChannel((__P), (__O))
#else
#define AP_AUTO_CH_SEL(__P, __O) APAutoSelectChannel((__P), (__O))
#endif
ULONG AutoChBssInsertEntry(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pBssid,
IN CHAR Ssid[],
IN UCHAR SsidLen,
IN UCHAR ChannelNo,
IN UCHAR ExtChOffset,
IN CHAR Rssi);
void AutoChBssTableInit(
IN PRTMP_ADAPTER pAd);
void ChannelInfoInit(
IN PRTMP_ADAPTER pAd);
void AutoChBssTableDestroy(
IN PRTMP_ADAPTER pAd);
void ChannelInfoDestroy(
IN PRTMP_ADAPTER pAd);
UCHAR New_APAutoSelectChannel(
IN PRTMP_ADAPTER pAd,
IN BOOLEAN Optimal);
UCHAR APAutoSelectChannel(
IN PRTMP_ADAPTER pAd,
IN BOOLEAN Optimal);
#endif // __AUTOCHSELECT_H__ //

View file

@ -0,0 +1,66 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
ap_autoChSel_cmm.h
Abstract:
Miniport generic portion header file
Revision History:
Who When What
-------- ---------- ----------------------------------------------
*/
#ifndef __AUTOCHSELECT_CMM_H__
#define __AUTOCHSELECT_CMM_H__
#define RSSI_TO_DBM_OFFSET 120 // RSSI-115 = dBm
typedef struct {
ULONG dirtyness[MAX_NUM_OF_CHANNELS+1];
ULONG max_rssi[MAX_NUM_OF_CHANNELS+1];
ULONG total_rssi[MAX_NUM_OF_CHANNELS+1];
UINT32 FalseCCA[MAX_NUM_OF_CHANNELS+1];
} CHANNELINFO, *PCHANNELINFO;
typedef struct {
UCHAR Bssid[MAC_ADDR_LEN];
UCHAR SsidLen;
CHAR Ssid[MAX_LEN_OF_SSID];
UCHAR Channel;
UCHAR ExtChOffset;
UCHAR Rssi;
} BSSENTRY, *PBSSENTRY;
typedef struct {
UCHAR BssNr;
BSSENTRY BssEntry[MAX_LEN_OF_BSS_TABLE];
} BSSINFO, *PBSSINFO;
#endif // __AUTOCHSELECT_CMM_H__ //

View file

@ -0,0 +1,118 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
ap_cfg.h
Abstract:
Miniport generic portion header file
Revision History:
Who When What
-------- ---------- ----------------------------------------------
*/
#ifndef __AP_CFG_H__
#define __AP_CFG_H__
#include "rt_config.h"
INT RTMPAPPrivIoctlSet(
IN RTMP_ADAPTER *pAd,
IN struct iwreq *pIoctlCmdStr);
INT RTMPAPPrivIoctlShow(
IN RTMP_ADAPTER *pAd,
IN struct iwreq *pIoctlCmdStr);
INT RTMPAPSetInformation(
IN PRTMP_ADAPTER pAd,
IN OUT struct iwreq *rq,
IN INT cmd);
INT RTMPAPQueryInformation(
IN PRTMP_ADAPTER pAd,
IN OUT struct iwreq *rq,
IN INT cmd);
VOID RTMPIoctlStatistics(
IN PRTMP_ADAPTER pAd,
IN struct iwreq *wrq);
VOID RTMPIoctlGetMacTable(
IN PRTMP_ADAPTER pAd,
IN struct iwreq *wrq);
#ifdef DBG
VOID RTMPAPIoctlBBP(
IN PRTMP_ADAPTER pAdapter,
IN struct iwreq *wrq);
VOID RTMPAPIoctlMAC(
IN PRTMP_ADAPTER pAdapter,
IN struct iwreq *wrq);
VOID RTMPAPIoctlE2PROM(
IN PRTMP_ADAPTER pAdapter,
IN struct iwreq *wrq);
#ifdef RTMP_RF_RW_SUPPORT
VOID RTMPAPIoctlRF(
IN PRTMP_ADAPTER pAdapter,
IN struct iwreq *wrq);
#endif // RTMP_RF_RW_SUPPORT //
#endif // DBG //
VOID RT28XX_IOCTL_MaxRateGet(
IN RTMP_ADAPTER *pAd,
IN PHTTRANSMIT_SETTING pHtPhyMode,
OUT UINT32 *pRate);
#ifdef DOT11_N_SUPPORT
VOID RTMPIoctlQueryBaTable(
IN PRTMP_ADAPTER pAd,
IN struct iwreq *wrq);
#endif // DOT11_N_SUPPORT //
VOID RTMPIoctlStaticWepCopy(
IN PRTMP_ADAPTER pAd,
IN struct iwreq *wrq);
VOID RTMPIoctlRadiusData(
IN PRTMP_ADAPTER pAd,
IN struct iwreq *wrq);
VOID RTMPIoctlAddWPAKey(
IN PRTMP_ADAPTER pAd,
IN struct iwreq *wrq);
VOID RTMPIoctlAddPMKIDCache(
IN PRTMP_ADAPTER pAd,
IN struct iwreq *wrq);
#endif // __AP_CFG_H__ //

View file

@ -0,0 +1,82 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
ap_ids.h
Abstract:
Miniport generic portion header file
Revision History:
Who When What
-------- ---------- ----------------------------------------------
*/
VOID RTMPIdsPeriodicExec(
IN PVOID SystemSpecific1,
IN PVOID FunctionContext,
IN PVOID SystemSpecific2,
IN PVOID SystemSpecific3);
BOOLEAN RTMPSpoofedMgmtDetection(
IN PRTMP_ADAPTER pAd,
IN PHEADER_802_11 pHeader,
IN CHAR Rssi0,
IN CHAR Rssi1,
IN CHAR Rssi2);
VOID RTMPConflictSsidDetection(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pSsid,
IN UCHAR SsidLen,
IN CHAR Rssi0,
IN CHAR Rssi1,
IN CHAR Rssi2);
BOOLEAN RTMPReplayAttackDetection(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pAddr2,
IN CHAR Rssi0,
IN CHAR Rssi1,
IN CHAR Rssi2);
VOID RTMPUpdateStaMgmtCounter(
IN PRTMP_ADAPTER pAd,
IN USHORT type);
VOID RTMPClearAllIdsCounter(
IN PRTMP_ADAPTER pAd);
VOID RTMPIdsStart(
IN PRTMP_ADAPTER pAd);
VOID RTMPIdsStop(
IN PRTMP_ADAPTER pAd);
VOID rtmp_read_ids_from_file(
IN PRTMP_ADAPTER pAd,
char *tmpbuf,
char *buffer);

View file

@ -0,0 +1,72 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
ap_mbss.h
Abstract:
Miniport generic portion header file
Revision History:
Who When What
-------- ---------- ----------------------------------------------
*/
#ifndef MODULE_MBSS
#define MBSS_EXTERN extern
#else
#define MBSS_EXTERN
#endif // MODULE_MBSS //
/* Public function list */
MBSS_EXTERN VOID RT28xx_MBSS_Init(
IN PRTMP_ADAPTER ad_p,
IN PNET_DEV main_dev_p);
MBSS_EXTERN VOID RT28xx_MBSS_Close(
IN PRTMP_ADAPTER ad_p);
MBSS_EXTERN VOID RT28xx_MBSS_Remove(
IN PRTMP_ADAPTER ad_p);
INT MBSS_VirtualIF_Open(
IN PNET_DEV dev_p);
INT MBSS_VirtualIF_Close(
IN PNET_DEV dev_p);
INT MBSS_VirtualIF_PacketSend(
IN PNDIS_PACKET skb_p,
IN PNET_DEV dev_p);
INT MBSS_VirtualIF_Ioctl(
IN PNET_DEV dev_p,
IN OUT struct ifreq *rq_p,
IN INT cmd);
/* End of ap_mbss.h */

View file

@ -0,0 +1,636 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
ap_uapsd.h
Abstract:
Miniport generic portion header file
Revision History:
Who When What
-------- ---------- ----------------------------------------------
*/
/* only for UAPSD_TIMING_RECORD */
//#define UAPSD_TIMING_RECORD_FUNC
#define UAPSD_TIMING_RECORD_MAX 1000
#define UAPSD_TIMING_RECORD_DISPLAY_TIMES 10
#define UAPSD_TIMING_RECORD_ISR 1
#define UAPSD_TIMING_RECORD_TASKLET 2
#define UAPSD_TIMING_RECORD_TRG_RCV 3
#define UAPSD_TIMING_RECORD_MOVE2TX 4
#define UAPSD_TIMING_RECORD_TX2AIR 5
#define UAPSD_TIMING_CTRL_STOP 0
#define UAPSD_TIMING_CTRL_START 1
#define UAPSD_TIMING_CTRL_SUSPEND 2
#define UAPSD_TIMESTAMP_GET(__pAd, __TimeStamp) \
{ \
UINT32 __CSR=0; UINT64 __Value64; \
RTMP_IO_READ32((__pAd), TSF_TIMER_DW0, &__CSR); \
__TimeStamp = (UINT64)__CSR; \
RTMP_IO_READ32((__pAd), TSF_TIMER_DW1, &__CSR); \
__Value64 = (UINT64)__CSR; \
__TimeStamp |= (__Value64 << 32); \
}
#ifdef LINUX
#define UAPSD_TIME_GET(__pAd, __Time) \
__Time = jiffies
#endif // LINUX //
#ifdef UAPSD_TIMING_RECORD_FUNC
#define UAPSD_TIMING_RECORD_START() \
UAPSD_TimingRecordCtrl(UAPSD_TIMING_CTRL_START);
#define UAPSD_TIMING_RECORD_STOP() \
UAPSD_TimingRecordCtrl(UAPSD_TIMING_CTRL_STOP);
#define UAPSD_TIMING_RECORD(__pAd, __Type) \
UAPSD_TimingRecord(__pAd, __Type);
#define UAPSD_TIMING_RECORD_INDEX(__LoopIndex) \
UAPSD_TimeingRecordLoopIndex(__LoopIndex);
#else
#define UAPSD_TIMING_RECORD_START()
#define UAPSD_TIMING_RECORD_STOP()
#define UAPSD_TIMING_RECORD(__pAd, __type)
#define UAPSD_TIMING_RECORD_INDEX(__LoopIndex)
#endif // UAPSD_TIMING_RECORD_FUNC //
#ifndef MODULE_WMM_UAPSD
#define UAPSD_EXTERN extern
/* Public Marco list */
/*
Init some parameters in packet structure for QoS Null frame;
purpose: is for management frame tx done use
*/
#define UAPSD_MR_QOS_NULL_HANDLE(__pAd, __pData, __pPacket) \
{ \
PHEADER_802_11 __pHeader = (PHEADER_802_11)(__pData); \
MAC_TABLE_ENTRY *__pEntry; \
if (__pHeader->FC.SubType == SUBTYPE_QOS_NULL) \
{ \
RTMP_SET_PACKET_QOS_NULL((__pPacket)); \
__pEntry = MacTableLookup((__pAd), __pHeader->Addr1); \
if (__pEntry != NULL) \
{ \
RTMP_SET_PACKET_WCID((__pPacket), __pEntry->Aid); \
} \
} \
else \
{ \
RTMP_SET_PACKET_NON_QOS_NULL((__pPacket)); \
} \
}
/*
Init MAC entry UAPSD parameters;
purpose: initialize UAPSD PS queue and control parameters
*/
#define UAPSD_MR_ENTRY_INIT(__pEntry) \
{ \
UINT16 __IdAc; \
for(__IdAc=0; __IdAc<WMM_NUM_OF_AC; __IdAc++) \
InitializeQueueHeader(&(__pEntry)->UAPSDQueue[__IdAc]); \
(__pEntry)->UAPSDTxNum = 0; \
(__pEntry)->pUAPSDEOSPFrame = NULL; \
(__pEntry)->bAPSDFlagSPStart = 0; \
(__pEntry)->bAPSDFlagEOSPOK = 0; \
(__pEntry)->MaxSPLength = 0; \
}
/*
Reset MAC entry UAPSD parameters;
purpose: clean all UAPSD PS queue; release the EOSP frame if exists;
reset control parameters
*/
#define UAPSD_MR_ENTRY_RESET(__pAd, __pEntry) \
{ \
MAC_TABLE_ENTRY *__pSta; \
UINT32 __IdAc; \
__pSta = (__pEntry); \
/* clear all U-APSD queues */ \
for(__IdAc=0; __IdAc<WMM_NUM_OF_AC; __IdAc++) \
APCleanupPsQueue((__pAd), &__pSta->UAPSDQueue[__IdAc]); \
/* clear EOSP frame */ \
__pSta->UAPSDTxNum = 0; \
if (__pSta->pUAPSDEOSPFrame != NULL) { \
RELEASE_NDIS_PACKET((__pAd), \
QUEUE_ENTRY_TO_PACKET(__pSta->pUAPSDEOSPFrame), \
NDIS_STATUS_FAILURE); \
__pSta->pUAPSDEOSPFrame = NULL; } \
__pSta->bAPSDFlagSPStart = 0; \
__pSta->bAPSDFlagEOSPOK = 0; }
/*
Enable or disable UAPSD flag in WMM element in beacon frame;
purpose: set UAPSD enable/disable bit
*/
#define UAPSD_MR_IE_FILL(__QosCtrlField, __pAd) \
(__QosCtrlField) |= ((__pAd)->CommonCfg.bAPSDCapable) ? 0x80 : 0x00;
/*
Check if we do NOT need to control TIM bit for the station;
note: we control TIM bit only when all AC are UAPSD AC
*/
#define UAPSD_MR_IS_NOT_TIM_BIT_NEEDED_HANDLED(__pMacEntry, __QueIdx) \
(CLIENT_STATUS_TEST_FLAG((__pMacEntry), fCLIENT_STATUS_APSD_CAPABLE) && \
(!(__pMacEntry)->bAPSDDeliverEnabledPerAC[QID_AC_VO] || \
!(__pMacEntry)->bAPSDDeliverEnabledPerAC[QID_AC_VI] || \
!(__pMacEntry)->bAPSDDeliverEnabledPerAC[QID_AC_BE] || \
!(__pMacEntry)->bAPSDDeliverEnabledPerAC[QID_AC_BK]) && \
(__pMacEntry)->bAPSDDeliverEnabledPerAC[__QueIdx])
/* check if the AC is UAPSD delivery-enabled AC */
#define UAPSD_MR_IS_UAPSD_AC(__pMacEntry, __AcId) \
(CLIENT_STATUS_TEST_FLAG((__pMacEntry), fCLIENT_STATUS_APSD_CAPABLE) && \
((0 <= (__AcId)) && ((__AcId) < WMM_NUM_OF_AC)) && /* 0 ~ 3 */ \
(__pMacEntry)->bAPSDDeliverEnabledPerAC[(__AcId)])
/* check if all AC are UAPSD delivery-enabled AC */
#define UAPSD_MR_IS_ALL_AC_UAPSD(__FlgIsActive, __pMacEntry) \
(((__FlgIsActive) == FALSE) && ((__pMacEntry)->bAPSDAllAC == 1))
/* suspend SP */
#define UAPSD_MR_SP_SUSPEND(__pAd) \
(__pAd)->bAPSDFlagSPSuspend = 1;
/* resume SP */
#define UAPSD_MR_SP_RESUME(__pAd) \
(__pAd)->bAPSDFlagSPSuspend = 0;
/* mark PS poll frame sent in mix mode */
#ifdef RTMP_MAC_PCI
/*
Note:
(1) When SP is not started, try to mark a flag to record if the legacy ps
packet is handled in statistics handler;
(2) When SP is started, increase the UAPSD count number for the legacy PS.
*/
#define UAPSD_MR_MIX_PS_POLL_RCV(__pAd, __pMacEntry) \
if ((__pMacEntry)->bAPSDFlagSpRoughUse == 0) \
{ \
if ((__pMacEntry)->bAPSDFlagSPStart == 0) \
{ \
if ((__pMacEntry)->bAPSDFlagLegacySent == 1) \
NICUpdateFifoStaCounters((__pAd)); \
(__pMacEntry)->bAPSDFlagLegacySent = 1; \
} \
else \
{ \
(__pMacEntry)->UAPSDTxNum ++; \
} \
}
#endif // RTMP_MAC_PCI //
#else
#define UAPSD_EXTERN
#define UAPSD_QOS_NULL_QUE_ID 0x7f
#ifdef RTMP_MAC_PCI
/*
In RT2870, FIFO counter is for all stations, not for per-entry,
so we can not use accurate method in RT2870
*/
/*
Note for SP ACCURATE Mechanism:
1. When traffic is busy for the PS station
Statistics FIFO counter maybe overflow before we read it, so UAPSD
counting mechanism will not accurately.
Solution:
We need to avoid the worse case so we suggest a maximum interval for
a SP that the interval between last frame from QAP and data frame from
QSTA is larger than UAPSD_EPT_SP_INT.
2. When traffic use CCK/1Mbps from QAP
Statistics FIFO will not count the packet. There are 2 cases:
(1) We force to downgrage ARP response & DHCP packet to 1Mbps;
(2) After rate switch mechanism, tx rate is fixed to 1Mbps.
Solution:
Use old DMA UAPSD mechanism.
3. When part of AC uses legacy PS mode
Statistics count will inclue packet statistics for legacy PS packets
so we can not know which one is UAPSD, which one is legacy.
Solution:
Cound the legacy PS packet.
4. Check FIFO statistics count in Rx Done function
We can not to check TX FIFO statistics count in Rx Done function or
the real packet tx/rx sequence will be disarranged.
Solution:
Suspend SP handle before rx done and resume SP handle after rx done.
*/
#define UAPSD_SP_ACCURATE /* use more accurate method to send EOSP */
#endif // RTMP_MAC_PCI //
#define UAPSD_EPT_SP_INT (100000/(1000000/OS_HZ)) /* 100ms */
#endif // MODULE_WMM_UAPSD //
/* max UAPSD buffer queue size */
#define MAX_PACKETS_IN_UAPSD_QUEUE 16 /* for each AC = 16*4 = 64 */
/* Public function list */
/*
========================================================================
Routine Description:
UAPSD Module Init.
Arguments:
pAd Pointer to our adapter
Return Value:
None
Note:
========================================================================
*/
UAPSD_EXTERN VOID UAPSD_Init(
IN PRTMP_ADAPTER pAd);
/*
========================================================================
Routine Description:
UAPSD Module Release.
Arguments:
pAd Pointer to our adapter
Return Value:
None
Note:
========================================================================
*/
UAPSD_EXTERN VOID UAPSD_Release(
IN PRTMP_ADAPTER pAd);
/*
========================================================================
Routine Description:
Free all EOSP frames and close all SP.
Arguments:
pAd Pointer to our adapter
Return Value:
None
Note:
========================================================================
*/
UAPSD_EXTERN VOID UAPSD_FreeAll(
IN PRTMP_ADAPTER pAd);
/*
========================================================================
Routine Description:
Close current Service Period.
Arguments:
pAd Pointer to our adapter
pEntry Close the SP of the entry
Return Value:
None
Note:
========================================================================
*/
UAPSD_EXTERN VOID UAPSD_SP_Close(
IN PRTMP_ADAPTER pAd,
IN MAC_TABLE_ENTRY *pEntry);
/*
========================================================================
Routine Description:
Deliver all queued packets.
Arguments:
pAd Pointer to our adapter
*pEntry STATION
Return Value:
None
Note:
SMP protection by caller for packet enqueue.
========================================================================
*/
UAPSD_EXTERN VOID UAPSD_AllPacketDeliver(
IN PRTMP_ADAPTER pAd,
IN MAC_TABLE_ENTRY *pEntry);
/*
========================================================================
Routine Description:
Parse the UAPSD field in WMM element in (re)association request frame.
Arguments:
pAd Pointer to our adapter
*pEntry STATION
*pElm QoS information field
Return Value:
None
Note:
No protection is needed.
1. Association -> TSPEC:
use static UAPSD settings in Association
update UAPSD settings in TSPEC
2. Association -> TSPEC(11r) -> Reassociation:
update UAPSD settings in TSPEC
backup static UAPSD settings in Reassociation
3. Association -> Reassociation:
update UAPSD settings in TSPEC
backup static UAPSD settings in Reassociation
========================================================================
*/
UAPSD_EXTERN VOID UAPSD_AssocParse(
IN PRTMP_ADAPTER pAd,
IN MAC_TABLE_ENTRY *pEntry,
IN UCHAR *pElm);
/*
========================================================================
Routine Description:
Enqueue a UAPSD packet.
Arguments:
pAd Pointer to our adapter
*pEntry STATION
pPacket UAPSD dnlink packet
IdAc UAPSD AC ID (0 ~ 3)
Return Value:
None
Note:
========================================================================
*/
UAPSD_EXTERN VOID UAPSD_PacketEnqueue(
IN PRTMP_ADAPTER pAd,
IN MAC_TABLE_ENTRY *pEntry,
IN PNDIS_PACKET pPacket,
IN UINT32 IdAc);
/*
========================================================================
Routine Description:
Handle QoS Null Frame Tx Done or Management Tx Done interrupt.
Arguments:
pAd Pointer to our adapter
pPacket Completed TX packet
pDstMac Destinated MAC address
Return Value:
None
Note:
========================================================================
*/
UAPSD_EXTERN VOID UAPSD_QoSNullTxMgmtTxDoneHandle(
IN PRTMP_ADAPTER pAd,
IN PNDIS_PACKET pPacket,
IN UCHAR *pDstMac);
/*
========================================================================
Routine Description:
Maintenance our UAPSD PS queue. Release all queued packet if timeout.
Arguments:
pAd Pointer to our adapter
*pEntry STATION
Return Value:
None
Note:
If in RT2870, pEntry can not be removed during UAPSD_QueueMaintenance()
========================================================================
*/
UAPSD_EXTERN VOID UAPSD_QueueMaintenance(
IN PRTMP_ADAPTER pAd,
IN MAC_TABLE_ENTRY *pEntry);
/*
========================================================================
Routine Description:
Close SP in Tx Done, not Tx DMA Done.
Arguments:
pAd Pointer to our adapter
pEntry destination entry
FlgSuccess 0:tx success, 1:tx fail
Return Value:
None
Note:
For RT28xx series, for packetID=0 or multicast frame, no statistics
count can be got, ex: ARP response or DHCP packets, we will use
low rate to set (CCK, MCS=0=packetID).
So SP will not be close until UAPSD_EPT_SP_INT timeout.
So if the tx rate is 1Mbps for a entry, we will use DMA done, not
use UAPSD_SP_AUE_Handle().
========================================================================
*/
UAPSD_EXTERN VOID UAPSD_SP_AUE_Handle(
IN RTMP_ADAPTER *pAd,
IN MAC_TABLE_ENTRY *pEntry,
IN UCHAR FlgSuccess);
/*
========================================================================
Routine Description:
Close current Service Period.
Arguments:
pAd Pointer to our adapter
Return Value:
None
Note:
When we receive EOSP frame tx done interrupt and a uplink packet
from the station simultaneously, we will regard it as a new trigger
frame because the packet is received when EOSP frame tx done interrupt.
We can not sure the uplink packet is sent after old SP or in the old SP.
So we must close the old SP in receive done ISR to avoid the problem.
========================================================================
*/
UAPSD_EXTERN VOID UAPSD_SP_CloseInRVDone(
IN PRTMP_ADAPTER pAd);
/*
========================================================================
Routine Description:
Check if we need to close current SP.
Arguments:
pAd Pointer to our adapter
pPacket Completed TX packet
pDstMac Destinated MAC address
Return Value:
None
Note:
1. We need to call the function in TxDone ISR.
2. SMP protection by caller for packet enqueue.
========================================================================
*/
UAPSD_EXTERN VOID UAPSD_SP_PacketCheck(
IN PRTMP_ADAPTER pAd,
IN PNDIS_PACKET pPacket,
IN UCHAR *pDstMac);
#ifdef UAPSD_TIMING_RECORD_FUNC
/*
========================================================================
Routine Description:
Enable/Disable Timing Record Function.
Arguments:
pAd Pointer to our adapter
Flag 1 (Enable) or 0 (Disable)
Return Value:
None
Note:
========================================================================
*/
UAPSD_EXTERN VOID UAPSD_TimingRecordCtrl(
IN UINT32 Flag);
/*
========================================================================
Routine Description:
Record some timings.
Arguments:
pAd Pointer to our adapter
Type The timing is for what type
Return Value:
None
Note:
UAPSD_TIMING_RECORD_ISR
UAPSD_TIMING_RECORD_TASKLET
UAPSD_TIMING_RECORD_TRG_RCV
UAPSD_TIMING_RECORD_MOVE2TX
UAPSD_TIMING_RECORD_TX2AIR
========================================================================
*/
UAPSD_EXTERN VOID UAPSD_TimingRecord(
IN PRTMP_ADAPTER pAd,
IN UINT32 Type);
/*
========================================================================
Routine Description:
Record the loop index for received packet handle.
Arguments:
pAd Pointer to our adapter
LoopIndex The RxProcessed in APRxDoneInterruptHandle()
Return Value:
None
Note:
========================================================================
*/
UAPSD_EXTERN VOID UAPSD_TimeingRecordLoopIndex(
IN UINT32 LoopIndex);
#endif // UAPSD_TIMING_RECORD_FUNC //
/*
========================================================================
Routine Description:
Handle UAPSD Trigger Frame.
Arguments:
pAd Pointer to our adapter
*pEntry the source STATION
UpOfFrame the UP of the trigger frame
Return Value:
None
Note:
========================================================================
*/
UAPSD_EXTERN VOID UAPSD_TriggerFrameHandle(
IN PRTMP_ADAPTER pAd,
IN MAC_TABLE_ENTRY *pEntry,
IN UCHAR UpOfFrame);
/* End of ap_uapsd.h */

View file

@ -0,0 +1,212 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
ap_cfg.h
Abstract:
Miniport generic portion header file
Revision History:
Who When What
-------- ---------- ----------------------------------------------
Fonchi 02-13-2007 created
*/
#ifndef _AP_WDS_H_
#define _AP_WDS_H_
#define WDS_ENTRY_RETRY_INTERVAL (100 * OS_HZ / 1000)
static inline BOOLEAN WDS_IF_UP_CHECK(
IN PRTMP_ADAPTER pAd,
IN ULONG ifidx)
{
if ((pAd->flg_wds_init != TRUE) ||
(ifidx >= MAX_WDS_ENTRY))
return FALSE;
// if (pAd->WdsTab.WdsEntry[ifidx].dev->flags & IFF_UP)
// Patch for wds ,when dirver call apmlmeperiod => APMlmeDynamicTxRateSwitching check if wds device ready
if ((pAd->WdsTab.WdsEntry[ifidx].dev != NULL) && (pAd->WdsTab.WdsEntry[ifidx].dev->flags & IFF_UP))
return TRUE;
return FALSE;
}
LONG WdsEntryAlloc(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pAddr);
VOID WdsEntryDel(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pAddr);
MAC_TABLE_ENTRY *MacTableInsertWDSEntry(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pAddr,
UINT WdsTabIdx);
BOOLEAN MacTableDeleteWDSEntry(
IN PRTMP_ADAPTER pAd,
IN USHORT wcid,
IN PUCHAR pAddr);
BOOLEAN ApWdsAllowToSendPacket(
IN RTMP_ADAPTER *pAd,
IN PNDIS_PACKET pPacket,
OUT UCHAR *pWcid);
MAC_TABLE_ENTRY *WdsTableLookupByWcid(
IN PRTMP_ADAPTER pAd,
IN UCHAR wcid,
IN PUCHAR pAddr,
IN BOOLEAN bResetIdelCount);
MAC_TABLE_ENTRY *WdsTableLookup(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pAddr,
IN BOOLEAN bResetIdelCount);
MAC_TABLE_ENTRY *FindWdsEntry(
IN PRTMP_ADAPTER pAd,
IN UCHAR Wcid,
IN PUCHAR pAddr,
IN UINT32 PhyMode);
VOID WdsTableMaintenance(
IN PRTMP_ADAPTER pAd);
VOID RT28xx_WDS_Init(
IN PRTMP_ADAPTER pAd,
IN PNET_DEV net_dev);
VOID RT28xx_WDS_Close(
IN PRTMP_ADAPTER pAd);
VOID RT28xx_WDS_Remove(
IN PRTMP_ADAPTER pAd);
VOID WdsDown(
IN PRTMP_ADAPTER pAd);
VOID AsicUpdateWdsRxWCIDTable(
IN PRTMP_ADAPTER pAd);
VOID AsicUpdateWdsEncryption(
IN PRTMP_ADAPTER pAd,
IN UCHAR wcid);
VOID WdsPeerBeaconProc(
IN PRTMP_ADAPTER pAd,
IN PMAC_TABLE_ENTRY pEntry,
IN USHORT CapabilityInfo,
IN UCHAR MaxSupportedRateIn500Kbps,
IN UCHAR MaxSupportedRateLen,
IN BOOLEAN bWmmCapable,
IN ULONG ClientRalinkIe,
IN HT_CAPABILITY_IE *pHtCapability,
IN UCHAR HtCapabilityLen);
VOID APWdsInitialize(
IN PRTMP_ADAPTER pAd);
INT Show_WdsTable_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
VOID rtmp_read_wds_from_file(
IN PRTMP_ADAPTER pAd,
PSTRING tmpbuf,
PSTRING buffer);
VOID WdsPrepareWepKeyFromMainBss(
IN PRTMP_ADAPTER pAd);
INT WdsVirtualIFSendPackets(
IN PNDIS_PACKET pSkb,
IN PNET_DEV dev);
INT WdsVirtualIF_open(
IN PNET_DEV dev);
INT WdsVirtualIF_close(
IN PNET_DEV dev);
INT WdsVirtualIF_ioctl(
IN PNET_DEV net_dev,
IN OUT struct ifreq *rq,
IN INT cmd);
/*
==========================================================================
Description:
Check the WDS Entry is valid or not.
==========================================================================
*/
static inline BOOLEAN ValidWdsEntry(
IN PRTMP_ADAPTER pAd,
IN UCHAR WdsIndex)
{
BOOLEAN result;
PMAC_TABLE_ENTRY pMacEntry;
do
{
if (WdsIndex >= MAX_WDS_ENTRY)
{
result = FALSE;
break;
}
if (pAd->WdsTab.WdsEntry[WdsIndex].Valid != TRUE)
{
result = FALSE;
break;
}
if ((pAd->WdsTab.WdsEntry[WdsIndex].MacTabMatchWCID==0)
|| (pAd->WdsTab.WdsEntry[WdsIndex].MacTabMatchWCID >= MAX_LEN_OF_MAC_TABLE))
{
result = FALSE;
break;
}
pMacEntry = &pAd->MacTab.Content[pAd->WdsTab.WdsEntry[WdsIndex].MacTabMatchWCID];
if (pMacEntry->ValidAsWDS != TRUE)
{
result = FALSE;
break;
}
result = TRUE;
} while(FALSE);
return result;
}
#endif // _AP_WDS_H_ //

View file

@ -0,0 +1,123 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
rt3090.c
Abstract:
Specific funcitons and variables for RT3070
Revision History:
Who When What
-------- ---------- ----------------------------------------------
*/
#ifdef RT3090
#include "../rt_config.h"
#ifndef RTMP_RF_RW_SUPPORT
#error "You Should Enable compile flag RTMP_RF_RW_SUPPORT for this chip"
#endif // RTMP_RF_RW_SUPPORT //
VOID NICInitRT3090RFRegisters(IN PRTMP_ADAPTER pAd)
{
INT i;
// Driver must read EEPROM to get RfIcType before initial RF registers
// Initialize RF register to default value
if (IS_RT3090(pAd))
{
// Init RF calibration
// Driver should toggle RF R30 bit7 before init RF registers
UINT32 RfReg = 0, data;
RT30xxReadRFRegister(pAd, RF_R30, (PUCHAR)&RfReg);
RfReg |= 0x80;
RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg);
RTMPusecDelay(1000);
RfReg &= 0x7F;
RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg);
// init R24, R31
RT30xxWriteRFRegister(pAd, RF_R24, 0x0F);
RT30xxWriteRFRegister(pAd, RF_R31, 0x0F);
// RT309x version E has fixed this issue
if ((pAd->NicConfig2.field.DACTestBit == 1) && ((pAd->MACVersion & 0xffff) < 0x0211))
{
// patch tx EVM issue temporarily
RTMP_IO_READ32(pAd, LDO_CFG0, &data);
data = ((data & 0xE0FFFFFF) | 0x0D000000);
RTMP_IO_WRITE32(pAd, LDO_CFG0, data);
}
else
{
RTMP_IO_READ32(pAd, LDO_CFG0, &data);
data = ((data & 0xE0FFFFFF) | 0x01000000);
RTMP_IO_WRITE32(pAd, LDO_CFG0, data);
}
// patch LNA_PE_G1 failed issue
RTMP_IO_READ32(pAd, GPIO_SWITCH, &data);
data &= ~(0x20);
RTMP_IO_WRITE32(pAd, GPIO_SWITCH, data);
// Initialize RF register to default value
for (i = 0; i < NUM_RF_REG_PARMS; i++)
{
RT30xxWriteRFRegister(pAd, RT30xx_RFRegTable[i].Register, RT30xx_RFRegTable[i].Value);
}
// Driver should set RF R6 bit6 on before calibration
RT30xxReadRFRegister(pAd, RF_R06, (PUCHAR)&RfReg);
RfReg |= 0x40;
RT30xxWriteRFRegister(pAd, RF_R06, (UCHAR)RfReg);
//For RF filter Calibration
RTMPFilterCalibration(pAd);
// Initialize RF R27 register, set RF R27 must be behind RTMPFilterCalibration()
if ((pAd->MACVersion & 0xffff) < 0x0211)
RT30xxWriteRFRegister(pAd, RF_R27, 0x3);
// set led open drain enable
RTMP_IO_READ32(pAd, OPT_14, &data);
data |= 0x01;
RTMP_IO_WRITE32(pAd, OPT_14, data);
// set default antenna as main
if (pAd->RfIcType == RFIC_3020)
AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
// add by johnli, RF power sequence setup, load RF normal operation-mode setup
RT30xxLoadRFNormalModeSetup(pAd);
}
}
#endif // RT3090 //

View file

@ -0,0 +1,525 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
rt30xx.c
Abstract:
Specific funcitons and variables for RT30xx.
Revision History:
Who When What
-------- ---------- ----------------------------------------------
*/
#ifdef RT30xx
#ifndef RTMP_RF_RW_SUPPORT
#error "You Should Enable compile flag RTMP_RF_RW_SUPPORT for this chip"
#endif // RTMP_RF_RW_SUPPORT //
#include "../rt_config.h"
//
// RF register initialization set
//
REG_PAIR RT30xx_RFRegTable[] = {
{RF_R04, 0x40},
{RF_R05, 0x03},
{RF_R06, 0x02},
{RF_R07, 0x70},
{RF_R09, 0x0F},
{RF_R10, 0x41},
{RF_R11, 0x21},
{RF_R12, 0x7B},
{RF_R14, 0x90},
{RF_R15, 0x58},
{RF_R16, 0xB3},
{RF_R17, 0x92},
{RF_R18, 0x2C},
{RF_R19, 0x02},
{RF_R20, 0xBA},
{RF_R21, 0xDB},
{RF_R24, 0x16},
{RF_R25, 0x01},
{RF_R29, 0x1F},
};
UCHAR NUM_RF_REG_PARMS = (sizeof(RT30xx_RFRegTable) / sizeof(REG_PAIR));
// Antenna divesity use GPIO3 and EESK pin for control
// Antenna and EEPROM access are both using EESK pin,
// Therefor we should avoid accessing EESK at the same time
// Then restore antenna after EEPROM access
// The original name of this function is AsicSetRxAnt(), now change to
//VOID AsicSetRxAnt(
VOID RT30xxSetRxAnt(
IN PRTMP_ADAPTER pAd,
IN UCHAR Ant)
{
UINT32 Value;
UINT32 x;
if ((pAd->EepromAccess) ||
(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) ||
(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) ||
(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) ||
(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
{
return;
}
// the antenna selection is through firmware and MAC register(GPIO3)
if (Ant == 0)
{
// Main antenna
#ifdef RTMP_MAC_PCI
RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
x |= (EESK);
RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
#else
AsicSendCommandToMcu(pAd, 0x73, 0xFF, 0x1, 0x0);
#endif // RTMP_MAC_PCI //
RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value);
Value &= ~(0x0808);
RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value);
DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicSetRxAnt, switch to main antenna\n"));
}
else
{
// Aux antenna
#ifdef RTMP_MAC_PCI
RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
x &= ~(EESK);
RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
#else
AsicSendCommandToMcu(pAd, 0x73, 0xFF, 0x0, 0x0);
#endif // RTMP_MAC_PCI //
RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value);
Value &= ~(0x0808);
Value |= 0x08;
RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value);
DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicSetRxAnt, switch to aux antenna\n"));
}
}
/*
========================================================================
Routine Description:
For RF filter calibration purpose
Arguments:
pAd Pointer to our adapter
Return Value:
None
IRQL = PASSIVE_LEVEL
========================================================================
*/
VOID RTMPFilterCalibration(
IN PRTMP_ADAPTER pAd)
{
UCHAR R55x = 0, value, FilterTarget = 0x1E, BBPValue=0;
UINT loop = 0, count = 0, loopcnt = 0, ReTry = 0;
UCHAR RF_R24_Value = 0;
// Give bbp filter initial value
pAd->Mlme.CaliBW20RfR24 = 0x1F;
pAd->Mlme.CaliBW40RfR24 = 0x2F; //Bit[5] must be 1 for BW 40
do
{
if (loop == 1) //BandWidth = 40 MHz
{
// Write 0x27 to RF_R24 to program filter
RF_R24_Value = 0x27;
RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
if (IS_RT3090(pAd) || IS_RT3572(pAd)|| IS_RT3390(pAd))
FilterTarget = 0x15;
else
FilterTarget = 0x19;
// when calibrate BW40, BBP mask must set to BW40.
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
BBPValue&= (~0x18);
BBPValue|= (0x10);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
// set to BW40
RT30xxReadRFRegister(pAd, RF_R31, &value);
value |= 0x20;
RT30xxWriteRFRegister(pAd, RF_R31, value);
}
else //BandWidth = 20 MHz
{
// Write 0x07 to RF_R24 to program filter
RF_R24_Value = 0x07;
RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
if (IS_RT3090(pAd) || IS_RT3572(pAd)|| IS_RT3390(pAd))
FilterTarget = 0x13;
else
FilterTarget = 0x16;
// set to BW20
RT30xxReadRFRegister(pAd, RF_R31, &value);
value &= (~0x20);
RT30xxWriteRFRegister(pAd, RF_R31, value);
}
// Write 0x01 to RF_R22 to enable baseband loopback mode
RT30xxReadRFRegister(pAd, RF_R22, &value);
value |= 0x01;
RT30xxWriteRFRegister(pAd, RF_R22, value);
// Write 0x00 to BBP_R24 to set power & frequency of passband test tone
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0);
do
{
// Write 0x90 to BBP_R25 to transmit test tone
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x90);
RTMPusecDelay(1000);
// Read BBP_R55[6:0] for received power, set R55x = BBP_R55[6:0]
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R55, &value);
R55x = value & 0xFF;
} while ((ReTry++ < 100) && (R55x == 0));
// Write 0x06 to BBP_R24 to set power & frequency of stopband test tone
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0x06);
while(TRUE)
{
// Write 0x90 to BBP_R25 to transmit test tone
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x90);
//We need to wait for calibration
RTMPusecDelay(1000);
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R55, &value);
value &= 0xFF;
if ((R55x - value) < FilterTarget)
{
RF_R24_Value ++;
}
else if ((R55x - value) == FilterTarget)
{
RF_R24_Value ++;
count ++;
}
else
{
break;
}
// prevent infinite loop cause driver hang.
if (loopcnt++ > 100)
{
DBGPRINT(RT_DEBUG_ERROR, ("RTMPFilterCalibration - can't find a valid value, loopcnt=%d stop calibrating", loopcnt));
break;
}
// Write RF_R24 to program filter
RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
}
if (count > 0)
{
RF_R24_Value = RF_R24_Value - ((count) ? (1) : (0));
}
// Store for future usage
if (loopcnt < 100)
{
if (loop++ == 0)
{
//BandWidth = 20 MHz
pAd->Mlme.CaliBW20RfR24 = (UCHAR)RF_R24_Value;
}
else
{
//BandWidth = 40 MHz
pAd->Mlme.CaliBW40RfR24 = (UCHAR)RF_R24_Value;
break;
}
}
else
break;
RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
// reset count
count = 0;
} while(TRUE);
//
// Set back to initial state
//
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0);
RT30xxReadRFRegister(pAd, RF_R22, &value);
value &= ~(0x01);
RT30xxWriteRFRegister(pAd, RF_R22, value);
// set BBP back to BW20
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
BBPValue&= (~0x18);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
DBGPRINT(RT_DEBUG_TRACE, ("RTMPFilterCalibration - CaliBW20RfR24=0x%x, CaliBW40RfR24=0x%x\n", pAd->Mlme.CaliBW20RfR24, pAd->Mlme.CaliBW40RfR24));
}
// add by johnli, RF power sequence setup
/*
==========================================================================
Description:
Load RF normal operation-mode setup
==========================================================================
*/
VOID RT30xxLoadRFNormalModeSetup(
IN PRTMP_ADAPTER pAd)
{
UCHAR RFValue;
// RX0_PD & TX0_PD, RF R1 register Bit 2 & Bit 3 to 0 and RF_BLOCK_en,RX1_PD & TX1_PD, Bit0, Bit 4 & Bit5 to 1
RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
RFValue = (RFValue & (~0x0C)) | 0x31;
RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
// TX_LO2_en, RF R15 register Bit 3 to 0
RT30xxReadRFRegister(pAd, RF_R15, &RFValue);
RFValue &= (~0x08);
RT30xxWriteRFRegister(pAd, RF_R15, RFValue);
/* move to NICInitRT30xxRFRegisters
// TX_LO1_en, RF R17 register Bit 3 to 0
RT30xxReadRFRegister(pAd, RF_R17, &RFValue);
RFValue &= (~0x08);
// to fix rx long range issue
if (((pAd->MACVersion & 0xffff) >= 0x0211) && (pAd->NicConfig2.field.ExternalLNAForG == 0))
{
RFValue |= 0x20;
}
// set RF_R17_bit[2:0] equal to EEPROM setting at 0x48h
if (pAd->TxMixerGain24G >= 2)
{
RFValue &= (~0x7); // clean bit [2:0]
RFValue |= pAd->TxMixerGain24G;
}
RT30xxWriteRFRegister(pAd, RF_R17, RFValue);
*/
// RX_LO1_en, RF R20 register Bit 3 to 0
RT30xxReadRFRegister(pAd, RF_R20, &RFValue);
RFValue &= (~0x08);
RT30xxWriteRFRegister(pAd, RF_R20, RFValue);
// RX_LO2_en, RF R21 register Bit 3 to 0
RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
RFValue &= (~0x08);
RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
/* add by johnli, reset RF_R27 when interface down & up to fix throughput problem*/
// LDORF_VC, RF R27 register Bit 2 to 0
RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
// TX to RX IQ glitch(RF_R27) has been fixed in RT3070(F).
// Raising RF voltage is no longer needed for RT3070(F)
if (IS_RT3090(pAd)) // RT309x and RT3071/72
{
if ((pAd->MACVersion & 0xffff) < 0x0211)
RFValue = (RFValue & (~0x77)) | 0x3;
else
RFValue = (RFValue & (~0x77));
RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
}
/* end johnli */
}
/*
==========================================================================
Description:
Load RF sleep-mode setup
==========================================================================
*/
VOID RT30xxLoadRFSleepModeSetup(
IN PRTMP_ADAPTER pAd)
{
UCHAR RFValue;
UINT32 MACValue;
{
// RF_BLOCK_en. RF R1 register Bit 0 to 0
RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
RFValue &= (~0x01);
RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
// VCO_IC, RF R7 register Bit 4 & Bit 5 to 0
RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
RFValue &= (~0x30);
RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
// Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 0
RT30xxReadRFRegister(pAd, RF_R09, &RFValue);
RFValue &= (~0x0E);
RT30xxWriteRFRegister(pAd, RF_R09, RFValue);
// RX_CTB_en, RF R21 register Bit 7 to 0
RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
RFValue &= (~0x80);
RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
}
if (IS_RT3090(pAd) || // IS_RT3090 including RT309x and RT3071/72
IS_RT3572(pAd) ||
(IS_RT3070(pAd) && ((pAd->MACVersion & 0xffff) < 0x0201)))
{
{
RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
RFValue |= 0x77;
RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
}
RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
MACValue |= 0x1D000000;
RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
}
}
/*
==========================================================================
Description:
Reverse RF sleep-mode setup
==========================================================================
*/
VOID RT30xxReverseRFSleepModeSetup(
IN PRTMP_ADAPTER pAd)
{
UCHAR RFValue;
UINT32 MACValue;
{
// RF_BLOCK_en, RF R1 register Bit 0 to 1
RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
RFValue |= 0x01;
RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
// VCO_IC, RF R7 register Bit 4 & Bit 5 to 1
RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
RFValue |= 0x30;
RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
// Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 1
RT30xxReadRFRegister(pAd, RF_R09, &RFValue);
RFValue |= 0x0E;
RT30xxWriteRFRegister(pAd, RF_R09, RFValue);
// RX_CTB_en, RF R21 register Bit 7 to 1
RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
RFValue |= 0x80;
RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
}
if (IS_RT3090(pAd) || // IS_RT3090 including RT309x and RT3071/72
IS_RT3572(pAd) ||
IS_RT3390(pAd) ||
(IS_RT3070(pAd) && ((pAd->MACVersion & 0xffff) < 0x0201)))
{
{
RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
if ((pAd->MACVersion & 0xffff) < 0x0211)
RFValue = (RFValue & (~0x77)) | 0x3;
else
RFValue = (RFValue & (~0x77));
RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
}
// RT3071 version E has fixed this issue
if ((pAd->NicConfig2.field.DACTestBit == 1) && ((pAd->MACVersion & 0xffff) < 0x0211))
{
// patch tx EVM issue temporarily
RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
MACValue = ((MACValue & 0xE0FFFFFF) | 0x0D000000);
RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
}
else
{
RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
MACValue = ((MACValue & 0xE0FFFFFF) | 0x01000000);
RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
}
}
if(IS_RT3572(pAd))
RT30xxWriteRFRegister(pAd, RF_R08, 0x80);
}
// end johnli
VOID RT30xxHaltAction(
IN PRTMP_ADAPTER pAd)
{
UINT32 TxPinCfg = 0x00050F0F;
//
// Turn off LNA_PE or TRSW_POL
//
if (IS_RT3070(pAd) || IS_RT3071(pAd) || IS_RT3572(pAd))
{
if ((IS_RT3071(pAd) || IS_RT3572(pAd))
#ifdef RTMP_EFUSE_SUPPORT
&& (pAd->bUseEfuse)
#endif // RTMP_EFUSE_SUPPORT //
)
{
TxPinCfg &= 0xFFFBF0F0; // bit18 off
}
else
{
TxPinCfg &= 0xFFFFF0F0;
}
RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
}
}
#endif // RT30xx //

View file

@ -0,0 +1,121 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
rt3370.c
Abstract:
Specific funcitons and variables for RT30xx.
Revision History:
Who When What
-------- ---------- ----------------------------------------------
*/
#ifdef RT3370
#include "../rt_config.h"
#ifndef RTMP_RF_RW_SUPPORT
#error "You Should Enable compile flag RTMP_RF_RW_SUPPORT for this chip"
#endif // RTMP_RF_RW_SUPPORT //
VOID NICInitRT3370RFRegisters(IN PRTMP_ADAPTER pAd)
{
INT i;
// Driver must read EEPROM to get RfIcType before initial RF registers
// Initialize RF register to default value
if (IS_RT3090(pAd)||IS_RT3390(pAd)||IS_RT3572(pAd))
{
// Init RF calibration
// Driver should toggle RF R30 bit7 before init RF registers
UINT32 RfReg = 0, data;
RT30xxReadRFRegister(pAd, RF_R30, (PUCHAR)&RfReg);
RfReg |= 0x80;
RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg);
RTMPusecDelay(1000);
RfReg &= 0x7F;
RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg);
// init R24, R31
RT30xxWriteRFRegister(pAd, RF_R24, 0x0F);
RT30xxWriteRFRegister(pAd, RF_R31, 0x0F);
if (IS_RT3390(pAd))
{
// patch LNA_PE_G1 failed issue
RTMP_IO_READ32(pAd, GPIO_SWITCH, &data);
data &= ~(0x20);
RTMP_IO_WRITE32(pAd, GPIO_SWITCH, data);
// RF registers initialization
for (i = 0; i < NUM_RF_REG_PARMS_OVER_RT3390; i++)
{
RT30xxWriteRFRegister(pAd, RFRegTableOverRT3390[i].Register, RFRegTableOverRT3390[i].Value);
}
}
// patch LNA_PE_G1 failed issue
RTMP_IO_READ32(pAd, GPIO_SWITCH, &data);
data &= ~(0x20);
RTMP_IO_WRITE32(pAd, GPIO_SWITCH, data);
// Initialize RF register to default value
for (i = 0; i < NUM_RF_REG_PARMS_OVER_RT3390; i++)
{
RT30xxWriteRFRegister(pAd, RT30xx_RFRegTable[i].Register, RT30xx_RFRegTable[i].Value);
}
// Driver should set RF R6 bit6 on before calibration
RT30xxReadRFRegister(pAd, RF_R06, (PUCHAR)&RfReg);
RfReg |= 0x40;
RT30xxWriteRFRegister(pAd, RF_R06, (UCHAR)RfReg);
//For RF filter Calibration
RTMPFilterCalibration(pAd);
// Initialize RF R27 register, set RF R27 must be behind RTMPFilterCalibration()
if ((pAd->MACVersion & 0xffff) < 0x0211)
RT30xxWriteRFRegister(pAd, RF_R27, 0x3);
// set led open drain enable
RTMP_IO_READ32(pAd, OPT_14, &data);
data |= 0x01;
RTMP_IO_WRITE32(pAd, OPT_14, data);
// set default antenna as main
if (pAd->RfIcType == RFIC_3020)
AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
// add by johnli, RF power sequence setup, load RF normal operation-mode setup
RT30xxLoadRFNormalModeSetup(pAd);
}
}
#endif // RT3070 //

View file

@ -0,0 +1,122 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
rt3390.c
Abstract:
Specific funcitons and variables for RT30xx.
Revision History:
Who When What
-------- ---------- ----------------------------------------------
*/
#ifdef RT3390
#include "../rt_config.h"
#ifndef RTMP_RF_RW_SUPPORT
#error "You Should Enable compile flag RTMP_RF_RW_SUPPORT for this chip"
#endif // RTMP_RF_RW_SUPPORT //
VOID NICInitRT3390RFRegisters(IN PRTMP_ADAPTER pAd)
{
INT i;
// Driver must read EEPROM to get RfIcType before initial RF registers
// Initialize RF register to default value
if (IS_RT3090(pAd)||IS_RT3390(pAd)||IS_RT3572(pAd))
{
// Init RF calibration
// Driver should toggle RF R30 bit7 before init RF registers
UINT32 RfReg = 0, data;
RT30xxReadRFRegister(pAd, RF_R30, (PUCHAR)&RfReg);
RfReg |= 0x80;
RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg);
RTMPusecDelay(1000);
RfReg &= 0x7F;
RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg);
// init R24, R31
RT30xxWriteRFRegister(pAd, RF_R24, 0x0F);
RT30xxWriteRFRegister(pAd, RF_R31, 0x0F);
if (IS_RT3390(pAd))
{
// patch LNA_PE_G1 failed issue
RTMP_IO_READ32(pAd, GPIO_SWITCH, &data);
data &= ~(0x20);
RTMP_IO_WRITE32(pAd, GPIO_SWITCH, data);
// RF registers initialization
for (i = 0; i < NUM_RF_REG_PARMS_OVER_RT3390; i++)
{
RT30xxWriteRFRegister(pAd, RFRegTableOverRT3390[i].Register, RFRegTableOverRT3390[i].Value);
}
}
// patch LNA_PE_G1 failed issue
RTMP_IO_READ32(pAd, GPIO_SWITCH, &data);
data &= ~(0x20);
RTMP_IO_WRITE32(pAd, GPIO_SWITCH, data);
// Initialize RF register to default value
for (i = 0; i < NUM_RF_REG_PARMS_OVER_RT3390; i++)
{
RT30xxWriteRFRegister(pAd, RFRegTableOverRT3390[i].Register, RFRegTableOverRT3390[i].Value);
}
// Driver should set RF R6 bit6 on before calibration
RT30xxReadRFRegister(pAd, RF_R06, (PUCHAR)&RfReg);
RfReg |= 0x40;
RT30xxWriteRFRegister(pAd, RF_R06, (UCHAR)RfReg);
//For RF filter Calibration
RTMPFilterCalibration(pAd);
// Initialize RF R27 register, set RF R27 must be behind RTMPFilterCalibration()
if ((pAd->MACVersion & 0xffff) < 0x0211)
RT30xxWriteRFRegister(pAd, RF_R27, 0x3);
// set led open drain enable
RTMP_IO_READ32(pAd, OPT_14, &data);
data |= 0x01;
RTMP_IO_WRITE32(pAd, OPT_14, data);
// set default antenna as main
if (pAd->RfIcType == RFIC_3020)
AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
// add by johnli, RF power sequence setup, load RF normal operation-mode setup
RT33xxLoadRFNormalModeSetup(pAd);
}
}
#endif // RT3390 //

View file

@ -0,0 +1,536 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
rt33xx.c
Abstract:
Specific funcitons and variables for RT30xx.
Revision History:
Who When What
-------- ---------- ----------------------------------------------
*/
#ifdef RT33xx
#ifndef RTMP_RF_RW_SUPPORT
#error "You Should Enable compile flag RTMP_RF_RW_SUPPORT for this chip"
#endif // RTMP_RF_RW_SUPPORT //
#include "../rt_config.h"
//
// RF register initialization set
//
REG_PAIR RFRegTableOverRT3390[] = {
{RF_R00, 0xA0},
{RF_R01, 0xE1},
{RF_R02, 0xF1},
{RF_R03, 0x62},
{RF_R04, 0x40},
{RF_R05, 0x8B},
{RF_R06, 0x42},
{RF_R07, 0x34},
{RF_R08, 0x00}, // Read only
{RF_R09, 0xC0},
{RF_R10, 0x61},
{RF_R11, 0x21},
{RF_R12, 0x3B},
{RF_R13, 0xE0},
{RF_R14, 0x90},
{RF_R15, 0x53},
{RF_R16, 0x0E},
{RF_R17, 0x94},
{RF_R18, 0x5C},
{RF_R19, 0x4A},
{RF_R20, 0xB2},
{RF_R21, 0xF6},
{RF_R22, 0x00},
{RF_R23, 0x14},
{RF_R24, 0x08},
{RF_R25, 0x3D},
{RF_R26, 0x85},
{RF_R27, 0x00},
{RF_R28, 0x41},
{RF_R29, 0x8F},
{RF_R30, 0x20},
{RF_R31, 0x0F},
};
UCHAR NUM_RF_REG_PARMS_OVER_RT3390=(sizeof(RFRegTableOverRT3390) / sizeof(REG_PAIR));
// Antenna divesity use GPIO3 and EESK pin for control
// Antenna and EEPROM access are both using EESK pin,
// Therefor we should avoid accessing EESK at the same time
// Then restore antenna after EEPROM access
// The original name of this function is AsicSetRxAnt(), now change to
//VOID AsicSetRxAnt(
VOID RT33xxSetRxAnt(
IN PRTMP_ADAPTER pAd,
IN UCHAR Ant)
{
UINT32 Value;
UINT32 x;
if ((pAd->EepromAccess) ||
(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) ||
(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) ||
(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) ||
(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
{
return;
}
// the antenna selection is through firmware and MAC register(GPIO3)
if (Ant == 0)
{
// Main antenna
RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
x |= (EESK);
RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value);
Value &= ~(0x0808);
RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value);
DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicSetRxAnt, switch to main antenna\n"));
}
else
{
// Aux antenna
RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
x &= ~(EESK);
RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value);
Value &= ~(0x0808);
Value |= 0x08;
RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value);
DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicSetRxAnt, switch to aux antenna\n"));
}
}
/*
========================================================================
Routine Description:
For RF filter calibration purpose
Arguments:
pAd Pointer to our adapter
Return Value:
None
IRQL = PASSIVE_LEVEL
========================================================================
*/
VOID RTMPFilterCalibration(
IN PRTMP_ADAPTER pAd)
{
UCHAR R55x = 0, value, FilterTarget = 0x1E, BBPValue=0;
UINT loop = 0, count = 0, loopcnt = 0, ReTry = 0;
UCHAR RF_R24_Value = 0;
// Give bbp filter initial value
pAd->Mlme.CaliBW20RfR24 = 0x1F;
pAd->Mlme.CaliBW40RfR24 = 0x2F; //Bit[5] must be 1 for BW 40
do
{
if (loop == 1) //BandWidth = 40 MHz
{
// Write 0x27 to RF_R24 to program filter
RF_R24_Value = 0x27;
RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
if (IS_RT3090(pAd) || IS_RT3572(pAd)|| IS_RT3390(pAd))
FilterTarget = 0x15;
else
FilterTarget = 0x19;
// when calibrate BW40, BBP mask must set to BW40.
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
BBPValue&= (~0x18);
BBPValue|= (0x10);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
// set to BW40
RT30xxReadRFRegister(pAd, RF_R31, &value);
value |= 0x20;
RT30xxWriteRFRegister(pAd, RF_R31, value);
}
else //BandWidth = 20 MHz
{
// Write 0x07 to RF_R24 to program filter
RF_R24_Value = 0x07;
RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
if (IS_RT3090(pAd) || IS_RT3572(pAd)|| IS_RT3390(pAd))
FilterTarget = 0x13;
else
FilterTarget = 0x16;
// set to BW20
RT30xxReadRFRegister(pAd, RF_R31, &value);
value &= (~0x20);
RT30xxWriteRFRegister(pAd, RF_R31, value);
}
// Write 0x01 to RF_R22 to enable baseband loopback mode
RT30xxReadRFRegister(pAd, RF_R22, &value);
value |= 0x01;
RT30xxWriteRFRegister(pAd, RF_R22, value);
// Write 0x00 to BBP_R24 to set power & frequency of passband test tone
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0);
do
{
// Write 0x90 to BBP_R25 to transmit test tone
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x90);
RTMPusecDelay(1000);
// Read BBP_R55[6:0] for received power, set R55x = BBP_R55[6:0]
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R55, &value);
R55x = value & 0xFF;
} while ((ReTry++ < 100) && (R55x == 0));
// Write 0x06 to BBP_R24 to set power & frequency of stopband test tone
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0x06);
while(TRUE)
{
// Write 0x90 to BBP_R25 to transmit test tone
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x90);
//We need to wait for calibration
RTMPusecDelay(1000);
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R55, &value);
value &= 0xFF;
if ((R55x - value) < FilterTarget)
{
RF_R24_Value ++;
}
else if ((R55x - value) == FilterTarget)
{
RF_R24_Value ++;
count ++;
}
else
{
break;
}
// prevent infinite loop cause driver hang.
if (loopcnt++ > 100)
{
DBGPRINT(RT_DEBUG_ERROR, ("RTMPFilterCalibration - can't find a valid value, loopcnt=%d stop calibrating", loopcnt));
break;
}
// Write RF_R24 to program filter
RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
}
if (count > 0)
{
RF_R24_Value = RF_R24_Value - ((count) ? (1) : (0));
}
// Store for future usage
if (loopcnt < 100)
{
if (loop++ == 0)
{
//BandWidth = 20 MHz
pAd->Mlme.CaliBW20RfR24 = (UCHAR)RF_R24_Value;
}
else
{
//BandWidth = 40 MHz
pAd->Mlme.CaliBW40RfR24 = (UCHAR)RF_R24_Value;
break;
}
}
else
break;
RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
// reset count
count = 0;
} while(TRUE);
//
// Set back to initial state
//
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0);
RT30xxReadRFRegister(pAd, RF_R22, &value);
value &= ~(0x01);
RT30xxWriteRFRegister(pAd, RF_R22, value);
// set BBP back to BW20
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
BBPValue&= (~0x18);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
DBGPRINT(RT_DEBUG_TRACE, ("RTMPFilterCalibration - CaliBW20RfR24=0x%x, CaliBW40RfR24=0x%x\n", pAd->Mlme.CaliBW20RfR24, pAd->Mlme.CaliBW40RfR24));
}
// add by johnli, RF power sequence setup
/*
==========================================================================
Description:
Load RF normal operation-mode setup
==========================================================================
*/
VOID RT33xxLoadRFNormalModeSetup(
IN PRTMP_ADAPTER pAd)
{
UCHAR RFValue;
// RX0_PD & TX0_PD, RF R1 register Bit 2 & Bit 3 to 0 and RF_BLOCK_en,RX1_PD & TX1_PD, Bit0, Bit 4 & Bit5 to 1
RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
RFValue = (RFValue & (~0x0C)) | 0x31;
RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
// TX_LO2_en, RF R15 register Bit 3 to 0
RT30xxReadRFRegister(pAd, RF_R15, &RFValue);
RFValue &= (~0x08);
RT30xxWriteRFRegister(pAd, RF_R15, RFValue);
/* move to NICInitRT30xxRFRegisters
// TX_LO1_en, RF R17 register Bit 3 to 0
RT30xxReadRFRegister(pAd, RF_R17, &RFValue);
RFValue &= (~0x08);
// to fix rx long range issue
if (((pAd->MACVersion & 0xffff) >= 0x0211) && (pAd->NicConfig2.field.ExternalLNAForG == 0))
{
RFValue |= 0x20;
}
// set RF_R17_bit[2:0] equal to EEPROM setting at 0x48h
if (pAd->TxMixerGain24G >= 2)
{
RFValue &= (~0x7); // clean bit [2:0]
RFValue |= pAd->TxMixerGain24G;
}
RT30xxWriteRFRegister(pAd, RF_R17, RFValue);
*/
// RX_LO1_en, RF R20 register Bit 3 to 0
RT30xxReadRFRegister(pAd, RF_R20, &RFValue);
RFValue &= (~0x08);
RT30xxWriteRFRegister(pAd, RF_R20, RFValue);
// RX_LO2_en, RF R21 register Bit 3 to 0
RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
RFValue &= (~0x08);
RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
/* add by johnli, reset RF_R27 when interface down & up to fix throughput problem*/
// LDORF_VC, RF R27 register Bit 2 to 0
RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
// TX to RX IQ glitch(RF_R27) has been fixed in RT3070(F).
// Raising RF voltage is no longer needed for RT3070(F)
if (IS_RT3090(pAd)) // RT309x and RT3071/72
{
if ((pAd->MACVersion & 0xffff) < 0x0211)
RFValue = (RFValue & (~0x77)) | 0x3;
else
RFValue = (RFValue & (~0x77));
RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
}
/* end johnli */
}
/*
==========================================================================
Description:
Load RF sleep-mode setup
==========================================================================
*/
VOID RT33xxLoadRFSleepModeSetup(
IN PRTMP_ADAPTER pAd)
{
UCHAR RFValue;
UINT32 MACValue;
{
// RF_BLOCK_en. RF R1 register Bit 0 to 0
RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
RFValue &= (~0x01);
RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
// VCO_IC, RF R7 register Bit 4 & Bit 5 to 0
RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
RFValue &= (~0x30);
RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
// Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 0
RT30xxReadRFRegister(pAd, RF_R09, &RFValue);
RFValue &= (~0x0E);
RT30xxWriteRFRegister(pAd, RF_R09, RFValue);
// RX_CTB_en, RF R21 register Bit 7 to 0
RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
RFValue &= (~0x80);
RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
}
if (IS_RT3090(pAd) || // IS_RT3090 including RT309x and RT3071/72
IS_RT3572(pAd) ||
IS_RT3390(pAd) ||
(IS_RT3070(pAd) && ((pAd->MACVersion & 0xffff) < 0x0201)))
{
{
RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
RFValue |= 0x77;
RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
}
RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
MACValue |= 0x1D000000;
RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
}
}
/*
==========================================================================
Description:
Reverse RF sleep-mode setup
==========================================================================
*/
VOID RT33xxReverseRFSleepModeSetup(
IN PRTMP_ADAPTER pAd)
{
UCHAR RFValue;
UINT32 MACValue;
{
// RF_BLOCK_en, RF R1 register Bit 0 to 1
RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
RFValue |= 0x01;
RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
// VCO_IC, RF R7 register Bit 4 & Bit 5 to 1
RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
RFValue |= 0x30;
RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
// Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 1
RT30xxReadRFRegister(pAd, RF_R09, &RFValue);
RFValue |= 0x0E;
RT30xxWriteRFRegister(pAd, RF_R09, RFValue);
// RX_CTB_en, RF R21 register Bit 7 to 1
RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
RFValue |= 0x80;
RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
}
if (IS_RT3090(pAd) || // IS_RT3090 including RT309x and RT3071/72
IS_RT3572(pAd) ||
IS_RT3390(pAd) ||
(IS_RT3070(pAd) && ((pAd->MACVersion & 0xffff) < 0x0201)))
{
{
RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
if ((pAd->MACVersion & 0xffff) < 0x0211)
RFValue = (RFValue & (~0x77)) | 0x3;
else
RFValue = (RFValue & (~0x77));
RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
}
// RT3071 version E has fixed this issue
if ((pAd->NicConfig2.field.DACTestBit == 1) && ((pAd->MACVersion & 0xffff) < 0x0211))
{
// patch tx EVM issue temporarily
RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
MACValue = ((MACValue & 0xE0FFFFFF) | 0x0D000000);
RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
}
else
{
RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
MACValue = ((MACValue & 0xE0FFFFFF) | 0x01000000);
RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
}
}
if(IS_RT3572(pAd))
RT30xxWriteRFRegister(pAd, RF_R08, 0x80);
}
// end johnli
VOID RT33xxHaltAction(
IN PRTMP_ADAPTER pAd)
{
UINT32 TxPinCfg = 0x00050F0F;
//
// Turn off LNA_PE or TRSW_POL
//
if (IS_RT3070(pAd) || IS_RT3071(pAd) || IS_RT3390(pAd)||IS_RT3572(pAd))
{
//KH? Both support 3390 usb and PCI
if ((IS_RT3071(pAd) || IS_RT3572(pAd)||IS_RT3390(pAd))
#ifdef RTMP_EFUSE_SUPPORT
&& (pAd->bUseEfuse)
#endif // RTMP_EFUSE_SUPPORT //
)
{
TxPinCfg &= 0xFFFBF0F0; // bit18 off
}
else
{
TxPinCfg &= 0xFFFFF0F0;
}
RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
}
}
#endif // RT30xx //

View file

@ -0,0 +1,130 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
chlist.h
Abstract:
Miniport generic portion header file
Revision History:
Who When What
-------- ---------- ----------------------------------------------
Fonchi Wu 2007-12-19 created
*/
#ifndef __CHLIST_H__
#define __CHLIST_H__
#include "rtmp_type.h"
#include "rtmp_def.h"
#define ODOR 0
#define IDOR 1
#define BOTH 2
#define BAND_5G 0
#define BAND_24G 1
#define BAND_BOTH 2
typedef struct _CH_DESP {
UCHAR FirstChannel;
UCHAR NumOfCh;
CHAR MaxTxPwr; // dBm
UCHAR Geography; // 0:out door, 1:in door, 2:both
BOOLEAN DfsReq; // Dfs require, 0: No, 1: yes.
} CH_DESP, *PCH_DESP;
typedef struct _CH_REGION {
UCHAR CountReg[3];
UCHAR DfsType; // 0: CE, 1: FCC, 2: JAP, 3:JAP_W53, JAP_W56
CH_DESP ChDesp[10];
} CH_REGION, *PCH_REGION;
extern CH_REGION ChRegion[];
typedef struct _CH_FREQ_MAP_{
UINT16 channel;
UINT16 freqKHz;
}CH_FREQ_MAP;
extern CH_FREQ_MAP CH_HZ_ID_MAP[];
extern int CH_HZ_ID_MAP_NUM;
#define MAP_CHANNEL_ID_TO_KHZ(_ch, _khz) \
do{ \
int _chIdx; \
for (_chIdx = 0; _chIdx < CH_HZ_ID_MAP_NUM; _chIdx++)\
{ \
if ((_ch) == CH_HZ_ID_MAP[_chIdx].channel) \
{ \
(_khz) = CH_HZ_ID_MAP[_chIdx].freqKHz * 1000; \
break; \
} \
} \
if (_chIdx == CH_HZ_ID_MAP_NUM) \
(_khz) = 2412000; \
}while(0)
#define MAP_KHZ_TO_CHANNEL_ID(_khz, _ch) \
do{ \
int _chIdx; \
for (_chIdx = 0; _chIdx < CH_HZ_ID_MAP_NUM; _chIdx++)\
{ \
if ((_khz) == CH_HZ_ID_MAP[_chIdx].freqKHz) \
{ \
(_ch) = CH_HZ_ID_MAP[_chIdx].channel; \
break; \
} \
} \
if (_chIdx == CH_HZ_ID_MAP_NUM) \
(_ch) = 1; \
}while(0)
VOID BuildChannelListEx(
IN PRTMP_ADAPTER pAd);
VOID BuildBeaconChList(
IN PRTMP_ADAPTER pAd,
OUT PUCHAR pBuf,
OUT PULONG pBufLen);
#ifdef DOT11_N_SUPPORT
VOID N_ChannelCheck(
IN PRTMP_ADAPTER pAd);
VOID N_SetCenCh(
IN PRTMP_ADAPTER pAd);
#endif // DOT11_N_SUPPORT //
UINT8 GetCuntryMaxTxPwr(
IN PRTMP_ADAPTER pAd,
IN UINT8 channel);
#endif // __CHLIST_H__

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,295 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
cmm_cfg.c
Abstract:
Ralink WiFi Driver configuration related subroutines
Revision History:
Who When What
--------- ---------- ----------------------------------------------
*/
#include "../rt_config.h"
char* GetPhyMode(
int Mode)
{
switch(Mode)
{
case MODE_CCK:
return "CCK";
case MODE_OFDM:
return "OFDM";
#ifdef DOT11_N_SUPPORT
case MODE_HTMIX:
return "HTMIX";
case MODE_HTGREENFIELD:
return "GREEN";
#endif // DOT11_N_SUPPORT //
default:
return "N/A";
}
}
char* GetBW(
int BW)
{
switch(BW)
{
case BW_10:
return "10M";
case BW_20:
return "20M";
#ifdef DOT11_N_SUPPORT
case BW_40:
return "40M";
#endif // DOT11_N_SUPPORT //
default:
return "N/A";
}
}
/*
==========================================================================
Description:
Set Country Region to pAd->CommonCfg.CountryRegion.
This command will not work, if the field of CountryRegion in eeprom is programmed.
Return:
TRUE if all parameters are OK, FALSE otherwise
==========================================================================
*/
INT RT_CfgSetCountryRegion(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg,
IN INT band)
{
LONG region, regionMax;
UCHAR *pCountryRegion;
region = simple_strtol(arg, 0, 10);
if (band == BAND_24G)
{
pCountryRegion = &pAd->CommonCfg.CountryRegion;
regionMax = REGION_MAXIMUM_BG_BAND;
}
else
{
pCountryRegion = &pAd->CommonCfg.CountryRegionForABand;
regionMax = REGION_MAXIMUM_A_BAND;
}
// TODO: Is it neccesay for following check???
// Country can be set only when EEPROM not programmed
if (*pCountryRegion & 0x80)
{
DBGPRINT(RT_DEBUG_ERROR, ("CfgSetCountryRegion():CountryRegion in eeprom was programmed\n"));
return FALSE;
}
if((region >= 0) && (region <= REGION_MAXIMUM_BG_BAND))
{
*pCountryRegion= (UCHAR) region;
}
else if ((region == REGION_31_BG_BAND) && (band == BAND_24G))
{
*pCountryRegion = (UCHAR) region;
}
else
{
DBGPRINT(RT_DEBUG_ERROR, ("CfgSetCountryRegion():region(%ld) out of range!\n", region));
return FALSE;
}
return TRUE;
}
/*
==========================================================================
Description:
Set Wireless Mode
Return:
TRUE if all parameters are OK, FALSE otherwise
==========================================================================
*/
INT RT_CfgSetWirelessMode(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg)
{
INT MaxPhyMode = PHY_11G;
LONG WirelessMode;
#ifdef DOT11_N_SUPPORT
MaxPhyMode = PHY_11N_5G;
#endif // DOT11_N_SUPPORT //
WirelessMode = simple_strtol(arg, 0, 10);
if (WirelessMode <= MaxPhyMode)
{
pAd->CommonCfg.PhyMode = WirelessMode;
pAd->CommonCfg.DesiredPhyMode = WirelessMode;
return TRUE;
}
return FALSE;
}
INT RT_CfgSetShortSlot(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg)
{
LONG ShortSlot;
ShortSlot = simple_strtol(arg, 0, 10);
if (ShortSlot == 1)
pAd->CommonCfg.bUseShortSlotTime = TRUE;
else if (ShortSlot == 0)
pAd->CommonCfg.bUseShortSlotTime = FALSE;
else
return FALSE; //Invalid argument
return TRUE;
}
/*
==========================================================================
Description:
Set WEP KEY base on KeyIdx
Return:
TRUE if all parameters are OK, FALSE otherwise
==========================================================================
*/
INT RT_CfgSetWepKey(
IN PRTMP_ADAPTER pAd,
IN PSTRING keyString,
IN CIPHER_KEY *pSharedKey,
IN INT keyIdx)
{
INT KeyLen;
INT i;
UCHAR CipherAlg = CIPHER_NONE;
BOOLEAN bKeyIsHex = FALSE;
// TODO: Shall we do memset for the original key info??
memset(pSharedKey, 0, sizeof(CIPHER_KEY));
KeyLen = strlen(keyString);
switch (KeyLen)
{
case 5: //wep 40 Ascii type
case 13: //wep 104 Ascii type
bKeyIsHex = FALSE;
pSharedKey->KeyLen = KeyLen;
NdisMoveMemory(pSharedKey->Key, keyString, KeyLen);
break;
case 10: //wep 40 Hex type
case 26: //wep 104 Hex type
for(i=0; i < KeyLen; i++)
{
if( !isxdigit(*(keyString+i)) )
return FALSE; //Not Hex value;
}
bKeyIsHex = TRUE;
pSharedKey->KeyLen = KeyLen/2 ;
AtoH(keyString, pSharedKey->Key, pSharedKey->KeyLen);
break;
default: //Invalid argument
DBGPRINT(RT_DEBUG_TRACE, ("RT_CfgSetWepKey(keyIdx=%d):Invalid argument (arg=%s)\n", keyIdx, keyString));
return FALSE;
}
pSharedKey->CipherAlg = ((KeyLen % 5) ? CIPHER_WEP128 : CIPHER_WEP64);
DBGPRINT(RT_DEBUG_TRACE, ("RT_CfgSetWepKey:(KeyIdx=%d,type=%s, Alg=%s)\n",
keyIdx, (bKeyIsHex == FALSE ? "Ascii" : "Hex"), CipherName[CipherAlg]));
return TRUE;
}
/*
==========================================================================
Description:
Set WPA PSK key
Arguments:
pAdapter Pointer to our adapter
keyString WPA pre-shared key string
pHashStr String used for password hash function
hashStrLen Lenght of the hash string
pPMKBuf Output buffer of WPAPSK key
Return:
TRUE if all parameters are OK, FALSE otherwise
==========================================================================
*/
INT RT_CfgSetWPAPSKKey(
IN RTMP_ADAPTER *pAd,
IN PSTRING keyString,
IN UCHAR *pHashStr,
IN INT hashStrLen,
OUT PUCHAR pPMKBuf)
{
int keyLen;
UCHAR keyMaterial[40];
keyLen = strlen(keyString);
if ((keyLen < 8) || (keyLen > 64))
{
DBGPRINT(RT_DEBUG_TRACE, ("WPAPSK Key length(%d) error, required 8 ~ 64 characters!(keyStr=%s)\n",
keyLen, keyString));
return FALSE;
}
memset(pPMKBuf, 0, 32);
if (keyLen == 64)
{
AtoH(keyString, pPMKBuf, 32);
}
else
{
PasswordHash(keyString, pHashStr, hashStrLen, keyMaterial);
NdisMoveMemory(pPMKBuf, keyMaterial, 32);
}
return TRUE;
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,734 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
cmm_sync.c
Abstract:
Revision History:
Who When What
-------- ---------- ----------------------------------------------
John Chang 2004-09-01 modified for rt2561/2661
*/
#include "../rt_config.h"
// 2.4 Ghz channel plan index in the TxPower arrays.
#define BG_BAND_REGION_0_START 0 // 1,2,3,4,5,6,7,8,9,10,11
#define BG_BAND_REGION_0_SIZE 11
#define BG_BAND_REGION_1_START 0 // 1,2,3,4,5,6,7,8,9,10,11,12,13
#define BG_BAND_REGION_1_SIZE 13
#define BG_BAND_REGION_2_START 9 // 10,11
#define BG_BAND_REGION_2_SIZE 2
#define BG_BAND_REGION_3_START 9 // 10,11,12,13
#define BG_BAND_REGION_3_SIZE 4
#define BG_BAND_REGION_4_START 13 // 14
#define BG_BAND_REGION_4_SIZE 1
#define BG_BAND_REGION_5_START 0 // 1,2,3,4,5,6,7,8,9,10,11,12,13,14
#define BG_BAND_REGION_5_SIZE 14
#define BG_BAND_REGION_6_START 2 // 3,4,5,6,7,8,9
#define BG_BAND_REGION_6_SIZE 7
#define BG_BAND_REGION_7_START 4 // 5,6,7,8,9,10,11,12,13
#define BG_BAND_REGION_7_SIZE 9
#define BG_BAND_REGION_31_START 0 // 1,2,3,4,5,6,7,8,9,10,11,12,13,14
#define BG_BAND_REGION_31_SIZE 14
// 5 Ghz channel plan index in the TxPower arrays.
UCHAR A_BAND_REGION_0_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165};
UCHAR A_BAND_REGION_1_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
UCHAR A_BAND_REGION_2_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64};
UCHAR A_BAND_REGION_3_CHANNEL_LIST[]={52, 56, 60, 64, 149, 153, 157, 161};
UCHAR A_BAND_REGION_4_CHANNEL_LIST[]={149, 153, 157, 161, 165};
UCHAR A_BAND_REGION_5_CHANNEL_LIST[]={149, 153, 157, 161};
UCHAR A_BAND_REGION_6_CHANNEL_LIST[]={36, 40, 44, 48};
UCHAR A_BAND_REGION_7_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165, 169, 173};
UCHAR A_BAND_REGION_8_CHANNEL_LIST[]={52, 56, 60, 64};
UCHAR A_BAND_REGION_9_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165};
UCHAR A_BAND_REGION_10_CHANNEL_LIST[]={36, 40, 44, 48, 149, 153, 157, 161, 165};
UCHAR A_BAND_REGION_11_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 149, 153, 157, 161};
UCHAR A_BAND_REGION_12_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
UCHAR A_BAND_REGION_13_CHANNEL_LIST[]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161};
UCHAR A_BAND_REGION_14_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165};
UCHAR A_BAND_REGION_15_CHANNEL_LIST[]={149, 153, 157, 161, 165, 169, 173};
//BaSizeArray follows the 802.11n definition as MaxRxFactor. 2^(13+factor) bytes. When factor =0, it's about Ba buffer size =8.
UCHAR BaSizeArray[4] = {8,16,32,64};
/*
==========================================================================
Description:
Update StaCfg->ChannelList[] according to 1) Country Region 2) RF IC type,
and 3) PHY-mode user selected.
The outcome is used by driver when doing site survey.
IRQL = PASSIVE_LEVEL
IRQL = DISPATCH_LEVEL
==========================================================================
*/
VOID BuildChannelList(
IN PRTMP_ADAPTER pAd)
{
UCHAR i, j, index=0, num=0;
PUCHAR pChannelList = NULL;
NdisZeroMemory(pAd->ChannelList, MAX_NUM_OF_CHANNELS * sizeof(CHANNEL_TX_POWER));
// if not 11a-only mode, channel list starts from 2.4Ghz band
if ((pAd->CommonCfg.PhyMode != PHY_11A)
#ifdef DOT11_N_SUPPORT
&& (pAd->CommonCfg.PhyMode != PHY_11AN_MIXED) && (pAd->CommonCfg.PhyMode != PHY_11N_5G)
#endif // DOT11_N_SUPPORT //
)
{
switch (pAd->CommonCfg.CountryRegion & 0x7f)
{
case REGION_0_BG_BAND: // 1 -11
NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_0_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_0_SIZE);
index += BG_BAND_REGION_0_SIZE;
break;
case REGION_1_BG_BAND: // 1 - 13
NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_1_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_1_SIZE);
index += BG_BAND_REGION_1_SIZE;
break;
case REGION_2_BG_BAND: // 10 - 11
NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_2_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_2_SIZE);
index += BG_BAND_REGION_2_SIZE;
break;
case REGION_3_BG_BAND: // 10 - 13
NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_3_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_3_SIZE);
index += BG_BAND_REGION_3_SIZE;
break;
case REGION_4_BG_BAND: // 14
NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_4_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_4_SIZE);
index += BG_BAND_REGION_4_SIZE;
break;
case REGION_5_BG_BAND: // 1 - 14
NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_5_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_5_SIZE);
index += BG_BAND_REGION_5_SIZE;
break;
case REGION_6_BG_BAND: // 3 - 9
NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_6_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_6_SIZE);
index += BG_BAND_REGION_6_SIZE;
break;
case REGION_7_BG_BAND: // 5 - 13
NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_7_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_7_SIZE);
index += BG_BAND_REGION_7_SIZE;
break;
case REGION_31_BG_BAND: // 1 - 14
NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_31_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_31_SIZE);
index += BG_BAND_REGION_31_SIZE;
break;
default: // Error. should never happen
break;
}
for (i=0; i<index; i++)
pAd->ChannelList[i].MaxTxPwr = 20;
}
if ((pAd->CommonCfg.PhyMode == PHY_11A) || (pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED)
#ifdef DOT11_N_SUPPORT
|| (pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11AN_MIXED)
|| (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11N_5G)
#endif // DOT11_N_SUPPORT //
)
{
switch (pAd->CommonCfg.CountryRegionForABand & 0x7f)
{
case REGION_0_A_BAND:
num = sizeof(A_BAND_REGION_0_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_0_CHANNEL_LIST;
break;
case REGION_1_A_BAND:
num = sizeof(A_BAND_REGION_1_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_1_CHANNEL_LIST;
break;
case REGION_2_A_BAND:
num = sizeof(A_BAND_REGION_2_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_2_CHANNEL_LIST;
break;
case REGION_3_A_BAND:
num = sizeof(A_BAND_REGION_3_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_3_CHANNEL_LIST;
break;
case REGION_4_A_BAND:
num = sizeof(A_BAND_REGION_4_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_4_CHANNEL_LIST;
break;
case REGION_5_A_BAND:
num = sizeof(A_BAND_REGION_5_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_5_CHANNEL_LIST;
break;
case REGION_6_A_BAND:
num = sizeof(A_BAND_REGION_6_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_6_CHANNEL_LIST;
break;
case REGION_7_A_BAND:
num = sizeof(A_BAND_REGION_7_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_7_CHANNEL_LIST;
break;
case REGION_8_A_BAND:
num = sizeof(A_BAND_REGION_8_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_8_CHANNEL_LIST;
break;
case REGION_9_A_BAND:
num = sizeof(A_BAND_REGION_9_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_9_CHANNEL_LIST;
break;
case REGION_10_A_BAND:
num = sizeof(A_BAND_REGION_10_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_10_CHANNEL_LIST;
break;
case REGION_11_A_BAND:
num = sizeof(A_BAND_REGION_11_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_11_CHANNEL_LIST;
break;
case REGION_12_A_BAND:
num = sizeof(A_BAND_REGION_12_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_12_CHANNEL_LIST;
break;
case REGION_13_A_BAND:
num = sizeof(A_BAND_REGION_13_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_13_CHANNEL_LIST;
break;
case REGION_14_A_BAND:
num = sizeof(A_BAND_REGION_14_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_14_CHANNEL_LIST;
break;
case REGION_15_A_BAND:
num = sizeof(A_BAND_REGION_15_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_15_CHANNEL_LIST;
break;
default: // Error. should never happen
DBGPRINT(RT_DEBUG_WARN,("countryregion=%d not support", pAd->CommonCfg.CountryRegionForABand));
break;
}
if (num != 0)
{
UCHAR RadarCh[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
for (i=0; i<num; i++)
{
for (j=0; j<MAX_NUM_OF_CHANNELS; j++)
{
if (pChannelList[i] == pAd->TxPower[j].Channel)
NdisMoveMemory(&pAd->ChannelList[index+i], &pAd->TxPower[j], sizeof(CHANNEL_TX_POWER));
}
for (j=0; j<15; j++)
{
if (pChannelList[i] == RadarCh[j])
pAd->ChannelList[index+i].DfsReq = TRUE;
}
pAd->ChannelList[index+i].MaxTxPwr = 20;
}
index += num;
}
}
pAd->ChannelListNum = index;
DBGPRINT(RT_DEBUG_TRACE,("country code=%d/%d, RFIC=%d, PHY mode=%d, support %d channels\n",
pAd->CommonCfg.CountryRegion, pAd->CommonCfg.CountryRegionForABand, pAd->RfIcType, pAd->CommonCfg.PhyMode, pAd->ChannelListNum));
#ifdef DBG
for (i=0;i<pAd->ChannelListNum;i++)
{
DBGPRINT_RAW(RT_DEBUG_TRACE,("BuildChannel # %d :: Pwr0 = %d, Pwr1 =%d, \n ", pAd->ChannelList[i].Channel, pAd->ChannelList[i].Power, pAd->ChannelList[i].Power2));
}
#endif
}
/*
==========================================================================
Description:
This routine return the first channel number according to the country
code selection and RF IC selection (signal band or dual band). It is called
whenever driver need to start a site survey of all supported channels.
Return:
ch - the first channel number of current country code setting
IRQL = PASSIVE_LEVEL
==========================================================================
*/
UCHAR FirstChannel(
IN PRTMP_ADAPTER pAd)
{
return pAd->ChannelList[0].Channel;
}
/*
==========================================================================
Description:
This routine returns the next channel number. This routine is called
during driver need to start a site survey of all supported channels.
Return:
next_channel - the next channel number valid in current country code setting.
Note:
return 0 if no more next channel
==========================================================================
*/
UCHAR NextChannel(
IN PRTMP_ADAPTER pAd,
IN UCHAR channel)
{
int i;
UCHAR next_channel = 0;
for (i = 0; i < (pAd->ChannelListNum - 1); i++)
if (channel == pAd->ChannelList[i].Channel)
{
next_channel = pAd->ChannelList[i+1].Channel;
break;
}
return next_channel;
}
/*
==========================================================================
Description:
This routine is for Cisco Compatible Extensions 2.X
Spec31. AP Control of Client Transmit Power
Return:
None
Note:
Required by Aironet dBm(mW)
0dBm(1mW), 1dBm(5mW), 13dBm(20mW), 15dBm(30mW),
17dBm(50mw), 20dBm(100mW)
We supported
3dBm(Lowest), 6dBm(10%), 9dBm(25%), 12dBm(50%),
14dBm(75%), 15dBm(100%)
The client station's actual transmit power shall be within +/- 5dB of
the minimum value or next lower value.
==========================================================================
*/
VOID ChangeToCellPowerLimit(
IN PRTMP_ADAPTER pAd,
IN UCHAR AironetCellPowerLimit)
{
//valud 0xFF means that hasn't found power limit information
//from the AP's Beacon/Probe response.
if (AironetCellPowerLimit == 0xFF)
return;
if (AironetCellPowerLimit < 6) //Used Lowest Power Percentage.
pAd->CommonCfg.TxPowerPercentage = 6;
else if (AironetCellPowerLimit < 9)
pAd->CommonCfg.TxPowerPercentage = 10;
else if (AironetCellPowerLimit < 12)
pAd->CommonCfg.TxPowerPercentage = 25;
else if (AironetCellPowerLimit < 14)
pAd->CommonCfg.TxPowerPercentage = 50;
else if (AironetCellPowerLimit < 15)
pAd->CommonCfg.TxPowerPercentage = 75;
else
pAd->CommonCfg.TxPowerPercentage = 100; //else used maximum
if (pAd->CommonCfg.TxPowerPercentage > pAd->CommonCfg.TxPowerDefault)
pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
}
CHAR ConvertToRssi(
IN PRTMP_ADAPTER pAd,
IN CHAR Rssi,
IN UCHAR RssiNumber)
{
UCHAR RssiOffset, LNAGain;
// Rssi equals to zero should be an invalid value
if (Rssi == 0)
return -99;
LNAGain = GET_LNA_GAIN(pAd);
if (pAd->LatchRfRegs.Channel > 14)
{
if (RssiNumber == 0)
RssiOffset = pAd->ARssiOffset0;
else if (RssiNumber == 1)
RssiOffset = pAd->ARssiOffset1;
else
RssiOffset = pAd->ARssiOffset2;
}
else
{
if (RssiNumber == 0)
RssiOffset = pAd->BGRssiOffset0;
else if (RssiNumber == 1)
RssiOffset = pAd->BGRssiOffset1;
else
RssiOffset = pAd->BGRssiOffset2;
}
return (-12 - RssiOffset - LNAGain - Rssi);
}
/*
==========================================================================
Description:
Scan next channel
==========================================================================
*/
VOID ScanNextChannel(
IN PRTMP_ADAPTER pAd)
{
HEADER_802_11 Hdr80211;
PUCHAR pOutBuffer = NULL;
NDIS_STATUS NStatus;
ULONG FrameLen = 0;
UCHAR SsidLen = 0, ScanType = pAd->MlmeAux.ScanType, BBPValue = 0;
#ifdef CONFIG_STA_SUPPORT
USHORT Status;
PHEADER_802_11 pHdr80211;
#endif // CONFIG_STA_SUPPORT //
UINT ScanTimeIn5gChannel = SHORT_CHANNEL_TIME;
#ifdef CONFIG_STA_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
{
if (MONITOR_ON(pAd))
return;
}
#endif // CONFIG_STA_SUPPORT //
#ifdef RALINK_ATE
// Nothing to do in ATE mode.
if (ATE_ON(pAd))
return;
#endif // RALINK_ATE //
if (pAd->MlmeAux.Channel == 0)
{
if ((pAd->CommonCfg.BBPCurrentBW == BW_40)
#ifdef CONFIG_STA_SUPPORT
&& (INFRA_ON(pAd)
|| (pAd->OpMode == OPMODE_AP))
#endif // CONFIG_STA_SUPPORT //
)
{
AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
BBPValue &= (~0x18);
BBPValue |= 0x10;
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n",pAd->CommonCfg.CentralChannel, pAd->ScanTab.BssNr));
}
else
{
AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
AsicLockChannel(pAd, pAd->CommonCfg.Channel);
DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to channel %d, Total BSS[%02d]\n",pAd->CommonCfg.Channel, pAd->ScanTab.BssNr));
}
#ifdef CONFIG_STA_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
{
//
// To prevent data lost.
// Send an NULL data with turned PSM bit on to current associated AP before SCAN progress.
// Now, we need to send an NULL data with turned PSM bit off to AP, when scan progress done
//
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && (INFRA_ON(pAd)))
{
NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);
if (NStatus == NDIS_STATUS_SUCCESS)
{
pHdr80211 = (PHEADER_802_11) pOutBuffer;
MgtMacHeaderInit(pAd, pHdr80211, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
pHdr80211->Duration = 0;
pHdr80211->FC.Type = BTYPE_DATA;
pHdr80211->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE);
// Send using priority queue
MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
DBGPRINT(RT_DEBUG_TRACE, ("MlmeScanReqAction -- Send PSM Data frame\n"));
MlmeFreeMemory(pAd, pOutBuffer);
RTMPusecDelay(5000);
}
}
pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
Status = MLME_SUCCESS;
MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
}
#endif // CONFIG_STA_SUPPORT //
RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
}
else
{
#ifdef CONFIG_STA_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
{
// BBP and RF are not accessible in PS mode, we has to wake them up first
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
AsicForceWakeup(pAd, TRUE);
// leave PSM during scanning. otherwise we may lost ProbeRsp & BEACON
if (pAd->StaCfg.Psm == PWR_SAVE)
RTMP_SET_PSM_BIT(pAd, PWR_ACTIVE);
}
#endif // CONFIG_STA_SUPPORT //
AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, TRUE);
AsicLockChannel(pAd, pAd->MlmeAux.Channel);
#ifdef CONFIG_STA_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
{
if (pAd->MlmeAux.Channel > 14)
{
if ((pAd->CommonCfg.bIEEE80211H == 1) && RadarChannelCheck(pAd, pAd->MlmeAux.Channel))
{
ScanType = SCAN_PASSIVE;
ScanTimeIn5gChannel = MIN_CHANNEL_TIME;
}
}
#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
// carrier detection
if (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
{
ScanType = SCAN_PASSIVE;
ScanTimeIn5gChannel = MIN_CHANNEL_TIME;
}
#endif // CARRIER_DETECTION_SUPPORT //
}
#endif // CONFIG_STA_SUPPORT //
//Global country domain(ch1-11:active scan, ch12-14 passive scan)
if ((pAd->MlmeAux.Channel <= 14) && (pAd->MlmeAux.Channel >= 12) && ((pAd->CommonCfg.CountryRegion & 0x7f) == REGION_31_BG_BAND))
{
ScanType = SCAN_PASSIVE;
}
// We need to shorten active scan time in order for WZC connect issue
// Chnage the channel scan time for CISCO stuff based on its IAPP announcement
if (ScanType == FAST_SCAN_ACTIVE)
RTMPSetTimer(&pAd->MlmeAux.ScanTimer, FAST_ACTIVE_SCAN_TIME);
else // must be SCAN_PASSIVE or SCAN_ACTIVE
{
if ((pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED)
#ifdef DOT11_N_SUPPORT
|| (pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED)
#endif // DOT11_N_SUPPORT //
)
{
if (pAd->MlmeAux.Channel > 14)
RTMPSetTimer(&pAd->MlmeAux.ScanTimer, ScanTimeIn5gChannel);
else
RTMPSetTimer(&pAd->MlmeAux.ScanTimer, MIN_CHANNEL_TIME);
}
else
RTMPSetTimer(&pAd->MlmeAux.ScanTimer, MAX_CHANNEL_TIME);
}
if ((ScanType == SCAN_ACTIVE)
|| (ScanType == FAST_SCAN_ACTIVE)
)
{
NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
if (NStatus != NDIS_STATUS_SUCCESS)
{
DBGPRINT(RT_DEBUG_TRACE, ("SYNC - ScanNextChannel() allocate memory fail\n"));
#ifdef CONFIG_STA_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
{
pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
Status = MLME_FAIL_NO_RESOURCE;
MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
}
#endif // CONFIG_STA_SUPPORT //
return;
}
// There is no need to send broadcast probe request if active scan is in effect.
if ((ScanType == SCAN_ACTIVE) || (ScanType == FAST_SCAN_ACTIVE)
)
SsidLen = pAd->MlmeAux.SsidLen;
else
SsidLen = 0;
#ifdef CONFIG_STA_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, BROADCAST_ADDR);
#endif // CONFIG_STA_SUPPORT //
MakeOutgoingFrame(pOutBuffer, &FrameLen,
sizeof(HEADER_802_11), &Hdr80211,
1, &SsidIe,
1, &SsidLen,
SsidLen, pAd->MlmeAux.Ssid,
1, &SupRateIe,
1, &pAd->CommonCfg.SupRateLen,
pAd->CommonCfg.SupRateLen, pAd->CommonCfg.SupRate,
END_OF_ARGS);
if (pAd->CommonCfg.ExtRateLen)
{
ULONG Tmp;
MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
1, &ExtRateIe,
1, &pAd->CommonCfg.ExtRateLen,
pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRate,
END_OF_ARGS);
FrameLen += Tmp;
}
#ifdef DOT11_N_SUPPORT
if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
{
ULONG Tmp;
UCHAR HtLen;
UCHAR BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
#ifdef RT_BIG_ENDIAN
HT_CAPABILITY_IE HtCapabilityTmp;
#endif
if (pAd->bBroadComHT == TRUE)
{
HtLen = pAd->MlmeAux.HtCapabilityLen + 4;
#ifdef RT_BIG_ENDIAN
NdisMoveMemory(&HtCapabilityTmp, &pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
*(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
#ifdef UNALIGNMENT_SUPPORT
{
EXT_HT_CAP_INFO extHtCapInfo;
NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO));
*(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo));
NdisMoveMemory((PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO));
}
#else
*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = cpu2le16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
#endif // UNALIGNMENT_SUPPORT //
MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
1, &WpaIe,
1, &HtLen,
4, &BROADCOM[0],
pAd->MlmeAux.HtCapabilityLen, &HtCapabilityTmp,
END_OF_ARGS);
#else
MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
1, &WpaIe,
1, &HtLen,
4, &BROADCOM[0],
pAd->MlmeAux.HtCapabilityLen, &pAd->MlmeAux.HtCapability,
END_OF_ARGS);
#endif // RT_BIG_ENDIAN //
}
else
{
HtLen = pAd->MlmeAux.HtCapabilityLen;
#ifdef RT_BIG_ENDIAN
NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, SIZE_HT_CAP_IE);
*(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
#ifdef UNALIGNMENT_SUPPORT
{
EXT_HT_CAP_INFO extHtCapInfo;
NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO));
*(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo));
NdisMoveMemory((PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO));
}
#else
*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = cpu2le16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
#endif // UNALIGNMENT_SUPPORT //
MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
1, &HtCapIe,
1, &HtLen,
HtLen, &HtCapabilityTmp,
END_OF_ARGS);
#else
MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
1, &HtCapIe,
1, &HtLen,
HtLen, &pAd->CommonCfg.HtCapability,
END_OF_ARGS);
#endif // RT_BIG_ENDIAN //
}
FrameLen += Tmp;
#ifdef DOT11N_DRAFT3
if (pAd->CommonCfg.BACapability.field.b2040CoexistScanSup == 1)
{
ULONG Tmp;
HtLen = 1;
MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
1, &ExtHtCapIe,
1, &HtLen,
1, &pAd->CommonCfg.BSSCoexist2040.word,
END_OF_ARGS);
FrameLen += Tmp;
}
#endif // DOT11N_DRAFT3 //
}
#endif // DOT11_N_SUPPORT //
MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
MlmeFreeMemory(pAd, pOutBuffer);
}
// For SCAN_CISCO_PASSIVE, do nothing and silently wait for beacon or other probe reponse
#ifdef CONFIG_STA_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
pAd->Mlme.SyncMachine.CurrState = SCAN_LISTEN;
#endif // CONFIG_STA_SUPPORT //
}
}
VOID MgtProbReqMacHeaderInit(
IN PRTMP_ADAPTER pAd,
IN OUT PHEADER_802_11 pHdr80211,
IN UCHAR SubType,
IN UCHAR ToDs,
IN PUCHAR pDA,
IN PUCHAR pBssid)
{
NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
pHdr80211->FC.Type = BTYPE_MGMT;
pHdr80211->FC.SubType = SubType;
if (SubType == SUBTYPE_ACK)
pHdr80211->FC.Type = BTYPE_CNTL;
pHdr80211->FC.ToDs = ToDs;
COPY_MAC_ADDR(pHdr80211->Addr1, pDA);
COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
COPY_MAC_ADDR(pHdr80211->Addr3, pBssid);
}

View file

@ -0,0 +1,966 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
cmm_tkip.c
Abstract:
Revision History:
Who When What
-------- ---------- ----------------------------------------------
Paul Wu 02-25-02 Initial
*/
#include "../rt_config.h"
// 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) )
UINT Tkip_Sbox_Lower[256] =
{
0xA5,0x84,0x99,0x8D,0x0D,0xBD,0xB1,0x54,
0x50,0x03,0xA9,0x7D,0x19,0x62,0xE6,0x9A,
0x45,0x9D,0x40,0x87,0x15,0xEB,0xC9,0x0B,
0xEC,0x67,0xFD,0xEA,0xBF,0xF7,0x96,0x5B,
0xC2,0x1C,0xAE,0x6A,0x5A,0x41,0x02,0x4F,
0x5C,0xF4,0x34,0x08,0x93,0x73,0x53,0x3F,
0x0C,0x52,0x65,0x5E,0x28,0xA1,0x0F,0xB5,
0x09,0x36,0x9B,0x3D,0x26,0x69,0xCD,0x9F,
0x1B,0x9E,0x74,0x2E,0x2D,0xB2,0xEE,0xFB,
0xF6,0x4D,0x61,0xCE,0x7B,0x3E,0x71,0x97,
0xF5,0x68,0x00,0x2C,0x60,0x1F,0xC8,0xED,
0xBE,0x46,0xD9,0x4B,0xDE,0xD4,0xE8,0x4A,
0x6B,0x2A,0xE5,0x16,0xC5,0xD7,0x55,0x94,
0xCF,0x10,0x06,0x81,0xF0,0x44,0xBA,0xE3,
0xF3,0xFE,0xC0,0x8A,0xAD,0xBC,0x48,0x04,
0xDF,0xC1,0x75,0x63,0x30,0x1A,0x0E,0x6D,
0x4C,0x14,0x35,0x2F,0xE1,0xA2,0xCC,0x39,
0x57,0xF2,0x82,0x47,0xAC,0xE7,0x2B,0x95,
0xA0,0x98,0xD1,0x7F,0x66,0x7E,0xAB,0x83,
0xCA,0x29,0xD3,0x3C,0x79,0xE2,0x1D,0x76,
0x3B,0x56,0x4E,0x1E,0xDB,0x0A,0x6C,0xE4,
0x5D,0x6E,0xEF,0xA6,0xA8,0xA4,0x37,0x8B,
0x32,0x43,0x59,0xB7,0x8C,0x64,0xD2,0xE0,
0xB4,0xFA,0x07,0x25,0xAF,0x8E,0xE9,0x18,
0xD5,0x88,0x6F,0x72,0x24,0xF1,0xC7,0x51,
0x23,0x7C,0x9C,0x21,0xDD,0xDC,0x86,0x85,
0x90,0x42,0xC4,0xAA,0xD8,0x05,0x01,0x12,
0xA3,0x5F,0xF9,0xD0,0x91,0x58,0x27,0xB9,
0x38,0x13,0xB3,0x33,0xBB,0x70,0x89,0xA7,
0xB6,0x22,0x92,0x20,0x49,0xFF,0x78,0x7A,
0x8F,0xF8,0x80,0x17,0xDA,0x31,0xC6,0xB8,
0xC3,0xB0,0x77,0x11,0xCB,0xFC,0xD6,0x3A
};
UINT Tkip_Sbox_Upper[256] =
{
0xC6,0xF8,0xEE,0xF6,0xFF,0xD6,0xDE,0x91,
0x60,0x02,0xCE,0x56,0xE7,0xB5,0x4D,0xEC,
0x8F,0x1F,0x89,0xFA,0xEF,0xB2,0x8E,0xFB,
0x41,0xB3,0x5F,0x45,0x23,0x53,0xE4,0x9B,
0x75,0xE1,0x3D,0x4C,0x6C,0x7E,0xF5,0x83,
0x68,0x51,0xD1,0xF9,0xE2,0xAB,0x62,0x2A,
0x08,0x95,0x46,0x9D,0x30,0x37,0x0A,0x2F,
0x0E,0x24,0x1B,0xDF,0xCD,0x4E,0x7F,0xEA,
0x12,0x1D,0x58,0x34,0x36,0xDC,0xB4,0x5B,
0xA4,0x76,0xB7,0x7D,0x52,0xDD,0x5E,0x13,
0xA6,0xB9,0x00,0xC1,0x40,0xE3,0x79,0xB6,
0xD4,0x8D,0x67,0x72,0x94,0x98,0xB0,0x85,
0xBB,0xC5,0x4F,0xED,0x86,0x9A,0x66,0x11,
0x8A,0xE9,0x04,0xFE,0xA0,0x78,0x25,0x4B,
0xA2,0x5D,0x80,0x05,0x3F,0x21,0x70,0xF1,
0x63,0x77,0xAF,0x42,0x20,0xE5,0xFD,0xBF,
0x81,0x18,0x26,0xC3,0xBE,0x35,0x88,0x2E,
0x93,0x55,0xFC,0x7A,0xC8,0xBA,0x32,0xE6,
0xC0,0x19,0x9E,0xA3,0x44,0x54,0x3B,0x0B,
0x8C,0xC7,0x6B,0x28,0xA7,0xBC,0x16,0xAD,
0xDB,0x64,0x74,0x14,0x92,0x0C,0x48,0xB8,
0x9F,0xBD,0x43,0xC4,0x39,0x31,0xD3,0xF2,
0xD5,0x8B,0x6E,0xDA,0x01,0xB1,0x9C,0x49,
0xD8,0xAC,0xF3,0xCF,0xCA,0xF4,0x47,0x10,
0x6F,0xF0,0x4A,0x5C,0x38,0x57,0x73,0x97,
0xCB,0xA1,0xE8,0x3E,0x96,0x61,0x0D,0x0F,
0xE0,0x7C,0x71,0xCC,0x90,0x06,0xF7,0x1C,
0xC2,0x6A,0xAE,0x69,0x17,0x99,0x3A,0x27,
0xD9,0xEB,0x2B,0x22,0xD2,0xA9,0x07,0x33,
0x2D,0x3C,0x15,0xC9,0x87,0xAA,0x50,0xA5,
0x03,0x59,0x09,0x1A,0x65,0xD7,0x84,0xD0,
0x82,0x29,0x5A,0x1E,0x7B,0xA8,0x6D,0x2C
};
//
// Expanded IV for TKIP function.
//
typedef struct PACKED _IV_CONTROL_
{
union PACKED
{
struct PACKED
{
UCHAR rc0;
UCHAR rc1;
UCHAR rc2;
union PACKED
{
struct PACKED
{
#ifdef RT_BIG_ENDIAN
UCHAR KeyID:2;
UCHAR ExtIV:1;
UCHAR Rsvd:5;
#else
UCHAR Rsvd:5;
UCHAR ExtIV:1;
UCHAR KeyID:2;
#endif
} field;
UCHAR Byte;
} CONTROL;
} field;
ULONG word;
} IV16;
ULONG IV32;
} TKIP_IV, *PTKIP_IV;
/*
========================================================================
Routine Description:
Convert from UCHAR[] to ULONG in a portable way
Arguments:
pMICKey pointer to MIC Key
Return Value:
None
Note:
========================================================================
*/
ULONG RTMPTkipGetUInt32(
IN PUCHAR pMICKey)
{
ULONG res = 0;
INT i;
for (i = 0; i < 4; i++)
{
res |= (*pMICKey++) << (8 * i);
}
return res;
}
/*
========================================================================
Routine Description:
Convert from ULONG to UCHAR[] in a portable way
Arguments:
pDst pointer to destination for convert ULONG to UCHAR[]
val the value for convert
Return Value:
None
IRQL = DISPATCH_LEVEL
Note:
========================================================================
*/
VOID RTMPTkipPutUInt32(
IN OUT PUCHAR pDst,
IN ULONG val)
{
INT i;
for(i = 0; i < 4; i++)
{
*pDst++ = (UCHAR) (val & 0xff);
val >>= 8;
}
}
/*
========================================================================
Routine Description:
Set the MIC Key.
Arguments:
pAd Pointer to our adapter
pMICKey pointer to MIC Key
Return Value:
None
IRQL = DISPATCH_LEVEL
Note:
========================================================================
*/
VOID RTMPTkipSetMICKey(
IN PTKIP_KEY_INFO pTkip,
IN PUCHAR pMICKey)
{
// Set the key
pTkip->K0 = RTMPTkipGetUInt32(pMICKey);
pTkip->K1 = RTMPTkipGetUInt32(pMICKey + 4);
// and reset the message
pTkip->L = pTkip->K0;
pTkip->R = pTkip->K1;
pTkip->nBytesInM = 0;
pTkip->M = 0;
}
/*
========================================================================
Routine Description:
Calculate the MIC Value.
Arguments:
pAd Pointer to our adapter
uChar Append this uChar
Return Value:
None
IRQL = DISPATCH_LEVEL
Note:
========================================================================
*/
VOID RTMPTkipAppendByte(
IN PTKIP_KEY_INFO pTkip,
IN UCHAR uChar)
{
// Append the byte to our word-sized buffer
pTkip->M |= (uChar << (8* pTkip->nBytesInM));
pTkip->nBytesInM++;
// Process the word if it is full.
if( pTkip->nBytesInM >= 4 )
{
pTkip->L ^= pTkip->M;
pTkip->R ^= ROL32( pTkip->L, 17 );
pTkip->L += pTkip->R;
pTkip->R ^= ((pTkip->L & 0xff00ff00) >> 8) | ((pTkip->L & 0x00ff00ff) << 8);
pTkip->L += pTkip->R;
pTkip->R ^= ROL32( pTkip->L, 3 );
pTkip->L += pTkip->R;
pTkip->R ^= ROR32( pTkip->L, 2 );
pTkip->L += pTkip->R;
// Clear the buffer
pTkip->M = 0;
pTkip->nBytesInM = 0;
}
}
/*
========================================================================
Routine Description:
Calculate the MIC Value.
Arguments:
pAd Pointer to our adapter
pSrc Pointer to source data for Calculate MIC Value
Len Indicate the length of the source data
Return Value:
None
IRQL = DISPATCH_LEVEL
Note:
========================================================================
*/
VOID RTMPTkipAppend(
IN PTKIP_KEY_INFO pTkip,
IN PUCHAR pSrc,
IN UINT nBytes)
{
// This is simple
while(nBytes > 0)
{
RTMPTkipAppendByte(pTkip, *pSrc++);
nBytes--;
}
}
/*
========================================================================
Routine Description:
Get the MIC Value.
Arguments:
pAd Pointer to our adapter
Return Value:
None
IRQL = DISPATCH_LEVEL
Note:
the MIC Value is store in pAd->PrivateInfo.MIC
========================================================================
*/
VOID RTMPTkipGetMIC(
IN PTKIP_KEY_INFO pTkip)
{
// Append the minimum padding
RTMPTkipAppendByte(pTkip, 0x5a );
RTMPTkipAppendByte(pTkip, 0 );
RTMPTkipAppendByte(pTkip, 0 );
RTMPTkipAppendByte(pTkip, 0 );
RTMPTkipAppendByte(pTkip, 0 );
// and then zeroes until the length is a multiple of 4
while( pTkip->nBytesInM != 0 )
{
RTMPTkipAppendByte(pTkip, 0 );
}
// The appendByte function has already computed the result.
RTMPTkipPutUInt32(pTkip->MIC, pTkip->L);
RTMPTkipPutUInt32(pTkip->MIC + 4, pTkip->R);
}
/*
========================================================================
Routine Description:
Init Tkip function.
Arguments:
pAd Pointer to our adapter
pTKey Pointer to the Temporal Key (TK), TK shall be 128bits.
KeyId TK Key ID
pTA Pointer to transmitter address
pMICKey pointer to MIC Key
Return Value:
None
IRQL = DISPATCH_LEVEL
Note:
========================================================================
*/
VOID RTMPInitTkipEngine(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pKey,
IN UCHAR KeyId,
IN PUCHAR pTA,
IN PUCHAR pMICKey,
IN PUCHAR pTSC,
OUT PULONG pIV16,
OUT PULONG pIV32)
{
TKIP_IV tkipIv;
// Prepare 8 bytes TKIP encapsulation for MPDU
NdisZeroMemory(&tkipIv, sizeof(TKIP_IV));
tkipIv.IV16.field.rc0 = *(pTSC + 1);
tkipIv.IV16.field.rc1 = (tkipIv.IV16.field.rc0 | 0x20) & 0x7f;
tkipIv.IV16.field.rc2 = *pTSC;
tkipIv.IV16.field.CONTROL.field.ExtIV = 1; // 0: non-extended IV, 1: an extended IV
tkipIv.IV16.field.CONTROL.field.KeyID = KeyId;
// tkipIv.IV32 = *(PULONG)(pTSC + 2);
NdisMoveMemory(&tkipIv.IV32, (pTSC + 2), 4); // Copy IV
*pIV16 = tkipIv.IV16.word;
*pIV32 = tkipIv.IV32;
}
/*
========================================================================
Routine Description:
Init MIC Value calculation function which include set MIC key &
calculate first 16 bytes (DA + SA + priority + 0)
Arguments:
pAd Pointer to our adapter
pTKey Pointer to the Temporal Key (TK), TK shall be 128bits.
pDA Pointer to DA address
pSA Pointer to SA address
pMICKey pointer to MIC Key
Return Value:
None
Note:
========================================================================
*/
VOID RTMPInitMICEngine(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pKey,
IN PUCHAR pDA,
IN PUCHAR pSA,
IN UCHAR UserPriority,
IN PUCHAR pMICKey)
{
ULONG Priority = UserPriority;
// Init MIC value calculation
RTMPTkipSetMICKey(&pAd->PrivateInfo.Tx, pMICKey);
// DA
RTMPTkipAppend(&pAd->PrivateInfo.Tx, pDA, MAC_ADDR_LEN);
// SA
RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSA, MAC_ADDR_LEN);
// Priority + 3 bytes of 0
RTMPTkipAppend(&pAd->PrivateInfo.Tx, (PUCHAR)&Priority, 4);
}
/*
========================================================================
Routine Description:
Compare MIC value of received MSDU
Arguments:
pAd Pointer to our adapter
pSrc Pointer to the received Plain text data
pDA Pointer to DA address
pSA Pointer to SA address
pMICKey pointer to MIC Key
Len the length of the received plain text data exclude MIC value
Return Value:
TRUE MIC value matched
FALSE MIC value mismatched
IRQL = DISPATCH_LEVEL
Note:
========================================================================
*/
BOOLEAN RTMPTkipCompareMICValue(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pSrc,
IN PUCHAR pDA,
IN PUCHAR pSA,
IN PUCHAR pMICKey,
IN UCHAR UserPriority,
IN UINT Len)
{
UCHAR OldMic[8];
ULONG Priority = UserPriority;
// Init MIC value calculation
RTMPTkipSetMICKey(&pAd->PrivateInfo.Rx, pMICKey);
// DA
RTMPTkipAppend(&pAd->PrivateInfo.Rx, pDA, MAC_ADDR_LEN);
// SA
RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSA, MAC_ADDR_LEN);
// Priority + 3 bytes of 0
RTMPTkipAppend(&pAd->PrivateInfo.Rx, (PUCHAR)&Priority, 4);
// Calculate MIC value from plain text data
RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSrc, Len);
// Get MIC valude from received frame
NdisMoveMemory(OldMic, pSrc + Len, 8);
// Get MIC value from decrypted plain data
RTMPTkipGetMIC(&pAd->PrivateInfo.Rx);
// Move MIC value from MSDU, this steps should move to data path.
// Since the MIC value might cross MPDUs.
if(!NdisEqualMemory(pAd->PrivateInfo.Rx.MIC, OldMic, 8))
{
DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTMPTkipCompareMICValue(): TKIP MIC Error !\n")); //MIC error.
return (FALSE);
}
return (TRUE);
}
/*
========================================================================
Routine Description:
Compare MIC value of received MSDU
Arguments:
pAd Pointer to our adapter
pLLC LLC header
pSrc Pointer to the received Plain text data
pDA Pointer to DA address
pSA Pointer to SA address
pMICKey pointer to MIC Key
Len the length of the received plain text data exclude MIC value
Return Value:
TRUE MIC value matched
FALSE MIC value mismatched
IRQL = DISPATCH_LEVEL
Note:
========================================================================
*/
BOOLEAN RTMPTkipCompareMICValueWithLLC(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pLLC,
IN PUCHAR pSrc,
IN PUCHAR pDA,
IN PUCHAR pSA,
IN PUCHAR pMICKey,
IN UINT Len)
{
UCHAR OldMic[8];
ULONG Priority = 0;
// Init MIC value calculation
RTMPTkipSetMICKey(&pAd->PrivateInfo.Rx, pMICKey);
// DA
RTMPTkipAppend(&pAd->PrivateInfo.Rx, pDA, MAC_ADDR_LEN);
// SA
RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSA, MAC_ADDR_LEN);
// Priority + 3 bytes of 0
RTMPTkipAppend(&pAd->PrivateInfo.Rx, (PUCHAR)&Priority, 4);
// Start with LLC header
RTMPTkipAppend(&pAd->PrivateInfo.Rx, pLLC, 8);
// Calculate MIC value from plain text data
RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSrc, Len);
// Get MIC valude from received frame
NdisMoveMemory(OldMic, pSrc + Len, 8);
// Get MIC value from decrypted plain data
RTMPTkipGetMIC(&pAd->PrivateInfo.Rx);
// Move MIC value from MSDU, this steps should move to data path.
// Since the MIC value might cross MPDUs.
if(!NdisEqualMemory(pAd->PrivateInfo.Rx.MIC, OldMic, 8))
{
DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTMPTkipCompareMICValueWithLLC(): TKIP MIC Error !\n")); //MIC error.
return (FALSE);
}
return (TRUE);
}
/*
========================================================================
Routine Description:
Copy frame from waiting queue into relative ring buffer and set
appropriate ASIC register to kick hardware transmit function
Arguments:
pAd Pointer to our adapter
PNDIS_PACKET Pointer to Ndis Packet for MIC calculation
pEncap Pointer to LLC encap data
LenEncap Total encap length, might be 0 which indicates no encap
Return Value:
None
IRQL = DISPATCH_LEVEL
Note:
========================================================================
*/
VOID RTMPCalculateMICValue(
IN PRTMP_ADAPTER pAd,
IN PNDIS_PACKET pPacket,
IN PUCHAR pEncap,
IN PCIPHER_KEY pKey,
IN UCHAR apidx)
{
PACKET_INFO PacketInfo;
PUCHAR pSrcBufVA;
UINT SrcBufLen;
PUCHAR pSrc;
UCHAR UserPriority;
UCHAR vlan_offset = 0;
RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
UserPriority = RTMP_GET_PACKET_UP(pPacket);
pSrc = pSrcBufVA;
// determine if this is a vlan packet
if (((*(pSrc + 12) << 8) + *(pSrc + 13)) == 0x8100)
vlan_offset = 4;
#ifdef CONFIG_STA_SUPPORT
#endif // CONFIG_STA_SUPPORT //
{
RTMPInitMICEngine(
pAd,
pKey->Key,
pSrc,
pSrc + 6,
UserPriority,
pKey->TxMic);
}
if (pEncap != NULL)
{
// LLC encapsulation
RTMPTkipAppend(&pAd->PrivateInfo.Tx, pEncap, 6);
// Protocol Type
RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSrc + 12 + vlan_offset, 2);
}
SrcBufLen -= (14 + vlan_offset);
pSrc += (14 + vlan_offset);
do
{
if (SrcBufLen > 0)
{
RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSrc, SrcBufLen);
}
break; // No need handle next packet
} while (TRUE); // End of copying payload
// Compute the final MIC Value
RTMPTkipGetMIC(&pAd->PrivateInfo.Tx);
}
/************************************************************/
/* tkip_sbox() */
/* Returns a 16 bit value from a 64K entry table. The Table */
/* is synthesized from two 256 entry byte wide tables. */
/************************************************************/
UINT tkip_sbox(UINT index)
{
UINT index_low;
UINT index_high;
UINT left, right;
index_low = (index % 256);
index_high = ((index >> 8) % 256);
left = Tkip_Sbox_Lower[index_low] + (Tkip_Sbox_Upper[index_low] * 256);
right = Tkip_Sbox_Upper[index_high] + (Tkip_Sbox_Lower[index_high] * 256);
return (left ^ right);
}
UINT rotr1(UINT a)
{
unsigned int b;
if ((a & 0x01) == 0x01)
{
b = (a >> 1) | 0x8000;
}
else
{
b = (a >> 1) & 0x7fff;
}
b = b % 65536;
return b;
}
VOID RTMPTkipMixKey(
UCHAR *key,
UCHAR *ta,
ULONG pnl, /* Least significant 16 bits of PN */
ULONG pnh, /* Most significant 32 bits of PN */
UCHAR *rc4key,
UINT *p1k)
{
UINT tsc0;
UINT tsc1;
UINT tsc2;
UINT ppk0;
UINT ppk1;
UINT ppk2;
UINT ppk3;
UINT ppk4;
UINT ppk5;
INT i;
INT j;
tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */
tsc1 = (unsigned int)(pnh % 65536);
tsc2 = (unsigned int)(pnl % 65536); /* lsb */
/* Phase 1, step 1 */
p1k[0] = tsc1;
p1k[1] = tsc0;
p1k[2] = (UINT)(ta[0] + (ta[1]*256));
p1k[3] = (UINT)(ta[2] + (ta[3]*256));
p1k[4] = (UINT)(ta[4] + (ta[5]*256));
/* Phase 1, step 2 */
for (i=0; i<8; i++)
{
j = 2*(i & 1);
p1k[0] = (p1k[0] + tkip_sbox( (p1k[4] ^ ((256*key[1+j]) + key[j])) % 65536 )) % 65536;
p1k[1] = (p1k[1] + tkip_sbox( (p1k[0] ^ ((256*key[5+j]) + key[4+j])) % 65536 )) % 65536;
p1k[2] = (p1k[2] + tkip_sbox( (p1k[1] ^ ((256*key[9+j]) + key[8+j])) % 65536 )) % 65536;
p1k[3] = (p1k[3] + tkip_sbox( (p1k[2] ^ ((256*key[13+j]) + key[12+j])) % 65536 )) % 65536;
p1k[4] = (p1k[4] + tkip_sbox( (p1k[3] ^ (((256*key[1+j]) + key[j]))) % 65536 )) % 65536;
p1k[4] = (p1k[4] + i) % 65536;
}
/* Phase 2, Step 1 */
ppk0 = p1k[0];
ppk1 = p1k[1];
ppk2 = p1k[2];
ppk3 = p1k[3];
ppk4 = p1k[4];
ppk5 = (p1k[4] + tsc2) % 65536;
/* Phase2, Step 2 */
ppk0 = ppk0 + tkip_sbox( (ppk5 ^ ((256*key[1]) + key[0])) % 65536);
ppk1 = ppk1 + tkip_sbox( (ppk0 ^ ((256*key[3]) + key[2])) % 65536);
ppk2 = ppk2 + tkip_sbox( (ppk1 ^ ((256*key[5]) + key[4])) % 65536);
ppk3 = ppk3 + tkip_sbox( (ppk2 ^ ((256*key[7]) + key[6])) % 65536);
ppk4 = ppk4 + tkip_sbox( (ppk3 ^ ((256*key[9]) + key[8])) % 65536);
ppk5 = ppk5 + tkip_sbox( (ppk4 ^ ((256*key[11]) + key[10])) % 65536);
ppk0 = ppk0 + rotr1(ppk5 ^ ((256*key[13]) + key[12]));
ppk1 = ppk1 + rotr1(ppk0 ^ ((256*key[15]) + key[14]));
ppk2 = ppk2 + rotr1(ppk1);
ppk3 = ppk3 + rotr1(ppk2);
ppk4 = ppk4 + rotr1(ppk3);
ppk5 = ppk5 + rotr1(ppk4);
/* Phase 2, Step 3 */
/* Phase 2, Step 3 */
tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */
tsc1 = (unsigned int)(pnh % 65536);
tsc2 = (unsigned int)(pnl % 65536); /* lsb */
rc4key[0] = (tsc2 >> 8) % 256;
rc4key[1] = (((tsc2 >> 8) % 256) | 0x20) & 0x7f;
rc4key[2] = tsc2 % 256;
rc4key[3] = ((ppk5 ^ ((256*key[1]) + key[0])) >> 1) % 256;
rc4key[4] = ppk0 % 256;
rc4key[5] = (ppk0 >> 8) % 256;
rc4key[6] = ppk1 % 256;
rc4key[7] = (ppk1 >> 8) % 256;
rc4key[8] = ppk2 % 256;
rc4key[9] = (ppk2 >> 8) % 256;
rc4key[10] = ppk3 % 256;
rc4key[11] = (ppk3 >> 8) % 256;
rc4key[12] = ppk4 % 256;
rc4key[13] = (ppk4 >> 8) % 256;
rc4key[14] = ppk5 % 256;
rc4key[15] = (ppk5 >> 8) % 256;
}
//
// TRUE: Success!
// FALSE: Decrypt Error!
//
BOOLEAN RTMPSoftDecryptTKIP(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pData,
IN ULONG DataByteCnt,
IN UCHAR UserPriority,
IN PCIPHER_KEY pWpaKey)
{
UCHAR KeyID;
UINT HeaderLen;
UCHAR fc0;
UCHAR fc1;
USHORT fc;
UINT frame_type;
UINT frame_subtype;
UINT from_ds;
UINT to_ds;
INT a4_exists;
INT qc_exists;
USHORT duration;
USHORT seq_control;
USHORT qos_control;
UCHAR TA[MAC_ADDR_LEN];
UCHAR DA[MAC_ADDR_LEN];
UCHAR SA[MAC_ADDR_LEN];
UCHAR RC4Key[16];
UINT p1k[5]; //for mix_key;
ULONG pnl;/* Least significant 16 bits of PN */
ULONG pnh;/* Most significant 32 bits of PN */
UINT num_blocks;
UINT payload_remainder;
ARCFOURCONTEXT ArcFourContext;
UINT crc32 = 0;
UINT trailfcs = 0;
UCHAR MIC[8];
UCHAR TrailMIC[8];
#ifdef RT_BIG_ENDIAN
RTMPFrameEndianChange(pAd, (PUCHAR)pData, DIR_READ, FALSE);
#endif
fc0 = *pData;
fc1 = *(pData + 1);
fc = *((PUSHORT)pData);
frame_type = ((fc0 >> 2) & 0x03);
frame_subtype = ((fc0 >> 4) & 0x0f);
from_ds = (fc1 & 0x2) >> 1;
to_ds = (fc1 & 0x1);
a4_exists = (from_ds & to_ds);
qc_exists = ((frame_subtype == 0x08) || /* Assumed QoS subtypes */
(frame_subtype == 0x09) || /* Likely to change. */
(frame_subtype == 0x0a) ||
(frame_subtype == 0x0b)
);
HeaderLen = 24;
if (a4_exists)
HeaderLen += 6;
KeyID = *((PUCHAR)(pData+ HeaderLen + 3));
KeyID = KeyID >> 6;
if (pWpaKey[KeyID].KeyLen == 0)
{
DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptTKIP failed!(KeyID[%d] Length can not be 0)\n", KeyID));
return FALSE;
}
duration = *((PUSHORT)(pData+2));
seq_control = *((PUSHORT)(pData+22));
if (qc_exists)
{
if (a4_exists)
{
qos_control = *((PUSHORT)(pData+30));
}
else
{
qos_control = *((PUSHORT)(pData+24));
}
}
if (to_ds == 0 && from_ds == 1)
{
NdisMoveMemory(DA, pData+4, MAC_ADDR_LEN);
NdisMoveMemory(SA, pData+16, MAC_ADDR_LEN);
NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN); //BSSID
}
else if (to_ds == 0 && from_ds == 0 )
{
NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN);
NdisMoveMemory(DA, pData+4, MAC_ADDR_LEN);
NdisMoveMemory(SA, pData+10, MAC_ADDR_LEN);
}
else if (to_ds == 1 && from_ds == 0)
{
NdisMoveMemory(SA, pData+10, MAC_ADDR_LEN);
NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN);
NdisMoveMemory(DA, pData+16, MAC_ADDR_LEN);
}
else if (to_ds == 1 && from_ds == 1)
{
NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN);
NdisMoveMemory(DA, pData+16, MAC_ADDR_LEN);
NdisMoveMemory(SA, pData+22, MAC_ADDR_LEN);
}
num_blocks = (DataByteCnt - 16) / 16;
payload_remainder = (DataByteCnt - 16) % 16;
pnl = (*(pData + HeaderLen)) * 256 + *(pData + HeaderLen + 2);
pnh = *((PULONG)(pData + HeaderLen + 4));
pnh = cpu2le32(pnh);
RTMPTkipMixKey(pWpaKey[KeyID].Key, TA, pnl, pnh, RC4Key, p1k);
ARCFOUR_INIT(&ArcFourContext, RC4Key, 16);
ARCFOUR_DECRYPT(&ArcFourContext, pData + HeaderLen, pData + HeaderLen + 8, DataByteCnt - HeaderLen - 8);
NdisMoveMemory(&trailfcs, pData + DataByteCnt - 8 - 4, 4);
crc32 = RTMP_CALC_FCS32(PPPINITFCS32, pData + HeaderLen, DataByteCnt - HeaderLen - 8 - 4); //Skip IV+EIV 8 bytes & Skip last 4 bytes(FCS).
crc32 ^= 0xffffffff; /* complement */
if(crc32 != cpu2le32(trailfcs))
{
DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptTKIP, WEP Data ICV Error !\n")); //ICV error.
return (FALSE);
}
NdisMoveMemory(TrailMIC, pData + DataByteCnt - 8 - 8 - 4, 8);
RTMPInitMICEngine(pAd, pWpaKey[KeyID].Key, DA, SA, UserPriority, pWpaKey[KeyID].RxMic);
RTMPTkipAppend(&pAd->PrivateInfo.Tx, pData + HeaderLen, DataByteCnt - HeaderLen - 8 - 12);
RTMPTkipGetMIC(&pAd->PrivateInfo.Tx);
NdisMoveMemory(MIC, pAd->PrivateInfo.Tx.MIC, 8);
if (!NdisEqualMemory(MIC, TrailMIC, 8))
{
DBGPRINT(RT_DEBUG_ERROR, ("RTMPSoftDecryptTKIP, WEP Data MIC Error !\n")); //MIC error.
//RTMPReportMicError(pAd, &pWpaKey[KeyID]); // marked by AlbertY @ 20060630
return (FALSE);
}
#ifdef RT_BIG_ENDIAN
RTMPFrameEndianChange(pAd, (PUCHAR)pData, DIR_READ, FALSE);
#endif
//DBGPRINT(RT_DEBUG_TRACE, "RTMPSoftDecryptTKIP Decript done!!\n");
return TRUE;
}

View file

@ -0,0 +1,500 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
rtmp_wep.c
Abstract:
Revision History:
Who When What
-------- ---------- ----------------------------------------------
Paul Wu 10-28-02 Initial
*/
#include "../rt_config.h"
UINT FCSTAB_32[256] =
{
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
/*
UCHAR WEPKEY[] = {
//IV
0x00, 0x11, 0x22,
//WEP KEY
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC
};
*/
/*
========================================================================
Routine Description:
Init WEP function.
Arguments:
pAd Pointer to our adapter
pKey Pointer to the WEP KEY
KeyId WEP Key ID
KeyLen the length of WEP KEY
pDest Pointer to the destination which Encryption data will store in.
Return Value:
None
IRQL = DISPATCH_LEVEL
Note:
========================================================================
*/
VOID RTMPInitWepEngine(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pKey,
IN UCHAR KeyId,
IN UCHAR KeyLen,
IN OUT PUCHAR pDest)
{
UINT i;
UCHAR WEPKEY[] = {
//IV
0x00, 0x11, 0x22,
//WEP KEY
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC
};
pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32; //Init crc32.
{
NdisMoveMemory(WEPKEY + 3, pKey, KeyLen);
for(i = 0; i < 3; i++)
WEPKEY[i] = RandomByte(pAd); //Call mlme RandomByte() function.
ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, WEPKEY, KeyLen + 3); //INIT SBOX, KEYLEN+3(IV)
NdisMoveMemory(pDest, WEPKEY, 3); //Append Init Vector
}
*(pDest+3) = (KeyId << 6); //Append KEYID
}
/*
========================================================================
Routine Description:
Encrypt transimitted data
Arguments:
pAd Pointer to our adapter
pSrc Pointer to the transimitted source data that will be encrypt
pDest Pointer to the destination where entryption data will be store in.
Len Indicate the length of the source data
Return Value:
None
IRQL = DISPATCH_LEVEL
Note:
========================================================================
*/
VOID RTMPEncryptData(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pSrc,
IN PUCHAR pDest,
IN UINT Len)
{
pAd->PrivateInfo.FCSCRC32 = RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, pSrc, Len);
ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest, pSrc, Len);
}
/*
========================================================================
Routine Description:
Decrypt received WEP data
Arguments:
pAdapter Pointer to our adapter
pSrc Pointer to the received data
Len the length of the received data
Return Value:
TRUE Decrypt WEP data success
FALSE Decrypt WEP data failed
Note:
========================================================================
*/
BOOLEAN RTMPSoftDecryptWEP(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pData,
IN ULONG DataByteCnt,
IN PCIPHER_KEY pGroupKey)
{
UINT trailfcs;
UINT crc32;
UCHAR KeyIdx;
UCHAR WEPKEY[] = {
//IV
0x00, 0x11, 0x22,
//WEP KEY
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC
};
UCHAR *pPayload = (UCHAR *)pData + LENGTH_802_11;
ULONG payload_len = DataByteCnt - LENGTH_802_11;
NdisMoveMemory(WEPKEY, pPayload, 3); //Get WEP IV
KeyIdx = (*(pPayload + 3) & 0xc0) >> 6;
if (pGroupKey[KeyIdx].KeyLen == 0)
return (FALSE);
NdisMoveMemory(WEPKEY + 3, pGroupKey[KeyIdx].Key, pGroupKey[KeyIdx].KeyLen);
ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, WEPKEY, pGroupKey[KeyIdx].KeyLen + 3);
ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, pPayload, pPayload + 4, payload_len - 4);
NdisMoveMemory(&trailfcs, pPayload + payload_len - 8, 4);
crc32 = RTMP_CALC_FCS32(PPPINITFCS32, pPayload, payload_len - 8); //Skip last 4 bytes(FCS).
crc32 ^= 0xffffffff; /* complement */
if(crc32 != cpu2le32(trailfcs))
{
DBGPRINT(RT_DEBUG_TRACE, ("! WEP Data CRC Error !\n")); //CRC error.
return (FALSE);
}
return (TRUE);
}
/*
========================================================================
Routine Description:
The Stream Cipher Encryption Algorithm "ARCFOUR" initialize
Arguments:
Ctx Pointer to ARCFOUR CONTEXT (SBOX)
pKey Pointer to the WEP KEY
KeyLen Indicate the length fo the WEP KEY
Return Value:
None
IRQL = DISPATCH_LEVEL
Note:
========================================================================
*/
VOID ARCFOUR_INIT(
IN PARCFOURCONTEXT Ctx,
IN PUCHAR pKey,
IN UINT KeyLen)
{
UCHAR t, u;
UINT keyindex;
UINT stateindex;
PUCHAR state;
UINT counter;
state = Ctx->STATE;
Ctx->X = 0;
Ctx->Y = 0;
for (counter = 0; counter < 256; counter++)
state[counter] = (UCHAR)counter;
keyindex = 0;
stateindex = 0;
for (counter = 0; counter < 256; counter++)
{
t = state[counter];
stateindex = (stateindex + pKey[keyindex] + t) & 0xff;
u = state[stateindex];
state[stateindex] = t;
state[counter] = u;
if (++keyindex >= KeyLen)
keyindex = 0;
}
}
/*
========================================================================
Routine Description:
Get bytes from ARCFOUR CONTEXT (S-BOX)
Arguments:
Ctx Pointer to ARCFOUR CONTEXT (SBOX)
Return Value:
UCHAR - the value of the ARCFOUR CONTEXT (S-BOX)
Note:
========================================================================
*/
UCHAR ARCFOUR_BYTE(
IN PARCFOURCONTEXT Ctx)
{
UINT x;
UINT y;
UCHAR sx, sy;
PUCHAR state;
state = Ctx->STATE;
x = (Ctx->X + 1) & 0xff;
sx = state[x];
y = (sx + Ctx->Y) & 0xff;
sy = state[y];
Ctx->X = x;
Ctx->Y = y;
state[y] = sx;
state[x] = sy;
return(state[(sx + sy) & 0xff]);
}
/*
========================================================================
Routine Description:
The Stream Cipher Decryption Algorithm
Arguments:
Ctx Pointer to ARCFOUR CONTEXT (SBOX)
pDest Pointer to the Destination
pSrc Pointer to the Source data
Len Indicate the length of the Source data
Return Value:
None
Note:
========================================================================
*/
VOID ARCFOUR_DECRYPT(
IN PARCFOURCONTEXT Ctx,
IN PUCHAR pDest,
IN PUCHAR pSrc,
IN UINT Len)
{
UINT i;
for (i = 0; i < Len; i++)
pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
}
/*
========================================================================
Routine Description:
The Stream Cipher Encryption Algorithm
Arguments:
Ctx Pointer to ARCFOUR CONTEXT (SBOX)
pDest Pointer to the Destination
pSrc Pointer to the Source data
Len Indicate the length of the Source dta
Return Value:
None
IRQL = DISPATCH_LEVEL
Note:
========================================================================
*/
VOID ARCFOUR_ENCRYPT(
IN PARCFOURCONTEXT Ctx,
IN PUCHAR pDest,
IN PUCHAR pSrc,
IN UINT Len)
{
UINT i;
for (i = 0; i < Len; i++)
pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
}
/*
========================================================================
Routine Description:
The Stream Cipher Encryption Algorithm which conform to the special requirement to encrypt GTK.
Arguments:
Ctx Pointer to ARCFOUR CONTEXT (SBOX)
pDest Pointer to the Destination
pSrc Pointer to the Source data
Len Indicate the length of the Source dta
========================================================================
*/
VOID WPAARCFOUR_ENCRYPT(
IN PARCFOURCONTEXT Ctx,
IN PUCHAR pDest,
IN PUCHAR pSrc,
IN UINT Len)
{
UINT i;
//discard first 256 bytes
for (i = 0; i < 256; i++)
ARCFOUR_BYTE(Ctx);
for (i = 0; i < Len; i++)
pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
}
/*
========================================================================
Routine Description:
Calculate a new FCS given the current FCS and the new data.
Arguments:
Fcs the original FCS value
Cp pointer to the data which will be calculate the FCS
Len the length of the data
Return Value:
UINT - FCS 32 bits
IRQL = DISPATCH_LEVEL
Note:
========================================================================
*/
UINT RTMP_CALC_FCS32(
IN UINT Fcs,
IN PUCHAR Cp,
IN INT Len)
{
while (Len--)
Fcs = (((Fcs) >> 8) ^ FCSTAB_32[((Fcs) ^ (*Cp++)) & 0xff]);
return (Fcs);
}
/*
========================================================================
Routine Description:
Get last FCS and encrypt it to the destination
Arguments:
pDest Pointer to the Destination
Return Value:
None
Note:
========================================================================
*/
VOID RTMPSetICV(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pDest)
{
pAd->PrivateInfo.FCSCRC32 ^= 0xffffffff; /* complement */
pAd->PrivateInfo.FCSCRC32 = cpu2le32(pAd->PrivateInfo.FCSCRC32);
ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest, (PUCHAR) &pAd->PrivateInfo.FCSCRC32, 4);
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,234 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
crypt_dh.c
Abstract:
Revision History:
Who When What
-------- ---------- ----------------------------------------------
Eddy 2009/01/19 Create AES-128, AES-192, AES-256, AES-CBC
*/
#include "crypt_dh.h"
#include "crypt_biginteger.h"
/*
========================================================================
Routine Description:
Diffie-Hellman public key generation
Arguments:
GValue Array in UINT8
GValueLength The length of G in bytes
PValue Array in UINT8
PValueLength The length of P in bytes
PrivateKey Private key
PrivateKeyLength The length of Private key in bytes
Return Value:
PublicKey Public key
PublicKeyLength The length of public key in bytes
Note:
Reference to RFC2631
PublicKey = G^PrivateKey (mod P)
========================================================================
*/
void DH_PublicKey_Generate (
IN UINT8 GValue[],
IN UINT GValueLength,
IN UINT8 PValue[],
IN UINT PValueLength,
IN UINT8 PrivateKey[],
IN UINT PrivateKeyLength,
OUT UINT8 PublicKey[],
INOUT UINT *PublicKeyLength)
{
PBIG_INTEGER pBI_G = NULL;
PBIG_INTEGER pBI_P = NULL;
PBIG_INTEGER pBI_PrivateKey = NULL;
PBIG_INTEGER pBI_PublicKey = NULL;
/*
* 1. Check the input parameters
* - GValueLength, PValueLength and PrivateLength must be large than zero
* - PublicKeyLength must be large or equal than PValueLength
* - PValue must be odd
*
* - PValue must be prime number (no implement)
* - GValue must be greater than 0 but less than the PValue (no implement)
*/
if (GValueLength == 0) {
DBGPRINT(RT_DEBUG_ERROR, ("DH_PublicKey_Generate: G length is (%d)\n", GValueLength));
return;
} /* End of if */
if (PValueLength == 0) {
DBGPRINT(RT_DEBUG_ERROR, ("DH_PublicKey_Generate: P length is (%d)\n", PValueLength));
return;
} /* End of if */
if (PrivateKeyLength == 0) {
DBGPRINT(RT_DEBUG_ERROR, ("DH_PublicKey_Generate: private key length is (%d)\n", PrivateKeyLength));
return;
} /* End of if */
if (*PublicKeyLength < PValueLength) {
DBGPRINT(RT_DEBUG_ERROR, ("DH_PublicKey_Generate: public key length(%d) must be large or equal than P length(%d)\n",
*PublicKeyLength, PValueLength));
return;
} /* End of if */
if (!(PValue[PValueLength - 1] & 0x1)) {
DBGPRINT(RT_DEBUG_ERROR, ("DH_PublicKey_Generate: P value must be odd\n"));
return;
} /* End of if */
/*
* 2. Transfer parameters to BigInteger structure
*/
BigInteger_Init(&pBI_G);
BigInteger_Init(&pBI_P);
BigInteger_Init(&pBI_PrivateKey);
BigInteger_Init(&pBI_PublicKey);
BigInteger_Bin2BI(GValue, GValueLength, &pBI_G);
BigInteger_Bin2BI(PValue, PValueLength, &pBI_P);
BigInteger_Bin2BI(PrivateKey, PrivateKeyLength, &pBI_PrivateKey);
/*
* 3. Calculate PublicKey = G^PrivateKey (mod P)
* - BigInteger Operation
* - Montgomery reduction
*/
BigInteger_Montgomery_ExpMod(pBI_G, pBI_PrivateKey, pBI_P, &pBI_PublicKey);
/*
* 4. Transfer BigInteger structure to char array
*/
BigInteger_BI2Bin(pBI_PublicKey, PublicKey, PublicKeyLength);
BigInteger_Free(&pBI_G);
BigInteger_Free(&pBI_P);
BigInteger_Free(&pBI_PrivateKey);
BigInteger_Free(&pBI_PublicKey);
} /* End of DH_PublicKey_Generate */
/*
========================================================================
Routine Description:
Diffie-Hellman secret key generation
Arguments:
PublicKey Public key
PublicKeyLength The length of Public key in bytes
PValue Array in UINT8
PValueLength The length of P in bytes
PrivateKey Private key
PrivateKeyLength The length of Private key in bytes
Return Value:
SecretKey Secret key
SecretKeyLength The length of secret key in bytes
Note:
Reference to RFC2631
SecretKey = PublicKey^PrivateKey (mod P)
========================================================================
*/
void DH_SecretKey_Generate (
IN UINT8 PublicKey[],
IN UINT PublicKeyLength,
IN UINT8 PValue[],
IN UINT PValueLength,
IN UINT8 PrivateKey[],
IN UINT PrivateKeyLength,
OUT UINT8 SecretKey[],
INOUT UINT *SecretKeyLength)
{
PBIG_INTEGER pBI_P = NULL;
PBIG_INTEGER pBI_SecretKey = NULL;
PBIG_INTEGER pBI_PrivateKey = NULL;
PBIG_INTEGER pBI_PublicKey = NULL;
/*
* 1. Check the input parameters
* - PublicKeyLength, PValueLength and PrivateLength must be large than zero
* - SecretKeyLength must be large or equal than PValueLength
* - PValue must be odd
*
* - PValue must be prime number (no implement)
*/
if (PublicKeyLength == 0) {
DBGPRINT(RT_DEBUG_ERROR, ("DH_SecretKey_Generate: public key length is (%d)\n", PublicKeyLength));
return;
} /* End of if */
if (PValueLength == 0) {
DBGPRINT(RT_DEBUG_ERROR, ("DH_SecretKey_Generate: P length is (%d)\n", PValueLength));
return;
} /* End of if */
if (PrivateKeyLength == 0) {
DBGPRINT(RT_DEBUG_ERROR, ("DH_SecretKey_Generate: private key length is (%d)\n", PrivateKeyLength));
return;
} /* End of if */
if (*SecretKeyLength < PValueLength) {
DBGPRINT(RT_DEBUG_ERROR, ("DH_SecretKey_Generate: secret key length(%d) must be large or equal than P length(%d)\n",
*SecretKeyLength, PValueLength));
return;
} /* End of if */
if (!(PValue[PValueLength - 1] & 0x1)) {
DBGPRINT(RT_DEBUG_ERROR, ("DH_SecretKey_Generate: P value must be odd\n"));
return;
} /* End of if */
/*
* 2. Transfer parameters to BigInteger structure
*/
BigInteger_Init(&pBI_P);
BigInteger_Init(&pBI_PrivateKey);
BigInteger_Init(&pBI_PublicKey);
BigInteger_Init(&pBI_SecretKey);
BigInteger_Bin2BI(PublicKey, PublicKeyLength, &pBI_PublicKey);
BigInteger_Bin2BI(PValue, PValueLength, &pBI_P);
BigInteger_Bin2BI(PrivateKey, PrivateKeyLength, &pBI_PrivateKey);
/*
* 3. Calculate SecretKey = PublicKey^PrivateKey (mod P)
* - BigInteger Operation
* - Montgomery reduction
*/
BigInteger_Montgomery_ExpMod(pBI_PublicKey, pBI_PrivateKey, pBI_P, &pBI_SecretKey);
/*
* 4. Transfer BigInteger structure to char array
*/
BigInteger_BI2Bin(pBI_SecretKey, SecretKey, SecretKeyLength);
BigInteger_Free(&pBI_P);
BigInteger_Free(&pBI_PrivateKey);
BigInteger_Free(&pBI_PublicKey);
BigInteger_Free(&pBI_SecretKey);
} /* End of DH_SecretKey_Generate */

View file

@ -0,0 +1,279 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************/
#include "../crypt_hmac.h"
#ifdef HMAC_SHA1_SUPPORT
/*
========================================================================
Routine Description:
HMAC using SHA1 hash function
Arguments:
key Secret key
key_len The length of the key in bytes
message Message context
message_len The length of message in bytes
macLen Request the length of message authentication code
Return Value:
mac Message authentication code
Note:
None
========================================================================
*/
VOID HMAC_SHA1 (
IN const UINT8 Key[],
IN UINT KeyLen,
IN const UINT8 Message[],
IN UINT MessageLen,
OUT UINT8 MAC[],
IN UINT MACLen)
{
SHA1_CTX_STRUC sha_ctx1;
SHA1_CTX_STRUC sha_ctx2;
UINT8 K0[SHA1_BLOCK_SIZE];
UINT8 Digest[SHA1_DIGEST_SIZE];
UINT index;
NdisZeroMemory(&sha_ctx1, sizeof(SHA1_CTX_STRUC));
NdisZeroMemory(&sha_ctx2, sizeof(SHA1_CTX_STRUC));
/*
* If the length of K = B(Block size): K0 = K.
* If the length of K > B: hash K to obtain an L byte string,
* then append (B-L) zeros to create a B-byte string K0 (i.e., K0 = H(K) || 00...00).
* If the length of K < B: append zeros to the end of K to create a B-byte string K0
*/
NdisZeroMemory(K0, SHA1_BLOCK_SIZE);
if (KeyLen <= SHA1_BLOCK_SIZE)
NdisMoveMemory(K0, Key, KeyLen);
else
RT_SHA1(Key, KeyLen, K0);
/* End of if */
/* Exclusive-Or K0 with ipad */
/* ipad: Inner pad; the byte x<><78>36<33><36> repeated B times. */
for (index = 0; index < SHA1_BLOCK_SIZE; index++)
K0[index] ^= 0x36;
/* End of for */
SHA1_Init(&sha_ctx1);
/* H(K0^ipad) */
SHA1_Append(&sha_ctx1, K0, sizeof(K0));
/* H((K0^ipad)||text) */
SHA1_Append(&sha_ctx1, Message, MessageLen);
SHA1_End(&sha_ctx1, Digest);
/* Exclusive-Or K0 with opad and remove ipad */
/* opad: Outer pad; the byte x<><78>5c<35><63> repeated B times. */
for (index = 0; index < SHA1_BLOCK_SIZE; index++)
K0[index] ^= 0x36^0x5c;
/* End of for */
SHA1_Init(&sha_ctx2);
/* H(K0^opad) */
SHA1_Append(&sha_ctx2, K0, sizeof(K0));
/* H( (K0^opad) || H((K0^ipad)||text) ) */
SHA1_Append(&sha_ctx2, Digest, SHA1_DIGEST_SIZE);
SHA1_End(&sha_ctx2, Digest);
if (MACLen > SHA1_DIGEST_SIZE)
NdisMoveMemory(MAC, Digest, SHA1_DIGEST_SIZE);
else
NdisMoveMemory(MAC, Digest, MACLen);
} /* End of HMAC_SHA1 */
#endif /* HMAC_SHA1_SUPPORT */
#ifdef HMAC_SHA256_SUPPORT
/*
========================================================================
Routine Description:
HMAC using SHA256 hash function
Arguments:
key Secret key
key_len The length of the key in bytes
message Message context
message_len The length of message in bytes
macLen Request the length of message authentication code
Return Value:
mac Message authentication code
Note:
None
========================================================================
*/
VOID HMAC_SHA256 (
IN const UINT8 Key[],
IN UINT KeyLen,
IN const UINT8 Message[],
IN UINT MessageLen,
OUT UINT8 MAC[],
IN UINT MACLen)
{
SHA256_CTX_STRUC sha_ctx1;
SHA256_CTX_STRUC sha_ctx2;
UINT8 K0[SHA256_BLOCK_SIZE];
UINT8 Digest[SHA256_DIGEST_SIZE];
UINT index;
NdisZeroMemory(&sha_ctx1, sizeof(SHA256_CTX_STRUC));
NdisZeroMemory(&sha_ctx2, sizeof(SHA256_CTX_STRUC));
/*
* If the length of K = B(Block size): K0 = K.
* If the length of K > B: hash K to obtain an L byte string,
* then append (B-L) zeros to create a B-byte string K0 (i.e., K0 = H(K) || 00...00).
* If the length of K < B: append zeros to the end of K to create a B-byte string K0
*/
NdisZeroMemory(K0, SHA256_BLOCK_SIZE);
if (KeyLen <= SHA256_BLOCK_SIZE) {
NdisMoveMemory(K0, Key, KeyLen);
} else {
RT_SHA256(Key, KeyLen, K0);
}
/* Exclusive-Or K0 with ipad */
/* ipad: Inner pad; the byte x<><78>36<33><36> repeated B times. */
for (index = 0; index < SHA256_BLOCK_SIZE; index++)
K0[index] ^= 0x36;
/* End of for */
SHA256_Init(&sha_ctx1);
/* H(K0^ipad) */
SHA256_Append(&sha_ctx1, K0, sizeof(K0));
/* H((K0^ipad)||text) */
SHA256_Append(&sha_ctx1, Message, MessageLen);
SHA256_End(&sha_ctx1, Digest);
/* Exclusive-Or K0 with opad and remove ipad */
/* opad: Outer pad; the byte x<><78>5c<35><63> repeated B times. */
for (index = 0; index < SHA256_BLOCK_SIZE; index++)
K0[index] ^= 0x36^0x5c;
/* End of for */
SHA256_Init(&sha_ctx2);
/* H(K0^opad) */
SHA256_Append(&sha_ctx2, K0, sizeof(K0));
/* H( (K0^opad) || H((K0^ipad)||text) ) */
SHA256_Append(&sha_ctx2, Digest, SHA256_DIGEST_SIZE);
SHA256_End(&sha_ctx2, Digest);
if (MACLen > SHA256_DIGEST_SIZE)
NdisMoveMemory(MAC, Digest,SHA256_DIGEST_SIZE);
else
NdisMoveMemory(MAC, Digest, MACLen);
} /* End of HMAC_SHA256 */
#endif /* HMAC_SHA256_SUPPORT */
#ifdef HMAC_MD5_SUPPORT
/*
========================================================================
Routine Description:
HMAC using MD5 hash function
Arguments:
key Secret key
key_len The length of the key in bytes
message Message context
message_len The length of message in bytes
macLen Request the length of message authentication code
Return Value:
mac Message authentication code
Note:
None
========================================================================
*/
VOID HMAC_MD5(
IN const UINT8 Key[],
IN UINT KeyLen,
IN const UINT8 Message[],
IN UINT MessageLen,
OUT UINT8 MAC[],
IN UINT MACLen)
{
MD5_CTX_STRUC md5_ctx1;
MD5_CTX_STRUC md5_ctx2;
UINT8 K0[MD5_BLOCK_SIZE];
UINT8 Digest[MD5_DIGEST_SIZE];
UINT index;
NdisZeroMemory(&md5_ctx1, sizeof(MD5_CTX_STRUC));
NdisZeroMemory(&md5_ctx2, sizeof(MD5_CTX_STRUC));
/*
* If the length of K = B(Block size): K0 = K.
* If the length of K > B: hash K to obtain an L byte string,
* then append (B-L) zeros to create a B-byte string K0 (i.e., K0 = H(K) || 00...00).
* If the length of K < B: append zeros to the end of K to create a B-byte string K0
*/
NdisZeroMemory(K0, MD5_BLOCK_SIZE);
if (KeyLen <= MD5_BLOCK_SIZE) {
NdisMoveMemory(K0, Key, KeyLen);
} else {
RT_MD5(Key, KeyLen, K0);
}
/* Exclusive-Or K0 with ipad */
/* ipad: Inner pad; the byte x<><78>36<33><36> repeated B times. */
for (index = 0; index < MD5_BLOCK_SIZE; index++)
K0[index] ^= 0x36;
/* End of for */
MD5_Init(&md5_ctx1);
/* H(K0^ipad) */
MD5_Append(&md5_ctx1, K0, sizeof(K0));
/* H((K0^ipad)||text) */
MD5_Append(&md5_ctx1, Message, MessageLen);
MD5_End(&md5_ctx1, Digest);
/* Exclusive-Or K0 with opad and remove ipad */
/* opad: Outer pad; the byte x<><78>5c<35><63> repeated B times. */
for (index = 0; index < MD5_BLOCK_SIZE; index++)
K0[index] ^= 0x36^0x5c;
/* End of for */
MD5_Init(&md5_ctx2);
/* H(K0^opad) */
MD5_Append(&md5_ctx2, K0, sizeof(K0));
/* H( (K0^opad) || H((K0^ipad)||text) ) */
MD5_Append(&md5_ctx2, Digest, MD5_DIGEST_SIZE);
MD5_End(&md5_ctx2, Digest);
if (MACLen > MD5_DIGEST_SIZE)
NdisMoveMemory(MAC, Digest, MD5_DIGEST_SIZE);
else
NdisMoveMemory(MAC, Digest, MACLen);
} /* End of HMAC_SHA256 */
#endif /* HMAC_MD5_SUPPORT */
/* End of crypt_hmac.c */

View file

@ -0,0 +1,353 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************/
#include "../crypt_md5.h"
#ifdef MD5_SUPPORT
/*
* F, G, H and I are basic MD5 functions.
*/
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
#define ROTL(x,n,w) ((x << n) | (x >> (w - n)))
#define ROTL32(x,n) ROTL(x,n,32) /* 32 bits word */
#define ROUND1(a, b, c, d, x, s, ac) { \
(a) += F((b),(c),(d)) + (x) + (UINT32)(ac); \
(a) = ROTL32((a),(s)); \
(a) += (b); \
}
#define ROUND2(a, b, c, d, x, s, ac) { \
(a) += G((b),(c),(d)) + (x) + (UINT32)(ac); \
(a) = ROTL32((a),(s)); \
(a) += (b); \
}
#define ROUND3(a, b, c, d, x, s, ac) { \
(a) += H((b),(c),(d)) + (x) + (UINT32)(ac); \
(a) = ROTL32((a),(s)); \
(a) += (b); \
}
#define ROUND4(a, b, c, d, x, s, ac) { \
(a) += I((b),(c),(d)) + (x) + (UINT32)(ac); \
(a) = ROTL32((a),(s)); \
(a) += (b); \
}
static const UINT32 MD5_DefaultHashValue[4] = {
0x67452301UL, 0xefcdab89UL, 0x98badcfeUL, 0x10325476UL
};
#endif /* MD5_SUPPORT */
#ifdef MD5_SUPPORT
/*
========================================================================
Routine Description:
Initial Md5_CTX_STRUC
Arguments:
pMD5_CTX Pointer to Md5_CTX_STRUC
Return Value:
None
Note:
None
========================================================================
*/
VOID MD5_Init (
IN MD5_CTX_STRUC *pMD5_CTX)
{
NdisMoveMemory(pMD5_CTX->HashValue, MD5_DefaultHashValue,
sizeof(MD5_DefaultHashValue));
NdisZeroMemory(pMD5_CTX->Block, MD5_BLOCK_SIZE);
pMD5_CTX->BlockLen = 0;
pMD5_CTX->MessageLen = 0;
} /* End of MD5_Init */
/*
========================================================================
Routine Description:
MD5 computation for one block (512 bits)
Arguments:
pMD5_CTX Pointer to Md5_CTX_STRUC
Return Value:
None
Note:
T[i] := floor(abs(sin(i + 1)) * (2 pow 32)), i is number of round
========================================================================
*/
VOID MD5_Hash (
IN MD5_CTX_STRUC *pMD5_CTX)
{
UINT32 X_i;
UINT32 X[16];
UINT32 a,b,c,d;
/* Prepare the message schedule, {X_i} */
NdisMoveMemory(X, pMD5_CTX->Block, MD5_BLOCK_SIZE);
for (X_i = 0; X_i < 16; X_i++)
X[X_i] = cpu2le32(X[X_i]); /* Endian Swap */
/* End of for */
/* MD5 hash computation */
/* Initialize the working variables */
a = pMD5_CTX->HashValue[0];
b = pMD5_CTX->HashValue[1];
c = pMD5_CTX->HashValue[2];
d = pMD5_CTX->HashValue[3];
/*
* Round 1
* Let [abcd k s i] denote the operation
* a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s)
*/
ROUND1(a, b, c, d, X[ 0], 7, 0xd76aa478); /* 1 */
ROUND1(d, a, b, c, X[ 1], 12, 0xe8c7b756); /* 2 */
ROUND1(c, d, a, b, X[ 2], 17, 0x242070db); /* 3 */
ROUND1(b, c, d, a, X[ 3], 22, 0xc1bdceee); /* 4 */
ROUND1(a, b, c, d, X[ 4], 7, 0xf57c0faf); /* 5 */
ROUND1(d, a, b, c, X[ 5], 12, 0x4787c62a); /* 6 */
ROUND1(c, d, a, b, X[ 6], 17, 0xa8304613); /* 7 */
ROUND1(b, c, d, a, X[ 7], 22, 0xfd469501); /* 8 */
ROUND1(a, b, c, d, X[ 8], 7, 0x698098d8); /* 9 */
ROUND1(d, a, b, c, X[ 9], 12, 0x8b44f7af); /* 10 */
ROUND1(c, d, a, b, X[10], 17, 0xffff5bb1); /* 11 */
ROUND1(b, c, d, a, X[11], 22, 0x895cd7be); /* 12 */
ROUND1(a, b, c, d, X[12], 7, 0x6b901122); /* 13 */
ROUND1(d, a, b, c, X[13], 12, 0xfd987193); /* 14 */
ROUND1(c, d, a, b, X[14], 17, 0xa679438e); /* 15 */
ROUND1(b, c, d, a, X[15], 22, 0x49b40821); /* 16 */
/*
* Round 2
* Let [abcd k s i] denote the operation
* a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s)
*/
ROUND2(a, b, c, d, X[ 1], 5, 0xf61e2562); /* 17 */
ROUND2(d, a, b, c, X[ 6], 9, 0xc040b340); /* 18 */
ROUND2(c, d, a, b, X[11], 14, 0x265e5a51); /* 19 */
ROUND2(b, c, d, a, X[ 0], 20, 0xe9b6c7aa); /* 20 */
ROUND2(a, b, c, d, X[ 5], 5, 0xd62f105d); /* 21 */
ROUND2(d, a, b, c, X[10], 9, 0x2441453); /* 22 */
ROUND2(c, d, a, b, X[15], 14, 0xd8a1e681); /* 23 */
ROUND2(b, c, d, a, X[ 4], 20, 0xe7d3fbc8); /* 24 */
ROUND2(a, b, c, d, X[ 9], 5, 0x21e1cde6); /* 25 */
ROUND2(d, a, b, c, X[14], 9, 0xc33707d6); /* 26 */
ROUND2(c, d, a, b, X[ 3], 14, 0xf4d50d87); /* 27 */
ROUND2(b, c, d, a, X[ 8], 20, 0x455a14ed); /* 28 */
ROUND2(a, b, c, d, X[13], 5, 0xa9e3e905); /* 29 */
ROUND2(d, a, b, c, X[ 2], 9, 0xfcefa3f8); /* 30 */
ROUND2(c, d, a, b, X[ 7], 14, 0x676f02d9); /* 31 */
ROUND2(b, c, d, a, X[12], 20, 0x8d2a4c8a); /* 32 */
/*
* Round 3
* Let [abcd k s t] denote the operation
* a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s)
*/
ROUND3(a, b, c, d, X[ 5], 4, 0xfffa3942); /* 33 */
ROUND3(d, a, b, c, X[ 8], 11, 0x8771f681); /* 34 */
ROUND3(c, d, a, b, X[11], 16, 0x6d9d6122); /* 35 */
ROUND3(b, c, d, a, X[14], 23, 0xfde5380c); /* 36 */
ROUND3(a, b, c, d, X[ 1], 4, 0xa4beea44); /* 37 */
ROUND3(d, a, b, c, X[ 4], 11, 0x4bdecfa9); /* 38 */
ROUND3(c, d, a, b, X[ 7], 16, 0xf6bb4b60); /* 39 */
ROUND3(b, c, d, a, X[10], 23, 0xbebfbc70); /* 40 */
ROUND3(a, b, c, d, X[13], 4, 0x289b7ec6); /* 41 */
ROUND3(d, a, b, c, X[ 0], 11, 0xeaa127fa); /* 42 */
ROUND3(c, d, a, b, X[ 3], 16, 0xd4ef3085); /* 43 */
ROUND3(b, c, d, a, X[ 6], 23, 0x4881d05); /* 44 */
ROUND3(a, b, c, d, X[ 9], 4, 0xd9d4d039); /* 45 */
ROUND3(d, a, b, c, X[12], 11, 0xe6db99e5); /* 46 */
ROUND3(c, d, a, b, X[15], 16, 0x1fa27cf8); /* 47 */
ROUND3(b, c, d, a, X[ 2], 23, 0xc4ac5665); /* 48 */
/*
* Round 4
* Let [abcd k s t] denote the operation
* a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s)
*/
ROUND4(a, b, c, d, X[ 0], 6, 0xf4292244); /* 49 */
ROUND4(d, a, b, c, X[ 7], 10, 0x432aff97); /* 50 */
ROUND4(c, d, a, b, X[14], 15, 0xab9423a7); /* 51 */
ROUND4(b, c, d, a, X[ 5], 21, 0xfc93a039); /* 52 */
ROUND4(a, b, c, d, X[12], 6, 0x655b59c3); /* 53 */
ROUND4(d, a, b, c, X[ 3], 10, 0x8f0ccc92); /* 54 */
ROUND4(c, d, a, b, X[10], 15, 0xffeff47d); /* 55 */
ROUND4(b, c, d, a, X[ 1], 21, 0x85845dd1); /* 56 */
ROUND4(a, b, c, d, X[ 8], 6, 0x6fa87e4f); /* 57 */
ROUND4(d, a, b, c, X[15], 10, 0xfe2ce6e0); /* 58 */
ROUND4(c, d, a, b, X[ 6], 15, 0xa3014314); /* 59 */
ROUND4(b, c, d, a, X[13], 21, 0x4e0811a1); /* 60 */
ROUND4(a, b, c, d, X[ 4], 6, 0xf7537e82); /* 61 */
ROUND4(d, a, b, c, X[11], 10, 0xbd3af235); /* 62 */
ROUND4(c, d, a, b, X[ 2], 15, 0x2ad7d2bb); /* 63 */
ROUND4(b, c, d, a, X[ 9], 21, 0xeb86d391); /* 64 */
/* Compute the i^th intermediate hash value H^(i) */
pMD5_CTX->HashValue[0] += a;
pMD5_CTX->HashValue[1] += b;
pMD5_CTX->HashValue[2] += c;
pMD5_CTX->HashValue[3] += d;
NdisZeroMemory(pMD5_CTX->Block, MD5_BLOCK_SIZE);
pMD5_CTX->BlockLen = 0;
} /* End of MD5_Hash */
/*
========================================================================
Routine Description:
The message is appended to block. If block size > 64 bytes, the MD5_Hash
will be called.
Arguments:
pMD5_CTX Pointer to MD5_CTX_STRUC
message Message context
messageLen The length of message in bytes
Return Value:
None
Note:
None
========================================================================
*/
VOID MD5_Append (
IN MD5_CTX_STRUC *pMD5_CTX,
IN const UINT8 Message[],
IN UINT MessageLen)
{
UINT appendLen = 0;
UINT diffLen = 0;
while (appendLen != MessageLen) {
diffLen = MessageLen - appendLen;
if ((pMD5_CTX->BlockLen + diffLen) < MD5_BLOCK_SIZE) {
NdisMoveMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen,
Message + appendLen, diffLen);
pMD5_CTX->BlockLen += diffLen;
appendLen += diffLen;
}
else
{
NdisMoveMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen,
Message + appendLen, MD5_BLOCK_SIZE - pMD5_CTX->BlockLen);
appendLen += (MD5_BLOCK_SIZE - pMD5_CTX->BlockLen);
pMD5_CTX->BlockLen = MD5_BLOCK_SIZE;
MD5_Hash(pMD5_CTX);
} /* End of if */
} /* End of while */
pMD5_CTX->MessageLen += MessageLen;
} /* End of MD5_Append */
/*
========================================================================
Routine Description:
1. Append bit 1 to end of the message
2. Append the length of message in rightmost 64 bits
3. Transform the Hash Value to digest message
Arguments:
pMD5_CTX Pointer to MD5_CTX_STRUC
Return Value:
digestMessage Digest message
Note:
None
========================================================================
*/
VOID MD5_End (
IN MD5_CTX_STRUC *pMD5_CTX,
OUT UINT8 DigestMessage[])
{
UINT index;
UINT64 message_length_bits;
/* append 1 bits to end of the message */
NdisFillMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen, 1, 0x80);
/* 55 = 64 - 8 - 1: append 1 bit(1 byte) and message length (8 bytes) */
if (pMD5_CTX->BlockLen > 55)
MD5_Hash(pMD5_CTX);
/* End of if */
/* Append the length of message in rightmost 64 bits */
message_length_bits = pMD5_CTX->MessageLen*8;
message_length_bits = cpu2le64(message_length_bits);
NdisMoveMemory(&pMD5_CTX->Block[56], &message_length_bits, 8);
MD5_Hash(pMD5_CTX);
/* Return message digest, transform the UINT32 hash value to bytes */
for (index = 0; index < 4;index++)
pMD5_CTX->HashValue[index] = cpu2le32(pMD5_CTX->HashValue[index]);
/* End of for */
NdisMoveMemory(DigestMessage, pMD5_CTX->HashValue, MD5_DIGEST_SIZE);
} /* End of MD5_End */
/*
========================================================================
Routine Description:
MD5 algorithm
Arguments:
message Message context
messageLen The length of message in bytes
Return Value:
digestMessage Digest message
Note:
None
========================================================================
*/
VOID RT_MD5 (
IN const UINT8 Message[],
IN UINT MessageLen,
OUT UINT8 DigestMessage[])
{
MD5_CTX_STRUC md5_ctx;
NdisZeroMemory(&md5_ctx, sizeof(MD5_CTX_STRUC));
MD5_Init(&md5_ctx);
MD5_Append(&md5_ctx, Message, MessageLen);
MD5_End(&md5_ctx, DigestMessage);
} /* End of RT_MD5 */
#endif /* MD5_SUPPORT */
/* End of crypt_md5.c */

View file

@ -0,0 +1,536 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************/
#include "../crypt_sha2.h"
/* Basic operations */
#define SHR(x,n) (x >> n) /* SHR(x)^n, right shift n bits , x is w-bit word, 0 <= n <= w */
#define ROTR(x,n,w) ((x >> n) | (x << (w - n))) /* ROTR(x)^n, circular right shift n bits , x is w-bit word, 0 <= n <= w */
#define ROTL(x,n,w) ((x << n) | (x >> (w - n))) /* ROTL(x)^n, circular left shift n bits , x is w-bit word, 0 <= n <= w */
#define ROTR32(x,n) ROTR(x,n,32) /* 32 bits word */
#define ROTL32(x,n) ROTL(x,n,32) /* 32 bits word */
/* Basic functions */
#define Ch(x,y,z) ((x & y) ^ ((~x) & z))
#define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z))
#define Parity(x,y,z) (x ^ y ^ z)
#ifdef SHA1_SUPPORT
/* SHA1 constants */
#define SHA1_MASK 0x0000000f
static const UINT32 SHA1_K[4] = {
0x5a827999UL, 0x6ed9eba1UL, 0x8f1bbcdcUL, 0xca62c1d6UL
};
static const UINT32 SHA1_DefaultHashValue[5] = {
0x67452301UL, 0xefcdab89UL, 0x98badcfeUL, 0x10325476UL, 0xc3d2e1f0UL
};
#endif /* SHA1_SUPPORT */
#ifdef SHA256_SUPPORT
/* SHA256 functions */
#define Zsigma_256_0(x) (ROTR32(x,2) ^ ROTR32(x,13) ^ ROTR32(x,22))
#define Zsigma_256_1(x) (ROTR32(x,6) ^ ROTR32(x,11) ^ ROTR32(x,25))
#define Sigma_256_0(x) (ROTR32(x,7) ^ ROTR32(x,18) ^ SHR(x,3))
#define Sigma_256_1(x) (ROTR32(x,17) ^ ROTR32(x,19) ^ SHR(x,10))
/* SHA256 constants */
static const UINT32 SHA256_K[64] = {
0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
};
static const UINT32 SHA256_DefaultHashValue[8] = {
0x6a09e667UL, 0xbb67ae85UL, 0x3c6ef372UL, 0xa54ff53aUL,
0x510e527fUL, 0x9b05688cUL, 0x1f83d9abUL, 0x5be0cd19UL
};
#endif /* SHA256_SUPPORT */
#ifdef SHA1_SUPPORT
/*
========================================================================
Routine Description:
Initial SHA1_CTX_STRUC
Arguments:
pSHA_CTX Pointer to SHA1_CTX_STRUC
Return Value:
None
Note:
None
========================================================================
*/
VOID SHA1_Init (
IN SHA1_CTX_STRUC *pSHA_CTX)
{
NdisMoveMemory(pSHA_CTX->HashValue, SHA1_DefaultHashValue,
sizeof(SHA1_DefaultHashValue));
NdisZeroMemory(pSHA_CTX->Block, SHA1_BLOCK_SIZE);
pSHA_CTX->MessageLen = 0;
pSHA_CTX->BlockLen = 0;
} /* End of SHA1_Init */
/*
========================================================================
Routine Description:
SHA1 computation for one block (512 bits)
Arguments:
pSHA_CTX Pointer to SHA1_CTX_STRUC
Return Value:
None
Note:
None
========================================================================
*/
VOID SHA1_Hash (
IN SHA1_CTX_STRUC *pSHA_CTX)
{
UINT32 W_i,t,s;
UINT32 W[16];
UINT32 a,b,c,d,e,T,f_t = 0;
/* Prepare the message schedule, {W_i}, 0 < t < 15 */
NdisMoveMemory(W, pSHA_CTX->Block, SHA1_BLOCK_SIZE);
for (W_i = 0; W_i < 16; W_i++)
W[W_i] = cpu2be32(W[W_i]); /* Endian Swap */
/* End of for */
/* SHA256 hash computation */
/* Initialize the working variables */
a = pSHA_CTX->HashValue[0];
b = pSHA_CTX->HashValue[1];
c = pSHA_CTX->HashValue[2];
d = pSHA_CTX->HashValue[3];
e = pSHA_CTX->HashValue[4];
/* 80 rounds */
for (t = 0;t < 80;t++) {
s = t & SHA1_MASK;
if (t > 15) { /* Prepare the message schedule, {W_i}, 16 < t < 79 */
W[s] = (W[(s+13) & SHA1_MASK]) ^ (W[(s+8) & SHA1_MASK]) ^ (W[(s+2) & SHA1_MASK]) ^ W[s];
W[s] = ROTL32(W[s],1);
} /* End of if */
switch (t / 20) {
case 0:
f_t = Ch(b,c,d);
break;
case 1:
f_t = Parity(b,c,d);
break;
case 2:
f_t = Maj(b,c,d);
break;
case 3:
f_t = Parity(b,c,d);
break;
} /* End of switch */
T = ROTL32(a,5) + f_t + e + SHA1_K[t / 20] + W[s];
e = d;
d = c;
c = ROTL32(b,30);
b = a;
a = T;
} /* End of for */
/* Compute the i^th intermediate hash value H^(i) */
pSHA_CTX->HashValue[0] += a;
pSHA_CTX->HashValue[1] += b;
pSHA_CTX->HashValue[2] += c;
pSHA_CTX->HashValue[3] += d;
pSHA_CTX->HashValue[4] += e;
NdisZeroMemory(pSHA_CTX->Block, SHA1_BLOCK_SIZE);
pSHA_CTX->BlockLen = 0;
} /* End of SHA1_Hash */
/*
========================================================================
Routine Description:
The message is appended to block. If block size > 64 bytes, the SHA1_Hash
will be called.
Arguments:
pSHA_CTX Pointer to SHA1_CTX_STRUC
message Message context
messageLen The length of message in bytes
Return Value:
None
Note:
None
========================================================================
*/
VOID SHA1_Append (
IN SHA1_CTX_STRUC *pSHA_CTX,
IN const UINT8 Message[],
IN UINT MessageLen)
{
UINT appendLen = 0;
UINT diffLen = 0;
while (appendLen != MessageLen) {
diffLen = MessageLen - appendLen;
if ((pSHA_CTX->BlockLen + diffLen) < SHA1_BLOCK_SIZE) {
NdisMoveMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen,
Message + appendLen, diffLen);
pSHA_CTX->BlockLen += diffLen;
appendLen += diffLen;
}
else
{
NdisMoveMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen,
Message + appendLen, SHA1_BLOCK_SIZE - pSHA_CTX->BlockLen);
appendLen += (SHA1_BLOCK_SIZE - pSHA_CTX->BlockLen);
pSHA_CTX->BlockLen = SHA1_BLOCK_SIZE;
SHA1_Hash(pSHA_CTX);
} /* End of if */
} /* End of while */
pSHA_CTX->MessageLen += MessageLen;
} /* End of SHA1_Append */
/*
========================================================================
Routine Description:
1. Append bit 1 to end of the message
2. Append the length of message in rightmost 64 bits
3. Transform the Hash Value to digest message
Arguments:
pSHA_CTX Pointer to SHA1_CTX_STRUC
Return Value:
digestMessage Digest message
Note:
None
========================================================================
*/
VOID SHA1_End (
IN SHA1_CTX_STRUC *pSHA_CTX,
OUT UINT8 DigestMessage[])
{
UINT index;
UINT64 message_length_bits;
/* Append bit 1 to end of the message */
NdisFillMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen, 1, 0x80);
/* 55 = 64 - 8 - 1: append 1 bit(1 byte) and message length (8 bytes) */
if (pSHA_CTX->BlockLen > 55)
SHA1_Hash(pSHA_CTX);
/* End of if */
/* Append the length of message in rightmost 64 bits */
message_length_bits = pSHA_CTX->MessageLen*8;
message_length_bits = cpu2be64(message_length_bits);
NdisMoveMemory(&pSHA_CTX->Block[56], &message_length_bits, 8);
SHA1_Hash(pSHA_CTX);
/* Return message digest, transform the UINT32 hash value to bytes */
for (index = 0; index < 5;index++)
pSHA_CTX->HashValue[index] = cpu2be32(pSHA_CTX->HashValue[index]);
/* End of for */
NdisMoveMemory(DigestMessage, pSHA_CTX->HashValue, SHA1_DIGEST_SIZE);
} /* End of SHA1_End */
/*
========================================================================
Routine Description:
SHA1 algorithm
Arguments:
message Message context
messageLen The length of message in bytes
Return Value:
digestMessage Digest message
Note:
None
========================================================================
*/
VOID RT_SHA1 (
IN const UINT8 Message[],
IN UINT MessageLen,
OUT UINT8 DigestMessage[])
{
SHA1_CTX_STRUC sha_ctx;
NdisZeroMemory(&sha_ctx, sizeof(SHA1_CTX_STRUC));
SHA1_Init(&sha_ctx);
SHA1_Append(&sha_ctx, Message, MessageLen);
SHA1_End(&sha_ctx, DigestMessage);
} /* End of RT_SHA1 */
#endif /* SHA1_SUPPORT */
#ifdef SHA256_SUPPORT
/*
========================================================================
Routine Description:
Initial SHA256_CTX_STRUC
Arguments:
pSHA_CTX Pointer to SHA256_CTX_STRUC
Return Value:
None
Note:
None
========================================================================
*/
VOID SHA256_Init (
IN SHA256_CTX_STRUC *pSHA_CTX)
{
NdisMoveMemory(pSHA_CTX->HashValue, SHA256_DefaultHashValue,
sizeof(SHA256_DefaultHashValue));
NdisZeroMemory(pSHA_CTX->Block, SHA256_BLOCK_SIZE);
pSHA_CTX->MessageLen = 0;
pSHA_CTX->BlockLen = 0;
} /* End of SHA256_Init */
/*
========================================================================
Routine Description:
SHA256 computation for one block (512 bits)
Arguments:
pSHA_CTX Pointer to SHA256_CTX_STRUC
Return Value:
None
Note:
None
========================================================================
*/
VOID SHA256_Hash (
IN SHA256_CTX_STRUC *pSHA_CTX)
{
UINT32 W_i,t;
UINT32 W[64];
UINT32 a,b,c,d,e,f,g,h,T1,T2;
/* Prepare the message schedule, {W_i}, 0 < t < 15 */
NdisMoveMemory(W, pSHA_CTX->Block, SHA256_BLOCK_SIZE);
for (W_i = 0; W_i < 16; W_i++)
W[W_i] = cpu2be32(W[W_i]); /* Endian Swap */
/* End of for */
/* SHA256 hash computation */
/* Initialize the working variables */
a = pSHA_CTX->HashValue[0];
b = pSHA_CTX->HashValue[1];
c = pSHA_CTX->HashValue[2];
d = pSHA_CTX->HashValue[3];
e = pSHA_CTX->HashValue[4];
f = pSHA_CTX->HashValue[5];
g = pSHA_CTX->HashValue[6];
h = pSHA_CTX->HashValue[7];
/* 64 rounds */
for (t = 0;t < 64;t++) {
if (t > 15) /* Prepare the message schedule, {W_i}, 16 < t < 63 */
W[t] = Sigma_256_1(W[t-2]) + W[t-7] + Sigma_256_0(W[t-15]) + W[t-16];
/* End of if */
T1 = h + Zsigma_256_1(e) + Ch(e,f,g) + SHA256_K[t] + W[t];
T2 = Zsigma_256_0(a) + Maj(a,b,c);
h = g;
g = f;
f = e;
e = d + T1;
d = c;
c = b;
b = a;
a = T1 + T2;
} /* End of for */
/* Compute the i^th intermediate hash value H^(i) */
pSHA_CTX->HashValue[0] += a;
pSHA_CTX->HashValue[1] += b;
pSHA_CTX->HashValue[2] += c;
pSHA_CTX->HashValue[3] += d;
pSHA_CTX->HashValue[4] += e;
pSHA_CTX->HashValue[5] += f;
pSHA_CTX->HashValue[6] += g;
pSHA_CTX->HashValue[7] += h;
NdisZeroMemory(pSHA_CTX->Block, SHA256_BLOCK_SIZE);
pSHA_CTX->BlockLen = 0;
} /* End of SHA256_Hash */
/*
========================================================================
Routine Description:
The message is appended to block. If block size > 64 bytes, the SHA256_Hash
will be called.
Arguments:
pSHA_CTX Pointer to SHA256_CTX_STRUC
message Message context
messageLen The length of message in bytes
Return Value:
None
Note:
None
========================================================================
*/
VOID SHA256_Append (
IN SHA256_CTX_STRUC *pSHA_CTX,
IN const UINT8 Message[],
IN UINT MessageLen)
{
UINT appendLen = 0;
UINT diffLen = 0;
while (appendLen != MessageLen) {
diffLen = MessageLen - appendLen;
if ((pSHA_CTX->BlockLen + diffLen) < SHA256_BLOCK_SIZE) {
NdisMoveMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen,
Message + appendLen, diffLen);
pSHA_CTX->BlockLen += diffLen;
appendLen += diffLen;
}
else
{
NdisMoveMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen,
Message + appendLen, SHA256_BLOCK_SIZE - pSHA_CTX->BlockLen);
appendLen += (SHA256_BLOCK_SIZE - pSHA_CTX->BlockLen);
pSHA_CTX->BlockLen = SHA256_BLOCK_SIZE;
SHA256_Hash(pSHA_CTX);
} /* End of if */
} /* End of while */
pSHA_CTX->MessageLen += MessageLen;
} /* End of SHA256_Append */
/*
========================================================================
Routine Description:
1. Append bit 1 to end of the message
2. Append the length of message in rightmost 64 bits
3. Transform the Hash Value to digest message
Arguments:
pSHA_CTX Pointer to SHA256_CTX_STRUC
Return Value:
digestMessage Digest message
Note:
None
========================================================================
*/
VOID SHA256_End (
IN SHA256_CTX_STRUC *pSHA_CTX,
OUT UINT8 DigestMessage[])
{
UINT index;
UINT64 message_length_bits;
/* Append bit 1 to end of the message */
NdisFillMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen, 1, 0x80);
/* 55 = 64 - 8 - 1: append 1 bit(1 byte) and message length (8 bytes) */
if (pSHA_CTX->BlockLen > 55)
SHA256_Hash(pSHA_CTX);
/* End of if */
/* Append the length of message in rightmost 64 bits */
message_length_bits = pSHA_CTX->MessageLen*8;
message_length_bits = cpu2be64(message_length_bits);
NdisMoveMemory(&pSHA_CTX->Block[56], &message_length_bits, 8);
SHA256_Hash(pSHA_CTX);
/* Return message digest, transform the UINT32 hash value to bytes */
for (index = 0; index < 8;index++)
pSHA_CTX->HashValue[index] = cpu2be32(pSHA_CTX->HashValue[index]);
/* End of for */
NdisMoveMemory(DigestMessage, pSHA_CTX->HashValue, SHA256_DIGEST_SIZE);
} /* End of SHA256_End */
/*
========================================================================
Routine Description:
SHA256 algorithm
Arguments:
message Message context
messageLen The length of message in bytes
Return Value:
digestMessage Digest message
Note:
None
========================================================================
*/
VOID RT_SHA256 (
IN const UINT8 Message[],
IN UINT MessageLen,
OUT UINT8 DigestMessage[])
{
SHA256_CTX_STRUC sha_ctx;
NdisZeroMemory(&sha_ctx, sizeof(SHA256_CTX_STRUC));
SHA256_Init(&sha_ctx);
SHA256_Append(&sha_ctx, Message, MessageLen);
SHA256_End(&sha_ctx, DigestMessage);
} /* End of RT_SHA256 */
#endif /* SHA256_SUPPORT */
/* End of crypt_sha2.c */

View file

@ -0,0 +1,481 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
ap_dfs.c
Abstract:
Support DFS function.
Revision History:
Who When What
-------- ---------- ----------------------------------------------
*/
#include "../rt_config.h"
typedef struct _RADAR_DURATION_TABLE
{
ULONG RDDurRegion;
ULONG RadarSignalDuration;
ULONG Tolerance;
} RADAR_DURATION_TABLE, *PRADAR_DURATION_TABLE;
UCHAR RdIdleTimeTable[MAX_RD_REGION][4] =
{
{9, 250, 250, 250}, // CE
#ifdef DFS_FCC_BW40_FIX
{1, 250, 250, 250}, // FCC
#else
{4, 250, 250, 250}, // FCC
#endif
{4, 250, 250, 250}, // JAP
{15, 250, 250, 250}, // JAP_W53
{4, 250, 250, 250} // JAP_W56
};
#ifdef TONE_RADAR_DETECT_SUPPORT
static void ToneRadarProgram(PRTMP_ADAPTER pAd);
static void ToneRadarEnable(PRTMP_ADAPTER pAd);
#endif // TONE_RADAR_DETECT_SUPPORT //
#ifdef DFS_SUPPORT
/*
========================================================================
Routine Description:
Bbp Radar detection routine
Arguments:
pAd Pointer to our adapter
Return Value:
========================================================================
*/
VOID BbpRadarDetectionStart(
IN PRTMP_ADAPTER pAd)
{
UINT8 RadarPeriod;
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 114, 0x02);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 121, 0x20);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 122, 0x00);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 123, 0x08/*0x80*/);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 124, 0x28);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 125, 0xff);
#ifdef MERGE_ARCH_TEAM
if ((pAd->CommonCfg.RadarDetect.RDDurRegion == JAP) || (pAd->CommonCfg.RadarDetect.RDDurRegion == JAP_W53) || (pAd->CommonCfg.RadarDetect.RDDurRegion == JAP_W56))
{
pAd->CommonCfg.RadarDetect.RDDurRegion = JAP;
pAd->CommonCfg.RadarDetect.RDDurRegion = JapRadarType(pAd);
if (pAd->CommonCfg.RadarDetect.RDDurRegion == JAP_W56)
{
pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
}
else if (pAd->CommonCfg.RadarDetect.RDDurRegion == JAP_W53)
{
pAd->CommonCfg.RadarDetect.DfsSessionTime = 15;
}
#ifdef CARRIER_DETECTION_SUPPORT
pAd->CommonCfg.CarrierDetect.Enable = 1;
#endif // CARRIER_DETECTION_SUPPORT //
}
#endif // MERGE_ARCH_TEAM //
RadarPeriod = ((UINT)RdIdleTimeTable[pAd->CommonCfg.RadarDetect.RDDurRegion][0] + (UINT)pAd->CommonCfg.RadarDetect.DfsSessionTime) < 250 ?
(RdIdleTimeTable[pAd->CommonCfg.RadarDetect.RDDurRegion][0] + pAd->CommonCfg.RadarDetect.DfsSessionTime) : 250;
#ifdef MERGE_ARCH_TEAM
#else // Original RT28xx source code.
RTMP_IO_WRITE8(pAd, 0x7020, 0x1d);
RTMP_IO_WRITE8(pAd, 0x7021, 0x40);
#endif // MERGE_ARCH_TEAM //
RadarDetectionStart(pAd, 0, RadarPeriod);
return;
}
/*
========================================================================
Routine Description:
Bbp Radar detection routine
Arguments:
pAd Pointer to our adapter
Return Value:
========================================================================
*/
VOID BbpRadarDetectionStop(
IN PRTMP_ADAPTER pAd)
{
RTMP_IO_WRITE8(pAd, 0x7020, 0x1d);
RTMP_IO_WRITE8(pAd, 0x7021, 0x60);
RadarDetectionStop(pAd);
return;
}
/*
========================================================================
Routine Description:
Radar detection routine
Arguments:
pAd Pointer to our adapter
Return Value:
========================================================================
*/
VOID RadarDetectionStart(
IN PRTMP_ADAPTER pAd,
IN BOOLEAN CTSProtect,
IN UINT8 CTSPeriod)
{
UINT8 DfsActiveTime = (pAd->CommonCfg.RadarDetect.DfsSessionTime & 0x1f);
UINT8 CtsProtect = (CTSProtect == 1) ? 0x02 : 0x01; // CTS protect.
if (CTSProtect != 0)
{
switch(pAd->CommonCfg.RadarDetect.RDDurRegion)
{
case FCC:
case JAP_W56:
CtsProtect = 0x03;
break;
case JAP:
{
UCHAR RDDurRegion;
RDDurRegion = JapRadarType(pAd);
if (RDDurRegion == JAP_W56)
CtsProtect = 0x03;
else
CtsProtect = 0x02;
break;
}
case CE:
case JAP_W53:
default:
CtsProtect = 0x02;
break;
}
}
else
CtsProtect = 0x01;
// send start-RD with CTS protection command to MCU
// highbyte [7] reserve
// highbyte [6:5] 0x: stop Carrier/Radar detection
// highbyte [10]: Start Carrier/Radar detection without CTS protection, 11: Start Carrier/Radar detection with CTS protection
// highbyte [4:0] Radar/carrier detection duration. In 1ms.
// lowbyte [7:0] Radar/carrier detection period, in 1ms.
AsicSendCommandToMcu(pAd, 0x60, 0xff, CTSPeriod, DfsActiveTime | (CtsProtect << 5));
//AsicSendCommandToMcu(pAd, 0x63, 0xff, 10, 0);
return;
}
/*
========================================================================
Routine Description:
Radar detection routine
Arguments:
pAd Pointer to our adapter
Return Value:
TRUE Found radar signal
FALSE Not found radar signal
========================================================================
*/
VOID RadarDetectionStop(
IN PRTMP_ADAPTER pAd)
{
DBGPRINT(RT_DEBUG_TRACE,("RadarDetectionStop.\n"));
AsicSendCommandToMcu(pAd, 0x60, 0xff, 0x00, 0x00); // send start-RD with CTS protection command to MCU
return;
}
#endif // DFS_SUPPORT //
/*
========================================================================
Routine Description:
Radar channel check routine
Arguments:
pAd Pointer to our adapter
Return Value:
TRUE need to do radar detect
FALSE need not to do radar detect
========================================================================
*/
BOOLEAN RadarChannelCheck(
IN PRTMP_ADAPTER pAd,
IN UCHAR Ch)
{
INT i;
BOOLEAN result = FALSE;
for (i=0; i<pAd->ChannelListNum; i++)
{
if (Ch == pAd->ChannelList[i].Channel)
{
result = pAd->ChannelList[i].DfsReq;
break;
}
}
return result;
}
#ifdef DFS_SUPPORT
ULONG JapRadarType(
IN PRTMP_ADAPTER pAd)
{
ULONG i;
const UCHAR Channel[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
if (pAd->CommonCfg.RadarDetect.RDDurRegion != JAP)
{
return pAd->CommonCfg.RadarDetect.RDDurRegion;
}
for (i=0; i<15; i++)
{
if (pAd->CommonCfg.Channel == Channel[i])
{
break;
}
}
if (i < 4)
return JAP_W53;
else if (i < 15)
return JAP_W56;
else
return JAP; // W52
}
ULONG RTMPBbpReadRadarDuration(
IN PRTMP_ADAPTER pAd)
{
UINT8 byteValue = 0;
ULONG result;
BBP_IO_READ8_BY_REG_ID(pAd, BBP_R115, &byteValue);
result = 0;
switch (byteValue)
{
case 1: // radar signal detected by pulse mode.
case 2: // radar signal detected by width mode.
result = RTMPReadRadarDuration(pAd);
break;
case 0: // No radar signal.
default:
result = 0;
break;
}
return result;
}
ULONG RTMPReadRadarDuration(
IN PRTMP_ADAPTER pAd)
{
ULONG result = 0;
#ifdef DFS_SUPPORT
UINT8 duration1 = 0, duration2 = 0, duration3 = 0;
BBP_IO_READ8_BY_REG_ID(pAd, BBP_R116, &duration1);
BBP_IO_READ8_BY_REG_ID(pAd, BBP_R117, &duration2);
BBP_IO_READ8_BY_REG_ID(pAd, BBP_R118, &duration3);
result = (duration1 << 16) + (duration2 << 8) + duration3;
#endif // DFS_SUPPORT //
return result;
}
VOID RTMPCleanRadarDuration(
IN PRTMP_ADAPTER pAd)
{
return;
}
/*
========================================================================
Routine Description:
Radar wave detection. The API should be invoke each second.
Arguments:
pAd - Adapter pointer
Return Value:
None
========================================================================
*/
VOID ApRadarDetectPeriodic(
IN PRTMP_ADAPTER pAd)
{
INT i;
pAd->CommonCfg.RadarDetect.InServiceMonitorCount++;
for (i=0; i<pAd->ChannelListNum; i++)
{
if (pAd->ChannelList[i].RemainingTimeForUse > 0)
{
pAd->ChannelList[i].RemainingTimeForUse --;
if ((pAd->Mlme.PeriodicRound%5) == 0)
{
DBGPRINT(RT_DEBUG_TRACE, ("RadarDetectPeriodic - ch=%d, RemainingTimeForUse=%d\n", pAd->ChannelList[i].Channel, pAd->ChannelList[i].RemainingTimeForUse));
}
}
}
//radar detect
if ((pAd->CommonCfg.Channel > 14)
&& (pAd->CommonCfg.bIEEE80211H == 1)
&& RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
{
RadarDetectPeriodic(pAd);
}
return;
}
// Periodic Radar detection, switch channel will occur in RTMPHandleTBTTInterrupt()
// Before switch channel, driver needs doing channel switch announcement.
VOID RadarDetectPeriodic(
IN PRTMP_ADAPTER pAd)
{
// need to check channel availability, after switch channel
if (pAd->CommonCfg.RadarDetect.RDMode != RD_SILENCE_MODE)
return;
// channel availability check time is 60sec, use 65 for assurance
if (pAd->CommonCfg.RadarDetect.RDCount++ > pAd->CommonCfg.RadarDetect.ChMovingTime)
{
DBGPRINT(RT_DEBUG_TRACE, ("Not found radar signal, start send beacon and radar detection in service monitor\n\n"));
BbpRadarDetectionStop(pAd);
AsicEnableBssSync(pAd);
pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
return;
}
return;
}
#endif // DFS_SUPPORT //
#ifdef DFS_SUPPORT
/*
==========================================================================
Description:
change channel moving time for DFS testing.
Arguments:
pAdapter Pointer to our adapter
wrq Pointer to the ioctl argument
Return Value:
None
Note:
Usage:
1.) iwpriv ra0 set ChMovTime=[value]
==========================================================================
*/
INT Set_ChMovingTime_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg)
{
UINT8 Value;
Value = (UINT8) simple_strtol(arg, 0, 10);
pAd->CommonCfg.RadarDetect.ChMovingTime = Value;
DBGPRINT(RT_DEBUG_TRACE, ("%s:: %d\n", __FUNCTION__,
pAd->CommonCfg.RadarDetect.ChMovingTime));
return TRUE;
}
INT Set_LongPulseRadarTh_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg)
{
UINT8 Value;
Value = (UINT8) simple_strtol(arg, 0, 10) > 10 ? 10 : simple_strtol(arg, 0, 10);
pAd->CommonCfg.RadarDetect.LongPulseRadarTh = Value;
DBGPRINT(RT_DEBUG_TRACE, ("%s:: %d\n", __FUNCTION__,
pAd->CommonCfg.RadarDetect.LongPulseRadarTh));
return TRUE;
}
#endif // DFS_SUPPORT //

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,308 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
ee_prom.c
Abstract:
Miniport generic portion header file
Revision History:
Who When What
-------- ---------- ----------------------------------------------
*/
#include "../rt_config.h"
// IRQL = PASSIVE_LEVEL
static inline VOID RaiseClock(
IN PRTMP_ADAPTER pAd,
IN UINT32 *x)
{
*x = *x | EESK;
RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
RTMPusecDelay(1); // Max frequency = 1MHz in Spec. definition
}
// IRQL = PASSIVE_LEVEL
static inline VOID LowerClock(
IN PRTMP_ADAPTER pAd,
IN UINT32 *x)
{
*x = *x & ~EESK;
RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
RTMPusecDelay(1);
}
// IRQL = PASSIVE_LEVEL
static inline USHORT ShiftInBits(
IN PRTMP_ADAPTER pAd)
{
UINT32 x,i;
USHORT data=0;
RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
x &= ~( EEDO | EEDI);
for(i=0; i<16; i++)
{
data = data << 1;
RaiseClock(pAd, &x);
RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
LowerClock(pAd, &x); //prevent read failed
x &= ~(EEDI);
if(x & EEDO)
data |= 1;
}
return data;
}
// IRQL = PASSIVE_LEVEL
static inline VOID ShiftOutBits(
IN PRTMP_ADAPTER pAd,
IN USHORT data,
IN USHORT count)
{
UINT32 x,mask;
mask = 0x01 << (count - 1);
RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
x &= ~(EEDO | EEDI);
do
{
x &= ~EEDI;
if(data & mask) x |= EEDI;
RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
RaiseClock(pAd, &x);
LowerClock(pAd, &x);
mask = mask >> 1;
} while(mask);
x &= ~EEDI;
RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
}
// IRQL = PASSIVE_LEVEL
static inline VOID EEpromCleanup(
IN PRTMP_ADAPTER pAd)
{
UINT32 x;
RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
x &= ~(EECS | EEDI);
RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
RaiseClock(pAd, &x);
LowerClock(pAd, &x);
}
static inline VOID EWEN(
IN PRTMP_ADAPTER pAd)
{
UINT32 x;
// reset bits and set EECS
RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
x &= ~(EEDI | EEDO | EESK);
x |= EECS;
RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
// kick a pulse
RaiseClock(pAd, &x);
LowerClock(pAd, &x);
// output the read_opcode and six pulse in that order
ShiftOutBits(pAd, EEPROM_EWEN_OPCODE, 5);
ShiftOutBits(pAd, 0, 6);
EEpromCleanup(pAd);
}
static inline VOID EWDS(
IN PRTMP_ADAPTER pAd)
{
UINT32 x;
// reset bits and set EECS
RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
x &= ~(EEDI | EEDO | EESK);
x |= EECS;
RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
// kick a pulse
RaiseClock(pAd, &x);
LowerClock(pAd, &x);
// output the read_opcode and six pulse in that order
ShiftOutBits(pAd, EEPROM_EWDS_OPCODE, 5);
ShiftOutBits(pAd, 0, 6);
EEpromCleanup(pAd);
}
// IRQL = PASSIVE_LEVEL
int rtmp_ee_prom_read16(
IN PRTMP_ADAPTER pAd,
IN USHORT Offset,
OUT USHORT *pValue)
{
UINT32 x;
USHORT data;
#ifdef RT30xx
#ifdef ANT_DIVERSITY_SUPPORT
if (pAd->NicConfig2.field.AntDiversity)
{
pAd->EepromAccess = TRUE;
}
#endif // ANT_DIVERSITY_SUPPORT //
#endif // RT30xx //
Offset /= 2;
// reset bits and set EECS
RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
x &= ~(EEDI | EEDO | EESK);
x |= EECS;
RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
// patch can not access e-Fuse issue
if (!(IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)))
{
// kick a pulse
RaiseClock(pAd, &x);
LowerClock(pAd, &x);
}
// output the read_opcode and register number in that order
ShiftOutBits(pAd, EEPROM_READ_OPCODE, 3);
ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum);
// Now read the data (16 bits) in from the selected EEPROM word
data = ShiftInBits(pAd);
EEpromCleanup(pAd);
#ifdef RT30xx
#ifdef ANT_DIVERSITY_SUPPORT
// Antenna and EEPROM access are both using EESK pin,
// Therefor we should avoid accessing EESK at the same time
// Then restore antenna after EEPROM access
if ((pAd->NicConfig2.field.AntDiversity)/* || (pAd->RfIcType == RFIC_3020)*/)
{
pAd->EepromAccess = FALSE;
AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
}
#endif // ANT_DIVERSITY_SUPPORT //
#endif // RT30xx //
*pValue = data;
return NDIS_STATUS_SUCCESS;
}
int rtmp_ee_prom_write16(
IN PRTMP_ADAPTER pAd,
IN USHORT Offset,
IN USHORT Data)
{
UINT32 x;
#ifdef RT30xx
#ifdef ANT_DIVERSITY_SUPPORT
if (pAd->NicConfig2.field.AntDiversity)
{
pAd->EepromAccess = TRUE;
}
#endif // ANT_DIVERSITY_SUPPORT //
#endif // RT30xx //
Offset /= 2;
EWEN(pAd);
// reset bits and set EECS
RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
x &= ~(EEDI | EEDO | EESK);
x |= EECS;
RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
// patch can not access e-Fuse issue
if (!(IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)))
{
// kick a pulse
RaiseClock(pAd, &x);
LowerClock(pAd, &x);
}
// output the read_opcode ,register number and data in that order
ShiftOutBits(pAd, EEPROM_WRITE_OPCODE, 3);
ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum);
ShiftOutBits(pAd, Data, 16); // 16-bit access
// read DO status
RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
EEpromCleanup(pAd);
RTMPusecDelay(10000); //delay for twp(MAX)=10ms
EWDS(pAd);
EEpromCleanup(pAd);
#ifdef RT30xx
#ifdef ANT_DIVERSITY_SUPPORT
// Antenna and EEPROM access are both using EESK pin,
// Therefor we should avoid accessing EESK at the same time
// Then restore antenna after EEPROM access
if ((pAd->NicConfig2.field.AntDiversity) /*|| (pAd->RfIcType == RFIC_3020)*/)
{
pAd->EepromAccess = FALSE;
AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
}
#endif // ANT_DIVERSITY_SUPPORT //
#endif // RT30xx //
return NDIS_STATUS_SUCCESS;
}

View file

@ -0,0 +1,98 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
eeprom.c
Abstract:
Revision History:
Who When What
-------- ---------- ----------------------------------------------
Name Date Modification logs
*/
#include "../rt_config.h"
INT RtmpChipOpsEepromHook(
IN RTMP_ADAPTER *pAd,
IN INT infType)
{
RTMP_CHIP_OP *pChipOps = &pAd->chipOps;
#ifdef RT30xx
#ifdef RTMP_EFUSE_SUPPORT
UINT32 eFuseCtrl, MacCsr0;
int index;
index = 0;
do
{
RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0);
pAd->MACVersion = MacCsr0;
if ((pAd->MACVersion != 0x00) && (pAd->MACVersion != 0xFFFFFFFF))
break;
RTMPusecDelay(10);
} while (index++ < 100);
pAd->bUseEfuse=FALSE;
RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrl);
pAd->bUseEfuse = ( (eFuseCtrl & 0x80000000) == 0x80000000) ? 1 : 0;
if(pAd->bUseEfuse)
{
pChipOps->eeinit = eFuse_init;
pChipOps->eeread = rtmp_ee_efuse_read16;
pChipOps->eewrite = rtmp_ee_efuse_write16;
return 0 ;
}
else
{
pAd->bFroceEEPROMBuffer = FALSE;
DBGPRINT(RT_DEBUG_TRACE, ("NVM is EEPROM\n"));
}
#endif // RTMP_EFUSE_SUPPORT //
#endif // RT30xx //
switch(infType)
{
#ifdef RTMP_PCI_SUPPORT
case RTMP_DEV_INF_PCI:
pChipOps->eeinit = NULL;
pChipOps->eeread = rtmp_ee_prom_read16;
pChipOps->eewrite = rtmp_ee_prom_write16;
break;
#endif // RTMP_PCI_SUPPORT //
default:
DBGPRINT(RT_DEBUG_ERROR, ("RtmpChipOpsEepromHook() failed!\n"));
break;
}
return 0;
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,215 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
mlme_ex.c
Abstract:
Miniport generic portion header file
Revision History:
Who When What
-------- ---------- ----------------------------------------------
Fonchi 2007-06-25 Extend original mlme APIs to support multi-entries
*/
#include "../rt_config.h"
#include "../mlme_ex_def.h"
//#include <stdarg.h>
// ===========================================================================================
// state_machine
// ===========================================================================================
/*! \brief Initialize the state machine.
* \param *S pointer to the state machine
* \param Trans State machine transition function
* \param StNr number of states
* \param MsgNr number of messages
* \param DefFunc default function, when there is invalid state/message combination
* \param InitState initial state of the state machine
* \param Base StateMachine base, internal use only
* \pre p_sm should be a legal pointer
* \post
*/
VOID StateMachineInitEx(
IN STATE_MACHINE_EX *S,
IN STATE_MACHINE_FUNC_EX Trans[],
IN ULONG StNr,
IN ULONG MsgNr,
IN STATE_MACHINE_FUNC_EX DefFunc,
IN ULONG InitState,
IN ULONG Base)
{
ULONG i, j;
// set number of states and messages
S->NrState = StNr;
S->NrMsg = MsgNr;
S->Base = Base;
S->TransFunc = Trans;
// init all state transition to default function
for (i = 0; i < StNr; i++)
{
for (j = 0; j < MsgNr; j++)
{
S->TransFunc[i * MsgNr + j] = DefFunc;
}
}
// set the starting state
S->CurrState = InitState;
return;
}
/*! \brief This function fills in the function pointer into the cell in the state machine
* \param *S pointer to the state machine
* \param St state
* \param Msg incoming message
* \param f the function to be executed when (state, message) combination occurs at the state machine
* \pre *S should be a legal pointer to the state machine, st, msg, should be all within the range, Base should be set in the initial state
* \post
*/
VOID StateMachineSetActionEx(
IN STATE_MACHINE_EX *S,
IN ULONG St,
IN ULONG Msg,
IN STATE_MACHINE_FUNC_EX Func)
{
ULONG MsgIdx;
MsgIdx = Msg - S->Base;
if (St < S->NrState && MsgIdx < S->NrMsg)
{
// boundary checking before setting the action
S->TransFunc[St * S->NrMsg + MsgIdx] = Func;
}
return;
}
/*! \brief This function does the state transition
* \param *Adapter the NIC adapter pointer
* \param *S the state machine
* \param *Elem the message to be executed
* \return None
*/
VOID StateMachinePerformActionEx(
IN PRTMP_ADAPTER pAd,
IN STATE_MACHINE_EX *S,
IN MLME_QUEUE_ELEM *Elem,
USHORT Idx,
PULONG pCurrState)
{
if (S->TransFunc[(*pCurrState) * S->NrMsg + Elem->MsgType - S->Base])
(*(S->TransFunc[(*pCurrState) * S->NrMsg + Elem->MsgType - S->Base]))(pAd, Elem, pCurrState, Idx);
return;
}
/*! \brief Enqueue a message for other threads, if they want to send messages to MLME thread
* \param *Queue The MLME Queue
* \param Machine The State Machine Id
* \param MsgType The Message Type
* \param MsgLen The Message length
* \param *Msg The message pointer
* \return TRUE if enqueue is successful, FALSE if the queue is full
* \pre
* \post
* \note The message has to be initialized
*/
BOOLEAN MlmeEnqueueEx(
IN PRTMP_ADAPTER pAd,
IN ULONG Machine,
IN ULONG MsgType,
IN ULONG MsgLen,
IN VOID *Msg,
IN USHORT Idx)
{
INT Tail;
MLME_QUEUE *Queue = (MLME_QUEUE *)&pAd->Mlme.Queue;
// Do nothing if the driver is starting halt state.
// This might happen when timer already been fired before cancel timer with mlmehalt
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
return FALSE;
// First check the size, it MUST not exceed the mlme queue size
if (MsgLen > MAX_LEN_OF_MLME_BUFFER)
{
DBGPRINT_ERR(("MlmeEnqueueEx: msg too large, size = %ld \n", MsgLen));
return FALSE;
}
if (MlmeQueueFull(Queue))
{
return FALSE;
}
RTMP_SEM_LOCK(&Queue->Lock);
Tail = Queue->Tail;
Queue->Tail++;
Queue->Num++;
if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE)
{
Queue->Tail = 0;
}
Queue->Entry[Tail].Occupied = TRUE;
Queue->Entry[Tail].Machine = Machine;
Queue->Entry[Tail].MsgType = MsgType;
Queue->Entry[Tail].MsgLen = MsgLen;
Queue->Entry[Tail].Idx = Idx;
if (Msg != NULL)
NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen);
RTMP_SEM_UNLOCK(&Queue->Lock);
return TRUE;
}
/*
==========================================================================
Description:
The drop function, when machine executes this, the message is simply
ignored. This function does nothing, the message is freed in
StateMachinePerformAction()
==========================================================================
*/
VOID DropEx(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem,
PULONG pCurrState,
USHORT Idx)
{
return;
}

View file

@ -0,0 +1,147 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
*/
#ifdef BLOCK_NET_IF
#include "../rt_config.h"
#include "../netif_block.h"
static NETIF_ENTRY freeNetIfEntryPool[FREE_NETIF_POOL_SIZE];
static LIST_HEADER freeNetIfEntryList;
void initblockQueueTab(
IN PRTMP_ADAPTER pAd)
{
int i;
initList(&freeNetIfEntryList);
for (i = 0; i < FREE_NETIF_POOL_SIZE; i++)
insertTailList(&freeNetIfEntryList, (PLIST_ENTRY)&freeNetIfEntryPool[i]);
for (i=0; i < NUM_OF_TX_RING; i++)
initList(&pAd->blockQueueTab[i].NetIfList);
return;
}
BOOLEAN blockNetIf(
IN PBLOCK_QUEUE_ENTRY pBlockQueueEntry,
IN PNET_DEV pNetDev)
{
PNETIF_ENTRY pNetIfEntry = NULL;
if ((pNetIfEntry = (PNETIF_ENTRY)removeHeadList(&freeNetIfEntryList)) != NULL)
{
RTMP_OS_NETDEV_STOP_QUEUE(pNetDev);
pNetIfEntry->pNetDev = pNetDev;
insertTailList(&pBlockQueueEntry->NetIfList, (PLIST_ENTRY)pNetIfEntry);
pBlockQueueEntry->SwTxQueueBlockFlag = TRUE;
DBGPRINT(RT_DEBUG_TRACE, ("RTMP_OS_NETDEV_STOP_QUEUE(%s)\n", RTMP_OS_NETDEV_GET_DEVNAME(pNetDev)));
}
else
return FALSE;
return TRUE;
}
VOID releaseNetIf(
IN PBLOCK_QUEUE_ENTRY pBlockQueueEntry)
{
PNETIF_ENTRY pNetIfEntry = NULL;
PLIST_HEADER pNetIfList = &pBlockQueueEntry->NetIfList;
while((pNetIfEntry = (PNETIF_ENTRY)removeHeadList(pNetIfList)) != NULL)
{
PNET_DEV pNetDev = pNetIfEntry->pNetDev;
RTMP_OS_NETDEV_WAKE_QUEUE(pNetDev);
insertTailList(&freeNetIfEntryList, (PLIST_ENTRY)pNetIfEntry);
DBGPRINT(RT_DEBUG_TRACE, ("RTMP_OS_NETDEV_WAKE_QUEUE(%s)\n", RTMP_OS_NETDEV_GET_DEVNAME(pNetDev)));
}
pBlockQueueEntry->SwTxQueueBlockFlag = FALSE;
return;
}
VOID StopNetIfQueue(
IN PRTMP_ADAPTER pAd,
IN UCHAR QueIdx,
IN PNDIS_PACKET pPacket)
{
PNET_DEV NetDev = NULL;
UCHAR IfIdx = 0;
BOOLEAN valid = FALSE;
#ifdef APCLI_SUPPORT
if (RTMP_GET_PACKET_NET_DEVICE(pPacket) >= MIN_NET_DEVICE_FOR_APCLI)
{
IfIdx = (RTMP_GET_PACKET_NET_DEVICE(pPacket) - MIN_NET_DEVICE_FOR_APCLI) % MAX_APCLI_NUM;
NetDev = pAd->ApCfg.ApCliTab[IfIdx].dev;
}
else
#endif // APCLI_SUPPORT //
#ifdef WDS_SUPPORT
if (RTMP_GET_PACKET_NET_DEVICE(pPacket) >= MIN_NET_DEVICE_FOR_WDS)
{
IfIdx = (RTMP_GET_PACKET_NET_DEVICE(pPacket) - MIN_NET_DEVICE_FOR_WDS) % MAX_WDS_ENTRY;
NetDev = pAd->WdsTab.WdsEntry[IfIdx].dev;
}
else
#endif // WDS_SUPPORT //
{
#ifdef MBSS_SUPPORT
if (pAd->OpMode == OPMODE_AP)
{
IfIdx = (RTMP_GET_PACKET_NET_DEVICE(pPacket) - MIN_NET_DEVICE_FOR_MBSSID) % MAX_MBSSID_NUM;
NetDev = pAd->ApCfg.MBSSID[IfIdx].MSSIDDev;
}
else
{
IfIdx = MAIN_MBSSID;
NetDev = pAd->net_dev;
}
#else
IfIdx = MAIN_MBSSID;
NetDev = pAd->net_dev;
#endif
}
// WMM support 4 software queues.
// One software queue full doesn't mean device have no capbility to transmit packet.
// So disable block Net-If queue function while WMM enable.
#ifdef CONFIG_STA_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
valid = (pAd->CommonCfg.bWmmCapable == TRUE) ? FALSE : TRUE;
#endif // CONFIG_STA_SUPPORT //
if (valid)
blockNetIf(&pAd->blockQueueTab[QueIdx], NetDev);
return;
}
#endif // BLOCK_NET_IF //

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,201 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
rt_rf.c
Abstract:
Ralink Wireless driver RF related functions
Revision History:
Who When What
-------- ---------- ----------------------------------------------
*/
#include "../rt_config.h"
#ifdef RTMP_RF_RW_SUPPORT
/*
========================================================================
Routine Description: Write RT30xx RF register through MAC
Arguments:
Return Value:
IRQL =
Note:
========================================================================
*/
NDIS_STATUS RT30xxWriteRFRegister(
IN PRTMP_ADAPTER pAd,
IN UCHAR regID,
IN UCHAR value)
{
RF_CSR_CFG_STRUC rfcsr;
UINT i = 0;
do
{
RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
if (!rfcsr.field.RF_CSR_KICK)
break;
i++;
}
while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
{
DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
return STATUS_UNSUCCESSFUL;
}
rfcsr.field.RF_CSR_WR = 1;
rfcsr.field.RF_CSR_KICK = 1;
rfcsr.field.TESTCSR_RFACC_REGNUM = regID;
rfcsr.field.RF_CSR_DATA = value;
RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word);
return NDIS_STATUS_SUCCESS;
}
/*
========================================================================
Routine Description: Read RT30xx RF register through MAC
Arguments:
Return Value:
IRQL =
Note:
========================================================================
*/
NDIS_STATUS RT30xxReadRFRegister(
IN PRTMP_ADAPTER pAd,
IN UCHAR regID,
IN PUCHAR pValue)
{
RF_CSR_CFG_STRUC rfcsr;
UINT i=0, k=0;
for (i=0; i<MAX_BUSY_COUNT; i++)
{
RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
if (rfcsr.field.RF_CSR_KICK == BUSY)
{
continue;
}
rfcsr.word = 0;
rfcsr.field.RF_CSR_WR = 0;
rfcsr.field.RF_CSR_KICK = 1;
rfcsr.field.TESTCSR_RFACC_REGNUM = regID;
RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word);
for (k=0; k<MAX_BUSY_COUNT; k++)
{
RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
if (rfcsr.field.RF_CSR_KICK == IDLE)
break;
}
if ((rfcsr.field.RF_CSR_KICK == IDLE) &&
(rfcsr.field.TESTCSR_RFACC_REGNUM == regID))
{
*pValue = (UCHAR)rfcsr.field.RF_CSR_DATA;
break;
}
}
if (rfcsr.field.RF_CSR_KICK == BUSY)
{
DBGPRINT_ERR(("RF read R%d=0x%x fail, i[%d], k[%d]\n", regID, rfcsr.word,i,k));
return STATUS_UNSUCCESSFUL;
}
return STATUS_SUCCESS;
}
VOID NICInitRFRegisters(
IN RTMP_ADAPTER *pAd)
{
if (pAd->chipOps.AsicRfInit)
pAd->chipOps.AsicRfInit(pAd);
}
VOID RtmpChipOpsRFHook(
IN RTMP_ADAPTER *pAd)
{
RTMP_CHIP_OP *pChipOps = &pAd->chipOps;
pChipOps->pRFRegTable = NULL;
pChipOps->AsicRfInit = NULL;
pChipOps->AsicRfTurnOn = NULL;
pChipOps->AsicRfTurnOff = NULL;
pChipOps->AsicReverseRfFromSleepMode = NULL;
pChipOps->AsicHaltAction = NULL;
#ifdef RT33xx
if (IS_RT3390(pAd) && (pAd->infType == RTMP_DEV_INF_PCI))
{
pChipOps->pRFRegTable = RFRegTableOverRT3390;
pChipOps->AsicHaltAction = RT33xxHaltAction;
pChipOps->AsicRfTurnOff = RT33xxLoadRFSleepModeSetup;
pChipOps->AsicRfInit = NICInitRT3390RFRegisters;
pChipOps->AsicReverseRfFromSleepMode = RT33xxReverseRFSleepModeSetup;
}
#else // RT33xx //
/* We depends on RfICType and MACVersion to assign the corresponding operation callbacks. */
#ifdef RT30xx
if (IS_RT30xx(pAd))
{
pChipOps->pRFRegTable = RT30xx_RFRegTable;
pChipOps->AsicHaltAction = RT30xxHaltAction;
#ifdef RT3090
if (IS_RT3090(pAd) && (pAd->infType == RTMP_DEV_INF_PCI))
{
pChipOps->AsicRfTurnOff = RT30xxLoadRFSleepModeSetup;
pChipOps->AsicRfInit = NICInitRT3090RFRegisters;
pChipOps->AsicReverseRfFromSleepMode = RT30xxReverseRFSleepModeSetup;
}
#endif // RT3090 //
}
#endif // RT30xx //
#endif // RT33xx //
}
#endif // RTMP_RF_RW_SUPPORT //

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,560 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
rtmp_mcu.c
Abstract:
Miniport generic portion header file
Revision History:
Who When What
-------- ---------- ----------------------------------------------
*/
#include "../rt_config.h"
#include "../firmware.h"
//#define BIN_IN_FILE /* use *.bin firmware */
// New 8k byte firmware size for RT3071/RT3072
#define FIRMWAREIMAGE_MAX_LENGTH 0x2000
#define FIRMWAREIMAGE_LENGTH (sizeof (FirmwareImage) / sizeof(UCHAR))
#define FIRMWARE_MAJOR_VERSION 0
#define FIRMWAREIMAGEV1_LENGTH 0x1000
#define FIRMWAREIMAGEV2_LENGTH 0x1000
#ifdef RTMP_MAC_PCI
#define FIRMWARE_MINOR_VERSION 2
#endif // RTMP_MAC_PCI //
const unsigned short ccitt_16Table[] = {
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
};
#define ByteCRC16(v, crc) \
(unsigned short)((crc << 8) ^ ccitt_16Table[((crc >> 8) ^ (v)) & 255])
unsigned char BitReverse(unsigned char x)
{
int i;
unsigned char Temp=0;
for(i=0; ; i++)
{
if(x & 0x80) Temp |= 0x80;
if(i==7) break;
x <<= 1;
Temp >>= 1;
}
return Temp;
}
/*
========================================================================
Routine Description:
erase 8051 firmware image in MAC ASIC
Arguments:
Adapter Pointer to our adapter
IRQL = PASSIVE_LEVEL
========================================================================
*/
INT RtmpAsicEraseFirmware(
IN PRTMP_ADAPTER pAd)
{
ULONG i;
for(i=0; i<MAX_FIRMWARE_IMAGE_SIZE; i+=4)
RTMP_IO_WRITE32(pAd, FIRMWARE_IMAGE_BASE + i, 0);
return 0;
}
/*
========================================================================
Routine Description:
Load 8051 firmware file into MAC ASIC
Arguments:
Adapter Pointer to our adapter
Return Value:
NDIS_STATUS_SUCCESS firmware image load ok
NDIS_STATUS_FAILURE image not found
IRQL = PASSIVE_LEVEL
========================================================================
*/
NDIS_STATUS RtmpAsicLoadFirmware(
IN PRTMP_ADAPTER pAd)
{
#ifdef BIN_IN_FILE
#define NICLF_DEFAULT_USE() \
flg_default_firm_use = TRUE; \
DBGPRINT(RT_DEBUG_OFF, ("%s - Use default firmware!\n", __FUNCTION__));
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
PUCHAR src;
RTMP_OS_FD srcf;
INT retval, i;
PUCHAR pFirmwareImage;
INT FileLength = 0;
UINT32 MacReg;
ULONG Index;
ULONG firm;
BOOLEAN flg_default_firm_use = FALSE;
RTMP_OS_FS_INFO osFSInfo;
DBGPRINT(RT_DEBUG_TRACE, ("===> %s\n", __FUNCTION__));
/* init */
pFirmwareImage = NULL;
src = RTMP_FIRMWARE_FILE_NAME;
RtmpOSFSInfoChange(&osFSInfo, TRUE);
pAd->FirmwareVersion = (FIRMWARE_MAJOR_VERSION << 8) + \
FIRMWARE_MINOR_VERSION;
/* allocate firmware buffer */
pFirmwareImage = kmalloc(MAX_FIRMWARE_IMAGE_SIZE, MEM_ALLOC_FLAG);
if (pFirmwareImage == NULL)
{
/* allocate fail, use default firmware array in firmware.h */
DBGPRINT(RT_DEBUG_ERROR, ("%s - Allocate memory fail!\n", __FUNCTION__));
NICLF_DEFAULT_USE();
}
else
{
/* allocate ok! zero the firmware buffer */
memset(pFirmwareImage, 0x00, MAX_FIRMWARE_IMAGE_SIZE);
} /* End of if */
/* if ok, read firmware file from *.bin file */
if (flg_default_firm_use == FALSE)
{
do
{
/* open the bin file */
srcf = RtmpOSFileOpen(src, O_RDONLY, 0);
if (IS_FILE_OPEN_ERR(srcf))
{
DBGPRINT(RT_DEBUG_ERROR, ("%s - Error opening file %s\n", __FUNCTION__, src));
NICLF_DEFAULT_USE();
break;
}
/* read the firmware from the file *.bin */
FileLength = RtmpOSFileRead(srcf, pFirmwareImage, MAX_FIRMWARE_IMAGE_SIZE);
if (FileLength != MAX_FIRMWARE_IMAGE_SIZE)
{
DBGPRINT(RT_DEBUG_ERROR, ("%s: error file length (=%d) in RT2860AP.BIN\n",
__FUNCTION__, FileLength));
NICLF_DEFAULT_USE();
break;
}
else
{
PUCHAR ptr = pFirmwareImage;
USHORT crc = 0xffff;
/* calculate firmware CRC */
for(i=0; i<(MAX_FIRMWARE_IMAGE_SIZE-2); i++, ptr++)
crc = ByteCRC16(BitReverse(*ptr), crc);
/* End of for */
if ((pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-2] != \
(UCHAR)BitReverse((UCHAR)(crc>>8))) ||
(pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-1] != \
(UCHAR)BitReverse((UCHAR)crc)))
{
/* CRC fail */
DBGPRINT(RT_DEBUG_ERROR, ("%s: CRC = 0x%02x 0x%02x "
"error, should be 0x%02x 0x%02x\n",
__FUNCTION__,
pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-2],
pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-1],
(UCHAR)(crc>>8), (UCHAR)(crc)));
NICLF_DEFAULT_USE();
break;
}
else
{
/* firmware is ok */
pAd->FirmwareVersion = \
(pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-4] << 8) +
pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-3];
/* check if firmware version of the file is too old */
if ((pAd->FirmwareVersion) < \
((FIRMWARE_MAJOR_VERSION << 8) +
FIRMWARE_MINOR_VERSION))
{
DBGPRINT(RT_DEBUG_ERROR, ("%s: firmware version too old!\n", __FUNCTION__));
NICLF_DEFAULT_USE();
break;
} /* End of if */
} /* End of if */
DBGPRINT(RT_DEBUG_TRACE,
("NICLoadFirmware: CRC ok, ver=%d.%d\n",
pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-4],
pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-3]));
} /* End of if (FileLength == MAX_FIRMWARE_IMAGE_SIZE) */
break;
} while(TRUE);
/* close firmware file */
if (IS_FILE_OPEN_ERR(srcf))
;
else
{
retval = RtmpOSFileClose(srcf);
if (retval)
{
DBGPRINT(RT_DEBUG_ERROR, ("--> Error %d closing %s\n", -retval, src));
}
}
}
/* write firmware to ASIC */
if (flg_default_firm_use == TRUE)
{
/* use default fimeware, free allocated buffer */
if (pFirmwareImage != NULL)
kfree(pFirmwareImage);
/* End of if */
/* use default *.bin array */
pFirmwareImage = FirmwareImage;
FileLength = sizeof(FirmwareImage);
} /* End of if */
/* enable Host program ram write selection */
RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x10000);
for(i=0; i<FileLength; i+=4)
{
firm = pFirmwareImage[i] +
(pFirmwareImage[i+3] << 24) +
(pFirmwareImage[i+2] << 16) +
(pFirmwareImage[i+1] << 8);
RTMP_IO_WRITE32(pAd, FIRMWARE_IMAGE_BASE + i, firm);
} /* End of for */
RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x00000);
RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x00001);
/* initialize BBP R/W access agent */
RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, 0);
RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, 0);
if (flg_default_firm_use == FALSE)
{
/* use file firmware, free allocated buffer */
if (pFirmwareImage != NULL)
kfree(pFirmwareImage);
/* End of if */
} /* End of if */
RtmpOSFSInfoChange(&osFSInfo, FALSE);
#else
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
PUCHAR pFirmwareImage;
ULONG FileLength, Index;
//ULONG firm;
UINT32 MacReg = 0;
UINT32 Version = (pAd->MACVersion >> 16);
pFirmwareImage = FirmwareImage;
FileLength = sizeof(FirmwareImage);
// New 8k byte firmware size for RT3071/RT3072
//DBGPRINT(RT_DEBUG_TRACE, ("Usb Chip\n"));
if (FIRMWAREIMAGE_LENGTH == FIRMWAREIMAGE_MAX_LENGTH)
//The firmware image consists of two parts. One is the origianl and the other is the new.
//Use Second Part
{
#ifdef RTMP_MAC_PCI
if ((Version == 0x2860) || IS_RT3090(pAd)||IS_RT3390(pAd))
{
pFirmwareImage = FirmwareImage;
FileLength = FIRMWAREIMAGE_LENGTH;
}
#endif // RTMP_MAC_PCI //
}
else
{
DBGPRINT(RT_DEBUG_ERROR, ("KH: bin file should be 8KB.\n"));
Status = NDIS_STATUS_FAILURE;
}
RTMP_WRITE_FIRMWARE(pAd, pFirmwareImage, FileLength);
#endif
/* check if MCU is ready */
Index = 0;
do
{
RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &MacReg);
if (MacReg & 0x80)
break;
RTMPusecDelay(1000);
} while (Index++ < 1000);
if (Index >= 1000)
{
DBGPRINT(RT_DEBUG_ERROR, ("NICLoadFirmware: MCU is not ready\n\n\n"));
Status = NDIS_STATUS_FAILURE;
}
DBGPRINT(RT_DEBUG_TRACE, ("<=== %s (status=%d)\n", __FUNCTION__, Status));
return Status;
}
INT RtmpAsicSendCommandToMcu(
IN PRTMP_ADAPTER pAd,
IN UCHAR Command,
IN UCHAR Token,
IN UCHAR Arg0,
IN UCHAR Arg1)
{
HOST_CMD_CSR_STRUC H2MCmd;
H2M_MAILBOX_STRUC H2MMailbox;
ULONG i = 0;
#ifdef RTMP_MAC_PCI
#ifdef RALINK_ATE
static UINT32 j = 0;
#endif // RALINK_ATE //
#endif // RTMP_MAC_PCI //
#ifdef PCIE_PS_SUPPORT
#ifdef CONFIG_STA_SUPPORT
// 3090F power solution 3 has hw limitation that needs to ban all mcu command
// when firmware is in radio state. For other chip doesn't have this limitation.
if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) && IS_VERSION_AFTER_F(pAd)) && IS_VERSION_AFTER_F(pAd)
&& (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
&& (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE))
{
RTMP_SEM_LOCK(&pAd->McuCmdLock);
if ((pAd->brt30xxBanMcuCmd == TRUE)
&& (Command != WAKE_MCU_CMD) && (Command != RFOFF_MCU_CMD))
{
RTMP_SEM_UNLOCK(&pAd->McuCmdLock);
DBGPRINT(RT_DEBUG_TRACE, (" Ban Mcu Cmd %x in sleep mode\n", Command));
return FALSE;
}
else if ((Command == SLEEP_MCU_CMD)
||(Command == RFOFF_MCU_CMD))
{
pAd->brt30xxBanMcuCmd = TRUE;
}
else if (Command != WAKE_MCU_CMD)
{
pAd->brt30xxBanMcuCmd = FALSE;
}
RTMP_SEM_UNLOCK(&pAd->McuCmdLock);
}
if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) && IS_VERSION_AFTER_F(pAd)) && IS_VERSION_AFTER_F(pAd)
&& (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
&& (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
&& (Command == WAKE_MCU_CMD))
{
do
{
RTMP_IO_FORCE_READ32(pAd, H2M_MAILBOX_CSR, &H2MMailbox.word);
if (H2MMailbox.field.Owner == 0)
break;
RTMPusecDelay(2);
DBGPRINT(RT_DEBUG_INFO, ("AsicSendCommanToMcu::Mail box is busy\n"));
} while(i++ < 100);
if (i >= 100)
{
DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n"));
return FALSE;
}
H2MMailbox.field.Owner = 1; // pass ownership to MCU
H2MMailbox.field.CmdToken = Token;
H2MMailbox.field.HighByte = Arg1;
H2MMailbox.field.LowByte = Arg0;
RTMP_IO_FORCE_WRITE32(pAd, H2M_MAILBOX_CSR, H2MMailbox.word);
H2MCmd.word = 0;
H2MCmd.field.HostCommand = Command;
RTMP_IO_FORCE_WRITE32(pAd, HOST_CMD_CSR, H2MCmd.word);
}
else
#endif // CONFIG_STA_SUPPORT //
#endif // PCIE_PS_SUPPORT //
{
do
{
RTMP_IO_READ32(pAd, H2M_MAILBOX_CSR, &H2MMailbox.word);
if (H2MMailbox.field.Owner == 0)
break;
RTMPusecDelay(2);
} while(i++ < 100);
if (i >= 100)
{
#ifdef RTMP_MAC_PCI
#ifdef RALINK_ATE
if (pAd->ate.bFWLoading == TRUE)
{
/* reloading firmware when received iwpriv cmd "ATE=ATESTOP" */
if (j > 0)
{
if (j % 64 != 0)
{
ATEDBGPRINT(RT_DEBUG_ERROR, ("#"));
}
else
{
ATEDBGPRINT(RT_DEBUG_ERROR, ("\n"));
}
++j;
}
else if (j == 0)
{
ATEDBGPRINT(RT_DEBUG_ERROR, ("Loading firmware. Please wait for a moment...\n"));
++j;
}
}
else
#endif // RALINK_ATE //
#endif // RTMP_MAC_PCI //
{
DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n"));
}
return FALSE;
}
#ifdef RTMP_MAC_PCI
#ifdef RALINK_ATE
else if (pAd->ate.bFWLoading == TRUE)
{
/* reloading of firmware is completed */
pAd->ate.bFWLoading = FALSE;
ATEDBGPRINT(RT_DEBUG_ERROR, ("\n"));
j = 0;
}
#endif // RALINK_ATE //
#endif // RTMP_MAC_PCI //
H2MMailbox.field.Owner = 1; // pass ownership to MCU
H2MMailbox.field.CmdToken = Token;
H2MMailbox.field.HighByte = Arg1;
H2MMailbox.field.LowByte = Arg0;
RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, H2MMailbox.word);
H2MCmd.word = 0;
H2MCmd.field.HostCommand = Command;
RTMP_IO_WRITE32(pAd, HOST_CMD_CSR, H2MCmd.word);
if (Command != 0x80)
{
}
}
#ifdef PCIE_PS_SUPPORT
#ifdef CONFIG_STA_SUPPORT
// 3090 MCU Wakeup command needs more time to be stable.
// Before stable, don't issue other MCU command to prevent from firmware error.
if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) && IS_VERSION_AFTER_F(pAd)) && IS_VERSION_AFTER_F(pAd)
&& (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
&& (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
&& (Command == WAKE_MCU_CMD))
{
RTMPusecDelay(2000);
//Put this is after RF programming.
//NdisAcquireSpinLock(&pAd->McuCmdLock);
//pAd->brt30xxBanMcuCmd = FALSE;
//NdisReleaseSpinLock(&pAd->McuCmdLock);
}
#endif // CONFIG_STA_SUPPORT //
#endif // PCIE_PS_SUPPORT //
return TRUE;
}

View file

@ -0,0 +1,327 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
rtmp_timer.c
Abstract:
task for timer handling
Revision History:
Who When What
-------- ---------- ----------------------------------------------
Name Date Modification logs
Shiang Tu 08-28-2008 init version
*/
#include "../rt_config.h"
BUILD_TIMER_FUNCTION(MlmePeriodicExec);
//BUILD_TIMER_FUNCTION(MlmeRssiReportExec);
BUILD_TIMER_FUNCTION(AsicRxAntEvalTimeout);
BUILD_TIMER_FUNCTION(APSDPeriodicExec);
BUILD_TIMER_FUNCTION(AsicRfTuningExec);
#ifdef CONFIG_STA_SUPPORT
BUILD_TIMER_FUNCTION(BeaconTimeout);
BUILD_TIMER_FUNCTION(ScanTimeout);
BUILD_TIMER_FUNCTION(AuthTimeout);
BUILD_TIMER_FUNCTION(AssocTimeout);
BUILD_TIMER_FUNCTION(ReassocTimeout);
BUILD_TIMER_FUNCTION(DisassocTimeout);
BUILD_TIMER_FUNCTION(LinkDownExec);
BUILD_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
BUILD_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
#ifdef RTMP_MAC_PCI
BUILD_TIMER_FUNCTION(PsPollWakeExec);
BUILD_TIMER_FUNCTION(RadioOnExec);
#endif // RTMP_MAC_PCI //
#ifdef QOS_DLS_SUPPORT
BUILD_TIMER_FUNCTION(DlsTimeoutAction);
#endif // QOS_DLS_SUPPORT //
#endif // CONFIG_STA_SUPPORT //
#if defined(AP_LED) || defined(STA_LED)
extern void LedCtrlMain(
IN PVOID SystemSpecific1,
IN PVOID FunctionContext,
IN PVOID SystemSpecific2,
IN PVOID SystemSpecific3);
BUILD_TIMER_FUNCTION(LedCtrlMain);
#endif
#ifdef RTMP_TIMER_TASK_SUPPORT
static void RtmpTimerQHandle(RTMP_ADAPTER *pAd)
{
#ifndef KTHREAD_SUPPORT
int status;
#endif
RALINK_TIMER_STRUCT *pTimer;
RTMP_TIMER_TASK_ENTRY *pEntry;
unsigned long irqFlag;
RTMP_OS_TASK *pTask;
pTask = &pAd->timerTask;
while(!pTask->task_killed)
{
pTimer = NULL;
#ifdef KTHREAD_SUPPORT
RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask);
#else
RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status);
#endif
if (pAd->TimerQ.status == RTMP_TASK_STAT_STOPED)
break;
// event happened.
while(pAd->TimerQ.pQHead)
{
RTMP_INT_LOCK(&pAd->TimerQLock, irqFlag);
pEntry = pAd->TimerQ.pQHead;
if (pEntry)
{
pTimer = pEntry->pRaTimer;
// update pQHead
pAd->TimerQ.pQHead = pEntry->pNext;
if (pEntry == pAd->TimerQ.pQTail)
pAd->TimerQ.pQTail = NULL;
// return this queue entry to timerQFreeList.
pEntry->pNext = pAd->TimerQ.pQPollFreeList;
pAd->TimerQ.pQPollFreeList = pEntry;
}
RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlag);
if (pTimer)
{
if ((pTimer->handle != NULL) && (!pAd->PM_FlgSuspend))
pTimer->handle(NULL, (PVOID) pTimer->cookie, NULL, pTimer);
if ((pTimer->Repeat) && (pTimer->State == FALSE))
RTMP_OS_Add_Timer(&pTimer->TimerObj, pTimer->TimerValue);
}
}
#ifndef KTHREAD_SUPPORT
if (status != 0)
{
pAd->TimerQ.status = RTMP_TASK_STAT_STOPED;
RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
break;
}
#endif
}
}
INT RtmpTimerQThread(
IN OUT PVOID Context)
{
RTMP_OS_TASK *pTask;
PRTMP_ADAPTER pAd;
pTask = (RTMP_OS_TASK *)Context;
pAd = (PRTMP_ADAPTER)pTask->priv;
RtmpOSTaskCustomize(pTask);
RtmpTimerQHandle(pAd);
DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__FUNCTION__));
#ifndef KTHREAD_SUPPORT
pTask->taskPID = THREAD_PID_INIT_VALUE;
#endif
/* notify the exit routine that we're actually exiting now
*
* complete()/wait_for_completion() is similar to up()/down(),
* except that complete() is safe in the case where the structure
* is getting deleted in a parallel mode of execution (i.e. just
* after the down() -- that's necessary for the thread-shutdown
* case.
*
* complete_and_exit() goes even further than this -- it is safe in
* the case that the thread of the caller is going away (not just
* the structure) -- this is necessary for the module-remove case.
* This is important in preemption kernels, which transfer the flow
* of execution immediately upon a complete().
*/
RtmpOSTaskNotifyToExit(pTask);
return 0;
}
RTMP_TIMER_TASK_ENTRY *RtmpTimerQInsert(
IN RTMP_ADAPTER *pAd,
IN RALINK_TIMER_STRUCT *pTimer)
{
RTMP_TIMER_TASK_ENTRY *pQNode = NULL, *pQTail;
unsigned long irqFlags;
RTMP_OS_TASK *pTask = &pAd->timerTask;
RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags);
if (pAd->TimerQ.status & RTMP_TASK_CAN_DO_INSERT)
{
if(pAd->TimerQ.pQPollFreeList)
{
pQNode = pAd->TimerQ.pQPollFreeList;
pAd->TimerQ.pQPollFreeList = pQNode->pNext;
pQNode->pRaTimer = pTimer;
pQNode->pNext = NULL;
pQTail = pAd->TimerQ.pQTail;
if (pAd->TimerQ.pQTail != NULL)
pQTail->pNext = pQNode;
pAd->TimerQ.pQTail = pQNode;
if (pAd->TimerQ.pQHead == NULL)
pAd->TimerQ.pQHead = pQNode;
}
}
RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
if (pQNode)
{
#ifdef KTHREAD_SUPPORT
WAKE_UP(pTask);
#else
RTMP_SEM_EVENT_UP(&pTask->taskSema);
#endif
}
return pQNode;
}
BOOLEAN RtmpTimerQRemove(
IN RTMP_ADAPTER *pAd,
IN RALINK_TIMER_STRUCT *pTimer)
{
RTMP_TIMER_TASK_ENTRY *pNode, *pPrev = NULL;
unsigned long irqFlags;
RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags);
if (pAd->TimerQ.status >= RTMP_TASK_STAT_INITED)
{
pNode = pAd->TimerQ.pQHead;
while (pNode)
{
if (pNode->pRaTimer == pTimer)
break;
pPrev = pNode;
pNode = pNode->pNext;
}
// Now move it to freeList queue.
if (pNode)
{
if (pNode == pAd->TimerQ.pQHead)
pAd->TimerQ.pQHead = pNode->pNext;
if (pNode == pAd->TimerQ.pQTail)
pAd->TimerQ.pQTail = pPrev;
if (pPrev != NULL)
pPrev->pNext = pNode->pNext;
// return this queue entry to timerQFreeList.
pNode->pNext = pAd->TimerQ.pQPollFreeList;
pAd->TimerQ.pQPollFreeList = pNode;
}
}
RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
return TRUE;
}
void RtmpTimerQExit(RTMP_ADAPTER *pAd)
{
RTMP_TIMER_TASK_ENTRY *pTimerQ;
unsigned long irqFlags;
RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags);
while (pAd->TimerQ.pQHead)
{
pTimerQ = pAd->TimerQ.pQHead;
pAd->TimerQ.pQHead = pTimerQ->pNext;
// remove the timeQ
}
pAd->TimerQ.pQPollFreeList = NULL;
os_free_mem(pAd, pAd->TimerQ.pTimerQPoll);
pAd->TimerQ.pQTail = NULL;
pAd->TimerQ.pQHead = NULL;
#ifndef KTHREAD_SUPPORT
pAd->TimerQ.status = RTMP_TASK_STAT_STOPED;
#endif
RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
}
void RtmpTimerQInit(RTMP_ADAPTER *pAd)
{
int i;
RTMP_TIMER_TASK_ENTRY *pQNode, *pEntry;
unsigned long irqFlags;
NdisAllocateSpinLock(&pAd->TimerQLock);
NdisZeroMemory(&pAd->TimerQ, sizeof(pAd->TimerQ));
os_alloc_mem(pAd, &pAd->TimerQ.pTimerQPoll, sizeof(RTMP_TIMER_TASK_ENTRY) * TIMER_QUEUE_SIZE_MAX);
if (pAd->TimerQ.pTimerQPoll)
{
pEntry = NULL;
pQNode = (RTMP_TIMER_TASK_ENTRY *)pAd->TimerQ.pTimerQPoll;
NdisZeroMemory(pAd->TimerQ.pTimerQPoll, sizeof(RTMP_TIMER_TASK_ENTRY) * TIMER_QUEUE_SIZE_MAX);
RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags);
for (i = 0 ;i <TIMER_QUEUE_SIZE_MAX; i++)
{
pQNode->pNext = pEntry;
pEntry = pQNode;
pQNode++;
}
pAd->TimerQ.pQPollFreeList = pEntry;
pAd->TimerQ.pQHead = NULL;
pAd->TimerQ.pQTail = NULL;
pAd->TimerQ.status = RTMP_TASK_STAT_INITED;
RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
}
}
#endif // RTMP_TIMER_TASK_SUPPORT //

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,187 @@
# Support ATE function
HAS_ATE=y
# Support 28xx QA ATE function
HAS_28xx_QA=n
HAS_NINTENDO=n
# Support LLTD function
HAS_LLTD=n
# Support WDS function
HAS_WDS=n
# Support AP-Client function
HAS_APCLI=n
# Support Wpa_Supplicant
HAS_WPA_SUPPLICANT=y
# Support Native WpaSupplicant for Network Maganger
HAS_NATIVE_WPA_SUPPLICANT_SUPPORT=n
#Support Net interface block while Tx-Sw queue full
HAS_BLOCK_NET_IF=n
#Support IGMP-Snooping function.
HAS_IGMP_SNOOP_SUPPORT=n
#Support DFS function
HAS_DFS_SUPPORT=n
#Support Carrier-Sense function
HAS_CS_SUPPORT=n
# Support for STA Ethernet Converter
HAS_ETH_CONVERT_SUPPORT=n
# Support user specific transmit rate of Multicast packet.
HAS_MCAST_RATE_SPECIFIC_SUPPORT=n
# Support for Multiple Cards
HAS_MC_SUPPORT=n
#Support for PCI-MSI
HAS_MSI_SUPPORT=n
#Support for IEEE802.11e DLS
HAS_QOS_DLS_SUPPORT=n
#Support for EXT_CHANNEL
HAS_EXT_BUILD_CHANNEL_LIST=n
#Support for IDS
HAS_IDS_SUPPORT=n
#Support for Net-SNMP
HAS_SNMP_SUPPORT=n
#Support features of 802.11n Draft3
HAS_DOT11N_DRAFT3_SUPPORT=n
#Support features of Single SKU.
HAS_SINGLE_SKU_SUPPORT=n
#Support features of 802.11n
HAS_DOT11_N_SUPPORT=y
#Support for 2860/2880 co-exist
HAS_RT2880_RT2860_COEXIST=n
HAS_KTHREAD_SUPPORT=n
#Support for Auto channel select enhance
HAS_AUTO_CH_SELECT_ENHANCE=n
#Support bypass bridge
HAS_BG_FT_SUPPORT=n
#Support Antenna Diversity
HAS_ANTENNA_DIVERSITY_SUPPORT=y
#################################################
WFLAGS := -DAGGREGATION_SUPPORT -DPIGGYBACK_SUPPORT -DWMM_SUPPORT -DLINUX -Wall -Wstrict-prototypes -Wno-trigraphs -Wpointer-sign
ifeq ($(HAS_KTHREAD_SUPPORT),y)
WFLAGS += -DKTHREAD_SUPPORT
endif
#################################################
# config for STA mode
WFLAGS += -DCONFIG_STA_SUPPORT -DDBG
ifeq ($(HAS_WPA_SUPPLICANT),y)
WFLAGS += -DWPA_SUPPLICANT_SUPPORT
ifeq ($(HAS_NATIVE_WPA_SUPPLICANT_SUPPORT),y)
WFLAGS += -DNATIVE_WPA_SUPPLICANT_SUPPORT
endif
endif
ifeq ($(HAS_ETH_CONVERT_SUPPORT), y)
WFLAGS += -DETH_CONVERT_SUPPORT -DMAT_SUPPORT
endif
ifeq ($(HAS_ATE),y)
WFLAGS += -DRALINK_ATE
ifeq ($(HAS_28xx_QA),y)
WFLAGS += -DRALINK_28xx_QA
endif
endif
ifeq ($(HAS_SNMP_SUPPORT),y)
WFLAGS += -DSNMP_SUPPORT
endif
ifeq ($(HAS_QOS_DLS_SUPPORT),y)
WFLAGS += -DQOS_DLS_SUPPORT
endif
ifeq ($(HAS_DOT11_N_SUPPORT),y)
WFLAGS += -DDOT11_N_SUPPORT
endif
ifeq ($(HAS_CS_SUPPORT),y)
WFLAGS += -DCARRIER_DETECTION_SUPPORT
endif
ifeq ($(HAS_ANTENNA_DIVERSITY_SUPPORT),y)
WFLAGS += -DANT_DIVERSITY_SUPPORT
endif
#################################################
#################################################
#
# Common compiler flag
#
ifeq ($(HAS_EXT_BUILD_CHANNEL_LIST),y)
WFLAGS += -DEXT_BUILD_CHANNEL_LIST
endif
ifeq ($(HAS_IDS_SUPPORT),y)
WFLAGS += -DIDS_SUPPORT
endif
#################################################
# ChipSet specific definitions.
#
WFLAGS +=-DRTMP_MAC_PCI -DRT30xx -DRT3090 -DRTMP_PCI_SUPPORT -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT
#################################################
ifeq ($(HAS_BLOCK_NET_IF),y)
WFLAGS += -DBLOCK_NET_IF
endif
ifeq ($(HAS_DFS_SUPPORT),y)
WFLAGS += -DDFS_SUPPORT
endif
ifeq ($(HAS_MC_SUPPORT),y)
WFLAGS += -DMULTIPLE_CARD_SUPPORT
endif
ifeq ($(HAS_LLTD),y)
WFLAGS += -DLLTD_SUPPORT
endif
EXTRA_CFLAGS := $(WFLAGS)

View file

@ -0,0 +1,81 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
crypt_hmac.h
Abstract:
Miniport generic portion header file
Revision History:
Who When What
-------- ---------- ----------------------------------------------
Eddy 2008/11/24 Create HMAC-SHA1, HMAC-SHA256
*/
#ifndef __CRYPT_HMAC_H__
#define __CRYPT_HMAC_H__
#ifdef CRYPT_TESTPLAN
#include "crypt_testplan.h"
#else
#include "rt_config.h"
#endif /* CRYPT_TESTPLAN */
#ifdef SHA1_SUPPORT
#define HMAC_SHA1_SUPPORT
VOID HMAC_SHA1 (
IN const UINT8 Key[],
IN UINT KeyLen,
IN const UINT8 Message[],
IN UINT MessageLen,
OUT UINT8 MAC[],
IN UINT MACLen);
#endif /* SHA1_SUPPORT */
#ifdef SHA256_SUPPORT
#define HMAC_SHA256_SUPPORT
VOID HMAC_SHA256 (
IN const UINT8 Key[],
IN UINT KeyLen,
IN const UINT8 Message[],
IN UINT MessageLen,
OUT UINT8 MAC[],
IN UINT MACLen);
#endif /* SHA256_SUPPORT */
#ifdef MD5_SUPPORT
#define HMAC_MD5_SUPPORT
VOID HMAC_MD5 (
IN const UINT8 Key[],
IN UINT KeyLen,
IN const UINT8 Message[],
IN UINT MessageLen,
OUT UINT8 MAC[],
IN UINT MACLen);
#endif /* MD5_SUPPORT */
#endif /* __CRYPT_HMAC_H__ */

View file

@ -0,0 +1,78 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
crypt_md5.h
Abstract:
Miniport generic portion header file
Revision History:
Who When What
-------- ---------- ----------------------------------------------
Eddy 2008/11/24 Create md5
*/
#ifndef __CRYPT_MD5_H__
#define __CRYPT_MD5_H__
#ifdef CRYPT_TESTPLAN
#include "crypt_testplan.h"
#else
#include "rt_config.h"
#endif /* CRYPT_TESTPLAN */
/* Algorithm options */
#define MD5_SUPPORT
#ifdef MD5_SUPPORT
#define MD5_BLOCK_SIZE 64 /* 512 bits = 64 bytes */
#define MD5_DIGEST_SIZE 16 /* 128 bits = 16 bytes */
typedef struct {
UINT32 HashValue[4];
UINT64 MessageLen;
UINT8 Block[MD5_BLOCK_SIZE];
UINT BlockLen;
} MD5_CTX_STRUC, *PMD5_CTX_STRUC;
VOID MD5_Init (
IN MD5_CTX_STRUC *pMD5_CTX);
VOID MD5_Hash (
IN MD5_CTX_STRUC *pMD5_CTX);
VOID MD5_Append (
IN MD5_CTX_STRUC *pMD5_CTX,
IN const UINT8 Message[],
IN UINT MessageLen);
VOID MD5_End (
IN MD5_CTX_STRUC *pMD5_CTX,
OUT UINT8 DigestMessage[]);
VOID RT_MD5 (
IN const UINT8 Message[],
IN UINT MessageLen,
OUT UINT8 DigestMessage[]);
#endif /* MD5_SUPPORT */
#endif /* __CRYPT_MD5_H__ */

View file

@ -0,0 +1,107 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
crypt_sha2.h
Abstract:
Miniport generic portion header file
Revision History:
Who When What
-------- ---------- ----------------------------------------------
Eddy 2008/11/24 Create SHA1
Eddy 2008/07/23 Create SHA256
*/
#ifndef __CRYPT_SHA2_H__
#define __CRYPT_SHA2_H__
#ifdef CRYPT_TESTPLAN
#include "crypt_testplan.h"
#else
#include "rt_config.h"
#endif /* CRYPT_TESTPLAN */
/* Algorithm options */
#define SHA1_SUPPORT
#define SHA256_SUPPORT
#ifdef SHA1_SUPPORT
#define SHA1_BLOCK_SIZE 64 /* 512 bits = 64 bytes */
#define SHA1_DIGEST_SIZE 20 /* 160 bits = 20 bytes */
typedef struct _SHA1_CTX_STRUC {
UINT32 HashValue[5]; /* 5 = (SHA1_DIGEST_SIZE / 32) */
UINT64 MessageLen; /* total size */
UINT8 Block[SHA1_BLOCK_SIZE];
UINT BlockLen;
} SHA1_CTX_STRUC, *PSHA1_CTX_STRUC;
VOID SHA1_Init (
IN SHA1_CTX_STRUC *pSHA_CTX);
VOID SHA1_Hash (
IN SHA1_CTX_STRUC *pSHA_CTX);
VOID SHA1_Append (
IN SHA1_CTX_STRUC *pSHA_CTX,
IN const UINT8 Message[],
IN UINT MessageLen);
VOID SHA1_End (
IN SHA1_CTX_STRUC *pSHA_CTX,
OUT UINT8 DigestMessage[]);
VOID RT_SHA1 (
IN const UINT8 Message[],
IN UINT MessageLen,
OUT UINT8 DigestMessage[]);
#endif /* SHA1_SUPPORT */
#ifdef SHA256_SUPPORT
#define SHA256_BLOCK_SIZE 64 /* 512 bits = 64 bytes */
#define SHA256_DIGEST_SIZE 32 /* 256 bits = 32 bytes */
typedef struct _SHA256_CTX_STRUC {
UINT32 HashValue[8]; /* 8 = (SHA256_DIGEST_SIZE / 32) */
UINT64 MessageLen; /* total size */
UINT8 Block[SHA256_BLOCK_SIZE];
UINT BlockLen;
} SHA256_CTX_STRUC, *PSHA256_CTX_STRUC;
VOID SHA256_Init (
IN SHA256_CTX_STRUC *pSHA_CTX);
VOID SHA256_Hash (
IN SHA256_CTX_STRUC *pSHA_CTX);
VOID SHA256_Append (
IN SHA256_CTX_STRUC *pSHA_CTX,
IN const UINT8 Message[],
IN UINT MessageLen);
VOID SHA256_End (
IN SHA256_CTX_STRUC *pSHA_CTX,
OUT UINT8 DigestMessage[]);
VOID RT_SHA256 (
IN const UINT8 Message[],
IN UINT MessageLen,
OUT UINT8 DigestMessage[]);
#endif /* SHA256_SUPPORT */
#endif /* __CRYPT_SHA2_H__ */

View file

@ -0,0 +1,137 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
dfs.h
Abstract:
Miniport generic portion header file
Revision History:
Who When What
-------- ---------- ----------------------------------------------
Fonchi 03-12-2007 created
*/
#define RADAR_PULSE 1
#define RADAR_WIDTH 2
#define WIDTH_RD_IDLE 0
#define WIDTH_RD_CHECK 1
/*************************************************************************
*
* DFS Radar related definitions.
*
************************************************************************/
//#define CARRIER_DETECT_TASK_NUM 6
//#define RADAR_DETECT_TASK_NUM 7
// McuRadarState && McuCarrierState for 2880-SW-MCU
#define FREE_FOR_TX 0
#define WAIT_CTS_BEING_SENT 1
#define DO_DETECTION 2
// McuRadarEvent
#define RADAR_EVENT_CTS_SENT 0x01 // Host signal MCU that CTS has been sent
#define RADAR_EVENT_CTS_CARRIER_SENT 0x02 // Host signal MCU that CTS has been sent (Carrier)
#define RADAR_EVENT_RADAR_DETECTING 0x04 // Radar detection is on going, carrier detection hold back
#define RADAR_EVENT_CARRIER_DETECTING 0x08 // Carrier detection is on going, radar detection hold back
#define RADAR_EVENT_WIDTH_RADAR 0x10 // BBP == 2 radar detected
#define RADAR_EVENT_CTS_KICKED 0x20 // Radar detection need to sent double CTS, first CTS sent
// McuRadarCmd
#define DETECTION_STOP 0
#define RADAR_DETECTION 1
#define CARRIER_DETECTION 2
#ifdef TONE_RADAR_DETECT_SUPPORT
INT Set_CarrierCriteria_Proc(IN PRTMP_ADAPTER pAd, IN PSTRING arg);
int Set_CarrierReCheck_Proc(IN PRTMP_ADAPTER pAd, IN PSTRING arg);
INT Set_CarrierStopCheck_Proc(IN PRTMP_ADAPTER pAd, IN PSTRING arg);
void NewCarrierDetectionStart(PRTMP_ADAPTER pAd);
void RTMPHandleRadarInterrupt(PRTMP_ADAPTER pAd);
VOID CSAsicDisableSync(IN PRTMP_ADAPTER pAd);
#endif // TONE_RADAR_DETECT_SUPPORT //
VOID BbpRadarDetectionStart(
IN PRTMP_ADAPTER pAd);
VOID BbpRadarDetectionStop(
IN PRTMP_ADAPTER pAd);
VOID RadarDetectionStart(
IN PRTMP_ADAPTER pAd,
IN BOOLEAN CTS_Protect,
IN UINT8 CTSPeriod);
VOID RadarDetectionStop(
IN PRTMP_ADAPTER pAd);
VOID RadarDetectPeriodic(
IN PRTMP_ADAPTER pAd);
BOOLEAN RadarChannelCheck(
IN PRTMP_ADAPTER pAd,
IN UCHAR Ch);
ULONG JapRadarType(
IN PRTMP_ADAPTER pAd);
ULONG RTMPBbpReadRadarDuration(
IN PRTMP_ADAPTER pAd);
ULONG RTMPReadRadarDuration(
IN PRTMP_ADAPTER pAd);
VOID RTMPCleanRadarDuration(
IN PRTMP_ADAPTER pAd);
VOID RTMPPrepareRDCTSFrame(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pDA,
IN ULONG Duration,
IN UCHAR RTSRate,
IN ULONG CTSBaseAddr,
IN UCHAR FrameGap);
VOID RTMPPrepareRadarDetectParams(
IN PRTMP_ADAPTER pAd);
INT Set_ChMovingTime_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
INT Set_LongPulseRadarTh_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);

View file

@ -0,0 +1,82 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
eeprom.h
Abstract:
Miniport generic portion header file
Revision History:
Who When What
-------- ---------- ----------------------------------------------
*/
#ifndef __EEPROM_H__
#define __EEPROM_H__
#ifdef RTMP_PCI_SUPPORT
/*************************************************************************
* Public function declarations for prom-based chipset
************************************************************************/
int rtmp_ee_prom_read16(
IN PRTMP_ADAPTER pAd,
IN USHORT Offset,
OUT USHORT *pValue);
int rtmp_ee_prom_write16(
IN PRTMP_ADAPTER pAd,
IN USHORT Offset,
IN USHORT value);
#endif // RTMP_PCI_SUPPORT //
#ifdef RT30xx
#ifdef RTMP_EFUSE_SUPPORT
int rtmp_ee_efuse_read16(
IN RTMP_ADAPTER *pAd,
IN USHORT Offset,
OUT USHORT *pValue);
int rtmp_ee_efuse_write16(
IN RTMP_ADAPTER *pAd,
IN USHORT Offset,
IN USHORT data);
#endif // RTMP_EFUSE_SUPPORT //
#endif // RT30xx //
/*************************************************************************
* Public function declarations for prom operation callback functions setting
************************************************************************/
INT RtmpChipOpsEepromHook(
IN RTMP_ADAPTER *pAd,
IN INT infType);
#endif // __EEPROM_H__ //

View file

@ -0,0 +1,517 @@
/* AUTO GEN PLEASE DO NOT MODIFY IT */
/* AUTO GEN PLEASE DO NOT MODIFY IT */
UCHAR FirmwareImage [] = {
0x02, 0x02, 0xf3, 0x02, 0x02, 0xa1, 0x22, 0x22, 0xff, 0xff, 0xff, 0x02, 0x01, 0x27, 0xff, 0xff,
0xff, 0xff, 0xff, 0x02, 0x00, 0x1e, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x00, 0xd8, 0xc0, 0xe0,
0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x18, 0xc2, 0xaf, 0x30, 0x45, 0x03,
0x12, 0x10, 0x09, 0x90, 0x04, 0x16, 0xe0, 0x30, 0xe3, 0x03, 0x74, 0x08, 0xf0, 0x90, 0x04, 0x14,
0xe0, 0x20, 0xe7, 0x03, 0x02, 0x00, 0xcb, 0x74, 0x80, 0xf0, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x36,
0x90, 0x04, 0x04, 0xe0, 0x24, 0xcf, 0x60, 0x30, 0x14, 0x60, 0x42, 0x24, 0xe2, 0x60, 0x47, 0x14,
0x60, 0x55, 0x24, 0x21, 0x70, 0x60, 0xe5, 0x55, 0x24, 0xfe, 0x60, 0x07, 0x14, 0x60, 0x08, 0x24,
0x02, 0x70, 0x08, 0x7d, 0x01, 0x80, 0x28, 0x7d, 0x02, 0x80, 0x24, 0x90, 0x70, 0x10, 0xe0, 0xf5,
0x50, 0x85, 0x36, 0x40, 0xd2, 0x01, 0x80, 0x3e, 0xe5, 0x55, 0x64, 0x03, 0x60, 0x04, 0xe5, 0x55,
0x70, 0x04, 0x7d, 0x02, 0x80, 0x09, 0x85, 0x36, 0x41, 0xd2, 0x02, 0x80, 0x29, 0xad, 0x55, 0xaf,
0x36, 0x12, 0x02, 0x7d, 0x80, 0x20, 0x90, 0x70, 0x10, 0xe0, 0xf5, 0x47, 0x90, 0x70, 0x11, 0xe0,
0xf5, 0x44, 0x12, 0x10, 0x25, 0x80, 0x06, 0x90, 0x70, 0x10, 0xe0, 0xf5, 0x45, 0xe4, 0xfd, 0xaf,
0x36, 0x12, 0x02, 0x7d, 0xd2, 0x04, 0x90, 0x70, 0x13, 0xe4, 0xf0, 0xd2, 0xaf, 0xd0, 0xd0, 0xd0,
0x82, 0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82,
0xc0, 0xd0, 0xe8, 0xc0, 0xe0, 0xe9, 0xc0, 0xe0, 0xea, 0xc0, 0xe0, 0xeb, 0xc0, 0xe0, 0xec, 0xc0,
0xe0, 0xed, 0xc0, 0xe0, 0xee, 0xc0, 0xe0, 0xef, 0xc0, 0xe0, 0xc2, 0xaf, 0x30, 0x45, 0x03, 0x12,
0x10, 0x12, 0xd2, 0xaf, 0xd0, 0xe0, 0xff, 0xd0, 0xe0, 0xfe, 0xd0, 0xe0, 0xfd, 0xd0, 0xe0, 0xfc,
0xd0, 0xe0, 0xfb, 0xd0, 0xe0, 0xfa, 0xd0, 0xe0, 0xf9, 0xd0, 0xe0, 0xf8, 0xd0, 0xd0, 0xd0, 0x82,
0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0,
0xd0, 0x75, 0xd0, 0x10, 0xc2, 0xaf, 0x30, 0x45, 0x03, 0x12, 0x10, 0x0c, 0x30, 0x58, 0x0a, 0xe5,
0x54, 0x60, 0x04, 0x15, 0x54, 0x80, 0x02, 0xc2, 0x58, 0x30, 0x59, 0x0a, 0xe5, 0x50, 0x60, 0x04,
0x15, 0x50, 0x80, 0x02, 0xc2, 0x59, 0xd5, 0x53, 0x07, 0x30, 0x60, 0x04, 0x15, 0x46, 0xd2, 0x04,
0x30, 0x45, 0x03, 0x12, 0x10, 0x0f, 0xc2, 0x8d, 0xd2, 0xaf, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83,
0xd0, 0xf0, 0xd0, 0xe0, 0x32, 0x90, 0x70, 0x2a, 0xe0, 0x30, 0xe1, 0x43, 0xc2, 0xaf, 0x90, 0x70,
0x28, 0xe0, 0x90, 0x10, 0x1c, 0xf0, 0x90, 0x70, 0x29, 0xe0, 0x90, 0x10, 0x1d, 0xf0, 0x90, 0x70,
0x2a, 0xe0, 0x90, 0x10, 0x1e, 0xf0, 0x90, 0x10, 0x1c, 0xe0, 0xf5, 0x37, 0x90, 0x10, 0x1e, 0xe0,
0x20, 0xe1, 0xf3, 0x90, 0x10, 0x1c, 0xe0, 0x90, 0x70, 0x28, 0xf0, 0x90, 0x10, 0x1d, 0xe0, 0x90,
0x70, 0x29, 0xf0, 0x90, 0x10, 0x1e, 0xe0, 0x90, 0x70, 0x2a, 0xf0, 0xc2, 0x05, 0xd2, 0xaf, 0x22,
0x12, 0x02, 0xc3, 0x30, 0x45, 0x03, 0x12, 0x10, 0x03, 0x30, 0x01, 0x06, 0x20, 0x09, 0x03, 0x12,
0x10, 0x1c, 0x30, 0x02, 0x06, 0x20, 0x0a, 0x03, 0x12, 0x10, 0x1f, 0x30, 0x03, 0x06, 0x20, 0x0b,
0x03, 0x12, 0x10, 0x1f, 0x30, 0x04, 0x06, 0x20, 0x0c, 0x03, 0x12, 0x10, 0x22, 0x20, 0x13, 0x09,
0x20, 0x11, 0x06, 0xe5, 0x2b, 0x45, 0x2c, 0x60, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0xa9, 0x12,
0x03, 0x1c, 0x80, 0xbf, 0xc2, 0x43, 0xd2, 0x45, 0xe4, 0xf5, 0x20, 0xf5, 0x21, 0xf5, 0x53, 0xf5,
0x46, 0xf5, 0x2b, 0xf5, 0x2c, 0xc2, 0x42, 0xf5, 0x51, 0xf5, 0x52, 0xf5, 0x55, 0x90, 0x04, 0x18,
0x74, 0x80, 0xf0, 0x90, 0x04, 0x1a, 0x74, 0x08, 0xf0, 0xc2, 0x1a, 0xc2, 0x18, 0xc2, 0x1b, 0x22,
0xc8, 0xef, 0xc8, 0xe6, 0xfa, 0x08, 0xe6, 0x4a, 0x60, 0x0c, 0xc8, 0xef, 0xc8, 0x08, 0xe6, 0x16,
0x18, 0x70, 0x01, 0x16, 0xc3, 0x22, 0xed, 0x24, 0xff, 0xfd, 0xec, 0x34, 0xff, 0xc8, 0xef, 0xc8,
0xf6, 0x08, 0xc6, 0xed, 0xc6, 0xd3, 0x22, 0xd0, 0x83, 0xd0, 0x82, 0xf8, 0xe4, 0x93, 0x70, 0x12,
0x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, 0xa3, 0x93, 0xf8, 0x74, 0x01, 0x93, 0xf5, 0x82, 0x88, 0x83,
0xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60, 0xef, 0xa3, 0xa3, 0xa3, 0x80, 0xdf, 0xef, 0xf4, 0x60,
0x1f, 0xe4, 0xfe, 0x12, 0x03, 0x5b, 0xe0, 0xb4, 0xff, 0x12, 0x12, 0x03, 0x5b, 0xef, 0xf0, 0x74,
0x1c, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe, 0x04, 0xe3,
0x22, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x08, 0xc2, 0xaf,
0x30, 0x45, 0x03, 0x12, 0x10, 0x06, 0xd2, 0xaf, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xf0,
0xd0, 0xe0, 0x32, 0xc2, 0xaf, 0x12, 0x00, 0x06, 0x12, 0x02, 0x04, 0x12, 0x02, 0xdc, 0xe4, 0xf5,
0x22, 0xf5, 0x47, 0x90, 0x04, 0x00, 0x74, 0x80, 0xf0, 0xd2, 0xaf, 0x22, 0x75, 0x89, 0x02, 0xe4,
0xf5, 0x8c, 0xf5, 0x8a, 0xf5, 0x88, 0xf5, 0xb8, 0xf5, 0xe8, 0x75, 0x90, 0x18, 0xd2, 0x8c, 0x75,
0xa8, 0x05, 0x22, 0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x5f, 0x02, 0x01, 0xc0, 0xff,
0xc0, 0x26, 0x74, 0x03, 0xc0, 0xe0, 0xc0, 0x82, 0xc0, 0x83, 0x75, 0x26, 0x0a, 0x22, 0xc0, 0x26,
0x74, 0x03, 0xc0, 0xe0, 0xc0, 0x82, 0xc0, 0x83, 0x75, 0x26, 0x18, 0x22, 0x30, 0x45, 0x03, 0x12,
0x10, 0x15, 0xe5, 0x20, 0x70, 0x03, 0x20, 0x10, 0x03, 0x30, 0x11, 0x03, 0x43, 0x87, 0x01, 0x22,
0xce, 0xef, 0xce, 0xee, 0x60, 0x08, 0x7f, 0xff, 0x12, 0x03, 0x71, 0x1e, 0x80, 0xf5, 0x22, 0xc8,
0xef, 0xc8, 0xe6, 0x60, 0x03, 0x16, 0xc3, 0x22, 0xed, 0x14, 0xf6, 0xd3, 0x22, 0xc8, 0xef, 0xc8,
0xe6, 0x60, 0x06, 0x16, 0xe6, 0x24, 0xff, 0xb3, 0x22, 0xc3, 0x22, 0x74, 0x14, 0x2e, 0xf5, 0x82,
0xe4, 0x34, 0x70, 0xf5, 0x83, 0x22, 0xef, 0x90, 0x03, 0x6f, 0x93, 0x90, 0x03, 0x00, 0x73, 0x0a,
0x18, 0xef, 0x60, 0x03, 0x1f, 0x80, 0xfa, 0x22, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x3b, 0x02, 0x10, 0x3c, 0x02, 0x13, 0x68, 0x02,
0x13, 0x69, 0x02, 0x14, 0x1e, 0x02, 0x14, 0x1f, 0xc3, 0x22, 0xff, 0xff, 0x02, 0x19, 0xa1, 0x02,
0x1b, 0x31, 0x02, 0x14, 0xea, 0x02, 0x14, 0x20, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x01,
0x75, 0x30, 0x06, 0x06, 0x20, 0x0e, 0x03, 0x12, 0x1c, 0x4f, 0x22, 0x22, 0x90, 0x04, 0x14, 0xe0,
0x20, 0xe7, 0x03, 0x02, 0x13, 0x67, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0,
0x12, 0x02, 0x57, 0x11, 0x11, 0x30, 0x10, 0xe2, 0x31, 0x10, 0x90, 0x33, 0x10, 0xa0, 0x34, 0x10,
0xbe, 0x35, 0x10, 0xac, 0x36, 0x11, 0x1f, 0x50, 0x11, 0x68, 0x51, 0x11, 0x71, 0x52, 0x11, 0x71,
0x53, 0x11, 0x71, 0x54, 0x11, 0xb3, 0x55, 0x12, 0x16, 0x70, 0x12, 0x42, 0x71, 0x12, 0x71, 0x72,
0x12, 0xda, 0x73, 0x12, 0xfe, 0x80, 0x13, 0x29, 0x83, 0x13, 0x47, 0x84, 0x00, 0x00, 0x13, 0x67,
0xd2, 0x18, 0xd2, 0x61, 0x75, 0x35, 0x2a, 0x75, 0x32, 0x0b, 0x75, 0x33, 0xb8, 0x02, 0x13, 0x62,
0xc2, 0x18, 0x90, 0x01, 0x14, 0xe0, 0x54, 0xfd, 0xf0, 0x02, 0x13, 0x62, 0x90, 0x70, 0x11, 0xe0,
0xf5, 0x3c, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x22, 0xe5, 0x55,
0xb4, 0x02, 0x0f, 0xe5, 0x59, 0xb4, 0x28, 0x06, 0x90, 0x01, 0x0d, 0x74, 0x08, 0xf0, 0x7d, 0x01,
0x80, 0x02, 0x7d, 0x02, 0xaf, 0x56, 0x12, 0x02, 0x7d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x02,
0x13, 0x62, 0x20, 0x02, 0x03, 0x30, 0x03, 0x10, 0x7d, 0x02, 0xaf, 0x56, 0x12, 0x02, 0x7d, 0x90,
0x04, 0x14, 0x74, 0x80, 0xf0, 0x02, 0x13, 0x62, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x0c, 0x90,
0x01, 0x0c, 0xe0, 0x44, 0x02, 0xf0, 0xa3, 0xe0, 0x44, 0x04, 0xf0, 0x85, 0x56, 0x41, 0xd2, 0x02,
0x22, 0x90, 0x70, 0x11, 0xe0, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x67, 0xe0, 0xf5, 0x30, 0x22, 0xe5,
0x34, 0xc3, 0x94, 0x03, 0x40, 0x07, 0xe5, 0x55, 0x60, 0x03, 0x02, 0x13, 0x67, 0x90, 0x70, 0x10,
0xe0, 0x54, 0x7f, 0xff, 0xbf, 0x0a, 0x0d, 0x90, 0x70, 0x11, 0xe0, 0xb4, 0x08, 0x06, 0x75, 0x4e,
0x01, 0x75, 0x4f, 0x84, 0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0x64, 0x02, 0x60, 0x03, 0x02, 0x13,
0x67, 0x90, 0x70, 0x11, 0xe0, 0x64, 0x08, 0x60, 0x08, 0xe0, 0x64, 0x20, 0x60, 0x03, 0x02, 0x13,
0x67, 0x75, 0x4e, 0x03, 0x75, 0x4f, 0x20, 0x22, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92, 0x47,
0x22, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x07, 0xe5, 0x55, 0x60, 0x03, 0x02, 0x13, 0x09, 0x90,
0x04, 0x04, 0xe0, 0x25, 0xe0, 0x24, 0x5d, 0xf5, 0x57, 0x90, 0x70, 0x10, 0xe0, 0xff, 0x74, 0x47,
0x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0x90, 0x70, 0x11, 0xe0, 0xff, 0x74, 0x48, 0x25, 0x57, 0xf8,
0xc6, 0xef, 0xc6, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x02, 0x7d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0,
0x02, 0x13, 0x62, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x07, 0xe5, 0x55, 0x60, 0x03, 0x02, 0x13,
0x09, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x23, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x1d, 0xe5, 0x47, 0x64,
0x09, 0x60, 0x17, 0xe5, 0x47, 0x64, 0x0a, 0x60, 0x11, 0xe5, 0x47, 0x64, 0x0b, 0x60, 0x0b, 0xe5,
0x47, 0x64, 0x0d, 0x60, 0x05, 0xe5, 0x47, 0xb4, 0x0d, 0x08, 0x90, 0x70, 0x11, 0xe0, 0x54, 0x0f,
0xf5, 0x3a, 0xe5, 0x47, 0xb4, 0x09, 0x08, 0xe5, 0x3a, 0xb4, 0x03, 0x03, 0xe4, 0xf5, 0x46, 0xe5,
0x47, 0xb4, 0x0a, 0x08, 0xe5, 0x3a, 0xb4, 0x01, 0x03, 0xe4, 0xf5, 0x46, 0xe4, 0xfd, 0xaf, 0x56,
0x12, 0x02, 0x7d, 0xd2, 0x04, 0x22, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x07, 0xe5, 0x55, 0x60,
0x03, 0x02, 0x13, 0x09, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf8,
0xe6, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x02, 0x7d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x02,
0x13, 0x62, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x07, 0xe5, 0x55, 0x60, 0x03, 0x02, 0x13, 0x09,
0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf5, 0x82, 0x8e, 0x83, 0xe0,
0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x02, 0x7d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x02, 0x13,
0x62, 0x90, 0x10, 0x00, 0xe0, 0xf5, 0x57, 0x90, 0x10, 0x02, 0xe0, 0xf5, 0x58, 0xa3, 0xe0, 0xf5,
0x59, 0xe5, 0x58, 0xb4, 0x70, 0x1e, 0xe5, 0x59, 0xb4, 0x30, 0x19, 0x90, 0x05, 0x08, 0xe0, 0x44,
0x01, 0xf0, 0xfd, 0x90, 0x05, 0x05, 0xe0, 0x54, 0xfb, 0xf0, 0x44, 0x04, 0xf0, 0xed, 0x54, 0xfe,
0x90, 0x05, 0x08, 0xf0, 0xe4, 0xf5, 0x4e, 0xf5, 0x4f, 0x75, 0x3a, 0xff, 0xc2, 0x1a, 0xc2, 0x18,
0xc2, 0x1b, 0xf5, 0x34, 0x90, 0x05, 0xa4, 0x74, 0x11, 0xf0, 0xa3, 0x74, 0xff, 0xf0, 0xa3, 0x74,
0x03, 0xf0, 0xe4, 0xf5, 0x30, 0xc2, 0x19, 0x75, 0x3c, 0xff, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x02,
0x7d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x02, 0x13, 0x62, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40,
0x06, 0xe5, 0x55, 0x60, 0x02, 0x80, 0x22, 0x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x93, 0xe4,
0xfd, 0xaf, 0x56, 0x12, 0x02, 0x7d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x80, 0x64, 0xe5, 0x34,
0xc3, 0x94, 0x03, 0x40, 0x0b, 0xe5, 0x55, 0x60, 0x07, 0x7d, 0x03, 0xaf, 0x56, 0x02, 0x02, 0x7d,
0x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x4a, 0xd2, 0x05, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x02,
0x7d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x80, 0x39, 0xe4, 0xf5, 0x34, 0xf5, 0x30, 0x90, 0x70,
0x10, 0xe0, 0xf4, 0x60, 0x03, 0xe0, 0xf5, 0x34, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x02, 0x7d, 0x90,
0x04, 0x14, 0x74, 0x80, 0xf0, 0x80, 0x1b, 0xd2, 0x19, 0x05, 0x2f, 0xe5, 0x2f, 0xb4, 0x1a, 0x03,
0xe4, 0xf5, 0x2f, 0xd2, 0x04, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x02, 0x7d, 0x90, 0x04, 0x14, 0x74,
0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0x22, 0x22, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x17,
0xe5, 0x55, 0xb4, 0x02, 0x12, 0xe5, 0x30, 0x60, 0x0e, 0x30, 0x60, 0x0b, 0x74, 0xfd, 0x25, 0x46,
0xf5, 0x46, 0xd2, 0x04, 0xe4, 0xf5, 0x53, 0xe5, 0x53, 0x60, 0x03, 0x02, 0x14, 0x1d, 0x30, 0x60,
0x21, 0xb2, 0x4d, 0x30, 0x4d, 0x1c, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x11, 0xe5, 0x55, 0xb4,
0x02, 0x0c, 0xe5, 0x30, 0x60, 0x08, 0x74, 0x03, 0x25, 0x46, 0xf5, 0x46, 0x80, 0x02, 0x05, 0x46,
0xc2, 0x04, 0xe5, 0x4f, 0x45, 0x4e, 0x60, 0x08, 0xe5, 0x4f, 0x15, 0x4f, 0x70, 0x02, 0x15, 0x4e,
0x30, 0x1a, 0x49, 0x7f, 0x32, 0x7d, 0xb8, 0x7c, 0x0b, 0x12, 0x02, 0x30, 0x50, 0x06, 0x90, 0x04,
0x10, 0x74, 0x40, 0xf0, 0x7f, 0x35, 0x7d, 0x32, 0x12, 0x03, 0x3f, 0x50, 0x09, 0x90, 0x10, 0x04,
0xe0, 0x54, 0xf7, 0xf0, 0xd2, 0x06, 0xe5, 0x35, 0xd3, 0x94, 0x2d, 0x40, 0x30, 0x30, 0x1b, 0x2d,
0xc2, 0x1b, 0xa2, 0x18, 0x92, 0x1a, 0x20, 0x1a, 0x24, 0x90, 0x04, 0x09, 0xe0, 0x54, 0xdd, 0xf0,
0x90, 0x10, 0x04, 0xe0, 0x44, 0x08, 0xf0, 0xc2, 0x61, 0xd2, 0x03, 0x22, 0xe4, 0xf5, 0x35, 0xa2,
0x18, 0x92, 0x1a, 0x30, 0x1a, 0x07, 0x90, 0x04, 0x09, 0xe0, 0x44, 0x22, 0xf0, 0x22, 0x22, 0x22,
0xc2, 0x4b, 0xc2, 0x4c, 0xe5, 0x44, 0x12, 0x02, 0x57, 0x14, 0x42, 0x00, 0x14, 0xd5, 0x04, 0x14,
0xd1, 0x08, 0x14, 0xac, 0x10, 0x14, 0x56, 0x20, 0x14, 0x76, 0x60, 0x14, 0x87, 0xa0, 0x00, 0x00,
0x14, 0xd7, 0x85, 0x48, 0x43, 0x85, 0x4a, 0x42, 0x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60,
0x03, 0x02, 0x14, 0xd7, 0x80, 0x1b, 0xe5, 0x48, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4a, 0xc4,
0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4c, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70,
0x66, 0x53, 0x43, 0x0f, 0x80, 0x61, 0x85, 0x49, 0x43, 0x85, 0x4b, 0x42, 0x85, 0x4d, 0x5e, 0xe5,
0x47, 0x64, 0x06, 0x70, 0x52, 0x80, 0x1b, 0xe5, 0x49, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4b,
0xc4, 0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4d, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06,
0x70, 0x35, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x10, 0xf5, 0x43, 0x80, 0x2b, 0xe5, 0x47, 0xb4, 0x04,
0x06, 0x53, 0x5e, 0xfb, 0x75, 0x42, 0x09, 0xe5, 0x47, 0xb4, 0x05, 0x06, 0x43, 0x5e, 0x04, 0x75,
0x42, 0x09, 0xe5, 0x47, 0xb4, 0x06, 0x10, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x30, 0xf5, 0x43, 0x80,
0x06, 0xd2, 0x4b, 0x80, 0x02, 0xd2, 0x4c, 0xe4, 0xf5, 0x2a, 0xe5, 0x42, 0xc4, 0x54, 0xf0, 0xff,
0xe5, 0x43, 0x54, 0x0f, 0x4f, 0xf5, 0x5f, 0xd2, 0x60, 0x22, 0xe5, 0x47, 0x60, 0x1a, 0x24, 0xc0,
0x60, 0x0a, 0x24, 0x35, 0x70, 0x09, 0x12, 0x19, 0x5f, 0x12, 0x15, 0x09, 0x12, 0x19, 0x5f, 0x12,
0x15, 0x09, 0xc2, 0xaf, 0xc2, 0x04, 0xd2, 0xaf, 0x22, 0xc2, 0xaf, 0x90, 0x04, 0x14, 0xe0, 0x54,
0x0e, 0x60, 0x04, 0xd2, 0x1c, 0x80, 0x08, 0xe5, 0x4e, 0x45, 0x4f, 0x24, 0xff, 0x92, 0x1c, 0xd2,
0xaf, 0x90, 0x04, 0x14, 0xe0, 0xa2, 0xe4, 0x92, 0x1d, 0x74, 0x1e, 0xf0, 0xe5, 0x5f, 0x54, 0x0f,
0xf5, 0x2d, 0xe5, 0x2a, 0x70, 0x13, 0x30, 0x1c, 0x05, 0xe5, 0x5f, 0x20, 0xe5, 0x0b, 0x30, 0x1d,
0x29, 0xe5, 0x5f, 0x54, 0x30, 0x64, 0x30, 0x70, 0x21, 0xe5, 0x2a, 0x70, 0x15, 0xe5, 0x34, 0xc3,
0x94, 0x03, 0x40, 0x09, 0xe5, 0x30, 0x60, 0x05, 0x75, 0x2a, 0x05, 0x80, 0x07, 0x75, 0x2a, 0x0c,
0x80, 0x02, 0x15, 0x2a, 0xd2, 0x6c, 0xd2, 0x6d, 0x80, 0x0f, 0xe5, 0x5f, 0x30, 0xe6, 0x06, 0xc2,
0x6c, 0xd2, 0x6d, 0x80, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0xe5, 0x47, 0x64, 0x03, 0x70, 0x21, 0x30,
0x4b, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x18, 0xe5, 0x2a, 0x70, 0x03, 0x30, 0x4c, 0x11, 0xc2,
0x4c, 0xe5, 0x2a, 0x70, 0x05, 0x75, 0x2a, 0x07, 0x80, 0x02, 0x15, 0x2a, 0xd2, 0x6c, 0xd2, 0x6d,
0xe5, 0x47, 0xb4, 0x09, 0x14, 0xe5, 0x44, 0x20, 0xe3, 0x0b, 0xe5, 0x3a, 0x64, 0x02, 0x60, 0x05,
0xe5, 0x3a, 0xb4, 0x03, 0x04, 0xc2, 0x6c, 0xd2, 0x6d, 0xe5, 0x47, 0xb4, 0x0a, 0x13, 0xe5, 0x3a,
0xb4, 0x01, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x08, 0xe5, 0x3a, 0x70, 0x04, 0xd2, 0x6c, 0xc2,
0x6d, 0x20, 0x69, 0x07, 0xe5, 0x5e, 0x20, 0xe0, 0x02, 0xb2, 0x68, 0x20, 0x6b, 0x07, 0xe5, 0x5e,
0x20, 0xe1, 0x02, 0xb2, 0x6a, 0x20, 0x6d, 0x07, 0xe5, 0x5e, 0x20, 0xe2, 0x02, 0xb2, 0x6c, 0x75,
0x2e, 0x40, 0x20, 0x69, 0x04, 0xa2, 0x68, 0x80, 0x45, 0x30, 0x68, 0x06, 0xe5, 0x46, 0xa2, 0xe2,
0x80, 0x3c, 0x30, 0x19, 0x1c, 0xe5, 0x5e, 0x20, 0xe2, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00,
0xe5, 0x2f, 0xb4, 0x19, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x80,
0x1d, 0xe5, 0x5e, 0x20, 0xe2, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0,
0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x73,
0x92, 0x72, 0x20, 0x6b, 0x04, 0xa2, 0x6a, 0x80, 0x45, 0x30, 0x6a, 0x06, 0xe5, 0x46, 0xa2, 0xe2,
0x80, 0x3c, 0x30, 0x19, 0x1c, 0xe5, 0x5e, 0x20, 0xe0, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00,
0xe5, 0x2f, 0xb4, 0x19, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x80,
0x1d, 0xe5, 0x5e, 0x20, 0xe0, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0,
0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x75,
0x92, 0x74, 0x20, 0x6d, 0x04, 0xa2, 0x6c, 0x80, 0x64, 0xe5, 0x47, 0x64, 0x0a, 0x70, 0x19, 0xe5,
0x3a, 0xb4, 0x01, 0x06, 0xe5, 0x46, 0xa2, 0xe3, 0x80, 0x53, 0xe5, 0x46, 0x20, 0xe4, 0x03, 0x30,
0xe5, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x80, 0x45, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80,
0x3c, 0x30, 0x19, 0x1c, 0xe5, 0x5e, 0x20, 0xe1, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5,
0x2f, 0xb4, 0x19, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x80, 0x1d,
0xe5, 0x5e, 0x20, 0xe1, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe,
0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x71, 0x92,
0x70, 0x90, 0x10, 0x00, 0xe0, 0x90, 0x10, 0x2c, 0xf0, 0x90, 0x10, 0x03, 0xe0, 0xc3, 0x94, 0x30,
0x40, 0x14, 0xa2, 0x71, 0x92, 0x77, 0xa2, 0x70, 0x92, 0x76, 0xe5, 0x2e, 0x13, 0x13, 0x54, 0x3f,
0xf5, 0x2e, 0xc2, 0x77, 0xd2, 0x76, 0x90, 0x10, 0x2f, 0xe5, 0x2e, 0xf0, 0xe5, 0x47, 0x64, 0x06,
0x70, 0x46, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f, 0x14, 0x60,
0x14, 0x24, 0xfe, 0x60, 0x1f, 0x24, 0x03, 0x60, 0x03, 0x02, 0x19, 0x5e, 0x90, 0x02, 0x28, 0xe0,
0x30, 0x47, 0x0d, 0x80, 0x07, 0x90, 0x02, 0x28, 0xe0, 0x20, 0x47, 0x04, 0x54, 0xfe, 0xf0, 0x22,
0x44, 0x01, 0xf0, 0x22, 0xe5, 0x46, 0x30, 0xe2, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x90,
0x02, 0x28, 0xe0, 0x54, 0xfe, 0x4f, 0xf0, 0x22, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x0f, 0xe5, 0x47,
0x64, 0x08, 0x60, 0x09, 0xe5, 0x47, 0x64, 0x09, 0x60, 0x03, 0x02, 0x18, 0x27, 0xe4, 0xf5, 0x27,
0x90, 0x02, 0x29, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x2d, 0x14, 0x60, 0x2e, 0x14,
0x60, 0x36, 0x24, 0xfc, 0x60, 0x5f, 0x24, 0xf9, 0x60, 0x1f, 0x24, 0x0e, 0x70, 0x69, 0xe5, 0x46,
0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xaf, 0xf0, 0x20, 0x47, 0x04, 0x7e, 0x01, 0x80,
0x02, 0x7e, 0x00, 0xef, 0x6e, 0x24, 0xff, 0x80, 0x45, 0xa2, 0x47, 0x80, 0x41, 0xe5, 0x46, 0x30,
0xe2, 0x03, 0xd3, 0x80, 0x27, 0xc3, 0x80, 0x24, 0xe5, 0x46, 0x30, 0xe2, 0x0d, 0x54, 0x38, 0xc3,
0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0x20, 0x47,
0x04, 0x7d, 0x01, 0x80, 0x02, 0x7d, 0x00, 0xef, 0x6d, 0x4e, 0x24, 0xff, 0x92, 0x38, 0xa2, 0x47,
0xb3, 0x92, 0x39, 0x80, 0x19, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x39,
0xa2, 0x47, 0xb3, 0x92, 0x38, 0x80, 0x07, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x92, 0x39, 0x90, 0x02,
0x28, 0xe0, 0x54, 0xfc, 0x02, 0x19, 0x5b, 0xe5, 0x47, 0x64, 0x0c, 0x60, 0x09, 0xe5, 0x47, 0x64,
0x0b, 0x60, 0x03, 0x02, 0x18, 0xc6, 0xe4, 0xf5, 0x27, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfd, 0xf0,
0xe5, 0x3a, 0x14, 0x60, 0x2b, 0x14, 0x60, 0x2e, 0x14, 0x60, 0x38, 0x24, 0xfc, 0x60, 0x5c, 0x24,
0xf9, 0x60, 0x1d, 0x24, 0x0e, 0x70, 0x61, 0xe5, 0x46, 0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, 0x03,
0x84, 0xaf, 0xf0, 0x20, 0x47, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xef, 0x6e, 0x80, 0x35,
0xa2, 0x47, 0x92, 0x39, 0x80, 0x47, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92,
0x39, 0x80, 0x3a, 0xe5, 0x46, 0x30, 0xe2, 0x0d, 0x54, 0x38, 0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e,
0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0x20, 0x47, 0x04, 0x7d, 0x01, 0x80, 0x02,
0x7d, 0x00, 0xef, 0x6d, 0x4e, 0x24, 0xff, 0x92, 0x39, 0x80, 0x12, 0xe5, 0x46, 0x30, 0xe2, 0x03,
0xd3, 0x80, 0x01, 0xc3, 0x92, 0x39, 0x80, 0x05, 0xa2, 0x47, 0xb3, 0x92, 0x39, 0x90, 0x02, 0x28,
0xe0, 0x54, 0xfd, 0x02, 0x19, 0x5b, 0xe5, 0x47, 0x64, 0x0d, 0x60, 0x03, 0x02, 0x19, 0x5e, 0xf5,
0x27, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xef, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x2b, 0x14, 0x60, 0x2e,
0x14, 0x60, 0x38, 0x24, 0xfc, 0x60, 0x5c, 0x24, 0xf9, 0x60, 0x1d, 0x24, 0x0e, 0x70, 0x61, 0xe5,
0x46, 0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xaf, 0xf0, 0x20, 0x47, 0x04, 0x7e, 0x01,
0x80, 0x02, 0x7e, 0x00, 0xef, 0x6e, 0x80, 0x35, 0xa2, 0x47, 0x92, 0x3c, 0x80, 0x47, 0xe5, 0x46,
0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x3c, 0x80, 0x3a, 0xe5, 0x46, 0x30, 0xe2, 0x0d,
0x54, 0x38, 0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f,
0x00, 0x20, 0x47, 0x04, 0x7d, 0x01, 0x80, 0x02, 0x7d, 0x00, 0xef, 0x6d, 0x4e, 0x24, 0xff, 0x92,
0x3c, 0x80, 0x12, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x3c, 0x80, 0x05,
0xa2, 0x47, 0xb3, 0x92, 0x3c, 0x90, 0x02, 0x28, 0xe0, 0x54, 0xef, 0x45, 0x27, 0xf0, 0x22, 0xe5,
0x47, 0x64, 0x0b, 0x70, 0x1c, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xeb, 0xf0, 0x30, 0x47, 0x04, 0xaf,
0x45, 0x80, 0x05, 0xe5, 0x45, 0x64, 0x14, 0xff, 0x90, 0x02, 0x28, 0xe0, 0x54, 0xeb, 0x4f, 0xf0,
0x22, 0xe4, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x45, 0x80, 0x04, 0xe5, 0x45, 0xf4,
0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22, 0x8f, 0x50, 0xd2, 0x59, 0x22, 0x8f, 0x54, 0xd2, 0x58,
0x22, 0xe4, 0xf5, 0x37, 0xc2, 0xaf, 0xe5, 0x51, 0x14, 0x60, 0x4a, 0x14, 0x60, 0x6b, 0x24, 0x02,
0x60, 0x03, 0x02, 0x1b, 0x12, 0xd2, 0x59, 0x75, 0x55, 0x01, 0x20, 0x1a, 0x1c, 0x90, 0x02, 0x08,
0xe0, 0x54, 0xfe, 0xf0, 0xe0, 0x20, 0xe1, 0x23, 0x90, 0x04, 0x34, 0xe0, 0xb4, 0x02, 0x1c, 0xa3,
0xe0, 0xb4, 0x02, 0x17, 0xa3, 0xe0, 0xb4, 0x02, 0x12, 0x7f, 0x20, 0x12, 0x19, 0x97, 0x90, 0x10,
0x04, 0xe0, 0x54, 0xf3, 0xf0, 0x75, 0x51, 0x01, 0x02, 0x1b, 0x12, 0xe5, 0x50, 0x70, 0x06, 0x75,
0x37, 0x03, 0x02, 0x1b, 0x12, 0x90, 0x12, 0x00, 0xe0, 0x54, 0x03, 0x70, 0x15, 0x7f, 0x20, 0x12,
0x19, 0x97, 0x20, 0x1a, 0x07, 0x90, 0x02, 0x08, 0xe0, 0x54, 0xfb, 0xf0, 0x75, 0x51, 0x02, 0x02,
0x1b, 0x12, 0xe5, 0x50, 0x70, 0x03, 0x02, 0x1b, 0x0d, 0x20, 0x1a, 0x15, 0x90, 0x02, 0x08, 0xe0,
0x30, 0xe3, 0x03, 0x02, 0x1b, 0x09, 0x90, 0x04, 0x37, 0xe0, 0x64, 0x22, 0x60, 0x03, 0x02, 0x1b,
0x09, 0x90, 0x12, 0x04, 0x74, 0x0a, 0xf0, 0xe5, 0x58, 0xb4, 0x72, 0x15, 0xe5, 0x59, 0xb4, 0x35,
0x10, 0xe4, 0x90, 0x05, 0x00, 0xf0, 0xa3, 0x74, 0x08, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03,
0xf0, 0x7f, 0x01, 0x12, 0x03, 0x30, 0x90, 0x13, 0x28, 0xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54,
0xf0, 0xf0, 0xe5, 0x59, 0xb4, 0x35, 0x14, 0xe5, 0x3c, 0xf4, 0x60, 0x06, 0xa3, 0xe0, 0x54, 0xf3,
0x80, 0x14, 0x90, 0x13, 0x2a, 0xe0, 0x54, 0xfb, 0xf0, 0x80, 0x14, 0xe5, 0x3c, 0xf4, 0x90, 0x13,
0x2a, 0x60, 0x08, 0xe0, 0x54, 0xf2, 0x45, 0x3c, 0xf0, 0x80, 0x04, 0xe0, 0x54, 0xfa, 0xf0, 0x20,
0x1a, 0x07, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x10, 0xf0, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x09,
0xe5, 0x30, 0x70, 0x05, 0x75, 0x8c, 0x40, 0x80, 0x03, 0x75, 0x8c, 0x80, 0x90, 0x04, 0x01, 0xe0,
0x54, 0xfd, 0xf0, 0x20, 0x1a, 0x07, 0x90, 0x12, 0x04, 0xe0, 0x44, 0x04, 0xf0, 0xe5, 0x59, 0xb4,
0x28, 0x06, 0x90, 0x01, 0x0d, 0xe0, 0xf5, 0x31, 0xe5, 0x34, 0xc3, 0x94, 0x02, 0x40, 0x14, 0x90,
0x01, 0x0d, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x59, 0x64, 0x35, 0x60, 0x07, 0x90, 0x12, 0x04, 0xe0,
0x54, 0xfd, 0xf0, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x14, 0x20, 0x02, 0x11, 0x20, 0x03, 0x0e,
0x90, 0x01, 0x0d, 0xe0, 0x54, 0xfb, 0xf0, 0x90, 0x01, 0x0c, 0xe0, 0x54, 0xfd, 0xf0, 0x75, 0x37,
0x01, 0x75, 0x55, 0x02, 0xe4, 0xf5, 0x51, 0x80, 0x09, 0xe5, 0x50, 0x70, 0x05, 0x75, 0x37, 0x03,
0xf5, 0x51, 0xe5, 0x37, 0x60, 0x18, 0xc2, 0x01, 0xe4, 0xf5, 0x51, 0xc2, 0x59, 0x20, 0x1a, 0x0e,
0xad, 0x37, 0xaf, 0x40, 0x12, 0x1c, 0x1b, 0xe5, 0x37, 0xb4, 0x03, 0x02, 0xd2, 0x03, 0xd2, 0xaf,
0x22, 0xc2, 0xaf, 0x30, 0x01, 0x0e, 0xe4, 0xf5, 0x51, 0xc2, 0x59, 0xc2, 0x01, 0x7d, 0x02, 0xaf,
0x40, 0x12, 0x1c, 0x1b, 0xe5, 0x52, 0x14, 0x60, 0x5c, 0x14, 0x60, 0x3a, 0x24, 0x02, 0x60, 0x03,
0x02, 0x1c, 0x18, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x0c, 0x90, 0x01, 0x0c, 0xe0, 0x44, 0x02,
0xf0, 0xa3, 0xe0, 0x44, 0x04, 0xf0, 0xe5, 0x34, 0xc3, 0x94, 0x02, 0x40, 0x13, 0x90, 0x12, 0x04,
0xe0, 0x44, 0x02, 0xf0, 0x7f, 0x32, 0x12, 0x03, 0x30, 0x90, 0x01, 0x0d, 0xe0, 0x54, 0xfe, 0xf0,
0x75, 0x52, 0x02, 0x75, 0x55, 0x03, 0xe5, 0x59, 0xb4, 0x28, 0x06, 0x90, 0x01, 0x0d, 0xe5, 0x31,
0xf0, 0x90, 0x12, 0x04, 0xe0, 0x54, 0xfb, 0xf0, 0x7f, 0x20, 0x12, 0x19, 0x9c, 0x75, 0x52, 0x01,
0x75, 0x55, 0x03, 0x80, 0x73, 0xe5, 0x54, 0x70, 0x6f, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x0e, 0xf0,
0x20, 0x1a, 0x04, 0xe0, 0x54, 0xef, 0xf0, 0xe4, 0xf5, 0x8c, 0x90, 0x13, 0x28, 0xe0, 0x44, 0x0f,
0xf0, 0xa3, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x05, 0xf0, 0x90, 0x12, 0x04, 0x74, 0x03,
0xf0, 0xe5, 0x58, 0xb4, 0x72, 0x16, 0xe5, 0x59, 0xb4, 0x35, 0x11, 0x90, 0x05, 0x00, 0x74, 0xe2,
0xf0, 0xa3, 0x74, 0x08, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, 0xf0, 0x7f, 0x01, 0x12, 0x03,
0x30, 0x20, 0x1a, 0x07, 0x90, 0x02, 0x08, 0xe0, 0x44, 0x05, 0xf0, 0x90, 0x10, 0x04, 0xe0, 0x44,
0x0c, 0xf0, 0xe4, 0xf5, 0x52, 0xf5, 0x55, 0x30, 0x02, 0x09, 0xc2, 0x02, 0x7d, 0x01, 0xaf, 0x41,
0x12, 0x1c, 0x1b, 0x30, 0x03, 0x02, 0xc2, 0x03, 0xd2, 0xaf, 0x22, 0xef, 0xf4, 0x60, 0x2d, 0xe4,
0xfe, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xe0, 0xb4, 0xff, 0x19, 0x74,
0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xef, 0xf0, 0x74, 0x1c, 0x2e, 0xf5, 0x82,
0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe, 0x04, 0xd5, 0x22, 0x22, 0x22, 0x30,
0x1a, 0x77, 0x90, 0x04, 0x37, 0xe0, 0x20, 0xe5, 0x6c, 0x90, 0x04, 0x28, 0xe0, 0xf5, 0x38, 0xa3,
0xe0, 0xf5, 0x37, 0xf5, 0x39, 0xe4, 0xf5, 0x25, 0xe5, 0x39, 0x75, 0xf0, 0x80, 0xa4, 0x24, 0x00,
0xff, 0xe5, 0xf0, 0x34, 0x80, 0xfe, 0xe5, 0x37, 0x65, 0x39, 0x70, 0x05, 0xfc, 0x7d, 0x28, 0x80,
0x04, 0x7c, 0x00, 0x7d, 0x00, 0xef, 0x2d, 0xff, 0xee, 0x3c, 0xfe, 0x12, 0x1c, 0xca, 0x50, 0x07,
0x90, 0x01, 0x14, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x39, 0x65, 0x38, 0x60, 0x10, 0xe4, 0x25, 0x39,
0xff, 0xe4, 0x34, 0x80, 0x8f, 0x82, 0xf5, 0x83, 0xe0, 0xf5, 0x39, 0x80, 0xbb, 0x90, 0x04, 0x10,
0x74, 0x01, 0xf0, 0x90, 0x04, 0x28, 0xe5, 0x38, 0xf0, 0xa3, 0xe5, 0x37, 0xf0, 0x90, 0x04, 0x11,
0x74, 0x01, 0xf0, 0x80, 0x8d, 0xc2, 0x06, 0xd2, 0x1b, 0x22, 0xe5, 0x25, 0xc3, 0x94, 0x06, 0x50,
0x19, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xb4, 0xff, 0x07, 0x05, 0x25, 0xe4, 0xf5, 0x24, 0x80, 0x2e,
0xe4, 0xf5, 0x25, 0x8f, 0x82, 0x8e, 0x83, 0xf0, 0x80, 0x24, 0xe5, 0x24, 0x75, 0xf0, 0x06, 0x84,
0x74, 0x08, 0x25, 0xf0, 0xf5, 0x82, 0xe4, 0x34, 0x10, 0xf5, 0x83, 0xe0, 0xfd, 0x8f, 0x82, 0x8e,
0x83, 0xe0, 0x6d, 0x70, 0x06, 0x05, 0x25, 0x05, 0x24, 0x80, 0x03, 0xe4, 0xf5, 0x25, 0x0f, 0xbf,
0x00, 0x01, 0x0e, 0xef, 0x54, 0x7f, 0x60, 0x07, 0xe5, 0x25, 0xc3, 0x94, 0x2a, 0x40, 0xab, 0xe5,
0x25, 0xb4, 0x2a, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xe3, 0x34, } ;

View file

@ -0,0 +1,152 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
igmp_snoop.h
Abstract:
Miniport generic portion header file
Revision History:
Who When What
-------- ---------- ----------------------------------------------
*/
#ifndef __RTMP_IGMP_SNOOP_H__
#define __RTMP_IGMP_SNOOP_H__
#include "link_list.h"
#define IGMP_PROTOCOL_DESCRIPTOR 0x02
#define IGMP_V1_MEMBERSHIP_REPORT 0x12
#define IGMP_V2_MEMBERSHIP_REPORT 0x16
#define IGMP_LEAVE_GROUP 0x17
#define IGMP_V3_MEMBERSHIP_REPORT 0x22
#define MLD_V1_LISTENER_REPORT 131
#define MLD_V1_LISTENER_DONE 132
#define MLD_V2_LISTERNER_REPORT 143
#define IGMPMAC_TB_ENTRY_AGEOUT_TIME 120 * OS_HZ
#define MULTICAST_ADDR_HASH_INDEX(Addr) (MAC_ADDR_HASH(Addr) % (MAX_LEN_OF_MULTICAST_FILTER_HASH_TABLE))
#define IS_MULTICAST_MAC_ADDR(Addr) ((((Addr[0]) & 0x01) == 0x01) && ((Addr[0]) != 0xff))
#define IS_BROADCAST_MAC_ADDR(Addr) ((((Addr[0]) & 0xff) == 0xff))
VOID MulticastFilterTableInit(
IN PMULTICAST_FILTER_TABLE *ppMulticastFilterTable);
VOID MultiCastFilterTableReset(
IN PMULTICAST_FILTER_TABLE *ppMulticastFilterTable);
BOOLEAN MulticastFilterTableInsertEntry(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pGrpId,
IN PUCHAR pMemberAddr,
IN PNET_DEV dev,
IN MulticastFilterEntryType type);
BOOLEAN MulticastFilterTableDeleteEntry(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pGrpId,
IN PUCHAR pMemberAddr,
IN PNET_DEV dev);
PMULTICAST_FILTER_TABLE_ENTRY MulticastFilterTableLookup(
IN PMULTICAST_FILTER_TABLE pMulticastFilterTable,
IN PUCHAR pAddr,
IN PNET_DEV dev);
BOOLEAN isIgmpPkt(
IN PUCHAR pDstMacAddr,
IN PUCHAR pIpHeader);
VOID IGMPSnooping(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pDstMacAddr,
IN PUCHAR pSrcMacAddr,
IN PUCHAR pIpHeader,
IN PNET_DEV pDev);
BOOLEAN isMldPkt(
IN PUCHAR pDstMacAddr,
IN PUCHAR pIpHeader,
OUT UINT8 *pProtoType,
OUT PUCHAR *pMldHeader);
VOID MLDSnooping(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pDstMacAddr,
IN PUCHAR pSrcMacAddr,
IN PUCHAR pIpHeader,
IN PNET_DEV pDev);
UCHAR IgmpMemberCnt(
IN PLIST_HEADER pList);
VOID IgmpGroupDelMembers(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pMemberAddr,
IN PNET_DEV pDev);
INT Set_IgmpSn_Enable_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
INT Set_IgmpSn_AddEntry_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
INT Set_IgmpSn_DelEntry_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
INT Set_IgmpSn_TabDisplay_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
void rtmp_read_igmp_snoop_from_file(
IN PRTMP_ADAPTER pAd,
PSTRING tmpbuf,
PSTRING buffer);
NDIS_STATUS IgmpPktInfoQuery(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pSrcBufVA,
IN PNDIS_PACKET pPacket,
IN UCHAR apidx,
OUT BOOLEAN *pInIgmpGroup,
OUT PMULTICAST_FILTER_TABLE_ENTRY *ppGroupEntry);
NDIS_STATUS IgmpPktClone(
IN PRTMP_ADAPTER pAd,
IN PNDIS_PACKET pPacket,
IN UCHAR QueIdx,
IN PMULTICAST_FILTER_TABLE_ENTRY pGroupEntry);
#endif /* __RTMP_IGMP_SNOOP_H__ */

View file

@ -0,0 +1,215 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
ipv6.h
Abstract:
Miniport generic portion header file
Revision History:
Who When What
-------- ---------- ----------------------------------------------
*/
#ifndef __IPV6_HDR_H_
#define __IPV6_HDR_H_
#define IPV6_ADDR_LEN 16
#define IPV6_HDR_LEN 40
// IPv6 address definition
#define IPV6_LINK_LOCAL_ADDR_PREFIX 0xFE8
#define IPV6_SITE_LOCAL_ADDR_PREFIX 0xFEC
#define IPV6_LOCAL_ADDR_PREFIX 0xFE8
#define IPV6_MULTICAST_ADDR_PREFIX 0xFF
#define IPV6_LOOPBACK_ADDR 0x1
#define IPV6_UNSPECIFIED_ADDR 0x0
// defined as sequence in IPv6 header
#define IPV6_NEXT_HEADER_HOP_BY_HOP 0x00 // 0
#define IPV6_NEXT_HEADER_DESTINATION 0x3c // 60
#define IPV6_NEXT_HEADER_ROUTING 0x2b // 43
#define IPV6_NEXT_HEADER_FRAGMENT 0x2c // 44
#define IPV6_NEXT_HEADER_AUTHENTICATION 0x33 // 51
#define IPV6_NEXT_HEADER_ENCAPSULATION 0x32 // 50, RFC-2406
#define IPV6_NEXT_HEADER_NONE 0x3b // 59
#define IPV6_NEXT_HEADER_TCP 0x06
#define IPV6_NEXT_HEADER_UDP 0x11
#define IPV6_NEXT_HEADER_ICMPV6 0x3a
// ICMPv6 msg type definition
#define ICMPV6_MSG_TYPE_ROUTER_SOLICITATION 0x85 // 133
#define ROUTER_SOLICITATION_FIXED_LEN 8
#define ICMPV6_MSG_TYPE_ROUTER_ADVERTISEMENT 0x86 // 134
#define ROUTER_ADVERTISEMENT_FIXED_LEN 16
#define ICMPV6_MSG_TYPE_NEIGHBOR_SOLICITATION 0x87 // 135
#define NEIGHBOR_SOLICITATION_FIXED_LEN 24
#define ICMPV6_MSG_TYPE_NEIGHBOR_ADVERTISEMENT 0x88 // 136
#define NEIGHBOR_ADVERTISEMENT_FIXED_LEN 24
#define ICMPV6_MSG_TYPE_REDIRECT 0x89 // 137
#define REDIRECT_FIXED_LEN 40
/* IPv6 Address related structures */
typedef struct rt_ipv6_addr_
{
union
{
UCHAR ipv6Addr8[16];
USHORT ipv6Addr16[8];
UINT32 ipv6Addr32[4];
}addr;
#define ipv6_addr addr.ipv6Addr8
#define ipv6_addr16 addr.ipv6Addr16
#define ipv6_addr32 addr.ipv6Addr32
}RT_IPV6_ADDR, *PRT_IPV6_ADDR;
#define PRINT_IPV6_ADDR(ipv6Addr) \
OS_NTOHS((ipv6Addr).ipv6_addr16[0]), \
OS_NTOHS((ipv6Addr).ipv6_addr16[1]), \
OS_NTOHS((ipv6Addr).ipv6_addr16[2]), \
OS_NTOHS((ipv6Addr).ipv6_addr16[3]), \
OS_NTOHS((ipv6Addr).ipv6_addr16[4]), \
OS_NTOHS((ipv6Addr).ipv6_addr16[5]), \
OS_NTOHS((ipv6Addr).ipv6_addr16[6]), \
OS_NTOHS((ipv6Addr).ipv6_addr16[7])
/*IPv6 Header related structures */
typedef struct PACKED _rt_ipv6_hdr_
{
UINT32 ver:4,
trafficClass:8,
flowLabel:20;
USHORT payload_len;
UCHAR nextHdr;
UCHAR hopLimit;
RT_IPV6_ADDR srcAddr;
RT_IPV6_ADDR dstAddr;
}RT_IPV6_HDR, *PRT_IPV6_HDR;
typedef struct PACKED _rt_ipv6_ext_hdr_
{
UCHAR nextProto; // Indicate the protocol type of next extension header.
UCHAR extHdrLen; // optional field for msg length of this extension header which didn't include the first "nextProto" field.
UCHAR octets[1]; // hook to extend header message body.
}RT_IPV6_EXT_HDR, *PRT_IPV6_EXT_HDR;
/* ICMPv6 related structures */
typedef struct PACKED _rt_ipv6_icmpv6_hdr_
{
UCHAR type;
UCHAR code;
USHORT chksum;
UCHAR octets[1]; //hook to extend header message body.
}RT_ICMPV6_HDR, *PRT_ICMPV6_HDR;
typedef struct PACKED _rt_icmp6_option_hdr_
{
UCHAR type;
UCHAR len;
UCHAR octet[1];
}RT_ICMPV6_OPTION_HDR, *PRT_ICMPV6_OPTION_HDR;
typedef enum{
// Defined ICMPv6 Option Types.
TYPE_SRC_LL_ADDR = 1,
TYPE_TGT_LL_ADDR = 2,
TYPE_PREFIX_INFO = 3,
TYPE_REDIRECTED_HDR = 4,
TYPE_MTU = 5,
}ICMPV6_OPTIONS_TYPE_DEF;
static inline BOOLEAN IPv6ExtHdrHandle(
RT_IPV6_EXT_HDR *pExtHdr,
UCHAR *pProto,
UINT32 *pOffset)
{
UCHAR nextProto = 0xff;
UINT32 extLen = 0;
BOOLEAN status = TRUE;
//printk("%s(): parsing the Extension Header with Protocol(0x%x):\n", __FUNCTION__, *pProto);
switch (*pProto)
{
case IPV6_NEXT_HEADER_HOP_BY_HOP:
// IPv6ExtHopByHopHandle();
nextProto = pExtHdr->nextProto;
extLen = (pExtHdr->extHdrLen + 1) * 8;
break;
case IPV6_NEXT_HEADER_DESTINATION:
// IPv6ExtDestHandle();
nextProto = pExtHdr->nextProto;
extLen = (pExtHdr->extHdrLen + 1) * 8;
break;
case IPV6_NEXT_HEADER_ROUTING:
// IPv6ExtRoutingHandle();
nextProto = pExtHdr->nextProto;
extLen = (pExtHdr->extHdrLen + 1) * 8;
break;
case IPV6_NEXT_HEADER_FRAGMENT:
// IPv6ExtFragmentHandle();
nextProto = pExtHdr->nextProto;
extLen = 8; // The Fragment header length is fixed to 8 bytes.
break;
case IPV6_NEXT_HEADER_AUTHENTICATION:
// IPV6_NEXT_HEADER_ENCAPSULATION:
/*
TODO: Not support. For encryption issue.
*/
nextProto = 0xFF;
status = FALSE;
break;
default:
nextProto = 0xFF;
status = FALSE;
break;
}
*pProto = nextProto;
*pOffset += extLen;
//printk("%s(): nextProto = 0x%x!, offset=0x%x!\n", __FUNCTION__, nextProto, offset);
return status;
}
#endif // __IPV6_HDR_H_ //

View file

@ -0,0 +1,133 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
*/
#ifndef __LINK_LIST_H__
#define __LINK_LIST_H__
typedef struct _LIST_ENTRY
{
struct _LIST_ENTRY *pNext;
} LIST_ENTRY, *PLIST_ENTRY;
typedef struct _LIST_HEADR
{
PLIST_ENTRY pHead;
PLIST_ENTRY pTail;
UCHAR size;
} LIST_HEADER, *PLIST_HEADER;
static inline VOID initList(
IN PLIST_HEADER pList)
{
pList->pHead = pList->pTail = NULL;
pList->size = 0;
return;
}
static inline VOID insertTailList(
IN PLIST_HEADER pList,
IN PLIST_ENTRY pEntry)
{
pEntry->pNext = NULL;
if (pList->pTail)
pList->pTail->pNext = pEntry;
else
pList->pHead = pEntry;
pList->pTail = pEntry;
pList->size++;
return;
}
static inline PLIST_ENTRY removeHeadList(
IN PLIST_HEADER pList)
{
PLIST_ENTRY pNext;
PLIST_ENTRY pEntry;
pEntry = pList->pHead;
if (pList->pHead != NULL)
{
pNext = pList->pHead->pNext;
pList->pHead = pNext;
if (pNext == NULL)
pList->pTail = NULL;
pList->size--;
}
return pEntry;
}
static inline int getListSize(
IN PLIST_HEADER pList)
{
return pList->size;
}
static inline PLIST_ENTRY delEntryList(
IN PLIST_HEADER pList,
IN PLIST_ENTRY pEntry)
{
PLIST_ENTRY pCurEntry;
PLIST_ENTRY pPrvEntry;
if(pList->pHead == NULL)
return NULL;
if(pEntry == pList->pHead)
{
pCurEntry = pList->pHead;
pList->pHead = pCurEntry->pNext;
if(pList->pHead == NULL)
pList->pTail = NULL;
pList->size--;
return pCurEntry;
}
pPrvEntry = pList->pHead;
pCurEntry = pPrvEntry->pNext;
while(pCurEntry != NULL)
{
if (pEntry == pCurEntry)
{
pPrvEntry->pNext = pCurEntry->pNext;
if(pEntry == pList->pTail)
pList->pTail = pPrvEntry;
pList->size--;
break;
}
pPrvEntry = pCurEntry;
pCurEntry = pPrvEntry->pNext;
}
return pCurEntry;
}
#endif // ___LINK_LIST_H__ //

View file

@ -0,0 +1,454 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
mac_pci.h
Abstract:
Revision History:
Who When What
--------- ---------- ----------------------------------------------
*/
#ifndef __MAC_PCI_H__
#define __MAC_PCI_H__
#include "rtmp_type.h"
#include "rtmp_mac.h"
#include "rtmp_phy.h"
#include "rtmp_iface.h"
#include "rtmp_dot11.h"
//
// Device ID & Vendor ID related definitions,
// NOTE: you should not add the new VendorID/DeviceID here unless you not sure it belongs to what chip.
//
#define NIC_PCI_VENDOR_ID 0x1814
#define PCIBUS_INTEL_VENDOR 0x8086
#if !defined(PCI_CAP_ID_EXP)
#define PCI_CAP_ID_EXP 0x10
#endif
#if !defined(PCI_EXP_LNKCTL)
#define PCI_EXP_LNKCTL 0x10
#endif
#if !defined(PCI_CLASS_BRIDGE_PCI)
#define PCI_CLASS_BRIDGE_PCI 0x0604
#endif
#define TXINFO_SIZE 0
#define RTMP_PKT_TAIL_PADDING 0
#define fRTMP_ADAPTER_NEED_STOP_TX 0
#define AUX_CTRL 0x10c
//
// TX descriptor format, Tx ring, Mgmt Ring
//
#ifdef RT_BIG_ENDIAN
typedef struct PACKED _TXD_STRUC {
// Word 0
UINT32 SDPtr0;
// Word 1
UINT32 DMADONE:1;
UINT32 LastSec0:1;
UINT32 SDLen0:14;
UINT32 Burst:1;
UINT32 LastSec1:1;
UINT32 SDLen1:14;
// Word 2
UINT32 SDPtr1;
// Word 3
UINT32 ICO:1;
UINT32 UCO:1;
UINT32 TCO:1;
UINT32 rsv:2;
UINT32 QSEL:2; // select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA
UINT32 WIV:1; // Wireless Info Valid. 1 if Driver already fill WI, o if DMA needs to copy WI to correctposition
UINT32 rsv2:24;
} TXD_STRUC, *PTXD_STRUC;
#else
typedef struct PACKED _TXD_STRUC {
// Word 0
UINT32 SDPtr0;
// Word 1
UINT32 SDLen1:14;
UINT32 LastSec1:1;
UINT32 Burst:1;
UINT32 SDLen0:14;
UINT32 LastSec0:1;
UINT32 DMADONE:1;
//Word2
UINT32 SDPtr1;
//Word3
UINT32 rsv2:24;
UINT32 WIV:1; // Wireless Info Valid. 1 if Driver already fill WI, o if DMA needs to copy WI to correctposition
UINT32 QSEL:2; // select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA
UINT32 rsv:2;
UINT32 TCO:1; //
UINT32 UCO:1; //
UINT32 ICO:1; //
} TXD_STRUC, *PTXD_STRUC;
#endif
//
// Rx descriptor format, Rx Ring
//
#ifdef RT_BIG_ENDIAN
typedef struct PACKED _RXD_STRUC{
// Word 0
UINT32 SDP0;
// Word 1
UINT32 DDONE:1;
UINT32 LS0:1;
UINT32 SDL0:14;
UINT32 Rsv:2;
UINT32 SDL1:14;
// Word 2
UINT32 SDP1;
// Word 3
UINT32 Rsv1:13;
UINT32 PlcpRssil:1;// To be moved
UINT32 PlcpSignal:1; // To be moved
UINT32 Decrypted:1; // this frame is being decrypted.
UINT32 AMPDU:1;
UINT32 L2PAD:1;
UINT32 RSSI:1;
UINT32 HTC:1;
UINT32 AMSDU:1; // rx with 802.3 header, not 802.11 header. obsolete.
UINT32 CipherErr:2; // 0: decryption okay, 1:ICV error, 2:MIC error, 3:KEY not valid
UINT32 Crc:1; // 1: CRC error
UINT32 MyBss:1; // 1: this frame belongs to the same BSSID
UINT32 Bcast:1; // 1: this is a broadcast frame
UINT32 Mcast:1; // 1: this is a multicast frame
UINT32 U2M:1; // 1: this RX frame is unicast to me
UINT32 FRAG:1;
UINT32 NULLDATA:1;
UINT32 DATA:1;
UINT32 BA:1;
} RXD_STRUC, *PRXD_STRUC, RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC;
#else
typedef struct PACKED _RXD_STRUC{
// Word 0
UINT32 SDP0;
// Word 1
UINT32 SDL1:14;
UINT32 Rsv:2;
UINT32 SDL0:14;
UINT32 LS0:1;
UINT32 DDONE:1;
// Word 2
UINT32 SDP1;
// Word 3
UINT32 BA:1;
UINT32 DATA:1;
UINT32 NULLDATA:1;
UINT32 FRAG:1;
UINT32 U2M:1; // 1: this RX frame is unicast to me
UINT32 Mcast:1; // 1: this is a multicast frame
UINT32 Bcast:1; // 1: this is a broadcast frame
UINT32 MyBss:1; // 1: this frame belongs to the same BSSID
UINT32 Crc:1; // 1: CRC error
UINT32 CipherErr:2; // 0: decryption okay, 1:ICV error, 2:MIC error, 3:KEY not valid
UINT32 AMSDU:1; // rx with 802.3 header, not 802.11 header.
UINT32 HTC:1;
UINT32 RSSI:1;
UINT32 L2PAD:1;
UINT32 AMPDU:1;
UINT32 Decrypted:1; // this frame is being decrypted.
UINT32 PlcpSignal:1; // To be moved
UINT32 PlcpRssil:1;// To be moved
UINT32 Rsv1:13;
} RXD_STRUC, *PRXD_STRUC, RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC;
#endif
#ifdef BIG_ENDIAN
typedef union _TX_ATTENUATION_CTRL_STRUC
{
struct
{
ULONG Reserve1:20;
ULONG PCIE_PHY_TX_ATTEN_EN:1;
ULONG PCIE_PHY_TX_ATTEN_VALUE:3;
ULONG Reserve2:7;
ULONG RF_ISOLATION_ENABLE:1;
} field;
ULONG word;
} TX_ATTENUATION_CTRL_STRUC, *PTX_ATTENUATION_CTRL_STRUC;
#else
typedef union _TX_ATTENUATION_CTRL_STRUC {
struct
{
ULONG RF_ISOLATION_ENABLE:1;
ULONG Reserve2:7;
ULONG PCIE_PHY_TX_ATTEN_VALUE:3;
ULONG PCIE_PHY_TX_ATTEN_EN:1;
ULONG Reserve1:20;
} field;
ULONG word;
} TX_ATTENUATION_CTRL_STRUC, *PTX_ATTENUATION_CTRL_STRUC;
#endif
/* ----------------- EEPROM Related MACRO ----------------- */
// 8051 firmware image for RT2860 - base address = 0x4000
#define FIRMWARE_IMAGE_BASE 0x2000
#define MAX_FIRMWARE_IMAGE_SIZE 0x2000 // 8kbyte
/* ----------------- Frimware Related MACRO ----------------- */
#define RTMP_WRITE_FIRMWARE(_pAd, _pFwImage, _FwLen) \
do{ \
ULONG _i, _firm; \
RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, 0x10000); \
\
for(_i=0; _i<_FwLen; _i+=4) \
{ \
_firm = _pFwImage[_i] + \
(_pFwImage[_i+3] << 24) + \
(_pFwImage[_i+2] << 16) + \
(_pFwImage[_i+1] << 8); \
RTMP_IO_WRITE32(_pAd, FIRMWARE_IMAGE_BASE + _i, _firm); \
} \
RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, 0x00000); \
RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, 0x00001); \
\
/* initialize BBP R/W access agent */ \
RTMP_IO_WRITE32(_pAd, H2M_BBP_AGENT, 0); \
RTMP_IO_WRITE32(_pAd, H2M_MAILBOX_CSR, 0); \
}while(0)
/* ----------------- TX Related MACRO ----------------- */
#define RTMP_START_DEQUEUE(pAd, QueIdx, irqFlags) do{}while(0)
#define RTMP_STOP_DEQUEUE(pAd, QueIdx, irqFlags) do{}while(0)
#define RTMP_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, freeNum, pPacket) \
((freeNum) >= (ULONG)(pTxBlk->TotalFragNum + RTMP_GET_PACKET_FRAGMENTS(pPacket) + 3)) /* rough estimate we will use 3 more descriptor. */
#define RTMP_RELEASE_DESC_RESOURCE(pAd, QueIdx) \
do{}while(0)
#define NEED_QUEUE_BACK_FOR_AGG(pAd, QueIdx, freeNum, _TxFrameType) \
(((freeNum != (TX_RING_SIZE-1)) && (pAd->TxSwQueue[QueIdx].Number == 0)) || (freeNum<3))
//(((freeNum) != (TX_RING_SIZE-1)) && (pAd->TxSwQueue[QueIdx].Number == 1 /*0*/))
#define HAL_KickOutMgmtTx(_pAd, _QueIdx, _pPacket, _pSrcBufVA, _SrcBufLen) \
RtmpPCIMgmtKickOut(_pAd, _QueIdx, _pPacket, _pSrcBufVA, _SrcBufLen)
#define HAL_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber) \
/* RtmpPCI_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)*/
#define HAL_WriteTxResource(pAd, pTxBlk,bIsLast, pFreeNumber) \
RtmpPCI_WriteSingleTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)
#define HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber) \
RtmpPCI_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber)
#define HAL_WriteMultiTxResource(pAd, pTxBlk,frameNum, pFreeNumber) \
RtmpPCI_WriteMultiTxResource(pAd, pTxBlk, frameNum, pFreeNumber)
#define HAL_FinalWriteTxResource(_pAd, _pTxBlk, _TotalMPDUSize, _FirstTxIdx) \
RtmpPCI_FinalWriteTxResource(_pAd, _pTxBlk, _TotalMPDUSize, _FirstTxIdx)
#define HAL_LastTxIdx(_pAd, _QueIdx,_LastTxIdx) \
/*RtmpPCIDataLastTxIdx(_pAd, _QueIdx,_LastTxIdx)*/
#define HAL_KickOutTx(_pAd, _pTxBlk, _QueIdx) \
RTMP_IO_WRITE32((_pAd), TX_CTX_IDX0+((_QueIdx)*0x10), (_pAd)->TxRing[(_QueIdx)].TxCpuIdx)
/* RtmpPCIDataKickOut(_pAd, _pTxBlk, _QueIdx)*/
#define HAL_KickOutNullFrameTx(_pAd, _QueIdx, _pNullFrame, _frameLen) \
MiniportMMRequest(_pAd, _QueIdx, _pNullFrame, _frameLen)
#define GET_TXRING_FREENO(_pAd, _QueIdx) \
(_pAd->TxRing[_QueIdx].TxSwFreeIdx > _pAd->TxRing[_QueIdx].TxCpuIdx) ? \
(_pAd->TxRing[_QueIdx].TxSwFreeIdx - _pAd->TxRing[_QueIdx].TxCpuIdx - 1) \
: \
(_pAd->TxRing[_QueIdx].TxSwFreeIdx + TX_RING_SIZE - _pAd->TxRing[_QueIdx].TxCpuIdx - 1);
#define GET_MGMTRING_FREENO(_pAd) \
(_pAd->MgmtRing.TxSwFreeIdx > _pAd->MgmtRing.TxCpuIdx) ? \
(_pAd->MgmtRing.TxSwFreeIdx - _pAd->MgmtRing.TxCpuIdx - 1) \
: \
(_pAd->MgmtRing.TxSwFreeIdx + MGMT_RING_SIZE - _pAd->MgmtRing.TxCpuIdx - 1);
/* ----------------- RX Related MACRO ----------------- */
/* ----------------- ASIC Related MACRO ----------------- */
// reset MAC of a station entry to 0x000000000000
#define RTMP_STA_ENTRY_MAC_RESET(pAd, Wcid) \
AsicDelWcidTab(pAd, Wcid);
// add this entry into ASIC RX WCID search table
#define RTMP_STA_ENTRY_ADD(pAd, pEntry) \
AsicUpdateRxWCIDTable(pAd, pEntry->Aid, pEntry->Addr);
// add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
// Set MAC register value according operation mode
#define RTMP_UPDATE_PROTECT(pAd) \
AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT), TRUE, 0);
// end johnli
// remove Pair-wise key material from ASIC
#define RTMP_STA_ENTRY_KEY_DEL(pAd, BssIdx, Wcid) \
AsicRemovePairwiseKeyEntry(pAd, BssIdx, (UCHAR)Wcid);
// add Client security information into ASIC WCID table and IVEIV table
#define RTMP_STA_SECURITY_INFO_ADD(pAd, apidx, KeyID, pEntry) \
RTMPAddWcidAttributeEntry(pAd, apidx, KeyID, \
pAd->SharedKey[apidx][KeyID].CipherAlg, pEntry);
#define RTMP_SECURITY_KEY_ADD(pAd, apidx, KeyID, pEntry) \
{ /* update pairwise key information to ASIC Shared Key Table */ \
AsicAddSharedKeyEntry(pAd, apidx, KeyID, \
pAd->SharedKey[apidx][KeyID].CipherAlg, \
pAd->SharedKey[apidx][KeyID].Key, \
pAd->SharedKey[apidx][KeyID].TxMic, \
pAd->SharedKey[apidx][KeyID].RxMic); \
/* update ASIC WCID attribute table and IVEIV table */ \
RTMPAddWcidAttributeEntry(pAd, apidx, KeyID, \
pAd->SharedKey[apidx][KeyID].CipherAlg, \
pEntry); }
// Insert the BA bitmap to ASIC for the Wcid entry
#define RTMP_ADD_BA_SESSION_TO_ASIC(_pAd, _Aid, _TID) \
do{ \
UINT32 _Value = 0, _Offset; \
_Offset = MAC_WCID_BASE + (_Aid) * HW_WCID_ENTRY_SIZE + 4; \
RTMP_IO_READ32((_pAd), _Offset, &_Value);\
_Value |= (0x10000<<(_TID)); \
RTMP_IO_WRITE32((_pAd), _Offset, _Value);\
}while(0)
// Remove the BA bitmap from ASIC for the Wcid entry
// bitmap field starts at 0x10000 in ASIC WCID table
#define RTMP_DEL_BA_SESSION_FROM_ASIC(_pAd, _Wcid, _TID) \
do{ \
UINT32 _Value = 0, _Offset; \
_Offset = MAC_WCID_BASE + (_Wcid) * HW_WCID_ENTRY_SIZE + 4; \
RTMP_IO_READ32((_pAd), _Offset, &_Value); \
_Value &= (~(0x10000 << (_TID))); \
RTMP_IO_WRITE32((_pAd), _Offset, _Value); \
}while(0)
/* ----------------- Interface Related MACRO ----------------- */
//
// Enable & Disable NIC interrupt via writing interrupt mask register
// Since it use ADAPTER structure, it have to be put after structure definition.
//
#define RTMP_ASIC_INTERRUPT_DISABLE(_pAd) \
do{ \
RTMP_IO_WRITE32((_pAd), INT_MASK_CSR, 0x0); /* 0: disable */ \
RTMP_CLEAR_FLAG((_pAd), fRTMP_ADAPTER_INTERRUPT_ACTIVE); \
}while(0)
#define RTMP_ASIC_INTERRUPT_ENABLE(_pAd)\
do{ \
RTMP_IO_WRITE32((_pAd), INT_MASK_CSR, (_pAd)->int_enable_reg /*DELAYINTMASK*/); /* 1:enable */ \
RTMP_SET_FLAG((_pAd), fRTMP_ADAPTER_INTERRUPT_ACTIVE); \
}while(0)
#define RTMP_IRQ_INIT(pAd) \
{ pAd->int_enable_reg = ((DELAYINTMASK) | \
(RxINT|TxDataInt|TxMgmtInt)) & ~(0x03); \
pAd->int_disable_mask = 0; \
pAd->int_pending = 0; }
#define RTMP_IRQ_ENABLE(pAd) \
{ /* clear garbage ints */ \
RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, 0xffffffff);\
RTMP_ASIC_INTERRUPT_ENABLE(pAd); }
/* ----------------- MLME Related MACRO ----------------- */
#define RTMP_MLME_HANDLER(pAd) MlmeHandler(pAd)
#define RTMP_MLME_PRE_SANITY_CHECK(pAd)
#define RTMP_MLME_STA_QUICK_RSP_WAKE_UP(pAd) \
RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100);
#define RTMP_MLME_RESET_STATE_MACHINE(pAd) \
MlmeRestartStateMachine(pAd)
#define RTMP_HANDLE_COUNTER_MEASURE(_pAd, _pEntry)\
HandleCounterMeasure(_pAd, _pEntry)
/* ----------------- Power Save Related MACRO ----------------- */
#define RTMP_PS_POLL_ENQUEUE(pAd) EnqueuePsPoll(pAd)
// For RTMPPCIePowerLinkCtrlRestore () function
#define RESTORE_HALT 1
#define RESTORE_WAKEUP 2
#define RESTORE_CLOSE 3
#define PowerSafeCID 1
#define PowerRadioOffCID 2
#define PowerWakeCID 3
#define CID0MASK 0x000000ff
#define CID1MASK 0x0000ff00
#define CID2MASK 0x00ff0000
#define CID3MASK 0xff000000
#ifdef CONFIG_STA_SUPPORT
#define RTMP_STA_FORCE_WAKEUP(pAd, bFromTx) \
RT28xxPciStaAsicForceWakeup(pAd, bFromTx);
#define RTMP_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp) \
RT28xxPciStaAsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
#define RTMP_SET_PSM_BIT(_pAd, _val) \
MlmeSetPsmBit(_pAd, _val);
#endif // CONFIG_STA_SUPPORT //
#define RTMP_MLME_RADIO_ON(pAd) \
RT28xxPciMlmeRadioOn(pAd);
#define RTMP_MLME_RADIO_OFF(pAd) \
RT28xxPciMlmeRadioOFF(pAd);
#endif //__MAC_PCI_H__ //

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,83 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
mlme_ex.h
Abstract:
Miniport generic portion header file
Revision History:
Who When What
-------- ---------- ----------------------------------------------
Fonchi 2007-06-25 Extend original mlme APIs to support multi-entries
*/
#ifndef __MLME_EX_H__
#define __MLME_EX_H__
#include "mlme_ex_def.h"
VOID StateMachineInitEx(
IN STATE_MACHINE_EX *S,
IN STATE_MACHINE_FUNC_EX Trans[],
IN ULONG StNr,
IN ULONG MsgNr,
IN STATE_MACHINE_FUNC_EX DefFunc,
IN ULONG InitState,
IN ULONG Base);
VOID StateMachineSetActionEx(
IN STATE_MACHINE_EX *S,
IN ULONG St,
IN ULONG Msg,
IN STATE_MACHINE_FUNC_EX Func);
BOOLEAN isValidApCliIf(
SHORT Idx);
VOID StateMachinePerformActionEx(
IN PRTMP_ADAPTER pAd,
IN STATE_MACHINE_EX *S,
IN MLME_QUEUE_ELEM *Elem,
USHORT Idx,
PULONG pCurrState);
BOOLEAN MlmeEnqueueEx(
IN PRTMP_ADAPTER pAd,
IN ULONG Machine,
IN ULONG MsgType,
IN ULONG MsgLen,
IN VOID *Msg,
IN USHORT Idx);
VOID DropEx(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem,
PULONG pCurrState,
USHORT Idx);
#endif /* __MLME_EX_H__ */

View file

@ -0,0 +1,53 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
mlme_ex_def.h
Abstract:
Miniport generic portion header file
Revision History:
Who When What
-------- ---------- ----------------------------------------------
Fonchi 2007-06-25 Extend original mlme APIs to support multi-entries
*/
#ifndef __MLME_EX_DEF_H__
#define __MLME_EX_DEF_H__
typedef VOID (*STATE_MACHINE_FUNC_EX)(VOID *Adaptor, MLME_QUEUE_ELEM *Elem, PULONG pCurrState, USHORT Idx);
typedef struct _STA_STATE_MACHINE_EX
{
ULONG Base;
ULONG NrState;
ULONG NrMsg;
ULONG CurrState;
STATE_MACHINE_FUNC_EX *TransFunc;
} STATE_MACHINE_EX, *PSTA_STATE_MACHINE_EX;
#endif // __MLME_EX_DEF_H__ //

View file

@ -0,0 +1,56 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
*/
#ifndef __NET_IF_BLOCK_H__
#define __NET_IF_BLOCK_H__
#include "link_list.h"
#include "rtmp.h"
#define FREE_NETIF_POOL_SIZE 32
typedef struct _NETIF_ENTRY
{
struct _NETIF_ENTRY *pNext;
PNET_DEV pNetDev;
} NETIF_ENTRY, *PNETIF_ENTRY;
void initblockQueueTab(
IN PRTMP_ADAPTER pAd);
BOOLEAN blockNetIf(
IN PBLOCK_QUEUE_ENTRY pBlockQueueEntry,
IN PNET_DEV pNetDev);
VOID releaseNetIf(
IN PBLOCK_QUEUE_ENTRY pBlockQueueEntry);
VOID StopNetIfQueue(
IN PRTMP_ADAPTER pAd,
IN UCHAR QueIdx,
IN PNDIS_PACKET pPacket);
#endif // __NET_IF_BLOCK_H__

1144
drivers/staging/rt3090/oid.h Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,77 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
rt3090.h
Abstract:
Revision History:
Who When What
--------- ---------- ----------------------------------------------
*/
#ifndef __RT3090_H__
#define __RT3090_H__
#ifdef RT3090
#ifndef RTMP_PCI_SUPPORT
#error "For RT3090, you should define the compile flag -DRTMP_PCI_SUPPORT"
#endif
#ifndef RTMP_MAC_PCI
#error "For RT3090, you should define the compile flag -DRTMP_MAC_PCI"
#endif
#ifndef RTMP_RF_RW_SUPPORT
#error "For RT3090, you should define the compile flag -DRTMP_RF_RW_SUPPORT"
#endif
#ifndef RT30xx
#error "For RT3090, you should define the compile flag -DRT30xx"
#endif
#ifdef CARRIER_DETECTION_SUPPORT
#define TONE_RADAR_DETECT_SUPPORT
#define CARRIER_SENSE_NEW_ALGO
#endif // CARRIER_DETECTION_SUPPORT //
#define PCIE_PS_SUPPORT
#include "mac_pci.h"
#include "rt30xx.h"
//
// Device ID & Vendor ID, these values should match EEPROM value
//
#define NIC3090_PCIe_DEVICE_ID 0x3090 // 1T/1R miniCard
#define NIC3091_PCIe_DEVICE_ID 0x3091 // 1T/2R miniCard
#define NIC3092_PCIe_DEVICE_ID 0x3092 // 2T/2R miniCard
#endif // RT3090 //
#endif //__RT3090_H__ //

View file

@ -0,0 +1,48 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
rt30xx.h
Abstract:
Revision History:
Who When What
--------- ---------- ----------------------------------------------
*/
#ifndef __RT30XX_H__
#define __RT30XX_H__
#ifdef RT30xx
extern REG_PAIR RT30xx_RFRegTable[];
extern UCHAR NUM_RF_REG_PARMS;
#endif // RT30xx //
#endif //__RT30XX_H__ //

View file

@ -0,0 +1,64 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
rt3370.h
Abstract:
Revision History:
Who When What
--------- ---------- ----------------------------------------------
*/
#ifndef __RT3370_H__
#define __RT3370_H__
#ifdef RT3370
#error "For RT3070, you should define the compile flag -DRTMP_USB_SUPPORT"
#error "For RT3070, you should define the compile flag -DRTMP_MAC_USB"
#ifndef RTMP_RF_RW_SUPPORT
#error "For RT3070, you should define the compile flag -DRTMP_RF_RW_SUPPORT"
#endif
#ifndef RT33xx
#error "For RT3070, you should define the compile flag -DRT30xx"
#endif
#include "mac_usb.h"
#include "rt33xx.h"
//
// Device ID & Vendor ID, these values should match EEPROM value
//
#endif // RT3370 //
#endif //__RT3370_H__ //

View file

@ -0,0 +1,77 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
rt3390.h
Abstract:
Revision History:
Who When What
--------- ---------- ----------------------------------------------
*/
#ifndef __RT3390_H__
#define __RT3390_H__
#ifdef RT3390
#ifndef RTMP_PCI_SUPPORT
#error "For RT3390, you should define the compile flag -DRTMP_PCI_SUPPORT"
#endif
#ifndef RTMP_MAC_PCI
#error "For RT3390, you should define the compile flag -DRTMP_MAC_PCI"
#endif
#ifndef RTMP_RF_RW_SUPPORT
#error "For RT3390, you should define the compile flag -DRTMP_RF_RW_SUPPORT"
#endif
#ifndef RT30xx
#error "For RT3390, you should define the compile flag -DRT30xx"
#endif
#ifdef CARRIER_DETECTION_SUPPORT
#define TONE_RADAR_DETECT_SUPPORT
#define CARRIER_SENSE_NEW_ALGO
#endif // CARRIER_DETECTION_SUPPORT //
#define PCIE_PS_SUPPORT
#include "mac_pci.h"
#include "rt33xx.h"
//
// Device ID & Vendor ID, these values should match EEPROM value
//
#define NIC3390_PCIe_DEVICE_ID 0x3090 // 1T/1R miniCard
#define NIC3391_PCIe_DEVICE_ID 0x3091 // 1T/2R miniCard
#define NIC3392_PCIe_DEVICE_ID 0x3092 // 2T/2R miniCard
#endif // RT3390 //
#endif //__RT3390_H__ //

View file

@ -0,0 +1,48 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
rt33xx.h
Abstract:
Revision History:
Who When What
--------- ---------- ----------------------------------------------
*/
#ifndef __RT33XX_H__
#define __RT33XX_H__
#ifdef RT33xx
extern REG_PAIR RFRegTableOverRT3390[];
extern UCHAR NUM_RF_REG_PARMS_OVER_RT3390;
#endif // RT33xx //
#endif //__RT33XX_H__ //

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,314 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
*/
#ifndef __ATE_H__
#define __ATE_H__
#ifdef LINUX
#define ate_print printk
#define ATEDBGPRINT DBGPRINT
#ifdef RTMP_MAC_PCI
#define EEPROM_SIZE 0x200
#ifdef CONFIG_STA_SUPPORT
#define EEPROM_BIN_FILE_NAME "/etc/Wireless/RT2860STA/e2p.bin"
#endif // CONFIG_STA_SUPPORT //
#endif // RTMP_MAC_PCI //
#endif // LINUX //
#define ATE_ON(_p) (((_p)->ate.Mode) != ATE_STOP)
#ifdef RTMP_MAC_PCI
#define ATE_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) \
{ \
BBP_CSR_CFG_STRUC BbpCsr; \
int j, k; \
for (j=0; j<MAX_BUSY_COUNT; j++) \
{ \
RTMP_IO_READ32(_A, BBP_CSR_CFG, &BbpCsr.word); \
if (BbpCsr.field.Busy == BUSY) \
{ \
continue; \
} \
BbpCsr.word = 0; \
BbpCsr.field.fRead = 1; \
BbpCsr.field.BBP_RW_MODE = 1; \
BbpCsr.field.Busy = 1; \
BbpCsr.field.RegNum = _I; \
RTMP_IO_WRITE32(_A, BBP_CSR_CFG, BbpCsr.word); \
for (k=0; k<MAX_BUSY_COUNT; k++) \
{ \
RTMP_IO_READ32(_A, BBP_CSR_CFG, &BbpCsr.word); \
if (BbpCsr.field.Busy == IDLE) \
break; \
} \
if ((BbpCsr.field.Busy == IDLE) && \
(BbpCsr.field.RegNum == _I)) \
{ \
*(_pV) = (UCHAR)BbpCsr.field.Value; \
break; \
} \
} \
if (BbpCsr.field.Busy == BUSY) \
{ \
ATEDBGPRINT(RT_DEBUG_ERROR, ("BBP read R%d fail\n", _I)); \
*(_pV) = (_A)->BbpWriteLatch[_I]; \
} \
}
#define ATE_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) \
{ \
BBP_CSR_CFG_STRUC BbpCsr; \
int BusyCnt; \
for (BusyCnt=0; BusyCnt<MAX_BUSY_COUNT; BusyCnt++) \
{ \
RTMP_IO_READ32(_A, BBP_CSR_CFG, &BbpCsr.word); \
if (BbpCsr.field.Busy == BUSY) \
continue; \
BbpCsr.word = 0; \
BbpCsr.field.fRead = 0; \
BbpCsr.field.BBP_RW_MODE = 1; \
BbpCsr.field.Busy = 1; \
BbpCsr.field.Value = _V; \
BbpCsr.field.RegNum = _I; \
RTMP_IO_WRITE32(_A, BBP_CSR_CFG, BbpCsr.word); \
(_A)->BbpWriteLatch[_I] = _V; \
break; \
} \
if (BusyCnt == MAX_BUSY_COUNT) \
{ \
ATEDBGPRINT(RT_DEBUG_ERROR, ("BBP write R%d fail\n", _I)); \
} \
}
#endif // RTMP_MAC_PCI //
#ifdef RT30xx
#define ATE_RF_IO_READ8_BY_REG_ID(_A, _I, _pV) RTMP_RF_IO_READ8_BY_REG_ID(_A, _I, _pV)
#define ATE_RF_IO_WRITE8_BY_REG_ID(_A, _I, _V) RTMP_RF_IO_WRITE8_BY_REG_ID(_A, _I, _V)
#endif // RT30xx //
VOID rt_ee_read_all(
IN PRTMP_ADAPTER pAd,
OUT USHORT *Data);
VOID rt_ee_write_all(
IN PRTMP_ADAPTER pAd,
IN USHORT *Data);
INT Set_ATE_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
INT Set_ATE_DA_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
INT Set_ATE_SA_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
INT Set_ATE_BSSID_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
INT Set_ATE_CHANNEL_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
INT Set_ATE_TX_POWER0_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
INT Set_ATE_TX_POWER1_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
INT Set_ATE_TX_Antenna_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
INT Set_ATE_RX_Antenna_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
INT Set_ATE_TX_FREQOFFSET_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
INT Set_ATE_TX_BW_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
INT Set_ATE_TX_LENGTH_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
INT Set_ATE_TX_COUNT_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
INT Set_ATE_TX_MCS_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
INT Set_ATE_TX_MODE_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
INT Set_ATE_TX_GI_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
INT Set_ATE_RX_FER_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
INT Set_ATE_Read_RF_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
INT Set_ATE_Write_RF1_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
INT Set_ATE_Write_RF2_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
INT Set_ATE_Write_RF3_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
INT Set_ATE_Write_RF4_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
INT Set_ATE_Load_E2P_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
INT Set_ATE_Read_E2P_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
INT Set_ATE_Show_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
INT Set_ATE_Help_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
#ifdef RALINK_28xx_QA
VOID ATE_QA_Statistics(
IN PRTMP_ADAPTER pAd,
IN PRXWI_STRUC pRxWI,
IN PRT28XX_RXD_STRUC p28xxRxD,
IN PHEADER_802_11 pHeader);
VOID RtmpDoAte(
IN PRTMP_ADAPTER pAdapter,
IN struct iwreq *wrq);
VOID BubbleSort(
IN INT32 n,
IN INT32 a[]);
VOID CalNoiseLevel(
IN PRTMP_ADAPTER pAdapter,
IN UCHAR channel,
OUT INT32 buffer[3][10]);
BOOLEAN SyncTxRxConfig(
IN PRTMP_ADAPTER pAdapter,
IN USHORT offset,
IN UCHAR value);
INT Set_TxStop_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
INT Set_RxStop_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
#ifdef DBG
INT Set_EERead_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
INT Set_EEWrite_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
INT Set_BBPRead_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
INT Set_BBPWrite_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
INT Set_RFWrite_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
#endif // DBG //
#endif // RALINK_28xx_QA //
VOID ATEAsicSwitchChannel(
IN PRTMP_ADAPTER pAd);
VOID ATEAsicAdjustTxPower(
IN PRTMP_ADAPTER pAd);
VOID ATEDisableAsicProtect(
IN PRTMP_ADAPTER pAd);
CHAR ATEConvertToRssi(
IN PRTMP_ADAPTER pAd,
IN CHAR Rssi,
IN UCHAR RssiNumber);
VOID ATESampleRssi(
IN PRTMP_ADAPTER pAd,
IN PRXWI_STRUC pRxWI);
#ifdef CONFIG_STA_SUPPORT
VOID RTMPStationStop(
IN PRTMP_ADAPTER pAd);
VOID RTMPStationStart(
IN PRTMP_ADAPTER pAd);
#endif // CONFIG_STA_SUPPORT //
#endif // __ATE_H__ //

View file

@ -0,0 +1,126 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
rt_config.h
Abstract:
Central header file to maintain all include files for all NDIS
miniport driver routines.
Revision History:
Who When What
-------- ---------- ----------------------------------------------
Paul Lin 08-01-2002 created
*/
#ifndef __RT_CONFIG_H__
#define __RT_CONFIG_H__
#include "rtmp_type.h"
#include "rtmp_os.h"
#include "rtmp_def.h"
#include "rtmp_chip.h"
#include "rtmp_timer.h"
#include "oid.h"
#include "mlme.h"
#include "wpa.h"
#include "crypt_md5.h"
#include "crypt_sha2.h"
#include "crypt_hmac.h"
#include "rtmp.h"
#include "ap.h"
#include "dfs.h"
#include "chlist.h"
#include "spectrum.h"
#ifdef MLME_EX
#include "mlme_ex_def.h"
#include "mlme_ex.h"
#endif // MLME_EX //
#include "eeprom.h"
#if defined(RTMP_PCI_SUPPORT) || defined(RTMP_USB_SUPPORT)
#include "rtmp_mcu.h"
#endif
#undef AP_WSC_INCLUDED
#undef STA_WSC_INCLUDED
#undef WSC_INCLUDED
#ifdef CONFIG_STA_SUPPORT
#endif // CONFIG_STA_SUPPORT //
#ifdef BLOCK_NET_IF
#include "netif_block.h"
#endif // BLOCK_NET_IF //
#ifdef IGMP_SNOOP_SUPPORT
#include "igmp_snoop.h"
#endif // IGMP_SNOOP_SUPPORT //
#ifdef RALINK_ATE
#include "rt_ate.h"
#endif // RALINK_ATE //
#ifdef RALINK_28xx_QA
#ifndef RALINK_ATE
#error "For supporting QA GUI, please set HAS_ATE=y and HAS_28xx_QA=y."
#endif // RALINK_ATE //
#endif // RALINK_28xx_QA //
#if defined(AP_WSC_INCLUDED) || defined(STA_WSC_INCLUDED)
#define WSC_INCLUDED
#endif
#ifdef CONFIG_STA_SUPPORT
#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
#ifndef WPA_SUPPLICANT_SUPPORT
#error "Build for being controlled by NetworkManager or wext, please set HAS_WPA_SUPPLICANT=y and HAS_NATIVE_WPA_SUPPLICANT_SUPPORT=y"
#endif // WPA_SUPPLICANT_SUPPORT //
#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
#endif // CONFIG_STA_SUPPORT //
#ifdef IKANOS_VX_1X0
#include "vr_ikans.h"
#endif // IKANOS_VX_1X0 //
#endif // __RT_CONFIG_H__

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,897 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
rt_main_dev.c
Abstract:
Create and register network interface.
Revision History:
Who When What
-------- ---------- ----------------------------------------------
*/
#include "rt_config.h"
#ifdef CONFIG_APSTA_MIXED_SUPPORT
UINT32 CW_MAX_IN_BITS;
#endif // CONFIG_APSTA_MIXED_SUPPORT //
/*---------------------------------------------------------------------*/
/* Private Variables Used */
/*---------------------------------------------------------------------*/
PSTRING mac = ""; // default 00:00:00:00:00:00
PSTRING hostname = ""; // default CMPC
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12)
MODULE_PARM (mac, "s");
#else
module_param (mac, charp, 0);
#endif
MODULE_PARM_DESC (mac, "rt28xx: wireless mac addr");
/*---------------------------------------------------------------------*/
/* Prototypes of Functions Used */
/*---------------------------------------------------------------------*/
// public function prototype
int rt28xx_close(IN struct net_device *net_dev);
int rt28xx_open(struct net_device *net_dev);
// private function prototype
static INT rt28xx_send_packets(IN struct sk_buff *skb_p, IN struct net_device *net_dev);
static struct net_device_stats *RT28xx_get_ether_stats(
IN struct net_device *net_dev);
/*
========================================================================
Routine Description:
Close raxx interface.
Arguments:
*net_dev the raxx interface pointer
Return Value:
0 Open OK
otherwise Open Fail
Note:
1. if open fail, kernel will not call the close function.
2. Free memory for
(1) Mlme Memory Handler: MlmeHalt()
(2) TX & RX: RTMPFreeTxRxRingMemory()
(3) BA Reordering: ba_reordering_resource_release()
========================================================================
*/
int MainVirtualIF_close(IN struct net_device *net_dev)
{
RTMP_ADAPTER *pAd = RTMP_OS_NETDEV_GET_PRIV(net_dev);
// Sanity check for pAd
if (pAd == NULL)
return 0; // close ok
netif_carrier_off(pAd->net_dev);
netif_stop_queue(pAd->net_dev);
#ifdef CONFIG_STA_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
{
BOOLEAN Cancelled;
#ifdef QOS_DLS_SUPPORT
// send DLS-TEAR_DOWN message,
if (pAd->CommonCfg.bDLSCapable)
{
UCHAR i;
// tear down local dls table entry
for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
{
if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
{
RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
pAd->StaCfg.DLSEntry[i].Valid = FALSE;
}
}
// tear down peer dls table entry
for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
{
if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
{
RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
pAd->StaCfg.DLSEntry[i].Valid = FALSE;
}
}
RTMP_MLME_HANDLER(pAd);
}
#endif // QOS_DLS_SUPPORT //
if (INFRA_ON(pAd) &&
(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
{
MLME_DISASSOC_REQ_STRUCT DisReq;
MLME_QUEUE_ELEM *MsgElem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
if (MsgElem)
{
COPY_MAC_ADDR(DisReq.Addr, pAd->CommonCfg.Bssid);
DisReq.Reason = REASON_DEAUTH_STA_LEAVING;
MsgElem->Machine = ASSOC_STATE_MACHINE;
MsgElem->MsgType = MT2_MLME_DISASSOC_REQ;
MsgElem->MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT);
NdisMoveMemory(MsgElem->Msg, &DisReq, sizeof(MLME_DISASSOC_REQ_STRUCT));
// Prevent to connect AP again in STAMlmePeriodicExec
pAd->MlmeAux.AutoReconnectSsidLen= 32;
NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
MlmeDisassocReqAction(pAd, MsgElem);
kfree(MsgElem);
}
RTMPusecDelay(1000);
}
RTMPCancelTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, &Cancelled);
RTMPCancelTimer(&pAd->StaCfg.WpaDisassocAndBlockAssocTimer, &Cancelled);
#ifdef WPA_SUPPLICANT_SUPPORT
#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
// send wireless event to wpa_supplicant for infroming interface down.
RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, RT_INTERFACE_DOWN, NULL, NULL, 0);
#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
#endif // WPA_SUPPLICANT_SUPPORT //
}
#endif // CONFIG_STA_SUPPORT //
VIRTUAL_IF_DOWN(pAd);
RT_MOD_DEC_USE_COUNT();
return 0; // close ok
}
/*
========================================================================
Routine Description:
Open raxx interface.
Arguments:
*net_dev the raxx interface pointer
Return Value:
0 Open OK
otherwise Open Fail
Note:
1. if open fail, kernel will not call the close function.
2. Free memory for
(1) Mlme Memory Handler: MlmeHalt()
(2) TX & RX: RTMPFreeTxRxRingMemory()
(3) BA Reordering: ba_reordering_resource_release()
========================================================================
*/
int MainVirtualIF_open(IN struct net_device *net_dev)
{
RTMP_ADAPTER *pAd = RTMP_OS_NETDEV_GET_PRIV(net_dev);
// Sanity check for pAd
if (pAd == NULL)
return 0; // close ok
if (VIRTUAL_IF_UP(pAd) != 0)
return -1;
// increase MODULE use count
RT_MOD_INC_USE_COUNT();
netif_start_queue(net_dev);
netif_carrier_on(net_dev);
netif_wake_queue(net_dev);
return 0;
}
/*
========================================================================
Routine Description:
Close raxx interface.
Arguments:
*net_dev the raxx interface pointer
Return Value:
0 Open OK
otherwise Open Fail
Note:
1. if open fail, kernel will not call the close function.
2. Free memory for
(1) Mlme Memory Handler: MlmeHalt()
(2) TX & RX: RTMPFreeTxRxRingMemory()
(3) BA Reordering: ba_reordering_resource_release()
========================================================================
*/
int rt28xx_close(IN PNET_DEV dev)
{
struct net_device * net_dev = (struct net_device *)dev;
RTMP_ADAPTER *pAd = RTMP_OS_NETDEV_GET_PRIV(net_dev);
BOOLEAN Cancelled;
UINT32 i = 0;
DBGPRINT(RT_DEBUG_TRACE, ("===> rt28xx_close\n"));
Cancelled = FALSE;
// Sanity check for pAd
if (pAd == NULL)
return 0; // close ok
#ifdef WDS_SUPPORT
WdsDown(pAd);
#endif // WDS_SUPPORT //
#ifdef CONFIG_STA_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
{
#ifdef RTMP_MAC_PCI
RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_CLOSE);
#endif // RTMP_MAC_PCI //
// If dirver doesn't wake up firmware here,
// NICLoadFirmware will hang forever when interface is up again.
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
{
AsicForceWakeup(pAd, TRUE);
}
MlmeRadioOff(pAd);
#ifdef RTMP_MAC_PCI
pAd->bPCIclkOff = FALSE;
#endif // RTMP_MAC_PCI //
}
#endif // CONFIG_STA_SUPPORT //
RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
for (i = 0 ; i < NUM_OF_TX_RING; i++)
{
while (pAd->DeQueueRunning[i] == TRUE)
{
DBGPRINT(RT_DEBUG_TRACE, ("Waiting for TxQueue[%d] done..........\n", i));
RTMPusecDelay(1000);
}
}
// Stop Mlme state machine
MlmeHalt(pAd);
// Close net tasklets
RtmpNetTaskExit(pAd);
#ifdef CONFIG_STA_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
{
MacTableReset(pAd);
}
#endif // CONFIG_STA_SUPPORT //
MeasureReqTabExit(pAd);
TpcReqTabExit(pAd);
// Close kernel threads
RtmpMgmtTaskExit(pAd);
#ifdef RTMP_MAC_PCI
{
BOOLEAN brc;
// ULONG Value;
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE))
{
RTMP_ASIC_INTERRUPT_DISABLE(pAd);
}
// Receive packets to clear DMA index after disable interrupt.
//RTMPHandleRxDoneInterrupt(pAd);
// put to radio off to save power when driver unload. After radiooff, can't write /read register. So need to finish all
// register access before Radio off.
brc=RT28xxPciAsicRadioOff(pAd, RTMP_HALT, 0);
//In solution 3 of 3090F, the bPCIclkOff will be set to TRUE after calling RT28xxPciAsicRadioOff
pAd->bPCIclkOff = FALSE;
if (brc==FALSE)
{
DBGPRINT(RT_DEBUG_ERROR,("%s call RT28xxPciAsicRadioOff fail !!\n", __FUNCTION__));
}
}
/*
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE))
{
RTMP_ASIC_INTERRUPT_DISABLE(pAd);
}
// Disable Rx, register value supposed will remain after reset
NICIssueReset(pAd);
*/
#endif // RTMP_MAC_PCI //
// Free IRQ
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
{
#ifdef RTMP_MAC_PCI
// Deregister interrupt function
RTMP_IRQ_RELEASE(net_dev)
#endif // RTMP_MAC_PCI //
RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
}
// Free Ring or USB buffers
RTMPFreeTxRxRingMemory(pAd);
RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
#ifdef DOT11_N_SUPPORT
// Free BA reorder resource
ba_reordering_resource_release(pAd);
#endif // DOT11_N_SUPPORT //
#ifdef CONFIG_STA_SUPPORT
#endif // CONFIG_STA_SUPPORT //
RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_START_UP);
/*+++Modify by woody to solve the bulk fail+++*/
#ifdef CONFIG_STA_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
{
}
#endif // CONFIG_STA_SUPPORT //
DBGPRINT(RT_DEBUG_TRACE, ("<=== rt28xx_close\n"));
return 0; // close ok
} /* End of rt28xx_close */
/*
========================================================================
Routine Description:
Open raxx interface.
Arguments:
*net_dev the raxx interface pointer
Return Value:
0 Open OK
otherwise Open Fail
Note:
========================================================================
*/
int rt28xx_open(IN PNET_DEV dev)
{
struct net_device * net_dev = (struct net_device *)dev;
PRTMP_ADAPTER pAd = RTMP_OS_NETDEV_GET_PRIV(net_dev);
int retval = 0;
//POS_COOKIE pObj;
// Sanity check for pAd
if (pAd == NULL)
{
/* if 1st open fail, pAd will be free;
So the net_dev->priv will be NULL in 2rd open */
return -1;
}
#ifdef CONFIG_APSTA_MIXED_SUPPORT
if (pAd->OpMode == OPMODE_AP)
{
CW_MAX_IN_BITS = 6;
}
else if (pAd->OpMode == OPMODE_STA)
{
CW_MAX_IN_BITS = 10;
}
#endif // CONFIG_APSTA_MIXED_SUPPORT //
#if WIRELESS_EXT >= 12
if (net_dev->priv_flags == INT_MAIN)
{
#ifdef CONFIG_APSTA_MIXED_SUPPORT
if (pAd->OpMode == OPMODE_AP)
net_dev->wireless_handlers = (struct iw_handler_def *) &rt28xx_ap_iw_handler_def;
#endif // CONFIG_APSTA_MIXED_SUPPORT //
#ifdef CONFIG_STA_SUPPORT
if (pAd->OpMode == OPMODE_STA)
net_dev->wireless_handlers = (struct iw_handler_def *) &rt28xx_iw_handler_def;
#endif // CONFIG_STA_SUPPORT //
}
#endif // WIRELESS_EXT >= 12 //
// Request interrupt service routine for PCI device
// register the interrupt routine with the os
RTMP_IRQ_REQUEST(net_dev);
// Init IRQ parameters stored in pAd
RTMP_IRQ_INIT(pAd);
// Chip & other init
if (rt28xx_init(pAd, mac, hostname) == FALSE)
goto err;
#ifdef CONFIG_STA_SUPPORT
#endif // CONFIG_STA_SUPPORT //
// Enable Interrupt
RTMP_IRQ_ENABLE(pAd);
// Now Enable RxTx
RTMPEnableRxTx(pAd);
RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP);
{
UINT32 reg = 0;
RTMP_IO_READ32(pAd, 0x1300, &reg); // clear garbage interrupts
printk("0x1300 = %08x\n", reg);
}
{
// u32 reg;
// UINT8 byte;
// u16 tmp;
// RTMP_IO_READ32(pAd, XIFS_TIME_CFG, &reg);
// tmp = 0x0805;
// reg = (reg & 0xffff0000) | tmp;
// RTMP_IO_WRITE32(pAd, XIFS_TIME_CFG, reg);
}
#ifdef CONFIG_STA_SUPPORT
#ifdef RTMP_MAC_PCI
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
RTMPInitPCIeLinkCtrlValue(pAd);
#endif // RTMP_MAC_PCI //
#endif // CONFIG_STA_SUPPORT //
return (retval);
err:
//+++Add by shiang, move from rt28xx_init() to here.
RTMP_IRQ_RELEASE(net_dev);
//---Add by shiang, move from rt28xx_init() to here.
return (-1);
} /* End of rt28xx_open */
static const struct net_device_ops rt3090_netdev_ops = {
.ndo_open = MainVirtualIF_open,
.ndo_stop = MainVirtualIF_close,
.ndo_do_ioctl = rt28xx_ioctl,
.ndo_get_stats = RT28xx_get_ether_stats,
.ndo_set_mac_address = eth_mac_addr,
.ndo_change_mtu = eth_change_mtu,
#ifdef IKANOS_VX_1X0
.ndo_start_xmit = IKANOS_DataFramesTx,
#else
.ndo_start_xmit = rt28xx_send_packets,
#endif
};
PNET_DEV RtmpPhyNetDevInit(
IN RTMP_ADAPTER *pAd,
IN RTMP_OS_NETDEV_OP_HOOK *pNetDevHook)
{
struct net_device *net_dev = NULL;
// NDIS_STATUS Status;
net_dev = RtmpOSNetDevCreate(pAd, INT_MAIN, 0, sizeof(PRTMP_ADAPTER), INF_MAIN_DEV_NAME);
if (net_dev == NULL)
{
printk("RtmpPhyNetDevInit(): creation failed for main physical net device!\n");
return NULL;
}
NdisZeroMemory((unsigned char *)pNetDevHook, sizeof(RTMP_OS_NETDEV_OP_HOOK));
pNetDevHook->netdev_ops = &rt3090_netdev_ops;
pNetDevHook->priv_flags = INT_MAIN;
pNetDevHook->needProtcted = FALSE;
RTMP_OS_NETDEV_SET_PRIV(net_dev, pAd);
//net_dev->priv = (PVOID)pAd;
pAd->net_dev = net_dev;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
SET_MODULE_OWNER(net_dev);
#endif
netif_stop_queue(net_dev);
return net_dev;
}
/*
========================================================================
Routine Description:
The entry point for Linux kernel sent packet to our driver.
Arguments:
sk_buff *skb the pointer refer to a sk_buffer.
Return Value:
0
Note:
This function is the entry point of Tx Path for Os delivery packet to
our driver. You only can put OS-depened & STA/AP common handle procedures
in here.
========================================================================
*/
int rt28xx_packet_xmit(struct sk_buff *skb)
{
struct net_device *net_dev = skb->dev;
PRTMP_ADAPTER pAd = RTMP_OS_NETDEV_GET_PRIV(net_dev);
int status = 0;
PNDIS_PACKET pPacket = (PNDIS_PACKET) skb;
/* RT2870STA does this in RTMPSendPackets() */
#ifdef RALINK_ATE
if (ATE_ON(pAd))
{
RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_RESOURCES);
return 0;
}
#endif // RALINK_ATE //
#ifdef CONFIG_STA_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
{
// Drop send request since we are in monitor mode
if (MONITOR_ON(pAd))
{
RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
goto done;
}
}
#endif // CONFIG_STA_SUPPORT //
// EapolStart size is 18
if (skb->len < 14)
{
//printk("bad packet size: %d\n", pkt->len);
hex_dump("bad packet", skb->data, skb->len);
RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
goto done;
}
RTMP_SET_PACKET_5VT(pPacket, 0);
// MiniportMMRequest(pAd, pkt->data, pkt->len);
#ifdef CONFIG_5VT_ENHANCE
if (*(int*)(skb->cb) == BRIDGE_TAG) {
RTMP_SET_PACKET_5VT(pPacket, 1);
}
#endif
#ifdef CONFIG_STA_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
{
STASendPackets((NDIS_HANDLE)pAd, (PPNDIS_PACKET) &pPacket, 1);
}
#endif // CONFIG_STA_SUPPORT //
status = 0;
done:
return status;
}
/*
========================================================================
Routine Description:
Send a packet to WLAN.
Arguments:
skb_p points to our adapter
dev_p which WLAN network interface
Return Value:
0: transmit successfully
otherwise: transmit fail
Note:
========================================================================
*/
static int rt28xx_send_packets(
IN struct sk_buff *skb_p,
IN struct net_device *net_dev)
{
RTMP_ADAPTER *pAd = RTMP_OS_NETDEV_GET_PRIV(net_dev);
if (!(net_dev->flags & IFF_UP))
{
RELEASE_NDIS_PACKET(pAd, (PNDIS_PACKET)skb_p, NDIS_STATUS_FAILURE);
return 0;
}
NdisZeroMemory((PUCHAR)&skb_p->cb[CB_OFF], 15);
RTMP_SET_PACKET_NET_DEVICE_MBSSID(skb_p, MAIN_MBSSID);
return rt28xx_packet_xmit(skb_p);
}
#if WIRELESS_EXT >= 12
// This function will be called when query /proc
struct iw_statistics *rt28xx_get_wireless_stats(
IN struct net_device *net_dev)
{
PRTMP_ADAPTER pAd = RTMP_OS_NETDEV_GET_PRIV(net_dev);
DBGPRINT(RT_DEBUG_TRACE, ("rt28xx_get_wireless_stats --->\n"));
pAd->iw_stats.status = 0; // Status - device dependent for now
// link quality
#ifdef CONFIG_STA_SUPPORT
if (pAd->OpMode == OPMODE_STA)
pAd->iw_stats.qual.qual = ((pAd->Mlme.ChannelQuality * 12)/10 + 10);
#endif // CONFIG_STA_SUPPORT //
if(pAd->iw_stats.qual.qual > 100)
pAd->iw_stats.qual.qual = 100;
#ifdef CONFIG_STA_SUPPORT
if (pAd->OpMode == OPMODE_STA)
{
pAd->iw_stats.qual.level =
RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0,
pAd->StaCfg.RssiSample.LastRssi1,
pAd->StaCfg.RssiSample.LastRssi2);
}
#endif // CONFIG_STA_SUPPORT //
pAd->iw_stats.qual.noise = pAd->BbpWriteLatch[66]; // noise level (dBm)
pAd->iw_stats.qual.noise += 256 - 143;
pAd->iw_stats.qual.updated = 1; // Flags to know if updated
#ifdef IW_QUAL_DBM
pAd->iw_stats.qual.updated |= IW_QUAL_DBM; // Level + Noise are dBm
#endif // IW_QUAL_DBM //
pAd->iw_stats.discard.nwid = 0; // Rx : Wrong nwid/essid
pAd->iw_stats.miss.beacon = 0; // Missed beacons/superframe
DBGPRINT(RT_DEBUG_TRACE, ("<--- rt28xx_get_wireless_stats\n"));
return &pAd->iw_stats;
}
#endif // WIRELESS_EXT //
void tbtt_tasklet(unsigned long data)
{
//#define MAX_TX_IN_TBTT (16)
}
INT rt28xx_ioctl(
IN PNET_DEV net_dev,
IN OUT struct ifreq *rq,
IN INT cmd)
{
RTMP_ADAPTER *pAd = NULL;
INT ret = 0;
pAd = RTMP_OS_NETDEV_GET_PRIV(net_dev);
if (pAd == NULL)
{
/* if 1st open fail, pAd will be free;
So the net_dev->priv will be NULL in 2rd open */
return -ENETDOWN;
}
#ifdef CONFIG_STA_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
{
ret = rt28xx_sta_ioctl(net_dev, rq, cmd);
}
#endif // CONFIG_STA_SUPPORT //
return ret;
}
/*
========================================================================
Routine Description:
return ethernet statistics counter
Arguments:
net_dev Pointer to net_device
Return Value:
net_device_stats*
Note:
========================================================================
*/
static struct net_device_stats *RT28xx_get_ether_stats(
IN struct net_device *net_dev)
{
RTMP_ADAPTER *pAd = NULL;
if (net_dev)
pAd = RTMP_OS_NETDEV_GET_PRIV(net_dev);
if (pAd)
{
pAd->stats.rx_packets = pAd->WlanCounters.ReceivedFragmentCount.QuadPart;
pAd->stats.tx_packets = pAd->WlanCounters.TransmittedFragmentCount.QuadPart;
pAd->stats.rx_bytes = pAd->RalinkCounters.ReceivedByteCount;
pAd->stats.tx_bytes = pAd->RalinkCounters.TransmittedByteCount;
pAd->stats.rx_errors = pAd->Counters8023.RxErrors;
pAd->stats.tx_errors = pAd->Counters8023.TxErrors;
pAd->stats.rx_dropped = 0;
pAd->stats.tx_dropped = 0;
pAd->stats.multicast = pAd->WlanCounters.MulticastReceivedFrameCount.QuadPart; // multicast packets received
pAd->stats.collisions = pAd->Counters8023.OneCollision + pAd->Counters8023.MoreCollisions; // Collision packets
pAd->stats.rx_length_errors = 0;
pAd->stats.rx_over_errors = pAd->Counters8023.RxNoBuffer; // receiver ring buff overflow
pAd->stats.rx_crc_errors = 0;//pAd->WlanCounters.FCSErrorCount; // recved pkt with crc error
pAd->stats.rx_frame_errors = pAd->Counters8023.RcvAlignmentErrors; // recv'd frame alignment error
pAd->stats.rx_fifo_errors = pAd->Counters8023.RxNoBuffer; // recv'r fifo overrun
pAd->stats.rx_missed_errors = 0; // receiver missed packet
// detailed tx_errors
pAd->stats.tx_aborted_errors = 0;
pAd->stats.tx_carrier_errors = 0;
pAd->stats.tx_fifo_errors = 0;
pAd->stats.tx_heartbeat_errors = 0;
pAd->stats.tx_window_errors = 0;
// for cslip etc
pAd->stats.rx_compressed = 0;
pAd->stats.tx_compressed = 0;
return &pAd->stats;
}
else
return NULL;
}
BOOLEAN RtmpPhyNetDevExit(
IN RTMP_ADAPTER *pAd,
IN PNET_DEV net_dev)
{
#ifdef INF_AMAZON_PPA
if (ppa_hook_directpath_register_dev_fn && pAd->PPAEnable==TRUE)
{
UINT status;
status=ppa_hook_directpath_register_dev_fn(&pAd->g_if_id, pAd->net_dev, NULL, PPA_F_DIRECTPATH_DEREGISTER);
printk("unregister PPA:g_if_id=%d status=%d\n",pAd->g_if_id,status);
}
kfree(pAd->pDirectpathCb);
#endif // INF_AMAZON_PPA //
// Unregister network device
if (net_dev != NULL)
{
printk("RtmpOSNetDevDetach(): RtmpOSNetDeviceDetach(), dev->name=%s!\n", net_dev->name);
RtmpOSNetDevDetach(net_dev);
}
return TRUE;
}
/*
========================================================================
Routine Description:
Allocate memory for adapter control block.
Arguments:
pAd Pointer to our adapter
Return Value:
NDIS_STATUS_SUCCESS
NDIS_STATUS_FAILURE
NDIS_STATUS_RESOURCES
Note:
========================================================================
*/
NDIS_STATUS AdapterBlockAllocateMemory(
IN PVOID handle,
OUT PVOID *ppAd)
{
*ppAd = (PVOID)vmalloc(sizeof(RTMP_ADAPTER)); //pci_alloc_consistent(pci_dev, sizeof(RTMP_ADAPTER), phy_addr);
if (*ppAd)
{
NdisZeroMemory(*ppAd, sizeof(RTMP_ADAPTER));
((PRTMP_ADAPTER)*ppAd)->OS_Cookie = handle;
return (NDIS_STATUS_SUCCESS);
} else {
return (NDIS_STATUS_FAILURE);
}
}

View file

@ -0,0 +1,989 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
rt_pci_rbus.c
Abstract:
Create and register network interface.
Revision History:
Who When What
-------- ---------- ----------------------------------------------
*/
#include "rt_config.h"
#include <linux/pci.h>
IRQ_HANDLE_TYPE
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19))
rt2860_interrupt(int irq, void *dev_instance);
#else
rt2860_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
#endif
static void rx_done_tasklet(unsigned long data);
static void mgmt_dma_done_tasklet(unsigned long data);
static void ac0_dma_done_tasklet(unsigned long data);
static void ac1_dma_done_tasklet(unsigned long data);
static void ac2_dma_done_tasklet(unsigned long data);
static void ac3_dma_done_tasklet(unsigned long data);
/*static void hcca_dma_done_tasklet(unsigned long data);*/
static void fifo_statistic_full_tasklet(unsigned long data);
/*---------------------------------------------------------------------*/
/* Symbol & Macro Definitions */
/*---------------------------------------------------------------------*/
#define RT2860_INT_RX_DLY (1<<0) // bit 0
#define RT2860_INT_TX_DLY (1<<1) // bit 1
#define RT2860_INT_RX_DONE (1<<2) // bit 2
#define RT2860_INT_AC0_DMA_DONE (1<<3) // bit 3
#define RT2860_INT_AC1_DMA_DONE (1<<4) // bit 4
#define RT2860_INT_AC2_DMA_DONE (1<<5) // bit 5
#define RT2860_INT_AC3_DMA_DONE (1<<6) // bit 6
#define RT2860_INT_HCCA_DMA_DONE (1<<7) // bit 7
#define RT2860_INT_MGMT_DONE (1<<8) // bit 8
#ifdef TONE_RADAR_DETECT_SUPPORT
#define RT2860_INT_TONE_RADAR (1<<20) // bit 20
#endif // TONE_RADAR_DETECT_SUPPORT //
#define INT_RX RT2860_INT_RX_DONE
#define INT_AC0_DLY (RT2860_INT_AC0_DMA_DONE) //| RT2860_INT_TX_DLY)
#define INT_AC1_DLY (RT2860_INT_AC1_DMA_DONE) //| RT2860_INT_TX_DLY)
#define INT_AC2_DLY (RT2860_INT_AC2_DMA_DONE) //| RT2860_INT_TX_DLY)
#define INT_AC3_DLY (RT2860_INT_AC3_DMA_DONE) //| RT2860_INT_TX_DLY)
#define INT_HCCA_DLY (RT2860_INT_HCCA_DMA_DONE) //| RT2860_INT_TX_DLY)
#define INT_MGMT_DLY RT2860_INT_MGMT_DONE
#ifdef TONE_RADAR_DETECT_SUPPORT
#define INT_TONE_RADAR (RT2860_INT_TONE_RADAR)
#endif // TONE_RADAR_DETECT_SUPPORT //
/***************************************************************************
*
* Interface-depended memory allocation/Free related procedures.
* Mainly for Hardware TxDesc/RxDesc/MgmtDesc, DMA Memory for TxData/RxData, etc.,
*
**************************************************************************/
// Function for TxDesc Memory allocation.
void RTMP_AllocateTxDescMemory(
IN PRTMP_ADAPTER pAd,
IN UINT Index,
IN ULONG Length,
IN BOOLEAN Cached,
OUT PVOID *VirtualAddress,
OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
{
POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
*VirtualAddress = (PVOID)pci_alloc_consistent(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
}
// Function for MgmtDesc Memory allocation.
void RTMP_AllocateMgmtDescMemory(
IN PRTMP_ADAPTER pAd,
IN ULONG Length,
IN BOOLEAN Cached,
OUT PVOID *VirtualAddress,
OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
{
POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
*VirtualAddress = (PVOID)pci_alloc_consistent(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
}
// Function for RxDesc Memory allocation.
void RTMP_AllocateRxDescMemory(
IN PRTMP_ADAPTER pAd,
IN ULONG Length,
IN BOOLEAN Cached,
OUT PVOID *VirtualAddress,
OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
{
POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
*VirtualAddress = (PVOID)pci_alloc_consistent(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
}
// Function for free allocated Desc Memory.
void RTMP_FreeDescMemory(
IN PRTMP_ADAPTER pAd,
IN ULONG Length,
IN PVOID VirtualAddress,
IN NDIS_PHYSICAL_ADDRESS PhysicalAddress)
{
POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
pci_free_consistent(pObj->pci_dev, Length, VirtualAddress, PhysicalAddress);
}
// Function for TxData DMA Memory allocation.
void RTMP_AllocateFirstTxBuffer(
IN PRTMP_ADAPTER pAd,
IN UINT Index,
IN ULONG Length,
IN BOOLEAN Cached,
OUT PVOID *VirtualAddress,
OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
{
POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
*VirtualAddress = (PVOID)pci_alloc_consistent(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
}
void RTMP_FreeFirstTxBuffer(
IN PRTMP_ADAPTER pAd,
IN ULONG Length,
IN BOOLEAN Cached,
IN PVOID VirtualAddress,
IN NDIS_PHYSICAL_ADDRESS PhysicalAddress)
{
POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
pci_free_consistent(pObj->pci_dev, Length, VirtualAddress, PhysicalAddress);
}
/*
* FUNCTION: Allocate a common buffer for DMA
* ARGUMENTS:
* AdapterHandle: AdapterHandle
* Length: Number of bytes to allocate
* Cached: Whether or not the memory can be cached
* VirtualAddress: Pointer to memory is returned here
* PhysicalAddress: Physical address corresponding to virtual address
*/
void RTMP_AllocateSharedMemory(
IN PRTMP_ADAPTER pAd,
IN ULONG Length,
IN BOOLEAN Cached,
OUT PVOID *VirtualAddress,
OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
{
POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
*VirtualAddress = (PVOID)pci_alloc_consistent(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
}
/*
* FUNCTION: Allocate a packet buffer for DMA
* ARGUMENTS:
* AdapterHandle: AdapterHandle
* Length: Number of bytes to allocate
* Cached: Whether or not the memory can be cached
* VirtualAddress: Pointer to memory is returned here
* PhysicalAddress: Physical address corresponding to virtual address
* Notes:
* Cached is ignored: always cached memory
*/
PNDIS_PACKET RTMP_AllocateRxPacketBuffer(
IN PRTMP_ADAPTER pAd,
IN ULONG Length,
IN BOOLEAN Cached,
OUT PVOID *VirtualAddress,
OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
{
struct sk_buff *pkt;
pkt = dev_alloc_skb(Length);
if (pkt == NULL) {
DBGPRINT(RT_DEBUG_ERROR, ("can't allocate rx %ld size packet\n",Length));
}
if (pkt) {
RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
*VirtualAddress = (PVOID) pkt->data;
//#ifdef CONFIG_5VT_ENHANCE
// *PhysicalAddress = PCI_MAP_SINGLE(pAd, *VirtualAddress, 1600, PCI_DMA_FROMDEVICE);
//#else
*PhysicalAddress = PCI_MAP_SINGLE(pAd, *VirtualAddress, Length, -1, PCI_DMA_FROMDEVICE);
//#endif
} else {
*VirtualAddress = (PVOID) NULL;
*PhysicalAddress = (NDIS_PHYSICAL_ADDRESS) NULL;
}
return (PNDIS_PACKET) pkt;
}
VOID Invalid_Remaining_Packet(
IN PRTMP_ADAPTER pAd,
IN ULONG VirtualAddress)
{
NDIS_PHYSICAL_ADDRESS PhysicalAddress;
PhysicalAddress = PCI_MAP_SINGLE(pAd, (void *)(VirtualAddress+1600), RX_BUFFER_NORMSIZE-1600, -1, PCI_DMA_FROMDEVICE);
}
int RtmpOSIRQRequest(IN struct net_device *net_dev)
{
PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)(RTMP_OS_NETDEV_GET_PRIV(net_dev));
int retval = 0;
ASSERT(pAd);
if (pAd->infType != RTMP_DEV_INF_RBUS)
{
POS_COOKIE _pObj = (POS_COOKIE)(pAd->OS_Cookie);
RTMP_MSI_ENABLE(pAd);
retval = request_irq(_pObj->pci_dev->irq, rt2860_interrupt, SA_SHIRQ, (net_dev)->name, (net_dev));
if (retval != 0)
printk("RT2860: request_irq ERROR(%d)\n", retval);
}
else
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
if ((retval = request_irq(net_dev->irq, rt2860_interrupt, IRQF_SHARED, net_dev->name ,net_dev)))
#else
if ((retval = request_irq(net_dev->irq,rt2860_interrupt, SA_INTERRUPT, net_dev->name ,net_dev)))
#endif
{
printk("RT2860: request_irq ERROR(%d)\n", retval);
}
}
return retval;
}
int RtmpOSIRQRelease(IN struct net_device *net_dev)
{
PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)(RTMP_OS_NETDEV_GET_PRIV(net_dev));
ASSERT(pAd);
if (pAd->infType != RTMP_DEV_INF_RBUS)
{
POS_COOKIE pObj = (POS_COOKIE)(pAd->OS_Cookie);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
synchronize_irq(pObj->pci_dev->irq);
#endif
free_irq(pObj->pci_dev->irq, (net_dev));
RTMP_MSI_DISABLE(pAd);
}
else
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
synchronize_irq(net_dev->irq);
#endif
free_irq(net_dev->irq, (net_dev));
}
return 0;
}
NDIS_STATUS RtmpNetTaskInit(IN RTMP_ADAPTER *pAd)
{
POS_COOKIE pObj;
pObj = (POS_COOKIE) pAd->OS_Cookie;
tasklet_init(&pObj->rx_done_task, rx_done_tasklet, (unsigned long)pAd);
tasklet_init(&pObj->mgmt_dma_done_task, mgmt_dma_done_tasklet, (unsigned long)pAd);
tasklet_init(&pObj->ac0_dma_done_task, ac0_dma_done_tasklet, (unsigned long)pAd);
tasklet_init(&pObj->ac1_dma_done_task, ac1_dma_done_tasklet, (unsigned long)pAd);
tasklet_init(&pObj->ac2_dma_done_task, ac2_dma_done_tasklet, (unsigned long)pAd);
tasklet_init(&pObj->ac3_dma_done_task, ac3_dma_done_tasklet, (unsigned long)pAd);
/*tasklet_init(&pObj->hcca_dma_done_task, hcca_dma_done_tasklet, (unsigned long)pAd);*/
tasklet_init(&pObj->tbtt_task, tbtt_tasklet, (unsigned long)pAd);
tasklet_init(&pObj->fifo_statistic_full_task, fifo_statistic_full_tasklet, (unsigned long)pAd);
return NDIS_STATUS_SUCCESS;
}
void RtmpNetTaskExit(IN RTMP_ADAPTER *pAd)
{
POS_COOKIE pObj;
pObj = (POS_COOKIE) pAd->OS_Cookie;
tasklet_kill(&pObj->rx_done_task);
tasklet_kill(&pObj->mgmt_dma_done_task);
tasklet_kill(&pObj->ac0_dma_done_task);
tasklet_kill(&pObj->ac1_dma_done_task);
tasklet_kill(&pObj->ac2_dma_done_task);
tasklet_kill(&pObj->ac3_dma_done_task);
/*tasklet_kill(&pObj->hcca_dma_done_task);*/
tasklet_kill(&pObj->tbtt_task);
tasklet_kill(&pObj->fifo_statistic_full_task);
}
NDIS_STATUS RtmpMgmtTaskInit(IN RTMP_ADAPTER *pAd)
{
return NDIS_STATUS_SUCCESS;
}
/*
========================================================================
Routine Description:
Close kernel threads.
Arguments:
*pAd the raxx interface data pointer
Return Value:
NONE
Note:
========================================================================
*/
VOID RtmpMgmtTaskExit(
IN RTMP_ADAPTER *pAd)
{
return;
}
static inline void rt2860_int_enable(PRTMP_ADAPTER pAd, unsigned int mode)
{
u32 regValue;
pAd->int_disable_mask &= ~(mode);
regValue = pAd->int_enable_reg & ~(pAd->int_disable_mask);
//if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
{
RTMP_IO_WRITE32(pAd, INT_MASK_CSR, regValue); // 1:enable
}
//else
// DBGPRINT(RT_DEBUG_TRACE, ("fOP_STATUS_DOZE !\n"));
if (regValue != 0)
RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE);
}
static inline void rt2860_int_disable(PRTMP_ADAPTER pAd, unsigned int mode)
{
u32 regValue;
pAd->int_disable_mask |= mode;
regValue = pAd->int_enable_reg & ~(pAd->int_disable_mask);
RTMP_IO_WRITE32(pAd, INT_MASK_CSR, regValue); // 0: disable
if (regValue == 0)
{
RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE);
}
}
/***************************************************************************
*
* tasklet related procedures.
*
**************************************************************************/
static void mgmt_dma_done_tasklet(unsigned long data)
{
unsigned long flags;
PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
INT_SOURCE_CSR_STRUC IntSource;
POS_COOKIE pObj;
// Do nothing if the driver is starting halt state.
// This might happen when timer already been fired before cancel timer with mlmehalt
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
return;
pObj = (POS_COOKIE) pAd->OS_Cookie;
// printk("mgmt_dma_done_process\n");
IntSource.word = 0;
IntSource.field.MgmtDmaDone = 1;
pAd->int_pending &= ~INT_MGMT_DLY;
RTMPHandleMgmtRingDmaDoneInterrupt(pAd);
// if you use RTMP_SEM_LOCK, sometimes kernel will hang up, no any
// bug report output
RTMP_INT_LOCK(&pAd->irq_lock, flags);
/*
* double check to avoid lose of interrupts
*/
if (pAd->int_pending & INT_MGMT_DLY)
{
tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
return;
}
/* enable TxDataInt again */
rt2860_int_enable(pAd, INT_MGMT_DLY);
RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
}
static void rx_done_tasklet(unsigned long data)
{
unsigned long flags;
PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
BOOLEAN bReschedule = 0;
POS_COOKIE pObj;
// Do nothing if the driver is starting halt state.
// This might happen when timer already been fired before cancel timer with mlmehalt
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
return;
#ifdef UAPSD_AP_SUPPORT
UAPSD_TIMING_RECORD(pAd, UAPSD_TIMING_RECORD_TASKLET);
#endif // UAPSD_AP_SUPPORT //
pObj = (POS_COOKIE) pAd->OS_Cookie;
pAd->int_pending &= ~(INT_RX);
#ifdef CONFIG_STA_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
bReschedule = STARxDoneInterruptHandle(pAd, 0);
#endif // CONFIG_STA_SUPPORT //
#ifdef UAPSD_AP_SUPPORT
UAPSD_TIMING_RECORD_STOP();
#endif // UAPSD_AP_SUPPORT //
RTMP_INT_LOCK(&pAd->irq_lock, flags);
/*
* double check to avoid rotting packet
*/
if (pAd->int_pending & INT_RX || bReschedule)
{
tasklet_hi_schedule(&pObj->rx_done_task);
RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
return;
}
/* enable RxINT again */
rt2860_int_enable(pAd, INT_RX);
RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
}
void fifo_statistic_full_tasklet(unsigned long data)
{
unsigned long flags;
PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
POS_COOKIE pObj;
// Do nothing if the driver is starting halt state.
// This might happen when timer already been fired before cancel timer with mlmehalt
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
return;
pObj = (POS_COOKIE) pAd->OS_Cookie;
pAd->int_pending &= ~(FifoStaFullInt);
NICUpdateFifoStaCounters(pAd);
RTMP_INT_LOCK(&pAd->irq_lock, flags);
/*
* double check to avoid rotting packet
*/
if (pAd->int_pending & FifoStaFullInt)
{
tasklet_hi_schedule(&pObj->fifo_statistic_full_task);
RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
return;
}
/* enable RxINT again */
rt2860_int_enable(pAd, FifoStaFullInt);
RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
}
static void ac3_dma_done_tasklet(unsigned long data)
{
unsigned long flags;
PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
INT_SOURCE_CSR_STRUC IntSource;
POS_COOKIE pObj;
BOOLEAN bReschedule = 0;
// Do nothing if the driver is starting halt state.
// This might happen when timer already been fired before cancel timer with mlmehalt
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
return;
pObj = (POS_COOKIE) pAd->OS_Cookie;
// printk("ac0_dma_done_process\n");
IntSource.word = 0;
IntSource.field.Ac3DmaDone = 1;
pAd->int_pending &= ~INT_AC3_DLY;
bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
RTMP_INT_LOCK(&pAd->irq_lock, flags);
/*
* double check to avoid lose of interrupts
*/
if ((pAd->int_pending & INT_AC3_DLY) || bReschedule)
{
tasklet_hi_schedule(&pObj->ac3_dma_done_task);
RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
return;
}
/* enable TxDataInt again */
rt2860_int_enable(pAd, INT_AC3_DLY);
RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
}
static void ac2_dma_done_tasklet(unsigned long data)
{
unsigned long flags;
PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
INT_SOURCE_CSR_STRUC IntSource;
POS_COOKIE pObj;
BOOLEAN bReschedule = 0;
// Do nothing if the driver is starting halt state.
// This might happen when timer already been fired before cancel timer with mlmehalt
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
return;
pObj = (POS_COOKIE) pAd->OS_Cookie;
IntSource.word = 0;
IntSource.field.Ac2DmaDone = 1;
pAd->int_pending &= ~INT_AC2_DLY;
bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
RTMP_INT_LOCK(&pAd->irq_lock, flags);
/*
* double check to avoid lose of interrupts
*/
if ((pAd->int_pending & INT_AC2_DLY) || bReschedule)
{
tasklet_hi_schedule(&pObj->ac2_dma_done_task);
RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
return;
}
/* enable TxDataInt again */
rt2860_int_enable(pAd, INT_AC2_DLY);
RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
}
static void ac1_dma_done_tasklet(unsigned long data)
{
unsigned long flags;
PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
INT_SOURCE_CSR_STRUC IntSource;
POS_COOKIE pObj;
BOOLEAN bReschedule = 0;
// Do nothing if the driver is starting halt state.
// This might happen when timer already been fired before cancel timer with mlmehalt
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
return;
pObj = (POS_COOKIE) pAd->OS_Cookie;
// printk("ac0_dma_done_process\n");
IntSource.word = 0;
IntSource.field.Ac1DmaDone = 1;
pAd->int_pending &= ~INT_AC1_DLY;
bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
RTMP_INT_LOCK(&pAd->irq_lock, flags);
/*
* double check to avoid lose of interrupts
*/
if ((pAd->int_pending & INT_AC1_DLY) || bReschedule)
{
tasklet_hi_schedule(&pObj->ac1_dma_done_task);
RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
return;
}
/* enable TxDataInt again */
rt2860_int_enable(pAd, INT_AC1_DLY);
RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
}
static void ac0_dma_done_tasklet(unsigned long data)
{
unsigned long flags;
PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
INT_SOURCE_CSR_STRUC IntSource;
POS_COOKIE pObj;
BOOLEAN bReschedule = 0;
// Do nothing if the driver is starting halt state.
// This might happen when timer already been fired before cancel timer with mlmehalt
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
return;
pObj = (POS_COOKIE) pAd->OS_Cookie;
// printk("ac0_dma_done_process\n");
IntSource.word = 0;
IntSource.field.Ac0DmaDone = 1;
pAd->int_pending &= ~INT_AC0_DLY;
// RTMPHandleMgmtRingDmaDoneInterrupt(pAd);
bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
RTMP_INT_LOCK(&pAd->irq_lock, flags);
/*
* double check to avoid lose of interrupts
*/
if ((pAd->int_pending & INT_AC0_DLY) || bReschedule)
{
tasklet_hi_schedule(&pObj->ac0_dma_done_task);
RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
return;
}
/* enable TxDataInt again */
rt2860_int_enable(pAd, INT_AC0_DLY);
RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
}
/***************************************************************************
*
* interrupt handler related procedures.
*
**************************************************************************/
int print_int_count;
IRQ_HANDLE_TYPE
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19))
rt2860_interrupt(int irq, void *dev_instance)
#else
rt2860_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
#endif
{
struct net_device *net_dev = (struct net_device *) dev_instance;
PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) RTMP_OS_NETDEV_GET_PRIV(net_dev);
INT_SOURCE_CSR_STRUC IntSource;
POS_COOKIE pObj;
pObj = (POS_COOKIE) pAd->OS_Cookie;
/* Note 03312008: we can not return here before
RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IntSource.word);
RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, IntSource.word);
Or kernel will panic after ifconfig ra0 down sometimes */
//
// Inital the Interrupt source.
//
IntSource.word = 0x00000000L;
// McuIntSource.word = 0x00000000L;
//
// Get the interrupt sources & saved to local variable
//
//RTMP_IO_READ32(pAd, where, &McuIntSource.word);
//RTMP_IO_WRITE32(pAd, , McuIntSource.word);
//
// Flag fOP_STATUS_DOZE On, means ASIC put to sleep, elase means ASICK WakeUp
// And at the same time, clock maybe turned off that say there is no DMA service.
// when ASIC get to sleep.
// To prevent system hang on power saving.
// We need to check it before handle the INT_SOURCE_CSR, ASIC must be wake up.
//
// RT2661 => when ASIC is sleeping, MAC register cannot be read and written.
// RT2860 => when ASIC is sleeping, MAC register can be read and written.
// if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
{
RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IntSource.word);
RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, IntSource.word); // write 1 to clear
}
// else
// DBGPRINT(RT_DEBUG_TRACE, (">>>fOP_STATUS_DOZE<<<\n"));
// RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IsrAfterClear);
// RTMP_IO_READ32(pAd, MCU_INT_SOURCE_CSR, &McuIsrAfterClear);
// DBGPRINT(RT_DEBUG_INFO, ("====> RTMPHandleInterrupt(ISR=%08x,Mcu ISR=%08x, After clear ISR=%08x, MCU ISR=%08x)\n",
// IntSource.word, McuIntSource.word, IsrAfterClear, McuIsrAfterClear));
// Do nothing if Reset in progress
if (RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |fRTMP_ADAPTER_HALT_IN_PROGRESS)))
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
return IRQ_HANDLED;
#else
return;
#endif
}
//
// Handle interrupt, walk through all bits
// Should start from highest priority interrupt
// The priority can be adjust by altering processing if statement
//
#ifdef DBG
#endif
pAd->bPCIclkOff = FALSE;
// If required spinlock, each interrupt service routine has to acquire
// and release itself.
//
// Do nothing if NIC doesn't exist
if (IntSource.word == 0xffffffff)
{
RTMP_SET_FLAG(pAd, (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS));
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
return IRQ_HANDLED;
#else
return;
#endif
}
if (IntSource.word & TxCoherent)
{
DBGPRINT(RT_DEBUG_ERROR, (">>>TxCoherent<<<\n"));
RTMPHandleRxCoherentInterrupt(pAd);
}
if (IntSource.word & RxCoherent)
{
DBGPRINT(RT_DEBUG_ERROR, (">>>RxCoherent<<<\n"));
RTMPHandleRxCoherentInterrupt(pAd);
}
if (IntSource.word & FifoStaFullInt)
{
if ((pAd->int_disable_mask & FifoStaFullInt) == 0)
{
/* mask FifoStaFullInt */
rt2860_int_disable(pAd, FifoStaFullInt);
tasklet_hi_schedule(&pObj->fifo_statistic_full_task);
}
pAd->int_pending |= FifoStaFullInt;
}
if (IntSource.word & INT_MGMT_DLY)
{
if ((pAd->int_disable_mask & INT_MGMT_DLY) ==0 )
{
rt2860_int_disable(pAd, INT_MGMT_DLY);
tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
}
pAd->int_pending |= INT_MGMT_DLY ;
}
if (IntSource.word & INT_RX)
{
if ((pAd->int_disable_mask & INT_RX) == 0)
{
/* mask RxINT */
rt2860_int_disable(pAd, INT_RX);
tasklet_hi_schedule(&pObj->rx_done_task);
}
pAd->int_pending |= INT_RX;
}
if (IntSource.word & INT_AC3_DLY)
{
if ((pAd->int_disable_mask & INT_AC3_DLY) == 0)
{
/* mask TxDataInt */
rt2860_int_disable(pAd, INT_AC3_DLY);
tasklet_hi_schedule(&pObj->ac3_dma_done_task);
}
pAd->int_pending |= INT_AC3_DLY;
}
if (IntSource.word & INT_AC2_DLY)
{
if ((pAd->int_disable_mask & INT_AC2_DLY) == 0)
{
/* mask TxDataInt */
rt2860_int_disable(pAd, INT_AC2_DLY);
tasklet_hi_schedule(&pObj->ac2_dma_done_task);
}
pAd->int_pending |= INT_AC2_DLY;
}
if (IntSource.word & INT_AC1_DLY)
{
pAd->int_pending |= INT_AC1_DLY;
if ((pAd->int_disable_mask & INT_AC1_DLY) == 0)
{
/* mask TxDataInt */
rt2860_int_disable(pAd, INT_AC1_DLY);
tasklet_hi_schedule(&pObj->ac1_dma_done_task);
}
}
if (IntSource.word & INT_AC0_DLY)
{
/*
if (IntSource.word & 0x2) {
u32 reg;
RTMP_IO_READ32(pAd, DELAY_INT_CFG, &reg);
printk("IntSource.word = %08x, DELAY_REG = %08x\n", IntSource.word, reg);
}
*/
pAd->int_pending |= INT_AC0_DLY;
if ((pAd->int_disable_mask & INT_AC0_DLY) == 0)
{
/* mask TxDataInt */
rt2860_int_disable(pAd, INT_AC0_DLY);
tasklet_hi_schedule(&pObj->ac0_dma_done_task);
}
}
if (IntSource.word & PreTBTTInt)
{
RTMPHandlePreTBTTInterrupt(pAd);
}
if (IntSource.word & TBTTInt)
{
RTMPHandleTBTTInterrupt(pAd);
}
#ifdef CONFIG_STA_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
{
if (IntSource.word & AutoWakeupInt)
RTMPHandleTwakeupInterrupt(pAd);
}
#endif // CONFIG_STA_SUPPORT //
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
return IRQ_HANDLED;
#endif
}
/*
* invaild or writeback cache
* and convert virtual address to physical address
*/
dma_addr_t linux_pci_map_single(void *handle, void *ptr, size_t size, int sd_idx, int direction)
{
PRTMP_ADAPTER pAd;
POS_COOKIE pObj;
/*
------ Porting Information ------
> For Tx Alloc:
mgmt packets => sd_idx = 0
SwIdx: pAd->MgmtRing.TxCpuIdx
pTxD : pAd->MgmtRing.Cell[SwIdx].AllocVa;
data packets => sd_idx = 1
TxIdx : pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx
QueIdx: pTxBlk->QueIdx
pTxD : pAd->TxRing[pTxBlk->QueIdx].Cell[TxIdx].AllocVa;
> For Rx Alloc:
sd_idx = -1
*/
pAd = (PRTMP_ADAPTER)handle;
pObj = (POS_COOKIE)pAd->OS_Cookie;
if (sd_idx == 1)
{
PTX_BLK pTxBlk;
pTxBlk = (PTX_BLK)ptr;
return pci_map_single(pObj->pci_dev, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen, direction);
}
else
{
return pci_map_single(pObj->pci_dev, ptr, size, direction);
}
}
void linux_pci_unmap_single(void *handle, dma_addr_t dma_addr, size_t size, int direction)
{
PRTMP_ADAPTER pAd;
POS_COOKIE pObj;
pAd=(PRTMP_ADAPTER)handle;
pObj = (POS_COOKIE)pAd->OS_Cookie;
pci_unmap_single(pObj->pci_dev, dma_addr, size, direction);
}

View file

@ -0,0 +1,101 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
rt_profile.c
Abstract:
Revision History:
Who When What
--------- ---------- ----------------------------------------------
*/
#include "rt_config.h"
NDIS_STATUS RTMPReadParametersHook(
IN PRTMP_ADAPTER pAd)
{
PSTRING src = NULL;
RTMP_OS_FD srcf;
RTMP_OS_FS_INFO osFSInfo;
INT retval = NDIS_STATUS_FAILURE;
PSTRING buffer;
buffer = kmalloc(MAX_INI_BUFFER_SIZE, MEM_ALLOC_FLAG);
if(buffer == NULL)
return NDIS_STATUS_FAILURE;
memset(buffer, 0x00, MAX_INI_BUFFER_SIZE);
{
#ifdef CONFIG_STA_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
{
src = STA_PROFILE_PATH;
}
#endif // CONFIG_STA_SUPPORT //
#ifdef MULTIPLE_CARD_SUPPORT
src = (PSTRING)pAd->MC_FileName;
#endif // MULTIPLE_CARD_SUPPORT //
}
if (src && *src)
{
RtmpOSFSInfoChange(&osFSInfo, TRUE);
srcf = RtmpOSFileOpen(src, O_RDONLY, 0);
if (IS_FILE_OPEN_ERR(srcf))
{
DBGPRINT(RT_DEBUG_ERROR, ("Open file \"%s\" failed!\n", src));
}
else
{
retval =RtmpOSFileRead(srcf, buffer, MAX_INI_BUFFER_SIZE);
if (retval > 0)
{
RTMPSetProfileParameters(pAd, buffer);
retval = NDIS_STATUS_SUCCESS;
}
else
DBGPRINT(RT_DEBUG_ERROR, ("Read file \"%s\" failed(errCode=%d)!\n", src, retval));
retval = RtmpOSFileClose(srcf);
if ( retval != 0)
{
retval = NDIS_STATUS_FAILURE;
DBGPRINT(RT_DEBUG_ERROR, ("Close file \"%s\" failed(errCode=%d)!\n", src, retval));
}
}
RtmpOSFSInfoChange(&osFSInfo, FALSE);
}
kfree(buffer);
return (retval);
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,355 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
rtmp_chip.h
Abstract:
Ralink Wireless Chip related definition & structures
Revision History:
Who When What
-------- ---------- ----------------------------------------------
*/
#ifndef __RTMP_CHIP_H__
#define __RTMP_CHIP_H__
#include "rtmp_type.h"
#ifdef RT3090
#include "rt3090.h"
#endif // RT3090 //
#ifdef RT3370
#include "rt3370.h"
#endif // RT3370 //
#ifdef RT3390
#include "rt3390.h"
#endif // RT3390 //
// We will have a cost down version which mac version is 0x3090xxxx
//
// RT3090A facts
//
// a) 2.4 GHz
// b) Replacement for RT3090
// c) Internal LNA
// d) Interference over channel #14
// e) New BBP features (e.g., SIG re-modulation)
//
#define IS_RT3090A(_pAd) ((((_pAd)->MACVersion & 0xffff0000) == 0x30900000))
// We will have a cost down version which mac version is 0x3090xxxx
#define IS_RT3090(_pAd) ((((_pAd)->MACVersion & 0xffff0000) == 0x30710000) || (IS_RT3090A(_pAd)))
#define IS_RT3070(_pAd) (((_pAd)->MACVersion & 0xffff0000) == 0x30700000)
#define IS_RT3071(_pAd) (((_pAd)->MACVersion & 0xffff0000) == 0x30710000)
#define IS_RT2070(_pAd) (((_pAd)->RfIcType == RFIC_2020) || ((_pAd)->EFuseTag == 0x27))
#define IS_RT30xx(_pAd) (((_pAd)->MACVersion & 0xfff00000) == 0x30700000||IS_RT3090A(_pAd))
//#define IS_RT305X(_pAd) ((_pAd)->MACVersion == 0x28720200)
/* RT3572, 3592, 3562, 3062 share the same MAC version */
#define IS_RT3572(_pAd) (((_pAd)->MACVersion & 0xffff0000) == 0x35720000)
#define IS_VERSION_BEFORE_F(_pAd) (((_pAd)->MACVersion&0xffff) <= 0x0211)
// F version is 0x0212, E version is 0x0211. 309x can save more power after F version.
#define IS_VERSION_AFTER_F(_pAd) ((((_pAd)->MACVersion&0xffff) >= 0x0212) || (((_pAd)->b3090ESpecialChip == TRUE)))
//
// RT3390 facts
//
// a) Base on RT3090 (RF IC: RT3020)
// b) 2.4 GHz
// c) 1x1
// d) Single chip
// e) Internal components: PA and LNA
//
//RT3390,RT3370
#define IS_RT3390(_pAd) (((_pAd)->MACVersion & 0xFFFF0000) == 0x33900000)
// ------------------------------------------------------
// PCI registers - base address 0x0000
// ------------------------------------------------------
#define CHIP_PCI_CFG 0x0000
#define CHIP_PCI_EECTRL 0x0004
#define CHIP_PCI_MCUCTRL 0x0008
#define OPT_14 0x114
#define RETRY_LIMIT 10
// ------------------------------------------------------
// BBP & RF definition
// ------------------------------------------------------
#define BUSY 1
#define IDLE 0
//-------------------------------------------------------------------------
// EEPROM definition
//-------------------------------------------------------------------------
#define EEDO 0x08
#define EEDI 0x04
#define EECS 0x02
#define EESK 0x01
#define EERL 0x80
#define EEPROM_WRITE_OPCODE 0x05
#define EEPROM_READ_OPCODE 0x06
#define EEPROM_EWDS_OPCODE 0x10
#define EEPROM_EWEN_OPCODE 0x13
#define NUM_EEPROM_BBP_PARMS 19 // Include NIC Config 0, 1, CR, TX ALC step, BBPs
#define NUM_EEPROM_TX_G_PARMS 7
#define EEPROM_NIC1_OFFSET 0x34 // The address is from NIC config 0, not BBP register ID
#define EEPROM_NIC2_OFFSET 0x36 // The address is from NIC config 0, not BBP register ID
#define EEPROM_BBP_BASE_OFFSET 0xf0 // The address is from NIC config 0, not BBP register ID
#define EEPROM_G_TX_PWR_OFFSET 0x52
#define EEPROM_G_TX2_PWR_OFFSET 0x60
#define EEPROM_LED1_OFFSET 0x3c
#define EEPROM_LED2_OFFSET 0x3e
#define EEPROM_LED3_OFFSET 0x40
#define EEPROM_LNA_OFFSET 0x44
#define EEPROM_RSSI_BG_OFFSET 0x46
#define EEPROM_TXMIXER_GAIN_2_4G 0x48
#define EEPROM_RSSI_A_OFFSET 0x4a
#define EEPROM_TXMIXER_GAIN_5G 0x4c
#define EEPROM_DEFINE_MAX_TXPWR 0x4e
#define EEPROM_TXPOWER_BYRATE_20MHZ_2_4G 0xde // 20MHZ 2.4G tx power.
#define EEPROM_TXPOWER_BYRATE_40MHZ_2_4G 0xee // 40MHZ 2.4G tx power.
#define EEPROM_TXPOWER_BYRATE_20MHZ_5G 0xfa // 20MHZ 5G tx power.
#define EEPROM_TXPOWER_BYRATE_40MHZ_5G 0x10a // 40MHZ 5G tx power.
#define EEPROM_A_TX_PWR_OFFSET 0x78
#define EEPROM_A_TX2_PWR_OFFSET 0xa6
//#define EEPROM_Japan_TX_PWR_OFFSET 0x90 // 802.11j
//#define EEPROM_Japan_TX2_PWR_OFFSET 0xbe
//#define EEPROM_TSSI_REF_OFFSET 0x54
//#define EEPROM_TSSI_DELTA_OFFSET 0x24
//#define EEPROM_CCK_TX_PWR_OFFSET 0x62
//#define EEPROM_CALIBRATE_OFFSET 0x7c
#define EEPROM_VERSION_OFFSET 0x02
#define EEPROM_FREQ_OFFSET 0x3a
#define EEPROM_TXPOWER_BYRATE 0xde // 20MHZ power.
#define EEPROM_TXPOWER_DELTA 0x50 // 20MHZ AND 40 MHZ use different power. This is delta in 40MHZ.
#define VALID_EEPROM_VERSION 1
/*
* EEPROM operation related marcos
*/
#define RT28xx_EEPROM_READ16(_pAd, _offset, _value) \
(_pAd)->chipOps.eeread((RTMP_ADAPTER *)(_pAd), (USHORT)(_offset), (PUSHORT)&(_value))
#define RT28xx_EEPROM_WRITE16(_pAd, _offset, _value) \
(_pAd)->chipOps.eewrite((RTMP_ADAPTER *)(_pAd), (USHORT)(_offset), (USHORT)(_value))
// -------------------------------------------------------------------
// E2PROM data layout
// -------------------------------------------------------------------
//
// MCU_LEDCS: MCU LED Control Setting.
//
typedef union _MCU_LEDCS_STRUC {
struct {
#ifdef RT_BIG_ENDIAN
UCHAR Polarity:1;
UCHAR LedMode:7;
#else
UCHAR LedMode:7;
UCHAR Polarity:1;
#endif // RT_BIG_ENDIAN //
} field;
UCHAR word;
} MCU_LEDCS_STRUC, *PMCU_LEDCS_STRUC;
//
// EEPROM antenna select format
//
#ifdef RT_BIG_ENDIAN
typedef union _EEPROM_ANTENNA_STRUC {
struct {
USHORT Rsv:4;
USHORT RfIcType:4; // see E2PROM document
USHORT TxPath:4; // 1: 1T, 2: 2T
USHORT RxPath:4; // 1: 1R, 2: 2R, 3: 3R
} field;
USHORT word;
} EEPROM_ANTENNA_STRUC, *PEEPROM_ANTENNA_STRUC;
#else
typedef union _EEPROM_ANTENNA_STRUC {
struct {
USHORT RxPath:4; // 1: 1R, 2: 2R, 3: 3R
USHORT TxPath:4; // 1: 1T, 2: 2T
USHORT RfIcType:4; // see E2PROM document
USHORT Rsv:4;
} field;
USHORT word;
} EEPROM_ANTENNA_STRUC, *PEEPROM_ANTENNA_STRUC;
#endif
#ifdef RT_BIG_ENDIAN
typedef union _EEPROM_NIC_CINFIG2_STRUC {
struct {
USHORT DACTestBit:1; // control if driver should patch the DAC issue
USHORT Rsv2:3; // must be 0
USHORT AntDiversity:1; // Antenna diversity
USHORT Rsv1:1; // must be 0
USHORT BW40MAvailForA:1; // 0:enable, 1:disable
USHORT BW40MAvailForG:1; // 0:enable, 1:disable
USHORT EnableWPSPBC:1; // WPS PBC Control bit
USHORT BW40MSidebandForA:1;
USHORT BW40MSidebandForG:1;
USHORT CardbusAcceleration:1; // !!! NOTE: 0 - enable, 1 - disable
USHORT ExternalLNAForA:1; // external LNA enable for 5G
USHORT ExternalLNAForG:1; // external LNA enable for 2.4G
USHORT DynamicTxAgcControl:1; //
USHORT HardwareRadioControl:1; // Whether RF is controlled by driver or HW. 1:enable hw control, 0:disable
} field;
USHORT word;
} EEPROM_NIC_CONFIG2_STRUC, *PEEPROM_NIC_CONFIG2_STRUC;
#else
typedef union _EEPROM_NIC_CINFIG2_STRUC {
struct {
USHORT HardwareRadioControl:1; // 1:enable, 0:disable
USHORT DynamicTxAgcControl:1; //
USHORT ExternalLNAForG:1; //
USHORT ExternalLNAForA:1; // external LNA enable for 2.4G
USHORT CardbusAcceleration:1; // !!! NOTE: 0 - enable, 1 - disable
USHORT BW40MSidebandForG:1;
USHORT BW40MSidebandForA:1;
USHORT EnableWPSPBC:1; // WPS PBC Control bit
USHORT BW40MAvailForG:1; // 0:enable, 1:disable
USHORT BW40MAvailForA:1; // 0:enable, 1:disable
USHORT Rsv1:1; // must be 0
USHORT AntDiversity:1; // Antenna diversity
USHORT Rsv2:3; // must be 0
USHORT DACTestBit:1; // control if driver should patch the DAC issue
} field;
USHORT word;
} EEPROM_NIC_CONFIG2_STRUC, *PEEPROM_NIC_CONFIG2_STRUC;
#endif
//
// TX_PWR Value valid range 0xFA(-6) ~ 0x24(36)
//
#ifdef RT_BIG_ENDIAN
typedef union _EEPROM_TX_PWR_STRUC {
struct {
CHAR Byte1; // High Byte
CHAR Byte0; // Low Byte
} field;
USHORT word;
} EEPROM_TX_PWR_STRUC, *PEEPROM_TX_PWR_STRUC;
#else
typedef union _EEPROM_TX_PWR_STRUC {
struct {
CHAR Byte0; // Low Byte
CHAR Byte1; // High Byte
} field;
USHORT word;
} EEPROM_TX_PWR_STRUC, *PEEPROM_TX_PWR_STRUC;
#endif
#ifdef RT_BIG_ENDIAN
typedef union _EEPROM_VERSION_STRUC {
struct {
UCHAR Version; // High Byte
UCHAR FaeReleaseNumber; // Low Byte
} field;
USHORT word;
} EEPROM_VERSION_STRUC, *PEEPROM_VERSION_STRUC;
#else
typedef union _EEPROM_VERSION_STRUC {
struct {
UCHAR FaeReleaseNumber; // Low Byte
UCHAR Version; // High Byte
} field;
USHORT word;
} EEPROM_VERSION_STRUC, *PEEPROM_VERSION_STRUC;
#endif
#ifdef RT_BIG_ENDIAN
typedef union _EEPROM_LED_STRUC {
struct {
USHORT Rsvd:3; // Reserved
USHORT LedMode:5; // Led mode.
USHORT PolarityGPIO_4:1; // Polarity GPIO#4 setting.
USHORT PolarityGPIO_3:1; // Polarity GPIO#3 setting.
USHORT PolarityGPIO_2:1; // Polarity GPIO#2 setting.
USHORT PolarityGPIO_1:1; // Polarity GPIO#1 setting.
USHORT PolarityGPIO_0:1; // Polarity GPIO#0 setting.
USHORT PolarityACT:1; // Polarity ACT setting.
USHORT PolarityRDY_A:1; // Polarity RDY_A setting.
USHORT PolarityRDY_G:1; // Polarity RDY_G setting.
} field;
USHORT word;
} EEPROM_LED_STRUC, *PEEPROM_LED_STRUC;
#else
typedef union _EEPROM_LED_STRUC {
struct {
USHORT PolarityRDY_G:1; // Polarity RDY_G setting.
USHORT PolarityRDY_A:1; // Polarity RDY_A setting.
USHORT PolarityACT:1; // Polarity ACT setting.
USHORT PolarityGPIO_0:1; // Polarity GPIO#0 setting.
USHORT PolarityGPIO_1:1; // Polarity GPIO#1 setting.
USHORT PolarityGPIO_2:1; // Polarity GPIO#2 setting.
USHORT PolarityGPIO_3:1; // Polarity GPIO#3 setting.
USHORT PolarityGPIO_4:1; // Polarity GPIO#4 setting.
USHORT LedMode:5; // Led mode.
USHORT Rsvd:3; // Reserved
} field;
USHORT word;
} EEPROM_LED_STRUC, *PEEPROM_LED_STRUC;
#endif
#ifdef RT_BIG_ENDIAN
typedef union _EEPROM_TXPOWER_DELTA_STRUC {
struct {
UCHAR TxPowerEnable:1;// Enable
UCHAR Type:1; // 1: plus the delta value, 0: minus the delta value
UCHAR DeltaValue:6; // Tx Power dalta value (MAX=4)
} field;
UCHAR value;
} EEPROM_TXPOWER_DELTA_STRUC, *PEEPROM_TXPOWER_DELTA_STRUC;
#else
typedef union _EEPROM_TXPOWER_DELTA_STRUC {
struct {
UCHAR DeltaValue:6; // Tx Power dalta value (MAX=4)
UCHAR Type:1; // 1: plus the delta value, 0: minus the delta value
UCHAR TxPowerEnable:1;// Enable
} field;
UCHAR value;
} EEPROM_TXPOWER_DELTA_STRUC, *PEEPROM_TXPOWER_DELTA_STRUC;
#endif
#endif // __RTMP_CHIP_H__ //

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,146 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
*/
#ifndef __DOT11_BASE_H__
#define __DOT11_BASE_H__
#include "rtmp_type.h"
// 4-byte HTC field. maybe included in any frame except non-QOS data frame. The Order bit must set 1.
typedef struct PACKED {
#ifdef RT_BIG_ENDIAN
UINT32 RDG:1; //RDG / More PPDU
UINT32 ACConstraint:1; //feedback request
UINT32 rsv:5; //calibration sequence
UINT32 ZLFAnnouce:1; // ZLF announcement
UINT32 CSISTEERING:2; //CSI/ STEERING
UINT32 FBKReq:2; //feedback request
UINT32 CalSeq:2; //calibration sequence
UINT32 CalPos:2; // calibration position
UINT32 MFBorASC:7; //Link adaptation feedback containing recommended MCS. 0x7f for no feedback or not available
UINT32 MFS:3; //SET to the received value of MRS. 0x111 for unsolicited MFB.
UINT32 MRSorASI:3; // MRQ Sequence identifier. unchanged during entire procedure. 0x000-0x110.
UINT32 MRQ:1; //MCS feedback. Request for a MCS feedback
UINT32 TRQ:1; //sounding request
UINT32 MA:1; //management action payload exist in (QoS Null+HTC)
#else
UINT32 MA:1; //management action payload exist in (QoS Null+HTC)
UINT32 TRQ:1; //sounding request
UINT32 MRQ:1; //MCS feedback. Request for a MCS feedback
UINT32 MRSorASI:3; // MRQ Sequence identifier. unchanged during entire procedure. 0x000-0x110.
UINT32 MFS:3; //SET to the received value of MRS. 0x111 for unsolicited MFB.
UINT32 MFBorASC:7; //Link adaptation feedback containing recommended MCS. 0x7f for no feedback or not available
UINT32 CalPos:2; // calibration position
UINT32 CalSeq:2; //calibration sequence
UINT32 FBKReq:2; //feedback request
UINT32 CSISTEERING:2; //CSI/ STEERING
UINT32 ZLFAnnouce:1; // ZLF announcement
UINT32 rsv:5; //calibration sequence
UINT32 ACConstraint:1; //feedback request
UINT32 RDG:1; //RDG / More PPDU
#endif /* !RT_BIG_ENDIAN */
} HT_CONTROL, *PHT_CONTROL;
// 2-byte QOS CONTROL field
typedef struct PACKED {
#ifdef RT_BIG_ENDIAN
USHORT Txop_QueueSize:8;
USHORT AMsduPresent:1;
USHORT AckPolicy:2; //0: normal ACK 1:No ACK 2:scheduled under MTBA/PSMP 3: BA
USHORT EOSP:1;
USHORT TID:4;
#else
USHORT TID:4;
USHORT EOSP:1;
USHORT AckPolicy:2; //0: normal ACK 1:No ACK 2:scheduled under MTBA/PSMP 3: BA
USHORT AMsduPresent:1;
USHORT Txop_QueueSize:8;
#endif /* !RT_BIG_ENDIAN */
} QOS_CONTROL, *PQOS_CONTROL;
// 2-byte Frame control field
typedef struct PACKED {
#ifdef RT_BIG_ENDIAN
USHORT Order:1; // Strict order expected
USHORT Wep:1; // Wep data
USHORT MoreData:1; // More data bit
USHORT PwrMgmt:1; // Power management bit
USHORT Retry:1; // Retry status bit
USHORT MoreFrag:1; // More fragment bit
USHORT FrDs:1; // From DS indication
USHORT ToDs:1; // To DS indication
USHORT SubType:4; // MSDU subtype
USHORT Type:2; // MSDU type
USHORT Ver:2; // Protocol version
#else
USHORT Ver:2; // Protocol version
USHORT Type:2; // MSDU type
USHORT SubType:4; // MSDU subtype
USHORT ToDs:1; // To DS indication
USHORT FrDs:1; // From DS indication
USHORT MoreFrag:1; // More fragment bit
USHORT Retry:1; // Retry status bit
USHORT PwrMgmt:1; // Power management bit
USHORT MoreData:1; // More data bit
USHORT Wep:1; // Wep data
USHORT Order:1; // Strict order expected
#endif /* !RT_BIG_ENDIAN */
} FRAME_CONTROL, *PFRAME_CONTROL;
typedef struct PACKED _HEADER_802_11 {
FRAME_CONTROL FC;
USHORT Duration;
UCHAR Addr1[MAC_ADDR_LEN];
UCHAR Addr2[MAC_ADDR_LEN];
UCHAR Addr3[MAC_ADDR_LEN];
#ifdef RT_BIG_ENDIAN
USHORT Sequence:12;
USHORT Frag:4;
#else
USHORT Frag:4;
USHORT Sequence:12;
#endif /* !RT_BIG_ENDIAN */
UCHAR Octet[0];
} HEADER_802_11, *PHEADER_802_11;
typedef struct PACKED _PSPOLL_FRAME {
FRAME_CONTROL FC;
USHORT Aid;
UCHAR Bssid[MAC_ADDR_LEN];
UCHAR Ta[MAC_ADDR_LEN];
} PSPOLL_FRAME, *PPSPOLL_FRAME;
typedef struct PACKED _RTS_FRAME {
FRAME_CONTROL FC;
USHORT Duration;
UCHAR Addr1[MAC_ADDR_LEN];
UCHAR Addr2[MAC_ADDR_LEN];
}RTS_FRAME, *PRTS_FRAME;
#endif // __DOT11_BASE_H__ //

View file

@ -0,0 +1,81 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
rt_iface.h
Abstract:
Revision History:
Who When What
--------- ---------- ----------------------------------------------
*/
#ifndef __RTMP_IFACE_H__
#define __RTMP_IFACE_H__
#ifdef RTMP_PCI_SUPPORT
#include "rtmp_pci.h"
#endif // RTMP_PCI_SUPPORT //
typedef struct _INF_PCI_CONFIG_
{
unsigned long CSRBaseAddress; // PCI MMIO Base Address, all access will use
unsigned int irq_num;
}INF_PCI_CONFIG;
typedef struct _INF_USB_CONFIG_
{
UINT8 BulkInEpAddr; // bulk-in endpoint address
UINT8 BulkOutEpAddr[6]; // bulk-out endpoint address
}INF_USB_CONFIG;
typedef struct _INF_RBUS_CONFIG_
{
unsigned long csr_addr;
unsigned int irq;
}INF_RBUS_CONFIG;
typedef enum _RTMP_INF_TYPE_
{
RTMP_DEV_INF_UNKNOWN = 0,
RTMP_DEV_INF_PCI = 1,
RTMP_DEV_INF_USB = 2,
RTMP_DEV_INF_RBUS = 4,
}RTMP_INF_TYPE;
typedef union _RTMP_INF_CONFIG_{
struct _INF_PCI_CONFIG_ pciConfig;
struct _INF_USB_CONFIG_ usbConfig;
struct _INF_RBUS_CONFIG_ rbusConfig;
}RTMP_INF_CONFIG;
#endif // __RTMP_IFACE_H__ //

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,55 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
rtmp_mcu.h
Abstract:
Miniport header file for mcu related information
Revision History:
Who When What
-------- ---------- ----------------------------------------------
*/
#ifndef __RTMP_MCU_H__
#define __RTMP_MCU_H__
INT RtmpAsicEraseFirmware(
IN PRTMP_ADAPTER pAd);
NDIS_STATUS RtmpAsicLoadFirmware(
IN PRTMP_ADAPTER pAd);
INT RtmpAsicSendCommandToMcu(
IN PRTMP_ADAPTER pAd,
IN UCHAR Command,
IN UCHAR Token,
IN UCHAR Arg0,
IN UCHAR Arg1);
#endif // __RTMP_MCU_H__ //

View file

@ -0,0 +1,93 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
rtmp_os.h
Abstract:
Revision History:
Who When What
--------- ---------- ----------------------------------------------
*/
#ifndef __RTMP_OS_H__
#define __RTMP_OS_H__
#ifdef LINUX
#include "rt_linux.h"
#endif // LINUX //
/*
This data structure mainly strip some callback function defined in
"struct net_device" in kernel source "include/linux/netdevice.h".
The definition of this data structure may various depends on different
OS. Use it carefully.
*/
typedef struct _RTMP_OS_NETDEV_OP_HOOK_
{
const struct net_device_ops *netdev_ops;
void *priv;
int priv_flags;
unsigned char devAddr[6];
unsigned char devName[16];
unsigned char needProtcted;
}RTMP_OS_NETDEV_OP_HOOK, *PRTMP_OS_NETDEV_OP_HOOK;
typedef enum _RTMP_TASK_STATUS_
{
RTMP_TASK_STAT_UNKNOWN = 0,
RTMP_TASK_STAT_INITED = 1,
RTMP_TASK_STAT_RUNNING = 2,
RTMP_TASK_STAT_STOPED = 4,
}RTMP_TASK_STATUS;
#define RTMP_TASK_CAN_DO_INSERT (RTMP_TASK_STAT_INITED |RTMP_TASK_STAT_RUNNING)
#define RTMP_OS_TASK_NAME_LEN 16
typedef struct _RTMP_OS_TASK_
{
char taskName[RTMP_OS_TASK_NAME_LEN];
void *priv;
//unsigned long taskFlags;
RTMP_TASK_STATUS taskStatus;
#ifndef KTHREAD_SUPPORT
RTMP_OS_SEM taskSema;
RTMP_OS_PID taskPID;
struct completion taskComplete;
#endif
unsigned char task_killed;
#ifdef KTHREAD_SUPPORT
struct task_struct *kthread_task;
wait_queue_head_t kthread_q;
BOOLEAN kthread_running;
#endif
}RTMP_OS_TASK;
#endif // __RMTP_OS_H__ //

View file

@ -0,0 +1,110 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
*/
#ifndef __RTMP_PCI_H__
#define __RTMP_PCI_H__
#define RT28XX_HANDLE_DEV_ASSIGN(handle, dev_p) \
((POS_COOKIE)handle)->pci_dev = dev_p;
#ifdef LINUX
// set driver data
#define RT28XX_DRVDATA_SET(_a) pci_set_drvdata(_a, net_dev);
#define RT28XX_PUT_DEVICE(dev_p)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
#define SA_SHIRQ IRQF_SHARED
#endif
#ifdef PCI_MSI_SUPPORT
#define RTMP_MSI_ENABLE(_pAd) \
{ POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie); \
(_pAd)->HaveMsi = pci_enable_msi(_pObj->pci_dev) == 0 ? TRUE : FALSE; }
#define RTMP_MSI_DISABLE(_pAd) \
{ POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie); \
if (_pAd->HaveMsi == TRUE) \
pci_disable_msi(_pObj->pci_dev); \
_pAd->HaveMsi = FALSE; }
#else
#define RTMP_MSI_ENABLE(_pAd)
#define RTMP_MSI_DISABLE(_pAd)
#endif // PCI_MSI_SUPPORT //
#define RTMP_PCI_DEV_UNMAP() \
{ if (net_dev->base_addr) { \
iounmap((void *)(net_dev->base_addr)); \
release_mem_region(pci_resource_start(dev_p, 0), \
pci_resource_len(dev_p, 0)); } \
if (net_dev->irq) pci_release_regions(dev_p); }
#define RTMP_IRQ_REQUEST(net_dev) \
{ PRTMP_ADAPTER _pAd = (PRTMP_ADAPTER)(RTMP_OS_NETDEV_GET_PRIV(net_dev)); \
POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie); \
RTMP_MSI_ENABLE(_pAd); \
if ((retval = request_irq(_pObj->pci_dev->irq, \
rt2860_interrupt, SA_SHIRQ, \
(net_dev)->name, (net_dev)))) { \
DBGPRINT(RT_DEBUG_ERROR, ("request_irq error(%d)\n", retval)); \
return retval; } }
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
#define RTMP_IRQ_RELEASE(net_dev) \
{ PRTMP_ADAPTER _pAd = (PRTMP_ADAPTER)(RTMP_OS_NETDEV_GET_PRIV(net_dev)); \
POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie); \
synchronize_irq(_pObj->pci_dev->irq); \
free_irq(_pObj->pci_dev->irq, (net_dev)); \
RTMP_MSI_DISABLE(_pAd); }
#else
#define RTMP_IRQ_RELEASE(net_dev) \
{ PRTMP_ADAPTER _pAd = (PRTMP_ADAPTER)(RTMP_OS_NETDEV_GET_PRIV(net_dev)); \
POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie); \
free_irq(_pObj->pci_dev->irq, (net_dev)); \
RTMP_MSI_DISABLE(_pAd); }
#endif
#define PCI_REG_READ_WORD(pci_dev, offset, Configuration) \
if (pci_read_config_word(pci_dev, offset, &reg16) == 0) \
Configuration = le2cpu16(reg16); \
else \
Configuration = 0;
#define PCI_REG_WIRTE_WORD(pci_dev, offset, Configuration) \
reg16 = cpu2le16(Configuration); \
pci_write_config_word(pci_dev, offset, reg16); \
#endif // LINUX //
#endif // __RTMP_PCI_H__ //

View file

@ -0,0 +1,631 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
rtmp_phy.h
Abstract:
Ralink Wireless Chip PHY(BBP/RF) related definition & structures
Revision History:
Who When What
-------- ---------- ----------------------------------------------
*/
#ifndef __RTMP_PHY_H__
#define __RTMP_PHY_H__
/*
RF sections
*/
#define RF_R00 0
#define RF_R01 1
#define RF_R02 2
#define RF_R03 3
#define RF_R04 4
#define RF_R05 5
#define RF_R06 6
#define RF_R07 7
#define RF_R08 8
#define RF_R09 9
#define RF_R10 10
#define RF_R11 11
#define RF_R12 12
#define RF_R13 13
#define RF_R14 14
#define RF_R15 15
#define RF_R16 16
#define RF_R17 17
#define RF_R18 18
#define RF_R19 19
#define RF_R20 20
#define RF_R21 21
#define RF_R22 22
#define RF_R23 23
#define RF_R24 24
#define RF_R25 25
#define RF_R26 26
#define RF_R27 27
#define RF_R28 28
#define RF_R29 29
#define RF_R30 30
#define RF_R31 31
// value domain of pAd->RfIcType
#define RFIC_2820 1 // 2.4G 2T3R
#define RFIC_2850 2 // 2.4G/5G 2T3R
#define RFIC_2720 3 // 2.4G 1T2R
#define RFIC_2750 4 // 2.4G/5G 1T2R
#define RFIC_3020 5 // 2.4G 1T1R
#define RFIC_2020 6 // 2.4G B/G
#define RFIC_3021 7 // 2.4G 1T2R
#define RFIC_3022 8 // 2.4G 2T2R
#define RFIC_3052 9 // 2.4G/5G 2T2R
/*
BBP sections
*/
#define BBP_R0 0 // version
#define BBP_R1 1 // TSSI
#define BBP_R2 2 // TX configure
#define BBP_R3 3
#define BBP_R4 4
#define BBP_R5 5
#define BBP_R6 6
#define BBP_R14 14 // RX configure
#define BBP_R16 16
#define BBP_R17 17 // RX sensibility
#define BBP_R18 18
#define BBP_R21 21
#define BBP_R22 22
#define BBP_R24 24
#define BBP_R25 25
#define BBP_R26 26
#define BBP_R27 27
#define BBP_R31 31
#define BBP_R49 49 //TSSI
#define BBP_R50 50
#define BBP_R51 51
#define BBP_R52 52
#define BBP_R55 55
#define BBP_R62 62 // Rx SQ0 Threshold HIGH
#define BBP_R63 63
#define BBP_R64 64
#define BBP_R65 65
#define BBP_R66 66
#define BBP_R67 67
#define BBP_R68 68
#define BBP_R69 69
#define BBP_R70 70 // Rx AGC SQ CCK Xcorr threshold
#define BBP_R73 73
#define BBP_R75 75
#define BBP_R77 77
#define BBP_R78 78
#define BBP_R79 79
#define BBP_R80 80
#define BBP_R81 81
#define BBP_R82 82
#define BBP_R83 83
#define BBP_R84 84
#define BBP_R86 86
#define BBP_R91 91
#define BBP_R92 92
#define BBP_R94 94 // Tx Gain Control
#define BBP_R103 103
#define BBP_R105 105
#define BBP_R106 106
#define BBP_R113 113
#define BBP_R114 114
#define BBP_R115 115
#define BBP_R116 116
#define BBP_R117 117
#define BBP_R118 118
#define BBP_R119 119
#define BBP_R120 120
#define BBP_R121 121
#define BBP_R122 122
#define BBP_R123 123
#ifdef RT30xx
#define BBP_R138 138 // add by johnli, RF power sequence setup, ADC dynamic on/off control
#endif // RT30xx //
#define BBPR94_DEFAULT 0x06 // Add 1 value will gain 1db
#ifdef MERGE_ARCH_TEAM
#define MAX_BBP_ID 200
#define MAX_BBP_MSG_SIZE 4096
#else
#ifdef RT30xx
// edit by johnli, RF power sequence setup, add BBP R138 for ADC dynamic on/off control
#define MAX_BBP_ID 138
#endif // RT30xx //
#ifndef RT30xx
#define MAX_BBP_ID 136
#endif // RT30xx //
#define MAX_BBP_MSG_SIZE 2048
#endif // MERGE_ARCH_TEAM //
//
// BBP & RF are using indirect access. Before write any value into it.
// We have to make sure there is no outstanding command pending via checking busy bit.
//
#define MAX_BUSY_COUNT 100 // Number of retry before failing access BBP & RF indirect register
//#define PHY_TR_SWITCH_TIME 5 // usec
//#define BBP_R17_LOW_SENSIBILITY 0x50
//#define BBP_R17_MID_SENSIBILITY 0x41
//#define BBP_R17_DYNAMIC_UP_BOUND 0x40
#define RSSI_FOR_VERY_LOW_SENSIBILITY -35
#define RSSI_FOR_LOW_SENSIBILITY -58
#define RSSI_FOR_MID_LOW_SENSIBILITY -80
#define RSSI_FOR_MID_SENSIBILITY -90
/*****************************************************************************
RF register Read/Write marco definition
*****************************************************************************/
#ifdef RTMP_MAC_PCI
#define RTMP_RF_IO_WRITE32(_A, _V) \
{ \
if ((_A)->bPCIclkOff == FALSE) \
{ \
PHY_CSR4_STRUC _value; \
ULONG _busyCnt = 0; \
\
do { \
RTMP_IO_READ32((_A), RF_CSR_CFG0, &_value.word); \
if (_value.field.Busy == IDLE) \
break; \
_busyCnt++; \
}while (_busyCnt < MAX_BUSY_COUNT); \
if(_busyCnt < MAX_BUSY_COUNT) \
{ \
RTMP_IO_WRITE32((_A), RF_CSR_CFG0, (_V)); \
} \
} \
}
#endif // RTMP_MAC_PCI //
#ifdef RT30xx
#define RTMP_RF_IO_READ8_BY_REG_ID(_A, _I, _pV) RT30xxReadRFRegister(_A, _I, _pV)
#define RTMP_RF_IO_WRITE8_BY_REG_ID(_A, _I, _V) RT30xxWriteRFRegister(_A, _I, _V)
#endif // RT30xx //
/*****************************************************************************
BBP register Read/Write marco definitions.
we read/write the bbp value by register's ID.
Generate PER to test BA
*****************************************************************************/
#ifdef RTMP_MAC_PCI
/*
basic marco for BBP read operation.
_pAd: the data structure pointer of RTMP_ADAPTER
_bbpID : the bbp register ID
_pV: data pointer used to save the value of queried bbp register.
_bViaMCU: if we need access the bbp via the MCU.
*/
#define RTMP_BBP_IO_READ8(_pAd, _bbpID, _pV, _bViaMCU) \
do{ \
BBP_CSR_CFG_STRUC BbpCsr; \
int _busyCnt, _secCnt, _regID; \
\
_regID = ((_bViaMCU) == TRUE ? H2M_BBP_AGENT : BBP_CSR_CFG); \
for (_busyCnt=0; _busyCnt<MAX_BUSY_COUNT; _busyCnt++) \
{ \
RTMP_IO_READ32(_pAd, _regID, &BbpCsr.word); \
if (BbpCsr.field.Busy == BUSY) \
continue; \
BbpCsr.word = 0; \
BbpCsr.field.fRead = 1; \
BbpCsr.field.BBP_RW_MODE = 1; \
BbpCsr.field.Busy = 1; \
BbpCsr.field.RegNum = _bbpID; \
RTMP_IO_WRITE32(_pAd, _regID, BbpCsr.word); \
if ((_bViaMCU) == TRUE) \
{ \
AsicSendCommandToMcu(_pAd, 0x80, 0xff, 0x0, 0x0); \
RTMPusecDelay(1000); \
} \
for (_secCnt=0; _secCnt<MAX_BUSY_COUNT; _secCnt++) \
{ \
RTMP_IO_READ32(_pAd, _regID, &BbpCsr.word); \
if (BbpCsr.field.Busy == IDLE) \
break; \
} \
if ((BbpCsr.field.Busy == IDLE) && \
(BbpCsr.field.RegNum == _bbpID)) \
{ \
*(_pV) = (UCHAR)BbpCsr.field.Value; \
break; \
} \
} \
if (BbpCsr.field.Busy == BUSY) \
{ \
DBGPRINT_ERR(("BBP(viaMCU=%d) read R%d fail\n", (_bViaMCU), _bbpID)); \
*(_pV) = (_pAd)->BbpWriteLatch[_bbpID]; \
if ((_bViaMCU) == TRUE) \
{ \
RTMP_IO_READ32(_pAd, _regID, &BbpCsr.word); \
BbpCsr.field.Busy = 0; \
RTMP_IO_WRITE32(_pAd, _regID, BbpCsr.word); \
} \
} \
}while(0)
/*
This marco used for the BBP read operation which didn't need via MCU.
*/
#define BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) \
RTMP_BBP_IO_READ8((_A), (_I), (_pV), FALSE)
/*
This marco used for the BBP read operation which need via MCU.
But for some chipset which didn't have mcu (e.g., RBUS based chipset), we
will use this function too and didn't access the bbp register via the MCU.
*/
#ifndef CONFIG_STA_SUPPORT
#define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) \
do{ \
if ((_A)->bPCIclkOff == FALSE) \
{ \
if ((_A)->infType == RTMP_DEV_INF_RBUS) \
RTMP_BBP_IO_READ8((_A), (_I), (_pV), FALSE); \
else \
RTMP_BBP_IO_READ8((_A), (_I), (_pV), TRUE); \
} \
}while(0)
#endif // CONFIG_STA_SUPPORT //
#ifdef CONFIG_STA_SUPPORT
// Read BBP register by register's ID. Generate PER to test BA
#define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) \
{ \
BBP_CSR_CFG_STRUC BbpCsr; \
int i, k; \
BOOLEAN brc; \
BbpCsr.field.Busy = IDLE; \
if ((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) && ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3) \
&& ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE) \
&& ((_A)->bPCIclkOff == FALSE) \
&& ((_A)->brt30xxBanMcuCmd == FALSE)) \
{ \
for (i=0; i<MAX_BUSY_COUNT; i++) \
{ \
RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \
if (BbpCsr.field.Busy == BUSY) \
{ \
continue; \
} \
BbpCsr.word = 0; \
BbpCsr.field.fRead = 1; \
BbpCsr.field.BBP_RW_MODE = 1; \
BbpCsr.field.Busy = 1; \
BbpCsr.field.RegNum = _I; \
RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \
brc = AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0); \
if (brc == TRUE) \
{ \
for (k=0; k<MAX_BUSY_COUNT; k++) \
{ \
RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \
if (BbpCsr.field.Busy == IDLE) \
break; \
} \
if ((BbpCsr.field.Busy == IDLE) && \
(BbpCsr.field.RegNum == _I)) \
{ \
*(_pV) = (UCHAR)BbpCsr.field.Value; \
break; \
} \
} \
else \
{ \
BbpCsr.field.Busy = 0; \
RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \
} \
} \
} \
else if (!((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) && ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3) \
&& ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE)) \
&& ((_A)->bPCIclkOff == FALSE)) \
{ \
for (i=0; i<MAX_BUSY_COUNT; i++) \
{ \
RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \
if (BbpCsr.field.Busy == BUSY) \
{ \
continue; \
} \
BbpCsr.word = 0; \
BbpCsr.field.fRead = 1; \
BbpCsr.field.BBP_RW_MODE = 1; \
BbpCsr.field.Busy = 1; \
BbpCsr.field.RegNum = _I; \
RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \
AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0); \
for (k=0; k<MAX_BUSY_COUNT; k++) \
{ \
RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \
if (BbpCsr.field.Busy == IDLE) \
break; \
} \
if ((BbpCsr.field.Busy == IDLE) && \
(BbpCsr.field.RegNum == _I)) \
{ \
*(_pV) = (UCHAR)BbpCsr.field.Value; \
break; \
} \
} \
} \
else \
{ \
DBGPRINT_ERR((" , brt30xxBanMcuCmd = %d, Read BBP %d \n", (_A)->brt30xxBanMcuCmd, (_I))); \
*(_pV) = (_A)->BbpWriteLatch[_I]; \
} \
if ((BbpCsr.field.Busy == BUSY) || ((_A)->bPCIclkOff == TRUE)) \
{ \
DBGPRINT_ERR(("BBP read R%d=0x%x fail\n", _I, BbpCsr.word)); \
*(_pV) = (_A)->BbpWriteLatch[_I]; \
} \
}
#endif // CONFIG_STA_SUPPORT //
/*
basic marco for BBP write operation.
_pAd: the data structure pointer of RTMP_ADAPTER
_bbpID : the bbp register ID
_pV: data used to save the value of queried bbp register.
_bViaMCU: if we need access the bbp via the MCU.
*/
#define RTMP_BBP_IO_WRITE8(_pAd, _bbpID, _pV, _bViaMCU) \
do{ \
BBP_CSR_CFG_STRUC BbpCsr; \
int _busyCnt, _regID; \
\
_regID = ((_bViaMCU) == TRUE ? H2M_BBP_AGENT : BBP_CSR_CFG); \
for (_busyCnt=0; _busyCnt<MAX_BUSY_COUNT; _busyCnt++) \
{ \
RTMP_IO_READ32((_pAd), BBP_CSR_CFG, &BbpCsr.word); \
if (BbpCsr.field.Busy == BUSY) \
continue; \
BbpCsr.word = 0; \
BbpCsr.field.fRead = 0; \
BbpCsr.field.BBP_RW_MODE = 1; \
BbpCsr.field.Busy = 1; \
BbpCsr.field.Value = _pV; \
BbpCsr.field.RegNum = _bbpID; \
RTMP_IO_WRITE32((_pAd), BBP_CSR_CFG, BbpCsr.word); \
if ((_bViaMCU) == TRUE) \
{ \
AsicSendCommandToMcu(_pAd, 0x80, 0xff, 0x0, 0x0); \
if ((_pAd)->OpMode == OPMODE_AP) \
RTMPusecDelay(1000); \
} \
(_pAd)->BbpWriteLatch[_bbpID] = _pV; \
break; \
} \
if (_busyCnt == MAX_BUSY_COUNT) \
{ \
DBGPRINT_ERR(("BBP write R%d fail\n", _bbpID)); \
if((_bViaMCU) == TRUE) \
{ \
RTMP_IO_READ32(_pAd, H2M_BBP_AGENT, &BbpCsr.word); \
BbpCsr.field.Busy = 0; \
RTMP_IO_WRITE32(_pAd, H2M_BBP_AGENT, BbpCsr.word); \
} \
} \
}while(0)
/*
This marco used for the BBP write operation which didn't need via MCU.
*/
#define BBP_IO_WRITE8_BY_REG_ID(_A, _I, _pV) \
RTMP_BBP_IO_WRITE8((_A), (_I), (_pV), FALSE)
/*
This marco used for the BBP write operation which need via MCU.
But for some chipset which didn't have mcu (e.g., RBUS based chipset), we
will use this function too and didn't access the bbp register via the MCU.
*/
#ifndef CONFIG_STA_SUPPORT
#define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _pV) \
do{ \
if ((_A)->bPCIclkOff == FALSE) \
{ \
if ((_A)->infType == RTMP_DEV_INF_RBUS) \
RTMP_BBP_IO_WRITE8((_A), (_I), (_pV), FALSE); \
else \
RTMP_BBP_IO_WRITE8((_A), (_I), (_pV), TRUE); \
} \
}while(0)
#endif // CONFIG_STA_SUPPORT //
#ifdef CONFIG_STA_SUPPORT
// Write BBP register by register's ID & value
#define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) \
{ \
BBP_CSR_CFG_STRUC BbpCsr; \
INT BusyCnt = 0; \
BOOLEAN brc; \
if (_I < MAX_NUM_OF_BBP_LATCH) \
{ \
if ((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) && ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3) \
&& ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE) \
&& ((_A)->bPCIclkOff == FALSE) \
&& ((_A)->brt30xxBanMcuCmd == FALSE)) \
{ \
if (_A->AccessBBPFailCount > 20) \
{ \
AsicResetBBPAgent(_A); \
_A->AccessBBPFailCount = 0; \
} \
for (BusyCnt=0; BusyCnt<MAX_BUSY_COUNT; BusyCnt++) \
{ \
RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \
if (BbpCsr.field.Busy == BUSY) \
continue; \
BbpCsr.word = 0; \
BbpCsr.field.fRead = 0; \
BbpCsr.field.BBP_RW_MODE = 1; \
BbpCsr.field.Busy = 1; \
BbpCsr.field.Value = _V; \
BbpCsr.field.RegNum = _I; \
RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \
brc = AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0); \
if (brc == TRUE) \
{ \
(_A)->BbpWriteLatch[_I] = _V; \
} \
else \
{ \
BbpCsr.field.Busy = 0; \
RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \
} \
break; \
} \
} \
else if (!((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) && ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3) \
&& ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE)) \
&& ((_A)->bPCIclkOff == FALSE)) \
{ \
if (_A->AccessBBPFailCount > 20) \
{ \
AsicResetBBPAgent(_A); \
_A->AccessBBPFailCount = 0; \
} \
for (BusyCnt=0; BusyCnt<MAX_BUSY_COUNT; BusyCnt++) \
{ \
RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \
if (BbpCsr.field.Busy == BUSY) \
continue; \
BbpCsr.word = 0; \
BbpCsr.field.fRead = 0; \
BbpCsr.field.BBP_RW_MODE = 1; \
BbpCsr.field.Busy = 1; \
BbpCsr.field.Value = _V; \
BbpCsr.field.RegNum = _I; \
RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \
AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0); \
(_A)->BbpWriteLatch[_I] = _V; \
break; \
} \
} \
else \
{ \
DBGPRINT_ERR((" brt30xxBanMcuCmd = %d. Write BBP %d \n", (_A)->brt30xxBanMcuCmd, (_I))); \
} \
if ((BusyCnt == MAX_BUSY_COUNT) || ((_A)->bPCIclkOff == TRUE)) \
{ \
if (BusyCnt == MAX_BUSY_COUNT) \
(_A)->AccessBBPFailCount++; \
DBGPRINT_ERR(("BBP write R%d=0x%x fail. BusyCnt= %d.bPCIclkOff = %d. \n", _I, BbpCsr.word, BusyCnt, (_A)->bPCIclkOff )); \
} \
} \
else \
{ \
DBGPRINT_ERR(("****** BBP_Write_Latch Buffer exceeds max boundry ****** \n")); \
} \
}
#endif // CONFIG_STA_SUPPORT //
#endif // RTMP_MAC_PCI //
#ifdef RT30xx
//Need to collect each ant's rssi concurrently
//rssi1 is report to pair2 Ant and rss2 is reprot to pair1 Ant when 4 Ant
#define COLLECT_RX_ANTENNA_AVERAGE_RSSI(_pAd, _rssi1, _rssi2) \
{ \
SHORT AvgRssi; \
UCHAR UsedAnt; \
if (_pAd->RxAnt.EvaluatePeriod == 0) \
{ \
UsedAnt = _pAd->RxAnt.Pair1PrimaryRxAnt; \
AvgRssi = _pAd->RxAnt.Pair1AvgRssi[UsedAnt]; \
if (AvgRssi < 0) \
AvgRssi = AvgRssi - (AvgRssi >> 3) + _rssi1; \
else \
AvgRssi = _rssi1 << 3; \
_pAd->RxAnt.Pair1AvgRssi[UsedAnt] = AvgRssi; \
} \
else \
{ \
UsedAnt = _pAd->RxAnt.Pair1SecondaryRxAnt; \
AvgRssi = _pAd->RxAnt.Pair1AvgRssi[UsedAnt]; \
if ((AvgRssi < 0) && (_pAd->RxAnt.FirstPktArrivedWhenEvaluate)) \
AvgRssi = AvgRssi - (AvgRssi >> 3) + _rssi1; \
else \
{ \
_pAd->RxAnt.FirstPktArrivedWhenEvaluate = TRUE; \
AvgRssi = _rssi1 << 3; \
} \
_pAd->RxAnt.Pair1AvgRssi[UsedAnt] = AvgRssi; \
_pAd->RxAnt.RcvPktNumWhenEvaluate++; \
} \
}
#define RTMP_ASIC_MMPS_DISABLE(_pAd) \
do{ \
UCHAR _bbpData; \
UINT32 _macData; \
/* disable MMPS BBP control register */ \
RTMP_BBP_IO_READ8_BY_REG_ID(_pAd, BBP_R3, &_bbpData); \
_bbpData &= ~(0x04); /*bit 2*/ \
RTMP_BBP_IO_WRITE8_BY_REG_ID(_pAd, BBP_R3, _bbpData); \
\
/* disable MMPS MAC control register */ \
RTMP_IO_READ32(_pAd, 0x1210, &_macData); \
_macData &= ~(0x09); /*bit 0, 3*/ \
RTMP_IO_WRITE32(_pAd, 0x1210, _macData); \
}while(0)
#define RTMP_ASIC_MMPS_ENABLE(_pAd) \
do{ \
UCHAR _bbpData; \
UINT32 _macData; \
/* enable MMPS BBP control register */ \
RTMP_BBP_IO_READ8_BY_REG_ID(_pAd, BBP_R3, &_bbpData); \
_bbpData |= (0x04); /*bit 2*/ \
RTMP_BBP_IO_WRITE8_BY_REG_ID(_pAd, BBP_R3, _bbpData); \
\
/* enable MMPS MAC control register */ \
RTMP_IO_READ32(_pAd, 0x1210, &_macData); \
_macData |= (0x09); /*bit 0, 3*/ \
RTMP_IO_WRITE32(_pAd, 0x1210, _macData); \
}while(0)
#endif // RT30xx //
#endif // __RTMP_PHY_H__ //

View file

@ -0,0 +1,162 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
rtmp_timer.h
Abstract:
Ralink Wireless Driver timer related data structures and delcarations
Revision History:
Who When What
-------- ---------- ----------------------------------------------
Name Date Modification logs
Shiang Tu Aug-28-2008 init version
*/
#ifndef __RTMP_TIMER_H__
#define __RTMP_TIMER_H__
#include "rtmp_os.h"
#define DECLARE_TIMER_FUNCTION(_func) \
void rtmp_timer_##_func(unsigned long data)
#define GET_TIMER_FUNCTION(_func) \
rtmp_timer_##_func
/* ----------------- Timer Related MARCO ---------------*/
// In some os or chipset, we have a lot of timer functions and will read/write register,
// it's not allowed in Linux USB sub-system to do it ( because of sleep issue when
// submit to ctrl pipe). So we need a wrapper function to take care it.
#ifdef RTMP_TIMER_TASK_SUPPORT
typedef VOID (*RTMP_TIMER_TASK_HANDLE)(
IN PVOID SystemSpecific1,
IN PVOID FunctionContext,
IN PVOID SystemSpecific2,
IN PVOID SystemSpecific3);
#endif // RTMP_TIMER_TASK_SUPPORT //
typedef struct _RALINK_TIMER_STRUCT {
RTMP_OS_TIMER TimerObj; // Ndis Timer object
BOOLEAN Valid; // Set to True when call RTMPInitTimer
BOOLEAN State; // True if timer cancelled
BOOLEAN PeriodicType; // True if timer is periodic timer
BOOLEAN Repeat; // True if periodic timer
ULONG TimerValue; // Timer value in milliseconds
ULONG cookie; // os specific object
#ifdef RTMP_TIMER_TASK_SUPPORT
RTMP_TIMER_TASK_HANDLE handle;
void *pAd;
#endif // RTMP_TIMER_TASK_SUPPORT //
}RALINK_TIMER_STRUCT, *PRALINK_TIMER_STRUCT;
#ifdef RTMP_TIMER_TASK_SUPPORT
typedef struct _RTMP_TIMER_TASK_ENTRY_
{
RALINK_TIMER_STRUCT *pRaTimer;
struct _RTMP_TIMER_TASK_ENTRY_ *pNext;
}RTMP_TIMER_TASK_ENTRY;
#define TIMER_QUEUE_SIZE_MAX 128
typedef struct _RTMP_TIMER_TASK_QUEUE_
{
unsigned int status;
unsigned char *pTimerQPoll;
RTMP_TIMER_TASK_ENTRY *pQPollFreeList;
RTMP_TIMER_TASK_ENTRY *pQHead;
RTMP_TIMER_TASK_ENTRY *pQTail;
}RTMP_TIMER_TASK_QUEUE;
#define BUILD_TIMER_FUNCTION(_func) \
void rtmp_timer_##_func(unsigned long data) \
{ \
PRALINK_TIMER_STRUCT _pTimer = (PRALINK_TIMER_STRUCT)data; \
RTMP_TIMER_TASK_ENTRY *_pQNode; \
RTMP_ADAPTER *_pAd; \
\
_pTimer->handle = _func; \
_pAd = (RTMP_ADAPTER *)_pTimer->pAd; \
_pQNode = RtmpTimerQInsert(_pAd, _pTimer); \
if ((_pQNode == NULL) && (_pAd->TimerQ.status & RTMP_TASK_CAN_DO_INSERT)) \
RTMP_OS_Add_Timer(&_pTimer->TimerObj, OS_HZ); \
}
#else
#define BUILD_TIMER_FUNCTION(_func) \
void rtmp_timer_##_func(unsigned long data) \
{ \
PRALINK_TIMER_STRUCT pTimer = (PRALINK_TIMER_STRUCT) data; \
\
_func(NULL, (PVOID) pTimer->cookie, NULL, pTimer); \
if (pTimer->Repeat) \
RTMP_OS_Add_Timer(&pTimer->TimerObj, pTimer->TimerValue); \
}
#endif // RTMP_TIMER_TASK_SUPPORT //
DECLARE_TIMER_FUNCTION(MlmePeriodicExec);
DECLARE_TIMER_FUNCTION(MlmeRssiReportExec);
DECLARE_TIMER_FUNCTION(AsicRxAntEvalTimeout);
DECLARE_TIMER_FUNCTION(APSDPeriodicExec);
DECLARE_TIMER_FUNCTION(AsicRfTuningExec);
#ifdef CONFIG_STA_SUPPORT
DECLARE_TIMER_FUNCTION(BeaconTimeout);
DECLARE_TIMER_FUNCTION(ScanTimeout);
DECLARE_TIMER_FUNCTION(AuthTimeout);
DECLARE_TIMER_FUNCTION(AssocTimeout);
DECLARE_TIMER_FUNCTION(ReassocTimeout);
DECLARE_TIMER_FUNCTION(DisassocTimeout);
DECLARE_TIMER_FUNCTION(LinkDownExec);
DECLARE_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
DECLARE_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
DECLARE_TIMER_FUNCTION(PsPollWakeExec);
DECLARE_TIMER_FUNCTION(RadioOnExec);
#ifdef QOS_DLS_SUPPORT
DECLARE_TIMER_FUNCTION(DlsTimeoutAction);
#endif // QOS_DLS_SUPPORT //
#endif // CONFIG_STA_SUPPORT //
#if defined(AP_LED) || defined(STA_LED)
DECLARE_TIMER_FUNCTION(LedCtrlMain);
#endif
#endif // __RTMP_TIMER_H__ //

View file

@ -0,0 +1,147 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
rtmp_type.h
Abstract:
Revision History:
Who When What
-------- ---------- ----------------------------------------------
Name Date Modification logs
Paul Lin 1-2-2004
*/
#ifndef __RTMP_TYPE_H__
#define __RTMP_TYPE_H__
#define PACKED __attribute__ ((packed))
#ifdef LINUX
// Put platform dependent declaration here
// For example, linux type definition
typedef unsigned char UINT8;
typedef unsigned short UINT16;
typedef unsigned int UINT32;
typedef unsigned long long UINT64;
typedef int INT32;
typedef long long INT64;
#endif // LINUX //
typedef unsigned char * PUINT8;
typedef unsigned short * PUINT16;
typedef unsigned int * PUINT32;
typedef unsigned long long * PUINT64;
typedef int * PINT32;
typedef long long * PINT64;
// modified for fixing compile warning on Sigma 8634 platform
typedef char STRING;
typedef signed char CHAR;
typedef signed short SHORT;
typedef signed int INT;
typedef signed long LONG;
typedef signed long long LONGLONG;
#ifdef LINUX
typedef unsigned char UCHAR;
typedef unsigned short USHORT;
typedef unsigned int UINT;
typedef unsigned long ULONG;
#endif // LINUX //
typedef unsigned long long ULONGLONG;
typedef unsigned char BOOLEAN;
#ifdef LINUX
typedef void VOID;
#endif // LINUX //
typedef char * PSTRING;
typedef VOID * PVOID;
typedef CHAR * PCHAR;
typedef UCHAR * PUCHAR;
typedef USHORT * PUSHORT;
typedef LONG * PLONG;
typedef ULONG * PULONG;
typedef UINT * PUINT;
typedef unsigned int NDIS_MEDIA_STATE;
typedef union _LARGE_INTEGER {
struct {
UINT LowPart;
INT32 HighPart;
} u;
INT64 QuadPart;
} LARGE_INTEGER;
//
// Register set pair for initialzation register set definition
//
typedef struct _RTMP_REG_PAIR
{
ULONG Register;
ULONG Value;
} RTMP_REG_PAIR, *PRTMP_REG_PAIR;
typedef struct _REG_PAIR
{
UCHAR Register;
UCHAR Value;
} REG_PAIR, *PREG_PAIR;
//
// Register set pair for initialzation register set definition
//
typedef struct _RTMP_RF_REGS
{
UCHAR Channel;
ULONG R1;
ULONG R2;
ULONG R3;
ULONG R4;
} RTMP_RF_REGS, *PRTMP_RF_REGS;
typedef struct _FREQUENCY_ITEM {
UCHAR Channel;
UCHAR N;
UCHAR R;
UCHAR K;
} FREQUENCY_ITEM, *PFREQUENCY_ITEM;
typedef int NTSTATUS;
#define STATUS_SUCCESS 0x00
#define STATUS_UNSUCCESSFUL 0x01
#endif // __RTMP_TYPE_H__ //

View file

@ -0,0 +1,234 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
*/
#ifndef __SPECTRUM_H__
#define __SPECTRUM_H__
#include "rtmp_type.h"
#include "spectrum_def.h"
CHAR RTMP_GetTxPwr(
IN PRTMP_ADAPTER pAd,
IN HTTRANSMIT_SETTING HTTxMode);
/*
==========================================================================
Description:
Prepare Measurement request action frame and enqueue it into
management queue waiting for transmition.
Parametrs:
1. the destination mac address of the frame.
Return : None.
==========================================================================
*/
VOID MakeMeasurementReqFrame(
IN PRTMP_ADAPTER pAd,
OUT PUCHAR pOutBuffer,
OUT PULONG pFrameLen,
IN UINT8 TotalLen,
IN UINT8 Category,
IN UINT8 Action,
IN UINT8 MeasureToken,
IN UINT8 MeasureReqMode,
IN UINT8 MeasureReqType,
IN UINT8 NumOfRepetitions);
/*
==========================================================================
Description:
Prepare Measurement report action frame and enqueue it into
management queue waiting for transmition.
Parametrs:
1. the destination mac address of the frame.
Return : None.
==========================================================================
*/
VOID EnqueueMeasurementRep(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pDA,
IN UINT8 DialogToken,
IN UINT8 MeasureToken,
IN UINT8 MeasureReqMode,
IN UINT8 MeasureReqType,
IN UINT8 ReportInfoLen,
IN PUINT8 pReportInfo);
/*
==========================================================================
Description:
Prepare TPC Request action frame and enqueue it into
management queue waiting for transmition.
Parametrs:
1. the destination mac address of the frame.
Return : None.
==========================================================================
*/
VOID EnqueueTPCReq(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pDA,
IN UCHAR DialogToken);
/*
==========================================================================
Description:
Prepare TPC Report action frame and enqueue it into
management queue waiting for transmition.
Parametrs:
1. the destination mac address of the frame.
Return : None.
==========================================================================
*/
VOID EnqueueTPCRep(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pDA,
IN UINT8 DialogToken,
IN UINT8 TxPwr,
IN UINT8 LinkMargin);
/*
==========================================================================
Description:
Prepare Channel Switch Announcement action frame and enqueue it into
management queue waiting for transmition.
Parametrs:
1. the destination mac address of the frame.
2. Channel switch announcement mode.
2. a New selected channel.
Return : None.
==========================================================================
*/
VOID EnqueueChSwAnn(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pDA,
IN UINT8 ChSwMode,
IN UINT8 NewCh);
/*
==========================================================================
Description:
Spectrun action frames Handler such as channel switch annoucement,
measurement report, measurement request actions frames.
Parametrs:
Elme - MLME message containing the received frame
Return : None.
==========================================================================
*/
VOID PeerSpectrumAction(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem);
/*
==========================================================================
Description:
Parametrs:
Return : None.
==========================================================================
*/
INT Set_MeasureReq_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
INT Set_TpcReq_Proc(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
INT Set_PwrConstraint(
IN PRTMP_ADAPTER pAd,
IN PSTRING arg);
VOID MeasureReqTabInit(
IN PRTMP_ADAPTER pAd);
VOID MeasureReqTabExit(
IN PRTMP_ADAPTER pAd);
PMEASURE_REQ_ENTRY MeasureReqLookUp(
IN PRTMP_ADAPTER pAd,
IN UINT8 DialogToken);
PMEASURE_REQ_ENTRY MeasureReqInsert(
IN PRTMP_ADAPTER pAd,
IN UINT8 DialogToken);
VOID MeasureReqDelete(
IN PRTMP_ADAPTER pAd,
IN UINT8 DialogToken);
VOID InsertChannelRepIE(
IN PRTMP_ADAPTER pAd,
OUT PUCHAR pFrameBuf,
OUT PULONG pFrameLen,
IN PSTRING pCountry,
IN UINT8 RegulatoryClass);
VOID InsertTpcReportIE(
IN PRTMP_ADAPTER pAd,
OUT PUCHAR pFrameBuf,
OUT PULONG pFrameLen,
IN UINT8 TxPwr,
IN UINT8 LinkMargin);
VOID InsertDialogToken(
IN PRTMP_ADAPTER pAd,
OUT PUCHAR pFrameBuf,
OUT PULONG pFrameLen,
IN UINT8 DialogToken);
VOID TpcReqTabInit(
IN PRTMP_ADAPTER pAd);
VOID TpcReqTabExit(
IN PRTMP_ADAPTER pAd);
VOID NotifyChSwAnnToPeerAPs(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pRA,
IN PUCHAR pTA,
IN UINT8 ChSwMode,
IN UINT8 Channel);
VOID RguClass_BuildBcnChList(
IN PRTMP_ADAPTER pAd,
OUT PUCHAR pBuf,
OUT PULONG pBufLen);
#endif // __SPECTRUM_H__ //

View file

@ -0,0 +1,257 @@
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
spectrum_def.h
Abstract:
Handle association related requests either from WSTA or from local MLME
Revision History:
Who When What
--------- ---------- ----------------------------------------------
Fonchi Wu 2008 created for 802.11h
*/
#ifndef __SPECTRUM_DEF_H__
#define __SPECTRUM_DEF_H__
#define MAX_MEASURE_REQ_TAB_SIZE 32
#define MAX_HASH_MEASURE_REQ_TAB_SIZE MAX_MEASURE_REQ_TAB_SIZE
#define MAX_TPC_REQ_TAB_SIZE 32
#define MAX_HASH_TPC_REQ_TAB_SIZE MAX_TPC_REQ_TAB_SIZE
#define MIN_RCV_PWR 100 /* Negative value ((dBm) */
#define TPC_REQ_AGE_OUT 500 /* ms */
#define MQ_REQ_AGE_OUT 500 /* ms */
#define TPC_DIALOGTOKEN_HASH_INDEX(_DialogToken) ((_DialogToken) % MAX_HASH_TPC_REQ_TAB_SIZE)
#define MQ_DIALOGTOKEN_HASH_INDEX(_DialogToken) ((_DialogToken) % MAX_MEASURE_REQ_TAB_SIZE)
typedef struct _MEASURE_REQ_ENTRY
{
struct _MEASURE_REQ_ENTRY *pNext;
ULONG lastTime;
BOOLEAN Valid;
UINT8 DialogToken;
UINT8 MeasureDialogToken[3]; // 0:basic measure, 1: CCA measure, 2: RPI_Histogram measure.
} MEASURE_REQ_ENTRY, *PMEASURE_REQ_ENTRY;
typedef struct _MEASURE_REQ_TAB
{
UCHAR Size;
PMEASURE_REQ_ENTRY Hash[MAX_HASH_MEASURE_REQ_TAB_SIZE];
MEASURE_REQ_ENTRY Content[MAX_MEASURE_REQ_TAB_SIZE];
} MEASURE_REQ_TAB, *PMEASURE_REQ_TAB;
typedef struct _TPC_REQ_ENTRY
{
struct _TPC_REQ_ENTRY *pNext;
ULONG lastTime;
BOOLEAN Valid;
UINT8 DialogToken;
} TPC_REQ_ENTRY, *PTPC_REQ_ENTRY;
typedef struct _TPC_REQ_TAB
{
UCHAR Size;
PTPC_REQ_ENTRY Hash[MAX_HASH_TPC_REQ_TAB_SIZE];
TPC_REQ_ENTRY Content[MAX_TPC_REQ_TAB_SIZE];
} TPC_REQ_TAB, *PTPC_REQ_TAB;
/* The regulatory information */
typedef struct _DOT11_CHANNEL_SET
{
UCHAR NumberOfChannels;
UINT8 MaxTxPwr;
UCHAR ChannelList[16];
} DOT11_CHANNEL_SET, *PDOT11_CHANNEL_SET;
typedef struct _DOT11_REGULATORY_INFORMATION
{
UCHAR RegulatoryClass;
DOT11_CHANNEL_SET ChannelSet;
} DOT11_REGULATORY_INFORMATION, *PDOT11_REGULATORY_INFORMATION;
#define RM_TPC_REQ 0
#define RM_MEASURE_REQ 1
#define RM_BASIC 0
#define RM_CCA 1
#define RM_RPI_HISTOGRAM 2
#define RM_CH_LOAD 3
#define RM_NOISE_HISTOGRAM 4
typedef struct PACKED _TPC_REPORT_INFO
{
UINT8 TxPwr;
UINT8 LinkMargin;
} TPC_REPORT_INFO, *PTPC_REPORT_INFO;
typedef struct PACKED _CH_SW_ANN_INFO
{
UINT8 ChSwMode;
UINT8 Channel;
UINT8 ChSwCnt;
} CH_SW_ANN_INFO, *PCH_SW_ANN_INFO;
typedef union PACKED _MEASURE_REQ_MODE
{
#ifdef RT_BIG_ENDIAN
struct PACKED
{
UINT8 :3;
UINT8 DurationMandatory:1;
UINT8 Report:1;
UINT8 Request:1;
UINT8 Enable:1;
UINT8 Parallel:1;
} field;
#else
struct PACKED
{
UINT8 Parallel:1;
UINT8 Enable:1;
UINT8 Request:1;
UINT8 Report:1;
UINT8 DurationMandatory:1;
UINT8 :3;
} field;
#endif // RT_BIG_ENDIAN //
UINT8 word;
} MEASURE_REQ_MODE, *PMEASURE_REQ_MODE;
typedef struct PACKED _MEASURE_REQ
{
UINT8 ChNum;
UINT64 MeasureStartTime;
UINT16 MeasureDuration;
} MEASURE_REQ, *PMEASURE_REQ;
typedef struct PACKED _MEASURE_REQ_INFO
{
UINT8 Token;
MEASURE_REQ_MODE ReqMode;
UINT8 ReqType;
UINT8 Oct[0];
} MEASURE_REQ_INFO, *PMEASURE_REQ_INFO;
typedef union PACKED _MEASURE_BASIC_REPORT_MAP
{
#ifdef RT_BIG_ENDIAN
struct PACKED
{
UINT8 Rev:3;
UINT8 Unmeasure:1;
UINT8 Radar:1;
UINT8 UnidentifiedSignal:1;
UINT8 OfdmPreamble:1;
UINT8 BSS:1;
} field;
#else
struct PACKED
{
UINT8 BSS:1;
UINT8 OfdmPreamble:1;
UINT8 UnidentifiedSignal:1;
UINT8 Radar:1;
UINT8 Unmeasure:1;
UINT8 Rev:3;
} field;
#endif // RT_BIG_ENDIAN //
UINT8 word;
} MEASURE_BASIC_REPORT_MAP, *PMEASURE_BASIC_REPORT_MAP;
typedef struct PACKED _MEASURE_BASIC_REPORT
{
UINT8 ChNum;
UINT64 MeasureStartTime;
UINT16 MeasureDuration;
MEASURE_BASIC_REPORT_MAP Map;
} MEASURE_BASIC_REPORT, *PMEASURE_BASIC_REPORT;
typedef struct PACKED _MEASURE_CCA_REPORT
{
UINT8 ChNum;
UINT64 MeasureStartTime;
UINT16 MeasureDuration;
UINT8 CCA_Busy_Fraction;
} MEASURE_CCA_REPORT, *PMEASURE_CCA_REPORT;
typedef struct PACKED _MEASURE_RPI_REPORT
{
UINT8 ChNum;
UINT64 MeasureStartTime;
UINT16 MeasureDuration;
UINT8 RPI_Density[8];
} MEASURE_RPI_REPORT, *PMEASURE_RPI_REPORT;
typedef union PACKED _MEASURE_REPORT_MODE
{
struct PACKED
{
#ifdef RT_BIG_ENDIAN
UINT8 Rev:5;
UINT8 Refused:1;
UINT8 Incapable:1;
UINT8 Late:1;
#else
UINT8 Late:1;
UINT8 Incapable:1;
UINT8 Refused:1;
UINT8 Rev:5;
#endif // RT_BIG_ENDIAN //
} field;
UINT8 word;
} MEASURE_REPORT_MODE, *PMEASURE_REPORT_MODE;
typedef struct PACKED _MEASURE_REPORT_INFO
{
UINT8 Token;
UINT8 ReportMode;
UINT8 ReportType;
UINT8 Octect[0];
} MEASURE_REPORT_INFO, *PMEASURE_REPORT_INFO;
typedef struct PACKED _QUIET_INFO
{
UINT8 QuietCnt;
UINT8 QuietPeriod;
UINT16 QuietDuration;
UINT16 QuietOffset;
} QUIET_INFO, *PQUIET_INFO;
#endif // __SPECTRUM_DEF_H__ //

File diff suppressed because it is too large Load diff

Some files were not shown because too many files have changed in this diff Show more