staging: rtl8192e: delete the driver

This driver is using lib80211 and any driver that plans to ever
leave staging should never have done that, so remove the driver
to enable cleaning up lib80211 into libipw inside the old Intel
drivers.

Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Link: https://patch.msgid.link/20241007202707.d0e59cdd2cdc.I8e4d74a6e1d09eefe1f5e2e208735ba2ccef1d4f@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Johannes Berg 2024-10-07 20:26:54 +02:00
parent 4fe9a5ec45
commit be9be9f54f
56 changed files with 0 additions and 24188 deletions

View File

@ -26,8 +26,6 @@ if STAGING
source "drivers/staging/olpc_dcon/Kconfig"
source "drivers/staging/rtl8192e/Kconfig"
source "drivers/staging/rtl8723bs/Kconfig"
source "drivers/staging/rtl8712/Kconfig"

View File

@ -3,7 +3,6 @@
obj-y += media/
obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon/
obj-$(CONFIG_RTL8192E) += rtl8192e/
obj-$(CONFIG_RTL8723BS) += rtl8723bs/
obj-$(CONFIG_R8712U) += rtl8712/
obj-$(CONFIG_RTS5208) += rts5208/

View File

@ -1,61 +0,0 @@
# SPDX-License-Identifier: GPL-2.0
config RTLLIB
tristate "Support for rtllib wireless devices"
depends on WLAN && m
select LIB80211
select CRC32
help
If you have a wireless card that uses rtllib, say
Y. Currently the only card is the rtl8192e.
If unsure, say N.
This driver adds support for rtllib wireless cards.
Only the rtl8192e is supported as of now.
if RTLLIB
config RTLLIB_CRYPTO_CCMP
tristate "Support for rtllib CCMP crypto"
depends on RTLLIB
select CRYPTO
select CRYPTO_AES
select CRYPTO_CCM
default y
help
CCMP crypto driver for rtllib.
If you enabled RTLLIB, you want this.
Adds support for the CCM mode Protocol crypto driver for
use in wireless cards (including rtllib cards).
config RTLLIB_CRYPTO_TKIP
tristate "Support for rtllib TKIP crypto"
depends on RTLLIB
select CRYPTO
select CRYPTO_LIB_ARC4
select CRYPTO_MICHAEL_MIC
default y
help
TKIP crypto driver for rtllib.
If you enabled RTLLIB, you want this.
Adds support for the Temporal Key Integrity Protocol for
the IEEE 802.11i standard for use on wireless cards.
config RTLLIB_CRYPTO_WEP
tristate "Support for rtllib WEP crypto"
select CRYPTO_LIB_ARC4
depends on RTLLIB
default y
help
WEP crypto driver for rtllib.
If you enabled RTLLIB, you want this.
Adds support for the (now weak) Wired Equivalent Privacy
(WEP) crypto protocol for wireless cards.
NOTE: This protocol is now considered insecure.
source "drivers/staging/rtl8192e/rtl8192e/Kconfig"
endif

View File

@ -1,19 +0,0 @@
# SPDX-License-Identifier: GPL-2.0
rtllib-objs := \
rtllib_module.o \
rtllib_rx.o \
rtllib_tx.o \
rtllib_wx.o \
rtllib_softmac.o \
rtllib_softmac_wx.o \
rtl819x_BAProc.o \
rtl819x_HTProc.o \
rtl819x_TSProc.o
obj-$(CONFIG_RTLLIB) += rtllib.o
obj-$(CONFIG_RTLLIB_CRYPTO_CCMP) += rtllib_crypt_ccmp.o
obj-$(CONFIG_RTLLIB_CRYPTO_TKIP) += rtllib_crypt_tkip.o
obj-$(CONFIG_RTLLIB_CRYPTO_WEP) += rtllib_crypt_wep.o
obj-$(CONFIG_RTL8192E) += rtl8192e/

View File

@ -1,18 +0,0 @@
To-do list:
* merge into drivers/net/wireless/realtek/rtlwifi/rtl8192*
* clean up function naming
* Correct the coding style according to Linux guidelines; please read the document
at https://www.kernel.org/doc/html/latest/process/coding-style.html.
* Remove unnecessary debugging/printing macros; for those that are still needed
use the proper kernel API (pr_debug(), dev_dbg(), netdev_dbg()).
* Remove dead code such as unusued functions, variables, fields, etc..
* Use in-kernel API and remove unnecessary wrappers where possible.
* Fix bugs due to code that sleeps in atomic context.
* Remove the HAL layer and migrate its functionality into the relevant parts of
the driver.
* Switch to use LIB80211.
* Switch to use MAC80211.
* Switch to use CFG80211.
* Improve the error handling of various functions, particularly those that use
existing kernel APIs.

View File

@ -1,10 +0,0 @@
# SPDX-License-Identifier: GPL-2.0
config RTL8192E
tristate "RealTek RTL8192E Wireless LAN NIC driver"
depends on PCI && WLAN && RTLLIB
depends on m
select CFG80211
select WIRELESS_EXT
select WEXT_PRIV
select CRYPTO
select FW_LOADER

View File

@ -1,19 +0,0 @@
# SPDX-License-Identifier: GPL-2.0
r8192e_pci-objs := \
r8192E_dev.o \
r8192E_phy.o \
r8192E_firmware.o \
r8192E_cmdpkt.o \
table.o \
r8190P_rtl8256.o \
rtl_cam.o \
rtl_core.o \
rtl_dm.o \
rtl_eeprom.o \
rtl_ethtool.o \
rtl_pci.o \
rtl_pm.o \
rtl_ps.o \
rtl_wx.o \
obj-$(CONFIG_RTL8192E) += r8192e_pci.o

View File

@ -1,265 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Contact Information: wlanfae <wlanfae@realtek.com>
*/
#ifndef R8190P_DEF_H
#define R8190P_DEF_H
#include <linux/types.h>
#define MAX_SILENT_RESET_RX_SLOT_NUM 10
enum rtl819x_loopback {
RTL819X_NO_LOOPBACK = 0,
RTL819X_MAC_LOOPBACK = 1,
RTL819X_DMA_LOOPBACK = 2,
RTL819X_CCK_LOOPBACK = 3,
};
#define DESC90_RATE1M 0x00
#define DESC90_RATE2M 0x01
#define DESC90_RATE5_5M 0x02
#define DESC90_RATE11M 0x03
#define DESC90_RATE6M 0x04
#define DESC90_RATE9M 0x05
#define DESC90_RATE12M 0x06
#define DESC90_RATE18M 0x07
#define DESC90_RATE24M 0x08
#define DESC90_RATE36M 0x09
#define DESC90_RATE48M 0x0a
#define DESC90_RATE54M 0x0b
#define DESC90_RATEMCS0 0x00
#define DESC90_RATEMCS1 0x01
#define DESC90_RATEMCS2 0x02
#define DESC90_RATEMCS3 0x03
#define DESC90_RATEMCS4 0x04
#define DESC90_RATEMCS5 0x05
#define DESC90_RATEMCS6 0x06
#define DESC90_RATEMCS7 0x07
#define DESC90_RATEMCS8 0x08
#define DESC90_RATEMCS9 0x09
#define DESC90_RATEMCS10 0x0a
#define DESC90_RATEMCS11 0x0b
#define DESC90_RATEMCS12 0x0c
#define DESC90_RATEMCS13 0x0d
#define DESC90_RATEMCS14 0x0e
#define DESC90_RATEMCS15 0x0f
#define DESC90_RATEMCS32 0x20
#define SHORT_SLOT_TIME 9
#define NON_SHORT_SLOT_TIME 20
#define RX_SMOOTH 20
#define QSLT_BK 0x1
#define QSLT_BE 0x0
#define QSLT_VI 0x4
#define QSLT_VO 0x6
#define QSLT_BEACON 0x10
#define QSLT_HIGH 0x11
#define QSLT_MGNT 0x12
#define QSLT_CMD 0x13
#define NUM_OF_PAGE_IN_FW_QUEUE_BK 0x007
#define NUM_OF_PAGE_IN_FW_QUEUE_BE 0x0aa
#define NUM_OF_PAGE_IN_FW_QUEUE_VI 0x024
#define NUM_OF_PAGE_IN_FW_QUEUE_VO 0x007
#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT 0x10
#define NUM_OF_PAGE_IN_FW_QUEUE_BCN 0x4
#define NUM_OF_PAGE_IN_FW_QUEUE_PUB 0xd
#define APPLIED_RESERVED_QUEUE_IN_FW 0x80000000
#define RSVD_FW_QUEUE_PAGE_BK_SHIFT 0x00
#define RSVD_FW_QUEUE_PAGE_BE_SHIFT 0x08
#define RSVD_FW_QUEUE_PAGE_VI_SHIFT 0x10
#define RSVD_FW_QUEUE_PAGE_VO_SHIFT 0x18
#define RSVD_FW_QUEUE_PAGE_MGNT_SHIFT 0x10
#define RSVD_FW_QUEUE_PAGE_BCN_SHIFT 0x00
#define RSVD_FW_QUEUE_PAGE_PUB_SHIFT 0x08
#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0
#define HAL_PRIME_CHNL_OFFSET_LOWER 1
#define HAL_PRIME_CHNL_OFFSET_UPPER 2
enum version_8190_loopback {
VERSION_8190_BD = 0x3,
VERSION_8190_BE
};
#define IC_VersionCut_D 0x3
enum rf_optype {
RF_OP_By_SW_3wire = 0,
RF_OP_By_FW,
RF_OP_MAX
};
struct bb_reg_definition {
u32 rfintfs;
u32 rfintfo;
u32 rfintfe;
u32 rf3wireOffset;
u32 rfHSSIPara2;
u32 rfLSSIReadBack;
u32 rfLSSIReadBackPi;
};
struct tx_fwinfo_8190pci {
u8 TxRate:7;
u8 CtsEnable:1;
u8 RtsRate:7;
u8 RtsEnable:1;
u8 TxHT:1;
u8 Short:1;
u8 TxBandwidth:1;
u8 TxSubCarrier:2;
u8 STBC:2;
u8 AllowAggregation:1;
u8 RtsHT:1;
u8 RtsShort:1;
u8 RtsBandwidth:1;
u8 RtsSubcarrier:2;
u8 RtsSTBC:2;
u8 EnableCPUDur:1;
u32 RxMF:2;
u32 RxAMD:3;
u32 TxPerPktInfoFeedback:1;
u32 Reserved1:2;
u32 TxAGCOffset:4;
u32 TxAGCSign:1;
u32 RAW_TXD:1;
u32 Retry_Limit:4;
u32 Reserved2:1;
u32 PacketID:13;
};
struct phy_sts_ofdm_819xpci {
u8 trsw_gain_X[4];
u8 pwdb_all;
u8 cfosho_X[4];
u8 cfotail_X[4];
u8 rxevm_X[2];
u8 rxsnr_X[4];
u8 pdsnr_X[2];
u8 csi_current_X[2];
u8 csi_target_X[2];
u8 sigevm;
u8 max_ex_pwr;
u8 sgi_en;
u8 rxsc_sgien_exflg;
};
struct phy_sts_cck_819xpci {
u8 adc_pwdb_X[4];
u8 sq_rpt;
u8 cck_agc_rpt;
};
#define PHY_RSSI_SLID_WIN_MAX 100
#define PHY_Beacon_RSSI_SLID_WIN_MAX 10
struct tx_desc {
u16 PktSize;
u8 Offset;
u8 Reserved1:3;
u8 CmdInit:1;
u8 LastSeg:1;
u8 FirstSeg:1;
u8 LINIP:1;
u8 OWN:1;
u8 TxFWInfoSize;
u8 RATid:3;
u8 DISFB:1;
u8 USERATE:1;
u8 MOREFRAG:1;
u8 NoEnc:1;
u8 PIFS:1;
u8 QueueSelect:5;
u8 NoACM:1;
u8 Resv:2;
u8 SecCAMID:5;
u8 SecDescAssign:1;
u8 SecType:2;
u16 TxBufferSize;
u8 PktId:7;
u8 Resv1:1;
u8 Reserved2;
u32 TxBuffAddr;
u32 NextDescAddress;
u32 Reserved5;
u32 Reserved6;
u32 Reserved7;
};
struct tx_desc_cmd {
u16 PktSize;
u8 Reserved1;
u8 CmdType:3;
u8 CmdInit:1;
u8 LastSeg:1;
u8 FirstSeg:1;
u8 LINIP:1;
u8 OWN:1;
u16 ElementReport;
u16 Reserved2;
u16 TxBufferSize;
u16 Reserved3;
u32 TxBuffAddr;
u32 NextDescAddress;
u32 Reserved4;
u32 Reserved5;
u32 Reserved6;
};
struct rx_desc {
u16 Length:14;
u16 CRC32:1;
u16 ICV:1;
u8 RxDrvInfoSize;
u8 Shift:2;
u8 PHYStatus:1;
u8 SWDec:1;
u8 LastSeg:1;
u8 FirstSeg:1;
u8 EOR:1;
u8 OWN:1;
u32 Reserved2;
u32 Reserved3;
u32 BufferAddress;
};
struct rx_fwinfo {
u16 Reserved1:12;
u16 PartAggr:1;
u16 FirstAGGR:1;
u16 Reserved2:2;
u8 RxRate:7;
u8 RxHT:1;
u8 BW:1;
u8 SPLCP:1;
u8 Reserved3:2;
u8 PAM:1;
u8 Mcast:1;
u8 Bcast:1;
u8 Reserved4:1;
u32 TSFL;
};
#endif

View File

@ -1,198 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Contact Information: wlanfae <wlanfae@realtek.com>
*/
#include "rtl_core.h"
#include "r8192E_phyreg.h"
#include "r8192E_phy.h"
#include "r8190P_rtl8256.h"
void rtl92e_set_bandwidth(struct net_device *dev,
enum ht_channel_width bandwidth)
{
u8 eRFPath;
struct r8192_priv *priv = rtllib_priv(dev);
if (priv->card_8192_version != VERSION_8190_BD &&
priv->card_8192_version != VERSION_8190_BE) {
netdev_warn(dev, "%s(): Unknown HW version.\n", __func__);
return;
}
for (eRFPath = 0; eRFPath < priv->num_total_rf_path; eRFPath++) {
switch (bandwidth) {
case HT_CHANNEL_WIDTH_20:
rtl92e_set_rf_reg(dev, (enum rf90_radio_path)eRFPath,
0x0b, bMask12Bits, 0x100);
rtl92e_set_rf_reg(dev, (enum rf90_radio_path)eRFPath,
0x2c, bMask12Bits, 0x3d7);
rtl92e_set_rf_reg(dev, (enum rf90_radio_path)eRFPath,
0x0e, bMask12Bits, 0x021);
break;
case HT_CHANNEL_WIDTH_20_40:
rtl92e_set_rf_reg(dev, (enum rf90_radio_path)eRFPath,
0x0b, bMask12Bits, 0x300);
rtl92e_set_rf_reg(dev, (enum rf90_radio_path)eRFPath,
0x2c, bMask12Bits, 0x3ff);
rtl92e_set_rf_reg(dev, (enum rf90_radio_path)eRFPath,
0x0e, bMask12Bits, 0x0e1);
break;
default:
netdev_err(dev, "%s(): Unknown bandwidth: %#X\n",
__func__, bandwidth);
break;
}
}
}
bool rtl92e_config_rf(struct net_device *dev)
{
u32 u4RegValue = 0;
u8 eRFPath;
bool rtStatus = true;
struct bb_reg_definition *pPhyReg;
struct r8192_priv *priv = rtllib_priv(dev);
u32 RegOffSetToBeCheck = 0x3;
u32 RegValueToBeCheck = 0x7f1;
u32 RF3_Final_Value = 0;
u8 ConstRetryTimes = 5, RetryTimes = 5;
u8 ret = 0;
priv->num_total_rf_path = RTL819X_TOTAL_RF_PATH;
for (eRFPath = (enum rf90_radio_path)RF90_PATH_A;
eRFPath < priv->num_total_rf_path; eRFPath++) {
pPhyReg = &priv->phy_reg_def[eRFPath];
switch (eRFPath) {
case RF90_PATH_A:
u4RegValue = rtl92e_get_bb_reg(dev, pPhyReg->rfintfs,
bRFSI_RFENV);
break;
case RF90_PATH_B:
u4RegValue = rtl92e_get_bb_reg(dev, pPhyReg->rfintfs,
bRFSI_RFENV << 16);
break;
}
rtl92e_set_bb_reg(dev, pPhyReg->rfintfe, bRFSI_RFENV << 16, 0x1);
rtl92e_set_bb_reg(dev, pPhyReg->rfintfo, bRFSI_RFENV, 0x1);
rtl92e_set_bb_reg(dev, pPhyReg->rfHSSIPara2,
b3WireAddressLength, 0x0);
rtl92e_set_bb_reg(dev, pPhyReg->rfHSSIPara2,
b3WireDataLength, 0x0);
rtl92e_set_rf_reg(dev, (enum rf90_radio_path)eRFPath, 0x0,
bMask12Bits, 0xbf);
rtStatus = rtl92e_check_bb_and_rf(dev, HW90_BLOCK_RF,
(enum rf90_radio_path)eRFPath);
if (!rtStatus) {
netdev_err(dev, "%s(): Failed to check RF Path %d.\n",
__func__, eRFPath);
goto fail;
}
RetryTimes = ConstRetryTimes;
RF3_Final_Value = 0;
while (RF3_Final_Value != RegValueToBeCheck &&
RetryTimes != 0) {
ret = rtl92e_config_rf_path(dev,
(enum rf90_radio_path)eRFPath);
RF3_Final_Value = rtl92e_get_rf_reg(dev,
(enum rf90_radio_path)eRFPath,
RegOffSetToBeCheck,
bMask12Bits);
RetryTimes--;
}
switch (eRFPath) {
case RF90_PATH_A:
rtl92e_set_bb_reg(dev, pPhyReg->rfintfs, bRFSI_RFENV,
u4RegValue);
break;
case RF90_PATH_B:
rtl92e_set_bb_reg(dev, pPhyReg->rfintfs,
bRFSI_RFENV << 16, u4RegValue);
break;
}
if (ret) {
netdev_err(dev,
"%s(): Failed to initialize RF Path %d.\n",
__func__, eRFPath);
goto fail;
}
}
return true;
fail:
return false;
}
void rtl92e_set_cck_tx_power(struct net_device *dev, u8 powerlevel)
{
u32 TxAGC = 0;
struct r8192_priv *priv = rtllib_priv(dev);
TxAGC = powerlevel;
if (priv->dynamic_tx_low_pwr) {
if (priv->customer_id == RT_CID_819X_NETCORE)
TxAGC = 0x22;
else
TxAGC += priv->cck_pwr_enl;
}
if (TxAGC > 0x24)
TxAGC = 0x24;
rtl92e_set_bb_reg(dev, rTxAGC_CCK_Mcs32, bTxAGCRateCCK, TxAGC);
}
void rtl92e_set_ofdm_tx_power(struct net_device *dev, u8 powerlevel)
{
struct r8192_priv *priv = rtllib_priv(dev);
u32 writeVal, powerBase0, powerBase1, writeVal_tmp;
u8 index = 0;
u16 RegOffset[6] = {0xe00, 0xe04, 0xe10, 0xe14, 0xe18, 0xe1c};
u8 byte0, byte1, byte2, byte3;
powerBase0 = powerlevel + priv->legacy_ht_tx_pwr_diff;
powerBase0 = (powerBase0 << 24) | (powerBase0 << 16) |
(powerBase0 << 8) | powerBase0;
powerBase1 = powerlevel;
powerBase1 = (powerBase1 << 24) | (powerBase1 << 16) |
(powerBase1 << 8) | powerBase1;
for (index = 0; index < 6; index++) {
writeVal = (u32)(priv->mcs_tx_pwr_level_org_offset[index] +
((index < 2) ? powerBase0 : powerBase1));
byte0 = writeVal & 0x7f;
byte1 = (writeVal & 0x7f00) >> 8;
byte2 = (writeVal & 0x7f0000) >> 16;
byte3 = (writeVal & 0x7f000000) >> 24;
if (byte0 > 0x24)
byte0 = 0x24;
if (byte1 > 0x24)
byte1 = 0x24;
if (byte2 > 0x24)
byte2 = 0x24;
if (byte3 > 0x24)
byte3 = 0x24;
if (index == 3) {
writeVal_tmp = (byte3 << 24) | (byte2 << 16) |
(byte1 << 8) | byte0;
priv->pwr_track = writeVal_tmp;
}
if (priv->dynamic_tx_high_pwr)
writeVal = 0x03030303;
else
writeVal = (byte3 << 24) | (byte2 << 16) |
(byte1 << 8) | byte0;
rtl92e_set_bb_reg(dev, RegOffset[index], 0x7f7f7f7f, writeVal);
}
}

View File

@ -1,17 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Contact Information: wlanfae <wlanfae@realtek.com>
*/
#ifndef RTL8225H
#define RTL8225H
#define RTL819X_TOTAL_RF_PATH 2
void rtl92e_set_bandwidth(struct net_device *dev,
enum ht_channel_width bandwidth);
bool rtl92e_config_rf(struct net_device *dev);
void rtl92e_set_cck_tx_power(struct net_device *dev, u8 powerlevel);
void rtl92e_set_ofdm_tx_power(struct net_device *dev, u8 powerlevel);
#endif

View File

@ -1,79 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Contact Information: wlanfae <wlanfae@realtek.com>
*/
#include "rtl_core.h"
#include "r8192E_hw.h"
#include "r8192E_cmdpkt.h"
bool rtl92e_send_cmd_pkt(struct net_device *dev, u32 type, const void *data,
u32 len)
{
struct r8192_priv *priv = rtllib_priv(dev);
u16 frag_length = 0, frag_offset = 0;
struct sk_buff *skb;
unsigned char *seg_ptr;
struct cb_desc *tcb_desc;
u8 bLastIniPkt;
struct tx_fwinfo_8190pci *pTxFwInfo = NULL;
do {
if ((len - frag_offset) > CMDPACKET_FRAG_SIZE) {
frag_length = CMDPACKET_FRAG_SIZE;
bLastIniPkt = 0;
} else {
frag_length = (u16)(len - frag_offset);
bLastIniPkt = 1;
}
if (type == DESC_PACKET_TYPE_NORMAL)
skb = dev_alloc_skb(frag_length +
priv->rtllib->tx_headroom + 4);
else
skb = dev_alloc_skb(frag_length + 4);
if (!skb)
return false;
memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev));
tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
tcb_desc->queue_index = TXCMD_QUEUE;
tcb_desc->bCmdOrInit = type;
tcb_desc->bLastIniPkt = bLastIniPkt;
if (type == DESC_PACKET_TYPE_NORMAL) {
tcb_desc->pkt_size = frag_length;
seg_ptr = skb_put(skb, priv->rtllib->tx_headroom);
pTxFwInfo = (struct tx_fwinfo_8190pci *)seg_ptr;
memset(pTxFwInfo, 0, sizeof(struct tx_fwinfo_8190pci));
memset(pTxFwInfo, 0x12, 8);
} else {
tcb_desc->txbuf_size = frag_length;
}
skb_put_data(skb, data, frag_length);
if (type == DESC_PACKET_TYPE_INIT &&
(!priv->rtllib->check_nic_enough_desc(dev, TXCMD_QUEUE) ||
(!skb_queue_empty(&priv->rtllib->skb_waitq[TXCMD_QUEUE])) ||
(priv->rtllib->queue_stop))) {
skb_queue_tail(&priv->rtllib->skb_waitq[TXCMD_QUEUE],
skb);
} else {
priv->rtllib->softmac_hard_start_xmit(skb, dev);
}
data += frag_length;
frag_offset += frag_length;
} while (frag_offset < len);
rtl92e_writeb(dev, TP_POLL, TP_POLL_CQ);
return true;
}

View File

@ -1,12 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Contact Information: wlanfae <wlanfae@realtek.com>
*/
#ifndef R819XUSB_CMDPKT_H
#define R819XUSB_CMDPKT_H
bool rtl92e_send_cmd_pkt(struct net_device *dev, u32 type, const void *data,
u32 len);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,34 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Contact Information: wlanfae <wlanfae@realtek.com>
*/
#ifndef _RTL8192E_H
#define _RTL8192E_H
#include "r8190P_def.h"
bool rtl92e_is_halfn_supported_by_ap(struct net_device *dev);
bool rtl92e_get_nmode_support_by_sec(struct net_device *dev);
bool rtl92e_is_tx_stuck(struct net_device *dev);
bool rtl92e_is_rx_stuck(struct net_device *dev);
void rtl92e_ack_irq(struct net_device *dev, u32 *p_inta);
void rtl92e_enable_rx(struct net_device *dev);
void rtl92e_enable_tx(struct net_device *dev);
void rtl92e_init_variables(struct net_device *dev);
void rtl92e_set_reg(struct net_device *dev, u8 variable, u8 *val);
void rtl92e_get_eeprom_size(struct net_device *dev);
bool rtl92e_start_adapter(struct net_device *dev);
void rtl92e_link_change(struct net_device *dev);
void rtl92e_set_monitor_mode(struct net_device *dev, bool allow_all_da,
bool write_into_reg);
void rtl92e_fill_tx_desc(struct net_device *dev, struct tx_desc *pdesc,
struct cb_desc *cb_desc, struct sk_buff *skb);
void rtl92e_fill_tx_cmd_desc(struct net_device *dev, struct tx_desc_cmd *entry,
struct cb_desc *cb_desc, struct sk_buff *skb);
bool rtl92e_get_rx_stats(struct net_device *dev, struct rtllib_rx_stats *stats,
struct rx_desc *pdesc, struct sk_buff *skb);
void rtl92e_stop_adapter(struct net_device *dev, bool reset);
void rtl92e_update_ratr_table(struct net_device *dev);
#endif

View File

@ -1,189 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Contact Information: wlanfae <wlanfae@realtek.com>
*/
#include "rtl_core.h"
#include "r8192E_hw.h"
#include "table.h"
#include "r8192E_firmware.h"
#include "r8192E_cmdpkt.h"
#include <linux/firmware.h>
static bool _rtl92e_wait_for_fw(struct net_device *dev, u32 mask, u32 timeout)
{
unsigned long deadline = jiffies + msecs_to_jiffies(timeout);
while (time_before(jiffies, deadline)) {
if (rtl92e_readl(dev, CPU_GEN) & mask)
return true;
mdelay(2);
}
return false;
}
static bool _rtl92e_fw_boot_cpu(struct net_device *dev)
{
u32 CPU_status = 0;
if (!_rtl92e_wait_for_fw(dev, CPU_GEN_PUT_CODE_OK, 200)) {
netdev_err(dev, "Firmware download failed.\n");
return false;
}
netdev_dbg(dev, "Download Firmware: Put code ok!\n");
CPU_status = rtl92e_readl(dev, CPU_GEN);
rtl92e_writeb(dev, CPU_GEN, (CPU_status | CPU_GEN_PWR_STB_CPU) & 0xff);
mdelay(1);
if (!_rtl92e_wait_for_fw(dev, CPU_GEN_BOOT_RDY, 200)) {
netdev_err(dev, "Firmware boot failed.\n");
return false;
}
netdev_dbg(dev, "Download Firmware: Boot ready!\n");
return true;
}
static bool _rtl92e_fw_check_ready(struct net_device *dev,
u8 load_fw_status)
{
struct r8192_priv *priv = rtllib_priv(dev);
struct rt_firmware *pfirmware = priv->fw_info;
bool rt_status = true;
switch (load_fw_status) {
case FW_INIT_STEP0_BOOT:
pfirmware->status = FW_STATUS_1_MOVE_BOOT_CODE;
break;
case FW_INIT_STEP1_MAIN:
pfirmware->status = FW_STATUS_2_MOVE_MAIN_CODE;
rt_status = _rtl92e_fw_boot_cpu(dev);
if (rt_status)
pfirmware->status = FW_STATUS_3_TURNON_CPU;
else
netdev_dbg(dev, "_rtl92e_fw_boot_cpu fail!\n");
break;
case FW_INIT_STEP2_DATA:
pfirmware->status = FW_STATUS_4_MOVE_DATA_CODE;
mdelay(1);
rt_status = _rtl92e_wait_for_fw(dev, CPU_GEN_FIRM_RDY, 20);
if (rt_status)
pfirmware->status = FW_STATUS_5_READY;
break;
default:
rt_status = false;
netdev_dbg(dev, "Unknown firmware status");
break;
}
return rt_status;
}
static bool _rtl92e_fw_prepare(struct net_device *dev, struct rt_fw_blob *blob,
const char *name, u8 padding)
{
const struct firmware *fw;
int rc, i;
bool ret = true;
rc = request_firmware(&fw, name, &dev->dev);
if (rc < 0)
return false;
if (round_up(fw->size, 4) > MAX_FW_SIZE - padding) {
netdev_err(dev, "Firmware image %s too big for the device.\n",
name);
ret = false;
goto out;
}
if (padding)
memset(blob->data, 0, padding);
if (fw->size % 4)
memset(blob->data + padding + fw->size, 0, 4);
memcpy(blob->data + padding, fw->data, fw->size);
blob->size = round_up(fw->size, 4) + padding;
/* Swap endian - firmware is packaged in invalid endiannes*/
for (i = padding; i < blob->size; i += 4) {
u32 *data = (u32 *)(blob->data + i);
*data = swab32p(data);
}
out:
release_firmware(fw);
return ret;
}
bool rtl92e_init_fw(struct net_device *dev)
{
struct r8192_priv *priv = rtllib_priv(dev);
bool rt_status = true;
u32 file_length = 0;
u8 *mapped_file = NULL;
u8 i = 0;
enum opt_rst_type rst_opt = OPT_SYSTEM_RESET;
enum firmware_init_step starting_state = FW_INIT_STEP0_BOOT;
struct rt_firmware *pfirmware = priv->fw_info;
netdev_dbg(dev, " PlatformInitFirmware()==>\n");
if (pfirmware->status == FW_STATUS_0_INIT) {
rst_opt = OPT_SYSTEM_RESET;
starting_state = FW_INIT_STEP0_BOOT;
} else if (pfirmware->status == FW_STATUS_5_READY) {
rst_opt = OPT_FIRMWARE_RESET;
starting_state = FW_INIT_STEP2_DATA;
}
for (i = starting_state; i <= FW_INIT_STEP2_DATA; i++) {
if (rst_opt == OPT_SYSTEM_RESET) {
if (pfirmware->blobs[i].size == 0) {
const char *fw_name[3] = {
RTL8192E_BOOT_IMG_FW,
RTL8192E_MAIN_IMG_FW,
RTL8192E_DATA_IMG_FW
};
int pad = 0;
if (i == FW_INIT_STEP1_MAIN)
pad = 128;
if (!_rtl92e_fw_prepare(dev,
&pfirmware->blobs[i],
fw_name[i],
pad))
goto download_firmware_fail;
}
}
mapped_file = pfirmware->blobs[i].data;
file_length = pfirmware->blobs[i].size;
rt_status = rtl92e_send_cmd_pkt(dev, DESC_PACKET_TYPE_INIT,
mapped_file, file_length);
if (!rt_status)
goto download_firmware_fail;
if (!_rtl92e_fw_check_ready(dev, i))
goto download_firmware_fail;
}
netdev_dbg(dev, "Firmware Download Success\n");
return rt_status;
download_firmware_fail:
netdev_err(dev, "%s: Failed to initialize firmware.\n", __func__);
return false;
}

View File

@ -1,52 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Contact Information: wlanfae <wlanfae@realtek.com>
*/
#ifndef __INC_FIRMWARE_H
#define __INC_FIRMWARE_H
#define RTL8192E_BOOT_IMG_FW "RTL8192E/boot.img"
#define RTL8192E_MAIN_IMG_FW "RTL8192E/main.img"
#define RTL8192E_DATA_IMG_FW "RTL8192E/data.img"
enum firmware_init_step {
FW_INIT_STEP0_BOOT = 0,
FW_INIT_STEP1_MAIN = 1,
FW_INIT_STEP2_DATA = 2,
};
enum opt_rst_type {
OPT_SYSTEM_RESET = 0,
OPT_FIRMWARE_RESET = 1,
};
enum desc_packet_type {
DESC_PACKET_TYPE_INIT = 0,
DESC_PACKET_TYPE_NORMAL = 1,
};
enum firmware_status {
FW_STATUS_0_INIT = 0,
FW_STATUS_1_MOVE_BOOT_CODE = 1,
FW_STATUS_2_MOVE_MAIN_CODE = 2,
FW_STATUS_3_TURNON_CPU = 3,
FW_STATUS_4_MOVE_DATA_CODE = 4,
FW_STATUS_5_READY = 5,
};
#define MAX_FW_SIZE 64000
struct rt_fw_blob {
u16 size;
u8 data[MAX_FW_SIZE];
};
#define FW_BLOBS 3
struct rt_firmware {
enum firmware_status status;
struct rt_fw_blob blobs[FW_BLOBS];
};
bool rtl92e_init_fw(struct net_device *dev);
#endif

View File

