Staging: delete rtl8192su driver
Now that we have a much better driver for this device (rtl8712), delete this driver as it is no longer needed. Cc: Larry Finger <Larry.Finger@lwfinger.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
Родитель
1407a9e105
Коммит
760ffce8ab
|
@ -73,8 +73,6 @@ source "drivers/staging/panel/Kconfig"
|
|||
|
||||
source "drivers/staging/rtl8187se/Kconfig"
|
||||
|
||||
source "drivers/staging/rtl8192su/Kconfig"
|
||||
|
||||
source "drivers/staging/rtl8192u/Kconfig"
|
||||
|
||||
source "drivers/staging/rtl8192e/Kconfig"
|
||||
|
|
|
@ -20,7 +20,6 @@ obj-$(CONFIG_COMEDI) += comedi/
|
|||
obj-$(CONFIG_ASUS_OLED) += asus_oled/
|
||||
obj-$(CONFIG_PANEL) += panel/
|
||||
obj-$(CONFIG_R8187SE) += rtl8187se/
|
||||
obj-$(CONFIG_RTL8192SU) += rtl8192su/
|
||||
obj-$(CONFIG_RTL8192U) += rtl8192u/
|
||||
obj-$(CONFIG_RTL8192E) += rtl8192e/
|
||||
obj-$(CONFIG_R8712U) += rtl8712/
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
config RTL8192SU
|
||||
tristate "RealTek RTL8192SU Wireless LAN NIC driver"
|
||||
depends on PCI && WLAN && USB
|
||||
select WIRELESS_EXT
|
||||
select WEXT_PRIV
|
||||
select EEPROM_93CX6
|
||||
select CRYPTO
|
||||
default N
|
||||
---help---
|
|
@ -1,39 +0,0 @@
|
|||
NIC_SELECT = RTL8192SU
|
||||
|
||||
EXTRA_CFLAGS += -std=gnu89
|
||||
EXTRA_CFLAGS += -O2
|
||||
|
||||
EXTRA_CFLAGS += -DJACKSON_NEW_RX
|
||||
EXTRA_CFLAGS += -DTHOMAS_BEACON
|
||||
|
||||
#EXTRA_CFLAGS += -DMUTIPLE_BULK_OUT
|
||||
|
||||
r8192s_usb-objs := \
|
||||
r8192U_wx.o \
|
||||
r8192S_phy.o \
|
||||
r8192S_rtl6052.o \
|
||||
r8192S_rtl8225.o \
|
||||
r819xU_cmdpkt.o \
|
||||
r8192U_dm.o \
|
||||
r8192SU_HWImg.o \
|
||||
r8192S_firmware.o \
|
||||
r8192S_Efuse.o \
|
||||
r8192U_core.o \
|
||||
r8192U_pm.o \
|
||||
r8192SU_led.o \
|
||||
ieee80211/ieee80211_crypt.o \
|
||||
ieee80211/ieee80211_crypt_tkip.o \
|
||||
ieee80211/ieee80211_crypt_ccmp.o \
|
||||
ieee80211/ieee80211_crypt_wep.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
|
||||
|
||||
obj-$(CONFIG_RTL8192SU) += r8192s_usb.o
|
|
@ -1,21 +0,0 @@
|
|||
TODO:
|
||||
- merge realteks bugfixes and new features into the driver:
|
||||
- an updated version of this driver can be found here:
|
||||
http://www.getnet.eu/products_GN-621U.html
|
||||
- note:
|
||||
realtek has stripped alomost all comments from the source,
|
||||
so please leave all comments that may help in development in the code.
|
||||
- prepare private ieee80211 stack for merge with rtl8187se's version:
|
||||
- remove rtl8192su's specific dead code
|
||||
- cleanup ieee80211.h
|
||||
- move rtl8192su's specific code out from ieee80211.h
|
||||
- abstract rtl819su's specific code
|
||||
- switch to use shared "librtl" instead of private ieee80211 stack
|
||||
- switch to use LIB80211
|
||||
- switch to use MAC80211
|
||||
- use kernel coding style
|
||||
- checkpatch.pl fixes
|
||||
- sparse fixes
|
||||
- integrate with drivers/net/wireless/rtl818x
|
||||
|
||||
Please send any patches to Greg Kroah-Hartman <greg@kroah.com>.
|
|
@ -1 +0,0 @@
|
|||
Andrea Merello <andreamrl@tiscali.it>
|
|
@ -1,30 +0,0 @@
|
|||
NIC_SELECT = RTL8192SU
|
||||
|
||||
EXTRA_CFLAGS += -O2
|
||||
EXTRA_CFLAGS += -DRTL8192S_DISABLE_FW_DM=0
|
||||
EXTRA_CFLAGS += -DRTL8192SU
|
||||
#EXTRA_CFLAGS += -DJOHN_NOCPY
|
||||
EXTRA_CFLAGS += -DTHOMAS_TURBO
|
||||
|
||||
ieee80211-rsl-objs := ieee80211_rx.o \
|
||||
ieee80211_softmac.o \
|
||||
ieee80211_tx.o \
|
||||
ieee80211_wx.o \
|
||||
ieee80211_module.o \
|
||||
ieee80211_softmac_wx.o\
|
||||
rtl819x_HTProc.o\
|
||||
rtl819x_TSProc.o\
|
||||
rtl819x_BAProc.o\
|
||||
dot11d.o
|
||||
|
||||
ieee80211_crypt-rsl-objs := ieee80211_crypt.o
|
||||
ieee80211_crypt_tkip-rsl-objs := ieee80211_crypt_tkip.o
|
||||
ieee80211_crypt_ccmp-rsl-objs := ieee80211_crypt_ccmp.o
|
||||
ieee80211_crypt_wep-rsl-objs := ieee80211_crypt_wep.o
|
||||
|
||||
obj-m +=ieee80211-rsl.o
|
||||
obj-m +=ieee80211_crypt-rsl.o
|
||||
obj-m +=ieee80211_crypt_wep-rsl.o
|
||||
obj-m +=ieee80211_crypt_tkip-rsl.o
|
||||
obj-m +=ieee80211_crypt_ccmp-rsl.o
|
||||
|
|
@ -1,224 +0,0 @@
|
|||
/******************************************************************************
|
||||
* 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"
|
||||
|
||||
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);
|
||||
|
||||
// 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;
|
||||
}
|
|
@ -1,111 +0,0 @@
|
|||
/******************************************************************************
|
||||
* 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
|
||||
|
||||
#include "ieee80211.h"
|
||||
|
||||
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 {
|
||||
|
||||
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 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
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,242 +0,0 @@
|
|||
/*
|
||||
* Host AP crypto routines
|
||||
*
|
||||
* Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
|
||||
* Portions Copyright (C) 2004, Intel Corporation <jketreno@linux.intel.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation. See README and COPYING for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#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"
|
||||
|
||||
MODULE_AUTHOR("Jouni Malinen");
|
||||
MODULE_DESCRIPTION("HostAP crypto");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
struct ieee80211_crypto_alg {
|
||||
struct list_head list;
|
||||
struct ieee80211_crypto_ops *ops;
|
||||
};
|
||||
|
||||
|
||||
struct ieee80211_crypto {
|
||||
struct list_head algs;
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
static struct ieee80211_crypto *hcrypt;
|
||||
|
||||
void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee,
|
||||
int force)
|
||||
{
|
||||
struct list_head *ptr, *n;
|
||||
struct ieee80211_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);
|
||||
|
||||
if (atomic_read(&entry->refcnt) != 0 && !force)
|
||||
continue;
|
||||
|
||||
list_del(ptr);
|
||||
|
||||
if (entry->ops)
|
||||
entry->ops->deinit(entry->priv);
|
||||
kfree(entry);
|
||||
}
|
||||
}
|
||||
|
||||
void ieee80211_crypt_deinit_handler(unsigned long data)
|
||||
{
|
||||
struct ieee80211_device *ieee = (struct ieee80211_device *)data;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&ieee->lock, flags);
|
||||
ieee80211_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);
|
||||
ieee->crypt_deinit_timer.expires = jiffies + HZ;
|
||||
add_timer(&ieee->crypt_deinit_timer);
|
||||
}
|
||||
spin_unlock_irqrestore(&ieee->lock, flags);
|
||||
|
||||
}
|
||||
|
||||
void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
|
||||
struct ieee80211_crypt_data **crypt)
|
||||
{
|
||||
struct ieee80211_crypt_data *tmp;
|
||||
unsigned long flags;
|
||||
|
||||
if (*crypt == NULL)
|
||||
return;
|
||||
|
||||
tmp = *crypt;
|
||||
*crypt = NULL;
|
||||
|
||||
/* must not run ops->deinit() while there may be pending encrypt or
|
||||
* decrypt operations. Use a list of delayed deinits to avoid needing
|
||||
* locking. */
|
||||
|
||||
spin_lock_irqsave(&ieee->lock, flags);
|
||||
list_add(&tmp->list, &ieee->crypt_deinit_list);
|
||||
if (!timer_pending(&ieee->crypt_deinit_timer)) {
|
||||
ieee->crypt_deinit_timer.expires = jiffies + HZ;
|
||||
add_timer(&ieee->crypt_deinit_timer);
|
||||
}
|
||||
spin_unlock_irqrestore(&ieee->lock, flags);
|
||||
}
|
||||
|
||||
int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct ieee80211_crypto_alg *alg;
|
||||
|
||||
if (hcrypt == NULL)
|
||||
return -1;
|
||||
|
||||
alg = kzalloc(sizeof(*alg), GFP_KERNEL);
|
||||
if (alg == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
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",
|
||||
ops->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct list_head *ptr;
|
||||
struct ieee80211_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;
|
||||
if (alg->ops == ops) {
|
||||
list_del(&alg->list);
|
||||
del_alg = alg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&hcrypt->lock, flags);
|
||||
|
||||
if (del_alg) {
|
||||
printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
|
||||
"'%s'\n", ops->name);
|
||||
kfree(del_alg);
|
||||
}
|
||||
|
||||
return del_alg ? 0 : -1;
|
||||
}
|
||||
|
||||
|
||||
struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct list_head *ptr;
|
||||
struct ieee80211_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;
|
||||
if (strcmp(alg->ops->name, name) == 0) {
|
||||
found_alg = alg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&hcrypt->lock, flags);
|
||||
|
||||
if (found_alg)
|
||||
return found_alg->ops;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void * ieee80211_crypt_null_init(int keyidx) { return (void *) 1; }
|
||||
static void ieee80211_crypt_null_deinit(void *priv) {}
|
||||
|
||||
static struct ieee80211_crypto_ops ieee80211_crypt_null = {
|
||||
.name = "NULL",
|
||||
.init = ieee80211_crypt_null_init,
|
||||
.deinit = ieee80211_crypt_null_deinit,
|
||||
.encrypt_mpdu = NULL,
|
||||
.decrypt_mpdu = NULL,
|
||||
.encrypt_msdu = NULL,
|
||||
.decrypt_msdu = NULL,
|
||||
.set_key = NULL,
|
||||
.get_key = NULL,
|
||||
.extra_prefix_len = 0,
|
||||
.extra_postfix_len = 0,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
int ieee80211_crypto_init(void)
|
||||
{
|
||||
int ret = -ENOMEM;
|
||||
|
||||
hcrypt = kzalloc(sizeof(*hcrypt), GFP_KERNEL);
|
||||
if (!hcrypt)
|
||||
goto out;
|
||||
|
||||
INIT_LIST_HEAD(&hcrypt->algs);
|
||||
spin_lock_init(&hcrypt->lock);
|
||||
|
||||
ret = ieee80211_register_crypto_ops(&ieee80211_crypt_null);
|
||||
if (ret < 0) {
|
||||
kfree(hcrypt);
|
||||
hcrypt = NULL;
|
||||
}
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ieee80211_crypto_deinit(void)
|
||||
{
|
||||
struct list_head *ptr, *n;
|
||||
struct ieee80211_crypto_alg *alg = NULL;
|
||||
|
||||
if (hcrypt == NULL)
|
||||
return;
|
||||
|
||||
list_for_each_safe(ptr, n, &hcrypt->algs) {
|
||||
alg = list_entry(ptr, struct ieee80211_crypto_alg, list);
|
||||
if (alg) {
|
||||
list_del(ptr);
|
||||
printk(KERN_DEBUG
|
||||
"ieee80211_crypt: unregistered algorithm '%s' (deinit)\n",
|
||||
alg->ops->name);
|
||||
kfree(alg);
|
||||
}
|
||||
}
|
||||
kfree(hcrypt);
|
||||
}
|
|
@ -1,86 +0,0 @@
|
|||
/*
|
||||
* Original code based on Host AP (software wireless LAN access point) driver
|
||||
* for Intersil Prism2/2.5/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>
|
||||
*
|
||||
* Adaption to a generic IEEE 802.11 stack by James Ketrenos
|
||||
* <jketreno@linux.intel.com>
|
||||
*
|
||||
* Copyright (c) 2004, Intel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation. See README and COPYING for
|
||||
* more details.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file defines the interface to the ieee80211 crypto module.
|
||||
*/
|
||||
#ifndef IEEE80211_CRYPT_H
|
||||
#define IEEE80211_CRYPT_H
|
||||
|
||||
#include <linux/skbuff.h>
|
||||
|
||||
struct ieee80211_crypto_ops {
|
||||
const char *name;
|
||||
|
||||
/* init new crypto context (e.g., allocate private data space,
|
||||
* select IV, etc.); returns NULL on failure or pointer to allocated
|
||||
* private data on success */
|
||||
void * (*init)(int keyidx);
|
||||
|
||||
/* deinitialize crypto context and free allocated private data */
|
||||
void (*deinit)(void *priv);
|
||||
|
||||
/* encrypt/decrypt return < 0 on error or >= 0 on success. The return
|
||||
* value from decrypt_mpdu is passed as the keyidx value for
|
||||
* decrypt_msdu. skb must have enough head and tail room for the
|
||||
* encryption; if not, error will be returned; these functions are
|
||||
* called for all MPDUs (i.e., fragments).
|
||||
*/
|
||||
int (*encrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
|
||||
int (*decrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
|
||||
|
||||
/* These functions are called for full MSDUs, i.e. full frames.
|
||||
* 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, struct ieee80211_device* ieee);
|
||||
|
||||
int (*set_key)(void *key, int len, u8 *seq, void *priv);
|
||||
int (*get_key)(void *key, int len, u8 *seq, void *priv);
|
||||
|
||||
/* procfs handler for printing out key information and possible
|
||||
* statistics */
|
||||
char * (*print_stats)(char *p, void *priv);
|
||||
|
||||
/* maximum number of bytes added by encryption; encrypt buf is
|
||||
* allocated with extra_prefix_len bytes, copy of in_buf, and
|
||||
* extra_postfix_len; encrypt need not use all this space, but
|
||||
* the result must start at the beginning of the buffer and correct
|
||||
* length must be returned */
|
||||
int extra_prefix_len, extra_postfix_len;
|
||||
|
||||
struct module *owner;
|
||||
};
|
||||
|
||||
struct ieee80211_crypt_data {
|
||||
struct list_head list; /* delayed deletion list */
|
||||
struct ieee80211_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);
|
||||
|
||||
#endif
|
|
@ -1,471 +0,0 @@
|
|||
/*
|
||||
* Host AP crypt: host-based CCMP encryption implementation for Host AP driver
|
||||
*
|
||||
* Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation. See README and COPYING for
|
||||
* 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 <linux/netdevice.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/if_arp.h>
|
||||
#include <asm/string.h>
|
||||
#include <linux/wireless.h>
|
||||
|
||||
#include "ieee80211.h"
|
||||
|
||||
#include <linux/crypto.h>
|
||||
#include <linux/scatterlist.h>
|
||||
|
||||
MODULE_AUTHOR("Jouni Malinen");
|
||||
MODULE_DESCRIPTION("Host AP crypt: CCMP");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
#define AES_BLOCK_LEN 16
|
||||
#define CCMP_HDR_LEN 8
|
||||
#define CCMP_MIC_LEN 8
|
||||
#define CCMP_TK_LEN 16
|
||||
#define CCMP_PN_LEN 6
|
||||
|
||||
struct ieee80211_ccmp_data {
|
||||
u8 key[CCMP_TK_LEN];
|
||||
int key_set;
|
||||
|
||||
u8 tx_pn[CCMP_PN_LEN];
|
||||
u8 rx_pn[CCMP_PN_LEN];
|
||||
|
||||
u32 dot11RSNAStatsCCMPFormatErrors;
|
||||
u32 dot11RSNAStatsCCMPReplays;
|
||||
u32 dot11RSNAStatsCCMPDecryptErrors;
|
||||
|
||||
int key_idx;
|
||||
|
||||
struct crypto_tfm *tfm;
|
||||
|
||||
/* scratch buffers for virt_to_page() (crypto API) */
|
||||
u8 tx_b0[AES_BLOCK_LEN], tx_b[AES_BLOCK_LEN],
|
||||
tx_e[AES_BLOCK_LEN], tx_s0[AES_BLOCK_LEN];
|
||||
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,
|
||||
const u8 pt[16], u8 ct[16])
|
||||
{
|
||||
crypto_cipher_encrypt_one((void*)tfm, ct, pt);
|
||||
}
|
||||
|
||||
static void * ieee80211_ccmp_init(int key_idx)
|
||||
{
|
||||
struct ieee80211_ccmp_data *priv;
|
||||
|
||||
priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
|
||||
if (priv == NULL)
|
||||
goto fail;
|
||||
priv->key_idx = key_idx;
|
||||
|
||||
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 "
|
||||
"crypto API aes\n");
|
||||
priv->tfm = NULL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return priv;
|
||||
|
||||
fail:
|
||||
if (priv) {
|
||||
if (priv->tfm)
|
||||
crypto_free_cipher((void*)priv->tfm);
|
||||
kfree(priv);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void ieee80211_ccmp_deinit(void *priv)
|
||||
{
|
||||
struct ieee80211_ccmp_data *_priv = priv;
|
||||
|
||||
if (_priv && _priv->tfm)
|
||||
crypto_free_cipher((void*)_priv->tfm);
|
||||
kfree(priv);
|
||||
}
|
||||
|
||||
|
||||
static inline void xor_block(u8 *b, u8 *a, size_t len)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < len; i++)
|
||||
b[i] ^= a[i];
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void ccmp_init_blocks(struct crypto_tfm *tfm,
|
||||
struct ieee80211_hdr_4addr *hdr,
|
||||
u8 *pn, size_t dlen, u8 *b0, u8 *auth,
|
||||
u8 *s0)
|
||||
{
|
||||
u8 *pos, qc = 0;
|
||||
size_t aad_len;
|
||||
u16 fc;
|
||||
int a4_included, qc_included;
|
||||
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));
|
||||
/*
|
||||
qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
|
||||
(WLAN_FC_GET_STYPE(fc) & 0x08));
|
||||
*/
|
||||
qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
|
||||
(WLAN_FC_GET_STYPE(fc) & 0x80));
|
||||
aad_len = 22;
|
||||
if (a4_included)
|
||||
aad_len += 6;
|
||||
if (qc_included) {
|
||||
pos = (u8 *) &hdr->addr4;
|
||||
if (a4_included)
|
||||
pos += 6;
|
||||
qc = *pos & 0x0f;
|
||||
aad_len += 2;
|
||||
}
|
||||
/* CCM Initial Block:
|
||||
* Flag (Include authentication header, M=3 (8-octet MIC),
|
||||
* L=1 (2-octet Dlen))
|
||||
* Nonce: 0x00 | A2 | PN
|
||||
* Dlen */
|
||||
b0[0] = 0x59;
|
||||
b0[1] = qc;
|
||||
memcpy(b0 + 2, hdr->addr2, ETH_ALEN);
|
||||
memcpy(b0 + 8, pn, CCMP_PN_LEN);
|
||||
b0[14] = (dlen >> 8) & 0xff;
|
||||
b0[15] = dlen & 0xff;
|
||||
|
||||
/* AAD:
|
||||
* FC with bits 4..6 and 11..13 masked to zero; 14 is always one
|
||||
* A1 | A2 | A3
|
||||
* SC with bits 4..15 (seq#) masked to zero
|
||||
* A4 (if present)
|
||||
* QC (if present)
|
||||
*/
|
||||
pos = (u8 *) hdr;
|
||||
aad[0] = 0; /* aad_len >> 8 */
|
||||
aad[1] = aad_len & 0xff;
|
||||
aad[2] = pos[0] & 0x8f;
|
||||
aad[3] = pos[1] & 0xc7;
|
||||
memcpy(aad + 4, hdr->addr1, 3 * ETH_ALEN);
|
||||
pos = (u8 *) &hdr->seq_ctl;
|
||||
aad[22] = pos[0] & 0x0f;
|
||||
aad[23] = 0; /* all bits masked */
|
||||
memset(aad + 24, 0, 8);
|
||||
if (a4_included)
|
||||
memcpy(aad + 24, hdr->addr4, ETH_ALEN);
|
||||
if (qc_included) {
|
||||
aad[a4_included ? 30 : 24] = qc;
|
||||
/* rest of QC masked */
|
||||
}
|
||||
|
||||
/* Start with the first block and AAD */
|
||||
ieee80211_ccmp_aes_encrypt(tfm, b0, auth);
|
||||
xor_block(auth, aad, AES_BLOCK_LEN);
|
||||
ieee80211_ccmp_aes_encrypt(tfm, auth, auth);
|
||||
xor_block(auth, &aad[AES_BLOCK_LEN], AES_BLOCK_LEN);
|
||||
ieee80211_ccmp_aes_encrypt(tfm, auth, auth);
|
||||
b0[0] &= 0x07;
|
||||
b0[14] = b0[15] = 0;
|
||||
ieee80211_ccmp_aes_encrypt(tfm, b0, s0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
||||
{
|
||||
struct ieee80211_ccmp_data *key = priv;
|
||||
int data_len, i;
|
||||
u8 *pos;
|
||||
struct ieee80211_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)
|
||||
return -1;
|
||||
|
||||
data_len = skb->len - hdr_len;
|
||||
pos = skb_push(skb, CCMP_HDR_LEN);
|
||||
memmove(pos, pos + CCMP_HDR_LEN, hdr_len);
|
||||
pos += hdr_len;
|
||||
|
||||
i = CCMP_PN_LEN - 1;
|
||||
while (i >= 0) {
|
||||
key->tx_pn[i]++;
|
||||
if (key->tx_pn[i] != 0)
|
||||
break;
|
||||
i--;
|
||||
}
|
||||
|
||||
*pos++ = key->tx_pn[5];
|
||||
*pos++ = key->tx_pn[4];
|
||||
*pos++ = 0;
|
||||
*pos++ = (key->key_idx << 6) | (1 << 5) /* Ext IV included */;
|
||||
*pos++ = key->tx_pn[3];
|
||||
*pos++ = key->tx_pn[2];
|
||||
*pos++ = key->tx_pn[1];
|
||||
*pos++ = key->tx_pn[0];
|
||||
|
||||
|
||||
hdr = (struct ieee80211_hdr_4addr *) skb->data;
|
||||
if (!tcb_desc->bHwSec)
|
||||
{
|
||||
int blocks, last, len;
|
||||
u8 *mic;
|
||||
u8 *b0 = key->tx_b0;
|
||||
u8 *b = key->tx_b;
|
||||
u8 *e = key->tx_e;
|
||||
u8 *s0 = key->tx_s0;
|
||||
|
||||
mic = skb_put(skb, CCMP_MIC_LEN);
|
||||
|
||||
ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0);
|
||||
|
||||
blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
|
||||
last = data_len % AES_BLOCK_LEN;
|
||||
|
||||
for (i = 1; i <= blocks; i++) {
|
||||
len = (i == blocks && last) ? last : AES_BLOCK_LEN;
|
||||
/* Authentication */
|
||||
xor_block(b, pos, len);
|
||||
ieee80211_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);
|
||||
xor_block(pos, e, len);
|
||||
pos += len;
|
||||
}
|
||||
|
||||
for (i = 0; i < CCMP_MIC_LEN; i++)
|
||||
mic[i] = b[i] ^ s0[i];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
||||
{
|
||||
struct ieee80211_ccmp_data *key = priv;
|
||||
u8 keyidx, *pos;
|
||||
struct ieee80211_hdr_4addr *hdr;
|
||||
cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
|
||||
u8 pn[6];
|
||||
|
||||
if (skb->len < hdr_len + CCMP_HDR_LEN + CCMP_MIC_LEN) {
|
||||
key->dot11RSNAStatsCCMPFormatErrors++;
|
||||
return -1;
|
||||
}
|
||||
|
||||
hdr = (struct ieee80211_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);
|
||||
}
|
||||
key->dot11RSNAStatsCCMPFormatErrors++;
|
||||
return -2;
|
||||
}
|
||||
keyidx >>= 6;
|
||||
if (key->key_idx != keyidx) {
|
||||
printk(KERN_DEBUG "CCMP: RX tkey->key_idx=%d frame "
|
||||
"keyidx=%d priv=%p\n", key->key_idx, keyidx, priv);
|
||||
return -6;
|
||||
}
|
||||
if (!key->key_set) {
|
||||
if (net_ratelimit()) {
|
||||
printk(KERN_DEBUG "CCMP: received packet from %pM"
|
||||
" with keyid=%d that does not have a configured"
|
||||
" key\n", hdr->addr2, keyidx);
|
||||
}
|
||||
return -3;
|
||||
}
|
||||
|
||||
pn[0] = pos[7];
|
||||
pn[1] = pos[6];
|
||||
pn[2] = pos[5];
|
||||
pn[3] = pos[4];
|
||||
pn[4] = pos[1];
|
||||
pn[5] = pos[0];
|
||||
pos += 8;
|
||||
|
||||
if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) {
|
||||
if (net_ratelimit()) {
|
||||
printk(KERN_DEBUG "CCMP: replay detected: STA=%pM"
|
||||
" previous PN %pm received PN %pm\n",
|
||||
hdr->addr2, key->rx_pn, pn);
|
||||
}
|
||||
key->dot11RSNAStatsCCMPReplays++;
|
||||
return -4;
|
||||
}
|
||||
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;
|
||||
u8 *b = key->rx_b;
|
||||
u8 *a = key->rx_a;
|
||||
int i, blocks, last, len;
|
||||
|
||||
|
||||
ccmp_init_blocks(key->tfm, hdr, pn, data_len, b0, a, b);
|
||||
xor_block(mic, b, CCMP_MIC_LEN);
|
||||
|
||||
blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
|
||||
last = data_len % AES_BLOCK_LEN;
|
||||
|
||||
for (i = 1; i <= blocks; i++) {
|
||||
len = (i == blocks && last) ? last : AES_BLOCK_LEN;
|
||||
/* Decrypt, with counter */
|
||||
b0[14] = (i >> 8) & 0xff;
|
||||
b0[15] = i & 0xff;
|
||||
ieee80211_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);
|
||||
pos += len;
|
||||
}
|
||||
|
||||
if (memcmp(mic, a, CCMP_MIC_LEN) != 0) {
|
||||
if (net_ratelimit()) {
|
||||
printk(KERN_DEBUG "CCMP: decrypt failed: STA="
|
||||
"%pM\n", hdr->addr2);
|
||||
}
|
||||
key->dot11RSNAStatsCCMPDecryptErrors++;
|
||||
return -5;
|
||||
}
|
||||
|
||||
memcpy(key->rx_pn, pn, CCMP_PN_LEN);
|
||||
}
|
||||
/* Remove hdr and MIC */
|
||||
memmove(skb->data + CCMP_HDR_LEN, skb->data, hdr_len);
|
||||
skb_pull(skb, CCMP_HDR_LEN);
|
||||
skb_trim(skb, skb->len - CCMP_MIC_LEN);
|
||||
|
||||
return keyidx;
|
||||
}
|
||||
|
||||
|
||||
static int ieee80211_ccmp_set_key(void *key, int len, u8 *seq, void *priv)
|
||||
{
|
||||
struct ieee80211_ccmp_data *data = priv;
|
||||
int keyidx;
|
||||
struct crypto_tfm *tfm = data->tfm;
|
||||
|
||||
keyidx = data->key_idx;
|
||||
memset(data, 0, sizeof(*data));
|
||||
data->key_idx = keyidx;
|
||||
data->tfm = tfm;
|
||||
if (len == CCMP_TK_LEN) {
|
||||
memcpy(data->key, key, CCMP_TK_LEN);
|
||||
data->key_set = 1;
|
||||
if (seq) {
|
||||
data->rx_pn[0] = seq[5];
|
||||
data->rx_pn[1] = seq[4];
|
||||
data->rx_pn[2] = seq[3];
|
||||
data->rx_pn[3] = seq[2];
|
||||
data->rx_pn[4] = seq[1];
|
||||
data->rx_pn[5] = seq[0];
|
||||
}
|
||||
crypto_cipher_setkey((void*)data->tfm, data->key, CCMP_TK_LEN);
|
||||
} else if (len == 0)
|
||||
data->key_set = 0;
|
||||
else
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int ieee80211_ccmp_get_key(void *key, int len, u8 *seq, void *priv)
|
||||
{
|
||||
struct ieee80211_ccmp_data *data = priv;
|
||||
|
||||
if (len < CCMP_TK_LEN)
|
||||
return -1;
|
||||
|
||||
if (!data->key_set)
|
||||
return 0;
|
||||
memcpy(key, data->key, CCMP_TK_LEN);
|
||||
|
||||
if (seq) {
|
||||
seq[0] = data->tx_pn[5];
|
||||
seq[1] = data->tx_pn[4];
|
||||
seq[2] = data->tx_pn[3];
|
||||
seq[3] = data->tx_pn[2];
|
||||
seq[4] = data->tx_pn[1];
|
||||
seq[5] = data->tx_pn[0];
|
||||
}
|
||||
|
||||
return CCMP_TK_LEN;
|
||||
}
|
||||
|
||||
|
||||
static char * ieee80211_ccmp_print_stats(char *p, void *priv)
|
||||
{
|
||||
struct ieee80211_ccmp_data *ccmp = priv;
|
||||
p += sprintf(p, "key[%d] alg=CCMP key_set=%d "
|
||||
"tx_pn=%pm rx_pn=%pm "
|
||||
"format_errors=%d replays=%d decrypt_errors=%d\n",
|
||||
ccmp->key_idx, ccmp->key_set,
|
||||
ccmp->tx_pn, ccmp->rx_pn,
|
||||
ccmp->dot11RSNAStatsCCMPFormatErrors,
|
||||
ccmp->dot11RSNAStatsCCMPReplays,
|
||||
ccmp->dot11RSNAStatsCCMPDecryptErrors);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void ieee80211_ccmp_null(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = {
|
||||
.name = "CCMP",
|
||||
.init = ieee80211_ccmp_init,
|
||||
.deinit = ieee80211_ccmp_deinit,
|
||||
.encrypt_mpdu = ieee80211_ccmp_encrypt,
|
||||
.decrypt_mpdu = ieee80211_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,
|
||||
.extra_prefix_len = CCMP_HDR_LEN,
|
||||
.extra_postfix_len = CCMP_MIC_LEN,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
int __init ieee80211_crypto_ccmp_init(void)
|
||||
{
|
||||
return ieee80211_register_crypto_ops(&ieee80211_crypt_ccmp);
|
||||
}
|
||||
|
||||
void ieee80211_crypto_ccmp_exit(void)
|
||||
{
|
||||
ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp);
|
||||
}
|
|
@ -1,776 +0,0 @@
|
|||
/*
|
||||
* Host AP crypt: host-based TKIP encryption implementation for Host AP driver
|
||||
*
|
||||
* Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation. See README and COPYING for
|
||||
* 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 <linux/netdevice.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/if_arp.h>
|
||||
#include <asm/string.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: TKIP");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
struct ieee80211_tkip_data {
|
||||
#define TKIP_KEY_LEN 32
|
||||
u8 key[TKIP_KEY_LEN];
|
||||
int key_set;
|
||||
|
||||
u32 tx_iv32;
|
||||
u16 tx_iv16;
|
||||
u16 tx_ttak[5];
|
||||
int tx_phase1_done;
|
||||
|
||||
u32 rx_iv32;
|
||||
u16 rx_iv16;
|
||||
bool initialized;
|
||||
u16 rx_ttak[5];
|
||||
int rx_phase1_done;
|
||||
u32 rx_iv32_new;
|
||||
u16 rx_iv16_new;
|
||||
|
||||
u32 dot11RSNAStatsTKIPReplays;
|
||||
u32 dot11RSNAStatsTKIPICVErrors;
|
||||
u32 dot11RSNAStatsTKIPLocalMICFailures;
|
||||
|
||||
int key_idx;
|
||||
|
||||
struct crypto_blkcipher *rx_tfm_arc4;
|
||||
struct crypto_hash *rx_tfm_michael;
|
||||
struct crypto_blkcipher *tx_tfm_arc4;
|
||||
struct crypto_hash *tx_tfm_michael;
|
||||
|
||||
/* scratch buffers for virt_to_page() (crypto API) */
|
||||
u8 rx_hdr[16], tx_hdr[16];
|
||||
};
|
||||
|
||||
static void * ieee80211_tkip_init(int key_idx)
|
||||
{
|
||||
struct ieee80211_tkip_data *priv;
|
||||
|
||||
priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
|
||||
if (priv == NULL)
|
||||
goto fail;
|
||||
priv->key_idx = key_idx;
|
||||
|
||||
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 "
|
||||
"crypto API arc4\n");
|
||||
priv->tx_tfm_arc4 = NULL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
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 "
|
||||
"crypto API michael_mic\n");
|
||||
priv->tx_tfm_michael = NULL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
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 "
|
||||
"crypto API arc4\n");
|
||||
priv->rx_tfm_arc4 = NULL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
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 "
|
||||
"crypto API michael_mic\n");
|
||||
priv->rx_tfm_michael = NULL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return priv;
|
||||
|
||||
fail:
|
||||
if (priv) {
|
||||
if (priv->tx_tfm_michael)
|
||||
crypto_free_hash(priv->tx_tfm_michael);
|
||||
if (priv->tx_tfm_arc4)
|
||||
crypto_free_blkcipher(priv->tx_tfm_arc4);
|
||||
if (priv->rx_tfm_michael)
|
||||
crypto_free_hash(priv->rx_tfm_michael);
|
||||
if (priv->rx_tfm_arc4)
|
||||
crypto_free_blkcipher(priv->rx_tfm_arc4);
|
||||
kfree(priv);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void ieee80211_tkip_deinit(void *priv)
|
||||
{
|
||||
struct ieee80211_tkip_data *_priv = priv;
|
||||
|
||||
if (_priv) {
|
||||
if (_priv->tx_tfm_michael)
|
||||
crypto_free_hash(_priv->tx_tfm_michael);
|
||||
if (_priv->tx_tfm_arc4)
|
||||
crypto_free_blkcipher(_priv->tx_tfm_arc4);
|
||||
if (_priv->rx_tfm_michael)
|
||||
crypto_free_hash(_priv->rx_tfm_michael);
|
||||
if (_priv->rx_tfm_arc4)
|
||||
crypto_free_blkcipher(_priv->rx_tfm_arc4);
|
||||
}
|
||||
kfree(priv);
|
||||
}
|
||||
|
||||
|
||||
static inline u16 RotR1(u16 val)
|
||||
{
|
||||
return (val >> 1) | (val << 15);
|
||||
}
|
||||
|
||||
|
||||
static inline u8 Lo8(u16 val)
|
||||
{
|
||||
return val & 0xff;
|
||||
}
|
||||
|
||||
|
||||
static inline u8 Hi8(u16 val)
|
||||
{
|
||||
return val >> 8;
|
||||
}
|
||||
|
||||
|
||||
static inline u16 Lo16(u32 val)
|
||||
{
|
||||
return val & 0xffff;
|
||||
}
|
||||
|
||||
|
||||
static inline u16 Hi16(u32 val)
|
||||
{
|
||||
return val >> 16;
|
||||
}
|
||||
|
||||
|
||||
static inline u16 Mk16(u8 hi, u8 lo)
|
||||
{
|
||||
return lo | (((u16) hi) << 8);
|
||||
}
|
||||
|
||||
|
||||
static inline u16 Mk16_le(u16 *v)
|
||||
{
|
||||
return le16_to_cpu(*v);
|
||||
}
|
||||
|
||||
|
||||
static const u16 Sbox[256] =
|
||||
{
|
||||
0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
|
||||
0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
|
||||
0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
|
||||
0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
|
||||
0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
|
||||
0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
|
||||
0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
|
||||
0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
|
||||
0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
|
||||
0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
|
||||
0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
|
||||
0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
|
||||
0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
|
||||
0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
|
||||
0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
|
||||
0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
|
||||
0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
|
||||
0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
|
||||
0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
|
||||
0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
|
||||
0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
|
||||
0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
|
||||
0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
|
||||
0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
|
||||
0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
|
||||
0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
|
||||
0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
|
||||
0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
|
||||
0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
|
||||
0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
|
||||
0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
|
||||
0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
|
||||
};
|
||||
|
||||
|
||||
static inline u16 _S_(u16 v)
|
||||
{
|
||||
u16 t = Sbox[Hi8(v)];
|
||||
return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
|
||||
}
|
||||
|
||||
|
||||
#define PHASE1_LOOP_COUNT 8
|
||||
|
||||
|
||||
static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
/* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */
|
||||
TTAK[0] = Lo16(IV32);
|
||||
TTAK[1] = Hi16(IV32);
|
||||
TTAK[2] = Mk16(TA[1], TA[0]);
|
||||
TTAK[3] = Mk16(TA[3], TA[2]);
|
||||
TTAK[4] = Mk16(TA[5], TA[4]);
|
||||
|
||||
for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
|
||||
j = 2 * (i & 1);
|
||||
TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j]));
|
||||
TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j]));
|
||||
TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j]));
|
||||
TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j]));
|
||||
TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK,
|
||||
u16 IV16)
|
||||
{
|
||||
/* Make temporary area overlap WEP seed so that the final copy can be
|
||||
* avoided on little endian hosts. */
|
||||
u16 *PPK = (u16 *) &WEPSeed[4];
|
||||
|
||||
/* Step 1 - make copy of TTAK and bring in TSC */
|
||||
PPK[0] = TTAK[0];
|
||||
PPK[1] = TTAK[1];
|
||||
PPK[2] = TTAK[2];
|
||||
PPK[3] = TTAK[3];
|
||||
PPK[4] = TTAK[4];
|
||||
PPK[5] = TTAK[4] + IV16;
|
||||
|
||||
/* Step 2 - 96-bit bijective mixing using S-box */
|
||||
PPK[0] += _S_(PPK[5] ^ Mk16_le((u16 *) &TK[0]));
|
||||
PPK[1] += _S_(PPK[0] ^ Mk16_le((u16 *) &TK[2]));
|
||||
PPK[2] += _S_(PPK[1] ^ Mk16_le((u16 *) &TK[4]));
|
||||
PPK[3] += _S_(PPK[2] ^ Mk16_le((u16 *) &TK[6]));
|
||||
PPK[4] += _S_(PPK[3] ^ Mk16_le((u16 *) &TK[8]));
|
||||
PPK[5] += _S_(PPK[4] ^ Mk16_le((u16 *) &TK[10]));
|
||||
|
||||
PPK[0] += RotR1(PPK[5] ^ Mk16_le((u16 *) &TK[12]));
|
||||
PPK[1] += RotR1(PPK[0] ^ Mk16_le((u16 *) &TK[14]));
|
||||
PPK[2] += RotR1(PPK[1]);
|
||||
PPK[3] += RotR1(PPK[2]);
|
||||
PPK[4] += RotR1(PPK[3]);
|
||||
PPK[5] += RotR1(PPK[4]);
|
||||
|
||||
/* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value
|
||||
* WEPSeed[0..2] is transmitted as WEP IV */
|
||||
WEPSeed[0] = Hi8(IV16);
|
||||
WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F;
|
||||
WEPSeed[2] = Lo8(IV16);
|
||||
WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((u16 *) &TK[0])) >> 1);
|
||||
|
||||
#ifdef __BIG_ENDIAN
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 6; i++)
|
||||
PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
||||
{
|
||||
struct ieee80211_tkip_data *tkey = priv;
|
||||
int len;
|
||||
u8 *pos;
|
||||
struct ieee80211_hdr_4addr *hdr;
|
||||
cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
|
||||
struct blkcipher_desc desc = { .tfm = tkey->tx_tfm_arc4 };
|
||||
int ret = 0;
|
||||
u8 rc4key[16], *icv;
|
||||
u32 crc;
|
||||
struct scatterlist sg;
|
||||
|
||||
if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 ||
|
||||
skb->len < hdr_len)
|
||||
return -1;
|
||||
|
||||
hdr = (struct ieee80211_hdr_4addr *) skb->data;
|
||||
|
||||
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
|
||||
tkey->tx_phase1_done = 1;
|
||||
|
||||
|
||||
len = skb->len - hdr_len;
|
||||
pos = skb_push(skb, 8);
|
||||
memmove(pos, pos + 8, hdr_len);
|
||||
pos += hdr_len;
|
||||
|
||||
if (tcb_desc->bHwSec)
|
||||
{
|
||||
*pos++ = Hi8(tkey->tx_iv16);
|
||||
*pos++ = (Hi8(tkey->tx_iv16) | 0x20) & 0x7F;
|
||||
*pos++ = Lo8(tkey->tx_iv16);
|
||||
}
|
||||
else
|
||||
{
|
||||
*pos++ = rc4key[0];
|
||||
*pos++ = rc4key[1];
|
||||
*pos++ = rc4key[2];
|
||||
}
|
||||
|
||||
*pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */;
|
||||
*pos++ = tkey->tx_iv32 & 0xff;
|
||||
*pos++ = (tkey->tx_iv32 >> 8) & 0xff;
|
||||
*pos++ = (tkey->tx_iv32 >> 16) & 0xff;
|
||||
*pos++ = (tkey->tx_iv32 >> 24) & 0xff;
|
||||
|
||||
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);
|
||||
sg_init_one(&sg, pos, len + 4);
|
||||
ret= crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
|
||||
}
|
||||
|
||||
tkey->tx_iv16++;
|
||||
if (tkey->tx_iv16 == 0) {
|
||||
tkey->tx_phase1_done = 0;
|
||||
tkey->tx_iv32++;
|
||||
}
|
||||
|
||||
if (!tcb_desc->bHwSec)
|
||||
return ret;
|
||||
else
|
||||
return 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
||||
{
|
||||
struct ieee80211_tkip_data *tkey = priv;
|
||||
u8 keyidx, *pos;
|
||||
u32 iv32;
|
||||
u16 iv16;
|
||||
struct ieee80211_hdr_4addr *hdr;
|
||||
cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
|
||||
struct blkcipher_desc desc = { .tfm = tkey->rx_tfm_arc4 };
|
||||
u8 rc4key[16];
|
||||
u8 icv[4];
|
||||
u32 crc;
|
||||
struct scatterlist sg;
|
||||
int plen;
|
||||
if (skb->len < hdr_len + 8 + 4)
|
||||
return -1;
|
||||
|
||||
hdr = (struct ieee80211_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);
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
keyidx >>= 6;
|
||||
if (tkey->key_idx != keyidx) {
|
||||
printk(KERN_DEBUG "TKIP: RX tkey->key_idx=%d frame "
|
||||
"keyidx=%d priv=%p\n", tkey->key_idx, keyidx, priv);
|
||||
return -6;
|
||||
}
|
||||
if (!tkey->key_set) {
|
||||
if (net_ratelimit()) {
|
||||
printk(KERN_DEBUG "TKIP: received packet from %pM"
|
||||
" with keyid=%d that does not have a configured"
|
||||
" key\n", hdr->addr2, keyidx);
|
||||
}
|
||||
return -3;
|
||||
}
|
||||
iv16 = (pos[0] << 8) | pos[2];
|
||||
iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24);
|
||||
pos += 8;
|
||||
|
||||
if (!tcb_desc->bHwSec)
|
||||
{
|
||||
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"
|
||||
" previous TSC %08x%04x received TSC "
|
||||
"%08x%04x\n", 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);
|
||||
tkey->rx_phase1_done = 1;
|
||||
}
|
||||
tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16);
|
||||
|
||||
plen = skb->len - hdr_len - 12;
|
||||
sg_init_one(&sg, pos, plen+4);
|
||||
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);
|
||||
}
|
||||
return -7;
|
||||
}
|
||||
|
||||
crc = ~crc32_le(~0, pos, plen);
|
||||
icv[0] = crc;
|
||||
icv[1] = crc >> 8;
|
||||
icv[2] = crc >> 16;
|
||||
icv[3] = crc >> 24;
|
||||
|
||||
if (memcmp(icv, pos + plen, 4) != 0) {
|
||||
if (iv32 != tkey->rx_iv32) {
|
||||
/* Previously cached Phase1 result was already lost, so
|
||||
* it needs to be recalculated for the next packet. */
|
||||
tkey->rx_phase1_done = 0;
|
||||
}
|
||||
if (net_ratelimit()) {
|
||||
printk(KERN_DEBUG "TKIP: ICV error detected: STA="
|
||||
"%pM\n", hdr->addr2);
|
||||
}
|
||||
tkey->dot11RSNAStatsTKIPICVErrors++;
|
||||
return -5;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Update real counters only after Michael MIC verification has
|
||||
* completed */
|
||||
tkey->rx_iv32_new = iv32;
|
||||
tkey->rx_iv16_new = iv16;
|
||||
|
||||
/* Remove IV and ICV */
|
||||
memmove(skb->data + 8, skb->data, hdr_len);
|
||||
skb_pull(skb, 8);
|
||||
skb_trim(skb, skb->len - 4);
|
||||
|
||||
return keyidx;
|
||||
}
|
||||
|
||||
static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
|
||||
u8 * data, size_t data_len, u8 * mic)
|
||||
{
|
||||
struct hash_desc desc;
|
||||
struct scatterlist sg[2];
|
||||
|
||||
if (tfm_michael == NULL) {
|
||||
printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
sg_init_table(sg, 2);
|
||||
sg_set_buf(&sg[0], hdr, 16);
|
||||
sg_set_buf(&sg[1], data, data_len);
|
||||
|
||||
if (crypto_hash_setkey(tfm_michael, key, 8))
|
||||
return -1;
|
||||
|
||||
desc.tfm = tfm_michael;
|
||||
desc.flags = 0;
|
||||
return crypto_hash_digest(&desc, sg, data_len + 16, mic);
|
||||
}
|
||||
|
||||
static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr)
|
||||
{
|
||||
struct ieee80211_hdr_4addr *hdr11;
|
||||
|
||||
hdr11 = (struct ieee80211_hdr_4addr *) skb->data;
|
||||
switch (le16_to_cpu(hdr11->frame_ctl) &
|
||||
(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
|
||||
case IEEE80211_FCTL_TODS:
|
||||
memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
|
||||
memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
|
||||
break;
|
||||
case IEEE80211_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:
|
||||
memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
|
||||
memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */
|
||||
break;
|
||||
case 0:
|
||||
memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
|
||||
memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
|
||||
break;
|
||||
}
|
||||
|
||||
hdr[12] = 0; /* priority */
|
||||
|
||||
hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
|
||||
}
|
||||
|
||||
|
||||
static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv)
|
||||
{
|
||||
struct ieee80211_tkip_data *tkey = priv;
|
||||
u8 *pos;
|
||||
struct ieee80211_hdr_4addr *hdr;
|
||||
|
||||
hdr = (struct ieee80211_hdr_4addr *) skb->data;
|
||||
|
||||
if (skb_tailroom(skb) < 8 || skb->len < hdr_len) {
|
||||
printk(KERN_DEBUG "Invalid packet for Michael MIC add "
|
||||
"(tailroom=%d hdr_len=%d skb->len=%d)\n",
|
||||
skb_tailroom(skb), hdr_len, skb->len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
michael_mic_hdr(skb, tkey->tx_hdr);
|
||||
|
||||
if(IEEE80211_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 (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
|
||||
skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ieee80211_michael_mic_failure(struct net_device *dev,
|
||||
struct ieee80211_hdr_4addr *hdr,
|
||||
int keyidx)
|
||||
{
|
||||
union iwreq_data wrqu;
|
||||
struct iw_michaelmicfailure ev;
|
||||
|
||||
/* TODO: needed parameters: count, keyid, key type, TSC */
|
||||
memset(&ev, 0, sizeof(ev));
|
||||
ev.flags = keyidx & IW_MICFAILURE_KEY_ID;
|
||||
if (hdr->addr1[0] & 0x01)
|
||||
ev.flags |= IW_MICFAILURE_GROUP;
|
||||
else
|
||||
ev.flags |= IW_MICFAILURE_PAIRWISE;
|
||||
ev.src_addr.sa_family = ARPHRD_ETHER;
|
||||
memcpy(ev.src_addr.sa_data, hdr->addr2, ETH_ALEN);
|
||||
memset(&wrqu, 0, sizeof(wrqu));
|
||||
wrqu.data.length = sizeof(ev);
|
||||
wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *) &ev);
|
||||
}
|
||||
|
||||
static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
|
||||
int hdr_len, void *priv, struct ieee80211_device* ieee)
|
||||
{
|
||||
struct ieee80211_tkip_data *tkey = priv;
|
||||
u8 mic[8];
|
||||
struct ieee80211_hdr_4addr *hdr;
|
||||
|
||||
hdr = (struct ieee80211_hdr_4addr *) skb->data;
|
||||
|
||||
if (!tkey->key_set)
|
||||
return -1;
|
||||
|
||||
michael_mic_hdr(skb, tkey->rx_hdr);
|
||||
if(IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) {
|
||||
tkey->rx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
|
||||
}
|
||||
|
||||
if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
|
||||
skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
|
||||
return -1;
|
||||
if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
|
||||
struct ieee80211_hdr_4addr *hdr;
|
||||
hdr = (struct ieee80211_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,
|
||||
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");
|
||||
ieee80211_michael_mic_failure(skb->dev, hdr, keyidx);
|
||||
}
|
||||
tkey->dot11RSNAStatsTKIPLocalMICFailures++;
|
||||
ieee->force_mic_error = false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Update TSC counters for RX now that the packet verification has
|
||||
* completed. */
|
||||
tkey->rx_iv32 = tkey->rx_iv32_new;
|
||||
tkey->rx_iv16 = tkey->rx_iv16_new;
|
||||
|
||||
skb_trim(skb, skb->len - 8);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int ieee80211_tkip_set_key(void *key, int len, u8 *seq, void *priv)
|
||||
{
|
||||
struct ieee80211_tkip_data *tkey = priv;
|
||||
int keyidx;
|
||||
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;
|
||||
|
||||
keyidx = tkey->key_idx;
|
||||
memset(tkey, 0, sizeof(*tkey));
|
||||
tkey->key_idx = keyidx;
|
||||
tkey->tx_tfm_michael = tfm;
|
||||
tkey->tx_tfm_arc4 = tfm2;
|
||||
tkey->rx_tfm_michael = tfm3;
|
||||
tkey->rx_tfm_arc4 = tfm4;
|
||||
|
||||
if (len == TKIP_KEY_LEN) {
|
||||
memcpy(tkey->key, key, TKIP_KEY_LEN);
|
||||
tkey->key_set = 1;
|
||||
tkey->tx_iv16 = 1; /* TSC is initialized to 1 */
|
||||
if (seq) {
|
||||
tkey->rx_iv32 = (seq[5] << 24) | (seq[4] << 16) |
|
||||
(seq[3] << 8) | seq[2];
|
||||
tkey->rx_iv16 = (seq[1] << 8) | seq[0];
|
||||
}
|
||||
} else if (len == 0)
|
||||
tkey->key_set = 0;
|
||||
else
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int ieee80211_tkip_get_key(void *key, int len, u8 *seq, void *priv)
|
||||
{
|
||||
struct ieee80211_tkip_data *tkey = priv;
|
||||
|
||||
if (len < TKIP_KEY_LEN)
|
||||
return -1;
|
||||
|
||||
if (!tkey->key_set)
|
||||
return 0;
|
||||
memcpy(key, tkey->key, TKIP_KEY_LEN);
|
||||
|
||||
if (seq) {
|
||||
/* Return the sequence number of the last transmitted frame. */
|
||||
u16 iv16 = tkey->tx_iv16;
|
||||
u32 iv32 = tkey->tx_iv32;
|
||||
if (iv16 == 0)
|
||||
iv32--;
|
||||
iv16--;
|
||||
seq[0] = tkey->tx_iv16;
|
||||
seq[1] = tkey->tx_iv16 >> 8;
|
||||
seq[2] = tkey->tx_iv32;
|
||||
seq[3] = tkey->tx_iv32 >> 8;
|
||||
seq[4] = tkey->tx_iv32 >> 16;
|
||||
seq[5] = tkey->tx_iv32 >> 24;
|
||||
}
|
||||
|
||||
return TKIP_KEY_LEN;
|
||||
}
|
||||
|
||||
|
||||
static char * ieee80211_tkip_print_stats(char *p, void *priv)
|
||||
{
|
||||
struct ieee80211_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 "
|
||||
"replays=%d icv_errors=%d local_mic_failures=%d\n",
|
||||
tkip->key_idx, tkip->key_set,
|
||||
(tkip->tx_iv32 >> 24) & 0xff,
|
||||
(tkip->tx_iv32 >> 16) & 0xff,
|
||||
(tkip->tx_iv32 >> 8) & 0xff,
|
||||
tkip->tx_iv32 & 0xff,
|
||||
(tkip->tx_iv16 >> 8) & 0xff,
|
||||
tkip->tx_iv16 & 0xff,
|
||||
(tkip->rx_iv32 >> 24) & 0xff,
|
||||
(tkip->rx_iv32 >> 16) & 0xff,
|
||||
(tkip->rx_iv32 >> 8) & 0xff,
|
||||
tkip->rx_iv32 & 0xff,
|
||||
(tkip->rx_iv16 >> 8) & 0xff,
|
||||
tkip->rx_iv16 & 0xff,
|
||||
tkip->dot11RSNAStatsTKIPReplays,
|
||||
tkip->dot11RSNAStatsTKIPICVErrors,
|
||||
tkip->dot11RSNAStatsTKIPLocalMICFailures);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
static struct ieee80211_crypto_ops ieee80211_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,
|
||||
.extra_prefix_len = 4 + 4, /* IV + ExtIV */
|
||||
.extra_postfix_len = 8 + 4, /* MIC + ICV */
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
int ieee80211_crypto_tkip_init(void)
|
||||
{
|
||||
return ieee80211_register_crypto_ops(&ieee80211_crypt_tkip);
|
||||
}
|
||||
|
||||
void ieee80211_crypto_tkip_exit(void)
|
||||
{
|
||||
ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip);
|
||||
}
|
||||
|
||||
void ieee80211_tkip_null(void)
|
||||
{
|
||||
return;
|
||||
}
|
|
@ -1,294 +0,0 @@
|
|||
/*
|
||||
* Host AP crypt: host-based WEP encryption implementation for Host AP driver
|
||||
*
|
||||
* Copyright (c) 2002-2004, Jouni Malinen <jkmaline@cc.hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation. See README and COPYING for
|
||||
* 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 "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");
|
||||
|
||||
struct prism2_wep_data {
|
||||
u32 iv;
|
||||
#define WEP_KEY_LEN 13
|
||||
u8 key[WEP_KEY_LEN + 1];
|
||||
u8 key_len;
|
||||
u8 key_idx;
|
||||
struct crypto_blkcipher *tx_tfm;
|
||||
struct crypto_blkcipher *rx_tfm;
|
||||
};
|
||||
|
||||
|
||||
static void * prism2_wep_init(int keyidx)
|
||||
{
|
||||
struct prism2_wep_data *priv;
|
||||
|
||||
priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
|
||||
if (priv == NULL)
|
||||
goto fail;
|
||||
priv->key_idx = keyidx;
|
||||
|
||||
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 "
|
||||
"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 "
|
||||
"crypto API arc4\n");
|
||||
priv->rx_tfm = NULL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* start WEP IV from a random value */
|
||||
get_random_bytes(&priv->iv, 4);
|
||||
|
||||
return priv;
|
||||
|
||||
fail:
|
||||
if (priv) {
|
||||
if (priv->tx_tfm)
|
||||
crypto_free_blkcipher(priv->tx_tfm);
|
||||
if (priv->rx_tfm)
|
||||
crypto_free_blkcipher(priv->rx_tfm);
|
||||
kfree(priv);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void prism2_wep_deinit(void *priv)
|
||||
{
|
||||
struct prism2_wep_data *_priv = priv;
|
||||
|
||||
if (_priv) {
|
||||
if (_priv->tx_tfm)
|
||||
crypto_free_blkcipher(_priv->tx_tfm);
|
||||
if (_priv->rx_tfm)
|
||||
crypto_free_blkcipher(_priv->rx_tfm);
|
||||
}
|
||||
kfree(priv);
|
||||
}
|
||||
|
||||
/* Perform WEP encryption on given skb that has at least 4 bytes of headroom
|
||||
* for IV and 4 bytes of tailroom for ICV. Both IV and ICV will be transmitted,
|
||||
* so the payload length increases with 8 bytes.
|
||||
*
|
||||
* WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data))
|
||||
*/
|
||||
static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
||||
{
|
||||
struct prism2_wep_data *wep = priv;
|
||||
u32 klen, len;
|
||||
u8 key[WEP_KEY_LEN + 3];
|
||||
u8 *pos;
|
||||
cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
|
||||
struct blkcipher_desc desc = { .tfm = wep->tx_tfm };
|
||||
u32 crc;
|
||||
u8 *icv;
|
||||
struct scatterlist sg;
|
||||
if (skb_headroom(skb) < 4 || skb_tailroom(skb) < 4 ||
|
||||
skb->len < hdr_len)
|
||||
return -1;
|
||||
|
||||
len = skb->len - hdr_len;
|
||||
pos = skb_push(skb, 4);
|
||||
memmove(pos, pos + 4, hdr_len);
|
||||
pos += hdr_len;
|
||||
|
||||
klen = 3 + wep->key_len;
|
||||
|
||||
wep->iv++;
|
||||
|
||||
/* Fluhrer, Mantin, and Shamir have reported weaknesses in the key
|
||||
* scheduling algorithm of RC4. At least IVs (KeyByte + 3, 0xff, N)
|
||||
* can be used to speedup attacks, so avoid using them. */
|
||||
if ((wep->iv & 0xff00) == 0xff00) {
|
||||
u8 B = (wep->iv >> 16) & 0xff;
|
||||
if (B >= 3 && B < klen)
|
||||
wep->iv += 0x0100;
|
||||
}
|
||||
|
||||
/* Prepend 24-bit IV to RC4 key and TX frame */
|
||||
*pos++ = key[0] = (wep->iv >> 16) & 0xff;
|
||||
*pos++ = key[1] = (wep->iv >> 8) & 0xff;
|
||||
*pos++ = key[2] = wep->iv & 0xff;
|
||||
*pos++ = wep->key_idx << 6;
|
||||
|
||||
/* Copy rest of the WEP key (the secret part) */
|
||||
memcpy(key + 3, wep->key, wep->key_len);
|
||||
|
||||
if (!tcb_desc->bHwSec)
|
||||
{
|
||||
|
||||
/* Append little-endian CRC32 and encrypt it to produce ICV */
|
||||
crc = ~crc32_le(~0, pos, len);
|
||||
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);
|
||||
sg_init_one(&sg, pos, len+4);
|
||||
|
||||
return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Perform WEP decryption on given buffer. Buffer includes whole WEP part of
|
||||
* the frame: IV (4 bytes), encrypted payload (including SNAP header),
|
||||
* ICV (4 bytes). len includes both IV and ICV.
|
||||
*
|
||||
* Returns 0 if frame was decrypted successfully and ICV was correct and -1 on
|
||||
* failure. If frame is OK, IV and ICV will be removed.
|
||||
*/
|
||||
static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
||||
{
|
||||
struct prism2_wep_data *wep = priv;
|
||||
u32 klen, plen;
|
||||
u8 key[WEP_KEY_LEN + 3];
|
||||
u8 keyidx, *pos;
|
||||
cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
|
||||
struct blkcipher_desc desc = { .tfm = wep->rx_tfm };
|
||||
u32 crc;
|
||||
u8 icv[4];
|
||||
struct scatterlist sg;
|
||||
if (skb->len < hdr_len + 8)
|
||||
return -1;
|
||||
|
||||
pos = skb->data + hdr_len;
|
||||
key[0] = *pos++;
|
||||
key[1] = *pos++;
|
||||
key[2] = *pos++;
|
||||
keyidx = *pos++ >> 6;
|
||||
if (keyidx != wep->key_idx)
|
||||
return -1;
|
||||
|
||||
klen = 3 + wep->key_len;
|
||||
|
||||
/* Copy rest of the WEP key (the secret part) */
|
||||
memcpy(key + 3, wep->key, wep->key_len);
|
||||
|
||||
/* Apply RC4 to data and compute CRC32 over decrypted data */
|
||||
plen = skb->len - hdr_len - 8;
|
||||
|
||||
if (!tcb_desc->bHwSec)
|
||||
{
|
||||
crypto_blkcipher_setkey(wep->rx_tfm, key, klen);
|
||||
sg_init_one(&sg, pos, plen + 4);
|
||||
|
||||
if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4))
|
||||
return -7;
|
||||
|
||||
crc = ~crc32_le(~0, pos, plen);
|
||||
icv[0] = crc;
|
||||
icv[1] = crc >> 8;
|
||||
icv[2] = crc >> 16;
|
||||
icv[3] = crc >> 24;
|
||||
if (memcmp(icv, pos + plen, 4) != 0) {
|
||||
/* ICV mismatch - drop frame */
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
/* Remove IV and ICV */
|
||||
memmove(skb->data + 4, skb->data, hdr_len);
|
||||
skb_pull(skb, 4);
|
||||
skb_trim(skb, skb->len - 4);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int prism2_wep_set_key(void *key, int len, u8 *seq, void *priv)
|
||||
{
|
||||
struct prism2_wep_data *wep = priv;
|
||||
|
||||
if (len < 0 || len > WEP_KEY_LEN)
|
||||
return -1;
|
||||
|
||||
memcpy(wep->key, key, len);
|
||||
wep->key_len = len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int prism2_wep_get_key(void *key, int len, u8 *seq, void *priv)
|
||||
{
|
||||
struct prism2_wep_data *wep = priv;
|
||||
|
||||
if (len < wep->key_len)
|
||||
return -1;
|
||||
|
||||
memcpy(key, wep->key, wep->key_len);
|
||||
|
||||
return wep->key_len;
|
||||
}
|
||||
|
||||
|
||||
static char * prism2_wep_print_stats(char *p, void *priv)
|
||||
{
|
||||
struct prism2_wep_data *wep = priv;
|
||||
p += sprintf(p, "key[%d] alg=WEP len=%d\n",
|
||||
wep->key_idx, wep->key_len);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
static struct ieee80211_crypto_ops ieee80211_crypt_wep = {
|
||||
.name = "WEP",
|
||||
.init = prism2_wep_init,
|
||||
.deinit = prism2_wep_deinit,
|
||||
.encrypt_mpdu = prism2_wep_encrypt,
|
||||
.decrypt_mpdu = prism2_wep_decrypt,
|
||||
.encrypt_msdu = NULL,
|
||||
.decrypt_msdu = NULL,
|
||||
.set_key = prism2_wep_set_key,
|
||||
.get_key = prism2_wep_get_key,
|
||||
.print_stats = prism2_wep_print_stats,
|
||||
.extra_prefix_len = 4, /* IV */
|
||||
.extra_postfix_len = 4, /* ICV */
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
int ieee80211_crypto_wep_init(void)
|
||||
{
|
||||
return ieee80211_register_crypto_ops(&ieee80211_crypt_wep);
|
||||
}
|
||||
|
||||
void ieee80211_crypto_wep_exit(void)
|
||||
{
|
||||
ieee80211_unregister_crypto_ops(&ieee80211_crypt_wep);
|
||||
}
|
||||
|
||||
void ieee80211_wep_null(void)
|
||||
{
|
||||
return;
|
||||
}
|
|
@ -1,301 +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/version.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);
|
||||
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_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;
|
||||
}
|
||||
|
||||
//These function were added to load crypte module autoly
|
||||
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;
|
||||
#if 1
|
||||
if (ieee->pHTInfo != NULL)
|
||||
{
|
||||
kfree(ieee->pHTInfo);
|
||||
ieee->pHTInfo = NULL;
|
||||
}
|
||||
#endif
|
||||
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_ERR //awayls open this flags 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_t(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
|
||||
ieee80211_debug_level = val;
|
||||
|
||||
return strnlen(buf, count);
|
||||
}
|
||||
|
||||
int ieee80211_debug_init(void)
|
||||
{
|
||||
struct proc_dir_entry *e;
|
||||
|
||||
ieee80211_debug_level = debug;
|
||||
|
||||
ieee80211_proc = create_proc_entry(DRV_NAME, S_IFDIR, 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 ieee80211_debug_exit(void)
|
||||
{
|
||||
if (ieee80211_proc) {
|
||||
remove_proc_entry("debug_level", ieee80211_proc);
|
||||
remove_proc_entry(DRV_NAME, init_net.proc_net);
|
||||
ieee80211_proc = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#include <linux/moduleparam.h>
|
||||
module_param(debug, int, 0444);
|
||||
MODULE_PARM_DESC(debug, "debug output mask");
|
||||
#endif
|
|
@ -1,449 +0,0 @@
|
|||
#ifndef __IEEE80211_R8192S_H
|
||||
#define __IEEE80211_R8192S_H
|
||||
|
||||
/* added for rtl819x tx procedure */
|
||||
#define MAX_QUEUE_SIZE 0x10
|
||||
|
||||
/* 8190 queue mapping */
|
||||
enum {
|
||||
BK_QUEUE = 0,
|
||||
BE_QUEUE = 1,
|
||||
VI_QUEUE = 2,
|
||||
VO_QUEUE = 3,
|
||||
HCCA_QUEUE = 4,
|
||||
TXCMD_QUEUE = 5,
|
||||
MGNT_QUEUE = 6,
|
||||
HIGH_QUEUE = 7,
|
||||
BEACON_QUEUE = 8,
|
||||
|
||||
LOW_QUEUE = BE_QUEUE,
|
||||
NORMAL_QUEUE = MGNT_QUEUE
|
||||
};
|
||||
|
||||
#define SWRF_TIMEOUT 50
|
||||
|
||||
/* LEAP related */
|
||||
/* Flag byte: byte 8, numbered from 0. */
|
||||
#define IE_CISCO_FLAG_POSITION 0x08
|
||||
#define SUPPORT_CKIP_MIC 0x08 /* bit3 */
|
||||
#define SUPPORT_CKIP_PK 0x10 /* bit4 */
|
||||
|
||||
/* defined for skb cb field, at most 28 byte */
|
||||
typedef struct cb_desc {
|
||||
/* Tx Desc Related flags (8-9) */
|
||||
u8 bLastIniPkt:1;
|
||||
u8 bCmdOrInit:1;
|
||||
u8 bFirstSeg:1;
|
||||
u8 bLastSeg:1;
|
||||
u8 bEncrypt:1;
|
||||
u8 bTxDisableRateFallBack:1;
|
||||
u8 bTxUseDriverAssingedRate:1;
|
||||
u8 bHwSec:1; /* indicate whether use Hw security */
|
||||
|
||||
u8 reserved1;
|
||||
|
||||
/* Tx Firmware Relaged flags (10-11) */
|
||||
u8 bCTSEnable:1;
|
||||
u8 bRTSEnable:1;
|
||||
u8 bUseShortGI:1;
|
||||
u8 bUseShortPreamble:1;
|
||||
u8 bTxEnableFwCalcDur:1;
|
||||
u8 bAMPDUEnable:1;
|
||||
u8 bRTSSTBC:1;
|
||||
u8 RTSSC:1;
|
||||
|
||||
u8 bRTSBW:1;
|
||||
u8 bPacketBW:1;
|
||||
u8 bRTSUseShortPreamble:1;
|
||||
u8 bRTSUseShortGI:1;
|
||||
u8 bMulticast:1;
|
||||
u8 bBroadcast:1;
|
||||
u8 drv_agg_enable:1;
|
||||
u8 reserved2:1;
|
||||
|
||||
/* Tx Desc related element(12-19) */
|
||||
u8 rata_index;
|
||||
u8 queue_index;
|
||||
u16 txbuf_size;
|
||||
u8 RATRIndex;
|
||||
u8 reserved6;
|
||||
u8 reserved7;
|
||||
u8 reserved8;
|
||||
|
||||
/* Tx firmware related element(20-27) */
|
||||
u8 data_rate;
|
||||
u8 rts_rate;
|
||||
u8 ampdu_factor;
|
||||
u8 ampdu_density;
|
||||
u8 DrvAggrNum;
|
||||
u16 pkt_size;
|
||||
u8 reserved12;
|
||||
} cb_desc, *pcb_desc;
|
||||
|
||||
enum {
|
||||
MGN_1M = 0x02,
|
||||
MGN_2M = 0x04,
|
||||
MGN_5_5M = 0x0b,
|
||||
MGN_11M = 0x16,
|
||||
|
||||
MGN_6M = 0x0c,
|
||||
MGN_9M = 0x12,
|
||||
MGN_12M = 0x18,
|
||||
MGN_18M = 0x24,
|
||||
MGN_24M = 0x30,
|
||||
MGN_36M = 0x48,
|
||||
MGN_48M = 0x60,
|
||||
MGN_54M = 0x6c,
|
||||
|
||||
MGN_MCS0 = 0x80,
|
||||
MGN_MCS1 = 0x81,
|
||||
MGN_MCS2 = 0x82,
|
||||
MGN_MCS3 = 0x83,
|
||||
MGN_MCS4 = 0x84,
|
||||
MGN_MCS5 = 0x85,
|
||||
MGN_MCS6 = 0x86,
|
||||
MGN_MCS7 = 0x87,
|
||||
MGN_MCS8 = 0x88,
|
||||
MGN_MCS9 = 0x89,
|
||||
MGN_MCS10 = 0x8a,
|
||||
MGN_MCS11 = 0x8b,
|
||||
MGN_MCS12 = 0x8c,
|
||||
MGN_MCS13 = 0x8d,
|
||||
MGN_MCS14 = 0x8e,
|
||||
MGN_MCS15 = 0x8f,
|
||||
|
||||
MGN_MCS0_SG = 0x90,
|
||||
MGN_MCS1_SG = 0x91,
|
||||
MGN_MCS2_SG = 0x92,
|
||||
MGN_MCS3_SG = 0x93,
|
||||
MGN_MCS4_SG = 0x94,
|
||||
MGN_MCS5_SG = 0x95,
|
||||
MGN_MCS6_SG = 0x96,
|
||||
MGN_MCS7_SG = 0x97,
|
||||
MGN_MCS8_SG = 0x98,
|
||||
MGN_MCS9_SG = 0x99,
|
||||
MGN_MCS10_SG = 0x9a,
|
||||
MGN_MCS11_SG = 0x9b,
|
||||
MGN_MCS12_SG = 0x9c,
|
||||
MGN_MCS13_SG = 0x9d,
|
||||
MGN_MCS14_SG = 0x9e,
|
||||
MGN_MCS15_SG = 0x9f,
|
||||
};
|
||||
|
||||
#define FC_QOS_BIT BIT7
|
||||
|
||||
#define IsDataFrame(pdu) (((pdu[0] & 0x0C) == 0x08) ? true : false)
|
||||
#define IsLegacyDataFrame(pdu) (IsDataFrame(pdu) && (!(pdu[0] & FC_QOS_BIT)))
|
||||
#define IsQoSDataFrame(pframe) \
|
||||
((*(u16 *)pframe & (IEEE80211_STYPE_QOS_DATA | IEEE80211_FTYPE_DATA)) \
|
||||
== (IEEE80211_STYPE_QOS_DATA | IEEE80211_FTYPE_DATA))
|
||||
|
||||
#define Frame_Order(pframe) (*(u16 *)pframe & IEEE80211_FCTL_ORDER)
|
||||
|
||||
#define SN_LESS(a, b) (((a - b) & 0x800) != 0)
|
||||
#define SN_EQUAL(a, b) (a == b)
|
||||
|
||||
#define MAX_DEV_ADDR_SIZE 8
|
||||
|
||||
enum {
|
||||
/* ACT_CATEGORY */
|
||||
ACT_CAT_QOS = 1,
|
||||
ACT_CAT_DLS = 2,
|
||||
ACT_CAT_BA = 3,
|
||||
ACT_CAT_HT = 7,
|
||||
ACT_CAT_WMM = 17,
|
||||
|
||||
/* TS_ACTION */
|
||||
ACT_ADDTSREQ = 0,
|
||||
ACT_ADDTSRSP = 1,
|
||||
ACT_DELTS = 2,
|
||||
ACT_SCHEDULE = 3,
|
||||
|
||||
/* BA_ACTION */
|
||||
ACT_ADDBAREQ = 0,
|
||||
ACT_ADDBARSP = 1,
|
||||
ACT_DELBA = 2,
|
||||
};
|
||||
|
||||
/* InitialGainOpType */
|
||||
enum {
|
||||
IG_Backup = 0,
|
||||
IG_Restore,
|
||||
IG_Max
|
||||
};
|
||||
|
||||
typedef enum _LED_CTL_MODE{
|
||||
LED_CTL_POWER_ON = 1,
|
||||
LED_CTL_LINK = 2,
|
||||
LED_CTL_NO_LINK = 3,
|
||||
LED_CTL_TX = 4,
|
||||
LED_CTL_RX = 5,
|
||||
LED_CTL_SITE_SURVEY = 6,
|
||||
LED_CTL_POWER_OFF = 7,
|
||||
LED_CTL_START_TO_LINK = 8,
|
||||
LED_CTL_START_WPS = 9,
|
||||
LED_CTL_STOP_WPS = 10,
|
||||
LED_CTL_START_WPS_BOTTON = 11,
|
||||
LED_CTL_STOP_WPS_FAIL = 12,
|
||||
LED_CTL_STOP_WPS_FAIL_OVERLAP = 13,
|
||||
} LED_CTL_MODE;
|
||||
|
||||
typedef union _frameqos {
|
||||
u16 shortdata;
|
||||
u8 chardata[2];
|
||||
struct {
|
||||
u16 tid:4;
|
||||
u16 eosp:1;
|
||||
u16 ack_policy:2;
|
||||
u16 reserved:1;
|
||||
u16 txop:8;
|
||||
} field;
|
||||
} frameqos;
|
||||
|
||||
static inline u8 Frame_QoSTID(u8 *buf)
|
||||
{
|
||||
struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *)buf;
|
||||
u16 fc = le16_to_cpu(hdr->frame_control);
|
||||
|
||||
return (u8)((frameqos *)(buf +
|
||||
(((fc & IEEE80211_FCTL_TODS) &&
|
||||
(fc & IEEE80211_FCTL_FROMDS)) ? 30 : 24)))->field.tid;
|
||||
}
|
||||
|
||||
enum {
|
||||
ERP_NonERPpresent = 1,
|
||||
ERP_UseProtection = 2,
|
||||
ERP_BarkerPreambleMode = 4,
|
||||
};
|
||||
|
||||
struct bandwidth_autoswitch {
|
||||
long threshold_20Mhzto40Mhz;
|
||||
long threshold_40Mhzto20Mhz;
|
||||
bool bforced_tx20Mhz;
|
||||
bool bautoswitch_enable;
|
||||
};
|
||||
|
||||
#define REORDER_WIN_SIZE 128
|
||||
#define REORDER_ENTRY_NUM 128
|
||||
typedef struct _RX_REORDER_ENTRY {
|
||||
struct list_head List;
|
||||
u16 SeqNum;
|
||||
struct ieee80211_rxb *prxb;
|
||||
} RX_REORDER_ENTRY, *PRX_REORDER_ENTRY;
|
||||
|
||||
typedef enum _Fsync_State{
|
||||
Default_Fsync,
|
||||
HW_Fsync,
|
||||
SW_Fsync
|
||||
} Fsync_State;
|
||||
|
||||
/* Power save mode configured. */
|
||||
typedef enum _RT_PS_MODE {
|
||||
eActive, /* Active/Continuous access. */
|
||||
eMaxPs, /* Max power save mode. */
|
||||
eFastPs /* Fast power save mode. */
|
||||
} RT_PS_MODE;
|
||||
|
||||
typedef enum _IPS_CALLBACK_FUNCION {
|
||||
IPS_CALLBACK_NONE = 0,
|
||||
IPS_CALLBACK_MGNT_LINK_REQUEST = 1,
|
||||
IPS_CALLBACK_JOIN_REQUEST = 2,
|
||||
} IPS_CALLBACK_FUNCION;
|
||||
|
||||
typedef enum _RT_JOIN_ACTION {
|
||||
RT_JOIN_INFRA = 1,
|
||||
RT_JOIN_IBSS = 2,
|
||||
RT_START_IBSS = 3,
|
||||
RT_NO_ACTION = 4,
|
||||
} RT_JOIN_ACTION;
|
||||
|
||||
struct ibss_parms {
|
||||
u16 atimWin;
|
||||
};
|
||||
|
||||
/* Max num of support rates element: 8, Max num of ext. support rate: 255. */
|
||||
#define MAX_NUM_RATES 264
|
||||
|
||||
typedef enum _RT_RF_POWER_STATE {
|
||||
eRfOn,
|
||||
eRfSleep,
|
||||
eRfOff
|
||||
} RT_RF_POWER_STATE;
|
||||
|
||||
struct rt_power_save_control {
|
||||
/* Inactive Power Save (IPS): disable RF when disconnected */
|
||||
bool bInactivePs;
|
||||
bool bIPSModeBackup;
|
||||
bool bHaltAdapterClkRQ;
|
||||
bool bSwRfProcessing;
|
||||
RT_RF_POWER_STATE eInactivePowerState;
|
||||
struct work_struct InactivePsWorkItem;
|
||||
struct timer_list InactivePsTimer;
|
||||
|
||||
/* return point for join action */
|
||||
IPS_CALLBACK_FUNCION ReturnPoint;
|
||||
|
||||
/* Recored Parameters for rescheduled JoinRequest */
|
||||
bool bTmpBssDesc;
|
||||
RT_JOIN_ACTION tmpJoinAction;
|
||||
struct ieee80211_network tmpBssDesc;
|
||||
|
||||
/* Recored Parameters for rescheduled MgntLinkRequest */
|
||||
bool bTmpScanOnly;
|
||||
bool bTmpActiveScan;
|
||||
bool bTmpFilterHiddenAP;
|
||||
bool bTmpUpdateParms;
|
||||
u8 tmpSsidBuf[33];
|
||||
OCTET_STRING tmpSsid2Scan;
|
||||
bool bTmpSsid2Scan;
|
||||
u8 tmpNetworkType;
|
||||
u8 tmpChannelNumber;
|
||||
u16 tmpBcnPeriod;
|
||||
u8 tmpDtimPeriod;
|
||||
u16 tmpmCap;
|
||||
OCTET_STRING tmpSuppRateSet;
|
||||
u8 tmpSuppRateBuf[MAX_NUM_RATES];
|
||||
bool bTmpSuppRate;
|
||||
struct ibss_parms tmpIbpm;
|
||||
bool bTmpIbpm;
|
||||
|
||||
/* Leisre Poswer Save: disable RF if connected but traffic isn't busy */
|
||||
bool bLeisurePs;
|
||||
u32 PowerProfile;
|
||||
u8 LpsIdleCount;
|
||||
u8 RegMaxLPSAwakeIntvl;
|
||||
u8 LPSAwakeIntvl;
|
||||
|
||||
/* RF OFF Level */
|
||||
u32 CurPsLevel;
|
||||
u32 RegRfPsLevel;
|
||||
|
||||
/* Fw Control LPS */
|
||||
bool bFwCtrlLPS;
|
||||
u8 FWCtrlPSMode;
|
||||
|
||||
/* Record if there is a link request in IPS RF off progress. */
|
||||
bool LinkReqInIPSRFOffPgs;
|
||||
/*
|
||||
* To make sure that connect info should be executed, so we set the
|
||||
* bit to filter the link info which comes after the connect info.
|
||||
*/
|
||||
bool BufConnectinfoBefore;
|
||||
};
|
||||
|
||||
enum {
|
||||
RF_CHANGE_BY_SW = BIT31,
|
||||
RF_CHANGE_BY_HW = BIT30,
|
||||
RF_CHANGE_BY_PS = BIT29,
|
||||
RF_CHANGE_BY_IPS = BIT28,
|
||||
};
|
||||
|
||||
/* Firmware related CMD IO. */
|
||||
typedef enum _FW_CMD_IO_TYPE{
|
||||
FW_CMD_DIG_ENABLE = 0, /* for DIG DM */
|
||||
FW_CMD_DIG_DISABLE = 1,
|
||||
FW_CMD_DIG_HALT = 2,
|
||||
FW_CMD_DIG_RESUME = 3,
|
||||
FW_CMD_HIGH_PWR_ENABLE = 4, /* for DIG DM */
|
||||
FW_CMD_HIGH_PWR_DISABLE = 5,
|
||||
FW_CMD_RA_RESET = 6, /* for DIG DM */
|
||||
FW_CMD_RA_ACTIVE= 7,
|
||||
FW_CMD_RA_REFRESH_N= 8,
|
||||
FW_CMD_RA_REFRESH_BG= 9,
|
||||
FW_CMD_RA_INIT= 10, /* for FW supported IQK */
|
||||
FW_CMD_IQK_ENABLE = 11, /* Tx power tracking switch */
|
||||
FW_CMD_TXPWR_TRACK_ENABLE = 12, /* Tx power tracking switch */
|
||||
FW_CMD_TXPWR_TRACK_DISABLE = 13,
|
||||
FW_CMD_TXPWR_TRACK_THERMAL = 14,
|
||||
FW_CMD_PAUSE_DM_BY_SCAN = 15,
|
||||
/* indicate firmware that driver enters LPS, for PS-Poll hardware bug */
|
||||
FW_CMD_RESUME_DM_BY_SCAN = 16,
|
||||
/* indicate firmware that driver leave LPS */
|
||||
FW_CMD_RA_REFRESH_N_COMB = 17,
|
||||
FW_CMD_RA_REFRESH_BG_COMB = 18,
|
||||
FW_CMD_ANTENNA_SW_ENABLE = 19,
|
||||
FW_CMD_ANTENNA_SW_DISABLE = 20,
|
||||
FW_CMD_TX_FEEDBACK_CCX_ENABLE = 21,
|
||||
FW_CMD_LPS_ENTER = 22,
|
||||
FW_CMD_LPS_LEAVE = 23,
|
||||
FW_CMD_DIG_MODE_SS = 24,
|
||||
FW_CMD_DIG_MODE_FA = 25,
|
||||
FW_CMD_ADD_A2_ENTRY = 26,
|
||||
FW_CMD_CTRL_DM_BY_DRIVER = 27,
|
||||
FW_CMD_CTRL_DM_BY_DRIVER_NEW = 28,
|
||||
}FW_CMD_IO_TYPE,*PFW_CMD_IO_TYPE;
|
||||
|
||||
#define RT_MAX_LD_SLOT_NUM 10
|
||||
struct rt_link_detect {
|
||||
u32 NumRecvBcnInPeriod;
|
||||
u32 NumRecvDataInPeriod;
|
||||
|
||||
/* number of Rx beacon / CheckForHang_period to determine link status */
|
||||
u32 RxBcnNum[RT_MAX_LD_SLOT_NUM];
|
||||
/* number of Rx data / CheckForHang_period to determine link status */
|
||||
u32 RxDataNum[RT_MAX_LD_SLOT_NUM];
|
||||
/* number of CheckForHang period to determine link status */
|
||||
u16 SlotNum;
|
||||
u16 SlotIndex;
|
||||
|
||||
u32 NumTxOkInPeriod;
|
||||
u32 NumRxOkInPeriod;
|
||||
bool bBusyTraffic;
|
||||
};
|
||||
|
||||
/* HT */
|
||||
#define MAX_RECEIVE_BUFFER_SIZE 9100
|
||||
extern void HTDebugHTCapability(u8 *CapIE, u8 *TitleString);
|
||||
extern void HTDebugHTInfo(u8 *InfoIE, u8 *TitleString);
|
||||
|
||||
extern void HTSetConnectBwMode(struct ieee80211_device *ieee,
|
||||
HT_CHANNEL_WIDTH Bandwidth,
|
||||
HT_EXTCHNL_OFFSET Offset);
|
||||
extern void HTUpdateDefaultSetting(struct ieee80211_device *ieee);
|
||||
extern void HTConstructCapabilityElement(struct ieee80211_device *ieee,
|
||||
u8 *posHTCap, u8 *len, u8 isEncrypt);
|
||||
extern void HTConstructInfoElement(struct ieee80211_device *ieee,
|
||||
u8 *posHTInfo, u8 *len, u8 isEncrypt);
|
||||
extern void HTConstructRT2RTAggElement(struct ieee80211_device *ieee,
|
||||
u8 *posRT2RTAgg, u8 *len);
|
||||
extern void HTOnAssocRsp(struct ieee80211_device *ieee);
|
||||
extern void HTInitializeHTInfo(struct ieee80211_device *ieee);
|
||||
extern void HTInitializeBssDesc(PBSS_HT pBssHT);
|
||||
extern void HTResetSelfAndSavePeerSetting(struct ieee80211_device *ieee,
|
||||
struct ieee80211_network *pNetwork);
|
||||
extern void HTUpdateSelfAndPeerSetting(struct ieee80211_device *ieee,
|
||||
struct ieee80211_network *pNetwork);
|
||||
extern u8 HTGetHighestMCSRate(struct ieee80211_device *ieee, u8 *pMCSRateSet,
|
||||
u8 *pMCSFilter);
|
||||
extern u8 MCS_FILTER_ALL[];
|
||||
extern u16 MCS_DATA_RATE[2][2][77] ;
|
||||
extern u8 HTCCheck(struct ieee80211_device *ieee, u8 *pFrame);
|
||||
extern void HTResetIOTSetting(PRT_HIGH_THROUGHPUT pHTInfo);
|
||||
extern bool IsHTHalfNmodeAPs(struct ieee80211_device *ieee);
|
||||
extern u16 HTHalfMcsToDataRate(struct ieee80211_device *ieee, u8 nMcsRate);
|
||||
extern u16 HTMcsToDataRate(struct ieee80211_device *ieee, u8 nMcsRate);
|
||||
extern u16 TxCountToDataRate(struct ieee80211_device *ieee, u8 nDataRate);
|
||||
extern int ieee80211_rx_ADDBAReq(struct ieee80211_device *ieee,
|
||||
struct sk_buff *skb);
|
||||
extern int ieee80211_rx_ADDBARsp(struct ieee80211_device *ieee,
|
||||
struct sk_buff *skb);
|
||||
extern int ieee80211_rx_DELBA(struct ieee80211_device *ieee,
|
||||
struct sk_buff *skb);
|
||||
extern void TsInitAddBA(struct ieee80211_device *ieee, PTX_TS_RECORD pTS,
|
||||
u8 Policy, u8 bOverwritePending);
|
||||
extern void TsInitDelBA(struct ieee80211_device *ieee,
|
||||
PTS_COMMON_INFO pTsCommonInfo, TR_SELECT TxRxSelect);
|
||||
extern void BaSetupTimeOut(unsigned long data);
|
||||
extern void TxBaInactTimeout(unsigned long data);
|
||||
extern void RxBaInactTimeout(unsigned long data);
|
||||
extern void ResetBaEntry(PBA_RECORD pBA);
|
||||
extern bool GetTs(struct ieee80211_device *ieee, PTS_COMMON_INFO *ppTS,
|
||||
u8 *Addr, u8 TID, TR_SELECT TxRxSelect, /* Rx:1, Tx:0 */
|
||||
bool bAddNewTs);
|
||||
extern void TSInitialize(struct ieee80211_device *ieee);
|
||||
extern void TsStartAddBaProcess(struct ieee80211_device *ieee,
|
||||
PTX_TS_RECORD pTxTS);
|
||||
extern void RemovePeerTS(struct ieee80211_device *ieee, u8 *Addr);
|
||||
extern void RemoveAllTS(struct ieee80211_device *ieee);
|
||||
|
||||
#endif /* __IEEE80211_R8192S_H */
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,625 +0,0 @@
|
|||
/* IEEE 802.11 SoftMAC layer
|
||||
* Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
|
||||
*
|
||||
* Mostly extracted from the rtl8180-sa2400 driver for the
|
||||
* in-kernel generic ieee802.11 stack.
|
||||
*
|
||||
* Some pieces of code might be stolen from ipw2100 driver
|
||||
* copyright of who own it's copyright ;-)
|
||||
*
|
||||
* PS wx handler mostly stolen from hostap, copyright who
|
||||
* own it's copyright ;-)
|
||||
*
|
||||
* released under the GPL
|
||||
*/
|
||||
|
||||
|
||||
#include "ieee80211.h"
|
||||
#include "dot11d.h"
|
||||
/* FIXME: add A freqs */
|
||||
|
||||
const long ieee80211_wlan_frequencies[] = {
|
||||
2412, 2417, 2422, 2427,
|
||||
2432, 2437, 2442, 2447,
|
||||
2452, 2457, 2462, 2467,
|
||||
2472, 2484
|
||||
};
|
||||
|
||||
|
||||
int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
|
||||
union iwreq_data *wrqu, char *b)
|
||||
{
|
||||
int ret;
|
||||
struct iw_freq *fwrq = & wrqu->freq;
|
||||
|
||||
down(&ieee->wx_sem);
|
||||
|
||||
if(ieee->iw_mode == IW_MODE_INFRA){
|
||||
ret = -EOPNOTSUPP;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* if setting by freq convert to channel */
|
||||
if (fwrq->e == 1) {
|
||||
if ((fwrq->m >= (int) 2.412e8 &&
|
||||
fwrq->m <= (int) 2.487e8)) {
|
||||
int f = fwrq->m / 100000;
|
||||
int c = 0;
|
||||
|
||||
while ((c < 14) && (f != ieee80211_wlan_frequencies[c]))
|
||||
c++;
|
||||
|
||||
/* hack to fall through */
|
||||
fwrq->e = 0;
|
||||
fwrq->m = c + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (fwrq->e > 0 || fwrq->m > 14 || fwrq->m < 1 ){
|
||||
ret = -EOPNOTSUPP;
|
||||
goto out;
|
||||
|
||||
}else { /* Set the channel */
|
||||
|
||||
if (!(GET_DOT11D_INFO(ieee)->channel_map)[fwrq->m]) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
ieee->current_network.channel = fwrq->m;
|
||||
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){
|
||||
|
||||
ieee80211_stop_send_beacons(ieee);
|
||||
ieee80211_start_send_beacons(ieee);
|
||||
}
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
up(&ieee->wx_sem);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int ieee80211_wx_get_freq(struct ieee80211_device *ieee,
|
||||
struct iw_request_info *a,
|
||||
union iwreq_data *wrqu, char *b)
|
||||
{
|
||||
struct iw_freq *fwrq = & wrqu->freq;
|
||||
|
||||
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->e = 1;
|
||||
// fwrq->m = ieee->current_network.channel;
|
||||
// fwrq->e = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ieee80211_wx_get_wap(struct ieee80211_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)
|
||||
return -1;
|
||||
|
||||
/* 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 &&
|
||||
ieee->wap_set == 0)
|
||||
|
||||
memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
|
||||
else
|
||||
memcpy(wrqu->ap_addr.sa_data,
|
||||
ieee->current_network.bssid, ETH_ALEN);
|
||||
|
||||
spin_unlock_irqrestore(&ieee->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
|
||||
struct iw_request_info *info,
|
||||
union iwreq_data *awrq,
|
||||
char *extra)
|
||||
{
|
||||
|
||||
int ret = 0;
|
||||
u8 zero[] = {0,0,0,0,0,0};
|
||||
unsigned long flags;
|
||||
|
||||
short ifup = ieee->proto_started;//dev->flags & IFF_UP;
|
||||
struct sockaddr *temp = (struct sockaddr *)awrq;
|
||||
|
||||
ieee->sync_scan_hurryup = 1;
|
||||
|
||||
down(&ieee->wx_sem);
|
||||
/* use ifconfig hw ether */
|
||||
if (ieee->iw_mode == IW_MODE_MASTER){
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (temp->sa_family != ARPHRD_ETHER){
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ifup)
|
||||
ieee80211_stop_protocol(ieee);
|
||||
|
||||
/* just to avoid to give inconsistent infos in the
|
||||
* get wx method. not really needed otherwise
|
||||
*/
|
||||
spin_lock_irqsave(&ieee->lock, flags);
|
||||
|
||||
memcpy(ieee->current_network.bssid, temp->sa_data, ETH_ALEN);
|
||||
ieee->wap_set = memcmp(temp->sa_data, zero,ETH_ALEN)!=0;
|
||||
|
||||
spin_unlock_irqrestore(&ieee->lock, flags);
|
||||
|
||||
if (ifup)
|
||||
ieee80211_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 len,ret = 0;
|
||||
unsigned long flags;
|
||||
|
||||
if (ieee->iw_mode == IW_MODE_MONITOR)
|
||||
return -1;
|
||||
|
||||
/* We want avoid to give to the user inconsistent infos*/
|
||||
spin_lock_irqsave(&ieee->lock, flags);
|
||||
|
||||
if (ieee->current_network.ssid[0] == '\0' ||
|
||||
ieee->current_network.ssid_len == 0){
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ieee->state != IEEE80211_LINKED &&
|
||||
ieee->state != IEEE80211_LINKED_SCANNING &&
|
||||
ieee->ssid_set == 0){
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
len = ieee->current_network.ssid_len;
|
||||
wrqu->essid.length = len;
|
||||
strncpy(b,ieee->current_network.ssid,len);
|
||||
wrqu->essid.flags = 1;
|
||||
|
||||
out:
|
||||
spin_unlock_irqrestore(&ieee->lock, flags);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
|
||||
struct iw_request_info *info,
|
||||
union iwreq_data *wrqu, char *extra)
|
||||
{
|
||||
|
||||
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,
|
||||
struct iw_request_info *info,
|
||||
union iwreq_data *wrqu, char *extra)
|
||||
{
|
||||
u32 tmp_rate = 0;
|
||||
//printk("===>mode:%d, halfNmode:%d\n", ieee->mode, ieee->bHalfWirelessN24GMode);
|
||||
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);
|
||||
}
|
||||
wrqu->bitrate.value = tmp_rate * 500000;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int ieee80211_wx_set_rts(struct ieee80211_device *ieee,
|
||||
struct iw_request_info *info,
|
||||
union iwreq_data *wrqu, char *extra)
|
||||
{
|
||||
if (wrqu->rts.disabled || !wrqu->rts.fixed)
|
||||
ieee->rts = DEFAULT_RTS_THRESHOLD;
|
||||
else
|
||||
{
|
||||
if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
|
||||
wrqu->rts.value > MAX_RTS_THRESHOLD)
|
||||
return -EINVAL;
|
||||
ieee->rts = wrqu->rts.value;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ieee80211_wx_get_rts(struct ieee80211_device *ieee,
|
||||
struct iw_request_info *info,
|
||||
union iwreq_data *wrqu, char *extra)
|
||||
{
|
||||
wrqu->rts.value = ieee->rts;
|
||||
wrqu->rts.fixed = 0; /* no auto select */
|
||||
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,
|
||||
union iwreq_data *wrqu, char *b)
|
||||
{
|
||||
|
||||
ieee->sync_scan_hurryup = 1;
|
||||
|
||||
down(&ieee->wx_sem);
|
||||
|
||||
if (wrqu->mode == ieee->iw_mode)
|
||||
goto out;
|
||||
|
||||
if (wrqu->mode == IW_MODE_MONITOR){
|
||||
|
||||
ieee->dev->type = ARPHRD_IEEE80211;
|
||||
}else{
|
||||
ieee->dev->type = ARPHRD_ETHER;
|
||||
}
|
||||
|
||||
if (!ieee->proto_started){
|
||||
ieee->iw_mode = wrqu->mode;
|
||||
}else{
|
||||
ieee80211_stop_protocol(ieee);
|
||||
ieee->iw_mode = wrqu->mode;
|
||||
ieee80211_start_protocol(ieee);
|
||||
}
|
||||
|
||||
out:
|
||||
up(&ieee->wx_sem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ieee80211_wx_sync_scan_wq(struct work_struct *work)
|
||||
{
|
||||
struct ieee80211_device *ieee = container_of(work, struct ieee80211_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;
|
||||
netif_carrier_off(ieee->dev);
|
||||
|
||||
if (ieee->data_hard_stop)
|
||||
ieee->data_hard_stop(ieee->dev);
|
||||
|
||||
ieee80211_stop_send_beacons(ieee);
|
||||
|
||||
ieee->state = IEEE80211_LINKED_SCANNING;
|
||||
ieee->link_change(ieee->dev);
|
||||
ieee->InitialGainHandler(ieee->dev,IG_Backup);
|
||||
if (ieee->SetFwCmdHandler)
|
||||
{
|
||||
ieee->SetFwCmdHandler(ieee->dev, FW_CMD_DIG_HALT);
|
||||
ieee->SetFwCmdHandler(ieee->dev, FW_CMD_HIGH_PWR_DISABLE);
|
||||
}
|
||||
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->dev, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
|
||||
}
|
||||
ieee80211_start_scan_syncro(ieee);
|
||||
if (b40M) {
|
||||
printk("Scan in 20M, back to 40M\n");
|
||||
if (chan_offset == HT_EXTCHNL_OFFSET_UPPER)
|
||||
ieee->set_chan(ieee->dev, chan + 2);
|
||||
else if (chan_offset == HT_EXTCHNL_OFFSET_LOWER)
|
||||
ieee->set_chan(ieee->dev, chan - 2);
|
||||
else
|
||||
ieee->set_chan(ieee->dev, chan);
|
||||
ieee->SetBWModeHandler(ieee->dev, bandwidth, chan_offset);
|
||||
} else {
|
||||
ieee->set_chan(ieee->dev, chan);
|
||||
}
|
||||
|
||||
ieee->InitialGainHandler(ieee->dev,IG_Restore);
|
||||
if (ieee->SetFwCmdHandler)
|
||||
{
|
||||
ieee->SetFwCmdHandler(ieee->dev, FW_CMD_DIG_RESUME);
|
||||
ieee->SetFwCmdHandler(ieee->dev, FW_CMD_HIGH_PWR_ENABLE);
|
||||
}
|
||||
ieee->state = IEEE80211_LINKED;
|
||||
ieee->link_change(ieee->dev);
|
||||
// To prevent the immediately calling watch_dog after scan.
|
||||
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->dev);
|
||||
|
||||
if(ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
|
||||
ieee80211_start_send_beacons(ieee);
|
||||
|
||||
netif_carrier_on(ieee->dev);
|
||||
count = 0;
|
||||
up(&ieee->wx_sem);
|
||||
|
||||
}
|
||||
|
||||
int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a,
|
||||
union iwreq_data *wrqu, char *b)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
down(&ieee->wx_sem);
|
||||
|
||||
if (ieee->iw_mode == IW_MODE_MONITOR || !(ieee->proto_started)){
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ( ieee->state == IEEE80211_LINKED){
|
||||
queue_work(ieee->wq, &ieee->wx_sync_scan_wq);
|
||||
/* intentionally forget to up sem */
|
||||
return 0;
|
||||
}
|
||||
|
||||
out:
|
||||
up(&ieee->wx_sem);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
|
||||
struct iw_request_info *a,
|
||||
union iwreq_data *wrqu, char *extra)
|
||||
{
|
||||
|
||||
int ret=0,len;
|
||||
short proto_started;
|
||||
unsigned long flags;
|
||||
|
||||
ieee->sync_scan_hurryup = 1;
|
||||
down(&ieee->wx_sem);
|
||||
|
||||
proto_started = ieee->proto_started;
|
||||
|
||||
if (wrqu->essid.length > IW_ESSID_MAX_SIZE){
|
||||
ret= -E2BIG;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ieee->iw_mode == IW_MODE_MONITOR){
|
||||
ret= -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(proto_started)
|
||||
ieee80211_stop_protocol(ieee);
|
||||
|
||||
|
||||
/* this is just to be sure that the GET wx callback
|
||||
* has consisten infos. not needed otherwise
|
||||
*/
|
||||
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;
|
||||
ieee->ssid_set = 1;
|
||||
}
|
||||
else{
|
||||
ieee->ssid_set = 0;
|
||||
ieee->current_network.ssid[0] = '\0';
|
||||
ieee->current_network.ssid_len = 0;
|
||||
}
|
||||
spin_unlock_irqrestore(&ieee->lock, flags);
|
||||
|
||||
if (proto_started)
|
||||
ieee80211_start_protocol(ieee);
|
||||
out:
|
||||
up(&ieee->wx_sem);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ieee80211_wx_get_mode(struct ieee80211_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,
|
||||
struct iw_request_info *info,
|
||||
union iwreq_data *wrqu, char *extra)
|
||||
{
|
||||
|
||||
int *parms = (int *)extra;
|
||||
int enable = (parms[0] > 0);
|
||||
short prev = ieee->raw_tx;
|
||||
|
||||
down(&ieee->wx_sem);
|
||||
|
||||
if(enable)
|
||||
ieee->raw_tx = 1;
|
||||
else
|
||||
ieee->raw_tx = 0;
|
||||
|
||||
printk(KERN_INFO"raw TX is %s\n",
|
||||
ieee->raw_tx ? "enabled" : "disabled");
|
||||
|
||||
if(ieee->iw_mode == IW_MODE_MONITOR)
|
||||
{
|
||||
if(prev == 0 && ieee->raw_tx){
|
||||
if (ieee->data_hard_resume)
|
||||
ieee->data_hard_resume(ieee->dev);
|
||||
|
||||
netif_carrier_on(ieee->dev);
|
||||
}
|
||||
|
||||
if(prev && ieee->raw_tx == 1)
|
||||
netif_carrier_off(ieee->dev);
|
||||
}
|
||||
|
||||
up(&ieee->wx_sem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ieee80211_wx_get_name(struct ieee80211_device *ieee,
|
||||
struct iw_request_info *info,
|
||||
union iwreq_data *wrqu, char *extra)
|
||||
{
|
||||
strlcpy(wrqu->name, "802.11", IFNAMSIZ);
|
||||
if(ieee->modulation & IEEE80211_CCK_MODULATION){
|
||||
strlcat(wrqu->name, "b", IFNAMSIZ);
|
||||
if(ieee->modulation & IEEE80211_OFDM_MODULATION)
|
||||
strlcat(wrqu->name, "/g", IFNAMSIZ);
|
||||
}else if(ieee->modulation & IEEE80211_OFDM_MODULATION)
|
||||
strlcat(wrqu->name, "g", IFNAMSIZ);
|
||||
if (ieee->mode & (IEEE_N_24G | IEEE_N_5G))
|
||||
strlcat(wrqu->name, "/n", IFNAMSIZ);
|
||||
|
||||
if((ieee->state == IEEE80211_LINKED) ||
|
||||
(ieee->state == IEEE80211_LINKED_SCANNING))
|
||||
strlcat(wrqu->name, " link", IFNAMSIZ);
|
||||
else if(ieee->state != IEEE80211_NOLINK)
|
||||
strlcat(wrqu->name, " .....", IFNAMSIZ);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* this is mostly stolen from hostap */
|
||||
int ieee80211_wx_set_power(struct ieee80211_device *ieee,
|
||||
struct iw_request_info *info,
|
||||
union iwreq_data *wrqu, char *extra)
|
||||
{
|
||||
int ret = 0;
|
||||
#if 1
|
||||
if(
|
||||
(!ieee->sta_wake_up) ||
|
||||
// (!ieee->ps_request_tx_ack) ||
|
||||
(!ieee->enter_sleep_state) ||
|
||||
(!ieee->ps_is_queue_empty)){
|
||||
|
||||
// printk("ERROR. PS mode is tryied to be use but driver missed a callback\n\n");
|
||||
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
down(&ieee->wx_sem);
|
||||
|
||||
if (wrqu->power.disabled){
|
||||
ieee->ps = IEEE80211_PS_DISABLED;
|
||||
goto exit;
|
||||
}
|
||||
if (wrqu->power.flags & IW_POWER_TIMEOUT) {
|
||||
//ieee->ps_period = wrqu->power.value / 1000;
|
||||
ieee->ps_timeout = wrqu->power.value / 1000;
|
||||
}
|
||||
|
||||
if (wrqu->power.flags & IW_POWER_PERIOD) {
|
||||
|
||||
//ieee->ps_timeout = wrqu->power.value / 1000;
|
||||
ieee->ps_period = wrqu->power.value / 1000;
|
||||
//wrq->value / 1024;
|
||||
|
||||
}
|
||||
switch (wrqu->power.flags & IW_POWER_MODE) {
|
||||
case IW_POWER_UNICAST_R:
|
||||
ieee->ps = IEEE80211_PS_UNICAST;
|
||||
break;
|
||||
case IW_POWER_MULTICAST_R:
|
||||
ieee->ps = IEEE80211_PS_MBCAST;
|
||||
break;
|
||||
case IW_POWER_ALL_R:
|
||||
ieee->ps = IEEE80211_PS_UNICAST | IEEE80211_PS_MBCAST;
|
||||
break;
|
||||
|
||||
case IW_POWER_ON:
|
||||
// ieee->ps = IEEE80211_PS_DISABLED;
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
|
||||
}
|
||||
exit:
|
||||
up(&ieee->wx_sem);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
/* this is stolen from hostap */
|
||||
int ieee80211_wx_get_power(struct ieee80211_device *ieee,
|
||||
struct iw_request_info *info,
|
||||
union iwreq_data *wrqu, char *extra)
|
||||
{
|
||||
int ret =0;
|
||||
|
||||
down(&ieee->wx_sem);
|
||||
|
||||
if(ieee->ps == IEEE80211_PS_DISABLED){
|
||||
wrqu->power.disabled = 1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
wrqu->power.disabled = 0;
|
||||
|
||||
if ((wrqu->power.flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
|
||||
wrqu->power.flags = IW_POWER_TIMEOUT;
|
||||
wrqu->power.value = ieee->ps_timeout * 1000;
|
||||
} else {
|
||||
// ret = -EOPNOTSUPP;
|
||||
// goto exit;
|
||||
wrqu->power.flags = IW_POWER_PERIOD;
|
||||
wrqu->power.value = ieee->ps_period * 1000;
|
||||
//ieee->current_network.dtim_period * ieee->current_network.beacon_interval * 1024;
|
||||
}
|
||||
|
||||
if ((ieee->ps & (IEEE80211_PS_MBCAST | IEEE80211_PS_UNICAST)) == (IEEE80211_PS_MBCAST | IEEE80211_PS_UNICAST))
|
||||
wrqu->power.flags |= IW_POWER_ALL_R;
|
||||
else if (ieee->ps & IEEE80211_PS_MBCAST)
|
||||
wrqu->power.flags |= IW_POWER_MULTICAST_R;
|
||||
else
|
||||
wrqu->power.flags |= IW_POWER_UNICAST_R;
|
||||
|
||||
exit:
|
||||
up(&ieee->wx_sem);
|
||||
return ret;
|
||||
|
||||
}
|
|
@ -1,916 +0,0 @@
|
|||
/******************************************************************************
|
||||
|
||||
Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
|
||||
|
||||
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
|
||||
|
||||
******************************************************************************
|
||||
|
||||
Few modifications for Realtek's Wi-Fi drivers by
|
||||
Andrea Merello <andreamrl@tiscali.it>
|
||||
|
||||
A special thanks goes to Realtek for their support !
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#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 <linux/if_vlan.h>
|
||||
|
||||
#include "ieee80211.h"
|
||||
|
||||
|
||||
/*
|
||||
|
||||
|
||||
802.11 Data Frame
|
||||
|
||||
|
||||
802.11 frame_contorl for data frames - 2 bytes
|
||||
,-----------------------------------------------------------------------------------------.
|
||||
bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e |
|
||||
|----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
|
||||
val | 0 | 0 | 0 | 1 | x | 0 | 0 | 0 | 1 | 0 | x | x | x | x | x |
|
||||
|----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
|
||||
desc | ^-ver-^ | ^type-^ | ^-----subtype-----^ | to |from |more |retry| pwr |more |wep |
|
||||
| | | x=0 data,x=1 data+ack | DS | DS |frag | | mgm |data | |
|
||||
'-----------------------------------------------------------------------------------------'
|
||||
/\
|
||||
|
|
||||
802.11 Data Frame |
|
||||
,--------- 'ctrl' expands to >-----------'
|
||||
|
|
||||
,--'---,-------------------------------------------------------------.
|
||||
Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 |
|
||||
|------|------|---------|---------|---------|------|---------|------|
|
||||
Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | Frame | fcs |
|
||||
| | tion | (BSSID) | | | ence | data | |
|
||||
`--------------------------------------------------| |------'
|
||||
Total: 28 non-data bytes `----.----'
|
||||
|
|
||||
.- 'Frame data' expands to <---------------------------'
|
||||
|
|
||||
V
|
||||
,---------------------------------------------------.
|
||||
Bytes | 1 | 1 | 1 | 3 | 2 | 0-2304 |
|
||||
|------|------|---------|----------|------|---------|
|
||||
Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP |
|
||||
| DSAP | SSAP | | | | Packet |
|
||||
| 0xAA | 0xAA |0x03 (UI)|0x00-00-F8| | |
|
||||
`-----------------------------------------| |
|
||||
Total: 8 non-data bytes `----.----'
|
||||
|
|
||||
.- 'IP Packet' expands, if WEP enabled, to <--'
|
||||
|
|
||||
V
|
||||
,-----------------------.
|
||||
Bytes | 4 | 0-2296 | 4 |
|
||||
|-----|-----------|-----|
|
||||
Desc. | IV | Encrypted | ICV |
|
||||
| | IP Packet | |
|
||||
`-----------------------'
|
||||
Total: 8 non-data bytes
|
||||
|
||||
|
||||
802.3 Ethernet Data Frame
|
||||
|
||||
,-----------------------------------------.
|
||||
Bytes | 6 | 6 | 2 | Variable | 4 |
|
||||
|-------|-------|------|-----------|------|
|
||||
Desc. | Dest. | Source| Type | IP Packet | fcs |
|
||||
| MAC | MAC | | | |
|
||||
`-----------------------------------------'
|
||||
Total: 18 non-data bytes
|
||||
|
||||
In the event that fragmentation is required, the incoming payload is split into
|
||||
N parts of size ieee->fts. The first fragment contains the SNAP header and the
|
||||
remaining packets are just data.
|
||||
|
||||
If encryption is enabled, each fragment payload size is reduced by enough space
|
||||
to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP)
|
||||
So if you have 1500 bytes of payload with ieee->fts set to 500 without
|
||||
encryption it will take 3 frames. With WEP it will take 4 frames as the
|
||||
payload of each frame is reduced to 492 bytes.
|
||||
|
||||
* SKB visualization
|
||||
*
|
||||
* ,- skb->data
|
||||
* |
|
||||
* | ETHERNET HEADER ,-<-- PAYLOAD
|
||||
* | | 14 bytes from skb->data
|
||||
* | 2 bytes for Type --> ,T. | (sizeof ethhdr)
|
||||
* | | | |
|
||||
* |,-Dest.--. ,--Src.---. | | |
|
||||
* | 6 bytes| | 6 bytes | | | |
|
||||
* v | | | | | |
|
||||
* 0 | v 1 | v | v 2
|
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
|
||||
* ^ | ^ | ^ |
|
||||
* | | | | | |
|
||||
* | | | | `T' <---- 2 bytes for Type
|
||||
* | | | |
|
||||
* | | '---SNAP--' <-------- 6 bytes for SNAP
|
||||
* | |
|
||||
* `-IV--' <-------------------- 4 bytes for IV (WEP)
|
||||
*
|
||||
* SNAP HEADER
|
||||
*
|
||||
*/
|
||||
|
||||
static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
|
||||
static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
|
||||
|
||||
static inline int ieee80211_put_snap(u8 *data, u16 h_proto)
|
||||
{
|
||||
struct ieee80211_snap_hdr *snap;
|
||||
u8 *oui;
|
||||
|
||||
snap = (struct ieee80211_snap_hdr *)data;
|
||||
snap->dsap = 0xaa;
|
||||
snap->ssap = 0xaa;
|
||||
snap->ctrl = 0x03;
|
||||
|
||||
if (h_proto == 0x8137 || h_proto == 0x80f3)
|
||||
oui = P802_1H_OUI;
|
||||
else
|
||||
oui = RFC1042_OUI;
|
||||
snap->oui[0] = oui[0];
|
||||
snap->oui[1] = oui[1];
|
||||
snap->oui[2] = oui[2];
|
||||
|
||||
*(u16 *)(data + SNAP_SIZE) = htons(h_proto);
|
||||
|
||||
return SNAP_SIZE + sizeof(u16);
|
||||
}
|
||||
|
||||
int ieee80211_encrypt_fragment(
|
||||
struct ieee80211_device *ieee,
|
||||
struct sk_buff *frag,
|
||||
int hdr_len)
|
||||
{
|
||||
struct ieee80211_crypt_data* crypt = ieee->crypt[ieee->tx_keyidx];
|
||||
int res;
|
||||
|
||||
if (!(crypt && crypt->ops))
|
||||
{
|
||||
printk("=========>%s(), crypt is null\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
#ifdef CONFIG_IEEE80211_CRYPT_TKIP
|
||||
struct rtl_ieee80211_hdr *header;
|
||||
|
||||
if (ieee->tkip_countermeasures &&
|
||||
crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
|
||||
header = (struct rtl_ieee80211_hdr *)frag->data;
|
||||
if (net_ratelimit()) {
|
||||
printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
|
||||
"TX packet to %pM\n",
|
||||
ieee->dev->name, header->addr1);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
/* To encrypt, frame format is:
|
||||
* IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */
|
||||
|
||||
/* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
|
||||
* call both MSDU and MPDU encryption functions from here. */
|
||||
atomic_inc(&crypt->refcnt);
|
||||
res = 0;
|
||||
if (crypt->ops->encrypt_msdu)
|
||||
res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv);
|
||||
if (res == 0 && crypt->ops->encrypt_mpdu)
|
||||
res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv);
|
||||
|
||||
atomic_dec(&crypt->refcnt);
|
||||
if (res < 0) {
|
||||
printk(KERN_INFO "%s: Encryption failed: len=%d.\n",
|
||||
ieee->dev->name, frag->len);
|
||||
ieee->ieee_stats.tx_discards++;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void ieee80211_txb_free(struct ieee80211_txb *txb) {
|
||||
if (unlikely(!txb))
|
||||
return;
|
||||
kfree(txb);
|
||||
}
|
||||
|
||||
struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
|
||||
int gfp_mask)
|
||||
{
|
||||
struct ieee80211_txb *txb;
|
||||
int i;
|
||||
txb = kmalloc(
|
||||
sizeof(struct ieee80211_txb) + (sizeof(u8*) * nr_frags),
|
||||
gfp_mask);
|
||||
if (!txb)
|
||||
return NULL;
|
||||
|
||||
memset(txb, 0, sizeof(struct ieee80211_txb));
|
||||
txb->nr_frags = nr_frags;
|
||||
txb->frag_size = txb_size;
|
||||
|
||||
for (i = 0; i < nr_frags; i++) {
|
||||
txb->fragments[i] = dev_alloc_skb(txb_size);
|
||||
if (unlikely(!txb->fragments[i])) {
|
||||
i--;
|
||||
break;
|
||||
}
|
||||
memset(txb->fragments[i]->cb, 0, sizeof(txb->fragments[i]->cb));
|
||||
}
|
||||
if (unlikely(i != nr_frags)) {
|
||||
while (i >= 0)
|
||||
dev_kfree_skb_any(txb->fragments[i--]);
|
||||
kfree(txb);
|
||||
return NULL;
|
||||
}
|
||||
return txb;
|
||||
}
|
||||
|
||||
// Classify the to-be send data packet
|
||||
// Need to acquire the sent queue index.
|
||||
static int
|
||||
ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network)
|
||||
{
|
||||
struct ethhdr *eth;
|
||||
struct iphdr *ip;
|
||||
eth = (struct ethhdr *)skb->data;
|
||||
if (eth->h_proto != htons(ETH_P_IP))
|
||||
return 0;
|
||||
|
||||
ip = ip_hdr(skb);
|
||||
|
||||
switch (ip->tos & 0xfc) {
|
||||
case 0x20:
|
||||
return 2;
|
||||
case 0x40:
|
||||
return 1;
|
||||
case 0x60:
|
||||
return 3;
|
||||
case 0x80:
|
||||
return 4;
|
||||
case 0xa0:
|
||||
return 5;
|
||||
case 0xc0:
|
||||
return 6;
|
||||
case 0xe0:
|
||||
return 7;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ieee80211_tx_query_agg_cap(struct ieee80211_device* ieee, struct sk_buff* skb, cb_desc* tcb_desc)
|
||||
{
|
||||
PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
|
||||
PTX_TS_RECORD pTxTs = NULL;
|
||||
struct ieee80211_hdr_1addr* hdr = (struct ieee80211_hdr_1addr*)skb->data;
|
||||
|
||||
if (!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
|
||||
return;
|
||||
if (!IsQoSDataFrame(skb->data))
|
||||
return;
|
||||
|
||||
if (is_multicast_ether_addr(hdr->addr1) || is_broadcast_ether_addr(hdr->addr1))
|
||||
return;
|
||||
//check packet and mode later
|
||||
#ifdef TO_DO_LIST
|
||||
if(pTcb->PacketLength >= 4096)
|
||||
return;
|
||||
// For RTL819X, if pairwisekey = wep/tkip, we don't aggrregation.
|
||||
if(!Adapter->HalFunc.GetNmodeSupportBySecCfgHandler(Adapter))
|
||||
return;
|
||||
#endif
|
||||
|
||||
if(pHTInfo->IOTAction & HT_IOT_ACT_TX_NO_AGGREGATION)
|
||||
return;
|
||||
|
||||
#if 1
|
||||
if(!ieee->GetNmodeSupportBySecCfg(ieee->dev))
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if(pHTInfo->bCurrentAMPDUEnable)
|
||||
{
|
||||
if (!GetTs(ieee, (PTS_COMMON_INFO*)(&pTxTs), hdr->addr1, skb->priority, TX_DIR, true))
|
||||
{
|
||||
printk("===>can't get TS\n");
|
||||
return;
|
||||
}
|
||||
if (pTxTs->TxAdmittedBARecord.bValid == false)
|
||||
{
|
||||
//as some AP will refuse our action frame until key handshake has been finished. WB
|
||||
if (ieee->wpa_ie_len && (ieee->pairwise_key_type == KEY_TYPE_NA))
|
||||
;
|
||||
else
|
||||
TsStartAddBaProcess(ieee, pTxTs);
|
||||
goto FORCED_AGG_SETTING;
|
||||
}
|
||||
else if (pTxTs->bUsingBa == false)
|
||||
{
|
||||
if (SN_LESS(pTxTs->TxAdmittedBARecord.BaStartSeqCtrl.field.SeqNum, (pTxTs->TxCurSeq+1)%4096))
|
||||
pTxTs->bUsingBa = true;
|
||||
else
|
||||
goto FORCED_AGG_SETTING;
|
||||
}
|
||||
|
||||
if (ieee->iw_mode == IW_MODE_INFRA)
|
||||
{
|
||||
tcb_desc->bAMPDUEnable = true;
|
||||
tcb_desc->ampdu_factor = pHTInfo->CurrentAMPDUFactor;
|
||||
tcb_desc->ampdu_density = pHTInfo->CurrentMPDUDensity;
|
||||
}
|
||||
}
|
||||
FORCED_AGG_SETTING:
|
||||
switch(pHTInfo->ForcedAMPDUMode )
|
||||
{
|
||||
case HT_AGG_AUTO:
|
||||
break;
|
||||
|
||||
case HT_AGG_FORCE_ENABLE:
|
||||
tcb_desc->bAMPDUEnable = true;
|
||||
tcb_desc->ampdu_density = pHTInfo->ForcedMPDUDensity;
|
||||
tcb_desc->ampdu_factor = pHTInfo->ForcedAMPDUFactor;
|
||||
break;
|
||||
|
||||
case HT_AGG_FORCE_DISABLE:
|
||||
tcb_desc->bAMPDUEnable = false;
|
||||
tcb_desc->ampdu_density = 0;
|
||||
tcb_desc->ampdu_factor = 0;
|
||||
break;
|
||||
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
extern void ieee80211_qurey_ShortPreambleMode(struct ieee80211_device* ieee, cb_desc* tcb_desc)
|
||||
{
|
||||
tcb_desc->bUseShortPreamble = false;
|
||||
if (tcb_desc->data_rate == 2)
|
||||
{//// 1M can only use Long Preamble. 11B spec
|
||||
return;
|
||||
}
|
||||
else if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
|
||||
{
|
||||
tcb_desc->bUseShortPreamble = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
extern void
|
||||
ieee80211_query_HTCapShortGI(struct ieee80211_device *ieee, cb_desc *tcb_desc)
|
||||
{
|
||||
PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
|
||||
|
||||
tcb_desc->bUseShortGI = false;
|
||||
|
||||
if(!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
|
||||
return;
|
||||
|
||||
if(pHTInfo->bForcedShortGI)
|
||||
{
|
||||
tcb_desc->bUseShortGI = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if((pHTInfo->bCurBW40MHz==true) && pHTInfo->bCurShortGI40MHz)
|
||||
tcb_desc->bUseShortGI = true;
|
||||
else if((pHTInfo->bCurBW40MHz==false) && pHTInfo->bCurShortGI20MHz)
|
||||
tcb_desc->bUseShortGI = true;
|
||||
}
|
||||
|
||||
void ieee80211_query_BandwidthMode(struct ieee80211_device* ieee, cb_desc *tcb_desc)
|
||||
{
|
||||
PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
|
||||
|
||||
tcb_desc->bPacketBW = false;
|
||||
|
||||
if(!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
|
||||
return;
|
||||
|
||||
if(tcb_desc->bMulticast || tcb_desc->bBroadcast)
|
||||
return;
|
||||
|
||||
if((tcb_desc->data_rate & 0x80)==0) // If using legacy rate, it shall use 20MHz channel.
|
||||
return;
|
||||
//BandWidthAutoSwitch is for auto switch to 20 or 40 in long distance
|
||||
if(pHTInfo->bCurBW40MHz && pHTInfo->bCurTxBW40MHz && !ieee->bandwidth_auto_switch.bforced_tx20Mhz)
|
||||
tcb_desc->bPacketBW = true;
|
||||
return;
|
||||
}
|
||||
|
||||
void ieee80211_query_protectionmode(struct ieee80211_device* ieee, cb_desc* tcb_desc, struct sk_buff* skb)
|
||||
{
|
||||
// Common Settings
|
||||
tcb_desc->bRTSSTBC = false;
|
||||
tcb_desc->bRTSUseShortGI = false; // Since protection frames are always sent by legacy rate, ShortGI will never be used.
|
||||
tcb_desc->bCTSEnable = false; // Most of protection using RTS/CTS
|
||||
tcb_desc->RTSSC = 0; // 20MHz: Don't care; 40MHz: Duplicate.
|
||||
tcb_desc->bRTSBW = false; // RTS frame bandwidth is always 20MHz
|
||||
|
||||
if(tcb_desc->bBroadcast || tcb_desc->bMulticast)//only unicast frame will use rts/cts
|
||||
return;
|
||||
|
||||
if (is_broadcast_ether_addr(skb->data+16)) //check addr3 as infrastructure add3 is DA.
|
||||
return;
|
||||
|
||||
if (ieee->mode < IEEE_N_24G) //b, g mode
|
||||
{
|
||||
// (1) RTS_Threshold is compared to the MPDU, not MSDU.
|
||||
// (2) If there are more than one frag in this MSDU, only the first frag uses protection frame.
|
||||
// Other fragments are protected by previous fragment.
|
||||
// So we only need to check the length of first fragment.
|
||||
if (skb->len > ieee->rts)
|
||||
{
|
||||
tcb_desc->bRTSEnable = true;
|
||||
tcb_desc->rts_rate = MGN_24M;
|
||||
}
|
||||
else if (ieee->current_network.buseprotection)
|
||||
{
|
||||
// Use CTS-to-SELF in protection mode.
|
||||
tcb_desc->bRTSEnable = true;
|
||||
tcb_desc->bCTSEnable = true;
|
||||
tcb_desc->rts_rate = MGN_24M;
|
||||
}
|
||||
//otherwise return;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{// 11n High throughput case.
|
||||
PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
|
||||
while (true)
|
||||
{
|
||||
//check IOT action
|
||||
if(pHTInfo->IOTAction & HT_IOT_ACT_FORCED_CTS2SELF)
|
||||
{
|
||||
tcb_desc->bCTSEnable = true;
|
||||
tcb_desc->rts_rate = MGN_24M;
|
||||
tcb_desc->bRTSEnable = false;
|
||||
break;
|
||||
}
|
||||
else if(pHTInfo->IOTAction & (HT_IOT_ACT_FORCED_RTS|HT_IOT_ACT_PURE_N_MODE))
|
||||
{
|
||||
tcb_desc->bRTSEnable = true;
|
||||
tcb_desc->rts_rate = MGN_24M;
|
||||
break;
|
||||
}
|
||||
//check ERP protection
|
||||
if (ieee->current_network.buseprotection)
|
||||
{// CTS-to-SELF
|
||||
tcb_desc->bRTSEnable = true;
|
||||
tcb_desc->bCTSEnable = true;
|
||||
tcb_desc->rts_rate = MGN_24M;
|
||||
break;
|
||||
}
|
||||
//check HT op mode
|
||||
if(pHTInfo->bCurrentHTSupport && pHTInfo->bEnableHT)
|
||||
{
|
||||
u8 HTOpMode = pHTInfo->CurrentOpMode;
|
||||
if((pHTInfo->bCurBW40MHz && (HTOpMode == 2 || HTOpMode == 3)) ||
|
||||
(!pHTInfo->bCurBW40MHz && HTOpMode == 3) )
|
||||
{
|
||||
tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
|
||||
tcb_desc->bRTSEnable = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//check rts
|
||||
if (skb->len > ieee->rts)
|
||||
{
|
||||
tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
|
||||
tcb_desc->bRTSEnable = true;
|
||||
break;
|
||||
}
|
||||
//to do list: check MIMO power save condition.
|
||||
//check AMPDU aggregation for TXOP
|
||||
if(tcb_desc->bAMPDUEnable)
|
||||
{
|
||||
tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
|
||||
// According to 8190 design, firmware sends CF-End only if RTS/CTS is enabled. However, it degrads
|
||||
// throughput around 10M, so we disable of this mechanism. 2007.08.03 by Emily
|
||||
tcb_desc->bRTSEnable = false;
|
||||
break;
|
||||
}
|
||||
// Totally no protection case!!
|
||||
goto NO_PROTECTION;
|
||||
}
|
||||
}
|
||||
// For test , CTS replace with RTS
|
||||
if( 0 )
|
||||
{
|
||||
tcb_desc->bCTSEnable = true;
|
||||
tcb_desc->rts_rate = MGN_24M;
|
||||
tcb_desc->bRTSEnable = true;
|
||||
}
|
||||
if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
|
||||
tcb_desc->bUseShortPreamble = true;
|
||||
if (ieee->mode == IW_MODE_MASTER)
|
||||
goto NO_PROTECTION;
|
||||
return;
|
||||
NO_PROTECTION:
|
||||
tcb_desc->bRTSEnable = false;
|
||||
tcb_desc->bCTSEnable = false;
|
||||
tcb_desc->rts_rate = 0;
|
||||
tcb_desc->RTSSC = 0;
|
||||
tcb_desc->bRTSBW = false;
|
||||
}
|
||||
|
||||
|
||||
void ieee80211_txrate_selectmode(struct ieee80211_device* ieee, cb_desc* tcb_desc)
|
||||
{
|
||||
#ifdef TO_DO_LIST
|
||||
if(!IsDataFrame(pFrame))
|
||||
{
|
||||
pTcb->bTxDisableRateFallBack = TRUE;
|
||||
pTcb->bTxUseDriverAssingedRate = TRUE;
|
||||
pTcb->RATRIndex = 7;
|
||||
return;
|
||||
}
|
||||
|
||||
if(pMgntInfo->ForcedDataRate!= 0)
|
||||
{
|
||||
pTcb->bTxDisableRateFallBack = TRUE;
|
||||
pTcb->bTxUseDriverAssingedRate = TRUE;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if(ieee->bTxDisableRateFallBack)
|
||||
tcb_desc->bTxDisableRateFallBack = true;
|
||||
|
||||
if(ieee->bTxUseDriverAssingedRate)
|
||||
tcb_desc->bTxUseDriverAssingedRate = true;
|
||||
if(!tcb_desc->bTxDisableRateFallBack || !tcb_desc->bTxUseDriverAssingedRate)
|
||||
{
|
||||
if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
|
||||
tcb_desc->RATRIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ieee80211_query_seqnum(struct ieee80211_device*ieee, struct sk_buff* skb, u8* dst)
|
||||
{
|
||||
if (is_multicast_ether_addr(dst) || is_broadcast_ether_addr(dst))
|
||||
return;
|
||||
if (IsQoSDataFrame(skb->data)) //we deal qos data only
|
||||
{
|
||||
PTX_TS_RECORD pTS = NULL;
|
||||
if (!GetTs(ieee, (PTS_COMMON_INFO*)(&pTS), dst, skb->priority, TX_DIR, true))
|
||||
{
|
||||
return;
|
||||
}
|
||||
pTS->TxCurSeq = (pTS->TxCurSeq+1)%4096;
|
||||
}
|
||||
}
|
||||
|
||||
int rtl8192_ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
{
|
||||
struct ieee80211_device *ieee = netdev_priv(dev);
|
||||
struct ieee80211_txb *txb = NULL;
|
||||
struct ieee80211_hdr_3addrqos *frag_hdr;
|
||||
int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
|
||||
unsigned long flags;
|
||||
struct net_device_stats *stats = &ieee->stats;
|
||||
int ether_type = 0, encrypt;
|
||||
int bytes, fc, qos_ctl = 0, hdr_len;
|
||||
struct sk_buff *skb_frag;
|
||||
struct ieee80211_hdr_3addrqos header = { /* Ensure zero initialized */
|
||||
.duration_id = 0,
|
||||
.seq_ctl = 0,
|
||||
.qos_ctl = 0
|
||||
};
|
||||
u8 dest[ETH_ALEN], src[ETH_ALEN];
|
||||
int qos_actived = ieee->current_network.qos_data.active;
|
||||
|
||||
struct ieee80211_crypt_data* crypt;
|
||||
|
||||
cb_desc *tcb_desc;
|
||||
|
||||
spin_lock_irqsave(&ieee->lock, flags);
|
||||
|
||||
/* If there is no driver handler to take the TXB, dont' bother
|
||||
* creating it... */
|
||||
if ((!ieee->hard_start_xmit && !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE))||
|
||||
((!ieee->softmac_data_hard_start_xmit && (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) {
|
||||
printk(KERN_WARNING "%s: No xmit handler.\n",
|
||||
ieee->dev->name);
|
||||
goto success;
|
||||
}
|
||||
|
||||
|
||||
if(likely(ieee->raw_tx == 0)){
|
||||
if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
|
||||
printk(KERN_WARNING "%s: skb too small (%d).\n",
|
||||
ieee->dev->name, skb->len);
|
||||
goto success;
|
||||
}
|
||||
|
||||
memset(skb->cb, 0, sizeof(skb->cb));
|
||||
ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
|
||||
|
||||
crypt = ieee->crypt[ieee->tx_keyidx];
|
||||
|
||||
encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
|
||||
ieee->host_encrypt && crypt && crypt->ops;
|
||||
|
||||
if (!encrypt && ieee->ieee802_1x &&
|
||||
ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
|
||||
stats->tx_dropped++;
|
||||
goto success;
|
||||
}
|
||||
#ifdef CONFIG_IEEE80211_DEBUG
|
||||
if (crypt && !encrypt && ether_type == ETH_P_PAE) {
|
||||
struct eapol *eap = (struct eapol *)(skb->data +
|
||||
sizeof(struct ethhdr) - SNAP_SIZE - sizeof(u16));
|
||||
IEEE80211_DEBUG_EAP("TX: IEEE 802.11 EAPOL frame: %s\n",
|
||||
eap_get_type(eap->type));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Save source and destination addresses */
|
||||
memcpy(&dest, skb->data, ETH_ALEN);
|
||||
memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN);
|
||||
|
||||
/* Advance the SKB to the start of the payload */
|
||||
skb_pull(skb, sizeof(struct ethhdr));
|
||||
|
||||
/* Determine total amount of storage required for TXB packets */
|
||||
bytes = skb->len + SNAP_SIZE + sizeof(u16);
|
||||
|
||||
if (encrypt)
|
||||
fc = IEEE80211_FTYPE_DATA | IEEE80211_FCTL_WEP;
|
||||
else
|
||||
fc = IEEE80211_FTYPE_DATA;
|
||||
|
||||
if(qos_actived)
|
||||
fc |= IEEE80211_STYPE_QOS_DATA;
|
||||
else
|
||||
fc |= IEEE80211_STYPE_DATA;
|
||||
|
||||
if (ieee->iw_mode == IW_MODE_INFRA) {
|
||||
fc |= IEEE80211_FCTL_TODS;
|
||||
/* To DS: Addr1 = BSSID, Addr2 = SA,
|
||||
Addr3 = DA */
|
||||
memcpy(&header.addr1, ieee->current_network.bssid, ETH_ALEN);
|
||||
memcpy(&header.addr2, &src, ETH_ALEN);
|
||||
memcpy(&header.addr3, &dest, ETH_ALEN);
|
||||
} else if (ieee->iw_mode == IW_MODE_ADHOC) {
|
||||
/* not From/To DS: Addr1 = DA, Addr2 = SA,
|
||||
Addr3 = BSSID */
|
||||
memcpy(&header.addr1, dest, ETH_ALEN);
|
||||
memcpy(&header.addr2, src, ETH_ALEN);
|
||||
memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN);
|
||||
}
|
||||
|
||||
header.frame_ctl = cpu_to_le16(fc);
|
||||
|
||||
/* Determine fragmentation size based on destination (multicast
|
||||
* and broadcast are not fragmented) */
|
||||
if (is_multicast_ether_addr(header.addr1) ||
|
||||
is_broadcast_ether_addr(header.addr1)) {
|
||||
frag_size = MAX_FRAG_THRESHOLD;
|
||||
qos_ctl |= QOS_CTL_NOTCONTAIN_ACK;
|
||||
}
|
||||
else {
|
||||
frag_size = ieee->fts;//default:392
|
||||
qos_ctl = 0;
|
||||
}
|
||||
|
||||
//if (ieee->current_network.QoS_Enable)
|
||||
if(qos_actived)
|
||||
{
|
||||
hdr_len = IEEE80211_3ADDR_LEN + 2;
|
||||
|
||||
skb->priority = ieee80211_classify(skb, &ieee->current_network);
|
||||
qos_ctl |= skb->priority; //set in the ieee80211_classify
|
||||
header.qos_ctl = cpu_to_le16(qos_ctl & IEEE80211_QOS_TID);
|
||||
} else {
|
||||
hdr_len = IEEE80211_3ADDR_LEN;
|
||||
}
|
||||
/* Determine amount of payload per fragment. Regardless of if
|
||||
* this stack is providing the full 802.11 header, one will
|
||||
* eventually be affixed to this fragment -- so we must account for
|
||||
* it when determining the amount of payload space. */
|
||||
bytes_per_frag = frag_size - hdr_len;
|
||||
if (ieee->config &
|
||||
(CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
|
||||
bytes_per_frag -= IEEE80211_FCS_LEN;
|
||||
|
||||
/* Each fragment may need to have room for encryptiong pre/postfix */
|
||||
if (encrypt)
|
||||
bytes_per_frag -= crypt->ops->extra_prefix_len +
|
||||
crypt->ops->extra_postfix_len;
|
||||
|
||||
/* Number of fragments is the total bytes_per_frag /
|
||||
* payload_per_fragment */
|
||||
nr_frags = bytes / bytes_per_frag;
|
||||
bytes_last_frag = bytes % bytes_per_frag;
|
||||
if (bytes_last_frag)
|
||||
nr_frags++;
|
||||
else
|
||||
bytes_last_frag = bytes_per_frag;
|
||||
|
||||
/* When we allocate the TXB we allocate enough space for the reserve
|
||||
* and full fragment bytes (bytes_per_frag doesn't include prefix,
|
||||
* postfix, header, FCS, etc.) */
|
||||
txb = ieee80211_alloc_txb(nr_frags, frag_size + ieee->tx_headroom, GFP_ATOMIC);
|
||||
if (unlikely(!txb)) {
|
||||
printk(KERN_WARNING "%s: Could not allocate TXB\n",
|
||||
ieee->dev->name);
|
||||
goto failed;
|
||||
}
|
||||
txb->encrypted = encrypt;
|
||||
txb->payload_size = bytes;
|
||||
|
||||
if(qos_actived)
|
||||
{
|
||||
txb->queue_index = UP2AC(skb->priority);
|
||||
} else {
|
||||
txb->queue_index = WME_AC_BK;;
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (i = 0; i < nr_frags; i++) {
|
||||
skb_frag = txb->fragments[i];
|
||||
tcb_desc = (cb_desc *)(skb_frag->cb + MAX_DEV_ADDR_SIZE);
|
||||
if(qos_actived){
|
||||
skb_frag->priority = skb->priority;//UP2AC(skb->priority);
|
||||
tcb_desc->queue_index = UP2AC(skb->priority);
|
||||
} else {
|
||||
skb_frag->priority = WME_AC_BK;
|
||||
tcb_desc->queue_index = WME_AC_BK;
|
||||
}
|
||||
skb_reserve(skb_frag, ieee->tx_headroom);
|
||||
|
||||
if (encrypt){
|
||||
if (ieee->hwsec_active)
|
||||
tcb_desc->bHwSec = 1;
|
||||
else
|
||||
tcb_desc->bHwSec = 0;
|
||||
skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
tcb_desc->bHwSec = 0;
|
||||
}
|
||||
frag_hdr = (struct ieee80211_hdr_3addrqos *)skb_put(skb_frag, hdr_len);
|
||||
memcpy(frag_hdr, &header, hdr_len);
|
||||
|
||||
/* If this is not the last fragment, then add the MOREFRAGS
|
||||
* bit to the frame control */
|
||||
if (i != nr_frags - 1) {
|
||||
frag_hdr->frame_ctl = cpu_to_le16(
|
||||
fc | IEEE80211_FCTL_MOREFRAGS);
|
||||
bytes = bytes_per_frag;
|
||||
|
||||
} else {
|
||||
/* The last fragment takes the remaining length */
|
||||
bytes = bytes_last_frag;
|
||||
}
|
||||
if(qos_actived)
|
||||
{
|
||||
// add 1 only indicate to corresponding seq number control 2006/7/12
|
||||
frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[UP2AC(skb->priority)+1]<<4 | i);
|
||||
} else {
|
||||
frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i);
|
||||
}
|
||||
|
||||
/* Put a SNAP header on the first fragment */
|
||||
if (i == 0) {
|
||||
ieee80211_put_snap(
|
||||
skb_put(skb_frag, SNAP_SIZE + sizeof(u16)),
|
||||
ether_type);
|
||||
bytes -= SNAP_SIZE + sizeof(u16);
|
||||
}
|
||||
|
||||
memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
|
||||
|
||||
/* Advance the SKB... */
|
||||
skb_pull(skb, bytes);
|
||||
|
||||
/* Encryption routine will move the header forward in order
|
||||
* to insert the IV between the header and the payload */
|
||||
if (encrypt)
|
||||
ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
|
||||
if (ieee->config &
|
||||
(CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
|
||||
skb_put(skb_frag, 4);
|
||||
}
|
||||
|
||||
if(qos_actived)
|
||||
{
|
||||
if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF)
|
||||
ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0;
|
||||
else
|
||||
ieee->seq_ctrl[UP2AC(skb->priority) + 1]++;
|
||||
} else {
|
||||
if (ieee->seq_ctrl[0] == 0xFFF)
|
||||
ieee->seq_ctrl[0] = 0;
|
||||
else
|
||||
ieee->seq_ctrl[0]++;
|
||||
}
|
||||
}else{
|
||||
if (unlikely(skb->len < sizeof(struct ieee80211_hdr_3addr))) {
|
||||
printk(KERN_WARNING "%s: skb too small (%d).\n",
|
||||
ieee->dev->name, skb->len);
|
||||
goto success;
|
||||
}
|
||||
|
||||
txb = ieee80211_alloc_txb(1, skb->len, GFP_ATOMIC);
|
||||
if(!txb){
|
||||
printk(KERN_WARNING "%s: Could not allocate TXB\n",
|
||||
ieee->dev->name);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
txb->encrypted = 0;
|
||||
txb->payload_size = skb->len;
|
||||
memcpy(skb_put(txb->fragments[0],skb->len), skb->data, skb->len);
|
||||
}
|
||||
|
||||
success:
|
||||
//WB add to fill data tcb_desc here. only first fragment is considered, need to change, and you may remove to other place.
|
||||
if (txb)
|
||||
{
|
||||
#if 1
|
||||
cb_desc *tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
|
||||
tcb_desc->bTxEnableFwCalcDur = 1;
|
||||
if (is_multicast_ether_addr(header.addr1))
|
||||
tcb_desc->bMulticast = 1;
|
||||
if (is_broadcast_ether_addr(header.addr1))
|
||||
tcb_desc->bBroadcast = 1;
|
||||
ieee80211_txrate_selectmode(ieee, tcb_desc);
|
||||
if ( tcb_desc->bMulticast || tcb_desc->bBroadcast)
|
||||
tcb_desc->data_rate = ieee->basic_rate;
|
||||
else
|
||||
tcb_desc->data_rate = CURRENT_RATE(ieee->mode, ieee->rate, ieee->HTCurrentOperaRate);
|
||||
ieee80211_qurey_ShortPreambleMode(ieee, tcb_desc);
|
||||
ieee80211_tx_query_agg_cap(ieee, txb->fragments[0], tcb_desc);
|
||||
ieee80211_query_HTCapShortGI(ieee, tcb_desc);
|
||||
ieee80211_query_BandwidthMode(ieee, tcb_desc);
|
||||
ieee80211_query_protectionmode(ieee, tcb_desc, txb->fragments[0]);
|
||||
ieee80211_query_seqnum(ieee, txb->fragments[0], header.addr1);
|
||||
#endif
|
||||
}
|
||||
spin_unlock_irqrestore(&ieee->lock, flags);
|
||||
dev_kfree_skb_any(skb);
|
||||
if (txb) {
|
||||
if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE){
|
||||
ieee80211_softmac_xmit(txb, ieee);
|
||||
}else{
|
||||
if ((*ieee->hard_start_xmit)(txb, dev) == 0) {
|
||||
stats->tx_packets++;
|
||||
stats->tx_bytes += txb->payload_size;
|
||||
return 0;
|
||||
}
|
||||
ieee80211_txb_free(txb);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
spin_unlock_irqrestore(&ieee->lock, flags);
|
||||
netif_stop_queue(dev);
|
||||
stats->tx_errors++;
|
||||
return 1;
|
||||
|
||||
}
|
|
@ -1,772 +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/wireless.h>
|
||||
#include <linux/kmod.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "ieee80211.h"
|
||||
|
||||
struct modes_unit {
|
||||
char *mode_string;
|
||||
int mode_size;
|
||||
};
|
||||
struct modes_unit ieee80211_modes[] = {
|
||||
{"a",1},
|
||||
{"b",1},
|
||||
{"g",1},
|
||||
{"?",1},
|
||||
{"N-24G",5},
|
||||
{"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,
|
||||
char *start, char *stop,
|
||||
struct ieee80211_network *network,
|
||||
struct iw_request_info *info)
|
||||
{
|
||||
char custom[MAX_CUSTOM_LEN];
|
||||
char proto_name[IFNAMSIZ];
|
||||
char *pname = proto_name;
|
||||
char *p;
|
||||
struct iw_event iwe;
|
||||
int i, j;
|
||||
u16 max_rate, rate;
|
||||
static u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33};
|
||||
|
||||
/* First entry *MUST* be the AP MAC address */
|
||||
iwe.cmd = SIOCGIWAP;
|
||||
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
|
||||
memcpy(iwe.u.ap_addr.sa_data, network->bssid, ETH_ALEN);
|
||||
start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_ADDR_LEN);
|
||||
|
||||
/* Remaining entries will be displayed in the order we provide them */
|
||||
|
||||
/* Add the ESSID */
|
||||
iwe.cmd = SIOCGIWESSID;
|
||||
iwe.u.data.flags = 1;
|
||||
if (network->ssid_len == 0) {
|
||||
iwe.u.data.length = sizeof("<hidden>");
|
||||
start = iwe_stream_add_point(info, start, stop, &iwe, "<hidden>");
|
||||
} else {
|
||||
iwe.u.data.length = min(network->ssid_len, (u8)32);
|
||||
start = iwe_stream_add_point(info, start, stop, &iwe, network->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;
|
||||
}
|
||||
}
|
||||
*pname = '\0';
|
||||
snprintf(iwe.u.name, IFNAMSIZ, "IEEE802.11%s", proto_name);
|
||||
start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_CHAR_LEN);
|
||||
/* Add mode */
|
||||
iwe.cmd = SIOCGIWMODE;
|
||||
if (network->capability &
|
||||
(WLAN_CAPABILITY_BSS | WLAN_CAPABILITY_IBSS)) {
|
||||
if (network->capability & WLAN_CAPABILITY_BSS)
|
||||
iwe.u.mode = IW_MODE_MASTER;
|
||||
else
|
||||
iwe.u.mode = IW_MODE_ADHOC;
|
||||
start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_UINT_LEN);
|
||||
}
|
||||
|
||||
/* Add frequency/channel */
|
||||
iwe.cmd = SIOCGIWFREQ;
|
||||
/* iwe.u.freq.m = ieee80211_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)
|
||||
iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
|
||||
else
|
||||
iwe.u.data.flags = IW_ENCODE_DISABLED;
|
||||
iwe.u.data.length = 0;
|
||||
start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
|
||||
/* Add basic and extended rates */
|
||||
max_rate = 0;
|
||||
p = custom;
|
||||
p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
|
||||
for (i = 0, j = 0; i < network->rates_len; ) {
|
||||
if (j < network->rates_ex_len &&
|
||||
((network->rates_ex[j] & 0x7F) <
|
||||
(network->rates[i] & 0x7F)))
|
||||
rate = network->rates_ex[j++] & 0x7F;
|
||||
else
|
||||
rate = network->rates[i++] & 0x7F;
|
||||
if (rate > max_rate)
|
||||
max_rate = rate;
|
||||
p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
|
||||
"%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
|
||||
}
|
||||
for (; j < network->rates_ex_len; j++) {
|
||||
rate = network->rates_ex[j] & 0x7F;
|
||||
p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
|
||||
"%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
|
||||
if (rate > max_rate)
|
||||
max_rate = rate;
|
||||
}
|
||||
|
||||
if (network->mode >= IEEE_N_24G)//add N rate here;
|
||||
{
|
||||
PHT_CAPABILITY_ELE ht_cap = NULL;
|
||||
bool is40M = false, isShortGI = false;
|
||||
u8 max_mcs = 0;
|
||||
if (!memcmp(network->bssht.bdHTCapBuf, EWC11NHTCap, 4))
|
||||
ht_cap = (PHT_CAPABILITY_ELE)&network->bssht.bdHTCapBuf[4];
|
||||
else
|
||||
ht_cap = (PHT_CAPABILITY_ELE)&network->bssht.bdHTCapBuf[0];
|
||||
is40M = (ht_cap->ChlWidth)?1:0;
|
||||
isShortGI = (ht_cap->ChlWidth)?
|
||||
((ht_cap->ShortGI40Mhz)?1:0):
|
||||
((ht_cap->ShortGI20Mhz)?1:0);
|
||||
|
||||
max_mcs = HTGetHighestMCSRate(ieee, ht_cap->MCS, MCS_FILTER_ALL);
|
||||
rate = MCS_DATA_RATE[is40M][isShortGI][max_mcs&0x7f];
|
||||
if (rate > max_rate)
|
||||
max_rate = rate;
|
||||
}
|
||||
|
||||
iwe.cmd = SIOCGIWRATE;
|
||||
iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
|
||||
iwe.u.bitrate.value = max_rate * 500000;
|
||||
start = iwe_stream_add_event_rsl(info, start, stop, &iwe,
|
||||
IW_EV_PARAM_LEN);
|
||||
|
||||
iwe.cmd = IWEVCUSTOM;
|
||||
iwe.u.data.length = p - custom;
|
||||
if (iwe.u.data.length)
|
||||
start = iwe_stream_add_point(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 |= IW_QUAL_LEVEL_INVALID;
|
||||
if (!(network->stats.mask & IEEE80211_STATMASK_NOISE))
|
||||
iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID;
|
||||
if (!(network->stats.mask & IEEE80211_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);
|
||||
|
||||
memset(&iwe, 0, sizeof(iwe));
|
||||
if (network->wpa_ie_len)
|
||||
{
|
||||
char buf[MAX_WPA_IE_LEN];
|
||||
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);
|
||||
}
|
||||
memset(&iwe, 0, sizeof(iwe));
|
||||
if (network->rsn_ie_len)
|
||||
{
|
||||
char buf[MAX_WPA_IE_LEN];
|
||||
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);
|
||||
}
|
||||
|
||||
/* Add EXTRA: Age to display seconds since last beacon/probe response
|
||||
* for given network. */
|
||||
iwe.cmd = IWEVCUSTOM;
|
||||
p = custom;
|
||||
p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
|
||||
" 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);
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
|
||||
struct iw_request_info *info,
|
||||
union iwreq_data *wrqu, char *extra)
|
||||
{
|
||||
struct ieee80211_network *network;
|
||||
unsigned long flags;
|
||||
|
||||
char *ev = extra;
|
||||
char *stop = ev + wrqu->data.length;//IW_SCAN_MAX_DATA;
|
||||
int i = 0;
|
||||
int err = 0;
|
||||
IEEE80211_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)
|
||||
{
|
||||
err = -E2BIG;
|
||||
break;
|
||||
}
|
||||
if (ieee->scan_age == 0 ||
|
||||
time_after(network->last_scanned + ieee->scan_age, jiffies))
|
||||
ev = rtl819x_translate_scan(ieee, ev, stop, network, info);
|
||||
else
|
||||
IEEE80211_DEBUG_SCAN(
|
||||
"Not showing network '%s ("
|
||||
"%pM)' due to age (%lums).\n",
|
||||
escape_essid(network->ssid,
|
||||
network->ssid_len),
|
||||
network->bssid,
|
||||
(jiffies - network->last_scanned) / (HZ / 100));
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&ieee->lock, flags);
|
||||
up(&ieee->wx_sem);
|
||||
wrqu->data.length = ev - extra;
|
||||
wrqu->data.flags = 0;
|
||||
|
||||
IEEE80211_DEBUG_WX("exit: %d networks returned.\n", i);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int ieee80211_wx_set_encode(struct ieee80211_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 = {
|
||||
.flags = 0
|
||||
};
|
||||
int i, key, key_provided, len;
|
||||
struct ieee80211_crypt_data **crypt;
|
||||
|
||||
IEEE80211_DEBUG_WX("SET_ENCODE\n");
|
||||
|
||||
key = erq->flags & IW_ENCODE_INDEX;
|
||||
if (key) {
|
||||
if (key > WEP_KEYS)
|
||||
return -EINVAL;
|
||||
key--;
|
||||
key_provided = 1;
|
||||
} else {
|
||||
key_provided = 0;
|
||||
key = ieee->tx_keyidx;
|
||||
}
|
||||
|
||||
IEEE80211_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",
|
||||
key);
|
||||
ieee80211_crypt_delayed_deinit(ieee, crypt);
|
||||
} else
|
||||
IEEE80211_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 */
|
||||
for (i = 0; i < WEP_KEYS; i++) {
|
||||
if (ieee->crypt[i] != NULL) {
|
||||
if (key_provided)
|
||||
break;
|
||||
ieee80211_crypt_delayed_deinit(
|
||||
ieee, &ieee->crypt[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (i == WEP_KEYS) {
|
||||
sec.enabled = 0;
|
||||
sec.level = SEC_LEVEL_0;
|
||||
sec.flags |= SEC_ENABLED | SEC_LEVEL;
|
||||
}
|
||||
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
||||
|
||||
sec.enabled = 1;
|
||||
sec.flags |= SEC_ENABLED;
|
||||
|
||||
if (*crypt != NULL && (*crypt)->ops != NULL &&
|
||||
strcmp((*crypt)->ops->name, "WEP") != 0) {
|
||||
/* changing to use WEP; deinit previously used algorithm
|
||||
* on this key */
|
||||
ieee80211_crypt_delayed_deinit(ieee, crypt);
|
||||
}
|
||||
|
||||
if (*crypt == NULL) {
|
||||
struct ieee80211_crypt_data *new_crypt;
|
||||
|
||||
/* take WEP into use */
|
||||
new_crypt = kzalloc(sizeof(struct ieee80211_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");
|
||||
if (new_crypt->ops)
|
||||
new_crypt->priv = new_crypt->ops->init(key);
|
||||
|
||||
if (!new_crypt->ops || !new_crypt->priv) {
|
||||
kfree(new_crypt);
|
||||
new_crypt = NULL;
|
||||
|
||||
printk(KERN_WARNING "%s: could not initialize WEP: "
|
||||
"load module ieee80211_crypt_wep\n",
|
||||
dev->name);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
*crypt = new_crypt;
|
||||
}
|
||||
|
||||
/* If a new key was provided, set it up */
|
||||
if (erq->length > 0) {
|
||||
len = erq->length <= 5 ? 5 : 13;
|
||||
memcpy(sec.keys[key], keybuf, erq->length);
|
||||
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",
|
||||
key, escape_essid(sec.keys[key], len),
|
||||
erq->length, len);
|
||||
sec.key_sizes[key] = len;
|
||||
(*crypt)->ops->set_key(sec.keys[key], len, NULL,
|
||||
(*crypt)->priv);
|
||||
sec.flags |= (1 << key);
|
||||
/* This ensures a key will be activated if no key is
|
||||
* explicitely set */
|
||||
if (key == sec.active_key)
|
||||
sec.flags |= SEC_ACTIVE_KEY;
|
||||
ieee->tx_keyidx = key;
|
||||
|
||||
} else {
|
||||
len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,
|
||||
NULL, (*crypt)->priv);
|
||||
if (len == 0) {
|
||||
/* Set a default key of all 0 */
|
||||
printk("Setting key %d to all zero.\n",
|
||||
key);
|
||||
|
||||
IEEE80211_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,
|
||||
(*crypt)->priv);
|
||||
sec.key_sizes[key] = 13;
|
||||
sec.flags |= (1 << key);
|
||||
}
|
||||
|
||||
/* No key data - just set the default TX key index */
|
||||
if (key_provided) {
|
||||
IEEE80211_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 ?
|
||||
"OPEN" : "SHARED KEY");
|
||||
|
||||
/* For now we just support WEP, so only set that security level...
|
||||
* TODO: When WPA is added this is one place that needs to change */
|
||||
sec.flags |= SEC_LEVEL;
|
||||
sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */
|
||||
|
||||
if (ieee->set_security)
|
||||
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
|
||||
* with IEEE 802.1X. If your hardware requires a reset after WEP
|
||||
* configuration (for example... Prism2), implement the reset_port in
|
||||
* 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(dev)) {
|
||||
printk(KERN_DEBUG "%s: reset_port failed\n", dev->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ieee80211_wx_get_encode(struct ieee80211_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;
|
||||
|
||||
IEEE80211_DEBUG_WX("GET_ENCODE\n");
|
||||
|
||||
if(ieee->iw_mode == IW_MODE_MONITOR)
|
||||
return -1;
|
||||
|
||||
key = erq->flags & IW_ENCODE_INDEX;
|
||||
if (key) {
|
||||
if (key > WEP_KEYS)
|
||||
return -EINVAL;
|
||||
key--;
|
||||
} else
|
||||
key = ieee->tx_keyidx;
|
||||
|
||||
crypt = ieee->crypt[key];
|
||||
erq->flags = key + 1;
|
||||
|
||||
if (crypt == NULL || crypt->ops == NULL) {
|
||||
erq->length = 0;
|
||||
erq->flags |= IW_ENCODE_DISABLED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = crypt->ops->get_key(keybuf, SCM_KEY_LEN, NULL, crypt->priv);
|
||||
erq->length = (len >= 0 ? len : 0);
|
||||
|
||||
erq->flags |= IW_ENCODE_ENABLED;
|
||||
|
||||
if (ieee->open_wep)
|
||||
erq->flags |= IW_ENCODE_OPEN;
|
||||
else
|
||||
erq->flags |= IW_ENCODE_RESTRICTED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
|
||||
struct iw_request_info *info,
|
||||
union iwreq_data *wrqu, char *extra)
|
||||
{
|
||||
int ret = 0;
|
||||
struct net_device *dev = ieee->dev;
|
||||
struct iw_point *encoding = &wrqu->encoding;
|
||||
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;
|
||||
|
||||
struct ieee80211_security sec = {
|
||||
.flags = 0,
|
||||
};
|
||||
idx = encoding->flags & IW_ENCODE_INDEX;
|
||||
if (idx) {
|
||||
if (idx < 1 || idx > WEP_KEYS)
|
||||
return -EINVAL;
|
||||
idx--;
|
||||
} 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 */
|
||||
//printk("not group key, flags:%x, ext->alg:%d\n", ext->ext_flags, ext->alg);
|
||||
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;
|
||||
|
||||
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++)
|
||||
|
||||
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;
|
||||
}
|
||||
//printk("disabled: flag:%x\n", encoding->flags);
|
||||
goto done;
|
||||
}
|
||||
|
||||
sec.enabled = 1;
|
||||
|
||||
switch (ext->alg) {
|
||||
case IW_ENCODE_ALG_WEP:
|
||||
alg = "WEP";
|
||||
break;
|
||||
case IW_ENCODE_ALG_TKIP:
|
||||
alg = "TKIP";
|
||||
break;
|
||||
case IW_ENCODE_ALG_CCMP:
|
||||
alg = "CCMP";
|
||||
break;
|
||||
default:
|
||||
IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
|
||||
dev->name, ext->alg);
|
||||
ret = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
IEEE80211_DEBUG_WX("alg name: %s\n", alg);
|
||||
|
||||
ops = ieee80211_get_crypto_ops(alg);
|
||||
if (ops == NULL)
|
||||
ops = ieee80211_get_crypto_ops(alg);
|
||||
if (ops == NULL) {
|
||||
IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
|
||||
dev->name, ext->alg);
|
||||
printk("========>unknown crypto alg %d\n", ext->alg);
|
||||
ret = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (*crypt == NULL || (*crypt)->ops != ops) {
|
||||
struct ieee80211_crypt_data *new_crypt;
|
||||
|
||||
ieee80211_crypt_delayed_deinit(ieee, crypt);
|
||||
|
||||
new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
|
||||
if (new_crypt == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
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;
|
||||
goto done;
|
||||
}
|
||||
*crypt = new_crypt;
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
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) {
|
||||
sec.key_sizes[idx] = ext->key_len;
|
||||
sec.flags |= (1 << idx);
|
||||
if (ext->alg == IW_ENCODE_ALG_WEP) {
|
||||
sec.flags |= SEC_LEVEL;
|
||||
sec.level = SEC_LEVEL_1;
|
||||
} else if (ext->alg == IW_ENCODE_ALG_TKIP) {
|
||||
sec.flags |= SEC_LEVEL;
|
||||
sec.level = SEC_LEVEL_2;
|
||||
} else if (ext->alg == IW_ENCODE_ALG_CCMP) {
|
||||
sec.flags |= SEC_LEVEL;
|
||||
sec.level = SEC_LEVEL_3;
|
||||
}
|
||||
/* Don't set sec level for group keys. */
|
||||
if (group_key)
|
||||
sec.flags &= ~SEC_LEVEL;
|
||||
}
|
||||
#endif
|
||||
done:
|
||||
if (ieee->set_security)
|
||||
ieee->set_security(ieee->dev, &sec);
|
||||
|
||||
if (ieee->reset_on_keychange &&
|
||||
ieee->iw_mode != IW_MODE_INFRA &&
|
||||
ieee->reset_port && ieee->reset_port(dev)) {
|
||||
IEEE80211_DEBUG_WX("%s: reset_port failed\n", dev->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
|
||||
struct iw_request_info *info,
|
||||
union iwreq_data *wrqu, char *extra)
|
||||
{
|
||||
struct iw_mlme *mlme = (struct iw_mlme *) extra;
|
||||
|
||||
switch (mlme->cmd) {
|
||||
case IW_MLME_DEAUTH:
|
||||
case IW_MLME_DISASSOC:
|
||||
ieee80211_disassociate(ieee);
|
||||
break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ieee80211_wx_set_auth(struct ieee80211_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.
|
||||
* */
|
||||
break;
|
||||
case IW_AUTH_TKIP_COUNTERMEASURES:
|
||||
ieee->tkip_countermeasures = data->value;
|
||||
break;
|
||||
case IW_AUTH_DROP_UNENCRYPTED:
|
||||
ieee->drop_unencrypted = data->value;
|
||||
break;
|
||||
|
||||
case IW_AUTH_80211_AUTH_ALG:
|
||||
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){
|
||||
ieee->open_wep = 1;
|
||||
ieee->auth_mode = 0;
|
||||
}
|
||||
else if(data->value & IW_AUTH_ALG_LEAP){
|
||||
ieee->open_wep = 1;
|
||||
ieee->auth_mode = 2;
|
||||
}
|
||||
else
|
||||
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;
|
||||
case IW_AUTH_PRIVACY_INVOKED:
|
||||
ieee->privacy_invoked = data->value;
|
||||
break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 1
|
||||
int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len)
|
||||
{
|
||||
u8 *buf;
|
||||
|
||||
if (len>MAX_WPA_IE_LEN || (len && ie == NULL))
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
if (len)
|
||||
{
|
||||
if (len != ie[1]+2)
|
||||
{
|
||||
printk("len: %Zd, ie:%d\n", len, ie[1]);
|
||||
return -EINVAL;
|
||||
}
|
||||
buf = kmemdup(ie, len, GFP_KERNEL);
|
||||
if (buf == NULL)
|
||||
return -ENOMEM;
|
||||
kfree(ieee->wpa_ie);
|
||||
ieee->wpa_ie = buf;
|
||||
ieee->wpa_ie_len = len;
|
||||
}
|
||||
else{
|
||||
if (ieee->wpa_ie)
|
||||
kfree(ieee->wpa_ie);
|
||||
ieee->wpa_ie = NULL;
|
||||
ieee->wpa_ie_len = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
#endif
|
|
@ -1,162 +0,0 @@
|
|||
What this layer should do
|
||||
|
||||
- It mantain the old mechanism as alternative, so the
|
||||
ipw2100 driver works with really few changes.
|
||||
- Encapsulate / Decapsulate ieee80211 packet
|
||||
- Handle fragmentation
|
||||
- Optionally provide an alterantive mechanism for netif queue stop/wake,
|
||||
so that the ieee80211 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.
|
||||
- Although 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 ieee80211.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:
|
||||
|
||||
ieee80211_get_beacon - this is called by the driver when
|
||||
the HW needs a beacon.
|
||||
ieee80211_softmac_start_protocol - this should normally be called in the
|
||||
driver open function
|
||||
ieee80211_softmac_stop_protocol - the opposite of the above
|
||||
ieee80211_wake_queue - this is similar to netif_wake_queue
|
||||
ieee80211_reset_queue - this throw away fragments pending(if any)
|
||||
ieee80211_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).
|
||||
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
/******************************************************************************
|
||||
* 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_
|
||||
|
||||
#define TOTAL_TXBA_NUM 16
|
||||
#define TOTAL_RXBA_NUM 16
|
||||
|
||||
#define BA_SETUP_TIMEOUT 200
|
||||
#define BA_INACT_TIMEOUT 60000
|
||||
|
||||
#define BA_POLICY_DELAYED 0
|
||||
#define BA_POLICY_IMMEDIATE 1
|
||||
|
||||
#define ADDBA_STATUS_SUCCESS 0
|
||||
#define ADDBA_STATUS_REFUSED 37
|
||||
#define ADDBA_STATUS_INVALID_PARAM 38
|
||||
|
||||
#define DELBA_REASON_QSTA_LEAVING 36
|
||||
#define DELBA_REASON_END_BA 37
|
||||
#define DELBA_REASON_UNKNOWN_BA 38
|
||||
#define DELBA_REASON_TIMEOUT 39
|
||||
|
||||
typedef union _SEQUENCE_CONTROL{
|
||||
u16 ShortData;
|
||||
struct
|
||||
{
|
||||
u16 FragNum:4;
|
||||
u16 SeqNum:12;
|
||||
}field;
|
||||
}SEQUENCE_CONTROL, *PSEQUENCE_CONTROL;
|
||||
|
||||
typedef union _BA_PARAM_SET {
|
||||
u8 charData[2];
|
||||
u16 shortData;
|
||||
struct {
|
||||
u16 AMSDU_Support:1;
|
||||
u16 BAPolicy:1;
|
||||
u16 TID:4;
|
||||
u16 BufferSize:10;
|
||||
} field;
|
||||
} BA_PARAM_SET, *PBA_PARAM_SET;
|
||||
|
||||
typedef union _DELBA_PARAM_SET {
|
||||
u8 charData[2];
|
||||
u16 shortData;
|
||||
struct {
|
||||
u16 Reserved:11;
|
||||
u16 Initiator:1;
|
||||
u16 TID:4;
|
||||
} field;
|
||||
} DELBA_PARAM_SET, *PDELBA_PARAM_SET;
|
||||
|
||||
typedef struct _BA_RECORD {
|
||||
struct timer_list Timer;
|
||||
u8 bValid;
|
||||
u8 DialogToken;
|
||||
BA_PARAM_SET BaParamSet;
|
||||
u16 BaTimeoutValue;
|
||||
SEQUENCE_CONTROL BaStartSeqCtrl;
|
||||
} BA_RECORD, *PBA_RECORD;
|
||||
|
||||
#endif
|
|
@ -1,745 +0,0 @@
|
|||
/******************************************************************************
|
||||
* 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 "ieee80211.h"
|
||||
#include "rtl819x_BA.h"
|
||||
|
||||
/********************************************************************************************************************
|
||||
*function: Activate BA entry. And if Time is nozero, start timer.
|
||||
* input: PBA_RECORD pBA //BA entry to be enabled
|
||||
* u16 Time //indicate time delay.
|
||||
* output: none
|
||||
********************************************************************************************************************/
|
||||
void ActivateBAEntry(struct ieee80211_device* ieee, PBA_RECORD pBA, u16 Time)
|
||||
{
|
||||
pBA->bValid = true;
|
||||
if(Time != 0)
|
||||
mod_timer(&pBA->Timer, jiffies + MSECS(Time));
|
||||
}
|
||||
|
||||
/********************************************************************************************************************
|
||||
*function: deactivate BA entry, including its timer.
|
||||
* input: PBA_RECORD pBA //BA entry to be disabled
|
||||
* output: none
|
||||
********************************************************************************************************************/
|
||||
void DeActivateBAEntry( struct ieee80211_device* ieee, PBA_RECORD pBA)
|
||||
{
|
||||
pBA->bValid = false;
|
||||
del_timer_sync(&pBA->Timer);
|
||||
}
|
||||
/********************************************************************************************************************
|
||||
*function: deactivete BA entry in Tx Ts, and send DELBA.
|
||||
* input:
|
||||
* PTX_TS_RECORD pTxTs //Tx Ts which is to deactivate BA entry.
|
||||
* output: none
|
||||
* notice: As PTX_TS_RECORD structure will be defined in QOS, so wait to be merged. //FIXME
|
||||
********************************************************************************************************************/
|
||||
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;
|
||||
}
|
||||
|
||||
/********************************************************************************************************************
|
||||
*function: deactivete BA entry in Tx Ts, and send DELBA.
|
||||
* input:
|
||||
* PRX_TS_RECORD pRxTs //Rx Ts which is to deactivate BA entry.
|
||||
* output: none
|
||||
* notice: As PRX_TS_RECORD structure will be defined in QOS, so wait to be merged. //FIXME, same with above
|
||||
********************************************************************************************************************/
|
||||
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;
|
||||
}
|
||||
|
||||
/********************************************************************************************************************
|
||||
*function: reset BA entry
|
||||
* input:
|
||||
* PBA_RECORD pBA //entry to be reset
|
||||
* output: none
|
||||
********************************************************************************************************************/
|
||||
void ResetBaEntry( PBA_RECORD pBA)
|
||||
{
|
||||
pBA->bValid = false;
|
||||
pBA->BaParamSet.shortData = 0;
|
||||
pBA->BaTimeoutValue = 0;
|
||||
pBA->DialogToken = 0;
|
||||
pBA->BaStartSeqCtrl.ShortData = 0;
|
||||
}
|
||||
//These functions need porting here or not?
|
||||
/*******************************************************************************************************************************
|
||||
*function: construct ADDBAREQ and ADDBARSP frame here together.
|
||||
* input: u8* Dst //ADDBA frame's destination
|
||||
* PBA_RECORD pBA //BA_RECORD entry which stores the necessary information for BA.
|
||||
* u16 StatusCode //status code in RSP and I will use it to indicate whether it's RSP or REQ(will I?)
|
||||
* u8 type //indicate whether it's RSP(ACT_ADDBARSP) ow REQ(ACT_ADDBAREQ)
|
||||
* output: none
|
||||
* return: sk_buff* skb //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;
|
||||
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_control = cpu_to_le16(IEEE80211_STYPE_MANAGE_ACT); //action frame
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/********************************************************************************************************************
|
||||
*function: construct DELBA frame
|
||||
* input: u8* dst //DELBA frame's destination
|
||||
* PBA_RECORD pBA //BA_RECORD entry which stores the necessary information for BA
|
||||
* TR_SELECT TxRxSelect //TX RX direction
|
||||
* u16 ReasonCode //status code.
|
||||
* output: none
|
||||
* return: sk_buff* skb //return constructed skb to xmit
|
||||
********************************************************************************************************************/
|
||||
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;
|
||||
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;
|
||||
}
|
||||
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_control = 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;
|
||||
}
|
||||
|
||||
/********************************************************************************************************************
|
||||
*function: send ADDBAReq frame out
|
||||
* input: u8* dst //ADDBAReq frame's destination
|
||||
* PBA_RECORD pBA //BA_RECORD entry which stores the necessary information for BA
|
||||
* output: none
|
||||
* notice: 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);
|
||||
}
|
||||
else
|
||||
{
|
||||
IEEE80211_DEBUG(IEEE80211_DL_ERR, "alloc skb error in function %s()\n", __FUNCTION__);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/********************************************************************************************************************
|
||||
*function: send ADDBARSP frame out
|
||||
* input: u8* dst //DELBA frame's destination
|
||||
* PBA_RECORD pBA //BA_RECORD entry which stores the necessary information for BA
|
||||
* u16 StatusCode //RSP StatusCode
|
||||
* output: none
|
||||
* notice: 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);
|
||||
}
|
||||
else
|
||||
{
|
||||
IEEE80211_DEBUG(IEEE80211_DL_ERR, "alloc skb error in function %s()\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
/********************************************************************************************************************
|
||||
*function: send ADDBARSP frame out
|
||||
* input: u8* dst //DELBA frame's destination
|
||||
* PBA_RECORD pBA //BA_RECORD entry which stores the necessary information for BA
|
||||
* TR_SELECT TxRxSelect //TX or RX
|
||||
* u16 ReasonCode //DEL ReasonCode
|
||||
* output: none
|
||||
* notice: 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);
|
||||
}
|
||||
else
|
||||
{
|
||||
IEEE80211_DEBUG(IEEE80211_DL_ERR, "alloc skb error in function %s()\n", __FUNCTION__);
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
/********************************************************************************************************************
|
||||
*function: RX ADDBAReq
|
||||
* input: struct sk_buff * skb //incoming ADDBAReq skb.
|
||||
* return: 0(pass), other(fail)
|
||||
* notice: As this function need support of QOS, I comment some code out. And when qos is ready, this code need to be support.
|
||||
********************************************************************************************************************/
|
||||
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 / %zd)\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->pHTInfo->IOTAction & HT_IOT_ACT_REJECT_ADDBA_REQ))
|
||||
{
|
||||
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->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);
|
||||
ieee80211_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;
|
||||
ieee80211_send_ADDBARsp(ieee, dst, &BA, rc);
|
||||
return 0; //we send RSP out.
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/********************************************************************************************************************
|
||||
*function: RX ADDBARSP
|
||||
* input: struct sk_buff * skb //incoming ADDBAReq skb.
|
||||
* return: 0(pass), other(fail)
|
||||
* notice: As this function need support of QOS, I comment some code out. And when qos is ready, this code need to be support.
|
||||
********************************************************************************************************************/
|
||||
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 / %zd)\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 {
|
||||
pTS->bAddBaReqDelayed = true;
|
||||
pTS->bDisable_AddBa = true;
|
||||
ReasonCode = DELBA_REASON_END_BA;
|
||||
goto OnADDBARsp_Reject;
|
||||
}
|
||||
|
||||
// End of procedure
|
||||
return 0;
|
||||
|
||||
OnADDBARsp_Reject:
|
||||
{
|
||||
BA_RECORD BA;
|
||||
BA.BaParamSet = *pBaParamSet;
|
||||
ieee80211_send_DELBA(ieee, dst, &BA, TX_DIR, ReasonCode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/********************************************************************************************************************
|
||||
*function: RX DELBA
|
||||
* input: struct sk_buff * skb //incoming ADDBAReq skb.
|
||||
* return: 0(pass), other(fail)
|
||||
* notice: As this function need support of QOS, I comment some code out. And when qos is ready, this code need to be support.
|
||||
********************************************************************************************************************/
|
||||
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 / %zd)\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);
|
||||
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 );
|
||||
}
|
||||
}
|
||||
/********************************************************************************************************************
|
||||
*function: BA setup timer
|
||||
* input: unsigned long data //acturally we send TX_TS_RECORD or RX_TS_RECORD to these timer
|
||||
* return: NULL
|
||||
* notice:
|
||||
********************************************************************************************************************/
|
||||
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);
|
||||
return ;
|
||||
}
|
||||
|
|
@ -1,530 +0,0 @@
|
|||
/******************************************************************************
|
||||
* 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
|
||||
|
||||
|
||||
#define HT_SUPPORTED_MCS_1SS_BITMAP 0x000000ff
|
||||
#define HT_SUPPORTED_MCS_2SS_BITMAP 0x0000ff00
|
||||
#define HT_SUPPORTED_MCS_1SS_2SS_BITMAP HT_MCS_1SS_BITMAP|HT_MCS_1SS_2SS_BITMAP
|
||||
|
||||
|
||||
typedef enum _HT_MCS_RATE{
|
||||
HT_MCS0 = 0x00000001,
|
||||
HT_MCS1 = 0x00000002,
|
||||
HT_MCS2 = 0x00000004,
|
||||
HT_MCS3 = 0x00000008,
|
||||
HT_MCS4 = 0x00000010,
|
||||
HT_MCS5 = 0x00000020,
|
||||
HT_MCS6 = 0x00000040,
|
||||
HT_MCS7 = 0x00000080,
|
||||
HT_MCS8 = 0x00000100,
|
||||
HT_MCS9 = 0x00000200,
|
||||
HT_MCS10 = 0x00000400,
|
||||
HT_MCS11 = 0x00000800,
|
||||
HT_MCS12 = 0x00001000,
|
||||
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 Extention 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,
|
||||
HT_EXTCHNL_OFFSET_NO_DEF = 2,
|
||||
HT_EXTCHNL_OFFSET_LOWER = 3,
|
||||
}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, *PCHNLOP;
|
||||
|
||||
// Determine if the Channel Operation is in progress
|
||||
#define CHHLOP_IN_PROGRESS(_pHTInfo) \
|
||||
((_pHTInfo)->ChnlOp > CHNLOP_NONE) ? TRUE : FALSE
|
||||
|
||||
/*
|
||||
typedef union _HT_CAPABILITY{
|
||||
u16 ShortData;
|
||||
u8 CharData[2];
|
||||
struct
|
||||
{
|
||||
u16 AdvCoding:1;
|
||||
u16 ChlWidth:1;
|
||||
u16 MimoPwrSave:2;
|
||||
u16 GreenField:1;
|
||||
u16 ShortGI20Mhz:1;
|
||||
u16 ShortGI40Mhz:1;
|
||||
u16 STBC:1;
|
||||
u16 BeamForm:1;
|
||||
u16 DelayBA:1;
|
||||
u16 MaxAMSDUSize:1;
|
||||
u16 DssCCk:1;
|
||||
u16 PSMP:1;
|
||||
u16 Rsvd:3;
|
||||
}Field;
|
||||
}HT_CAPABILITY, *PHT_CAPABILITY;
|
||||
|
||||
typedef union _HT_CAPABILITY_MACPARA{
|
||||
u8 ShortData;
|
||||
u8 CharData[1];
|
||||
struct
|
||||
{
|
||||
u8 MaxRxAMPDU:2;
|
||||
u8 MPDUDensity:2;
|
||||
u8 Rsvd:4;
|
||||
}Field;
|
||||
}HT_CAPABILITY_MACPARA, *PHT_CAPABILITY_MACPARA;
|
||||
*/
|
||||
|
||||
typedef enum _HT_ACTION{
|
||||
ACT_RECOMMAND_WIDTH = 0,
|
||||
ACT_MIMO_PWR_SAVE = 1,
|
||||
ACT_PSMP = 2,
|
||||
ACT_SET_PCO_PHASE = 3,
|
||||
ACT_MIMO_CHL_MEASURE = 4,
|
||||
ACT_RECIPROCITY_CORRECT = 5,
|
||||
ACT_MIMO_CSI_MATRICS = 6,
|
||||
ACT_MIMO_NOCOMPR_STEER = 7,
|
||||
ACT_MIMO_COMPR_STEER = 8,
|
||||
ACT_ANTENNA_SELECT = 9,
|
||||
} 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,
|
||||
SC_MODE_UPPER = 2,
|
||||
SC_MODE_FULL40MHZ = 3,
|
||||
}HT_BW40_SC_E;
|
||||
|
||||
typedef struct _HT_CAPABILITY_ELE{
|
||||
|
||||
//HT capability info
|
||||
u8 AdvCoding:1;
|
||||
u8 ChlWidth:1;
|
||||
u8 MimoPwrSave:2;
|
||||
u8 GreenField:1;
|
||||
u8 ShortGI20Mhz:1;
|
||||
u8 ShortGI40Mhz:1;
|
||||
u8 TxSTBC:1;
|
||||
u8 RxSTBC:2;
|
||||
u8 DelayBA:1;
|
||||
u8 MaxAMSDUSize:1;
|
||||
u8 DssCCk:1;
|
||||
u8 PSMP:1;
|
||||
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;
|
||||
|
||||
u8 ExtChlOffset:2;
|
||||
u8 RecommemdedTxWidth:1;
|
||||
u8 RIFS:1;
|
||||
u8 PSMPAccessOnly:1;
|
||||
u8 SrvIntGranularity:3;
|
||||
|
||||
u8 OptMode:2;
|
||||
u8 NonGFDevPresent:1;
|
||||
u8 Revd1:5;
|
||||
u8 Revd2:8;
|
||||
|
||||
u8 Rsvd3:6;
|
||||
u8 DualBeacon:1;
|
||||
u8 DualCTSProtect:1;
|
||||
|
||||
u8 SecondaryBeacon:1;
|
||||
u8 LSigTxopProtectFull:1;
|
||||
u8 PcoActive:1;
|
||||
u8 PcoPhase:1;
|
||||
u8 Rsvd4:4;
|
||||
|
||||
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;
|
||||
u8 Reserved:6;
|
||||
} MIMOPS_CTRL, *PMIMOPS_CTRL;
|
||||
|
||||
typedef enum _HT_SPEC_VER{
|
||||
HT_SPEC_VER_IEEE = 0,
|
||||
HT_SPEC_VER_EWC = 1,
|
||||
}HT_SPEC_VER, *PHT_SPEC_VER;
|
||||
|
||||
typedef enum _HT_AGGRE_MODE_E{
|
||||
HT_AGG_AUTO = 0,
|
||||
HT_AGG_FORCE_ENABLE = 1,
|
||||
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 bRegShortGI40MHz; // Tx Short GI for 40Mhz
|
||||
u8 bCurShortGI40MHz; // Tx Short GI for 40MHz
|
||||
|
||||
u8 bRegShortGI20MHz; // Tx Short GI for 20MHz
|
||||
u8 bCurShortGI20MHz; // Tx Short GI for 20MHz
|
||||
|
||||
u8 bRegSuppCCK; // Tx CCK rate capability
|
||||
u8 bCurSuppCCK; // Tx CCK rate capability
|
||||
|
||||
// 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 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
|
||||
|
||||
|
||||
// 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;
|
||||
|
||||
u8 bForcedShortGI;
|
||||
|
||||
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 PeerBandwidth;
|
||||
|
||||
// For Bandwidth Switching
|
||||
u8 bSwBwInProgress;
|
||||
CHNLOP ChnlOp; // software switching channel in progress. By Bruce, 2008-02-15.
|
||||
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;
|
||||
u8 RxReorderPendingTime;
|
||||
u16 RxReorderDropCounter;
|
||||
|
||||
|
||||
// Add for Broadcom(Linksys) IOT. Joseph
|
||||
u8 bIsPeerBcm;
|
||||
|
||||
// For IOT issue.
|
||||
u8 IOTPeer;
|
||||
u32 IOTAction;
|
||||
u8 IOTRaFunc;
|
||||
} __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;
|
||||
|
||||
u8 bSupportCck;
|
||||
|
||||
u16 AMSDU_MaxSize;
|
||||
|
||||
u8 AMPDU_Factor;
|
||||
u8 MPDU_Density;
|
||||
|
||||
u8 HTHighestOperaRate;
|
||||
|
||||
u8 bBw40MHz;
|
||||
|
||||
u8 MimoPs;
|
||||
|
||||
u8 McsRateSet[16];
|
||||
|
||||
|
||||
}RT_HTINFO_STA_ENTRY, *PRT_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_CHANNEL_WIDTH bdBandWidth;
|
||||
|
||||
u8 bdRT2RTAggregation;
|
||||
u8 bdRT2RTLongSlotTime;
|
||||
u8 RT2RT_HT_Mode;
|
||||
bool bdHT1R;
|
||||
} __attribute__ ((packed)) BSS_HT, *PBSS_HT;
|
||||
|
||||
typedef struct _MIMO_RSSI{
|
||||
u32 EnableAntenna;
|
||||
u32 AntennaA;
|
||||
u32 AntennaB;
|
||||
u32 AntennaC;
|
||||
u32 AntennaD;
|
||||
u32 Average;
|
||||
}MIMO_RSSI, *PMIMO_RSSI;
|
||||
|
||||
typedef struct _MIMO_EVM{
|
||||
u32 EVM1;
|
||||
u32 EVM2;
|
||||
}MIMO_EVM, *PMIMO_EVM;
|
||||
|
||||
typedef struct _FALSE_ALARM_STATISTICS{
|
||||
u32 Cnt_Parity_Fail;
|
||||
u32 Cnt_Rate_Illegal;
|
||||
u32 Cnt_Crc8_fail;
|
||||
u32 Cnt_all;
|
||||
}FALSE_ALARM_STATISTICS, *PFALSE_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) \
|
||||
((WirelessMode & (LEGACY_WIRELESS_MODE))!=0)?\
|
||||
(LegacyRate):\
|
||||
(PICK_RATE(LegacyRate, HTRate))
|
||||
|
||||
|
||||
|
||||
// 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_MCS32_MASK 0x01
|
||||
|
||||
#define IS_11N_MCS_RATE(rate) (rate&0x80)
|
||||
|
||||
typedef enum _HT_AGGRE_SIZE{
|
||||
HT_AGG_SIZE_8K = 0,
|
||||
HT_AGG_SIZE_16K = 1,
|
||||
HT_AGG_SIZE_32K = 2,
|
||||
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_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_MAX = 10,
|
||||
}HT_IOT_PEER_E, *PHTIOT_PEER_E;
|
||||
|
||||
//
|
||||
// IOT Action for different AP
|
||||
//
|
||||
typedef enum _HT_IOT_ACTION{
|
||||
HT_IOT_ACT_TX_USE_AMSDU_4K = 0x00000001,
|
||||
HT_IOT_ACT_TX_USE_AMSDU_8K = 0x00000002,
|
||||
HT_IOT_ACT_DISABLE_MCS14 = 0x00000004,
|
||||
HT_IOT_ACT_DISABLE_MCS15 = 0x00000008,
|
||||
HT_IOT_ACT_DISABLE_ALL_2SS = 0x00000010,
|
||||
HT_IOT_ACT_DISABLE_EDCA_TURBO = 0x00000020,
|
||||
HT_IOT_ACT_MGNT_USE_CCK_6M = 0x00000040,
|
||||
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_ACTION_E, *PHT_IOT_ACTION_E;
|
||||
|
||||
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
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,540 +0,0 @@
|
|||
/******************************************************************************
|
||||
* 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
|
||||
|
||||
#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
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
}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;
|
||||
}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;
|
||||
}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;
|
||||
}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{
|
||||
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 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{
|
||||
u8 AC;
|
||||
WMM_TSPEC TSpec;
|
||||
QOS_TCLAS TClass;
|
||||
} QOS_TSTREAM, *PQOS_TSTREAM;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// 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{
|
||||
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;
|
||||
|
||||
#define sQoSCtlLng 2
|
||||
#define QOS_CTRL_LEN(_QosMode) ((_QosMode > QOS_DISABLE)? sQoSCtlLng : 0)
|
||||
|
||||
#define IsACValid(ac) ((ac<=7 )?true:false )
|
||||
|
||||
#endif
|
|
@ -1,71 +0,0 @@
|
|||
/******************************************************************************
|
||||
* 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_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,
|
||||
} TR_SELECT, *PTR_SELECT;
|
||||
|
||||
typedef struct _TS_COMMON_INFO{
|
||||
struct list_head List;
|
||||
struct timer_list SetupTimer;
|
||||
struct timer_list InactTimer;
|
||||
u8 Addr[6];
|
||||
TSPEC_BODY TSpec;
|
||||
QOS_TCLAS TClass[TCLAS_NUM];
|
||||
u8 TClasProc;
|
||||
u8 TClasNum;
|
||||
} TS_COMMON_INFO, *PTS_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
|
||||
u8 bAddBaReqInProgress;
|
||||
u8 bAddBaReqDelayed;
|
||||
u8 bUsingBa;
|
||||
u8 bDisable_AddBa;
|
||||
struct timer_list TsAddBaTimer;
|
||||
u8 num;
|
||||
} TX_TS_RECORD, *PTX_TS_RECORD;
|
||||
|
||||
typedef struct _RX_TS_RECORD {
|
||||
TS_COMMON_INFO TsCommonInfo;
|
||||
u16 RxIndicateSeq;
|
||||
u16 RxTimeoutIndicateSeq;
|
||||
struct list_head RxPendingPktList;
|
||||
struct timer_list RxPktPendingTimer;
|
||||
BA_RECORD RxAdmittedBARecord; // For BA Recepient
|
||||
u16 RxLastSeqNum;
|
||||
u8 RxLastFragNum;
|
||||
u8 num;
|
||||
} RX_TS_RECORD, *PRX_TS_RECORD;
|
||||
|
||||
#endif
|
|
@ -1,631 +0,0 @@
|
|||
/******************************************************************************
|
||||
* 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 "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;
|
||||
|
||||
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);
|
||||
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)
|
||||
{
|
||||
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);
|
||||
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);
|
||||
//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;
|
||||
pTS->bDisable_AddBa = 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 Recepient
|
||||
}
|
||||
|
||||
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);
|
||||
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 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)
|
||||
{
|
||||
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 = 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;
|
||||
}
|
||||
|
||||
|
||||
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, "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, "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
|
||||
)
|
||||
{
|
||||
unsigned long flags = 0;
|
||||
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))
|
||||
{
|
||||
spin_lock_irqsave(&(ieee->reorder_spinlock), flags);
|
||||
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);
|
||||
spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
|
||||
}
|
||||
}
|
||||
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__);
|
||||
}
|
|
@ -1,647 +0,0 @@
|
|||
/*Created on 2009/ 1/15, 3:10*/
|
||||
|
||||
#include "r8192SU_HWImg.h"
|
||||
|
||||
u8 Rtl8192SUFwMainArray[MainArrayLength] = {
|
||||
0x0, };
|
||||
|
||||
u8 Rtl8192SUFwDataArray[DataArrayLength] = {
|
||||
0x0, };
|
||||
|
||||
u32 Rtl8192SUPHY_REG_2T2RArray[PHY_REG_2T2RArrayLength] = {
|
||||
0x01c,0x07000000,
|
||||
0x800,0x00040000,
|
||||
0x804,0x00008003,
|
||||
0x808,0x0000fc00,
|
||||
0x80c,0x0000000a,
|
||||
0x810,0x10005088,
|
||||
0x814,0x020c3d10,
|
||||
0x818,0x00200185,
|
||||
0x81c,0x00000000,
|
||||
0x820,0x01000000,
|
||||
0x824,0x00390004,
|
||||
0x828,0x01000000,
|
||||
0x82c,0x00390004,
|
||||
0x830,0x00000004,
|
||||
0x834,0x00690200,
|
||||
0x838,0x00000004,
|
||||
0x83c,0x00690200,
|
||||
0x840,0x00010000,
|
||||
0x844,0x00010000,
|
||||
0x848,0x00000000,
|
||||
0x84c,0x00000000,
|
||||
0x850,0x00000000,
|
||||
0x854,0x00000000,
|
||||
0x858,0x48484848,
|
||||
0x85c,0x65a965a9,
|
||||
0x860,0x0f7f0130,
|
||||
0x864,0x0f7f0130,
|
||||
0x868,0x0f7f0130,
|
||||
0x86c,0x0f7f0130,
|
||||
0x870,0x03000700,
|
||||
0x874,0x03000300,
|
||||
0x878,0x00020002,
|
||||
0x87c,0x004f0201,
|
||||
0x880,0xa8300ac1,
|
||||
0x884,0x00000058,
|
||||
0x888,0x00000008,
|
||||
0x88c,0x00000004,
|
||||
0x890,0x00000000,
|
||||
0x894,0xfffffffe,
|
||||
0x898,0x40302010,
|
||||
0x89c,0x00706050,
|
||||
0x8b0,0x00000000,
|
||||
0x8e0,0x00000000,
|
||||
0x8e4,0x00000000,
|
||||
0xe00,0x30333333,
|
||||
0xe04,0x2a2d2e2f,
|
||||
0xe08,0x00003232,
|
||||
0xe10,0x30333333,
|
||||
0xe14,0x2a2d2e2f,
|
||||
0xe18,0x30333333,
|
||||
0xe1c,0x2a2d2e2f,
|
||||
0xe30,0x01007c00,
|
||||
0xe34,0x01004800,
|
||||
0xe38,0x1000dc1f,
|
||||
0xe3c,0x10008c1f,
|
||||
0xe40,0x021400a0,
|
||||
0xe44,0x281600a0,
|
||||
0xe48,0xf8000001,
|
||||
0xe4c,0x00002910,
|
||||
0xe50,0x01007c00,
|
||||
0xe54,0x01004800,
|
||||
0xe58,0x1000dc1f,
|
||||
0xe5c,0x10008c1f,
|
||||
0xe60,0x021400a0,
|
||||
0xe64,0x281600a0,
|
||||
0xe6c,0x00002910,
|
||||
0xe70,0x31ed92fb,
|
||||
0xe74,0x361536fb,
|
||||
0xe78,0x361536fb,
|
||||
0xe7c,0x361536fb,
|
||||
0xe80,0x361536fb,
|
||||
0xe84,0x000d92fb,
|
||||
0xe88,0x000d92fb,
|
||||
0xe8c,0x31ed92fb,
|
||||
0xed0,0x31ed92fb,
|
||||
0xed4,0x31ed92fb,
|
||||
0xed8,0x000d92fb,
|
||||
0xedc,0x000d92fb,
|
||||
0xee0,0x000d92fb,
|
||||
0xee4,0x015e5448,
|
||||
0xee8,0x21555448,
|
||||
0x900,0x00000000,
|
||||
0x904,0x00000023,
|
||||
0x908,0x00000000,
|
||||
0x90c,0x01121313,
|
||||
0xa00,0x00d047c8,
|
||||
0xa04,0x80ff0008,
|
||||
0xa08,0x8ccd8300,
|
||||
0xa0c,0x2e62120f,
|
||||
0xa10,0x9500bb78,
|
||||
0xa14,0x11144028,
|
||||
0xa18,0x00881117,
|
||||
0xa1c,0x89140f00,
|
||||
0xa20,0x1a1b0000,
|
||||
0xa24,0x090e1317,
|
||||
0xa28,0x00000204,
|
||||
0xa2c,0x10d30000,
|
||||
0xc00,0x40071d40,
|
||||
0xc04,0x00a05633,
|
||||
0xc08,0x000000e4,
|
||||
0xc0c,0x6c6c6c6c,
|
||||
0xc10,0x08800000,
|
||||
0xc14,0x40000100,
|
||||
0xc18,0x08000000,
|
||||
0xc1c,0x40000100,
|
||||
0xc20,0x08000000,
|
||||
0xc24,0x40000100,
|
||||
0xc28,0x08000000,
|
||||
0xc2c,0x40000100,
|
||||
0xc30,0x6de9ac44,
|
||||
0xc34,0x469652cf,
|
||||
0xc38,0x49795994,
|
||||
0xc3c,0x0a979764,
|
||||
0xc40,0x1f7c403f,
|
||||
0xc44,0x000100b7,
|
||||
0xc48,0xec020000,
|
||||
0xc4c,0x007f037f,
|
||||
0xc50,0x69543420,
|
||||
0xc54,0x433c0094,
|
||||
0xc58,0x69543420,
|
||||
0xc5c,0x433c0094,
|
||||
0xc60,0x69543420,
|
||||
0xc64,0x433c0094,
|
||||
0xc68,0x69543420,
|
||||
0xc6c,0x433c0094,
|
||||
0xc70,0x2c7f000d,
|
||||
0xc74,0x0186175b,
|
||||
0xc78,0x0000001f,
|
||||
0xc7c,0x00b91612,
|
||||
0xc80,0x40000100,
|
||||
0xc84,0x20f60000,
|
||||
0xc88,0x20000080,
|
||||
0xc8c,0x20200000,
|
||||
0xc90,0x40000100,
|
||||
0xc94,0x00000000,
|
||||
0xc98,0x40000100,
|
||||
0xc9c,0x00000000,
|
||||
0xca0,0x00492492,
|
||||
0xca4,0x00000000,
|
||||
0xca8,0x00000000,
|
||||
0xcac,0x00000000,
|
||||
0xcb0,0x00000000,
|
||||
0xcb4,0x00000000,
|
||||
0xcb8,0x00000000,
|
||||
0xcbc,0x28000000,
|
||||
0xcc0,0x00000000,
|
||||
0xcc4,0x00000000,
|
||||
0xcc8,0x00000000,
|
||||
0xccc,0x00000000,
|
||||
0xcd0,0x00000000,
|
||||
0xcd4,0x00000000,
|
||||
0xcd8,0x64b22427,
|
||||
0xcdc,0x00766932,
|
||||
0xce0,0x00222222,
|
||||
0xce4,0x00000000,
|
||||
0xce8,0x37644302,
|
||||
0xcec,0x2f97d40c,
|
||||
0xd00,0x00000750,
|
||||
0xd04,0x00000403,
|
||||
0xd08,0x0000907f,
|
||||
0xd0c,0x00000001,
|
||||
0xd10,0xa0633333,
|
||||
0xd14,0x33333c63,
|
||||
0xd18,0x6a8f5b6b,
|
||||
0xd1c,0x00000000,
|
||||
0xd20,0x00000000,
|
||||
0xd24,0x00000000,
|
||||
0xd28,0x00000000,
|
||||
0xd2c,0xcc979975,
|
||||
0xd30,0x00000000,
|
||||
0xd34,0x00000000,
|
||||
0xd38,0x00000000,
|
||||
0xd3c,0x00027293,
|
||||
0xd40,0x00000000,
|
||||
0xd44,0x00000000,
|
||||
0xd48,0x00000000,
|
||||
0xd50,0x6437140a,
|
||||
0xd54,0x024dbd02,
|
||||
0xd58,0x00000000,
|
||||
0xd5c,0x30032064,
|
||||
0xd60,0x4653de68,
|
||||
0xd64,0x00518a3c,
|
||||
0xd68,0x00002101,
|
||||
0xf14,0x00000003,
|
||||
0xf4c,0x00000000,
|
||||
0xf00,0x00000300,
|
||||
};
|
||||
|
||||
u32 Rtl8192SUPHY_REG_1T2RArray[PHY_REG_1T2RArrayLength] = {
|
||||
0x0, };
|
||||
|
||||
u32 Rtl8192SUPHY_ChangeTo_1T1RArray[PHY_ChangeTo_1T1RArrayLength] = {
|
||||
0x844,0xffffffff,0x00010000,
|
||||
0x804,0x0000000f,0x00000001,
|
||||
0x824,0x00f0000f,0x00300004,
|
||||
0x82c,0x00f0000f,0x00100002,
|
||||
0x870,0x04000000,0x00000001,
|
||||
0x864,0x00000400,0x00000000,
|
||||
0x878,0x000f000f,0x00000002,
|
||||
0xe74,0x0f000000,0x00000002,
|
||||
0xe78,0x0f000000,0x00000002,
|
||||
0xe7c,0x0f000000,0x00000002,
|
||||
0xe80,0x0f000000,0x00000002,
|
||||
0x90c,0x000000ff,0x00000011,
|
||||
0xc04,0x000000ff,0x00000011,
|
||||
0xd04,0x0000000f,0x00000001,
|
||||
0x1f4,0xffff0000,0x00007777,
|
||||
0x234,0xf8000000,0x0000000a,
|
||||
};
|
||||
|
||||
u32 Rtl8192SUPHY_ChangeTo_1T2RArray[PHY_ChangeTo_1T2RArrayLength] = {
|
||||
0x804,0x0000000f,0x00000003,
|
||||
0x824,0x00f0000f,0x00300004,
|
||||
0x82c,0x00f0000f,0x00300002,
|
||||
0x870,0x04000000,0x00000001,
|
||||
0x864,0x00000400,0x00000000,
|
||||
0x878,0x000f000f,0x00000002,
|
||||
0xe74,0x0f000000,0x00000002,
|
||||
0xe78,0x0f000000,0x00000002,
|
||||
0xe7c,0x0f000000,0x00000002,
|
||||
0xe80,0x0f000000,0x00000002,
|
||||
0x90c,0x000000ff,0x00000011,
|
||||
0xc04,0x000000ff,0x00000033,
|
||||
0xd04,0x0000000f,0x00000003,
|
||||
0x1f4,0xffff0000,0x00007777,
|
||||
0x234,0xf8000000,0x0000000a,
|
||||
};
|
||||
|
||||
u32 Rtl8192SUPHY_ChangeTo_2T2RArray[PHY_ChangeTo_2T2RArrayLength] = {
|
||||
0x804,0x0000000f,0x00000003,
|
||||
0x824,0x00f0000f,0x00300004,
|
||||
0x82c,0x00f0000f,0x00300004,
|
||||
0x870,0x04000000,0x00000001,
|
||||
0x864,0x00000400,0x00000001,
|
||||
0x878,0x000f000f,0x00020002,
|
||||
0xe74,0x0f000000,0x00000006,
|
||||
0xe78,0x0f000000,0x00000006,
|
||||
0xe7c,0x0f000000,0x00000006,
|
||||
0xe80,0x0f000000,0x00000006,
|
||||
0x90c,0x000000ff,0x00000033,
|
||||
0xc04,0x000000ff,0x00000033,
|
||||
0xd04,0x0000000f,0x00000003,
|
||||
0x1f4,0xffff0000,0x0000ffff,
|
||||
0x234,0xf8000000,0x00000013,
|
||||
};
|
||||
|
||||
u32 Rtl8192SUPHY_REG_Array_PG[PHY_REG_Array_PGLength] = {
|
||||
0xe00,0xffffffff,0x04060606,
|
||||
0xe04,0xffffffff,0x00020204,
|
||||
0xe08,0x0000ff00,0x00000000,
|
||||
0xe10,0xffffffff,0x0408080a,
|
||||
0xe14,0xffffffff,0x00020204,
|
||||
0xe18,0xffffffff,0x0408080a,
|
||||
0xe1c,0xffffffff,0x00020204,
|
||||
0xe00,0xffffffff,0x00000000,
|
||||
0xe04,0xffffffff,0x00000000,
|
||||
0xe08,0x0000ff00,0x00000000,
|
||||
0xe10,0xffffffff,0x00000000,
|
||||
0xe14,0xffffffff,0x00000000,
|
||||
0xe18,0xffffffff,0x00000000,
|
||||
0xe1c,0xffffffff,0x00000000,
|
||||
0xe00,0xffffffff,0x00000000,
|
||||
0xe04,0xffffffff,0x00000000,
|
||||
0xe08,0x0000ff00,0x00000000,
|
||||
0xe10,0xffffffff,0x00000000,
|
||||
0xe14,0xffffffff,0x00000000,
|
||||
0xe18,0xffffffff,0x00000000,
|
||||
0xe1c,0xffffffff,0x00000000,
|
||||
0xe00,0xffffffff,0x00000000,
|
||||
0xe04,0xffffffff,0x00000000,
|
||||
0xe08,0x0000ff00,0x00000000,
|
||||
0xe10,0xffffffff,0x00000000,
|
||||
0xe14,0xffffffff,0x00000000,
|
||||
0xe18,0xffffffff,0x00000000,
|
||||
0xe1c,0xffffffff,0x00000000,
|
||||
};
|
||||
|
||||
u32 Rtl8192SURadioA_1T_Array[RadioA_1T_ArrayLength] = {
|
||||
0x000,0x00030159,
|
||||
0x001,0x00030250,
|
||||
0x002,0x00010000,
|
||||
0x010,0x0008000f,
|
||||
0x011,0x000231fc,
|
||||
0x010,0x000c000f,
|
||||
0x011,0x0003f9f8,
|
||||
0x010,0x0002000f,
|
||||
0x011,0x00020101,
|
||||
0x014,0x0001093e,
|
||||
0x014,0x0009093e,
|
||||
0x015,0x000198f4,
|
||||
0x017,0x000f6500,
|
||||
0x01a,0x00013056,
|
||||
0x01b,0x00060000,
|
||||
0x01c,0x00000300,
|
||||
0x01e,0x00031059,
|
||||
0x021,0x00054000,
|
||||
0x022,0x0000083c,
|
||||
0x023,0x00001558,
|
||||
0x024,0x00000060,
|
||||
0x025,0x00022583,
|
||||
0x026,0x0000f200,
|
||||
0x027,0x000eacf1,
|
||||
0x028,0x0009bd54,
|
||||
0x029,0x00004582,
|
||||
0x02a,0x00000001,
|
||||
0x02b,0x00021334,
|
||||
0x02a,0x00000000,
|
||||
0x02b,0x0000000a,
|
||||
0x02a,0x00000001,
|
||||
0x02b,0x00000808,
|
||||
0x02b,0x00053333,
|
||||
0x02c,0x0000000c,
|
||||
0x02a,0x00000002,
|
||||
0x02b,0x00000808,
|
||||
0x02b,0x0005b333,
|
||||
0x02c,0x0000000d,
|
||||
0x02a,0x00000003,
|
||||
0x02b,0x00000808,
|
||||
0x02b,0x00063333,
|
||||
0x02c,0x0000000d,
|
||||
0x02a,0x00000004,
|
||||
0x02b,0x00000808,
|
||||
0x02b,0x0006b333,
|
||||
0x02c,0x0000000d,
|
||||
0x02a,0x00000005,
|
||||
0x02b,0x00000709,
|
||||
0x02b,0x00053333,
|
||||
0x02c,0x0000000d,
|
||||
0x02a,0x00000006,
|
||||
0x02b,0x00000709,
|
||||
0x02b,0x0005b333,
|
||||
0x02c,0x0000000d,
|
||||
0x02a,0x00000007,
|
||||
0x02b,0x00000709,
|
||||
0x02b,0x00063333,
|
||||
0x02c,0x0000000d,
|
||||
0x02a,0x00000008,
|
||||
0x02b,0x00000709,
|
||||
0x02b,0x0006b333,
|
||||
0x02c,0x0000000d,
|
||||
0x02a,0x00000009,
|
||||
0x02b,0x0000060a,
|
||||
0x02b,0x00053333,
|
||||
0x02c,0x0000000d,
|
||||
0x02a,0x0000000a,
|
||||
0x02b,0x0000060a,
|
||||
0x02b,0x0005b333,
|
||||
0x02c,0x0000000d,
|
||||
0x02a,0x0000000b,
|
||||
0x02b,0x0000060a,
|
||||
0x02b,0x00063333,
|
||||
0x02c,0x0000000d,
|
||||
0x02a,0x0000000c,
|
||||
0x02b,0x0000060a,
|
||||
0x02b,0x0006b333,
|
||||
0x02c,0x0000000d,
|
||||
0x02a,0x0000000d,
|
||||
0x02b,0x0000050b,
|
||||
0x02b,0x00053333,
|
||||
0x02c,0x0000000d,
|
||||
0x02a,0x0000000e,
|
||||
0x02b,0x0000050b,
|
||||
0x02b,0x00066623,
|
||||
0x02c,0x0000001a,
|
||||
0x02a,0x000e4000,
|
||||
0x030,0x00020000,
|
||||
0x031,0x000b9631,
|
||||
0x032,0x0000130d,
|
||||
0x033,0x00000187,
|
||||
0x013,0x00019e6c,
|
||||
0x013,0x00015e94,
|
||||
0x000,0x00010159,
|
||||
0x018,0x0000f401,
|
||||
0x0fe,0x00000000,
|
||||
0x01e,0x0003105b,
|
||||
0x0fe,0x00000000,
|
||||
0x000,0x00030159,
|
||||
0x010,0x0004000f,
|
||||
0x011,0x000203f9,
|
||||
};
|
||||
|
||||
u32 Rtl8192SURadioB_Array[RadioB_ArrayLength] = {
|
||||
0x000,0x00030159,
|
||||
0x001,0x00001041,
|
||||
0x002,0x00011000,
|
||||
0x005,0x00080fc0,
|
||||
0x007,0x000fc803,
|
||||
0x013,0x00017cb0,
|
||||
0x013,0x00011cc0,
|
||||
0x013,0x0000dc60,
|
||||
0x013,0x00008c60,
|
||||
0x013,0x00004450,
|
||||
0x013,0x00000020,
|
||||
};
|
||||
|
||||
u32 Rtl8192SURadioA_to1T_Array[RadioA_to1T_ArrayLength] = {
|
||||
0x000,0x00000000,
|
||||
};
|
||||
|
||||
u32 Rtl8192SURadioA_to2T_Array[RadioA_to2T_ArrayLength] = {
|
||||
0x000,0x00000000,
|
||||
};
|
||||
|
||||
u32 Rtl8192SURadioB_GM_Array[RadioB_GM_ArrayLength] = {
|
||||
0x000,0x00030159,
|
||||
0x001,0x00001041,
|
||||
0x002,0x00011000,
|
||||
0x005,0x00080fc0,
|
||||
0x007,0x000fc803,
|
||||
0x013,0x0000bef0,
|
||||
0x013,0x00007e90,
|
||||
0x013,0x00003e30,
|
||||
};
|
||||
|
||||
u32 Rtl8192SUMAC_2T_Array[MAC_2T_ArrayLength] = {
|
||||
0x020,0x00000035,
|
||||
0x048,0x0000000e,
|
||||
0x049,0x000000f0,
|
||||
0x04a,0x00000077,
|
||||
0x04b,0x00000083,
|
||||
0x0b5,0x00000021,
|
||||
0x0dc,0x000000ff,
|
||||
0x0dd,0x000000ff,
|
||||
0x0de,0x000000ff,
|
||||
0x0df,0x000000ff,
|
||||
0x116,0x00000000,
|
||||
0x117,0x00000000,
|
||||
0x118,0x00000000,
|
||||
0x119,0x00000000,
|
||||
0x11a,0x00000000,
|
||||
0x11b,0x00000000,
|
||||
0x11c,0x00000000,
|
||||
0x11d,0x00000000,
|
||||
0x160,0x0000000b,
|
||||
0x161,0x0000000b,
|
||||
0x162,0x0000000b,
|
||||
0x163,0x0000000b,
|
||||
0x164,0x0000000b,
|
||||
0x165,0x0000000b,
|
||||
0x166,0x0000000b,
|
||||
0x167,0x0000000b,
|
||||
0x168,0x0000000b,
|
||||
0x169,0x0000000b,
|
||||
0x16a,0x0000000b,
|
||||
0x16b,0x0000000b,
|
||||
0x16c,0x0000000b,
|
||||
0x16d,0x0000000b,
|
||||
0x16e,0x0000000b,
|
||||
0x16f,0x0000000b,
|
||||
0x170,0x0000000b,
|
||||
0x171,0x0000000b,
|
||||
0x172,0x0000000b,
|
||||
0x173,0x0000000b,
|
||||
0x174,0x0000000b,
|
||||
0x175,0x0000000b,
|
||||
0x176,0x0000000b,
|
||||
0x177,0x0000000b,
|
||||
0x178,0x0000000b,
|
||||
0x179,0x0000000b,
|
||||
0x17a,0x0000000b,
|
||||
0x17b,0x0000000b,
|
||||
0x17c,0x0000000b,
|
||||
0x17d,0x0000000b,
|
||||
0x17e,0x0000000b,
|
||||
0x17f,0x0000000b,
|
||||
0x236,0x0000000c,
|
||||
0x503,0x00000022,
|
||||
0x560,0x00000009,
|
||||
};
|
||||
|
||||
u32 Rtl8192SUMACPHY_Array_PG[MACPHY_Array_PGLength] = {
|
||||
0x0, };
|
||||
|
||||
u32 Rtl8192SUAGCTAB_Array[AGCTAB_ArrayLength] = {
|
||||
0xc78,0x7f000001,
|
||||
0xc78,0x7f010001,
|
||||
0xc78,0x7e020001,
|
||||
0xc78,0x7d030001,
|
||||
0xc78,0x7c040001,
|
||||
0xc78,0x7b050001,
|
||||
0xc78,0x7a060001,
|
||||
0xc78,0x79070001,
|
||||
0xc78,0x78080001,
|
||||
0xc78,0x77090001,
|
||||
0xc78,0x760a0001,
|
||||
0xc78,0x750b0001,
|
||||
0xc78,0x740c0001,
|
||||
0xc78,0x730d0001,
|
||||
0xc78,0x720e0001,
|
||||
0xc78,0x710f0001,
|
||||
0xc78,0x70100001,
|
||||
0xc78,0x6f110001,
|
||||
0xc78,0x6f120001,
|
||||
0xc78,0x6e130001,
|
||||
0xc78,0x6d140001,
|
||||
0xc78,0x6d150001,
|
||||
0xc78,0x6c160001,
|
||||
0xc78,0x6b170001,
|
||||
0xc78,0x6a180001,
|
||||
0xc78,0x6a190001,
|
||||
0xc78,0x691a0001,
|
||||
0xc78,0x681b0001,
|
||||
0xc78,0x671c0001,
|
||||
0xc78,0x661d0001,
|
||||
0xc78,0x651e0001,
|
||||
0xc78,0x641f0001,
|
||||
0xc78,0x63200001,
|
||||
0xc78,0x4c210001,
|
||||
0xc78,0x4b220001,
|
||||
0xc78,0x4a230001,
|
||||
0xc78,0x49240001,
|
||||
0xc78,0x48250001,
|
||||
0xc78,0x47260001,
|
||||
0xc78,0x46270001,
|
||||
0xc78,0x45280001,
|
||||
0xc78,0x44290001,
|
||||
0xc78,0x2c2a0001,
|
||||
0xc78,0x2b2b0001,
|
||||
0xc78,0x2a2c0001,
|
||||
0xc78,0x292d0001,
|
||||
0xc78,0x282e0001,
|
||||
0xc78,0x272f0001,
|
||||
0xc78,0x26300001,
|
||||
0xc78,0x25310001,
|
||||
0xc78,0x24320001,
|
||||
0xc78,0x23330001,
|
||||
0xc78,0x22340001,
|
||||
0xc78,0x09350001,
|
||||
0xc78,0x08360001,
|
||||
0xc78,0x07370001,
|
||||
0xc78,0x06380001,
|
||||
0xc78,0x05390001,
|
||||
0xc78,0x043a0001,
|
||||
0xc78,0x033b0001,
|
||||
0xc78,0x023c0001,
|
||||
0xc78,0x013d0001,
|
||||
0xc78,0x003e0001,
|
||||
0xc78,0x003f0001,
|
||||
0xc78,0x7f400001,
|
||||
0xc78,0x7f410001,
|
||||
0xc78,0x7e420001,
|
||||
0xc78,0x7d430001,
|
||||
0xc78,0x7c440001,
|
||||
0xc78,0x7b450001,
|
||||
0xc78,0x7a460001,
|
||||
0xc78,0x79470001,
|
||||
0xc78,0x78480001,
|
||||
0xc78,0x77490001,
|
||||
0xc78,0x764a0001,
|
||||
0xc78,0x754b0001,
|
||||
0xc78,0x744c0001,
|
||||
0xc78,0x734d0001,
|
||||
0xc78,0x724e0001,
|
||||
0xc78,0x714f0001,
|
||||
0xc78,0x70500001,
|
||||
0xc78,0x6f510001,
|
||||
0xc78,0x6f520001,
|
||||
0xc78,0x6e530001,
|
||||
0xc78,0x6d540001,
|
||||
0xc78,0x6d550001,
|
||||
0xc78,0x6c560001,
|
||||
0xc78,0x6b570001,
|
||||
0xc78,0x6a580001,
|
||||
0xc78,0x6a590001,
|
||||
0xc78,0x695a0001,
|
||||
0xc78,0x685b0001,
|
||||
0xc78,0x675c0001,
|
||||
0xc78,0x665d0001,
|
||||
0xc78,0x655e0001,
|
||||
0xc78,0x645f0001,
|
||||
0xc78,0x63600001,
|
||||
0xc78,0x4c610001,
|
||||
0xc78,0x4b620001,
|
||||
0xc78,0x4a630001,
|
||||
0xc78,0x49640001,
|
||||
0xc78,0x48650001,
|
||||
0xc78,0x47660001,
|
||||
0xc78,0x46670001,
|
||||
0xc78,0x45680001,
|
||||
0xc78,0x44690001,
|
||||
0xc78,0x2c6a0001,
|
||||
0xc78,0x2b6b0001,
|
||||
0xc78,0x2a6c0001,
|
||||
0xc78,0x296d0001,
|
||||
0xc78,0x286e0001,
|
||||
0xc78,0x276f0001,
|
||||
0xc78,0x26700001,
|
||||
0xc78,0x25710001,
|
||||
0xc78,0x24720001,
|
||||
0xc78,0x23730001,
|
||||
0xc78,0x22740001,
|
||||
0xc78,0x09750001,
|
||||
0xc78,0x08760001,
|
||||
0xc78,0x07770001,
|
||||
0xc78,0x06780001,
|
||||
0xc78,0x05790001,
|
||||
0xc78,0x047a0001,
|
||||
0xc78,0x037b0001,
|
||||
0xc78,0x027c0001,
|
||||
0xc78,0x017d0001,
|
||||
0xc78,0x007e0001,
|
||||
0xc78,0x007f0001,
|
||||
0xc78,0x3000001e,
|
||||
0xc78,0x3001001e,
|
||||
0xc78,0x3002001e,
|
||||
0xc78,0x3003001e,
|
||||
0xc78,0x3004001e,
|
||||
0xc78,0x3405001e,
|
||||
0xc78,0x3806001e,
|
||||
0xc78,0x3e07001e,
|
||||
0xc78,0x3e08001e,
|
||||
0xc78,0x4409001e,
|
||||
0xc78,0x460a001e,
|
||||
0xc78,0x480b001e,
|
||||
0xc78,0x480c001e,
|
||||
0xc78,0x4e0d001e,
|
||||
0xc78,0x560e001e,
|
||||
0xc78,0x5a0f001e,
|
||||
0xc78,0x5e10001e,
|
||||
0xc78,0x6211001e,
|
||||
0xc78,0x6c12001e,
|
||||
0xc78,0x7213001e,
|
||||
0xc78,0x7214001e,
|
||||
0xc78,0x7215001e,
|
||||
0xc78,0x7216001e,
|
||||
0xc78,0x7217001e,
|
||||
0xc78,0x7218001e,
|
||||
0xc78,0x7219001e,
|
||||
0xc78,0x721a001e,
|
||||
0xc78,0x721b001e,
|
||||
0xc78,0x721c001e,
|
||||
0xc78,0x721d001e,
|
||||
0xc78,0x721e001e,
|
||||
0xc78,0x721f001e,
|
||||
};
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
/******************************************************************************
|
||||
* 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_HAL8192SU_FW_IMG_H
|
||||
#define __INC_HAL8192SU_FW_IMG_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
/*Created on 2009/ 3/ 6, 5:29*/
|
||||
|
||||
#define MainArrayLength 1
|
||||
extern u8 Rtl8192SUFwMainArray[MainArrayLength];
|
||||
#define DataArrayLength 1
|
||||
extern u8 Rtl8192SUFwDataArray[DataArrayLength];
|
||||
#define PHY_REG_2T2RArrayLength 372
|
||||
extern u32 Rtl8192SUPHY_REG_2T2RArray[PHY_REG_2T2RArrayLength];
|
||||
#define PHY_REG_1T2RArrayLength 1
|
||||
extern u32 Rtl8192SUPHY_REG_1T2RArray[PHY_REG_1T2RArrayLength];
|
||||
#define PHY_ChangeTo_1T1RArrayLength 48
|
||||
extern u32 Rtl8192SUPHY_ChangeTo_1T1RArray[PHY_ChangeTo_1T1RArrayLength];
|
||||
#define PHY_ChangeTo_1T2RArrayLength 45
|
||||
extern u32 Rtl8192SUPHY_ChangeTo_1T2RArray[PHY_ChangeTo_1T2RArrayLength];
|
||||
#define PHY_ChangeTo_2T2RArrayLength 45
|
||||
extern u32 Rtl8192SUPHY_ChangeTo_2T2RArray[PHY_ChangeTo_2T2RArrayLength];
|
||||
#define PHY_REG_Array_PGLength 84
|
||||
extern u32 Rtl8192SUPHY_REG_Array_PG[PHY_REG_Array_PGLength];
|
||||
#define RadioA_1T_ArrayLength 202
|
||||
extern u32 Rtl8192SURadioA_1T_Array[RadioA_1T_ArrayLength];
|
||||
#define RadioB_ArrayLength 22
|
||||
extern u32 Rtl8192SURadioB_Array[RadioB_ArrayLength];
|
||||
#define RadioA_to1T_ArrayLength 2
|
||||
extern u32 Rtl8192SURadioA_to1T_Array[RadioA_to1T_ArrayLength];
|
||||
#define RadioA_to2T_ArrayLength 2
|
||||
extern u32 Rtl8192SURadioA_to2T_Array[RadioA_to2T_ArrayLength];
|
||||
#define RadioB_GM_ArrayLength 16
|
||||
extern u32 Rtl8192SURadioB_GM_Array[RadioB_GM_ArrayLength];
|
||||
#define MAC_2T_ArrayLength 106
|
||||
extern u32 Rtl8192SUMAC_2T_Array[MAC_2T_ArrayLength];
|
||||
#define MACPHY_Array_PGLength 1
|
||||
extern u32 Rtl8192SUMACPHY_Array_PG[MACPHY_Array_PGLength];
|
||||
#define AGCTAB_ArrayLength 320
|
||||
extern u32 Rtl8192SUAGCTAB_Array[AGCTAB_ArrayLength];
|
||||
|
||||
#endif
|
||||
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,93 +0,0 @@
|
|||
/******************************************************************************
|
||||
* 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_HAL8192USBLED_H
|
||||
#define __INC_HAL8192USBLED_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/timer.h>
|
||||
|
||||
typedef enum _LED_STATE_819xUsb{
|
||||
LED_UNKNOWN = 0,
|
||||
LED_ON = 1,
|
||||
LED_OFF = 2,
|
||||
LED_BLINK_NORMAL = 3,
|
||||
LED_BLINK_SLOWLY = 4,
|
||||
LED_POWER_ON_BLINK = 5,
|
||||
LED_SCAN_BLINK = 6,
|
||||
LED_NO_LINK_BLINK = 7,
|
||||
LED_BLINK_StartToBlink = 8,
|
||||
LED_BLINK_WPS = 9,
|
||||
LED_TXRX_BLINK = 10,
|
||||
LED_BLINK_WPS_STOP = 11,
|
||||
LED_BLINK_WPS_STOP_OVERLAP = 12,
|
||||
|
||||
}LED_STATE_819xUsb;
|
||||
|
||||
#define IS_LED_WPS_BLINKING(_LED_819xUsb) (((PLED_819xUsb)_LED_819xUsb)->CurrLedState==LED_BLINK_WPS \
|
||||
|| ((PLED_819xUsb)_LED_819xUsb)->CurrLedState==LED_BLINK_WPS_STOP \
|
||||
|| ((PLED_819xUsb)_LED_819xUsb)->bLedWPSBlinkInProgress)
|
||||
|
||||
#define IS_LED_BLINKING(_LED_819xUsb) (((PLED_819xUsb)_LED_819xUsb)->bLedWPSBlinkInProgress \
|
||||
||((PLED_819xUsb)_LED_819xUsb)->bLedScanBlinkInProgress)
|
||||
|
||||
typedef enum _LED_PIN_819xUsb{
|
||||
LED_PIN_GPIO0,
|
||||
LED_PIN_LED0,
|
||||
LED_PIN_LED1
|
||||
}LED_PIN_819xUsb;
|
||||
|
||||
typedef enum _LED_STRATEGY_819xUsb{
|
||||
SW_LED_MODE0, /* SW control 1 LED via GPIO0. It is default option. */
|
||||
SW_LED_MODE1, /* SW control for PCI Express */
|
||||
SW_LED_MODE2, /* SW control for Cameo. */
|
||||
SW_LED_MODE3, /* SW contorl for RunTop. */
|
||||
SW_LED_MODE4, /* SW control for Netcore */
|
||||
SW_LED_MODE5,
|
||||
HW_LED, /* HW control 2 LEDs, LED0 and LED1 (there are 4 different control modes) */
|
||||
}LED_STRATEGY_819xUsb, *PLED_STRATEGY_819xUsb;
|
||||
|
||||
typedef struct _LED_819xUsb{
|
||||
struct net_device *dev;
|
||||
|
||||
LED_PIN_819xUsb LedPin;
|
||||
|
||||
LED_STATE_819xUsb CurrLedState;
|
||||
bool bLedOn;
|
||||
|
||||
bool bSWLedCtrl;
|
||||
|
||||
bool bLedBlinkInProgress;
|
||||
bool bLedNoLinkBlinkInProgress;
|
||||
bool bLedLinkBlinkInProgress;
|
||||
bool bLedStartToLinkBlinkInProgress;
|
||||
bool bLedScanBlinkInProgress;
|
||||
bool bLedWPSBlinkInProgress;
|
||||
|
||||
u32 BlinkTimes;
|
||||
LED_STATE_819xUsb BlinkingLedState;
|
||||
|
||||
struct timer_list BlinkTimer;
|
||||
} LED_819xUsb, *PLED_819xUsb;
|
||||
|
||||
void InitSwLeds(struct net_device *dev);
|
||||
void DeInitSwLeds(struct net_device *dev);
|
||||
void LedControl8192SUsb(struct net_device *dev,LED_CTL_MODE LedAction);
|
||||
|
||||
#endif
|
||||
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,79 +0,0 @@
|
|||
/******************************************************************************
|
||||
* 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 __INC_EFUSE_H
|
||||
#define __INC_EFUSE_H
|
||||
|
||||
#define EFUSE_FOR_92SU 1
|
||||
|
||||
#define EFUSE_MAC_LEN 0x200
|
||||
#define EFUSE_REAL_CONTENT_LEN 512
|
||||
#define EFUSE_MAP_LEN 128
|
||||
#define EFUSE_MAX_SECTION 16
|
||||
#define EFUSE_MAX_WORD_UNIT 4
|
||||
|
||||
#define EFUSE_INIT_MAP 0
|
||||
#define EFUSE_MODIFY_MAP 1
|
||||
|
||||
#define EFUSE_CLK_CTRL EFUSE_CTRL
|
||||
#define EFUSE_BIT(x) (1 << (x))
|
||||
|
||||
#define PG_STATE_HEADER 0x01
|
||||
#define PG_STATE_WORD_0 0x02
|
||||
#define PG_STATE_WORD_1 0x04
|
||||
#define PG_STATE_WORD_2 0x08
|
||||
#define PG_STATE_WORD_3 0x10
|
||||
#define PG_STATE_DATA 0x20
|
||||
|
||||
#define PG_SWBYTE_H 0x01
|
||||
#define PG_SWBYTE_L 0x02
|
||||
|
||||
extern void
|
||||
EFUSE_Initialize(struct net_device* dev);
|
||||
extern u8
|
||||
EFUSE_Read1Byte(struct net_device* dev,u16 Address);
|
||||
extern void
|
||||
EFUSE_Write1Byte(struct net_device* dev,u16 Address,u8 Value);
|
||||
|
||||
#ifdef EFUSE_FOR_92SU
|
||||
extern void
|
||||
ReadEFuse(struct net_device* dev,u16 _offset,u16 _size_byte,u8* pbuf);
|
||||
extern void
|
||||
ReadEFuseByte(struct net_device* dev,u16 _offset,u8 *pbuf);
|
||||
#endif
|
||||
|
||||
extern void
|
||||
EFUSE_ShadowRead(struct net_device* dev,unsigned char Type,unsigned short Offset,u32 *Value);
|
||||
extern void
|
||||
EFUSE_ShadowWrite(struct net_device* dev,unsigned char Type,unsigned short Offset,u32 Value);
|
||||
extern bool
|
||||
EFUSE_ShadowUpdate(struct net_device* dev);
|
||||
extern void
|
||||
EFUSE_ShadowMapUpdate(struct net_device* dev);
|
||||
|
||||
extern bool
|
||||
EFUSE_ProgramMap(struct net_device* dev,char* pFileName, u8 TableType); // 0=Shadow 1=Real Efuse
|
||||
|
||||
#endif
|
|
@ -1,481 +0,0 @@
|
|||
/******************************************************************************
|
||||
* 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 "r8192U.h"
|
||||
#include "r8192S_firmware.h"
|
||||
#include <linux/unistd.h>
|
||||
|
||||
#include "r8192S_hw.h"
|
||||
#include "r8192SU_HWImg.h"
|
||||
|
||||
#include <linux/firmware.h>
|
||||
|
||||
#define byte(x,n) ( (x >> (8 * n)) & 0xff )
|
||||
|
||||
//
|
||||
// Description: This routine will intialize firmware. If any error occurs during the initialization
|
||||
// process, the routine shall terminate immediately and return fail.
|
||||
//
|
||||
// Arguments: The pointer of the adapter
|
||||
// Code address (Virtual address, should fill descriptor with physical address)
|
||||
// Code size
|
||||
// Created by Roger, 2008.04.10.
|
||||
//
|
||||
bool FirmwareDownloadCode(struct net_device *dev,
|
||||
u8 *code_virtual_address,
|
||||
u32 buffer_len)
|
||||
{
|
||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
||||
bool rt_status = true;
|
||||
/* Fragmentation might be required in 90/92 but not in 92S */
|
||||
u16 frag_threshold = MAX_FIRMWARE_CODE_SIZE;
|
||||
u16 frag_length, frag_offset = 0;
|
||||
struct sk_buff *skb;
|
||||
unsigned char *seg_ptr;
|
||||
cb_desc *tcb_desc;
|
||||
u8 bLastIniPkt = 0;
|
||||
u16 ExtraDescOffset = 0;
|
||||
|
||||
if (buffer_len >= MAX_FIRMWARE_CODE_SIZE - USB_HWDESC_HEADER_LEN) {
|
||||
RT_TRACE(COMP_ERR, "(%s): Firmware exceeds"
|
||||
" MAX_FIRMWARE_CODE_SIZE\n", __func__);
|
||||
goto cmdsend_downloadcode_fail;
|
||||
}
|
||||
ExtraDescOffset = USB_HWDESC_HEADER_LEN;
|
||||
do {
|
||||
if((buffer_len-frag_offset) > frag_threshold)
|
||||
frag_length = frag_threshold + ExtraDescOffset;
|
||||
else {
|
||||
frag_length = (u16)(buffer_len -
|
||||
frag_offset + ExtraDescOffset);
|
||||
bLastIniPkt = 1;
|
||||
}
|
||||
/*
|
||||
* Allocate skb buffer to contain firmware info
|
||||
* and tx descriptor info.
|
||||
*/
|
||||
skb = dev_alloc_skb(frag_length);
|
||||
if (skb == NULL) {
|
||||
RT_TRACE(COMP_ERR, "(%s): unable to alloc skb buffer\n",
|
||||
__func__);
|
||||
goto cmdsend_downloadcode_fail;
|
||||
}
|
||||
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;
|
||||
|
||||
skb_reserve(skb, ExtraDescOffset);
|
||||
|
||||
seg_ptr = (u8 *)skb_put(skb,
|
||||
(u32)(frag_length - ExtraDescOffset));
|
||||
|
||||
memcpy(seg_ptr, code_virtual_address + frag_offset,
|
||||
(u32)(frag_length-ExtraDescOffset));
|
||||
|
||||
tcb_desc->txbuf_size = frag_length;
|
||||
|
||||
if (!priv->ieee80211->check_nic_enough_desc(dev, tcb_desc->queue_index) ||
|
||||
(!skb_queue_empty(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index])) ||
|
||||
(priv->ieee80211->queue_stop)) {
|
||||
RT_TRACE(COMP_FIRMWARE,"=====================================================> tx full!\n");
|
||||
skb_queue_tail(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index], skb);
|
||||
} else
|
||||
priv->ieee80211->softmac_hard_start_xmit(skb, dev);
|
||||
|
||||
frag_offset += (frag_length - ExtraDescOffset);
|
||||
|
||||
} while (frag_offset < buffer_len);
|
||||
return rt_status ;
|
||||
|
||||
cmdsend_downloadcode_fail:
|
||||
rt_status = false;
|
||||
RT_TRACE(COMP_ERR, "(%s): failed\n", __func__);
|
||||
return rt_status;
|
||||
}
|
||||
|
||||
|
||||
bool FirmwareEnableCPU(struct net_device *dev)
|
||||
{
|
||||
bool rtStatus = true;
|
||||
u8 tmpU1b, CPUStatus = 0;
|
||||
u16 tmpU2b;
|
||||
u32 iCheckTime = 200;
|
||||
|
||||
/* Enable CPU. */
|
||||
tmpU1b = read_nic_byte(dev, SYS_CLKR);
|
||||
/* AFE source */
|
||||
write_nic_byte(dev, SYS_CLKR, (tmpU1b|SYS_CPU_CLKSEL));
|
||||
tmpU2b = read_nic_word(dev, SYS_FUNC_EN);
|
||||
write_nic_word(dev, SYS_FUNC_EN, (tmpU2b|FEN_CPUEN));
|
||||
/* Poll IMEM Ready after CPU has refilled. */
|
||||
do {
|
||||
CPUStatus = read_nic_byte(dev, TCR);
|
||||
if (CPUStatus & IMEM_RDY)
|
||||
/* success */
|
||||
break;
|
||||
udelay(100);
|
||||
} while (iCheckTime--);
|
||||
if (!(CPUStatus & IMEM_RDY)) {
|
||||
RT_TRACE(COMP_ERR, "%s(): failed to enable CPU", __func__);
|
||||
rtStatus = false;
|
||||
}
|
||||
return rtStatus;
|
||||
}
|
||||
|
||||
FIRMWARE_8192S_STATUS
|
||||
FirmwareGetNextStatus(FIRMWARE_8192S_STATUS FWCurrentStatus)
|
||||
{
|
||||
FIRMWARE_8192S_STATUS NextFWStatus = 0;
|
||||
|
||||
switch(FWCurrentStatus)
|
||||
{
|
||||
case FW_STATUS_INIT:
|
||||
NextFWStatus = FW_STATUS_LOAD_IMEM;
|
||||
break;
|
||||
|
||||
case FW_STATUS_LOAD_IMEM:
|
||||
NextFWStatus = FW_STATUS_LOAD_EMEM;
|
||||
break;
|
||||
|
||||
case FW_STATUS_LOAD_EMEM:
|
||||
NextFWStatus = FW_STATUS_LOAD_DMEM;
|
||||
break;
|
||||
|
||||
case FW_STATUS_LOAD_DMEM:
|
||||
NextFWStatus = FW_STATUS_READY;
|
||||
break;
|
||||
|
||||
default:
|
||||
RT_TRACE(COMP_ERR,"Invalid FW Status(%#x)!!\n", FWCurrentStatus);
|
||||
break;
|
||||
}
|
||||
return NextFWStatus;
|
||||
}
|
||||
|
||||
bool FirmwareCheckReady(struct net_device *dev, u8 LoadFWStatus)
|
||||
{
|
||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
||||
bool rtStatus = true;
|
||||
rt_firmware *pFirmware = priv->pFirmware;
|
||||
int PollingCnt = 1000;
|
||||
u8 CPUStatus = 0;
|
||||
u32 tmpU4b;
|
||||
|
||||
pFirmware->FWStatus = (FIRMWARE_8192S_STATUS)LoadFWStatus;
|
||||
switch (LoadFWStatus) {
|
||||
case FW_STATUS_LOAD_IMEM:
|
||||
do { /* Polling IMEM code done. */
|
||||
CPUStatus = read_nic_byte(dev, TCR);
|
||||
if(CPUStatus& IMEM_CODE_DONE)
|
||||
break;
|
||||
udelay(5);
|
||||
} while (PollingCnt--);
|
||||
if (!(CPUStatus & IMEM_CHK_RPT) || PollingCnt <= 0) {
|
||||
RT_TRACE(COMP_ERR, "FW_STATUS_LOAD_IMEM FAIL CPU, Status=%x\r\n", CPUStatus);
|
||||
goto FirmwareCheckReadyFail;
|
||||
}
|
||||
break;
|
||||
case FW_STATUS_LOAD_EMEM: /* Check Put Code OK and Turn On CPU */
|
||||
do { /* Polling EMEM code done. */
|
||||
CPUStatus = read_nic_byte(dev, TCR);
|
||||
if(CPUStatus& EMEM_CODE_DONE)
|
||||
break;
|
||||
udelay(5);
|
||||
} while (PollingCnt--);
|
||||
if (!(CPUStatus & EMEM_CHK_RPT)) {
|
||||
RT_TRACE(COMP_ERR, "FW_STATUS_LOAD_EMEM FAIL CPU, Status=%x\r\n", CPUStatus);
|
||||
goto FirmwareCheckReadyFail;
|
||||
}
|
||||
/* Turn On CPU */
|
||||
if (FirmwareEnableCPU(dev) != true) {
|
||||
RT_TRACE(COMP_ERR, "%s(): failed to enable CPU",
|
||||
__func__);
|
||||
goto FirmwareCheckReadyFail;
|
||||
}
|
||||
break;
|
||||
case FW_STATUS_LOAD_DMEM:
|
||||
do { /* Polling DMEM code done */
|
||||
CPUStatus = read_nic_byte(dev, TCR);
|
||||
if(CPUStatus& DMEM_CODE_DONE)
|
||||
break;
|
||||
|
||||
udelay(5);
|
||||
} while (PollingCnt--);
|
||||
|
||||
if (!(CPUStatus & DMEM_CODE_DONE)) {
|
||||
RT_TRACE(COMP_ERR, "Polling DMEM code done fail ! CPUStatus(%#x)\n", CPUStatus);
|
||||
goto FirmwareCheckReadyFail;
|
||||
}
|
||||
|
||||
RT_TRACE(COMP_FIRMWARE, "%s(): DMEM code download success, "
|
||||
"CPUStatus(%#x)",
|
||||
__func__, CPUStatus);
|
||||
|
||||
PollingCnt = 10000; /* Set polling cycle to 10ms. */
|
||||
|
||||
do { /* Polling Load Firmware ready */
|
||||
CPUStatus = read_nic_byte(dev, TCR);
|
||||
if(CPUStatus & FWRDY)
|
||||
break;
|
||||
udelay(100);
|
||||
} while (PollingCnt--);
|
||||
|
||||
RT_TRACE(COMP_FIRMWARE, "%s(): polling load firmware ready, "
|
||||
"CPUStatus(%x)",
|
||||
__func__, CPUStatus);
|
||||
|
||||
if ((CPUStatus & LOAD_FW_READY) != LOAD_FW_READY) {
|
||||
RT_TRACE(COMP_ERR, "Polling Load Firmware ready failed "
|
||||
"CPUStatus(%x)\n", CPUStatus);
|
||||
goto FirmwareCheckReadyFail;
|
||||
}
|
||||
/*
|
||||
* USB interface will update
|
||||
* reserved followings parameters later
|
||||
*/
|
||||
|
||||
//
|
||||
// <Roger_Notes> If right here, we can set TCR/RCR to desired value
|
||||
// and config MAC lookback mode to normal mode. 2008.08.28.
|
||||
//
|
||||
tmpU4b = read_nic_dword(dev,TCR);
|
||||
write_nic_dword(dev, TCR, (tmpU4b&(~TCR_ICV)));
|
||||
|
||||
tmpU4b = read_nic_dword(dev, RCR);
|
||||
write_nic_dword(dev, RCR,
|
||||
(tmpU4b|RCR_APPFCS|RCR_APP_ICV|RCR_APP_MIC));
|
||||
|
||||
RT_TRACE(COMP_FIRMWARE, "%s(): Current RCR settings(%#x)",
|
||||
__func__, tmpU4b);
|
||||
// Set to normal mode.
|
||||
write_nic_byte(dev, LBKMD_SEL, LBK_NORMAL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
RT_TRACE(COMP_FIRMWARE, "%s(): LoadFWStatus(%d), success",
|
||||
__func__, LoadFWStatus);
|
||||
return rtStatus;
|
||||
|
||||
FirmwareCheckReadyFail:
|
||||
rtStatus = false;
|
||||
RT_TRACE(COMP_FIRMWARE, "%s(): LoadFWStatus(%d), failed",
|
||||
__func__, LoadFWStatus);
|
||||
return rtStatus;
|
||||
}
|
||||
|
||||
//
|
||||
// Description: This routine is to update the RF types in FW header partially.
|
||||
//
|
||||
// Created by Roger, 2008.12.24.
|
||||
//
|
||||
u8 FirmwareHeaderMapRfType(struct net_device *dev)
|
||||
{
|
||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
||||
switch(priv->rf_type)
|
||||
{
|
||||
case RF_1T1R: return 0x11;
|
||||
case RF_1T2R: return 0x12;
|
||||
case RF_2T2R: return 0x22;
|
||||
case RF_2T2R_GREEN: return 0x92;
|
||||
default:
|
||||
RT_TRACE(COMP_INIT, "Unknown RF type(%x)\n",priv->rf_type);
|
||||
break;
|
||||
}
|
||||
return 0x22;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Description: This routine is to update the private parts in FW header partially.
|
||||
//
|
||||
// Created by Roger, 2008.12.18.
|
||||
//
|
||||
void FirmwareHeaderPriveUpdate(struct net_device *dev, PRT_8192S_FIRMWARE_PRIV pFwPriv)
|
||||
{
|
||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
||||
// Update USB endpoint number for RQPN settings.
|
||||
pFwPriv->usb_ep_num = priv->EEPROMUsbEndPointNumber; // endpoint number: 4, 6 and 11.
|
||||
RT_TRACE(COMP_INIT, "FirmwarePriveUpdate(): usb_ep_num(%#x)\n", pFwPriv->usb_ep_num);
|
||||
|
||||
// Update RF types for RATR settings.
|
||||
pFwPriv->rf_config = FirmwareHeaderMapRfType(dev);
|
||||
}
|
||||
|
||||
bool FirmwareRequest92S(struct net_device *dev, rt_firmware *pFirmware)
|
||||
{
|
||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
||||
bool rtStatus = true;
|
||||
const char *pFwImageFileName[1] = {"RTL8192SU/rtl8192sfw.bin"};
|
||||
u8 *pucMappedFile = NULL;
|
||||
u32 ulInitStep = 0;
|
||||
u8 FwHdrSize = RT_8192S_FIRMWARE_HDR_SIZE;
|
||||
PRT_8192S_FIRMWARE_HDR pFwHdr = NULL;
|
||||
u32 file_length = 0;
|
||||
int rc;
|
||||
const struct firmware *fw_entry;
|
||||
|
||||
rc = request_firmware(&fw_entry,
|
||||
pFwImageFileName[ulInitStep],
|
||||
&priv->udev->dev);
|
||||
if (rc < 0)
|
||||
goto RequestFirmware_Fail;
|
||||
|
||||
if (fw_entry->size > sizeof(pFirmware->szFwTmpBuffer)) {
|
||||
RT_TRACE(COMP_ERR, "%s(): image file too large"
|
||||
"for container buffer", __func__);
|
||||
release_firmware(fw_entry);
|
||||
goto RequestFirmware_Fail;
|
||||
}
|
||||
|
||||
memcpy(pFirmware->szFwTmpBuffer, fw_entry->data, fw_entry->size);
|
||||
pFirmware->szFwTmpBufferLen = fw_entry->size;
|
||||
release_firmware(fw_entry);
|
||||
|
||||
pucMappedFile = pFirmware->szFwTmpBuffer;
|
||||
file_length = pFirmware->szFwTmpBufferLen;
|
||||
|
||||
/* Retrieve FW header. */
|
||||
pFirmware->pFwHeader = (PRT_8192S_FIRMWARE_HDR) pucMappedFile;
|
||||
pFwHdr = pFirmware->pFwHeader;
|
||||
|
||||
RT_TRACE(COMP_FIRMWARE, "%s(): signature: %x, version: %x, "
|
||||
"size: %x, imemsize: %x, sram size: %x",
|
||||
__func__, pFwHdr->Signature, pFwHdr->Version,
|
||||
pFwHdr->DMEMSize, pFwHdr->IMG_IMEM_SIZE,
|
||||
pFwHdr->IMG_SRAM_SIZE);
|
||||
|
||||
pFirmware->FirmwareVersion = byte(pFwHdr->Version , 0);
|
||||
|
||||
if ((pFwHdr->IMG_IMEM_SIZE == 0) ||
|
||||
(pFwHdr->IMG_IMEM_SIZE > sizeof(pFirmware->FwIMEM))) {
|
||||
RT_TRACE(COMP_ERR, "%s(): memory for data image is less than"
|
||||
" IMEM requires", __func__);
|
||||
goto RequestFirmware_Fail;
|
||||
} else {
|
||||
pucMappedFile += FwHdrSize;
|
||||
/* Retrieve IMEM image. */
|
||||
memcpy(pFirmware->FwIMEM, pucMappedFile, pFwHdr->IMG_IMEM_SIZE);
|
||||
pFirmware->FwIMEMLen = pFwHdr->IMG_IMEM_SIZE;
|
||||
}
|
||||
|
||||
if (pFwHdr->IMG_SRAM_SIZE > sizeof(pFirmware->FwEMEM)) {
|
||||
RT_TRACE(COMP_ERR, "%s(): memory for data image is less than"
|
||||
" EMEM requires", __func__);
|
||||
goto RequestFirmware_Fail;
|
||||
} else {
|
||||
pucMappedFile += pFirmware->FwIMEMLen;
|
||||
/* Retriecve EMEM image */
|
||||
memcpy(pFirmware->FwEMEM, pucMappedFile, pFwHdr->IMG_SRAM_SIZE);
|
||||
pFirmware->FwEMEMLen = pFwHdr->IMG_SRAM_SIZE;
|
||||
}
|
||||
return rtStatus;
|
||||
|
||||
RequestFirmware_Fail:
|
||||
RT_TRACE(COMP_ERR, "%s(): failed with TCR-Status: %x\n",
|
||||
__func__, read_nic_word(dev, TCR));
|
||||
rtStatus = false;
|
||||
return rtStatus;
|
||||
}
|
||||
|
||||
bool FirmwareDownload92S(struct net_device *dev)
|
||||
{
|
||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
||||
bool rtStatus = true;
|
||||
u8 *pucMappedFile = NULL;
|
||||
u32 ulFileLength;
|
||||
u8 FwHdrSize = RT_8192S_FIRMWARE_HDR_SIZE;
|
||||
rt_firmware *pFirmware = priv->pFirmware;
|
||||
u8 FwStatus = FW_STATUS_INIT;
|
||||
PRT_8192S_FIRMWARE_HDR pFwHdr = NULL;
|
||||
PRT_8192S_FIRMWARE_PRIV pFwPriv = NULL;
|
||||
|
||||
pFirmware->FWStatus = FW_STATUS_INIT;
|
||||
/*
|
||||
* Load the firmware from RTL8192SU/rtl8192sfw.bin if necessary
|
||||
*/
|
||||
if (pFirmware->szFwTmpBufferLen == 0) {
|
||||
if (FirmwareRequest92S(dev, pFirmware) != true)
|
||||
goto DownloadFirmware_Fail;
|
||||
}
|
||||
FwStatus = FirmwareGetNextStatus(pFirmware->FWStatus);
|
||||
while (FwStatus != FW_STATUS_READY) {
|
||||
/* Image buffer redirection. */
|
||||
switch (FwStatus) {
|
||||
case FW_STATUS_LOAD_IMEM:
|
||||
pucMappedFile = pFirmware->FwIMEM;
|
||||
ulFileLength = pFirmware->FwIMEMLen;
|
||||
break;
|
||||
|
||||
case FW_STATUS_LOAD_EMEM:
|
||||
pucMappedFile = pFirmware->FwEMEM;
|
||||
ulFileLength = pFirmware->FwEMEMLen;
|
||||
break;
|
||||
|
||||
case FW_STATUS_LOAD_DMEM:
|
||||
/* Partial update the content of private header */
|
||||
pFwHdr = pFirmware->pFwHeader;
|
||||
pFwPriv = (PRT_8192S_FIRMWARE_PRIV)&pFwHdr->FWPriv;
|
||||
FirmwareHeaderPriveUpdate(dev, pFwPriv);
|
||||
pucMappedFile = (u8 *)(pFirmware->pFwHeader) +
|
||||
RT_8192S_FIRMWARE_HDR_EXCLUDE_PRI_SIZE;
|
||||
|
||||
ulFileLength = FwHdrSize -
|
||||
RT_8192S_FIRMWARE_HDR_EXCLUDE_PRI_SIZE;
|
||||
break;
|
||||
|
||||
default:
|
||||
RT_TRACE(COMP_ERR, "Unexpected Download step!!\n");
|
||||
goto DownloadFirmware_Fail;
|
||||
break;
|
||||
}
|
||||
|
||||
/* <2> Download image file */
|
||||
|
||||
rtStatus = FirmwareDownloadCode(dev,
|
||||
pucMappedFile,
|
||||
ulFileLength);
|
||||
|
||||
if(rtStatus != true)
|
||||
goto DownloadFirmware_Fail;
|
||||
|
||||
/* <3> Check whether load FW process is ready */
|
||||
|
||||
rtStatus = FirmwareCheckReady(dev, FwStatus);
|
||||
|
||||
if(rtStatus != true)
|
||||
goto DownloadFirmware_Fail;
|
||||
|
||||
FwStatus = FirmwareGetNextStatus(pFirmware->FWStatus);
|
||||
}
|
||||
|
||||
RT_TRACE(COMP_FIRMWARE, "%s(): Firmware Download Success", __func__);
|
||||
return rtStatus;
|
||||
|
||||
DownloadFirmware_Fail:
|
||||
RT_TRACE(COMP_ERR, "%s(): failed with TCR-Status: %x\n",
|
||||
__func__, read_nic_word(dev, TCR));
|
||||
rtStatus = false;
|
||||
return rtStatus;
|
||||
}
|
||||
|
||||
MODULE_FIRMWARE("RTL8192SU/rtl8192sfw.bin");
|
|
@ -1,210 +0,0 @@
|
|||
/******************************************************************************
|
||||
* 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_MAX_FIRMWARE_CODE_SIZE 64000 //64k
|
||||
#define MAX_FIRMWARE_CODE_SIZE 0xFF00 // Firmware Local buffer size.
|
||||
#define RTL8190_CPU_START_OFFSET 0x80
|
||||
#define RTL8192S_FW_PKT_FRAG_SIZE 0x4000
|
||||
#define GET_COMMAND_PACKET_FRAG_THRESHOLD(v) (4*(v/4) - 8 - USB_HWDESC_HEADER_LEN)
|
||||
|
||||
|
||||
#ifdef RTL8192S
|
||||
typedef enum _firmware_init_step{
|
||||
FW_INIT_STEP0_IMEM = 0,
|
||||
FW_INIT_STEP1_MAIN = 1,
|
||||
FW_INIT_STEP2_DATA = 2,
|
||||
}firmware_init_step_e;
|
||||
#else
|
||||
typedef enum _firmware_init_step{
|
||||
FW_INIT_STEP0_BOOT = 0,
|
||||
FW_INIT_STEP1_MAIN = 1,
|
||||
FW_INIT_STEP2_DATA = 2,
|
||||
}firmware_init_step_e;
|
||||
#endif
|
||||
|
||||
/* due to rtl8192 firmware */
|
||||
typedef enum _desc_packet_type_e{
|
||||
DESC_PACKET_TYPE_INIT = 0,
|
||||
DESC_PACKET_TYPE_NORMAL = 1,
|
||||
}desc_packet_type_e;
|
||||
|
||||
typedef enum _opt_rst_type{
|
||||
OPT_SYSTEM_RESET = 0,
|
||||
OPT_FIRMWARE_RESET = 1,
|
||||
}opt_rst_type_e;
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// RTL8192S Firmware related
|
||||
//--------------------------------------------------------------------------------
|
||||
typedef struct _RT_8192S_FIRMWARE_PRIV { //8-bytes alignment required
|
||||
|
||||
//--- long word 0 ----
|
||||
u8 signature_0; //0x12: CE product, 0x92: IT product
|
||||
u8 signature_1; //0x87: CE product, 0x81: IT product
|
||||
u8 hci_sel; //0x81: PCI-AP, 01:PCIe, 02: 92S-U, 0x82: USB-AP, 0x12: 72S-U, 03:SDIO
|
||||
u8 chip_version; //the same value as reigster value
|
||||
u8 customer_ID_0; //customer ID low byte
|
||||
u8 customer_ID_1; //customer ID high byte
|
||||
u8 rf_config; //0x11: 1T1R, 0x12: 1T2R, 0x92: 1T2R turbo, 0x22: 2T2R
|
||||
u8 usb_ep_num; // 4: 4EP, 6: 6EP, 11: 11EP
|
||||
|
||||
//--- long word 1 ----
|
||||
u8 regulatory_class_0; //regulatory class bit map 0
|
||||
u8 regulatory_class_1; //regulatory class bit map 1
|
||||
u8 regulatory_class_2; //regulatory class bit map 2
|
||||
u8 regulatory_class_3; //regulatory class bit map 3
|
||||
u8 rfintfs; // 0:SWSI, 1:HWSI, 2:HWPI
|
||||
u8 def_nettype;
|
||||
u8 rsvd010;
|
||||
u8 rsvd011;
|
||||
|
||||
|
||||
//--- long word 2 ----
|
||||
u8 lbk_mode; //0x00: normal, 0x03: MACLBK, 0x01: PHYLBK
|
||||
u8 mp_mode; // 1: for MP use, 0: for normal driver (to be discussed)
|
||||
u8 rsvd020;
|
||||
u8 rsvd021;
|
||||
u8 rsvd022;
|
||||
u8 rsvd023;
|
||||
u8 rsvd024;
|
||||
u8 rsvd025;
|
||||
|
||||
//--- long word 3 ----
|
||||
u8 qos_en; // QoS enable
|
||||
u8 bw_40MHz_en; // 40MHz BW enable
|
||||
u8 AMSDU2AMPDU_en; // 4181 convert AMSDU to AMPDU, 0: disable
|
||||
u8 AMPDU_en; // 11n AMPDU enable
|
||||
u8 rate_control_offload;//FW offloads, 0: driver handles
|
||||
u8 aggregation_offload; // FW offloads, 0: driver handles
|
||||
u8 rsvd030;
|
||||
u8 rsvd031;
|
||||
|
||||
|
||||
//--- long word 4 ----
|
||||
unsigned char beacon_offload; // 1. FW offloads, 0: driver handles
|
||||
unsigned char MLME_offload; // 2. FW offloads, 0: driver handles
|
||||
unsigned char hwpc_offload; // 3. FW offloads, 0: driver handles
|
||||
unsigned char tcp_checksum_offload; // 4. FW offloads, 0: driver handles
|
||||
unsigned char tcp_offload; // 5. FW offloads, 0: driver handles
|
||||
unsigned char ps_control_offload; // 6. FW offloads, 0: driver handles
|
||||
unsigned char WWLAN_offload; // 7. FW offloads, 0: driver handles
|
||||
unsigned char rsvd040;
|
||||
|
||||
//--- long word 5 ----
|
||||
u8 tcp_tx_frame_len_L; //tcp tx packet length low byte
|
||||
u8 tcp_tx_frame_len_H; //tcp tx packet length high byte
|
||||
u8 tcp_rx_frame_len_L; //tcp rx packet length low byte
|
||||
u8 tcp_rx_frame_len_H; //tcp rx packet length high byte
|
||||
u8 rsvd050;
|
||||
u8 rsvd051;
|
||||
u8 rsvd052;
|
||||
u8 rsvd053;
|
||||
}RT_8192S_FIRMWARE_PRIV, *PRT_8192S_FIRMWARE_PRIV;
|
||||
|
||||
typedef struct _RT_8192S_FIRMWARE_HDR {//8-byte alinment required
|
||||
|
||||
//--- LONG WORD 0 ----
|
||||
u16 Signature;
|
||||
u16 Version; //0x8000 ~ 0x8FFF for FPGA version, 0x0000 ~ 0x7FFF for ASIC version,
|
||||
u32 DMEMSize; //define the size of boot loader
|
||||
|
||||
|
||||
//--- LONG WORD 1 ----
|
||||
u32 IMG_IMEM_SIZE; //define the size of FW in IMEM
|
||||
u32 IMG_SRAM_SIZE; //define the size of FW in SRAM
|
||||
|
||||
//--- LONG WORD 2 ----
|
||||
u32 FW_PRIV_SIZE; //define the size of DMEM variable
|
||||
u32 Rsvd0;
|
||||
|
||||
//--- LONG WORD 3 ----
|
||||
u32 Rsvd1;
|
||||
u32 Rsvd2;
|
||||
|
||||
RT_8192S_FIRMWARE_PRIV FWPriv;
|
||||
|
||||
}RT_8192S_FIRMWARE_HDR, *PRT_8192S_FIRMWARE_HDR;
|
||||
|
||||
#define RT_8192S_FIRMWARE_HDR_SIZE 80
|
||||
#define RT_8192S_FIRMWARE_HDR_EXCLUDE_PRI_SIZE 32
|
||||
|
||||
typedef enum _FIRMWARE_8192S_STATUS{
|
||||
FW_STATUS_INIT = 0,
|
||||
FW_STATUS_LOAD_IMEM = 1,
|
||||
FW_STATUS_LOAD_EMEM = 2,
|
||||
FW_STATUS_LOAD_DMEM = 3,
|
||||
FW_STATUS_READY = 4,
|
||||
}FIRMWARE_8192S_STATUS;
|
||||
|
||||
#define RTL8190_MAX_FIRMWARE_CODE_SIZE 64000 //64k
|
||||
|
||||
typedef struct _rt_firmware{
|
||||
PRT_8192S_FIRMWARE_HDR pFwHeader;
|
||||
FIRMWARE_8192S_STATUS FWStatus;
|
||||
u8 FwIMEM[RTL8190_MAX_FIRMWARE_CODE_SIZE];
|
||||
u8 FwEMEM[RTL8190_MAX_FIRMWARE_CODE_SIZE];
|
||||
u32 FwIMEMLen;
|
||||
u32 FwEMEMLen;
|
||||
u8 szFwTmpBuffer[164000];
|
||||
u32 szFwTmpBufferLen;
|
||||
u16 CmdPacketFragThresold;
|
||||
u16 FirmwareVersion;
|
||||
}rt_firmware, *prt_firmware;
|
||||
|
||||
#define FW_DIG_ENABLE_CTL BIT0
|
||||
#define FW_HIGH_PWR_ENABLE_CTL BIT1
|
||||
#define FW_SS_CTL BIT2
|
||||
#define FW_RA_INIT_CTL BIT3
|
||||
#define FW_RA_BG_CTL BIT4
|
||||
#define FW_RA_N_CTL BIT5
|
||||
#define FW_PWR_TRK_CTL BIT6
|
||||
#define FW_IQK_CTL BIT7
|
||||
#define FW_ANTENNA_SW BIT8
|
||||
#define FW_DISABLE_ALL_DM 0
|
||||
|
||||
#define FW_PWR_TRK_PARAM_CLR 0x0000ffff
|
||||
#define FW_RA_PARAM_CLR 0xffff0000
|
||||
|
||||
#define FW_CMD_IO_CLR(_pdev, _Bit) \
|
||||
udelay(1000); \
|
||||
((struct r8192_priv *)ieee80211_priv(_pdev))->FwCmdIOMap &= (~_Bit);
|
||||
|
||||
#define FW_CMD_IO_UPDATE(_pdev, _val) \
|
||||
((struct r8192_priv *)ieee80211_priv(_pdev))->FwCmdIOMap = _val;
|
||||
|
||||
#define FW_CMD_IO_SET(_pdev, _val) \
|
||||
write_nic_word(_pdev, LBUS_MON_ADDR, (u16)_val); \
|
||||
FW_CMD_IO_UPDATE(_pdev, _val);
|
||||
|
||||
#define FW_CMD_PARA_SET(_pdev, _val) \
|
||||
write_nic_dword(_pdev, LBUS_ADDR_MASK, _val); \
|
||||
((struct r8192_priv *)ieee80211_priv(_pdev))->FwCmdIOParam = _val;
|
||||
|
||||
#define FW_CMD_IO_QUERY(_pdev) (u16)(((struct r8192_priv *)ieee80211_priv(_pdev))->FwCmdIOMap)
|
||||
#define FW_CMD_IO_PARA_QUERY(_pdev) (u32)(((struct r8192_priv *)ieee80211_priv(_pdev))->FwCmdIOParam)
|
||||
|
||||
|
||||
|
||||
bool FirmwareDownload92S(struct net_device *dev);
|
||||
|
||||
#endif
|
||||
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,135 +0,0 @@
|
|||
/*****************************************************************************
|
||||
* Copyright(c) 2008, RealTEK Technology Inc. All Right Reserved.
|
||||
*
|
||||
* Module: __INC_HAL8192SPHYCFG_H
|
||||
*
|
||||
*
|
||||
* Note:
|
||||
*
|
||||
*
|
||||
* Export: Constants, macro, functions(API), global variables(None).
|
||||
*
|
||||
* Abbrev:
|
||||
*
|
||||
* History:
|
||||
* Data Who Remark
|
||||
* 08/07/2007 MHC 1. Porting from 9x series PHYCFG.h.
|
||||
* 2. Reorganize code architecture.
|
||||
*
|
||||
*****************************************************************************/
|
||||
/* Check to see if the file has been included already. */
|
||||
#ifndef _R8192S_PHY_H
|
||||
#define _R8192S_PHY_H
|
||||
|
||||
|
||||
/*--------------------------Define Parameters-------------------------------*/
|
||||
#define LOOP_LIMIT 5
|
||||
#define MAX_STALL_TIME 50 //us
|
||||
#define AntennaDiversityValue 0x80 //(dev->bSoftwareAntennaDiversity ? 0x00:0x80)
|
||||
#define MAX_TXPWR_IDX_NMODE_92S 63
|
||||
|
||||
//#define delay_ms(_t) PlatformStallExecution(1000*(_t))
|
||||
//#define delay_us(_t) PlatformStallExecution(_t)
|
||||
|
||||
/* Channel switch:The size of command tables for switch channel*/
|
||||
#define MAX_PRECMD_CNT 16
|
||||
#define MAX_RFDEPENDCMD_CNT 16
|
||||
#define MAX_POSTCMD_CNT 16
|
||||
|
||||
|
||||
/*------------------------------Define structure----------------------------*/
|
||||
typedef enum _SwChnlCmdID{
|
||||
CmdID_End,
|
||||
CmdID_SetTxPowerLevel,
|
||||
CmdID_BBRegWrite10,
|
||||
CmdID_WritePortUlong,
|
||||
CmdID_WritePortUshort,
|
||||
CmdID_WritePortUchar,
|
||||
CmdID_RF_WriteReg,
|
||||
}SwChnlCmdID;
|
||||
|
||||
|
||||
/* 1. Switch channel related */
|
||||
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, // Never use this
|
||||
}HW90_BLOCK_E, *PHW90_BLOCK_E;
|
||||
|
||||
typedef enum _RF90_RADIO_PATH{
|
||||
RF90_PATH_A = 0, //Radio Path A
|
||||
RF90_PATH_B = 1, //Radio Path B
|
||||
RF90_PATH_C = 2, //Radio Path C
|
||||
RF90_PATH_D = 3, //Radio Path D
|
||||
RF90_PATH_MAX = 4, //Max RF number 90 support
|
||||
}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
|
||||
|
||||
typedef enum _VERSION_8190{
|
||||
// RTL8190
|
||||
VERSION_8190_BD=0x3,
|
||||
VERSION_8190_BE
|
||||
}VERSION_8190,*PVERSION_8190;
|
||||
|
||||
//
|
||||
// BB and RF register read/write
|
||||
//
|
||||
|
||||
extern u32 rtl8192_QueryBBReg(struct net_device* dev,u32 RegAddr, u32 BitMask);
|
||||
extern void rtl8192_setBBreg(struct net_device* dev,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_SetRFReg(struct net_device* dev,RF90_RADIO_PATH_E eRFPath, u32 RegAddr,u32 BitMask,u32 Data);
|
||||
|
||||
bool rtl8192_phy_checkBBAndRF(struct net_device* dev, HW90_BLOCK_E CheckBlock, RF90_RADIO_PATH_E eRFPath);
|
||||
|
||||
|
||||
/* MAC/BB/RF HAL config */
|
||||
extern bool PHY_MACConfig8192S(struct net_device* dev);
|
||||
extern bool PHY_BBConfig8192S(struct net_device* dev);
|
||||
extern bool PHY_RFConfig8192S(struct net_device* dev);
|
||||
|
||||
extern u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device* dev,RF90_RADIO_PATH_E eRFPath);
|
||||
extern void rtl8192_SetBWMode(struct net_device* dev,HT_CHANNEL_WIDTH ChnlWidth,HT_EXTCHNL_OFFSET Offset );
|
||||
extern u8 rtl8192_phy_SwChnl(struct net_device* dev,u8 channel);
|
||||
extern u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device* dev,u32 eRFPath );
|
||||
extern void rtl8192_BBConfig(struct net_device* dev);
|
||||
extern void PHY_IQCalibrateBcut(struct net_device* dev);
|
||||
extern void PHY_IQCalibrate(struct net_device* dev);
|
||||
extern void PHY_GetHWRegOriginalValue(struct net_device* dev);
|
||||
|
||||
extern void InitialGainOperateWorkItemCallBack(struct work_struct *work);
|
||||
|
||||
void PHY_SetTxPowerLevel8192S(struct net_device* dev, u8 channel);
|
||||
void PHY_InitialGain8192S(struct net_device* dev,u8 Operation );
|
||||
|
||||
/*--------------------------Exported Function prototype---------------------*/
|
||||
bool HalSetFwCmd8192S(struct net_device* dev, FW_CMD_IO_TYPE FwCmdIO);
|
||||
extern void PHY_SetBeaconHwReg( struct net_device* dev, u16 BeaconInterval);
|
||||
void ChkFwCmdIoDone(struct net_device* dev);
|
||||
|
||||
#endif // __INC_HAL8192SPHYCFG_H
|
||||
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,842 +0,0 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* (c) Copyright 2008, RealTEK Technologies Inc. All Rights Reserved.
|
||||
*
|
||||
* Module: HalRf6052.c ( Source C File)
|
||||
*
|
||||
* Note: Provide RF 6052 series relative API.
|
||||
*
|
||||
* Function:
|
||||
*
|
||||
* Export:
|
||||
*
|
||||
* Abbrev:
|
||||
*
|
||||
* History:
|
||||
* Data Who Remark
|
||||
*
|
||||
* 09/25/2008 MHC Create initial version.
|
||||
* 11/05/2008 MHC Add API for tw power setting.
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
#include "r8192U.h"
|
||||
#include "r8192S_rtl6052.h"
|
||||
|
||||
#include "r8192S_hw.h"
|
||||
#include "r8192S_phyreg.h"
|
||||
#include "r8192S_phy.h"
|
||||
|
||||
|
||||
/*---------------------------Define Local Constant---------------------------*/
|
||||
// Define local structure for debug!!!!!
|
||||
typedef struct RF_Shadow_Compare_Map {
|
||||
// Shadow register value
|
||||
u32 Value;
|
||||
// Compare or not flag
|
||||
u8 Compare;
|
||||
// Record If it had ever modified unpredicted
|
||||
u8 ErrorOrNot;
|
||||
// Recorver Flag
|
||||
u8 Recorver;
|
||||
//
|
||||
u8 Driver_Write;
|
||||
}RF_SHADOW_T;
|
||||
/*---------------------------Define Local Constant---------------------------*/
|
||||
|
||||
|
||||
/*------------------------Define global variable-----------------------------*/
|
||||
/*------------------------Define global variable-----------------------------*/
|
||||
|
||||
|
||||
|
||||
|
||||
/*---------------------Define local function prototype-----------------------*/
|
||||
void phy_RF6052_Config_HardCode(struct net_device* dev);
|
||||
|
||||
RT_STATUS phy_RF6052_Config_ParaFile(struct net_device* dev);
|
||||
/*---------------------Define local function prototype-----------------------*/
|
||||
|
||||
/*------------------------Define function prototype--------------------------*/
|
||||
extern void RF_ChangeTxPath(struct net_device* dev, u16 DataRate);
|
||||
|
||||
/*------------------------Define function prototype--------------------------*/
|
||||
|
||||
/*------------------------Define local variable------------------------------*/
|
||||
// 2008/11/20 MH For Debug only, RF
|
||||
static RF_SHADOW_T RF_Shadow[RF6052_MAX_PATH][RF6052_MAX_REG];// = {{0}};//FIXLZM
|
||||
/*------------------------Define local variable------------------------------*/
|
||||
|
||||
/*------------------------Define function prototype--------------------------*/
|
||||
/*-----------------------------------------------------------------------------
|
||||
* Function: RF_ChangeTxPath
|
||||
*
|
||||
* Overview: For RL6052, we must change some RF settign for 1T or 2T.
|
||||
*
|
||||
* Input: u16 DataRate // 0x80-8f, 0x90-9f
|
||||
*
|
||||
* Output: NONE
|
||||
*
|
||||
* Return: NONE
|
||||
*
|
||||
* Revised History:
|
||||
* When Who Remark
|
||||
* 09/25/2008 MHC Create Version 0.
|
||||
* Firmwaer support the utility later.
|
||||
*
|
||||
*---------------------------------------------------------------------------*/
|
||||
extern void RF_ChangeTxPath(struct net_device* dev, u16 DataRate)
|
||||
{
|
||||
} /* RF_ChangeTxPath */
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* Function: PHY_RF6052SetBandwidth()
|
||||
*
|
||||
* Overview: This function is called by SetBWModeCallback8190Pci() only
|
||||
*
|
||||
* Input: PADAPTER Adapter
|
||||
* WIRELESS_BANDWIDTH_E Bandwidth //20M or 40M
|
||||
*
|
||||
* Output: NONE
|
||||
*
|
||||
* Return: NONE
|
||||
*
|
||||
* Note: For RF type 0222D
|
||||
*---------------------------------------------------------------------------*/
|
||||
void PHY_RF6052SetBandwidth(struct net_device* dev, HT_CHANNEL_WIDTH Bandwidth) //20M or 40M
|
||||
{
|
||||
//u8 eRFPath;
|
||||
//struct r8192_priv *priv = ieee80211_priv(dev);
|
||||
|
||||
|
||||
//if (priv->card_8192 == NIC_8192SE)
|
||||
{
|
||||
switch(Bandwidth)
|
||||
{
|
||||
case HT_CHANNEL_WIDTH_20:
|
||||
//if (priv->card_8192_version >= VERSION_8192S_BCUT)
|
||||
// rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0xff, 0x58);
|
||||
|
||||
rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)RF90_PATH_A, RF_CHNLBW, BIT10|BIT11, 0x01);
|
||||
break;
|
||||
case HT_CHANNEL_WIDTH_20_40:
|
||||
//if (priv->card_8192_version >= VERSION_8192S_BCUT)
|
||||
// rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0xff, 0x18);
|
||||
|
||||
rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)RF90_PATH_A, RF_CHNLBW, BIT10|BIT11, 0x00);
|
||||
break;
|
||||
default:
|
||||
RT_TRACE(COMP_DBG, "PHY_SetRF6052Bandwidth(): unknown Bandwidth: %#X\n",Bandwidth);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// else
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* Function: PHY_RF6052SetCckTxPower
|
||||
*
|
||||
* Overview:
|
||||
*
|
||||
* Input: NONE
|
||||
*
|
||||
* Output: NONE
|
||||
*
|
||||
* Return: NONE
|
||||
*
|
||||
* Revised History:
|
||||
* When Who Remark
|
||||
* 11/05/2008 MHC Simulate 8192series..
|
||||
*
|
||||
*---------------------------------------------------------------------------*/
|
||||
extern void PHY_RF6052SetCckTxPower(struct net_device* dev, u8 powerlevel)
|
||||
{
|
||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
||||
u32 TxAGC=0;
|
||||
|
||||
if(priv->ieee80211->scanning == 1)
|
||||
TxAGC = 0x3f;
|
||||
else if(priv->bDynamicTxLowPower == true)//cosa 04282008 for cck long range
|
||||
TxAGC = 0x22;
|
||||
else
|
||||
TxAGC = powerlevel;
|
||||
|
||||
//cosa add for lenovo, to pass the safety spec, don't increase power index for different rates.
|
||||
if(priv->bIgnoreDiffRateTxPowerOffset)
|
||||
TxAGC = powerlevel;
|
||||
|
||||
if(TxAGC > RF6052_MAX_TX_PWR)
|
||||
TxAGC = RF6052_MAX_TX_PWR;
|
||||
|
||||
//printk("CCK PWR= %x\n", TxAGC);
|
||||
rtl8192_setBBreg(dev, rTxAGC_CCK_Mcs32, bTxAGCRateCCK, TxAGC);
|
||||
|
||||
} /* PHY_RF6052SetCckTxPower */
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* Function: PHY_RF6052SetOFDMTxPower
|
||||
*
|
||||
* Overview: For legacy and HY OFDM, we must read EEPROM TX power index for
|
||||
* different channel and read original value in TX power register area from
|
||||
* 0xe00. We increase offset and original value to be correct tx pwr.
|
||||
*
|
||||
* Input: NONE
|
||||
*
|
||||
* Output: NONE
|
||||
*
|
||||
* Return: NONE
|
||||
*
|
||||
* Revised History:
|
||||
* When Who Remark
|
||||
* 11/05/2008 MHC Simulate 8192 series method.
|
||||
* 01/06/2009 MHC 1. Prevent Path B tx power overflow or underflow dure to
|
||||
* A/B pwr difference or legacy/HT pwr diff.
|
||||
* 2. We concern with path B legacy/HT OFDM difference.
|
||||
* 01/22/2009 MHC Support new EPRO format from SD3.
|
||||
*---------------------------------------------------------------------------*/
|
||||
#if 1
|
||||
extern void PHY_RF6052SetOFDMTxPower(struct net_device* dev, u8 powerlevel)
|
||||
{
|
||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
||||
u32 writeVal, powerBase0, powerBase1;
|
||||
u8 index = 0;
|
||||
u16 RegOffset[6] = {0xe00, 0xe04, 0xe10, 0xe14, 0xe18, 0xe1c};
|
||||
//u8 byte0, byte1, byte2, byte3;
|
||||
u8 Channel = priv->ieee80211->current_network.channel;
|
||||
u8 rfa_pwr[4];
|
||||
u8 rfa_lower_bound = 0, rfa_upper_bound = 0 /*, rfa_htpwr, rfa_legacypwr*/;
|
||||
u8 i;
|
||||
u8 rf_pwr_diff = 0;
|
||||
u8 Legacy_pwrdiff=0, HT20_pwrdiff=0, BandEdge_Pwrdiff=0;
|
||||
u8 ofdm_bandedge_chnl_low=0, ofdm_bandedge_chnl_high=0;
|
||||
|
||||
|
||||
// We only care about the path A for legacy.
|
||||
if (priv->EEPROMVersion != 2)
|
||||
powerBase0 = powerlevel + (priv->LegacyHTTxPowerDiff & 0xf);
|
||||
else if (priv->EEPROMVersion == 2) // Defined by SD1 Jong
|
||||
{
|
||||
//
|
||||
// 2009/01/21 MH Support new EEPROM format from SD3 requirement
|
||||
//
|
||||
Legacy_pwrdiff = priv->TxPwrLegacyHtDiff[RF90_PATH_A][Channel-1];
|
||||
// For legacy OFDM, tx pwr always > HT OFDM pwr. We do not care Path B
|
||||
// legacy OFDM pwr diff. NO BB register to notify HW.
|
||||
powerBase0 = powerlevel + Legacy_pwrdiff;
|
||||
//RTPRINT(FPHY, PHY_TXPWR, (" [LagacyToHT40 pwr diff = %d]\n", Legacy_pwrdiff));
|
||||
|
||||
// Band Edge scheme is enabled for FCC mode
|
||||
if (priv->TxPwrbandEdgeFlag == 1/* && pHalData->ChannelPlan == 0*/)
|
||||
{
|
||||
ofdm_bandedge_chnl_low = 1;
|
||||
ofdm_bandedge_chnl_high = 11;
|
||||
BandEdge_Pwrdiff = 0;
|
||||
if (Channel <= ofdm_bandedge_chnl_low)
|
||||
BandEdge_Pwrdiff = priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_A][0];
|
||||
else if (Channel >= ofdm_bandedge_chnl_high)
|
||||
{
|
||||
BandEdge_Pwrdiff = priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_A][1];
|
||||
}
|
||||
powerBase0 -= BandEdge_Pwrdiff;
|
||||
if (Channel <= ofdm_bandedge_chnl_low || Channel >= ofdm_bandedge_chnl_high)
|
||||
{
|
||||
//RTPRINT(FPHY, PHY_TXPWR, (" [OFDM band-edge channel = %d, pwr diff = %d]\n",
|
||||
//Channel, BandEdge_Pwrdiff));
|
||||
}
|
||||
}
|
||||
//RTPRINT(FPHY, PHY_TXPWR, (" [OFDM power base index = 0x%x]\n", powerBase0));
|
||||
}
|
||||
powerBase0 = (powerBase0<<24) | (powerBase0<<16) |(powerBase0<<8) |powerBase0;
|
||||
|
||||
//MCS rates
|
||||
if(priv->EEPROMVersion == 2)
|
||||
{
|
||||
//Cosa add for new EEPROM content. 02102009
|
||||
|
||||
//Check HT20 to HT40 diff
|
||||
if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20)
|
||||
{
|
||||
// HT 20<->40 pwr diff
|
||||
HT20_pwrdiff = priv->TxPwrHt20Diff[RF90_PATH_A][Channel-1];
|
||||
|
||||
// Calculate Antenna pwr diff
|
||||
if (HT20_pwrdiff < 8) // 0~+7
|
||||
powerlevel += HT20_pwrdiff;
|
||||
else // index8-15=-8~-1
|
||||
powerlevel -= (16-HT20_pwrdiff);
|
||||
|
||||
//RTPRINT(FPHY, PHY_TXPWR, (" [HT20 to HT40 pwrdiff = %d]\n", HT20_pwrdiff));
|
||||
//RTPRINT(FPHY, PHY_TXPWR, (" [MCS power base index = 0x%x]\n", powerlevel));
|
||||
}
|
||||
|
||||
// Band Edge scheme is enabled for FCC mode
|
||||
if (priv->TxPwrbandEdgeFlag == 1/* && pHalData->ChannelPlan == 0*/)
|
||||
{
|
||||
BandEdge_Pwrdiff = 0;
|
||||
if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
|
||||
{
|
||||
if (Channel <= 3)
|
||||
BandEdge_Pwrdiff = priv->TxPwrbandEdgeHt40[RF90_PATH_A][0];
|
||||
else if (Channel >= 9)
|
||||
BandEdge_Pwrdiff = priv->TxPwrbandEdgeHt40[RF90_PATH_A][1];
|
||||
if (Channel <= 3 || Channel >= 9)
|
||||
{
|
||||
//RTPRINT(FPHY, PHY_TXPWR, (" [HT40 band-edge channel = %d, pwr diff = %d]\n",
|
||||
//Channel, BandEdge_Pwrdiff));
|
||||
}
|
||||
}
|
||||
else if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20)
|
||||
{
|
||||
if (Channel <= 1)
|
||||
BandEdge_Pwrdiff = priv->TxPwrbandEdgeHt20[RF90_PATH_A][0];
|
||||
else if (Channel >= 11)
|
||||
BandEdge_Pwrdiff = priv->TxPwrbandEdgeHt20[RF90_PATH_A][1];
|
||||
if (Channel <= 1 || Channel >= 11)
|
||||
{
|
||||
//RTPRINT(FPHY, PHY_TXPWR, (" [HT20 band-edge channel = %d, pwr diff = %d]\n",
|
||||
//Channel, BandEdge_Pwrdiff));
|
||||
}
|
||||
}
|
||||
powerlevel -= BandEdge_Pwrdiff;
|
||||
//RTPRINT(FPHY, PHY_TXPWR, (" [MCS power base index = 0x%x]\n", powerlevel));
|
||||
}
|
||||
}
|
||||
powerBase1 = powerlevel;
|
||||
powerBase1 = (powerBase1<<24) | (powerBase1<<16) |(powerBase1<<8) |powerBase1;
|
||||
|
||||
//RTPRINT(FPHY, PHY_TXPWR, (" [Legacy/HT power index= %x/%x]\n", powerBase0, powerBase1));
|
||||
|
||||
for(index=0; index<6; index++)
|
||||
{
|
||||
//
|
||||
// Index 0 & 1= legacy OFDM, 2-5=HT_MCS rate
|
||||
//
|
||||
//cosa add for lenovo, to pass the safety spec, don't increase power index for different rates.
|
||||
if(priv->bIgnoreDiffRateTxPowerOffset)
|
||||
writeVal = ((index<2)?powerBase0:powerBase1);
|
||||
else
|
||||
writeVal = priv->MCSTxPowerLevelOriginalOffset[index] + ((index<2)?powerBase0:powerBase1);
|
||||
|
||||
//RTPRINT(FPHY, PHY_TXPWR, ("Reg 0x%x, Original=%x writeVal=%x\n",
|
||||
//RegOffset[index], priv->MCSTxPowerLevelOriginalOffset[index], writeVal));
|
||||
|
||||
//
|
||||
// If path A and Path B coexist, we must limit Path A tx power.
|
||||
// Protect Path B pwr over or underflow. We need to calculate upper and
|
||||
// lower bound of path A tx power.
|
||||
//
|
||||
if (priv->rf_type == RF_2T2R)
|
||||
{
|
||||
rf_pwr_diff = priv->AntennaTxPwDiff[0];
|
||||
//RTPRINT(FPHY, PHY_TXPWR, ("2T2R RF-B to RF-A PWR DIFF=%d\n", rf_pwr_diff));
|
||||
|
||||
if (rf_pwr_diff >= 8) // Diff=-8~-1
|
||||
{ // Prevent underflow!!
|
||||
rfa_lower_bound = 0x10-rf_pwr_diff;
|
||||
//RTPRINT(FPHY, PHY_TXPWR, ("rfa_lower_bound= %d\n", rfa_lower_bound));
|
||||
}
|
||||
else if (rf_pwr_diff >= 0) // Diff = 0-7
|
||||
{
|
||||
rfa_upper_bound = RF6052_MAX_TX_PWR-rf_pwr_diff;
|
||||
//RTPRINT(FPHY, PHY_TXPWR, ("rfa_upper_bound= %d\n", rfa_upper_bound));
|
||||
}
|
||||
}
|
||||
|
||||
for (i= 0; i <4; i++)
|
||||
{
|
||||
rfa_pwr[i] = (u8)((writeVal & (0x7f<<(i*8)))>>(i*8));
|
||||
if (rfa_pwr[i] > RF6052_MAX_TX_PWR)
|
||||
rfa_pwr[i] = RF6052_MAX_TX_PWR;
|
||||
|
||||
//
|
||||
// If path A and Path B coexist, we must limit Path A tx power.
|
||||
// Protect Path B pwr under/over flow. We need to calculate upper and
|
||||
// lower bound of path A tx power.
|
||||
//
|
||||
if (priv->rf_type == RF_2T2R)
|
||||
{
|
||||
if (rf_pwr_diff >= 8) // Diff=-8~-1
|
||||
{ // Prevent underflow!!
|
||||
if (rfa_pwr[i] <rfa_lower_bound)
|
||||
{
|
||||
//RTPRINT(FPHY, PHY_TXPWR, ("Underflow"));
|
||||
rfa_pwr[i] = rfa_lower_bound;
|
||||
}
|
||||
}
|
||||
else if (rf_pwr_diff >= 1) // Diff = 0-7
|
||||
{ // Prevent overflow
|
||||
if (rfa_pwr[i] > rfa_upper_bound)
|
||||
{
|
||||
//RTPRINT(FPHY, PHY_TXPWR, ("Overflow"));
|
||||
rfa_pwr[i] = rfa_upper_bound;
|
||||
}
|
||||
}
|
||||
//RTPRINT(FPHY, PHY_TXPWR, ("rfa_pwr[%d]=%x\n", i, rfa_pwr[i]));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// Add description: PWDB > threshold!!!High power issue!!
|
||||
// We must decrease tx power !! Why is the value ???
|
||||
//
|
||||
if(priv->bDynamicTxHighPower == TRUE)
|
||||
{
|
||||
// For MCS rate
|
||||
if(index > 1)
|
||||
{
|
||||
writeVal = 0x03030303;
|
||||
}
|
||||
// For Legacy rate
|
||||
else
|
||||
{
|
||||
writeVal = (rfa_pwr[3]<<24) | (rfa_pwr[2]<<16) |(rfa_pwr[1]<<8) |rfa_pwr[0];
|
||||
}
|
||||
//RTPRINT(FPHY, PHY_TXPWR, ("HighPower=%08x\n", writeVal));
|
||||
}
|
||||
else
|
||||
{
|
||||
writeVal = (rfa_pwr[3]<<24) | (rfa_pwr[2]<<16) |(rfa_pwr[1]<<8) |rfa_pwr[0];
|
||||
//RTPRINT(FPHY, PHY_TXPWR, ("NormalPower=%08x\n", writeVal));
|
||||
}
|
||||
|
||||
//
|
||||
// Write different rate set tx power index.
|
||||
//
|
||||
//if (DCMD_Test_Flag == 0)
|
||||
rtl8192_setBBreg(dev, RegOffset[index], 0x7f7f7f7f, writeVal);
|
||||
}
|
||||
|
||||
} /* PHY_RF6052SetOFDMTxPower */
|
||||
#else
|
||||
extern void PHY_RF6052SetOFDMTxPower(struct net_device* dev, u8 powerlevel)
|
||||
{
|
||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
||||
u32 writeVal, powerBase0, powerBase1;
|
||||
u8 index = 0;
|
||||
u16 RegOffset[6] = {0xe00, 0xe04, 0xe10, 0xe14, 0xe18, 0xe1c};
|
||||
u8 byte0, byte1, byte2, byte3;
|
||||
u8 channel = priv->ieee80211->current_network.channel;
|
||||
|
||||
//Legacy OFDM rates
|
||||
powerBase0 = powerlevel + (priv->LegacyHTTxPowerDiff & 0xf);
|
||||
powerBase0 = (powerBase0<<24) | (powerBase0<<16) |(powerBase0<<8) |powerBase0;
|
||||
|
||||
//MCS rates HT OFDM
|
||||
powerBase1 = powerlevel;
|
||||
powerBase1 = (powerBase1<<24) | (powerBase1<<16) |(powerBase1<<8) |powerBase1;
|
||||
|
||||
//printk("Legacy/HT PWR= %x/%x\n", powerBase0, powerBase1);
|
||||
|
||||
for(index=0; index<6; index++)
|
||||
{
|
||||
//
|
||||
// Index 0 & 1= legacy OFDM, 2-5=HT_MCS rate
|
||||
//
|
||||
writeVal = priv->MCSTxPowerLevelOriginalOffset[index] + ((index<2)?powerBase0:powerBase1);
|
||||
|
||||
//printk("Index = %d Original=%x writeVal=%x\n", index, priv->MCSTxPowerLevelOriginalOffset[index], writeVal);
|
||||
|
||||
byte0 = (u8)(writeVal & 0x7f);
|
||||
byte1 = (u8)((writeVal & 0x7f00)>>8);
|
||||
byte2 = (u8)((writeVal & 0x7f0000)>>16);
|
||||
byte3 = (u8)((writeVal & 0x7f000000)>>24);
|
||||
|
||||
// Max power index = 0x3F Range = 0-0x3F
|
||||
if(byte0 > RF6052_MAX_TX_PWR)
|
||||
byte0 = RF6052_MAX_TX_PWR;
|
||||
if(byte1 > RF6052_MAX_TX_PWR)
|
||||
byte1 = RF6052_MAX_TX_PWR;
|
||||
if(byte2 > RF6052_MAX_TX_PWR)
|
||||
byte2 = RF6052_MAX_TX_PWR;
|
||||
if(byte3 > RF6052_MAX_TX_PWR)
|
||||
byte3 = RF6052_MAX_TX_PWR;
|
||||
|
||||
//
|
||||
// Add description: PWDB > threshold!!!High power issue!!
|
||||
// We must decrease tx power !! Why is the value ???
|
||||
//
|
||||
if(priv->bDynamicTxHighPower == true)
|
||||
{
|
||||
// For MCS rate
|
||||
if(index > 1)
|
||||
{
|
||||
writeVal = 0x03030303;
|
||||
}
|
||||
// For Legacy rate
|
||||
else
|
||||
{
|
||||
writeVal = (byte3<<24) | (byte2<<16) |(byte1<<8) |byte0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
writeVal = (byte3<<24) | (byte2<<16) |(byte1<<8) |byte0;
|
||||
}
|
||||
|
||||
//
|
||||
// Write different rate set tx power index.
|
||||
//
|
||||
rtl8192_setBBreg(dev, RegOffset[index], 0x7f7f7f7f, writeVal);
|
||||
}
|
||||
|
||||
} /* PHY_RF6052SetOFDMTxPower */
|
||||
#endif
|
||||
|
||||
RT_STATUS PHY_RF6052_Config(struct net_device* dev)
|
||||
{
|
||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
||||
RT_STATUS rtStatus = RT_STATUS_SUCCESS;
|
||||
//RF90_RADIO_PATH_E eRFPath;
|
||||
//BB_REGISTER_DEFINITION_T *pPhyReg;
|
||||
//u32 OrgStoreRFIntSW[RF90_PATH_D+1];
|
||||
|
||||
//
|
||||
// Initialize general global value
|
||||
//
|
||||
// TODO: Extend RF_PATH_C and RF_PATH_D in the future
|
||||
if(priv->rf_type == RF_1T1R)
|
||||
priv->NumTotalRFPath = 1;
|
||||
else
|
||||
priv->NumTotalRFPath = 2;
|
||||
|
||||
//
|
||||
// Config BB and RF
|
||||
//
|
||||
// switch( priv->bRegHwParaFile )
|
||||
// {
|
||||
// case 0:
|
||||
// phy_RF6052_Config_HardCode(dev);
|
||||
// break;
|
||||
|
||||
// case 1:
|
||||
rtStatus = phy_RF6052_Config_ParaFile(dev);
|
||||
// break;
|
||||
|
||||
// case 2:
|
||||
// Partial Modify.
|
||||
// phy_RF6052_Config_HardCode(dev);
|
||||
// phy_RF6052_Config_ParaFile(dev);
|
||||
// break;
|
||||
|
||||
// default:
|
||||
// phy_RF6052_Config_HardCode(dev);
|
||||
// break;
|
||||
// }
|
||||
return rtStatus;
|
||||
|
||||
}
|
||||
|
||||
void phy_RF6052_Config_HardCode(struct net_device* dev)
|
||||
{
|
||||
|
||||
// Set Default Bandwidth to 20M
|
||||
//Adapter->HalFunc .SetBWModeHandler(Adapter, HT_CHANNEL_WIDTH_20);
|
||||
|
||||
// TODO: Set Default Channel to channel one for RTL8225
|
||||
|
||||
}
|
||||
|
||||
RT_STATUS phy_RF6052_Config_ParaFile(struct net_device* dev)
|
||||
{
|
||||
u32 u4RegValue = 0;
|
||||
//static s1Byte szRadioAFile[] = RTL819X_PHY_RADIO_A;
|
||||
//static s1Byte szRadioBFile[] = RTL819X_PHY_RADIO_B;
|
||||
//static s1Byte szRadioBGMFile[] = RTL819X_PHY_RADIO_B_GM;
|
||||
u8 eRFPath;
|
||||
RT_STATUS rtStatus = RT_STATUS_SUCCESS;
|
||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
||||
BB_REGISTER_DEFINITION_T *pPhyReg;
|
||||
//u8 eCheckItem;
|
||||
|
||||
|
||||
//3//-----------------------------------------------------------------
|
||||
//3// <2> Initialize RF
|
||||
//3//-----------------------------------------------------------------
|
||||
//for(eRFPath = RF90_PATH_A; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
|
||||
for(eRFPath = 0; eRFPath <priv->NumTotalRFPath; eRFPath++)
|
||||
{
|
||||
|
||||
pPhyReg = &priv->PHYRegDef[eRFPath];
|
||||
|
||||
/*----Store original RFENV control type----*/
|
||||
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;
|
||||
}
|
||||
|
||||
/*----Set RF_ENV enable----*/
|
||||
rtl8192_setBBreg(dev, pPhyReg->rfintfe, bRFSI_RFENV<<16, 0x1);
|
||||
|
||||
/*----Set RF_ENV output high----*/
|
||||
rtl8192_setBBreg(dev, pPhyReg->rfintfo, bRFSI_RFENV, 0x1);
|
||||
|
||||
/* Set bit number of Address and Data for RF register */
|
||||
rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, b3WireAddressLength, 0x0); // Set 1 to 4 bits for 8255
|
||||
rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, b3WireDataLength, 0x0); // Set 0 to 12 bits for 8255
|
||||
|
||||
|
||||
/*----Initialize RF fom connfiguration file----*/
|
||||
switch(eRFPath)
|
||||
{
|
||||
case RF90_PATH_A:
|
||||
rtStatus= rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
|
||||
break;
|
||||
case RF90_PATH_B:
|
||||
rtStatus= rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
|
||||
break;
|
||||
case RF90_PATH_C:
|
||||
break;
|
||||
case RF90_PATH_D:
|
||||
break;
|
||||
}
|
||||
|
||||
/*----Restore RFENV control type----*/;
|
||||
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(rtStatus != RT_STATUS_SUCCESS){
|
||||
printk("phy_RF6052_Config_ParaFile():Radio[%d] Fail!!", eRFPath);
|
||||
goto phy_RF6052_Config_ParaFile_Fail;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
RT_TRACE(COMP_INIT, "<---phy_RF6052_Config_ParaFile()\n");
|
||||
return rtStatus;
|
||||
|
||||
phy_RF6052_Config_ParaFile_Fail:
|
||||
return rtStatus;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ==> RF shadow Operation API Code Section!!!
|
||||
//
|
||||
/*-----------------------------------------------------------------------------
|
||||
* Function: PHY_RFShadowRead
|
||||
* PHY_RFShadowWrite
|
||||
* PHY_RFShadowCompare
|
||||
* PHY_RFShadowRecorver
|
||||
* PHY_RFShadowCompareAll
|
||||
* PHY_RFShadowRecorverAll
|
||||
* PHY_RFShadowCompareFlagSet
|
||||
* PHY_RFShadowRecorverFlagSet
|
||||
*
|
||||
* Overview: When we set RF register, we must write shadow at first.
|
||||
* When we are running, we must compare shadow abd locate error addr.
|
||||
* Decide to recorver or not.
|
||||
*
|
||||
* Input: NONE
|
||||
*
|
||||
* Output: NONE
|
||||
*
|
||||
* Return: NONE
|
||||
*
|
||||
* Revised History:
|
||||
* When Who Remark
|
||||
* 11/20/2008 MHC Create Version 0.
|
||||
*
|
||||
*---------------------------------------------------------------------------*/
|
||||
extern u32 PHY_RFShadowRead(
|
||||
struct net_device * dev,
|
||||
RF90_RADIO_PATH_E eRFPath,
|
||||
u32 Offset)
|
||||
{
|
||||
return RF_Shadow[eRFPath][Offset].Value;
|
||||
|
||||
} /* PHY_RFShadowRead */
|
||||
|
||||
|
||||
extern void PHY_RFShadowWrite(
|
||||
struct net_device * dev,
|
||||
u32 eRFPath,
|
||||
u32 Offset,
|
||||
u32 Data)
|
||||
{
|
||||
//RF_Shadow[eRFPath][Offset].Value = (Data & bMask20Bits);
|
||||
RF_Shadow[eRFPath][Offset].Value = (Data & bRFRegOffsetMask);
|
||||
RF_Shadow[eRFPath][Offset].Driver_Write = true;
|
||||
|
||||
} /* PHY_RFShadowWrite */
|
||||
|
||||
|
||||
extern void PHY_RFShadowCompare(
|
||||
struct net_device * dev,
|
||||
RF90_RADIO_PATH_E eRFPath,
|
||||
u32 Offset)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
// Check if we need to check the register
|
||||
if (RF_Shadow[eRFPath][Offset].Compare == true)
|
||||
{
|
||||
reg = rtl8192_phy_QueryRFReg(dev, eRFPath, Offset, bRFRegOffsetMask);
|
||||
// Compare shadow and real rf register for 20bits!!
|
||||
if (RF_Shadow[eRFPath][Offset].Value != reg)
|
||||
{
|
||||
// Locate error position.
|
||||
RF_Shadow[eRFPath][Offset].ErrorOrNot = true;
|
||||
RT_TRACE(COMP_INIT, "PHY_RFShadowCompare RF-%d Addr%02xErr = %05x", eRFPath, Offset, reg);
|
||||
}
|
||||
}
|
||||
|
||||
} /* PHY_RFShadowCompare */
|
||||
|
||||
extern void PHY_RFShadowRecorver(
|
||||
struct net_device * dev,
|
||||
RF90_RADIO_PATH_E eRFPath,
|
||||
u32 Offset)
|
||||
{
|
||||
// Check if the address is error
|
||||
if (RF_Shadow[eRFPath][Offset].ErrorOrNot == true)
|
||||
{
|
||||
// Check if we need to recorver the register.
|
||||
if (RF_Shadow[eRFPath][Offset].Recorver == true)
|
||||
{
|
||||
rtl8192_phy_SetRFReg(dev, eRFPath, Offset, bRFRegOffsetMask, RF_Shadow[eRFPath][Offset].Value);
|
||||
RT_TRACE(COMP_INIT, "PHY_RFShadowRecorver RF-%d Addr%02x=%05x",
|
||||
eRFPath, Offset, RF_Shadow[eRFPath][Offset].Value);
|
||||
}
|
||||
}
|
||||
|
||||
} /* PHY_RFShadowRecorver */
|
||||
|
||||
|
||||
extern void PHY_RFShadowCompareAll(struct net_device * dev)
|
||||
{
|
||||
u32 eRFPath;
|
||||
u32 Offset;
|
||||
|
||||
for (eRFPath = 0; eRFPath < RF6052_MAX_PATH; eRFPath++)
|
||||
{
|
||||
for (Offset = 0; Offset <= RF6052_MAX_REG; Offset++)
|
||||
{
|
||||
PHY_RFShadowCompare(dev, (RF90_RADIO_PATH_E)eRFPath, Offset);
|
||||
}
|
||||
}
|
||||
|
||||
} /* PHY_RFShadowCompareAll */
|
||||
|
||||
|
||||
extern void PHY_RFShadowRecorverAll(struct net_device * dev)
|
||||
{
|
||||
u32 eRFPath;
|
||||
u32 Offset;
|
||||
|
||||
for (eRFPath = 0; eRFPath < RF6052_MAX_PATH; eRFPath++)
|
||||
{
|
||||
for (Offset = 0; Offset <= RF6052_MAX_REG; Offset++)
|
||||
{
|
||||
PHY_RFShadowRecorver(dev, (RF90_RADIO_PATH_E)eRFPath, Offset);
|
||||
}
|
||||
}
|
||||
|
||||
} /* PHY_RFShadowRecorverAll */
|
||||
|
||||
|
||||
extern void PHY_RFShadowCompareFlagSet(
|
||||
struct net_device * dev,
|
||||
RF90_RADIO_PATH_E eRFPath,
|
||||
u32 Offset,
|
||||
u8 Type)
|
||||
{
|
||||
// Set True or False!!!
|
||||
RF_Shadow[eRFPath][Offset].Compare = Type;
|
||||
|
||||
} /* PHY_RFShadowCompareFlagSet */
|
||||
|
||||
|
||||
extern void PHY_RFShadowRecorverFlagSet(
|
||||
struct net_device * dev,
|
||||
RF90_RADIO_PATH_E eRFPath,
|
||||
u32 Offset,
|
||||
u8 Type)
|
||||
{
|
||||
// Set True or False!!!
|
||||
RF_Shadow[eRFPath][Offset].Recorver= Type;
|
||||
|
||||
} /* PHY_RFShadowRecorverFlagSet */
|
||||
|
||||
|
||||
extern void PHY_RFShadowCompareFlagSetAll(struct net_device * dev)
|
||||
{
|
||||
u32 eRFPath;
|
||||
u32 Offset;
|
||||
|
||||
for (eRFPath = 0; eRFPath < RF6052_MAX_PATH; eRFPath++)
|
||||
{
|
||||
for (Offset = 0; Offset <= RF6052_MAX_REG; Offset++)
|
||||
{
|
||||
// 2008/11/20 MH For S3S4 test, we only check reg 26/27 now!!!!
|
||||
if (Offset != 0x26 && Offset != 0x27)
|
||||
PHY_RFShadowCompareFlagSet(dev, (RF90_RADIO_PATH_E)eRFPath, Offset, FALSE);
|
||||
else
|
||||
PHY_RFShadowCompareFlagSet(dev, (RF90_RADIO_PATH_E)eRFPath, Offset, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
} /* PHY_RFShadowCompareFlagSetAll */
|
||||
|
||||
|
||||
extern void PHY_RFShadowRecorverFlagSetAll(struct net_device * dev)
|
||||
{
|
||||
u32 eRFPath;
|
||||
u32 Offset;
|
||||
|
||||
for (eRFPath = 0; eRFPath < RF6052_MAX_PATH; eRFPath++)
|
||||
{
|
||||
for (Offset = 0; Offset <= RF6052_MAX_REG; Offset++)
|
||||
{
|
||||
// 2008/11/20 MH For S3S4 test, we only check reg 26/27 now!!!!
|
||||
if (Offset != 0x26 && Offset != 0x27)
|
||||
PHY_RFShadowRecorverFlagSet(dev, (RF90_RADIO_PATH_E)eRFPath, Offset, FALSE);
|
||||
else
|
||||
PHY_RFShadowRecorverFlagSet(dev, (RF90_RADIO_PATH_E)eRFPath, Offset, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
} /* PHY_RFShadowCompareFlagSetAll */
|
||||
|
||||
|
||||
|
||||
extern void PHY_RFShadowRefresh(struct net_device * dev)
|
||||
{
|
||||
u32 eRFPath;
|
||||
u32 Offset;
|
||||
|
||||
for (eRFPath = 0; eRFPath < RF6052_MAX_PATH; eRFPath++)
|
||||
{
|
||||
for (Offset = 0; Offset <= RF6052_MAX_REG; Offset++)
|
||||
{
|
||||
RF_Shadow[eRFPath][Offset].Value = 0;
|
||||
RF_Shadow[eRFPath][Offset].Compare = false;
|
||||
RF_Shadow[eRFPath][Offset].Recorver = false;
|
||||
RF_Shadow[eRFPath][Offset].ErrorOrNot = false;
|
||||
RF_Shadow[eRFPath][Offset].Driver_Write = false;
|
||||
}
|
||||
}
|
||||
|
||||
} /* PHY_RFShadowRead */
|
||||
|
||||
/* End of HalRf6052.c */
|
|
@ -1,87 +0,0 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* (c) Copyright 2008, RealTEK Technologies Inc. All Rights Reserved.
|
||||
*
|
||||
* Module: HalRf.h ( Header File)
|
||||
*
|
||||
* Note: Collect every HAL RF type exter API or constant.
|
||||
*
|
||||
* Function:
|
||||
*
|
||||
* Export:
|
||||
*
|
||||
* Abbrev:
|
||||
*
|
||||
* History:
|
||||
* Data Who Remark
|
||||
*
|
||||
* 09/25/2008 MHC Create initial version.
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
/* Check to see if the file has been included already. */
|
||||
|
||||
|
||||
/*--------------------------Define Parameters-------------------------------*/
|
||||
|
||||
//
|
||||
// For RF 6052 Series
|
||||
//
|
||||
#define RF6052_MAX_TX_PWR 0x3F
|
||||
#define RF6052_MAX_REG 0x3F
|
||||
#define RF6052_MAX_PATH 4
|
||||
/*--------------------------Define Parameters-------------------------------*/
|
||||
|
||||
|
||||
/*------------------------------Define structure----------------------------*/
|
||||
|
||||
/*------------------------------Define structure----------------------------*/
|
||||
|
||||
|
||||
/*------------------------Export global variable----------------------------*/
|
||||
/*------------------------Export global variable----------------------------*/
|
||||
|
||||
/*------------------------Export Marco Definition---------------------------*/
|
||||
|
||||
/*------------------------Export Marco Definition---------------------------*/
|
||||
|
||||
|
||||
/*--------------------------Exported Function prototype---------------------*/
|
||||
//======================================================
|
||||
#if 1
|
||||
// Function prototypes for HalPhy8225.c
|
||||
//1======================================================
|
||||
extern void PHY_SetRF0222DBandwidth(struct net_device* dev , HT_CHANNEL_WIDTH Bandwidth); //20M or 40M;
|
||||
extern void PHY_SetRF8225Bandwidth( struct net_device* dev , HT_CHANNEL_WIDTH Bandwidth);
|
||||
extern bool PHY_RF8225_Config(struct net_device* dev );
|
||||
extern void phy_RF8225_Config_HardCode(struct net_device* dev);
|
||||
extern bool phy_RF8225_Config_ParaFile(struct net_device* dev);
|
||||
extern void PHY_SetRF8225CckTxPower(struct net_device* dev ,u8 powerlevel);
|
||||
extern void PHY_SetRF8225OfdmTxPower(struct net_device* dev ,u8 powerlevel);
|
||||
extern void PHY_SetRF0222DOfdmTxPower(struct net_device* dev ,u8 powerlevel);
|
||||
extern void PHY_SetRF0222DCckTxPower(struct net_device* dev ,u8 powerlevel);
|
||||
|
||||
//1======================================================
|
||||
// Function prototypes for HalPhy8256.c
|
||||
//1======================================================
|
||||
extern void PHY_SetRF8256Bandwidth(struct net_device* dev , HT_CHANNEL_WIDTH Bandwidth);
|
||||
extern void PHY_RF8256_Config(struct net_device* dev);
|
||||
extern void 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
|
||||
|
||||
//
|
||||
// RF RL6052 Series API
|
||||
//
|
||||
extern void RF_ChangeTxPath(struct net_device * dev, u16 DataRate);
|
||||
extern void PHY_RF6052SetBandwidth(struct net_device * dev,HT_CHANNEL_WIDTH Bandwidth);
|
||||
extern void PHY_RF6052SetCckTxPower(struct net_device * dev, u8 powerlevel);
|
||||
extern void PHY_RF6052SetOFDMTxPower(struct net_device * dev, u8 powerlevel);
|
||||
extern RT_STATUS PHY_RF6052_Config(struct net_device * dev);
|
||||
extern void PHY_RFShadowRefresh( struct net_device * dev);
|
||||
extern void PHY_RFShadowWrite( struct net_device* dev, u32 eRFPath, u32 Offset, u32 Data);
|
||||
/*--------------------------Exported Function prototype---------------------*/
|
||||
|
||||
|
||||
/* End of HalRf.h */
|
|
@ -1,292 +0,0 @@
|
|||
|
||||
#include "r8192U.h"
|
||||
#include "r8192S_hw.h"
|
||||
#include "r8192S_phyreg.h"
|
||||
#include "r8192S_phy.h"
|
||||
#include "r8192S_rtl8225.h"
|
||||
|
||||
/*---------------------Define local function prototype-----------------------*/
|
||||
void phy_RF8225_Config_HardCode(struct net_device* dev );
|
||||
bool phy_RF8225_Config_ParaFile(struct net_device* dev );
|
||||
/*---------------------Define local function prototype-----------------------*/
|
||||
void PHY_SetRF8225OfdmTxPower(struct net_device* dev ,u8 powerlevel)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PHY_SetRF8225CckTxPower( struct net_device* dev , u8 powerlevel)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
// TODO: The following RF 022D related function should be removed to HalPhy0222D.c.
|
||||
void PHY_SetRF0222DOfdmTxPower(struct net_device* dev ,u8 powerlevel)
|
||||
{
|
||||
//TODO: We should set RF TxPower for RF 0222D here!!
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PHY_SetRF0222DCckTxPower(struct net_device* dev ,u8 powerlevel)
|
||||
{
|
||||
//TODO: We should set RF TxPower for RF 0222D here!!
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* Function: PHY_SetRF0222DBandwidth()
|
||||
*
|
||||
* Overview: This function is called by SetBWModeCallback8190Pci() only
|
||||
*
|
||||
* Input: PADAPTER Adapter
|
||||
* WIRELESS_BANDWIDTH_E Bandwidth //20M or 40M
|
||||
*
|
||||
* Output: NONE
|
||||
*
|
||||
* Return: NONE
|
||||
*
|
||||
* Note: For RF type 0222D
|
||||
*---------------------------------------------------------------------------*/
|
||||
//just in phy
|
||||
void PHY_SetRF0222DBandwidth(struct net_device* dev , HT_CHANNEL_WIDTH Bandwidth) //20M or 40M
|
||||
{
|
||||
u8 eRFPath;
|
||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
||||
|
||||
|
||||
//if (IS_HARDWARE_TYPE_8192S(dev))
|
||||
if (1)
|
||||
{
|
||||
#ifndef RTL92SE_FPGA_VERIFY
|
||||
switch(Bandwidth)
|
||||
{
|
||||
case HT_CHANNEL_WIDTH_20:
|
||||
#ifdef FIB_MODIFICATION
|
||||
write_nic_byte(dev, rFPGA0_AnalogParameter2, 0x58);
|
||||
#endif
|
||||
rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)RF90_PATH_A, RF_CHNLBW, BIT10|BIT11, 0x01);
|
||||
break;
|
||||
case HT_CHANNEL_WIDTH_20_40:
|
||||
#ifdef FIB_MODIFICATION
|
||||
write_nic_byte(dev, rFPGA0_AnalogParameter2, 0x18);
|
||||
#endif
|
||||
rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)RF90_PATH_A, RF_CHNLBW, BIT10|BIT11, 0x00);
|
||||
break;
|
||||
default:
|
||||
;//RT_TRACE(COMP_DBG, DBG_LOUD, ("PHY_SetRF8225Bandwidth(): unknown Bandwidth: %#X\n",Bandwidth ));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
for(eRFPath = 0; eRFPath <priv->NumTotalRFPath; eRFPath++)
|
||||
{
|
||||
switch(Bandwidth)
|
||||
{
|
||||
case HT_CHANNEL_WIDTH_20:
|
||||
//rtl8192_phy_SetRFReg(Adapter, (RF90_RADIO_PATH_E)RF90_PATH_A, RF_CHNLBW, (BIT10|BIT11), 0x01);
|
||||
break;
|
||||
case HT_CHANNEL_WIDTH_20_40:
|
||||
//rtl8192_phy_SetRFReg(Adapter, (RF90_RADIO_PATH_E)RF90_PATH_A, RF_CHNLBW, (BIT10|BIT11), 0x00);
|
||||
break;
|
||||
default:
|
||||
;//RT_TRACE(COMP_DBG, DBG_LOUD, ("PHY_SetRF8225Bandwidth(): unknown Bandwidth: %#X\n",Bandwidth ));
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// TODO: Aabove RF 022D related function should be removed to HalPhy0222D.c.
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* Function: PHY_SetRF8225Bandwidth()
|
||||
*
|
||||
* Overview: This function is called by SetBWModeCallback8190Pci() only
|
||||
*
|
||||
* Input: PADAPTER Adapter
|
||||
* WIRELESS_BANDWIDTH_E Bandwidth //20M or 40M
|
||||
*
|
||||
* Output: NONE
|
||||
*
|
||||
* Return: NONE
|
||||
*
|
||||
* Note: 8225(zebra1) support 20M only
|
||||
*---------------------------------------------------------------------------*/
|
||||
//just in phy
|
||||
void PHY_SetRF8225Bandwidth(struct net_device* dev ,HT_CHANNEL_WIDTH Bandwidth) //20M or 40M
|
||||
{
|
||||
u8 eRFPath;
|
||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
||||
|
||||
//for(eRFPath = RF90_PATH_A; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
|
||||
for(eRFPath = 0; eRFPath <priv->NumTotalRFPath; eRFPath++)
|
||||
{
|
||||
switch(Bandwidth)
|
||||
{
|
||||
case HT_CHANNEL_WIDTH_20:
|
||||
// TODO: Update the parameters here
|
||||
break;
|
||||
case HT_CHANNEL_WIDTH_20_40:
|
||||
RT_TRACE(COMP_DBG, "SetChannelBandwidth8190Pci():8225 does not support 40M mode\n");
|
||||
break;
|
||||
default:
|
||||
RT_TRACE(COMP_DBG, "PHY_SetRF8225Bandwidth(): unknown Bandwidth: %#X\n",Bandwidth );
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//just in phy
|
||||
bool PHY_RF8225_Config(struct net_device* dev )
|
||||
{
|
||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
||||
bool rtStatus = true;
|
||||
//RF90_RADIO_PATH_E eRFPath;
|
||||
//BB_REGISTER_DEFINITION_T *pPhyReg;
|
||||
//u32 OrgStoreRFIntSW[RF90_PATH_D+1];
|
||||
|
||||
//
|
||||
// Initialize general global value
|
||||
//
|
||||
// TODO: Extend RF_PATH_C and RF_PATH_D in the future
|
||||
priv->NumTotalRFPath = 2;
|
||||
|
||||
//
|
||||
// Config BB and RF
|
||||
//
|
||||
//switch( Adapter->MgntInfo.bRegHwParaFile )
|
||||
//{
|
||||
// case 0:
|
||||
// phy_RF8225_Config_HardCode(dev);
|
||||
// break;
|
||||
|
||||
// case 1:
|
||||
// rtStatus = phy_RF8225_Config_ParaFile(dev);
|
||||
// break;
|
||||
|
||||
// case 2:
|
||||
// Partial Modify.
|
||||
phy_RF8225_Config_HardCode(dev);
|
||||
phy_RF8225_Config_ParaFile(dev);
|
||||
// break;
|
||||
|
||||
// default:
|
||||
// phy_RF8225_Config_HardCode(dev);
|
||||
// break;
|
||||
//}
|
||||
return rtStatus;
|
||||
|
||||
}
|
||||
|
||||
//just in 8225
|
||||
void phy_RF8225_Config_HardCode(struct net_device* dev)
|
||||
{
|
||||
|
||||
// Set Default Bandwidth to 20M
|
||||
//Adapter->HalFunc .SetBWModeHandler(Adapter, HT_CHANNEL_WIDTH_20);
|
||||
|
||||
// TODO: Set Default Channel to channel one for RTL8225
|
||||
|
||||
}
|
||||
|
||||
//just in 8225
|
||||
bool phy_RF8225_Config_ParaFile(struct net_device* dev)
|
||||
{
|
||||
u32 u4RegValue = 0;
|
||||
//static char szRadioAFile[] = RTL819X_PHY_RADIO_A;
|
||||
//static char szRadioBFile[] = RTL819X_PHY_RADIO_B;
|
||||
u8 eRFPath;
|
||||
bool rtStatus = true;
|
||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
||||
BB_REGISTER_DEFINITION_T *pPhyReg;
|
||||
//u8 eCheckItem;
|
||||
|
||||
#if 1
|
||||
//3//-----------------------------------------------------------------
|
||||
//3// <2> Initialize RF
|
||||
//3//-----------------------------------------------------------------
|
||||
//for(eRFPath = RF90_PATH_A; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
|
||||
for(eRFPath = 0; eRFPath <priv->NumTotalRFPath; eRFPath++)
|
||||
{
|
||||
|
||||
pPhyReg = &priv->PHYRegDef[eRFPath];
|
||||
|
||||
/*----Store original RFENV control type----*/
|
||||
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;
|
||||
}
|
||||
|
||||
/*----Set RF_ENV enable----*/
|
||||
rtl8192_setBBreg(dev, pPhyReg->rfintfe, bRFSI_RFENV<<16, 0x1);
|
||||
|
||||
/*----Set RF_ENV output high----*/
|
||||
rtl8192_setBBreg(dev, pPhyReg->rfintfo, bRFSI_RFENV, 0x1);
|
||||
|
||||
/* Set bit number of Address and Data for RF register */
|
||||
rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, b3WireAddressLength, 0x0); // Set 1 to 4 bits for 8255
|
||||
rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, b3WireDataLength, 0x0); // Set 0 to 12 bits for 8255
|
||||
|
||||
|
||||
/*----Initialize RF fom connfiguration file----*/
|
||||
switch(eRFPath)
|
||||
{
|
||||
case RF90_PATH_A:
|
||||
//rtStatus = PHY_ConfigRFWithParaFile(dev, (char* )&szRadioAFile, (RF90_RADIO_PATH_E)eRFPath);
|
||||
rtStatus = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
|
||||
break;
|
||||
case RF90_PATH_B:
|
||||
//rtStatus = PHY_ConfigRFWithParaFile(dev, (char* )&szRadioBFile, (RF90_RADIO_PATH_E)eRFPath);
|
||||
rtStatus = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
|
||||
break;
|
||||
case RF90_PATH_C:
|
||||
break;
|
||||
case RF90_PATH_D:
|
||||
break;
|
||||
}
|
||||
|
||||
/*----Restore RFENV control type----*/;
|
||||
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(rtStatus == false){
|
||||
//RT_TRACE(COMP_FPGA, DBG_LOUD, ("phy_RF8225_Config_ParaFile():Radio[%d] Fail!!", eRFPath));
|
||||
goto phy_RF8225_Config_ParaFile_Fail;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//RT_TRACE(COMP_INIT, DBG_LOUD, ("<---phy_RF8225_Config_ParaFile()\n"));
|
||||
return rtStatus;
|
||||
|
||||
phy_RF8225_Config_ParaFile_Fail:
|
||||
#endif
|
||||
return rtStatus;
|
||||
}
|
||||
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
This is part of the rtl8180-sa2400 driver
|
||||
released under the GPL (See file COPYING for details).
|
||||
Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
|
||||
|
||||
This files contains programming code for the rtl8256
|
||||
radio frontend.
|
||||
|
||||
*Many* thanks to Realtek Corp. for their great support!
|
||||
|
||||
*/
|
||||
|
||||
#ifndef RTL8225H
|
||||
#define RTL8225H
|
||||
|
||||
#ifdef RTL8190P
|
||||
#define RTL819X_TOTAL_RF_PATH 4 //for 90P
|
||||
#else
|
||||
#define RTL819X_TOTAL_RF_PATH 2 //for 8192U
|
||||
#endif
|
||||
extern void PHY_SetRF0222DBandwidth(struct net_device* dev , HT_CHANNEL_WIDTH Bandwidth); //20M or 40M;
|
||||
extern void PHY_SetRF8225Bandwidth( struct net_device* dev , HT_CHANNEL_WIDTH Bandwidth);
|
||||
extern bool PHY_RF8225_Config(struct net_device* dev );
|
||||
extern void phy_RF8225_Config_HardCode(struct net_device* dev);
|
||||
extern bool phy_RF8225_Config_ParaFile(struct net_device* dev);
|
||||
extern void PHY_SetRF8225CckTxPower(struct net_device* dev ,u8 powerlevel);
|
||||
extern void PHY_SetRF8225OfdmTxPower(struct net_device* dev ,u8 powerlevel);
|
||||
extern void PHY_SetRF0222DOfdmTxPower(struct net_device* dev ,u8 powerlevel);
|
||||
extern void PHY_SetRF0222DCckTxPower(struct net_device* dev ,u8 powerlevel);
|
||||
#endif
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,254 +0,0 @@
|
|||
/*****************************************************************************
|
||||
* Copyright(c) 2007, RealTEK Technology Inc. All Right Reserved.
|
||||
*
|
||||
* Module: Hal819xUsbDM.h (RTL8192 Header H File)
|
||||
*
|
||||
*
|
||||
* Note: For dynamic control definition constant structure.
|
||||
*
|
||||
*
|
||||
* Export:
|
||||
*
|
||||
* Abbrev:
|
||||
*
|
||||
* History:
|
||||
* Data Who Remark
|
||||
* 10/04/2007 MHC Create initial version.
|
||||
*
|
||||
*****************************************************************************/
|
||||
/* Check to see if the file has been included already. */
|
||||
#ifndef __R8192UDM_H__
|
||||
#define __R8192UDM_H__
|
||||
|
||||
|
||||
/*--------------------------Define Parameters-------------------------------*/
|
||||
#define DM_DIG_THRESH_HIGH 40
|
||||
#define DM_DIG_THRESH_LOW 35
|
||||
|
||||
#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
|
||||
#define DM_DIG_MAX 0x36
|
||||
#define DM_DIG_MIN 0x1c
|
||||
#define DM_DIG_MIN_Netcore 0x12
|
||||
|
||||
#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
|
||||
#define CTSToSelfTHVal 30
|
||||
|
||||
//defined by vivi, for tx power track
|
||||
#define E_FOR_TX_POWER_TRACK 300
|
||||
//Dynamic Tx Power Control Threshold
|
||||
#define TX_POWER_NEAR_FIELD_THRESH_HIGH 68
|
||||
#define TX_POWER_NEAR_FIELD_THRESH_LOW 62
|
||||
//added by amy for atheros AP
|
||||
#define TX_POWER_ATHEROAP_THRESH_HIGH 78
|
||||
#define TX_POWER_ATHEROAP_THRESH_LOW 72
|
||||
|
||||
//defined by vivi, for showing on UI
|
||||
#define Current_Tx_Rate_Reg 0x1b8
|
||||
#define Initial_Tx_Rate_Reg 0x1b9
|
||||
#define Tx_Retry_Count_Reg 0x1ac
|
||||
#define RegC38_TH 20
|
||||
/*--------------------------Define Parameters-------------------------------*/
|
||||
|
||||
|
||||
/*------------------------------Define structure----------------------------*/
|
||||
/* 2007/10/04 MH Define upper and lower threshold of DIG enable or disable. */
|
||||
typedef struct _dynamic_initial_gain_threshold_
|
||||
{
|
||||
u8 dig_enable_flag;
|
||||
u8 dig_algorithm;
|
||||
u8 dbg_mode;
|
||||
u8 dig_algorithm_switch;
|
||||
|
||||
long rssi_low_thresh;
|
||||
long rssi_high_thresh;
|
||||
|
||||
long rssi_high_power_lowthresh;
|
||||
long rssi_high_power_highthresh;
|
||||
|
||||
u8 dig_state;
|
||||
u8 dig_highpwr_state;
|
||||
u8 cur_connect_state;
|
||||
u8 pre_connect_state;
|
||||
|
||||
u8 curpd_thstate;
|
||||
u8 prepd_thstate;
|
||||
u8 curcs_ratio_state;
|
||||
u8 precs_ratio_state;
|
||||
|
||||
u32 pre_ig_value;
|
||||
u32 cur_ig_value;
|
||||
|
||||
u8 backoff_val;
|
||||
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;
|
||||
|
||||
|
||||
/* 2007/10/08 MH Define RATR state. */
|
||||
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;
|
||||
|
||||
/* 2007/10/11 MH Define DIG operation type. */
|
||||
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_MAX
|
||||
}dm_dig_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_DISCONNECT = 0,
|
||||
DIG_CONNECT = 1,
|
||||
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; /* Command packet type. */
|
||||
u32 Length; /* Command packet 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;
|
||||
/*------------------------Export global variable----------------------------*/
|
||||
|
||||
|
||||
/*------------------------Export Marco Definition---------------------------*/
|
||||
|
||||
/*------------------------Export Marco Definition---------------------------*/
|
||||
|
||||
|
||||
/*--------------------------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(struct work_struct *work);
|
||||
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_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(struct work_struct *work);
|
||||
extern void dm_fsync_timer_callback(unsigned long data);
|
||||
extern void dm_cck_txpower_adjust(struct net_device *dev,bool binch14);
|
||||
extern void dm_shadow_init(struct net_device *dev);
|
||||
extern void dm_initialize_txpower_tracking(struct net_device *dev);
|
||||
/*--------------------------Exported Function prototype---------------------*/
|
||||
|
||||
|
||||
#endif /*__R8192UDM_H__ */
|
||||
|
||||
|
||||
/* End of r8192U_dm.h */
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
/*
|
||||
Power management interface routines.
|
||||
Written by Mariusz Matuszek.
|
||||
This code is currently just a placeholder for later work and
|
||||
does not do anything useful.
|
||||
|
||||
This is part of rtl8180 OpenSource driver.
|
||||
Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it>
|
||||
Released under the terms of GPL (General Public Licence)
|
||||
*/
|
||||
|
||||
#include "r8192U.h"
|
||||
#include "r8192U_pm.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
int rtl8192U_save_state (struct pci_dev *dev, u32 state)
|
||||
{
|
||||
printk(KERN_NOTICE "r8192U save state call (state %u).\n", state);
|
||||
return(-EAGAIN);
|
||||
}
|
||||
|
||||
int rtl8192U_suspend(struct usb_interface *intf, pm_message_t state)
|
||||
{
|
||||
struct net_device *dev = usb_get_intfdata(intf);
|
||||
|
||||
RT_TRACE(COMP_POWER, "============> r8192U suspend call.\n");
|
||||
|
||||
if(dev) {
|
||||
if (!netif_running(dev)) {
|
||||
printk(KERN_WARNING "netif not running, go out suspend function\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (dev->netdev_ops->ndo_stop)
|
||||
dev->netdev_ops->ndo_stop(dev);
|
||||
|
||||
mdelay(10);
|
||||
|
||||
netif_device_detach(dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtl8192U_resume (struct usb_interface *intf)
|
||||
{
|
||||
struct net_device *dev = usb_get_intfdata(intf);
|
||||
|
||||
RT_TRACE(COMP_POWER, "================>r8192U resume call.");
|
||||
|
||||
if(dev) {
|
||||
if (!netif_running(dev)){
|
||||
printk(KERN_WARNING "netif not running, go out resume function\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
netif_device_attach(dev);
|
||||
|
||||
if (dev->netdev_ops->ndo_open)
|
||||
dev->netdev_ops->ndo_open(dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtl8192U_enable_wake (struct pci_dev *dev, u32 state, int enable)
|
||||
{
|
||||
printk(KERN_NOTICE "r8192U enable wake call (state %u, enable %d).\n",
|
||||
state, enable);
|
||||
return(-EAGAIN);
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
/*
|
||||
Power management interface routines.
|
||||
Written by Mariusz Matuszek.
|
||||
This code is currently just a placeholder for later work and
|
||||
does not do anything useful.
|
||||
|
||||
This is part of rtl8180 OpenSource driver.
|
||||
Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it>
|
||||
Released under the terms of GPL (General Public Licence)
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifndef R8192_PM_H
|
||||
#define R8192_PM_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/usb.h>
|
||||
|
||||
int rtl8192U_save_tate (struct pci_dev *dev, u32 state);
|
||||
int rtl8192U_suspend(struct usb_interface *intf, pm_message_t state);
|
||||
int rtl8192U_resume (struct usb_interface *intf);
|
||||
int rtl8192U_enable_wake (struct pci_dev *dev, u32 state, int enable);
|
||||
|
||||
#endif //R8192U_PM_H
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,22 +0,0 @@
|
|||
/*
|
||||
This is part of rtl8180 OpenSource driver - v 0.3
|
||||
Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it>
|
||||
Released under the terms of GPL (General Public Licence)
|
||||
|
||||
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 such projects and the Ndiswrapper project Authors.
|
||||
*/
|
||||
|
||||
/* this file (will) contains wireless extension handlers*/
|
||||
|
||||
#ifndef R8180_WX_H
|
||||
#define R8180_WX_H
|
||||
//#include <linux/wireless.h>
|
||||
extern struct iw_handler_def r8192_wx_handlers_def;
|
||||
/* Enable the rtl819x_core.c to share this function, david 2008.9.22 */
|
||||
extern struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev);
|
||||
|
||||
#endif
|
|
@ -1,22 +0,0 @@
|
|||
//
|
||||
// IOT Action for different AP
|
||||
//
|
||||
typedef enum _HT_IOT_ACTION{
|
||||
HT_IOT_ACT_TX_USE_AMSDU_4K = 0x00000001,
|
||||
HT_IOT_ACT_TX_USE_AMSDU_8K = 0x00000002,
|
||||
HT_IOT_ACT_DECLARE_MCS13 = 0x00000004,
|
||||
HT_IOT_ACT_DISABLE_EDCA_TURBO = 0x00000008,
|
||||
HT_IOT_ACT_MGNT_USE_CCK_6M = 0x00000010,
|
||||
HT_IOT_ACT_CDD_FSYNC = 0x00000020,
|
||||
HT_IOT_ACT_PURE_N_MODE = 0x00000040,
|
||||
|
||||
//LZM ADD 090224
|
||||
HT_IOT_ACT_EDCA_BIAS_ON_RX = 0x00004000,
|
||||
HT_IOT_ACT_HYBRID_AGGREGATION = 0x00010000,
|
||||
HT_IOT_ACT_AMSDU_ENABLE = 0x00000800,
|
||||
HT_IOT_ACT_DISABLE_SHORT_GI = 0x00020000,
|
||||
HT_IOT_ACT_DISABLE_HIGH_POWER = 0x00040000,
|
||||
HT_IOT_ACT_DISABLE_TX_2SS = 0x00200000,
|
||||
HT_IOT_ACT_DISABLE_TX_40_MHZ = 0x00080000,
|
||||
}HT_IOT_ACTION_E, *PHT_IOT_ACTION_E;
|
||||
|
|
@ -1,383 +0,0 @@
|
|||
#ifndef _R819XU_HTTYPE_H_
|
||||
#define _R819XU_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
|
||||
|
||||
|
||||
#define HT_SUPPORTED_MCS_1SS_BITMAP 0x000000ff
|
||||
#define HT_SUPPORTED_MCS_2SS_BITMAP 0x0000ff00
|
||||
#define HT_SUPPORTED_MCS_1SS_2SS_BITMAP HT_MCS_1SS_BITMAP|HT_MCS_1SS_2SS_BITMAP
|
||||
|
||||
|
||||
typedef enum _HT_MCS_RATE{
|
||||
HT_MCS0 = 0x00000001,
|
||||
HT_MCS1 = 0x00000002,
|
||||
HT_MCS2 = 0x00000004,
|
||||
HT_MCS3 = 0x00000008,
|
||||
HT_MCS4 = 0x00000010,
|
||||
HT_MCS5 = 0x00000020,
|
||||
HT_MCS6 = 0x00000040,
|
||||
HT_MCS7 = 0x00000080,
|
||||
HT_MCS8 = 0x00000100,
|
||||
HT_MCS9 = 0x00000200,
|
||||
HT_MCS10 = 0x00000400,
|
||||
HT_MCS11 = 0x00000800,
|
||||
HT_MCS12 = 0x00001000,
|
||||
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 Extention 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,
|
||||
HT_EXTCHNL_OFFSET_NO_DEF = 2,
|
||||
HT_EXTCHNL_OFFSET_LOWER = 3,
|
||||
}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, *PCHNLOP;
|
||||
|
||||
// Determine if the Channel Operation is in progress
|
||||
#define CHHLOP_IN_PROGRESS(_pHTInfo) \
|
||||
((_pHTInfo)->ChnlOp > CHNLOP_NONE) ? TRUE : FALSE
|
||||
|
||||
|
||||
typedef enum _HT_ACTION{
|
||||
ACT_RECOMMAND_WIDTH = 0,
|
||||
ACT_MIMO_PWR_SAVE = 1,
|
||||
ACT_PSMP = 2,
|
||||
ACT_SET_PCO_PHASE = 3,
|
||||
ACT_MIMO_CHL_MEASURE = 4,
|
||||
ACT_RECIPROCITY_CORRECT = 5,
|
||||
ACT_MIMO_CSI_MATRICS = 6,
|
||||
ACT_MIMO_NOCOMPR_STEER = 7,
|
||||
ACT_MIMO_COMPR_STEER = 8,
|
||||
ACT_ANTENNA_SELECT = 9,
|
||||
} 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,
|
||||
SC_MODE_UPPER = 2,
|
||||
SC_MODE_FULL40MHZ = 3,
|
||||
}HT_BW40_SC_E;
|
||||
|
||||
typedef struct _HT_CAPABILITY_ELE{
|
||||
|
||||
//HT capability info
|
||||
u8 AdvCoding:1;
|
||||
u8 ChlWidth:1;
|
||||
u8 MimoPwrSave:2;
|
||||
u8 GreenField:1;
|
||||
u8 ShortGI20Mhz:1;
|
||||
u8 ShortGI40Mhz:1;
|
||||
u8 TxSTBC:1;
|
||||
u8 RxSTBC:2;
|
||||
u8 DelayBA:1;
|
||||
u8 MaxAMSDUSize:1;
|
||||
u8 DssCCk:1;
|
||||
u8 PSMP:1;
|
||||
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;
|
||||
|
||||
u8 ExtChlOffset:2;
|
||||
u8 RecommemdedTxWidth:1;
|
||||
u8 RIFS:1;
|
||||
u8 PSMPAccessOnly:1;
|
||||
u8 SrvIntGranularity:3;
|
||||
|
||||
u8 OptMode:2;
|
||||
u8 NonGFDevPresent:1;
|
||||
u8 Revd1:5;
|
||||
u8 Revd2:8;
|
||||
|
||||
u8 Rsvd3:6;
|
||||
u8 DualBeacon:1;
|
||||
u8 DualCTSProtect:1;
|
||||
|
||||
u8 SecondaryBeacon:1;
|
||||
u8 LSigTxopProtectFull:1;
|
||||
u8 PcoActive:1;
|
||||
u8 PcoPhase:1;
|
||||
u8 Rsvd4:4;
|
||||
|
||||
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;
|
||||
u8 Reserved:6;
|
||||
} MIMOPS_CTRL, *PMIMOPS_CTRL;
|
||||
|
||||
typedef enum _HT_SPEC_VER{
|
||||
HT_SPEC_VER_IEEE = 0,
|
||||
HT_SPEC_VER_EWC = 1,
|
||||
}HT_SPEC_VER, *PHT_SPEC_VER;
|
||||
|
||||
typedef enum _HT_AGGRE_MODE_E{
|
||||
HT_AGG_AUTO = 0,
|
||||
HT_AGG_FORCE_ENABLE = 1,
|
||||
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{
|
||||
// DECLARE_RT_OBJECT(_RT_HIGH_THROUGHPUT);
|
||||
u8 bEnableHT;
|
||||
u8 bCurrentHTSupport;
|
||||
|
||||
u8 bRegBW40MHz; // Tx 40MHz channel capablity
|
||||
u8 bCurBW40MHz; // Tx 40MHz channel capability
|
||||
|
||||
u8 bRegShortGI40MHz; // Tx Short GI for 40Mhz
|
||||
u8 bCurShortGI40MHz; // Tx Short GI for 40MHz
|
||||
|
||||
u8 bRegShortGI20MHz; // Tx Short GI for 20MHz
|
||||
u8 bCurShortGI20MHz; // Tx Short GI for 20MHz
|
||||
|
||||
u8 bRegSuppCCK; // Tx CCK rate capability
|
||||
u8 bCurSuppCCK; // Tx CCK rate capability
|
||||
|
||||
// 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 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
|
||||
|
||||
|
||||
// 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;
|
||||
|
||||
u8 bForcedShortGI;
|
||||
|
||||
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 PeerBandwidth;
|
||||
|
||||
// For Bandwidth Switching
|
||||
u8 bSwBwInProgress;
|
||||
CHNLOP ChnlOp; // software switching channel in progress. By Bruce, 2008-02-15.
|
||||
u8 SwBwStep;
|
||||
//RT_TIMER SwBwTimer;
|
||||
struct timer_list SwBwTimer;
|
||||
|
||||
// For Realtek proprietary A-MPDU factor for aggregation
|
||||
u8 bRegRT2RTAggregation;
|
||||
u8 bCurrentRT2RTAggregation;
|
||||
u8 bCurrentRT2RTLongSlotTime;
|
||||
u8 szRT2RTAggBuffer[10];
|
||||
|
||||
// Rx Reorder control
|
||||
u8 bRegRxReorderEnable;
|
||||
u8 bCurRxReorderEnable;
|
||||
u8 RxReorderWinSize;
|
||||
u8 RxReorderPendingTime;
|
||||
u16 RxReorderDropCounter;
|
||||
|
||||
|
||||
// Add for Broadcom(Linksys) IOT. Joseph
|
||||
u8 bIsPeerBcm;
|
||||
|
||||
// For IOT issue.
|
||||
u32 IOTAction;
|
||||
}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;
|
||||
|
||||
u8 bSupportCck;
|
||||
|
||||
u16 AMSDU_MaxSize;
|
||||
|
||||
u8 AMPDU_Factor;
|
||||
u8 MPDU_Density;
|
||||
|
||||
u8 HTHighestOperaRate;
|
||||
|
||||
u8 bBw40MHz;
|
||||
|
||||
u8 MimoPs;
|
||||
|
||||
u8 McsRateSet[16];
|
||||
|
||||
|
||||
}RT_HTINFO_STA_ENTRY, *PRT_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;
|
||||
|
||||
u8 bdRT2RTAggregation;
|
||||
u8 bdRT2RTLongSlotTime;
|
||||
bool bdHT1R;
|
||||
}BSS_HT, *PBSS_HT;
|
||||
|
||||
typedef struct _MIMO_RSSI{
|
||||
u32 EnableAntenna;
|
||||
u32 AntennaA;
|
||||
u32 AntennaB;
|
||||
u32 AntennaC;
|
||||
u32 AntennaD;
|
||||
u32 Average;
|
||||
}MIMO_RSSI, *PMIMO_RSSI;
|
||||
|
||||
typedef struct _MIMO_EVM{
|
||||
u32 EVM1;
|
||||
u32 EVM2;
|
||||
}MIMO_EVM, *PMIMO_EVM;
|
||||
|
||||
typedef struct _FALSE_ALARM_STATISTICS{
|
||||
u32 Cnt_Parity_Fail;
|
||||
u32 Cnt_Rate_Illegal;
|
||||
u32 Cnt_Crc8_fail;
|
||||
u32 Cnt_all;
|
||||
}FALSE_ALARM_STATISTICS, *PFALSE_ALARM_STATISTICS;
|
||||
|
||||
|
||||
|
||||
#endif //__INC_HTTYPE_H
|
||||
|
|
@ -1,512 +0,0 @@
|
|||
/******************************************************************************
|
||||
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
|
||||
* Linux device driver for RTL8192U
|
||||
*
|
||||
* 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 "r8192U.h"
|
||||
#include "r819xU_cmdpkt.h"
|
||||
|
||||
bool SendTxCommandPacket(struct net_device *dev, void *pData, u32 DataLen)
|
||||
{
|
||||
bool rtStatus = true;
|
||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
||||
struct sk_buff *skb;
|
||||
cb_desc *tcb_desc;
|
||||
unsigned char *ptr_buf;
|
||||
|
||||
/*
|
||||
* Get TCB and local buffer from common pool.
|
||||
* (It is shared by CmdQ, MgntQ, and USB coalesce DataQ)
|
||||
*/
|
||||
skb = dev_alloc_skb(USB_HWDESC_HEADER_LEN + DataLen + 4);
|
||||
if (!skb)
|
||||
return false;
|
||||
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 = 0;
|
||||
skb_reserve(skb, USB_HWDESC_HEADER_LEN);
|
||||
ptr_buf = skb_put(skb, DataLen);
|
||||
memcpy(ptr_buf, pData, DataLen);
|
||||
tcb_desc->txbuf_size = (u16)DataLen;
|
||||
|
||||
if (!priv->ieee80211->check_nic_enough_desc(dev, tcb_desc->queue_index) ||
|
||||
(!skb_queue_empty(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index])) ||
|
||||
(priv->ieee80211->queue_stop)) {
|
||||
RT_TRACE(COMP_FIRMWARE, "NULL packet => tx full\n");
|
||||
skb_queue_tail(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index], skb);
|
||||
} else {
|
||||
priv->ieee80211->softmac_hard_start_xmit(skb, dev);
|
||||
}
|
||||
|
||||
return rtStatus;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: cmpk_message_handle_tx()
|
||||
*
|
||||
* Overview: Driver internal module can call the API to send message to
|
||||
* firmware side. For example, you can send a debug command packet.
|
||||
* Or you can send a request for FW to modify RLX4181 LBUS HW bank.
|
||||
* Otherwise, you can change MAC/PHT/RF register by firmware at
|
||||
* run time. We do not support message more than one segment now.
|
||||
*
|
||||
* Input: NONE
|
||||
*
|
||||
* Output: NONE
|
||||
*
|
||||
* Return: NONE
|
||||
*/
|
||||
extern bool cmpk_message_handle_tx(
|
||||
struct net_device *dev,
|
||||
u8 *codevirtualaddress,
|
||||
u32 packettype,
|
||||
u32 buffer_len)
|
||||
{
|
||||
bool rt_status = true;
|
||||
return rt_status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: cmpk_counttxstatistic()
|
||||
*/
|
||||
static void
|
||||
cmpk_count_txstatistic(struct net_device *dev, cmpk_txfb_t *pstx_fb)
|
||||
{
|
||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
||||
#ifdef ENABLE_PS
|
||||
RT_RF_POWER_STATE rtState;
|
||||
|
||||
pAdapter->HalFunc.GetHwRegHandler(pAdapter,
|
||||
HW_VAR_RF_STATE,
|
||||
(pu1Byte)(&rtState));
|
||||
|
||||
/*
|
||||
* When RF is off, we should not count the packet for hw/sw synchronize
|
||||
* reason, ie. there may be a duration while sw switch is changed and hw
|
||||
* switch is being changed.
|
||||
*/
|
||||
if (rtState == eRfOff)
|
||||
return;
|
||||
#endif
|
||||
|
||||
#ifdef TODO
|
||||
if (pAdapter->bInHctTest)
|
||||
return;
|
||||
#endif
|
||||
/*
|
||||
* We can not know the packet length and transmit type:
|
||||
* broadcast or uni or multicast.
|
||||
* So the relative statistics must be collected in tx feedback info
|
||||
*/
|
||||
if (pstx_fb->tok) {
|
||||
priv->stats.txfeedbackok++;
|
||||
priv->stats.txoktotal++;
|
||||
priv->stats.txokbytestotal += pstx_fb->pkt_length;
|
||||
priv->stats.txokinperiod++;
|
||||
/* We can not make sure broadcast/multicast or unicast mode. */
|
||||
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;
|
||||
/* We can not make sure broadcast/multicast or unicast mode. */
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: cmpk_handle_tx_feedback()
|
||||
*
|
||||
* Overview: The function is responsible for extract the message inside TX
|
||||
* feedbck message from firmware. It will contain dedicated info in
|
||||
* ws-06-0063-rtl8190-command-packet-specification. Please
|
||||
* refer to chapter "TX Feedback Element". We have to read 20 bytes
|
||||
* in the command packet.
|
||||
*
|
||||
* Input: struct net_device * dev
|
||||
* u8 *pmsg - Msg Ptr of the command packet.
|
||||
*
|
||||
* Output: NONE
|
||||
*
|
||||
* Return: NONE
|
||||
*/
|
||||
static void cmpk_handle_tx_feedback(struct net_device *dev, u8 *pmsg)
|
||||
{
|
||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
||||
cmpk_txfb_t rx_tx_fb;
|
||||
|
||||
priv->stats.txfeedback++;
|
||||
|
||||
/* 1. Extract TX feedback info from RFD to temp structure buffer. */
|
||||
memcpy((u8 *)&rx_tx_fb, pmsg, sizeof(cmpk_txfb_t));
|
||||
|
||||
/* 2. Use tx feedback info to count TX statistics. */
|
||||
cmpk_count_txstatistic(dev, &rx_tx_fb);
|
||||
}
|
||||
|
||||
void cmdpkt_beacontimerinterrupt_819xusb(struct net_device *dev)
|
||||
{
|
||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
||||
u16 tx_rate;
|
||||
|
||||
if (priv->ieee80211->current_network.mode == IEEE_A ||
|
||||
priv->ieee80211->current_network.mode == IEEE_N_5G ||
|
||||
(priv->ieee80211->current_network.mode == IEEE_N_24G &&
|
||||
(!priv->ieee80211->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");
|
||||
}
|
||||
rtl819xusb_beacon_tx(dev, tx_rate); /* HW Beacon */
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: cmpk_handle_interrupt_status()
|
||||
*
|
||||
* Overview: The function is responsible for extract the message from
|
||||
* firmware. It will contain dedicated info in
|
||||
* ws-07-0063-v06-rtl819x-command-packet-specification-070315.doc.
|
||||
* Please refer to chapter "Interrupt Status Element".
|
||||
*
|
||||
* Input: struct net_device *dev,
|
||||
* u8* pmsg - Message Pointer of the command packet.
|
||||
*
|
||||
* Output: NONE
|
||||
*
|
||||
* Return: NONE
|
||||
*/
|
||||
static void cmpk_handle_interrupt_status(struct net_device *dev, u8 *pmsg)
|
||||
{
|
||||
cmpk_intr_sta_t rx_intr_status; /* */
|
||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
||||
|
||||
DMESG("---> cmpk_Handle_Interrupt_Status()\n");
|
||||
|
||||
/* 1. Extract TX feedback info from RFD to temp structure buffer. */
|
||||
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;
|
||||
}
|
||||
/* Statistics of beacon for ad-hoc mode. */
|
||||
if (priv->ieee80211->iw_mode == IW_MODE_ADHOC) {
|
||||
//2 maybe need endian transform?
|
||||
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->ieee80211->bibsscoordinator = true;
|
||||
priv->stats.txbeaconokint++;
|
||||
} else if (rx_intr_status.interrupt_status & ISR_TxBcnErr) {
|
||||
priv->ieee80211->bibsscoordinator = false;
|
||||
priv->stats.txbeaconerr++;
|
||||
}
|
||||
|
||||
if (rx_intr_status.interrupt_status & ISR_BcnTimerIntr)
|
||||
cmdpkt_beacontimerinterrupt_819xusb(dev);
|
||||
}
|
||||
/* Other informations in interrupt status we need? */
|
||||
DMESG("<---- cmpk_handle_interrupt_status()\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: cmpk_handle_query_config_rx()
|
||||
*
|
||||
* Overview: The function is responsible for extract the message from
|
||||
* firmware. It will contain dedicated info in
|
||||
* ws-06-0063-rtl8190-command-packet-specification
|
||||
* Please refer to chapter "Beacon State Element".
|
||||
*
|
||||
* Input: u8 * pmsg - Message Pointer of the command packet.
|
||||
*
|
||||
* Output: NONE
|
||||
*
|
||||
* Return: NONE
|
||||
*
|
||||
*/
|
||||
static void cmpk_handle_query_config_rx(struct net_device *dev, u8 *pmsg)
|
||||
{
|
||||
cmpk_query_cfg_t rx_query_cfg;
|
||||
/*
|
||||
* Extract TX feedback info from RFD to temp structure buffer.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: cmpk_count_tx_status()
|
||||
*
|
||||
* Overview: Count aggregated tx status from firmware of one type rx command
|
||||
* packet element id = RX_TX_STATUS.
|
||||
*
|
||||
* Input: NONE
|
||||
*
|
||||
* Output: NONE
|
||||
*
|
||||
* Return: NONE
|
||||
*/
|
||||
static void cmpk_count_tx_status(struct net_device *dev,
|
||||
cmpk_tx_status_t *pstx_status)
|
||||
{
|
||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
||||
|
||||
#ifdef ENABLE_PS
|
||||
|
||||
RT_RF_POWER_STATE rtstate;
|
||||
|
||||
pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState));
|
||||
|
||||
/*
|
||||
* When RF is off, we should not count the packet for hw/sw synchronize
|
||||
* reason, ie. there may be a duration while sw switch is changed and hw
|
||||
* switch is being changed.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: cmpk_handle_tx_status()
|
||||
*
|
||||
* Overview: Firmware add a new tx feedback status to reduce rx command
|
||||
* packet buffer operation load.
|
||||
*
|
||||
* Input: NONE
|
||||
*
|
||||
* Output: NONE
|
||||
*
|
||||
* Return: NONE
|
||||
*/
|
||||
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));
|
||||
/* 2. Use tx feedback info to count TX statistics. */
|
||||
cmpk_count_tx_status(dev, &rx_tx_sts);
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: cmpk_handle_tx_rate_history()
|
||||
*
|
||||
* Overview: Firmware add a new tx rate history
|
||||
*
|
||||
* Input: NONE
|
||||
*
|
||||
* Output: NONE
|
||||
*
|
||||
* Return: NONE
|
||||
*/
|
||||
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 = ieee80211_priv(dev);
|
||||
|
||||
#ifdef ENABLE_PS
|
||||
pAdapter->HalFunc.GetHwRegHandler(pAdapter,
|
||||
HW_VAR_RF_STATE,
|
||||
(pu1Byte)(&rtState));
|
||||
/*
|
||||
* When RF is off, we should not count the packet for hw/sw synchronize
|
||||
* reason, ie. there may be a duration while sw switch is changed and hw
|
||||
* switch is being changed.
|
||||
*/
|
||||
if (rtState == eRfOff)
|
||||
return;
|
||||
#endif
|
||||
ptemp = (u32 *)pmsg;
|
||||
|
||||
/*
|
||||
* Do endian transfer to word alignment(16 bits) for windows system.
|
||||
* You must do different endian transfer for linux and MAC OS
|
||||
*/
|
||||
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++) {
|
||||
/* Collect CCK rate packet num */
|
||||
if (i < 4)
|
||||
priv->stats.txrate.cck[i] += ptxrate->cck[i];
|
||||
/* Collect OFDM rate packet num */
|
||||
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];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: cmpk_message_handle_rx()
|
||||
*
|
||||
* Overview: In the function, we will capture different RX command packet
|
||||
* info. Every RX command packet element has different message
|
||||
* length and meaning in content. We only support three type of RX
|
||||
* command packet now. Please refer to document
|
||||
* ws-06-0063-rtl8190-command-packet-specification.
|
||||
*
|
||||
* Input: NONE
|
||||
*
|
||||
* Output: NONE
|
||||
*
|
||||
* Return: NONE
|
||||
*/
|
||||
extern u32
|
||||
cmpk_message_handle_rx(
|
||||
struct net_device *dev,
|
||||
struct ieee80211_rx_stats *pstats)
|
||||
{
|
||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
||||
int total_length;
|
||||
u8 cmd_length, exe_cnt = 0;
|
||||
u8 element_id;
|
||||
u8 *pcmd_buff;
|
||||
|
||||
/*
|
||||
* 0. Check input arguments.
|
||||
* If is is a command queue message or pointer is null
|
||||
*/
|
||||
if ((pstats == NULL))
|
||||
return 0; /* This is not a command packet. */
|
||||
|
||||
/* 1. Read received command packet message length from RFD. */
|
||||
total_length = pstats->Length;
|
||||
|
||||
/* 2. Read virtual address from RFD. */
|
||||
pcmd_buff = pstats->virtual_address;
|
||||
|
||||
/* 3. Read command pakcet element id and length. */
|
||||
element_id = pcmd_buff[0];
|
||||
|
||||
/*
|
||||
* 4. Check every received command packet conent according to different
|
||||
* element type. Because FW may aggregate RX command packet to minimize
|
||||
* transmit time between DRV and FW.
|
||||
*/
|
||||
|
||||
/* Add a counter to prevent to locked in the loop too long */
|
||||
while (total_length > 0 || exe_cnt++ > 100) {
|
||||
/* We support aggregation of different cmd in the same packet */
|
||||
element_id = pcmd_buff[0];
|
||||
switch (element_id) {
|
||||
case RX_TX_FEEDBACK:
|
||||
cmpk_handle_tx_feedback(dev, pcmd_buff);
|
||||
cmd_length = CMPK_RX_TX_FB_SIZE;
|
||||
break;
|
||||
case RX_INTERRUPT_STATUS:
|
||||
cmpk_handle_interrupt_status(dev, pcmd_buff);
|
||||
cmd_length = sizeof(cmpk_intr_sta_t);
|
||||
break;
|
||||
case BOTH_QUERY_CONFIG:
|
||||
cmpk_handle_query_config_rx(dev, pcmd_buff);
|
||||
cmd_length = CMPK_BOTH_QUERY_CONFIG_SIZE;
|
||||
break;
|
||||
case RX_TX_STATUS:
|
||||
cmpk_handle_tx_status(dev, pcmd_buff);
|
||||
cmd_length = CMPK_RX_TX_STS_SIZE;
|
||||
break;
|
||||
case RX_TX_PER_PKT_FEEDBACK:
|
||||
cmd_length = CMPK_RX_TX_FB_SIZE;
|
||||
break;
|
||||
case RX_TX_RATE_HISTORY:
|
||||
cmpk_handle_tx_rate_history(dev, pcmd_buff);
|
||||
cmd_length = CMPK_TX_RAHIS_SIZE;
|
||||
break;
|
||||
case RX_TX_TSSI_MEAN_BACK:
|
||||
{
|
||||
u32 *pMsg;
|
||||
pMsg = (u32 *)pcmd_buff;
|
||||
}
|
||||
cmd_length = 32;
|
||||
break;
|
||||
default:
|
||||
RT_TRACE(COMP_ERR, "(%s): unknown CMD Element\n",
|
||||
__func__);
|
||||
return 1; /* This is a command packet. */
|
||||
}
|
||||
priv->stats.rxcmdpkt[element_id]++;
|
||||
total_length -= cmd_length;
|
||||
pcmd_buff += cmd_length;
|
||||
}
|
||||
return 1; /* This is a command packet. */
|
||||
}
|
|
@ -1,192 +0,0 @@
|
|||
#ifndef R819XUSB_CMDPKT_H
|
||||
#define R819XUSB_CMDPKT_H
|
||||
|
||||
/*
|
||||
* Different command packets have dedicated message length and definition.
|
||||
*/
|
||||
#define CMPK_RX_TX_FB_SIZE sizeof(cmpk_txfb_t) /* 20 */
|
||||
#define CMPK_TX_SET_CONFIG_SIZE sizeof(cmpk_set_cfg_t) /* 16 */
|
||||
#define CMPK_BOTH_QUERY_CONFIG_SIZE sizeof(cmpk_set_cfg_t) /* 16 */
|
||||
#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)
|
||||
|
||||
/* For USB constant. */
|
||||
#define ISR_TxBcnOk BIT27 /* Transmit Beacon OK */
|
||||
#define ISR_TxBcnErr BIT26 /* Transmit Beacon Error */
|
||||
#define ISR_BcnTimerIntr BIT13 /* Beacon Timer Interrupt */
|
||||
|
||||
/*
|
||||
* Define different command packet structures
|
||||
*
|
||||
* 1. RX side: TX feedback packet.
|
||||
*/
|
||||
typedef struct tag_cmd_pkt_tx_feedback {
|
||||
/* DWORD 0 */
|
||||
u8 element_id; /* Command packet type. */
|
||||
u8 length; /* Command packet length. */
|
||||
/* TX Feedback Info Field */
|
||||
u8 TID:4;
|
||||
u8 fail_reason:3;
|
||||
u8 tok:1; /* Transmit ok. */
|
||||
u8 reserve1:4;
|
||||
u8 pkt_type:2;
|
||||
u8 bandwidth:1;
|
||||
u8 qos_pkt:1;
|
||||
|
||||
/* DWORD 1 */
|
||||
u8 reserve2;
|
||||
/* TX Feedback Info Field */
|
||||
u8 retry_cnt;
|
||||
u16 pkt_id;
|
||||
|
||||
/* DWORD 3 */
|
||||
u16 seq_num;
|
||||
u8 s_rate; /* Start rate. */
|
||||
u8 f_rate; /* Final rate. */
|
||||
|
||||
/* DWORD 4 */
|
||||
u8 s_rts_rate;
|
||||
u8 f_rts_rate;
|
||||
u16 pkt_length;
|
||||
|
||||
/* DWORD 5 */
|
||||
u16 reserve3;
|
||||
u16 duration;
|
||||
} cmpk_txfb_t;
|
||||
|
||||
/*
|
||||
* 2. RX side: Interrupt status packet.
|
||||
* It includes Beacon State, Beacon Timer Interrupt
|
||||
* and other useful informations in MAC ISR Reg.
|
||||
*/
|
||||
typedef struct tag_cmd_pkt_interrupt_status {
|
||||
u8 element_id; /* Command packet type. */
|
||||
u8 length; /* Command packet length. */
|
||||
u16 reserve;
|
||||
u32 interrupt_status; /* Interrupt Status. */
|
||||
} cmpk_intr_sta_t;
|
||||
|
||||
|
||||
/*
|
||||
* 3. TX side: Set configuration packet.
|
||||
*/
|
||||
typedef struct tag_cmd_pkt_set_configuration {
|
||||
u8 element_id; /* Command packet type. */
|
||||
u8 length; /* Command packet length. */
|
||||
u16 reserve1;
|
||||
u8 cfg_reserve1:3;
|
||||
u8 cfg_size:2; /* Configuration info. */
|
||||
u8 cfg_type:2; /* Configuration info. */
|
||||
u8 cfg_action:1; /* Configuration info. */
|
||||
u8 cfg_reserve2; /* Configuration info. */
|
||||
u8 cfg_page:4; /* Configuration info. */
|
||||
u8 cfg_reserve3:4; /* Configuration info. */
|
||||
u8 cfg_offset; /* Configuration info. */
|
||||
u32 value;
|
||||
u32 mask;
|
||||
} cmpk_set_cfg_t;
|
||||
|
||||
/*
|
||||
* 4. Both side : TX/RX query configuraton packet.
|
||||
* The query structure is the same as set configuration.
|
||||
*/
|
||||
#define cmpk_query_cfg_t cmpk_set_cfg_t
|
||||
|
||||
/*
|
||||
* 5. Multi packet feedback status.
|
||||
*/
|
||||
typedef struct tag_tx_stats_feedback {
|
||||
/*
|
||||
* For endian transfer
|
||||
* Driver will not the same as firmware structure.
|
||||
*/
|
||||
/* DW 0 */
|
||||
u16 reserve1;
|
||||
u8 length; /* Command packet length */
|
||||
u8 element_id; /* Command packet type */
|
||||
|
||||
/* DW 1 */
|
||||
u16 txfail; /* Tx Fail count */
|
||||
u16 txok; /* Tx ok count */
|
||||
|
||||
/* DW 2 */
|
||||
u16 txmcok; /* tx multicast */
|
||||
u16 txretry; /* Tx Retry count */
|
||||
|
||||
/* DW 3 */
|
||||
u16 txucok; /* tx unicast */
|
||||
u16 txbcok; /* tx broadcast */
|
||||
|
||||
/* DW 4 */
|
||||
u16 txbcfail;
|
||||
u16 txmcfail;
|
||||
|
||||
/* DW 5 */
|
||||
u16 reserve2;
|
||||
u16 txucfail;
|
||||
|
||||
/* DW 6-8 */
|
||||
u32 txmclength;
|
||||
u32 txbclength;
|
||||
u32 txuclength;
|
||||
|
||||
/* DW 9 */
|
||||
u16 reserve3_23;
|
||||
u8 reserve3_1;
|
||||
u8 rate;
|
||||
} __attribute__((packed)) cmpk_tx_status_t;
|
||||
|
||||
/*
|
||||
* 6. Debug feedback message.
|
||||
*/
|
||||
typedef struct tag_rx_debug_message_feedback {
|
||||
/* For endian transfer --> for driver */
|
||||
/* DW 0 */
|
||||
u16 reserve1;
|
||||
u8 length; /* Command packet length */
|
||||
u8 element_id; /* Command packet type */
|
||||
} cmpk_rx_dbginfo_t;
|
||||
|
||||
/*
|
||||
* Define transmit rate history. For big endian format.
|
||||
*/
|
||||
typedef struct tag_tx_rate_history {
|
||||
/* For endian transfer --> for driver */
|
||||
/* DW 0 */
|
||||
u8 element_id; /* Command packet type */
|
||||
u8 length; /* Command packet length */
|
||||
u16 reserved1;
|
||||
/* DW 1-2 CCK rate counter */
|
||||
u16 cck[4];
|
||||
/* DW 3-6 */
|
||||
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_TX_TSSI_MEAN_BACK = 8,
|
||||
RX_CMD_ELE_MAX
|
||||
} cmpk_element_e;
|
||||
|
||||
extern bool cmpk_message_handle_tx(struct net_device *dev,
|
||||
u8 *codevirtualaddress,
|
||||
u32 packettype,
|
||||
u32 buffer_len);
|
||||
|
||||
extern u32 cmpk_message_handle_rx(struct net_device *dev,
|
||||
struct ieee80211_rx_stats *pstats);
|
||||
|
||||
extern bool SendTxCommandPacket(struct net_device *dev,
|
||||
void *pData,
|
||||
u32 DataLen);
|
||||
|
||||
#endif
|
Загрузка…
Ссылка в новой задаче