mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 04:18:39 +08:00
Staging driver updates for 6.7-rc1
Here is the big set of staging driver updates for 6.7-rc1. A bit bigger than 6.6 this time around, as it coincided with the Outreachy and mentorship application process, so we got a bunch of new developers sending in their first changes, which is nice to see. Also in here is a removal of the qlge ethernet driver, and the rtl8192u wireless driver. Both of these were very old and no one was maintaining them, the wireless driver removal was due to no one using it anymore, and no hardware to be found, and is part of a larger effort to remove unused and old wifi drivers from the system. The qlge ethernet driver did have one user pop up after it was dropped, and we are working with the network mainainers to figure out what tree it will come back in from and who will be responsible for it, and if it really is being used or not. Odds are it will show up in a network subsystem pull request after -rc1 is out, but we aren't sure yet. Other smaller changes in here are: - Lots of vc04_services work by Umang to clean up the mess created by the rpi developers long ago, bringing it almost into good enough shape to get out of staging, hopefully next major release, it's getting close. - rtl8192e variable cleanups and removal of unused code and structures - vme_user coding style cleanups - other small coding style cleanups to lots of the staging drivers - octeon typedef removals, and then last-minute revert when it was found to break the build in some configurations (it's a hard driver to build properly, none of the normal automated testing catches it.) All of these have been in linux-next for a while with no reported issues. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCZUTg9w8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+ymL+QCg2YS9Mbr7W6zNAdRTbDybzp08ZzUAnRHQXUfB WbZERHQpNOSTE3HwuW1D =tZpl -----END PGP SIGNATURE----- Merge tag 'staging-6.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging Pull staging driver updates from Greg KH: "Here is the big set of staging driver updates for 6.7-rc1. A bit bigger than 6.6 this time around, as it coincided with the Outreachy and mentorship application process, so we got a bunch of new developers sending in their first changes, which is nice to see. Also in here is a removal of the qlge ethernet driver, and the rtl8192u wireless driver. Both of these were very old and no one was maintaining them, the wireless driver removal was due to no one using it anymore, and no hardware to be found, and is part of a larger effort to remove unused and old wifi drivers from the system. The qlge ethernet driver did have one user pop up after it was dropped, and we are working with the network mainainers to figure out what tree it will come back in from and who will be responsible for it, and if it really is being used or not. Odds are it will show up in a network subsystem pull request after -rc1 is out, but we aren't sure yet. Other smaller changes in here are: - Lots of vc04_services work by Umang to clean up the mess created by the rpi developers long ago, bringing it almost into good enough shape to get out of staging, hopefully next major release, it's getting close. - rtl8192e variable cleanups and removal of unused code and structures - vme_user coding style cleanups - other small coding style cleanups to lots of the staging drivers - octeon typedef removals, and then last-minute revert when it was found to break the build in some configurations (it's a hard driver to build properly, none of the normal automated testing catches it.) All of these have been in linux-next for a while with no reported issues" * tag 'staging-6.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (256 commits) Revert "staging: octeon: remove typedef in enum cvmx_spi_mode_t" Revert "staging: octeon: remove typedef in enum cvmx_helper_interface_mode_t" Revert "staging: octeon: remove typedef in enum cvmx_pow_wait_t" Revert "staging: octeon: remove typedef in struct cvmx_pko_lock_t" Revert "staging: octeon: remove typedef in enum cvmx_pko_status_t" Revert "staging: octeon: remove typedef in structs cvmx_pip_port_status_t and cvmx_pko_port_status_t" staging: vt6655: Type encoding info dropped from variable name "byRxRate" staging: vt6655: Type encoding info dropped from function name "CARDbUpdateTSF" staging: vt6655: Type encoding info dropped from function name "CARDvSetRSPINF" staging: vt6655: Type encoding info dropped from function name "CARDbyGetPktType" staging: vt6655: Type encoding info dropped from variable name "byPacketType" staging: vt6655: Type encoding info dropped from function name "CARDbSetPhyParameter" staging: vt6655: Type encoding info dropped from variable name "pbyRsvTime" staging: vt6655: Type encoding info dropped from variable name "pbyTxRate" staging: vt6655: Type encoding info dropped from function name "s_vCalculateOFDMRParameter" staging: vt6655: Type encoding info dropped from array name "cwRXBCNTSFOff" staging: fbtft: Convert to platform remove callback returning void staging: olpc_dcon: Remove I2C_CLASS_DDC support staging: vc04_services: use snprintf instead of sprintf staging: rtl8192e: Fix line break issue at priv->rx_buf[priv->rx_idx] ...
This commit is contained in:
commit
4c7a0c95ad
@ -15,7 +15,6 @@ Contents:
|
|||||||
ethernet/index
|
ethernet/index
|
||||||
fddi/index
|
fddi/index
|
||||||
hamradio/index
|
hamradio/index
|
||||||
qlogic/index
|
|
||||||
wifi/index
|
wifi/index
|
||||||
wwan/index
|
wwan/index
|
||||||
|
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
.. SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
|
||||||
|
|
||||||
QLogic QLGE Device Drivers
|
|
||||||
===============================================
|
|
||||||
|
|
||||||
Contents:
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:maxdepth: 2
|
|
||||||
|
|
||||||
qlge
|
|
||||||
|
|
||||||
.. only:: subproject and html
|
|
||||||
|
|
||||||
Indices
|
|
||||||
=======
|
|
||||||
|
|
||||||
* :ref:`genindex`
|
|
@ -1,118 +0,0 @@
|
|||||||
.. SPDX-License-Identifier: GPL-2.0
|
|
||||||
|
|
||||||
=======================================
|
|
||||||
QLogic QLGE 10Gb Ethernet device driver
|
|
||||||
=======================================
|
|
||||||
|
|
||||||
This driver use drgn and devlink for debugging.
|
|
||||||
|
|
||||||
Dump kernel data structures in drgn
|
|
||||||
-----------------------------------
|
|
||||||
|
|
||||||
To dump kernel data structures, the following Python script can be used
|
|
||||||
in drgn:
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
def align(x, a):
|
|
||||||
"""the alignment a should be a power of 2
|
|
||||||
"""
|
|
||||||
mask = a - 1
|
|
||||||
return (x+ mask) & ~mask
|
|
||||||
|
|
||||||
def struct_size(struct_type):
|
|
||||||
struct_str = "struct {}".format(struct_type)
|
|
||||||
return sizeof(Object(prog, struct_str, address=0x0))
|
|
||||||
|
|
||||||
def netdev_priv(netdevice):
|
|
||||||
NETDEV_ALIGN = 32
|
|
||||||
return netdevice.value_() + align(struct_size("net_device"), NETDEV_ALIGN)
|
|
||||||
|
|
||||||
name = 'xxx'
|
|
||||||
qlge_device = None
|
|
||||||
netdevices = prog['init_net'].dev_base_head.address_of_()
|
|
||||||
for netdevice in list_for_each_entry("struct net_device", netdevices, "dev_list"):
|
|
||||||
if netdevice.name.string_().decode('ascii') == name:
|
|
||||||
print(netdevice.name)
|
|
||||||
|
|
||||||
ql_adapter = Object(prog, "struct ql_adapter", address=netdev_priv(qlge_device))
|
|
||||||
|
|
||||||
The struct ql_adapter will be printed in drgn as follows,
|
|
||||||
|
|
||||||
>>> ql_adapter
|
|
||||||
(struct ql_adapter){
|
|
||||||
.ricb = (struct ricb){
|
|
||||||
.base_cq = (u8)0,
|
|
||||||
.flags = (u8)120,
|
|
||||||
.mask = (__le16)26637,
|
|
||||||
.hash_cq_id = (u8 [1024]){ 172, 142, 255, 255 },
|
|
||||||
.ipv6_hash_key = (__le32 [10]){},
|
|
||||||
.ipv4_hash_key = (__le32 [4]){},
|
|
||||||
},
|
|
||||||
.flags = (unsigned long)0,
|
|
||||||
.wol = (u32)0,
|
|
||||||
.nic_stats = (struct nic_stats){
|
|
||||||
.tx_pkts = (u64)0,
|
|
||||||
.tx_bytes = (u64)0,
|
|
||||||
.tx_mcast_pkts = (u64)0,
|
|
||||||
.tx_bcast_pkts = (u64)0,
|
|
||||||
.tx_ucast_pkts = (u64)0,
|
|
||||||
.tx_ctl_pkts = (u64)0,
|
|
||||||
.tx_pause_pkts = (u64)0,
|
|
||||||
...
|
|
||||||
},
|
|
||||||
.active_vlans = (unsigned long [64]){
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52780853100545, 18446744073709551615,
|
|
||||||
18446619461681283072, 0, 42949673024, 2147483647,
|
|
||||||
},
|
|
||||||
.rx_ring = (struct rx_ring [17]){
|
|
||||||
{
|
|
||||||
.cqicb = (struct cqicb){
|
|
||||||
.msix_vect = (u8)0,
|
|
||||||
.reserved1 = (u8)0,
|
|
||||||
.reserved2 = (u8)0,
|
|
||||||
.flags = (u8)0,
|
|
||||||
.len = (__le16)0,
|
|
||||||
.rid = (__le16)0,
|
|
||||||
...
|
|
||||||
},
|
|
||||||
.cq_base = (void *)0x0,
|
|
||||||
.cq_base_dma = (dma_addr_t)0,
|
|
||||||
}
|
|
||||||
...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
coredump via devlink
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
|
|
||||||
And the coredump obtained via devlink in json format looks like,
|
|
||||||
|
|
||||||
.. code:: shell
|
|
||||||
|
|
||||||
$ devlink health dump show DEVICE reporter coredump -p -j
|
|
||||||
{
|
|
||||||
"Core Registers": {
|
|
||||||
"segment": 1,
|
|
||||||
"values": [ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ]
|
|
||||||
},
|
|
||||||
"Test Logic Regs": {
|
|
||||||
"segment": 2,
|
|
||||||
"values": [ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ]
|
|
||||||
},
|
|
||||||
"RMII Registers": {
|
|
||||||
"segment": 3,
|
|
||||||
"values": [ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ]
|
|
||||||
},
|
|
||||||
...
|
|
||||||
"Sem Registers": {
|
|
||||||
"segment": 50,
|
|
||||||
"values": [ 0,0,0,0 ]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
When the module parameter qlge_force_coredump is set to be true, the MPI
|
|
||||||
RISC reset before coredumping. So coredumping will much longer since
|
|
||||||
devlink tool has to wait for 5 secs for the resetting to be
|
|
||||||
finished.
|
|
@ -17673,15 +17673,6 @@ L: netdev@vger.kernel.org
|
|||||||
S: Supported
|
S: Supported
|
||||||
F: drivers/net/ethernet/qlogic/qlcnic/
|
F: drivers/net/ethernet/qlogic/qlcnic/
|
||||||
|
|
||||||
QLOGIC QLGE 10Gb ETHERNET DRIVER
|
|
||||||
M: Manish Chopra <manishc@marvell.com>
|
|
||||||
M: GR-Linux-NIC-Dev@marvell.com
|
|
||||||
M: Coiby Xu <coiby.xu@gmail.com>
|
|
||||||
L: netdev@vger.kernel.org
|
|
||||||
S: Supported
|
|
||||||
F: Documentation/networking/device_drivers/qlogic/qlge.rst
|
|
||||||
F: drivers/staging/qlge/
|
|
||||||
|
|
||||||
QM1D1B0004 MEDIA DRIVER
|
QM1D1B0004 MEDIA DRIVER
|
||||||
M: Akihiro Tsukada <tskd08@gmail.com>
|
M: Akihiro Tsukada <tskd08@gmail.com>
|
||||||
L: linux-media@vger.kernel.org
|
L: linux-media@vger.kernel.org
|
||||||
|
@ -248,7 +248,6 @@ CONFIG_UIO_AEC=m
|
|||||||
CONFIG_UIO_SERCOS3=m
|
CONFIG_UIO_SERCOS3=m
|
||||||
CONFIG_UIO_PCI_GENERIC=m
|
CONFIG_UIO_PCI_GENERIC=m
|
||||||
CONFIG_STAGING=y
|
CONFIG_STAGING=y
|
||||||
CONFIG_QLGE=m
|
|
||||||
CONFIG_EXT2_FS=y
|
CONFIG_EXT2_FS=y
|
||||||
CONFIG_EXT2_FS_XATTR=y
|
CONFIG_EXT2_FS_XATTR=y
|
||||||
CONFIG_EXT2_FS_SECURITY=y
|
CONFIG_EXT2_FS_SECURITY=y
|
||||||
|
@ -28,8 +28,6 @@ source "drivers/staging/wlan-ng/Kconfig"
|
|||||||
|
|
||||||
source "drivers/staging/olpc_dcon/Kconfig"
|
source "drivers/staging/olpc_dcon/Kconfig"
|
||||||
|
|
||||||
source "drivers/staging/rtl8192u/Kconfig"
|
|
||||||
|
|
||||||
source "drivers/staging/rtl8192e/Kconfig"
|
source "drivers/staging/rtl8192e/Kconfig"
|
||||||
|
|
||||||
source "drivers/staging/rtl8723bs/Kconfig"
|
source "drivers/staging/rtl8723bs/Kconfig"
|
||||||
@ -74,8 +72,6 @@ source "drivers/staging/axis-fifo/Kconfig"
|
|||||||
|
|
||||||
source "drivers/staging/fieldbus/Kconfig"
|
source "drivers/staging/fieldbus/Kconfig"
|
||||||
|
|
||||||
source "drivers/staging/qlge/Kconfig"
|
|
||||||
|
|
||||||
source "drivers/staging/vme_user/Kconfig"
|
source "drivers/staging/vme_user/Kconfig"
|
||||||
|
|
||||||
endif # STAGING
|
endif # STAGING
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
obj-y += media/
|
obj-y += media/
|
||||||
obj-$(CONFIG_PRISM2_USB) += wlan-ng/
|
obj-$(CONFIG_PRISM2_USB) += wlan-ng/
|
||||||
obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon/
|
obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon/
|
||||||
obj-$(CONFIG_RTL8192U) += rtl8192u/
|
|
||||||
obj-$(CONFIG_RTL8192E) += rtl8192e/
|
obj-$(CONFIG_RTL8192E) += rtl8192e/
|
||||||
obj-$(CONFIG_RTL8723BS) += rtl8723bs/
|
obj-$(CONFIG_RTL8723BS) += rtl8723bs/
|
||||||
obj-$(CONFIG_R8712U) += rtl8712/
|
obj-$(CONFIG_R8712U) += rtl8712/
|
||||||
@ -27,4 +26,3 @@ obj-$(CONFIG_BCM2835_VCHIQ) += vc04_services/
|
|||||||
obj-$(CONFIG_PI433) += pi433/
|
obj-$(CONFIG_PI433) += pi433/
|
||||||
obj-$(CONFIG_XIL_AXIS_FIFO) += axis-fifo/
|
obj-$(CONFIG_XIL_AXIS_FIFO) += axis-fifo/
|
||||||
obj-$(CONFIG_FIELDBUS_DEV) += fieldbus/
|
obj-$(CONFIG_FIELDBUS_DEV) += fieldbus/
|
||||||
obj-$(CONFIG_QLGE) += qlge/
|
|
||||||
|
@ -310,12 +310,11 @@ static int fbtft_driver_probe_pdev(struct platform_device *pdev) \
|
|||||||
return fbtft_probe_common(_display, NULL, pdev); \
|
return fbtft_probe_common(_display, NULL, pdev); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static int fbtft_driver_remove_pdev(struct platform_device *pdev) \
|
static void fbtft_driver_remove_pdev(struct platform_device *pdev) \
|
||||||
{ \
|
{ \
|
||||||
struct fb_info *info = platform_get_drvdata(pdev); \
|
struct fb_info *info = platform_get_drvdata(pdev); \
|
||||||
\
|
\
|
||||||
fbtft_remove_common(&pdev->dev, info); \
|
fbtft_remove_common(&pdev->dev, info); \
|
||||||
return 0; \
|
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
FBTFT_DT_TABLE(_compatible) \
|
FBTFT_DT_TABLE(_compatible) \
|
||||||
@ -329,7 +328,7 @@ static struct platform_driver fbtft_driver_platform_driver = { \
|
|||||||
.of_match_table = dt_ids, \
|
.of_match_table = dt_ids, \
|
||||||
}, \
|
}, \
|
||||||
.probe = fbtft_driver_probe_pdev, \
|
.probe = fbtft_driver_probe_pdev, \
|
||||||
.remove = fbtft_driver_remove_pdev, \
|
.remove_new = fbtft_driver_remove_pdev, \
|
||||||
}; \
|
}; \
|
||||||
\
|
\
|
||||||
static int __init fbtft_driver_module_init(void) \
|
static int __init fbtft_driver_module_init(void) \
|
||||||
|
@ -218,7 +218,10 @@ static const struct regulator_desc can_power_desc = {
|
|||||||
.ops = &can_power_ops,
|
.ops = &can_power_ops,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct class *controller_class;
|
static const struct class controller_class = {
|
||||||
|
.name = "arcx_anybus_controller",
|
||||||
|
};
|
||||||
|
|
||||||
static DEFINE_IDA(controller_index_ida);
|
static DEFINE_IDA(controller_index_ida);
|
||||||
|
|
||||||
static int controller_probe(struct platform_device *pdev)
|
static int controller_probe(struct platform_device *pdev)
|
||||||
@ -301,7 +304,7 @@ static int controller_probe(struct platform_device *pdev)
|
|||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
goto out_ida;
|
goto out_ida;
|
||||||
}
|
}
|
||||||
cd->class_dev->class = controller_class;
|
cd->class_dev->class = &controller_class;
|
||||||
cd->class_dev->groups = controller_attribute_groups;
|
cd->class_dev->groups = controller_attribute_groups;
|
||||||
cd->class_dev->parent = dev;
|
cd->class_dev->parent = dev;
|
||||||
cd->class_dev->id = id;
|
cd->class_dev->id = id;
|
||||||
@ -351,12 +354,12 @@ static int __init controller_init(void)
|
|||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
controller_class = class_create("arcx_anybus_controller");
|
err = class_register(&controller_class);
|
||||||
if (IS_ERR(controller_class))
|
if (err)
|
||||||
return PTR_ERR(controller_class);
|
return err;
|
||||||
err = platform_driver_register(&controller_driver);
|
err = platform_driver_register(&controller_driver);
|
||||||
if (err)
|
if (err)
|
||||||
class_destroy(controller_class);
|
class_unregister(&controller_class);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -364,7 +367,7 @@ static int __init controller_init(void)
|
|||||||
static void __exit controller_exit(void)
|
static void __exit controller_exit(void)
|
||||||
{
|
{
|
||||||
platform_driver_unregister(&controller_driver);
|
platform_driver_unregister(&controller_driver);
|
||||||
class_destroy(controller_class);
|
class_unregister(&controller_class);
|
||||||
ida_destroy(&controller_index_ida);
|
ida_destroy(&controller_index_ida);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,6 +160,7 @@ static ssize_t gdm_tty_write(struct tty_struct *tty, const u8 *buf, size_t len)
|
|||||||
|
|
||||||
while (remain) {
|
while (remain) {
|
||||||
size_t sending_len = min_t(size_t, MUX_TX_MAX_SIZE, remain);
|
size_t sending_len = min_t(size_t, MUX_TX_MAX_SIZE, remain);
|
||||||
|
|
||||||
gdm->tty_dev->send_func(gdm->tty_dev->priv_dev,
|
gdm->tty_dev->send_func(gdm->tty_dev->priv_dev,
|
||||||
(void *)(buf + sent_len),
|
(void *)(buf + sent_len),
|
||||||
sending_len,
|
sending_len,
|
||||||
|
@ -12,10 +12,9 @@
|
|||||||
|
|
||||||
#include "audio_manager.h"
|
#include "audio_manager.h"
|
||||||
|
|
||||||
int gb_audio_manager_module_create(
|
int gb_audio_manager_module_create(struct gb_audio_manager_module **module,
|
||||||
struct gb_audio_manager_module **module,
|
struct kset *manager_kset, int id,
|
||||||
struct kset *manager_kset,
|
struct gb_audio_manager_module_descriptor *desc);
|
||||||
int id, struct gb_audio_manager_module_descriptor *desc);
|
|
||||||
|
|
||||||
/* module destroyed via kobject_put */
|
/* module destroyed via kobject_put */
|
||||||
|
|
||||||
|
@ -36,7 +36,10 @@ struct gb_cap {
|
|||||||
dev_t dev_num;
|
dev_t dev_num;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct class *cap_class;
|
static const struct class cap_class = {
|
||||||
|
.name = "gb_authenticate",
|
||||||
|
};
|
||||||
|
|
||||||
static dev_t cap_dev_num;
|
static dev_t cap_dev_num;
|
||||||
static DEFINE_IDA(cap_minors_map);
|
static DEFINE_IDA(cap_minors_map);
|
||||||
static LIST_HEAD(cap_list);
|
static LIST_HEAD(cap_list);
|
||||||
@ -336,7 +339,7 @@ int gb_cap_connection_init(struct gb_connection *connection)
|
|||||||
goto err_remove_ida;
|
goto err_remove_ida;
|
||||||
|
|
||||||
/* Add a soft link to the previously added char-dev within the bundle */
|
/* Add a soft link to the previously added char-dev within the bundle */
|
||||||
cap->class_device = device_create(cap_class, cap->parent, cap->dev_num,
|
cap->class_device = device_create(&cap_class, cap->parent, cap->dev_num,
|
||||||
NULL, "gb-authenticate-%d", minor);
|
NULL, "gb-authenticate-%d", minor);
|
||||||
if (IS_ERR(cap->class_device)) {
|
if (IS_ERR(cap->class_device)) {
|
||||||
ret = PTR_ERR(cap->class_device);
|
ret = PTR_ERR(cap->class_device);
|
||||||
@ -370,7 +373,7 @@ void gb_cap_connection_exit(struct gb_connection *connection)
|
|||||||
|
|
||||||
cap = gb_connection_get_data(connection);
|
cap = gb_connection_get_data(connection);
|
||||||
|
|
||||||
device_destroy(cap_class, cap->dev_num);
|
device_destroy(&cap_class, cap->dev_num);
|
||||||
cdev_del(&cap->cdev);
|
cdev_del(&cap->cdev);
|
||||||
ida_simple_remove(&cap_minors_map, MINOR(cap->dev_num));
|
ida_simple_remove(&cap_minors_map, MINOR(cap->dev_num));
|
||||||
|
|
||||||
@ -402,9 +405,9 @@ int cap_init(void)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
cap_class = class_create("gb_authenticate");
|
ret = class_register(&cap_class);
|
||||||
if (IS_ERR(cap_class))
|
if (ret)
|
||||||
return PTR_ERR(cap_class);
|
return ret;
|
||||||
|
|
||||||
ret = alloc_chrdev_region(&cap_dev_num, 0, NUM_MINORS,
|
ret = alloc_chrdev_region(&cap_dev_num, 0, NUM_MINORS,
|
||||||
"gb_authenticate");
|
"gb_authenticate");
|
||||||
@ -414,13 +417,13 @@ int cap_init(void)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_remove_class:
|
err_remove_class:
|
||||||
class_destroy(cap_class);
|
class_unregister(&cap_class);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cap_exit(void)
|
void cap_exit(void)
|
||||||
{
|
{
|
||||||
unregister_chrdev_region(cap_dev_num, NUM_MINORS);
|
unregister_chrdev_region(cap_dev_num, NUM_MINORS);
|
||||||
class_destroy(cap_class);
|
class_unregister(&cap_class);
|
||||||
ida_destroy(&cap_minors_map);
|
ida_destroy(&cap_minors_map);
|
||||||
}
|
}
|
||||||
|
@ -491,8 +491,6 @@ static void gb_bootrom_disconnect(struct gb_bundle *bundle)
|
|||||||
{
|
{
|
||||||
struct gb_bootrom *bootrom = greybus_get_drvdata(bundle);
|
struct gb_bootrom *bootrom = greybus_get_drvdata(bundle);
|
||||||
|
|
||||||
dev_dbg(&bundle->dev, "%s\n", __func__);
|
|
||||||
|
|
||||||
gb_connection_disable(bootrom->connection);
|
gb_connection_disable(bootrom->connection);
|
||||||
|
|
||||||
/* Disable timeouts */
|
/* Disable timeouts */
|
||||||
|
@ -220,7 +220,7 @@ static int gb_camera_operation_sync_flags(struct gb_connection *connection,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int gb_camera_get_max_pkt_size(struct gb_camera *gcam,
|
static int gb_camera_get_max_pkt_size(struct gb_camera *gcam,
|
||||||
struct gb_camera_configure_streams_response *resp)
|
struct gb_camera_configure_streams_response *resp)
|
||||||
{
|
{
|
||||||
unsigned int max_pkt_size = 0;
|
unsigned int max_pkt_size = 0;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
@ -267,8 +267,7 @@ static int gb_camera_get_max_pkt_size(struct gb_camera *gcam,
|
|||||||
* Validate the stream configuration response verifying padding is correctly
|
* Validate the stream configuration response verifying padding is correctly
|
||||||
* set and the returned number of streams is supported
|
* set and the returned number of streams is supported
|
||||||
*/
|
*/
|
||||||
static const int gb_camera_configure_streams_validate_response(
|
static const int gb_camera_configure_streams_validate_response(struct gb_camera *gcam,
|
||||||
struct gb_camera *gcam,
|
|
||||||
struct gb_camera_configure_streams_response *resp,
|
struct gb_camera_configure_streams_response *resp,
|
||||||
unsigned int nstreams)
|
unsigned int nstreams)
|
||||||
{
|
{
|
||||||
@ -378,8 +377,8 @@ struct ap_csi_config_request {
|
|||||||
#define GB_CAMERA_CSI_CLK_FREQ_MARGIN 150000000U
|
#define GB_CAMERA_CSI_CLK_FREQ_MARGIN 150000000U
|
||||||
|
|
||||||
static int gb_camera_setup_data_connection(struct gb_camera *gcam,
|
static int gb_camera_setup_data_connection(struct gb_camera *gcam,
|
||||||
struct gb_camera_configure_streams_response *resp,
|
struct gb_camera_configure_streams_response *resp,
|
||||||
struct gb_camera_csi_params *csi_params)
|
struct gb_camera_csi_params *csi_params)
|
||||||
{
|
{
|
||||||
struct ap_csi_config_request csi_cfg;
|
struct ap_csi_config_request csi_cfg;
|
||||||
struct gb_connection *conn;
|
struct gb_connection *conn;
|
||||||
@ -783,8 +782,8 @@ static ssize_t gb_camera_op_capabilities(void *priv, char *data, size_t len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int gb_camera_op_configure_streams(void *priv, unsigned int *nstreams,
|
static int gb_camera_op_configure_streams(void *priv, unsigned int *nstreams,
|
||||||
unsigned int *flags, struct gb_camera_stream *streams,
|
unsigned int *flags, struct gb_camera_stream *streams,
|
||||||
struct gb_camera_csi_params *csi_params)
|
struct gb_camera_csi_params *csi_params)
|
||||||
{
|
{
|
||||||
struct gb_camera *gcam = priv;
|
struct gb_camera *gcam = priv;
|
||||||
struct gb_camera_stream_config *gb_streams;
|
struct gb_camera_stream_config *gb_streams;
|
||||||
|
@ -55,7 +55,10 @@ struct fw_mgmt {
|
|||||||
*/
|
*/
|
||||||
#define NUM_MINORS U8_MAX
|
#define NUM_MINORS U8_MAX
|
||||||
|
|
||||||
static struct class *fw_mgmt_class;
|
static const struct class fw_mgmt_class = {
|
||||||
|
.name = "gb_fw_mgmt",
|
||||||
|
};
|
||||||
|
|
||||||
static dev_t fw_mgmt_dev_num;
|
static dev_t fw_mgmt_dev_num;
|
||||||
static DEFINE_IDA(fw_mgmt_minors_map);
|
static DEFINE_IDA(fw_mgmt_minors_map);
|
||||||
static LIST_HEAD(fw_mgmt_list);
|
static LIST_HEAD(fw_mgmt_list);
|
||||||
@ -629,7 +632,7 @@ int gb_fw_mgmt_connection_init(struct gb_connection *connection)
|
|||||||
goto err_remove_ida;
|
goto err_remove_ida;
|
||||||
|
|
||||||
/* Add a soft link to the previously added char-dev within the bundle */
|
/* Add a soft link to the previously added char-dev within the bundle */
|
||||||
fw_mgmt->class_device = device_create(fw_mgmt_class, fw_mgmt->parent,
|
fw_mgmt->class_device = device_create(&fw_mgmt_class, fw_mgmt->parent,
|
||||||
fw_mgmt->dev_num, NULL,
|
fw_mgmt->dev_num, NULL,
|
||||||
"gb-fw-mgmt-%d", minor);
|
"gb-fw-mgmt-%d", minor);
|
||||||
if (IS_ERR(fw_mgmt->class_device)) {
|
if (IS_ERR(fw_mgmt->class_device)) {
|
||||||
@ -664,7 +667,7 @@ void gb_fw_mgmt_connection_exit(struct gb_connection *connection)
|
|||||||
|
|
||||||
fw_mgmt = gb_connection_get_data(connection);
|
fw_mgmt = gb_connection_get_data(connection);
|
||||||
|
|
||||||
device_destroy(fw_mgmt_class, fw_mgmt->dev_num);
|
device_destroy(&fw_mgmt_class, fw_mgmt->dev_num);
|
||||||
cdev_del(&fw_mgmt->cdev);
|
cdev_del(&fw_mgmt->cdev);
|
||||||
ida_simple_remove(&fw_mgmt_minors_map, MINOR(fw_mgmt->dev_num));
|
ida_simple_remove(&fw_mgmt_minors_map, MINOR(fw_mgmt->dev_num));
|
||||||
|
|
||||||
@ -696,9 +699,9 @@ int fw_mgmt_init(void)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
fw_mgmt_class = class_create("gb_fw_mgmt");
|
ret = class_register(&fw_mgmt_class);
|
||||||
if (IS_ERR(fw_mgmt_class))
|
if (ret)
|
||||||
return PTR_ERR(fw_mgmt_class);
|
return ret;
|
||||||
|
|
||||||
ret = alloc_chrdev_region(&fw_mgmt_dev_num, 0, NUM_MINORS,
|
ret = alloc_chrdev_region(&fw_mgmt_dev_num, 0, NUM_MINORS,
|
||||||
"gb_fw_mgmt");
|
"gb_fw_mgmt");
|
||||||
@ -708,13 +711,13 @@ int fw_mgmt_init(void)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_remove_class:
|
err_remove_class:
|
||||||
class_destroy(fw_mgmt_class);
|
class_unregister(&fw_mgmt_class);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fw_mgmt_exit(void)
|
void fw_mgmt_exit(void)
|
||||||
{
|
{
|
||||||
unregister_chrdev_region(fw_mgmt_dev_num, NUM_MINORS);
|
unregister_chrdev_region(fw_mgmt_dev_num, NUM_MINORS);
|
||||||
class_destroy(fw_mgmt_class);
|
class_unregister(&fw_mgmt_class);
|
||||||
ida_destroy(&fw_mgmt_minors_map);
|
ida_destroy(&fw_mgmt_minors_map);
|
||||||
}
|
}
|
||||||
|
@ -29,10 +29,13 @@ struct gb_raw {
|
|||||||
struct raw_data {
|
struct raw_data {
|
||||||
struct list_head entry;
|
struct list_head entry;
|
||||||
u32 len;
|
u32 len;
|
||||||
u8 data[];
|
u8 data[] __counted_by(len);
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct class raw_class = {
|
||||||
|
.name = "gb_raw",
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct class *raw_class;
|
|
||||||
static int raw_major;
|
static int raw_major;
|
||||||
static const struct file_operations raw_fops;
|
static const struct file_operations raw_fops;
|
||||||
static DEFINE_IDA(minors);
|
static DEFINE_IDA(minors);
|
||||||
@ -70,7 +73,7 @@ static int receive_data(struct gb_raw *raw, u32 len, u8 *data)
|
|||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
raw_data = kmalloc(sizeof(*raw_data) + len, GFP_KERNEL);
|
raw_data = kmalloc(struct_size(raw_data, data, len), GFP_KERNEL);
|
||||||
if (!raw_data) {
|
if (!raw_data) {
|
||||||
retval = -ENOMEM;
|
retval = -ENOMEM;
|
||||||
goto exit;
|
goto exit;
|
||||||
@ -195,7 +198,7 @@ static int gb_raw_probe(struct gb_bundle *bundle,
|
|||||||
if (retval)
|
if (retval)
|
||||||
goto error_connection_disable;
|
goto error_connection_disable;
|
||||||
|
|
||||||
raw->device = device_create(raw_class, &connection->bundle->dev,
|
raw->device = device_create(&raw_class, &connection->bundle->dev,
|
||||||
raw->dev, raw, "gb!raw%d", minor);
|
raw->dev, raw, "gb!raw%d", minor);
|
||||||
if (IS_ERR(raw->device)) {
|
if (IS_ERR(raw->device)) {
|
||||||
retval = PTR_ERR(raw->device);
|
retval = PTR_ERR(raw->device);
|
||||||
@ -229,7 +232,7 @@ static void gb_raw_disconnect(struct gb_bundle *bundle)
|
|||||||
struct raw_data *temp;
|
struct raw_data *temp;
|
||||||
|
|
||||||
// FIXME - handle removing a connection when the char device node is open.
|
// FIXME - handle removing a connection when the char device node is open.
|
||||||
device_destroy(raw_class, raw->dev);
|
device_destroy(&raw_class, raw->dev);
|
||||||
cdev_del(&raw->cdev);
|
cdev_del(&raw->cdev);
|
||||||
gb_connection_disable(connection);
|
gb_connection_disable(connection);
|
||||||
ida_simple_remove(&minors, MINOR(raw->dev));
|
ida_simple_remove(&minors, MINOR(raw->dev));
|
||||||
@ -340,11 +343,9 @@ static int raw_init(void)
|
|||||||
dev_t dev;
|
dev_t dev;
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
raw_class = class_create("gb_raw");
|
retval = class_register(&raw_class);
|
||||||
if (IS_ERR(raw_class)) {
|
if (retval)
|
||||||
retval = PTR_ERR(raw_class);
|
|
||||||
goto error_class;
|
goto error_class;
|
||||||
}
|
|
||||||
|
|
||||||
retval = alloc_chrdev_region(&dev, 0, NUM_MINORS, "gb_raw");
|
retval = alloc_chrdev_region(&dev, 0, NUM_MINORS, "gb_raw");
|
||||||
if (retval < 0)
|
if (retval < 0)
|
||||||
@ -361,7 +362,7 @@ static int raw_init(void)
|
|||||||
error_gb:
|
error_gb:
|
||||||
unregister_chrdev_region(dev, NUM_MINORS);
|
unregister_chrdev_region(dev, NUM_MINORS);
|
||||||
error_chrdev:
|
error_chrdev:
|
||||||
class_destroy(raw_class);
|
class_unregister(&raw_class);
|
||||||
error_class:
|
error_class:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
@ -371,7 +372,7 @@ static void __exit raw_exit(void)
|
|||||||
{
|
{
|
||||||
greybus_deregister(&gb_raw_driver);
|
greybus_deregister(&gb_raw_driver);
|
||||||
unregister_chrdev_region(MKDEV(raw_major, 0), NUM_MINORS);
|
unregister_chrdev_region(MKDEV(raw_major, 0), NUM_MINORS);
|
||||||
class_destroy(raw_class);
|
class_unregister(&raw_class);
|
||||||
ida_destroy(&minors);
|
ida_destroy(&minors);
|
||||||
}
|
}
|
||||||
module_exit(raw_exit);
|
module_exit(raw_exit);
|
||||||
|
@ -395,9 +395,9 @@ int ks_wlan_hw_tx(struct ks_wlan_private *priv, void *p, unsigned long size,
|
|||||||
priv->hostt.buff[priv->hostt.qtail] = le16_to_cpu(hdr->event);
|
priv->hostt.buff[priv->hostt.qtail] = le16_to_cpu(hdr->event);
|
||||||
priv->hostt.qtail = (priv->hostt.qtail + 1) % SME_EVENT_BUFF_SIZE;
|
priv->hostt.qtail = (priv->hostt.qtail + 1) % SME_EVENT_BUFF_SIZE;
|
||||||
|
|
||||||
spin_lock(&priv->tx_dev.tx_dev_lock);
|
spin_lock_bh(&priv->tx_dev.tx_dev_lock);
|
||||||
result = enqueue_txdev(priv, p, size, complete_handler, skb);
|
result = enqueue_txdev(priv, p, size, complete_handler, skb);
|
||||||
spin_unlock(&priv->tx_dev.tx_dev_lock);
|
spin_unlock_bh(&priv->tx_dev.tx_dev_lock);
|
||||||
|
|
||||||
if (txq_has_space(priv))
|
if (txq_has_space(priv))
|
||||||
queue_delayed_work(priv->wq, &priv->rw_dwork, 0);
|
queue_delayed_work(priv->wq, &priv->rw_dwork, 0);
|
||||||
|
@ -777,7 +777,7 @@ static struct i2c_driver dcon_driver = {
|
|||||||
.name = "olpc_dcon",
|
.name = "olpc_dcon",
|
||||||
.pm = &dcon_pm_ops,
|
.pm = &dcon_pm_ops,
|
||||||
},
|
},
|
||||||
.class = I2C_CLASS_DDC | I2C_CLASS_HWMON,
|
.class = I2C_CLASS_HWMON,
|
||||||
.id_table = dcon_idtable,
|
.id_table = dcon_idtable,
|
||||||
.probe = dcon_probe,
|
.probe = dcon_probe,
|
||||||
.remove = dcon_remove,
|
.remove = dcon_remove,
|
||||||
|
@ -56,7 +56,10 @@ static DEFINE_IDR(pi433_idr);
|
|||||||
static DEFINE_MUTEX(minor_lock); /* Protect idr accesses */
|
static DEFINE_MUTEX(minor_lock); /* Protect idr accesses */
|
||||||
static struct dentry *root_dir; /* debugfs root directory for the driver */
|
static struct dentry *root_dir; /* debugfs root directory for the driver */
|
||||||
|
|
||||||
static struct class *pi433_class; /* mainly for udev to create /dev/pi433 */
|
/* mainly for udev to create /dev/pi433 */
|
||||||
|
static const struct class pi433_class = {
|
||||||
|
.name = "pi433",
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* tx config is instance specific
|
* tx config is instance specific
|
||||||
@ -1259,7 +1262,7 @@ static int pi433_probe(struct spi_device *spi)
|
|||||||
|
|
||||||
/* create device */
|
/* create device */
|
||||||
device->devt = MKDEV(MAJOR(pi433_dev), device->minor);
|
device->devt = MKDEV(MAJOR(pi433_dev), device->minor);
|
||||||
device->dev = device_create(pi433_class,
|
device->dev = device_create(&pi433_class,
|
||||||
&spi->dev,
|
&spi->dev,
|
||||||
device->devt,
|
device->devt,
|
||||||
device,
|
device,
|
||||||
@ -1315,7 +1318,7 @@ del_cdev:
|
|||||||
cdev_failed:
|
cdev_failed:
|
||||||
kthread_stop(device->tx_task_struct);
|
kthread_stop(device->tx_task_struct);
|
||||||
send_thread_failed:
|
send_thread_failed:
|
||||||
device_destroy(pi433_class, device->devt);
|
device_destroy(&pi433_class, device->devt);
|
||||||
device_create_failed:
|
device_create_failed:
|
||||||
pi433_free_minor(device);
|
pi433_free_minor(device);
|
||||||
minor_failed:
|
minor_failed:
|
||||||
@ -1342,7 +1345,7 @@ static void pi433_remove(struct spi_device *spi)
|
|||||||
|
|
||||||
kthread_stop(device->tx_task_struct);
|
kthread_stop(device->tx_task_struct);
|
||||||
|
|
||||||
device_destroy(pi433_class, device->devt);
|
device_destroy(&pi433_class, device->devt);
|
||||||
|
|
||||||
cdev_del(device->cdev);
|
cdev_del(device->cdev);
|
||||||
|
|
||||||
@ -1398,18 +1401,18 @@ static int __init pi433_init(void)
|
|||||||
if (status < 0)
|
if (status < 0)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
pi433_class = class_create("pi433");
|
status = class_register(&pi433_class);
|
||||||
if (IS_ERR(pi433_class)) {
|
if (status) {
|
||||||
unregister_chrdev(MAJOR(pi433_dev),
|
unregister_chrdev(MAJOR(pi433_dev),
|
||||||
pi433_spi_driver.driver.name);
|
pi433_spi_driver.driver.name);
|
||||||
return PTR_ERR(pi433_class);
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
root_dir = debugfs_create_dir(KBUILD_MODNAME, NULL);
|
root_dir = debugfs_create_dir(KBUILD_MODNAME, NULL);
|
||||||
|
|
||||||
status = spi_register_driver(&pi433_spi_driver);
|
status = spi_register_driver(&pi433_spi_driver);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
class_destroy(pi433_class);
|
class_unregister(&pi433_class);
|
||||||
unregister_chrdev(MAJOR(pi433_dev),
|
unregister_chrdev(MAJOR(pi433_dev),
|
||||||
pi433_spi_driver.driver.name);
|
pi433_spi_driver.driver.name);
|
||||||
}
|
}
|
||||||
@ -1422,7 +1425,7 @@ module_init(pi433_init);
|
|||||||
static void __exit pi433_exit(void)
|
static void __exit pi433_exit(void)
|
||||||
{
|
{
|
||||||
spi_unregister_driver(&pi433_spi_driver);
|
spi_unregister_driver(&pi433_spi_driver);
|
||||||
class_destroy(pi433_class);
|
class_unregister(&pi433_class);
|
||||||
unregister_chrdev(MAJOR(pi433_dev), pi433_spi_driver.driver.name);
|
unregister_chrdev(MAJOR(pi433_dev), pi433_spi_driver.driver.name);
|
||||||
debugfs_remove(root_dir);
|
debugfs_remove(root_dir);
|
||||||
}
|
}
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
|
||||||
|
|
||||||
config QLGE
|
|
||||||
tristate "QLogic QLGE 10Gb Ethernet Driver Support"
|
|
||||||
depends on ETHERNET && PCI
|
|
||||||
select NET_DEVLINK
|
|
||||||
help
|
|
||||||
This driver supports QLogic ISP8XXX 10Gb Ethernet cards.
|
|
||||||
|
|
||||||
To compile this driver as a module, choose M here. The module will be
|
|
||||||
called qlge.
|
|
@ -1,8 +0,0 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0-only
|
|
||||||
#
|
|
||||||
# Makefile for the Qlogic 10GbE PCI Express ethernet driver
|
|
||||||
#
|
|
||||||
|
|
||||||
obj-$(CONFIG_QLGE) += qlge.o
|
|
||||||
|
|
||||||
qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o qlge_devlink.o
|
|
@ -1,33 +0,0 @@
|
|||||||
* commit 7c734359d350 ("qlge: Size RX buffers based on MTU.", v2.6.33-rc1)
|
|
||||||
introduced dead code in the receive routines, which should be rewritten
|
|
||||||
anyways by the admission of the author himself, see the comment above
|
|
||||||
ql_build_rx_skb(). That function is now used exclusively to handle packets
|
|
||||||
that underwent header splitting but it still contains code to handle non
|
|
||||||
split cases.
|
|
||||||
* truesize accounting is incorrect (ex: a 9000B frame has skb->truesize 10280
|
|
||||||
while containing two frags of order-1 allocations, ie. >16K)
|
|
||||||
* while in that area, using two 8k buffers to store one 9k frame is a poor
|
|
||||||
choice of buffer size.
|
|
||||||
* in the "chain of large buffers" case, the driver uses an skb allocated with
|
|
||||||
head room but only puts data in the frags.
|
|
||||||
* rename "rx" queues to "completion" queues. Calling tx completion queues "rx
|
|
||||||
queues" is confusing.
|
|
||||||
* struct rx_ring is used for rx and tx completions, with some members relevant
|
|
||||||
to one case only
|
|
||||||
* the flow control implementation in firmware is buggy (sends a flood of pause
|
|
||||||
frames, resets the link, device and driver buffer queues become
|
|
||||||
desynchronized), disable it by default
|
|
||||||
* some structures are initialized redundantly (ex. memset 0 after
|
|
||||||
alloc_etherdev())
|
|
||||||
* the driver has a habit of using runtime checks where compile time checks are
|
|
||||||
possible (ex. ql_free_rx_buffers(), ql_alloc_rx_buffers())
|
|
||||||
* reorder struct members to avoid holes if it doesn't impact performance
|
|
||||||
* avoid legacy/deprecated apis (ex. replace pci_dma_*, replace pci_enable_msi,
|
|
||||||
use pci_iomap)
|
|
||||||
* some "while" loops could be rewritten with simple "for", ex.
|
|
||||||
ql_wait_reg_rdy(), ql_start_rx_ring())
|
|
||||||
* remove duplicate and useless comments
|
|
||||||
* fix weird line wrapping (all over, ex. the ql_set_routing_reg() calls in
|
|
||||||
qlge_set_multicast_list()).
|
|
||||||
* fix weird indentation (all over, ex. the for loops in qlge_get_stats())
|
|
||||||
* fix checkpatch issues
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,139 +0,0 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
#include "qlge.h"
|
|
||||||
#include "qlge_devlink.h"
|
|
||||||
|
|
||||||
static void qlge_fill_seg_(struct devlink_fmsg *fmsg,
|
|
||||||
struct mpi_coredump_segment_header *seg_header,
|
|
||||||
u32 *reg_data)
|
|
||||||
{
|
|
||||||
int regs_num = (seg_header->seg_size
|
|
||||||
- sizeof(struct mpi_coredump_segment_header)) / sizeof(u32);
|
|
||||||
int i;
|
|
||||||
|
|
||||||
devlink_fmsg_pair_nest_start(fmsg, seg_header->description);
|
|
||||||
devlink_fmsg_obj_nest_start(fmsg);
|
|
||||||
devlink_fmsg_u32_pair_put(fmsg, "segment", seg_header->seg_num);
|
|
||||||
devlink_fmsg_arr_pair_nest_start(fmsg, "values");
|
|
||||||
for (i = 0; i < regs_num; i++) {
|
|
||||||
devlink_fmsg_u32_put(fmsg, *reg_data);
|
|
||||||
reg_data++;
|
|
||||||
}
|
|
||||||
devlink_fmsg_obj_nest_end(fmsg);
|
|
||||||
devlink_fmsg_arr_pair_nest_end(fmsg);
|
|
||||||
devlink_fmsg_pair_nest_end(fmsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define FILL_SEG(seg_hdr, seg_regs) \
|
|
||||||
qlge_fill_seg_(fmsg, &dump->seg_hdr, dump->seg_regs)
|
|
||||||
|
|
||||||
static int qlge_reporter_coredump(struct devlink_health_reporter *reporter,
|
|
||||||
struct devlink_fmsg *fmsg, void *priv_ctx,
|
|
||||||
struct netlink_ext_ack *extack)
|
|
||||||
{
|
|
||||||
int err = 0;
|
|
||||||
|
|
||||||
struct qlge_adapter *qdev = devlink_health_reporter_priv(reporter);
|
|
||||||
struct qlge_mpi_coredump *dump;
|
|
||||||
wait_queue_head_t wait;
|
|
||||||
|
|
||||||
if (!netif_running(qdev->ndev))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (test_bit(QL_FRC_COREDUMP, &qdev->flags)) {
|
|
||||||
if (qlge_own_firmware(qdev)) {
|
|
||||||
qlge_queue_fw_error(qdev);
|
|
||||||
init_waitqueue_head(&wait);
|
|
||||||
wait_event_timeout(wait, 0, 5 * HZ);
|
|
||||||
} else {
|
|
||||||
netif_err(qdev, ifup, qdev->ndev,
|
|
||||||
"Force Coredump failed because this NIC function doesn't own the firmware\n");
|
|
||||||
return -EPERM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dump = kvmalloc(sizeof(*dump), GFP_KERNEL);
|
|
||||||
if (!dump)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
err = qlge_core_dump(qdev, dump);
|
|
||||||
if (err) {
|
|
||||||
kvfree(dump);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
qlge_soft_reset_mpi_risc(qdev);
|
|
||||||
|
|
||||||
FILL_SEG(core_regs_seg_hdr, mpi_core_regs);
|
|
||||||
FILL_SEG(test_logic_regs_seg_hdr, test_logic_regs);
|
|
||||||
FILL_SEG(rmii_regs_seg_hdr, rmii_regs);
|
|
||||||
FILL_SEG(fcmac1_regs_seg_hdr, fcmac1_regs);
|
|
||||||
FILL_SEG(fcmac2_regs_seg_hdr, fcmac2_regs);
|
|
||||||
FILL_SEG(fc1_mbx_regs_seg_hdr, fc1_mbx_regs);
|
|
||||||
FILL_SEG(ide_regs_seg_hdr, ide_regs);
|
|
||||||
FILL_SEG(nic1_mbx_regs_seg_hdr, nic1_mbx_regs);
|
|
||||||
FILL_SEG(smbus_regs_seg_hdr, smbus_regs);
|
|
||||||
FILL_SEG(fc2_mbx_regs_seg_hdr, fc2_mbx_regs);
|
|
||||||
FILL_SEG(nic2_mbx_regs_seg_hdr, nic2_mbx_regs);
|
|
||||||
FILL_SEG(i2c_regs_seg_hdr, i2c_regs);
|
|
||||||
FILL_SEG(memc_regs_seg_hdr, memc_regs);
|
|
||||||
FILL_SEG(pbus_regs_seg_hdr, pbus_regs);
|
|
||||||
FILL_SEG(mde_regs_seg_hdr, mde_regs);
|
|
||||||
FILL_SEG(nic_regs_seg_hdr, nic_regs);
|
|
||||||
FILL_SEG(nic2_regs_seg_hdr, nic2_regs);
|
|
||||||
FILL_SEG(xgmac1_seg_hdr, xgmac1);
|
|
||||||
FILL_SEG(xgmac2_seg_hdr, xgmac2);
|
|
||||||
FILL_SEG(code_ram_seg_hdr, code_ram);
|
|
||||||
FILL_SEG(memc_ram_seg_hdr, memc_ram);
|
|
||||||
FILL_SEG(xaui_an_hdr, serdes_xaui_an);
|
|
||||||
FILL_SEG(xaui_hss_pcs_hdr, serdes_xaui_hss_pcs);
|
|
||||||
FILL_SEG(xfi_an_hdr, serdes_xfi_an);
|
|
||||||
FILL_SEG(xfi_train_hdr, serdes_xfi_train);
|
|
||||||
FILL_SEG(xfi_hss_pcs_hdr, serdes_xfi_hss_pcs);
|
|
||||||
FILL_SEG(xfi_hss_tx_hdr, serdes_xfi_hss_tx);
|
|
||||||
FILL_SEG(xfi_hss_rx_hdr, serdes_xfi_hss_rx);
|
|
||||||
FILL_SEG(xfi_hss_pll_hdr, serdes_xfi_hss_pll);
|
|
||||||
qlge_fill_seg_(fmsg, &dump->misc_nic_seg_hdr,
|
|
||||||
(u32 *)&dump->misc_nic_info);
|
|
||||||
FILL_SEG(intr_states_seg_hdr, intr_states);
|
|
||||||
FILL_SEG(cam_entries_seg_hdr, cam_entries);
|
|
||||||
FILL_SEG(nic_routing_words_seg_hdr, nic_routing_words);
|
|
||||||
FILL_SEG(ets_seg_hdr, ets);
|
|
||||||
FILL_SEG(probe_dump_seg_hdr, probe_dump);
|
|
||||||
FILL_SEG(routing_reg_seg_hdr, routing_regs);
|
|
||||||
FILL_SEG(mac_prot_reg_seg_hdr, mac_prot_regs);
|
|
||||||
FILL_SEG(xaui2_an_hdr, serdes2_xaui_an);
|
|
||||||
FILL_SEG(xaui2_hss_pcs_hdr, serdes2_xaui_hss_pcs);
|
|
||||||
FILL_SEG(xfi2_an_hdr, serdes2_xfi_an);
|
|
||||||
FILL_SEG(xfi2_train_hdr, serdes2_xfi_train);
|
|
||||||
FILL_SEG(xfi2_hss_pcs_hdr, serdes2_xfi_hss_pcs);
|
|
||||||
FILL_SEG(xfi2_hss_tx_hdr, serdes2_xfi_hss_tx);
|
|
||||||
FILL_SEG(xfi2_hss_rx_hdr, serdes2_xfi_hss_rx);
|
|
||||||
FILL_SEG(xfi2_hss_pll_hdr, serdes2_xfi_hss_pll);
|
|
||||||
FILL_SEG(sem_regs_seg_hdr, sem_regs);
|
|
||||||
|
|
||||||
kvfree(dump);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct devlink_health_reporter_ops qlge_reporter_ops = {
|
|
||||||
.name = "coredump",
|
|
||||||
.dump = qlge_reporter_coredump,
|
|
||||||
};
|
|
||||||
|
|
||||||
long qlge_health_create_reporters(struct qlge_adapter *priv)
|
|
||||||
{
|
|
||||||
struct devlink *devlink;
|
|
||||||
long err = 0;
|
|
||||||
|
|
||||||
devlink = priv_to_devlink(priv);
|
|
||||||
priv->reporter =
|
|
||||||
devlink_health_reporter_create(devlink, &qlge_reporter_ops,
|
|
||||||
0, priv);
|
|
||||||
if (IS_ERR(priv->reporter)) {
|
|
||||||
err = PTR_ERR(priv->reporter);
|
|
||||||
netdev_warn(priv->ndev,
|
|
||||||
"Failed to create reporter, err = %ld\n",
|
|
||||||
err);
|
|
||||||
}
|
|
||||||
return err;
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
||||||
#ifndef QLGE_DEVLINK_H
|
|
||||||
#define QLGE_DEVLINK_H
|
|
||||||
|
|
||||||
#include <net/devlink.h>
|
|
||||||
|
|
||||||
long qlge_health_create_reporters(struct qlge_adapter *priv);
|
|
||||||
|
|
||||||
#endif /* QLGE_DEVLINK_H */
|
|
@ -1,746 +0,0 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/types.h>
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/list.h>
|
|
||||||
#include <linux/pci.h>
|
|
||||||
#include <linux/dma-mapping.h>
|
|
||||||
#include <linux/pagemap.h>
|
|
||||||
#include <linux/sched.h>
|
|
||||||
#include <linux/dmapool.h>
|
|
||||||
#include <linux/mempool.h>
|
|
||||||
#include <linux/spinlock.h>
|
|
||||||
#include <linux/kthread.h>
|
|
||||||
#include <linux/interrupt.h>
|
|
||||||
#include <linux/errno.h>
|
|
||||||
#include <linux/ioport.h>
|
|
||||||
#include <linux/in.h>
|
|
||||||
#include <linux/ip.h>
|
|
||||||
#include <linux/ipv6.h>
|
|
||||||
#include <net/ipv6.h>
|
|
||||||
#include <linux/tcp.h>
|
|
||||||
#include <linux/udp.h>
|
|
||||||
#include <linux/if_arp.h>
|
|
||||||
#include <linux/if_ether.h>
|
|
||||||
#include <linux/netdevice.h>
|
|
||||||
#include <linux/etherdevice.h>
|
|
||||||
#include <linux/ethtool.h>
|
|
||||||
#include <linux/skbuff.h>
|
|
||||||
#include <linux/rtnetlink.h>
|
|
||||||
#include <linux/if_vlan.h>
|
|
||||||
#include <linux/delay.h>
|
|
||||||
#include <linux/mm.h>
|
|
||||||
#include <linux/vmalloc.h>
|
|
||||||
|
|
||||||
#include "qlge.h"
|
|
||||||
|
|
||||||
struct qlge_stats {
|
|
||||||
char stat_string[ETH_GSTRING_LEN];
|
|
||||||
int sizeof_stat;
|
|
||||||
int stat_offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define QL_SIZEOF(m) sizeof_field(struct qlge_adapter, m)
|
|
||||||
#define QL_OFF(m) offsetof(struct qlge_adapter, m)
|
|
||||||
|
|
||||||
static const struct qlge_stats qlge_gstrings_stats[] = {
|
|
||||||
{"tx_pkts", QL_SIZEOF(nic_stats.tx_pkts), QL_OFF(nic_stats.tx_pkts)},
|
|
||||||
{"tx_bytes", QL_SIZEOF(nic_stats.tx_bytes), QL_OFF(nic_stats.tx_bytes)},
|
|
||||||
{"tx_mcast_pkts", QL_SIZEOF(nic_stats.tx_mcast_pkts),
|
|
||||||
QL_OFF(nic_stats.tx_mcast_pkts)},
|
|
||||||
{"tx_bcast_pkts", QL_SIZEOF(nic_stats.tx_bcast_pkts),
|
|
||||||
QL_OFF(nic_stats.tx_bcast_pkts)},
|
|
||||||
{"tx_ucast_pkts", QL_SIZEOF(nic_stats.tx_ucast_pkts),
|
|
||||||
QL_OFF(nic_stats.tx_ucast_pkts)},
|
|
||||||
{"tx_ctl_pkts", QL_SIZEOF(nic_stats.tx_ctl_pkts),
|
|
||||||
QL_OFF(nic_stats.tx_ctl_pkts)},
|
|
||||||
{"tx_pause_pkts", QL_SIZEOF(nic_stats.tx_pause_pkts),
|
|
||||||
QL_OFF(nic_stats.tx_pause_pkts)},
|
|
||||||
{"tx_64_pkts", QL_SIZEOF(nic_stats.tx_64_pkt),
|
|
||||||
QL_OFF(nic_stats.tx_64_pkt)},
|
|
||||||
{"tx_65_to_127_pkts", QL_SIZEOF(nic_stats.tx_65_to_127_pkt),
|
|
||||||
QL_OFF(nic_stats.tx_65_to_127_pkt)},
|
|
||||||
{"tx_128_to_255_pkts", QL_SIZEOF(nic_stats.tx_128_to_255_pkt),
|
|
||||||
QL_OFF(nic_stats.tx_128_to_255_pkt)},
|
|
||||||
{"tx_256_511_pkts", QL_SIZEOF(nic_stats.tx_256_511_pkt),
|
|
||||||
QL_OFF(nic_stats.tx_256_511_pkt)},
|
|
||||||
{"tx_512_to_1023_pkts", QL_SIZEOF(nic_stats.tx_512_to_1023_pkt),
|
|
||||||
QL_OFF(nic_stats.tx_512_to_1023_pkt)},
|
|
||||||
{"tx_1024_to_1518_pkts", QL_SIZEOF(nic_stats.tx_1024_to_1518_pkt),
|
|
||||||
QL_OFF(nic_stats.tx_1024_to_1518_pkt)},
|
|
||||||
{"tx_1519_to_max_pkts", QL_SIZEOF(nic_stats.tx_1519_to_max_pkt),
|
|
||||||
QL_OFF(nic_stats.tx_1519_to_max_pkt)},
|
|
||||||
{"tx_undersize_pkts", QL_SIZEOF(nic_stats.tx_undersize_pkt),
|
|
||||||
QL_OFF(nic_stats.tx_undersize_pkt)},
|
|
||||||
{"tx_oversize_pkts", QL_SIZEOF(nic_stats.tx_oversize_pkt),
|
|
||||||
QL_OFF(nic_stats.tx_oversize_pkt)},
|
|
||||||
{"rx_bytes", QL_SIZEOF(nic_stats.rx_bytes), QL_OFF(nic_stats.rx_bytes)},
|
|
||||||
{"rx_bytes_ok", QL_SIZEOF(nic_stats.rx_bytes_ok),
|
|
||||||
QL_OFF(nic_stats.rx_bytes_ok)},
|
|
||||||
{"rx_pkts", QL_SIZEOF(nic_stats.rx_pkts), QL_OFF(nic_stats.rx_pkts)},
|
|
||||||
{"rx_pkts_ok", QL_SIZEOF(nic_stats.rx_pkts_ok),
|
|
||||||
QL_OFF(nic_stats.rx_pkts_ok)},
|
|
||||||
{"rx_bcast_pkts", QL_SIZEOF(nic_stats.rx_bcast_pkts),
|
|
||||||
QL_OFF(nic_stats.rx_bcast_pkts)},
|
|
||||||
{"rx_mcast_pkts", QL_SIZEOF(nic_stats.rx_mcast_pkts),
|
|
||||||
QL_OFF(nic_stats.rx_mcast_pkts)},
|
|
||||||
{"rx_ucast_pkts", QL_SIZEOF(nic_stats.rx_ucast_pkts),
|
|
||||||
QL_OFF(nic_stats.rx_ucast_pkts)},
|
|
||||||
{"rx_undersize_pkts", QL_SIZEOF(nic_stats.rx_undersize_pkts),
|
|
||||||
QL_OFF(nic_stats.rx_undersize_pkts)},
|
|
||||||
{"rx_oversize_pkts", QL_SIZEOF(nic_stats.rx_oversize_pkts),
|
|
||||||
QL_OFF(nic_stats.rx_oversize_pkts)},
|
|
||||||
{"rx_jabber_pkts", QL_SIZEOF(nic_stats.rx_jabber_pkts),
|
|
||||||
QL_OFF(nic_stats.rx_jabber_pkts)},
|
|
||||||
{"rx_undersize_fcerr_pkts",
|
|
||||||
QL_SIZEOF(nic_stats.rx_undersize_fcerr_pkts),
|
|
||||||
QL_OFF(nic_stats.rx_undersize_fcerr_pkts)},
|
|
||||||
{"rx_drop_events", QL_SIZEOF(nic_stats.rx_drop_events),
|
|
||||||
QL_OFF(nic_stats.rx_drop_events)},
|
|
||||||
{"rx_fcerr_pkts", QL_SIZEOF(nic_stats.rx_fcerr_pkts),
|
|
||||||
QL_OFF(nic_stats.rx_fcerr_pkts)},
|
|
||||||
{"rx_align_err", QL_SIZEOF(nic_stats.rx_align_err),
|
|
||||||
QL_OFF(nic_stats.rx_align_err)},
|
|
||||||
{"rx_symbol_err", QL_SIZEOF(nic_stats.rx_symbol_err),
|
|
||||||
QL_OFF(nic_stats.rx_symbol_err)},
|
|
||||||
{"rx_mac_err", QL_SIZEOF(nic_stats.rx_mac_err),
|
|
||||||
QL_OFF(nic_stats.rx_mac_err)},
|
|
||||||
{"rx_ctl_pkts", QL_SIZEOF(nic_stats.rx_ctl_pkts),
|
|
||||||
QL_OFF(nic_stats.rx_ctl_pkts)},
|
|
||||||
{"rx_pause_pkts", QL_SIZEOF(nic_stats.rx_pause_pkts),
|
|
||||||
QL_OFF(nic_stats.rx_pause_pkts)},
|
|
||||||
{"rx_64_pkts", QL_SIZEOF(nic_stats.rx_64_pkts),
|
|
||||||
QL_OFF(nic_stats.rx_64_pkts)},
|
|
||||||
{"rx_65_to_127_pkts", QL_SIZEOF(nic_stats.rx_65_to_127_pkts),
|
|
||||||
QL_OFF(nic_stats.rx_65_to_127_pkts)},
|
|
||||||
{"rx_128_255_pkts", QL_SIZEOF(nic_stats.rx_128_255_pkts),
|
|
||||||
QL_OFF(nic_stats.rx_128_255_pkts)},
|
|
||||||
{"rx_256_511_pkts", QL_SIZEOF(nic_stats.rx_256_511_pkts),
|
|
||||||
QL_OFF(nic_stats.rx_256_511_pkts)},
|
|
||||||
{"rx_512_to_1023_pkts", QL_SIZEOF(nic_stats.rx_512_to_1023_pkts),
|
|
||||||
QL_OFF(nic_stats.rx_512_to_1023_pkts)},
|
|
||||||
{"rx_1024_to_1518_pkts", QL_SIZEOF(nic_stats.rx_1024_to_1518_pkts),
|
|
||||||
QL_OFF(nic_stats.rx_1024_to_1518_pkts)},
|
|
||||||
{"rx_1519_to_max_pkts", QL_SIZEOF(nic_stats.rx_1519_to_max_pkts),
|
|
||||||
QL_OFF(nic_stats.rx_1519_to_max_pkts)},
|
|
||||||
{"rx_len_err_pkts", QL_SIZEOF(nic_stats.rx_len_err_pkts),
|
|
||||||
QL_OFF(nic_stats.rx_len_err_pkts)},
|
|
||||||
{"rx_code_err", QL_SIZEOF(nic_stats.rx_code_err),
|
|
||||||
QL_OFF(nic_stats.rx_code_err)},
|
|
||||||
{"rx_oversize_err", QL_SIZEOF(nic_stats.rx_oversize_err),
|
|
||||||
QL_OFF(nic_stats.rx_oversize_err)},
|
|
||||||
{"rx_undersize_err", QL_SIZEOF(nic_stats.rx_undersize_err),
|
|
||||||
QL_OFF(nic_stats.rx_undersize_err)},
|
|
||||||
{"rx_preamble_err", QL_SIZEOF(nic_stats.rx_preamble_err),
|
|
||||||
QL_OFF(nic_stats.rx_preamble_err)},
|
|
||||||
{"rx_frame_len_err", QL_SIZEOF(nic_stats.rx_frame_len_err),
|
|
||||||
QL_OFF(nic_stats.rx_frame_len_err)},
|
|
||||||
{"rx_crc_err", QL_SIZEOF(nic_stats.rx_crc_err),
|
|
||||||
QL_OFF(nic_stats.rx_crc_err)},
|
|
||||||
{"rx_err_count", QL_SIZEOF(nic_stats.rx_err_count),
|
|
||||||
QL_OFF(nic_stats.rx_err_count)},
|
|
||||||
{"tx_cbfc_pause_frames0", QL_SIZEOF(nic_stats.tx_cbfc_pause_frames0),
|
|
||||||
QL_OFF(nic_stats.tx_cbfc_pause_frames0)},
|
|
||||||
{"tx_cbfc_pause_frames1", QL_SIZEOF(nic_stats.tx_cbfc_pause_frames1),
|
|
||||||
QL_OFF(nic_stats.tx_cbfc_pause_frames1)},
|
|
||||||
{"tx_cbfc_pause_frames2", QL_SIZEOF(nic_stats.tx_cbfc_pause_frames2),
|
|
||||||
QL_OFF(nic_stats.tx_cbfc_pause_frames2)},
|
|
||||||
{"tx_cbfc_pause_frames3", QL_SIZEOF(nic_stats.tx_cbfc_pause_frames3),
|
|
||||||
QL_OFF(nic_stats.tx_cbfc_pause_frames3)},
|
|
||||||
{"tx_cbfc_pause_frames4", QL_SIZEOF(nic_stats.tx_cbfc_pause_frames4),
|
|
||||||
QL_OFF(nic_stats.tx_cbfc_pause_frames4)},
|
|
||||||
{"tx_cbfc_pause_frames5", QL_SIZEOF(nic_stats.tx_cbfc_pause_frames5),
|
|
||||||
QL_OFF(nic_stats.tx_cbfc_pause_frames5)},
|
|
||||||
{"tx_cbfc_pause_frames6", QL_SIZEOF(nic_stats.tx_cbfc_pause_frames6),
|
|
||||||
QL_OFF(nic_stats.tx_cbfc_pause_frames6)},
|
|
||||||
{"tx_cbfc_pause_frames7", QL_SIZEOF(nic_stats.tx_cbfc_pause_frames7),
|
|
||||||
QL_OFF(nic_stats.tx_cbfc_pause_frames7)},
|
|
||||||
{"rx_cbfc_pause_frames0", QL_SIZEOF(nic_stats.rx_cbfc_pause_frames0),
|
|
||||||
QL_OFF(nic_stats.rx_cbfc_pause_frames0)},
|
|
||||||
{"rx_cbfc_pause_frames1", QL_SIZEOF(nic_stats.rx_cbfc_pause_frames1),
|
|
||||||
QL_OFF(nic_stats.rx_cbfc_pause_frames1)},
|
|
||||||
{"rx_cbfc_pause_frames2", QL_SIZEOF(nic_stats.rx_cbfc_pause_frames2),
|
|
||||||
QL_OFF(nic_stats.rx_cbfc_pause_frames2)},
|
|
||||||
{"rx_cbfc_pause_frames3", QL_SIZEOF(nic_stats.rx_cbfc_pause_frames3),
|
|
||||||
QL_OFF(nic_stats.rx_cbfc_pause_frames3)},
|
|
||||||
{"rx_cbfc_pause_frames4", QL_SIZEOF(nic_stats.rx_cbfc_pause_frames4),
|
|
||||||
QL_OFF(nic_stats.rx_cbfc_pause_frames4)},
|
|
||||||
{"rx_cbfc_pause_frames5", QL_SIZEOF(nic_stats.rx_cbfc_pause_frames5),
|
|
||||||
QL_OFF(nic_stats.rx_cbfc_pause_frames5)},
|
|
||||||
{"rx_cbfc_pause_frames6", QL_SIZEOF(nic_stats.rx_cbfc_pause_frames6),
|
|
||||||
QL_OFF(nic_stats.rx_cbfc_pause_frames6)},
|
|
||||||
{"rx_cbfc_pause_frames7", QL_SIZEOF(nic_stats.rx_cbfc_pause_frames7),
|
|
||||||
QL_OFF(nic_stats.rx_cbfc_pause_frames7)},
|
|
||||||
{"rx_nic_fifo_drop", QL_SIZEOF(nic_stats.rx_nic_fifo_drop),
|
|
||||||
QL_OFF(nic_stats.rx_nic_fifo_drop)},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char qlge_gstrings_test[][ETH_GSTRING_LEN] = {
|
|
||||||
"Loopback test (offline)"
|
|
||||||
};
|
|
||||||
|
|
||||||
#define QLGE_TEST_LEN (sizeof(qlge_gstrings_test) / ETH_GSTRING_LEN)
|
|
||||||
#define QLGE_STATS_LEN ARRAY_SIZE(qlge_gstrings_stats)
|
|
||||||
#define QLGE_RCV_MAC_ERR_STATS 7
|
|
||||||
|
|
||||||
static int qlge_update_ring_coalescing(struct qlge_adapter *qdev)
|
|
||||||
{
|
|
||||||
int i, status = 0;
|
|
||||||
struct rx_ring *rx_ring;
|
|
||||||
struct cqicb *cqicb;
|
|
||||||
|
|
||||||
if (!netif_running(qdev->ndev))
|
|
||||||
return status;
|
|
||||||
|
|
||||||
/* Skip the default queue, and update the outbound handler
|
|
||||||
* queues if they changed.
|
|
||||||
*/
|
|
||||||
cqicb = (struct cqicb *)&qdev->rx_ring[qdev->rss_ring_count];
|
|
||||||
if (le16_to_cpu(cqicb->irq_delay) != qdev->tx_coalesce_usecs ||
|
|
||||||
le16_to_cpu(cqicb->pkt_delay) != qdev->tx_max_coalesced_frames) {
|
|
||||||
for (i = qdev->rss_ring_count; i < qdev->rx_ring_count; i++) {
|
|
||||||
rx_ring = &qdev->rx_ring[i];
|
|
||||||
cqicb = (struct cqicb *)rx_ring;
|
|
||||||
cqicb->irq_delay = cpu_to_le16(qdev->tx_coalesce_usecs);
|
|
||||||
cqicb->pkt_delay =
|
|
||||||
cpu_to_le16(qdev->tx_max_coalesced_frames);
|
|
||||||
cqicb->flags = FLAGS_LI;
|
|
||||||
status = qlge_write_cfg(qdev, cqicb, sizeof(*cqicb),
|
|
||||||
CFG_LCQ, rx_ring->cq_id);
|
|
||||||
if (status) {
|
|
||||||
netif_err(qdev, ifup, qdev->ndev,
|
|
||||||
"Failed to load CQICB.\n");
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Update the inbound (RSS) handler queues if they changed. */
|
|
||||||
cqicb = (struct cqicb *)&qdev->rx_ring[0];
|
|
||||||
if (le16_to_cpu(cqicb->irq_delay) != qdev->rx_coalesce_usecs ||
|
|
||||||
le16_to_cpu(cqicb->pkt_delay) != qdev->rx_max_coalesced_frames) {
|
|
||||||
for (i = 0; i < qdev->rss_ring_count; i++, rx_ring++) {
|
|
||||||
rx_ring = &qdev->rx_ring[i];
|
|
||||||
cqicb = (struct cqicb *)rx_ring;
|
|
||||||
cqicb->irq_delay = cpu_to_le16(qdev->rx_coalesce_usecs);
|
|
||||||
cqicb->pkt_delay =
|
|
||||||
cpu_to_le16(qdev->rx_max_coalesced_frames);
|
|
||||||
cqicb->flags = FLAGS_LI;
|
|
||||||
status = qlge_write_cfg(qdev, cqicb, sizeof(*cqicb),
|
|
||||||
CFG_LCQ, rx_ring->cq_id);
|
|
||||||
if (status) {
|
|
||||||
netif_err(qdev, ifup, qdev->ndev,
|
|
||||||
"Failed to load CQICB.\n");
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exit:
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void qlge_update_stats(struct qlge_adapter *qdev)
|
|
||||||
{
|
|
||||||
u32 i;
|
|
||||||
u64 data;
|
|
||||||
u64 *iter = &qdev->nic_stats.tx_pkts;
|
|
||||||
|
|
||||||
spin_lock(&qdev->stats_lock);
|
|
||||||
if (qlge_sem_spinlock(qdev, qdev->xg_sem_mask)) {
|
|
||||||
netif_err(qdev, drv, qdev->ndev,
|
|
||||||
"Couldn't get xgmac sem.\n");
|
|
||||||
goto quit;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Get TX statistics.
|
|
||||||
*/
|
|
||||||
for (i = 0x200; i < 0x280; i += 8) {
|
|
||||||
if (qlge_read_xgmac_reg64(qdev, i, &data)) {
|
|
||||||
netif_err(qdev, drv, qdev->ndev,
|
|
||||||
"Error reading status register 0x%.04x.\n",
|
|
||||||
i);
|
|
||||||
goto end;
|
|
||||||
} else {
|
|
||||||
*iter = data;
|
|
||||||
}
|
|
||||||
iter++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get RX statistics.
|
|
||||||
*/
|
|
||||||
for (i = 0x300; i < 0x3d0; i += 8) {
|
|
||||||
if (qlge_read_xgmac_reg64(qdev, i, &data)) {
|
|
||||||
netif_err(qdev, drv, qdev->ndev,
|
|
||||||
"Error reading status register 0x%.04x.\n",
|
|
||||||
i);
|
|
||||||
goto end;
|
|
||||||
} else {
|
|
||||||
*iter = data;
|
|
||||||
}
|
|
||||||
iter++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Update receive mac error statistics */
|
|
||||||
iter += QLGE_RCV_MAC_ERR_STATS;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get Per-priority TX pause frame counter statistics.
|
|
||||||
*/
|
|
||||||
for (i = 0x500; i < 0x540; i += 8) {
|
|
||||||
if (qlge_read_xgmac_reg64(qdev, i, &data)) {
|
|
||||||
netif_err(qdev, drv, qdev->ndev,
|
|
||||||
"Error reading status register 0x%.04x.\n",
|
|
||||||
i);
|
|
||||||
goto end;
|
|
||||||
} else {
|
|
||||||
*iter = data;
|
|
||||||
}
|
|
||||||
iter++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get Per-priority RX pause frame counter statistics.
|
|
||||||
*/
|
|
||||||
for (i = 0x568; i < 0x5a8; i += 8) {
|
|
||||||
if (qlge_read_xgmac_reg64(qdev, i, &data)) {
|
|
||||||
netif_err(qdev, drv, qdev->ndev,
|
|
||||||
"Error reading status register 0x%.04x.\n",
|
|
||||||
i);
|
|
||||||
goto end;
|
|
||||||
} else {
|
|
||||||
*iter = data;
|
|
||||||
}
|
|
||||||
iter++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get RX NIC FIFO DROP statistics.
|
|
||||||
*/
|
|
||||||
if (qlge_read_xgmac_reg64(qdev, 0x5b8, &data)) {
|
|
||||||
netif_err(qdev, drv, qdev->ndev,
|
|
||||||
"Error reading status register 0x%.04x.\n", i);
|
|
||||||
goto end;
|
|
||||||
} else {
|
|
||||||
*iter = data;
|
|
||||||
}
|
|
||||||
end:
|
|
||||||
qlge_sem_unlock(qdev, qdev->xg_sem_mask);
|
|
||||||
quit:
|
|
||||||
spin_unlock(&qdev->stats_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void qlge_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
|
|
||||||
{
|
|
||||||
int index;
|
|
||||||
|
|
||||||
switch (stringset) {
|
|
||||||
case ETH_SS_TEST:
|
|
||||||
memcpy(buf, *qlge_gstrings_test, QLGE_TEST_LEN * ETH_GSTRING_LEN);
|
|
||||||
break;
|
|
||||||
case ETH_SS_STATS:
|
|
||||||
for (index = 0; index < QLGE_STATS_LEN; index++) {
|
|
||||||
memcpy(buf + index * ETH_GSTRING_LEN,
|
|
||||||
qlge_gstrings_stats[index].stat_string,
|
|
||||||
ETH_GSTRING_LEN);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int qlge_get_sset_count(struct net_device *dev, int sset)
|
|
||||||
{
|
|
||||||
switch (sset) {
|
|
||||||
case ETH_SS_TEST:
|
|
||||||
return QLGE_TEST_LEN;
|
|
||||||
case ETH_SS_STATS:
|
|
||||||
return QLGE_STATS_LEN;
|
|
||||||
default:
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
qlge_get_ethtool_stats(struct net_device *ndev,
|
|
||||||
struct ethtool_stats *stats, u64 *data)
|
|
||||||
{
|
|
||||||
struct qlge_adapter *qdev = netdev_to_qdev(ndev);
|
|
||||||
int index, length;
|
|
||||||
|
|
||||||
length = QLGE_STATS_LEN;
|
|
||||||
qlge_update_stats(qdev);
|
|
||||||
|
|
||||||
for (index = 0; index < length; index++) {
|
|
||||||
char *p = (char *)qdev +
|
|
||||||
qlge_gstrings_stats[index].stat_offset;
|
|
||||||
*data++ = (qlge_gstrings_stats[index].sizeof_stat ==
|
|
||||||
sizeof(u64)) ? *(u64 *)p : (*(u32 *)p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int qlge_get_link_ksettings(struct net_device *ndev,
|
|
||||||
struct ethtool_link_ksettings *ecmd)
|
|
||||||
{
|
|
||||||
struct qlge_adapter *qdev = netdev_to_qdev(ndev);
|
|
||||||
u32 supported, advertising;
|
|
||||||
|
|
||||||
supported = SUPPORTED_10000baseT_Full;
|
|
||||||
advertising = ADVERTISED_10000baseT_Full;
|
|
||||||
|
|
||||||
if ((qdev->link_status & STS_LINK_TYPE_MASK) ==
|
|
||||||
STS_LINK_TYPE_10GBASET) {
|
|
||||||
supported |= (SUPPORTED_TP | SUPPORTED_Autoneg);
|
|
||||||
advertising |= (ADVERTISED_TP | ADVERTISED_Autoneg);
|
|
||||||
ecmd->base.port = PORT_TP;
|
|
||||||
ecmd->base.autoneg = AUTONEG_ENABLE;
|
|
||||||
} else {
|
|
||||||
supported |= SUPPORTED_FIBRE;
|
|
||||||
advertising |= ADVERTISED_FIBRE;
|
|
||||||
ecmd->base.port = PORT_FIBRE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ecmd->base.speed = SPEED_10000;
|
|
||||||
ecmd->base.duplex = DUPLEX_FULL;
|
|
||||||
|
|
||||||
ethtool_convert_legacy_u32_to_link_mode(ecmd->link_modes.supported,
|
|
||||||
supported);
|
|
||||||
ethtool_convert_legacy_u32_to_link_mode(ecmd->link_modes.advertising,
|
|
||||||
advertising);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void qlge_get_drvinfo(struct net_device *ndev,
|
|
||||||
struct ethtool_drvinfo *drvinfo)
|
|
||||||
{
|
|
||||||
struct qlge_adapter *qdev = netdev_to_qdev(ndev);
|
|
||||||
|
|
||||||
strscpy(drvinfo->driver, qlge_driver_name, sizeof(drvinfo->driver));
|
|
||||||
strscpy(drvinfo->version, qlge_driver_version,
|
|
||||||
sizeof(drvinfo->version));
|
|
||||||
snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
|
|
||||||
"v%d.%d.%d",
|
|
||||||
(qdev->fw_rev_id & 0x00ff0000) >> 16,
|
|
||||||
(qdev->fw_rev_id & 0x0000ff00) >> 8,
|
|
||||||
(qdev->fw_rev_id & 0x000000ff));
|
|
||||||
strscpy(drvinfo->bus_info, pci_name(qdev->pdev),
|
|
||||||
sizeof(drvinfo->bus_info));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void qlge_get_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
|
|
||||||
{
|
|
||||||
struct qlge_adapter *qdev = netdev_to_qdev(ndev);
|
|
||||||
unsigned short ssys_dev = qdev->pdev->subsystem_device;
|
|
||||||
|
|
||||||
/* WOL is only supported for mezz card. */
|
|
||||||
if (ssys_dev == QLGE_MEZZ_SSYS_ID_068 ||
|
|
||||||
ssys_dev == QLGE_MEZZ_SSYS_ID_180) {
|
|
||||||
wol->supported = WAKE_MAGIC;
|
|
||||||
wol->wolopts = qdev->wol;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int qlge_set_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
|
|
||||||
{
|
|
||||||
struct qlge_adapter *qdev = netdev_to_qdev(ndev);
|
|
||||||
unsigned short ssys_dev = qdev->pdev->subsystem_device;
|
|
||||||
|
|
||||||
/* WOL is only supported for mezz card. */
|
|
||||||
if (ssys_dev != QLGE_MEZZ_SSYS_ID_068 &&
|
|
||||||
ssys_dev != QLGE_MEZZ_SSYS_ID_180) {
|
|
||||||
netif_info(qdev, drv, qdev->ndev,
|
|
||||||
"WOL is only supported for mezz card\n");
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
}
|
|
||||||
if (wol->wolopts & ~WAKE_MAGIC)
|
|
||||||
return -EINVAL;
|
|
||||||
qdev->wol = wol->wolopts;
|
|
||||||
|
|
||||||
netif_info(qdev, drv, qdev->ndev, "Set wol option 0x%x\n", qdev->wol);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int qlge_set_phys_id(struct net_device *ndev,
|
|
||||||
enum ethtool_phys_id_state state)
|
|
||||||
|
|
||||||
{
|
|
||||||
struct qlge_adapter *qdev = netdev_to_qdev(ndev);
|
|
||||||
|
|
||||||
switch (state) {
|
|
||||||
case ETHTOOL_ID_ACTIVE:
|
|
||||||
/* Save the current LED settings */
|
|
||||||
if (qlge_mb_get_led_cfg(qdev))
|
|
||||||
return -EIO;
|
|
||||||
|
|
||||||
/* Start blinking */
|
|
||||||
qlge_mb_set_led_cfg(qdev, QL_LED_BLINK);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case ETHTOOL_ID_INACTIVE:
|
|
||||||
/* Restore LED settings */
|
|
||||||
if (qlge_mb_set_led_cfg(qdev, qdev->led_config))
|
|
||||||
return -EIO;
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int qlge_start_loopback(struct qlge_adapter *qdev)
|
|
||||||
{
|
|
||||||
if (netif_carrier_ok(qdev->ndev)) {
|
|
||||||
set_bit(QL_LB_LINK_UP, &qdev->flags);
|
|
||||||
netif_carrier_off(qdev->ndev);
|
|
||||||
} else {
|
|
||||||
clear_bit(QL_LB_LINK_UP, &qdev->flags);
|
|
||||||
}
|
|
||||||
qdev->link_config |= CFG_LOOPBACK_PCS;
|
|
||||||
return qlge_mb_set_port_cfg(qdev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void qlge_stop_loopback(struct qlge_adapter *qdev)
|
|
||||||
{
|
|
||||||
qdev->link_config &= ~CFG_LOOPBACK_PCS;
|
|
||||||
qlge_mb_set_port_cfg(qdev);
|
|
||||||
if (test_bit(QL_LB_LINK_UP, &qdev->flags)) {
|
|
||||||
netif_carrier_on(qdev->ndev);
|
|
||||||
clear_bit(QL_LB_LINK_UP, &qdev->flags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void qlge_create_lb_frame(struct sk_buff *skb,
|
|
||||||
unsigned int frame_size)
|
|
||||||
{
|
|
||||||
memset(skb->data, 0xFF, frame_size);
|
|
||||||
frame_size &= ~1;
|
|
||||||
memset(&skb->data[frame_size / 2], 0xAA, frame_size / 2 - 1);
|
|
||||||
skb->data[frame_size / 2 + 10] = (unsigned char)0xBE;
|
|
||||||
skb->data[frame_size / 2 + 12] = (unsigned char)0xAF;
|
|
||||||
}
|
|
||||||
|
|
||||||
void qlge_check_lb_frame(struct qlge_adapter *qdev,
|
|
||||||
struct sk_buff *skb)
|
|
||||||
{
|
|
||||||
unsigned int frame_size = skb->len;
|
|
||||||
|
|
||||||
if ((*(skb->data + 3) == 0xFF) &&
|
|
||||||
(*(skb->data + frame_size / 2 + 10) == 0xBE) &&
|
|
||||||
(*(skb->data + frame_size / 2 + 12) == 0xAF)) {
|
|
||||||
atomic_dec(&qdev->lb_count);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int qlge_run_loopback_test(struct qlge_adapter *qdev)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
netdev_tx_t rc;
|
|
||||||
struct sk_buff *skb;
|
|
||||||
unsigned int size = SMALL_BUF_MAP_SIZE;
|
|
||||||
|
|
||||||
for (i = 0; i < 64; i++) {
|
|
||||||
skb = netdev_alloc_skb(qdev->ndev, size);
|
|
||||||
if (!skb)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
skb->queue_mapping = 0;
|
|
||||||
skb_put(skb, size);
|
|
||||||
qlge_create_lb_frame(skb, size);
|
|
||||||
rc = qlge_lb_send(skb, qdev->ndev);
|
|
||||||
if (rc != NETDEV_TX_OK)
|
|
||||||
return -EPIPE;
|
|
||||||
atomic_inc(&qdev->lb_count);
|
|
||||||
}
|
|
||||||
/* Give queue time to settle before testing results. */
|
|
||||||
usleep_range(2000, 2100);
|
|
||||||
qlge_clean_lb_rx_ring(&qdev->rx_ring[0], 128);
|
|
||||||
return atomic_read(&qdev->lb_count) ? -EIO : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int qlge_loopback_test(struct qlge_adapter *qdev, u64 *data)
|
|
||||||
{
|
|
||||||
*data = qlge_start_loopback(qdev);
|
|
||||||
if (*data)
|
|
||||||
goto out;
|
|
||||||
*data = qlge_run_loopback_test(qdev);
|
|
||||||
out:
|
|
||||||
qlge_stop_loopback(qdev);
|
|
||||||
return *data;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void qlge_self_test(struct net_device *ndev,
|
|
||||||
struct ethtool_test *eth_test, u64 *data)
|
|
||||||
{
|
|
||||||
struct qlge_adapter *qdev = netdev_to_qdev(ndev);
|
|
||||||
|
|
||||||
memset(data, 0, sizeof(u64) * QLGE_TEST_LEN);
|
|
||||||
|
|
||||||
if (netif_running(ndev)) {
|
|
||||||
set_bit(QL_SELFTEST, &qdev->flags);
|
|
||||||
if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
|
|
||||||
/* Offline tests */
|
|
||||||
if (qlge_loopback_test(qdev, &data[0]))
|
|
||||||
eth_test->flags |= ETH_TEST_FL_FAILED;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
/* Online tests */
|
|
||||||
data[0] = 0;
|
|
||||||
}
|
|
||||||
clear_bit(QL_SELFTEST, &qdev->flags);
|
|
||||||
/* Give link time to come up after
|
|
||||||
* port configuration changes.
|
|
||||||
*/
|
|
||||||
msleep_interruptible(4 * 1000);
|
|
||||||
} else {
|
|
||||||
netif_err(qdev, drv, qdev->ndev,
|
|
||||||
"is down, Loopback test will fail.\n");
|
|
||||||
eth_test->flags |= ETH_TEST_FL_FAILED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int qlge_get_regs_len(struct net_device *ndev)
|
|
||||||
{
|
|
||||||
struct qlge_adapter *qdev = netdev_to_qdev(ndev);
|
|
||||||
|
|
||||||
if (!test_bit(QL_FRC_COREDUMP, &qdev->flags))
|
|
||||||
return sizeof(struct qlge_mpi_coredump);
|
|
||||||
else
|
|
||||||
return sizeof(struct qlge_reg_dump);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void qlge_get_regs(struct net_device *ndev,
|
|
||||||
struct ethtool_regs *regs, void *p)
|
|
||||||
{
|
|
||||||
struct qlge_adapter *qdev = netdev_to_qdev(ndev);
|
|
||||||
|
|
||||||
qlge_get_dump(qdev, p);
|
|
||||||
if (!test_bit(QL_FRC_COREDUMP, &qdev->flags))
|
|
||||||
regs->len = sizeof(struct qlge_mpi_coredump);
|
|
||||||
else
|
|
||||||
regs->len = sizeof(struct qlge_reg_dump);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int qlge_get_coalesce(struct net_device *ndev,
|
|
||||||
struct ethtool_coalesce *c,
|
|
||||||
struct kernel_ethtool_coalesce *kernel_coal,
|
|
||||||
struct netlink_ext_ack *extack)
|
|
||||||
{
|
|
||||||
struct qlge_adapter *qdev = netdev_to_qdev(ndev);
|
|
||||||
|
|
||||||
c->rx_coalesce_usecs = qdev->rx_coalesce_usecs;
|
|
||||||
c->tx_coalesce_usecs = qdev->tx_coalesce_usecs;
|
|
||||||
|
|
||||||
/* This chip coalesces as follows:
|
|
||||||
* If a packet arrives, hold off interrupts until
|
|
||||||
* cqicb->int_delay expires, but if no other packets arrive don't
|
|
||||||
* wait longer than cqicb->pkt_int_delay. But ethtool doesn't use a
|
|
||||||
* timer to coalesce on a frame basis. So, we have to take ethtool's
|
|
||||||
* max_coalesced_frames value and convert it to a delay in microseconds.
|
|
||||||
* We do this by using a basic thoughput of 1,000,000 frames per
|
|
||||||
* second @ (1024 bytes). This means one frame per usec. So it's a
|
|
||||||
* simple one to one ratio.
|
|
||||||
*/
|
|
||||||
c->rx_max_coalesced_frames = qdev->rx_max_coalesced_frames;
|
|
||||||
c->tx_max_coalesced_frames = qdev->tx_max_coalesced_frames;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int qlge_set_coalesce(struct net_device *ndev,
|
|
||||||
struct ethtool_coalesce *c,
|
|
||||||
struct kernel_ethtool_coalesce *kernel_coal,
|
|
||||||
struct netlink_ext_ack *extack)
|
|
||||||
{
|
|
||||||
struct qlge_adapter *qdev = netdev_to_qdev(ndev);
|
|
||||||
|
|
||||||
/* Validate user parameters. */
|
|
||||||
if (c->rx_coalesce_usecs > qdev->rx_ring_size / 2)
|
|
||||||
return -EINVAL;
|
|
||||||
/* Don't wait more than 10 usec. */
|
|
||||||
if (c->rx_max_coalesced_frames > MAX_INTER_FRAME_WAIT)
|
|
||||||
return -EINVAL;
|
|
||||||
if (c->tx_coalesce_usecs > qdev->tx_ring_size / 2)
|
|
||||||
return -EINVAL;
|
|
||||||
if (c->tx_max_coalesced_frames > MAX_INTER_FRAME_WAIT)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
/* Verify a change took place before updating the hardware. */
|
|
||||||
if (qdev->rx_coalesce_usecs == c->rx_coalesce_usecs &&
|
|
||||||
qdev->tx_coalesce_usecs == c->tx_coalesce_usecs &&
|
|
||||||
qdev->rx_max_coalesced_frames == c->rx_max_coalesced_frames &&
|
|
||||||
qdev->tx_max_coalesced_frames == c->tx_max_coalesced_frames)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
qdev->rx_coalesce_usecs = c->rx_coalesce_usecs;
|
|
||||||
qdev->tx_coalesce_usecs = c->tx_coalesce_usecs;
|
|
||||||
qdev->rx_max_coalesced_frames = c->rx_max_coalesced_frames;
|
|
||||||
qdev->tx_max_coalesced_frames = c->tx_max_coalesced_frames;
|
|
||||||
|
|
||||||
return qlge_update_ring_coalescing(qdev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void qlge_get_pauseparam(struct net_device *ndev,
|
|
||||||
struct ethtool_pauseparam *pause)
|
|
||||||
{
|
|
||||||
struct qlge_adapter *qdev = netdev_to_qdev(ndev);
|
|
||||||
|
|
||||||
qlge_mb_get_port_cfg(qdev);
|
|
||||||
if (qdev->link_config & CFG_PAUSE_STD) {
|
|
||||||
pause->rx_pause = 1;
|
|
||||||
pause->tx_pause = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int qlge_set_pauseparam(struct net_device *ndev,
|
|
||||||
struct ethtool_pauseparam *pause)
|
|
||||||
{
|
|
||||||
struct qlge_adapter *qdev = netdev_to_qdev(ndev);
|
|
||||||
|
|
||||||
if ((pause->rx_pause) && (pause->tx_pause))
|
|
||||||
qdev->link_config |= CFG_PAUSE_STD;
|
|
||||||
else if (!pause->rx_pause && !pause->tx_pause)
|
|
||||||
qdev->link_config &= ~CFG_PAUSE_STD;
|
|
||||||
else
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
return qlge_mb_set_port_cfg(qdev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 qlge_get_msglevel(struct net_device *ndev)
|
|
||||||
{
|
|
||||||
struct qlge_adapter *qdev = netdev_to_qdev(ndev);
|
|
||||||
|
|
||||||
return qdev->msg_enable;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void qlge_set_msglevel(struct net_device *ndev, u32 value)
|
|
||||||
{
|
|
||||||
struct qlge_adapter *qdev = netdev_to_qdev(ndev);
|
|
||||||
|
|
||||||
qdev->msg_enable = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
const struct ethtool_ops qlge_ethtool_ops = {
|
|
||||||
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
|
|
||||||
ETHTOOL_COALESCE_MAX_FRAMES,
|
|
||||||
.get_drvinfo = qlge_get_drvinfo,
|
|
||||||
.get_wol = qlge_get_wol,
|
|
||||||
.set_wol = qlge_set_wol,
|
|
||||||
.get_regs_len = qlge_get_regs_len,
|
|
||||||
.get_regs = qlge_get_regs,
|
|
||||||
.get_msglevel = qlge_get_msglevel,
|
|
||||||
.set_msglevel = qlge_set_msglevel,
|
|
||||||
.get_link = ethtool_op_get_link,
|
|
||||||
.set_phys_id = qlge_set_phys_id,
|
|
||||||
.self_test = qlge_self_test,
|
|
||||||
.get_pauseparam = qlge_get_pauseparam,
|
|
||||||
.set_pauseparam = qlge_set_pauseparam,
|
|
||||||
.get_coalesce = qlge_get_coalesce,
|
|
||||||
.set_coalesce = qlge_set_coalesce,
|
|
||||||
.get_sset_count = qlge_get_sset_count,
|
|
||||||
.get_strings = qlge_get_strings,
|
|
||||||
.get_ethtool_stats = qlge_get_ethtool_stats,
|
|
||||||
.get_link_ksettings = qlge_get_link_ksettings,
|
|
||||||
};
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -73,19 +73,16 @@ void dot11d_channel_map(u8 channel_plan, struct rtllib_device *ieee)
|
|||||||
for (i = 12; i <= 14; i++)
|
for (i = 12; i <= 14; i++)
|
||||||
GET_DOT11D_INFO(ieee)->channel_map[i] = 2;
|
GET_DOT11D_INFO(ieee)->channel_map[i] = 2;
|
||||||
ieee->bss_start_channel = 10;
|
ieee->bss_start_channel = 10;
|
||||||
ieee->ibss_maxjoin_chal = 11;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COUNTRY_CODE_WORLD_WIDE_13:
|
case COUNTRY_CODE_WORLD_WIDE_13:
|
||||||
for (i = 12; i <= 13; i++)
|
for (i = 12; i <= 13; i++)
|
||||||
GET_DOT11D_INFO(ieee)->channel_map[i] = 2;
|
GET_DOT11D_INFO(ieee)->channel_map[i] = 2;
|
||||||
ieee->bss_start_channel = 10;
|
ieee->bss_start_channel = 10;
|
||||||
ieee->ibss_maxjoin_chal = 11;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ieee->bss_start_channel = 1;
|
ieee->bss_start_channel = 1;
|
||||||
ieee->ibss_maxjoin_chal = 14;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,6 @@
|
|||||||
|
|
||||||
#define MAX_SILENT_RESET_RX_SLOT_NUM 10
|
#define MAX_SILENT_RESET_RX_SLOT_NUM 10
|
||||||
|
|
||||||
#define RX_MPDU_QUEUE 0
|
|
||||||
|
|
||||||
enum rtl819x_loopback {
|
enum rtl819x_loopback {
|
||||||
RTL819X_NO_LOOPBACK = 0,
|
RTL819X_NO_LOOPBACK = 0,
|
||||||
RTL819X_MAC_LOOPBACK = 1,
|
RTL819X_MAC_LOOPBACK = 1,
|
||||||
|
@ -18,30 +18,6 @@
|
|||||||
static int WDCAPARA_ADD[] = {EDCAPARA_BE, EDCAPARA_BK, EDCAPARA_VI,
|
static int WDCAPARA_ADD[] = {EDCAPARA_BE, EDCAPARA_BK, EDCAPARA_VI,
|
||||||
EDCAPARA_VO};
|
EDCAPARA_VO};
|
||||||
|
|
||||||
void rtl92e_start_beacon(struct net_device *dev)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
|
|
||||||
struct rtllib_network *net = &priv->rtllib->current_network;
|
|
||||||
u16 BcnTimeCfg = 0;
|
|
||||||
u16 BcnCW = 6;
|
|
||||||
u16 BcnIFS = 0xf;
|
|
||||||
|
|
||||||
rtl92e_irq_disable(dev);
|
|
||||||
|
|
||||||
rtl92e_writew(dev, ATIMWND, 2);
|
|
||||||
|
|
||||||
rtl92e_writew(dev, BCN_INTERVAL, net->beacon_interval);
|
|
||||||
rtl92e_writew(dev, BCN_DRV_EARLY_INT, 10);
|
|
||||||
rtl92e_writew(dev, BCN_DMATIME, 256);
|
|
||||||
|
|
||||||
rtl92e_writeb(dev, BCN_ERR_THRESH, 100);
|
|
||||||
|
|
||||||
BcnTimeCfg |= BcnCW << BCN_TCFG_CW_SHIFT;
|
|
||||||
BcnTimeCfg |= BcnIFS << BCN_TCFG_IFS;
|
|
||||||
rtl92e_writew(dev, BCN_TCFG, BcnTimeCfg);
|
|
||||||
rtl92e_irq_enable(dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _rtl92e_update_msr(struct net_device *dev)
|
static void _rtl92e_update_msr(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct r8192_priv *priv = rtllib_priv(dev);
|
struct r8192_priv *priv = rtllib_priv(dev);
|
||||||
@ -55,10 +31,6 @@ static void _rtl92e_update_msr(struct net_device *dev)
|
|||||||
if (priv->rtllib->link_state == MAC80211_LINKED)
|
if (priv->rtllib->link_state == MAC80211_LINKED)
|
||||||
msr |= MSR_LINK_MANAGED;
|
msr |= MSR_LINK_MANAGED;
|
||||||
break;
|
break;
|
||||||
case IW_MODE_ADHOC:
|
|
||||||
if (priv->rtllib->link_state == MAC80211_LINKED)
|
|
||||||
msr |= MSR_LINK_ADHOC;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -513,10 +485,10 @@ bool rtl92e_start_adapter(struct net_device *dev)
|
|||||||
start:
|
start:
|
||||||
rtl92e_reset_desc_ring(dev);
|
rtl92e_reset_desc_ring(dev);
|
||||||
priv->rf_mode = RF_OP_By_SW_3wire;
|
priv->rf_mode = RF_OP_By_SW_3wire;
|
||||||
if (priv->rst_progress == RESET_TYPE_NORESET) {
|
|
||||||
rtl92e_writeb(dev, ANAPAR, 0x37);
|
rtl92e_writeb(dev, ANAPAR, 0x37);
|
||||||
mdelay(500);
|
mdelay(500);
|
||||||
}
|
|
||||||
priv->fw_info->status = FW_STATUS_0_INIT;
|
priv->fw_info->status = FW_STATUS_0_INIT;
|
||||||
|
|
||||||
ulRegRead = rtl92e_readl(dev, CPU_GEN);
|
ulRegRead = rtl92e_readl(dev, CPU_GEN);
|
||||||
@ -546,21 +518,20 @@ start:
|
|||||||
}
|
}
|
||||||
|
|
||||||
priv->loopback_mode = RTL819X_NO_LOOPBACK;
|
priv->loopback_mode = RTL819X_NO_LOOPBACK;
|
||||||
if (priv->rst_progress == RESET_TYPE_NORESET) {
|
ulRegRead = rtl92e_readl(dev, CPU_GEN);
|
||||||
ulRegRead = rtl92e_readl(dev, CPU_GEN);
|
if (priv->loopback_mode == RTL819X_NO_LOOPBACK)
|
||||||
if (priv->loopback_mode == RTL819X_NO_LOOPBACK)
|
ulRegRead = (ulRegRead & CPU_GEN_NO_LOOPBACK_MSK) |
|
||||||
ulRegRead = (ulRegRead & CPU_GEN_NO_LOOPBACK_MSK) |
|
CPU_GEN_NO_LOOPBACK_SET;
|
||||||
CPU_GEN_NO_LOOPBACK_SET;
|
else if (priv->loopback_mode == RTL819X_MAC_LOOPBACK)
|
||||||
else if (priv->loopback_mode == RTL819X_MAC_LOOPBACK)
|
ulRegRead |= CPU_CCK_LOOPBACK;
|
||||||
ulRegRead |= CPU_CCK_LOOPBACK;
|
else
|
||||||
else
|
netdev_err(dev, "%s: Invalid loopback mode setting.\n",
|
||||||
netdev_err(dev, "%s: Invalid loopback mode setting.\n",
|
__func__);
|
||||||
__func__);
|
|
||||||
|
|
||||||
rtl92e_writel(dev, CPU_GEN, ulRegRead);
|
rtl92e_writel(dev, CPU_GEN, ulRegRead);
|
||||||
|
|
||||||
|
udelay(500);
|
||||||
|
|
||||||
udelay(500);
|
|
||||||
}
|
|
||||||
_rtl92e_hwconfig(dev);
|
_rtl92e_hwconfig(dev);
|
||||||
rtl92e_writeb(dev, CMDR, CR_RE | CR_TE);
|
rtl92e_writeb(dev, CMDR, CR_RE | CR_TE);
|
||||||
|
|
||||||
@ -595,8 +566,7 @@ start:
|
|||||||
|
|
||||||
rtl92e_writeb(dev, ACK_TIMEOUT, 0x30);
|
rtl92e_writeb(dev, ACK_TIMEOUT, 0x30);
|
||||||
|
|
||||||
if (priv->rst_progress == RESET_TYPE_NORESET)
|
rtl92e_set_wireless_mode(dev, priv->rtllib->mode);
|
||||||
rtl92e_set_wireless_mode(dev, priv->rtllib->mode);
|
|
||||||
rtl92e_cam_reset(dev);
|
rtl92e_cam_reset(dev);
|
||||||
{
|
{
|
||||||
u8 SECR_value = 0x0;
|
u8 SECR_value = 0x0;
|
||||||
@ -635,12 +605,10 @@ start:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->rst_progress == RESET_TYPE_NORESET) {
|
rtStatus = rtl92e_config_rf(dev);
|
||||||
rtStatus = rtl92e_config_rf(dev);
|
if (!rtStatus) {
|
||||||
if (!rtStatus) {
|
netdev_info(dev, "RF Config failed\n");
|
||||||
netdev_info(dev, "RF Config failed\n");
|
return rtStatus;
|
||||||
return rtStatus;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rtl92e_set_bb_reg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
|
rtl92e_set_bb_reg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
|
||||||
@ -662,39 +630,37 @@ start:
|
|||||||
else
|
else
|
||||||
priv->rf_mode = RF_OP_By_SW_3wire;
|
priv->rf_mode = RF_OP_By_SW_3wire;
|
||||||
|
|
||||||
if (priv->rst_progress == RESET_TYPE_NORESET) {
|
rtl92e_dm_init_txpower_tracking(dev);
|
||||||
rtl92e_dm_init_txpower_tracking(dev);
|
|
||||||
|
|
||||||
if (priv->ic_cut >= IC_VersionCut_D) {
|
if (priv->ic_cut >= IC_VersionCut_D) {
|
||||||
tmpRegA = rtl92e_get_bb_reg(dev, rOFDM0_XATxIQImbalance,
|
tmpRegA = rtl92e_get_bb_reg(dev, rOFDM0_XATxIQImbalance,
|
||||||
bMaskDWord);
|
bMaskDWord);
|
||||||
rtl92e_get_bb_reg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord);
|
rtl92e_get_bb_reg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord);
|
||||||
|
|
||||||
for (i = 0; i < TX_BB_GAIN_TABLE_LEN; i++) {
|
for (i = 0; i < TX_BB_GAIN_TABLE_LEN; i++) {
|
||||||
if (tmpRegA == dm_tx_bb_gain[i]) {
|
if (tmpRegA == dm_tx_bb_gain[i]) {
|
||||||
priv->rfa_txpowertrackingindex = i;
|
priv->rfa_txpowertrackingindex = i;
|
||||||
priv->rfa_txpowertrackingindex_real = i;
|
priv->rfa_txpowertrackingindex_real = i;
|
||||||
priv->rfa_txpowertracking_default =
|
priv->rfa_txpowertracking_default =
|
||||||
priv->rfa_txpowertrackingindex;
|
priv->rfa_txpowertrackingindex;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TempCCk = rtl92e_get_bb_reg(dev, rCCK0_TxFilter1,
|
|
||||||
bMaskByte2);
|
|
||||||
|
|
||||||
for (i = 0; i < CCK_TX_BB_GAIN_TABLE_LEN; i++) {
|
|
||||||
if (TempCCk == dm_cck_tx_bb_gain[i][0]) {
|
|
||||||
priv->cck_present_attn_20m_def = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
priv->cck_present_attn_40m_def = 0;
|
|
||||||
priv->cck_present_attn_diff = 0;
|
|
||||||
priv->cck_present_attn =
|
|
||||||
priv->cck_present_attn_20m_def;
|
|
||||||
priv->btxpower_tracking = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TempCCk = rtl92e_get_bb_reg(dev, rCCK0_TxFilter1,
|
||||||
|
bMaskByte2);
|
||||||
|
|
||||||
|
for (i = 0; i < CCK_TX_BB_GAIN_TABLE_LEN; i++) {
|
||||||
|
if (TempCCk == dm_cck_tx_bb_gain[i][0]) {
|
||||||
|
priv->cck_present_attn_20m_def = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
priv->cck_present_attn_40m_def = 0;
|
||||||
|
priv->cck_present_attn_diff = 0;
|
||||||
|
priv->cck_present_attn =
|
||||||
|
priv->cck_present_attn_20m_def;
|
||||||
|
priv->btxpower_tracking = false;
|
||||||
}
|
}
|
||||||
rtl92e_irq_enable(dev);
|
rtl92e_irq_enable(dev);
|
||||||
end:
|
end:
|
||||||
@ -706,7 +672,6 @@ static void _rtl92e_net_update(struct net_device *dev)
|
|||||||
{
|
{
|
||||||
struct r8192_priv *priv = rtllib_priv(dev);
|
struct r8192_priv *priv = rtllib_priv(dev);
|
||||||
struct rtllib_network *net;
|
struct rtllib_network *net;
|
||||||
u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf;
|
|
||||||
u16 rate_config = 0;
|
u16 rate_config = 0;
|
||||||
|
|
||||||
net = &priv->rtllib->current_network;
|
net = &priv->rtllib->current_network;
|
||||||
@ -715,19 +680,6 @@ static void _rtl92e_net_update(struct net_device *dev)
|
|||||||
priv->basic_rate = rate_config &= 0x15f;
|
priv->basic_rate = rate_config &= 0x15f;
|
||||||
rtl92e_writew(dev, BSSIDR, *(u16 *)net->bssid);
|
rtl92e_writew(dev, BSSIDR, *(u16 *)net->bssid);
|
||||||
rtl92e_writel(dev, BSSIDR + 2, *(u32 *)(net->bssid + 2));
|
rtl92e_writel(dev, BSSIDR + 2, *(u32 *)(net->bssid + 2));
|
||||||
|
|
||||||
if (priv->rtllib->iw_mode == IW_MODE_ADHOC) {
|
|
||||||
rtl92e_writew(dev, ATIMWND, 2);
|
|
||||||
rtl92e_writew(dev, BCN_DMATIME, 256);
|
|
||||||
rtl92e_writew(dev, BCN_INTERVAL, net->beacon_interval);
|
|
||||||
rtl92e_writew(dev, BCN_DRV_EARLY_INT, 10);
|
|
||||||
rtl92e_writeb(dev, BCN_ERR_THRESH, 100);
|
|
||||||
|
|
||||||
BcnTimeCfg |= (BcnCW << BCN_TCFG_CW_SHIFT);
|
|
||||||
BcnTimeCfg |= BcnIFS << BCN_TCFG_IFS;
|
|
||||||
|
|
||||||
rtl92e_writew(dev, BCN_TCFG, BcnTimeCfg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtl92e_link_change(struct net_device *dev)
|
void rtl92e_link_change(struct net_device *dev)
|
||||||
@ -749,15 +701,12 @@ void rtl92e_link_change(struct net_device *dev)
|
|||||||
}
|
}
|
||||||
_rtl92e_update_msr(dev);
|
_rtl92e_update_msr(dev);
|
||||||
|
|
||||||
if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC) {
|
if (ieee->iw_mode == IW_MODE_INFRA) {
|
||||||
u32 reg;
|
u32 reg;
|
||||||
|
|
||||||
reg = rtl92e_readl(dev, RCR);
|
reg = rtl92e_readl(dev, RCR);
|
||||||
if (priv->rtllib->link_state == MAC80211_LINKED) {
|
if (priv->rtllib->link_state == MAC80211_LINKED) {
|
||||||
if (ieee->intel_promiscuous_md_info.promiscuous_on)
|
priv->receive_config = reg |= RCR_CBSSID;
|
||||||
;
|
|
||||||
else
|
|
||||||
priv->receive_config = reg |= RCR_CBSSID;
|
|
||||||
} else {
|
} else {
|
||||||
priv->receive_config = reg &= ~RCR_CBSSID;
|
priv->receive_config = reg &= ~RCR_CBSSID;
|
||||||
}
|
}
|
||||||
@ -1411,12 +1360,12 @@ static void _rtl92e_process_phyinfo(struct r8192_priv *priv, u8 *buffer,
|
|||||||
static u32 slide_beacon_adc_pwdb_index;
|
static u32 slide_beacon_adc_pwdb_index;
|
||||||
static u32 slide_beacon_adc_pwdb_statistics;
|
static u32 slide_beacon_adc_pwdb_statistics;
|
||||||
static u32 last_beacon_adc_pwdb;
|
static u32 last_beacon_adc_pwdb;
|
||||||
struct rtllib_hdr_3addr *hdr;
|
struct ieee80211_hdr_3addr *hdr;
|
||||||
u16 sc;
|
u16 sc;
|
||||||
unsigned int seq;
|
unsigned int seq;
|
||||||
|
|
||||||
hdr = (struct rtllib_hdr_3addr *)buffer;
|
hdr = (struct ieee80211_hdr_3addr *)buffer;
|
||||||
sc = le16_to_cpu(hdr->seq_ctl);
|
sc = le16_to_cpu(hdr->seq_ctrl);
|
||||||
seq = WLAN_GET_SEQ_SEQ(sc);
|
seq = WLAN_GET_SEQ_SEQ(sc);
|
||||||
curr_st->Seq_Num = seq;
|
curr_st->Seq_Num = seq;
|
||||||
if (!prev_st->bIsAMPDU)
|
if (!prev_st->bIsAMPDU)
|
||||||
@ -1561,7 +1510,7 @@ static void _rtl92e_translate_rx_signal_stats(struct net_device *dev,
|
|||||||
struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
|
struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
|
||||||
bool bpacket_match_bssid, bpacket_toself;
|
bool bpacket_match_bssid, bpacket_toself;
|
||||||
bool bPacketBeacon = false;
|
bool bPacketBeacon = false;
|
||||||
struct rtllib_hdr_3addr *hdr;
|
struct ieee80211_hdr_3addr *hdr;
|
||||||
bool bToSelfBA = false;
|
bool bToSelfBA = false;
|
||||||
static struct rtllib_rx_stats previous_stats;
|
static struct rtllib_rx_stats previous_stats;
|
||||||
u16 fc, type;
|
u16 fc, type;
|
||||||
@ -1570,21 +1519,21 @@ static void _rtl92e_translate_rx_signal_stats(struct net_device *dev,
|
|||||||
|
|
||||||
tmp_buf = skb->data + pstats->RxDrvInfoSize + pstats->RxBufShift;
|
tmp_buf = skb->data + pstats->RxDrvInfoSize + pstats->RxBufShift;
|
||||||
|
|
||||||
hdr = (struct rtllib_hdr_3addr *)tmp_buf;
|
hdr = (struct ieee80211_hdr_3addr *)tmp_buf;
|
||||||
fc = le16_to_cpu(hdr->frame_ctl);
|
fc = le16_to_cpu(hdr->frame_control);
|
||||||
type = WLAN_FC_GET_TYPE(fc);
|
type = WLAN_FC_GET_TYPE(fc);
|
||||||
praddr = hdr->addr1;
|
praddr = hdr->addr1;
|
||||||
|
|
||||||
bpacket_match_bssid =
|
bpacket_match_bssid =
|
||||||
((type != RTLLIB_FTYPE_CTL) &&
|
((type != RTLLIB_FTYPE_CTL) &&
|
||||||
ether_addr_equal(priv->rtllib->current_network.bssid,
|
ether_addr_equal(priv->rtllib->current_network.bssid,
|
||||||
(fc & RTLLIB_FCTL_TODS) ? hdr->addr1 :
|
(fc & IEEE80211_FCTL_TODS) ? hdr->addr1 :
|
||||||
(fc & RTLLIB_FCTL_FROMDS) ? hdr->addr2 :
|
(fc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 :
|
||||||
hdr->addr3) &&
|
hdr->addr3) &&
|
||||||
(!pstats->bHwError) && (!pstats->bCRC) && (!pstats->bICV));
|
(!pstats->bHwError) && (!pstats->bCRC) && (!pstats->bICV));
|
||||||
bpacket_toself = bpacket_match_bssid && /* check this */
|
bpacket_toself = bpacket_match_bssid && /* check this */
|
||||||
ether_addr_equal(praddr, priv->rtllib->dev->dev_addr);
|
ether_addr_equal(praddr, priv->rtllib->dev->dev_addr);
|
||||||
if (WLAN_FC_GET_FRAMETYPE(fc) == RTLLIB_STYPE_BEACON)
|
if (ieee80211_is_beacon(hdr->frame_control))
|
||||||
bPacketBeacon = true;
|
bPacketBeacon = true;
|
||||||
_rtl92e_process_phyinfo(priv, tmp_buf, &previous_stats, pstats);
|
_rtl92e_process_phyinfo(priv, tmp_buf, &previous_stats, pstats);
|
||||||
_rtl92e_query_rxphystatus(priv, pstats, pdesc, pdrvinfo,
|
_rtl92e_query_rxphystatus(priv, pstats, pdesc, pdrvinfo,
|
||||||
@ -1870,7 +1819,7 @@ rtl92e_init_variables(struct net_device *dev)
|
|||||||
priv->bfirst_after_down = false;
|
priv->bfirst_after_down = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtl92e_enable_irq(struct net_device *dev)
|
void rtl92e_irq_enable(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
|
struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
|
||||||
|
|
||||||
@ -1879,7 +1828,7 @@ void rtl92e_enable_irq(struct net_device *dev)
|
|||||||
rtl92e_writel(dev, INTA_MASK, priv->irq_mask[0]);
|
rtl92e_writel(dev, INTA_MASK, priv->irq_mask[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtl92e_disable_irq(struct net_device *dev)
|
void rtl92e_irq_disable(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
|
struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
|
||||||
|
|
||||||
@ -1892,7 +1841,7 @@ void rtl92e_enable_rx(struct net_device *dev)
|
|||||||
{
|
{
|
||||||
struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
|
struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
|
||||||
|
|
||||||
rtl92e_writel(dev, RDQDA, priv->rx_ring_dma[RX_MPDU_QUEUE]);
|
rtl92e_writel(dev, RDQDA, priv->rx_ring_dma);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const u32 TX_DESC_BASE[] = {
|
static const u32 TX_DESC_BASE[] = {
|
||||||
|
@ -16,10 +16,7 @@ bool rtl92e_is_rx_stuck(struct net_device *dev);
|
|||||||
void rtl92e_ack_irq(struct net_device *dev, u32 *p_inta);
|
void rtl92e_ack_irq(struct net_device *dev, u32 *p_inta);
|
||||||
void rtl92e_enable_rx(struct net_device *dev);
|
void rtl92e_enable_rx(struct net_device *dev);
|
||||||
void rtl92e_enable_tx(struct net_device *dev);
|
void rtl92e_enable_tx(struct net_device *dev);
|
||||||
void rtl92e_enable_irq(struct net_device *dev);
|
|
||||||
void rtl92e_disable_irq(struct net_device *dev);
|
|
||||||
void rtl92e_init_variables(struct net_device *dev);
|
void rtl92e_init_variables(struct net_device *dev);
|
||||||
void rtl92e_start_beacon(struct net_device *dev);
|
|
||||||
void rtl92e_set_reg(struct net_device *dev, u8 variable, u8 *val);
|
void rtl92e_set_reg(struct net_device *dev, u8 variable, u8 *val);
|
||||||
void rtl92e_get_eeprom_size(struct net_device *dev);
|
void rtl92e_get_eeprom_size(struct net_device *dev);
|
||||||
bool rtl92e_start_adapter(struct net_device *dev);
|
bool rtl92e_start_adapter(struct net_device *dev);
|
||||||
|
@ -43,7 +43,7 @@ enum _RTL8192PCI_HW {
|
|||||||
PMR = 0x00c,
|
PMR = 0x00c,
|
||||||
EPROM_CMD = 0x00e,
|
EPROM_CMD = 0x00e,
|
||||||
|
|
||||||
#define EPROM_CMD_9356SEL BIT4
|
#define EPROM_CMD_9356SEL BIT(4)
|
||||||
#define EPROM_CMD_OPERATING_MODE_SHIFT 6
|
#define EPROM_CMD_OPERATING_MODE_SHIFT 6
|
||||||
#define EPROM_CMD_NORMAL 0
|
#define EPROM_CMD_NORMAL 0
|
||||||
#define EPROM_CMD_PROGRAM 2
|
#define EPROM_CMD_PROGRAM 2
|
||||||
@ -61,16 +61,16 @@ enum _RTL8192PCI_HW {
|
|||||||
#define CR_TE 0x04
|
#define CR_TE 0x04
|
||||||
SIFS = 0x03E,
|
SIFS = 0x03E,
|
||||||
RCR = 0x044,
|
RCR = 0x044,
|
||||||
#define RCR_ONLYERLPKT BIT31
|
#define RCR_ONLYERLPKT BIT(31)
|
||||||
#define RCR_CBSSID BIT23
|
#define RCR_CBSSID BIT(23)
|
||||||
#define RCR_ADD3 BIT21
|
#define RCR_ADD3 BIT(21)
|
||||||
#define RCR_AMF BIT20
|
#define RCR_AMF BIT(20)
|
||||||
#define RCR_ADF BIT18
|
#define RCR_ADF BIT(18)
|
||||||
#define RCR_AICV BIT12
|
#define RCR_AICV BIT(12)
|
||||||
#define RCR_AB BIT3
|
#define RCR_AB BIT(3)
|
||||||
#define RCR_AM BIT2
|
#define RCR_AM BIT(2)
|
||||||
#define RCR_APM BIT1
|
#define RCR_APM BIT(1)
|
||||||
#define RCR_AAP BIT0
|
#define RCR_AAP BIT(0)
|
||||||
#define RCR_MXDMA_OFFSET 8
|
#define RCR_MXDMA_OFFSET 8
|
||||||
#define RCR_FIFO_OFFSET 13
|
#define RCR_FIFO_OFFSET 13
|
||||||
SLOT_TIME = 0x049,
|
SLOT_TIME = 0x049,
|
||||||
@ -95,34 +95,34 @@ enum _RTL8192PCI_HW {
|
|||||||
#define TOTAL_CAM_ENTRY 32
|
#define TOTAL_CAM_ENTRY 32
|
||||||
WCAMI = 0x0A4,
|
WCAMI = 0x0A4,
|
||||||
SECR = 0x0B0,
|
SECR = 0x0B0,
|
||||||
#define SCR_TxUseDK BIT0
|
#define SCR_TxUseDK BIT(0)
|
||||||
#define SCR_RxUseDK BIT1
|
#define SCR_RxUseDK BIT(1)
|
||||||
#define SCR_TxEncEnable BIT2
|
#define SCR_TxEncEnable BIT(2)
|
||||||
#define SCR_RxDecEnable BIT3
|
#define SCR_RxDecEnable BIT(3)
|
||||||
#define SCR_NoSKMC BIT5
|
#define SCR_NoSKMC BIT(5)
|
||||||
SWREGULATOR = 0x0BD,
|
SWREGULATOR = 0x0BD,
|
||||||
INTA_MASK = 0x0f4,
|
INTA_MASK = 0x0f4,
|
||||||
#define IMR_TBDOK BIT27
|
#define IMR_TBDOK BIT(27)
|
||||||
#define IMR_TBDER BIT26
|
#define IMR_TBDER BIT(26)
|
||||||
#define IMR_TXFOVW BIT15
|
#define IMR_TXFOVW BIT(15)
|
||||||
#define IMR_TIMEOUT0 BIT14
|
#define IMR_TIMEOUT0 BIT(14)
|
||||||
#define IMR_BcnInt BIT13
|
#define IMR_BcnInt BIT(13)
|
||||||
#define IMR_RXFOVW BIT12
|
#define IMR_RXFOVW BIT(12)
|
||||||
#define IMR_RDU BIT11
|
#define IMR_RDU BIT(11)
|
||||||
#define IMR_RXCMDOK BIT10
|
#define IMR_RXCMDOK BIT(10)
|
||||||
#define IMR_BDOK BIT9
|
#define IMR_BDOK BIT(9)
|
||||||
#define IMR_HIGHDOK BIT8
|
#define IMR_HIGHDOK BIT(8)
|
||||||
#define IMR_COMDOK BIT7
|
#define IMR_COMDOK BIT(7)
|
||||||
#define IMR_MGNTDOK BIT6
|
#define IMR_MGNTDOK BIT(6)
|
||||||
#define IMR_HCCADOK BIT5
|
#define IMR_HCCADOK BIT(5)
|
||||||
#define IMR_BKDOK BIT4
|
#define IMR_BKDOK BIT(4)
|
||||||
#define IMR_BEDOK BIT3
|
#define IMR_BEDOK BIT(3)
|
||||||
#define IMR_VIDOK BIT2
|
#define IMR_VIDOK BIT(2)
|
||||||
#define IMR_VODOK BIT1
|
#define IMR_VODOK BIT(1)
|
||||||
#define IMR_ROK BIT0
|
#define IMR_ROK BIT(0)
|
||||||
ISR = 0x0f8,
|
ISR = 0x0f8,
|
||||||
TP_POLL = 0x0fd,
|
TP_POLL = 0x0fd,
|
||||||
#define TP_POLL_CQ BIT5
|
#define TP_POLL_CQ BIT(5)
|
||||||
PSR = 0x0ff,
|
PSR = 0x0ff,
|
||||||
CPU_GEN = 0x100,
|
CPU_GEN = 0x100,
|
||||||
#define CPU_CCK_LOOPBACK 0x00030000
|
#define CPU_CCK_LOOPBACK 0x00030000
|
||||||
@ -136,9 +136,9 @@ enum _RTL8192PCI_HW {
|
|||||||
#define CPU_GEN_NO_LOOPBACK_MSK 0xFFF8FFFF
|
#define CPU_GEN_NO_LOOPBACK_MSK 0xFFF8FFFF
|
||||||
#define CPU_GEN_NO_LOOPBACK_SET 0x00080000
|
#define CPU_GEN_NO_LOOPBACK_SET 0x00080000
|
||||||
ACM_HW_CTRL = 0x171,
|
ACM_HW_CTRL = 0x171,
|
||||||
#define ACM_HW_BEQ_EN BIT1
|
#define ACM_HW_BEQ_EN BIT(1)
|
||||||
#define ACM_HW_VIQ_EN BIT2
|
#define ACM_HW_VIQ_EN BIT(2)
|
||||||
#define ACM_HW_VOQ_EN BIT3
|
#define ACM_HW_VOQ_EN BIT(3)
|
||||||
RQPN1 = 0x180,
|
RQPN1 = 0x180,
|
||||||
RQPN2 = 0x184,
|
RQPN2 = 0x184,
|
||||||
RQPN3 = 0x188,
|
RQPN3 = 0x188,
|
||||||
@ -159,7 +159,7 @@ enum _RTL8192PCI_HW {
|
|||||||
WFCRC2 = 0x2f8,
|
WFCRC2 = 0x2f8,
|
||||||
|
|
||||||
BW_OPMODE = 0x300,
|
BW_OPMODE = 0x300,
|
||||||
#define BW_OPMODE_20MHZ BIT2
|
#define BW_OPMODE_20MHZ BIT(2)
|
||||||
IC_VERRSION = 0x301,
|
IC_VERRSION = 0x301,
|
||||||
MSR = 0x303,
|
MSR = 0x303,
|
||||||
#define MSR_LINK_MASK (BIT(1) | BIT(0))
|
#define MSR_LINK_MASK (BIT(1) | BIT(0))
|
||||||
@ -178,19 +178,19 @@ enum _RTL8192PCI_HW {
|
|||||||
TSFR = 0x308,
|
TSFR = 0x308,
|
||||||
RRSR = 0x310,
|
RRSR = 0x310,
|
||||||
#define RRSR_SHORT_OFFSET 23
|
#define RRSR_SHORT_OFFSET 23
|
||||||
#define RRSR_1M BIT0
|
#define RRSR_1M BIT(0)
|
||||||
#define RRSR_2M BIT1
|
#define RRSR_2M BIT(1)
|
||||||
#define RRSR_5_5M BIT2
|
#define RRSR_5_5M BIT(2)
|
||||||
#define RRSR_11M BIT3
|
#define RRSR_11M BIT(3)
|
||||||
#define RRSR_6M BIT4
|
#define RRSR_6M BIT(4)
|
||||||
#define RRSR_9M BIT5
|
#define RRSR_9M BIT(5)
|
||||||
#define RRSR_12M BIT6
|
#define RRSR_12M BIT(6)
|
||||||
#define RRSR_18M BIT7
|
#define RRSR_18M BIT(7)
|
||||||
#define RRSR_24M BIT8
|
#define RRSR_24M BIT(8)
|
||||||
#define RRSR_36M BIT9
|
#define RRSR_36M BIT(9)
|
||||||
#define RRSR_48M BIT10
|
#define RRSR_48M BIT(10)
|
||||||
#define RRSR_54M BIT11
|
#define RRSR_54M BIT(11)
|
||||||
#define BRSR_AckShortPmb BIT23
|
#define BRSR_AckShortPmb BIT(23)
|
||||||
UFWP = 0x318,
|
UFWP = 0x318,
|
||||||
RATR0 = 0x320,
|
RATR0 = 0x320,
|
||||||
#define RATR_1M 0x00000001
|
#define RATR_1M 0x00000001
|
||||||
|
@ -513,7 +513,7 @@ static u8 _rtl92e_phy_set_sw_chnl_cmd_array(struct net_device *dev,
|
|||||||
{
|
{
|
||||||
struct sw_chnl_cmd *pCmd;
|
struct sw_chnl_cmd *pCmd;
|
||||||
|
|
||||||
if (CmdTable == NULL) {
|
if (!CmdTable) {
|
||||||
netdev_err(dev, "%s(): CmdTable cannot be NULL.\n", __func__);
|
netdev_err(dev, "%s(): CmdTable cannot be NULL.\n", __func__);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -920,9 +920,6 @@ void rtl92e_init_gain(struct net_device *dev, u8 Operation)
|
|||||||
case IG_Backup:
|
case IG_Backup:
|
||||||
initial_gain = SCAN_RX_INITIAL_GAIN;
|
initial_gain = SCAN_RX_INITIAL_GAIN;
|
||||||
BitMask = bMaskByte0;
|
BitMask = bMaskByte0;
|
||||||
if (dm_digtable.dig_algorithm ==
|
|
||||||
DIG_ALGO_BY_FALSE_ALARM)
|
|
||||||
rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x8);
|
|
||||||
priv->initgain_backup.xaagccore1 =
|
priv->initgain_backup.xaagccore1 =
|
||||||
rtl92e_get_bb_reg(dev, rOFDM0_XAAGCCore1,
|
rtl92e_get_bb_reg(dev, rOFDM0_XAAGCCore1,
|
||||||
BitMask);
|
BitMask);
|
||||||
@ -947,10 +944,6 @@ void rtl92e_init_gain(struct net_device *dev, u8 Operation)
|
|||||||
break;
|
break;
|
||||||
case IG_Restore:
|
case IG_Restore:
|
||||||
BitMask = 0x7f;
|
BitMask = 0x7f;
|
||||||
if (dm_digtable.dig_algorithm ==
|
|
||||||
DIG_ALGO_BY_FALSE_ALARM)
|
|
||||||
rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x8);
|
|
||||||
|
|
||||||
rtl92e_set_bb_reg(dev, rOFDM0_XAAGCCore1, BitMask,
|
rtl92e_set_bb_reg(dev, rOFDM0_XAAGCCore1, BitMask,
|
||||||
(u32)priv->initgain_backup.xaagccore1);
|
(u32)priv->initgain_backup.xaagccore1);
|
||||||
rtl92e_set_bb_reg(dev, rOFDM0_XBAGCCore1, BitMask,
|
rtl92e_set_bb_reg(dev, rOFDM0_XBAGCCore1, BitMask,
|
||||||
@ -965,10 +958,6 @@ void rtl92e_init_gain(struct net_device *dev, u8 Operation)
|
|||||||
|
|
||||||
rtl92e_set_tx_power(dev,
|
rtl92e_set_tx_power(dev,
|
||||||
priv->rtllib->current_network.channel);
|
priv->rtllib->current_network.channel);
|
||||||
|
|
||||||
if (dm_digtable.dig_algorithm ==
|
|
||||||
DIG_ALGO_BY_FALSE_ALARM)
|
|
||||||
rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x1);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -976,7 +965,7 @@ void rtl92e_init_gain(struct net_device *dev, u8 Operation)
|
|||||||
|
|
||||||
void rtl92e_set_rf_off(struct net_device *dev)
|
void rtl92e_set_rf_off(struct net_device *dev)
|
||||||
{
|
{
|
||||||
rtl92e_set_bb_reg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x0);
|
rtl92e_set_bb_reg(dev, rFPGA0_XA_RFInterfaceOE, BIT(4), 0x0);
|
||||||
rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter4, 0x300, 0x0);
|
rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter4, 0x300, 0x0);
|
||||||
rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter1, 0x18, 0x0);
|
rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter1, 0x18, 0x0);
|
||||||
rtl92e_set_bb_reg(dev, rOFDM0_TRxPathEnable, 0xf, 0x0);
|
rtl92e_set_bb_reg(dev, rOFDM0_TRxPathEnable, 0xf, 0x0);
|
||||||
@ -1027,7 +1016,7 @@ static bool _rtl92e_set_rf_power_state(struct net_device *dev,
|
|||||||
0x4, 0x1);
|
0x4, 0x1);
|
||||||
priv->hw_rf_off_action = 0;
|
priv->hw_rf_off_action = 0;
|
||||||
rtl92e_set_bb_reg(dev, rFPGA0_XA_RFInterfaceOE,
|
rtl92e_set_bb_reg(dev, rFPGA0_XA_RFInterfaceOE,
|
||||||
BIT4, 0x1);
|
BIT(4), 0x1);
|
||||||
rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter4,
|
rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter4,
|
||||||
0x300, 0x3);
|
0x300, 0x3);
|
||||||
rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter1,
|
rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter1,
|
||||||
|
@ -248,75 +248,15 @@
|
|||||||
#define bPAEnd 0xf
|
#define bPAEnd 0xf
|
||||||
#define bTREnd 0x0f000000
|
#define bTREnd 0x0f000000
|
||||||
#define bRFEnd 0x000f0000
|
#define bRFEnd 0x000f0000
|
||||||
/* T2R */
|
|
||||||
#define bCCAMask 0x000000f0
|
|
||||||
#define bR2RCCAMask 0x00000f00
|
|
||||||
#define bHSSI_R2TDelay 0xf8000000
|
|
||||||
#define bHSSI_T2RDelay 0xf80000
|
|
||||||
/* Channel gain at continue TX. */
|
/* Channel gain at continue TX. */
|
||||||
#define bContTxHSSI 0x400
|
|
||||||
#define bIGFromCCK 0x200
|
|
||||||
#define bAGCAddress 0x3f
|
|
||||||
#define bRxHPTx 0x7000
|
|
||||||
#define bRxHPT2R 0x38000
|
|
||||||
#define bRxHPCCKIni 0xc0000
|
|
||||||
#define bAGCTxCode 0xc00000
|
|
||||||
#define bAGCRxCode 0x300000
|
|
||||||
#define b3WireDataLength 0x800
|
#define b3WireDataLength 0x800
|
||||||
#define b3WireAddressLength 0x400
|
#define b3WireAddressLength 0x400
|
||||||
#define b3WireRFPowerDown 0x1
|
|
||||||
/*#define bHWSISelect 0x8 */
|
|
||||||
#define b2GPAPEPolarity 0x80000000
|
|
||||||
#define bRFSW_TxDefaultAnt 0x3
|
|
||||||
#define bRFSW_TxOptionAnt 0x30
|
|
||||||
#define bRFSW_RxDefaultAnt 0x300
|
|
||||||
#define bRFSW_RxOptionAnt 0x3000
|
|
||||||
#define bRFSI_3WireData 0x1
|
|
||||||
#define bRFSI_3WireClock 0x2
|
|
||||||
#define bRFSI_3WireLoad 0x4
|
|
||||||
#define bRFSI_3WireRW 0x8
|
|
||||||
/* 3-wire total control */
|
/* 3-wire total control */
|
||||||
#define bRFSI_3Wire 0xf
|
|
||||||
#define bRFSI_RFENV 0x10
|
#define bRFSI_RFENV 0x10
|
||||||
#define bRFSI_TRSW 0x20
|
|
||||||
#define bRFSI_TRSWB 0x40
|
|
||||||
#define bRFSI_ANTSW 0x100
|
|
||||||
#define bRFSI_ANTSWB 0x200
|
|
||||||
#define bRFSI_PAPE 0x400
|
|
||||||
#define bBandSelect 0x1
|
|
||||||
#define bHTSIG2_GI 0x80
|
|
||||||
#define bHTSIG2_Smoothing 0x01
|
|
||||||
#define bHTSIG2_Sounding 0x02
|
|
||||||
#define bHTSIG2_Aggreaton 0x08
|
|
||||||
#define bHTSIG2_STBC 0x30
|
|
||||||
#define bHTSIG2_AdvCoding 0x40
|
|
||||||
#define bHTSIG2_NumOfHTLTF 0x300
|
|
||||||
#define bHTSIG2_CRC8 0x3fc
|
|
||||||
#define bHTSIG1_MCS 0x7f
|
|
||||||
#define bHTSIG1_BandWidth 0x80
|
|
||||||
#define bHTSIG1_HTLength 0xffff
|
|
||||||
#define bLSIG_Rate 0xf
|
|
||||||
#define bLSIG_Reserved 0x10
|
|
||||||
#define bLSIG_Length 0x1fffe
|
|
||||||
#define bLSIG_Parity 0x20
|
|
||||||
#define bCCKRxPhase 0x4
|
|
||||||
#define bLSSIReadAddress 0x3f000000 /* LSSI "read" address */
|
#define bLSSIReadAddress 0x3f000000 /* LSSI "read" address */
|
||||||
#define bLSSIReadEdge 0x80000000 /* LSSI "read" edge signal */
|
#define bLSSIReadEdge 0x80000000 /* LSSI "read" edge signal */
|
||||||
#define bLSSIReadBackData 0xfff
|
#define bLSSIReadBackData 0xfff
|
||||||
#define bLSSIReadOKFlag 0x1000
|
|
||||||
#define bCCKSampleRate 0x8 /* 0: 44 MHz, 1: 88MHz */
|
|
||||||
|
|
||||||
#define bRegulator0Standby 0x1
|
|
||||||
#define bRegulatorPLLStandby 0x2
|
|
||||||
#define bRegulator1Standby 0x4
|
|
||||||
#define bPLLPowerUp 0x8
|
|
||||||
#define bDPLLPowerUp 0x10
|
|
||||||
#define bDA10PowerUp 0x20
|
|
||||||
#define bAD7PowerUp 0x200
|
|
||||||
#define bDA6PowerUp 0x2000
|
|
||||||
#define bXtalPowerUp 0x4000
|
|
||||||
#define b40MDClkPowerUP 0x8000
|
|
||||||
#define bDA6DebugMode 0x20000
|
|
||||||
#define bDA6Swing 0x380000
|
#define bDA6Swing 0x380000
|
||||||
#define bADClkPhase 0x4000000
|
#define bADClkPhase 0x4000000
|
||||||
#define b80MClkDelay 0x18000000
|
#define b80MClkDelay 0x18000000
|
||||||
|
@ -17,7 +17,7 @@ void rtl92e_cam_reset(struct net_device *dev)
|
|||||||
{
|
{
|
||||||
u32 ulcommand = 0;
|
u32 ulcommand = 0;
|
||||||
|
|
||||||
ulcommand |= BIT31 | BIT30;
|
ulcommand |= BIT(31) | BIT(30);
|
||||||
rtl92e_writel(dev, RWCAM, ulcommand);
|
rtl92e_writel(dev, RWCAM, ulcommand);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,11 +33,6 @@ void rtl92e_enable_hw_security_config(struct net_device *dev)
|
|||||||
(priv->rtllib->auth_mode != 2)) {
|
(priv->rtllib->auth_mode != 2)) {
|
||||||
SECR_value |= SCR_RxUseDK;
|
SECR_value |= SCR_RxUseDK;
|
||||||
SECR_value |= SCR_TxUseDK;
|
SECR_value |= SCR_TxUseDK;
|
||||||
} else if ((ieee->iw_mode == IW_MODE_ADHOC) &&
|
|
||||||
(ieee->pairwise_key_type & (KEY_TYPE_CCMP |
|
|
||||||
KEY_TYPE_TKIP))) {
|
|
||||||
SECR_value |= SCR_RxUseDK;
|
|
||||||
SECR_value |= SCR_TxUseDK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ieee->hwsec_active = 1;
|
ieee->hwsec_active = 1;
|
||||||
@ -94,13 +89,13 @@ void rtl92e_set_key(struct net_device *dev, u8 EntryNo, u8 KeyIndex,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (DefaultKey)
|
if (DefaultKey)
|
||||||
usConfig |= BIT15 | (KeyType << 2);
|
usConfig |= BIT(15) | (KeyType << 2);
|
||||||
else
|
else
|
||||||
usConfig |= BIT15 | (KeyType << 2) | KeyIndex;
|
usConfig |= BIT(15) | (KeyType << 2) | KeyIndex;
|
||||||
|
|
||||||
for (i = 0; i < CAM_CONTENT_COUNT; i++) {
|
for (i = 0; i < CAM_CONTENT_COUNT; i++) {
|
||||||
TargetCommand = i + CAM_CONTENT_COUNT * EntryNo;
|
TargetCommand = i + CAM_CONTENT_COUNT * EntryNo;
|
||||||
TargetCommand |= BIT31 | BIT16;
|
TargetCommand |= BIT(31) | BIT(16);
|
||||||
|
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
TargetContent = (u32)(*(MacAddr + 0)) << 16 |
|
TargetContent = (u32)(*(MacAddr + 0)) << 16 |
|
||||||
@ -117,7 +112,7 @@ void rtl92e_set_key(struct net_device *dev, u8 EntryNo, u8 KeyIndex,
|
|||||||
rtl92e_writel(dev, WCAMI, TargetContent);
|
rtl92e_writel(dev, WCAMI, TargetContent);
|
||||||
rtl92e_writel(dev, RWCAM, TargetCommand);
|
rtl92e_writel(dev, RWCAM, TargetCommand);
|
||||||
} else {
|
} else {
|
||||||
if (KeyContent != NULL) {
|
if (KeyContent) {
|
||||||
rtl92e_writel(dev, WCAMI,
|
rtl92e_writel(dev, WCAMI,
|
||||||
(u32)(*(KeyContent + i - 2)));
|
(u32)(*(KeyContent + i - 2)));
|
||||||
rtl92e_writel(dev, RWCAM, TargetCommand);
|
rtl92e_writel(dev, RWCAM, TargetCommand);
|
||||||
@ -126,108 +121,3 @@ void rtl92e_set_key(struct net_device *dev, u8 EntryNo, u8 KeyIndex,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtl92e_cam_restore(struct net_device *dev)
|
|
||||||
{
|
|
||||||
u8 EntryId = 0;
|
|
||||||
struct r8192_priv *priv = rtllib_priv(dev);
|
|
||||||
u8 *MacAddr = priv->rtllib->current_network.bssid;
|
|
||||||
|
|
||||||
static u8 CAM_CONST_ADDR[4][6] = {
|
|
||||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
||||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
|
|
||||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
|
|
||||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x03}
|
|
||||||
};
|
|
||||||
static u8 CAM_CONST_BROAD[] = {
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff
|
|
||||||
};
|
|
||||||
|
|
||||||
if ((priv->rtllib->pairwise_key_type == KEY_TYPE_WEP40) ||
|
|
||||||
(priv->rtllib->pairwise_key_type == KEY_TYPE_WEP104)) {
|
|
||||||
for (EntryId = 0; EntryId < 4; EntryId++) {
|
|
||||||
MacAddr = CAM_CONST_ADDR[EntryId];
|
|
||||||
if (priv->rtllib->swcamtable[EntryId].bused) {
|
|
||||||
rtl92e_set_key(dev, EntryId, EntryId,
|
|
||||||
priv->rtllib->pairwise_key_type,
|
|
||||||
MacAddr, 0,
|
|
||||||
(u32 *)(&priv->rtllib->swcamtable
|
|
||||||
[EntryId].key_buf[0]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (priv->rtllib->pairwise_key_type == KEY_TYPE_TKIP) {
|
|
||||||
if (priv->rtllib->iw_mode == IW_MODE_ADHOC) {
|
|
||||||
rtl92e_set_key(dev, 4, 0,
|
|
||||||
priv->rtllib->pairwise_key_type,
|
|
||||||
(const u8 *)dev->dev_addr, 0,
|
|
||||||
(u32 *)(&priv->rtllib->swcamtable[4].key_buf[0]));
|
|
||||||
} else {
|
|
||||||
rtl92e_set_key(dev, 4, 0,
|
|
||||||
priv->rtllib->pairwise_key_type,
|
|
||||||
MacAddr, 0,
|
|
||||||
(u32 *)(&priv->rtllib->swcamtable[4].key_buf[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (priv->rtllib->pairwise_key_type == KEY_TYPE_CCMP) {
|
|
||||||
if (priv->rtllib->iw_mode == IW_MODE_ADHOC) {
|
|
||||||
rtl92e_set_key(dev, 4, 0,
|
|
||||||
priv->rtllib->pairwise_key_type,
|
|
||||||
(const u8 *)dev->dev_addr, 0,
|
|
||||||
(u32 *)(&priv->rtllib->swcamtable[4].key_buf[0]));
|
|
||||||
} else {
|
|
||||||
rtl92e_set_key(dev, 4, 0,
|
|
||||||
priv->rtllib->pairwise_key_type, MacAddr,
|
|
||||||
0, (u32 *)(&priv->rtllib->swcamtable[4].key_buf[0]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (priv->rtllib->group_key_type == KEY_TYPE_TKIP) {
|
|
||||||
MacAddr = CAM_CONST_BROAD;
|
|
||||||
for (EntryId = 1; EntryId < 4; EntryId++) {
|
|
||||||
if (priv->rtllib->swcamtable[EntryId].bused) {
|
|
||||||
rtl92e_set_key(dev, EntryId, EntryId,
|
|
||||||
priv->rtllib->group_key_type,
|
|
||||||
MacAddr, 0,
|
|
||||||
(u32 *)(&priv->rtllib->swcamtable[EntryId].key_buf[0]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (priv->rtllib->iw_mode == IW_MODE_ADHOC) {
|
|
||||||
if (priv->rtllib->swcamtable[0].bused) {
|
|
||||||
rtl92e_set_key(dev, 0, 0,
|
|
||||||
priv->rtllib->group_key_type,
|
|
||||||
CAM_CONST_ADDR[0], 0,
|
|
||||||
(u32 *)(&priv->rtllib->swcamtable[0].key_buf[0]));
|
|
||||||
} else {
|
|
||||||
netdev_warn(dev,
|
|
||||||
"%s(): ADHOC TKIP: missing key entry.\n",
|
|
||||||
__func__);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (priv->rtllib->group_key_type == KEY_TYPE_CCMP) {
|
|
||||||
MacAddr = CAM_CONST_BROAD;
|
|
||||||
for (EntryId = 1; EntryId < 4; EntryId++) {
|
|
||||||
if (priv->rtllib->swcamtable[EntryId].bused) {
|
|
||||||
rtl92e_set_key(dev, EntryId, EntryId,
|
|
||||||
priv->rtllib->group_key_type,
|
|
||||||
MacAddr, 0,
|
|
||||||
(u32 *)(&priv->rtllib->swcamtable[EntryId].key_buf[0]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (priv->rtllib->iw_mode == IW_MODE_ADHOC) {
|
|
||||||
if (priv->rtllib->swcamtable[0].bused) {
|
|
||||||
rtl92e_set_key(dev, 0, 0,
|
|
||||||
priv->rtllib->group_key_type,
|
|
||||||
CAM_CONST_ADDR[0], 0,
|
|
||||||
(u32 *)(&priv->rtllib->swcamtable[0].key_buf[0]));
|
|
||||||
} else {
|
|
||||||
netdev_warn(dev,
|
|
||||||
"%s(): ADHOC CCMP: missing key entry.\n",
|
|
||||||
__func__);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -20,6 +20,5 @@ void rtl92e_set_key(struct net_device *dev, u8 EntryNo, u8 KeyIndex,
|
|||||||
u32 *KeyContent);
|
u32 *KeyContent);
|
||||||
void rtl92e_set_swcam(struct net_device *dev, u8 EntryNo, u8 KeyIndex,
|
void rtl92e_set_swcam(struct net_device *dev, u8 EntryNo, u8 KeyIndex,
|
||||||
u16 KeyType, const u8 *MacAddr, u32 *KeyContent);
|
u16 KeyType, const u8 *MacAddr, u32 *KeyContent);
|
||||||
void rtl92e_cam_restore(struct net_device *dev);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -61,7 +61,7 @@ static short _rtl92e_pci_initdescring(struct net_device *dev);
|
|||||||
static void _rtl92e_irq_tx_tasklet(struct tasklet_struct *t);
|
static void _rtl92e_irq_tx_tasklet(struct tasklet_struct *t);
|
||||||
static void _rtl92e_irq_rx_tasklet(struct tasklet_struct *t);
|
static void _rtl92e_irq_rx_tasklet(struct tasklet_struct *t);
|
||||||
static void _rtl92e_cancel_deferred_work(struct r8192_priv *priv);
|
static void _rtl92e_cancel_deferred_work(struct r8192_priv *priv);
|
||||||
static int _rtl92e_up(struct net_device *dev, bool is_silent_reset);
|
static int _rtl92e_up(struct net_device *dev);
|
||||||
static int _rtl92e_try_up(struct net_device *dev);
|
static int _rtl92e_try_up(struct net_device *dev);
|
||||||
static int _rtl92e_down(struct net_device *dev, bool shutdownrf);
|
static int _rtl92e_down(struct net_device *dev, bool shutdownrf);
|
||||||
static void _rtl92e_restart(void *data);
|
static void _rtl92e_restart(void *data);
|
||||||
@ -165,8 +165,7 @@ bool rtl92e_set_rf_state(struct net_device *dev,
|
|||||||
|
|
||||||
case rf_off:
|
case rf_off:
|
||||||
|
|
||||||
if ((priv->rtllib->iw_mode == IW_MODE_INFRA) ||
|
if (priv->rtllib->iw_mode == IW_MODE_INFRA) {
|
||||||
(priv->rtllib->iw_mode == IW_MODE_ADHOC)) {
|
|
||||||
if ((priv->rtllib->rf_off_reason > RF_CHANGE_BY_IPS) ||
|
if ((priv->rtllib->rf_off_reason > RF_CHANGE_BY_IPS) ||
|
||||||
(change_source > RF_CHANGE_BY_IPS)) {
|
(change_source > RF_CHANGE_BY_IPS)) {
|
||||||
if (ieee->link_state == MAC80211_LINKED)
|
if (ieee->link_state == MAC80211_LINKED)
|
||||||
@ -227,24 +226,6 @@ static void _rtl92e_tx_timeout(struct net_device *dev, unsigned int txqueue)
|
|||||||
netdev_info(dev, "TXTIMEOUT");
|
netdev_info(dev, "TXTIMEOUT");
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtl92e_irq_enable(struct net_device *dev)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = rtllib_priv(dev);
|
|
||||||
|
|
||||||
priv->irq_enabled = 1;
|
|
||||||
|
|
||||||
rtl92e_enable_irq(dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
void rtl92e_irq_disable(struct net_device *dev)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = rtllib_priv(dev);
|
|
||||||
|
|
||||||
rtl92e_disable_irq(dev);
|
|
||||||
|
|
||||||
priv->irq_enabled = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _rtl92e_set_chan(struct net_device *dev, short ch)
|
static void _rtl92e_set_chan(struct net_device *dev, short ch)
|
||||||
{
|
{
|
||||||
struct r8192_priv *priv = rtllib_priv(dev);
|
struct r8192_priv *priv = rtllib_priv(dev);
|
||||||
@ -313,7 +294,7 @@ static void _rtl92e_update_beacon(void *data)
|
|||||||
struct rtllib_device *ieee = priv->rtllib;
|
struct rtllib_device *ieee = priv->rtllib;
|
||||||
struct rtllib_network *net = &ieee->current_network;
|
struct rtllib_network *net = &ieee->current_network;
|
||||||
|
|
||||||
if (ieee->ht_info->bCurrentHTSupport)
|
if (ieee->ht_info->current_ht_support)
|
||||||
HT_update_self_and_peer_setting(ieee, net);
|
HT_update_self_and_peer_setting(ieee, net);
|
||||||
ieee->ht_info->current_rt2rt_long_slot_time = net->bssht.bd_rt2rt_long_slot_time;
|
ieee->ht_info->current_rt2rt_long_slot_time = net->bssht.bd_rt2rt_long_slot_time;
|
||||||
ieee->ht_info->RT2RT_HT_Mode = net->bssht.rt2rt_ht_mode;
|
ieee->ht_info->RT2RT_HT_Mode = net->bssht.rt2rt_ht_mode;
|
||||||
@ -477,10 +458,6 @@ static void _rtl92e_prepare_beacon(struct tasklet_struct *t)
|
|||||||
pdesc->OWN = 1;
|
pdesc->OWN = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _rtl92e_stop_beacon(struct net_device *dev)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void rtl92e_config_rate(struct net_device *dev, u16 *rate_config)
|
void rtl92e_config_rate(struct net_device *dev, u16 *rate_config)
|
||||||
{
|
{
|
||||||
struct r8192_priv *priv = rtllib_priv(dev);
|
struct r8192_priv *priv = rtllib_priv(dev);
|
||||||
@ -611,7 +588,7 @@ void rtl92e_set_wireless_mode(struct net_device *dev, u8 wireless_mode)
|
|||||||
_rtl92e_refresh_support_rate(priv);
|
_rtl92e_refresh_support_rate(priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _rtl92e_sta_up(struct net_device *dev, bool is_silent_reset)
|
static int _rtl92e_sta_up(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct r8192_priv *priv = rtllib_priv(dev);
|
struct r8192_priv *priv = rtllib_priv(dev);
|
||||||
struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *)
|
struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *)
|
||||||
@ -634,7 +611,7 @@ static int _rtl92e_sta_up(struct net_device *dev, bool is_silent_reset)
|
|||||||
rtl92e_check_rfctrl_gpio_timer(&priv->gpio_polling_timer);
|
rtl92e_check_rfctrl_gpio_timer(&priv->gpio_polling_timer);
|
||||||
|
|
||||||
if (priv->rtllib->link_state != MAC80211_LINKED)
|
if (priv->rtllib->link_state != MAC80211_LINKED)
|
||||||
rtllib_softmac_start_protocol(priv->rtllib, 0);
|
rtllib_softmac_start_protocol(priv->rtllib);
|
||||||
rtllib_reset_queue(priv->rtllib);
|
rtllib_reset_queue(priv->rtllib);
|
||||||
_rtl92e_watchdog_timer_cb(&priv->watch_dog_timer);
|
_rtl92e_watchdog_timer_cb(&priv->watch_dog_timer);
|
||||||
|
|
||||||
@ -678,7 +655,7 @@ static int _rtl92e_sta_down(struct net_device *dev, bool shutdownrf)
|
|||||||
_rtl92e_cancel_deferred_work(priv);
|
_rtl92e_cancel_deferred_work(priv);
|
||||||
cancel_delayed_work(&priv->rtllib->hw_wakeup_wq);
|
cancel_delayed_work(&priv->rtllib->hw_wakeup_wq);
|
||||||
|
|
||||||
rtllib_softmac_stop_protocol(priv->rtllib, 0, true);
|
rtllib_softmac_stop_protocol(priv->rtllib);
|
||||||
spin_lock_irqsave(&priv->rf_ps_lock, flags);
|
spin_lock_irqsave(&priv->rf_ps_lock, flags);
|
||||||
while (priv->rf_change_in_progress) {
|
while (priv->rf_change_in_progress) {
|
||||||
spin_unlock_irqrestore(&priv->rf_ps_lock, flags);
|
spin_unlock_irqrestore(&priv->rf_ps_lock, flags);
|
||||||
@ -719,9 +696,6 @@ static void _rtl92e_init_priv_handler(struct net_device *dev)
|
|||||||
priv->rtllib->set_bw_mode_handler = rtl92e_set_bw_mode;
|
priv->rtllib->set_bw_mode_handler = rtl92e_set_bw_mode;
|
||||||
priv->rf_set_chan = rtl92e_set_channel;
|
priv->rf_set_chan = rtl92e_set_channel;
|
||||||
|
|
||||||
priv->rtllib->start_send_beacons = rtl92e_start_beacon;
|
|
||||||
priv->rtllib->stop_send_beacons = _rtl92e_stop_beacon;
|
|
||||||
|
|
||||||
priv->rtllib->sta_wake_up = rtl92e_hw_wakeup;
|
priv->rtllib->sta_wake_up = rtl92e_hw_wakeup;
|
||||||
priv->rtllib->enter_sleep_state = rtl92e_enter_sleep;
|
priv->rtllib->enter_sleep_state = rtl92e_enter_sleep;
|
||||||
priv->rtllib->ps_is_queue_empty = _rtl92e_is_tx_queue_empty;
|
priv->rtllib->ps_is_queue_empty = _rtl92e_is_tx_queue_empty;
|
||||||
@ -738,15 +712,6 @@ static void _rtl92e_init_priv_handler(struct net_device *dev)
|
|||||||
priv->rtllib->ScanOperationBackupHandler = rtl92e_scan_op_backup;
|
priv->rtllib->ScanOperationBackupHandler = rtl92e_scan_op_backup;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _rtl92e_init_priv_constant(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->reg_max_lps_awake_intvl = 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _rtl92e_init_priv_variable(struct net_device *dev)
|
static void _rtl92e_init_priv_variable(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct r8192_priv *priv = rtllib_priv(dev);
|
struct r8192_priv *priv = rtllib_priv(dev);
|
||||||
@ -765,10 +730,6 @@ static void _rtl92e_init_priv_variable(struct net_device *dev)
|
|||||||
priv->chan = 1;
|
priv->chan = 1;
|
||||||
priv->rtllib->mode = WIRELESS_MODE_AUTO;
|
priv->rtllib->mode = WIRELESS_MODE_AUTO;
|
||||||
priv->rtllib->iw_mode = IW_MODE_INFRA;
|
priv->rtllib->iw_mode = IW_MODE_INFRA;
|
||||||
priv->rtllib->net_promiscuous_md = false;
|
|
||||||
priv->rtllib->intel_promiscuous_md_info.promiscuous_on = false;
|
|
||||||
priv->rtllib->intel_promiscuous_md_info.fltr_src_sta_frame =
|
|
||||||
false;
|
|
||||||
priv->rtllib->ieee_up = 0;
|
priv->rtllib->ieee_up = 0;
|
||||||
priv->retry_rts = DEFAULT_RETRY_RTS;
|
priv->retry_rts = DEFAULT_RETRY_RTS;
|
||||||
priv->retry_data = DEFAULT_RETRY_DATA;
|
priv->retry_data = DEFAULT_RETRY_DATA;
|
||||||
@ -778,10 +739,7 @@ static void _rtl92e_init_priv_variable(struct net_device *dev)
|
|||||||
priv->bcck_in_ch14 = false;
|
priv->bcck_in_ch14 = false;
|
||||||
priv->cck_present_attn = 0;
|
priv->cck_present_attn = 0;
|
||||||
priv->rfa_txpowertrackingindex = 0;
|
priv->rfa_txpowertrackingindex = 0;
|
||||||
priv->rfc_txpowertrackingindex = 0;
|
|
||||||
priv->cck_pwr_enl = 6;
|
priv->cck_pwr_enl = 6;
|
||||||
priv->rst_progress = RESET_TYPE_NORESET;
|
|
||||||
priv->force_reset = false;
|
|
||||||
memset(priv->rtllib->swcamtable, 0, sizeof(struct sw_cam_table) * 32);
|
memset(priv->rtllib->swcamtable, 0, sizeof(struct sw_cam_table) * 32);
|
||||||
priv->rx_ctr = 0;
|
priv->rx_ctr = 0;
|
||||||
priv->rtllib->wx_set_enc = 0;
|
priv->rtllib->wx_set_enc = 0;
|
||||||
@ -797,7 +755,6 @@ static void _rtl92e_init_priv_variable(struct net_device *dev)
|
|||||||
|
|
||||||
priv->rtllib->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
|
priv->rtllib->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
|
||||||
priv->rtllib->iw_mode = IW_MODE_INFRA;
|
priv->rtllib->iw_mode = IW_MODE_INFRA;
|
||||||
priv->rtllib->active_scan = 1;
|
|
||||||
priv->rtllib->be_scan_inprogress = false;
|
priv->rtllib->be_scan_inprogress = false;
|
||||||
|
|
||||||
priv->rtllib->fts = DEFAULT_FRAG_THRESHOLD;
|
priv->rtllib->fts = DEFAULT_FRAG_THRESHOLD;
|
||||||
@ -871,7 +828,6 @@ static short _rtl92e_init(struct net_device *dev)
|
|||||||
memset(&priv->stats, 0, sizeof(struct rt_stats));
|
memset(&priv->stats, 0, sizeof(struct rt_stats));
|
||||||
|
|
||||||
_rtl92e_init_priv_handler(dev);
|
_rtl92e_init_priv_handler(dev);
|
||||||
_rtl92e_init_priv_constant(dev);
|
|
||||||
_rtl92e_init_priv_variable(dev);
|
_rtl92e_init_priv_variable(dev);
|
||||||
_rtl92e_init_priv_lock(priv);
|
_rtl92e_init_priv_lock(priv);
|
||||||
_rtl92e_init_priv_task(dev);
|
_rtl92e_init_priv_task(dev);
|
||||||
@ -984,7 +940,7 @@ static enum reset_type _rtl92e_rx_check_stuck(struct net_device *dev)
|
|||||||
return RESET_TYPE_NORESET;
|
return RESET_TYPE_NORESET;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum reset_type _rtl92e_if_check_reset(struct net_device *dev)
|
static void _rtl92e_if_check_reset(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct r8192_priv *priv = rtllib_priv(dev);
|
struct r8192_priv *priv = rtllib_priv(dev);
|
||||||
enum reset_type TxResetType = RESET_TYPE_NORESET;
|
enum reset_type TxResetType = RESET_TYPE_NORESET;
|
||||||
@ -1001,133 +957,12 @@ static enum reset_type _rtl92e_if_check_reset(struct net_device *dev)
|
|||||||
(priv->rtllib->link_state == MAC80211_LINKED))
|
(priv->rtllib->link_state == MAC80211_LINKED))
|
||||||
RxResetType = _rtl92e_rx_check_stuck(dev);
|
RxResetType = _rtl92e_rx_check_stuck(dev);
|
||||||
|
|
||||||
if (TxResetType == RESET_TYPE_NORMAL ||
|
if (TxResetType == RESET_TYPE_SILENT ||
|
||||||
RxResetType == RESET_TYPE_NORMAL) {
|
|
||||||
netdev_info(dev, "%s(): TxResetType is %d, RxResetType is %d\n",
|
|
||||||
__func__, TxResetType, RxResetType);
|
|
||||||
return RESET_TYPE_NORMAL;
|
|
||||||
} else if (TxResetType == RESET_TYPE_SILENT ||
|
|
||||||
RxResetType == RESET_TYPE_SILENT) {
|
RxResetType == RESET_TYPE_SILENT) {
|
||||||
netdev_info(dev, "%s(): TxResetType is %d, RxResetType is %d\n",
|
netdev_info(dev, "%s(): TxResetType is %d, RxResetType is %d\n",
|
||||||
__func__, TxResetType, RxResetType);
|
__func__, TxResetType, RxResetType);
|
||||||
return RESET_TYPE_SILENT;
|
|
||||||
} else {
|
|
||||||
return RESET_TYPE_NORESET;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _rtl92e_if_silent_reset(struct net_device *dev)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = rtllib_priv(dev);
|
|
||||||
u8 reset_times = 0;
|
|
||||||
int reset_status = 0;
|
|
||||||
struct rtllib_device *ieee = priv->rtllib;
|
|
||||||
unsigned long flag;
|
|
||||||
|
|
||||||
if (priv->rst_progress == RESET_TYPE_NORESET) {
|
|
||||||
priv->rst_progress = RESET_TYPE_SILENT;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&priv->rf_ps_lock, flag);
|
|
||||||
if (priv->rf_change_in_progress) {
|
|
||||||
spin_unlock_irqrestore(&priv->rf_ps_lock, flag);
|
|
||||||
goto END;
|
|
||||||
}
|
|
||||||
priv->rf_change_in_progress = true;
|
|
||||||
priv->reset_in_progress = true;
|
|
||||||
spin_unlock_irqrestore(&priv->rf_ps_lock, flag);
|
|
||||||
|
|
||||||
RESET_START:
|
|
||||||
|
|
||||||
mutex_lock(&priv->wx_mutex);
|
|
||||||
|
|
||||||
if (priv->rtllib->link_state == MAC80211_LINKED)
|
|
||||||
rtl92e_leisure_ps_leave(dev);
|
|
||||||
|
|
||||||
if (priv->up) {
|
|
||||||
netdev_info(dev, "%s():the driver is not up.\n",
|
|
||||||
__func__);
|
|
||||||
mutex_unlock(&priv->wx_mutex);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
priv->up = 0;
|
|
||||||
|
|
||||||
mdelay(1000);
|
|
||||||
|
|
||||||
if (!netif_queue_stopped(dev))
|
|
||||||
netif_stop_queue(dev);
|
|
||||||
|
|
||||||
rtl92e_irq_disable(dev);
|
|
||||||
del_timer_sync(&priv->watch_dog_timer);
|
|
||||||
_rtl92e_cancel_deferred_work(priv);
|
|
||||||
rtl92e_dm_deinit(dev);
|
|
||||||
rtllib_stop_scan_syncro(ieee);
|
|
||||||
|
|
||||||
if (ieee->link_state == MAC80211_LINKED) {
|
|
||||||
mutex_lock(&ieee->wx_mutex);
|
|
||||||
netdev_info(dev, "ieee->link_state is MAC80211_LINKED\n");
|
|
||||||
rtllib_stop_send_beacons(priv->rtllib);
|
|
||||||
del_timer_sync(&ieee->associate_timer);
|
|
||||||
cancel_delayed_work(&ieee->associate_retry_wq);
|
|
||||||
rtllib_stop_scan(ieee);
|
|
||||||
netif_carrier_off(dev);
|
|
||||||
mutex_unlock(&ieee->wx_mutex);
|
|
||||||
} else {
|
|
||||||
netdev_info(dev, "ieee->link_state is NOT LINKED\n");
|
|
||||||
rtllib_softmac_stop_protocol(priv->rtllib, 0, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
rtl92e_dm_backup_state(dev);
|
|
||||||
|
|
||||||
mutex_unlock(&priv->wx_mutex);
|
|
||||||
reset_status = _rtl92e_up(dev, true);
|
|
||||||
|
|
||||||
if (reset_status == -1) {
|
|
||||||
if (reset_times < 3) {
|
|
||||||
reset_times++;
|
|
||||||
goto RESET_START;
|
|
||||||
} else {
|
|
||||||
netdev_warn(dev, "%s(): Reset Failed\n",
|
|
||||||
__func__);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ieee->is_silent_reset = 1;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&priv->rf_ps_lock, flag);
|
|
||||||
priv->rf_change_in_progress = false;
|
|
||||||
spin_unlock_irqrestore(&priv->rf_ps_lock, flag);
|
|
||||||
|
|
||||||
rtl92e_enable_hw_security_config(dev);
|
|
||||||
|
|
||||||
if (ieee->link_state == MAC80211_LINKED && ieee->iw_mode ==
|
|
||||||
IW_MODE_INFRA) {
|
|
||||||
ieee->set_chan(ieee->dev,
|
|
||||||
ieee->current_network.channel);
|
|
||||||
|
|
||||||
schedule_work(&ieee->associate_complete_wq);
|
|
||||||
|
|
||||||
} else if (ieee->link_state == MAC80211_LINKED && ieee->iw_mode ==
|
|
||||||
IW_MODE_ADHOC) {
|
|
||||||
ieee->set_chan(ieee->dev,
|
|
||||||
ieee->current_network.channel);
|
|
||||||
ieee->link_change(ieee->dev);
|
|
||||||
|
|
||||||
notify_wx_assoc_event(ieee);
|
|
||||||
|
|
||||||
rtllib_start_send_beacons(ieee);
|
|
||||||
|
|
||||||
netif_carrier_on(ieee->dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
rtl92e_cam_restore(dev);
|
|
||||||
rtl92e_dm_restore_state(dev);
|
|
||||||
END:
|
|
||||||
priv->rst_progress = RESET_TYPE_NORESET;
|
|
||||||
priv->reset_count++;
|
|
||||||
priv->reset_in_progress = false;
|
|
||||||
|
|
||||||
rtl92e_writeb(dev, UFWP, 1);
|
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _rtl92e_update_rxcounts(struct r8192_priv *priv, u32 *TotalRxBcnNum,
|
static void _rtl92e_update_rxcounts(struct r8192_priv *priv, u32 *TotalRxBcnNum,
|
||||||
@ -1157,7 +992,6 @@ static void _rtl92e_watchdog_wq_cb(void *data)
|
|||||||
struct r8192_priv, watch_dog_wq);
|
struct r8192_priv, watch_dog_wq);
|
||||||
struct net_device *dev = priv->rtllib->dev;
|
struct net_device *dev = priv->rtllib->dev;
|
||||||
struct rtllib_device *ieee = priv->rtllib;
|
struct rtllib_device *ieee = priv->rtllib;
|
||||||
enum reset_type ResetType = RESET_TYPE_NORESET;
|
|
||||||
static u8 check_reset_cnt;
|
static u8 check_reset_cnt;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *)
|
struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *)
|
||||||
@ -1184,15 +1018,12 @@ static void _rtl92e_watchdog_wq_cb(void *data)
|
|||||||
MAC80211_NOLINK) &&
|
MAC80211_NOLINK) &&
|
||||||
(ieee->rf_power_state == rf_on) && !ieee->is_set_key &&
|
(ieee->rf_power_state == rf_on) && !ieee->is_set_key &&
|
||||||
(!ieee->proto_stoppping) && !ieee->wx_set_enc) {
|
(!ieee->proto_stoppping) && !ieee->wx_set_enc) {
|
||||||
if ((ieee->pwr_save_ctrl.ReturnPoint ==
|
if (ieee->pwr_save_ctrl.ReturnPoint == IPS_CALLBACK_NONE) {
|
||||||
IPS_CALLBACK_NONE) &&
|
|
||||||
(!ieee->net_promiscuous_md)) {
|
|
||||||
rtl92e_ips_enter(dev);
|
rtl92e_ips_enter(dev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((ieee->link_state == MAC80211_LINKED) && (ieee->iw_mode ==
|
if ((ieee->link_state == MAC80211_LINKED) && (ieee->iw_mode == IW_MODE_INFRA)) {
|
||||||
IW_MODE_INFRA) && (!ieee->net_promiscuous_md)) {
|
|
||||||
if (ieee->link_detect_info.NumRxOkInPeriod > 100 ||
|
if (ieee->link_detect_info.NumRxOkInPeriod > 100 ||
|
||||||
ieee->link_detect_info.NumTxOkInPeriod > 100)
|
ieee->link_detect_info.NumTxOkInPeriod > 100)
|
||||||
bBusyTraffic = true;
|
bBusyTraffic = true;
|
||||||
@ -1275,20 +1106,10 @@ static void _rtl92e_watchdog_wq_cb(void *data)
|
|||||||
spin_lock_irqsave(&priv->tx_lock, flags);
|
spin_lock_irqsave(&priv->tx_lock, flags);
|
||||||
if ((check_reset_cnt++ >= 3) && (!ieee->is_roaming) &&
|
if ((check_reset_cnt++ >= 3) && (!ieee->is_roaming) &&
|
||||||
(!priv->rf_change_in_progress) && (!psc->bSwRfProcessing)) {
|
(!priv->rf_change_in_progress) && (!psc->bSwRfProcessing)) {
|
||||||
ResetType = _rtl92e_if_check_reset(dev);
|
_rtl92e_if_check_reset(dev);
|
||||||
check_reset_cnt = 3;
|
check_reset_cnt = 3;
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&priv->tx_lock, flags);
|
spin_unlock_irqrestore(&priv->tx_lock, flags);
|
||||||
|
|
||||||
if (ResetType == RESET_TYPE_NORMAL) {
|
|
||||||
priv->rst_progress = RESET_TYPE_NORMAL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((priv->force_reset || ResetType == RESET_TYPE_SILENT))
|
|
||||||
_rtl92e_if_silent_reset(dev);
|
|
||||||
priv->force_reset = false;
|
|
||||||
priv->reset_in_progress = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _rtl92e_watchdog_timer_cb(struct timer_list *t)
|
static void _rtl92e_watchdog_timer_cb(struct timer_list *t)
|
||||||
@ -1320,28 +1141,25 @@ void rtl92e_tx_enable(struct net_device *dev)
|
|||||||
static void _rtl92e_free_rx_ring(struct net_device *dev)
|
static void _rtl92e_free_rx_ring(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct r8192_priv *priv = rtllib_priv(dev);
|
struct r8192_priv *priv = rtllib_priv(dev);
|
||||||
int i, rx_queue_idx;
|
int i;
|
||||||
|
|
||||||
for (rx_queue_idx = 0; rx_queue_idx < MAX_RX_QUEUE;
|
for (i = 0; i < priv->rxringcount; i++) {
|
||||||
rx_queue_idx++) {
|
struct sk_buff *skb = priv->rx_buf[i];
|
||||||
for (i = 0; i < priv->rxringcount; i++) {
|
|
||||||
struct sk_buff *skb = priv->rx_buf[rx_queue_idx][i];
|
|
||||||
|
|
||||||
if (!skb)
|
if (!skb)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
dma_unmap_single(&priv->pdev->dev,
|
dma_unmap_single(&priv->pdev->dev,
|
||||||
*((dma_addr_t *)skb->cb),
|
*((dma_addr_t *)skb->cb),
|
||||||
priv->rxbuffersize, DMA_FROM_DEVICE);
|
priv->rxbuffersize, DMA_FROM_DEVICE);
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
}
|
|
||||||
|
|
||||||
dma_free_coherent(&priv->pdev->dev,
|
|
||||||
sizeof(*priv->rx_ring[rx_queue_idx]) * priv->rxringcount,
|
|
||||||
priv->rx_ring[rx_queue_idx],
|
|
||||||
priv->rx_ring_dma[rx_queue_idx]);
|
|
||||||
priv->rx_ring[rx_queue_idx] = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dma_free_coherent(&priv->pdev->dev,
|
||||||
|
sizeof(*priv->rx_ring) * priv->rxringcount,
|
||||||
|
priv->rx_ring,
|
||||||
|
priv->rx_ring_dma);
|
||||||
|
priv->rx_ring = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _rtl92e_free_tx_ring(struct net_device *dev, unsigned int prio)
|
static void _rtl92e_free_tx_ring(struct net_device *dev, unsigned int prio)
|
||||||
@ -1374,8 +1192,7 @@ static void _rtl92e_hard_data_xmit(struct sk_buff *skb, struct net_device *dev,
|
|||||||
MAX_DEV_ADDR_SIZE);
|
MAX_DEV_ADDR_SIZE);
|
||||||
u8 queue_index = tcb_desc->queue_index;
|
u8 queue_index = tcb_desc->queue_index;
|
||||||
|
|
||||||
if ((priv->rtllib->rf_power_state == rf_off) || !priv->up ||
|
if ((priv->rtllib->rf_power_state == rf_off) || !priv->up) {
|
||||||
priv->reset_in_progress) {
|
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1408,7 +1225,7 @@ static int _rtl92e_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||||||
|
|
||||||
if (queue_index != TXCMD_QUEUE) {
|
if (queue_index != TXCMD_QUEUE) {
|
||||||
if ((priv->rtllib->rf_power_state == rf_off) ||
|
if ((priv->rtllib->rf_power_state == rf_off) ||
|
||||||
!priv->up || priv->reset_in_progress) {
|
!priv->up) {
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1488,7 +1305,7 @@ static short _rtl92e_tx(struct net_device *dev, struct sk_buff *skb)
|
|||||||
struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb +
|
struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb +
|
||||||
MAX_DEV_ADDR_SIZE);
|
MAX_DEV_ADDR_SIZE);
|
||||||
struct tx_desc *pdesc = NULL;
|
struct tx_desc *pdesc = NULL;
|
||||||
struct rtllib_hdr_1addr *header = NULL;
|
struct ieee80211_hdr *header = NULL;
|
||||||
u8 *pda_addr = NULL;
|
u8 *pda_addr = NULL;
|
||||||
int idx;
|
int idx;
|
||||||
u32 fwinfo_size = 0;
|
u32 fwinfo_size = 0;
|
||||||
@ -1497,7 +1314,7 @@ static short _rtl92e_tx(struct net_device *dev, struct sk_buff *skb)
|
|||||||
|
|
||||||
fwinfo_size = sizeof(struct tx_fwinfo_8190pci);
|
fwinfo_size = sizeof(struct tx_fwinfo_8190pci);
|
||||||
|
|
||||||
header = (struct rtllib_hdr_1addr *)(((u8 *)skb->data) + fwinfo_size);
|
header = (struct ieee80211_hdr *)(((u8 *)skb->data) + fwinfo_size);
|
||||||
pda_addr = header->addr1;
|
pda_addr = header->addr1;
|
||||||
|
|
||||||
if (!is_broadcast_ether_addr(pda_addr) && !is_multicast_ether_addr(pda_addr))
|
if (!is_broadcast_ether_addr(pda_addr) && !is_multicast_ether_addr(pda_addr))
|
||||||
@ -1533,47 +1350,44 @@ static short _rtl92e_alloc_rx_ring(struct net_device *dev)
|
|||||||
{
|
{
|
||||||
struct r8192_priv *priv = rtllib_priv(dev);
|
struct r8192_priv *priv = rtllib_priv(dev);
|
||||||
struct rx_desc *entry = NULL;
|
struct rx_desc *entry = NULL;
|
||||||
int i, rx_queue_idx;
|
int i;
|
||||||
|
|
||||||
for (rx_queue_idx = 0; rx_queue_idx < MAX_RX_QUEUE; rx_queue_idx++) {
|
priv->rx_ring = dma_alloc_coherent(&priv->pdev->dev,
|
||||||
priv->rx_ring[rx_queue_idx] = dma_alloc_coherent(&priv->pdev->dev,
|
sizeof(*priv->rx_ring) * priv->rxringcount,
|
||||||
sizeof(*priv->rx_ring[rx_queue_idx]) * priv->rxringcount,
|
&priv->rx_ring_dma,
|
||||||
&priv->rx_ring_dma[rx_queue_idx],
|
GFP_ATOMIC);
|
||||||
GFP_ATOMIC);
|
if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) {
|
||||||
if (!priv->rx_ring[rx_queue_idx] ||
|
netdev_warn(dev, "Cannot allocate RX ring\n");
|
||||||
(unsigned long)priv->rx_ring[rx_queue_idx] & 0xFF) {
|
return -ENOMEM;
|
||||||
netdev_warn(dev, "Cannot allocate RX ring\n");
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
priv->rx_idx[rx_queue_idx] = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < priv->rxringcount; i++) {
|
|
||||||
struct sk_buff *skb = dev_alloc_skb(priv->rxbuffersize);
|
|
||||||
dma_addr_t *mapping;
|
|
||||||
|
|
||||||
entry = &priv->rx_ring[rx_queue_idx][i];
|
|
||||||
if (!skb)
|
|
||||||
return 0;
|
|
||||||
skb->dev = dev;
|
|
||||||
priv->rx_buf[rx_queue_idx][i] = skb;
|
|
||||||
mapping = (dma_addr_t *)skb->cb;
|
|
||||||
*mapping = dma_map_single(&priv->pdev->dev,
|
|
||||||
skb_tail_pointer(skb),
|
|
||||||
priv->rxbuffersize, DMA_FROM_DEVICE);
|
|
||||||
if (dma_mapping_error(&priv->pdev->dev, *mapping)) {
|
|
||||||
dev_kfree_skb_any(skb);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
entry->BufferAddress = *mapping;
|
|
||||||
|
|
||||||
entry->Length = priv->rxbuffersize;
|
|
||||||
entry->OWN = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entry)
|
|
||||||
entry->EOR = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
priv->rx_idx = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < priv->rxringcount; i++) {
|
||||||
|
struct sk_buff *skb = dev_alloc_skb(priv->rxbuffersize);
|
||||||
|
dma_addr_t *mapping;
|
||||||
|
|
||||||
|
entry = &priv->rx_ring[i];
|
||||||
|
if (!skb)
|
||||||
|
return 0;
|
||||||
|
skb->dev = dev;
|
||||||
|
priv->rx_buf[i] = skb;
|
||||||
|
mapping = (dma_addr_t *)skb->cb;
|
||||||
|
*mapping = dma_map_single(&priv->pdev->dev,
|
||||||
|
skb_tail_pointer(skb),
|
||||||
|
priv->rxbuffersize, DMA_FROM_DEVICE);
|
||||||
|
if (dma_mapping_error(&priv->pdev->dev, *mapping)) {
|
||||||
|
dev_kfree_skb_any(skb);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
entry->BufferAddress = *mapping;
|
||||||
|
|
||||||
|
entry->Length = priv->rxbuffersize;
|
||||||
|
entry->OWN = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry)
|
||||||
|
entry->EOR = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1635,19 +1449,17 @@ err_free_rings:
|
|||||||
void rtl92e_reset_desc_ring(struct net_device *dev)
|
void rtl92e_reset_desc_ring(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct r8192_priv *priv = rtllib_priv(dev);
|
struct r8192_priv *priv = rtllib_priv(dev);
|
||||||
int i, rx_queue_idx;
|
int i;
|
||||||
unsigned long flags = 0;
|
unsigned long flags = 0;
|
||||||
|
|
||||||
for (rx_queue_idx = 0; rx_queue_idx < MAX_RX_QUEUE; rx_queue_idx++) {
|
if (priv->rx_ring) {
|
||||||
if (priv->rx_ring[rx_queue_idx]) {
|
struct rx_desc *entry = NULL;
|
||||||
struct rx_desc *entry = NULL;
|
|
||||||
|
|
||||||
for (i = 0; i < priv->rxringcount; i++) {
|
for (i = 0; i < priv->rxringcount; i++) {
|
||||||
entry = &priv->rx_ring[rx_queue_idx][i];
|
entry = &priv->rx_ring[i];
|
||||||
entry->OWN = 1;
|
entry->OWN = 1;
|
||||||
}
|
|
||||||
priv->rx_idx[rx_queue_idx] = 0;
|
|
||||||
}
|
}
|
||||||
|
priv->rx_idx = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock_irqsave(&priv->irq_th_lock, flags);
|
spin_lock_irqsave(&priv->irq_th_lock, flags);
|
||||||
@ -1743,10 +1555,9 @@ void rtl92e_copy_mpdu_stats(struct rtllib_rx_stats *psrc_stats,
|
|||||||
static void _rtl92e_rx_normal(struct net_device *dev)
|
static void _rtl92e_rx_normal(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct r8192_priv *priv = rtllib_priv(dev);
|
struct r8192_priv *priv = rtllib_priv(dev);
|
||||||
struct rtllib_hdr_1addr *rtllib_hdr = NULL;
|
struct ieee80211_hdr *rtllib_hdr = NULL;
|
||||||
bool unicast_packet = false;
|
bool unicast_packet = false;
|
||||||
u32 skb_len = 0;
|
u32 skb_len = 0;
|
||||||
int rx_queue_idx = RX_MPDU_QUEUE;
|
|
||||||
|
|
||||||
struct rtllib_rx_stats stats = {
|
struct rtllib_rx_stats stats = {
|
||||||
.signal = 0,
|
.signal = 0,
|
||||||
@ -1758,10 +1569,10 @@ static void _rtl92e_rx_normal(struct net_device *dev)
|
|||||||
stats.nic_type = NIC_8192E;
|
stats.nic_type = NIC_8192E;
|
||||||
|
|
||||||
while (count--) {
|
while (count--) {
|
||||||
struct rx_desc *pdesc = &priv->rx_ring[rx_queue_idx]
|
struct rx_desc *pdesc = &priv->rx_ring
|
||||||
[priv->rx_idx[rx_queue_idx]];
|
[priv->rx_idx];
|
||||||
struct sk_buff *skb = priv->rx_buf[rx_queue_idx]
|
struct sk_buff *skb = priv->rx_buf
|
||||||
[priv->rx_idx[rx_queue_idx]];
|
[priv->rx_idx];
|
||||||
struct sk_buff *new_skb;
|
struct sk_buff *new_skb;
|
||||||
|
|
||||||
if (pdesc->OWN)
|
if (pdesc->OWN)
|
||||||
@ -1782,7 +1593,7 @@ static void _rtl92e_rx_normal(struct net_device *dev)
|
|||||||
skb_reserve(skb, stats.RxDrvInfoSize +
|
skb_reserve(skb, stats.RxDrvInfoSize +
|
||||||
stats.RxBufShift);
|
stats.RxBufShift);
|
||||||
skb_trim(skb, skb->len - S_CRC_LEN);
|
skb_trim(skb, skb->len - S_CRC_LEN);
|
||||||
rtllib_hdr = (struct rtllib_hdr_1addr *)skb->data;
|
rtllib_hdr = (struct ieee80211_hdr *)skb->data;
|
||||||
if (!is_multicast_ether_addr(rtllib_hdr->addr1)) {
|
if (!is_multicast_ether_addr(rtllib_hdr->addr1)) {
|
||||||
/* unicast packet */
|
/* unicast packet */
|
||||||
unicast_packet = true;
|
unicast_packet = true;
|
||||||
@ -1799,8 +1610,7 @@ static void _rtl92e_rx_normal(struct net_device *dev)
|
|||||||
skb = new_skb;
|
skb = new_skb;
|
||||||
skb->dev = dev;
|
skb->dev = dev;
|
||||||
|
|
||||||
priv->rx_buf[rx_queue_idx][priv->rx_idx[rx_queue_idx]] =
|
priv->rx_buf[priv->rx_idx] = skb;
|
||||||
skb;
|
|
||||||
*((dma_addr_t *)skb->cb) = dma_map_single(&priv->pdev->dev,
|
*((dma_addr_t *)skb->cb) = dma_map_single(&priv->pdev->dev,
|
||||||
skb_tail_pointer(skb),
|
skb_tail_pointer(skb),
|
||||||
priv->rxbuffersize, DMA_FROM_DEVICE);
|
priv->rxbuffersize, DMA_FROM_DEVICE);
|
||||||
@ -1812,9 +1622,9 @@ done:
|
|||||||
pdesc->BufferAddress = *((dma_addr_t *)skb->cb);
|
pdesc->BufferAddress = *((dma_addr_t *)skb->cb);
|
||||||
pdesc->OWN = 1;
|
pdesc->OWN = 1;
|
||||||
pdesc->Length = priv->rxbuffersize;
|
pdesc->Length = priv->rxbuffersize;
|
||||||
if (priv->rx_idx[rx_queue_idx] == priv->rxringcount - 1)
|
if (priv->rx_idx == priv->rxringcount - 1)
|
||||||
pdesc->EOR = 1;
|
pdesc->EOR = 1;
|
||||||
priv->rx_idx[rx_queue_idx] = (priv->rx_idx[rx_queue_idx] + 1) %
|
priv->rx_idx = (priv->rx_idx + 1) %
|
||||||
priv->rxringcount;
|
priv->rxringcount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1865,9 +1675,9 @@ static void _rtl92e_cancel_deferred_work(struct r8192_priv *priv)
|
|||||||
cancel_work_sync(&priv->qos_activate);
|
cancel_work_sync(&priv->qos_activate);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _rtl92e_up(struct net_device *dev, bool is_silent_reset)
|
static int _rtl92e_up(struct net_device *dev)
|
||||||
{
|
{
|
||||||
if (_rtl92e_sta_up(dev, is_silent_reset) == -1)
|
if (_rtl92e_sta_up(dev) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1889,7 +1699,7 @@ static int _rtl92e_try_up(struct net_device *dev)
|
|||||||
|
|
||||||
if (priv->up == 1)
|
if (priv->up == 1)
|
||||||
return -1;
|
return -1;
|
||||||
return _rtl92e_up(dev, false);
|
return _rtl92e_up(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _rtl92e_close(struct net_device *dev)
|
static int _rtl92e_close(struct net_device *dev)
|
||||||
@ -1925,10 +1735,10 @@ void rtl92e_commit(struct net_device *dev)
|
|||||||
|
|
||||||
if (priv->up == 0)
|
if (priv->up == 0)
|
||||||
return;
|
return;
|
||||||
rtllib_softmac_stop_protocol(priv->rtllib, 0, true);
|
rtllib_softmac_stop_protocol(priv->rtllib);
|
||||||
rtl92e_irq_disable(dev);
|
rtl92e_irq_disable(dev);
|
||||||
rtl92e_stop_adapter(dev, true);
|
rtl92e_stop_adapter(dev, true);
|
||||||
_rtl92e_up(dev, false);
|
_rtl92e_up(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _rtl92e_restart(void *data)
|
static void _rtl92e_restart(void *data)
|
||||||
|
@ -91,8 +91,6 @@
|
|||||||
|
|
||||||
#define MAX_TX_QUEUE 9
|
#define MAX_TX_QUEUE 9
|
||||||
|
|
||||||
#define MAX_RX_QUEUE 1
|
|
||||||
|
|
||||||
#define MAX_RX_COUNT 64
|
#define MAX_RX_COUNT 64
|
||||||
#define MAX_TX_QUEUE_COUNT 9
|
#define MAX_TX_QUEUE_COUNT 9
|
||||||
|
|
||||||
@ -132,7 +130,6 @@ enum rt_customer_id {
|
|||||||
|
|
||||||
enum reset_type {
|
enum reset_type {
|
||||||
RESET_TYPE_NORESET = 0x00,
|
RESET_TYPE_NORESET = 0x00,
|
||||||
RESET_TYPE_NORMAL = 0x01,
|
|
||||||
RESET_TYPE_SILENT = 0x02
|
RESET_TYPE_SILENT = 0x02
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -233,10 +230,10 @@ struct r8192_priv {
|
|||||||
|
|
||||||
u8 (*rf_set_chan)(struct net_device *dev, u8 ch);
|
u8 (*rf_set_chan)(struct net_device *dev, u8 ch);
|
||||||
|
|
||||||
struct rx_desc *rx_ring[MAX_RX_QUEUE];
|
struct rx_desc *rx_ring;
|
||||||
struct sk_buff *rx_buf[MAX_RX_QUEUE][MAX_RX_COUNT];
|
struct sk_buff *rx_buf[MAX_RX_COUNT];
|
||||||
dma_addr_t rx_ring_dma[MAX_RX_QUEUE];
|
dma_addr_t rx_ring_dma;
|
||||||
unsigned int rx_idx[MAX_RX_QUEUE];
|
unsigned int rx_idx;
|
||||||
int rxringcount;
|
int rxringcount;
|
||||||
u16 rxbuffersize;
|
u16 rxbuffersize;
|
||||||
|
|
||||||
@ -264,7 +261,6 @@ struct r8192_priv {
|
|||||||
short promisc;
|
short promisc;
|
||||||
|
|
||||||
short chan;
|
short chan;
|
||||||
bool ps_force;
|
|
||||||
|
|
||||||
u32 irq_mask[2];
|
u32 irq_mask[2];
|
||||||
|
|
||||||
@ -345,7 +341,6 @@ struct r8192_priv {
|
|||||||
u8 rfa_txpowertrackingindex;
|
u8 rfa_txpowertrackingindex;
|
||||||
u8 rfa_txpowertrackingindex_real;
|
u8 rfa_txpowertrackingindex_real;
|
||||||
u8 rfa_txpowertracking_default;
|
u8 rfa_txpowertracking_default;
|
||||||
u8 rfc_txpowertrackingindex;
|
|
||||||
bool btxpower_tracking;
|
bool btxpower_tracking;
|
||||||
bool bcck_in_ch14;
|
bool bcck_in_ch14;
|
||||||
|
|
||||||
@ -369,14 +364,9 @@ struct r8192_priv {
|
|||||||
u32 continue_diff_count;
|
u32 continue_diff_count;
|
||||||
bool bswitch_fsync;
|
bool bswitch_fsync;
|
||||||
u8 framesync;
|
u8 framesync;
|
||||||
u32 reset_count;
|
|
||||||
|
|
||||||
enum reset_type rst_progress;
|
|
||||||
u16 tx_counter;
|
u16 tx_counter;
|
||||||
u16 rx_ctr;
|
u16 rx_ctr;
|
||||||
bool reset_in_progress;
|
|
||||||
bool force_reset;
|
|
||||||
bool force_lps;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const struct ethtool_ops rtl819x_ethtool_ops;
|
extern const struct ethtool_ops rtl819x_ethtool_ops;
|
||||||
|
@ -161,12 +161,9 @@ static void _rtl92e_dm_bandwidth_autoswitch(struct net_device *dev);
|
|||||||
|
|
||||||
static void _rtl92e_dm_check_tx_power_tracking(struct net_device *dev);
|
static void _rtl92e_dm_check_tx_power_tracking(struct net_device *dev);
|
||||||
|
|
||||||
static void _rtl92e_dm_bb_initialgain_restore(struct net_device *dev);
|
|
||||||
static void _rtl92e_dm_dig_init(struct net_device *dev);
|
static void _rtl92e_dm_dig_init(struct net_device *dev);
|
||||||
static void _rtl92e_dm_ctrl_initgain_byrssi(struct net_device *dev);
|
static void _rtl92e_dm_ctrl_initgain_byrssi(struct net_device *dev);
|
||||||
static void _rtl92e_dm_ctrl_initgain_byrssi_highpwr(struct net_device *dev);
|
|
||||||
static void _rtl92e_dm_ctrl_initgain_byrssi_driver(struct net_device *dev);
|
static void _rtl92e_dm_ctrl_initgain_byrssi_driver(struct net_device *dev);
|
||||||
static void _rtl92e_dm_ctrl_initgain_byrssi_false_alarm(struct net_device *dev);
|
|
||||||
static void _rtl92e_dm_initial_gain(struct net_device *dev);
|
static void _rtl92e_dm_initial_gain(struct net_device *dev);
|
||||||
static void _rtl92e_dm_pd_th(struct net_device *dev);
|
static void _rtl92e_dm_pd_th(struct net_device *dev);
|
||||||
static void _rtl92e_dm_cs_ratio(struct net_device *dev);
|
static void _rtl92e_dm_cs_ratio(struct net_device *dev);
|
||||||
@ -285,9 +282,6 @@ static void _rtl92e_dm_check_rate_adaptive(struct net_device *dev)
|
|||||||
if (!priv->up)
|
if (!priv->up)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (pra->rate_adaptive_disabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (priv->rtllib->mode != WIRELESS_MODE_N_24G)
|
if (priv->rtllib->mode != WIRELESS_MODE_N_24G)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -298,25 +292,25 @@ static void _rtl92e_dm_check_rate_adaptive(struct net_device *dev)
|
|||||||
ht_info->bCurShortGI20MHz);
|
ht_info->bCurShortGI20MHz);
|
||||||
|
|
||||||
pra->upper_rssi_threshold_ratr =
|
pra->upper_rssi_threshold_ratr =
|
||||||
(pra->upper_rssi_threshold_ratr & (~BIT31)) |
|
(pra->upper_rssi_threshold_ratr & (~BIT(31))) |
|
||||||
((bshort_gi_enabled) ? BIT31 : 0);
|
((bshort_gi_enabled) ? BIT(31) : 0);
|
||||||
|
|
||||||
pra->middle_rssi_threshold_ratr =
|
pra->middle_rssi_threshold_ratr =
|
||||||
(pra->middle_rssi_threshold_ratr & (~BIT31)) |
|
(pra->middle_rssi_threshold_ratr & (~BIT(31))) |
|
||||||
((bshort_gi_enabled) ? BIT31 : 0);
|
((bshort_gi_enabled) ? BIT(31) : 0);
|
||||||
|
|
||||||
if (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20) {
|
if (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20) {
|
||||||
pra->low_rssi_threshold_ratr =
|
pra->low_rssi_threshold_ratr =
|
||||||
(pra->low_rssi_threshold_ratr_40M & (~BIT31)) |
|
(pra->low_rssi_threshold_ratr_40M & (~BIT(31))) |
|
||||||
((bshort_gi_enabled) ? BIT31 : 0);
|
((bshort_gi_enabled) ? BIT(31) : 0);
|
||||||
} else {
|
} else {
|
||||||
pra->low_rssi_threshold_ratr =
|
pra->low_rssi_threshold_ratr =
|
||||||
(pra->low_rssi_threshold_ratr_20M & (~BIT31)) |
|
(pra->low_rssi_threshold_ratr_20M & (~BIT(31))) |
|
||||||
((bshort_gi_enabled) ? BIT31 : 0);
|
((bshort_gi_enabled) ? BIT(31) : 0);
|
||||||
}
|
}
|
||||||
pra->ping_rssi_ratr =
|
pra->ping_rssi_ratr =
|
||||||
(pra->ping_rssi_ratr & (~BIT31)) |
|
(pra->ping_rssi_ratr & (~BIT(31))) |
|
||||||
((bshort_gi_enabled) ? BIT31 : 0);
|
((bshort_gi_enabled) ? BIT(31) : 0);
|
||||||
|
|
||||||
if (pra->ratr_state == DM_RATR_STA_HIGH) {
|
if (pra->ratr_state == DM_RATR_STA_HIGH) {
|
||||||
high_rssi_thresh_for_ra = pra->high2low_rssi_thresh_for_ra;
|
high_rssi_thresh_for_ra = pra->high2low_rssi_thresh_for_ra;
|
||||||
@ -371,8 +365,6 @@ static void _rtl92e_dm_check_rate_adaptive(struct net_device *dev)
|
|||||||
ratr_value &= ~(RATE_ALL_OFDM_2SS);
|
ratr_value &= ~(RATE_ALL_OFDM_2SS);
|
||||||
rtl92e_writel(dev, RATR0, ratr_value);
|
rtl92e_writel(dev, RATR0, ratr_value);
|
||||||
rtl92e_writeb(dev, UFWP, 1);
|
rtl92e_writeb(dev, UFWP, 1);
|
||||||
|
|
||||||
pra->last_ratr = target_ratr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -530,11 +522,6 @@ static void _rtl92e_dm_tx_power_tracking_callback_tssi(struct net_device *dev)
|
|||||||
if (Pwr_Flag == 0) {
|
if (Pwr_Flag == 0) {
|
||||||
mdelay(1);
|
mdelay(1);
|
||||||
|
|
||||||
if (priv->reset_in_progress) {
|
|
||||||
rtl92e_writeb(dev, Pw_Track_Flag, 0);
|
|
||||||
rtl92e_writeb(dev, FW_Busy_Flag, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (priv->rtllib->rf_power_state != rf_on) {
|
if (priv->rtllib->rf_power_state != rf_on) {
|
||||||
rtl92e_writeb(dev, Pw_Track_Flag, 0);
|
rtl92e_writeb(dev, Pw_Track_Flag, 0);
|
||||||
rtl92e_writeb(dev, FW_Busy_Flag, 0);
|
rtl92e_writeb(dev, FW_Busy_Flag, 0);
|
||||||
@ -920,95 +907,10 @@ void rtl92e_dm_cck_txpower_adjust(struct net_device *dev, bool binch14)
|
|||||||
_rtl92e_dm_cck_tx_power_adjust_thermal_meter(dev, binch14);
|
_rtl92e_dm_cck_tx_power_adjust_thermal_meter(dev, binch14);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _rtl92e_dm_tx_power_reset_recovery(struct net_device *dev)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = rtllib_priv(dev);
|
|
||||||
|
|
||||||
rtl92e_set_bb_reg(dev, rOFDM0_XATxIQImbalance, bMaskDWord,
|
|
||||||
dm_tx_bb_gain[priv->rfa_txpowertrackingindex]);
|
|
||||||
rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
|
|
||||||
|
|
||||||
rtl92e_set_bb_reg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord,
|
|
||||||
dm_tx_bb_gain[priv->rfc_txpowertrackingindex]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void rtl92e_dm_restore_state(struct net_device *dev)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = rtllib_priv(dev);
|
|
||||||
u32 reg_ratr = priv->rate_adaptive.last_ratr;
|
|
||||||
u32 ratr_value;
|
|
||||||
|
|
||||||
if (!priv->up)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (priv->rate_adaptive.rate_adaptive_disabled)
|
|
||||||
return;
|
|
||||||
if (priv->rtllib->mode != WIRELESS_MODE_N_24G)
|
|
||||||
return;
|
|
||||||
ratr_value = reg_ratr;
|
|
||||||
ratr_value &= ~(RATE_ALL_OFDM_2SS);
|
|
||||||
rtl92e_writel(dev, RATR0, ratr_value);
|
|
||||||
rtl92e_writeb(dev, UFWP, 1);
|
|
||||||
if (priv->tx_pwr_tracking_init && priv->btxpower_tracking)
|
|
||||||
_rtl92e_dm_tx_power_reset_recovery(dev);
|
|
||||||
|
|
||||||
_rtl92e_dm_bb_initialgain_restore(dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _rtl92e_dm_bb_initialgain_restore(struct net_device *dev)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = rtllib_priv(dev);
|
|
||||||
u32 bit_mask = 0x7f;
|
|
||||||
|
|
||||||
if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
|
|
||||||
return;
|
|
||||||
|
|
||||||
rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x8);
|
|
||||||
rtl92e_set_bb_reg(dev, rOFDM0_XAAGCCore1, bit_mask,
|
|
||||||
(u32)priv->initgain_backup.xaagccore1);
|
|
||||||
rtl92e_set_bb_reg(dev, rOFDM0_XBAGCCore1, bit_mask,
|
|
||||||
(u32)priv->initgain_backup.xbagccore1);
|
|
||||||
rtl92e_set_bb_reg(dev, rOFDM0_XCAGCCore1, bit_mask,
|
|
||||||
(u32)priv->initgain_backup.xcagccore1);
|
|
||||||
rtl92e_set_bb_reg(dev, rOFDM0_XDAGCCore1, bit_mask,
|
|
||||||
(u32)priv->initgain_backup.xdagccore1);
|
|
||||||
bit_mask = bMaskByte2;
|
|
||||||
rtl92e_set_bb_reg(dev, rCCK0_CCA, bit_mask,
|
|
||||||
(u32)priv->initgain_backup.cca);
|
|
||||||
rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void rtl92e_dm_backup_state(struct net_device *dev)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = rtllib_priv(dev);
|
|
||||||
u32 bit_mask = bMaskByte0;
|
|
||||||
|
|
||||||
priv->bswitch_fsync = false;
|
|
||||||
|
|
||||||
if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
|
|
||||||
return;
|
|
||||||
|
|
||||||
rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x8);
|
|
||||||
priv->initgain_backup.xaagccore1 = rtl92e_get_bb_reg(dev, rOFDM0_XAAGCCore1, bit_mask);
|
|
||||||
priv->initgain_backup.xbagccore1 = rtl92e_get_bb_reg(dev, rOFDM0_XBAGCCore1, bit_mask);
|
|
||||||
priv->initgain_backup.xcagccore1 = rtl92e_get_bb_reg(dev, rOFDM0_XCAGCCore1, bit_mask);
|
|
||||||
priv->initgain_backup.xdagccore1 = rtl92e_get_bb_reg(dev, rOFDM0_XDAGCCore1, bit_mask);
|
|
||||||
bit_mask = bMaskByte2;
|
|
||||||
priv->initgain_backup.cca = (u8)rtl92e_get_bb_reg(dev, rCCK0_CCA, bit_mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _rtl92e_dm_dig_init(struct net_device *dev)
|
static void _rtl92e_dm_dig_init(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct r8192_priv *priv = rtllib_priv(dev);
|
struct r8192_priv *priv = rtllib_priv(dev);
|
||||||
|
|
||||||
dm_digtable.dig_enable_flag = true;
|
|
||||||
|
|
||||||
dm_digtable.dig_algorithm = DIG_ALGO_BY_RSSI;
|
|
||||||
|
|
||||||
dm_digtable.dig_algorithm_switch = 0;
|
|
||||||
|
|
||||||
dm_digtable.dig_state = DM_STA_DIG_MAX;
|
|
||||||
dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX;
|
|
||||||
dm_digtable.cur_sta_connect_state = DIG_STA_DISCONNECT;
|
dm_digtable.cur_sta_connect_state = DIG_STA_DISCONNECT;
|
||||||
dm_digtable.pre_sta_connect_state = DIG_STA_DISCONNECT;
|
dm_digtable.pre_sta_connect_state = DIG_STA_DISCONNECT;
|
||||||
|
|
||||||
@ -1029,15 +931,7 @@ static void _rtl92e_dm_dig_init(struct net_device *dev)
|
|||||||
|
|
||||||
static void _rtl92e_dm_ctrl_initgain_byrssi(struct net_device *dev)
|
static void _rtl92e_dm_ctrl_initgain_byrssi(struct net_device *dev)
|
||||||
{
|
{
|
||||||
if (!dm_digtable.dig_enable_flag)
|
_rtl92e_dm_ctrl_initgain_byrssi_driver(dev);
|
||||||
return;
|
|
||||||
|
|
||||||
if (dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
|
|
||||||
_rtl92e_dm_ctrl_initgain_byrssi_false_alarm(dev);
|
|
||||||
else if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
|
|
||||||
_rtl92e_dm_ctrl_initgain_byrssi_driver(dev);
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------
|
/*-----------------------------------------------------------------------------
|
||||||
@ -1064,16 +958,10 @@ static void _rtl92e_dm_ctrl_initgain_byrssi_driver(struct net_device *dev)
|
|||||||
u8 i;
|
u8 i;
|
||||||
static u8 fw_dig;
|
static u8 fw_dig;
|
||||||
|
|
||||||
if (!dm_digtable.dig_enable_flag)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (dm_digtable.dig_algorithm_switch)
|
|
||||||
fw_dig = 0;
|
|
||||||
if (fw_dig <= 3) {
|
if (fw_dig <= 3) {
|
||||||
for (i = 0; i < 3; i++)
|
for (i = 0; i < 3; i++)
|
||||||
rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x8);
|
rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x8);
|
||||||
fw_dig++;
|
fw_dig++;
|
||||||
dm_digtable.dig_state = DM_STA_DIG_OFF;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->rtllib->link_state == MAC80211_LINKED)
|
if (priv->rtllib->link_state == MAC80211_LINKED)
|
||||||
@ -1085,150 +973,14 @@ static void _rtl92e_dm_ctrl_initgain_byrssi_driver(struct net_device *dev)
|
|||||||
_rtl92e_dm_initial_gain(dev);
|
_rtl92e_dm_initial_gain(dev);
|
||||||
_rtl92e_dm_pd_th(dev);
|
_rtl92e_dm_pd_th(dev);
|
||||||
_rtl92e_dm_cs_ratio(dev);
|
_rtl92e_dm_cs_ratio(dev);
|
||||||
if (dm_digtable.dig_algorithm_switch)
|
|
||||||
dm_digtable.dig_algorithm_switch = 0;
|
|
||||||
dm_digtable.pre_sta_connect_state = dm_digtable.cur_sta_connect_state;
|
dm_digtable.pre_sta_connect_state = dm_digtable.cur_sta_connect_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _rtl92e_dm_ctrl_initgain_byrssi_false_alarm(struct net_device *dev)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = rtllib_priv(dev);
|
|
||||||
static u32 reset_cnt;
|
|
||||||
u8 i;
|
|
||||||
|
|
||||||
if (!dm_digtable.dig_enable_flag)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (dm_digtable.dig_algorithm_switch) {
|
|
||||||
dm_digtable.dig_state = DM_STA_DIG_MAX;
|
|
||||||
for (i = 0; i < 3; i++)
|
|
||||||
rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x1);
|
|
||||||
dm_digtable.dig_algorithm_switch = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (priv->rtllib->link_state != MAC80211_LINKED)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_low_thresh) &&
|
|
||||||
(priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_thresh))
|
|
||||||
return;
|
|
||||||
if (priv->undecorated_smoothed_pwdb <= dm_digtable.rssi_low_thresh) {
|
|
||||||
if (dm_digtable.dig_state == DM_STA_DIG_OFF &&
|
|
||||||
(priv->reset_count == reset_cnt))
|
|
||||||
return;
|
|
||||||
reset_cnt = priv->reset_count;
|
|
||||||
|
|
||||||
dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX;
|
|
||||||
dm_digtable.dig_state = DM_STA_DIG_OFF;
|
|
||||||
|
|
||||||
rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x8);
|
|
||||||
|
|
||||||
rtl92e_writeb(dev, rOFDM0_XAAGCCore1, 0x17);
|
|
||||||
rtl92e_writeb(dev, rOFDM0_XBAGCCore1, 0x17);
|
|
||||||
rtl92e_writeb(dev, rOFDM0_XCAGCCore1, 0x17);
|
|
||||||
rtl92e_writeb(dev, rOFDM0_XDAGCCore1, 0x17);
|
|
||||||
|
|
||||||
if (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20)
|
|
||||||
rtl92e_writeb(dev, (rOFDM0_XATxAFE + 3), 0x00);
|
|
||||||
else
|
|
||||||
rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x42);
|
|
||||||
|
|
||||||
rtl92e_writeb(dev, 0xa0a, 0x08);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) {
|
|
||||||
u8 reset_flag = 0;
|
|
||||||
|
|
||||||
if (dm_digtable.dig_state == DM_STA_DIG_ON &&
|
|
||||||
(priv->reset_count == reset_cnt)) {
|
|
||||||
_rtl92e_dm_ctrl_initgain_byrssi_highpwr(dev);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (priv->reset_count != reset_cnt)
|
|
||||||
reset_flag = 1;
|
|
||||||
|
|
||||||
reset_cnt = priv->reset_count;
|
|
||||||
|
|
||||||
dm_digtable.dig_state = DM_STA_DIG_ON;
|
|
||||||
|
|
||||||
if (reset_flag == 1) {
|
|
||||||
rtl92e_writeb(dev, rOFDM0_XAAGCCore1, 0x2c);
|
|
||||||
rtl92e_writeb(dev, rOFDM0_XBAGCCore1, 0x2c);
|
|
||||||
rtl92e_writeb(dev, rOFDM0_XCAGCCore1, 0x2c);
|
|
||||||
rtl92e_writeb(dev, rOFDM0_XDAGCCore1, 0x2c);
|
|
||||||
} else {
|
|
||||||
rtl92e_writeb(dev, rOFDM0_XAAGCCore1, 0x20);
|
|
||||||
rtl92e_writeb(dev, rOFDM0_XBAGCCore1, 0x20);
|
|
||||||
rtl92e_writeb(dev, rOFDM0_XCAGCCore1, 0x20);
|
|
||||||
rtl92e_writeb(dev, rOFDM0_XDAGCCore1, 0x20);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20)
|
|
||||||
rtl92e_writeb(dev, (rOFDM0_XATxAFE + 3), 0x20);
|
|
||||||
else
|
|
||||||
rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x44);
|
|
||||||
|
|
||||||
rtl92e_writeb(dev, 0xa0a, 0xcd);
|
|
||||||
|
|
||||||
rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x1);
|
|
||||||
}
|
|
||||||
_rtl92e_dm_ctrl_initgain_byrssi_highpwr(dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _rtl92e_dm_ctrl_initgain_byrssi_highpwr(struct net_device *dev)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = rtllib_priv(dev);
|
|
||||||
static u32 reset_cnt_highpwr;
|
|
||||||
|
|
||||||
if ((priv->undecorated_smoothed_pwdb >
|
|
||||||
dm_digtable.rssi_high_power_lowthresh) &&
|
|
||||||
(priv->undecorated_smoothed_pwdb <
|
|
||||||
dm_digtable.rssi_high_power_highthresh))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (priv->undecorated_smoothed_pwdb >=
|
|
||||||
dm_digtable.rssi_high_power_highthresh) {
|
|
||||||
if (dm_digtable.dig_highpwr_state == DM_STA_DIG_ON &&
|
|
||||||
(priv->reset_count == reset_cnt_highpwr))
|
|
||||||
return;
|
|
||||||
dm_digtable.dig_highpwr_state = DM_STA_DIG_ON;
|
|
||||||
|
|
||||||
if (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20)
|
|
||||||
rtl92e_writeb(dev, (rOFDM0_XATxAFE + 3), 0x10);
|
|
||||||
else
|
|
||||||
rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x43);
|
|
||||||
} else {
|
|
||||||
if (dm_digtable.dig_highpwr_state == DM_STA_DIG_OFF &&
|
|
||||||
(priv->reset_count == reset_cnt_highpwr))
|
|
||||||
return;
|
|
||||||
dm_digtable.dig_highpwr_state = DM_STA_DIG_OFF;
|
|
||||||
|
|
||||||
if ((priv->undecorated_smoothed_pwdb <
|
|
||||||
dm_digtable.rssi_high_power_lowthresh) &&
|
|
||||||
(priv->undecorated_smoothed_pwdb >=
|
|
||||||
dm_digtable.rssi_high_thresh)) {
|
|
||||||
if (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20)
|
|
||||||
rtl92e_writeb(dev, (rOFDM0_XATxAFE + 3), 0x20);
|
|
||||||
else
|
|
||||||
rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x44);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
reset_cnt_highpwr = priv->reset_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _rtl92e_dm_initial_gain(struct net_device *dev)
|
static void _rtl92e_dm_initial_gain(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct r8192_priv *priv = rtllib_priv(dev);
|
struct r8192_priv *priv = rtllib_priv(dev);
|
||||||
u8 initial_gain = 0;
|
u8 initial_gain = 0;
|
||||||
static u8 initialized, force_write;
|
static u8 initialized, force_write;
|
||||||
static u32 reset_cnt;
|
|
||||||
|
|
||||||
if (dm_digtable.dig_algorithm_switch) {
|
|
||||||
initialized = 0;
|
|
||||||
reset_cnt = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rtllib_act_scanning(priv->rtllib, true)) {
|
if (rtllib_act_scanning(priv->rtllib, true)) {
|
||||||
force_write = 1;
|
force_write = 1;
|
||||||
@ -1254,11 +1006,6 @@ static void _rtl92e_dm_initial_gain(struct net_device *dev)
|
|||||||
dm_digtable.pre_ig_value = 0;
|
dm_digtable.pre_ig_value = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->reset_count != reset_cnt) {
|
|
||||||
force_write = 1;
|
|
||||||
reset_cnt = priv->reset_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dm_digtable.pre_ig_value != rtl92e_readb(dev, rOFDM0_XAAGCCore1))
|
if (dm_digtable.pre_ig_value != rtl92e_readb(dev, rOFDM0_XAAGCCore1))
|
||||||
force_write = 1;
|
force_write = 1;
|
||||||
|
|
||||||
@ -1279,12 +1026,6 @@ static void _rtl92e_dm_pd_th(struct net_device *dev)
|
|||||||
{
|
{
|
||||||
struct r8192_priv *priv = rtllib_priv(dev);
|
struct r8192_priv *priv = rtllib_priv(dev);
|
||||||
static u8 initialized, force_write;
|
static u8 initialized, force_write;
|
||||||
static u32 reset_cnt;
|
|
||||||
|
|
||||||
if (dm_digtable.dig_algorithm_switch) {
|
|
||||||
initialized = 0;
|
|
||||||
reset_cnt = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dm_digtable.pre_sta_connect_state == dm_digtable.cur_sta_connect_state) {
|
if (dm_digtable.pre_sta_connect_state == dm_digtable.cur_sta_connect_state) {
|
||||||
if (dm_digtable.cur_sta_connect_state == DIG_STA_CONNECT) {
|
if (dm_digtable.cur_sta_connect_state == DIG_STA_CONNECT) {
|
||||||
@ -1312,11 +1053,6 @@ static void _rtl92e_dm_pd_th(struct net_device *dev)
|
|||||||
dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
|
dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->reset_count != reset_cnt) {
|
|
||||||
force_write = 1;
|
|
||||||
reset_cnt = priv->reset_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((dm_digtable.prepd_thstate != dm_digtable.curpd_thstate) ||
|
if ((dm_digtable.prepd_thstate != dm_digtable.curpd_thstate) ||
|
||||||
(initialized <= 3) || force_write) {
|
(initialized <= 3) || force_write) {
|
||||||
if (dm_digtable.curpd_thstate == DIG_PD_AT_LOW_POWER) {
|
if (dm_digtable.curpd_thstate == DIG_PD_AT_LOW_POWER) {
|
||||||
@ -1345,14 +1081,7 @@ static void _rtl92e_dm_pd_th(struct net_device *dev)
|
|||||||
|
|
||||||
static void _rtl92e_dm_cs_ratio(struct net_device *dev)
|
static void _rtl92e_dm_cs_ratio(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct r8192_priv *priv = rtllib_priv(dev);
|
|
||||||
static u8 initialized, force_write;
|
static u8 initialized, force_write;
|
||||||
static u32 reset_cnt;
|
|
||||||
|
|
||||||
if (dm_digtable.dig_algorithm_switch) {
|
|
||||||
initialized = 0;
|
|
||||||
reset_cnt = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dm_digtable.pre_sta_connect_state == dm_digtable.cur_sta_connect_state) {
|
if (dm_digtable.pre_sta_connect_state == dm_digtable.cur_sta_connect_state) {
|
||||||
if (dm_digtable.cur_sta_connect_state == DIG_STA_CONNECT) {
|
if (dm_digtable.cur_sta_connect_state == DIG_STA_CONNECT) {
|
||||||
@ -1369,11 +1098,6 @@ static void _rtl92e_dm_cs_ratio(struct net_device *dev)
|
|||||||
dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
|
dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->reset_count != reset_cnt) {
|
|
||||||
force_write = 1;
|
|
||||||
reset_cnt = priv->reset_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((dm_digtable.precs_ratio_state != dm_digtable.curcs_ratio_state) ||
|
if ((dm_digtable.precs_ratio_state != dm_digtable.curcs_ratio_state) ||
|
||||||
!initialized || force_write) {
|
!initialized || force_write) {
|
||||||
if (dm_digtable.curcs_ratio_state == DIG_CS_RATIO_LOWER)
|
if (dm_digtable.curcs_ratio_state == DIG_CS_RATIO_LOWER)
|
||||||
@ -1405,8 +1129,6 @@ static void _rtl92e_dm_check_edca_turbo(struct net_device *dev)
|
|||||||
unsigned long curTxOkCnt = 0;
|
unsigned long curTxOkCnt = 0;
|
||||||
unsigned long curRxOkCnt = 0;
|
unsigned long curRxOkCnt = 0;
|
||||||
|
|
||||||
if (priv->rtllib->iw_mode == IW_MODE_ADHOC)
|
|
||||||
goto dm_CheckEdcaTurbo_EXIT;
|
|
||||||
if (priv->rtllib->link_state != MAC80211_LINKED)
|
if (priv->rtllib->link_state != MAC80211_LINKED)
|
||||||
goto dm_CheckEdcaTurbo_EXIT;
|
goto dm_CheckEdcaTurbo_EXIT;
|
||||||
if (priv->rtllib->ht_info->iot_action & HT_IOT_ACT_DISABLE_EDCA_TURBO)
|
if (priv->rtllib->ht_info->iot_action & HT_IOT_ACT_DISABLE_EDCA_TURBO)
|
||||||
@ -1525,7 +1247,7 @@ static void _rtl92e_dm_check_rf_ctrl_gpio(void *data)
|
|||||||
|
|
||||||
tmp1byte = rtl92e_readb(dev, GPI);
|
tmp1byte = rtl92e_readb(dev, GPI);
|
||||||
|
|
||||||
rf_power_state_to_set = (tmp1byte & BIT1) ? rf_on : rf_off;
|
rf_power_state_to_set = (tmp1byte & BIT(1)) ? rf_on : rf_off;
|
||||||
|
|
||||||
if (priv->hw_radio_off && (rf_power_state_to_set == rf_on)) {
|
if (priv->hw_radio_off && (rf_power_state_to_set == rf_on)) {
|
||||||
netdev_info(dev, "gpiochangeRF - HW Radio ON\n");
|
netdev_info(dev, "gpiochangeRF - HW Radio ON\n");
|
||||||
@ -1989,7 +1711,6 @@ static void _rtl92e_dm_check_fsync(struct net_device *dev)
|
|||||||
#define RegC38_Fsync_AP_BCM 2
|
#define RegC38_Fsync_AP_BCM 2
|
||||||
struct r8192_priv *priv = rtllib_priv(dev);
|
struct r8192_priv *priv = rtllib_priv(dev);
|
||||||
static u8 reg_c38_State = RegC38_Default;
|
static u8 reg_c38_State = RegC38_Default;
|
||||||
static u32 reset_cnt;
|
|
||||||
|
|
||||||
if (priv->rtllib->link_state == MAC80211_LINKED &&
|
if (priv->rtllib->link_state == MAC80211_LINKED &&
|
||||||
priv->rtllib->ht_info->IOTPeer == HT_IOT_PEER_BROADCOM) {
|
priv->rtllib->ht_info->IOTPeer == HT_IOT_PEER_BROADCOM) {
|
||||||
@ -2073,12 +1794,6 @@ static void _rtl92e_dm_check_fsync(struct net_device *dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (priv->reset_count != reset_cnt) {
|
|
||||||
rtl92e_writeb(dev, rOFDM0_RxDetector3,
|
|
||||||
priv->framesync);
|
|
||||||
reg_c38_State = RegC38_Default;
|
|
||||||
reset_cnt = priv->reset_count;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------Define function prototype------------------------*/
|
/*---------------------------Define function prototype------------------------*/
|
||||||
|
@ -50,18 +50,12 @@
|
|||||||
|
|
||||||
/*------------------------------Define structure----------------------------*/
|
/*------------------------------Define structure----------------------------*/
|
||||||
struct dig_t {
|
struct dig_t {
|
||||||
u8 dig_enable_flag;
|
|
||||||
u8 dig_algorithm;
|
|
||||||
u8 dig_algorithm_switch;
|
|
||||||
|
|
||||||
long rssi_low_thresh;
|
long rssi_low_thresh;
|
||||||
long rssi_high_thresh;
|
long rssi_high_thresh;
|
||||||
|
|
||||||
long rssi_high_power_lowthresh;
|
long rssi_high_power_lowthresh;
|
||||||
long rssi_high_power_highthresh;
|
long rssi_high_power_highthresh;
|
||||||
|
|
||||||
u8 dig_state;
|
|
||||||
u8 dig_highpwr_state;
|
|
||||||
u8 cur_sta_connect_state;
|
u8 cur_sta_connect_state;
|
||||||
u8 pre_sta_connect_state;
|
u8 pre_sta_connect_state;
|
||||||
|
|
||||||
@ -80,12 +74,6 @@ struct dig_t {
|
|||||||
long rssi_val;
|
long rssi_val;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum dm_dig_sta {
|
|
||||||
DM_STA_DIG_OFF = 0,
|
|
||||||
DM_STA_DIG_ON,
|
|
||||||
DM_STA_DIG_MAX
|
|
||||||
};
|
|
||||||
|
|
||||||
enum dm_ratr_sta {
|
enum dm_ratr_sta {
|
||||||
DM_RATR_STA_HIGH = 0,
|
DM_RATR_STA_HIGH = 0,
|
||||||
DM_RATR_STA_MIDDLE = 1,
|
DM_RATR_STA_MIDDLE = 1,
|
||||||
@ -93,22 +81,9 @@ enum dm_ratr_sta {
|
|||||||
DM_RATR_STA_MAX
|
DM_RATR_STA_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
enum dm_dig_alg {
|
|
||||||
DIG_ALGO_BY_FALSE_ALARM = 0,
|
|
||||||
DIG_ALGO_BY_RSSI = 1,
|
|
||||||
DIG_ALGO_BEFORE_CONNECT_BY_RSSI_AND_ALARM = 2,
|
|
||||||
DIG_ALGO_BY_TOW_PORT = 3,
|
|
||||||
DIG_ALGO_MAX
|
|
||||||
};
|
|
||||||
|
|
||||||
enum dm_dig_connect {
|
enum dm_dig_connect {
|
||||||
DIG_STA_DISCONNECT = 0,
|
DIG_STA_DISCONNECT = 0,
|
||||||
DIG_STA_CONNECT = 1,
|
DIG_STA_CONNECT = 1,
|
||||||
DIG_STA_BEFORE_CONNECT = 2,
|
|
||||||
DIG_AP_DISCONNECT = 3,
|
|
||||||
DIG_AP_CONNECT = 4,
|
|
||||||
DIG_AP_ADD_STATION = 5,
|
|
||||||
DIG_CONNECT_MAX
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum dm_dig_pd_th {
|
enum dm_dig_pd_th {
|
||||||
@ -178,8 +153,6 @@ void rtl92e_dm_txpower_tracking_wq(void *data);
|
|||||||
|
|
||||||
void rtl92e_dm_cck_txpower_adjust(struct net_device *dev, bool binch14);
|
void rtl92e_dm_cck_txpower_adjust(struct net_device *dev, bool binch14);
|
||||||
|
|
||||||
void rtl92e_dm_restore_state(struct net_device *dev);
|
|
||||||
void rtl92e_dm_backup_state(struct net_device *dev);
|
|
||||||
void rtl92e_dm_init_edca_turbo(struct net_device *dev);
|
void rtl92e_dm_init_edca_turbo(struct net_device *dev);
|
||||||
void rtl92e_dm_rf_pathcheck_wq(void *data);
|
void rtl92e_dm_rf_pathcheck_wq(void *data);
|
||||||
void rtl92e_dm_init_txpower_tracking(struct net_device *dev);
|
void rtl92e_dm_init_txpower_tracking(struct net_device *dev);
|
||||||
|
@ -21,7 +21,7 @@ static void _rtl92e_parse_pci_configuration(struct pci_dev *pdev,
|
|||||||
pcie_capability_read_word(priv->pdev, PCI_EXP_LNKCTL, &link_ctrl_reg);
|
pcie_capability_read_word(priv->pdev, PCI_EXP_LNKCTL, &link_ctrl_reg);
|
||||||
|
|
||||||
pci_read_config_byte(pdev, 0x98, &tmp);
|
pci_read_config_byte(pdev, 0x98, &tmp);
|
||||||
tmp |= BIT4;
|
tmp |= BIT(4);
|
||||||
pci_write_config_byte(pdev, 0x98, tmp);
|
pci_write_config_byte(pdev, 0x98, tmp);
|
||||||
|
|
||||||
tmp = 0x17;
|
tmp = 0x17;
|
||||||
|
@ -181,11 +181,7 @@ static bool _rtl92e_ps_set_mode(struct net_device *dev, u8 rtPsMode)
|
|||||||
{
|
{
|
||||||
struct r8192_priv *priv = rtllib_priv(dev);
|
struct r8192_priv *priv = rtllib_priv(dev);
|
||||||
|
|
||||||
if (priv->rtllib->iw_mode == IW_MODE_ADHOC)
|
priv->rtllib->ps = rtPsMode;
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!priv->ps_force)
|
|
||||||
priv->rtllib->ps = rtPsMode;
|
|
||||||
if (priv->rtllib->sta_sleep != LPS_IS_WAKE &&
|
if (priv->rtllib->sta_sleep != LPS_IS_WAKE &&
|
||||||
rtPsMode == RTLLIB_PS_DISABLED) {
|
rtPsMode == RTLLIB_PS_DISABLED) {
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
@ -208,8 +204,7 @@ void rtl92e_leisure_ps_enter(struct net_device *dev)
|
|||||||
&priv->rtllib->pwr_save_ctrl;
|
&priv->rtllib->pwr_save_ctrl;
|
||||||
|
|
||||||
if (!((priv->rtllib->iw_mode == IW_MODE_INFRA) &&
|
if (!((priv->rtllib->iw_mode == IW_MODE_INFRA) &&
|
||||||
(priv->rtllib->link_state == MAC80211_LINKED))
|
(priv->rtllib->link_state == MAC80211_LINKED)))
|
||||||
|| (priv->rtllib->iw_mode == IW_MODE_ADHOC))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (psc->bLeisurePs) {
|
if (psc->bLeisurePs) {
|
||||||
|
@ -122,126 +122,11 @@ static int _rtl92e_wx_get_power(struct net_device *dev,
|
|||||||
return rtllib_wx_get_power(priv->rtllib, info, wrqu, extra);
|
return rtllib_wx_get_power(priv->rtllib, info, wrqu, extra);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _rtl92e_wx_set_rawtx(struct net_device *dev,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *extra)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = rtllib_priv(dev);
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (priv->hw_radio_off)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
mutex_lock(&priv->wx_mutex);
|
|
||||||
|
|
||||||
ret = rtllib_wx_set_rawtx(priv->rtllib, info, wrqu, extra);
|
|
||||||
|
|
||||||
mutex_unlock(&priv->wx_mutex);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _rtl92e_wx_force_reset(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);
|
|
||||||
|
|
||||||
priv->force_reset = *extra;
|
|
||||||
mutex_unlock(&priv->wx_mutex);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _rtl92e_wx_adapter_power_status(struct net_device *dev,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *extra)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = rtllib_priv(dev);
|
|
||||||
struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *)
|
|
||||||
(&priv->rtllib->pwr_save_ctrl);
|
|
||||||
struct rtllib_device *ieee = priv->rtllib;
|
|
||||||
|
|
||||||
mutex_lock(&priv->wx_mutex);
|
|
||||||
|
|
||||||
if (*extra || priv->force_lps) {
|
|
||||||
priv->ps_force = false;
|
|
||||||
psc->bLeisurePs = true;
|
|
||||||
} else {
|
|
||||||
if (priv->rtllib->link_state == MAC80211_LINKED)
|
|
||||||
rtl92e_leisure_ps_leave(dev);
|
|
||||||
|
|
||||||
priv->ps_force = true;
|
|
||||||
psc->bLeisurePs = false;
|
|
||||||
ieee->ps = *extra;
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_unlock(&priv->wx_mutex);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _rtl92e_wx_set_lps_awake_interval(struct net_device *dev,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu,
|
|
||||||
char *extra)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = rtllib_priv(dev);
|
|
||||||
struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *)
|
|
||||||
(&priv->rtllib->pwr_save_ctrl);
|
|
||||||
|
|
||||||
mutex_lock(&priv->wx_mutex);
|
|
||||||
|
|
||||||
netdev_info(dev, "%s(): set lps awake interval ! extra is %d\n",
|
|
||||||
__func__, *extra);
|
|
||||||
|
|
||||||
psc->reg_max_lps_awake_intvl = *extra;
|
|
||||||
mutex_unlock(&priv->wx_mutex);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _rtl92e_wx_set_force_lps(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);
|
|
||||||
|
|
||||||
netdev_info(dev,
|
|
||||||
"%s(): force LPS ! extra is %d (1 is open 0 is close)\n",
|
|
||||||
__func__, *extra);
|
|
||||||
priv->force_lps = *extra;
|
|
||||||
mutex_unlock(&priv->wx_mutex);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _rtl92e_wx_set_debug(struct net_device *dev,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *extra)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = rtllib_priv(dev);
|
|
||||||
u8 c = *extra;
|
|
||||||
|
|
||||||
if (priv->hw_radio_off)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
netdev_info(dev, "=====>%s(), *extra:%x, debugflag:%x\n", __func__,
|
|
||||||
*extra, rt_global_debug_component);
|
|
||||||
if (c > 0)
|
|
||||||
rt_global_debug_component |= (1 << c);
|
|
||||||
else
|
|
||||||
rt_global_debug_component &= BIT31;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _rtl92e_wx_set_mode(struct net_device *dev,
|
static int _rtl92e_wx_set_mode(struct net_device *dev,
|
||||||
struct iw_request_info *a,
|
struct iw_request_info *a,
|
||||||
union iwreq_data *wrqu, char *b)
|
union iwreq_data *wrqu, char *b)
|
||||||
{
|
{
|
||||||
struct r8192_priv *priv = rtllib_priv(dev);
|
struct r8192_priv *priv = rtllib_priv(dev);
|
||||||
struct rtllib_device *ieee = netdev_priv_rsl(dev);
|
|
||||||
|
|
||||||
enum rt_rf_power_state rt_state;
|
enum rt_rf_power_state rt_state;
|
||||||
int ret;
|
int ret;
|
||||||
@ -250,8 +135,7 @@ static int _rtl92e_wx_set_mode(struct net_device *dev,
|
|||||||
return 0;
|
return 0;
|
||||||
rt_state = priv->rtllib->rf_power_state;
|
rt_state = priv->rtllib->rf_power_state;
|
||||||
mutex_lock(&priv->wx_mutex);
|
mutex_lock(&priv->wx_mutex);
|
||||||
if (wrqu->mode == IW_MODE_ADHOC || wrqu->mode == IW_MODE_MONITOR ||
|
if (wrqu->mode == IW_MODE_MONITOR) {
|
||||||
ieee->net_promiscuous_md) {
|
|
||||||
if (rt_state == rf_off) {
|
if (rt_state == rf_off) {
|
||||||
if (priv->rtllib->rf_off_reason >
|
if (priv->rtllib->rf_off_reason >
|
||||||
RF_CHANGE_BY_IPS) {
|
RF_CHANGE_BY_IPS) {
|
||||||
@ -724,22 +608,6 @@ end_hw_sec:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _rtl92e_wx_set_scan_type(struct net_device *dev,
|
|
||||||
struct iw_request_info *aa,
|
|
||||||
union iwreq_data *wrqu, char *p)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = rtllib_priv(dev);
|
|
||||||
int *parms = (int *)p;
|
|
||||||
int mode = parms[0];
|
|
||||||
|
|
||||||
if (priv->hw_radio_off)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
priv->rtllib->active_scan = mode;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define R8192_MAX_RETRY 255
|
#define R8192_MAX_RETRY 255
|
||||||
static int _rtl92e_wx_set_retry(struct net_device *dev,
|
static int _rtl92e_wx_set_retry(struct net_device *dev,
|
||||||
struct iw_request_info *info,
|
struct iw_request_info *info,
|
||||||
@ -844,8 +712,7 @@ static int _rtl92e_wx_set_encode_ext(struct net_device *dev,
|
|||||||
idx--;
|
idx--;
|
||||||
group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY;
|
group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY;
|
||||||
|
|
||||||
if ((!group) || (ieee->iw_mode == IW_MODE_ADHOC) ||
|
if ((!group) || (alg == KEY_TYPE_WEP40)) {
|
||||||
(alg == KEY_TYPE_WEP40)) {
|
|
||||||
if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40))
|
if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40))
|
||||||
alg = KEY_TYPE_WEP104;
|
alg = KEY_TYPE_WEP104;
|
||||||
ieee->pairwise_key_type = alg;
|
ieee->pairwise_key_type = alg;
|
||||||
@ -865,7 +732,7 @@ static int _rtl92e_wx_set_encode_ext(struct net_device *dev,
|
|||||||
rtl92e_set_swcam(dev, idx, idx, alg, broadcast_addr, key);
|
rtl92e_set_swcam(dev, idx, idx, alg, broadcast_addr, key);
|
||||||
} else {
|
} else {
|
||||||
if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) &&
|
if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) &&
|
||||||
ieee->ht_info->bCurrentHTSupport)
|
ieee->ht_info->current_ht_support)
|
||||||
rtl92e_writeb(dev, 0x173, 1);
|
rtl92e_writeb(dev, 0x173, 1);
|
||||||
rtl92e_set_key(dev, 4, idx, alg,
|
rtl92e_set_key(dev, 4, idx, alg,
|
||||||
(u8 *)ieee->ap_mac_addr, 0, key);
|
(u8 *)ieee->ap_mac_addr, 0, key);
|
||||||
@ -938,7 +805,7 @@ static int _rtl92e_wx_get_gen_ie(struct net_device *dev,
|
|||||||
struct r8192_priv *priv = rtllib_priv(dev);
|
struct r8192_priv *priv = rtllib_priv(dev);
|
||||||
struct rtllib_device *ieee = priv->rtllib;
|
struct rtllib_device *ieee = priv->rtllib;
|
||||||
|
|
||||||
if (ieee->wpa_ie_len == 0 || ieee->wpa_ie == NULL) {
|
if (ieee->wpa_ie_len == 0 || !ieee->wpa_ie) {
|
||||||
data->data.length = 0;
|
data->data.length = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -951,67 +818,6 @@ static int _rtl92e_wx_get_gen_ie(struct net_device *dev,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define OID_RT_INTEL_PROMISCUOUS_MODE 0xFF0101F6
|
|
||||||
|
|
||||||
static int _rtl92e_wx_set_promisc_mode(struct net_device *dev,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *extra)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = rtllib_priv(dev);
|
|
||||||
struct rtllib_device *ieee = priv->rtllib;
|
|
||||||
|
|
||||||
u32 info_buf[3];
|
|
||||||
|
|
||||||
u32 oid;
|
|
||||||
u32 promiscuous_on;
|
|
||||||
u32 fltr_src_sta_frame;
|
|
||||||
|
|
||||||
if (copy_from_user(info_buf, wrqu->data.pointer, sizeof(info_buf)))
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
oid = info_buf[0];
|
|
||||||
promiscuous_on = info_buf[1];
|
|
||||||
fltr_src_sta_frame = info_buf[2];
|
|
||||||
|
|
||||||
if (oid == OID_RT_INTEL_PROMISCUOUS_MODE) {
|
|
||||||
ieee->intel_promiscuous_md_info.promiscuous_on =
|
|
||||||
(promiscuous_on) ? (true) : (false);
|
|
||||||
ieee->intel_promiscuous_md_info.fltr_src_sta_frame =
|
|
||||||
(fltr_src_sta_frame) ? (true) : (false);
|
|
||||||
(promiscuous_on) ?
|
|
||||||
(rtllib_EnableIntelPromiscuousMode(dev, false)) :
|
|
||||||
(rtllib_DisableIntelPromiscuousMode(dev, false));
|
|
||||||
|
|
||||||
netdev_info(dev,
|
|
||||||
"=======>%s(), on = %d, filter src sta = %d\n",
|
|
||||||
__func__, promiscuous_on,
|
|
||||||
fltr_src_sta_frame);
|
|
||||||
} else {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _rtl92e_wx_get_promisc_mode(struct net_device *dev,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *extra)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = rtllib_priv(dev);
|
|
||||||
struct rtllib_device *ieee = priv->rtllib;
|
|
||||||
|
|
||||||
mutex_lock(&priv->wx_mutex);
|
|
||||||
|
|
||||||
snprintf(extra, 45, "PromiscuousMode:%d, FilterSrcSTAFrame:%d",
|
|
||||||
ieee->intel_promiscuous_md_info.promiscuous_on,
|
|
||||||
ieee->intel_promiscuous_md_info.fltr_src_sta_frame);
|
|
||||||
wrqu->data.length = strlen(extra) + 1;
|
|
||||||
|
|
||||||
mutex_unlock(&priv->wx_mutex);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define IW_IOCTL(x) ((x) - SIOCSIWCOMMIT)
|
#define IW_IOCTL(x) ((x) - SIOCSIWCOMMIT)
|
||||||
static iw_handler r8192_wx_handlers[] = {
|
static iw_handler r8192_wx_handlers[] = {
|
||||||
[IW_IOCTL(SIOCGIWNAME)] = _rtl92e_wx_get_name,
|
[IW_IOCTL(SIOCGIWNAME)] = _rtl92e_wx_get_name,
|
||||||
@ -1047,72 +853,6 @@ static iw_handler r8192_wx_handlers[] = {
|
|||||||
[IW_IOCTL(SIOCSIWENCODEEXT)] = _rtl92e_wx_set_encode_ext,
|
[IW_IOCTL(SIOCSIWENCODEEXT)] = _rtl92e_wx_set_encode_ext,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* the following rule need to be following,
|
|
||||||
* Odd : get (world access),
|
|
||||||
* even : set (root access)
|
|
||||||
*/
|
|
||||||
static const struct iw_priv_args r8192_private_args[] = {
|
|
||||||
{
|
|
||||||
SIOCIWFIRSTPRIV + 0x0,
|
|
||||||
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_debugflag"
|
|
||||||
}, {
|
|
||||||
SIOCIWFIRSTPRIV + 0x1,
|
|
||||||
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
|
|
||||||
}, {
|
|
||||||
SIOCIWFIRSTPRIV + 0x2,
|
|
||||||
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
|
|
||||||
}, {
|
|
||||||
SIOCIWFIRSTPRIV + 0x3,
|
|
||||||
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
|
|
||||||
}, {
|
|
||||||
SIOCIWFIRSTPRIV + 0x6,
|
|
||||||
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_NONE,
|
|
||||||
"set_power"
|
|
||||||
}, {
|
|
||||||
SIOCIWFIRSTPRIV + 0xa,
|
|
||||||
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_NONE,
|
|
||||||
"lps_interv"
|
|
||||||
}, {
|
|
||||||
SIOCIWFIRSTPRIV + 0xb,
|
|
||||||
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_NONE,
|
|
||||||
"lps_force"
|
|
||||||
}, {
|
|
||||||
SIOCIWFIRSTPRIV + 0x16,
|
|
||||||
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "setpromisc"
|
|
||||||
}, {
|
|
||||||
SIOCIWFIRSTPRIV + 0x17,
|
|
||||||
0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 45, "getpromisc"
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
static iw_handler r8192_private_handler[] = {
|
|
||||||
(iw_handler)_rtl92e_wx_set_debug, /*SIOCIWSECONDPRIV*/
|
|
||||||
(iw_handler)_rtl92e_wx_set_scan_type,
|
|
||||||
(iw_handler)_rtl92e_wx_set_rawtx,
|
|
||||||
(iw_handler)_rtl92e_wx_force_reset,
|
|
||||||
(iw_handler)NULL,
|
|
||||||
(iw_handler)NULL,
|
|
||||||
(iw_handler)_rtl92e_wx_adapter_power_status,
|
|
||||||
(iw_handler)NULL,
|
|
||||||
(iw_handler)NULL,
|
|
||||||
(iw_handler)NULL,
|
|
||||||
(iw_handler)_rtl92e_wx_set_lps_awake_interval,
|
|
||||||
(iw_handler)_rtl92e_wx_set_force_lps,
|
|
||||||
(iw_handler)NULL,
|
|
||||||
(iw_handler)NULL,
|
|
||||||
(iw_handler)NULL,
|
|
||||||
(iw_handler)NULL,
|
|
||||||
(iw_handler)NULL,
|
|
||||||
(iw_handler)NULL,
|
|
||||||
(iw_handler)NULL,
|
|
||||||
(iw_handler)NULL,
|
|
||||||
(iw_handler)NULL,
|
|
||||||
(iw_handler)NULL,
|
|
||||||
(iw_handler)_rtl92e_wx_set_promisc_mode,
|
|
||||||
(iw_handler)_rtl92e_wx_get_promisc_mode,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct iw_statistics *_rtl92e_get_wireless_stats(struct net_device *dev)
|
static struct iw_statistics *_rtl92e_get_wireless_stats(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct r8192_priv *priv = rtllib_priv(dev);
|
struct r8192_priv *priv = rtllib_priv(dev);
|
||||||
@ -1144,10 +884,5 @@ static struct iw_statistics *_rtl92e_get_wireless_stats(struct net_device *dev)
|
|||||||
const struct iw_handler_def r8192_wx_handlers_def = {
|
const struct iw_handler_def r8192_wx_handlers_def = {
|
||||||
.standard = r8192_wx_handlers,
|
.standard = r8192_wx_handlers,
|
||||||
.num_standard = ARRAY_SIZE(r8192_wx_handlers),
|
.num_standard = ARRAY_SIZE(r8192_wx_handlers),
|
||||||
.private = r8192_private_handler,
|
|
||||||
.num_private = ARRAY_SIZE(r8192_private_handler),
|
|
||||||
.num_private_args = sizeof(r8192_private_args) /
|
|
||||||
sizeof(struct iw_priv_args),
|
|
||||||
.get_wireless_stats = _rtl92e_get_wireless_stats,
|
.get_wireless_stats = _rtl92e_get_wireless_stats,
|
||||||
.private_args = (struct iw_priv_args *)r8192_private_args,
|
|
||||||
};
|
};
|
||||||
|
@ -10,109 +10,109 @@
|
|||||||
#include "rtllib.h"
|
#include "rtllib.h"
|
||||||
#include "rtl819x_BA.h"
|
#include "rtl819x_BA.h"
|
||||||
|
|
||||||
static void activate_ba_entry(struct ba_record *pBA, u16 Time)
|
static void activate_ba_entry(struct ba_record *ba, u16 time)
|
||||||
{
|
{
|
||||||
pBA->b_valid = true;
|
ba->b_valid = true;
|
||||||
if (Time != 0)
|
if (time != 0)
|
||||||
mod_timer(&pBA->timer, jiffies + msecs_to_jiffies(Time));
|
mod_timer(&ba->timer, jiffies + msecs_to_jiffies(time));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void deactivate_ba_entry(struct rtllib_device *ieee, struct ba_record *pBA)
|
static void deactivate_ba_entry(struct rtllib_device *ieee, struct ba_record *ba)
|
||||||
{
|
{
|
||||||
pBA->b_valid = false;
|
ba->b_valid = false;
|
||||||
del_timer_sync(&pBA->timer);
|
del_timer_sync(&ba->timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u8 tx_ts_delete_ba(struct rtllib_device *ieee, struct tx_ts_record *pTxTs)
|
static u8 tx_ts_delete_ba(struct rtllib_device *ieee, struct tx_ts_record *pTxTs)
|
||||||
{
|
{
|
||||||
struct ba_record *pAdmittedBa = &pTxTs->TxAdmittedBARecord;
|
struct ba_record *admitted_ba = &pTxTs->TxAdmittedBARecord;
|
||||||
struct ba_record *pPendingBa = &pTxTs->TxPendingBARecord;
|
struct ba_record *pending_ba = &pTxTs->TxPendingBARecord;
|
||||||
u8 bSendDELBA = false;
|
u8 bSendDELBA = false;
|
||||||
|
|
||||||
if (pPendingBa->b_valid) {
|
if (pending_ba->b_valid) {
|
||||||
deactivate_ba_entry(ieee, pPendingBa);
|
deactivate_ba_entry(ieee, pending_ba);
|
||||||
bSendDELBA = true;
|
bSendDELBA = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pAdmittedBa->b_valid) {
|
if (admitted_ba->b_valid) {
|
||||||
deactivate_ba_entry(ieee, pAdmittedBa);
|
deactivate_ba_entry(ieee, admitted_ba);
|
||||||
bSendDELBA = true;
|
bSendDELBA = true;
|
||||||
}
|
}
|
||||||
return bSendDELBA;
|
return bSendDELBA;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u8 rx_ts_delete_ba(struct rtllib_device *ieee, struct rx_ts_record *pRxTs)
|
static u8 rx_ts_delete_ba(struct rtllib_device *ieee, struct rx_ts_record *ts)
|
||||||
{
|
{
|
||||||
struct ba_record *pBa = &pRxTs->rx_admitted_ba_record;
|
struct ba_record *ba = &ts->rx_admitted_ba_record;
|
||||||
u8 bSendDELBA = false;
|
u8 bSendDELBA = false;
|
||||||
|
|
||||||
if (pBa->b_valid) {
|
if (ba->b_valid) {
|
||||||
deactivate_ba_entry(ieee, pBa);
|
deactivate_ba_entry(ieee, ba);
|
||||||
bSendDELBA = true;
|
bSendDELBA = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return bSendDELBA;
|
return bSendDELBA;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtllib_reset_ba_entry(struct ba_record *pBA)
|
void rtllib_reset_ba_entry(struct ba_record *ba)
|
||||||
{
|
{
|
||||||
pBA->b_valid = false;
|
ba->b_valid = false;
|
||||||
pBA->ba_param_set.short_data = 0;
|
ba->ba_param_set.short_data = 0;
|
||||||
pBA->ba_timeout_value = 0;
|
ba->ba_timeout_value = 0;
|
||||||
pBA->dialog_token = 0;
|
ba->dialog_token = 0;
|
||||||
pBA->ba_start_seq_ctrl.short_data = 0;
|
ba->ba_start_seq_ctrl.short_data = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct sk_buff *rtllib_ADDBA(struct rtllib_device *ieee, u8 *Dst,
|
static struct sk_buff *rtllib_ADDBA(struct rtllib_device *ieee, u8 *dst,
|
||||||
struct ba_record *pBA,
|
struct ba_record *ba,
|
||||||
u16 StatusCode, u8 type)
|
u16 status_code, u8 type)
|
||||||
{
|
{
|
||||||
struct sk_buff *skb = NULL;
|
struct sk_buff *skb = NULL;
|
||||||
struct rtllib_hdr_3addr *BAReq = NULL;
|
struct ieee80211_hdr_3addr *BAReq = NULL;
|
||||||
u8 *tag = NULL;
|
u8 *tag = NULL;
|
||||||
u16 len = ieee->tx_headroom + 9;
|
u16 len = ieee->tx_headroom + 9;
|
||||||
|
|
||||||
netdev_dbg(ieee->dev, "%s(): frame(%d) sentd to: %pM, ieee->dev:%p\n",
|
netdev_dbg(ieee->dev, "%s(): frame(%d) sentd to: %pM, ieee->dev:%p\n",
|
||||||
__func__, type, Dst, ieee->dev);
|
__func__, type, dst, ieee->dev);
|
||||||
|
|
||||||
if (!pBA) {
|
if (!ba) {
|
||||||
netdev_warn(ieee->dev, "pBA is NULL\n");
|
netdev_warn(ieee->dev, "ba is NULL\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
skb = dev_alloc_skb(len + sizeof(struct rtllib_hdr_3addr));
|
skb = dev_alloc_skb(len + sizeof(struct ieee80211_hdr_3addr));
|
||||||
if (!skb)
|
if (!skb)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
memset(skb->data, 0, sizeof(struct rtllib_hdr_3addr));
|
memset(skb->data, 0, sizeof(struct ieee80211_hdr_3addr));
|
||||||
|
|
||||||
skb_reserve(skb, ieee->tx_headroom);
|
skb_reserve(skb, ieee->tx_headroom);
|
||||||
|
|
||||||
BAReq = skb_put(skb, sizeof(struct rtllib_hdr_3addr));
|
BAReq = skb_put(skb, sizeof(struct ieee80211_hdr_3addr));
|
||||||
|
|
||||||
ether_addr_copy(BAReq->addr1, Dst);
|
ether_addr_copy(BAReq->addr1, dst);
|
||||||
ether_addr_copy(BAReq->addr2, ieee->dev->dev_addr);
|
ether_addr_copy(BAReq->addr2, ieee->dev->dev_addr);
|
||||||
|
|
||||||
ether_addr_copy(BAReq->addr3, ieee->current_network.bssid);
|
ether_addr_copy(BAReq->addr3, ieee->current_network.bssid);
|
||||||
BAReq->frame_ctl = cpu_to_le16(RTLLIB_STYPE_MANAGE_ACT);
|
BAReq->frame_control = cpu_to_le16(IEEE80211_STYPE_ACTION);
|
||||||
|
|
||||||
tag = skb_put(skb, 9);
|
tag = skb_put(skb, 9);
|
||||||
*tag++ = ACT_CAT_BA;
|
*tag++ = ACT_CAT_BA;
|
||||||
*tag++ = type;
|
*tag++ = type;
|
||||||
*tag++ = pBA->dialog_token;
|
*tag++ = ba->dialog_token;
|
||||||
|
|
||||||
if (type == ACT_ADDBARSP) {
|
if (type == ACT_ADDBARSP) {
|
||||||
put_unaligned_le16(StatusCode, tag);
|
put_unaligned_le16(status_code, tag);
|
||||||
tag += 2;
|
tag += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
put_unaligned_le16(pBA->ba_param_set.short_data, tag);
|
put_unaligned_le16(ba->ba_param_set.short_data, tag);
|
||||||
tag += 2;
|
tag += 2;
|
||||||
|
|
||||||
put_unaligned_le16(pBA->ba_timeout_value, tag);
|
put_unaligned_le16(ba->ba_timeout_value, tag);
|
||||||
tag += 2;
|
tag += 2;
|
||||||
|
|
||||||
if (type == ACT_ADDBAREQ) {
|
if (type == ACT_ADDBAREQ) {
|
||||||
memcpy(tag, (u8 *)&pBA->ba_start_seq_ctrl, 2);
|
memcpy(tag, (u8 *)&ba->ba_start_seq_ctrl, 2);
|
||||||
tag += 2;
|
tag += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,36 +124,36 @@ static struct sk_buff *rtllib_ADDBA(struct rtllib_device *ieee, u8 *Dst,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct sk_buff *rtllib_DELBA(struct rtllib_device *ieee, u8 *dst,
|
static struct sk_buff *rtllib_DELBA(struct rtllib_device *ieee, u8 *dst,
|
||||||
struct ba_record *pBA,
|
struct ba_record *ba,
|
||||||
enum tr_select TxRxSelect, u16 ReasonCode)
|
enum tr_select TxRxSelect, u16 reason_code)
|
||||||
{
|
{
|
||||||
union delba_param_set DelbaParamSet;
|
union delba_param_set DelbaParamSet;
|
||||||
struct sk_buff *skb = NULL;
|
struct sk_buff *skb = NULL;
|
||||||
struct rtllib_hdr_3addr *Delba = NULL;
|
struct ieee80211_hdr_3addr *Delba = NULL;
|
||||||
u8 *tag = NULL;
|
u8 *tag = NULL;
|
||||||
u16 len = 6 + ieee->tx_headroom;
|
u16 len = 6 + ieee->tx_headroom;
|
||||||
|
|
||||||
if (net_ratelimit())
|
if (net_ratelimit())
|
||||||
netdev_dbg(ieee->dev, "%s(): ReasonCode(%d) sentd to: %pM\n",
|
netdev_dbg(ieee->dev, "%s(): reason_code(%d) sentd to: %pM\n",
|
||||||
__func__, ReasonCode, dst);
|
__func__, reason_code, dst);
|
||||||
|
|
||||||
memset(&DelbaParamSet, 0, 2);
|
memset(&DelbaParamSet, 0, 2);
|
||||||
|
|
||||||
DelbaParamSet.field.initiator = (TxRxSelect == TX_DIR) ? 1 : 0;
|
DelbaParamSet.field.initiator = (TxRxSelect == TX_DIR) ? 1 : 0;
|
||||||
DelbaParamSet.field.tid = pBA->ba_param_set.field.tid;
|
DelbaParamSet.field.tid = ba->ba_param_set.field.tid;
|
||||||
|
|
||||||
skb = dev_alloc_skb(len + sizeof(struct rtllib_hdr_3addr));
|
skb = dev_alloc_skb(len + sizeof(struct ieee80211_hdr_3addr));
|
||||||
if (!skb)
|
if (!skb)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
skb_reserve(skb, ieee->tx_headroom);
|
skb_reserve(skb, ieee->tx_headroom);
|
||||||
|
|
||||||
Delba = skb_put(skb, sizeof(struct rtllib_hdr_3addr));
|
Delba = skb_put(skb, sizeof(struct ieee80211_hdr_3addr));
|
||||||
|
|
||||||
ether_addr_copy(Delba->addr1, dst);
|
ether_addr_copy(Delba->addr1, dst);
|
||||||
ether_addr_copy(Delba->addr2, ieee->dev->dev_addr);
|
ether_addr_copy(Delba->addr2, ieee->dev->dev_addr);
|
||||||
ether_addr_copy(Delba->addr3, ieee->current_network.bssid);
|
ether_addr_copy(Delba->addr3, ieee->current_network.bssid);
|
||||||
Delba->frame_ctl = cpu_to_le16(RTLLIB_STYPE_MANAGE_ACT);
|
Delba->frame_control = cpu_to_le16(IEEE80211_STYPE_ACTION);
|
||||||
|
|
||||||
tag = skb_put(skb, 6);
|
tag = skb_put(skb, 6);
|
||||||
|
|
||||||
@ -163,7 +163,7 @@ static struct sk_buff *rtllib_DELBA(struct rtllib_device *ieee, u8 *dst,
|
|||||||
put_unaligned_le16(DelbaParamSet.short_data, tag);
|
put_unaligned_le16(DelbaParamSet.short_data, tag);
|
||||||
tag += 2;
|
tag += 2;
|
||||||
|
|
||||||
put_unaligned_le16(ReasonCode, tag);
|
put_unaligned_le16(reason_code, tag);
|
||||||
tag += 2;
|
tag += 2;
|
||||||
|
|
||||||
#ifdef VERBOSE_DEBUG
|
#ifdef VERBOSE_DEBUG
|
||||||
@ -174,11 +174,11 @@ static struct sk_buff *rtllib_DELBA(struct rtllib_device *ieee, u8 *dst,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void rtllib_send_ADDBAReq(struct rtllib_device *ieee, u8 *dst,
|
static void rtllib_send_ADDBAReq(struct rtllib_device *ieee, u8 *dst,
|
||||||
struct ba_record *pBA)
|
struct ba_record *ba)
|
||||||
{
|
{
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
|
|
||||||
skb = rtllib_ADDBA(ieee, dst, pBA, 0, ACT_ADDBAREQ);
|
skb = rtllib_ADDBA(ieee, dst, ba, 0, ACT_ADDBAREQ);
|
||||||
|
|
||||||
if (skb)
|
if (skb)
|
||||||
softmac_mgmt_xmit(skb, ieee);
|
softmac_mgmt_xmit(skb, ieee);
|
||||||
@ -187,11 +187,11 @@ static void rtllib_send_ADDBAReq(struct rtllib_device *ieee, u8 *dst,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void rtllib_send_ADDBARsp(struct rtllib_device *ieee, u8 *dst,
|
static void rtllib_send_ADDBARsp(struct rtllib_device *ieee, u8 *dst,
|
||||||
struct ba_record *pBA, u16 StatusCode)
|
struct ba_record *ba, u16 status_code)
|
||||||
{
|
{
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
|
|
||||||
skb = rtllib_ADDBA(ieee, dst, pBA, StatusCode, ACT_ADDBARSP);
|
skb = rtllib_ADDBA(ieee, dst, ba, status_code, ACT_ADDBARSP);
|
||||||
if (skb)
|
if (skb)
|
||||||
softmac_mgmt_xmit(skb, ieee);
|
softmac_mgmt_xmit(skb, ieee);
|
||||||
else
|
else
|
||||||
@ -199,12 +199,12 @@ static void rtllib_send_ADDBARsp(struct rtllib_device *ieee, u8 *dst,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void rtllib_send_DELBA(struct rtllib_device *ieee, u8 *dst,
|
static void rtllib_send_DELBA(struct rtllib_device *ieee, u8 *dst,
|
||||||
struct ba_record *pBA, enum tr_select TxRxSelect,
|
struct ba_record *ba, enum tr_select TxRxSelect,
|
||||||
u16 ReasonCode)
|
u16 reason_code)
|
||||||
{
|
{
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
|
|
||||||
skb = rtllib_DELBA(ieee, dst, pBA, TxRxSelect, ReasonCode);
|
skb = rtllib_DELBA(ieee, dst, ba, TxRxSelect, reason_code);
|
||||||
if (skb)
|
if (skb)
|
||||||
softmac_mgmt_xmit(skb, ieee);
|
softmac_mgmt_xmit(skb, ieee);
|
||||||
else
|
else
|
||||||
@ -213,19 +213,19 @@ static void rtllib_send_DELBA(struct rtllib_device *ieee, u8 *dst,
|
|||||||
|
|
||||||
int rtllib_rx_ADDBAReq(struct rtllib_device *ieee, struct sk_buff *skb)
|
int rtllib_rx_ADDBAReq(struct rtllib_device *ieee, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct rtllib_hdr_3addr *req = NULL;
|
struct ieee80211_hdr_3addr *req = NULL;
|
||||||
u16 rc = 0;
|
u16 rc = 0;
|
||||||
u8 *dst = NULL, *pDialogToken = NULL, *tag = NULL;
|
u8 *dst = NULL, *pDialogToken = NULL, *tag = NULL;
|
||||||
struct ba_record *pBA = NULL;
|
struct ba_record *ba = NULL;
|
||||||
union ba_param_set *pBaParamSet = NULL;
|
union ba_param_set *pBaParamSet = NULL;
|
||||||
u16 *pBaTimeoutVal = NULL;
|
u16 *pBaTimeoutVal = NULL;
|
||||||
union sequence_control *pBaStartSeqCtrl = NULL;
|
union sequence_control *pBaStartSeqCtrl = NULL;
|
||||||
struct rx_ts_record *pTS = NULL;
|
struct rx_ts_record *ts = NULL;
|
||||||
|
|
||||||
if (skb->len < sizeof(struct rtllib_hdr_3addr) + 9) {
|
if (skb->len < sizeof(struct ieee80211_hdr_3addr) + 9) {
|
||||||
netdev_warn(ieee->dev, "Invalid skb len in BAREQ(%d / %d)\n",
|
netdev_warn(ieee->dev, "Invalid skb len in BAREQ(%d / %d)\n",
|
||||||
(int)skb->len,
|
(int)skb->len,
|
||||||
(int)(sizeof(struct rtllib_hdr_3addr) + 9));
|
(int)(sizeof(struct ieee80211_hdr_3addr) + 9));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,32 +234,32 @@ int rtllib_rx_ADDBAReq(struct rtllib_device *ieee, struct sk_buff *skb)
|
|||||||
skb->data, skb->len);
|
skb->data, skb->len);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
req = (struct rtllib_hdr_3addr *)skb->data;
|
req = (struct ieee80211_hdr_3addr *)skb->data;
|
||||||
tag = (u8 *)req;
|
tag = (u8 *)req;
|
||||||
dst = (u8 *)(&req->addr2[0]);
|
dst = (u8 *)(&req->addr2[0]);
|
||||||
tag += sizeof(struct rtllib_hdr_3addr);
|
tag += sizeof(struct ieee80211_hdr_3addr);
|
||||||
pDialogToken = tag + 2;
|
pDialogToken = tag + 2;
|
||||||
pBaParamSet = (union ba_param_set *)(tag + 3);
|
pBaParamSet = (union ba_param_set *)(tag + 3);
|
||||||
pBaTimeoutVal = (u16 *)(tag + 5);
|
pBaTimeoutVal = (u16 *)(tag + 5);
|
||||||
pBaStartSeqCtrl = (union sequence_control *)(req + 7);
|
pBaStartSeqCtrl = (union sequence_control *)(req + 7);
|
||||||
|
|
||||||
if (!ieee->current_network.qos_data.active ||
|
if (!ieee->current_network.qos_data.active ||
|
||||||
!ieee->ht_info->bCurrentHTSupport ||
|
!ieee->ht_info->current_ht_support ||
|
||||||
(ieee->ht_info->iot_action & HT_IOT_ACT_REJECT_ADDBA_REQ)) {
|
(ieee->ht_info->iot_action & HT_IOT_ACT_REJECT_ADDBA_REQ)) {
|
||||||
rc = ADDBA_STATUS_REFUSED;
|
rc = ADDBA_STATUS_REFUSED;
|
||||||
netdev_warn(ieee->dev,
|
netdev_warn(ieee->dev,
|
||||||
"Failed to reply on ADDBA_REQ as some capability is not ready(%d, %d)\n",
|
"Failed to reply on ADDBA_REQ as some capability is not ready(%d, %d)\n",
|
||||||
ieee->current_network.qos_data.active,
|
ieee->current_network.qos_data.active,
|
||||||
ieee->ht_info->bCurrentHTSupport);
|
ieee->ht_info->current_ht_support);
|
||||||
goto OnADDBAReq_Fail;
|
goto OnADDBAReq_Fail;
|
||||||
}
|
}
|
||||||
if (!GetTs(ieee, (struct ts_common_info **)&pTS, dst,
|
if (!rtllib_get_ts(ieee, (struct ts_common_info **)&ts, dst,
|
||||||
(u8)(pBaParamSet->field.tid), RX_DIR, true)) {
|
(u8)(pBaParamSet->field.tid), RX_DIR, true)) {
|
||||||
rc = ADDBA_STATUS_REFUSED;
|
rc = ADDBA_STATUS_REFUSED;
|
||||||
netdev_warn(ieee->dev, "%s(): can't get TS\n", __func__);
|
netdev_warn(ieee->dev, "%s(): can't get TS\n", __func__);
|
||||||
goto OnADDBAReq_Fail;
|
goto OnADDBAReq_Fail;
|
||||||
}
|
}
|
||||||
pBA = &pTS->rx_admitted_ba_record;
|
ba = &ts->rx_admitted_ba_record;
|
||||||
|
|
||||||
if (pBaParamSet->field.ba_policy == BA_POLICY_DELAYED) {
|
if (pBaParamSet->field.ba_policy == BA_POLICY_DELAYED) {
|
||||||
rc = ADDBA_STATUS_INVALID_PARAM;
|
rc = ADDBA_STATUS_INVALID_PARAM;
|
||||||
@ -268,22 +268,22 @@ int rtllib_rx_ADDBAReq(struct rtllib_device *ieee, struct sk_buff *skb)
|
|||||||
goto OnADDBAReq_Fail;
|
goto OnADDBAReq_Fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
rtllib_FlushRxTsPendingPkts(ieee, pTS);
|
rtllib_FlushRxTsPendingPkts(ieee, ts);
|
||||||
|
|
||||||
deactivate_ba_entry(ieee, pBA);
|
deactivate_ba_entry(ieee, ba);
|
||||||
pBA->dialog_token = *pDialogToken;
|
ba->dialog_token = *pDialogToken;
|
||||||
pBA->ba_param_set = *pBaParamSet;
|
ba->ba_param_set = *pBaParamSet;
|
||||||
pBA->ba_timeout_value = *pBaTimeoutVal;
|
ba->ba_timeout_value = *pBaTimeoutVal;
|
||||||
pBA->ba_start_seq_ctrl = *pBaStartSeqCtrl;
|
ba->ba_start_seq_ctrl = *pBaStartSeqCtrl;
|
||||||
|
|
||||||
if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev) ||
|
if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev) ||
|
||||||
(ieee->ht_info->iot_action & HT_IOT_ACT_ALLOW_PEER_AGG_ONE_PKT))
|
(ieee->ht_info->iot_action & HT_IOT_ACT_ALLOW_PEER_AGG_ONE_PKT))
|
||||||
pBA->ba_param_set.field.buffer_size = 1;
|
ba->ba_param_set.field.buffer_size = 1;
|
||||||
else
|
else
|
||||||
pBA->ba_param_set.field.buffer_size = 32;
|
ba->ba_param_set.field.buffer_size = 32;
|
||||||
|
|
||||||
activate_ba_entry(pBA, 0);
|
activate_ba_entry(ba, 0);
|
||||||
rtllib_send_ADDBARsp(ieee, dst, pBA, ADDBA_STATUS_SUCCESS);
|
rtllib_send_ADDBARsp(ieee, dst, ba, ADDBA_STATUS_SUCCESS);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -302,88 +302,88 @@ OnADDBAReq_Fail:
|
|||||||
|
|
||||||
int rtllib_rx_ADDBARsp(struct rtllib_device *ieee, struct sk_buff *skb)
|
int rtllib_rx_ADDBARsp(struct rtllib_device *ieee, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct rtllib_hdr_3addr *rsp = NULL;
|
struct ieee80211_hdr_3addr *rsp = NULL;
|
||||||
struct ba_record *pPendingBA, *pAdmittedBA;
|
struct ba_record *pending_ba, *pAdmittedBA;
|
||||||
struct tx_ts_record *pTS = NULL;
|
struct tx_ts_record *ts = NULL;
|
||||||
u8 *dst = NULL, *pDialogToken = NULL, *tag = NULL;
|
u8 *dst = NULL, *pDialogToken = NULL, *tag = NULL;
|
||||||
u16 *pStatusCode = NULL, *pBaTimeoutVal = NULL;
|
u16 *status_code = NULL, *pBaTimeoutVal = NULL;
|
||||||
union ba_param_set *pBaParamSet = NULL;
|
union ba_param_set *pBaParamSet = NULL;
|
||||||
u16 ReasonCode;
|
u16 reason_code;
|
||||||
|
|
||||||
if (skb->len < sizeof(struct rtllib_hdr_3addr) + 9) {
|
if (skb->len < sizeof(struct ieee80211_hdr_3addr) + 9) {
|
||||||
netdev_warn(ieee->dev, "Invalid skb len in BARSP(%d / %d)\n",
|
netdev_warn(ieee->dev, "Invalid skb len in BARSP(%d / %d)\n",
|
||||||
(int)skb->len,
|
(int)skb->len,
|
||||||
(int)(sizeof(struct rtllib_hdr_3addr) + 9));
|
(int)(sizeof(struct ieee80211_hdr_3addr) + 9));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
rsp = (struct rtllib_hdr_3addr *)skb->data;
|
rsp = (struct ieee80211_hdr_3addr *)skb->data;
|
||||||
tag = (u8 *)rsp;
|
tag = (u8 *)rsp;
|
||||||
dst = (u8 *)(&rsp->addr2[0]);
|
dst = (u8 *)(&rsp->addr2[0]);
|
||||||
tag += sizeof(struct rtllib_hdr_3addr);
|
tag += sizeof(struct ieee80211_hdr_3addr);
|
||||||
pDialogToken = tag + 2;
|
pDialogToken = tag + 2;
|
||||||
pStatusCode = (u16 *)(tag + 3);
|
status_code = (u16 *)(tag + 3);
|
||||||
pBaParamSet = (union ba_param_set *)(tag + 5);
|
pBaParamSet = (union ba_param_set *)(tag + 5);
|
||||||
pBaTimeoutVal = (u16 *)(tag + 7);
|
pBaTimeoutVal = (u16 *)(tag + 7);
|
||||||
|
|
||||||
if (!ieee->current_network.qos_data.active ||
|
if (!ieee->current_network.qos_data.active ||
|
||||||
!ieee->ht_info->bCurrentHTSupport ||
|
!ieee->ht_info->current_ht_support ||
|
||||||
!ieee->ht_info->bCurrentAMPDUEnable) {
|
!ieee->ht_info->bCurrentAMPDUEnable) {
|
||||||
netdev_warn(ieee->dev,
|
netdev_warn(ieee->dev,
|
||||||
"reject to ADDBA_RSP as some capability is not ready(%d, %d, %d)\n",
|
"reject to ADDBA_RSP as some capability is not ready(%d, %d, %d)\n",
|
||||||
ieee->current_network.qos_data.active,
|
ieee->current_network.qos_data.active,
|
||||||
ieee->ht_info->bCurrentHTSupport,
|
ieee->ht_info->current_ht_support,
|
||||||
ieee->ht_info->bCurrentAMPDUEnable);
|
ieee->ht_info->bCurrentAMPDUEnable);
|
||||||
ReasonCode = DELBA_REASON_UNKNOWN_BA;
|
reason_code = DELBA_REASON_UNKNOWN_BA;
|
||||||
goto OnADDBARsp_Reject;
|
goto OnADDBARsp_Reject;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GetTs(ieee, (struct ts_common_info **)&pTS, dst,
|
if (!rtllib_get_ts(ieee, (struct ts_common_info **)&ts, dst,
|
||||||
(u8)(pBaParamSet->field.tid), TX_DIR, false)) {
|
(u8)(pBaParamSet->field.tid), TX_DIR, false)) {
|
||||||
netdev_warn(ieee->dev, "%s(): can't get TS\n", __func__);
|
netdev_warn(ieee->dev, "%s(): can't get TS\n", __func__);
|
||||||
ReasonCode = DELBA_REASON_UNKNOWN_BA;
|
reason_code = DELBA_REASON_UNKNOWN_BA;
|
||||||
goto OnADDBARsp_Reject;
|
goto OnADDBARsp_Reject;
|
||||||
}
|
}
|
||||||
|
|
||||||
pTS->bAddBaReqInProgress = false;
|
ts->bAddBaReqInProgress = false;
|
||||||
pPendingBA = &pTS->TxPendingBARecord;
|
pending_ba = &ts->TxPendingBARecord;
|
||||||
pAdmittedBA = &pTS->TxAdmittedBARecord;
|
pAdmittedBA = &ts->TxAdmittedBARecord;
|
||||||
|
|
||||||
if (pAdmittedBA->b_valid) {
|
if (pAdmittedBA->b_valid) {
|
||||||
netdev_dbg(ieee->dev, "%s(): ADDBA response already admitted\n",
|
netdev_dbg(ieee->dev, "%s(): ADDBA response already admitted\n",
|
||||||
__func__);
|
__func__);
|
||||||
return -1;
|
return -1;
|
||||||
} else if (!pPendingBA->b_valid ||
|
} else if (!pending_ba->b_valid ||
|
||||||
(*pDialogToken != pPendingBA->dialog_token)) {
|
(*pDialogToken != pending_ba->dialog_token)) {
|
||||||
netdev_warn(ieee->dev,
|
netdev_warn(ieee->dev,
|
||||||
"%s(): ADDBA Rsp. BA invalid, DELBA!\n",
|
"%s(): ADDBA Rsp. BA invalid, DELBA!\n",
|
||||||
__func__);
|
__func__);
|
||||||
ReasonCode = DELBA_REASON_UNKNOWN_BA;
|
reason_code = DELBA_REASON_UNKNOWN_BA;
|
||||||
goto OnADDBARsp_Reject;
|
goto OnADDBARsp_Reject;
|
||||||
} else {
|
} else {
|
||||||
netdev_dbg(ieee->dev,
|
netdev_dbg(ieee->dev,
|
||||||
"%s(): Recv ADDBA Rsp. BA is admitted! Status code:%X\n",
|
"%s(): Recv ADDBA Rsp. BA is admitted! Status code:%X\n",
|
||||||
__func__, *pStatusCode);
|
__func__, *status_code);
|
||||||
deactivate_ba_entry(ieee, pPendingBA);
|
deactivate_ba_entry(ieee, pending_ba);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*pStatusCode == ADDBA_STATUS_SUCCESS) {
|
if (*status_code == ADDBA_STATUS_SUCCESS) {
|
||||||
if (pBaParamSet->field.ba_policy == BA_POLICY_DELAYED) {
|
if (pBaParamSet->field.ba_policy == BA_POLICY_DELAYED) {
|
||||||
pTS->bAddBaReqDelayed = true;
|
ts->bAddBaReqDelayed = true;
|
||||||
deactivate_ba_entry(ieee, pAdmittedBA);
|
deactivate_ba_entry(ieee, pAdmittedBA);
|
||||||
ReasonCode = DELBA_REASON_END_BA;
|
reason_code = DELBA_REASON_END_BA;
|
||||||
goto OnADDBARsp_Reject;
|
goto OnADDBARsp_Reject;
|
||||||
}
|
}
|
||||||
|
|
||||||
pAdmittedBA->dialog_token = *pDialogToken;
|
pAdmittedBA->dialog_token = *pDialogToken;
|
||||||
pAdmittedBA->ba_timeout_value = *pBaTimeoutVal;
|
pAdmittedBA->ba_timeout_value = *pBaTimeoutVal;
|
||||||
pAdmittedBA->ba_start_seq_ctrl = pPendingBA->ba_start_seq_ctrl;
|
pAdmittedBA->ba_start_seq_ctrl = pending_ba->ba_start_seq_ctrl;
|
||||||
pAdmittedBA->ba_param_set = *pBaParamSet;
|
pAdmittedBA->ba_param_set = *pBaParamSet;
|
||||||
deactivate_ba_entry(ieee, pAdmittedBA);
|
deactivate_ba_entry(ieee, pAdmittedBA);
|
||||||
activate_ba_entry(pAdmittedBA, *pBaTimeoutVal);
|
activate_ba_entry(pAdmittedBA, *pBaTimeoutVal);
|
||||||
} else {
|
} else {
|
||||||
pTS->bAddBaReqDelayed = true;
|
ts->bAddBaReqDelayed = true;
|
||||||
pTS->bDisable_AddBa = true;
|
ts->bDisable_AddBa = true;
|
||||||
ReasonCode = DELBA_REASON_END_BA;
|
reason_code = DELBA_REASON_END_BA;
|
||||||
goto OnADDBARsp_Reject;
|
goto OnADDBARsp_Reject;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -394,30 +394,30 @@ OnADDBARsp_Reject:
|
|||||||
struct ba_record BA;
|
struct ba_record BA;
|
||||||
|
|
||||||
BA.ba_param_set = *pBaParamSet;
|
BA.ba_param_set = *pBaParamSet;
|
||||||
rtllib_send_DELBA(ieee, dst, &BA, TX_DIR, ReasonCode);
|
rtllib_send_DELBA(ieee, dst, &BA, TX_DIR, reason_code);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int rtllib_rx_DELBA(struct rtllib_device *ieee, struct sk_buff *skb)
|
int rtllib_rx_DELBA(struct rtllib_device *ieee, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct rtllib_hdr_3addr *delba = NULL;
|
struct ieee80211_hdr_3addr *delba = NULL;
|
||||||
union delba_param_set *pDelBaParamSet = NULL;
|
union delba_param_set *pDelBaParamSet = NULL;
|
||||||
u8 *dst = NULL;
|
u8 *dst = NULL;
|
||||||
|
|
||||||
if (skb->len < sizeof(struct rtllib_hdr_3addr) + 6) {
|
if (skb->len < sizeof(struct ieee80211_hdr_3addr) + 6) {
|
||||||
netdev_warn(ieee->dev, "Invalid skb len in DELBA(%d / %d)\n",
|
netdev_warn(ieee->dev, "Invalid skb len in DELBA(%d / %d)\n",
|
||||||
(int)skb->len,
|
(int)skb->len,
|
||||||
(int)(sizeof(struct rtllib_hdr_3addr) + 6));
|
(int)(sizeof(struct ieee80211_hdr_3addr) + 6));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ieee->current_network.qos_data.active ||
|
if (!ieee->current_network.qos_data.active ||
|
||||||
!ieee->ht_info->bCurrentHTSupport) {
|
!ieee->ht_info->current_ht_support) {
|
||||||
netdev_warn(ieee->dev,
|
netdev_warn(ieee->dev,
|
||||||
"received DELBA while QOS or HT is not supported(%d, %d)\n",
|
"received DELBA while QOS or HT is not supported(%d, %d)\n",
|
||||||
ieee->current_network. qos_data.active,
|
ieee->current_network. qos_data.active,
|
||||||
ieee->ht_info->bCurrentHTSupport);
|
ieee->ht_info->current_ht_support);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -425,14 +425,14 @@ int rtllib_rx_DELBA(struct rtllib_device *ieee, struct sk_buff *skb)
|
|||||||
print_hex_dump_bytes("%s: ", DUMP_PREFIX_NONE, skb->data,
|
print_hex_dump_bytes("%s: ", DUMP_PREFIX_NONE, skb->data,
|
||||||
__func__, skb->len);
|
__func__, skb->len);
|
||||||
#endif
|
#endif
|
||||||
delba = (struct rtllib_hdr_3addr *)skb->data;
|
delba = (struct ieee80211_hdr_3addr *)skb->data;
|
||||||
dst = (u8 *)(&delba->addr2[0]);
|
dst = (u8 *)(&delba->addr2[0]);
|
||||||
pDelBaParamSet = (union delba_param_set *)&delba->payload[2];
|
pDelBaParamSet = (union delba_param_set *)&delba->seq_ctrl + 2;
|
||||||
|
|
||||||
if (pDelBaParamSet->field.initiator == 1) {
|
if (pDelBaParamSet->field.initiator == 1) {
|
||||||
struct rx_ts_record *pRxTs;
|
struct rx_ts_record *ts;
|
||||||
|
|
||||||
if (!GetTs(ieee, (struct ts_common_info **)&pRxTs, dst,
|
if (!rtllib_get_ts(ieee, (struct ts_common_info **)&ts, dst,
|
||||||
(u8)pDelBaParamSet->field.tid, RX_DIR, false)) {
|
(u8)pDelBaParamSet->field.tid, RX_DIR, false)) {
|
||||||
netdev_warn(ieee->dev,
|
netdev_warn(ieee->dev,
|
||||||
"%s(): can't get TS for RXTS. dst:%pM TID:%d\n",
|
"%s(): can't get TS for RXTS. dst:%pM TID:%d\n",
|
||||||
@ -441,11 +441,11 @@ int rtllib_rx_DELBA(struct rtllib_device *ieee, struct sk_buff *skb)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
rx_ts_delete_ba(ieee, pRxTs);
|
rx_ts_delete_ba(ieee, ts);
|
||||||
} else {
|
} else {
|
||||||
struct tx_ts_record *pTxTs;
|
struct tx_ts_record *pTxTs;
|
||||||
|
|
||||||
if (!GetTs(ieee, (struct ts_common_info **)&pTxTs, dst,
|
if (!rtllib_get_ts(ieee, (struct ts_common_info **)&pTxTs, dst,
|
||||||
(u8)pDelBaParamSet->field.tid, TX_DIR, false)) {
|
(u8)pDelBaParamSet->field.tid, TX_DIR, false)) {
|
||||||
netdev_warn(ieee->dev, "%s(): can't get TS for TXTS\n",
|
netdev_warn(ieee->dev, "%s(): can't get TS for TXTS\n",
|
||||||
__func__);
|
__func__);
|
||||||
@ -461,27 +461,27 @@ int rtllib_rx_DELBA(struct rtllib_device *ieee, struct sk_buff *skb)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtllib_ts_init_add_ba(struct rtllib_device *ieee, struct tx_ts_record *pTS,
|
void rtllib_ts_init_add_ba(struct rtllib_device *ieee, struct tx_ts_record *ts,
|
||||||
u8 Policy, u8 bOverwritePending)
|
u8 policy, u8 bOverwritePending)
|
||||||
{
|
{
|
||||||
struct ba_record *pBA = &pTS->TxPendingBARecord;
|
struct ba_record *ba = &ts->TxPendingBARecord;
|
||||||
|
|
||||||
if (pBA->b_valid && !bOverwritePending)
|
if (ba->b_valid && !bOverwritePending)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
deactivate_ba_entry(ieee, pBA);
|
deactivate_ba_entry(ieee, ba);
|
||||||
|
|
||||||
pBA->dialog_token++;
|
ba->dialog_token++;
|
||||||
pBA->ba_param_set.field.amsdu_support = 0;
|
ba->ba_param_set.field.amsdu_support = 0;
|
||||||
pBA->ba_param_set.field.ba_policy = Policy;
|
ba->ba_param_set.field.ba_policy = policy;
|
||||||
pBA->ba_param_set.field.tid = pTS->TsCommonInfo.TSpec.f.TSInfo.field.ucTSID;
|
ba->ba_param_set.field.tid = ts->TsCommonInfo.TSpec.ucTSID;
|
||||||
pBA->ba_param_set.field.buffer_size = 32;
|
ba->ba_param_set.field.buffer_size = 32;
|
||||||
pBA->ba_timeout_value = 0;
|
ba->ba_timeout_value = 0;
|
||||||
pBA->ba_start_seq_ctrl.field.seq_num = (pTS->TxCurSeq + 3) % 4096;
|
ba->ba_start_seq_ctrl.field.seq_num = (ts->TxCurSeq + 3) % 4096;
|
||||||
|
|
||||||
activate_ba_entry(pBA, BA_SETUP_TIMEOUT);
|
activate_ba_entry(ba, BA_SETUP_TIMEOUT);
|
||||||
|
|
||||||
rtllib_send_ADDBAReq(ieee, pTS->TsCommonInfo.Addr, pBA);
|
rtllib_send_ADDBAReq(ieee, ts->TsCommonInfo.addr, ba);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtllib_ts_init_del_ba(struct rtllib_device *ieee,
|
void rtllib_ts_init_del_ba(struct rtllib_device *ieee,
|
||||||
@ -493,17 +493,17 @@ void rtllib_ts_init_del_ba(struct rtllib_device *ieee,
|
|||||||
(struct tx_ts_record *)pTsCommonInfo;
|
(struct tx_ts_record *)pTsCommonInfo;
|
||||||
|
|
||||||
if (tx_ts_delete_ba(ieee, pTxTs))
|
if (tx_ts_delete_ba(ieee, pTxTs))
|
||||||
rtllib_send_DELBA(ieee, pTsCommonInfo->Addr,
|
rtllib_send_DELBA(ieee, pTsCommonInfo->addr,
|
||||||
(pTxTs->TxAdmittedBARecord.b_valid) ?
|
(pTxTs->TxAdmittedBARecord.b_valid) ?
|
||||||
(&pTxTs->TxAdmittedBARecord) :
|
(&pTxTs->TxAdmittedBARecord) :
|
||||||
(&pTxTs->TxPendingBARecord),
|
(&pTxTs->TxPendingBARecord),
|
||||||
TxRxSelect, DELBA_REASON_END_BA);
|
TxRxSelect, DELBA_REASON_END_BA);
|
||||||
} else if (TxRxSelect == RX_DIR) {
|
} else if (TxRxSelect == RX_DIR) {
|
||||||
struct rx_ts_record *pRxTs =
|
struct rx_ts_record *ts =
|
||||||
(struct rx_ts_record *)pTsCommonInfo;
|
(struct rx_ts_record *)pTsCommonInfo;
|
||||||
if (rx_ts_delete_ba(ieee, pRxTs))
|
if (rx_ts_delete_ba(ieee, ts))
|
||||||
rtllib_send_DELBA(ieee, pTsCommonInfo->Addr,
|
rtllib_send_DELBA(ieee, pTsCommonInfo->addr,
|
||||||
&pRxTs->rx_admitted_ba_record,
|
&ts->rx_admitted_ba_record,
|
||||||
TxRxSelect, DELBA_REASON_END_BA);
|
TxRxSelect, DELBA_REASON_END_BA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -525,20 +525,20 @@ void rtllib_tx_ba_inact_timeout(struct timer_list *t)
|
|||||||
struct rtllib_device *ieee = container_of(pTxTs, struct rtllib_device,
|
struct rtllib_device *ieee = container_of(pTxTs, struct rtllib_device,
|
||||||
TxTsRecord[pTxTs->num]);
|
TxTsRecord[pTxTs->num]);
|
||||||
tx_ts_delete_ba(ieee, pTxTs);
|
tx_ts_delete_ba(ieee, pTxTs);
|
||||||
rtllib_send_DELBA(ieee, pTxTs->TsCommonInfo.Addr,
|
rtllib_send_DELBA(ieee, pTxTs->TsCommonInfo.addr,
|
||||||
&pTxTs->TxAdmittedBARecord, TX_DIR,
|
&pTxTs->TxAdmittedBARecord, TX_DIR,
|
||||||
DELBA_REASON_TIMEOUT);
|
DELBA_REASON_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtllib_rx_ba_inact_timeout(struct timer_list *t)
|
void rtllib_rx_ba_inact_timeout(struct timer_list *t)
|
||||||
{
|
{
|
||||||
struct rx_ts_record *pRxTs = from_timer(pRxTs, t,
|
struct rx_ts_record *ts = from_timer(ts, t,
|
||||||
rx_admitted_ba_record.timer);
|
rx_admitted_ba_record.timer);
|
||||||
struct rtllib_device *ieee = container_of(pRxTs, struct rtllib_device,
|
struct rtllib_device *ieee = container_of(ts, struct rtllib_device,
|
||||||
RxTsRecord[pRxTs->num]);
|
RxTsRecord[ts->num]);
|
||||||
|
|
||||||
rx_ts_delete_ba(ieee, pRxTs);
|
rx_ts_delete_ba(ieee, ts);
|
||||||
rtllib_send_DELBA(ieee, pRxTs->ts_common_info.Addr,
|
rtllib_send_DELBA(ieee, ts->ts_common_info.addr,
|
||||||
&pRxTs->rx_admitted_ba_record, RX_DIR,
|
&ts->rx_admitted_ba_record, RX_DIR,
|
||||||
DELBA_REASON_TIMEOUT);
|
DELBA_REASON_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ enum ht_aggre_mode {
|
|||||||
|
|
||||||
struct rt_hi_throughput {
|
struct rt_hi_throughput {
|
||||||
u8 enable_ht;
|
u8 enable_ht;
|
||||||
u8 bCurrentHTSupport;
|
u8 current_ht_support;
|
||||||
u8 bRegBW40MHz;
|
u8 bRegBW40MHz;
|
||||||
u8 bCurBW40MHz;
|
u8 bCurBW40MHz;
|
||||||
u8 bRegShortGI40MHz;
|
u8 bRegShortGI40MHz;
|
||||||
|
@ -67,7 +67,7 @@ static u8 CISCO_BROADCOM[3] = {0x00, 0x17, 0x94};
|
|||||||
|
|
||||||
static u8 LINKSYS_MARVELL_4400N[3] = {0x00, 0x14, 0xa4};
|
static u8 LINKSYS_MARVELL_4400N[3] = {0x00, 0x14, 0xa4};
|
||||||
|
|
||||||
void HTUpdateDefaultSetting(struct rtllib_device *ieee)
|
void ht_update_default_setting(struct rtllib_device *ieee)
|
||||||
{
|
{
|
||||||
struct rt_hi_throughput *ht_info = ieee->ht_info;
|
struct rt_hi_throughput *ht_info = ieee->ht_info;
|
||||||
|
|
||||||
@ -207,27 +207,6 @@ static void HTIOTPeerDetermine(struct rtllib_device *ieee)
|
|||||||
netdev_dbg(ieee->dev, "IOTPEER: %x\n", ht_info->IOTPeer);
|
netdev_dbg(ieee->dev, "IOTPEER: %x\n", ht_info->IOTPeer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u8 HTIOTActIsDisableMCS14(struct rtllib_device *ieee, u8 *PeerMacAddr)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool HTIOTActIsDisableMCS15(struct rtllib_device *ieee)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool HTIOTActIsDisableMCSTwoSpatialStream(struct rtllib_device *ieee)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static u8 HTIOTActIsDisableEDCATurbo(struct rtllib_device *ieee,
|
|
||||||
u8 *PeerMacAddr)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static u8 HTIOTActIsMgntUseCCK6M(struct rtllib_device *ieee,
|
static u8 HTIOTActIsMgntUseCCK6M(struct rtllib_device *ieee,
|
||||||
struct rtllib_network *network)
|
struct rtllib_network *network)
|
||||||
{
|
{
|
||||||
@ -352,7 +331,6 @@ void HTConstructCapabilityElement(struct rtllib_device *ieee, u8 *posHTCap,
|
|||||||
void HTConstructInfoElement(struct rtllib_device *ieee, u8 *posHTInfo,
|
void HTConstructInfoElement(struct rtllib_device *ieee, u8 *posHTInfo,
|
||||||
u8 *len, u8 IsEncrypt)
|
u8 *len, u8 IsEncrypt)
|
||||||
{
|
{
|
||||||
struct rt_hi_throughput *pHT = ieee->ht_info;
|
|
||||||
struct ht_info_ele *pHTInfoEle = (struct ht_info_ele *)posHTInfo;
|
struct ht_info_ele *pHTInfoEle = (struct ht_info_ele *)posHTInfo;
|
||||||
|
|
||||||
if (!posHTInfo || !pHTInfoEle) {
|
if (!posHTInfo || !pHTInfoEle) {
|
||||||
@ -363,32 +341,7 @@ void HTConstructInfoElement(struct rtllib_device *ieee, u8 *posHTInfo,
|
|||||||
}
|
}
|
||||||
|
|
||||||
memset(posHTInfo, 0, *len);
|
memset(posHTInfo, 0, *len);
|
||||||
if (ieee->iw_mode == IW_MODE_ADHOC) {
|
*len = 0;
|
||||||
pHTInfoEle->ControlChl = ieee->current_network.channel;
|
|
||||||
pHTInfoEle->ExtChlOffset = ((!pHT->bRegBW40MHz) ?
|
|
||||||
HT_EXTCHNL_OFFSET_NO_EXT :
|
|
||||||
(ieee->current_network.channel <= 6)
|
|
||||||
? HT_EXTCHNL_OFFSET_UPPER :
|
|
||||||
HT_EXTCHNL_OFFSET_LOWER);
|
|
||||||
pHTInfoEle->RecommemdedTxWidth = pHT->bRegBW40MHz;
|
|
||||||
pHTInfoEle->RIFS = 0;
|
|
||||||
pHTInfoEle->PSMPAccessOnly = 0;
|
|
||||||
pHTInfoEle->SrvIntGranularity = 0;
|
|
||||||
pHTInfoEle->OptMode = pHT->current_op_mode;
|
|
||||||
pHTInfoEle->NonGFDevPresent = 0;
|
|
||||||
pHTInfoEle->DualBeacon = 0;
|
|
||||||
pHTInfoEle->SecondaryBeacon = 0;
|
|
||||||
pHTInfoEle->LSigTxopProtectFull = 0;
|
|
||||||
pHTInfoEle->PcoActive = 0;
|
|
||||||
pHTInfoEle->PcoPhase = 0;
|
|
||||||
|
|
||||||
memset(pHTInfoEle->BasicMSC, 0, 16);
|
|
||||||
|
|
||||||
*len = 22 + 2;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
*len = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HTConstructRT2RTAggElement(struct rtllib_device *ieee, u8 *posRT2RTAgg,
|
void HTConstructRT2RTAggElement(struct rtllib_device *ieee, u8 *posRT2RTAgg,
|
||||||
@ -515,7 +468,7 @@ void HTOnAssocRsp(struct rtllib_device *ieee)
|
|||||||
static const u8 EWC11NHTCap[] = { 0x00, 0x90, 0x4c, 0x33 };
|
static const u8 EWC11NHTCap[] = { 0x00, 0x90, 0x4c, 0x33 };
|
||||||
static const u8 EWC11NHTInfo[] = { 0x00, 0x90, 0x4c, 0x34 };
|
static const u8 EWC11NHTInfo[] = { 0x00, 0x90, 0x4c, 0x34 };
|
||||||
|
|
||||||
if (!ht_info->bCurrentHTSupport) {
|
if (!ht_info->current_ht_support) {
|
||||||
netdev_warn(ieee->dev, "%s(): HT_DISABLE\n", __func__);
|
netdev_warn(ieee->dev, "%s(): HT_DISABLE\n", __func__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -620,7 +573,7 @@ void HTInitializeHTInfo(struct rtllib_device *ieee)
|
|||||||
{
|
{
|
||||||
struct rt_hi_throughput *ht_info = ieee->ht_info;
|
struct rt_hi_throughput *ht_info = ieee->ht_info;
|
||||||
|
|
||||||
ht_info->bCurrentHTSupport = false;
|
ht_info->current_ht_support = false;
|
||||||
|
|
||||||
ht_info->bCurBW40MHz = false;
|
ht_info->bCurBW40MHz = false;
|
||||||
ht_info->cur_tx_bw40mhz = false;
|
ht_info->cur_tx_bw40mhz = false;
|
||||||
@ -691,7 +644,7 @@ void HTResetSelfAndSavePeerSetting(struct rtllib_device *ieee,
|
|||||||
* function rtllib_softmac_new_net. WB 2008.09.10
|
* function rtllib_softmac_new_net. WB 2008.09.10
|
||||||
*/
|
*/
|
||||||
if (pNetwork->bssht.bd_support_ht) {
|
if (pNetwork->bssht.bd_support_ht) {
|
||||||
ht_info->bCurrentHTSupport = true;
|
ht_info->current_ht_support = true;
|
||||||
ht_info->ePeerHTSpecVer = pNetwork->bssht.bd_ht_spec_ver;
|
ht_info->ePeerHTSpecVer = pNetwork->bssht.bd_ht_spec_ver;
|
||||||
|
|
||||||
if (pNetwork->bssht.bd_ht_cap_len > 0 &&
|
if (pNetwork->bssht.bd_ht_cap_len > 0 &&
|
||||||
@ -722,22 +675,6 @@ void HTResetSelfAndSavePeerSetting(struct rtllib_device *ieee,
|
|||||||
HTIOTPeerDetermine(ieee);
|
HTIOTPeerDetermine(ieee);
|
||||||
|
|
||||||
ht_info->iot_action = 0;
|
ht_info->iot_action = 0;
|
||||||
bIOTAction = HTIOTActIsDisableMCS14(ieee, pNetwork->bssid);
|
|
||||||
if (bIOTAction)
|
|
||||||
ht_info->iot_action |= HT_IOT_ACT_DISABLE_MCS14;
|
|
||||||
|
|
||||||
bIOTAction = HTIOTActIsDisableMCS15(ieee);
|
|
||||||
if (bIOTAction)
|
|
||||||
ht_info->iot_action |= HT_IOT_ACT_DISABLE_MCS15;
|
|
||||||
|
|
||||||
bIOTAction = HTIOTActIsDisableMCSTwoSpatialStream(ieee);
|
|
||||||
if (bIOTAction)
|
|
||||||
ht_info->iot_action |= HT_IOT_ACT_DISABLE_ALL_2SS;
|
|
||||||
|
|
||||||
bIOTAction = HTIOTActIsDisableEDCATurbo(ieee, pNetwork->bssid);
|
|
||||||
if (bIOTAction)
|
|
||||||
ht_info->iot_action |= HT_IOT_ACT_DISABLE_EDCA_TURBO;
|
|
||||||
|
|
||||||
bIOTAction = HTIOTActIsMgntUseCCK6M(ieee, pNetwork);
|
bIOTAction = HTIOTActIsMgntUseCCK6M(ieee, pNetwork);
|
||||||
if (bIOTAction)
|
if (bIOTAction)
|
||||||
ht_info->iot_action |= HT_IOT_ACT_MGNT_USE_CCK_6M;
|
ht_info->iot_action |= HT_IOT_ACT_MGNT_USE_CCK_6M;
|
||||||
@ -745,7 +682,7 @@ void HTResetSelfAndSavePeerSetting(struct rtllib_device *ieee,
|
|||||||
if (bIOTAction)
|
if (bIOTAction)
|
||||||
ht_info->iot_action |= HT_IOT_ACT_CDD_FSYNC;
|
ht_info->iot_action |= HT_IOT_ACT_CDD_FSYNC;
|
||||||
} else {
|
} else {
|
||||||
ht_info->bCurrentHTSupport = false;
|
ht_info->current_ht_support = false;
|
||||||
ht_info->current_rt2rt_aggregation = false;
|
ht_info->current_rt2rt_aggregation = false;
|
||||||
ht_info->current_rt2rt_long_slot_time = false;
|
ht_info->current_rt2rt_long_slot_time = false;
|
||||||
ht_info->RT2RT_HT_Mode = (enum rt_ht_capability)0;
|
ht_info->RT2RT_HT_Mode = (enum rt_ht_capability)0;
|
||||||
@ -762,52 +699,16 @@ void HT_update_self_and_peer_setting(struct rtllib_device *ieee,
|
|||||||
struct ht_info_ele *pPeerHTInfo =
|
struct ht_info_ele *pPeerHTInfo =
|
||||||
(struct ht_info_ele *)pNetwork->bssht.bd_ht_info_buf;
|
(struct ht_info_ele *)pNetwork->bssht.bd_ht_info_buf;
|
||||||
|
|
||||||
if (ht_info->bCurrentHTSupport) {
|
if (ht_info->current_ht_support) {
|
||||||
if (pNetwork->bssht.bd_ht_info_len != 0)
|
if (pNetwork->bssht.bd_ht_info_len != 0)
|
||||||
ht_info->current_op_mode = pPeerHTInfo->OptMode;
|
ht_info->current_op_mode = pPeerHTInfo->OptMode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(HT_update_self_and_peer_setting);
|
EXPORT_SYMBOL(HT_update_self_and_peer_setting);
|
||||||
|
|
||||||
void HTUseDefaultSetting(struct rtllib_device *ieee)
|
|
||||||
{
|
|
||||||
struct rt_hi_throughput *ht_info = ieee->ht_info;
|
|
||||||
|
|
||||||
if (ht_info->enable_ht) {
|
|
||||||
ht_info->bCurrentHTSupport = true;
|
|
||||||
ht_info->bCurSuppCCK = ht_info->bRegSuppCCK;
|
|
||||||
|
|
||||||
ht_info->bCurBW40MHz = ht_info->bRegBW40MHz;
|
|
||||||
ht_info->bCurShortGI20MHz = ht_info->bRegShortGI20MHz;
|
|
||||||
|
|
||||||
ht_info->bCurShortGI40MHz = ht_info->bRegShortGI40MHz;
|
|
||||||
|
|
||||||
if (ieee->iw_mode == IW_MODE_ADHOC)
|
|
||||||
ieee->current_network.qos_data.active =
|
|
||||||
ieee->current_network.qos_data.supported;
|
|
||||||
ht_info->bCurrent_AMSDU_Support = ht_info->bAMSDU_Support;
|
|
||||||
ht_info->nCurrent_AMSDU_MaxSize = ht_info->nAMSDU_MaxSize;
|
|
||||||
|
|
||||||
ht_info->bCurrentAMPDUEnable = ht_info->bAMPDUEnable;
|
|
||||||
ht_info->CurrentAMPDUFactor = ht_info->AMPDU_Factor;
|
|
||||||
|
|
||||||
ht_info->current_mpdu_density = ht_info->current_mpdu_density;
|
|
||||||
|
|
||||||
HTFilterMCSRate(ieee, ieee->reg_dot11tx_ht_oper_rate_set,
|
|
||||||
ieee->dot11ht_oper_rate_set);
|
|
||||||
ieee->HTHighestOperaRate = HTGetHighestMCSRate(ieee,
|
|
||||||
ieee->dot11ht_oper_rate_set,
|
|
||||||
MCS_FILTER_ALL);
|
|
||||||
ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
ht_info->bCurrentHTSupport = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
u8 HTCCheck(struct rtllib_device *ieee, u8 *pFrame)
|
u8 HTCCheck(struct rtllib_device *ieee, u8 *pFrame)
|
||||||
{
|
{
|
||||||
if (ieee->ht_info->bCurrentHTSupport) {
|
if (ieee->ht_info->current_ht_support) {
|
||||||
if ((IsQoSDataFrame(pFrame) && Frame_Order(pFrame)) == 1) {
|
if ((IsQoSDataFrame(pFrame) && Frame_Order(pFrame)) == 1) {
|
||||||
netdev_dbg(ieee->dev, "HT CONTROL FILED EXIST!!\n");
|
netdev_dbg(ieee->dev, "HT CONTROL FILED EXIST!!\n");
|
||||||
return true;
|
return true;
|
||||||
|
@ -7,76 +7,9 @@
|
|||||||
#ifndef __INC_QOS_TYPE_H
|
#ifndef __INC_QOS_TYPE_H
|
||||||
#define __INC_QOS_TYPE_H
|
#define __INC_QOS_TYPE_H
|
||||||
|
|
||||||
#define BIT0 0x00000001
|
struct qos_tsinfo {
|
||||||
#define BIT1 0x00000002
|
u8 ucTSID:4;
|
||||||
#define BIT2 0x00000004
|
u8 ucDirection:2;
|
||||||
#define BIT3 0x00000008
|
|
||||||
#define BIT4 0x00000010
|
|
||||||
#define BIT5 0x00000020
|
|
||||||
#define BIT6 0x00000040
|
|
||||||
#define BIT7 0x00000080
|
|
||||||
#define BIT8 0x00000100
|
|
||||||
#define BIT9 0x00000200
|
|
||||||
#define BIT10 0x00000400
|
|
||||||
#define BIT11 0x00000800
|
|
||||||
#define BIT12 0x00001000
|
|
||||||
#define BIT13 0x00002000
|
|
||||||
#define BIT14 0x00004000
|
|
||||||
#define BIT15 0x00008000
|
|
||||||
#define BIT16 0x00010000
|
|
||||||
#define BIT17 0x00020000
|
|
||||||
#define BIT18 0x00040000
|
|
||||||
#define BIT19 0x00080000
|
|
||||||
#define BIT20 0x00100000
|
|
||||||
#define BIT21 0x00200000
|
|
||||||
#define BIT22 0x00400000
|
|
||||||
#define BIT23 0x00800000
|
|
||||||
#define BIT24 0x01000000
|
|
||||||
#define BIT25 0x02000000
|
|
||||||
#define BIT26 0x04000000
|
|
||||||
#define BIT27 0x08000000
|
|
||||||
#define BIT28 0x10000000
|
|
||||||
#define BIT29 0x20000000
|
|
||||||
#define BIT30 0x40000000
|
|
||||||
#define BIT31 0x80000000
|
|
||||||
|
|
||||||
union qos_tsinfo {
|
|
||||||
u8 charData[3];
|
|
||||||
struct {
|
|
||||||
u8 ucTrafficType:1;
|
|
||||||
u8 ucTSID:4;
|
|
||||||
u8 ucDirection:2;
|
|
||||||
u8 ucAccessPolicy:2;
|
|
||||||
u8 ucAggregation:1;
|
|
||||||
u8 ucPSB:1;
|
|
||||||
u8 ucUP:3;
|
|
||||||
u8 ucTSInfoAckPolicy:2;
|
|
||||||
u8 ucSchedule:1;
|
|
||||||
u8 ucReserved:7;
|
|
||||||
} field;
|
|
||||||
};
|
|
||||||
|
|
||||||
union tspec_body {
|
|
||||||
u8 charData[55];
|
|
||||||
|
|
||||||
struct {
|
|
||||||
union qos_tsinfo TSInfo;
|
|
||||||
u16 NominalMSDUsize;
|
|
||||||
u16 MaxMSDUsize;
|
|
||||||
u32 MinServiceItv;
|
|
||||||
u32 MaxServiceItv;
|
|
||||||
u32 InactivityItv;
|
|
||||||
u32 SuspenItv;
|
|
||||||
u32 ServiceStartTime;
|
|
||||||
u32 MinDataRate;
|
|
||||||
u32 MeanDataRate;
|
|
||||||
u32 PeakDataRate;
|
|
||||||
u32 MaxBurstSize;
|
|
||||||
u32 DelayBound;
|
|
||||||
u32 MinPhyRate;
|
|
||||||
u16 SurplusBandwidthAllowance;
|
|
||||||
u16 MediumTime;
|
|
||||||
} f;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct octet_string {
|
struct octet_string {
|
||||||
@ -88,7 +21,6 @@ struct octet_string {
|
|||||||
#define AC1_BK 1
|
#define AC1_BK 1
|
||||||
#define AC2_VI 2
|
#define AC2_VI 2
|
||||||
#define AC3_VO 3
|
#define AC3_VO 3
|
||||||
#define AC_MAX 4
|
|
||||||
|
|
||||||
enum direction_value {
|
enum direction_value {
|
||||||
DIR_UP = 0,
|
DIR_UP = 0,
|
||||||
@ -97,62 +29,6 @@ enum direction_value {
|
|||||||
DIR_BI_DIR = 3,
|
DIR_BI_DIR = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct acm {
|
|
||||||
u64 UsedTime;
|
|
||||||
u64 MediumTime;
|
|
||||||
u8 HwAcmCtl;
|
|
||||||
};
|
|
||||||
|
|
||||||
union qos_tclas {
|
|
||||||
struct _TYPE_GENERAL {
|
|
||||||
u8 Priority;
|
|
||||||
u8 ClassifierType;
|
|
||||||
u8 Mask;
|
|
||||||
} TYPE_GENERAL;
|
|
||||||
|
|
||||||
struct _TYPE0_ETH {
|
|
||||||
u8 Priority;
|
|
||||||
u8 ClassifierType;
|
|
||||||
u8 Mask;
|
|
||||||
u8 SrcAddr[ETH_ALEN];
|
|
||||||
u8 DstAddr[ETH_ALEN];
|
|
||||||
u16 Type;
|
|
||||||
} TYPE0_ETH;
|
|
||||||
|
|
||||||
struct _TYPE1_IPV4 {
|
|
||||||
u8 Priority;
|
|
||||||
u8 ClassifierType;
|
|
||||||
u8 Mask;
|
|
||||||
u8 Version;
|
|
||||||
u8 SrcIP[4];
|
|
||||||
u8 DstIP[4];
|
|
||||||
u16 SrcPort;
|
|
||||||
u16 DstPort;
|
|
||||||
u8 DSCP;
|
|
||||||
u8 Protocol;
|
|
||||||
u8 Reserved;
|
|
||||||
} TYPE1_IPV4;
|
|
||||||
|
|
||||||
struct _TYPE1_IPV6 {
|
|
||||||
u8 Priority;
|
|
||||||
u8 ClassifierType;
|
|
||||||
u8 Mask;
|
|
||||||
u8 Version;
|
|
||||||
u8 SrcIP[16];
|
|
||||||
u8 DstIP[16];
|
|
||||||
u16 SrcPort;
|
|
||||||
u16 DstPort;
|
|
||||||
u8 FlowLabel[3];
|
|
||||||
} TYPE1_IPV6;
|
|
||||||
|
|
||||||
struct _TYPE2_8021Q {
|
|
||||||
u8 Priority;
|
|
||||||
u8 ClassifierType;
|
|
||||||
u8 Mask;
|
|
||||||
u16 TagType;
|
|
||||||
} TYPE2_8021Q;
|
|
||||||
};
|
|
||||||
|
|
||||||
union aci_aifsn {
|
union aci_aifsn {
|
||||||
u8 charData;
|
u8 charData;
|
||||||
|
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
#define TS_ADDBA_DELAY 60
|
#define TS_ADDBA_DELAY 60
|
||||||
|
|
||||||
#define TOTAL_TS_NUM 16
|
#define TOTAL_TS_NUM 16
|
||||||
#define TCLAS_NUM 4
|
|
||||||
|
|
||||||
enum tr_select {
|
enum tr_select {
|
||||||
TX_DIR = 0,
|
TX_DIR = 0,
|
||||||
@ -19,11 +18,8 @@ enum tr_select {
|
|||||||
|
|
||||||
struct ts_common_info {
|
struct ts_common_info {
|
||||||
struct list_head List;
|
struct list_head List;
|
||||||
u8 Addr[ETH_ALEN];
|
u8 addr[ETH_ALEN];
|
||||||
union tspec_body TSpec;
|
struct qos_tsinfo TSpec;
|
||||||
union qos_tclas TClass[TCLAS_NUM];
|
|
||||||
u8 TClasProc;
|
|
||||||
u8 TClasNum;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tx_ts_record {
|
struct tx_ts_record {
|
||||||
|
@ -10,10 +10,9 @@
|
|||||||
|
|
||||||
static void RxPktPendingTimeout(struct timer_list *t)
|
static void RxPktPendingTimeout(struct timer_list *t)
|
||||||
{
|
{
|
||||||
struct rx_ts_record *pRxTs = from_timer(pRxTs, t,
|
struct rx_ts_record *ts = from_timer(ts, t, rx_pkt_pending_timer);
|
||||||
rx_pkt_pending_timer);
|
struct rtllib_device *ieee = container_of(ts, struct rtllib_device,
|
||||||
struct rtllib_device *ieee = container_of(pRxTs, struct rtllib_device,
|
RxTsRecord[ts->num]);
|
||||||
RxTsRecord[pRxTs->num]);
|
|
||||||
|
|
||||||
struct rx_reorder_entry *pReorderEntry = NULL;
|
struct rx_reorder_entry *pReorderEntry = NULL;
|
||||||
|
|
||||||
@ -22,24 +21,24 @@ static void RxPktPendingTimeout(struct timer_list *t)
|
|||||||
bool bPktInBuf = false;
|
bool bPktInBuf = false;
|
||||||
|
|
||||||
spin_lock_irqsave(&(ieee->reorder_spinlock), flags);
|
spin_lock_irqsave(&(ieee->reorder_spinlock), flags);
|
||||||
if (pRxTs->rx_timeout_indicate_seq != 0xffff) {
|
if (ts->rx_timeout_indicate_seq != 0xffff) {
|
||||||
while (!list_empty(&pRxTs->rx_pending_pkt_list)) {
|
while (!list_empty(&ts->rx_pending_pkt_list)) {
|
||||||
pReorderEntry = (struct rx_reorder_entry *)
|
pReorderEntry = (struct rx_reorder_entry *)
|
||||||
list_entry(pRxTs->rx_pending_pkt_list.prev,
|
list_entry(ts->rx_pending_pkt_list.prev,
|
||||||
struct rx_reorder_entry, List);
|
struct rx_reorder_entry, List);
|
||||||
if (index == 0)
|
if (index == 0)
|
||||||
pRxTs->rx_indicate_seq = pReorderEntry->SeqNum;
|
ts->rx_indicate_seq = pReorderEntry->SeqNum;
|
||||||
|
|
||||||
if (SN_LESS(pReorderEntry->SeqNum,
|
if (SN_LESS(pReorderEntry->SeqNum,
|
||||||
pRxTs->rx_indicate_seq) ||
|
ts->rx_indicate_seq) ||
|
||||||
SN_EQUAL(pReorderEntry->SeqNum,
|
SN_EQUAL(pReorderEntry->SeqNum,
|
||||||
pRxTs->rx_indicate_seq)) {
|
ts->rx_indicate_seq)) {
|
||||||
list_del_init(&pReorderEntry->List);
|
list_del_init(&pReorderEntry->List);
|
||||||
|
|
||||||
if (SN_EQUAL(pReorderEntry->SeqNum,
|
if (SN_EQUAL(pReorderEntry->SeqNum,
|
||||||
pRxTs->rx_indicate_seq))
|
ts->rx_indicate_seq))
|
||||||
pRxTs->rx_indicate_seq =
|
ts->rx_indicate_seq =
|
||||||
(pRxTs->rx_indicate_seq + 1) % 4096;
|
(ts->rx_indicate_seq + 1) % 4096;
|
||||||
|
|
||||||
netdev_dbg(ieee->dev,
|
netdev_dbg(ieee->dev,
|
||||||
"%s(): Indicate SeqNum: %d\n",
|
"%s(): Indicate SeqNum: %d\n",
|
||||||
@ -58,7 +57,7 @@ static void RxPktPendingTimeout(struct timer_list *t)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (index > 0) {
|
if (index > 0) {
|
||||||
pRxTs->rx_timeout_indicate_seq = 0xffff;
|
ts->rx_timeout_indicate_seq = 0xffff;
|
||||||
|
|
||||||
if (index > REORDER_WIN_SIZE) {
|
if (index > REORDER_WIN_SIZE) {
|
||||||
netdev_warn(ieee->dev,
|
netdev_warn(ieee->dev,
|
||||||
@ -72,9 +71,9 @@ static void RxPktPendingTimeout(struct timer_list *t)
|
|||||||
bPktInBuf = false;
|
bPktInBuf = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bPktInBuf && (pRxTs->rx_timeout_indicate_seq == 0xffff)) {
|
if (bPktInBuf && (ts->rx_timeout_indicate_seq == 0xffff)) {
|
||||||
pRxTs->rx_timeout_indicate_seq = pRxTs->rx_indicate_seq;
|
ts->rx_timeout_indicate_seq = ts->rx_indicate_seq;
|
||||||
mod_timer(&pRxTs->rx_pkt_pending_timer, jiffies +
|
mod_timer(&ts->rx_pkt_pending_timer, jiffies +
|
||||||
msecs_to_jiffies(ieee->ht_info->rx_reorder_pending_time)
|
msecs_to_jiffies(ieee->ht_info->rx_reorder_pending_time)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -94,37 +93,34 @@ static void TsAddBaProcess(struct timer_list *t)
|
|||||||
|
|
||||||
static void ResetTsCommonInfo(struct ts_common_info *pTsCommonInfo)
|
static void ResetTsCommonInfo(struct ts_common_info *pTsCommonInfo)
|
||||||
{
|
{
|
||||||
eth_zero_addr(pTsCommonInfo->Addr);
|
eth_zero_addr(pTsCommonInfo->addr);
|
||||||
memset(&pTsCommonInfo->TSpec, 0, sizeof(union tspec_body));
|
memset(&pTsCommonInfo->TSpec, 0, sizeof(struct qos_tsinfo));
|
||||||
memset(&pTsCommonInfo->TClass, 0, sizeof(union qos_tclas) * TCLAS_NUM);
|
|
||||||
pTsCommonInfo->TClasProc = 0;
|
|
||||||
pTsCommonInfo->TClasNum = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ResetTxTsEntry(struct tx_ts_record *pTS)
|
static void ResetTxTsEntry(struct tx_ts_record *ts)
|
||||||
{
|
{
|
||||||
ResetTsCommonInfo(&pTS->TsCommonInfo);
|
ResetTsCommonInfo(&ts->TsCommonInfo);
|
||||||
pTS->TxCurSeq = 0;
|
ts->TxCurSeq = 0;
|
||||||
pTS->bAddBaReqInProgress = false;
|
ts->bAddBaReqInProgress = false;
|
||||||
pTS->bAddBaReqDelayed = false;
|
ts->bAddBaReqDelayed = false;
|
||||||
pTS->bUsingBa = false;
|
ts->bUsingBa = false;
|
||||||
pTS->bDisable_AddBa = false;
|
ts->bDisable_AddBa = false;
|
||||||
rtllib_reset_ba_entry(&pTS->TxAdmittedBARecord);
|
rtllib_reset_ba_entry(&ts->TxAdmittedBARecord);
|
||||||
rtllib_reset_ba_entry(&pTS->TxPendingBARecord);
|
rtllib_reset_ba_entry(&ts->TxPendingBARecord);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ResetRxTsEntry(struct rx_ts_record *pTS)
|
static void ResetRxTsEntry(struct rx_ts_record *ts)
|
||||||
{
|
{
|
||||||
ResetTsCommonInfo(&pTS->ts_common_info);
|
ResetTsCommonInfo(&ts->ts_common_info);
|
||||||
pTS->rx_indicate_seq = 0xffff;
|
ts->rx_indicate_seq = 0xffff;
|
||||||
pTS->rx_timeout_indicate_seq = 0xffff;
|
ts->rx_timeout_indicate_seq = 0xffff;
|
||||||
rtllib_reset_ba_entry(&pTS->rx_admitted_ba_record);
|
rtllib_reset_ba_entry(&ts->rx_admitted_ba_record);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TSInitialize(struct rtllib_device *ieee)
|
void rtllib_ts_init(struct rtllib_device *ieee)
|
||||||
{
|
{
|
||||||
struct tx_ts_record *pTxTS = ieee->TxTsRecord;
|
struct tx_ts_record *pTxTS = ieee->TxTsRecord;
|
||||||
struct rx_ts_record *pRxTS = ieee->RxTsRecord;
|
struct rx_ts_record *rxts = ieee->RxTsRecord;
|
||||||
struct rx_reorder_entry *pRxReorderEntry = ieee->RxReorderEntry;
|
struct rx_reorder_entry *pRxReorderEntry = ieee->RxReorderEntry;
|
||||||
u8 count = 0;
|
u8 count = 0;
|
||||||
|
|
||||||
@ -151,17 +147,17 @@ void TSInitialize(struct rtllib_device *ieee)
|
|||||||
INIT_LIST_HEAD(&ieee->Rx_TS_Pending_List);
|
INIT_LIST_HEAD(&ieee->Rx_TS_Pending_List);
|
||||||
INIT_LIST_HEAD(&ieee->Rx_TS_Unused_List);
|
INIT_LIST_HEAD(&ieee->Rx_TS_Unused_List);
|
||||||
for (count = 0; count < TOTAL_TS_NUM; count++) {
|
for (count = 0; count < TOTAL_TS_NUM; count++) {
|
||||||
pRxTS->num = count;
|
rxts->num = count;
|
||||||
INIT_LIST_HEAD(&pRxTS->rx_pending_pkt_list);
|
INIT_LIST_HEAD(&rxts->rx_pending_pkt_list);
|
||||||
timer_setup(&pRxTS->rx_admitted_ba_record.timer,
|
timer_setup(&rxts->rx_admitted_ba_record.timer,
|
||||||
rtllib_rx_ba_inact_timeout, 0);
|
rtllib_rx_ba_inact_timeout, 0);
|
||||||
|
|
||||||
timer_setup(&pRxTS->rx_pkt_pending_timer, RxPktPendingTimeout, 0);
|
timer_setup(&rxts->rx_pkt_pending_timer, RxPktPendingTimeout, 0);
|
||||||
|
|
||||||
ResetRxTsEntry(pRxTS);
|
ResetRxTsEntry(rxts);
|
||||||
list_add_tail(&pRxTS->ts_common_info.List,
|
list_add_tail(&rxts->ts_common_info.List,
|
||||||
&ieee->Rx_TS_Unused_List);
|
&ieee->Rx_TS_Unused_List);
|
||||||
pRxTS++;
|
rxts++;
|
||||||
}
|
}
|
||||||
INIT_LIST_HEAD(&ieee->RxReorder_Unused_List);
|
INIT_LIST_HEAD(&ieee->RxReorder_Unused_List);
|
||||||
for (count = 0; count < REORDER_ENTRY_NUM; count++) {
|
for (count = 0; count < REORDER_ENTRY_NUM; count++) {
|
||||||
@ -174,7 +170,7 @@ void TSInitialize(struct rtllib_device *ieee)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct ts_common_info *SearchAdmitTRStream(struct rtllib_device *ieee,
|
static struct ts_common_info *SearchAdmitTRStream(struct rtllib_device *ieee,
|
||||||
u8 *Addr, u8 TID,
|
u8 *addr, u8 TID,
|
||||||
enum tr_select TxRxSelect)
|
enum tr_select TxRxSelect)
|
||||||
{
|
{
|
||||||
u8 dir;
|
u8 dir;
|
||||||
@ -182,21 +178,14 @@ static struct ts_common_info *SearchAdmitTRStream(struct rtllib_device *ieee,
|
|||||||
struct list_head *psearch_list;
|
struct list_head *psearch_list;
|
||||||
struct ts_common_info *pRet = NULL;
|
struct ts_common_info *pRet = NULL;
|
||||||
|
|
||||||
if (ieee->iw_mode == IW_MODE_ADHOC) {
|
if (TxRxSelect == TX_DIR) {
|
||||||
if (TxRxSelect == TX_DIR)
|
search_dir[DIR_UP] = true;
|
||||||
search_dir[DIR_UP] = true;
|
search_dir[DIR_BI_DIR] = true;
|
||||||
else
|
search_dir[DIR_DIRECT] = true;
|
||||||
search_dir[DIR_DOWN] = true;
|
|
||||||
} else {
|
} else {
|
||||||
if (TxRxSelect == TX_DIR) {
|
search_dir[DIR_DOWN] = true;
|
||||||
search_dir[DIR_UP] = true;
|
search_dir[DIR_BI_DIR] = true;
|
||||||
search_dir[DIR_BI_DIR] = true;
|
search_dir[DIR_DIRECT] = true;
|
||||||
search_dir[DIR_DIRECT] = true;
|
|
||||||
} else {
|
|
||||||
search_dir[DIR_DOWN] = true;
|
|
||||||
search_dir[DIR_BI_DIR] = true;
|
|
||||||
search_dir[DIR_DIRECT] = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TxRxSelect == TX_DIR)
|
if (TxRxSelect == TX_DIR)
|
||||||
@ -208,9 +197,9 @@ static struct ts_common_info *SearchAdmitTRStream(struct rtllib_device *ieee,
|
|||||||
if (!search_dir[dir])
|
if (!search_dir[dir])
|
||||||
continue;
|
continue;
|
||||||
list_for_each_entry(pRet, psearch_list, List) {
|
list_for_each_entry(pRet, psearch_list, List) {
|
||||||
if (memcmp(pRet->Addr, Addr, 6) == 0 &&
|
if (memcmp(pRet->addr, addr, 6) == 0 &&
|
||||||
pRet->TSpec.f.TSInfo.field.ucTSID == TID &&
|
pRet->TSpec.ucTSID == TID &&
|
||||||
pRet->TSpec.f.TSInfo.field.ucDirection == dir)
|
pRet->TSpec.ucDirection == dir)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (&pRet->List != psearch_list)
|
if (&pRet->List != psearch_list)
|
||||||
@ -222,40 +211,30 @@ static struct ts_common_info *SearchAdmitTRStream(struct rtllib_device *ieee,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MakeTSEntry(struct ts_common_info *pTsCommonInfo, u8 *Addr,
|
static void MakeTSEntry(struct ts_common_info *pTsCommonInfo, u8 *addr,
|
||||||
union tspec_body *pTSPEC, union qos_tclas *pTCLAS,
|
struct qos_tsinfo *pTSPEC)
|
||||||
u8 TCLAS_Num, u8 TCLAS_Proc)
|
|
||||||
{
|
{
|
||||||
u8 count;
|
|
||||||
|
|
||||||
if (!pTsCommonInfo)
|
if (!pTsCommonInfo)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
memcpy(pTsCommonInfo->Addr, Addr, 6);
|
memcpy(pTsCommonInfo->addr, addr, 6);
|
||||||
|
|
||||||
if (pTSPEC)
|
if (pTSPEC)
|
||||||
memcpy((u8 *)(&(pTsCommonInfo->TSpec)), (u8 *)pTSPEC,
|
memcpy((u8 *)(&(pTsCommonInfo->TSpec)), (u8 *)pTSPEC,
|
||||||
sizeof(union tspec_body));
|
sizeof(struct qos_tsinfo));
|
||||||
|
|
||||||
for (count = 0; count < TCLAS_Num; count++)
|
|
||||||
memcpy((u8 *)(&(pTsCommonInfo->TClass[count])),
|
|
||||||
(u8 *)pTCLAS, sizeof(union qos_tclas));
|
|
||||||
|
|
||||||
pTsCommonInfo->TClasProc = TCLAS_Proc;
|
|
||||||
pTsCommonInfo->TClasNum = TCLAS_Num;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetTs(struct rtllib_device *ieee, struct ts_common_info **ppTS,
|
bool rtllib_get_ts(struct rtllib_device *ieee, struct ts_common_info **ppTS,
|
||||||
u8 *Addr, u8 TID, enum tr_select TxRxSelect, bool bAddNewTs)
|
u8 *addr, u8 TID, enum tr_select TxRxSelect, bool bAddNewTs)
|
||||||
{
|
{
|
||||||
u8 UP = 0;
|
u8 UP = 0;
|
||||||
union tspec_body TSpec;
|
struct qos_tsinfo TSpec;
|
||||||
union qos_tsinfo *pTSInfo = &TSpec.f.TSInfo;
|
struct qos_tsinfo *ts_info = &TSpec;
|
||||||
struct list_head *pUnusedList;
|
struct list_head *pUnusedList;
|
||||||
struct list_head *pAddmitList;
|
struct list_head *pAddmitList;
|
||||||
enum direction_value Dir;
|
enum direction_value Dir;
|
||||||
|
|
||||||
if (is_multicast_ether_addr(Addr)) {
|
if (is_multicast_ether_addr(addr)) {
|
||||||
netdev_warn(ieee->dev, "Get TS for Broadcast or Multicast\n");
|
netdev_warn(ieee->dev, "Get TS for Broadcast or Multicast\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -286,7 +265,7 @@ bool GetTs(struct rtllib_device *ieee, struct ts_common_info **ppTS,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*ppTS = SearchAdmitTRStream(ieee, Addr, UP, TxRxSelect);
|
*ppTS = SearchAdmitTRStream(ieee, addr, UP, TxRxSelect);
|
||||||
if (*ppTS)
|
if (*ppTS)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -316,27 +295,20 @@ bool GetTs(struct rtllib_device *ieee, struct ts_common_info **ppTS,
|
|||||||
TsCommonInfo);
|
TsCommonInfo);
|
||||||
ResetTxTsEntry(tmp);
|
ResetTxTsEntry(tmp);
|
||||||
} else {
|
} else {
|
||||||
struct rx_ts_record *tmp =
|
struct rx_ts_record *ts =
|
||||||
container_of(*ppTS,
|
container_of(*ppTS,
|
||||||
struct rx_ts_record,
|
struct rx_ts_record,
|
||||||
ts_common_info);
|
ts_common_info);
|
||||||
ResetRxTsEntry(tmp);
|
ResetRxTsEntry(ts);
|
||||||
}
|
}
|
||||||
|
|
||||||
netdev_dbg(ieee->dev,
|
netdev_dbg(ieee->dev,
|
||||||
"to init current TS, UP:%d, Dir:%d, addr: %pM ppTs=%p\n",
|
"to init current TS, UP:%d, Dir:%d, addr: %pM ppTs=%p\n",
|
||||||
UP, Dir, Addr, *ppTS);
|
UP, Dir, addr, *ppTS);
|
||||||
pTSInfo->field.ucTrafficType = 0;
|
ts_info->ucTSID = UP;
|
||||||
pTSInfo->field.ucTSID = UP;
|
ts_info->ucDirection = Dir;
|
||||||
pTSInfo->field.ucDirection = Dir;
|
|
||||||
pTSInfo->field.ucAccessPolicy = 1;
|
|
||||||
pTSInfo->field.ucAggregation = 0;
|
|
||||||
pTSInfo->field.ucPSB = 0;
|
|
||||||
pTSInfo->field.ucUP = UP;
|
|
||||||
pTSInfo->field.ucTSInfoAckPolicy = 0;
|
|
||||||
pTSInfo->field.ucSchedule = 0;
|
|
||||||
|
|
||||||
MakeTSEntry(*ppTS, Addr, &TSpec, NULL, 0, 0);
|
MakeTSEntry(*ppTS, addr, &TSpec);
|
||||||
list_add_tail(&((*ppTS)->List), pAddmitList);
|
list_add_tail(&((*ppTS)->List), pAddmitList);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -355,14 +327,14 @@ static void RemoveTsEntry(struct rtllib_device *ieee,
|
|||||||
|
|
||||||
if (TxRxSelect == RX_DIR) {
|
if (TxRxSelect == RX_DIR) {
|
||||||
struct rx_reorder_entry *pRxReorderEntry;
|
struct rx_reorder_entry *pRxReorderEntry;
|
||||||
struct rx_ts_record *pRxTS = (struct rx_ts_record *)pTs;
|
struct rx_ts_record *ts = (struct rx_ts_record *)pTs;
|
||||||
|
|
||||||
if (timer_pending(&pRxTS->rx_pkt_pending_timer))
|
if (timer_pending(&ts->rx_pkt_pending_timer))
|
||||||
del_timer_sync(&pRxTS->rx_pkt_pending_timer);
|
del_timer_sync(&ts->rx_pkt_pending_timer);
|
||||||
|
|
||||||
while (!list_empty(&pRxTS->rx_pending_pkt_list)) {
|
while (!list_empty(&ts->rx_pending_pkt_list)) {
|
||||||
pRxReorderEntry = (struct rx_reorder_entry *)
|
pRxReorderEntry = (struct rx_reorder_entry *)
|
||||||
list_entry(pRxTS->rx_pending_pkt_list.prev,
|
list_entry(ts->rx_pending_pkt_list.prev,
|
||||||
struct rx_reorder_entry, List);
|
struct rx_reorder_entry, List);
|
||||||
netdev_dbg(ieee->dev, "%s(): Delete SeqNum %d!\n",
|
netdev_dbg(ieee->dev, "%s(): Delete SeqNum %d!\n",
|
||||||
__func__, pRxReorderEntry->SeqNum);
|
__func__, pRxReorderEntry->SeqNum);
|
||||||
@ -388,43 +360,43 @@ static void RemoveTsEntry(struct rtllib_device *ieee,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemovePeerTS(struct rtllib_device *ieee, u8 *Addr)
|
void RemovePeerTS(struct rtllib_device *ieee, u8 *addr)
|
||||||
{
|
{
|
||||||
struct ts_common_info *pTS, *pTmpTS;
|
struct ts_common_info *ts, *pTmpTS;
|
||||||
|
|
||||||
netdev_info(ieee->dev, "===========>%s, %pM\n", __func__, Addr);
|
netdev_info(ieee->dev, "===========>%s, %pM\n", __func__, addr);
|
||||||
|
|
||||||
list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List) {
|
list_for_each_entry_safe(ts, pTmpTS, &ieee->Tx_TS_Pending_List, List) {
|
||||||
if (memcmp(pTS->Addr, Addr, 6) == 0) {
|
if (memcmp(ts->addr, addr, 6) == 0) {
|
||||||
RemoveTsEntry(ieee, pTS, TX_DIR);
|
RemoveTsEntry(ieee, ts, TX_DIR);
|
||||||
list_del_init(&pTS->List);
|
list_del_init(&ts->List);
|
||||||
list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List);
|
list_add_tail(&ts->List, &ieee->Tx_TS_Unused_List);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Admit_List, List) {
|
list_for_each_entry_safe(ts, pTmpTS, &ieee->Tx_TS_Admit_List, List) {
|
||||||
if (memcmp(pTS->Addr, Addr, 6) == 0) {
|
if (memcmp(ts->addr, addr, 6) == 0) {
|
||||||
netdev_info(ieee->dev,
|
netdev_info(ieee->dev,
|
||||||
"====>remove Tx_TS_admin_list\n");
|
"====>remove Tx_TS_admin_list\n");
|
||||||
RemoveTsEntry(ieee, pTS, TX_DIR);
|
RemoveTsEntry(ieee, ts, TX_DIR);
|
||||||
list_del_init(&pTS->List);
|
list_del_init(&ts->List);
|
||||||
list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List);
|
list_add_tail(&ts->List, &ieee->Tx_TS_Unused_List);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Pending_List, List) {
|
list_for_each_entry_safe(ts, pTmpTS, &ieee->Rx_TS_Pending_List, List) {
|
||||||
if (memcmp(pTS->Addr, Addr, 6) == 0) {
|
if (memcmp(ts->addr, addr, 6) == 0) {
|
||||||
RemoveTsEntry(ieee, pTS, RX_DIR);
|
RemoveTsEntry(ieee, ts, RX_DIR);
|
||||||
list_del_init(&pTS->List);
|
list_del_init(&ts->List);
|
||||||
list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List);
|
list_add_tail(&ts->List, &ieee->Rx_TS_Unused_List);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Admit_List, List) {
|
list_for_each_entry_safe(ts, pTmpTS, &ieee->Rx_TS_Admit_List, List) {
|
||||||
if (memcmp(pTS->Addr, Addr, 6) == 0) {
|
if (memcmp(ts->addr, addr, 6) == 0) {
|
||||||
RemoveTsEntry(ieee, pTS, RX_DIR);
|
RemoveTsEntry(ieee, ts, RX_DIR);
|
||||||
list_del_init(&pTS->List);
|
list_del_init(&ts->List);
|
||||||
list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List);
|
list_add_tail(&ts->List, &ieee->Rx_TS_Unused_List);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -432,30 +404,30 @@ EXPORT_SYMBOL(RemovePeerTS);
|
|||||||
|
|
||||||
void RemoveAllTS(struct rtllib_device *ieee)
|
void RemoveAllTS(struct rtllib_device *ieee)
|
||||||
{
|
{
|
||||||
struct ts_common_info *pTS, *pTmpTS;
|
struct ts_common_info *ts, *pTmpTS;
|
||||||
|
|
||||||
list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List) {
|
list_for_each_entry_safe(ts, pTmpTS, &ieee->Tx_TS_Pending_List, List) {
|
||||||
RemoveTsEntry(ieee, pTS, TX_DIR);
|
RemoveTsEntry(ieee, ts, TX_DIR);
|
||||||
list_del_init(&pTS->List);
|
list_del_init(&ts->List);
|
||||||
list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List);
|
list_add_tail(&ts->List, &ieee->Tx_TS_Unused_List);
|
||||||
}
|
}
|
||||||
|
|
||||||
list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Admit_List, List) {
|
list_for_each_entry_safe(ts, pTmpTS, &ieee->Tx_TS_Admit_List, List) {
|
||||||
RemoveTsEntry(ieee, pTS, TX_DIR);
|
RemoveTsEntry(ieee, ts, TX_DIR);
|
||||||
list_del_init(&pTS->List);
|
list_del_init(&ts->List);
|
||||||
list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List);
|
list_add_tail(&ts->List, &ieee->Tx_TS_Unused_List);
|
||||||
}
|
}
|
||||||
|
|
||||||
list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Pending_List, List) {
|
list_for_each_entry_safe(ts, pTmpTS, &ieee->Rx_TS_Pending_List, List) {
|
||||||
RemoveTsEntry(ieee, pTS, RX_DIR);
|
RemoveTsEntry(ieee, ts, RX_DIR);
|
||||||
list_del_init(&pTS->List);
|
list_del_init(&ts->List);
|
||||||
list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List);
|
list_add_tail(&ts->List, &ieee->Rx_TS_Unused_List);
|
||||||
}
|
}
|
||||||
|
|
||||||
list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Admit_List, List) {
|
list_for_each_entry_safe(ts, pTmpTS, &ieee->Rx_TS_Admit_List, List) {
|
||||||
RemoveTsEntry(ieee, pTS, RX_DIR);
|
RemoveTsEntry(ieee, ts, RX_DIR);
|
||||||
list_del_init(&pTS->List);
|
list_del_init(&ts->List);
|
||||||
list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List);
|
list_add_tail(&ts->List, &ieee->Rx_TS_Unused_List);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/wireless.h>
|
#include <linux/wireless.h>
|
||||||
|
|
||||||
#include "rtllib_debug.h"
|
|
||||||
#include "rtl819x_HT.h"
|
#include "rtl819x_HT.h"
|
||||||
#include "rtl819x_BA.h"
|
#include "rtl819x_BA.h"
|
||||||
#include "rtl819x_TS.h"
|
#include "rtl819x_TS.h"
|
||||||
@ -92,7 +91,7 @@ static inline void *netdev_priv_rsl(struct net_device *dev)
|
|||||||
#define IE_CISCO_FLAG_POSITION 0x08
|
#define IE_CISCO_FLAG_POSITION 0x08
|
||||||
#define SUPPORT_CKIP_MIC 0x08
|
#define SUPPORT_CKIP_MIC 0x08
|
||||||
#define SUPPORT_CKIP_PK 0x10
|
#define SUPPORT_CKIP_PK 0x10
|
||||||
#define RT_RF_OFF_LEVL_HALT_NIC BIT3
|
#define RT_RF_OFF_LEVL_HALT_NIC BIT(3)
|
||||||
#define RT_IN_PS_LEVEL(psc, _PS_FLAG) \
|
#define RT_IN_PS_LEVEL(psc, _PS_FLAG) \
|
||||||
((psc->CurPsLevel & _PS_FLAG) ? true : false)
|
((psc->CurPsLevel & _PS_FLAG) ? true : false)
|
||||||
#define RT_CLEAR_PS_LEVEL(psc, _PS_FLAG) \
|
#define RT_CLEAR_PS_LEVEL(psc, _PS_FLAG) \
|
||||||
@ -172,7 +171,7 @@ struct sw_chnl_cmd {
|
|||||||
u32 Para1;
|
u32 Para1;
|
||||||
u32 Para2;
|
u32 Para2;
|
||||||
u32 msDelay;
|
u32 msDelay;
|
||||||
} __packed;
|
};
|
||||||
|
|
||||||
/*--------------------------Define -------------------------------------------*/
|
/*--------------------------Define -------------------------------------------*/
|
||||||
#define MGN_1M 0x02
|
#define MGN_1M 0x02
|
||||||
@ -332,66 +331,23 @@ enum rt_op_mode {
|
|||||||
#define MIN_FRAG_THRESHOLD 256U
|
#define MIN_FRAG_THRESHOLD 256U
|
||||||
#define MAX_FRAG_THRESHOLD 2346U
|
#define MAX_FRAG_THRESHOLD 2346U
|
||||||
|
|
||||||
/* Frame control field constants */
|
|
||||||
#define RTLLIB_FCTL_FTYPE 0x000c
|
|
||||||
#define RTLLIB_FCTL_STYPE 0x00f0
|
|
||||||
#define RTLLIB_FCTL_FRAMETYPE 0x00fc
|
|
||||||
#define RTLLIB_FCTL_TODS 0x0100
|
|
||||||
#define RTLLIB_FCTL_FROMDS 0x0200
|
|
||||||
#define RTLLIB_FCTL_DSTODS 0x0300
|
|
||||||
#define RTLLIB_FCTL_MOREFRAGS 0x0400
|
|
||||||
#define RTLLIB_FCTL_RETRY 0x0800
|
|
||||||
#define RTLLIB_FCTL_PM 0x1000
|
|
||||||
#define RTLLIB_FCTL_MOREDATA 0x2000
|
|
||||||
#define RTLLIB_FCTL_WEP 0x4000
|
|
||||||
#define RTLLIB_FCTL_ORDER 0x8000
|
|
||||||
|
|
||||||
#define RTLLIB_FTYPE_MGMT 0x0000
|
#define RTLLIB_FTYPE_MGMT 0x0000
|
||||||
#define RTLLIB_FTYPE_CTL 0x0004
|
#define RTLLIB_FTYPE_CTL 0x0004
|
||||||
#define RTLLIB_FTYPE_DATA 0x0008
|
#define RTLLIB_FTYPE_DATA 0x0008
|
||||||
|
|
||||||
/* management */
|
|
||||||
#define RTLLIB_STYPE_ASSOC_REQ 0x0000
|
|
||||||
#define RTLLIB_STYPE_ASSOC_RESP 0x0010
|
|
||||||
#define RTLLIB_STYPE_REASSOC_REQ 0x0020
|
|
||||||
#define RTLLIB_STYPE_REASSOC_RESP 0x0030
|
|
||||||
#define RTLLIB_STYPE_PROBE_REQ 0x0040
|
|
||||||
#define RTLLIB_STYPE_PROBE_RESP 0x0050
|
|
||||||
#define RTLLIB_STYPE_BEACON 0x0080
|
|
||||||
#define RTLLIB_STYPE_ATIM 0x0090
|
|
||||||
#define RTLLIB_STYPE_DISASSOC 0x00A0
|
|
||||||
#define RTLLIB_STYPE_AUTH 0x00B0
|
|
||||||
#define RTLLIB_STYPE_DEAUTH 0x00C0
|
|
||||||
#define RTLLIB_STYPE_MANAGE_ACT 0x00D0
|
|
||||||
|
|
||||||
/* control */
|
|
||||||
#define RTLLIB_STYPE_PSPOLL 0x00A0
|
|
||||||
#define RTLLIB_STYPE_RTS 0x00B0
|
|
||||||
#define RTLLIB_STYPE_CTS 0x00C0
|
|
||||||
#define RTLLIB_STYPE_ACK 0x00D0
|
|
||||||
|
|
||||||
/* data */
|
|
||||||
#define RTLLIB_STYPE_DATA 0x0000
|
|
||||||
#define RTLLIB_STYPE_DATA_CFACK 0x0010
|
|
||||||
#define RTLLIB_STYPE_DATA_CFPOLL 0x0020
|
|
||||||
#define RTLLIB_STYPE_DATA_CFACKPOLL 0x0030
|
|
||||||
#define RTLLIB_STYPE_NULLFUNC 0x0040
|
|
||||||
#define RTLLIB_STYPE_QOS_DATA 0x0080
|
|
||||||
#define RTLLIB_STYPE_QOS_NULL 0x00C0
|
|
||||||
|
|
||||||
#define RTLLIB_SCTL_FRAG 0x000F
|
#define RTLLIB_SCTL_FRAG 0x000F
|
||||||
#define RTLLIB_SCTL_SEQ 0xFFF0
|
#define RTLLIB_SCTL_SEQ 0xFFF0
|
||||||
|
|
||||||
/* QOS control */
|
/* QOS control */
|
||||||
#define RTLLIB_QCTL_TID 0x000F
|
#define RTLLIB_QCTL_TID 0x000F
|
||||||
|
|
||||||
#define FC_QOS_BIT BIT7
|
#define FC_QOS_BIT BIT(7)
|
||||||
#define IsDataFrame(pdu) (((pdu[0] & 0x0C) == 0x08) ? true : false)
|
#define IsDataFrame(pdu) (((pdu[0] & 0x0C) == 0x08) ? true : false)
|
||||||
#define IsLegacyDataFrame(pdu) (IsDataFrame(pdu) && (!(pdu[0]&FC_QOS_BIT)))
|
#define IsLegacyDataFrame(pdu) (IsDataFrame(pdu) && (!(pdu[0]&FC_QOS_BIT)))
|
||||||
#define IsQoSDataFrame(pframe) \
|
#define IsQoSDataFrame(pframe) \
|
||||||
((*(u16 *)pframe&(RTLLIB_STYPE_QOS_DATA|RTLLIB_FTYPE_DATA)) == \
|
((*(u16 *)pframe&(IEEE80211_STYPE_QOS_DATA|RTLLIB_FTYPE_DATA)) == \
|
||||||
(RTLLIB_STYPE_QOS_DATA|RTLLIB_FTYPE_DATA))
|
(IEEE80211_STYPE_QOS_DATA|RTLLIB_FTYPE_DATA))
|
||||||
#define Frame_Order(pframe) (*(u16 *)pframe&RTLLIB_FCTL_ORDER)
|
#define Frame_Order(pframe) (*(u16 *)pframe&IEEE80211_FCTL_ORDER)
|
||||||
#define SN_LESS(a, b) (((a-b)&0x800) != 0)
|
#define SN_LESS(a, b) (((a-b)&0x800) != 0)
|
||||||
#define SN_EQUAL(a, b) (a == b)
|
#define SN_EQUAL(a, b) (a == b)
|
||||||
#define MAX_DEV_ADDR_SIZE 8
|
#define MAX_DEV_ADDR_SIZE 8
|
||||||
@ -455,11 +411,10 @@ enum _REG_PREAMBLE_MODE {
|
|||||||
|
|
||||||
#define SNAP_SIZE sizeof(struct rtllib_snap_hdr)
|
#define SNAP_SIZE sizeof(struct rtllib_snap_hdr)
|
||||||
|
|
||||||
#define WLAN_FC_GET_TYPE(fc) ((fc) & RTLLIB_FCTL_FTYPE)
|
#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE)
|
||||||
#define WLAN_FC_GET_STYPE(fc) ((fc) & RTLLIB_FCTL_STYPE)
|
#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE)
|
||||||
#define WLAN_FC_MORE_DATA(fc) ((fc) & RTLLIB_FCTL_MOREDATA)
|
#define WLAN_FC_MORE_DATA(fc) ((fc) & IEEE80211_FCTL_MOREDATA)
|
||||||
|
|
||||||
#define WLAN_FC_GET_FRAMETYPE(fc) ((fc) & RTLLIB_FCTL_FRAMETYPE)
|
|
||||||
#define WLAN_GET_SEQ_FRAG(seq) ((seq) & RTLLIB_SCTL_FRAG)
|
#define WLAN_GET_SEQ_FRAG(seq) ((seq) & RTLLIB_SCTL_FRAG)
|
||||||
#define WLAN_GET_SEQ_SEQ(seq) (((seq) & RTLLIB_SCTL_SEQ) >> 4)
|
#define WLAN_GET_SEQ_SEQ(seq) (((seq) & RTLLIB_SCTL_SEQ) >> 4)
|
||||||
|
|
||||||
@ -510,13 +465,6 @@ enum _REG_PREAMBLE_MODE {
|
|||||||
|
|
||||||
/* this is stolen from ipw2200 driver */
|
/* this is stolen from ipw2200 driver */
|
||||||
#define IEEE_IBSS_MAC_HASH_SIZE 31
|
#define IEEE_IBSS_MAC_HASH_SIZE 31
|
||||||
struct ieee_ibss_seq {
|
|
||||||
u8 mac[ETH_ALEN];
|
|
||||||
u16 seq_num[17];
|
|
||||||
u16 frag_num[17];
|
|
||||||
unsigned long packet_time[17];
|
|
||||||
struct list_head list;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* NOTE: This data is for statistical purposes; not all hardware provides this
|
/* NOTE: This data is for statistical purposes; not all hardware provides this
|
||||||
* information for frames received. Not setting these will not cause
|
* information for frames received. Not setting these will not cause
|
||||||
@ -673,78 +621,6 @@ enum rtllib_mfie {
|
|||||||
* information to determine what type of underlying data type is actually
|
* information to determine what type of underlying data type is actually
|
||||||
* stored in the data.
|
* stored in the data.
|
||||||
*/
|
*/
|
||||||
struct rtllib_pspoll_hdr {
|
|
||||||
__le16 frame_ctl;
|
|
||||||
__le16 aid;
|
|
||||||
u8 bssid[ETH_ALEN];
|
|
||||||
u8 ta[ETH_ALEN];
|
|
||||||
} __packed;
|
|
||||||
|
|
||||||
struct rtllib_hdr {
|
|
||||||
__le16 frame_ctl;
|
|
||||||
__le16 duration_id;
|
|
||||||
u8 payload[];
|
|
||||||
} __packed;
|
|
||||||
|
|
||||||
struct rtllib_hdr_1addr {
|
|
||||||
__le16 frame_ctl;
|
|
||||||
__le16 duration_id;
|
|
||||||
u8 addr1[ETH_ALEN];
|
|
||||||
u8 payload[];
|
|
||||||
} __packed;
|
|
||||||
|
|
||||||
struct rtllib_hdr_2addr {
|
|
||||||
__le16 frame_ctl;
|
|
||||||
__le16 duration_id;
|
|
||||||
u8 addr1[ETH_ALEN];
|
|
||||||
u8 addr2[ETH_ALEN];
|
|
||||||
u8 payload[];
|
|
||||||
} __packed;
|
|
||||||
|
|
||||||
struct rtllib_hdr_3addr {
|
|
||||||
__le16 frame_ctl;
|
|
||||||
__le16 duration_id;
|
|
||||||
u8 addr1[ETH_ALEN];
|
|
||||||
u8 addr2[ETH_ALEN];
|
|
||||||
u8 addr3[ETH_ALEN];
|
|
||||||
__le16 seq_ctl;
|
|
||||||
u8 payload[];
|
|
||||||
} __packed;
|
|
||||||
|
|
||||||
struct rtllib_hdr_4addr {
|
|
||||||
__le16 frame_ctl;
|
|
||||||
__le16 duration_id;
|
|
||||||
u8 addr1[ETH_ALEN];
|
|
||||||
u8 addr2[ETH_ALEN];
|
|
||||||
u8 addr3[ETH_ALEN];
|
|
||||||
__le16 seq_ctl;
|
|
||||||
u8 addr4[ETH_ALEN];
|
|
||||||
u8 payload[];
|
|
||||||
} __packed;
|
|
||||||
|
|
||||||
struct rtllib_hdr_3addrqos {
|
|
||||||
__le16 frame_ctl;
|
|
||||||
__le16 duration_id;
|
|
||||||
u8 addr1[ETH_ALEN];
|
|
||||||
u8 addr2[ETH_ALEN];
|
|
||||||
u8 addr3[ETH_ALEN];
|
|
||||||
__le16 seq_ctl;
|
|
||||||
__le16 qos_ctl;
|
|
||||||
u8 payload[];
|
|
||||||
} __packed;
|
|
||||||
|
|
||||||
struct rtllib_hdr_4addrqos {
|
|
||||||
__le16 frame_ctl;
|
|
||||||
__le16 duration_id;
|
|
||||||
u8 addr1[ETH_ALEN];
|
|
||||||
u8 addr2[ETH_ALEN];
|
|
||||||
u8 addr3[ETH_ALEN];
|
|
||||||
__le16 seq_ctl;
|
|
||||||
u8 addr4[ETH_ALEN];
|
|
||||||
__le16 qos_ctl;
|
|
||||||
u8 payload[];
|
|
||||||
} __packed;
|
|
||||||
|
|
||||||
struct rtllib_info_element {
|
struct rtllib_info_element {
|
||||||
u8 id;
|
u8 id;
|
||||||
u8 len;
|
u8 len;
|
||||||
@ -752,32 +628,32 @@ struct rtllib_info_element {
|
|||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
struct rtllib_authentication {
|
struct rtllib_authentication {
|
||||||
struct rtllib_hdr_3addr header;
|
struct ieee80211_hdr_3addr header;
|
||||||
__le16 algorithm;
|
__le16 algorithm;
|
||||||
__le16 transaction;
|
__le16 transaction;
|
||||||
__le16 status;
|
__le16 status;
|
||||||
/*challenge*/
|
/*challenge*/
|
||||||
struct rtllib_info_element info_element[];
|
struct rtllib_info_element info_element[];
|
||||||
} __packed;
|
} __packed __aligned(2);
|
||||||
|
|
||||||
struct rtllib_disauth {
|
struct rtllib_disauth {
|
||||||
struct rtllib_hdr_3addr header;
|
struct ieee80211_hdr_3addr header;
|
||||||
__le16 reason;
|
__le16 reason;
|
||||||
} __packed;
|
} __packed __aligned(2);
|
||||||
|
|
||||||
struct rtllib_disassoc {
|
struct rtllib_disassoc {
|
||||||
struct rtllib_hdr_3addr header;
|
struct ieee80211_hdr_3addr header;
|
||||||
__le16 reason;
|
__le16 reason;
|
||||||
} __packed;
|
} __packed __aligned(2);
|
||||||
|
|
||||||
struct rtllib_probe_request {
|
struct rtllib_probe_request {
|
||||||
struct rtllib_hdr_3addr header;
|
struct ieee80211_hdr_3addr header;
|
||||||
/* SSID, supported rates */
|
/* SSID, supported rates */
|
||||||
struct rtllib_info_element info_element[];
|
struct rtllib_info_element info_element[];
|
||||||
} __packed;
|
} __packed __aligned(2);
|
||||||
|
|
||||||
struct rtllib_probe_response {
|
struct rtllib_probe_response {
|
||||||
struct rtllib_hdr_3addr header;
|
struct ieee80211_hdr_3addr header;
|
||||||
u32 time_stamp[2];
|
u32 time_stamp[2];
|
||||||
__le16 beacon_interval;
|
__le16 beacon_interval;
|
||||||
__le16 capability;
|
__le16 capability;
|
||||||
@ -785,26 +661,26 @@ struct rtllib_probe_response {
|
|||||||
* CF params, IBSS params, TIM (if beacon), RSN
|
* CF params, IBSS params, TIM (if beacon), RSN
|
||||||
*/
|
*/
|
||||||
struct rtllib_info_element info_element[];
|
struct rtllib_info_element info_element[];
|
||||||
} __packed;
|
} __packed __aligned(2);
|
||||||
|
|
||||||
/* Alias beacon for probe_response */
|
/* Alias beacon for probe_response */
|
||||||
#define rtllib_beacon rtllib_probe_response
|
#define rtllib_beacon rtllib_probe_response
|
||||||
|
|
||||||
struct rtllib_assoc_request_frame {
|
struct rtllib_assoc_request_frame {
|
||||||
struct rtllib_hdr_3addr header;
|
struct ieee80211_hdr_3addr header;
|
||||||
__le16 capability;
|
__le16 capability;
|
||||||
__le16 listen_interval;
|
__le16 listen_interval;
|
||||||
/* SSID, supported rates, RSN */
|
/* SSID, supported rates, RSN */
|
||||||
struct rtllib_info_element info_element[];
|
struct rtllib_info_element info_element[];
|
||||||
} __packed;
|
} __packed __aligned(2);
|
||||||
|
|
||||||
struct rtllib_assoc_response_frame {
|
struct rtllib_assoc_response_frame {
|
||||||
struct rtllib_hdr_3addr header;
|
struct ieee80211_hdr_3addr header;
|
||||||
__le16 capability;
|
__le16 capability;
|
||||||
__le16 status;
|
__le16 status;
|
||||||
__le16 aid;
|
__le16 aid;
|
||||||
struct rtllib_info_element info_element[]; /* supported rates */
|
struct rtllib_info_element info_element[]; /* supported rates */
|
||||||
} __packed;
|
} __packed __aligned(2);
|
||||||
|
|
||||||
struct rtllib_txb {
|
struct rtllib_txb {
|
||||||
u8 nr_frags;
|
u8 nr_frags;
|
||||||
@ -823,7 +699,7 @@ struct rtllib_rxb {
|
|||||||
struct sk_buff *subframes[MAX_SUBFRAME_COUNT];
|
struct sk_buff *subframes[MAX_SUBFRAME_COUNT];
|
||||||
u8 dst[ETH_ALEN];
|
u8 dst[ETH_ALEN];
|
||||||
u8 src[ETH_ALEN];
|
u8 src[ETH_ALEN];
|
||||||
} __packed;
|
};
|
||||||
|
|
||||||
union frameqos {
|
union frameqos {
|
||||||
u16 shortdata;
|
u16 shortdata;
|
||||||
@ -947,13 +823,13 @@ static inline const char *eap_get_type(int type)
|
|||||||
|
|
||||||
static inline u8 Frame_QoSTID(u8 *buf)
|
static inline u8 Frame_QoSTID(u8 *buf)
|
||||||
{
|
{
|
||||||
struct rtllib_hdr_3addr *hdr;
|
struct ieee80211_hdr_3addr *hdr;
|
||||||
u16 fc;
|
u16 fc;
|
||||||
|
|
||||||
hdr = (struct rtllib_hdr_3addr *)buf;
|
hdr = (struct ieee80211_hdr_3addr *)buf;
|
||||||
fc = le16_to_cpu(hdr->frame_ctl);
|
fc = le16_to_cpu(hdr->frame_control);
|
||||||
return (u8)((union frameqos *)(buf + (((fc & RTLLIB_FCTL_TODS) &&
|
return (u8)((union frameqos *)(buf + (((fc & IEEE80211_FCTL_TODS) &&
|
||||||
(fc & RTLLIB_FCTL_FROMDS)) ? 30 : 24)))->field.tid;
|
(fc & IEEE80211_FCTL_FROMDS)) ? 30 : 24)))->field.tid;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct eapol {
|
struct eapol {
|
||||||
@ -1035,7 +911,6 @@ enum {WMM_all_frame, WMM_two_frame, WMM_four_frame, WMM_six_frame};
|
|||||||
((up) < 6) ? WME_AC_VI : \
|
((up) < 6) ? WME_AC_VI : \
|
||||||
WME_AC_VO)
|
WME_AC_VO)
|
||||||
|
|
||||||
#define ETHER_ADDR_LEN 6 /* length of an Ethernet address */
|
|
||||||
#define ETHERNET_HEADER_SIZE 14 /* length of two Ethernet address
|
#define ETHERNET_HEADER_SIZE 14 /* length of two Ethernet address
|
||||||
* plus ether type
|
* plus ether type
|
||||||
*/
|
*/
|
||||||
@ -1183,13 +1058,6 @@ enum fsync_state {
|
|||||||
SW_Fsync
|
SW_Fsync
|
||||||
};
|
};
|
||||||
|
|
||||||
enum rt_ps_mode {
|
|
||||||
eActive,
|
|
||||||
eMaxPs,
|
|
||||||
eFastPs,
|
|
||||||
eAutoPs,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum ips_callback_function {
|
enum ips_callback_function {
|
||||||
IPS_CALLBACK_NONE = 0,
|
IPS_CALLBACK_NONE = 0,
|
||||||
IPS_CALLBACK_MGNT_LINK_REQUEST = 1,
|
IPS_CALLBACK_MGNT_LINK_REQUEST = 1,
|
||||||
@ -1209,7 +1077,6 @@ struct rt_pwr_save_ctrl {
|
|||||||
|
|
||||||
bool bLeisurePs;
|
bool bLeisurePs;
|
||||||
u8 LpsIdleCount;
|
u8 LpsIdleCount;
|
||||||
u8 reg_max_lps_awake_intvl;
|
|
||||||
u8 LPSAwakeIntvl;
|
u8 LPSAwakeIntvl;
|
||||||
|
|
||||||
u32 CurPsLevel;
|
u32 CurPsLevel;
|
||||||
@ -1217,10 +1084,10 @@ struct rt_pwr_save_ctrl {
|
|||||||
|
|
||||||
#define RT_RF_CHANGE_SOURCE u32
|
#define RT_RF_CHANGE_SOURCE u32
|
||||||
|
|
||||||
#define RF_CHANGE_BY_SW BIT31
|
#define RF_CHANGE_BY_SW BIT(31)
|
||||||
#define RF_CHANGE_BY_HW BIT30
|
#define RF_CHANGE_BY_HW BIT(30)
|
||||||
#define RF_CHANGE_BY_PS BIT29
|
#define RF_CHANGE_BY_PS BIT(29)
|
||||||
#define RF_CHANGE_BY_IPS BIT28
|
#define RF_CHANGE_BY_IPS BIT(28)
|
||||||
#define RF_CHANGE_BY_INIT 0
|
#define RF_CHANGE_BY_INIT 0
|
||||||
|
|
||||||
enum country_code_type {
|
enum country_code_type {
|
||||||
@ -1246,33 +1113,6 @@ enum scan_op_backup_opt {
|
|||||||
SCAN_OPT_MAX
|
SCAN_OPT_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
enum fw_cmd_io_type {
|
|
||||||
FW_CMD_DIG_ENABLE = 0,
|
|
||||||
FW_CMD_DIG_DISABLE = 1,
|
|
||||||
FW_CMD_DIG_HALT = 2,
|
|
||||||
FW_CMD_DIG_RESUME = 3,
|
|
||||||
FW_CMD_HIGH_PWR_ENABLE = 4,
|
|
||||||
FW_CMD_HIGH_PWR_DISABLE = 5,
|
|
||||||
FW_CMD_RA_RESET = 6,
|
|
||||||
FW_CMD_RA_ACTIVE = 7,
|
|
||||||
FW_CMD_RA_REFRESH_N = 8,
|
|
||||||
FW_CMD_RA_REFRESH_BG = 9,
|
|
||||||
FW_CMD_RA_INIT = 10,
|
|
||||||
FW_CMD_IQK_ENABLE = 11,
|
|
||||||
FW_CMD_TXPWR_TRACK_ENABLE = 12,
|
|
||||||
FW_CMD_TXPWR_TRACK_DISABLE = 13,
|
|
||||||
FW_CMD_TXPWR_TRACK_THERMAL = 14,
|
|
||||||
FW_CMD_PAUSE_DM_BY_SCAN = 15,
|
|
||||||
FW_CMD_RESUME_DM_BY_SCAN = 16,
|
|
||||||
FW_CMD_RA_REFRESH_N_COMB = 17,
|
|
||||||
FW_CMD_RA_REFRESH_BG_COMB = 18,
|
|
||||||
FW_CMD_ANTENNA_SW_ENABLE = 19,
|
|
||||||
FW_CMD_ANTENNA_SW_DISABLE = 20,
|
|
||||||
FW_CMD_TX_FEEDBACK_CCX_ENABLE = 21,
|
|
||||||
FW_CMD_LPS_ENTER = 22,
|
|
||||||
FW_CMD_LPS_LEAVE = 23,
|
|
||||||
};
|
|
||||||
|
|
||||||
#define RT_MAX_LD_SLOT_NUM 10
|
#define RT_MAX_LD_SLOT_NUM 10
|
||||||
struct rt_link_detect {
|
struct rt_link_detect {
|
||||||
u32 NumRecvBcnInPeriod;
|
u32 NumRecvBcnInPeriod;
|
||||||
@ -1303,7 +1143,6 @@ struct sw_cam_table {
|
|||||||
|
|
||||||
#define TOTAL_CAM_ENTRY 32
|
#define TOTAL_CAM_ENTRY 32
|
||||||
struct rate_adaptive {
|
struct rate_adaptive {
|
||||||
u8 rate_adaptive_disabled;
|
|
||||||
u8 ratr_state;
|
u8 ratr_state;
|
||||||
u16 reserve;
|
u16 reserve;
|
||||||
|
|
||||||
@ -1321,7 +1160,6 @@ struct rate_adaptive {
|
|||||||
u8 ping_rssi_enable;
|
u8 ping_rssi_enable;
|
||||||
u32 ping_rssi_ratr;
|
u32 ping_rssi_ratr;
|
||||||
u32 ping_rssi_thresh_for_ra;
|
u32 ping_rssi_thresh_for_ra;
|
||||||
u32 last_ratr;
|
|
||||||
u8 PreRATRState;
|
u8 PreRATRState;
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -1334,11 +1172,6 @@ struct rt_pmkid_list {
|
|||||||
u8 bUsed;
|
u8 bUsed;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rt_intel_promisc_mode {
|
|
||||||
bool promiscuous_on;
|
|
||||||
bool fltr_src_sta_frame;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*************** DRIVER STATUS *****/
|
/*************** DRIVER STATUS *****/
|
||||||
#define STATUS_SCANNING 0
|
#define STATUS_SCANNING 0
|
||||||
/*************** DRIVER STATUS *****/
|
/*************** DRIVER STATUS *****/
|
||||||
@ -1368,7 +1201,6 @@ struct rtllib_device {
|
|||||||
bool bForcedBgMode;
|
bool bForcedBgMode;
|
||||||
|
|
||||||
u8 hwsec_active;
|
u8 hwsec_active;
|
||||||
bool is_silent_reset;
|
|
||||||
bool is_roaming;
|
bool is_roaming;
|
||||||
bool ieee_up;
|
bool ieee_up;
|
||||||
bool cannot_notify;
|
bool cannot_notify;
|
||||||
@ -1418,8 +1250,6 @@ struct rtllib_device {
|
|||||||
int scan_age;
|
int scan_age;
|
||||||
|
|
||||||
int iw_mode; /* operating mode (IW_MODE_*) */
|
int iw_mode; /* operating mode (IW_MODE_*) */
|
||||||
bool net_promiscuous_md;
|
|
||||||
struct rt_intel_promisc_mode intel_promiscuous_md_info;
|
|
||||||
|
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
spinlock_t wpax_suitlist_lock;
|
spinlock_t wpax_suitlist_lock;
|
||||||
@ -1496,13 +1326,10 @@ struct rtllib_device {
|
|||||||
u8 active_channel_map[MAX_CHANNEL_NUMBER+1];
|
u8 active_channel_map[MAX_CHANNEL_NUMBER+1];
|
||||||
|
|
||||||
u8 bss_start_channel;
|
u8 bss_start_channel;
|
||||||
u8 ibss_maxjoin_chal;
|
|
||||||
|
|
||||||
int rate; /* current rate */
|
int rate; /* current rate */
|
||||||
int basic_rate;
|
int basic_rate;
|
||||||
|
|
||||||
short active_scan;
|
|
||||||
|
|
||||||
/* this contains flags for selectively enable softmac support */
|
/* this contains flags for selectively enable softmac support */
|
||||||
u16 softmac_features;
|
u16 softmac_features;
|
||||||
|
|
||||||
@ -1525,7 +1352,6 @@ struct rtllib_device {
|
|||||||
u64 ps_time;
|
u64 ps_time;
|
||||||
bool polling;
|
bool polling;
|
||||||
|
|
||||||
short raw_tx;
|
|
||||||
/* used if IEEE_SOFTMAC_TX_QUEUE is set */
|
/* used if IEEE_SOFTMAC_TX_QUEUE is set */
|
||||||
short queue_stop;
|
short queue_stop;
|
||||||
short scanning_continue;
|
short scanning_continue;
|
||||||
@ -1602,7 +1428,6 @@ struct rtllib_device {
|
|||||||
struct delayed_work associate_procedure_wq;
|
struct delayed_work associate_procedure_wq;
|
||||||
struct delayed_work softmac_scan_wq;
|
struct delayed_work softmac_scan_wq;
|
||||||
struct delayed_work associate_retry_wq;
|
struct delayed_work associate_retry_wq;
|
||||||
struct delayed_work start_ibss_wq;
|
|
||||||
struct delayed_work hw_wakeup_wq;
|
struct delayed_work hw_wakeup_wq;
|
||||||
struct delayed_work hw_sleep_wq;
|
struct delayed_work hw_sleep_wq;
|
||||||
struct delayed_work link_change_wq;
|
struct delayed_work link_change_wq;
|
||||||
@ -1653,15 +1478,6 @@ struct rtllib_device {
|
|||||||
*/
|
*/
|
||||||
void (*link_change)(struct net_device *dev);
|
void (*link_change)(struct net_device *dev);
|
||||||
|
|
||||||
/* these two function indicates to the HW when to start
|
|
||||||
* and stop to send beacons. This is used when the
|
|
||||||
* IEEE_SOFTMAC_BEACONS is not set. For now the
|
|
||||||
* stop_send_bacons is NOT guaranteed to be called only
|
|
||||||
* after start_send_beacons.
|
|
||||||
*/
|
|
||||||
void (*start_send_beacons)(struct net_device *dev);
|
|
||||||
void (*stop_send_beacons)(struct net_device *dev);
|
|
||||||
|
|
||||||
/* power save mode related */
|
/* power save mode related */
|
||||||
void (*sta_wake_up)(struct net_device *dev);
|
void (*sta_wake_up)(struct net_device *dev);
|
||||||
void (*enter_sleep_state)(struct net_device *dev, u64 time);
|
void (*enter_sleep_state)(struct net_device *dev, u64 time);
|
||||||
@ -1761,15 +1577,15 @@ static inline int rtllib_get_hdrlen(u16 fc)
|
|||||||
|
|
||||||
switch (WLAN_FC_GET_TYPE(fc)) {
|
switch (WLAN_FC_GET_TYPE(fc)) {
|
||||||
case RTLLIB_FTYPE_DATA:
|
case RTLLIB_FTYPE_DATA:
|
||||||
if ((fc & RTLLIB_FCTL_FROMDS) && (fc & RTLLIB_FCTL_TODS))
|
if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
|
||||||
hdrlen = RTLLIB_4ADDR_LEN; /* Addr4 */
|
hdrlen = RTLLIB_4ADDR_LEN; /* Addr4 */
|
||||||
if (RTLLIB_QOS_HAS_SEQ(fc))
|
if (RTLLIB_QOS_HAS_SEQ(fc))
|
||||||
hdrlen += 2; /* QOS ctrl*/
|
hdrlen += 2; /* QOS ctrl*/
|
||||||
break;
|
break;
|
||||||
case RTLLIB_FTYPE_CTL:
|
case RTLLIB_FTYPE_CTL:
|
||||||
switch (WLAN_FC_GET_STYPE(fc)) {
|
switch (WLAN_FC_GET_STYPE(fc)) {
|
||||||
case RTLLIB_STYPE_CTS:
|
case IEEE80211_STYPE_CTS:
|
||||||
case RTLLIB_STYPE_ACK:
|
case IEEE80211_STYPE_ACK:
|
||||||
hdrlen = RTLLIB_1ADDR_LEN;
|
hdrlen = RTLLIB_1ADDR_LEN;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -1782,21 +1598,6 @@ static inline int rtllib_get_hdrlen(u16 fc)
|
|||||||
return hdrlen;
|
return hdrlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline u8 *rtllib_get_payload(struct rtllib_hdr *hdr)
|
|
||||||
{
|
|
||||||
switch (rtllib_get_hdrlen(le16_to_cpu(hdr->frame_ctl))) {
|
|
||||||
case RTLLIB_1ADDR_LEN:
|
|
||||||
return ((struct rtllib_hdr_1addr *)hdr)->payload;
|
|
||||||
case RTLLIB_2ADDR_LEN:
|
|
||||||
return ((struct rtllib_hdr_2addr *)hdr)->payload;
|
|
||||||
case RTLLIB_3ADDR_LEN:
|
|
||||||
return ((struct rtllib_hdr_3addr *)hdr)->payload;
|
|
||||||
case RTLLIB_4ADDR_LEN:
|
|
||||||
return ((struct rtllib_hdr_4addr *)hdr)->payload;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int rtllib_is_ofdm_rate(u8 rate)
|
static inline int rtllib_is_ofdm_rate(u8 rate)
|
||||||
{
|
{
|
||||||
switch (rate & ~RTLLIB_BASIC_RATE_MASK) {
|
switch (rate & ~RTLLIB_BASIC_RATE_MASK) {
|
||||||
@ -1841,8 +1642,6 @@ void rtllib_txb_free(struct rtllib_txb *txb);
|
|||||||
/* rtllib_rx.c */
|
/* rtllib_rx.c */
|
||||||
int rtllib_rx(struct rtllib_device *ieee, struct sk_buff *skb,
|
int rtllib_rx(struct rtllib_device *ieee, struct sk_buff *skb,
|
||||||
struct rtllib_rx_stats *rx_stats);
|
struct rtllib_rx_stats *rx_stats);
|
||||||
void rtllib_rx_probe_rq(struct rtllib_device *ieee,
|
|
||||||
struct sk_buff *skb);
|
|
||||||
int rtllib_legal_channel(struct rtllib_device *rtllib, u8 channel);
|
int rtllib_legal_channel(struct rtllib_device *rtllib, u8 channel);
|
||||||
|
|
||||||
/* rtllib_wx.c */
|
/* rtllib_wx.c */
|
||||||
@ -1876,7 +1675,6 @@ void rtllib_softmac_new_net(struct rtllib_device *ieee,
|
|||||||
void SendDisassociation(struct rtllib_device *ieee, bool deauth, u16 asRsn);
|
void SendDisassociation(struct rtllib_device *ieee, bool deauth, u16 asRsn);
|
||||||
void rtllib_softmac_xmit(struct rtllib_txb *txb, struct rtllib_device *ieee);
|
void rtllib_softmac_xmit(struct rtllib_txb *txb, struct rtllib_device *ieee);
|
||||||
|
|
||||||
void rtllib_start_ibss(struct rtllib_device *ieee);
|
|
||||||
int rtllib_softmac_init(struct rtllib_device *ieee);
|
int rtllib_softmac_init(struct rtllib_device *ieee);
|
||||||
void rtllib_softmac_free(struct rtllib_device *ieee);
|
void rtllib_softmac_free(struct rtllib_device *ieee);
|
||||||
void rtllib_disassociate(struct rtllib_device *ieee);
|
void rtllib_disassociate(struct rtllib_device *ieee);
|
||||||
@ -1887,23 +1685,18 @@ void rtllib_start_scan_syncro(struct rtllib_device *ieee);
|
|||||||
void rtllib_sta_ps_send_null_frame(struct rtllib_device *ieee, short pwr);
|
void rtllib_sta_ps_send_null_frame(struct rtllib_device *ieee, short pwr);
|
||||||
void rtllib_sta_ps_send_pspoll_frame(struct rtllib_device *ieee);
|
void rtllib_sta_ps_send_pspoll_frame(struct rtllib_device *ieee);
|
||||||
void rtllib_start_protocol(struct rtllib_device *ieee);
|
void rtllib_start_protocol(struct rtllib_device *ieee);
|
||||||
void rtllib_stop_protocol(struct rtllib_device *ieee, u8 shutdown);
|
void rtllib_stop_protocol(struct rtllib_device *ieee);
|
||||||
|
|
||||||
void rtllib_EnableNetMonitorMode(struct net_device *dev, bool bInitState);
|
void rtllib_EnableNetMonitorMode(struct net_device *dev, bool bInitState);
|
||||||
void rtllib_DisableNetMonitorMode(struct net_device *dev, bool bInitState);
|
void rtllib_DisableNetMonitorMode(struct net_device *dev, bool bInitState);
|
||||||
void rtllib_EnableIntelPromiscuousMode(struct net_device *dev, bool bInitState);
|
|
||||||
void rtllib_DisableIntelPromiscuousMode(struct net_device *dev,
|
void rtllib_softmac_stop_protocol(struct rtllib_device *ieee);
|
||||||
bool bInitState);
|
void rtllib_softmac_start_protocol(struct rtllib_device *ieee);
|
||||||
void rtllib_softmac_stop_protocol(struct rtllib_device *ieee,
|
|
||||||
u8 mesh_flag, u8 shutdown);
|
|
||||||
void rtllib_softmac_start_protocol(struct rtllib_device *ieee, u8 mesh_flag);
|
|
||||||
|
|
||||||
void rtllib_reset_queue(struct rtllib_device *ieee);
|
void rtllib_reset_queue(struct rtllib_device *ieee);
|
||||||
void rtllib_wake_all_queues(struct rtllib_device *ieee);
|
void rtllib_wake_all_queues(struct rtllib_device *ieee);
|
||||||
void rtllib_stop_all_queues(struct rtllib_device *ieee);
|
void rtllib_stop_all_queues(struct rtllib_device *ieee);
|
||||||
struct sk_buff *rtllib_get_beacon(struct rtllib_device *ieee);
|
struct sk_buff *rtllib_get_beacon(struct rtllib_device *ieee);
|
||||||
void rtllib_start_send_beacons(struct rtllib_device *ieee);
|
|
||||||
void rtllib_stop_send_beacons(struct rtllib_device *ieee);
|
|
||||||
|
|
||||||
void notify_wx_assoc_event(struct rtllib_device *ieee);
|
void notify_wx_assoc_event(struct rtllib_device *ieee);
|
||||||
void rtllib_ps_tx_ack(struct rtllib_device *ieee, short success);
|
void rtllib_ps_tx_ack(struct rtllib_device *ieee, short success);
|
||||||
@ -1947,10 +1740,6 @@ int rtllib_wx_get_freq(struct rtllib_device *ieee, struct iw_request_info *a,
|
|||||||
union iwreq_data *wrqu, char *b);
|
union iwreq_data *wrqu, char *b);
|
||||||
void rtllib_wx_sync_scan_wq(void *data);
|
void rtllib_wx_sync_scan_wq(void *data);
|
||||||
|
|
||||||
int rtllib_wx_set_rawtx(struct rtllib_device *ieee,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *extra);
|
|
||||||
|
|
||||||
int rtllib_wx_get_name(struct rtllib_device *ieee, struct iw_request_info *info,
|
int rtllib_wx_get_name(struct rtllib_device *ieee, struct iw_request_info *info,
|
||||||
union iwreq_data *wrqu, char *extra);
|
union iwreq_data *wrqu, char *extra);
|
||||||
|
|
||||||
@ -1972,7 +1761,7 @@ int rtllib_wx_get_rts(struct rtllib_device *ieee, struct iw_request_info *info,
|
|||||||
void HTSetConnectBwMode(struct rtllib_device *ieee,
|
void HTSetConnectBwMode(struct rtllib_device *ieee,
|
||||||
enum ht_channel_width bandwidth,
|
enum ht_channel_width bandwidth,
|
||||||
enum ht_extchnl_offset Offset);
|
enum ht_extchnl_offset Offset);
|
||||||
void HTUpdateDefaultSetting(struct rtllib_device *ieee);
|
void ht_update_default_setting(struct rtllib_device *ieee);
|
||||||
void HTConstructCapabilityElement(struct rtllib_device *ieee,
|
void HTConstructCapabilityElement(struct rtllib_device *ieee,
|
||||||
u8 *posHTCap, u8 *len,
|
u8 *posHTCap, u8 *len,
|
||||||
u8 isEncrypt, bool bAssoc);
|
u8 isEncrypt, bool bAssoc);
|
||||||
@ -1998,21 +1787,21 @@ u16 TxCountToDataRate(struct rtllib_device *ieee, u8 nDataRate);
|
|||||||
int rtllib_rx_ADDBAReq(struct rtllib_device *ieee, struct sk_buff *skb);
|
int rtllib_rx_ADDBAReq(struct rtllib_device *ieee, struct sk_buff *skb);
|
||||||
int rtllib_rx_ADDBARsp(struct rtllib_device *ieee, struct sk_buff *skb);
|
int rtllib_rx_ADDBARsp(struct rtllib_device *ieee, struct sk_buff *skb);
|
||||||
int rtllib_rx_DELBA(struct rtllib_device *ieee, struct sk_buff *skb);
|
int rtllib_rx_DELBA(struct rtllib_device *ieee, struct sk_buff *skb);
|
||||||
void rtllib_ts_init_add_ba(struct rtllib_device *ieee, struct tx_ts_record *pTS,
|
void rtllib_ts_init_add_ba(struct rtllib_device *ieee, struct tx_ts_record *ts,
|
||||||
u8 Policy, u8 bOverwritePending);
|
u8 policy, u8 bOverwritePending);
|
||||||
void rtllib_ts_init_del_ba(struct rtllib_device *ieee,
|
void rtllib_ts_init_del_ba(struct rtllib_device *ieee,
|
||||||
struct ts_common_info *pTsCommonInfo,
|
struct ts_common_info *pTsCommonInfo,
|
||||||
enum tr_select TxRxSelect);
|
enum tr_select TxRxSelect);
|
||||||
void rtllib_ba_setup_timeout(struct timer_list *t);
|
void rtllib_ba_setup_timeout(struct timer_list *t);
|
||||||
void rtllib_tx_ba_inact_timeout(struct timer_list *t);
|
void rtllib_tx_ba_inact_timeout(struct timer_list *t);
|
||||||
void rtllib_rx_ba_inact_timeout(struct timer_list *t);
|
void rtllib_rx_ba_inact_timeout(struct timer_list *t);
|
||||||
void rtllib_reset_ba_entry(struct ba_record *pBA);
|
void rtllib_reset_ba_entry(struct ba_record *ba);
|
||||||
bool GetTs(struct rtllib_device *ieee, struct ts_common_info **ppTS, u8 *Addr,
|
bool rtllib_get_ts(struct rtllib_device *ieee, struct ts_common_info **ppTS, u8 *addr,
|
||||||
u8 TID, enum tr_select TxRxSelect, bool bAddNewTs);
|
u8 TID, enum tr_select TxRxSelect, bool bAddNewTs);
|
||||||
void TSInitialize(struct rtllib_device *ieee);
|
void rtllib_ts_init(struct rtllib_device *ieee);
|
||||||
void TsStartAddBaProcess(struct rtllib_device *ieee,
|
void TsStartAddBaProcess(struct rtllib_device *ieee,
|
||||||
struct tx_ts_record *pTxTS);
|
struct tx_ts_record *pTxTS);
|
||||||
void RemovePeerTS(struct rtllib_device *ieee, u8 *Addr);
|
void RemovePeerTS(struct rtllib_device *ieee, u8 *addr);
|
||||||
void RemoveAllTS(struct rtllib_device *ieee);
|
void RemoveAllTS(struct rtllib_device *ieee);
|
||||||
|
|
||||||
static inline const char *escape_essid(const char *essid, u8 essid_len)
|
static inline const char *escape_essid(const char *essid, u8 essid_len)
|
||||||
@ -2035,7 +1824,7 @@ bool rtllib_MgntDisconnect(struct rtllib_device *rtllib, u8 asRsn);
|
|||||||
* ieee handler to refer to it.
|
* ieee handler to refer to it.
|
||||||
*/
|
*/
|
||||||
void rtllib_FlushRxTsPendingPkts(struct rtllib_device *ieee,
|
void rtllib_FlushRxTsPendingPkts(struct rtllib_device *ieee,
|
||||||
struct rx_ts_record *pTS);
|
struct rx_ts_record *ts);
|
||||||
int rtllib_parse_info_param(struct rtllib_device *ieee,
|
int rtllib_parse_info_param(struct rtllib_device *ieee,
|
||||||
struct rtllib_info_element *info_element,
|
struct rtllib_info_element *info_element,
|
||||||
u16 length,
|
u16 length,
|
||||||
@ -2044,7 +1833,6 @@ int rtllib_parse_info_param(struct rtllib_device *ieee,
|
|||||||
|
|
||||||
void rtllib_indicate_packets(struct rtllib_device *ieee,
|
void rtllib_indicate_packets(struct rtllib_device *ieee,
|
||||||
struct rtllib_rxb **prxbIndicateArray, u8 index);
|
struct rtllib_rxb **prxbIndicateArray, u8 index);
|
||||||
void HTUseDefaultSetting(struct rtllib_device *ieee);
|
|
||||||
#define RT_ASOC_RETRY_LIMIT 5
|
#define RT_ASOC_RETRY_LIMIT 5
|
||||||
u8 MgntQuery_TxRateExcludeCCKRates(struct rtllib_device *ieee);
|
u8 MgntQuery_TxRateExcludeCCKRates(struct rtllib_device *ieee);
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ static void *rtllib_ccmp_init(int key_idx)
|
|||||||
struct rtllib_ccmp_data *priv;
|
struct rtllib_ccmp_data *priv;
|
||||||
|
|
||||||
priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
|
priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
|
||||||
if (priv == NULL)
|
if (!priv)
|
||||||
goto fail;
|
goto fail;
|
||||||
priv->key_idx = key_idx;
|
priv->key_idx = key_idx;
|
||||||
|
|
||||||
@ -83,7 +83,7 @@ static void rtllib_ccmp_deinit(void *priv)
|
|||||||
kfree(priv);
|
kfree(priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ccmp_init_iv_and_aad(struct rtllib_hdr_4addr *hdr,
|
static int ccmp_init_iv_and_aad(struct ieee80211_hdr *hdr,
|
||||||
u8 *pn, u8 *iv, u8 *aad)
|
u8 *pn, u8 *iv, u8 *aad)
|
||||||
{
|
{
|
||||||
u8 *pos, qc = 0;
|
u8 *pos, qc = 0;
|
||||||
@ -91,9 +91,8 @@ static int ccmp_init_iv_and_aad(struct rtllib_hdr_4addr *hdr,
|
|||||||
u16 fc;
|
u16 fc;
|
||||||
int a4_included, qc_included;
|
int a4_included, qc_included;
|
||||||
|
|
||||||
fc = le16_to_cpu(hdr->frame_ctl);
|
fc = le16_to_cpu(hdr->frame_control);
|
||||||
a4_included = ((fc & (RTLLIB_FCTL_TODS | RTLLIB_FCTL_FROMDS)) ==
|
a4_included = ieee80211_has_a4(hdr->frame_control);
|
||||||
(RTLLIB_FCTL_TODS | RTLLIB_FCTL_FROMDS));
|
|
||||||
|
|
||||||
qc_included = ((WLAN_FC_GET_TYPE(fc) == RTLLIB_FTYPE_DATA) &&
|
qc_included = ((WLAN_FC_GET_TYPE(fc) == RTLLIB_FTYPE_DATA) &&
|
||||||
(WLAN_FC_GET_STYPE(fc) & 0x80));
|
(WLAN_FC_GET_STYPE(fc) & 0x80));
|
||||||
@ -134,7 +133,7 @@ static int ccmp_init_iv_and_aad(struct rtllib_hdr_4addr *hdr,
|
|||||||
memcpy(&aad[2], &hdr->addr1, ETH_ALEN);
|
memcpy(&aad[2], &hdr->addr1, ETH_ALEN);
|
||||||
memcpy(&aad[8], &hdr->addr2, ETH_ALEN);
|
memcpy(&aad[8], &hdr->addr2, ETH_ALEN);
|
||||||
memcpy(&aad[14], &hdr->addr3, ETH_ALEN);
|
memcpy(&aad[14], &hdr->addr3, ETH_ALEN);
|
||||||
pos = (u8 *)&hdr->seq_ctl;
|
pos = (u8 *)&hdr->seq_ctrl;
|
||||||
aad[20] = pos[0] & 0x0f;
|
aad[20] = pos[0] & 0x0f;
|
||||||
aad[21] = 0; /* all bits masked */
|
aad[21] = 0; /* all bits masked */
|
||||||
memset(aad + 22, 0, 8);
|
memset(aad + 22, 0, 8);
|
||||||
@ -153,7 +152,7 @@ static int rtllib_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
|||||||
struct rtllib_ccmp_data *key = priv;
|
struct rtllib_ccmp_data *key = priv;
|
||||||
int i;
|
int i;
|
||||||
u8 *pos;
|
u8 *pos;
|
||||||
struct rtllib_hdr_4addr *hdr;
|
struct ieee80211_hdr *hdr;
|
||||||
struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb +
|
struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb +
|
||||||
MAX_DEV_ADDR_SIZE);
|
MAX_DEV_ADDR_SIZE);
|
||||||
if (skb_headroom(skb) < CCMP_HDR_LEN ||
|
if (skb_headroom(skb) < CCMP_HDR_LEN ||
|
||||||
@ -182,7 +181,7 @@ static int rtllib_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
|||||||
*pos++ = key->tx_pn[1];
|
*pos++ = key->tx_pn[1];
|
||||||
*pos++ = key->tx_pn[0];
|
*pos++ = key->tx_pn[0];
|
||||||
|
|
||||||
hdr = (struct rtllib_hdr_4addr *)skb->data;
|
hdr = (struct ieee80211_hdr *)skb->data;
|
||||||
if (!tcb_desc->bHwSec) {
|
if (!tcb_desc->bHwSec) {
|
||||||
struct aead_request *req;
|
struct aead_request *req;
|
||||||
struct scatterlist sg[2];
|
struct scatterlist sg[2];
|
||||||
@ -220,7 +219,7 @@ static int rtllib_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
|||||||
{
|
{
|
||||||
struct rtllib_ccmp_data *key = priv;
|
struct rtllib_ccmp_data *key = priv;
|
||||||
u8 keyidx, *pos;
|
u8 keyidx, *pos;
|
||||||
struct rtllib_hdr_4addr *hdr;
|
struct ieee80211_hdr *hdr;
|
||||||
struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb +
|
struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb +
|
||||||
MAX_DEV_ADDR_SIZE);
|
MAX_DEV_ADDR_SIZE);
|
||||||
u8 pn[6];
|
u8 pn[6];
|
||||||
@ -230,7 +229,7 @@ static int rtllib_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
hdr = (struct rtllib_hdr_4addr *)skb->data;
|
hdr = (struct ieee80211_hdr *)skb->data;
|
||||||
pos = skb->data + hdr_len;
|
pos = skb->data + hdr_len;
|
||||||
keyidx = pos[3];
|
keyidx = pos[3];
|
||||||
if (!(keyidx & (1 << 5))) {
|
if (!(keyidx & (1 << 5))) {
|
||||||
|
@ -255,7 +255,7 @@ static int rtllib_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
|||||||
struct rtllib_tkip_data *tkey = priv;
|
struct rtllib_tkip_data *tkey = priv;
|
||||||
int len;
|
int len;
|
||||||
u8 *pos;
|
u8 *pos;
|
||||||
struct rtllib_hdr_4addr *hdr;
|
struct ieee80211_hdr *hdr;
|
||||||
struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb +
|
struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb +
|
||||||
MAX_DEV_ADDR_SIZE);
|
MAX_DEV_ADDR_SIZE);
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@ -266,7 +266,7 @@ static int rtllib_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
|||||||
skb->len < hdr_len)
|
skb->len < hdr_len)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
hdr = (struct rtllib_hdr_4addr *)skb->data;
|
hdr = (struct ieee80211_hdr *)skb->data;
|
||||||
|
|
||||||
if (!tcb_desc->bHwSec) {
|
if (!tcb_desc->bHwSec) {
|
||||||
if (!tkey->tx_phase1_done) {
|
if (!tkey->tx_phase1_done) {
|
||||||
@ -330,7 +330,7 @@ static int rtllib_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
|||||||
u8 keyidx, *pos;
|
u8 keyidx, *pos;
|
||||||
u32 iv32;
|
u32 iv32;
|
||||||
u16 iv16;
|
u16 iv16;
|
||||||
struct rtllib_hdr_4addr *hdr;
|
struct ieee80211_hdr *hdr;
|
||||||
struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb +
|
struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb +
|
||||||
MAX_DEV_ADDR_SIZE);
|
MAX_DEV_ADDR_SIZE);
|
||||||
u8 rc4key[16];
|
u8 rc4key[16];
|
||||||
@ -341,7 +341,7 @@ static int rtllib_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
|||||||
if (skb->len < hdr_len + 8 + 4)
|
if (skb->len < hdr_len + 8 + 4)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
hdr = (struct rtllib_hdr_4addr *)skb->data;
|
hdr = (struct ieee80211_hdr *)skb->data;
|
||||||
pos = skb->data + hdr_len;
|
pos = skb->data + hdr_len;
|
||||||
keyidx = pos[3];
|
keyidx = pos[3];
|
||||||
if (!(keyidx & (1 << 5))) {
|
if (!(keyidx & (1 << 5))) {
|
||||||
@ -465,20 +465,20 @@ out:
|
|||||||
|
|
||||||
static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr)
|
static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr)
|
||||||
{
|
{
|
||||||
struct rtllib_hdr_4addr *hdr11;
|
struct ieee80211_hdr *hdr11;
|
||||||
|
|
||||||
hdr11 = (struct rtllib_hdr_4addr *)skb->data;
|
hdr11 = (struct ieee80211_hdr *)skb->data;
|
||||||
switch (le16_to_cpu(hdr11->frame_ctl) &
|
switch (le16_to_cpu(hdr11->frame_control) &
|
||||||
(RTLLIB_FCTL_FROMDS | RTLLIB_FCTL_TODS)) {
|
(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
|
||||||
case RTLLIB_FCTL_TODS:
|
case IEEE80211_FCTL_TODS:
|
||||||
ether_addr_copy(hdr, hdr11->addr3); /* DA */
|
ether_addr_copy(hdr, hdr11->addr3); /* DA */
|
||||||
ether_addr_copy(hdr + ETH_ALEN, hdr11->addr2); /* SA */
|
ether_addr_copy(hdr + ETH_ALEN, hdr11->addr2); /* SA */
|
||||||
break;
|
break;
|
||||||
case RTLLIB_FCTL_FROMDS:
|
case IEEE80211_FCTL_FROMDS:
|
||||||
ether_addr_copy(hdr, hdr11->addr1); /* DA */
|
ether_addr_copy(hdr, hdr11->addr1); /* DA */
|
||||||
ether_addr_copy(hdr + ETH_ALEN, hdr11->addr3); /* SA */
|
ether_addr_copy(hdr + ETH_ALEN, hdr11->addr3); /* SA */
|
||||||
break;
|
break;
|
||||||
case RTLLIB_FCTL_FROMDS | RTLLIB_FCTL_TODS:
|
case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
|
||||||
ether_addr_copy(hdr, hdr11->addr3); /* DA */
|
ether_addr_copy(hdr, hdr11->addr3); /* DA */
|
||||||
ether_addr_copy(hdr + ETH_ALEN, hdr11->addr4); /* SA */
|
ether_addr_copy(hdr + ETH_ALEN, hdr11->addr4); /* SA */
|
||||||
break;
|
break;
|
||||||
@ -501,9 +501,9 @@ static int rtllib_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv)
|
|||||||
{
|
{
|
||||||
struct rtllib_tkip_data *tkey = priv;
|
struct rtllib_tkip_data *tkey = priv;
|
||||||
u8 *pos;
|
u8 *pos;
|
||||||
struct rtllib_hdr_4addr *hdr;
|
struct ieee80211_hdr *hdr;
|
||||||
|
|
||||||
hdr = (struct rtllib_hdr_4addr *)skb->data;
|
hdr = (struct ieee80211_hdr *)skb->data;
|
||||||
|
|
||||||
if (skb_tailroom(skb) < 8 || skb->len < hdr_len) {
|
if (skb_tailroom(skb) < 8 || skb->len < hdr_len) {
|
||||||
netdev_dbg(skb->dev,
|
netdev_dbg(skb->dev,
|
||||||
@ -514,7 +514,7 @@ static int rtllib_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv)
|
|||||||
|
|
||||||
michael_mic_hdr(skb, tkey->tx_hdr);
|
michael_mic_hdr(skb, tkey->tx_hdr);
|
||||||
|
|
||||||
if (RTLLIB_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl)))
|
if (RTLLIB_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_control)))
|
||||||
tkey->tx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
|
tkey->tx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
|
||||||
pos = skb_put(skb, 8);
|
pos = skb_put(skb, 8);
|
||||||
if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
|
if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
|
||||||
@ -525,7 +525,7 @@ static int rtllib_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void rtllib_michael_mic_failure(struct net_device *dev,
|
static void rtllib_michael_mic_failure(struct net_device *dev,
|
||||||
struct rtllib_hdr_4addr *hdr,
|
struct ieee80211_hdr *hdr,
|
||||||
int keyidx)
|
int keyidx)
|
||||||
{
|
{
|
||||||
union iwreq_data wrqu;
|
union iwreq_data wrqu;
|
||||||
@ -550,15 +550,15 @@ static int rtllib_michael_mic_verify(struct sk_buff *skb, int keyidx,
|
|||||||
{
|
{
|
||||||
struct rtllib_tkip_data *tkey = priv;
|
struct rtllib_tkip_data *tkey = priv;
|
||||||
u8 mic[8];
|
u8 mic[8];
|
||||||
struct rtllib_hdr_4addr *hdr;
|
struct ieee80211_hdr *hdr;
|
||||||
|
|
||||||
hdr = (struct rtllib_hdr_4addr *)skb->data;
|
hdr = (struct ieee80211_hdr *)skb->data;
|
||||||
|
|
||||||
if (!tkey->key_set)
|
if (!tkey->key_set)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
michael_mic_hdr(skb, tkey->rx_hdr);
|
michael_mic_hdr(skb, tkey->rx_hdr);
|
||||||
if (RTLLIB_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl)))
|
if (RTLLIB_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_control)))
|
||||||
tkey->rx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
|
tkey->rx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
|
||||||
|
|
||||||
if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
|
if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
|
||||||
@ -566,9 +566,9 @@ static int rtllib_michael_mic_verify(struct sk_buff *skb, int keyidx,
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
|
if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
|
||||||
struct rtllib_hdr_4addr *hdr;
|
struct ieee80211_hdr *hdr;
|
||||||
|
|
||||||
hdr = (struct rtllib_hdr_4addr *)skb->data;
|
hdr = (struct ieee80211_hdr *)skb->data;
|
||||||
netdev_dbg(skb->dev,
|
netdev_dbg(skb->dev,
|
||||||
"Michael MIC verification failed for MSDU from %pM keyidx=%d\n",
|
"Michael MIC verification failed for MSDU from %pM keyidx=%d\n",
|
||||||
hdr->addr2, keyidx);
|
hdr->addr2, keyidx);
|
||||||
|
@ -35,7 +35,7 @@ static void *prism2_wep_init(int keyidx)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
|
priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
|
||||||
if (priv == NULL)
|
if (!priv)
|
||||||
return NULL;
|
return NULL;
|
||||||
priv->key_idx = keyidx;
|
priv->key_idx = keyidx;
|
||||||
|
|
||||||
|
@ -1,49 +0,0 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
/*
|
|
||||||
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
|
|
||||||
*
|
|
||||||
* Contact Information: wlanfae <wlanfae@realtek.com>
|
|
||||||
*/
|
|
||||||
#ifndef _RTL_DEBUG_H
|
|
||||||
#define _RTL_DEBUG_H
|
|
||||||
|
|
||||||
#include <linux/bits.h>
|
|
||||||
|
|
||||||
/* Allow files to override DRV_NAME */
|
|
||||||
#ifndef DRV_NAME
|
|
||||||
#define DRV_NAME "rtllib_92e"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern u32 rt_global_debug_component;
|
|
||||||
|
|
||||||
/* These are the defines for rt_global_debug_component */
|
|
||||||
enum RTL_DEBUG {
|
|
||||||
COMP_TRACE = BIT(0),
|
|
||||||
COMP_DBG = BIT(1),
|
|
||||||
COMP_INIT = BIT(2),
|
|
||||||
COMP_RECV = BIT(3),
|
|
||||||
COMP_POWER = BIT(6),
|
|
||||||
COMP_SWBW = BIT(8),
|
|
||||||
COMP_SEC = BIT(9),
|
|
||||||
COMP_LPS = BIT(10),
|
|
||||||
COMP_QOS = BIT(11),
|
|
||||||
COMP_RATE = BIT(12),
|
|
||||||
COMP_RXDESC = BIT(13),
|
|
||||||
COMP_PHY = BIT(14),
|
|
||||||
COMP_DIG = BIT(15),
|
|
||||||
COMP_TXAGC = BIT(16),
|
|
||||||
COMP_HALDM = BIT(17),
|
|
||||||
COMP_POWER_TRACKING = BIT(18),
|
|
||||||
COMP_CH = BIT(19),
|
|
||||||
COMP_RF = BIT(20),
|
|
||||||
COMP_FIRMWARE = BIT(21),
|
|
||||||
COMP_RESET = BIT(23),
|
|
||||||
COMP_CMDPKT = BIT(24),
|
|
||||||
COMP_SCAN = BIT(25),
|
|
||||||
COMP_PS = BIT(26),
|
|
||||||
COMP_DOWN = BIT(27),
|
|
||||||
COMP_INTR = BIT(28),
|
|
||||||
COMP_ERR = BIT(31)
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -34,9 +34,6 @@
|
|||||||
#include <net/arp.h>
|
#include <net/arp.h>
|
||||||
#include "rtllib.h"
|
#include "rtllib.h"
|
||||||
|
|
||||||
u32 rt_global_debug_component = COMP_ERR;
|
|
||||||
EXPORT_SYMBOL(rt_global_debug_component);
|
|
||||||
|
|
||||||
static inline int rtllib_networks_allocate(struct rtllib_device *ieee)
|
static inline int rtllib_networks_allocate(struct rtllib_device *ieee)
|
||||||
{
|
{
|
||||||
if (ieee->networks)
|
if (ieee->networks)
|
||||||
@ -114,7 +111,6 @@ struct net_device *alloc_rtllib(int sizeof_priv)
|
|||||||
ieee->drop_unencrypted = 0;
|
ieee->drop_unencrypted = 0;
|
||||||
ieee->privacy_invoked = 0;
|
ieee->privacy_invoked = 0;
|
||||||
ieee->ieee802_1x = 1;
|
ieee->ieee802_1x = 1;
|
||||||
ieee->raw_tx = 0;
|
|
||||||
ieee->hwsec_active = 0;
|
ieee->hwsec_active = 0;
|
||||||
|
|
||||||
memset(ieee->swcamtable, 0, sizeof(struct sw_cam_table) * 32);
|
memset(ieee->swcamtable, 0, sizeof(struct sw_cam_table) * 32);
|
||||||
@ -126,9 +122,9 @@ struct net_device *alloc_rtllib(int sizeof_priv)
|
|||||||
if (!ieee->ht_info)
|
if (!ieee->ht_info)
|
||||||
goto free_softmac;
|
goto free_softmac;
|
||||||
|
|
||||||
HTUpdateDefaultSetting(ieee);
|
ht_update_default_setting(ieee);
|
||||||
HTInitializeHTInfo(ieee);
|
HTInitializeHTInfo(ieee);
|
||||||
TSInitialize(ieee);
|
rtllib_ts_init(ieee);
|
||||||
for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++)
|
for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++)
|
||||||
INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
|
INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -187,8 +187,8 @@ inline void softmac_mgmt_xmit(struct sk_buff *skb, struct rtllib_device *ieee)
|
|||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
|
short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
|
||||||
struct rtllib_hdr_3addr *header =
|
struct ieee80211_hdr_3addr *header =
|
||||||
(struct rtllib_hdr_3addr *)skb->data;
|
(struct ieee80211_hdr_3addr *)skb->data;
|
||||||
|
|
||||||
struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + 8);
|
struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + 8);
|
||||||
|
|
||||||
@ -197,7 +197,7 @@ inline void softmac_mgmt_xmit(struct sk_buff *skb, struct rtllib_device *ieee)
|
|||||||
/* called with 2nd param 0, no mgmt lock required */
|
/* called with 2nd param 0, no mgmt lock required */
|
||||||
rtllib_sta_wakeup(ieee, 0);
|
rtllib_sta_wakeup(ieee, 0);
|
||||||
|
|
||||||
if (le16_to_cpu(header->frame_ctl) == RTLLIB_STYPE_BEACON)
|
if (ieee80211_is_beacon(header->frame_control))
|
||||||
tcb_desc->queue_index = BEACON_QUEUE;
|
tcb_desc->queue_index = BEACON_QUEUE;
|
||||||
else
|
else
|
||||||
tcb_desc->queue_index = MGNT_QUEUE;
|
tcb_desc->queue_index = MGNT_QUEUE;
|
||||||
@ -213,7 +213,7 @@ inline void softmac_mgmt_xmit(struct sk_buff *skb, struct rtllib_device *ieee)
|
|||||||
if (ieee->queue_stop) {
|
if (ieee->queue_stop) {
|
||||||
enqueue_mgmt(ieee, skb);
|
enqueue_mgmt(ieee, skb);
|
||||||
} else {
|
} else {
|
||||||
header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
|
header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
|
||||||
|
|
||||||
if (ieee->seq_ctrl[0] == 0xFFF)
|
if (ieee->seq_ctrl[0] == 0xFFF)
|
||||||
ieee->seq_ctrl[0] = 0;
|
ieee->seq_ctrl[0] = 0;
|
||||||
@ -230,7 +230,7 @@ inline void softmac_mgmt_xmit(struct sk_buff *skb, struct rtllib_device *ieee)
|
|||||||
spin_unlock_irqrestore(&ieee->lock, flags);
|
spin_unlock_irqrestore(&ieee->lock, flags);
|
||||||
spin_lock_irqsave(&ieee->mgmt_tx_lock, flags);
|
spin_lock_irqsave(&ieee->mgmt_tx_lock, flags);
|
||||||
|
|
||||||
header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
|
header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
|
||||||
|
|
||||||
if (ieee->seq_ctrl[0] == 0xFFF)
|
if (ieee->seq_ctrl[0] == 0xFFF)
|
||||||
ieee->seq_ctrl[0] = 0;
|
ieee->seq_ctrl[0] = 0;
|
||||||
@ -264,16 +264,16 @@ softmac_ps_mgmt_xmit(struct sk_buff *skb,
|
|||||||
struct rtllib_device *ieee)
|
struct rtllib_device *ieee)
|
||||||
{
|
{
|
||||||
short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
|
short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
|
||||||
struct rtllib_hdr_3addr *header =
|
struct ieee80211_hdr_3addr *header =
|
||||||
(struct rtllib_hdr_3addr *)skb->data;
|
(struct ieee80211_hdr_3addr *)skb->data;
|
||||||
u16 fc, type, stype;
|
u16 fc, type, stype;
|
||||||
struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + 8);
|
struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + 8);
|
||||||
|
|
||||||
fc = le16_to_cpu(header->frame_ctl);
|
fc = le16_to_cpu(header->frame_control);
|
||||||
type = WLAN_FC_GET_TYPE(fc);
|
type = WLAN_FC_GET_TYPE(fc);
|
||||||
stype = WLAN_FC_GET_STYPE(fc);
|
stype = WLAN_FC_GET_STYPE(fc);
|
||||||
|
|
||||||
if (stype != RTLLIB_STYPE_PSPOLL)
|
if (stype != IEEE80211_STYPE_PSPOLL)
|
||||||
tcb_desc->queue_index = MGNT_QUEUE;
|
tcb_desc->queue_index = MGNT_QUEUE;
|
||||||
else
|
else
|
||||||
tcb_desc->queue_index = HIGH_QUEUE;
|
tcb_desc->queue_index = HIGH_QUEUE;
|
||||||
@ -287,7 +287,7 @@ softmac_ps_mgmt_xmit(struct sk_buff *skb,
|
|||||||
tcb_desc->tx_use_drv_assinged_rate = 1;
|
tcb_desc->tx_use_drv_assinged_rate = 1;
|
||||||
if (single) {
|
if (single) {
|
||||||
if (type != RTLLIB_FTYPE_CTL) {
|
if (type != RTLLIB_FTYPE_CTL) {
|
||||||
header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
|
header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
|
||||||
|
|
||||||
if (ieee->seq_ctrl[0] == 0xFFF)
|
if (ieee->seq_ctrl[0] == 0xFFF)
|
||||||
ieee->seq_ctrl[0] = 0;
|
ieee->seq_ctrl[0] = 0;
|
||||||
@ -300,7 +300,7 @@ softmac_ps_mgmt_xmit(struct sk_buff *skb,
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (type != RTLLIB_FTYPE_CTL) {
|
if (type != RTLLIB_FTYPE_CTL) {
|
||||||
header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
|
header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
|
||||||
|
|
||||||
if (ieee->seq_ctrl[0] == 0xFFF)
|
if (ieee->seq_ctrl[0] == 0xFFF)
|
||||||
ieee->seq_ctrl[0] = 0;
|
ieee->seq_ctrl[0] = 0;
|
||||||
@ -331,7 +331,7 @@ static inline struct sk_buff *rtllib_probe_req(struct rtllib_device *ieee)
|
|||||||
skb_reserve(skb, ieee->tx_headroom);
|
skb_reserve(skb, ieee->tx_headroom);
|
||||||
|
|
||||||
req = skb_put(skb, sizeof(struct rtllib_probe_request));
|
req = skb_put(skb, sizeof(struct rtllib_probe_request));
|
||||||
req->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_PROBE_REQ);
|
req->header.frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
|
||||||
req->header.duration_id = 0;
|
req->header.duration_id = 0;
|
||||||
|
|
||||||
eth_broadcast_addr(req->header.addr1);
|
eth_broadcast_addr(req->header.addr1);
|
||||||
@ -406,49 +406,6 @@ void rtllib_DisableNetMonitorMode(struct net_device *dev,
|
|||||||
ieee->AllowAllDestAddrHandler(dev, false, !bInitState);
|
ieee->AllowAllDestAddrHandler(dev, false, !bInitState);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enables the specialized promiscuous mode required by Intel.
|
|
||||||
* In this mode, Intel intends to hear traffics from/to other STAs in the
|
|
||||||
* same BSS. Therefore we don't have to disable checking BSSID and we only need
|
|
||||||
* to allow all dest. BUT: if we enable checking BSSID then we can't recv
|
|
||||||
* packets from other STA.
|
|
||||||
*/
|
|
||||||
void rtllib_EnableIntelPromiscuousMode(struct net_device *dev,
|
|
||||||
bool bInitState)
|
|
||||||
{
|
|
||||||
bool bFilterOutNonAssociatedBSSID = false;
|
|
||||||
|
|
||||||
struct rtllib_device *ieee = netdev_priv_rsl(dev);
|
|
||||||
|
|
||||||
netdev_info(dev, "========>Enter Intel Promiscuous Mode\n");
|
|
||||||
|
|
||||||
ieee->AllowAllDestAddrHandler(dev, true, !bInitState);
|
|
||||||
ieee->SetHwRegHandler(dev, HW_VAR_CECHK_BSSID,
|
|
||||||
(u8 *)&bFilterOutNonAssociatedBSSID);
|
|
||||||
|
|
||||||
ieee->net_promiscuous_md = true;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(rtllib_EnableIntelPromiscuousMode);
|
|
||||||
|
|
||||||
/* Disables the specialized promiscuous mode required by Intel.
|
|
||||||
* See MgntEnableIntelPromiscuousMode for detail.
|
|
||||||
*/
|
|
||||||
void rtllib_DisableIntelPromiscuousMode(struct net_device *dev,
|
|
||||||
bool bInitState)
|
|
||||||
{
|
|
||||||
bool bFilterOutNonAssociatedBSSID = true;
|
|
||||||
|
|
||||||
struct rtllib_device *ieee = netdev_priv_rsl(dev);
|
|
||||||
|
|
||||||
netdev_info(dev, "========>Exit Intel Promiscuous Mode\n");
|
|
||||||
|
|
||||||
ieee->AllowAllDestAddrHandler(dev, false, !bInitState);
|
|
||||||
ieee->SetHwRegHandler(dev, HW_VAR_CECHK_BSSID,
|
|
||||||
(u8 *)&bFilterOutNonAssociatedBSSID);
|
|
||||||
|
|
||||||
ieee->net_promiscuous_md = false;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(rtllib_DisableIntelPromiscuousMode);
|
|
||||||
|
|
||||||
static void rtllib_send_probe(struct rtllib_device *ieee)
|
static void rtllib_send_probe(struct rtllib_device *ieee)
|
||||||
{
|
{
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
@ -462,8 +419,7 @@ static void rtllib_send_probe(struct rtllib_device *ieee)
|
|||||||
|
|
||||||
static void rtllib_send_probe_requests(struct rtllib_device *ieee)
|
static void rtllib_send_probe_requests(struct rtllib_device *ieee)
|
||||||
{
|
{
|
||||||
if (ieee->active_scan && (ieee->softmac_features &
|
if (ieee->softmac_features & IEEE_SOFTMAC_PROBERQ) {
|
||||||
IEEE_SOFTMAC_PROBERQ)) {
|
|
||||||
rtllib_send_probe(ieee);
|
rtllib_send_probe(ieee);
|
||||||
rtllib_send_probe(ieee);
|
rtllib_send_probe(ieee);
|
||||||
}
|
}
|
||||||
@ -607,46 +563,6 @@ out1:
|
|||||||
mutex_unlock(&ieee->scan_mutex);
|
mutex_unlock(&ieee->scan_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtllib_beacons_start(struct rtllib_device *ieee)
|
|
||||||
{
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&ieee->beacon_lock, flags);
|
|
||||||
|
|
||||||
ieee->beacon_txing = 1;
|
|
||||||
rtllib_send_beacon(ieee);
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&ieee->beacon_lock, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void rtllib_beacons_stop(struct rtllib_device *ieee)
|
|
||||||
{
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&ieee->beacon_lock, flags);
|
|
||||||
|
|
||||||
ieee->beacon_txing = 0;
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&ieee->beacon_lock, flags);
|
|
||||||
del_timer_sync(&ieee->beacon_timer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void rtllib_stop_send_beacons(struct rtllib_device *ieee)
|
|
||||||
{
|
|
||||||
ieee->stop_send_beacons(ieee->dev);
|
|
||||||
if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
|
|
||||||
rtllib_beacons_stop(ieee);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(rtllib_stop_send_beacons);
|
|
||||||
|
|
||||||
void rtllib_start_send_beacons(struct rtllib_device *ieee)
|
|
||||||
{
|
|
||||||
ieee->start_send_beacons(ieee->dev);
|
|
||||||
if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
|
|
||||||
rtllib_beacons_start(ieee);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(rtllib_start_send_beacons);
|
|
||||||
|
|
||||||
static void rtllib_softmac_stop_scan(struct rtllib_device *ieee)
|
static void rtllib_softmac_stop_scan(struct rtllib_device *ieee)
|
||||||
{
|
{
|
||||||
mutex_lock(&ieee->scan_mutex);
|
mutex_lock(&ieee->scan_mutex);
|
||||||
@ -739,9 +655,9 @@ rtllib_authentication_req(struct rtllib_network *beacon,
|
|||||||
|
|
||||||
auth = skb_put(skb, sizeof(struct rtllib_authentication));
|
auth = skb_put(skb, sizeof(struct rtllib_authentication));
|
||||||
|
|
||||||
auth->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_AUTH);
|
auth->header.frame_control = cpu_to_le16(IEEE80211_STYPE_AUTH);
|
||||||
if (challengelen)
|
if (challengelen)
|
||||||
auth->header.frame_ctl |= cpu_to_le16(RTLLIB_FCTL_WEP);
|
auth->header.frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
|
||||||
|
|
||||||
auth->header.duration_id = cpu_to_le16(0x013a);
|
auth->header.duration_id = cpu_to_le16(0x013a);
|
||||||
ether_addr_copy(auth->header.addr1, beacon->bssid);
|
ether_addr_copy(auth->header.addr1, beacon->bssid);
|
||||||
@ -809,7 +725,7 @@ static struct sk_buff *rtllib_probe_resp(struct rtllib_device *ieee,
|
|||||||
crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
|
crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
|
||||||
encrypt = crypt && crypt->ops &&
|
encrypt = crypt && crypt->ops &&
|
||||||
((strcmp(crypt->ops->name, "R-WEP") == 0 || wpa_ie_len));
|
((strcmp(crypt->ops->name, "R-WEP") == 0 || wpa_ie_len));
|
||||||
if (ieee->ht_info->bCurrentHTSupport) {
|
if (ieee->ht_info->current_ht_support) {
|
||||||
tmp_ht_cap_buf = (u8 *)&(ieee->ht_info->SelfHTCap);
|
tmp_ht_cap_buf = (u8 *)&(ieee->ht_info->SelfHTCap);
|
||||||
tmp_ht_cap_len = sizeof(ieee->ht_info->SelfHTCap);
|
tmp_ht_cap_len = sizeof(ieee->ht_info->SelfHTCap);
|
||||||
tmp_ht_info_buf = (u8 *)&(ieee->ht_info->SelfHTInfo);
|
tmp_ht_info_buf = (u8 *)&(ieee->ht_info->SelfHTInfo);
|
||||||
@ -860,7 +776,7 @@ static struct sk_buff *rtllib_probe_resp(struct rtllib_device *ieee,
|
|||||||
if (encrypt)
|
if (encrypt)
|
||||||
beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
|
beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
|
||||||
|
|
||||||
beacon_buf->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_PROBE_RESP);
|
beacon_buf->header.frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP);
|
||||||
beacon_buf->info_element[0].id = MFIE_TYPE_SSID;
|
beacon_buf->info_element[0].id = MFIE_TYPE_SSID;
|
||||||
beacon_buf->info_element[0].len = ssid_len;
|
beacon_buf->info_element[0].len = ssid_len;
|
||||||
|
|
||||||
@ -901,8 +817,6 @@ static struct sk_buff *rtllib_probe_resp(struct rtllib_device *ieee,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (wpa_ie_len) {
|
if (wpa_ie_len) {
|
||||||
if (ieee->iw_mode == IW_MODE_ADHOC)
|
|
||||||
memcpy(&ieee->wpa_ie[14], &ieee->wpa_ie[8], 4);
|
|
||||||
memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
|
memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
|
||||||
tag += ieee->wpa_ie_len;
|
tag += ieee->wpa_ie_len;
|
||||||
}
|
}
|
||||||
@ -912,23 +826,23 @@ static struct sk_buff *rtllib_probe_resp(struct rtllib_device *ieee,
|
|||||||
static struct sk_buff *rtllib_null_func(struct rtllib_device *ieee, short pwr)
|
static struct sk_buff *rtllib_null_func(struct rtllib_device *ieee, short pwr)
|
||||||
{
|
{
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
struct rtllib_hdr_3addr *hdr;
|
struct ieee80211_hdr_3addr *hdr;
|
||||||
|
|
||||||
skb = dev_alloc_skb(sizeof(struct rtllib_hdr_3addr) + ieee->tx_headroom);
|
skb = dev_alloc_skb(sizeof(struct ieee80211_hdr_3addr) + ieee->tx_headroom);
|
||||||
if (!skb)
|
if (!skb)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
skb_reserve(skb, ieee->tx_headroom);
|
skb_reserve(skb, ieee->tx_headroom);
|
||||||
|
|
||||||
hdr = skb_put(skb, sizeof(struct rtllib_hdr_3addr));
|
hdr = skb_put(skb, sizeof(struct ieee80211_hdr_3addr));
|
||||||
|
|
||||||
ether_addr_copy(hdr->addr1, ieee->current_network.bssid);
|
ether_addr_copy(hdr->addr1, ieee->current_network.bssid);
|
||||||
ether_addr_copy(hdr->addr2, ieee->dev->dev_addr);
|
ether_addr_copy(hdr->addr2, ieee->dev->dev_addr);
|
||||||
ether_addr_copy(hdr->addr3, ieee->current_network.bssid);
|
ether_addr_copy(hdr->addr3, ieee->current_network.bssid);
|
||||||
|
|
||||||
hdr->frame_ctl = cpu_to_le16(RTLLIB_FTYPE_DATA |
|
hdr->frame_control = cpu_to_le16(RTLLIB_FTYPE_DATA |
|
||||||
RTLLIB_STYPE_NULLFUNC | RTLLIB_FCTL_TODS |
|
IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS |
|
||||||
(pwr ? RTLLIB_FCTL_PM : 0));
|
(pwr ? IEEE80211_FCTL_PM : 0));
|
||||||
|
|
||||||
return skb;
|
return skb;
|
||||||
}
|
}
|
||||||
@ -936,34 +850,26 @@ static struct sk_buff *rtllib_null_func(struct rtllib_device *ieee, short pwr)
|
|||||||
static struct sk_buff *rtllib_pspoll_func(struct rtllib_device *ieee)
|
static struct sk_buff *rtllib_pspoll_func(struct rtllib_device *ieee)
|
||||||
{
|
{
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
struct rtllib_pspoll_hdr *hdr;
|
struct ieee80211_pspoll *hdr;
|
||||||
|
|
||||||
skb = dev_alloc_skb(sizeof(struct rtllib_pspoll_hdr) + ieee->tx_headroom);
|
skb = dev_alloc_skb(sizeof(struct ieee80211_pspoll) + ieee->tx_headroom);
|
||||||
if (!skb)
|
if (!skb)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
skb_reserve(skb, ieee->tx_headroom);
|
skb_reserve(skb, ieee->tx_headroom);
|
||||||
|
|
||||||
hdr = skb_put(skb, sizeof(struct rtllib_pspoll_hdr));
|
hdr = skb_put(skb, sizeof(struct ieee80211_pspoll));
|
||||||
|
|
||||||
ether_addr_copy(hdr->bssid, ieee->current_network.bssid);
|
ether_addr_copy(hdr->bssid, ieee->current_network.bssid);
|
||||||
ether_addr_copy(hdr->ta, ieee->dev->dev_addr);
|
ether_addr_copy(hdr->ta, ieee->dev->dev_addr);
|
||||||
|
|
||||||
hdr->aid = cpu_to_le16(ieee->assoc_id | 0xc000);
|
hdr->aid = cpu_to_le16(ieee->assoc_id | 0xc000);
|
||||||
hdr->frame_ctl = cpu_to_le16(RTLLIB_FTYPE_CTL | RTLLIB_STYPE_PSPOLL |
|
hdr->frame_control = cpu_to_le16(RTLLIB_FTYPE_CTL | IEEE80211_STYPE_PSPOLL |
|
||||||
RTLLIB_FCTL_PM);
|
IEEE80211_FCTL_PM);
|
||||||
|
|
||||||
return skb;
|
return skb;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtllib_resp_to_probe(struct rtllib_device *ieee, u8 *dest)
|
|
||||||
{
|
|
||||||
struct sk_buff *buf = rtllib_probe_resp(ieee, dest);
|
|
||||||
|
|
||||||
if (buf)
|
|
||||||
softmac_mgmt_xmit(buf, ieee);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int SecIsInPMKIDList(struct rtllib_device *ieee, u8 *bssid)
|
static inline int SecIsInPMKIDList(struct rtllib_device *ieee, u8 *bssid)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@ -1012,7 +918,7 @@ rtllib_association_req(struct rtllib_network *beacon,
|
|||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
|
crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
|
||||||
if (crypt != NULL)
|
if (crypt)
|
||||||
encrypt = crypt && crypt->ops &&
|
encrypt = crypt && crypt->ops &&
|
||||||
((strcmp(crypt->ops->name, "R-WEP") == 0 ||
|
((strcmp(crypt->ops->name, "R-WEP") == 0 ||
|
||||||
wpa_ie_len));
|
wpa_ie_len));
|
||||||
@ -1026,7 +932,7 @@ rtllib_association_req(struct rtllib_network *beacon,
|
|||||||
ieee->mode = WIRELESS_MODE_G;
|
ieee->mode = WIRELESS_MODE_G;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ieee->ht_info->bCurrentHTSupport && ieee->ht_info->enable_ht) {
|
if (ieee->ht_info->current_ht_support && ieee->ht_info->enable_ht) {
|
||||||
ht_cap_buf = (u8 *)&(ieee->ht_info->SelfHTCap);
|
ht_cap_buf = (u8 *)&(ieee->ht_info->SelfHTCap);
|
||||||
ht_cap_len = sizeof(ieee->ht_info->SelfHTCap);
|
ht_cap_len = sizeof(ieee->ht_info->SelfHTCap);
|
||||||
HTConstructCapabilityElement(ieee, ht_cap_buf, &ht_cap_len,
|
HTConstructCapabilityElement(ieee, ht_cap_buf, &ht_cap_len,
|
||||||
@ -1076,7 +982,7 @@ rtllib_association_req(struct rtllib_network *beacon,
|
|||||||
|
|
||||||
hdr = skb_put(skb, sizeof(struct rtllib_assoc_request_frame) + 2);
|
hdr = skb_put(skb, sizeof(struct rtllib_assoc_request_frame) + 2);
|
||||||
|
|
||||||
hdr->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_ASSOC_REQ);
|
hdr->header.frame_control = cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ);
|
||||||
hdr->header.duration_id = cpu_to_le16(37);
|
hdr->header.duration_id = cpu_to_le16(37);
|
||||||
ether_addr_copy(hdr->header.addr1, beacon->bssid);
|
ether_addr_copy(hdr->header.addr1, beacon->bssid);
|
||||||
ether_addr_copy(hdr->header.addr2, ieee->dev->dev_addr);
|
ether_addr_copy(hdr->header.addr2, ieee->dev->dev_addr);
|
||||||
@ -1164,7 +1070,7 @@ rtllib_association_req(struct rtllib_network *beacon,
|
|||||||
memcpy(tag, osCcxVerNum.Octet, osCcxVerNum.Length);
|
memcpy(tag, osCcxVerNum.Octet, osCcxVerNum.Length);
|
||||||
tag += osCcxVerNum.Length;
|
tag += osCcxVerNum.Length;
|
||||||
}
|
}
|
||||||
if (ieee->ht_info->bCurrentHTSupport && ieee->ht_info->enable_ht) {
|
if (ieee->ht_info->current_ht_support && ieee->ht_info->enable_ht) {
|
||||||
if (ieee->ht_info->ePeerHTSpecVer != HT_SPEC_VER_EWC) {
|
if (ieee->ht_info->ePeerHTSpecVer != HT_SPEC_VER_EWC) {
|
||||||
tag = skb_put(skb, ht_cap_len);
|
tag = skb_put(skb, ht_cap_len);
|
||||||
*tag++ = MFIE_TYPE_HT_CAP;
|
*tag++ = MFIE_TYPE_HT_CAP;
|
||||||
@ -1198,7 +1104,7 @@ rtllib_association_req(struct rtllib_network *beacon,
|
|||||||
rtllib_TURBO_Info(ieee, &tag);
|
rtllib_TURBO_Info(ieee, &tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ieee->ht_info->bCurrentHTSupport && ieee->ht_info->enable_ht) {
|
if (ieee->ht_info->current_ht_support && ieee->ht_info->enable_ht) {
|
||||||
if (ieee->ht_info->ePeerHTSpecVer == HT_SPEC_VER_EWC) {
|
if (ieee->ht_info->ePeerHTSpecVer == HT_SPEC_VER_EWC) {
|
||||||
tag = skb_put(skb, ht_cap_len);
|
tag = skb_put(skb, ht_cap_len);
|
||||||
*tag++ = MFIE_TYPE_GENERIC;
|
*tag++ = MFIE_TYPE_GENERIC;
|
||||||
@ -1311,7 +1217,7 @@ static void rtllib_auth_challenge(struct rtllib_device *ieee, u8 *challenge,
|
|||||||
"Sending authentication challenge response\n");
|
"Sending authentication challenge response\n");
|
||||||
|
|
||||||
rtllib_encrypt_fragment(ieee, skb,
|
rtllib_encrypt_fragment(ieee, skb,
|
||||||
sizeof(struct rtllib_hdr_3addr));
|
sizeof(struct ieee80211_hdr_3addr));
|
||||||
|
|
||||||
softmac_mgmt_xmit(skb, ieee);
|
softmac_mgmt_xmit(skb, ieee);
|
||||||
mod_timer(&ieee->associate_timer, jiffies + (HZ / 2));
|
mod_timer(&ieee->associate_timer, jiffies + (HZ / 2));
|
||||||
@ -1348,10 +1254,8 @@ static void rtllib_associate_complete_wq(void *data)
|
|||||||
|
|
||||||
netdev_info(ieee->dev, "Associated successfully with %pM\n",
|
netdev_info(ieee->dev, "Associated successfully with %pM\n",
|
||||||
ieee->current_network.bssid);
|
ieee->current_network.bssid);
|
||||||
if (!ieee->is_silent_reset) {
|
netdev_info(ieee->dev, "normal associate\n");
|
||||||
netdev_info(ieee->dev, "normal associate\n");
|
notify_wx_assoc_event(ieee);
|
||||||
notify_wx_assoc_event(ieee);
|
|
||||||
}
|
|
||||||
|
|
||||||
netif_carrier_on(ieee->dev);
|
netif_carrier_on(ieee->dev);
|
||||||
ieee->is_roaming = false;
|
ieee->is_roaming = false;
|
||||||
@ -1363,13 +1267,13 @@ static void rtllib_associate_complete_wq(void *data)
|
|||||||
ieee->set_wireless_mode(ieee->dev, WIRELESS_MODE_B);
|
ieee->set_wireless_mode(ieee->dev, WIRELESS_MODE_B);
|
||||||
netdev_info(ieee->dev, "Using B rates:%d\n", ieee->rate);
|
netdev_info(ieee->dev, "Using B rates:%d\n", ieee->rate);
|
||||||
}
|
}
|
||||||
if (ieee->ht_info->bCurrentHTSupport && ieee->ht_info->enable_ht) {
|
if (ieee->ht_info->current_ht_support && ieee->ht_info->enable_ht) {
|
||||||
netdev_info(ieee->dev, "Successfully associated, ht enabled\n");
|
netdev_info(ieee->dev, "Successfully associated, ht enabled\n");
|
||||||
HTOnAssocRsp(ieee);
|
HTOnAssocRsp(ieee);
|
||||||
} else {
|
} else {
|
||||||
netdev_info(ieee->dev,
|
netdev_info(ieee->dev,
|
||||||
"Successfully associated, ht not enabled(%d, %d)\n",
|
"Successfully associated, ht not enabled(%d, %d)\n",
|
||||||
ieee->ht_info->bCurrentHTSupport,
|
ieee->ht_info->current_ht_support,
|
||||||
ieee->ht_info->enable_ht);
|
ieee->ht_info->enable_ht);
|
||||||
memset(ieee->dot11ht_oper_rate_set, 0, 16);
|
memset(ieee->dot11ht_oper_rate_set, 0, 16);
|
||||||
}
|
}
|
||||||
@ -1384,10 +1288,6 @@ static void rtllib_associate_complete_wq(void *data)
|
|||||||
psc->LpsIdleCount = 0;
|
psc->LpsIdleCount = 0;
|
||||||
ieee->link_change(ieee->dev);
|
ieee->link_change(ieee->dev);
|
||||||
|
|
||||||
if (ieee->is_silent_reset) {
|
|
||||||
netdev_info(ieee->dev, "silent reset associate\n");
|
|
||||||
ieee->is_silent_reset = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtllib_sta_send_associnfo(struct rtllib_device *ieee)
|
static void rtllib_sta_send_associnfo(struct rtllib_device *ieee)
|
||||||
@ -1445,14 +1345,7 @@ inline void rtllib_softmac_new_net(struct rtllib_device *ieee,
|
|||||||
WLAN_CAPABILITY_ESS))
|
WLAN_CAPABILITY_ESS))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability &
|
if (ieee->iw_mode == IW_MODE_INFRA) {
|
||||||
WLAN_CAPABILITY_IBSS))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if ((ieee->iw_mode == IW_MODE_ADHOC) &&
|
|
||||||
(net->channel > ieee->ibss_maxjoin_chal))
|
|
||||||
return;
|
|
||||||
if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC) {
|
|
||||||
/* if the user specified the AP MAC, we need also the essid
|
/* if the user specified the AP MAC, we need also the essid
|
||||||
* This could be obtained by beacons or, if the network does not
|
* This could be obtained by beacons or, if the network does not
|
||||||
* broadcast it, it can be put manually.
|
* broadcast it, it can be put manually.
|
||||||
@ -1534,8 +1427,7 @@ inline void rtllib_softmac_new_net(struct rtllib_device *ieee,
|
|||||||
HTResetSelfAndSavePeerSetting(ieee,
|
HTResetSelfAndSavePeerSetting(ieee,
|
||||||
&(ieee->current_network));
|
&(ieee->current_network));
|
||||||
else
|
else
|
||||||
ieee->ht_info->bCurrentHTSupport =
|
ieee->ht_info->current_ht_support = false;
|
||||||
false;
|
|
||||||
|
|
||||||
ieee->link_state = RTLLIB_ASSOCIATING;
|
ieee->link_state = RTLLIB_ASSOCIATING;
|
||||||
schedule_delayed_work(
|
schedule_delayed_work(
|
||||||
@ -1613,52 +1505,6 @@ static inline int auth_parse(struct net_device *dev, struct sk_buff *skb,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static short probe_rq_parse(struct rtllib_device *ieee, struct sk_buff *skb,
|
|
||||||
u8 *src)
|
|
||||||
{
|
|
||||||
u8 *tag;
|
|
||||||
u8 *skbend;
|
|
||||||
u8 *ssid = NULL;
|
|
||||||
u8 ssidlen = 0;
|
|
||||||
struct rtllib_hdr_3addr *header =
|
|
||||||
(struct rtllib_hdr_3addr *)skb->data;
|
|
||||||
bool bssid_match;
|
|
||||||
|
|
||||||
if (skb->len < sizeof(struct rtllib_hdr_3addr))
|
|
||||||
return -1; /* corrupted */
|
|
||||||
|
|
||||||
bssid_match =
|
|
||||||
(!ether_addr_equal(header->addr3, ieee->current_network.bssid)) &&
|
|
||||||
(!is_broadcast_ether_addr(header->addr3));
|
|
||||||
if (bssid_match)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
ether_addr_copy(src, header->addr2);
|
|
||||||
|
|
||||||
skbend = (u8 *)skb->data + skb->len;
|
|
||||||
|
|
||||||
tag = skb->data + sizeof(struct rtllib_hdr_3addr);
|
|
||||||
|
|
||||||
while (tag + 1 < skbend) {
|
|
||||||
if (*tag == 0) {
|
|
||||||
ssid = tag + 2;
|
|
||||||
ssidlen = *(tag + 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
tag++; /* point to the len field */
|
|
||||||
tag = tag + *(tag); /* point to the last data byte of the tag */
|
|
||||||
tag++; /* point to the next tag */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ssidlen == 0)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (!ssid)
|
|
||||||
return 1; /* ssid not found in tagged param */
|
|
||||||
|
|
||||||
return !strncmp(ssid, ieee->current_network.ssid, ssidlen);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline u16 assoc_parse(struct rtllib_device *ieee, struct sk_buff *skb,
|
static inline u16 assoc_parse(struct rtllib_device *ieee, struct sk_buff *skb,
|
||||||
int *aid)
|
int *aid)
|
||||||
{
|
{
|
||||||
@ -1688,17 +1534,6 @@ static inline u16 assoc_parse(struct rtllib_device *ieee, struct sk_buff *skb,
|
|||||||
return le16_to_cpu(response_head->status);
|
return le16_to_cpu(response_head->status);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtllib_rx_probe_rq(struct rtllib_device *ieee, struct sk_buff *skb)
|
|
||||||
{
|
|
||||||
u8 dest[ETH_ALEN];
|
|
||||||
|
|
||||||
ieee->softmac_stats.rx_probe_rq++;
|
|
||||||
if (probe_rq_parse(ieee, skb, dest) > 0) {
|
|
||||||
ieee->softmac_stats.tx_probe_rs++;
|
|
||||||
rtllib_resp_to_probe(ieee, dest);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void rtllib_sta_ps_send_null_frame(struct rtllib_device *ieee, short pwr)
|
void rtllib_sta_ps_send_null_frame(struct rtllib_device *ieee, short pwr)
|
||||||
{
|
{
|
||||||
struct sk_buff *buf = rtllib_null_func(ieee, pwr);
|
struct sk_buff *buf = rtllib_null_func(ieee, pwr);
|
||||||
@ -1752,16 +1587,10 @@ static short rtllib_sta_ps_sleep(struct rtllib_device *ieee, u64 *time)
|
|||||||
if (ieee->bAwakePktSent) {
|
if (ieee->bAwakePktSent) {
|
||||||
psc->LPSAwakeIntvl = 1;
|
psc->LPSAwakeIntvl = 1;
|
||||||
} else {
|
} else {
|
||||||
u8 MaxPeriod = 1;
|
u8 MaxPeriod = 5;
|
||||||
|
|
||||||
if (psc->LPSAwakeIntvl == 0)
|
if (psc->LPSAwakeIntvl == 0)
|
||||||
psc->LPSAwakeIntvl = 1;
|
psc->LPSAwakeIntvl = 1;
|
||||||
if (psc->reg_max_lps_awake_intvl == 0)
|
|
||||||
MaxPeriod = 1;
|
|
||||||
else if (psc->reg_max_lps_awake_intvl == 0xFF)
|
|
||||||
MaxPeriod = ieee->current_network.dtim_period;
|
|
||||||
else
|
|
||||||
MaxPeriod = psc->reg_max_lps_awake_intvl;
|
|
||||||
psc->LPSAwakeIntvl = (psc->LPSAwakeIntvl >=
|
psc->LPSAwakeIntvl = (psc->LPSAwakeIntvl >=
|
||||||
MaxPeriod) ? MaxPeriod :
|
MaxPeriod) ? MaxPeriod :
|
||||||
(psc->LPSAwakeIntvl + 1);
|
(psc->LPSAwakeIntvl + 1);
|
||||||
@ -1921,16 +1750,9 @@ EXPORT_SYMBOL(rtllib_ps_tx_ack);
|
|||||||
static void rtllib_process_action(struct rtllib_device *ieee,
|
static void rtllib_process_action(struct rtllib_device *ieee,
|
||||||
struct sk_buff *skb)
|
struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct rtllib_hdr_3addr *header = (struct rtllib_hdr_3addr *)skb->data;
|
u8 *act = skb->data + RTLLIB_3ADDR_LEN;
|
||||||
u8 *act = rtllib_get_payload((struct rtllib_hdr *)header);
|
|
||||||
u8 category = 0;
|
u8 category = 0;
|
||||||
|
|
||||||
if (act == NULL) {
|
|
||||||
netdev_warn(ieee->dev,
|
|
||||||
"Error getting payload of action frame\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
category = *act;
|
category = *act;
|
||||||
act++;
|
act++;
|
||||||
switch (category) {
|
switch (category) {
|
||||||
@ -1960,8 +1782,8 @@ rtllib_rx_assoc_resp(struct rtllib_device *ieee, struct sk_buff *skb,
|
|||||||
int aid;
|
int aid;
|
||||||
u8 *ies;
|
u8 *ies;
|
||||||
struct rtllib_assoc_response_frame *assoc_resp;
|
struct rtllib_assoc_response_frame *assoc_resp;
|
||||||
struct rtllib_hdr_3addr *header = (struct rtllib_hdr_3addr *)skb->data;
|
struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *)skb->data;
|
||||||
u16 frame_ctl = le16_to_cpu(header->frame_ctl);
|
u16 frame_ctl = le16_to_cpu(header->frame_control);
|
||||||
|
|
||||||
netdev_dbg(ieee->dev, "received [RE]ASSOCIATION RESPONSE (%d)\n",
|
netdev_dbg(ieee->dev, "received [RE]ASSOCIATION RESPONSE (%d)\n",
|
||||||
WLAN_FC_GET_STYPE(frame_ctl));
|
WLAN_FC_GET_STYPE(frame_ctl));
|
||||||
@ -2099,7 +1921,7 @@ rtllib_rx_auth(struct rtllib_device *ieee, struct sk_buff *skb,
|
|||||||
static inline int
|
static inline int
|
||||||
rtllib_rx_deauth(struct rtllib_device *ieee, struct sk_buff *skb)
|
rtllib_rx_deauth(struct rtllib_device *ieee, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct rtllib_hdr_3addr *header = (struct rtllib_hdr_3addr *)skb->data;
|
struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *)skb->data;
|
||||||
u16 frame_ctl;
|
u16 frame_ctl;
|
||||||
|
|
||||||
if (memcmp(header->addr3, ieee->current_network.bssid, ETH_ALEN) != 0)
|
if (memcmp(header->addr3, ieee->current_network.bssid, ETH_ALEN) != 0)
|
||||||
@ -2111,7 +1933,7 @@ rtllib_rx_deauth(struct rtllib_device *ieee, struct sk_buff *skb)
|
|||||||
if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
|
if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
|
||||||
ieee->link_state == MAC80211_LINKED &&
|
ieee->link_state == MAC80211_LINKED &&
|
||||||
(ieee->iw_mode == IW_MODE_INFRA)) {
|
(ieee->iw_mode == IW_MODE_INFRA)) {
|
||||||
frame_ctl = le16_to_cpu(header->frame_ctl);
|
frame_ctl = le16_to_cpu(header->frame_control);
|
||||||
netdev_info(ieee->dev,
|
netdev_info(ieee->dev,
|
||||||
"==========>received disassoc/deauth(%x) frame, reason code:%x\n",
|
"==========>received disassoc/deauth(%x) frame, reason code:%x\n",
|
||||||
WLAN_FC_GET_STYPE(frame_ctl),
|
WLAN_FC_GET_STYPE(frame_ctl),
|
||||||
@ -2135,30 +1957,30 @@ inline int rtllib_rx_frame_softmac(struct rtllib_device *ieee,
|
|||||||
struct rtllib_rx_stats *rx_stats, u16 type,
|
struct rtllib_rx_stats *rx_stats, u16 type,
|
||||||
u16 stype)
|
u16 stype)
|
||||||
{
|
{
|
||||||
struct rtllib_hdr_3addr *header = (struct rtllib_hdr_3addr *)skb->data;
|
struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *)skb->data;
|
||||||
u16 frame_ctl;
|
u16 frame_ctl;
|
||||||
|
|
||||||
if (!ieee->proto_started)
|
if (!ieee->proto_started)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
frame_ctl = le16_to_cpu(header->frame_ctl);
|
frame_ctl = le16_to_cpu(header->frame_control);
|
||||||
switch (WLAN_FC_GET_STYPE(frame_ctl)) {
|
switch (WLAN_FC_GET_STYPE(frame_ctl)) {
|
||||||
case RTLLIB_STYPE_ASSOC_RESP:
|
case IEEE80211_STYPE_ASSOC_RESP:
|
||||||
case RTLLIB_STYPE_REASSOC_RESP:
|
case IEEE80211_STYPE_REASSOC_RESP:
|
||||||
if (rtllib_rx_assoc_resp(ieee, skb, rx_stats) == 1)
|
if (rtllib_rx_assoc_resp(ieee, skb, rx_stats) == 1)
|
||||||
return 1;
|
return 1;
|
||||||
break;
|
break;
|
||||||
case RTLLIB_STYPE_ASSOC_REQ:
|
case IEEE80211_STYPE_ASSOC_REQ:
|
||||||
case RTLLIB_STYPE_REASSOC_REQ:
|
case IEEE80211_STYPE_REASSOC_REQ:
|
||||||
break;
|
break;
|
||||||
case RTLLIB_STYPE_AUTH:
|
case IEEE80211_STYPE_AUTH:
|
||||||
rtllib_rx_auth(ieee, skb, rx_stats);
|
rtllib_rx_auth(ieee, skb, rx_stats);
|
||||||
break;
|
break;
|
||||||
case RTLLIB_STYPE_DISASSOC:
|
case IEEE80211_STYPE_DISASSOC:
|
||||||
case RTLLIB_STYPE_DEAUTH:
|
case IEEE80211_STYPE_DEAUTH:
|
||||||
rtllib_rx_deauth(ieee, skb);
|
rtllib_rx_deauth(ieee, skb);
|
||||||
break;
|
break;
|
||||||
case RTLLIB_STYPE_MANAGE_ACT:
|
case IEEE80211_STYPE_ACTION:
|
||||||
rtllib_process_action(ieee, skb);
|
rtllib_process_action(ieee, skb);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -2263,128 +2085,6 @@ void rtllib_wake_all_queues(struct rtllib_device *ieee)
|
|||||||
netif_tx_wake_all_queues(ieee->dev);
|
netif_tx_wake_all_queues(ieee->dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtllib_start_monitor_mode(struct rtllib_device *ieee)
|
|
||||||
{
|
|
||||||
/* reset hardware status */
|
|
||||||
if (ieee->raw_tx)
|
|
||||||
netif_carrier_on(ieee->dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void rtllib_start_ibss_wq(void *data)
|
|
||||||
{
|
|
||||||
struct rtllib_device *ieee = container_of_dwork_rsl(data,
|
|
||||||
struct rtllib_device, start_ibss_wq);
|
|
||||||
/* iwconfig mode ad-hoc will schedule this and return
|
|
||||||
* on the other hand this will block further iwconfig SET
|
|
||||||
* operations because of the wx_mutex hold.
|
|
||||||
* Anyway some most set operations set a flag to speed-up
|
|
||||||
* (abort) this wq (when syncro scanning) before sleeping
|
|
||||||
* on the mutex
|
|
||||||
*/
|
|
||||||
if (!ieee->proto_started) {
|
|
||||||
netdev_info(ieee->dev, "==========oh driver down return\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mutex_lock(&ieee->wx_mutex);
|
|
||||||
|
|
||||||
if (ieee->current_network.ssid_len == 0) {
|
|
||||||
strscpy(ieee->current_network.ssid, RTLLIB_DEFAULT_TX_ESSID,
|
|
||||||
sizeof(ieee->current_network.ssid));
|
|
||||||
ieee->current_network.ssid_len = strlen(RTLLIB_DEFAULT_TX_ESSID);
|
|
||||||
ieee->ssid_set = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ieee->link_state = MAC80211_NOLINK;
|
|
||||||
ieee->mode = WIRELESS_MODE_G;
|
|
||||||
/* check if we have this cell in our network list */
|
|
||||||
rtllib_softmac_check_all_nets(ieee);
|
|
||||||
|
|
||||||
/* if not then the state is not linked. Maybe the user switched to
|
|
||||||
* ad-hoc mode just after being in monitor mode, or just after
|
|
||||||
* being very few time in managed mode (so the card have had no
|
|
||||||
* time to scan all the chans..) or we have just run up the iface
|
|
||||||
* after setting ad-hoc mode. So we have to give another try..
|
|
||||||
* Here, in ibss mode, should be safe to do this without extra care
|
|
||||||
* (in bss mode we had to make sure no-one tried to associate when
|
|
||||||
* we had just checked the ieee->link_state and we was going to start the
|
|
||||||
* scan) because in ibss mode the rtllib_new_net function, when
|
|
||||||
* finds a good net, just set the ieee->link_state to MAC80211_LINKED,
|
|
||||||
* so, at worst, we waste a bit of time to initiate an unneeded syncro
|
|
||||||
* scan, that will stop at the first round because it sees the state
|
|
||||||
* associated.
|
|
||||||
*/
|
|
||||||
if (ieee->link_state == MAC80211_NOLINK)
|
|
||||||
rtllib_start_scan_syncro(ieee);
|
|
||||||
|
|
||||||
/* the network definitively is not here.. create a new cell */
|
|
||||||
if (ieee->link_state == MAC80211_NOLINK) {
|
|
||||||
netdev_info(ieee->dev, "creating new IBSS cell\n");
|
|
||||||
ieee->current_network.channel = ieee->bss_start_channel;
|
|
||||||
if (!ieee->wap_set)
|
|
||||||
eth_random_addr(ieee->current_network.bssid);
|
|
||||||
|
|
||||||
ieee->current_network.rates_len = 4;
|
|
||||||
ieee->current_network.rates[0] =
|
|
||||||
RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_1MB;
|
|
||||||
ieee->current_network.rates[1] =
|
|
||||||
RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_2MB;
|
|
||||||
ieee->current_network.rates[2] =
|
|
||||||
RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_5MB;
|
|
||||||
ieee->current_network.rates[3] =
|
|
||||||
RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_11MB;
|
|
||||||
|
|
||||||
ieee->current_network.rates_ex_len = 8;
|
|
||||||
ieee->current_network.rates_ex[0] =
|
|
||||||
RTLLIB_OFDM_RATE_6MB;
|
|
||||||
ieee->current_network.rates_ex[1] =
|
|
||||||
RTLLIB_OFDM_RATE_9MB;
|
|
||||||
ieee->current_network.rates_ex[2] =
|
|
||||||
RTLLIB_OFDM_RATE_12MB;
|
|
||||||
ieee->current_network.rates_ex[3] =
|
|
||||||
RTLLIB_OFDM_RATE_18MB;
|
|
||||||
ieee->current_network.rates_ex[4] =
|
|
||||||
RTLLIB_OFDM_RATE_24MB;
|
|
||||||
ieee->current_network.rates_ex[5] =
|
|
||||||
RTLLIB_OFDM_RATE_36MB;
|
|
||||||
ieee->current_network.rates_ex[6] =
|
|
||||||
RTLLIB_OFDM_RATE_48MB;
|
|
||||||
ieee->current_network.rates_ex[7] =
|
|
||||||
RTLLIB_OFDM_RATE_54MB;
|
|
||||||
ieee->rate = 108;
|
|
||||||
|
|
||||||
ieee->current_network.qos_data.supported = 0;
|
|
||||||
ieee->set_wireless_mode(ieee->dev, WIRELESS_MODE_G);
|
|
||||||
ieee->current_network.mode = ieee->mode;
|
|
||||||
ieee->current_network.atim_window = 0;
|
|
||||||
ieee->current_network.capability = WLAN_CAPABILITY_IBSS;
|
|
||||||
}
|
|
||||||
|
|
||||||
netdev_info(ieee->dev, "%s(): ieee->mode = %d\n", __func__, ieee->mode);
|
|
||||||
if (ieee->mode == WIRELESS_MODE_N_24G)
|
|
||||||
HTUseDefaultSetting(ieee);
|
|
||||||
else
|
|
||||||
ieee->ht_info->bCurrentHTSupport = false;
|
|
||||||
|
|
||||||
ieee->SetHwRegHandler(ieee->dev, HW_VAR_MEDIA_STATUS,
|
|
||||||
(u8 *)(&ieee->link_state));
|
|
||||||
|
|
||||||
ieee->link_state = MAC80211_LINKED;
|
|
||||||
ieee->link_change(ieee->dev);
|
|
||||||
|
|
||||||
HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
|
|
||||||
rtllib_start_send_beacons(ieee);
|
|
||||||
|
|
||||||
notify_wx_assoc_event(ieee);
|
|
||||||
netif_carrier_on(ieee->dev);
|
|
||||||
|
|
||||||
mutex_unlock(&ieee->wx_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void rtllib_start_ibss(struct rtllib_device *ieee)
|
|
||||||
{
|
|
||||||
schedule_delayed_work(&ieee->start_ibss_wq, msecs_to_jiffies(150));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* this is called only in user context, with wx_mutex held */
|
/* this is called only in user context, with wx_mutex held */
|
||||||
static void rtllib_start_bss(struct rtllib_device *ieee)
|
static void rtllib_start_bss(struct rtllib_device *ieee)
|
||||||
{
|
{
|
||||||
@ -2495,7 +2195,7 @@ static struct sk_buff *rtllib_get_beacon_(struct rtllib_device *ieee)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
b = (struct rtllib_probe_response *)skb->data;
|
b = (struct rtllib_probe_response *)skb->data;
|
||||||
b->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_BEACON);
|
b->header.frame_control = cpu_to_le16(IEEE80211_STYPE_BEACON);
|
||||||
|
|
||||||
return skb;
|
return skb;
|
||||||
}
|
}
|
||||||
@ -2510,7 +2210,7 @@ struct sk_buff *rtllib_get_beacon(struct rtllib_device *ieee)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
b = (struct rtllib_probe_response *)skb->data;
|
b = (struct rtllib_probe_response *)skb->data;
|
||||||
b->header.seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
|
b->header.seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
|
||||||
|
|
||||||
if (ieee->seq_ctrl[0] == 0xFFF)
|
if (ieee->seq_ctrl[0] == 0xFFF)
|
||||||
ieee->seq_ctrl[0] = 0;
|
ieee->seq_ctrl[0] = 0;
|
||||||
@ -2521,31 +2221,28 @@ struct sk_buff *rtllib_get_beacon(struct rtllib_device *ieee)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(rtllib_get_beacon);
|
EXPORT_SYMBOL(rtllib_get_beacon);
|
||||||
|
|
||||||
void rtllib_softmac_stop_protocol(struct rtllib_device *ieee, u8 mesh_flag,
|
void rtllib_softmac_stop_protocol(struct rtllib_device *ieee)
|
||||||
u8 shutdown)
|
|
||||||
{
|
{
|
||||||
rtllib_stop_scan_syncro(ieee);
|
rtllib_stop_scan_syncro(ieee);
|
||||||
mutex_lock(&ieee->wx_mutex);
|
mutex_lock(&ieee->wx_mutex);
|
||||||
rtllib_stop_protocol(ieee, shutdown);
|
rtllib_stop_protocol(ieee);
|
||||||
mutex_unlock(&ieee->wx_mutex);
|
mutex_unlock(&ieee->wx_mutex);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(rtllib_softmac_stop_protocol);
|
EXPORT_SYMBOL(rtllib_softmac_stop_protocol);
|
||||||
|
|
||||||
void rtllib_stop_protocol(struct rtllib_device *ieee, u8 shutdown)
|
void rtllib_stop_protocol(struct rtllib_device *ieee)
|
||||||
{
|
{
|
||||||
if (!ieee->proto_started)
|
if (!ieee->proto_started)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (shutdown) {
|
ieee->proto_started = 0;
|
||||||
ieee->proto_started = 0;
|
ieee->proto_stoppping = 1;
|
||||||
ieee->proto_stoppping = 1;
|
ieee->rtllib_ips_leave(ieee->dev);
|
||||||
ieee->rtllib_ips_leave(ieee->dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
rtllib_stop_send_beacons(ieee);
|
|
||||||
del_timer_sync(&ieee->associate_timer);
|
del_timer_sync(&ieee->associate_timer);
|
||||||
|
mutex_unlock(&ieee->wx_mutex);
|
||||||
cancel_delayed_work_sync(&ieee->associate_retry_wq);
|
cancel_delayed_work_sync(&ieee->associate_retry_wq);
|
||||||
cancel_delayed_work_sync(&ieee->start_ibss_wq);
|
mutex_lock(&ieee->wx_mutex);
|
||||||
cancel_delayed_work_sync(&ieee->link_change_wq);
|
cancel_delayed_work_sync(&ieee->link_change_wq);
|
||||||
rtllib_stop_scan(ieee);
|
rtllib_stop_scan(ieee);
|
||||||
|
|
||||||
@ -2558,10 +2255,9 @@ void rtllib_stop_protocol(struct rtllib_device *ieee, u8 shutdown)
|
|||||||
rtllib_disassociate(ieee);
|
rtllib_disassociate(ieee);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shutdown) {
|
RemoveAllTS(ieee);
|
||||||
RemoveAllTS(ieee);
|
ieee->proto_stoppping = 0;
|
||||||
ieee->proto_stoppping = 0;
|
|
||||||
}
|
|
||||||
kfree(ieee->assocreq_ies);
|
kfree(ieee->assocreq_ies);
|
||||||
ieee->assocreq_ies = NULL;
|
ieee->assocreq_ies = NULL;
|
||||||
ieee->assocreq_ies_len = 0;
|
ieee->assocreq_ies_len = 0;
|
||||||
@ -2570,7 +2266,7 @@ void rtllib_stop_protocol(struct rtllib_device *ieee, u8 shutdown)
|
|||||||
ieee->assocresp_ies_len = 0;
|
ieee->assocresp_ies_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtllib_softmac_start_protocol(struct rtllib_device *ieee, u8 mesh_flag)
|
void rtllib_softmac_start_protocol(struct rtllib_device *ieee)
|
||||||
{
|
{
|
||||||
mutex_lock(&ieee->wx_mutex);
|
mutex_lock(&ieee->wx_mutex);
|
||||||
rtllib_start_protocol(ieee);
|
rtllib_start_protocol(ieee);
|
||||||
@ -2618,12 +2314,6 @@ void rtllib_start_protocol(struct rtllib_device *ieee)
|
|||||||
case IW_MODE_INFRA:
|
case IW_MODE_INFRA:
|
||||||
rtllib_start_bss(ieee);
|
rtllib_start_bss(ieee);
|
||||||
break;
|
break;
|
||||||
case IW_MODE_ADHOC:
|
|
||||||
rtllib_start_ibss(ieee);
|
|
||||||
break;
|
|
||||||
case IW_MODE_MONITOR:
|
|
||||||
rtllib_start_monitor_mode(ieee);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2682,7 +2372,6 @@ int rtllib_softmac_init(struct rtllib_device *ieee)
|
|||||||
timer_setup(&ieee->beacon_timer, rtllib_send_beacon_cb, 0);
|
timer_setup(&ieee->beacon_timer, rtllib_send_beacon_cb, 0);
|
||||||
|
|
||||||
INIT_DELAYED_WORK(&ieee->link_change_wq, (void *)rtllib_link_change_wq);
|
INIT_DELAYED_WORK(&ieee->link_change_wq, (void *)rtllib_link_change_wq);
|
||||||
INIT_DELAYED_WORK(&ieee->start_ibss_wq, (void *)rtllib_start_ibss_wq);
|
|
||||||
INIT_WORK(&ieee->associate_complete_wq, (void *)rtllib_associate_complete_wq);
|
INIT_WORK(&ieee->associate_complete_wq, (void *)rtllib_associate_complete_wq);
|
||||||
INIT_DELAYED_WORK(&ieee->associate_procedure_wq, (void *)rtllib_associate_procedure_wq);
|
INIT_DELAYED_WORK(&ieee->associate_procedure_wq, (void *)rtllib_associate_procedure_wq);
|
||||||
INIT_DELAYED_WORK(&ieee->softmac_scan_wq, (void *)rtllib_softmac_scan_wq);
|
INIT_DELAYED_WORK(&ieee->softmac_scan_wq, (void *)rtllib_softmac_scan_wq);
|
||||||
@ -2703,15 +2392,11 @@ int rtllib_softmac_init(struct rtllib_device *ieee)
|
|||||||
|
|
||||||
void rtllib_softmac_free(struct rtllib_device *ieee)
|
void rtllib_softmac_free(struct rtllib_device *ieee)
|
||||||
{
|
{
|
||||||
mutex_lock(&ieee->wx_mutex);
|
|
||||||
kfree(ieee->dot11d_info);
|
|
||||||
ieee->dot11d_info = NULL;
|
|
||||||
del_timer_sync(&ieee->associate_timer);
|
del_timer_sync(&ieee->associate_timer);
|
||||||
|
|
||||||
cancel_delayed_work_sync(&ieee->associate_retry_wq);
|
cancel_delayed_work_sync(&ieee->associate_retry_wq);
|
||||||
cancel_delayed_work_sync(&ieee->associate_procedure_wq);
|
cancel_delayed_work_sync(&ieee->associate_procedure_wq);
|
||||||
cancel_delayed_work_sync(&ieee->softmac_scan_wq);
|
cancel_delayed_work_sync(&ieee->softmac_scan_wq);
|
||||||
cancel_delayed_work_sync(&ieee->start_ibss_wq);
|
|
||||||
cancel_delayed_work_sync(&ieee->hw_wakeup_wq);
|
cancel_delayed_work_sync(&ieee->hw_wakeup_wq);
|
||||||
cancel_delayed_work_sync(&ieee->hw_sleep_wq);
|
cancel_delayed_work_sync(&ieee->hw_sleep_wq);
|
||||||
cancel_delayed_work_sync(&ieee->link_change_wq);
|
cancel_delayed_work_sync(&ieee->link_change_wq);
|
||||||
@ -2719,7 +2404,9 @@ void rtllib_softmac_free(struct rtllib_device *ieee)
|
|||||||
cancel_work_sync(&ieee->ips_leave_wq);
|
cancel_work_sync(&ieee->ips_leave_wq);
|
||||||
cancel_work_sync(&ieee->wx_sync_scan_wq);
|
cancel_work_sync(&ieee->wx_sync_scan_wq);
|
||||||
cancel_work_sync(&ieee->ps_task);
|
cancel_work_sync(&ieee->ps_task);
|
||||||
mutex_unlock(&ieee->wx_mutex);
|
|
||||||
|
kfree(ieee->dot11d_info);
|
||||||
|
ieee->dot11d_info = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct sk_buff *
|
static inline struct sk_buff *
|
||||||
@ -2737,7 +2424,7 @@ rtllib_disauth_skb(struct rtllib_network *beacon,
|
|||||||
skb_reserve(skb, ieee->tx_headroom);
|
skb_reserve(skb, ieee->tx_headroom);
|
||||||
|
|
||||||
disauth = skb_put(skb, sizeof(struct rtllib_disauth));
|
disauth = skb_put(skb, sizeof(struct rtllib_disauth));
|
||||||
disauth->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_DEAUTH);
|
disauth->header.frame_control = cpu_to_le16(IEEE80211_STYPE_DEAUTH);
|
||||||
disauth->header.duration_id = 0;
|
disauth->header.duration_id = 0;
|
||||||
|
|
||||||
ether_addr_copy(disauth->header.addr1, beacon->bssid);
|
ether_addr_copy(disauth->header.addr1, beacon->bssid);
|
||||||
@ -2764,7 +2451,7 @@ rtllib_disassociate_skb(struct rtllib_network *beacon,
|
|||||||
skb_reserve(skb, ieee->tx_headroom);
|
skb_reserve(skb, ieee->tx_headroom);
|
||||||
|
|
||||||
disass = skb_put(skb, sizeof(struct rtllib_disassoc));
|
disass = skb_put(skb, sizeof(struct rtllib_disassoc));
|
||||||
disass->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_DISASSOC);
|
disass->header.frame_control = cpu_to_le16(IEEE80211_STYPE_DISASSOC);
|
||||||
disass->header.duration_id = 0;
|
disass->header.duration_id = 0;
|
||||||
|
|
||||||
ether_addr_copy(disass->header.addr1, beacon->bssid);
|
ether_addr_copy(disass->header.addr1, beacon->bssid);
|
||||||
@ -2817,30 +2504,6 @@ u8 rtllib_ap_sec_type(struct rtllib_device *ieee)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtllib_MgntDisconnectIBSS(struct rtllib_device *rtllib)
|
|
||||||
{
|
|
||||||
u8 OpMode;
|
|
||||||
u8 i;
|
|
||||||
bool bFilterOutNonAssociatedBSSID = false;
|
|
||||||
|
|
||||||
rtllib->link_state = MAC80211_NOLINK;
|
|
||||||
|
|
||||||
for (i = 0; i < 6; i++)
|
|
||||||
rtllib->current_network.bssid[i] = 0x55;
|
|
||||||
|
|
||||||
rtllib->OpMode = RT_OP_MODE_NO_LINK;
|
|
||||||
rtllib->SetHwRegHandler(rtllib->dev, HW_VAR_BSSID,
|
|
||||||
rtllib->current_network.bssid);
|
|
||||||
OpMode = RT_OP_MODE_NO_LINK;
|
|
||||||
rtllib->SetHwRegHandler(rtllib->dev, HW_VAR_MEDIA_STATUS, &OpMode);
|
|
||||||
rtllib_stop_send_beacons(rtllib);
|
|
||||||
|
|
||||||
bFilterOutNonAssociatedBSSID = false;
|
|
||||||
rtllib->SetHwRegHandler(rtllib->dev, HW_VAR_CECHK_BSSID,
|
|
||||||
(u8 *)(&bFilterOutNonAssociatedBSSID));
|
|
||||||
notify_wx_assoc_event(rtllib);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void rtllib_MlmeDisassociateRequest(struct rtllib_device *rtllib,
|
static void rtllib_MlmeDisassociateRequest(struct rtllib_device *rtllib,
|
||||||
u8 *asSta, u8 asRsn)
|
u8 *asSta, u8 asRsn)
|
||||||
{
|
{
|
||||||
@ -2888,8 +2551,6 @@ bool rtllib_MgntDisconnect(struct rtllib_device *rtllib, u8 asRsn)
|
|||||||
rtllib->sta_wake_up(rtllib->dev);
|
rtllib->sta_wake_up(rtllib->dev);
|
||||||
|
|
||||||
if (rtllib->link_state == MAC80211_LINKED) {
|
if (rtllib->link_state == MAC80211_LINKED) {
|
||||||
if (rtllib->iw_mode == IW_MODE_ADHOC)
|
|
||||||
rtllib_MgntDisconnectIBSS(rtllib);
|
|
||||||
if (rtllib->iw_mode == IW_MODE_INFRA)
|
if (rtllib->iw_mode == IW_MODE_INFRA)
|
||||||
rtllib_MgntDisconnectAP(rtllib, asRsn);
|
rtllib_MgntDisconnectAP(rtllib, asRsn);
|
||||||
}
|
}
|
||||||
|
@ -50,12 +50,6 @@ int rtllib_wx_set_freq(struct rtllib_device *ieee, struct iw_request_info *a,
|
|||||||
}
|
}
|
||||||
ieee->current_network.channel = fwrq->m;
|
ieee->current_network.channel = fwrq->m;
|
||||||
ieee->set_chan(ieee->dev, ieee->current_network.channel);
|
ieee->set_chan(ieee->dev, ieee->current_network.channel);
|
||||||
|
|
||||||
if (ieee->iw_mode == IW_MODE_ADHOC)
|
|
||||||
if (ieee->link_state == MAC80211_LINKED) {
|
|
||||||
rtllib_stop_send_beacons(ieee);
|
|
||||||
rtllib_start_send_beacons(ieee);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
@ -140,7 +134,7 @@ int rtllib_wx_set_wap(struct rtllib_device *ieee,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ifup)
|
if (ifup)
|
||||||
rtllib_stop_protocol(ieee, true);
|
rtllib_stop_protocol(ieee);
|
||||||
|
|
||||||
/* just to avoid to give inconsistent infos in the
|
/* just to avoid to give inconsistent infos in the
|
||||||
* get wx method. not really needed otherwise
|
* get wx method. not really needed otherwise
|
||||||
@ -258,7 +252,6 @@ int rtllib_wx_set_mode(struct rtllib_device *ieee, struct iw_request_info *a,
|
|||||||
mutex_lock(&ieee->wx_mutex);
|
mutex_lock(&ieee->wx_mutex);
|
||||||
switch (wrqu->mode) {
|
switch (wrqu->mode) {
|
||||||
case IW_MODE_MONITOR:
|
case IW_MODE_MONITOR:
|
||||||
case IW_MODE_ADHOC:
|
|
||||||
case IW_MODE_INFRA:
|
case IW_MODE_INFRA:
|
||||||
break;
|
break;
|
||||||
case IW_MODE_AUTO:
|
case IW_MODE_AUTO:
|
||||||
@ -284,7 +277,7 @@ int rtllib_wx_set_mode(struct rtllib_device *ieee, struct iw_request_info *a,
|
|||||||
if (!ieee->proto_started) {
|
if (!ieee->proto_started) {
|
||||||
ieee->iw_mode = wrqu->mode;
|
ieee->iw_mode = wrqu->mode;
|
||||||
} else {
|
} else {
|
||||||
rtllib_stop_protocol(ieee, true);
|
rtllib_stop_protocol(ieee);
|
||||||
ieee->iw_mode = wrqu->mode;
|
ieee->iw_mode = wrqu->mode;
|
||||||
rtllib_start_protocol(ieee);
|
rtllib_start_protocol(ieee);
|
||||||
}
|
}
|
||||||
@ -317,7 +310,6 @@ void rtllib_wx_sync_scan_wq(void *data)
|
|||||||
rtllib_sta_ps_send_null_frame(ieee, 1);
|
rtllib_sta_ps_send_null_frame(ieee, 1);
|
||||||
|
|
||||||
rtllib_stop_all_queues(ieee);
|
rtllib_stop_all_queues(ieee);
|
||||||
rtllib_stop_send_beacons(ieee);
|
|
||||||
ieee->link_state = MAC80211_LINKED_SCANNING;
|
ieee->link_state = MAC80211_LINKED_SCANNING;
|
||||||
ieee->link_change(ieee->dev);
|
ieee->link_change(ieee->dev);
|
||||||
/* wait for ps packet to be kicked out successfully */
|
/* wait for ps packet to be kicked out successfully */
|
||||||
@ -325,7 +317,7 @@ void rtllib_wx_sync_scan_wq(void *data)
|
|||||||
|
|
||||||
ieee->ScanOperationBackupHandler(ieee->dev, SCAN_OPT_BACKUP);
|
ieee->ScanOperationBackupHandler(ieee->dev, SCAN_OPT_BACKUP);
|
||||||
|
|
||||||
if (ieee->ht_info->bCurrentHTSupport && ieee->ht_info->enable_ht &&
|
if (ieee->ht_info->current_ht_support && ieee->ht_info->enable_ht &&
|
||||||
ieee->ht_info->bCurBW40MHz) {
|
ieee->ht_info->bCurBW40MHz) {
|
||||||
b40M = 1;
|
b40M = 1;
|
||||||
chan_offset = ieee->ht_info->CurSTAExtChnlOffset;
|
chan_offset = ieee->ht_info->CurSTAExtChnlOffset;
|
||||||
@ -361,9 +353,6 @@ void rtllib_wx_sync_scan_wq(void *data)
|
|||||||
ieee->link_detect_info.NumRecvBcnInPeriod = 1;
|
ieee->link_detect_info.NumRecvBcnInPeriod = 1;
|
||||||
ieee->link_detect_info.NumRecvDataInPeriod = 1;
|
ieee->link_detect_info.NumRecvDataInPeriod = 1;
|
||||||
}
|
}
|
||||||
if (ieee->iw_mode == IW_MODE_ADHOC)
|
|
||||||
rtllib_start_send_beacons(ieee);
|
|
||||||
|
|
||||||
rtllib_wake_all_queues(ieee);
|
rtllib_wake_all_queues(ieee);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@ -412,7 +401,7 @@ int rtllib_wx_set_essid(struct rtllib_device *ieee,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (proto_started)
|
if (proto_started)
|
||||||
rtllib_stop_protocol(ieee, true);
|
rtllib_stop_protocol(ieee);
|
||||||
|
|
||||||
/* this is just to be sure that the GET wx callback
|
/* this is just to be sure that the GET wx callback
|
||||||
* has consistent infos. not needed otherwise
|
* has consistent infos. not needed otherwise
|
||||||
@ -447,38 +436,6 @@ int rtllib_wx_get_mode(struct rtllib_device *ieee, struct iw_request_info *a,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(rtllib_wx_get_mode);
|
EXPORT_SYMBOL(rtllib_wx_get_mode);
|
||||||
|
|
||||||
int rtllib_wx_set_rawtx(struct rtllib_device *ieee,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *extra)
|
|
||||||
{
|
|
||||||
int *parms = (int *)extra;
|
|
||||||
int enable = (parms[0] > 0);
|
|
||||||
short prev = ieee->raw_tx;
|
|
||||||
|
|
||||||
mutex_lock(&ieee->wx_mutex);
|
|
||||||
|
|
||||||
if (enable)
|
|
||||||
ieee->raw_tx = 1;
|
|
||||||
else
|
|
||||||
ieee->raw_tx = 0;
|
|
||||||
|
|
||||||
netdev_info(ieee->dev, "raw TX is %s\n",
|
|
||||||
ieee->raw_tx ? "enabled" : "disabled");
|
|
||||||
|
|
||||||
if (ieee->iw_mode == IW_MODE_MONITOR) {
|
|
||||||
if (prev == 0 && ieee->raw_tx)
|
|
||||||
netif_carrier_on(ieee->dev);
|
|
||||||
|
|
||||||
if (prev && ieee->raw_tx == 1)
|
|
||||||
netif_carrier_off(ieee->dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_unlock(&ieee->wx_mutex);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(rtllib_wx_set_rawtx);
|
|
||||||
|
|
||||||
int rtllib_wx_get_name(struct rtllib_device *ieee, struct iw_request_info *info,
|
int rtllib_wx_get_name(struct rtllib_device *ieee, struct iw_request_info *info,
|
||||||
union iwreq_data *wrqu, char *extra)
|
union iwreq_data *wrqu, char *extra)
|
||||||
{
|
{
|
||||||
|
@ -268,12 +268,12 @@ static void rtllib_tx_query_agg_cap(struct rtllib_device *ieee,
|
|||||||
{
|
{
|
||||||
struct rt_hi_throughput *ht_info = ieee->ht_info;
|
struct rt_hi_throughput *ht_info = ieee->ht_info;
|
||||||
struct tx_ts_record *pTxTs = NULL;
|
struct tx_ts_record *pTxTs = NULL;
|
||||||
struct rtllib_hdr_1addr *hdr = (struct rtllib_hdr_1addr *)skb->data;
|
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||||||
|
|
||||||
if (rtllib_act_scanning(ieee, false))
|
if (rtllib_act_scanning(ieee, false))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!ht_info->bCurrentHTSupport || !ht_info->enable_ht)
|
if (!ht_info->current_ht_support || !ht_info->enable_ht)
|
||||||
return;
|
return;
|
||||||
if (!IsQoSDataFrame(skb->data))
|
if (!IsQoSDataFrame(skb->data))
|
||||||
return;
|
return;
|
||||||
@ -289,7 +289,7 @@ static void rtllib_tx_query_agg_cap(struct rtllib_device *ieee,
|
|||||||
if (!ieee->GetNmodeSupportBySecCfg(ieee->dev))
|
if (!ieee->GetNmodeSupportBySecCfg(ieee->dev))
|
||||||
return;
|
return;
|
||||||
if (ht_info->bCurrentAMPDUEnable) {
|
if (ht_info->bCurrentAMPDUEnable) {
|
||||||
if (!GetTs(ieee, (struct ts_common_info **)(&pTxTs), hdr->addr1,
|
if (!rtllib_get_ts(ieee, (struct ts_common_info **)(&pTxTs), hdr->addr1,
|
||||||
skb->priority, TX_DIR, true)) {
|
skb->priority, TX_DIR, true)) {
|
||||||
netdev_info(ieee->dev, "%s: can't get TS\n", __func__);
|
netdev_info(ieee->dev, "%s: can't get TS\n", __func__);
|
||||||
return;
|
return;
|
||||||
@ -354,7 +354,7 @@ static void rtllib_query_HTCapShortGI(struct rtllib_device *ieee,
|
|||||||
|
|
||||||
tcb_desc->bUseShortGI = false;
|
tcb_desc->bUseShortGI = false;
|
||||||
|
|
||||||
if (!ht_info->bCurrentHTSupport || !ht_info->enable_ht)
|
if (!ht_info->current_ht_support || !ht_info->enable_ht)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (ht_info->forced_short_gi) {
|
if (ht_info->forced_short_gi) {
|
||||||
@ -375,7 +375,7 @@ static void rtllib_query_BandwidthMode(struct rtllib_device *ieee,
|
|||||||
|
|
||||||
tcb_desc->bPacketBW = false;
|
tcb_desc->bPacketBW = false;
|
||||||
|
|
||||||
if (!ht_info->bCurrentHTSupport || !ht_info->enable_ht)
|
if (!ht_info->current_ht_support || !ht_info->enable_ht)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (tcb_desc->bMulticast || tcb_desc->bBroadcast)
|
if (tcb_desc->bMulticast || tcb_desc->bBroadcast)
|
||||||
@ -438,7 +438,7 @@ static void rtllib_query_protectionmode(struct rtllib_device *ieee,
|
|||||||
tcb_desc->rts_rate = MGN_24M;
|
tcb_desc->rts_rate = MGN_24M;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ht_info->bCurrentHTSupport && ht_info->enable_ht) {
|
if (ht_info->current_ht_support && ht_info->enable_ht) {
|
||||||
u8 HTOpMode = ht_info->current_op_mode;
|
u8 HTOpMode = ht_info->current_op_mode;
|
||||||
|
|
||||||
if ((ht_info->bCurBW40MHz && (HTOpMode == 2 ||
|
if ((ht_info->bCurBW40MHz && (HTOpMode == 2 ||
|
||||||
@ -482,8 +482,7 @@ static void rtllib_txrate_selectmode(struct rtllib_device *ieee,
|
|||||||
tcb_desc->tx_use_drv_assinged_rate = true;
|
tcb_desc->tx_use_drv_assinged_rate = true;
|
||||||
if (!tcb_desc->tx_dis_rate_fallback ||
|
if (!tcb_desc->tx_dis_rate_fallback ||
|
||||||
!tcb_desc->tx_use_drv_assinged_rate) {
|
!tcb_desc->tx_use_drv_assinged_rate) {
|
||||||
if (ieee->iw_mode == IW_MODE_INFRA ||
|
if (ieee->iw_mode == IW_MODE_INFRA)
|
||||||
ieee->iw_mode == IW_MODE_ADHOC)
|
|
||||||
tcb_desc->ratr_index = 0;
|
tcb_desc->ratr_index = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -496,13 +495,13 @@ static u16 rtllib_query_seqnum(struct rtllib_device *ieee, struct sk_buff *skb,
|
|||||||
if (is_multicast_ether_addr(dst))
|
if (is_multicast_ether_addr(dst))
|
||||||
return 0;
|
return 0;
|
||||||
if (IsQoSDataFrame(skb->data)) {
|
if (IsQoSDataFrame(skb->data)) {
|
||||||
struct tx_ts_record *pTS = NULL;
|
struct tx_ts_record *ts = NULL;
|
||||||
|
|
||||||
if (!GetTs(ieee, (struct ts_common_info **)(&pTS), dst,
|
if (!rtllib_get_ts(ieee, (struct ts_common_info **)(&ts), dst,
|
||||||
skb->priority, TX_DIR, true))
|
skb->priority, TX_DIR, true))
|
||||||
return 0;
|
return 0;
|
||||||
seqnum = pTS->TxCurSeq;
|
seqnum = ts->TxCurSeq;
|
||||||
pTS->TxCurSeq = (pTS->TxCurSeq + 1) % 4096;
|
ts->TxCurSeq = (ts->TxCurSeq + 1) % 4096;
|
||||||
return seqnum;
|
return seqnum;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -544,17 +543,17 @@ static int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev)
|
|||||||
struct rtllib_device *ieee = (struct rtllib_device *)
|
struct rtllib_device *ieee = (struct rtllib_device *)
|
||||||
netdev_priv_rsl(dev);
|
netdev_priv_rsl(dev);
|
||||||
struct rtllib_txb *txb = NULL;
|
struct rtllib_txb *txb = NULL;
|
||||||
struct rtllib_hdr_3addrqos *frag_hdr;
|
struct ieee80211_qos_hdr *frag_hdr;
|
||||||
int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
|
int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
struct net_device_stats *stats = &ieee->stats;
|
struct net_device_stats *stats = &ieee->stats;
|
||||||
int ether_type = 0, encrypt;
|
int ether_type = 0, encrypt;
|
||||||
int bytes, fc, qos_ctl = 0, hdr_len;
|
int bytes, fc, qos_ctl = 0, hdr_len;
|
||||||
struct sk_buff *skb_frag;
|
struct sk_buff *skb_frag;
|
||||||
struct rtllib_hdr_3addrqos header = { /* Ensure zero initialized */
|
struct ieee80211_qos_hdr header = { /* Ensure zero initialized */
|
||||||
.duration_id = 0,
|
.duration_id = 0,
|
||||||
.seq_ctl = 0,
|
.seq_ctrl = 0,
|
||||||
.qos_ctl = 0
|
.qos_ctrl = 0
|
||||||
};
|
};
|
||||||
int qos_activated = ieee->current_network.qos_data.active;
|
int qos_activated = ieee->current_network.qos_data.active;
|
||||||
u8 dest[ETH_ALEN];
|
u8 dest[ETH_ALEN];
|
||||||
@ -577,297 +576,271 @@ static int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev)
|
|||||||
goto success;
|
goto success;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (likely(ieee->raw_tx == 0)) {
|
if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
|
||||||
if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
|
netdev_warn(ieee->dev, "skb too small (%d).\n",
|
||||||
netdev_warn(ieee->dev, "skb too small (%d).\n",
|
skb->len);
|
||||||
skb->len);
|
goto success;
|
||||||
goto success;
|
}
|
||||||
}
|
/* Save source and destination addresses */
|
||||||
/* Save source and destination addresses */
|
ether_addr_copy(dest, skb->data);
|
||||||
ether_addr_copy(dest, skb->data);
|
ether_addr_copy(src, skb->data + ETH_ALEN);
|
||||||
ether_addr_copy(src, skb->data + ETH_ALEN);
|
|
||||||
|
|
||||||
memset(skb->cb, 0, sizeof(skb->cb));
|
memset(skb->cb, 0, sizeof(skb->cb));
|
||||||
ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
|
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->LPSDelayCnt = 200;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (ether_type == ETH_P_ARP) {
|
|
||||||
netdev_info(ieee->dev,
|
|
||||||
"=================>DHCP Protocol start tx ARP pkt!!\n");
|
|
||||||
bdhcp = true;
|
|
||||||
ieee->LPSDelayCnt =
|
|
||||||
ieee->current_network.tim.tim_count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
skb->priority = rtllib_classify(skb, IsAmsdu);
|
|
||||||
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 | RTLLIB_FCTL_WEP;
|
|
||||||
else
|
|
||||||
fc = RTLLIB_FTYPE_DATA;
|
|
||||||
|
|
||||||
if (qos_activated)
|
|
||||||
fc |= RTLLIB_STYPE_QOS_DATA;
|
|
||||||
else
|
|
||||||
fc |= RTLLIB_STYPE_DATA;
|
|
||||||
|
|
||||||
if (ieee->iw_mode == IW_MODE_INFRA) {
|
|
||||||
fc |= RTLLIB_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);
|
|
||||||
if (IsAmsdu)
|
|
||||||
ether_addr_copy(header.addr3,
|
|
||||||
ieee->current_network.bssid);
|
|
||||||
else
|
|
||||||
ether_addr_copy(header.addr3, dest);
|
|
||||||
} else if (ieee->iw_mode == IW_MODE_ADHOC) {
|
|
||||||
/* not From/To DS: Addr1 = DA, Addr2 = SA,
|
|
||||||
* Addr3 = BSSID
|
|
||||||
*/
|
|
||||||
ether_addr_copy(header.addr1, dest);
|
|
||||||
ether_addr_copy(header.addr2, src);
|
|
||||||
ether_addr_copy(header.addr3,
|
|
||||||
ieee->current_network.bssid);
|
|
||||||
}
|
|
||||||
|
|
||||||
bIsMulticast = is_multicast_ether_addr(header.addr1);
|
|
||||||
|
|
||||||
header.frame_ctl = cpu_to_le16(fc);
|
|
||||||
|
|
||||||
/* Determine fragmentation size based on destination (multicast
|
|
||||||
* and broadcast are not fragmented)
|
|
||||||
*/
|
|
||||||
if (bIsMulticast) {
|
|
||||||
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_ctl = 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->bHwSec = 1;
|
|
||||||
else
|
|
||||||
tcb_desc->bHwSec = 0;
|
|
||||||
skb_reserve(skb_frag,
|
|
||||||
crypt->ops->extra_mpdu_prefix_len +
|
|
||||||
crypt->ops->extra_msdu_prefix_len);
|
|
||||||
} else {
|
|
||||||
tcb_desc->bHwSec = 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_ctl = cpu_to_le16(fc |
|
|
||||||
RTLLIB_FCTL_MOREFRAGS);
|
|
||||||
bytes = bytes_per_frag;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
/* The last fragment has the remaining length */
|
|
||||||
bytes = bytes_last_frag;
|
|
||||||
}
|
|
||||||
if ((qos_activated) && (!bIsMulticast)) {
|
|
||||||
frag_hdr->seq_ctl =
|
|
||||||
cpu_to_le16(rtllib_query_seqnum(ieee, skb_frag,
|
|
||||||
header.addr1));
|
|
||||||
frag_hdr->seq_ctl =
|
|
||||||
cpu_to_le16(le16_to_cpu(frag_hdr->seq_ctl) << 4 | i);
|
|
||||||
} else {
|
|
||||||
frag_hdr->seq_ctl =
|
|
||||||
cpu_to_le16(ieee->seq_ctrl[0] << 4 | i);
|
|
||||||
}
|
|
||||||
/* Put a SNAP header on the first fragment */
|
|
||||||
if (i == 0) {
|
|
||||||
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) && (!bIsMulticast)) {
|
|
||||||
if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF)
|
|
||||||
ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0;
|
|
||||||
else
|
|
||||||
ieee->seq_ctrl[UP2AC(skb->priority) + 1]++;
|
|
||||||
} else {
|
|
||||||
if (ieee->seq_ctrl[0] == 0xFFF)
|
|
||||||
ieee->seq_ctrl[0] = 0;
|
|
||||||
else
|
|
||||||
ieee->seq_ctrl[0]++;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (unlikely(skb->len < sizeof(struct rtllib_hdr_3addr))) {
|
|
||||||
netdev_warn(ieee->dev, "skb too small (%d).\n",
|
|
||||||
skb->len);
|
|
||||||
goto success;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (ieee->iw_mode == IW_MODE_MONITOR) {
|
||||||
txb = rtllib_alloc_txb(1, skb->len, GFP_ATOMIC);
|
txb = rtllib_alloc_txb(1, skb->len, GFP_ATOMIC);
|
||||||
if (!txb) {
|
if (unlikely(!txb)) {
|
||||||
netdev_warn(ieee->dev, "Could not allocate TXB\n");
|
netdev_warn(ieee->dev,
|
||||||
|
"Could not allocate TXB\n");
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
txb->encrypted = 0;
|
txb->encrypted = 0;
|
||||||
txb->payload_size = cpu_to_le16(skb->len);
|
txb->payload_size = cpu_to_le16(skb->len);
|
||||||
skb_put_data(txb->fragments[0], skb->data, 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->LPSDelayCnt = 200;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (ether_type == ETH_P_ARP) {
|
||||||
|
netdev_info(ieee->dev,
|
||||||
|
"=================>DHCP Protocol start tx ARP pkt!!\n");
|
||||||
|
bdhcp = true;
|
||||||
|
ieee->LPSDelayCnt =
|
||||||
|
ieee->current_network.tim.tim_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
skb->priority = rtllib_classify(skb, IsAmsdu);
|
||||||
|
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);
|
||||||
|
if (IsAmsdu)
|
||||||
|
ether_addr_copy(header.addr3,
|
||||||
|
ieee->current_network.bssid);
|
||||||
|
else
|
||||||
|
ether_addr_copy(header.addr3, dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
bIsMulticast = 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 (bIsMulticast) {
|
||||||
|
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->bHwSec = 1;
|
||||||
|
else
|
||||||
|
tcb_desc->bHwSec = 0;
|
||||||
|
skb_reserve(skb_frag,
|
||||||
|
crypt->ops->extra_mpdu_prefix_len +
|
||||||
|
crypt->ops->extra_msdu_prefix_len);
|
||||||
|
} else {
|
||||||
|
tcb_desc->bHwSec = 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) && (!bIsMulticast)) {
|
||||||
|
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) && (!bIsMulticast)) {
|
||||||
|
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:
|
success:
|
||||||
|
@ -29,7 +29,7 @@ static inline char *rtl819x_translate_scan(struct rtllib_device *ieee,
|
|||||||
struct iw_request_info *info)
|
struct iw_request_info *info)
|
||||||
{
|
{
|
||||||
char custom[MAX_CUSTOM_LEN];
|
char custom[MAX_CUSTOM_LEN];
|
||||||
char proto_name[IFNAMSIZ];
|
char proto_name[6];
|
||||||
char *pname = proto_name;
|
char *pname = proto_name;
|
||||||
char *p;
|
char *p;
|
||||||
struct iw_event iwe;
|
struct iw_event iwe;
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
|
||||||
config RTL8192U
|
|
||||||
tristate "RealTek RTL8192U Wireless LAN NIC driver"
|
|
||||||
depends on PCI && WLAN && USB
|
|
||||||
depends on m
|
|
||||||
select WIRELESS_EXT
|
|
||||||
select WEXT_PRIV
|
|
||||||
select CRC32
|
|
||||||
select CRYPTO
|
|
||||||
select CRYPTO_AES
|
|
||||||
select CRYPTO_CCM
|
|
||||||
select CRYPTO_LIB_ARC4
|
|
@ -1,27 +0,0 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
|
||||||
NIC_SELECT = RTL8192U
|
|
||||||
|
|
||||||
ccflags-y += -DCONFIG_FORCE_HARD_FLOAT=y
|
|
||||||
ccflags-y += -DJACKSON_NEW_8187 -DJACKSON_NEW_RX
|
|
||||||
ccflags-y += -DTHOMAS_BEACON -DTHOMAS_TASKLET -DTHOMAS_SKB -DTHOMAS_TURBO
|
|
||||||
|
|
||||||
r8192u_usb-y := r8192U_core.o r8180_93cx6.o r8192U_wx.o \
|
|
||||||
r8190_rtl8256.o r819xU_phy.o r819xU_firmware.o \
|
|
||||||
r819xU_cmdpkt.o r8192U_dm.o r819xU_firmware_img.o \
|
|
||||||
r8192U_debugfs.o \
|
|
||||||
ieee80211/ieee80211_crypt.o \
|
|
||||||
ieee80211/ieee80211_crypt_tkip.o \
|
|
||||||
ieee80211/ieee80211_crypt_ccmp.o \
|
|
||||||
ieee80211/ieee80211_crypt_wep.o \
|
|
||||||
ieee80211/ieee80211_rx.o \
|
|
||||||
ieee80211/ieee80211_softmac.o \
|
|
||||||
ieee80211/ieee80211_tx.o \
|
|
||||||
ieee80211/ieee80211_wx.o \
|
|
||||||
ieee80211/ieee80211_module.o \
|
|
||||||
ieee80211/ieee80211_softmac_wx.o \
|
|
||||||
ieee80211/rtl819x_HTProc.o \
|
|
||||||
ieee80211/rtl819x_TSProc.o \
|
|
||||||
ieee80211/rtl819x_BAProc.o \
|
|
||||||
ieee80211/dot11d.o
|
|
||||||
|
|
||||||
obj-$(CONFIG_RTL8192U) += r8192u_usb.o
|
|
@ -1,16 +0,0 @@
|
|||||||
To-do list:
|
|
||||||
|
|
||||||
* 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.
|
|
@ -1 +0,0 @@
|
|||||||
Andrea Merello <andrea.merello@gmail.com>
|
|
@ -1,4 +0,0 @@
|
|||||||
v 0.1
|
|
||||||
|
|
||||||
First version.
|
|
||||||
This is based on the rtl8180-sa2400 pre-0.22-CVS code..
|
|
@ -1,174 +0,0 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0
|
|
||||||
/* Implement 802.11d. */
|
|
||||||
|
|
||||||
#include "dot11d.h"
|
|
||||||
|
|
||||||
void rtl8192u_dot11d_init(struct ieee80211_device *ieee)
|
|
||||||
{
|
|
||||||
struct rt_dot11d_info *dot11d_info = GET_DOT11D_INFO(ieee);
|
|
||||||
|
|
||||||
dot11d_info->dot11d_enabled = false;
|
|
||||||
|
|
||||||
dot11d_info->state = DOT11D_STATE_NONE;
|
|
||||||
dot11d_info->country_ie_len = 0;
|
|
||||||
memset(dot11d_info->channel_map, 0, MAX_CHANNEL_NUMBER + 1);
|
|
||||||
memset(dot11d_info->max_tx_pwr_dbm_list, 0xFF, MAX_CHANNEL_NUMBER + 1);
|
|
||||||
RESET_CIE_WATCHDOG(ieee);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(rtl8192u_dot11d_init);
|
|
||||||
|
|
||||||
/* Reset to the state as we are just entering a regulatory domain. */
|
|
||||||
void dot11d_reset(struct ieee80211_device *ieee)
|
|
||||||
{
|
|
||||||
u32 i;
|
|
||||||
struct rt_dot11d_info *dot11d_info = GET_DOT11D_INFO(ieee);
|
|
||||||
/* Clear old channel map */
|
|
||||||
memset(dot11d_info->channel_map, 0, MAX_CHANNEL_NUMBER + 1);
|
|
||||||
memset(dot11d_info->max_tx_pwr_dbm_list, 0xFF, MAX_CHANNEL_NUMBER + 1);
|
|
||||||
/* Set new channel map */
|
|
||||||
for (i = 1; i <= 11; i++)
|
|
||||||
(dot11d_info->channel_map)[i] = 1;
|
|
||||||
|
|
||||||
for (i = 12; i <= 14; i++)
|
|
||||||
(dot11d_info->channel_map)[i] = 2;
|
|
||||||
|
|
||||||
dot11d_info->state = DOT11D_STATE_NONE;
|
|
||||||
dot11d_info->country_ie_len = 0;
|
|
||||||
RESET_CIE_WATCHDOG(ieee);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(dot11d_reset);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Update country IE from Beacon or Probe Resopnse and configure PHY for
|
|
||||||
* operation in the regulatory domain.
|
|
||||||
*
|
|
||||||
* TODO: Configure Tx power.
|
|
||||||
* Assumption:
|
|
||||||
* 1. IS_DOT11D_ENABLE() is TRUE.
|
|
||||||
* 2. Input IE is an valid one.
|
|
||||||
*/
|
|
||||||
void dot11d_update_country_ie(struct ieee80211_device *dev, u8 *pTaddr,
|
|
||||||
u16 CoutryIeLen, u8 *pCoutryIe)
|
|
||||||
{
|
|
||||||
struct rt_dot11d_info *dot11d_info = GET_DOT11D_INFO(dev);
|
|
||||||
u8 i, j, NumTriples, MaxChnlNum;
|
|
||||||
struct chnl_txpower_triple *pTriple;
|
|
||||||
|
|
||||||
memset(dot11d_info->channel_map, 0, MAX_CHANNEL_NUMBER + 1);
|
|
||||||
memset(dot11d_info->max_tx_pwr_dbm_list, 0xFF, MAX_CHANNEL_NUMBER + 1);
|
|
||||||
MaxChnlNum = 0;
|
|
||||||
NumTriples = (CoutryIeLen - 3) / 3; /* skip 3-byte country string. */
|
|
||||||
pTriple = (struct chnl_txpower_triple *)(pCoutryIe + 3);
|
|
||||||
for (i = 0; i < NumTriples; i++) {
|
|
||||||
if (MaxChnlNum >= pTriple->first_channel) {
|
|
||||||
/* It is not in a monotonically increasing order, so
|
|
||||||
* stop processing.
|
|
||||||
*/
|
|
||||||
netdev_err(dev->dev, "%s: Invalid country IE, skip it 1\n", __func__);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (MAX_CHANNEL_NUMBER < (pTriple->first_channel + pTriple->num_channels)) {
|
|
||||||
/* It is not a valid set of channel id, so stop
|
|
||||||
* processing.
|
|
||||||
*/
|
|
||||||
netdev_err(dev->dev, "%s: Invalid country IE, skip it 2\n", __func__);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (j = 0; j < pTriple->num_channels; j++) {
|
|
||||||
dot11d_info->channel_map[pTriple->first_channel + j] = 1;
|
|
||||||
dot11d_info->max_tx_pwr_dbm_list[pTriple->first_channel + j] = pTriple->max_tx_pwr_dbm;
|
|
||||||
MaxChnlNum = pTriple->first_channel + j;
|
|
||||||
}
|
|
||||||
|
|
||||||
pTriple = (struct chnl_txpower_triple *)((u8 *)pTriple + 3);
|
|
||||||
}
|
|
||||||
netdev_info(dev->dev, "Channel List:");
|
|
||||||
for (i = 1; i <= MAX_CHANNEL_NUMBER; i++)
|
|
||||||
if (dot11d_info->channel_map[i] > 0)
|
|
||||||
netdev_info(dev->dev, " %d", i);
|
|
||||||
netdev_info(dev->dev, "\n");
|
|
||||||
|
|
||||||
UPDATE_CIE_SRC(dev, pTaddr);
|
|
||||||
|
|
||||||
dot11d_info->country_ie_len = CoutryIeLen;
|
|
||||||
memcpy(dot11d_info->country_ie_buf, pCoutryIe, CoutryIeLen);
|
|
||||||
dot11d_info->state = DOT11D_STATE_LEARNED;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(dot11d_update_country_ie);
|
|
||||||
|
|
||||||
u8 dot11d_get_max_tx_pwr_in_dbm(struct ieee80211_device *dev, u8 Channel)
|
|
||||||
{
|
|
||||||
struct rt_dot11d_info *dot11d_info = GET_DOT11D_INFO(dev);
|
|
||||||
u8 MaxTxPwrInDbm = 255;
|
|
||||||
|
|
||||||
if (Channel > MAX_CHANNEL_NUMBER) {
|
|
||||||
netdev_err(dev->dev, "%s: Invalid Channel\n", __func__);
|
|
||||||
return MaxTxPwrInDbm;
|
|
||||||
}
|
|
||||||
if (dot11d_info->channel_map[Channel])
|
|
||||||
MaxTxPwrInDbm = dot11d_info->max_tx_pwr_dbm_list[Channel];
|
|
||||||
|
|
||||||
return MaxTxPwrInDbm;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(dot11d_get_max_tx_pwr_in_dbm);
|
|
||||||
|
|
||||||
void dot11d_scan_complete(struct ieee80211_device *dev)
|
|
||||||
{
|
|
||||||
struct rt_dot11d_info *dot11d_info = GET_DOT11D_INFO(dev);
|
|
||||||
|
|
||||||
switch (dot11d_info->state) {
|
|
||||||
case DOT11D_STATE_LEARNED:
|
|
||||||
dot11d_info->state = DOT11D_STATE_DONE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DOT11D_STATE_DONE:
|
|
||||||
if (GET_CIE_WATCHDOG(dev) == 0) {
|
|
||||||
/* Reset country IE if previous one is gone. */
|
|
||||||
dot11d_reset(dev);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case DOT11D_STATE_NONE:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(dot11d_scan_complete);
|
|
||||||
|
|
||||||
int is_legal_channel(struct ieee80211_device *dev, u8 channel)
|
|
||||||
{
|
|
||||||
struct rt_dot11d_info *dot11d_info = GET_DOT11D_INFO(dev);
|
|
||||||
|
|
||||||
if (channel > MAX_CHANNEL_NUMBER) {
|
|
||||||
netdev_err(dev->dev, "%s: Invalid Channel\n", __func__);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (dot11d_info->channel_map[channel] > 0)
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(is_legal_channel);
|
|
||||||
|
|
||||||
int to_legal_channel(struct ieee80211_device *dev, u8 channel)
|
|
||||||
{
|
|
||||||
struct rt_dot11d_info *dot11d_info = GET_DOT11D_INFO(dev);
|
|
||||||
u8 default_chn = 0;
|
|
||||||
u32 i = 0;
|
|
||||||
|
|
||||||
for (i = 1; i <= MAX_CHANNEL_NUMBER; i++) {
|
|
||||||
if (dot11d_info->channel_map[i] > 0) {
|
|
||||||
default_chn = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (channel > MAX_CHANNEL_NUMBER) {
|
|
||||||
netdev_err(dev->dev, "%s: Invalid Channel\n", __func__);
|
|
||||||
return default_chn;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dot11d_info->channel_map[channel] > 0)
|
|
||||||
return channel;
|
|
||||||
|
|
||||||
return default_chn;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(to_legal_channel);
|
|
@ -1,57 +0,0 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
#ifndef __INC_DOT11D_H
|
|
||||||
#define __INC_DOT11D_H
|
|
||||||
|
|
||||||
#include "ieee80211.h"
|
|
||||||
|
|
||||||
struct chnl_txpower_triple {
|
|
||||||
u8 first_channel;
|
|
||||||
u8 num_channels;
|
|
||||||
u8 max_tx_pwr_dbm;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum dot11d_state {
|
|
||||||
DOT11D_STATE_NONE = 0,
|
|
||||||
DOT11D_STATE_LEARNED,
|
|
||||||
DOT11D_STATE_DONE,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct rt_dot11d_info {
|
|
||||||
u16 country_ie_len; /* > 0 if country_ie_buf[] contains valid country information element. */
|
|
||||||
|
|
||||||
/* country_ie_src_addr u16 aligned for comparison and copy */
|
|
||||||
u8 country_ie_src_addr[ETH_ALEN]; /* Source AP of the country IE. */
|
|
||||||
u8 country_ie_buf[MAX_IE_LEN];
|
|
||||||
u8 country_ie_watchdog;
|
|
||||||
|
|
||||||
u8 channel_map[MAX_CHANNEL_NUMBER + 1]; /* !Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan) */
|
|
||||||
u8 max_tx_pwr_dbm_list[MAX_CHANNEL_NUMBER + 1];
|
|
||||||
|
|
||||||
enum dot11d_state state;
|
|
||||||
u8 dot11d_enabled; /* dot11MultiDomainCapabilityEnabled */
|
|
||||||
};
|
|
||||||
|
|
||||||
#define GET_DOT11D_INFO(ieee_dev) ((struct rt_dot11d_info *)((ieee_dev)->dot11d_info))
|
|
||||||
|
|
||||||
#define IS_DOT11D_ENABLE(ieee_dev) (GET_DOT11D_INFO(ieee_dev)->dot11d_enabled)
|
|
||||||
#define IS_COUNTRY_IE_VALID(ieee_dev) (GET_DOT11D_INFO(ieee_dev)->country_ie_len > 0)
|
|
||||||
|
|
||||||
#define IS_EQUAL_CIE_SRC(ieee_dev, addr) ether_addr_equal(GET_DOT11D_INFO(ieee_dev)->country_ie_src_addr, addr)
|
|
||||||
#define UPDATE_CIE_SRC(ieee_dev, addr) ether_addr_copy(GET_DOT11D_INFO(ieee_dev)->country_ie_src_addr, addr)
|
|
||||||
|
|
||||||
#define GET_CIE_WATCHDOG(ieee_dev) (GET_DOT11D_INFO(ieee_dev)->country_ie_watchdog)
|
|
||||||
#define RESET_CIE_WATCHDOG(ieee_dev) (GET_CIE_WATCHDOG(ieee_dev) = 0)
|
|
||||||
#define UPDATE_CIE_WATCHDOG(ieee_dev) (++GET_CIE_WATCHDOG(ieee_dev))
|
|
||||||
|
|
||||||
void rtl8192u_dot11d_init(struct ieee80211_device *dev);
|
|
||||||
void dot11d_reset(struct ieee80211_device *dev);
|
|
||||||
void dot11d_update_country_ie(struct ieee80211_device *dev,
|
|
||||||
u8 *addr,
|
|
||||||
u16 coutry_ie_len,
|
|
||||||
u8 *coutry_ie);
|
|
||||||
u8 dot11d_get_max_tx_pwr_in_dbm(struct ieee80211_device *dev, u8 channel);
|
|
||||||
void dot11d_scan_complete(struct ieee80211_device *dev);
|
|
||||||
int is_legal_channel(struct ieee80211_device *dev, u8 channel);
|
|
||||||
int to_legal_channel(struct ieee80211_device *dev, u8 channel);
|
|
||||||
|
|
||||||
#endif /* #ifndef __INC_DOT11D_H */
|
|
File diff suppressed because it is too large
Load Diff
@ -1,235 +0,0 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0
|
|
||||||
/*
|
|
||||||
* Host AP crypto routines
|
|
||||||
*
|
|
||||||
* Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
|
|
||||||
* Portions Copyright (C) 2004, Intel Corporation <jketreno@linux.intel.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/slab.h>
|
|
||||||
#include <linux/string.h>
|
|
||||||
#include <linux/errno.h>
|
|
||||||
|
|
||||||
#include "ieee80211.h"
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Jouni Malinen");
|
|
||||||
MODULE_DESCRIPTION("HostAP crypto");
|
|
||||||
MODULE_LICENSE("GPL");
|
|
||||||
|
|
||||||
struct ieee80211_crypto_alg {
|
|
||||||
struct list_head list;
|
|
||||||
struct ieee80211_crypto_ops *ops;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct ieee80211_crypto {
|
|
||||||
struct list_head algs;
|
|
||||||
spinlock_t lock;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct ieee80211_crypto *hcrypt;
|
|
||||||
|
|
||||||
void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee,
|
|
||||||
int force)
|
|
||||||
{
|
|
||||||
struct list_head *ptr, *n;
|
|
||||||
struct ieee80211_crypt_data *entry;
|
|
||||||
|
|
||||||
for (ptr = ieee->crypt_deinit_list.next, n = ptr->next;
|
|
||||||
ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) {
|
|
||||||
entry = list_entry(ptr, struct ieee80211_crypt_data, list);
|
|
||||||
|
|
||||||
if (atomic_read(&entry->refcnt) != 0 && !force)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
list_del(ptr);
|
|
||||||
|
|
||||||
if (entry->ops)
|
|
||||||
entry->ops->deinit(entry->priv);
|
|
||||||
kfree(entry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ieee80211_crypt_deinit_handler(struct timer_list *t)
|
|
||||||
{
|
|
||||||
struct ieee80211_device *ieee = from_timer(ieee, t, crypt_deinit_timer);
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&ieee->lock, flags);
|
|
||||||
ieee80211_crypt_deinit_entries(ieee, 0);
|
|
||||||
if (!list_empty(&ieee->crypt_deinit_list)) {
|
|
||||||
netdev_dbg(ieee->dev, "%s: entries remaining in delayed crypt deletion list\n",
|
|
||||||
ieee->dev->name);
|
|
||||||
ieee->crypt_deinit_timer.expires = jiffies + HZ;
|
|
||||||
add_timer(&ieee->crypt_deinit_timer);
|
|
||||||
}
|
|
||||||
spin_unlock_irqrestore(&ieee->lock, flags);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
|
|
||||||
struct ieee80211_crypt_data **crypt)
|
|
||||||
{
|
|
||||||
struct ieee80211_crypt_data *tmp;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
if (!(*crypt))
|
|
||||||
return;
|
|
||||||
|
|
||||||
tmp = *crypt;
|
|
||||||
*crypt = NULL;
|
|
||||||
|
|
||||||
/* must not run ops->deinit() while there may be pending encrypt or
|
|
||||||
* decrypt operations. Use a list of delayed deinits to avoid needing
|
|
||||||
* locking.
|
|
||||||
*/
|
|
||||||
|
|
||||||
spin_lock_irqsave(&ieee->lock, flags);
|
|
||||||
list_add(&tmp->list, &ieee->crypt_deinit_list);
|
|
||||||
if (!timer_pending(&ieee->crypt_deinit_timer)) {
|
|
||||||
ieee->crypt_deinit_timer.expires = jiffies + HZ;
|
|
||||||
add_timer(&ieee->crypt_deinit_timer);
|
|
||||||
}
|
|
||||||
spin_unlock_irqrestore(&ieee->lock, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
|
|
||||||
{
|
|
||||||
unsigned long flags;
|
|
||||||
struct ieee80211_crypto_alg *alg;
|
|
||||||
|
|
||||||
if (!hcrypt)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
alg = kzalloc(sizeof(*alg), GFP_KERNEL);
|
|
||||||
if (!alg)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
alg->ops = ops;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&hcrypt->lock, flags);
|
|
||||||
list_add(&alg->list, &hcrypt->algs);
|
|
||||||
spin_unlock_irqrestore(&hcrypt->lock, flags);
|
|
||||||
|
|
||||||
pr_debug("ieee80211_crypt: registered algorithm '%s'\n",
|
|
||||||
ops->name);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops)
|
|
||||||
{
|
|
||||||
unsigned long flags;
|
|
||||||
struct list_head *ptr;
|
|
||||||
struct ieee80211_crypto_alg *del_alg = NULL;
|
|
||||||
|
|
||||||
if (!hcrypt)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&hcrypt->lock, flags);
|
|
||||||
for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
|
|
||||||
struct ieee80211_crypto_alg *alg =
|
|
||||||
(struct ieee80211_crypto_alg *)ptr;
|
|
||||||
if (alg->ops == ops) {
|
|
||||||
list_del(&alg->list);
|
|
||||||
del_alg = alg;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
spin_unlock_irqrestore(&hcrypt->lock, flags);
|
|
||||||
|
|
||||||
if (del_alg) {
|
|
||||||
pr_debug("ieee80211_crypt: unregistered algorithm '%s'\n",
|
|
||||||
ops->name);
|
|
||||||
kfree(del_alg);
|
|
||||||
}
|
|
||||||
|
|
||||||
return del_alg ? 0 : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name)
|
|
||||||
{
|
|
||||||
unsigned long flags;
|
|
||||||
struct list_head *ptr;
|
|
||||||
struct ieee80211_crypto_alg *found_alg = NULL;
|
|
||||||
|
|
||||||
if (!hcrypt)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&hcrypt->lock, flags);
|
|
||||||
for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
|
|
||||||
struct ieee80211_crypto_alg *alg =
|
|
||||||
(struct ieee80211_crypto_alg *)ptr;
|
|
||||||
if (strcmp(alg->ops->name, name) == 0) {
|
|
||||||
found_alg = alg;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
spin_unlock_irqrestore(&hcrypt->lock, flags);
|
|
||||||
|
|
||||||
if (found_alg)
|
|
||||||
return found_alg->ops;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void *ieee80211_crypt_null_init(int keyidx) { return (void *)1; }
|
|
||||||
static void ieee80211_crypt_null_deinit(void *priv) {}
|
|
||||||
|
|
||||||
static struct ieee80211_crypto_ops ieee80211_crypt_null = {
|
|
||||||
.name = "NULL",
|
|
||||||
.init = ieee80211_crypt_null_init,
|
|
||||||
.deinit = ieee80211_crypt_null_deinit,
|
|
||||||
.encrypt_mpdu = NULL,
|
|
||||||
.decrypt_mpdu = NULL,
|
|
||||||
.encrypt_msdu = NULL,
|
|
||||||
.decrypt_msdu = NULL,
|
|
||||||
.set_key = NULL,
|
|
||||||
.get_key = NULL,
|
|
||||||
.extra_prefix_len = 0,
|
|
||||||
.extra_postfix_len = 0,
|
|
||||||
.owner = THIS_MODULE,
|
|
||||||
};
|
|
||||||
|
|
||||||
int __init ieee80211_crypto_init(void)
|
|
||||||
{
|
|
||||||
int ret = -ENOMEM;
|
|
||||||
|
|
||||||
hcrypt = kzalloc(sizeof(*hcrypt), GFP_KERNEL);
|
|
||||||
if (!hcrypt)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
INIT_LIST_HEAD(&hcrypt->algs);
|
|
||||||
spin_lock_init(&hcrypt->lock);
|
|
||||||
|
|
||||||
ret = ieee80211_register_crypto_ops(&ieee80211_crypt_null);
|
|
||||||
if (ret < 0) {
|
|
||||||
kfree(hcrypt);
|
|
||||||
hcrypt = NULL;
|
|
||||||
}
|
|
||||||
out:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ieee80211_crypto_deinit(void)
|
|
||||||
{
|
|
||||||
struct list_head *ptr, *n;
|
|
||||||
|
|
||||||
if (!hcrypt)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs;
|
|
||||||
ptr = n, n = ptr->next) {
|
|
||||||
struct ieee80211_crypto_alg *alg =
|
|
||||||
(struct ieee80211_crypto_alg *)ptr;
|
|
||||||
list_del(ptr);
|
|
||||||
pr_debug("ieee80211_crypt: unregistered algorithm '%s' (deinit)\n",
|
|
||||||
alg->ops->name);
|
|
||||||
kfree(alg);
|
|
||||||
}
|
|
||||||
|
|
||||||
kfree(hcrypt);
|
|
||||||
}
|
|
@ -1,86 +0,0 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
/*
|
|
||||||
* Original code based on Host AP (software wireless LAN access point) driver
|
|
||||||
* for Intersil Prism2/2.5/3.
|
|
||||||
*
|
|
||||||
* Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
|
|
||||||
* <jkmaline@cc.hut.fi>
|
|
||||||
* Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
|
|
||||||
*
|
|
||||||
* Adaption to a generic IEEE 802.11 stack by James Ketrenos
|
|
||||||
* <jketreno@linux.intel.com>
|
|
||||||
*
|
|
||||||
* Copyright (c) 2004, Intel Corporation
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file defines the interface to the ieee80211 crypto module.
|
|
||||||
*/
|
|
||||||
#ifndef IEEE80211_CRYPT_H
|
|
||||||
#define IEEE80211_CRYPT_H
|
|
||||||
|
|
||||||
#include <linux/skbuff.h>
|
|
||||||
|
|
||||||
struct ieee80211_crypto_ops {
|
|
||||||
const char *name;
|
|
||||||
|
|
||||||
/* init new crypto context (e.g., allocate private data space,
|
|
||||||
* select IV, etc.); returns NULL on failure or pointer to allocated
|
|
||||||
* private data on success
|
|
||||||
*/
|
|
||||||
void * (*init)(int keyidx);
|
|
||||||
|
|
||||||
/* deinitialize crypto context and free allocated private data */
|
|
||||||
void (*deinit)(void *priv);
|
|
||||||
|
|
||||||
/* encrypt/decrypt return < 0 on error or >= 0 on success. The return
|
|
||||||
* value from decrypt_mpdu is passed as the keyidx value for
|
|
||||||
* decrypt_msdu. skb must have enough head and tail room for the
|
|
||||||
* encryption; if not, error will be returned; these functions are
|
|
||||||
* called for all MPDUs (i.e., fragments).
|
|
||||||
*/
|
|
||||||
int (*encrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
|
|
||||||
int (*decrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
|
|
||||||
|
|
||||||
/* These functions are called for full MSDUs, i.e. full frames.
|
|
||||||
* These can be NULL if full MSDU operations are not needed.
|
|
||||||
*/
|
|
||||||
int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv);
|
|
||||||
int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len,
|
|
||||||
void *priv);
|
|
||||||
|
|
||||||
int (*set_key)(void *key, int len, u8 *seq, void *priv);
|
|
||||||
int (*get_key)(void *key, int len, u8 *seq, void *priv);
|
|
||||||
|
|
||||||
/* procfs handler for printing out key information and possible
|
|
||||||
* statistics
|
|
||||||
*/
|
|
||||||
char * (*print_stats)(char *p, void *priv);
|
|
||||||
|
|
||||||
/* maximum number of bytes added by encryption; encrypt buf is
|
|
||||||
* allocated with extra_prefix_len bytes, copy of in_buf, and
|
|
||||||
* extra_postfix_len; encrypt need not use all this space, but
|
|
||||||
* the result must start at the beginning of the buffer and correct
|
|
||||||
* length must be returned
|
|
||||||
*/
|
|
||||||
int extra_prefix_len, extra_postfix_len;
|
|
||||||
|
|
||||||
struct module *owner;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ieee80211_crypt_data {
|
|
||||||
struct list_head list; /* delayed deletion list */
|
|
||||||
struct ieee80211_crypto_ops *ops;
|
|
||||||
void *priv;
|
|
||||||
atomic_t refcnt;
|
|
||||||
};
|
|
||||||
|
|
||||||
int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops);
|
|
||||||
int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops);
|
|
||||||
struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name);
|
|
||||||
void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force);
|
|
||||||
void ieee80211_crypt_deinit_handler(struct timer_list *t);
|
|
||||||
void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
|
|
||||||
struct ieee80211_crypt_data **crypt);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,421 +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 "ieee80211.h"
|
|
||||||
|
|
||||||
#include <linux/crypto.h>
|
|
||||||
#include <crypto/aead.h>
|
|
||||||
#include <linux/scatterlist.h>
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Jouni Malinen");
|
|
||||||
MODULE_DESCRIPTION("Host AP crypt: CCMP");
|
|
||||||
MODULE_LICENSE("GPL");
|
|
||||||
|
|
||||||
#define AES_BLOCK_LEN 16
|
|
||||||
#define CCMP_HDR_LEN 8
|
|
||||||
#define CCMP_MIC_LEN 8
|
|
||||||
#define CCMP_TK_LEN 16
|
|
||||||
#define CCMP_PN_LEN 6
|
|
||||||
|
|
||||||
struct ieee80211_ccmp_data {
|
|
||||||
u8 key[CCMP_TK_LEN];
|
|
||||||
int key_set;
|
|
||||||
|
|
||||||
u8 tx_pn[CCMP_PN_LEN];
|
|
||||||
u8 rx_pn[CCMP_PN_LEN];
|
|
||||||
|
|
||||||
u32 dot11RSNAStatsCCMPFormatErrors;
|
|
||||||
u32 dot11RSNAStatsCCMPReplays;
|
|
||||||
u32 dot11RSNAStatsCCMPDecryptErrors;
|
|
||||||
|
|
||||||
int key_idx;
|
|
||||||
|
|
||||||
struct crypto_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 *ieee80211_ccmp_init(int key_idx)
|
|
||||||
{
|
|
||||||
struct ieee80211_ccmp_data *priv;
|
|
||||||
|
|
||||||
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
|
|
||||||
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("ieee80211_crypt_ccmp: could not allocate crypto API aes\n");
|
|
||||||
priv->tfm = NULL;
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
return priv;
|
|
||||||
|
|
||||||
fail:
|
|
||||||
if (priv) {
|
|
||||||
if (priv->tfm)
|
|
||||||
crypto_free_aead(priv->tfm);
|
|
||||||
kfree(priv);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ieee80211_ccmp_deinit(void *priv)
|
|
||||||
{
|
|
||||||
struct ieee80211_ccmp_data *_priv = priv;
|
|
||||||
|
|
||||||
if (_priv && _priv->tfm)
|
|
||||||
crypto_free_aead(_priv->tfm);
|
|
||||||
kfree(priv);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ccmp_init_iv_and_aad(struct rtl_80211_hdr_4addr *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_ctl);
|
|
||||||
a4_included = ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
|
|
||||||
(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS));
|
|
||||||
/* qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
|
|
||||||
* (WLAN_FC_GET_STYPE(fc) & 0x08));
|
|
||||||
*/
|
|
||||||
/* fixed by David :2006.9.6 */
|
|
||||||
qc_included = (WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
|
|
||||||
(WLAN_FC_GET_STYPE(fc) & 0x80);
|
|
||||||
aad_len = 22;
|
|
||||||
if (a4_included)
|
|
||||||
aad_len += 6;
|
|
||||||
if (qc_included) {
|
|
||||||
pos = (u8 *)&hdr->addr4;
|
|
||||||
if (a4_included)
|
|
||||||
pos += 6;
|
|
||||||
qc = *pos & 0x0f;
|
|
||||||
aad_len += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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_ctl;
|
|
||||||
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 ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
|
||||||
{
|
|
||||||
struct ieee80211_ccmp_data *key = priv;
|
|
||||||
int i;
|
|
||||||
u8 *pos;
|
|
||||||
struct rtl_80211_hdr_4addr *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;
|
|
||||||
/* mic = skb_put(skb, CCMP_MIC_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) | BIT(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 rtl_80211_hdr_4addr *)skb->data;
|
|
||||||
if (!tcb_desc->bHwSec) {
|
|
||||||
struct aead_request *req;
|
|
||||||
struct scatterlist sg[2];
|
|
||||||
u8 *aad = key->tx_aad;
|
|
||||||
u8 iv[AES_BLOCK_LEN];
|
|
||||||
int aad_len, ret;
|
|
||||||
size_t 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 ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
|
||||||
{
|
|
||||||
struct ieee80211_ccmp_data *key = priv;
|
|
||||||
u8 keyidx, *pos;
|
|
||||||
struct rtl_80211_hdr_4addr *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->dot11RSNAStatsCCMPFormatErrors++;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
hdr = (struct rtl_80211_hdr_4addr *)skb->data;
|
|
||||||
pos = skb->data + hdr_len;
|
|
||||||
keyidx = pos[3];
|
|
||||||
if (!(keyidx & BIT(5))) {
|
|
||||||
if (net_ratelimit()) {
|
|
||||||
netdev_dbg(skb->dev, "CCMP: received packet without ExtIV flag from %pM\n",
|
|
||||||
hdr->addr2);
|
|
||||||
}
|
|
||||||
key->dot11RSNAStatsCCMPFormatErrors++;
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
keyidx >>= 6;
|
|
||||||
if (key->key_idx != keyidx) {
|
|
||||||
netdev_dbg(skb->dev, "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()) {
|
|
||||||
netdev_dbg(skb->dev, "CCMP: received packet from %pM with keyid=%d that does not have a configured key\n",
|
|
||||||
hdr->addr2, keyidx);
|
|
||||||
}
|
|
||||||
return -3;
|
|
||||||
}
|
|
||||||
|
|
||||||
pn[0] = pos[7];
|
|
||||||
pn[1] = pos[6];
|
|
||||||
pn[2] = pos[5];
|
|
||||||
pn[3] = pos[4];
|
|
||||||
pn[4] = pos[1];
|
|
||||||
pn[5] = pos[0];
|
|
||||||
pos += 8;
|
|
||||||
|
|
||||||
if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) {
|
|
||||||
if (net_ratelimit()) {
|
|
||||||
netdev_dbg(skb->dev, "CCMP: replay detected: STA=%pM previous PN %pm received PN %pm\n",
|
|
||||||
hdr->addr2, key->rx_pn, pn);
|
|
||||||
}
|
|
||||||
key->dot11RSNAStatsCCMPReplays++;
|
|
||||||
return -4;
|
|
||||||
}
|
|
||||||
if (!tcb_desc->bHwSec) {
|
|
||||||
struct aead_request *req;
|
|
||||||
struct scatterlist sg[2];
|
|
||||||
u8 *aad = key->rx_aad;
|
|
||||||
u8 iv[AES_BLOCK_LEN];
|
|
||||||
int aad_len, ret;
|
|
||||||
size_t 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, 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()) {
|
|
||||||
netdev_dbg(skb->dev, "CCMP: decrypt failed: STA=%pM\n",
|
|
||||||
hdr->addr2);
|
|
||||||
}
|
|
||||||
key->dot11RSNAStatsCCMPDecryptErrors++;
|
|
||||||
return -5;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(key->rx_pn, pn, CCMP_PN_LEN);
|
|
||||||
}
|
|
||||||
/* Remove hdr and MIC */
|
|
||||||
memmove(skb->data + CCMP_HDR_LEN, skb->data, hdr_len);
|
|
||||||
skb_pull(skb, CCMP_HDR_LEN);
|
|
||||||
skb_trim(skb, skb->len - CCMP_MIC_LEN);
|
|
||||||
|
|
||||||
return keyidx;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ieee80211_ccmp_set_key(void *key, int len, u8 *seq, void *priv)
|
|
||||||
{
|
|
||||||
struct ieee80211_ccmp_data *data = priv;
|
|
||||||
int keyidx;
|
|
||||||
struct crypto_aead *tfm = data->tfm;
|
|
||||||
|
|
||||||
keyidx = data->key_idx;
|
|
||||||
memset(data, 0, sizeof(*data));
|
|
||||||
data->key_idx = keyidx;
|
|
||||||
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(tfm, CCMP_MIC_LEN) ||
|
|
||||||
crypto_aead_setkey(tfm, data->key, CCMP_TK_LEN))
|
|
||||||
return -1;
|
|
||||||
} else if (len == 0) {
|
|
||||||
data->key_set = 0;
|
|
||||||
} else {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ieee80211_ccmp_get_key(void *key, int len, u8 *seq, void *priv)
|
|
||||||
{
|
|
||||||
struct ieee80211_ccmp_data *data = priv;
|
|
||||||
|
|
||||||
if (len < CCMP_TK_LEN)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (!data->key_set)
|
|
||||||
return 0;
|
|
||||||
memcpy(key, data->key, CCMP_TK_LEN);
|
|
||||||
|
|
||||||
if (seq) {
|
|
||||||
seq[0] = data->tx_pn[5];
|
|
||||||
seq[1] = data->tx_pn[4];
|
|
||||||
seq[2] = data->tx_pn[3];
|
|
||||||
seq[3] = data->tx_pn[2];
|
|
||||||
seq[4] = data->tx_pn[1];
|
|
||||||
seq[5] = data->tx_pn[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
return CCMP_TK_LEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *ieee80211_ccmp_print_stats(char *p, void *priv)
|
|
||||||
{
|
|
||||||
struct ieee80211_ccmp_data *ccmp = priv;
|
|
||||||
|
|
||||||
p += sprintf(p, "key[%d] alg=CCMP key_set=%d tx_pn=%pm rx_pn=%pm format_errors=%d replays=%d decrypt_errors=%d\n",
|
|
||||||
ccmp->key_idx, ccmp->key_set,
|
|
||||||
ccmp->tx_pn, ccmp->rx_pn,
|
|
||||||
ccmp->dot11RSNAStatsCCMPFormatErrors,
|
|
||||||
ccmp->dot11RSNAStatsCCMPReplays,
|
|
||||||
ccmp->dot11RSNAStatsCCMPDecryptErrors);
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = {
|
|
||||||
.name = "CCMP",
|
|
||||||
.init = ieee80211_ccmp_init,
|
|
||||||
.deinit = ieee80211_ccmp_deinit,
|
|
||||||
.encrypt_mpdu = ieee80211_ccmp_encrypt,
|
|
||||||
.decrypt_mpdu = ieee80211_ccmp_decrypt,
|
|
||||||
.encrypt_msdu = NULL,
|
|
||||||
.decrypt_msdu = NULL,
|
|
||||||
.set_key = ieee80211_ccmp_set_key,
|
|
||||||
.get_key = ieee80211_ccmp_get_key,
|
|
||||||
.print_stats = ieee80211_ccmp_print_stats,
|
|
||||||
.extra_prefix_len = CCMP_HDR_LEN,
|
|
||||||
.extra_postfix_len = CCMP_MIC_LEN,
|
|
||||||
.owner = THIS_MODULE,
|
|
||||||
};
|
|
||||||
|
|
||||||
int __init ieee80211_crypto_ccmp_init(void)
|
|
||||||
{
|
|
||||||
return ieee80211_register_crypto_ops(&ieee80211_crypt_ccmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ieee80211_crypto_ccmp_exit(void)
|
|
||||||
{
|
|
||||||
ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp);
|
|
||||||
}
|
|
@ -1,718 +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 <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 "ieee80211.h"
|
|
||||||
|
|
||||||
#include <crypto/arc4.h>
|
|
||||||
#include <crypto/hash.h>
|
|
||||||
#include <linux/crc32.h>
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Jouni Malinen");
|
|
||||||
MODULE_DESCRIPTION("Host AP crypt: TKIP");
|
|
||||||
MODULE_LICENSE("GPL");
|
|
||||||
|
|
||||||
struct ieee80211_tkip_data {
|
|
||||||
#define TKIP_KEY_LEN 32
|
|
||||||
u8 key[TKIP_KEY_LEN];
|
|
||||||
int key_set;
|
|
||||||
|
|
||||||
u32 tx_iv32;
|
|
||||||
u16 tx_iv16;
|
|
||||||
u16 tx_ttak[5];
|
|
||||||
int tx_phase1_done;
|
|
||||||
|
|
||||||
u32 rx_iv32;
|
|
||||||
u16 rx_iv16;
|
|
||||||
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], tx_hdr[16];
|
|
||||||
};
|
|
||||||
|
|
||||||
static void *ieee80211_tkip_init(int key_idx)
|
|
||||||
{
|
|
||||||
struct ieee80211_tkip_data *priv;
|
|
||||||
|
|
||||||
if (fips_enabled)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
|
|
||||||
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)) {
|
|
||||||
printk(KERN_DEBUG "ieee80211_crypt_tkip: 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)) {
|
|
||||||
printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
|
|
||||||
"crypto API michael_mic\n");
|
|
||||||
priv->rx_tfm_michael = NULL;
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
return priv;
|
|
||||||
|
|
||||||
fail:
|
|
||||||
if (priv) {
|
|
||||||
crypto_free_shash(priv->tx_tfm_michael);
|
|
||||||
crypto_free_shash(priv->rx_tfm_michael);
|
|
||||||
kfree(priv);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void ieee80211_tkip_deinit(void *priv)
|
|
||||||
{
|
|
||||||
struct ieee80211_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 | (((u16)hi) << 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
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] ^ le16_to_cpu(*(__le16 *)(&TK[0])));
|
|
||||||
PPK[1] += _S_(PPK[0] ^ le16_to_cpu(*(__le16 *)(&TK[2])));
|
|
||||||
PPK[2] += _S_(PPK[1] ^ le16_to_cpu(*(__le16 *)(&TK[4])));
|
|
||||||
PPK[3] += _S_(PPK[2] ^ le16_to_cpu(*(__le16 *)(&TK[6])));
|
|
||||||
PPK[4] += _S_(PPK[3] ^ le16_to_cpu(*(__le16 *)(&TK[8])));
|
|
||||||
PPK[5] += _S_(PPK[4] ^ le16_to_cpu(*(__le16 *)(&TK[10])));
|
|
||||||
|
|
||||||
PPK[0] += RotR1(PPK[5] ^ le16_to_cpu(*(__le16 *)(&TK[12])));
|
|
||||||
PPK[1] += RotR1(PPK[0] ^ le16_to_cpu(*(__le16 *)(&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] ^ le16_to_cpu(*(__le16 *)(&TK[0]))) >> 1);
|
|
||||||
|
|
||||||
#ifdef __BIG_ENDIAN
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < 6; i++)
|
|
||||||
PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
|
||||||
{
|
|
||||||
struct ieee80211_tkip_data *tkey = priv;
|
|
||||||
int len;
|
|
||||||
u8 *pos;
|
|
||||||
struct rtl_80211_hdr_4addr *hdr;
|
|
||||||
struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
|
|
||||||
u8 rc4key[16], *icv;
|
|
||||||
u32 crc;
|
|
||||||
|
|
||||||
if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 ||
|
|
||||||
skb->len < hdr_len)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
hdr = (struct rtl_80211_hdr_4addr *)skb->data;
|
|
||||||
|
|
||||||
if (!tcb_desc->bHwSec) {
|
|
||||||
if (!tkey->tx_phase1_done) {
|
|
||||||
tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
|
|
||||||
tkey->tx_iv32);
|
|
||||||
tkey->tx_phase1_done = 1;
|
|
||||||
}
|
|
||||||
tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);
|
|
||||||
} else
|
|
||||||
tkey->tx_phase1_done = 1;
|
|
||||||
|
|
||||||
|
|
||||||
len = skb->len - hdr_len;
|
|
||||||
pos = skb_push(skb, 8);
|
|
||||||
memmove(pos, pos + 8, hdr_len);
|
|
||||||
pos += hdr_len;
|
|
||||||
|
|
||||||
if (tcb_desc->bHwSec) {
|
|
||||||
*pos++ = Hi8(tkey->tx_iv16);
|
|
||||||
*pos++ = (Hi8(tkey->tx_iv16) | 0x20) & 0x7F;
|
|
||||||
*pos++ = Lo8(tkey->tx_iv16);
|
|
||||||
} else {
|
|
||||||
*pos++ = rc4key[0];
|
|
||||||
*pos++ = rc4key[1];
|
|
||||||
*pos++ = rc4key[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
*pos++ = (tkey->key_idx << 6) | BIT(5) /* Ext IV included */;
|
|
||||||
*pos++ = tkey->tx_iv32 & 0xff;
|
|
||||||
*pos++ = (tkey->tx_iv32 >> 8) & 0xff;
|
|
||||||
*pos++ = (tkey->tx_iv32 >> 16) & 0xff;
|
|
||||||
*pos++ = (tkey->tx_iv32 >> 24) & 0xff;
|
|
||||||
|
|
||||||
if (!tcb_desc->bHwSec) {
|
|
||||||
icv = skb_put(skb, 4);
|
|
||||||
crc = ~crc32_le(~0, pos, len);
|
|
||||||
icv[0] = crc;
|
|
||||||
icv[1] = crc >> 8;
|
|
||||||
icv[2] = crc >> 16;
|
|
||||||
icv[3] = crc >> 24;
|
|
||||||
|
|
||||||
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++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
|
||||||
{
|
|
||||||
struct ieee80211_tkip_data *tkey = priv;
|
|
||||||
u8 keyidx, *pos;
|
|
||||||
u32 iv32;
|
|
||||||
u16 iv16;
|
|
||||||
struct rtl_80211_hdr_4addr *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 rtl_80211_hdr_4addr *)skb->data;
|
|
||||||
pos = skb->data + hdr_len;
|
|
||||||
keyidx = pos[3];
|
|
||||||
if (!(keyidx & BIT(5))) {
|
|
||||||
if (net_ratelimit()) {
|
|
||||||
netdev_dbg(skb->dev, "TKIP: received packet without ExtIV"
|
|
||||||
" flag from %pM\n", hdr->addr2);
|
|
||||||
}
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
keyidx >>= 6;
|
|
||||||
if (tkey->key_idx != keyidx) {
|
|
||||||
netdev_dbg(skb->dev, "TKIP: RX tkey->key_idx=%d frame "
|
|
||||||
"keyidx=%d priv=%p\n", tkey->key_idx, keyidx, priv);
|
|
||||||
return -6;
|
|
||||||
}
|
|
||||||
if (!tkey->key_set) {
|
|
||||||
if (net_ratelimit()) {
|
|
||||||
netdev_dbg(skb->dev, "TKIP: received packet from %pM"
|
|
||||||
" with keyid=%d that does not have a configured"
|
|
||||||
" key\n", hdr->addr2, keyidx);
|
|
||||||
}
|
|
||||||
return -3;
|
|
||||||
}
|
|
||||||
iv16 = (pos[0] << 8) | pos[2];
|
|
||||||
iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24);
|
|
||||||
pos += 8;
|
|
||||||
|
|
||||||
if (!tcb_desc->bHwSec) {
|
|
||||||
if (iv32 < tkey->rx_iv32 ||
|
|
||||||
(iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
|
|
||||||
if (net_ratelimit()) {
|
|
||||||
netdev_dbg(skb->dev, "TKIP: replay detected: STA=%pM"
|
|
||||||
" previous TSC %08x%04x received TSC "
|
|
||||||
"%08x%04x\n", hdr->addr2,
|
|
||||||
tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
|
|
||||||
}
|
|
||||||
tkey->dot11RSNAStatsTKIPReplays++;
|
|
||||||
return -4;
|
|
||||||
}
|
|
||||||
|
|
||||||
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, "TKIP: ICV error detected: STA="
|
|
||||||
"%pM\n", hdr->addr2);
|
|
||||||
}
|
|
||||||
tkey->dot11RSNAStatsTKIPICVErrors++;
|
|
||||||
return -5;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Update real counters only after Michael MIC verification has
|
|
||||||
* completed.
|
|
||||||
*/
|
|
||||||
tkey->rx_iv32_new = iv32;
|
|
||||||
tkey->rx_iv16_new = iv16;
|
|
||||||
|
|
||||||
/* Remove IV and ICV */
|
|
||||||
memmove(skb->data + 8, skb->data, hdr_len);
|
|
||||||
skb_pull(skb, 8);
|
|
||||||
skb_trim(skb, skb->len - 4);
|
|
||||||
|
|
||||||
return keyidx;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int michael_mic(struct crypto_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 rtl_80211_hdr_4addr *hdr11;
|
|
||||||
|
|
||||||
hdr11 = (struct rtl_80211_hdr_4addr *)skb->data;
|
|
||||||
switch (le16_to_cpu(hdr11->frame_ctl) &
|
|
||||||
(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
|
|
||||||
case IEEE80211_FCTL_TODS:
|
|
||||||
memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
|
|
||||||
memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
|
|
||||||
break;
|
|
||||||
case IEEE80211_FCTL_FROMDS:
|
|
||||||
memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
|
|
||||||
memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */
|
|
||||||
break;
|
|
||||||
case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
|
|
||||||
memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
|
|
||||||
memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
|
|
||||||
memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
hdr[12] = 0; /* priority */
|
|
||||||
|
|
||||||
hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv)
|
|
||||||
{
|
|
||||||
struct ieee80211_tkip_data *tkey = priv;
|
|
||||||
u8 *pos;
|
|
||||||
struct rtl_80211_hdr_4addr *hdr;
|
|
||||||
|
|
||||||
hdr = (struct rtl_80211_hdr_4addr *)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);
|
|
||||||
|
|
||||||
// { david, 2006.9.1
|
|
||||||
// fix the wpa process with wmm enabled.
|
|
||||||
if (IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl)))
|
|
||||||
tkey->tx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
|
|
||||||
// }
|
|
||||||
pos = skb_put(skb, 8);
|
|
||||||
|
|
||||||
if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
|
|
||||||
skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ieee80211_michael_mic_failure(struct net_device *dev,
|
|
||||||
struct rtl_80211_hdr_4addr *hdr,
|
|
||||||
int keyidx)
|
|
||||||
{
|
|
||||||
union iwreq_data wrqu;
|
|
||||||
struct iw_michaelmicfailure ev;
|
|
||||||
|
|
||||||
/* TODO: needed parameters: count, keyid, key type, TSC */
|
|
||||||
memset(&ev, 0, sizeof(ev));
|
|
||||||
ev.flags = keyidx & IW_MICFAILURE_KEY_ID;
|
|
||||||
if (hdr->addr1[0] & 0x01)
|
|
||||||
ev.flags |= IW_MICFAILURE_GROUP;
|
|
||||||
else
|
|
||||||
ev.flags |= IW_MICFAILURE_PAIRWISE;
|
|
||||||
ev.src_addr.sa_family = ARPHRD_ETHER;
|
|
||||||
memcpy(ev.src_addr.sa_data, hdr->addr2, ETH_ALEN);
|
|
||||||
memset(&wrqu, 0, sizeof(wrqu));
|
|
||||||
wrqu.data.length = sizeof(ev);
|
|
||||||
wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
|
|
||||||
int hdr_len, void *priv)
|
|
||||||
{
|
|
||||||
struct ieee80211_tkip_data *tkey = priv;
|
|
||||||
u8 mic[8];
|
|
||||||
struct rtl_80211_hdr_4addr *hdr;
|
|
||||||
|
|
||||||
hdr = (struct rtl_80211_hdr_4addr *)skb->data;
|
|
||||||
|
|
||||||
if (!tkey->key_set)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
michael_mic_hdr(skb, tkey->rx_hdr);
|
|
||||||
// { david, 2006.9.1
|
|
||||||
// fix the wpa process with wmm enabled.
|
|
||||||
if (IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl)))
|
|
||||||
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 rtl_80211_hdr_4addr *hdr;
|
|
||||||
hdr = (struct rtl_80211_hdr_4addr *)skb->data;
|
|
||||||
|
|
||||||
netdev_dbg(skb->dev, "Michael MIC verification failed for "
|
|
||||||
"MSDU from %pM keyidx=%d\n",
|
|
||||||
hdr->addr2, keyidx);
|
|
||||||
if (skb->dev)
|
|
||||||
ieee80211_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 ieee80211_tkip_set_key(void *key, int len, u8 *seq, void *priv)
|
|
||||||
{
|
|
||||||
struct ieee80211_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 ieee80211_tkip_get_key(void *key, int len, u8 *seq, void *priv)
|
|
||||||
{
|
|
||||||
struct ieee80211_tkip_data *tkey = priv;
|
|
||||||
|
|
||||||
if (len < TKIP_KEY_LEN)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (!tkey->key_set)
|
|
||||||
return 0;
|
|
||||||
memcpy(key, tkey->key, TKIP_KEY_LEN);
|
|
||||||
|
|
||||||
if (seq) {
|
|
||||||
/* Return the sequence number of the last transmitted frame. */
|
|
||||||
u16 iv16 = tkey->tx_iv16;
|
|
||||||
u32 iv32 = tkey->tx_iv32;
|
|
||||||
|
|
||||||
if (iv16 == 0)
|
|
||||||
iv32--;
|
|
||||||
iv16--;
|
|
||||||
seq[0] = tkey->tx_iv16;
|
|
||||||
seq[1] = tkey->tx_iv16 >> 8;
|
|
||||||
seq[2] = tkey->tx_iv32;
|
|
||||||
seq[3] = tkey->tx_iv32 >> 8;
|
|
||||||
seq[4] = tkey->tx_iv32 >> 16;
|
|
||||||
seq[5] = tkey->tx_iv32 >> 24;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TKIP_KEY_LEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static char *ieee80211_tkip_print_stats(char *p, void *priv)
|
|
||||||
{
|
|
||||||
struct ieee80211_tkip_data *tkip = priv;
|
|
||||||
|
|
||||||
p += sprintf(p, "key[%d] alg=TKIP key_set=%d "
|
|
||||||
"tx_pn=%02x%02x%02x%02x%02x%02x "
|
|
||||||
"rx_pn=%02x%02x%02x%02x%02x%02x "
|
|
||||||
"replays=%d icv_errors=%d local_mic_failures=%d\n",
|
|
||||||
tkip->key_idx, tkip->key_set,
|
|
||||||
(tkip->tx_iv32 >> 24) & 0xff,
|
|
||||||
(tkip->tx_iv32 >> 16) & 0xff,
|
|
||||||
(tkip->tx_iv32 >> 8) & 0xff,
|
|
||||||
tkip->tx_iv32 & 0xff,
|
|
||||||
(tkip->tx_iv16 >> 8) & 0xff,
|
|
||||||
tkip->tx_iv16 & 0xff,
|
|
||||||
(tkip->rx_iv32 >> 24) & 0xff,
|
|
||||||
(tkip->rx_iv32 >> 16) & 0xff,
|
|
||||||
(tkip->rx_iv32 >> 8) & 0xff,
|
|
||||||
tkip->rx_iv32 & 0xff,
|
|
||||||
(tkip->rx_iv16 >> 8) & 0xff,
|
|
||||||
tkip->rx_iv16 & 0xff,
|
|
||||||
tkip->dot11RSNAStatsTKIPReplays,
|
|
||||||
tkip->dot11RSNAStatsTKIPICVErrors,
|
|
||||||
tkip->dot11RSNAStatsTKIPLocalMICFailures);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static struct ieee80211_crypto_ops ieee80211_crypt_tkip = {
|
|
||||||
.name = "TKIP",
|
|
||||||
.init = ieee80211_tkip_init,
|
|
||||||
.deinit = ieee80211_tkip_deinit,
|
|
||||||
.encrypt_mpdu = ieee80211_tkip_encrypt,
|
|
||||||
.decrypt_mpdu = ieee80211_tkip_decrypt,
|
|
||||||
.encrypt_msdu = ieee80211_michael_mic_add,
|
|
||||||
.decrypt_msdu = ieee80211_michael_mic_verify,
|
|
||||||
.set_key = ieee80211_tkip_set_key,
|
|
||||||
.get_key = ieee80211_tkip_get_key,
|
|
||||||
.print_stats = ieee80211_tkip_print_stats,
|
|
||||||
.extra_prefix_len = 4 + 4, /* IV + ExtIV */
|
|
||||||
.extra_postfix_len = 8 + 4, /* MIC + ICV */
|
|
||||||
.owner = THIS_MODULE,
|
|
||||||
};
|
|
||||||
|
|
||||||
int __init ieee80211_crypto_tkip_init(void)
|
|
||||||
{
|
|
||||||
return ieee80211_register_crypto_ops(&ieee80211_crypt_tkip);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ieee80211_crypto_tkip_exit(void)
|
|
||||||
{
|
|
||||||
ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip);
|
|
||||||
}
|
|
@ -1,247 +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 <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 "ieee80211.h"
|
|
||||||
|
|
||||||
#include <crypto/arc4.h>
|
|
||||||
#include <linux/crc32.h>
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Jouni Malinen");
|
|
||||||
MODULE_DESCRIPTION("Host AP crypt: WEP");
|
|
||||||
MODULE_LICENSE("GPL");
|
|
||||||
|
|
||||||
struct prism2_wep_data {
|
|
||||||
u32 iv;
|
|
||||||
#define WEP_KEY_LEN 13
|
|
||||||
u8 key[WEP_KEY_LEN + 1];
|
|
||||||
u8 key_len;
|
|
||||||
u8 key_idx;
|
|
||||||
struct 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_KERNEL);
|
|
||||||
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)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
len = skb->len - hdr_len;
|
|
||||||
pos = skb_push(skb, 4);
|
|
||||||
memmove(pos, pos + 4, hdr_len);
|
|
||||||
pos += hdr_len;
|
|
||||||
|
|
||||||
klen = 3 + wep->key_len;
|
|
||||||
|
|
||||||
wep->iv++;
|
|
||||||
|
|
||||||
/* Fluhrer, Mantin, and Shamir have reported weaknesses in the key
|
|
||||||
* scheduling algorithm of RC4. At least IVs (KeyByte + 3, 0xff, N)
|
|
||||||
* can be used to speedup attacks, so avoid using them.
|
|
||||||
*/
|
|
||||||
if ((wep->iv & 0xff00) == 0xff00) {
|
|
||||||
u8 B = (wep->iv >> 16) & 0xff;
|
|
||||||
|
|
||||||
if (B >= 3 && B < klen)
|
|
||||||
wep->iv += 0x0100;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Prepend 24-bit IV to RC4 key and TX frame */
|
|
||||||
*pos++ = key[0] = (wep->iv >> 16) & 0xff;
|
|
||||||
*pos++ = key[1] = (wep->iv >> 8) & 0xff;
|
|
||||||
*pos++ = key[2] = wep->iv & 0xff;
|
|
||||||
*pos++ = wep->key_idx << 6;
|
|
||||||
|
|
||||||
/* Copy rest of the WEP key (the secret part) */
|
|
||||||
memcpy(key + 3, wep->key, wep->key_len);
|
|
||||||
|
|
||||||
if (!tcb_desc->bHwSec) {
|
|
||||||
/* Append little-endian CRC32 and encrypt it to produce ICV */
|
|
||||||
crc = ~crc32_le(~0, pos, len);
|
|
||||||
icv = skb_put(skb, 4);
|
|
||||||
icv[0] = crc;
|
|
||||||
icv[1] = crc >> 8;
|
|
||||||
icv[2] = crc >> 16;
|
|
||||||
icv[3] = crc >> 24;
|
|
||||||
|
|
||||||
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 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->bHwSec) {
|
|
||||||
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 0;
|
|
||||||
|
|
||||||
memcpy(key, wep->key, wep->key_len);
|
|
||||||
|
|
||||||
return wep->key_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static char *prism2_wep_print_stats(char *p, void *priv)
|
|
||||||
{
|
|
||||||
struct prism2_wep_data *wep = priv;
|
|
||||||
|
|
||||||
p += sprintf(p, "key[%d] alg=WEP len=%d\n",
|
|
||||||
wep->key_idx, wep->key_len);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static struct ieee80211_crypto_ops ieee80211_crypt_wep = {
|
|
||||||
.name = "WEP",
|
|
||||||
.init = prism2_wep_init,
|
|
||||||
.deinit = prism2_wep_deinit,
|
|
||||||
.encrypt_mpdu = prism2_wep_encrypt,
|
|
||||||
.decrypt_mpdu = prism2_wep_decrypt,
|
|
||||||
.encrypt_msdu = NULL,
|
|
||||||
.decrypt_msdu = NULL,
|
|
||||||
.set_key = prism2_wep_set_key,
|
|
||||||
.get_key = prism2_wep_get_key,
|
|
||||||
.print_stats = prism2_wep_print_stats,
|
|
||||||
.extra_prefix_len = 4, /* IV */
|
|
||||||
.extra_postfix_len = 4, /* ICV */
|
|
||||||
.owner = THIS_MODULE,
|
|
||||||
};
|
|
||||||
|
|
||||||
int __init ieee80211_crypto_wep_init(void)
|
|
||||||
{
|
|
||||||
return ieee80211_register_crypto_ops(&ieee80211_crypt_wep);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ieee80211_crypto_wep_exit(void)
|
|
||||||
{
|
|
||||||
ieee80211_unregister_crypto_ops(&ieee80211_crypt_wep);
|
|
||||||
}
|
|
||||||
|
|
@ -1,287 +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 "ieee80211.h"
|
|
||||||
|
|
||||||
MODULE_DESCRIPTION("802.11 data/management/control stack");
|
|
||||||
MODULE_AUTHOR("Copyright (C) 2004 Intel Corporation <jketreno@linux.intel.com>");
|
|
||||||
MODULE_LICENSE("GPL");
|
|
||||||
|
|
||||||
#define DRV_NAME "ieee80211"
|
|
||||||
|
|
||||||
static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee)
|
|
||||||
{
|
|
||||||
if (ieee->networks)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
ieee->networks = kcalloc(MAX_NETWORK_COUNT,
|
|
||||||
sizeof(struct ieee80211_network),
|
|
||||||
GFP_KERNEL);
|
|
||||||
if (!ieee->networks) {
|
|
||||||
netdev_warn(ieee->dev, "Out of memory allocating beacons\n");
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void ieee80211_networks_free(struct ieee80211_device *ieee)
|
|
||||||
{
|
|
||||||
if (!ieee->networks)
|
|
||||||
return;
|
|
||||||
kfree(ieee->networks);
|
|
||||||
ieee->networks = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void ieee80211_networks_initialize(struct ieee80211_device *ieee)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
INIT_LIST_HEAD(&ieee->network_free_list);
|
|
||||||
INIT_LIST_HEAD(&ieee->network_list);
|
|
||||||
for (i = 0; i < MAX_NETWORK_COUNT; i++)
|
|
||||||
list_add_tail(&ieee->networks[i].list, &ieee->network_free_list);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct net_device *alloc_ieee80211(int sizeof_priv)
|
|
||||||
{
|
|
||||||
struct ieee80211_device *ieee;
|
|
||||||
struct net_device *dev;
|
|
||||||
int i, err;
|
|
||||||
|
|
||||||
IEEE80211_DEBUG_INFO("Initializing...\n");
|
|
||||||
|
|
||||||
dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv);
|
|
||||||
if (!dev) {
|
|
||||||
IEEE80211_ERROR("Unable to network device.\n");
|
|
||||||
goto failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
ieee = netdev_priv(dev);
|
|
||||||
ieee->dev = dev;
|
|
||||||
|
|
||||||
err = ieee80211_networks_allocate(ieee);
|
|
||||||
if (err) {
|
|
||||||
IEEE80211_ERROR("Unable to allocate beacon storage: %d\n",
|
|
||||||
err);
|
|
||||||
goto failed;
|
|
||||||
}
|
|
||||||
ieee80211_networks_initialize(ieee);
|
|
||||||
|
|
||||||
/* Default fragmentation threshold is maximum payload size */
|
|
||||||
ieee->fts = DEFAULT_FTS;
|
|
||||||
ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
|
|
||||||
ieee->open_wep = 1;
|
|
||||||
|
|
||||||
/* Default to enabling full open WEP with host based encrypt/decrypt */
|
|
||||||
ieee->host_encrypt = 1;
|
|
||||||
ieee->host_decrypt = 1;
|
|
||||||
ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
|
|
||||||
|
|
||||||
INIT_LIST_HEAD(&ieee->crypt_deinit_list);
|
|
||||||
timer_setup(&ieee->crypt_deinit_timer, ieee80211_crypt_deinit_handler,
|
|
||||||
0);
|
|
||||||
|
|
||||||
spin_lock_init(&ieee->lock);
|
|
||||||
spin_lock_init(&ieee->wpax_suitlist_lock);
|
|
||||||
spin_lock_init(&ieee->bw_spinlock);
|
|
||||||
spin_lock_init(&ieee->reorder_spinlock);
|
|
||||||
/* added by WB */
|
|
||||||
atomic_set(&ieee->atm_chnlop, 0);
|
|
||||||
atomic_set(&ieee->atm_swbw, 0);
|
|
||||||
|
|
||||||
ieee->wpax_type_set = 0;
|
|
||||||
ieee->wpa_enabled = 0;
|
|
||||||
ieee->tkip_countermeasures = 0;
|
|
||||||
ieee->drop_unencrypted = 0;
|
|
||||||
ieee->privacy_invoked = 0;
|
|
||||||
ieee->ieee802_1x = 1;
|
|
||||||
ieee->raw_tx = 0;
|
|
||||||
//ieee->hwsec_support = 1; //defalt support hw security. //use module_param instead.
|
|
||||||
ieee->hwsec_active = 0; /* disable hwsec, switch it on when necessary. */
|
|
||||||
|
|
||||||
ieee80211_softmac_init(ieee);
|
|
||||||
|
|
||||||
ieee->pHTInfo = kzalloc(sizeof(RT_HIGH_THROUGHPUT), GFP_KERNEL);
|
|
||||||
if (!ieee->pHTInfo) {
|
|
||||||
IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for HTInfo\n");
|
|
||||||
|
|
||||||
/* By this point in code ieee80211_networks_allocate() has been
|
|
||||||
* successfully called so the memory allocated should be freed
|
|
||||||
*/
|
|
||||||
ieee80211_networks_free(ieee);
|
|
||||||
goto failed;
|
|
||||||
}
|
|
||||||
HTUpdateDefaultSetting(ieee);
|
|
||||||
HTInitializeHTInfo(ieee); /* may move to other place. */
|
|
||||||
TSInitialize(ieee);
|
|
||||||
|
|
||||||
for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++)
|
|
||||||
INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
|
|
||||||
|
|
||||||
for (i = 0; i < 17; i++) {
|
|
||||||
ieee->last_rxseq_num[i] = -1;
|
|
||||||
ieee->last_rxfrag_num[i] = -1;
|
|
||||||
ieee->last_packet_time[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return dev;
|
|
||||||
|
|
||||||
failed:
|
|
||||||
if (dev)
|
|
||||||
free_netdev(dev);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void free_ieee80211(struct net_device *dev)
|
|
||||||
{
|
|
||||||
struct ieee80211_device *ieee = netdev_priv(dev);
|
|
||||||
int i;
|
|
||||||
/* struct list_head *p, *q; */
|
|
||||||
// del_timer_sync(&ieee->SwBwTimer);
|
|
||||||
kfree(ieee->pHTInfo);
|
|
||||||
ieee->pHTInfo = NULL;
|
|
||||||
RemoveAllTS(ieee);
|
|
||||||
ieee80211_softmac_free(ieee);
|
|
||||||
del_timer_sync(&ieee->crypt_deinit_timer);
|
|
||||||
ieee80211_crypt_deinit_entries(ieee, 1);
|
|
||||||
|
|
||||||
for (i = 0; i < WEP_KEYS; i++) {
|
|
||||||
struct ieee80211_crypt_data *crypt = ieee->crypt[i];
|
|
||||||
|
|
||||||
if (crypt) {
|
|
||||||
if (crypt->ops)
|
|
||||||
crypt->ops->deinit(crypt->priv);
|
|
||||||
kfree(crypt);
|
|
||||||
ieee->crypt[i] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ieee80211_networks_free(ieee);
|
|
||||||
free_netdev(dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_IEEE80211_DEBUG
|
|
||||||
|
|
||||||
u32 ieee80211_debug_level;
|
|
||||||
static int debug = // IEEE80211_DL_INFO |
|
|
||||||
// IEEE80211_DL_WX |
|
|
||||||
// IEEE80211_DL_SCAN |
|
|
||||||
// IEEE80211_DL_STATE |
|
|
||||||
// IEEE80211_DL_MGMT |
|
|
||||||
// IEEE80211_DL_FRAG |
|
|
||||||
// IEEE80211_DL_EAP |
|
|
||||||
// IEEE80211_DL_DROP |
|
|
||||||
// IEEE80211_DL_TX |
|
|
||||||
// IEEE80211_DL_RX |
|
|
||||||
//IEEE80211_DL_QOS |
|
|
||||||
// IEEE80211_DL_HT |
|
|
||||||
// IEEE80211_DL_TS |
|
|
||||||
// IEEE80211_DL_BA |
|
|
||||||
// IEEE80211_DL_REORDER|
|
|
||||||
// IEEE80211_DL_TRACE |
|
|
||||||
//IEEE80211_DL_DATA |
|
|
||||||
IEEE80211_DL_ERR /* awayls open this flags to show error out */
|
|
||||||
;
|
|
||||||
static struct proc_dir_entry *ieee80211_proc;
|
|
||||||
|
|
||||||
static int show_debug_level(struct seq_file *m, void *v)
|
|
||||||
{
|
|
||||||
seq_printf(m, "0x%08X\n", ieee80211_debug_level);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t write_debug_level(struct file *file, const char __user *buffer,
|
|
||||||
size_t count, loff_t *ppos)
|
|
||||||
{
|
|
||||||
unsigned long val;
|
|
||||||
int err = kstrtoul_from_user(buffer, count, 0, &val);
|
|
||||||
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
ieee80211_debug_level = val;
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int open_debug_level(struct inode *inode, struct file *file)
|
|
||||||
{
|
|
||||||
return single_open(file, show_debug_level, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct proc_ops debug_level_proc_ops = {
|
|
||||||
.proc_open = open_debug_level,
|
|
||||||
.proc_read = seq_read,
|
|
||||||
.proc_lseek = seq_lseek,
|
|
||||||
.proc_write = write_debug_level,
|
|
||||||
.proc_release = single_release,
|
|
||||||
};
|
|
||||||
|
|
||||||
int __init ieee80211_debug_init(void)
|
|
||||||
{
|
|
||||||
struct proc_dir_entry *e;
|
|
||||||
|
|
||||||
ieee80211_debug_level = debug;
|
|
||||||
|
|
||||||
ieee80211_proc = proc_mkdir(DRV_NAME, init_net.proc_net);
|
|
||||||
if (!ieee80211_proc) {
|
|
||||||
IEEE80211_ERROR("Unable to create " DRV_NAME
|
|
||||||
" proc directory\n");
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
e = proc_create("debug_level", 0644, ieee80211_proc, &debug_level_proc_ops);
|
|
||||||
if (!e) {
|
|
||||||
remove_proc_entry(DRV_NAME, init_net.proc_net);
|
|
||||||
ieee80211_proc = NULL;
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ieee80211_debug_exit(void)
|
|
||||||
{
|
|
||||||
if (ieee80211_proc) {
|
|
||||||
remove_proc_entry("debug_level", ieee80211_proc);
|
|
||||||
remove_proc_entry(DRV_NAME, init_net.proc_net);
|
|
||||||
ieee80211_proc = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module_param(debug, int, 0444);
|
|
||||||
MODULE_PARM_DESC(debug, "debug output mask");
|
|
||||||
#endif
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,598 +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 "ieee80211.h"
|
|
||||||
#include "dot11d.h"
|
|
||||||
/* FIXME: add A freqs */
|
|
||||||
|
|
||||||
const long ieee80211_wlan_frequencies[] = {
|
|
||||||
2412, 2417, 2422, 2427,
|
|
||||||
2432, 2437, 2442, 2447,
|
|
||||||
2452, 2457, 2462, 2467,
|
|
||||||
2472, 2484
|
|
||||||
};
|
|
||||||
EXPORT_SYMBOL(ieee80211_wlan_frequencies);
|
|
||||||
|
|
||||||
int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
|
|
||||||
union iwreq_data *wrqu, char *b)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
struct iw_freq *fwrq = &wrqu->freq;
|
|
||||||
|
|
||||||
mutex_lock(&ieee->wx_mutex);
|
|
||||||
|
|
||||||
if (ieee->iw_mode == IW_MODE_INFRA) {
|
|
||||||
ret = -EOPNOTSUPP;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if setting by freq convert to channel */
|
|
||||||
if (fwrq->e == 1) {
|
|
||||||
if ((fwrq->m >= (int)2.412e8 &&
|
|
||||||
fwrq->m <= (int)2.487e8)) {
|
|
||||||
int f = fwrq->m / 100000;
|
|
||||||
int c = 0;
|
|
||||||
|
|
||||||
while ((c < 14) && (f != ieee80211_wlan_frequencies[c]))
|
|
||||||
c++;
|
|
||||||
|
|
||||||
/* hack to fall through */
|
|
||||||
fwrq->e = 0;
|
|
||||||
fwrq->m = c + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fwrq->e > 0 || fwrq->m > 14 || fwrq->m < 1) {
|
|
||||||
ret = -EOPNOTSUPP;
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
} else { /* Set the channel */
|
|
||||||
|
|
||||||
if (!(GET_DOT11D_INFO(ieee)->channel_map)[fwrq->m]) {
|
|
||||||
ret = -EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
ieee->current_network.channel = fwrq->m;
|
|
||||||
ieee->set_chan(ieee->dev, ieee->current_network.channel);
|
|
||||||
|
|
||||||
if (ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
|
|
||||||
if (ieee->state == IEEE80211_LINKED) {
|
|
||||||
ieee80211_stop_send_beacons(ieee);
|
|
||||||
ieee80211_start_send_beacons(ieee);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = 0;
|
|
||||||
out:
|
|
||||||
mutex_unlock(&ieee->wx_mutex);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(ieee80211_wx_set_freq);
|
|
||||||
|
|
||||||
int ieee80211_wx_get_freq(struct ieee80211_device *ieee,
|
|
||||||
struct iw_request_info *a,
|
|
||||||
union iwreq_data *wrqu, char *b)
|
|
||||||
{
|
|
||||||
struct iw_freq *fwrq = &wrqu->freq;
|
|
||||||
|
|
||||||
if (ieee->current_network.channel == 0)
|
|
||||||
return -1;
|
|
||||||
/* NM 0.7.0 will not accept channel any more. */
|
|
||||||
fwrq->m = ieee80211_wlan_frequencies[ieee->current_network.channel - 1] * 100000;
|
|
||||||
fwrq->e = 1;
|
|
||||||
/* fwrq->m = ieee->current_network.channel; */
|
|
||||||
/* fwrq->e = 0; */
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(ieee80211_wx_get_freq);
|
|
||||||
|
|
||||||
int ieee80211_wx_get_wap(struct ieee80211_device *ieee,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *extra)
|
|
||||||
{
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
wrqu->ap_addr.sa_family = ARPHRD_ETHER;
|
|
||||||
|
|
||||||
if (ieee->iw_mode == IW_MODE_MONITOR)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
/* We want avoid to give to the user inconsistent infos*/
|
|
||||||
spin_lock_irqsave(&ieee->lock, flags);
|
|
||||||
|
|
||||||
if (ieee->state != IEEE80211_LINKED &&
|
|
||||||
ieee->state != IEEE80211_LINKED_SCANNING &&
|
|
||||||
ieee->wap_set == 0)
|
|
||||||
|
|
||||||
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(ieee80211_wx_get_wap);
|
|
||||||
|
|
||||||
int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *awrq,
|
|
||||||
char *extra)
|
|
||||||
{
|
|
||||||
|
|
||||||
int ret = 0;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
short ifup = ieee->proto_started; /* dev->flags & IFF_UP; */
|
|
||||||
struct sockaddr *temp = (struct sockaddr *)awrq;
|
|
||||||
|
|
||||||
ieee->sync_scan_hurryup = 1;
|
|
||||||
|
|
||||||
mutex_lock(&ieee->wx_mutex);
|
|
||||||
/* use ifconfig hw ether */
|
|
||||||
if (ieee->iw_mode == IW_MODE_MASTER) {
|
|
||||||
ret = -1;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (temp->sa_family != ARPHRD_ETHER) {
|
|
||||||
ret = -EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ifup)
|
|
||||||
ieee80211_stop_protocol(ieee);
|
|
||||||
|
|
||||||
/* just to avoid to give inconsistent infos in the
|
|
||||||
* get wx method. not really needed otherwise
|
|
||||||
*/
|
|
||||||
spin_lock_irqsave(&ieee->lock, flags);
|
|
||||||
|
|
||||||
memcpy(ieee->current_network.bssid, temp->sa_data, ETH_ALEN);
|
|
||||||
ieee->wap_set = !is_zero_ether_addr(temp->sa_data);
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&ieee->lock, flags);
|
|
||||||
|
|
||||||
if (ifup)
|
|
||||||
ieee80211_start_protocol(ieee);
|
|
||||||
out:
|
|
||||||
mutex_unlock(&ieee->wx_mutex);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(ieee80211_wx_set_wap);
|
|
||||||
|
|
||||||
int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a, union iwreq_data *wrqu, char *b)
|
|
||||||
{
|
|
||||||
int len, ret = 0;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
if (ieee->iw_mode == IW_MODE_MONITOR)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
/* We want avoid to give to the user inconsistent infos*/
|
|
||||||
spin_lock_irqsave(&ieee->lock, flags);
|
|
||||||
|
|
||||||
if (ieee->current_network.ssid[0] == '\0' ||
|
|
||||||
ieee->current_network.ssid_len == 0) {
|
|
||||||
ret = -1;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ieee->state != IEEE80211_LINKED &&
|
|
||||||
ieee->state != IEEE80211_LINKED_SCANNING &&
|
|
||||||
ieee->ssid_set == 0) {
|
|
||||||
ret = -1;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
len = ieee->current_network.ssid_len;
|
|
||||||
wrqu->essid.length = len;
|
|
||||||
strncpy(b, ieee->current_network.ssid, len);
|
|
||||||
wrqu->essid.flags = 1;
|
|
||||||
|
|
||||||
out:
|
|
||||||
spin_unlock_irqrestore(&ieee->lock, flags);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(ieee80211_wx_get_essid);
|
|
||||||
|
|
||||||
int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *extra)
|
|
||||||
{
|
|
||||||
|
|
||||||
u32 target_rate = wrqu->bitrate.value;
|
|
||||||
|
|
||||||
ieee->rate = target_rate / 100000;
|
|
||||||
/* FIXME: we might want to limit rate also in management protocols. */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(ieee80211_wx_set_rate);
|
|
||||||
|
|
||||||
int ieee80211_wx_get_rate(struct ieee80211_device *ieee,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *extra)
|
|
||||||
{
|
|
||||||
u32 tmp_rate;
|
|
||||||
|
|
||||||
tmp_rate = TxCountToDataRate(ieee, ieee->softmac_stats.CurrentShowTxate);
|
|
||||||
|
|
||||||
wrqu->bitrate.value = tmp_rate * 500000;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(ieee80211_wx_get_rate);
|
|
||||||
|
|
||||||
int ieee80211_wx_set_rts(struct ieee80211_device *ieee,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *extra)
|
|
||||||
{
|
|
||||||
if (wrqu->rts.disabled || !wrqu->rts.fixed) {
|
|
||||||
ieee->rts = DEFAULT_RTS_THRESHOLD;
|
|
||||||
} else {
|
|
||||||
if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
|
|
||||||
wrqu->rts.value > MAX_RTS_THRESHOLD)
|
|
||||||
return -EINVAL;
|
|
||||||
ieee->rts = wrqu->rts.value;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(ieee80211_wx_set_rts);
|
|
||||||
|
|
||||||
int ieee80211_wx_get_rts(struct ieee80211_device *ieee,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *extra)
|
|
||||||
{
|
|
||||||
wrqu->rts.value = ieee->rts;
|
|
||||||
wrqu->rts.fixed = 0; /* no auto select */
|
|
||||||
wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(ieee80211_wx_get_rts);
|
|
||||||
|
|
||||||
int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
|
|
||||||
union iwreq_data *wrqu, char *b)
|
|
||||||
{
|
|
||||||
|
|
||||||
ieee->sync_scan_hurryup = 1;
|
|
||||||
|
|
||||||
mutex_lock(&ieee->wx_mutex);
|
|
||||||
|
|
||||||
if (wrqu->mode == ieee->iw_mode)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (wrqu->mode == IW_MODE_MONITOR)
|
|
||||||
ieee->dev->type = ARPHRD_IEEE80211;
|
|
||||||
else
|
|
||||||
ieee->dev->type = ARPHRD_ETHER;
|
|
||||||
|
|
||||||
if (!ieee->proto_started) {
|
|
||||||
ieee->iw_mode = wrqu->mode;
|
|
||||||
} else {
|
|
||||||
ieee80211_stop_protocol(ieee);
|
|
||||||
ieee->iw_mode = wrqu->mode;
|
|
||||||
ieee80211_start_protocol(ieee);
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
mutex_unlock(&ieee->wx_mutex);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(ieee80211_wx_set_mode);
|
|
||||||
|
|
||||||
void ieee80211_wx_sync_scan_wq(struct work_struct *work)
|
|
||||||
{
|
|
||||||
struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, wx_sync_scan_wq);
|
|
||||||
short chan;
|
|
||||||
enum ht_extension_chan_offset chan_offset = 0;
|
|
||||||
enum ht_channel_width bandwidth = 0;
|
|
||||||
int b40M = 0;
|
|
||||||
|
|
||||||
chan = ieee->current_network.channel;
|
|
||||||
netif_carrier_off(ieee->dev);
|
|
||||||
|
|
||||||
if (ieee->data_hard_stop)
|
|
||||||
ieee->data_hard_stop(ieee->dev);
|
|
||||||
|
|
||||||
ieee80211_stop_send_beacons(ieee);
|
|
||||||
|
|
||||||
ieee->state = IEEE80211_LINKED_SCANNING;
|
|
||||||
ieee->link_change(ieee->dev);
|
|
||||||
ieee->InitialGainHandler(ieee->dev, IG_Backup);
|
|
||||||
if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT && ieee->pHTInfo->bCurBW40MHz) {
|
|
||||||
b40M = 1;
|
|
||||||
chan_offset = ieee->pHTInfo->CurSTAExtChnlOffset;
|
|
||||||
bandwidth = (enum ht_channel_width)ieee->pHTInfo->bCurBW40MHz;
|
|
||||||
printk("Scan in 40M, force to 20M first:%d, %d\n", chan_offset, bandwidth);
|
|
||||||
ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
|
|
||||||
}
|
|
||||||
ieee80211_start_scan_syncro(ieee);
|
|
||||||
if (b40M) {
|
|
||||||
printk("Scan in 20M, back to 40M\n");
|
|
||||||
if (chan_offset == HT_EXTCHNL_OFFSET_UPPER)
|
|
||||||
ieee->set_chan(ieee->dev, chan + 2);
|
|
||||||
else if (chan_offset == HT_EXTCHNL_OFFSET_LOWER)
|
|
||||||
ieee->set_chan(ieee->dev, chan - 2);
|
|
||||||
else
|
|
||||||
ieee->set_chan(ieee->dev, chan);
|
|
||||||
ieee->SetBWModeHandler(ieee->dev, bandwidth, chan_offset);
|
|
||||||
} else {
|
|
||||||
ieee->set_chan(ieee->dev, chan);
|
|
||||||
}
|
|
||||||
|
|
||||||
ieee->InitialGainHandler(ieee->dev, IG_Restore);
|
|
||||||
ieee->state = IEEE80211_LINKED;
|
|
||||||
ieee->link_change(ieee->dev);
|
|
||||||
/* To prevent the immediately calling watch_dog after scan. */
|
|
||||||
if (ieee->LinkDetectInfo.NumRecvBcnInPeriod == 0 || ieee->LinkDetectInfo.NumRecvDataInPeriod == 0) {
|
|
||||||
ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1;
|
|
||||||
ieee->LinkDetectInfo.NumRecvDataInPeriod = 1;
|
|
||||||
}
|
|
||||||
if (ieee->data_hard_resume)
|
|
||||||
ieee->data_hard_resume(ieee->dev);
|
|
||||||
|
|
||||||
if (ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
|
|
||||||
ieee80211_start_send_beacons(ieee);
|
|
||||||
|
|
||||||
netif_carrier_on(ieee->dev);
|
|
||||||
mutex_unlock(&ieee->wx_mutex);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a,
|
|
||||||
union iwreq_data *wrqu, char *b)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
mutex_lock(&ieee->wx_mutex);
|
|
||||||
|
|
||||||
if (ieee->iw_mode == IW_MODE_MONITOR || !(ieee->proto_started)) {
|
|
||||||
ret = -1;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ieee->state == IEEE80211_LINKED) {
|
|
||||||
queue_work(ieee->wq, &ieee->wx_sync_scan_wq);
|
|
||||||
/* intentionally forget to up sem */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
mutex_unlock(&ieee->wx_mutex);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(ieee80211_wx_set_scan);
|
|
||||||
|
|
||||||
int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
|
|
||||||
struct iw_request_info *a,
|
|
||||||
union iwreq_data *wrqu, char *extra)
|
|
||||||
{
|
|
||||||
|
|
||||||
int ret = 0, len;
|
|
||||||
short proto_started;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
ieee->sync_scan_hurryup = 1;
|
|
||||||
mutex_lock(&ieee->wx_mutex);
|
|
||||||
|
|
||||||
proto_started = ieee->proto_started;
|
|
||||||
|
|
||||||
if (wrqu->essid.length > IW_ESSID_MAX_SIZE) {
|
|
||||||
ret = -E2BIG;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ieee->iw_mode == IW_MODE_MONITOR) {
|
|
||||||
ret = -1;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (proto_started)
|
|
||||||
ieee80211_stop_protocol(ieee);
|
|
||||||
|
|
||||||
|
|
||||||
/* this is just to be sure that the GET wx callback
|
|
||||||
* has consisten infos. not needed otherwise
|
|
||||||
*/
|
|
||||||
spin_lock_irqsave(&ieee->lock, flags);
|
|
||||||
|
|
||||||
if (wrqu->essid.flags && wrqu->essid.length) {
|
|
||||||
/* first flush current network.ssid */
|
|
||||||
len = ((wrqu->essid.length - 1) < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length - 1) : IW_ESSID_MAX_SIZE;
|
|
||||||
strncpy(ieee->current_network.ssid, extra, len + 1);
|
|
||||||
ieee->current_network.ssid_len = len + 1;
|
|
||||||
ieee->ssid_set = 1;
|
|
||||||
} else {
|
|
||||||
ieee->ssid_set = 0;
|
|
||||||
ieee->current_network.ssid[0] = '\0';
|
|
||||||
ieee->current_network.ssid_len = 0;
|
|
||||||
}
|
|
||||||
spin_unlock_irqrestore(&ieee->lock, flags);
|
|
||||||
|
|
||||||
if (proto_started)
|
|
||||||
ieee80211_start_protocol(ieee);
|
|
||||||
out:
|
|
||||||
mutex_unlock(&ieee->wx_mutex);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(ieee80211_wx_set_essid);
|
|
||||||
|
|
||||||
int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
|
|
||||||
union iwreq_data *wrqu, char *b)
|
|
||||||
{
|
|
||||||
|
|
||||||
wrqu->mode = ieee->iw_mode;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(ieee80211_wx_get_mode);
|
|
||||||
|
|
||||||
int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *extra)
|
|
||||||
{
|
|
||||||
|
|
||||||
int *parms = (int *)extra;
|
|
||||||
int enable = (parms[0] > 0);
|
|
||||||
short prev = ieee->raw_tx;
|
|
||||||
|
|
||||||
mutex_lock(&ieee->wx_mutex);
|
|
||||||
|
|
||||||
if (enable)
|
|
||||||
ieee->raw_tx = 1;
|
|
||||||
else
|
|
||||||
ieee->raw_tx = 0;
|
|
||||||
|
|
||||||
netdev_info(ieee->dev, "raw TX is %s\n",
|
|
||||||
ieee->raw_tx ? "enabled" : "disabled");
|
|
||||||
|
|
||||||
if (ieee->iw_mode == IW_MODE_MONITOR) {
|
|
||||||
if (prev == 0 && ieee->raw_tx) {
|
|
||||||
if (ieee->data_hard_resume)
|
|
||||||
ieee->data_hard_resume(ieee->dev);
|
|
||||||
|
|
||||||
netif_carrier_on(ieee->dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (prev && ieee->raw_tx == 1)
|
|
||||||
netif_carrier_off(ieee->dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_unlock(&ieee->wx_mutex);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(ieee80211_wx_set_rawtx);
|
|
||||||
|
|
||||||
int ieee80211_wx_get_name(struct ieee80211_device *ieee,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *extra)
|
|
||||||
{
|
|
||||||
strscpy(wrqu->name, "802.11", IFNAMSIZ);
|
|
||||||
if (ieee->modulation & IEEE80211_CCK_MODULATION) {
|
|
||||||
strlcat(wrqu->name, "b", IFNAMSIZ);
|
|
||||||
if (ieee->modulation & IEEE80211_OFDM_MODULATION)
|
|
||||||
strlcat(wrqu->name, "/g", IFNAMSIZ);
|
|
||||||
} else if (ieee->modulation & IEEE80211_OFDM_MODULATION) {
|
|
||||||
strlcat(wrqu->name, "g", IFNAMSIZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ieee->mode & (IEEE_N_24G | IEEE_N_5G))
|
|
||||||
strlcat(wrqu->name, "/n", IFNAMSIZ);
|
|
||||||
|
|
||||||
if ((ieee->state == IEEE80211_LINKED) ||
|
|
||||||
(ieee->state == IEEE80211_LINKED_SCANNING))
|
|
||||||
strlcat(wrqu->name, " linked", IFNAMSIZ);
|
|
||||||
else if (ieee->state != IEEE80211_NOLINK)
|
|
||||||
strlcat(wrqu->name, " link..", IFNAMSIZ);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(ieee80211_wx_get_name);
|
|
||||||
|
|
||||||
/* this is mostly stolen from hostap */
|
|
||||||
int ieee80211_wx_set_power(struct ieee80211_device *ieee,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *extra)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
mutex_lock(&ieee->wx_mutex);
|
|
||||||
|
|
||||||
if (wrqu->power.disabled) {
|
|
||||||
ieee->ps = IEEE80211_PS_DISABLED;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
if (wrqu->power.flags & IW_POWER_TIMEOUT) {
|
|
||||||
/* ieee->ps_period = wrqu->power.value / 1000; */
|
|
||||||
ieee->ps_timeout = wrqu->power.value / 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wrqu->power.flags & IW_POWER_PERIOD) {
|
|
||||||
|
|
||||||
/* ieee->ps_timeout = wrqu->power.value / 1000; */
|
|
||||||
ieee->ps_period = wrqu->power.value / 1000;
|
|
||||||
/* wrq->value / 1024; */
|
|
||||||
|
|
||||||
}
|
|
||||||
switch (wrqu->power.flags & IW_POWER_MODE) {
|
|
||||||
case IW_POWER_UNICAST_R:
|
|
||||||
ieee->ps = IEEE80211_PS_UNICAST;
|
|
||||||
break;
|
|
||||||
case IW_POWER_MULTICAST_R:
|
|
||||||
ieee->ps = IEEE80211_PS_MBCAST;
|
|
||||||
break;
|
|
||||||
case IW_POWER_ALL_R:
|
|
||||||
ieee->ps = IEEE80211_PS_UNICAST | IEEE80211_PS_MBCAST;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IW_POWER_ON:
|
|
||||||
/* ieee->ps = IEEE80211_PS_DISABLED; */
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
ret = -EINVAL;
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
}
|
|
||||||
exit:
|
|
||||||
mutex_unlock(&ieee->wx_mutex);
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(ieee80211_wx_set_power);
|
|
||||||
|
|
||||||
/* this is stolen from hostap */
|
|
||||||
int ieee80211_wx_get_power(struct ieee80211_device *ieee,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *extra)
|
|
||||||
{
|
|
||||||
mutex_lock(&ieee->wx_mutex);
|
|
||||||
|
|
||||||
if (ieee->ps == IEEE80211_PS_DISABLED) {
|
|
||||||
wrqu->power.disabled = 1;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
wrqu->power.disabled = 0;
|
|
||||||
|
|
||||||
if ((wrqu->power.flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
|
|
||||||
wrqu->power.flags = IW_POWER_TIMEOUT;
|
|
||||||
wrqu->power.value = ieee->ps_timeout * 1000;
|
|
||||||
} else {
|
|
||||||
/* ret = -EOPNOTSUPP; */
|
|
||||||
/* goto exit; */
|
|
||||||
wrqu->power.flags = IW_POWER_PERIOD;
|
|
||||||
wrqu->power.value = ieee->ps_period * 1000;
|
|
||||||
/* ieee->current_network.dtim_period * ieee->current_network.beacon_interval * 1024; */
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ieee->ps & (IEEE80211_PS_MBCAST | IEEE80211_PS_UNICAST)) == (IEEE80211_PS_MBCAST | IEEE80211_PS_UNICAST))
|
|
||||||
wrqu->power.flags |= IW_POWER_ALL_R;
|
|
||||||
else if (ieee->ps & IEEE80211_PS_MBCAST)
|
|
||||||
wrqu->power.flags |= IW_POWER_MULTICAST_R;
|
|
||||||
else
|
|
||||||
wrqu->power.flags |= IW_POWER_UNICAST_R;
|
|
||||||
|
|
||||||
exit:
|
|
||||||
mutex_unlock(&ieee->wx_mutex);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(ieee80211_wx_get_power);
|
|
@ -1,839 +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 "ieee80211.h"
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* 802.11 Data Frame
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* 802.11 frame_contorl for data frames - 2 bytes
|
|
||||||
* ,-----------------------------------------------------------------------------------------.
|
|
||||||
* bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e |
|
|
||||||
* |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
|
|
||||||
* val | 0 | 0 | 0 | 1 | x | 0 | 0 | 0 | 1 | 0 | x | x | x | x | x |
|
|
||||||
* |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
|
|
||||||
* desc | ^-ver-^ | ^type-^ | ^-----subtype-----^ | to |from |more |retry| pwr |more |wep |
|
|
||||||
* | | | x=0 data,x=1 data+ack | DS | DS |frag | | mgm |data | |
|
|
||||||
* '-----------------------------------------------------------------------------------------'
|
|
||||||
* /\
|
|
||||||
* |
|
|
||||||
* 802.11 Data Frame |
|
|
||||||
* ,--------- 'ctrl' expands to >-----------'
|
|
||||||
* |
|
|
||||||
* ,--'---,-------------------------------------------------------------.
|
|
||||||
* Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 |
|
|
||||||
* |------|------|---------|---------|---------|------|---------|------|
|
|
||||||
* Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | Frame | fcs |
|
|
||||||
* | | tion | (BSSID) | | | ence | data | |
|
|
||||||
* `--------------------------------------------------| |------'
|
|
||||||
* Total: 28 non-data bytes `----.----'
|
|
||||||
* |
|
|
||||||
* .- 'Frame data' expands to <---------------------------'
|
|
||||||
* |
|
|
||||||
* V
|
|
||||||
* ,---------------------------------------------------.
|
|
||||||
* Bytes | 1 | 1 | 1 | 3 | 2 | 0-2304 |
|
|
||||||
* |------|------|---------|----------|------|---------|
|
|
||||||
* Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP |
|
|
||||||
* | DSAP | SSAP | | | | Packet |
|
|
||||||
* | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8| | |
|
|
||||||
* `-----------------------------------------| |
|
|
||||||
* Total: 8 non-data bytes `----.----'
|
|
||||||
* |
|
|
||||||
* .- 'IP Packet' expands, if WEP enabled, to <--'
|
|
||||||
* |
|
|
||||||
* V
|
|
||||||
* ,-----------------------.
|
|
||||||
* Bytes | 4 | 0-2296 | 4 |
|
|
||||||
* |-----|-----------|-----|
|
|
||||||
* Desc. | IV | Encrypted | ICV |
|
|
||||||
* | | IP Packet | |
|
|
||||||
* `-----------------------'
|
|
||||||
* Total: 8 non-data bytes
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* 802.3 Ethernet Data Frame
|
|
||||||
*
|
|
||||||
* ,-----------------------------------------.
|
|
||||||
* Bytes | 6 | 6 | 2 | Variable | 4 |
|
|
||||||
* |-------|-------|------|-----------|------|
|
|
||||||
* Desc. | Dest. | Source| Type | IP Packet | fcs |
|
|
||||||
* | MAC | MAC | | | |
|
|
||||||
* `-----------------------------------------'
|
|
||||||
* Total: 18 non-data bytes
|
|
||||||
*
|
|
||||||
* In the event that fragmentation is required, the incoming payload is split into
|
|
||||||
* N parts of size ieee->fts. The first fragment contains the SNAP header and the
|
|
||||||
* remaining packets are just data.
|
|
||||||
*
|
|
||||||
* If encryption is enabled, each fragment payload size is reduced by enough space
|
|
||||||
* to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP)
|
|
||||||
* So if you have 1500 bytes of payload with ieee->fts set to 500 without
|
|
||||||
* encryption it will take 3 frames. With WEP it will take 4 frames as the
|
|
||||||
* payload of each frame is reduced to 492 bytes.
|
|
||||||
*
|
|
||||||
* SKB visualization
|
|
||||||
*
|
|
||||||
* ,- skb->data
|
|
||||||
* |
|
|
||||||
* | ETHERNET HEADER ,-<-- PAYLOAD
|
|
||||||
* | | 14 bytes from skb->data
|
|
||||||
* | 2 bytes for Type --> ,T. | (sizeof ethhdr)
|
|
||||||
* | | | |
|
|
||||||
* |,-Dest.--. ,--Src.---. | | |
|
|
||||||
* | 6 bytes| | 6 bytes | | | |
|
|
||||||
* v | | | | | |
|
|
||||||
* 0 | v 1 | v | v 2
|
|
||||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
|
|
||||||
* ^ | ^ | ^ |
|
|
||||||
* | | | | | |
|
|
||||||
* | | | | `T' <---- 2 bytes for Type
|
|
||||||
* | | | |
|
|
||||||
* | | '---SNAP--' <-------- 6 bytes for SNAP
|
|
||||||
* | |
|
|
||||||
* `-IV--' <-------------------- 4 bytes for IV (WEP)
|
|
||||||
*
|
|
||||||
* SNAP HEADER
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
|
|
||||||
static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
|
|
||||||
|
|
||||||
static inline int ieee80211_put_snap(u8 *data, u16 h_proto)
|
|
||||||
{
|
|
||||||
struct ieee80211_snap_hdr *snap;
|
|
||||||
u8 *oui;
|
|
||||||
|
|
||||||
snap = (struct ieee80211_snap_hdr *)data;
|
|
||||||
snap->dsap = 0xaa;
|
|
||||||
snap->ssap = 0xaa;
|
|
||||||
snap->ctrl = 0x03;
|
|
||||||
|
|
||||||
if (h_proto == 0x8137 || h_proto == 0x80f3)
|
|
||||||
oui = P802_1H_OUI;
|
|
||||||
else
|
|
||||||
oui = RFC1042_OUI;
|
|
||||||
snap->oui[0] = oui[0];
|
|
||||||
snap->oui[1] = oui[1];
|
|
||||||
snap->oui[2] = oui[2];
|
|
||||||
|
|
||||||
*(__be16 *)(data + SNAP_SIZE) = htons(h_proto);
|
|
||||||
|
|
||||||
return SNAP_SIZE + sizeof(u16);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ieee80211_encrypt_fragment(
|
|
||||||
struct ieee80211_device *ieee,
|
|
||||||
struct sk_buff *frag,
|
|
||||||
int hdr_len)
|
|
||||||
{
|
|
||||||
struct ieee80211_crypt_data *crypt = ieee->crypt[ieee->tx_keyidx];
|
|
||||||
int res;
|
|
||||||
|
|
||||||
if (!(crypt && crypt->ops)) {
|
|
||||||
printk("=========>%s(), crypt is null\n", __func__);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ieee->tkip_countermeasures &&
|
|
||||||
crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
|
|
||||||
if (net_ratelimit()) {
|
|
||||||
struct rtl_80211_hdr_3addrqos *header;
|
|
||||||
|
|
||||||
header = (struct rtl_80211_hdr_3addrqos *)frag->data;
|
|
||||||
netdev_dbg(ieee->dev, "TKIP countermeasures: dropped "
|
|
||||||
"TX packet to %pM\n", header->addr1);
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* To encrypt, frame format is:
|
|
||||||
* IV (4 bytes), clear payload (including SNAP), ICV (4 bytes)
|
|
||||||
*/
|
|
||||||
|
|
||||||
// PR: FIXME: Copied from hostap. Check fragmentation/MSDU/MPDU encryption.
|
|
||||||
/* 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, "Encryption failed: len=%d.\n",
|
|
||||||
frag->len);
|
|
||||||
ieee->ieee_stats.tx_discards++;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ieee80211_txb_free(struct ieee80211_txb *txb)
|
|
||||||
{
|
|
||||||
//int i;
|
|
||||||
if (unlikely(!txb))
|
|
||||||
return;
|
|
||||||
kfree(txb);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(ieee80211_txb_free);
|
|
||||||
|
|
||||||
static struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
|
|
||||||
gfp_t gfp_mask)
|
|
||||||
{
|
|
||||||
struct ieee80211_txb *txb;
|
|
||||||
int i;
|
|
||||||
txb = kmalloc(
|
|
||||||
sizeof(struct ieee80211_txb) + (sizeof(u8 *) * nr_frags),
|
|
||||||
gfp_mask);
|
|
||||||
if (!txb)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
memset(txb, 0, sizeof(struct ieee80211_txb));
|
|
||||||
txb->nr_frags = nr_frags;
|
|
||||||
txb->frag_size = __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])) {
|
|
||||||
i--;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
memset(txb->fragments[i]->cb, 0, sizeof(txb->fragments[i]->cb));
|
|
||||||
}
|
|
||||||
if (unlikely(i != nr_frags)) {
|
|
||||||
while (i >= 0)
|
|
||||||
dev_kfree_skb_any(txb->fragments[i--]);
|
|
||||||
kfree(txb);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return txb;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Classify the to-be send data packet
|
|
||||||
// Need to acquire the sent queue index.
|
|
||||||
static int
|
|
||||||
ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network)
|
|
||||||
{
|
|
||||||
struct ethhdr *eth;
|
|
||||||
struct iphdr *ip;
|
|
||||||
eth = (struct ethhdr *)skb->data;
|
|
||||||
if (eth->h_proto != htons(ETH_P_IP))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
ip = ip_hdr(skb);
|
|
||||||
switch (ip->tos & 0xfc) {
|
|
||||||
case 0x20:
|
|
||||||
return 2;
|
|
||||||
case 0x40:
|
|
||||||
return 1;
|
|
||||||
case 0x60:
|
|
||||||
return 3;
|
|
||||||
case 0x80:
|
|
||||||
return 4;
|
|
||||||
case 0xa0:
|
|
||||||
return 5;
|
|
||||||
case 0xc0:
|
|
||||||
return 6;
|
|
||||||
case 0xe0:
|
|
||||||
return 7;
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ieee80211_tx_query_agg_cap(struct ieee80211_device *ieee,
|
|
||||||
struct sk_buff *skb, struct cb_desc *tcb_desc)
|
|
||||||
{
|
|
||||||
PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
|
|
||||||
struct tx_ts_record *pTxTs = NULL;
|
|
||||||
struct rtl_80211_hdr_1addr *hdr = (struct rtl_80211_hdr_1addr *)skb->data;
|
|
||||||
|
|
||||||
if (!pHTInfo->bCurrentHTSupport || !pHTInfo->bEnableHT)
|
|
||||||
return;
|
|
||||||
if (!IsQoSDataFrame(skb->data))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (is_multicast_ether_addr(hdr->addr1))
|
|
||||||
return;
|
|
||||||
//check packet and mode later
|
|
||||||
if (!ieee->GetNmodeSupportBySecCfg(ieee->dev))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (pHTInfo->bCurrentAMPDUEnable) {
|
|
||||||
if (!GetTs(ieee, (struct ts_common_info **)(&pTxTs), hdr->addr1, skb->priority, TX_DIR, true)) {
|
|
||||||
printk("===>can't get TS\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!pTxTs->tx_admitted_ba_record.valid) {
|
|
||||||
TsStartAddBaProcess(ieee, pTxTs);
|
|
||||||
goto FORCED_AGG_SETTING;
|
|
||||||
} else if (!pTxTs->using_ba) {
|
|
||||||
if (SN_LESS(pTxTs->tx_admitted_ba_record.start_seq_ctrl.field.seq_num, (pTxTs->tx_cur_seq + 1) % 4096))
|
|
||||||
pTxTs->using_ba = true;
|
|
||||||
else
|
|
||||||
goto FORCED_AGG_SETTING;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ieee->iw_mode == IW_MODE_INFRA) {
|
|
||||||
tcb_desc->bAMPDUEnable = true;
|
|
||||||
tcb_desc->ampdu_factor = pHTInfo->CurrentAMPDUFactor;
|
|
||||||
tcb_desc->ampdu_density = pHTInfo->CurrentMPDUDensity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FORCED_AGG_SETTING:
|
|
||||||
switch (pHTInfo->ForcedAMPDUMode) {
|
|
||||||
case HT_AGG_AUTO:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HT_AGG_FORCE_ENABLE:
|
|
||||||
tcb_desc->bAMPDUEnable = true;
|
|
||||||
tcb_desc->ampdu_density = pHTInfo->ForcedMPDUDensity;
|
|
||||||
tcb_desc->ampdu_factor = pHTInfo->ForcedAMPDUFactor;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HT_AGG_FORCE_DISABLE:
|
|
||||||
tcb_desc->bAMPDUEnable = false;
|
|
||||||
tcb_desc->ampdu_density = 0;
|
|
||||||
tcb_desc->ampdu_factor = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ieee80211_qurey_ShortPreambleMode(struct ieee80211_device *ieee,
|
|
||||||
struct cb_desc *tcb_desc)
|
|
||||||
{
|
|
||||||
tcb_desc->bUseShortPreamble = false;
|
|
||||||
if (tcb_desc->data_rate == 2) {//// 1M can only use Long Preamble. 11B spec
|
|
||||||
return;
|
|
||||||
} else if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE) {
|
|
||||||
tcb_desc->bUseShortPreamble = true;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
static void
|
|
||||||
ieee80211_query_HTCapShortGI(struct ieee80211_device *ieee, struct cb_desc *tcb_desc)
|
|
||||||
{
|
|
||||||
PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
|
|
||||||
|
|
||||||
tcb_desc->bUseShortGI = false;
|
|
||||||
|
|
||||||
if (!pHTInfo->bCurrentHTSupport || !pHTInfo->bEnableHT)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (pHTInfo->bForcedShortGI) {
|
|
||||||
tcb_desc->bUseShortGI = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pHTInfo->bCurBW40MHz && pHTInfo->bCurShortGI40MHz)
|
|
||||||
tcb_desc->bUseShortGI = true;
|
|
||||||
else if (!pHTInfo->bCurBW40MHz && pHTInfo->bCurShortGI20MHz)
|
|
||||||
tcb_desc->bUseShortGI = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ieee80211_query_BandwidthMode(struct ieee80211_device *ieee,
|
|
||||||
struct cb_desc *tcb_desc)
|
|
||||||
{
|
|
||||||
PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
|
|
||||||
|
|
||||||
tcb_desc->bPacketBW = false;
|
|
||||||
|
|
||||||
if (!pHTInfo->bCurrentHTSupport || !pHTInfo->bEnableHT)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (tcb_desc->bMulticast || tcb_desc->bBroadcast)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if ((tcb_desc->data_rate & 0x80) == 0) // If using legacy rate, it shall use 20MHz channel.
|
|
||||||
return;
|
|
||||||
//BandWidthAutoSwitch is for auto switch to 20 or 40 in long distance
|
|
||||||
if (pHTInfo->bCurBW40MHz && pHTInfo->bCurTxBW40MHz && !ieee->bandwidth_auto_switch.bforced_tx20Mhz)
|
|
||||||
tcb_desc->bPacketBW = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ieee80211_query_protectionmode(struct ieee80211_device *ieee,
|
|
||||||
struct cb_desc *tcb_desc,
|
|
||||||
struct sk_buff *skb)
|
|
||||||
{
|
|
||||||
// Common Settings
|
|
||||||
tcb_desc->bRTSSTBC = false;
|
|
||||||
tcb_desc->bRTSUseShortGI = false; // Since protection frames are always sent by legacy rate, ShortGI will never be used.
|
|
||||||
tcb_desc->bCTSEnable = false; // Most of protection using RTS/CTS
|
|
||||||
tcb_desc->RTSSC = 0; // 20MHz: Don't care; 40MHz: Duplicate.
|
|
||||||
tcb_desc->bRTSBW = false; // RTS frame bandwidth is always 20MHz
|
|
||||||
|
|
||||||
if (tcb_desc->bBroadcast || tcb_desc->bMulticast) //only unicast frame will use rts/cts
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (is_broadcast_ether_addr(skb->data + 16)) //check addr3 as infrastructure add3 is DA.
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (ieee->mode < IEEE_N_24G) /* b, g mode */ {
|
|
||||||
// (1) RTS_Threshold is compared to the MPDU, not MSDU.
|
|
||||||
// (2) If there are more than one frag in this MSDU, only the first frag uses protection frame.
|
|
||||||
// Other fragments are protected by previous fragment.
|
|
||||||
// So we only need to check the length of first fragment.
|
|
||||||
if (skb->len > ieee->rts) {
|
|
||||||
tcb_desc->bRTSEnable = true;
|
|
||||||
tcb_desc->rts_rate = MGN_24M;
|
|
||||||
} else if (ieee->current_network.buseprotection) {
|
|
||||||
// Use CTS-to-SELF in protection mode.
|
|
||||||
tcb_desc->bRTSEnable = true;
|
|
||||||
tcb_desc->bCTSEnable = true;
|
|
||||||
tcb_desc->rts_rate = MGN_24M;
|
|
||||||
}
|
|
||||||
//otherwise return;
|
|
||||||
return;
|
|
||||||
} else { // 11n High throughput case.
|
|
||||||
PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
|
|
||||||
while (true) {
|
|
||||||
//check ERP protection
|
|
||||||
if (ieee->current_network.buseprotection) {// CTS-to-SELF
|
|
||||||
tcb_desc->bRTSEnable = true;
|
|
||||||
tcb_desc->bCTSEnable = true;
|
|
||||||
tcb_desc->rts_rate = MGN_24M;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
//check HT op mode
|
|
||||||
if (pHTInfo->bCurrentHTSupport && pHTInfo->bEnableHT) {
|
|
||||||
u8 HTOpMode = pHTInfo->CurrentOpMode;
|
|
||||||
if ((pHTInfo->bCurBW40MHz && (HTOpMode == 2 || HTOpMode == 3)) ||
|
|
||||||
(!pHTInfo->bCurBW40MHz && HTOpMode == 3)) {
|
|
||||||
tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
|
|
||||||
tcb_desc->bRTSEnable = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//check rts
|
|
||||||
if (skb->len > ieee->rts) {
|
|
||||||
tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
|
|
||||||
tcb_desc->bRTSEnable = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
//to do list: check MIMO power save condition.
|
|
||||||
//check AMPDU aggregation for TXOP
|
|
||||||
if (tcb_desc->bAMPDUEnable) {
|
|
||||||
tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
|
|
||||||
// According to 8190 design, firmware sends CF-End only if RTS/CTS is enabled. However, it degrads
|
|
||||||
// throughput around 10M, so we disable of this mechanism. 2007.08.03 by Emily
|
|
||||||
tcb_desc->bRTSEnable = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
//check IOT action
|
|
||||||
if (pHTInfo->IOTAction & HT_IOT_ACT_FORCED_CTS2SELF) {
|
|
||||||
tcb_desc->bCTSEnable = true;
|
|
||||||
tcb_desc->rts_rate = MGN_24M;
|
|
||||||
tcb_desc->bRTSEnable = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// Totally no protection case!!
|
|
||||||
goto NO_PROTECTION;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// For test , CTS replace with RTS
|
|
||||||
if (0) {
|
|
||||||
tcb_desc->bCTSEnable = true;
|
|
||||||
tcb_desc->rts_rate = MGN_24M;
|
|
||||||
tcb_desc->bRTSEnable = true;
|
|
||||||
}
|
|
||||||
if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
|
|
||||||
tcb_desc->bUseShortPreamble = true;
|
|
||||||
if (ieee->mode == IW_MODE_MASTER)
|
|
||||||
goto NO_PROTECTION;
|
|
||||||
return;
|
|
||||||
NO_PROTECTION:
|
|
||||||
tcb_desc->bRTSEnable = false;
|
|
||||||
tcb_desc->bCTSEnable = false;
|
|
||||||
tcb_desc->rts_rate = 0;
|
|
||||||
tcb_desc->RTSSC = 0;
|
|
||||||
tcb_desc->bRTSBW = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void ieee80211_txrate_selectmode(struct ieee80211_device *ieee,
|
|
||||||
struct cb_desc *tcb_desc)
|
|
||||||
{
|
|
||||||
if (ieee->bTxDisableRateFallBack)
|
|
||||||
tcb_desc->bTxDisableRateFallBack = true;
|
|
||||||
|
|
||||||
if (ieee->bTxUseDriverAssingedRate)
|
|
||||||
tcb_desc->bTxUseDriverAssingedRate = true;
|
|
||||||
if (!tcb_desc->bTxDisableRateFallBack || !tcb_desc->bTxUseDriverAssingedRate) {
|
|
||||||
if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
|
|
||||||
tcb_desc->RATRIndex = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ieee80211_query_seqnum(struct ieee80211_device *ieee,
|
|
||||||
struct sk_buff *skb, u8 *dst)
|
|
||||||
{
|
|
||||||
if (is_multicast_ether_addr(dst))
|
|
||||||
return;
|
|
||||||
if (IsQoSDataFrame(skb->data)) /* we deal qos data only */ {
|
|
||||||
struct tx_ts_record *pTS = NULL;
|
|
||||||
if (!GetTs(ieee, (struct ts_common_info **)(&pTS), dst, skb->priority, TX_DIR, true)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pTS->tx_cur_seq = (pTS->tx_cur_seq + 1) % 4096;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
netdev_tx_t ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
|
|
||||||
{
|
|
||||||
struct ieee80211_device *ieee = netdev_priv(dev);
|
|
||||||
struct ieee80211_txb *txb = NULL;
|
|
||||||
struct rtl_80211_hdr_3addrqos *frag_hdr;
|
|
||||||
int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
|
|
||||||
unsigned long flags;
|
|
||||||
struct net_device_stats *stats = &ieee->stats;
|
|
||||||
int ether_type = 0, encrypt;
|
|
||||||
int bytes, fc, qos_ctl = 0, hdr_len;
|
|
||||||
struct sk_buff *skb_frag;
|
|
||||||
struct rtl_80211_hdr_3addrqos header = { /* Ensure zero initialized */
|
|
||||||
.duration_id = 0,
|
|
||||||
.seq_ctl = 0,
|
|
||||||
.qos_ctl = 0
|
|
||||||
};
|
|
||||||
u8 dest[ETH_ALEN], src[ETH_ALEN];
|
|
||||||
int qos_actived = ieee->current_network.qos_data.active;
|
|
||||||
|
|
||||||
struct ieee80211_crypt_data *crypt;
|
|
||||||
|
|
||||||
struct cb_desc *tcb_desc;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&ieee->lock, flags);
|
|
||||||
|
|
||||||
/* If there is no driver handler to take the TXB, dont' bother
|
|
||||||
* creating it...
|
|
||||||
*/
|
|
||||||
if ((!ieee->hard_start_xmit && !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)) ||
|
|
||||||
((!ieee->softmac_data_hard_start_xmit && (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) {
|
|
||||||
netdev_warn(ieee->dev, "No xmit handler.\n");
|
|
||||||
goto success;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (likely(ieee->raw_tx == 0)) {
|
|
||||||
if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
|
|
||||||
netdev_warn(ieee->dev, "skb too small (%d).\n",
|
|
||||||
skb->len);
|
|
||||||
goto success;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(skb->cb, 0, sizeof(skb->cb));
|
|
||||||
ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
|
|
||||||
|
|
||||||
crypt = ieee->crypt[ieee->tx_keyidx];
|
|
||||||
|
|
||||||
encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
|
|
||||||
ieee->host_encrypt && crypt && crypt->ops;
|
|
||||||
|
|
||||||
if (!encrypt && ieee->ieee802_1x &&
|
|
||||||
ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
|
|
||||||
stats->tx_dropped++;
|
|
||||||
goto success;
|
|
||||||
}
|
|
||||||
#ifdef CONFIG_IEEE80211_DEBUG
|
|
||||||
if (crypt && !encrypt && ether_type == ETH_P_PAE) {
|
|
||||||
struct eapol *eap = (struct eapol *)(skb->data +
|
|
||||||
sizeof(struct ethhdr) - SNAP_SIZE - sizeof(u16));
|
|
||||||
IEEE80211_DEBUG_EAP("TX: IEEE 802.11 EAPOL frame: %s\n",
|
|
||||||
eap_get_type(eap->type));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Save source and destination addresses */
|
|
||||||
memcpy(&dest, skb->data, ETH_ALEN);
|
|
||||||
memcpy(&src, skb->data + ETH_ALEN, ETH_ALEN);
|
|
||||||
|
|
||||||
/* Advance the SKB to the start of the payload */
|
|
||||||
skb_pull(skb, sizeof(struct ethhdr));
|
|
||||||
|
|
||||||
/* Determine total amount of storage required for TXB packets */
|
|
||||||
bytes = skb->len + SNAP_SIZE + sizeof(u16);
|
|
||||||
|
|
||||||
if (encrypt)
|
|
||||||
fc = IEEE80211_FTYPE_DATA | IEEE80211_FCTL_WEP;
|
|
||||||
else
|
|
||||||
|
|
||||||
fc = IEEE80211_FTYPE_DATA;
|
|
||||||
|
|
||||||
//if(ieee->current_network.QoS_Enable)
|
|
||||||
if (qos_actived)
|
|
||||||
fc |= IEEE80211_STYPE_QOS_DATA;
|
|
||||||
else
|
|
||||||
fc |= IEEE80211_STYPE_DATA;
|
|
||||||
|
|
||||||
if (ieee->iw_mode == IW_MODE_INFRA) {
|
|
||||||
fc |= IEEE80211_FCTL_TODS;
|
|
||||||
/* To DS: Addr1 = BSSID, Addr2 = SA,
|
|
||||||
* Addr3 = DA
|
|
||||||
*/
|
|
||||||
memcpy(&header.addr1, ieee->current_network.bssid, ETH_ALEN);
|
|
||||||
memcpy(&header.addr2, &src, ETH_ALEN);
|
|
||||||
memcpy(&header.addr3, &dest, ETH_ALEN);
|
|
||||||
} else if (ieee->iw_mode == IW_MODE_ADHOC) {
|
|
||||||
/* not From/To DS: Addr1 = DA, Addr2 = SA,
|
|
||||||
* Addr3 = BSSID
|
|
||||||
*/
|
|
||||||
memcpy(&header.addr1, dest, ETH_ALEN);
|
|
||||||
memcpy(&header.addr2, src, ETH_ALEN);
|
|
||||||
memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
header.frame_ctl = cpu_to_le16(fc);
|
|
||||||
|
|
||||||
/* Determine fragmentation size based on destination (multicast
|
|
||||||
* and broadcast are not fragmented)
|
|
||||||
*/
|
|
||||||
if (is_multicast_ether_addr(header.addr1)) {
|
|
||||||
frag_size = MAX_FRAG_THRESHOLD;
|
|
||||||
qos_ctl |= QOS_CTL_NOTCONTAIN_ACK;
|
|
||||||
} else {
|
|
||||||
frag_size = ieee->fts;//default:392
|
|
||||||
qos_ctl = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//if (ieee->current_network.QoS_Enable)
|
|
||||||
if (qos_actived) {
|
|
||||||
hdr_len = IEEE80211_3ADDR_LEN + 2;
|
|
||||||
|
|
||||||
skb->priority = ieee80211_classify(skb, &ieee->current_network);
|
|
||||||
qos_ctl |= skb->priority; //set in the ieee80211_classify
|
|
||||||
header.qos_ctl = cpu_to_le16(qos_ctl & IEEE80211_QOS_TID);
|
|
||||||
} else {
|
|
||||||
hdr_len = IEEE80211_3ADDR_LEN;
|
|
||||||
}
|
|
||||||
/* Determine amount of payload per fragment. Regardless of if
|
|
||||||
* this stack is providing the full 802.11 header, one will
|
|
||||||
* eventually be affixed to this fragment -- so we must account for
|
|
||||||
* it when determining the amount of payload space.
|
|
||||||
*/
|
|
||||||
bytes_per_frag = frag_size - hdr_len;
|
|
||||||
if (ieee->config &
|
|
||||||
(CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
|
|
||||||
bytes_per_frag -= IEEE80211_FCS_LEN;
|
|
||||||
|
|
||||||
/* Each fragment may need to have room for encryption pre/postfix */
|
|
||||||
if (encrypt)
|
|
||||||
bytes_per_frag -= crypt->ops->extra_prefix_len +
|
|
||||||
crypt->ops->extra_postfix_len;
|
|
||||||
|
|
||||||
/* Number of fragments is the total bytes_per_frag /
|
|
||||||
* payload_per_fragment
|
|
||||||
*/
|
|
||||||
nr_frags = bytes / bytes_per_frag;
|
|
||||||
bytes_last_frag = bytes % bytes_per_frag;
|
|
||||||
if (bytes_last_frag)
|
|
||||||
nr_frags++;
|
|
||||||
else
|
|
||||||
bytes_last_frag = bytes_per_frag;
|
|
||||||
|
|
||||||
/* When we allocate the TXB we allocate enough space for the reserve
|
|
||||||
* and full fragment bytes (bytes_per_frag doesn't include prefix,
|
|
||||||
* postfix, header, FCS, etc.)
|
|
||||||
*/
|
|
||||||
txb = ieee80211_alloc_txb(nr_frags, frag_size + ieee->tx_headroom, GFP_ATOMIC);
|
|
||||||
if (unlikely(!txb)) {
|
|
||||||
netdev_warn(ieee->dev, "Could not allocate TXB\n");
|
|
||||||
goto failed;
|
|
||||||
}
|
|
||||||
txb->encrypted = encrypt;
|
|
||||||
txb->payload_size = __cpu_to_le16(bytes);
|
|
||||||
|
|
||||||
//if (ieee->current_network.QoS_Enable)
|
|
||||||
if (qos_actived)
|
|
||||||
txb->queue_index = UP2AC(skb->priority);
|
|
||||||
else
|
|
||||||
txb->queue_index = WME_AC_BK;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for (i = 0; i < nr_frags; i++) {
|
|
||||||
skb_frag = txb->fragments[i];
|
|
||||||
tcb_desc = (struct cb_desc *)(skb_frag->cb + MAX_DEV_ADDR_SIZE);
|
|
||||||
if (qos_actived) {
|
|
||||||
skb_frag->priority = skb->priority;//UP2AC(skb->priority);
|
|
||||||
tcb_desc->queue_index = UP2AC(skb->priority);
|
|
||||||
} else {
|
|
||||||
skb_frag->priority = WME_AC_BK;
|
|
||||||
tcb_desc->queue_index = WME_AC_BK;
|
|
||||||
}
|
|
||||||
skb_reserve(skb_frag, ieee->tx_headroom);
|
|
||||||
|
|
||||||
if (encrypt) {
|
|
||||||
if (ieee->hwsec_active)
|
|
||||||
tcb_desc->bHwSec = 1;
|
|
||||||
else
|
|
||||||
tcb_desc->bHwSec = 0;
|
|
||||||
skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
|
|
||||||
} else {
|
|
||||||
tcb_desc->bHwSec = 0;
|
|
||||||
}
|
|
||||||
frag_hdr = 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_ctl = cpu_to_le16(
|
|
||||||
fc | IEEE80211_FCTL_MOREFRAGS);
|
|
||||||
bytes = bytes_per_frag;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
/* The last fragment takes the remaining length */
|
|
||||||
bytes = bytes_last_frag;
|
|
||||||
}
|
|
||||||
//if(ieee->current_network.QoS_Enable)
|
|
||||||
if (qos_actived) {
|
|
||||||
// add 1 only indicate to corresponding seq number control 2006/7/12
|
|
||||||
frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[UP2AC(skb->priority) + 1] << 4 | i);
|
|
||||||
} else {
|
|
||||||
frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4 | i);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Put a SNAP header on the first fragment */
|
|
||||||
if (i == 0) {
|
|
||||||
ieee80211_put_snap(
|
|
||||||
skb_put(skb_frag, SNAP_SIZE + sizeof(u16)),
|
|
||||||
ether_type);
|
|
||||||
bytes -= SNAP_SIZE + sizeof(u16);
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
|
|
||||||
if (ieee->config &
|
|
||||||
(CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
|
|
||||||
skb_put(skb_frag, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (qos_actived) {
|
|
||||||
if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF)
|
|
||||||
ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0;
|
|
||||||
else
|
|
||||||
ieee->seq_ctrl[UP2AC(skb->priority) + 1]++;
|
|
||||||
} else {
|
|
||||||
if (ieee->seq_ctrl[0] == 0xFFF)
|
|
||||||
ieee->seq_ctrl[0] = 0;
|
|
||||||
else
|
|
||||||
ieee->seq_ctrl[0]++;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (unlikely(skb->len < sizeof(struct rtl_80211_hdr_3addr))) {
|
|
||||||
netdev_warn(ieee->dev, "skb too small (%d).\n",
|
|
||||||
skb->len);
|
|
||||||
goto success;
|
|
||||||
}
|
|
||||||
|
|
||||||
txb = ieee80211_alloc_txb(1, skb->len, GFP_ATOMIC);
|
|
||||||
if (!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);
|
|
||||||
}
|
|
||||||
|
|
||||||
success:
|
|
||||||
//WB add to fill data tcb_desc here. only first fragment is considered, need to change, and you may remove to other place.
|
|
||||||
if (txb) {
|
|
||||||
tcb_desc = (struct cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
|
|
||||||
tcb_desc->bTxEnableFwCalcDur = 1;
|
|
||||||
if (is_multicast_ether_addr(header.addr1))
|
|
||||||
tcb_desc->bMulticast = 1;
|
|
||||||
if (is_broadcast_ether_addr(header.addr1))
|
|
||||||
tcb_desc->bBroadcast = 1;
|
|
||||||
ieee80211_txrate_selectmode(ieee, tcb_desc);
|
|
||||||
if (tcb_desc->bMulticast || tcb_desc->bBroadcast)
|
|
||||||
tcb_desc->data_rate = ieee->basic_rate;
|
|
||||||
else
|
|
||||||
tcb_desc->data_rate = CURRENT_RATE(ieee->mode, ieee->rate, ieee->HTCurrentOperaRate);
|
|
||||||
ieee80211_qurey_ShortPreambleMode(ieee, tcb_desc);
|
|
||||||
ieee80211_tx_query_agg_cap(ieee, txb->fragments[0], tcb_desc);
|
|
||||||
ieee80211_query_HTCapShortGI(ieee, tcb_desc);
|
|
||||||
ieee80211_query_BandwidthMode(ieee, tcb_desc);
|
|
||||||
ieee80211_query_protectionmode(ieee, tcb_desc, txb->fragments[0]);
|
|
||||||
ieee80211_query_seqnum(ieee, txb->fragments[0], header.addr1);
|
|
||||||
}
|
|
||||||
spin_unlock_irqrestore(&ieee->lock, flags);
|
|
||||||
dev_kfree_skb_any(skb);
|
|
||||||
if (txb) {
|
|
||||||
if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE) {
|
|
||||||
ieee80211_softmac_xmit(txb, ieee);
|
|
||||||
} else {
|
|
||||||
if ((*ieee->hard_start_xmit)(txb, dev) == 0) {
|
|
||||||
stats->tx_packets++;
|
|
||||||
stats->tx_bytes += __le16_to_cpu(txb->payload_size);
|
|
||||||
return NETDEV_TX_OK;
|
|
||||||
}
|
|
||||||
ieee80211_txb_free(txb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NETDEV_TX_OK;
|
|
||||||
|
|
||||||
failed:
|
|
||||||
spin_unlock_irqrestore(&ieee->lock, flags);
|
|
||||||
netif_stop_queue(dev);
|
|
||||||
stats->tx_errors++;
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
}
|
|
@ -1,810 +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/slab.h>
|
|
||||||
#include <linux/module.h>
|
|
||||||
|
|
||||||
#include "ieee80211.h"
|
|
||||||
struct modes_unit {
|
|
||||||
char *mode_string;
|
|
||||||
int mode_size;
|
|
||||||
};
|
|
||||||
static struct modes_unit ieee80211_modes[] = {
|
|
||||||
{"a", 1},
|
|
||||||
{"b", 1},
|
|
||||||
{"g", 1},
|
|
||||||
{"?", 1},
|
|
||||||
{"N-24G", 5},
|
|
||||||
{"N-5G", 4},
|
|
||||||
};
|
|
||||||
|
|
||||||
#define iwe_stream_add_event_rsl iwe_stream_add_event
|
|
||||||
|
|
||||||
#define MAX_CUSTOM_LEN 64
|
|
||||||
static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
|
|
||||||
char *start, char *stop,
|
|
||||||
struct ieee80211_network *network,
|
|
||||||
struct iw_request_info *info)
|
|
||||||
{
|
|
||||||
char custom[MAX_CUSTOM_LEN];
|
|
||||||
char proto_name[IFNAMSIZ];
|
|
||||||
char *pname = proto_name;
|
|
||||||
char *p;
|
|
||||||
struct iw_event iwe;
|
|
||||||
int i, j;
|
|
||||||
u16 max_rate, rate;
|
|
||||||
static u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33};
|
|
||||||
|
|
||||||
/* First entry *MUST* be the AP MAC address */
|
|
||||||
iwe.cmd = SIOCGIWAP;
|
|
||||||
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
|
|
||||||
memcpy(iwe.u.ap_addr.sa_data, network->bssid, ETH_ALEN);
|
|
||||||
start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_ADDR_LEN);
|
|
||||||
/* Remaining entries will be displayed in the order we provide them */
|
|
||||||
|
|
||||||
/* Add the ESSID */
|
|
||||||
iwe.cmd = SIOCGIWESSID;
|
|
||||||
iwe.u.data.flags = 1;
|
|
||||||
// if (network->flags & NETWORK_EMPTY_ESSID) {
|
|
||||||
if (network->ssid_len == 0) {
|
|
||||||
iwe.u.data.length = sizeof("<hidden>");
|
|
||||||
start = iwe_stream_add_point(info, start, stop, &iwe, "<hidden>");
|
|
||||||
} else {
|
|
||||||
iwe.u.data.length = min(network->ssid_len, (u8)32);
|
|
||||||
start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
|
|
||||||
}
|
|
||||||
/* Add the protocol name */
|
|
||||||
iwe.cmd = SIOCGIWNAME;
|
|
||||||
for (i = 0; i < ARRAY_SIZE(ieee80211_modes); i++) {
|
|
||||||
if (network->mode & BIT(i)) {
|
|
||||||
sprintf(pname, ieee80211_modes[i].mode_string, ieee80211_modes[i].mode_size);
|
|
||||||
pname += ieee80211_modes[i].mode_size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*pname = '\0';
|
|
||||||
snprintf(iwe.u.name, IFNAMSIZ, "IEEE802.11%s", proto_name);
|
|
||||||
start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_CHAR_LEN);
|
|
||||||
/* Add mode */
|
|
||||||
iwe.cmd = SIOCGIWMODE;
|
|
||||||
if (network->capability &
|
|
||||||
(WLAN_CAPABILITY_BSS | WLAN_CAPABILITY_IBSS)) {
|
|
||||||
if (network->capability & WLAN_CAPABILITY_BSS)
|
|
||||||
iwe.u.mode = IW_MODE_MASTER;
|
|
||||||
else
|
|
||||||
iwe.u.mode = IW_MODE_ADHOC;
|
|
||||||
start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_UINT_LEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add frequency/channel */
|
|
||||||
iwe.cmd = SIOCGIWFREQ;
|
|
||||||
/* iwe.u.freq.m = ieee80211_frequency(network->channel, network->mode);
|
|
||||||
iwe.u.freq.e = 3; */
|
|
||||||
iwe.u.freq.m = network->channel;
|
|
||||||
iwe.u.freq.e = 0;
|
|
||||||
iwe.u.freq.i = 0;
|
|
||||||
start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_FREQ_LEN);
|
|
||||||
/* Add encryption capability */
|
|
||||||
iwe.cmd = SIOCGIWENCODE;
|
|
||||||
if (network->capability & WLAN_CAPABILITY_PRIVACY)
|
|
||||||
iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
|
|
||||||
else
|
|
||||||
iwe.u.data.flags = IW_ENCODE_DISABLED;
|
|
||||||
iwe.u.data.length = 0;
|
|
||||||
start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
|
|
||||||
/* Add basic and extended rates */
|
|
||||||
max_rate = 0;
|
|
||||||
p = custom;
|
|
||||||
p += 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 >= IEEE_N_24G) /* add N rate here */ {
|
|
||||||
struct ht_capability_ele *ht_cap = NULL;
|
|
||||||
bool is40M = false, isShortGI = false;
|
|
||||||
u8 max_mcs = 0;
|
|
||||||
if (!memcmp(network->bssht.bdHTCapBuf, EWC11NHTCap, 4))
|
|
||||||
ht_cap = (struct ht_capability_ele *)&network->bssht.bdHTCapBuf[4];
|
|
||||||
else
|
|
||||||
ht_cap = (struct ht_capability_ele *)&network->bssht.bdHTCapBuf[0];
|
|
||||||
is40M = (ht_cap->ChlWidth) ? 1 : 0;
|
|
||||||
isShortGI = (ht_cap->ChlWidth) ?
|
|
||||||
((ht_cap->ShortGI40Mhz) ? 1 : 0) :
|
|
||||||
((ht_cap->ShortGI20Mhz) ? 1 : 0);
|
|
||||||
|
|
||||||
max_mcs = HTGetHighestMCSRate(ieee, ht_cap->MCS, MCS_FILTER_ALL);
|
|
||||||
rate = MCS_DATA_RATE[is40M][isShortGI][max_mcs & 0x7f];
|
|
||||||
if (rate > max_rate)
|
|
||||||
max_rate = rate;
|
|
||||||
}
|
|
||||||
iwe.cmd = SIOCGIWRATE;
|
|
||||||
iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
|
|
||||||
iwe.u.bitrate.value = max_rate * 500000;
|
|
||||||
start = iwe_stream_add_event_rsl(info, start, stop, &iwe,
|
|
||||||
IW_EV_PARAM_LEN);
|
|
||||||
iwe.cmd = IWEVCUSTOM;
|
|
||||||
iwe.u.data.length = p - custom;
|
|
||||||
if (iwe.u.data.length)
|
|
||||||
start = iwe_stream_add_point(info, start, stop, &iwe, custom);
|
|
||||||
/* Add quality statistics */
|
|
||||||
/* TODO: Fix these values... */
|
|
||||||
iwe.cmd = IWEVQUAL;
|
|
||||||
iwe.u.qual.qual = network->stats.signal;
|
|
||||||
iwe.u.qual.level = network->stats.rssi;
|
|
||||||
iwe.u.qual.noise = network->stats.noise;
|
|
||||||
iwe.u.qual.updated = network->stats.mask & IEEE80211_STATMASK_WEMASK;
|
|
||||||
if (!(network->stats.mask & IEEE80211_STATMASK_RSSI))
|
|
||||||
iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID;
|
|
||||||
if (!(network->stats.mask & IEEE80211_STATMASK_NOISE))
|
|
||||||
iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID;
|
|
||||||
if (!(network->stats.mask & IEEE80211_STATMASK_SIGNAL))
|
|
||||||
iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID;
|
|
||||||
iwe.u.qual.updated = 7;
|
|
||||||
start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_QUAL_LEN);
|
|
||||||
iwe.cmd = IWEVCUSTOM;
|
|
||||||
p = custom;
|
|
||||||
|
|
||||||
iwe.u.data.length = p - custom;
|
|
||||||
if (iwe.u.data.length)
|
|
||||||
start = iwe_stream_add_point(info, start, stop, &iwe, custom);
|
|
||||||
|
|
||||||
if (ieee->wpa_enabled && network->wpa_ie_len) {
|
|
||||||
char buf[MAX_WPA_IE_LEN * 2 + 30];
|
|
||||||
// printk("WPA IE\n");
|
|
||||||
u8 *p = buf;
|
|
||||||
p += sprintf(p, "wpa_ie=");
|
|
||||||
for (i = 0; i < network->wpa_ie_len; i++)
|
|
||||||
p += sprintf(p, "%02x", network->wpa_ie[i]);
|
|
||||||
|
|
||||||
memset(&iwe, 0, sizeof(iwe));
|
|
||||||
iwe.cmd = IWEVCUSTOM;
|
|
||||||
iwe.u.data.length = strlen(buf);
|
|
||||||
start = iwe_stream_add_point(info, start, stop, &iwe, buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ieee->wpa_enabled && network->rsn_ie_len) {
|
|
||||||
char buf[MAX_WPA_IE_LEN * 2 + 30];
|
|
||||||
|
|
||||||
u8 *p = buf;
|
|
||||||
p += sprintf(p, "rsn_ie=");
|
|
||||||
for (i = 0; i < network->rsn_ie_len; i++)
|
|
||||||
p += sprintf(p, "%02x", network->rsn_ie[i]);
|
|
||||||
|
|
||||||
memset(&iwe, 0, sizeof(iwe));
|
|
||||||
iwe.cmd = IWEVCUSTOM;
|
|
||||||
iwe.u.data.length = strlen(buf);
|
|
||||||
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", (jiffies - network->last_scanned) / (HZ / 100));
|
|
||||||
iwe.u.data.length = p - custom;
|
|
||||||
if (iwe.u.data.length)
|
|
||||||
start = iwe_stream_add_point(info, start, stop, &iwe, custom);
|
|
||||||
|
|
||||||
return start;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *extra)
|
|
||||||
{
|
|
||||||
struct ieee80211_network *network;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
char *ev = extra;
|
|
||||||
// char *stop = ev + IW_SCAN_MAX_DATA;
|
|
||||||
char *stop = ev + wrqu->data.length;//IW_SCAN_MAX_DATA;
|
|
||||||
//char *stop = ev + IW_SCAN_MAX_DATA;
|
|
||||||
int i = 0;
|
|
||||||
int err = 0;
|
|
||||||
IEEE80211_DEBUG_WX("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
|
|
||||||
IEEE80211_DEBUG_SCAN(
|
|
||||||
"Not showing network '%s ("
|
|
||||||
"%pM)' due to age (%lums).\n",
|
|
||||||
escape_essid(network->ssid,
|
|
||||||
network->ssid_len),
|
|
||||||
network->bssid,
|
|
||||||
(jiffies - network->last_scanned) / (HZ / 100));
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&ieee->lock, flags);
|
|
||||||
mutex_unlock(&ieee->wx_mutex);
|
|
||||||
wrqu->data.length = ev - extra;
|
|
||||||
wrqu->data.flags = 0;
|
|
||||||
|
|
||||||
IEEE80211_DEBUG_WX("exit: %d networks returned.\n", i);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(ieee80211_wx_get_scan);
|
|
||||||
|
|
||||||
int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *keybuf)
|
|
||||||
{
|
|
||||||
struct iw_point *erq = &(wrqu->encoding);
|
|
||||||
struct net_device *dev = ieee->dev;
|
|
||||||
struct ieee80211_security sec = {
|
|
||||||
.flags = 0
|
|
||||||
};
|
|
||||||
int i, key, key_provided, len;
|
|
||||||
struct ieee80211_crypt_data **crypt;
|
|
||||||
|
|
||||||
IEEE80211_DEBUG_WX("SET_ENCODE\n");
|
|
||||||
|
|
||||||
key = erq->flags & IW_ENCODE_INDEX;
|
|
||||||
if (key) {
|
|
||||||
if (key > WEP_KEYS)
|
|
||||||
return -EINVAL;
|
|
||||||
key--;
|
|
||||||
key_provided = 1;
|
|
||||||
} else {
|
|
||||||
key_provided = 0;
|
|
||||||
key = ieee->tx_keyidx;
|
|
||||||
}
|
|
||||||
|
|
||||||
IEEE80211_DEBUG_WX("Key: %d [%s]\n", key, key_provided ?
|
|
||||||
"provided" : "default");
|
|
||||||
crypt = &ieee->crypt[key];
|
|
||||||
|
|
||||||
if (erq->flags & IW_ENCODE_DISABLED) {
|
|
||||||
if (key_provided && *crypt) {
|
|
||||||
IEEE80211_DEBUG_WX("Disabling encryption on key %d.\n",
|
|
||||||
key);
|
|
||||||
ieee80211_crypt_delayed_deinit(ieee, crypt);
|
|
||||||
} else
|
|
||||||
IEEE80211_DEBUG_WX("Disabling encryption.\n");
|
|
||||||
|
|
||||||
/* Check all the keys to see if any are still configured,
|
|
||||||
* and if no key index was provided, de-init them all */
|
|
||||||
for (i = 0; i < WEP_KEYS; i++) {
|
|
||||||
if (ieee->crypt[i]) {
|
|
||||||
if (key_provided)
|
|
||||||
break;
|
|
||||||
ieee80211_crypt_delayed_deinit(
|
|
||||||
ieee, &ieee->crypt[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i == WEP_KEYS) {
|
|
||||||
sec.enabled = 0;
|
|
||||||
sec.level = SEC_LEVEL_0;
|
|
||||||
sec.flags |= SEC_ENABLED | SEC_LEVEL;
|
|
||||||
}
|
|
||||||
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
sec.enabled = 1;
|
|
||||||
sec.flags |= SEC_ENABLED;
|
|
||||||
|
|
||||||
if (*crypt && (*crypt)->ops &&
|
|
||||||
strcmp((*crypt)->ops->name, "WEP") != 0) {
|
|
||||||
/* changing to use WEP; deinit previously used algorithm
|
|
||||||
* on this key */
|
|
||||||
ieee80211_crypt_delayed_deinit(ieee, crypt);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!*crypt) {
|
|
||||||
struct ieee80211_crypt_data *new_crypt;
|
|
||||||
|
|
||||||
/* take WEP into use */
|
|
||||||
new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data),
|
|
||||||
GFP_KERNEL);
|
|
||||||
if (!new_crypt)
|
|
||||||
return -ENOMEM;
|
|
||||||
new_crypt->ops = try_then_request_module(ieee80211_get_crypto_ops("WEP"),
|
|
||||||
"ieee80211_crypt_wep");
|
|
||||||
if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
|
|
||||||
new_crypt->priv = new_crypt->ops->init(key);
|
|
||||||
|
|
||||||
if (!new_crypt->ops || !new_crypt->priv) {
|
|
||||||
kfree(new_crypt);
|
|
||||||
new_crypt = NULL;
|
|
||||||
|
|
||||||
netdev_warn(dev, "could not initialize WEP: "
|
|
||||||
"load module ieee80211_crypt_wep\n");
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
}
|
|
||||||
*crypt = new_crypt;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If a new key was provided, set it up */
|
|
||||||
if (erq->length > 0) {
|
|
||||||
len = erq->length <= 5 ? 5 : 13;
|
|
||||||
memcpy(sec.keys[key], keybuf, erq->length);
|
|
||||||
if (len > erq->length)
|
|
||||||
memset(sec.keys[key] + erq->length, 0,
|
|
||||||
len - erq->length);
|
|
||||||
IEEE80211_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n",
|
|
||||||
key, escape_essid(sec.keys[key], len),
|
|
||||||
erq->length, len);
|
|
||||||
sec.key_sizes[key] = len;
|
|
||||||
(*crypt)->ops->set_key(sec.keys[key], len, NULL,
|
|
||||||
(*crypt)->priv);
|
|
||||||
sec.flags |= BIT(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->tx_keyidx = key;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,
|
|
||||||
NULL, (*crypt)->priv);
|
|
||||||
if (len == 0) {
|
|
||||||
/* Set a default key of all 0 */
|
|
||||||
printk("Setting key %d to all zero.\n",
|
|
||||||
key);
|
|
||||||
|
|
||||||
IEEE80211_DEBUG_WX("Setting key %d to all zero.\n",
|
|
||||||
key);
|
|
||||||
memset(sec.keys[key], 0, 13);
|
|
||||||
(*crypt)->ops->set_key(sec.keys[key], 13, NULL,
|
|
||||||
(*crypt)->priv);
|
|
||||||
sec.key_sizes[key] = 13;
|
|
||||||
sec.flags |= BIT(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* No key data - just set the default TX key index */
|
|
||||||
if (key_provided) {
|
|
||||||
IEEE80211_DEBUG_WX(
|
|
||||||
"Setting key %d to default Tx key.\n", key);
|
|
||||||
ieee->tx_keyidx = key;
|
|
||||||
sec.active_key = key;
|
|
||||||
sec.flags |= SEC_ACTIVE_KEY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
done:
|
|
||||||
ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
|
|
||||||
ieee->auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
|
|
||||||
sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
|
|
||||||
sec.flags |= SEC_AUTH_MODE;
|
|
||||||
IEEE80211_DEBUG_WX("Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ?
|
|
||||||
"OPEN" : "SHARED KEY");
|
|
||||||
|
|
||||||
/* For now we just support WEP, so only set that security level...
|
|
||||||
* TODO: When WPA is added this is one place that needs to change */
|
|
||||||
sec.flags |= SEC_LEVEL;
|
|
||||||
sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */
|
|
||||||
|
|
||||||
if (ieee->set_security)
|
|
||||||
ieee->set_security(dev, &sec);
|
|
||||||
|
|
||||||
/* Do not reset port if card is in Managed mode since resetting will
|
|
||||||
* generate new IEEE 802.11 authentication which may end up in looping
|
|
||||||
* with IEEE 802.1X. If your hardware requires a reset after WEP
|
|
||||||
* configuration (for example... Prism2), implement the reset_port in
|
|
||||||
* the callbacks structures used to initialize the 802.11 stack. */
|
|
||||||
if (ieee->reset_on_keychange &&
|
|
||||||
ieee->iw_mode != IW_MODE_INFRA &&
|
|
||||||
ieee->reset_port && ieee->reset_port(dev)) {
|
|
||||||
netdev_dbg(ieee->dev, "reset_port failed\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(ieee80211_wx_set_encode);
|
|
||||||
|
|
||||||
int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *keybuf)
|
|
||||||
{
|
|
||||||
struct iw_point *erq = &(wrqu->encoding);
|
|
||||||
int len, key;
|
|
||||||
struct ieee80211_crypt_data *crypt;
|
|
||||||
|
|
||||||
IEEE80211_DEBUG_WX("GET_ENCODE\n");
|
|
||||||
|
|
||||||
if (ieee->iw_mode == IW_MODE_MONITOR)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
key = erq->flags & IW_ENCODE_INDEX;
|
|
||||||
if (key) {
|
|
||||||
if (key > WEP_KEYS)
|
|
||||||
return -EINVAL;
|
|
||||||
key--;
|
|
||||||
} else
|
|
||||||
key = ieee->tx_keyidx;
|
|
||||||
|
|
||||||
crypt = ieee->crypt[key];
|
|
||||||
erq->flags = key + 1;
|
|
||||||
|
|
||||||
if (!crypt || !crypt->ops) {
|
|
||||||
erq->length = 0;
|
|
||||||
erq->flags |= IW_ENCODE_DISABLED;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
len = crypt->ops->get_key(keybuf, SCM_KEY_LEN, NULL, crypt->priv);
|
|
||||||
if (len < 0)
|
|
||||||
len = 0;
|
|
||||||
erq->length = len;
|
|
||||||
|
|
||||||
erq->flags |= IW_ENCODE_ENABLED;
|
|
||||||
|
|
||||||
if (ieee->open_wep)
|
|
||||||
erq->flags |= IW_ENCODE_OPEN;
|
|
||||||
else
|
|
||||||
erq->flags |= IW_ENCODE_RESTRICTED;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(ieee80211_wx_get_encode);
|
|
||||||
|
|
||||||
int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *extra)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
struct net_device *dev = ieee->dev;
|
|
||||||
struct iw_point *encoding = &wrqu->encoding;
|
|
||||||
struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
|
|
||||||
int i, idx;
|
|
||||||
int group_key = 0;
|
|
||||||
const char *alg, *module;
|
|
||||||
struct ieee80211_crypto_ops *ops;
|
|
||||||
struct ieee80211_crypt_data **crypt;
|
|
||||||
|
|
||||||
struct ieee80211_security sec = {
|
|
||||||
.flags = 0,
|
|
||||||
};
|
|
||||||
idx = encoding->flags & IW_ENCODE_INDEX;
|
|
||||||
if (idx) {
|
|
||||||
if (idx < 1 || idx > WEP_KEYS)
|
|
||||||
return -EINVAL;
|
|
||||||
idx--;
|
|
||||||
} else
|
|
||||||
idx = ieee->tx_keyidx;
|
|
||||||
|
|
||||||
if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
|
|
||||||
|
|
||||||
crypt = &ieee->crypt[idx];
|
|
||||||
|
|
||||||
group_key = 1;
|
|
||||||
} else {
|
|
||||||
/* some Cisco APs use idx>0 for unicast in dynamic WEP */
|
|
||||||
if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
|
|
||||||
return -EINVAL;
|
|
||||||
if (ieee->iw_mode == IW_MODE_INFRA)
|
|
||||||
|
|
||||||
crypt = &ieee->crypt[idx];
|
|
||||||
|
|
||||||
else
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
sec.flags |= SEC_ENABLED;// | SEC_ENCRYPT;
|
|
||||||
if ((encoding->flags & IW_ENCODE_DISABLED) ||
|
|
||||||
ext->alg == IW_ENCODE_ALG_NONE) {
|
|
||||||
if (*crypt)
|
|
||||||
ieee80211_crypt_delayed_deinit(ieee, crypt);
|
|
||||||
|
|
||||||
for (i = 0; i < WEP_KEYS; i++)
|
|
||||||
|
|
||||||
if (ieee->crypt[i])
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (i == WEP_KEYS) {
|
|
||||||
sec.enabled = 0;
|
|
||||||
// sec.encrypt = 0;
|
|
||||||
sec.level = SEC_LEVEL_0;
|
|
||||||
sec.flags |= SEC_LEVEL;
|
|
||||||
}
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
sec.enabled = 1;
|
|
||||||
// sec.encrypt = 1;
|
|
||||||
switch (ext->alg) {
|
|
||||||
case IW_ENCODE_ALG_WEP:
|
|
||||||
alg = "WEP";
|
|
||||||
module = "ieee80211_crypt_wep";
|
|
||||||
break;
|
|
||||||
case IW_ENCODE_ALG_TKIP:
|
|
||||||
alg = "TKIP";
|
|
||||||
module = "ieee80211_crypt_tkip";
|
|
||||||
break;
|
|
||||||
case IW_ENCODE_ALG_CCMP:
|
|
||||||
alg = "CCMP";
|
|
||||||
module = "ieee80211_crypt_ccmp";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
|
|
||||||
dev->name, ext->alg);
|
|
||||||
ret = -EINVAL;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
printk("alg name:%s\n", alg);
|
|
||||||
|
|
||||||
ops = try_then_request_module(ieee80211_get_crypto_ops(alg), module);
|
|
||||||
if (!ops) {
|
|
||||||
IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
|
|
||||||
dev->name, ext->alg);
|
|
||||||
printk("========>unknown crypto alg %d\n", ext->alg);
|
|
||||||
ret = -EINVAL;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!*crypt || (*crypt)->ops != ops) {
|
|
||||||
struct ieee80211_crypt_data *new_crypt;
|
|
||||||
|
|
||||||
ieee80211_crypt_delayed_deinit(ieee, crypt);
|
|
||||||
|
|
||||||
new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
|
|
||||||
if (!new_crypt) {
|
|
||||||
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) {
|
|
||||||
IEEE80211_DEBUG_WX("%s: key setting failed\n", dev->name);
|
|
||||||
printk("key setting failed\n");
|
|
||||||
ret = -EINVAL;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
//skip_host_crypt:
|
|
||||||
if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
|
|
||||||
ieee->tx_keyidx = idx;
|
|
||||||
sec.active_key = idx;
|
|
||||||
sec.flags |= SEC_ACTIVE_KEY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ext->alg != IW_ENCODE_ALG_NONE) {
|
|
||||||
//memcpy(sec.keys[idx], ext->key, ext->key_len);
|
|
||||||
sec.key_sizes[idx] = ext->key_len;
|
|
||||||
sec.flags |= BIT(idx);
|
|
||||||
if (ext->alg == IW_ENCODE_ALG_WEP) {
|
|
||||||
// sec.encode_alg[idx] = SEC_ALG_WEP;
|
|
||||||
sec.flags |= SEC_LEVEL;
|
|
||||||
sec.level = SEC_LEVEL_1;
|
|
||||||
} else if (ext->alg == IW_ENCODE_ALG_TKIP) {
|
|
||||||
// sec.encode_alg[idx] = SEC_ALG_TKIP;
|
|
||||||
sec.flags |= SEC_LEVEL;
|
|
||||||
sec.level = SEC_LEVEL_2;
|
|
||||||
} else if (ext->alg == IW_ENCODE_ALG_CCMP) {
|
|
||||||
// sec.encode_alg[idx] = SEC_ALG_CCMP;
|
|
||||||
sec.flags |= SEC_LEVEL;
|
|
||||||
sec.level = SEC_LEVEL_3;
|
|
||||||
}
|
|
||||||
/* Don't set sec level for group keys. */
|
|
||||||
if (group_key)
|
|
||||||
sec.flags &= ~SEC_LEVEL;
|
|
||||||
}
|
|
||||||
done:
|
|
||||||
if (ieee->set_security)
|
|
||||||
ieee->set_security(ieee->dev, &sec);
|
|
||||||
|
|
||||||
if (ieee->reset_on_keychange &&
|
|
||||||
ieee->iw_mode != IW_MODE_INFRA &&
|
|
||||||
ieee->reset_port && ieee->reset_port(dev)) {
|
|
||||||
IEEE80211_DEBUG_WX("%s: reset_port failed\n", dev->name);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(ieee80211_wx_set_encode_ext);
|
|
||||||
|
|
||||||
int ieee80211_wx_get_encode_ext(struct ieee80211_device *ieee,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *extra)
|
|
||||||
{
|
|
||||||
struct iw_point *encoding = &wrqu->encoding;
|
|
||||||
struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
|
|
||||||
struct ieee80211_crypt_data *crypt;
|
|
||||||
int idx, max_key_len;
|
|
||||||
|
|
||||||
max_key_len = encoding->length - sizeof(*ext);
|
|
||||||
if (max_key_len < 0)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
idx = encoding->flags & IW_ENCODE_INDEX;
|
|
||||||
if (idx) {
|
|
||||||
if (idx < 1 || idx > WEP_KEYS)
|
|
||||||
return -EINVAL;
|
|
||||||
idx--;
|
|
||||||
} else
|
|
||||||
idx = ieee->tx_keyidx;
|
|
||||||
|
|
||||||
if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) &&
|
|
||||||
ext->alg != IW_ENCODE_ALG_WEP)
|
|
||||||
if (idx != 0 || ieee->iw_mode != IW_MODE_INFRA)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
crypt = ieee->crypt[idx];
|
|
||||||
encoding->flags = idx + 1;
|
|
||||||
memset(ext, 0, sizeof(*ext));
|
|
||||||
|
|
||||||
if (!crypt || !crypt->ops) {
|
|
||||||
ext->alg = IW_ENCODE_ALG_NONE;
|
|
||||||
ext->key_len = 0;
|
|
||||||
encoding->flags |= IW_ENCODE_DISABLED;
|
|
||||||
} else {
|
|
||||||
if (strcmp(crypt->ops->name, "WEP") == 0)
|
|
||||||
ext->alg = IW_ENCODE_ALG_WEP;
|
|
||||||
else if (strcmp(crypt->ops->name, "TKIP") == 0)
|
|
||||||
ext->alg = IW_ENCODE_ALG_TKIP;
|
|
||||||
else if (strcmp(crypt->ops->name, "CCMP") == 0)
|
|
||||||
ext->alg = IW_ENCODE_ALG_CCMP;
|
|
||||||
else
|
|
||||||
return -EINVAL;
|
|
||||||
ext->key_len = crypt->ops->get_key(ext->key, SCM_KEY_LEN, NULL, crypt->priv);
|
|
||||||
encoding->flags |= IW_ENCODE_ENABLED;
|
|
||||||
if (ext->key_len &&
|
|
||||||
(ext->alg == IW_ENCODE_ALG_TKIP ||
|
|
||||||
ext->alg == IW_ENCODE_ALG_CCMP))
|
|
||||||
ext->ext_flags |= IW_ENCODE_EXT_TX_SEQ_VALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(ieee80211_wx_get_encode_ext);
|
|
||||||
|
|
||||||
int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *extra)
|
|
||||||
{
|
|
||||||
struct iw_mlme *mlme = (struct iw_mlme *)extra;
|
|
||||||
switch (mlme->cmd) {
|
|
||||||
case IW_MLME_DEAUTH:
|
|
||||||
case IW_MLME_DISASSOC:
|
|
||||||
ieee80211_disassociate(ieee);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(ieee80211_wx_set_mlme);
|
|
||||||
|
|
||||||
int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
struct iw_param *data, char *extra)
|
|
||||||
{
|
|
||||||
switch (data->flags & IW_AUTH_INDEX) {
|
|
||||||
case IW_AUTH_WPA_VERSION:
|
|
||||||
/*need to support wpa2 here*/
|
|
||||||
break;
|
|
||||||
case IW_AUTH_CIPHER_PAIRWISE:
|
|
||||||
case IW_AUTH_CIPHER_GROUP:
|
|
||||||
case IW_AUTH_KEY_MGMT:
|
|
||||||
/*
|
|
||||||
* * Host AP driver does not use these parameters and allows
|
|
||||||
* * wpa_supplicant to control them internally.
|
|
||||||
* */
|
|
||||||
break;
|
|
||||||
case IW_AUTH_TKIP_COUNTERMEASURES:
|
|
||||||
ieee->tkip_countermeasures = data->value;
|
|
||||||
break;
|
|
||||||
case IW_AUTH_DROP_UNENCRYPTED:
|
|
||||||
ieee->drop_unencrypted = data->value;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IW_AUTH_80211_AUTH_ALG:
|
|
||||||
//printk("======>%s():data->value is %d\n",__func__,data->value);
|
|
||||||
// ieee->open_wep = (data->value&IW_AUTH_ALG_OPEN_SYSTEM)?1:0;
|
|
||||||
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(ieee80211_wx_set_auth);
|
|
||||||
|
|
||||||
int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len)
|
|
||||||
{
|
|
||||||
u8 *buf;
|
|
||||||
|
|
||||||
if (len > MAX_WPA_IE_LEN || (len && !ie)) {
|
|
||||||
//printk("return error out, len:%d\n", len);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (len) {
|
|
||||||
if (len != ie[1] + 2) {
|
|
||||||
printk("len:%zu, ie:%d\n", len, ie[1]);
|
|
||||||
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(ieee80211_wx_set_gen_ie);
|
|
@ -1,54 +0,0 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
#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 {
|
|
||||||
u16 short_data;
|
|
||||||
struct {
|
|
||||||
u16 amsdu_support:1;
|
|
||||||
u16 ba_policy:1;
|
|
||||||
u16 tid:4;
|
|
||||||
u16 buffer_size:10;
|
|
||||||
} field;
|
|
||||||
};
|
|
||||||
|
|
||||||
union delba_param_set {
|
|
||||||
u16 short_data;
|
|
||||||
struct {
|
|
||||||
u16 reserved:11;
|
|
||||||
u16 initiator:1;
|
|
||||||
u16 tid:4;
|
|
||||||
} field;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ba_record {
|
|
||||||
struct timer_list timer;
|
|
||||||
u8 valid;
|
|
||||||
u8 dialog_token;
|
|
||||||
union ba_param_set param_set;
|
|
||||||
u16 timeout_value;
|
|
||||||
union sequence_control start_seq_ctrl;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif //end _BATYPE_H_
|
|
@ -1,700 +0,0 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0
|
|
||||||
/********************************************************************************************************************************
|
|
||||||
* This file is created to process BA Action Frame. According to 802.11 spec, there are 3 BA action types at all. And as BA is
|
|
||||||
* related to TS, this part need some structure defined in QOS side code. Also TX RX is going to be resturctured, so how to send
|
|
||||||
* ADDBAREQ ADDBARSP and DELBA packet is still on consideration. Temporarily use MANAGE QUEUE instead of Normal Queue.
|
|
||||||
* WB 2008-05-27
|
|
||||||
* *****************************************************************************************************************************/
|
|
||||||
#include <asm/byteorder.h>
|
|
||||||
#include <asm/unaligned.h>
|
|
||||||
#include "ieee80211.h"
|
|
||||||
#include "rtl819x_BA.h"
|
|
||||||
|
|
||||||
/********************************************************************************************************************
|
|
||||||
*function: Activate BA entry. And if Time is nozero, start timer.
|
|
||||||
* input: struct ba_record *pBA //BA entry to be enabled
|
|
||||||
* u16 Time //indicate time delay.
|
|
||||||
* output: none
|
|
||||||
********************************************************************************************************************/
|
|
||||||
static void ActivateBAEntry(struct ieee80211_device *ieee, struct ba_record *pBA, u16 Time)
|
|
||||||
{
|
|
||||||
pBA->valid = true;
|
|
||||||
if (Time != 0)
|
|
||||||
mod_timer(&pBA->timer, jiffies + msecs_to_jiffies(Time));
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************************************************************
|
|
||||||
*function: deactivate BA entry, including its timer.
|
|
||||||
* input: struct ba_record *pBA //BA entry to be disabled
|
|
||||||
* output: none
|
|
||||||
********************************************************************************************************************/
|
|
||||||
static void DeActivateBAEntry(struct ieee80211_device *ieee, struct ba_record *pBA)
|
|
||||||
{
|
|
||||||
pBA->valid = false;
|
|
||||||
del_timer_sync(&pBA->timer);
|
|
||||||
}
|
|
||||||
/********************************************************************************************************************
|
|
||||||
*function: deactivete BA entry in Tx Ts, and send DELBA.
|
|
||||||
* input:
|
|
||||||
* struct tx_ts_record *pTxTs //Tx Ts which is to deactivate BA entry.
|
|
||||||
* output: none
|
|
||||||
* notice: As struct tx_ts_record * structure will be defined in QOS, so wait to be merged. //FIXME
|
|
||||||
********************************************************************************************************************/
|
|
||||||
static u8 TxTsDeleteBA(struct ieee80211_device *ieee, struct tx_ts_record *pTxTs)
|
|
||||||
{
|
|
||||||
struct ba_record *pAdmittedBa = &pTxTs->tx_admitted_ba_record; //These two BA entries must exist in TS structure
|
|
||||||
struct ba_record *pPendingBa = &pTxTs->tx_pending_ba_record;
|
|
||||||
u8 bSendDELBA = false;
|
|
||||||
|
|
||||||
// Delete pending BA
|
|
||||||
if (pPendingBa->valid) {
|
|
||||||
DeActivateBAEntry(ieee, pPendingBa);
|
|
||||||
bSendDELBA = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete admitted BA
|
|
||||||
if (pAdmittedBa->valid) {
|
|
||||||
DeActivateBAEntry(ieee, pAdmittedBa);
|
|
||||||
bSendDELBA = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return bSendDELBA;
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************************************************************
|
|
||||||
*function: deactivete BA entry in Tx Ts, and send DELBA.
|
|
||||||
* input:
|
|
||||||
* struct rx_ts_record *pRxTs //Rx Ts which is to deactivate BA entry.
|
|
||||||
* output: none
|
|
||||||
* notice: As struct rx_ts_record * structure will be defined in QOS, so wait to be merged. //FIXME, same with above
|
|
||||||
********************************************************************************************************************/
|
|
||||||
static u8 RxTsDeleteBA(struct ieee80211_device *ieee, struct rx_ts_record *pRxTs)
|
|
||||||
{
|
|
||||||
struct ba_record *pBa = &pRxTs->rx_admitted_ba_record;
|
|
||||||
u8 bSendDELBA = false;
|
|
||||||
|
|
||||||
if (pBa->valid) {
|
|
||||||
DeActivateBAEntry(ieee, pBa);
|
|
||||||
bSendDELBA = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return bSendDELBA;
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************************************************************
|
|
||||||
*function: reset BA entry
|
|
||||||
* input:
|
|
||||||
* struct ba_record *pBA //entry to be reset
|
|
||||||
* output: none
|
|
||||||
********************************************************************************************************************/
|
|
||||||
void ResetBaEntry(struct ba_record *pBA)
|
|
||||||
{
|
|
||||||
pBA->valid = false;
|
|
||||||
pBA->param_set.short_data = 0;
|
|
||||||
pBA->timeout_value = 0;
|
|
||||||
pBA->dialog_token = 0;
|
|
||||||
pBA->start_seq_ctrl.short_data = 0;
|
|
||||||
}
|
|
||||||
//These functions need porting here or not?
|
|
||||||
/*******************************************************************************************************************************
|
|
||||||
*function: construct ADDBAREQ and ADDBARSP frame here together.
|
|
||||||
* input: u8* Dst //ADDBA frame's destination
|
|
||||||
* struct ba_record *pBA //BA_RECORD entry which stores the necessary information for BA.
|
|
||||||
* u16 StatusCode //status code in RSP and I will use it to indicate whether it's RSP or REQ(will I?)
|
|
||||||
* u8 type //indicate whether it's RSP(ACT_ADDBARSP) ow REQ(ACT_ADDBAREQ)
|
|
||||||
* output: none
|
|
||||||
* return: sk_buff* skb //return constructed skb to xmit
|
|
||||||
*******************************************************************************************************************************/
|
|
||||||
static struct sk_buff *ieee80211_ADDBA(struct ieee80211_device *ieee, u8 *Dst, struct ba_record *pBA, u16 StatusCode, u8 type)
|
|
||||||
{
|
|
||||||
struct sk_buff *skb = NULL;
|
|
||||||
struct rtl_80211_hdr_3addr *BAReq = NULL;
|
|
||||||
u8 *tag = NULL;
|
|
||||||
u16 len = ieee->tx_headroom + 9;
|
|
||||||
//category(1) + action field(1) + Dialog Token(1) + BA Parameter Set(2) + BA Timeout Value(2) + BA Start SeqCtrl(2)(or StatusCode(2))
|
|
||||||
IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:%pM, ieee->dev:%p\n", __func__, type, Dst, ieee->dev);
|
|
||||||
if (pBA == NULL) {
|
|
||||||
IEEE80211_DEBUG(IEEE80211_DL_ERR, "pBA is NULL\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
skb = dev_alloc_skb(len + sizeof(struct rtl_80211_hdr_3addr)); //need to add something others? FIXME
|
|
||||||
if (!skb)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
memset(skb->data, 0, sizeof(struct rtl_80211_hdr_3addr)); //I wonder whether it's necessary. Apparently kernel will not do it when alloc a skb.
|
|
||||||
skb_reserve(skb, ieee->tx_headroom);
|
|
||||||
|
|
||||||
BAReq = skb_put(skb, sizeof(struct rtl_80211_hdr_3addr));
|
|
||||||
|
|
||||||
memcpy(BAReq->addr1, Dst, ETH_ALEN);
|
|
||||||
memcpy(BAReq->addr2, ieee->dev->dev_addr, ETH_ALEN);
|
|
||||||
|
|
||||||
memcpy(BAReq->addr3, ieee->current_network.bssid, ETH_ALEN);
|
|
||||||
|
|
||||||
BAReq->frame_ctl = cpu_to_le16(IEEE80211_STYPE_MANAGE_ACT); //action frame
|
|
||||||
|
|
||||||
//tag += sizeof( struct rtl_80211_hdr_3addr); //move to action field
|
|
||||||
tag = skb_put(skb, 9);
|
|
||||||
*tag++ = ACT_CAT_BA;
|
|
||||||
*tag++ = type;
|
|
||||||
// Dialog Token
|
|
||||||
*tag++ = pBA->dialog_token;
|
|
||||||
|
|
||||||
if (type == ACT_ADDBARSP) {
|
|
||||||
// Status Code
|
|
||||||
netdev_info(ieee->dev, "=====>to send ADDBARSP\n");
|
|
||||||
|
|
||||||
put_unaligned_le16(StatusCode, tag);
|
|
||||||
tag += 2;
|
|
||||||
}
|
|
||||||
// BA Parameter Set
|
|
||||||
|
|
||||||
put_unaligned_le16(pBA->param_set.short_data, tag);
|
|
||||||
tag += 2;
|
|
||||||
// BA Timeout Value
|
|
||||||
|
|
||||||
put_unaligned_le16(pBA->timeout_value, tag);
|
|
||||||
tag += 2;
|
|
||||||
|
|
||||||
if (type == ACT_ADDBAREQ) {
|
|
||||||
// BA Start SeqCtrl
|
|
||||||
memcpy(tag, (u8 *)&(pBA->start_seq_ctrl), 2);
|
|
||||||
tag += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA | IEEE80211_DL_BA, skb->data, skb->len);
|
|
||||||
return skb;
|
|
||||||
//return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/********************************************************************************************************************
|
|
||||||
*function: construct DELBA frame
|
|
||||||
* input: u8* dst //DELBA frame's destination
|
|
||||||
* struct ba_record *pBA //BA_RECORD entry which stores the necessary information for BA
|
|
||||||
* enum tr_select TxRxSelect //TX RX direction
|
|
||||||
* u16 ReasonCode //status code.
|
|
||||||
* output: none
|
|
||||||
* return: sk_buff* skb //return constructed skb to xmit
|
|
||||||
********************************************************************************************************************/
|
|
||||||
static struct sk_buff *ieee80211_DELBA(
|
|
||||||
struct ieee80211_device *ieee,
|
|
||||||
u8 *dst,
|
|
||||||
struct ba_record *pBA,
|
|
||||||
enum tr_select TxRxSelect,
|
|
||||||
u16 ReasonCode
|
|
||||||
)
|
|
||||||
{
|
|
||||||
union delba_param_set DelbaParamSet;
|
|
||||||
struct sk_buff *skb = NULL;
|
|
||||||
struct rtl_80211_hdr_3addr *Delba = NULL;
|
|
||||||
u8 *tag = NULL;
|
|
||||||
//len = head len + DELBA Parameter Set(2) + Reason Code(2)
|
|
||||||
u16 len = 6 + ieee->tx_headroom;
|
|
||||||
|
|
||||||
if (net_ratelimit())
|
|
||||||
IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA,
|
|
||||||
"========>%s(), ReasonCode(%d) sentd to:%pM\n",
|
|
||||||
__func__, ReasonCode, dst);
|
|
||||||
|
|
||||||
memset(&DelbaParamSet, 0, 2);
|
|
||||||
|
|
||||||
DelbaParamSet.field.initiator = (TxRxSelect == TX_DIR) ? 1 : 0;
|
|
||||||
DelbaParamSet.field.tid = pBA->param_set.field.tid;
|
|
||||||
|
|
||||||
skb = dev_alloc_skb(len + sizeof(struct rtl_80211_hdr_3addr)); //need to add something others? FIXME
|
|
||||||
if (!skb)
|
|
||||||
return NULL;
|
|
||||||
// memset(skb->data, 0, len+sizeof( struct rtl_80211_hdr_3addr));
|
|
||||||
skb_reserve(skb, ieee->tx_headroom);
|
|
||||||
|
|
||||||
Delba = skb_put(skb, sizeof(struct rtl_80211_hdr_3addr));
|
|
||||||
|
|
||||||
memcpy(Delba->addr1, dst, ETH_ALEN);
|
|
||||||
memcpy(Delba->addr2, ieee->dev->dev_addr, ETH_ALEN);
|
|
||||||
memcpy(Delba->addr3, ieee->current_network.bssid, ETH_ALEN);
|
|
||||||
Delba->frame_ctl = cpu_to_le16(IEEE80211_STYPE_MANAGE_ACT); //action frame
|
|
||||||
|
|
||||||
tag = skb_put(skb, 6);
|
|
||||||
|
|
||||||
*tag++ = ACT_CAT_BA;
|
|
||||||
*tag++ = ACT_DELBA;
|
|
||||||
|
|
||||||
// DELBA Parameter Set
|
|
||||||
|
|
||||||
put_unaligned_le16(DelbaParamSet.short_data, tag);
|
|
||||||
tag += 2;
|
|
||||||
// Reason Code
|
|
||||||
|
|
||||||
put_unaligned_le16(ReasonCode, tag);
|
|
||||||
tag += 2;
|
|
||||||
|
|
||||||
IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA | IEEE80211_DL_BA, skb->data, skb->len);
|
|
||||||
if (net_ratelimit())
|
|
||||||
IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA,
|
|
||||||
"<=====%s()\n", __func__);
|
|
||||||
return skb;
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************************************************************
|
|
||||||
*function: send ADDBAReq frame out
|
|
||||||
* input: u8* dst //ADDBAReq frame's destination
|
|
||||||
* struct ba_record *pBA //BA_RECORD entry which stores the necessary information for BA
|
|
||||||
* output: none
|
|
||||||
* notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does
|
|
||||||
********************************************************************************************************************/
|
|
||||||
static void ieee80211_send_ADDBAReq(struct ieee80211_device *ieee,
|
|
||||||
u8 *dst, struct ba_record *pBA)
|
|
||||||
{
|
|
||||||
struct sk_buff *skb;
|
|
||||||
skb = ieee80211_ADDBA(ieee, dst, pBA, 0, ACT_ADDBAREQ); //construct ACT_ADDBAREQ frames so set statuscode zero.
|
|
||||||
|
|
||||||
if (skb) {
|
|
||||||
softmac_mgmt_xmit(skb, ieee);
|
|
||||||
//add statistic needed here.
|
|
||||||
//and skb will be freed in softmac_mgmt_xmit(), so omit all dev_kfree_skb_any() outside softmac_mgmt_xmit()
|
|
||||||
//WB
|
|
||||||
} else {
|
|
||||||
IEEE80211_DEBUG(IEEE80211_DL_ERR, "alloc skb error in function %s()\n", __func__);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************************************************************
|
|
||||||
*function: send ADDBARSP frame out
|
|
||||||
* input: u8* dst //DELBA frame's destination
|
|
||||||
* struct ba_record *pBA //BA_RECORD entry which stores the necessary information for BA
|
|
||||||
* u16 StatusCode //RSP StatusCode
|
|
||||||
* output: none
|
|
||||||
* notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does
|
|
||||||
********************************************************************************************************************/
|
|
||||||
static void ieee80211_send_ADDBARsp(struct ieee80211_device *ieee, u8 *dst,
|
|
||||||
struct ba_record *pBA, u16 StatusCode)
|
|
||||||
{
|
|
||||||
struct sk_buff *skb;
|
|
||||||
skb = ieee80211_ADDBA(ieee, dst, pBA, StatusCode, ACT_ADDBARSP); //construct ACT_ADDBARSP frames
|
|
||||||
if (skb) {
|
|
||||||
softmac_mgmt_xmit(skb, ieee);
|
|
||||||
//same above
|
|
||||||
} else {
|
|
||||||
IEEE80211_DEBUG(IEEE80211_DL_ERR, "alloc skb error in function %s()\n", __func__);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
}
|
|
||||||
/********************************************************************************************************************
|
|
||||||
*function: send ADDBARSP frame out
|
|
||||||
* input: u8* dst //DELBA frame's destination
|
|
||||||
* struct ba_record *pBA //BA_RECORD entry which stores the necessary information for BA
|
|
||||||
* enum tr_select TxRxSelect //TX or RX
|
|
||||||
* u16 ReasonCode //DEL ReasonCode
|
|
||||||
* output: none
|
|
||||||
* notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does
|
|
||||||
********************************************************************************************************************/
|
|
||||||
|
|
||||||
static void ieee80211_send_DELBA(struct ieee80211_device *ieee, u8 *dst,
|
|
||||||
struct ba_record *pBA, enum tr_select TxRxSelect,
|
|
||||||
u16 ReasonCode)
|
|
||||||
{
|
|
||||||
struct sk_buff *skb;
|
|
||||||
skb = ieee80211_DELBA(ieee, dst, pBA, TxRxSelect, ReasonCode); //construct ACT_ADDBARSP frames
|
|
||||||
if (skb) {
|
|
||||||
softmac_mgmt_xmit(skb, ieee);
|
|
||||||
//same above
|
|
||||||
} else {
|
|
||||||
IEEE80211_DEBUG(IEEE80211_DL_ERR, "alloc skb error in function %s()\n", __func__);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************************************************************
|
|
||||||
*function: RX ADDBAReq
|
|
||||||
* input: struct sk_buff * skb //incoming ADDBAReq skb.
|
|
||||||
* return: 0(pass), other(fail)
|
|
||||||
* notice: As this function need support of QOS, I comment some code out. And when qos is ready, this code need to be support.
|
|
||||||
********************************************************************************************************************/
|
|
||||||
int ieee80211_rx_ADDBAReq(struct ieee80211_device *ieee, struct sk_buff *skb)
|
|
||||||
{
|
|
||||||
struct rtl_80211_hdr_3addr *req = NULL;
|
|
||||||
u16 rc = 0;
|
|
||||||
u8 *dst = NULL, *pDialogToken = NULL, *tag = NULL;
|
|
||||||
struct ba_record *pBA = NULL;
|
|
||||||
union ba_param_set *pBaParamSet = NULL;
|
|
||||||
u16 *pBaTimeoutVal = NULL;
|
|
||||||
union sequence_control *pBaStartSeqCtrl = NULL;
|
|
||||||
struct rx_ts_record *pTS = NULL;
|
|
||||||
|
|
||||||
if (skb->len < sizeof(struct rtl_80211_hdr_3addr) + 9) {
|
|
||||||
IEEE80211_DEBUG(IEEE80211_DL_ERR,
|
|
||||||
" Invalid skb len in BAREQ(%d / %zu)\n",
|
|
||||||
skb->len,
|
|
||||||
(sizeof(struct rtl_80211_hdr_3addr) + 9));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA | IEEE80211_DL_BA, skb->data, skb->len);
|
|
||||||
|
|
||||||
req = (struct rtl_80211_hdr_3addr *)skb->data;
|
|
||||||
tag = (u8 *)req;
|
|
||||||
dst = &req->addr2[0];
|
|
||||||
tag += sizeof(struct rtl_80211_hdr_3addr);
|
|
||||||
pDialogToken = tag + 2; //category+action
|
|
||||||
pBaParamSet = (union ba_param_set *)(tag + 3); //+DialogToken
|
|
||||||
pBaTimeoutVal = (u16 *)(tag + 5);
|
|
||||||
pBaStartSeqCtrl = (union sequence_control *)(req + 7);
|
|
||||||
|
|
||||||
netdev_info(ieee->dev, "====================>rx ADDBAREQ from :%pM\n", dst);
|
|
||||||
//some other capability is not ready now.
|
|
||||||
if ((ieee->current_network.qos_data.active == 0) ||
|
|
||||||
(!ieee->pHTInfo->bCurrentHTSupport)) //||
|
|
||||||
// (!ieee->pStaQos->bEnableRxImmBA) )
|
|
||||||
{
|
|
||||||
rc = ADDBA_STATUS_REFUSED;
|
|
||||||
IEEE80211_DEBUG(IEEE80211_DL_ERR, "Failed to reply on ADDBA_REQ as some capability is not ready(%d, %d)\n", ieee->current_network.qos_data.active, ieee->pHTInfo->bCurrentHTSupport);
|
|
||||||
goto OnADDBAReq_Fail;
|
|
||||||
}
|
|
||||||
// Search for related traffic stream.
|
|
||||||
// If there is no matched TS, reject the ADDBA request.
|
|
||||||
if (!GetTs(
|
|
||||||
ieee,
|
|
||||||
(struct ts_common_info **)(&pTS),
|
|
||||||
dst,
|
|
||||||
(u8)(pBaParamSet->field.tid),
|
|
||||||
RX_DIR,
|
|
||||||
true)) {
|
|
||||||
rc = ADDBA_STATUS_REFUSED;
|
|
||||||
IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't get TS in %s()\n", __func__);
|
|
||||||
goto OnADDBAReq_Fail;
|
|
||||||
}
|
|
||||||
pBA = &pTS->rx_admitted_ba_record;
|
|
||||||
// To Determine the ADDBA Req content
|
|
||||||
// We can do much more check here, including buffer_size, AMSDU_Support, Policy, StartSeqCtrl...
|
|
||||||
// I want to check StartSeqCtrl to make sure when we start aggregation!!!
|
|
||||||
//
|
|
||||||
if (pBaParamSet->field.ba_policy == BA_POLICY_DELAYED) {
|
|
||||||
rc = ADDBA_STATUS_INVALID_PARAM;
|
|
||||||
IEEE80211_DEBUG(IEEE80211_DL_ERR, "BA Policy is not correct in %s()\n", __func__);
|
|
||||||
goto OnADDBAReq_Fail;
|
|
||||||
}
|
|
||||||
// Admit the ADDBA Request
|
|
||||||
//
|
|
||||||
DeActivateBAEntry(ieee, pBA);
|
|
||||||
pBA->dialog_token = *pDialogToken;
|
|
||||||
pBA->param_set = *pBaParamSet;
|
|
||||||
pBA->timeout_value = *pBaTimeoutVal;
|
|
||||||
pBA->start_seq_ctrl = *pBaStartSeqCtrl;
|
|
||||||
//for half N mode we only aggregate 1 frame
|
|
||||||
if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))
|
|
||||||
pBA->param_set.field.buffer_size = 1;
|
|
||||||
else
|
|
||||||
pBA->param_set.field.buffer_size = 32;
|
|
||||||
ActivateBAEntry(ieee, pBA, pBA->timeout_value);
|
|
||||||
ieee80211_send_ADDBARsp(ieee, dst, pBA, ADDBA_STATUS_SUCCESS);
|
|
||||||
|
|
||||||
// End of procedure.
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
OnADDBAReq_Fail:
|
|
||||||
{
|
|
||||||
struct ba_record BA;
|
|
||||||
BA.param_set = *pBaParamSet;
|
|
||||||
BA.timeout_value = *pBaTimeoutVal;
|
|
||||||
BA.dialog_token = *pDialogToken;
|
|
||||||
BA.param_set.field.ba_policy = BA_POLICY_IMMEDIATE;
|
|
||||||
ieee80211_send_ADDBARsp(ieee, dst, &BA, rc);
|
|
||||||
return 0; //we send RSP out.
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************************************************************
|
|
||||||
*function: RX ADDBARSP
|
|
||||||
* input: struct sk_buff * skb //incoming ADDBAReq skb.
|
|
||||||
* return: 0(pass), other(fail)
|
|
||||||
* notice: As this function need support of QOS, I comment some code out. And when qos is ready, this code need to be support.
|
|
||||||
********************************************************************************************************************/
|
|
||||||
int ieee80211_rx_ADDBARsp(struct ieee80211_device *ieee, struct sk_buff *skb)
|
|
||||||
{
|
|
||||||
struct rtl_80211_hdr_3addr *rsp = NULL;
|
|
||||||
struct ba_record *pPendingBA, *pAdmittedBA;
|
|
||||||
struct tx_ts_record *pTS = NULL;
|
|
||||||
u8 *dst = NULL, *pDialogToken = NULL, *tag = NULL;
|
|
||||||
u16 *pStatusCode = NULL, *pBaTimeoutVal = NULL;
|
|
||||||
union ba_param_set *pBaParamSet = NULL;
|
|
||||||
u16 ReasonCode;
|
|
||||||
|
|
||||||
if (skb->len < sizeof(struct rtl_80211_hdr_3addr) + 9) {
|
|
||||||
IEEE80211_DEBUG(IEEE80211_DL_ERR,
|
|
||||||
" Invalid skb len in BARSP(%d / %zu)\n",
|
|
||||||
skb->len,
|
|
||||||
(sizeof(struct rtl_80211_hdr_3addr) + 9));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
rsp = (struct rtl_80211_hdr_3addr *)skb->data;
|
|
||||||
tag = (u8 *)rsp;
|
|
||||||
dst = &rsp->addr2[0];
|
|
||||||
tag += sizeof(struct rtl_80211_hdr_3addr);
|
|
||||||
pDialogToken = tag + 2;
|
|
||||||
pStatusCode = (u16 *)(tag + 3);
|
|
||||||
pBaParamSet = (union ba_param_set *)(tag + 5);
|
|
||||||
pBaTimeoutVal = (u16 *)(tag + 7);
|
|
||||||
|
|
||||||
// Check the capability
|
|
||||||
// Since we can always receive A-MPDU, we just check if it is under HT mode.
|
|
||||||
if (ieee->current_network.qos_data.active == 0 ||
|
|
||||||
!ieee->pHTInfo->bCurrentHTSupport ||
|
|
||||||
!ieee->pHTInfo->bCurrentAMPDUEnable) {
|
|
||||||
IEEE80211_DEBUG(IEEE80211_DL_ERR, "reject to ADDBA_RSP as some capability is not ready(%d, %d, %d)\n", ieee->current_network.qos_data.active, ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bCurrentAMPDUEnable);
|
|
||||||
ReasonCode = DELBA_REASON_UNKNOWN_BA;
|
|
||||||
goto OnADDBARsp_Reject;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Search for related TS.
|
|
||||||
// If there is no TS found, we wil reject ADDBA Rsp by sending DELBA frame.
|
|
||||||
//
|
|
||||||
if (!GetTs(
|
|
||||||
ieee,
|
|
||||||
(struct ts_common_info **)(&pTS),
|
|
||||||
dst,
|
|
||||||
(u8)(pBaParamSet->field.tid),
|
|
||||||
TX_DIR,
|
|
||||||
false)) {
|
|
||||||
IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't get TS in %s()\n", __func__);
|
|
||||||
ReasonCode = DELBA_REASON_UNKNOWN_BA;
|
|
||||||
goto OnADDBARsp_Reject;
|
|
||||||
}
|
|
||||||
|
|
||||||
pTS->add_ba_req_in_progress = false;
|
|
||||||
pPendingBA = &pTS->tx_pending_ba_record;
|
|
||||||
pAdmittedBA = &pTS->tx_admitted_ba_record;
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Check if related BA is waiting for setup.
|
|
||||||
// If not, reject by sending DELBA frame.
|
|
||||||
//
|
|
||||||
if (pAdmittedBA->valid) {
|
|
||||||
// Since BA is already setup, we ignore all other ADDBA Response.
|
|
||||||
IEEE80211_DEBUG(IEEE80211_DL_BA, "OnADDBARsp(): Recv ADDBA Rsp. Drop because already admit it! \n");
|
|
||||||
return -1;
|
|
||||||
} else if ((!pPendingBA->valid) || (*pDialogToken != pPendingBA->dialog_token)) {
|
|
||||||
IEEE80211_DEBUG(IEEE80211_DL_ERR, "OnADDBARsp(): Recv ADDBA Rsp. BA invalid, DELBA! \n");
|
|
||||||
ReasonCode = DELBA_REASON_UNKNOWN_BA;
|
|
||||||
goto OnADDBARsp_Reject;
|
|
||||||
} else {
|
|
||||||
IEEE80211_DEBUG(IEEE80211_DL_BA, "OnADDBARsp(): Recv ADDBA Rsp. BA is admitted! Status code:%X\n", *pStatusCode);
|
|
||||||
DeActivateBAEntry(ieee, pPendingBA);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (*pStatusCode == ADDBA_STATUS_SUCCESS) {
|
|
||||||
//
|
|
||||||
// Determine ADDBA Rsp content here.
|
|
||||||
// We can compare the value of BA parameter set that Peer returned and Self sent.
|
|
||||||
// If it is OK, then admitted. Or we can send DELBA to cancel BA mechanism.
|
|
||||||
//
|
|
||||||
if (pBaParamSet->field.ba_policy == BA_POLICY_DELAYED) {
|
|
||||||
// Since this is a kind of ADDBA failed, we delay next ADDBA process.
|
|
||||||
pTS->add_ba_req_delayed = true;
|
|
||||||
DeActivateBAEntry(ieee, pAdmittedBA);
|
|
||||||
ReasonCode = DELBA_REASON_END_BA;
|
|
||||||
goto OnADDBARsp_Reject;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Admitted condition
|
|
||||||
//
|
|
||||||
pAdmittedBA->dialog_token = *pDialogToken;
|
|
||||||
pAdmittedBA->timeout_value = *pBaTimeoutVal;
|
|
||||||
pAdmittedBA->start_seq_ctrl = pPendingBA->start_seq_ctrl;
|
|
||||||
pAdmittedBA->param_set = *pBaParamSet;
|
|
||||||
DeActivateBAEntry(ieee, pAdmittedBA);
|
|
||||||
ActivateBAEntry(ieee, pAdmittedBA, *pBaTimeoutVal);
|
|
||||||
} else {
|
|
||||||
// Delay next ADDBA process.
|
|
||||||
pTS->add_ba_req_delayed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// End of procedure
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
OnADDBARsp_Reject:
|
|
||||||
{
|
|
||||||
struct ba_record BA;
|
|
||||||
BA.param_set = *pBaParamSet;
|
|
||||||
ieee80211_send_DELBA(ieee, dst, &BA, TX_DIR, ReasonCode);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************************************************************
|
|
||||||
*function: RX DELBA
|
|
||||||
* input: struct sk_buff * skb //incoming ADDBAReq skb.
|
|
||||||
* return: 0(pass), other(fail)
|
|
||||||
* notice: As this function need support of QOS, I comment some code out. And when qos is ready, this code need to be support.
|
|
||||||
********************************************************************************************************************/
|
|
||||||
int ieee80211_rx_DELBA(struct ieee80211_device *ieee, struct sk_buff *skb)
|
|
||||||
{
|
|
||||||
struct rtl_80211_hdr_3addr *delba = NULL;
|
|
||||||
union delba_param_set *pDelBaParamSet = NULL;
|
|
||||||
u8 *dst = NULL;
|
|
||||||
|
|
||||||
if (skb->len < sizeof(struct rtl_80211_hdr_3addr) + 6) {
|
|
||||||
IEEE80211_DEBUG(IEEE80211_DL_ERR,
|
|
||||||
" Invalid skb len in DELBA(%d / %zu)\n",
|
|
||||||
skb->len,
|
|
||||||
(sizeof(struct rtl_80211_hdr_3addr) + 6));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ieee->current_network.qos_data.active == 0 ||
|
|
||||||
!ieee->pHTInfo->bCurrentHTSupport) {
|
|
||||||
IEEE80211_DEBUG(IEEE80211_DL_ERR, "received DELBA while QOS or HT is not supported(%d, %d)\n", ieee->current_network.qos_data.active, ieee->pHTInfo->bCurrentHTSupport);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA | IEEE80211_DL_BA, skb->data, skb->len);
|
|
||||||
delba = (struct rtl_80211_hdr_3addr *)skb->data;
|
|
||||||
dst = &delba->addr2[0];
|
|
||||||
pDelBaParamSet = (union delba_param_set *)&delba->payload[2];
|
|
||||||
|
|
||||||
if (pDelBaParamSet->field.initiator == 1) {
|
|
||||||
struct rx_ts_record *pRxTs;
|
|
||||||
|
|
||||||
if (!GetTs(
|
|
||||||
ieee,
|
|
||||||
(struct ts_common_info **)&pRxTs,
|
|
||||||
dst,
|
|
||||||
(u8)pDelBaParamSet->field.tid,
|
|
||||||
RX_DIR,
|
|
||||||
false)) {
|
|
||||||
IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't get TS for RXTS in %s()\n", __func__);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
RxTsDeleteBA(ieee, pRxTs);
|
|
||||||
} else {
|
|
||||||
struct tx_ts_record *pTxTs;
|
|
||||||
|
|
||||||
if (!GetTs(
|
|
||||||
ieee,
|
|
||||||
(struct ts_common_info **)&pTxTs,
|
|
||||||
dst,
|
|
||||||
(u8)pDelBaParamSet->field.tid,
|
|
||||||
TX_DIR,
|
|
||||||
false)) {
|
|
||||||
IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't get TS for TXTS in %s()\n", __func__);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
pTxTs->using_ba = false;
|
|
||||||
pTxTs->add_ba_req_in_progress = false;
|
|
||||||
pTxTs->add_ba_req_delayed = false;
|
|
||||||
del_timer_sync(&pTxTs->ts_add_ba_timer);
|
|
||||||
//PlatformCancelTimer(Adapter, &pTxTs->ts_add_ba_timer);
|
|
||||||
TxTsDeleteBA(ieee, pTxTs);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// ADDBA initiate. This can only be called by TX side.
|
|
||||||
//
|
|
||||||
void
|
|
||||||
TsInitAddBA(
|
|
||||||
struct ieee80211_device *ieee,
|
|
||||||
struct tx_ts_record *pTS,
|
|
||||||
u8 Policy,
|
|
||||||
u8 bOverwritePending
|
|
||||||
)
|
|
||||||
{
|
|
||||||
struct ba_record *pBA = &pTS->tx_pending_ba_record;
|
|
||||||
|
|
||||||
if (pBA->valid && !bOverwritePending)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Set parameters to "Pending" variable set
|
|
||||||
DeActivateBAEntry(ieee, pBA);
|
|
||||||
|
|
||||||
pBA->dialog_token++; // DialogToken: Only keep the latest dialog token
|
|
||||||
pBA->param_set.field.amsdu_support = 0; // Do not support A-MSDU with A-MPDU now!!
|
|
||||||
pBA->param_set.field.ba_policy = Policy; // Policy: Delayed or Immediate
|
|
||||||
pBA->param_set.field.tid = pTS->ts_common_info.t_spec.ts_info.uc_tsid; // TID
|
|
||||||
// buffer_size: This need to be set according to A-MPDU vector
|
|
||||||
pBA->param_set.field.buffer_size = 32; // buffer_size: This need to be set according to A-MPDU vector
|
|
||||||
pBA->timeout_value = 0; // Timeout value: Set 0 to disable Timer
|
|
||||||
pBA->start_seq_ctrl.field.seq_num = (pTS->tx_cur_seq + 3) % 4096; // Block Ack will start after 3 packets later.
|
|
||||||
|
|
||||||
ActivateBAEntry(ieee, pBA, BA_SETUP_TIMEOUT);
|
|
||||||
|
|
||||||
ieee80211_send_ADDBAReq(ieee, pTS->ts_common_info.addr, pBA);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
TsInitDelBA(struct ieee80211_device *ieee, struct ts_common_info *pTsCommonInfo, enum tr_select TxRxSelect)
|
|
||||||
{
|
|
||||||
if (TxRxSelect == TX_DIR) {
|
|
||||||
struct tx_ts_record *pTxTs = (struct tx_ts_record *)pTsCommonInfo;
|
|
||||||
|
|
||||||
if (TxTsDeleteBA(ieee, pTxTs))
|
|
||||||
ieee80211_send_DELBA(
|
|
||||||
ieee,
|
|
||||||
pTsCommonInfo->addr,
|
|
||||||
(pTxTs->tx_admitted_ba_record.valid) ? (&pTxTs->tx_admitted_ba_record) : (&pTxTs->tx_pending_ba_record),
|
|
||||||
TxRxSelect,
|
|
||||||
DELBA_REASON_END_BA);
|
|
||||||
} else if (TxRxSelect == RX_DIR) {
|
|
||||||
struct rx_ts_record *pRxTs = (struct rx_ts_record *)pTsCommonInfo;
|
|
||||||
if (RxTsDeleteBA(ieee, pRxTs))
|
|
||||||
ieee80211_send_DELBA(
|
|
||||||
ieee,
|
|
||||||
pTsCommonInfo->addr,
|
|
||||||
&pRxTs->rx_admitted_ba_record,
|
|
||||||
TxRxSelect,
|
|
||||||
DELBA_REASON_END_BA);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/********************************************************************************************************************
|
|
||||||
*function: BA setup timer
|
|
||||||
* input: unsigned long data //acturally we send struct tx_ts_record or struct rx_ts_record to these timer
|
|
||||||
* return: NULL
|
|
||||||
* notice:
|
|
||||||
********************************************************************************************************************/
|
|
||||||
void BaSetupTimeOut(struct timer_list *t)
|
|
||||||
{
|
|
||||||
struct tx_ts_record *pTxTs = from_timer(pTxTs, t, tx_pending_ba_record.timer);
|
|
||||||
|
|
||||||
pTxTs->add_ba_req_in_progress = false;
|
|
||||||
pTxTs->add_ba_req_delayed = true;
|
|
||||||
pTxTs->tx_pending_ba_record.valid = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TxBaInactTimeout(struct timer_list *t)
|
|
||||||
{
|
|
||||||
struct tx_ts_record *pTxTs = from_timer(pTxTs, t, tx_admitted_ba_record.timer);
|
|
||||||
struct ieee80211_device *ieee = container_of(pTxTs, struct ieee80211_device, TxTsRecord[pTxTs->num]);
|
|
||||||
TxTsDeleteBA(ieee, pTxTs);
|
|
||||||
ieee80211_send_DELBA(
|
|
||||||
ieee,
|
|
||||||
pTxTs->ts_common_info.addr,
|
|
||||||
&pTxTs->tx_admitted_ba_record,
|
|
||||||
TX_DIR,
|
|
||||||
DELBA_REASON_TIMEOUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RxBaInactTimeout(struct timer_list *t)
|
|
||||||
{
|
|
||||||
struct rx_ts_record *pRxTs = from_timer(pRxTs, t, rx_admitted_ba_record.timer);
|
|
||||||
struct ieee80211_device *ieee = container_of(pRxTs, struct ieee80211_device, RxTsRecord[pRxTs->num]);
|
|
||||||
|
|
||||||
RxTsDeleteBA(ieee, pRxTs);
|
|
||||||
ieee80211_send_DELBA(
|
|
||||||
ieee,
|
|
||||||
pRxTs->ts_common_info.addr,
|
|
||||||
&pRxTs->rx_admitted_ba_record,
|
|
||||||
RX_DIR,
|
|
||||||
DELBA_REASON_TIMEOUT);
|
|
||||||
}
|
|
@ -1,302 +0,0 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
#ifndef _RTL819XU_HTTYPE_H_
|
|
||||||
#define _RTL819XU_HTTYPE_H_
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The HT Capability element is present in beacons, association request,
|
|
||||||
* reassociation request and probe response frames
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* MIMO Power Save Settings
|
|
||||||
*/
|
|
||||||
#define MIMO_PS_STATIC 0
|
|
||||||
|
|
||||||
/*
|
|
||||||
* There should be 128 bits to cover all of the MCS rates. However, since
|
|
||||||
* 8190 does not support too much rates, one integer is quite enough.
|
|
||||||
*/
|
|
||||||
#define HTCLNG 4
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Represent Channel Width in HT Capabilities
|
|
||||||
*/
|
|
||||||
enum ht_channel_width {
|
|
||||||
HT_CHANNEL_WIDTH_20 = 0,
|
|
||||||
HT_CHANNEL_WIDTH_20_40 = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Represent Extension Channel Offset in HT Capabilities
|
|
||||||
* This is available only in 40Mhz mode.
|
|
||||||
*/
|
|
||||||
enum ht_extension_chan_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_capability_ele {
|
|
||||||
//HT capability info
|
|
||||||
u8 AdvCoding:1;
|
|
||||||
u8 ChlWidth:1;
|
|
||||||
u8 MimoPwrSave:2;
|
|
||||||
u8 GreenField:1;
|
|
||||||
u8 ShortGI20Mhz:1;
|
|
||||||
u8 ShortGI40Mhz:1;
|
|
||||||
u8 TxSTBC:1;
|
|
||||||
u8 RxSTBC:2;
|
|
||||||
u8 DelayBA:1;
|
|
||||||
u8 MaxAMSDUSize:1;
|
|
||||||
u8 DssCCk:1;
|
|
||||||
u8 PSMP:1;
|
|
||||||
u8 Rsvd1:1;
|
|
||||||
u8 LSigTxopProtect:1;
|
|
||||||
|
|
||||||
//MAC HT parameters info
|
|
||||||
u8 MaxRxAMPDUFactor:2;
|
|
||||||
u8 MPDUDensity:3;
|
|
||||||
u8 Rsvd2:3;
|
|
||||||
|
|
||||||
//Supported MCS set
|
|
||||||
u8 MCS[16];
|
|
||||||
|
|
||||||
//Extended HT Capability Info
|
|
||||||
u16 ExtHTCapInfo;
|
|
||||||
|
|
||||||
//TXBF Capabilities
|
|
||||||
u8 TxBFCap[4];
|
|
||||||
|
|
||||||
//Antenna Selection Capabilities
|
|
||||||
u8 ASCap;
|
|
||||||
|
|
||||||
} __packed;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The HT Information element is present in beacons
|
|
||||||
* Only AP is required to include this element
|
|
||||||
*/
|
|
||||||
typedef struct _HT_INFORMATION_ELE {
|
|
||||||
u8 ControlChl;
|
|
||||||
|
|
||||||
u8 ExtChlOffset:2;
|
|
||||||
u8 RecommemdedTxWidth:1;
|
|
||||||
u8 RIFS:1;
|
|
||||||
u8 PSMPAccessOnly:1;
|
|
||||||
u8 SrvIntGranularity:3;
|
|
||||||
|
|
||||||
u8 OptMode:2;
|
|
||||||
u8 NonGFDevPresent:1;
|
|
||||||
u8 Revd1:5;
|
|
||||||
u8 Revd2:8;
|
|
||||||
|
|
||||||
u8 Rsvd3:6;
|
|
||||||
u8 DualBeacon:1;
|
|
||||||
u8 DualCTSProtect:1;
|
|
||||||
|
|
||||||
u8 SecondaryBeacon:1;
|
|
||||||
u8 LSigTxopProtectFull:1;
|
|
||||||
u8 PcoActive:1;
|
|
||||||
u8 PcoPhase:1;
|
|
||||||
u8 Rsvd4:4;
|
|
||||||
|
|
||||||
u8 BasicMSC[16];
|
|
||||||
} __attribute__ ((packed)) HT_INFORMATION_ELE, *PHT_INFORMATION_ELE;
|
|
||||||
|
|
||||||
typedef enum _HT_SPEC_VER {
|
|
||||||
HT_SPEC_VER_IEEE = 0,
|
|
||||||
HT_SPEC_VER_EWC = 1,
|
|
||||||
} HT_SPEC_VER, *PHT_SPEC_VER;
|
|
||||||
|
|
||||||
typedef enum _HT_AGGRE_MODE_E {
|
|
||||||
HT_AGG_AUTO = 0,
|
|
||||||
HT_AGG_FORCE_ENABLE = 1,
|
|
||||||
HT_AGG_FORCE_DISABLE = 2,
|
|
||||||
} HT_AGGRE_MODE_E, *PHT_AGGRE_MODE_E;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The Data structure is used to keep HT related variables when card is
|
|
||||||
* configured as non-AP STA mode. **Note** Current_xxx should be set
|
|
||||||
* to default value in HTInitializeHTInfo()
|
|
||||||
*/
|
|
||||||
typedef struct _RT_HIGH_THROUGHPUT {
|
|
||||||
u8 bEnableHT;
|
|
||||||
u8 bCurrentHTSupport;
|
|
||||||
|
|
||||||
u8 bRegBW40MHz; // Tx 40MHz channel capability
|
|
||||||
u8 bCurBW40MHz; // Tx 40MHz channel capability
|
|
||||||
|
|
||||||
u8 bRegShortGI40MHz; // Tx Short GI for 40Mhz
|
|
||||||
u8 bCurShortGI40MHz; // Tx Short GI for 40MHz
|
|
||||||
|
|
||||||
u8 bRegShortGI20MHz; // Tx Short GI for 20MHz
|
|
||||||
u8 bCurShortGI20MHz; // Tx Short GI for 20MHz
|
|
||||||
|
|
||||||
u8 bRegSuppCCK; // Tx CCK rate capability
|
|
||||||
u8 bCurSuppCCK; // Tx CCK rate capability
|
|
||||||
|
|
||||||
// 802.11n spec version for "peer"
|
|
||||||
HT_SPEC_VER ePeerHTSpecVer;
|
|
||||||
|
|
||||||
// HT related information for "Self"
|
|
||||||
struct ht_capability_ele SelfHTCap; // This is HT cap element sent to peer STA, which also indicate HT Rx capabilities.
|
|
||||||
HT_INFORMATION_ELE SelfHTInfo; // This is HT info element sent to peer STA, which also indicate HT Rx capabilities.
|
|
||||||
|
|
||||||
// HT related information for "Peer"
|
|
||||||
u8 PeerHTCapBuf[32];
|
|
||||||
u8 PeerHTInfoBuf[32];
|
|
||||||
|
|
||||||
// A-MSDU related
|
|
||||||
u8 bAMSDU_Support; // This indicates Tx A-MSDU capability
|
|
||||||
u16 nAMSDU_MaxSize; // This indicates Tx A-MSDU capability
|
|
||||||
u8 bCurrent_AMSDU_Support; // This indicates Tx A-MSDU capability
|
|
||||||
u16 nCurrent_AMSDU_MaxSize; // This indicates Tx A-MSDU capability
|
|
||||||
|
|
||||||
// AMPDU related <2006.08.10 Emily>
|
|
||||||
u8 bAMPDUEnable; // This indicate Tx A-MPDU capability
|
|
||||||
u8 bCurrentAMPDUEnable; // This indicate Tx A-MPDU capability
|
|
||||||
u8 AMPDU_Factor; // This indicate Tx A-MPDU capability
|
|
||||||
u8 CurrentAMPDUFactor; // This indicate Tx A-MPDU capability
|
|
||||||
u8 MPDU_Density; // This indicate Tx A-MPDU capability
|
|
||||||
u8 CurrentMPDUDensity; // This indicate Tx A-MPDU capability
|
|
||||||
|
|
||||||
// Forced A-MPDU enable
|
|
||||||
HT_AGGRE_MODE_E ForcedAMPDUMode;
|
|
||||||
u8 ForcedAMPDUFactor;
|
|
||||||
u8 ForcedMPDUDensity;
|
|
||||||
|
|
||||||
// Forced A-MSDU enable
|
|
||||||
HT_AGGRE_MODE_E ForcedAMSDUMode;
|
|
||||||
u16 ForcedAMSDUMaxSize;
|
|
||||||
|
|
||||||
u8 bForcedShortGI;
|
|
||||||
|
|
||||||
u8 CurrentOpMode;
|
|
||||||
|
|
||||||
// MIMO PS related
|
|
||||||
u8 SelfMimoPs;
|
|
||||||
u8 PeerMimoPs;
|
|
||||||
|
|
||||||
// 40MHz Channel Offset settings.
|
|
||||||
enum ht_extension_chan_offset CurSTAExtChnlOffset;
|
|
||||||
u8 bCurTxBW40MHz; // If we use 40 MHz to Tx
|
|
||||||
u8 PeerBandwidth;
|
|
||||||
|
|
||||||
// For Bandwidth Switching
|
|
||||||
u8 bSwBwInProgress;
|
|
||||||
u8 SwBwStep;
|
|
||||||
//struct timer_list SwBwTimer; //moved to ieee80211_device. as timer_list need include some header file here.
|
|
||||||
|
|
||||||
// For Realtek proprietary A-MPDU factor for aggregation
|
|
||||||
u8 bRegRT2RTAggregation;
|
|
||||||
u8 bCurrentRT2RTAggregation;
|
|
||||||
u8 bCurrentRT2RTLongSlotTime;
|
|
||||||
u8 szRT2RTAggBuffer[10];
|
|
||||||
|
|
||||||
// Rx Reorder control
|
|
||||||
u8 bRegRxReorderEnable;
|
|
||||||
u8 bCurRxReorderEnable;
|
|
||||||
u8 RxReorderWinSize;
|
|
||||||
u8 RxReorderPendingTime;
|
|
||||||
u16 RxReorderDropCounter;
|
|
||||||
|
|
||||||
#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
|
|
||||||
u8 UsbTxAggrNum;
|
|
||||||
#endif
|
|
||||||
#ifdef USB_RX_AGGREGATION_SUPPORT
|
|
||||||
u8 UsbRxFwAggrEn;
|
|
||||||
u8 UsbRxFwAggrPageNum;
|
|
||||||
u8 UsbRxFwAggrPacketNum;
|
|
||||||
u8 UsbRxFwAggrTimeout;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Add for Broadcom(Linksys) IOT. Joseph
|
|
||||||
u8 bIsPeerBcm;
|
|
||||||
|
|
||||||
// For IOT issue.
|
|
||||||
u8 IOTPeer;
|
|
||||||
u32 IOTAction;
|
|
||||||
} __attribute__ ((packed)) RT_HIGH_THROUGHPUT, *PRT_HIGH_THROUGHPUT;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The Data structure is used to keep HT related variable for "each AP"
|
|
||||||
* when card is configured as "STA mode"
|
|
||||||
*/
|
|
||||||
typedef struct _BSS_HT {
|
|
||||||
u8 bdSupportHT;
|
|
||||||
|
|
||||||
// HT related elements
|
|
||||||
u8 bdHTCapBuf[32];
|
|
||||||
u16 bdHTCapLen;
|
|
||||||
u8 bdHTInfoBuf[32];
|
|
||||||
u16 bdHTInfoLen;
|
|
||||||
|
|
||||||
HT_SPEC_VER bdHTSpecVer;
|
|
||||||
//struct ht_capability_ele bdHTCapEle;
|
|
||||||
//HT_INFORMATION_ELE bdHTInfoEle;
|
|
||||||
|
|
||||||
u8 bdRT2RTAggregation;
|
|
||||||
u8 bdRT2RTLongSlotTime;
|
|
||||||
} __attribute__ ((packed)) BSS_HT, *PBSS_HT;
|
|
||||||
|
|
||||||
extern u8 MCS_FILTER_ALL[16];
|
|
||||||
extern u8 MCS_FILTER_1SS[16];
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 2007/07/11 MH Modify the macro. Becaus STA may link with a N-AP. If we set
|
|
||||||
* STA in A/B/G mode and AP is still in N mode. The macro will be wrong. We have
|
|
||||||
* to add a macro to judge wireless mode.
|
|
||||||
*/
|
|
||||||
#define PICK_RATE(_nLegacyRate, _nMcsRate) \
|
|
||||||
(_nMcsRate == 0) ? (_nLegacyRate & 0x7f) : (_nMcsRate)
|
|
||||||
/* 2007/07/12 MH We only define legacy and HT wireless mode now. */
|
|
||||||
#define LEGACY_WIRELESS_MODE IEEE_MODE_MASK
|
|
||||||
|
|
||||||
#define CURRENT_RATE(WirelessMode, LegacyRate, HTRate) \
|
|
||||||
((WirelessMode & (LEGACY_WIRELESS_MODE)) != 0) ? \
|
|
||||||
(LegacyRate) : \
|
|
||||||
(PICK_RATE(LegacyRate, HTRate))
|
|
||||||
|
|
||||||
// MCS Bw 40 {1~7, 12~15,32}
|
|
||||||
#define RATE_ADPT_1SS_MASK 0xFF
|
|
||||||
#define RATE_ADPT_2SS_MASK 0xF0 //Skip MCS8~11 because mcs7 > mcs6, 9, 10, 11. 2007.01.16 by Emily
|
|
||||||
#define RATE_ADPT_MCS32_MASK 0x01
|
|
||||||
|
|
||||||
#define IS_11N_MCS_RATE(rate) (rate & 0x80)
|
|
||||||
|
|
||||||
typedef enum _HT_AGGRE_SIZE {
|
|
||||||
HT_AGG_SIZE_8K = 0,
|
|
||||||
HT_AGG_SIZE_16K = 1,
|
|
||||||
HT_AGG_SIZE_32K = 2,
|
|
||||||
HT_AGG_SIZE_64K = 3,
|
|
||||||
} HT_AGGRE_SIZE_E, *PHT_AGGRE_SIZE_E;
|
|
||||||
|
|
||||||
/* Indicate different AP vendor for IOT issue */
|
|
||||||
typedef enum _HT_IOT_PEER {
|
|
||||||
HT_IOT_PEER_UNKNOWN = 0,
|
|
||||||
HT_IOT_PEER_REALTEK = 1,
|
|
||||||
HT_IOT_PEER_BROADCOM = 2,
|
|
||||||
HT_IOT_PEER_RALINK = 3,
|
|
||||||
HT_IOT_PEER_ATHEROS = 4,
|
|
||||||
HT_IOT_PEER_CISCO = 5,
|
|
||||||
HT_IOT_PEER_MAX = 6
|
|
||||||
} HT_IOT_PEER_E, *PHTIOT_PEER_E;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* IOT Action for different AP
|
|
||||||
*/
|
|
||||||
typedef enum _HT_IOT_ACTION {
|
|
||||||
HT_IOT_ACT_TX_USE_AMSDU_4K = 0x00000001,
|
|
||||||
HT_IOT_ACT_TX_USE_AMSDU_8K = 0x00000002,
|
|
||||||
HT_IOT_ACT_DISABLE_MCS14 = 0x00000004,
|
|
||||||
HT_IOT_ACT_DISABLE_MCS15 = 0x00000008,
|
|
||||||
HT_IOT_ACT_DISABLE_ALL_2SS = 0x00000010,
|
|
||||||
HT_IOT_ACT_DISABLE_EDCA_TURBO = 0x00000020,
|
|
||||||
HT_IOT_ACT_MGNT_USE_CCK_6M = 0x00000040,
|
|
||||||
HT_IOT_ACT_CDD_FSYNC = 0x00000080,
|
|
||||||
HT_IOT_ACT_PURE_N_MODE = 0x00000100,
|
|
||||||
HT_IOT_ACT_FORCED_CTS2SELF = 0x00000200,
|
|
||||||
} HT_IOT_ACTION_E, *PHT_IOT_ACTION_E;
|
|
||||||
|
|
||||||
#endif //_RTL819XU_HTTYPE_H_
|
|
File diff suppressed because it is too large
Load Diff
@ -1,82 +0,0 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
#ifndef __INC_QOS_TYPE_H
|
|
||||||
#define __INC_QOS_TYPE_H
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ACI/AIFSN Field.
|
|
||||||
* Ref: WMM spec 2.2.2: WME Parameter Element, p.12.
|
|
||||||
* Note: 1 Byte Length
|
|
||||||
*/
|
|
||||||
struct aci_aifsn {
|
|
||||||
u8 aifsn:4;
|
|
||||||
u8 acm:1;
|
|
||||||
u8 aci:2;
|
|
||||||
u8:1;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Direction Field Values.
|
|
||||||
* Ref: WMM spec 2.2.11: WME TSPEC Element, p.18.
|
|
||||||
*/
|
|
||||||
enum direction_value {
|
|
||||||
DIR_UP = 0, // 0x00 // UpLink
|
|
||||||
DIR_DOWN = 1, // 0x01 // DownLink
|
|
||||||
DIR_DIRECT = 2, // 0x10 // DirectLink
|
|
||||||
DIR_BI_DIR = 3, // 0x11 // Bi-Direction
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* TS Info field in WMM TSPEC Element.
|
|
||||||
* Ref:
|
|
||||||
* 1. WMM spec 2.2.11: WME TSPEC Element, p.18.
|
|
||||||
* 2. 8185 QoS code: QOS_TSINFO [def. in QoS_mp.h]
|
|
||||||
* Note: sizeof 3 Bytes
|
|
||||||
*/
|
|
||||||
struct qos_tsinfo {
|
|
||||||
u16 uc_traffic_type:1; //WMM is reserved
|
|
||||||
u16 uc_tsid:4;
|
|
||||||
u16 uc_direction:2;
|
|
||||||
u16 uc_access_policy:2; //WMM: bit8=0, bit7=1
|
|
||||||
u16 uc_aggregation:1; //WMM is reserved
|
|
||||||
u16 uc_psb:1; //WMMSA is APSD
|
|
||||||
u16 uc_up:3;
|
|
||||||
u16 uc_ts_info_ack_policy:2; //WMM is reserved
|
|
||||||
u8 uc_schedule:1; //WMM is reserved
|
|
||||||
u8:7;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* WMM TSPEC Body.
|
|
||||||
* Ref: WMM spec 2.2.11: WME TSPEC Element, p.16.
|
|
||||||
* Note: sizeof 55 bytes
|
|
||||||
*/
|
|
||||||
struct tspec_body {
|
|
||||||
struct qos_tsinfo ts_info; //u8 TSInfo[3];
|
|
||||||
u16 nominal_msd_usize;
|
|
||||||
u16 max_msd_usize;
|
|
||||||
u32 min_service_itv;
|
|
||||||
u32 max_service_itv;
|
|
||||||
u32 inactivity_itv;
|
|
||||||
u32 suspen_itv;
|
|
||||||
u32 service_start_time;
|
|
||||||
u32 min_data_rate;
|
|
||||||
u32 mean_data_rate;
|
|
||||||
u32 peak_data_rate;
|
|
||||||
u32 max_burst_size;
|
|
||||||
u32 delay_bound;
|
|
||||||
u32 min_phy_rate;
|
|
||||||
u16 surplus_bandwidth_allowance;
|
|
||||||
u16 medium_time;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 802.11 Management frame Status Code field
|
|
||||||
*/
|
|
||||||
struct octet_string {
|
|
||||||
u8 *octet;
|
|
||||||
u16 length;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define is_ac_valid(ac) (((ac) <= 7) ? true : false)
|
|
||||||
|
|
||||||
#endif // #ifndef __INC_QOS_TYPE_H
|
|
@ -1,102 +0,0 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
#ifndef _TSTYPE_H_
|
|
||||||
#define _TSTYPE_H_
|
|
||||||
#include "rtl819x_Qos.h"
|
|
||||||
|
|
||||||
#define TS_ADDBA_DELAY 60
|
|
||||||
|
|
||||||
#define TOTAL_TS_NUM 16
|
|
||||||
#define TCLAS_NUM 4
|
|
||||||
|
|
||||||
/* This define the Tx/Rx directions */
|
|
||||||
enum tr_select {
|
|
||||||
TX_DIR = 0,
|
|
||||||
RX_DIR = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
union qos_tclas {
|
|
||||||
struct type_general {
|
|
||||||
u8 priority;
|
|
||||||
u8 classifier_type;
|
|
||||||
u8 mask;
|
|
||||||
} type_general;
|
|
||||||
|
|
||||||
struct type0_eth {
|
|
||||||
u8 priority;
|
|
||||||
u8 classifier_type;
|
|
||||||
u8 mask;
|
|
||||||
u8 src_addr[6];
|
|
||||||
u8 dst_addr[6];
|
|
||||||
u16 type;
|
|
||||||
} type0_eth;
|
|
||||||
|
|
||||||
struct type1_ipv4 {
|
|
||||||
u8 priority;
|
|
||||||
u8 classifier_type;
|
|
||||||
u8 mask;
|
|
||||||
u8 version;
|
|
||||||
u8 src_ip[4];
|
|
||||||
u8 dst_ip[4];
|
|
||||||
u16 src_port;
|
|
||||||
u16 dst_port;
|
|
||||||
u8 dscp;
|
|
||||||
u8 protocol;
|
|
||||||
u8 reserved;
|
|
||||||
} type1_ipv4;
|
|
||||||
|
|
||||||
struct type1_ipv6 {
|
|
||||||
u8 priority;
|
|
||||||
u8 classifier_type;
|
|
||||||
u8 mask;
|
|
||||||
u8 version;
|
|
||||||
u8 src_ip[16];
|
|
||||||
u8 dst_ip[16];
|
|
||||||
u16 src_port;
|
|
||||||
u16 dst_port;
|
|
||||||
u8 flow_label[3];
|
|
||||||
} type1_ipv6;
|
|
||||||
|
|
||||||
struct type2_8021q {
|
|
||||||
u8 priority;
|
|
||||||
u8 classifier_type;
|
|
||||||
u8 mask;
|
|
||||||
u16 tag_type;
|
|
||||||
} type2_8021q;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ts_common_info {
|
|
||||||
struct list_head list;
|
|
||||||
struct timer_list setup_timer;
|
|
||||||
struct timer_list inact_timer;
|
|
||||||
u8 addr[6];
|
|
||||||
struct tspec_body t_spec;
|
|
||||||
union qos_tclas t_class[TCLAS_NUM];
|
|
||||||
u8 t_clas_proc;
|
|
||||||
u8 t_clas_num;
|
|
||||||
};
|
|
||||||
|
|
||||||
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;
|
|
||||||
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
|
|
@ -1,534 +0,0 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0
|
|
||||||
#include "ieee80211.h"
|
|
||||||
#include <linux/etherdevice.h>
|
|
||||||
#include <linux/slab.h>
|
|
||||||
#include "rtl819x_TS.h"
|
|
||||||
|
|
||||||
static void TsSetupTimeOut(struct timer_list *unused)
|
|
||||||
{
|
|
||||||
// Not implement yet
|
|
||||||
// This is used for WMMSA and ACM , that would send ADDTSReq frame.
|
|
||||||
}
|
|
||||||
|
|
||||||
static void TsInactTimeout(struct timer_list *unused)
|
|
||||||
{
|
|
||||||
// Not implement yet
|
|
||||||
// This is used for WMMSA and ACM.
|
|
||||||
// This function would be call when TS is no Tx/Rx for some period of time.
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************************************************************
|
|
||||||
*function: I still not understand this function, so wait for further implementation
|
|
||||||
* input: unsigned long data //acturally we send struct tx_ts_record or struct rx_ts_record to these timer
|
|
||||||
* return: NULL
|
|
||||||
* notice:
|
|
||||||
********************************************************************************************************************/
|
|
||||||
static void RxPktPendingTimeout(struct timer_list *t)
|
|
||||||
{
|
|
||||||
struct rx_ts_record *pRxTs = from_timer(pRxTs, t, rx_pkt_pending_timer);
|
|
||||||
struct ieee80211_device *ieee = container_of(pRxTs, struct ieee80211_device, RxTsRecord[pRxTs->num]);
|
|
||||||
|
|
||||||
struct rx_reorder_entry *pReorderEntry = NULL;
|
|
||||||
|
|
||||||
//u32 flags = 0;
|
|
||||||
unsigned long flags = 0;
|
|
||||||
u8 index = 0;
|
|
||||||
bool bPktInBuf = false;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&(ieee->reorder_spinlock), flags);
|
|
||||||
IEEE80211_DEBUG(IEEE80211_DL_REORDER, "==================>%s()\n", __func__);
|
|
||||||
if (pRxTs->rx_timeout_indicate_seq != 0xffff) {
|
|
||||||
// Indicate the pending packets sequentially according to SeqNum until meet the gap.
|
|
||||||
while (!list_empty(&pRxTs->rx_pending_pkt_list)) {
|
|
||||||
pReorderEntry = list_entry(pRxTs->rx_pending_pkt_list.prev, struct rx_reorder_entry, List);
|
|
||||||
if (index == 0)
|
|
||||||
pRxTs->rx_indicate_seq = pReorderEntry->SeqNum;
|
|
||||||
|
|
||||||
if (SN_LESS(pReorderEntry->SeqNum, pRxTs->rx_indicate_seq) ||
|
|
||||||
SN_EQUAL(pReorderEntry->SeqNum, pRxTs->rx_indicate_seq)) {
|
|
||||||
list_del_init(&pReorderEntry->List);
|
|
||||||
|
|
||||||
if (SN_EQUAL(pReorderEntry->SeqNum, pRxTs->rx_indicate_seq))
|
|
||||||
pRxTs->rx_indicate_seq = (pRxTs->rx_indicate_seq + 1) % 4096;
|
|
||||||
|
|
||||||
IEEE80211_DEBUG(IEEE80211_DL_REORDER, "%s: IndicateSeq: %d\n", __func__, pReorderEntry->SeqNum);
|
|
||||||
ieee->stats_IndicateArray[index] = pReorderEntry->prxb;
|
|
||||||
index++;
|
|
||||||
|
|
||||||
list_add_tail(&pReorderEntry->List, &ieee->RxReorder_Unused_List);
|
|
||||||
} else {
|
|
||||||
bPktInBuf = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index > 0) {
|
|
||||||
// Set rx_timeout_indicate_seq to 0xffff to indicate no pending packets in buffer now.
|
|
||||||
pRxTs->rx_timeout_indicate_seq = 0xffff;
|
|
||||||
|
|
||||||
// Indicate packets
|
|
||||||
if (index > REORDER_WIN_SIZE) {
|
|
||||||
IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): Rx Reorder buffer full!! \n");
|
|
||||||
spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ieee80211_indicate_packets(ieee, ieee->stats_IndicateArray, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bPktInBuf && (pRxTs->rx_timeout_indicate_seq == 0xffff)) {
|
|
||||||
pRxTs->rx_timeout_indicate_seq = pRxTs->rx_indicate_seq;
|
|
||||||
mod_timer(&pRxTs->rx_pkt_pending_timer,
|
|
||||||
jiffies + msecs_to_jiffies(ieee->pHTInfo->RxReorderPendingTime));
|
|
||||||
}
|
|
||||||
spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************************************************************
|
|
||||||
*function: Add BA timer function
|
|
||||||
* input: unsigned long data //acturally we send struct tx_ts_record or struct rx_ts_record to these timer
|
|
||||||
* return: NULL
|
|
||||||
* notice:
|
|
||||||
********************************************************************************************************************/
|
|
||||||
static void TsAddBaProcess(struct timer_list *t)
|
|
||||||
{
|
|
||||||
struct tx_ts_record *pTxTs = from_timer(pTxTs, t, ts_add_ba_timer);
|
|
||||||
u8 num = pTxTs->num;
|
|
||||||
struct ieee80211_device *ieee = container_of(pTxTs, struct ieee80211_device, TxTsRecord[num]);
|
|
||||||
|
|
||||||
TsInitAddBA(ieee, pTxTs, BA_POLICY_IMMEDIATE, false);
|
|
||||||
IEEE80211_DEBUG(IEEE80211_DL_BA, "%s: ADDBA Req is started!! \n", __func__);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void ResetTsCommonInfo(struct ts_common_info *pTsCommonInfo)
|
|
||||||
{
|
|
||||||
eth_zero_addr(pTsCommonInfo->addr);
|
|
||||||
memset(&pTsCommonInfo->t_spec, 0, sizeof(struct tspec_body));
|
|
||||||
memset(&pTsCommonInfo->t_class, 0, sizeof(union qos_tclas) * TCLAS_NUM);
|
|
||||||
pTsCommonInfo->t_clas_proc = 0;
|
|
||||||
pTsCommonInfo->t_clas_num = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ResetTxTsEntry(struct tx_ts_record *pTS)
|
|
||||||
{
|
|
||||||
ResetTsCommonInfo(&pTS->ts_common_info);
|
|
||||||
pTS->tx_cur_seq = 0;
|
|
||||||
pTS->add_ba_req_in_progress = false;
|
|
||||||
pTS->add_ba_req_delayed = false;
|
|
||||||
pTS->using_ba = false;
|
|
||||||
ResetBaEntry(&pTS->tx_admitted_ba_record); //For BA Originator
|
|
||||||
ResetBaEntry(&pTS->tx_pending_ba_record);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ResetRxTsEntry(struct rx_ts_record *pTS)
|
|
||||||
{
|
|
||||||
ResetTsCommonInfo(&pTS->ts_common_info);
|
|
||||||
pTS->rx_indicate_seq = 0xffff; // This indicate the rx_indicate_seq is not used now!!
|
|
||||||
pTS->rx_timeout_indicate_seq = 0xffff; // This indicate the rx_timeout_indicate_seq is not used now!!
|
|
||||||
ResetBaEntry(&pTS->rx_admitted_ba_record); // For BA Recipient
|
|
||||||
}
|
|
||||||
|
|
||||||
void TSInitialize(struct ieee80211_device *ieee)
|
|
||||||
{
|
|
||||||
struct tx_ts_record *pTxTS = ieee->TxTsRecord;
|
|
||||||
struct rx_ts_record *pRxTS = ieee->RxTsRecord;
|
|
||||||
struct rx_reorder_entry *pRxReorderEntry = ieee->RxReorderEntry;
|
|
||||||
u8 count = 0;
|
|
||||||
IEEE80211_DEBUG(IEEE80211_DL_TS, "==========>%s()\n", __func__);
|
|
||||||
// Initialize Tx TS related info.
|
|
||||||
INIT_LIST_HEAD(&ieee->Tx_TS_Admit_List);
|
|
||||||
INIT_LIST_HEAD(&ieee->Tx_TS_Pending_List);
|
|
||||||
INIT_LIST_HEAD(&ieee->Tx_TS_Unused_List);
|
|
||||||
|
|
||||||
for (count = 0; count < TOTAL_TS_NUM; count++) {
|
|
||||||
//
|
|
||||||
pTxTS->num = count;
|
|
||||||
// The timers for the operation of Traffic Stream and Block Ack.
|
|
||||||
// DLS related timer will be add here in the future!!
|
|
||||||
timer_setup(&pTxTS->ts_common_info.setup_timer, TsSetupTimeOut,
|
|
||||||
0);
|
|
||||||
timer_setup(&pTxTS->ts_common_info.inact_timer, TsInactTimeout,
|
|
||||||
0);
|
|
||||||
timer_setup(&pTxTS->ts_add_ba_timer, TsAddBaProcess, 0);
|
|
||||||
timer_setup(&pTxTS->tx_pending_ba_record.timer, BaSetupTimeOut,
|
|
||||||
0);
|
|
||||||
timer_setup(&pTxTS->tx_admitted_ba_record.timer,
|
|
||||||
TxBaInactTimeout, 0);
|
|
||||||
ResetTxTsEntry(pTxTS);
|
|
||||||
list_add_tail(&pTxTS->ts_common_info.list, &ieee->Tx_TS_Unused_List);
|
|
||||||
pTxTS++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize Rx TS related info.
|
|
||||||
INIT_LIST_HEAD(&ieee->Rx_TS_Admit_List);
|
|
||||||
INIT_LIST_HEAD(&ieee->Rx_TS_Pending_List);
|
|
||||||
INIT_LIST_HEAD(&ieee->Rx_TS_Unused_List);
|
|
||||||
for (count = 0; count < TOTAL_TS_NUM; count++) {
|
|
||||||
pRxTS->num = count;
|
|
||||||
INIT_LIST_HEAD(&pRxTS->rx_pending_pkt_list);
|
|
||||||
timer_setup(&pRxTS->ts_common_info.setup_timer, TsSetupTimeOut,
|
|
||||||
0);
|
|
||||||
timer_setup(&pRxTS->ts_common_info.inact_timer, TsInactTimeout,
|
|
||||||
0);
|
|
||||||
timer_setup(&pRxTS->rx_admitted_ba_record.timer,
|
|
||||||
RxBaInactTimeout, 0);
|
|
||||||
timer_setup(&pRxTS->rx_pkt_pending_timer, RxPktPendingTimeout, 0);
|
|
||||||
ResetRxTsEntry(pRxTS);
|
|
||||||
list_add_tail(&pRxTS->ts_common_info.list, &ieee->Rx_TS_Unused_List);
|
|
||||||
pRxTS++;
|
|
||||||
}
|
|
||||||
// Initialize unused Rx Reorder List.
|
|
||||||
INIT_LIST_HEAD(&ieee->RxReorder_Unused_List);
|
|
||||||
for (count = 0; count < REORDER_ENTRY_NUM; count++) {
|
|
||||||
list_add_tail(&pRxReorderEntry->List, &ieee->RxReorder_Unused_List);
|
|
||||||
if (count == (REORDER_ENTRY_NUM - 1))
|
|
||||||
break;
|
|
||||||
pRxReorderEntry = &ieee->RxReorderEntry[count + 1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void AdmitTS(struct ieee80211_device *ieee,
|
|
||||||
struct ts_common_info *pTsCommonInfo, u32 InactTime)
|
|
||||||
{
|
|
||||||
del_timer_sync(&pTsCommonInfo->setup_timer);
|
|
||||||
del_timer_sync(&pTsCommonInfo->inact_timer);
|
|
||||||
|
|
||||||
if (InactTime != 0)
|
|
||||||
mod_timer(&pTsCommonInfo->inact_timer,
|
|
||||||
jiffies + msecs_to_jiffies(InactTime));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static struct ts_common_info *SearchAdmitTRStream(struct ieee80211_device *ieee,
|
|
||||||
u8 *Addr, u8 TID,
|
|
||||||
enum tr_select TxRxSelect)
|
|
||||||
{
|
|
||||||
//DIRECTION_VALUE dir;
|
|
||||||
u8 dir;
|
|
||||||
bool search_dir[4] = {0};
|
|
||||||
struct list_head *psearch_list; //FIXME
|
|
||||||
struct ts_common_info *pRet = NULL;
|
|
||||||
if (ieee->iw_mode == IW_MODE_MASTER) { //ap mode
|
|
||||||
if (TxRxSelect == TX_DIR) {
|
|
||||||
search_dir[DIR_DOWN] = true;
|
|
||||||
search_dir[DIR_BI_DIR] = true;
|
|
||||||
} else {
|
|
||||||
search_dir[DIR_UP] = true;
|
|
||||||
search_dir[DIR_BI_DIR] = true;
|
|
||||||
}
|
|
||||||
} else if (ieee->iw_mode == IW_MODE_ADHOC) {
|
|
||||||
if (TxRxSelect == TX_DIR)
|
|
||||||
search_dir[DIR_UP] = true;
|
|
||||||
else
|
|
||||||
search_dir[DIR_DOWN] = true;
|
|
||||||
} else {
|
|
||||||
if (TxRxSelect == TX_DIR) {
|
|
||||||
search_dir[DIR_UP] = true;
|
|
||||||
search_dir[DIR_BI_DIR] = true;
|
|
||||||
search_dir[DIR_DIRECT] = true;
|
|
||||||
} else {
|
|
||||||
search_dir[DIR_DOWN] = true;
|
|
||||||
search_dir[DIR_BI_DIR] = true;
|
|
||||||
search_dir[DIR_DIRECT] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TxRxSelect == TX_DIR)
|
|
||||||
psearch_list = &ieee->Tx_TS_Admit_List;
|
|
||||||
else
|
|
||||||
psearch_list = &ieee->Rx_TS_Admit_List;
|
|
||||||
|
|
||||||
//for(dir = DIR_UP; dir <= DIR_BI_DIR; dir++)
|
|
||||||
for (dir = 0; dir <= DIR_BI_DIR; dir++) {
|
|
||||||
if (!search_dir[dir])
|
|
||||||
continue;
|
|
||||||
list_for_each_entry(pRet, psearch_list, list) {
|
|
||||||
// IEEE80211_DEBUG(IEEE80211_DL_TS, "ADD:%pM, TID:%d, dir:%d\n", pRet->Addr, pRet->TSpec.ts_info.ucTSID, pRet->TSpec.ts_info.ucDirection);
|
|
||||||
if (memcmp(pRet->addr, Addr, 6) == 0)
|
|
||||||
if (pRet->t_spec.ts_info.uc_tsid == TID)
|
|
||||||
if (pRet->t_spec.ts_info.uc_direction == dir) {
|
|
||||||
// printk("Bingo! got it\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (&pRet->list != psearch_list)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (&pRet->list != psearch_list)
|
|
||||||
return pRet;
|
|
||||||
else
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void MakeTSEntry(struct ts_common_info *pTsCommonInfo, u8 *Addr,
|
|
||||||
struct tspec_body *pTSPEC, union qos_tclas *pTCLAS, u8 TCLAS_Num,
|
|
||||||
u8 TCLAS_Proc)
|
|
||||||
{
|
|
||||||
u8 count;
|
|
||||||
|
|
||||||
if (pTsCommonInfo == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
memcpy(pTsCommonInfo->addr, Addr, 6);
|
|
||||||
|
|
||||||
if (pTSPEC != NULL)
|
|
||||||
memcpy((u8 *)(&(pTsCommonInfo->t_spec)), (u8 *)pTSPEC, sizeof(struct tspec_body));
|
|
||||||
|
|
||||||
for (count = 0; count < TCLAS_Num; count++)
|
|
||||||
memcpy((u8 *)(&(pTsCommonInfo->t_class[count])), (u8 *)pTCLAS, sizeof(union qos_tclas));
|
|
||||||
|
|
||||||
pTsCommonInfo->t_clas_proc = TCLAS_Proc;
|
|
||||||
pTsCommonInfo->t_clas_num = TCLAS_Num;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool GetTs(
|
|
||||||
struct ieee80211_device *ieee,
|
|
||||||
struct ts_common_info **ppTS,
|
|
||||||
u8 *Addr,
|
|
||||||
u8 TID,
|
|
||||||
enum tr_select TxRxSelect, //Rx:1, Tx:0
|
|
||||||
bool bAddNewTs
|
|
||||||
)
|
|
||||||
{
|
|
||||||
u8 UP = 0;
|
|
||||||
//
|
|
||||||
// We do not build any TS for Broadcast or Multicast stream.
|
|
||||||
// So reject these kinds of search here.
|
|
||||||
//
|
|
||||||
if (is_multicast_ether_addr(Addr)) {
|
|
||||||
IEEE80211_DEBUG(IEEE80211_DL_ERR, "get TS for Broadcast or Multicast\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ieee->current_network.qos_data.supported == 0) {
|
|
||||||
UP = 0;
|
|
||||||
} else {
|
|
||||||
// In WMM case: we use 4 TID only
|
|
||||||
if (!is_ac_valid(TID)) {
|
|
||||||
IEEE80211_DEBUG(IEEE80211_DL_ERR, " in %s(), TID(%d) is not valid\n", __func__, TID);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (TID) {
|
|
||||||
case 0:
|
|
||||||
case 3:
|
|
||||||
UP = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
case 2:
|
|
||||||
UP = 2;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 4:
|
|
||||||
case 5:
|
|
||||||
UP = 5;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 6:
|
|
||||||
case 7:
|
|
||||||
UP = 7;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*ppTS = SearchAdmitTRStream(
|
|
||||||
ieee,
|
|
||||||
Addr,
|
|
||||||
UP,
|
|
||||||
TxRxSelect);
|
|
||||||
if (*ppTS != NULL) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
if (!bAddNewTs) {
|
|
||||||
IEEE80211_DEBUG(IEEE80211_DL_TS, "add new TS failed(tid:%d)\n", UP);
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
//
|
|
||||||
// Create a new Traffic stream for current Tx/Rx
|
|
||||||
// This is for EDCA and WMM to add a new TS.
|
|
||||||
// For HCCA or WMMSA, TS cannot be addmit without negotiation.
|
|
||||||
//
|
|
||||||
struct tspec_body TSpec;
|
|
||||||
struct qos_tsinfo *pTSInfo = &TSpec.ts_info;
|
|
||||||
struct list_head *pUnusedList =
|
|
||||||
(TxRxSelect == TX_DIR) ?
|
|
||||||
(&ieee->Tx_TS_Unused_List) :
|
|
||||||
(&ieee->Rx_TS_Unused_List);
|
|
||||||
|
|
||||||
struct list_head *pAddmitList =
|
|
||||||
(TxRxSelect == TX_DIR) ?
|
|
||||||
(&ieee->Tx_TS_Admit_List) :
|
|
||||||
(&ieee->Rx_TS_Admit_List);
|
|
||||||
|
|
||||||
enum direction_value Dir = (ieee->iw_mode == IW_MODE_MASTER) ?
|
|
||||||
((TxRxSelect == TX_DIR) ? DIR_DOWN : DIR_UP) :
|
|
||||||
((TxRxSelect == TX_DIR) ? DIR_UP : DIR_DOWN);
|
|
||||||
IEEE80211_DEBUG(IEEE80211_DL_TS, "to add Ts\n");
|
|
||||||
if (!list_empty(pUnusedList)) {
|
|
||||||
(*ppTS) = list_entry(pUnusedList->next, struct ts_common_info, list);
|
|
||||||
list_del_init(&(*ppTS)->list);
|
|
||||||
if (TxRxSelect == TX_DIR) {
|
|
||||||
struct tx_ts_record *tmp = container_of(*ppTS, struct tx_ts_record, ts_common_info);
|
|
||||||
ResetTxTsEntry(tmp);
|
|
||||||
} else {
|
|
||||||
struct rx_ts_record *tmp = container_of(*ppTS, struct rx_ts_record, ts_common_info);
|
|
||||||
ResetRxTsEntry(tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
IEEE80211_DEBUG(IEEE80211_DL_TS, "to init current TS, UP:%d, Dir:%d, addr:%pM\n", UP, Dir, Addr);
|
|
||||||
// Prepare TS Info related field
|
|
||||||
pTSInfo->uc_traffic_type = 0; // Traffic type: WMM is reserved in this field
|
|
||||||
pTSInfo->uc_tsid = UP; // TSID
|
|
||||||
pTSInfo->uc_direction = Dir; // Direction: if there is DirectLink, this need additional consideration.
|
|
||||||
pTSInfo->uc_access_policy = 1; // Access policy
|
|
||||||
pTSInfo->uc_aggregation = 0; // Aggregation
|
|
||||||
pTSInfo->uc_psb = 0; // Aggregation
|
|
||||||
pTSInfo->uc_up = UP; // User priority
|
|
||||||
pTSInfo->uc_ts_info_ack_policy = 0; // Ack policy
|
|
||||||
pTSInfo->uc_schedule = 0; // Schedule
|
|
||||||
|
|
||||||
MakeTSEntry(*ppTS, Addr, &TSpec, NULL, 0, 0);
|
|
||||||
AdmitTS(ieee, *ppTS, 0);
|
|
||||||
list_add_tail(&((*ppTS)->list), pAddmitList);
|
|
||||||
// if there is DirectLink, we need to do additional operation here!!
|
|
||||||
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
IEEE80211_DEBUG(IEEE80211_DL_ERR, "in function %s() There is not enough TS record to be used!!", __func__);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void RemoveTsEntry(struct ieee80211_device *ieee, struct ts_common_info *pTs,
|
|
||||||
enum tr_select TxRxSelect)
|
|
||||||
{
|
|
||||||
//u32 flags = 0;
|
|
||||||
unsigned long flags = 0;
|
|
||||||
del_timer_sync(&pTs->setup_timer);
|
|
||||||
del_timer_sync(&pTs->inact_timer);
|
|
||||||
TsInitDelBA(ieee, pTs, TxRxSelect);
|
|
||||||
|
|
||||||
if (TxRxSelect == RX_DIR) {
|
|
||||||
struct rx_reorder_entry *pRxReorderEntry;
|
|
||||||
struct rx_ts_record *pRxTS = (struct rx_ts_record *)pTs;
|
|
||||||
if (timer_pending(&pRxTS->rx_pkt_pending_timer))
|
|
||||||
del_timer_sync(&pRxTS->rx_pkt_pending_timer);
|
|
||||||
|
|
||||||
while (!list_empty(&pRxTS->rx_pending_pkt_list)) {
|
|
||||||
spin_lock_irqsave(&(ieee->reorder_spinlock), flags);
|
|
||||||
//pRxReorderEntry = list_entry(&pRxTS->rx_pending_pkt_list.prev,RX_REORDER_ENTRY,List);
|
|
||||||
pRxReorderEntry = list_entry(pRxTS->rx_pending_pkt_list.prev, struct rx_reorder_entry, List);
|
|
||||||
list_del_init(&pRxReorderEntry->List);
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
struct ieee80211_rxb *prxb = pRxReorderEntry->prxb;
|
|
||||||
if (unlikely(!prxb)) {
|
|
||||||
spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (i = 0; i < prxb->nr_subframes; i++)
|
|
||||||
dev_kfree_skb(prxb->subframes[i]);
|
|
||||||
|
|
||||||
kfree(prxb);
|
|
||||||
prxb = NULL;
|
|
||||||
}
|
|
||||||
list_add_tail(&pRxReorderEntry->List, &ieee->RxReorder_Unused_List);
|
|
||||||
spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
struct tx_ts_record *pTxTS = (struct tx_ts_record *)pTs;
|
|
||||||
del_timer_sync(&pTxTS->ts_add_ba_timer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RemovePeerTS(struct ieee80211_device *ieee, u8 *Addr)
|
|
||||||
{
|
|
||||||
struct ts_common_info *pTS, *pTmpTS;
|
|
||||||
|
|
||||||
printk("===========>%s,%pM\n", __func__, Addr);
|
|
||||||
list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, list) {
|
|
||||||
if (memcmp(pTS->addr, Addr, 6) == 0) {
|
|
||||||
RemoveTsEntry(ieee, pTS, TX_DIR);
|
|
||||||
list_del_init(&pTS->list);
|
|
||||||
list_add_tail(&pTS->list, &ieee->Tx_TS_Unused_List);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Admit_List, list) {
|
|
||||||
if (memcmp(pTS->addr, Addr, 6) == 0) {
|
|
||||||
printk("====>remove Tx_TS_admin_list\n");
|
|
||||||
RemoveTsEntry(ieee, pTS, TX_DIR);
|
|
||||||
list_del_init(&pTS->list);
|
|
||||||
list_add_tail(&pTS->list, &ieee->Tx_TS_Unused_List);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Pending_List, list) {
|
|
||||||
if (memcmp(pTS->addr, Addr, 6) == 0) {
|
|
||||||
RemoveTsEntry(ieee, pTS, RX_DIR);
|
|
||||||
list_del_init(&pTS->list);
|
|
||||||
list_add_tail(&pTS->list, &ieee->Rx_TS_Unused_List);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Admit_List, list) {
|
|
||||||
if (memcmp(pTS->addr, Addr, 6) == 0) {
|
|
||||||
RemoveTsEntry(ieee, pTS, RX_DIR);
|
|
||||||
list_del_init(&pTS->list);
|
|
||||||
list_add_tail(&pTS->list, &ieee->Rx_TS_Unused_List);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RemoveAllTS(struct ieee80211_device *ieee)
|
|
||||||
{
|
|
||||||
struct ts_common_info *pTS, *pTmpTS;
|
|
||||||
|
|
||||||
list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, list) {
|
|
||||||
RemoveTsEntry(ieee, pTS, TX_DIR);
|
|
||||||
list_del_init(&pTS->list);
|
|
||||||
list_add_tail(&pTS->list, &ieee->Tx_TS_Unused_List);
|
|
||||||
}
|
|
||||||
|
|
||||||
list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Admit_List, list) {
|
|
||||||
RemoveTsEntry(ieee, pTS, TX_DIR);
|
|
||||||
list_del_init(&pTS->list);
|
|
||||||
list_add_tail(&pTS->list, &ieee->Tx_TS_Unused_List);
|
|
||||||
}
|
|
||||||
|
|
||||||
list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Pending_List, list) {
|
|
||||||
RemoveTsEntry(ieee, pTS, RX_DIR);
|
|
||||||
list_del_init(&pTS->list);
|
|
||||||
list_add_tail(&pTS->list, &ieee->Rx_TS_Unused_List);
|
|
||||||
}
|
|
||||||
|
|
||||||
list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Admit_List, list) {
|
|
||||||
RemoveTsEntry(ieee, pTS, RX_DIR);
|
|
||||||
list_del_init(&pTS->list);
|
|
||||||
list_add_tail(&pTS->list, &ieee->Rx_TS_Unused_List);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TsStartAddBaProcess(struct ieee80211_device *ieee, struct tx_ts_record *pTxTS)
|
|
||||||
{
|
|
||||||
if (!pTxTS->add_ba_req_in_progress) {
|
|
||||||
pTxTS->add_ba_req_in_progress = true;
|
|
||||||
if (pTxTS->add_ba_req_delayed) {
|
|
||||||
IEEE80211_DEBUG(IEEE80211_DL_BA, "%s: Delayed Start ADDBA after 60 sec!!\n", __func__);
|
|
||||||
mod_timer(&pTxTS->ts_add_ba_timer,
|
|
||||||
jiffies + msecs_to_jiffies(TS_ADDBA_DELAY));
|
|
||||||
} else {
|
|
||||||
IEEE80211_DEBUG(IEEE80211_DL_BA, "%s: Immediately Start ADDBA now!!\n", __func__);
|
|
||||||
mod_timer(&pTxTS->ts_add_ba_timer, jiffies + 10); //set 10 ticks
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
IEEE80211_DEBUG(IEEE80211_DL_ERR, "%s()==>BA timer is already added\n", __func__);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,170 +0,0 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0
|
|
||||||
/*
|
|
||||||
* This files contains card eeprom (93c46 or 93c56) programming routines,
|
|
||||||
* memory is addressed by 16 bits words.
|
|
||||||
*
|
|
||||||
* This is part of rtl8180 OpenSource driver.
|
|
||||||
* Copyright (C) Andrea Merello 2004 <andrea.merello@gmail.com>
|
|
||||||
*
|
|
||||||
* Parts of this driver are based on the GPL part of the
|
|
||||||
* official realtek driver.
|
|
||||||
*
|
|
||||||
* Parts of this driver are based on the rtl8180 driver skeleton
|
|
||||||
* from Patric Schenke & Andres Salomon.
|
|
||||||
*
|
|
||||||
* Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
|
|
||||||
*
|
|
||||||
* We want to thank the Authors of those projects and the Ndiswrapper
|
|
||||||
* project Authors.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "r8180_93cx6.h"
|
|
||||||
|
|
||||||
static void eprom_cs(struct net_device *dev, short bit)
|
|
||||||
{
|
|
||||||
u8 cmdreg;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
err = read_nic_byte_E(dev, EPROM_CMD, &cmdreg);
|
|
||||||
if (err)
|
|
||||||
return;
|
|
||||||
if (bit)
|
|
||||||
/* enable EPROM */
|
|
||||||
write_nic_byte_E(dev, EPROM_CMD, cmdreg | EPROM_CS_BIT);
|
|
||||||
else
|
|
||||||
/* disable EPROM */
|
|
||||||
write_nic_byte_E(dev, EPROM_CMD, cmdreg & ~EPROM_CS_BIT);
|
|
||||||
|
|
||||||
force_pci_posting(dev);
|
|
||||||
udelay(EPROM_DELAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void eprom_ck_cycle(struct net_device *dev)
|
|
||||||
{
|
|
||||||
u8 cmdreg;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
err = read_nic_byte_E(dev, EPROM_CMD, &cmdreg);
|
|
||||||
if (err)
|
|
||||||
return;
|
|
||||||
write_nic_byte_E(dev, EPROM_CMD, cmdreg | EPROM_CK_BIT);
|
|
||||||
force_pci_posting(dev);
|
|
||||||
udelay(EPROM_DELAY);
|
|
||||||
|
|
||||||
read_nic_byte_E(dev, EPROM_CMD, &cmdreg);
|
|
||||||
write_nic_byte_E(dev, EPROM_CMD, cmdreg & ~EPROM_CK_BIT);
|
|
||||||
force_pci_posting(dev);
|
|
||||||
udelay(EPROM_DELAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void eprom_w(struct net_device *dev, short bit)
|
|
||||||
{
|
|
||||||
u8 cmdreg;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
err = read_nic_byte_E(dev, EPROM_CMD, &cmdreg);
|
|
||||||
if (err)
|
|
||||||
return;
|
|
||||||
if (bit)
|
|
||||||
write_nic_byte_E(dev, EPROM_CMD, cmdreg | EPROM_W_BIT);
|
|
||||||
else
|
|
||||||
write_nic_byte_E(dev, EPROM_CMD, cmdreg & ~EPROM_W_BIT);
|
|
||||||
|
|
||||||
force_pci_posting(dev);
|
|
||||||
udelay(EPROM_DELAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
static short eprom_r(struct net_device *dev)
|
|
||||||
{
|
|
||||||
u8 bit;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
err = read_nic_byte_E(dev, EPROM_CMD, &bit);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
udelay(EPROM_DELAY);
|
|
||||||
|
|
||||||
if (bit & EPROM_R_BIT)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void eprom_send_bits_string(struct net_device *dev, short b[], int len)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < len; i++) {
|
|
||||||
eprom_w(dev, b[i]);
|
|
||||||
eprom_ck_cycle(dev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int eprom_read(struct net_device *dev, u32 addr)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
short read_cmd[] = {1, 1, 0};
|
|
||||||
short addr_str[8];
|
|
||||||
int i;
|
|
||||||
int addr_len;
|
|
||||||
u32 ret;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
ret = 0;
|
|
||||||
/* enable EPROM programming */
|
|
||||||
write_nic_byte_E(dev, EPROM_CMD,
|
|
||||||
(EPROM_CMD_PROGRAM << EPROM_CMD_OPERATING_MODE_SHIFT));
|
|
||||||
force_pci_posting(dev);
|
|
||||||
udelay(EPROM_DELAY);
|
|
||||||
|
|
||||||
if (priv->epromtype == EPROM_93c56) {
|
|
||||||
addr_str[7] = addr & 1;
|
|
||||||
addr_str[6] = addr & BIT(1);
|
|
||||||
addr_str[5] = addr & BIT(2);
|
|
||||||
addr_str[4] = addr & BIT(3);
|
|
||||||
addr_str[3] = addr & BIT(4);
|
|
||||||
addr_str[2] = addr & BIT(5);
|
|
||||||
addr_str[1] = addr & BIT(6);
|
|
||||||
addr_str[0] = addr & BIT(7);
|
|
||||||
addr_len = 8;
|
|
||||||
} else {
|
|
||||||
addr_str[5] = addr & 1;
|
|
||||||
addr_str[4] = addr & BIT(1);
|
|
||||||
addr_str[3] = addr & BIT(2);
|
|
||||||
addr_str[2] = addr & BIT(3);
|
|
||||||
addr_str[1] = addr & BIT(4);
|
|
||||||
addr_str[0] = addr & BIT(5);
|
|
||||||
addr_len = 6;
|
|
||||||
}
|
|
||||||
eprom_cs(dev, 1);
|
|
||||||
eprom_ck_cycle(dev);
|
|
||||||
eprom_send_bits_string(dev, read_cmd, 3);
|
|
||||||
eprom_send_bits_string(dev, addr_str, addr_len);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* keep chip pin D to low state while reading.
|
|
||||||
* I'm unsure if it is necessary, but anyway shouldn't hurt
|
|
||||||
*/
|
|
||||||
eprom_w(dev, 0);
|
|
||||||
|
|
||||||
for (i = 0; i < 16; i++) {
|
|
||||||
/* eeprom needs a clk cycle between writing opcode&adr
|
|
||||||
* and reading data. (eeprom outs a dummy 0)
|
|
||||||
*/
|
|
||||||
eprom_ck_cycle(dev);
|
|
||||||
err = eprom_r(dev);
|
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
ret |= err << (15 - i);
|
|
||||||
}
|
|
||||||
|
|
||||||
eprom_cs(dev, 0);
|
|
||||||
eprom_ck_cycle(dev);
|
|
||||||
|
|
||||||
/* disable EPROM programming */
|
|
||||||
write_nic_byte_E(dev, EPROM_CMD,
|
|
||||||
(EPROM_CMD_NORMAL << EPROM_CMD_OPERATING_MODE_SHIFT));
|
|
||||||
return ret;
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
/*
|
|
||||||
* This is part of rtl8187 OpenSource driver
|
|
||||||
* Copyright (C) Andrea Merello 2004-2005 <andrea.merello@gmail.com>
|
|
||||||
* Released under the terms of GPL (General Public Licence)
|
|
||||||
*
|
|
||||||
* Parts of this driver are based on the GPL part of the
|
|
||||||
* official realtek driver
|
|
||||||
* Parts of this driver are based on the rtl8180 driver skeleton
|
|
||||||
* from Patric Schenke & Andres Salomon
|
|
||||||
* Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
|
|
||||||
*
|
|
||||||
* We want to thank the Authors of such projects and the Ndiswrapper
|
|
||||||
* project Authors.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*This files contains card eeprom (93c46 or 93c56) programming routines*/
|
|
||||||
/*memory is addressed by WORDS*/
|
|
||||||
|
|
||||||
#include "r8192U.h"
|
|
||||||
#include "r8192U_hw.h"
|
|
||||||
|
|
||||||
#define EPROM_DELAY 10
|
|
||||||
|
|
||||||
int eprom_read(struct net_device *dev, u32 addr); /* reads a 16 bits word */
|
|
@ -1,294 +0,0 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0
|
|
||||||
/*
|
|
||||||
* This is part of the rtl8192 driver
|
|
||||||
*
|
|
||||||
* This files contains programming code for the rtl8256
|
|
||||||
* radio frontend.
|
|
||||||
*
|
|
||||||
* *Many* thanks to Realtek Corp. for their great support!
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "r8192U.h"
|
|
||||||
#include "r8192U_hw.h"
|
|
||||||
#include "r819xU_phyreg.h"
|
|
||||||
#include "r819xU_phy.h"
|
|
||||||
#include "r8190_rtl8256.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Forward declaration of local functions
|
|
||||||
*/
|
|
||||||
static void phy_rf8256_config_para_file(struct net_device *dev);
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------
|
|
||||||
* Overview: set RF band width (20M or 40M)
|
|
||||||
* Input: struct net_device* dev
|
|
||||||
* WIRELESS_BANDWIDTH_E Bandwidth //20M or 40M
|
|
||||||
* Output: NONE
|
|
||||||
* Return: NONE
|
|
||||||
* Note: 8226 support both 20M and 40 MHz
|
|
||||||
*--------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
void phy_set_rf8256_bandwidth(struct net_device *dev, enum ht_channel_width Bandwidth)
|
|
||||||
{
|
|
||||||
u8 eRFPath;
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
|
|
||||||
/* for(eRFPath = RF90_PATH_A; eRFPath <pHalData->NumTotalRFPath;
|
|
||||||
* eRFPath++)
|
|
||||||
*/
|
|
||||||
for (eRFPath = 0; eRFPath < RF90_PATH_MAX; eRFPath++) {
|
|
||||||
if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
switch (Bandwidth) {
|
|
||||||
case HT_CHANNEL_WIDTH_20:
|
|
||||||
if (priv->card_8192_version == VERSION_819XU_A ||
|
|
||||||
priv->card_8192_version == VERSION_819XU_B) {
|
|
||||||
/* 8256 D-cut, E-cut, xiong: consider it later! */
|
|
||||||
rtl8192_phy_SetRFReg(dev,
|
|
||||||
(enum rf90_radio_path_e)eRFPath,
|
|
||||||
0x0b, bMask12Bits, 0x100); /* phy para:1ba */
|
|
||||||
rtl8192_phy_SetRFReg(dev,
|
|
||||||
(enum rf90_radio_path_e)eRFPath,
|
|
||||||
0x2c, bMask12Bits, 0x3d7);
|
|
||||||
rtl8192_phy_SetRFReg(dev,
|
|
||||||
(enum rf90_radio_path_e)eRFPath,
|
|
||||||
0x0e, bMask12Bits, 0x021);
|
|
||||||
rtl8192_phy_SetRFReg(dev,
|
|
||||||
(enum rf90_radio_path_e)eRFPath,
|
|
||||||
0x14, bMask12Bits, 0x5ab);
|
|
||||||
} else {
|
|
||||||
RT_TRACE(COMP_ERR, "%s(): unknown hardware version\n", __func__);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case HT_CHANNEL_WIDTH_20_40:
|
|
||||||
if (priv->card_8192_version == VERSION_819XU_A || priv->card_8192_version == VERSION_819XU_B) { /* 8256 D-cut, E-cut, xiong: consider it later! */
|
|
||||||
rtl8192_phy_SetRFReg(dev, (enum rf90_radio_path_e)eRFPath, 0x0b, bMask12Bits, 0x300); /* phy para:3ba */
|
|
||||||
rtl8192_phy_SetRFReg(dev, (enum rf90_radio_path_e)eRFPath, 0x2c, bMask12Bits, 0x3df);
|
|
||||||
rtl8192_phy_SetRFReg(dev, (enum rf90_radio_path_e)eRFPath, 0x0e, bMask12Bits, 0x0a1);
|
|
||||||
|
|
||||||
if (priv->chan == 3 || priv->chan == 9)
|
|
||||||
/* I need to set priv->chan whenever current channel changes */
|
|
||||||
rtl8192_phy_SetRFReg(dev, (enum rf90_radio_path_e)eRFPath, 0x14, bMask12Bits, 0x59b);
|
|
||||||
else
|
|
||||||
rtl8192_phy_SetRFReg(dev, (enum rf90_radio_path_e)eRFPath, 0x14, bMask12Bits, 0x5ab);
|
|
||||||
} else {
|
|
||||||
RT_TRACE(COMP_ERR, "%s(): unknown hardware version\n", __func__);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
RT_TRACE(COMP_ERR, "%s(): unknown Bandwidth: %#X\n", __func__, Bandwidth);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------
|
|
||||||
* Overview: Interface to config 8256
|
|
||||||
* Input: struct net_device* dev
|
|
||||||
* Output: NONE
|
|
||||||
* Return: NONE
|
|
||||||
*--------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
void phy_rf8256_config(struct net_device *dev)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
/* Initialize general global value
|
|
||||||
*
|
|
||||||
* TODO: Extend RF_PATH_C and RF_PATH_D in the future
|
|
||||||
*/
|
|
||||||
priv->NumTotalRFPath = RTL819X_TOTAL_RF_PATH;
|
|
||||||
/* Config BB and RF */
|
|
||||||
phy_rf8256_config_para_file(dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------
|
|
||||||
* Overview: Interface to config 8256
|
|
||||||
* Input: struct net_device* dev
|
|
||||||
* Output: NONE
|
|
||||||
* Return: NONE
|
|
||||||
*--------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
static void phy_rf8256_config_para_file(struct net_device *dev)
|
|
||||||
{
|
|
||||||
u32 u4RegValue = 0;
|
|
||||||
u8 eRFPath;
|
|
||||||
BB_REGISTER_DEFINITION_T *pPhyReg;
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
u32 RegOffSetToBeCheck = 0x3;
|
|
||||||
u32 RegValueToBeCheck = 0x7f1;
|
|
||||||
u32 RF3_Final_Value = 0;
|
|
||||||
u8 ConstRetryTimes = 5, RetryTimes = 5;
|
|
||||||
u8 ret = 0;
|
|
||||||
/* Initialize RF */
|
|
||||||
for (eRFPath = (enum rf90_radio_path_e)RF90_PATH_A; eRFPath < priv->NumTotalRFPath; eRFPath++) {
|
|
||||||
if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
pPhyReg = &priv->PHYRegDef[eRFPath];
|
|
||||||
|
|
||||||
/* Joseph test for shorten RF config
|
|
||||||
* pHalData->RfReg0Value[eRFPath] = rtl8192_phy_QueryRFReg(dev, (enum rf90_radio_path_e)eRFPath, rGlobalCtrl, bMaskDWord);
|
|
||||||
* ----Store original RFENV control type
|
|
||||||
*/
|
|
||||||
switch (eRFPath) {
|
|
||||||
case RF90_PATH_A:
|
|
||||||
case RF90_PATH_C:
|
|
||||||
u4RegValue = rtl8192_QueryBBReg(dev, pPhyReg->rfintfs, bRFSI_RFENV);
|
|
||||||
break;
|
|
||||||
case RF90_PATH_B:
|
|
||||||
case RF90_PATH_D:
|
|
||||||
u4RegValue = rtl8192_QueryBBReg(dev, pPhyReg->rfintfs, bRFSI_RFENV << 16);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*----Set RF_ENV enable----*/
|
|
||||||
rtl8192_setBBreg(dev, pPhyReg->rfintfe, bRFSI_RFENV << 16, 0x1);
|
|
||||||
|
|
||||||
/*----Set RF_ENV output high----*/
|
|
||||||
rtl8192_setBBreg(dev, pPhyReg->rfintfo, bRFSI_RFENV, 0x1);
|
|
||||||
|
|
||||||
/* Set bit number of Address and Data for RF register */
|
|
||||||
rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, b3WireAddressLength, 0x0); /* Set 0 to 4 bits for Z-serial and set 1 to 6 bits for 8258 */
|
|
||||||
rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, b3WireDataLength, 0x0); /* Set 0 to 12 bits for Z-serial and 8258, and set 1 to 14 bits for ??? */
|
|
||||||
|
|
||||||
rtl8192_phy_SetRFReg(dev, (enum rf90_radio_path_e)eRFPath, 0x0, bMask12Bits, 0xbf);
|
|
||||||
|
|
||||||
/* Check RF block (for FPGA platform only)----
|
|
||||||
* TODO: this function should be removed on ASIC , Emily 2007.2.2
|
|
||||||
*/
|
|
||||||
if (rtl8192_phy_checkBBAndRF(dev, HW90_BLOCK_RF, (enum rf90_radio_path_e)eRFPath)) {
|
|
||||||
RT_TRACE(COMP_ERR, "phy_rf8256_config():Check Radio[%d] Fail!!\n", eRFPath);
|
|
||||||
goto phy_RF8256_Config_ParaFile_Fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
RetryTimes = ConstRetryTimes;
|
|
||||||
RF3_Final_Value = 0;
|
|
||||||
/*----Initialize RF fom connfiguration file----*/
|
|
||||||
switch (eRFPath) {
|
|
||||||
case RF90_PATH_A:
|
|
||||||
while (RF3_Final_Value != RegValueToBeCheck && RetryTimes != 0) {
|
|
||||||
ret = rtl8192_phy_ConfigRFWithHeaderFile(dev, (enum rf90_radio_path_e)eRFPath);
|
|
||||||
RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (enum rf90_radio_path_e)eRFPath, RegOffSetToBeCheck, bMask12Bits);
|
|
||||||
RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value);
|
|
||||||
RetryTimes--;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RF90_PATH_B:
|
|
||||||
while (RF3_Final_Value != RegValueToBeCheck && RetryTimes != 0) {
|
|
||||||
ret = rtl8192_phy_ConfigRFWithHeaderFile(dev, (enum rf90_radio_path_e)eRFPath);
|
|
||||||
RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (enum rf90_radio_path_e)eRFPath, RegOffSetToBeCheck, bMask12Bits);
|
|
||||||
RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value);
|
|
||||||
RetryTimes--;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RF90_PATH_C:
|
|
||||||
while (RF3_Final_Value != RegValueToBeCheck && RetryTimes != 0) {
|
|
||||||
ret = rtl8192_phy_ConfigRFWithHeaderFile(dev, (enum rf90_radio_path_e)eRFPath);
|
|
||||||
RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (enum rf90_radio_path_e)eRFPath, RegOffSetToBeCheck, bMask12Bits);
|
|
||||||
RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value);
|
|
||||||
RetryTimes--;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RF90_PATH_D:
|
|
||||||
while (RF3_Final_Value != RegValueToBeCheck && RetryTimes != 0) {
|
|
||||||
ret = rtl8192_phy_ConfigRFWithHeaderFile(dev, (enum rf90_radio_path_e)eRFPath);
|
|
||||||
RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (enum rf90_radio_path_e)eRFPath, RegOffSetToBeCheck, bMask12Bits);
|
|
||||||
RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value);
|
|
||||||
RetryTimes--;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*----Restore RFENV control type----*/
|
|
||||||
switch (eRFPath) {
|
|
||||||
case RF90_PATH_A:
|
|
||||||
case RF90_PATH_C:
|
|
||||||
rtl8192_setBBreg(dev, pPhyReg->rfintfs, bRFSI_RFENV, u4RegValue);
|
|
||||||
break;
|
|
||||||
case RF90_PATH_B:
|
|
||||||
case RF90_PATH_D:
|
|
||||||
rtl8192_setBBreg(dev, pPhyReg->rfintfs, bRFSI_RFENV << 16, u4RegValue);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret) {
|
|
||||||
RT_TRACE(COMP_ERR, "%s():Radio[%d] Fail!!", __func__, eRFPath);
|
|
||||||
goto phy_RF8256_Config_ParaFile_Fail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RT_TRACE(COMP_PHY, "PHY Initialization Success\n");
|
|
||||||
return;
|
|
||||||
|
|
||||||
phy_RF8256_Config_ParaFile_Fail:
|
|
||||||
RT_TRACE(COMP_ERR, "PHY Initialization failed\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void phy_set_rf8256_cck_tx_power(struct net_device *dev, u8 powerlevel)
|
|
||||||
{
|
|
||||||
u32 TxAGC = 0;
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
|
|
||||||
TxAGC = powerlevel;
|
|
||||||
|
|
||||||
if (priv->bDynamicTxLowPower) {
|
|
||||||
if (priv->CustomerID == RT_CID_819x_Netcore)
|
|
||||||
TxAGC = 0x22;
|
|
||||||
else
|
|
||||||
TxAGC += priv->CckPwEnl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TxAGC > 0x24)
|
|
||||||
TxAGC = 0x24;
|
|
||||||
rtl8192_setBBreg(dev, rTxAGC_CCK_Mcs32, bTxAGCRateCCK, TxAGC);
|
|
||||||
}
|
|
||||||
|
|
||||||
void phy_set_rf8256_ofdm_tx_power(struct net_device *dev, u8 powerlevel)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
/* Joseph TxPower for 8192 testing */
|
|
||||||
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->TxPowerDiff; /* OFDM rates */
|
|
||||||
powerBase0 = (powerBase0 << 24) | (powerBase0 << 16) | (powerBase0 << 8) | powerBase0;
|
|
||||||
powerBase1 = powerlevel; /* MCS rates */
|
|
||||||
powerBase1 = (powerBase1 << 24) | (powerBase1 << 16) | (powerBase1 << 8) | powerBase1;
|
|
||||||
|
|
||||||
for (index = 0; index < 6; index++) {
|
|
||||||
writeVal = priv->MCSTxPowerLevelOriginalOffset[index] + ((index < 2) ? powerBase0 : powerBase1);
|
|
||||||
byte0 = (u8)(writeVal & 0x7f);
|
|
||||||
byte1 = (u8)((writeVal & 0x7f00) >> 8);
|
|
||||||
byte2 = (u8)((writeVal & 0x7f0000) >> 16);
|
|
||||||
byte3 = (u8)((writeVal & 0x7f000000) >> 24);
|
|
||||||
|
|
||||||
if (byte0 > 0x24)
|
|
||||||
/* Max power index = 0x24 */
|
|
||||||
byte0 = 0x24;
|
|
||||||
if (byte1 > 0x24)
|
|
||||||
byte1 = 0x24;
|
|
||||||
if (byte2 > 0x24)
|
|
||||||
byte2 = 0x24;
|
|
||||||
if (byte3 > 0x24)
|
|
||||||
byte3 = 0x24;
|
|
||||||
|
|
||||||
/* for tx power track */
|
|
||||||
if (index == 3) {
|
|
||||||
writeVal_tmp = (byte3 << 24) | (byte2 << 16) | (byte1 << 8) | byte0;
|
|
||||||
priv->Pwr_Track = writeVal_tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (priv->bDynamicTxHighPower) {
|
|
||||||
/*Add by Jacken 2008/03/06
|
|
||||||
*Emily, 20080613. Set low tx power for both MCS and legacy OFDM
|
|
||||||
*/
|
|
||||||
writeVal = 0x03030303;
|
|
||||||
} else {
|
|
||||||
writeVal = (byte3 << 24) | (byte2 << 16) | (byte1 << 8) | byte0;
|
|
||||||
}
|
|
||||||
rtl8192_setBBreg(dev, RegOffset[index], 0x7f7f7f7f, writeVal);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
/*
|
|
||||||
* This is part of the rtl8180-sa2400 driver
|
|
||||||
* released under the GPL (See file COPYING for details).
|
|
||||||
* Copyright (c) 2005 Andrea Merello <andrea.merello@gmail.com>
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* This files contains programming code for the rtl8256
|
|
||||||
* radio frontend.
|
|
||||||
*
|
|
||||||
* *Many* thanks to Realtek Corp. for their great support!
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef RTL8225H
|
|
||||||
#define RTL8225H
|
|
||||||
|
|
||||||
#define RTL819X_TOTAL_RF_PATH 2 /* for 8192U */
|
|
||||||
void phy_set_rf8256_bandwidth(struct net_device *dev,
|
|
||||||
enum ht_channel_width bandwidth);
|
|
||||||
void phy_rf8256_config(struct net_device *dev);
|
|
||||||
void phy_set_rf8256_cck_tx_power(struct net_device *dev, u8 powerlevel);
|
|
||||||
void phy_set_rf8256_ofdm_tx_power(struct net_device *dev, u8 powerlevel);
|
|
||||||
|
|
||||||
#endif
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,188 +0,0 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0
|
|
||||||
/****************************************************************************
|
|
||||||
* -----------------------------DEGUGFS STUFF-------------------------
|
|
||||||
****************************************************************************/
|
|
||||||
#include <linux/debugfs.h>
|
|
||||||
#include <linux/seq_file.h>
|
|
||||||
#include "r8192U.h"
|
|
||||||
|
|
||||||
#define KBUILD_MODNAME "r8192u_usb"
|
|
||||||
|
|
||||||
static int rtl8192_usb_stats_ap_show(struct seq_file *m, void *v)
|
|
||||||
{
|
|
||||||
struct net_device *dev = m->private;
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
struct ieee80211_device *ieee = priv->ieee80211;
|
|
||||||
struct ieee80211_network *target;
|
|
||||||
|
|
||||||
list_for_each_entry(target, &ieee->network_list, list) {
|
|
||||||
const char *wpa = "non_WPA";
|
|
||||||
|
|
||||||
if (target->wpa_ie_len > 0 || target->rsn_ie_len > 0)
|
|
||||||
wpa = "WPA";
|
|
||||||
|
|
||||||
seq_printf(m, "%s %s\n", target->ssid, wpa);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int rtl8192_usb_registers_show(struct seq_file *m, void *v)
|
|
||||||
{
|
|
||||||
struct net_device *dev = m->private;
|
|
||||||
int i, n, max = 0xff;
|
|
||||||
u8 byte_rd;
|
|
||||||
|
|
||||||
seq_puts(m, "\n####################page 0##################\n ");
|
|
||||||
|
|
||||||
for (n = 0; n <= max;) {
|
|
||||||
seq_printf(m, "\nD: %2x > ", n);
|
|
||||||
|
|
||||||
for (i = 0; i < 16 && n <= max; i++, n++) {
|
|
||||||
read_nic_byte(dev, 0x000 | n, &byte_rd);
|
|
||||||
seq_printf(m, "%2x ", byte_rd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
seq_puts(m, "\n####################page 1##################\n ");
|
|
||||||
for (n = 0; n <= max;) {
|
|
||||||
seq_printf(m, "\nD: %2x > ", n);
|
|
||||||
|
|
||||||
for (i = 0; i < 16 && n <= max; i++, n++) {
|
|
||||||
read_nic_byte(dev, 0x100 | n, &byte_rd);
|
|
||||||
seq_printf(m, "%2x ", byte_rd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
seq_puts(m, "\n####################page 3##################\n ");
|
|
||||||
for (n = 0; n <= max;) {
|
|
||||||
seq_printf(m, "\nD: %2x > ", n);
|
|
||||||
|
|
||||||
for (i = 0; i < 16 && n <= max; i++, n++) {
|
|
||||||
read_nic_byte(dev, 0x300 | n, &byte_rd);
|
|
||||||
seq_printf(m, "%2x ", byte_rd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
seq_putc(m, '\n');
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int rtl8192_usb_stats_tx_show(struct seq_file *m, void *v)
|
|
||||||
{
|
|
||||||
struct net_device *dev = m->private;
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
|
|
||||||
seq_printf(m,
|
|
||||||
"TX VI priority ok int: %lu\n"
|
|
||||||
"TX VI priority error int: %lu\n"
|
|
||||||
"TX VO priority ok int: %lu\n"
|
|
||||||
"TX VO priority error int: %lu\n"
|
|
||||||
"TX BE priority ok int: %lu\n"
|
|
||||||
"TX BE priority error int: %lu\n"
|
|
||||||
"TX BK priority ok int: %lu\n"
|
|
||||||
"TX BK priority error int: %lu\n"
|
|
||||||
"TX MANAGE priority ok int: %lu\n"
|
|
||||||
"TX MANAGE priority error int: %lu\n"
|
|
||||||
"TX BEACON priority ok int: %lu\n"
|
|
||||||
"TX BEACON priority error int: %lu\n"
|
|
||||||
"TX queue resume: %lu\n"
|
|
||||||
"TX queue stopped?: %d\n"
|
|
||||||
"TX fifo overflow: %lu\n"
|
|
||||||
"TX VI queue: %d\n"
|
|
||||||
"TX VO queue: %d\n"
|
|
||||||
"TX BE queue: %d\n"
|
|
||||||
"TX BK queue: %d\n"
|
|
||||||
"TX VI dropped: %lu\n"
|
|
||||||
"TX VO dropped: %lu\n"
|
|
||||||
"TX BE dropped: %lu\n"
|
|
||||||
"TX BK dropped: %lu\n"
|
|
||||||
"TX total data packets %lu\n",
|
|
||||||
priv->stats.txviokint,
|
|
||||||
priv->stats.txvierr,
|
|
||||||
priv->stats.txvookint,
|
|
||||||
priv->stats.txvoerr,
|
|
||||||
priv->stats.txbeokint,
|
|
||||||
priv->stats.txbeerr,
|
|
||||||
priv->stats.txbkokint,
|
|
||||||
priv->stats.txbkerr,
|
|
||||||
priv->stats.txmanageokint,
|
|
||||||
priv->stats.txmanageerr,
|
|
||||||
priv->stats.txbeaconokint,
|
|
||||||
priv->stats.txbeaconerr,
|
|
||||||
priv->stats.txresumed,
|
|
||||||
netif_queue_stopped(dev),
|
|
||||||
priv->stats.txoverflow,
|
|
||||||
atomic_read(&(priv->tx_pending[VI_PRIORITY])),
|
|
||||||
atomic_read(&(priv->tx_pending[VO_PRIORITY])),
|
|
||||||
atomic_read(&(priv->tx_pending[BE_PRIORITY])),
|
|
||||||
atomic_read(&(priv->tx_pending[BK_PRIORITY])),
|
|
||||||
priv->stats.txvidrop,
|
|
||||||
priv->stats.txvodrop,
|
|
||||||
priv->stats.txbedrop,
|
|
||||||
priv->stats.txbkdrop,
|
|
||||||
priv->stats.txdatapkt
|
|
||||||
);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int rtl8192_usb_stats_rx_show(struct seq_file *m, void *v)
|
|
||||||
{
|
|
||||||
struct net_device *dev = m->private;
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
|
|
||||||
seq_printf(m,
|
|
||||||
"RX packets: %lu\n"
|
|
||||||
"RX urb status error: %lu\n"
|
|
||||||
"RX invalid urb error: %lu\n",
|
|
||||||
priv->stats.rxoktotal,
|
|
||||||
priv->stats.rxstaterr,
|
|
||||||
priv->stats.rxurberr);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_SHOW_ATTRIBUTE(rtl8192_usb_stats_rx);
|
|
||||||
DEFINE_SHOW_ATTRIBUTE(rtl8192_usb_stats_tx);
|
|
||||||
DEFINE_SHOW_ATTRIBUTE(rtl8192_usb_stats_ap);
|
|
||||||
DEFINE_SHOW_ATTRIBUTE(rtl8192_usb_registers);
|
|
||||||
|
|
||||||
void rtl8192_debugfs_init_one(struct net_device *dev)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
struct dentry *parent_dir = debugfs_lookup(KBUILD_MODNAME, NULL);
|
|
||||||
struct dentry *dir = debugfs_create_dir(dev->name, parent_dir);
|
|
||||||
|
|
||||||
debugfs_create_file("stats-rx", 0444, dir, dev, &rtl8192_usb_stats_rx_fops);
|
|
||||||
debugfs_create_file("stats-tx", 0444, dir, dev, &rtl8192_usb_stats_tx_fops);
|
|
||||||
debugfs_create_file("stats-ap", 0444, dir, dev, &rtl8192_usb_stats_ap_fops);
|
|
||||||
debugfs_create_file("registers", 0444, dir, dev, &rtl8192_usb_registers_fops);
|
|
||||||
|
|
||||||
priv->debugfs_dir = dir;
|
|
||||||
}
|
|
||||||
|
|
||||||
void rtl8192_debugfs_exit_one(struct net_device *dev)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
|
|
||||||
debugfs_remove_recursive(priv->debugfs_dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
void rtl8192_debugfs_rename_one(struct net_device *dev)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
struct dentry *parent_dir = debugfs_lookup(KBUILD_MODNAME, NULL);
|
|
||||||
|
|
||||||
debugfs_rename(parent_dir, priv->debugfs_dir, parent_dir, dev->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void rtl8192_debugfs_init(void)
|
|
||||||
{
|
|
||||||
debugfs_create_dir(KBUILD_MODNAME, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void rtl8192_debugfs_exit(void)
|
|
||||||
{
|
|
||||||
debugfs_remove_recursive(debugfs_lookup(KBUILD_MODNAME, NULL));
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -1,176 +0,0 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
/*****************************************************************************
|
|
||||||
* Copyright(c) 2007, RealTEK Technology Inc. All Right Reserved.
|
|
||||||
*
|
|
||||||
* Module: Hal819xUsbDM.h (RTL8192 Header H File)
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Note: For dynamic control definition constant structure.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Export:
|
|
||||||
*
|
|
||||||
* Abbrev:
|
|
||||||
*
|
|
||||||
* History:
|
|
||||||
* Data Who Remark
|
|
||||||
* 10/04/2007 MHC Create initial version.
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
/* Check to see if the file has been included already. */
|
|
||||||
#ifndef __R8192UDM_H__
|
|
||||||
#define __R8192UDM_H__
|
|
||||||
|
|
||||||
/*--------------------------Define Parameters-------------------------------*/
|
|
||||||
#define DM_DIG_THRESH_HIGH 40
|
|
||||||
#define DM_DIG_THRESH_LOW 35
|
|
||||||
|
|
||||||
#define DM_DIG_HIGH_PWR_THRESH_HIGH 75
|
|
||||||
#define DM_DIG_HIGH_PWR_THRESH_LOW 70
|
|
||||||
|
|
||||||
#define BW_AUTO_SWITCH_HIGH_LOW 25
|
|
||||||
#define BW_AUTO_SWITCH_LOW_HIGH 30
|
|
||||||
|
|
||||||
#define DM_DIG_BACKOFF 12
|
|
||||||
#define DM_DIG_MAX 0x36
|
|
||||||
#define DM_DIG_MIN 0x1c
|
|
||||||
#define DM_DIG_MIN_NETCORE 0x12
|
|
||||||
|
|
||||||
#define RX_PATH_SELECTION_SS_TH_LOW 30
|
|
||||||
#define RX_PATH_SELECTION_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 CTS_TO_SELF_TH_VAL 30
|
|
||||||
|
|
||||||
/* defined by vivi, for tx power track */
|
|
||||||
#define E_FOR_TX_POWER_TRACK 300
|
|
||||||
/* Dynamic Tx Power Control Threshold */
|
|
||||||
#define TX_POWER_NEAR_FIELD_THRESH_HIGH 68
|
|
||||||
#define TX_POWER_NEAR_FIELD_THRESH_LOW 62
|
|
||||||
/* added by amy for atheros AP */
|
|
||||||
#define TX_POWER_ATHEROAP_THRESH_HIGH 78
|
|
||||||
#define TX_POWER_ATHEROAP_THRESH_LOW 72
|
|
||||||
|
|
||||||
/* defined by vivi, for showing on UI */
|
|
||||||
#define CURRENT_TX_RATE_REG 0x1b8
|
|
||||||
#define INITIAL_TX_RATE_REG 0x1b9
|
|
||||||
#define TX_RETRY_COUNT_REG 0x1ac
|
|
||||||
#define REG_C38_TH 20
|
|
||||||
/*--------------------------Define Parameters-------------------------------*/
|
|
||||||
|
|
||||||
/*------------------------------Define structure----------------------------*/
|
|
||||||
|
|
||||||
enum dig_algorithm {
|
|
||||||
DIG_ALGO_BY_FALSE_ALARM = 0,
|
|
||||||
DIG_ALGO_BY_RSSI = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum dynamic_init_gain_state {
|
|
||||||
DM_STA_DIG_OFF = 0,
|
|
||||||
DM_STA_DIG_ON,
|
|
||||||
DM_STA_DIG_MAX
|
|
||||||
};
|
|
||||||
|
|
||||||
enum dig_connect {
|
|
||||||
DIG_DISCONNECT = 0,
|
|
||||||
DIG_CONNECT = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum dig_pkt_detection_threshold {
|
|
||||||
DIG_PD_AT_LOW_POWER = 0,
|
|
||||||
DIG_PD_AT_NORMAL_POWER = 1,
|
|
||||||
DIG_PD_AT_HIGH_POWER = 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum dig_cck_cs_ratio_state {
|
|
||||||
DIG_CS_RATIO_LOWER = 0,
|
|
||||||
DIG_CS_RATIO_HIGHER = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* 2007/10/04 MH Define upper and lower threshold of DIG enable or disable. */
|
|
||||||
struct dig {
|
|
||||||
u8 dig_enable_flag;
|
|
||||||
enum dig_algorithm dig_algorithm;
|
|
||||||
u8 dig_algorithm_switch;
|
|
||||||
|
|
||||||
long rssi_low_thresh;
|
|
||||||
long rssi_high_thresh;
|
|
||||||
|
|
||||||
long rssi_high_power_lowthresh;
|
|
||||||
long rssi_high_power_highthresh;
|
|
||||||
|
|
||||||
enum dynamic_init_gain_state dig_state;
|
|
||||||
enum dynamic_init_gain_state dig_highpwr_state;
|
|
||||||
enum dig_connect cur_connect_state;
|
|
||||||
enum dig_connect pre_connect_state;
|
|
||||||
|
|
||||||
enum dig_pkt_detection_threshold curpd_thstate;
|
|
||||||
enum dig_pkt_detection_threshold prepd_thstate;
|
|
||||||
enum dig_cck_cs_ratio_state curcs_ratio_state;
|
|
||||||
enum dig_cck_cs_ratio_state precs_ratio_state;
|
|
||||||
|
|
||||||
u32 pre_ig_value;
|
|
||||||
u32 cur_ig_value;
|
|
||||||
|
|
||||||
u8 backoff_val;
|
|
||||||
u8 rx_gain_range_min;
|
|
||||||
|
|
||||||
long rssi_val;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum cck_rx_path_method {
|
|
||||||
CCK_RX_VERSION_1 = 0,
|
|
||||||
CCK_RX_VERSION_2 = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct dynamic_rx_path_sel {
|
|
||||||
enum cck_rx_path_method cck_method;
|
|
||||||
u8 cck_rx_path;
|
|
||||||
|
|
||||||
u8 disabled_rf;
|
|
||||||
|
|
||||||
u8 rf_rssi[4];
|
|
||||||
u8 rf_enable_rssi_th[4];
|
|
||||||
long cck_pwdb_sta[4];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct tx_config_cmd {
|
|
||||||
u32 cmd_op; /* Command packet type. */
|
|
||||||
u32 cmd_length; /* Command packet length. */
|
|
||||||
u32 cmd_value;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*------------------------------Define structure----------------------------*/
|
|
||||||
|
|
||||||
/*------------------------Export global variable----------------------------*/
|
|
||||||
extern struct dig dm_digtable;
|
|
||||||
extern u8 dm_shadow[16][256];
|
|
||||||
/*------------------------Export global variable----------------------------*/
|
|
||||||
|
|
||||||
/*------------------------Export Marco Definition---------------------------*/
|
|
||||||
|
|
||||||
/*------------------------Export Marco Definition---------------------------*/
|
|
||||||
|
|
||||||
/*--------------------------Exported Function prototype---------------------*/
|
|
||||||
void init_hal_dm(struct net_device *dev);
|
|
||||||
void deinit_hal_dm(struct net_device *dev);
|
|
||||||
void hal_dm_watchdog(struct net_device *dev);
|
|
||||||
void init_rate_adaptive(struct net_device *dev);
|
|
||||||
void dm_txpower_trackingcallback(struct work_struct *work);
|
|
||||||
void dm_restore_dynamic_mechanism_state(struct net_device *dev);
|
|
||||||
void dm_force_tx_fw_info(struct net_device *dev,
|
|
||||||
u32 force_type, u32 force_value);
|
|
||||||
void dm_init_edca_turbo(struct net_device *dev);
|
|
||||||
void dm_rf_operation_test_callback(unsigned long data);
|
|
||||||
void dm_rf_pathcheck_workitemcallback(struct work_struct *work);
|
|
||||||
void dm_fsync_work_callback(struct work_struct *work);
|
|
||||||
void dm_cck_txpower_adjust(struct net_device *dev, bool binch14);
|
|
||||||
void dm_initialize_txpower_tracking(struct net_device *dev);
|
|
||||||
/*--------------------------Exported Function prototype---------------------*/
|
|
||||||
|
|
||||||
#endif /*__R8192UDM_H__ */
|
|
||||||
|
|
||||||
/* End of r8192U_dm.h */
|
|
@ -1,246 +0,0 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
/*
|
|
||||||
* This is part of rtl8187 OpenSource driver.
|
|
||||||
* Copyright (C) Andrea Merello 2004-2005 <andrea.merello@gmail.com>
|
|
||||||
*
|
|
||||||
* Parts of this driver are based on the GPL part of the
|
|
||||||
* official Realtek driver.
|
|
||||||
* Parts of this driver are based on the rtl8180 driver skeleton
|
|
||||||
* from Patric Schenke & Andres Salomon.
|
|
||||||
* Parts of this driver are based on the Intel Pro Wireless
|
|
||||||
* 2100 GPL driver.
|
|
||||||
*
|
|
||||||
* We want to thank the Authors of those projects
|
|
||||||
* and the Ndiswrapper project Authors.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Mariusz Matuszek added full registers definition with Realtek's name */
|
|
||||||
|
|
||||||
/* this file contains register definitions for the rtl8187 MAC controller */
|
|
||||||
#ifndef R8192_HW
|
|
||||||
#define R8192_HW
|
|
||||||
|
|
||||||
#define RTL8187_REQT_READ 0xc0
|
|
||||||
#define RTL8187_REQT_WRITE 0x40
|
|
||||||
#define RTL8187_REQ_GET_REGS 0x05
|
|
||||||
#define RTL8187_REQ_SET_REGS 0x05
|
|
||||||
|
|
||||||
#define MAX_TX_URB 5
|
|
||||||
#define MAX_RX_URB 16
|
|
||||||
|
|
||||||
#define R8180_MAX_RETRY 255
|
|
||||||
|
|
||||||
#define RX_URB_SIZE 9100
|
|
||||||
|
|
||||||
#define RTL8190_EEPROM_ID 0x8129
|
|
||||||
#define EEPROM_VID 0x02
|
|
||||||
#define EEPROM_PID 0x04
|
|
||||||
#define EEPROM_NODE_ADDRESS_BYTE_0 0x0C
|
|
||||||
|
|
||||||
#define EEPROM_TX_POWER_DIFF 0x1F
|
|
||||||
#define EEPROM_THERMAL_METER 0x20
|
|
||||||
#define EEPROM_PW_DIFF 0x21 //0x21
|
|
||||||
#define EEPROM_CRYSTAL_CAP 0x22 //0x22
|
|
||||||
|
|
||||||
#define EEPROM_TX_PW_INDEX_CCK 0x23 //0x23
|
|
||||||
#define EEPROM_TX_PW_INDEX_OFDM_24G 0x24 //0x24~0x26
|
|
||||||
#define EEPROM_TX_PW_INDEX_CCK_V1 0x29 //0x29~0x2B
|
|
||||||
#define EEPROM_TX_PW_INDEX_OFDM_24G_V1 0x2C //0x2C~0x2E
|
|
||||||
#define EEPROM_TX_PW_INDEX_VER 0x27 //0x27
|
|
||||||
|
|
||||||
#define EEPROM_DEFAULT_THERNAL_METER 0x7
|
|
||||||
#define EEPROM_DEFAULT_PW_DIFF 0x4
|
|
||||||
#define EEPROM_DEFAULT_CRYSTAL_CAP 0x5
|
|
||||||
#define EEPROM_DEFAULT_TX_POWER 0x1010
|
|
||||||
#define EEPROM_CUSTOMER_ID 0x7B //0x7B:CustomerID
|
|
||||||
#define EEPROM_CHANNEL_PLAN 0x16 //0x7C
|
|
||||||
|
|
||||||
#define EEPROM_CID_RUNTOP 0x2
|
|
||||||
#define EEPROM_CID_DLINK 0x8
|
|
||||||
|
|
||||||
#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
|
|
||||||
|
|
||||||
//#endif
|
|
||||||
enum _RTL8192Usb_HW {
|
|
||||||
MAC0 = 0x000,
|
|
||||||
MAC4 = 0x004,
|
|
||||||
|
|
||||||
#define BB_GLOBAL_RESET_BIT 0x1
|
|
||||||
BB_GLOBAL_RESET = 0x020, // BasebandGlobal Reset Register
|
|
||||||
BSSIDR = 0x02E, // BSSID Register
|
|
||||||
CMDR = 0x037, // Command register
|
|
||||||
#define CR_RE 0x08
|
|
||||||
#define CR_TE 0x04
|
|
||||||
SIFS = 0x03E, // SIFS register
|
|
||||||
|
|
||||||
#define TCR_MXDMA_2048 7
|
|
||||||
#define TCR_LRL_OFFSET 0
|
|
||||||
#define TCR_SRL_OFFSET 8
|
|
||||||
#define TCR_MXDMA_OFFSET 21
|
|
||||||
#define TCR_SAT BIT(24) // Enable Rate depedent ack timeout timer
|
|
||||||
RCR = 0x044, // Receive Configuration Register
|
|
||||||
#define MAC_FILTER_MASK (BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(5) | \
|
|
||||||
BIT(12) | BIT(18) | BIT(19) | BIT(20) | BIT(21) | \
|
|
||||||
BIT(22) | BIT(23))
|
|
||||||
#define RX_FIFO_THRESHOLD_MASK (BIT(13) | BIT(14) | BIT(15))
|
|
||||||
#define RX_FIFO_THRESHOLD_SHIFT 13
|
|
||||||
#define RX_FIFO_THRESHOLD_NONE 7
|
|
||||||
#define MAX_RX_DMA_MASK (BIT(8) | BIT(9) | BIT(10))
|
|
||||||
#define RCR_MXDMA_OFFSET 8
|
|
||||||
#define RCR_FIFO_OFFSET 13
|
|
||||||
#define RCR_ONLYERLPKT BIT(31) // Early Receiving based on Packet Size.
|
|
||||||
#define RCR_CBSSID BIT(23) // Accept BSSID match packet
|
|
||||||
#define RCR_APWRMGT BIT(22) // Accept power management packet
|
|
||||||
#define RCR_AMF BIT(20) // Accept management type frame
|
|
||||||
#define RCR_ACF BIT(19) // Accept control type frame
|
|
||||||
#define RCR_ADF BIT(18) // Accept data type frame
|
|
||||||
#define RCR_AICV BIT(12) // Accept ICV error packet
|
|
||||||
#define RCR_ACRC32 BIT(5) // Accept CRC32 error packet
|
|
||||||
#define RCR_AB BIT(3) // Accept broadcast packet
|
|
||||||
#define RCR_AM BIT(2) // Accept multicast packet
|
|
||||||
#define RCR_APM BIT(1) // Accept physical match packet
|
|
||||||
#define RCR_AAP BIT(0) // Accept all unicast packet
|
|
||||||
SLOT_TIME = 0x049, // Slot Time Register
|
|
||||||
ACK_TIMEOUT = 0x04c, // Ack Timeout Register
|
|
||||||
EDCAPARA_BE = 0x050, // EDCA Parameter of AC BE
|
|
||||||
EDCAPARA_BK = 0x054, // EDCA Parameter of AC BK
|
|
||||||
EDCAPARA_VO = 0x058, // EDCA Parameter of AC VO
|
|
||||||
EDCAPARA_VI = 0x05C, // EDCA Parameter of AC VI
|
|
||||||
BCN_TCFG = 0x062, // Beacon Time Configuration
|
|
||||||
#define BCN_TCFG_CW_SHIFT 8
|
|
||||||
#define BCN_TCFG_IFS 0
|
|
||||||
BCN_INTERVAL = 0x070, // Beacon Interval (TU)
|
|
||||||
ATIMWND = 0x072, // ATIM Window Size (TU)
|
|
||||||
BCN_DRV_EARLY_INT = 0x074, // Driver Early Interrupt Time (TU). Time to send interrupt to notify to change beacon content before TBTT
|
|
||||||
BCN_DMATIME = 0x076, // Beacon DMA and ATIM interrupt time (US). Indicates the time before TBTT to perform beacon queue DMA
|
|
||||||
BCN_ERR_THRESH = 0x078, // Beacon Error Threshold
|
|
||||||
RWCAM = 0x0A0, //IN 8190 Data Sheet is called CAMcmd
|
|
||||||
WCAMI = 0x0A4, // Software write CAM input content
|
|
||||||
SECR = 0x0B0, //Security Configuration Register
|
|
||||||
#define SCR_TxUseDK BIT(0) //Force Tx Use Default Key
|
|
||||||
#define SCR_RxUseDK BIT(1) //Force Rx Use Default Key
|
|
||||||
#define SCR_TxEncEnable BIT(2) //Enable Tx Encryption
|
|
||||||
#define SCR_RxDecEnable BIT(3) //Enable Rx Decryption
|
|
||||||
#define SCR_SKByA2 BIT(4) //Search kEY BY A2
|
|
||||||
#define SCR_NoSKMC BIT(5) //No Key Search for Multicast
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
// 8190 CPU General Register (offset 0x100, 4 byte)
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
#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 // Set bit18,17,16 to 0. Set bit19
|
|
||||||
#define CPU_GEN_NO_LOOPBACK_SET 0x00080000 // Set BIT19 to 1
|
|
||||||
CPU_GEN = 0x100, // CPU Reset Register
|
|
||||||
|
|
||||||
AcmHwCtrl = 0x171, // ACM Hardware Control Register
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
////
|
|
||||||
//// 8190 AcmHwCtrl bits (offset 0x171, 1 byte)
|
|
||||||
////----------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
#define AcmHw_BeqEn BIT(1)
|
|
||||||
|
|
||||||
RQPN1 = 0x180, // Reserved Queue Page Number , Vo Vi, Be, Bk
|
|
||||||
RQPN2 = 0x184, // Reserved Queue Page Number, HCCA, Cmd, Mgnt, High
|
|
||||||
RQPN3 = 0x188, // Reserved Queue Page Number, Bcn, Public,
|
|
||||||
QPNR = 0x1D0, //0x1F0, // Queue Packet Number report per TID
|
|
||||||
|
|
||||||
#define BW_OPMODE_5G BIT(1)
|
|
||||||
#define BW_OPMODE_20MHZ BIT(2)
|
|
||||||
BW_OPMODE = 0x300, // Bandwidth operation mode
|
|
||||||
MSR = 0x303, // Media Status register
|
|
||||||
#define MSR_LINK_MASK (BIT(0) | BIT(1))
|
|
||||||
#define MSR_LINK_MANAGED 2
|
|
||||||
#define MSR_LINK_NONE 0
|
|
||||||
#define MSR_LINK_SHIFT 0
|
|
||||||
#define MSR_LINK_ADHOC 1
|
|
||||||
#define MSR_LINK_MASTER 3
|
|
||||||
RETRY_LIMIT = 0x304, // Retry Limit [15:8]-short, [7:0]-long
|
|
||||||
#define RETRY_LIMIT_SHORT_SHIFT 8
|
|
||||||
#define RETRY_LIMIT_LONG_SHIFT 0
|
|
||||||
RRSR = 0x310, // Response Rate Set
|
|
||||||
#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) // CCK ACK: use Short Preamble or not.
|
|
||||||
UFWP = 0x318,
|
|
||||||
RATR0 = 0x320, // Rate Adaptive Table register1
|
|
||||||
DRIVER_RSSI = 0x32c, // Driver tell Firmware current RSSI
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
// 8190 Rate Adaptive Table Register (offset 0x320, 4 byte)
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
//CCK
|
|
||||||
#define RATR_1M 0x00000001
|
|
||||||
#define RATR_2M 0x00000002
|
|
||||||
#define RATR_55M 0x00000004
|
|
||||||
#define RATR_11M 0x00000008
|
|
||||||
//OFDM
|
|
||||||
#define RATR_6M 0x00000010
|
|
||||||
#define RATR_9M 0x00000020
|
|
||||||
#define RATR_12M 0x00000040
|
|
||||||
#define RATR_18M 0x00000080
|
|
||||||
#define RATR_24M 0x00000100
|
|
||||||
#define RATR_36M 0x00000200
|
|
||||||
#define RATR_48M 0x00000400
|
|
||||||
#define RATR_54M 0x00000800
|
|
||||||
//MCS 1 Spatial Stream
|
|
||||||
#define RATR_MCS0 0x00001000
|
|
||||||
#define RATR_MCS1 0x00002000
|
|
||||||
#define RATR_MCS2 0x00004000
|
|
||||||
#define RATR_MCS3 0x00008000
|
|
||||||
#define RATR_MCS4 0x00010000
|
|
||||||
#define RATR_MCS5 0x00020000
|
|
||||||
#define RATR_MCS6 0x00040000
|
|
||||||
#define RATR_MCS7 0x00080000
|
|
||||||
//MCS 2 Spatial Stream
|
|
||||||
#define RATR_MCS8 0x00100000
|
|
||||||
#define RATR_MCS9 0x00200000
|
|
||||||
#define RATR_MCS10 0x00400000
|
|
||||||
#define RATR_MCS11 0x00800000
|
|
||||||
#define RATR_MCS12 0x01000000
|
|
||||||
#define RATR_MCS13 0x02000000
|
|
||||||
#define RATR_MCS14 0x04000000
|
|
||||||
#define RATR_MCS15 0x08000000
|
|
||||||
// ALL CCK Rate
|
|
||||||
#define RATE_ALL_CCK (RATR_1M | RATR_2M | RATR_55M | RATR_11M)
|
|
||||||
#define RATE_ALL_OFDM_AG (RATR_6M | RATR_9M | RATR_12M | RATR_18M |\
|
|
||||||
RATR_24M | RATR_36M | RATR_48M | RATR_54M)
|
|
||||||
#define RATE_ALL_OFDM_1SS (RATR_MCS0 | RATR_MCS1 | RATR_MCS2 | RATR_MCS3 |\
|
|
||||||
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)
|
|
||||||
EPROM_CMD = 0xfe58,
|
|
||||||
#define Cmd9346CR_9356SEL BIT(4)
|
|
||||||
#define EPROM_CMD_OPERATING_MODE_SHIFT 6
|
|
||||||
#define EPROM_CMD_NORMAL 0
|
|
||||||
#define EPROM_CMD_PROGRAM 2
|
|
||||||
#define EPROM_CS_BIT BIT(3)
|
|
||||||
#define EPROM_CK_BIT BIT(2)
|
|
||||||
#define EPROM_W_BIT BIT(1)
|
|
||||||
#define EPROM_R_BIT BIT(0)
|
|
||||||
};
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
// 818xB AnaParm & AnaParm2 Register
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
#define GPI 0x108
|
|
||||||
#endif
|
|
@ -1,943 +0,0 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0
|
|
||||||
/******************************************************************************
|
|
||||||
*
|
|
||||||
* This file contains wireless extension handlers.
|
|
||||||
*
|
|
||||||
* This is part of rtl8180 OpenSource driver.
|
|
||||||
* Copyright (C) Andrea Merello 2004-2005 <andrea.merello@gmail.com>
|
|
||||||
*
|
|
||||||
* Parts of this driver are based on the GPL part
|
|
||||||
* of the official realtek driver.
|
|
||||||
*
|
|
||||||
* Parts of this driver are based on the rtl8180 driver skeleton
|
|
||||||
* from Patric Schenke & Andres Salomon.
|
|
||||||
*
|
|
||||||
* Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
|
|
||||||
*
|
|
||||||
* We want to thank the Authors of those projects and the Ndiswrapper
|
|
||||||
* project Authors.
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
#include <linux/string.h>
|
|
||||||
#include "r8192U.h"
|
|
||||||
#include "r8192U_hw.h"
|
|
||||||
|
|
||||||
#include "ieee80211/dot11d.h"
|
|
||||||
#include "r8192U_wx.h"
|
|
||||||
|
|
||||||
#define RATE_COUNT 12
|
|
||||||
static const u32 rtl8180_rates[] = {1000000, 2000000, 5500000, 11000000,
|
|
||||||
6000000, 9000000, 12000000, 18000000, 24000000, 36000000, 48000000, 54000000};
|
|
||||||
|
|
||||||
#ifndef ENETDOWN
|
|
||||||
#define ENETDOWN 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int r8192_wx_get_freq(struct net_device *dev,
|
|
||||||
struct iw_request_info *a,
|
|
||||||
union iwreq_data *wrqu, char *b)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
|
|
||||||
return ieee80211_wx_get_freq(priv->ieee80211, a, wrqu, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int r8192_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
|
|
||||||
union iwreq_data *wrqu, char *b)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
|
|
||||||
return ieee80211_wx_get_mode(priv->ieee80211, a, wrqu, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int r8192_wx_get_rate(struct net_device *dev,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *extra)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
|
|
||||||
return ieee80211_wx_get_rate(priv->ieee80211, info, wrqu, extra);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int r8192_wx_set_rate(struct net_device *dev,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *extra)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
|
|
||||||
mutex_lock(&priv->wx_mutex);
|
|
||||||
|
|
||||||
ret = ieee80211_wx_set_rate(priv->ieee80211, info, wrqu, extra);
|
|
||||||
|
|
||||||
mutex_unlock(&priv->wx_mutex);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int r8192_wx_set_rts(struct net_device *dev,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *extra)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
|
|
||||||
mutex_lock(&priv->wx_mutex);
|
|
||||||
|
|
||||||
ret = ieee80211_wx_set_rts(priv->ieee80211, info, wrqu, extra);
|
|
||||||
|
|
||||||
mutex_unlock(&priv->wx_mutex);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int r8192_wx_get_rts(struct net_device *dev,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *extra)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
|
|
||||||
return ieee80211_wx_get_rts(priv->ieee80211, info, wrqu, extra);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int r8192_wx_set_power(struct net_device *dev,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *extra)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
|
|
||||||
mutex_lock(&priv->wx_mutex);
|
|
||||||
|
|
||||||
ret = ieee80211_wx_set_power(priv->ieee80211, info, wrqu, extra);
|
|
||||||
|
|
||||||
mutex_unlock(&priv->wx_mutex);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int r8192_wx_get_power(struct net_device *dev,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *extra)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
|
|
||||||
return ieee80211_wx_get_power(priv->ieee80211, info, wrqu, extra);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int r8192_wx_force_reset(struct net_device *dev,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *extra)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
|
|
||||||
mutex_lock(&priv->wx_mutex);
|
|
||||||
|
|
||||||
netdev_dbg(dev, "%s(): force reset ! extra is %d\n", __func__, *extra);
|
|
||||||
priv->force_reset = *extra;
|
|
||||||
mutex_unlock(&priv->wx_mutex);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int r8192_wx_set_rawtx(struct net_device *dev,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *extra)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
mutex_lock(&priv->wx_mutex);
|
|
||||||
|
|
||||||
ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
|
|
||||||
|
|
||||||
mutex_unlock(&priv->wx_mutex);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int r8192_wx_set_crcmon(struct net_device *dev,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *extra)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
int *parms = (int *)extra;
|
|
||||||
int enable = (parms[0] > 0);
|
|
||||||
|
|
||||||
mutex_lock(&priv->wx_mutex);
|
|
||||||
|
|
||||||
if (enable)
|
|
||||||
priv->crcmon = 1;
|
|
||||||
else
|
|
||||||
priv->crcmon = 0;
|
|
||||||
|
|
||||||
DMESG("bad CRC in monitor mode are %s",
|
|
||||||
priv->crcmon ? "accepted" : "rejected");
|
|
||||||
|
|
||||||
mutex_unlock(&priv->wx_mutex);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
|
|
||||||
union iwreq_data *wrqu, char *b)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
mutex_lock(&priv->wx_mutex);
|
|
||||||
|
|
||||||
ret = ieee80211_wx_set_mode(priv->ieee80211, a, wrqu, b);
|
|
||||||
|
|
||||||
rtl8192_set_rxconf(dev);
|
|
||||||
|
|
||||||
mutex_unlock(&priv->wx_mutex);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct iw_range_with_scan_capa {
|
|
||||||
/* Informative stuff (to choose between different interface) */
|
|
||||||
__u32 throughput; /* To give an idea... */
|
|
||||||
/* In theory this value should be the maximum benchmarked
|
|
||||||
* TCP/IP throughput, because with most of these devices the
|
|
||||||
* bit rate is meaningless (overhead an co) to estimate how
|
|
||||||
* fast the connection will go and pick the fastest one.
|
|
||||||
* I suggest people to play with Netperf or any benchmark...
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* NWID (or domain id) */
|
|
||||||
__u32 min_nwid; /* Minimal NWID we are able to set */
|
|
||||||
__u32 max_nwid; /* Maximal NWID we are able to set */
|
|
||||||
|
|
||||||
/* Old Frequency (backward compat - moved lower ) */
|
|
||||||
__u16 old_num_channels;
|
|
||||||
__u8 old_num_frequency;
|
|
||||||
|
|
||||||
/* Scan capabilities */
|
|
||||||
__u8 scan_capa;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int rtl8180_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 iw_range_with_scan_capa *tmp = (struct iw_range_with_scan_capa *)range;
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
u16 val;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
wrqu->data.length = sizeof(*range);
|
|
||||||
memset(range, 0, sizeof(*range));
|
|
||||||
|
|
||||||
/* Let's try to keep this struct in the same order as in
|
|
||||||
* linux/include/wireless.h
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* TODO: See what values we can set, and remove the ones we can't
|
|
||||||
* set, or fill them with some default data.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* ~5 Mb/s real (802.11b) */
|
|
||||||
range->throughput = 5 * 1000 * 1000;
|
|
||||||
|
|
||||||
/* TODO: Not used in 802.11b? */
|
|
||||||
/* range->min_nwid; */ /* Minimal NWID we are able to set */
|
|
||||||
/* TODO: Not used in 802.11b? */
|
|
||||||
/* range->max_nwid; */ /* Maximal NWID we are able to set */
|
|
||||||
|
|
||||||
/* Old Frequency (backward compat - moved lower ) */
|
|
||||||
/* range->old_num_channels; */
|
|
||||||
/* range->old_num_frequency; */
|
|
||||||
/* range->old_freq[6]; */ /* Filler to keep "version" at the same offset */
|
|
||||||
if (priv->rf_set_sens)
|
|
||||||
range->sensitivity = priv->max_sens; /* signal level threshold range */
|
|
||||||
|
|
||||||
range->max_qual.qual = 100;
|
|
||||||
/* TODO: Find real max RSSI and stick here */
|
|
||||||
range->max_qual.level = 0;
|
|
||||||
range->max_qual.noise = 0x100 - 98;
|
|
||||||
range->max_qual.updated = 7; /* Updated all three */
|
|
||||||
|
|
||||||
range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
|
|
||||||
/* TODO: Find real 'good' to 'bad' threshold value for RSSI */
|
|
||||||
range->avg_qual.level = 0x100 - 78;
|
|
||||||
range->avg_qual.noise = 0;
|
|
||||||
range->avg_qual.updated = 7; /* Updated all three */
|
|
||||||
|
|
||||||
range->num_bitrates = RATE_COUNT;
|
|
||||||
|
|
||||||
for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
|
|
||||||
range->bitrate[i] = rtl8180_rates[i];
|
|
||||||
|
|
||||||
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 = 16;
|
|
||||||
|
|
||||||
/* range->retry_capa; */ /* What retry options are supported */
|
|
||||||
/* range->retry_flags; */ /* How to decode max/min retry limit */
|
|
||||||
/* range->r_time_flags; */ /* How to decode max/min retry life */
|
|
||||||
/* range->min_retry; */ /* Minimal number of retries */
|
|
||||||
/* range->max_retry; */ /* Maximal number of retries */
|
|
||||||
/* range->min_r_time; */ /* Minimal retry lifetime */
|
|
||||||
/* range->max_r_time; */ /* Maximal retry lifetime */
|
|
||||||
|
|
||||||
for (i = 0, val = 0; i < 14; i++) {
|
|
||||||
/* Include only legal frequencies for some countries */
|
|
||||||
if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i + 1]) {
|
|
||||||
range->freq[val].i = i + 1;
|
|
||||||
range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
|
|
||||||
range->freq[val].e = 1;
|
|
||||||
val++;
|
|
||||||
} else {
|
|
||||||
/* FIXME: do we need to set anything for channels */
|
|
||||||
/* we don't use ? */
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
tmp->scan_capa = 0x01;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
|
|
||||||
union iwreq_data *wrqu, char *b)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
struct ieee80211_device *ieee = priv->ieee80211;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
if (!priv->up)
|
|
||||||
return -ENETDOWN;
|
|
||||||
|
|
||||||
if (priv->ieee80211->LinkDetectInfo.bBusyTraffic)
|
|
||||||
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);
|
|
||||||
if (priv->ieee80211->state != IEEE80211_LINKED) {
|
|
||||||
priv->ieee80211->scanning = 0;
|
|
||||||
ieee80211_softmac_scan_syncro(priv->ieee80211);
|
|
||||||
ret = 0;
|
|
||||||
} else {
|
|
||||||
ret = ieee80211_wx_set_scan(priv->ieee80211, a, wrqu, b);
|
|
||||||
}
|
|
||||||
mutex_unlock(&priv->wx_mutex);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
|
|
||||||
union iwreq_data *wrqu, char *b)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
|
|
||||||
if (!priv->up)
|
|
||||||
return -ENETDOWN;
|
|
||||||
|
|
||||||
mutex_lock(&priv->wx_mutex);
|
|
||||||
|
|
||||||
ret = ieee80211_wx_get_scan(priv->ieee80211, a, wrqu, b);
|
|
||||||
|
|
||||||
mutex_unlock(&priv->wx_mutex);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int r8192_wx_set_essid(struct net_device *dev,
|
|
||||||
struct iw_request_info *a,
|
|
||||||
union iwreq_data *wrqu, char *b)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
mutex_lock(&priv->wx_mutex);
|
|
||||||
|
|
||||||
ret = ieee80211_wx_set_essid(priv->ieee80211, a, wrqu, b);
|
|
||||||
|
|
||||||
mutex_unlock(&priv->wx_mutex);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int r8192_wx_get_essid(struct net_device *dev,
|
|
||||||
struct iw_request_info *a,
|
|
||||||
union iwreq_data *wrqu, char *b)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
|
|
||||||
mutex_lock(&priv->wx_mutex);
|
|
||||||
|
|
||||||
ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
|
|
||||||
|
|
||||||
mutex_unlock(&priv->wx_mutex);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
|
|
||||||
union iwreq_data *wrqu, char *b)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
|
|
||||||
mutex_lock(&priv->wx_mutex);
|
|
||||||
|
|
||||||
ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
|
|
||||||
|
|
||||||
mutex_unlock(&priv->wx_mutex);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int r8192_wx_get_name(struct net_device *dev,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *extra)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
|
|
||||||
return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int r8192_wx_set_frag(struct net_device *dev,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *extra)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
|
|
||||||
if (wrqu->frag.disabled) {
|
|
||||||
priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
|
|
||||||
} else {
|
|
||||||
if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
|
|
||||||
wrqu->frag.value > MAX_FRAG_THRESHOLD)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
priv->ieee80211->fts = wrqu->frag.value & ~0x1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int r8192_wx_get_frag(struct net_device *dev,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *extra)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
|
|
||||||
wrqu->frag.value = priv->ieee80211->fts;
|
|
||||||
wrqu->frag.fixed = 0; /* no auto select */
|
|
||||||
wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int r8192_wx_set_wap(struct net_device *dev,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *awrq,
|
|
||||||
char *extra)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
/* struct sockaddr *temp = (struct sockaddr *)awrq; */
|
|
||||||
mutex_lock(&priv->wx_mutex);
|
|
||||||
|
|
||||||
ret = ieee80211_wx_set_wap(priv->ieee80211, info, awrq, extra);
|
|
||||||
|
|
||||||
mutex_unlock(&priv->wx_mutex);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int r8192_wx_get_wap(struct net_device *dev,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *extra)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
|
|
||||||
return ieee80211_wx_get_wap(priv->ieee80211, info, wrqu, extra);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int r8192_wx_get_enc(struct net_device *dev,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *key)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
|
|
||||||
return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int r8192_wx_set_enc(struct net_device *dev,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *key)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
struct ieee80211_device *ieee = priv->ieee80211;
|
|
||||||
int ret;
|
|
||||||
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->up)
|
|
||||||
return -ENETDOWN;
|
|
||||||
|
|
||||||
mutex_lock(&priv->wx_mutex);
|
|
||||||
|
|
||||||
RT_TRACE(COMP_SEC, "Setting SW wep key");
|
|
||||||
ret = ieee80211_wx_set_encode(priv->ieee80211, info, wrqu, key);
|
|
||||||
|
|
||||||
mutex_unlock(&priv->wx_mutex);
|
|
||||||
|
|
||||||
/* sometimes, the length is zero while we do not type key value */
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define CONF_WEP40 0x4
|
|
||||||
#define CONF_WEP104 0x14
|
|
||||||
|
|
||||||
switch (wrqu->encoding.flags & IW_ENCODE_INDEX) {
|
|
||||||
case 0:
|
|
||||||
key_idx = ieee->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;
|
|
||||||
EnableHWSecurityConfig8192(dev);
|
|
||||||
|
|
||||||
setKey(dev,
|
|
||||||
key_idx, /* EntryNo */
|
|
||||||
key_idx, /* KeyIndex */
|
|
||||||
KEY_TYPE_WEP40, /* KeyType */
|
|
||||||
zero_addr[key_idx],
|
|
||||||
0, /* DefaultKey */
|
|
||||||
hwkey); /* KeyContent */
|
|
||||||
} else if (wrqu->encoding.length == 0xd) {
|
|
||||||
ieee->pairwise_key_type = KEY_TYPE_WEP104;
|
|
||||||
EnableHWSecurityConfig8192(dev);
|
|
||||||
|
|
||||||
setKey(dev,
|
|
||||||
key_idx, /* EntryNo */
|
|
||||||
key_idx, /* KeyIndex */
|
|
||||||
KEY_TYPE_WEP104, /* KeyType */
|
|
||||||
zero_addr[key_idx],
|
|
||||||
0, /* DefaultKey */
|
|
||||||
hwkey); /* KeyContent */
|
|
||||||
} else {
|
|
||||||
netdev_warn(dev, "wrong type in WEP, not WEP40 and WEP104\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int r8192_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa,
|
|
||||||
union iwreq_data *wrqu, char *p)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
int *parms = (int *)p;
|
|
||||||
int mode = parms[0];
|
|
||||||
|
|
||||||
priv->ieee80211->active_scan = mode;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int r8192_wx_set_retry(struct net_device *dev,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *extra)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
int err = 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 > R8180_MAX_RETRY) {
|
|
||||||
err = -EINVAL;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
if (wrqu->retry.flags & IW_RETRY_MAX) {
|
|
||||||
priv->retry_rts = wrqu->retry.value;
|
|
||||||
DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
priv->retry_data = wrqu->retry.value;
|
|
||||||
DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* FIXME !
|
|
||||||
* We might try to write directly the TX config register
|
|
||||||
* or to restart just the (R)TX process.
|
|
||||||
* I'm unsure if whole reset is really needed
|
|
||||||
*/
|
|
||||||
|
|
||||||
rtl8192_commit(dev);
|
|
||||||
exit:
|
|
||||||
mutex_unlock(&priv->wx_mutex);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int r8192_wx_get_retry(struct net_device *dev,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *extra)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = ieee80211_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 r8192_wx_get_sens(struct net_device *dev,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *extra)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
|
|
||||||
if (!priv->rf_set_sens)
|
|
||||||
return -1; /* we have not this support for this radio */
|
|
||||||
wrqu->sens.value = priv->sens;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int r8192_wx_set_sens(struct net_device *dev,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *extra)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
short err = 0;
|
|
||||||
|
|
||||||
mutex_lock(&priv->wx_mutex);
|
|
||||||
if (!priv->rf_set_sens) {
|
|
||||||
err = -1; /* we have not this support for this radio */
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
if (priv->rf_set_sens(dev, wrqu->sens.value) == 0)
|
|
||||||
priv->sens = wrqu->sens.value;
|
|
||||||
else
|
|
||||||
err = -EINVAL;
|
|
||||||
|
|
||||||
exit:
|
|
||||||
mutex_unlock(&priv->wx_mutex);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* hw security need to reorganized. */
|
|
||||||
static int r8192_wx_set_enc_ext(struct net_device *dev,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
union iwreq_data *wrqu, char *extra)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
struct ieee80211_device *ieee = priv->ieee80211;
|
|
||||||
|
|
||||||
mutex_lock(&priv->wx_mutex);
|
|
||||||
ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
|
|
||||||
|
|
||||||
{
|
|
||||||
u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
|
||||||
u8 zero[6] = {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)
|
|
||||||
/* none is not allowed to use hwsec WB 2008.07.01 */
|
|
||||||
goto end_hw_sec;
|
|
||||||
|
|
||||||
/* as IW_ENCODE_ALG_CCMP is defined to be 3 and KEY_TYPE_CCMP is defined to 4; */
|
|
||||||
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) || (ieee->iw_mode == IW_MODE_ADHOC) || (alg == KEY_TYPE_WEP40)) {
|
|
||||||
if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40))
|
|
||||||
alg = KEY_TYPE_WEP104;
|
|
||||||
ieee->pairwise_key_type = alg;
|
|
||||||
EnableHWSecurityConfig8192(dev);
|
|
||||||
}
|
|
||||||
memcpy((u8 *)key, ext->key, 16); /* we only get 16 bytes key.why? WB 2008.7.1 */
|
|
||||||
|
|
||||||
if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode != 2)) {
|
|
||||||
setKey(dev,
|
|
||||||
idx, /* EntryNao */
|
|
||||||
idx, /* KeyIndex */
|
|
||||||
alg, /* KeyType */
|
|
||||||
zero, /* MacAddr */
|
|
||||||
0, /* DefaultKey */
|
|
||||||
key); /* KeyContent */
|
|
||||||
} else if (group) {
|
|
||||||
ieee->group_key_type = alg;
|
|
||||||
setKey(dev,
|
|
||||||
idx, /* EntryNo */
|
|
||||||
idx, /* KeyIndex */
|
|
||||||
alg, /* KeyType */
|
|
||||||
broadcast_addr, /* MacAddr */
|
|
||||||
0, /* DefaultKey */
|
|
||||||
key); /* KeyContent */
|
|
||||||
} else { /* pairwise key */
|
|
||||||
setKey(dev,
|
|
||||||
4, /* EntryNo */
|
|
||||||
idx, /* KeyIndex */
|
|
||||||
alg, /* KeyType */
|
|
||||||
(u8 *)ieee->ap_mac_addr,/* MacAddr */
|
|
||||||
0, /* DefaultKey */
|
|
||||||
key); /* KeyContent */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
end_hw_sec:
|
|
||||||
|
|
||||||
mutex_unlock(&priv->wx_mutex);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int r8192_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 = ieee80211_priv(dev);
|
|
||||||
|
|
||||||
mutex_lock(&priv->wx_mutex);
|
|
||||||
ret = ieee80211_wx_set_auth(priv->ieee80211, info, &data->param, extra);
|
|
||||||
mutex_unlock(&priv->wx_mutex);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int r8192_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 = ieee80211_priv(dev);
|
|
||||||
|
|
||||||
mutex_lock(&priv->wx_mutex);
|
|
||||||
ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
|
|
||||||
|
|
||||||
mutex_unlock(&priv->wx_mutex);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int r8192_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 = ieee80211_priv(dev);
|
|
||||||
|
|
||||||
mutex_lock(&priv->wx_mutex);
|
|
||||||
ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length);
|
|
||||||
mutex_unlock(&priv->wx_mutex);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int dummy(struct net_device *dev, struct iw_request_info *a,
|
|
||||||
union iwreq_data *wrqu, char *b)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static iw_handler r8192_wx_handlers[] = {
|
|
||||||
NULL, /* SIOCSIWCOMMIT */
|
|
||||||
r8192_wx_get_name, /* SIOCGIWNAME */
|
|
||||||
dummy, /* SIOCSIWNWID */
|
|
||||||
dummy, /* SIOCGIWNWID */
|
|
||||||
r8192_wx_set_freq, /* SIOCSIWFREQ */
|
|
||||||
r8192_wx_get_freq, /* SIOCGIWFREQ */
|
|
||||||
r8192_wx_set_mode, /* SIOCSIWMODE */
|
|
||||||
r8192_wx_get_mode, /* SIOCGIWMODE */
|
|
||||||
r8192_wx_set_sens, /* SIOCSIWSENS */
|
|
||||||
r8192_wx_get_sens, /* SIOCGIWSENS */
|
|
||||||
NULL, /* SIOCSIWRANGE */
|
|
||||||
rtl8180_wx_get_range, /* SIOCGIWRANGE */
|
|
||||||
NULL, /* SIOCSIWPRIV */
|
|
||||||
NULL, /* SIOCGIWPRIV */
|
|
||||||
NULL, /* SIOCSIWSTATS */
|
|
||||||
NULL, /* SIOCGIWSTATS */
|
|
||||||
dummy, /* SIOCSIWSPY */
|
|
||||||
dummy, /* SIOCGIWSPY */
|
|
||||||
NULL, /* SIOCGIWTHRSPY */
|
|
||||||
NULL, /* SIOCWIWTHRSPY */
|
|
||||||
r8192_wx_set_wap, /* SIOCSIWAP */
|
|
||||||
r8192_wx_get_wap, /* SIOCGIWAP */
|
|
||||||
r8192_wx_set_mlme, /* MLME-- */
|
|
||||||
dummy, /* SIOCGIWAPLIST -- deprecated */
|
|
||||||
r8192_wx_set_scan, /* SIOCSIWSCAN */
|
|
||||||
r8192_wx_get_scan, /* SIOCGIWSCAN */
|
|
||||||
r8192_wx_set_essid, /* SIOCSIWESSID */
|
|
||||||
r8192_wx_get_essid, /* SIOCGIWESSID */
|
|
||||||
dummy, /* SIOCSIWNICKN */
|
|
||||||
dummy, /* SIOCGIWNICKN */
|
|
||||||
NULL, /* -- hole -- */
|
|
||||||
NULL, /* -- hole -- */
|
|
||||||
r8192_wx_set_rate, /* SIOCSIWRATE */
|
|
||||||
r8192_wx_get_rate, /* SIOCGIWRATE */
|
|
||||||
r8192_wx_set_rts, /* SIOCSIWRTS */
|
|
||||||
r8192_wx_get_rts, /* SIOCGIWRTS */
|
|
||||||
r8192_wx_set_frag, /* SIOCSIWFRAG */
|
|
||||||
r8192_wx_get_frag, /* SIOCGIWFRAG */
|
|
||||||
dummy, /* SIOCSIWTXPOW */
|
|
||||||
dummy, /* SIOCGIWTXPOW */
|
|
||||||
r8192_wx_set_retry, /* SIOCSIWRETRY */
|
|
||||||
r8192_wx_get_retry, /* SIOCGIWRETRY */
|
|
||||||
r8192_wx_set_enc, /* SIOCSIWENCODE */
|
|
||||||
r8192_wx_get_enc, /* SIOCGIWENCODE */
|
|
||||||
r8192_wx_set_power, /* SIOCSIWPOWER */
|
|
||||||
r8192_wx_get_power, /* SIOCGIWPOWER */
|
|
||||||
NULL, /*---hole---*/
|
|
||||||
NULL, /*---hole---*/
|
|
||||||
r8192_wx_set_gen_ie, /* NULL, */ /* SIOCSIWGENIE */
|
|
||||||
NULL, /* SIOCSIWGENIE */
|
|
||||||
|
|
||||||
r8192_wx_set_auth,/* NULL, */ /* SIOCSIWAUTH */
|
|
||||||
NULL,/* r8192_wx_get_auth, */ /* NULL, */ /* SIOCSIWAUTH */
|
|
||||||
r8192_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
|
|
||||||
NULL,/* r8192_wx_get_enc_ext, *//* NULL, */ /* SIOCSIWENCODEEXT */
|
|
||||||
NULL, /* SIOCSIWPMKSA */
|
|
||||||
NULL, /*---hole---*/
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct iw_priv_args r8192_private_args[] = {
|
|
||||||
{
|
|
||||||
SIOCIWFIRSTPRIV + 0x0,
|
|
||||||
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
SIOCIWFIRSTPRIV + 0x1,
|
|
||||||
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
|
|
||||||
|
|
||||||
},
|
|
||||||
{
|
|
||||||
SIOCIWFIRSTPRIV + 0x2,
|
|
||||||
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
SIOCIWFIRSTPRIV + 0x3,
|
|
||||||
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static iw_handler r8192_private_handler[] = {
|
|
||||||
r8192_wx_set_crcmon,
|
|
||||||
r8192_wx_set_scan_type,
|
|
||||||
r8192_wx_set_rawtx,
|
|
||||||
r8192_wx_force_reset,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
|
|
||||||
{
|
|
||||||
struct r8192_priv *priv = ieee80211_priv(dev);
|
|
||||||
struct ieee80211_device *ieee = priv->ieee80211;
|
|
||||||
struct iw_statistics *wstats = &priv->wstats;
|
|
||||||
int tmp_level = 0;
|
|
||||||
int tmp_qual = 0;
|
|
||||||
int tmp_noise = 0;
|
|
||||||
|
|
||||||
if (ieee->state < IEEE80211_LINKED) {
|
|
||||||
wstats->qual.qual = 0;
|
|
||||||
wstats->qual.level = 0;
|
|
||||||
wstats->qual.noise = 0;
|
|
||||||
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),
|
|
||||||
.private = r8192_private_handler,
|
|
||||||
.num_private = ARRAY_SIZE(r8192_private_handler),
|
|
||||||
.num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args),
|
|
||||||
.get_wireless_stats = r8192_get_wireless_stats,
|
|
||||||
.private_args = (struct iw_priv_args *)r8192_private_args,
|
|
||||||
};
|
|
@ -1,24 +0,0 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
/*
|
|
||||||
* This is part of rtl8180 OpenSource driver - v 0.3
|
|
||||||
* Copyright (C) Andrea Merello 2004 <andrea.merello@gmail.com>
|
|
||||||
*
|
|
||||||
* Parts of this driver are based on the GPL part of the official realtek driver
|
|
||||||
* Parts of this driver are based on the rtl8180 driver skeleton from Patric
|
|
||||||
* Schenke & Andres Salomon
|
|
||||||
* Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
|
|
||||||
*
|
|
||||||
* We want to thank the Authors of such projects and the Ndiswrapper project
|
|
||||||
* Authors.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* this file (will) contains wireless extension handlers */
|
|
||||||
|
|
||||||
#ifndef R8180_WX_H
|
|
||||||
#define R8180_WX_H
|
|
||||||
|
|
||||||
extern const struct iw_handler_def r8192_wx_handlers_def;
|
|
||||||
/* Enable the rtl819x_core.c to share this function, david 2008.9.22 */
|
|
||||||
struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev);
|
|
||||||
|
|
||||||
#endif
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user