@ -1,244 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Contact Information: wlanfae <wlanfae@realtek.com>
*/
#ifndef R8180_HW
#define R8180_HW
enum baseband_config {
BB_CONFIG_PHY_REG = 0,
BB_CONFIG_AGC_TAB = 1,
};
#define RTL8190_EEPROM_ID 0x8129
#define EEPROM_VID 0x02
#define EEPROM_DID 0x04
#define EEPROM_NODE_ADDRESS_BYTE_0 0x0C
#define EEPROM_Default_ThermalMeter 0x77
#define EEPROM_Default_AntTxPowerDiff 0x0
#define EEPROM_Default_TxPwDiff_CrystalCap 0x5
#define EEPROM_Default_TxPower 0x1010
#define EEPROM_ICVersion_ChannelPlan 0x7C
#define EEPROM_Customer_ID 0x7B
#define EEPROM_RFInd_PowerDiff 0x28
#define EEPROM_ThermalMeter 0x29
#define EEPROM_TxPwDiff_CrystalCap 0x2A
#define EEPROM_TxPwIndex_CCK 0x2C
#define EEPROM_TxPwIndex_OFDM_24G 0x3A
#define EEPROM_CID_TOSHIBA 0x4
#define EEPROM_CID_NetCore 0x5
enum _RTL8192PCI_HW {
MAC0 = 0x000,
MAC4 = 0x004,
PCIF = 0x009,
#define MXDMA2_NO_LIMIT 0x7
#define MXDMA2_RX_SHIFT 4
#define MXDMA2_TX_SHIFT 0
PMR = 0x00c,
EPROM_CMD = 0x00e,
#define EPROM_CMD_9356SEL BIT(4)
#define EPROM_CMD_OPERATING_MODE_SHIFT 6
#define EPROM_CMD_NORMAL 0
#define EPROM_CMD_PROGRAM 2
#define EPROM_CS_BIT 3
#define EPROM_CK_BIT 2
#define EPROM_W_BIT 1
#define EPROM_R_BIT 0
ANAPAR = 0x17,
#define BB_GLOBAL_RESET_BIT 0x1
BB_GLOBAL_RESET = 0x020,
BSSIDR = 0x02E,
CMDR = 0x037,
#define CR_RE 0x08
#define CR_TE 0x04
SIFS = 0x03E,
RCR = 0x044,
#define RCR_ONLYERLPKT BIT(31)
#define RCR_CBSSID BIT(23)
#define RCR_ADD3 BIT(21)
#define RCR_AMF BIT(20)
#define RCR_ADF BIT(18)
#define RCR_AICV BIT(12)
#define RCR_AB BIT(3)
#define RCR_AM BIT(2)
#define RCR_APM BIT(1)
#define RCR_AAP BIT(0)
#define RCR_MXDMA_OFFSET 8
#define RCR_FIFO_OFFSET 13
SLOT_TIME = 0x049,
ACK_TIMEOUT = 0x04c,
EDCAPARA_BE = 0x050,
EDCAPARA_BK = 0x054,
EDCAPARA_VO = 0x058,
EDCAPARA_VI = 0x05C,
#define AC_PARAM_TXOP_LIMIT_OFFSET 16
#define AC_PARAM_ECW_MAX_OFFSET 12
#define AC_PARAM_ECW_MIN_OFFSET 8
#define AC_PARAM_AIFS_OFFSET 0
BCN_TCFG = 0x062,
#define BCN_TCFG_CW_SHIFT 8
#define BCN_TCFG_IFS 0
BCN_INTERVAL = 0x070,
ATIMWND = 0x072,
BCN_DRV_EARLY_INT = 0x074,
BCN_DMATIME = 0x076,
BCN_ERR_THRESH = 0x078,
RWCAM = 0x0A0,
#define TOTAL_CAM_ENTRY 32
WCAMI = 0x0A4,
SECR = 0x0B0,
#define SCR_TxUseDK BIT(0)
#define SCR_RxUseDK BIT(1)
#define SCR_TxEncEnable BIT(2)
#define SCR_RxDecEnable BIT(3)
#define SCR_NoSKMC BIT(5)
SWREGULATOR = 0x0BD,
INTA_MASK = 0x0f4,
#define IMR_TBDOK BIT(27)
#define IMR_TBDER BIT(26)
#define IMR_TXFOVW BIT(15)
#define IMR_TIMEOUT0 BIT(14)
#define IMR_BcnInt BIT(13)
#define IMR_RXFOVW BIT(12)
#define IMR_RDU BIT(11)
#define IMR_RXCMDOK BIT(10)
#define IMR_BDOK BIT(9)
#define IMR_HIGHDOK BIT(8)
#define IMR_COMDOK BIT(7)
#define IMR_MGNTDOK BIT(6)
#define IMR_HCCADOK BIT(5)
#define IMR_BKDOK BIT(4)
#define IMR_BEDOK BIT(3)
#define IMR_VIDOK BIT(2)
#define IMR_VODOK BIT(1)
#define IMR_ROK BIT(0)
ISR = 0x0f8,
TP_POLL = 0x0fd,
#define TP_POLL_CQ BIT(5)
PSR = 0x0ff,
CPU_GEN = 0x100,
#define CPU_CCK_LOOPBACK 0x00030000
#define CPU_GEN_SYSTEM_RESET 0x00000001
#define CPU_GEN_FIRMWARE_RESET 0x00000008
#define CPU_GEN_BOOT_RDY 0x00000010
#define CPU_GEN_FIRM_RDY 0x00000020
#define CPU_GEN_PUT_CODE_OK 0x00000080
#define CPU_GEN_BB_RST 0x00000100
#define CPU_GEN_PWR_STB_CPU 0x00000004
#define CPU_GEN_NO_LOOPBACK_MSK 0xFFF8FFFF
#define CPU_GEN_NO_LOOPBACK_SET 0x00080000
ACM_HW_CTRL = 0x171,
#define ACM_HW_BEQ_EN BIT(1)
#define ACM_HW_VIQ_EN BIT(2)
#define ACM_HW_VOQ_EN BIT(3)
RQPN1 = 0x180,
RQPN2 = 0x184,
RQPN3 = 0x188,
QPNR = 0x1F0,
BQDA = 0x200,
HQDA = 0x204,
CQDA = 0x208,
MQDA = 0x20C,
HCCAQDA = 0x210,
VOQDA = 0x214,
VIQDA = 0x218,
BEQDA = 0x21C,
BKQDA = 0x220,
RDQDA = 0x228,
WFCRC0 = 0x2f0,
WFCRC1 = 0x2f4,
WFCRC2 = 0x2f8,
BW_OPMODE = 0x300,
#define BW_OPMODE_20MHZ BIT(2)
IC_VERRSION = 0x301,
MSR = 0x303,
#define MSR_LINK_MASK (BIT(1) | BIT(0))
#define MSR_LINK_MANAGED 2
#define MSR_LINK_ADHOC 1
#define MSR_LINK_MASTER 3
#define MSR_NOLINK 0x00
#define MSR_ADHOC 0x01
#define MSR_INFRA 0x02
#define MSR_AP 0x03
RETRY_LIMIT = 0x304,
#define RETRY_LIMIT_SHORT_SHIFT 8
#define RETRY_LIMIT_LONG_SHIFT 0
TSFR = 0x308,
RRSR = 0x310,
#define RRSR_SHORT_OFFSET 23
#define RRSR_1M BIT(0)
#define RRSR_2M BIT(1)
#define RRSR_5_5M BIT(2)
#define RRSR_11M BIT(3)
#define RRSR_6M BIT(4)
#define RRSR_9M BIT(5)
#define RRSR_12M BIT(6)
#define RRSR_18M BIT(7)
#define RRSR_24M BIT(8)
#define RRSR_36M BIT(9)
#define RRSR_48M BIT(10)
#define RRSR_54M BIT(11)
#define BRSR_AckShortPmb BIT(23)
UFWP = 0x318,
RATR0 = 0x320,
#define RATR_1M 0x00000001
#define RATR_2M 0x00000002
#define RATR_55M 0x00000004
#define RATR_11M 0x00000008
#define RATR_6M 0x00000010
#define RATR_9M 0x00000020
#define RATR_12M 0x00000040
#define RATR_18M 0x00000080
#define RATR_24M 0x00000100
#define RATR_36M 0x00000200
#define RATR_48M 0x00000400
#define RATR_54M 0x00000800
#define RATR_MCS0 0x00001000
#define RATR_MCS1 0x00002000
#define RATR_MCS2 0x00004000
#define RATR_MCS3 0x00008000
#define RATR_MCS4 0x00010000
#define RATR_MCS5 0x00020000
#define RATR_MCS6 0x00040000
#define RATR_MCS7 0x00080000
#define RATR_MCS8 0x00100000
#define RATR_MCS9 0x00200000
#define RATR_MCS10 0x00400000
#define RATR_MCS11 0x00800000
#define RATR_MCS12 0x01000000
#define RATR_MCS13 0x02000000
#define RATR_MCS14 0x04000000
#define RATR_MCS15 0x08000000
#define RATE_ALL_CCK (RATR_1M | RATR_2M | RATR_55M | RATR_11M)
#define RATE_ALL_OFDM_AG (RATR_6M | RATR_9M | RATR_12M | RATR_18M | \
RATR_24M | RATR_36M | RATR_48M | RATR_54M)
#define RATE_ALL_OFDM_1SS (RATR_MCS0 | RATR_MCS1 | RATR_MCS2 | \
RATR_MCS3 | RATR_MCS4 | RATR_MCS5 | \
RATR_MCS6 | RATR_MCS7)
#define RATE_ALL_OFDM_2SS (RATR_MCS8 | RATR_MCS9 | RATR_MCS10 | \
RATR_MCS11 | RATR_MCS12 | RATR_MCS13 | \
RATR_MCS14|RATR_MCS15)
DRIVER_RSSI = 0x32c,
MCS_TXAGC = 0x340,
CCK_TXAGC = 0x348,
MAC_BLK_CTRL = 0x403,
};
#define GPI 0x108
#define ANAPAR_FOR_8192PCIE 0x17
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,57 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Contact Information: wlanfae <wlanfae@realtek.com>
*/
#ifndef _R819XU_PHY_H
#define _R819XU_PHY_H
#define MAX_DOZE_WAITING_TIMES_9x 64
enum hw90_block {
HW90_BLOCK_MAC = 0,
HW90_BLOCK_PHY0 = 1,
HW90_BLOCK_PHY1 = 2,
HW90_BLOCK_RF = 3,
HW90_BLOCK_MAXIMUM = 4,
};
enum rf90_radio_path {
RF90_PATH_A = 0,
RF90_PATH_B = 1,
RF90_PATH_C = 2,
RF90_PATH_D = 3,
RF90_PATH_MAX
};
void rtl92e_set_bb_reg(struct net_device *dev, u32 dwRegAddr,
u32 dwBitMask, u32 dwData);
u32 rtl92e_get_bb_reg(struct net_device *dev, u32 dwRegAddr, u32 dwBitMask);
void rtl92e_set_rf_reg(struct net_device *dev, enum rf90_radio_path eRFPath,
u32 RegAddr, u32 BitMask, u32 Data);
u32 rtl92e_get_rf_reg(struct net_device *dev, enum rf90_radio_path eRFPath,
u32 RegAddr, u32 BitMask);
void rtl92e_config_mac(struct net_device *dev);
bool rtl92e_check_bb_and_rf(struct net_device *dev,
enum hw90_block CheckBlock,
enum rf90_radio_path eRFPath);
bool rtl92e_config_bb(struct net_device *dev);
void rtl92e_get_tx_power(struct net_device *dev);
void rtl92e_set_tx_power(struct net_device *dev, u8 channel);
u8 rtl92e_config_rf_path(struct net_device *dev, enum rf90_radio_path eRFPath);
void rtl92e_set_channel(struct net_device *dev, u8 channel);
void rtl92e_set_bw_mode(struct net_device *dev,
enum ht_channel_width bandwidth,
enum ht_extchnl_offset Offset);
void rtl92e_init_gain(struct net_device *dev, u8 Operation);
void rtl92e_set_rf_off(struct net_device *dev);
bool rtl92e_set_rf_power_state(struct net_device *dev,
enum rt_rf_power_state rf_power_state);
void rtl92e_scan_op_backup(struct net_device *dev, u8 Operation);
#endif

View File

@ -1,773 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Contact Information: wlanfae <wlanfae@realtek.com>
*/
#ifndef _R819XU_PHYREG_H
#define _R819XU_PHYREG_H
#define RF_DATA 0x1d4
#define rPMAC_Reset 0x100
#define rPMAC_TxStart 0x104
#define rPMAC_TxLegacySIG 0x108
#define rPMAC_TxHTSIG1 0x10c
#define rPMAC_TxHTSIG2 0x110
#define rPMAC_PHYDebug 0x114
#define rPMAC_TxPacketNum 0x118
#define rPMAC_TxIdle 0x11c
#define rPMAC_TxMACHeader0 0x120
#define rPMAC_TxMACHeader1 0x124
#define rPMAC_TxMACHeader2 0x128
#define rPMAC_TxMACHeader3 0x12c
#define rPMAC_TxMACHeader4 0x130
#define rPMAC_TxMACHeader5 0x134
#define rPMAC_TxDataType 0x138
#define rPMAC_TxRandomSeed 0x13c
#define rPMAC_CCKPLCPPreamble 0x140
#define rPMAC_CCKPLCPHeader 0x144
#define rPMAC_CCKCRC16 0x148
#define rPMAC_OFDMRxCRC32OK 0x170
#define rPMAC_OFDMRxCRC32Er 0x174
#define rPMAC_OFDMRxParityEr 0x178
#define rPMAC_OFDMRxCRC8Er 0x17c
#define rPMAC_CCKCRxRC16Er 0x180
#define rPMAC_CCKCRxRC32Er 0x184
#define rPMAC_CCKCRxRC32OK 0x188
#define rPMAC_TxStatus 0x18c
#define MCS_TXAGC 0x340
#define CCK_TXAGC 0x348
/* Mac block on/off control register */
#define rFPGA0_RFMOD 0x800 /* RF mode & CCK TxSC */
#define rFPGA0_TxInfo 0x804
#define rFPGA0_PSDFunction 0x808
#define rFPGA0_TxGainStage 0x80c
#define rFPGA0_RFTiming1 0x810
#define rFPGA0_RFTiming2 0x814
#define rFPGA0_XA_HSSIParameter2 0x824
#define rFPGA0_XB_HSSIParameter2 0x82c
#define rFPGA0_XA_LSSIParameter 0x840
#define rFPGA0_XB_LSSIParameter 0x844
#define rFPGA0_RFWakeUpParameter 0x850
#define rFPGA0_RFSleepUpParameter 0x854
#define rFPGA0_XA_RFInterfaceOE 0x860
#define rFPGA0_XB_RFInterfaceOE 0x864
#define rFPGA0_XAB_RFInterfaceSW 0x870
#define rFPGA0_AnalogParameter1 0x880
#define rFPGA0_AnalogParameter2 0x884
#define rFPGA0_AnalogParameter3 0x888
#define rFPGA0_AnalogParameter4 0x88c
#define rFPGA0_XA_LSSIReadBack 0x8a0
#define rFPGA0_XB_LSSIReadBack 0x8a4
#define rFPGA0_PSDReport 0x8b4
/* Page 9 - RF mode & OFDM TxSC */
#define rFPGA1_RFMOD 0x900
#define rFPGA1_TxBlock 0x904
#define rFPGA1_DebugSelect 0x908
#define rFPGA1_TxInfo 0x90c
#define rCCK0_System 0xa00
#define rCCK0_AFESetting 0xa04
#define rCCK0_CCA 0xa08
/* AGC default value, saturation level */
#define rCCK0_RxAGC1 0xa0c
#define rCCK0_RxAGC2 0xa10 /* AGC & DAGC */
#define rCCK0_RxHP 0xa14
/* Timing recovery & channel estimation threshold */
#define rCCK0_DSPParameter1 0xa18
#define rCCK0_DSPParameter2 0xa1c /* SQ threshold */
#define rCCK0_TxFilter1 0xa20
#define rCCK0_TxFilter2 0xa24
#define rCCK0_DebugPort 0xa28 /* Debug port and TX filter 3 */
#define rCCK0_FalseAlarmReport 0xa2c
#define rCCK0_TRSSIReport 0xa50
#define rCCK0_RxReport 0xa54
#define rCCK0_FACounterLower 0xa5c
#define rCCK0_FACounterUpper 0xa58
#define rOFDM0_LSTF 0xc00
#define rOFDM0_TRxPathEnable 0xc04
#define rOFDM0_TRMuxPar 0xc08
#define rOFDM0_TRSWIsolation 0xc0c
#define rOFDM0_RxDetector1 0xc30 /* PD, BW & SBD */
#define rOFDM0_RxDetector2 0xc34 /* SBD */
#define rOFDM0_RxDetector3 0xc38 /* Frame Sync */
/* PD, SBD, Frame Sync & Short-GI */
#define rOFDM0_RxDetector4 0xc3c
#define rOFDM0_RxDSP 0xc40 /* Rx Sync Path */
#define rOFDM0_CFOandDAGC 0xc44 /* CFO & DAGC */
#define rOFDM0_CCADropThreshold 0xc48
#define rOFDM0_ECCAThreshold 0xc4c /* Energy CCA */
#define rOFDM0_XAAGCCore1 0xc50
#define rOFDM0_XBAGCCore1 0xc58
#define rOFDM0_XCAGCCore1 0xc60
#define rOFDM0_XDAGCCore1 0xc68
#define rOFDM0_AGCParameter1 0xc70
#define rOFDM0_AGCParameter2 0xc74
#define rOFDM0_AGCRSSITable 0xc78
#define rOFDM0_HTSTFAGC 0xc7c
#define rOFDM0_XATxIQImbalance 0xc80
#define rOFDM0_XATxAFE 0xc84
#define rOFDM0_XCTxIQImbalance 0xc90
#define rOFDM0_RxHPParameter 0xce0
#define rOFDM0_TxPseudoNoiseWgt 0xce4
#define rOFDM0_FrameSync 0xcf0
#define rOFDM0_DFSReport 0xcf4
#define rOFDM0_TxCoeff1 0xca4
#define rOFDM0_TxCoeff2 0xca8
#define rOFDM0_TxCoeff3 0xcac
#define rOFDM0_TxCoeff4 0xcb0
#define rOFDM0_TxCoeff5 0xcb4
#define rOFDM0_TxCoeff6 0xcb8
#define rOFDM1_LSTF 0xd00
#define rOFDM1_TRxPathEnable 0xd04
#define rOFDM1_CFO 0xd08
#define rOFDM1_CSI1 0xd10
#define rOFDM1_SBD 0xd14
#define rOFDM1_CSI2 0xd18
#define rOFDM1_CFOTracking 0xd2c
#define rOFDM1_TRxMesaure1 0xd34
#define rOFDM1_IntfDet 0xd3c
#define rOFDM1_PseudoNoiseStateAB 0xd50
#define rOFDM1_PseudoNoiseStateCD 0xd54
#define rOFDM1_RxPseudoNoiseWgt 0xd58
#define rOFDM_PHYCounter1 0xda0 /* cca, parity fail */
#define rOFDM_PHYCounter2 0xda4 /* rate illegal, crc8 fail */
#define rOFDM_PHYCounter3 0xda8 /* MCS not supported */
#define rOFDM_ShortCFOAB 0xdac
#define rOFDM_ShortCFOCD 0xdb0
#define rOFDM_LongCFOAB 0xdb4
#define rOFDM_LongCFOCD 0xdb8
#define rOFDM_TailCFOAB 0xdbc
#define rOFDM_TailCFOCD 0xdc0
#define rOFDM_PWMeasure1 0xdc4
#define rOFDM_PWMeasure2 0xdc8
#define rOFDM_BWReport 0xdcc
#define rOFDM_AGCReport 0xdd0
#define rOFDM_RxSNR 0xdd4
#define rOFDM_RxEVMCSI 0xdd8
#define rOFDM_SIGReport 0xddc
#define rTxAGC_Rate18_06 0xe00
#define rTxAGC_Rate54_24 0xe04
#define rTxAGC_CCK_Mcs32 0xe08
#define rTxAGC_Mcs03_Mcs00 0xe10
#define rTxAGC_Mcs07_Mcs04 0xe14
#define rTxAGC_Mcs11_Mcs08 0xe18
#define rTxAGC_Mcs15_Mcs12 0xe1c
#define rZebra1_HSSIEnable 0x0
#define rZebra1_TRxEnable1 0x1
#define rZebra1_TRxEnable2 0x2
#define rZebra1_AGC 0x4
#define rZebra1_ChargePump 0x5
#define rZebra1_Channel 0x7
#define rZebra1_TxGain 0x8
#define rZebra1_TxLPF 0x9
#define rZebra1_RxLPF 0xb
#define rZebra1_RxHPFCorner 0xc
/* Zebra 4 */
#define rGlobalCtrl 0
#define rRTL8256_TxLPF 19
#define rRTL8256_RxLPF 11
/* RTL8258 */
#define rRTL8258_TxLPF 0x11
#define rRTL8258_RxLPF 0x13
#define rRTL8258_RSSILPF 0xa
/* Bit Mask - Page 1*/
#define bBBResetB 0x100
#define bGlobalResetB 0x200
#define bOFDMTxStart 0x4
#define bCCKTxStart 0x8
#define bCRC32Debug 0x100
#define bPMACLoopback 0x10
#define bTxLSIG 0xffffff
#define bOFDMTxRate 0xf
#define bOFDMTxReserved 0x10
#define bOFDMTxLength 0x1ffe0
#define bOFDMTxParity 0x20000
#define bTxHTSIG1 0xffffff
#define bTxHTMCSRate 0x7f
#define bTxHTBW 0x80
#define bTxHTLength 0xffff00
#define bTxHTSIG2 0xffffff
#define bTxHTSmoothing 0x1
#define bTxHTSounding 0x2
#define bTxHTReserved 0x4
#define bTxHTAggreation 0x8
#define bTxHTSTBC 0x30
#define bTxHTAdvanceCoding 0x40
#define bTxHTShortGI 0x80
#define bTxHTNumberHT_LTF 0x300
#define bTxHTCRC8 0x3fc00
#define bCounterReset 0x10000
#define bNumOfOFDMTx 0xffff
#define bNumOfCCKTx 0xffff0000
#define bTxIdleInterval 0xffff
#define bOFDMService 0xffff0000
#define bTxMACHeader 0xffffffff
#define bTxDataInit 0xff
#define bTxHTMode 0x100
#define bTxDataType 0x30000
#define bTxRandomSeed 0xffffffff
#define bCCKTxPreamble 0x1
#define bCCKTxSFD 0xffff0000
#define bCCKTxSIG 0xff
#define bCCKTxService 0xff00
#define bCCKLengthExt 0x8000
#define bCCKTxLength 0xffff0000
#define bCCKTxCRC16 0xffff
#define bCCKTxStatus 0x1
#define bOFDMTxStatus 0x2
/* Bit Mask - Page 8 */
#define bRFMOD 0x1
#define bJapanMode 0x2
#define bCCKTxSC 0x30
#define bCCKEn 0x1000000
#define bOFDMEn 0x2000000
#define bOFDMRxADCPhase 0x10000
#define bOFDMTxDACPhase 0x40000
#define bXATxAGC 0x3f
#define bXBTxAGC 0xf00
#define bXCTxAGC 0xf000
#define bXDTxAGC 0xf0000
#define bPAStart 0xf0000000
#define bTRStart 0x00f00000
#define bRFStart 0x0000f000
#define bBBStart 0x000000f0
#define bBBCCKStart 0x0000000f
/* Bit Mask - rFPGA0_RFTiming2 */
#define bPAEnd 0xf
#define bTREnd 0x0f000000
#define bRFEnd 0x000f0000
/* Channel gain at continue TX. */
#define b3WireDataLength 0x800
#define b3WireAddressLength 0x400
/* 3-wire total control */
#define bRFSI_RFENV 0x10
#define bLSSIReadAddress 0x3f000000 /* LSSI "read" address */
#define bLSSIReadEdge 0x80000000 /* LSSI "read" edge signal */
#define bLSSIReadBackData 0xfff
#define bDA6Swing 0x380000
#define bADClkPhase 0x4000000
#define b80MClkDelay 0x18000000
#define bAFEWatchDogEnable 0x20000000
#define bXtalCap 0x0f000000
#define bXtalCap01 0xc0000000
#define bXtalCap23 0x3
#define bXtalCap92x 0x0f000000
#define bIntDifClkEnable 0x400
#define bExtSigClkEnable 0x800
#define bBandgapMbiasPowerUp 0x10000
#define bAD11SHGain 0xc0000
#define bAD11InputRange 0x700000
#define bAD11OPCurrent 0x3800000
#define bIPathLoopback 0x4000000
#define bQPathLoopback 0x8000000
#define bAFELoopback 0x10000000
#define bDA10Swing 0x7e0
#define bDA10Reverse 0x800
#define bDAClkSource 0x1000
#define bAD7InputRange 0x6000
#define bAD7Gain 0x38000
#define bAD7OutputCMMode 0x40000
#define bAD7InputCMMode 0x380000
#define bAD7Current 0xc00000
#define bRegulatorAdjust 0x7000000
#define bAD11PowerUpAtTx 0x1
#define bDA10PSAtTx 0x10
#define bAD11PowerUpAtRx 0x100
#define bDA10PSAtRx 0x1000
#define bCCKRxAGCFormat 0x200
#define bPSDFFTSamplepPoint 0xc000
#define bPSDAverageNum 0x3000
#define bIQPathControl 0xc00
#define bPSDFreq 0x3ff
#define bPSDAntennaPath 0x30
#define bPSDIQSwitch 0x40
#define bPSDRxTrigger 0x400000
#define bPSDTxTrigger 0x80000000
#define bPSDSineToneScale 0x7f000000
#define bPSDReport 0xffff
/* Page 8 */
#define bOFDMTxSC 0x30000000
#define bCCKTxOn 0x1
#define bOFDMTxOn 0x2
/* Reset debug page and also HWord, LWord */
#define bDebugPage 0xfff
/* Reset debug page and LWord */
#define bDebugItem 0xff
#define bAntL 0x10
#define bAntNonHT 0x100
#define bAntHT1 0x1000
#define bAntHT2 0x10000
#define bAntHT1S1 0x100000
#define bAntNonHTS1 0x1000000
/* Page a */
#define bCCKBBMode 0x3
#define bCCKTxPowerSaving 0x80
#define bCCKRxPowerSaving 0x40
#define bCCKSideBand 0x10
#define bCCKScramble 0x8
#define bCCKAntDiversity 0x8000
#define bCCKCarrierRecovery 0x4000
#define bCCKTxRate 0x3000
#define bCCKDCCancel 0x0800
#define bCCKISICancel 0x0400
#define bCCKMatchFilter 0x0200
#define bCCKEqualizer 0x0100
#define bCCKPreambleDetect 0x800000
#define bCCKFastFalseCCA 0x400000
#define bCCKChEstStart 0x300000
#define bCCKCCACount 0x080000
#define bCCKcs_lim 0x070000
#define bCCKBistMode 0x80000000
#define bCCKCCAMask 0x40000000
#define bCCKTxDACPhase 0x4
#define bCCKRxADCPhase 0x20000000 /* r_rx_clk */
#define bCCKr_cp_mode0 0x0100
#define bCCKTxDCOffset 0xf0
#define bCCKRxDCOffset 0xf
#define bCCKCCAMode 0xc000
#define bCCKFalseCS_lim 0x3f00
#define bCCKCS_ratio 0xc00000
#define bCCKCorgBit_sel 0x300000
#define bCCKPD_lim 0x0f0000
#define bCCKNewCCA 0x80000000
#define bCCKRxHPofIG 0x8000
#define bCCKRxIG 0x7f00
#define bCCKLNAPolarity 0x800000
#define bCCKRx1stGain 0x7f0000
/* CCK Rx Initial gain polarity */
#define bCCKRFExtend 0x20000000
#define bCCKRxAGCSatLevel 0x1f000000
#define bCCKRxAGCSatCount 0xe0
/* AGCSAmp_dly */
#define bCCKRxRFSettle 0x1f
#define bCCKFixedRxAGC 0x8000
/*#define bCCKRxAGCFormat 0x4000 remove to HSSI register 0x824 */
#define bCCKAntennaPolarity 0x2000
#define bCCKTxFilterType 0x0c00
#define bCCKRxAGCReportType 0x0300
#define bCCKRxDAGCEn 0x80000000
#define bCCKRxDAGCPeriod 0x20000000
#define bCCKRxDAGCSatLevel 0x1f000000
#define bCCKTimingRecovery 0x800000
#define bCCKTxC0 0x3f0000
#define bCCKTxC1 0x3f000000
#define bCCKTxC2 0x3f
#define bCCKTxC3 0x3f00
#define bCCKTxC4 0x3f0000
#define bCCKTxC5 0x3f000000
#define bCCKTxC6 0x3f
#define bCCKTxC7 0x3f00
#define bCCKDebugPort 0xff0000
#define bCCKDACDebug 0x0f000000
#define bCCKFalseAlarmEnable 0x8000
#define bCCKFalseAlarmRead 0x4000
#define bCCKTRSSI 0x7f
#define bCCKRxAGCReport 0xfe
#define bCCKRxReport_AntSel 0x80000000
#define bCCKRxReport_MFOff 0x40000000
#define bCCKRxRxReport_SQLoss 0x20000000
#define bCCKRxReport_Pktloss 0x10000000
#define bCCKRxReport_Lockedbit 0x08000000
#define bCCKRxReport_RateError 0x04000000
#define bCCKRxReport_RxRate 0x03000000
#define bCCKRxFACounterLower 0xff
#define bCCKRxFACounterUpper 0xff000000
#define bCCKRxHPAGCStart 0xe000
#define bCCKRxHPAGCFinal 0x1c00
#define bCCKRxFalseAlarmEnable 0x8000
#define bCCKFACounterFreeze 0x4000
#define bCCKTxPathSel 0x10000000
#define bCCKDefaultRxPath 0xc000000
#define bCCKOptionRxPath 0x3000000
/* Page c */
#define bNumOfSTF 0x3
#define bShift_L 0xc0
#define bGI_TH 0xc
#define bRxPathA 0x1
#define bRxPathB 0x2
#define bRxPathC 0x4
#define bRxPathD 0x8
#define bTxPathA 0x1
#define bTxPathB 0x2
#define bTxPathC 0x4
#define bTxPathD 0x8
#define bTRSSIFreq 0x200
#define bADCBackoff 0x3000
#define bDFIRBackoff 0xc000
#define bTRSSILatchPhase 0x10000
#define bRxIDCOffset 0xff
#define bRxQDCOffset 0xff00
#define bRxDFIRMode 0x1800000
#define bRxDCNFType 0xe000000
#define bRXIQImb_A 0x3ff
#define bRXIQImb_B 0xfc00
#define bRXIQImb_C 0x3f0000
#define bRXIQImb_D 0xffc00000
#define bDC_dc_Notch 0x60000
#define bRxNBINotch 0x1f000000
#define bPD_TH 0xf
#define bPD_TH_Opt2 0xc000
#define bPWED_TH 0x700
#define bIfMF_Win_L 0x800
#define bPD_Option 0x1000
#define bMF_Win_L 0xe000
#define bBW_Search_L 0x30000
#define bwin_enh_L 0xc0000
#define bBW_TH 0x700000
#define bED_TH2 0x3800000
#define bBW_option 0x4000000
#define bRatio_TH 0x18000000
#define bWindow_L 0xe0000000
#define bSBD_Option 0x1
#define bFrame_TH 0x1c
#define bFS_Option 0x60
#define bDC_Slope_check 0x80
#define bFGuard_Counter_DC_L 0xe00
#define bFrame_Weight_Short 0x7000
#define bSub_Tune 0xe00000
#define bFrame_DC_Length 0xe000000
#define bSBD_start_offset 0x30000000
#define bFrame_TH_2 0x7
#define bFrame_GI2_TH 0x38
#define bGI2_Sync_en 0x40
#define bSarch_Short_Early 0x300
#define bSarch_Short_Late 0xc00
#define bSarch_GI2_Late 0x70000
#define bCFOAntSum 0x1
#define bCFOAcc 0x2
#define bCFOStartOffset 0xc
#define bCFOLookBack 0x70
#define bCFOSumWeight 0x80
#define bDAGCEnable 0x10000
#define bTXIQImb_A 0x3ff
#define bTXIQImb_B 0xfc00
#define bTXIQImb_C 0x3f0000
#define bTXIQImb_D 0xffc00000
#define bTxIDCOffset 0xff
#define bTxQDCOffset 0xff00
#define bTxDFIRMode 0x10000
#define bTxPesudoNoiseOn 0x4000000
#define bTxPesudoNoise_A 0xff
#define bTxPesudoNoise_B 0xff00
#define bTxPesudoNoise_C 0xff0000
#define bTxPesudoNoise_D 0xff000000
#define bCCADropOption 0x20000
#define bCCADropThres 0xfff00000
#define bEDCCA_H 0xf
#define bEDCCA_L 0xf0
#define bLambda_ED 0x300
#define bRxInitialGain 0x7f
#define bRxAntDivEn 0x80
#define bRxAGCAddressForLNA 0x7f00
#define bRxHighPowerFlow 0x8000
#define bRxAGCFreezeThres 0xc0000
#define bRxFreezeStep_AGC1 0x300000
#define bRxFreezeStep_AGC2 0xc00000
#define bRxFreezeStep_AGC3 0x3000000
#define bRxFreezeStep_AGC0 0xc000000
#define bRxRssi_Cmp_En 0x10000000
#define bRxQuickAGCEn 0x20000000
#define bRxAGCFreezeThresMode 0x40000000
#define bRxOverFlowCheckType 0x80000000
#define bRxAGCShift 0x7f
#define bTRSW_Tri_Only 0x80
#define bPowerThres 0x300
#define bRxAGCEn 0x1
#define bRxAGCTogetherEn 0x2
#define bRxAGCMin 0x4
#define bRxHP_Ini 0x7
#define bRxHP_TRLNA 0x70
#define bRxHP_RSSI 0x700
#define bRxHP_BBP1 0x7000
#define bRxHP_BBP2 0x70000
#define bRxHP_BBP3 0x700000
/* The threshold for high power */
#define bRSSI_H 0x7f0000
/* The threshold for ant diversity */
#define bRSSI_Gen 0x7f000000
#define bRxSettle_TRSW 0x7
#define bRxSettle_LNA 0x38
#define bRxSettle_RSSI 0x1c0
#define bRxSettle_BBP 0xe00
#define bRxSettle_RxHP 0x7000
#define bRxSettle_AntSW_RSSI 0x38000
#define bRxSettle_AntSW 0xc0000
#define bRxProcessTime_DAGC 0x300000
#define bRxSettle_HSSI 0x400000
#define bRxProcessTime_BBPPW 0x800000
#define bRxAntennaPowerShift 0x3000000
#define bRSSITableSelect 0xc000000
#define bRxHP_Final 0x7000000
#define bRxHTSettle_BBP 0x7
#define bRxHTSettle_HSSI 0x8
#define bRxHTSettle_RxHP 0x70
#define bRxHTSettle_BBPPW 0x80
#define bRxHTSettle_Idle 0x300
#define bRxHTSettle_Reserved 0x1c00
#define bRxHTRxHPEn 0x8000
#define bRxHTAGCFreezeThres 0x30000
#define bRxHTAGCTogetherEn 0x40000
#define bRxHTAGCMin 0x80000
#define bRxHTAGCEn 0x100000
#define bRxHTDAGCEn 0x200000
#define bRxHTRxHP_BBP 0x1c00000
#define bRxHTRxHP_Final 0xe0000000
#define bRxPWRatioTH 0x3
#define bRxPWRatioEn 0x4
#define bRxMFHold 0x3800
#define bRxPD_Delay_TH1 0x38
#define bRxPD_Delay_TH2 0x1c0
#define bRxPD_DC_COUNT_MAX 0x600
/*#define bRxMF_Hold 0x3800*/
#define bRxPD_Delay_TH 0x8000
#define bRxProcess_Delay 0xf0000
#define bRxSearchrange_GI2_Early 0x700000
#define bRxFrame_Guard_Counter_L 0x3800000
#define bRxSGI_Guard_L 0xc000000
#define bRxSGI_Search_L 0x30000000
#define bRxSGI_TH 0xc0000000
#define bDFSCnt0 0xff
#define bDFSCnt1 0xff00
#define bDFSFlag 0xf0000
#define bMFWeightSum 0x300000
#define bMinIdxTH 0x7f000000
#define bDAFormat 0x40000
#define bTxChEmuEnable 0x01000000
#define bTRSWIsolation_A 0x7f
#define bTRSWIsolation_B 0x7f00
#define bTRSWIsolation_C 0x7f0000
#define bTRSWIsolation_D 0x7f000000
#define bExtLNAGain 0x7c00
/* Page d */
#define bSTBCEn 0x4
#define bAntennaMapping 0x10
#define bNss 0x20
#define bCFOAntSumD 0x200
#define bPHYCounterReset 0x8000000
#define bCFOReportGet 0x4000000
#define bOFDMContinueTx 0x10000000
#define bOFDMSingleCarrier 0x20000000
#define bOFDMSingleTone 0x40000000
/* #define bRxPath1 0x01
* #define bRxPath2 0x02
* #define bRxPath3 0x04
* #define bRxPath4 0x08
* #define bTxPath1 0x10
* #define bTxPath2 0x20
*/
#define bHTDetect 0x100
#define bCFOEn 0x10000
#define bCFOValue 0xfff00000
#define bSigTone_Re 0x3f
#define bSigTone_Im 0x7f00
#define bCounter_CCA 0xffff
#define bCounter_ParityFail 0xffff0000
#define bCounter_RateIllegal 0xffff
#define bCounter_CRC8Fail 0xffff0000
#define bCounter_MCSNoSupport 0xffff
#define bCounter_FastSync 0xffff
#define bShortCFO 0xfff
#define bShortCFOTLength 12 /* total */
#define bShortCFOFLength 11 /* fraction */
#define bLongCFO 0x7ff
#define bLongCFOTLength 11
#define bLongCFOFLength 11
#define bTailCFO 0x1fff
#define bTailCFOTLength 13
#define bTailCFOFLength 12
#define bmax_en_pwdB 0xffff
#define bCC_power_dB 0xffff0000
#define bnoise_pwdB 0xffff
#define bPowerMeasTLength 10
#define bPowerMeasFLength 3
#define bRx_HT_BW 0x1
#define bRxSC 0x6
#define bRx_HT 0x8
#define bNB_intf_det_on 0x1
#define bIntf_win_len_cfg 0x30
#define bNB_Intf_TH_cfg 0x1c0
#define bRFGain 0x3f
#define bTableSel 0x40
#define bTRSW 0x80
#define bRxSNR_A 0xff
#define bRxSNR_B 0xff00
#define bRxSNR_C 0xff0000
#define bRxSNR_D 0xff000000
#define bSNREVMTLength 8
#define bSNREVMFLength 1
#define bCSI1st 0xff
#define bCSI2nd 0xff00
#define bRxEVM1st 0xff0000
#define bRxEVM2nd 0xff000000
#define bSIGEVM 0xff
#define bPWDB 0xff00
#define bSGIEN 0x10000
#define bSFactorQAM1 0xf
#define bSFactorQAM2 0xf0
#define bSFactorQAM3 0xf00
#define bSFactorQAM4 0xf000
#define bSFactorQAM5 0xf0000
#define bSFactorQAM6 0xf0000
#define bSFactorQAM7 0xf00000
#define bSFactorQAM8 0xf000000
#define bSFactorQAM9 0xf0000000
#define bCSIScheme 0x100000
#define bNoiseLvlTopSet 0x3
#define bChSmooth 0x4
#define bChSmoothCfg1 0x38
#define bChSmoothCfg2 0x1c0
#define bChSmoothCfg3 0xe00
#define bChSmoothCfg4 0x7000
#define bMRCMode 0x800000
#define bTHEVMCfg 0x7000000
#define bLoopFitType 0x1
#define bUpdCFO 0x40
#define bUpdCFOOffData 0x80
#define bAdvUpdCFO 0x100
#define bAdvTimeCtrl 0x800
#define bUpdClko 0x1000
#define bFC 0x6000
#define bTrackingMode 0x8000
#define bPhCmpEnable 0x10000
#define bUpdClkoLTF 0x20000
#define bComChCFO 0x40000
#define bCSIEstiMode 0x80000
#define bAdvUpdEqz 0x100000
#define bUChCfg 0x7000000
#define bUpdEqz 0x8000000
/* Page e */
#define bTxAGCRate18_06 0x7f7f7f7f
#define bTxAGCRate54_24 0x7f7f7f7f
#define bTxAGCRateMCS32 0x7f
#define bTxAGCRateCCK 0x7f00
#define bTxAGCRateMCS3_MCS0 0x7f7f7f7f
#define bTxAGCRateMCS7_MCS4 0x7f7f7f7f
#define bTxAGCRateMCS11_MCS8 0x7f7f7f7f
#define bTxAGCRateMCS15_MCS12 0x7f7f7f7f
#define bRxPesudoNoiseOn 0x20000000 /* Rx Pseduo noise */
#define bRxPesudoNoise_A 0xff
#define bRxPesudoNoise_B 0xff00
#define bRxPesudoNoise_C 0xff0000
#define bRxPesudoNoise_D 0xff000000
#define bPesudoNoiseState_A 0xffff
#define bPesudoNoiseState_B 0xffff0000
#define bPesudoNoiseState_C 0xffff
#define bPesudoNoiseState_D 0xffff0000
/* RF Zebra 1 */
#define bZebra1_HSSIEnable 0x8
#define bZebra1_TRxControl 0xc00
#define bZebra1_TRxGainSetting 0x07f
#define bZebra1_RxCorner 0xc00
#define bZebra1_TxChargePump 0x38
#define bZebra1_RxChargePump 0x7
#define bZebra1_ChannelNum 0xf80
#define bZebra1_TxLPFBW 0x400
#define bZebra1_RxLPFBW 0x600
/* Zebra4 */
#define bRTL8256RegModeCtrl1 0x100
#define bRTL8256RegModeCtrl0 0x40
#define bRTL8256_TxLPFBW 0x18
#define bRTL8256_RxLPFBW 0x600
/* RTL8258 */
#define bRTL8258_TxLPFBW 0xc
#define bRTL8258_RxLPFBW 0xc00
#define bRTL8258_RSSILPFBW 0xc0
/* byte enable for sb_write */
#define bByte0 0x1
#define bByte1 0x2
#define bByte2 0x4
#define bByte3 0x8
#define bWord0 0x3
#define bWord1 0xc
#define bDWord 0xf
/* for PutRegsetting & GetRegSetting BitMask */
#define bMaskByte0 0xff
#define bMaskByte1 0xff00
#define bMaskByte2 0xff0000
#define bMaskByte3 0xff000000
#define bMaskHWord 0xffff0000
#define bMaskLWord 0x0000ffff
#define bMaskDWord 0xffffffff
/* for PutRFRegsetting & GetRFRegSetting BitMask */
#define bMask12Bits 0xfff
#define bEnable 0x1
#define bDisable 0x0
#define LeftAntenna 0x0
#define RightAntenna 0x1
#define tCheckTxStatus 500 /* 500 ms */
#define tUpdateRxCounter 100 /* 100 ms */
#define rateCCK 0
#define rateOFDM 1
#define rateHT 2
#define bPMAC_End 0x1ff /* define Register-End */
#define bFPGAPHY0_End 0x8ff
#define bFPGAPHY1_End 0x9ff
#define bCCKPHY0_End 0xaff
#define bOFDMPHY0_End 0xcff
#define bOFDMPHY1_End 0xdff
#define bPMACControl 0x0
#define bWMACControl 0x1
#define bWNICControl 0x2
#define PathA 0x0
#define PathB 0x1
#define PathC 0x2
#define PathD 0x3
#define rRTL8256RxMixerPole 0xb
#define bZebraRxMixerPole 0x6
#define rRTL8256TxBBOPBias 0x9
#define bRTL8256TxBBOPBias 0x400
#define rRTL8256TxBBBW 19
#define bRTL8256TxBBBW 0x18
#endif

