提交 60b0fa1a 编写于 作者: G Greg Kroah-Hartman

Merge git://git.kernel.org/pub/scm/linux/kernel/git/lwfinger/linux-staging into staging-next

* git://git.kernel.org/pub/scm/linux/kernel/git/lwfinger/linux-staging:
  staging: rt2860sta and rt2870sta: Remove drivers replaced in net/wireless
Signed-off-by: NGreg Kroah-Hartman <gregkh@suse.de>
......@@ -67,10 +67,6 @@ source "drivers/staging/echo/Kconfig"
source "drivers/staging/brcm80211/Kconfig"
source "drivers/staging/rt2860/Kconfig"
source "drivers/staging/rt2870/Kconfig"
source "drivers/staging/comedi/Kconfig"
source "drivers/staging/olpc_dcon/Kconfig"
......
......@@ -18,8 +18,6 @@ obj-$(CONFIG_PRISM2_USB) += wlan-ng/
obj-$(CONFIG_ECHO) += echo/
obj-$(CONFIG_BRCMSMAC) += brcm80211/
obj-$(CONFIG_BRCMFMAC) += brcm80211/
obj-$(CONFIG_RT2860) += rt2860/
obj-$(CONFIG_RT2870) += rt2870/
obj-$(CONFIG_COMEDI) += comedi/
obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon/
obj-$(CONFIG_ASUS_OLED) += asus_oled/
......
config RT2860
tristate "Ralink 2860/3090 wireless support"
depends on PCI && X86 && WLAN
select WIRELESS_EXT
select WEXT_PRIV
select CRC_CCITT
select FW_LOADER
---help---
This is an experimental driver for the Ralink 2860 and 3090
wireless chips.
obj-$(CONFIG_RT2860) += rt2860sta.o
# TODO: all of these should be removed
ccflags-y := -DLINUX -DAGGREGATION_SUPPORT -DPIGGYBACK_SUPPORT -DWMM_SUPPORT
ccflags-y += -DRTMP_MAC_PCI -DRTMP_PCI_SUPPORT -DRT2860
ccflags-y += -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DRT30xx -DRT3090
ccflags-y += -DDBG
rt2860sta-y := \
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_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_main_dev.o \
sta_ioctl.o \
common/ba_action.o \
pci_main_dev.o \
rt_pci_rbus.o \
common/cmm_mac_pci.o \
common/cmm_data_pci.o \
common/ee_prom.o \
common/rtmp_mcu.o \
common/ee_efuse.o \
chips/rt30xx.o \
common/rt_rf.o \
chips/rt3090.o
I'm hesitant to add a TODO file here, as the wireless developers would
really have people help them out on the "clean" rt2860 driver that can
be found at the http://rt2x00.serialmonkey.com/ site.
But, if you wish to clean up this driver instead, here's a short list of
things that need to be done to get it into a more mergable shape:
TODO:
- checkpatch.pl clean
- sparse clean
- port to in-kernel 80211 stack and common rt2x00 infrastructure
- review by the wireless developer community
Please send any patches or complaints about this driver to Greg
Kroah-Hartman <greg@kroah.com> and don't bother the upstream wireless
kernel developers about it, they want nothing to do with it.
/*
*************************************************************************
* 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__
/* ap_wpa.c */
void WpaStateMachineInit(struct rt_rtmp_adapter *pAd,
struct rt_state_machine *Sm,
OUT STATE_MACHINE_FUNC Trans[]);
#ifdef RTMP_MAC_USB
void BeaconUpdateExec(void *SystemSpecific1,
void *FunctionContext,
void *SystemSpecific2, void *SystemSpecific3);
#endif /* RTMP_MAC_USB // */
void RTMPSetPiggyBack(struct rt_rtmp_adapter *pAd, IN BOOLEAN bPiggyBack);
void MacTableReset(struct rt_rtmp_adapter *pAd);
struct rt_mac_table_entry *MacTableInsertEntry(struct rt_rtmp_adapter *pAd,
u8 *pAddr,
u8 apidx, IN BOOLEAN CleanAll);
BOOLEAN MacTableDeleteEntry(struct rt_rtmp_adapter *pAd,
u16 wcid, u8 *pAddr);
struct rt_mac_table_entry *MacTableLookup(struct rt_rtmp_adapter *pAd,
u8 *pAddr);
#endif /* __AP_H__ */
/*
*************************************************************************
* 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
Justin P. Mattock 11/07/2010 Fix some typos
--------- ---------- ----------------------------------------------
*/
#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 know for sure what chip it belongs too. */
/* */
#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 */
/* */
struct PACKED rt_txd {
/* Word 0 */
u32 SDPtr0;
/* Word 1 */
u32 SDLen1:14;
u32 LastSec1:1;
u32 Burst:1;
u32 SDLen0:14;
u32 LastSec0:1;
u32 DMADONE:1;
/*Word2 */
u32 SDPtr1;
/*Word3 */
u32 rsv2:24;
u32 WIV:1; /* Wireless Info Valid. 1 if Driver already fill WI, o if DMA needs to copy WI to correct position */
u32 QSEL:2; /* select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA */
u32 rsv:2;
u32 TCO:1; /* */
u32 UCO:1; /* */
u32 ICO:1; /* */
};
/* */
/* Rx descriptor format, Rx Ring */
/* */
typedef struct PACKED rt_rxd {
/* Word 0 */
u32 SDP0;
/* Word 1 */
u32 SDL1:14;
u32 Rsv:2;
u32 SDL0:14;
u32 LS0:1;
u32 DDONE:1;
/* Word 2 */
u32 SDP1;
/* Word 3 */
u32 BA:1;
u32 DATA:1;
u32 NULLDATA:1;
u32 FRAG:1;
u32 U2M:1; /* 1: this RX frame is unicast to me */
u32 Mcast:1; /* 1: this is a multicast frame */
u32 Bcast:1; /* 1: this is a broadcast frame */
u32 MyBss:1; /* 1: this frame belongs to the same BSSID */
u32 Crc:1; /* 1: CRC error */
u32 CipherErr:2; /* 0: decryption okay, 1:ICV error, 2:MIC error, 3:KEY not valid */
u32 AMSDU:1; /* rx with 802.3 header, not 802.11 header. */
u32 HTC:1;
u32 RSSI:1;
u32 L2PAD:1;
u32 AMPDU:1;
u32 Decrypted:1; /* this frame is being decrypted. */
u32 PlcpSignal:1; /* To be moved */
u32 PlcpRssil:1; /* To be moved */
u32 Rsv1:13;
} RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC;
typedef union _TX_ATTENUATION_CTRL_STRUC {
struct {
unsigned long RF_ISOLATION_ENABLE:1;
unsigned long Reserve2:7;
unsigned long PCIE_PHY_TX_ATTEN_VALUE:3;
unsigned long PCIE_PHY_TX_ATTEN_EN:1;
unsigned long Reserve1:20;
} field;
unsigned long word;
} TX_ATTENUATION_CTRL_STRUC, *PTX_ATTENUATION_CTRL_STRUC;
/* ----------------- 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 { \
unsigned long _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) >= (unsigned long)(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))
#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, (u8)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 { \
u32 _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 { \
u32 _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
#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);
#define RTMP_MLME_RADIO_ON(pAd) \
RT28xxPciMlmeRadioOn(pAd);
#define RTMP_MLME_RADIO_OFF(pAd) \
RT28xxPciMlmeRadioOFF(pAd);
#endif /*__MAC_PCI_H__ // */
/*
*************************************************************************
* 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_usb.h
Abstract:
Revision History:
Who When What
Justin P. Mattock 11/07/2010 Fix a typo
--------- ---------- ----------------------------------------------
*/
#ifndef __MAC_USB_H__
#define __MAC_USB_H__
#include "../rtmp_type.h"
#include "rtmp_mac.h"
#include "rtmp_phy.h"
#include "../rtmp_iface.h"
#include "../rtmp_dot11.h"
#define USB_CYC_CFG 0x02a4
#define BEACON_RING_SIZE 2
#define MGMTPIPEIDX 0 /* EP6 is highest priority */
#define RTMP_PKT_TAIL_PADDING 11 /* 3(max 4 byte padding) + 4 (last packet padding) + 4 (MaxBulkOutsize align padding) */
#define fRTMP_ADAPTER_NEED_STOP_TX \
(fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \
fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_BULKOUT_RESET | \
fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_REMOVE_IN_PROGRESS)
/* */
/* RXINFO appends at the end of each rx packet. */
/* */
#define RXINFO_SIZE 4
#define RT2870_RXDMALEN_FIELD_SIZE 4
typedef struct PACKED rt_rxinfo {
u32 BA:1;
u32 DATA:1;
u32 NULLDATA:1;
u32 FRAG:1;
u32 U2M:1; /* 1: this RX frame is unicast to me */
u32 Mcast:1; /* 1: this is a multicast frame */
u32 Bcast:1; /* 1: this is a broadcast frame */
u32 MyBss:1; /* 1: this frame belongs to the same BSSID */
u32 Crc:1; /* 1: CRC error */
u32 CipherErr:2; /* 0: decryption okay, 1:ICV error, 2:MIC error, 3:KEY not valid */
u32 AMSDU:1; /* rx with 802.3 header, not 802.11 header. */
u32 HTC:1;
u32 RSSI:1;
u32 L2PAD:1;
u32 AMPDU:1; /* To be moved */
u32 Decrypted:1;
u32 PlcpRssil:1;
u32 CipherAlg:1;
u32 LastAMSDU:1;
u32 PlcpSignal:12;
} RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC;
/* */
/* TXINFO */
/* */
#define TXINFO_SIZE 4
struct rt_txinfo {
/* Word 0 */
u32 USBDMATxPktLen:16; /*used ONLY in USB bulk Aggregation, Total byte counts of all sub-frame. */
u32 rsv:8;
u32 WIV:1; /* Wireless Info Valid. 1 if Driver already fill WI, o if DMA needs to copy WI to correct position */
u32 QSEL:2; /* select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA */
u32 SwUseLastRound:1; /* Software use. */
u32 rsv2:2; /* Software use. */
u32 USBDMANextVLD:1; /*used ONLY in USB bulk Aggregation, NextValid */
u32 USBDMATxburst:1; /*used ONLY in USB bulk Aggre. Force USB DMA transmit frame from current selected endpoint */
};
/* */
/* Management ring buffer format */
/* */
struct rt_mgmt {
BOOLEAN Valid;
u8 *pBuffer;
unsigned long Length;
};
/*////////////////////////////////////////////////////////////////////////// */
/* The struct rt_tx_buffer structure forms the transmitted USB packet to the device */
/*////////////////////////////////////////////////////////////////////////// */
struct rt_tx_buffer {
union {
u8 WirelessPacket[TX_BUFFER_NORMSIZE];
struct rt_header_802_11 NullFrame;
struct rt_pspoll_frame PsPollPacket;
struct rt_rts_frame RTSFrame;
} field;
u8 Aggregation[4]; /*Buffer for save Aggregation size. */
};
struct rt_httx_buffer {
union {
u8 WirelessPacket[MAX_TXBULK_SIZE];
struct rt_header_802_11 NullFrame;
struct rt_pspoll_frame PsPollPacket;
struct rt_rts_frame RTSFrame;
} field;
u8 Aggregation[4]; /*Buffer for save Aggregation size. */
};
/* used to track driver-generated write irps */
struct rt_tx_context {
void *pAd; /*Initialized in MiniportInitialize */
PURB pUrb; /*Initialized in MiniportInitialize */
PIRP pIrp; /*used to cancel pending bulk out. */
/*Initialized in MiniportInitialize */
struct rt_tx_buffer *TransferBuffer; /*Initialized in MiniportInitialize */
unsigned long BulkOutSize;
u8 BulkOutPipeId;
u8 SelfIdx;
BOOLEAN InUse;
BOOLEAN bWaitingBulkOut; /* at least one packet is in this TxContext, ready for making IRP anytime. */
BOOLEAN bFullForBulkOut; /* all tx buffer are full , so waiting for tx bulkout. */
BOOLEAN IRPPending;
BOOLEAN LastOne;
BOOLEAN bAggregatible;
u8 Header_802_3[LENGTH_802_3];
u8 Rsv[2];
unsigned long DataOffset;
u32 TxRate;
dma_addr_t data_dma; /* urb dma on linux */
};
/* used to track driver-generated write irps */
struct rt_ht_tx_context {
void *pAd; /*Initialized in MiniportInitialize */
PURB pUrb; /*Initialized in MiniportInitialize */
PIRP pIrp; /*used to cancel pending bulk out. */
/*Initialized in MiniportInitialize */
struct rt_httx_buffer *TransferBuffer; /*Initialized in MiniportInitialize */
unsigned long BulkOutSize; /* Indicate the total bulk-out size in bytes in one bulk-transmission */
u8 BulkOutPipeId;
BOOLEAN IRPPending;
BOOLEAN LastOne;
BOOLEAN bCurWriting;
BOOLEAN bRingEmpty;
BOOLEAN bCopySavePad;
u8 SavedPad[8];
u8 Header_802_3[LENGTH_802_3];
unsigned long CurWritePosition; /* Indicate the buffer offset which packet will be inserted start from. */
unsigned long CurWriteRealPos; /* Indicate the buffer offset which packet now are writing to. */
unsigned long NextBulkOutPosition; /* Indicate the buffer start offset of a bulk-transmission */
unsigned long ENextBulkOutPosition; /* Indicate the buffer end offset of a bulk-transmission */
u32 TxRate;
dma_addr_t data_dma; /* urb dma on linux */
};
/* */
/* Structure to keep track of receive packets and buffers to indicate */
/* receive data to the protocol. */
/* */
struct rt_rx_context {
u8 *TransferBuffer;
void *pAd;
PIRP pIrp; /*used to cancel pending bulk in. */
PURB pUrb;
/*These 2 Boolean shouldn't both be 1 at the same time. */
unsigned long BulkInOffset; /* number of packets waiting for reordering . */
/* BOOLEAN ReorderInUse; // At least one packet in this buffer are in reordering buffer and wait for receive indication */
BOOLEAN bRxHandling; /* Notify this packet is being process now. */
BOOLEAN InUse; /* USB Hardware Occupied. Wait for USB HW to put packet. */
BOOLEAN Readable; /* Receive Complete back. OK for driver to indicate receiving packet. */
BOOLEAN IRPPending; /* TODO: To be removed */
atomic_t IrpLock;
spinlock_t RxContextLock;
dma_addr_t data_dma; /* urb dma on linux */
};
/******************************************************************************
USB Frimware Related MACRO
******************************************************************************/
/* 8051 firmware image for usb - use last-half base address = 0x3000 */
#define FIRMWARE_IMAGE_BASE 0x3000
#define MAX_FIRMWARE_IMAGE_SIZE 0x1000 /* 4kbyte */
#define RTMP_WRITE_FIRMWARE(_pAd, _pFwImage, _FwLen) \
RTUSBFirmwareWrite(_pAd, _pFwImage, _FwLen)
/******************************************************************************
USB TX Related MACRO
******************************************************************************/
#define RTMP_START_DEQUEUE(pAd, QueIdx, irqFlags) \
do { \
RTMP_IRQ_LOCK(&pAd->DeQueueLock[QueIdx], irqFlags); \
if (pAd->DeQueueRunning[QueIdx]) { \
RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags); \
DBGPRINT(RT_DEBUG_OFF, ("DeQueueRunning[%d]= TRUE!\n", QueIdx)); \
continue; \
} else { \
pAd->DeQueueRunning[QueIdx] = TRUE; \
RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags);\
} \
} while (0)
#define RTMP_STOP_DEQUEUE(pAd, QueIdx, irqFlags) \
do { \
RTMP_IRQ_LOCK(&pAd->DeQueueLock[QueIdx], irqFlags); \
pAd->DeQueueRunning[QueIdx] = FALSE; \
RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags); \
} while (0)
#define RTMP_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, freeNum, pPacket) \
(RTUSBFreeDescriptorRequest(pAd, pTxBlk->QueIdx, (pTxBlk->TotalFrameLen + GET_OS_PKT_LEN(pPacket))) == NDIS_STATUS_SUCCESS)
#define RTMP_RELEASE_DESC_RESOURCE(pAd, QueIdx) \
do {} while (0)
#define NEED_QUEUE_BACK_FOR_AGG(_pAd, _QueIdx, _freeNum, _TxFrameType) \
((_TxFrameType == TX_RALINK_FRAME) && \
(RTUSBNeedQueueBackForAgg(_pAd, _QueIdx)))
#define HAL_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber) \
RtmpUSB_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)
#define HAL_WriteTxResource(pAd, pTxBlk, bIsLast, pFreeNumber) \
RtmpUSB_WriteSingleTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)
#define HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber) \
RtmpUSB_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber)
#define HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, pFreeNumber) \
RtmpUSB_WriteMultiTxResource(pAd, pTxBlk, frameNum, pFreeNumber)
#define HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, TxIdx) \
RtmpUSB_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, TxIdx)
#define HAL_LastTxIdx(pAd, QueIdx, TxIdx) \
/*RtmpUSBDataLastTxIdx(pAd, QueIdx,TxIdx) */
#define HAL_KickOutTx(pAd, pTxBlk, QueIdx) \
RtmpUSBDataKickOut(pAd, pTxBlk, QueIdx)
#define HAL_KickOutMgmtTx(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen) \
RtmpUSBMgmtKickOut(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen)
#define HAL_KickOutNullFrameTx(_pAd, _QueIdx, _pNullFrame, _frameLen) \
RtmpUSBNullFrameKickOut(_pAd, _QueIdx, _pNullFrame, _frameLen)
#define GET_TXRING_FREENO(_pAd, _QueIdx) (_QueIdx) /*(_pAd->TxRing[_QueIdx].TxSwFreeIdx) */
#define GET_MGMTRING_FREENO(_pAd) (_pAd->MgmtRing.TxSwFreeIdx)
/* ----------------- RX Related MACRO ----------------- */
/*
* Device Hardware Interface Related MACRO
*/
#define RTMP_IRQ_INIT(pAd) do {} while (0)
#define RTMP_IRQ_ENABLE(pAd) do {} while (0)
/*
* MLME Related MACRO
*/
#define RTMP_MLME_HANDLER(pAd) RTUSBMlmeUp(pAd)
#define RTMP_MLME_PRE_SANITY_CHECK(pAd) \
{ if ((pAd->CommonCfg.bHardwareRadio == TRUE) && \
(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && \
(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))) { \
RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_CHECK_GPIO, NULL, 0); } }
#define RTMP_MLME_STA_QUICK_RSP_WAKE_UP(pAd) \
{ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_QKERIODIC_EXECUT, NULL, 0); \
RTUSBMlmeUp(pAd); }
#define RTMP_MLME_RESET_STATE_MACHINE(pAd) \
{ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_RESET_CONF, 0, NULL); \
RTUSBMlmeUp(pAd); }
#define RTMP_HANDLE_COUNTER_MEASURE(_pAd, _pEntry) \
{ RTUSBEnqueueInternalCmd(_pAd, CMDTHREAD_802_11_COUNTER_MEASURE, _pEntry, sizeof(struct rt_mac_table_entry)); \
RTUSBMlmeUp(_pAd); \
}
/*
* Power Save Related MACRO
*/
#define RTMP_PS_POLL_ENQUEUE(pAd) \
{ RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL); \
RTUSBKickBulkOut(pAd); }
#define RTMP_STA_FORCE_WAKEUP(_pAd, bFromTx) \
RT28xxUsbStaAsicForceWakeup(_pAd, bFromTx);
#define RTMP_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp) \
RT28xxUsbStaAsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
#define RTMP_SET_PSM_BIT(_pAd, _val) \
{\
if ((_pAd)->StaCfg.WindowsPowerMode == Ndis802_11PowerModeFast_PSP) \
MlmeSetPsmBit(_pAd, _val);\
else { \
u16 _psm_val; \
_psm_val = _val; \
RTUSBEnqueueInternalCmd(_pAd, CMDTHREAD_SET_PSM_BIT, &(_psm_val), sizeof(u16)); \
} \
}
#define RTMP_MLME_RADIO_ON(pAd) \
RT28xxUsbMlmeRadioOn(pAd);
#define RTMP_MLME_RADIO_OFF(pAd) \
RT28xxUsbMlmeRadioOFF(pAd);
#endif /*__MAC_USB_H__ // */
/*
*************************************************************************
* 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 __RT2860_H__
#define __RT2860_H__
#include "mac_pci.h"
#ifndef RTMP_PCI_SUPPORT
#error "For RT2860, you should define the compile flag -DRTMP_PCI_SUPPORT"
#endif
#ifndef RTMP_MAC_PCI
#error "For RT2880, you should define the compile flag -DRTMP_MAC_PCI"
#endif
/* */
/* Device ID & Vendor ID, these values should match EEPROM value */
/* */
#define NIC2860_PCI_DEVICE_ID 0x0601
#define NIC2860_PCIe_DEVICE_ID 0x0681
#define NIC2760_PCI_DEVICE_ID 0x0701 /* 1T/2R Cardbus ??? */
#define NIC2790_PCIe_DEVICE_ID 0x0781 /* 1T/2R miniCard */
#define VEN_AWT_PCIe_DEVICE_ID 0x1059
#define VEN_AWT_PCI_VENDOR_ID 0x1A3B
#define EDIMAX_PCI_VENDOR_ID 0x1432
#endif /*__RT2860_H__ // */
/*
*************************************************************************
* 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 __RT2870_H__
#define __RT2870_H__
#ifdef RT2870
#ifndef RTMP_USB_SUPPORT
#error "For RT2870, you should define the compile flag -DRTMP_USB_SUPPORT"
#endif
#ifndef RTMP_MAC_USB
#error "For RT2870, you should define the compile flag -DRTMP_MAC_USB"
#endif
#include "../rtmp_type.h"
#include "mac_usb.h"
/*#define RTMP_CHIP_NAME "RT2870" */
#endif /* RT2870 // */
#endif /*__RT2870_H__ // */
/*
*************************************************************************
* 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:
rt3070.h
Abstract:
Revision History:
Who When What
--------- ---------- ----------------------------------------------
*/
#ifndef __RT3070_H__
#define __RT3070_H__
#ifdef RT3070
#ifndef RTMP_USB_SUPPORT
#error "For RT3070, you should define the compile flag -DRTMP_USB_SUPPORT"
#endif
#ifndef RTMP_MAC_USB
#error "For RT3070, you should define the compile flag -DRTMP_MAC_USB"
#endif
#ifndef RTMP_RF_RW_SUPPORT
#error "For RT3070, you should define the compile flag -DRTMP_RF_RW_SUPPORT"
#endif
#ifndef RT30xx
#error "For RT3070, you should define the compile flag -DRT30xx"
#endif
#include "mac_usb.h"
#include "rt30xx.h"
/* */
/* Device ID & Vendor ID, these values should match EEPROM value */
/* */
#endif /* RT3070 // */
#endif /*__RT3070_H__ // */
/*
*************************************************************************
* 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
#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__ // */
/*
*************************************************************************
* 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 struct rt_reg_pair RT30xx_RFRegTable[];
extern u8 NUM_RF_REG_PARMS;
#endif /* RT30xx // */
#endif /*__RT30XX_H__ // */
此差异已折叠。
/*
*************************************************************************
* 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 */
/* */
/* 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; \
unsigned long _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 RTMP_MAC_USB
#define RTMP_RF_IO_WRITE32(_A, _V) RTUSBWriteRFRegister(_A, _V)
#endif /* RTMP_MAC_USB // */
#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 struct rt_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) = (u8)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.
*/
/* 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) = (u8)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) = (u8)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]; \
} \
}
/*
basic marco for BBP write operation.
_pAd: the data structure pointer of struct rt_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.
*/
/* 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 boundary ****** \n"); \
} \
}
#endif /* RTMP_MAC_PCI // */
#ifdef RTMP_MAC_USB
#define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) RTUSBReadBBPRegister(_A, _I, _pV)
#define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) RTUSBWriteBBPRegister(_A, _I, _V)
#define BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) RTUSBWriteBBPRegister(_A, _I, _V)
#define BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) RTUSBReadBBPRegister(_A, _I, _pV)
#endif /* RTMP_MAC_USB // */
#ifdef RT30xx
#define RTMP_ASIC_MMPS_DISABLE(_pAd) \
do { \
u32 _macData; \
u8 _bbpData = 0; \
/* 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 { \
u32 _macData; \
u8 _bbpData = 0; \
/* 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__ // */
/*
*************************************************************************
* 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:
rt3070.c
Abstract:
Specific funcitons and variables for RT3070
Revision History:
Who When What
-------- ---------- ----------------------------------------------
*/
#ifdef RT3070
#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 NICInitRT3070RFRegisters(struct rt_rtmp_adapter *pAd)
{
int i;
u8 RFValue;
/* Driver must read EEPROM to get RfIcType before initial RF registers */
/* Initialize RF register to default value */
if (IS_RT3070(pAd) || IS_RT3071(pAd)) {
/* Init RF calibration */
/* Driver should toggle RF R30 bit7 before init RF registers */
u32 RfReg = 0;
u32 data;
RT30xxReadRFRegister(pAd, RF_R30, (u8 *)&RfReg);
RfReg |= 0x80;
RT30xxWriteRFRegister(pAd, RF_R30, (u8)RfReg);
RTMPusecDelay(1000);
RfReg &= 0x7F;
RT30xxWriteRFRegister(pAd, RF_R30, (u8)RfReg);
/* 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);
}
/* add by johnli */
if (IS_RT3070(pAd)) {
/* */
/* The DAC issue(LDO_CFG0) has been fixed in RT3070(F). */
/* The voltage raising patch is no longer needed for RT3070(F) */
/* */
if ((pAd->MACVersion & 0xffff) < 0x0201) {
/* Update MAC 0x05D4 from 01xxxxxx to 0Dxxxxxx (voltage 1.2V to 1.35V) for RT3070 to improve yield rate */
RTUSBReadMACRegister(pAd, LDO_CFG0, &data);
data = ((data & 0xF0FFFFFF) | 0x0D000000);
RTUSBWriteMACRegister(pAd, LDO_CFG0, data);
}
} else if (IS_RT3071(pAd)) {
/* Driver should set RF R6 bit6 on before init RF registers */
RT30xxReadRFRegister(pAd, RF_R06, (u8 *)&RfReg);
RfReg |= 0x40;
RT30xxWriteRFRegister(pAd, RF_R06, (u8)RfReg);
/* init R31 */
RT30xxWriteRFRegister(pAd, RF_R31, 0x14);
/* RT3071 version E has fixed this issue */
if ((pAd->NicConfig2.field.DACTestBit == 1)
&& ((pAd->MACVersion & 0xffff) < 0x0211)) {
/* patch tx EVM issue temporarily */
RTUSBReadMACRegister(pAd, LDO_CFG0, &data);
data = ((data & 0xE0FFFFFF) | 0x0D000000);
RTUSBWriteMACRegister(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 */
RTUSBReadMACRegister(pAd, GPIO_SWITCH, &data);
data &= ~(0x20);
RTUSBWriteMACRegister(pAd, GPIO_SWITCH, data);
}
/*For RF filter Calibration */
RTMPFilterCalibration(pAd);
/* Initialize RF R27 register, set RF R27 must be behind RTMPFilterCalibration() */
/* */
/* 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_RT3070(pAd)) && ((pAd->MACVersion & 0xffff) < 0x0201)) {
RT30xxWriteRFRegister(pAd, RF_R27, 0x3);
} else if ((IS_RT3071(pAd))
&& ((pAd->MACVersion & 0xffff) < 0x0211)) {
RT30xxWriteRFRegister(pAd, RF_R27, 0x3);
}
/* set led open drain enable */
RTUSBReadMACRegister(pAd, OPT_14, &data);
data |= 0x01;
RTUSBWriteMACRegister(pAd, OPT_14, data);
/* move from RT30xxLoadRFNormalModeSetup because it's needed for both RT3070 and RT3071 */
/* 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->NicConfig2.field.ExternalLNAForG == 0) {
if ((IS_RT3071(pAd)
&& ((pAd->MACVersion & 0xffff) >= 0x0211))
|| IS_RT3070(pAd)) {
RFValue |= 0x20;
}
}
/* set RF_R17_bit[2:0] equal to EEPROM setting at 0x48h */
if (pAd->TxMixerGain24G >= 1) {
RFValue &= (~0x7); /* clean bit [2:0] */
RFValue |= pAd->TxMixerGain24G;
}
RT30xxWriteRFRegister(pAd, RF_R17, RFValue);
if (IS_RT3071(pAd)) {
/* add by johnli, RF power sequence setup, load RF normal operation-mode setup */
RT30xxLoadRFNormalModeSetup(pAd);
} else if (IS_RT3070(pAd)) {
/* 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 ((pAd->MACVersion & 0xffff) < 0x0201)
RFValue = (RFValue & (~0x77)) | 0x3;
else
RFValue = (RFValue & (~0x77));
RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
/* end johnli */
}
}
}
#endif /* RT3070 // */
/*
*************************************************************************
* 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 functions and variables for RT3070
Revision History:
Who When What
Justin P. Mattock 11/07/2010 Fix a typo
-------- ---------- ----------------------------------------------
*/
#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(struct rt_rtmp_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 */
u8 RfReg;
u32 data;
RT30xxReadRFRegister(pAd, RF_R30, (u8 *)&RfReg);
RfReg |= 0x80;
RT30xxWriteRFRegister(pAd, RF_R30, (u8)RfReg);
RTMPusecDelay(1000);
RfReg &= 0x7F;
RT30xxWriteRFRegister(pAd, RF_R30, (u8)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, (u8 *)&RfReg);
RfReg |= 0x40;
RT30xxWriteRFRegister(pAd, RF_R06, (u8)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 // */
/*
*************************************************************************
* 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 functions and variables for RT30xx.
Revision History:
Who When What
Justin P. Mattock 11/07/2010 Fix some typos
-------- ---------- ----------------------------------------------
*/
#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 */
/* */
struct rt_reg_pair RT30xx_RFRegTable[] = {
{RF_R04, 0x40}
,
{RF_R05, 0x03}
,
{RF_R06, 0x02}
,
{RF_R07, 0x60}
,
{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}
,
};
u8 NUM_RF_REG_PARMS = (sizeof(RT30xx_RFRegTable) / sizeof(struct rt_reg_pair));
/* Antenna diversity 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(struct rt_rtmp_adapter *pAd, u8 Ant)
{
u32 Value;
#ifdef RTMP_MAC_PCI
u32 x;
#endif
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(struct rt_rtmp_adapter *pAd)
{
u8 R55x = 0, value, FilterTarget = 0x1E, BBPValue = 0;
u32 loop = 0, count = 0, loopcnt = 0, ReTry = 0;
u8 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; causes 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 = (u8)RF_R24_Value;
} else {
/*BandWidth = 40 MHz */
pAd->Mlme.CaliBW40RfR24 = (u8)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(struct rt_rtmp_adapter *pAd)
{
u8 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(struct rt_rtmp_adapter *pAd)
{
u8 RFValue;
u32 MACValue;
#ifdef RTMP_MAC_USB
if (!IS_RT3572(pAd))
#endif /* RTMP_MAC_USB // */
{
/* 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))) {
#ifdef RTMP_MAC_USB
if (!IS_RT3572(pAd))
#endif /* RTMP_MAC_USB // */
{
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(struct rt_rtmp_adapter *pAd)
{
u8 RFValue;
u32 MACValue;
#ifdef RTMP_MAC_USB
if (!IS_RT3572(pAd))
#endif /* RTMP_MAC_USB // */
{
/* 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 |= 0x20;
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))) {
#ifdef RTMP_MAC_USB
if (!IS_RT3572(pAd))
#endif /* RTMP_MAC_USB // */
{
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(struct rt_rtmp_adapter *pAd)
{
u32 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 // */
/*
*************************************************************************
* 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.c
Abstract:
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
struct rt_ch_desp {
u8 FirstChannel;
u8 NumOfCh;
char MaxTxPwr; /* dBm */
u8 Geography; /* 0:out door, 1:in door, 2:both */
BOOLEAN DfsReq; /* Dfs require, 0: No, 1: yes. */
};
struct rt_ch_region {
u8 CountReg[3];
u8 DfsType; /* 0: CE, 1: FCC, 2: JAP, 3:JAP_W53, JAP_W56 */
struct rt_ch_desp ChDesp[10];
};
extern struct rt_ch_region ChRegion[];
struct rt_ch_freq_map {
u16 channel;
u16 freqKHz;
};
extern struct rt_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(struct rt_rtmp_adapter *pAd);
void BuildBeaconChList(struct rt_rtmp_adapter *pAd,
u8 *pBuf, unsigned long *pBufLen);
void N_ChannelCheck(struct rt_rtmp_adapter *pAd);
void N_SetCenCh(struct rt_rtmp_adapter *pAd);
u8 GetCuntryMaxTxPwr(struct rt_rtmp_adapter *pAd, u8 channel);
#endif /* __CHLIST_H__ */
/*
*************************************************************************
* 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:
action.c
Abstract:
Handle association related requests either from WSTA or from local MLME
Revision History:
Who When What
-------- ---------- ----------------------------------------------
Jan Lee 2006 created for rt2860
*/
#include "../rt_config.h"
#include "action.h"
static void ReservedAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
/*
==========================================================================
Description:
association state machine init, including state transition and timer init
Parameters:
S - pointer to the association state machine
Note:
The state machine looks like the following
ASSOC_IDLE
MT2_MLME_DISASSOC_REQ mlme_disassoc_req_action
MT2_PEER_DISASSOC_REQ peer_disassoc_action
MT2_PEER_ASSOC_REQ drop
MT2_PEER_REASSOC_REQ drop
MT2_CLS3ERR cls3err_action
==========================================================================
*/
void ActionStateMachineInit(struct rt_rtmp_adapter *pAd,
struct rt_state_machine *S,
OUT STATE_MACHINE_FUNC Trans[])
{
StateMachineInit(S, (STATE_MACHINE_FUNC *) Trans, MAX_ACT_STATE,
MAX_ACT_MSG, (STATE_MACHINE_FUNC) Drop, ACT_IDLE,
ACT_MACHINE_BASE);
StateMachineSetAction(S, ACT_IDLE, MT2_PEER_SPECTRUM_CATE,
(STATE_MACHINE_FUNC) PeerSpectrumAction);
StateMachineSetAction(S, ACT_IDLE, MT2_PEER_QOS_CATE,
(STATE_MACHINE_FUNC) PeerQOSAction);
StateMachineSetAction(S, ACT_IDLE, MT2_PEER_DLS_CATE,
(STATE_MACHINE_FUNC) ReservedAction);
StateMachineSetAction(S, ACT_IDLE, MT2_PEER_BA_CATE,
(STATE_MACHINE_FUNC) PeerBAAction);
StateMachineSetAction(S, ACT_IDLE, MT2_PEER_HT_CATE,
(STATE_MACHINE_FUNC) PeerHTAction);
StateMachineSetAction(S, ACT_IDLE, MT2_MLME_ADD_BA_CATE,
(STATE_MACHINE_FUNC) MlmeADDBAAction);
StateMachineSetAction(S, ACT_IDLE, MT2_MLME_ORI_DELBA_CATE,
(STATE_MACHINE_FUNC) MlmeDELBAAction);
StateMachineSetAction(S, ACT_IDLE, MT2_MLME_REC_DELBA_CATE,
(STATE_MACHINE_FUNC) MlmeDELBAAction);
StateMachineSetAction(S, ACT_IDLE, MT2_PEER_PUBLIC_CATE,
(STATE_MACHINE_FUNC) PeerPublicAction);
StateMachineSetAction(S, ACT_IDLE, MT2_PEER_RM_CATE,
(STATE_MACHINE_FUNC) PeerRMAction);
StateMachineSetAction(S, ACT_IDLE, MT2_MLME_QOS_CATE,
(STATE_MACHINE_FUNC) MlmeQOSAction);
StateMachineSetAction(S, ACT_IDLE, MT2_MLME_DLS_CATE,
(STATE_MACHINE_FUNC) MlmeDLSAction);
StateMachineSetAction(S, ACT_IDLE, MT2_ACT_INVALID,
(STATE_MACHINE_FUNC) MlmeInvalidAction);
}
void MlmeADDBAAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
{
struct rt_mlme_addba_req *pInfo;
u8 Addr[6];
u8 *pOutBuffer = NULL;
int NStatus;
unsigned long Idx;
struct rt_frame_addba_req Frame;
unsigned long FrameLen;
struct rt_ba_ori_entry *pBAEntry = NULL;
pInfo = (struct rt_mlme_addba_req *)Elem->Msg;
NdisZeroMemory(&Frame, sizeof(struct rt_frame_addba_req));
if (MlmeAddBAReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr)) {
NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */
if (NStatus != NDIS_STATUS_SUCCESS) {
DBGPRINT(RT_DEBUG_TRACE,
("BA - MlmeADDBAAction() allocate memory failed \n"));
return;
}
/* 1. find entry */
Idx =
pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID];
if (Idx == 0) {
MlmeFreeMemory(pAd, pOutBuffer);
DBGPRINT(RT_DEBUG_ERROR,
("BA - MlmeADDBAAction() can't find BAOriEntry \n"));
return;
} else {
pBAEntry = &pAd->BATable.BAOriEntry[Idx];
}
{
if (ADHOC_ON(pAd))
ActHeaderInit(pAd, &Frame.Hdr, pInfo->pAddr,
pAd->CurrentAddress,
pAd->CommonCfg.Bssid);
else
ActHeaderInit(pAd, &Frame.Hdr,
pAd->CommonCfg.Bssid,
pAd->CurrentAddress,
pInfo->pAddr);
}
Frame.Category = CATEGORY_BA;
Frame.Action = ADDBA_REQ;
Frame.BaParm.AMSDUSupported = 0;
Frame.BaParm.BAPolicy = IMMED_BA;
Frame.BaParm.TID = pInfo->TID;
Frame.BaParm.BufSize = pInfo->BaBufSize;
Frame.Token = pInfo->Token;
Frame.TimeOutValue = pInfo->TimeOutValue;
Frame.BaStartSeq.field.FragNum = 0;
Frame.BaStartSeq.field.StartSeq =
pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID];
*(u16 *) (&Frame.BaParm) =
cpu2le16(*(u16 *) (&Frame.BaParm));
Frame.TimeOutValue = cpu2le16(Frame.TimeOutValue);
Frame.BaStartSeq.word = cpu2le16(Frame.BaStartSeq.word);
MakeOutgoingFrame(pOutBuffer, &FrameLen,
sizeof(struct rt_frame_addba_req), &Frame, END_OF_ARGS);
MiniportMMRequest(pAd,
(MGMT_USE_QUEUE_FLAG |
MapUserPriorityToAccessCategory[pInfo->TID]),
pOutBuffer, FrameLen);
MlmeFreeMemory(pAd, pOutBuffer);
DBGPRINT(RT_DEBUG_TRACE,
("BA - Send ADDBA request. StartSeq = %x, FrameLen = %ld. BufSize = %d\n",
Frame.BaStartSeq.field.StartSeq, FrameLen,
Frame.BaParm.BufSize));
}
}
/*
==========================================================================
Description:
send DELBA and delete BaEntry if any
Parametrs:
Elem - MLME message struct rt_mlme_delba_req
IRQL = DISPATCH_LEVEL
==========================================================================
*/
void MlmeDELBAAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
{
struct rt_mlme_delba_req *pInfo;
u8 *pOutBuffer = NULL;
u8 *pOutBuffer2 = NULL;
int NStatus;
unsigned long Idx;
struct rt_frame_delba_req Frame;
unsigned long FrameLen;
struct rt_frame_bar FrameBar;
pInfo = (struct rt_mlme_delba_req *)Elem->Msg;
/* must send back DELBA */
NdisZeroMemory(&Frame, sizeof(struct rt_frame_delba_req));
DBGPRINT(RT_DEBUG_TRACE,
("==> MlmeDELBAAction(), Initiator(%d) \n", pInfo->Initiator));
if (MlmeDelBAReqSanity(pAd, Elem->Msg, Elem->MsgLen)) {
NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */
if (NStatus != NDIS_STATUS_SUCCESS) {
DBGPRINT(RT_DEBUG_ERROR,
("BA - MlmeDELBAAction() allocate memory failed 1. \n"));
return;
}
NStatus = MlmeAllocateMemory(pAd, &pOutBuffer2); /*Get an unused nonpaged memory */
if (NStatus != NDIS_STATUS_SUCCESS) {
MlmeFreeMemory(pAd, pOutBuffer);
DBGPRINT(RT_DEBUG_ERROR,
("BA - MlmeDELBAAction() allocate memory failed 2. \n"));
return;
}
/* SEND BAR (Send BAR to refresh peer reordering buffer.) */
Idx =
pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID];
BarHeaderInit(pAd, &FrameBar,
pAd->MacTab.Content[pInfo->Wcid].Addr,
pAd->CurrentAddress);
FrameBar.StartingSeq.field.FragNum = 0; /* make sure sequence not clear in DEL funciton. */
FrameBar.StartingSeq.field.StartSeq = pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID]; /* make sure sequence not clear in DEL funciton. */
FrameBar.BarControl.TID = pInfo->TID; /* make sure sequence not clear in DEL funciton. */
FrameBar.BarControl.ACKPolicy = IMMED_BA; /* make sure sequence not clear in DEL funciton. */
FrameBar.BarControl.Compressed = 1; /* make sure sequence not clear in DEL funciton. */
FrameBar.BarControl.MTID = 0; /* make sure sequence not clear in DEL funciton. */
MakeOutgoingFrame(pOutBuffer2, &FrameLen,
sizeof(struct rt_frame_bar), &FrameBar, END_OF_ARGS);
MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer2, FrameLen);
MlmeFreeMemory(pAd, pOutBuffer2);
DBGPRINT(RT_DEBUG_TRACE,
("BA - MlmeDELBAAction() . Send BAR to refresh peer reordering buffer \n"));
/* SEND DELBA FRAME */
FrameLen = 0;
{
if (ADHOC_ON(pAd))
ActHeaderInit(pAd, &Frame.Hdr,
pAd->MacTab.Content[pInfo->Wcid].
Addr, pAd->CurrentAddress,
pAd->CommonCfg.Bssid);
else
ActHeaderInit(pAd, &Frame.Hdr,
pAd->CommonCfg.Bssid,
pAd->CurrentAddress,
pAd->MacTab.Content[pInfo->Wcid].
Addr);
}
Frame.Category = CATEGORY_BA;
Frame.Action = DELBA;
Frame.DelbaParm.Initiator = pInfo->Initiator;
Frame.DelbaParm.TID = pInfo->TID;
Frame.ReasonCode = 39; /* Time Out */
*(u16 *) (&Frame.DelbaParm) =
cpu2le16(*(u16 *) (&Frame.DelbaParm));
Frame.ReasonCode = cpu2le16(Frame.ReasonCode);
MakeOutgoingFrame(pOutBuffer, &FrameLen,
sizeof(struct rt_frame_delba_req), &Frame, END_OF_ARGS);
MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
MlmeFreeMemory(pAd, pOutBuffer);
DBGPRINT(RT_DEBUG_TRACE,
("BA - MlmeDELBAAction() . 3 DELBA sent. Initiator(%d)\n",
pInfo->Initiator));
}
}
void MlmeQOSAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
{
}
void MlmeDLSAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
{
}
void MlmeInvalidAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
{
/*u8 * pOutBuffer = NULL; */
/*Return the receiving frame except the MSB of category filed set to 1. 7.3.1.11 */
}
void PeerQOSAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
{
}
void PeerBAAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
{
u8 Action = Elem->Msg[LENGTH_802_11 + 1];
switch (Action) {
case ADDBA_REQ:
PeerAddBAReqAction(pAd, Elem);
break;
case ADDBA_RESP:
PeerAddBARspAction(pAd, Elem);
break;
case DELBA:
PeerDelBAAction(pAd, Elem);
break;
}
}
void PeerPublicAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
{
if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
return;
}
static void ReservedAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
{
u8 Category;
if (Elem->MsgLen <= LENGTH_802_11) {
return;
}
Category = Elem->Msg[LENGTH_802_11];
DBGPRINT(RT_DEBUG_TRACE,
("Rcv reserved category(%d) Action Frame\n", Category));
hex_dump("Reserved Action Frame", &Elem->Msg[0], Elem->MsgLen);
}
void PeerRMAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
{
return;
}
static void respond_ht_information_exchange_action(struct rt_rtmp_adapter *pAd,
struct rt_mlme_queue_elem *Elem)
{
u8 *pOutBuffer = NULL;
int NStatus;
unsigned long FrameLen;
struct rt_frame_ht_info HTINFOframe, *pFrame;
u8 *pAddr;
/* 2. Always send back ADDBA Response */
NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */
if (NStatus != NDIS_STATUS_SUCCESS) {
DBGPRINT(RT_DEBUG_TRACE,
("ACTION - respond_ht_information_exchange_action() allocate memory failed \n"));
return;
}
/* get RA */
pFrame = (struct rt_frame_ht_info *) & Elem->Msg[0];
pAddr = pFrame->Hdr.Addr2;
NdisZeroMemory(&HTINFOframe, sizeof(struct rt_frame_ht_info));
/* 2-1. Prepare ADDBA Response frame. */
{
if (ADHOC_ON(pAd))
ActHeaderInit(pAd, &HTINFOframe.Hdr, pAddr,
pAd->CurrentAddress,
pAd->CommonCfg.Bssid);
else
ActHeaderInit(pAd, &HTINFOframe.Hdr,
pAd->CommonCfg.Bssid, pAd->CurrentAddress,
pAddr);
}
HTINFOframe.Category = CATEGORY_HT;
HTINFOframe.Action = HT_INFO_EXCHANGE;
HTINFOframe.HT_Info.Request = 0;
HTINFOframe.HT_Info.Forty_MHz_Intolerant =
pAd->CommonCfg.HtCapability.HtCapInfo.Forty_Mhz_Intolerant;
HTINFOframe.HT_Info.STA_Channel_Width =
pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth;
MakeOutgoingFrame(pOutBuffer, &FrameLen,
sizeof(struct rt_frame_ht_info), &HTINFOframe, END_OF_ARGS);
MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
MlmeFreeMemory(pAd, pOutBuffer);
}
void PeerHTAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
{
u8 Action = Elem->Msg[LENGTH_802_11 + 1];
if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
return;
switch (Action) {
case NOTIFY_BW_ACTION:
DBGPRINT(RT_DEBUG_TRACE,
("ACTION - HT Notify Channel bandwidth action----> \n"));
if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) {
/* Note, this is to patch DIR-1353 AP. When the AP set to Wep, it will use legacy mode. But AP still keeps */
/* sending BW_Notify Action frame, and cause us to linkup and linkdown. */
/* In legacy mode, don't need to parse HT action frame. */
DBGPRINT(RT_DEBUG_TRACE,
("ACTION -Ignore HT Notify Channel BW when link as legacy mode. BW = %d---> \n",
Elem->Msg[LENGTH_802_11 + 2]));
break;
}
if (Elem->Msg[LENGTH_802_11 + 2] == 0) /* 7.4.8.2. if value is 1, keep the same as supported channel bandwidth. */
pAd->MacTab.Content[Elem->Wcid].HTPhyMode.field.BW = 0;
break;
case SMPS_ACTION:
/* 7.3.1.25 */
DBGPRINT(RT_DEBUG_TRACE, ("ACTION - SMPS action----> \n"));
if (((Elem->Msg[LENGTH_802_11 + 2] & 0x1) == 0)) {
pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_ENABLE;
} else if (((Elem->Msg[LENGTH_802_11 + 2] & 0x2) == 0)) {
pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_STATIC;
} else {
pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_DYNAMIC;
}
DBGPRINT(RT_DEBUG_TRACE,
("Aid(%d) MIMO PS = %d\n", Elem->Wcid,
pAd->MacTab.Content[Elem->Wcid].MmpsMode));
/* rt2860c : add something for smps change. */
break;
case SETPCO_ACTION:
break;
case MIMO_CHA_MEASURE_ACTION:
break;
case HT_INFO_EXCHANGE:
{
struct rt_ht_information_octet *pHT_info;
pHT_info =
(struct rt_ht_information_octet *) & Elem->Msg[LENGTH_802_11 +
2];
/* 7.4.8.10 */
DBGPRINT(RT_DEBUG_TRACE,
("ACTION - HT Information Exchange action----> \n"));
if (pHT_info->Request) {
respond_ht_information_exchange_action(pAd,
Elem);
}
}
break;
}
}
/*
==========================================================================
Description:
Retry sending ADDBA Reqest.
IRQL = DISPATCH_LEVEL
Parametrs:
p8023Header: if this is already 802.3 format, p8023Header is NULL
Return : TRUE if put into rx reordering buffer, shouldn't indicaterxhere.
FALSE , then continue indicaterx at this moment.
==========================================================================
*/
void ORIBATimerTimeout(struct rt_rtmp_adapter *pAd)
{
struct rt_mac_table_entry *pEntry;
int i, total;
u8 TID;
total = pAd->MacTab.Size * NUM_OF_TID;
for (i = 1; ((i < MAX_LEN_OF_BA_ORI_TABLE) && (total > 0)); i++) {
if (pAd->BATable.BAOriEntry[i].ORI_BA_Status == Originator_Done) {
pEntry =
&pAd->MacTab.Content[pAd->BATable.BAOriEntry[i].
Wcid];
TID = pAd->BATable.BAOriEntry[i].TID;
ASSERT(pAd->BATable.BAOriEntry[i].Wcid <
MAX_LEN_OF_MAC_TABLE);
}
total--;
}
}
void SendRefreshBAR(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry)
{
struct rt_frame_bar FrameBar;
unsigned long FrameLen;
int NStatus;
u8 *pOutBuffer = NULL;
u16 Sequence;
u8 i, TID;
u16 idx;
struct rt_ba_ori_entry *pBAEntry;
for (i = 0; i < NUM_OF_TID; i++) {
idx = pEntry->BAOriWcidArray[i];
if (idx == 0) {
continue;
}
pBAEntry = &pAd->BATable.BAOriEntry[idx];
if (pBAEntry->ORI_BA_Status == Originator_Done) {
TID = pBAEntry->TID;
ASSERT(pBAEntry->Wcid < MAX_LEN_OF_MAC_TABLE);
NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */
if (NStatus != NDIS_STATUS_SUCCESS) {
DBGPRINT(RT_DEBUG_ERROR,
("BA - MlmeADDBAAction() allocate memory failed \n"));
return;
}
Sequence = pEntry->TxSeq[TID];
BarHeaderInit(pAd, &FrameBar, pEntry->Addr,
pAd->CurrentAddress);
FrameBar.StartingSeq.field.FragNum = 0; /* make sure sequence not clear in DEL function. */
FrameBar.StartingSeq.field.StartSeq = Sequence; /* make sure sequence not clear in DEL funciton. */
FrameBar.BarControl.TID = TID; /* make sure sequence not clear in DEL funciton. */
MakeOutgoingFrame(pOutBuffer, &FrameLen,
sizeof(struct rt_frame_bar), &FrameBar,
END_OF_ARGS);
/*if (!(CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET))) */
if (1) /* Now we always send BAR. */
{
/*MiniportMMRequestUnlock(pAd, 0, pOutBuffer, FrameLen); */
MiniportMMRequest(pAd,
(MGMT_USE_QUEUE_FLAG |
MapUserPriorityToAccessCategory
[TID]), pOutBuffer,
FrameLen);
}
MlmeFreeMemory(pAd, pOutBuffer);
}
}
}
void ActHeaderInit(struct rt_rtmp_adapter *pAd,
struct rt_header_802_11 * pHdr80211,
u8 *Addr1, u8 *Addr2, u8 *Addr3)
{
NdisZeroMemory(pHdr80211, sizeof(struct rt_header_802_11));
pHdr80211->FC.Type = BTYPE_MGMT;
pHdr80211->FC.SubType = SUBTYPE_ACTION;
COPY_MAC_ADDR(pHdr80211->Addr1, Addr1);
COPY_MAC_ADDR(pHdr80211->Addr2, Addr2);
COPY_MAC_ADDR(pHdr80211->Addr3, Addr3);
}
void BarHeaderInit(struct rt_rtmp_adapter *pAd,
struct rt_frame_bar * pCntlBar, u8 *pDA, u8 *pSA)
{
NdisZeroMemory(pCntlBar, sizeof(struct rt_frame_bar));
pCntlBar->FC.Type = BTYPE_CNTL;
pCntlBar->FC.SubType = SUBTYPE_BLOCK_ACK_REQ;
pCntlBar->BarControl.MTID = 0;
pCntlBar->BarControl.Compressed = 1;
pCntlBar->BarControl.ACKPolicy = 0;
pCntlBar->Duration =
16 + RTMPCalcDuration(pAd, RATE_1, sizeof(struct rt_frame_ba));
COPY_MAC_ADDR(pCntlBar->Addr1, pDA);
COPY_MAC_ADDR(pCntlBar->Addr2, pSA);
}
/*
==========================================================================
Description:
Insert Category and action code into the action frame.
Parametrs:
1. frame buffer pointer.
2. frame length.
3. category code of the frame.
4. action code of the frame.
Return : None.
==========================================================================
*/
void InsertActField(struct rt_rtmp_adapter *pAd,
u8 *pFrameBuf,
unsigned long *pFrameLen, u8 Category, u8 ActCode)
{
unsigned long TempLen;
MakeOutgoingFrame(pFrameBuf, &TempLen,
1, &Category, 1, &ActCode, END_OF_ARGS);
*pFrameLen = *pFrameLen + TempLen;
return;
}
/*
*************************************************************************
* 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__
struct PACKED rt_ht_information_octet {
u8 Request:1;
u8 Forty_MHz_Intolerant:1;
u8 STA_Channel_Width:1;
u8 Reserved:5;
};
struct PACKED rt_frame_ht_info {
struct rt_header_802_11 Hdr;
u8 Category;
u8 Action;
struct rt_ht_information_octet HT_Info;
};
#endif /* __ACTION_H__ */
此差异已折叠。
此差异已折叠。
此差异已折叠。
/*
*************************************************************************
* 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";
case MODE_HTMIX:
return "HTMIX";
case MODE_HTGREENFIELD:
return "GREEN";
default:
return "N/A";
}
}
char *GetBW(int BW)
{
switch (BW) {
case BW_10:
return "10M";
case BW_20:
return "20M";
case BW_40:
return "40M";
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(struct rt_rtmp_adapter *pAd, char *arg, int band)
{
long region, regionMax;
u8 *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 = (u8)region;
} else if ((region == REGION_31_BG_BAND) && (band == BAND_24G)) {
*pCountryRegion = (u8)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(struct rt_rtmp_adapter *pAd, char *arg)
{
int MaxPhyMode = PHY_11G;
long WirelessMode;
MaxPhyMode = PHY_11N_5G;
WirelessMode = simple_strtol(arg, 0, 10);
if (WirelessMode <= MaxPhyMode) {
pAd->CommonCfg.PhyMode = WirelessMode;
return TRUE;
}
return FALSE;
}
int RT_CfgSetShortSlot(struct rt_rtmp_adapter *pAd, char *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(struct rt_rtmp_adapter *pAd,
char *keyString,
struct rt_cipher_key *pSharedKey, int keyIdx)
{
int KeyLen;
int i;
u8 CipherAlg = CIPHER_NONE;
BOOLEAN bKeyIsHex = FALSE;
/* TODO: Shall we do memset for the original key info?? */
memset(pSharedKey, 0, sizeof(struct rt_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 Length of the hash string
pPMKBuf Output buffer of WPAPSK key
Return:
TRUE if all parameters are OK, FALSE otherwise
==========================================================================
*/
int RT_CfgSetWPAPSKKey(struct rt_rtmp_adapter *pAd,
char *keyString,
u8 * pHashStr,
int hashStrLen, u8 *pPMKBuf)
{
int keyLen;
u8 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;
}
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
/*
*************************************************************************
* 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 u8 Key[],
u32 KeyLen,
IN const u8 Message[],
u32 MessageLen, u8 MAC[], u32 MACLen)
{
struct rt_sha1_ctx sha_ctx1;
struct rt_sha1_ctx sha_ctx2;
u8 K0[SHA1_BLOCK_SIZE];
u8 Digest[SHA1_DIGEST_SIZE];
u32 index;
NdisZeroMemory(&sha_ctx1, sizeof(struct rt_sha1_ctx));
NdisZeroMemory(&sha_ctx2, sizeof(struct rt_sha1_ctx));
/*
* 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¡¦36¡¦ repeated B times. */
for (index = 0; index < SHA1_BLOCK_SIZE; index++)
K0[index] ^= 0x36;
/* End of for */
RT_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¡¦5c¡¦ repeated B times. */
for (index = 0; index < SHA1_BLOCK_SIZE; index++)
K0[index] ^= 0x36 ^ 0x5c;
/* End of for */
RT_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_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 u8 Key[],
u32 KeyLen,
IN const u8 Message[],
u32 MessageLen, u8 MAC[], u32 MACLen)
{
struct rt_md5_ctx_struc md5_ctx1;
struct rt_md5_ctx_struc md5_ctx2;
u8 K0[MD5_BLOCK_SIZE];
u8 Digest[MD5_DIGEST_SIZE];
u32 index;
NdisZeroMemory(&md5_ctx1, sizeof(struct rt_md5_ctx_struc));
NdisZeroMemory(&md5_ctx2, sizeof(struct rt_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¡¦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¡¦5c¡¦ 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 */
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册