From: wlanfae <wlanfae@realtek.com>

[PATCH 1/8] rtl8192e: Import new version of driver from realtek

Signed-off-by: wlanfae <wlanfae@realtek.com>
Signed-off-by: Mike McCormack <mikem@ring3k.org>
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
---
This commit is contained in:
Larry Finger 2011-08-23 19:00:42 -05:00
parent 8cfcabf80c
commit 94a799425e
76 changed files with 59876 additions and 14262 deletions

View file

@ -1,38 +1,46 @@
NIC_SELECT = RTL8192E
ccflags-y := -DRTL8192E
ccflags-y += -std=gnu89
ccflags-y += -O2
ccflags-y += -DTHOMAS_TURBO
ccflags-y += -DRTL8192E
ccflags-y += -DEEPROM_OLD_FORMAT_SUPPORT=1
ccflags-y += -DUSE_FW_SOURCE_IMG_FILE
ccflags-y += -DENABLE_GPIO_RADIO_CTL
ccflags-y += -DCONFIG_PM_RTL
ccflags-y += -DCONFIG_PM
ccflags-y += -DENABLE_DOT11D
ccflags-y += -DHAVE_NET_DEVICE_OPS
ccflags-y += -DENABLE_DOT11D
ccflags-y += -DENABLE_IPS
ccflags-y += -DENABLE_LPS
r8192e_pci-objs := \
r8192E_core.o \
r8180_93cx6.o \
r8192E_wx.o \
r8190_rtl8256.o \
r819xE_phy.o \
r819xE_firmware.o \
r819xE_cmdpkt.o \
r8192E_dm.o \
r8192_pm.o \
ieee80211/ieee80211_rx.o \
ieee80211/ieee80211_softmac.o \
ieee80211/ieee80211_tx.o \
ieee80211/ieee80211_wx.o \
ieee80211/ieee80211_module.o \
ieee80211/ieee80211_softmac_wx.o \
ieee80211/rtl819x_HTProc.o \
ieee80211/rtl819x_TSProc.o \
ieee80211/rtl819x_BAProc.o \
ieee80211/dot11d.o \
ieee80211/ieee80211_crypt.o \
ieee80211/ieee80211_crypt_tkip.o \
ieee80211/ieee80211_crypt_ccmp.o \
ieee80211/ieee80211_crypt_wep.o
rtl_core.o \
rtl_eeprom.o \
rtl_ps.o \
rtl_wx.o \
rtl_cam.o \
rtl_dm.o \
rtl_pm.o \
rtl_pci.o \
rtl_debug.o \
rtl_ethtool.o \
r8192E_dev.o \
r8192E_phy.o \
r8192E_firmware.o \
r8192E_cmdpkt.o \
r8192E_hwimg.o \
r8190P_rtl8256.o \
rtllib_rx.o \
rtllib_softmac.o \
rtllib_tx.o \
rtllib_wx.o \
rtllib_module.o \
rtllib_softmac_wx.o \
rtl819x_HTProc.o \
rtl819x_TSProc.o \
rtl819x_BAProc.o \
dot11d.o \
rtllib_crypt.o \
rtllib_crypt_tkip.o \
rtllib_crypt_ccmp.o \
rtllib_crypt_wep.o
obj-$(CONFIG_RTL8192E) += r8192e_pci.o

View file

@ -0,0 +1,216 @@
/******************************************************************************
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
******************************************************************************/
#include "dot11d.h"
struct channel_list {
u8 Channel[32];
u8 Len;
};
static struct channel_list ChannelPlan[] = {
{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64,
149, 153, 157, 161, 165}, 24},
{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11},
{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56,
60, 64}, 21},
{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52,
56, 60, 64}, 22},
{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52,
56, 60, 64}, 22},
{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52,
56, 60, 64}, 22},
{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52,
56, 60, 64}, 22},
{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14},
{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52,
56, 60, 64}, 21}
};
void Dot11d_Init(struct rtllib_device *ieee)
{
struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(ieee);
pDot11dInfo->bEnabled = false;
pDot11dInfo->State = DOT11D_STATE_NONE;
pDot11dInfo->CountryIeLen = 0;
memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
RESET_CIE_WATCHDOG(ieee);
}
void Dot11d_Channelmap(u8 channel_plan, struct rtllib_device *ieee)
{
int i, max_chan = 14, min_chan = 1;
ieee->bGlobalDomain = false;
if (ChannelPlan[channel_plan].Len != 0) {
memset(GET_DOT11D_INFO(ieee)->channel_map, 0,
sizeof(GET_DOT11D_INFO(ieee)->channel_map));
for (i = 0; i < ChannelPlan[channel_plan].Len; i++) {
if (ChannelPlan[channel_plan].Channel[i] < min_chan ||
ChannelPlan[channel_plan].Channel[i] > max_chan)
break;
GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan
[channel_plan].Channel[i]] = 1;
}
}
switch (channel_plan) {
case COUNTRY_CODE_GLOBAL_DOMAIN:
ieee->bGlobalDomain = true;
for (i = 12; i <= 14; i++)
GET_DOT11D_INFO(ieee)->channel_map[i] = 2;
ieee->IbssStartChnl = 10;
ieee->ibss_maxjoin_chal = 11;
break;
case COUNTRY_CODE_WORLD_WIDE_13:
for (i = 12; i <= 13; i++)
GET_DOT11D_INFO(ieee)->channel_map[i] = 2;
ieee->IbssStartChnl = 10;
ieee->ibss_maxjoin_chal = 11;
break;
default:
ieee->IbssStartChnl = 1;
ieee->ibss_maxjoin_chal = 14;
break;
}
}
void Dot11d_Reset(struct rtllib_device *ieee)
{
struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(ieee);
u32 i;
memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
for (i = 1; i <= 11; i++)
(pDot11dInfo->channel_map)[i] = 1;
for (i = 12; i <= 14; i++)
(pDot11dInfo->channel_map)[i] = 2;
pDot11dInfo->State = DOT11D_STATE_NONE;
pDot11dInfo->CountryIeLen = 0;
RESET_CIE_WATCHDOG(ieee);
}
void Dot11d_UpdateCountryIe(struct rtllib_device *dev, u8 *pTaddr,
u16 CoutryIeLen, u8 *pCoutryIe)
{
struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(dev);
u8 i, j, NumTriples, MaxChnlNum;
struct chnl_txpow_triple *pTriple;
memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
MaxChnlNum = 0;
NumTriples = (CoutryIeLen - 3) / 3;
pTriple = (struct chnl_txpow_triple *)(pCoutryIe + 3);
for (i = 0; i < NumTriples; i++) {
if (MaxChnlNum >= pTriple->FirstChnl) {
printk(KERN_INFO "Dot11d_UpdateCountryIe(): Invalid"
" country IE, skip it........1\n");
return;
}
if (MAX_CHANNEL_NUMBER < (pTriple->FirstChnl +
pTriple->NumChnls)) {
printk(KERN_INFO "Dot11d_UpdateCountryIe(): Invalid "
"country IE, skip it........2\n");
return;
}
for (j = 0 ; j < pTriple->NumChnls; j++) {
pDot11dInfo->channel_map[pTriple->FirstChnl + j] = 1;
pDot11dInfo->MaxTxPwrDbmList[pTriple->FirstChnl + j] =
pTriple->MaxTxPowerInDbm;
MaxChnlNum = pTriple->FirstChnl + j;
}
pTriple = (struct chnl_txpow_triple *)((u8*)pTriple + 3);
}
UPDATE_CIE_SRC(dev, pTaddr);
pDot11dInfo->CountryIeLen = CoutryIeLen;
memcpy(pDot11dInfo->CountryIeBuf, pCoutryIe, CoutryIeLen);
pDot11dInfo->State = DOT11D_STATE_LEARNED;
}
u8 DOT11D_GetMaxTxPwrInDbm(struct rtllib_device *dev, u8 Channel)
{
struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(dev);
u8 MaxTxPwrInDbm = 255;
if (MAX_CHANNEL_NUMBER < Channel) {
printk(KERN_INFO "DOT11D_GetMaxTxPwrInDbm(): Invalid "
"Channel\n");
return MaxTxPwrInDbm;
}
if (pDot11dInfo->channel_map[Channel])
MaxTxPwrInDbm = pDot11dInfo->MaxTxPwrDbmList[Channel];
return MaxTxPwrInDbm;
}
void DOT11D_ScanComplete(struct rtllib_device *dev)
{
struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(dev);
switch (pDot11dInfo->State) {
case DOT11D_STATE_LEARNED:
pDot11dInfo->State = DOT11D_STATE_DONE;
break;
case DOT11D_STATE_DONE:
Dot11d_Reset(dev);
break;
case DOT11D_STATE_NONE:
break;
}
}
int ToLegalChannel(struct rtllib_device *dev, u8 channel)
{
struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(dev);
u8 default_chn = 0;
u32 i;
for (i = 1; i <= MAX_CHANNEL_NUMBER; i++) {
if (pDot11dInfo->channel_map[i] > 0) {
default_chn = i;
break;
}
}
if (MAX_CHANNEL_NUMBER < channel) {
printk(KERN_ERR "%s(): Invalid Channel\n", __func__);
return default_chn;
}
if (pDot11dInfo->channel_map[channel] > 0)
return channel;
return default_chn;
}

View file

@ -1,24 +1,42 @@
#ifndef INC_DOT11D_H
#define INC_DOT11D_H
/******************************************************************************
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
******************************************************************************/
#ifndef __INC_DOT11D_H
#define __INC_DOT11D_H
#ifdef ENABLE_DOT11D
#include "ieee80211.h"
#include "rtllib.h"
struct _CHNL_TXPOWER_TRIPLE {
struct chnl_txpow_triple {
u8 FirstChnl;
u8 NumChnls;
u8 MaxTxPowerInDbm;
};
enum _DOT11D_STATE {
enum dot11d_state {
DOT11D_STATE_NONE = 0,
DOT11D_STATE_LEARNED,
DOT11D_STATE_DONE,
};
/**
* struct _RT_DOT11D_INFO
* @CountryIeLen: value greater than 0 if @CountryIeBuf contains
* struct rt_dot11d_info * @CountryIeLen: value greater than 0 if @CountryIeBuf contains
* valid country information element.
* @chanell_map: holds channel values
* 0 - invalid,
@ -27,7 +45,8 @@ enum _DOT11D_STATE {
* @CountryIeSrcAddr - Source AP of the country IE
*/
struct _RT_DOT11D_INFO {
struct rt_dot11d_info {
bool bEnabled;
u16 CountryIeLen;
@ -38,7 +57,7 @@ struct _RT_DOT11D_INFO {
u8 channel_map[MAX_CHANNEL_NUMBER+1];
u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
DOT11D_STATE State;
enum dot11d_state State;
};
static inline void cpMacAddr(unsigned char *des, unsigned char *src)
@ -46,49 +65,41 @@ static inline void cpMacAddr(unsigned char *des, unsigned char *src)
memcpy(des, src, 6);
}
#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO) \
((__pIeeeDev)->pDot11dInfo))
#define GET_DOT11D_INFO(__pIeeeDev) \
((struct rt_dot11d_info *)((__pIeeeDev)->pDot11dInfo))
#define IS_DOT11D_ENABLE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->bEnabled)
#define IS_DOT11D_ENABLE(__pIeeeDev) \
(GET_DOT11D_INFO(__pIeeeDev)->bEnabled)
#define IS_COUNTRY_IE_VALID(__pIeeeDev) \
(GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) \
eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) \
cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \
(((__Ie).Length == 0 || (__Ie).Length != \
GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? FALSE : \
(!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, \
GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \
false : (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, \
(__Ie).Octet, (__Ie).Length)))
#define CIE_WATCHDOG_TH 1
#define GET_CIE_WATCHDOG(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)-> \
CountryIeWatchdog)
#define GET_CIE_WATCHDOG(__pIeeeDev) \
(GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog)
#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0
#define UPDATE_CIE_WATCHDOG(__pIeeeDev) (++GET_CIE_WATCHDOG(__pIeeeDev))
#define IS_DOT11D_STATE_DONE(__pIeeeDev) \
(GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
void Dot11d_Init(struct ieee80211_device *dev);
void Dot11d_Reset(struct ieee80211_device *dev);
void Dot11d_UpdateCountryIe(struct ieee80211_device *dev, u8 *pTaddr,
void Dot11d_Init(struct rtllib_device *dev);
void Dot11d_Channelmap(u8 channel_plan, struct rtllib_device *ieee);
void Dot11d_Reset(struct rtllib_device *dev);
void Dot11d_UpdateCountryIe(struct rtllib_device *dev, u8 *pTaddr,
u16 CoutryIeLen, u8 *pCoutryIe);
u8 DOT11D_GetMaxTxPwrInDbm(struct rtllib_device *dev, u8 Channel);
void DOT11D_ScanComplete(struct rtllib_device *dev);
int ToLegalChannel(struct rtllib_device *dev, u8 channel);
u8 DOT11D_GetMaxTxPwrInDbm(struct ieee80211_device *dev, u8 channel);
void DOT11D_ScanComplete(struct ieee80211_device *dev);
int IsLegalChannel(struct ieee80211_device *dev, u8 channel);
int ToLegalChannel(struct ieee80211_device *dev, u8 channel);
#endif /* ENABLE_DOT11D */
#endif /* INC_DOT11D_H */
#endif

View file

@ -1,218 +0,0 @@
#ifdef ENABLE_DOT11D
//-----------------------------------------------------------------------------
// File:
// Dot11d.c
//
// Description:
// Implement 802.11d.
//
//-----------------------------------------------------------------------------
#include "dot11d.h"
void
Dot11d_Init(struct ieee80211_device *ieee)
{
PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
pDot11dInfo->bEnabled = 0;
pDot11dInfo->State = DOT11D_STATE_NONE;
pDot11dInfo->CountryIeLen = 0;
memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
RESET_CIE_WATCHDOG(ieee);
printk("Dot11d_Init()\n");
}
//
// Description:
// Reset to the state as we are just entering a regulatory domain.
//
void
Dot11d_Reset(struct ieee80211_device *ieee)
{
u32 i;
PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
#if 0
if(!pDot11dInfo->bEnabled)
return;
#endif
// Clear old channel map
memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
// Set new channel map
for (i=1; i<=11; i++) {
(pDot11dInfo->channel_map)[i] = 1;
}
for (i=12; i<=14; i++) {
(pDot11dInfo->channel_map)[i] = 2;
}
pDot11dInfo->State = DOT11D_STATE_NONE;
pDot11dInfo->CountryIeLen = 0;
RESET_CIE_WATCHDOG(ieee);
}
//
// Description:
// Update country IE from Beacon or Probe Resopnse
// and configure PHY for operation in the regulatory domain.
//
// TODO:
// Configure Tx power.
//
// Assumption:
// 1. IS_DOT11D_ENABLE() is TRUE.
// 2. Input IE is an valid one.
//
void
Dot11d_UpdateCountryIe(
struct ieee80211_device *dev,
u8 * pTaddr,
u16 CoutryIeLen,
u8 * pCoutryIe
)
{
PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
u8 i, j, NumTriples, MaxChnlNum;
PCHNL_TXPOWER_TRIPLE pTriple;
memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
MaxChnlNum = 0;
NumTriples = (CoutryIeLen - 3) / 3; // skip 3-byte country string.
pTriple = (PCHNL_TXPOWER_TRIPLE)(pCoutryIe + 3);
for(i = 0; i < NumTriples; i++)
{
if(MaxChnlNum >= pTriple->FirstChnl)
{ // It is not in a monotonically increasing order, so stop processing.
printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
return;
}
if(MAX_CHANNEL_NUMBER < (pTriple->FirstChnl + pTriple->NumChnls))
{ // It is not a valid set of channel id, so stop processing.
printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........2\n");
return;
}
for(j = 0 ; j < pTriple->NumChnls; j++)
{
pDot11dInfo->channel_map[pTriple->FirstChnl + j] = 1;
pDot11dInfo->MaxTxPwrDbmList[pTriple->FirstChnl + j] = pTriple->MaxTxPowerInDbm;
MaxChnlNum = pTriple->FirstChnl + j;
}
pTriple = (PCHNL_TXPOWER_TRIPLE)((u8*)pTriple + 3);
}
#if 1
printk("Channel List:");
for(i=1; i<= MAX_CHANNEL_NUMBER; i++)
if(pDot11dInfo->channel_map[i] > 0)
printk(" %d", i);
printk("\n");
#endif
UPDATE_CIE_SRC(dev, pTaddr);
pDot11dInfo->CountryIeLen = CoutryIeLen;
memcpy(pDot11dInfo->CountryIeBuf, pCoutryIe,CoutryIeLen);
pDot11dInfo->State = DOT11D_STATE_LEARNED;
}
u8
DOT11D_GetMaxTxPwrInDbm(
struct ieee80211_device *dev,
u8 Channel
)
{
PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
u8 MaxTxPwrInDbm = 255;
if(MAX_CHANNEL_NUMBER < Channel)
{
printk("DOT11D_GetMaxTxPwrInDbm(): Invalid Channel\n");
return MaxTxPwrInDbm;
}
if(pDot11dInfo->channel_map[Channel])
{
MaxTxPwrInDbm = pDot11dInfo->MaxTxPwrDbmList[Channel];
}
return MaxTxPwrInDbm;
}
void
DOT11D_ScanComplete(
struct ieee80211_device * dev
)
{
PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
switch(pDot11dInfo->State)
{
case DOT11D_STATE_LEARNED:
pDot11dInfo->State = DOT11D_STATE_DONE;
break;
case DOT11D_STATE_DONE:
if( GET_CIE_WATCHDOG(dev) == 0 )
{ // Reset country IE if previous one is gone.
Dot11d_Reset(dev);
}
break;
case DOT11D_STATE_NONE:
break;
}
}
int IsLegalChannel(
struct ieee80211_device * dev,
u8 channel
)
{
PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
if(MAX_CHANNEL_NUMBER < channel)
{
printk("IsLegalChannel(): Invalid Channel\n");
return 0;
}
if(pDot11dInfo->channel_map[channel] > 0)
return 1;
return 0;
}
int ToLegalChannel(
struct ieee80211_device * dev,
u8 channel
)
{
PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
u8 default_chn = 0;
u32 i = 0;
for (i=1; i<= MAX_CHANNEL_NUMBER; i++)
{
if(pDot11dInfo->channel_map[i] > 0)
{
default_chn = i;
break;
}
}
if(MAX_CHANNEL_NUMBER < channel)
{
printk("IsLegalChannel(): Invalid Channel\n");
return default_chn;
}
if(pDot11dInfo->channel_map[channel] > 0)
return channel;
return default_chn;
}
#endif

View file

@ -1,102 +0,0 @@
#ifndef __INC_DOT11D_H
#define __INC_DOT11D_H
#ifdef ENABLE_DOT11D
#include "ieee80211.h"
//#define ENABLE_DOT11D
//#define DOT11D_MAX_CHNL_NUM 83
typedef struct _CHNL_TXPOWER_TRIPLE {
u8 FirstChnl;
u8 NumChnls;
u8 MaxTxPowerInDbm;
}CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
typedef enum _DOT11D_STATE {
DOT11D_STATE_NONE = 0,
DOT11D_STATE_LEARNED,
DOT11D_STATE_DONE,
}DOT11D_STATE;
typedef struct _RT_DOT11D_INFO {
//DECLARE_RT_OBJECT(RT_DOT11D_INFO);
bool bEnabled; // dot11MultiDomainCapabilityEnabled
u16 CountryIeLen; // > 0 if CountryIeBuf[] contains valid country information element.
u8 CountryIeBuf[MAX_IE_LEN];
u8 CountryIeSrcAddr[6]; // Source AP of the country IE.
u8 CountryIeWatchdog;
u8 channel_map[MAX_CHANNEL_NUMBER+1]; //!!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan)
//u8 ChnlListLen; // #Bytes valid in ChnlList[].
//u8 ChnlList[DOT11D_MAX_CHNL_NUM];
u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
DOT11D_STATE State;
}RT_DOT11D_INFO, *PRT_DOT11D_INFO;
#define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 )
#define cpMacAddr(des,src) ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5])
#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo))
#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled
#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \
(((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \
FALSE : \
(!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length)))
#define CIE_WATCHDOG_TH 1
#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog
#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0
#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev)
#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
void
Dot11d_Init(
struct ieee80211_device *dev
);
void
Dot11d_Reset(
struct ieee80211_device *dev
);
void
Dot11d_UpdateCountryIe(
struct ieee80211_device *dev,
u8 * pTaddr,
u16 CoutryIeLen,
u8 * pCoutryIe
);
u8
DOT11D_GetMaxTxPwrInDbm(
struct ieee80211_device *dev,
u8 Channel
);
void
DOT11D_ScanComplete(
struct ieee80211_device * dev
);
int IsLegalChannel(
struct ieee80211_device * dev,
u8 channel
);
int ToLegalChannel(
struct ieee80211_device * dev,
u8 channel
);
#endif //ENABLE_DOT11D
#endif // #ifndef __INC_DOT11D_H

File diff suppressed because it is too large Load diff

View file

@ -1,352 +0,0 @@
/*******************************************************************************
Copyright(c) 2004 Intel Corporation. All rights reserved.
Portions of this file are based on the WEP enablement code provided by the
Host AP project hostap-drivers v0.1.3
Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
<jkmaline@cc.hut.fi>
Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
This program is free software; you can redistribute it and/or modify it
under the terms of version 2 of the GNU General Public License as
published by the Free Software Foundation.
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.
The full GNU General Public License is included in this distribution in the
file called LICENSE.
Contact Information:
James P. Ketrenos <ipw2100-admin@linux.intel.com>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
#include <linux/compiler.h>
#include <linux/errno.h>
#include <linux/if_arp.h>
#include <linux/in6.h>
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/pci.h>
#include <linux/proc_fs.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/tcp.h>
#include <linux/types.h>
#include <linux/wireless.h>
#include <linux/etherdevice.h>
#include <asm/uaccess.h>
#include <net/arp.h>
#include "ieee80211.h"
MODULE_DESCRIPTION("802.11 data/management/control stack");
MODULE_AUTHOR("Copyright (C) 2004 Intel Corporation <jketreno@linux.intel.com>");
MODULE_LICENSE("GPL");
#define DRV_NAME "ieee80211"
static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee)
{
if (ieee->networks)
return 0;
ieee->networks = kcalloc(
MAX_NETWORK_COUNT, sizeof(struct ieee80211_network),
GFP_KERNEL);
if (!ieee->networks) {
printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
ieee->dev->name);
return -ENOMEM;
}
return 0;
}
static inline void ieee80211_networks_free(struct ieee80211_device *ieee)
{
if (!ieee->networks)
return;
kfree(ieee->networks);
ieee->networks = NULL;
}
static inline void ieee80211_networks_initialize(struct ieee80211_device *ieee)
{
int i;
INIT_LIST_HEAD(&ieee->network_free_list);
INIT_LIST_HEAD(&ieee->network_list);
for (i = 0; i < MAX_NETWORK_COUNT; i++)
list_add_tail(&ieee->networks[i].list, &ieee->network_free_list);
}
struct net_device *alloc_ieee80211(int sizeof_priv)
{
struct ieee80211_device *ieee;
struct net_device *dev;
int i, err;
IEEE80211_DEBUG_INFO("Initializing...\n");
dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv);
if (!dev) {
IEEE80211_ERROR("Unable to network device.\n");
goto failed;
}
ieee = netdev_priv(dev);
memset(ieee, 0, sizeof(struct ieee80211_device) + sizeof_priv);
ieee->dev = dev;
err = ieee80211_networks_allocate(ieee);
if (err) {
IEEE80211_ERROR("Unable to allocate beacon storage: %d\n",
err);
goto failed;
}
ieee80211_networks_initialize(ieee);
/* Default fragmentation threshold is maximum payload size */
ieee->fts = DEFAULT_FTS;
ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
ieee->open_wep = 1;
/* Default to enabling full open WEP with host based encrypt/decrypt */
ieee->host_encrypt = 1;
ieee->host_decrypt = 1;
ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
INIT_LIST_HEAD(&ieee->crypt_deinit_list);
init_timer(&ieee->crypt_deinit_timer);
ieee->crypt_deinit_timer.data = (unsigned long)ieee;
ieee->crypt_deinit_timer.function = ieee80211_crypt_deinit_handler;
spin_lock_init(&ieee->lock);
spin_lock_init(&ieee->wpax_suitlist_lock);
spin_lock_init(&ieee->bw_spinlock);
spin_lock_init(&ieee->reorder_spinlock);
/* added by WB */
atomic_set(&(ieee->atm_chnlop), 0);
atomic_set(&(ieee->atm_swbw), 0);
ieee->wpax_type_set = 0;
ieee->wpa_enabled = 0;
ieee->tkip_countermeasures = 0;
ieee->drop_unencrypted = 0;
ieee->privacy_invoked = 0;
ieee->ieee802_1x = 1;
ieee->raw_tx = 0;
/* ieee->hwsec_support = 1; default support hw security: use module_param instead */
ieee->hwsec_active = 0; /* disable hwsec, switch it on when necessary */
ieee80211_softmac_init(ieee);
ieee->pHTInfo = kzalloc(sizeof(RT_HIGH_THROUGHPUT), GFP_KERNEL);
if (ieee->pHTInfo == NULL)
{
IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for HTInfo\n");
return NULL;
}
HTUpdateDefaultSetting(ieee);
HTInitializeHTInfo(ieee); /* may move to other place */
TSInitialize(ieee);
for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++)
INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
for (i = 0; i < 17; i++) {
ieee->last_rxseq_num[i] = -1;
ieee->last_rxfrag_num[i] = -1;
ieee->last_packet_time[i] = 0;
}
/* Functions to load crypt module automatically */
ieee80211_tkip_null();
ieee80211_wep_null();
ieee80211_ccmp_null();
return dev;
failed:
if (dev)
free_netdev(dev);
return NULL;
}
void free_ieee80211(struct net_device *dev)
{
struct ieee80211_device *ieee = netdev_priv(dev);
int i;
kfree(ieee->pHTInfo);
ieee->pHTInfo = NULL;
RemoveAllTS(ieee);
ieee80211_softmac_free(ieee);
del_timer_sync(&ieee->crypt_deinit_timer);
ieee80211_crypt_deinit_entries(ieee, 1);
for (i = 0; i < WEP_KEYS; i++) {
struct ieee80211_crypt_data *crypt = ieee->crypt[i];
if (crypt) {
if (crypt->ops)
crypt->ops->deinit(crypt->priv);
kfree(crypt);
ieee->crypt[i] = NULL;
}
}
ieee80211_networks_free(ieee);
free_netdev(dev);
}
#ifdef CONFIG_IEEE80211_DEBUG
u32 ieee80211_debug_level = 0;
static int debug =
/* IEEE80211_DL_INFO | */
/* IEEE80211_DL_WX | */
/* IEEE80211_DL_SCAN | */
/* IEEE80211_DL_STATE | */
/* IEEE80211_DL_MGMT | */
/* IEEE80211_DL_FRAG | */
/* IEEE80211_DL_EAP | */
/* IEEE80211_DL_DROP | */
/* IEEE80211_DL_TX | */
/* IEEE80211_DL_RX | */
/* IEEE80211_DL_QOS | */
/* IEEE80211_DL_HT | */
/* IEEE80211_DL_TS | */
/* IEEE80211_DL_BA | */
/* IEEE80211_DL_REORDER | */
/* IEEE80211_DL_TRACE | */
/* IEEE80211_DL_DATA | */
IEEE80211_DL_ERR /* always open this flag to show error out */
;
struct proc_dir_entry *ieee80211_proc = NULL;
static int show_debug_level(char *page, char **start, off_t offset,
int count, int *eof, void *data)
{
return snprintf(page, count, "0x%08X\n", ieee80211_debug_level);
}
static int store_debug_level(struct file *file, const char *buffer,
unsigned long count, void *data)
{
char buf[] = "0x00000000";
unsigned long len = min(sizeof(buf) - 1, (u32)count);
char *p = (char *)buf;
unsigned long val;
if (copy_from_user(buf, buffer, len))
return count;
buf[len] = 0;
if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
p++;
if (p[0] == 'x' || p[0] == 'X')
p++;
val = simple_strtoul(p, &p, 16);
} else
val = simple_strtoul(p, &p, 10);
if (p == buf)
printk(KERN_INFO DRV_NAME
": %s is not in hex or decimal form.\n", buf);
else
ieee80211_debug_level = val;
return strnlen(buf, count);
}
extern int ieee80211_crypto_init(void);
extern void ieee80211_crypto_deinit(void);
extern int ieee80211_crypto_tkip_init(void);
extern void ieee80211_crypto_tkip_exit(void);
extern int ieee80211_crypto_ccmp_init(void);
extern void ieee80211_crypto_ccmp_exit(void);
extern int ieee80211_crypto_wep_init(void);
extern void ieee80211_crypto_wep_exit(void);
int __init ieee80211_rtl_init(void)
{
struct proc_dir_entry *e;
int retval;
retval = ieee80211_crypto_init();
if (retval)
return retval;
retval = ieee80211_crypto_tkip_init();
if (retval) {
ieee80211_crypto_deinit();
return retval;
}
retval = ieee80211_crypto_ccmp_init();
if (retval) {
ieee80211_crypto_tkip_exit();
ieee80211_crypto_deinit();
return retval;
}
retval = ieee80211_crypto_wep_init();
if (retval) {
ieee80211_crypto_ccmp_exit();
ieee80211_crypto_tkip_exit();
ieee80211_crypto_deinit();
return retval;
}
ieee80211_debug_level = debug;
ieee80211_proc = proc_mkdir(DRV_NAME, init_net.proc_net);
if (ieee80211_proc == NULL) {
IEEE80211_ERROR("Unable to create " DRV_NAME
" proc directory\n");
return -EIO;
}
e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
ieee80211_proc);
if (!e) {
remove_proc_entry(DRV_NAME, init_net.proc_net);
ieee80211_proc = NULL;
return -EIO;
}
e->read_proc = show_debug_level;
e->write_proc = store_debug_level;
e->data = NULL;
return 0;
}
void __exit ieee80211_rtl_exit(void)
{
if (ieee80211_proc) {
remove_proc_entry("debug_level", ieee80211_proc);
remove_proc_entry(DRV_NAME, init_net.proc_net);
ieee80211_proc = NULL;
}
ieee80211_crypto_wep_exit();
ieee80211_crypto_ccmp_exit();
ieee80211_crypto_tkip_exit();
ieee80211_crypto_deinit();
}
#include <linux/moduleparam.h>
module_param(debug, int, 0444);
MODULE_PARM_DESC(debug, "debug output mask");
#endif

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,676 +0,0 @@
/*
* This file is created to process BA Action Frame. According to 802.11 spec,
* there are 3 BA action types at all. And as BA is related to TS, this part
* need some struture defined in QOS side code. Also TX RX is going to be
* resturctured, so how to send ADDBAREQ ADDBARSP and DELBA packet is still
* on consideration. Temporarily use MANAGE QUEUE instead of Normal Queue.
*/
#include "ieee80211.h"
#include "rtl819x_BA.h"
/*
* Activate BA entry. And if Time is nozero, start timer.
*/
void ActivateBAEntry(struct ieee80211_device* ieee, PBA_RECORD pBA, u16 Time)
{
pBA->bValid = true;
if(Time != 0)
mod_timer(&pBA->Timer, jiffies + MSECS(Time));
}
/*
* deactivate BA entry, including its timer.
*/
void DeActivateBAEntry( struct ieee80211_device* ieee, PBA_RECORD pBA)
{
pBA->bValid = false;
del_timer_sync(&pBA->Timer);
}
/*
* deactivete BA entry in Tx Ts, and send DELBA.
*/
u8 TxTsDeleteBA( struct ieee80211_device* ieee, PTX_TS_RECORD pTxTs)
{
PBA_RECORD pAdmittedBa = &pTxTs->TxAdmittedBARecord; //These two BA entries must exist in TS structure
PBA_RECORD pPendingBa = &pTxTs->TxPendingBARecord;
u8 bSendDELBA = false;
// Delete pending BA
if(pPendingBa->bValid)
{
DeActivateBAEntry(ieee, pPendingBa);
bSendDELBA = true;
}
// Delete admitted BA
if(pAdmittedBa->bValid)
{
DeActivateBAEntry(ieee, pAdmittedBa);
bSendDELBA = true;
}
return bSendDELBA;
}
/*
* deactivete BA entry in Tx Ts, and send DELBA.
*/
u8 RxTsDeleteBA( struct ieee80211_device* ieee, PRX_TS_RECORD pRxTs)
{
PBA_RECORD pBa = &pRxTs->RxAdmittedBARecord;
u8 bSendDELBA = false;
if(pBa->bValid)
{
DeActivateBAEntry(ieee, pBa);
bSendDELBA = true;
}
return bSendDELBA;
}
/*
* reset BA entry
*/
void ResetBaEntry( PBA_RECORD pBA)
{
pBA->bValid = false;
pBA->BaParamSet.shortData = 0;
pBA->BaTimeoutValue = 0;
pBA->DialogToken = 0;
pBA->BaStartSeqCtrl.ShortData = 0;
}
/*
* construct ADDBAREQ and ADDBARSP frame here together.
* return constructed skb to xmit
*/
static struct sk_buff* ieee80211_ADDBA(struct ieee80211_device* ieee, u8* Dst, PBA_RECORD pBA, u16 StatusCode, u8 type)
{
struct sk_buff *skb = NULL;
struct ieee80211_hdr_3addr* BAReq = NULL;
u8* tag = NULL;
u16 tmp = 0;
u16 len = ieee->tx_headroom + 9;
//category(1) + action field(1) + Dialog Token(1) + BA Parameter Set(2) + BA Timeout Value(2) + BA Start SeqCtrl(2)(or StatusCode(2))
IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:%pM, ieee->dev:%p\n", __FUNCTION__, type, Dst, ieee->dev);
if (pBA == NULL||ieee == NULL)
{
IEEE80211_DEBUG(IEEE80211_DL_ERR, "pBA(%p) is NULL or ieee(%p) is NULL\n", pBA, ieee);
return NULL;
}
skb = dev_alloc_skb(len + sizeof( struct ieee80211_hdr_3addr)); //need to add something others? FIXME
if (skb == NULL)
{
IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc skb for ADDBA_REQ\n");
return NULL;
}
memset(skb->data, 0, sizeof( struct ieee80211_hdr_3addr)); //I wonder whether it's necessary. Apparently kernel will not do it when alloc a skb.
skb_reserve(skb, ieee->tx_headroom);
BAReq = ( struct ieee80211_hdr_3addr *) skb_put(skb,sizeof( struct ieee80211_hdr_3addr));
memcpy(BAReq->addr1, Dst, ETH_ALEN);
memcpy(BAReq->addr2, ieee->dev->dev_addr, ETH_ALEN);
memcpy(BAReq->addr3, ieee->current_network.bssid, ETH_ALEN);
BAReq->frame_ctl = cpu_to_le16(IEEE80211_STYPE_MANAGE_ACT); //action frame
//tag += sizeof( struct ieee80211_hdr_3addr); //move to action field
tag = (u8*)skb_put(skb, 9);
*tag ++= ACT_CAT_BA;
*tag ++= type;
// Dialog Token
*tag ++= pBA->DialogToken;
if (ACT_ADDBARSP == type)
{
// Status Code
printk("=====>to send ADDBARSP\n");
tmp = cpu_to_le16(StatusCode);
memcpy(tag, (u8*)&tmp, 2);
tag += 2;
}
// BA Parameter Set
tmp = cpu_to_le16(pBA->BaParamSet.shortData);
memcpy(tag, (u8*)&tmp, 2);
tag += 2;
// BA Timeout Value
tmp = cpu_to_le16(pBA->BaTimeoutValue);
memcpy(tag, (u8*)&tmp, 2);
tag += 2;
if (ACT_ADDBAREQ == type)
{
// BA Start SeqCtrl
memcpy(tag,(u8*)&(pBA->BaStartSeqCtrl), 2);
tag += 2;
}
IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
return skb;
//return NULL;
}
/*
* construct DELBA frame
*/
static struct sk_buff* ieee80211_DELBA(
struct ieee80211_device* ieee,
u8* dst,
PBA_RECORD pBA,
TR_SELECT TxRxSelect,
u16 ReasonCode
)
{
DELBA_PARAM_SET DelbaParamSet;
struct sk_buff *skb = NULL;
struct ieee80211_hdr_3addr* Delba = NULL;
u8* tag = NULL;
u16 tmp = 0;
//len = head len + DELBA Parameter Set(2) + Reason Code(2)
u16 len = 6 + ieee->tx_headroom;
if (net_ratelimit())
IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), ReasonCode(%d) sentd to:%pM\n", __FUNCTION__, ReasonCode, dst);
memset(&DelbaParamSet, 0, 2);
DelbaParamSet.field.Initiator = (TxRxSelect==TX_DIR)?1:0;
DelbaParamSet.field.TID = pBA->BaParamSet.field.TID;
skb = dev_alloc_skb(len + sizeof( struct ieee80211_hdr_3addr)); //need to add something others? FIXME
if (skb == NULL)
{
IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc skb for ADDBA_REQ\n");
return NULL;
}
// memset(skb->data, 0, len+sizeof( struct ieee80211_hdr_3addr));
skb_reserve(skb, ieee->tx_headroom);
Delba = ( struct ieee80211_hdr_3addr *) skb_put(skb,sizeof( struct ieee80211_hdr_3addr));
memcpy(Delba->addr1, dst, ETH_ALEN);
memcpy(Delba->addr2, ieee->dev->dev_addr, ETH_ALEN);
memcpy(Delba->addr3, ieee->current_network.bssid, ETH_ALEN);
Delba->frame_ctl = cpu_to_le16(IEEE80211_STYPE_MANAGE_ACT); //action frame
tag = (u8*)skb_put(skb, 6);
*tag ++= ACT_CAT_BA;
*tag ++= ACT_DELBA;
// DELBA Parameter Set
tmp = cpu_to_le16(DelbaParamSet.shortData);
memcpy(tag, (u8*)&tmp, 2);
tag += 2;
// Reason Code
tmp = cpu_to_le16(ReasonCode);
memcpy(tag, (u8*)&tmp, 2);
tag += 2;
IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
if (net_ratelimit())
IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "<=====%s()\n", __FUNCTION__);
return skb;
}
/*
* send ADDBAReq frame out
* If any possible, please hide pBA in ieee.
* And temporarily use Manage Queue as softmac_mgmt_xmit() usually does
*/
void ieee80211_send_ADDBAReq(struct ieee80211_device* ieee, u8* dst, PBA_RECORD pBA)
{
struct sk_buff *skb = NULL;
skb = ieee80211_ADDBA(ieee, dst, pBA, 0, ACT_ADDBAREQ); //construct ACT_ADDBAREQ frames so set statuscode zero.
if (skb)
{
softmac_mgmt_xmit(skb, ieee);
//add statistic needed here.
//and skb will be freed in softmac_mgmt_xmit(), so omit all dev_kfree_skb_any() outside softmac_mgmt_xmit()
//WB
}
else
{
IEEE80211_DEBUG(IEEE80211_DL_ERR, "alloc skb error in function %s()\n", __FUNCTION__);
}
}
/*
* send ADDBARSP frame out
* If any possible, please hide pBA in ieee.
* And temporarily use Manage Queue as softmac_mgmt_xmit() usually does
*/
void ieee80211_send_ADDBARsp(struct ieee80211_device* ieee, u8* dst, PBA_RECORD pBA, u16 StatusCode)
{
struct sk_buff *skb = NULL;
skb = ieee80211_ADDBA(ieee, dst, pBA, StatusCode, ACT_ADDBARSP); //construct ACT_ADDBARSP frames
if (skb)
{
softmac_mgmt_xmit(skb, ieee);
//same above
}
else
{
IEEE80211_DEBUG(IEEE80211_DL_ERR, "alloc skb error in function %s()\n", __FUNCTION__);
}
}
/*
* send ADDBARSP frame out
* If any possible, please hide pBA in ieee.
* And temporarily use Manage Queue as softmac_mgmt_xmit() usually does
*/
void ieee80211_send_DELBA(struct ieee80211_device* ieee, u8* dst, PBA_RECORD pBA, TR_SELECT TxRxSelect, u16 ReasonCode)
{
struct sk_buff *skb = NULL;
skb = ieee80211_DELBA(ieee, dst, pBA, TxRxSelect, ReasonCode); //construct ACT_ADDBARSP frames
if (skb)
{
softmac_mgmt_xmit(skb, ieee);
//same above
}
else
{
IEEE80211_DEBUG(IEEE80211_DL_ERR, "alloc skb error in function %s()\n", __FUNCTION__);
}
return ;
}
int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb)
{
struct ieee80211_hdr_3addr* req = NULL;
u16 rc = 0;
u8 * dst = NULL, *pDialogToken = NULL, *tag = NULL;
PBA_RECORD pBA = NULL;
PBA_PARAM_SET pBaParamSet = NULL;
u16* pBaTimeoutVal = NULL;
PSEQUENCE_CONTROL pBaStartSeqCtrl = NULL;
PRX_TS_RECORD pTS = NULL;
if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9)
{
IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BAREQ(%d / %zu)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 9));
return -1;
}
IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
req = ( struct ieee80211_hdr_3addr*) skb->data;
tag = (u8*)req;
dst = (u8*)(&req->addr2[0]);
tag += sizeof( struct ieee80211_hdr_3addr);
pDialogToken = tag + 2; //category+action
pBaParamSet = (PBA_PARAM_SET)(tag + 3); //+DialogToken
pBaTimeoutVal = (u16*)(tag + 5);
pBaStartSeqCtrl = (PSEQUENCE_CONTROL)(req + 7);
printk("====================>rx ADDBAREQ from :%pM\n", dst);
//some other capability is not ready now.
if( (ieee->current_network.qos_data.active == 0) ||
(ieee->pHTInfo->bCurrentHTSupport == false)) //||
// (ieee->pStaQos->bEnableRxImmBA == false) )
{
rc = ADDBA_STATUS_REFUSED;
IEEE80211_DEBUG(IEEE80211_DL_ERR, "Failed to reply on ADDBA_REQ as some capability is not ready(%d, %d)\n", ieee->current_network.qos_data.active, ieee->pHTInfo->bCurrentHTSupport);
goto OnADDBAReq_Fail;
}
// Search for related traffic stream.
// If there is no matched TS, reject the ADDBA request.
if( !GetTs(
ieee,
(PTS_COMMON_INFO*)(&pTS),
dst,
(u8)(pBaParamSet->field.TID),
RX_DIR,
true) )
{
rc = ADDBA_STATUS_REFUSED;
IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't get TS in %s()\n", __FUNCTION__);
goto OnADDBAReq_Fail;
}
pBA = &pTS->RxAdmittedBARecord;
// To Determine the ADDBA Req content
// We can do much more check here, including BufferSize, AMSDU_Support, Policy, StartSeqCtrl...
// I want to check StartSeqCtrl to make sure when we start aggregation!!!
//
if(pBaParamSet->field.BAPolicy == BA_POLICY_DELAYED)
{
rc = ADDBA_STATUS_INVALID_PARAM;
IEEE80211_DEBUG(IEEE80211_DL_ERR, "BA Policy is not correct in %s()\n", __FUNCTION__);
goto OnADDBAReq_Fail;
}
// Admit the ADDBA Request
//
DeActivateBAEntry(ieee, pBA);
pBA->DialogToken = *pDialogToken;
pBA->BaParamSet = *pBaParamSet;
pBA->BaTimeoutValue = *pBaTimeoutVal;
pBA->BaStartSeqCtrl = *pBaStartSeqCtrl;
//for half N mode we only aggregate 1 frame
if (ieee->GetHalfNmodeSupportByAPsHandler(ieee))
pBA->BaParamSet.field.BufferSize = 1;
else
pBA->BaParamSet.field.BufferSize = 32;
ActivateBAEntry(ieee, pBA, pBA->BaTimeoutValue);
ieee80211_send_ADDBARsp(ieee, dst, pBA, ADDBA_STATUS_SUCCESS);
// End of procedure.
return 0;
OnADDBAReq_Fail:
{
BA_RECORD BA;
BA.BaParamSet = *pBaParamSet;
BA.BaTimeoutValue = *pBaTimeoutVal;
BA.DialogToken = *pDialogToken;
BA.BaParamSet.field.BAPolicy = BA_POLICY_IMMEDIATE;
ieee80211_send_ADDBARsp(ieee, dst, &BA, rc);
return 0; //we send RSP out.
}
}
int ieee80211_rx_ADDBARsp( struct ieee80211_device* ieee, struct sk_buff *skb)
{
struct ieee80211_hdr_3addr* rsp = NULL;
PBA_RECORD pPendingBA, pAdmittedBA;
PTX_TS_RECORD pTS = NULL;
u8* dst = NULL, *pDialogToken = NULL, *tag = NULL;
u16* pStatusCode = NULL, *pBaTimeoutVal = NULL;
PBA_PARAM_SET pBaParamSet = NULL;
u16 ReasonCode;
if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9)
{
IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BARSP(%d / %zu)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 9));
return -1;
}
rsp = ( struct ieee80211_hdr_3addr*)skb->data;
tag = (u8*)rsp;
dst = (u8*)(&rsp->addr2[0]);
tag += sizeof( struct ieee80211_hdr_3addr);
pDialogToken = tag + 2;
pStatusCode = (u16*)(tag + 3);
pBaParamSet = (PBA_PARAM_SET)(tag + 5);
pBaTimeoutVal = (u16*)(tag + 7);
// Check the capability
// Since we can always receive A-MPDU, we just check if it is under HT mode.
if( ieee->current_network.qos_data.active == 0 ||
ieee->pHTInfo->bCurrentHTSupport == false ||
ieee->pHTInfo->bCurrentAMPDUEnable == false )
{
IEEE80211_DEBUG(IEEE80211_DL_ERR, "reject to ADDBA_RSP as some capability is not ready(%d, %d, %d)\n",ieee->current_network.qos_data.active, ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bCurrentAMPDUEnable);
ReasonCode = DELBA_REASON_UNKNOWN_BA;
goto OnADDBARsp_Reject;
}
//
// Search for related TS.
// If there is no TS found, we wil reject ADDBA Rsp by sending DELBA frame.
//
if (!GetTs(
ieee,
(PTS_COMMON_INFO*)(&pTS),
dst,
(u8)(pBaParamSet->field.TID),
TX_DIR,
false) )
{
IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't get TS in %s()\n", __FUNCTION__);
ReasonCode = DELBA_REASON_UNKNOWN_BA;
goto OnADDBARsp_Reject;
}
pTS->bAddBaReqInProgress = false;
pPendingBA = &pTS->TxPendingBARecord;
pAdmittedBA = &pTS->TxAdmittedBARecord;
//
// Check if related BA is waiting for setup.
// If not, reject by sending DELBA frame.
//
if((pAdmittedBA->bValid==true))
{
// Since BA is already setup, we ignore all other ADDBA Response.
IEEE80211_DEBUG(IEEE80211_DL_BA, "OnADDBARsp(): Recv ADDBA Rsp. Drop because already admit it! \n");
return -1;
}
else if((pPendingBA->bValid == false) ||(*pDialogToken != pPendingBA->DialogToken))
{
IEEE80211_DEBUG(IEEE80211_DL_ERR, "OnADDBARsp(): Recv ADDBA Rsp. BA invalid, DELBA! \n");
ReasonCode = DELBA_REASON_UNKNOWN_BA;
goto OnADDBARsp_Reject;
}
else
{
IEEE80211_DEBUG(IEEE80211_DL_BA, "OnADDBARsp(): Recv ADDBA Rsp. BA is admitted! Status code:%X\n", *pStatusCode);
DeActivateBAEntry(ieee, pPendingBA);
}
if(*pStatusCode == ADDBA_STATUS_SUCCESS)
{
//
// Determine ADDBA Rsp content here.
// We can compare the value of BA parameter set that Peer returned and Self sent.
// If it is OK, then admitted. Or we can send DELBA to cancel BA mechanism.
//
if(pBaParamSet->field.BAPolicy == BA_POLICY_DELAYED)
{
// Since this is a kind of ADDBA failed, we delay next ADDBA process.
pTS->bAddBaReqDelayed = true;
DeActivateBAEntry(ieee, pAdmittedBA);
ReasonCode = DELBA_REASON_END_BA;
goto OnADDBARsp_Reject;
}
//
// Admitted condition
//
pAdmittedBA->DialogToken = *pDialogToken;
pAdmittedBA->BaTimeoutValue = *pBaTimeoutVal;
pAdmittedBA->BaStartSeqCtrl = pPendingBA->BaStartSeqCtrl;
pAdmittedBA->BaParamSet = *pBaParamSet;
DeActivateBAEntry(ieee, pAdmittedBA);
ActivateBAEntry(ieee, pAdmittedBA, *pBaTimeoutVal);
}
else
{
// Delay next ADDBA process.
pTS->bAddBaReqDelayed = true;
}
// End of procedure
return 0;
OnADDBARsp_Reject:
{
BA_RECORD BA;
BA.BaParamSet = *pBaParamSet;
ieee80211_send_DELBA(ieee, dst, &BA, TX_DIR, ReasonCode);
return 0;
}
}
int ieee80211_rx_DELBA(struct ieee80211_device* ieee,struct sk_buff *skb)
{
struct ieee80211_hdr_3addr* delba = NULL;
PDELBA_PARAM_SET pDelBaParamSet = NULL;
u16* pReasonCode = NULL;
u8* dst = NULL;
if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 6)
{
IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in DELBA(%d / %zu)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 6));
return -1;
}
if(ieee->current_network.qos_data.active == 0 ||
ieee->pHTInfo->bCurrentHTSupport == false )
{
IEEE80211_DEBUG(IEEE80211_DL_ERR, "received DELBA while QOS or HT is not supported(%d, %d)\n",ieee->current_network.qos_data.active, ieee->pHTInfo->bCurrentHTSupport);
return -1;
}
IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
delba = ( struct ieee80211_hdr_3addr*)skb->data;
dst = (u8*)(&delba->addr2[0]);
delba += sizeof( struct ieee80211_hdr_3addr);
pDelBaParamSet = (PDELBA_PARAM_SET)(delba+2);
pReasonCode = (u16*)(delba+4);
if(pDelBaParamSet->field.Initiator == 1)
{
PRX_TS_RECORD pRxTs;
if( !GetTs(
ieee,
(PTS_COMMON_INFO*)&pRxTs,
dst,
(u8)pDelBaParamSet->field.TID,
RX_DIR,
false) )
{
IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't get TS for RXTS in %s()\n", __FUNCTION__);
return -1;
}
RxTsDeleteBA(ieee, pRxTs);
}
else
{
PTX_TS_RECORD pTxTs;
if(!GetTs(
ieee,
(PTS_COMMON_INFO*)&pTxTs,
dst,
(u8)pDelBaParamSet->field.TID,
TX_DIR,
false) )
{
IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't get TS for TXTS in %s()\n", __FUNCTION__);
return -1;
}
pTxTs->bUsingBa = false;
pTxTs->bAddBaReqInProgress = false;
pTxTs->bAddBaReqDelayed = false;
del_timer_sync(&pTxTs->TsAddBaTimer);
//PlatformCancelTimer(Adapter, &pTxTs->TsAddBaTimer);
TxTsDeleteBA(ieee, pTxTs);
}
return 0;
}
/* ADDBA initiate. This can only be called by TX side. */
void
TsInitAddBA(
struct ieee80211_device* ieee,
PTX_TS_RECORD pTS,
u8 Policy,
u8 bOverwritePending
)
{
PBA_RECORD pBA = &pTS->TxPendingBARecord;
if(pBA->bValid==true && bOverwritePending==false)
return;
// Set parameters to "Pending" variable set
DeActivateBAEntry(ieee, pBA);
pBA->DialogToken++; // DialogToken: Only keep the latest dialog token
pBA->BaParamSet.field.AMSDU_Support = 0; // Do not support A-MSDU with A-MPDU now!!
pBA->BaParamSet.field.BAPolicy = Policy; // Policy: Delayed or Immediate
pBA->BaParamSet.field.TID = pTS->TsCommonInfo.TSpec.f.TSInfo.field.ucTSID; // TID
// BufferSize: This need to be set according to A-MPDU vector
pBA->BaParamSet.field.BufferSize = 32; // BufferSize: This need to be set according to A-MPDU vector
pBA->BaTimeoutValue = 0; // Timeout value: Set 0 to disable Timer
pBA->BaStartSeqCtrl.field.SeqNum = (pTS->TxCurSeq + 3) % 4096; // Block Ack will start after 3 packets later.
ActivateBAEntry(ieee, pBA, BA_SETUP_TIMEOUT);
ieee80211_send_ADDBAReq(ieee, pTS->TsCommonInfo.Addr, pBA);
}
void
TsInitDelBA( struct ieee80211_device* ieee, PTS_COMMON_INFO pTsCommonInfo, TR_SELECT TxRxSelect)
{
if(TxRxSelect == TX_DIR)
{
PTX_TS_RECORD pTxTs = (PTX_TS_RECORD)pTsCommonInfo;
if(TxTsDeleteBA(ieee, pTxTs))
ieee80211_send_DELBA(
ieee,
pTsCommonInfo->Addr,
(pTxTs->TxAdmittedBARecord.bValid)?(&pTxTs->TxAdmittedBARecord):(&pTxTs->TxPendingBARecord),
TxRxSelect,
DELBA_REASON_END_BA);
}
else if(TxRxSelect == RX_DIR)
{
PRX_TS_RECORD pRxTs = (PRX_TS_RECORD)pTsCommonInfo;
if(RxTsDeleteBA(ieee, pRxTs))
ieee80211_send_DELBA(
ieee,
pTsCommonInfo->Addr,
&pRxTs->RxAdmittedBARecord,
TxRxSelect,
DELBA_REASON_END_BA );
}
}
/*
* BA setup timer
* acturally we send TX_TS_RECORD or RX_TS_RECORD to these timer
*/
void BaSetupTimeOut(unsigned long data)
{
PTX_TS_RECORD pTxTs = (PTX_TS_RECORD)data;
pTxTs->bAddBaReqInProgress = false;
pTxTs->bAddBaReqDelayed = true;
pTxTs->TxPendingBARecord.bValid = false;
}
void TxBaInactTimeout(unsigned long data)
{
PTX_TS_RECORD pTxTs = (PTX_TS_RECORD)data;
struct ieee80211_device *ieee = container_of(pTxTs, struct ieee80211_device, TxTsRecord[pTxTs->num]);
TxTsDeleteBA(ieee, pTxTs);
ieee80211_send_DELBA(
ieee,
pTxTs->TsCommonInfo.Addr,
&pTxTs->TxAdmittedBARecord,
TX_DIR,
DELBA_REASON_TIMEOUT);
}
void RxBaInactTimeout(unsigned long data)
{
PRX_TS_RECORD pRxTs = (PRX_TS_RECORD)data;
struct ieee80211_device *ieee = container_of(pRxTs, struct ieee80211_device, RxTsRecord[pRxTs->num]);
RxTsDeleteBA(ieee, pRxTs);
ieee80211_send_DELBA(
ieee,
pRxTs->TsCommonInfo.Addr,
&pRxTs->RxAdmittedBARecord,
RX_DIR,
DELBA_REASON_TIMEOUT);
}

File diff suppressed because it is too large Load diff

View file

@ -1,582 +0,0 @@
#ifndef __INC_QOS_TYPE_H
#define __INC_QOS_TYPE_H
#define BIT0 0x00000001
#define BIT1 0x00000002
#define BIT2 0x00000004
#define BIT3 0x00000008
#define BIT4 0x00000010
#define BIT5 0x00000020
#define BIT6 0x00000040
#define BIT7 0x00000080
#define BIT8 0x00000100
#define BIT9 0x00000200
#define BIT10 0x00000400
#define BIT11 0x00000800
#define BIT12 0x00001000
#define BIT13 0x00002000
#define BIT14 0x00004000
#define BIT15 0x00008000
#define BIT16 0x00010000
#define BIT17 0x00020000
#define BIT18 0x00040000
#define BIT19 0x00080000
#define BIT20 0x00100000
#define BIT21 0x00200000
#define BIT22 0x00400000
#define BIT23 0x00800000
#define BIT24 0x01000000
#define BIT25 0x02000000
#define BIT26 0x04000000
#define BIT27 0x08000000
#define BIT28 0x10000000
#define BIT29 0x20000000
#define BIT30 0x40000000
#define BIT31 0x80000000
#define MAX_WMMELE_LENGTH 64
//
// QoS mode.
// enum 0, 1, 2, 4: since we can use the OR(|) operation.
//
// QOS_MODE is redefined for enum can't be ++, | under C++ compiler, 2006.05.17, by rcnjko.
//typedef enum _QOS_MODE{
// QOS_DISABLE = 0,
// QOS_WMM = 1,
// QOS_EDCA = 2,
// QOS_HCCA = 4,
//}QOS_MODE,*PQOS_MODE;
//
typedef u32 QOS_MODE, *PQOS_MODE;
#define QOS_DISABLE 0
#define QOS_WMM 1
#define QOS_WMMSA 2
#define QOS_EDCA 4
#define QOS_HCCA 8
#define QOS_WMM_UAPSD 16 //WMM Power Save, 2006-06-14 Isaiah
#define AC_PARAM_SIZE 4
#define WMM_PARAM_ELE_BODY_LEN 18
//
// QoS ACK Policy Field Values
// Ref: WMM spec 2.1.6: QoS Control Field, p.10.
//
typedef enum _ACK_POLICY{
eAckPlc0_ACK = 0x00,
eAckPlc1_NoACK = 0x01,
}ACK_POLICY,*PACK_POLICY;
#define WMM_PARAM_ELEMENT_SIZE (8+(4*AC_PARAM_SIZE))
//
// QoS Control Field
// Ref:
// 1. WMM spec 2.1.6: QoS Control Field, p.9.
// 2. 802.11e/D13.0 7.1.3.5, p.26.
//
typedef union _QOS_CTRL_FIELD{
u8 charData[2];
u16 shortData;
// WMM spec
struct
{
u8 UP:3;
u8 usRsvd1:1;
u8 EOSP:1;
u8 AckPolicy:2;
u8 usRsvd2:1;
u8 ucRsvdByte;
}WMM;
// 802.11e: QoS data type frame sent by non-AP QSTAs.
struct
{
u8 TID:4;
u8 bIsQsize:1;// 0: BIT[8:15] is TXOP Duration Requested, 1: BIT[8:15] is Queue Size.
u8 AckPolicy:2;
u8 usRsvd:1;
u8 TxopOrQsize; // (BIT4=0)TXOP Duration Requested or (BIT4=1)Queue Size.
}BySta;
// 802.11e: QoS data, QoS Null, and QoS Data+CF-Ack frames sent by HC.
struct
{
u8 TID:4;
u8 EOSP:1;
u8 AckPolicy:2;
u8 usRsvd:1;
u8 PSBufState; // QAP PS Buffer State.
}ByHc_Data;
// 802.11e: QoS (+) CF-Poll frames sent by HC.
struct
{
u8 TID:4;
u8 EOSP:1;
u8 AckPolicy:2;
u8 usRsvd:1;
u8 TxopLimit; // TXOP Limit.
}ByHc_CFP;
}QOS_CTRL_FIELD, *PQOS_CTRL_FIELD;
//
// QoS Info Field
// Ref:
// 1. WMM spec 2.2.1: WME Information Element, p.11.
// 2. 8185 QoS code: QOS_INFO [def. in QoS_mp.h]
//
typedef union _QOS_INFO_FIELD{
u8 charData;
struct
{
u8 ucParameterSetCount:4;
u8 ucReserved:4;
}WMM;
struct
{
//Ref WMM_Specification_1-1.pdf, 2006-06-13 Isaiah
u8 ucAC_VO_UAPSD:1;
u8 ucAC_VI_UAPSD:1;
u8 ucAC_BE_UAPSD:1;
u8 ucAC_BK_UAPSD:1;
u8 ucReserved1:1;
u8 ucMaxSPLen:2;
u8 ucReserved2:1;
}ByWmmPsSta;
struct
{
//Ref WMM_Specification_1-1.pdf, 2006-06-13 Isaiah
u8 ucParameterSetCount:4;
u8 ucReserved:3;
u8 ucApUapsd:1;
}ByWmmPsAp;
struct
{
u8 ucAC3_UAPSD:1;
u8 ucAC2_UAPSD:1;
u8 ucAC1_UAPSD:1;
u8 ucAC0_UAPSD:1;
u8 ucQAck:1;
u8 ucMaxSPLen:2;
u8 ucMoreDataAck:1;
} By11eSta;
struct
{
u8 ucParameterSetCount:4;
u8 ucQAck:1;
u8 ucQueueReq:1;
u8 ucTXOPReq:1;
u8 ucReserved:1;
} By11eAp;
struct
{
u8 ucReserved1:4;
u8 ucQAck:1;
u8 ucReserved2:2;
u8 ucMoreDataAck:1;
} ByWmmsaSta;
struct
{
u8 ucReserved1:4;
u8 ucQAck:1;
u8 ucQueueReq:1;
u8 ucTXOPReq:1;
u8 ucReserved2:1;
} ByWmmsaAp;
struct
{
u8 ucAC3_UAPSD:1;
u8 ucAC2_UAPSD:1;
u8 ucAC1_UAPSD:1;
u8 ucAC0_UAPSD:1;
u8 ucQAck:1;
u8 ucMaxSPLen:2;
u8 ucMoreDataAck:1;
} ByAllSta;
struct
{
u8 ucParameterSetCount:4;
u8 ucQAck:1;
u8 ucQueueReq:1;
u8 ucTXOPReq:1;
u8 ucApUapsd:1;
} ByAllAp;
}QOS_INFO_FIELD, *PQOS_INFO_FIELD;
//
// ACI to AC coding.
// Ref: WMM spec 2.2.2: WME Parameter Element, p.13.
//
// AC_CODING is redefined for enum can't be ++, | under C++ compiler, 2006.05.17, by rcnjko.
//typedef enum _AC_CODING{
// AC0_BE = 0, // ACI: 0x00 // Best Effort
// AC1_BK = 1, // ACI: 0x01 // Background
// AC2_VI = 2, // ACI: 0x10 // Video
// AC3_VO = 3, // ACI: 0x11 // Voice
// AC_MAX = 4, // Max: define total number; Should not to be used as a real enum.
//}AC_CODING,*PAC_CODING;
//
typedef u32 AC_CODING;
#define AC0_BE 0 // ACI: 0x00 // Best Effort
#define AC1_BK 1 // ACI: 0x01 // Background
#define AC2_VI 2 // ACI: 0x10 // Video
#define AC3_VO 3 // ACI: 0x11 // Voice
#define AC_MAX 4 // Max: define total number; Should not to be used as a real enum.
//
// ACI/AIFSN Field.
// Ref: WMM spec 2.2.2: WME Parameter Element, p.12.
//
typedef union _ACI_AIFSN{
u8 charData;
struct
{
u8 AIFSN:4;
u8 ACM:1;
u8 ACI:2;
u8 Reserved:1;
}f; // Field
}ACI_AIFSN, *PACI_AIFSN;
//
// ECWmin/ECWmax field.
// Ref: WMM spec 2.2.2: WME Parameter Element, p.13.
//
typedef union _ECW{
u8 charData;
struct
{
u8 ECWmin:4;
u8 ECWmax:4;
}f; // Field
}ECW, *PECW;
//
// AC Parameters Record Format.
// Ref: WMM spec 2.2.2: WME Parameter Element, p.12.
//
typedef union _AC_PARAM{
u32 longData;
u8 charData[4];
struct
{
ACI_AIFSN AciAifsn;
ECW Ecw;
u16 TXOPLimit;
}f; // Field
}AC_PARAM, *PAC_PARAM;
//
// QoS element subtype
//
typedef enum _QOS_ELE_SUBTYPE{
QOSELE_TYPE_INFO = 0x00, // 0x00: Information element
QOSELE_TYPE_PARAM = 0x01, // 0x01: parameter element
}QOS_ELE_SUBTYPE,*PQOS_ELE_SUBTYPE;
//
// Direction Field Values.
// Ref: WMM spec 2.2.11: WME TSPEC Element, p.18.
//
typedef enum _DIRECTION_VALUE{
DIR_UP = 0, // 0x00 // UpLink
DIR_DOWN = 1, // 0x01 // DownLink
DIR_DIRECT = 2, // 0x10 // DirectLink
DIR_BI_DIR = 3, // 0x11 // Bi-Direction
}DIRECTION_VALUE,*PDIRECTION_VALUE;
//
// TS Info field in WMM TSPEC Element.
// Ref:
// 1. WMM spec 2.2.11: WME TSPEC Element, p.18.
// 2. 8185 QoS code: QOS_TSINFO [def. in QoS_mp.h]
//
typedef union _QOS_TSINFO{
u8 charData[3];
struct {
u8 ucTrafficType:1; //WMM is reserved
u8 ucTSID:4;
u8 ucDirection:2;
u8 ucAccessPolicy:2; //WMM: bit8=0, bit7=1
u8 ucAggregation:1; //WMM is reserved
u8 ucPSB:1; //WMMSA is APSD
u8 ucUP:3;
u8 ucTSInfoAckPolicy:2; //WMM is reserved
u8 ucSchedule:1; //WMM is reserved
u8 ucReserved:7;
}field;
}QOS_TSINFO, *PQOS_TSINFO;
//
// WMM TSPEC Body.
// Ref: WMM spec 2.2.11: WME TSPEC Element, p.16.
//
typedef union _TSPEC_BODY{
u8 charData[55];
struct
{
QOS_TSINFO TSInfo; //u8 TSInfo[3];
u16 NominalMSDUsize;
u16 MaxMSDUsize;
u32 MinServiceItv;
u32 MaxServiceItv;
u32 InactivityItv;
u32 SuspenItv;
u32 ServiceStartTime;
u32 MinDataRate;
u32 MeanDataRate;
u32 PeakDataRate;
u32 MaxBurstSize;
u32 DelayBound;
u32 MinPhyRate;
u16 SurplusBandwidthAllowance;
u16 MediumTime;
} f; // Field
}TSPEC_BODY, *PTSPEC_BODY;
//
// WMM TSPEC Element.
// Ref: WMM spec 2.2.11: WME TSPEC Element, p.16.
//
typedef struct _WMM_TSPEC{
u8 ID;
u8 Length;
u8 OUI[3];
u8 OUI_Type;
u8 OUI_SubType;
u8 Version;
TSPEC_BODY Body;
} WMM_TSPEC, *PWMM_TSPEC;
//
// ACM implementation method.
// Annie, 2005-12-13.
//
typedef enum _ACM_METHOD{
eAcmWay0_SwAndHw = 0, // By SW and HW.
eAcmWay1_HW = 1, // By HW.
eAcmWay2_SW = 2, // By SW.
}ACM_METHOD,*PACM_METHOD;
typedef struct _ACM{
// u8 RegEnableACM;
u64 UsedTime;
u64 MediumTime;
u8 HwAcmCtl; // TRUE: UsedTime exceed => Do NOT USE this AC. It wll be written to ACM_CONTROL(0xBF BIT 0/1/2 in 8185B).
}ACM, *PACM;
typedef u8 AC_UAPSD, *PAC_UAPSD;
#define GET_VO_UAPSD(_apsd) ((_apsd) & BIT0)
#define SET_VO_UAPSD(_apsd) ((_apsd) |= BIT0)
#define GET_VI_UAPSD(_apsd) ((_apsd) & BIT1)
#define SET_VI_UAPSD(_apsd) ((_apsd) |= BIT1)
#define GET_BK_UAPSD(_apsd) ((_apsd) & BIT2)
#define SET_BK_UAPSD(_apsd) ((_apsd) |= BIT2)
#define GET_BE_UAPSD(_apsd) ((_apsd) & BIT3)
#define SET_BE_UAPSD(_apsd) ((_apsd) |= BIT3)
//typedef struct _TCLASS{
// TODO
//} TCLASS, *PTCLASS;
typedef union _QOS_TCLAS{
struct _TYPE_GENERAL{
u8 Priority;
u8 ClassifierType;
u8 Mask;
} TYPE_GENERAL;
struct _TYPE0_ETH{
u8 Priority;
u8 ClassifierType;
u8 Mask;
u8 SrcAddr[6];
u8 DstAddr[6];
u16 Type;
} TYPE0_ETH;
struct _TYPE1_IPV4{
u8 Priority;
u8 ClassifierType;
u8 Mask;
u8 Version;
u8 SrcIP[4];
u8 DstIP[4];
u16 SrcPort;
u16 DstPort;
u8 DSCP;
u8 Protocol;
u8 Reserved;
} TYPE1_IPV4;
struct _TYPE1_IPV6{
u8 Priority;
u8 ClassifierType;
u8 Mask;
u8 Version;
u8 SrcIP[16];
u8 DstIP[16];
u16 SrcPort;
u16 DstPort;
u8 FlowLabel[3];
} TYPE1_IPV6;
struct _TYPE2_8021Q{
u8 Priority;
u8 ClassifierType;
u8 Mask;
u16 TagType;
} TYPE2_8021Q;
} QOS_TCLAS, *PQOS_TCLAS;
//typedef struct _WMM_TSTREAM{
//
//- TSPEC
//- AC (which to mapping)
//} WMM_TSTREAM, *PWMM_TSTREAM;
typedef struct _QOS_TSTREAM{
u8 AC;
WMM_TSPEC TSpec;
QOS_TCLAS TClass;
} QOS_TSTREAM, *PQOS_TSTREAM;
//typedef struct _U_APSD{
//- TriggerEnable [4]
//- MaxSPLength
//- HighestAcBuffered
//} U_APSD, *PU_APSD;
//joseph TODO:
// UAPSD function should be implemented by 2 data structure
// "Qos control field" and "Qos info field"
//typedef struct _QOS_UAPSD{
// u8 bTriggerEnable[4];
// u8 MaxSPLength;
// u8 HighestBufAC;
//} QOS_UAPSD, *PQOS_APSD;
//----------------------------------------------------------------------------
// 802.11 Management frame Status Code field
//----------------------------------------------------------------------------
typedef struct _OCTET_STRING{
u8 *Octet;
u16 Length;
}OCTET_STRING, *POCTET_STRING;
//
// STA QoS data.
// Ref: DOT11_QOS in 8185 code. [def. in QoS_mp.h]
//
typedef struct _STA_QOS{
//DECLARE_RT_OBJECT(STA_QOS);
u8 WMMIEBuf[MAX_WMMELE_LENGTH];
u8* WMMIE;
// Part 1. Self QoS Mode.
QOS_MODE QosCapability; //QoS Capability, 2006-06-14 Isaiah
QOS_MODE CurrentQosMode;
// For WMM Power Save Mode :
// ACs are trigger/delivery enabled or legacy power save enabled. 2006-06-13 Isaiah
AC_UAPSD b4ac_Uapsd; //VoUapsd(bit0), ViUapsd(bit1), BkUapsd(bit2), BeUapsd(bit3),
AC_UAPSD Curr4acUapsd;
u8 bInServicePeriod;
u8 MaxSPLength;
int NumBcnBeforeTrigger;
// Part 2. EDCA Parameter (perAC)
u8 * pWMMInfoEle;
u8 WMMParamEle[WMM_PARAM_ELEMENT_SIZE];
u8 WMMPELength;
// <Bruce_Note>
//2 ToDo: remove the Qos Info Field and replace it by the above WMM Info element.
// By Bruce, 2008-01-30.
// Part 2. EDCA Parameter (perAC)
QOS_INFO_FIELD QosInfoField_STA; // Maintained by STA
QOS_INFO_FIELD QosInfoField_AP; // Retrieved from AP
AC_PARAM CurAcParameters[4];
// Part 3. ACM
ACM acm[4];
ACM_METHOD AcmMethod;
// Part 4. Per TID (Part 5: TCLASS will be described by TStream)
QOS_TSTREAM TStream[16];
WMM_TSPEC TSpec;
u32 QBssWirelessMode;
// No Ack Setting
u8 bNoAck;
// Enable/Disable Rx immediate BA capability.
u8 bEnableRxImmBA;
}STA_QOS, *PSTA_QOS;
//
// BSS QOS data.
// Ref: BssDscr in 8185 code. [def. in BssDscr.h]
//
typedef struct _BSS_QOS{
QOS_MODE bdQoSMode;
u8 bdWMMIEBuf[MAX_WMMELE_LENGTH];
u8* bdWMMIE;
QOS_ELE_SUBTYPE EleSubType;
u8 * pWMMInfoEle;
u8 * pWMMParamEle;
QOS_INFO_FIELD QosInfoField;
AC_PARAM AcParameter[4];
}BSS_QOS, *PBSS_QOS;
//
// Ref: sQoSCtlLng and QoSCtl definition in 8185 QoS code.
//#define QoSCtl (( (Adapter->bRegQoS) && (Adapter->dot11QoS.QoSMode &(QOS_EDCA|QOS_HCCA)) ) ?sQoSCtlLng:0)
//
#define sQoSCtlLng 2
#define QOS_CTRL_LEN(_QosMode) ((_QosMode > QOS_DISABLE)? sQoSCtlLng : 0)
//Added by joseph
//UP Mapping to AC, using in MgntQuery_SequenceNumber() and maybe for DSCP
//#define UP2AC(up) ((up<3)?((up==0)?1:0):(up>>1))
#define IsACValid(ac) ((ac<=7 )?true:false )
#endif // #ifndef __INC_QOS_TYPE_H

View file

@ -1,627 +0,0 @@
#include "ieee80211.h"
#include <linux/etherdevice.h>
#include <linux/slab.h>
#include "rtl819x_TS.h"
void TsSetupTimeOut(unsigned long data)
{
// Not implement yet
// This is used for WMMSA and ACM , that would send ADDTSReq frame.
}
void TsInactTimeout(unsigned long data)
{
// Not implement yet
// This is used for WMMSA and ACM.
// This function would be call when TS is no Tx/Rx for some period of time.
}
/********************************************************************************************************************
*function: I still not understand this function, so wait for further implementation
* input: unsigned long data //acturally we send TX_TS_RECORD or RX_TS_RECORD to these timer
* return: NULL
* notice:
********************************************************************************************************************/
void RxPktPendingTimeout(unsigned long data)
{
PRX_TS_RECORD pRxTs = (PRX_TS_RECORD)data;
struct ieee80211_device *ieee = container_of(pRxTs, struct ieee80211_device, RxTsRecord[pRxTs->num]);
PRX_REORDER_ENTRY pReorderEntry = NULL;
//u32 flags = 0;
unsigned long flags = 0;
struct ieee80211_rxb *stats_IndicateArray[REORDER_WIN_SIZE];
u8 index = 0;
bool bPktInBuf = false;
spin_lock_irqsave(&(ieee->reorder_spinlock), flags);
//PlatformAcquireSpinLock(Adapter, RT_RX_SPINLOCK);
IEEE80211_DEBUG(IEEE80211_DL_REORDER,"==================>%s()\n",__FUNCTION__);
if(pRxTs->RxTimeoutIndicateSeq != 0xffff)
{
// Indicate the pending packets sequentially according to SeqNum until meet the gap.
while(!list_empty(&pRxTs->RxPendingPktList))
{
pReorderEntry = (PRX_REORDER_ENTRY)list_entry(pRxTs->RxPendingPktList.prev,RX_REORDER_ENTRY,List);
if(index == 0)
pRxTs->RxIndicateSeq = pReorderEntry->SeqNum;
if( SN_LESS(pReorderEntry->SeqNum, pRxTs->RxIndicateSeq) ||
SN_EQUAL(pReorderEntry->SeqNum, pRxTs->RxIndicateSeq) )
{
list_del_init(&pReorderEntry->List);
if(SN_EQUAL(pReorderEntry->SeqNum, pRxTs->RxIndicateSeq))
pRxTs->RxIndicateSeq = (pRxTs->RxIndicateSeq + 1) % 4096;
IEEE80211_DEBUG(IEEE80211_DL_REORDER,"RxPktPendingTimeout(): IndicateSeq: %d\n", pReorderEntry->SeqNum);
stats_IndicateArray[index] = pReorderEntry->prxb;
index++;
list_add_tail(&pReorderEntry->List, &ieee->RxReorder_Unused_List);
}
else
{
bPktInBuf = true;
break;
}
}
}
if(index>0)
{
// Set RxTimeoutIndicateSeq to 0xffff to indicate no pending packets in buffer now.
pRxTs->RxTimeoutIndicateSeq = 0xffff;
// Indicate packets
if(index > REORDER_WIN_SIZE){
IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): Rx Reorer buffer full!! \n");
spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
return;
}
ieee80211_indicate_packets(ieee, stats_IndicateArray, index);
}
if(bPktInBuf && (pRxTs->RxTimeoutIndicateSeq==0xffff))
{
pRxTs->RxTimeoutIndicateSeq = pRxTs->RxIndicateSeq;
mod_timer(&pRxTs->RxPktPendingTimer, jiffies + MSECS(ieee->pHTInfo->RxReorderPendingTime));
}
spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
//PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK);
}
/********************************************************************************************************************
*function: Add BA timer function
* input: unsigned long data //acturally we send TX_TS_RECORD or RX_TS_RECORD to these timer
* return: NULL
* notice:
********************************************************************************************************************/
void TsAddBaProcess(unsigned long data)
{
PTX_TS_RECORD pTxTs = (PTX_TS_RECORD)data;
u8 num = pTxTs->num;
struct ieee80211_device *ieee = container_of(pTxTs, struct ieee80211_device, TxTsRecord[num]);
TsInitAddBA(ieee, pTxTs, BA_POLICY_IMMEDIATE, false);
IEEE80211_DEBUG(IEEE80211_DL_BA, "TsAddBaProcess(): ADDBA Req is started!! \n");
}
void ResetTsCommonInfo(PTS_COMMON_INFO pTsCommonInfo)
{
memset(pTsCommonInfo->Addr, 0, 6);
memset(&pTsCommonInfo->TSpec, 0, sizeof(TSPEC_BODY));
memset(&pTsCommonInfo->TClass, 0, sizeof(QOS_TCLAS)*TCLAS_NUM);
pTsCommonInfo->TClasProc = 0;
pTsCommonInfo->TClasNum = 0;
}
void ResetTxTsEntry(PTX_TS_RECORD pTS)
{
ResetTsCommonInfo(&pTS->TsCommonInfo);
pTS->TxCurSeq = 0;
pTS->bAddBaReqInProgress = false;
pTS->bAddBaReqDelayed = false;
pTS->bUsingBa = false;
ResetBaEntry(&pTS->TxAdmittedBARecord); //For BA Originator
ResetBaEntry(&pTS->TxPendingBARecord);
}
void ResetRxTsEntry(PRX_TS_RECORD pTS)
{
ResetTsCommonInfo(&pTS->TsCommonInfo);
pTS->RxIndicateSeq = 0xffff; // This indicate the RxIndicateSeq is not used now!!
pTS->RxTimeoutIndicateSeq = 0xffff; // This indicate the RxTimeoutIndicateSeq is not used now!!
ResetBaEntry(&pTS->RxAdmittedBARecord); // For BA Recipient
}
void TSInitialize(struct ieee80211_device *ieee)
{
PTX_TS_RECORD pTxTS = ieee->TxTsRecord;
PRX_TS_RECORD pRxTS = ieee->RxTsRecord;
PRX_REORDER_ENTRY pRxReorderEntry = ieee->RxReorderEntry;
u8 count = 0;
IEEE80211_DEBUG(IEEE80211_DL_TS, "==========>%s()\n", __FUNCTION__);
// Initialize Tx TS related info.
INIT_LIST_HEAD(&ieee->Tx_TS_Admit_List);
INIT_LIST_HEAD(&ieee->Tx_TS_Pending_List);
INIT_LIST_HEAD(&ieee->Tx_TS_Unused_List);
for(count = 0; count < TOTAL_TS_NUM; count++)
{
//
pTxTS->num = count;
// The timers for the operation of Traffic Stream and Block Ack.
// DLS related timer will be add here in the future!!
init_timer(&pTxTS->TsCommonInfo.SetupTimer);
pTxTS->TsCommonInfo.SetupTimer.data = (unsigned long)pTxTS;
pTxTS->TsCommonInfo.SetupTimer.function = TsSetupTimeOut;
init_timer(&pTxTS->TsCommonInfo.InactTimer);
pTxTS->TsCommonInfo.InactTimer.data = (unsigned long)pTxTS;
pTxTS->TsCommonInfo.InactTimer.function = TsInactTimeout;
init_timer(&pTxTS->TsAddBaTimer);
pTxTS->TsAddBaTimer.data = (unsigned long)pTxTS;
pTxTS->TsAddBaTimer.function = TsAddBaProcess;
init_timer(&pTxTS->TxPendingBARecord.Timer);
pTxTS->TxPendingBARecord.Timer.data = (unsigned long)pTxTS;
pTxTS->TxPendingBARecord.Timer.function = BaSetupTimeOut;
init_timer(&pTxTS->TxAdmittedBARecord.Timer);
pTxTS->TxAdmittedBARecord.Timer.data = (unsigned long)pTxTS;
pTxTS->TxAdmittedBARecord.Timer.function = TxBaInactTimeout;
ResetTxTsEntry(pTxTS);
list_add_tail(&pTxTS->TsCommonInfo.List, &ieee->Tx_TS_Unused_List);
pTxTS++;
}
// Initialize Rx TS related info.
INIT_LIST_HEAD(&ieee->Rx_TS_Admit_List);
INIT_LIST_HEAD(&ieee->Rx_TS_Pending_List);
INIT_LIST_HEAD(&ieee->Rx_TS_Unused_List);
for(count = 0; count < TOTAL_TS_NUM; count++)
{
pRxTS->num = count;
INIT_LIST_HEAD(&pRxTS->RxPendingPktList);
init_timer(&pRxTS->TsCommonInfo.SetupTimer);
pRxTS->TsCommonInfo.SetupTimer.data = (unsigned long)pRxTS;
pRxTS->TsCommonInfo.SetupTimer.function = TsSetupTimeOut;
init_timer(&pRxTS->TsCommonInfo.InactTimer);
pRxTS->TsCommonInfo.InactTimer.data = (unsigned long)pRxTS;
pRxTS->TsCommonInfo.InactTimer.function = TsInactTimeout;
init_timer(&pRxTS->RxAdmittedBARecord.Timer);
pRxTS->RxAdmittedBARecord.Timer.data = (unsigned long)pRxTS;
pRxTS->RxAdmittedBARecord.Timer.function = RxBaInactTimeout;
init_timer(&pRxTS->RxPktPendingTimer);
pRxTS->RxPktPendingTimer.data = (unsigned long)pRxTS;
pRxTS->RxPktPendingTimer.function = RxPktPendingTimeout;
ResetRxTsEntry(pRxTS);
list_add_tail(&pRxTS->TsCommonInfo.List, &ieee->Rx_TS_Unused_List);
pRxTS++;
}
// Initialize unused Rx Reorder List.
INIT_LIST_HEAD(&ieee->RxReorder_Unused_List);
//#ifdef TO_DO_LIST
for(count = 0; count < REORDER_ENTRY_NUM; count++)
{
list_add_tail( &pRxReorderEntry->List,&ieee->RxReorder_Unused_List);
if(count == (REORDER_ENTRY_NUM-1))
break;
pRxReorderEntry = &ieee->RxReorderEntry[count+1];
}
//#endif
}
void AdmitTS(struct ieee80211_device *ieee, PTS_COMMON_INFO pTsCommonInfo, u32 InactTime)
{
del_timer_sync(&pTsCommonInfo->SetupTimer);
del_timer_sync(&pTsCommonInfo->InactTimer);
if(InactTime!=0)
mod_timer(&pTsCommonInfo->InactTimer, jiffies + MSECS(InactTime));
}
PTS_COMMON_INFO SearchAdmitTRStream(struct ieee80211_device *ieee, u8* Addr, u8 TID, TR_SELECT TxRxSelect)
{
//DIRECTION_VALUE dir;
u8 dir;
bool search_dir[4] = {0, 0, 0, 0};
struct list_head* psearch_list; //FIXME
PTS_COMMON_INFO pRet = NULL;
if(ieee->iw_mode == IW_MODE_MASTER) //ap mode
{
if(TxRxSelect == TX_DIR)
{
search_dir[DIR_DOWN] = true;
search_dir[DIR_BI_DIR]= true;
}
else
{
search_dir[DIR_UP] = true;
search_dir[DIR_BI_DIR]= true;
}
}
else if(ieee->iw_mode == IW_MODE_ADHOC)
{
if(TxRxSelect == TX_DIR)
search_dir[DIR_UP] = true;
else
search_dir[DIR_DOWN] = true;
}
else
{
if(TxRxSelect == TX_DIR)
{
search_dir[DIR_UP] = true;
search_dir[DIR_BI_DIR]= true;
search_dir[DIR_DIRECT]= true;
}
else
{
search_dir[DIR_DOWN] = true;
search_dir[DIR_BI_DIR]= true;
search_dir[DIR_DIRECT]= true;
}
}
if(TxRxSelect == TX_DIR)
psearch_list = &ieee->Tx_TS_Admit_List;
else
psearch_list = &ieee->Rx_TS_Admit_List;
//for(dir = DIR_UP; dir <= DIR_BI_DIR; dir++)
for(dir = 0; dir <= DIR_BI_DIR; dir++)
{
if(search_dir[dir] ==false )
continue;
list_for_each_entry(pRet, psearch_list, List){
// IEEE80211_DEBUG(IEEE80211_DL_TS, "ADD:%pM, TID:%d, dir:%d\n", pRet->Addr, pRet->TSpec.f.TSInfo.field.ucTSID, pRet->TSpec.f.TSInfo.field.ucDirection);
if (memcmp(pRet->Addr, Addr, 6) == 0)
if (pRet->TSpec.f.TSInfo.field.ucTSID == TID)
if(pRet->TSpec.f.TSInfo.field.ucDirection == dir)
{
break;
}
}
if(&pRet->List != psearch_list)
break;
}
if(&pRet->List != psearch_list){
return pRet ;
}
else
return NULL;
}
void MakeTSEntry(
PTS_COMMON_INFO pTsCommonInfo,
u8* Addr,
PTSPEC_BODY pTSPEC,
PQOS_TCLAS pTCLAS,
u8 TCLAS_Num,
u8 TCLAS_Proc
)
{
u8 count;
if(pTsCommonInfo == NULL)
return;
memcpy(pTsCommonInfo->Addr, Addr, 6);
if(pTSPEC != NULL)
memcpy((u8*)(&(pTsCommonInfo->TSpec)), (u8*)pTSPEC, sizeof(TSPEC_BODY));
for(count = 0; count < TCLAS_Num; count++)
memcpy((u8*)(&(pTsCommonInfo->TClass[count])), (u8*)pTCLAS, sizeof(QOS_TCLAS));
pTsCommonInfo->TClasProc = TCLAS_Proc;
pTsCommonInfo->TClasNum = TCLAS_Num;
}
bool GetTs(
struct ieee80211_device* ieee,
PTS_COMMON_INFO *ppTS,
u8* Addr,
u8 TID,
TR_SELECT TxRxSelect, //Rx:1, Tx:0
bool bAddNewTs
)
{
u8 UP = 0;
//
// We do not build any TS for Broadcast or Multicast stream.
// So reject these kinds of search here.
//
if(is_broadcast_ether_addr(Addr) || is_multicast_ether_addr(Addr))
{
IEEE80211_DEBUG(IEEE80211_DL_ERR, "get TS for Broadcast or Multicast\n");
return false;
}
if (ieee->current_network.qos_data.supported == 0)
UP = 0;
else
{
// In WMM case: we use 4 TID only
if (!IsACValid(TID))
{
IEEE80211_DEBUG(IEEE80211_DL_ERR, " in %s(), TID(%d) is not valid\n", __FUNCTION__, TID);
return false;
}
switch(TID)
{
case 0:
case 3:
UP = 0;
break;
case 1:
case 2:
UP = 2;
break;
case 4:
case 5:
UP = 5;
break;
case 6:
case 7:
UP = 7;
break;
}
}
*ppTS = SearchAdmitTRStream(
ieee,
Addr,
UP,
TxRxSelect);
if(*ppTS != NULL)
{
return true;
}
else
{
if(bAddNewTs == false)
{
IEEE80211_DEBUG(IEEE80211_DL_TS, "add new TS failed(tid:%d)\n", UP);
return false;
}
else
{
//
// Create a new Traffic stream for current Tx/Rx
// This is for EDCA and WMM to add a new TS.
// For HCCA or WMMSA, TS cannot be addmit without negotiation.
//
TSPEC_BODY TSpec;
PQOS_TSINFO pTSInfo = &TSpec.f.TSInfo;
struct list_head* pUnusedList =
(TxRxSelect == TX_DIR)?
(&ieee->Tx_TS_Unused_List):
(&ieee->Rx_TS_Unused_List);
struct list_head* pAddmitList =
(TxRxSelect == TX_DIR)?
(&ieee->Tx_TS_Admit_List):
(&ieee->Rx_TS_Admit_List);
DIRECTION_VALUE Dir = (ieee->iw_mode == IW_MODE_MASTER)?
((TxRxSelect==TX_DIR)?DIR_DOWN:DIR_UP):
((TxRxSelect==TX_DIR)?DIR_UP:DIR_DOWN);
IEEE80211_DEBUG(IEEE80211_DL_TS, "to add Ts\n");
if(!list_empty(pUnusedList))
{
(*ppTS) = list_entry(pUnusedList->next, TS_COMMON_INFO, List);
list_del_init(&(*ppTS)->List);
if(TxRxSelect==TX_DIR)
{
PTX_TS_RECORD tmp = container_of(*ppTS, TX_TS_RECORD, TsCommonInfo);
ResetTxTsEntry(tmp);
}
else{
PRX_TS_RECORD tmp = container_of(*ppTS, RX_TS_RECORD, TsCommonInfo);
ResetRxTsEntry(tmp);
}
IEEE80211_DEBUG(IEEE80211_DL_TS, "to init current TS, UP:%d, Dir:%d, addr:%pM\n", UP, Dir, Addr);
// Prepare TS Info releated field
pTSInfo->field.ucTrafficType = 0; // Traffic type: WMM is reserved in this field
pTSInfo->field.ucTSID = UP; // TSID
pTSInfo->field.ucDirection = Dir; // Direction: if there is DirectLink, this need additional consideration.
pTSInfo->field.ucAccessPolicy = 1; // Access policy
pTSInfo->field.ucAggregation = 0; // Aggregation
pTSInfo->field.ucPSB = 0; // Aggregation
pTSInfo->field.ucUP = UP; // User priority
pTSInfo->field.ucTSInfoAckPolicy = 0; // Ack policy
pTSInfo->field.ucSchedule = 0; // Schedule
MakeTSEntry(*ppTS, Addr, &TSpec, NULL, 0, 0);
AdmitTS(ieee, *ppTS, 0);
list_add_tail(&((*ppTS)->List), pAddmitList);
// if there is DirectLink, we need to do additional operation here!!
return true;
}
else
{
IEEE80211_DEBUG(IEEE80211_DL_ERR, "in function %s() There is not enough TS record to be used!!", __FUNCTION__);
return false;
}
}
}
}
void RemoveTsEntry(
struct ieee80211_device* ieee,
PTS_COMMON_INFO pTs,
TR_SELECT TxRxSelect
)
{
//u32 flags = 0;
unsigned long flags = 0;
del_timer_sync(&pTs->SetupTimer);
del_timer_sync(&pTs->InactTimer);
TsInitDelBA(ieee, pTs, TxRxSelect);
if(TxRxSelect == RX_DIR)
{
//#ifdef TO_DO_LIST
PRX_REORDER_ENTRY pRxReorderEntry;
PRX_TS_RECORD pRxTS = (PRX_TS_RECORD)pTs;
if(timer_pending(&pRxTS->RxPktPendingTimer))
del_timer_sync(&pRxTS->RxPktPendingTimer);
while(!list_empty(&pRxTS->RxPendingPktList))
{
// PlatformAcquireSpinLock(Adapter, RT_RX_SPINLOCK);
spin_lock_irqsave(&(ieee->reorder_spinlock), flags);
//pRxReorderEntry = list_entry(&pRxTS->RxPendingPktList.prev,RX_REORDER_ENTRY,List);
pRxReorderEntry = (PRX_REORDER_ENTRY)list_entry(pRxTS->RxPendingPktList.prev,RX_REORDER_ENTRY,List);
list_del_init(&pRxReorderEntry->List);
{
int i = 0;
struct ieee80211_rxb * prxb = pRxReorderEntry->prxb;
if (unlikely(!prxb))
{
spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
return;
}
for(i =0; i < prxb->nr_subframes; i++) {
dev_kfree_skb(prxb->subframes[i]);
}
kfree(prxb);
prxb = NULL;
}
list_add_tail(&pRxReorderEntry->List,&ieee->RxReorder_Unused_List);
//PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK);
spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
}
//#endif
}
else
{
PTX_TS_RECORD pTxTS = (PTX_TS_RECORD)pTs;
del_timer_sync(&pTxTS->TsAddBaTimer);
}
}
void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr)
{
PTS_COMMON_INFO pTS, pTmpTS;
printk("===========>RemovePeerTS,%pM\n", Addr);
list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List)
{
if (memcmp(pTS->Addr, Addr, 6) == 0)
{
RemoveTsEntry(ieee, pTS, TX_DIR);
list_del_init(&pTS->List);
list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List);
}
}
list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Admit_List, List)
{
if (memcmp(pTS->Addr, Addr, 6) == 0)
{
printk("====>remove Tx_TS_admin_list\n");
RemoveTsEntry(ieee, pTS, TX_DIR);
list_del_init(&pTS->List);
list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List);
}
}
list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Pending_List, List)
{
if (memcmp(pTS->Addr, Addr, 6) == 0)
{
RemoveTsEntry(ieee, pTS, RX_DIR);
list_del_init(&pTS->List);
list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List);
}
}
list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Admit_List, List)
{
if (memcmp(pTS->Addr, Addr, 6) == 0)
{
RemoveTsEntry(ieee, pTS, RX_DIR);
list_del_init(&pTS->List);
list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List);
}
}
}
void RemoveAllTS(struct ieee80211_device* ieee)
{
PTS_COMMON_INFO pTS, pTmpTS;
list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List)
{
RemoveTsEntry(ieee, pTS, TX_DIR);
list_del_init(&pTS->List);
list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List);
}
list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Admit_List, List)
{
RemoveTsEntry(ieee, pTS, TX_DIR);
list_del_init(&pTS->List);
list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List);
}
list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Pending_List, List)
{
RemoveTsEntry(ieee, pTS, RX_DIR);
list_del_init(&pTS->List);
list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List);
}
list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Admit_List, List)
{
RemoveTsEntry(ieee, pTS, RX_DIR);
list_del_init(&pTS->List);
list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List);
}
}
void TsStartAddBaProcess(struct ieee80211_device* ieee, PTX_TS_RECORD pTxTS)
{
if(pTxTS->bAddBaReqInProgress == false)
{
pTxTS->bAddBaReqInProgress = true;
if(pTxTS->bAddBaReqDelayed)
{
IEEE80211_DEBUG(IEEE80211_DL_BA, "TsStartAddBaProcess(): Delayed Start ADDBA after 60 sec!!\n");
mod_timer(&pTxTS->TsAddBaTimer, jiffies + MSECS(TS_ADDBA_DELAY));
}
else
{
IEEE80211_DEBUG(IEEE80211_DL_BA,"TsStartAddBaProcess(): Immediately Start ADDBA now!!\n");
mod_timer(&pTxTS->TsAddBaTimer, jiffies+10); //set 10 ticks
}
}
else
IEEE80211_DEBUG(IEEE80211_DL_ERR, "%s()==>BA timer is already added\n", __FUNCTION__);
}

View file

@ -0,0 +1,129 @@
/*
* Cryptographic API.
*
* Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
*
* 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.
*
*/
#ifndef _CRYPTO_INTERNAL_H
#define _CRYPTO_INTERNAL_H
#include <linux/version.h>
#include "rtl_crypto.h"
#include <linux/mm.h>
#include <linux/highmem.h>
#include <linux/init.h>
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12))
#include <asm/hardirq.h>
#else
#include <linux/hardirq.h>
#include <linux/sched.h>
#endif
#include <asm/kmap_types.h>
#ifdef BUILT_IN_CRYPTO
#ifdef CONFIG_CRYPTO_HMAC
#undef CONFIG_CRYPTO_HMAC
#endif
#ifdef CONFIG_KMOD
#undef CONFIG_KMOD
#endif
#endif /* BUILT_IN_CRYPTO */
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,20))
#define list_for_each_entry(pos, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member), \
prefetch(pos->member.next); \
&pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member), \
prefetch(pos->member.next))
static inline void cond_resched(void)
{
if (need_resched()) {
set_current_state(TASK_RUNNING);
schedule();
}
}
#endif
extern enum km_type crypto_km_types[];
static inline enum km_type crypto_kmap_type(int out)
{
return crypto_km_types[(in_softirq() ? 2 : 0) + out];
}
static inline void *crypto_kmap(struct page *page, int out)
{
return kmap_atomic(page, crypto_kmap_type(out));
}
static inline void crypto_kunmap(void *vaddr, int out)
{
kunmap_atomic(vaddr, crypto_kmap_type(out));
}
static inline void crypto_yield(struct crypto_tfm *tfm)
{
if (!in_softirq())
cond_resched();
}
static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm)
{
return (void *)&tfm[1];
}
struct crypto_alg *crypto_alg_lookup(const char *name);
#ifdef CONFIG_KMOD
void crypto_alg_autoload(const char *name);
struct crypto_alg *crypto_alg_mod_lookup(const char *name);
#else
static inline struct crypto_alg *crypto_alg_mod_lookup(const char *name)
{
return crypto_alg_lookup(name);
}
#endif
#ifdef CONFIG_CRYPTO_HMAC
int crypto_alloc_hmac_block(struct crypto_tfm *tfm);
void crypto_free_hmac_block(struct crypto_tfm *tfm);
#else
static inline int crypto_alloc_hmac_block(struct crypto_tfm *tfm)
{
return 0;
}
static inline void crypto_free_hmac_block(struct crypto_tfm *tfm)
{ }
#endif
#ifdef CONFIG_PROC_FS
void __init crypto_init_proc(void);
#else
static inline void crypto_init_proc(void)
{ }
#endif
int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags);
int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags);
int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags);
int crypto_init_digest_ops(struct crypto_tfm *tfm);
int crypto_init_cipher_ops(struct crypto_tfm *tfm);
int crypto_init_compress_ops(struct crypto_tfm *tfm);
void crypto_exit_digest_ops(struct crypto_tfm *tfm);
void crypto_exit_cipher_ops(struct crypto_tfm *tfm);
void crypto_exit_compress_ops(struct crypto_tfm *tfm);
#endif /* _CRYPTO_INTERNAL_H */

View file

@ -0,0 +1,20 @@
#ifndef __KMAP_TYPES_H
#define __KMAP_TYPES_H
enum km_type {
KM_BOUNCE_READ,
KM_SKB_SUNRPC_DATA,
KM_SKB_DATA_SOFTIRQ,
KM_USER0,
KM_USER1,
KM_BH_IRQ,
KM_SOFTIRQ0,
KM_SOFTIRQ1,
KM_TYPE_NR
};
#define _ASM_KMAP_TYPES_H
#endif

View file

@ -0,0 +1,339 @@
"This software program is licensed subject to the GNU General Public License
(GPL). Version 2, June 1991, available at
<http:
GNU General Public License
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
Everyone is permitted to copy and distribute verbatim copies of this license
document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your freedom to
share and change it. By contrast, the GNU General Public License is intended
to guarantee your freedom to share and change free software--to make sure
the software is free for all its users. This General Public License applies
to most of the Free Software Foundation's software and to any other program
whose authors commit to using it. (Some other Free Software Foundation
software is covered by the GNU Library General Public License instead.) You
can apply it to your programs, too.
When we speak of free software, we are referring to freedom, not price. Our
General Public Licenses are designed to make sure that you have the freedom
to distribute copies of free software (and charge for this service if you
wish), that you receive source code or can get it if you want it, that you
can change the software or use pieces of it in new free programs; and that
you know you can do these things.
To protect your rights, we need to make restrictions that forbid anyone to
deny you these rights or to ask you to surrender the rights. These
restrictions translate to certain responsibilities for you if you distribute
copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether gratis or
for a fee, you must give the recipients all the rights that you have. You
must make sure that they, too, receive or can get the source code. And you
must show them these terms so they know their rights.
We protect your rights with two steps: (1) copyright the software, and (2)
offer you this license which gives you legal permission to copy, distribute
and/or modify the software.
Also, for each author's protection and ours, we want to make certain that
everyone understands that there is no warranty for this free software. If
the software is modified by someone else and passed on, we want its
recipients to know that what they have is not the original, so that any
problems introduced by others will not reflect on the original authors'
reputations.
Finally, any free program is threatened constantly by software patents. We
wish to avoid the danger that redistributors of a free program will
individually obtain patent licenses, in effect making the program
proprietary. To prevent this, we have made it clear that any patent must be
licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and modification
follow.
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains a notice
placed by the copyright holder saying it may be distributed under the
terms of this General Public License. The "Program", below, refers to any
such program or work, and a "work based on the Program" means either the
Program or any derivative work under copyright law: that is to say, a
work containing the Program or a portion of it, either verbatim or with
modifications and/or translated into another language. (Hereinafter,
translation is included without limitation in the term "modification".)
Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of running
the Program is not restricted, and the output from the Program is covered
only if its contents constitute a work based on the Program (independent
of having been made by running the Program). Whether that is true depends
on what the Program does.
1. You may copy and distribute verbatim copies of the Program's source code
as you receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice and
disclaimer of warranty; keep intact all the notices that refer to this
License and to the absence of any warranty; and give any other recipients
of the Program a copy of this License along with the Program.
You may charge a fee for the physical act of transferring a copy, and you
may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion of it,
thus forming a work based on the Program, and copy and distribute such
modifications or work under the terms of Section 1 above, provided that
you also meet all of these conditions:
* a) You must cause the modified files to carry prominent notices stating
that you changed the files and the date of any change.
* b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any part
thereof, to be licensed as a whole at no charge to all third parties
under the terms of this License.
* c) If the modified program normally reads commands interactively when
run, you must cause it, when started running for such interactive
use in the most ordinary way, to print or display an announcement
including an appropriate copyright notice and a notice that there is
no warranty (or else, saying that you provide a warranty) and that
users may redistribute the program under these conditions, and
telling the user how to view a copy of this License. (Exception: if
the Program itself is interactive but does not normally print such
an announcement, your work based on the Program is not required to
print an announcement.)
These requirements apply to the modified work as a whole. If identifiable
sections of that work are not derived from the Program, and can be
reasonably considered independent and separate works in themselves, then
this License, and its terms, do not apply to those sections when you
distribute them as separate works. But when you distribute the same
sections as part of a whole which is a work based on the Program, the
distribution of the whole must be on the terms of this License, whose
permissions for other licensees extend to the entire whole, and thus to
each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of a
storage or distribution medium does not bring the other work under the
scope of this License.
3. You may copy and distribute the Program (or a work based on it, under
Section 2) in object code or executable form under the terms of Sections
1 and 2 above provided that you also do one of the following:
* a) Accompany it with the complete corresponding machine-readable source
code, which must be distributed under the terms of Sections 1 and 2
above on a medium customarily used for software interchange; or,
* b) Accompany it with a written offer, valid for at least three years,
to give any third party, for a charge no more than your cost of
physically performing source distribution, a complete machine-
readable copy of the corresponding source code, to be distributed
under the terms of Sections 1 and 2 above on a medium customarily
used for software interchange; or,
* c) Accompany it with the information you received as to the offer to
distribute corresponding source code. (This alternative is allowed
only for noncommercial distribution and only if you received the
program in object code or executable form with such an offer, in
accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source code
means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to control
compilation and installation of the executable. However, as a special
exception, the source code distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on which
the executable runs, unless that component itself accompanies the
executable.
If distribution of executable or object code is made by offering access
to copy from a designated place, then offering equivalent access to copy
the source code from the same place counts as distribution of the source
code, even though third parties are not compelled to copy the source
along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program except as
expressly provided under this License. Any attempt otherwise to copy,
modify, sublicense or distribute the Program is void, and will
automatically terminate your rights under this License. However, parties
who have received copies, or rights, from you under this License will not
have their licenses terminated so long as such parties remain in full
compliance.
5. You are not required to accept this License, since you have not signed
it. However, nothing else grants you permission to modify or distribute
the Program or its derivative works. These actions are prohibited by law
if you do not accept this License. Therefore, by modifying or
distributing the Program (or any work based on the Program), you
indicate your acceptance of this License to do so, and all its terms and
conditions for copying, distributing or modifying the Program or works
based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further restrictions
on the recipients' exercise of the rights granted herein. You are not
responsible for enforcing compliance by third parties to this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot distribute
so as to satisfy simultaneously your obligations under this License and
any other pertinent obligations, then as a consequence you may not
distribute the Program at all. For example, if a patent license would
not permit royalty-free redistribution of the Program by all those who
receive copies directly or indirectly through you, then the only way you
could satisfy both it and this License would be to refrain entirely from
distribution of the Program.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is implemented
by public license practices. Many people have made generous contributions
to the wide range of software distributed through that system in
reliance on consistent application of that system; it is up to the
author/donor to decide if he or she is willing to distribute software
through any other system and a licensee cannot impose that choice.
This section is intended to make thoroughly clear what is believed to be
a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in certain
countries either by patents or by copyrighted interfaces, the original
copyright holder who places the Program under this License may add an
explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions of
the General Public License from time to time. Such new versions will be
similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Program does not specify a version
number of this License, you may choose any version ever published by the
Free Software Foundation.
10. If you wish to incorporate parts of the Program into other free programs
whose distribution conditions are different, write to the author to ask
for permission. For software which is copyrighted by the Free Software
Foundation, write to the Free Software Foundation; we sometimes make
exceptions for this. Our decision will be guided by the two goals of
preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH
YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
NECESSARY SERVICING, REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR
DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM
(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF
THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR
OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it free
software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest to
attach them to the start of each source file to most effectively convey the
exclusion of warranty; and each file should have at least the "copyright"
line and a pointer to where the full notice is found.
one line to give the program's name and an idea of what it does.
Copyright (C) yyyy name of author
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.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this when
it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author Gnomovision comes
with ABSOLUTELY NO WARRANTY; for details type 'show w'. This is free
software, and you are welcome to redistribute it under certain conditions;
type 'show c' for details.
The hypothetical commands 'show w' and 'show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may be
called something other than 'show w' and 'show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
'Gnomovision' (which makes passes at compilers) written by James Hacker.
signature of Ty Coon, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General Public
License instead of this License.

View file

@ -0,0 +1,415 @@
/******************************************************************************
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
******************************************************************************/
#ifndef R8190P_DEF_H
#define R8190P_DEF_H
#include <linux/types.h>
#define MAX_SILENT_RESET_RX_SLOT_NUM 10
#define RX_MPDU_QUEUE 0
#define RX_CMD_QUEUE 1
typedef enum _rtl819x_loopback{
RTL819X_NO_LOOPBACK = 0,
RTL819X_MAC_LOOPBACK = 1,
RTL819X_DMA_LOOPBACK = 2,
RTL819X_CCK_LOOPBACK = 3,
}rtl819x_loopback_e;
#define RESET_DELAY_8185 20
#define RT_IBSS_INT_MASKS (IMR_BcnInt | IMR_BcnInt | IMR_TBDOK | IMR_TBDER)
#define DESC90_RATE1M 0x00
#define DESC90_RATE2M 0x01
#define DESC90_RATE5_5M 0x02
#define DESC90_RATE11M 0x03
#define DESC90_RATE6M 0x04
#define DESC90_RATE9M 0x05
#define DESC90_RATE12M 0x06
#define DESC90_RATE18M 0x07
#define DESC90_RATE24M 0x08
#define DESC90_RATE36M 0x09
#define DESC90_RATE48M 0x0a
#define DESC90_RATE54M 0x0b
#define DESC90_RATEMCS0 0x00
#define DESC90_RATEMCS1 0x01
#define DESC90_RATEMCS2 0x02
#define DESC90_RATEMCS3 0x03
#define DESC90_RATEMCS4 0x04
#define DESC90_RATEMCS5 0x05
#define DESC90_RATEMCS6 0x06
#define DESC90_RATEMCS7 0x07
#define DESC90_RATEMCS8 0x08
#define DESC90_RATEMCS9 0x09
#define DESC90_RATEMCS10 0x0a
#define DESC90_RATEMCS11 0x0b
#define DESC90_RATEMCS12 0x0c
#define DESC90_RATEMCS13 0x0d
#define DESC90_RATEMCS14 0x0e
#define DESC90_RATEMCS15 0x0f
#define DESC90_RATEMCS32 0x20
#define SHORT_SLOT_TIME 9
#define NON_SHORT_SLOT_TIME 20
#define MAX_LINES_HWCONFIG_TXT 1000
#define MAX_BYTES_LINE_HWCONFIG_TXT 128
#define SW_THREE_WIRE 0
#define HW_THREE_WIRE 2
#define BT_DEMO_BOARD 0
#define BT_QA_BOARD 1
#define BT_FPGA 2
#define Rx_Smooth_Factor 20
#define QSLT_BK 0x1
#define QSLT_BE 0x0
#define QSLT_VI 0x4
#define QSLT_VO 0x6
#define QSLT_BEACON 0x10
#define QSLT_HIGH 0x11
#define QSLT_MGNT 0x12
#define QSLT_CMD 0x13
#define NUM_OF_FIRMWARE_QUEUE 10
#define NUM_OF_PAGES_IN_FW 0x100
#define NUM_OF_PAGE_IN_FW_QUEUE_BK 0x007
#define NUM_OF_PAGE_IN_FW_QUEUE_BE 0x0aa
#define NUM_OF_PAGE_IN_FW_QUEUE_VI 0x024
#define NUM_OF_PAGE_IN_FW_QUEUE_VO 0x007
#define NUM_OF_PAGE_IN_FW_QUEUE_HCCA 0
#define NUM_OF_PAGE_IN_FW_QUEUE_CMD 0x2
#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT 0x10
#define NUM_OF_PAGE_IN_FW_QUEUE_HIGH 0
#define NUM_OF_PAGE_IN_FW_QUEUE_BCN 0x4
#define NUM_OF_PAGE_IN_FW_QUEUE_PUB 0xd
#define NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM 0x026
#define NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM 0x048
#define NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM 0x048
#define NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM 0x026
#define NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM 0x00
#define APPLIED_RESERVED_QUEUE_IN_FW 0x80000000
#define RSVD_FW_QUEUE_PAGE_BK_SHIFT 0x00
#define RSVD_FW_QUEUE_PAGE_BE_SHIFT 0x08
#define RSVD_FW_QUEUE_PAGE_VI_SHIFT 0x10
#define RSVD_FW_QUEUE_PAGE_VO_SHIFT 0x18
#define RSVD_FW_QUEUE_PAGE_MGNT_SHIFT 0x10
#define RSVD_FW_QUEUE_PAGE_BCN_SHIFT 0x00
#define RSVD_FW_QUEUE_PAGE_PUB_SHIFT 0x08
#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0
#define HAL_PRIME_CHNL_OFFSET_LOWER 1
#define HAL_PRIME_CHNL_OFFSET_UPPER 2
typedef enum _VERSION_8190{
VERSION_8190_BD=0x3,
VERSION_8190_BE
}VERSION_8190,*PVERSION_8190;
#define IC_VersionCut_C 0x2
#define IC_VersionCut_D 0x3
#define IC_VersionCut_E 0x4
typedef enum tag_Rf_OpType
{
RF_OP_By_SW_3wire = 0,
RF_OP_By_FW,
RF_OP_MAX
}RF_OpType_E;
typedef enum _POWER_SAVE_MODE
{
POWER_SAVE_MODE_ACTIVE,
POWER_SAVE_MODE_SAVE,
}POWER_SAVE_MODE;
typedef enum _INTERFACE_SELECT_8190PCI{
INTF_SEL1_MINICARD = 0,
INTF_SEL0_PCIE = 1,
INTF_SEL2_RSV = 2,
INTF_SEL3_RSV = 3,
} INTERFACE_SELECT_8190PCI, *PINTERFACE_SELECT_8190PCI;
typedef struct _BB_REGISTER_DEFINITION{
u32 rfintfs;
u32 rfintfi;
u32 rfintfo;
u32 rfintfe;
u32 rf3wireOffset;
u32 rfLSSI_Select;
u32 rfTxGainStage;
u32 rfHSSIPara1;
u32 rfHSSIPara2;
u32 rfSwitchControl;
u32 rfAGCControl1;
u32 rfAGCControl2;
u32 rfRxIQImbalance;
u32 rfRxAFE;
u32 rfTxIQImbalance;
u32 rfTxAFE;
u32 rfLSSIReadBack;
u32 rfLSSIReadBackPi;
}BB_REGISTER_DEFINITION_T, *PBB_REGISTER_DEFINITION_T;
typedef struct _TX_FWINFO_STRUCUTRE{
u8 TxRate:7;
u8 CtsEnable:1;
u8 RtsRate:7;
u8 RtsEnable:1;
u8 TxHT:1;
u8 Short:1;
u8 TxBandwidth:1;
u8 TxSubCarrier:2;
u8 STBC:2;
u8 AllowAggregation:1;
u8 RtsHT:1;
u8 RtsShort:1;
u8 RtsBandwidth:1;
u8 RtsSubcarrier:2;
u8 RtsSTBC:2;
u8 EnableCPUDur:1;
u32 RxMF:2;
u32 RxAMD:3;
u32 Reserved1:3;
u32 TxAGCOffset:4;
u32 TxAGCSign:1;
u32 Tx_INFO_RSVD:6;
u32 PacketID:13;
}TX_FWINFO_T;
typedef struct _TX_FWINFO_8190PCI{
u8 TxRate:7;
u8 CtsEnable:1;
u8 RtsRate:7;
u8 RtsEnable:1;
u8 TxHT:1;
u8 Short:1;
u8 TxBandwidth:1;
u8 TxSubCarrier:2;
u8 STBC:2;
u8 AllowAggregation:1;
u8 RtsHT:1;
u8 RtsShort:1;
u8 RtsBandwidth:1;
u8 RtsSubcarrier:2;
u8 RtsSTBC:2;
u8 EnableCPUDur:1;
u32 RxMF:2;
u32 RxAMD:3;
u32 TxPerPktInfoFeedback:1;
u32 Reserved1:2;
u32 TxAGCOffset:4;
u32 TxAGCSign:1;
u32 RAW_TXD:1;
u32 Retry_Limit:4;
u32 Reserved2:1;
u32 PacketID:13;
}TX_FWINFO_8190PCI, *PTX_FWINFO_8190PCI;
#define TX_DESC_SIZE 32
#define TX_DESC_CMD_SIZE 32
#define TX_STATUS_DESC_SIZE 32
#define TX_FWINFO_SIZE 8
#define RX_DESC_SIZE 16
#define RX_STATUS_DESC_SIZE 16
#define RX_DRIVER_INFO_SIZE 8
typedef struct _LOG_INTERRUPT_8190
{
u32 nIMR_COMDOK;
u32 nIMR_MGNTDOK;
u32 nIMR_HIGH;
u32 nIMR_VODOK;
u32 nIMR_VIDOK;
u32 nIMR_BEDOK;
u32 nIMR_BKDOK;
u32 nIMR_ROK;
u32 nIMR_RCOK;
u32 nIMR_TBDOK;
u32 nIMR_BDOK;
u32 nIMR_RXFOVW;
} LOG_INTERRUPT_8190_T, *PLOG_INTERRUPT_8190_T;
typedef struct _phy_ofdm_rx_status_rxsc_sgien_exintfflag{
u8 reserved:4;
u8 rxsc:2;
u8 sgi_en:1;
u8 ex_intf_flag:1;
}phy_ofdm_rx_status_rxsc_sgien_exintfflag;
typedef struct _phy_ofdm_rx_status_report_819xpci
{
u8 trsw_gain_X[4];
u8 pwdb_all;
u8 cfosho_X[4];
u8 cfotail_X[4];
u8 rxevm_X[2];
u8 rxsnr_X[4];
u8 pdsnr_X[2];
u8 csi_current_X[2];
u8 csi_target_X[2];
u8 sigevm;
u8 max_ex_pwr;
u8 sgi_en;
u8 rxsc_sgien_exflg;
}phy_sts_ofdm_819xpci_t;
typedef struct _phy_cck_rx_status_report_819xpci
{
u8 adc_pwdb_X[4];
u8 sq_rpt;
u8 cck_agc_rpt;
}phy_sts_cck_819xpci_t, phy_sts_cck_8192s_t;
#define PHY_RSSI_SLID_WIN_MAX 100
#define PHY_Beacon_RSSI_SLID_WIN_MAX 10
typedef struct _tx_desc_819x_pci {
u16 PktSize;
u8 Offset;
u8 Reserved1:3;
u8 CmdInit:1;
u8 LastSeg:1;
u8 FirstSeg:1;
u8 LINIP:1;
u8 OWN:1;
u8 TxFWInfoSize;
u8 RATid:3;
u8 DISFB:1;
u8 USERATE:1;
u8 MOREFRAG:1;
u8 NoEnc:1;
u8 PIFS:1;
u8 QueueSelect:5;
u8 NoACM:1;
u8 Resv:2;
u8 SecCAMID:5;
u8 SecDescAssign:1;
u8 SecType:2;
u16 TxBufferSize;
u8 PktId:7;
u8 Resv1:1;
u8 Reserved2;
u32 TxBuffAddr;
u32 NextDescAddress;
u32 Reserved5;
u32 Reserved6;
u32 Reserved7;
}tx_desc, *ptx_desc;
typedef struct _tx_desc_cmd_819x_pci {
u16 PktSize;
u8 Reserved1;
u8 CmdType:3;
u8 CmdInit:1;
u8 LastSeg:1;
u8 FirstSeg:1;
u8 LINIP:1;
u8 OWN:1;
u16 ElementReport;
u16 Reserved2;
u16 TxBufferSize;
u16 Reserved3;
u32 TxBuffAddr;
u32 NextDescAddress;
u32 Reserved4;
u32 Reserved5;
u32 Reserved6;
}tx_desc_cmd, *ptx_desc_cmd;
typedef struct _rx_desc_819x_pci{
u16 Length:14;
u16 CRC32:1;
u16 ICV:1;
u8 RxDrvInfoSize;
u8 Shift:2;
u8 PHYStatus:1;
u8 SWDec:1;
u8 LastSeg:1;
u8 FirstSeg:1;
u8 EOR:1;
u8 OWN:1;
u32 Reserved2;
u32 Reserved3;
u32 BufferAddress;
}rx_desc, *prx_desc;
typedef struct _rx_fwinfo_819x_pci{
u16 Reserved1:12;
u16 PartAggr:1;
u16 FirstAGGR:1;
u16 Reserved2:2;
u8 RxRate:7;
u8 RxHT:1;
u8 BW:1;
u8 SPLCP:1;
u8 Reserved3:2;
u8 PAM:1;
u8 Mcast:1;
u8 Bcast:1;
u8 Reserved4:1;
u32 TSFL;
}rx_fwinfo, *prx_fwinfo;
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,51 @@
/******************************************************************************
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
******************************************************************************/
#ifndef __INC_HAL8190Pci_FW_IMG_H
#define __INC_HAL8190Pci_FW_IMG_H
/*Created on 2008/12/ 3, 3:26*/
#include <linux/types.h>
#define BootArrayLengthPci 344
extern u8 Rtl8190PciFwBootArray[BootArrayLengthPci];
#define MainArrayLengthPci 55388
extern u8 Rtl8190PciFwMainArray[MainArrayLengthPci];
#define DataArrayLengthPci 2960
extern u8 Rtl8190PciFwDataArray[DataArrayLengthPci];
#define PHY_REGArrayLengthPci 280
extern u32 Rtl8190PciPHY_REGArray[PHY_REGArrayLengthPci];
#define PHY_REG_1T2RArrayLengthPci 280
extern u32 Rtl8190PciPHY_REG_1T2RArray[PHY_REG_1T2RArrayLengthPci];
#define RadioA_ArrayLengthPci 246
extern u32 Rtl8190PciRadioA_Array[RadioA_ArrayLengthPci] ;
#define RadioB_ArrayLengthPci 78
extern u32 Rtl8190PciRadioB_Array[RadioB_ArrayLengthPci] ;
#define RadioC_ArrayLengthPci 246
extern u32 Rtl8190PciRadioC_Array[RadioC_ArrayLengthPci] ;
#define RadioD_ArrayLengthPci 78
extern u32 Rtl8190PciRadioD_Array[RadioD_ArrayLengthPci] ;
#define MACPHY_ArrayLengthPci 18
extern u32 Rtl8190PciMACPHY_Array[MACPHY_ArrayLengthPci] ;
#define MACPHY_Array_PGLengthPci 21
extern u32 Rtl8190PciMACPHY_Array_PG[MACPHY_Array_PGLengthPci] ;
#define AGCTAB_ArrayLengthPci 384
extern u32 Rtl8190PciAGCTAB_Array[AGCTAB_ArrayLengthPci] ;
#endif

View file

@ -0,0 +1,366 @@
/******************************************************************************
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
******************************************************************************/
#include "rtl_core.h"
#ifdef RTL8192SE
#include "rtl8192s/r8192S_phyreg.h"
#include "rtl8192s/r8192S_phy.h"
#else
#include "r8192E_phyreg.h"
#include "r8192E_phy.h"
#endif
#include "r8190P_rtl8256.h"
void PHY_SetRF8256Bandwidth(struct net_device* dev , HT_CHANNEL_WIDTH Bandwidth)
{
u8 eRFPath;
struct r8192_priv *priv = rtllib_priv(dev);
for (eRFPath = 0; eRFPath <priv->NumTotalRFPath; eRFPath++) {
if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath))
continue;
switch (Bandwidth) {
case HT_CHANNEL_WIDTH_20:
if (priv->card_8192_version == VERSION_8190_BD || priv->card_8192_version == VERSION_8190_BE) {
rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0b, bMask12Bits, 0x100);
rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x2c, bMask12Bits, 0x3d7);
rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0e, bMask12Bits, 0x021);
} else {
RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown hardware version\n");
}
break;
case HT_CHANNEL_WIDTH_20_40:
if (priv->card_8192_version == VERSION_8190_BD ||priv->card_8192_version == VERSION_8190_BE) {
rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0b, bMask12Bits, 0x300);
rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x2c, bMask12Bits, 0x3ff);
rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0e, bMask12Bits, 0x0e1);
} else {
RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown hardware version\n");
}
break;
default:
RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown Bandwidth: %#X\n",Bandwidth );
break;
}
}
return;
}
bool PHY_RF8256_Config(struct net_device* dev)
{
struct r8192_priv *priv = rtllib_priv(dev);
bool rtStatus = true;
priv->NumTotalRFPath = RTL819X_TOTAL_RF_PATH;
rtStatus = phy_RF8256_Config_ParaFile(dev);
return rtStatus;
}
bool phy_RF8256_Config_ParaFile(struct net_device* dev)
{
u32 u4RegValue = 0;
u8 eRFPath;
bool rtStatus = true;
BB_REGISTER_DEFINITION_T *pPhyReg;
struct r8192_priv *priv = rtllib_priv(dev);
u32 RegOffSetToBeCheck = 0x3;
u32 RegValueToBeCheck = 0x7f1;
u32 RF3_Final_Value = 0;
u8 ConstRetryTimes = 5, RetryTimes = 5;
u8 ret = 0;
for (eRFPath = (RF90_RADIO_PATH_E)RF90_PATH_A; eRFPath <priv->NumTotalRFPath; eRFPath++) {
if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath))
continue;
pPhyReg = &priv->PHYRegDef[eRFPath];
switch (eRFPath) {
case RF90_PATH_A:
case RF90_PATH_C:
u4RegValue = rtl8192_QueryBBReg(dev, pPhyReg->rfintfs, bRFSI_RFENV);
break;
case RF90_PATH_B :
case RF90_PATH_D:
u4RegValue = rtl8192_QueryBBReg(dev, pPhyReg->rfintfs, bRFSI_RFENV<<16);
break;
}
rtl8192_setBBreg(dev, pPhyReg->rfintfe, bRFSI_RFENV<<16, 0x1);
rtl8192_setBBreg(dev, pPhyReg->rfintfo, bRFSI_RFENV, 0x1);
rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, b3WireAddressLength, 0x0);
rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, b3WireDataLength, 0x0);
rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E) eRFPath, 0x0, bMask12Bits, 0xbf);
rtStatus = rtl8192_phy_checkBBAndRF(dev, HW90_BLOCK_RF, (RF90_RADIO_PATH_E)eRFPath);
if (rtStatus!= true) {
RT_TRACE(COMP_ERR, "PHY_RF8256_Config():Check Radio[%d] Fail!!\n", eRFPath);
goto phy_RF8256_Config_ParaFile_Fail;
}
RetryTimes = ConstRetryTimes;
RF3_Final_Value = 0;
switch (eRFPath) {
case RF90_PATH_A:
while (RF3_Final_Value!=RegValueToBeCheck && RetryTimes != 0) {
ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits);
RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value);
RetryTimes--;
}
break;
case RF90_PATH_B:
while (RF3_Final_Value!=RegValueToBeCheck && RetryTimes != 0) {
ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits);
RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value);
RetryTimes--;
}
break;
case RF90_PATH_C:
while (RF3_Final_Value!=RegValueToBeCheck && RetryTimes != 0) {
ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits);
RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value);
RetryTimes--;
}
break;
case RF90_PATH_D:
while (RF3_Final_Value!=RegValueToBeCheck && RetryTimes != 0) {
ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits);
RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value);
RetryTimes--;
}
break;
}
switch (eRFPath) {
case RF90_PATH_A:
case RF90_PATH_C:
rtl8192_setBBreg(dev, pPhyReg->rfintfs, bRFSI_RFENV, u4RegValue);
break;
case RF90_PATH_B :
case RF90_PATH_D:
rtl8192_setBBreg(dev, pPhyReg->rfintfs, bRFSI_RFENV<<16, u4RegValue);
break;
}
if (ret) {
RT_TRACE(COMP_ERR, "phy_RF8256_Config_ParaFile():Radio[%d] Fail!!", eRFPath);
goto phy_RF8256_Config_ParaFile_Fail;
}
}
RT_TRACE(COMP_PHY, "PHY Initialization Success\n") ;
return true;
phy_RF8256_Config_ParaFile_Fail:
RT_TRACE(COMP_ERR, "PHY Initialization failed\n") ;
return false;
}
#ifndef RTL8192SE
void PHY_SetRF8256CCKTxPower(struct net_device* dev, u8 powerlevel)
{
u32 TxAGC=0;
struct r8192_priv *priv = rtllib_priv(dev);
#ifdef RTL8190P
u8 byte0, byte1;
TxAGC |= ((powerlevel<<8)|powerlevel);
TxAGC += priv->CCKTxPowerLevelOriginalOffset;
if (priv->bDynamicTxLowPower == true
/*pMgntInfo->bScanInProgress == true*/ )
{
if (priv->CustomerID == RT_CID_819x_Netcore)
TxAGC = 0x2222;
else
TxAGC += ((priv->CckPwEnl<<8)|priv->CckPwEnl);
}
byte0 = (u8)(TxAGC & 0xff);
byte1 = (u8)((TxAGC & 0xff00)>>8);
if (byte0 > 0x24)
byte0 = 0x24;
if (byte1 > 0x24)
byte1 = 0x24;
if (priv->rf_type == RF_2T4R)
{
if (priv->RF_C_TxPwDiff > 0)
{
if ( (byte0 + (u8)priv->RF_C_TxPwDiff) > 0x24)
byte0 = 0x24 - priv->RF_C_TxPwDiff;
if ( (byte1 + (u8)priv->RF_C_TxPwDiff) > 0x24)
byte1 = 0x24 - priv->RF_C_TxPwDiff;
}
}
TxAGC = (byte1<<8) |byte0;
write_nic_dword(dev, CCK_TXAGC, TxAGC);
#else
#ifdef RTL8192E
TxAGC = powerlevel;
if (priv->bDynamicTxLowPower == true)
{
if (priv->CustomerID == RT_CID_819x_Netcore)
TxAGC = 0x22;
else
TxAGC += priv->CckPwEnl;
}
if (TxAGC > 0x24)
TxAGC = 0x24;
rtl8192_setBBreg(dev, rTxAGC_CCK_Mcs32, bTxAGCRateCCK, TxAGC);
#endif
#endif
}
void PHY_SetRF8256OFDMTxPower(struct net_device* dev, u8 powerlevel)
{
struct r8192_priv *priv = rtllib_priv(dev);
#ifdef RTL8190P
u32 TxAGC1=0, TxAGC2=0, TxAGC2_tmp = 0;
u8 i, byteVal1[4], byteVal2[4], byteVal3[4];
if (priv->bDynamicTxHighPower == true)
{
TxAGC1 |= ((powerlevel<<24)|(powerlevel<<16)|(powerlevel<<8)|powerlevel);
TxAGC2_tmp = TxAGC1;
TxAGC1 += priv->MCSTxPowerLevelOriginalOffset[0];
TxAGC2 =0x03030303;
TxAGC2_tmp += priv->MCSTxPowerLevelOriginalOffset[1];
}
else
{
TxAGC1 |= ((powerlevel<<24)|(powerlevel<<16)|(powerlevel<<8)|powerlevel);
TxAGC2 = TxAGC1;
TxAGC1 += priv->MCSTxPowerLevelOriginalOffset[0];
TxAGC2 += priv->MCSTxPowerLevelOriginalOffset[1];
TxAGC2_tmp = TxAGC2;
}
for (i=0; i<4; i++)
{
byteVal1[i] = (u8)( (TxAGC1 & (0xff<<(i*8))) >>(i*8) );
if (byteVal1[i] > 0x24)
byteVal1[i] = 0x24;
byteVal2[i] = (u8)( (TxAGC2 & (0xff<<(i*8))) >>(i*8) );
if (byteVal2[i] > 0x24)
byteVal2[i] = 0x24;
byteVal3[i] = (u8)( (TxAGC2_tmp & (0xff<<(i*8))) >>(i*8) );
if (byteVal3[i] > 0x24)
byteVal3[i] = 0x24;
}
if (priv->rf_type == RF_2T4R)
{
if (priv->RF_C_TxPwDiff > 0)
{
for (i=0; i<4; i++)
{
if ( (byteVal1[i] + (u8)priv->RF_C_TxPwDiff) > 0x24)
byteVal1[i] = 0x24 - priv->RF_C_TxPwDiff;
if ( (byteVal2[i] + (u8)priv->RF_C_TxPwDiff) > 0x24)
byteVal2[i] = 0x24 - priv->RF_C_TxPwDiff;
if ( (byteVal3[i] + (u8)priv->RF_C_TxPwDiff) > 0x24)
byteVal3[i] = 0x24 - priv->RF_C_TxPwDiff;
}
}
}
TxAGC1 = (byteVal1[3]<<24) | (byteVal1[2]<<16) |(byteVal1[1]<<8) |byteVal1[0];
TxAGC2 = (byteVal2[3]<<24) | (byteVal2[2]<<16) |(byteVal2[1]<<8) |byteVal2[0];
TxAGC2_tmp = (byteVal3[3]<<24) | (byteVal3[2]<<16) |(byteVal3[1]<<8) |byteVal3[0];
priv->Pwr_Track = TxAGC2_tmp;
write_nic_dword(dev, MCS_TXAGC, TxAGC1);
write_nic_dword(dev, MCS_TXAGC+4, TxAGC2);
#else
#ifdef RTL8192E
u32 writeVal, powerBase0, powerBase1, writeVal_tmp;
u8 index = 0;
u16 RegOffset[6] = {0xe00, 0xe04, 0xe10, 0xe14, 0xe18, 0xe1c};
u8 byte0, byte1, byte2, byte3;
powerBase0 = powerlevel + priv->LegacyHTTxPowerDiff;
powerBase0 = (powerBase0<<24) | (powerBase0<<16) |(powerBase0<<8) |powerBase0;
powerBase1 = powerlevel;
powerBase1 = (powerBase1<<24) | (powerBase1<<16) |(powerBase1<<8) |powerBase1;
for (index=0; index<6; index++)
{
writeVal = (u32)(priv->MCSTxPowerLevelOriginalOffset[index] + ((index<2)?powerBase0:powerBase1));
byte0 = (u8)(writeVal & 0x7f);
byte1 = (u8)((writeVal & 0x7f00)>>8);
byte2 = (u8)((writeVal & 0x7f0000)>>16);
byte3 = (u8)((writeVal & 0x7f000000)>>24);
if (byte0 > 0x24)
byte0 = 0x24;
if (byte1 > 0x24)
byte1 = 0x24;
if (byte2 > 0x24)
byte2 = 0x24;
if (byte3 > 0x24)
byte3 = 0x24;
if (index == 3)
{
writeVal_tmp = (byte3<<24) | (byte2<<16) |(byte1<<8) |byte0;
priv->Pwr_Track = writeVal_tmp;
}
if (priv->bDynamicTxHighPower == true)
{
writeVal = 0x03030303;
}
else
{
writeVal = (byte3<<24) | (byte2<<16) |(byte1<<8) |byte0;
}
rtl8192_setBBreg(dev, RegOffset[index], 0x7f7f7f7f, writeVal);
}
#endif
#endif
return;
}
#endif

View file

@ -0,0 +1,34 @@
/******************************************************************************
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
******************************************************************************/
#ifndef RTL8225H
#define RTL8225H
#ifdef RTL8190P
#define RTL819X_TOTAL_RF_PATH 4
#else
#define RTL819X_TOTAL_RF_PATH 2
#endif
extern void PHY_SetRF8256Bandwidth(struct net_device* dev , HT_CHANNEL_WIDTH Bandwidth);
extern bool PHY_RF8256_Config(struct net_device* dev);
extern bool phy_RF8256_Config_ParaFile(struct net_device* dev);
extern void PHY_SetRF8256CCKTxPower(struct net_device* dev, u8 powerlevel);
extern void PHY_SetRF8256OFDMTxPower(struct net_device* dev, u8 powerlevel);
#endif

View file

@ -0,0 +1,478 @@
/******************************************************************************
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
******************************************************************************/
#if (defined(RTL8192E) || defined(RTL8190P))
#include "rtl_core.h"
#include "r8192E_hw.h"
#include "r8192E_cmdpkt.h"
/*---------------------------Define Local Constant---------------------------*/
/* Debug constant*/
#define CMPK_DEBOUNCE_CNT 1
#define CMPK_PRINT(Address)\
{\
unsigned char i;\
u32 temp[10];\
\
memcpy(temp, Address, 40);\
for (i = 0; i <40; i+=4)\
printk("\r\n %08x", temp[i]);\
}\
/*---------------------------Define functions---------------------------------*/
extern bool cmpk_message_handle_tx(
struct net_device *dev,
u8* code_virtual_address,
u32 packettype,
u32 buffer_len)
{
bool rt_status = true;
struct r8192_priv *priv = rtllib_priv(dev);
u16 frag_threshold;
u16 frag_length = 0, frag_offset = 0;
rt_firmware *pfirmware = priv->pFirmware;
struct sk_buff *skb;
unsigned char *seg_ptr;
cb_desc *tcb_desc;
u8 bLastIniPkt;
PTX_FWINFO_8190PCI pTxFwInfo = NULL;
RT_TRACE(COMP_CMDPKT,"%s(),buffer_len is %d\n",__func__,buffer_len);
firmware_init_param(dev);
frag_threshold = pfirmware->cmdpacket_frag_thresold;
do {
if ((buffer_len - frag_offset) > frag_threshold) {
frag_length = frag_threshold ;
bLastIniPkt = 0;
} else {
frag_length =(u16)(buffer_len - frag_offset);
bLastIniPkt = 1;
}
skb = dev_alloc_skb(frag_length + priv->rtllib->tx_headroom + 4);
if (skb == NULL) {
rt_status = false;
goto Failed;
}
memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
tcb_desc = (cb_desc*)(skb->cb + MAX_DEV_ADDR_SIZE);
tcb_desc->queue_index = TXCMD_QUEUE;
tcb_desc->bCmdOrInit = DESC_PACKET_TYPE_NORMAL;
tcb_desc->bLastIniPkt = bLastIniPkt;
tcb_desc->pkt_size = frag_length;
seg_ptr = skb_put(skb, priv->rtllib->tx_headroom);
pTxFwInfo = (PTX_FWINFO_8190PCI)seg_ptr;
memset(pTxFwInfo,0,sizeof(TX_FWINFO_8190PCI));
memset(pTxFwInfo,0x12,8);
seg_ptr = skb_put(skb, frag_length);
memcpy(seg_ptr, code_virtual_address, (u32)frag_length);
priv->rtllib->softmac_hard_start_xmit(skb,dev);
code_virtual_address += frag_length;
frag_offset += frag_length;
}while(frag_offset < buffer_len);
write_nic_byte(dev, TPPoll, TPPoll_CQ);
Failed:
return rt_status;
} /* CMPK_Message_Handle_Tx */
static void
cmpk_count_txstatistic(
struct net_device *dev,
cmpk_txfb_t *pstx_fb)
{
struct r8192_priv *priv = rtllib_priv(dev);
#ifdef ENABLE_PS
RT_RF_POWER_STATE rtState;
pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState));
if (rtState == eRfOff)
{
return;
}
#endif
#ifdef TODO
if (pAdapter->bInHctTest)
return;
#endif
if (pstx_fb->tok)
{
priv->stats.txfeedbackok++;
priv->stats.txoktotal++;
priv->stats.txokbytestotal += pstx_fb->pkt_length;
priv->stats.txokinperiod++;
if (pstx_fb->pkt_type == PACKET_MULTICAST)
{
priv->stats.txmulticast++;
priv->stats.txbytesmulticast += pstx_fb->pkt_length;
}
else if (pstx_fb->pkt_type == PACKET_BROADCAST)
{
priv->stats.txbroadcast++;
priv->stats.txbytesbroadcast += pstx_fb->pkt_length;
}
else
{
priv->stats.txunicast++;
priv->stats.txbytesunicast += pstx_fb->pkt_length;
}
}
else
{
priv->stats.txfeedbackfail++;
priv->stats.txerrtotal++;
priv->stats.txerrbytestotal += pstx_fb->pkt_length;
if (pstx_fb->pkt_type == PACKET_MULTICAST)
{
priv->stats.txerrmulticast++;
}
else if (pstx_fb->pkt_type == PACKET_BROADCAST)
{
priv->stats.txerrbroadcast++;
}
else
{
priv->stats.txerrunicast++;
}
}
priv->stats.txretrycount += pstx_fb->retry_cnt;
priv->stats.txfeedbackretry += pstx_fb->retry_cnt;
} /* cmpk_CountTxStatistic */
static void
cmpk_handle_tx_feedback(
struct net_device *dev,
u8 * pmsg)
{
struct r8192_priv *priv = rtllib_priv(dev);
cmpk_txfb_t rx_tx_fb; /* */
priv->stats.txfeedback++;
memcpy((u8*)&rx_tx_fb, pmsg, sizeof(cmpk_txfb_t));
cmpk_count_txstatistic(dev, &rx_tx_fb);
} /* cmpk_Handle_Tx_Feedback */
void
cmdpkt_beacontimerinterrupt_819xusb(
struct net_device *dev
)
{
struct r8192_priv *priv = rtllib_priv(dev);
u16 tx_rate;
{
if ((priv->rtllib->current_network.mode == IEEE_A) ||
(priv->rtllib->current_network.mode == IEEE_N_5G) ||
((priv->rtllib->current_network.mode == IEEE_N_24G) && (!priv->rtllib->pHTInfo->bCurSuppCCK)))
{
tx_rate = 60;
DMESG("send beacon frame tx rate is 6Mbpm\n");
}
else
{
tx_rate =10;
DMESG("send beacon frame tx rate is 1Mbpm\n");
}
}
}
static void
cmpk_handle_interrupt_status(
struct net_device *dev,
u8* pmsg)
{
cmpk_intr_sta_t rx_intr_status; /* */
struct r8192_priv *priv = rtllib_priv(dev);
DMESG("---> cmpk_Handle_Interrupt_Status()\n");
rx_intr_status.length = pmsg[1];
if (rx_intr_status.length != (sizeof(cmpk_intr_sta_t) - 2))
{
DMESG("cmpk_Handle_Interrupt_Status: wrong length!\n");
return;
}
if ( priv->rtllib->iw_mode == IW_MODE_ADHOC)
{
rx_intr_status.interrupt_status = *((u32 *)(pmsg + 4));
DMESG("interrupt status = 0x%x\n", rx_intr_status.interrupt_status);
if (rx_intr_status.interrupt_status & ISR_TxBcnOk)
{
priv->rtllib->bibsscoordinator = true;
priv->stats.txbeaconokint++;
}
else if (rx_intr_status.interrupt_status & ISR_TxBcnErr)
{
priv->rtllib->bibsscoordinator = false;
priv->stats.txbeaconerr++;
}
if (rx_intr_status.interrupt_status & ISR_BcnTimerIntr)
{
cmdpkt_beacontimerinterrupt_819xusb(dev);
}
}
DMESG("<---- cmpk_handle_interrupt_status()\n");
} /* cmpk_handle_interrupt_status */
static void
cmpk_handle_query_config_rx(
struct net_device *dev,
u8* pmsg)
{
cmpk_query_cfg_t rx_query_cfg; /* */
rx_query_cfg.cfg_action = (pmsg[4] & 0x80000000)>>31;
rx_query_cfg.cfg_type = (pmsg[4] & 0x60) >> 5;
rx_query_cfg.cfg_size = (pmsg[4] & 0x18) >> 3;
rx_query_cfg.cfg_page = (pmsg[6] & 0x0F) >> 0;
rx_query_cfg.cfg_offset = pmsg[7];
rx_query_cfg.value = (pmsg[8] << 24) | (pmsg[9] << 16) |
(pmsg[10] << 8) | (pmsg[11] << 0);
rx_query_cfg.mask = (pmsg[12] << 24) | (pmsg[13] << 16) |
(pmsg[14] << 8) | (pmsg[15] << 0);
} /* cmpk_Handle_Query_Config_Rx */
static void cmpk_count_tx_status( struct net_device *dev,
cmpk_tx_status_t *pstx_status)
{
struct r8192_priv *priv = rtllib_priv(dev);
#ifdef ENABLE_PS
RT_RF_POWER_STATE rtstate;
pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState));
if (rtState == eRfOff)
{
return;
}
#endif
priv->stats.txfeedbackok += pstx_status->txok;
priv->stats.txoktotal += pstx_status->txok;
priv->stats.txfeedbackfail += pstx_status->txfail;
priv->stats.txerrtotal += pstx_status->txfail;
priv->stats.txretrycount += pstx_status->txretry;
priv->stats.txfeedbackretry += pstx_status->txretry;
priv->stats.txmulticast += pstx_status->txmcok;
priv->stats.txbroadcast += pstx_status->txbcok;
priv->stats.txunicast += pstx_status->txucok;
priv->stats.txerrmulticast += pstx_status->txmcfail;
priv->stats.txerrbroadcast += pstx_status->txbcfail;
priv->stats.txerrunicast += pstx_status->txucfail;
priv->stats.txbytesmulticast += pstx_status->txmclength;
priv->stats.txbytesbroadcast += pstx_status->txbclength;
priv->stats.txbytesunicast += pstx_status->txuclength;
priv->stats.last_packet_rate = pstx_status->rate;
} /* cmpk_CountTxStatus */
static void
cmpk_handle_tx_status(
struct net_device *dev,
u8* pmsg)
{
cmpk_tx_status_t rx_tx_sts; /* */
memcpy((void*)&rx_tx_sts, (void*)pmsg, sizeof(cmpk_tx_status_t));
cmpk_count_tx_status(dev, &rx_tx_sts);
}
static void
cmpk_handle_tx_rate_history(
struct net_device *dev,
u8* pmsg)
{
cmpk_tx_rahis_t *ptxrate;
u8 i, j;
u16 length = sizeof(cmpk_tx_rahis_t);
u32 *ptemp;
struct r8192_priv *priv = rtllib_priv(dev);
#ifdef ENABLE_PS
pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState));
if (rtState == eRfOff)
{
return;
}
#endif
ptemp = (u32 *)pmsg;
for (i = 0; i < (length/4); i++)
{
u16 temp1, temp2;
temp1 = ptemp[i]&0x0000FFFF;
temp2 = ptemp[i]>>16;
ptemp[i] = (temp1<<16)|temp2;
}
ptxrate = (cmpk_tx_rahis_t *)pmsg;
if (ptxrate == NULL )
{
return;
}
for (i = 0; i < 16; i++)
{
if (i < 4)
priv->stats.txrate.cck[i] += ptxrate->cck[i];
if (i< 8)
priv->stats.txrate.ofdm[i] += ptxrate->ofdm[i];
for (j = 0; j < 4; j++)
priv->stats.txrate.ht_mcs[j][i] += ptxrate->ht_mcs[j][i];
}
}
extern u32
cmpk_message_handle_rx(
struct net_device *dev,
struct rtllib_rx_stats *pstats)
{
struct r8192_priv *priv = rtllib_priv(dev);
int total_length;
u8 cmd_length, exe_cnt = 0;
u8 element_id;
u8 *pcmd_buff;
RT_TRACE(COMP_CMDPKT, "---->cmpk_message_handle_rx()\n");
if (/*(prfd->queue_id != CMPK_RX_QUEUE_ID) || */(pstats== NULL))
{
/* Print error message. */
/*RT_TRACE(COMP_SEND, DebugLevel,
("\n\r[CMPK]-->Err queue id or pointer"));*/
return 0;
}
total_length = pstats->Length;
pcmd_buff = pstats->virtual_address;
element_id = pcmd_buff[0];
while (total_length > 0 || exe_cnt++ >100)
{
element_id = pcmd_buff[0];
switch (element_id) {
case RX_TX_FEEDBACK:
RT_TRACE(COMP_CMDPKT, "---->cmpk_message_handle_rx():RX_TX_FEEDBACK\n");
cmpk_handle_tx_feedback (dev, pcmd_buff);
cmd_length = CMPK_RX_TX_FB_SIZE;
break;
case RX_INTERRUPT_STATUS:
RT_TRACE(COMP_CMDPKT, "---->cmpk_message_handle_rx():RX_INTERRUPT_STATUS\n");
cmpk_handle_interrupt_status(dev, pcmd_buff);
cmd_length = sizeof(cmpk_intr_sta_t);
break;
case BOTH_QUERY_CONFIG:
RT_TRACE(COMP_CMDPKT, "---->cmpk_message_handle_rx():BOTH_QUERY_CONFIG\n");
cmpk_handle_query_config_rx(dev, pcmd_buff);
cmd_length = CMPK_BOTH_QUERY_CONFIG_SIZE;
break;
case RX_TX_STATUS:
RT_TRACE(COMP_CMDPKT, "---->cmpk_message_handle_rx():RX_TX_STATUS\n");
cmpk_handle_tx_status(dev, pcmd_buff);
cmd_length = CMPK_RX_TX_STS_SIZE;
break;
case RX_TX_PER_PKT_FEEDBACK:
RT_TRACE(COMP_CMDPKT, "---->cmpk_message_handle_rx():RX_TX_PER_PKT_FEEDBACK\n");
cmd_length = CMPK_RX_TX_FB_SIZE;
break;
case RX_TX_RATE_HISTORY:
RT_TRACE(COMP_CMDPKT, "---->cmpk_message_handle_rx():RX_TX_HISTORY\n");
cmpk_handle_tx_rate_history(dev, pcmd_buff);
cmd_length = CMPK_TX_RAHIS_SIZE;
break;
default:
RT_TRACE(COMP_CMDPKT, "---->cmpk_message_handle_rx():unknow CMD Element\n");
return 1;
}
priv->stats.rxcmdpkt[element_id]++;
total_length -= cmd_length;
pcmd_buff += cmd_length;
}
return 1;
RT_TRACE(COMP_CMDPKT, "<----cmpk_message_handle_rx()\n");
}
#endif

View file

@ -0,0 +1,163 @@
/******************************************************************************
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
******************************************************************************/
#ifndef R819XUSB_CMDPKT_H
#define R819XUSB_CMDPKT_H
#define CMPK_RX_TX_FB_SIZE sizeof(cmpk_txfb_t)
#define CMPK_TX_SET_CONFIG_SIZE sizeof(cmpk_set_cfg_t)
#define CMPK_BOTH_QUERY_CONFIG_SIZE sizeof(cmpk_set_cfg_t)
#define CMPK_RX_TX_STS_SIZE sizeof(cmpk_tx_status_t)
#define CMPK_RX_DBG_MSG_SIZE sizeof(cmpk_rx_dbginfo_t)
#define CMPK_TX_RAHIS_SIZE sizeof(cmpk_tx_rahis_t)
#define ISR_TxBcnOk BIT27
#define ISR_TxBcnErr BIT26
#define ISR_BcnTimerIntr BIT13
typedef struct tag_cmd_pkt_tx_feedback
{
u8 element_id;
u8 length;
u8 TID:4; /* */
u8 fail_reason:3; /* */
u8 tok:1;
u8 reserve1:4; /* */
u8 pkt_type:2; /* */
u8 bandwidth:1; /* */
u8 qos_pkt:1; /* */
u8 reserve2; /* */
u8 retry_cnt; /* */
u16 pkt_id; /* */
u16 seq_num; /* */
u8 s_rate;
u8 f_rate;
u8 s_rts_rate; /* */
u8 f_rts_rate; /* */
u16 pkt_length; /* */
u16 reserve3; /* */
u16 duration; /* */
}cmpk_txfb_t;
typedef struct tag_cmd_pkt_interrupt_status
{
u8 element_id;
u8 length;
u16 reserve;
u32 interrupt_status;
}cmpk_intr_sta_t;
typedef struct tag_cmd_pkt_set_configuration
{
u8 element_id;
u8 length;
u16 reserve1;
u8 cfg_reserve1:3;
u8 cfg_size:2;
u8 cfg_type:2;
u8 cfg_action:1;
u8 cfg_reserve2;
u8 cfg_page:4;
u8 cfg_reserve3:4;
u8 cfg_offset;
u32 value;
u32 mask;
}cmpk_set_cfg_t;
#define cmpk_query_cfg_t cmpk_set_cfg_t
typedef struct tag_tx_stats_feedback
{
u16 reserve1;
u8 length;
u8 element_id;
u16 txfail;
u16 txok;
u16 txmcok;
u16 txretry;
u16 txucok;
u16 txbcok;
u16 txbcfail;
u16 txmcfail;
u16 reserve2;
u16 txucfail;
u32 txmclength;
u32 txbclength;
u32 txuclength;
u16 reserve3_23;
u8 reserve3_1;
u8 rate;
}__attribute__((packed)) cmpk_tx_status_t;
typedef struct tag_rx_debug_message_feedback
{
u16 reserve1;
u8 length;
u8 element_id;
}cmpk_rx_dbginfo_t;
typedef struct tag_tx_rate_history
{
u8 element_id;
u8 length;
u16 reserved1;
u16 cck[4];
u16 ofdm[8];
u16 ht_mcs[4][16];
}__attribute__((packed)) cmpk_tx_rahis_t;
typedef enum tag_command_packet_directories
{
RX_TX_FEEDBACK = 0,
RX_INTERRUPT_STATUS = 1,
TX_SET_CONFIG = 2,
BOTH_QUERY_CONFIG = 3,
RX_TX_STATUS = 4,
RX_DBGINFO_FEEDBACK = 5,
RX_TX_PER_PKT_FEEDBACK = 6,
RX_TX_RATE_HISTORY = 7,
RX_CMD_ELE_MAX
}cmpk_element_e;
extern u32 cmpk_message_handle_rx(struct net_device *dev, struct rtllib_rx_stats * pstats);
extern bool cmpk_message_handle_tx(struct net_device *dev, u8* codevirtualaddress, u32 packettype, u32 buffer_len);
#endif

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,56 @@
/******************************************************************************
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Based on the r8180 driver, which is:
* Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al.
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
******************************************************************************/
#ifndef _RTL8192E_H
#define _RTL8192E_H
#include "r8190P_def.h"
u8 rtl8192_QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc);
bool rtl8192_GetHalfNmodeSupportByAPs(struct net_device* dev);
bool rtl8192_GetNmodeSupportBySecCfg(struct net_device *dev);
bool rtl8192_HalTxCheckStuck(struct net_device *dev);
bool rtl8192_HalRxCheckStuck(struct net_device *dev);
void rtl8192_interrupt_recognized(struct net_device *dev, u32 *p_inta, u32 *p_intb);
void rtl8192_enable_rx(struct net_device *dev);
void rtl8192_enable_tx(struct net_device *dev);
void rtl8192_EnableInterrupt(struct net_device *dev);
void rtl8192_DisableInterrupt(struct net_device *dev);
void rtl8192_ClearInterrupt(struct net_device *dev);
void rtl8192_InitializeVariables(struct net_device *dev);
void rtl8192e_start_beacon(struct net_device *dev);
void rtl8192e_SetHwReg(struct net_device *dev,u8 variable,u8* val);
void rtl8192_get_eeprom_size(struct net_device* dev);
bool rtl8192_adapter_start(struct net_device *dev);
void rtl8192_link_change(struct net_device *dev);
void rtl8192_AllowAllDestAddr(struct net_device* dev, bool bAllowAllDA, bool WriteIntoReg);
void rtl8192_tx_fill_desc(struct net_device* dev, tx_desc * pdesc, cb_desc * cb_desc,
struct sk_buff* skb);
void rtl8192_tx_fill_cmd_desc(struct net_device* dev, tx_desc_cmd * entry,
cb_desc * cb_desc, struct sk_buff* skb);
bool rtl8192_rx_query_status_desc(struct net_device* dev, struct rtllib_rx_stats *stats,
rx_desc *pdesc, struct sk_buff* skb);
void rtl8192_halt_adapter(struct net_device *dev, bool reset);
void rtl8192_update_ratr_table(struct net_device* dev);
#endif

View file

@ -0,0 +1,396 @@
/******************************************************************************
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
******************************************************************************/
#if (defined(RTL8192E) || defined(RTL8190P))
#include "rtl_core.h"
#include "r8192E_hw.h"
#ifdef RTL8190P
#include "r8190P_hwimg.h"
#elif defined RTL8192E
#include "r8192E_hwimg.h"
#endif
#include "r8192E_firmware.h"
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
#include <linux/firmware.h>
#endif
extern void firmware_init_param(struct net_device *dev)
{
struct r8192_priv *priv = rtllib_priv(dev);
rt_firmware *pfirmware = priv->pFirmware;
pfirmware->cmdpacket_frag_thresold = GET_COMMAND_PACKET_FRAG_THRESHOLD(MAX_TRANSMIT_BUFFER_SIZE);
}
bool fw_download_code(struct net_device *dev, u8 *code_virtual_address, u32 buffer_len)
{
struct r8192_priv *priv = rtllib_priv(dev);
bool rt_status = true;
u16 frag_threshold;
u16 frag_length, frag_offset = 0;
int i;
rt_firmware *pfirmware = priv->pFirmware;
struct sk_buff *skb;
unsigned char *seg_ptr;
cb_desc *tcb_desc;
u8 bLastIniPkt;
firmware_init_param(dev);
frag_threshold = pfirmware->cmdpacket_frag_thresold;
do {
if ((buffer_len - frag_offset) > frag_threshold) {
frag_length = frag_threshold ;
bLastIniPkt = 0;
} else {
frag_length = buffer_len - frag_offset;
bLastIniPkt = 1;
}
skb = dev_alloc_skb(frag_length + 4);
memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
tcb_desc = (cb_desc*)(skb->cb + MAX_DEV_ADDR_SIZE);
tcb_desc->queue_index = TXCMD_QUEUE;
tcb_desc->bCmdOrInit = DESC_PACKET_TYPE_INIT;
tcb_desc->bLastIniPkt = bLastIniPkt;
seg_ptr = skb->data;
for (i=0 ; i < frag_length; i+=4) {
*seg_ptr++ = ((i+0)<frag_length)?code_virtual_address[i+3]:0;
*seg_ptr++ = ((i+1)<frag_length)?code_virtual_address[i+2]:0;
*seg_ptr++ = ((i+2)<frag_length)?code_virtual_address[i+1]:0;
*seg_ptr++ = ((i+3)<frag_length)?code_virtual_address[i+0]:0;
}
tcb_desc->txbuf_size= (u16)i;
skb_put(skb, i);
if (!priv->rtllib->check_nic_enough_desc(dev,tcb_desc->queue_index)||
(!skb_queue_empty(&priv->rtllib->skb_waitQ[tcb_desc->queue_index]))||\
(priv->rtllib->queue_stop) ) {
RT_TRACE(COMP_FIRMWARE, "===================> tx full!\n");
skb_queue_tail(&priv->rtllib->skb_waitQ[tcb_desc->queue_index], skb);
} else {
priv->rtllib->softmac_hard_start_xmit(skb,dev);
}
code_virtual_address += frag_length;
frag_offset += frag_length;
}while(frag_offset < buffer_len);
write_nic_byte(dev, TPPoll, TPPoll_CQ);
return rt_status;
}
bool
fwSendNullPacket(
struct net_device *dev,
u32 Length
)
{
bool rtStatus = true;
struct r8192_priv *priv = rtllib_priv(dev);
struct sk_buff *skb;
cb_desc *tcb_desc;
unsigned char *ptr_buf;
bool bLastInitPacket = false;
skb = dev_alloc_skb(Length+ 4);
memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
tcb_desc = (cb_desc*)(skb->cb + MAX_DEV_ADDR_SIZE);
tcb_desc->queue_index = TXCMD_QUEUE;
tcb_desc->bCmdOrInit = DESC_PACKET_TYPE_INIT;
tcb_desc->bLastIniPkt = bLastInitPacket;
ptr_buf = skb_put(skb, Length);
memset(ptr_buf,0,Length);
tcb_desc->txbuf_size= (u16)Length;
if (!priv->rtllib->check_nic_enough_desc(dev,tcb_desc->queue_index)||
(!skb_queue_empty(&priv->rtllib->skb_waitQ[tcb_desc->queue_index]))||\
(priv->rtllib->queue_stop) ) {
RT_TRACE(COMP_FIRMWARE,"===================NULL packet================> tx full!\n");
skb_queue_tail(&priv->rtllib->skb_waitQ[tcb_desc->queue_index], skb);
} else {
priv->rtllib->softmac_hard_start_xmit(skb,dev);
}
write_nic_byte(dev, TPPoll, TPPoll_CQ);
return rtStatus;
}
bool CPUcheck_maincodeok_turnonCPU(struct net_device *dev)
{
bool rt_status = true;
u32 CPU_status = 0;
unsigned long timeout;
timeout = jiffies + MSECS(200);
while (time_before(jiffies, timeout)) {
CPU_status = read_nic_dword(dev, CPU_GEN);
if (CPU_status & CPU_GEN_PUT_CODE_OK)
break;
msleep(2);
}
if (!(CPU_status&CPU_GEN_PUT_CODE_OK)) {
RT_TRACE(COMP_ERR, "Download Firmware: Put code fail!\n");
goto CPUCheckMainCodeOKAndTurnOnCPU_Fail;
} else {
RT_TRACE(COMP_FIRMWARE, "Download Firmware: Put code ok!\n");
}
CPU_status = read_nic_dword(dev, CPU_GEN);
write_nic_byte(dev, CPU_GEN, (u8)((CPU_status|CPU_GEN_PWR_STB_CPU)&0xff));
mdelay(1);
timeout = jiffies + MSECS(200);
while (time_before(jiffies, timeout)) {
CPU_status = read_nic_dword(dev, CPU_GEN);
if (CPU_status&CPU_GEN_BOOT_RDY)
break;
msleep(2);
}
if (!(CPU_status&CPU_GEN_BOOT_RDY)) {
goto CPUCheckMainCodeOKAndTurnOnCPU_Fail;
} else {
RT_TRACE(COMP_FIRMWARE, "Download Firmware: Boot ready!\n");
}
return rt_status;
CPUCheckMainCodeOKAndTurnOnCPU_Fail:
RT_TRACE(COMP_ERR, "ERR in %s()\n", __func__);
rt_status = false;
return rt_status;
}
bool CPUcheck_firmware_ready(struct net_device *dev)
{
bool rt_status = true;
u32 CPU_status = 0;
unsigned long timeout;
timeout = jiffies + MSECS(20);
while (time_before(jiffies, timeout)) {
CPU_status = read_nic_dword(dev, CPU_GEN);
if (CPU_status&CPU_GEN_FIRM_RDY)
break;
msleep(2);
}
if (!(CPU_status&CPU_GEN_FIRM_RDY))
goto CPUCheckFirmwareReady_Fail;
else
RT_TRACE(COMP_FIRMWARE, "Download Firmware: Firmware ready!\n");
return rt_status;
CPUCheckFirmwareReady_Fail:
RT_TRACE(COMP_ERR, "ERR in %s()\n", __func__);
rt_status = false;
return rt_status;
}
inline static bool firmware_check_ready(struct net_device *dev, u8 load_fw_status)
{
struct r8192_priv *priv = rtllib_priv(dev);
rt_firmware *pfirmware = priv->pFirmware;
bool rt_status = true;
switch (load_fw_status) {
case FW_INIT_STEP0_BOOT:
pfirmware->firmware_status = FW_STATUS_1_MOVE_BOOT_CODE;
#ifdef RTL8190P
rt_status = fwSendNullPacket(dev, RTL8190_CPU_START_OFFSET);
if (!rt_status) {
RT_TRACE(COMP_INIT, "fwSendNullPacket() fail ! \n");
}
#endif
break;
case FW_INIT_STEP1_MAIN:
pfirmware->firmware_status = FW_STATUS_2_MOVE_MAIN_CODE;
rt_status = CPUcheck_maincodeok_turnonCPU(dev);
if (rt_status) {
pfirmware->firmware_status = FW_STATUS_3_TURNON_CPU;
} else {
RT_TRACE(COMP_FIRMWARE, "CPUcheck_maincodeok_turnonCPU fail!\n");
}
break;
case FW_INIT_STEP2_DATA:
pfirmware->firmware_status = FW_STATUS_4_MOVE_DATA_CODE;
mdelay(1);
rt_status = CPUcheck_firmware_ready(dev);
if (rt_status) {
pfirmware->firmware_status = FW_STATUS_5_READY;
} else {
RT_TRACE(COMP_FIRMWARE, "CPUcheck_firmware_ready fail(%d)!\n",rt_status);
}
break;
default:
rt_status = false;
RT_TRACE(COMP_FIRMWARE, "Unknown firware status");
break;
}
return rt_status;
}
bool init_firmware(struct net_device *dev)
{
struct r8192_priv *priv = rtllib_priv(dev);
bool rt_status = true;
#ifdef RTL8190P
u8 *firmware_img_buf[3] = { &Rtl8190PciFwBootArray[0],
&Rtl8190PciFwMainArray[0],
&Rtl8190PciFwDataArray[0]};
u32 firmware_img_len[3] = { sizeof(Rtl8190PciFwBootArray),
sizeof(Rtl8190PciFwMainArray),
sizeof(Rtl8190PciFwDataArray)};
#else
u8 *firmware_img_buf[3] = { &Rtl8192PciEFwBootArray[0],
&Rtl8192PciEFwMainArray[0],
&Rtl8192PciEFwDataArray[0]};
u32 firmware_img_len[3] = { sizeof(Rtl8192PciEFwBootArray),
sizeof(Rtl8192PciEFwMainArray),
sizeof(Rtl8192PciEFwDataArray)};
#endif
u32 file_length = 0;
u8 *mapped_file = NULL;
u8 init_step = 0;
opt_rst_type_e rst_opt = OPT_SYSTEM_RESET;
firmware_init_step_e starting_state = FW_INIT_STEP0_BOOT;
rt_firmware *pfirmware = priv->pFirmware;
RT_TRACE(COMP_FIRMWARE, " PlatformInitFirmware()==>\n");
if (pfirmware->firmware_status == FW_STATUS_0_INIT ) {
rst_opt = OPT_SYSTEM_RESET;
starting_state = FW_INIT_STEP0_BOOT;
}else if (pfirmware->firmware_status == FW_STATUS_5_READY) {
rst_opt = OPT_FIRMWARE_RESET;
starting_state = FW_INIT_STEP2_DATA;
}else {
RT_TRACE(COMP_FIRMWARE, "PlatformInitFirmware: undefined firmware state\n");
}
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) && defined(USE_FW_SOURCE_IMG_FILE)
priv->firmware_source = FW_SOURCE_IMG_FILE;
#else
priv->firmware_source = FW_SOURCE_HEADER_FILE;
#endif
for (init_step = starting_state; init_step <= FW_INIT_STEP2_DATA; init_step++) {
if (rst_opt == OPT_SYSTEM_RESET) {
switch (priv->firmware_source) {
case FW_SOURCE_IMG_FILE:
{
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) && defined(USE_FW_SOURCE_IMG_FILE)
if (pfirmware->firmware_buf_size[init_step] == 0) {
const char *fw_name[3] = { "RTL8192E/boot.img",
"RTL8192E/main.img",
"RTL8192E/data.img"
};
const struct firmware *fw_entry;
int rc;
rc = request_firmware(&fw_entry, fw_name[init_step],&priv->pdev->dev);
if (rc < 0 ) {
RT_TRACE(COMP_FIRMWARE, "request firmware fail!\n");
goto download_firmware_fail;
}
if (fw_entry->size > sizeof(pfirmware->firmware_buf[init_step])) {
RT_TRACE(COMP_FIRMWARE, "img file size exceed the container buffer fail!\n");
goto download_firmware_fail;
}
if (init_step != FW_INIT_STEP1_MAIN) {
memcpy(pfirmware->firmware_buf[init_step],fw_entry->data,fw_entry->size);
pfirmware->firmware_buf_size[init_step] = fw_entry->size;
} else {
memset(pfirmware->firmware_buf[init_step],0,128);
memcpy(&pfirmware->firmware_buf[init_step][128],fw_entry->data,fw_entry->size);
pfirmware->firmware_buf_size[init_step] = fw_entry->size+128;
}
if (rst_opt == OPT_SYSTEM_RESET) {
release_firmware(fw_entry);
}
}
mapped_file = pfirmware->firmware_buf[init_step];
file_length = pfirmware->firmware_buf_size[init_step];
#endif
break;
}
case FW_SOURCE_HEADER_FILE:
mapped_file = firmware_img_buf[init_step];
file_length = firmware_img_len[init_step];
if (init_step == FW_INIT_STEP2_DATA) {
memcpy(pfirmware->firmware_buf[init_step], mapped_file, file_length);
pfirmware->firmware_buf_size[init_step] = file_length;
}
break;
default:
break;
}
} else if (rst_opt == OPT_FIRMWARE_RESET) {
mapped_file = pfirmware->firmware_buf[init_step];
file_length = pfirmware->firmware_buf_size[init_step];
}
rt_status = fw_download_code(dev,mapped_file,file_length);
if (rt_status != true) {
goto download_firmware_fail;
}
if (!firmware_check_ready(dev, init_step)) {
goto download_firmware_fail;
}
}
RT_TRACE(COMP_FIRMWARE, "Firmware Download Success\n");
return rt_status;
download_firmware_fail:
RT_TRACE(COMP_ERR, "ERR in %s()\n", __func__);
rt_status = false;
return rt_status;
}
#endif

View file

@ -0,0 +1,73 @@
/******************************************************************************
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
******************************************************************************/
#ifndef __INC_FIRMWARE_H
#define __INC_FIRMWARE_H
#define RTL8190_CPU_START_OFFSET 0x80
#define GET_COMMAND_PACKET_FRAG_THRESHOLD(v) (4*(v/4) - 8 )
typedef enum _firmware_init_step{
FW_INIT_STEP0_BOOT = 0,
FW_INIT_STEP1_MAIN = 1,
FW_INIT_STEP2_DATA = 2,
}firmware_init_step_e;
typedef enum _opt_rst_type{
OPT_SYSTEM_RESET = 0,
OPT_FIRMWARE_RESET = 1,
}opt_rst_type_e;
typedef enum _desc_packet_type_e{
DESC_PACKET_TYPE_INIT = 0,
DESC_PACKET_TYPE_NORMAL = 1,
}desc_packet_type_e;
typedef enum _firmware_source{
FW_SOURCE_IMG_FILE = 0,
FW_SOURCE_HEADER_FILE = 1,
}firmware_source_e, *pfirmware_source_e;
typedef enum _firmware_status{
FW_STATUS_0_INIT = 0,
FW_STATUS_1_MOVE_BOOT_CODE = 1,
FW_STATUS_2_MOVE_MAIN_CODE = 2,
FW_STATUS_3_TURNON_CPU = 3,
FW_STATUS_4_MOVE_DATA_CODE = 4,
FW_STATUS_5_READY = 5,
}firmware_status_e;
typedef struct _rt_firmare_seg_container {
u16 seg_size;
u8 *seg_ptr;
}fw_seg_container, *pfw_seg_container;
typedef struct _rt_firmware{
firmware_status_e firmware_status;
u16 cmdpacket_frag_thresold;
#define RTL8190_MAX_FIRMWARE_CODE_SIZE 64000
#define MAX_FW_INIT_STEP 3
u8 firmware_buf[MAX_FW_INIT_STEP][RTL8190_MAX_FIRMWARE_CODE_SIZE];
u16 firmware_buf_size[MAX_FW_INIT_STEP];
} rt_firmware, *prt_firmware;
bool init_firmware(struct net_device *dev);
extern void firmware_init_param(struct net_device *dev);
#endif

View file

@ -1,49 +1,36 @@
/*
This is part of rtl8187 OpenSource driver.
Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
Released under the terms of GPL (General Public Licence)
/******************************************************************************
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
******************************************************************************/
Parts of this driver are based on the GPL part of the
official Realtek driver.
Parts of this driver are based on the rtl8180 driver skeleton
from Patric Schenke & Andres Salomon.
Parts of this driver are based on the Intel Pro Wireless
2100 GPL driver.
We want to tanks the Authors of those projects
and the Ndiswrapper project Authors.
*/
/* Mariusz Matuszek added full registers definition with Realtek's name */
/* this file contains register definitions for the rtl8187 MAC controller */
#ifndef R8180_HW
#define R8180_HW
typedef enum _VERSION_8190{
VERSION_8190_BD=0x3,
VERSION_8190_BE
}VERSION_8190,*PVERSION_8190;
//added for different RF type
typedef enum _RT_RF_TYPE_DEF
{
RF_1T2R = 0,
RF_2T4R,
RF_819X_MAX_TYPE
}RT_RF_TYPE_DEF;
typedef enum _BaseBand_Config_Type{
BaseBand_Config_PHY_REG = 0, //Radio Path A
BaseBand_Config_AGC_TAB = 1, //Radio Path B
}BaseBand_Config_Type, *PBaseBand_Config_Type;
typedef enum _BaseBand_Config_Type {
BaseBand_Config_PHY_REG = 0,
BaseBand_Config_AGC_TAB = 1,
} BaseBand_Config_Type, *PBaseBand_Config_Type;
#define RTL8187_REQT_READ 0xc0
#define RTL8187_REQT_WRITE 0x40
#define RTL8187_REQ_GET_REGS 0x05
#define RTL8187_REQ_SET_REGS 0x05
#define R8180_MAX_RETRY 255
#define MAX_TX_URB 5
#define MAX_RX_URB 16
#define RX_URB_SIZE 9100
@ -65,14 +52,14 @@ typedef enum _BaseBand_Config_Type{
#define EEPROM_TxPowerDiff 0x1F
#define EEPROM_PwDiff 0x21 //0x21
#define EEPROM_CrystalCap 0x22 //0x22
#define EEPROM_PwDiff 0x21
#define EEPROM_CrystalCap 0x22
#define EEPROM_TxPwIndex_CCK_V1 0x29 //0x29~0x2B
#define EEPROM_TxPwIndex_OFDM_24G_V1 0x2C //0x2C~0x2E
#define EEPROM_TxPwIndex_Ver 0x27 //0x27
#define EEPROM_TxPwIndex_CCK_V1 0x29
#define EEPROM_TxPwIndex_OFDM_24G_V1 0x2C
#define EEPROM_TxPwIndex_Ver 0x27
#define EEPROM_Default_TxPowerDiff 0x0
#define EEPROM_Default_ThermalMeter 0x77
@ -81,31 +68,43 @@ typedef enum _BaseBand_Config_Type{
#define EEPROM_Default_PwDiff 0x4
#define EEPROM_Default_CrystalCap 0x5
#define EEPROM_Default_TxPower 0x1010
#define EEPROM_ICVersion_ChannelPlan 0x7C //0x7C:ChannelPlan, 0x7D:IC_Version
#define EEPROM_Customer_ID 0x7B //0x7B:CustomerID
#define EEPROM_ICVersion_ChannelPlan 0x7C
#define EEPROM_Customer_ID 0x7B
#ifdef RTL8190P
#define EEPROM_RFInd_PowerDiff 0x14
#define EEPROM_ThermalMeter 0x15
#define EEPROM_TxPwDiff_CrystalCap 0x16
#define EEPROM_TxPwIndex_CCK 0x18
#define EEPROM_TxPwIndex_OFDM_24G 0x26
#define EEPROM_TxPwIndex_OFDM_5G 0x34
#define EEPROM_C56_CrystalCap 0x17
#define EEPROM_C56_RfA_CCK_Chnl1_TxPwIndex 0x80
#define EEPROM_C56_RfA_HT_OFDM_TxPwIndex 0x81
#define EEPROM_C56_RfC_CCK_Chnl1_TxPwIndex 0xbc
#define EEPROM_C56_RfC_HT_OFDM_TxPwIndex 0xb9
#else
#ifdef RTL8192E
#define EEPROM_RFInd_PowerDiff 0x28
#define EEPROM_ThermalMeter 0x29
#define EEPROM_TxPwDiff_CrystalCap 0x2A //0x2A~0x2B
#define EEPROM_TxPwIndex_CCK 0x2C //0x23
#define EEPROM_TxPwIndex_OFDM_24G 0x3A //0x24~0x26
#define EEPROM_TxPwDiff_CrystalCap 0x2A
#define EEPROM_TxPwIndex_CCK 0x2C
#define EEPROM_TxPwIndex_OFDM_24G 0x3A
#endif
#endif
#define EEPROM_Default_TxPowerLevel 0x10
#define EEPROM_IC_VER 0x7d //0x7D
#define EEPROM_CRC 0x7e //0x7E~0x7F
#define EEPROM_IC_VER 0x7d
#define EEPROM_CRC 0x7e
#define EEPROM_CID_DEFAULT 0x0
#define EEPROM_CID_CAMEO 0x1
#define EEPROM_CID_RUNTOP 0x2
#define EEPROM_CID_Senao 0x3
#define EEPROM_CID_TOSHIBA 0x4 // Toshiba setting, Merge by Jacken, 2008/01/31
#define EEPROM_CID_TOSHIBA 0x4
#define EEPROM_CID_NetCore 0x5
#define EEPROM_CID_Nettronix 0x6
#define EEPROM_CID_Pronet 0x7
#define EEPROM_CID_DLINK 0x8
#define EEPROM_CID_WHQL 0xFE //added by sherry for dtm, 20080728
#define EEPROM_CID_WHQL 0xFE
enum _RTL8192Pci_HW {
MAC0 = 0x000,
MAC1 = 0x001,
@ -113,10 +112,7 @@ enum _RTL8192Pci_HW {
MAC3 = 0x003,
MAC4 = 0x004,
MAC5 = 0x005,
PCIF = 0x009, // PCI Function Register 0x0009h~0x000bh
//----------------------------------------------------------------------------
// 8190 PCIF bits (Offset 0x009-000b, 24bit)
//----------------------------------------------------------------------------
PCIF = 0x009,
#define MXDMA2_16bytes 0x000
#define MXDMA2_32bytes 0x001
#define MXDMA2_64bytes 0x010
@ -129,7 +125,7 @@ enum _RTL8192Pci_HW {
#define MULRW_SHIFT 3
#define MXDMA2_RX_SHIFT 4
#define MXDMA2_TX_SHIFT 0
PMR = 0x00c, // Power management register
PMR = 0x00c,
EPROM_CMD = 0x00e,
#define EPROM_CMD_RESERVED_MASK BIT5
#define EPROM_CMD_9356SEL BIT4
@ -151,71 +147,65 @@ enum _RTL8192Pci_HW {
ANAPAR = 0x17,
#define BB_GLOBAL_RESET_BIT 0x1
BB_GLOBAL_RESET = 0x020, // BasebandGlobal Reset Register
BSSIDR = 0x02E, // BSSID Register
CMDR = 0x037, // Command register
BB_GLOBAL_RESET = 0x020,
BSSIDR = 0x02E,
CMDR = 0x037,
#define CR_RST 0x10
#define CR_RE 0x08
#define CR_TE 0x04
#define CR_MulRW 0x01
SIFS = 0x03E, // SIFS register
TCR = 0x040, // Transmit Configuration Register
RCR = 0x044, // Receive Configuration Register
//----------------------------------------------------------------------------
//// 8190 (RCR) Receive Configuration Register (Offset 0x44~47, 32 bit)
////----------------------------------------------------------------------------
SIFS = 0x03E,
TCR = 0x040,
RCR = 0x044,
#define RCR_FILTER_MASK (BIT0|BIT1|BIT2|BIT3|BIT5|BIT12|BIT18|BIT19|BIT20|BIT21|BIT22|BIT23)
#define RCR_ONLYERLPKT BIT31 // Early Receiving based on Packet Size.
#define RCR_ENCS2 BIT30 // Enable Carrier Sense Detection Method 2
#define RCR_ENCS1 BIT29 // Enable Carrier Sense Detection Method 1
#define RCR_ENMBID BIT27 // Enable Multiple BssId.
#define RCR_ACKTXBW (BIT24|BIT25) // TXBW Setting of ACK frames
#define RCR_CBSSID BIT23 // Accept BSSID match packet
#define RCR_APWRMGT BIT22 // Accept power management packet
#define RCR_ADD3 BIT21 // Accept address 3 match packet
#define RCR_AMF BIT20 // Accept management type frame
#define RCR_ACF BIT19 // Accept control type frame
#define RCR_ADF BIT18 // Accept data type frame
#define RCR_RXFTH BIT13 // Rx FIFO Threshold
#define RCR_AICV BIT12 // Accept ICV error packet
#define RCR_ACRC32 BIT5 // Accept CRC32 error packet
#define RCR_AB BIT3 // Accept broadcast packet
#define RCR_AM BIT2 // Accept multicast packet
#define RCR_APM BIT1 // Accept physical match packet
#define RCR_AAP BIT0 // Accept all unicast packet
#define RCR_ONLYERLPKT BIT31
#define RCR_ENCS2 BIT30
#define RCR_ENCS1 BIT29
#define RCR_ENMBID BIT27
#define RCR_ACKTXBW (BIT24|BIT25)
#define RCR_CBSSID BIT23
#define RCR_APWRMGT BIT22
#define RCR_ADD3 BIT21
#define RCR_AMF BIT20
#define RCR_ACF BIT19
#define RCR_ADF BIT18
#define RCR_RXFTH BIT13
#define RCR_AICV BIT12
#define RCR_ACRC32 BIT5
#define RCR_AB BIT3
#define RCR_AM BIT2
#define RCR_APM BIT1
#define RCR_AAP BIT0
#define RCR_MXDMA_OFFSET 8
#define RCR_FIFO_OFFSET 13
SLOT_TIME = 0x049, // Slot Time Register
ACK_TIMEOUT = 0x04c, // Ack Timeout Register
PIFS_TIME = 0x04d, // PIFS time
USTIME = 0x04e, // Microsecond Tuning Register, Sets the microsecond time unit used by MAC clock.
EDCAPARA_BE = 0x050, // EDCA Parameter of AC BE
EDCAPARA_BK = 0x054, // EDCA Parameter of AC BK
EDCAPARA_VO = 0x058, // EDCA Parameter of AC VO
EDCAPARA_VI = 0x05C, // EDCA Parameter of AC VI
SLOT_TIME = 0x049,
ACK_TIMEOUT = 0x04c,
PIFS_TIME = 0x04d,
USTIME = 0x04e,
EDCAPARA_BE = 0x050,
EDCAPARA_BK = 0x054,
EDCAPARA_VO = 0x058,
EDCAPARA_VI = 0x05C,
#define AC_PARAM_TXOP_LIMIT_OFFSET 16
#define AC_PARAM_ECW_MAX_OFFSET 12
#define AC_PARAM_ECW_MIN_OFFSET 8
#define AC_PARAM_AIFS_OFFSET 0
RFPC = 0x05F, // Rx FIFO Packet Count
CWRR = 0x060, // Contention Window Report Register
BCN_TCFG = 0x062, // Beacon Time Configuration
RFPC = 0x05F,
CWRR = 0x060,
BCN_TCFG = 0x062,
#define BCN_TCFG_CW_SHIFT 8
#define BCN_TCFG_IFS 0
BCN_INTERVAL = 0x070, // Beacon Interval (TU)
ATIMWND = 0x072, // ATIM Window Size (TU)
BCN_DRV_EARLY_INT = 0x074, // Driver Early Interrupt Time (TU). Time to send interrupt to notify to change beacon content before TBTT
BCN_INTERVAL = 0x070,
ATIMWND = 0x072,
BCN_DRV_EARLY_INT = 0x074,
#define BCN_DRV_EARLY_INT_SWBCN_SHIFT 8
#define BCN_DRV_EARLY_INT_TIME_SHIFT 0
BCN_DMATIME = 0x076, // Beacon DMA and ATIM interrupt time (US). Indicates the time before TBTT to perform beacon queue DMA
BCN_ERR_THRESH = 0x078, // Beacon Error Threshold
RWCAM = 0x0A0, //IN 8190 Data Sheet is called CAMcmd
//----------------------------------------------------------------------------
//// 8190 CAM Command Register (offset 0xA0, 4 byte)
////----------------------------------------------------------------------------
#define CAM_CM_SecCAMPolling BIT31 //Security CAM Polling
#define CAM_CM_SecCAMClr BIT30 //Clear all bits in CAM
#define CAM_CM_SecCAMWE BIT16 //Security CAM enable
BCN_DMATIME = 0x076,
BCN_ERR_THRESH = 0x078,
RWCAM = 0x0A0,
#define CAM_CM_SecCAMPolling BIT31
#define CAM_CM_SecCAMClr BIT30
#define CAM_CM_SecCAMWE BIT16
#define CAM_VALID BIT15
#define CAM_NOTVALID 0x0000
#define CAM_USEDK BIT5
@ -234,68 +224,62 @@ enum _RTL8192Pci_HW {
#define CAM_READ 0x00000000
#define CAM_POLLINIG BIT31
#define SCR_UseDK 0x01
WCAMI = 0x0A4, // Software write CAM input content
RCAMO = 0x0A8, // Software read/write CAM config
SECR = 0x0B0, //Security Configuration Register
#define SCR_TxUseDK BIT0 //Force Tx Use Default Key
#define SCR_RxUseDK BIT1 //Force Rx Use Default Key
#define SCR_TxEncEnable BIT2 //Enable Tx Encryption
#define SCR_RxDecEnable BIT3 //Enable Rx Decryption
#define SCR_SKByA2 BIT4 //Search kEY BY A2
#define SCR_NoSKMC BIT5 //No Key Search for Multicast
SWREGULATOR = 0x0BD, // Switching Regulator
WCAMI = 0x0A4,
RCAMO = 0x0A8,
SECR = 0x0B0,
#define SCR_TxUseDK BIT0
#define SCR_RxUseDK BIT1
#define SCR_TxEncEnable BIT2
#define SCR_RxDecEnable BIT3
#define SCR_SKByA2 BIT4
#define SCR_NoSKMC BIT5
SWREGULATOR = 0x0BD,
INTA_MASK = 0x0f4,
//----------------------------------------------------------------------------
// 8190 IMR/ISR bits (offset 0xfd, 8bits)
//----------------------------------------------------------------------------
#define IMR8190_DISABLED 0x0
#define IMR_ATIMEND BIT28 // ATIM Window End Interrupt
#define IMR_TBDOK BIT27 // Transmit Beacon OK Interrupt
#define IMR_TBDER BIT26 // Transmit Beacon Error Interrupt
#define IMR_TXFOVW BIT15 // Transmit FIFO Overflow
#define IMR_TIMEOUT0 BIT14 // TimeOut0
#define IMR_BcnInt BIT13 // Beacon DMA Interrupt 0
#define IMR_RXFOVW BIT12 // Receive FIFO Overflow
#define IMR_RDU BIT11 // Receive Descriptor Unavailable
#define IMR_RXCMDOK BIT10 // Receive Command Packet OK
#define IMR_BDOK BIT9 // Beacon Queue DMA OK Interrup
#define IMR_HIGHDOK BIT8 // High Queue DMA OK Interrupt
#define IMR_COMDOK BIT7 // Command Queue DMA OK Interrupt
#define IMR_MGNTDOK BIT6 // Management Queue DMA OK Interrupt
#define IMR_HCCADOK BIT5 // HCCA Queue DMA OK Interrupt
#define IMR_BKDOK BIT4 // AC_BK DMA OK Interrupt
#define IMR_BEDOK BIT3 // AC_BE DMA OK Interrupt
#define IMR_VIDOK BIT2 // AC_VI DMA OK Interrupt
#define IMR_VODOK BIT1 // AC_VO DMA Interrupt
#define IMR_ROK BIT0 // Receive DMA OK Interrupt
ISR = 0x0f8, // Interrupt Status Register
TPPoll = 0x0fd, // Transmit priority polling register
#define TPPoll_BKQ BIT0 // BK queue polling
#define TPPoll_BEQ BIT1 // BE queue polling
#define TPPoll_VIQ BIT2 // VI queue polling
#define TPPoll_VOQ BIT3 // VO queue polling
#define TPPoll_BQ BIT4 // Beacon queue polling
#define TPPoll_CQ BIT5 // Command queue polling
#define TPPoll_MQ BIT6 // Management queue polling
#define TPPoll_HQ BIT7 // High queue polling
#define TPPoll_HCCAQ BIT8 // HCCA queue polling
#define TPPoll_StopBK BIT9 // Stop BK queue
#define TPPoll_StopBE BIT10 // Stop BE queue
#define TPPoll_StopVI BIT11 // Stop VI queue
#define TPPoll_StopVO BIT12 // Stop VO queue
#define TPPoll_StopMgt BIT13 // Stop Mgnt queue
#define TPPoll_StopHigh BIT14 // Stop High queue
#define TPPoll_StopHCCA BIT15 // Stop HCCA queue
#define TPPoll_SHIFT 8 // Queue ID mapping
#define IMR_ATIMEND BIT28
#define IMR_TBDOK BIT27
#define IMR_TBDER BIT26
#define IMR_TXFOVW BIT15
#define IMR_TIMEOUT0 BIT14
#define IMR_BcnInt BIT13
#define IMR_RXFOVW BIT12
#define IMR_RDU BIT11
#define IMR_RXCMDOK BIT10
#define IMR_BDOK BIT9
#define IMR_HIGHDOK BIT8
#define IMR_COMDOK BIT7
#define IMR_MGNTDOK BIT6
#define IMR_HCCADOK BIT5
#define IMR_BKDOK BIT4
#define IMR_BEDOK BIT3
#define IMR_VIDOK BIT2
#define IMR_VODOK BIT1
#define IMR_ROK BIT0
ISR = 0x0f8,
TPPoll = 0x0fd,
#define TPPoll_BKQ BIT0
#define TPPoll_BEQ BIT1
#define TPPoll_VIQ BIT2
#define TPPoll_VOQ BIT3
#define TPPoll_BQ BIT4
#define TPPoll_CQ BIT5
#define TPPoll_MQ BIT6
#define TPPoll_HQ BIT7
#define TPPoll_HCCAQ BIT8
#define TPPoll_StopBK BIT9
#define TPPoll_StopBE BIT10
#define TPPoll_StopVI BIT11
#define TPPoll_StopVO BIT12
#define TPPoll_StopMgt BIT13
#define TPPoll_StopHigh BIT14
#define TPPoll_StopHCCA BIT15
#define TPPoll_SHIFT 8
PSR = 0x0ff, // Page Select Register
#define PSR_GEN 0x0 // Page 0 register general MAC Control
#define PSR_CPU 0x1 // Page 1 register for CPU
CPU_GEN = 0x100, // CPU Reset Register
BB_RESET = 0x101, // Baseband Reset
//----------------------------------------------------------------------------
// 8190 CPU General Register (offset 0x100, 4 byte)
//----------------------------------------------------------------------------
PSR = 0x0ff,
#define PSR_GEN 0x0
#define PSR_CPU 0x1
CPU_GEN = 0x100,
BB_RESET = 0x101,
#define CPU_CCK_LOOPBACK 0x00030000
#define CPU_GEN_SYSTEM_RESET 0x00000001
#define CPU_GEN_FIRMWARE_RESET 0x00000008
@ -304,19 +288,15 @@ enum _RTL8192Pci_HW {
#define CPU_GEN_PUT_CODE_OK 0x00000080
#define CPU_GEN_BB_RST 0x00000100
#define CPU_GEN_PWR_STB_CPU 0x00000004
#define CPU_GEN_NO_LOOPBACK_MSK 0xFFF8FFFF // Set bit18,17,16 to 0. Set bit19
#define CPU_GEN_NO_LOOPBACK_SET 0x00080000 // Set BIT19 to 1
#define CPU_GEN_NO_LOOPBACK_MSK 0xFFF8FFFF
#define CPU_GEN_NO_LOOPBACK_SET 0x00080000
#define CPU_GEN_GPIO_UART 0x00007000
LED1Cfg = 0x154,// LED1 Configuration Register
LED0Cfg = 0x155,// LED0 Configuration Register
LED1Cfg = 0x154,
LED0Cfg = 0x155,
AcmAvg = 0x170, // ACM Average Period Register
AcmHwCtrl = 0x171, // ACM Hardware Control Register
//----------------------------------------------------------------------------
//
// 8190 AcmHwCtrl bits (offset 0x171, 1 byte)
//----------------------------------------------------------------------------
AcmAvg = 0x170,
AcmHwCtrl = 0x171,
#define AcmHw_HwEn BIT0
#define AcmHw_BeqEn BIT1
#define AcmHw_ViqEn BIT2
@ -324,67 +304,65 @@ enum _RTL8192Pci_HW {
#define AcmHw_BeqStatus BIT4
#define AcmHw_ViqStatus BIT5
#define AcmHw_VoqStatus BIT6
AcmFwCtrl = 0x172, // ACM Firmware Control Register
AcmFwCtrl = 0x172,
#define AcmFw_BeqStatus BIT0
#define AcmFw_ViqStatus BIT1
#define AcmFw_VoqStatus BIT2
VOAdmTime = 0x174, // VO Queue Admitted Time Register
VIAdmTime = 0x178, // VI Queue Admitted Time Register
BEAdmTime = 0x17C, // BE Queue Admitted Time Register
RQPN1 = 0x180, // Reserved Queue Page Number , Vo Vi, Be, Bk
RQPN2 = 0x184, // Reserved Queue Page Number, HCCA, Cmd, Mgnt, High
RQPN3 = 0x188, // Reserved Queue Page Number, Bcn, Public,
QPRR = 0x1E0, // Queue Page Report per TID
QPNR = 0x1F0, // Queue Packet Number report per TID
/* there's 9 tx descriptor base address available */
BQDA = 0x200, // Beacon Queue Descriptor Address
HQDA = 0x204, // High Priority Queue Descriptor Address
CQDA = 0x208, // Command Queue Descriptor Address
MQDA = 0x20C, // Management Queue Descriptor Address
HCCAQDA = 0x210, // HCCA Queue Descriptor Address
VOQDA = 0x214, // VO Queue Descriptor Address
VIQDA = 0x218, // VI Queue Descriptor Address
BEQDA = 0x21C, // BE Queue Descriptor Address
BKQDA = 0x220, // BK Queue Descriptor Address
/* there's 2 rx descriptor base address availalbe */
RCQDA = 0x224, // Receive command Queue Descriptor Address
RDQDA = 0x228, // Receive Queue Descriptor Start Address
VOAdmTime = 0x174,
VIAdmTime = 0x178,
BEAdmTime = 0x17C,
RQPN1 = 0x180,
RQPN2 = 0x184,
RQPN3 = 0x188,
QPRR = 0x1E0,
QPNR = 0x1F0,
BQDA = 0x200,
HQDA = 0x204,
CQDA = 0x208,
MQDA = 0x20C,
HCCAQDA = 0x210,
VOQDA = 0x214,
VIQDA = 0x218,
BEQDA = 0x21C,
BKQDA = 0x220,
RCQDA = 0x224,
RDQDA = 0x228,
MAR0 = 0x240, // Multicast filter.
MAR0 = 0x240,
MAR4 = 0x244,
CCX_PERIOD = 0x250, // CCX Measurement Period Register, in unit of TU.
CLM_RESULT = 0x251, // CCA Busy fraction register.
NHM_PERIOD = 0x252, // NHM Measurement Period register, in unit of TU.
CCX_PERIOD = 0x250,
CLM_RESULT = 0x251,
NHM_PERIOD = 0x252,
NHM_THRESHOLD0 = 0x253, // Noise Histogram Meashorement0.
NHM_THRESHOLD1 = 0x254, // Noise Histogram Meashorement1.
NHM_THRESHOLD2 = 0x255, // Noise Histogram Meashorement2.
NHM_THRESHOLD3 = 0x256, // Noise Histogram Meashorement3.
NHM_THRESHOLD4 = 0x257, // Noise Histogram Meashorement4.
NHM_THRESHOLD5 = 0x258, // Noise Histogram Meashorement5.
NHM_THRESHOLD6 = 0x259, // Noise Histogram Meashorement6
NHM_THRESHOLD0 = 0x253,
NHM_THRESHOLD1 = 0x254,
NHM_THRESHOLD2 = 0x255,
NHM_THRESHOLD3 = 0x256,
NHM_THRESHOLD4 = 0x257,
NHM_THRESHOLD5 = 0x258,
NHM_THRESHOLD6 = 0x259,
MCTRL = 0x25A, // Measurement Control
MCTRL = 0x25A,
NHM_RPI_COUNTER0 = 0x264, // Noise Histogram RPI counter0, the fraction of signal strength < NHM_THRESHOLD0.
NHM_RPI_COUNTER1 = 0x265, // Noise Histogram RPI counter1, the fraction of signal strength in (NHM_THRESHOLD0, NHM_THRESHOLD1].
NHM_RPI_COUNTER2 = 0x266, // Noise Histogram RPI counter2, the fraction of signal strength in (NHM_THRESHOLD1, NHM_THRESHOLD2].
NHM_RPI_COUNTER3 = 0x267, // Noise Histogram RPI counter3, the fraction of signal strength in (NHM_THRESHOLD2, NHM_THRESHOLD3].
NHM_RPI_COUNTER4 = 0x268, // Noise Histogram RPI counter4, the fraction of signal strength in (NHM_THRESHOLD3, NHM_THRESHOLD4].
NHM_RPI_COUNTER5 = 0x269, // Noise Histogram RPI counter5, the fraction of signal strength in (NHM_THRESHOLD4, NHM_THRESHOLD5].
NHM_RPI_COUNTER6 = 0x26A, // Noise Histogram RPI counter6, the fraction of signal strength in (NHM_THRESHOLD5, NHM_THRESHOLD6].
NHM_RPI_COUNTER7 = 0x26B, // Noise Histogram RPI counter7, the fraction of signal strength in (NHM_THRESHOLD6, NHM_THRESHOLD7].
NHM_RPI_COUNTER0 = 0x264,
NHM_RPI_COUNTER1 = 0x265,
NHM_RPI_COUNTER2 = 0x266,
NHM_RPI_COUNTER3 = 0x267,
NHM_RPI_COUNTER4 = 0x268,
NHM_RPI_COUNTER5 = 0x269,
NHM_RPI_COUNTER6 = 0x26A,
NHM_RPI_COUNTER7 = 0x26B,
WFCRC0 = 0x2f0,
WFCRC1 = 0x2f4,
WFCRC2 = 0x2f8,
BW_OPMODE = 0x300, // Bandwidth operation mode
BW_OPMODE = 0x300,
#define BW_OPMODE_11J BIT0
#define BW_OPMODE_5G BIT1
#define BW_OPMODE_20MHZ BIT2
IC_VERRSION = 0x301, //IC_VERSION
MSR = 0x303, // Media Status register
IC_VERRSION = 0x301,
MSR = 0x303,
#define MSR_LINK_MASK ((1<<0)|(1<<1))
#define MSR_LINK_MANAGED 2
#define MSR_LINK_NONE 0
@ -392,11 +370,17 @@ enum _RTL8192Pci_HW {
#define MSR_LINK_ADHOC 1
#define MSR_LINK_MASTER 3
#define MSR_LINK_ENEDCA (1<<4)
RETRY_LIMIT = 0x304, // Retry Limit [15:8]-short, [7:0]-long
#define MSR_NOLINK 0x00
#define MSR_ADHOC 0x01
#define MSR_INFRA 0x02
#define MSR_AP 0x03
RETRY_LIMIT = 0x304,
#define RETRY_LIMIT_SHORT_SHIFT 8
#define RETRY_LIMIT_LONG_SHIFT 0
TSFR = 0x308,
RRSR = 0x310, // Response Rate Set
RRSR = 0x310,
#define RRSR_RSC_OFFSET 21
#define RRSR_SHORT_OFFSET 23
#define RRSR_RSC_DUPLICATE 0x600000
@ -423,18 +407,13 @@ enum _RTL8192Pci_HW {
#define RRSR_MCS5 BIT17
#define RRSR_MCS6 BIT18
#define RRSR_MCS7 BIT19
#define BRSR_AckShortPmb BIT23 // CCK ACK: use Short Preamble or not
#define BRSR_AckShortPmb BIT23
UFWP = 0x318,
RATR0 = 0x320, // Rate Adaptive Table register1
//----------------------------------------------------------------------------
// 8190 Rate Adaptive Table Register (offset 0x320, 4 byte)
//----------------------------------------------------------------------------
//CCK
RATR0 = 0x320,
#define RATR_1M 0x00000001
#define RATR_2M 0x00000002
#define RATR_55M 0x00000004
#define RATR_11M 0x00000008
//OFDM
#define RATR_6M 0x00000010
#define RATR_9M 0x00000020
#define RATR_12M 0x00000040
@ -443,7 +422,6 @@ enum _RTL8192Pci_HW {
#define RATR_36M 0x00000200
#define RATR_48M 0x00000400
#define RATR_54M 0x00000800
//MCS 1 Spatial Stream
#define RATR_MCS0 0x00001000
#define RATR_MCS1 0x00002000
#define RATR_MCS2 0x00004000
@ -452,7 +430,6 @@ enum _RTL8192Pci_HW {
#define RATR_MCS5 0x00020000
#define RATR_MCS6 0x00040000
#define RATR_MCS7 0x00080000
//MCS 2 Spatial Stream
#define RATR_MCS8 0x00100000
#define RATR_MCS9 0x00200000
#define RATR_MCS10 0x00400000
@ -461,7 +438,6 @@ enum _RTL8192Pci_HW {
#define RATR_MCS13 0x02000000
#define RATR_MCS14 0x04000000
#define RATR_MCS15 0x08000000
// ALL CCK Rate
#define RATE_ALL_CCK RATR_1M|RATR_2M|RATR_55M|RATR_11M
#define RATE_ALL_OFDM_AG RATR_6M|RATR_9M|RATR_12M|RATR_18M|RATR_24M|RATR_36M|RATR_48M|RATR_54M
#define RATE_ALL_OFDM_1SS RATR_MCS0|RATR_MCS1|RATR_MCS2|RATR_MCS3 | \
@ -470,22 +446,20 @@ enum _RTL8192Pci_HW {
RATR_MCS12|RATR_MCS13|RATR_MCS14|RATR_MCS15
DRIVER_RSSI = 0x32c, // Driver tell Firmware current RSSI
MCS_TXAGC = 0x340, // MCS AGC
CCK_TXAGC = 0x348, // CCK AGC
MacBlkCtrl = 0x403, // Mac block on/off control register
DRIVER_RSSI = 0x32c,
MCS_TXAGC = 0x340,
CCK_TXAGC = 0x348,
MacBlkCtrl = 0x403,
};
}
;
#define GPI 0x108
#define GPO 0x109
#define GPE 0x10a
#define ANAPAR_FOR_8192PciE 0x17 // Analog parameter register
#define HWSET_MAX_SIZE_92S 128
#define MSR_NOLINK 0x00
#define MSR_ADHOC 0x01
#define MSR_INFRA 0x02
#define MSR_AP 0x03
#define ANAPAR_FOR_8192PciE 0x17
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,51 @@
/******************************************************************************
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
******************************************************************************/
#ifndef __INC_HAL8192PciE_FW_IMG_H
#define __INC_HAL8192PciE_FW_IMG_H
/*Created on 2008/11/18, 3: 7*/
#include <linux/types.h>
#define BootArrayLengthPciE 344
extern u8 Rtl8192PciEFwBootArray[BootArrayLengthPciE];
#define MainArrayLengthPciE 43012
extern u8 Rtl8192PciEFwMainArray[MainArrayLengthPciE];
#define DataArrayLengthPciE 848
extern u8 Rtl8192PciEFwDataArray[DataArrayLengthPciE];
#define PHY_REGArrayLengthPciE 1
extern u32 Rtl8192PciEPHY_REGArray[PHY_REGArrayLengthPciE];
#define PHY_REG_1T2RArrayLengthPciE 296
extern u32 Rtl8192PciEPHY_REG_1T2RArray[PHY_REG_1T2RArrayLengthPciE];
#define RadioA_ArrayLengthPciE 246
extern u32 Rtl8192PciERadioA_Array[RadioA_ArrayLengthPciE] ;
#define RadioB_ArrayLengthPciE 78
extern u32 Rtl8192PciERadioB_Array[RadioB_ArrayLengthPciE] ;
#define RadioC_ArrayLengthPciE 1
extern u32 Rtl8192PciERadioC_Array[RadioC_ArrayLengthPciE] ;
#define RadioD_ArrayLengthPciE 1
extern u32 Rtl8192PciERadioD_Array[RadioD_ArrayLengthPciE] ;
#define MACPHY_ArrayLengthPciE 18
extern u32 Rtl8192PciEMACPHY_Array[MACPHY_ArrayLengthPciE] ;
#define MACPHY_Array_PGLengthPciE 30
extern u32 Rtl8192PciEMACPHY_Array_PG[MACPHY_Array_PGLengthPciE] ;
#define AGCTAB_ArrayLengthPciE 384
extern u32 Rtl8192PciEAGCTAB_Array[AGCTAB_ArrayLengthPciE] ;
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,164 @@
/******************************************************************************
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
******************************************************************************/
#ifndef _R819XU_PHY_H
#define _R819XU_PHY_H
#define MAX_DOZE_WAITING_TIMES_9x 64
#define MAX_PRECMD_CNT 16
#define MAX_RFDEPENDCMD_CNT 16
#define MAX_POSTCMD_CNT 16
#ifdef RTL8190P
#define AGCTAB_ArrayLength AGCTAB_ArrayLengthPci
#define MACPHY_ArrayLength MACPHY_ArrayLengthPci
#define RadioA_ArrayLength RadioA_ArrayLengthPci
#define RadioB_ArrayLength RadioB_ArrayLengthPci
#define MACPHY_Array_PGLength MACPHY_Array_PGLengthPci
#define RadioC_ArrayLength RadioC_ArrayLengthPci
#define RadioD_ArrayLength RadioD_ArrayLengthPci
#define PHY_REGArrayLength PHY_REGArrayLengthPci
#define PHY_REG_1T2RArrayLength PHY_REG_1T2RArrayLengthPci
#define Rtl819XMACPHY_Array_PG Rtl8190PciMACPHY_Array_PG
#define Rtl819XMACPHY_Array Rtl8190PciMACPHY_Array
#define Rtl819XRadioA_Array Rtl8190PciRadioA_Array
#define Rtl819XRadioB_Array Rtl8190PciRadioB_Array
#define Rtl819XRadioC_Array Rtl8190PciRadioC_Array
#define Rtl819XRadioD_Array Rtl8190PciRadioD_Array
#define Rtl819XAGCTAB_Array Rtl8190PciAGCTAB_Array
#define Rtl819XPHY_REGArray Rtl8190PciPHY_REGArray
#define Rtl819XPHY_REG_1T2RArray Rtl8190PciPHY_REG_1T2RArray
#endif
#ifdef RTL8192E
#define AGCTAB_ArrayLength AGCTAB_ArrayLengthPciE
#define MACPHY_ArrayLength MACPHY_ArrayLengthPciE
#define RadioA_ArrayLength RadioA_ArrayLengthPciE
#define RadioB_ArrayLength RadioB_ArrayLengthPciE
#define MACPHY_Array_PGLength MACPHY_Array_PGLengthPciE
#define RadioC_ArrayLength RadioC_ArrayLengthPciE
#define RadioD_ArrayLength RadioD_ArrayLengthPciE
#define PHY_REGArrayLength PHY_REGArrayLengthPciE
#define PHY_REG_1T2RArrayLength PHY_REG_1T2RArrayLengthPciE
#define Rtl819XMACPHY_Array_PG Rtl8192PciEMACPHY_Array_PG
#define Rtl819XMACPHY_Array Rtl8192PciEMACPHY_Array
#define Rtl819XRadioA_Array Rtl8192PciERadioA_Array
#define Rtl819XRadioB_Array Rtl8192PciERadioB_Array
#define Rtl819XRadioC_Array Rtl8192PciERadioC_Array
#define Rtl819XRadioD_Array Rtl8192PciERadioD_Array
#define Rtl819XAGCTAB_Array Rtl8192PciEAGCTAB_Array
#define Rtl819XPHY_REGArray Rtl8192PciEPHY_REGArray
#define Rtl819XPHY_REG_1T2RArray Rtl8192PciEPHY_REG_1T2RArray
#endif
typedef enum _SwChnlCmdID{
CmdID_End,
CmdID_SetTxPowerLevel,
CmdID_BBRegWrite10,
CmdID_WritePortUlong,
CmdID_WritePortUshort,
CmdID_WritePortUchar,
CmdID_RF_WriteReg,
}SwChnlCmdID;
/*--------------------------------Define structure--------------------------------*/
typedef struct _SwChnlCmd{
SwChnlCmdID CmdID;
u32 Para1;
u32 Para2;
u32 msDelay;
}__attribute__ ((packed)) SwChnlCmd;
extern u32 rtl819XMACPHY_Array_PG[];
extern u32 rtl819XPHY_REG_1T2RArray[];
extern u32 rtl819XAGCTAB_Array[];
extern u32 rtl819XRadioA_Array[];
extern u32 rtl819XRadioB_Array[];
extern u32 rtl819XRadioC_Array[];
extern u32 rtl819XRadioD_Array[];
typedef enum _HW90_BLOCK{
HW90_BLOCK_MAC = 0,
HW90_BLOCK_PHY0 = 1,
HW90_BLOCK_PHY1 = 2,
HW90_BLOCK_RF = 3,
HW90_BLOCK_MAXIMUM = 4,
}HW90_BLOCK_E, *PHW90_BLOCK_E;
typedef enum _RF90_RADIO_PATH{
RF90_PATH_A = 0,
RF90_PATH_B = 1,
RF90_PATH_C = 2,
RF90_PATH_D = 3,
RF90_PATH_MAX
}RF90_RADIO_PATH_E, *PRF90_RADIO_PATH_E;
#define bMaskByte0 0xff
#define bMaskByte1 0xff00
#define bMaskByte2 0xff0000
#define bMaskByte3 0xff000000
#define bMaskHWord 0xffff0000
#define bMaskLWord 0x0000ffff
#define bMaskDWord 0xffffffff
extern u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device* dev, u32 eRFPath);
extern void rtl8192_setBBreg(struct net_device* dev, u32 dwRegAddr, u32 dwBitMask, u32 dwData);
extern u32 rtl8192_QueryBBReg(struct net_device* dev, u32 dwRegAddr, u32 dwBitMask);
extern void rtl8192_phy_SetRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask, u32 Data);
extern u32 rtl8192_phy_QueryRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask);
extern void rtl8192_phy_configmac(struct net_device* dev);
extern void rtl8192_phyConfigBB(struct net_device* dev, u8 ConfigType);
extern bool rtl8192_phy_checkBBAndRF(struct net_device* dev, HW90_BLOCK_E CheckBlock, RF90_RADIO_PATH_E eRFPath);
extern bool rtl8192_BBConfig(struct net_device* dev);
extern void rtl8192_phy_getTxPower(struct net_device* dev);
extern void rtl8192_phy_setTxPower(struct net_device* dev, u8 channel);
extern bool rtl8192_phy_RFConfig(struct net_device* dev);
extern void rtl8192_phy_updateInitGain(struct net_device* dev);
extern u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device* dev, RF90_RADIO_PATH_E eRFPath);
extern u8 rtl8192_phy_SwChnl(struct net_device* dev, u8 channel);
extern void rtl8192_SetBWMode(struct net_device *dev, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset);
extern void rtl8192_SwChnl_WorkItem(struct net_device *dev);
extern void rtl8192_SetBWModeWorkItem(struct net_device *dev);
extern void InitialGain819xPci(struct net_device *dev, u8 Operation);
#if defined RTL8190P
extern void
PHY_SetRtl8190pRfOff(struct net_device* dev );
#endif
#if defined RTL8192E
extern void
PHY_SetRtl8192eRfOff(struct net_device* dev );
#endif
bool
SetRFPowerState(
struct net_device* dev,
RT_RF_POWER_STATE eRFPowerState
);
#define PHY_SetRFPowerState SetRFPowerState
extern void PHY_ScanOperationBackup8192(struct net_device* dev,u8 Operation);
#endif

View file

@ -0,0 +1,852 @@
/******************************************************************************
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
******************************************************************************/
#ifndef _R819XU_PHYREG_H
#define _R819XU_PHYREG_H
#define RF_DATA 0x1d4
#define rPMAC_Reset 0x100
#define rPMAC_TxStart 0x104
#define rPMAC_TxLegacySIG 0x108
#define rPMAC_TxHTSIG1 0x10c
#define rPMAC_TxHTSIG2 0x110
#define rPMAC_PHYDebug 0x114
#define rPMAC_TxPacketNum 0x118
#define rPMAC_TxIdle 0x11c
#define rPMAC_TxMACHeader0 0x120
#define rPMAC_TxMACHeader1 0x124
#define rPMAC_TxMACHeader2 0x128
#define rPMAC_TxMACHeader3 0x12c
#define rPMAC_TxMACHeader4 0x130
#define rPMAC_TxMACHeader5 0x134
#define rPMAC_TxDataType 0x138
#define rPMAC_TxRandomSeed 0x13c
#define rPMAC_CCKPLCPPreamble 0x140
#define rPMAC_CCKPLCPHeader 0x144
#define rPMAC_CCKCRC16 0x148
#define rPMAC_OFDMRxCRC32OK 0x170
#define rPMAC_OFDMRxCRC32Er 0x174
#define rPMAC_OFDMRxParityEr 0x178
#define rPMAC_OFDMRxCRC8Er 0x17c
#define rPMAC_CCKCRxRC16Er 0x180
#define rPMAC_CCKCRxRC32Er 0x184
#define rPMAC_CCKCRxRC32OK 0x188
#define rPMAC_TxStatus 0x18c
#define MCS_TXAGC 0x340
#define CCK_TXAGC 0x348
/*---------------------0x400~0x4ff----------------------*/
#define MacBlkCtrl 0x403
#define rFPGA0_RFMOD 0x800
#define rFPGA0_TxInfo 0x804
#define rFPGA0_PSDFunction 0x808
#define rFPGA0_TxGainStage 0x80c
#define rFPGA0_RFTiming1 0x810
#define rFPGA0_RFTiming2 0x814
#define rFPGA0_XA_HSSIParameter1 0x820
#define rFPGA0_XA_HSSIParameter2 0x824
#define rFPGA0_XB_HSSIParameter1 0x828
#define rFPGA0_XB_HSSIParameter2 0x82c
#define rFPGA0_XC_HSSIParameter1 0x830
#define rFPGA0_XC_HSSIParameter2 0x834
#define rFPGA0_XD_HSSIParameter1 0x838
#define rFPGA0_XD_HSSIParameter2 0x83c
#define rFPGA0_XA_LSSIParameter 0x840
#define rFPGA0_XB_LSSIParameter 0x844
#define rFPGA0_XC_LSSIParameter 0x848
#define rFPGA0_XD_LSSIParameter 0x84c
#define rFPGA0_RFWakeUpParameter 0x850
#define rFPGA0_RFSleepUpParameter 0x854
#define rFPGA0_XAB_SwitchControl 0x858
#define rFPGA0_XCD_SwitchControl 0x85c
#define rFPGA0_XA_RFInterfaceOE 0x860
#define rFPGA0_XB_RFInterfaceOE 0x864
#define rFPGA0_XC_RFInterfaceOE 0x868
#define rFPGA0_XD_RFInterfaceOE 0x86c
#define rFPGA0_XAB_RFInterfaceSW 0x870
#define rFPGA0_XCD_RFInterfaceSW 0x874
#define rFPGA0_XAB_RFParameter 0x878
#define rFPGA0_XCD_RFParameter 0x87c
#define rFPGA0_AnalogParameter1 0x880
#define rFPGA0_AnalogParameter2 0x884
#define rFPGA0_AnalogParameter3 0x888
#define rFPGA0_AnalogParameter4 0x88c
#define rFPGA0_XA_LSSIReadBack 0x8a0
#define rFPGA0_XB_LSSIReadBack 0x8a4
#define rFPGA0_XC_LSSIReadBack 0x8a8
#define rFPGA0_XD_LSSIReadBack 0x8ac
#define rFPGA0_PSDReport 0x8b4
#define rFPGA0_XAB_RFInterfaceRB 0x8e0
#define rFPGA0_XCD_RFInterfaceRB 0x8e4
#define rFPGA1_RFMOD 0x900
#define rFPGA1_TxBlock 0x904
#define rFPGA1_DebugSelect 0x908
#define rFPGA1_TxInfo 0x90c
#define rCCK0_System 0xa00
#define rCCK0_AFESetting 0xa04
#define rCCK0_CCA 0xa08
#define rCCK0_RxAGC1 0xa0c
#define rCCK0_RxAGC2 0xa10
#define rCCK0_RxHP 0xa14
#define rCCK0_DSPParameter1 0xa18
#define rCCK0_DSPParameter2 0xa1c
#define rCCK0_TxFilter1 0xa20
#define rCCK0_TxFilter2 0xa24
#define rCCK0_DebugPort 0xa28
#define rCCK0_FalseAlarmReport 0xa2c
#define rCCK0_TRSSIReport 0xa50
#define rCCK0_RxReport 0xa54
#define rCCK0_FACounterLower 0xa5c
#define rCCK0_FACounterUpper 0xa58
#define rOFDM0_LSTF 0xc00
#define rOFDM0_TRxPathEnable 0xc04
#define rOFDM0_TRMuxPar 0xc08
#define rOFDM0_TRSWIsolation 0xc0c
#define rOFDM0_XARxAFE 0xc10
#define rOFDM0_XARxIQImbalance 0xc14
#define rOFDM0_XBRxAFE 0xc18
#define rOFDM0_XBRxIQImbalance 0xc1c
#define rOFDM0_XCRxAFE 0xc20
#define rOFDM0_XCRxIQImbalance 0xc24
#define rOFDM0_XDRxAFE 0xc28
#define rOFDM0_XDRxIQImbalance 0xc2c
#define rOFDM0_RxDetector1 0xc30
#define rOFDM0_RxDetector2 0xc34
#define rOFDM0_RxDetector3 0xc38
#define rOFDM0_RxDetector4 0xc3c
#define rOFDM0_RxDSP 0xc40
#define rOFDM0_CFOandDAGC 0xc44
#define rOFDM0_CCADropThreshold 0xc48
#define rOFDM0_ECCAThreshold 0xc4c
#define rOFDM0_XAAGCCore1 0xc50
#define rOFDM0_XAAGCCore2 0xc54
#define rOFDM0_XBAGCCore1 0xc58
#define rOFDM0_XBAGCCore2 0xc5c
#define rOFDM0_XCAGCCore1 0xc60
#define rOFDM0_XCAGCCore2 0xc64
#define rOFDM0_XDAGCCore1 0xc68
#define rOFDM0_XDAGCCore2 0xc6c
#define rOFDM0_AGCParameter1 0xc70
#define rOFDM0_AGCParameter2 0xc74
#define rOFDM0_AGCRSSITable 0xc78
#define rOFDM0_HTSTFAGC 0xc7c
#define rOFDM0_XATxIQImbalance 0xc80
#define rOFDM0_XATxAFE 0xc84
#define rOFDM0_XBTxIQImbalance 0xc88
#define rOFDM0_XBTxAFE 0xc8c
#define rOFDM0_XCTxIQImbalance 0xc90
#define rOFDM0_XCTxAFE 0xc94
#define rOFDM0_XDTxIQImbalance 0xc98
#define rOFDM0_XDTxAFE 0xc9c
#define rOFDM0_RxHPParameter 0xce0
#define rOFDM0_TxPseudoNoiseWgt 0xce4
#define rOFDM0_FrameSync 0xcf0
#define rOFDM0_DFSReport 0xcf4
#define rOFDM0_TxCoeff1 0xca4
#define rOFDM0_TxCoeff2 0xca8
#define rOFDM0_TxCoeff3 0xcac
#define rOFDM0_TxCoeff4 0xcb0
#define rOFDM0_TxCoeff5 0xcb4
#define rOFDM0_TxCoeff6 0xcb8
#define rOFDM1_LSTF 0xd00
#define rOFDM1_TRxPathEnable 0xd04
#define rOFDM1_CFO 0xd08
#define rOFDM1_CSI1 0xd10
#define rOFDM1_SBD 0xd14
#define rOFDM1_CSI2 0xd18
#define rOFDM1_CFOTracking 0xd2c
#define rOFDM1_TRxMesaure1 0xd34
#define rOFDM1_IntfDet 0xd3c
#define rOFDM1_PseudoNoiseStateAB 0xd50
#define rOFDM1_PseudoNoiseStateCD 0xd54
#define rOFDM1_RxPseudoNoiseWgt 0xd58
#define rOFDM_PHYCounter1 0xda0
#define rOFDM_PHYCounter2 0xda4
#define rOFDM_PHYCounter3 0xda8
#define rOFDM_ShortCFOAB 0xdac
#define rOFDM_ShortCFOCD 0xdb0
#define rOFDM_LongCFOAB 0xdb4
#define rOFDM_LongCFOCD 0xdb8
#define rOFDM_TailCFOAB 0xdbc
#define rOFDM_TailCFOCD 0xdc0
#define rOFDM_PWMeasure1 0xdc4
#define rOFDM_PWMeasure2 0xdc8
#define rOFDM_BWReport 0xdcc
#define rOFDM_AGCReport 0xdd0
#define rOFDM_RxSNR 0xdd4
#define rOFDM_RxEVMCSI 0xdd8
#define rOFDM_SIGReport 0xddc
#define rTxAGC_Rate18_06 0xe00
#define rTxAGC_Rate54_24 0xe04
#define rTxAGC_CCK_Mcs32 0xe08
#define rTxAGC_Mcs03_Mcs00 0xe10
#define rTxAGC_Mcs07_Mcs04 0xe14
#define rTxAGC_Mcs11_Mcs08 0xe18
#define rTxAGC_Mcs15_Mcs12 0xe1c
#define rZebra1_HSSIEnable 0x0
#define rZebra1_TRxEnable1 0x1
#define rZebra1_TRxEnable2 0x2
#define rZebra1_AGC 0x4
#define rZebra1_ChargePump 0x5
#define rZebra1_Channel 0x7
#define rZebra1_TxGain 0x8
#define rZebra1_TxLPF 0x9
#define rZebra1_RxLPF 0xb
#define rZebra1_RxHPFCorner 0xc
#define rGlobalCtrl 0
#define rRTL8256_TxLPF 19
#define rRTL8256_RxLPF 11
#define rRTL8258_TxLPF 0x11
#define rRTL8258_RxLPF 0x13
#define rRTL8258_RSSILPF 0xa
#define bBBResetB 0x100
#define bGlobalResetB 0x200
#define bOFDMTxStart 0x4
#define bCCKTxStart 0x8
#define bCRC32Debug 0x100
#define bPMACLoopback 0x10
#define bTxLSIG 0xffffff
#define bOFDMTxRate 0xf
#define bOFDMTxReserved 0x10
#define bOFDMTxLength 0x1ffe0
#define bOFDMTxParity 0x20000
#define bTxHTSIG1 0xffffff
#define bTxHTMCSRate 0x7f
#define bTxHTBW 0x80
#define bTxHTLength 0xffff00
#define bTxHTSIG2 0xffffff
#define bTxHTSmoothing 0x1
#define bTxHTSounding 0x2
#define bTxHTReserved 0x4
#define bTxHTAggreation 0x8
#define bTxHTSTBC 0x30
#define bTxHTAdvanceCoding 0x40
#define bTxHTShortGI 0x80
#define bTxHTNumberHT_LTF 0x300
#define bTxHTCRC8 0x3fc00
#define bCounterReset 0x10000
#define bNumOfOFDMTx 0xffff
#define bNumOfCCKTx 0xffff0000
#define bTxIdleInterval 0xffff
#define bOFDMService 0xffff0000
#define bTxMACHeader 0xffffffff
#define bTxDataInit 0xff
#define bTxHTMode 0x100
#define bTxDataType 0x30000
#define bTxRandomSeed 0xffffffff
#define bCCKTxPreamble 0x1
#define bCCKTxSFD 0xffff0000
#define bCCKTxSIG 0xff
#define bCCKTxService 0xff00
#define bCCKLengthExt 0x8000
#define bCCKTxLength 0xffff0000
#define bCCKTxCRC16 0xffff
#define bCCKTxStatus 0x1
#define bOFDMTxStatus 0x2
#define bRFMOD 0x1
#define bJapanMode 0x2
#define bCCKTxSC 0x30
#define bCCKEn 0x1000000
#define bOFDMEn 0x2000000
#define bOFDMRxADCPhase 0x10000
#define bOFDMTxDACPhase 0x40000
#define bXATxAGC 0x3f
#define bXBTxAGC 0xf00
#define bXCTxAGC 0xf000
#define bXDTxAGC 0xf0000
#define bPAStart 0xf0000000
#define bTRStart 0x00f00000
#define bRFStart 0x0000f000
#define bBBStart 0x000000f0
#define bBBCCKStart 0x0000000f
#define bPAEnd 0xf
#define bTREnd 0x0f000000
#define bRFEnd 0x000f0000
#define bCCAMask 0x000000f0
#define bR2RCCAMask 0x00000f00
#define bHSSI_R2TDelay 0xf8000000
#define bHSSI_T2RDelay 0xf80000
#define bContTxHSSI 0x400
#define bIGFromCCK 0x200
#define bAGCAddress 0x3f
#define bRxHPTx 0x7000
#define bRxHPT2R 0x38000
#define bRxHPCCKIni 0xc0000
#define bAGCTxCode 0xc00000
#define bAGCRxCode 0x300000
#define b3WireDataLength 0x800
#define b3WireAddressLength 0x400
#define b3WireRFPowerDown 0x1
#define b5GPAPEPolarity 0x40000000
#define b2GPAPEPolarity 0x80000000
#define bRFSW_TxDefaultAnt 0x3
#define bRFSW_TxOptionAnt 0x30
#define bRFSW_RxDefaultAnt 0x300
#define bRFSW_RxOptionAnt 0x3000
#define bRFSI_3WireData 0x1
#define bRFSI_3WireClock 0x2
#define bRFSI_3WireLoad 0x4
#define bRFSI_3WireRW 0x8
#define bRFSI_3Wire 0xf
#define bRFSI_RFENV 0x10
#define bRFSI_TRSW 0x20
#define bRFSI_TRSWB 0x40
#define bRFSI_ANTSW 0x100
#define bRFSI_ANTSWB 0x200
#define bRFSI_PAPE 0x400
#define bRFSI_PAPE5G 0x800
#define bBandSelect 0x1
#define bHTSIG2_GI 0x80
#define bHTSIG2_Smoothing 0x01
#define bHTSIG2_Sounding 0x02
#define bHTSIG2_Aggreaton 0x08
#define bHTSIG2_STBC 0x30
#define bHTSIG2_AdvCoding 0x40
#define bHTSIG2_NumOfHTLTF 0x300
#define bHTSIG2_CRC8 0x3fc
#define bHTSIG1_MCS 0x7f
#define bHTSIG1_BandWidth 0x80
#define bHTSIG1_HTLength 0xffff
#define bLSIG_Rate 0xf
#define bLSIG_Reserved 0x10
#define bLSIG_Length 0x1fffe
#define bLSIG_Parity 0x20
#define bCCKRxPhase 0x4
#define bLSSIReadAddress 0x3f000000
#define bLSSIReadEdge 0x80000000
#define bLSSIReadBackData 0xfff
#define bLSSIReadOKFlag 0x1000
#define bCCKSampleRate 0x8
#define bRegulator0Standby 0x1
#define bRegulatorPLLStandby 0x2
#define bRegulator1Standby 0x4
#define bPLLPowerUp 0x8
#define bDPLLPowerUp 0x10
#define bDA10PowerUp 0x20
#define bAD7PowerUp 0x200
#define bDA6PowerUp 0x2000
#define bXtalPowerUp 0x4000
#define b40MDClkPowerUP 0x8000
#define bDA6DebugMode 0x20000
#define bDA6Swing 0x380000
#define bADClkPhase 0x4000000
#define b80MClkDelay 0x18000000
#define bAFEWatchDogEnable 0x20000000
#define bXtalCap 0x0f000000
#define bXtalCap01 0xc0000000
#define bXtalCap23 0x3
#define bXtalCap92x 0x0f000000
#define bIntDifClkEnable 0x400
#define bExtSigClkEnable 0x800
#define bBandgapMbiasPowerUp 0x10000
#define bAD11SHGain 0xc0000
#define bAD11InputRange 0x700000
#define bAD11OPCurrent 0x3800000
#define bIPathLoopback 0x4000000
#define bQPathLoopback 0x8000000
#define bAFELoopback 0x10000000
#define bDA10Swing 0x7e0
#define bDA10Reverse 0x800
#define bDAClkSource 0x1000
#define bAD7InputRange 0x6000
#define bAD7Gain 0x38000
#define bAD7OutputCMMode 0x40000
#define bAD7InputCMMode 0x380000
#define bAD7Current 0xc00000
#define bRegulatorAdjust 0x7000000
#define bAD11PowerUpAtTx 0x1
#define bDA10PSAtTx 0x10
#define bAD11PowerUpAtRx 0x100
#define bDA10PSAtRx 0x1000
#define bCCKRxAGCFormat 0x200
#define bPSDFFTSamplepPoint 0xc000
#define bPSDAverageNum 0x3000
#define bIQPathControl 0xc00
#define bPSDFreq 0x3ff
#define bPSDAntennaPath 0x30
#define bPSDIQSwitch 0x40
#define bPSDRxTrigger 0x400000
#define bPSDTxTrigger 0x80000000
#define bPSDSineToneScale 0x7f000000
#define bPSDReport 0xffff
#define bOFDMTxSC 0x30000000
#define bCCKTxOn 0x1
#define bOFDMTxOn 0x2
#define bDebugPage 0xfff
#define bDebugItem 0xff
#define bAntL 0x10
#define bAntNonHT 0x100
#define bAntHT1 0x1000
#define bAntHT2 0x10000
#define bAntHT1S1 0x100000
#define bAntNonHTS1 0x1000000
#define bCCKBBMode 0x3
#define bCCKTxPowerSaving 0x80
#define bCCKRxPowerSaving 0x40
#define bCCKSideBand 0x10
#define bCCKScramble 0x8
#define bCCKAntDiversity 0x8000
#define bCCKCarrierRecovery 0x4000
#define bCCKTxRate 0x3000
#define bCCKDCCancel 0x0800
#define bCCKISICancel 0x0400
#define bCCKMatchFilter 0x0200
#define bCCKEqualizer 0x0100
#define bCCKPreambleDetect 0x800000
#define bCCKFastFalseCCA 0x400000
#define bCCKChEstStart 0x300000
#define bCCKCCACount 0x080000
#define bCCKcs_lim 0x070000
#define bCCKBistMode 0x80000000
#define bCCKCCAMask 0x40000000
#define bCCKTxDACPhase 0x4
#define bCCKRxADCPhase 0x20000000
#define bCCKr_cp_mode0 0x0100
#define bCCKTxDCOffset 0xf0
#define bCCKRxDCOffset 0xf
#define bCCKCCAMode 0xc000
#define bCCKFalseCS_lim 0x3f00
#define bCCKCS_ratio 0xc00000
#define bCCKCorgBit_sel 0x300000
#define bCCKPD_lim 0x0f0000
#define bCCKNewCCA 0x80000000
#define bCCKRxHPofIG 0x8000
#define bCCKRxIG 0x7f00
#define bCCKLNAPolarity 0x800000
#define bCCKRx1stGain 0x7f0000
#define bCCKRFExtend 0x20000000
#define bCCKRxAGCSatLevel 0x1f000000
#define bCCKRxAGCSatCount 0xe0
#define bCCKRxRFSettle 0x1f
#define bCCKFixedRxAGC 0x8000
#define bCCKAntennaPolarity 0x2000
#define bCCKTxFilterType 0x0c00
#define bCCKRxAGCReportType 0x0300
#define bCCKRxDAGCEn 0x80000000
#define bCCKRxDAGCPeriod 0x20000000
#define bCCKRxDAGCSatLevel 0x1f000000
#define bCCKTimingRecovery 0x800000
#define bCCKTxC0 0x3f0000
#define bCCKTxC1 0x3f000000
#define bCCKTxC2 0x3f
#define bCCKTxC3 0x3f00
#define bCCKTxC4 0x3f0000
#define bCCKTxC5 0x3f000000
#define bCCKTxC6 0x3f
#define bCCKTxC7 0x3f00
#define bCCKDebugPort 0xff0000
#define bCCKDACDebug 0x0f000000
#define bCCKFalseAlarmEnable 0x8000
#define bCCKFalseAlarmRead 0x4000
#define bCCKTRSSI 0x7f
#define bCCKRxAGCReport 0xfe
#define bCCKRxReport_AntSel 0x80000000
#define bCCKRxReport_MFOff 0x40000000
#define bCCKRxRxReport_SQLoss 0x20000000
#define bCCKRxReport_Pktloss 0x10000000
#define bCCKRxReport_Lockedbit 0x08000000
#define bCCKRxReport_RateError 0x04000000
#define bCCKRxReport_RxRate 0x03000000
#define bCCKRxFACounterLower 0xff
#define bCCKRxFACounterUpper 0xff000000
#define bCCKRxHPAGCStart 0xe000
#define bCCKRxHPAGCFinal 0x1c00
#define bCCKRxFalseAlarmEnable 0x8000
#define bCCKFACounterFreeze 0x4000
#define bCCKTxPathSel 0x10000000
#define bCCKDefaultRxPath 0xc000000
#define bCCKOptionRxPath 0x3000000
#define bNumOfSTF 0x3
#define bShift_L 0xc0
#define bGI_TH 0xc
#define bRxPathA 0x1
#define bRxPathB 0x2
#define bRxPathC 0x4
#define bRxPathD 0x8
#define bTxPathA 0x1
#define bTxPathB 0x2
#define bTxPathC 0x4
#define bTxPathD 0x8
#define bTRSSIFreq 0x200
#define bADCBackoff 0x3000
#define bDFIRBackoff 0xc000
#define bTRSSILatchPhase 0x10000
#define bRxIDCOffset 0xff
#define bRxQDCOffset 0xff00
#define bRxDFIRMode 0x1800000
#define bRxDCNFType 0xe000000
#define bRXIQImb_A 0x3ff
#define bRXIQImb_B 0xfc00
#define bRXIQImb_C 0x3f0000
#define bRXIQImb_D 0xffc00000
#define bDC_dc_Notch 0x60000
#define bRxNBINotch 0x1f000000
#define bPD_TH 0xf
#define bPD_TH_Opt2 0xc000
#define bPWED_TH 0x700
#define bIfMF_Win_L 0x800
#define bPD_Option 0x1000
#define bMF_Win_L 0xe000
#define bBW_Search_L 0x30000
#define bwin_enh_L 0xc0000
#define bBW_TH 0x700000
#define bED_TH2 0x3800000
#define bBW_option 0x4000000
#define bRatio_TH 0x18000000
#define bWindow_L 0xe0000000
#define bSBD_Option 0x1
#define bFrame_TH 0x1c
#define bFS_Option 0x60
#define bDC_Slope_check 0x80
#define bFGuard_Counter_DC_L 0xe00
#define bFrame_Weight_Short 0x7000
#define bSub_Tune 0xe00000
#define bFrame_DC_Length 0xe000000
#define bSBD_start_offset 0x30000000
#define bFrame_TH_2 0x7
#define bFrame_GI2_TH 0x38
#define bGI2_Sync_en 0x40
#define bSarch_Short_Early 0x300
#define bSarch_Short_Late 0xc00
#define bSarch_GI2_Late 0x70000
#define bCFOAntSum 0x1
#define bCFOAcc 0x2
#define bCFOStartOffset 0xc
#define bCFOLookBack 0x70
#define bCFOSumWeight 0x80
#define bDAGCEnable 0x10000
#define bTXIQImb_A 0x3ff
#define bTXIQImb_B 0xfc00
#define bTXIQImb_C 0x3f0000
#define bTXIQImb_D 0xffc00000
#define bTxIDCOffset 0xff
#define bTxQDCOffset 0xff00
#define bTxDFIRMode 0x10000
#define bTxPesudoNoiseOn 0x4000000
#define bTxPesudoNoise_A 0xff
#define bTxPesudoNoise_B 0xff00
#define bTxPesudoNoise_C 0xff0000
#define bTxPesudoNoise_D 0xff000000
#define bCCADropOption 0x20000
#define bCCADropThres 0xfff00000
#define bEDCCA_H 0xf
#define bEDCCA_L 0xf0
#define bLambda_ED 0x300
#define bRxInitialGain 0x7f
#define bRxAntDivEn 0x80
#define bRxAGCAddressForLNA 0x7f00
#define bRxHighPowerFlow 0x8000
#define bRxAGCFreezeThres 0xc0000
#define bRxFreezeStep_AGC1 0x300000
#define bRxFreezeStep_AGC2 0xc00000
#define bRxFreezeStep_AGC3 0x3000000
#define bRxFreezeStep_AGC0 0xc000000
#define bRxRssi_Cmp_En 0x10000000
#define bRxQuickAGCEn 0x20000000
#define bRxAGCFreezeThresMode 0x40000000
#define bRxOverFlowCheckType 0x80000000
#define bRxAGCShift 0x7f
#define bTRSW_Tri_Only 0x80
#define bPowerThres 0x300
#define bRxAGCEn 0x1
#define bRxAGCTogetherEn 0x2
#define bRxAGCMin 0x4
#define bRxHP_Ini 0x7
#define bRxHP_TRLNA 0x70
#define bRxHP_RSSI 0x700
#define bRxHP_BBP1 0x7000
#define bRxHP_BBP2 0x70000
#define bRxHP_BBP3 0x700000
#define bRSSI_H 0x7f0000
#define bRSSI_Gen 0x7f000000
#define bRxSettle_TRSW 0x7
#define bRxSettle_LNA 0x38
#define bRxSettle_RSSI 0x1c0
#define bRxSettle_BBP 0xe00
#define bRxSettle_RxHP 0x7000
#define bRxSettle_AntSW_RSSI 0x38000
#define bRxSettle_AntSW 0xc0000
#define bRxProcessTime_DAGC 0x300000
#define bRxSettle_HSSI 0x400000
#define bRxProcessTime_BBPPW 0x800000
#define bRxAntennaPowerShift 0x3000000
#define bRSSITableSelect 0xc000000
#define bRxHP_Final 0x7000000
#define bRxHTSettle_BBP 0x7
#define bRxHTSettle_HSSI 0x8
#define bRxHTSettle_RxHP 0x70
#define bRxHTSettle_BBPPW 0x80
#define bRxHTSettle_Idle 0x300
#define bRxHTSettle_Reserved 0x1c00
#define bRxHTRxHPEn 0x8000
#define bRxHTAGCFreezeThres 0x30000
#define bRxHTAGCTogetherEn 0x40000
#define bRxHTAGCMin 0x80000
#define bRxHTAGCEn 0x100000
#define bRxHTDAGCEn 0x200000
#define bRxHTRxHP_BBP 0x1c00000
#define bRxHTRxHP_Final 0xe0000000
#define bRxPWRatioTH 0x3
#define bRxPWRatioEn 0x4
#define bRxMFHold 0x3800
#define bRxPD_Delay_TH1 0x38
#define bRxPD_Delay_TH2 0x1c0
#define bRxPD_DC_COUNT_MAX 0x600
#define bRxPD_Delay_TH 0x8000
#define bRxProcess_Delay 0xf0000
#define bRxSearchrange_GI2_Early 0x700000
#define bRxFrame_Guard_Counter_L 0x3800000
#define bRxSGI_Guard_L 0xc000000
#define bRxSGI_Search_L 0x30000000
#define bRxSGI_TH 0xc0000000
#define bDFSCnt0 0xff
#define bDFSCnt1 0xff00
#define bDFSFlag 0xf0000
#define bMFWeightSum 0x300000
#define bMinIdxTH 0x7f000000
#define bDAFormat 0x40000
#define bTxChEmuEnable 0x01000000
#define bTRSWIsolation_A 0x7f
#define bTRSWIsolation_B 0x7f00
#define bTRSWIsolation_C 0x7f0000
#define bTRSWIsolation_D 0x7f000000
#define bExtLNAGain 0x7c00
#define bSTBCEn 0x4
#define bAntennaMapping 0x10
#define bNss 0x20
#define bCFOAntSumD 0x200
#define bPHYCounterReset 0x8000000
#define bCFOReportGet 0x4000000
#define bOFDMContinueTx 0x10000000
#define bOFDMSingleCarrier 0x20000000
#define bOFDMSingleTone 0x40000000
#define bHTDetect 0x100
#define bCFOEn 0x10000
#define bCFOValue 0xfff00000
#define bSigTone_Re 0x3f
#define bSigTone_Im 0x7f00
#define bCounter_CCA 0xffff
#define bCounter_ParityFail 0xffff0000
#define bCounter_RateIllegal 0xffff
#define bCounter_CRC8Fail 0xffff0000
#define bCounter_MCSNoSupport 0xffff
#define bCounter_FastSync 0xffff
#define bShortCFO 0xfff
#define bShortCFOTLength 12
#define bShortCFOFLength 11
#define bLongCFO 0x7ff
#define bLongCFOTLength 11
#define bLongCFOFLength 11
#define bTailCFO 0x1fff
#define bTailCFOTLength 13
#define bTailCFOFLength 12
#define bmax_en_pwdB 0xffff
#define bCC_power_dB 0xffff0000
#define bnoise_pwdB 0xffff
#define bPowerMeasTLength 10
#define bPowerMeasFLength 3
#define bRx_HT_BW 0x1
#define bRxSC 0x6
#define bRx_HT 0x8
#define bNB_intf_det_on 0x1
#define bIntf_win_len_cfg 0x30
#define bNB_Intf_TH_cfg 0x1c0
#define bRFGain 0x3f
#define bTableSel 0x40
#define bTRSW 0x80
#define bRxSNR_A 0xff
#define bRxSNR_B 0xff00
#define bRxSNR_C 0xff0000
#define bRxSNR_D 0xff000000
#define bSNREVMTLength 8
#define bSNREVMFLength 1
#define bCSI1st 0xff
#define bCSI2nd 0xff00
#define bRxEVM1st 0xff0000
#define bRxEVM2nd 0xff000000
#define bSIGEVM 0xff
#define bPWDB 0xff00
#define bSGIEN 0x10000
#define bSFactorQAM1 0xf
#define bSFactorQAM2 0xf0
#define bSFactorQAM3 0xf00
#define bSFactorQAM4 0xf000
#define bSFactorQAM5 0xf0000
#define bSFactorQAM6 0xf0000
#define bSFactorQAM7 0xf00000
#define bSFactorQAM8 0xf000000
#define bSFactorQAM9 0xf0000000
#define bCSIScheme 0x100000
#define bNoiseLvlTopSet 0x3
#define bChSmooth 0x4
#define bChSmoothCfg1 0x38
#define bChSmoothCfg2 0x1c0
#define bChSmoothCfg3 0xe00
#define bChSmoothCfg4 0x7000
#define bMRCMode 0x800000
#define bTHEVMCfg 0x7000000
#define bLoopFitType 0x1
#define bUpdCFO 0x40
#define bUpdCFOOffData 0x80
#define bAdvUpdCFO 0x100
#define bAdvTimeCtrl 0x800
#define bUpdClko 0x1000
#define bFC 0x6000
#define bTrackingMode 0x8000
#define bPhCmpEnable 0x10000
#define bUpdClkoLTF 0x20000
#define bComChCFO 0x40000
#define bCSIEstiMode 0x80000
#define bAdvUpdEqz 0x100000
#define bUChCfg 0x7000000
#define bUpdEqz 0x8000000
#define bTxAGCRate18_06 0x7f7f7f7f
#define bTxAGCRate54_24 0x7f7f7f7f
#define bTxAGCRateMCS32 0x7f
#define bTxAGCRateCCK 0x7f00
#define bTxAGCRateMCS3_MCS0 0x7f7f7f7f
#define bTxAGCRateMCS7_MCS4 0x7f7f7f7f
#define bTxAGCRateMCS11_MCS8 0x7f7f7f7f
#define bTxAGCRateMCS15_MCS12 0x7f7f7f7f
#define bRxPesudoNoiseOn 0x20000000
#define bRxPesudoNoise_A 0xff
#define bRxPesudoNoise_B 0xff00
#define bRxPesudoNoise_C 0xff0000
#define bRxPesudoNoise_D 0xff000000
#define bPesudoNoiseState_A 0xffff
#define bPesudoNoiseState_B 0xffff0000
#define bPesudoNoiseState_C 0xffff
#define bPesudoNoiseState_D 0xffff0000
#define bZebra1_HSSIEnable 0x8
#define bZebra1_TRxControl 0xc00
#define bZebra1_TRxGainSetting 0x07f
#define bZebra1_RxCorner 0xc00
#define bZebra1_TxChargePump 0x38
#define bZebra1_RxChargePump 0x7
#define bZebra1_ChannelNum 0xf80
#define bZebra1_TxLPFBW 0x400
#define bZebra1_RxLPFBW 0x600
#define bRTL8256RegModeCtrl1 0x100
#define bRTL8256RegModeCtrl0 0x40
#define bRTL8256_TxLPFBW 0x18
#define bRTL8256_RxLPFBW 0x600
#define bRTL8258_TxLPFBW 0xc
#define bRTL8258_RxLPFBW 0xc00
#define bRTL8258_RSSILPFBW 0xc0
#define bByte0 0x1
#define bByte1 0x2
#define bByte2 0x4
#define bByte3 0x8
#define bWord0 0x3
#define bWord1 0xc
#define bDWord 0xf
#define bMaskByte0 0xff
#define bMaskByte1 0xff00
#define bMaskByte2 0xff0000
#define bMaskByte3 0xff000000
#define bMaskHWord 0xffff0000
#define bMaskLWord 0x0000ffff
#define bMaskDWord 0xffffffff
#define bMask12Bits 0xfff
#define bEnable 0x1
#define bDisable 0x0
#define LeftAntenna 0x0
#define RightAntenna 0x1
#define tCheckTxStatus 500
#define tUpdateRxCounter 100
#define rateCCK 0
#define rateOFDM 1
#define rateHT 2
#define bPMAC_End 0x1ff
#define bFPGAPHY0_End 0x8ff
#define bFPGAPHY1_End 0x9ff
#define bCCKPHY0_End 0xaff
#define bOFDMPHY0_End 0xcff
#define bOFDMPHY1_End 0xdff
#define bPMACControl 0x0
#define bWMACControl 0x1
#define bWNICControl 0x2
#define PathA 0x0
#define PathB 0x1
#define PathC 0x2
#define PathD 0x3
#define rRTL8256RxMixerPole 0xb
#define bZebraRxMixerPole 0x6
#define rRTL8256TxBBOPBias 0x9
#define bRTL8256TxBBOPBias 0x400
#define rRTL8256TxBBBW 19
#define bRTL8256TxBBBW 0x18
#endif

View file

@ -0,0 +1,160 @@
What this layer should do
- It mantain the old mechanism as alternative, so the
ipw2100 driver works with really few changes.
- Encapsulate / Decapsulate rtllib packet
- Handle fragmentation
- Optionally provide an alterantive mechanism for netif queue stop/wake,
so that the rtllib layer will pass one fragment per time instead of
one txb struct per time. so the driver can stop the queue in the middle
of a packet.
- Provide two different TX interfaces for cards that can handle management
frames on one HW queue, and data on another, and for cards that have only
one HW queue (the latter untested and very, very rough).
- Optionally provide the logic for handling IBSS/MASTER/MONITOR/BSS modes
and for the channel, essid and wap get/set wireless extension requests.
so that the driver has only to change channel when the ieee stack tell it.
- Optionally provide a scanning mechanism so that the driver has not to
worry about this, just implement the set channel calback and pass
frames to the upper layer
- Optionally provide the bss client protocol handshaking (just with open
authentication)
- Optionally provide the probe request send mechanism
- Optionally provide the bss master mode logic to handle association
protocol (only open authentication) and probe responses.
- SW wep encryption (with open authentication)
- It collects some stats
- It provides beacons to the card when it ask for them
What this layer doesn't do (yet)
- Perform shared authentication
- Have full support for master mode (the AP should loop back in the air
frames from an associated client to another. This could be done easily
with few lines of code, and it is done in my previous version of the
stach, but a table of association must be keept and a disassociation
policy must be decided and implemented.
- Handle cleanly the full ieee 802.11 protocol. In AP mode it never
disassociate clients, and it is really prone to always allow access.
In bss client mode it is a bit rough with AP deauth and disassoc requests.
- It has not any entry point to view the collected stats.
- Altought it takes care of the card supported rates in the management frame
it sends, support for rate changing on TXed packet is not complete.
- Give up once associated in bss client mode (it never detect a
signal loss condition to disassociate and restart scanning)
- Provide a mechanism for enabling the TX in monitor mode, so
userspace programs can TX raw packets.
- Provide a mechanism for cards that need that the SW take care of beacon
TX completely, in sense that the SW has to enqueue by itself beacons
to the card so it TX them (if any...)
APIs
Callback functions in the original stack has been mantained.
following has been added (from rtllib.h)
/* Softmac-generated frames (mamagement) are TXed via this
* callback if the flag IEEE_SOFTMAC_SINGLE_QUEUE is
* not set. As some cards may have different HW queues that
* one might want to use for data and management frames
* the option to have two callbacks might be useful.
* This fucntion can't sleep.
*/
int (*softmac_hard_start_xmit)(struct sk_buff *skb,
struct net_device *dev);
/* used instead of hard_start_xmit (not softmac_hard_start_xmit)
* if the IEEE_SOFTMAC_TX_QUEUE feature is used to TX data
* frames. I the option IEEE_SOFTMAC_SINGLE_QUEUE is also set
* then also management frames are sent via this callback.
* This function can't sleep.
*/
void (*softmac_data_hard_start_xmit)(struct sk_buff *skb,
struct net_device *dev);
/* stops the HW queue for DATA frames. Useful to avoid
* waste time to TX data frame when we are reassociating
* This function can sleep.
*/
void (*data_hard_stop)(struct net_device *dev);
/* OK this is complementar to data_poll_hard_stop */
void (*data_hard_resume)(struct net_device *dev);
/* ask to the driver to retune the radio .
* This function can sleep. the driver should ensure
* the radio has been swithced before return.
*/
void (*set_chan)(struct net_device *dev,short ch);
/* These are not used if the ieee stack takes care of
* scanning (IEEE_SOFTMAC_SCAN feature set).
* In this case only the set_chan is used.
*
* The syncro version is similar to the start_scan but
* does not return until all channels has been scanned.
* this is called in user context and should sleep,
* it is called in a work_queue when swithcing to ad-hoc mode
* or in behalf of iwlist scan when the card is associated
* and root user ask for a scan.
* the fucntion stop_scan should stop both the syncro and
* background scanning and can sleep.
* The fucntion start_scan should initiate the background
* scanning and can't sleep.
*/
void (*scan_syncro)(struct net_device *dev);
void (*start_scan)(struct net_device *dev);
void (*stop_scan)(struct net_device *dev);
/* indicate the driver that the link state is changed
* for example it may indicate the card is associated now.
* Driver might be interested in this to apply RX filter
* rules or simply light the LINK led
*/
void (*link_change)(struct net_device *dev);
Functions hard_data_[resume/stop] are optional and should not be used
if the driver decides to uses data+management frames enqueue in a
single HQ queue (thus using just the softmac_hard_data_start_xmit
callback).
Function that the driver can use are:
rtllib_get_beacon - this is called by the driver when
the HW needs a beacon.
rtllib_softmac_start_protocol - this should normally be called in the
driver open function
rtllib_softmac_stop_protocol - the opposite of the above
rtllib_wake_queue - this is similar to netif_wake_queue
rtllib_reset_queue - this throw away fragments pending(if any)
rtllib_stop_queue - this is similar to netif_stop_queue
known BUGS:
- When performing syncro scan (possiblily when swithcing to ad-hoc mode
and when running iwlist scan when associated) there is still an odd
behaviour.. I have not looked in this more accurately (yet).
locking:
locking is done by means of three structures.
1- ieee->lock (by means of spin_[un]lock_irq[save/restore]
2- ieee->wx_sem
3- ieee->scan_sem
the lock 1 is what protect most of the critical sections in the ieee stack.
the lock 2 is used to avoid that more than one of the SET wireless extension
handlers (as well as start/stop protocol function) are running at the same time.
the lock 1 is used when we need to modify or read the shared data in the wx handlers.
In other words the lock 2 will prevent one SET action will run across another SET
action (by make sleep the 2nd one) but allow GET actions, while the lock 1
make atomic those little shared data access in both GET and SET operation.
So get operation will be never be delayed really: they will never sleep..
Furthermore in the top of some SET operations a flag is set before acquiring
the lock. This is an help to make the previous running SET operation to
finish faster if needed (just in case the second one will totally undo the
first, so there is not need to complete the 1st really.. ).
The background scanning mechaninsm is protected by the lock 1 except for the
workqueue. this wq is here just to let the set_chan callback sleep (I thinked it
might be appreciated by USB network card driver developer). In this case the lock 3
take its turn.
Thus the stop function needs both the locks.
Funny in the syncro scan the lock 2 play its role (as both the syncro_scan
function and the stop scan function are called with this semaphore held).

View file

@ -1,3 +1,21 @@
/******************************************************************************
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
******************************************************************************/
#ifndef _BATYPE_H_
#define _BATYPE_H_
@ -18,14 +36,6 @@
#define DELBA_REASON_END_BA 37
#define DELBA_REASON_UNKNOWN_BA 38
#define DELBA_REASON_TIMEOUT 39
/* whether need define BA Action frames here?
struct ieee80211_ADDBA_Req{
struct ieee80211_header_data header;
u8 category;
u8
} __attribute__ ((packed));
*/
//Is this need?I put here just to make it easier to define structure BA_RECORD //WB
typedef union _SEQUENCE_CONTROL{
u16 ShortData;
struct
@ -65,5 +75,4 @@ typedef struct _BA_RECORD {
SEQUENCE_CONTROL BaStartSeqCtrl;
} BA_RECORD, *PBA_RECORD;
#endif //end _BATYPE_H_
#endif

View file

@ -0,0 +1,618 @@
/******************************************************************************
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
******************************************************************************/
#include "rtllib.h"
#include "rtl819x_BA.h"
#include "rtl_core.h"
#ifdef RTK_DMP_PLATFORM
#include <linux/usb_setting.h>
#endif
void ActivateBAEntry(struct rtllib_device* ieee, PBA_RECORD pBA, u16 Time)
{
pBA->bValid = true;
if (Time != 0)
mod_timer(&pBA->Timer, jiffies + MSECS(Time));
}
void DeActivateBAEntry( struct rtllib_device* ieee, PBA_RECORD pBA)
{
pBA->bValid = false;
del_timer_sync(&pBA->Timer);
}
u8 TxTsDeleteBA( struct rtllib_device* ieee, PTX_TS_RECORD pTxTs)
{
PBA_RECORD pAdmittedBa = &pTxTs->TxAdmittedBARecord;
PBA_RECORD pPendingBa = &pTxTs->TxPendingBARecord;
u8 bSendDELBA = false;
if (pPendingBa->bValid)
{
DeActivateBAEntry(ieee, pPendingBa);
bSendDELBA = true;
}
if (pAdmittedBa->bValid)
{
DeActivateBAEntry(ieee, pAdmittedBa);
bSendDELBA = true;
}
return bSendDELBA;
}
u8 RxTsDeleteBA( struct rtllib_device* ieee, PRX_TS_RECORD pRxTs)
{
PBA_RECORD pBa = &pRxTs->RxAdmittedBARecord;
u8 bSendDELBA = false;
if (pBa->bValid)
{
DeActivateBAEntry(ieee, pBa);
bSendDELBA = true;
}
return bSendDELBA;
}
void ResetBaEntry( PBA_RECORD pBA)
{
pBA->bValid = false;
pBA->BaParamSet.shortData = 0;
pBA->BaTimeoutValue = 0;
pBA->DialogToken = 0;
pBA->BaStartSeqCtrl.ShortData = 0;
}
static struct sk_buff* rtllib_ADDBA(struct rtllib_device* ieee, u8* Dst, PBA_RECORD pBA, u16 StatusCode, u8 type)
{
struct sk_buff *skb = NULL;
struct rtllib_hdr_3addr* BAReq = NULL;
u8* tag = NULL;
u16 tmp = 0;
u16 len = ieee->tx_headroom + 9;
RTLLIB_DEBUG(RTLLIB_DL_TRACE | RTLLIB_DL_BA, "========>%s(), frame(%d) sentd to:"MAC_FMT", ieee->dev:%p\n", __func__, type, MAC_ARG(Dst), ieee->dev);
if (pBA == NULL||ieee == NULL)
{
RTLLIB_DEBUG(RTLLIB_DL_ERR, "pBA(%p) is NULL or ieee(%p) is NULL\n", pBA, ieee);
return NULL;
}
#ifdef USB_USE_ALIGNMENT
u32 Tmpaddr=0;
int alignment=0;
skb = dev_alloc_skb(len + sizeof( struct rtllib_hdr_3addr) + USB_512B_ALIGNMENT_SIZE);
#else
skb = dev_alloc_skb(len + sizeof( struct rtllib_hdr_3addr));
#endif
if (skb == NULL)
{
RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't alloc skb for ADDBA_REQ\n");
return NULL;
}
memset(skb->data, 0, sizeof( struct rtllib_hdr_3addr));
#ifdef USB_USE_ALIGNMENT
Tmpaddr = (u32)skb->data;
alignment = Tmpaddr & 0x1ff;
skb_reserve(skb,(USB_512B_ALIGNMENT_SIZE - alignment));
#endif
skb_reserve(skb, ieee->tx_headroom);
BAReq = ( struct rtllib_hdr_3addr *) skb_put(skb,sizeof( struct rtllib_hdr_3addr));
memcpy(BAReq->addr1, Dst, ETH_ALEN);
memcpy(BAReq->addr2, ieee->dev->dev_addr, ETH_ALEN);
memcpy(BAReq->addr3, ieee->current_network.bssid, ETH_ALEN);
BAReq->frame_ctl = cpu_to_le16(RTLLIB_STYPE_MANAGE_ACT);
tag = (u8*)skb_put(skb, 9);
*tag ++= ACT_CAT_BA;
*tag ++= type;
*tag ++= pBA->DialogToken;
if (ACT_ADDBARSP == type)
{
RT_TRACE(COMP_DBG, "====>to send ADDBARSP\n");
tmp = cpu_to_le16(StatusCode);
memcpy(tag, (u8*)&tmp, 2);
tag += 2;
}
tmp = cpu_to_le16(pBA->BaParamSet.shortData);
memcpy(tag, (u8*)&tmp, 2);
tag += 2;
tmp = cpu_to_le16(pBA->BaTimeoutValue);
memcpy(tag, (u8*)&tmp, 2);
tag += 2;
if (ACT_ADDBAREQ == type)
{
memcpy(tag,(u8*)&(pBA->BaStartSeqCtrl), 2);
tag += 2;
}
RTLLIB_DEBUG_DATA(RTLLIB_DL_DATA|RTLLIB_DL_BA, skb->data, skb->len);
return skb;
}
static struct sk_buff* rtllib_DELBA(
struct rtllib_device* ieee,
u8* dst,
PBA_RECORD pBA,
TR_SELECT TxRxSelect,
u16 ReasonCode
)
{
DELBA_PARAM_SET DelbaParamSet;
struct sk_buff *skb = NULL;
struct rtllib_hdr_3addr* Delba = NULL;
u8* tag = NULL;
u16 tmp = 0;
u16 len = 6 + ieee->tx_headroom;
if (net_ratelimit())
RTLLIB_DEBUG(RTLLIB_DL_TRACE | RTLLIB_DL_BA, "========>%s(), ReasonCode(%d) sentd to:"MAC_FMT"\n", __func__, ReasonCode, MAC_ARG(dst));
memset(&DelbaParamSet, 0, 2);
DelbaParamSet.field.Initiator = (TxRxSelect==TX_DIR)?1:0;
DelbaParamSet.field.TID = pBA->BaParamSet.field.TID;
#ifdef USB_USE_ALIGNMENT
u32 Tmpaddr=0;
int alignment=0;
skb = dev_alloc_skb(len + sizeof( struct rtllib_hdr_3addr) + USB_512B_ALIGNMENT_SIZE);
#else
skb = dev_alloc_skb(len + sizeof( struct rtllib_hdr_3addr));
#endif
if (skb == NULL)
{
RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't alloc skb for ADDBA_REQ\n");
return NULL;
}
#ifdef USB_USE_ALIGNMENT
Tmpaddr = (u32)skb->data;
alignment = Tmpaddr & 0x1ff;
skb_reserve(skb,(USB_512B_ALIGNMENT_SIZE - alignment));
#endif
skb_reserve(skb, ieee->tx_headroom);
Delba = ( struct rtllib_hdr_3addr *) skb_put(skb,sizeof( struct rtllib_hdr_3addr));
memcpy(Delba->addr1, dst, ETH_ALEN);
memcpy(Delba->addr2, ieee->dev->dev_addr, ETH_ALEN);
memcpy(Delba->addr3, ieee->current_network.bssid, ETH_ALEN);
Delba->frame_ctl = cpu_to_le16(RTLLIB_STYPE_MANAGE_ACT);
tag = (u8*)skb_put(skb, 6);
*tag ++= ACT_CAT_BA;
*tag ++= ACT_DELBA;
tmp = cpu_to_le16(DelbaParamSet.shortData);
memcpy(tag, (u8*)&tmp, 2);
tag += 2;
tmp = cpu_to_le16(ReasonCode);
memcpy(tag, (u8*)&tmp, 2);
tag += 2;
RTLLIB_DEBUG_DATA(RTLLIB_DL_DATA|RTLLIB_DL_BA, skb->data, skb->len);
if (net_ratelimit())
RTLLIB_DEBUG(RTLLIB_DL_TRACE | RTLLIB_DL_BA, "<=====%s()\n", __func__);
return skb;
}
void rtllib_send_ADDBAReq(struct rtllib_device* ieee, u8* dst, PBA_RECORD pBA)
{
struct sk_buff *skb = NULL;
skb = rtllib_ADDBA(ieee, dst, pBA, 0, ACT_ADDBAREQ);
if (skb) {
RT_TRACE(COMP_DBG, "====>to send ADDBAREQ!!!!!\n");
softmac_mgmt_xmit(skb, ieee);
} else {
RTLLIB_DEBUG(RTLLIB_DL_ERR, "alloc skb error in function %s()\n", __func__);
}
return;
}
void rtllib_send_ADDBARsp(struct rtllib_device* ieee, u8* dst, PBA_RECORD pBA, u16 StatusCode)
{
struct sk_buff *skb = NULL;
skb = rtllib_ADDBA(ieee, dst, pBA, StatusCode, ACT_ADDBARSP);
if (skb)
softmac_mgmt_xmit(skb, ieee);
else
RTLLIB_DEBUG(RTLLIB_DL_ERR, "alloc skb error in function %s()\n", __func__);
return;
}
void rtllib_send_DELBA(struct rtllib_device* ieee, u8* dst, PBA_RECORD pBA, TR_SELECT TxRxSelect, u16 ReasonCode)
{
struct sk_buff *skb = NULL;
skb = rtllib_DELBA(ieee, dst, pBA, TxRxSelect, ReasonCode);
if (skb)
{
softmac_mgmt_xmit(skb, ieee);
}
else
{
RTLLIB_DEBUG(RTLLIB_DL_ERR, "alloc skb error in function %s()\n", __func__);
}
return ;
}
int rtllib_rx_ADDBAReq( struct rtllib_device* ieee, struct sk_buff *skb)
{
struct rtllib_hdr_3addr* req = NULL;
u16 rc = 0;
u8 * dst = NULL, *pDialogToken = NULL, *tag = NULL;
PBA_RECORD pBA = NULL;
PBA_PARAM_SET pBaParamSet = NULL;
u16* pBaTimeoutVal = NULL;
PSEQUENCE_CONTROL pBaStartSeqCtrl = NULL;
PRX_TS_RECORD pTS = NULL;
if (skb->len < sizeof( struct rtllib_hdr_3addr) + 9)
{
RTLLIB_DEBUG(RTLLIB_DL_ERR, " Invalid skb len in BAREQ(%d / %d)\n",(int)skb->len, (int)(sizeof( struct rtllib_hdr_3addr) + 9));
return -1;
}
RTLLIB_DEBUG_DATA(RTLLIB_DL_DATA|RTLLIB_DL_BA, skb->data, skb->len);
req = ( struct rtllib_hdr_3addr*) skb->data;
tag = (u8*)req;
dst = (u8*)(&req->addr2[0]);
tag += sizeof( struct rtllib_hdr_3addr);
pDialogToken = tag + 2;
pBaParamSet = (PBA_PARAM_SET)(tag + 3);
pBaTimeoutVal = (u16*)(tag + 5);
pBaStartSeqCtrl = (PSEQUENCE_CONTROL)(req + 7);
RT_TRACE(COMP_DBG, "====>rx ADDBAREQ from :"MAC_FMT"\n", MAC_ARG(dst));
if (ieee->current_network.qos_data.active == 0 ||
(ieee->pHTInfo->bCurrentHTSupport == false) ||
(ieee->pHTInfo->IOTAction & HT_IOT_ACT_REJECT_ADDBA_REQ)) {
rc = ADDBA_STATUS_REFUSED;
RTLLIB_DEBUG(RTLLIB_DL_ERR, "Failed to reply on ADDBA_REQ as some capability is not ready(%d, %d)\n", ieee->current_network.qos_data.active, ieee->pHTInfo->bCurrentHTSupport);
goto OnADDBAReq_Fail;
}
if (!GetTs(
ieee,
(PTS_COMMON_INFO*)(&pTS),
dst,
(u8)(pBaParamSet->field.TID),
RX_DIR,
true) )
{
rc = ADDBA_STATUS_REFUSED;
RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't get TS in %s()\n", __func__);
goto OnADDBAReq_Fail;
}
pBA = &pTS->RxAdmittedBARecord;
if (pBaParamSet->field.BAPolicy == BA_POLICY_DELAYED)
{
rc = ADDBA_STATUS_INVALID_PARAM;
RTLLIB_DEBUG(RTLLIB_DL_ERR, "BA Policy is not correct in %s()\n", __func__);
goto OnADDBAReq_Fail;
}
rtllib_FlushRxTsPendingPkts(ieee, pTS);
DeActivateBAEntry(ieee, pBA);
pBA->DialogToken = *pDialogToken;
pBA->BaParamSet = *pBaParamSet;
pBA->BaTimeoutValue = *pBaTimeoutVal;
pBA->BaStartSeqCtrl = *pBaStartSeqCtrl;
if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)||
(ieee->pHTInfo->IOTAction & HT_IOT_ACT_ALLOW_PEER_AGG_ONE_PKT))
pBA->BaParamSet.field.BufferSize = 1;
else
pBA->BaParamSet.field.BufferSize = 32;
ActivateBAEntry(ieee, pBA, 0);
rtllib_send_ADDBARsp(ieee, dst, pBA, ADDBA_STATUS_SUCCESS);
return 0;
OnADDBAReq_Fail:
{
BA_RECORD BA;
BA.BaParamSet = *pBaParamSet;
BA.BaTimeoutValue = *pBaTimeoutVal;
BA.DialogToken = *pDialogToken;
BA.BaParamSet.field.BAPolicy = BA_POLICY_IMMEDIATE;
rtllib_send_ADDBARsp(ieee, dst, &BA, rc);
return 0;
}
}
int rtllib_rx_ADDBARsp( struct rtllib_device* ieee, struct sk_buff *skb)
{
struct rtllib_hdr_3addr* rsp = NULL;
PBA_RECORD pPendingBA, pAdmittedBA;
PTX_TS_RECORD pTS = NULL;
u8* dst = NULL, *pDialogToken = NULL, *tag = NULL;
u16* pStatusCode = NULL, *pBaTimeoutVal = NULL;
PBA_PARAM_SET pBaParamSet = NULL;
u16 ReasonCode;
if (skb->len < sizeof( struct rtllib_hdr_3addr) + 9)
{
RTLLIB_DEBUG(RTLLIB_DL_ERR, " Invalid skb len in BARSP(%d / %d)\n", (int)skb->len, (int)(sizeof( struct rtllib_hdr_3addr) + 9));
return -1;
}
rsp = ( struct rtllib_hdr_3addr*)skb->data;
tag = (u8*)rsp;
dst = (u8*)(&rsp->addr2[0]);
tag += sizeof( struct rtllib_hdr_3addr);
pDialogToken = tag + 2;
pStatusCode = (u16*)(tag + 3);
pBaParamSet = (PBA_PARAM_SET)(tag + 5);
pBaTimeoutVal = (u16*)(tag + 7);
RT_TRACE(COMP_DBG, "====>rx ADDBARSP from :"MAC_FMT"\n", MAC_ARG(dst));
if (
ieee->current_network.qos_data.active == 0 ||
ieee->pHTInfo->bCurrentHTSupport == false ||
ieee->pHTInfo->bCurrentAMPDUEnable == false )
{
RTLLIB_DEBUG(RTLLIB_DL_ERR, "reject to ADDBA_RSP as some capability is not ready(%d, %d, %d)\n",ieee->current_network.qos_data.active, ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bCurrentAMPDUEnable);
ReasonCode = DELBA_REASON_UNKNOWN_BA;
goto OnADDBARsp_Reject;
}
if (!GetTs(ieee, (PTS_COMMON_INFO*)(&pTS), dst,
(u8)(pBaParamSet->field.TID), TX_DIR, false)) {
RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't get TS in %s()\n", __func__);
ReasonCode = DELBA_REASON_UNKNOWN_BA;
goto OnADDBARsp_Reject;
}
pTS->bAddBaReqInProgress = false;
pPendingBA = &pTS->TxPendingBARecord;
pAdmittedBA = &pTS->TxAdmittedBARecord;
if ((pAdmittedBA->bValid==true))
{
RTLLIB_DEBUG(RTLLIB_DL_BA, "OnADDBARsp(): Recv ADDBA Rsp. Drop because already admit it! \n");
return -1;
}
else if ((pPendingBA->bValid == false) ||(*pDialogToken != pPendingBA->DialogToken))
{
RTLLIB_DEBUG(RTLLIB_DL_ERR, "OnADDBARsp(): Recv ADDBA Rsp. BA invalid, DELBA! \n");
ReasonCode = DELBA_REASON_UNKNOWN_BA;
goto OnADDBARsp_Reject;
}
else
{
RTLLIB_DEBUG(RTLLIB_DL_BA, "OnADDBARsp(): Recv ADDBA Rsp. BA is admitted! Status code:%X\n", *pStatusCode);
DeActivateBAEntry(ieee, pPendingBA);
}
if (*pStatusCode == ADDBA_STATUS_SUCCESS)
{
if (pBaParamSet->field.BAPolicy == BA_POLICY_DELAYED)
{
pTS->bAddBaReqDelayed = true;
DeActivateBAEntry(ieee, pAdmittedBA);
ReasonCode = DELBA_REASON_END_BA;
goto OnADDBARsp_Reject;
}
pAdmittedBA->DialogToken = *pDialogToken;
pAdmittedBA->BaTimeoutValue = *pBaTimeoutVal;
pAdmittedBA->BaStartSeqCtrl = pPendingBA->BaStartSeqCtrl;
pAdmittedBA->BaParamSet = *pBaParamSet;
DeActivateBAEntry(ieee, pAdmittedBA);
ActivateBAEntry(ieee, pAdmittedBA, *pBaTimeoutVal);
} else {
pTS->bAddBaReqDelayed = true;
pTS->bDisable_AddBa = true;
ReasonCode = DELBA_REASON_END_BA;
goto OnADDBARsp_Reject;
}
return 0;
OnADDBARsp_Reject:
{
BA_RECORD BA;
BA.BaParamSet = *pBaParamSet;
rtllib_send_DELBA(ieee, dst, &BA, TX_DIR, ReasonCode);
return 0;
}
}
int rtllib_rx_DELBA(struct rtllib_device* ieee,struct sk_buff *skb)
{
struct rtllib_hdr_3addr* delba = NULL;
PDELBA_PARAM_SET pDelBaParamSet = NULL;
u16* pReasonCode = NULL;
u8* dst = NULL;
if (skb->len < sizeof( struct rtllib_hdr_3addr) + 6)
{
RTLLIB_DEBUG(RTLLIB_DL_ERR, " Invalid skb len in DELBA(%d / %d)\n", (int)skb->len, (int)(sizeof( struct rtllib_hdr_3addr) + 6));
return -1;
}
if (
ieee->current_network.qos_data.active == 0 ||
ieee->pHTInfo->bCurrentHTSupport == false )
{
RTLLIB_DEBUG(RTLLIB_DL_ERR, "received DELBA while QOS or HT is not supported(%d, %d)\n",ieee->current_network.qos_data.active, ieee->pHTInfo->bCurrentHTSupport);
return -1;
}
RTLLIB_DEBUG_DATA(RTLLIB_DL_DATA|RTLLIB_DL_BA, skb->data, skb->len);
delba = ( struct rtllib_hdr_3addr*)skb->data;
dst = (u8*)(&delba->addr2[0]);
delba += sizeof( struct rtllib_hdr_3addr);
pDelBaParamSet = (PDELBA_PARAM_SET)(delba+2);
pReasonCode = (u16*)(delba+4);
if (pDelBaParamSet->field.Initiator == 1)
{
PRX_TS_RECORD pRxTs;
if ( !GetTs(
ieee,
(PTS_COMMON_INFO*)&pRxTs,
dst,
(u8)pDelBaParamSet->field.TID,
RX_DIR,
false) )
{
RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't get TS for RXTS in %s().dst:"MAC_FMT" TID:%d\n", __func__, MAC_ARG(dst), (u8)pDelBaParamSet->field.TID);
return -1;
}
RxTsDeleteBA(ieee, pRxTs);
}
else
{
PTX_TS_RECORD pTxTs;
if (!GetTs(
ieee,
(PTS_COMMON_INFO*)&pTxTs,
dst,
(u8)pDelBaParamSet->field.TID,
TX_DIR,
false) )
{
RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't get TS for TXTS in %s()\n", __func__);
return -1;
}
pTxTs->bUsingBa = false;
pTxTs->bAddBaReqInProgress = false;
pTxTs->bAddBaReqDelayed = false;
del_timer_sync(&pTxTs->TsAddBaTimer);
TxTsDeleteBA(ieee, pTxTs);
}
return 0;
}
void
TsInitAddBA(
struct rtllib_device* ieee,
PTX_TS_RECORD pTS,
u8 Policy,
u8 bOverwritePending
)
{
PBA_RECORD pBA = &pTS->TxPendingBARecord;
if (pBA->bValid==true && bOverwritePending==false)
return;
DeActivateBAEntry(ieee, pBA);
pBA->DialogToken++;
pBA->BaParamSet.field.AMSDU_Support = 0;
pBA->BaParamSet.field.BAPolicy = Policy;
pBA->BaParamSet.field.TID = pTS->TsCommonInfo.TSpec.f.TSInfo.field.ucTSID;
pBA->BaParamSet.field.BufferSize = 32;
pBA->BaTimeoutValue = 0;
pBA->BaStartSeqCtrl.field.SeqNum = (pTS->TxCurSeq + 3) % 4096;
ActivateBAEntry(ieee, pBA, BA_SETUP_TIMEOUT);
rtllib_send_ADDBAReq(ieee, pTS->TsCommonInfo.Addr, pBA);
}
void
TsInitDelBA( struct rtllib_device* ieee, PTS_COMMON_INFO pTsCommonInfo, TR_SELECT TxRxSelect)
{
if (TxRxSelect == TX_DIR)
{
PTX_TS_RECORD pTxTs = (PTX_TS_RECORD)pTsCommonInfo;
if (TxTsDeleteBA(ieee, pTxTs))
rtllib_send_DELBA(
ieee,
pTsCommonInfo->Addr,
(pTxTs->TxAdmittedBARecord.bValid)?(&pTxTs->TxAdmittedBARecord):(&pTxTs->TxPendingBARecord),
TxRxSelect,
DELBA_REASON_END_BA);
}
else if (TxRxSelect == RX_DIR)
{
PRX_TS_RECORD pRxTs = (PRX_TS_RECORD)pTsCommonInfo;
if (RxTsDeleteBA(ieee, pRxTs))
rtllib_send_DELBA(
ieee,
pTsCommonInfo->Addr,
&pRxTs->RxAdmittedBARecord,
TxRxSelect,
DELBA_REASON_END_BA );
}
}
void BaSetupTimeOut(unsigned long data)
{
PTX_TS_RECORD pTxTs = (PTX_TS_RECORD)data;
pTxTs->bAddBaReqInProgress = false;
pTxTs->bAddBaReqDelayed = true;
pTxTs->TxPendingBARecord.bValid = false;
}
void TxBaInactTimeout(unsigned long data)
{
PTX_TS_RECORD pTxTs = (PTX_TS_RECORD)data;
struct rtllib_device *ieee = container_of(pTxTs, struct rtllib_device, TxTsRecord[pTxTs->num]);
TxTsDeleteBA(ieee, pTxTs);
rtllib_send_DELBA(
ieee,
pTxTs->TsCommonInfo.Addr,
&pTxTs->TxAdmittedBARecord,
TX_DIR,
DELBA_REASON_TIMEOUT);
}
void RxBaInactTimeout(unsigned long data)
{
PRX_TS_RECORD pRxTs = (PRX_TS_RECORD)data;
struct rtllib_device *ieee = container_of(pRxTs, struct rtllib_device, RxTsRecord[pRxTs->num]);
RxTsDeleteBA(ieee, pRxTs);
rtllib_send_DELBA(
ieee,
pRxTs->TsCommonInfo.Addr,
&pRxTs->RxAdmittedBARecord,
RX_DIR,
DELBA_REASON_TIMEOUT);
return ;
}

View file

@ -1,31 +1,35 @@
/******************************************************************************
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
******************************************************************************/
#ifndef _RTL819XU_HTTYPE_H_
#define _RTL819XU_HTTYPE_H_
//------------------------------------------------------------
// The HT Capability element is present in beacons, association request,
// reassociation request and probe response frames
//------------------------------------------------------------
//
// Operation mode value
//
#define HT_OPMODE_NO_PROTECT 0
#define HT_OPMODE_OPTIONAL 1
#define HT_OPMODE_40MHZ_PROTECT 2
#define HT_OPMODE_MIXED 3
//
// MIMO Power Save Setings
//
#define MIMO_PS_STATIC 0
#define MIMO_PS_DYNAMIC 1
#define MIMO_PS_NOLIMIT 3
//
// There should be 128 bits to cover all of the MCS rates. However, since
// 8190 does not support too much rates, one integer is quite enough.
//
#define sHTCLng 4
@ -52,21 +56,13 @@ typedef enum _HT_MCS_RATE{
HT_MCS13 = 0x00002000,
HT_MCS14 = 0x00004000,
HT_MCS15 = 0x00008000,
// Do not define MCS32 here although 8190 support MCS32
}HT_MCS_RATE,*PHT_MCS_RATE;
//
// Represent Channel Width in HT Capabilities
//
typedef enum _HT_CHANNEL_WIDTH{
HT_CHANNEL_WIDTH_20 = 0,
HT_CHANNEL_WIDTH_20_40 = 1,
}HT_CHANNEL_WIDTH, *PHT_CHANNEL_WIDTH;
//
// Represent Extension Channel Offset in HT Capabilities
// This is available only in 40Mhz mode.
//
typedef enum _HT_EXTCHNL_OFFSET{
HT_EXTCHNL_OFFSET_NO_EXT = 0,
HT_EXTCHNL_OFFSET_UPPER = 1,
@ -75,15 +71,14 @@ typedef enum _HT_EXTCHNL_OFFSET{
}HT_EXTCHNL_OFFSET, *PHT_EXTCHNL_OFFSET;
typedef enum _CHNLOP{
CHNLOP_NONE = 0, // No Action now
CHNLOP_SCAN = 1, // Scan in progress
CHNLOP_SWBW = 2, // Bandwidth switching in progress
CHNLOP_SWCHNL = 3, // Software Channel switching in progress
CHNLOP_NONE = 0,
CHNLOP_SCAN = 1,
CHNLOP_SWBW = 2,
CHNLOP_SWCHNL = 3,
} CHNLOP, *PCHNLOP;
// Determine if the Channel Operation is in progress
#define CHHLOP_IN_PROGRESS(_pHTInfo) \
((_pHTInfo)->ChnlOp > CHNLOP_NONE) ? TRUE : FALSE
((_pHTInfo)->ChnlOp > CHNLOP_NONE) ? true : false
/*
typedef union _HT_CAPABILITY{
@ -133,7 +128,6 @@ typedef enum _HT_ACTION{
} HT_ACTION, *PHT_ACTION;
/* 2007/06/07 MH Define sub-carrier mode for 40MHZ. */
typedef enum _HT_Bandwidth_40MHZ_Sub_Carrier{
SC_MODE_DUPLICATE = 0,
SC_MODE_LOWER = 1,
@ -143,7 +137,6 @@ typedef enum _HT_Bandwidth_40MHZ_Sub_Carrier{
typedef struct _HT_CAPABILITY_ELE{
//HT capability info
u8 AdvCoding:1;
u8 ChlWidth:1;
u8 MimoPwrSave:2;
@ -159,30 +152,21 @@ typedef struct _HT_CAPABILITY_ELE{
u8 Rsvd1:1;
u8 LSigTxopProtect:1;
//MAC HT parameters info
u8 MaxRxAMPDUFactor:2;
u8 MPDUDensity:3;
u8 Rsvd2:3;
//Supported MCS set
u8 MCS[16];
//Extended HT Capability Info
u16 ExtHTCapInfo;
//TXBF Capabilities
u8 TxBFCap[4];
//Antenna Selection Capabilities
u8 ASCap;
} __attribute__ ((packed)) HT_CAPABILITY_ELE, *PHT_CAPABILITY_ELE;
//------------------------------------------------------------
// The HT Information element is present in beacons
// Only AP is required to include this element
//------------------------------------------------------------
typedef struct _HT_INFORMATION_ELE{
u8 ControlChl;
@ -211,10 +195,6 @@ typedef struct _HT_INFORMATION_ELE{
u8 BasicMSC[16];
} __attribute__ ((packed)) HT_INFORMATION_ELE, *PHT_INFORMATION_ELE;
//
// MIMO Power Save control field.
// This is appear in MIMO Power Save Action Frame
//
typedef struct _MIMOPS_CTRL{
u8 MimoPsEnable:1;
u8 MimoPsMode:1;
@ -232,62 +212,49 @@ typedef enum _HT_AGGRE_MODE_E{
HT_AGG_FORCE_DISABLE = 2,
}HT_AGGRE_MODE_E, *PHT_AGGRE_MODE_E;
//------------------------------------------------------------
// The Data structure is used to keep HT related variables when card is
// configured as non-AP STA mode. **Note** Current_xxx should be set
// to default value in HTInitializeHTInfo()
//------------------------------------------------------------
typedef struct _RT_HIGH_THROUGHPUT{
u8 bEnableHT;
u8 bCurrentHTSupport;
u8 bRegBW40MHz; // Tx 40MHz channel capablity
u8 bCurBW40MHz; // Tx 40MHz channel capability
u8 bRegBW40MHz;
u8 bCurBW40MHz;
u8 bRegShortGI40MHz; // Tx Short GI for 40Mhz
u8 bCurShortGI40MHz; // Tx Short GI for 40MHz
u8 bRegShortGI40MHz;
u8 bCurShortGI40MHz;
u8 bRegShortGI20MHz; // Tx Short GI for 20MHz
u8 bCurShortGI20MHz; // Tx Short GI for 20MHz
u8 bRegShortGI20MHz;
u8 bCurShortGI20MHz;
u8 bRegSuppCCK; // Tx CCK rate capability
u8 bCurSuppCCK; // Tx CCK rate capability
u8 bRegSuppCCK;
u8 bCurSuppCCK;
// 802.11n spec version for "peer"
HT_SPEC_VER ePeerHTSpecVer;
// HT related information for "Self"
HT_CAPABILITY_ELE SelfHTCap; // This is HT cap element sent to peer STA, which also indicate HT Rx capabilities.
HT_INFORMATION_ELE SelfHTInfo; // This is HT info element sent to peer STA, which also indicate HT Rx capabilities.
HT_CAPABILITY_ELE SelfHTCap;
HT_INFORMATION_ELE SelfHTInfo;
// HT related information for "Peer"
u8 PeerHTCapBuf[32];
u8 PeerHTInfoBuf[32];
// A-MSDU related
u8 bAMSDU_Support; // This indicates Tx A-MSDU capability
u16 nAMSDU_MaxSize; // This indicates Tx A-MSDU capability
u8 bCurrent_AMSDU_Support; // This indicates Tx A-MSDU capability
u16 nCurrent_AMSDU_MaxSize; // This indicates Tx A-MSDU capability
u8 bAMSDU_Support;
u16 nAMSDU_MaxSize;
u8 bCurrent_AMSDU_Support;
u16 nCurrent_AMSDU_MaxSize;
u8 bAMPDUEnable;
u8 bCurrentAMPDUEnable;
u8 AMPDU_Factor;
u8 CurrentAMPDUFactor;
u8 MPDU_Density;
u8 CurrentMPDUDensity;
// AMPDU related <2006.08.10 Emily>
u8 bAMPDUEnable; // This indicate Tx A-MPDU capability
u8 bCurrentAMPDUEnable; // This indicate Tx A-MPDU capability
u8 AMPDU_Factor; // This indicate Tx A-MPDU capability
u8 CurrentAMPDUFactor; // This indicate Tx A-MPDU capability
u8 MPDU_Density; // This indicate Tx A-MPDU capability
u8 CurrentMPDUDensity; // This indicate Tx A-MPDU capability
// Forced A-MPDU enable
HT_AGGRE_MODE_E ForcedAMPDUMode;
u8 ForcedAMPDUFactor;
u8 ForcedMPDUDensity;
// Forced A-MSDU enable
HT_AGGRE_MODE_E ForcedAMSDUMode;
u16 ForcedAMSDUMaxSize;
@ -295,28 +262,23 @@ typedef struct _RT_HIGH_THROUGHPUT{
u8 CurrentOpMode;
// MIMO PS related
u8 SelfMimoPs;
u8 PeerMimoPs;
// 40MHz Channel Offset settings.
HT_EXTCHNL_OFFSET CurSTAExtChnlOffset;
u8 bCurTxBW40MHz; // If we use 40 MHz to Tx
u8 bCurTxBW40MHz;
u8 PeerBandwidth;
// For Bandwidth Switching
u8 bSwBwInProgress;
CHNLOP ChnlOp; // software switching channel in progress. By Bruce, 2008-02-15.
CHNLOP ChnlOp;
u8 SwBwStep;
//struct timer_list SwBwTimer; //moved to ieee80211_device. as timer_list need include some header file here.
// For Realtek proprietary A-MPDU factor for aggregation
u8 bRegRT2RTAggregation;
u8 RT2RT_HT_Mode;
u8 bCurrentRT2RTAggregation;
u8 bCurrentRT2RTLongSlotTime;
u8 szRT2RTAggBuffer[10];
// Rx Reorder control
u8 bRegRxReorderEnable;
u8 bCurRxReorderEnable;
u8 RxReorderWinSize;
@ -331,21 +293,26 @@ typedef struct _RT_HIGH_THROUGHPUT{
u8 UsbRxFwAggrPageNum;
u8 UsbRxFwAggrPacketNum;
u8 UsbRxFwAggrTimeout;
u8 UsbRxPageSize;
#endif
// Add for Broadcom(Linksys) IOT. Joseph
u8 bIsPeerBcm;
// For IOT issue.
u8 IOTPeer;
u32 IOTAction;
u8 IOTRaFunc;
u8 bWAIotBroadcom;
u8 WAIotTH;
#ifdef RTL8192CE
u8 bRDGEnable;
#endif
u8 bAcceptAddbaReq;
} __attribute__ ((packed)) RT_HIGH_THROUGHPUT, *PRT_HIGH_THROUGHPUT;
//------------------------------------------------------------
// The Data structure is used to keep HT related variable for "each Sta"
// when card is configured as "AP mode"
//------------------------------------------------------------
typedef struct _RT_HTINFO_STA_ENTRY{
u8 bEnableHT;
@ -361,10 +328,19 @@ typedef struct _RT_HTINFO_STA_ENTRY{
u8 bBw40MHz;
u8 bCurTxBW40MHz;
u8 bCurShortGI20MHz;
u8 bCurShortGI40MHz;
u8 MimoPs;
u8 McsRateSet[16];
u8 bCurRxReorderEnable;
u16 nAMSDU_MaxSize;
}RT_HTINFO_STA_ENTRY, *PRT_HTINFO_STA_ENTRY;
@ -372,27 +348,23 @@ typedef struct _RT_HTINFO_STA_ENTRY{
//------------------------------------------------------------
// The Data structure is used to keep HT related variable for "each AP"
// when card is configured as "STA mode"
//------------------------------------------------------------
typedef struct _BSS_HT{
u8 bdSupportHT;
// HT related elements
u8 bdHTCapBuf[32];
u16 bdHTCapLen;
u8 bdHTInfoBuf[32];
u16 bdHTInfoLen;
HT_SPEC_VER bdHTSpecVer;
//HT_CAPABILITY_ELE bdHTCapEle;
//HT_INFORMATION_ELE bdHTInfoEle;
HT_CHANNEL_WIDTH bdBandWidth;
u8 bdRT2RTAggregation;
u8 bdRT2RTLongSlotTime;
u8 RT2RT_HT_Mode;
u8 bdHT1R;
} __attribute__ ((packed)) BSS_HT, *PBSS_HT;
typedef struct _MIMO_RSSI{
@ -413,6 +385,9 @@ typedef struct _FALSE_ALARM_STATISTICS{
u32 Cnt_Parity_Fail;
u32 Cnt_Rate_Illegal;
u32 Cnt_Crc8_fail;
u32 Cnt_Mcs_fail;
u32 Cnt_Ofdm_fail;
u32 Cnt_Cck_fail;
u32 Cnt_all;
}FALSE_ALARM_STATISTICS, *PFALSE_ALARM_STATISTICS;
@ -420,12 +395,8 @@ typedef struct _FALSE_ALARM_STATISTICS{
extern u8 MCS_FILTER_ALL[16];
extern u8 MCS_FILTER_1SS[16];
/* 2007/07/11 MH Modify the macro. Becaus STA may link with a N-AP. If we set
STA in A/B/G mode and AP is still in N mode. The macro will be wrong. We have
to add a macro to judge wireless mode. */
#define PICK_RATE(_nLegacyRate, _nMcsRate) \
(_nMcsRate==0)?(_nLegacyRate&0x7f):(_nMcsRate)
/* 2007/07/12 MH We only define legacy and HT wireless mode now. */
#define LEGACY_WIRELESS_MODE IEEE_MODE_MASK
#define CURRENT_RATE(WirelessMode, LegacyRate, HTRate) \
@ -435,9 +406,8 @@ extern u8 MCS_FILTER_1SS[16];
// MCS Bw 40 {1~7, 12~15,32}
#define RATE_ADPT_1SS_MASK 0xFF
#define RATE_ADPT_2SS_MASK 0xF0 //Skip MCS8~11 because mcs7 > mcs6, 9, 10, 11. 2007.01.16 by Emily
#define RATE_ADPT_2SS_MASK 0xF0
#define RATE_ADPT_MCS32_MASK 0x01
#define IS_11N_MCS_RATE(rate) (rate&0x80)
@ -449,22 +419,27 @@ typedef enum _HT_AGGRE_SIZE{
HT_AGG_SIZE_64K = 3,
}HT_AGGRE_SIZE_E, *PHT_AGGRE_SIZE_E;
/* Indicate different AP vendor for IOT issue */
typedef enum _HT_IOT_PEER
{
HT_IOT_PEER_UNKNOWN = 0,
HT_IOT_PEER_REALTEK = 1,
HT_IOT_PEER_BROADCOM = 2,
HT_IOT_PEER_RALINK = 3,
HT_IOT_PEER_ATHEROS = 4,
HT_IOT_PEER_CISCO= 5,
HT_IOT_PEER_MARVELL=6,
HT_IOT_PEER_MAX = 7
HT_IOT_PEER_REALTEK_92SE = 2,
HT_IOT_PEER_BROADCOM = 3,
HT_IOT_PEER_RALINK = 4,
HT_IOT_PEER_ATHEROS = 5,
HT_IOT_PEER_CISCO= 6,
HT_IOT_PEER_MARVELL=7,
HT_IOT_PEER_92U_SOFTAP = 8,
HT_IOT_PEER_SELF_SOFTAP = 9,
HT_IOT_PEER_AIRGO = 10,
HT_IOT_PEER_MAX = 11,
}HT_IOT_PEER_E, *PHTIOT_PEER_E;
//
// IOT Action for different AP
//
typedef enum _HT_IOT_PEER_SUBTYPE
{
HT_IOT_PEER_ATHEROS_DIR635 = 0,
}HT_IOT_PEER_SUBTYPE_E, *PHTIOT_PEER_SUBTYPE_E;
typedef enum _HT_IOT_ACTION{
HT_IOT_ACT_TX_USE_AMSDU_4K = 0x00000001,
HT_IOT_ACT_TX_USE_AMSDU_8K = 0x00000002,
@ -476,8 +451,43 @@ typedef enum _HT_IOT_ACTION{
HT_IOT_ACT_CDD_FSYNC = 0x00000080,
HT_IOT_ACT_PURE_N_MODE = 0x00000100,
HT_IOT_ACT_FORCED_CTS2SELF = 0x00000200,
HT_IOT_ACT_FORCED_RTS = 0x00000400,
HT_IOT_ACT_AMSDU_ENABLE = 0x00000800,
HT_IOT_ACT_REJECT_ADDBA_REQ = 0x00001000,
HT_IOT_ACT_ALLOW_PEER_AGG_ONE_PKT = 0x00002000,
HT_IOT_ACT_EDCA_BIAS_ON_RX = 0x00004000,
HT_IOT_ACT_HYBRID_AGGREGATION = 0x00010000,
HT_IOT_ACT_DISABLE_SHORT_GI = 0x00020000,
HT_IOT_ACT_DISABLE_HIGH_POWER = 0x00040000,
HT_IOT_ACT_DISABLE_TX_40_MHZ = 0x00080000,
HT_IOT_ACT_TX_NO_AGGREGATION = 0x00100000,
HT_IOT_ACT_DISABLE_TX_2SS = 0x00200000,
HT_IOT_ACT_MID_HIGHPOWER = 0x00400000,
HT_IOT_ACT_NULL_DATA_POWER_SAVING = 0x00800000,
HT_IOT_ACT_DISABLE_CCK_RATE = 0x01000000,
HT_IOT_ACT_FORCED_ENABLE_BE_TXOP = 0x02000000,
HT_IOT_ACT_WA_IOT_Broadcom = 0x04000000,
HT_IOT_ACT_DISABLE_RX_40MHZ_SHORT_GI = 0x08000000,
}HT_IOT_ACTION_E, *PHT_IOT_ACTION_E;
#endif //_RTL819XU_HTTYPE_H_
typedef enum _HT_IOT_RAFUNC{
HT_IOT_RAFUNC_DISABLE_ALL = 0x00,
HT_IOT_RAFUNC_PEER_1R = 0x01,
HT_IOT_RAFUNC_TX_AMSDU = 0x02,
}HT_IOT_RAFUNC, *PHT_IOT_RAFUNC;
typedef enum _RT_HT_CAP{
RT_HT_CAP_USE_TURBO_AGGR = 0x01,
RT_HT_CAP_USE_LONG_PREAMBLE = 0x02,
RT_HT_CAP_USE_AMPDU = 0x04,
RT_HT_CAP_USE_WOW = 0x8,
RT_HT_CAP_USE_SOFTAP = 0x10,
RT_HT_CAP_USE_92SE = 0x20,
}RT_HT_CAPBILITY, *PRT_HT_CAPBILITY;
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,422 @@
/******************************************************************************
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
******************************************************************************/
#ifndef __INC_QOS_TYPE_H
#define __INC_QOS_TYPE_H
#include "rtllib_endianfree.h"
#define BIT0 0x00000001
#define BIT1 0x00000002
#define BIT2 0x00000004
#define BIT3 0x00000008
#define BIT4 0x00000010
#define BIT5 0x00000020
#define BIT6 0x00000040
#define BIT7 0x00000080
#define BIT8 0x00000100
#define BIT9 0x00000200
#define BIT10 0x00000400
#define BIT11 0x00000800
#define BIT12 0x00001000
#define BIT13 0x00002000
#define BIT14 0x00004000
#define BIT15 0x00008000
#define BIT16 0x00010000
#define BIT17 0x00020000
#define BIT18 0x00040000
#define BIT19 0x00080000
#define BIT20 0x00100000
#define BIT21 0x00200000
#define BIT22 0x00400000
#define BIT23 0x00800000
#define BIT24 0x01000000
#define BIT25 0x02000000
#define BIT26 0x04000000
#define BIT27 0x08000000
#define BIT28 0x10000000
#define BIT29 0x20000000
#define BIT30 0x40000000
#define BIT31 0x80000000
#ifndef RTK_DMP_PLATFORM
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
#ifndef bool
typedef enum{false = 0, true} bool;
#endif
#endif
#endif
typedef union _QOS_TSINFO{
u8 charData[3];
struct {
u8 ucTrafficType:1;
u8 ucTSID:4;
u8 ucDirection:2;
u8 ucAccessPolicy:2;
u8 ucAggregation:1;
u8 ucPSB:1;
u8 ucUP:3;
u8 ucTSInfoAckPolicy:2;
u8 ucSchedule:1;
u8 ucReserved:7;
}field;
}QOS_TSINFO, *PQOS_TSINFO;
typedef union _TSPEC_BODY{
u8 charData[55];
struct
{
QOS_TSINFO TSInfo;
u16 NominalMSDUsize;
u16 MaxMSDUsize;
u32 MinServiceItv;
u32 MaxServiceItv;
u32 InactivityItv;
u32 SuspenItv;
u32 ServiceStartTime;
u32 MinDataRate;
u32 MeanDataRate;
u32 PeakDataRate;
u32 MaxBurstSize;
u32 DelayBound;
u32 MinPhyRate;
u16 SurplusBandwidthAllowance;
u16 MediumTime;
} f;
}TSPEC_BODY, *PTSPEC_BODY;
typedef struct _WMM_TSPEC{
u8 ID;
u8 Length;
u8 OUI[3];
u8 OUI_Type;
u8 OUI_SubType;
u8 Version;
TSPEC_BODY Body;
} WMM_TSPEC, *PWMM_TSPEC;
typedef struct _OCTET_STRING{
u8 *Octet;
u16 Length;
}OCTET_STRING, *POCTET_STRING;
#define MAX_WMMELE_LENGTH 64
typedef u32 QOS_MODE, *PQOS_MODE;
#define QOS_DISABLE 0
#define QOS_WMM 1
#define QOS_WMMSA 2
#define QOS_EDCA 4
#define QOS_HCCA 8
#define QOS_WMM_UAPSD 16
#define WMM_PARAM_ELE_BODY_LEN 18
#define MAX_STA_TS_COUNT 16
#define MAX_AP_TS_COUNT 32
#define QOS_TSTREAM_KEY_SIZE 13
#define WMM_ACTION_CATEGORY_CODE 17
#define WMM_PARAM_ELE_BODY_LEN 18
#define MAX_TSPEC_TSID 15
#define SESSION_REJECT_TSID 0xfe
#define DEFAULT_TSID 0xff
#define ADDTS_TIME_SLOT 100
#define ACM_TIMEOUT 1000
#define SESSION_REJECT_TIMEOUT 60000
typedef enum _ACK_POLICY{
eAckPlc0_ACK = 0x00,
eAckPlc1_NoACK = 0x01,
}ACK_POLICY,*PACK_POLICY;
#define SET_WMM_QOS_INFO_FIELD(_pStart, _val) WriteEF1Byte(_pStart, _val)
#define GET_WMM_QOS_INFO_FIELD_PARAMETERSET_COUNT(_pStart) LE_BITS_TO_1BYTE(_pStart, 0, 4)
#define SET_WMM_QOS_INFO_FIELD_PARAMETERSET_COUNT(_pStart, _val) SET_BITS_TO_LE_1BYTE(_pStart, 0, 4, _val)
#define GET_WMM_QOS_INFO_FIELD_AP_UAPSD(_pStart) LE_BITS_TO_1BYTE(_pStart, 7, 1)
#define SET_WMM_QOS_INFO_FIELD_AP_UAPSD(_pStart, _val) SET_BITS_TO_LE_1BYTE(_pStart, 7, 1, _val)
#define GET_WMM_QOS_INFO_FIELD_STA_AC_VO_UAPSD(_pStart) LE_BITS_TO_1BYTE(_pStart, 0, 1)
#define SET_WMM_QOS_INFO_FIELD_STA_AC_VO_UAPSD(_pStart, _val) SET_BITS_TO_LE_1BYTE(_pStart, 0, 1, _val)
#define GET_WMM_QOS_INFO_FIELD_STA_AC_VI_UAPSD(_pStart) LE_BITS_TO_1BYTE(_pStart, 1, 1)
#define SET_WMM_QOS_INFO_FIELD_STA_AC_VI_UAPSD(_pStart, _val) SET_BITS_TO_LE_1BYTE(_pStart, 1, 1, _val)
#define GET_WMM_QOS_INFO_FIELD_STA_AC_BE_UAPSD(_pStart) LE_BITS_TO_1BYTE(_pStart, 2, 1)
#define SET_WMM_QOS_INFO_FIELD_STA_AC_BE_UAPSD(_pStart, _val) SET_BITS_TO_LE_1BYTE(_pStart, 2, 1, _val)
#define GET_WMM_QOS_INFO_FIELD_STA_AC_BK_UAPSD(_pStart) LE_BITS_TO_1BYTE(_pStart, 3, 1)
#define SET_WMM_QOS_INFO_FIELD_STA_AC_BK_UAPSD(_pStart, _val) SET_BITS_TO_LE_1BYTE(_pStart, 3, 1, _val)
#define GET_WMM_QOS_INFO_FIELD_STA_MAX_SP_LEN(_pStart) LE_BITS_TO_1BYTE(_pStart, 5, 2)
#define SET_WMM_QOS_INFO_FIELD_STA_MAX_SP_LEN(_pStart, _val) SET_BITS_TO_LE_1BYTE(_pStart, 5, 2, _val)
typedef enum {
QOSIE_SRC_ADDTSREQ,
QOSIE_SRC_ADDTSRSP,
QOSIE_SRC_REASOCREQ,
QOSIE_SRC_REASOCRSP,
QOSIE_SRC_DELTS,
} QOSIE_SOURCE;
typedef u32 AC_CODING;
#define AC0_BE 0
#define AC1_BK 1
#define AC2_VI 2
#define AC3_VO 3
#define AC_MAX 4
#define AC_PARAM_SIZE 4
#define GET_WMM_AC_PARAM_AIFSN(_pStart) ( (u8)LE_BITS_TO_4BYTE(_pStart, 0, 4) )
#define SET_WMM_AC_PARAM_AIFSN(_pStart, _val) SET_BITS_TO_LE_4BYTE(_pStart, 0, 4, _val)
#define GET_WMM_AC_PARAM_ACM(_pStart) ( (u8)LE_BITS_TO_4BYTE(_pStart, 4, 1) )
#define SET_WMM_AC_PARAM_ACM(_pStart, _val) SET_BITS_TO_LE_4BYTE(_pStart, 4, 1, _val)
#define GET_WMM_AC_PARAM_ACI(_pStart) ( (u8)LE_BITS_TO_4BYTE(_pStart, 5, 2) )
#define SET_WMM_AC_PARAM_ACI(_pStart, _val) SET_BITS_TO_LE_4BYTE(_pStart, 5, 2, _val)
#define GET_WMM_AC_PARAM_ACI_AIFSN(_pStart) ( (u8)LE_BITS_TO_4BYTE(_pStart, 0, 8) )
#define SET_WMM_AC_PARAM_ACI_AIFSN(_pStart, _val) SET_BITS_TO_LE_4BYTE(_pStart, 0, 8, _val)
#define GET_WMM_AC_PARAM_ECWMIN(_pStart) ( (u8)LE_BITS_TO_4BYTE(_pStart, 8, 4) )
#define SET_WMM_AC_PARAM_ECWMIN(_pStart, _val) SET_BITS_TO_LE_4BYTE(_pStart, 8, 4, _val)
#define GET_WMM_AC_PARAM_ECWMAX(_pStart) ( (u8)LE_BITS_TO_4BYTE(_pStart, 12, 4) )
#define SET_WMM_AC_PARAM_ECWMAX(_pStart, _val) SET_BITS_TO_LE_4BYTE(_pStart, 12, 4, _val)
#define GET_WMM_AC_PARAM_TXOP_LIMIT(_pStart) ( (u8)LE_BITS_TO_4BYTE(_pStart, 16, 16) )
#define SET_WMM_AC_PARAM_TXOP_LIMIT(_pStart, _val) SET_BITS_TO_LE_4BYTE(_pStart, 16, 16, _val)
#define WMM_PARAM_ELEMENT_SIZE (8+(4*AC_PARAM_SIZE))
typedef enum _QOS_ELE_SUBTYPE{
QOSELE_TYPE_INFO = 0x00,
QOSELE_TYPE_PARAM = 0x01,
}QOS_ELE_SUBTYPE,*PQOS_ELE_SUBTYPE;
typedef enum _DIRECTION_VALUE{
DIR_UP = 0,
DIR_DOWN = 1,
DIR_DIRECT = 2,
DIR_BI_DIR = 3,
}DIRECTION_VALUE,*PDIRECTION_VALUE;
typedef enum _ACM_METHOD{
eAcmWay0_SwAndHw = 0,
eAcmWay1_HW = 1,
eAcmWay2_SW = 2,
}ACM_METHOD,*PACM_METHOD;
typedef struct _ACM{
u64 UsedTime;
u64 MediumTime;
u8 HwAcmCtl;
}ACM, *PACM;
typedef u8 AC_UAPSD, *PAC_UAPSD;
#define GET_VO_UAPSD(_apsd) ((_apsd) & BIT0)
#define SET_VO_UAPSD(_apsd) ((_apsd) |= BIT0)
#define GET_VI_UAPSD(_apsd) ((_apsd) & BIT1)
#define SET_VI_UAPSD(_apsd) ((_apsd) |= BIT1)
#define GET_BK_UAPSD(_apsd) ((_apsd) & BIT2)
#define SET_BK_UAPSD(_apsd) ((_apsd) |= BIT2)
#define GET_BE_UAPSD(_apsd) ((_apsd) & BIT3)
#define SET_BE_UAPSD(_apsd) ((_apsd) |= BIT3)
typedef union _QOS_TCLAS{
struct _TYPE_GENERAL{
u8 Priority;
u8 ClassifierType;
u8 Mask;
} TYPE_GENERAL;
struct _TYPE0_ETH{
u8 Priority;
u8 ClassifierType;
u8 Mask;
u8 SrcAddr[6];
u8 DstAddr[6];
u16 Type;
} TYPE0_ETH;
struct _TYPE1_IPV4{
u8 Priority;
u8 ClassifierType;
u8 Mask;
u8 Version;
u8 SrcIP[4];
u8 DstIP[4];
u16 SrcPort;
u16 DstPort;
u8 DSCP;
u8 Protocol;
u8 Reserved;
} TYPE1_IPV4;
struct _TYPE1_IPV6{
u8 Priority;
u8 ClassifierType;
u8 Mask;
u8 Version;
u8 SrcIP[16];
u8 DstIP[16];
u16 SrcPort;
u16 DstPort;
u8 FlowLabel[3];
} TYPE1_IPV6;
struct _TYPE2_8021Q{
u8 Priority;
u8 ClassifierType;
u8 Mask;
u16 TagType;
} TYPE2_8021Q;
} QOS_TCLAS, *PQOS_TCLAS;
typedef struct _QOS_TSTREAM{
bool bUsed;
u16 MsduLifetime;
bool bEstablishing;
u8 TimeSlotCount;
u8 DialogToken;
WMM_TSPEC TSpec;
WMM_TSPEC OutStandingTSpec;
u8 NominalPhyRate;
} QOS_TSTREAM, *PQOS_TSTREAM;
typedef struct _STA_QOS{
u8 WMMIEBuf[MAX_WMMELE_LENGTH];
u8* WMMIE;
QOS_MODE QosCapability;
QOS_MODE CurrentQosMode;
AC_UAPSD b4ac_Uapsd;
AC_UAPSD Curr4acUapsd;
u8 bInServicePeriod;
u8 MaxSPLength;
int NumBcnBeforeTrigger;
u8 * pWMMInfoEle;
u8 WMMParamEle[WMM_PARAM_ELEMENT_SIZE];
ACM acm[4];
ACM_METHOD AcmMethod;
QOS_TSTREAM StaTsArray[MAX_STA_TS_COUNT];
u8 DialogToken;
WMM_TSPEC TSpec;
u8 QBssWirelessMode;
bool bNoAck;
bool bEnableRxImmBA;
}STA_QOS, *PSTA_QOS;
#define QBSS_LOAD_SIZE 5
#define GET_QBSS_LOAD_STA_COUNT(__pStart) ReadEF2Byte(__pStart)
#define SET_QBSS_LOAD_STA_COUNT(__pStart, __Value) WriteEF2Byte(__pStart, __Value)
#define GET_QBSS_LOAD_CHNL_UTILIZATION(__pStart) ReadEF1Byte((u8*)(__pStart) + 2)
#define SET_QBSS_LOAD_CHNL_UTILIZATION(__pStart, __Value) WriteEF1Byte((u8*)(__pStart) + 2, __Value)
#define GET_QBSS_LOAD_AVAILABLE_CAPACITY(__pStart) ReadEF2Byte((u8*)(__pStart) + 3)
#define SET_QBSS_LOAD_AVAILABLE_CAPACITY(__pStart, __Value) WriteEF2Byte((u8*)(__pStart) + 3, __Value)
typedef struct _BSS_QOS{
QOS_MODE bdQoSMode;
u8 bdWMMIEBuf[MAX_WMMELE_LENGTH];
OCTET_STRING bdWMMIE;
QOS_ELE_SUBTYPE EleSubType;
u8* pWMMInfoEle;
u8* pWMMParamEle;
u8 QBssLoad[QBSS_LOAD_SIZE];
bool bQBssLoadValid;
}BSS_QOS, *PBSS_QOS;
#define sQoSCtlLng 2
#define QOS_CTRL_LEN(_QosMode) ( (_QosMode > QOS_DISABLE)? sQoSCtlLng : 0 )
#define IsACValid(ac) ( ( ac>=0 && ac<=7 )? true : false )
typedef union _ACI_AIFSN{
u8 charData;
struct
{
u8 AIFSN:4;
u8 ACM:1;
u8 ACI:2;
u8 Reserved:1;
}f;
}ACI_AIFSN, *PACI_AIFSN;
typedef union _ECW{
u8 charData;
struct
{
u8 ECWmin:4;
u8 ECWmax:4;
}f;
}ECW, *PECW;
typedef union _AC_PARAM{
u32 longData;
u8 charData[4];
struct
{
ACI_AIFSN AciAifsn;
ECW Ecw;
u16 TXOPLimit;
}f;
}AC_PARAM, *PAC_PARAM;
#endif

View file

@ -1,14 +1,31 @@
/******************************************************************************
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
******************************************************************************/
#ifndef _TSTYPE_H_
#define _TSTYPE_H_
#include "rtl819x_Qos.h"
#define TS_SETUP_TIMEOUT 60 // In millisecond
#define TS_SETUP_TIMEOUT 60
#define TS_INACT_TIMEOUT 60
#define TS_ADDBA_DELAY 60
#define TOTAL_TS_NUM 16
#define TCLAS_NUM 4
// This define the Tx/Rx directions
typedef enum _TR_SELECT {
TX_DIR = 0,
RX_DIR = 1,
@ -28,12 +45,12 @@ typedef struct _TS_COMMON_INFO{
typedef struct _TX_TS_RECORD{
TS_COMMON_INFO TsCommonInfo;
u16 TxCurSeq;
BA_RECORD TxPendingBARecord; // For BA Originator
BA_RECORD TxAdmittedBARecord; // For BA Originator
// QOS_DL_RECORD DLRecord;
BA_RECORD TxPendingBARecord;
BA_RECORD TxAdmittedBARecord;
u8 bAddBaReqInProgress;
u8 bAddBaReqDelayed;
u8 bUsingBa;
u8 bDisable_AddBa;
struct timer_list TsAddBaTimer;
u8 num;
} TX_TS_RECORD, *PTX_TS_RECORD;
@ -44,13 +61,11 @@ typedef struct _RX_TS_RECORD {
u16 RxTimeoutIndicateSeq;
struct list_head RxPendingPktList;
struct timer_list RxPktPendingTimer;
BA_RECORD RxAdmittedBARecord; // For BA Recipient
BA_RECORD RxAdmittedBARecord;
u16 RxLastSeqNum;
u8 RxLastFragNum;
u8 num;
// QOS_DL_RECORD DLRecord;
} RX_TS_RECORD, *PRX_TS_RECORD;
#endif

View file

@ -0,0 +1,647 @@
/******************************************************************************
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
******************************************************************************/
#include "rtllib.h"
#include <linux/etherdevice.h>
#include "rtl819x_TS.h"
extern void _setup_timer( struct timer_list*, void*, unsigned long);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
#define list_for_each_entry_safe(pos, n, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member), \
n = list_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.next, typeof(*n), member))
#endif
void TsSetupTimeOut(unsigned long data)
{
}
void TsInactTimeout(unsigned long data)
{
}
void RxPktPendingTimeout(unsigned long data)
{
PRX_TS_RECORD pRxTs = (PRX_TS_RECORD)data;
struct rtllib_device *ieee = container_of(pRxTs, struct rtllib_device, RxTsRecord[pRxTs->num]);
PRX_REORDER_ENTRY pReorderEntry = NULL;
unsigned long flags = 0;
struct rtllib_rxb *stats_IndicateArray[REORDER_WIN_SIZE];
u8 index = 0;
bool bPktInBuf = false;
spin_lock_irqsave(&(ieee->reorder_spinlock), flags);
if (pRxTs->RxTimeoutIndicateSeq != 0xffff)
{
while(!list_empty(&pRxTs->RxPendingPktList))
{
pReorderEntry = (PRX_REORDER_ENTRY)list_entry(pRxTs->RxPendingPktList.prev,RX_REORDER_ENTRY,List);
if (index == 0)
pRxTs->RxIndicateSeq = pReorderEntry->SeqNum;
if ( SN_LESS(pReorderEntry->SeqNum, pRxTs->RxIndicateSeq) ||
SN_EQUAL(pReorderEntry->SeqNum, pRxTs->RxIndicateSeq) )
{
list_del_init(&pReorderEntry->List);
if (SN_EQUAL(pReorderEntry->SeqNum, pRxTs->RxIndicateSeq))
pRxTs->RxIndicateSeq = (pRxTs->RxIndicateSeq + 1) % 4096;
RTLLIB_DEBUG(RTLLIB_DL_REORDER,"%s(): Indicate SeqNum: %d\n",__func__, pReorderEntry->SeqNum);
stats_IndicateArray[index] = pReorderEntry->prxb;
index++;
list_add_tail(&pReorderEntry->List, &ieee->RxReorder_Unused_List);
}
else
{
bPktInBuf = true;
break;
}
}
}
if (index>0){
pRxTs->RxTimeoutIndicateSeq = 0xffff;
if (index > REORDER_WIN_SIZE){
RTLLIB_DEBUG(RTLLIB_DL_ERR, "RxReorderIndicatePacket(): Rx Reorer buffer full!! \n");
spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
return;
}
rtllib_indicate_packets(ieee, stats_IndicateArray, index);
bPktInBuf = false;
}
if (bPktInBuf && (pRxTs->RxTimeoutIndicateSeq==0xffff)){
pRxTs->RxTimeoutIndicateSeq = pRxTs->RxIndicateSeq;
mod_timer(&pRxTs->RxPktPendingTimer, jiffies + MSECS(ieee->pHTInfo->RxReorderPendingTime));
}
spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
}
void TsAddBaProcess(unsigned long data)
{
PTX_TS_RECORD pTxTs = (PTX_TS_RECORD)data;
u8 num = pTxTs->num;
struct rtllib_device *ieee = container_of(pTxTs, struct rtllib_device, TxTsRecord[num]);
TsInitAddBA(ieee, pTxTs, BA_POLICY_IMMEDIATE, false);
RTLLIB_DEBUG(RTLLIB_DL_BA, "TsAddBaProcess(): ADDBA Req is started!! \n");
}
void ResetTsCommonInfo(PTS_COMMON_INFO pTsCommonInfo)
{
memset(pTsCommonInfo->Addr, 0, 6);
memset(&pTsCommonInfo->TSpec, 0, sizeof(TSPEC_BODY));
memset(&pTsCommonInfo->TClass, 0, sizeof(QOS_TCLAS)*TCLAS_NUM);
pTsCommonInfo->TClasProc = 0;
pTsCommonInfo->TClasNum = 0;
}
void ResetTxTsEntry(PTX_TS_RECORD pTS)
{
ResetTsCommonInfo(&pTS->TsCommonInfo);
pTS->TxCurSeq = 0;
pTS->bAddBaReqInProgress = false;
pTS->bAddBaReqDelayed = false;
pTS->bUsingBa = false;
pTS->bDisable_AddBa = false;
ResetBaEntry(&pTS->TxAdmittedBARecord);
ResetBaEntry(&pTS->TxPendingBARecord);
}
void ResetRxTsEntry(PRX_TS_RECORD pTS)
{
ResetTsCommonInfo(&pTS->TsCommonInfo);
pTS->RxIndicateSeq = 0xffff;
pTS->RxTimeoutIndicateSeq = 0xffff;
ResetBaEntry(&pTS->RxAdmittedBARecord);
}
#ifdef _RTL8192_EXT_PATCH_
void ResetAdmitTRStream(struct rtllib_device *ieee, u8 *Addr)
{
u8 dir;
bool search_dir[4] = {0, 0, 0, 0};
struct list_head* psearch_list;
PTS_COMMON_INFO pRet = NULL;
PRX_TS_RECORD pRxTS = NULL;
PTX_TS_RECORD pTxTS = NULL;
if (ieee->iw_mode != IW_MODE_MESH)
return;
search_dir[DIR_DOWN] = true;
psearch_list = &ieee->Rx_TS_Admit_List;
for (dir = 0; dir <= DIR_BI_DIR; dir++)
{
if (search_dir[dir] ==false )
continue;
list_for_each_entry(pRet, psearch_list, List){
if ((memcmp(pRet->Addr, Addr, 6) == 0) && (pRet->TSpec.f.TSInfo.field.ucDirection == dir))
{
pRxTS = (PRX_TS_RECORD)pRet;
pRxTS->RxIndicateSeq = 0xffff;
pRxTS->RxTimeoutIndicateSeq = 0xffff;
}
}
}
search_dir[DIR_UP] = true;
psearch_list = &ieee->Tx_TS_Admit_List;
for (dir = 0; dir <= DIR_BI_DIR; dir++)
{
if (search_dir[dir] ==false )
continue;
list_for_each_entry(pRet, psearch_list, List){
if ((memcmp(pRet->Addr, Addr, 6) == 0) && (pRet->TSpec.f.TSInfo.field.ucDirection == dir))
{
pTxTS = (PTX_TS_RECORD)pRet;
pTxTS->TxCurSeq = 0xffff;
}
}
}
return;
}
#endif
void TSInitialize(struct rtllib_device *ieee)
{
PTX_TS_RECORD pTxTS = ieee->TxTsRecord;
PRX_TS_RECORD pRxTS = ieee->RxTsRecord;
PRX_REORDER_ENTRY pRxReorderEntry = ieee->RxReorderEntry;
u8 count = 0;
RTLLIB_DEBUG(RTLLIB_DL_TS, "==========>%s()\n", __func__);
INIT_LIST_HEAD(&ieee->Tx_TS_Admit_List);
INIT_LIST_HEAD(&ieee->Tx_TS_Pending_List);
INIT_LIST_HEAD(&ieee->Tx_TS_Unused_List);
for (count = 0; count < TOTAL_TS_NUM; count++)
{
pTxTS->num = count;
_setup_timer(&pTxTS->TsCommonInfo.SetupTimer,
TsSetupTimeOut,
(unsigned long) pTxTS);
_setup_timer(&pTxTS->TsCommonInfo.InactTimer,
TsInactTimeout,
(unsigned long) pTxTS);
_setup_timer(&pTxTS->TsAddBaTimer,
TsAddBaProcess,
(unsigned long) pTxTS);
_setup_timer(&pTxTS->TxPendingBARecord.Timer,
BaSetupTimeOut,
(unsigned long) pTxTS);
_setup_timer(&pTxTS->TxAdmittedBARecord.Timer,
TxBaInactTimeout,
(unsigned long) pTxTS);
ResetTxTsEntry(pTxTS);
list_add_tail(&pTxTS->TsCommonInfo.List,
&ieee->Tx_TS_Unused_List);
pTxTS++;
}
INIT_LIST_HEAD(&ieee->Rx_TS_Admit_List);
INIT_LIST_HEAD(&ieee->Rx_TS_Pending_List);
INIT_LIST_HEAD(&ieee->Rx_TS_Unused_List);
for (count = 0; count < TOTAL_TS_NUM; count++)
{
pRxTS->num = count;
INIT_LIST_HEAD(&pRxTS->RxPendingPktList);
_setup_timer(&pRxTS->TsCommonInfo.SetupTimer,
TsSetupTimeOut,
(unsigned long) pRxTS);
_setup_timer(&pRxTS->TsCommonInfo.InactTimer,
TsInactTimeout,
(unsigned long) pRxTS);
_setup_timer(&pRxTS->RxAdmittedBARecord.Timer,
RxBaInactTimeout,
(unsigned long) pRxTS);
_setup_timer(&pRxTS->RxPktPendingTimer,
RxPktPendingTimeout,
(unsigned long) pRxTS);
ResetRxTsEntry(pRxTS);
list_add_tail(&pRxTS->TsCommonInfo.List, &ieee->Rx_TS_Unused_List);
pRxTS++;
}
INIT_LIST_HEAD(&ieee->RxReorder_Unused_List);
for (count = 0; count < REORDER_ENTRY_NUM; count++)
{
list_add_tail( &pRxReorderEntry->List,&ieee->RxReorder_Unused_List);
if (count == (REORDER_ENTRY_NUM-1))
break;
pRxReorderEntry = &ieee->RxReorderEntry[count+1];
}
}
void AdmitTS(struct rtllib_device *ieee, PTS_COMMON_INFO pTsCommonInfo, u32 InactTime)
{
del_timer_sync(&pTsCommonInfo->SetupTimer);
del_timer_sync(&pTsCommonInfo->InactTimer);
if (InactTime!=0)
mod_timer(&pTsCommonInfo->InactTimer, jiffies + MSECS(InactTime));
}
PTS_COMMON_INFO SearchAdmitTRStream(struct rtllib_device *ieee, u8* Addr, u8 TID, TR_SELECT TxRxSelect)
{
u8 dir;
bool search_dir[4] = {0, 0, 0, 0};
struct list_head* psearch_list;
PTS_COMMON_INFO pRet = NULL;
if (ieee->iw_mode == IW_MODE_MASTER)
{
if (TxRxSelect == TX_DIR)
{
search_dir[DIR_DOWN] = true;
search_dir[DIR_BI_DIR]= true;
}
else
{
search_dir[DIR_UP] = true;
search_dir[DIR_BI_DIR]= true;
}
}
else if (ieee->iw_mode == IW_MODE_ADHOC)
{
if (TxRxSelect == TX_DIR)
search_dir[DIR_UP] = true;
else
search_dir[DIR_DOWN] = true;
}
else
{
if (TxRxSelect == TX_DIR)
{
search_dir[DIR_UP] = true;
search_dir[DIR_BI_DIR]= true;
search_dir[DIR_DIRECT]= true;
}
else
{
search_dir[DIR_DOWN] = true;
search_dir[DIR_BI_DIR]= true;
search_dir[DIR_DIRECT]= true;
}
}
if (TxRxSelect == TX_DIR)
psearch_list = &ieee->Tx_TS_Admit_List;
else
psearch_list = &ieee->Rx_TS_Admit_List;
for (dir = 0; dir <= DIR_BI_DIR; dir++)
{
if (search_dir[dir] ==false )
continue;
list_for_each_entry(pRet, psearch_list, List){
if (memcmp(pRet->Addr, Addr, 6) == 0)
if (pRet->TSpec.f.TSInfo.field.ucTSID == TID)
if (pRet->TSpec.f.TSInfo.field.ucDirection == dir)
{
break;
}
}
if (&pRet->List != psearch_list)
break;
}
if (&pRet->List != psearch_list){
return pRet ;
}
else
return NULL;
}
void MakeTSEntry(
PTS_COMMON_INFO pTsCommonInfo,
u8* Addr,
PTSPEC_BODY pTSPEC,
PQOS_TCLAS pTCLAS,
u8 TCLAS_Num,
u8 TCLAS_Proc
)
{
u8 count;
if (pTsCommonInfo == NULL)
return;
memcpy(pTsCommonInfo->Addr, Addr, 6);
if (pTSPEC != NULL)
memcpy((u8*)(&(pTsCommonInfo->TSpec)), (u8*)pTSPEC, sizeof(TSPEC_BODY));
for (count = 0; count < TCLAS_Num; count++)
memcpy((u8*)(&(pTsCommonInfo->TClass[count])), (u8*)pTCLAS, sizeof(QOS_TCLAS));
pTsCommonInfo->TClasProc = TCLAS_Proc;
pTsCommonInfo->TClasNum = TCLAS_Num;
}
#ifdef _RTL8192_EXT_PATCH_
void dump_ts_list(struct list_head * ts_list)
{
PTS_COMMON_INFO pRet = NULL;
u8 i=0;
list_for_each_entry(pRet, ts_list, List){
printk("i=%d ADD:"MAC_FMT", TID:%d, dir:%d\n",i,MAC_ARG(pRet->Addr), pRet->TSpec.f.TSInfo.field.ucTSID, pRet->TSpec.f.TSInfo.field.ucDirection);
i++;
}
}
#endif
bool GetTs(
struct rtllib_device* ieee,
PTS_COMMON_INFO *ppTS,
u8* Addr,
u8 TID,
TR_SELECT TxRxSelect,
bool bAddNewTs)
{
u8 UP = 0;
if (is_broadcast_ether_addr(Addr) || is_multicast_ether_addr(Addr))
{
RTLLIB_DEBUG(RTLLIB_DL_ERR, "ERR! get TS for Broadcast or Multicast\n");
return false;
}
if (ieee->current_network.qos_data.supported == 0) {
UP = 0;
} else {
if (!IsACValid(TID)) {
RTLLIB_DEBUG(RTLLIB_DL_ERR, "ERR! in %s(), TID(%d) is not valid\n", __func__, TID);
return false;
}
switch (TID) {
case 0:
case 3:
UP = 0;
break;
case 1:
case 2:
UP = 2;
break;
case 4:
case 5:
UP = 5;
break;
case 6:
case 7:
UP = 7;
break;
}
}
*ppTS = SearchAdmitTRStream(
ieee,
Addr,
UP,
TxRxSelect);
if (*ppTS != NULL)
{
return true;
}
else
{
if (bAddNewTs == false)
{
RTLLIB_DEBUG(RTLLIB_DL_TS, "add new TS failed(tid:%d)\n", UP);
return false;
}
else
{
TSPEC_BODY TSpec;
PQOS_TSINFO pTSInfo = &TSpec.f.TSInfo;
struct list_head* pUnusedList =
(TxRxSelect == TX_DIR)?
(&ieee->Tx_TS_Unused_List):
(&ieee->Rx_TS_Unused_List);
struct list_head* pAddmitList =
(TxRxSelect == TX_DIR)?
(&ieee->Tx_TS_Admit_List):
(&ieee->Rx_TS_Admit_List);
DIRECTION_VALUE Dir = (ieee->iw_mode == IW_MODE_MASTER)?
((TxRxSelect==TX_DIR)?DIR_DOWN:DIR_UP):
((TxRxSelect==TX_DIR)?DIR_UP:DIR_DOWN);
RTLLIB_DEBUG(RTLLIB_DL_TS, "to add Ts\n");
if (!list_empty(pUnusedList))
{
(*ppTS) = list_entry(pUnusedList->next, TS_COMMON_INFO, List);
list_del_init(&(*ppTS)->List);
if (TxRxSelect==TX_DIR)
{
PTX_TS_RECORD tmp = container_of(*ppTS, TX_TS_RECORD, TsCommonInfo);
ResetTxTsEntry(tmp);
}
else{
PRX_TS_RECORD tmp = container_of(*ppTS, RX_TS_RECORD, TsCommonInfo);
ResetRxTsEntry(tmp);
}
RTLLIB_DEBUG(RTLLIB_DL_TS, "to init current TS, UP:%d, Dir:%d, addr:"MAC_FMT" ppTs=%p\n", UP, Dir, MAC_ARG(Addr), *ppTS);
pTSInfo->field.ucTrafficType = 0;
pTSInfo->field.ucTSID = UP;
pTSInfo->field.ucDirection = Dir;
pTSInfo->field.ucAccessPolicy = 1;
pTSInfo->field.ucAggregation = 0;
pTSInfo->field.ucPSB = 0;
pTSInfo->field.ucUP = UP;
pTSInfo->field.ucTSInfoAckPolicy = 0;
pTSInfo->field.ucSchedule = 0;
MakeTSEntry(*ppTS, Addr, &TSpec, NULL, 0, 0);
AdmitTS(ieee, *ppTS, 0);
list_add_tail(&((*ppTS)->List), pAddmitList);
return true;
}
else
{
RTLLIB_DEBUG(RTLLIB_DL_ERR, "ERR!!in function %s() There is not enough dir=%d(0=up down=1) TS record to be used!!", __func__,Dir);
return false;
}
}
}
}
void RemoveTsEntry(
struct rtllib_device* ieee,
PTS_COMMON_INFO pTs,
TR_SELECT TxRxSelect
)
{
del_timer_sync(&pTs->SetupTimer);
del_timer_sync(&pTs->InactTimer);
TsInitDelBA(ieee, pTs, TxRxSelect);
if (TxRxSelect == RX_DIR)
{
PRX_REORDER_ENTRY pRxReorderEntry;
PRX_TS_RECORD pRxTS = (PRX_TS_RECORD)pTs;
if (timer_pending(&pRxTS->RxPktPendingTimer))
del_timer_sync(&pRxTS->RxPktPendingTimer);
while(!list_empty(&pRxTS->RxPendingPktList)){
pRxReorderEntry = (PRX_REORDER_ENTRY)list_entry(pRxTS->RxPendingPktList.prev,RX_REORDER_ENTRY,List);
RTLLIB_DEBUG(RTLLIB_DL_REORDER,"%s(): Delete SeqNum %d!\n",__func__, pRxReorderEntry->SeqNum);
list_del_init(&pRxReorderEntry->List);
{
int i = 0;
struct rtllib_rxb * prxb = pRxReorderEntry->prxb;
if (unlikely(!prxb)){
return;
}
for (i =0; i < prxb->nr_subframes; i++) {
dev_kfree_skb(prxb->subframes[i]);
}
kfree(prxb);
prxb = NULL;
}
list_add_tail(&pRxReorderEntry->List,&ieee->RxReorder_Unused_List);
}
}
else{
PTX_TS_RECORD pTxTS = (PTX_TS_RECORD)pTs;
del_timer_sync(&pTxTS->TsAddBaTimer);
}
}
void RemovePeerTS(struct rtllib_device* ieee, u8* Addr)
{
PTS_COMMON_INFO pTS, pTmpTS;
printk("===========>RemovePeerTS,"MAC_FMT"\n", MAC_ARG(Addr));
#if 1
list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List)
{
if (memcmp(pTS->Addr, Addr, 6) == 0)
{
RemoveTsEntry(ieee, pTS, TX_DIR);
list_del_init(&pTS->List);
list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List);
}
}
list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Admit_List, List)
{
if (memcmp(pTS->Addr, Addr, 6) == 0)
{
printk("====>remove Tx_TS_admin_list\n");
RemoveTsEntry(ieee, pTS, TX_DIR);
list_del_init(&pTS->List);
list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List);
}
}
list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Pending_List, List)
{
if (memcmp(pTS->Addr, Addr, 6) == 0)
{
RemoveTsEntry(ieee, pTS, RX_DIR);
list_del_init(&pTS->List);
list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List);
}
}
list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Admit_List, List)
{
if (memcmp(pTS->Addr, Addr, 6) == 0)
{
RemoveTsEntry(ieee, pTS, RX_DIR);
list_del_init(&pTS->List);
list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List);
}
}
#endif
}
void RemoveAllTS(struct rtllib_device* ieee)
{
PTS_COMMON_INFO pTS, pTmpTS;
#if 1
list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List)
{
RemoveTsEntry(ieee, pTS, TX_DIR);
list_del_init(&pTS->List);
list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List);
}
list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Admit_List, List)
{
RemoveTsEntry(ieee, pTS, TX_DIR);
list_del_init(&pTS->List);
list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List);
}
list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Pending_List, List)
{
RemoveTsEntry(ieee, pTS, RX_DIR);
list_del_init(&pTS->List);
list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List);
}
list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Admit_List, List)
{
RemoveTsEntry(ieee, pTS, RX_DIR);
list_del_init(&pTS->List);
list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List);
}
#endif
}
void TsStartAddBaProcess(struct rtllib_device* ieee, PTX_TS_RECORD pTxTS)
{
if (pTxTS->bAddBaReqInProgress == false)
{
pTxTS->bAddBaReqInProgress = true;
#if 1
if (pTxTS->bAddBaReqDelayed)
{
RTLLIB_DEBUG(RTLLIB_DL_BA, "TsStartAddBaProcess(): Delayed Start ADDBA after 60 sec!!\n");
mod_timer(&pTxTS->TsAddBaTimer, jiffies + MSECS(TS_ADDBA_DELAY));
}
else
{
RTLLIB_DEBUG(RTLLIB_DL_BA,"TsStartAddBaProcess(): Immediately Start ADDBA now!!\n");
mod_timer(&pTxTS->TsAddBaTimer, jiffies+10);
}
#endif
}
else
RTLLIB_DEBUG(RTLLIB_DL_BA, "%s()==>BA timer is already added\n", __func__);
}

View file

@ -0,0 +1,379 @@
/******************************************************************************
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Based on the r8180 driver, which is:
* Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al.
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
******************************************************************************/
#include "rtl_core.h"
#include "r8192E_phy.h"
#include "r8192E_phyreg.h"
#include "r8190P_rtl8256.h" /* RTL8225 Radio frontend */
#include "r8192E_cmdpkt.h"
extern int hwwep;
void CamResetAllEntry(struct net_device *dev)
{
u32 ulcommand = 0;
ulcommand |= BIT31|BIT30;
write_nic_dword(dev, RWCAM, ulcommand);
}
void write_cam(struct net_device *dev, u8 addr, u32 data)
{
write_nic_dword(dev, WCAMI, data);
write_nic_dword(dev, RWCAM, BIT31|BIT16|(addr&0xff) );
}
u32 read_cam(struct net_device *dev, u8 addr)
{
write_nic_dword(dev, RWCAM, 0x80000000|(addr&0xff) );
return read_nic_dword(dev, 0xa8);
}
void EnableHWSecurityConfig8192(struct net_device *dev)
{
u8 SECR_value = 0x0;
struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
struct rtllib_device* ieee = priv->rtllib;
SECR_value = SCR_TxEncEnable | SCR_RxDecEnable;
if (((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) && (priv->rtllib->auth_mode != 2))
{
SECR_value |= SCR_RxUseDK;
SECR_value |= SCR_TxUseDK;
}
else if ((ieee->iw_mode == IW_MODE_ADHOC) && (ieee->pairwise_key_type & (KEY_TYPE_CCMP | KEY_TYPE_TKIP)))
{
SECR_value |= SCR_RxUseDK;
SECR_value |= SCR_TxUseDK;
}
ieee->hwsec_active = 1;
if ((ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE) || !hwwep)
{
ieee->hwsec_active = 0;
SECR_value &= ~SCR_RxDecEnable;
}
RT_TRACE(COMP_SEC,"%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", __func__, \
ieee->hwsec_active, ieee->pairwise_key_type, SECR_value);
{
write_nic_byte(dev, SECR, SECR_value);
}
}
void set_swcam(struct net_device *dev,
u8 EntryNo,
u8 KeyIndex,
u16 KeyType,
u8 *MacAddr,
u8 DefaultKey,
u32 *KeyContent,
u8 is_mesh)
{
struct r8192_priv *priv = rtllib_priv(dev);
struct rtllib_device *ieee = priv->rtllib;
RT_TRACE(COMP_DBG, "===========>%s():EntryNo is %d,KeyIndex is "
"%d,KeyType is %d,is_mesh is %d\n", __func__, EntryNo,
KeyIndex, KeyType, is_mesh);
if (is_mesh){
} else {
ieee->swcamtable[EntryNo].bused=true;
ieee->swcamtable[EntryNo].key_index=KeyIndex;
ieee->swcamtable[EntryNo].key_type=KeyType;
memcpy(ieee->swcamtable[EntryNo].macaddr,MacAddr,6);
ieee->swcamtable[EntryNo].useDK=DefaultKey;
memcpy(ieee->swcamtable[EntryNo].key_buf,(u8*)KeyContent,16);
}
}
void setKey(struct net_device *dev,
u8 EntryNo,
u8 KeyIndex,
u16 KeyType,
u8 *MacAddr,
u8 DefaultKey,
u32 *KeyContent )
{
u32 TargetCommand = 0;
u32 TargetContent = 0;
u16 usConfig = 0;
u8 i;
struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
RT_RF_POWER_STATE rtState;
rtState = priv->rtllib->eRFPowerState;
if (priv->rtllib->PowerSaveControl.bInactivePs){
if (rtState == eRfOff){
if (priv->rtllib->RfOffReason > RF_CHANGE_BY_IPS)
{
RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__func__);
return ;
}
else{
down(&priv->rtllib->ips_sem);
IPSLeave(dev);
up(&priv->rtllib->ips_sem); }
}
}
priv->rtllib->is_set_key = true;
if (EntryNo >= TOTAL_CAM_ENTRY)
RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d,"
"KeyType:%d, MacAddr"MAC_FMT"\n", dev,EntryNo, KeyIndex,
KeyType, MAC_ARG(MacAddr));
if (DefaultKey)
usConfig |= BIT15 | (KeyType<<2);
else
usConfig |= BIT15 | (KeyType<<2) | KeyIndex;
for (i = 0; i < CAM_CONTENT_COUNT; i++) {
TargetCommand = i+CAM_CONTENT_COUNT*EntryNo;
TargetCommand |= BIT31|BIT16;
if (i == 0) {
TargetContent = (u32)(*(MacAddr+0)) << 16|
(u32)(*(MacAddr+1)) << 24|
(u32)usConfig;
write_nic_dword(dev, WCAMI, TargetContent);
write_nic_dword(dev, RWCAM, TargetCommand);
} else if (i == 1) {
TargetContent = (u32)(*(MacAddr+2)) |
(u32)(*(MacAddr+3)) << 8|
(u32)(*(MacAddr+4)) << 16|
(u32)(*(MacAddr+5)) << 24;
write_nic_dword(dev, WCAMI, TargetContent);
write_nic_dword(dev, RWCAM, TargetCommand);
} else {
if (KeyContent != NULL) {
write_nic_dword(dev, WCAMI, (u32)(*(KeyContent+i-2)) );
write_nic_dword(dev, RWCAM, TargetCommand);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31))
udelay(100);
#endif
}
}
}
RT_TRACE(COMP_SEC,"=========>after set key, usconfig:%x\n", usConfig);
}
void CAM_read_entry(struct net_device *dev, u32 iIndex)
{
u32 target_command=0;
u32 target_content=0;
u8 entry_i=0;
u32 ulStatus;
s32 i=100;
for (entry_i=0;entry_i<CAM_CONTENT_COUNT;entry_i++)
{
target_command= entry_i+CAM_CONTENT_COUNT*iIndex;
target_command= target_command | BIT31;
while((i--)>=0)
{
ulStatus = read_nic_dword(dev, RWCAM);
if (ulStatus & BIT31){
continue;
}
else{
break;
}
}
write_nic_dword(dev, RWCAM, target_command);
RT_TRACE(COMP_SEC,"CAM_read_entry(): WRITE A0: %x \n",target_command);
target_content = read_nic_dword(dev, RCAMO);
RT_TRACE(COMP_SEC, "CAM_read_entry(): WRITE A8: %x \n",target_content);
}
printk("\n");
}
void CamRestoreAllEntry( struct net_device *dev)
{
u8 EntryId = 0;
struct r8192_priv *priv = rtllib_priv(dev);
u8* MacAddr = priv->rtllib->current_network.bssid;
static u8 CAM_CONST_ADDR[4][6] = {
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
static u8 CAM_CONST_BROAD[] =
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
RT_TRACE(COMP_SEC, "CamRestoreAllEntry: \n");
if ((priv->rtllib->pairwise_key_type == KEY_TYPE_WEP40)||
(priv->rtllib->pairwise_key_type == KEY_TYPE_WEP104))
{
for (EntryId=0; EntryId<4; EntryId++)
{
{
MacAddr = CAM_CONST_ADDR[EntryId];
if (priv->rtllib->swcamtable[EntryId].bused )
{
setKey(dev,
EntryId ,
EntryId,
priv->rtllib->pairwise_key_type,
MacAddr,
0,
(u32*)(&priv->rtllib->swcamtable[EntryId].key_buf[0])
);
}
}
}
}
else if (priv->rtllib->pairwise_key_type == KEY_TYPE_TKIP)
{
{
if (priv->rtllib->iw_mode == IW_MODE_ADHOC)
{
setKey(dev,
4,
0,
priv->rtllib->pairwise_key_type,
(u8*)dev->dev_addr,
0,
(u32*)(&priv->rtllib->swcamtable[4].key_buf[0])
);
}
else
{
setKey(dev,
4,
0,
priv->rtllib->pairwise_key_type,
MacAddr,
0,
(u32*)(&priv->rtllib->swcamtable[4].key_buf[0])
);
}
}
}
else if (priv->rtllib->pairwise_key_type == KEY_TYPE_CCMP)
{
{
if (priv->rtllib->iw_mode == IW_MODE_ADHOC)
{
setKey(dev,
4,
0,
priv->rtllib->pairwise_key_type,
(u8*)dev->dev_addr,
0,
(u32*)(&priv->rtllib->swcamtable[4].key_buf[0])
);
}
else
{
setKey(dev,
4,
0,
priv->rtllib->pairwise_key_type,
MacAddr,
0,
(u32*)(&priv->rtllib->swcamtable[4].key_buf[0])
);
}
}
}
if (priv->rtllib->group_key_type == KEY_TYPE_TKIP)
{
MacAddr = CAM_CONST_BROAD;
for (EntryId=1 ; EntryId<4 ; EntryId++)
{
if (priv->rtllib->swcamtable[EntryId].bused )
{
setKey(dev,
EntryId,
EntryId,
priv->rtllib->group_key_type,
MacAddr,
0,
(u32*)(&priv->rtllib->swcamtable[EntryId].key_buf[0])
);
}
}
if (priv->rtllib->iw_mode == IW_MODE_ADHOC)
{
if (priv->rtllib->swcamtable[0].bused ){
setKey(dev,
0,
0,
priv->rtllib->group_key_type,
CAM_CONST_ADDR[0],
0,
(u32*)(&priv->rtllib->swcamtable[0].key_buf[0])
);
}
else
{
RT_TRACE(COMP_ERR,"===>%s():ERR!! ADHOC TKIP ,but 0 entry is have no data\n",__func__);
return;
}
}
} else if (priv->rtllib->group_key_type == KEY_TYPE_CCMP) {
MacAddr = CAM_CONST_BROAD;
for (EntryId=1; EntryId<4 ; EntryId++)
{
if (priv->rtllib->swcamtable[EntryId].bused )
{
setKey(dev,
EntryId ,
EntryId,
priv->rtllib->group_key_type,
MacAddr,
0,
(u32*)(&priv->rtllib->swcamtable[EntryId].key_buf[0]));
}
}
if (priv->rtllib->iw_mode == IW_MODE_ADHOC) {
if (priv->rtllib->swcamtable[0].bused) {
setKey(dev,
0 ,
0,
priv->rtllib->group_key_type,
CAM_CONST_ADDR[0],
0,
(u32*)(&priv->rtllib->swcamtable[0].key_buf[0]));
} else {
RT_TRACE(COMP_ERR,"===>%s():ERR!! ADHOC CCMP ,but 0 entry is have no data\n",
__func__);
return;
}
}
}
}

View file

@ -0,0 +1,44 @@
/******************************************************************************
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Based on the r8180 driver, which is:
* Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al.
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
******************************************************************************/
#ifndef _RTL_CAM_H
#define _RTL_CAM_H
#include <linux/types.h>
struct net_device;
void CamResetAllEntry(struct net_device* dev);
void EnableHWSecurityConfig8192(struct net_device *dev);
void setKey(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType, u8 *MacAddr, u8 DefaultKey, u32 *KeyContent );
void set_swcam(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType, u8 *MacAddr, u8 DefaultKey, u32 *KeyContent, u8 is_mesh);
void CamPrintDbgReg(struct net_device* dev);
u32 read_cam(struct net_device *dev, u8 addr);
void write_cam(struct net_device *dev, u8 addr, u32 data);
void CamRestoreAllEntry(struct net_device *dev);
void CAM_read_entry(struct net_device *dev, u32 iIndex);
#endif

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -24,6 +24,16 @@
#include <asm/page.h>
#include <asm/errno.h>
#ifdef BUILT_IN_CRYPTO
#ifdef CONFIG_CRYPTO_HMAC
#undef CONFIG_CRYPTO_HMAC
#endif
#ifdef CONFIG_KMOD
#undef CONFIG_KMOD
#endif
#endif /* BUILT_IN_CRYPTO */
#define crypto_register_alg crypto_register_alg_rsl
#define crypto_unregister_alg crypto_unregister_alg_rsl
#define crypto_alloc_tfm crypto_alloc_tfm_rsl
@ -396,4 +406,3 @@ void crypto_hmac(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen,
#endif /* CONFIG_CRYPTO_HMAC */
#endif /* _LINUX_CRYPTO_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,319 @@
/******************************************************************************
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Based on the r8180 driver, which is:
* Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al.
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
******************************************************************************/
#ifndef _RTL_DEBUG_H
#define _RTL_DEBUG_H
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/version.h>
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9))
#include <linux/debugfs.h>
#endif
struct r8192_priv;
struct _tx_desc_8192se;
struct _TX_DESC_8192CE;
struct net_device;
#define DBG_LOUD 4
#define RT_ASSERT(_Exp,Fmt) \
if (!(_Exp)) \
{ \
printk("Rtl819x: "); \
printk Fmt; \
}
typedef enum tag_DBGP_Flag_Type_Definition
{
FQoS = 0,
FTX = 1,
FRX = 2,
FSEC = 3,
FMGNT = 4,
FMLME = 5,
FRESOURCE = 6,
FBEACON = 7,
FISR = 8,
FPHY = 9,
FMP = 10,
FEEPROM = 11,
FPWR = 12,
FDM = 13,
FDBGCtrl = 14,
FC2H = 15,
FBT = 16,
FINIT = 17,
FIOCTL = 18,
DBGP_TYPE_MAX
}DBGP_FLAG_E;
#define QoS_INIT BIT0
#define QoS_VISTA BIT1
#define TX_DESC BIT0
#define TX_DESC_TID BIT1
#define RX_DATA BIT0
#define RX_PHY_STS BIT1
#define RX_PHY_SS BIT2
#define RX_PHY_SQ BIT3
#define RX_PHY_ASTS BIT4
#define RX_ERR_LEN BIT5
#define RX_DEFRAG BIT6
#define RX_ERR_RATE BIT7
#define MEDIA_STS BIT0
#define LINK_STS BIT1
#define OS_CHK BIT0
#define BCN_SHOW BIT0
#define BCN_PEER BIT1
#define ISR_CHK BIT0
#define PHY_BBR BIT0
#define PHY_BBW BIT1
#define PHY_RFR BIT2
#define PHY_RFW BIT3
#define PHY_MACR BIT4
#define PHY_MACW BIT5
#define PHY_ALLR BIT6
#define PHY_ALLW BIT7
#define PHY_TXPWR BIT8
#define PHY_PWRDIFF BIT9
#define MP_RX BIT0
#define MP_SWICH_CH BIT1
#define EEPROM_W BIT0
#define EFUSE_PG BIT1
#define EFUSE_READ_ALL BIT2
#define LPS BIT0
#define IPS BIT1
#define PWRSW BIT2
#define PWRHW BIT3
#define PWRHAL BIT4
#define WA_IOT BIT0
#define DM_PWDB BIT1
#define DM_Monitor BIT2
#define DM_DIG BIT3
#define DM_EDCA_Turbo BIT4
#define DbgCtrl_Trace BIT0
#define DbgCtrl_InbandNoise BIT1
#define BT_TRACE BIT0
#define BT_RFPoll BIT1
#define C2H_Summary BIT0
#define C2H_PacketData BIT1
#define C2H_ContentData BIT2
#define BT_TRACE BIT0
#define BT_RFPoll BIT1
#define INIT_EEPROM BIT0
#define INIT_TxPower BIT1
#define INIT_IQK BIT2
#define INIT_RF BIT3
#define IOCTL_TRACE BIT0
#define IOCTL_BT_EVENT BIT1
#define IOCTL_BT_EVENT_DETAIL BIT2
#define IOCTL_BT_TX_ACLDATA BIT3
#define IOCTL_BT_TX_ACLDATA_DETAIL BIT4
#define IOCTL_BT_RX_ACLDATA BIT5
#define IOCTL_BT_RX_ACLDATA_DETAIL BIT6
#define IOCTL_BT_HCICMD BIT7
#define IOCTL_BT_HCICMD_DETAIL BIT8
#define IOCTL_IRP BIT9
#define IOCTL_IRP_DETAIL BIT10
#define IOCTL_CALLBACK_FUN BIT11
#define IOCTL_STATE BIT12
#define IOCTL_BT_TP BIT13
#define IOCTL_BT_LOGO BIT14
/* 2007/07/13 MH ------For DeBuG Print modeue------*/
/*------------------------------Define structure----------------------------*/
/*------------------------Export Marco Definition---------------------------*/
#define DEBUG_PRINT 1
#if (DEBUG_PRINT == 1)
#define RTPRINT(dbgtype, dbgflag, printstr) \
{ \
if (DBGP_Type[dbgtype] & dbgflag)\
{ \
printk printstr; \
} \
}
#define RTPRINT_ADDR(dbgtype, dbgflag, printstr, _Ptr)\
{\
if (DBGP_Type[dbgtype] & dbgflag)\
{\
int __i; \
u8* ptr = (u8*)_Ptr; \
printk printstr; \
printk(" "); \
for ( __i=0; __i<6; __i++ ) \
printk("%02X%s", ptr[__i], (__i==5)?"":"-"); \
printk("\n"); \
}\
}
#define RTPRINT_DATA(dbgtype, dbgflag, _TitleString, _HexData, _HexDataLen)\
{\
if (DBGP_Type[dbgtype] & dbgflag)\
{\
int __i; \
u8* ptr = (u8*)_HexData; \
printk(_TitleString); \
for ( __i=0; __i<(int)_HexDataLen; __i++ ) \
{ \
printk("%02X%s", ptr[__i], (((__i + 1) % 4) == 0)?" ":" ");\
if (((__i + 1) % 16) == 0) printk("\n");\
} \
printk("\n"); \
}\
}
#else
#define RTPRINT(dbgtype, dbgflag, printstr)
#define RTPRINT_ADDR(dbgtype, dbgflag, printstr, _Ptr)
#define RTPRINT_DATA(dbgtype, dbgflag, _TitleString, _HexData, _HexDataLen)
#endif
extern u32 DBGP_Type[DBGP_TYPE_MAX];
#define RT_PRINT_DATA(_Comp, _Level, _TitleString, _HexData, _HexDataLen) \
do {\
if (((_Comp) & rt_global_debug_component ) && (_Level <= rt_global_debug_component )) \
{ \
int __i; \
u8* ptr = (u8*)_HexData; \
printk("Rtl819x: "); \
printk(_TitleString); \
for ( __i=0; __i<(int)_HexDataLen; __i++ ) \
{ \
printk("%02X%s", ptr[__i], (((__i + 1) % 4) == 0)?" ":" "); \
if (((__i + 1) % 16) == 0) printk("\n"); \
} \
printk("\n"); \
} \
}while(0);
#define DMESG(x,a...)
#define DMESGW(x,a...)
#define DMESGE(x,a...)
extern u32 rt_global_debug_component;
#define RT_TRACE(component, x, args...) \
do { if (rt_global_debug_component & component) \
printk(KERN_DEBUG DRV_NAME ":" x "\n" , \
##args);\
}while(0);
#define RTL819x_DEBUG
#ifdef RTL819x_DEBUG
#define assert(expr) \
if (!(expr)) { \
printk( "Assertion failed! %s,%s,%s,line=%d\n", \
#expr,__FILE__,__func__,__LINE__); \
}
#define RT_DEBUG_DATA(level, data, datalen) \
do{ if ((rt_global_debug_component & (level)) == (level)) \
{ \
int _i; \
u8* _pdata = (u8*) data; \
printk(KERN_DEBUG DRV_NAME ": %s()\n", __func__); \
for (_i=0; _i<(int)(datalen); _i++) \
{ \
printk("%2x ", _pdata[_i]); \
if ((_i+1)%16 == 0) printk("\n"); \
} \
printk("\n"); \
} \
} while (0)
#else
#define assert(expr) do {} while (0)
#define RT_DEBUG_DATA(level, data, datalen) do {} while(0)
#endif
typedef struct _rtl_fs_debug
{
const char *name;
struct dentry *dir_drv;
struct dentry *debug_register;
u32 hw_type;
u32 hw_offset;
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,20))
bool hw_holding;
#else
u8 hw_holding;
#endif
} rtl_fs_debug;
void print_buffer(u32 *buffer, int len);
void dump_eprom(struct net_device *dev);
void rtl8192_dump_reg(struct net_device *dev);
#ifdef RTL8192SE
void rtl8192se_dump_tx_desc(struct _tx_desc_8192se *pDesc);
#endif
#ifdef RTL8192CE
void rtl8192ce_dump_tx_desc(struct _TX_DESC_8192CE *pDesc);
#endif
/* debugfs stuff */
#ifdef CONFIG_RTLWIFI_DEBUGFS
int rtl_debug_module_init(struct r8192_priv *priv, const char *name);
void rtl_debug_module_remove(struct r8192_priv *priv);
int rtl_create_debugfs_root(void);
void rtl_remove_debugfs_root(void);
#else
static inline int rtl_debug_module_init(struct r8192_priv *priv, const char *name) {
return 0;
}
static inline void rtl_debug_module_remove(struct r8192_priv *priv) {
}
static inline int rtl_create_debugfs_root(void) {
return 0;
}
static inline void rtl_remove_debugfs_root(void) {
}
#endif
/* proc stuff */
void rtl8192_proc_init_one(struct net_device *dev);
void rtl8192_proc_remove_one(struct net_device *dev);
void rtl8192_proc_module_init(void);
void rtl8192_proc_module_remove(void);
void rtl8192_dbgp_flag_init(struct net_device *dev);
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,331 @@
/******************************************************************************
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
******************************************************************************/
#ifndef __R8192UDM_H__
#define __R8192UDM_H__
/*--------------------------Define Parameters-------------------------------*/
#define OFDM_Table_Length 19
#define CCK_Table_length 12
#define DM_DIG_THRESH_HIGH 40
#define DM_DIG_THRESH_LOW 35
#define DM_FALSEALARM_THRESH_LOW 40
#define DM_FALSEALARM_THRESH_HIGH 1000
#define DM_DIG_HIGH_PWR_THRESH_HIGH 75
#define DM_DIG_HIGH_PWR_THRESH_LOW 70
#define BW_AUTO_SWITCH_HIGH_LOW 25
#define BW_AUTO_SWITCH_LOW_HIGH 30
#define DM_check_fsync_time_interval 500
#define DM_DIG_BACKOFF 12
#ifdef RTL8192SE
#define DM_DIG_MAX 0x3e
#elif defined RTL8190P || defined RTL8192E
#define DM_DIG_MAX 0x36
#endif
#define DM_DIG_MIN 0x1c
#define DM_DIG_MIN_Netcore 0x12
#define DM_DIG_BACKOFF_MAX 12
#define DM_DIG_BACKOFF_MIN -4
#define RxPathSelection_SS_TH_low 30
#define RxPathSelection_diff_TH 18
#define RateAdaptiveTH_High 50
#define RateAdaptiveTH_Low_20M 30
#define RateAdaptiveTH_Low_40M 10
#define VeryLowRSSI 15
#ifdef RTL8192SE
#define CTSToSelfTHVal 30
#elif defined RTL8190P || defined RTL8192E
#define CTSToSelfTHVal 35
#endif
#define WAIotTHVal 25
#define E_FOR_TX_POWER_TRACK 300
#define TX_POWER_NEAR_FIELD_THRESH_HIGH 68
#define TX_POWER_NEAR_FIELD_THRESH_LOW 62
#define TX_POWER_ATHEROAP_THRESH_HIGH 78
#define TX_POWER_ATHEROAP_THRESH_LOW 72
#define Current_Tx_Rate_Reg 0x1e0
#define Initial_Tx_Rate_Reg 0x1e1
#define Tx_Retry_Count_Reg 0x1ac
#define RegC38_TH 20
#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74
#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67
#define TxHighPwrLevel_Normal 0
#define TxHighPwrLevel_Level1 1
#define TxHighPwrLevel_Level2 2
#define DM_Type_ByFW 0
#define DM_Type_ByDriver 1
/*--------------------------Define Parameters-------------------------------*/
/*------------------------------Define structure----------------------------*/
typedef struct _dynamic_initial_gain_threshold_
{
u8 dig_enable_flag;
u8 dig_algorithm;
u8 Dig_TwoPort_Algorithm;
u8 Dig_Ext_Port_Stage;
u8 dbg_mode;
u8 dig_algorithm_switch;
long rssi_low_thresh;
long rssi_high_thresh;
u32 FALowThresh;
u32 FAHighThresh;
long rssi_high_power_lowthresh;
long rssi_high_power_highthresh;
u8 dig_state;
u8 dig_highpwr_state;
u8 CurSTAConnectState;
u8 PreSTAConnectState;
u8 CurAPConnectState;
u8 PreAPConnectState;
u8 curpd_thstate;
u8 prepd_thstate;
u8 curcs_ratio_state;
u8 precs_ratio_state;
u32 pre_ig_value;
u32 cur_ig_value;
u8 Backoff_Enable_Flag;
u8 backoff_val;
char BackoffVal_range_max;
char BackoffVal_range_min;
u8 rx_gain_range_max;
u8 rx_gain_range_min;
bool initialgain_lowerbound_state;
long rssi_val;
}dig_t;
typedef enum tag_dynamic_init_gain_state_definition
{
DM_STA_DIG_OFF = 0,
DM_STA_DIG_ON,
DM_STA_DIG_MAX
}dm_dig_sta_e;
typedef enum tag_dynamic_ratr_state_definition
{
DM_RATR_STA_HIGH = 0,
DM_RATR_STA_MIDDLE = 1,
DM_RATR_STA_LOW = 2,
DM_RATR_STA_MAX
}dm_ratr_sta_e;
typedef enum tag_dynamic_init_gain_operation_type_definition
{
DIG_TYPE_THRESH_HIGH = 0,
DIG_TYPE_THRESH_LOW = 1,
DIG_TYPE_THRESH_HIGHPWR_HIGH = 2,
DIG_TYPE_THRESH_HIGHPWR_LOW = 3,
DIG_TYPE_DBG_MODE = 4,
DIG_TYPE_RSSI = 5,
DIG_TYPE_ALGORITHM = 6,
DIG_TYPE_BACKOFF = 7,
DIG_TYPE_PWDB_FACTOR = 8,
DIG_TYPE_RX_GAIN_MIN = 9,
DIG_TYPE_RX_GAIN_MAX = 10,
DIG_TYPE_ENABLE = 20,
DIG_TYPE_DISABLE = 30,
DIG_OP_TYPE_MAX
}dm_dig_op_e;
typedef enum tag_dig_algorithm_definition
{
DIG_ALGO_BY_FALSE_ALARM = 0,
DIG_ALGO_BY_RSSI = 1,
DIG_ALGO_BEFORE_CONNECT_BY_RSSI_AND_ALARM = 2,
DIG_ALGO_BY_TOW_PORT = 3,
DIG_ALGO_MAX
}dm_dig_alg_e;
typedef enum tag_DIG_TWO_PORT_ALGO_Definition
{
DIG_TWO_PORT_ALGO_RSSI = 0,
DIG_TWO_PORT_ALGO_FALSE_ALARM = 1,
}DM_DIG_TWO_PORT_ALG_E;
typedef enum tag_DIG_EXT_PORT_ALGO_Definition
{
DIG_EXT_PORT_STAGE_0 = 0,
DIG_EXT_PORT_STAGE_1 = 1,
DIG_EXT_PORT_STAGE_2 = 2,
DIG_EXT_PORT_STAGE_3 = 3,
DIG_EXT_PORT_STAGE_MAX = 4,
}DM_DIG_EXT_PORT_ALG_E;
typedef enum tag_dig_dbgmode_definition
{
DIG_DBG_OFF = 0,
DIG_DBG_ON = 1,
DIG_DBG_MAX
}dm_dig_dbg_e;
typedef enum tag_dig_connect_definition
{
DIG_STA_DISCONNECT = 0,
DIG_STA_CONNECT = 1,
DIG_STA_BEFORE_CONNECT = 2,
DIG_AP_DISCONNECT = 3,
DIG_AP_CONNECT = 4,
DIG_AP_ADD_STATION = 5,
DIG_CONNECT_MAX
}dm_dig_connect_e;
typedef enum tag_dig_packetdetection_threshold_definition
{
DIG_PD_AT_LOW_POWER = 0,
DIG_PD_AT_NORMAL_POWER = 1,
DIG_PD_AT_HIGH_POWER = 2,
DIG_PD_MAX
}dm_dig_pd_th_e;
typedef enum tag_dig_cck_cs_ratio_state_definition
{
DIG_CS_RATIO_LOWER = 0,
DIG_CS_RATIO_HIGHER = 1,
DIG_CS_MAX
}dm_dig_cs_ratio_e;
typedef struct _Dynamic_Rx_Path_Selection_
{
u8 Enable;
u8 DbgMode;
u8 cck_method;
u8 cck_Rx_path;
u8 SS_TH_low;
u8 diff_TH;
u8 disabledRF;
u8 reserved;
u8 rf_rssi[4];
u8 rf_enable_rssi_th[4];
long cck_pwdb_sta[4];
}DRxPathSel;
typedef enum tag_CCK_Rx_Path_Method_Definition
{
CCK_Rx_Version_1 = 0,
CCK_Rx_Version_2= 1,
CCK_Rx_Version_MAX
}DM_CCK_Rx_Path_Method;
typedef enum tag_DM_DbgMode_Definition
{
DM_DBG_OFF = 0,
DM_DBG_ON = 1,
DM_DBG_MAX
}DM_DBG_E;
typedef struct tag_Tx_Config_Cmd_Format
{
u32 Op;
u32 Length;
u32 Value;
}DCMD_TXCMD_T, *PDCMD_TXCMD_T;
/*------------------------------Define structure----------------------------*/
/*------------------------Export global variable----------------------------*/
extern dig_t dm_digtable;
extern u8 dm_shadow[16][256];
extern DRxPathSel DM_RxPathSelTable;
extern u8 test_flag;
/*------------------------Export global variable----------------------------*/
/*------------------------Export Marco Definition---------------------------*/
#define DM_APInitGainChangeNotify(Event) {dm_digtable.CurAPConnectState = Event;}
/*------------------------Export Marco Definition---------------------------*/
/*--------------------------Exported Function prototype---------------------*/
/*--------------------------Exported Function prototype---------------------*/
extern void init_hal_dm(struct net_device *dev);
extern void deinit_hal_dm(struct net_device *dev);
extern void hal_dm_watchdog(struct net_device *dev);
extern void init_rate_adaptive(struct net_device *dev);
extern void dm_txpower_trackingcallback(void *data);
#ifndef RTL8192SE
extern void dm_cck_txpower_adjust(struct net_device *dev,bool binch14);
#endif
extern void dm_restore_dynamic_mechanism_state(struct net_device *dev);
extern void dm_backup_dynamic_mechanism_state(struct net_device *dev);
extern void dm_change_dynamic_initgain_thresh(struct net_device *dev,
u32 dm_type,
u32 dm_value);
extern void DM_ChangeFsyncSetting(struct net_device *dev,
s32 DM_Type,
s32 DM_Value);
extern void dm_force_tx_fw_info(struct net_device *dev,
u32 force_type,
u32 force_value);
extern void dm_init_edca_turbo(struct net_device *dev);
extern void dm_rf_operation_test_callback(unsigned long data);
extern void dm_rf_pathcheck_workitemcallback(void *data);
extern void dm_fsync_timer_callback(unsigned long data);
extern void dm_check_fsync(struct net_device *dev);
extern void dm_shadow_init(struct net_device *dev);
extern void dm_initialize_txpower_tracking(struct net_device *dev);
#if (defined RTL8192E || defined RTL8192SE)
extern void dm_CheckRfCtrlGPIO(void *data);
#endif
#ifdef RTL8192SE
extern void Power_DomainInit92SE(struct net_device *dev);
#endif
extern void dm_InitRateAdaptiveMask(struct net_device * dev);
#endif /*__R8192UDM_H__ */
/* End of r8192U_dm.h */

View file

@ -0,0 +1,141 @@
/******************************************************************************
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Based on the r8180 driver, which is:
* Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al.
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
******************************************************************************/
#include "rtl_core.h"
#include "rtl_eeprom.h"
void eprom_cs(struct net_device *dev, short bit)
{
if (bit)
write_nic_byte(dev, EPROM_CMD,
(1<<EPROM_CS_SHIFT) | \
read_nic_byte(dev, EPROM_CMD));
else
write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev, EPROM_CMD)\
&~(1<<EPROM_CS_SHIFT));
udelay(EPROM_DELAY);
}
void eprom_ck_cycle(struct net_device *dev)
{
write_nic_byte(dev, EPROM_CMD,
(1<<EPROM_CK_SHIFT) | read_nic_byte(dev,EPROM_CMD));
udelay(EPROM_DELAY);
write_nic_byte(dev, EPROM_CMD,
read_nic_byte(dev, EPROM_CMD) &~ (1<<EPROM_CK_SHIFT));
udelay(EPROM_DELAY);
}
void eprom_w(struct net_device *dev,short bit)
{
if (bit)
write_nic_byte(dev, EPROM_CMD, (1<<EPROM_W_SHIFT) | \
read_nic_byte(dev,EPROM_CMD));
else
write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev,EPROM_CMD)\
&~(1<<EPROM_W_SHIFT));
udelay(EPROM_DELAY);
}
short eprom_r(struct net_device *dev)
{
short bit;
bit=(read_nic_byte(dev, EPROM_CMD) & (1<<EPROM_R_SHIFT) );
udelay(EPROM_DELAY);
if (bit)
return 1;
return 0;
}
void eprom_send_bits_string(struct net_device *dev, short b[], int len)
{
int i;
for (i=0; i<len; i++){
eprom_w(dev, b[i]);
eprom_ck_cycle(dev);
}
}
u32 eprom_read(struct net_device *dev, u32 addr)
{
struct r8192_priv *priv = rtllib_priv(dev);
short read_cmd[]={1,1,0};
short addr_str[8];
int i;
int addr_len;
u32 ret;
ret=0;
write_nic_byte(dev, EPROM_CMD,
(EPROM_CMD_PROGRAM<<EPROM_CMD_OPERATING_MODE_SHIFT));
udelay(EPROM_DELAY);
if (priv->epromtype==EEPROM_93C56){
addr_str[7]=addr & 1;
addr_str[6]=addr & (1<<1);
addr_str[5]=addr & (1<<2);
addr_str[4]=addr & (1<<3);
addr_str[3]=addr & (1<<4);
addr_str[2]=addr & (1<<5);
addr_str[1]=addr & (1<<6);
addr_str[0]=addr & (1<<7);
addr_len=8;
}else{
addr_str[5]=addr & 1;
addr_str[4]=addr & (1<<1);
addr_str[3]=addr & (1<<2);
addr_str[2]=addr & (1<<3);
addr_str[1]=addr & (1<<4);
addr_str[0]=addr & (1<<5);
addr_len=6;
}
eprom_cs(dev, 1);
eprom_ck_cycle(dev);
eprom_send_bits_string(dev, read_cmd, 3);
eprom_send_bits_string(dev, addr_str, addr_len);
eprom_w(dev, 0);
for (i = 0; i < 16; i++){
eprom_ck_cycle(dev);
ret |= (eprom_r(dev)<<(15-i));
}
eprom_cs(dev, 0);
eprom_ck_cycle(dev);
write_nic_byte(dev, EPROM_CMD,
(EPROM_CMD_NORMAL<<EPROM_CMD_OPERATING_MODE_SHIFT));
return ret;
}

View file

@ -0,0 +1,29 @@
/******************************************************************************
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Based on the r8180 driver, which is:
* Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al.
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
******************************************************************************/
#define EPROM_DELAY 10
u32 eprom_read(struct net_device *dev,u32 addr);

View file

@ -0,0 +1,59 @@
/******************************************************************************
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Based on the r8180 driver, which is:
* Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al.
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
*****************************************************************************
*/
#include <linux/netdevice.h>
#include <linux/ethtool.h>
#include <linux/delay.h>
#include "rtl_core.h"
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
static void rtl819x_ethtool_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *info)
{
struct r8192_priv *priv = rtllib_priv(dev);
strcpy(info->driver, DRV_NAME);
strcpy(info->version, DRV_VERSION);
#if defined RTL8192SE
snprintf(info->fw_version, sizeof(info->fw_version), "%d",
priv->pFirmware->FirmwareVersion);
#endif
strcpy(info->bus_info, pci_name(priv->pdev));
}
static u32 rtl819x_ethtool_get_link(struct net_device *dev)
{
struct r8192_priv *priv = rtllib_priv(dev);
return ((priv->rtllib->state == RTLLIB_LINKED) ||
(priv->rtllib->state == RTLLIB_LINKED_SCANNING));
}
const struct ethtool_ops rtl819x_ethtool_ops = {
.get_drvinfo = rtl819x_ethtool_get_drvinfo,
.get_link = rtl819x_ethtool_get_link,
};
#endif

View file

@ -0,0 +1,444 @@
/******************************************************************************
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Based on the r8180 driver, which is:
* Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al.
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
*****************************************************************************/
#include "rtl_pci.h"
#include "rtl_core.h"
#if defined RTL8192CE || defined RTL8192SE
bool
rtl8192_get_LinkControl_field(
struct net_device *dev,
u8 BusNum,
u8 DevNum,
u8 FuncNum
)
{
struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
RT_PCI_CAPABILITIES_HEADER CapabilityHdr;
unsigned char CapabilityOffset, Num4Bytes;
u32 PciCfgAddrPort=0;
u8 LinkCtrlReg;
bool Status = false;
if ( BusNum == 0xff && DevNum == 0xff && FuncNum == 0xff ){
printk("GetLinkControlField(): Fail to find PCIe Capability\n");
return false;
}
PciCfgAddrPort= (BusNum<< 16)|(DevNum << 11)|(FuncNum << 8)|(1 << 31);
Num4Bytes = 0x34/4;
NdisRawWritePortUlong(PCI_CONF_ADDRESS , PciCfgAddrPort+( Num4Bytes<< 2));
NdisRawReadPortUchar(PCI_CONF_DATA, &CapabilityOffset);
while (CapabilityOffset != 0)
{
Num4Bytes = CapabilityOffset/4;
NdisRawWritePortUlong(PCI_CONF_ADDRESS , PciCfgAddrPort+( Num4Bytes<< 2));
NdisRawReadPortUshort(PCI_CONF_DATA, (u16*)&CapabilityHdr);
if (CapabilityHdr.CapabilityID == PCI_CAPABILITY_ID_PCI_EXPRESS)
{
break;
}
else
{
CapabilityOffset = CapabilityHdr.Next;
}
}
if (CapabilityHdr.CapabilityID == PCI_CAPABILITY_ID_PCI_EXPRESS)
{
Num4Bytes = (CapabilityOffset+0x10)/4;
NdisRawWritePortUlong(PCI_CONF_ADDRESS , PciCfgAddrPort+(Num4Bytes << 2));
NdisRawReadPortUchar(PCI_CONF_DATA, &LinkCtrlReg);
priv->NdisAdapter.PciBridgePCIeHdrOffset = CapabilityOffset;
priv->NdisAdapter.PciBridgeLinkCtrlReg = LinkCtrlReg;
Status = true;
}
else
{
printk("GetLinkControlField(): Cannot Find PCIe Capability\n");
}
return Status;
}
bool
rtl8192_get_pci_BusInfo(
struct net_device *dev,
u16 VendorId,
u16 DeviceId,
u8 IRQL,
u8 BaseCode,
u8 SubClass,
u8 filed19val,
u8* BusNum,
u8* DevNum,
u8* FuncNum
)
{
u8 busNumIdx, deviceNumIdx, functionNumIdx;
u32 PciCfgAddrPort=0;
u32 devVenID = 0, classCode, field19, headertype;
u16 venId, devId;
u8 basec, subc, irqLine;
u16 RegOffset;
bool bSingleFunc = false;
bool bBridgeChk = false;
*BusNum = 0xFF;
*DevNum = 0xFF;
*FuncNum = 0xFF;
if ((BaseCode == PCI_CLASS_BRIDGE_DEV) && (SubClass==PCI_SUBCLASS_BR_PCI_TO_PCI) && (filed19val==U1DONTCARE))
bBridgeChk = true;
for (busNumIdx = 0; busNumIdx < PCI_MAX_BRIDGE_NUMBER ; busNumIdx++)
{
for (deviceNumIdx = 0; deviceNumIdx < PCI_MAX_DEVICES; deviceNumIdx ++)
{
bSingleFunc = false;
for (functionNumIdx = 0; functionNumIdx < PCI_MAX_FUNCTION; functionNumIdx++)
{
if (functionNumIdx == 0)
{
PciCfgAddrPort= (busNumIdx << 16)|(deviceNumIdx << 11)|(functionNumIdx << 8)|(1 << 31);
NdisRawWritePortUlong(PCI_CONF_ADDRESS , PciCfgAddrPort + (3 << 2));
NdisRawReadPortUlong(PCI_CONF_DATA, &headertype);
headertype = ((headertype >> 16) & 0x0080) >> 7;
if ( headertype == 0)
bSingleFunc = true;
}
else
{
if (bSingleFunc == true) break;
}
PciCfgAddrPort= (busNumIdx << 16)|(deviceNumIdx << 11)|(functionNumIdx << 8)|(1 << 31);
NdisRawWritePortUlong(PCI_CONF_ADDRESS , PciCfgAddrPort);
NdisRawReadPortUlong(PCI_CONF_DATA, &devVenID);
if ( devVenID == 0xFFFFFFFF||devVenID == 0 ) continue;
RegOffset = 0x3C;
PciCfgAddrPort= (busNumIdx << 16)|(deviceNumIdx << 11)|(functionNumIdx << 8)|(1 << 31)|(RegOffset & 0xFFFFFFFC);
NdisRawWritePortUlong(PCI_CONF_ADDRESS , PciCfgAddrPort);
NdisRawReadPortUchar((PCI_CONF_DATA+ (RegOffset & 0x3)), &irqLine);
venId = (u16)(devVenID >> 0)& 0xFFFF;
devId = (u16)(devVenID >> 16)& 0xFFFF;
if (!bBridgeChk && (venId != VendorId) && (VendorId != U2DONTCARE))
continue;
if (!bBridgeChk && (devId != DeviceId) && (DeviceId != U2DONTCARE))
continue;
if (!bBridgeChk && (irqLine != IRQL) && (IRQL != U1DONTCARE))
continue;
PciCfgAddrPort= (busNumIdx << 16)|(deviceNumIdx << 11)|(functionNumIdx << 8)|(1 << 31);
NdisRawWritePortUlong(PCI_CONF_ADDRESS , PciCfgAddrPort + (2 << 2));
NdisRawReadPortUlong(PCI_CONF_DATA, &classCode);
classCode = classCode >> 8;
basec = (u8)(classCode >>16 ) & 0xFF;
subc = (u8)(classCode >>8 ) & 0xFF;
if (bBridgeChk && (venId != VendorId) &&(basec == BaseCode) && (subc== SubClass ) )
return true;
if (bBridgeChk && (venId != VendorId) && (VendorId != U2DONTCARE))
continue;
if (bBridgeChk && (devId != DeviceId) && (DeviceId != U2DONTCARE))
continue;
if (bBridgeChk && (irqLine != IRQL) && (IRQL != U1DONTCARE))
continue;
NdisRawWritePortUlong(PCI_CONF_ADDRESS , PciCfgAddrPort + (6 << 2));
NdisRawReadPortUlong(PCI_CONF_DATA, &field19);
field19 = (field19 >> 8)& 0xFF;
if ((basec == BaseCode) && (subc== SubClass ) && ((field19 == filed19val) ||(filed19val==U1DONTCARE) ))
{
*BusNum = busNumIdx;
*DevNum = deviceNumIdx;
*FuncNum = functionNumIdx;
printk( "GetPciBusInfo(): Find Device(%X:%X) bus=%d dev=%d, func=%d\n",VendorId, DeviceId, busNumIdx, deviceNumIdx, functionNumIdx);
return true;
}
}
}
}
printk( "GetPciBusInfo(): Cannot Find Device(%X:%X:%X)\n",VendorId, DeviceId, devVenID);
return false;
}
bool rtl8192_get_pci_BridegInfo(
struct net_device *dev,
u8 BaseCode,
u8 SubClass,
u8 filed19val,
u8* BusNum,
u8* DevNum,
u8* FuncNum,
u16* VendorId,
u16* DeviceId
)
{
u8 busNumIdx, deviceNumIdx, functionNumIdx;
u32 PciCfgAddrPort=0;
u32 devVenID, classCode, field19, headertype;
u16 venId, devId;
u8 basec, subc, irqLine;
u16 RegOffset;
bool bSingleFunc = false;
*BusNum = 0xFF;
*DevNum = 0xFF;
*FuncNum = 0xFF;
for (busNumIdx = 0; busNumIdx < PCI_MAX_BRIDGE_NUMBER ; busNumIdx++)
{
for (deviceNumIdx = 0; deviceNumIdx < PCI_MAX_DEVICES; deviceNumIdx ++)
{
bSingleFunc = false;
for (functionNumIdx = 0; functionNumIdx < PCI_MAX_FUNCTION; functionNumIdx++)
{
if (functionNumIdx == 0)
{
PciCfgAddrPort= (busNumIdx << 16)|(deviceNumIdx << 11)|(functionNumIdx << 8)|(1 << 31);
NdisRawWritePortUlong(PCI_CONF_ADDRESS , PciCfgAddrPort + (3 << 2));
NdisRawReadPortUlong(PCI_CONF_DATA, &headertype);
headertype = ((headertype >> 16) & 0x0080) >> 7;
if ( headertype == 0)
bSingleFunc = true;
}
else
{
if ( bSingleFunc ==true ) break;
}
PciCfgAddrPort= (busNumIdx << 16)|(deviceNumIdx << 11)|(functionNumIdx << 8)|(1 << 31);
NdisRawWritePortUlong(PCI_CONF_ADDRESS , PciCfgAddrPort);
NdisRawReadPortUlong(PCI_CONF_DATA, &devVenID);
RegOffset = 0x3C;
PciCfgAddrPort= (busNumIdx << 16)|(deviceNumIdx << 11)|(functionNumIdx << 8)|(1 << 31)|(RegOffset & 0xFFFFFFFC);
NdisRawWritePortUlong(PCI_CONF_ADDRESS , PciCfgAddrPort);
NdisRawReadPortUchar((PCI_CONF_DATA+ (RegOffset & 0x3)), &irqLine);
venId = (u16)(devVenID >> 0)& 0xFFFF;
devId = (u16)(devVenID >> 16)& 0xFFFF;
PciCfgAddrPort= (busNumIdx << 16)|(deviceNumIdx << 11)|(functionNumIdx << 8)|(1 << 31);
NdisRawWritePortUlong(PCI_CONF_ADDRESS , PciCfgAddrPort + (2 << 2));
NdisRawReadPortUlong(PCI_CONF_DATA, &classCode);
classCode = classCode >> 8;
basec = (u8)(classCode >>16 ) & 0xFF;
subc = (u8)(classCode >>8 ) & 0xFF;
NdisRawWritePortUlong(PCI_CONF_ADDRESS , PciCfgAddrPort + (6 << 2));
NdisRawReadPortUlong(PCI_CONF_DATA, &field19);
field19 = (field19 >> 8)& 0xFF;
if ((basec == BaseCode) && (subc== SubClass ) && ((field19 == filed19val) ||(filed19val==U1DONTCARE) ))
{
*BusNum = busNumIdx;
*DevNum = deviceNumIdx;
*FuncNum = functionNumIdx;
*VendorId = venId;
*DeviceId = devId;
printk("GetPciBridegInfo : Find Device(%X:%X) bus=%d dev=%d, func=%d\n",
venId, devId, busNumIdx, deviceNumIdx, functionNumIdx);
return true;
}
}
}
}
printk( "GetPciBridegInfo(): Cannot Find PciBridge for Device\n");
return false;
}
static u16 PciBridgeVendorArray[PCI_BRIDGE_VENDOR_MAX]
= {INTEL_VENDOR_ID,ATI_VENDOR_ID,AMD_VENDOR_ID,SIS_VENDOR_ID};
void
rtl8192_pci_find_BridgeInfo(struct net_device *dev)
{
struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
u8 PciBridgeBusNum = 0xff;
u8 PciBridgeDevNum = 0xff;
u8 PciBridgeFuncNum = 0xff;
u16 PciBridgeVendorId= 0xff;
u16 PciBridgeDeviceId = 0xff;
u8 tmp = 0;
rtl8192_get_pci_BridegInfo(dev,
PCI_CLASS_BRIDGE_DEV,
PCI_SUBCLASS_BR_PCI_TO_PCI ,
priv->NdisAdapter.BusNumber,
&PciBridgeBusNum,
&PciBridgeDevNum,
&PciBridgeFuncNum,
&PciBridgeVendorId,
&PciBridgeDeviceId);
priv->NdisAdapter.PciBridgeVendor = PCI_BRIDGE_VENDOR_UNKNOWN;
for (tmp = 0; tmp < PCI_BRIDGE_VENDOR_MAX; tmp++) {
if (PciBridgeVendorId == PciBridgeVendorArray[tmp]) {
priv->NdisAdapter.PciBridgeVendor = tmp;
printk("Pci Bridge Vendor is found index: %d\n",tmp);
break;
}
}
printk("Pci Bridge Vendor is %x\n",PciBridgeVendorArray[tmp]);
priv->NdisAdapter.PciBridgeBusNum = PciBridgeBusNum;
priv->NdisAdapter.PciBridgeDevNum = PciBridgeDevNum;
priv->NdisAdapter.PciBridgeFuncNum = PciBridgeFuncNum;
priv->NdisAdapter.PciBridgeVendorId = PciBridgeVendorId;
priv->NdisAdapter.PciBridgeDeviceId = PciBridgeDeviceId;
}
#endif
static void rtl8192_parse_pci_configuration(struct pci_dev *pdev, struct net_device *dev)
{
struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
u8 tmp;
int pos;
u8 LinkCtrlReg;
pos = pci_find_capability(priv->pdev, PCI_CAP_ID_EXP);
pci_read_config_byte(priv->pdev, pos + PCI_EXP_LNKCTL, &LinkCtrlReg);
priv->NdisAdapter.LinkCtrlReg = LinkCtrlReg;
RT_TRACE(COMP_INIT, "Link Control Register =%x\n", priv->NdisAdapter.LinkCtrlReg);
pci_read_config_byte(pdev, 0x98, &tmp);
tmp |=BIT4;
pci_write_config_byte(pdev, 0x98, tmp);
tmp = 0x17;
pci_write_config_byte(pdev, 0x70f, tmp);
}
bool rtl8192_pci_findadapter(struct pci_dev *pdev, struct net_device *dev)
{
struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
u16 VenderID;
u16 DeviceID;
u8 RevisionID;
u16 IrqLine;
VenderID = pdev->vendor;
DeviceID = pdev->device;
RevisionID = pdev->revision;
pci_read_config_word(pdev, 0x3C, &IrqLine);
priv->card_8192 = priv->ops->nic_type;
if (DeviceID == 0x8172) {
switch (RevisionID) {
case HAL_HW_PCI_REVISION_ID_8192PCIE:
printk("Adapter(8192 PCI-E) is found - DeviceID=%x\n", DeviceID);
priv->card_8192 = NIC_8192E;
break;
case HAL_HW_PCI_REVISION_ID_8192SE:
printk("Adapter(8192SE) is found - DeviceID=%x\n", DeviceID);
priv->card_8192 = NIC_8192SE;
break;
default:
printk("UNKNOWN nic type(%4x:%4x)\n", pdev->vendor, pdev->device);
priv->card_8192 = NIC_UNKNOWN;
return false;
}
}
if (priv->ops->nic_type != priv->card_8192) {
printk("Detect info(%x) and hardware info(%x) not match!\n",
priv->ops->nic_type, priv->card_8192);
printk("Please select proper driver before install!!!!\n");
return false;
}
#if defined RTL8192CE || defined RTL8192SE
rtl8192_get_pci_BusInfo(dev,
VenderID,
DeviceID,
(u8)IrqLine,
0x02,0x80, U1DONTCARE,
&priv->NdisAdapter.BusNumber,
&priv->NdisAdapter.DevNumber,
&priv->NdisAdapter.FuncNumber);
rtl8192_pci_find_BridgeInfo(dev);
#ifdef RTL8192SE
if (priv->NdisAdapter.PciBridgeVendor != PCI_BRIDGE_VENDOR_UNKNOWN)
#endif
{
rtl8192_get_LinkControl_field(dev, priv->NdisAdapter.PciBridgeBusNum,
priv->NdisAdapter.PciBridgeDevNum, priv->NdisAdapter.PciBridgeFuncNum);
}
#endif
rtl8192_parse_pci_configuration(pdev, dev);
return true;
}

View file

@ -0,0 +1,104 @@
/******************************************************************************
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Based on the r8180 driver, which is:
* Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al.
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
******************************************************************************/
#ifndef _RTL_PCI_H
#define _RTL_PCI_H
#include <linux/types.h>
#include <linux/pci.h>
#include "rtllib.h"
static inline void NdisRawWritePortUlong(u32 port, u32 val)
{
outl(val, port);
}
static inline void NdisRawWritePortUchar(u32 port, u8 val)
{
outb(val, port);
}
static inline void NdisRawReadPortUchar(u32 port, u8 *pval)
{
*pval = inb(port);
}
static inline void NdisRawReadPortUshort(u32 port, u16 *pval)
{
*pval = inw(port);
}
static inline void NdisRawReadPortUlong(u32 port, u32 *pval)
{
*pval = inl(port);
}
typedef struct _mp_adapter{
u8 LinkCtrlReg;
u8 BusNumber;
u8 DevNumber;
u8 FuncNumber;
u8 PciBridgeBusNum;
u8 PciBridgeDevNum;
u8 PciBridgeFuncNum;
u8 PciBridgeVendor;
u16 PciBridgeVendorId;
u16 PciBridgeDeviceId;
u8 PciBridgePCIeHdrOffset;
u8 PciBridgeLinkCtrlReg;
}mp_adapter,*pmp_adapter;
typedef struct _RT_PCI_CAPABILITIES_HEADER {
unsigned char CapabilityID;
unsigned char Next;
} RT_PCI_CAPABILITIES_HEADER, *PRT_PCI_CAPABILITIES_HEADER;
#define PCI_MAX_BRIDGE_NUMBER 255
#define PCI_MAX_DEVICES 32
#define PCI_MAX_FUNCTION 8
#define PCI_CONF_ADDRESS 0x0CF8
#define PCI_CONF_DATA 0x0CFC
#define PCI_CLASS_BRIDGE_DEV 0x06
#define PCI_SUBCLASS_BR_PCI_TO_PCI 0x04
#define U1DONTCARE 0xFF
#define U2DONTCARE 0xFFFF
#define U4DONTCARE 0xFFFFFFFF
#define INTEL_VENDOR_ID 0x8086
#define SIS_VENDOR_ID 0x1039
#define ATI_VENDOR_ID 0x1002
#define ATI_DEVICE_ID 0x7914
#define AMD_VENDOR_ID 0x1022
#define PCI_CAPABILITY_ID_PCI_EXPRESS 0x10
struct net_device;
bool rtl8192_pci_findadapter(struct pci_dev *pdev, struct net_device *dev);
#endif

View file

@ -0,0 +1,168 @@
/******************************************************************************
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
******************************************************************************/
#ifdef CONFIG_PM_RTL
#include "rtl_core.h"
#include "r8192E_hw.h"
#include "r8190P_rtl8256.h"
#include "rtl_pm.h"
int rtl8192E_save_state (struct pci_dev *dev, pm_message_t state)
{
printk(KERN_NOTICE "r8192E save state call (state %u).\n", state.event);
return(-EAGAIN);
}
int rtl8192E_suspend (struct pci_dev *pdev, pm_message_t state)
{
struct net_device *dev = pci_get_drvdata(pdev);
struct r8192_priv *priv = rtllib_priv(dev);
#if !(defined RTL8192SE || defined RTL8192CE)
u32 ulRegRead;
#endif
RT_TRACE(COMP_POWER, "============> r8192E suspend call.\n");
printk("============> r8192E suspend call.\n");
#ifdef ENABLE_GPIO_RADIO_CTL
del_timer_sync(&priv->gpio_polling_timer);
cancel_delayed_work(&priv->gpio_change_rf_wq);
priv->polling_timer_on = 0;
#endif
if (!netif_running(dev)){
printk("RTL819XE:UI is open out of suspend function\n");
goto out_pci_suspend;
}
#ifdef HAVE_NET_DEVICE_OPS
if (dev->netdev_ops->ndo_stop)
dev->netdev_ops->ndo_stop(dev);
#else
dev->stop(dev);
#endif
netif_device_detach(dev);
#if !(defined RTL8192SE || defined RTL8192CE)
if (!priv->rtllib->bSupportRemoteWakeUp) {
MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_INIT,true);
ulRegRead = read_nic_dword(dev, CPU_GEN);
ulRegRead|=CPU_GEN_SYSTEM_RESET;
write_nic_dword(dev, CPU_GEN, ulRegRead);
} else {
write_nic_dword(dev, WFCRC0, 0xffffffff);
write_nic_dword(dev, WFCRC1, 0xffffffff);
write_nic_dword(dev, WFCRC2, 0xffffffff);
#ifdef RTL8190P
{
u8 ucRegRead;
ucRegRead = read_nic_byte(dev, GPO);
ucRegRead |= BIT0;
write_nic_byte(dev, GPO, ucRegRead);
}
#endif
write_nic_byte(dev, PMR, 0x5);
write_nic_byte(dev, MacBlkCtrl, 0xa);
}
#endif
out_pci_suspend:
RT_TRACE(COMP_POWER, "r8192E support WOL call??????????????????????\n");
printk("r8192E support WOL call??????????????????????\n");
if (priv->rtllib->bSupportRemoteWakeUp) {
RT_TRACE(COMP_POWER, "r8192E support WOL call!!!!!!!!!!!!!!!!!!.\n");
}
pci_save_state(pdev);
pci_disable_device(pdev);
pci_enable_wake(pdev, pci_choose_state(pdev,state),\
priv->rtllib->bSupportRemoteWakeUp?1:0);
pci_set_power_state(pdev,pci_choose_state(pdev,state));
mdelay(20);
return 0;
}
int rtl8192E_resume (struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
#if defined ENABLE_GPIO_RADIO_CTL || !(defined RTL8192SE || defined RTL8192CE)
struct r8192_priv *priv = rtllib_priv(dev);
#endif
int err;
u32 val;
RT_TRACE(COMP_POWER, "================>r8192E resume call.");
printk("================>r8192E resume call.\n");
pci_set_power_state(pdev, PCI_D0);
err = pci_enable_device(pdev);
if (err) {
printk(KERN_ERR "%s: pci_enable_device failed on resume\n",
dev->name);
return err;
}
pci_restore_state(pdev);
pci_read_config_dword(pdev, 0x40, &val);
if ((val & 0x0000ff00) != 0) {
pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
}
pci_enable_wake(pdev, PCI_D0, 0);
#ifdef ENABLE_GPIO_RADIO_CTL
if (priv->polling_timer_on == 0){
check_rfctrl_gpio_timer((unsigned long)dev);
}
#endif
if (!netif_running(dev)){
printk("RTL819XE:UI is open out of resume function\n");
goto out;
}
netif_device_attach(dev);
#ifdef HAVE_NET_DEVICE_OPS
if (dev->netdev_ops->ndo_open)
dev->netdev_ops->ndo_open(dev);
#else
dev->open(dev);
#endif
#if !(defined RTL8192SE || defined RTL8192CE)
if (!priv->rtllib->bSupportRemoteWakeUp) {
MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_INIT,true);
}
#endif
out:
RT_TRACE(COMP_POWER, "<================r8192E resume call.\n");
return 0;
}
int rtl8192E_enable_wake (struct pci_dev *dev, pm_message_t state, int enable)
{
printk(KERN_NOTICE "r8192E enable wake call (state %u, enable %d).\n",
state.event, enable);
return(-EAGAIN);
}
#endif

View file

@ -0,0 +1,39 @@
/******************************************************************************
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
******************************************************************************/
#ifdef CONFIG_PM_RTL
#ifndef R8192E_PM_H
#define R8192E_PM_H
#include <linux/types.h>
#include <linux/pci.h>
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10))
#define pm_message_t u32
#endif
int rtl8192E_save_state (struct pci_dev *dev, pm_message_t state);
int rtl8192E_suspend (struct pci_dev *dev, pm_message_t state);
int rtl8192E_resume (struct pci_dev *dev);
int rtl8192E_enable_wake (struct pci_dev *dev, pm_message_t state, int enable);
#endif
#endif

View file

@ -0,0 +1,649 @@
/******************************************************************************
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Based on the r8180 driver, which is:
* Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al.
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
*****************************************************************************/
#include "rtl_ps.h"
#include "rtl_core.h"
#include "r8192E_phy.h"
#include "r8192E_phyreg.h"
#include "r8190P_rtl8256.h" /* RTL8225 Radio frontend */
#include "r8192E_cmdpkt.h"
void rtl8192_hw_sleep_down(struct net_device *dev)
{
struct r8192_priv *priv = rtllib_priv(dev);
unsigned long flags = 0;
#ifdef CONFIG_ASPM_OR_D3
PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->rtllib->PowerSaveControl));
#endif
spin_lock_irqsave(&priv->rf_ps_lock,flags);
if (priv->RFChangeInProgress) {
spin_unlock_irqrestore(&priv->rf_ps_lock,flags);
RT_TRACE(COMP_DBG, "rtl8192_hw_sleep_down(): RF Change in progress! \n");
return;
}
spin_unlock_irqrestore(&priv->rf_ps_lock,flags);
RT_TRACE(COMP_DBG, "%s()============>come to sleep down\n", __func__);
#ifdef CONFIG_RTLWIFI_DEBUGFS
if (priv->debug->hw_holding) {
return;
}
#endif
MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS,false);
#ifdef CONFIG_ASPM_OR_D3
if (pPSC->RegRfPsLevel & RT_RF_LPS_LEVEL_ASPM)
{
RT_ENABLE_ASPM(dev);
RT_SET_PS_LEVEL(pPSC, RT_RF_LPS_LEVEL_ASPM);
}
#endif
}
void rtl8192_hw_sleep_wq(void *data)
{
struct rtllib_device *ieee = container_of_dwork_rsl(data,struct rtllib_device,hw_sleep_wq);
struct net_device *dev = ieee->dev;
rtl8192_hw_sleep_down(dev);
}
void rtl8192_hw_wakeup(struct net_device* dev)
{
struct r8192_priv *priv = rtllib_priv(dev);
unsigned long flags = 0;
#ifdef CONFIG_ASPM_OR_D3
PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->rtllib->PowerSaveControl));
#endif
spin_lock_irqsave(&priv->rf_ps_lock,flags);
if (priv->RFChangeInProgress) {
spin_unlock_irqrestore(&priv->rf_ps_lock,flags);
RT_TRACE(COMP_DBG, "rtl8192_hw_wakeup(): RF Change in progress! \n");
queue_delayed_work_rsl(priv->rtllib->wq,&priv->rtllib->hw_wakeup_wq,MSECS(10));
return;
}
spin_unlock_irqrestore(&priv->rf_ps_lock,flags);
#ifdef CONFIG_ASPM_OR_D3
if (pPSC->RegRfPsLevel & RT_RF_LPS_LEVEL_ASPM) {
RT_DISABLE_ASPM(dev);
RT_CLEAR_PS_LEVEL(pPSC, RT_RF_LPS_LEVEL_ASPM);
}
#endif
RT_TRACE(COMP_PS, "%s()============>come to wake up\n", __func__);
MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_PS,false);
}
void rtl8192_hw_wakeup_wq(void *data)
{
struct rtllib_device *ieee = container_of_dwork_rsl(data,struct rtllib_device,hw_wakeup_wq);
struct net_device *dev = ieee->dev;
rtl8192_hw_wakeup(dev);
}
#define MIN_SLEEP_TIME 50
#define MAX_SLEEP_TIME 10000
void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl)
{
struct r8192_priv *priv = rtllib_priv(dev);
u32 rb = jiffies;
unsigned long flags;
spin_lock_irqsave(&priv->ps_lock,flags);
tl -= MSECS(8+16+7);
if (((tl>=rb)&& (tl-rb) <= MSECS(MIN_SLEEP_TIME))
||((rb>tl)&& (rb-tl) < MSECS(MIN_SLEEP_TIME))) {
spin_unlock_irqrestore(&priv->ps_lock,flags);
printk("too short to sleep::%x, %x, %lx\n",tl, rb, MSECS(MIN_SLEEP_TIME));
return;
}
if (((tl > rb) && ((tl-rb) > MSECS(MAX_SLEEP_TIME)))||
((tl < rb) && (tl>MSECS(69)) && ((rb-tl) > MSECS(MAX_SLEEP_TIME)))||
((tl<rb)&&(tl<MSECS(69))&&((tl+0xffffffff-rb)>MSECS(MAX_SLEEP_TIME)))) {
printk("========>too long to sleep:%x, %x, %lx\n", tl, rb, MSECS(MAX_SLEEP_TIME));
spin_unlock_irqrestore(&priv->ps_lock,flags);
return;
}
{
u32 tmp = (tl>rb)?(tl-rb):(rb-tl);
queue_delayed_work_rsl(priv->rtllib->wq,
&priv->rtllib->hw_wakeup_wq,tmp);
}
queue_delayed_work_rsl(priv->rtllib->wq,
(void *)&priv->rtllib->hw_sleep_wq,0);
spin_unlock_irqrestore(&priv->ps_lock,flags);
}
void InactivePsWorkItemCallback(struct net_device *dev)
{
struct r8192_priv *priv = rtllib_priv(dev);
PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->rtllib->PowerSaveControl));
RT_TRACE(COMP_PS, "InactivePsWorkItemCallback() ---------> \n");
pPSC->bSwRfProcessing = true;
RT_TRACE(COMP_PS, "InactivePsWorkItemCallback(): Set RF to %s.\n", \
pPSC->eInactivePowerState == eRfOff?"OFF":"ON");
#ifdef CONFIG_ASPM_OR_D3
if (pPSC->eInactivePowerState == eRfOn)
{
if ((pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_ASPM) && RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_ASPM))
{
RT_DISABLE_ASPM(dev);
RT_CLEAR_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_ASPM);
}
#ifdef TODO
else if ((pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_PCI_D3) && RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_PCI_D3))
{
RT_LEAVE_D3(dev, false);
RT_CLEAR_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_PCI_D3);
}
#endif
}
#endif
MgntActSet_RF_State(dev, pPSC->eInactivePowerState, RF_CHANGE_BY_IPS,false);
#ifdef CONFIG_ASPM_OR_D3
if (pPSC->eInactivePowerState == eRfOff)
{
if (pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_ASPM)
{
RT_ENABLE_ASPM(dev);
RT_SET_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_ASPM);
}
#ifdef TODO
else if (pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_PCI_D3)
{
RT_ENTER_D3(dev, false);
RT_SET_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_PCI_D3);
}
#endif
}
#endif
pPSC->bSwRfProcessing = false;
RT_TRACE(COMP_PS, "InactivePsWorkItemCallback() <--------- \n");
}
void
IPSEnter(struct net_device *dev)
{
struct r8192_priv *priv = rtllib_priv(dev);
PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->rtllib->PowerSaveControl));
RT_RF_POWER_STATE rtState;
if (pPSC->bInactivePs)
{
rtState = priv->rtllib->eRFPowerState;
if (rtState == eRfOn && !pPSC->bSwRfProcessing &&\
(priv->rtllib->state != RTLLIB_LINKED)&&\
(priv->rtllib->iw_mode != IW_MODE_MASTER))
{
RT_TRACE(COMP_PS,"IPSEnter(): Turn off RF.\n");
pPSC->eInactivePowerState = eRfOff;
priv->isRFOff = true;
priv->bInPowerSaveMode = true;
InactivePsWorkItemCallback(dev);
}
}
}
void
IPSLeave(struct net_device *dev)
{
struct r8192_priv *priv = rtllib_priv(dev);
PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->rtllib->PowerSaveControl));
RT_RF_POWER_STATE rtState;
if (pPSC->bInactivePs)
{
rtState = priv->rtllib->eRFPowerState;
if (rtState != eRfOn && !pPSC->bSwRfProcessing && priv->rtllib->RfOffReason <= RF_CHANGE_BY_IPS)
{
RT_TRACE(COMP_PS, "IPSLeave(): Turn on RF.\n");
pPSC->eInactivePowerState = eRfOn;
priv->bInPowerSaveMode = false;
InactivePsWorkItemCallback(dev);
}
}
}
void IPSLeave_wq(void *data)
{
struct rtllib_device *ieee = container_of_work_rsl(data,struct rtllib_device,ips_leave_wq);
struct net_device *dev = ieee->dev;
struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
down(&priv->rtllib->ips_sem);
IPSLeave(dev);
up(&priv->rtllib->ips_sem);
}
void rtllib_ips_leave_wq(struct net_device *dev)
{
struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
RT_RF_POWER_STATE rtState;
rtState = priv->rtllib->eRFPowerState;
if (priv->rtllib->PowerSaveControl.bInactivePs){
if (rtState == eRfOff){
if (priv->rtllib->RfOffReason > RF_CHANGE_BY_IPS)
{
RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__func__);
return;
}
else{
printk("=========>%s(): IPSLeave\n",__func__);
queue_work_rsl(priv->rtllib->wq,&priv->rtllib->ips_leave_wq);
}
}
}
}
void rtllib_ips_leave(struct net_device *dev)
{
struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
down(&priv->rtllib->ips_sem);
IPSLeave(dev);
up(&priv->rtllib->ips_sem);
}
bool MgntActSet_802_11_PowerSaveMode(struct net_device *dev, u8 rtPsMode)
{
struct r8192_priv *priv = rtllib_priv(dev);
if (priv->rtllib->iw_mode == IW_MODE_ADHOC)
return false;
RT_TRACE(COMP_LPS,"%s(): set ieee->ps = %x\n",__func__,rtPsMode);
if (!priv->ps_force) {
priv->rtllib->ps = rtPsMode;
}
if (priv->rtllib->sta_sleep != LPS_IS_WAKE && rtPsMode == RTLLIB_PS_DISABLED) {
unsigned long flags;
rtl8192_hw_wakeup(dev);
priv->rtllib->sta_sleep = LPS_IS_WAKE;
spin_lock_irqsave(&(priv->rtllib->mgmt_tx_lock), flags);
RT_TRACE(COMP_DBG, "LPS leave: notify AP we are awaked"
" ++++++++++ SendNullFunctionData\n");
rtllib_sta_ps_send_null_frame(priv->rtllib, 0);
spin_unlock_irqrestore(&(priv->rtllib->mgmt_tx_lock), flags);
}
return true;
}
void LeisurePSEnter(struct net_device *dev)
{
struct r8192_priv *priv = rtllib_priv(dev);
PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->rtllib->PowerSaveControl));
RT_TRACE(COMP_PS, "LeisurePSEnter()...\n");
RT_TRACE(COMP_PS, "pPSC->bLeisurePs = %d, ieee->ps = %d,pPSC->LpsIdleCount is %d,RT_CHECK_FOR_HANG_PERIOD is %d\n",
pPSC->bLeisurePs, priv->rtllib->ps,pPSC->LpsIdleCount,RT_CHECK_FOR_HANG_PERIOD);
if (!((priv->rtllib->iw_mode == IW_MODE_INFRA) && (priv->rtllib->state == RTLLIB_LINKED))
|| (priv->rtllib->iw_mode == IW_MODE_ADHOC) || (priv->rtllib->iw_mode == IW_MODE_MASTER))
return;
if (pPSC->bLeisurePs) {
if (pPSC->LpsIdleCount >= RT_CHECK_FOR_HANG_PERIOD) {
if (priv->rtllib->ps == RTLLIB_PS_DISABLED) {
RT_TRACE(COMP_LPS, "LeisurePSEnter(): Enter 802.11 power save mode...\n");
if (!pPSC->bFwCtrlLPS) {
if (priv->rtllib->SetFwCmdHandler)
priv->rtllib->SetFwCmdHandler(dev, FW_CMD_LPS_ENTER);
}
MgntActSet_802_11_PowerSaveMode(dev, RTLLIB_PS_MBCAST|RTLLIB_PS_UNICAST);
}
} else
pPSC->LpsIdleCount++;
}
}
void LeisurePSLeave(struct net_device *dev)
{
struct r8192_priv *priv = rtllib_priv(dev);
PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->rtllib->PowerSaveControl));
RT_TRACE(COMP_PS, "LeisurePSLeave()...\n");
RT_TRACE(COMP_PS, "pPSC->bLeisurePs = %d, ieee->ps = %d\n",
pPSC->bLeisurePs, priv->rtllib->ps);
if (pPSC->bLeisurePs)
{
if (priv->rtllib->ps != RTLLIB_PS_DISABLED)
{
#ifdef CONFIG_ASPM_OR_D3
if (pPSC->RegRfPsLevel & RT_RF_LPS_LEVEL_ASPM && RT_IN_PS_LEVEL(pPSC, RT_RF_LPS_LEVEL_ASPM))
{
RT_DISABLE_ASPM(dev);
RT_CLEAR_PS_LEVEL(pPSC, RT_RF_LPS_LEVEL_ASPM);
}
#endif
RT_TRACE(COMP_LPS, "LeisurePSLeave(): Busy Traffic , Leave 802.11 power save..\n");
MgntActSet_802_11_PowerSaveMode(dev, RTLLIB_PS_DISABLED);
if (!pPSC->bFwCtrlLPS)
{
if (priv->rtllib->SetFwCmdHandler)
{
priv->rtllib->SetFwCmdHandler(dev, FW_CMD_LPS_LEAVE);
}
}
}
}
}
#ifdef CONFIG_ASPM_OR_D3
void
PlatformDisableHostL0s(struct net_device *dev)
{
struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
u32 PciCfgAddrPort=0;
u8 Num4Bytes;
u8 uPciBridgeASPMSetting = 0;
if ( (priv->NdisAdapter.BusNumber == 0xff && priv->NdisAdapter.DevNumber == 0xff && priv->NdisAdapter.FuncNumber == 0xff) ||
(priv->NdisAdapter.PciBridgeBusNum == 0xff && priv->NdisAdapter.PciBridgeDevNum == 0xff && priv->NdisAdapter.PciBridgeFuncNum == 0xff) )
{
printk("PlatformDisableHostL0s(): Fail to enable ASPM. Cannot find the Bus of PCI(Bridge).\n");
return;
}
PciCfgAddrPort= (priv->NdisAdapter.PciBridgeBusNum << 16)|(priv->NdisAdapter.PciBridgeDevNum<< 11)|(priv->NdisAdapter.PciBridgeFuncNum << 8)|(1 << 31);
Num4Bytes = (priv->NdisAdapter.PciBridgePCIeHdrOffset+0x10)/4;
NdisRawWritePortUlong(PCI_CONF_ADDRESS , PciCfgAddrPort+(Num4Bytes << 2));
NdisRawReadPortUchar(PCI_CONF_DATA, &uPciBridgeASPMSetting);
if (uPciBridgeASPMSetting & BIT0)
uPciBridgeASPMSetting &= ~(BIT0);
NdisRawWritePortUlong(PCI_CONF_ADDRESS , PciCfgAddrPort+(Num4Bytes << 2));
NdisRawWritePortUchar(PCI_CONF_DATA, uPciBridgeASPMSetting);
udelay(50);
printk("PlatformDisableHostL0s():PciBridge BusNumber[%x], DevNumbe[%x], FuncNumber[%x], Write reg[%x] = %x\n",
priv->NdisAdapter.PciBridgeBusNum, priv->NdisAdapter.PciBridgeDevNum, priv->NdisAdapter.PciBridgeFuncNum,
(priv->NdisAdapter.PciBridgePCIeHdrOffset+0x10), (priv->NdisAdapter.PciBridgeLinkCtrlReg | (priv->RegDevicePciASPMSetting&~BIT0)));
}
bool
PlatformEnable92CEBackDoor(struct net_device *dev)
{
struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
bool bResult = true;
u8 value;
if ( (priv->NdisAdapter.BusNumber == 0xff && priv->NdisAdapter.DevNumber == 0xff && priv->NdisAdapter.FuncNumber == 0xff) ||
(priv->NdisAdapter.PciBridgeBusNum == 0xff && priv->NdisAdapter.PciBridgeDevNum == 0xff && priv->NdisAdapter.PciBridgeFuncNum == 0xff) )
{
RT_TRACE(COMP_INIT, "PlatformEnableASPM(): Fail to enable ASPM. Cannot find the Bus of PCI(Bridge).\n");
return false;
}
pci_read_config_byte(priv->pdev, 0x70f, &value);
if (priv->NdisAdapter.PciBridgeVendor == PCI_BRIDGE_VENDOR_INTEL)
{
value |= BIT7;
}
else
{
value = 0x23;
}
pci_write_config_byte(priv->pdev, 0x70f, value);
pci_read_config_byte(priv->pdev, 0x719, &value);
value |= (BIT3|BIT4);
pci_write_config_byte(priv->pdev, 0x719, value);
return bResult;
}
bool PlatformSwitchDevicePciASPM(struct net_device *dev, u8 value)
{
struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
bool bResult = false;
pci_write_config_byte(priv->pdev, 0x80, value);
return bResult;
}
bool PlatformSwitchClkReq(struct net_device *dev, u8 value)
{
bool bResult = false;
struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
u8 Buffer;
Buffer= value;
#ifdef MERGE_TO_DO
if (Adapter->bDriverIsGoingToPnpSetPowerSleep && pDevice->RegSupportLowPowerState
&& value == 0x0)
return false;
#endif
pci_write_config_byte(priv->pdev,0x81,value);
bResult = true;
#ifdef TODO
if (Buffer) {
priv->ClkReqState = true;
} else {
priv->ClkReqState = false;
}
#endif
#ifdef RTL8192SE
udelay(100);
#endif
return bResult;
}
void
PlatformDisableASPM(struct net_device *dev)
{
struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->rtllib->PowerSaveControl));
#if 1
u32 PciCfgAddrPort=0;
u8 Num4Bytes;
#endif
u8 LinkCtrlReg;
u16 PciBridgeLinkCtrlReg, ASPMLevel=0;
if (priv->NdisAdapter.PciBridgeVendor == PCI_BRIDGE_VENDOR_UNKNOWN)
{
RT_TRACE(COMP_POWER, "%s(): Disable ASPM. Recognize the Bus of PCI(Bridge) as UNKNOWN.\n",__func__);
}
LinkCtrlReg = priv->NdisAdapter.LinkCtrlReg;
PciBridgeLinkCtrlReg = priv->NdisAdapter.PciBridgeLinkCtrlReg;
ASPMLevel |= BIT0|BIT1;
LinkCtrlReg &=~ASPMLevel;
PciBridgeLinkCtrlReg &=~(BIT0|BIT1);
if ( (priv->NdisAdapter.BusNumber == 0xff && priv->NdisAdapter.DevNumber == 0xff && priv->NdisAdapter.FuncNumber == 0xff) ||
(priv->NdisAdapter.PciBridgeBusNum == 0xff && priv->NdisAdapter.PciBridgeDevNum == 0xff && priv->NdisAdapter.PciBridgeFuncNum == 0xff) )
{
} else {
PciCfgAddrPort= (priv->NdisAdapter.PciBridgeBusNum << 16)|(priv->NdisAdapter.PciBridgeDevNum<< 11)|(priv->NdisAdapter.PciBridgeFuncNum << 8)|(1 << 31);
Num4Bytes = (priv->NdisAdapter.PciBridgePCIeHdrOffset+0x10)/4;
NdisRawWritePortUlong(PCI_CONF_ADDRESS , PciCfgAddrPort+(Num4Bytes << 2));
NdisRawWritePortUchar(PCI_CONF_DATA, PciBridgeLinkCtrlReg);
RT_TRACE(COMP_POWER, "PlatformDisableASPM():PciBridge BusNumber[%x], DevNumbe[%x], FuncNumber[%x], Write reg[%x] = %x\n",
priv->NdisAdapter.PciBridgeBusNum, priv->NdisAdapter.PciBridgeDevNum, priv->NdisAdapter.PciBridgeFuncNum,
(priv->NdisAdapter.PciBridgePCIeHdrOffset+0x10), PciBridgeLinkCtrlReg);
udelay(50);
}
}
void PlatformEnableASPM(struct net_device *dev)
{
struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->rtllib->PowerSaveControl));
u16 ASPMLevel = 0;
u32 PciCfgAddrPort=0;
u8 Num4Bytes;
u8 uPciBridgeASPMSetting = 0;
u8 uDeviceASPMSetting = 0;
if ( (priv->NdisAdapter.BusNumber == 0xff && priv->NdisAdapter.DevNumber == 0xff && priv->NdisAdapter.FuncNumber == 0xff) ||
(priv->NdisAdapter.PciBridgeBusNum == 0xff && priv->NdisAdapter.PciBridgeDevNum == 0xff && priv->NdisAdapter.PciBridgeFuncNum == 0xff) )
{
RT_TRACE(COMP_INIT, "PlatformEnableASPM(): Fail to enable ASPM. Cannot find the Bus of PCI(Bridge).\n");
return;
}
#ifdef RTL8192SE
if (priv->NdisAdapter.PciBridgeVendor != PCI_BRIDGE_VENDOR_INTEL )
{
RT_TRACE(COMP_POWER, "%s(): Dont modify ASPM for non intel chipset. For Bridge Vendor %d.\n"
,__func__,priv->NdisAdapter.PciBridgeVendor);
return;
}
#endif
ASPMLevel |= priv->RegDevicePciASPMSetting;
uDeviceASPMSetting = priv->NdisAdapter.LinkCtrlReg;
uDeviceASPMSetting |= ASPMLevel;
PlatformSwitchDevicePciASPM(dev, uDeviceASPMSetting);
if (pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_CLK_REQ) {
PlatformSwitchClkReq(dev,(pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_CLK_REQ) ? 1 : 0);
RT_SET_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_CLK_REQ);
}
udelay(100);
udelay(100);
}
u32 PlatformResetPciSpace(struct net_device *dev,u8 Value)
{
struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
pci_write_config_byte(priv->pdev,0x04,Value);
return 1;
}
bool PlatformSetPMCSR(struct net_device *dev,u8 value,bool bTempSetting)
{
bool bResult = false;
struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
u8 Buffer;
bool bActuallySet=false, bSetFunc=false;
unsigned long flag;
Buffer= value;
spin_lock_irqsave(&priv->D3_lock,flag);
#ifdef TODO
if (bTempSetting)
{
if (Buffer==0x00)
{
priv->LeaveD3Cnt++;
{
bActuallySet =true;
}
}
else
{
priv->LeaveD3Cnt--;
if (priv->LeaveD3Cnt == 0)
{
bActuallySet=true;
}
}
}
else
{
priv->LeaveD3Cnt=0;
bActuallySet=true;
bSetFunc=true;
}
#endif
if (bActuallySet) {
if (Buffer) {
PlatformSwitchClkReq(dev, 0x01);
} else {
PlatformSwitchClkReq(dev, 0x00);
}
pci_write_config_byte(priv->pdev,0x44,Buffer);
RT_TRACE(COMP_POWER, "PlatformSetPMCSR(): D3(value: %d)\n", Buffer);
bResult = true;
if (!Buffer) {
PlatformResetPciSpace(dev, 0x06);
PlatformResetPciSpace(dev, 0x07);
}
if (bSetFunc) {
if (Buffer) {
#ifdef TO_DO_LIST
RT_DISABLE_FUNC(Adapter, DF_IO_D3_BIT);
#endif
} else {
#ifdef TO_DO_LIST
RT_ENABLE_FUNC(Adapter, DF_IO_D3_BIT);
#endif
}
}
}
spin_unlock_irqrestore(&priv->D3_lock,flag);
return bResult;
}
#endif

View file

@ -0,0 +1,64 @@
/******************************************************************************
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Based on the r8180 driver, which is:
* Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al.
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
******************************************************************************/
#ifndef _RTL_PS_H
#define _RTL_PS_H
#include <linux/types.h>
#include "rtllib.h"
struct net_device;
#define RT_CHECK_FOR_HANG_PERIOD 2
#define INIT_DEFAULT_CHAN 1
#if defined CONFIG_ASPM_OR_D3
#define RT_DISABLE_ASPM(dev) PlatformDisableASPM(dev)
#define RT_ENABLE_ASPM(dev) PlatformEnableASPM(dev)
#define RT_ENTER_D3(dev, _bTempSetting) PlatformSetPMCSR(dev, 0x03, _bTempSetting)
#define RT_LEAVE_D3(dev, _bTempSetting) PlatformSetPMCSR(dev, 0, _bTempSetting)
#define RT_DISABLE_HOST_L0S(_PADAPTER) PlatformDisableHostL0s(dev)
void PlatformDisableHostL0s(struct net_device *dev);
bool PlatformEnable92CEBackDoor(struct net_device *dev);
void PlatformDisableASPM(struct net_device *dev);
void PlatformEnableASPM(struct net_device *dev);
u32 PlatformResetPciSpace(struct net_device *dev,u8 Value);
#endif
#if defined(RTL8192E) || defined(RTL8192SE) || defined RTL8192CE
void rtl8192_hw_wakeup(struct net_device *dev);
void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl);
void rtllib_ips_leave_wq(struct net_device *dev);
void rtllib_ips_leave(struct net_device *dev);
void IPSLeave_wq (void *data);
#endif
void IPSEnter(struct net_device *dev);
void IPSLeave(struct net_device *dev);
void LeisurePSEnter(struct net_device *dev);
void LeisurePSLeave(struct net_device *dev);
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,31 @@
/******************************************************************************
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
******************************************************************************/
#ifndef R819x_WX_H
#define R819x_WX_H
struct net_device;
struct iw_handler_def;
struct iw_statistics;
extern struct iw_handler_def r8192_wx_handlers_def;
struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev);
u16 rtl8192_11n_user_show_rates(struct net_device* dev);
#endif

File diff suppressed because it is too large Load diff

View file

@ -11,41 +11,37 @@
*
*/
//#include <linux/config.h>
#include <linux/version.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <asm/string.h>
#include <asm/errno.h>
#include "ieee80211.h"
#include "rtllib.h"
//MODULE_AUTHOR("Jouni Malinen");
//MODULE_DESCRIPTION("HostAP crypto");
//MODULE_LICENSE("GPL");
struct ieee80211_crypto_alg {
struct rtllib_crypto_alg {
struct list_head list;
struct ieee80211_crypto_ops *ops;
struct rtllib_crypto_ops *ops;
};
struct ieee80211_crypto {
struct rtllib_crypto {
struct list_head algs;
spinlock_t lock;
};
static struct ieee80211_crypto *hcrypt;
static struct rtllib_crypto *hcrypt;
void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee,
void rtllib_crypt_deinit_entries(struct rtllib_device *ieee,
int force)
{
struct list_head *ptr, *n;
struct ieee80211_crypt_data *entry;
struct rtllib_crypt_data *entry;
for (ptr = ieee->crypt_deinit_list.next, n = ptr->next;
ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) {
entry = list_entry(ptr, struct ieee80211_crypt_data, list);
entry = list_entry(ptr, struct rtllib_crypt_data, list);
if (atomic_read(&entry->refcnt) != 0 && !force)
continue;
@ -58,13 +54,13 @@ void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee,
}
}
void ieee80211_crypt_deinit_handler(unsigned long data)
void rtllib_crypt_deinit_handler(unsigned long data)
{
struct ieee80211_device *ieee = (struct ieee80211_device *)data;
struct rtllib_device *ieee = (struct rtllib_device *)data;
unsigned long flags;
spin_lock_irqsave(&ieee->lock, flags);
ieee80211_crypt_deinit_entries(ieee, 0);
rtllib_crypt_deinit_entries(ieee, 0);
if (!list_empty(&ieee->crypt_deinit_list)) {
printk(KERN_DEBUG "%s: entries remaining in delayed crypt "
"deletion list\n", ieee->dev->name);
@ -75,10 +71,10 @@ void ieee80211_crypt_deinit_handler(unsigned long data)
}
void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
struct ieee80211_crypt_data **crypt)
void rtllib_crypt_delayed_deinit(struct rtllib_device *ieee,
struct rtllib_crypt_data **crypt)
{
struct ieee80211_crypt_data *tmp;
struct rtllib_crypt_data *tmp;
unsigned long flags;
if (*crypt == NULL)
@ -100,43 +96,44 @@ void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
spin_unlock_irqrestore(&ieee->lock, flags);
}
int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
int rtllib_register_crypto_ops(struct rtllib_crypto_ops *ops)
{
unsigned long flags;
struct ieee80211_crypto_alg *alg;
struct rtllib_crypto_alg *alg;
if (hcrypt == NULL)
return -1;
alg = kzalloc(sizeof(*alg), GFP_KERNEL);
alg = kmalloc(sizeof(*alg), GFP_KERNEL);
if (alg == NULL)
return -ENOMEM;
memset(alg, 0, sizeof(*alg));
alg->ops = ops;
spin_lock_irqsave(&hcrypt->lock, flags);
list_add(&alg->list, &hcrypt->algs);
spin_unlock_irqrestore(&hcrypt->lock, flags);
printk(KERN_DEBUG "ieee80211_crypt: registered algorithm '%s'\n",
printk(KERN_DEBUG "rtllib_crypt: registered algorithm '%s'\n",
ops->name);
return 0;
}
int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops)
int rtllib_unregister_crypto_ops(struct rtllib_crypto_ops *ops)
{
unsigned long flags;
struct list_head *ptr;
struct ieee80211_crypto_alg *del_alg = NULL;
struct rtllib_crypto_alg *del_alg = NULL;
if (hcrypt == NULL)
return -1;
spin_lock_irqsave(&hcrypt->lock, flags);
for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
struct ieee80211_crypto_alg *alg =
(struct ieee80211_crypto_alg *) ptr;
struct rtllib_crypto_alg *alg =
(struct rtllib_crypto_alg *) ptr;
if (alg->ops == ops) {
list_del(&alg->list);
del_alg = alg;
@ -146,7 +143,7 @@ int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops)
spin_unlock_irqrestore(&hcrypt->lock, flags);
if (del_alg) {
printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
printk(KERN_DEBUG "rtllib_crypt: unregistered algorithm "
"'%s'\n", ops->name);
kfree(del_alg);
}
@ -155,19 +152,19 @@ int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops)
}
struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name)
struct rtllib_crypto_ops * rtllib_get_crypto_ops(const char *name)
{
unsigned long flags;
struct list_head *ptr;
struct ieee80211_crypto_alg *found_alg = NULL;
struct rtllib_crypto_alg *found_alg = NULL;
if (hcrypt == NULL)
return NULL;
spin_lock_irqsave(&hcrypt->lock, flags);
for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
struct ieee80211_crypto_alg *alg =
(struct ieee80211_crypto_alg *) ptr;
struct rtllib_crypto_alg *alg =
(struct rtllib_crypto_alg *) ptr;
if (strcmp(alg->ops->name, name) == 0) {
found_alg = alg;
break;
@ -182,13 +179,13 @@ struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name)
}
static void * ieee80211_crypt_null_init(int keyidx) { return (void *) 1; }
static void ieee80211_crypt_null_deinit(void *priv) {}
static void * rtllib_crypt_null_init(int keyidx) { return (void *) 1; }
static void rtllib_crypt_null_deinit(void *priv) {}
static struct ieee80211_crypto_ops ieee80211_crypt_null = {
static struct rtllib_crypto_ops rtllib_crypt_null = {
.name = "NULL",
.init = ieee80211_crypt_null_init,
.deinit = ieee80211_crypt_null_deinit,
.init = rtllib_crypt_null_init,
.deinit = rtllib_crypt_null_deinit,
.encrypt_mpdu = NULL,
.decrypt_mpdu = NULL,
.encrypt_msdu = NULL,
@ -201,18 +198,19 @@ static struct ieee80211_crypto_ops ieee80211_crypt_null = {
};
int __init ieee80211_crypto_init(void)
int __init rtllib_crypto_init(void)
{
int ret = -ENOMEM;
hcrypt = kzalloc(sizeof(*hcrypt), GFP_KERNEL);
hcrypt = kmalloc(sizeof(*hcrypt), GFP_KERNEL);
if (!hcrypt)
goto out;
memset(hcrypt, 0, sizeof(*hcrypt));
INIT_LIST_HEAD(&hcrypt->algs);
spin_lock_init(&hcrypt->lock);
ret = ieee80211_register_crypto_ops(&ieee80211_crypt_null);
ret = rtllib_register_crypto_ops(&rtllib_crypt_null);
if (ret < 0) {
kfree(hcrypt);
hcrypt = NULL;
@ -222,7 +220,7 @@ int __init ieee80211_crypto_init(void)
}
void ieee80211_crypto_deinit(void)
void __exit rtllib_crypto_deinit(void)
{
struct list_head *ptr, *n;
@ -231,14 +229,13 @@ void ieee80211_crypto_deinit(void)
for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs;
ptr = n, n = ptr->next) {
struct ieee80211_crypto_alg *alg =
(struct ieee80211_crypto_alg *) ptr;
struct rtllib_crypto_alg *alg =
(struct rtllib_crypto_alg *) ptr;
list_del(ptr);
printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
printk(KERN_DEBUG "rtllib_crypt: unregistered algorithm "
"'%s' (deinit)\n", alg->ops->name);
kfree(alg);
}
kfree(hcrypt);
}

View file

@ -18,14 +18,14 @@
*/
/*
* This file defines the interface to the ieee80211 crypto module.
* This file defines the interface to the rtllib crypto module.
*/
#ifndef IEEE80211_CRYPT_H
#define IEEE80211_CRYPT_H
#ifndef RTLLIB_CRYPT_H
#define RTLLIB_CRYPT_H
#include <linux/skbuff.h>
struct ieee80211_crypto_ops {
struct rtllib_crypto_ops {
const char *name;
/* init new crypto context (e.g., allocate private data space,
@ -49,7 +49,7 @@ struct ieee80211_crypto_ops {
* These can be NULL if full MSDU operations are not needed. */
int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv);
int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len,
void *priv);
void *priv, struct rtllib_device* ieee);
int (*set_key)(void *key, int len, u8 *seq, void *priv);
int (*get_key)(void *key, int len, u8 *seq, void *priv);
@ -68,18 +68,26 @@ struct ieee80211_crypto_ops {
struct module *owner;
};
struct ieee80211_crypt_data {
struct rtllib_crypt_data {
struct list_head list; /* delayed deletion list */
struct ieee80211_crypto_ops *ops;
struct rtllib_crypto_ops *ops;
void *priv;
atomic_t refcnt;
};
int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops);
int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops);
struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name);
void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int);
void ieee80211_crypt_deinit_handler(unsigned long);
void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
struct ieee80211_crypt_data **crypt);
int rtllib_register_crypto_ops(struct rtllib_crypto_ops *ops);
int rtllib_unregister_crypto_ops(struct rtllib_crypto_ops *ops);
struct rtllib_crypto_ops * rtllib_get_crypto_ops(const char *name);
void rtllib_crypt_deinit_entries(struct rtllib_device *, int);
void rtllib_crypt_deinit_handler(unsigned long);
void rtllib_crypt_delayed_deinit(struct rtllib_device *ieee,
struct rtllib_crypt_data **crypt);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,31))
#define crypto_alloc_tfm crypto_alloc_tfm_rsl
#define crypto_free_tfm crypto_free_tfm_rsl
#endif
#endif

View file

@ -9,7 +9,7 @@
* more details.
*/
//#include <linux/config.h>
#include <linux/version.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
@ -20,19 +20,18 @@
#include <linux/if_arp.h>
#include <asm/string.h>
#include <linux/wireless.h>
#include "rtllib.h"
#include "ieee80211.h"
#if defined(BUILT_IN_CRYPTO) || (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
#include "rtl_crypto.h"
#else
#include <linux/crypto.h>
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
#include <asm/scatterlist.h>
#else
#include <linux/scatterlist.h>
MODULE_AUTHOR("Jouni Malinen");
MODULE_DESCRIPTION("Host AP crypt: CCMP");
MODULE_LICENSE("GPL");
#ifndef OPENSUSE_SLED
#define OPENSUSE_SLED 0
#endif
#define AES_BLOCK_LEN 16
@ -41,7 +40,7 @@ MODULE_LICENSE("GPL");
#define CCMP_TK_LEN 16
#define CCMP_PN_LEN 6
struct ieee80211_ccmp_data {
struct rtllib_ccmp_data {
u8 key[CCMP_TK_LEN];
int key_set;
@ -62,34 +61,68 @@ struct ieee80211_ccmp_data {
u8 rx_b0[AES_BLOCK_LEN], rx_b[AES_BLOCK_LEN], rx_a[AES_BLOCK_LEN];
};
void ieee80211_ccmp_aes_encrypt(struct crypto_tfm *tfm,
void rtllib_ccmp_aes_encrypt(struct crypto_tfm *tfm,
const u8 pt[16], u8 ct[16])
{
#if ( defined(BUILT_IN_CRYPTO) || ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) )
struct scatterlist src, dst;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
src.page = virt_to_page(pt);
src.offset = offset_in_page(pt);
src.length = AES_BLOCK_LEN;
dst.page = virt_to_page(ct);
dst.offset = offset_in_page(ct);
dst.length = AES_BLOCK_LEN;
#else
sg_init_one(&src, pt, AES_BLOCK_LEN);
sg_init_one(&dst, ct, AES_BLOCK_LEN);
#endif
crypto_cipher_encrypt(tfm, &dst, &src, AES_BLOCK_LEN);
#else
crypto_cipher_encrypt_one((void*)tfm, ct, pt);
#endif
}
static void * ieee80211_ccmp_init(int key_idx)
static void * rtllib_ccmp_init(int key_idx)
{
struct ieee80211_ccmp_data *priv;
struct rtllib_ccmp_data *priv;
priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
if (priv == NULL)
goto fail;
memset(priv, 0, sizeof(*priv));
priv->key_idx = key_idx;
#if ( defined(BUILT_IN_CRYPTO) || ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) )
priv->tfm = crypto_alloc_tfm("aes", 0);
if (priv->tfm == NULL) {
printk(KERN_DEBUG "rtllib_crypt_ccmp: could not allocate "
"crypto API aes\n");
goto fail;
}
#else
priv->tfm = (void*)crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(priv->tfm)) {
printk(KERN_DEBUG "ieee80211_crypt_ccmp: could not allocate "
printk(KERN_DEBUG "rtllib_crypt_ccmp: could not allocate "
"crypto API aes\n");
priv->tfm = NULL;
goto fail;
}
#endif
return priv;
fail:
if (priv) {
if (priv->tfm)
#if defined(BUILT_IN_CRYPTO) || (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
crypto_free_tfm(priv->tfm);
#else
crypto_free_cipher((void*)priv->tfm);
#endif
kfree(priv);
}
@ -97,11 +130,15 @@ static void * ieee80211_ccmp_init(int key_idx)
}
static void ieee80211_ccmp_deinit(void *priv)
static void rtllib_ccmp_deinit(void *priv)
{
struct ieee80211_ccmp_data *_priv = priv;
struct rtllib_ccmp_data *_priv = priv;
if (_priv && _priv->tfm)
#if defined(BUILT_IN_CRYPTO) || (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
crypto_free_tfm(_priv->tfm);
#else
crypto_free_cipher((void*)_priv->tfm);
#endif
kfree(priv);
}
@ -116,7 +153,7 @@ static inline void xor_block(u8 *b, u8 *a, size_t len)
static void ccmp_init_blocks(struct crypto_tfm *tfm,
struct ieee80211_hdr_4addr *hdr,
struct rtllib_hdr_4addr *hdr,
u8 *pn, size_t dlen, u8 *b0, u8 *auth,
u8 *s0)
{
@ -127,14 +164,13 @@ static void ccmp_init_blocks(struct crypto_tfm *tfm,
u8 aad[2 * AES_BLOCK_LEN];
fc = le16_to_cpu(hdr->frame_ctl);
a4_included = ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS));
a4_included = ((fc & (RTLLIB_FCTL_TODS | RTLLIB_FCTL_FROMDS)) ==
(RTLLIB_FCTL_TODS | RTLLIB_FCTL_FROMDS));
/*
qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
qc_included = ((WLAN_FC_GET_TYPE(fc) == RTLLIB_FTYPE_DATA) &&
(WLAN_FC_GET_STYPE(fc) & 0x08));
*/
// fixed by David :2006.9.6
qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
qc_included = ((WLAN_FC_GET_TYPE(fc) == RTLLIB_FTYPE_DATA) &&
(WLAN_FC_GET_STYPE(fc) & 0x80));
aad_len = 22;
if (a4_included)
@ -183,26 +219,25 @@ static void ccmp_init_blocks(struct crypto_tfm *tfm,
}
/* Start with the first block and AAD */
ieee80211_ccmp_aes_encrypt(tfm, b0, auth);
rtllib_ccmp_aes_encrypt(tfm, b0, auth);
xor_block(auth, aad, AES_BLOCK_LEN);
ieee80211_ccmp_aes_encrypt(tfm, auth, auth);
rtllib_ccmp_aes_encrypt(tfm, auth, auth);
xor_block(auth, &aad[AES_BLOCK_LEN], AES_BLOCK_LEN);
ieee80211_ccmp_aes_encrypt(tfm, auth, auth);
rtllib_ccmp_aes_encrypt(tfm, auth, auth);
b0[0] &= 0x07;
b0[14] = b0[15] = 0;
ieee80211_ccmp_aes_encrypt(tfm, b0, s0);
rtllib_ccmp_aes_encrypt(tfm, b0, s0);
}
static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
static int rtllib_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
{
struct ieee80211_ccmp_data *key = priv;
struct rtllib_ccmp_data *key = priv;
int data_len, i;
u8 *pos;
struct ieee80211_hdr_4addr *hdr;
struct rtllib_hdr_4addr *hdr;
cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
if (skb_headroom(skb) < CCMP_HDR_LEN ||
skb_tailroom(skb) < CCMP_MIC_LEN ||
skb->len < hdr_len)
@ -212,7 +247,6 @@ static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
pos = skb_push(skb, CCMP_HDR_LEN);
memmove(pos, pos + CCMP_HDR_LEN, hdr_len);
pos += hdr_len;
// mic = skb_put(skb, CCMP_MIC_LEN);
i = CCMP_PN_LEN - 1;
while (i >= 0) {
@ -232,9 +266,8 @@ static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
*pos++ = key->tx_pn[0];
hdr = (struct ieee80211_hdr_4addr *) skb->data;
if (!tcb_desc->bHwSec)
{
hdr = (struct rtllib_hdr_4addr *) skb->data;
if (!tcb_desc->bHwSec) {
int blocks, last, len;
u8 *mic;
u8 *b0 = key->tx_b0;
@ -242,7 +275,6 @@ static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
u8 *e = key->tx_e;
u8 *s0 = key->tx_s0;
//mic is moved to here by john
mic = skb_put(skb, CCMP_MIC_LEN);
ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0);
@ -254,11 +286,11 @@ static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
len = (i == blocks && last) ? last : AES_BLOCK_LEN;
/* Authentication */
xor_block(b, pos, len);
ieee80211_ccmp_aes_encrypt(key->tfm, b, b);
rtllib_ccmp_aes_encrypt(key->tfm, b, b);
/* Encryption, with counter */
b0[14] = (i >> 8) & 0xff;
b0[15] = i & 0xff;
ieee80211_ccmp_aes_encrypt(key->tfm, b0, e);
rtllib_ccmp_aes_encrypt(key->tfm, b0, e);
xor_block(pos, e, len);
pos += len;
}
@ -270,11 +302,11 @@ static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
}
static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
static int rtllib_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
{
struct ieee80211_ccmp_data *key = priv;
struct rtllib_ccmp_data *key = priv;
u8 keyidx, *pos;
struct ieee80211_hdr_4addr *hdr;
struct rtllib_hdr_4addr *hdr;
cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
u8 pn[6];
@ -283,13 +315,13 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
return -1;
}
hdr = (struct ieee80211_hdr_4addr *) skb->data;
hdr = (struct rtllib_hdr_4addr *) skb->data;
pos = skb->data + hdr_len;
keyidx = pos[3];
if (!(keyidx & (1 << 5))) {
if (net_ratelimit()) {
printk(KERN_DEBUG "CCMP: received packet without ExtIV"
" flag from %pM\n", hdr->addr2);
" flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
}
key->dot11RSNAStatsCCMPFormatErrors++;
return -2;
@ -302,9 +334,9 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
}
if (!key->key_set) {
if (net_ratelimit()) {
printk(KERN_DEBUG "CCMP: received packet from %pM"
printk(KERN_DEBUG "CCMP: received packet from " MAC_FMT
" with keyid=%d that does not have a configured"
" key\n", hdr->addr2, keyidx);
" key\n", MAC_ARG(hdr->addr2), keyidx);
}
return -3;
}
@ -316,13 +348,11 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
pn[4] = pos[1];
pn[5] = pos[0];
pos += 8;
if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) {
key->dot11RSNAStatsCCMPReplays++;
return -4;
}
if (!tcb_desc->bHwSec)
{
if (!tcb_desc->bHwSec) {
size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN - CCMP_MIC_LEN;
u8 *mic = skb->data + skb->len - CCMP_MIC_LEN;
u8 *b0 = key->rx_b0;
@ -342,18 +372,18 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
/* Decrypt, with counter */
b0[14] = (i >> 8) & 0xff;
b0[15] = i & 0xff;
ieee80211_ccmp_aes_encrypt(key->tfm, b0, b);
rtllib_ccmp_aes_encrypt(key->tfm, b0, b);
xor_block(pos, b, len);
/* Authentication */
xor_block(a, pos, len);
ieee80211_ccmp_aes_encrypt(key->tfm, a, a);
rtllib_ccmp_aes_encrypt(key->tfm, a, a);
pos += len;
}
if (memcmp(mic, a, CCMP_MIC_LEN) != 0) {
if (net_ratelimit()) {
printk(KERN_DEBUG "CCMP: decrypt failed: STA="
"%pM\n", hdr->addr2);
MAC_FMT "\n", MAC_ARG(hdr->addr2));
}
key->dot11RSNAStatsCCMPDecryptErrors++;
return -5;
@ -370,9 +400,9 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
}
static int ieee80211_ccmp_set_key(void *key, int len, u8 *seq, void *priv)
static int rtllib_ccmp_set_key(void *key, int len, u8 *seq, void *priv)
{
struct ieee80211_ccmp_data *data = priv;
struct rtllib_ccmp_data *data = priv;
int keyidx;
struct crypto_tfm *tfm = data->tfm;
@ -401,9 +431,9 @@ static int ieee80211_ccmp_set_key(void *key, int len, u8 *seq, void *priv)
}
static int ieee80211_ccmp_get_key(void *key, int len, u8 *seq, void *priv)
static int rtllib_ccmp_get_key(void *key, int len, u8 *seq, void *priv)
{
struct ieee80211_ccmp_data *data = priv;
struct rtllib_ccmp_data *data = priv;
if (len < CCMP_TK_LEN)
return -1;
@ -425,22 +455,15 @@ static int ieee80211_ccmp_get_key(void *key, int len, u8 *seq, void *priv)
}
static char * ieee80211_ccmp_print_stats(char *p, void *priv)
static char * rtllib_ccmp_print_stats(char *p, void *priv)
{
struct ieee80211_ccmp_data *ccmp = priv;
int i;
p += sprintf(p, "key[%d] alg=CCMP key_set=%d tx_pn=",
ccmp->key_idx, ccmp->key_set);
for (i = 0; i < ARRAY_SIZE(ccmp->tx_pn); i++)
p += sprintf(p, "%02x", ccmp->tx_pn[i]);
sprintf(p, " rx_pn=");
for (i = 0; i < ARRAY_SIZE(ccmp->rx_pn); i++)
p += sprintf(p, "%02x", ccmp->tx_pn[i]);
p += sprintf(p, " format_errors=%d replays=%d decrypt_errors=%d\n",
struct rtllib_ccmp_data *ccmp = priv;
p += sprintf(p, "key[%d] alg=CCMP key_set=%d "
"tx_pn=%02x%02x%02x%02x%02x%02x "
"rx_pn=%02x%02x%02x%02x%02x%02x "
"format_errors=%d replays=%d decrypt_errors=%d\n",
ccmp->key_idx, ccmp->key_set,
MAC_ARG(ccmp->tx_pn), MAC_ARG(ccmp->rx_pn),
ccmp->dot11RSNAStatsCCMPFormatErrors,
ccmp->dot11RSNAStatsCCMPReplays,
ccmp->dot11RSNAStatsCCMPDecryptErrors);
@ -448,36 +471,35 @@ static char * ieee80211_ccmp_print_stats(char *p, void *priv)
return p;
}
void ieee80211_ccmp_null(void)
void rtllib_ccmp_null(void)
{
return;
}
static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = {
static struct rtllib_crypto_ops rtllib_crypt_ccmp = {
.name = "CCMP",
.init = ieee80211_ccmp_init,
.deinit = ieee80211_ccmp_deinit,
.encrypt_mpdu = ieee80211_ccmp_encrypt,
.decrypt_mpdu = ieee80211_ccmp_decrypt,
.init = rtllib_ccmp_init,
.deinit = rtllib_ccmp_deinit,
.encrypt_mpdu = rtllib_ccmp_encrypt,
.decrypt_mpdu = rtllib_ccmp_decrypt,
.encrypt_msdu = NULL,
.decrypt_msdu = NULL,
.set_key = ieee80211_ccmp_set_key,
.get_key = ieee80211_ccmp_get_key,
.print_stats = ieee80211_ccmp_print_stats,
.set_key = rtllib_ccmp_set_key,
.get_key = rtllib_ccmp_get_key,
.print_stats = rtllib_ccmp_print_stats,
.extra_prefix_len = CCMP_HDR_LEN,
.extra_postfix_len = CCMP_MIC_LEN,
.owner = THIS_MODULE,
};
int __init ieee80211_crypto_ccmp_init(void)
int __init rtllib_crypto_ccmp_init(void)
{
return ieee80211_register_crypto_ops(&ieee80211_crypt_ccmp);
return rtllib_register_crypto_ops(&rtllib_crypt_ccmp);
}
void ieee80211_crypto_ccmp_exit(void)
void __exit rtllib_crypto_ccmp_exit(void)
{
ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp);
rtllib_unregister_crypto_ops(&rtllib_crypt_ccmp);
}

View file

@ -9,7 +9,7 @@
* more details.
*/
//#include <linux/config.h>
#include <linux/version.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
@ -19,24 +19,23 @@
#include <linux/if_ether.h>
#include <linux/if_arp.h>
#include <asm/string.h>
#include "ieee80211.h"
#include "rtllib.h"
#if defined(BUILT_IN_CRYPTO) || (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
#include "rtl_crypto.h"
#else
#include <linux/crypto.h>
#include <linux/scatterlist.h>
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
#include <asm/scatterlist.h>
#else
#include <linux/scatterlist.h>
#endif
#include <linux/crc32.h>
MODULE_AUTHOR("Jouni Malinen");
MODULE_DESCRIPTION("Host AP crypt: TKIP");
MODULE_LICENSE("GPL");
#ifndef OPENSUSE_SLED
#define OPENSUSE_SLED 0
#endif
struct ieee80211_tkip_data {
struct rtllib_tkip_data {
#define TKIP_KEY_LEN 32
u8 key[TKIP_KEY_LEN];
int key_set;
@ -48,6 +47,7 @@ struct ieee80211_tkip_data {
u32 rx_iv32;
u16 rx_iv16;
bool initialized;
u16 rx_ttak[5];
int rx_phase1_done;
u32 rx_iv32_new;
@ -58,26 +58,63 @@ struct ieee80211_tkip_data {
u32 dot11RSNAStatsTKIPLocalMICFailures;
int key_idx;
#if ( !defined(BUILT_IN_CRYPTO) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) || (OPENSUSE_SLED)) )
struct crypto_blkcipher *rx_tfm_arc4;
struct crypto_hash *rx_tfm_michael;
struct crypto_blkcipher *tx_tfm_arc4;
struct crypto_hash *tx_tfm_michael;
#else
struct crypto_tfm *tx_tfm_arc4;
struct crypto_tfm *tx_tfm_michael;
struct crypto_tfm *rx_tfm_arc4;
struct crypto_tfm *rx_tfm_michael;
#endif
/* scratch buffers for virt_to_page() (crypto API) */
u8 rx_hdr[16], tx_hdr[16];
};
static void * ieee80211_tkip_init(int key_idx)
static void * rtllib_tkip_init(int key_idx)
{
struct ieee80211_tkip_data *priv;
struct rtllib_tkip_data *priv;
priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
if (priv == NULL)
goto fail;
memset(priv, 0, sizeof(*priv));
priv->key_idx = key_idx;
#if ( defined(BUILT_IN_CRYPTO) || ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) )
priv->tx_tfm_arc4 = crypto_alloc_tfm("arc4", 0);
if (priv->tx_tfm_arc4 == NULL) {
printk(KERN_DEBUG "rtllib_crypt_tkip: could not allocate "
"crypto API arc4\n");
goto fail;
}
priv->tx_tfm_michael = crypto_alloc_tfm("michael_mic", 0);
if (priv->tx_tfm_michael == NULL) {
printk(KERN_DEBUG "rtllib_crypt_tkip: could not allocate "
"crypto API michael_mic\n");
goto fail;
}
priv->rx_tfm_arc4 = crypto_alloc_tfm("arc4", 0);
if (priv->rx_tfm_arc4 == NULL) {
printk(KERN_DEBUG "rtllib_crypt_tkip: could not allocate "
"crypto API arc4\n");
goto fail;
}
priv->rx_tfm_michael = crypto_alloc_tfm("michael_mic", 0);
if (priv->rx_tfm_michael == NULL) {
printk(KERN_DEBUG "rtllib_crypt_tkip: could not allocate "
"crypto API michael_mic\n");
goto fail;
}
#else
priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
CRYPTO_ALG_ASYNC);
if (IS_ERR(priv->tx_tfm_arc4)) {
printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
printk(KERN_DEBUG "rtllib_crypt_tkip: could not allocate "
"crypto API arc4\n");
priv->tx_tfm_arc4 = NULL;
goto fail;
@ -86,7 +123,7 @@ static void * ieee80211_tkip_init(int key_idx)
priv->tx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
CRYPTO_ALG_ASYNC);
if (IS_ERR(priv->tx_tfm_michael)) {
printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
printk(KERN_DEBUG "rtllib_crypt_tkip: could not allocate "
"crypto API michael_mic\n");
priv->tx_tfm_michael = NULL;
goto fail;
@ -95,7 +132,7 @@ static void * ieee80211_tkip_init(int key_idx)
priv->rx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
CRYPTO_ALG_ASYNC);
if (IS_ERR(priv->rx_tfm_arc4)) {
printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
printk(KERN_DEBUG "rtllib_crypt_tkip: could not allocate "
"crypto API arc4\n");
priv->rx_tfm_arc4 = NULL;
goto fail;
@ -104,15 +141,27 @@ static void * ieee80211_tkip_init(int key_idx)
priv->rx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
CRYPTO_ALG_ASYNC);
if (IS_ERR(priv->rx_tfm_michael)) {
printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
printk(KERN_DEBUG "rtllib_crypt_tkip: could not allocate "
"crypto API michael_mic\n");
priv->rx_tfm_michael = NULL;
goto fail;
}
#endif
return priv;
fail:
if (priv) {
#if ( defined(BUILT_IN_CRYPTO) || ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) )
if (priv->tx_tfm_michael)
crypto_free_tfm(priv->tx_tfm_michael);
if (priv->tx_tfm_arc4)
crypto_free_tfm(priv->tx_tfm_arc4);
if (priv->rx_tfm_michael)
crypto_free_tfm(priv->rx_tfm_michael);
if (priv->rx_tfm_arc4)
crypto_free_tfm(priv->rx_tfm_arc4);
#else
if (priv->tx_tfm_michael)
crypto_free_hash(priv->tx_tfm_michael);
if (priv->tx_tfm_arc4)
@ -121,6 +170,7 @@ static void * ieee80211_tkip_init(int key_idx)
crypto_free_hash(priv->rx_tfm_michael);
if (priv->rx_tfm_arc4)
crypto_free_blkcipher(priv->rx_tfm_arc4);
#endif
kfree(priv);
}
@ -128,9 +178,19 @@ static void * ieee80211_tkip_init(int key_idx)
}
static void ieee80211_tkip_deinit(void *priv)
static void rtllib_tkip_deinit(void *priv)
{
struct ieee80211_tkip_data *_priv = priv;
struct rtllib_tkip_data *_priv = priv;
#if ( defined(BUILT_IN_CRYPTO) || ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) )
if (_priv->tx_tfm_michael)
crypto_free_tfm(_priv->tx_tfm_michael);
if (_priv->tx_tfm_arc4)
crypto_free_tfm(_priv->tx_tfm_arc4);
if (_priv->rx_tfm_michael)
crypto_free_tfm(_priv->rx_tfm_michael);
if (_priv->rx_tfm_arc4)
crypto_free_tfm(_priv->rx_tfm_arc4);
#else
if (_priv) {
if (_priv->tx_tfm_michael)
crypto_free_hash(_priv->tx_tfm_michael);
@ -141,6 +201,7 @@ static void ieee80211_tkip_deinit(void *priv)
if (_priv->rx_tfm_arc4)
crypto_free_blkcipher(_priv->rx_tfm_arc4);
}
#endif
kfree(priv);
}
@ -303,16 +364,18 @@ static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK,
}
static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
static int rtllib_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
{
struct ieee80211_tkip_data *tkey = priv;
struct rtllib_tkip_data *tkey = priv;
int len;
u8 *pos;
struct ieee80211_hdr_4addr *hdr;
struct rtllib_hdr_4addr *hdr;
cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
#if ( !defined(BUILT_IN_CRYPTO) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) || (OPENSUSE_SLED)) )
struct blkcipher_desc desc = {.tfm = tkey->tx_tfm_arc4};
int ret = 0;
#endif
u8 rc4key[16], *icv;
u32 crc;
struct scatterlist sg;
@ -321,18 +384,16 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
skb->len < hdr_len)
return -1;
hdr = (struct ieee80211_hdr_4addr *) skb->data;
hdr = (struct rtllib_hdr_4addr *) skb->data;
if (!tcb_desc->bHwSec)
{
if (!tcb_desc->bHwSec) {
if (!tkey->tx_phase1_done) {
tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
tkey->tx_iv32);
tkey->tx_phase1_done = 1;
}
tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);
}
else
} else
tkey->tx_phase1_done = 1;
@ -341,14 +402,11 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
memmove(pos, pos + 8, hdr_len);
pos += hdr_len;
if (tcb_desc->bHwSec)
{
if (tcb_desc->bHwSec) {
*pos++ = Hi8(tkey->tx_iv16);
*pos++ = (Hi8(tkey->tx_iv16) | 0x20) & 0x7F;
*pos++ = Lo8(tkey->tx_iv16);
}
else
{
} else {
*pos++ = rc4key[0];
*pos++ = rc4key[1];
*pos++ = rc4key[2];
@ -360,17 +418,30 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
*pos++ = (tkey->tx_iv32 >> 16) & 0xff;
*pos++ = (tkey->tx_iv32 >> 24) & 0xff;
if (!tcb_desc->bHwSec)
{
if (!tcb_desc->bHwSec) {
icv = skb_put(skb, 4);
crc = ~crc32_le(~0, pos, len);
icv[0] = crc;
icv[1] = crc >> 8;
icv[2] = crc >> 16;
icv[3] = crc >> 24;
crypto_blkcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
sg.page = virt_to_page(pos);
sg.offset = offset_in_page(pos);
sg.length = len + 4;
#else
sg_init_one(&sg, pos, len+4);
#endif
#if ( defined(BUILT_IN_CRYPTO) || ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) )
crypto_cipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
crypto_cipher_encrypt(tkey->tx_tfm_arc4, &sg, &sg, len + 4);
#else
crypto_blkcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
ret= crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
#endif
}
@ -381,22 +452,28 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
}
if (!tcb_desc->bHwSec)
#if ( defined(BUILT_IN_CRYPTO) || ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) )
return 0;
#else
return ret;
#endif
else
return 0;
}
static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
static int rtllib_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
{
struct ieee80211_tkip_data *tkey = priv;
struct rtllib_tkip_data *tkey = priv;
u8 keyidx, *pos;
u32 iv32;
u16 iv16;
struct ieee80211_hdr_4addr *hdr;
struct rtllib_hdr_4addr *hdr;
cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
#if ( !defined(BUILT_IN_CRYPTO) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) || (OPENSUSE_SLED)) )
struct blkcipher_desc desc = {.tfm = tkey->rx_tfm_arc4};
#endif
u8 rc4key[16];
u8 icv[4];
u32 crc;
@ -405,13 +482,13 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
if (skb->len < hdr_len + 8 + 4)
return -1;
hdr = (struct ieee80211_hdr_4addr *) skb->data;
hdr = (struct rtllib_hdr_4addr *) skb->data;
pos = skb->data + hdr_len;
keyidx = pos[3];
if (!(keyidx & (1 << 5))) {
if (net_ratelimit()) {
printk(KERN_DEBUG "TKIP: received packet without ExtIV"
" flag from %pM\n", hdr->addr2);
" flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
}
return -2;
}
@ -423,9 +500,9 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
}
if (!tkey->key_set) {
if (net_ratelimit()) {
printk(KERN_DEBUG "TKIP: received packet from %pM"
printk(KERN_DEBUG "TKIP: received packet from " MAC_FMT
" with keyid=%d that does not have a configured"
" key\n", hdr->addr2, keyidx);
" key\n", MAC_ARG(hdr->addr2), keyidx);
}
return -3;
}
@ -433,19 +510,20 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24);
pos += 8;
if (!tcb_desc->bHwSec)
if (!tcb_desc->bHwSec || (skb->cb[0] == 1))
{
if (iv32 < tkey->rx_iv32 ||
(iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
if ((iv32 < tkey->rx_iv32 ||
(iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16))&&tkey->initialized) {
if (net_ratelimit()) {
printk(KERN_DEBUG "TKIP: replay detected: STA=%pM"
printk(KERN_DEBUG "TKIP: replay detected: STA=" MAC_FMT
" previous TSC %08x%04x received TSC "
"%08x%04x\n", hdr->addr2,
"%08x%04x\n", MAC_ARG(hdr->addr2),
tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
}
tkey->dot11RSNAStatsTKIPReplays++;
return -4;
}
tkey->initialized = true;
if (iv32 != tkey->rx_iv32 || !tkey->rx_phase1_done) {
tkip_mixing_phase1(tkey->rx_ttak, tkey->key, hdr->addr2, iv32);
@ -455,18 +533,34 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
plen = skb->len - hdr_len - 12;
crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
sg.page = virt_to_page(pos);
sg.offset = offset_in_page(pos);
sg.length = plen + 4;
#else
sg_init_one(&sg, pos, plen+4);
#endif
#if ( defined(BUILT_IN_CRYPTO) || ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) )
crypto_cipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
crypto_cipher_decrypt(tkey->rx_tfm_arc4, &sg, &sg, plen + 4);
#else
crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
if (net_ratelimit()) {
printk(KERN_DEBUG ": TKIP: failed to decrypt "
"received packet from %pM\n",
hdr->addr2);
"received packet from " MAC_FMT "\n",
MAC_ARG(hdr->addr2));
}
return -7;
}
#endif
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
crc = ~crc32_le(~0, pos, plen);
#else
crc = ~ether_crc_le(plen, pos);
#endif
icv[0] = crc;
icv[1] = crc >> 8;
icv[2] = crc >> 16;
@ -479,9 +573,8 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
tkey->rx_phase1_done = 0;
}
if (net_ratelimit()) {
printk(KERN_DEBUG
"TKIP: ICV error detected: STA=%pM\n",
hdr->addr2);
printk(KERN_DEBUG "TKIP: ICV error detected: STA="
MAC_FMT "\n", MAC_ARG(hdr->addr2));
}
tkey->dot11RSNAStatsTKIPICVErrors++;
return -5;
@ -499,10 +592,66 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
skb_pull(skb, 8);
skb_trim(skb, skb->len - 4);
#ifdef JOHN_DUMP
if ( ((u16*)skb->data)[0] & 0x4000){
printk("@@ rx decrypted skb->data");
int i;
for (i = 0; i < skb->len; i++) {
if ( (i%24)==0 ) printk("\n");
printk("%2x ", ((u8*)skb->data)[i]);
}
printk("\n");
}
#endif /*JOHN_DUMP*/
return keyidx;
}
#if ( defined(BUILT_IN_CRYPTO) || ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) )
static int michael_mic(struct crypto_tfm * tfm_michael, u8 *key, u8 *hdr,
u8 *data, size_t data_len, u8 *mic)
{
struct scatterlist sg[2];
#if ( !defined(BUILT_IN_CRYPTO) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) )
struct hash_desc desc;
int ret = 0;
#endif
if (tfm_michael == NULL){
printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
return -1;
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
sg[0].page = virt_to_page(hdr);
sg[0].offset = offset_in_page(hdr);
sg[0].length = 16;
sg[1].page = virt_to_page(data);
sg[1].offset = offset_in_page(data);
sg[1].length = data_len;
#else
sg_init_table(sg, 2);
sg_set_buf(&sg[0], hdr, 16);
sg_set_buf(&sg[1], data, data_len);
#endif
#if ( defined(BUILT_IN_CRYPTO) || LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) )
crypto_digest_init(tfm_michael);
crypto_digest_setkey(tfm_michael, key, 8);
crypto_digest_update(tfm_michael, sg, 2);
crypto_digest_final(tfm_michael, mic);
return 0;
#else
if (crypto_hash_setkey(tkey->tfm_michael, key, 8))
return -1;
desc.tfm = tkey->tfm_michael;
desc.flags = 0;
ret = crypto_hash_digest(&desc, sg, data_len + 16, mic);
return ret;
#endif
}
#else
static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
u8 * data, size_t data_len, u8 * mic)
{
@ -513,9 +662,19 @@ static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
return -1;
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
sg[0].page = virt_to_page(hdr);
sg[0].offset = offset_in_page(hdr);
sg[0].length = 16;
sg[1].page = virt_to_page(data);
sg[1].offset = offset_in_page(data);
sg[1].length = data_len;
#else
sg_init_table(sg, 2);
sg_set_buf(&sg[0], hdr, 16);
sg_set_buf(&sg[1], data, data_len);
#endif
if (crypto_hash_setkey(tfm_michael, key, 8))
return -1;
@ -524,25 +683,26 @@ static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
desc.flags = 0;
return crypto_hash_digest(&desc, sg, data_len + 16, mic);
}
#endif
static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr)
{
struct ieee80211_hdr_4addr *hdr11;
struct rtllib_hdr_4addr *hdr11;
hdr11 = (struct ieee80211_hdr_4addr *) skb->data;
hdr11 = (struct rtllib_hdr_4addr *) skb->data;
switch (le16_to_cpu(hdr11->frame_ctl) &
(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
case IEEE80211_FCTL_TODS:
(RTLLIB_FCTL_FROMDS | RTLLIB_FCTL_TODS)) {
case RTLLIB_FCTL_TODS:
memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
break;
case IEEE80211_FCTL_FROMDS:
case RTLLIB_FCTL_FROMDS:
memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */
break;
case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
case RTLLIB_FCTL_FROMDS | RTLLIB_FCTL_TODS:
memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */
break;
@ -558,13 +718,13 @@ static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr)
}
static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv)
static int rtllib_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv)
{
struct ieee80211_tkip_data *tkey = priv;
struct rtllib_tkip_data *tkey = priv;
u8 *pos;
struct ieee80211_hdr_4addr *hdr;
struct rtllib_hdr_4addr *hdr;
hdr = (struct ieee80211_hdr_4addr *) skb->data;
hdr = (struct rtllib_hdr_4addr *) skb->data;
if (skb_tailroom(skb) < 8 || skb->len < hdr_len) {
printk(KERN_DEBUG "Invalid packet for Michael MIC add "
@ -575,15 +735,17 @@ static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, void *pri
michael_mic_hdr(skb, tkey->tx_hdr);
// { david, 2006.9.1
// fix the wpa process with wmm enabled.
if(IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) {
if (RTLLIB_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) {
tkey->tx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
}
// }
pos = skb_put(skb, 8);
#if ( defined(BUILT_IN_CRYPTO) || ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) )
if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
#else
if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
#endif
return -1;
return 0;
@ -591,8 +753,8 @@ static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, void *pri
#if WIRELESS_EXT >= 18
static void ieee80211_michael_mic_failure(struct net_device *dev,
struct ieee80211_hdr_4addr *hdr,
static void rtllib_michael_mic_failure(struct net_device *dev,
struct rtllib_hdr_4addr *hdr,
int keyidx)
{
union iwreq_data wrqu;
@ -612,8 +774,8 @@ static void ieee80211_michael_mic_failure(struct net_device *dev,
wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *) &ev);
}
#elif WIRELESS_EXT >= 15
static void ieee80211_michael_mic_failure(struct net_device *dev,
struct ieee80211_hdr_4addr *hdr,
static void rtllib_michael_mic_failure(struct net_device *dev,
struct rtllib_hdr_4addr *hdr,
int keyidx)
{
union iwreq_data wrqu;
@ -621,53 +783,61 @@ static void ieee80211_michael_mic_failure(struct net_device *dev,
/* TODO: needed parameters: count, keyid, key type, TSC */
sprintf(buf, "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr="
"%pM)", keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni",
hdr->addr2);
MAC_FMT ")", keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni",
MAC_ARG(hdr->addr2));
memset(&wrqu, 0, sizeof(wrqu));
wrqu.data.length = strlen(buf);
wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
}
#else /* WIRELESS_EXT >= 15 */
static inline void ieee80211_michael_mic_failure(struct net_device *dev,
struct ieee80211_hdr_4addr *hdr,
static inline void rtllib_michael_mic_failure(struct net_device *dev,
struct rtllib_hdr_4addr *hdr,
int keyidx)
{
}
#endif /* WIRELESS_EXT >= 15 */
static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
int hdr_len, void *priv)
static int rtllib_michael_mic_verify(struct sk_buff *skb, int keyidx,
int hdr_len, void *priv, struct rtllib_device* ieee)
{
struct ieee80211_tkip_data *tkey = priv;
struct rtllib_tkip_data *tkey = priv;
u8 mic[8];
struct ieee80211_hdr_4addr *hdr;
struct rtllib_hdr_4addr *hdr;
hdr = (struct ieee80211_hdr_4addr *) skb->data;
hdr = (struct rtllib_hdr_4addr *) skb->data;
if (!tkey->key_set)
return -1;
michael_mic_hdr(skb, tkey->rx_hdr);
// { david, 2006.9.1
// fix the wpa process with wmm enabled.
if(IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) {
if (RTLLIB_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) {
tkey->rx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
}
// }
#if ( defined(BUILT_IN_CRYPTO) || ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) )
if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
#else
if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
#endif
return -1;
if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
struct ieee80211_hdr_4addr *hdr;
hdr = (struct ieee80211_hdr_4addr *) skb->data;
if ((memcmp(mic, skb->data + skb->len - 8, 8) != 0)||(ieee->force_mic_error)) {
struct rtllib_hdr_4addr *hdr;
hdr = (struct rtllib_hdr_4addr *) skb->data;
printk(KERN_DEBUG "%s: Michael MIC verification failed for "
"MSDU from %pM keyidx=%d\n",
skb->dev ? skb->dev->name : "N/A", hdr->addr2,
"MSDU from " MAC_FMT " keyidx=%d\n",
skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2),
keyidx);
if (skb->dev)
ieee80211_michael_mic_failure(skb->dev, hdr, keyidx);
printk("%d, force_mic_error = %d\n", (memcmp(mic, skb->data + skb->len - 8, 8) != 0),\
ieee->force_mic_error);
if (skb->dev) {
printk("skb->dev != NULL\n");
rtllib_michael_mic_failure(skb->dev, hdr, keyidx);
}
tkey->dot11RSNAStatsTKIPLocalMICFailures++;
ieee->force_mic_error = false;
return -1;
}
@ -682,22 +852,36 @@ static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
}
static int ieee80211_tkip_set_key(void *key, int len, u8 *seq, void *priv)
static int rtllib_tkip_set_key(void *key, int len, u8 *seq, void *priv)
{
struct ieee80211_tkip_data *tkey = priv;
struct rtllib_tkip_data *tkey = priv;
int keyidx;
#if ( defined(BUILT_IN_CRYPTO) || ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) )
struct crypto_tfm *tfm = tkey->tx_tfm_michael;
struct crypto_tfm *tfm2 = tkey->tx_tfm_arc4;
struct crypto_tfm *tfm3 = tkey->rx_tfm_michael;
struct crypto_tfm *tfm4 = tkey->rx_tfm_arc4;
#else
struct crypto_hash *tfm = tkey->tx_tfm_michael;
struct crypto_blkcipher *tfm2 = tkey->tx_tfm_arc4;
struct crypto_hash *tfm3 = tkey->rx_tfm_michael;
struct crypto_blkcipher *tfm4 = tkey->rx_tfm_arc4;
#endif
keyidx = tkey->key_idx;
memset(tkey, 0, sizeof(*tkey));
tkey->key_idx = keyidx;
#if ( defined(BUILT_IN_CRYPTO) || ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) )
tkey->tx_tfm_michael = tfm;
tkey->tx_tfm_arc4 = tfm2;
tkey->rx_tfm_michael = tfm3;
tkey->rx_tfm_arc4 = tfm4;
#else
tkey->tx_tfm_michael = tfm;
tkey->tx_tfm_arc4 = tfm2;
tkey->rx_tfm_michael = tfm3;
tkey->rx_tfm_arc4 = tfm4;
#endif
if (len == TKIP_KEY_LEN) {
memcpy(tkey->key, key, TKIP_KEY_LEN);
@ -717,9 +901,9 @@ static int ieee80211_tkip_set_key(void *key, int len, u8 *seq, void *priv)
}
static int ieee80211_tkip_get_key(void *key, int len, u8 *seq, void *priv)
static int rtllib_tkip_get_key(void *key, int len, u8 *seq, void *priv)
{
struct ieee80211_tkip_data *tkey = priv;
struct rtllib_tkip_data *tkey = priv;
if (len < TKIP_KEY_LEN)
return -1;
@ -747,9 +931,9 @@ static int ieee80211_tkip_get_key(void *key, int len, u8 *seq, void *priv)
}
static char * ieee80211_tkip_print_stats(char *p, void *priv)
static char * rtllib_tkip_print_stats(char *p, void *priv)
{
struct ieee80211_tkip_data *tkip = priv;
struct rtllib_tkip_data *tkip = priv;
p += sprintf(p, "key[%d] alg=TKIP key_set=%d "
"tx_pn=%02x%02x%02x%02x%02x%02x "
"rx_pn=%02x%02x%02x%02x%02x%02x "
@ -774,36 +958,35 @@ static char * ieee80211_tkip_print_stats(char *p, void *priv)
}
static struct ieee80211_crypto_ops ieee80211_crypt_tkip = {
static struct rtllib_crypto_ops rtllib_crypt_tkip = {
.name = "TKIP",
.init = ieee80211_tkip_init,
.deinit = ieee80211_tkip_deinit,
.encrypt_mpdu = ieee80211_tkip_encrypt,
.decrypt_mpdu = ieee80211_tkip_decrypt,
.encrypt_msdu = ieee80211_michael_mic_add,
.decrypt_msdu = ieee80211_michael_mic_verify,
.set_key = ieee80211_tkip_set_key,
.get_key = ieee80211_tkip_get_key,
.print_stats = ieee80211_tkip_print_stats,
.init = rtllib_tkip_init,
.deinit = rtllib_tkip_deinit,
.encrypt_mpdu = rtllib_tkip_encrypt,
.decrypt_mpdu = rtllib_tkip_decrypt,
.encrypt_msdu = rtllib_michael_mic_add,
.decrypt_msdu = rtllib_michael_mic_verify,
.set_key = rtllib_tkip_set_key,
.get_key = rtllib_tkip_get_key,
.print_stats = rtllib_tkip_print_stats,
.extra_prefix_len = 4 + 4, /* IV + ExtIV */
.extra_postfix_len = 8 + 4, /* MIC + ICV */
.owner = THIS_MODULE,
};
int __init ieee80211_crypto_tkip_init(void)
int __init rtllib_crypto_tkip_init(void)
{
return ieee80211_register_crypto_ops(&ieee80211_crypt_tkip);
return rtllib_register_crypto_ops(&rtllib_crypt_tkip);
}
void ieee80211_crypto_tkip_exit(void)
void __exit rtllib_crypto_tkip_exit(void)
{
ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip);
rtllib_unregister_crypto_ops(&rtllib_crypt_tkip);
}
void ieee80211_tkip_null(void)
void rtllib_tkip_null(void)
{
return;
}

View file

@ -9,36 +9,53 @@
* more details.
*/
#include <linux/version.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/random.h>
#include <linux/skbuff.h>
#include <asm/string.h>
#include "rtllib.h"
#include "ieee80211.h"
#include <linux/crypto.h>
#include <linux/scatterlist.h>
#include <linux/crc32.h>
MODULE_AUTHOR("Jouni Malinen");
MODULE_DESCRIPTION("Host AP crypt: WEP");
MODULE_LICENSE("GPL");
#ifndef OPENSUSE_SLED
#define OPENSUSE_SLED 0
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,20))
#endif
#if defined(BUILT_IN_CRYPTO) || (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
#include "rtl_crypto.h"
#else
#include <linux/crypto.h>
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
#include <asm/scatterlist.h>
#else
#include <linux/scatterlist.h>
#endif
#include <linux/crc32.h>
/*
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
#include "rtl_crypto.h"
#else
#include <linux/crypto.h>
#endif
#include <asm/scatterlist.h>
#include <linux/crc32.h>
*/
struct prism2_wep_data {
u32 iv;
#define WEP_KEY_LEN 13
u8 key[WEP_KEY_LEN + 1];
u8 key_len;
u8 key_idx;
#if ( defined(BUILT_IN_CRYPTO) || ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) )
struct crypto_tfm *tfm;
#else
struct crypto_blkcipher *tx_tfm;
struct crypto_blkcipher *rx_tfm;
#endif
};
@ -46,25 +63,35 @@ static void * prism2_wep_init(int keyidx)
{
struct prism2_wep_data *priv;
priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
if (priv == NULL)
goto fail;
memset(priv, 0, sizeof(*priv));
priv->key_idx = keyidx;
#if ( defined(BUILT_IN_CRYPTO) || ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) )
priv->tfm = crypto_alloc_tfm("arc4", 0);
if (priv->tfm == NULL) {
printk(KERN_DEBUG "rtllib_crypt_wep: could not allocate "
"crypto API arc4\n");
goto fail;
}
#else
priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(priv->tx_tfm)) {
printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
printk(KERN_DEBUG "rtllib_crypt_wep: could not allocate "
"crypto API arc4\n");
priv->tx_tfm = NULL;
goto fail;
}
priv->rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(priv->rx_tfm)) {
printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
printk(KERN_DEBUG "rtllib_crypt_wep: could not allocate "
"crypto API arc4\n");
priv->rx_tfm = NULL;
goto fail;
}
#endif
/* start WEP IV from a random value */
get_random_bytes(&priv->iv, 4);
@ -72,6 +99,13 @@ static void * prism2_wep_init(int keyidx)
return priv;
fail:
#if ( defined(BUILT_IN_CRYPTO) || ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) )
if (priv) {
if (priv->tfm)
crypto_free_tfm(priv->tfm);
kfree(priv);
}
#else
if (priv) {
if (priv->tx_tfm)
crypto_free_blkcipher(priv->tx_tfm);
@ -79,6 +113,7 @@ static void * prism2_wep_init(int keyidx)
crypto_free_blkcipher(priv->rx_tfm);
kfree(priv);
}
#endif
return NULL;
}
@ -86,12 +121,17 @@ static void * prism2_wep_init(int keyidx)
static void prism2_wep_deinit(void *priv)
{
struct prism2_wep_data *_priv = priv;
#if ( defined(BUILT_IN_CRYPTO) || ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) )
if (_priv && _priv->tfm)
crypto_free_tfm(_priv->tfm);
#else
if (_priv) {
if (_priv->tx_tfm)
crypto_free_blkcipher(_priv->tx_tfm);
if (_priv->rx_tfm)
crypto_free_blkcipher(_priv->rx_tfm);
}
#endif
kfree(priv);
}
@ -108,14 +148,17 @@ static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
u8 key[WEP_KEY_LEN + 3];
u8 *pos;
cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
#if ( !defined(BUILT_IN_CRYPTO) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) || (OPENSUSE_SLED)) )
struct blkcipher_desc desc = {.tfm = wep->tx_tfm};
#endif
u32 crc;
u8 *icv;
struct scatterlist sg;
if (skb_headroom(skb) < 4 || skb_tailroom(skb) < 4 ||
skb->len < hdr_len)
skb->len < hdr_len){
printk("Error!!!headroom=%d tailroom=%d skblen=%d hdr_len=%d\n",skb_headroom(skb),skb_tailroom(skb),skb->len,hdr_len);
return -1;
}
len = skb->len - hdr_len;
pos = skb_push(skb, 4);
memmove(pos, pos + 4, hdr_len);
@ -147,16 +190,32 @@ static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
{
/* Append little-endian CRC32 and encrypt it to produce ICV */
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
crc = ~crc32_le(~0, pos, len);
#else
crc = ~ether_crc_le(len, pos);
#endif
icv = skb_put(skb, 4);
icv[0] = crc;
icv[1] = crc >> 8;
icv[2] = crc >> 16;
icv[3] = crc >> 24;
crypto_blkcipher_setkey(wep->tx_tfm, key, klen);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
sg.page = virt_to_page(pos);
sg.offset = offset_in_page(pos);
sg.length = len + 4;
#else
sg_init_one(&sg, pos, len+4);
#endif
#if ( defined(BUILT_IN_CRYPTO) || ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) )
crypto_cipher_setkey(wep->tfm, key, klen);
crypto_cipher_encrypt(wep->tfm, &sg, &sg, len + 4);
return 0;
#else
crypto_blkcipher_setkey(wep->tx_tfm, key, klen);
return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
#endif
}
return 0;
@ -177,7 +236,9 @@ static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
u8 key[WEP_KEY_LEN + 3];
u8 keyidx, *pos;
cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
#if ( !defined(BUILT_IN_CRYPTO) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) || (OPENSUSE_SLED)) )
struct blkcipher_desc desc = {.tfm = wep->rx_tfm};
#endif
u32 crc;
u8 icv[4];
struct scatterlist sg;
@ -202,11 +263,26 @@ static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
if (!tcb_desc->bHwSec)
{
crypto_blkcipher_setkey(wep->rx_tfm, key, klen);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
sg.page = virt_to_page(pos);
sg.offset = offset_in_page(pos);
sg.length = plen + 4;
#else
sg_init_one(&sg, pos, plen+4);
#endif
#if ( defined(BUILT_IN_CRYPTO) || ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) )
crypto_cipher_setkey(wep->tfm, key, klen);
crypto_cipher_decrypt(wep->tfm, &sg, &sg, plen + 4);
#else
crypto_blkcipher_setkey(wep->rx_tfm, key, klen);
if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4))
return -7;
#endif
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
crc = ~crc32_le(~0, pos, plen);
#else
crc = ~ether_crc_le(plen, pos);
#endif
icv[0] = crc;
icv[1] = crc >> 8;
icv[2] = crc >> 16;
@ -261,7 +337,7 @@ static char * prism2_wep_print_stats(char *p, void *priv)
}
static struct ieee80211_crypto_ops ieee80211_crypt_wep = {
static struct rtllib_crypto_ops rtllib_crypt_wep = {
.name = "WEP",
.init = prism2_wep_init,
.deinit = prism2_wep_deinit,
@ -278,19 +354,18 @@ static struct ieee80211_crypto_ops ieee80211_crypt_wep = {
};
int __init ieee80211_crypto_wep_init(void)
int __init rtllib_crypto_wep_init(void)
{
return ieee80211_register_crypto_ops(&ieee80211_crypt_wep);
return rtllib_register_crypto_ops(&rtllib_crypt_wep);
}
void __exit ieee80211_crypto_wep_exit(void)
void __exit rtllib_crypto_wep_exit(void)
{
ieee80211_unregister_crypto_ops(&ieee80211_crypt_wep);
rtllib_unregister_crypto_ops(&rtllib_crypt_wep);
}
void ieee80211_wep_null(void)
void rtllib_wep_null(void)
{
return;
}

View file

@ -0,0 +1,156 @@
#ifndef __INC_ENDIANFREE_H
#define __INC_ENDIANFREE_H
/*
* Call endian free function when
* 1. Read/write packet content.
* 2. Before write integer to IO.
* 3. After read integer from IO.
*/
#define __MACHINE_LITTLE_ENDIAN 1234 /* LSB first: i386, vax */
#define __MACHINE_BIG_ENDIAN 4321 /* MSB first: 68000, ibm, net, ppc */
#define BYTE_ORDER __MACHINE_LITTLE_ENDIAN
#if BYTE_ORDER == __MACHINE_LITTLE_ENDIAN
#define EF1Byte(_val) ((u8)(_val))
#define EF2Byte(_val) ((u16)(_val))
#define EF4Byte(_val) ((u32)(_val))
#else
#define EF1Byte(_val) ((u8)(_val))
#define EF2Byte(_val) (((((u16)(_val))&0x00ff)<<8)|((((u16)(_val))&0xff00)>>8))
#define EF4Byte(_val) (((((u32)(_val))&0x000000ff)<<24)|\
((((u32)(_val))&0x0000ff00)<<8)|\
((((u32)(_val))&0x00ff0000)>>8)|\
((((u32)(_val))&0xff000000)>>24))
#endif
#define ReadEF1Byte(_ptr) EF1Byte(*((u8 *)(_ptr)))
#define ReadEF2Byte(_ptr) EF2Byte(*((u16 *)(_ptr)))
#define ReadEF4Byte(_ptr) EF4Byte(*((u32 *)(_ptr)))
#define WriteEF1Byte(_ptr, _val) (*((u8 *)(_ptr)))=EF1Byte(_val)
#define WriteEF2Byte(_ptr, _val) (*((u16 *)(_ptr)))=EF2Byte(_val)
#define WriteEF4Byte(_ptr, _val) (*((u32 *)(_ptr)))=EF4Byte(_val)
#if BYTE_ORDER == __MACHINE_LITTLE_ENDIAN
#define H2N1BYTE(_val) ((u8)(_val))
#define H2N2BYTE(_val) (((((u16)(_val))&0x00ff)<<8)|\
((((u16)(_val))&0xff00)>>8))
#define H2N4BYTE(_val) (((((u32)(_val))&0x000000ff)<<24)|\
((((u32)(_val))&0x0000ff00)<<8) |\
((((u32)(_val))&0x00ff0000)>>8) |\
((((u32)(_val))&0xff000000)>>24))
#else
#define H2N1BYTE(_val) ((u8)(_val))
#define H2N2BYTE(_val) ((u16)(_val))
#define H2N4BYTE(_val) ((u32)(_val))
#endif
#if BYTE_ORDER == __MACHINE_LITTLE_ENDIAN
#define N2H1BYTE(_val) ((u8)(_val))
#define N2H2BYTE(_val) (((((u16)(_val))&0x00ff)<<8)|\
((((u16)(_val))&0xff00)>>8))
#define N2H4BYTE(_val) (((((u32)(_val))&0x000000ff)<<24)|\
((((u32)(_val))&0x0000ff00)<<8) |\
((((u32)(_val))&0x00ff0000)>>8) |\
((((u32)(_val))&0xff000000)>>24))
#else
#define N2H1BYTE(_val) ((u8)(_val))
#define N2H2BYTE(_val) ((u16)(_val))
#define N2H4BYTE(_val) ((u32)(_val))
#endif
#define BIT_LEN_MASK_32(__BitLen) (0xFFFFFFFF >> (32 - (__BitLen)))
#define BIT_OFFSET_LEN_MASK_32(__BitOffset, __BitLen) (BIT_LEN_MASK_32(__BitLen) << (__BitOffset))
#define LE_P4BYTE_TO_HOST_4BYTE(__pStart) (EF4Byte(*((u32 *)(__pStart))))
#define LE_BITS_TO_4BYTE(__pStart, __BitOffset, __BitLen) \
( \
( LE_P4BYTE_TO_HOST_4BYTE(__pStart) >> (__BitOffset) ) \
& \
BIT_LEN_MASK_32(__BitLen) \
)
#define LE_BITS_CLEARED_TO_4BYTE(__pStart, __BitOffset, __BitLen) \
( \
LE_P4BYTE_TO_HOST_4BYTE(__pStart) \
& \
( ~BIT_OFFSET_LEN_MASK_32(__BitOffset, __BitLen) ) \
)
#define SET_BITS_TO_LE_4BYTE(__pStart, __BitOffset, __BitLen, __Value) \
*((u32 *)(__pStart)) = \
EF4Byte( \
LE_BITS_CLEARED_TO_4BYTE(__pStart, __BitOffset, __BitLen) \
| \
( (((u32)__Value) & BIT_LEN_MASK_32(__BitLen)) << (__BitOffset) ) \
);
#define BIT_LEN_MASK_16(__BitLen) \
(0xFFFF >> (16 - (__BitLen)))
#define BIT_OFFSET_LEN_MASK_16(__BitOffset, __BitLen) \
(BIT_LEN_MASK_16(__BitLen) << (__BitOffset))
#define LE_P2BYTE_TO_HOST_2BYTE(__pStart) \
(EF2Byte(*((u16 *)(__pStart))))
#define LE_BITS_TO_2BYTE(__pStart, __BitOffset, __BitLen) \
( \
( LE_P2BYTE_TO_HOST_2BYTE(__pStart) >> (__BitOffset) ) \
& \
BIT_LEN_MASK_16(__BitLen) \
)
#define LE_BITS_CLEARED_TO_2BYTE(__pStart, __BitOffset, __BitLen) \
( \
LE_P2BYTE_TO_HOST_2BYTE(__pStart) \
& \
( ~BIT_OFFSET_LEN_MASK_16(__BitOffset, __BitLen) ) \
)
#define SET_BITS_TO_LE_2BYTE(__pStart, __BitOffset, __BitLen, __Value) \
*((u16 *)(__pStart)) = \
EF2Byte( \
LE_BITS_CLEARED_TO_2BYTE(__pStart, __BitOffset, __BitLen) \
| \
( (((u16)__Value) & BIT_LEN_MASK_16(__BitLen)) << (__BitOffset) ) \
);
#define BIT_LEN_MASK_8(__BitLen) \
(0xFF >> (8 - (__BitLen)))
#define BIT_OFFSET_LEN_MASK_8(__BitOffset, __BitLen) \
(BIT_LEN_MASK_8(__BitLen) << (__BitOffset))
#define LE_P1BYTE_TO_HOST_1BYTE(__pStart) \
(EF1Byte(*((u8 *)(__pStart))))
#define LE_BITS_TO_1BYTE(__pStart, __BitOffset, __BitLen) \
( \
( LE_P1BYTE_TO_HOST_1BYTE(__pStart) >> (__BitOffset) ) \
& \
BIT_LEN_MASK_8(__BitLen) \
)
#define LE_BITS_CLEARED_TO_1BYTE(__pStart, __BitOffset, __BitLen) \
( \
LE_P1BYTE_TO_HOST_1BYTE(__pStart) \
& \
( ~BIT_OFFSET_LEN_MASK_8(__BitOffset, __BitLen) ) \
)
#define SET_BITS_TO_LE_1BYTE(__pStart, __BitOffset, __BitLen, __Value) \
*((u8 *)(__pStart)) = \
EF1Byte( \
LE_BITS_CLEARED_TO_1BYTE(__pStart, __BitOffset, __BitLen) \
| \
( (((u8)__Value) & BIT_LEN_MASK_8(__BitLen)) << (__BitOffset) ) \
);
#define N_BYTE_ALIGMENT(__Value, __Aligment) ((__Aligment == 1) ? (__Value) : (((__Value + __Aligment - 1) / __Aligment) * __Aligment))
#endif

View file

@ -0,0 +1,374 @@
/*******************************************************************************
Copyright(c) 2004 Intel Corporation. All rights reserved.
Portions of this file are based on the WEP enablement code provided by the
Host AP project hostap-drivers v0.1.3
Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
<jkmaline@cc.hut.fi>
Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
This program is free software; you can redistribute it and/or modify it
under the terms of version 2 of the GNU General Public License as
published by the Free Software Foundation.
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.
The full GNU General Public License is included in this distribution in the
file called LICENSE.
Contact Information:
James P. Ketrenos <ipw2100-admin@linux.intel.com>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
#include <linux/compiler.h>
#include <linux/errno.h>
#include <linux/if_arp.h>
#include <linux/in6.h>
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/pci.h>
#include <linux/proc_fs.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/tcp.h>
#include <linux/types.h>
#include <linux/version.h>
#include <linux/wireless.h>
#include <linux/etherdevice.h>
#include <asm/uaccess.h>
#include <net/arp.h>
#include "rtllib.h"
#define DRV_NAME "rtllib_92e"
#ifdef CONFIG_CFG_80211
#ifdef CONFIG_RTL_RFKILL
static inline void rtllib_rfkill_poll(struct wiphy *wiphy)
{
struct rtllib_device *rtllib = NULL;
rtllib = (struct rtllib_device *)wiphy_priv(wiphy);
rtllib = (struct rtllib_device *)netdev_priv_rsl(rtllib->dev);
if (rtllib->rtllib_rfkill_poll)
rtllib->rtllib_rfkill_poll(rtllib->dev);
}
#else
static inline void rtllib_rfkill_poll(struct wiphy *wiphy) {}
#endif
struct cfg80211_ops rtllib_config_ops = {.rfkill_poll = rtllib_rfkill_poll };
void *rtllib_wiphy_privid = &rtllib_wiphy_privid;
#endif
void _setup_timer( struct timer_list* ptimer, void* fun, unsigned long data )
{
ptimer->function = fun;
ptimer->data = data;
init_timer( ptimer );
}
static inline int rtllib_networks_allocate(struct rtllib_device *ieee)
{
if (ieee->networks)
return 0;
#ifndef RTK_DMP_PLATFORM
ieee->networks = kmalloc(
MAX_NETWORK_COUNT * sizeof(struct rtllib_network),
GFP_KERNEL);
#else
ieee->networks = dvr_malloc(MAX_NETWORK_COUNT * sizeof(struct rtllib_network));
#endif
if (!ieee->networks) {
printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
ieee->dev->name);
return -ENOMEM;
}
memset(ieee->networks, 0,
MAX_NETWORK_COUNT * sizeof(struct rtllib_network));
return 0;
}
static inline void rtllib_networks_free(struct rtllib_device *ieee)
{
if (!ieee->networks)
return;
#ifndef RTK_DMP_PLATFORM
kfree(ieee->networks);
#else
dvr_free(ieee->networks);
#endif
ieee->networks = NULL;
}
static inline void rtllib_networks_initialize(struct rtllib_device *ieee)
{
int i;
INIT_LIST_HEAD(&ieee->network_free_list);
INIT_LIST_HEAD(&ieee->network_list);
for (i = 0; i < MAX_NETWORK_COUNT; i++)
list_add_tail(&ieee->networks[i].list, &ieee->network_free_list);
}
#if defined CONFIG_CFG_80211
static bool rtllib_wdev_alloc(struct rtllib_device *ieee, int sizeof_priv)
{
int priv_size;
struct rtllib_device *rtllib = NULL;
priv_size = ALIGN(sizeof(struct rtllib_device),NETDEV_ALIGN) + sizeof_priv;
ieee->wdev.wiphy = wiphy_new(&rtllib_config_ops, priv_size);
if (!ieee->wdev.wiphy) {
RTLLIB_ERROR("Unable to allocate wiphy.\n");
goto out_err_new;
}
rtllib = (struct rtllib_device *)wiphy_priv(ieee->wdev.wiphy);
rtllib->dev = ieee->dev;
ieee->dev->ieee80211_ptr = &ieee->wdev;
ieee->wdev.iftype = NL80211_IFTYPE_STATION;
/* Fill-out wiphy structure bits we know... Not enough info
* here to call set_wiphy_dev or set MAC address or channel info
* -- have to do that in ->ndo_init... */
ieee->wdev.wiphy->privid = rtllib_wiphy_privid;
ieee->wdev.wiphy->max_scan_ssids = 1;
ieee->wdev.wiphy->max_scan_ie_len = 0;
ieee->wdev.wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
return true;
out_err_new:
wiphy_free(ieee->wdev.wiphy);
return false;
}
#endif
struct net_device *alloc_rtllib(int sizeof_priv)
{
struct rtllib_device *ieee = NULL;
struct net_device *dev;
int i,err;
RTLLIB_DEBUG_INFO("Initializing...\n");
dev = alloc_etherdev(sizeof(struct rtllib_device) + sizeof_priv);
if (!dev) {
RTLLIB_ERROR("Unable to network device.\n");
goto failed;
}
ieee = (struct rtllib_device *)netdev_priv_rsl(dev);
memset(ieee, 0, sizeof(struct rtllib_device)+sizeof_priv);
ieee->dev = dev;
#ifdef CONFIG_CFG_80211
if (!rtllib_wdev_alloc(ieee, sizeof_priv))
goto failed;
#endif
err = rtllib_networks_allocate(ieee);
if (err) {
RTLLIB_ERROR("Unable to allocate beacon storage: %d\n",
err);
goto failed;
}
rtllib_networks_initialize(ieee);
/* Default fragmentation threshold is maximum payload size */
ieee->fts = DEFAULT_FTS;
ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
ieee->open_wep = 1;
/* Default to enabling full open WEP with host based encrypt/decrypt */
ieee->host_encrypt = 1;
ieee->host_decrypt = 1;
ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
INIT_LIST_HEAD(&ieee->crypt_deinit_list);
_setup_timer(&ieee->crypt_deinit_timer,
rtllib_crypt_deinit_handler,
(unsigned long) ieee);
ieee->rtllib_ap_sec_type = rtllib_ap_sec_type;
spin_lock_init(&ieee->lock);
spin_lock_init(&ieee->wpax_suitlist_lock);
spin_lock_init(&ieee->bw_spinlock);
spin_lock_init(&ieee->reorder_spinlock);
atomic_set(&(ieee->atm_chnlop), 0);
atomic_set(&(ieee->atm_swbw), 0);
ieee->bHalfNMode = false;
ieee->wpa_enabled = 0;
ieee->tkip_countermeasures = 0;
ieee->drop_unencrypted = 0;
ieee->privacy_invoked = 0;
ieee->ieee802_1x = 1;
ieee->raw_tx = 0;
ieee->hwsec_active = 0;
memset(ieee->swcamtable,0,sizeof(SW_CAM_TABLE)*32);
rtllib_softmac_init(ieee);
ieee->pHTInfo = (RT_HIGH_THROUGHPUT*)kzalloc(sizeof(RT_HIGH_THROUGHPUT), GFP_KERNEL);
if (ieee->pHTInfo == NULL)
{
RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't alloc memory for HTInfo\n");
return NULL;
}
HTUpdateDefaultSetting(ieee);
HTInitializeHTInfo(ieee);
TSInitialize(ieee);
for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++)
INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
for (i = 0; i < 17; i++) {
ieee->last_rxseq_num[i] = -1;
ieee->last_rxfrag_num[i] = -1;
ieee->last_packet_time[i] = 0;
}
rtllib_tkip_null();
rtllib_wep_null();
rtllib_ccmp_null();
return dev;
failed:
if (dev)
free_netdev(dev);
return NULL;
}
void free_rtllib(struct net_device *dev)
{
struct rtllib_device *ieee = (struct rtllib_device *)netdev_priv_rsl(dev);
int i;
if (ieee->pHTInfo != NULL) {
kfree(ieee->pHTInfo);
ieee->pHTInfo = NULL;
}
rtllib_softmac_free(ieee);
del_timer_sync(&ieee->crypt_deinit_timer);
rtllib_crypt_deinit_entries(ieee, 1);
for (i = 0; i < WEP_KEYS; i++) {
struct rtllib_crypt_data *crypt = ieee->crypt[i];
if (crypt) {
if (crypt->ops)
crypt->ops->deinit(crypt->priv);
kfree(crypt);
ieee->crypt[i] = NULL;
}
}
rtllib_networks_free(ieee);
#ifdef CONFIG_CFG_80211
wiphy_unregister(ieee->wdev.wiphy);
wiphy_free(ieee->wdev.wiphy);
#endif
free_netdev(dev);
}
#ifdef CONFIG_RTLLIB_DEBUG
u32 rtllib_debug_level = 0;
static int debug = \
RTLLIB_DL_ERR
;
struct proc_dir_entry *rtllib_proc = NULL;
static int show_debug_level(char *page, char **start, off_t offset,
int count, int *eof, void *data)
{
return snprintf(page, count, "0x%08X\n", rtllib_debug_level);
}
static int store_debug_level(struct file *file, const char *buffer,
unsigned long count, void *data)
{
char buf[] = "0x00000000";
unsigned long len = min((unsigned long)sizeof(buf) - 1, count);
char *p = (char *)buf;
unsigned long val;
if (copy_from_user(buf, buffer, len))
return count;
buf[len] = 0;
if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
p++;
if (p[0] == 'x' || p[0] == 'X')
p++;
val = simple_strtoul(p, &p, 16);
} else
val = simple_strtoul(p, &p, 10);
if (p == buf)
printk(KERN_INFO DRV_NAME
": %s is not in hex or decimal form.\n", buf);
else
rtllib_debug_level = val;
return strnlen(buf, count);
}
int __init rtllib_init(void)
{
#ifdef CONFIG_RTLLIB_DEBUG
struct proc_dir_entry *e;
rtllib_debug_level = debug;
rtllib_proc = create_proc_entry(DRV_NAME, S_IFDIR, init_net.proc_net);
if (rtllib_proc == NULL) {
RTLLIB_ERROR("Unable to create " DRV_NAME
" proc directory\n");
return -EIO;
}
e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
rtllib_proc);
if (!e) {
remove_proc_entry(DRV_NAME, init_net.proc_net);
rtllib_proc = NULL;
return -EIO;
}
e->read_proc = show_debug_level;
e->write_proc = store_debug_level;
e->data = NULL;
#endif
return 0;
}
void __exit rtllib_exit(void)
{
#ifdef CONFIG_RTLLIB_DEBUG
if (rtllib_proc) {
remove_proc_entry("debug_level", rtllib_proc);
remove_proc_entry(DRV_NAME, init_net.proc_net);
rtllib_proc = NULL;
}
#endif
}
#endif

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -14,13 +14,14 @@
*/
#include "ieee80211.h"
#include "rtllib.h"
#include "rtl_core.h"
#ifdef ENABLE_DOT11D
#include "dot11d.h"
#endif
/* FIXME: add A freqs */
const long ieee80211_wlan_frequencies[] = {
const long rtllib_wlan_frequencies[] = {
2412, 2417, 2422, 2427,
2432, 2437, 2442, 2447,
2452, 2457, 2462, 2467,
@ -28,7 +29,7 @@ const long ieee80211_wlan_frequencies[] = {
};
int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
int rtllib_wx_set_freq(struct rtllib_device *ieee, struct iw_request_info *a,
union iwreq_data *wrqu, char *b)
{
int ret;
@ -36,8 +37,8 @@ int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info
down(&ieee->wx_sem);
if(ieee->iw_mode == IW_MODE_INFRA){
ret = -EOPNOTSUPP;
if (ieee->iw_mode == IW_MODE_INFRA){
ret = 0;
goto out;
}
@ -48,7 +49,7 @@ int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info
int f = fwrq->m / 100000;
int c = 0;
while ((c < 14) && (f != ieee80211_wlan_frequencies[c]))
while ((c < 14) && (f != rtllib_wlan_frequencies[c]))
c++;
/* hack to fall through */
@ -64,19 +65,19 @@ int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info
}else { /* Set the channel */
#ifdef ENABLE_DOT11D
if (!(GET_DOT11D_INFO(ieee)->channel_map)[fwrq->m]) {
if (ieee->active_channel_map[fwrq->m] != 1) {
ret = -EINVAL;
goto out;
}
#endif
ieee->current_network.channel = fwrq->m;
ieee->set_chan(ieee, ieee->current_network.channel);
ieee->set_chan(ieee->dev, ieee->current_network.channel);
if(ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
if(ieee->state == IEEE80211_LINKED){
if (ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
if (ieee->state == RTLLIB_LINKED){
ieee80211_stop_send_beacons(ieee);
ieee80211_start_send_beacons(ieee);
rtllib_stop_send_beacons(ieee);
rtllib_start_send_beacons(ieee);
}
}
@ -87,7 +88,7 @@ int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info
}
int ieee80211_wx_get_freq(struct ieee80211_device *ieee,
int rtllib_wx_get_freq(struct rtllib_device *ieee,
struct iw_request_info *a,
union iwreq_data *wrqu, char *b)
{
@ -95,18 +96,17 @@ int ieee80211_wx_get_freq(struct ieee80211_device *ieee,
if (ieee->current_network.channel == 0)
return -1;
//NM 0.7.0 will not accept channel any more.
fwrq->m = ieee80211_wlan_frequencies[ieee->current_network.channel-1] * 100000;
fwrq->m = rtllib_wlan_frequencies[ieee->current_network.channel-1] * 100000;
fwrq->e = 1;
return 0;
}
int ieee80211_wx_get_wap(struct ieee80211_device *ieee,
int rtllib_wx_get_wap(struct rtllib_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
unsigned long flags;
wrqu->ap_addr.sa_family = ARPHRD_ETHER;
if (ieee->iw_mode == IW_MODE_MONITOR)
@ -115,8 +115,8 @@ int ieee80211_wx_get_wap(struct ieee80211_device *ieee,
/* We want avoid to give to the user inconsistent infos*/
spin_lock_irqsave(&ieee->lock, flags);
if (ieee->state != IEEE80211_LINKED &&
ieee->state != IEEE80211_LINKED_SCANNING &&
if (ieee->state != RTLLIB_LINKED &&
ieee->state != RTLLIB_LINKED_SCANNING &&
ieee->wap_set == 0)
memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
@ -130,7 +130,7 @@ int ieee80211_wx_get_wap(struct ieee80211_device *ieee,
}
int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
int rtllib_wx_set_wap(struct rtllib_device *ieee,
struct iw_request_info *info,
union iwreq_data *awrq,
char *extra)
@ -140,10 +140,10 @@ int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
u8 zero[] = {0,0,0,0,0,0};
unsigned long flags;
short ifup = ieee->proto_started;//dev->flags & IFF_UP;
short ifup = ieee->proto_started;
struct sockaddr *temp = (struct sockaddr *)awrq;
ieee->sync_scan_hurryup = 1;
rtllib_stop_scan_syncro(ieee);
down(&ieee->wx_sem);
/* use ifconfig hw ether */
@ -157,27 +157,38 @@ int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
goto out;
}
if (memcmp(temp->sa_data, zero,ETH_ALEN) == 0){
spin_lock_irqsave(&ieee->lock, flags);
memcpy(ieee->current_network.bssid, temp->sa_data, ETH_ALEN);
ieee->wap_set = 0;
spin_unlock_irqrestore(&ieee->lock, flags);
ret = -1;
goto out;
}
if (ifup)
ieee80211_stop_protocol(ieee,true);
rtllib_stop_protocol(ieee,true);
/* just to avoid to give inconsistent infos in the
* get wx method. not really needed otherwise
*/
spin_lock_irqsave(&ieee->lock, flags);
ieee->cannot_notify = false;
memcpy(ieee->current_network.bssid, temp->sa_data, ETH_ALEN);
ieee->wap_set = memcmp(temp->sa_data, zero,ETH_ALEN)!=0;
ieee->wap_set = (memcmp(temp->sa_data, zero,ETH_ALEN)!=0);
spin_unlock_irqrestore(&ieee->lock, flags);
if (ifup)
ieee80211_start_protocol(ieee);
rtllib_start_protocol(ieee);
out:
up(&ieee->wx_sem);
return ret;
}
int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b)
int rtllib_wx_get_essid(struct rtllib_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b)
{
int len,ret = 0;
unsigned long flags;
@ -194,8 +205,8 @@ int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
goto out;
}
if (ieee->state != IEEE80211_LINKED &&
ieee->state != IEEE80211_LINKED_SCANNING &&
if (ieee->state != RTLLIB_LINKED &&
ieee->state != RTLLIB_LINKED_SCANNING &&
ieee->ssid_set == 0){
ret = -1;
goto out;
@ -212,7 +223,7 @@ int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
}
int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
int rtllib_wx_set_rate(struct rtllib_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
@ -220,26 +231,37 @@ int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
u32 target_rate = wrqu->bitrate.value;
ieee->rate = target_rate/100000;
//FIXME: we might want to limit rate also in management protocols.
return 0;
}
int ieee80211_wx_get_rate(struct ieee80211_device *ieee,
int rtllib_wx_get_rate(struct rtllib_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
u32 tmp_rate;
u32 tmp_rate = 0;
#if defined RTL8192SU
if (ieee->mode & (IEEE_A | IEEE_B | IEEE_G))
tmp_rate = ieee->rate;
else if (ieee->mode & IEEE_N_5G)
tmp_rate = 580;
else if (ieee->mode & IEEE_N_24G) {
if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))
tmp_rate = HTHalfMcsToDataRate(ieee, 15);
else
tmp_rate = HTMcsToDataRate(ieee, 15);
}
#elif defined RTL8192SE || defined RTL8192CE
tmp_rate = ieee->rtl_11n_user_show_rates(ieee->dev);
#else
tmp_rate = TxCountToDataRate(ieee, ieee->softmac_stats.CurrentShowTxate);
#endif
wrqu->bitrate.value = tmp_rate * 500000;
return 0;
}
int ieee80211_wx_set_rts(struct ieee80211_device *ieee,
int rtllib_wx_set_rts(struct rtllib_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
@ -255,7 +277,7 @@ int ieee80211_wx_set_rts(struct ieee80211_device *ieee,
return 0;
}
int ieee80211_wx_get_rts(struct ieee80211_device *ieee,
int rtllib_wx_get_rts(struct rtllib_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
@ -264,113 +286,145 @@ int ieee80211_wx_get_rts(struct ieee80211_device *ieee,
wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD);
return 0;
}
int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
int rtllib_wx_set_mode(struct rtllib_device *ieee, struct iw_request_info *a,
union iwreq_data *wrqu, char *b)
{
int set_mode_status = 0;
ieee->sync_scan_hurryup = 1;
rtllib_stop_scan_syncro(ieee);
down(&ieee->wx_sem);
switch (wrqu->mode) {
case IW_MODE_MONITOR:
case IW_MODE_ADHOC:
case IW_MODE_INFRA:
break;
case IW_MODE_AUTO:
wrqu->mode = IW_MODE_INFRA;
break;
default:
set_mode_status = -EINVAL;
goto out;
}
if (wrqu->mode == ieee->iw_mode)
goto out;
if (wrqu->mode == IW_MODE_MONITOR){
if (wrqu->mode == IW_MODE_MONITOR) {
#if defined(RTLLIB_RADIOTAP) && (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10))
ieee->dev->type = ARPHRD_IEEE80211_RADIOTAP;
#else
ieee->dev->type = ARPHRD_IEEE80211;
}else{
#endif
rtllib_EnableNetMonitorMode(ieee->dev,false);
} else {
ieee->dev->type = ARPHRD_ETHER;
if (ieee->iw_mode == IW_MODE_MONITOR)
rtllib_DisableNetMonitorMode(ieee->dev,false);
}
if (!ieee->proto_started){
if (!ieee->proto_started) {
ieee->iw_mode = wrqu->mode;
}else{
ieee80211_stop_protocol(ieee,true);
} else {
rtllib_stop_protocol(ieee,true);
ieee->iw_mode = wrqu->mode;
ieee80211_start_protocol(ieee);
rtllib_start_protocol(ieee);
}
out:
up(&ieee->wx_sem);
return 0;
return set_mode_status;
}
void ieee80211_wx_sync_scan_wq(struct work_struct *work)
void rtllib_wx_sync_scan_wq(void *data)
{
struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, wx_sync_scan_wq);
struct rtllib_device *ieee = container_of_work_rsl(data, struct rtllib_device, wx_sync_scan_wq);
short chan;
HT_EXTCHNL_OFFSET chan_offset=0;
HT_CHANNEL_WIDTH bandwidth=0;
int b40M = 0;
static int count = 0;
chan = ieee->current_network.channel;
#ifdef ENABLE_LPS
if (ieee->LeisurePSLeave) {
ieee->LeisurePSLeave(ieee);
if (!(ieee->softmac_features & IEEE_SOFTMAC_SCAN)){
rtllib_start_scan_syncro(ieee, 0);
goto out;
}
chan = ieee->current_network.channel;
if (ieee->LeisurePSLeave)
ieee->LeisurePSLeave(ieee->dev);
/* notify AP to be in PS mode */
ieee80211_sta_ps_send_null_frame(ieee, 1);
ieee80211_sta_ps_send_null_frame(ieee, 1);
#endif
rtllib_sta_ps_send_null_frame(ieee, 1);
rtllib_sta_ps_send_null_frame(ieee, 1);
rtllib_stop_all_queues(ieee);
if (ieee->data_hard_stop)
ieee->data_hard_stop(ieee);
ieee->data_hard_stop(ieee->dev);
rtllib_stop_send_beacons(ieee);
ieee->state = RTLLIB_LINKED_SCANNING;
ieee->link_change(ieee->dev);
/* wait for ps packet to be kicked out successfully */
msleep(50);
ieee80211_stop_send_beacons(ieee);
if (ieee->ScanOperationBackupHandler)
ieee->ScanOperationBackupHandler(ieee->dev,SCAN_OPT_BACKUP);
ieee->state = IEEE80211_LINKED_SCANNING;
ieee->link_change(ieee);
ieee->InitialGainHandler(ieee, IG_Backup);
if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT && ieee->pHTInfo->bCurBW40MHz) {
b40M = 1;
chan_offset = ieee->pHTInfo->CurSTAExtChnlOffset;
bandwidth = (HT_CHANNEL_WIDTH)ieee->pHTInfo->bCurBW40MHz;
printk("Scan in 40M, force to 20M first:%d, %d\n", chan_offset, bandwidth);
ieee->SetBWModeHandler(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
RT_TRACE(COMP_DBG, "Scan in 40M, force to 20M first:%d, %d\n", chan_offset, bandwidth);
ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
}
ieee80211_start_scan_syncro(ieee);
rtllib_start_scan_syncro(ieee, 0);
if (b40M) {
printk("Scan in 20M, back to 40M\n");
RT_TRACE(COMP_DBG, "Scan in 20M, back to 40M\n");
if (chan_offset == HT_EXTCHNL_OFFSET_UPPER)
ieee->set_chan(ieee, chan + 2);
ieee->set_chan(ieee->dev, chan + 2);
else if (chan_offset == HT_EXTCHNL_OFFSET_LOWER)
ieee->set_chan(ieee, chan - 2);
ieee->set_chan(ieee->dev, chan - 2);
else
ieee->set_chan(ieee, chan);
ieee->SetBWModeHandler(ieee, bandwidth, chan_offset);
ieee->set_chan(ieee->dev, chan);
ieee->SetBWModeHandler(ieee->dev, bandwidth, chan_offset);
} else {
ieee->set_chan(ieee, chan);
ieee->set_chan(ieee->dev, chan);
}
ieee->InitialGainHandler(ieee, IG_Restore);
ieee->state = IEEE80211_LINKED;
ieee->link_change(ieee);
if (ieee->ScanOperationBackupHandler)
ieee->ScanOperationBackupHandler(ieee->dev,SCAN_OPT_RESTORE);
ieee->state = RTLLIB_LINKED;
ieee->link_change(ieee->dev);
#ifdef ENABLE_LPS
/* Notify AP that I wake up again */
ieee80211_sta_ps_send_null_frame(ieee, 0);
#endif
rtllib_sta_ps_send_null_frame(ieee, 0);
// To prevent the immediately calling watch_dog after scan.
if(ieee->LinkDetectInfo.NumRecvBcnInPeriod==0||ieee->LinkDetectInfo.NumRecvDataInPeriod==0 )
{
if (ieee->LinkDetectInfo.NumRecvBcnInPeriod == 0 ||
ieee->LinkDetectInfo.NumRecvDataInPeriod == 0 ) {
ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1;
ieee->LinkDetectInfo.NumRecvDataInPeriod= 1;
}
if (ieee->data_hard_resume)
ieee->data_hard_resume(ieee);
if(ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
ieee80211_start_send_beacons(ieee);
if (ieee->data_hard_resume)
ieee->data_hard_resume(ieee->dev);
if (ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
rtllib_start_send_beacons(ieee);
rtllib_wake_all_queues(ieee);
count = 0;
out:
up(&ieee->wx_sem);
}
int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a,
int rtllib_wx_set_scan(struct rtllib_device *ieee, struct iw_request_info *a,
union iwreq_data *wrqu, char *b)
{
int ret = 0;
@ -382,8 +436,8 @@ int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info
goto out;
}
if ( ieee->state == IEEE80211_LINKED){
queue_work(ieee->wq, &ieee->wx_sync_scan_wq);
if ( ieee->state == RTLLIB_LINKED){
queue_work_rsl(ieee->wq, &ieee->wx_sync_scan_wq);
/* intentionally forget to up sem */
return 0;
}
@ -393,21 +447,27 @@ int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info
return ret;
}
int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
int rtllib_wx_set_essid(struct rtllib_device *ieee,
struct iw_request_info *a,
union iwreq_data *wrqu, char *extra)
{
int ret=0,len;
int ret=0,len,i;
short proto_started;
unsigned long flags;
ieee->sync_scan_hurryup = 1;
rtllib_stop_scan_syncro(ieee);
down(&ieee->wx_sem);
proto_started = ieee->proto_started;
if (wrqu->essid.length > IW_ESSID_MAX_SIZE){
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
len = ((wrqu->essid.length-1) < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length-1) : IW_ESSID_MAX_SIZE;
#else
len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ? wrqu->essid.length : IW_ESSID_MAX_SIZE;
#endif
if (len > IW_ESSID_MAX_SIZE){
ret= -E2BIG;
goto out;
}
@ -417,9 +477,15 @@ int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
goto out;
}
if(proto_started){
ieee80211_stop_protocol(ieee,true);
for (i=0; i<len; i++){
if (extra[i] < 0){
ret= -1;
goto out;
}
}
if (proto_started)
rtllib_stop_protocol(ieee,true);
/* this is just to be sure that the GET wx callback
@ -428,10 +494,9 @@ int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
spin_lock_irqsave(&ieee->lock, flags);
if (wrqu->essid.flags && wrqu->essid.length) {
//first flush current network.ssid
len = ((wrqu->essid.length-1) < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length-1) : IW_ESSID_MAX_SIZE;
strncpy(ieee->current_network.ssid, extra, len+1);
ieee->current_network.ssid_len = len+1;
strncpy(ieee->current_network.ssid, extra, len);
ieee->current_network.ssid_len = len;
ieee->cannot_notify = false;
ieee->ssid_set = 1;
}
else{
@ -442,21 +507,20 @@ int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
spin_unlock_irqrestore(&ieee->lock, flags);
if (proto_started)
ieee80211_start_protocol(ieee);
rtllib_start_protocol(ieee);
out:
up(&ieee->wx_sem);
return ret;
}
int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
int rtllib_wx_get_mode(struct rtllib_device *ieee, struct iw_request_info *a,
union iwreq_data *wrqu, char *b)
{
wrqu->mode = ieee->iw_mode;
return 0;
}
int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
int rtllib_wx_set_rawtx(struct rtllib_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
@ -467,7 +531,7 @@ int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
down(&ieee->wx_sem);
if(enable)
if (enable)
ieee->raw_tx = 1;
else
ieee->raw_tx = 0;
@ -475,16 +539,16 @@ int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
printk(KERN_INFO"raw TX is %s\n",
ieee->raw_tx ? "enabled" : "disabled");
if(ieee->iw_mode == IW_MODE_MONITOR)
if (ieee->iw_mode == IW_MODE_MONITOR)
{
if(prev == 0 && ieee->raw_tx){
if (prev == 0 && ieee->raw_tx){
if (ieee->data_hard_resume)
ieee->data_hard_resume(ieee);
ieee->data_hard_resume(ieee->dev);
netif_carrier_on(ieee->dev);
}
if(prev && ieee->raw_tx == 1)
if (prev && ieee->raw_tx == 1)
netif_carrier_off(ieee->dev);
}
@ -493,14 +557,15 @@ int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
return 0;
}
int ieee80211_wx_get_name(struct ieee80211_device *ieee,
int rtllib_wx_get_name(struct rtllib_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
strcpy(wrqu->name, "802.11");
if(ieee->modulation & IEEE80211_CCK_MODULATION)
if (ieee->modulation & RTLLIB_CCK_MODULATION)
strcat(wrqu->name, "b");
if(ieee->modulation & IEEE80211_OFDM_MODULATION)
if (ieee->modulation & RTLLIB_OFDM_MODULATION)
strcat(wrqu->name, "g");
if (ieee->mode & (IEEE_N_24G | IEEE_N_5G))
strcat(wrqu->name, "n");
@ -509,42 +574,48 @@ int ieee80211_wx_get_name(struct ieee80211_device *ieee,
/* this is mostly stolen from hostap */
int ieee80211_wx_set_power(struct ieee80211_device *ieee,
int rtllib_wx_set_power(struct rtllib_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
int ret = 0;
if(
#if 1
if (
(!ieee->sta_wake_up) ||
(!ieee->enter_sleep_state) ||
(!ieee->ps_is_queue_empty)){
RTLLIB_DEBUG(RTLLIB_DL_ERR,"%s(): PS mode is tryied to be use but driver missed a callback\n\n",__func__);
return -1;
}
#endif
down(&ieee->wx_sem);
if (wrqu->power.disabled){
ieee->ps = IEEE80211_PS_DISABLED;
RT_TRACE(COMP_DBG, "===>%s(): power disable\n",__func__);
ieee->ps = RTLLIB_PS_DISABLED;
goto exit;
}
if (wrqu->power.flags & IW_POWER_TIMEOUT) {
ieee->ps_timeout = wrqu->power.value / 1000;
RT_TRACE(COMP_DBG, "===>%s():ps_timeout is %d\n",__func__,ieee->ps_timeout);
}
if (wrqu->power.flags & IW_POWER_PERIOD) {
ieee->ps_period = wrqu->power.value / 1000;
}
switch (wrqu->power.flags & IW_POWER_MODE) {
case IW_POWER_UNICAST_R:
ieee->ps = IEEE80211_PS_UNICAST;
ieee->ps = RTLLIB_PS_UNICAST;
break;
case IW_POWER_MULTICAST_R:
ieee->ps = IEEE80211_PS_MBCAST;
ieee->ps = RTLLIB_PS_MBCAST;
break;
case IW_POWER_ALL_R:
ieee->ps = IEEE80211_PS_UNICAST | IEEE80211_PS_MBCAST;
ieee->ps = RTLLIB_PS_UNICAST | RTLLIB_PS_MBCAST;
break;
case IW_POWER_ON:
@ -562,7 +633,7 @@ int ieee80211_wx_set_power(struct ieee80211_device *ieee,
}
/* this is stolen from hostap */
int ieee80211_wx_get_power(struct ieee80211_device *ieee,
int rtllib_wx_get_power(struct rtllib_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
@ -570,7 +641,7 @@ int ieee80211_wx_get_power(struct ieee80211_device *ieee,
down(&ieee->wx_sem);
if(ieee->ps == IEEE80211_PS_DISABLED){
if (ieee->ps == RTLLIB_PS_DISABLED) {
wrqu->power.disabled = 1;
goto exit;
}
@ -585,9 +656,9 @@ int ieee80211_wx_get_power(struct ieee80211_device *ieee,
wrqu->power.value = ieee->ps_period * 1000;
}
if ((ieee->ps & (IEEE80211_PS_MBCAST | IEEE80211_PS_UNICAST)) == (IEEE80211_PS_MBCAST | IEEE80211_PS_UNICAST))
if ((ieee->ps & (RTLLIB_PS_MBCAST | RTLLIB_PS_UNICAST)) == (RTLLIB_PS_MBCAST | RTLLIB_PS_UNICAST))
wrqu->power.flags |= IW_POWER_ALL_R;
else if (ieee->ps & IEEE80211_PS_MBCAST)
else if (ieee->ps & RTLLIB_PS_MBCAST)
wrqu->power.flags |= IW_POWER_MULTICAST_R;
else
wrqu->power.flags |= IW_POWER_UNICAST_R;
@ -597,4 +668,3 @@ int ieee80211_wx_get_power(struct ieee80211_device *ieee,
return ret;
}

View file

@ -32,16 +32,14 @@
#include <linux/wireless.h>
#include <linux/version.h>
#include <linux/kmod.h>
#include <linux/slab.h>
#include <linux/module.h>
#include "ieee80211.h"
#include "rtllib.h"
struct modes_unit {
char *mode_string;
int mode_size;
};
struct modes_unit ieee80211_modes[] = {
static struct modes_unit rtllib_modes[] = {
{"a",1},
{"b",1},
{"g",1},
@ -50,12 +48,10 @@ struct modes_unit ieee80211_modes[] = {
{"N-5G",4},
};
#define iwe_stream_add_event_rsl iwe_stream_add_event
#define MAX_CUSTOM_LEN 64
static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
static inline char *rtl819x_translate_scan(struct rtllib_device *ieee,
char *start, char *stop,
struct ieee80211_network *network,
struct rtllib_network *network,
struct iw_request_info *info)
{
char custom[MAX_CUSTOM_LEN];
@ -77,20 +73,22 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
/* Add the ESSID */
iwe.cmd = SIOCGIWESSID;
iwe.u.data.flags = 1;
// if (network->flags & NETWORK_EMPTY_ESSID) {
if (network->ssid_len == 0) {
iwe.u.data.length = sizeof("<hidden>");
start = iwe_stream_add_point(info, start, stop, &iwe, "<hidden>");
} else {
if (network->ssid_len > 0){
iwe.u.data.length = min(network->ssid_len, (u8)32);
start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
start = iwe_stream_add_point_rsl(info, start, stop, &iwe, network->ssid);
}else if (network->hidden_ssid_len == 0){
iwe.u.data.length = sizeof("<hidden>");
start = iwe_stream_add_point_rsl(info, start, stop, &iwe, "<hidden>");
}else {
iwe.u.data.length = min(network->hidden_ssid_len, (u8)32);
start = iwe_stream_add_point_rsl(info, start, stop, &iwe, network->hidden_ssid);
}
/* Add the protocol name */
iwe.cmd = SIOCGIWNAME;
for(i=0; i<ARRAY_SIZE(ieee80211_modes); i++) {
if(network->mode&(1<<i)) {
sprintf(pname,ieee80211_modes[i].mode_string,ieee80211_modes[i].mode_size);
pname +=ieee80211_modes[i].mode_size;
for (i=0; i<(sizeof(rtllib_modes)/sizeof(rtllib_modes[0])); i++) {
if (network->mode&(1<<i)) {
sprintf(pname,rtllib_modes[i].mode_string,rtllib_modes[i].mode_size);
pname +=rtllib_modes[i].mode_size;
}
}
*pname = '\0';
@ -99,8 +97,8 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
/* Add mode */
iwe.cmd = SIOCGIWMODE;
if (network->capability &
(WLAN_CAPABILITY_BSS | WLAN_CAPABILITY_IBSS)) {
if (network->capability & WLAN_CAPABILITY_BSS)
(WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
if (network->capability & WLAN_CAPABILITY_ESS)
iwe.u.mode = IW_MODE_MASTER;
else
iwe.u.mode = IW_MODE_ADHOC;
@ -109,12 +107,13 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
/* Add frequency/channel */
iwe.cmd = SIOCGIWFREQ;
/* iwe.u.freq.m = ieee80211_frequency(network->channel, network->mode);
/* iwe.u.freq.m = rtllib_frequency(network->channel, network->mode);
iwe.u.freq.e = 3; */
iwe.u.freq.m = network->channel;
iwe.u.freq.e = 0;
iwe.u.freq.i = 0;
start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_FREQ_LEN);
/* Add encryption capability */
iwe.cmd = SIOCGIWENCODE;
if (network->capability & WLAN_CAPABILITY_PRIVACY)
@ -122,7 +121,7 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
start = iwe_stream_add_point_rsl(info, start, stop, &iwe, network->ssid);
/* Add basic and extended rates */
max_rate = 0;
p = custom;
@ -147,7 +146,7 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
max_rate = rate;
}
if (network->mode >= IEEE_N_24G)//add N rate here;
if (network->mode >= IEEE_N_24G)
{
PHT_CAPABILITY_ELE ht_cap = NULL;
bool is40M = false, isShortGI = false;
@ -174,28 +173,28 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
iwe.cmd = IWEVCUSTOM;
iwe.u.data.length = p - custom;
if (iwe.u.data.length)
start = iwe_stream_add_point(info, start, stop, &iwe, custom);
start = iwe_stream_add_point_rsl(info, start, stop, &iwe, custom);
/* Add quality statistics */
/* TODO: Fix these values... */
iwe.cmd = IWEVQUAL;
iwe.u.qual.qual = network->stats.signal;
iwe.u.qual.level = network->stats.rssi;
iwe.u.qual.noise = network->stats.noise;
iwe.u.qual.updated = network->stats.mask & IEEE80211_STATMASK_WEMASK;
if (!(network->stats.mask & IEEE80211_STATMASK_RSSI))
iwe.u.qual.updated = network->stats.mask & RTLLIB_STATMASK_WEMASK;
if (!(network->stats.mask & RTLLIB_STATMASK_RSSI))
iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID;
if (!(network->stats.mask & IEEE80211_STATMASK_NOISE))
if (!(network->stats.mask & RTLLIB_STATMASK_NOISE))
iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID;
if (!(network->stats.mask & IEEE80211_STATMASK_SIGNAL))
if (!(network->stats.mask & RTLLIB_STATMASK_SIGNAL))
iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID;
iwe.u.qual.updated = 7;
start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_QUAL_LEN);
iwe.cmd = IWEVCUSTOM;
p = custom;
iwe.u.data.length = p - custom;
if (iwe.u.data.length)
start = iwe_stream_add_point(info, start, stop, &iwe, custom);
start = iwe_stream_add_point_rsl(info, start, stop, &iwe, custom);
#if (WIRELESS_EXT < 18)
if (ieee->wpa_enabled && network->wpa_ie_len){
char buf[MAX_WPA_IE_LEN * 2 + 30];
@ -208,7 +207,7 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVCUSTOM;
iwe.u.data.length = strlen(buf);
start = iwe_stream_add_point(info, start, stop, &iwe, buf);
start = iwe_stream_add_point_rsl(info, start, stop, &iwe, buf);
}
if (ieee->wpa_enabled && network->rsn_ie_len){
@ -223,7 +222,7 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVCUSTOM;
iwe.u.data.length = strlen(buf);
start = iwe_stream_add_point(info, start, stop, &iwe, buf);
start = iwe_stream_add_point_rsl(info, start, stop, &iwe, buf);
}
#else
memset(&iwe, 0, sizeof(iwe));
@ -233,7 +232,7 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
memcpy(buf, network->wpa_ie, network->wpa_ie_len);
iwe.cmd = IWEVGENIE;
iwe.u.data.length = network->wpa_ie_len;
start = iwe_stream_add_point(info, start, stop, &iwe, buf);
start = iwe_stream_add_point_rsl(info, start, stop, &iwe, buf);
}
memset(&iwe, 0, sizeof(iwe));
if (network->rsn_ie_len)
@ -242,10 +241,22 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
memcpy(buf, network->rsn_ie, network->rsn_ie_len);
iwe.cmd = IWEVGENIE;
iwe.u.data.length = network->rsn_ie_len;
start = iwe_stream_add_point(info, start, stop, &iwe, buf);
start = iwe_stream_add_point_rsl(info, start, stop, &iwe, buf);
}
#ifndef CUSTOMER_ID_INTEL_CMPC
/* add info for WZC */
memset(&iwe, 0, sizeof(iwe));
if (network->wzc_ie_len)
{
char buf[MAX_WZC_IE_LEN];
memcpy(buf, network->wzc_ie, network->wzc_ie_len);
iwe.cmd = IWEVGENIE;
iwe.u.data.length = network->wzc_ie_len;
start = iwe_stream_add_point_rsl(info, start, stop, &iwe, buf);
}
#endif
#endif
/* Add EXTRA: Age to display seconds since last beacon/probe response
* for given network. */
@ -255,31 +266,29 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
" Last beacon: %lums ago", (jiffies - network->last_scanned) / (HZ / 100));
iwe.u.data.length = p - custom;
if (iwe.u.data.length)
start = iwe_stream_add_point(info, start, stop, &iwe, custom);
start = iwe_stream_add_point_rsl(info, start, stop, &iwe, custom);
return start;
}
int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
int rtllib_wx_get_scan(struct rtllib_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
struct ieee80211_network *network;
struct rtllib_network *network;
unsigned long flags;
char *ev = extra;
// char *stop = ev + IW_SCAN_MAX_DATA;
char *stop = ev + wrqu->data.length;//IW_SCAN_MAX_DATA;
//char *stop = ev + IW_SCAN_MAX_DATA;
char *stop = ev + wrqu->data.length;
int i = 0;
int err = 0;
IEEE80211_DEBUG_WX("Getting scan\n");
RTLLIB_DEBUG_WX("Getting scan\n");
down(&ieee->wx_sem);
spin_lock_irqsave(&ieee->lock, flags);
list_for_each_entry(network, &ieee->network_list, list) {
i++;
if((stop-ev)<200)
if ((stop-ev)<200)
{
err = -E2BIG;
break;
@ -288,12 +297,12 @@ int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
time_after(network->last_scanned + ieee->scan_age, jiffies))
ev = rtl819x_translate_scan(ieee, ev, stop, network, info);
else
IEEE80211_DEBUG_SCAN(
RTLLIB_DEBUG_SCAN(
"Not showing network '%s ("
"%pM)' due to age (%lums).\n",
MAC_FMT ")' due to age (%lums).\n",
escape_essid(network->ssid,
network->ssid_len),
network->bssid,
MAC_ARG(network->bssid),
(jiffies - network->last_scanned) / (HZ / 100));
}
@ -302,24 +311,24 @@ int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
wrqu->data.length = ev - extra;
wrqu->data.flags = 0;
IEEE80211_DEBUG_WX("exit: %d networks returned.\n", i);
RTLLIB_DEBUG_WX("exit: %d networks returned.\n", i);
return err;
}
int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
int rtllib_wx_set_encode(struct rtllib_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *keybuf)
{
struct iw_point *erq = &(wrqu->encoding);
struct net_device *dev = ieee->dev;
struct ieee80211_security sec = {
struct rtllib_security sec = {
.flags = 0
};
int i, key, key_provided, len;
struct ieee80211_crypt_data **crypt;
struct rtllib_crypt_data **crypt;
IEEE80211_DEBUG_WX("SET_ENCODE\n");
RTLLIB_DEBUG_WX("SET_ENCODE\n");
key = erq->flags & IW_ENCODE_INDEX;
if (key) {
@ -332,17 +341,16 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
key = ieee->tx_keyidx;
}
IEEE80211_DEBUG_WX("Key: %d [%s]\n", key, key_provided ?
RTLLIB_DEBUG_WX("Key: %d [%s]\n", key, key_provided ?
"provided" : "default");
crypt = &ieee->crypt[key];
if (erq->flags & IW_ENCODE_DISABLED) {
if (key_provided && *crypt) {
IEEE80211_DEBUG_WX("Disabling encryption on key %d.\n",
RTLLIB_DEBUG_WX("Disabling encryption on key %d.\n",
key);
ieee80211_crypt_delayed_deinit(ieee, crypt);
rtllib_crypt_delayed_deinit(ieee, crypt);
} else
IEEE80211_DEBUG_WX("Disabling encryption.\n");
RTLLIB_DEBUG_WX("Disabling encryption.\n");
/* Check all the keys to see if any are still configured,
* and if no key index was provided, de-init them all */
@ -350,8 +358,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
if (ieee->crypt[i] != NULL) {
if (key_provided)
break;
ieee80211_crypt_delayed_deinit(
ieee, &ieee->crypt[i]);
rtllib_crypt_delayed_deinit(ieee, &ieee->crypt[i]);
}
}
@ -373,20 +380,24 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
strcmp((*crypt)->ops->name, "WEP") != 0) {
/* changing to use WEP; deinit previously used algorithm
* on this key */
ieee80211_crypt_delayed_deinit(ieee, crypt);
rtllib_crypt_delayed_deinit(ieee, crypt);
}
if (*crypt == NULL) {
struct ieee80211_crypt_data *new_crypt;
struct rtllib_crypt_data *new_crypt;
/* take WEP into use */
new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data),
new_crypt = kmalloc(sizeof(struct rtllib_crypt_data),
GFP_KERNEL);
if (new_crypt == NULL)
return -ENOMEM;
new_crypt->ops = ieee80211_get_crypto_ops("WEP");
if (!new_crypt->ops)
new_crypt->ops = ieee80211_get_crypto_ops("WEP");
memset(new_crypt, 0, sizeof(struct rtllib_crypt_data));
new_crypt->ops = rtllib_get_crypto_ops("WEP");
if (!new_crypt->ops) {
request_module("rtllib_crypt_wep");
new_crypt->ops = rtllib_get_crypto_ops("WEP");
}
if (new_crypt->ops)
new_crypt->priv = new_crypt->ops->init(key);
@ -395,7 +406,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
new_crypt = NULL;
printk(KERN_WARNING "%s: could not initialize WEP: "
"load module ieee80211_crypt_wep\n",
"load module rtllib_crypt_wep\n",
dev->name);
return -EOPNOTSUPP;
}
@ -409,7 +420,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
if (len > erq->length)
memset(sec.keys[key] + erq->length, 0,
len - erq->length);
IEEE80211_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n",
RTLLIB_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n",
key, escape_essid(sec.keys[key], len),
erq->length, len);
sec.key_sizes[key] = len;
@ -430,7 +441,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
printk("Setting key %d to all zero.\n",
key);
IEEE80211_DEBUG_WX("Setting key %d to all zero.\n",
RTLLIB_DEBUG_WX("Setting key %d to all zero.\n",
key);
memset(sec.keys[key], 0, 13);
(*crypt)->ops->set_key(sec.keys[key], 13, NULL,
@ -441,20 +452,19 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
/* No key data - just set the default TX key index */
if (key_provided) {
IEEE80211_DEBUG_WX(
RTLLIB_DEBUG_WX(
"Setting key %d to default Tx key.\n", key);
ieee->tx_keyidx = key;
sec.active_key = key;
sec.flags |= SEC_ACTIVE_KEY;
}
}
done:
ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
ieee->auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
sec.flags |= SEC_AUTH_MODE;
IEEE80211_DEBUG_WX("Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ?
RTLLIB_DEBUG_WX("Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ?
"OPEN" : "SHARED KEY");
/* For now we just support WEP, so only set that security level...
@ -463,7 +473,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */
if (ieee->set_security)
ieee->set_security(ieee, &sec);
ieee->set_security(dev, &sec);
/* Do not reset port if card is in Managed mode since resetting will
* generate new IEEE 802.11 authentication which may end up in looping
@ -472,24 +482,24 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
* the callbacks structures used to initialize the 802.11 stack. */
if (ieee->reset_on_keychange &&
ieee->iw_mode != IW_MODE_INFRA &&
ieee->reset_port && ieee->reset_port(ieee)) {
ieee->reset_port && ieee->reset_port(dev)) {
printk(KERN_DEBUG "%s: reset_port failed\n", dev->name);
return -EINVAL;
}
return 0;
}
int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
int rtllib_wx_get_encode(struct rtllib_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *keybuf)
{
struct iw_point *erq = &(wrqu->encoding);
int len, key;
struct ieee80211_crypt_data *crypt;
struct rtllib_crypt_data *crypt;
IEEE80211_DEBUG_WX("GET_ENCODE\n");
RTLLIB_DEBUG_WX("GET_ENCODE\n");
if(ieee->iw_mode == IW_MODE_MONITOR)
if (ieee->iw_mode == IW_MODE_MONITOR)
return -1;
key = erq->flags & IW_ENCODE_INDEX;
@ -497,10 +507,11 @@ int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
if (key > WEP_KEYS)
return -EINVAL;
key--;
} else
} else {
key = ieee->tx_keyidx;
}
crypt = ieee->crypt[key];
erq->flags = key + 1;
if (crypt == NULL || crypt->ops == NULL) {
@ -508,15 +519,6 @@ int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
erq->flags |= IW_ENCODE_DISABLED;
return 0;
}
#if 0
if (strcmp(crypt->ops->name, "WEP") != 0) {
/* only WEP is supported with wireless extensions, so just
* report that encryption is used */
erq->length = 0;
erq->flags |= IW_ENCODE_ENABLED;
return 0;
}
#endif
len = crypt->ops->get_key(keybuf, SCM_KEY_LEN, NULL, crypt->priv);
erq->length = (len >= 0 ? len : 0);
@ -530,7 +532,7 @@ int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
return 0;
}
#if (WIRELESS_EXT >= 18)
int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
int rtllib_wx_set_encode_ext(struct rtllib_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
@ -540,11 +542,11 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
int i, idx;
int group_key = 0;
const char *alg;
struct ieee80211_crypto_ops *ops;
struct ieee80211_crypt_data **crypt;
const char *alg, *module;
struct rtllib_crypto_ops *ops;
struct rtllib_crypt_data **crypt;
struct ieee80211_security sec = {
struct rtllib_security sec = {
.flags = 0,
};
idx = encoding->flags & IW_ENCODE_INDEX;
@ -552,41 +554,34 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
if (idx < 1 || idx > WEP_KEYS)
return -EINVAL;
idx--;
} else
} else{
idx = ieee->tx_keyidx;
}
if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
crypt = &ieee->crypt[idx];
group_key = 1;
} else {
/* some Cisco APs use idx>0 for unicast in dynamic WEP */
if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
return -EINVAL;
if (ieee->iw_mode == IW_MODE_INFRA)
crypt = &ieee->crypt[idx];
else
return -EINVAL;
}
sec.flags |= SEC_ENABLED;// | SEC_ENCRYPT;
sec.flags |= SEC_ENABLED;
if ((encoding->flags & IW_ENCODE_DISABLED) ||
ext->alg == IW_ENCODE_ALG_NONE) {
if (*crypt)
ieee80211_crypt_delayed_deinit(ieee, crypt);
for (i = 0; i < WEP_KEYS; i++)
rtllib_crypt_delayed_deinit(ieee, crypt);
for (i = 0; i < WEP_KEYS; i++) {
if (ieee->crypt[i] != NULL)
break;
}
if (i == WEP_KEYS) {
sec.enabled = 0;
// sec.encrypt = 0;
sec.level = SEC_LEVEL_0;
sec.flags |= SEC_LEVEL;
}
@ -594,36 +589,38 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
}
sec.enabled = 1;
// sec.encrypt = 1;
#if 0
if (group_key ? !ieee->host_mc_decrypt :
!(ieee->host_encrypt || ieee->host_decrypt ||
ieee->host_encrypt_msdu))
goto skip_host_crypt;
#endif
switch (ext->alg) {
case IW_ENCODE_ALG_WEP:
alg = "WEP";
module = "rtllib_crypt_wep";
break;
case IW_ENCODE_ALG_TKIP:
alg = "TKIP";
module = "rtllib_crypt_tkip";
break;
case IW_ENCODE_ALG_CCMP:
alg = "CCMP";
module = "rtllib_crypt_ccmp";
break;
default:
IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
RTLLIB_DEBUG_WX("%s: unknown crypto alg %d\n",
dev->name, ext->alg);
ret = -EINVAL;
goto done;
}
printk("alg name:%s\n",alg);
ops = ieee80211_get_crypto_ops(alg);
if (ops == NULL)
ops = ieee80211_get_crypto_ops(alg);
ops = rtllib_get_crypto_ops(alg);
if (ops == NULL) {
IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
char tempbuf[100];
memset( tempbuf, 0x00, 100 );
sprintf( tempbuf, "%s", module);
request_module("%s",tempbuf);
ops = rtllib_get_crypto_ops(alg);
}
if (ops == NULL) {
RTLLIB_DEBUG_WX("%s: unknown crypto alg %d\n",
dev->name, ext->alg);
printk("========>unknown crypto alg %d\n", ext->alg);
ret = -EINVAL;
@ -631,16 +628,11 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
}
if (*crypt == NULL || (*crypt)->ops != ops) {
struct ieee80211_crypt_data *new_crypt;
struct rtllib_crypt_data *new_crypt;
ieee80211_crypt_delayed_deinit(ieee, crypt);
rtllib_crypt_delayed_deinit(ieee, crypt);
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13))
new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
#else
new_crypt = kmalloc(sizeof(*new_crypt), GFP_KERNEL);
memset(new_crypt,0,sizeof(*new_crypt));
#endif
if (new_crypt == NULL) {
ret = -ENOMEM;
goto done;
@ -648,6 +640,7 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
new_crypt->ops = ops;
if (new_crypt->ops)
new_crypt->priv = new_crypt->ops->init(idx);
if (new_crypt->priv == NULL) {
kfree(new_crypt);
ret = -EINVAL;
@ -660,32 +653,26 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
if (ext->key_len > 0 && (*crypt)->ops->set_key &&
(*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq,
(*crypt)->priv) < 0) {
IEEE80211_DEBUG_WX("%s: key setting failed\n", dev->name);
RTLLIB_DEBUG_WX("%s: key setting failed\n", dev->name);
printk("key setting failed\n");
ret = -EINVAL;
goto done;
}
#if 1
if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
ieee->tx_keyidx = idx;
sec.active_key = idx;
sec.flags |= SEC_ACTIVE_KEY;
}
if (ext->alg != IW_ENCODE_ALG_NONE) {
//memcpy(sec.keys[idx], ext->key, ext->key_len);
sec.key_sizes[idx] = ext->key_len;
sec.flags |= (1 << idx);
if (ext->alg == IW_ENCODE_ALG_WEP) {
// sec.encode_alg[idx] = SEC_ALG_WEP;
sec.flags |= SEC_LEVEL;
sec.level = SEC_LEVEL_1;
} else if (ext->alg == IW_ENCODE_ALG_TKIP) {
// sec.encode_alg[idx] = SEC_ALG_TKIP;
sec.flags |= SEC_LEVEL;
sec.level = SEC_LEVEL_2;
} else if (ext->alg == IW_ENCODE_ALG_CCMP) {
// sec.encode_alg[idx] = SEC_ALG_CCMP;
sec.flags |= SEC_LEVEL;
sec.level = SEC_LEVEL_3;
}
@ -693,27 +680,26 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
if (group_key)
sec.flags &= ~SEC_LEVEL;
}
#endif
done:
if (ieee->set_security)
ieee->set_security(ieee, &sec);
ieee->set_security(ieee->dev, &sec);
if (ieee->reset_on_keychange &&
ieee->iw_mode != IW_MODE_INFRA &&
ieee->reset_port && ieee->reset_port(ieee)) {
IEEE80211_DEBUG_WX("%s: reset_port failed\n", dev->name);
ieee->reset_port && ieee->reset_port(dev)) {
RTLLIB_DEBUG_WX("%s: reset_port failed\n", dev->name);
return -EINVAL;
}
return ret;
}
int ieee80211_wx_get_encode_ext(struct ieee80211_device *ieee,
int rtllib_wx_get_encode_ext(struct rtllib_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
struct iw_point *encoding = &wrqu->encoding;
struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
struct ieee80211_crypt_data *crypt;
struct rtllib_crypt_data *crypt;
int idx, max_key_len;
max_key_len = encoding->length - sizeof(*ext);
@ -725,15 +711,16 @@ int ieee80211_wx_get_encode_ext(struct ieee80211_device *ieee,
if (idx < 1 || idx > WEP_KEYS)
return -EINVAL;
idx--;
} else
} else {
idx = ieee->tx_keyidx;
}
if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) &&
ext->alg != IW_ENCODE_ALG_WEP)
if (idx != 0 || ieee->iw_mode != IW_MODE_INFRA)
(ext->alg != IW_ENCODE_ALG_WEP))
if (idx != 0 || (ieee->iw_mode != IW_MODE_INFRA))
return -EINVAL;
crypt = ieee->crypt[idx];
encoding->flags = idx + 1;
memset(ext, 0, sizeof(*ext));
@ -762,37 +749,67 @@ int ieee80211_wx_get_encode_ext(struct ieee80211_device *ieee,
return 0;
}
int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
int rtllib_wx_set_mlme(struct rtllib_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
u8 i = 0;
bool deauth = false;
struct iw_mlme *mlme = (struct iw_mlme *) extra;
if (ieee->state != RTLLIB_LINKED)
return -ENOLINK;
down(&ieee->wx_sem);
switch (mlme->cmd) {
case IW_MLME_DEAUTH:
deauth = true;
/* leave break out intentionly */
case IW_MLME_DISASSOC:
ieee80211_disassociate(ieee);
if (deauth == true)
printk("disauth packet !\n");
else
printk("dis associate packet!\n");
ieee->cannot_notify = true;
SendDisassociation(ieee,deauth,mlme->reason_code);
rtllib_disassociate(ieee);
ieee->wap_set = 0;
for (i = 0; i < 6; i++)
ieee->current_network.bssid[i]= 0x55;
ieee->ssid_set = 0;
ieee->current_network.ssid[0] = '\0';
ieee->current_network.ssid_len = 0;
break;
default:
up(&ieee->wx_sem);
return -EOPNOTSUPP;
}
up(&ieee->wx_sem);
return 0;
}
int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
int rtllib_wx_set_auth(struct rtllib_device *ieee,
struct iw_request_info *info,
struct iw_param *data, char *extra)
{
switch (data->flags & IW_AUTH_INDEX) {
case IW_AUTH_WPA_VERSION:
/*need to support wpa2 here*/
break;
case IW_AUTH_CIPHER_PAIRWISE:
case IW_AUTH_CIPHER_GROUP:
case IW_AUTH_KEY_MGMT:
/*
* * Host AP driver does not use these parameters and allows
* * wpa_supplicant to control them internally.
* */
* Host AP driver does not use these parameters and allows
* wpa_supplicant to control them internally.
*/
break;
case IW_AUTH_TKIP_COUNTERMEASURES:
ieee->tkip_countermeasures = data->value;
@ -802,15 +819,15 @@ int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
break;
case IW_AUTH_80211_AUTH_ALG:
if(data->value & IW_AUTH_ALG_SHARED_KEY){
if (data->value & IW_AUTH_ALG_SHARED_KEY){
ieee->open_wep = 0;
ieee->auth_mode = 1;
}
else if(data->value & IW_AUTH_ALG_OPEN_SYSTEM){
else if (data->value & IW_AUTH_ALG_OPEN_SYSTEM){
ieee->open_wep = 1;
ieee->auth_mode = 0;
}
else if(data->value & IW_AUTH_ALG_LEAP){
else if (data->value & IW_AUTH_ALG_LEAP){
ieee->open_wep = 1;
ieee->auth_mode = 2;
}
@ -818,12 +835,10 @@ int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
return -EINVAL;
break;
#if 1
case IW_AUTH_WPA_ENABLED:
ieee->wpa_enabled = (data->value)?1:0;
break;
#endif
case IW_AUTH_RX_UNENCRYPTED_EAPOL:
ieee->ieee802_1x = data->value;
break;
@ -836,37 +851,51 @@ int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
return 0;
}
#endif
#if 1
int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len)
int rtllib_wx_set_gen_ie(struct rtllib_device *ieee, u8 *ie, size_t len)
{
#if (WIRELESS_EXT >= 18 )
u8 *buf;
u8 eid, wps_oui[4]={0x0,0x50,0xf2,0x04};
if (len>MAX_WPA_IE_LEN || (len && ie == NULL))
{
if (len > MAX_WPA_IE_LEN || (len && ie == NULL)) {
return -EINVAL;
}
if (len) {
eid = ie[0];
if ((eid == MFIE_TYPE_GENERIC) && (!memcmp(&ie[2], wps_oui, 4))) {
if (len)
{
if (len != ie[1]+2)
{
printk("len:%zu, ie:%d\n", len, ie[1]);
return -EINVAL;
}
buf = kmemdup(ie, len, GFP_KERNEL);
ieee->wps_ie_len = (len < MAX_WZC_IE_LEN) ? (len):(MAX_WZC_IE_LEN);
buf = kmalloc(ieee->wps_ie_len, GFP_KERNEL);
if (buf == NULL)
return -ENOMEM;
memcpy(buf, ie, ieee->wps_ie_len);
ieee->wps_ie = buf;
return 0;
}
}
ieee->wps_ie_len = 0;
if (ieee->wps_ie)
kfree(ieee->wps_ie);
ieee->wps_ie = NULL;
if (len) {
if (len != ie[1]+2) {
return -EINVAL;
}
buf = kmalloc(len, GFP_KERNEL);
if (buf == NULL)
return -ENOMEM;
memcpy(buf, ie, len);
kfree(ieee->wpa_ie);
ieee->wpa_ie = buf;
ieee->wpa_ie_len = len;
}
else{
} else {
if (ieee->wpa_ie)
kfree(ieee->wpa_ie);
ieee->wpa_ie = NULL;
ieee->wpa_ie_len = 0;
}
return 0;
}
#endif
return 0;
}