View File

@ -1,123 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Based on the r8180 driver, which is:
* Copyright 2004-2005 Andrea Merello <andrea.merello@gmail.com>, et al.
*
* Contact Information: wlanfae <wlanfae@realtek.com>
*/
#include "rtl_core.h"
#include "r8192E_phy.h"
#include "r8192E_phyreg.h"
#include "r8190P_rtl8256.h" /* RTL8225 Radio frontend */
#include "r8192E_cmdpkt.h"
void rtl92e_cam_reset(struct net_device *dev)
{
u32 ulcommand = 0;
ulcommand |= BIT(31) | BIT(30);
rtl92e_writel(dev, RWCAM, ulcommand);
}
void rtl92e_enable_hw_security_config(struct net_device *dev)
{
u8 SECR_value = 0x0;
struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
struct rtllib_device *ieee = priv->rtllib;
SECR_value = SCR_TxEncEnable | SCR_RxDecEnable;
if (((ieee->pairwise_key_type == KEY_TYPE_WEP40) ||
(ieee->pairwise_key_type == KEY_TYPE_WEP104)) &&
(priv->rtllib->auth_mode != 2)) {
SECR_value |= SCR_RxUseDK;
SECR_value |= SCR_TxUseDK;
}
ieee->hwsec_active = 1;
if ((ieee->ht_info->iot_action & HT_IOT_ACT_PURE_N_MODE) || !hwwep) {
ieee->hwsec_active = 0;
SECR_value &= ~SCR_RxDecEnable;
}
rtl92e_writeb(dev, SECR, SECR_value);
}
void rtl92e_set_swcam(struct net_device *dev, u8 EntryNo, u8 KeyIndex,
u16 KeyType, const u8 *MacAddr, u32 *KeyContent)
{
struct r8192_priv *priv = rtllib_priv(dev);
struct rtllib_device *ieee = priv->rtllib;
if (EntryNo >= TOTAL_CAM_ENTRY)
return;
ieee->swcamtable[EntryNo].bused = true;
ieee->swcamtable[EntryNo].key_index = KeyIndex;
ieee->swcamtable[EntryNo].key_type = KeyType;
memcpy(ieee->swcamtable[EntryNo].macaddr, MacAddr, 6);
ieee->swcamtable[EntryNo].useDK = 0;
memcpy(ieee->swcamtable[EntryNo].key_buf, (u8 *)KeyContent, 16);
}
void rtl92e_set_key(struct net_device *dev, u8 EntryNo, u8 KeyIndex,
u16 KeyType, const u8 *MacAddr, u8 DefaultKey,
u32 *KeyContent)
{
u32 TargetCommand = 0;
u32 TargetContent = 0;
u16 usConfig = 0;
u8 i;
struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
enum rt_rf_power_state rt_state;
rt_state = priv->rtllib->rf_power_state;
if (rt_state == rf_off) {
if (priv->rtllib->rf_off_reason > RF_CHANGE_BY_IPS) {
netdev_warn(dev, "%s(): RF is OFF.\n",
__func__);
return;
}
mutex_lock(&priv->rtllib->ips_mutex);
rtl92e_ips_leave(dev);
mutex_unlock(&priv->rtllib->ips_mutex);
}
priv->rtllib->is_set_key = true;
if (EntryNo >= TOTAL_CAM_ENTRY) {
netdev_info(dev, "%s(): Invalid CAM entry\n", __func__);
return;
}
if (DefaultKey)
usConfig |= BIT(15) | (KeyType << 2);
else
usConfig |= BIT(15) | (KeyType << 2) | KeyIndex;
for (i = 0; i < CAM_CONTENT_COUNT; i++) {
TargetCommand = i + CAM_CONTENT_COUNT * EntryNo;
TargetCommand |= BIT(31) | BIT(16);
if (i == 0) {
TargetContent = (u32)(*(MacAddr + 0)) << 16 |
(u32)(*(MacAddr + 1)) << 24 |
(u32)usConfig;
rtl92e_writel(dev, WCAMI, TargetContent);
rtl92e_writel(dev, RWCAM, TargetCommand);
} else if (i == 1) {
TargetContent = (u32)(*(MacAddr + 2)) |
(u32)(*(MacAddr + 3)) << 8 |
(u32)(*(MacAddr + 4)) << 16 |
(u32)(*(MacAddr + 5)) << 24;
rtl92e_writel(dev, WCAMI, TargetContent);
rtl92e_writel(dev, RWCAM, TargetCommand);
} else {
if (KeyContent) {
rtl92e_writel(dev, WCAMI,
(u32)(*(KeyContent + i - 2)));
rtl92e_writel(dev, RWCAM, TargetCommand);
udelay(100);
}
}
}
}

View File

@ -1,25 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Based on the r8180 driver, which is:
* Copyright 2004-2005 Andrea Merello <andrea.merello@gmail.com>, et al.
*
* Contact Information: wlanfae <wlanfae@realtek.com>
*/
#ifndef _RTL_CAM_H
#define _RTL_CAM_H
#include <linux/types.h>
struct net_device;
void rtl92e_cam_reset(struct net_device *dev);
void rtl92e_enable_hw_security_config(struct net_device *dev);
void rtl92e_set_key(struct net_device *dev, u8 EntryNo, u8 KeyIndex,
u16 KeyType, const u8 *MacAddr, u8 DefaultKey,
u32 *KeyContent);
void rtl92e_set_swcam(struct net_device *dev, u8 EntryNo, u8 KeyIndex,
u16 KeyType, const u8 *MacAddr, u32 *KeyContent);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,402 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Based on the r8180 driver, which is:
* Copyright 2004-2005 Andrea Merello <andrea.merello@gmail.com>, et al.
*
* Contact Information: wlanfae <wlanfae@realtek.com>
*/
#ifndef _RTL_CORE_H
#define _RTL_CORE_H
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/ioport.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/netdevice.h>
#include <linux/pci.h>
#include <linux/etherdevice.h>
#include <linux/delay.h>
#include <linux/rtnetlink.h>
#include <linux/wireless.h>
#include <linux/timer.h>
#include <linux/proc_fs.h>
#include <linux/if_arp.h>
#include <linux/random.h>
#include <linux/io.h>
/* Need this defined before including local include files */
#define DRV_NAME "rtl819xE"
#include "../rtllib.h"
#include "r8192E_firmware.h"
#include "r8192E_hw.h"
#include "r8190P_def.h"
#include "r8192E_dev.h"
#include "rtl_eeprom.h"
#include "rtl_ps.h"
#include "rtl_pci.h"
#include "rtl_cam.h"
#define DRV_COPYRIGHT \
"Copyright(c) 2008 - 2010 Realsil Semiconductor Corporation"
#define DRV_AUTHOR "<wlanfae@realtek.com>"
#define DRV_VERSION "0014.0401.2010"
#define TOTAL_CAM_ENTRY 32
#define CAM_CONTENT_COUNT 8
#define HAL_HW_PCI_REVISION_ID_8192PCIE 0x01
#define HAL_HW_PCI_REVISION_ID_8192SE 0x10
#define RTLLIB_WATCH_DOG_TIME 2000
#define MAX_DEV_ADDR_SIZE 8 /*support till 64 bit bus width OS*/
#define MAX_FIRMWARE_INFORMATION_SIZE 32
#define MAX_802_11_HEADER_LENGTH (40 + MAX_FIRMWARE_INFORMATION_SIZE)
#define ENCRYPTION_MAX_OVERHEAD 128
#define MAX_FRAGMENT_COUNT 8
#define MAX_TRANSMIT_BUFFER_SIZE \
(1600 + (MAX_802_11_HEADER_LENGTH + ENCRYPTION_MAX_OVERHEAD) * \
MAX_FRAGMENT_COUNT)
#define CMDPACKET_FRAG_SIZE (4 * (MAX_TRANSMIT_BUFFER_SIZE / 4) - 8)
#define DEFAULT_FRAG_THRESHOLD 2342U
#define MIN_FRAG_THRESHOLD 256U
#define DEFAULT_BEACONINTERVAL 0x64U
#define DEFAULT_RETRY_RTS 7
#define DEFAULT_RETRY_DATA 7
#define PHY_RSSI_SLID_WIN_MAX 100
#define TX_BB_GAIN_TABLE_LEN 37
#define CCK_TX_BB_GAIN_TABLE_LEN 23
#define CHANNEL_PLAN_LEN 10
#define S_CRC_LEN 4
#define NIC_SEND_HANG_THRESHOLD_NORMAL 4
#define NIC_SEND_HANG_THRESHOLD_POWERSAVE 8
#define MAX_TX_QUEUE 9
#define MAX_RX_COUNT 64
#define MAX_TX_QUEUE_COUNT 9
extern int hwwep;
enum nic_t {
NIC_UNKNOWN = 0,
NIC_8192E = 1,
NIC_8190P = 2,
NIC_8192SE = 4,
NIC_8192CE = 5,
NIC_8192CU = 6,
NIC_8192DE = 7,
NIC_8192DU = 8,
};
enum rt_eeprom_type {
EEPROM_93C46,
EEPROM_93C56,
};
enum dcmg_txcmd_op {
TXCMD_TXRA_HISTORY_CTRL = 0xFF900000,
TXCMD_RESET_TX_PKT_BUFF = 0xFF900001,
TXCMD_RESET_RX_PKT_BUFF = 0xFF900002,
TXCMD_SET_TX_DURATION = 0xFF900003,
TXCMD_SET_RX_RSSI = 0xFF900004,
TXCMD_SET_TX_PWR_TRACKING = 0xFF900005,
TXCMD_XXXX_CTRL,
};
enum rt_customer_id {
RT_CID_DEFAULT = 0,
RT_CID_TOSHIBA = 9,
RT_CID_819X_NETCORE = 10,
};
enum reset_type {
RESET_TYPE_NORESET = 0x00,
RESET_TYPE_SILENT = 0x02
};
struct rt_stats {
unsigned long received_rate_histogram[4][32];
unsigned long txbytesunicast;
unsigned long rxbytesunicast;
unsigned long txretrycount;
u8 last_packet_rate;
unsigned long slide_signal_strength[100];
unsigned long slide_evm[100];
unsigned long slide_rssi_total;
unsigned long slide_evm_total;
long signal_strength;
long last_signal_strength_inpercent;
long recv_signal_power;
u8 rx_rssi_percentage[4];
u8 rx_evm_percentage[2];
u32 slide_beacon_pwdb[100];
u32 slide_beacon_total;
u32 CurrentShowTxate;
};
struct init_gain {
u8 xaagccore1;
u8 xbagccore1;
u8 xcagccore1;
u8 xdagccore1;
u8 cca;
};
struct tx_ring {
u32 *desc;
u8 nStuckCount;
struct tx_ring *next;
} __packed;
struct rtl8192_tx_ring {
struct tx_desc *desc;
dma_addr_t dma;
unsigned int idx;
unsigned int entries;
struct sk_buff_head queue;
};
struct r8192_priv {
struct pci_dev *pdev;
struct pci_dev *bridge_pdev;
bool bfirst_after_down;
bool being_init_adapter;
int irq;
short irq_enabled;
short up;
short up_first_time;
struct delayed_work update_beacon_wq;
struct delayed_work watch_dog_wq;
struct delayed_work txpower_tracking_wq;
struct delayed_work rfpath_check_wq;
struct delayed_work gpio_change_rf_wq;
struct rtllib_device *rtllib;
struct work_struct reset_wq;
enum rt_customer_id customer_id;
enum ht_channel_width current_chnl_bw;
struct bb_reg_definition phy_reg_def[4];
struct rate_adaptive rate_adaptive;
struct rt_firmware *fw_info;
enum rtl819x_loopback loopback_mode;
struct timer_list watch_dog_timer;
struct timer_list fsync_timer;
struct timer_list gpio_polling_timer;
spinlock_t irq_th_lock;
spinlock_t tx_lock;
spinlock_t rf_ps_lock;
spinlock_t ps_lock;
struct sk_buff_head skb_queue;
struct tasklet_struct irq_rx_tasklet;
struct tasklet_struct irq_tx_tasklet;
struct mutex wx_mutex;
struct mutex rf_mutex;
struct mutex mutex;
struct rt_stats stats;
struct iw_statistics wstats;
struct rx_desc *rx_ring;
struct sk_buff *rx_buf[MAX_RX_COUNT];
dma_addr_t rx_ring_dma;
unsigned int rx_idx;
int rxringcount;
u16 rxbuffersize;
u32 receive_config;
u8 retry_data;
u8 retry_rts;
u16 rts;
struct rtl8192_tx_ring tx_ring[MAX_TX_QUEUE_COUNT];
int txringcount;
atomic_t tx_pending[0x10];
u16 short_retry_limit;
u16 long_retry_limit;
bool hw_radio_off;
bool blinked_ingpio;
u8 polling_timer_on;
/**********************************************************/
struct work_struct qos_activate;
short promisc;
short chan;
u32 irq_mask[2];
u8 rf_mode;
enum nic_t card_8192;
u8 card_8192_version;
u8 ic_cut;
char nick[IW_ESSID_MAX_SIZE + 1];
u8 check_roaming_cnt;
u32 silent_reset_rx_slot_index;
u32 silent_reset_rx_stuck_event[MAX_SILENT_RESET_RX_SLOT_NUM];
u16 basic_rate;
u8 short_preamble;
u8 dot11_current_preamble_mode;
u8 slot_time;
bool autoload_fail_flag;
short epromtype;
u16 eeprom_vid;
u16 eeprom_did;
u8 eeprom_customer_id;
u8 eeprom_tx_pwr_level_cck[14];
u8 eeprom_tx_pwr_level_ofdm24g[14];
u16 eeprom_ant_pwr_diff;
u8 eeprom_thermal_meter;
u8 eeprom_crystal_cap;
u8 eeprom_legacy_ht_tx_pwr_diff;
u8 crystal_cap;
u8 thermal_meter[2];
u8 sw_chnl_in_progress;
u8 sw_chnl_stage;
u8 sw_chnl_step;
u8 set_bw_mode_in_progress;
u8 n_cur_40mhz_prime_sc;
u32 rf_reg_0value[4];
u8 num_total_rf_path;
bool brfpath_rxenable[4];
bool tx_pwr_data_read_from_eeprom;
u8 hw_rf_off_action;
bool rf_change_in_progress;
bool set_rf_pwr_state_in_progress;
u8 cck_pwr_enl;
u16 tssi_13dBm;
u32 pwr_track;
u8 cck_present_attn_20m_def;
u8 cck_present_attn_40m_def;
s8 cck_present_attn_diff;
s8 cck_present_attn;
long undecorated_smoothed_pwdb;
u32 mcs_tx_pwr_level_org_offset[6];
u8 tx_pwr_level_cck[14];
u8 tx_pwr_level_ofdm_24g[14];
u8 legacy_ht_tx_pwr_diff;
u8 antenna_tx_pwr_diff[3];
bool dynamic_tx_high_pwr;
bool dynamic_tx_low_pwr;
bool last_dtp_flag_high;
bool last_dtp_flag_low;
u8 rfa_txpowertrackingindex;
u8 rfa_txpowertrackingindex_real;
u8 rfa_txpowertracking_default;
bool btxpower_tracking;
bool bcck_in_ch14;
u8 txpower_count;
bool tx_pwr_tracking_init;
u8 ofdm_index[2];
u8 cck_index;
u8 rec_cck_20m_idx;
u8 rec_cck_40m_idx;
struct init_gain initgain_backup;
u8 def_initial_gain[4];
bool bis_any_nonbepkts;
bool bcurrent_turbo_EDCA;
bool bis_cur_rdlstate;
u32 rate_record;
u32 rate_count_diff_rec;
u32 continue_diff_count;
bool bswitch_fsync;
u8 framesync;
u16 tx_counter;
u16 rx_ctr;
};
extern const struct ethtool_ops rtl819x_ethtool_ops;
u8 rtl92e_readb(struct net_device *dev, int x);
u32 rtl92e_readl(struct net_device *dev, int x);
u16 rtl92e_readw(struct net_device *dev, int x);
void rtl92e_writeb(struct net_device *dev, int x, u8 y);
void rtl92e_writew(struct net_device *dev, int x, u16 y);
void rtl92e_writel(struct net_device *dev, int x, u32 y);
void force_pci_posting(struct net_device *dev);
void rtl92e_rx_enable(struct net_device *dev);
void rtl92e_tx_enable(struct net_device *dev);
void rtl92e_hw_sleep_wq(void *data);
void rtl92e_commit(struct net_device *dev);
void rtl92e_check_rfctrl_gpio_timer(struct timer_list *t);
void rtl92e_hw_wakeup_wq(void *data);
void rtl92e_reset_desc_ring(struct net_device *dev);
void rtl92e_set_wireless_mode(struct net_device *dev, u8 wireless_mode);
void rtl92e_irq_enable(struct net_device *dev);
void rtl92e_config_rate(struct net_device *dev, u16 *rate_config);
void rtl92e_irq_disable(struct net_device *dev);
long rtl92e_translate_to_dbm(struct r8192_priv *priv, u8 signal_strength_index);
void rtl92e_update_rx_statistics(struct r8192_priv *priv,
struct rtllib_rx_stats *pprevious_stats);
u8 rtl92e_evm_db_to_percent(s8 value);
u8 rtl92e_rx_db_to_percent(s8 antpower);
void rtl92e_copy_mpdu_stats(struct rtllib_rx_stats *psrc_stats,
struct rtllib_rx_stats *ptarget_stats);
bool rtl92e_enable_nic(struct net_device *dev);
bool rtl92e_set_rf_state(struct net_device *dev,
enum rt_rf_power_state state_to_set,
RT_RF_CHANGE_SOURCE change_source);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,155 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Contact Information: wlanfae <wlanfae@realtek.com>
*/
#ifndef __R8192UDM_H__
#define __R8192UDM_H__
/*--------------------------Define Parameters-------------------------------*/
#define OFDM_TABLE_LEN 19
#define CCK_TABLE_LEN 12
#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_DIG_BACKOFF 12
#define DM_DIG_MAX 0x36
#define DM_DIG_MIN 0x1c
#define DM_DIG_MIN_Netcore 0x12
#define RX_PATH_SEL_SS_TH_LOW 30
#define RX_PATH_SEL_DIFF_TH 18
#define RATE_ADAPTIVE_TH_HIGH 50
#define RATE_ADAPTIVE_TH_LOW_20M 30
#define RATE_ADAPTIVE_TH_LOW_40M 10
#define VERY_LOW_RSSI 15
#define E_FOR_TX_POWER_TRACK 300
#define TX_POWER_NEAR_FIELD_THRESH_HIGH 68
#define TX_POWER_NEAR_FIELD_THRESH_LOW 62
#define TX_POWER_ATHEROAP_THRESH_HIGH 78
#define TX_POWER_ATHEROAP_THRESH_LOW 72
#define CURRENT_TX_RATE_REG 0x1e0
#define INITIAL_TX_RATE_REG 0x1e1
#define TX_RETRY_COUNT_REG 0x1ac
#define REG_C38_TH 20
/*--------------------------Define Parameters-------------------------------*/
/*------------------------------Define structure----------------------------*/
struct dig_t {
long rssi_low_thresh;
long rssi_high_thresh;
long rssi_high_power_lowthresh;
long rssi_high_power_highthresh;
u8 cur_sta_connect_state;
u8 pre_sta_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;
long rssi_val;
};
enum dm_ratr_sta {
DM_RATR_STA_HIGH = 0,
DM_RATR_STA_MIDDLE = 1,
DM_RATR_STA_LOW = 2,
DM_RATR_STA_MAX
};
enum dm_dig_connect {
DIG_STA_DISCONNECT = 0,
DIG_STA_CONNECT = 1,
};
enum dm_dig_pd_th {
DIG_PD_AT_LOW_POWER = 0,
DIG_PD_AT_NORMAL_POWER = 1,
DIG_PD_AT_HIGH_POWER = 2,
DIG_PD_MAX
};
enum dm_dig_cs_ratio {
DIG_CS_RATIO_LOWER = 0,
DIG_CS_RATIO_HIGHER = 1,
DIG_CS_MAX
};
struct drx_path_sel {
u8 enable;
u8 cck_method;
u8 cck_rx_path;
u8 ss_th_low;
u8 diff_th;
u8 disabled_rf;
u8 reserved;
u8 rf_rssi[4];
u8 rf_enable_rssi_th[4];
long cck_pwdb_sta[4];
};
enum dm_cck_rx_path_method {
CCK_Rx_Version_1 = 0,
CCK_Rx_Version_2 = 1,
CCK_Rx_Version_MAX
};
struct dcmd_txcmd {
u32 op;
u32 length;
u32 value;
};
/*------------------------------Define structure----------------------------*/
/*------------------------Export global variable----------------------------*/
extern struct dig_t dm_digtable;
/* Pre-calculated gain tables */
extern const u32 dm_tx_bb_gain[TX_BB_GAIN_TABLE_LEN];
extern const u8 dm_cck_tx_bb_gain[CCK_TX_BB_GAIN_TABLE_LEN][8];
extern const u8 dm_cck_tx_bb_gain_ch14[CCK_TX_BB_GAIN_TABLE_LEN][8];
/*------------------------Export global variable----------------------------*/
/*--------------------------Exported Function prototype---------------------*/
/*--------------------------Exported Function prototype---------------------*/
void rtl92e_dm_init(struct net_device *dev);
void rtl92e_dm_deinit(struct net_device *dev);
void rtl92e_dm_watchdog(struct net_device *dev);
void rtl92e_init_adaptive_rate(struct net_device *dev);
void rtl92e_dm_txpower_tracking_wq(void *data);
void rtl92e_dm_cck_txpower_adjust(struct net_device *dev, bool binch14);
void rtl92e_dm_init_edca_turbo(struct net_device *dev);
void rtl92e_dm_rf_pathcheck_wq(void *data);
void rtl92e_dm_init_txpower_tracking(struct net_device *dev);
#endif /*__R8192UDM_H__ */

View File

@ -1,84 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Based on the r8180 driver, which is:
* Copyright 2004-2005 Andrea Merello <andrea.merello@gmail.com>, et al.
*
* Contact Information: wlanfae <wlanfae@realtek.com>
*/
#include "rtl_core.h"
#include "rtl_eeprom.h"
static void _rtl92e_gpio_write_bit(struct net_device *dev, int no, bool val)
{
u8 reg = rtl92e_readb(dev, EPROM_CMD);
if (val)
reg |= 1 << no;
else
reg &= ~(1 << no);
rtl92e_writeb(dev, EPROM_CMD, reg);
udelay(EPROM_DELAY);
}
static bool _rtl92e_gpio_get_bit(struct net_device *dev, int no)
{
u8 reg = rtl92e_readb(dev, EPROM_CMD);
return (reg >> no) & 0x1;
}
static void _rtl92e_eeprom_ck_cycle(struct net_device *dev)
{
_rtl92e_gpio_write_bit(dev, EPROM_CK_BIT, 1);
_rtl92e_gpio_write_bit(dev, EPROM_CK_BIT, 0);
}
static u16 _rtl92e_eeprom_xfer(struct net_device *dev, u16 data, int tx_len)
{
u16 ret = 0;
int rx_len = 16;
_rtl92e_gpio_write_bit(dev, EPROM_CS_BIT, 1);
_rtl92e_eeprom_ck_cycle(dev);
while (tx_len--) {
_rtl92e_gpio_write_bit(dev, EPROM_W_BIT,
(data >> tx_len) & 0x1);
_rtl92e_eeprom_ck_cycle(dev);
}
_rtl92e_gpio_write_bit(dev, EPROM_W_BIT, 0);
while (rx_len--) {
_rtl92e_eeprom_ck_cycle(dev);
ret |= _rtl92e_gpio_get_bit(dev, EPROM_R_BIT) << rx_len;
}
_rtl92e_gpio_write_bit(dev, EPROM_CS_BIT, 0);
_rtl92e_eeprom_ck_cycle(dev);
return ret;
}
u32 rtl92e_eeprom_read(struct net_device *dev, u32 addr)
{
struct r8192_priv *priv = rtllib_priv(dev);
u32 ret = 0;
rtl92e_writeb(dev, EPROM_CMD,
(EPROM_CMD_PROGRAM << EPROM_CMD_OPERATING_MODE_SHIFT));
udelay(EPROM_DELAY);
/* EEPROM is configured as x16 */
if (priv->epromtype == EEPROM_93C56)
ret = _rtl92e_eeprom_xfer(dev, (addr & 0xFF) | (0x6 << 8), 11);
else
ret = _rtl92e_eeprom_xfer(dev, (addr & 0x3F) | (0x6 << 6), 9);
rtl92e_writeb(dev, EPROM_CMD,
(EPROM_CMD_NORMAL << EPROM_CMD_OPERATING_MODE_SHIFT));
return ret;
}

View File

@ -1,12 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Based on the r8180 driver, which is:
* Copyright 2004-2005 Andrea Merello <andrea.merello@gmail.com>, et al.
*
* Contact Information: wlanfae <wlanfae@realtek.com>
*/
#define EPROM_DELAY 10
u32 rtl92e_eeprom_read(struct net_device *dev, u32 addr);

View File

@ -1,37 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Based on the r8180 driver, which is:
* Copyright 2004-2005 Andrea Merello <andrea.merello@gmail.com>, et al.
*
* Contact Information: wlanfae <wlanfae@realtek.com>
*/
#include <linux/netdevice.h>
#include <linux/ethtool.h>
#include <linux/delay.h>
#include "rtl_core.h"
static void _rtl92e_ethtool_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *info)
{
struct r8192_priv *priv = rtllib_priv(dev);
strscpy(info->driver, DRV_NAME, sizeof(info->driver));
strscpy(info->version, DRV_VERSION, sizeof(info->version));
strscpy(info->bus_info, pci_name(priv->pdev), sizeof(info->bus_info));
}
static u32 _rtl92e_ethtool_get_link(struct net_device *dev)
{
struct r8192_priv *priv = rtllib_priv(dev);
return ((priv->rtllib->link_state == MAC80211_LINKED) ||
(priv->rtllib->link_state == MAC80211_LINKED_SCANNING));
}
const struct ethtool_ops rtl819x_ethtool_ops = {
.get_drvinfo = _rtl92e_ethtool_get_drvinfo,
.get_link = _rtl92e_ethtool_get_link,
};

View File

@ -1,79 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Based on the r8180 driver, which is:
* Copyright 2004-2005 Andrea Merello <andrea.merello@gmail.com>, et al.
*
* Contact Information: wlanfae <wlanfae@realtek.com>
*/
#include "rtl_pci.h"
#include "rtl_core.h"
static void _rtl92e_parse_pci_configuration(struct pci_dev *pdev,
struct net_device *dev)
{
struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
u8 tmp;
u16 link_ctrl_reg;
pcie_capability_read_word(priv->pdev, PCI_EXP_LNKCTL, &link_ctrl_reg);
pci_read_config_byte(pdev, 0x98, &tmp);
tmp |= BIT(4);
pci_write_config_byte(pdev, 0x98, tmp);
tmp = 0x17;
pci_write_config_byte(pdev, 0x70f, tmp);
}
bool rtl92e_check_adapter(struct pci_dev *pdev, struct net_device *dev)
{
struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
u16 device_id;
u8 revision_id;
u16 irq_line;
device_id = pdev->device;
revision_id = pdev->revision;
pci_read_config_word(pdev, 0x3C, &irq_line);
priv->card_8192 = NIC_8192E;
if (device_id == 0x8192) {
switch (revision_id) {
case HAL_HW_PCI_REVISION_ID_8192PCIE:
dev_info(&pdev->dev,
"Adapter(8192 PCI-E) is found - DeviceID=%x\n",
device_id);
priv->card_8192 = NIC_8192E;
break;
case HAL_HW_PCI_REVISION_ID_8192SE:
dev_info(&pdev->dev,
"Adapter(8192SE) is found - DeviceID=%x\n",
device_id);
priv->card_8192 = NIC_8192SE;
break;
default:
dev_info(&pdev->dev,
"UNKNOWN nic type(%4x:%4x)\n",
pdev->vendor, pdev->device);
priv->card_8192 = NIC_UNKNOWN;
return false;
}
}
if (priv->card_8192 != NIC_8192E) {
dev_info(&pdev->dev,
"Detect info(%x) and hardware info(%x) not match!\n",
NIC_8192E, priv->card_8192);
dev_info(&pdev->dev,
"Please select proper driver before install!!!!\n");
return false;
}
_rtl92e_parse_pci_configuration(pdev, dev);
return true;
}

View File

@ -1,20 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Based on the r8180 driver, which is:
* Copyright 2004-2005 Andrea Merello <andrea.merello@gmail.com>, et al.
*
* Contact Information: wlanfae <wlanfae@realtek.com>
*/
#ifndef _RTL_PCI_H
#define _RTL_PCI_H
#include <linux/types.h>
#include <linux/pci.h>
struct net_device;
bool rtl92e_check_adapter(struct pci_dev *pdev, struct net_device *dev);
#endif

View File

@ -1,89 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Contact Information: wlanfae <wlanfae@realtek.com>
*/
#include "rtl_core.h"
#include "r8192E_hw.h"
#include "r8190P_rtl8256.h"
#include "rtl_pm.h"
int rtl92e_suspend(struct device *dev_d)
{
struct net_device *dev = dev_get_drvdata(dev_d);
struct r8192_priv *priv = rtllib_priv(dev);
u32 ulRegRead;
netdev_info(dev, "============> r8192E suspend call.\n");
del_timer_sync(&priv->gpio_polling_timer);
cancel_delayed_work_sync(&priv->gpio_change_rf_wq);
priv->polling_timer_on = 0;
if (!netif_running(dev)) {
netdev_info(dev,
"RTL819XE:UI is open out of suspend function\n");
goto out_pci_suspend;
}
if (dev->netdev_ops->ndo_stop)
dev->netdev_ops->ndo_stop(dev);
netif_device_detach(dev);
if (!priv->rtllib->bSupportRemoteWakeUp) {
rtl92e_set_rf_state(dev, rf_off, RF_CHANGE_BY_INIT);
ulRegRead = rtl92e_readl(dev, CPU_GEN);
ulRegRead |= CPU_GEN_SYSTEM_RESET;
rtl92e_writel(dev, CPU_GEN, ulRegRead);
} else {
rtl92e_writel(dev, WFCRC0, 0xffffffff);
rtl92e_writel(dev, WFCRC1, 0xffffffff);
rtl92e_writel(dev, WFCRC2, 0xffffffff);
rtl92e_writeb(dev, PMR, 0x5);
rtl92e_writeb(dev, MAC_BLK_CTRL, 0xa);
}
out_pci_suspend:
netdev_info(dev, "WOL is %s\n", priv->rtllib->bSupportRemoteWakeUp ?
"Supported" : "Not supported");
device_set_wakeup_enable(dev_d, priv->rtllib->bSupportRemoteWakeUp);
mdelay(20);
return 0;
}
int rtl92e_resume(struct device *dev_d)
{
struct pci_dev *pdev = to_pci_dev(dev_d);
struct net_device *dev = dev_get_drvdata(dev_d);
struct r8192_priv *priv = rtllib_priv(dev);
u32 val;
netdev_info(dev, "================>r8192E resume call.\n");
pci_read_config_dword(pdev, 0x40, &val);
if ((val & 0x0000ff00) != 0)
pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
device_wakeup_disable(dev_d);
if (priv->polling_timer_on == 0)
rtl92e_check_rfctrl_gpio_timer(&priv->gpio_polling_timer);
if (!netif_running(dev)) {
netdev_info(dev,
"RTL819XE:UI is open out of resume function\n");
goto out;
}
netif_device_attach(dev);
if (dev->netdev_ops->ndo_open)
dev->netdev_ops->ndo_open(dev);
if (!priv->rtllib->bSupportRemoteWakeUp)
rtl92e_set_rf_state(dev, rf_on, RF_CHANGE_BY_INIT);
out:
return 0;
}

View File

@ -1,16 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Contact Information: wlanfae <wlanfae@realtek.com>
*/
#ifndef R8192E_PM_H
#define R8192E_PM_H
#include <linux/types.h>
#include <linux/pci.h>
int rtl92e_suspend(struct device *dev_d);
int rtl92e_resume(struct device *dev_d);
#endif

View File

@ -1,231 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Based on the r8180 driver, which is:
* Copyright 2004-2005 Andrea Merello <andrea.merello@gmail.com>, et al.
*
* Contact Information: wlanfae <wlanfae@realtek.com>
*/
#include "rtl_ps.h"
#include "rtl_core.h"
#include "r8192E_phy.h"
#include "r8192E_phyreg.h"
#include "r8190P_rtl8256.h" /* RTL8225 Radio frontend */
#include "r8192E_cmdpkt.h"
#include <linux/jiffies.h>
static void _rtl92e_hw_sleep(struct net_device *dev)
{
struct r8192_priv *priv = rtllib_priv(dev);
unsigned long flags = 0;
spin_lock_irqsave(&priv->rf_ps_lock, flags);
if (priv->rf_change_in_progress) {
spin_unlock_irqrestore(&priv->rf_ps_lock, flags);
return;
}
spin_unlock_irqrestore(&priv->rf_ps_lock, flags);
rtl92e_set_rf_state(dev, rf_sleep, RF_CHANGE_BY_PS);
}
void rtl92e_hw_sleep_wq(void *data)
{
struct rtllib_device *ieee = container_of_dwork_rsl(data,
struct rtllib_device, hw_sleep_wq);
struct net_device *dev = ieee->dev;
_rtl92e_hw_sleep(dev);
}
void rtl92e_hw_wakeup(struct net_device *dev)
{
struct r8192_priv *priv = rtllib_priv(dev);
unsigned long flags = 0;
spin_lock_irqsave(&priv->rf_ps_lock, flags);
if (priv->rf_change_in_progress) {
spin_unlock_irqrestore(&priv->rf_ps_lock, flags);
schedule_delayed_work(&priv->rtllib->hw_wakeup_wq,
msecs_to_jiffies(10));
return;
}
spin_unlock_irqrestore(&priv->rf_ps_lock, flags);
rtl92e_set_rf_state(dev, rf_on, RF_CHANGE_BY_PS);
}
void rtl92e_hw_wakeup_wq(void *data)
{
struct rtllib_device *ieee = container_of_dwork_rsl(data,
struct rtllib_device, hw_wakeup_wq);
struct net_device *dev = ieee->dev;
rtl92e_hw_wakeup(dev);
}
#define MIN_SLEEP_TIME 50
#define MAX_SLEEP_TIME 10000
void rtl92e_enter_sleep(struct net_device *dev, u64 time)
{
struct r8192_priv *priv = rtllib_priv(dev);
u32 tmp;
unsigned long flags;
unsigned long timeout;
spin_lock_irqsave(&priv->ps_lock, flags);
time -= msecs_to_jiffies(8 + 16 + 7);
timeout = jiffies + msecs_to_jiffies(MIN_SLEEP_TIME);
if (time_before((unsigned long)time, timeout)) {
spin_unlock_irqrestore(&priv->ps_lock, flags);
netdev_info(dev, "too short to sleep::%lld < %ld\n",
time - jiffies, msecs_to_jiffies(MIN_SLEEP_TIME));
return;
}
timeout = jiffies + msecs_to_jiffies(MAX_SLEEP_TIME);
if (time_after((unsigned long)time, timeout)) {
netdev_info(dev, "========>too long to sleep:%lld > %ld\n",
time - jiffies, msecs_to_jiffies(MAX_SLEEP_TIME));
spin_unlock_irqrestore(&priv->ps_lock, flags);
return;
}
tmp = time - jiffies;
schedule_delayed_work(&priv->rtllib->hw_wakeup_wq, tmp);
schedule_delayed_work(&priv->rtllib->hw_sleep_wq, 0);
spin_unlock_irqrestore(&priv->ps_lock, flags);
}
static void _rtl92e_ps_update_rf_state(struct net_device *dev)
{
struct r8192_priv *priv = rtllib_priv(dev);
struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *)
&priv->rtllib->pwr_save_ctrl;
psc->bSwRfProcessing = true;
rtl92e_set_rf_state(dev, psc->eInactivePowerState, RF_CHANGE_BY_IPS);
psc->bSwRfProcessing = false;
}
void rtl92e_ips_enter(struct net_device *dev)
{
struct r8192_priv *priv = rtllib_priv(dev);
struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *)
&priv->rtllib->pwr_save_ctrl;
enum rt_rf_power_state rt_state;
rt_state = priv->rtllib->rf_power_state;
if (rt_state == rf_on && !psc->bSwRfProcessing &&
(priv->rtllib->link_state != MAC80211_LINKED)) {
psc->eInactivePowerState = rf_off;
_rtl92e_ps_update_rf_state(dev);
}
}
void rtl92e_ips_leave(struct net_device *dev)
{
struct r8192_priv *priv = rtllib_priv(dev);
struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *)
&priv->rtllib->pwr_save_ctrl;
enum rt_rf_power_state rt_state;
rt_state = priv->rtllib->rf_power_state;
if (rt_state != rf_on && !psc->bSwRfProcessing &&
priv->rtllib->rf_off_reason <= RF_CHANGE_BY_IPS) {
psc->eInactivePowerState = rf_on;
_rtl92e_ps_update_rf_state(dev);
}
}
void rtl92e_ips_leave_wq(void *data)
{
struct rtllib_device *ieee = container_of(data, struct rtllib_device, ips_leave_wq);
struct net_device *dev = ieee->dev;
struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
mutex_lock(&priv->rtllib->ips_mutex);
rtl92e_ips_leave(dev);
mutex_unlock(&priv->rtllib->ips_mutex);
}
void rtl92e_rtllib_ips_leave_wq(struct net_device *dev)
{
struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
enum rt_rf_power_state rt_state;
rt_state = priv->rtllib->rf_power_state;
if (rt_state == rf_off) {
if (priv->rtllib->rf_off_reason > RF_CHANGE_BY_IPS) {
netdev_warn(dev, "%s(): RF is OFF.\n",
__func__);
return;
}
netdev_info(dev, "=========>%s(): rtl92e_ips_leave\n",
__func__);
schedule_work(&priv->rtllib->ips_leave_wq);
}
}
void rtl92e_rtllib_ips_leave(struct net_device *dev)
{
struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
mutex_lock(&priv->rtllib->ips_mutex);
rtl92e_ips_leave(dev);
mutex_unlock(&priv->rtllib->ips_mutex);
}
static bool _rtl92e_ps_set_mode(struct net_device *dev, u8 rtPsMode)
{
struct r8192_priv *priv = rtllib_priv(dev);
priv->rtllib->ps = rtPsMode;
if (priv->rtllib->sta_sleep != LPS_IS_WAKE &&
rtPsMode == RTLLIB_PS_DISABLED) {
unsigned long flags;
rtl92e_hw_wakeup(dev);
priv->rtllib->sta_sleep = LPS_IS_WAKE;
spin_lock_irqsave(&(priv->rtllib->mgmt_tx_lock), flags);
rtllib_sta_ps_send_null_frame(priv->rtllib, 0);
spin_unlock_irqrestore(&(priv->rtllib->mgmt_tx_lock), flags);
}
return true;
}
void rtl92e_leisure_ps_enter(struct net_device *dev)
{
struct r8192_priv *priv = rtllib_priv(dev);
struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *)
&priv->rtllib->pwr_save_ctrl;
if (!((priv->rtllib->iw_mode == IW_MODE_INFRA) &&
(priv->rtllib->link_state == MAC80211_LINKED)))
return;
if (psc->bLeisurePs) {
if (psc->lps_idle_count >= RT_CHECK_FOR_HANG_PERIOD) {
if (priv->rtllib->ps == RTLLIB_PS_DISABLED)
_rtl92e_ps_set_mode(dev, RTLLIB_PS_MBCAST | RTLLIB_PS_UNICAST);
} else {
psc->lps_idle_count++;
}
}
}
void rtl92e_leisure_ps_leave(struct net_device *dev)
{
struct r8192_priv *priv = rtllib_priv(dev);
struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *)
&priv->rtllib->pwr_save_ctrl;
if (psc->bLeisurePs) {
if (priv->rtllib->ps != RTLLIB_PS_DISABLED)
_rtl92e_ps_set_mode(dev, RTLLIB_PS_DISABLED);
}
}

