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:
Greg Kroah-Hartman 2010-08-30 16:29:56 -07:00
Родитель 1407a9e105
Коммит 760ffce8ab
58 изменённых файлов: 0 добавлений и 47254 удалений

Просмотреть файл

@ -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