View File

@ -1,31 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Based on the r8180 driver, which is:
* Copyright 2004-2005 Andrea Merello <andrea.merello@gmail.com>, et al.
*
* Contact Information: wlanfae <wlanfae@realtek.com>
*/
#ifndef _RTL_PS_H
#define _RTL_PS_H
#include <linux/types.h>
struct net_device;
#define RT_CHECK_FOR_HANG_PERIOD 2
void rtl92e_hw_wakeup(struct net_device *dev);
void rtl92e_enter_sleep(struct net_device *dev, u64 time);
void rtl92e_rtllib_ips_leave_wq(struct net_device *dev);
void rtl92e_rtllib_ips_leave(struct net_device *dev);
void rtl92e_ips_leave_wq(void *data);
void rtl92e_ips_enter(struct net_device *dev);
void rtl92e_ips_leave(struct net_device *dev);
void rtl92e_leisure_ps_enter(struct net_device *dev);
void rtl92e_leisure_ps_leave(struct net_device *dev);
#endif

View File

@ -1,866 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Contact Information: wlanfae <wlanfae@realtek.com>
*/
#include <linux/string.h>
#include "rtl_core.h"
#include "rtl_wx.h"
#define RATE_COUNT 12
static u32 rtl8192_rates[] = {
1000000, 2000000, 5500000, 11000000, 6000000, 9000000, 12000000,
18000000, 24000000, 36000000, 48000000, 54000000
};
#ifndef ENETDOWN
#define ENETDOWN 1
#endif
static int _rtl92e_wx_get_freq(struct net_device *dev,
struct iw_request_info *a,
union iwreq_data *wrqu, char *b)
{
struct r8192_priv *priv = rtllib_priv(dev);
return rtllib_wx_get_freq(priv->rtllib, a, wrqu, b);
}
static int _rtl92e_wx_get_mode(struct net_device *dev,
struct iw_request_info *a,
union iwreq_data *wrqu, char *b)
{
struct r8192_priv *priv = rtllib_priv(dev);
return rtllib_wx_get_mode(priv->rtllib, a, wrqu, b);
}
static int _rtl92e_wx_get_rate(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
struct r8192_priv *priv = rtllib_priv(dev);
return rtllib_wx_get_rate(priv->rtllib, info, wrqu, extra);
}
static int _rtl92e_wx_set_rate(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
int ret;
struct r8192_priv *priv = rtllib_priv(dev);
if (priv->hw_radio_off)
return 0;
mutex_lock(&priv->wx_mutex);
ret = rtllib_wx_set_rate(priv->rtllib, info, wrqu, extra);
mutex_unlock(&priv->wx_mutex);
return ret;
}
static int _rtl92e_wx_set_rts(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
int ret;
struct r8192_priv *priv = rtllib_priv(dev);
if (priv->hw_radio_off)
return 0;
mutex_lock(&priv->wx_mutex);
ret = rtllib_wx_set_rts(priv->rtllib, info, wrqu, extra);
mutex_unlock(&priv->wx_mutex);
return ret;
}
static int _rtl92e_wx_get_rts(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
struct r8192_priv *priv = rtllib_priv(dev);
return rtllib_wx_get_rts(priv->rtllib, info, wrqu, extra);
}
static int _rtl92e_wx_set_power(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
int ret;
struct r8192_priv *priv = rtllib_priv(dev);
if (priv->hw_radio_off) {
netdev_warn(dev, "%s(): Can't set Power: Radio is Off.\n",
__func__);
return 0;
}
mutex_lock(&priv->wx_mutex);
ret = rtllib_wx_set_power(priv->rtllib, info, wrqu, extra);
mutex_unlock(&priv->wx_mutex);
return ret;
}
static int _rtl92e_wx_get_power(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
struct r8192_priv *priv = rtllib_priv(dev);
return rtllib_wx_get_power(priv->rtllib, info, wrqu, extra);
}
static int _rtl92e_wx_set_mode(struct net_device *dev,
struct iw_request_info *a,
union iwreq_data *wrqu, char *b)
{
struct r8192_priv *priv = rtllib_priv(dev);
enum rt_rf_power_state rt_state;
int ret;
if (priv->hw_radio_off)
return 0;
rt_state = priv->rtllib->rf_power_state;
mutex_lock(&priv->wx_mutex);
if (wrqu->mode == IW_MODE_MONITOR) {
if (rt_state == rf_off) {
if (priv->rtllib->rf_off_reason >
RF_CHANGE_BY_IPS) {
netdev_warn(dev, "%s(): RF is OFF.\n",
__func__);
mutex_unlock(&priv->wx_mutex);
return -1;
}
netdev_info(dev,
"=========>%s(): rtl92e_ips_leave\n",
__func__);
mutex_lock(&priv->rtllib->ips_mutex);
rtl92e_ips_leave(dev);
mutex_unlock(&priv->rtllib->ips_mutex);
}
}
ret = rtllib_wx_set_mode(priv->rtllib, a, wrqu, b);
mutex_unlock(&priv->wx_mutex);
return ret;
}
static int _rtl92e_wx_get_range(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
struct iw_range *range = (struct iw_range *)extra;
struct r8192_priv *priv = rtllib_priv(dev);
u16 val;
int i;
wrqu->data.length = sizeof(*range);
memset(range, 0, sizeof(*range));
/* ~130 Mb/s real (802.11n) */
range->throughput = 130 * 1000 * 1000;
range->max_qual.qual = 100;
range->max_qual.level = 0;
range->max_qual.noise = 0;
range->max_qual.updated = 7; /* Updated all three */
range->avg_qual.qual = 70; /* > 8% missed beacons is 'bad' */
range->avg_qual.level = 0;
range->avg_qual.noise = 0;
range->avg_qual.updated = 7; /* Updated all three */
range->num_bitrates = min(RATE_COUNT, IW_MAX_BITRATES);
for (i = 0; i < range->num_bitrates; i++)
range->bitrate[i] = rtl8192_rates[i];
range->max_rts = DEFAULT_RTS_THRESHOLD;
range->min_frag = MIN_FRAG_THRESHOLD;
range->max_frag = MAX_FRAG_THRESHOLD;
range->min_pmp = 0;
range->max_pmp = 5000000;
range->min_pmt = 0;
range->max_pmt = 65535 * 1000;
range->pmp_flags = IW_POWER_PERIOD;
range->pmt_flags = IW_POWER_TIMEOUT;
range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
range->we_version_compiled = WIRELESS_EXT;
range->we_version_source = 18;
for (i = 0, val = 0; i < 14; i++) {
if ((priv->rtllib->active_channel_map)[i + 1]) {
s32 freq_khz;
range->freq[val].i = i + 1;
freq_khz = ieee80211_channel_to_freq_khz(i + 1, NL80211_BAND_2GHZ);
range->freq[val].m = freq_khz * 100;
range->freq[val].e = 1;
val++;
}
if (val == IW_MAX_FREQUENCIES)
break;
}
range->num_frequency = val;
range->num_channels = val;
range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE;
/* Event capability (kernel + driver) */
return 0;
}
static int _rtl92e_wx_set_scan(struct net_device *dev,
struct iw_request_info *a,
union iwreq_data *wrqu, char *b)
{
struct r8192_priv *priv = rtllib_priv(dev);
struct rtllib_device *ieee = priv->rtllib;
enum rt_rf_power_state rt_state;
int ret;
if (!(ieee->softmac_features & IEEE_SOFTMAC_SCAN)) {
if ((ieee->link_state >= RTLLIB_ASSOCIATING) &&
(ieee->link_state <= RTLLIB_ASSOCIATING_AUTHENTICATED))
return 0;
if ((priv->rtllib->link_state == MAC80211_LINKED) &&
(priv->rtllib->cnt_after_link < 2))
return 0;
}
if (priv->hw_radio_off) {
netdev_info(dev, "================>%s(): hwradio off\n",
__func__);
return 0;
}
rt_state = priv->rtllib->rf_power_state;
if (!priv->up)
return -ENETDOWN;
if (priv->rtllib->link_detect_info.busy_traffic)
return -EAGAIN;
if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
struct iw_scan_req *req = (struct iw_scan_req *)b;
if (req->essid_len) {
int len = min_t(int, req->essid_len, IW_ESSID_MAX_SIZE);
ieee->current_network.ssid_len = len;
memcpy(ieee->current_network.ssid, req->essid, len);
}
}
mutex_lock(&priv->wx_mutex);
priv->rtllib->first_ie_in_scan = true;
if (priv->rtllib->link_state != MAC80211_LINKED) {
if (rt_state == rf_off) {
if (priv->rtllib->rf_off_reason >
RF_CHANGE_BY_IPS) {
netdev_warn(dev, "%s(): RF is OFF.\n",
__func__);
mutex_unlock(&priv->wx_mutex);
return -1;
}
mutex_lock(&priv->rtllib->ips_mutex);
rtl92e_ips_leave(dev);
mutex_unlock(&priv->rtllib->ips_mutex);
}
rtllib_stop_scan(priv->rtllib);
if (priv->rtllib->rf_power_state != rf_off) {
priv->rtllib->actscanning = true;
ieee->ScanOperationBackupHandler(ieee->dev, SCAN_OPT_BACKUP);
rtllib_start_scan_syncro(priv->rtllib);
ieee->ScanOperationBackupHandler(ieee->dev, SCAN_OPT_RESTORE);
}
ret = 0;
} else {
priv->rtllib->actscanning = true;
ret = rtllib_wx_set_scan(priv->rtllib, a, wrqu, b);
}
mutex_unlock(&priv->wx_mutex);
return ret;
}
static int _rtl92e_wx_get_scan(struct net_device *dev,
struct iw_request_info *a,
union iwreq_data *wrqu, char *b)
{
int ret;
struct r8192_priv *priv = rtllib_priv(dev);
if (!priv->up)
return -ENETDOWN;
if (priv->hw_radio_off)
return 0;
mutex_lock(&priv->wx_mutex);
ret = rtllib_wx_get_scan(priv->rtllib, a, wrqu, b);
mutex_unlock(&priv->wx_mutex);
return ret;
}
static int _rtl92e_wx_set_essid(struct net_device *dev,
struct iw_request_info *a,
union iwreq_data *wrqu, char *b)
{
struct r8192_priv *priv = rtllib_priv(dev);
int ret;
if (priv->hw_radio_off) {
netdev_info(dev,
"=========>%s():hw radio off,or Rf state is rf_off, return\n",
__func__);
return 0;
}
mutex_lock(&priv->wx_mutex);
ret = rtllib_wx_set_essid(priv->rtllib, a, wrqu, b);
mutex_unlock(&priv->wx_mutex);
return ret;
}
static int _rtl92e_wx_get_essid(struct net_device *dev,
struct iw_request_info *a,
union iwreq_data *wrqu, char *b)
{
int ret;
struct r8192_priv *priv = rtllib_priv(dev);
mutex_lock(&priv->wx_mutex);
ret = rtllib_wx_get_essid(priv->rtllib, a, wrqu, b);
mutex_unlock(&priv->wx_mutex);
return ret;
}
static int _rtl92e_wx_set_nick(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
struct r8192_priv *priv = rtllib_priv(dev);
if (wrqu->data.length > IW_ESSID_MAX_SIZE)
return -E2BIG;
mutex_lock(&priv->wx_mutex);
wrqu->data.length = min_t(size_t, wrqu->data.length,
sizeof(priv->nick));
memset(priv->nick, 0, sizeof(priv->nick));
memcpy(priv->nick, extra, wrqu->data.length);
mutex_unlock(&priv->wx_mutex);
return 0;
}
static int _rtl92e_wx_get_nick(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
struct r8192_priv *priv = rtllib_priv(dev);
mutex_lock(&priv->wx_mutex);
wrqu->data.length = strlen(priv->nick);
memcpy(extra, priv->nick, wrqu->data.length);
wrqu->data.flags = 1; /* active */
mutex_unlock(&priv->wx_mutex);
return 0;
}
static int _rtl92e_wx_set_freq(struct net_device *dev,
struct iw_request_info *a,
union iwreq_data *wrqu, char *b)
{
int ret;
struct r8192_priv *priv = rtllib_priv(dev);
if (priv->hw_radio_off)
return 0;
mutex_lock(&priv->wx_mutex);
ret = rtllib_wx_set_freq(priv->rtllib, a, wrqu, b);
mutex_unlock(&priv->wx_mutex);
return ret;
}
static int _rtl92e_wx_get_name(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
struct r8192_priv *priv = rtllib_priv(dev);
return rtllib_wx_get_name(priv->rtllib, info, wrqu, extra);
}
static int _rtl92e_wx_set_frag(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
struct r8192_priv *priv = rtllib_priv(dev);
if (priv->hw_radio_off)
return 0;
if (wrqu->frag.disabled) {
priv->rtllib->fts = DEFAULT_FRAG_THRESHOLD;
} else {
if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
wrqu->frag.value > MAX_FRAG_THRESHOLD)
return -EINVAL;
priv->rtllib->fts = wrqu->frag.value & ~0x1;
}
return 0;
}
static int _rtl92e_wx_get_frag(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
struct r8192_priv *priv = rtllib_priv(dev);
wrqu->frag.value = priv->rtllib->fts;
wrqu->frag.fixed = 0; /* no auto select */
wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
return 0;
}
static int _rtl92e_wx_set_wap(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *awrq, char *extra)
{
int ret;
struct r8192_priv *priv = rtllib_priv(dev);
if (priv->hw_radio_off)
return 0;
mutex_lock(&priv->wx_mutex);
ret = rtllib_wx_set_wap(priv->rtllib, info, awrq, extra);
mutex_unlock(&priv->wx_mutex);
return ret;
}
static int _rtl92e_wx_get_wap(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
struct r8192_priv *priv = rtllib_priv(dev);
return rtllib_wx_get_wap(priv->rtllib, info, wrqu, extra);
}
static int _rtl92e_wx_get_enc(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *key)
{
struct r8192_priv *priv = rtllib_priv(dev);
return rtllib_wx_get_encode(priv->rtllib, info, wrqu, key);
}
static int _rtl92e_wx_set_enc(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *key)
{
struct r8192_priv *priv = rtllib_priv(dev);
int ret;
struct rtllib_device *ieee = priv->rtllib;
u32 hwkey[4] = {0, 0, 0, 0};
u8 mask = 0xff;
u32 key_idx = 0;
u8 zero_addr[4][6] = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x03} };
int i;
if (priv->hw_radio_off)
return 0;
if (!priv->up)
return -ENETDOWN;
priv->rtllib->wx_set_enc = 1;
mutex_lock(&priv->rtllib->ips_mutex);
rtl92e_ips_leave(dev);
mutex_unlock(&priv->rtllib->ips_mutex);
mutex_lock(&priv->wx_mutex);
ret = rtllib_wx_set_encode(priv->rtllib, info, wrqu, key);
mutex_unlock(&priv->wx_mutex);
if (wrqu->encoding.flags & IW_ENCODE_DISABLED) {
ieee->pairwise_key_type = ieee->group_key_type = KEY_TYPE_NA;
rtl92e_cam_reset(dev);
memset(priv->rtllib->swcamtable, 0,
sizeof(struct sw_cam_table) * 32);
goto end_hw_sec;
}
if (wrqu->encoding.length != 0) {
for (i = 0; i < 4; i++) {
hwkey[i] |= key[4 * i + 0] & mask;
if (i == 1 && (4 * i + 1) == wrqu->encoding.length)
mask = 0x00;
if (i == 3 && (4 * i + 1) == wrqu->encoding.length)
mask = 0x00;
hwkey[i] |= (key[4 * i + 1] & mask) << 8;
hwkey[i] |= (key[4 * i + 2] & mask) << 16;
hwkey[i] |= (key[4 * i + 3] & mask) << 24;
}
switch (wrqu->encoding.flags & IW_ENCODE_INDEX) {
case 0:
key_idx = ieee->crypt_info.tx_keyidx;
break;
case 1:
key_idx = 0;
break;
case 2:
key_idx = 1;
break;
case 3:
key_idx = 2;
break;
case 4:
key_idx = 3;
break;
default:
break;
}
if (wrqu->encoding.length == 0x5) {
ieee->pairwise_key_type = KEY_TYPE_WEP40;
rtl92e_enable_hw_security_config(dev);
}
else if (wrqu->encoding.length == 0xd) {
ieee->pairwise_key_type = KEY_TYPE_WEP104;
rtl92e_enable_hw_security_config(dev);
rtl92e_set_key(dev, key_idx, key_idx, KEY_TYPE_WEP104,
zero_addr[key_idx], 0, hwkey);
rtl92e_set_swcam(dev, key_idx, key_idx, KEY_TYPE_WEP104,
zero_addr[key_idx], hwkey);
} else {
netdev_info(dev,
"wrong type in WEP, not WEP40 and WEP104\n");
}
}
end_hw_sec:
priv->rtllib->wx_set_enc = 0;
return ret;
}
#define R8192_MAX_RETRY 255
static int _rtl92e_wx_set_retry(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
struct r8192_priv *priv = rtllib_priv(dev);
int err = 0;
if (priv->hw_radio_off)
return 0;
mutex_lock(&priv->wx_mutex);
if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
wrqu->retry.disabled) {
err = -EINVAL;
goto exit;
}
if (!(wrqu->retry.flags & IW_RETRY_LIMIT)) {
err = -EINVAL;
goto exit;
}
if (wrqu->retry.value > R8192_MAX_RETRY) {
err = -EINVAL;
goto exit;
}
if (wrqu->retry.flags & IW_RETRY_MAX)
priv->retry_rts = wrqu->retry.value;
else
priv->retry_data = wrqu->retry.value;
rtl92e_commit(dev);
exit:
mutex_unlock(&priv->wx_mutex);
return err;
}
static int _rtl92e_wx_get_retry(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
struct r8192_priv *priv = rtllib_priv(dev);
wrqu->retry.disabled = 0; /* can't be disabled */
if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
IW_RETRY_LIFETIME)
return -EINVAL;
if (wrqu->retry.flags & IW_RETRY_MAX) {
wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
wrqu->retry.value = priv->retry_rts;
} else {
wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
wrqu->retry.value = priv->retry_data;
}
return 0;
}
static int _rtl92e_wx_set_encode_ext(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
int ret = 0;
struct r8192_priv *priv = rtllib_priv(dev);
struct rtllib_device *ieee = priv->rtllib;
if (priv->hw_radio_off)
return 0;
mutex_lock(&priv->wx_mutex);
priv->rtllib->wx_set_enc = 1;
mutex_lock(&priv->rtllib->ips_mutex);
rtl92e_ips_leave(dev);
mutex_unlock(&priv->rtllib->ips_mutex);
ret = rtllib_wx_set_encode_ext(ieee, info, wrqu, extra);
{
const u8 broadcast_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
const u8 zero[ETH_ALEN] = {0};
u32 key[4] = {0};
struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
struct iw_point *encoding = &wrqu->encoding;
u8 idx = 0, alg = 0, group = 0;
if ((encoding->flags & IW_ENCODE_DISABLED) ||
ext->alg == IW_ENCODE_ALG_NONE) {
ieee->pairwise_key_type = ieee->group_key_type
= KEY_TYPE_NA;
rtl92e_cam_reset(dev);
memset(priv->rtllib->swcamtable, 0,
sizeof(struct sw_cam_table) * 32);
goto end_hw_sec;
}
alg = (ext->alg == IW_ENCODE_ALG_CCMP) ? KEY_TYPE_CCMP :
ext->alg;
idx = encoding->flags & IW_ENCODE_INDEX;
if (idx)
idx--;
group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY;
if ((!group) || (alg == KEY_TYPE_WEP40)) {
if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40))
alg = KEY_TYPE_WEP104;
ieee->pairwise_key_type = alg;
rtl92e_enable_hw_security_config(dev);
}
memcpy((u8 *)key, ext->key, 16);
if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode != 2)) {
if (ext->key_len == 13)
ieee->pairwise_key_type = alg = KEY_TYPE_WEP104;
rtl92e_set_key(dev, idx, idx, alg, zero, 0, key);
rtl92e_set_swcam(dev, idx, idx, alg, zero, key);
} else if (group) {
ieee->group_key_type = alg;
rtl92e_set_key(dev, idx, idx, alg, broadcast_addr, 0,
key);
rtl92e_set_swcam(dev, idx, idx, alg, broadcast_addr, key);
} else {
if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) &&
ieee->ht_info->current_ht_support)
rtl92e_writeb(dev, 0x173, 1);
rtl92e_set_key(dev, 4, idx, alg,
(u8 *)ieee->ap_mac_addr, 0, key);
rtl92e_set_swcam(dev, 4, idx, alg, (u8 *)ieee->ap_mac_addr, key);
}
}
end_hw_sec:
priv->rtllib->wx_set_enc = 0;
mutex_unlock(&priv->wx_mutex);
return ret;
}
static int _rtl92e_wx_set_auth(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *data, char *extra)
{
int ret = 0;
struct r8192_priv *priv = rtllib_priv(dev);
if (priv->hw_radio_off)
return 0;
mutex_lock(&priv->wx_mutex);
ret = rtllib_wx_set_auth(priv->rtllib, info, &data->param, extra);
mutex_unlock(&priv->wx_mutex);
return ret;
}
static int _rtl92e_wx_set_mlme(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
int ret = 0;
struct r8192_priv *priv = rtllib_priv(dev);
if (priv->hw_radio_off)
return 0;
mutex_lock(&priv->wx_mutex);
ret = rtllib_wx_set_mlme(priv->rtllib, info, wrqu, extra);
mutex_unlock(&priv->wx_mutex);
return ret;
}
static int _rtl92e_wx_set_gen_ie(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *data, char *extra)
{
int ret = 0;
struct r8192_priv *priv = rtllib_priv(dev);
if (priv->hw_radio_off)
return 0;
mutex_lock(&priv->wx_mutex);
ret = rtllib_wx_set_gen_ie(priv->rtllib, extra, data->data.length);
mutex_unlock(&priv->wx_mutex);
return ret;
}
static int _rtl92e_wx_get_gen_ie(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *data, char *extra)
{
int ret = 0;
struct r8192_priv *priv = rtllib_priv(dev);
struct rtllib_device *ieee = priv->rtllib;
if (ieee->wpa_ie_len == 0 || !ieee->wpa_ie) {
data->data.length = 0;
return 0;
}
if (data->data.length < ieee->wpa_ie_len)
return -E2BIG;
data->data.length = ieee->wpa_ie_len;
memcpy(extra, ieee->wpa_ie, ieee->wpa_ie_len);
return ret;
}
#define IW_IOCTL(x) ((x) - SIOCSIWCOMMIT)
static iw_handler r8192_wx_handlers[] = {
[IW_IOCTL(SIOCGIWNAME)] = _rtl92e_wx_get_name,
[IW_IOCTL(SIOCSIWFREQ)] = _rtl92e_wx_set_freq,
[IW_IOCTL(SIOCGIWFREQ)] = _rtl92e_wx_get_freq,
[IW_IOCTL(SIOCSIWMODE)] = _rtl92e_wx_set_mode,
[IW_IOCTL(SIOCGIWMODE)] = _rtl92e_wx_get_mode,
[IW_IOCTL(SIOCGIWRANGE)] = _rtl92e_wx_get_range,
[IW_IOCTL(SIOCSIWAP)] = _rtl92e_wx_set_wap,
[IW_IOCTL(SIOCGIWAP)] = _rtl92e_wx_get_wap,
[IW_IOCTL(SIOCSIWSCAN)] = _rtl92e_wx_set_scan,
[IW_IOCTL(SIOCGIWSCAN)] = _rtl92e_wx_get_scan,
[IW_IOCTL(SIOCSIWESSID)] = _rtl92e_wx_set_essid,
[IW_IOCTL(SIOCGIWESSID)] = _rtl92e_wx_get_essid,
[IW_IOCTL(SIOCSIWNICKN)] = _rtl92e_wx_set_nick,
[IW_IOCTL(SIOCGIWNICKN)] = _rtl92e_wx_get_nick,
[IW_IOCTL(SIOCSIWRATE)] = _rtl92e_wx_set_rate,
[IW_IOCTL(SIOCGIWRATE)] = _rtl92e_wx_get_rate,
[IW_IOCTL(SIOCSIWRTS)] = _rtl92e_wx_set_rts,
[IW_IOCTL(SIOCGIWRTS)] = _rtl92e_wx_get_rts,
[IW_IOCTL(SIOCSIWFRAG)] = _rtl92e_wx_set_frag,
[IW_IOCTL(SIOCGIWFRAG)] = _rtl92e_wx_get_frag,
[IW_IOCTL(SIOCSIWRETRY)] = _rtl92e_wx_set_retry,
[IW_IOCTL(SIOCGIWRETRY)] = _rtl92e_wx_get_retry,
[IW_IOCTL(SIOCSIWENCODE)] = _rtl92e_wx_set_enc,
[IW_IOCTL(SIOCGIWENCODE)] = _rtl92e_wx_get_enc,
[IW_IOCTL(SIOCSIWPOWER)] = _rtl92e_wx_set_power,
[IW_IOCTL(SIOCGIWPOWER)] = _rtl92e_wx_get_power,
[IW_IOCTL(SIOCSIWGENIE)] = _rtl92e_wx_set_gen_ie,
[IW_IOCTL(SIOCGIWGENIE)] = _rtl92e_wx_get_gen_ie,
[IW_IOCTL(SIOCSIWMLME)] = _rtl92e_wx_set_mlme,
[IW_IOCTL(SIOCSIWAUTH)] = _rtl92e_wx_set_auth,
[IW_IOCTL(SIOCSIWENCODEEXT)] = _rtl92e_wx_set_encode_ext,
};
static struct iw_statistics *_rtl92e_get_wireless_stats(struct net_device *dev)
{
struct r8192_priv *priv = rtllib_priv(dev);
struct rtllib_device *ieee = priv->rtllib;
struct iw_statistics *wstats = &priv->wstats;
int tmp_level = 0;
int tmp_qual = 0;
int tmp_noise = 0;
if (ieee->link_state < MAC80211_LINKED) {
wstats->qual.qual = 10;
wstats->qual.level = 0;
wstats->qual.noise = 0x100 - 100; /* -100 dBm */
wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
return wstats;
}
tmp_level = (&ieee->current_network)->stats.rssi;
tmp_qual = (&ieee->current_network)->stats.signal;
tmp_noise = (&ieee->current_network)->stats.noise;
wstats->qual.level = tmp_level;
wstats->qual.qual = tmp_qual;
wstats->qual.noise = tmp_noise;
wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
return wstats;
}
const struct iw_handler_def r8192_wx_handlers_def = {
.standard = r8192_wx_handlers,
.num_standard = ARRAY_SIZE(r8192_wx_handlers),
.get_wireless_stats = _rtl92e_get_wireless_stats,
};

View File

@ -1,13 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Contact Information: wlanfae <wlanfae@realtek.com>
*/
#ifndef R819x_WX_H
#define R819x_WX_H
struct iw_handler_def;
extern const struct iw_handler_def r8192_wx_handlers_def;
#endif

View File

@ -1,543 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Contact Information: wlanfae <wlanfae@realtek.com>
*/
#include "table.h"
u32 RTL8192E_PHY_REG_1T2R_ARR[RTL8192E_PHY_REG_1T2R_ARR_LEN] = {
0x800, 0x00000000,
0x804, 0x00000001,
0x808, 0x0000fc00,
0x80c, 0x0000001c,
0x810, 0x801010aa,
0x814, 0x008514d0,
0x818, 0x00000040,
0x81c, 0x00000000,
0x820, 0x00000004,
0x824, 0x00690000,
0x828, 0x00000004,
0x82c, 0x00e90000,
0x830, 0x00000004,
0x834, 0x00690000,
0x838, 0x00000004,
0x83c, 0x00e90000,
0x840, 0x00000000,
0x844, 0x00000000,
0x848, 0x00000000,
0x84c, 0x00000000,
0x850, 0x00000000,
0x854, 0x00000000,
0x858, 0x65a965a9,
0x85c, 0x65a965a9,
0x860, 0x001f0010,
0x864, 0x007f0010,
0x868, 0x001f0010,
0x86c, 0x007f0010,
0x870, 0x0f100f70,
0x874, 0x0f100f70,
0x878, 0x00000000,
0x87c, 0x00000000,
0x880, 0x6870e36c,
0x884, 0xe3573600,
0x888, 0x4260c340,
0x88c, 0x0000ff00,
0x890, 0x00000000,
0x894, 0xfffffffe,
0x898, 0x4c42382f,
0x89c, 0x00656056,
0x8b0, 0x00000000,
0x8e0, 0x00000000,
0x8e4, 0x00000000,
0x900, 0x00000000,
0x904, 0x00000023,
0x908, 0x00000000,
0x90c, 0x31121311,
0xa00, 0x00d0c7d8,
0xa04, 0x811f0008,
0xa08, 0x80cd8300,
0xa0c, 0x2e62740f,
0xa10, 0x95009b78,
0xa14, 0x11145008,
0xa18, 0x00881117,
0xa1c, 0x89140fa0,
0xa20, 0x1a1b0000,
0xa24, 0x090e1317,
0xa28, 0x00000204,
0xa2c, 0x00000000,
0xc00, 0x00000040,
0xc04, 0x00005433,
0xc08, 0x000000e4,
0xc0c, 0x6c6c6c6c,
0xc10, 0x08800000,
0xc14, 0x40000100,
0xc18, 0x08000000,
0xc1c, 0x40000100,
0xc20, 0x08000000,
0xc24, 0x40000100,
0xc28, 0x08000000,
0xc2c, 0x40000100,
0xc30, 0x6de9ac44,
0xc34, 0x465c52cd,
0xc38, 0x497f5994,
0xc3c, 0x0a969764,
0xc40, 0x1f7c403f,
0xc44, 0x000100b7,
0xc48, 0xec020000,
0xc4c, 0x00000300,
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, 0x20000000,
0xc88, 0x40000100,
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, 0x00492492,
0xcc0, 0x00000000,
0xcc4, 0x00000000,
0xcc8, 0x00000000,
0xccc, 0x00000000,
0xcd0, 0x00000000,
0xcd4, 0x00000000,
0xcd8, 0x64b22427,
0xcdc, 0x00766932,
0xce0, 0x00222222,
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,
0xd4c, 0x00000000,
0xd50, 0x6437140a,
0xd54, 0x024dbd02,
0xd58, 0x00000000,
0xd5c, 0x04032064,
0xe00, 0x161a1a1a,
0xe04, 0x12121416,
0xe08, 0x00001800,
0xe0c, 0x00000000,
0xe10, 0x161a1a1a,
0xe14, 0x12121416,
0xe18, 0x161a1a1a,
0xe1c, 0x12121416,
};
u32 RTL8192E_RADIO_A_ARR[RTL8192E_RADIO_A_ARR_LEN] = {
0x019, 0x00000003,
0x000, 0x000000bf,
0x001, 0x00000ee0,
0x002, 0x0000004c,
0x003, 0x000007f1,
0x004, 0x00000975,
0x005, 0x00000c58,
0x006, 0x00000ae6,
0x007, 0x000000ca,
0x008, 0x00000e1c,
0x009, 0x000007f0,
0x00a, 0x000009d0,
0x00b, 0x000001ba,
0x00c, 0x00000240,
0x00e, 0x00000020,
0x00f, 0x00000990,
0x012, 0x00000806,
0x014, 0x000005ab,
0x015, 0x00000f80,
0x016, 0x00000020,
0x017, 0x00000597,
0x018, 0x0000050a,
0x01a, 0x00000f80,
0x01b, 0x00000f5e,
0x01c, 0x00000008,
0x01d, 0x00000607,
0x01e, 0x000006cc,
0x01f, 0x00000000,
0x020, 0x000001a5,
0x01f, 0x00000001,
0x020, 0x00000165,
0x01f, 0x00000002,
0x020, 0x000000c6,
0x01f, 0x00000003,
0x020, 0x00000086,
0x01f, 0x00000004,
0x020, 0x00000046,
0x01f, 0x00000005,
0x020, 0x000001e6,
0x01f, 0x00000006,
0x020, 0x000001a6,
0x01f, 0x00000007,
0x020, 0x00000166,
0x01f, 0x00000008,
0x020, 0x000000c7,
0x01f, 0x00000009,
0x020, 0x00000087,
0x01f, 0x0000000a,
0x020, 0x000000f7,
0x01f, 0x0000000b,
0x020, 0x000000d7,
0x01f, 0x0000000c,
0x020, 0x000000b7,
0x01f, 0x0000000d,
0x020, 0x00000097,
0x01f, 0x0000000e,
0x020, 0x00000077,
0x01f, 0x0000000f,
0x020, 0x00000057,
0x01f, 0x00000010,
0x020, 0x00000037,
0x01f, 0x00000011,
0x020, 0x000000fb,
0x01f, 0x00000012,
0x020, 0x000000db,
0x01f, 0x00000013,
0x020, 0x000000bb,
0x01f, 0x00000014,
0x020, 0x000000ff,
0x01f, 0x00000015,
0x020, 0x000000e3,
0x01f, 0x00000016,
0x020, 0x000000c3,
0x01f, 0x00000017,
0x020, 0x000000a3,
0x01f, 0x00000018,
0x020, 0x00000083,
0x01f, 0x00000019,
0x020, 0x00000063,
0x01f, 0x0000001a,
0x020, 0x00000043,
0x01f, 0x0000001b,
0x020, 0x00000023,
0x01f, 0x0000001c,
0x020, 0x00000003,
0x01f, 0x0000001d,
0x020, 0x000001e3,
0x01f, 0x0000001e,
0x020, 0x000001c3,
0x01f, 0x0000001f,
0x020, 0x000001a3,
0x01f, 0x00000020,
0x020, 0x00000183,
0x01f, 0x00000021,
0x020, 0x00000163,
0x01f, 0x00000022,
0x020, 0x00000143,
0x01f, 0x00000023,
0x020, 0x00000123,
0x01f, 0x00000024,
0x020, 0x00000103,
0x023, 0x00000203,
0x024, 0x00000100,
0x00b, 0x000001ba,
0x02c, 0x000003d7,
0x02d, 0x00000ff0,
0x000, 0x00000037,
0x004, 0x00000160,
0x007, 0x00000080,
0x002, 0x0000088d,
0x0fe, 0x00000000,
0x0fe, 0x00000000,
0x016, 0x00000200,
0x016, 0x00000380,
0x016, 0x00000020,
0x016, 0x000001a0,
0x000, 0x000000bf,
0x00d, 0x0000001f,
0x00d, 0x00000c9f,
0x002, 0x0000004d,
0x000, 0x00000cbf,
0x004, 0x00000975,
0x007, 0x00000700,
};
u32 RTL8192E_RADIO_B_ARR[RTL8192E_RADIO_B_ARR_LEN] = {
0x019, 0x00000003,
0x000, 0x000000bf,
0x001, 0x000006e0,
0x002, 0x0000004c,
0x003, 0x000007f1,
0x004, 0x00000975,
0x005, 0x00000c58,
0x006, 0x00000ae6,
0x007, 0x000000ca,
0x008, 0x00000e1c,
0x000, 0x000000b7,
0x00a, 0x00000850,
0x000, 0x000000bf,
0x00b, 0x000001ba,
0x00c, 0x00000240,
0x00e, 0x00000020,
0x015, 0x00000f80,
0x016, 0x00000020,
0x017, 0x00000597,
0x018, 0x0000050a,
0x01a, 0x00000e00,
0x01b, 0x00000f5e,
0x01d, 0x00000607,
0x01e, 0x000006cc,
0x00b, 0x000001ba,
0x023, 0x00000203,
0x024, 0x00000100,
0x000, 0x00000037,
0x004, 0x00000160,
0x016, 0x00000200,
0x016, 0x00000380,
0x016, 0x00000020,
0x016, 0x000001a0,
0x00d, 0x00000ccc,
0x000, 0x000000bf,
0x002, 0x0000004d,
0x000, 0x00000cbf,
0x004, 0x00000975,
0x007, 0x00000700,
};
u32 RTL8192E_MACPHY_ARR[] = {
0x03c, 0xffff0000, 0x00000f0f,
0x340, 0xffffffff, 0x161a1a1a,
0x344, 0xffffffff, 0x12121416,
0x348, 0x0000ffff, 0x00001818,
0x12c, 0xffffffff, 0x04000802,
0x318, 0x00000fff, 0x00000100,
};
u32 RTL8192E_MACPHY_ARR_PG[] = {
0x03c, 0xffff0000, 0x00000f0f,
0xe00, 0xffffffff, 0x06090909,
0xe04, 0xffffffff, 0x00030306,
0xe08, 0x0000ff00, 0x00000000,
0xe10, 0xffffffff, 0x0a0c0d0f,
0xe14, 0xffffffff, 0x06070809,
0xe18, 0xffffffff, 0x0a0c0d0f,
0xe1c, 0xffffffff, 0x06070809,
0x12c, 0xffffffff, 0x04000802,
0x318, 0x00000fff, 0x00000800,
};
u32 RTL8192E_AGCTAB_ARR[RTL8192E_AGCTAB_ARR_LEN] = {
0xc78, 0x7d000001,
0xc78, 0x7d010001,
0xc78, 0x7d020001,
0xc78, 0x7d030001,
0xc78, 0x7d040001,
0xc78, 0x7d050001,
0xc78, 0x7c060001,
0xc78, 0x7b070001,
0xc78, 0x7a080001,
0xc78, 0x79090001,
0xc78, 0x780a0001,
0xc78, 0x770b0001,
0xc78, 0x760c0001,
0xc78, 0x750d0001,
0xc78, 0x740e0001,
0xc78, 0x730f0001,
0xc78, 0x72100001,
0xc78, 0x71110001,
0xc78, 0x70120001,
0xc78, 0x6f130001,
0xc78, 0x6e140001,
0xc78, 0x6d150001,
0xc78, 0x6c160001,
0xc78, 0x6b170001,
0xc78, 0x6a180001,
0xc78, 0x69190001,
0xc78, 0x681a0001,
0xc78, 0x671b0001,
0xc78, 0x661c0001,
0xc78, 0x651d0001,
0xc78, 0x641e0001,
0xc78, 0x491f0001,
0xc78, 0x48200001,
0xc78, 0x47210001,
0xc78, 0x46220001,
0xc78, 0x45230001,
0xc78, 0x44240001,
0xc78, 0x43250001,
0xc78, 0x28260001,
0xc78, 0x27270001,
0xc78, 0x26280001,
0xc78, 0x25290001,
0xc78, 0x242a0001,
0xc78, 0x232b0001,
0xc78, 0x222c0001,
0xc78, 0x212d0001,
0xc78, 0x202e0001,
0xc78, 0x0a2f0001,
0xc78, 0x08300001,
0xc78, 0x06310001,
0xc78, 0x05320001,
0xc78, 0x04330001,
0xc78, 0x03340001,
0xc78, 0x02350001,
0xc78, 0x01360001,
0xc78, 0x00370001,
0xc78, 0x00380001,
0xc78, 0x00390001,
0xc78, 0x003a0001,
0xc78, 0x003b0001,
0xc78, 0x003c0001,
0xc78, 0x003d0001,
0xc78, 0x003e0001,
0xc78, 0x003f0001,
0xc78, 0x7d400001,
0xc78, 0x7d410001,
0xc78, 0x7d420001,
0xc78, 0x7d430001,
0xc78, 0x7d440001,
0xc78, 0x7d450001,
0xc78, 0x7c460001,
0xc78, 0x7b470001,
0xc78, 0x7a480001,
0xc78, 0x79490001,
0xc78, 0x784a0001,
0xc78, 0x774b0001,
0xc78, 0x764c0001,
0xc78, 0x754d0001,
0xc78, 0x744e0001,
0xc78, 0x734f0001,
0xc78, 0x72500001,
0xc78, 0x71510001,
0xc78, 0x70520001,
0xc78, 0x6f530001,
0xc78, 0x6e540001,
0xc78, 0x6d550001,
0xc78, 0x6c560001,
0xc78, 0x6b570001,
0xc78, 0x6a580001,
0xc78, 0x69590001,
0xc78, 0x685a0001,
0xc78, 0x675b0001,
0xc78, 0x665c0001,
0xc78, 0x655d0001,
0xc78, 0x645e0001,
0xc78, 0x495f0001,
0xc78, 0x48600001,
0xc78, 0x47610001,
0xc78, 0x46620001,
0xc78, 0x45630001,
0xc78, 0x44640001,
0xc78, 0x43650001,
0xc78, 0x28660001,
0xc78, 0x27670001,
0xc78, 0x26680001,
0xc78, 0x25690001,
0xc78, 0x246a0001,
0xc78, 0x236b0001,
0xc78, 0x226c0001,
0xc78, 0x216d0001,
0xc78, 0x206e0001,
0xc78, 0x0a6f0001,
0xc78, 0x08700001,
0xc78, 0x06710001,
0xc78, 0x05720001,
0xc78, 0x04730001,
0xc78, 0x03740001,
0xc78, 0x02750001,
0xc78, 0x01760001,
0xc78, 0x00770001,
0xc78, 0x00780001,
0xc78, 0x00790001,
0xc78, 0x007a0001,
0xc78, 0x007b0001,
0xc78, 0x007c0001,
0xc78, 0x007d0001,
0xc78, 0x007e0001,
0xc78, 0x007f0001,
0xc78, 0x2e00001e,
0xc78, 0x2e01001e,
0xc78, 0x2e02001e,
0xc78, 0x2e03001e,
0xc78, 0x2e04001e,
0xc78, 0x2e05001e,
0xc78, 0x3006001e,
0xc78, 0x3407001e,
0xc78, 0x3908001e,
0xc78, 0x3c09001e,
0xc78, 0x3f0a001e,
0xc78, 0x420b001e,
0xc78, 0x440c001e,
0xc78, 0x450d001e,
0xc78, 0x460e001e,
0xc78, 0x460f001e,
0xc78, 0x4710001e,
0xc78, 0x4811001e,
0xc78, 0x4912001e,
0xc78, 0x4a13001e,
0xc78, 0x4b14001e,
0xc78, 0x4b15001e,
0xc78, 0x4c16001e,
0xc78, 0x4d17001e,
0xc78, 0x4e18001e,
0xc78, 0x4f19001e,
0xc78, 0x4f1a001e,
0xc78, 0x501b001e,
0xc78, 0x511c001e,
0xc78, 0x521d001e,
0xc78, 0x521e001e,
0xc78, 0x531f001e,
0xc78, 0x5320001e,
0xc78, 0x5421001e,
0xc78, 0x5522001e,
0xc78, 0x5523001e,
0xc78, 0x5624001e,
0xc78, 0x5725001e,
0xc78, 0x5726001e,
0xc78, 0x5827001e,
0xc78, 0x5828001e,
0xc78, 0x5929001e,
0xc78, 0x592a001e,
0xc78, 0x5a2b001e,
0xc78, 0x5b2c001e,
0xc78, 0x5c2d001e,
0xc78, 0x5c2e001e,
0xc78, 0x5d2f001e,
0xc78, 0x5e30001e,
0xc78, 0x5f31001e,
0xc78, 0x6032001e,
0xc78, 0x6033001e,
0xc78, 0x6134001e,
0xc78, 0x6235001e,
0xc78, 0x6336001e,
0xc78, 0x6437001e,
0xc78, 0x6438001e,
0xc78, 0x6539001e,
0xc78, 0x663a001e,
0xc78, 0x673b001e,
0xc78, 0x673c001e,
0xc78, 0x683d001e,
0xc78, 0x693e001e,
0xc78, 0x6a3f001e,
};

View File

@ -1,27 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Contact Information: wlanfae <wlanfae@realtek.com>
*/
#ifndef __INC_HAL8192PciE_FW_IMG_H
#define __INC_HAL8192PciE_FW_IMG_H
/*Created on 2008/11/18, 3: 7*/
#include <linux/types.h>
#define RTL8192E_PHY_REG_1T2R_ARR_LEN 296
extern u32 RTL8192E_PHY_REG_1T2R_ARR[RTL8192E_PHY_REG_1T2R_ARR_LEN];
#define RTL8192E_RADIO_A_ARR_LEN 246
extern u32 RTL8192E_RADIO_A_ARR[RTL8192E_RADIO_A_ARR_LEN];
#define RTL8192E_RADIO_B_ARR_LEN 78
extern u32 RTL8192E_RADIO_B_ARR[RTL8192E_RADIO_B_ARR_LEN];
#define RTL8192E_MACPHY_ARR_LEN 18
extern u32 RTL8192E_MACPHY_ARR[RTL8192E_MACPHY_ARR_LEN];
#define RTL8192E_MACPHY_ARR_PG_LEN 30
extern u32 RTL8192E_MACPHY_ARR_PG[RTL8192E_MACPHY_ARR_PG_LEN];
#define RTL8192E_AGCTAB_ARR_LEN 384
extern u32 RTL8192E_AGCTAB_ARR[RTL8192E_AGCTAB_ARR_LEN];
#endif

View File

@ -1,60 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Contact Information: wlanfae <wlanfae@realtek.com>
*/
#ifndef _BATYPE_H_
#define _BATYPE_H_
#define BA_SETUP_TIMEOUT 200
#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_END_BA 37
#define DELBA_REASON_UNKNOWN_BA 38
#define DELBA_REASON_TIMEOUT 39
union sequence_control {
u16 short_data;
struct {
u16 frag_num:4;
u16 seq_num:12;
} field;
};
union ba_param_set {
u8 char_data[2];
u16 short_data;
struct {
u16 amsdu_support:1;
u16 ba_policy:1;
u16 tid:4;
u16 buffer_size:10;
} field;
};
union delba_param_set {
u8 char_data[2];
u16 short_data;
struct {
u16 reserved:11;
u16 initiator:1;
u16 tid:4;
} field;
};
struct ba_record {
struct timer_list timer;
u8 b_valid;
u8 dialog_token;
union ba_param_set ba_param_set;
u16 ba_timeout_value;
union sequence_control ba_start_seq_ctrl;
};
#endif

View File

@ -1,544 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Contact Information: wlanfae <wlanfae@realtek.com>
*/
#include <asm/byteorder.h>
#include <asm/unaligned.h>
#include <linux/etherdevice.h>
#include "rtllib.h"
#include "rtl819x_BA.h"
static void activate_ba_entry(struct ba_record *ba, u16 time)
{
ba->b_valid = true;
if (time != 0)
mod_timer(&ba->timer, jiffies + msecs_to_jiffies(time));
}
static void deactivate_ba_entry(struct rtllib_device *ieee, struct ba_record *ba)
{
ba->b_valid = false;
del_timer_sync(&ba->timer);
}
static u8 tx_ts_delete_ba(struct rtllib_device *ieee, struct tx_ts_record *ts)
{
struct ba_record *admitted_ba = &ts->tx_admitted_ba_record;
struct ba_record *pending_ba = &ts->tx_pending_ba_record;
u8 send_del_ba = false;
if (pending_ba->b_valid) {
deactivate_ba_entry(ieee, pending_ba);
send_del_ba = true;
}
if (admitted_ba->b_valid) {
deactivate_ba_entry(ieee, admitted_ba);
send_del_ba = true;
}
return send_del_ba;
}
static u8 rx_ts_delete_ba(struct rtllib_device *ieee, struct rx_ts_record *ts)
{
struct ba_record *ba = &ts->rx_admitted_ba_record;
u8 send_del_ba = false;
if (ba->b_valid) {
deactivate_ba_entry(ieee, ba);
send_del_ba = true;
}
return send_del_ba;
}
void rtllib_reset_ba_entry(struct ba_record *ba)
{
ba->b_valid = false;
ba->ba_param_set.short_data = 0;
ba->ba_timeout_value = 0;
ba->dialog_token = 0;
ba->ba_start_seq_ctrl.short_data = 0;
}
static struct sk_buff *rtllib_ADDBA(struct rtllib_device *ieee, u8 *dst,
struct ba_record *ba,
u16 status_code, u8 type)
{
struct sk_buff *skb = NULL;
struct ieee80211_hdr_3addr *ba_req = NULL;
u8 *tag = NULL;
u16 len = ieee->tx_headroom + 9;
netdev_dbg(ieee->dev, "%s(): frame(%d) sentd to: %pM, ieee->dev:%p\n",
__func__, type, dst, ieee->dev);
if (!ba) {
netdev_warn(ieee->dev, "ba is NULL\n");
return NULL;
}
skb = dev_alloc_skb(len + sizeof(struct ieee80211_hdr_3addr));
if (!skb)
return NULL;
memset(skb->data, 0, sizeof(struct ieee80211_hdr_3addr));
skb_reserve(skb, ieee->tx_headroom);
ba_req = skb_put(skb, sizeof(struct ieee80211_hdr_3addr));
ether_addr_copy(ba_req->addr1, dst);
ether_addr_copy(ba_req->addr2, ieee->dev->dev_addr);
ether_addr_copy(ba_req->addr3, ieee->current_network.bssid);
ba_req->frame_control = cpu_to_le16(IEEE80211_STYPE_ACTION);
tag = skb_put(skb, 9);
*tag++ = ACT_CAT_BA;
*tag++ = type;
*tag++ = ba->dialog_token;
if (type == ACT_ADDBARSP) {
put_unaligned_le16(status_code, tag);
tag += 2;
}
put_unaligned_le16(ba->ba_param_set.short_data, tag);
tag += 2;
put_unaligned_le16(ba->ba_timeout_value, tag);
tag += 2;
if (type == ACT_ADDBAREQ) {
memcpy(tag, (u8 *)&ba->ba_start_seq_ctrl, 2);
tag += 2;
}
#ifdef VERBOSE_DEBUG
print_hex_dump_bytes("%s: ", DUMP_PREFIX_NONE, skb->data,
__func__, skb->len);
#endif
return skb;
}
static struct sk_buff *rtllib_DELBA(struct rtllib_device *ieee, u8 *dst,
struct ba_record *ba,
enum tr_select tx_rx_select, u16 reason_code)
{
union delba_param_set del_ba_param_set;
struct sk_buff *skb = NULL;
struct ieee80211_hdr_3addr *del_ba = NULL;
u8 *tag = NULL;
u16 len = 6 + ieee->tx_headroom;
if (net_ratelimit())
netdev_dbg(ieee->dev, "%s(): reason_code(%d) sentd to: %pM\n",
__func__, reason_code, dst);
memset(&del_ba_param_set, 0, 2);
del_ba_param_set.field.initiator = (tx_rx_select == TX_DIR) ? 1 : 0;
del_ba_param_set.field.tid = ba->ba_param_set.field.tid;
skb = dev_alloc_skb(len + sizeof(struct ieee80211_hdr_3addr));
if (!skb)
return NULL;
skb_reserve(skb, ieee->tx_headroom);
del_ba = skb_put(skb, sizeof(struct ieee80211_hdr_3addr));
ether_addr_copy(del_ba->addr1, dst);
ether_addr_copy(del_ba->addr2, ieee->dev->dev_addr);
ether_addr_copy(del_ba->addr3, ieee->current_network.bssid);
del_ba->frame_control = cpu_to_le16(IEEE80211_STYPE_ACTION);
tag = skb_put(skb, 6);
*tag++ = ACT_CAT_BA;
*tag++ = ACT_DELBA;
put_unaligned_le16(del_ba_param_set.short_data, tag);
tag += 2;
put_unaligned_le16(reason_code, tag);
tag += 2;
#ifdef VERBOSE_DEBUG
print_hex_dump_bytes("%s: ", DUMP_PREFIX_NONE, skb->data,
__func__, skb->len);
#endif
return skb;
}
static void rtllib_send_add_ba_req(struct rtllib_device *ieee, u8 *dst,
struct ba_record *ba)
{
struct sk_buff *skb;
skb = rtllib_ADDBA(ieee, dst, ba, 0, ACT_ADDBAREQ);
if (skb)
softmac_mgmt_xmit(skb, ieee);
else
netdev_dbg(ieee->dev, "Failed to generate ADDBAReq packet.\n");
}
static void rtllib_send_add_ba_rsp(struct rtllib_device *ieee, u8 *dst,
struct ba_record *ba, u16 status_code)
{
struct sk_buff *skb;
skb = rtllib_ADDBA(ieee, dst, ba, status_code, ACT_ADDBARSP);
if (skb)
softmac_mgmt_xmit(skb, ieee);
else
netdev_dbg(ieee->dev, "Failed to generate ADDBARsp packet.\n");
}
static void rtllib_send_DELBA(struct rtllib_device *ieee, u8 *dst,
struct ba_record *ba, enum tr_select tx_rx_select,
u16 reason_code)
{
struct sk_buff *skb;
skb = rtllib_DELBA(ieee, dst, ba, tx_rx_select, reason_code);
if (skb)
softmac_mgmt_xmit(skb, ieee);
else
netdev_dbg(ieee->dev, "Failed to generate DELBA packet.\n");
}
int rtllib_rx_add_ba_req(struct rtllib_device *ieee, struct sk_buff *skb)
{
struct ieee80211_hdr_3addr *req = NULL;
u16 rc = 0;
u8 *dst = NULL, *dialog_token = NULL, *tag = NULL;
struct ba_record *ba = NULL;
union ba_param_set *ba_param_set = NULL;
u16 *ba_timeout_value = NULL;
union sequence_control *ba_start_seq_ctrl = NULL;
struct rx_ts_record *ts = NULL;
if (skb->len < sizeof(struct ieee80211_hdr_3addr) + 9) {
netdev_warn(ieee->dev, "Invalid skb len in BAREQ(%d / %d)\n",
(int)skb->len,
(int)(sizeof(struct ieee80211_hdr_3addr) + 9));
return -1;
}
#ifdef VERBOSE_DEBUG
print_hex_dump_bytes("%s: ", DUMP_PREFIX_NONE, __func__,
skb->data, skb->len);
#endif
req = (struct ieee80211_hdr_3addr *)skb->data;
tag = (u8 *)req;
dst = (u8 *)(&req->addr2[0]);
tag += sizeof(struct ieee80211_hdr_3addr);
dialog_token = tag + 2;
ba_param_set = (union ba_param_set *)(tag + 3);
ba_timeout_value = (u16 *)(tag + 5);
ba_start_seq_ctrl = (union sequence_control *)(req + 7);
if (!ieee->current_network.qos_data.active ||
!ieee->ht_info->current_ht_support ||
(ieee->ht_info->iot_action & HT_IOT_ACT_REJECT_ADDBA_REQ)) {
rc = ADDBA_STATUS_REFUSED;
netdev_warn(ieee->dev,
"Failed to reply on ADDBA_REQ as some capability is not ready(%d, %d)\n",
ieee->current_network.qos_data.active,
ieee->ht_info->current_ht_support);
goto on_add_ba_req_fail;
}
if (!rtllib_get_ts(ieee, (struct ts_common_info **)&ts, dst,
(u8)(ba_param_set->field.tid), RX_DIR, true)) {
rc = ADDBA_STATUS_REFUSED;
netdev_warn(ieee->dev, "%s(): can't get TS\n", __func__);
goto on_add_ba_req_fail;
}
ba = &ts->rx_admitted_ba_record;
if (ba_param_set->field.ba_policy == BA_POLICY_DELAYED) {
rc = ADDBA_STATUS_INVALID_PARAM;
netdev_warn(ieee->dev, "%s(): BA Policy is not correct\n",
__func__);
goto on_add_ba_req_fail;
}
rtllib_flush_rx_ts_pending_pkts(ieee, ts);
deactivate_ba_entry(ieee, ba);
ba->dialog_token = *dialog_token;
ba->ba_param_set = *ba_param_set;
ba->ba_timeout_value = *ba_timeout_value;
ba->ba_start_seq_ctrl = *ba_start_seq_ctrl;
if (ieee->get_half_nmode_support_by_aps_handler(ieee->dev) ||
(ieee->ht_info->iot_action & HT_IOT_ACT_ALLOW_PEER_AGG_ONE_PKT))
ba->ba_param_set.field.buffer_size = 1;
else
ba->ba_param_set.field.buffer_size = 32;
activate_ba_entry(ba, 0);
rtllib_send_add_ba_rsp(ieee, dst, ba, ADDBA_STATUS_SUCCESS);
return 0;
on_add_ba_req_fail:
{
struct ba_record BA;
BA.ba_param_set = *ba_param_set;
BA.ba_timeout_value = *ba_timeout_value;
BA.dialog_token = *dialog_token;
BA.ba_param_set.field.ba_policy = BA_POLICY_IMMEDIATE;
rtllib_send_add_ba_rsp(ieee, dst, &BA, rc);
return 0;
}
}
int rtllib_rx_add_ba_rsp(struct rtllib_device *ieee, struct sk_buff *skb)
{
struct ieee80211_hdr_3addr *rsp = NULL;
struct ba_record *pending_ba, *admitted_ba;
struct tx_ts_record *ts = NULL;
u8 *dst = NULL, *dialog_token = NULL, *tag = NULL;
u16 *status_code = NULL, *ba_timeout_value = NULL;
union ba_param_set *ba_param_set = NULL;
u16 reason_code;
if (skb->len < sizeof(struct ieee80211_hdr_3addr) + 9) {
netdev_warn(ieee->dev, "Invalid skb len in BARSP(%d / %d)\n",
(int)skb->len,
(int)(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);
dialog_token = tag + 2;
status_code = (u16 *)(tag + 3);
ba_param_set = (union ba_param_set *)(tag + 5);
ba_timeout_value = (u16 *)(tag + 7);
if (!ieee->current_network.qos_data.active ||
!ieee->ht_info->current_ht_support ||
!ieee->ht_info->current_ampdu_enable) {
netdev_warn(ieee->dev,
"reject to ADDBA_RSP as some capability is not ready(%d, %d, %d)\n",
ieee->current_network.qos_data.active,
ieee->ht_info->current_ht_support,
ieee->ht_info->current_ampdu_enable);
reason_code = DELBA_REASON_UNKNOWN_BA;
goto on_add_ba_rsp_reject;
}
if (!rtllib_get_ts(ieee, (struct ts_common_info **)&ts, dst,
(u8)(ba_param_set->field.tid), TX_DIR, false)) {
netdev_warn(ieee->dev, "%s(): can't get TS\n", __func__);
reason_code = DELBA_REASON_UNKNOWN_BA;
goto on_add_ba_rsp_reject;
}
ts->add_ba_req_in_progress = false;
pending_ba = &ts->tx_pending_ba_record;
admitted_ba = &ts->tx_admitted_ba_record;
if (admitted_ba->b_valid) {
netdev_dbg(ieee->dev, "%s(): ADDBA response already admitted\n",
__func__);
return -1;
} else if (!pending_ba->b_valid ||
(*dialog_token != pending_ba->dialog_token)) {
netdev_warn(ieee->dev,
"%s(): ADDBA Rsp. BA invalid, DELBA!\n",
__func__);
reason_code = DELBA_REASON_UNKNOWN_BA;
goto on_add_ba_rsp_reject;
} else {
netdev_dbg(ieee->dev,
"%s(): Recv ADDBA Rsp. BA is admitted! Status code:%X\n",
__func__, *status_code);
deactivate_ba_entry(ieee, pending_ba);
}
if (*status_code == ADDBA_STATUS_SUCCESS) {
if (ba_param_set->field.ba_policy == BA_POLICY_DELAYED) {
ts->add_ba_req_delayed = true;
deactivate_ba_entry(ieee, admitted_ba);
reason_code = DELBA_REASON_END_BA;
goto on_add_ba_rsp_reject;
}
admitted_ba->dialog_token = *dialog_token;
admitted_ba->ba_timeout_value = *ba_timeout_value;
admitted_ba->ba_start_seq_ctrl = pending_ba->ba_start_seq_ctrl;
admitted_ba->ba_param_set = *ba_param_set;
deactivate_ba_entry(ieee, admitted_ba);
activate_ba_entry(admitted_ba, *ba_timeout_value);
} else {
ts->add_ba_req_delayed = true;
ts->disable_add_ba = true;
reason_code = DELBA_REASON_END_BA;
goto on_add_ba_rsp_reject;
}
return 0;
on_add_ba_rsp_reject:
{
struct ba_record BA;
BA.ba_param_set = *ba_param_set;
rtllib_send_DELBA(ieee, dst, &BA, TX_DIR, reason_code);
return 0;
}
}
int rtllib_rx_DELBA(struct rtllib_device *ieee, struct sk_buff *skb)
{
struct ieee80211_hdr_3addr *delba = NULL;
union delba_param_set *del_ba_param_set = NULL;
u8 *dst = NULL;
if (skb->len < sizeof(struct ieee80211_hdr_3addr) + 6) {
netdev_warn(ieee->dev, "Invalid skb len in DELBA(%d / %d)\n",
(int)skb->len,
(int)(sizeof(struct ieee80211_hdr_3addr) + 6));
return -1;
}
if (!ieee->current_network.qos_data.active ||
!ieee->ht_info->current_ht_support) {
netdev_warn(ieee->dev,
"received DELBA while QOS or HT is not supported(%d, %d)\n",
ieee->current_network. qos_data.active,
ieee->ht_info->current_ht_support);
return -1;
}
#ifdef VERBOSE_DEBUG
print_hex_dump_bytes("%s: ", DUMP_PREFIX_NONE, skb->data,
__func__, skb->len);
#endif
delba = (struct ieee80211_hdr_3addr *)skb->data;
dst = (u8 *)(&delba->addr2[0]);
del_ba_param_set = (union delba_param_set *)&delba->seq_ctrl + 2;
if (del_ba_param_set->field.initiator == 1) {
struct rx_ts_record *ts;
if (!rtllib_get_ts(ieee, (struct ts_common_info **)&ts, dst,
(u8)del_ba_param_set->field.tid, RX_DIR, false)) {
netdev_warn(ieee->dev,
"%s(): can't get TS for RXTS. dst:%pM TID:%d\n",
__func__, dst,
(u8)del_ba_param_set->field.tid);
return -1;
}
rx_ts_delete_ba(ieee, ts);
} else {
struct tx_ts_record *ts;
if (!rtllib_get_ts(ieee, (struct ts_common_info **)&ts, dst,
(u8)del_ba_param_set->field.tid, TX_DIR, false)) {
netdev_warn(ieee->dev, "%s(): can't get TS for TXTS\n",
__func__);
return -1;
}
ts->using_ba = false;
ts->add_ba_req_in_progress = false;
ts->add_ba_req_delayed = false;
del_timer_sync(&ts->ts_add_ba_timer);
tx_ts_delete_ba(ieee, ts);
}
return 0;
}
void rtllib_ts_init_add_ba(struct rtllib_device *ieee, struct tx_ts_record *ts,
u8 policy, u8 overwrite_pending)
{
struct ba_record *ba = &ts->tx_pending_ba_record;
if (ba->b_valid && !overwrite_pending)
return;
deactivate_ba_entry(ieee, ba);
ba->dialog_token++;
ba->ba_param_set.field.amsdu_support = 0;
ba->ba_param_set.field.ba_policy = policy;
ba->ba_param_set.field.tid = ts->ts_common_info.tspec.ts_id;
ba->ba_param_set.field.buffer_size = 32;
ba->ba_timeout_value = 0;
ba->ba_start_seq_ctrl.field.seq_num = (ts->tx_cur_seq + 3) % 4096;
activate_ba_entry(ba, BA_SETUP_TIMEOUT);
rtllib_send_add_ba_req(ieee, ts->ts_common_info.addr, ba);
}
void rtllib_ts_init_del_ba(struct rtllib_device *ieee,
struct ts_common_info *ts_common_info,
enum tr_select tx_rx_select)
{
if (tx_rx_select == TX_DIR) {
struct tx_ts_record *ts =
(struct tx_ts_record *)ts_common_info;
if (tx_ts_delete_ba(ieee, ts))
rtllib_send_DELBA(ieee, ts_common_info->addr,
(ts->tx_admitted_ba_record.b_valid) ?
(&ts->tx_admitted_ba_record) :
(&ts->tx_pending_ba_record),
tx_rx_select, DELBA_REASON_END_BA);
} else if (tx_rx_select == RX_DIR) {
struct rx_ts_record *ts =
(struct rx_ts_record *)ts_common_info;
if (rx_ts_delete_ba(ieee, ts))
rtllib_send_DELBA(ieee, ts_common_info->addr,
&ts->rx_admitted_ba_record,
tx_rx_select, DELBA_REASON_END_BA);
}
}
void rtllib_ba_setup_timeout(struct timer_list *t)
{
struct tx_ts_record *ts = from_timer(ts, t,
tx_pending_ba_record.timer);
ts->add_ba_req_in_progress = false;
ts->add_ba_req_delayed = true;
ts->tx_pending_ba_record.b_valid = false;
}
void rtllib_tx_ba_inact_timeout(struct timer_list *t)
{
struct tx_ts_record *ts = from_timer(ts, t,
tx_admitted_ba_record.timer);
struct rtllib_device *ieee = container_of(ts, struct rtllib_device,
tx_ts_records[ts->num]);
tx_ts_delete_ba(ieee, ts);
rtllib_send_DELBA(ieee, ts->ts_common_info.addr,
&ts->tx_admitted_ba_record, TX_DIR,
DELBA_REASON_TIMEOUT);
}
void rtllib_rx_ba_inact_timeout(struct timer_list *t)
{
struct rx_ts_record *ts = from_timer(ts, t,
rx_admitted_ba_record.timer);
struct rtllib_device *ieee = container_of(ts, struct rtllib_device,
rx_ts_records[ts->num]);
rx_ts_delete_ba(ieee, ts);
rtllib_send_DELBA(ieee, ts->ts_common_info.addr,
&ts->rx_admitted_ba_record, RX_DIR,
DELBA_REASON_TIMEOUT);
}

View File

@ -1,223 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Contact Information: wlanfae <wlanfae@realtek.com>
*/
#ifndef _RTL819XU_HTTYPE_H_
#define _RTL819XU_HTTYPE_H_
#define MIMO_PS_STATIC 0
#define sHTCLng 4
enum ht_channel_width {
HT_CHANNEL_WIDTH_20 = 0,
HT_CHANNEL_WIDTH_20_40 = 1,
};
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,
};
struct ht_capab_ele {
u8 adv_coding:1;
u8 chl_width:1;
u8 mimo_pwr_save:2;
u8 green_field:1;
u8 short_gi_20mhz:1;
u8 short_gi_40mhz:1;
u8 tx_stbc:1;
u8 rx_stbc:2;
u8 delay_ba:1;
u8 max_amsdu_size:1;
u8 dss_cck:1;
u8 PSMP:1;
u8 Rsvd1:1;
u8 lsig_txop_protect:1;
u8 max_rx_ampdu_factor:2;
u8 mpdu_density:3;
u8 Rsvd2:3;
u8 MCS[16];
u16 ext_ht_cap_info;
u8 TxBFCap[4];
u8 ASCap;
} __packed;
struct ht_info_ele {
u8 ControlChl;
u8 ExtChlOffset:2;
u8 RecommemdedTxWidth:1;
u8 RIFS:1;
u8 PSMPAccessOnly:1;
u8 SrvIntGranularity:3;
u8 opt_mode: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];
} __packed;
enum ht_spec_ver {
HT_SPEC_VER_IEEE = 0,
HT_SPEC_VER_EWC = 1,
};
enum ht_aggre_mode {
HT_AGG_AUTO = 0,
HT_AGG_FORCE_ENABLE = 1,
HT_AGG_FORCE_DISABLE = 2,
};
struct rt_hi_throughput {
u8 enable_ht;
u8 current_ht_support;
u8 cur_bw_40mhz;
u8 cur_short_gi_40mhz;
u8 cur_short_gi_20mhz;
enum ht_spec_ver peer_ht_spec_ver;
struct ht_capab_ele self_ht_cap;
u8 peer_ht_cap_buf[32];
u8 peer_ht_info_buf[32];
u8 ampdu_enable;
u8 current_ampdu_enable;
u8 ampdu_factor;
u8 current_ampdu_factor;
u8 current_mpdu_density;
u8 forced_ampdu_factor;
u8 forced_mpdu_density;
u8 current_op_mode;
enum ht_extchnl_offset cur_sta_ext_chnl_offset;
u8 cur_tx_bw40mhz;
u8 sw_bw_in_progress;
u8 current_rt2rt_aggregation;
u8 current_rt2rt_long_slot_time;
u8 sz_rt2rt_agg_buf[10];
u8 cur_rx_reorder_enable;
u8 rx_reorder_win_size;
u8 rx_reorder_pending_time;
u16 rx_reorder_drop_counter;
u8 iot_peer;
u32 iot_action;
u8 iot_ra_func;
} __packed;
struct bss_ht {
u8 bd_support_ht;
u8 bd_ht_cap_buf[32];
u16 bd_ht_cap_len;
u8 bd_ht_info_buf[32];
u16 bd_ht_info_len;
enum ht_spec_ver bd_ht_spec_ver;
enum ht_channel_width bd_bandwidth;
u8 bd_rt2rt_aggregation;
u8 bd_rt2rt_long_slot_time;
u8 rt2rt_ht_mode;
u8 bd_ht_1r;
};
extern u8 MCS_FILTER_ALL[16];
extern u8 MCS_FILTER_1SS[16];
#define RATE_ADPT_1SS_MASK 0xFF
#define RATE_ADPT_2SS_MASK 0xF0
#define RATE_ADPT_MCS32_MASK 0x01
enum ht_aggre_size {
HT_AGG_SIZE_8K = 0,
HT_AGG_SIZE_16K = 1,
HT_AGG_SIZE_32K = 2,
HT_AGG_SIZE_64K = 3,
};
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_AIRGO = 10,
HT_IOT_PEER_MAX = 11,
};
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_ACT_DISABLE_RX_40MHZ_SHORT_GI = 0x08000000,
};
enum ht_iot_rafunc {
HT_IOT_RAFUNC_DISABLE_ALL = 0x00,
HT_IOT_RAFUNC_PEER_1R = 0x01,
HT_IOT_RAFUNC_TX_AMSDU = 0x02,
};
enum rt_ht_capability {
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,
};
#endif

View File

@ -1,699 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Contact Information: wlanfae <wlanfae@realtek.com>
*/
#include "rtllib.h"
#include "rtl819x_HT.h"
u8 MCS_FILTER_ALL[16] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
u8 MCS_FILTER_1SS[16] = {
0xff, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
;
u16 MCS_DATA_RATE[2][2][77] = {
{{13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78, 104, 156, 208, 234,
260, 39, 78, 117, 234, 312, 351, 390, 52, 104, 156, 208, 312, 416,
468, 520, 0, 78, 104, 130, 117, 156, 195, 104, 130, 130, 156, 182,
182, 208, 156, 195, 195, 234, 273, 273, 312, 130, 156, 181, 156,
181, 208, 234, 208, 234, 260, 260, 286, 195, 234, 273, 234, 273,
312, 351, 312, 351, 390, 390, 429},
{14, 29, 43, 58, 87, 116, 130, 144, 29, 58, 87, 116, 173, 231, 260, 289,
43, 87, 130, 173, 260, 347, 390, 433, 58, 116, 173, 231, 347, 462, 520,
578, 0, 87, 116, 144, 130, 173, 217, 116, 144, 144, 173, 202, 202, 231,
173, 217, 217, 260, 303, 303, 347, 144, 173, 202, 173, 202, 231, 260,
231, 260, 289, 289, 318, 217, 260, 303, 260, 303, 347, 390, 347, 390,
433, 433, 477} },
{{27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486,
540, 81, 162, 243, 324, 486, 648, 729, 810, 108, 216, 324, 432, 648,
864, 972, 1080, 12, 162, 216, 270, 243, 324, 405, 216, 270, 270, 324,
378, 378, 432, 324, 405, 405, 486, 567, 567, 648, 270, 324, 378, 324,
378, 432, 486, 432, 486, 540, 540, 594, 405, 486, 567, 486, 567, 648,
729, 648, 729, 810, 810, 891},
{30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540,
600, 90, 180, 270, 360, 540, 720, 810, 900, 120, 240, 360, 480, 720,
960, 1080, 1200, 13, 180, 240, 300, 270, 360, 450, 240, 300, 300, 360,
420, 420, 480, 360, 450, 450, 540, 630, 630, 720, 300, 360, 420, 360,
420, 480, 540, 480, 540, 600, 600, 660, 450, 540, 630, 540, 630, 720,
810, 720, 810, 900, 900, 990} }
};
static u8 UNKNOWN_BORADCOM[3] = {0x00, 0x14, 0xbf};
static u8 LINKSYSWRT330_LINKSYSWRT300_BROADCOM[3] = {0x00, 0x1a, 0x70};
static u8 LINKSYSWRT350_LINKSYSWRT150_BROADCOM[3] = {0x00, 0x1d, 0x7e};
static u8 BELKINF5D8233V1_RALINK[3] = {0x00, 0x17, 0x3f};
static u8 BELKINF5D82334V3_RALINK[3] = {0x00, 0x1c, 0xdf};
static u8 PCI_RALINK[3] = {0x00, 0x90, 0xcc};
static u8 EDIMAX_RALINK[3] = {0x00, 0x0e, 0x2e};
static u8 AIRLINK_RALINK[3] = {0x00, 0x18, 0x02};
static u8 DLINK_ATHEROS_1[3] = {0x00, 0x1c, 0xf0};
static u8 DLINK_ATHEROS_2[3] = {0x00, 0x21, 0x91};
static u8 CISCO_BROADCOM[3] = {0x00, 0x17, 0x94};
static u8 LINKSYS_MARVELL_4400N[3] = {0x00, 0x14, 0xa4};
void ht_update_default_setting(struct rtllib_device *ieee)
{
struct rt_hi_throughput *ht_info = ieee->ht_info;
ht_info->ampdu_enable = 1;
ht_info->ampdu_factor = 2;
ieee->tx_dis_rate_fallback = 0;
ieee->tx_use_drv_assinged_rate = 0;
ieee->tx_enable_fw_calc_dur = 1;
ht_info->rx_reorder_win_size = 64;
ht_info->rx_reorder_pending_time = 30;
}
static u16 ht_mcs_to_data_rate(struct rtllib_device *ieee, u8 mcs_rate)
{
struct rt_hi_throughput *ht_info = ieee->ht_info;
u8 is40MHz = (ht_info->cur_bw_40mhz) ? 1 : 0;
u8 isShortGI = (ht_info->cur_bw_40mhz) ?
((ht_info->cur_short_gi_40mhz) ? 1 : 0) :
((ht_info->cur_short_gi_20mhz) ? 1 : 0);
return MCS_DATA_RATE[is40MHz][isShortGI][(mcs_rate & 0x7f)];
}
u16 tx_count_to_data_rate(struct rtllib_device *ieee, u8 data_rate)
{
u16 cck_of_dm_rate[12] = {0x02, 0x04, 0x0b, 0x16, 0x0c, 0x12, 0x18,
0x24, 0x30, 0x48, 0x60, 0x6c};
u8 is40MHz = 0;
u8 isShortGI = 0;
if (data_rate < 12)
return cck_of_dm_rate[data_rate];
if (data_rate >= 0x10 && data_rate <= 0x1f) {
is40MHz = 0;
isShortGI = 0;
} else if (data_rate >= 0x20 && data_rate <= 0x2f) {
is40MHz = 1;
isShortGI = 0;
} else if (data_rate >= 0x30 && data_rate <= 0x3f) {
is40MHz = 0;
isShortGI = 1;
} else if (data_rate >= 0x40 && data_rate <= 0x4f) {
is40MHz = 1;
isShortGI = 1;
}
return MCS_DATA_RATE[is40MHz][isShortGI][data_rate & 0xf];
}
bool is_ht_half_nmode_aps(struct rtllib_device *ieee)
{
bool retValue = false;
struct rtllib_network *net = &ieee->current_network;
if ((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3) == 0) ||
(memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3) == 0) ||
(memcmp(net->bssid, PCI_RALINK, 3) == 0) ||
(memcmp(net->bssid, EDIMAX_RALINK, 3) == 0) ||
(memcmp(net->bssid, AIRLINK_RALINK, 3) == 0) ||
(net->ralink_cap_exist))
retValue = true;
else if (!memcmp(net->bssid, UNKNOWN_BORADCOM, 3) ||
!memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3) ||
!memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3) ||
(net->broadcom_cap_exist))
retValue = true;
else if (net->bssht.bd_rt2rt_aggregation)
retValue = true;
else
retValue = false;
return retValue;
}
static void ht_iot_peer_determine(struct rtllib_device *ieee)
{
struct rt_hi_throughput *ht_info = ieee->ht_info;
struct rtllib_network *net = &ieee->current_network;
if (net->bssht.bd_rt2rt_aggregation) {
ht_info->iot_peer = HT_IOT_PEER_REALTEK;
if (net->bssht.rt2rt_ht_mode & RT_HT_CAP_USE_92SE)
ht_info->iot_peer = HT_IOT_PEER_REALTEK_92SE;
if (net->bssht.rt2rt_ht_mode & RT_HT_CAP_USE_SOFTAP)
ht_info->iot_peer = HT_IOT_PEER_92U_SOFTAP;
} else if (net->broadcom_cap_exist) {
ht_info->iot_peer = HT_IOT_PEER_BROADCOM;
} else if (!memcmp(net->bssid, UNKNOWN_BORADCOM, 3) ||
!memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3) ||
!memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)) {
ht_info->iot_peer = HT_IOT_PEER_BROADCOM;
} else if ((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3) == 0) ||
(memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3) == 0) ||
(memcmp(net->bssid, PCI_RALINK, 3) == 0) ||
(memcmp(net->bssid, EDIMAX_RALINK, 3) == 0) ||
(memcmp(net->bssid, AIRLINK_RALINK, 3) == 0) ||
net->ralink_cap_exist) {
ht_info->iot_peer = HT_IOT_PEER_RALINK;
} else if ((net->atheros_cap_exist) ||
(memcmp(net->bssid, DLINK_ATHEROS_1, 3) == 0) ||
(memcmp(net->bssid, DLINK_ATHEROS_2, 3) == 0)) {
ht_info->iot_peer = HT_IOT_PEER_ATHEROS;
} else if ((memcmp(net->bssid, CISCO_BROADCOM, 3) == 0) ||
net->cisco_cap_exist) {
ht_info->iot_peer = HT_IOT_PEER_CISCO;
} else if ((memcmp(net->bssid, LINKSYS_MARVELL_4400N, 3) == 0) ||
net->marvell_cap_exist) {
ht_info->iot_peer = HT_IOT_PEER_MARVELL;
} else if (net->airgo_cap_exist) {
ht_info->iot_peer = HT_IOT_PEER_AIRGO;
} else {
ht_info->iot_peer = HT_IOT_PEER_UNKNOWN;
}
netdev_dbg(ieee->dev, "IOTPEER: %x\n", ht_info->iot_peer);
}
static u8 ht_iot_act_is_mgnt_use_cck_6m(struct rtllib_device *ieee,
struct rtllib_network *network)
{
u8 retValue = 0;
if (ieee->ht_info->iot_peer == HT_IOT_PEER_BROADCOM)
retValue = 1;
return retValue;
}
static u8 ht_iot_act_is_ccd_fsync(struct rtllib_device *ieee)
{
u8 retValue = 0;
if (ieee->ht_info->iot_peer == HT_IOT_PEER_BROADCOM)
retValue = 1;
return retValue;
}
static void ht_iot_act_determine_ra_func(struct rtllib_device *ieee, bool bPeerRx2ss)
{
struct rt_hi_throughput *ht_info = ieee->ht_info;
ht_info->iot_ra_func &= HT_IOT_RAFUNC_DISABLE_ALL;
if (ht_info->iot_peer == HT_IOT_PEER_RALINK && !bPeerRx2ss)
ht_info->iot_ra_func |= HT_IOT_RAFUNC_PEER_1R;
if (ht_info->iot_action & HT_IOT_ACT_AMSDU_ENABLE)
ht_info->iot_ra_func |= HT_IOT_RAFUNC_TX_AMSDU;
}
void ht_reset_iot_setting(struct rt_hi_throughput *ht_info)
{
ht_info->iot_action = 0;
ht_info->iot_peer = HT_IOT_PEER_UNKNOWN;
ht_info->iot_ra_func = 0;
}
void ht_construct_capability_element(struct rtllib_device *ieee, u8 *pos_ht_cap,
u8 *len, u8 is_encrypt, bool assoc)
{
struct rt_hi_throughput *ht = ieee->ht_info;
struct ht_capab_ele *cap_ele = NULL;
if (!pos_ht_cap || !ht) {
netdev_warn(ieee->dev,
"%s(): pos_ht_cap and ht_info are null\n", __func__);
return;
}
memset(pos_ht_cap, 0, *len);
if ((assoc) && (ht->peer_ht_spec_ver == HT_SPEC_VER_EWC)) {
static const u8 EWC11NHTCap[] = { 0x00, 0x90, 0x4c, 0x33 };
memcpy(pos_ht_cap, EWC11NHTCap, sizeof(EWC11NHTCap));
cap_ele = (struct ht_capab_ele *)&pos_ht_cap[4];
*len = 30 + 2;
} else {
cap_ele = (struct ht_capab_ele *)pos_ht_cap;
*len = 26 + 2;
}
cap_ele->adv_coding = 0;
if (ieee->get_half_nmode_support_by_aps_handler(ieee->dev))
cap_ele->chl_width = 0;
else
cap_ele->chl_width = 1;
cap_ele->mimo_pwr_save = 3;
cap_ele->green_field = 0;
cap_ele->short_gi_20mhz = 1;
cap_ele->short_gi_40mhz = 1;
cap_ele->tx_stbc = 1;
cap_ele->rx_stbc = 0;
cap_ele->delay_ba = 0;
cap_ele->max_amsdu_size = (MAX_RECEIVE_BUFFER_SIZE >= 7935) ? 1 : 0;
cap_ele->dss_cck = 1;
cap_ele->PSMP = 0;
cap_ele->lsig_txop_protect = 0;
netdev_dbg(ieee->dev,
"TX HT cap/info ele BW=%d max_amsdu_size:%d dss_cck:%d\n",
cap_ele->chl_width, cap_ele->max_amsdu_size, cap_ele->dss_cck);
if (is_encrypt) {
cap_ele->mpdu_density = 7;
cap_ele->max_rx_ampdu_factor = 2;
} else {
cap_ele->max_rx_ampdu_factor = 3;
cap_ele->mpdu_density = 0;
}
memcpy(cap_ele->MCS, ieee->reg_dot11ht_oper_rate_set, 16);
memset(&cap_ele->ext_ht_cap_info, 0, 2);
memset(cap_ele->TxBFCap, 0, 4);
cap_ele->ASCap = 0;
if (assoc) {
if (ht->iot_action & HT_IOT_ACT_DISABLE_MCS15)
cap_ele->MCS[1] &= 0x7f;
if (ht->iot_action & HT_IOT_ACT_DISABLE_MCS14)
cap_ele->MCS[1] &= 0xbf;
if (ht->iot_action & HT_IOT_ACT_DISABLE_ALL_2SS)
cap_ele->MCS[1] &= 0x00;
if (ht->iot_action & HT_IOT_ACT_DISABLE_RX_40MHZ_SHORT_GI)
cap_ele->short_gi_40mhz = 0;
if (ieee->get_half_nmode_support_by_aps_handler(ieee->dev)) {
cap_ele->chl_width = 0;
cap_ele->MCS[1] = 0;
}
}
}
void ht_construct_rt2rt_agg_element(struct rtllib_device *ieee, u8 *posRT2RTAgg,
u8 *len)
{
if (!posRT2RTAgg) {
netdev_warn(ieee->dev, "%s(): posRT2RTAgg is null\n", __func__);
return;
}
memset(posRT2RTAgg, 0, *len);
*posRT2RTAgg++ = 0x00;
*posRT2RTAgg++ = 0xe0;
*posRT2RTAgg++ = 0x4c;
*posRT2RTAgg++ = 0x02;
*posRT2RTAgg++ = 0x01;
*posRT2RTAgg = 0x30;
if (ieee->bSupportRemoteWakeUp)
*posRT2RTAgg |= RT_HT_CAP_USE_WOW;
*len = 6 + 2;
}
static u8 ht_pick_mcs_rate(struct rtllib_device *ieee, u8 *pOperateMCS)
{
u8 i;
if (!pOperateMCS) {
netdev_warn(ieee->dev, "%s(): pOperateMCS is null\n", __func__);
return false;
}
switch (ieee->mode) {
case WIRELESS_MODE_B:
case WIRELESS_MODE_G:
for (i = 0; i <= 15; i++)
pOperateMCS[i] = 0;
break;
case WIRELESS_MODE_N_24G:
pOperateMCS[0] &= RATE_ADPT_1SS_MASK;
pOperateMCS[1] &= RATE_ADPT_2SS_MASK;
pOperateMCS[3] &= RATE_ADPT_MCS32_MASK;
break;
default:
break;
}
return true;
}
u8 ht_get_highest_mcs_rate(struct rtllib_device *ieee, u8 *pMCSRateSet,
u8 *pMCSFilter)
{
u8 i, j;
u8 bitMap;
u8 mcsRate = 0;
u8 availableMcsRate[16];
if (!pMCSRateSet || !pMCSFilter) {
netdev_warn(ieee->dev,
"%s(): pMCSRateSet and pMCSFilter are null\n",
__func__);
return false;
}
for (i = 0; i < 16; i++)
availableMcsRate[i] = pMCSRateSet[i] & pMCSFilter[i];
for (i = 0; i < 16; i++) {
if (availableMcsRate[i] != 0)
break;
}
if (i == 16)
return false;
for (i = 0; i < 16; i++) {
if (availableMcsRate[i] != 0) {
bitMap = availableMcsRate[i];
for (j = 0; j < 8; j++) {
if ((bitMap % 2) != 0) {
if (ht_mcs_to_data_rate(ieee, (8 * i + j)) >
ht_mcs_to_data_rate(ieee, mcsRate))
mcsRate = 8 * i + j;
}
bitMap >>= 1;
}
}
}
return mcsRate | 0x80;
}
static u8 ht_filter_mcs_rate(struct rtllib_device *ieee, u8 *pSupportMCS,
u8 *pOperateMCS)
{
u8 i;
for (i = 0; i <= 15; i++)
pOperateMCS[i] = ieee->reg_dot11tx_ht_oper_rate_set[i] &
pSupportMCS[i];
ht_pick_mcs_rate(ieee, pOperateMCS);
if (ieee->get_half_nmode_support_by_aps_handler(ieee->dev))
pOperateMCS[1] = 0;
for (i = 2; i <= 15; i++)
pOperateMCS[i] = 0;
return true;
}
void ht_set_connect_bw_mode(struct rtllib_device *ieee,
enum ht_channel_width bandwidth,
enum ht_extchnl_offset Offset);
void ht_on_assoc_rsp(struct rtllib_device *ieee)
{
struct rt_hi_throughput *ht_info = ieee->ht_info;
struct ht_capab_ele *pPeerHTCap = NULL;
struct ht_info_ele *pPeerHTInfo = NULL;
u8 *pMcsFilter = NULL;
static const u8 EWC11NHTCap[] = { 0x00, 0x90, 0x4c, 0x33 };
static const u8 EWC11NHTInfo[] = { 0x00, 0x90, 0x4c, 0x34 };
if (!ht_info->current_ht_support) {
netdev_warn(ieee->dev, "%s(): HT_DISABLE\n", __func__);
return;
}
netdev_dbg(ieee->dev, "%s(): HT_ENABLE\n", __func__);
if (!memcmp(ht_info->peer_ht_cap_buf, EWC11NHTCap, sizeof(EWC11NHTCap)))
pPeerHTCap = (struct ht_capab_ele *)(&ht_info->peer_ht_cap_buf[4]);
else
pPeerHTCap = (struct ht_capab_ele *)(ht_info->peer_ht_cap_buf);
if (!memcmp(ht_info->peer_ht_info_buf, EWC11NHTInfo, sizeof(EWC11NHTInfo)))
pPeerHTInfo = (struct ht_info_ele *)
(&ht_info->peer_ht_info_buf[4]);
else
pPeerHTInfo = (struct ht_info_ele *)(ht_info->peer_ht_info_buf);
#ifdef VERBOSE_DEBUG
print_hex_dump_bytes("%s: ", __func__, DUMP_PREFIX_NONE,
pPeerHTCap, sizeof(struct ht_capab_ele));
#endif
ht_set_connect_bw_mode(ieee, (enum ht_channel_width)(pPeerHTCap->chl_width),
(enum ht_extchnl_offset)(pPeerHTInfo->ExtChlOffset));
ht_info->cur_tx_bw40mhz = ((pPeerHTInfo->RecommemdedTxWidth == 1) ?
true : false);
ht_info->cur_short_gi_20mhz = ((pPeerHTCap->short_gi_20mhz == 1) ? true : false);
ht_info->cur_short_gi_40mhz = ((pPeerHTCap->short_gi_40mhz == 1) ? true : false);
ht_info->current_ampdu_enable = ht_info->ampdu_enable;
if (ieee->rtllib_ap_sec_type &&
(ieee->rtllib_ap_sec_type(ieee) & (SEC_ALG_WEP | SEC_ALG_TKIP))) {
if ((ht_info->iot_peer == HT_IOT_PEER_ATHEROS) ||
(ht_info->iot_peer == HT_IOT_PEER_UNKNOWN))
ht_info->current_ampdu_enable = false;
}
if (ieee->current_network.bssht.bd_rt2rt_aggregation) {
if (ieee->pairwise_key_type != KEY_TYPE_NA)
ht_info->current_ampdu_factor =
pPeerHTCap->max_rx_ampdu_factor;
else
ht_info->current_ampdu_factor = HT_AGG_SIZE_64K;
} else {
ht_info->current_ampdu_factor = min_t(u32, pPeerHTCap->max_rx_ampdu_factor,
HT_AGG_SIZE_32K);
}
ht_info->current_mpdu_density = pPeerHTCap->mpdu_density;
if (ht_info->iot_action & HT_IOT_ACT_TX_USE_AMSDU_8K)
ht_info->current_ampdu_enable = false;
ht_info->cur_rx_reorder_enable = 1;
if (pPeerHTCap->MCS[0] == 0)
pPeerHTCap->MCS[0] = 0xff;
ht_iot_act_determine_ra_func(ieee, ((pPeerHTCap->MCS[1]) != 0));
ht_filter_mcs_rate(ieee, pPeerHTCap->MCS, ieee->dot11ht_oper_rate_set);
pMcsFilter = MCS_FILTER_ALL;
ieee->HTHighestOperaRate = ht_get_highest_mcs_rate(ieee,
ieee->dot11ht_oper_rate_set,
pMcsFilter);
ieee->ht_curr_op_rate = ieee->HTHighestOperaRate;
ht_info->current_op_mode = pPeerHTInfo->opt_mode;
}
void ht_initialize_ht_info(struct rtllib_device *ieee)
{
struct rt_hi_throughput *ht_info = ieee->ht_info;
ht_info->current_ht_support = false;
ht_info->cur_bw_40mhz = false;
ht_info->cur_tx_bw40mhz = false;
ht_info->cur_short_gi_20mhz = false;
ht_info->cur_short_gi_40mhz = false;
ht_info->current_mpdu_density = 0;
ht_info->current_ampdu_factor = ht_info->ampdu_factor;
memset((void *)(&ht_info->self_ht_cap), 0,
sizeof(ht_info->self_ht_cap));
memset((void *)(&ht_info->peer_ht_cap_buf), 0,
sizeof(ht_info->peer_ht_cap_buf));
memset((void *)(&ht_info->peer_ht_info_buf), 0,
sizeof(ht_info->peer_ht_info_buf));
ht_info->sw_bw_in_progress = false;
ht_info->peer_ht_spec_ver = HT_SPEC_VER_IEEE;
ht_info->current_rt2rt_aggregation = false;
ht_info->current_rt2rt_long_slot_time = false;
ht_info->iot_peer = 0;
ht_info->iot_action = 0;
ht_info->iot_ra_func = 0;
{
u8 *RegHTSuppRateSets = &ieee->reg_ht_supp_rate_set[0];
RegHTSuppRateSets[0] = 0xFF;
RegHTSuppRateSets[1] = 0xFF;
RegHTSuppRateSets[4] = 0x01;
}
}
void ht_initialize_bss_desc(struct bss_ht *bss_ht)
{
bss_ht->bd_support_ht = false;
memset(bss_ht->bd_ht_cap_buf, 0, sizeof(bss_ht->bd_ht_cap_buf));
bss_ht->bd_ht_cap_len = 0;
memset(bss_ht->bd_ht_info_buf, 0, sizeof(bss_ht->bd_ht_info_buf));
bss_ht->bd_ht_info_len = 0;
bss_ht->bd_ht_spec_ver = HT_SPEC_VER_IEEE;
bss_ht->bd_rt2rt_aggregation = false;
bss_ht->bd_rt2rt_long_slot_time = false;
bss_ht->rt2rt_ht_mode = (enum rt_ht_capability)0;
}
void ht_reset_self_and_save_peer_setting(struct rtllib_device *ieee,
struct rtllib_network *pNetwork)
{
struct rt_hi_throughput *ht_info = ieee->ht_info;
u8 bIOTAction = 0;
/* unmark enable_ht flag here is the same reason why unmarked in
* function rtllib_softmac_new_net. WB 2008.09.10
*/
if (pNetwork->bssht.bd_support_ht) {
ht_info->current_ht_support = true;
ht_info->peer_ht_spec_ver = pNetwork->bssht.bd_ht_spec_ver;
if (pNetwork->bssht.bd_ht_cap_len > 0 &&
pNetwork->bssht.bd_ht_cap_len <= sizeof(ht_info->peer_ht_cap_buf))
memcpy(ht_info->peer_ht_cap_buf,
pNetwork->bssht.bd_ht_cap_buf,
pNetwork->bssht.bd_ht_cap_len);
if (pNetwork->bssht.bd_ht_info_len > 0 &&
pNetwork->bssht.bd_ht_info_len <=
sizeof(ht_info->peer_ht_info_buf))
memcpy(ht_info->peer_ht_info_buf,
pNetwork->bssht.bd_ht_info_buf,
pNetwork->bssht.bd_ht_info_len);
ht_info->current_rt2rt_aggregation =
pNetwork->bssht.bd_rt2rt_aggregation;
ht_info->current_rt2rt_long_slot_time =
pNetwork->bssht.bd_rt2rt_long_slot_time;
ht_iot_peer_determine(ieee);
ht_info->iot_action = 0;
bIOTAction = ht_iot_act_is_mgnt_use_cck_6m(ieee, pNetwork);
if (bIOTAction)
ht_info->iot_action |= HT_IOT_ACT_MGNT_USE_CCK_6M;
bIOTAction = ht_iot_act_is_ccd_fsync(ieee);
if (bIOTAction)
ht_info->iot_action |= HT_IOT_ACT_CDD_FSYNC;
} else {
ht_info->current_ht_support = false;
ht_info->current_rt2rt_aggregation = false;
ht_info->current_rt2rt_long_slot_time = false;
ht_info->iot_action = 0;
ht_info->iot_ra_func = 0;
}
}
void HT_update_self_and_peer_setting(struct rtllib_device *ieee,
struct rtllib_network *pNetwork)
{
struct rt_hi_throughput *ht_info = ieee->ht_info;
struct ht_info_ele *pPeerHTInfo =
(struct ht_info_ele *)pNetwork->bssht.bd_ht_info_buf;
if (ht_info->current_ht_support) {
if (pNetwork->bssht.bd_ht_info_len != 0)
ht_info->current_op_mode = pPeerHTInfo->opt_mode;
}
}
EXPORT_SYMBOL(HT_update_self_and_peer_setting);
u8 ht_c_check(struct rtllib_device *ieee, u8 *pFrame)
{
if (ieee->ht_info->current_ht_support) {
if ((is_qos_data_frame(pFrame) && frame_order(pFrame)) == 1) {
netdev_dbg(ieee->dev, "HT CONTROL FILED EXIST!!\n");
return true;
}
}
return false;
}
static void ht_set_connect_bw_mode_callback(struct rtllib_device *ieee)
{
struct rt_hi_throughput *ht_info = ieee->ht_info;
if (ht_info->cur_bw_40mhz) {
if (ht_info->cur_sta_ext_chnl_offset == HT_EXTCHNL_OFFSET_UPPER)
ieee->set_chan(ieee->dev,
ieee->current_network.channel + 2);
else if (ht_info->cur_sta_ext_chnl_offset ==
HT_EXTCHNL_OFFSET_LOWER)
ieee->set_chan(ieee->dev,
ieee->current_network.channel - 2);
else
ieee->set_chan(ieee->dev,
ieee->current_network.channel);
ieee->set_bw_mode_handler(ieee->dev, HT_CHANNEL_WIDTH_20_40,
ht_info->cur_sta_ext_chnl_offset);
} else {
ieee->set_chan(ieee->dev, ieee->current_network.channel);
ieee->set_bw_mode_handler(ieee->dev, HT_CHANNEL_WIDTH_20,
HT_EXTCHNL_OFFSET_NO_EXT);
}
ht_info->sw_bw_in_progress = false;
}
void ht_set_connect_bw_mode(struct rtllib_device *ieee,
enum ht_channel_width bandwidth,
enum ht_extchnl_offset Offset)
{
struct rt_hi_throughput *ht_info = ieee->ht_info;
if (ieee->get_half_nmode_support_by_aps_handler(ieee->dev))
bandwidth = HT_CHANNEL_WIDTH_20;
if (ht_info->sw_bw_in_progress) {
pr_info("%s: sw_bw_in_progress!!\n", __func__);
return;
}
if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
if (ieee->current_network.channel < 2 &&
Offset == HT_EXTCHNL_OFFSET_LOWER)
Offset = HT_EXTCHNL_OFFSET_NO_EXT;
if (Offset == HT_EXTCHNL_OFFSET_UPPER ||
Offset == HT_EXTCHNL_OFFSET_LOWER) {
ht_info->cur_bw_40mhz = true;
ht_info->cur_sta_ext_chnl_offset = Offset;
} else {
ht_info->cur_bw_40mhz = false;
ht_info->cur_sta_ext_chnl_offset = HT_EXTCHNL_OFFSET_NO_EXT;
}
} else {
ht_info->cur_bw_40mhz = false;
ht_info->cur_sta_ext_chnl_offset = HT_EXTCHNL_OFFSET_NO_EXT;
}
netdev_dbg(ieee->dev, "%s():ht_info->bCurBW40MHz:%x\n", __func__,
ht_info->cur_bw_40mhz);
ht_info->sw_bw_in_progress = true;
ht_set_connect_bw_mode_callback(ieee);
}

View File

@ -1,43 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Contact Information: wlanfae <wlanfae@realtek.com>
*/
#ifndef __INC_QOS_TYPE_H
#define __INC_QOS_TYPE_H
struct qos_tsinfo {
u8 ts_id:4;
u8 ucDirection:2;
};
struct octet_string {
u8 *octet;
u16 Length;
};
#define AC0_BE 0
#define AC1_BK 1
#define AC2_VI 2
#define AC3_VO 3
enum direction_value {
DIR_UP = 0,
DIR_DOWN = 1,
DIR_DIRECT = 2,
DIR_BI_DIR = 3,
};
union aci_aifsn {
u8 charData;
struct {
u8 AIFSN:4;
u8 acm:1;
u8 ACI:2;
u8 Reserved:1;
} f;
};
#endif

View File

@ -1,50 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Contact Information: wlanfae <wlanfae@realtek.com>
*/
#ifndef _TSTYPE_H_
#define _TSTYPE_H_
#include "rtl819x_Qos.h"
#define TS_ADDBA_DELAY 60
#define TOTAL_TS_NUM 16
enum tr_select {
TX_DIR = 0,
RX_DIR = 1,
};
struct ts_common_info {
struct list_head list;
u8 addr[ETH_ALEN];
struct qos_tsinfo tspec;
};
struct tx_ts_record {
struct ts_common_info ts_common_info;
u16 tx_cur_seq;
struct ba_record tx_pending_ba_record;
struct ba_record tx_admitted_ba_record;
u8 add_ba_req_in_progress;
u8 add_ba_req_delayed;
u8 using_ba;
u8 disable_add_ba;
struct timer_list ts_add_ba_timer;
u8 num;
};
struct rx_ts_record {
struct ts_common_info ts_common_info;
u16 rx_indicate_seq;
u16 rx_timeout_indicate_seq;
struct list_head rx_pending_pkt_list;
struct timer_list rx_pkt_pending_timer;
struct ba_record rx_admitted_ba_record;
u16 rx_last_seq_num;
u8 rx_last_frag_num;
u8 num;
};
#endif

View File

@ -1,450 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
*
* Contact Information: wlanfae <wlanfae@realtek.com>
*/
#include "rtllib.h"
#include <linux/etherdevice.h>
#include "rtl819x_TS.h"
static void RxPktPendingTimeout(struct timer_list *t)
{
struct rx_ts_record *ts = from_timer(ts, t, rx_pkt_pending_timer);
struct rtllib_device *ieee = container_of(ts, struct rtllib_device,
rx_ts_records[ts->num]);
struct rx_reorder_entry *pReorderEntry = NULL;
unsigned long flags = 0;
u8 index = 0;
bool pkt_in_buf = false;
spin_lock_irqsave(&(ieee->reorder_spinlock), flags);
if (ts->rx_timeout_indicate_seq != 0xffff) {
while (!list_empty(&ts->rx_pending_pkt_list)) {
pReorderEntry = (struct rx_reorder_entry *)
list_entry(ts->rx_pending_pkt_list.prev,
struct rx_reorder_entry, list);
if (index == 0)
ts->rx_indicate_seq = pReorderEntry->SeqNum;
if (SN_LESS(pReorderEntry->SeqNum,
ts->rx_indicate_seq) ||
SN_EQUAL(pReorderEntry->SeqNum,
ts->rx_indicate_seq)) {
list_del_init(&pReorderEntry->list);
if (SN_EQUAL(pReorderEntry->SeqNum,
ts->rx_indicate_seq))
ts->rx_indicate_seq =
(ts->rx_indicate_seq + 1) % 4096;
netdev_dbg(ieee->dev,
"%s(): Indicate SeqNum: %d\n",
__func__, pReorderEntry->SeqNum);
ieee->stats_IndicateArray[index] =
pReorderEntry->prxb;
index++;
list_add_tail(&pReorderEntry->list,
&ieee->RxReorder_Unused_List);
} else {
pkt_in_buf = true;
break;
}
}
}
if (index > 0) {
ts->rx_timeout_indicate_seq = 0xffff;
if (index > REORDER_WIN_SIZE) {
netdev_warn(ieee->dev,
"%s(): Rx Reorder struct buffer full\n",
__func__);
spin_unlock_irqrestore(&(ieee->reorder_spinlock),
flags);
return;
}
rtllib_indicate_packets(ieee, ieee->stats_IndicateArray, index);
pkt_in_buf = false;
}
if (pkt_in_buf && (ts->rx_timeout_indicate_seq == 0xffff)) {
ts->rx_timeout_indicate_seq = ts->rx_indicate_seq;
mod_timer(&ts->rx_pkt_pending_timer, jiffies +
msecs_to_jiffies(ieee->ht_info->rx_reorder_pending_time)
);
}
spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
}
static void TsAddBaProcess(struct timer_list *t)
{
struct tx_ts_record *ts = from_timer(ts, t, ts_add_ba_timer);
u8 num = ts->num;
struct rtllib_device *ieee = container_of(ts, struct rtllib_device,
tx_ts_records[num]);
rtllib_ts_init_add_ba(ieee, ts, BA_POLICY_IMMEDIATE, false);
netdev_dbg(ieee->dev, "%s(): ADDBA Req is started\n", __func__);
}
static void ResetTsCommonInfo(struct ts_common_info *ts_common_info)
{
eth_zero_addr(ts_common_info->addr);
memset(&ts_common_info->tspec, 0, sizeof(struct qos_tsinfo));
}
static void ResetTxTsEntry(struct tx_ts_record *ts)
{
ResetTsCommonInfo(&ts->ts_common_info);
ts->tx_cur_seq = 0;
ts->add_ba_req_in_progress = false;
ts->add_ba_req_delayed = false;
ts->using_ba = false;
ts->disable_add_ba = false;
rtllib_reset_ba_entry(&ts->tx_admitted_ba_record);
rtllib_reset_ba_entry(&ts->tx_pending_ba_record);
}
static void ResetRxTsEntry(struct rx_ts_record *ts)
{
ResetTsCommonInfo(&ts->ts_common_info);
ts->rx_indicate_seq = 0xffff;
ts->rx_timeout_indicate_seq = 0xffff;
rtllib_reset_ba_entry(&ts->rx_admitted_ba_record);
}
void rtllib_ts_init(struct rtllib_device *ieee)
{
struct tx_ts_record *pTxTS = ieee->tx_ts_records;
struct rx_ts_record *rxts = ieee->rx_ts_records;
struct rx_reorder_entry *pRxReorderEntry = ieee->RxReorderEntry;
u8 count = 0;
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;
timer_setup(&pTxTS->ts_add_ba_timer, TsAddBaProcess, 0);
timer_setup(&pTxTS->tx_pending_ba_record.timer, rtllib_ba_setup_timeout,
0);
timer_setup(&pTxTS->tx_admitted_ba_record.timer,
rtllib_tx_ba_inact_timeout, 0);
ResetTxTsEntry(pTxTS);
list_add_tail(&pTxTS->ts_common_info.list,
&ieee->Tx_TS_Unused_List);
pTxTS++;
}
INIT_LIST_HEAD(&ieee->Rx_TS_Admit_List);
INIT_LIST_HEAD(&ieee->Rx_TS_Pending_List);
INIT_LIST_HEAD(&ieee->Rx_TS_Unused_List);
for (count = 0; count < TOTAL_TS_NUM; count++) {
rxts->num = count;
INIT_LIST_HEAD(&rxts->rx_pending_pkt_list);
timer_setup(&rxts->rx_admitted_ba_record.timer,
rtllib_rx_ba_inact_timeout, 0);
timer_setup(&rxts->rx_pkt_pending_timer, RxPktPendingTimeout, 0);
ResetRxTsEntry(rxts);
list_add_tail(&rxts->ts_common_info.list,
&ieee->Rx_TS_Unused_List);
rxts++;
}
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];
}
}
static struct ts_common_info *SearchAdmitTRStream(struct rtllib_device *ieee,
u8 *addr, u8 TID,
enum tr_select tx_rx_select)
{
u8 dir;
bool search_dir[4] = {0};
struct list_head *psearch_list;
struct ts_common_info *pRet = NULL;
if (tx_rx_select == 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 (tx_rx_select == 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])
continue;
list_for_each_entry(pRet, psearch_list, list) {
if (memcmp(pRet->addr, addr, 6) == 0 &&
pRet->tspec.ts_id == TID &&
pRet->tspec.ucDirection == dir)
break;
}
if (&pRet->list != psearch_list)
break;
}
if (pRet && &pRet->list != psearch_list)
return pRet;
return NULL;
}
static void MakeTSEntry(struct ts_common_info *ts_common_info, u8 *addr,
struct qos_tsinfo *pTSPEC)
{
if (!ts_common_info)
return;
memcpy(ts_common_info->addr, addr, 6);
if (pTSPEC)
memcpy((u8 *)(&(ts_common_info->tspec)), (u8 *)pTSPEC,
sizeof(struct qos_tsinfo));
}
bool rtllib_get_ts(struct rtllib_device *ieee, struct ts_common_info **ppTS,
u8 *addr, u8 TID, enum tr_select tx_rx_select, bool bAddNewTs)
{
u8 UP = 0;
struct qos_tsinfo tspec;
struct qos_tsinfo *ts_info = &tspec;
struct list_head *pUnusedList;
struct list_head *pAddmitList;
enum direction_value Dir;
if (is_multicast_ether_addr(addr)) {
netdev_warn(ieee->dev, "Get TS for Broadcast or Multicast\n");
return false;
}
if (ieee->current_network.qos_data.supported == 0) {
UP = 0;
} else {
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;
default:
netdev_warn(ieee->dev, "%s(): TID(%d) is not valid\n",
__func__, TID);
return false;
}
}
*ppTS = SearchAdmitTRStream(ieee, addr, UP, tx_rx_select);
if (*ppTS)
return true;
if (!bAddNewTs) {
netdev_dbg(ieee->dev, "add new TS failed(tid:%d)\n", UP);
return false;
}
pUnusedList = (tx_rx_select == TX_DIR) ?
(&ieee->Tx_TS_Unused_List) :
(&ieee->Rx_TS_Unused_List);
pAddmitList = (tx_rx_select == TX_DIR) ?
(&ieee->Tx_TS_Admit_List) :
(&ieee->Rx_TS_Admit_List);
Dir = ((tx_rx_select == TX_DIR) ? DIR_UP : DIR_DOWN);
if (!list_empty(pUnusedList)) {
(*ppTS) = list_entry(pUnusedList->next,
struct ts_common_info, list);
list_del_init(&(*ppTS)->list);
if (tx_rx_select == TX_DIR) {
struct tx_ts_record *tmp =
container_of(*ppTS,
struct tx_ts_record,
ts_common_info);
ResetTxTsEntry(tmp);
} else {
struct rx_ts_record *ts =
container_of(*ppTS,
struct rx_ts_record,
ts_common_info);
ResetRxTsEntry(ts);
}
netdev_dbg(ieee->dev,
"to init current TS, UP:%d, Dir:%d, addr: %pM ppTs=%p\n",
UP, Dir, addr, *ppTS);
ts_info->ts_id = UP;
ts_info->ucDirection = Dir;
MakeTSEntry(*ppTS, addr, &tspec);
list_add_tail(&((*ppTS)->list), pAddmitList);
return true;
}
netdev_warn(ieee->dev,
"There is not enough dir=%d(0=up down=1) TS record to be used!",
Dir);
return false;
}
static void RemoveTsEntry(struct rtllib_device *ieee,
struct ts_common_info *pTs, enum tr_select tx_rx_select)
{
rtllib_ts_init_del_ba(ieee, pTs, tx_rx_select);
if (tx_rx_select == RX_DIR) {
struct rx_reorder_entry *pRxReorderEntry;
struct rx_ts_record *ts = (struct rx_ts_record *)pTs;
if (timer_pending(&ts->rx_pkt_pending_timer))
del_timer_sync(&ts->rx_pkt_pending_timer);
while (!list_empty(&ts->rx_pending_pkt_list)) {
pRxReorderEntry = (struct rx_reorder_entry *)
list_entry(ts->rx_pending_pkt_list.prev,
struct rx_reorder_entry, list);
netdev_dbg(ieee->dev, "%s(): Delete SeqNum %d!\n",
__func__, pRxReorderEntry->SeqNum);
list_del_init(&pRxReorderEntry->list);
{
int i = 0;
struct rtllib_rxb *prxb = pRxReorderEntry->prxb;
if (unlikely(!prxb))
return;
for (i = 0; i < prxb->nr_subframes; i++)
dev_kfree_skb(prxb->subframes[i]);
kfree(prxb);
prxb = NULL;
}
list_add_tail(&pRxReorderEntry->list,
&ieee->RxReorder_Unused_List);
}
} else {
struct tx_ts_record *pTxTS = (struct tx_ts_record *)pTs;
del_timer_sync(&pTxTS->ts_add_ba_timer);
}
}
void remove_peer_ts(struct rtllib_device *ieee, u8 *addr)
{
struct ts_common_info *ts, *pTmpTS;
netdev_info(ieee->dev, "===========>%s, %pM\n", __func__, addr);
list_for_each_entry_safe(ts, pTmpTS, &ieee->Tx_TS_Pending_List, list) {
if (memcmp(ts->addr, addr, 6) == 0) {
RemoveTsEntry(ieee, ts, TX_DIR);
list_del_init(&ts->list);
list_add_tail(&ts->list, &ieee->Tx_TS_Unused_List);
}
}
list_for_each_entry_safe(ts, pTmpTS, &ieee->Tx_TS_Admit_List, list) {
if (memcmp(ts->addr, addr, 6) == 0) {
netdev_info(ieee->dev,
"====>remove Tx_TS_admin_list\n");
RemoveTsEntry(ieee, ts, TX_DIR);
list_del_init(&ts->list);
list_add_tail(&ts->list, &ieee->Tx_TS_Unused_List);
}
}
list_for_each_entry_safe(ts, pTmpTS, &ieee->Rx_TS_Pending_List, list) {
if (memcmp(ts->addr, addr, 6) == 0) {
RemoveTsEntry(ieee, ts, RX_DIR);
list_del_init(&ts->list);
list_add_tail(&ts->list, &ieee->Rx_TS_Unused_List);
}
}
list_for_each_entry_safe(ts, pTmpTS, &ieee->Rx_TS_Admit_List, list) {
if (memcmp(ts->addr, addr, 6) == 0) {
RemoveTsEntry(ieee, ts, RX_DIR);
list_del_init(&ts->list);
list_add_tail(&ts->list, &ieee->Rx_TS_Unused_List);
}
}
}
EXPORT_SYMBOL(remove_peer_ts);
void remove_all_ts(struct rtllib_device *ieee)
{
struct ts_common_info *ts, *pTmpTS;
list_for_each_entry_safe(ts, pTmpTS, &ieee->Tx_TS_Pending_List, list) {
RemoveTsEntry(ieee, ts, TX_DIR);
list_del_init(&ts->list);
list_add_tail(&ts->list, &ieee->Tx_TS_Unused_List);
}
list_for_each_entry_safe(ts, pTmpTS, &ieee->Tx_TS_Admit_List, list) {
RemoveTsEntry(ieee, ts, TX_DIR);
list_del_init(&ts->list);
list_add_tail(&ts->list, &ieee->Tx_TS_Unused_List);
}
list_for_each_entry_safe(ts, pTmpTS, &ieee->Rx_TS_Pending_List, list) {
RemoveTsEntry(ieee, ts, RX_DIR);
list_del_init(&ts->list);
list_add_tail(&ts->list, &ieee->Rx_TS_Unused_List);
}
list_for_each_entry_safe(ts, pTmpTS, &ieee->Rx_TS_Admit_List, list) {
RemoveTsEntry(ieee, ts, RX_DIR);
list_del_init(&ts->list);
list_add_tail(&ts->list, &ieee->Rx_TS_Unused_List);
}
}
void rtllib_ts_start_add_ba_process(struct rtllib_device *ieee, struct tx_ts_record *pTxTS)
{
if (pTxTS->add_ba_req_in_progress == false) {
pTxTS->add_ba_req_in_progress = true;
if (pTxTS->add_ba_req_delayed) {
netdev_dbg(ieee->dev, "Start ADDBA after 60 sec!!\n");
mod_timer(&pTxTS->ts_add_ba_timer, jiffies +
msecs_to_jiffies(TS_ADDBA_DELAY));
} else {
netdev_dbg(ieee->dev, "Immediately Start ADDBA\n");
mod_timer(&pTxTS->ts_add_ba_timer, jiffies + 10);
}
} else {
netdev_dbg(ieee->dev, "BA timer is already added\n");
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,411 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/* Host AP crypt: host-based CCMP encryption implementation for Host AP driver
*
* Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
*/
#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 <linux/string.h>
#include <linux/wireless.h>
#include "rtllib.h"
#include <linux/crypto.h>
#include <crypto/aead.h>
#include <linux/scatterlist.h>
#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 rtllib_ccmp_data {
u8 key[CCMP_TK_LEN];
int key_set;
u8 tx_pn[CCMP_PN_LEN];
u8 rx_pn[CCMP_PN_LEN];
u32 dot11rsna_stats_ccmp_format_errors;
u32 dot11rsna_stats_ccmp_replays;
u32 dot11rsna_stats_ccmp_decrypt_errors;
int key_idx;
struct crypto_aead *tfm;
/* scratch buffers for virt_to_page() (crypto API) */
u8 tx_aad[2 * AES_BLOCK_LEN];
u8 rx_aad[2 * AES_BLOCK_LEN];
};
static void *rtllib_ccmp_init(int key_idx)
{
struct rtllib_ccmp_data *priv;
priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
if (!priv)
goto fail;
priv->key_idx = key_idx;
priv->tfm = crypto_alloc_aead("ccm(aes)", 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(priv->tfm)) {
pr_debug("Could not allocate crypto API aes\n");
priv->tfm = NULL;
goto fail;
}
return priv;
fail:
if (priv) {
if (priv->tfm)
crypto_free_aead(priv->tfm);
kfree(priv);
}
return NULL;
}
static void rtllib_ccmp_deinit(void *priv)
{
struct rtllib_ccmp_data *_priv = priv;
if (_priv && _priv->tfm)
crypto_free_aead(_priv->tfm);
kfree(priv);
}
static int ccmp_init_iv_and_aad(struct ieee80211_hdr *hdr,
u8 *pn, u8 *iv, u8 *aad)
{
u8 *pos, qc = 0;
size_t aad_len;
u16 fc;
int a4_included, qc_included;
fc = le16_to_cpu(hdr->frame_control);
a4_included = ieee80211_has_a4(hdr->frame_control);
qc_included = ((WLAN_FC_GET_TYPE(fc) == RTLLIB_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;
}
/* In CCM, the initial vectors (IV) used for CTR mode encryption and CBC
* mode authentication are not allowed to collide, yet both are derived
* from the same vector. We only set L := 1 here to indicate that the
* data size can be represented in (L+1) bytes. The CCM layer will take
* care of storing the data length in the top (L+1) bytes and setting
* and clearing the other bits as is required to derive the two IVs.
*/
iv[0] = 0x1;
/* Nonce: QC | A2 | PN */
iv[1] = qc;
memcpy(iv + 2, hdr->addr2, ETH_ALEN);
memcpy(iv + 8, pn, CCMP_PN_LEN);
/* 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] = pos[0] & 0x8f;
aad[1] = pos[1] & 0xc7;
memcpy(&aad[2], &hdr->addr1, ETH_ALEN);
memcpy(&aad[8], &hdr->addr2, ETH_ALEN);
memcpy(&aad[14], &hdr->addr3, ETH_ALEN);
pos = (u8 *)&hdr->seq_ctrl;
aad[20] = pos[0] & 0x0f;
aad[21] = 0; /* all bits masked */
memset(aad + 22, 0, 8);
if (a4_included)
memcpy(aad + 22, hdr->addr4, ETH_ALEN);
if (qc_included) {
aad[a4_included ? 28 : 22] = qc;
/* rest of QC masked */
}
return aad_len;
}
static int rtllib_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
{
struct rtllib_ccmp_data *key = priv;
int i;
u8 *pos;
struct ieee80211_hdr *hdr;
struct cb_desc *tcb_desc = (struct 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;
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 *)skb->data;
if (!tcb_desc->hw_sec) {
struct aead_request *req;
struct scatterlist sg[2];
u8 *aad = key->tx_aad;
u8 iv[AES_BLOCK_LEN];
int aad_len, ret;
int data_len = skb->len - hdr_len - CCMP_HDR_LEN;
req = aead_request_alloc(key->tfm, GFP_ATOMIC);
if (!req)
return -ENOMEM;
aad_len = ccmp_init_iv_and_aad(hdr, key->tx_pn, iv, aad);
skb_put(skb, CCMP_MIC_LEN);
sg_init_table(sg, 2);
sg_set_buf(&sg[0], aad, aad_len);
sg_set_buf(&sg[1], skb->data + hdr_len + CCMP_HDR_LEN,
data_len + CCMP_MIC_LEN);
aead_request_set_callback(req, 0, NULL, NULL);
aead_request_set_ad(req, aad_len);
aead_request_set_crypt(req, sg, sg, data_len, iv);
ret = crypto_aead_encrypt(req);
aead_request_free(req);
return ret;
}
return 0;
}
static int rtllib_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
{
struct rtllib_ccmp_data *key = priv;
u8 keyidx, *pos;
struct ieee80211_hdr *hdr;
struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb +
MAX_DEV_ADDR_SIZE);
u8 pn[6];
if (skb->len < hdr_len + CCMP_HDR_LEN + CCMP_MIC_LEN) {
key->dot11rsna_stats_ccmp_format_errors++;
return -1;
}
hdr = (struct ieee80211_hdr *)skb->data;
pos = skb->data + hdr_len;
keyidx = pos[3];
if (!(keyidx & (1 << 5))) {
if (net_ratelimit()) {
pr_debug("CCMP: received packet without ExtIV flag from %pM\n",
hdr->addr2);
}
key->dot11rsna_stats_ccmp_format_errors++;
return -2;
}
keyidx >>= 6;
if (key->key_idx != keyidx) {
pr_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()) {
pr_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) {
key->dot11rsna_stats_ccmp_replays++;
return -4;
}
if (!tcb_desc->hw_sec) {
size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN;
struct aead_request *req;
struct scatterlist sg[2];
u8 *aad = key->rx_aad;
u8 iv[AES_BLOCK_LEN];
int aad_len, ret;
req = aead_request_alloc(key->tfm, GFP_ATOMIC);
if (!req)
return -ENOMEM;
aad_len = ccmp_init_iv_and_aad(hdr, pn, iv, aad);
sg_init_table(sg, 2);
sg_set_buf(&sg[0], aad, aad_len);
sg_set_buf(&sg[1], pos, data_len);
aead_request_set_callback(req, 0, NULL, NULL);
aead_request_set_ad(req, aad_len);
aead_request_set_crypt(req, sg, sg, data_len, iv);
ret = crypto_aead_decrypt(req);
aead_request_free(req);
if (ret) {
if (net_ratelimit()) {
pr_debug("CCMP: decrypt failed: STA= %pM\n",
hdr->addr2);
}
key->dot11rsna_stats_ccmp_decrypt_errors++;
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 rtllib_ccmp_set_key(void *key, int len, u8 *seq, void *priv)
{
struct rtllib_ccmp_data *data = priv;
int keyidx;
struct crypto_aead *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];
}
if (crypto_aead_setauthsize(data->tfm, CCMP_MIC_LEN) ||
crypto_aead_setkey(data->tfm, data->key, CCMP_TK_LEN))
return -1;
} else if (len == 0) {
data->key_set = 0;
} else {
return -1;
}
return 0;
}
static int rtllib_ccmp_get_key(void *key, int len, u8 *seq, void *priv)
{
struct rtllib_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 void rtllib_ccmp_print_stats(struct seq_file *m, void *priv)
{
struct rtllib_ccmp_data *ccmp = priv;
seq_printf(m,
"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->dot11rsna_stats_ccmp_format_errors,
ccmp->dot11rsna_stats_ccmp_replays,
ccmp->dot11rsna_stats_ccmp_decrypt_errors);
}
static const struct lib80211_crypto_ops rtllib_crypt_ccmp = {
.name = "R-CCMP",
.init = rtllib_ccmp_init,
.deinit = rtllib_ccmp_deinit,
.encrypt_mpdu = rtllib_ccmp_encrypt,
.decrypt_mpdu = rtllib_ccmp_decrypt,
.encrypt_msdu = NULL,
.decrypt_msdu = NULL,
.set_key = rtllib_ccmp_set_key,
.get_key = rtllib_ccmp_get_key,
.print_stats = rtllib_ccmp_print_stats,
.extra_mpdu_prefix_len = CCMP_HDR_LEN,
.extra_mpdu_postfix_len = CCMP_MIC_LEN,
.owner = THIS_MODULE,
};
static int __init rtllib_crypto_ccmp_init(void)
{
return lib80211_register_crypto_ops(&rtllib_crypt_ccmp);
}
static void __exit rtllib_crypto_ccmp_exit(void)
{
lib80211_unregister_crypto_ops(&rtllib_crypt_ccmp);
}
module_init(rtllib_crypto_ccmp_init);
module_exit(rtllib_crypto_ccmp_exit);
MODULE_DESCRIPTION("Support module for rtllib CCMP crypto");
MODULE_LICENSE("GPL");

View File

@ -1,712 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Host AP crypt: host-based TKIP encryption implementation for Host AP driver
*
* Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
*/
#include <crypto/arc4.h>
#include <crypto/hash.h>
#include <linux/fips.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 <linux/string.h>
#include <linux/crc32.h>
#include <linux/etherdevice.h>
#include "rtllib.h"
struct rtllib_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 arc4_ctx rx_ctx_arc4;
struct arc4_ctx tx_ctx_arc4;
struct crypto_shash *rx_tfm_michael;
struct crypto_shash *tx_tfm_michael;
/* scratch buffers for virt_to_page() (crypto API) */
u8 rx_hdr[16];
u8 tx_hdr[16];
};
static void *rtllib_tkip_init(int key_idx)
{
struct rtllib_tkip_data *priv;
if (fips_enabled)
return NULL;
priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
if (!priv)
goto fail;
priv->key_idx = key_idx;
priv->tx_tfm_michael = crypto_alloc_shash("michael_mic", 0, 0);
if (IS_ERR(priv->tx_tfm_michael)) {
pr_debug("Could not allocate crypto API michael_mic\n");
priv->tx_tfm_michael = NULL;
goto fail;
}
priv->rx_tfm_michael = crypto_alloc_shash("michael_mic", 0, 0);
if (IS_ERR(priv->rx_tfm_michael)) {
pr_debug("Could not allocate crypto API michael_mic\n");
priv->rx_tfm_michael = NULL;
goto fail;
}
return priv;
fail:
if (priv) {
crypto_free_shash(priv->tx_tfm_michael);
crypto_free_shash(priv->rx_tfm_michael);
kfree(priv);
}
return NULL;
}
static void rtllib_tkip_deinit(void *priv)
{
struct rtllib_tkip_data *_priv = priv;
if (_priv) {
crypto_free_shash(_priv->tx_tfm_michael);
crypto_free_shash(_priv->rx_tfm_michael);
}
kfree_sensitive(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 | (hi << 8);
}
static inline u16 Mk16_le(u16 *v)
{
return *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 rtllib_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
{
struct rtllib_tkip_data *tkey = priv;
int len;
u8 *pos;
struct ieee80211_hdr *hdr;
struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb +
MAX_DEV_ADDR_SIZE);
int ret = 0;
u8 rc4key[16], *icv;
u32 crc;
if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 ||
skb->len < hdr_len)
return -1;
hdr = (struct ieee80211_hdr *)skb->data;
if (!tcb_desc->hw_sec) {
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->hw_sec) {
*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->hw_sec) {
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;
arc4_setkey(&tkey->tx_ctx_arc4, rc4key, 16);
arc4_crypt(&tkey->tx_ctx_arc4, pos, pos, len + 4);
}
tkey->tx_iv16++;
if (tkey->tx_iv16 == 0) {
tkey->tx_phase1_done = 0;
tkey->tx_iv32++;
}
if (!tcb_desc->hw_sec)
return ret;
return 0;
}
static int rtllib_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
{
struct rtllib_tkip_data *tkey = priv;
u8 keyidx, *pos;
u32 iv32;
u16 iv16;
struct ieee80211_hdr *hdr;
struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb +
MAX_DEV_ADDR_SIZE);
u8 rc4key[16];
u8 icv[4];
u32 crc;
int plen;
if (skb->len < hdr_len + 8 + 4)
return -1;
hdr = (struct ieee80211_hdr *)skb->data;
pos = skb->data + hdr_len;
keyidx = pos[3];
if (!(keyidx & (1 << 5))) {
if (net_ratelimit()) {
netdev_dbg(skb->dev,
"Received packet without ExtIV flag from %pM\n",
hdr->addr2);
}
return -2;
}
keyidx >>= 6;
if (tkey->key_idx != keyidx) {
netdev_dbg(skb->dev,
"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()) {
netdev_dbg(skb->dev,
"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->hw_sec || (skb->cb[0] == 1)) {
if ((iv32 < tkey->rx_iv32 ||
(iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) &&
tkey->initialized) {
if (net_ratelimit()) {
netdev_dbg(skb->dev,
"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;
arc4_setkey(&tkey->rx_ctx_arc4, rc4key, 16);
arc4_crypt(&tkey->rx_ctx_arc4, pos, pos, plen + 4);
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()) {
netdev_dbg(skb->dev,
"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_shash *tfm_michael, u8 *key, u8 *hdr,
u8 *data, size_t data_len, u8 *mic)
{
SHASH_DESC_ON_STACK(desc, tfm_michael);
int err;
desc->tfm = tfm_michael;
if (crypto_shash_setkey(tfm_michael, key, 8))
return -1;
err = crypto_shash_init(desc);
if (err)
goto out;
err = crypto_shash_update(desc, hdr, 16);
if (err)
goto out;
err = crypto_shash_update(desc, data, data_len);
if (err)
goto out;
err = crypto_shash_final(desc, mic);
out:
shash_desc_zero(desc);
return err;
}
static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr)
{
struct ieee80211_hdr *hdr11;
hdr11 = (struct ieee80211_hdr *)skb->data;
switch (le16_to_cpu(hdr11->frame_control) &
(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
case IEEE80211_FCTL_TODS:
ether_addr_copy(hdr, hdr11->addr3); /* DA */
ether_addr_copy(hdr + ETH_ALEN, hdr11->addr2); /* SA */
break;
case IEEE80211_FCTL_FROMDS:
ether_addr_copy(hdr, hdr11->addr1); /* DA */
ether_addr_copy(hdr + ETH_ALEN, hdr11->addr3); /* SA */
break;
case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
ether_addr_copy(hdr, hdr11->addr3); /* DA */
ether_addr_copy(hdr + ETH_ALEN, hdr11->addr4); /* SA */
break;
case 0:
ether_addr_copy(hdr, hdr11->addr1); /* DA */
ether_addr_copy(hdr + ETH_ALEN, hdr11->addr2); /* SA */
break;
}
/* priority */
hdr[12] = 0;
/* reserved */
hdr[13] = 0;
hdr[14] = 0;
hdr[15] = 0;
}
static int rtllib_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv)
{
struct rtllib_tkip_data *tkey = priv;
u8 *pos;
struct ieee80211_hdr *hdr;
hdr = (struct ieee80211_hdr *)skb->data;
if (skb_tailroom(skb) < 8 || skb->len < hdr_len) {
netdev_dbg(skb->dev,
"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 (RTLLIB_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_control)))
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 rtllib_michael_mic_failure(struct net_device *dev,
struct ieee80211_hdr *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;
ether_addr_copy(ev.src_addr.sa_data, hdr->addr2);
memset(&wrqu, 0, sizeof(wrqu));
wrqu.data.length = sizeof(ev);
wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev);
}
static int rtllib_michael_mic_verify(struct sk_buff *skb, int keyidx,
int hdr_len, void *priv)
{
struct rtllib_tkip_data *tkey = priv;
u8 mic[8];
struct ieee80211_hdr *hdr;
hdr = (struct ieee80211_hdr *)skb->data;
if (!tkey->key_set)
return -1;
michael_mic_hdr(skb, tkey->rx_hdr);
if (RTLLIB_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_control)))
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 *hdr;
hdr = (struct ieee80211_hdr *)skb->data;
netdev_dbg(skb->dev,
"Michael MIC verification failed for MSDU from %pM keyidx=%d\n",
hdr->addr2, keyidx);
netdev_dbg(skb->dev, "%d\n",
memcmp(mic, skb->data + skb->len - 8, 8) != 0);
if (skb->dev) {
pr_info("skb->dev != NULL\n");
rtllib_michael_mic_failure(skb->dev, hdr, keyidx);
}
tkey->dot11RSNAStatsTKIPLocalMICFailures++;
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 rtllib_tkip_set_key(void *key, int len, u8 *seq, void *priv)
{
struct rtllib_tkip_data *tkey = priv;
int keyidx;
struct crypto_shash *tfm = tkey->tx_tfm_michael;
struct crypto_shash *tfm3 = tkey->rx_tfm_michael;
keyidx = tkey->key_idx;
memset(tkey, 0, sizeof(*tkey));
tkey->key_idx = keyidx;
tkey->tx_tfm_michael = tfm;
tkey->rx_tfm_michael = tfm3;
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 rtllib_tkip_get_key(void *key, int len, u8 *seq, void *priv)
{
struct rtllib_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 void rtllib_tkip_print_stats(struct seq_file *m, void *priv)
{
struct rtllib_tkip_data *tkip = priv;
seq_printf(m,
"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);
}
static const struct lib80211_crypto_ops rtllib_crypt_tkip = {
.name = "R-TKIP",
.init = rtllib_tkip_init,
.deinit = rtllib_tkip_deinit,
.encrypt_mpdu = rtllib_tkip_encrypt,
.decrypt_mpdu = rtllib_tkip_decrypt,
.encrypt_msdu = rtllib_michael_mic_add,
.decrypt_msdu = rtllib_michael_mic_verify,
.set_key = rtllib_tkip_set_key,
.get_key = rtllib_tkip_get_key,
.print_stats = rtllib_tkip_print_stats,
.extra_mpdu_prefix_len = 4 + 4, /* IV + ExtIV */
.extra_mpdu_postfix_len = 4, /* ICV */
.extra_msdu_postfix_len = 8, /* MIC */
.owner = THIS_MODULE,
};
static int __init rtllib_crypto_tkip_init(void)
{
return lib80211_register_crypto_ops(&rtllib_crypt_tkip);
}
static void __exit rtllib_crypto_tkip_exit(void)
{
lib80211_unregister_crypto_ops(&rtllib_crypt_tkip);
}
module_init(rtllib_crypto_tkip_init);
module_exit(rtllib_crypto_tkip_exit);
MODULE_DESCRIPTION("Support module for rtllib TKIP crypto");
MODULE_LICENSE("GPL");

View File

@ -1,242 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Host AP crypt: host-based WEP encryption implementation for Host AP driver
*
* Copyright (c) 2002-2004, Jouni Malinen <jkmaline@cc.hut.fi>
*/
#include <crypto/arc4.h>
#include <linux/fips.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/random.h>
#include <linux/skbuff.h>
#include <linux/string.h>
#include "rtllib.h"
#include <linux/crc32.h>
struct prism2_wep_data {
u32 iv;
#define WEP_KEY_LEN 13
u8 key[WEP_KEY_LEN + 1];
u8 key_len;
u8 key_idx;
struct arc4_ctx rx_ctx_arc4;
struct arc4_ctx tx_ctx_arc4;
};
static void *prism2_wep_init(int keyidx)
{
struct prism2_wep_data *priv;
if (fips_enabled)
return NULL;
priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
if (!priv)
return NULL;
priv->key_idx = keyidx;
/* start WEP IV from a random value */
get_random_bytes(&priv->iv, 4);
return priv;
}
static void prism2_wep_deinit(void *priv)
{
kfree_sensitive(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;
struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb +
MAX_DEV_ADDR_SIZE);
u32 crc;
u8 *icv;
if (skb_headroom(skb) < 4 || skb_tailroom(skb) < 4 ||
skb->len < hdr_len){
pr_err("Error!!! headroom=%d tailroom=%d skblen=%d hdr_len=%d\n",
skb_headroom(skb), skb_tailroom(skb), skb->len, hdr_len);
return -1;
}
len = skb->len - hdr_len;
pos = skb_push(skb, 4);
memmove(pos, pos + 4, hdr_len);
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->hw_sec) {
/* 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;
arc4_setkey(&wep->tx_ctx_arc4, key, klen);
arc4_crypt(&wep->tx_ctx_arc4, pos, pos, len + 4);
}
return 0;
}
/* Perform WEP decryption on given struct 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;
struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb +
MAX_DEV_ADDR_SIZE);
u32 crc;
u8 icv[4];
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->hw_sec) {
arc4_setkey(&wep->rx_ctx_arc4, key, klen);
arc4_crypt(&wep->rx_ctx_arc4, pos, pos, plen + 4);
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 void prism2_wep_print_stats(struct seq_file *m, void *priv)
{
struct prism2_wep_data *wep = priv;
seq_printf(m, "key[%d] alg=WEP len=%d\n", wep->key_idx, wep->key_len);
}
static const struct lib80211_crypto_ops rtllib_crypt_wep = {
.name = "R-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_mpdu_prefix_len = 4, /* IV */
.extra_mpdu_postfix_len = 4, /* ICV */
.owner = THIS_MODULE,
};
static int __init rtllib_crypto_wep_init(void)
{
return lib80211_register_crypto_ops(&rtllib_crypt_wep);
}
static void __exit rtllib_crypto_wep_exit(void)
{
lib80211_unregister_crypto_ops(&rtllib_crypt_wep);
}
module_init(rtllib_crypto_wep_init);
module_exit(rtllib_crypto_wep_exit);
MODULE_DESCRIPTION("Support module for rtllib WEP crypto");
MODULE_LICENSE("GPL");

View File

@ -1,179 +0,0 @@
// SPDX-License-Identifier: GPL-2.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>
*
* Contact Information:
* James P. Ketrenos <ipw2100-admin@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*/
#include <linux/compiler.h>
#include <linux/errno.h>
#include <linux/if_arp.h>
#include <linux/in6.h>
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/pci.h>
#include <linux/proc_fs.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/tcp.h>
#include <linux/types.h>
#include <linux/wireless.h>
#include <linux/etherdevice.h>
#include <linux/uaccess.h>
#include <net/arp.h>
#include "rtllib.h"
static inline int rtllib_networks_allocate(struct rtllib_device *ieee)
{
if (ieee->networks)
return 0;
ieee->networks = kcalloc(MAX_NETWORK_COUNT,
sizeof(struct rtllib_network), GFP_KERNEL);
if (!ieee->networks)
return -ENOMEM;
return 0;
}
static inline void rtllib_networks_free(struct rtllib_device *ieee)
{
if (!ieee->networks)
return;
kfree(ieee->networks);
ieee->networks = NULL;
}
static inline void rtllib_networks_initialize(struct rtllib_device *ieee)
{
int i;
INIT_LIST_HEAD(&ieee->network_free_list);
INIT_LIST_HEAD(&ieee->network_list);
for (i = 0; i < MAX_NETWORK_COUNT; i++)
list_add_tail(&ieee->networks[i].list,
&ieee->network_free_list);
}
struct net_device *alloc_rtllib(int sizeof_priv)
{
struct rtllib_device *ieee = NULL;
struct net_device *dev;
int i, err;
pr_debug("rtllib: Initializing...\n");
dev = alloc_etherdev(sizeof(struct rtllib_device) + sizeof_priv);
if (!dev) {
pr_err("Unable to allocate net_device.\n");
return NULL;
}
ieee = (struct rtllib_device *)netdev_priv_rsl(dev);
ieee->dev = dev;
err = rtllib_networks_allocate(ieee);
if (err) {
pr_err("Unable to allocate beacon storage: %d\n", err);
goto free_netdev;
}
rtllib_networks_initialize(ieee);
/* Default fragmentation threshold is maximum payload size */
ieee->fts = DEFAULT_FTS;
ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
ieee->open_wep = 1;
ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
ieee->rtllib_ap_sec_type = rtllib_ap_sec_type;
spin_lock_init(&ieee->lock);
spin_lock_init(&ieee->wpax_suitlist_lock);
spin_lock_init(&ieee->reorder_spinlock);
atomic_set(&ieee->atm_swbw, 0);
/* SAM FIXME */
lib80211_crypt_info_init(&ieee->crypt_info, "RTLLIB", &ieee->lock);
ieee->wpa_enabled = 0;
ieee->tkip_countermeasures = 0;
ieee->drop_unencrypted = 0;
ieee->privacy_invoked = 0;
ieee->ieee802_1x = 1;
ieee->hwsec_active = 0;
memset(ieee->swcamtable, 0, sizeof(struct sw_cam_table) * 32);
err = rtllib_softmac_init(ieee);
if (err)
goto free_crypt_info;
ieee->ht_info = kzalloc(sizeof(struct rt_hi_throughput), GFP_KERNEL);
if (!ieee->ht_info)
goto free_softmac;
ht_update_default_setting(ieee);
ht_initialize_ht_info(ieee);
rtllib_ts_init(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;
}
return dev;
free_softmac:
rtllib_softmac_free(ieee);
free_crypt_info:
lib80211_crypt_info_free(&ieee->crypt_info);
rtllib_networks_free(ieee);
free_netdev:
free_netdev(dev);
return NULL;
}
EXPORT_SYMBOL(alloc_rtllib);
void free_rtllib(struct net_device *dev)
{
struct rtllib_device *ieee = (struct rtllib_device *)
netdev_priv_rsl(dev);
kfree(ieee->ht_info);
rtllib_softmac_free(ieee);
lib80211_crypt_info_free(&ieee->crypt_info);
rtllib_networks_free(ieee);
free_netdev(dev);
}
EXPORT_SYMBOL(free_rtllib);
static int __init rtllib_init(void)
{
return 0;
}
static void __exit rtllib_exit(void)
{
}
module_init(rtllib_init);
module_exit(rtllib_exit);
MODULE_DESCRIPTION("Support module for rtllib wireless devices");
MODULE_LICENSE("GPL");

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,534 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/* IEEE 802.11 SoftMAC layer
* Copyright (c) 2005 Andrea Merello <andrea.merello@gmail.com>
*
* 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 ;-)
*/
#include <linux/etherdevice.h>
#include "rtllib.h"
int rtllib_wx_set_freq(struct rtllib_device *ieee, struct iw_request_info *a,
union iwreq_data *wrqu, char *b)
{
int ret;
struct iw_freq *fwrq = &wrqu->freq;
mutex_lock(&ieee->wx_mutex);
if (ieee->iw_mode == IW_MODE_INFRA) {
ret = 0;
goto out;
}
/* if setting by freq convert to channel */
if (fwrq->e == 1) {
if ((fwrq->m >= (int)2.412e8 &&
fwrq->m <= (int)2.487e8)) {
fwrq->m = ieee80211_freq_khz_to_channel(fwrq->m / 100);
fwrq->e = 0;
}
}
if (fwrq->e > 0 || fwrq->m > 14 || fwrq->m < 1) {
ret = -EOPNOTSUPP;
goto out;
} else { /* Set the channel */
if (ieee->active_channel_map[fwrq->m] != 1) {
ret = -EINVAL;
goto out;
}
ieee->current_network.channel = fwrq->m;
ieee->set_chan(ieee->dev, ieee->current_network.channel);
}
ret = 0;
out:
mutex_unlock(&ieee->wx_mutex);
return ret;
}
EXPORT_SYMBOL(rtllib_wx_set_freq);
int rtllib_wx_get_freq(struct rtllib_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;
fwrq->m = ieee80211_channel_to_freq_khz(ieee->current_network.channel,
NL80211_BAND_2GHZ) * 100;
fwrq->e = 1;
return 0;
}
EXPORT_SYMBOL(rtllib_wx_get_freq);
int rtllib_wx_get_wap(struct rtllib_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
unsigned long flags;
wrqu->ap_addr.sa_family = ARPHRD_ETHER;
if (ieee->iw_mode == IW_MODE_MONITOR)
return -1;
/* We want avoid to give to the user inconsistent infos*/
spin_lock_irqsave(&ieee->lock, flags);
if (ieee->link_state != MAC80211_LINKED &&
ieee->link_state != MAC80211_LINKED_SCANNING &&
ieee->wap_set == 0)
eth_zero_addr(wrqu->ap_addr.sa_data);
else
memcpy(wrqu->ap_addr.sa_data,
ieee->current_network.bssid, ETH_ALEN);
spin_unlock_irqrestore(&ieee->lock, flags);
return 0;
}
EXPORT_SYMBOL(rtllib_wx_get_wap);
int rtllib_wx_set_wap(struct rtllib_device *ieee,
struct iw_request_info *info,
union iwreq_data *awrq,
char *extra)
{
int ret = 0;
unsigned long flags;
short ifup = ieee->proto_started;
struct sockaddr *temp = (struct sockaddr *)awrq;
rtllib_stop_scan_syncro(ieee);
mutex_lock(&ieee->wx_mutex);
/* use ifconfig hw ether */
if (temp->sa_family != ARPHRD_ETHER) {
ret = -EINVAL;
goto out;
}
if (is_zero_ether_addr(temp->sa_data)) {
spin_lock_irqsave(&ieee->lock, flags);
ether_addr_copy(ieee->current_network.bssid, temp->sa_data);
ieee->wap_set = 0;
spin_unlock_irqrestore(&ieee->lock, flags);
ret = -1;
goto out;
}
if (ifup)
rtllib_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);
ieee->cannot_notify = false;
ether_addr_copy(ieee->current_network.bssid, temp->sa_data);
ieee->wap_set = !is_zero_ether_addr(temp->sa_data);
spin_unlock_irqrestore(&ieee->lock, flags);
if (ifup)
rtllib_start_protocol(ieee);
out:
mutex_unlock(&ieee->wx_mutex);
return ret;
}
EXPORT_SYMBOL(rtllib_wx_set_wap);
int rtllib_wx_get_essid(struct rtllib_device *ieee, struct iw_request_info *a,
union iwreq_data *wrqu, char *b)
{
int len, ret = 0;
unsigned long flags;
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->link_state != MAC80211_LINKED &&
ieee->link_state != MAC80211_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;
}
EXPORT_SYMBOL(rtllib_wx_get_essid);
int rtllib_wx_set_rate(struct rtllib_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
u32 target_rate = wrqu->bitrate.value;
ieee->rate = target_rate / 100000;
return 0;
}
EXPORT_SYMBOL(rtllib_wx_set_rate);
int rtllib_wx_get_rate(struct rtllib_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
u32 tmp_rate;
tmp_rate = tx_count_to_data_rate(ieee,
ieee->softmac_stats.CurrentShowTxate);
wrqu->bitrate.value = tmp_rate * 500000;
return 0;
}
EXPORT_SYMBOL(rtllib_wx_get_rate);
int rtllib_wx_set_rts(struct rtllib_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;
}
EXPORT_SYMBOL(rtllib_wx_set_rts);
int rtllib_wx_get_rts(struct rtllib_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;
}
EXPORT_SYMBOL(rtllib_wx_get_rts);
int rtllib_wx_set_mode(struct rtllib_device *ieee, struct iw_request_info *a,
union iwreq_data *wrqu, char *b)
{
int set_mode_status = 0;
rtllib_stop_scan_syncro(ieee);
mutex_lock(&ieee->wx_mutex);
switch (wrqu->mode) {
case IW_MODE_MONITOR:
case IW_MODE_INFRA:
break;
case IW_MODE_AUTO:
wrqu->mode = IW_MODE_INFRA;
break;
default:
set_mode_status = -EINVAL;
goto out;
}
if (wrqu->mode == ieee->iw_mode)
goto out;
if (wrqu->mode == IW_MODE_MONITOR) {
ieee->dev->type = ARPHRD_IEEE80211;
rtllib_enable_net_monitor_mode(ieee->dev, false);
} else {
ieee->dev->type = ARPHRD_ETHER;
if (ieee->iw_mode == IW_MODE_MONITOR)
rtllib_disable_net_monitor_mode(ieee->dev, false);
}
if (!ieee->proto_started) {
ieee->iw_mode = wrqu->mode;
} else {
rtllib_stop_protocol(ieee);
ieee->iw_mode = wrqu->mode;
rtllib_start_protocol(ieee);
}
out:
mutex_unlock(&ieee->wx_mutex);
return set_mode_status;
}
EXPORT_SYMBOL(rtllib_wx_set_mode);
void rtllib_wx_sync_scan_wq(void *data)
{
struct rtllib_device *ieee = container_of(data, struct rtllib_device, wx_sync_scan_wq);
short chan;
enum ht_extchnl_offset chan_offset = 0;
enum ht_channel_width bandwidth = 0;
int b40M = 0;
mutex_lock(&ieee->wx_mutex);
if (!(ieee->softmac_features & IEEE_SOFTMAC_SCAN)) {
rtllib_start_scan_syncro(ieee);
goto out;
}
chan = ieee->current_network.channel;
ieee->leisure_ps_leave(ieee->dev);
/* notify AP to be in PS mode */
rtllib_sta_ps_send_null_frame(ieee, 1);
rtllib_sta_ps_send_null_frame(ieee, 1);
rtllib_stop_all_queues(ieee);
ieee->link_state = MAC80211_LINKED_SCANNING;
ieee->link_change(ieee->dev);
/* wait for ps packet to be kicked out successfully */
msleep(50);
ieee->ScanOperationBackupHandler(ieee->dev, SCAN_OPT_BACKUP);
if (ieee->ht_info->current_ht_support && ieee->ht_info->enable_ht &&
ieee->ht_info->cur_bw_40mhz) {
b40M = 1;
chan_offset = ieee->ht_info->cur_sta_ext_chnl_offset;
bandwidth = (enum ht_channel_width)ieee->ht_info->cur_bw_40mhz;
ieee->set_bw_mode_handler(ieee->dev, HT_CHANNEL_WIDTH_20,
HT_EXTCHNL_OFFSET_NO_EXT);
}
rtllib_start_scan_syncro(ieee);
if (b40M) {
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->set_bw_mode_handler(ieee->dev, bandwidth, chan_offset);
} else {
ieee->set_chan(ieee->dev, chan);
}
ieee->ScanOperationBackupHandler(ieee->dev, SCAN_OPT_RESTORE);
ieee->link_state = MAC80211_LINKED;
ieee->link_change(ieee->dev);
/* Notify AP that I wake up again */
rtllib_sta_ps_send_null_frame(ieee, 0);
if (ieee->link_detect_info.num_recv_bcn_in_period == 0 ||
ieee->link_detect_info.num_recv_data_in_period == 0) {
ieee->link_detect_info.num_recv_bcn_in_period = 1;
ieee->link_detect_info.num_recv_data_in_period = 1;
}
rtllib_wake_all_queues(ieee);
out:
mutex_unlock(&ieee->wx_mutex);
}
int rtllib_wx_set_scan(struct rtllib_device *ieee, struct iw_request_info *a,
union iwreq_data *wrqu, char *b)
{
int ret = 0;
if (ieee->iw_mode == IW_MODE_MONITOR || !(ieee->proto_started)) {
ret = -1;
goto out;
}
if (ieee->link_state == MAC80211_LINKED) {
schedule_work(&ieee->wx_sync_scan_wq);
/* intentionally forget to up sem */
return 0;
}
out:
return ret;
}
EXPORT_SYMBOL(rtllib_wx_set_scan);
int rtllib_wx_set_essid(struct rtllib_device *ieee,
struct iw_request_info *a,
union iwreq_data *wrqu, char *extra)
{
int ret = 0, len;
short proto_started;
unsigned long flags;
rtllib_stop_scan_syncro(ieee);
mutex_lock(&ieee->wx_mutex);
proto_started = ieee->proto_started;
len = min_t(__u16, wrqu->essid.length, IW_ESSID_MAX_SIZE);
if (ieee->iw_mode == IW_MODE_MONITOR) {
ret = -1;
goto out;
}
if (proto_started)
rtllib_stop_protocol(ieee);
/* this is just to be sure that the GET wx callback
* has consistent infos. not needed otherwise
*/
spin_lock_irqsave(&ieee->lock, flags);
if (wrqu->essid.flags && wrqu->essid.length) {
strncpy(ieee->current_network.ssid, extra, len);
ieee->current_network.ssid_len = len;
ieee->cannot_notify = false;
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)
rtllib_start_protocol(ieee);
out:
mutex_unlock(&ieee->wx_mutex);
return ret;
}
EXPORT_SYMBOL(rtllib_wx_set_essid);
int rtllib_wx_get_mode(struct rtllib_device *ieee, struct iw_request_info *a,
union iwreq_data *wrqu, char *b)
{
wrqu->mode = ieee->iw_mode;
return 0;
}
EXPORT_SYMBOL(rtllib_wx_get_mode);
int rtllib_wx_get_name(struct rtllib_device *ieee, struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
const char *n = ieee->mode & (WIRELESS_MODE_N_24G) ? "n" : "";
scnprintf(wrqu->name, sizeof(wrqu->name), "802.11bg%s", n);
return 0;
}
EXPORT_SYMBOL(rtllib_wx_get_name);
/* this is mostly stolen from hostap */
int rtllib_wx_set_power(struct rtllib_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
int ret = 0;
if ((!ieee->sta_wake_up) ||
(!ieee->enter_sleep_state) ||
(!ieee->ps_is_queue_empty)) {
netdev_warn(ieee->dev,
"%s(): PS mode is tried to be use but driver missed a callback\n",
__func__);
return -1;
}
mutex_lock(&ieee->wx_mutex);
if (wrqu->power.disabled) {
ieee->ps = RTLLIB_PS_DISABLED;
goto exit;
}
if (wrqu->power.flags & IW_POWER_TIMEOUT)
ieee->ps_timeout = wrqu->power.value / 1000;
if (wrqu->power.flags & IW_POWER_PERIOD)
ieee->ps_period = wrqu->power.value / 1000;
switch (wrqu->power.flags & IW_POWER_MODE) {
case IW_POWER_UNICAST_R:
ieee->ps = RTLLIB_PS_UNICAST;
break;
case IW_POWER_MULTICAST_R:
ieee->ps = RTLLIB_PS_MBCAST;
break;
case IW_POWER_ALL_R:
ieee->ps = RTLLIB_PS_UNICAST | RTLLIB_PS_MBCAST;
break;
case IW_POWER_ON:
break;
default:
ret = -EINVAL;
goto exit;
}
exit:
mutex_unlock(&ieee->wx_mutex);
return ret;
}
EXPORT_SYMBOL(rtllib_wx_set_power);
/* this is stolen from hostap */
int rtllib_wx_get_power(struct rtllib_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
mutex_lock(&ieee->wx_mutex);
if (ieee->ps == RTLLIB_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 {
wrqu->power.flags = IW_POWER_PERIOD;
wrqu->power.value = ieee->ps_period * 1000;
}
if ((ieee->ps & (RTLLIB_PS_MBCAST | RTLLIB_PS_UNICAST)) ==
(RTLLIB_PS_MBCAST | RTLLIB_PS_UNICAST))
wrqu->power.flags |= IW_POWER_ALL_R;
else if (ieee->ps & RTLLIB_PS_MBCAST)
wrqu->power.flags |= IW_POWER_MULTICAST_R;
else
wrqu->power.flags |= IW_POWER_UNICAST_R;
exit:
mutex_unlock(&ieee->wx_mutex);
return 0;
}
EXPORT_SYMBOL(rtllib_wx_get_power);

View File

@ -1,901 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
*
* 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 <andrea.merello@gmail.com>
*
* 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 <linux/uaccess.h>
#include <linux/if_vlan.h>
#include "rtllib.h"
/* 802.11 Data Frame
*
*
* 802.11 frame_control 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 |DS | DS |frag| | mgm |data | |
* | | | x=1 data+ack | | | | | | | |
* '--------------------------------------------------------------------'
* /\
* |
* 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 int rtllib_put_snap(u8 *data, u16 h_proto)
{
struct rtllib_snap_hdr *snap;
u8 *oui;
snap = (struct rtllib_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];
*(__be16 *)(data + SNAP_SIZE) = htons(h_proto);
return SNAP_SIZE + sizeof(u16);
}
int rtllib_encrypt_fragment(struct rtllib_device *ieee, struct sk_buff *frag,
int hdr_len)
{
struct lib80211_crypt_data *crypt = NULL;
int res;
crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
if (!(crypt && crypt->ops)) {
netdev_info(ieee->dev, "=========>%s(), crypt is null\n",
__func__);
return -1;
}
/* 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) {
netdev_info(ieee->dev, "%s: Encryption failed: len=%d.\n",
ieee->dev->name, frag->len);
return -1;
}
return 0;
}
void rtllib_txb_free(struct rtllib_txb *txb)
{
if (unlikely(!txb))
return;
kfree(txb);
}
static struct rtllib_txb *rtllib_alloc_txb(int nr_frags, int txb_size,
gfp_t gfp_mask)
{
struct rtllib_txb *txb;
int i;
txb = kzalloc(struct_size(txb, fragments, nr_frags), gfp_mask);
if (!txb)
return NULL;
txb->nr_frags = nr_frags;
txb->frag_size = cpu_to_le16(txb_size);
for (i = 0; i < nr_frags; i++) {
txb->fragments[i] = dev_alloc_skb(txb_size);
if (unlikely(!txb->fragments[i]))
goto err_free;
memset(txb->fragments[i]->cb, 0, sizeof(txb->fragments[i]->cb));
}
return txb;
err_free:
while (--i >= 0)
dev_kfree_skb_any(txb->fragments[i]);
kfree(txb);
return NULL;
}
static int rtllib_classify(struct sk_buff *skb)
{
struct ethhdr *eth;
struct iphdr *ip;
eth = (struct ethhdr *)skb->data;
if (eth->h_proto != htons(ETH_P_IP))
return 0;
#ifdef VERBOSE_DEBUG
print_hex_dump_bytes("%s: ", __func__, DUMP_PREFIX_NONE, skb->data,
skb->len);
#endif
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;
}
}
static void rtllib_tx_query_agg_cap(struct rtllib_device *ieee,
struct sk_buff *skb,
struct cb_desc *tcb_desc)
{
struct rt_hi_throughput *ht_info = ieee->ht_info;
struct tx_ts_record *ts = NULL;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
if (rtllib_act_scanning(ieee, false))
return;
if (!ht_info->current_ht_support || !ht_info->enable_ht)
return;
if (!is_qos_data_frame(skb->data))
return;
if (is_multicast_ether_addr(hdr->addr1))
return;
if (tcb_desc->bdhcp || ieee->cnt_after_link < 2)
return;
if (ht_info->iot_action & HT_IOT_ACT_TX_NO_AGGREGATION)
return;
if (!ieee->get_nmode_support_by_sec_cfg(ieee->dev))
return;
if (ht_info->current_ampdu_enable) {
if (!rtllib_get_ts(ieee, (struct ts_common_info **)(&ts), hdr->addr1,
skb->priority, TX_DIR, true)) {
netdev_info(ieee->dev, "%s: can't get TS\n", __func__);
return;
}
if (!ts->tx_admitted_ba_record.b_valid) {
if (ieee->wpa_ie_len && (ieee->pairwise_key_type ==
KEY_TYPE_NA)) {
;
} else if (tcb_desc->bdhcp == 1) {
;
} else if (!ts->disable_add_ba) {
rtllib_ts_start_add_ba_process(ieee, ts);
}
return;
} else if (!ts->using_ba) {
if (SN_LESS(ts->tx_admitted_ba_record.ba_start_seq_ctrl.field.seq_num,
(ts->tx_cur_seq + 1) % 4096))
ts->using_ba = true;
else
return;
}
if (ieee->iw_mode == IW_MODE_INFRA) {
tcb_desc->ampdu_enable = true;
tcb_desc->ampdu_factor = ht_info->current_ampdu_factor;
tcb_desc->ampdu_density = ht_info->current_mpdu_density;
}
}
}
static void rtllib_query_short_preamble_mode(struct rtllib_device *ieee,
struct cb_desc *tcb_desc)
{
tcb_desc->use_short_preamble = false;
if (tcb_desc->data_rate == 2)
return;
else if (ieee->current_network.capability &
WLAN_CAPABILITY_SHORT_PREAMBLE)
tcb_desc->use_short_preamble = true;
}
static void rtllib_query_ht_cap_short_gi(struct rtllib_device *ieee,
struct cb_desc *tcb_desc)
{
struct rt_hi_throughput *ht_info = ieee->ht_info;
tcb_desc->use_short_gi = false;
if (!ht_info->current_ht_support || !ht_info->enable_ht)
return;
if (ht_info->cur_bw_40mhz && ht_info->cur_short_gi_40mhz)
tcb_desc->use_short_gi = true;
else if (!ht_info->cur_bw_40mhz && ht_info->cur_short_gi_20mhz)
tcb_desc->use_short_gi = true;
}
static void rtllib_query_bandwidth_mode(struct rtllib_device *ieee,
struct cb_desc *tcb_desc)
{
struct rt_hi_throughput *ht_info = ieee->ht_info;
tcb_desc->packet_bw = false;
if (!ht_info->current_ht_support || !ht_info->enable_ht)
return;
if (tcb_desc->multicast || tcb_desc->broadcast)
return;
if ((tcb_desc->data_rate & 0x80) == 0)
return;
if (ht_info->cur_bw_40mhz && ht_info->cur_tx_bw40mhz &&
!ieee->bandwidth_auto_switch.forced_tx_20MHz)
tcb_desc->packet_bw = true;
}
static void rtllib_query_protectionmode(struct rtllib_device *ieee,
struct cb_desc *tcb_desc,
struct sk_buff *skb)
{
struct rt_hi_throughput *ht_info;
tcb_desc->rtsstbc = false;
tcb_desc->rts_use_short_gi = false;
tcb_desc->cts_enable = false;
tcb_desc->RTSSC = 0;
tcb_desc->rts_bw = false;
if (tcb_desc->broadcast || tcb_desc->multicast)
return;
if (is_broadcast_ether_addr(skb->data + 16))
return;
if (ieee->mode < WIRELESS_MODE_N_24G) {
if (skb->len > ieee->rts) {
tcb_desc->rts_enable = true;
tcb_desc->rts_rate = MGN_24M;
} else if (ieee->current_network.buseprotection) {
tcb_desc->rts_enable = true;
tcb_desc->cts_enable = true;
tcb_desc->rts_rate = MGN_24M;
}
return;
}
ht_info = ieee->ht_info;
while (true) {
if (ht_info->iot_action & HT_IOT_ACT_FORCED_CTS2SELF) {
tcb_desc->cts_enable = true;
tcb_desc->rts_rate = MGN_24M;
tcb_desc->rts_enable = true;
break;
} else if (ht_info->iot_action & (HT_IOT_ACT_FORCED_RTS |
HT_IOT_ACT_PURE_N_MODE)) {
tcb_desc->rts_enable = true;
tcb_desc->rts_rate = MGN_24M;
break;
}
if (ieee->current_network.buseprotection) {
tcb_desc->rts_enable = true;
tcb_desc->cts_enable = true;
tcb_desc->rts_rate = MGN_24M;
break;
}
if (ht_info->current_ht_support && ht_info->enable_ht) {
u8 ht_op_mode = ht_info->current_op_mode;
if ((ht_info->cur_bw_40mhz && (ht_op_mode == 2 ||
ht_op_mode == 3)) ||
(!ht_info->cur_bw_40mhz && ht_op_mode == 3)) {
tcb_desc->rts_rate = MGN_24M;
tcb_desc->rts_enable = true;
break;
}
}
if (skb->len > ieee->rts) {
tcb_desc->rts_rate = MGN_24M;
tcb_desc->rts_enable = true;
break;
}
if (tcb_desc->ampdu_enable) {
tcb_desc->rts_rate = MGN_24M;
tcb_desc->rts_enable = false;
break;
}
goto NO_PROTECTION;
}
if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
tcb_desc->use_short_preamble = true;
return;
NO_PROTECTION:
tcb_desc->rts_enable = false;
tcb_desc->cts_enable = false;
tcb_desc->rts_rate = 0;
tcb_desc->RTSSC = 0;
tcb_desc->rts_bw = false;
}
static void rtllib_txrate_selectmode(struct rtllib_device *ieee,
struct cb_desc *tcb_desc)
{
if (ieee->tx_dis_rate_fallback)
tcb_desc->tx_dis_rate_fallback = true;
if (ieee->tx_use_drv_assinged_rate)
tcb_desc->tx_use_drv_assinged_rate = true;
if (!tcb_desc->tx_dis_rate_fallback ||
!tcb_desc->tx_use_drv_assinged_rate) {
if (ieee->iw_mode == IW_MODE_INFRA)
tcb_desc->ratr_index = 0;
}
}
static u16 rtllib_query_seqnum(struct rtllib_device *ieee, struct sk_buff *skb,
u8 *dst)
{
u16 seqnum = 0;
if (is_multicast_ether_addr(dst))
return 0;
if (is_qos_data_frame(skb->data)) {
struct tx_ts_record *ts = NULL;
if (!rtllib_get_ts(ieee, (struct ts_common_info **)(&ts), dst,
skb->priority, TX_DIR, true))
return 0;
seqnum = ts->tx_cur_seq;
ts->tx_cur_seq = (ts->tx_cur_seq + 1) % 4096;
return seqnum;
}
return 0;
}
static int wme_downgrade_ac(struct sk_buff *skb)
{
switch (skb->priority) {
case 6:
case 7:
skb->priority = 5; /* VO -> VI */
return 0;
case 4:
case 5:
skb->priority = 3; /* VI -> BE */
return 0;
case 0:
case 3:
skb->priority = 1; /* BE -> BK */
return 0;
default:
return -1;
}
}
static u8 rtllib_current_rate(struct rtllib_device *ieee)
{
if (ieee->mode & IEEE_MODE_MASK)
return ieee->rate;
if (ieee->ht_curr_op_rate)
return ieee->ht_curr_op_rate;
else
return ieee->rate & 0x7F;
}
static int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev)
{
struct rtllib_device *ieee = (struct rtllib_device *)
netdev_priv_rsl(dev);
struct rtllib_txb *txb = NULL;
struct ieee80211_qos_hdr *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_qos_hdr header = { /* Ensure zero initialized */
.duration_id = 0,
.seq_ctrl = 0,
.qos_ctrl = 0
};
int qos_activated = ieee->current_network.qos_data.active;
u8 dest[ETH_ALEN];
u8 src[ETH_ALEN];
struct lib80211_crypt_data *crypt = NULL;
struct cb_desc *tcb_desc;
u8 is_multicast = false;
bool bdhcp = false;
spin_lock_irqsave(&ieee->lock, flags);
/* If there is no driver handler to take the TXB, don't bother
* creating it...
*/
if (!(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE) ||
((!ieee->softmac_data_hard_start_xmit &&
(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) {
netdev_warn(ieee->dev, "No xmit handler.\n");
goto success;
}
if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
netdev_warn(ieee->dev, "skb too small (%d).\n",
skb->len);
goto success;
}
/* Save source and destination addresses */
ether_addr_copy(dest, skb->data);
ether_addr_copy(src, skb->data + ETH_ALEN);
memset(skb->cb, 0, sizeof(skb->cb));
ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
if (ieee->iw_mode == IW_MODE_MONITOR) {
txb = rtllib_alloc_txb(1, skb->len, GFP_ATOMIC);
if (unlikely(!txb)) {
netdev_warn(ieee->dev,
"Could not allocate TXB\n");
goto failed;
}
txb->encrypted = 0;
txb->payload_size = cpu_to_le16(skb->len);
skb_put_data(txb->fragments[0], skb->data, skb->len);
goto success;
}
if (skb->len > 282) {
if (ether_type == ETH_P_IP) {
const struct iphdr *ip = (struct iphdr *)
((u8 *)skb->data + 14);
if (ip->protocol == IPPROTO_UDP) {
struct udphdr *udp;
udp = (struct udphdr *)((u8 *)ip +
(ip->ihl << 2));
if (((((u8 *)udp)[1] == 68) &&
(((u8 *)udp)[3] == 67)) ||
((((u8 *)udp)[1] == 67) &&
(((u8 *)udp)[3] == 68))) {
bdhcp = true;
ieee->lps_delay_cnt = 200;
}
}
} else if (ether_type == ETH_P_ARP) {
netdev_info(ieee->dev,
"=================>DHCP Protocol start tx ARP pkt!!\n");
bdhcp = true;
ieee->lps_delay_cnt =
ieee->current_network.tim.tim_count;
}
}
skb->priority = rtllib_classify(skb);
crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) && crypt && crypt->ops;
if (!encrypt && ieee->ieee802_1x &&
ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
stats->tx_dropped++;
goto success;
}
if (crypt && !encrypt && ether_type == ETH_P_PAE) {
struct eapol *eap = (struct eapol *)(skb->data +
sizeof(struct ethhdr) - SNAP_SIZE -
sizeof(u16));
netdev_dbg(ieee->dev,
"TX: IEEE 802.11 EAPOL frame: %s\n",
eap_get_type(eap->type));
}
/* 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 = RTLLIB_FTYPE_DATA | IEEE80211_FCTL_PROTECTED;
else
fc = RTLLIB_FTYPE_DATA;
if (qos_activated)
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
*/
ether_addr_copy(header.addr1,
ieee->current_network.bssid);
ether_addr_copy(header.addr2, src);
ether_addr_copy(header.addr3, dest);
}
is_multicast = is_multicast_ether_addr(header.addr1);
header.frame_control = cpu_to_le16(fc);
/* Determine fragmentation size based on destination (multicast
* and broadcast are not fragmented)
*/
if (is_multicast) {
frag_size = MAX_FRAG_THRESHOLD;
qos_ctl |= QOS_CTL_NOTCONTAIN_ACK;
} else {
frag_size = ieee->fts;
qos_ctl = 0;
}
if (qos_activated) {
hdr_len = RTLLIB_3ADDR_LEN + 2;
/* in case we are a client verify acm is not set for this ac */
while (unlikely(ieee->wmm_acm & (0x01 << skb->priority))) {
netdev_info(ieee->dev, "skb->priority = %x\n",
skb->priority);
if (wme_downgrade_ac(skb))
break;
netdev_info(ieee->dev, "converted skb->priority = %x\n",
skb->priority);
}
qos_ctl |= skb->priority;
header.qos_ctrl = cpu_to_le16(qos_ctl & RTLLIB_QOS_TID);
} else {
hdr_len = RTLLIB_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_RTLLIB_COMPUTE_FCS | CFG_RTLLIB_RESERVE_FCS))
bytes_per_frag -= RTLLIB_FCS_LEN;
/* Each fragment may need to have room for encrypting
* pre/postfix
*/
if (encrypt) {
bytes_per_frag -= crypt->ops->extra_mpdu_prefix_len +
crypt->ops->extra_mpdu_postfix_len +
crypt->ops->extra_msdu_prefix_len +
crypt->ops->extra_msdu_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 = rtllib_alloc_txb(nr_frags, frag_size +
ieee->tx_headroom, GFP_ATOMIC);
if (unlikely(!txb)) {
netdev_warn(ieee->dev, "Could not allocate TXB\n");
goto failed;
}
txb->encrypted = encrypt;
txb->payload_size = cpu_to_le16(bytes);
if (qos_activated)
txb->queue_index = UP2AC(skb->priority);
else
txb->queue_index = WME_AC_BE;
for (i = 0; i < nr_frags; i++) {
skb_frag = txb->fragments[i];
tcb_desc = (struct cb_desc *)(skb_frag->cb +
MAX_DEV_ADDR_SIZE);
if (qos_activated) {
skb_frag->priority = skb->priority;
tcb_desc->queue_index = UP2AC(skb->priority);
} else {
skb_frag->priority = WME_AC_BE;
tcb_desc->queue_index = WME_AC_BE;
}
skb_reserve(skb_frag, ieee->tx_headroom);
if (encrypt) {
if (ieee->hwsec_active)
tcb_desc->hw_sec = 1;
else
tcb_desc->hw_sec = 0;
skb_reserve(skb_frag,
crypt->ops->extra_mpdu_prefix_len +
crypt->ops->extra_msdu_prefix_len);
} else {
tcb_desc->hw_sec = 0;
}
frag_hdr = skb_put_data(skb_frag, &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_control = cpu_to_le16(fc |
IEEE80211_FCTL_MOREFRAGS);
bytes = bytes_per_frag;
} else {
/* The last fragment has the remaining length */
bytes = bytes_last_frag;
}
if ((qos_activated) && (!is_multicast)) {
frag_hdr->seq_ctrl =
cpu_to_le16(rtllib_query_seqnum(ieee, skb_frag,
header.addr1));
frag_hdr->seq_ctrl =
cpu_to_le16(le16_to_cpu(frag_hdr->seq_ctrl) << 4 | i);
} else {
frag_hdr->seq_ctrl =
cpu_to_le16(ieee->seq_ctrl[0] << 4 | i);
}
/* Put a SNAP header on the first fragment */
if (i == 0) {
rtllib_put_snap(skb_put(skb_frag,
SNAP_SIZE +
sizeof(u16)), ether_type);
bytes -= SNAP_SIZE + sizeof(u16);
}
skb_put_data(skb_frag, 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)
rtllib_encrypt_fragment(ieee, skb_frag,
hdr_len);
if (ieee->config &
(CFG_RTLLIB_COMPUTE_FCS | CFG_RTLLIB_RESERVE_FCS))
skb_put(skb_frag, 4);
}
if ((qos_activated) && (!is_multicast)) {
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]++;
}
success:
if (txb) {
tcb_desc = (struct cb_desc *)
(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
tcb_desc->tx_enable_fw_calc_dur = 1;
tcb_desc->priority = skb->priority;
if (ether_type == ETH_P_PAE) {
if (ieee->ht_info->iot_action &
HT_IOT_ACT_WA_IOT_Broadcom) {
tcb_desc->data_rate =
mgnt_query_tx_rate_exclude_cck_rates(ieee);
tcb_desc->tx_dis_rate_fallback = false;
} else {
tcb_desc->data_rate = ieee->basic_rate;
tcb_desc->tx_dis_rate_fallback = 1;
}
tcb_desc->ratr_index = 7;
tcb_desc->tx_use_drv_assinged_rate = 1;
} else {
if (is_multicast_ether_addr(header.addr1))
tcb_desc->multicast = 1;
if (is_broadcast_ether_addr(header.addr1))
tcb_desc->broadcast = 1;
rtllib_txrate_selectmode(ieee, tcb_desc);
if (tcb_desc->multicast || tcb_desc->broadcast)
tcb_desc->data_rate = ieee->basic_rate;
else
tcb_desc->data_rate = rtllib_current_rate(ieee);
if (bdhcp) {
if (ieee->ht_info->iot_action &
HT_IOT_ACT_WA_IOT_Broadcom) {
tcb_desc->data_rate =
mgnt_query_tx_rate_exclude_cck_rates(ieee);
tcb_desc->tx_dis_rate_fallback = false;
} else {
tcb_desc->data_rate = MGN_1M;
tcb_desc->tx_dis_rate_fallback = 1;
}
tcb_desc->ratr_index = 7;
tcb_desc->tx_use_drv_assinged_rate = 1;
tcb_desc->bdhcp = 1;
}
rtllib_query_short_preamble_mode(ieee, tcb_desc);
rtllib_tx_query_agg_cap(ieee, txb->fragments[0],
tcb_desc);
rtllib_query_ht_cap_short_gi(ieee, tcb_desc);
rtllib_query_bandwidth_mode(ieee, tcb_desc);
rtllib_query_protectionmode(ieee, tcb_desc,
txb->fragments[0]);
}
}
spin_unlock_irqrestore(&ieee->lock, flags);
dev_kfree_skb_any(skb);
if (txb) {
if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE) {
dev->stats.tx_packets++;
dev->stats.tx_bytes += le16_to_cpu(txb->payload_size);
rtllib_softmac_xmit(txb, ieee);
} else {
rtllib_txb_free(txb);
}
}
return 0;
failed:
spin_unlock_irqrestore(&ieee->lock, flags);
netif_stop_queue(dev);
stats->tx_errors++;
return 1;
}
netdev_tx_t rtllib_xmit(struct sk_buff *skb, struct net_device *dev)
{
memset(skb->cb, 0, sizeof(skb->cb));
return rtllib_xmit_inter(skb, dev) ? NETDEV_TX_BUSY : NETDEV_TX_OK;
}
EXPORT_SYMBOL(rtllib_xmit);

View File

@ -1,752 +0,0 @@
// SPDX-License-Identifier: GPL-2.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>
*
* 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/module.h>
#include <linux/etherdevice.h>
#include "rtllib.h"
static const char * const rtllib_modes[] = {
"a", "b", "g", "?", "N-24G"
};
#define MAX_CUSTOM_LEN 64
static inline char *rtl819x_translate_scan(struct rtllib_device *ieee,
char *start, char *stop,
struct rtllib_network *network,
struct iw_request_info *info)
{
char custom[MAX_CUSTOM_LEN];
char proto_name[6];
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;
ether_addr_copy(iwe.u.ap_addr.sa_data, network->bssid);
start = iwe_stream_add_event(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 = min_t(u8, network->ssid_len, 32);
start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
} else if (network->hidden_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_t(u8, network->hidden_ssid_len, 32);
start = iwe_stream_add_point(info, start, stop, &iwe, network->hidden_ssid);
}
/* Add the protocol name */
iwe.cmd = SIOCGIWNAME;
for (i = 0; i < ARRAY_SIZE(rtllib_modes); i++) {
if (network->mode & BIT(i)) {
strcpy(pname, rtllib_modes[i]);
pname += strlen(rtllib_modes[i]);
}
}
*pname = '\0';
snprintf(iwe.u.name, IFNAMSIZ, "IEEE802.11%s", proto_name);
start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
/* Add mode */
iwe.cmd = SIOCGIWMODE;
if (network->capability &
(WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
if (network->capability & WLAN_CAPABILITY_ESS)
iwe.u.mode = IW_MODE_MASTER;
else
iwe.u.mode = IW_MODE_ADHOC;
start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN);
}
/* Add frequency/channel */
iwe.cmd = SIOCGIWFREQ;
iwe.u.freq.m = network->channel;
iwe.u.freq.e = 0;
iwe.u.freq.i = 0;
start = iwe_stream_add_event(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 += scnprintf(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 += scnprintf(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 += scnprintf(p, MAX_CUSTOM_LEN - (p - custom),
"%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
if (rate > max_rate)
max_rate = rate;
}
if (network->mode >= WIRELESS_MODE_N_24G) {
struct ht_capab_ele *ht_cap = NULL;
bool is40M = false, isShortGI = false;
u8 max_mcs = 0;
if (!memcmp(network->bssht.bd_ht_cap_buf, EWC11NHTCap, 4))
ht_cap = (struct ht_capab_ele *)
&network->bssht.bd_ht_cap_buf[4];
else
ht_cap = (struct ht_capab_ele *)
&network->bssht.bd_ht_cap_buf[0];
is40M = (ht_cap->chl_width) ? 1 : 0;
isShortGI = (ht_cap->chl_width) ?
((ht_cap->short_gi_40mhz) ? 1 : 0) :
((ht_cap->short_gi_20mhz) ? 1 : 0);
max_mcs = ht_get_highest_mcs_rate(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.disabled = 0;
iwe.u.bitrate.fixed = 0;
iwe.u.bitrate.value = max_rate * 500000;
start = iwe_stream_add_event(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 & RTLLIB_STATMASK_WEMASK;
if (!(network->stats.mask & RTLLIB_STATMASK_RSSI))
iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID;
if (!(network->stats.mask & RTLLIB_STATMASK_NOISE))
iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID;
if (!(network->stats.mask & RTLLIB_STATMASK_SIGNAL))
iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID;
iwe.u.qual.updated = 7;
start = iwe_stream_add_event(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 info for WZC */
memset(&iwe, 0, sizeof(iwe));
if (network->wzc_ie_len) {
char buf[MAX_WZC_IE_LEN];
memcpy(buf, network->wzc_ie, network->wzc_ie_len);
iwe.cmd = IWEVGENIE;
iwe.u.data.length = network->wzc_ie_len;
start = iwe_stream_add_point(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 += scnprintf(p, MAX_CUSTOM_LEN - (p - custom),
" Last beacon: %lums ago",
(100 * (jiffies - network->last_scanned)) / HZ);
iwe.u.data.length = p - custom;
if (iwe.u.data.length)
start = iwe_stream_add_point(info, start, stop, &iwe, custom);
return start;
}
int rtllib_wx_get_scan(struct rtllib_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
struct rtllib_network *network;
unsigned long flags;
char *ev = extra;
char *stop = ev + wrqu->data.length;
int i = 0;
int err = 0;
netdev_dbg(ieee->dev, "Getting scan\n");
mutex_lock(&ieee->wx_mutex);
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
netdev_dbg(ieee->dev,
"Network '%s ( %pM)' hidden due to age (%lums).\n",
escape_essid(network->ssid,
network->ssid_len),
network->bssid,
(100 * (jiffies - network->last_scanned)) /
HZ);
}
spin_unlock_irqrestore(&ieee->lock, flags);
mutex_unlock(&ieee->wx_mutex);
wrqu->data.length = ev - extra;
wrqu->data.flags = 0;
netdev_dbg(ieee->dev, "%s(): %d networks returned.\n", __func__, i);
return err;
}
EXPORT_SYMBOL(rtllib_wx_get_scan);
int rtllib_wx_set_encode(struct rtllib_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *keybuf)
{
struct iw_point *erq = &wrqu->encoding;
struct net_device *dev = ieee->dev;
struct rtllib_security sec = {
.flags = 0
};
int i, key, key_provided, len;
struct lib80211_crypt_data **crypt;
key = erq->flags & IW_ENCODE_INDEX;
if (key) {
if (key > NUM_WEP_KEYS)
return -EINVAL;
key--;
key_provided = 1;
} else {
key_provided = 0;
key = ieee->crypt_info.tx_keyidx;
}
netdev_dbg(ieee->dev, "Key: %d [%s]\n", key, key_provided ?
"provided" : "default");
crypt = &ieee->crypt_info.crypt[key];
if (erq->flags & IW_ENCODE_DISABLED) {
if (key_provided && *crypt) {
netdev_dbg(ieee->dev,
"Disabling encryption on key %d.\n", key);
lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
} else {
netdev_dbg(ieee->dev, "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 < NUM_WEP_KEYS; i++) {
if (ieee->crypt_info.crypt[i]) {
if (key_provided)
break;
lib80211_crypt_delayed_deinit(&ieee->crypt_info,
&ieee->crypt_info.crypt[i]);
}
}
if (i == NUM_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 && (*crypt)->ops &&
strcmp((*crypt)->ops->name, "R-WEP") != 0) {
/* changing to use WEP; deinit previously used algorithm
* on this key
*/
lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
}
if (!*crypt) {
struct lib80211_crypt_data *new_crypt;
/* take WEP into use */
new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
if (!new_crypt)
return -ENOMEM;
new_crypt->ops = lib80211_get_crypto_ops("R-WEP");
if (!new_crypt->ops) {
request_module("rtllib_crypt_wep");
new_crypt->ops = lib80211_get_crypto_ops("R-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;
netdev_warn(dev,
"%s: could not initialize WEP: load module rtllib_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);
netdev_dbg(ieee->dev, "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
* explicitly set
*/
if (key == sec.active_key)
sec.flags |= SEC_ACTIVE_KEY;
ieee->crypt_info.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 */
netdev_info(ieee->dev, "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) {
netdev_dbg(ieee->dev,
"Setting key %d as default Tx key.\n", key);
ieee->crypt_info.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;
netdev_dbg(ieee->dev, "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 */
return 0;
}
EXPORT_SYMBOL(rtllib_wx_set_encode);
int rtllib_wx_get_encode(struct rtllib_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *keybuf)
{
struct iw_point *erq = &wrqu->encoding;
int len, key;
struct lib80211_crypt_data *crypt;
if (ieee->iw_mode == IW_MODE_MONITOR)
return -1;
key = erq->flags & IW_ENCODE_INDEX;
if (key) {
if (key > NUM_WEP_KEYS)
return -EINVAL;
key--;
} else {
key = ieee->crypt_info.tx_keyidx;
}
crypt = ieee->crypt_info.crypt[key];
erq->flags = key + 1;
if (!crypt || !crypt->ops) {
erq->length = 0;
erq->flags |= IW_ENCODE_DISABLED;
return 0;
}
len = crypt->ops->get_key(keybuf, SCM_KEY_LEN, NULL, crypt->priv);
erq->length = max(len, 0);
erq->flags |= IW_ENCODE_ENABLED;
if (ieee->open_wep)
erq->flags |= IW_ENCODE_OPEN;
else
erq->flags |= IW_ENCODE_RESTRICTED;
return 0;
}
EXPORT_SYMBOL(rtllib_wx_get_encode);
int rtllib_wx_set_encode_ext(struct rtllib_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, *module;
const struct lib80211_crypto_ops *ops;
struct lib80211_crypt_data **crypt;
struct rtllib_security sec = {
.flags = 0,
};
idx = encoding->flags & IW_ENCODE_INDEX;
if (idx) {
if (idx < 1 || idx > NUM_WEP_KEYS)
return -EINVAL;
idx--;
} else {
idx = ieee->crypt_info.tx_keyidx;
}
if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
crypt = &ieee->crypt_info.crypt[idx];
group_key = 1;
} else {
/* some Cisco APs use idx>0 for unicast in dynamic WEP */
if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
return -EINVAL;
if (ieee->iw_mode == IW_MODE_INFRA)
crypt = &ieee->crypt_info.crypt[idx];
else
return -EINVAL;
}
sec.flags |= SEC_ENABLED;
if ((encoding->flags & IW_ENCODE_DISABLED) ||
ext->alg == IW_ENCODE_ALG_NONE) {
if (*crypt)
lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
for (i = 0; i < NUM_WEP_KEYS; i++) {
if (ieee->crypt_info.crypt[i])
break;
}
if (i == NUM_WEP_KEYS) {
sec.enabled = 0;
sec.level = SEC_LEVEL_0;
sec.flags |= SEC_LEVEL;
}
goto done;
}
sec.enabled = 1;
switch (ext->alg) {
case IW_ENCODE_ALG_WEP:
alg = "R-WEP";
module = "rtllib_crypt_wep";
break;
case IW_ENCODE_ALG_TKIP:
alg = "R-TKIP";
module = "rtllib_crypt_tkip";
break;
case IW_ENCODE_ALG_CCMP:
alg = "R-CCMP";
module = "rtllib_crypt_ccmp";
break;
default:
netdev_dbg(ieee->dev, "Unknown crypto alg %d\n", ext->alg);
ret = -EINVAL;
goto done;
}
netdev_dbg(dev, "alg name:%s\n", alg);
ops = lib80211_get_crypto_ops(alg);
if (!ops) {
char tempbuf[100];
memset(tempbuf, 0x00, 100);
sprintf(tempbuf, "%s", module);
request_module("%s", tempbuf);
ops = lib80211_get_crypto_ops(alg);
}
if (!ops) {
netdev_info(dev, "========>unknown crypto alg %d\n", ext->alg);
ret = -EINVAL;
goto done;
}
if (!*crypt || (*crypt)->ops != ops) {
struct lib80211_crypt_data *new_crypt;
lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
if (!new_crypt) {
ret = -ENOMEM;
goto done;
}
new_crypt->ops = ops;
if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
new_crypt->priv = new_crypt->ops->init(idx);
if (!new_crypt->priv) {
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) {
netdev_info(dev, "key setting failed\n");
ret = -EINVAL;
goto done;
}
if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
ieee->crypt_info.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;
}
done:
return ret;
}
EXPORT_SYMBOL(rtllib_wx_set_encode_ext);
int rtllib_wx_set_mlme(struct rtllib_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
u8 i = 0;
bool deauth = false;
struct iw_mlme *mlme = (struct iw_mlme *)extra;
if (ieee->link_state != MAC80211_LINKED)
return -ENOLINK;
mutex_lock(&ieee->wx_mutex);
switch (mlme->cmd) {
case IW_MLME_DEAUTH:
deauth = true;
fallthrough;
case IW_MLME_DISASSOC:
if (deauth)
netdev_info(ieee->dev, "disauth packet !\n");
else
netdev_info(ieee->dev, "dis associate packet!\n");
ieee->cannot_notify = true;
send_disassociation(ieee, deauth, mlme->reason_code);
rtllib_disassociate(ieee);
ieee->wap_set = 0;
for (i = 0; i < 6; i++)
ieee->current_network.bssid[i] = 0x55;
ieee->ssid_set = 0;
ieee->current_network.ssid[0] = '\0';
ieee->current_network.ssid_len = 0;
break;
default:
mutex_unlock(&ieee->wx_mutex);
return -EOPNOTSUPP;
}
mutex_unlock(&ieee->wx_mutex);
return 0;
}
EXPORT_SYMBOL(rtllib_wx_set_mlme);
int rtllib_wx_set_auth(struct rtllib_device *ieee,
struct iw_request_info *info,
struct iw_param *data, char *extra)
{
switch (data->flags & IW_AUTH_INDEX) {
case IW_AUTH_WPA_VERSION:
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;
case IW_AUTH_WPA_ENABLED:
ieee->wpa_enabled = (data->value) ? 1 : 0;
break;
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;
}
EXPORT_SYMBOL(rtllib_wx_set_auth);
int rtllib_wx_set_gen_ie(struct rtllib_device *ieee, u8 *ie, size_t len)
{
u8 *buf;
u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
if (len > MAX_WPA_IE_LEN || (len && !ie))
return -EINVAL;
if (len) {
eid = ie[0];
if ((eid == MFIE_TYPE_GENERIC) && (!memcmp(&ie[2], wps_oui, 4))) {
ieee->wps_ie_len = min_t(size_t, len, MAX_WZC_IE_LEN);
buf = kmemdup(ie, ieee->wps_ie_len, GFP_KERNEL);
if (!buf)
return -ENOMEM;
ieee->wps_ie = buf;
return 0;
}
}
ieee->wps_ie_len = 0;
kfree(ieee->wps_ie);
ieee->wps_ie = NULL;
if (len) {
if (len != ie[1] + 2)
return -EINVAL;
buf = kmemdup(ie, len, GFP_KERNEL);
if (!buf)
return -ENOMEM;
kfree(ieee->wpa_ie);
ieee->wpa_ie = buf;
ieee->wpa_ie_len = len;
} else {
kfree(ieee->wpa_ie);
ieee->wpa_ie = NULL;
ieee->wpa_ie_len = 0;
}
return 0;
}
EXPORT_SYMBOL(rtllib_wx_set_gen_ie);