Compare commits

...

No commits in common. "pristine-tar" and "kali/master" have entirely different histories.

542 changed files with 379867 additions and 12 deletions

0
.gitgnore Normal file
View File

46
BUILD_FOR_NETHUNTER.md Normal file
View File

@ -0,0 +1,46 @@
## Build Kernel Headers
```
cd [your kernel source directory]
make module_prepare
make modules_install INSTALL_MOD_PATH=../
```
## Build RTL8188EUS driver/modules
```
cd ../
git clone https://github.com/aircrack-ng/rtl8188eus -b v5.3.9
cd rtl8188eus
```
That command places this driver behind your kernel source directory (RECOMMENDED).
If you put it anywhere you might need to set the Makefile in this driver, but i won't explain it.
Now, do:
```
export ARCH=arm64
export SUBARCH=arm64
export CROSS_COMPILE=../toolchain/toolchain64/bin/aarch64-linux-android-
export KBUILD_KVER=3.10.73-NetHunter-something
```
arm64 is the device architecture.
CROSS_COMPILE is your toolchain directory.
KBUILD_KVER is your kernel build version, you can search for it in ../lib/modules (the place of your modules_install when you build kernel headers).
Now, do:
```
make
```
If there is no error or success you will see a file named 8188eu.ko in this driver directory.
## Load the driver (8188eu.ko)
```
su
cd /system/lib/modules
insmod 8188eu.ko
```

6
Kconfig Normal file
View File

@ -0,0 +1,6 @@
config RTL8188EU
tristate "Realtek 8188E USB WiFi"
depends on USB
---help---
Help message of RTL8188EU

2133
Makefile Executable file

File diff suppressed because it is too large Load Diff

79
README.md Normal file
View File

@ -0,0 +1,79 @@
## rtl8188eus v5.3.9
# Realtek rtl8188eus & rtl8188eu & rtl8188etv WiFi drivers
[![Monitor mode](https://img.shields.io/badge/monitor%20mode-supported-brightgreen.svg)](#)
[![Frame Injection](https://img.shields.io/badge/frame%20injection-supported-brightgreen.svg)](#)
[![MESH Mode](https://img.shields.io/badge/mesh%20mode-supported-brightgreen.svg)](#)
[![GitHub issues](https://img.shields.io/github/issues/aircrack-ng/rtl8188eus.svg)](https://github.com/aircrack-ng/rtl8188eus/issues)
[![GitHub forks](https://img.shields.io/github/forks/aircrack-ng/rtl8188eus.svg)](https://github.com/aircrack-ng/rtl8188eus/network)
[![GitHub stars](https://img.shields.io/github/stars/aircrack-ng/rtl8188eus.svg)](https://github.com/aircrack-ng/rtl8188eus/stargazers)
[![GitHub license](https://img.shields.io/github/license/aircrack-ng/rtl8812au.svg)](https://github.com/aircrack-ng/rtl8188eus/blob/master/LICENSE)<br>
[![Android](https://img.shields.io/badge/android%20(8)-supported-brightgreen.svg)](#)
[![aircrack-ng](https://img.shields.io/badge/aircrack--ng-supported-blue.svg)](#)
# Supports
* Android 12/13
* MESH Support
* Monitor mode
* Frame injection
* Up to kernel v6.5+
... And a bunch of various wifi chipsets
# Howto build/install
1. Compile and install the driver:
```
cd rtl8188eus
make && sudo make install
```
2. Blacklist another drivers in order to use this one:
```
echo 'blacklist r8188eu' | sudo tee -a '/etc/modprobe.d/realtek.conf'
echo 'blacklist rtl8xxxu' | sudo tee -a '/etc/modprobe.d/realtek.conf'
```
3. `reboot` or remove all drivers related to RTL8188 and reload this one:
```
rmmod r8188eu rtl8xxxu 8188eu
modprobe 8188eu
```
# MONITOR MODE howto
Use these steps to enter monitor mode.
```
sudo airmon-ng check kill
sudo ip link set <interface> down
sudo iw dev <interface> set type monitor
```
Frame injection test may be performed with
(after kernel v5.2 scanning is slow, run a scan or simply an airodump-ng first!)
```
sudo aireplay-ng -9 <interface>
```
# NetworkManager configuration
Add these lines below to "NetworkManager.conf" and ADD YOUR ADAPTER MAC below [keyfile]
This will make the Network-Manager ignore the device, and therefore don't cause problems.
```
[device]
wifi.scan-rand-mac-address=no
[ifupdown]
managed=false
[connection]
wifi.powersave=0
[main]
plugins=keyfile
[keyfile]
unmanaged-devices=mac:A7:A7:A7:A7:A7
```
# Credits
Realtek - https://www.realtek.com<br>
Alfa Networks - https://www.alfa.com.tw<br>
aircrack-ng. - https://www.aircrack-ng.org<br>
<br>
And all those who may be using or contributing to it of anykind. Thanks!<br>

BIN
ReleaseNotes.pdf Normal file

Binary file not shown.

2216
core/efuse/rtw_efuse.c Normal file

File diff suppressed because it is too large Load Diff

3668
core/mesh/rtw_mesh.c Normal file

File diff suppressed because it is too large Load Diff

520
core/mesh/rtw_mesh.h Normal file
View File

@ -0,0 +1,520 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#ifndef __RTW_MESH_H_
#define __RTW_MESH_H_
#ifndef CONFIG_AP_MODE
#error "CONFIG_RTW_MESH can't be enabled when CONFIG_AP_MODE is not defined\n"
#endif
#ifndef RTW_MESH_SCAN_RESULT_EXP_MS
#define RTW_MESH_SCAN_RESULT_EXP_MS (10 * 1000)
#endif
#ifndef RTW_MESH_OFFCH_CAND_FIND_INT_MS
#define RTW_MESH_OFFCH_CAND_FIND_INT_MS (10 * 1000)
#endif
#define RTW_MESH_TTL 31
#define RTW_MESH_PERR_MIN_INT 100
#define RTW_MESH_DEFAULT_ELEMENT_TTL 31
#define RTW_MESH_RANN_INTERVAL 5000
#define RTW_MESH_PATH_TO_ROOT_TIMEOUT 6000
#define RTW_MESH_DIAM_TRAVERSAL_TIME 50
#define RTW_MESH_PATH_TIMEOUT 5000
#define RTW_MESH_PREQ_MIN_INT 10
#define RTW_MESH_MAX_PREQ_RETRIES 4
#define RTW_MESH_MIN_DISCOVERY_TIMEOUT (2 * RTW_MESH_DIAM_TRAVERSAL_TIME)
#define RTW_MESH_ROOT_CONFIRMATION_INTERVAL 2000
#define RTW_MESH_PATH_REFRESH_TIME 1000
#define RTW_MESH_ROOT_INTERVAL 5000
#define RTW_MESH_SANE_METRIC_DELTA 100
#define RTW_MESH_MAX_ROOT_ADD_CHK_CNT 2
#define RTW_MESH_PLINK_UNKNOWN 0
#define RTW_MESH_PLINK_LISTEN 1
#define RTW_MESH_PLINK_OPN_SNT 2
#define RTW_MESH_PLINK_OPN_RCVD 3
#define RTW_MESH_PLINK_CNF_RCVD 4
#define RTW_MESH_PLINK_ESTAB 5
#define RTW_MESH_PLINK_HOLDING 6
#define RTW_MESH_PLINK_BLOCKED 7
extern const char *_rtw_mesh_plink_str[];
#define rtw_mesh_plink_str(s) ((s <= RTW_MESH_PLINK_BLOCKED) ? _rtw_mesh_plink_str[s] : _rtw_mesh_plink_str[RTW_MESH_PLINK_UNKNOWN])
#define RTW_MESH_PS_UNKNOWN 0
#define RTW_MESH_PS_ACTIVE 1
#define RTW_MESH_PS_LSLEEP 2
#define RTW_MESH_PS_DSLEEP 3
extern const char *_rtw_mesh_ps_str[];
#define rtw_mesh_ps_str(mps) ((mps <= RTW_MESH_PS_DSLEEP) ? _rtw_mesh_ps_str[mps] : _rtw_mesh_ps_str[RTW_MESH_PS_UNKNOWN])
#define GET_MESH_CONF_ELE_PATH_SEL_PROTO_ID(_iec) LE_BITS_TO_1BYTE(((u8 *)(_iec)) + 0, 0, 8)
#define GET_MESH_CONF_ELE_PATH_SEL_METRIC_ID(_iec) LE_BITS_TO_1BYTE(((u8 *)(_iec)) + 1, 0, 8)
#define GET_MESH_CONF_ELE_CONGEST_CTRL_MODE_ID(_iec) LE_BITS_TO_1BYTE(((u8 *)(_iec)) + 2, 0, 8)
#define GET_MESH_CONF_ELE_SYNC_METHOD_ID(_iec) LE_BITS_TO_1BYTE(((u8 *)(_iec)) + 3, 0, 8)
#define GET_MESH_CONF_ELE_AUTH_PROTO_ID(_iec) LE_BITS_TO_1BYTE(((u8 *)(_iec)) + 4, 0, 8)
#define GET_MESH_CONF_ELE_MESH_FORMATION(_iec) LE_BITS_TO_1BYTE(((u8 *)(_iec)) + 5, 0, 8)
#define GET_MESH_CONF_ELE_CTO_MGATE(_iec) LE_BITS_TO_1BYTE(((u8 *)(_iec)) + 5, 0, 1)
#define GET_MESH_CONF_ELE_NUM_OF_PEERINGS(_iec) LE_BITS_TO_1BYTE(((u8 *)(_iec)) + 5, 1, 6)
#define GET_MESH_CONF_ELE_CTO_AS(_iec) LE_BITS_TO_1BYTE(((u8 *)(_iec)) + 5, 7, 1)
#define GET_MESH_CONF_ELE_MESH_CAP(_iec) LE_BITS_TO_1BYTE(((u8 *)(_iec)) + 6, 0, 8)
#define GET_MESH_CONF_ELE_ACCEPT_PEERINGS(_iec) LE_BITS_TO_1BYTE(((u8 *)(_iec)) + 6, 0, 1)
#define GET_MESH_CONF_ELE_MCCA_SUP(_iec) LE_BITS_TO_1BYTE(((u8 *)(_iec)) + 6, 1, 1)
#define GET_MESH_CONF_ELE_MCCA_EN(_iec) LE_BITS_TO_1BYTE(((u8 *)(_iec)) + 6, 2, 1)
#define GET_MESH_CONF_ELE_FORWARDING(_iec) LE_BITS_TO_1BYTE(((u8 *)(_iec)) + 6, 3, 1)
#define GET_MESH_CONF_ELE_MBCA_EN(_iec) LE_BITS_TO_1BYTE(((u8 *)(_iec)) + 6, 4, 1)
#define GET_MESH_CONF_ELE_TBTT_ADJ(_iec) LE_BITS_TO_1BYTE(((u8 *)(_iec)) + 6, 5, 1)
#define GET_MESH_CONF_ELE_PS_LEVEL(_iec) LE_BITS_TO_1BYTE(((u8 *)(_iec)) + 6, 6, 1)
#define SET_MESH_CONF_ELE_PATH_SEL_PROTO_ID(_iec, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_iec)) + 0, 0, 8, _val)
#define SET_MESH_CONF_ELE_PATH_SEL_METRIC_ID(_iec, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_iec)) + 1, 0, 8, _val)
#define SET_MESH_CONF_ELE_CONGEST_CTRL_MODE_ID(_iec, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_iec)) + 2, 0, 8, _val)
#define SET_MESH_CONF_ELE_SYNC_METHOD_ID(_iec, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_iec)) + 3, 0, 8, _val)
#define SET_MESH_CONF_ELE_AUTH_PROTO_ID(_iec, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_iec)) + 4, 0, 8, _val)
#define SET_MESH_CONF_ELE_CTO_MGATE(_iec, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_iec)) + 5, 0, 1, _val)
#define SET_MESH_CONF_ELE_NUM_OF_PEERINGS(_iec, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_iec)) + 5, 1, 6, _val)
#define SET_MESH_CONF_ELE_CTO_AS(_iec, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_iec)) + 5, 7, 1, _val)
#define SET_MESH_CONF_ELE_ACCEPT_PEERINGS(_iec, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_iec)) + 6, 0, 1, _val)
#define SET_MESH_CONF_ELE_MCCA_SUP(_iec, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_iec)) + 6, 1, 1, _val)
#define SET_MESH_CONF_ELE_MCCA_EN(_iec, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_iec)) + 6, 2, 1, _val)
#define SET_MESH_CONF_ELE_FORWARDING(_iec, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_iec)) + 6, 3, 1, _val)
#define SET_MESH_CONF_ELE_MBCA_EN(_iec, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_iec)) + 6, 4, 1, _val)
#define SET_MESH_CONF_ELE_TBTT_ADJ(_iec, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_iec)) + 6, 5, 1, _val)
#define SET_MESH_CONF_ELE_PS_LEVEL(_iec, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_iec)) + 6, 6, 1, _val)
/* Mesh flags */
#define MESH_FLAGS_AE 0x3 /* mask */
#define MESH_FLAGS_AE_A4 0x1
#define MESH_FLAGS_AE_A5_A6 0x2
/* Max number of paths */
#define RTW_MESH_MAX_PATHS 1024
#define RTW_PREQ_Q_F_START 0x1
#define RTW_PREQ_Q_F_REFRESH 0x2
#define RTW_PREQ_Q_F_CHK 0x4
#define RTW_PREQ_Q_F_PEER_AKA 0x8
struct rtw_mesh_preq_queue {
_list list;
u8 dst[ETH_ALEN];
u8 flags;
};
extern const u8 ae_to_mesh_ctrl_len[];
enum mesh_frame_type {
MESH_UCAST_DATA = 0x0,
MESH_BMCAST_DATA = 0x1,
MESH_UCAST_PX_DATA = 0x2,
MESH_BMCAST_PX_DATA = 0x3,
MESH_MHOP_UCAST_ACT = 0x4,
MESH_MHOP_BMCAST_ACT = 0x5,
};
enum mpath_sel_frame_type {
MPATH_PREQ = 0,
MPATH_PREP,
MPATH_PERR,
MPATH_RANN
};
/**
* enum rtw_mesh_deferred_task_flags - mesh deferred tasks
*
*
*
* @RTW_MESH_WORK_HOUSEKEEPING: run the periodic mesh housekeeping tasks
* @RTW_MESH_WORK_ROOT: the mesh root station needs to send a frame
* @RTW_MESH_WORK_DRIFT_ADJUST: time to compensate for clock drift relative to other
* mesh nodes
* @RTW_MESH_WORK_MBSS_CHANGED: rebuild beacon and notify driver of BSS changes
*/
enum rtw_mesh_deferred_task_flags {
RTW_MESH_WORK_HOUSEKEEPING,
RTW_MESH_WORK_ROOT,
RTW_MESH_WORK_DRIFT_ADJUST,
RTW_MESH_WORK_MBSS_CHANGED,
};
#define RTW_MESH_MAX_PEER_CANDIDATES 15 /* aid consideration */
#define RTW_MESH_MAX_PEER_LINKS 8
#define RTW_MESH_PEER_LINK_TIMEOUT 20
#define RTW_MESH_PEER_CONF_DISABLED 0 /* special time value means no confirmation ongoing */
#if CONFIG_RTW_MESH_PEER_BLACKLIST
#define IS_PEER_CONF_DISABLED(plink) ((plink)->peer_conf_end_time == RTW_MESH_PEER_CONF_DISABLED)
#define IS_PEER_CONF_TIMEOUT(plink)(!IS_PEER_CONF_DISABLED(plink) && rtw_time_after(rtw_get_current_time(), (plink)->peer_conf_end_time))
#define SET_PEER_CONF_DISABLED(plink) (plink)->peer_conf_end_time = RTW_MESH_PEER_CONF_DISABLED
#define SET_PEER_CONF_END_TIME(plink, timeout_ms) \
do { \
(plink)->peer_conf_end_time = rtw_get_current_time() + rtw_ms_to_systime(timeout_ms); \
if ((plink)->peer_conf_end_time == RTW_MESH_PEER_CONF_DISABLED) \
(plink)->peer_conf_end_time++; \
} while (0)
#else
#define IS_PEER_CONF_DISABLED(plink) 1
#define IS_PEER_CONF_TIMEOUT(plink) 0
#define SET_PEER_CONF_DISABLED(plink) do {} while (0)
#define SET_PEER_CONF_END_TIME(plink, timeout_ms) do {} while (0)
#endif /* CONFIG_RTW_MESH_PEER_BLACKLIST */
#define RTW_MESH_CTO_MGATE_CONF_DISABLED 0 /* special time value means no confirmation ongoing */
#if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
#define IS_CTO_MGATE_CONF_DISABLED(plink) ((plink)->cto_mgate_conf_end_time == RTW_MESH_CTO_MGATE_CONF_DISABLED)
#define IS_CTO_MGATE_CONF_TIMEOUT(plink)(!IS_CTO_MGATE_CONF_DISABLED(plink) && rtw_time_after(rtw_get_current_time(), (plink)->cto_mgate_conf_end_time))
#define SET_CTO_MGATE_CONF_DISABLED(plink) (plink)->cto_mgate_conf_end_time = RTW_MESH_CTO_MGATE_CONF_DISABLED
#define SET_CTO_MGATE_CONF_END_TIME(plink, timeout_ms) \
do { \
(plink)->cto_mgate_conf_end_time = rtw_get_current_time() + rtw_ms_to_systime(timeout_ms); \
if ((plink)->cto_mgate_conf_end_time == RTW_MESH_CTO_MGATE_CONF_DISABLED) \
(plink)->cto_mgate_conf_end_time++; \
} while (0)
#else
#define IS_CTO_MGATE_CONF_DISABLED(plink) 1
#define IS_CTO_MGATE_CONF_TIMEOUT(plink) 0
#define SET_CTO_MGATE_CONF_DISABLED(plink) do {} while (0)
#define SET_CTO_MGATE_CONF_END_TIME(plink, timeout_ms) do {} while (0)
#endif /* CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST */
struct mesh_plink_ent {
u8 valid;
u8 addr[ETH_ALEN];
u8 plink_state;
#ifdef CONFIG_RTW_MESH_AEK
u8 aek_valid;
u8 aek[32];
#endif
u16 llid;
u16 plid;
#ifndef CONFIG_RTW_MESH_DRIVER_AID
u16 aid; /* aid assigned from upper layer */
#endif
u16 peer_aid; /* aid assigned from peer */
u8 chosen_pmk[16];
#ifdef CONFIG_RTW_MESH_AEK
u8 sel_pcs[4];
u8 l_nonce[32];
u8 p_nonce[32];
#endif
#ifdef CONFIG_RTW_MESH_DRIVER_AID
u8 *tx_conf_ies;
u16 tx_conf_ies_len;
#endif
u8 *rx_conf_ies;
u16 rx_conf_ies_len;
struct wlan_network *scanned;
#if CONFIG_RTW_MESH_PEER_BLACKLIST
systime peer_conf_end_time;
#endif
#if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
systime cto_mgate_conf_end_time;
#endif
};
#ifdef CONFIG_RTW_MESH_AEK
#define MESH_PLINK_AEK_VALID(ent) ent->aek_valid
#else
#define MESH_PLINK_AEK_VALID(ent) 0
#endif
struct mesh_plink_pool {
_lock lock;
u8 num; /* current ent being used */
struct mesh_plink_ent ent[RTW_MESH_MAX_PEER_CANDIDATES];
#if CONFIG_RTW_MESH_PEER_BLACKLIST
_queue peer_blacklist;
#endif
#if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
_queue cto_mgate_blacklist;
#endif
};
#define RTW_MESH_PEER_CONF_TIMEOUT_MS (20 * 1000)
#define RTW_MESH_PEER_BLACKLIST_TIMEOUT_MS (20 * 1000)
#define RTW_MESH_CTO_MGATE_CONF_TIMEOUT_MS (20 * 1000)
#define RTW_MESH_CTO_MGATE_BLACKLIST_TIMEOUT_MS (20 * 1000)
struct mesh_peer_sel_policy {
u32 scanr_exp_ms;
#if CONFIG_RTW_MESH_OFFCH_CAND
u32 offch_find_int_ms; /* 0 means no offch find by driver */
#endif
#if CONFIG_RTW_MESH_PEER_BLACKLIST
u32 peer_conf_timeout_ms;
u32 peer_blacklist_timeout_ms;
#endif
#if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
u8 cto_mgate_require;
u32 cto_mgate_conf_timeout_ms;
u32 cto_mgate_blacklist_timeout_ms;
#endif
};
/* b2u flags */
#define RTW_MESH_B2U_ALL BIT0
#define RTW_MESH_B2U_GA_UCAST BIT1 /* Group addressed unicast frame, forward only */
#define RTW_MESH_B2U_BCAST BIT2
#define RTW_MESH_B2U_IP_MCAST BIT3
#define rtw_msrc_b2u_policy_chk(flags, mda) ( \
(flags & RTW_MESH_B2U_ALL) \
|| ((flags & RTW_MESH_B2U_BCAST) && is_broadcast_mac_addr(mda)) \
|| ((flags & RTW_MESH_B2U_IP_MCAST) && (IP_MCAST_MAC(mda) || ICMPV6_MCAST_MAC(mda))) \
)
#define rtw_mfwd_b2u_policy_chk(flags, mda, ucst) ( \
(flags & RTW_MESH_B2U_ALL) \
|| ((flags & RTW_MESH_B2U_GA_UCAST) && ucst) \
|| ((flags & RTW_MESH_B2U_BCAST) && is_broadcast_mac_addr(mda)) \
|| ((flags & RTW_MESH_B2U_IP_MCAST) && (IP_MCAST_MAC(mda) || ICMPV6_MCAST_MAC(mda))) \
)
/**
* @sane_metric_delta: Controlling if trigger additional path check mechanism
* @max_root_add_chk_cnt: The retry cnt to send additional root confirmation
* PREQ through old(last) path
*/
struct rtw_mesh_cfg {
u8 max_peer_links; /* peering limit */
u32 plink_timeout; /* seconds */
u8 dot11MeshTTL;
u8 element_ttl;
u32 path_refresh_time;
u16 dot11MeshHWMPpreqMinInterval;
u16 dot11MeshHWMPnetDiameterTraversalTime;
u32 dot11MeshHWMPactivePathTimeout;
u8 dot11MeshHWMPmaxPREQretries;
u16 min_discovery_timeout;
u16 dot11MeshHWMPconfirmationInterval;
u16 dot11MeshHWMPperrMinInterval;
u8 dot11MeshHWMPRootMode;
BOOLEAN dot11MeshForwarding;
s32 rssi_threshold; /* in dBm, 0: no specified */
u16 dot11MeshHWMPRannInterval;
BOOLEAN dot11MeshGateAnnouncementProtocol;
u32 dot11MeshHWMPactivePathToRootTimeout;
u16 dot11MeshHWMProotInterval;
u8 path_gate_timeout_factor;
#ifdef CONFIG_RTW_MESH_ADD_ROOT_CHK
u16 sane_metric_delta;
u8 max_root_add_chk_cnt;
#endif
struct mesh_peer_sel_policy peer_sel_policy;
#if CONFIG_RTW_MESH_DATA_BMC_TO_UC
u8 b2u_flags_msrc;
u8 b2u_flags_mfwd;
#endif
};
struct rtw_mesh_stats {
u32 fwded_mcast; /* Mesh forwarded multicast frames */
u32 fwded_unicast; /* Mesh forwarded unicast frames */
u32 fwded_frames; /* Mesh total forwarded frames */
u32 dropped_frames_ttl; /* Not transmitted since mesh_ttl == 0*/
u32 dropped_frames_no_route; /* Not transmitted, no route found */
u32 dropped_frames_congestion;/* Not forwarded due to congestion */
u32 dropped_frames_duplicate;
u32 mrc_del_qlen; /* MRC entry deleted cause by queue length limit */
};
struct rtw_mrc;
struct rtw_mesh_info {
u8 mesh_id[NDIS_802_11_LENGTH_SSID];
size_t mesh_id_len;
/* Active Path Selection Protocol Identifier */
u8 mesh_pp_id;
/* Active Path Selection Metric Identifier */
u8 mesh_pm_id;
/* Congestion Control Mode Identifier */
u8 mesh_cc_id;
/* Synchronization Protocol Identifier */
u8 mesh_sp_id;
/* Authentication Protocol Identifier */
u8 mesh_auth_id;
struct mesh_plink_pool plink_ctl;
u32 mesh_seqnum;
/* MSTA's own hwmp sequence number */
u32 sn;
systime last_preq;
systime last_sn_update;
systime next_perr;
/* Last used Path Discovery ID */
u32 preq_id;
ATOMIC_T mpaths;
struct rtw_mesh_table *mesh_paths;
struct rtw_mesh_table *mpp_paths;
int mesh_paths_generation;
int mpp_paths_generation;
int num_gates;
struct rtw_mesh_stats mshstats;
_queue mpath_tx_queue;
u32 mpath_tx_queue_len;
struct tasklet_struct mpath_tx_tasklet;
struct rtw_mrc *mrc;
_lock mesh_preq_queue_lock;
struct rtw_mesh_preq_queue preq_queue;
int preq_queue_len;
};
extern const char *_action_self_protected_str[];
#define action_self_protected_str(action) ((action < RTW_ACT_SELF_PROTECTED_NUM) ? _action_self_protected_str[action] : _action_self_protected_str[0])
u8 *rtw_set_ie_mesh_id(u8 *buf, u32 *buf_len, const char *mesh_id, u8 id_len);
u8 *rtw_set_ie_mesh_config(u8 *buf, u32 *buf_len
, u8 path_sel_proto, u8 path_sel_metric, u8 congest_ctl_mode, u8 sync_method, u8 auth_proto
, u8 num_of_peerings, bool cto_mgate, bool cto_as
, bool accept_peerings, bool mcca_sup, bool mcca_en, bool forwarding
, bool mbca_en, bool tbtt_adj, bool ps_level);
int rtw_bss_is_same_mbss(WLAN_BSSID_EX *a, WLAN_BSSID_EX *b);
int rtw_bss_is_candidate_mesh_peer(WLAN_BSSID_EX *self, WLAN_BSSID_EX *target, u8 ch, u8 add_peer);
void rtw_chk_candidate_peer_notify(_adapter *adapter, struct wlan_network *scanned);
void rtw_mesh_peer_status_chk(_adapter *adapter);
#if CONFIG_RTW_MESH_OFFCH_CAND
u8 rtw_mesh_offch_candidate_accepted(_adapter *adapter);
u8 rtw_mesh_select_operating_ch(_adapter *adapter);
#endif
#if CONFIG_RTW_MESH_PEER_BLACKLIST
int rtw_mesh_peer_blacklist_add(_adapter *adapter, const u8 *addr);
int rtw_mesh_peer_blacklist_del(_adapter *adapter, const u8 *addr);
int rtw_mesh_peer_blacklist_search(_adapter *adapter, const u8 *addr);
void rtw_mesh_peer_blacklist_flush(_adapter *adapter);
void dump_mesh_peer_blacklist(void *sel, _adapter *adapter);
void dump_mesh_peer_blacklist_settings(void *sel, _adapter *adapter);
#endif
#if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
u8 rtw_mesh_cto_mgate_required(_adapter *adapter);
u8 rtw_mesh_cto_mgate_network_filter(_adapter *adapter, struct wlan_network *scanned);
int rtw_mesh_cto_mgate_blacklist_add(_adapter *adapter, const u8 *addr);
int rtw_mesh_cto_mgate_blacklist_del(_adapter *adapter, const u8 *addr);
int rtw_mesh_cto_mgate_blacklist_search(_adapter *adapter, const u8 *addr);
void rtw_mesh_cto_mgate_blacklist_flush(_adapter *adapter);
void dump_mesh_cto_mgate_blacklist(void *sel, _adapter *adapter);
void dump_mesh_cto_mgate_blacklist_settings(void *sel, _adapter *adapter);
#endif
void dump_mesh_peer_sel_policy(void *sel, _adapter *adapter);
void dump_mesh_networks(void *sel, _adapter *adapter);
int rtw_sae_check_frames(_adapter *adapter, const u8 *buf, u32 len, u8 tx);
int rtw_mesh_check_frames_tx(_adapter *adapter, const u8 **buf, size_t *len);
int rtw_mesh_check_frames_rx(_adapter *adapter, const u8 *buf, size_t len);
unsigned int on_action_self_protected(_adapter *adapter, union recv_frame *rframe);
bool rtw_mesh_update_bss_peering_status(_adapter *adapter, WLAN_BSSID_EX *bss);
bool rtw_mesh_update_bss_formation_info(_adapter *adapter, WLAN_BSSID_EX *bss);
bool rtw_mesh_update_bss_forwarding_state(_adapter *adapter, WLAN_BSSID_EX *bss);
struct mesh_plink_ent *_rtw_mesh_plink_get(_adapter *adapter, const u8 *hwaddr);
struct mesh_plink_ent *rtw_mesh_plink_get(_adapter *adapter, const u8 *hwaddr);
struct mesh_plink_ent *rtw_mesh_plink_get_no_estab_by_idx(_adapter *adapter, u8 idx);
int _rtw_mesh_plink_add(_adapter *adapter, const u8 *hwaddr);
int rtw_mesh_plink_add(_adapter *adapter, const u8 *hwaddr);
int rtw_mesh_plink_set_state(_adapter *adapter, const u8 *hwaddr, u8 state);
#ifdef CONFIG_RTW_MESH_AEK
int rtw_mesh_plink_set_aek(_adapter *adapter, const u8 *hwaddr, const u8 *aek);
#endif
#if CONFIG_RTW_MESH_PEER_BLACKLIST
int rtw_mesh_plink_set_peer_conf_timeout(_adapter *adapter, const u8 *hwaddr);
#endif
void _rtw_mesh_plink_del_ent(_adapter *adapter, struct mesh_plink_ent *ent);
int rtw_mesh_plink_del(_adapter *adapter, const u8 *hwaddr);
void rtw_mesh_plink_ctl_init(_adapter *adapter);
void rtw_mesh_plink_ctl_deinit(_adapter *adapter);
void dump_mesh_plink_ctl(void *sel, _adapter *adapter);
int rtw_mesh_peer_establish(_adapter *adapter, struct mesh_plink_ent *plink, struct sta_info *sta);
void _rtw_mesh_expire_peer_ent(_adapter *adapter, struct mesh_plink_ent *plink);
void rtw_mesh_expire_peer(_adapter *adapter, const u8 *peer_addr);
u8 rtw_mesh_ps_annc(_adapter *adapter, u8 ps);
unsigned int on_action_mesh(_adapter *adapter, union recv_frame *rframe);
void rtw_mesh_cfg_init(_adapter *adapter);
void rtw_mesh_cfg_init_max_peer_links(_adapter *adapter, u8 stack_conf);
void rtw_mesh_cfg_init_plink_timeout(_adapter *adapter, u32 stack_conf);
void rtw_mesh_init_mesh_info(_adapter *adapter);
void rtw_mesh_deinit_mesh_info(_adapter *adapter);
#if CONFIG_RTW_MESH_DATA_BMC_TO_UC
void dump_mesh_b2u_flags(void *sel, _adapter *adapter);
#endif
int rtw_mesh_addr_resolve(_adapter *adapter, struct xmit_frame *xframe, _pkt *pkt, _list *b2u_list);
s8 rtw_mesh_tx_set_whdr_mctrl_len(u8 mesh_frame_mode, struct pkt_attrib *attrib);
void rtw_mesh_tx_build_mctrl(_adapter *adapter, struct pkt_attrib *attrib, u8 *buf);
u8 rtw_mesh_tx_build_whdr(_adapter *adapter, struct pkt_attrib *attrib
, u16 *fctrl, struct rtw_ieee80211_hdr *whdr);
int rtw_mesh_rx_data_validate_hdr(_adapter *adapter, union recv_frame *rframe, struct sta_info **sta);
int rtw_mesh_rx_data_validate_mctrl(_adapter *adapter, union recv_frame *rframe
, const struct rtw_ieee80211s_hdr *mctrl, const u8 *mda, const u8 *msa
, u8 *mctrl_len, const u8 **da, const u8 **sa);
int rtw_mesh_rx_validate_mctrl_non_amsdu(_adapter *adapter, union recv_frame *rframe);
int rtw_mesh_rx_msdu_act_check(union recv_frame *rframe
, const u8 *mda, const u8 *msa
, const u8 *da, const u8 *sa
, struct rtw_ieee80211s_hdr *mctrl
, struct xmit_frame **fwd_frame, _list *b2u_list);
void dump_mesh_stats(void *sel, _adapter *adapter);
#if defined(PLATFORM_LINUX) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32))
#define rtw_lockdep_assert_held(l) lockdep_assert_held(l)
#define rtw_lockdep_is_held(l) lockdep_is_held(l)
#else
#error "TBD\n"
#endif
#include "rtw_mesh_pathtbl.h"
#include "rtw_mesh_hwmp.h"
#endif /* __RTW_MESH_H_ */

1656
core/mesh/rtw_mesh_hwmp.c Normal file

File diff suppressed because it is too large Load Diff

60
core/mesh/rtw_mesh_hwmp.h Normal file
View File

@ -0,0 +1,60 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#ifndef __RTW_MESH_HWMP_H_
#define __RTW_MESH_HWMP_H_
#ifndef DBG_RTW_HWMP
#define DBG_RTW_HWMP 0
#endif
#if DBG_RTW_HWMP
#define RTW_HWMP_DBG(fmt, arg...) RTW_PRINT(fmt, ##arg)
#else
#define RTW_HWMP_DBG(fmt, arg...) RTW_DBG(fmt, ##arg)
#endif
#ifndef INFO_RTW_HWMP
#define INFO_RTW_HWMP 0
#endif
#if INFO_RTW_HWMP
#define RTW_HWMP_INFO(fmt, arg...) RTW_PRINT(fmt, ##arg)
#else
#define RTW_HWMP_INFO(fmt, arg...) RTW_INFO(fmt, ##arg)
#endif
void rtw_ewma_err_rate_init(struct rtw_ewma_err_rate *e);
unsigned long rtw_ewma_err_rate_read(struct rtw_ewma_err_rate *e);
void rtw_ewma_err_rate_add(struct rtw_ewma_err_rate *e, unsigned long val);
int rtw_mesh_path_error_tx(_adapter *adapter,
u8 ttl, const u8 *target, u32 target_sn,
u16 target_rcode, const u8 *ra);
void rtw_ieee80211s_update_metric(_adapter *adapter, u8 mac_id,
u8 per, u8 rate,
u8 bw, u8 total_pkt);
void rtw_mesh_rx_path_sel_frame(_adapter *adapter, union recv_frame *rframe);
void rtw_mesh_queue_preq(struct rtw_mesh_path *mpath, u8 flags);
void rtw_mesh_path_start_discovery(_adapter *adapter);
void rtw_mesh_path_timer(void *ctx);
void rtw_mesh_path_tx_root_frame(_adapter *adapter);
void rtw_mesh_work_hdl(_workitem *work);
void rtw_ieee80211_mesh_path_timer(void *ctx);
void rtw_ieee80211_mesh_path_root_timer(void *ctx);
BOOLEAN rtw_ieee80211_mesh_root_setup(_adapter *adapter);
void rtw_mesh_work(_workitem *work);
void rtw_mesh_atlm_param_req_timer(void *ctx);
#endif /* __RTW_MESH_HWMP_H_ */

1082
core/mesh/rtw_mesh_pathtbl.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,202 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#ifndef __RTW_MESH_PATHTBL_H_
#define __RTW_MESH_PATHTBL_H_
#ifndef DBG_RTW_MPATH
#define DBG_RTW_MPATH 1
#endif
#if DBG_RTW_MPATH
#define RTW_MPATH_DBG(fmt, arg...) RTW_PRINT(fmt, ##arg)
#else
#define RTW_MPATH_DBG(fmt, arg...) do {} while (0)
#endif
/**
* enum rtw_mesh_path_flags - mesh path flags
*
* @RTW_MESH_PATH_ACTIVE: the mesh path can be used for forwarding
* @RTW_MESH_PATH_RESOLVING: the discovery process is running for this mesh path
* @RTW_MESH_PATH_SN_VALID: the mesh path contains a valid destination sequence
* number
* @RTW_MESH_PATH_FIXED: the mesh path has been manually set and should not be
* modified
* @RTW_MESH_PATH_RESOLVED: the mesh path can has been resolved
* @RTW_MESH_PATH_REQ_QUEUED: there is an unsent path request for this destination
* already queued up, waiting for the discovery process to start.
* @RTW_MESH_PATH_DELETED: the mesh path has been deleted and should no longer
* be used
* @RTW_MESH_PATH_ROOT_ADD_CHK: root additional check in root mode.
* With this flag, It will try the last used rann_snd_addr
* @RTW_MESH_PATH_PEER_AKA: only used toward a peer, only used in active keep
* alive mechanism. PREQ's da = path dst
*
* RTW_MESH_PATH_RESOLVED is used by the mesh path timer to
* decide when to stop or cancel the mesh path discovery.
*/
enum rtw_mesh_path_flags {
RTW_MESH_PATH_ACTIVE = BIT(0),
RTW_MESH_PATH_RESOLVING = BIT(1),
RTW_MESH_PATH_SN_VALID = BIT(2),
RTW_MESH_PATH_FIXED = BIT(3),
RTW_MESH_PATH_RESOLVED = BIT(4),
RTW_MESH_PATH_REQ_QUEUED = BIT(5),
RTW_MESH_PATH_DELETED = BIT(6),
RTW_MESH_PATH_ROOT_ADD_CHK = BIT(7),
RTW_MESH_PATH_PEER_AKA = BIT(8),
};
/**
* struct rtw_mesh_path - mesh path structure
*
* @dst: mesh path destination mac address
* @mpp: mesh proxy mac address
* @rhash: rhashtable list pointer
* @gate_list: list pointer for known gates list
* @sdata: mesh subif
* @next_hop: mesh neighbor to which frames for this destination will be
* forwarded
* @timer: mesh path discovery timer
* @frame_queue: pending queue for frames sent to this destination while the
* path is unresolved
* @rcu: rcu head for freeing mesh path
* @sn: target sequence number
* @metric: current metric to this destination
* @hop_count: hops to destination
* @exp_time: in jiffies, when the path will expire or when it expired
* @discovery_timeout: timeout (lapse in jiffies) used for the last discovery
* retry
* @discovery_retries: number of discovery retries
* @flags: mesh path flags, as specified on &enum rtw_mesh_path_flags
* @state_lock: mesh path state lock used to protect changes to the
* mpath itself. No need to take this lock when adding or removing
* an mpath to a hash bucket on a path table.
* @rann_snd_addr: the RANN sender address
* @rann_metric: the aggregated path metric towards the root node
* @last_preq_to_root: Timestamp of last PREQ sent to root
* @is_root: the destination station of this path is a root node
* @is_gate: the destination station of this path is a mesh gate
*
*
* The dst address is unique in the mesh path table. Since the mesh_path is
* protected by RCU, deleting the next_hop STA must remove / substitute the
* mesh_path structure and wait until that is no longer reachable before
* destroying the STA completely.
*/
struct rtw_mesh_path {
u8 dst[ETH_ALEN];
u8 mpp[ETH_ALEN]; /* used for MPP or MAP */
rtw_rhash_head rhash;
rtw_hlist_node gate_list;
_adapter *adapter;
struct sta_info __rcu *next_hop;
_timer timer;
_queue frame_queue;
u32 frame_queue_len;
rtw_rcu_head rcu;
u32 sn;
u32 metric;
u8 hop_count;
systime exp_time;
systime discovery_timeout;
systime gate_timeout;
u32 gate_ann_int; /* gate announce interval */
u8 discovery_retries;
enum rtw_mesh_path_flags flags;
_lock state_lock;
u8 rann_snd_addr[ETH_ALEN];
#ifdef CONFIG_RTW_MESH_ADD_ROOT_CHK
u8 add_chk_rann_snd_addr[ETH_ALEN];
#endif
u32 rann_metric;
unsigned long last_preq_to_root;
bool is_root;
bool is_gate;
bool gate_asked;
};
/**
* struct rtw_mesh_table
*
* @known_gates: list of known mesh gates and their mpaths by the station. The
* gate's mpath may or may not be resolved and active.
* @gates_lock: protects updates to known_gates
* @rhead: the rhashtable containing struct mesh_paths, keyed by dest addr
* @entries: number of entries in the table
*/
struct rtw_mesh_table {
rtw_hlist_head known_gates;
_lock gates_lock;
rtw_rhashtable rhead;
ATOMIC_T entries;
};
#define RTW_MESH_PATH_EXPIRE (600 * HZ)
/* Maximum number of paths per interface */
#define RTW_MESH_MAX_MPATHS 1024
/* Number of frames buffered per destination for unresolved destinations */
#define RTW_MESH_FRAME_QUEUE_LEN 10
int rtw_mesh_nexthop_lookup(_adapter *adapter,
const u8 *mda, const u8 *msa, u8 *ra);
int rtw_mesh_nexthop_resolve(_adapter *adapter,
struct xmit_frame *xframe);
struct rtw_mesh_path *rtw_mesh_path_lookup(_adapter *adapter,
const u8 *dst);
struct rtw_mesh_path *rtw_mpp_path_lookup(_adapter *adapter,
const u8 *dst);
int rtw_mpp_path_add(_adapter *adapter,
const u8 *dst, const u8 *mpp);
struct rtw_mesh_path *
rtw_mesh_path_lookup_by_idx(_adapter *adapter, int idx);
struct rtw_mesh_path *
rtw_mpp_path_lookup_by_idx(_adapter *adapter, int idx);
void rtw_mesh_path_fix_nexthop(struct rtw_mesh_path *mpath, struct sta_info *next_hop);
void rtw_mesh_path_expire(_adapter *adapter);
struct rtw_mesh_path *
rtw_mesh_path_add(_adapter *adapter, const u8 *dst);
int rtw_mesh_path_add_gate(struct rtw_mesh_path *mpath);
void rtw_mesh_gate_del(struct rtw_mesh_table *tbl, struct rtw_mesh_path *mpath);
bool rtw_mesh_gate_search(struct rtw_mesh_table *tbl, const u8 *addr);
int rtw_mesh_path_send_to_gates(struct rtw_mesh_path *mpath);
int rtw_mesh_gate_num(_adapter *adapter);
void rtw_mesh_plink_broken(struct sta_info *sta);
void rtw_mesh_path_assign_nexthop(struct rtw_mesh_path *mpath, struct sta_info *sta);
void rtw_mesh_path_flush_pending(struct rtw_mesh_path *mpath);
void rtw_mesh_path_tx_pending(struct rtw_mesh_path *mpath);
int rtw_mesh_pathtbl_init(_adapter *adapter);
void rtw_mesh_pathtbl_unregister(_adapter *adapter);
int rtw_mesh_path_del(_adapter *adapter, const u8 *addr);
void rtw_mesh_path_flush_by_nexthop(struct sta_info *sta);
void rtw_mesh_path_discard_frame(_adapter *adapter,
struct xmit_frame *xframe);
static inline void rtw_mesh_path_activate(struct rtw_mesh_path *mpath)
{
mpath->flags |= RTW_MESH_PATH_ACTIVE | RTW_MESH_PATH_RESOLVED;
}
void rtw_mesh_path_flush_by_iface(_adapter *adapter);
#endif /* __RTW_MESH_PATHTBL_H_ */

5033
core/rtw_ap.c Normal file

File diff suppressed because it is too large Load Diff

3155
core/rtw_beamforming.c Normal file

File diff suppressed because it is too large Load Diff

1594
core/rtw_br_ext.c Normal file

File diff suppressed because it is too large Load Diff

1575
core/rtw_bt_mp.c Normal file

File diff suppressed because it is too large Load Diff

1763
core/rtw_btcoex.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,42 @@
/******************************************************************************
*
* Copyright(c) 2013 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#include <drv_types.h>
#include <hal_btcoex_wifionly.h>
#include <hal_data.h>
void rtw_btcoex_wifionly_switchband_notify(PADAPTER padapter)
{
hal_btcoex_wifionly_switchband_notify(padapter);
}
void rtw_btcoex_wifionly_scan_notify(PADAPTER padapter)
{
hal_btcoex_wifionly_scan_notify(padapter);
}
void rtw_btcoex_wifionly_hw_config(PADAPTER padapter)
{
hal_btcoex_wifionly_hw_config(padapter);
}
void rtw_btcoex_wifionly_initialize(PADAPTER padapter)
{
hal_btcoex_wifionly_initlizevariables(padapter);
}
void rtw_btcoex_wifionly_AntInfoSetting(PADAPTER padapter)
{
hal_btcoex_wifionly_AntInfoSetting(padapter);
}

5069
core/rtw_cmd.c Normal file

File diff suppressed because it is too large Load Diff

6167
core/rtw_debug.c Normal file

File diff suppressed because it is too large Load Diff

369
core/rtw_eeprom.c Normal file
View File

@ -0,0 +1,369 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#define _RTW_EEPROM_C_
#include <drv_conf.h>
#include <osdep_service.h>
#include <drv_types.h>
void up_clk(_adapter *padapter, u16 *x)
{
*x = *x | _EESK;
rtw_write8(padapter, EE_9346CR, (u8)*x);
rtw_udelay_os(CLOCK_RATE);
}
void down_clk(_adapter *padapter, u16 *x)
{
*x = *x & ~_EESK;
rtw_write8(padapter, EE_9346CR, (u8)*x);
rtw_udelay_os(CLOCK_RATE);
}
void shift_out_bits(_adapter *padapter, u16 data, u16 count)
{
u16 x, mask;
if (rtw_is_surprise_removed(padapter)) {
goto out;
}
mask = 0x01 << (count - 1);
x = rtw_read8(padapter, EE_9346CR);
x &= ~(_EEDO | _EEDI);
do {
x &= ~_EEDI;
if (data & mask)
x |= _EEDI;
if (rtw_is_surprise_removed(padapter)) {
goto out;
}
rtw_write8(padapter, EE_9346CR, (u8)x);
rtw_udelay_os(CLOCK_RATE);
up_clk(padapter, &x);
down_clk(padapter, &x);
mask = mask >> 1;
} while (mask);
if (rtw_is_surprise_removed(padapter)) {
goto out;
}
x &= ~_EEDI;
rtw_write8(padapter, EE_9346CR, (u8)x);
out:
return;
}
u16 shift_in_bits(_adapter *padapter)
{
u16 x, d = 0, i;
if (rtw_is_surprise_removed(padapter)) {
goto out;
}
x = rtw_read8(padapter, EE_9346CR);
x &= ~(_EEDO | _EEDI);
d = 0;
for (i = 0; i < 16; i++) {
d = d << 1;
up_clk(padapter, &x);
if (rtw_is_surprise_removed(padapter)) {
goto out;
}
x = rtw_read8(padapter, EE_9346CR);
x &= ~(_EEDI);
if (x & _EEDO)
d |= 1;
down_clk(padapter, &x);
}
out:
return d;
}
void standby(_adapter *padapter)
{
u8 x;
x = rtw_read8(padapter, EE_9346CR);
x &= ~(_EECS | _EESK);
rtw_write8(padapter, EE_9346CR, x);
rtw_udelay_os(CLOCK_RATE);
x |= _EECS;
rtw_write8(padapter, EE_9346CR, x);
rtw_udelay_os(CLOCK_RATE);
}
u16 wait_eeprom_cmd_done(_adapter *padapter)
{
u8 x;
u16 i, res = _FALSE;
standby(padapter);
for (i = 0; i < 200; i++) {
x = rtw_read8(padapter, EE_9346CR);
if (x & _EEDO) {
res = _TRUE;
goto exit;
}
rtw_udelay_os(CLOCK_RATE);
}
exit:
return res;
}
void eeprom_clean(_adapter *padapter)
{
u16 x;
if (rtw_is_surprise_removed(padapter)) {
goto out;
}
x = rtw_read8(padapter, EE_9346CR);
if (rtw_is_surprise_removed(padapter)) {
goto out;
}
x &= ~(_EECS | _EEDI);
rtw_write8(padapter, EE_9346CR, (u8)x);
if (rtw_is_surprise_removed(padapter)) {
goto out;
}
up_clk(padapter, &x);
if (rtw_is_surprise_removed(padapter)) {
goto out;
}
down_clk(padapter, &x);
out:
return;
}
void eeprom_write16(_adapter *padapter, u16 reg, u16 data)
{
u8 x;
#ifdef CONFIG_RTL8712
u8 tmp8_ori, tmp8_new, tmp8_clk_ori, tmp8_clk_new;
tmp8_ori = rtw_read8(padapter, 0x102502f1);
tmp8_new = tmp8_ori & 0xf7;
if (tmp8_ori != tmp8_new) {
rtw_write8(padapter, 0x102502f1, tmp8_new);
}
tmp8_clk_ori = rtw_read8(padapter, 0x10250003);
tmp8_clk_new = tmp8_clk_ori | 0x20;
if (tmp8_clk_new != tmp8_clk_ori) {
rtw_write8(padapter, 0x10250003, tmp8_clk_new);
}
#endif
x = rtw_read8(padapter, EE_9346CR);
x &= ~(_EEDI | _EEDO | _EESK | _EEM0);
x |= _EEM1 | _EECS;
rtw_write8(padapter, EE_9346CR, x);
shift_out_bits(padapter, EEPROM_EWEN_OPCODE, 5);
if (padapter->EepromAddressSize == 8) /* CF+ and SDIO */
shift_out_bits(padapter, 0, 6);
else /* USB */
shift_out_bits(padapter, 0, 4);
standby(padapter);
/* Commented out by rcnjko, 2004.0
* Erase this particular word. Write the erase opcode and register
* number in that order. The opcode is 3bits in length; reg is 6 bits long. */
/* shift_out_bits(Adapter, EEPROM_ERASE_OPCODE, 3);
* shift_out_bits(Adapter, reg, Adapter->EepromAddressSize);
*
* if (wait_eeprom_cmd_done(Adapter ) == FALSE)
* {
* return;
* } */
standby(padapter);
/* write the new word to the EEPROM */
/* send the write opcode the EEPORM */
shift_out_bits(padapter, EEPROM_WRITE_OPCODE, 3);
/* select which word in the EEPROM that we are writing to. */
shift_out_bits(padapter, reg, padapter->EepromAddressSize);
/* write the data to the selected EEPROM word. */
shift_out_bits(padapter, data, 16);
if (wait_eeprom_cmd_done(padapter) == _FALSE)
goto exit;
standby(padapter);
shift_out_bits(padapter, EEPROM_EWDS_OPCODE, 5);
shift_out_bits(padapter, reg, 4);
eeprom_clean(padapter);
exit:
#ifdef CONFIG_RTL8712
if (tmp8_clk_new != tmp8_clk_ori)
rtw_write8(padapter, 0x10250003, tmp8_clk_ori);
if (tmp8_new != tmp8_ori)
rtw_write8(padapter, 0x102502f1, tmp8_ori);
#endif
return;
}
u16 eeprom_read16(_adapter *padapter, u16 reg) /* ReadEEprom */
{
u16 x;
u16 data = 0;
#ifdef CONFIG_RTL8712
u8 tmp8_ori, tmp8_new, tmp8_clk_ori, tmp8_clk_new;
tmp8_ori = rtw_read8(padapter, 0x102502f1);
tmp8_new = tmp8_ori & 0xf7;
if (tmp8_ori != tmp8_new) {
rtw_write8(padapter, 0x102502f1, tmp8_new);
}
tmp8_clk_ori = rtw_read8(padapter, 0x10250003);
tmp8_clk_new = tmp8_clk_ori | 0x20;
if (tmp8_clk_new != tmp8_clk_ori) {
rtw_write8(padapter, 0x10250003, tmp8_clk_new);
}
#endif
if (rtw_is_surprise_removed(padapter)) {
goto out;
}
/* select EEPROM, reset bits, set _EECS */
x = rtw_read8(padapter, EE_9346CR);
if (rtw_is_surprise_removed(padapter)) {
goto out;
}
x &= ~(_EEDI | _EEDO | _EESK | _EEM0);
x |= _EEM1 | _EECS;
rtw_write8(padapter, EE_9346CR, (unsigned char)x);
/* write the read opcode and register number in that order */
/* The opcode is 3bits in length, reg is 6 bits long */
shift_out_bits(padapter, EEPROM_READ_OPCODE, 3);
shift_out_bits(padapter, reg, padapter->EepromAddressSize);
/* Now read the data (16 bits) in from the selected EEPROM word */
data = shift_in_bits(padapter);
eeprom_clean(padapter);
out:
#ifdef CONFIG_RTL8712
if (tmp8_clk_new != tmp8_clk_ori)
rtw_write8(padapter, 0x10250003, tmp8_clk_ori);
if (tmp8_new != tmp8_ori)
rtw_write8(padapter, 0x102502f1, tmp8_ori);
#endif
return data;
}
/* From even offset */
void eeprom_read_sz(_adapter *padapter, u16 reg, u8 *data, u32 sz)
{
u16 x, data16;
u32 i;
if (rtw_is_surprise_removed(padapter)) {
goto out;
}
/* select EEPROM, reset bits, set _EECS */
x = rtw_read8(padapter, EE_9346CR);
if (rtw_is_surprise_removed(padapter)) {
goto out;
}
x &= ~(_EEDI | _EEDO | _EESK | _EEM0);
x |= _EEM1 | _EECS;
rtw_write8(padapter, EE_9346CR, (unsigned char)x);
/* write the read opcode and register number in that order */
/* The opcode is 3bits in length, reg is 6 bits long */
shift_out_bits(padapter, EEPROM_READ_OPCODE, 3);
shift_out_bits(padapter, reg, padapter->EepromAddressSize);
for (i = 0; i < sz; i += 2) {
data16 = shift_in_bits(padapter);
data[i] = data16 & 0xff;
data[i + 1] = data16 >> 8;
}
eeprom_clean(padapter);
out:
return;
}
/* addr_off : address offset of the entry in eeprom (not the tuple number of eeprom (reg); that is addr_off !=reg) */
u8 eeprom_read(_adapter *padapter, u32 addr_off, u8 sz, u8 *rbuf)
{
u8 quotient, remainder, addr_2align_odd;
u16 reg, stmp , i = 0, idx = 0;
reg = (u16)(addr_off >> 1);
addr_2align_odd = (u8)(addr_off & 0x1);
if (addr_2align_odd) { /* read that start at high part: e.g 1,3,5,7,9,... */
stmp = eeprom_read16(padapter, reg);
rbuf[idx++] = (u8)((stmp >> 8) & 0xff); /* return hogh-part of the short */
reg++;
sz--;
}
quotient = sz >> 1;
remainder = sz & 0x1;
for (i = 0 ; i < quotient; i++) {
stmp = eeprom_read16(padapter, reg + i);
rbuf[idx++] = (u8)(stmp & 0xff);
rbuf[idx++] = (u8)((stmp >> 8) & 0xff);
}
reg = reg + i;
if (remainder) { /* end of read at lower part of short : 0,2,4,6,... */
stmp = eeprom_read16(padapter, reg);
rbuf[idx] = (u8)(stmp & 0xff);
}
return _TRUE;
}
VOID read_eeprom_content(_adapter *padapter)
{
}

2859
core/rtw_ieee80211.c Normal file

File diff suppressed because it is too large Load Diff

696
core/rtw_io.c Normal file
View File

@ -0,0 +1,696 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
/*
The purpose of rtw_io.c
a. provides the API
b. provides the protocol engine
c. provides the software interface between caller and the hardware interface
Compiler Flag Option:
1. CONFIG_SDIO_HCI:
a. USE_SYNC_IRP: Only sync operations are provided.
b. USE_ASYNC_IRP:Both sync/async operations are provided.
2. CONFIG_USB_HCI:
a. USE_ASYNC_IRP: Both sync/async operations are provided.
3. CONFIG_CFIO_HCI:
b. USE_SYNC_IRP: Only sync operations are provided.
Only sync read/rtw_write_mem operations are provided.
jackson@realtek.com.tw
*/
#define _RTW_IO_C_
#include <drv_types.h>
#include <hal_data.h>
#if defined(PLATFORM_LINUX) && defined (PLATFORM_WINDOWS)
#error "Shall be Linux or Windows, but not both!\n"
#endif
#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_PLATFORM_RTL8197D)
#define rtw_le16_to_cpu(val) val
#define rtw_le32_to_cpu(val) val
#define rtw_cpu_to_le16(val) val
#define rtw_cpu_to_le32(val) val
#else
#define rtw_le16_to_cpu(val) le16_to_cpu(val)
#define rtw_le32_to_cpu(val) le32_to_cpu(val)
#define rtw_cpu_to_le16(val) cpu_to_le16(val)
#define rtw_cpu_to_le32(val) cpu_to_le32(val)
#endif
u8 _rtw_read8(_adapter *adapter, u32 addr)
{
u8 r_val;
/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
u8(*_read8)(struct intf_hdl *pintfhdl, u32 addr);
_read8 = pintfhdl->io_ops._read8;
r_val = _read8(pintfhdl, addr);
return r_val;
}
u16 _rtw_read16(_adapter *adapter, u32 addr)
{
u16 r_val;
/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
u16(*_read16)(struct intf_hdl *pintfhdl, u32 addr);
_read16 = pintfhdl->io_ops._read16;
r_val = _read16(pintfhdl, addr);
return rtw_le16_to_cpu(r_val);
}
u32 _rtw_read32(_adapter *adapter, u32 addr)
{
u32 r_val;
/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
u32(*_read32)(struct intf_hdl *pintfhdl, u32 addr);
_read32 = pintfhdl->io_ops._read32;
r_val = _read32(pintfhdl, addr);
return rtw_le32_to_cpu(r_val);
}
int _rtw_write8(_adapter *adapter, u32 addr, u8 val)
{
/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
int (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
int ret;
_write8 = pintfhdl->io_ops._write8;
ret = _write8(pintfhdl, addr, val);
return RTW_STATUS_CODE(ret);
}
int _rtw_write16(_adapter *adapter, u32 addr, u16 val)
{
/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
int (*_write16)(struct intf_hdl *pintfhdl, u32 addr, u16 val);
int ret;
_write16 = pintfhdl->io_ops._write16;
val = rtw_cpu_to_le16(val);
ret = _write16(pintfhdl, addr, val);
return RTW_STATUS_CODE(ret);
}
int _rtw_write32(_adapter *adapter, u32 addr, u32 val)
{
/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
int (*_write32)(struct intf_hdl *pintfhdl, u32 addr, u32 val);
int ret;
_write32 = pintfhdl->io_ops._write32;
val = rtw_cpu_to_le32(val);
ret = _write32(pintfhdl, addr, val);
return RTW_STATUS_CODE(ret);
}
int _rtw_writeN(_adapter *adapter, u32 addr , u32 length , u8 *pdata)
{
/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = (struct intf_hdl *)(&(pio_priv->intf));
int (*_writeN)(struct intf_hdl *pintfhdl, u32 addr, u32 length, u8 *pdata);
int ret;
_writeN = pintfhdl->io_ops._writeN;
ret = _writeN(pintfhdl, addr, length, pdata);
return RTW_STATUS_CODE(ret);
}
#ifdef CONFIG_SDIO_HCI
u8 _rtw_sd_f0_read8(_adapter *adapter, u32 addr)
{
u8 r_val = 0x00;
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
u8(*_sd_f0_read8)(struct intf_hdl *pintfhdl, u32 addr);
_sd_f0_read8 = pintfhdl->io_ops._sd_f0_read8;
if (_sd_f0_read8)
r_val = _sd_f0_read8(pintfhdl, addr);
else
RTW_WARN(FUNC_ADPT_FMT" _sd_f0_read8 callback is NULL\n", FUNC_ADPT_ARG(adapter));
return r_val;
}
#ifdef CONFIG_SDIO_INDIRECT_ACCESS
u8 _rtw_sd_iread8(_adapter *adapter, u32 addr)
{
u8 r_val = 0x00;
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
u8(*_sd_iread8)(struct intf_hdl *pintfhdl, u32 addr);
_sd_iread8 = pintfhdl->io_ops._sd_iread8;
if (_sd_iread8)
r_val = _sd_iread8(pintfhdl, addr);
else
RTW_ERR(FUNC_ADPT_FMT" _sd_iread8 callback is NULL\n", FUNC_ADPT_ARG(adapter));
return r_val;
}
u16 _rtw_sd_iread16(_adapter *adapter, u32 addr)
{
u16 r_val = 0x00;
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
u16(*_sd_iread16)(struct intf_hdl *pintfhdl, u32 addr);
_sd_iread16 = pintfhdl->io_ops._sd_iread16;
if (_sd_iread16)
r_val = _sd_iread16(pintfhdl, addr);
else
RTW_ERR(FUNC_ADPT_FMT" _sd_iread16 callback is NULL\n", FUNC_ADPT_ARG(adapter));
return r_val;
}
u32 _rtw_sd_iread32(_adapter *adapter, u32 addr)
{
u32 r_val = 0x00;
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
u32(*_sd_iread32)(struct intf_hdl *pintfhdl, u32 addr);
_sd_iread32 = pintfhdl->io_ops._sd_iread32;
if (_sd_iread32)
r_val = _sd_iread32(pintfhdl, addr);
else
RTW_ERR(FUNC_ADPT_FMT" _sd_iread32 callback is NULL\n", FUNC_ADPT_ARG(adapter));
return r_val;
}
int _rtw_sd_iwrite8(_adapter *adapter, u32 addr, u8 val)
{
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
int (*_sd_iwrite8)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
int ret = -1;
_sd_iwrite8 = pintfhdl->io_ops._sd_iwrite8;
if (_sd_iwrite8)
ret = _sd_iwrite8(pintfhdl, addr, val);
else
RTW_ERR(FUNC_ADPT_FMT" _sd_iwrite8 callback is NULL\n", FUNC_ADPT_ARG(adapter));
return RTW_STATUS_CODE(ret);
}
int _rtw_sd_iwrite16(_adapter *adapter, u32 addr, u16 val)
{
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
int (*_sd_iwrite16)(struct intf_hdl *pintfhdl, u32 addr, u16 val);
int ret = -1;
_sd_iwrite16 = pintfhdl->io_ops._sd_iwrite16;
if (_sd_iwrite16)
ret = _sd_iwrite16(pintfhdl, addr, val);
else
RTW_ERR(FUNC_ADPT_FMT" _sd_iwrite16 callback is NULL\n", FUNC_ADPT_ARG(adapter));
return RTW_STATUS_CODE(ret);
}
int _rtw_sd_iwrite32(_adapter *adapter, u32 addr, u32 val)
{
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
int (*_sd_iwrite32)(struct intf_hdl *pintfhdl, u32 addr, u32 val);
int ret = -1;
_sd_iwrite32 = pintfhdl->io_ops._sd_iwrite32;
if (_sd_iwrite32)
ret = _sd_iwrite32(pintfhdl, addr, val);
else
RTW_ERR(FUNC_ADPT_FMT" _sd_iwrite32 callback is NULL\n", FUNC_ADPT_ARG(adapter));
return RTW_STATUS_CODE(ret);
}
#endif /* CONFIG_SDIO_INDIRECT_ACCESS */
#endif /* CONFIG_SDIO_HCI */
int _rtw_write8_async(_adapter *adapter, u32 addr, u8 val)
{
/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
int (*_write8_async)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
int ret;
_write8_async = pintfhdl->io_ops._write8_async;
ret = _write8_async(pintfhdl, addr, val);
return RTW_STATUS_CODE(ret);
}
int _rtw_write16_async(_adapter *adapter, u32 addr, u16 val)
{
/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
int (*_write16_async)(struct intf_hdl *pintfhdl, u32 addr, u16 val);
int ret;
_write16_async = pintfhdl->io_ops._write16_async;
val = rtw_cpu_to_le16(val);
ret = _write16_async(pintfhdl, addr, val);
return RTW_STATUS_CODE(ret);
}
int _rtw_write32_async(_adapter *adapter, u32 addr, u32 val)
{
/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
int (*_write32_async)(struct intf_hdl *pintfhdl, u32 addr, u32 val);
int ret;
_write32_async = pintfhdl->io_ops._write32_async;
val = rtw_cpu_to_le32(val);
ret = _write32_async(pintfhdl, addr, val);
return RTW_STATUS_CODE(ret);
}
void _rtw_read_mem(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
{
void (*_read_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
if (RTW_CANNOT_RUN(adapter)) {
return;
}
_read_mem = pintfhdl->io_ops._read_mem;
_read_mem(pintfhdl, addr, cnt, pmem);
}
void _rtw_write_mem(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
{
void (*_write_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
_write_mem = pintfhdl->io_ops._write_mem;
_write_mem(pintfhdl, addr, cnt, pmem);
}
void _rtw_read_port(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
{
u32(*_read_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
if (RTW_CANNOT_RUN(adapter)) {
return;
}
_read_port = pintfhdl->io_ops._read_port;
_read_port(pintfhdl, addr, cnt, pmem);
}
void _rtw_read_port_cancel(_adapter *adapter)
{
void (*_read_port_cancel)(struct intf_hdl *pintfhdl);
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
_read_port_cancel = pintfhdl->io_ops._read_port_cancel;
RTW_DISABLE_FUNC(adapter, DF_RX_BIT);
if (_read_port_cancel)
_read_port_cancel(pintfhdl);
}
u32 _rtw_write_port(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
{
u32(*_write_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
u32 ret = _SUCCESS;
_write_port = pintfhdl->io_ops._write_port;
ret = _write_port(pintfhdl, addr, cnt, pmem);
return ret;
}
u32 _rtw_write_port_and_wait(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem, int timeout_ms)
{
int ret = _SUCCESS;
struct xmit_buf *pxmitbuf = (struct xmit_buf *)pmem;
struct submit_ctx sctx;
rtw_sctx_init(&sctx, timeout_ms);
pxmitbuf->sctx = &sctx;
ret = _rtw_write_port(adapter, addr, cnt, pmem);
if (ret == _SUCCESS)
ret = rtw_sctx_wait(&sctx, __func__);
return ret;
}
void _rtw_write_port_cancel(_adapter *adapter)
{
void (*_write_port_cancel)(struct intf_hdl *pintfhdl);
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
_write_port_cancel = pintfhdl->io_ops._write_port_cancel;
RTW_DISABLE_FUNC(adapter, DF_TX_BIT);
if (_write_port_cancel)
_write_port_cancel(pintfhdl);
}
int rtw_init_io_priv(_adapter *padapter, void (*set_intf_ops)(_adapter *padapter, struct _io_ops *pops))
{
struct io_priv *piopriv = &padapter->iopriv;
struct intf_hdl *pintf = &piopriv->intf;
if (set_intf_ops == NULL)
return _FAIL;
piopriv->padapter = padapter;
pintf->padapter = padapter;
pintf->pintf_dev = adapter_to_dvobj(padapter);
set_intf_ops(padapter, &pintf->io_ops);
return _SUCCESS;
}
/*
* Increase and check if the continual_io_error of this @param dvobjprive is larger than MAX_CONTINUAL_IO_ERR
* @return _TRUE:
* @return _FALSE:
*/
int rtw_inc_and_chk_continual_io_error(struct dvobj_priv *dvobj)
{
int ret = _FALSE;
int value;
value = ATOMIC_INC_RETURN(&dvobj->continual_io_error);
if (value > MAX_CONTINUAL_IO_ERR) {
RTW_INFO("[dvobj:%p][ERROR] continual_io_error:%d > %d\n", dvobj, value, MAX_CONTINUAL_IO_ERR);
ret = _TRUE;
} else {
/* RTW_INFO("[dvobj:%p] continual_io_error:%d\n", dvobj, value); */
}
return ret;
}
/*
* Set the continual_io_error of this @param dvobjprive to 0
*/
void rtw_reset_continual_io_error(struct dvobj_priv *dvobj)
{
ATOMIC_SET(&dvobj->continual_io_error, 0);
}
#ifdef DBG_IO
u32 read_sniff_ranges[][2] = {
/* {0x520, 0x523}, */
};
u32 write_sniff_ranges[][2] = {
/* {0x520, 0x523}, */
/* {0x4c, 0x4c}, */
};
int read_sniff_num = sizeof(read_sniff_ranges) / sizeof(u32) / 2;
int write_sniff_num = sizeof(write_sniff_ranges) / sizeof(u32) / 2;
bool match_read_sniff_ranges(u32 addr, u16 len)
{
int i;
for (i = 0; i < read_sniff_num; i++) {
if (addr + len > read_sniff_ranges[i][0] && addr <= read_sniff_ranges[i][1])
return _TRUE;
}
return _FALSE;
}
bool match_write_sniff_ranges(u32 addr, u16 len)
{
int i;
for (i = 0; i < write_sniff_num; i++) {
if (addr + len > write_sniff_ranges[i][0] && addr <= write_sniff_ranges[i][1])
return _TRUE;
}
return _FALSE;
}
struct rf_sniff_ent {
u8 path;
u16 reg;
u32 mask;
};
struct rf_sniff_ent rf_read_sniff_ranges[] = {
/* example for all path addr 0x55 with all RF Reg mask */
/* {MAX_RF_PATH, 0x55, bRFRegOffsetMask}, */
};
struct rf_sniff_ent rf_write_sniff_ranges[] = {
/* example for all path addr 0x55 with all RF Reg mask */
/* {MAX_RF_PATH, 0x55, bRFRegOffsetMask}, */
};
int rf_read_sniff_num = sizeof(rf_read_sniff_ranges) / sizeof(struct rf_sniff_ent);
int rf_write_sniff_num = sizeof(rf_write_sniff_ranges) / sizeof(struct rf_sniff_ent);
bool match_rf_read_sniff_ranges(u8 path, u32 addr, u32 mask)
{
int i;
for (i = 0; i < rf_read_sniff_num; i++) {
if (rf_read_sniff_ranges[i].path == MAX_RF_PATH || rf_read_sniff_ranges[i].path == path)
if (addr == rf_read_sniff_ranges[i].reg && (mask & rf_read_sniff_ranges[i].mask))
return _TRUE;
}
return _FALSE;
}
bool match_rf_write_sniff_ranges(u8 path, u32 addr, u32 mask)
{
int i;
for (i = 0; i < rf_write_sniff_num; i++) {
if (rf_write_sniff_ranges[i].path == MAX_RF_PATH || rf_write_sniff_ranges[i].path == path)
if (addr == rf_write_sniff_ranges[i].reg && (mask & rf_write_sniff_ranges[i].mask))
return _TRUE;
}
return _FALSE;
}
u8 dbg_rtw_read8(_adapter *adapter, u32 addr, const char *caller, const int line)
{
u8 val = _rtw_read8(adapter, addr);
if (match_read_sniff_ranges(addr, 1))
RTW_INFO("DBG_IO %s:%d rtw_read8(0x%04x) return 0x%02x\n", caller, line, addr, val);
return val;
}
u16 dbg_rtw_read16(_adapter *adapter, u32 addr, const char *caller, const int line)
{
u16 val = _rtw_read16(adapter, addr);
if (match_read_sniff_ranges(addr, 2))
RTW_INFO("DBG_IO %s:%d rtw_read16(0x%04x) return 0x%04x\n", caller, line, addr, val);
return val;
}
u32 dbg_rtw_read32(_adapter *adapter, u32 addr, const char *caller, const int line)
{
u32 val = _rtw_read32(adapter, addr);
if (match_read_sniff_ranges(addr, 4))
RTW_INFO("DBG_IO %s:%d rtw_read32(0x%04x) return 0x%08x\n", caller, line, addr, val);
return val;
}
int dbg_rtw_write8(_adapter *adapter, u32 addr, u8 val, const char *caller, const int line)
{
if (match_write_sniff_ranges(addr, 1))
RTW_INFO("DBG_IO %s:%d rtw_write8(0x%04x, 0x%02x)\n", caller, line, addr, val);
return _rtw_write8(adapter, addr, val);
}
int dbg_rtw_write16(_adapter *adapter, u32 addr, u16 val, const char *caller, const int line)
{
if (match_write_sniff_ranges(addr, 2))
RTW_INFO("DBG_IO %s:%d rtw_write16(0x%04x, 0x%04x)\n", caller, line, addr, val);
return _rtw_write16(adapter, addr, val);
}
int dbg_rtw_write32(_adapter *adapter, u32 addr, u32 val, const char *caller, const int line)
{
if (match_write_sniff_ranges(addr, 4))
RTW_INFO("DBG_IO %s:%d rtw_write32(0x%04x, 0x%08x)\n", caller, line, addr, val);
return _rtw_write32(adapter, addr, val);
}
int dbg_rtw_writeN(_adapter *adapter, u32 addr , u32 length , u8 *data, const char *caller, const int line)
{
if (match_write_sniff_ranges(addr, length))
RTW_INFO("DBG_IO %s:%d rtw_writeN(0x%04x, %u)\n", caller, line, addr, length);
return _rtw_writeN(adapter, addr, length, data);
}
#ifdef CONFIG_SDIO_HCI
u8 dbg_rtw_sd_f0_read8(_adapter *adapter, u32 addr, const char *caller, const int line)
{
u8 val = _rtw_sd_f0_read8(adapter, addr);
#if 0
if (match_read_sniff_ranges(addr, 1))
RTW_INFO("DBG_IO %s:%d rtw_sd_f0_read8(0x%04x) return 0x%02x\n", caller, line, addr, val);
#endif
return val;
}
#ifdef CONFIG_SDIO_INDIRECT_ACCESS
u8 dbg_rtw_sd_iread8(_adapter *adapter, u32 addr, const char *caller, const int line)
{
u8 val = rtw_sd_iread8(adapter, addr);
if (match_read_sniff_ranges(addr, 1))
RTW_INFO("DBG_IO %s:%d rtw_sd_iread8(0x%04x) return 0x%02x\n", caller, line, addr, val);
return val;
}
u16 dbg_rtw_sd_iread16(_adapter *adapter, u32 addr, const char *caller, const int line)
{
u16 val = _rtw_sd_iread16(adapter, addr);
if (match_read_sniff_ranges(addr, 2))
RTW_INFO("DBG_IO %s:%d rtw_sd_iread16(0x%04x) return 0x%04x\n", caller, line, addr, val);
return val;
}
u32 dbg_rtw_sd_iread32(_adapter *adapter, u32 addr, const char *caller, const int line)
{
u32 val = _rtw_sd_iread32(adapter, addr);
if (match_read_sniff_ranges(addr, 4))
RTW_INFO("DBG_IO %s:%d rtw_sd_iread32(0x%04x) return 0x%08x\n", caller, line, addr, val);
return val;
}
int dbg_rtw_sd_iwrite8(_adapter *adapter, u32 addr, u8 val, const char *caller, const int line)
{
if (match_write_sniff_ranges(addr, 1))
RTW_INFO("DBG_IO %s:%d rtw_sd_iwrite8(0x%04x, 0x%02x)\n", caller, line, addr, val);
return _rtw_sd_iwrite8(adapter, addr, val);
}
int dbg_rtw_sd_iwrite16(_adapter *adapter, u32 addr, u16 val, const char *caller, const int line)
{
if (match_write_sniff_ranges(addr, 2))
RTW_INFO("DBG_IO %s:%d rtw_sd_iwrite16(0x%04x, 0x%04x)\n", caller, line, addr, val);
return _rtw_sd_iwrite16(adapter, addr, val);
}
int dbg_rtw_sd_iwrite32(_adapter *adapter, u32 addr, u32 val, const char *caller, const int line)
{
if (match_write_sniff_ranges(addr, 4))
RTW_INFO("DBG_IO %s:%d rtw_sd_iwrite32(0x%04x, 0x%08x)\n", caller, line, addr, val);
return _rtw_sd_iwrite32(adapter, addr, val);
}
#endif /* CONFIG_SDIO_INDIRECT_ACCESS */
#endif /* CONFIG_SDIO_HCI */
#endif

166
core/rtw_ioctl_query.c Normal file
View File

@ -0,0 +1,166 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#define _RTW_IOCTL_QUERY_C_
#include <drv_types.h>
#ifdef PLATFORM_WINDOWS
/*
* Added for WPA2-PSK, by Annie, 2005-09-20.
* */
u8
query_802_11_capability(
_adapter *Adapter,
u8 *pucBuf,
u32 *pulOutLen
)
{
static NDIS_802_11_AUTHENTICATION_ENCRYPTION szAuthEnc[] = {
{Ndis802_11AuthModeOpen, Ndis802_11EncryptionDisabled},
{Ndis802_11AuthModeOpen, Ndis802_11Encryption1Enabled},
{Ndis802_11AuthModeShared, Ndis802_11EncryptionDisabled},
{Ndis802_11AuthModeShared, Ndis802_11Encryption1Enabled},
{Ndis802_11AuthModeWPA, Ndis802_11Encryption2Enabled},
{Ndis802_11AuthModeWPA, Ndis802_11Encryption3Enabled},
{Ndis802_11AuthModeWPAPSK, Ndis802_11Encryption2Enabled},
{Ndis802_11AuthModeWPAPSK, Ndis802_11Encryption3Enabled},
{Ndis802_11AuthModeWPANone, Ndis802_11Encryption2Enabled},
{Ndis802_11AuthModeWPANone, Ndis802_11Encryption3Enabled},
{Ndis802_11AuthModeWPA2, Ndis802_11Encryption2Enabled},
{Ndis802_11AuthModeWPA2, Ndis802_11Encryption3Enabled},
{Ndis802_11AuthModeWPA2PSK, Ndis802_11Encryption2Enabled},
{Ndis802_11AuthModeWPA2PSK, Ndis802_11Encryption3Enabled}
};
static ULONG ulNumOfPairSupported = sizeof(szAuthEnc) / sizeof(NDIS_802_11_AUTHENTICATION_ENCRYPTION);
NDIS_802_11_CAPABILITY *pCap = (NDIS_802_11_CAPABILITY *)pucBuf;
u8 *pucAuthEncryptionSupported = (u8 *) pCap->AuthenticationEncryptionSupported;
pCap->Length = sizeof(NDIS_802_11_CAPABILITY);
if (ulNumOfPairSupported > 1)
pCap->Length += (ulNumOfPairSupported - 1) * sizeof(NDIS_802_11_AUTHENTICATION_ENCRYPTION);
pCap->Version = 2;
pCap->NoOfPMKIDs = NUM_PMKID_CACHE;
pCap->NoOfAuthEncryptPairsSupported = ulNumOfPairSupported;
if (sizeof(szAuthEnc) <= 240) /* 240 = 256 - 4*4 */ { /* SecurityInfo.szCapability: only 256 bytes in size. */
_rtw_memcpy(pucAuthEncryptionSupported, (u8 *)szAuthEnc, sizeof(szAuthEnc));
*pulOutLen = pCap->Length;
return _TRUE;
} else {
*pulOutLen = 0;
return _FALSE;
}
}
u8 query_802_11_association_information(_adapter *padapter, PNDIS_802_11_ASSOCIATION_INFORMATION pAssocInfo)
{
struct wlan_network *tgt_network;
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
struct security_priv *psecuritypriv = &(padapter->securitypriv);
WLAN_BSSID_EX *psecnetwork = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;
u8 *pDest = (u8 *)pAssocInfo + sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
unsigned char i, *auth_ie, *supp_ie;
/* NdisZeroMemory(pAssocInfo, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION)); */
_rtw_memset(pAssocInfo, 0, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION));
/* pAssocInfo->Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION); */
/* ------------------------------------------------------ */
/* Association Request related information */
/* ------------------------------------------------------ */
/* Req_1. AvailableRequestFixedIEs */
if (psecnetwork != NULL) {
pAssocInfo->AvailableRequestFixedIEs |= NDIS_802_11_AI_REQFI_CAPABILITIES | NDIS_802_11_AI_REQFI_CURRENTAPADDRESS;
pAssocInfo->RequestFixedIEs.Capabilities = (unsigned short) *&psecnetwork->IEs[10];
_rtw_memcpy(pAssocInfo->RequestFixedIEs.CurrentAPAddress,
&psecnetwork->MacAddress, 6);
pAssocInfo->OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING | _FW_LINKED) == _TRUE) {
if (psecuritypriv->ndisauthtype >= Ndis802_11AuthModeWPA2)
pDest[0] = 48; /* RSN Information Element */
else
pDest[0] = 221; /* WPA(SSN) Information Element */
supp_ie = &psecuritypriv->supplicant_ie[0];
i = 13; /* 0~11 is fixed information element */
while ((i < supp_ie[0]) && (i < 256)) {
if ((unsigned char)supp_ie[i] == pDest[0]) {
_rtw_memcpy((u8 *)(pDest),
&supp_ie[i],
supp_ie[1 + i] + 2);
break;
}
i = i + supp_ie[i + 1] + 2;
if (supp_ie[1 + i] == 0)
i = i + 1;
}
pAssocInfo->RequestIELength += (2 + supp_ie[1 + i]); /* (2 + psecnetwork->IEs[1+i]+4); */
}
}
/* ------------------------------------------------------ */
/* Association Response related information */
/* ------------------------------------------------------ */
if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
tgt_network = &(pmlmepriv->cur_network);
if (tgt_network != NULL) {
pAssocInfo->AvailableResponseFixedIEs =
NDIS_802_11_AI_RESFI_CAPABILITIES
| NDIS_802_11_AI_RESFI_ASSOCIATIONID
;
pAssocInfo->ResponseFixedIEs.Capabilities = (unsigned short) *&tgt_network->network.IEs[10];
pAssocInfo->ResponseFixedIEs.StatusCode = 0;
pAssocInfo->ResponseFixedIEs.AssociationId = (unsigned short) tgt_network->aid;
pDest = (u8 *)pAssocInfo + sizeof(NDIS_802_11_ASSOCIATION_INFORMATION) + pAssocInfo->RequestIELength;
auth_ie = &psecuritypriv->authenticator_ie[0];
i = auth_ie[0] - 12;
if (i > 0) {
_rtw_memcpy((u8 *)&pDest[0], &auth_ie[1], i);
pAssocInfo->ResponseIELength = i;
}
pAssocInfo->OffsetResponseIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION) + pAssocInfo->RequestIELength;
}
}
return _TRUE;
}
#endif

901
core/rtw_ioctl_rtl.c Normal file
View File

@ -0,0 +1,901 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#define _RTW_IOCTL_RTL_C_
#include <drv_types.h>
#ifdef CONFIG_MP_INCLUDED
#include <rtw_mp_ioctl.h>
#endif
struct oid_obj_priv oid_rtl_seg_01_01[] = {
{1, &oid_null_function}, /* 0x80 */
{1, &oid_null_function}, /* 0x81 */
{1, &oid_null_function}, /* 0x82 */
{1, &oid_null_function}, /* 0x83 */ /* OID_RT_SET_SNIFFER_MODE */
{1, &oid_rt_get_signal_quality_hdl}, /* 0x84 */
{1, &oid_rt_get_small_packet_crc_hdl}, /* 0x85 */
{1, &oid_rt_get_middle_packet_crc_hdl}, /* 0x86 */
{1, &oid_rt_get_large_packet_crc_hdl}, /* 0x87 */
{1, &oid_rt_get_tx_retry_hdl}, /* 0x88 */
{1, &oid_rt_get_rx_retry_hdl}, /* 0x89 */
{1, &oid_rt_pro_set_fw_dig_state_hdl}, /* 0x8A */
{1, &oid_rt_pro_set_fw_ra_state_hdl} , /* 0x8B */
{1, &oid_null_function}, /* 0x8C */
{1, &oid_null_function}, /* 0x8D */
{1, &oid_null_function}, /* 0x8E */
{1, &oid_null_function}, /* 0x8F */
{1, &oid_rt_get_rx_total_packet_hdl}, /* 0x90 */
{1, &oid_rt_get_tx_beacon_ok_hdl}, /* 0x91 */
{1, &oid_rt_get_tx_beacon_err_hdl}, /* 0x92 */
{1, &oid_rt_get_rx_icv_err_hdl}, /* 0x93 */
{1, &oid_rt_set_encryption_algorithm_hdl}, /* 0x94 */
{1, &oid_null_function}, /* 0x95 */
{1, &oid_rt_get_preamble_mode_hdl}, /* 0x96 */
{1, &oid_null_function}, /* 0x97 */
{1, &oid_rt_get_ap_ip_hdl}, /* 0x98 */
{1, &oid_rt_get_channelplan_hdl}, /* 0x99 */
{1, &oid_rt_set_preamble_mode_hdl}, /* 0x9A */
{1, &oid_rt_set_bcn_intvl_hdl}, /* 0x9B */
{1, &oid_null_function}, /* 0x9C */
{1, &oid_rt_dedicate_probe_hdl}, /* 0x9D */
{1, &oid_null_function}, /* 0x9E */
{1, &oid_null_function}, /* 0x9F */
{1, &oid_null_function}, /* 0xA0 */
{1, &oid_null_function}, /* 0xA1 */
{1, &oid_null_function}, /* 0xA2 */
{1, &oid_null_function}, /* 0xA3 */
{1, &oid_null_function}, /* 0xA4 */
{1, &oid_null_function}, /* 0xA5 */
{1, &oid_null_function}, /* 0xA6 */
{1, &oid_rt_get_total_tx_bytes_hdl}, /* 0xA7 */
{1, &oid_rt_get_total_rx_bytes_hdl}, /* 0xA8 */
{1, &oid_rt_current_tx_power_level_hdl}, /* 0xA9 */
{1, &oid_rt_get_enc_key_mismatch_count_hdl}, /* 0xAA */
{1, &oid_rt_get_enc_key_match_count_hdl}, /* 0xAB */
{1, &oid_rt_get_channel_hdl}, /* 0xAC */
{1, &oid_rt_set_channelplan_hdl}, /* 0xAD */
{1, &oid_rt_get_hardware_radio_off_hdl}, /* 0xAE */
{1, &oid_null_function}, /* 0xAF */
{1, &oid_null_function}, /* 0xB0 */
{1, &oid_null_function}, /* 0xB1 */
{1, &oid_null_function}, /* 0xB2 */
{1, &oid_null_function}, /* 0xB3 */
{1, &oid_rt_get_key_mismatch_hdl}, /* 0xB4 */
{1, &oid_null_function}, /* 0xB5 */
{1, &oid_null_function}, /* 0xB6 */
{1, &oid_null_function}, /* 0xB7 */
{1, &oid_null_function}, /* 0xB8 */
{1, &oid_null_function}, /* 0xB9 */
{1, &oid_null_function}, /* 0xBA */
{1, &oid_rt_supported_wireless_mode_hdl}, /* 0xBB */
{1, &oid_rt_get_channel_list_hdl}, /* 0xBC */
{1, &oid_rt_get_scan_in_progress_hdl}, /* 0xBD */
{1, &oid_null_function}, /* 0xBE */
{1, &oid_null_function}, /* 0xBF */
{1, &oid_null_function}, /* 0xC0 */
{1, &oid_rt_forced_data_rate_hdl}, /* 0xC1 */
{1, &oid_rt_wireless_mode_for_scan_list_hdl}, /* 0xC2 */
{1, &oid_rt_get_bss_wireless_mode_hdl}, /* 0xC3 */
{1, &oid_rt_scan_with_magic_packet_hdl}, /* 0xC4 */
{1, &oid_null_function}, /* 0xC5 */
{1, &oid_null_function}, /* 0xC6 */
{1, &oid_null_function}, /* 0xC7 */
{1, &oid_null_function}, /* 0xC8 */
{1, &oid_null_function}, /* 0xC9 */
{1, &oid_null_function}, /* 0xCA */
{1, &oid_null_function}, /* 0xCB */
{1, &oid_null_function}, /* 0xCC */
{1, &oid_null_function}, /* 0xCD */
{1, &oid_null_function}, /* 0xCE */
{1, &oid_null_function}, /* 0xCF */
};
struct oid_obj_priv oid_rtl_seg_01_03[] = {
{1, &oid_rt_ap_get_associated_station_list_hdl}, /* 0x00 */
{1, &oid_null_function}, /* 0x01 */
{1, &oid_rt_ap_switch_into_ap_mode_hdl}, /* 0x02 */
{1, &oid_null_function}, /* 0x03 */
{1, &oid_rt_ap_supported_hdl}, /* 0x04 */
{1, &oid_rt_ap_set_passphrase_hdl}, /* 0x05 */
};
struct oid_obj_priv oid_rtl_seg_01_11[] = {
{1, &oid_null_function}, /* 0xC0 OID_RT_PRO_RX_FILTER */
{1, &oid_null_function}, /* 0xC1 OID_CE_USB_WRITE_REGISTRY */
{1, &oid_null_function}, /* 0xC2 OID_CE_USB_READ_REGISTRY */
{1, &oid_null_function}, /* 0xC3 OID_RT_PRO_SET_INITIAL_GAIN */
{1, &oid_null_function}, /* 0xC4 OID_RT_PRO_SET_BB_RF_STANDBY_MODE */
{1, &oid_null_function}, /* 0xC5 OID_RT_PRO_SET_BB_RF_SHUTDOWN_MODE */
{1, &oid_null_function}, /* 0xC6 OID_RT_PRO_SET_TX_CHARGE_PUMP */
{1, &oid_null_function}, /* 0xC7 OID_RT_PRO_SET_RX_CHARGE_PUMP */
{1, &oid_rt_pro_rf_write_registry_hdl}, /* 0xC8 */
{1, &oid_rt_pro_rf_read_registry_hdl}, /* 0xC9 */
{1, &oid_null_function} /* 0xCA OID_RT_PRO_QUERY_RF_TYPE */
};
struct oid_obj_priv oid_rtl_seg_03_00[] = {
{1, &oid_null_function}, /* 0x00 */
{1, &oid_rt_get_connect_state_hdl}, /* 0x01 */
{1, &oid_null_function}, /* 0x02 */
{1, &oid_null_function}, /* 0x03 */
{1, &oid_rt_set_default_key_id_hdl}, /* 0x04 */
};
/* ************** oid_rtl_seg_01_01 section start ************** */
NDIS_STATUS oid_rt_pro_set_fw_dig_state_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
#if 0
PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context);
_irqL oldirql;
if (poid_par_priv->type_of_oid != SET_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
_irqlevel_changed_(&oldirql, LOWER);
if (poid_par_priv->information_buf_len >= sizeof(struct setdig_parm)) {
/* DEBUG_ERR(("===> oid_rt_pro_set_fw_dig_state_hdl. type:0x%02x.\n",*((unsigned char*)poid_par_priv->information_buf ))); */
if (!rtw_setfwdig_cmd(Adapter, *((unsigned char *)poid_par_priv->information_buf)))
status = NDIS_STATUS_NOT_ACCEPTED;
} else
status = NDIS_STATUS_NOT_ACCEPTED;
_irqlevel_changed_(&oldirql, RAISE);
#endif
return status;
}
/* ----------------------------------------------------------------------------- */
NDIS_STATUS oid_rt_pro_set_fw_ra_state_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
#if 0
PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context);
_irqL oldirql;
if (poid_par_priv->type_of_oid != SET_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
_irqlevel_changed_(&oldirql, LOWER);
if (poid_par_priv->information_buf_len >= sizeof(struct setra_parm)) {
/* DEBUG_ERR(("===> oid_rt_pro_set_fw_ra_state_hdl. type:0x%02x.\n",*((unsigned char*)poid_par_priv->information_buf ))); */
if (!rtw_setfwra_cmd(Adapter, *((unsigned char *)poid_par_priv->information_buf)))
status = NDIS_STATUS_NOT_ACCEPTED;
} else
status = NDIS_STATUS_NOT_ACCEPTED;
_irqlevel_changed_(&oldirql, RAISE);
#endif
return status;
}
/* ----------------------------------------------------------------------------- */
NDIS_STATUS oid_rt_get_signal_quality_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
/* DEBUG_ERR(("<**********************oid_rt_get_signal_quality_hdl\n")); */
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
#if 0
if (pMgntInfo->mAssoc || pMgntInfo->mIbss) {
ulInfo = pAdapter->RxStats.SignalQuality;
*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
} else {
ulInfo = 0xffffffff; /* It stands for -1 in 4-byte integer. */
}
break;
#endif
return status;
}
/* ------------------------------------------------------------------------------ */
NDIS_STATUS oid_rt_get_small_packet_crc_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
if (poid_par_priv->information_buf_len >= sizeof(ULONG)) {
*(ULONG *)poid_par_priv->information_buf = padapter->recvpriv.rx_smallpacket_crcerr;
*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
} else
status = NDIS_STATUS_INVALID_LENGTH;
return status;
}
/* ------------------------------------------------------------------------------ */
NDIS_STATUS oid_rt_get_middle_packet_crc_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
if (poid_par_priv->information_buf_len >= sizeof(ULONG)) {
*(ULONG *)poid_par_priv->information_buf = padapter->recvpriv.rx_middlepacket_crcerr;
*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
} else
status = NDIS_STATUS_INVALID_LENGTH;
return status;
}
/* ------------------------------------------------------------------------------ */
NDIS_STATUS oid_rt_get_large_packet_crc_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
if (poid_par_priv->information_buf_len >= sizeof(ULONG)) {
*(ULONG *)poid_par_priv->information_buf = padapter->recvpriv.rx_largepacket_crcerr;
*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
} else
status = NDIS_STATUS_INVALID_LENGTH;
return status;
}
/* ------------------------------------------------------------------------------ */
NDIS_STATUS oid_rt_get_tx_retry_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
return status;
}
NDIS_STATUS oid_rt_get_rx_retry_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
return status;
}
/* ------------------------------------------------------------------------------ */
NDIS_STATUS oid_rt_get_rx_total_packet_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
if (poid_par_priv->information_buf_len >= sizeof(ULONG)) {
*(u64 *)poid_par_priv->information_buf = padapter->recvpriv.rx_pkts + padapter->recvpriv.rx_drop;
*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
} else
status = NDIS_STATUS_INVALID_LENGTH;
return status;
}
/* ------------------------------------------------------------------------------ */
NDIS_STATUS oid_rt_get_tx_beacon_ok_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
return status;
}
NDIS_STATUS oid_rt_get_tx_beacon_err_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
return status;
}
/* ------------------------------------------------------------------------------ */
NDIS_STATUS oid_rt_get_rx_icv_err_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
if (poid_par_priv->information_buf_len >= sizeof(u32)) {
/* _rtw_memcpy(*(uint *)poid_par_priv->information_buf,padapter->recvpriv.rx_icv_err,sizeof(u32)); */
*(uint *)poid_par_priv->information_buf = padapter->recvpriv.rx_icv_err;
*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
} else
status = NDIS_STATUS_INVALID_LENGTH ;
return status;
}
/* ------------------------------------------------------------------------------ */
NDIS_STATUS oid_rt_set_encryption_algorithm_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != SET_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
return status;
}
/* ------------------------------------------------------------------------------ */
NDIS_STATUS oid_rt_get_preamble_mode_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
ULONG preamblemode = 0 ;
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
if (poid_par_priv->information_buf_len >= sizeof(ULONG)) {
if (padapter->registrypriv.preamble == PREAMBLE_LONG)
preamblemode = 0;
else if (padapter->registrypriv.preamble == PREAMBLE_AUTO)
preamblemode = 1;
else if (padapter->registrypriv.preamble == PREAMBLE_SHORT)
preamblemode = 2;
*(ULONG *)poid_par_priv->information_buf = preamblemode ;
*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
} else
status = NDIS_STATUS_INVALID_LENGTH ;
return status;
}
/* ------------------------------------------------------------------------------ */
NDIS_STATUS oid_rt_get_ap_ip_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
return status;
}
NDIS_STATUS oid_rt_get_channelplan_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
*(u16 *)poid_par_priv->information_buf = rfctl->ChannelPlan;
return status;
}
NDIS_STATUS oid_rt_set_channelplan_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
if (poid_par_priv->type_of_oid != SET_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
rfctl->ChannelPlan = *(u16 *)poid_par_priv->information_buf;
return status;
}
/* ------------------------------------------------------------------------------ */
NDIS_STATUS oid_rt_set_preamble_mode_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
ULONG preamblemode = 0;
if (poid_par_priv->type_of_oid != SET_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
if (poid_par_priv->information_buf_len >= sizeof(ULONG)) {
preamblemode = *(ULONG *)poid_par_priv->information_buf ;
if (preamblemode == 0)
padapter->registrypriv.preamble = PREAMBLE_LONG;
else if (preamblemode == 1)
padapter->registrypriv.preamble = PREAMBLE_AUTO;
else if (preamblemode == 2)
padapter->registrypriv.preamble = PREAMBLE_SHORT;
*(ULONG *)poid_par_priv->information_buf = preamblemode ;
*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
} else
status = NDIS_STATUS_INVALID_LENGTH ;
return status;
}
/* ------------------------------------------------------------------------------ */
NDIS_STATUS oid_rt_set_bcn_intvl_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != SET_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
return status;
}
NDIS_STATUS oid_rt_dedicate_probe_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
return status;
}
/* ------------------------------------------------------------------------------ */
NDIS_STATUS oid_rt_get_total_tx_bytes_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
if (poid_par_priv->information_buf_len >= sizeof(ULONG)) {
*(u64 *)poid_par_priv->information_buf = padapter->xmitpriv.tx_bytes;
*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
} else
status = NDIS_STATUS_INVALID_LENGTH ;
return status;
}
/* ------------------------------------------------------------------------------ */
NDIS_STATUS oid_rt_get_total_rx_bytes_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
if (poid_par_priv->information_buf_len >= sizeof(ULONG)) {
/* _rtw_memcpy(*(uint *)poid_par_priv->information_buf,padapter->recvpriv.rx_icv_err,sizeof(u32)); */
*(u64 *)poid_par_priv->information_buf = padapter->recvpriv.rx_bytes;
*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
} else
status = NDIS_STATUS_INVALID_LENGTH ;
return status;
}
/* ------------------------------------------------------------------------------ */
NDIS_STATUS oid_rt_current_tx_power_level_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
return status;
}
NDIS_STATUS oid_rt_get_enc_key_mismatch_count_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
return status;
}
NDIS_STATUS oid_rt_get_enc_key_match_count_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
return status;
}
NDIS_STATUS oid_rt_get_channel_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
NDIS_802_11_CONFIGURATION *pnic_Config;
ULONG channelnum;
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
if ((check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) ||
(check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE))
pnic_Config = &pmlmepriv->cur_network.network.Configuration;
else
pnic_Config = &padapter->registrypriv.dev_network.Configuration;
channelnum = pnic_Config->DSConfig;
*(ULONG *)poid_par_priv->information_buf = channelnum;
*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
return status;
}
NDIS_STATUS oid_rt_get_hardware_radio_off_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
return status;
}
NDIS_STATUS oid_rt_get_key_mismatch_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
return status;
}
NDIS_STATUS oid_rt_supported_wireless_mode_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
ULONG ulInfo = 0 ;
/* DEBUG_ERR(("<**********************oid_rt_supported_wireless_mode_hdl\n")); */
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
if (poid_par_priv->information_buf_len >= sizeof(ULONG)) {
ulInfo |= 0x0100; /* WIRELESS_MODE_B */
ulInfo |= 0x0200; /* WIRELESS_MODE_G */
ulInfo |= 0x0400; /* WIRELESS_MODE_A */
*(ULONG *) poid_par_priv->information_buf = ulInfo;
/* DEBUG_ERR(("<===oid_rt_supported_wireless_mode %x\n",ulInfo)); */
*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
} else
status = NDIS_STATUS_INVALID_LENGTH;
return status;
}
NDIS_STATUS oid_rt_get_channel_list_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
return status;
}
NDIS_STATUS oid_rt_get_scan_in_progress_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
return status;
}
NDIS_STATUS oid_rt_forced_data_rate_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
return status;
}
NDIS_STATUS oid_rt_wireless_mode_for_scan_list_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
return status;
}
NDIS_STATUS oid_rt_get_bss_wireless_mode_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
return status;
}
NDIS_STATUS oid_rt_scan_with_magic_packet_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
return status;
}
/* ************** oid_rtl_seg_01_01 section end ************** */
/* ************** oid_rtl_seg_01_03 section start ************** */
NDIS_STATUS oid_rt_ap_get_associated_station_list_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
return status;
}
NDIS_STATUS oid_rt_ap_switch_into_ap_mode_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
return status;
}
NDIS_STATUS oid_rt_ap_supported_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
return status;
}
NDIS_STATUS oid_rt_ap_set_passphrase_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != SET_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
return status;
}
/* ************** oid_rtl_seg_01_03 section end ************** */
/* **************** oid_rtl_seg_01_11 section start **************** */
NDIS_STATUS oid_rt_pro_rf_write_registry_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context);
_irqL oldirql;
/* DEBUG_ERR(("<**********************oid_rt_pro_rf_write_registry_hdl\n")); */
if (poid_par_priv->type_of_oid != SET_OID) { /* QUERY_OID */
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
_irqlevel_changed_(&oldirql, LOWER);
if (poid_par_priv->information_buf_len == (sizeof(unsigned long) * 3)) {
/* RegOffsetValue - The offset of RF register to write. */
/* RegDataWidth - The data width of RF register to write. */
/* RegDataValue - The value to write. */
/* RegOffsetValue = *((unsigned long*)InformationBuffer); */
/* RegDataWidth = *((unsigned long*)InformationBuffer+1); */
/* RegDataValue = *((unsigned long*)InformationBuffer+2); */
if (!rtw_setrfreg_cmd(Adapter,
*(unsigned char *)poid_par_priv->information_buf,
(unsigned long)(*((unsigned long *)poid_par_priv->information_buf + 2))))
status = NDIS_STATUS_NOT_ACCEPTED;
} else
status = NDIS_STATUS_INVALID_LENGTH;
_irqlevel_changed_(&oldirql, RAISE);
return status;
}
/* ------------------------------------------------------------------------------ */
NDIS_STATUS oid_rt_pro_rf_read_registry_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
#if 0
PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context);
_irqL oldirql;
/* DEBUG_ERR(("<**********************oid_rt_pro_rf_read_registry_hdl\n")); */
if (poid_par_priv->type_of_oid != SET_OID) { /* QUERY_OID */
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
_irqlevel_changed_(&oldirql, LOWER);
if (poid_par_priv->information_buf_len == (sizeof(unsigned long) * 3)) {
if (Adapter->mppriv.act_in_progress == _TRUE)
status = NDIS_STATUS_NOT_ACCEPTED;
else {
/* init workparam */
Adapter->mppriv.act_in_progress = _TRUE;
Adapter->mppriv.workparam.bcompleted = _FALSE;
Adapter->mppriv.workparam.act_type = MPT_READ_RF;
Adapter->mppriv.workparam.io_offset = *(unsigned long *)poid_par_priv->information_buf;
Adapter->mppriv.workparam.io_value = 0xcccccccc;
/* RegOffsetValue - The offset of RF register to read. */
/* RegDataWidth - The data width of RF register to read. */
/* RegDataValue - The value to read. */
/* RegOffsetValue = *((unsigned long*)InformationBuffer); */
/* RegDataWidth = *((unsigned long*)InformationBuffer+1); */
/* RegDataValue = *((unsigned long*)InformationBuffer+2); */
if (!rtw_getrfreg_cmd(Adapter,
*(unsigned char *)poid_par_priv->information_buf,
(unsigned char *)&Adapter->mppriv.workparam.io_value))
status = NDIS_STATUS_NOT_ACCEPTED;
}
} else
status = NDIS_STATUS_INVALID_LENGTH;
_irqlevel_changed_(&oldirql, RAISE);
#endif
return status;
}
/* **************** oid_rtl_seg_01_11 section end**************** */
/* ************** oid_rtl_seg_03_00 section start ************** */
enum _CONNECT_STATE_ {
CHECKINGSTATUS,
ASSOCIATED,
ADHOCMODE,
NOTASSOCIATED
};
NDIS_STATUS oid_rt_get_connect_state_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
ULONG ulInfo;
if (poid_par_priv->type_of_oid != QUERY_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
/* nStatus==0 CheckingStatus */
/* nStatus==1 Associated */
/* nStatus==2 AdHocMode */
/* nStatus==3 NotAssociated */
if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE)
ulInfo = CHECKINGSTATUS;
else if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
ulInfo = ASSOCIATED;
else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE)
ulInfo = ADHOCMODE;
else
ulInfo = NOTASSOCIATED ;
*(ULONG *)poid_par_priv->information_buf = ulInfo;
*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
#if 0
/* Rearrange the order to let the UI still shows connection when scan is in progress */
if (pMgntInfo->mAssoc)
ulInfo = 1;
else if (pMgntInfo->mIbss)
ulInfo = 2;
else if (pMgntInfo->bScanInProgress)
ulInfo = 0;
else
ulInfo = 3;
ulInfoLen = sizeof(ULONG);
#endif
return status;
}
NDIS_STATUS oid_rt_set_default_key_id_hdl(struct oid_par_priv *poid_par_priv)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context);
if (poid_par_priv->type_of_oid != SET_OID) {
status = NDIS_STATUS_NOT_ACCEPTED;
return status;
}
return status;
}
/* ************** oid_rtl_seg_03_00 section end ************** */

894
core/rtw_ioctl_set.c Normal file
View File

@ -0,0 +1,894 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#define _RTW_IOCTL_SET_C_
#include <drv_types.h>
#include <hal_data.h>
extern void indicate_wx_scan_complete_event(_adapter *padapter);
#define IS_MAC_ADDRESS_BROADCAST(addr) \
(\
((addr[0] == 0xff) && (addr[1] == 0xff) && \
(addr[2] == 0xff) && (addr[3] == 0xff) && \
(addr[4] == 0xff) && (addr[5] == 0xff)) ? _TRUE : _FALSE \
)
u8 rtw_validate_bssid(u8 *bssid)
{
u8 ret = _TRUE;
if (is_zero_mac_addr(bssid)
|| is_broadcast_mac_addr(bssid)
|| is_multicast_mac_addr(bssid)
)
ret = _FALSE;
return ret;
}
u8 rtw_validate_ssid(NDIS_802_11_SSID *ssid)
{
u8 i;
u8 ret = _TRUE;
if (ssid->SsidLength > 32) {
ret = _FALSE;
goto exit;
}
#ifdef CONFIG_VALIDATE_SSID
for (i = 0; i < ssid->SsidLength; i++) {
/* wifi, printable ascii code must be supported */
if (!((ssid->Ssid[i] >= 0x20) && (ssid->Ssid[i] <= 0x7e))) {
ret = _FALSE;
break;
}
}
#endif /* CONFIG_VALIDATE_SSID */
exit:
return ret;
}
u8 rtw_do_join(_adapter *padapter);
u8 rtw_do_join(_adapter *padapter)
{
_irqL irqL;
_list *plist, *phead;
u8 *pibss = NULL;
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
struct sitesurvey_parm parm;
_queue *queue = &(pmlmepriv->scanned_queue);
u8 ret = _SUCCESS;
_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
phead = get_list_head(queue);
plist = get_next(phead);
pmlmepriv->cur_network.join_res = -2;
set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
pmlmepriv->pscanned = plist;
pmlmepriv->to_join = _TRUE;
rtw_init_sitesurvey_parm(padapter, &parm);
_rtw_memcpy(&parm.ssid[0], &pmlmepriv->assoc_ssid, sizeof(NDIS_802_11_SSID));
parm.ssid_num = 1;
if (_rtw_queue_empty(queue) == _TRUE) {
_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
/* when set_ssid/set_bssid for rtw_do_join(), but scanning queue is empty */
/* we try to issue sitesurvey firstly */
if (pmlmepriv->LinkDetectInfo.bBusyTraffic == _FALSE
|| rtw_to_roam(padapter) > 0
) {
/* submit site_survey_cmd */
ret = rtw_sitesurvey_cmd(padapter, &parm);
if (_SUCCESS != ret) {
pmlmepriv->to_join = _FALSE;
}
} else {
pmlmepriv->to_join = _FALSE;
ret = _FAIL;
}
goto exit;
} else {
int select_ret;
_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
select_ret = rtw_select_and_join_from_scanned_queue(pmlmepriv);
if (select_ret == _SUCCESS) {
pmlmepriv->to_join = _FALSE;
_set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);
} else {
if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) {
/* submit createbss_cmd to change to a ADHOC_MASTER */
/* pmlmepriv->lock has been acquired by caller... */
WLAN_BSSID_EX *pdev_network = &(padapter->registrypriv.dev_network);
/*pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;*/
init_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
pibss = padapter->registrypriv.dev_network.MacAddress;
_rtw_memset(&pdev_network->Ssid, 0, sizeof(NDIS_802_11_SSID));
_rtw_memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(NDIS_802_11_SSID));
rtw_update_registrypriv_dev_network(padapter);
rtw_generate_random_ibss(pibss);
if (rtw_create_ibss_cmd(padapter, 0) != _SUCCESS) {
ret = _FALSE;
goto exit;
}
pmlmepriv->to_join = _FALSE;
} else {
/* can't associate ; reset under-linking */
_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
#if 0
if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)) {
if (_rtw_memcmp(pmlmepriv->cur_network.network.Ssid.Ssid, pmlmepriv->assoc_ssid.Ssid, pmlmepriv->assoc_ssid.SsidLength)) {
/* for funk to do roaming */
/* funk will reconnect, but funk will not sitesurvey before reconnect */
if (pmlmepriv->sitesurveyctrl.traffic_busy == _FALSE)
rtw_sitesurvey_cmd(padapter, &parm);
}
}
#endif
/* when set_ssid/set_bssid for rtw_do_join(), but there are no desired bss in scanning queue */
/* we try to issue sitesurvey firstly */
if (pmlmepriv->LinkDetectInfo.bBusyTraffic == _FALSE
|| rtw_to_roam(padapter) > 0
) {
/* RTW_INFO("rtw_do_join() when no desired bss in scanning queue\n"); */
ret = rtw_sitesurvey_cmd(padapter, &parm);
if (_SUCCESS != ret) {
pmlmepriv->to_join = _FALSE;
}
} else {
ret = _FAIL;
pmlmepriv->to_join = _FALSE;
}
}
}
}
exit:
return ret;
}
#ifdef PLATFORM_WINDOWS
u8 rtw_pnp_set_power_wakeup(_adapter *padapter)
{
u8 res = _SUCCESS;
res = rtw_setstandby_cmd(padapter, 0);
return res;
}
u8 rtw_pnp_set_power_sleep(_adapter *padapter)
{
u8 res = _SUCCESS;
/* DbgPrint("+rtw_pnp_set_power_sleep\n"); */
res = rtw_setstandby_cmd(padapter, 1);
return res;
}
u8 rtw_set_802_11_reload_defaults(_adapter *padapter, NDIS_802_11_RELOAD_DEFAULTS reloadDefaults)
{
/* SecClearAllKeys(Adapter); */
/* 8711 CAM was not for En/Decrypt only */
/* so, we can't clear all keys. */
/* should we disable WPAcfg (ox0088) bit 1-2, instead of clear all CAM */
/* TO DO... */
return _TRUE;
}
u8 set_802_11_test(_adapter *padapter, NDIS_802_11_TEST *test)
{
u8 ret = _TRUE;
switch (test->Type) {
case 1:
NdisMIndicateStatus(padapter->hndis_adapter, NDIS_STATUS_MEDIA_SPECIFIC_INDICATION, (PVOID)&test->AuthenticationEvent, test->Length - 8);
NdisMIndicateStatusComplete(padapter->hndis_adapter);
break;
case 2:
NdisMIndicateStatus(padapter->hndis_adapter, NDIS_STATUS_MEDIA_SPECIFIC_INDICATION, (PVOID)&test->RssiTrigger, sizeof(NDIS_802_11_RSSI));
NdisMIndicateStatusComplete(padapter->hndis_adapter);
break;
default:
ret = _FALSE;
break;
}
return ret;
}
u8 rtw_set_802_11_pmkid(_adapter *padapter, NDIS_802_11_PMKID *pmkid)
{
u8 ret = _SUCCESS;
return ret;
}
#endif
u8 rtw_set_802_11_bssid(_adapter *padapter, u8 *bssid)
{
_irqL irqL;
u8 status = _SUCCESS;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
RTW_PRINT("set bssid:%pM\n", bssid);
if ((bssid[0] == 0x00 && bssid[1] == 0x00 && bssid[2] == 0x00 && bssid[3] == 0x00 && bssid[4] == 0x00 && bssid[5] == 0x00) ||
(bssid[0] == 0xFF && bssid[1] == 0xFF && bssid[2] == 0xFF && bssid[3] == 0xFF && bssid[4] == 0xFF && bssid[5] == 0xFF)) {
status = _FAIL;
goto exit;
}
_enter_critical_bh(&pmlmepriv->lock, &irqL);
RTW_INFO("Set BSSID under fw_state=0x%08x\n", get_fwstate(pmlmepriv));
if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE)
goto handle_tkip_countermeasure;
else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE)
goto release_mlme_lock;
if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE) == _TRUE) {
if (_rtw_memcmp(&pmlmepriv->cur_network.network.MacAddress, bssid, ETH_ALEN) == _TRUE) {
if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _FALSE)
goto release_mlme_lock;/* it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. */
} else {
rtw_disassoc_cmd(padapter, 0, 0);
if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
rtw_indicate_disconnect(padapter, 0, _FALSE);
rtw_free_assoc_resources_cmd(padapter, _TRUE);
if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) {
_clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
}
}
}
handle_tkip_countermeasure:
if (rtw_handle_tkip_countermeasure(padapter, __func__) == _FAIL) {
status = _FAIL;
goto release_mlme_lock;
}
_rtw_memset(&pmlmepriv->assoc_ssid, 0, sizeof(NDIS_802_11_SSID));
_rtw_memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN);
pmlmepriv->assoc_by_bssid = _TRUE;
if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE)
pmlmepriv->to_join = _TRUE;
else
status = rtw_do_join(padapter);
release_mlme_lock:
_exit_critical_bh(&pmlmepriv->lock, &irqL);
exit:
return status;
}
u8 rtw_set_802_11_ssid(_adapter *padapter, NDIS_802_11_SSID *ssid)
{
_irqL irqL;
u8 status = _SUCCESS;
u32 cur_time = 0;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct wlan_network *pnetwork = &pmlmepriv->cur_network;
RTW_PRINT("set ssid [%s] fw_state=0x%08x\n",
ssid->Ssid, get_fwstate(pmlmepriv));
if (!rtw_is_hw_init_completed(padapter)) {
status = _FAIL;
goto exit;
}
_enter_critical_bh(&pmlmepriv->lock, &irqL);
RTW_INFO("Set SSID under fw_state=0x%08x\n", get_fwstate(pmlmepriv));
if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE)
goto handle_tkip_countermeasure;
else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE)
goto release_mlme_lock;
if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE) == _TRUE) {
if ((pmlmepriv->assoc_ssid.SsidLength == ssid->SsidLength) &&
(_rtw_memcmp(&pmlmepriv->assoc_ssid.Ssid, ssid->Ssid, ssid->SsidLength) == _TRUE)) {
if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _FALSE)) {
if (rtw_is_same_ibss(padapter, pnetwork) == _FALSE) {
/* if in WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE, create bss or rejoin again */
rtw_disassoc_cmd(padapter, 0, 0);
if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
rtw_indicate_disconnect(padapter, 0, _FALSE);
rtw_free_assoc_resources_cmd(padapter, _TRUE);
if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) {
_clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
}
} else {
goto release_mlme_lock;/* it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. */
}
}
#ifdef CONFIG_LPS
else
rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_JOINBSS, 1);
#endif
} else {
rtw_disassoc_cmd(padapter, 0, 0);
if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
rtw_indicate_disconnect(padapter, 0, _FALSE);
rtw_free_assoc_resources_cmd(padapter, _TRUE);
if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) {
_clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
}
}
}
handle_tkip_countermeasure:
if (rtw_handle_tkip_countermeasure(padapter, __func__) == _FAIL) {
status = _FAIL;
goto release_mlme_lock;
}
if (rtw_validate_ssid(ssid) == _FALSE) {
status = _FAIL;
goto release_mlme_lock;
}
_rtw_memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(NDIS_802_11_SSID));
pmlmepriv->assoc_by_bssid = _FALSE;
if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE)
pmlmepriv->to_join = _TRUE;
else
status = rtw_do_join(padapter);
release_mlme_lock:
_exit_critical_bh(&pmlmepriv->lock, &irqL);
exit:
return status;
}
u8 rtw_set_802_11_connect(_adapter *padapter, u8 *bssid, NDIS_802_11_SSID *ssid)
{
_irqL irqL;
u8 status = _SUCCESS;
u32 cur_time = 0;
bool bssid_valid = _TRUE;
bool ssid_valid = _TRUE;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
if (!ssid || rtw_validate_ssid(ssid) == _FALSE)
ssid_valid = _FALSE;
if (!bssid || rtw_validate_bssid(bssid) == _FALSE)
bssid_valid = _FALSE;
if (ssid_valid == _FALSE && bssid_valid == _FALSE) {
RTW_INFO(FUNC_ADPT_FMT" ssid:%p, ssid_valid:%d, bssid:%p, bssid_valid:%d\n",
FUNC_ADPT_ARG(padapter), ssid, ssid_valid, bssid, bssid_valid);
status = _FAIL;
goto exit;
}
if (!rtw_is_hw_init_completed(padapter)) {
status = _FAIL;
goto exit;
}
_enter_critical_bh(&pmlmepriv->lock, &irqL);
RTW_PRINT(FUNC_ADPT_FMT" fw_state=0x%08x\n",
FUNC_ADPT_ARG(padapter), get_fwstate(pmlmepriv));
if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE)
goto handle_tkip_countermeasure;
else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE)
goto release_mlme_lock;
handle_tkip_countermeasure:
if (rtw_handle_tkip_countermeasure(padapter, __func__) == _FAIL) {
status = _FAIL;
goto release_mlme_lock;
}
if (ssid && ssid_valid)
_rtw_memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(NDIS_802_11_SSID));
else
_rtw_memset(&pmlmepriv->assoc_ssid, 0, sizeof(NDIS_802_11_SSID));
if (bssid && bssid_valid) {
_rtw_memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN);
pmlmepriv->assoc_by_bssid = _TRUE;
} else
pmlmepriv->assoc_by_bssid = _FALSE;
if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE)
pmlmepriv->to_join = _TRUE;
else
status = rtw_do_join(padapter);
release_mlme_lock:
_exit_critical_bh(&pmlmepriv->lock, &irqL);
exit:
return status;
}
u8 rtw_set_802_11_infrastructure_mode(_adapter *padapter,
NDIS_802_11_NETWORK_INFRASTRUCTURE networktype)
{
_irqL irqL;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct wlan_network *cur_network = &pmlmepriv->cur_network;
NDIS_802_11_NETWORK_INFRASTRUCTURE *pold_state = &(cur_network->network.InfrastructureMode);
u8 ap2sta_mode = _FALSE;
u8 ret = _TRUE;
if (*pold_state != networktype) {
/* RTW_INFO("change mode, old_mode=%d, new_mode=%d, fw_state=0x%x\n", *pold_state, networktype, get_fwstate(pmlmepriv)); */
if (*pold_state == Ndis802_11APMode
|| *pold_state == Ndis802_11_mesh
) {
/* change to other mode from Ndis802_11APMode/Ndis802_11_mesh */
cur_network->join_res = -1;
ap2sta_mode = _TRUE;
#ifdef CONFIG_NATIVEAP_MLME
stop_ap_mode(padapter);
#endif
}
_enter_critical_bh(&pmlmepriv->lock, &irqL);
if ((check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) || (*pold_state == Ndis802_11IBSS))
rtw_disassoc_cmd(padapter, 0, 0);
if ((check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) ||
(check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE))
rtw_free_assoc_resources_cmd(padapter, _TRUE);
if ((*pold_state == Ndis802_11Infrastructure) || (*pold_state == Ndis802_11IBSS)) {
if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
rtw_indicate_disconnect(padapter, 0, _FALSE); /*will clr Linked_state; before this function, we must have checked whether issue dis-assoc_cmd or not*/
}
}
*pold_state = networktype;
_clr_fwstate_(pmlmepriv, ~WIFI_NULL_STATE);
switch (networktype) {
case Ndis802_11IBSS:
set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
break;
case Ndis802_11Infrastructure:
set_fwstate(pmlmepriv, WIFI_STATION_STATE);
if (ap2sta_mode)
rtw_init_bcmc_stainfo(padapter);
break;
case Ndis802_11APMode:
set_fwstate(pmlmepriv, WIFI_AP_STATE);
#ifdef CONFIG_NATIVEAP_MLME
start_ap_mode(padapter);
/* rtw_indicate_connect(padapter); */
#endif
break;
#ifdef CONFIG_RTW_MESH
case Ndis802_11_mesh:
set_fwstate(pmlmepriv, WIFI_MESH_STATE);
start_ap_mode(padapter);
break;
#endif
case Ndis802_11AutoUnknown:
case Ndis802_11InfrastructureMax:
break;
case Ndis802_11Monitor:
set_fwstate(pmlmepriv, WIFI_MONITOR_STATE);
break;
default:
ret = _FALSE;
rtw_warn_on(1);
}
/* SecClearAllKeys(adapter); */
_exit_critical_bh(&pmlmepriv->lock, &irqL);
}
return ret;
}
u8 rtw_set_802_11_disassociate(_adapter *padapter)
{
_irqL irqL;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
_enter_critical_bh(&pmlmepriv->lock, &irqL);
if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
rtw_disassoc_cmd(padapter, 0, 0);
rtw_indicate_disconnect(padapter, 0, _FALSE);
/* modify for CONFIG_IEEE80211W, none 11w can use it */
rtw_free_assoc_resources_cmd(padapter, _TRUE);
if (_FAIL == rtw_pwr_wakeup(padapter))
RTW_INFO("%s(): rtw_pwr_wakeup fail !!!\n", __FUNCTION__);
}
_exit_critical_bh(&pmlmepriv->lock, &irqL);
return _TRUE;
}
#if 1
u8 rtw_set_802_11_bssid_list_scan(_adapter *padapter, struct sitesurvey_parm *pparm)
{
_irqL irqL;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
u8 res = _TRUE;
_enter_critical_bh(&pmlmepriv->lock, &irqL);
res = rtw_sitesurvey_cmd(padapter, pparm);
_exit_critical_bh(&pmlmepriv->lock, &irqL);
return res;
}
#else
u8 rtw_set_802_11_bssid_list_scan(_adapter *padapter, struct sitesurvey_parm *pparm)
{
_irqL irqL;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
u8 res = _TRUE;
if (padapter == NULL) {
res = _FALSE;
goto exit;
}
if (!rtw_is_hw_init_completed(padapter)) {
res = _FALSE;
goto exit;
}
if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING) == _TRUE) ||
(pmlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE)) {
/* Scan or linking is in progress, do nothing. */
res = _TRUE;
} else {
if (rtw_is_scan_deny(padapter)) {
RTW_INFO(FUNC_ADPT_FMT": scan deny\n", FUNC_ADPT_ARG(padapter));
indicate_wx_scan_complete_event(padapter);
return _SUCCESS;
}
_enter_critical_bh(&pmlmepriv->lock, &irqL);
res = rtw_sitesurvey_cmd(padapter, pparm);
_exit_critical_bh(&pmlmepriv->lock, &irqL);
}
exit:
return res;
}
#endif
u8 rtw_set_802_11_authentication_mode(_adapter *padapter, NDIS_802_11_AUTHENTICATION_MODE authmode)
{
struct security_priv *psecuritypriv = &padapter->securitypriv;
int res;
u8 ret;
psecuritypriv->ndisauthtype = authmode;
if (psecuritypriv->ndisauthtype > 3)
psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
#ifdef CONFIG_WAPI_SUPPORT
if (psecuritypriv->ndisauthtype == 6)
psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
#endif
res = rtw_set_auth(padapter, psecuritypriv);
if (res == _SUCCESS)
ret = _TRUE;
else
ret = _FALSE;
return ret;
}
u8 rtw_set_802_11_add_wep(_adapter *padapter, NDIS_802_11_WEP *wep)
{
u8 bdefaultkey;
u8 btransmitkey;
sint keyid, res;
struct security_priv *psecuritypriv = &(padapter->securitypriv);
u8 ret = _SUCCESS;
bdefaultkey = (wep->KeyIndex & 0x40000000) > 0 ? _FALSE : _TRUE; /* for ??? */
btransmitkey = (wep->KeyIndex & 0x80000000) > 0 ? _TRUE : _FALSE; /* for ??? */
keyid = wep->KeyIndex & 0x3fffffff;
if (keyid >= 4) {
ret = _FALSE;
goto exit;
}
switch (wep->KeyLength) {
case 5:
psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
break;
case 13:
psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
break;
default:
psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
break;
}
_rtw_memcpy(&(psecuritypriv->dot11DefKey[keyid].skey[0]), &(wep->KeyMaterial), wep->KeyLength);
psecuritypriv->dot11DefKeylen[keyid] = wep->KeyLength;
psecuritypriv->dot11PrivacyKeyIndex = keyid;
res = rtw_set_key(padapter, psecuritypriv, keyid, 1, _TRUE);
if (res == _FAIL)
ret = _FALSE;
exit:
return ret;
}
/*
* rtw_get_cur_max_rate -
* @adapter: pointer to _adapter structure
*
* Return 0 or 100Kbps
*/
u16 rtw_get_cur_max_rate(_adapter *adapter)
{
int i = 0;
u16 rate = 0, max_rate = 0;
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network;
struct sta_info *psta = NULL;
u8 short_GI = 0;
#ifdef CONFIG_80211N_HT
u8 rf_type = 0;
#endif
#ifdef CONFIG_MP_INCLUDED
if (adapter->registrypriv.mp_mode == 1) {
if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE)
return 0;
}
#endif
if ((check_fwstate(pmlmepriv, _FW_LINKED) != _TRUE)
&& (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) != _TRUE))
return 0;
psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
if (psta == NULL)
return 0;
short_GI = query_ra_short_GI(psta, rtw_get_tx_bw_mode(adapter, psta));
#ifdef CONFIG_80211N_HT
if (is_supported_ht(psta->wireless_mode)) {
rtw_hal_get_hwreg(adapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
max_rate = rtw_mcs_rate(rf_type
, (psta->cmn.bw_mode == CHANNEL_WIDTH_40) ? 1 : 0
, short_GI
, psta->htpriv.ht_cap.supp_mcs_set
);
}
#ifdef CONFIG_80211AC_VHT
else if (is_supported_vht(psta->wireless_mode))
max_rate = ((rtw_vht_mcs_to_data_rate(psta->cmn.bw_mode, short_GI, pmlmepriv->vhtpriv.vht_highest_rate) + 1) >> 1) * 10;
#endif /* CONFIG_80211AC_VHT */
else
#endif /* CONFIG_80211N_HT */
{
while ((pcur_bss->SupportedRates[i] != 0) && (pcur_bss->SupportedRates[i] != 0xFF)) {
rate = pcur_bss->SupportedRates[i] & 0x7F;
if (rate > max_rate)
max_rate = rate;
i++;
}
max_rate = max_rate * 10 / 2;
}
return max_rate;
}
/*
* rtw_set_scan_mode -
* @adapter: pointer to _adapter structure
* @scan_mode:
*
* Return _SUCCESS or _FAIL
*/
int rtw_set_scan_mode(_adapter *adapter, RT_SCAN_TYPE scan_mode)
{
if (scan_mode != SCAN_ACTIVE && scan_mode != SCAN_PASSIVE)
return _FAIL;
adapter->mlmepriv.scan_mode = scan_mode;
return _SUCCESS;
}
/*
* rtw_set_channel_plan -
* @adapter: pointer to _adapter structure
* @channel_plan:
*
* Return _SUCCESS or _FAIL
*/
int rtw_set_channel_plan(_adapter *adapter, u8 channel_plan)
{
struct registry_priv *pregistrypriv = &adapter->registrypriv;
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
/* handle by cmd_thread to sync with scan operation */
return rtw_set_chplan_cmd(adapter, RTW_CMDF_WAIT_ACK, channel_plan, 1);
}
/*
* rtw_set_country -
* @adapter: pointer to _adapter structure
* @country_code: string of country code
*
* Return _SUCCESS or _FAIL
*/
int rtw_set_country(_adapter *adapter, const char *country_code)
{
#ifdef CONFIG_RTW_IOCTL_SET_COUNTRY
return rtw_set_country_cmd(adapter, RTW_CMDF_WAIT_ACK, country_code, 1);
#else
RTW_INFO("%s(): not applied\n", __func__);
return _SUCCESS;
#endif
}
/*
* rtw_set_band -
* @adapter: pointer to _adapter structure
* @band: band to set
*
* Return _SUCCESS or _FAIL
*/
int rtw_set_band(_adapter *adapter, u8 band)
{
if (rtw_band_valid(band)) {
RTW_INFO(FUNC_ADPT_FMT" band:%d\n", FUNC_ADPT_ARG(adapter), band);
adapter->setband = band;
return _SUCCESS;
}
RTW_PRINT(FUNC_ADPT_FMT" band:%d fail\n", FUNC_ADPT_ARG(adapter), band);
return _FAIL;
}

382
core/rtw_iol.c Normal file
View File

@ -0,0 +1,382 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#include <drv_types.h>
#ifdef CONFIG_IOL
struct xmit_frame *rtw_IOL_accquire_xmit_frame(ADAPTER *adapter)
{
struct xmit_frame *xmit_frame;
struct xmit_buf *xmitbuf;
struct pkt_attrib *pattrib;
struct xmit_priv *pxmitpriv = &(adapter->xmitpriv);
#if 1
xmit_frame = rtw_alloc_xmitframe(pxmitpriv);
if (xmit_frame == NULL) {
RTW_INFO("%s rtw_alloc_xmitframe return null\n", __FUNCTION__);
goto exit;
}
xmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
if (xmitbuf == NULL) {
RTW_INFO("%s rtw_alloc_xmitbuf return null\n", __FUNCTION__);
rtw_free_xmitframe(pxmitpriv, xmit_frame);
xmit_frame = NULL;
goto exit;
}
xmit_frame->frame_tag = MGNT_FRAMETAG;
xmit_frame->pxmitbuf = xmitbuf;
xmit_frame->buf_addr = xmitbuf->pbuf;
xmitbuf->priv_data = xmit_frame;
pattrib = &xmit_frame->attrib;
update_mgntframe_attrib(adapter, pattrib);
pattrib->qsel = QSLT_BEACON;/* Beacon */
pattrib->subtype = WIFI_BEACON;
pattrib->pktlen = pattrib->last_txcmdsz = 0;
#else
xmit_frame = alloc_mgtxmitframe(pxmitpriv);
if (xmit_frame == NULL)
RTW_INFO("%s alloc_mgtxmitframe return null\n", __FUNCTION__);
else {
pattrib = &xmit_frame->attrib;
update_mgntframe_attrib(adapter, pattrib);
pattrib->qsel = QSLT_BEACON;
pattrib->pktlen = pattrib->last_txcmdsz = 0;
}
#endif
exit:
return xmit_frame;
}
int rtw_IOL_append_cmds(struct xmit_frame *xmit_frame, u8 *IOL_cmds, u32 cmd_len)
{
struct pkt_attrib *pattrib = &xmit_frame->attrib;
u16 buf_offset;
u32 ori_len;
buf_offset = TXDESC_OFFSET;
ori_len = buf_offset + pattrib->pktlen;
/* check if the io_buf can accommodate new cmds */
if (ori_len + cmd_len + 8 > MAX_XMITBUF_SZ) {
RTW_INFO("%s %u is large than MAX_XMITBUF_SZ:%u, can't accommodate new cmds\n", __FUNCTION__
, ori_len + cmd_len + 8, MAX_XMITBUF_SZ);
return _FAIL;
}
_rtw_memcpy(xmit_frame->buf_addr + buf_offset + pattrib->pktlen, IOL_cmds, cmd_len);
pattrib->pktlen += cmd_len;
pattrib->last_txcmdsz += cmd_len;
/* RTW_INFO("%s ori:%u + cmd_len:%u = %u\n", __FUNCTION__, ori_len, cmd_len, buf_offset+pattrib->pktlen); */
return _SUCCESS;
}
bool rtw_IOL_applied(ADAPTER *adapter)
{
if (1 == adapter->registrypriv.fw_iol)
return _TRUE;
#ifdef CONFIG_USB_HCI
if ((2 == adapter->registrypriv.fw_iol) && (IS_FULL_SPEED_USB(adapter)))
return _TRUE;
#endif
return _FALSE;
}
int rtw_IOL_exec_cmds_sync(ADAPTER *adapter, struct xmit_frame *xmit_frame, u32 max_wating_ms, u32 bndy_cnt)
{
return rtw_hal_iol_cmd(adapter, xmit_frame, max_wating_ms, bndy_cnt);
}
#ifdef CONFIG_IOL_NEW_GENERATION
int rtw_IOL_append_LLT_cmd(struct xmit_frame *xmit_frame, u8 page_boundary)
{
return _SUCCESS;
}
int _rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value, u8 mask)
{
struct ioreg_cfg cmd = {8, IOREG_CMD_WB_REG, 0x0, 0x0, 0x0};
/* RTW_PUT_LE16((u8*)&cmd.address, addr); */
/* RTW_PUT_LE32((u8*)&cmd.value, (u32)value); */
cmd.address = cpu_to_le16(addr);
cmd.data = cpu_to_le32(value);
if (mask != 0xFF) {
cmd.length = 12;
/* RTW_PUT_LE32((u8*)&cmd.mask, (u32)mask); */
cmd.mask = cpu_to_le32(mask);
}
/* RTW_INFO("%s addr:0x%04x,value:0x%08x,mask:0x%08x\n", __FUNCTION__, addr,value,mask); */
return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
}
int _rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value, u16 mask)
{
struct ioreg_cfg cmd = {8, IOREG_CMD_WW_REG, 0x0, 0x0, 0x0};
/* RTW_PUT_LE16((u8*)&cmd.address, addr); */
/* RTW_PUT_LE32((u8*)&cmd.value, (u32)value); */
cmd.address = cpu_to_le16(addr);
cmd.data = cpu_to_le32(value);
if (mask != 0xFFFF) {
cmd.length = 12;
/* RTW_PUT_LE32((u8*)&cmd.mask, (u32)mask); */
cmd.mask = cpu_to_le32(mask);
}
/* RTW_INFO("%s addr:0x%04x,value:0x%08x,mask:0x%08x\n", __FUNCTION__, addr,value,mask); */
return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
}
int _rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value, u32 mask)
{
struct ioreg_cfg cmd = {8, IOREG_CMD_WD_REG, 0x0, 0x0, 0x0};
/* RTW_PUT_LE16((u8*)&cmd.address, addr); */
/* RTW_PUT_LE32((u8*)&cmd.value, (u32)value); */
cmd.address = cpu_to_le16(addr);
cmd.data = cpu_to_le32(value);
if (mask != 0xFFFFFFFF) {
cmd.length = 12;
/* RTW_PUT_LE32((u8*)&cmd.mask, (u32)mask); */
cmd.mask = cpu_to_le32(mask);
}
/* RTW_INFO("%s addr:0x%04x,value:0x%08x,mask:0x%08x\n", __FU2NCTION__, addr,value,mask); */
return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
}
int _rtw_IOL_append_WRF_cmd(struct xmit_frame *xmit_frame, u8 rf_path, u16 addr, u32 value, u32 mask)
{
struct ioreg_cfg cmd = {8, IOREG_CMD_W_RF, 0x0, 0x0, 0x0};
/* RTW_PUT_LE16((u8*)&cmd.address, addr); */
/* RTW_PUT_LE32((u8*)&cmd.value, (u32)value); */
cmd.address = (rf_path << 8) | ((addr) & 0xFF);
cmd.data = cpu_to_le32(value);
if (mask != 0x000FFFFF) {
cmd.length = 12;
/* RTW_PUT_LE32((u8*)&cmd.mask, (u32)mask); */
cmd.mask = cpu_to_le32(mask);
}
/* RTW_INFO("%s rf_path:0x%02x addr:0x%04x,value:0x%08x,mask:0x%08x\n", __FU2NCTION__,rf_path, addr,value,mask); */
return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
}
int rtw_IOL_append_DELAY_US_cmd(struct xmit_frame *xmit_frame, u16 us)
{
struct ioreg_cfg cmd = {4, IOREG_CMD_DELAY_US, 0x0, 0x0, 0x0};
/* RTW_PUT_LE16((u8*)&cmd.address, us); */
cmd.address = cpu_to_le16(us);
/* RTW_INFO("%s %u\n", __FUNCTION__, us); */
return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4);
}
int rtw_IOL_append_DELAY_MS_cmd(struct xmit_frame *xmit_frame, u16 ms)
{
struct ioreg_cfg cmd = {4, IOREG_CMD_DELAY_US, 0x0, 0x0, 0x0};
/* RTW_PUT_LE16((u8*)&cmd.address, ms); */
cmd.address = cpu_to_le16(ms);
/* RTW_INFO("%s %u\n", __FUNCTION__, ms); */
return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4);
}
int rtw_IOL_append_END_cmd(struct xmit_frame *xmit_frame)
{
struct ioreg_cfg cmd = {4, IOREG_CMD_END, 0xFFFF, 0xFF, 0x0};
return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4);
}
u8 rtw_IOL_cmd_boundary_handle(struct xmit_frame *pxmit_frame)
{
u8 is_cmd_bndy = _FALSE;
if (((pxmit_frame->attrib.pktlen + 32) % 256) + 8 >= 256) {
rtw_IOL_append_END_cmd(pxmit_frame);
pxmit_frame->attrib.pktlen = ((((pxmit_frame->attrib.pktlen + 32) / 256) + 1) * 256);
/* printk("==> %s, pktlen(%d)\n",__FUNCTION__,pxmit_frame->attrib.pktlen); */
pxmit_frame->attrib.last_txcmdsz = pxmit_frame->attrib.pktlen;
is_cmd_bndy = _TRUE;
}
return is_cmd_bndy;
}
void rtw_IOL_cmd_buf_dump(ADAPTER *Adapter, int buf_len, u8 *pbuf)
{
int i;
int j = 1;
printk("###### %s ######\n", __FUNCTION__);
for (i = 0; i < buf_len; i++) {
printk("%02x-", *(pbuf + i));
if (j % 32 == 0)
printk("\n");
j++;
}
printk("\n");
printk("============= ioreg_cmd len = %d ===============\n", buf_len);
}
#else /* CONFIG_IOL_NEW_GENERATION */
int rtw_IOL_append_LLT_cmd(struct xmit_frame *xmit_frame, u8 page_boundary)
{
IOL_CMD cmd = {0x0, IOL_CMD_LLT, 0x0, 0x0};
RTW_PUT_BE32((u8 *)&cmd.value, (u32)page_boundary);
return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 8);
}
int _rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value)
{
IOL_CMD cmd = {0x0, IOL_CMD_WB_REG, 0x0, 0x0};
RTW_PUT_BE16((u8 *)&cmd.address, (u16)addr);
RTW_PUT_BE32((u8 *)&cmd.value, (u32)value);
return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 8);
}
int _rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value)
{
IOL_CMD cmd = {0x0, IOL_CMD_WW_REG, 0x0, 0x0};
RTW_PUT_BE16((u8 *)&cmd.address, (u16)addr);
RTW_PUT_BE32((u8 *)&cmd.value, (u32)value);
return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 8);
}
int _rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value)
{
IOL_CMD cmd = {0x0, IOL_CMD_WD_REG, 0x0, 0x0};
u8 *pos = (u8 *)&cmd;
RTW_PUT_BE16((u8 *)&cmd.address, (u16)addr);
RTW_PUT_BE32((u8 *)&cmd.value, (u32)value);
return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 8);
}
#ifdef DBG_IO
int dbg_rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value, const char *caller, const int line)
{
if (match_write_sniff_ranges(addr, 1))
RTW_INFO("DBG_IO %s:%d IOL_WB(0x%04x, 0x%02x)\n", caller, line, addr, value);
return _rtw_IOL_append_WB_cmd(xmit_frame, addr, value);
}
int dbg_rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value, const char *caller, const int line)
{
if (match_write_sniff_ranges(addr, 2))
RTW_INFO("DBG_IO %s:%d IOL_WW(0x%04x, 0x%04x)\n", caller, line, addr, value);
return _rtw_IOL_append_WW_cmd(xmit_frame, addr, value);
}
int dbg_rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value, const char *caller, const int line)
{
if (match_write_sniff_ranges(addr, 4))
RTW_INFO("DBG_IO %s:%d IOL_WD(0x%04x, 0x%08x)\n", caller, line, addr, value);
return _rtw_IOL_append_WD_cmd(xmit_frame, addr, value);
}
#endif
int rtw_IOL_append_DELAY_US_cmd(struct xmit_frame *xmit_frame, u16 us)
{
IOL_CMD cmd = {0x0, IOL_CMD_DELAY_US, 0x0, 0x0};
RTW_PUT_BE32((u8 *)&cmd.value, (u32)us);
/* RTW_INFO("%s %u\n", __FUNCTION__, us); */
return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 8);
}
int rtw_IOL_append_DELAY_MS_cmd(struct xmit_frame *xmit_frame, u16 ms)
{
IOL_CMD cmd = {0x0, IOL_CMD_DELAY_MS, 0x0, 0x0};
RTW_PUT_BE32((u8 *)&cmd.value, (u32)ms);
/* RTW_INFO("%s %u\n", __FUNCTION__, ms); */
return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 8);
}
int rtw_IOL_append_END_cmd(struct xmit_frame *xmit_frame)
{
IOL_CMD end_cmd = {0x0, IOL_CMD_END, 0x0, 0x0};
return rtw_IOL_append_cmds(xmit_frame, (u8 *)&end_cmd, 8);
}
int rtw_IOL_exec_cmd_array_sync(PADAPTER adapter, u8 *IOL_cmds, u32 cmd_num, u32 max_wating_ms)
{
struct xmit_frame *xmit_frame;
xmit_frame = rtw_IOL_accquire_xmit_frame(adapter);
if (xmit_frame == NULL)
return _FAIL;
if (rtw_IOL_append_cmds(xmit_frame, IOL_cmds, cmd_num << 3) == _FAIL)
return _FAIL;
return rtw_IOL_exec_cmds_sync(adapter, xmit_frame, max_wating_ms, 0);
}
int rtw_IOL_exec_empty_cmds_sync(ADAPTER *adapter, u32 max_wating_ms)
{
IOL_CMD end_cmd = {0x0, IOL_CMD_END, 0x0, 0x0};
return rtw_IOL_exec_cmd_array_sync(adapter, (u8 *)&end_cmd, 1, max_wating_ms);
}
#endif /* CONFIG_IOL_NEW_GENERATION */
#endif /* CONFIG_IOL */

128
core/rtw_mem.c Normal file
View File

@ -0,0 +1,128 @@
/******************************************************************************
*
* Copyright(c) 2016 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#include <drv_types.h>
#include <rtw_mem.h>
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Realtek Wireless Lan Driver");
MODULE_AUTHOR("Realtek Semiconductor Corp.");
MODULE_VERSION("DRIVERVERSION");
struct sk_buff_head rtk_skb_mem_q;
struct u8 *rtk_buf_mem[NR_RECVBUFF];
struct u8 *rtw_get_buf_premem(int index)
{
printk("%s, rtk_buf_mem index : %d\n", __func__, index);
return rtk_buf_mem[index];
}
u16 rtw_rtkm_get_buff_size(void)
{
return MAX_RTKM_RECVBUF_SZ;
}
EXPORT_SYMBOL(rtw_rtkm_get_buff_size);
u8 rtw_rtkm_get_nr_recv_skb(void)
{
return MAX_RTKM_NR_PREALLOC_RECV_SKB;
}
EXPORT_SYMBOL(rtw_rtkm_get_nr_recv_skb);
struct sk_buff *rtw_alloc_skb_premem(u16 in_size)
{
struct sk_buff *skb = NULL;
if (in_size > MAX_RTKM_RECVBUF_SZ) {
pr_info("warning %s: driver buffer size(%d) > rtkm buffer size(%d)\n", __func__, in_size, MAX_RTKM_RECVBUF_SZ);
WARN_ON(1);
return skb;
}
skb = skb_dequeue(&rtk_skb_mem_q);
printk("%s, rtk_skb_mem_q len : %d\n", __func__, skb_queue_len(&rtk_skb_mem_q));
return skb;
}
EXPORT_SYMBOL(rtw_alloc_skb_premem);
int rtw_free_skb_premem(struct sk_buff *pskb)
{
if (!pskb)
return -1;
if (skb_queue_len(&rtk_skb_mem_q) >= MAX_RTKM_NR_PREALLOC_RECV_SKB)
return -1;
skb_queue_tail(&rtk_skb_mem_q, pskb);
printk("%s, rtk_skb_mem_q len : %d\n", __func__, skb_queue_len(&rtk_skb_mem_q));
return 0;
}
EXPORT_SYMBOL(rtw_free_skb_premem);
static int __init rtw_mem_init(void)
{
int i;
SIZE_PTR tmpaddr = 0;
SIZE_PTR alignment = 0;
struct sk_buff *pskb = NULL;
printk("%s\n", __func__);
pr_info("MAX_RTKM_NR_PREALLOC_RECV_SKB: %d\n", MAX_RTKM_NR_PREALLOC_RECV_SKB);
pr_info("MAX_RTKM_RECVBUF_SZ: %d\n", MAX_RTKM_RECVBUF_SZ);
#ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX
for (i = 0; i < NR_RECVBUFF; i++)
rtk_buf_mem[i] = usb_buffer_alloc(dev, size, (in_interrupt() ? GFP_ATOMIC : GFP_KERNEL), dma);
#endif /* CONFIG_USE_USB_BUFFER_ALLOC_RX */
skb_queue_head_init(&rtk_skb_mem_q);
for (i = 0; i < MAX_RTKM_NR_PREALLOC_RECV_SKB; i++) {
pskb = __dev_alloc_skb(MAX_RTKM_RECVBUF_SZ + RECVBUFF_ALIGN_SZ, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
if (pskb) {
tmpaddr = (SIZE_PTR)pskb->data;
alignment = tmpaddr & (RECVBUFF_ALIGN_SZ - 1);
skb_reserve(pskb, (RECVBUFF_ALIGN_SZ - alignment));
skb_queue_tail(&rtk_skb_mem_q, pskb);
} else
printk("%s, alloc skb memory fail!\n", __func__);
pskb = NULL;
}
printk("%s, rtk_skb_mem_q len : %d\n", __func__, skb_queue_len(&rtk_skb_mem_q));
return 0;
}
static void __exit rtw_mem_exit(void)
{
if (skb_queue_len(&rtk_skb_mem_q))
printk("%s, rtk_skb_mem_q len : %d\n", __func__, skb_queue_len(&rtk_skb_mem_q));
skb_queue_purge(&rtk_skb_mem_q);
printk("%s\n", __func__);
}
module_init(rtw_mem_init);
module_exit(rtw_mem_exit);

1478
core/rtw_mi.c Normal file

File diff suppressed because it is too large Load Diff

5134
core/rtw_mlme.c Normal file

File diff suppressed because it is too large Load Diff

16931
core/rtw_mlme_ext.c Normal file

File diff suppressed because it is too large Load Diff

3511
core/rtw_mp.c Normal file

File diff suppressed because it is too large Load Diff

2529
core/rtw_mp_ioctl.c Normal file

File diff suppressed because it is too large Load Diff

454
core/rtw_odm.c Normal file
View File

@ -0,0 +1,454 @@
/******************************************************************************
*
* Copyright(c) 2013 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#include <rtw_odm.h>
#include <hal_data.h>
u32 rtw_phydm_ability_ops(_adapter *adapter, HAL_PHYDM_OPS ops, u32 ability)
{
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
struct dm_struct *podmpriv = &pHalData->odmpriv;
u32 result = 0;
switch (ops) {
case HAL_PHYDM_DIS_ALL_FUNC:
podmpriv->support_ability = DYNAMIC_FUNC_DISABLE;
halrf_cmn_info_set(podmpriv, HALRF_CMNINFO_ABILITY, DYNAMIC_FUNC_DISABLE);
break;
case HAL_PHYDM_FUNC_SET:
podmpriv->support_ability |= ability;
break;
case HAL_PHYDM_FUNC_CLR:
podmpriv->support_ability &= ~(ability);
break;
case HAL_PHYDM_ABILITY_BK:
/* dm flag backup*/
podmpriv->bk_support_ability = podmpriv->support_ability;
pHalData->bk_rf_ability = halrf_cmn_info_get(podmpriv, HALRF_CMNINFO_ABILITY);
break;
case HAL_PHYDM_ABILITY_RESTORE:
/* restore dm flag */
podmpriv->support_ability = podmpriv->bk_support_ability;
halrf_cmn_info_set(podmpriv, HALRF_CMNINFO_ABILITY, pHalData->bk_rf_ability);
break;
case HAL_PHYDM_ABILITY_SET:
podmpriv->support_ability = ability;
break;
case HAL_PHYDM_ABILITY_GET:
result = podmpriv->support_ability;
break;
}
return result;
}
/* set ODM_CMNINFO_IC_TYPE based on chip_type */
void rtw_odm_init_ic_type(_adapter *adapter)
{
struct dm_struct *odm = adapter_to_phydm(adapter);
u4Byte ic_type = chip_type_to_odm_ic_type(rtw_get_chip_type(adapter));
rtw_warn_on(!ic_type);
odm_cmn_info_init(odm, ODM_CMNINFO_IC_TYPE, ic_type);
}
void rtw_odm_adaptivity_ver_msg(void *sel, _adapter *adapter)
{
RTW_PRINT_SEL(sel, "ADAPTIVITY_VERSION "ADAPTIVITY_VERSION"\n");
}
#define RTW_ADAPTIVITY_EN_DISABLE 0
#define RTW_ADAPTIVITY_EN_ENABLE 1
void rtw_odm_adaptivity_en_msg(void *sel, _adapter *adapter)
{
struct registry_priv *regsty = &adapter->registrypriv;
RTW_PRINT_SEL(sel, "RTW_ADAPTIVITY_EN_");
if (regsty->adaptivity_en == RTW_ADAPTIVITY_EN_DISABLE)
_RTW_PRINT_SEL(sel, "DISABLE\n");
else if (regsty->adaptivity_en == RTW_ADAPTIVITY_EN_ENABLE)
_RTW_PRINT_SEL(sel, "ENABLE\n");
else
_RTW_PRINT_SEL(sel, "INVALID\n");
}
#define RTW_ADAPTIVITY_MODE_NORMAL 0
#define RTW_ADAPTIVITY_MODE_CARRIER_SENSE 1
void rtw_odm_adaptivity_mode_msg(void *sel, _adapter *adapter)
{
struct registry_priv *regsty = &adapter->registrypriv;
RTW_PRINT_SEL(sel, "RTW_ADAPTIVITY_MODE_");
if (regsty->adaptivity_mode == RTW_ADAPTIVITY_MODE_NORMAL)
_RTW_PRINT_SEL(sel, "NORMAL\n");
else if (regsty->adaptivity_mode == RTW_ADAPTIVITY_MODE_CARRIER_SENSE)
_RTW_PRINT_SEL(sel, "CARRIER_SENSE\n");
else
_RTW_PRINT_SEL(sel, "INVALID\n");
}
#define RTW_ADAPTIVITY_DML_DISABLE 0
#define RTW_ADAPTIVITY_DML_ENABLE 1
void rtw_odm_adaptivity_dml_msg(void *sel, _adapter *adapter)
{
struct registry_priv *regsty = &adapter->registrypriv;
RTW_PRINT_SEL(sel, "RTW_ADAPTIVITY_DML_");
if (regsty->adaptivity_dml == RTW_ADAPTIVITY_DML_DISABLE)
_RTW_PRINT_SEL(sel, "DISABLE\n");
else if (regsty->adaptivity_dml == RTW_ADAPTIVITY_DML_ENABLE)
_RTW_PRINT_SEL(sel, "ENABLE\n");
else
_RTW_PRINT_SEL(sel, "INVALID\n");
}
void rtw_odm_adaptivity_dc_backoff_msg(void *sel, _adapter *adapter)
{
struct registry_priv *regsty = &adapter->registrypriv;
RTW_PRINT_SEL(sel, "RTW_ADAPTIVITY_DC_BACKOFF:%u\n", regsty->adaptivity_dc_backoff);
}
void rtw_odm_adaptivity_config_msg(void *sel, _adapter *adapter)
{
rtw_odm_adaptivity_ver_msg(sel, adapter);
rtw_odm_adaptivity_en_msg(sel, adapter);
rtw_odm_adaptivity_mode_msg(sel, adapter);
rtw_odm_adaptivity_dml_msg(sel, adapter);
rtw_odm_adaptivity_dc_backoff_msg(sel, adapter);
}
bool rtw_odm_adaptivity_needed(_adapter *adapter)
{
struct registry_priv *regsty = &adapter->registrypriv;
struct mlme_priv *mlme = &adapter->mlmepriv;
bool ret = _FALSE;
if (regsty->adaptivity_en == RTW_ADAPTIVITY_EN_ENABLE)
ret = _TRUE;
return ret;
}
void rtw_odm_adaptivity_parm_msg(void *sel, _adapter *adapter)
{
struct dm_struct *odm = adapter_to_phydm(adapter);
rtw_odm_adaptivity_config_msg(sel, adapter);
RTW_PRINT_SEL(sel, "%10s %16s %16s %22s %12s\n"
, "th_l2h_ini", "th_edcca_hl_diff", "th_l2h_ini_mode2", "th_edcca_hl_diff_mode2", "edcca_enable");
RTW_PRINT_SEL(sel, "0x%-8x %-16d 0x%-14x %-22d %-12d\n"
, (u8)odm->th_l2h_ini
, odm->th_edcca_hl_diff
, (u8)odm->th_l2h_ini_mode2
, odm->th_edcca_hl_diff_mode2
, odm->edcca_enable
);
RTW_PRINT_SEL(sel, "%15s %9s\n", "AdapEnableState", "Adap_Flag");
RTW_PRINT_SEL(sel, "%-15x %-9x\n"
, odm->adaptivity_enable
, odm->adaptivity_flag
);
}
void rtw_odm_adaptivity_parm_set(_adapter *adapter, s8 th_l2h_ini, s8 th_edcca_hl_diff, s8 th_l2h_ini_mode2, s8 th_edcca_hl_diff_mode2, u8 edcca_enable)
{
struct dm_struct *odm = adapter_to_phydm(adapter);
odm->th_l2h_ini = th_l2h_ini;
odm->th_edcca_hl_diff = th_edcca_hl_diff;
odm->th_l2h_ini_mode2 = th_l2h_ini_mode2;
odm->th_edcca_hl_diff_mode2 = th_edcca_hl_diff_mode2;
odm->edcca_enable = edcca_enable;
}
void rtw_odm_get_perpkt_rssi(void *sel, _adapter *adapter)
{
struct dm_struct *odm = adapter_to_phydm(adapter);
RTW_PRINT_SEL(sel, "rx_rate = %s, rssi_a = %d(%%), rssi_b = %d(%%)\n",
HDATA_RATE(odm->rx_rate), odm->rssi_a, odm->rssi_b);
}
void rtw_odm_acquirespinlock(_adapter *adapter, enum rt_spinlock_type type)
{
PHAL_DATA_TYPE pHalData = GET_HAL_DATA(adapter);
_irqL irqL;
switch (type) {
case RT_IQK_SPINLOCK:
_enter_critical_bh(&pHalData->IQKSpinLock, &irqL);
default:
break;
}
}
void rtw_odm_releasespinlock(_adapter *adapter, enum rt_spinlock_type type)
{
PHAL_DATA_TYPE pHalData = GET_HAL_DATA(adapter);
_irqL irqL;
switch (type) {
case RT_IQK_SPINLOCK:
_exit_critical_bh(&pHalData->IQKSpinLock, &irqL);
default:
break;
}
}
inline u8 rtw_odm_get_dfs_domain(_adapter *adapter)
{
#ifdef CONFIG_DFS_MASTER
struct dm_struct *pDM_Odm = adapter_to_phydm(adapter);
return pDM_Odm->dfs_region_domain;
#else
return PHYDM_DFS_DOMAIN_UNKNOWN;
#endif
}
inline u8 rtw_odm_dfs_domain_unknown(_adapter *adapter)
{
#ifdef CONFIG_DFS_MASTER
return rtw_odm_get_dfs_domain(adapter) == PHYDM_DFS_DOMAIN_UNKNOWN;
#else
return 1;
#endif
}
#ifdef CONFIG_DFS_MASTER
inline VOID rtw_odm_radar_detect_reset(_adapter *adapter)
{
phydm_radar_detect_reset(adapter_to_phydm(adapter));
}
inline VOID rtw_odm_radar_detect_disable(_adapter *adapter)
{
phydm_radar_detect_disable(adapter_to_phydm(adapter));
}
/* called after ch, bw is set */
inline VOID rtw_odm_radar_detect_enable(_adapter *adapter)
{
phydm_radar_detect_enable(adapter_to_phydm(adapter));
}
inline BOOLEAN rtw_odm_radar_detect(_adapter *adapter)
{
return phydm_radar_detect(adapter_to_phydm(adapter));
}
#endif /* CONFIG_DFS_MASTER */
void rtw_odm_parse_rx_phy_status_chinfo(union recv_frame *rframe, u8 *phys)
{
#ifndef DBG_RX_PHYSTATUS_CHINFO
#define DBG_RX_PHYSTATUS_CHINFO 0
#endif
#if (ODM_PHY_STATUS_NEW_TYPE_SUPPORT == 1)
_adapter *adapter = rframe->u.hdr.adapter;
struct dm_struct *phydm = adapter_to_phydm(adapter);
struct rx_pkt_attrib *attrib = &rframe->u.hdr.attrib;
u8 *wlanhdr = get_recvframe_data(rframe);
if (phydm->support_ic_type & PHYSTS_2ND_TYPE_IC) {
/*
* 8723D:
* type_0(CCK)
* l_rxsc
* is filled with primary channel SC, not real rxsc.
* 0:LSC, 1:USC
* type_1(OFDM)
* rf_mode
* RF bandwidth when RX
* l_rxsc(legacy), ht_rxsc
* see below RXSC N-series
* type_2(Not used)
*/
/*
* 8821C, 8822B:
* type_0(CCK)
* l_rxsc
* is filled with primary channel SC, not real rxsc.
* 0:LSC, 1:USC
* type_1(OFDM)
* rf_mode
* RF bandwidth when RX
* l_rxsc(legacy), ht_rxsc
* see below RXSC AC-series
* type_2(Not used)
*/
if ((*phys & 0xf) == 0) {
struct phy_status_rpt_jaguar2_type0 *phys_t0 = (struct phy_status_rpt_jaguar2_type0 *)phys;
if (DBG_RX_PHYSTATUS_CHINFO) {
RTW_PRINT("phys_t%u ta="MAC_FMT" %s, %s(band:%u, ch:%u, l_rxsc:%u)\n"
, *phys & 0xf
, MAC_ARG(get_ta(wlanhdr))
, is_broadcast_mac_addr(get_ra(wlanhdr)) ? "BC" : is_multicast_mac_addr(get_ra(wlanhdr)) ? "MC" : "UC"
, HDATA_RATE(attrib->data_rate)
, phys_t0->band, phys_t0->channel, phys_t0->rxsc
);
}
} else if ((*phys & 0xf) == 1) {
struct phy_status_rpt_jaguar2_type1 *phys_t1 = (struct phy_status_rpt_jaguar2_type1 *)phys;
u8 rxsc = (attrib->data_rate > DESC_RATE11M && attrib->data_rate < DESC_RATEMCS0) ? phys_t1->l_rxsc : phys_t1->ht_rxsc;
u8 pkt_cch = 0;
u8 pkt_bw = CHANNEL_WIDTH_20;
#if ODM_IC_11N_SERIES_SUPPORT
if (phydm->support_ic_type & ODM_IC_11N_SERIES) {
/* RXSC N-series */
#define RXSC_DUP 0
#define RXSC_LSC 1
#define RXSC_USC 2
#define RXSC_40M 3
static const s8 cch_offset_by_rxsc[4] = {0, -2, 2, 0};
if (phys_t1->rf_mode == 0) {
pkt_cch = phys_t1->channel;
pkt_bw = CHANNEL_WIDTH_20;
} else if (phys_t1->rf_mode == 1) {
if (rxsc == RXSC_LSC || rxsc == RXSC_USC) {
pkt_cch = phys_t1->channel + cch_offset_by_rxsc[rxsc];
pkt_bw = CHANNEL_WIDTH_20;
} else if (rxsc == RXSC_40M) {
pkt_cch = phys_t1->channel;
pkt_bw = CHANNEL_WIDTH_40;
}
} else
rtw_warn_on(1);
goto type1_end;
}
#endif /* ODM_IC_11N_SERIES_SUPPORT */
#if ODM_IC_11AC_SERIES_SUPPORT
if (phydm->support_ic_type & ODM_IC_11AC_SERIES) {
/* RXSC AC-series */
#define RXSC_DUP 0 /* 0: RX from all SC of current rf_mode */
#define RXSC_LL20M_OF_160M 8 /* 1~8: RX from 20MHz SC */
#define RXSC_L20M_OF_160M 6
#define RXSC_L20M_OF_80M 4
#define RXSC_L20M_OF_40M 2
#define RXSC_U20M_OF_40M 1
#define RXSC_U20M_OF_80M 3
#define RXSC_U20M_OF_160M 5
#define RXSC_UU20M_OF_160M 7
#define RXSC_L40M_OF_160M 12 /* 9~12: RX from 40MHz SC */
#define RXSC_L40M_OF_80M 10
#define RXSC_U40M_OF_80M 9
#define RXSC_U40M_OF_160M 11
#define RXSC_L80M_OF_160M 14 /* 13~14: RX from 80MHz SC */
#define RXSC_U80M_OF_160M 13
static const s8 cch_offset_by_rxsc[15] = {0, 2, -2, 6, -6, 10, -10, 14, -14, 4, -4, 12, -12, 8, -8};
if (phys_t1->rf_mode > 3) {
/* invalid rf_mode */
rtw_warn_on(1);
goto type1_end;
}
if (phys_t1->rf_mode == 0) {
/* RF 20MHz */
pkt_cch = phys_t1->channel;
pkt_bw = CHANNEL_WIDTH_20;
goto type1_end;
}
if (rxsc == 0) {
/* RF and RX with same BW */
if (attrib->data_rate >= DESC_RATEMCS0) {
pkt_cch = phys_t1->channel;
pkt_bw = phys_t1->rf_mode;
}
goto type1_end;
}
if ((phys_t1->rf_mode == 1 && rxsc >= 1 && rxsc <= 2) /* RF 40MHz, RX 20MHz */
|| (phys_t1->rf_mode == 2 && rxsc >= 1 && rxsc <= 4) /* RF 80MHz, RX 20MHz */
|| (phys_t1->rf_mode == 3 && rxsc >= 1 && rxsc <= 8) /* RF 160MHz, RX 20MHz */
) {
pkt_cch = phys_t1->channel + cch_offset_by_rxsc[rxsc];
pkt_bw = CHANNEL_WIDTH_20;
} else if ((phys_t1->rf_mode == 2 && rxsc >= 9 && rxsc <= 10) /* RF 80MHz, RX 40MHz */
|| (phys_t1->rf_mode == 3 && rxsc >= 9 && rxsc <= 12) /* RF 160MHz, RX 40MHz */
) {
if (attrib->data_rate >= DESC_RATEMCS0) {
pkt_cch = phys_t1->channel + cch_offset_by_rxsc[rxsc];
pkt_bw = CHANNEL_WIDTH_40;
}
} else if ((phys_t1->rf_mode == 3 && rxsc >= 13 && rxsc <= 14) /* RF 160MHz, RX 80MHz */
) {
if (attrib->data_rate >= DESC_RATEMCS0) {
pkt_cch = phys_t1->channel + cch_offset_by_rxsc[rxsc];
pkt_bw = CHANNEL_WIDTH_80;
}
} else
rtw_warn_on(1);
}
#endif /* ODM_IC_11AC_SERIES_SUPPORT */
type1_end:
if (DBG_RX_PHYSTATUS_CHINFO) {
RTW_PRINT("phys_t%u ta="MAC_FMT" %s, %s(band:%u, ch:%u, rf_mode:%u, l_rxsc:%u, ht_rxsc:%u) => %u,%u\n"
, *phys & 0xf
, MAC_ARG(get_ta(wlanhdr))
, is_broadcast_mac_addr(get_ra(wlanhdr)) ? "BC" : is_multicast_mac_addr(get_ra(wlanhdr)) ? "MC" : "UC"
, HDATA_RATE(attrib->data_rate)
, phys_t1->band, phys_t1->channel, phys_t1->rf_mode, phys_t1->l_rxsc, phys_t1->ht_rxsc
, pkt_cch, pkt_bw
);
}
/* for now, only return cneter channel of 20MHz packet */
if (pkt_cch && pkt_bw == CHANNEL_WIDTH_20)
attrib->ch = pkt_cch;
} else {
struct phy_status_rpt_jaguar2_type2 *phys_t2 = (struct phy_status_rpt_jaguar2_type2 *)phys;
if (DBG_RX_PHYSTATUS_CHINFO) {
RTW_PRINT("phys_t%u ta="MAC_FMT" %s, %s(band:%u, ch:%u, l_rxsc:%u, ht_rxsc:%u)\n"
, *phys & 0xf
, MAC_ARG(get_ta(wlanhdr))
, is_broadcast_mac_addr(get_ra(wlanhdr)) ? "BC" : is_multicast_mac_addr(get_ra(wlanhdr)) ? "MC" : "UC"
, HDATA_RATE(attrib->data_rate)
, phys_t2->band, phys_t2->channel, phys_t2->l_rxsc, phys_t2->ht_rxsc
);
}
}
}
#endif /* (ODM_PHY_STATUS_NEW_TYPE_SUPPORT == 1) */
}

5454
core/rtw_p2p.c Normal file

File diff suppressed because it is too large Load Diff

2673
core/rtw_pwrctrl.c Normal file

File diff suppressed because it is too large Load Diff

4991
core/rtw_recv.c Normal file

File diff suppressed because it is too large Load Diff

1909
core/rtw_rf.c Normal file

File diff suppressed because it is too large Load Diff

2493
core/rtw_rm.c Normal file

File diff suppressed because it is too large Load Diff

998
core/rtw_rm_fsm.c Normal file
View File

@ -0,0 +1,998 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#include <drv_types.h>
#include <hal_data.h>
#include "rtw_rm_fsm.h"
#ifdef CONFIG_RTW_80211K
struct fsm_state {
u8 *name;
int(*fsm_func)(struct rm_obj *prm, enum RM_EV_ID evid);
};
static void rm_state_initial(struct rm_obj *prm);
static void rm_state_goto(struct rm_obj *prm, enum RM_STATE rm_state);
static void rm_state_run(struct rm_obj *prm, enum RM_EV_ID evid);
static struct rm_event *rm_dequeue_ev(_queue *queue);
static struct rm_obj *rm_dequeue_rm(_queue *queue);
void rm_timer_callback(void *data)
{
int i;
_adapter *padapter = (_adapter *)data;
struct rm_priv *prmpriv = &padapter->rmpriv;
struct rm_clock *pclock;
/* deal with clock */
for (i=0;i<RM_TIMER_NUM;i++) {
pclock = &prmpriv->clock[i];
if (pclock->prm == NULL
||(ATOMIC_READ(&(pclock->counter)) == 0))
continue;
ATOMIC_DEC(&(pclock->counter));
if (ATOMIC_READ(&(pclock->counter)) == 0)
rm_post_event(pclock->prm->psta->padapter,
pclock->prm->rmid, prmpriv->clock[i].evid);
}
_set_timer(&prmpriv->rm_timer, CLOCK_UNIT);
}
int rtw_init_rm(_adapter *padapter)
{
struct rm_priv *prmpriv = &padapter->rmpriv;
RTW_INFO("RM: %s\n",__func__);
_rtw_init_queue(&(prmpriv->rm_queue));
_rtw_init_queue(&(prmpriv->ev_queue));
/* bit 0-7 */
prmpriv->rm_en_cap_def[0] = 0
/*| BIT(RM_LINK_MEAS_CAP_EN)*/
| BIT(RM_NB_REP_CAP_EN)
/*| BIT(RM_PARAL_MEAS_CAP_EN)*/
| BIT(RM_REPEAT_MEAS_CAP_EN)
| BIT(RM_BCN_PASSIVE_MEAS_CAP_EN)
| BIT(RM_BCN_ACTIVE_MEAS_CAP_EN)
| BIT(RM_BCN_TABLE_MEAS_CAP_EN)
/*| BIT(RM_BCN_MEAS_REP_COND_CAP_EN)*/;
/* bit 8-15 */
prmpriv->rm_en_cap_def[1] = 0
/*| BIT(RM_FRAME_MEAS_CAP_EN - 8)*/
#ifdef CONFIG_RTW_ACS
| BIT(RM_CH_LOAD_CAP_EN - 8)
| BIT(RM_NOISE_HISTO_CAP_EN - 8)
#endif
/*| BIT(RM_STATIS_MEAS_CAP_EN - 8)*/
/*| BIT(RM_LCI_MEAS_CAP_EN - 8)*/
/*| BIT(RM_LCI_AMIMUTH_CAP_EN - 8)*/
/*| BIT(RM_TRANS_STREAM_CAT_MEAS_CAP_EN - 8)*/
/*| BIT(RM_TRIG_TRANS_STREAM_CAT_MEAS_CAP_EN - 8)*/;
/* bit 16-23 */
prmpriv->rm_en_cap_def[2] = 0
/*| BIT(RM_AP_CH_REP_CAP_EN - 16)*/
/*| BIT(RM_RM_MIB_CAP_EN - 16)*/
/*| BIT(RM_OP_CH_MAX_MEAS_DUR0 - 16)*/
/*| BIT(RM_OP_CH_MAX_MEAS_DUR1 - 16)*/
/*| BIT(RM_OP_CH_MAX_MEAS_DUR2 - 16)*/
/*| BIT(RM_NONOP_CH_MAX_MEAS_DUR0 - 16)*/
/*| BIT(RM_NONOP_CH_MAX_MEAS_DUR1 - 16)*/
/*| BIT(RM_NONOP_CH_MAX_MEAS_DUR2 - 16)*/;
/* bit 24-31 */
prmpriv->rm_en_cap_def[3] = 0
/*| BIT(RM_MEAS_PILOT_CAP0 - 24)*/
/*| BIT(RM_MEAS_PILOT_CAP1 - 24)*/
/*| BIT(RM_MEAS_PILOT_CAP2 - 24)*/
/*| BIT(RM_MEAS_PILOT_TRANS_INFO_CAP_EN - 24)*/
/*| BIT(RM_NB_REP_TSF_OFFSET_CAP_EN - 24)*/
| BIT(RM_RCPI_MEAS_CAP_EN - 24)
| BIT(RM_RSNI_MEAS_CAP_EN - 24)
/*| BIT(RM_BSS_AVG_ACCESS_DELAY_CAP_EN - 24)*/;
/* bit 32-39 */
prmpriv->rm_en_cap_def[4] = 0
/*| BIT(RM_BSS_AVG_ACCESS_DELAY_CAP_EN - 32)*/
/*| BIT(RM_AVALB_ADMIS_CAPACITY_CAP_EN - 32)*/
/*| BIT(RM_ANT_CAP_EN - 32)*/;
prmpriv->enable = _TRUE;
/* clock timer */
rtw_init_timer(&prmpriv->rm_timer,
padapter, rm_timer_callback, padapter);
_set_timer(&prmpriv->rm_timer, CLOCK_UNIT);
return _SUCCESS;
}
int rtw_deinit_rm(_adapter *padapter)
{
struct rm_priv *prmpriv = &padapter->rmpriv;
struct rm_obj *prm;
struct rm_event *pev;
RTW_INFO("RM: %s\n",__func__);
prmpriv->enable = _FALSE;
_cancel_timer_ex(&prmpriv->rm_timer);
/* free all events and measurements */
while((pev = rm_dequeue_ev(&prmpriv->ev_queue)) != NULL)
rtw_mfree((void *)pev, sizeof(struct rm_event));
while((prm = rm_dequeue_rm(&prmpriv->rm_queue)) != NULL)
rm_state_run(prm, RM_EV_cancel);
_rtw_deinit_queue(&(prmpriv->rm_queue));
_rtw_deinit_queue(&(prmpriv->ev_queue));
return _SUCCESS;
}
int rtw_free_rm_priv(_adapter *padapter)
{
return rtw_deinit_rm(padapter);
}
static int rm_enqueue_ev(_queue *queue, struct rm_event *obj, bool to_head)
{
_irqL irqL;
if (obj == NULL)
return _FAIL;
_enter_critical(&queue->lock, &irqL);
if (to_head)
rtw_list_insert_head(&obj->list, &queue->queue);
else
rtw_list_insert_tail(&obj->list, &queue->queue);
_exit_critical(&queue->lock, &irqL);
return _SUCCESS;
}
static void rm_set_clock(struct rm_obj *prm, u32 ms, enum RM_EV_ID evid)
{
ATOMIC_SET(&(prm->pclock->counter), (ms/CLOCK_UNIT));
prm->pclock->evid = evid;
}
static struct rm_clock *rm_alloc_clock(_adapter *padapter, struct rm_obj *prm)
{
int i;
struct rm_priv *prmpriv = &padapter->rmpriv;
struct rm_clock *pclock = NULL;
for (i=0;i<RM_TIMER_NUM;i++) {
pclock = &prmpriv->clock[i];
if (pclock->prm == NULL) {
pclock->prm = prm;
ATOMIC_SET(&(pclock->counter), 0);
pclock->evid = RM_EV_max;
break;
}
}
return pclock;
}
static void rm_cancel_clock(struct rm_obj *prm)
{
ATOMIC_SET(&(prm->pclock->counter), 0);
prm->pclock->evid = RM_EV_max;
}
static void rm_free_clock(struct rm_clock *pclock)
{
pclock->prm = NULL;
ATOMIC_SET(&(pclock->counter), 0);
pclock->evid = RM_EV_max;
}
static int is_list_linked(const struct list_head *head)
{
return head->prev != NULL;
}
void rm_free_rmobj(struct rm_obj *prm)
{
if (is_list_linked(&prm->list))
rtw_list_delete(&prm->list);
if (prm->q.pssid)
rtw_mfree(prm->q.pssid, strlen(prm->q.pssid)+1);
if (prm->q.opt.bcn.req_start)
rtw_mfree(prm->q.opt.bcn.req_start,
prm->q.opt.bcn.req_len);
if (prm->pclock)
rm_free_clock(prm->pclock);
rtw_mfree((void *)prm, sizeof(struct rm_obj));
}
struct rm_obj *rm_alloc_rmobj(_adapter *padapter)
{
struct rm_obj *prm;
prm = (struct rm_obj *)rtw_malloc(sizeof(struct rm_obj));
if (prm == NULL)
return NULL;
_rtw_memset(prm, 0, sizeof(struct rm_obj));
/* alloc timer */
if ((prm->pclock = rm_alloc_clock(padapter, prm)) == NULL) {
rm_free_rmobj(prm);
return NULL;
}
return prm;
}
int rm_enqueue_rmobj(_adapter *padapter, struct rm_obj *prm, bool to_head)
{
_irqL irqL;
struct rm_priv *prmpriv = &padapter->rmpriv;
_queue *queue = &prmpriv->rm_queue;
if (prm == NULL)
return _FAIL;
_enter_critical(&queue->lock, &irqL);
if (to_head)
rtw_list_insert_head(&prm->list, &queue->queue);
else
rtw_list_insert_tail(&prm->list, &queue->queue);
_exit_critical(&queue->lock, &irqL);
rm_state_initial(prm);
return _SUCCESS;
}
static struct rm_obj *rm_dequeue_rm(_queue *queue)
{
_irqL irqL;
struct rm_obj *prm;
_enter_critical(&queue->lock, &irqL);
if (rtw_is_list_empty(&(queue->queue)))
prm = NULL;
else {
prm = LIST_CONTAINOR(get_next(&(queue->queue)),
struct rm_obj, list);
/* rtw_list_delete(&prm->list); */
}
_exit_critical(&queue->lock, &irqL);
return prm;
}
static struct rm_event *rm_dequeue_ev(_queue *queue)
{
_irqL irqL;
struct rm_event *ev;
_enter_critical(&queue->lock, &irqL);
if (rtw_is_list_empty(&(queue->queue)))
ev = NULL;
else {
ev = LIST_CONTAINOR(get_next(&(queue->queue)),
struct rm_event, list);
rtw_list_delete(&ev->list);
}
_exit_critical(&queue->lock, &irqL);
return ev;
}
static struct rm_obj *_rm_get_rmobj(_queue *queue, u32 rmid)
{
_irqL irqL;
_list *phead, *plist;
struct rm_obj *prm = NULL;
if (rmid == 0)
return NULL;
_enter_critical(&queue->lock, &irqL);
phead = get_list_head(queue);
plist = get_next(phead);
while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
prm = LIST_CONTAINOR(plist, struct rm_obj, list);
if (rmid == (prm->rmid)) {
_exit_critical(&queue->lock, &irqL);
return prm;
}
plist = get_next(plist);
}
_exit_critical(&queue->lock, &irqL);
return NULL;
}
struct sta_info *rm_get_psta(_adapter *padapter, u32 rmid)
{
struct rm_priv *prmpriv = &padapter->rmpriv;
struct rm_obj *prm;
prm = _rm_get_rmobj(&prmpriv->rm_queue, rmid);
if (prm)
return prm->psta;
return NULL;
}
struct rm_obj *rm_get_rmobj(_adapter *padapter, u32 rmid)
{
struct rm_priv *prmpriv = &padapter->rmpriv;
return _rm_get_rmobj(&prmpriv->rm_queue, rmid);
}
u8 rtw_rm_post_envent_cmd(_adapter *padapter, u32 rmid, u8 evid)
{
struct cmd_obj *pcmd;
struct rm_event *pev;
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
u8 res = _SUCCESS;
pcmd = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
if (pcmd == NULL) {
res = _FAIL;
goto exit;
}
pev = (struct rm_event*)rtw_zmalloc(sizeof(struct rm_event));
if (pev == NULL) {
rtw_mfree((u8 *) pcmd, sizeof(struct cmd_obj));
res = _FAIL;
goto exit;
}
pev->rmid = rmid;
pev->evid = evid;
init_h2fwcmd_w_parm_no_rsp(pcmd, pev, GEN_CMD_CODE(_RM_POST_EVENT));
res = rtw_enqueue_cmd(pcmdpriv, pcmd);
exit:
return res;
}
int rm_post_event(_adapter *padapter, u32 rmid, enum RM_EV_ID evid)
{
if (padapter->rmpriv.enable == _FALSE)
return _FALSE;
RTW_INFO("RM: post asyn %s to rmid=%x\n", rm_event_name(evid), rmid);
rtw_rm_post_envent_cmd(padapter, rmid, evid);
return _SUCCESS;
}
int _rm_post_event(_adapter *padapter, u32 rmid, enum RM_EV_ID evid)
{
struct rm_priv *prmpriv = &padapter->rmpriv;
struct rm_event *pev;
if (evid >= RM_EV_max || rmid == 0)
return _FALSE;
pev = (struct rm_event *)rtw_malloc(sizeof(struct rm_event));
if (pev == NULL)
return _FALSE;
pev->rmid = rmid;
pev->evid = evid;
RTW_INFO("RM: post sync %s to rmid=%x\n", rm_event_name(evid), rmid);
rm_enqueue_ev(&prmpriv->ev_queue, pev, FALSE);
return _SUCCESS;
}
static void rm_bcast_aid_handler(_adapter *padapter, struct rm_event *pev)
{
_irqL irqL;
_list *phead, *plist;
_queue *queue = &padapter->rmpriv.rm_queue;
struct rm_obj *prm;
_enter_critical(&queue->lock, &irqL);
phead = get_list_head(queue);
plist = get_next(phead);
while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
prm = LIST_CONTAINOR(plist, struct rm_obj, list);
plist = get_next(plist);
if (RM_GET_AID(pev->rmid) == RM_GET_AID(prm->rmid)) {
_exit_critical(&queue->lock, &irqL);
rm_state_run(prm, pev->evid);
_enter_critical(&queue->lock, &irqL);
}
}
_exit_critical(&queue->lock, &irqL);
return;
}
/* main handler of RM (Resource Management) */
void rm_handler(_adapter *padapter, struct rm_event *pe)
{
int i;
struct rm_priv *prmpriv = &padapter->rmpriv;
struct rm_obj *prm;
struct rm_event *pev;
/* dequeue event */
while((pev = rm_dequeue_ev(&prmpriv->ev_queue)) != NULL)
{
if (RM_IS_ID_FOR_ALL(pev->rmid)) {
/* apply to all aid mateched measurement */
rm_bcast_aid_handler(padapter, pev);
rtw_mfree((void *)pev, sizeof(struct rm_event));
continue;
}
/* retrieve rmobj */
prm = _rm_get_rmobj(&prmpriv->rm_queue, pev->rmid);
if (prm == NULL) {
RTW_ERR("RM: rmid=%x event=%s doesn't find rm obj\n",
pev->rmid, rm_event_name(pev->evid));
rtw_mfree((void *)pev, sizeof(struct rm_event));
return;
}
/* run state machine */
rm_state_run(prm, pev->evid);
rtw_mfree((void *)pev, sizeof(struct rm_event));
}
}
static int rm_issue_meas_req(struct rm_obj *prm)
{
switch (prm->q.action_code) {
case RM_ACT_RADIO_MEAS_REQ:
switch (prm->q.m_type) {
case bcn_req:
case ch_load_req:
case noise_histo_req:
issue_radio_meas_req(prm);
break;
default:
break;
} /* meas_type */
break;
case RM_ACT_NB_REP_REQ:
/* issue neighbor request */
issue_nb_req(prm);
break;
case RM_ACT_LINK_MEAS_REQ:
default:
return _FALSE;
} /* action_code */
return _SUCCESS;
}
/*
* RM state machine
*/
static int rm_state_idle(struct rm_obj *prm, enum RM_EV_ID evid)
{
_adapter *padapter = prm->psta->padapter;
u8 val8;
u32 val32;
prm->p.category = RTW_WLAN_CATEGORY_RADIO_MEAS;
switch (evid) {
case RM_EV_state_in:
switch (prm->q.action_code) {
case RM_ACT_RADIO_MEAS_REQ:
/* copy attrib from meas_req to meas_rep */
prm->p.action_code = RM_ACT_RADIO_MEAS_REP;
prm->p.diag_token = prm->q.diag_token;
prm->p.e_id = _MEAS_RSP_IE_;
prm->p.m_token = prm->q.m_token;
prm->p.m_type = prm->q.m_type;
prm->p.rpt = prm->q.rpt;
prm->p.ch_num = prm->q.ch_num;
prm->p.op_class = prm->q.op_class;
if (prm->q.m_type == ch_load_req
|| prm->q.m_type == noise_histo_req) {
/*
* phydm measure current ch periodically
* scan current ch is not necessary
*/
val8 = padapter->mlmeextpriv.cur_channel;
if (prm->q.ch_num == val8)
prm->poll_mode = 1;
}
RTW_INFO("RM: rmid=%x %s switch in repeat=%u\n",
prm->rmid, rm_type_req_name(prm->q.m_type),
prm->q.rpt);
break;
case RM_ACT_NB_REP_REQ:
prm->p.action_code = RM_ACT_NB_REP_RESP;
RTW_INFO("RM: rmid=%x Neighbor request switch in\n",
prm->rmid);
break;
case RM_ACT_LINK_MEAS_REQ:
prm->p.action_code = RM_ACT_LINK_MEAS_REP;
rm_set_rep_mode(prm, MEAS_REP_MOD_INCAP);
RTW_INFO("RM: rmid=%x Link meas switch in\n",
prm->rmid);
break;
default:
prm->p.action_code = prm->q.action_code;
rm_set_rep_mode(prm, MEAS_REP_MOD_INCAP);
RTW_INFO("RM: rmid=%x recv unknown action %d\n",
prm->rmid,prm->p.action_code);
break;
} /* switch() */
if (prm->rmid & RM_MASTER) {
if (rm_issue_meas_req(prm) == _SUCCESS)
rm_state_goto(prm, RM_ST_WAIT_MEAS);
else
rm_state_goto(prm, RM_ST_END);
return _SUCCESS;
} else {
rm_state_goto(prm, RM_ST_DO_MEAS);
return _SUCCESS;
}
if (prm->p.m_mode) {
issue_null_reply(prm);
rm_state_goto(prm, RM_ST_END);
return _SUCCESS;
}
if (prm->q.rand_intvl) {
/* get low tsf to generate random interval */
val32 = rtw_read32(padapter, REG_TSFTR);
val32 = val32 % prm->q.rand_intvl;
RTW_INFO("RM: rmid=%x rand_intval=%d, rand=%d\n",
prm->rmid, (int)prm->q.rand_intvl,val32);
rm_set_clock(prm, prm->q.rand_intvl,
RM_EV_delay_timer_expire);
return _SUCCESS;
}
break;
case RM_EV_delay_timer_expire:
rm_state_goto(prm, RM_ST_DO_MEAS);
break;
case RM_EV_cancel:
rm_state_goto(prm, RM_ST_END);
break;
case RM_EV_state_out:
rm_cancel_clock(prm);
break;
default:
break;
}
return _SUCCESS;
}
/* we do the measuring */
static int rm_state_do_meas(struct rm_obj *prm, enum RM_EV_ID evid)
{
_adapter *padapter = prm->psta->padapter;
u8 val8;
u64 val64;
switch (evid) {
case RM_EV_state_in:
if (prm->q.action_code == RM_ACT_RADIO_MEAS_REQ) {
switch (prm->q.m_type) {
case bcn_req:
if (prm->q.m_mode == bcn_req_bcn_table) {
RTW_INFO("RM: rmid=%x Beacon table\n",
prm->rmid);
_rm_post_event(padapter, prm->rmid,
RM_EV_survey_done);
return _SUCCESS;
}
break;
case ch_load_req:
case noise_histo_req:
if (prm->poll_mode)
_rm_post_event(padapter, prm->rmid,
RM_EV_survey_done);
return _SUCCESS;
default:
rm_state_goto(prm, RM_ST_END);
return _SUCCESS;
}
if (!ready_for_scan(prm)) {
prm->wait_busy = RM_BUSY_TRAFFIC_TIMES;
RTW_INFO("RM: wait busy traffic - %d\n",
prm->wait_busy);
rm_set_clock(prm, RM_WAIT_BUSY_TIMEOUT,
RM_EV_busy_timer_expire);
return _SUCCESS;
}
}
_rm_post_event(padapter, prm->rmid, RM_EV_start_meas);
break;
case RM_EV_start_meas:
if (prm->q.action_code == RM_ACT_RADIO_MEAS_REQ) {
/* resotre measurement start time */
rtw_hal_get_hwreg(padapter, HW_VAR_TSF, (u8 *)&val64);
prm->meas_start_time = val64;
switch (prm->q.m_type) {
case bcn_req:
val8 = 1; /* Enable free run counter */
rtw_hal_set_hwreg(padapter,
HW_VAR_FREECNT, &val8);
rm_sitesurvey(prm);
break;
case ch_load_req:
case noise_histo_req:
rm_sitesurvey(prm);
break;
default:
rm_state_goto(prm, RM_ST_END);
return _SUCCESS;
break;
}
}
/* handle measurement timeout */
rm_set_clock(prm, RM_MEAS_TIMEOUT, RM_EV_meas_timer_expire);
break;
case RM_EV_survey_done:
if (prm->q.action_code == RM_ACT_RADIO_MEAS_REQ) {
switch (prm->q.m_type) {
case bcn_req:
rm_cancel_clock(prm);
rm_state_goto(prm, RM_ST_SEND_REPORT);
return _SUCCESS;
case ch_load_req:
case noise_histo_req:
retrieve_radio_meas_result(prm);
if (rm_radio_meas_report_cond(prm) == _SUCCESS)
rm_state_goto(prm, RM_ST_SEND_REPORT);
else
rm_set_clock(prm, RM_COND_INTVL,
RM_EV_retry_timer_expire);
break;
default:
rm_state_goto(prm, RM_ST_END);
return _SUCCESS;
}
}
break;
case RM_EV_meas_timer_expire:
RTW_INFO("RM: rmid=%x measurement timeount\n",prm->rmid);
rm_set_rep_mode(prm, MEAS_REP_MOD_REFUSE);
issue_null_reply(prm);
rm_state_goto(prm, RM_ST_END);
break;
case RM_EV_busy_timer_expire:
if (!ready_for_scan(prm) && prm->wait_busy--) {
RTW_INFO("RM: wait busy - %d\n",prm->wait_busy);
rm_set_clock(prm, RM_WAIT_BUSY_TIMEOUT,
RM_EV_busy_timer_expire);
break;
}
else if (prm->wait_busy <= 0) {
RTW_INFO("RM: wait busy timeout\n");
rm_set_rep_mode(prm, MEAS_REP_MOD_REFUSE);
issue_null_reply(prm);
rm_state_goto(prm, RM_ST_END);
return _SUCCESS;
}
_rm_post_event(padapter, prm->rmid, RM_EV_start_meas);
break;
case RM_EV_request_timer_expire:
rm_set_rep_mode(prm, MEAS_REP_MOD_REFUSE);
issue_null_reply(prm);
rm_state_goto(prm, RM_ST_END);
break;
case RM_EV_retry_timer_expire:
/* expired due to meas condition mismatch, meas again */
_rm_post_event(padapter, prm->rmid, RM_EV_start_meas);
break;
case RM_EV_cancel:
rm_set_rep_mode(prm, MEAS_REP_MOD_REFUSE);
issue_null_reply(prm);
rm_state_goto(prm, RM_ST_END);
break;
case RM_EV_state_out:
rm_cancel_clock(prm);
/* resotre measurement end time */
rtw_hal_get_hwreg(padapter, HW_VAR_TSF, (u8 *)&val64);
_rtw_memcpy(&prm->meas_end_time, (char *)&val64, sizeof(u64));
val8 = 0; /* Disable free run counter */
rtw_hal_set_hwreg(padapter, HW_VAR_FREECNT, &val8);
break;
default:
break;
}
return _SUCCESS;
}
static int rm_state_wait_meas(struct rm_obj *prm, enum RM_EV_ID evid)
{
u8 val8;
u64 val64;
switch (evid) {
case RM_EV_state_in:
/* we create meas_req, waiting for peer report */
rm_set_clock(prm, RM_REQ_TIMEOUT,
RM_EV_request_timer_expire);
break;
case RM_EV_recv_rep:
rm_state_goto(prm, RM_ST_RECV_REPORT);
break;
case RM_EV_request_timer_expire:
case RM_EV_cancel:
rm_state_goto(prm, RM_ST_END);
break;
case RM_EV_state_out:
rm_cancel_clock(prm);
break;
default:
break;
}
return _SUCCESS;
}
static int rm_state_send_report(struct rm_obj *prm, enum RM_EV_ID evid)
{
u8 val8;
switch (evid) {
case RM_EV_state_in:
/* we have to issue report */
switch (prm->q.m_type) {
case bcn_req:
issue_beacon_rep(prm);
break;
case ch_load_req:
case noise_histo_req:
issue_radio_meas_rep(prm);
break;
default:
rm_state_goto(prm, RM_ST_END);
return _SUCCESS;
}
/* check repeat */
if (prm->p.rpt) {
RTW_INFO("RM: rmid=%x repeat=%u/%u\n",
prm->rmid, prm->p.rpt,
prm->q.rpt);
prm->p.rpt--;
/*
* we recv meas_req,
* delay for a wihile and than meas again
*/
if (prm->poll_mode)
rm_set_clock(prm, RM_REPT_POLL_INTVL,
RM_EV_repeat_delay_expire);
else
rm_set_clock(prm, RM_REPT_SCAN_INTVL,
RM_EV_repeat_delay_expire);
return _SUCCESS;
}
/* we are done */
rm_state_goto(prm, RM_ST_END);
break;
case RM_EV_repeat_delay_expire:
rm_state_goto(prm, RM_ST_DO_MEAS);
break;
case RM_EV_cancel:
rm_state_goto(prm, RM_ST_END);
break;
case RM_EV_state_out:
rm_cancel_clock(prm);
break;
default:
break;
}
return _SUCCESS;
}
static int rm_state_recv_report(struct rm_obj *prm, enum RM_EV_ID evid)
{
u8 val8;
switch (evid) {
case RM_EV_state_in:
/* we issue meas_req, got peer's meas report */
switch (prm->p.action_code) {
case RM_ACT_RADIO_MEAS_REP:
/* check refuse, incapable and repeat */
val8 = prm->p.m_mode;
if (val8) {
RTW_INFO("RM: rmid=%x peer reject (%s repeat=%d)\n",
prm->rmid,
val8|MEAS_REP_MOD_INCAP?"INCAP":
val8|MEAS_REP_MOD_REFUSE?"REFUSE":
val8|MEAS_REP_MOD_LATE?"LATE":"",
prm->p.rpt);
rm_state_goto(prm, RM_ST_END);
return _SUCCESS;
}
break;
case RM_ACT_NB_REP_RESP:
/* report to upper layer if needing */
rm_state_goto(prm, RM_ST_END);
return _SUCCESS;
default:
rm_state_goto(prm, RM_ST_END);
return _SUCCESS;
}
/* check repeat */
if (prm->p.rpt) {
RTW_INFO("RM: rmid=%x repeat=%u/%u\n",
prm->rmid, prm->p.rpt,
prm->q.rpt);
prm->p.rpt--;
/* waitting more report */
rm_state_goto(prm, RM_ST_WAIT_MEAS);
break;
}
/* we are done */
rm_state_goto(prm, RM_ST_END);
break;
case RM_EV_cancel:
rm_state_goto(prm, RM_ST_END);
break;
case RM_EV_state_out:
rm_cancel_clock(prm);
break;
default:
break;
}
return _SUCCESS;
}
static int rm_state_end(struct rm_obj *prm, enum RM_EV_ID evid)
{
switch (evid) {
case RM_EV_state_in:
_rm_post_event(prm->psta->padapter, prm->rmid, RM_EV_state_out);
break;
case RM_EV_cancel:
case RM_EV_state_out:
default:
rm_free_rmobj(prm);
break;
}
return _SUCCESS;
}
struct fsm_state rm_fsm[] = {
{"RM_ST_IDLE", rm_state_idle},
{"RM_ST_DO_MEAS", rm_state_do_meas},
{"RM_ST_WAIT_MEAS", rm_state_wait_meas},
{"RM_ST_SEND_REPORT", rm_state_send_report},
{"RM_ST_RECV_REPORT", rm_state_recv_report},
{"RM_ST_END", rm_state_end}
};
char *rm_state_name(enum RM_STATE state)
{
return rm_fsm[state].name;
}
char *rm_event_name(enum RM_EV_ID evid)
{
switch(evid) {
case RM_EV_state_in:
return "RM_EV_state_in";
case RM_EV_busy_timer_expire:
return "RM_EV_busy_timer_expire";
case RM_EV_delay_timer_expire:
return "RM_EV_delay_timer_expire";
case RM_EV_meas_timer_expire:
return "RM_EV_meas_timer_expire";
case RM_EV_repeat_delay_expire:
return "RM_EV_repeat_delay_expire";
case RM_EV_retry_timer_expire:
return "RM_EV_retry_timer_expire";
case RM_EV_request_timer_expire:
return "RM_EV_request_timer_expire";
case RM_EV_wait_report:
return "RM_EV_wait_report";
case RM_EV_start_meas:
return "RM_EV_start_meas";
case RM_EV_survey_done:
return "RM_EV_survey_done";
case RM_EV_recv_rep:
return "RM_EV_recv_report";
case RM_EV_cancel:
return "RM_EV_cancel";
case RM_EV_state_out:
return "RM_EV_state_out";
case RM_EV_max:
return "RM_EV_max";
default:
return "RM_EV_unknown";
}
return "UNKNOWN";
}
static void rm_state_initial(struct rm_obj *prm)
{
prm->state = RM_ST_IDLE;
RTW_INFO("\n");
RTW_INFO("RM: rmid=%x %-18s -> %s\n",prm->rmid,
"new measurement", rm_fsm[prm->state].name);
rm_post_event(prm->psta->padapter, prm->rmid, RM_EV_state_in);
}
static void rm_state_run(struct rm_obj *prm, enum RM_EV_ID evid)
{
RTW_INFO("RM: rmid=%x %-18s %s\n",prm->rmid,
rm_fsm[prm->state].name,rm_event_name(evid));
rm_fsm[prm->state].fsm_func(prm, evid);
}
static void rm_state_goto(struct rm_obj *prm, enum RM_STATE rm_state)
{
if (prm->state == rm_state)
return;
rm_state_run(prm, RM_EV_state_out);
RTW_INFO("\n");
RTW_INFO("RM: rmid=%x %-18s -> %s\n",prm->rmid,
rm_fsm[prm->state].name, rm_fsm[rm_state].name);
prm->state = rm_state;
rm_state_run(prm, RM_EV_state_in);
}
#endif /* CONFIG_RTW_80211K */

595
core/rtw_rson.c Normal file
View File

@ -0,0 +1,595 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
*
******************************************************************************/
#define _RTW_RSON_C_
#include <drv_types.h>
#ifdef CONFIG_RTW_REPEATER_SON
/******** Custommize Part ***********************/
unsigned char RTW_RSON_OUI[] = {0xFA, 0xFA, 0xFA};
#define RSON_SCORE_DIFF_TH 8
/*
Calculate the corresponding score.
*/
inline u8 rtw_cal_rson_score(struct rtw_rson_struct *cand_rson_data, NDIS_802_11_RSSI Rssi)
{
if ((cand_rson_data->hopcnt == RTW_RSON_HC_NOTREADY)
|| (cand_rson_data->connectible == RTW_RSON_DENYCONNECT))
return RTW_RSON_SCORE_NOTCNNT;
return RTW_RSON_SCORE_MAX - (cand_rson_data->hopcnt * 10) + (Rssi/10);
}
/*************************************************/
static u8 rtw_rson_block_bssid_idx = 0;
u8 rtw_rson_block_bssid[10][6] = {
/*{0x02, 0xE0, 0x4C, 0x07, 0xC3, 0xF6}*/
};
/* fake root, regard a real AP as a SO root */
static u8 rtw_rson_root_bssid_idx = 0;
u8 rtw_rson_root_bssid[10][6] = {
/*{0x1c, 0x5f, 0x2b, 0x5a, 0x60, 0x24}*/
};
int is_match_bssid(u8 *mac, u8 bssid_array[][6], int num)
{
int i;
for (i = 0; i < num; i++)
if (_rtw_memcmp(mac, bssid_array[i], 6) == _TRUE)
return _TRUE;
return _FALSE;
}
void init_rtw_rson_data(struct dvobj_priv *dvobj)
{
/*Aries todo. if pdvobj->rson_data.ver == 1 */
dvobj->rson_data.ver = RTW_RSON_VER;
dvobj->rson_data.id = CONFIG_RTW_REPEATER_SON_ID;
#ifdef CONFIG_RTW_REPEATER_SON_ROOT
dvobj->rson_data.hopcnt = RTW_RSON_HC_ROOT;
dvobj->rson_data.connectible = RTW_RSON_ALLOWCONNECT;
#else
dvobj->rson_data.hopcnt = RTW_RSON_HC_NOTREADY;
dvobj->rson_data.connectible = RTW_RSON_DENYCONNECT;
#endif
dvobj->rson_data.loading = 0;
_rtw_memset(dvobj->rson_data.res, 0xAA, sizeof(dvobj->rson_data.res));
}
void rtw_rson_get_property_str(_adapter *padapter, char *rson_data_str)
{
struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
sprintf(rson_data_str, "version : \t%d\nid : \t\t%08x\nhop count : \t%d\nconnectible : \t%s\nloading : \t%d\nreserve : \t%16ph\n",
pdvobj->rson_data.ver,
pdvobj->rson_data.id,
pdvobj->rson_data.hopcnt,
pdvobj->rson_data.connectible ? "connectable":"unconnectable",
pdvobj->rson_data.loading,
pdvobj->rson_data.res);
}
int str2hexbuf(char *str, u8 *hexbuf, int len)
{
u8 *p;
int i, slen, idx = 0;
p = (unsigned char *)str;
if ((*p != '0') || (*(p+1) != 'x'))
return _FALSE;
slen = strlen(str);
if (slen > (len*2) + 2)
return _FALSE;
p += 2;
for (i = 0 ; i < len; i++, idx = idx+2) {
hexbuf[i] = key_2char2num(p[idx], p[idx + 1]);
if (slen <= idx+2)
break;
}
return _TRUE;
}
int rtw_rson_set_property(_adapter *padapter, char *field, char *value)
{
struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
int num = 0;
if (_rtw_memcmp(field, (u8 *)"ver", 3) == _TRUE)
pdvobj->rson_data.ver = rtw_atoi(value);
else if (_rtw_memcmp(field, (u8 *)"id", 2) == _TRUE)
num = sscanf(value, "%08x", &(pdvobj->rson_data.id));
else if (_rtw_memcmp(field, (u8 *)"hc", 2) == _TRUE)
num = sscanf(value, "%hhu", &(pdvobj->rson_data.hopcnt));
else if (_rtw_memcmp(field, (u8 *)"cnt", 3) == _TRUE)
num = sscanf(value, "%hhu", &(pdvobj->rson_data.connectible));
else if (_rtw_memcmp(field, (u8 *)"loading", 2) == _TRUE)
num = sscanf(value, "%hhu", &(pdvobj->rson_data.loading));
else if (_rtw_memcmp(field, (u8 *)"res", 2) == _TRUE) {
str2hexbuf(value, pdvobj->rson_data.res, 16);
return 1;
} else
return _FALSE;
return num;
}
/*
return : TRUE -- competitor is taking advantage than condidate
FALSE -- we should continue keeping candidate
*/
int rtw_rson_choose(struct wlan_network **candidate, struct wlan_network *competitor)
{
s16 comp_score = 0, cand_score = 0;
struct rtw_rson_struct rson_cand, rson_comp;
if (is_match_bssid(competitor->network.MacAddress, rtw_rson_block_bssid, rtw_rson_block_bssid_idx) == _TRUE)
return _FALSE;
if ((competitor == NULL)
|| (rtw_get_rson_struct(&(competitor->network), &rson_comp) != _TRUE)
|| (rson_comp.id != CONFIG_RTW_REPEATER_SON_ID))
return _FALSE;
comp_score = rtw_cal_rson_score(&rson_comp, competitor->network.Rssi);
if (comp_score == RTW_RSON_SCORE_NOTCNNT)
return _FALSE;
if (*candidate == NULL)
return _TRUE;
if (rtw_get_rson_struct(&((*candidate)->network), &rson_cand) != _TRUE)
return _FALSE;
cand_score = rtw_cal_rson_score(&rson_cand, (*candidate)->network.Rssi);
RTW_INFO("%s: competitor_score=%d, candidate_score=%d\n", __func__, comp_score, cand_score);
if (comp_score - cand_score > RSON_SCORE_DIFF_TH)
return _TRUE;
return _FALSE;
}
inline u8 rtw_rson_varify_ie(u8 *p)
{
u8 *ptr = NULL;
u8 ver;
u32 id;
u8 hopcnt;
u8 allcnnt;
ptr = p + 2 + sizeof(RTW_RSON_OUI);
ver = *ptr;
/* for (ver == 1) */
if (ver != 1)
return _FALSE;
return _TRUE;
}
/*
Parsing RTK self-organization vendor IE
*/
int rtw_get_rson_struct(WLAN_BSSID_EX *bssid, struct rtw_rson_struct *rson_data)
{
sint limit = 0;
u32 len;
u8 *p;
if ((rson_data == NULL) || (bssid == NULL))
return -EINVAL;
/* Default */
rson_data->id = 0;
rson_data->ver = 0;
rson_data->hopcnt = 0;
rson_data->connectible = 0;
rson_data->loading = 0;
/* fake root */
if (is_match_bssid(bssid->MacAddress, rtw_rson_root_bssid, rtw_rson_root_bssid_idx) == _TRUE) {
rson_data->id = CONFIG_RTW_REPEATER_SON_ID;
rson_data->ver = RTW_RSON_VER;
rson_data->hopcnt = RTW_RSON_HC_ROOT;
rson_data->connectible = RTW_RSON_ALLOWCONNECT;
rson_data->loading = 0;
return _TRUE;
}
limit = bssid->IELength - _BEACON_IE_OFFSET_;
for (p = bssid->IEs + _BEACON_IE_OFFSET_; ; p += (len + 2)) {
p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &len, limit);
limit -= len;
if ((p == NULL) || (len == 0))
break;
if (p && (_rtw_memcmp(p + 2, RTW_RSON_OUI, sizeof(RTW_RSON_OUI)) == _TRUE)
&& rtw_rson_varify_ie(p)) {
p = p + 2 + sizeof(RTW_RSON_OUI);
rson_data->ver = *p;
/* for (ver == 1) */
p = p + 1;
rson_data->id = le32_to_cpup((__le32 *)p);
p = p + 4;
rson_data->hopcnt = *p;
p = p + 1;
rson_data->connectible = *p;
p = p + 1;
rson_data->loading = *p;
return _TRUE;
}
}
return -EBADMSG;
}
u32 rtw_rson_append_ie(_adapter *padapter, unsigned char *pframe, u32 *len)
{
u8 *ptr, *ori, ie_len = 0;
struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
/* static int iii = 0;*/
if ((!pdvobj) || (!pframe))
return 0;
ptr = ori = pframe;
*ptr++ = _VENDOR_SPECIFIC_IE_;
*ptr++ = ie_len = sizeof(RTW_RSON_OUI)+sizeof(pdvobj->rson_data);
_rtw_memcpy(ptr, RTW_RSON_OUI, sizeof(RTW_RSON_OUI));
ptr = ptr + sizeof(RTW_RSON_OUI);
*ptr++ = pdvobj->rson_data.ver;
*(s32 *)ptr = cpu_to_le32(pdvobj->rson_data.id);
ptr = ptr + sizeof(pdvobj->rson_data.id);
*ptr++ = pdvobj->rson_data.hopcnt;
*ptr++ = pdvobj->rson_data.connectible;
*ptr++ = pdvobj->rson_data.loading;
_rtw_memcpy(ptr, pdvobj->rson_data.res, sizeof(pdvobj->rson_data.res));
pframe = ptr;
/*
iii = iii % 20;
if (iii++ == 0)
RTW_INFO("%s : RTW RSON IE : %20ph\n", __func__, ori);
*/
*len += (ie_len+2);
return ie_len;
}
void rtw_rson_do_disconnect(_adapter *padapter)
{
struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
#ifndef CONFIG_RTW_REPEATER_SON_ROOT
pdvobj->rson_data.ver = RTW_RSON_VER;
pdvobj->rson_data.id = CONFIG_RTW_REPEATER_SON_ID;
pdvobj->rson_data.hopcnt = RTW_RSON_HC_NOTREADY;
pdvobj->rson_data.connectible = RTW_RSON_DENYCONNECT;
pdvobj->rson_data.loading = 0;
rtw_mi_tx_beacon_hdl(padapter);
#endif
}
void rtw_rson_join_done(_adapter *padapter)
{
struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
WLAN_BSSID_EX *cur_network = NULL;
struct rtw_rson_struct rson_data;
RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
if (!padapter->mlmepriv.cur_network_scanned)
return;
cur_network = &(padapter->mlmepriv.cur_network_scanned->network);
if (rtw_get_rson_struct(cur_network, &rson_data) != _TRUE) {
RTW_ERR("%s: try to join a improper network(%s)\n", __func__, cur_network->Ssid.Ssid);
return;
}
#ifndef CONFIG_RTW_REPEATER_SON_ROOT
/* update rson_data */
pdvobj->rson_data.ver = RTW_RSON_VER;
pdvobj->rson_data.id = rson_data.id;
pdvobj->rson_data.hopcnt = rson_data.hopcnt + 1;
pdvobj->rson_data.connectible = RTW_RSON_ALLOWCONNECT;
pdvobj->rson_data.loading = 0;
rtw_mi_tx_beacon_hdl(padapter);
#endif
}
int rtw_rson_isupdate_roamcan(struct mlme_priv *mlme
, struct wlan_network **candidate, struct wlan_network *competitor)
{
struct rtw_rson_struct rson_cand, rson_comp, rson_curr;
s16 comp_score, cand_score, curr_score;
if ((competitor == NULL)
|| (rtw_get_rson_struct(&(competitor->network), &rson_comp) != _TRUE)
|| (rson_comp.id != CONFIG_RTW_REPEATER_SON_ID))
return _FALSE;
if (is_match_bssid(competitor->network.MacAddress, rtw_rson_block_bssid, rtw_rson_block_bssid_idx) == _TRUE)
return _FALSE;
if ((!mlme->cur_network_scanned)
|| (mlme->cur_network_scanned == competitor)
|| (rtw_get_rson_struct(&(mlme->cur_network_scanned->network), &rson_curr)) != _TRUE)
return _FALSE;
if (rtw_get_passing_time_ms((u32)competitor->last_scanned) >= mlme->roam_scanr_exp_ms)
return _FALSE;
comp_score = rtw_cal_rson_score(&rson_comp, competitor->network.Rssi);
curr_score = rtw_cal_rson_score(&rson_curr, mlme->cur_network_scanned->network.Rssi);
if (comp_score - curr_score < RSON_SCORE_DIFF_TH)
return _FALSE;
if (*candidate == NULL)
return _TRUE;
if (rtw_get_rson_struct(&((*candidate)->network), &rson_cand) != _TRUE) {
RTW_ERR("%s : Unable to get rson_struct from candidate(%s -- " MAC_FMT")\n",
__func__, (*candidate)->network.Ssid.Ssid, MAC_ARG((*candidate)->network.MacAddress));
return _FALSE;
}
cand_score = rtw_cal_rson_score(&rson_cand, (*candidate)->network.Rssi);
RTW_DBG("comp_score=%d , cand_score=%d , curr_score=%d\n", comp_score, cand_score, curr_score);
if (cand_score < comp_score)
return _TRUE;
#if 0 /* Handle 11R protocol */
#ifdef CONFIG_RTW_80211R
if (rtw_chk_ft_flags(adapter, RTW_FT_SUPPORTED)) {
ptmp = rtw_get_ie(&competitor->network.IEs[12], _MDIE_, &mdie_len, competitor->network.IELength-12);
if (ptmp) {
if (!_rtw_memcmp(&pftpriv->mdid, ptmp+2, 2))
goto exit;
/*The candidate don't support over-the-DS*/
if (rtw_chk_ft_flags(adapter, RTW_FT_STA_OVER_DS_SUPPORTED)) {
if ((rtw_chk_ft_flags(adapter, RTW_FT_OVER_DS_SUPPORTED) && !(*(ptmp+4) & 0x01)) ||
(!rtw_chk_ft_flags(adapter, RTW_FT_OVER_DS_SUPPORTED) && (*(ptmp+4) & 0x01))) {
RTW_INFO("FT: ignore the candidate(" MAC_FMT ") for over-the-DS\n", MAC_ARG(competitor->network.MacAddress));
rtw_clr_ft_flags(adapter, RTW_FT_OVER_DS_SUPPORTED);
goto exit;
}
}
} else
goto exit;
}
#endif
#endif
return _FALSE;
}
void rtw_rson_show_survey_info(struct seq_file *m, _list *plist, _list *phead)
{
struct wlan_network *pnetwork = NULL;
struct rtw_rson_struct rson_data;
s16 rson_score;
u16 index = 0;
RTW_PRINT_SEL(m, "%5s %-17s %3s %5s %14s %10s %-3s %5s %32s\n", "index", "bssid", "ch", "id", "hop_cnt", "loading", "RSSI", "score", "ssid");
while (1) {
if (rtw_end_of_queue_search(phead, plist) == _TRUE)
break;
pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
if (!pnetwork)
break;
_rtw_memset(&rson_data, 0, sizeof(rson_data));
rson_score = 0;
if (rtw_get_rson_struct(&(pnetwork->network), &rson_data) == _TRUE)
rson_score = rtw_cal_rson_score(&rson_data, pnetwork->network.Rssi);
RTW_PRINT_SEL(m, "%5d "MAC_FMT" %3d 0x%08x %6d %10d %6d %6d %32s\n",
++index,
MAC_ARG(pnetwork->network.MacAddress),
pnetwork->network.Configuration.DSConfig,
rson_data.id,
rson_data.hopcnt,
rson_data.loading,
(int)pnetwork->network.Rssi,
rson_score,
pnetwork->network.Ssid.Ssid);
plist = get_next(plist);
}
}
/*
Description : As a AP role, We need to check the qualify of associating STA.
We also need to check if we are ready to be associated.
return : TRUE -- AP REJECT this STA
FALSE -- AP ACCEPT this STA
*/
u8 rtw_rson_ap_check_sta(_adapter *padapter, u8 *pframe, uint pkt_len, unsigned short ie_offset)
{
struct wlan_network *pnetwork = NULL;
struct rtw_rson_struct rson_target;
struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
int len = 0;
u8 ret = _FALSE;
u8 *p;
#ifndef CONFIG_RTW_REPEATER_SON_ROOT
_rtw_memset(&rson_target, 0, sizeof(rson_target));
for (p = pframe + WLAN_HDR_A3_LEN + ie_offset; ; p += (len + 2)) {
p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
if ((p == NULL) || (len == 0))
break;
if (p && (_rtw_memcmp(p + 2, RTW_RSON_OUI, sizeof(RTW_RSON_OUI)) == _TRUE)
&& rtw_rson_varify_ie(p)) {
p = p + 2 + sizeof(RTW_RSON_OUI);
rson_target.ver = *p;
/* for (ver == 1) */
p = p + 1;
rson_target.id = le32_to_cpup((__le32 *)p);
p = p + 4;
rson_target.hopcnt = *p;
p = p + 1;
rson_target.connectible = *p;
p = p + 1;
rson_target.loading = *p;
break;
}
}
if (rson_target.id == 0) /* Normal STA, not a RSON STA */
ret = _FALSE;
else if (rson_target.id != pdvobj->rson_data.id) {
ret = _TRUE;
RTW_INFO("%s : Reject AssoReq because RSON ID not match, STA=%08x, our=%08x\n",
__func__, rson_target.id, pdvobj->rson_data.id);
} else if ((pdvobj->rson_data.hopcnt == RTW_RSON_HC_NOTREADY)
|| (pdvobj->rson_data.connectible == RTW_RSON_DENYCONNECT)) {
ret = _TRUE;
RTW_INFO("%s : Reject AssoReq becuase our hopcnt=%d or connectbile=%d\n",
__func__, pdvobj->rson_data.hopcnt, pdvobj->rson_data.connectible);
}
#endif
return ret;
}
u8 rtw_rson_scan_wk_cmd(_adapter *padapter, int op)
{
struct cmd_obj *ph2c;
struct drvextra_cmd_parm *pdrvextra_cmd_parm;
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
u8 *extra_cmd_buf;
u8 res = _SUCCESS;
ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
if (ph2c == NULL) {
res = _FAIL;
goto exit;
}
pdrvextra_cmd_parm = (struct drvextra_cmd_parm *)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
if (pdrvextra_cmd_parm == NULL) {
rtw_mfree((u8 *)ph2c, sizeof(struct cmd_obj));
res = _FAIL;
goto exit;
}
pdrvextra_cmd_parm->ec_id = RSON_SCAN_WK_CID;
pdrvextra_cmd_parm->type = op;
pdrvextra_cmd_parm->size = 0;
pdrvextra_cmd_parm->pbuf = NULL;
init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
res = rtw_enqueue_cmd(pcmdpriv, ph2c);
exit:
return res;
}
void rtw_rson_scan_cmd_hdl(_adapter *padapter, int op)
{
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
u8 val8;
if (mlmeext_chk_scan_state(pmlmeext, SCAN_DISABLE) != _TRUE)
return;
if (op == RSON_SCAN_PROCESS) {
padapter->rtw_rson_scanstage = RSON_SCAN_PROCESS;
val8 = 0x1e;
rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &val8, _FALSE);
val8 = 1;
rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
issue_probereq(padapter, NULL, NULL);
/* stop rson_scan after 100ms */
_set_timer(&(pmlmeext->rson_scan_timer), 100);
} else if (op == RSON_SCAN_DISABLE) {
padapter->rtw_rson_scanstage = RSON_SCAN_DISABLE;
val8 = 0;
rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
val8 = 0xff;
rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &val8, _FALSE);
/* report_surveydone_event(padapter);*/
if (pmlmepriv->to_join == _TRUE) {
if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) != _TRUE) {
int s_ret;
set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
pmlmepriv->to_join = _FALSE;
s_ret = rtw_select_and_join_from_scanned_queue(pmlmepriv);
if (s_ret == _SUCCESS)
_set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);
else if (s_ret == 2) {
_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
rtw_indicate_connect(padapter);
} else {
RTW_INFO("try_to_join, but select scanning queue fail, to_roam:%d\n", rtw_to_roam(padapter));
if (rtw_to_roam(padapter) != 0) {
if (rtw_dec_to_roam(padapter) == 0) {
rtw_set_to_roam(padapter, 0);
#ifdef CONFIG_INTEL_WIDI
if (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_ROAMING) {
_rtw_memset(pmlmepriv->sa_ext, 0x00, L2SDTA_SERVICE_VE_LEN);
intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_WK, NULL, 0);
RTW_INFO("change to widi listen\n");
}
#endif /* CONFIG_INTEL_WIDI */
rtw_free_assoc_resources(padapter, _TRUE);
rtw_indicate_disconnect(padapter, 0, _FALSE);
} else
pmlmepriv->to_join = _TRUE;
} else
rtw_indicate_disconnect(padapter, 0, _FALSE);
_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
}
}
} else {
if (rtw_chk_roam_flags(padapter, RTW_ROAM_ACTIVE)) {
if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)
&& check_fwstate(pmlmepriv, _FW_LINKED)) {
if (rtw_select_roaming_candidate(pmlmepriv) == _SUCCESS) {
#ifdef CONFIG_RTW_80211R
if (rtw_chk_ft_flags(padapter, RTW_FT_OVER_DS_SUPPORTED)) {
start_clnt_ft_action(adapter, (u8 *)pmlmepriv->roam_network->network.MacAddress);
} else {
/*wait a little time to retrieve packets buffered in the current ap while scan*/
_set_timer(&pmlmeext->ft_roam_timer, 30);
}
#else
receive_disconnect(padapter, pmlmepriv->cur_network.network.MacAddress
, WLAN_REASON_ACTIVE_ROAM, _FALSE);
#endif
}
}
}
issue_action_BSSCoexistPacket(padapter);
issue_action_BSSCoexistPacket(padapter);
issue_action_BSSCoexistPacket(padapter);
}
} else {
RTW_ERR("%s : improper parameter -- op = %d\n", __func__, op);
}
}
#endif /* CONFIG_RTW_REPEATER_SON */

130
core/rtw_sdio.c Normal file
View File

@ -0,0 +1,130 @@
/******************************************************************************
*
* Copyright(c) 2015 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#define _RTW_SDIO_C_
#include <drv_types.h> /* struct dvobj_priv and etc. */
#include <drv_types_sdio.h> /* RTW_SDIO_ADDR_CMD52_GEN */
/*
* Description:
* Use SDIO cmd52 or cmd53 to read/write data
*
* Parameters:
* d pointer of device object(struct dvobj_priv)
* addr SDIO address, 17 bits
* buf buffer for I/O
* len length
* write 0:read, 1:write
* cmd52 0:cmd52, 1:cmd53
*
* Return:
* _SUCCESS I/O ok.
* _FAIL I/O fail.
*/
static u8 sdio_io(struct dvobj_priv *d, u32 addr, void *buf, size_t len, u8 write, u8 cmd52)
{
u32 addr_drv; /* address with driver defined bit */
int err;
u8 retry = 0;
u8 stop_retry = _FALSE; /* flag for stopping retry or not */
if (rtw_is_surprise_removed(dvobj_get_primary_adapter(d))) {
RTW_ERR("%s: bSurpriseRemoved, skip %s 0x%05x, %zu bytes\n",
__FUNCTION__, write?"write":"read", addr, len);
return _FAIL;
}
addr_drv = addr;
if (cmd52)
addr_drv = RTW_SDIO_ADDR_CMD52_GEN(addr_drv);
do {
if (write)
err = d->intf_ops->write(d, addr_drv, buf, len, 0);
else
err = d->intf_ops->read(d, addr_drv, buf, len, 0);
if (!err) {
if (retry) {
RTW_INFO("%s: Retry %s OK! addr=0x%05x %zu bytes, retry=%u,%u\n",
__FUNCTION__, write?"write":"read",
addr, len, retry, ATOMIC_READ(&d->continual_io_error));
RTW_INFO_DUMP("Data: ", buf, len);
}
rtw_reset_continual_io_error(d);
break;
}
RTW_ERR("%s: %s FAIL! error(%d) addr=0x%05x %zu bytes, retry=%u,%u\n",
__FUNCTION__, write?"write":"read", err, addr, len,
retry, ATOMIC_READ(&d->continual_io_error));
retry++;
stop_retry = rtw_inc_and_chk_continual_io_error(d);
if ((err == -1) || (stop_retry == _TRUE) || (retry > SD_IO_TRY_CNT)) {
/* critical error, unrecoverable */
RTW_ERR("%s: Fatal error! Set surprise remove flag ON! (retry=%u,%u)\n",
__FUNCTION__, retry, ATOMIC_READ(&d->continual_io_error));
rtw_set_surprise_removed(dvobj_get_primary_adapter(d));
return _FAIL;
}
/* WLAN IOREG or SDIO Local */
if ((addr & 0x10000) || !(addr & 0xE000)) {
RTW_WARN("%s: Retry %s addr=0x%05x %zu bytes, retry=%u,%u\n",
__FUNCTION__, write?"write":"read", addr, len,
retry, ATOMIC_READ(&d->continual_io_error));
continue;
}
return _FAIL;
} while (1);
return _SUCCESS;
}
u8 rtw_sdio_read_cmd52(struct dvobj_priv *d, u32 addr, void *buf, size_t len)
{
return sdio_io(d, addr, buf, len, 0, 1);
}
u8 rtw_sdio_read_cmd53(struct dvobj_priv *d, u32 addr, void *buf, size_t len)
{
return sdio_io(d, addr, buf, len, 0, 0);
}
u8 rtw_sdio_write_cmd52(struct dvobj_priv *d, u32 addr, void *buf, size_t len)
{
return sdio_io(d, addr, buf, len, 1, 1);
}
u8 rtw_sdio_write_cmd53(struct dvobj_priv *d, u32 addr, void *buf, size_t len)
{
return sdio_io(d, addr, buf, len, 1, 0);
}
u8 rtw_sdio_f0_read(struct dvobj_priv *d, u32 addr, void *buf, size_t len)
{
int err;
u8 ret;
ret = _SUCCESS;
addr = RTW_SDIO_ADDR_F0_GEN(addr);
err = d->intf_ops->read(d, addr, buf, len, 0);
if (err)
ret = _FAIL;
return ret;
}

3408
core/rtw_security.c Normal file

File diff suppressed because it is too large Load Diff

332
core/rtw_sreset.c Normal file
View File

@ -0,0 +1,332 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#include <drv_types.h>
#include <hal_data.h>
#include <rtw_sreset.h>
void sreset_init_value(_adapter *padapter)
{
#if defined(DBG_CONFIG_ERROR_DETECT)
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
struct sreset_priv *psrtpriv = &pHalData->srestpriv;
_rtw_mutex_init(&psrtpriv->silentreset_mutex);
psrtpriv->silent_reset_inprogress = _FALSE;
psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS;
psrtpriv->last_tx_time = 0;
psrtpriv->last_tx_complete_time = 0;
#endif
}
void sreset_reset_value(_adapter *padapter)
{
#if defined(DBG_CONFIG_ERROR_DETECT)
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
struct sreset_priv *psrtpriv = &pHalData->srestpriv;
psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS;
psrtpriv->last_tx_time = 0;
psrtpriv->last_tx_complete_time = 0;
#endif
}
u8 sreset_get_wifi_status(_adapter *padapter)
{
#if defined(DBG_CONFIG_ERROR_DETECT)
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
struct sreset_priv *psrtpriv = &pHalData->srestpriv;
u8 status = WIFI_STATUS_SUCCESS;
u32 val32 = 0;
_irqL irqL;
if (psrtpriv->silent_reset_inprogress == _TRUE)
return status;
val32 = rtw_read32(padapter, REG_TXDMA_STATUS);
if (val32 == 0xeaeaeaea)
psrtpriv->Wifi_Error_Status = WIFI_IF_NOT_EXIST;
else if (val32 != 0) {
RTW_INFO("txdmastatu(%x)\n", val32);
psrtpriv->Wifi_Error_Status = WIFI_MAC_TXDMA_ERROR;
}
if (WIFI_STATUS_SUCCESS != psrtpriv->Wifi_Error_Status) {
RTW_INFO("==>%s error_status(0x%x)\n", __FUNCTION__, psrtpriv->Wifi_Error_Status);
status = (psrtpriv->Wifi_Error_Status & (~(USB_READ_PORT_FAIL | USB_WRITE_PORT_FAIL)));
}
RTW_INFO("==> %s wifi_status(0x%x)\n", __FUNCTION__, status);
/* status restore */
psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS;
return status;
#else
return WIFI_STATUS_SUCCESS;
#endif
}
void sreset_set_wifi_error_status(_adapter *padapter, u32 status)
{
#if defined(DBG_CONFIG_ERROR_DETECT)
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
pHalData->srestpriv.Wifi_Error_Status = status;
#endif
}
void sreset_set_trigger_point(_adapter *padapter, s32 tgp)
{
#if defined(DBG_CONFIG_ERROR_DETECT)
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
pHalData->srestpriv.dbg_trigger_point = tgp;
#endif
}
bool sreset_inprogress(_adapter *padapter)
{
#if defined(DBG_CONFIG_ERROR_RESET)
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
return pHalData->srestpriv.silent_reset_inprogress;
#else
return _FALSE;
#endif
}
void sreset_restore_security_station(_adapter *padapter)
{
u8 EntryId = 0;
struct mlme_priv *mlmepriv = &padapter->mlmepriv;
struct sta_priv *pstapriv = &padapter->stapriv;
struct sta_info *psta;
struct security_priv *psecuritypriv = &(padapter->securitypriv);
struct mlme_ext_info *pmlmeinfo = &padapter->mlmeextpriv.mlmext_info;
{
u8 val8;
if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X) {
val8 = 0xcc;
#ifdef CONFIG_WAPI_SUPPORT
} else if (padapter->wapiInfo.bWapiEnable && pmlmeinfo->auth_algo == dot11AuthAlgrthm_WAPI) {
/* Disable TxUseDefaultKey, RxUseDefaultKey, RxBroadcastUseDefaultKey. */
val8 = 0x4c;
#endif
} else
val8 = 0xcf;
rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
}
if ((padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_) ||
(padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)) {
psta = rtw_get_stainfo(pstapriv, get_bssid(mlmepriv));
if (psta == NULL) {
/* DEBUG_ERR( ("Set wpa_set_encryption: Obtain Sta_info fail\n")); */
} else {
/* pairwise key */
rtw_setstakey_cmd(padapter, psta, UNICAST_KEY, _FALSE);
/* group key */
rtw_set_key(padapter, &padapter->securitypriv, padapter->securitypriv.dot118021XGrpKeyid, 0, _FALSE);
}
}
}
void sreset_restore_network_station(_adapter *padapter)
{
struct mlme_priv *mlmepriv = &padapter->mlmepriv;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
u8 doiqk = _FALSE;
#if 0
{
/* ======================================================= */
/* reset related register of Beacon control */
/* set MSR to nolink */
Set_MSR(padapter, _HW_STATE_NOLINK_);
/* reject all data frame */
rtw_write16(padapter, REG_RXFLTMAP2, 0x00);
/* reset TSF */
rtw_write8(padapter, REG_DUAL_TSF_RST, (BIT(0) | BIT(1)));
/* disable update TSF */
SetBcnCtrlReg(padapter, BIT(4), 0);
/* ======================================================= */
}
#endif
rtw_setopmode_cmd(padapter, Ndis802_11Infrastructure, RTW_CMDF_DIRECTLY);
{
u8 threshold;
#ifdef CONFIG_USB_HCI
/* TH=1 => means that invalidate usb rx aggregation */
/* TH=0 => means that validate usb rx aggregation, use init value. */
if (mlmepriv->htpriv.ht_option) {
if (padapter->registrypriv.wifi_spec == 1)
threshold = 1;
else
threshold = 0;
rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold));
} else {
threshold = 1;
rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold));
}
#endif
}
doiqk = _TRUE;
rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK , &doiqk);
set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
doiqk = _FALSE;
rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk);
/* disable dynamic functions, such as high power, DIG */
/*rtw_phydm_func_disable_all(padapter);*/
rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pmlmeinfo->network.MacAddress);
{
u8 join_type = 0;
rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
rtw_hal_rcr_set_chk_bssid(padapter, MLME_STA_CONNECTING);
}
Set_MSR(padapter, (pmlmeinfo->state & 0x3));
mlmeext_joinbss_event_callback(padapter, 1);
/* restore Sequence No. */
rtw_hal_set_hwreg(padapter, HW_VAR_RESTORE_HW_SEQ, 0);
sreset_restore_security_station(padapter);
}
void sreset_restore_network_status(_adapter *padapter)
{
struct mlme_priv *mlmepriv = &padapter->mlmepriv;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
if (check_fwstate(mlmepriv, WIFI_STATION_STATE)) {
RTW_INFO(FUNC_ADPT_FMT" fwstate:0x%08x - WIFI_STATION_STATE\n", FUNC_ADPT_ARG(padapter), get_fwstate(mlmepriv));
sreset_restore_network_station(padapter);
} else if (MLME_IS_AP(padapter) || MLME_IS_MESH(padapter)) {
RTW_INFO(FUNC_ADPT_FMT" %s\n", FUNC_ADPT_ARG(padapter), MLME_IS_AP(padapter) ? "AP" : "MESH");
rtw_ap_restore_network(padapter);
} else if (check_fwstate(mlmepriv, WIFI_ADHOC_STATE))
RTW_INFO(FUNC_ADPT_FMT" fwstate:0x%08x - WIFI_ADHOC_STATE\n", FUNC_ADPT_ARG(padapter), get_fwstate(mlmepriv));
else
RTW_INFO(FUNC_ADPT_FMT" fwstate:0x%08x - ???\n", FUNC_ADPT_ARG(padapter), get_fwstate(mlmepriv));
}
void sreset_stop_adapter(_adapter *padapter)
{
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
if (padapter == NULL)
return;
RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
rtw_netif_stop_queue(padapter->pnetdev);
rtw_cancel_all_timer(padapter);
/* TODO: OS and HCI independent */
#if defined(PLATFORM_LINUX) && defined(CONFIG_USB_HCI)
tasklet_kill(&pxmitpriv->xmit_tasklet);
#endif
if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
rtw_scan_abort(padapter);
if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
rtw_set_to_roam(padapter, 0);
rtw_join_timeout_handler(padapter);
}
}
void sreset_start_adapter(_adapter *padapter)
{
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
if (padapter == NULL)
return;
RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
if (check_fwstate(pmlmepriv, _FW_LINKED))
sreset_restore_network_status(padapter);
/* TODO: OS and HCI independent */
#if defined(PLATFORM_LINUX) && defined(CONFIG_USB_HCI)
tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
#endif
if (is_primary_adapter(padapter))
_set_timer(&adapter_to_dvobj(padapter)->dynamic_chk_timer, 2000);
rtw_netif_wake_queue(padapter->pnetdev);
}
void sreset_reset(_adapter *padapter)
{
#ifdef DBG_CONFIG_ERROR_RESET
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
struct sreset_priv *psrtpriv = &pHalData->srestpriv;
struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
_irqL irqL;
systime start = rtw_get_current_time();
struct dvobj_priv *psdpriv = padapter->dvobj;
struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
RTW_INFO("%s\n", __FUNCTION__);
psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS;
#ifdef CONFIG_LPS
rtw_set_ps_mode(padapter, PS_MODE_ACTIVE, 0, 0, "SRESET");
#endif/* #ifdef CONFIG_LPS */
_enter_pwrlock(&pwrpriv->lock);
psrtpriv->silent_reset_inprogress = _TRUE;
pwrpriv->change_rfpwrstate = rf_off;
rtw_mi_sreset_adapter_hdl(padapter, _FALSE);/*sreset_stop_adapter*/
#ifdef CONFIG_IPS
_ips_enter(padapter);
_ips_leave(padapter);
#endif
rtw_mi_sreset_adapter_hdl(padapter, _TRUE);/*sreset_start_adapter*/
psrtpriv->silent_reset_inprogress = _FALSE;
_exit_pwrlock(&pwrpriv->lock);
RTW_INFO("%s done in %d ms\n", __FUNCTION__, rtw_get_passing_time_ms(start));
pdbgpriv->dbg_sreset_cnt++;
psrtpriv->self_dect_fw = _FALSE;
psrtpriv->rx_cnt = 0;
#endif
}

1298
core/rtw_sta_mgt.c Normal file

File diff suppressed because it is too large Load Diff

3501
core/rtw_tdls.c Normal file

File diff suppressed because it is too large Load Diff

1054
core/rtw_vht.c Normal file

File diff suppressed because it is too large Load Diff

1312
core/rtw_wapi.c Normal file

File diff suppressed because it is too large Load Diff

922
core/rtw_wapi_sms4.c Normal file
View File

@ -0,0 +1,922 @@
/******************************************************************************
*
* Copyright(c) 2016 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#ifdef CONFIG_WAPI_SUPPORT
#include <linux/unistd.h>
#include <linux/etherdevice.h>
#include <drv_types.h>
#include <rtw_wapi.h>
#ifdef CONFIG_WAPI_SW_SMS4
#define WAPI_LITTLE_ENDIAN
/* #define BIG_ENDIAN */
#define ENCRYPT 0
#define DECRYPT 1
/**********************************************************
**********************************************************/
const u8 Sbox[256] = {
0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05,
0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3, 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99,
0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62,
0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95, 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6,
0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba, 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8,
0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b, 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35,
0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87,
0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52, 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e,
0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5, 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1,
0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55, 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3,
0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60, 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f,
0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f, 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51,
0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f, 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8,
0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0,
0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e, 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84,
0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20, 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48
};
const u32 CK[32] = {
0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,
0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,
0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,
0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279
};
#define Rotl(_x, _y) (((_x) << (_y)) | ((_x) >> (32 - (_y))))
#define ByteSub(_A) (Sbox[(_A) >> 24 & 0xFF] << 24 | \
Sbox[(_A) >> 16 & 0xFF] << 16 | \
Sbox[(_A) >> 8 & 0xFF] << 8 | \
Sbox[(_A) & 0xFF])
#define L1(_B) ((_B) ^ Rotl(_B, 2) ^ Rotl(_B, 10) ^ Rotl(_B, 18) ^ Rotl(_B, 24))
#define L2(_B) ((_B) ^ Rotl(_B, 13) ^ Rotl(_B, 23))
static void
xor_block(void *dst, void *src1, void *src2)
/* 128-bit xor: *dst = *src1 xor *src2. Pointers must be 32-bit aligned */
{
((u32 *)dst)[0] = ((u32 *)src1)[0] ^ ((u32 *)src2)[0];
((u32 *)dst)[1] = ((u32 *)src1)[1] ^ ((u32 *)src2)[1];
((u32 *)dst)[2] = ((u32 *)src1)[2] ^ ((u32 *)src2)[2];
((u32 *)dst)[3] = ((u32 *)src1)[3] ^ ((u32 *)src2)[3];
}
void SMS4Crypt(u8 *Input, u8 *Output, u32 *rk)
{
u32 r, mid, x0, x1, x2, x3, *p;
p = (u32 *)Input;
x0 = p[0];
x1 = p[1];
x2 = p[2];
x3 = p[3];
#ifdef WAPI_LITTLE_ENDIAN
x0 = Rotl(x0, 16);
x0 = ((x0 & 0x00FF00FF) << 8) | ((x0 & 0xFF00FF00) >> 8);
x1 = Rotl(x1, 16);
x1 = ((x1 & 0x00FF00FF) << 8) | ((x1 & 0xFF00FF00) >> 8);
x2 = Rotl(x2, 16);
x2 = ((x2 & 0x00FF00FF) << 8) | ((x2 & 0xFF00FF00) >> 8);
x3 = Rotl(x3, 16);
x3 = ((x3 & 0x00FF00FF) << 8) | ((x3 & 0xFF00FF00) >> 8);
#endif
for (r = 0; r < 32; r += 4) {
mid = x1 ^ x2 ^ x3 ^ rk[r + 0];
mid = ByteSub(mid);
x0 ^= L1(mid);
mid = x2 ^ x3 ^ x0 ^ rk[r + 1];
mid = ByteSub(mid);
x1 ^= L1(mid);
mid = x3 ^ x0 ^ x1 ^ rk[r + 2];
mid = ByteSub(mid);
x2 ^= L1(mid);
mid = x0 ^ x1 ^ x2 ^ rk[r + 3];
mid = ByteSub(mid);
x3 ^= L1(mid);
}
#ifdef WAPI_LITTLE_ENDIAN
x0 = Rotl(x0, 16);
x0 = ((x0 & 0x00FF00FF) << 8) | ((x0 & 0xFF00FF00) >> 8);
x1 = Rotl(x1, 16);
x1 = ((x1 & 0x00FF00FF) << 8) | ((x1 & 0xFF00FF00) >> 8);
x2 = Rotl(x2, 16);
x2 = ((x2 & 0x00FF00FF) << 8) | ((x2 & 0xFF00FF00) >> 8);
x3 = Rotl(x3, 16);
x3 = ((x3 & 0x00FF00FF) << 8) | ((x3 & 0xFF00FF00) >> 8);
#endif
p = (u32 *)Output;
p[0] = x3;
p[1] = x2;
p[2] = x1;
p[3] = x0;
}
void SMS4KeyExt(u8 *Key, u32 *rk, u32 CryptFlag)
{
u32 r, mid, x0, x1, x2, x3, *p;
p = (u32 *)Key;
x0 = p[0];
x1 = p[1];
x2 = p[2];
x3 = p[3];
#ifdef WAPI_LITTLE_ENDIAN
x0 = Rotl(x0, 16);
x0 = ((x0 & 0xFF00FF) << 8) | ((x0 & 0xFF00FF00) >> 8);
x1 = Rotl(x1, 16);
x1 = ((x1 & 0xFF00FF) << 8) | ((x1 & 0xFF00FF00) >> 8);
x2 = Rotl(x2, 16);
x2 = ((x2 & 0xFF00FF) << 8) | ((x2 & 0xFF00FF00) >> 8);
x3 = Rotl(x3, 16);
x3 = ((x3 & 0xFF00FF) << 8) | ((x3 & 0xFF00FF00) >> 8);
#endif
x0 ^= 0xa3b1bac6;
x1 ^= 0x56aa3350;
x2 ^= 0x677d9197;
x3 ^= 0xb27022dc;
for (r = 0; r < 32; r += 4) {
mid = x1 ^ x2 ^ x3 ^ CK[r + 0];
mid = ByteSub(mid);
rk[r + 0] = x0 ^= L2(mid);
mid = x2 ^ x3 ^ x0 ^ CK[r + 1];
mid = ByteSub(mid);
rk[r + 1] = x1 ^= L2(mid);
mid = x3 ^ x0 ^ x1 ^ CK[r + 2];
mid = ByteSub(mid);
rk[r + 2] = x2 ^= L2(mid);
mid = x0 ^ x1 ^ x2 ^ CK[r + 3];
mid = ByteSub(mid);
rk[r + 3] = x3 ^= L2(mid);
}
if (CryptFlag == DECRYPT) {
for (r = 0; r < 16; r++)
mid = rk[r], rk[r] = rk[31 - r], rk[31 - r] = mid;
}
}
void WapiSMS4Cryption(u8 *Key, u8 *IV, u8 *Input, u16 InputLength,
u8 *Output, u16 *OutputLength, u32 CryptFlag)
{
u32 blockNum, i, j, rk[32];
u16 remainder;
u8 blockIn[16], blockOut[16], tempIV[16], k;
*OutputLength = 0;
remainder = InputLength & 0x0F;
blockNum = InputLength >> 4;
if (remainder != 0)
blockNum++;
else
remainder = 16;
for (k = 0; k < 16; k++)
tempIV[k] = IV[15 - k];
memcpy(blockIn, tempIV, 16);
SMS4KeyExt((u8 *)Key, rk, CryptFlag);
for (i = 0; i < blockNum - 1; i++) {
SMS4Crypt((u8 *)blockIn, blockOut, rk);
xor_block(&Output[i * 16], &Input[i * 16], blockOut);
memcpy(blockIn, blockOut, 16);
}
*OutputLength = i * 16;
SMS4Crypt((u8 *)blockIn, blockOut, rk);
for (j = 0; j < remainder; j++)
Output[i * 16 + j] = Input[i * 16 + j] ^ blockOut[j];
*OutputLength += remainder;
}
void WapiSMS4Encryption(u8 *Key, u8 *IV, u8 *Input, u16 InputLength,
u8 *Output, u16 *OutputLength)
{
WapiSMS4Cryption(Key, IV, Input, InputLength, Output, OutputLength, ENCRYPT);
}
void WapiSMS4Decryption(u8 *Key, u8 *IV, u8 *Input, u16 InputLength,
u8 *Output, u16 *OutputLength)
{
/* OFB mode: is also ENCRYPT flag */
WapiSMS4Cryption(Key, IV, Input, InputLength, Output, OutputLength, ENCRYPT);
}
void WapiSMS4CalculateMic(u8 *Key, u8 *IV, u8 *Input1, u8 Input1Length,
u8 *Input2, u16 Input2Length, u8 *Output, u8 *OutputLength)
{
u32 blockNum, i, remainder, rk[32];
u8 BlockIn[16], BlockOut[16], TempBlock[16], tempIV[16], k;
*OutputLength = 0;
remainder = Input1Length & 0x0F;
blockNum = Input1Length >> 4;
for (k = 0; k < 16; k++)
tempIV[k] = IV[15 - k];
memcpy(BlockIn, tempIV, 16);
SMS4KeyExt((u8 *)Key, rk, ENCRYPT);
SMS4Crypt((u8 *)BlockIn, BlockOut, rk);
for (i = 0; i < blockNum; i++) {
xor_block(BlockIn, (Input1 + i * 16), BlockOut);
SMS4Crypt((u8 *)BlockIn, BlockOut, rk);
}
if (remainder != 0) {
memset(TempBlock, 0, 16);
memcpy(TempBlock, (Input1 + blockNum * 16), remainder);
xor_block(BlockIn, TempBlock, BlockOut);
SMS4Crypt((u8 *)BlockIn, BlockOut, rk);
}
remainder = Input2Length & 0x0F;
blockNum = Input2Length >> 4;
for (i = 0; i < blockNum; i++) {
xor_block(BlockIn, (Input2 + i * 16), BlockOut);
SMS4Crypt((u8 *)BlockIn, BlockOut, rk);
}
if (remainder != 0) {
memset(TempBlock, 0, 16);
memcpy(TempBlock, (Input2 + blockNum * 16), remainder);
xor_block(BlockIn, TempBlock, BlockOut);
SMS4Crypt((u8 *)BlockIn, BlockOut, rk);
}
memcpy(Output, BlockOut, 16);
*OutputLength = 16;
}
void SecCalculateMicSMS4(
u8 KeyIdx,
u8 *MicKey,
u8 *pHeader,
u8 *pData,
u16 DataLen,
u8 *MicBuffer
)
{
#if 0
struct ieee80211_hdr_3addr_qos *header;
u8 TempBuf[34], TempLen = 32, MicLen, QosOffset, *IV;
u16 *pTemp, fc;
WAPI_TRACE(WAPI_TX | WAPI_RX, "=========>%s\n", __FUNCTION__);
header = (struct ieee80211_hdr_3addr_qos *)pHeader;
memset(TempBuf, 0, 34);
memcpy(TempBuf, pHeader, 2); /* FrameCtrl */
pTemp = (u16 *)TempBuf;
*pTemp &= 0xc78f; /* bit4,5,6,11,12,13 */
memcpy((TempBuf + 2), (pHeader + 4), 12); /* Addr1, Addr2 */
memcpy((TempBuf + 14), (pHeader + 22), 2); /* SeqCtrl */
pTemp = (u16 *)(TempBuf + 14);
*pTemp &= 0x000f;
memcpy((TempBuf + 16), (pHeader + 16), 6); /* Addr3 */
fc = le16_to_cpu(header->frame_ctl);
if (GetFrDs((u16 *)&fc) && GetToDs((u16 *)&fc)) {
memcpy((TempBuf + 22), (pHeader + 24), 6);
QosOffset = 30;
} else {
memset((TempBuf + 22), 0, 6);
QosOffset = 24;
}
if ((fc & 0x0088) == 0x0088) {
memcpy((TempBuf + 28), (pHeader + QosOffset), 2);
TempLen += 2;
/* IV = pHeader + QosOffset + 2 + SNAP_SIZE + sizeof(u16) + 2; */
IV = pHeader + QosOffset + 2 + 2;
} else {
IV = pHeader + QosOffset + 2;
/* IV = pHeader + QosOffset + SNAP_SIZE + sizeof(u16) + 2; */
}
TempBuf[TempLen - 1] = (u8)(DataLen & 0xff);
TempBuf[TempLen - 2] = (u8)((DataLen & 0xff00) >> 8);
TempBuf[TempLen - 4] = KeyIdx;
WAPI_DATA(WAPI_TX, "CalculateMic - KEY", MicKey, 16);
WAPI_DATA(WAPI_TX, "CalculateMic - IV", IV, 16);
WAPI_DATA(WAPI_TX, "CalculateMic - TempBuf", TempBuf, TempLen);
WAPI_DATA(WAPI_TX, "CalculateMic - pData", pData, DataLen);
WapiSMS4CalculateMic(MicKey, IV, TempBuf, TempLen,
pData, DataLen, MicBuffer, &MicLen);
if (MicLen != 16)
WAPI_TRACE(WAPI_ERR, "%s: MIC Length Error!!\n", __FUNCTION__);
WAPI_TRACE(WAPI_TX | WAPI_RX, "<=========%s\n", __FUNCTION__);
#endif
}
/* AddCount: 1 or 2.
* If overflow, return 1,
* else return 0.
*/
u8 WapiIncreasePN(u8 *PN, u8 AddCount)
{
u8 i;
if (NULL == PN)
return 1;
/* YJ,test,091102 */
/*
if(AddCount == 2){
RTW_INFO("############################%s(): PN[0]=0x%x\n", __FUNCTION__, PN[0]);
if(PN[0] == 0x48){
PN[0] += AddCount;
return 1;
}else{
PN[0] += AddCount;
return 0;
}
}
*/
/* YJ,test,091102,end */
for (i = 0; i < 16; i++) {
if (PN[i] + AddCount <= 0xff) {
PN[i] += AddCount;
return 0;
} else {
PN[i] += AddCount;
AddCount = 1;
}
}
return 1;
}
void WapiGetLastRxUnicastPNForQoSData(
u8 UserPriority,
PRT_WAPI_STA_INFO pWapiStaInfo,
u8 *PNOut
)
{
WAPI_TRACE(WAPI_RX, "===========> %s\n", __FUNCTION__);
switch (UserPriority) {
case 0:
case 3:
memcpy(PNOut, pWapiStaInfo->lastRxUnicastPNBEQueue, 16);
break;
case 1:
case 2:
memcpy(PNOut, pWapiStaInfo->lastRxUnicastPNBKQueue, 16);
break;
case 4:
case 5:
memcpy(PNOut, pWapiStaInfo->lastRxUnicastPNVIQueue, 16);
break;
case 6:
case 7:
memcpy(PNOut, pWapiStaInfo->lastRxUnicastPNVOQueue, 16);
break;
default:
WAPI_TRACE(WAPI_ERR, "%s: Unknown TID\n", __FUNCTION__);
break;
}
WAPI_TRACE(WAPI_RX, "<=========== %s\n", __FUNCTION__);
}
void WapiSetLastRxUnicastPNForQoSData(
u8 UserPriority,
u8 *PNIn,
PRT_WAPI_STA_INFO pWapiStaInfo
)
{
WAPI_TRACE(WAPI_RX, "===========> %s\n", __FUNCTION__);
switch (UserPriority) {
case 0:
case 3:
memcpy(pWapiStaInfo->lastRxUnicastPNBEQueue, PNIn, 16);
break;
case 1:
case 2:
memcpy(pWapiStaInfo->lastRxUnicastPNBKQueue, PNIn, 16);
break;
case 4:
case 5:
memcpy(pWapiStaInfo->lastRxUnicastPNVIQueue, PNIn, 16);
break;
case 6:
case 7:
memcpy(pWapiStaInfo->lastRxUnicastPNVOQueue, PNIn, 16);
break;
default:
WAPI_TRACE(WAPI_ERR, "%s: Unknown TID\n", __FUNCTION__);
break;
}
WAPI_TRACE(WAPI_RX, "<=========== %s\n", __FUNCTION__);
}
/****************************************************************************
FALSE not RX-Reorder
TRUE do RX Reorder
add to support WAPI to N-mode
*****************************************************************************/
u8 WapiCheckPnInSwDecrypt(
_adapter *padapter,
struct sk_buff *pskb
)
{
u8 ret = false;
#if 0
struct ieee80211_hdr_3addr_qos *header;
u16 fc;
u8 *pDaddr, *pTaddr, *pRaddr;
header = (struct ieee80211_hdr_3addr_qos *)pskb->data;
pTaddr = header->addr2;
pRaddr = header->addr1;
fc = le16_to_cpu(header->frame_ctl);
if (GetToDs(&fc))
pDaddr = header->addr3;
else
pDaddr = header->addr1;
if ((_rtw_memcmp(pRaddr, padapter->pnetdev->dev_addr, ETH_ALEN) == 0)
&& !(pDaddr)
&& (GetFrameType(&fc) == WIFI_QOS_DATA_TYPE))
/* && ieee->pHTInfo->bCurrentHTSupport && */
/* ieee->pHTInfo->bCurRxReorderEnable) */
ret = false;
else
ret = true;
#endif
WAPI_TRACE(WAPI_RX, "%s: return %d\n", __FUNCTION__, ret);
return ret;
}
int SecSMS4HeaderFillIV(_adapter *padapter, u8 *pxmitframe)
{
struct pkt_attrib *pattrib = &((struct xmit_frame *)pxmitframe)->attrib;
u8 *frame = ((struct xmit_frame *)pxmitframe)->buf_addr + TXDESC_OFFSET;
u8 *pSecHeader = NULL, *pos = NULL, *pRA = NULL;
u8 bPNOverflow = false, bFindMatchPeer = false, hdr_len = 0;
PWLAN_HEADER_WAPI_EXTENSION pWapiExt = NULL;
PRT_WAPI_T pWapiInfo = &padapter->wapiInfo;
PRT_WAPI_STA_INFO pWapiSta = NULL;
int ret = 0;
WAPI_TRACE(WAPI_TX, "=========>%s\n", __FUNCTION__);
return ret;
#if 0
hdr_len = sMacHdrLng;
if (GetFrameType(pskb->data) == WIFI_QOS_DATA_TYPE)
hdr_len += 2;
/* hdr_len += SNAP_SIZE + sizeof(u16); */
pos = skb_push(pskb, padapter->wapiInfo.extra_prefix_len);
memmove(pos, pos + padapter->wapiInfo.extra_prefix_len, hdr_len);
pSecHeader = pskb->data + hdr_len;
pWapiExt = (PWLAN_HEADER_WAPI_EXTENSION)pSecHeader;
pRA = pskb->data + 4;
WAPI_DATA(WAPI_TX, "FillIV - Before Fill IV", pskb->data, pskb->len);
/* Address 1 is always receiver's address */
if (IS_MCAST(pRA)) {
if (!pWapiInfo->wapiTxMsk.bTxEnable) {
WAPI_TRACE(WAPI_ERR, "%s: bTxEnable = 0!!\n", __FUNCTION__);
return -2;
}
if (pWapiInfo->wapiTxMsk.keyId <= 1) {
pWapiExt->KeyIdx = pWapiInfo->wapiTxMsk.keyId;
pWapiExt->Reserved = 0;
bPNOverflow = WapiIncreasePN(pWapiInfo->lastTxMulticastPN, 1);
memcpy(pWapiExt->PN, pWapiInfo->lastTxMulticastPN, 16);
if (bPNOverflow) {
/* Update MSK Notification. */
WAPI_TRACE(WAPI_ERR, "===============>%s():multicast PN overflow\n", __FUNCTION__);
rtw_wapi_app_event_handler(padapter, NULL, 0, pRA, false, false, true, 0, false);
}
} else {
WAPI_TRACE(WAPI_ERR, "%s: Invalid Wapi Multicast KeyIdx!!\n", __FUNCTION__);
ret = -3;
}
} else {
list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
if (!memcmp(pWapiSta->PeerMacAddr, pRA, 6)) {
bFindMatchPeer = true;
break;
}
}
if (bFindMatchPeer) {
if ((!pWapiSta->wapiUskUpdate.bTxEnable) && (!pWapiSta->wapiUsk.bTxEnable)) {
WAPI_TRACE(WAPI_ERR, "%s: bTxEnable = 0!!\n", __FUNCTION__);
return -4;
}
if (pWapiSta->wapiUsk.keyId <= 1) {
if (pWapiSta->wapiUskUpdate.bTxEnable)
pWapiExt->KeyIdx = pWapiSta->wapiUskUpdate.keyId;
else
pWapiExt->KeyIdx = pWapiSta->wapiUsk.keyId;
pWapiExt->Reserved = 0;
bPNOverflow = WapiIncreasePN(pWapiSta->lastTxUnicastPN, 2);
memcpy(pWapiExt->PN, pWapiSta->lastTxUnicastPN, 16);
if (bPNOverflow) {
/* Update USK Notification. */
WAPI_TRACE(WAPI_ERR, "===============>%s():unicast PN overflow\n", __FUNCTION__);
rtw_wapi_app_event_handler(padapter, NULL, 0, pWapiSta->PeerMacAddr, false, true, false, 0, false);
}
} else {
WAPI_TRACE(WAPI_ERR, "%s: Invalid Wapi Unicast KeyIdx!!\n", __FUNCTION__);
ret = -5;
}
} else {
WAPI_TRACE(WAPI_ERR, "%s: Can not find Peer Sta "MAC_FMT"!!\n", __FUNCTION__, MAC_ARG(pRA));
ret = -6;
}
}
WAPI_DATA(WAPI_TX, "FillIV - After Fill IV", pskb->data, pskb->len);
WAPI_TRACE(WAPI_TX, "<=========%s\n", __FUNCTION__);
return ret;
#endif
}
/* WAPI SW Enc: must have done Coalesce! */
void SecSWSMS4Encryption(
_adapter *padapter,
u8 *pxmitframe
)
{
PRT_WAPI_T pWapiInfo = &padapter->wapiInfo;
PRT_WAPI_STA_INFO pWapiSta = NULL;
u8 *pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + TXDESC_SIZE;
struct pkt_attrib *pattrib = &((struct xmit_frame *)pxmitframe)->attrib;
u8 *SecPtr = NULL, *pRA, *pMicKey = NULL, *pDataKey = NULL, *pIV = NULL;
u8 IVOffset, DataOffset, bFindMatchPeer = false, KeyIdx = 0, MicBuffer[16];
u16 OutputLength;
WAPI_TRACE(WAPI_TX, "=========>%s\n", __FUNCTION__);
WAPI_TRACE(WAPI_TX, "hdrlen: %d\n", pattrib->hdrlen);
return;
DataOffset = pattrib->hdrlen + pattrib->iv_len;
pRA = pframe + 4;
if (IS_MCAST(pRA)) {
KeyIdx = pWapiInfo->wapiTxMsk.keyId;
pIV = pWapiInfo->lastTxMulticastPN;
pMicKey = pWapiInfo->wapiTxMsk.micKey;
pDataKey = pWapiInfo->wapiTxMsk.dataKey;
} else {
if (!list_empty(&(pWapiInfo->wapiSTAUsedList))) {
list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
if (0 == memcmp(pWapiSta->PeerMacAddr, pRA, 6)) {
bFindMatchPeer = true;
break;
}
}
if (bFindMatchPeer) {
if (pWapiSta->wapiUskUpdate.bTxEnable) {
KeyIdx = pWapiSta->wapiUskUpdate.keyId;
WAPI_TRACE(WAPI_TX, "%s(): Use update USK!! KeyIdx=%d\n", __FUNCTION__, KeyIdx);
pIV = pWapiSta->lastTxUnicastPN;
pMicKey = pWapiSta->wapiUskUpdate.micKey;
pDataKey = pWapiSta->wapiUskUpdate.dataKey;
} else {
KeyIdx = pWapiSta->wapiUsk.keyId;
WAPI_TRACE(WAPI_TX, "%s(): Use USK!! KeyIdx=%d\n", __FUNCTION__, KeyIdx);
pIV = pWapiSta->lastTxUnicastPN;
pMicKey = pWapiSta->wapiUsk.micKey;
pDataKey = pWapiSta->wapiUsk.dataKey;
}
} else {
WAPI_TRACE(WAPI_ERR, "%s: Can not find Peer Sta!!\n", __FUNCTION__);
return;
}
} else {
WAPI_TRACE(WAPI_ERR, "%s: wapiSTAUsedList is empty!!\n", __FUNCTION__);
return;
}
}
SecPtr = pframe;
SecCalculateMicSMS4(KeyIdx, pMicKey, SecPtr, (SecPtr + DataOffset), pattrib->pktlen, MicBuffer);
WAPI_DATA(WAPI_TX, "Encryption - MIC", MicBuffer, padapter->wapiInfo.extra_postfix_len);
memcpy(pframe + pattrib->hdrlen + pattrib->iv_len + pattrib->pktlen - pattrib->icv_len,
(u8 *)MicBuffer,
padapter->wapiInfo.extra_postfix_len
);
WapiSMS4Encryption(pDataKey, pIV, (SecPtr + DataOffset), pattrib->pktlen + pattrib->icv_len, (SecPtr + DataOffset), &OutputLength);
WAPI_DATA(WAPI_TX, "Encryption - After SMS4 encryption", pframe, pattrib->hdrlen + pattrib->iv_len + pattrib->pktlen);
WAPI_TRACE(WAPI_TX, "<=========%s\n", __FUNCTION__);
}
u8 SecSWSMS4Decryption(
_adapter *padapter,
u8 *precv_frame,
struct recv_priv *precv_priv
)
{
PRT_WAPI_T pWapiInfo = &padapter->wapiInfo;
struct recv_frame_hdr *precv_hdr;
PRT_WAPI_STA_INFO pWapiSta = NULL;
u8 IVOffset, DataOffset, bFindMatchPeer = false, bUseUpdatedKey = false;
u8 KeyIdx, MicBuffer[16], lastRxPNforQoS[16];
u8 *pRA, *pTA, *pMicKey, *pDataKey, *pLastRxPN, *pRecvPN, *pSecData, *pRecvMic, *pos;
u8 TID = 0;
u16 OutputLength, DataLen;
u8 bQosData;
struct sk_buff *pskb;
WAPI_TRACE(WAPI_RX, "=========>%s\n", __FUNCTION__);
return 0;
precv_hdr = &((union recv_frame *)precv_frame)->u.hdr;
pskb = (struct sk_buff *)(precv_hdr->rx_data);
precv_hdr->bWapiCheckPNInDecrypt = WapiCheckPnInSwDecrypt(padapter, pskb);
WAPI_TRACE(WAPI_RX, "=========>%s: check PN %d\n", __FUNCTION__, precv_hdr->bWapiCheckPNInDecrypt);
WAPI_DATA(WAPI_RX, "Decryption - Before decryption", pskb->data, pskb->len);
IVOffset = sMacHdrLng;
bQosData = GetFrameType(pskb->data) == WIFI_QOS_DATA_TYPE;
if (bQosData)
IVOffset += 2;
/* if(GetHTC()) */
/* IVOffset += 4; */
/* IVOffset += SNAP_SIZE + sizeof(u16); */
DataOffset = IVOffset + padapter->wapiInfo.extra_prefix_len;
pRA = pskb->data + 4;
pTA = pskb->data + 10;
KeyIdx = *(pskb->data + IVOffset);
pRecvPN = pskb->data + IVOffset + 2;
pSecData = pskb->data + DataOffset;
DataLen = pskb->len - DataOffset;
pRecvMic = pskb->data + pskb->len - padapter->wapiInfo.extra_postfix_len;
TID = GetTid(pskb->data);
if (!list_empty(&(pWapiInfo->wapiSTAUsedList))) {
list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
if (0 == memcmp(pWapiSta->PeerMacAddr, pTA, 6)) {
bFindMatchPeer = true;
break;
}
}
}
if (!bFindMatchPeer) {
WAPI_TRACE(WAPI_ERR, "%s: Can not find Peer Sta "MAC_FMT" for Key Info!!!\n", __FUNCTION__, MAC_ARG(pTA));
return false;
}
if (IS_MCAST(pRA)) {
WAPI_TRACE(WAPI_RX, "%s: Multicast decryption !!!\n", __FUNCTION__);
if (pWapiSta->wapiMsk.keyId == KeyIdx && pWapiSta->wapiMsk.bSet) {
pLastRxPN = pWapiSta->lastRxMulticastPN;
if (!WapiComparePN(pRecvPN, pLastRxPN)) {
WAPI_TRACE(WAPI_ERR, "%s: MSK PN is not larger than last, Dropped!!!\n", __FUNCTION__);
WAPI_DATA(WAPI_ERR, "pRecvPN:", pRecvPN, 16);
WAPI_DATA(WAPI_ERR, "pLastRxPN:", pLastRxPN, 16);
return false;
}
memcpy(pLastRxPN, pRecvPN, 16);
pMicKey = pWapiSta->wapiMsk.micKey;
pDataKey = pWapiSta->wapiMsk.dataKey;
} else if (pWapiSta->wapiMskUpdate.keyId == KeyIdx && pWapiSta->wapiMskUpdate.bSet) {
WAPI_TRACE(WAPI_RX, "%s: Use Updated MSK for Decryption !!!\n", __FUNCTION__);
bUseUpdatedKey = true;
memcpy(pWapiSta->lastRxMulticastPN, pRecvPN, 16);
pMicKey = pWapiSta->wapiMskUpdate.micKey;
pDataKey = pWapiSta->wapiMskUpdate.dataKey;
} else {
WAPI_TRACE(WAPI_ERR, "%s: Can not find MSK with matched KeyIdx(%d), Dropped !!!\n", __FUNCTION__, KeyIdx);
return false;
}
} else {
WAPI_TRACE(WAPI_RX, "%s: Unicast decryption !!!\n", __FUNCTION__);
if (pWapiSta->wapiUsk.keyId == KeyIdx && pWapiSta->wapiUsk.bSet) {
WAPI_TRACE(WAPI_RX, "%s: Use USK for Decryption!!!\n", __FUNCTION__);
if (precv_hdr->bWapiCheckPNInDecrypt) {
if (GetFrameType(pskb->data) == WIFI_QOS_DATA_TYPE) {
WapiGetLastRxUnicastPNForQoSData(TID, pWapiSta, lastRxPNforQoS);
pLastRxPN = lastRxPNforQoS;
} else
pLastRxPN = pWapiSta->lastRxUnicastPN;
if (!WapiComparePN(pRecvPN, pLastRxPN))
return false;
if (bQosData)
WapiSetLastRxUnicastPNForQoSData(TID, pRecvPN, pWapiSta);
else
memcpy(pWapiSta->lastRxUnicastPN, pRecvPN, 16);
} else
memcpy(precv_hdr->WapiTempPN, pRecvPN, 16);
if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE)) {
if ((pRecvPN[0] & 0x1) == 0) {
WAPI_TRACE(WAPI_ERR, "%s: Rx USK PN is not odd when Infra STA mode, Dropped !!!\n", __FUNCTION__);
return false;
}
}
pMicKey = pWapiSta->wapiUsk.micKey;
pDataKey = pWapiSta->wapiUsk.dataKey;
} else if (pWapiSta->wapiUskUpdate.keyId == KeyIdx && pWapiSta->wapiUskUpdate.bSet) {
WAPI_TRACE(WAPI_RX, "%s: Use Updated USK for Decryption!!!\n", __FUNCTION__);
if (pWapiSta->bAuthenticatorInUpdata)
bUseUpdatedKey = true;
else
bUseUpdatedKey = false;
if (bQosData)
WapiSetLastRxUnicastPNForQoSData(TID, pRecvPN, pWapiSta);
else
memcpy(pWapiSta->lastRxUnicastPN, pRecvPN, 16);
pMicKey = pWapiSta->wapiUskUpdate.micKey;
pDataKey = pWapiSta->wapiUskUpdate.dataKey;
} else {
WAPI_TRACE(WAPI_ERR, "%s: No valid USK!!!KeyIdx=%d pWapiSta->wapiUsk.keyId=%d pWapiSta->wapiUskUpdate.keyId=%d\n", __FUNCTION__, KeyIdx, pWapiSta->wapiUsk.keyId,
pWapiSta->wapiUskUpdate.keyId);
/* dump_buf(pskb->data,pskb->len); */
return false;
}
}
WAPI_DATA(WAPI_RX, "Decryption - DataKey", pDataKey, 16);
WAPI_DATA(WAPI_RX, "Decryption - IV", pRecvPN, 16);
WapiSMS4Decryption(pDataKey, pRecvPN, pSecData, DataLen, pSecData, &OutputLength);
if (OutputLength != DataLen)
WAPI_TRACE(WAPI_ERR, "%s: Output Length Error!!!!\n", __FUNCTION__);
WAPI_DATA(WAPI_RX, "Decryption - After decryption", pskb->data, pskb->len);
DataLen -= padapter->wapiInfo.extra_postfix_len;
SecCalculateMicSMS4(KeyIdx, pMicKey, pskb->data, pSecData, DataLen, MicBuffer);
WAPI_DATA(WAPI_RX, "Decryption - MIC received", pRecvMic, SMS4_MIC_LEN);
WAPI_DATA(WAPI_RX, "Decryption - MIC calculated", MicBuffer, SMS4_MIC_LEN);
if (0 == memcmp(MicBuffer, pRecvMic, padapter->wapiInfo.extra_postfix_len)) {
WAPI_TRACE(WAPI_RX, "%s: Check MIC OK!!\n", __FUNCTION__);
if (bUseUpdatedKey) {
/* delete the old key */
if (IS_MCAST(pRA)) {
WAPI_TRACE(WAPI_API, "%s(): AE use new update MSK!!\n", __FUNCTION__);
pWapiSta->wapiMsk.keyId = pWapiSta->wapiMskUpdate.keyId;
memcpy(pWapiSta->wapiMsk.dataKey, pWapiSta->wapiMskUpdate.dataKey, 16);
memcpy(pWapiSta->wapiMsk.micKey, pWapiSta->wapiMskUpdate.micKey, 16);
pWapiSta->wapiMskUpdate.bTxEnable = pWapiSta->wapiMskUpdate.bSet = false;
} else {
WAPI_TRACE(WAPI_API, "%s(): AE use new update USK!!\n", __FUNCTION__);
pWapiSta->wapiUsk.keyId = pWapiSta->wapiUskUpdate.keyId;
memcpy(pWapiSta->wapiUsk.dataKey, pWapiSta->wapiUskUpdate.dataKey, 16);
memcpy(pWapiSta->wapiUsk.micKey, pWapiSta->wapiUskUpdate.micKey, 16);
pWapiSta->wapiUskUpdate.bTxEnable = pWapiSta->wapiUskUpdate.bSet = false;
}
}
} else {
WAPI_TRACE(WAPI_ERR, "%s: Check MIC Error, Dropped !!!!\n", __FUNCTION__);
return false;
}
pos = pskb->data;
memmove(pos + padapter->wapiInfo.extra_prefix_len, pos, IVOffset);
skb_pull(pskb, padapter->wapiInfo.extra_prefix_len);
WAPI_TRACE(WAPI_RX, "<=========%s\n", __FUNCTION__);
return true;
}
u32 rtw_sms4_encrypt(_adapter *padapter, u8 *pxmitframe)
{
u8 *pframe;
u32 res = _SUCCESS;
WAPI_TRACE(WAPI_TX, "=========>%s\n", __FUNCTION__);
if ((!padapter->WapiSupport) || (!padapter->wapiInfo.bWapiEnable)) {
WAPI_TRACE(WAPI_TX, "<========== %s, WAPI not supported or enabled!\n", __FUNCTION__);
return _FAIL;
}
if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL)
return _FAIL;
pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + TXDESC_OFFSET;
SecSWSMS4Encryption(padapter, pxmitframe);
WAPI_TRACE(WAPI_TX, "<=========%s\n", __FUNCTION__);
return res;
}
u32 rtw_sms4_decrypt(_adapter *padapter, u8 *precvframe)
{
u8 *pframe;
u32 res = _SUCCESS;
WAPI_TRACE(WAPI_RX, "=========>%s\n", __FUNCTION__);
if ((!padapter->WapiSupport) || (!padapter->wapiInfo.bWapiEnable)) {
WAPI_TRACE(WAPI_RX, "<========== %s, WAPI not supported or enabled!\n", __FUNCTION__);
return _FAIL;
}
/* drop packet when hw decrypt fail
* return tempraily */
return _FAIL;
/* pframe=(unsigned char *)((union recv_frame*)precvframe)->u.hdr.rx_data; */
if (false == SecSWSMS4Decryption(padapter, precvframe, &padapter->recvpriv)) {
WAPI_TRACE(WAPI_ERR, "%s():SMS4 decrypt frame error\n", __FUNCTION__);
return _FAIL;
}
WAPI_TRACE(WAPI_RX, "<=========%s\n", __FUNCTION__);
return res;
}
#else
u32 rtw_sms4_encrypt(_adapter *padapter, u8 *pxmitframe)
{
WAPI_TRACE(WAPI_TX, "=========>Dummy %s\n", __FUNCTION__);
WAPI_TRACE(WAPI_TX, "<=========Dummy %s\n", __FUNCTION__);
return _SUCCESS;
}
u32 rtw_sms4_decrypt(_adapter *padapter, u8 *precvframe)
{
WAPI_TRACE(WAPI_RX, "=========>Dummy %s\n", __FUNCTION__);
WAPI_TRACE(WAPI_RX, "<=========Dummy %s\n", __FUNCTION__);
return _SUCCESS;
}
#endif
#endif

4748
core/rtw_wlan_util.c Normal file

File diff suppressed because it is too large Load Diff

5815
core/rtw_xmit.c Normal file

File diff suppressed because it is too large Load Diff

4
debian/README.Debian vendored Normal file
View File

@ -0,0 +1,4 @@
realtek-rtl8188eus DKMS module for Debian
This package was automatically generated by the DKMS system,
for distribution on Debian based operating systems.

156
debian/changelog vendored Normal file
View File

@ -0,0 +1,156 @@
realtek-rtl8188eus-dkms (5.3.9~git20230921.3fae723-0kali1) kali-dev; urgency=medium
* New upstream version 5.3.9~git20230921.3fae723
* Refresh patches
-- Sophie Brun <sophie@offensive-security.com> Mon, 15 Jan 2024 14:53:09 +0100
realtek-rtl8188eus-dkms (5.3.9~git20230101.f8ead57-0kali2) kali-dev; urgency=medium
[ Steev Klimaszewski ]
* Override dkms autopkgtest
[ Sophie Brun ]
* Import a patch to build for 6.3
-- Sophie Brun <sophie@offensive-security.com> Wed, 05 Jul 2023 14:32:27 +0200
realtek-rtl8188eus-dkms (5.3.9~git20230101.f8ead57-0kali1) kali-dev; urgency=medium
[ Kali Janitor ]
* Set upstream metadata fields: Repository.
* Update standards version to 4.6.2, no changes needed.
[ Sophie Brun ]
* New upstream version 5.3.9~git20230101.f8ead57
* Refresh patches
* Add support for Linux Kernel 6.1
-- Sophie Brun <sophie@offensive-security.com> Tue, 21 Feb 2023 14:51:34 +0100
realtek-rtl8188eus-dkms (5.3.9~git20221105.dab6e02-0kali1) kali-dev; urgency=medium
[ Kali Janitor ]
* Set upstream metadata fields: Repository-Browse.
[ Sophie Brun ]
* New upstream version 5.3.9~git20221105.dab6e02
* Refresh patches
-- Sophie Brun <sophie@offensive-security.com> Thu, 10 Nov 2022 12:01:30 +0100
realtek-rtl8188eus-dkms (5.3.9~git20220829.4ba8e08-0kali1) kali-dev; urgency=medium
[ Arnaud Rebillout ]
* No more dh-exec (requires compat 13)
* Switch to dh-sequence-dkms
* Set PACKAGE_VERSION in override_dh_dkms
[ Kali Janitor ]
* Trim trailing whitespace.
* debian/copyright: use spaces rather than tabs to start continuation lines.
* Set upstream metadata fields: Bug-Database, Bug-Submit.
* Update standards version to 4.6.1, no changes needed.
[ Sophie Brun ]
* New upstream version 5.3.9~git20220829.4ba8e08
* Refresh patches
* Import upstream patch to fix the build with Linux 5.19
-- Sophie Brun <sophie@offensive-security.com> Thu, 06 Oct 2022 15:05:27 +0200
realtek-rtl8188eus-dkms (5.3.9~git20220319.0958f29-0kali3) kali-dev; urgency=medium
* Remove useless patch (we change version in debian/rules)
* Refresh patch
* Add a patch to fix the build with kernel 5.18
-- Sophie Brun <sophie@offensive-security.com> Tue, 21 Jun 2022 12:20:45 +0200
realtek-rtl8188eus-dkms (5.3.9~git20220319.0958f29-0kali2) kali-dev; urgency=medium
* Add a patch to fix build build with kernel 5.17
-- Sophie Brun <sophie@offensive-security.com> Wed, 18 May 2022 17:50:10 +0200
realtek-rtl8188eus-dkms (5.3.9~git20220319.0958f29-0kali1) kali-dev; urgency=medium
* New upstream version 5.3.9~git20220319.0958f29
* Refresh patches
-- Sophie Brun <sophie@offensive-security.com> Thu, 12 May 2022 11:02:51 +0200
realtek-rtl8188eus-dkms (5.3.9~git20210504.6146193-0kali2) kali-dev; urgency=medium
[ Ben Wilson ]
* Remove template comment and switch spaces to tabs
[ Sophie Brun ]
* Add a patch to fix the compilation with kernel 5.15
-- Sophie Brun <sophie@offensive-security.com> Tue, 14 Dec 2021 17:56:08 +0100
realtek-rtl8188eus-dkms (5.3.9~git20210504.6146193-0kali1) kali-dev; urgency=medium
* New upstream version 5.3.9~git20210504.6146193
* Refresh patches
-- Sophie Brun <sophie@offensive-security.com> Tue, 28 Sep 2021 11:00:05 +0200
realtek-rtl8188eus-dkms (5.3.9~git20210206.1e7145f-0kali2) kali-dev; urgency=medium
* Bump Standards-Version to 4.5.1
* Blacklist r8188eu
-- Sophie Brun <sophie@offensive-security.com> Tue, 13 Jul 2021 10:50:42 +0200
realtek-rtl8188eus-dkms (5.3.9~git20210206.1e7145f-0kali1) kali-dev; urgency=medium
* Update debian/watch
* New upstream version 5.3.9~git20210206.1e7145f
* Refresh patches
-- Sophie Brun <sophie@offensive-security.com> Wed, 14 Apr 2021 17:25:11 +0200
realtek-rtl8188eus-dkms (5.3.9~git20201227-0kali1) kali-dev; urgency=medium
* New upstream version 5.3.9~git20201227
* Refresh patches
-- Sophie Brun <sophie@offensive-security.com> Tue, 26 Jan 2021 17:04:18 +0100
realtek-rtl8188eus-dkms (5.3.9~git20200829-0kali2) kali-dev; urgency=medium
* Fix errors introduced in 5a7f22 (lintian-overrides)
-- Sophie Brun <sophie@offensive-security.com> Wed, 16 Sep 2020 15:54:13 +0200
realtek-rtl8188eus-dkms (5.3.9~git20200829-0kali1) kali-dev; urgency=medium
* New upstream version 5.3.9~git20200829
* Refresh patches
* Add comment in debian/copyright
* Bump Standards-Version to 4.5.0
* Add lintian-overrides for dh-exec-subst-unknown-variable
-- Sophie Brun <sophie@offensive-security.com> Wed, 16 Sep 2020 15:07:29 +0200
realtek-rtl8188eus-dkms (5.3.9~git20200710-0kali1) kali-dev; urgency=medium
* New upstream version 5.3.9~20200710
-- Sophie Brun <sophie@offensive-security.com> Fri, 10 Jul 2020 08:49:51 +0200
realtek-rtl8188eus-dkms (5.3.9~git20200316-0kali1) kali-dev; urgency=medium
* Configure git-buildpackage for Kali
* Add GitLab's CI configuration file
* New upstream version 5.3.9~git20200316
-- Sophie Brun <sophie@offensive-security.com> Thu, 14 May 2020 11:45:14 +0200
realtek-rtl8188eus-dkms (5.3.9~20191129-0kali1) kali-dev; urgency=medium
* Initial release (see 5842)
-- Sophie Brun <sophie@offensive-security.com> Tue, 17 Dec 2019 17:14:38 +0100

18
debian/control vendored Normal file
View File

@ -0,0 +1,18 @@
Source: realtek-rtl8188eus-dkms
Section: contrib/kernel
Priority: optional
Maintainer: Kali Developers <devel@kali.org>
Uploaders: Sophie Brun <sophie@offensive-security.com>
Build-Depends: debhelper-compat (= 13), dh-sequence-dkms
Standards-Version: 4.6.2
Homepage: https://github.com/aircrack-ng/rtl8188eus
Vcs-Browser: https://gitlab.com/kalilinux/packages/realtek-rtl8188eus-dkms
Vcs-Git: https://gitlab.com/kalilinux/packages/realtek-rtl8188eus-dkms.git
Package: realtek-rtl8188eus-dkms
Architecture: all
Depends: dkms (>= 1.95), ${misc:Depends}
Description: Realtek RTL8188EUS driver in DKMS format
This package provides the source code for RTL8188EUS Linux driver (with
monitor mode and frame injection) to be build with dkms. Kernel sources or
headers are required to compile this module.

34
debian/copyright vendored Normal file
View File

@ -0,0 +1,34 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: realtek-rtl8188eus-dkms
Source: https://github.com/aircrack-ng/rtl8188eus
Comment: dkms package built during installation
Files: *
Copyright: 2007 - 2017 Realtek Corporation.
License: GPL-2
Files: os_dep/linux/rhashtable.*
Copyright: 2015 Herbert Xu <herbert@gondor.apana.org.au>
2014-2015 Thomas Graf <tgraf@suug.ch>
2008-2014 Patrick McHardy <kaber@trash.net>
License: GPL-2
Files: debian/*
Copyright: 2019 Sophie Brun <sophie@offensive-security.com>
License: GPL-2
License: GPL-2
This package is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License version 2 as published
by the Free Software Foundation.
.
This package is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>
.
On Debian systems, the complete text of the GNU General
Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".

10
debian/gbp.conf vendored Normal file
View File

@ -0,0 +1,10 @@
[DEFAULT]
debian-branch = kali/master
debian-tag = kali/%(version)s
pristine-tar = True
[pq]
patch-numbers = False
[dch]
multimaint-merge = True

2
debian/kali-ci.yml vendored Normal file
View File

@ -0,0 +1,2 @@
include:
- https://gitlab.com/kalilinux/tools/kali-ci-pipeline/raw/master/recipes/kali.yml

View File

@ -0,0 +1,19 @@
From: Sophie Brun <sophie@offensive-security.com>
Date: Tue, 21 Feb 2023 14:49:29 +0100
Subject: Add Linux 6.1 build support
Origin: https://github.com/aircrack-ng/rtl8188eus/pull/226
Forwarded: not-needed
---
dkms.conf | 1 -
1 file changed, 1 deletion(-)
diff --git a/dkms.conf b/dkms.conf
index 2c60a99..d1d1dc8 100644
--- a/dkms.conf
+++ b/dkms.conf
@@ -7,4 +7,3 @@ PROCS_NUM=`nproc`
DEST_MODULE_LOCATION[0]="/updates"
MAKE="'make' -j$PROCS_NUM KVER=${kernelver} KSRC=/lib/modules/${kernelver}/build"
AUTOINSTALL="yes"
-REMAKE_INITRD=no

View File

@ -0,0 +1,25 @@
From: Sophie Brun <sophie@offensive-security.com>
Date: Wed, 18 May 2022 17:47:55 +0200
Subject: Build support with kernel v5.17
Origin: https://github.com/aircrack-ng/rtl8188eus/commit/13cc38399eb44f234a52dde5f94509e54a09c71f
Forwarded: not-needed
---
os_dep/linux/rtw_proc.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/os_dep/linux/rtw_proc.c b/os_dep/linux/rtw_proc.c
index 8b1a424..9bd4041 100644
--- a/os_dep/linux/rtw_proc.c
+++ b/os_dep/linux/rtw_proc.c
@@ -39,6 +39,10 @@ inline struct proc_dir_entry *get_rtw_drv_proc(void)
#define proc_get_parent_data(inode) PDE((inode))->parent->data
#endif
+#if(LINUX_VERSION_CODE >= KERNEL_VERSION(5, 17, 0))
+#define PDE_DATA(inode) pde_data(inode)
+#endif
+
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24))
#define get_proc_net proc_net
#else

2
debian/patches/series vendored Normal file
View File

@ -0,0 +1,2 @@
add-support-kernel-5.17.patch
add-linux-6.1-support.patch

2
debian/r8188eus-dkms.conf vendored Normal file
View File

@ -0,0 +1,2 @@
# blacklist the driver
blacklist r8188eu

1
debian/realtek-rtl8188eus-dkms.docs vendored Normal file
View File

@ -0,0 +1 @@
README.md

View File

@ -0,0 +1,2 @@
core hal include Kconfig Makefile os_dep platform usr/src/realtek-rtl8188eus-${env:DEB_VERSION_UPSTREAM}
debian/r8188eus-dkms.conf etc/modprobe.d

21
debian/rules vendored Executable file
View File

@ -0,0 +1,21 @@
#!/usr/bin/make -f
include /usr/share/dpkg/pkg-info.mk
export DEB_VERSION_UPSTREAM
%:
dh $@
override_dh_dkms:
# Force PACKAGE_VERSION to be DEB_VERSION_UPSTREAM
sed -i dkms.conf -e 's%^PACKAGE_VERSION=.*%PACKAGE_VERSION="$(DEB_VERSION_UPSTREAM)"%'
dh_dkms -- dkms.conf
execute_after_dh_fixperms:
find debian/realtek-rtl8188eus-dkms/usr/src -type f -exec chmod -x {} \;
# Nothing to configure, build or auto-install (all is done after
# installation using dkms)
override_dh_auto_configure:
override_dh_auto_build:
override_dh_auto_install:

22
debian/script-targz vendored Executable file
View File

@ -0,0 +1,22 @@
#!/bin/bash
set -e
if [ "$1" = '--upstream-version' ]; then
new_version="$2"
else
printf "Missing --upstream-version argument" 1>&2
exit 1
fi
DEB_SOURCE="$(dpkg-parsechangelog -SSource)"
default_branch="$(git remote show https://github.com/aircrack-ng/rtl8188eus.git | grep 'HEAD' | sed 's/.*: v//')"
version="$(echo ${new_version} | sed 's/~git.*//')"
# fails if the upstream default branch has changed and is no longer the
# version mentioned in debian/watch
if [ "${default_branch}" != "${version}" ]; then
exit 1
fi

1
debian/source/format vendored Normal file
View File

@ -0,0 +1 @@
3.0 (quilt)

2
debian/tests/control vendored Normal file
View File

@ -0,0 +1,2 @@
Test-Command: debian/tests/dkms-autopkgtest
Restrictions: needs-root allow-stderr

229
debian/tests/dkms-autopkgtest vendored Executable file
View File

@ -0,0 +1,229 @@
#!/bin/sh
# Common autopkgtest script for testing a dkms source package.
# Author: Martin Pitt <martin.pitt@ubuntu.com>
# Copyright: (C) 2014 Canonical Ltd.
set -eu
export DEBIAN_FRONTEND=noninteractive
result=0
summary=
crlf="
"
header_packages=
check_for_linux_headers() {
# Act only on the first run.
if [ -n "$header_packages" ]; then
return
fi
# Which Linux header packages are installed?
header_packages=$(dpkg-query -f '${Status} ${Package}\n' -W 'linux-headers-*' 2>/dev/null | sed -r -n 's/^install ok installed //p')
if [ -n "$header_packages" ]; then
echo "I: Using the following Linux header packages that were already installed:"
for p in $header_packages ; do
echo "I: $p"
done
return
fi
# Which Linux header packages could be installed?
# linux-doc is a dependency generated by autodep8 for autopkgtest-pkg-dkms
# install only linux-headers-* matching the source version of linux-doc
wanted_source_version=$(dpkg-query -f '${source:Version}' -W linux-doc 2>/dev/null || true)
candidates=$(apt-cache search --names-only '^linux-headers-' | awk '{print $1}' | grep -v -E -e '-common(-rt)?$' | grep -v cloud)
echo "I: No Linux header packages are installed."
echo "I: Installing all available ones from src:linux $wanted_source_version:"
for p in $candidates ; do
if [ -z "$wanted_source_version" ]; then
echo "I: $p"
header_packages="$header_packages $p"
continue
fi
source_versions=$(apt-cache show $p | perl -ne 'if (/^$/) { print $s || $v, "\n"; $s=$v=""; } $s=$1 if /^Source: .* \((.*)\)$/; $v=$1 if /^Version: (.*)$/;')
for sv in $source_versions ; do
if [ "$sv" = "$wanted_source_version" ]; then
echo "I: install $p"
header_packages="$header_packages $p"
continue 2
fi
done
echo "I: skip $p"
done
RC=0
apt-get install --no-install-recommends -yq $header_packages </dev/null 2>&1 || RC=$?
if [ "$RC" -ne 0 ]; then
echo "E: Linux headers failed to install." >&2
exit 1
fi
}
run_pkg() {
pkg="$1"
test -x /usr/bin/openssl || apt-get install --no-install-recommends -yq openssl </dev/null 2>&1
echo "I: Removing binary package $pkg, to get clean state."
apt-get purge -yq $pkg </dev/null 2>&1 >/dev/null || true
echo "I: Installing binary package $pkg"
RC=0
apt-get install --no-install-recommends -yq $pkg </dev/null 2>&1 || RC=$?
if [ "$RC" -ne 0 ]; then
echo "E: Package $pkg failed to install." >&2
result=1
return
fi
# Try and remove dkms to spot packages which miss a dkms dependency
echo "I: Checking for missing dkms dependency by trying to deinstall dkms"
dpkg --remove dkms || true
if ! dkms_conf=$(dpkg -L $pkg | grep '/usr/src' | grep '/dkms.conf$'); then
echo "I: Package $pkg has no dkms.conf, skipping."
return
fi
check_for_linux_headers
echo "I: Testing binary package $pkg"
dkms_pkg=$(bash -c ". $dkms_conf > /dev/null; echo \$PACKAGE_NAME" 2>/dev/null)
dkms_ver=$(bash -c ". $dkms_conf > /dev/null; echo \$PACKAGE_VERSION" 2>/dev/null)
build_depends=$(bash -c ". $dkms_conf > /dev/null; echo \$BUILD_DEPENDS" 2>/dev/null)
versioned_build_depends=
for bd in $build_depends
do
bdpath=$(ls -d /usr/src/${bd}-*)
versioned_build_depends="$versioned_build_depends ${bd}/${bdpath#/usr/src/${bd}-}"
done
for k in $(ls -dv /lib/modules/*/build)
do
test -d "$k" || continue
kver="${k%/build}"
kver="${kver#/lib/modules/}"
# If any linux-meta is in triggers, only test abistems that
# match triggers otherwise continue. This helps integration
# with adt-matrix which specifically requests test results
# against each individual linux-meta and tracks unique results
# per kernel abi.
abistem=$(echo $kver | sed 's/-[a-z]*$//')
case "${ADT_TEST_TRIGGERS-}" in
*linux-meta*)
case "$ADT_TEST_TRIGGERS" in
*"$abistem"*)
;;
*)
continue
;;
esac
esac
for bdv in $versioned_build_depends
do
echo "I: Trying to install build dependency $bdv for $kver"
dkms install "$bdv" -k "$kver" || test $? = 77
done
echo "I: Trying to build $dkms_pkg/$dkms_ver for $kver"
res=0
dkms build -m "$dkms_pkg" -v "$dkms_ver" -k "$kver" || res=$?
if [ "$res" = 77 ]; then
echo "I: $dkms_pkg/$dkms_ver is not supported on $kver (BUILD_EXCLUSIVE directive), skipping."
summary="${summary}I: SKIP $kver${crlf}"
continue
fi
if [ "$res" != 0 ]; then
echo "E: $dkms_pkg/$dkms_ver failed to build for $kver" >&2
makelog="/var/lib/dkms/$dkms_pkg/$dkms_ver/build/make.log"
echo "========== $makelog ==========" >&2
cat "$makelog" >&2 || true
echo "====================" >&2
summary="${summary}I: FAIL $kver${crlf}"
result=1
continue
fi
if ! dkms install --force -m "$dkms_pkg" -v "$dkms_ver" -k "$kver" ; then
echo "E: $dkms_pkg/$dkms_ver failed to install for $kver" >&2
summary="${summary}I: FAIL $kver${crlf}"
result=1
continue
fi
echo "I: Testing if $dkms_pkg modules are correctly installed."
dkmsstatus="$(dkms status $dkms_pkg -k $kver)"
echo "$dkmsstatus"
if [ -z "$dkmsstatus" ]; then
echo "E: dkms status output is empty!" >&2
summary="${summary}I: FAIL $kver${crlf}"
result=1
continue
fi
if ! echo "$dkmsstatus" | grep -q "installed$"; then
echo "E: not installed" >&2
summary="${summary}I: FAIL $kver${crlf}"
result=1
continue
fi
summary="${summary}I: PASS $kver${crlf}"
done
# collect build logs as artifacts
if [ -d /var/lib/dkms ]; then
(cd /var/lib/dkms; find $dkms_pkg -name "make.log" -print0 | xargs -r -0 tar cvz) > "${AUTOPKGTEST_ARTIFACTS:-.}/$pkg-make-logs.tar.gz"
fi
# skip modprobing for now; this fails too often (needs particular
# hardware/firmware/etc)
# for mod in $(awk -F '"' '/^BUILT_MODULE_NAME/ {print $2}' $dkms_conf); do
# echo "I: modprobe $mod"
# if ! modprobe $mod; then
# echo "E: Failed to modprobe module $mod" >&2
# exit 1
# else
# echo "I: $modname loaded"
# fi
# done
}
# Do not (fail to) build the modules upon linux-header-* and *-dkms package
# installation, which can cause apt-get to fail. We will do this later with
# improved error reporting.
# (This only works if the *-dkms package is not yet installed.)
touch /etc/dkms/no-autoinstall
pkg_list="$*"
if [ -z "$pkg_list" ]; then
test -x /usr/bin/grep-dctrl || apt-get install --no-install-recommends -yq dctrl-tools </dev/null 2>&1
pkg_list="$(grep-dctrl -FDepends -e '(^| )dkms' -o -FPackage -e '\-dkms' debian/control -sPackage -n)"
fi
for pkg in $pkg_list; do
# package might be arch: restriction or udeb etc.
if ! apt-cache show $pkg >/dev/null 2>&1; then
echo "I: Skipping unavailable package $pkg"
continue
fi
run_pkg $pkg
done
if [ -n "$summary" ]; then
echo "I: Summary:"
echo -n "$summary"
fi
rm -f /etc/dkms/no-autoinstall
exit $result
# vim: sw=4:ts=4:et

5
debian/upstream/metadata vendored Normal file
View File

@ -0,0 +1,5 @@
---
Bug-Database: https://github.com/aircrack-ng/rtl8188eus/issues
Bug-Submit: https://github.com/aircrack-ng/rtl8188eus/issues/new
Repository: https://github.com/aircrack-ng/rtl8188eus.git
Repository-Browse: https://github.com/aircrack-ng/rtl8188eus

9
debian/watch vendored Normal file
View File

@ -0,0 +1,9 @@
version=4
opts="mode=git, pretty=5.3.9~git%cd.%h, pgpmode=none" \
https://github.com/aircrack-ng/rtl8188eus.git \
HEAD debian debian/script-targz
# Use the following when upstream starts to tag releases:
#opts="filenamemangle=s%(?:.*?)?v?(\d[\d.]*)\.tar\.gz%realtek-rtl8188eus-dkms-$1.tar.gz%" \
# https://github.com/aircrack-ng/rtl8188eus/tags \
# (?:.*?/)?v?(\d[\d.]*)\.tar\.gz debian uupdate

23
dkms-install.sh Executable file
View File

@ -0,0 +1,23 @@
#!/bin/bash
if [[ $EUID -ne 0 ]]; then
echo "You must run this with superuser priviliges. Try \"sudo ./dkms-install.sh\"" 2>&1
exit 1
else
echo "About to run dkms install steps..."
fi
DRV_DIR=rtl8188eus
DRV_NAME=8188eu
DRV_VERSION=5.3.9
cp -r ../${DRV_DIR} /usr/src/${DRV_NAME}-${DRV_VERSION}
dkms add -m ${DRV_NAME} -v ${DRV_VERSION}
dkms build -m ${DRV_NAME} -v ${DRV_VERSION}
dkms install -m ${DRV_NAME} -v ${DRV_VERSION}
RESULT=$?
echo "Finished running dkms install steps."
exit $RESULT

24
dkms-remove.sh Executable file
View File

@ -0,0 +1,24 @@
#!/bin/bash
if [[ $EUID -ne 0 ]]; then
echo "You must run this with superuser priviliges. Try \"sudo ./dkms-remove.sh\"" 2>&1
exit 1
else
echo "About to run dkms removal steps..."
fi
DRV_DIR=rtl8188eus
DRV_NAME=8188eu
DRV_VERSION=5.3.9
dkms remove ${DRV_NAME}/${DRV_VERSION} --all
rm -rf /usr/src/${DRV_NAME}-${DRV_VERSION}
RESULT=$?
if [[ "$RESULT" != "0" ]]; then
echo "Error occurred while running dkms remove." 2>&1
else
echo "Finished running dkms removal steps."
fi
exit $RESULT

10
dkms.conf Normal file
View File

@ -0,0 +1,10 @@
PACKAGE_NAME="realtek-rtl8188eus"
PACKAGE_VERSION="5.3.9~20221105"
CLEAN="'make' clean"
BUILT_MODULE_NAME[0]=8188eu
PROCS_NUM=`nproc`
[ $PROCS_NUM -gt 16 ] && PROCS_NUM=16
DEST_MODULE_LOCATION[0]="/updates"
MAKE="'make' -j$PROCS_NUM KVER=${kernelver} KSRC=/lib/modules/${kernelver}/build"
AUTOINSTALL="yes"
REMAKE_INITRD=no

185
hal/HalPwrSeqCmd.c Normal file
View File

@ -0,0 +1,185 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
/*++
Copyright (c) Realtek Semiconductor Corp. All rights reserved.
Module Name:
HalPwrSeqCmd.c
Abstract:
Implement HW Power sequence configuration CMD handling routine for Realtek devices.
Major Change History:
When Who What
---------- --------------- -------------------------------
2011-10-26 Lucas Modify to be compatible with SD4-CE driver.
2011-07-07 Roger Create.
--*/
#include <HalPwrSeqCmd.h>
/*
* Description:
* This routine deal with the Power Configuration CMDs parsing for RTL8723/RTL8188E Series IC.
*
* Assumption:
* We should follow specific format which was released from HW SD.
*
* 2011.07.07, added by Roger.
* */
u8 HalPwrSeqCmdParsing(
PADAPTER padapter,
u8 CutVersion,
u8 FabVersion,
u8 InterfaceType,
WLAN_PWR_CFG PwrSeqCmd[])
{
WLAN_PWR_CFG PwrCfgCmd = {0};
u8 bPollingBit = _FALSE;
u8 bHWICSupport = _FALSE;
u32 AryIdx = 0;
u8 value = 0;
u32 offset = 0;
u8 flag = 0;
u32 pollingCount = 0; /* polling autoload done. */
u32 maxPollingCnt = 5000;
do {
PwrCfgCmd = PwrSeqCmd[AryIdx];
/* 2 Only Handle the command whose FAB, CUT, and Interface are matched */
if ((GET_PWR_CFG_FAB_MASK(PwrCfgCmd) & FabVersion) &&
(GET_PWR_CFG_CUT_MASK(PwrCfgCmd) & CutVersion) &&
(GET_PWR_CFG_INTF_MASK(PwrCfgCmd) & InterfaceType)) {
switch (GET_PWR_CFG_CMD(PwrCfgCmd)) {
case PWR_CMD_READ:
break;
case PWR_CMD_WRITE:
offset = GET_PWR_CFG_OFFSET(PwrCfgCmd);
#ifdef CONFIG_SDIO_HCI
/* */
/* <Roger_Notes> We should deal with interface specific address mapping for some interfaces, e.g., SDIO interface */
/* 2011.07.07. */
/* */
if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO) {
/* Read Back SDIO Local value */
value = SdioLocalCmd52Read1Byte(padapter, offset);
value &= ~(GET_PWR_CFG_MASK(PwrCfgCmd));
value |= (GET_PWR_CFG_VALUE(PwrCfgCmd) & GET_PWR_CFG_MASK(PwrCfgCmd));
/* Write Back SDIO Local value */
SdioLocalCmd52Write1Byte(padapter, offset, value);
} else
#endif
{
#ifdef CONFIG_GSPI_HCI
if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO)
offset = SPI_LOCAL_OFFSET | offset;
#endif
/* Read the value from system register */
value = rtw_read8(padapter, offset);
value = value & (~(GET_PWR_CFG_MASK(PwrCfgCmd)));
value = value | (GET_PWR_CFG_VALUE(PwrCfgCmd) & GET_PWR_CFG_MASK(PwrCfgCmd));
/* Write the value back to sytem register */
rtw_write8(padapter, offset, value);
}
break;
case PWR_CMD_POLLING:
bPollingBit = _FALSE;
offset = GET_PWR_CFG_OFFSET(PwrCfgCmd);
rtw_hal_get_hwreg(padapter, HW_VAR_PWR_CMD, &bHWICSupport);
if (bHWICSupport && offset == 0x06) {
flag = 0;
maxPollingCnt = 100000;
} else
maxPollingCnt = 5000;
#ifdef CONFIG_GSPI_HCI
if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO)
offset = SPI_LOCAL_OFFSET | offset;
#endif
do {
#ifdef CONFIG_SDIO_HCI
if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO)
value = SdioLocalCmd52Read1Byte(padapter, offset);
else
#endif
value = rtw_read8(padapter, offset);
value = value & GET_PWR_CFG_MASK(PwrCfgCmd);
if (value == (GET_PWR_CFG_VALUE(PwrCfgCmd) & GET_PWR_CFG_MASK(PwrCfgCmd)))
bPollingBit = _TRUE;
else
rtw_udelay_os(10);
if (pollingCount++ > maxPollingCnt) {
RTW_ERR("HalPwrSeqCmdParsing: Fail to polling Offset[%#x]=%02x\n", offset, value);
/* For PCIE + USB package poll power bit timeout issue only modify 8821AE and 8723BE */
if (bHWICSupport && offset == 0x06 && flag == 0) {
RTW_ERR("[WARNING] PCIE polling(0x%X) timeout(%d), Toggle 0x04[3] and try again.\n", offset, maxPollingCnt);
if (IS_HARDWARE_TYPE_8723DE(padapter))
PlatformEFIOWrite1Byte(padapter, 0x40, (PlatformEFIORead1Byte(padapter, 0x40)) & (~BIT3));
PlatformEFIOWrite1Byte(padapter, 0x04, PlatformEFIORead1Byte(padapter, 0x04) | BIT3);
PlatformEFIOWrite1Byte(padapter, 0x04, PlatformEFIORead1Byte(padapter, 0x04) & ~BIT3);
if (IS_HARDWARE_TYPE_8723DE(padapter))
PlatformEFIOWrite1Byte(padapter, 0x40, PlatformEFIORead1Byte(padapter, 0x40)|BIT3);
/* Retry Polling Process one more time */
pollingCount = 0;
flag = 1;
} else {
return _FALSE;
}
}
} while (!bPollingBit);
break;
case PWR_CMD_DELAY:
if (GET_PWR_CFG_VALUE(PwrCfgCmd) == PWRSEQ_DELAY_US)
rtw_udelay_os(GET_PWR_CFG_OFFSET(PwrCfgCmd));
else
rtw_udelay_os(GET_PWR_CFG_OFFSET(PwrCfgCmd) * 1000);
break;
case PWR_CMD_END:
/* When this command is parsed, end the process */
return _TRUE;
break;
default:
break;
}
}
AryIdx++;/* Add Array Index */
} while (1);
return _TRUE;
}

138
hal/efuse/efuse_mask.h Normal file
View File

@ -0,0 +1,138 @@
/******************************************************************************
*
* Copyright(c) 2016 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#if DEV_BUS_TYPE == RT_USB_INTERFACE
#if defined(CONFIG_RTL8188E)
#include "rtl8188e/HalEfuseMask8188E_USB.h"
#endif
#if defined(CONFIG_RTL8812A)
#include "rtl8812a/HalEfuseMask8812A_USB.h"
#endif
#if defined(CONFIG_RTL8821A)
#include "rtl8812a/HalEfuseMask8821A_USB.h"
#endif
#if defined(CONFIG_RTL8192E)
#include "rtl8192e/HalEfuseMask8192E_USB.h"
#endif
#if defined(CONFIG_RTL8723B)
#include "rtl8723b/HalEfuseMask8723B_USB.h"
#endif
#if defined(CONFIG_RTL8814A)
#include "rtl8814a/HalEfuseMask8814A_USB.h"
#endif
#if defined(CONFIG_RTL8703B)
#include "rtl8703b/HalEfuseMask8703B_USB.h"
#endif
#if defined(CONFIG_RTL8723D)
#include "rtl8723d/HalEfuseMask8723D_USB.h"
#endif
#if defined(CONFIG_RTL8188F)
#include "rtl8188f/HalEfuseMask8188F_USB.h"
#endif
#if defined(CONFIG_RTL8822B)
#include "rtl8822b/HalEfuseMask8822B_USB.h"
#endif
#if defined(CONFIG_RTL8821C)
#include "rtl8821c/HalEfuseMask8821C_USB.h"
#endif
#elif DEV_BUS_TYPE == RT_PCI_INTERFACE
#if defined(CONFIG_RTL8188E)
#include "rtl8188e/HalEfuseMask8188E_PCIE.h"
#endif
#if defined(CONFIG_RTL8812A)
#include "rtl8812a/HalEfuseMask8812A_PCIE.h"
#endif
#if defined(CONFIG_RTL8821A)
#include "rtl8812a/HalEfuseMask8821A_PCIE.h"
#endif
#if defined(CONFIG_RTL8192E)
#include "rtl8192e/HalEfuseMask8192E_PCIE.h"
#endif
#if defined(CONFIG_RTL8723B)
#include "rtl8723b/HalEfuseMask8723B_PCIE.h"
#endif
#if defined(CONFIG_RTL8814A)
#include "rtl8814a/HalEfuseMask8814A_PCIE.h"
#endif
#if defined(CONFIG_RTL8703B)
#include "rtl8703b/HalEfuseMask8703B_PCIE.h"
#endif
#if defined(CONFIG_RTL8822B)
#include "rtl8822b/HalEfuseMask8822B_PCIE.h"
#endif
#if defined(CONFIG_RTL8723D)
#include "rtl8723d/HalEfuseMask8723D_PCIE.h"
#endif
#if defined(CONFIG_RTL8821C)
#include "rtl8821c/HalEfuseMask8821C_PCIE.h"
#endif
#elif DEV_BUS_TYPE == RT_SDIO_INTERFACE
#if defined(CONFIG_RTL8723B)
#include "rtl8723b/HalEfuseMask8723B_SDIO.h"
#endif
#if defined(CONFIG_RTL8188E)
#include "rtl8188e/HalEfuseMask8188E_SDIO.h"
#endif
#if defined(CONFIG_RTL8703B)
#include "rtl8703b/HalEfuseMask8703B_SDIO.h"
#endif
#if defined(CONFIG_RTL8188F)
#include "rtl8188f/HalEfuseMask8188F_SDIO.h"
#endif
#if defined(CONFIG_RTL8723D)
#include "rtl8723d/HalEfuseMask8723D_SDIO.h"
#endif
#if defined(CONFIG_RTL8192E)
#include "rtl8192e/HalEfuseMask8192E_SDIO.h"
#endif
#if defined(CONFIG_RTL8821A)
#include "rtl8812a/HalEfuseMask8821A_SDIO.h"
#endif
#if defined(CONFIG_RTL8821C)
#include "rtl8821c/HalEfuseMask8821C_SDIO.h"
#endif
#if defined(CONFIG_RTL8822B)
#include "rtl8822b/HalEfuseMask8822B_SDIO.h"
#endif
#endif

View File

@ -0,0 +1,95 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
/* #include "Mp_Precomp.h" */
/* #include "../odm_precomp.h" */
#include <drv_types.h>
#include "HalEfuseMask8188E_USB.h"
/******************************************************************************
* MUSB.TXT
******************************************************************************/
u1Byte Array_MP_8188E_MUSB[] = {
0xFF,
0xF3,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x0F,
0xF1,
0xFF,
0xFF,
0xFF,
0x00,
0x00,
0x00,
0xF7,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
};
u2Byte
EFUSE_GetArrayLen_MP_8188E_MUSB(VOID)
{
return sizeof(Array_MP_8188E_MUSB) / sizeof(u1Byte);
}
VOID
EFUSE_GetMaskArray_MP_8188E_MUSB(
IN OUT pu1Byte Array
)
{
u2Byte len = EFUSE_GetArrayLen_MP_8188E_MUSB(), i = 0;
for (i = 0; i < len; ++i)
Array[i] = Array_MP_8188E_MUSB[i];
}
BOOLEAN
EFUSE_IsAddressMasked_MP_8188E_MUSB(
IN u2Byte Offset
)
{
int r = Offset / 16;
int c = (Offset % 16) / 2;
int result = 0;
if (c < 4) /* Upper double word */
result = (Array_MP_8188E_MUSB[r] & (0x10 << c));
else
result = (Array_MP_8188E_MUSB[r] & (0x01 << (c - 4)));
return (result > 0) ? 0 : 1;
}

View File

@ -0,0 +1,34 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
/******************************************************************************
* MUSB.TXT
******************************************************************************/
u2Byte
EFUSE_GetArrayLen_MP_8188E_MUSB(VOID);
VOID
EFUSE_GetMaskArray_MP_8188E_MUSB(
IN OUT pu1Byte Array
);
BOOLEAN
EFUSE_IsAddressMasked_MP_8188E_MUSB(/* TC: Test Chip, MP: MP Chip */
IN u2Byte Offset
);

5469
hal/hal_btcoex.c Normal file

File diff suppressed because it is too large Load Diff

204
hal/hal_btcoex_wifionly.c Normal file
View File

@ -0,0 +1,204 @@
/******************************************************************************
*
* Copyright(c) 2016 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#include <hal_btcoex_wifionly.h>
#if (CONFIG_BTCOEX_SUPPORT_WIFI_ONLY_CFG == 1)
#include "btc/mp_precomp.h"
struct wifi_only_cfg GLBtCoexistWifiOnly;
void halwifionly_write1byte(PVOID pwifionlyContext, u32 RegAddr, u8 Data)
{
struct wifi_only_cfg *pwifionlycfg = (struct wifi_only_cfg *)pwifionlyContext;
PADAPTER Adapter = pwifionlycfg->Adapter;
rtw_write8(Adapter, RegAddr, Data);
}
void halwifionly_write2byte(PVOID pwifionlyContext, u32 RegAddr, u16 Data)
{
struct wifi_only_cfg *pwifionlycfg = (struct wifi_only_cfg *)pwifionlyContext;
PADAPTER Adapter = pwifionlycfg->Adapter;
rtw_write16(Adapter, RegAddr, Data);
}
void halwifionly_write4byte(PVOID pwifionlyContext, u32 RegAddr, u32 Data)
{
struct wifi_only_cfg *pwifionlycfg = (struct wifi_only_cfg *)pwifionlyContext;
PADAPTER Adapter = pwifionlycfg->Adapter;
rtw_write32(Adapter, RegAddr, Data);
}
u8 halwifionly_read1byte(PVOID pwifionlyContext, u32 RegAddr)
{
struct wifi_only_cfg *pwifionlycfg = (struct wifi_only_cfg *)pwifionlyContext;
PADAPTER Adapter = pwifionlycfg->Adapter;
return rtw_read8(Adapter, RegAddr);
}
u16 halwifionly_read2byte(PVOID pwifionlyContext, u32 RegAddr)
{
struct wifi_only_cfg *pwifionlycfg = (struct wifi_only_cfg *)pwifionlyContext;
PADAPTER Adapter = pwifionlycfg->Adapter;
return rtw_read16(Adapter, RegAddr);
}
u32 halwifionly_read4byte(PVOID pwifionlyContext, u32 RegAddr)
{
struct wifi_only_cfg *pwifionlycfg = (struct wifi_only_cfg *)pwifionlyContext;
PADAPTER Adapter = pwifionlycfg->Adapter;
return rtw_read32(Adapter, RegAddr);
}
void halwifionly_bitmaskwrite1byte(PVOID pwifionlyContext, u32 regAddr, u8 bitMask, u8 data)
{
u8 originalValue, bitShift = 0;
u8 i;
struct wifi_only_cfg *pwifionlycfg = (struct wifi_only_cfg *)pwifionlyContext;
PADAPTER Adapter = pwifionlycfg->Adapter;
if (bitMask != 0xff) {
originalValue = rtw_read8(Adapter, regAddr);
for (i = 0; i <= 7; i++) {
if ((bitMask >> i) & 0x1)
break;
}
bitShift = i;
data = ((originalValue) & (~bitMask)) | (((data << bitShift)) & bitMask);
}
rtw_write8(Adapter, regAddr, data);
}
void halwifionly_phy_set_rf_reg(PVOID pwifionlyContext, enum rf_path eRFPath, u32 RegAddr, u32 BitMask, u32 Data)
{
struct wifi_only_cfg *pwifionlycfg = (struct wifi_only_cfg *)pwifionlyContext;
PADAPTER Adapter = pwifionlycfg->Adapter;
phy_set_rf_reg(Adapter, eRFPath, RegAddr, BitMask, Data);
}
void halwifionly_phy_set_bb_reg(PVOID pwifionlyContext, u32 RegAddr, u32 BitMask, u32 Data)
{
struct wifi_only_cfg *pwifionlycfg = (struct wifi_only_cfg *)pwifionlyContext;
PADAPTER Adapter = pwifionlycfg->Adapter;
phy_set_bb_reg(Adapter, RegAddr, BitMask, Data);
}
void hal_btcoex_wifionly_switchband_notify(PADAPTER padapter)
{
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
u8 is_5g = _FALSE;
if (pHalData->current_band_type == BAND_ON_5G)
is_5g = _TRUE;
if (IS_HARDWARE_TYPE_8822B(padapter)) {
#ifdef CONFIG_RTL8822B
ex_hal8822b_wifi_only_switchbandnotify(&GLBtCoexistWifiOnly, is_5g);
#endif
}
#ifdef CONFIG_RTL8821C
else if (IS_HARDWARE_TYPE_8821C(padapter))
ex_hal8821c_wifi_only_switchbandnotify(&GLBtCoexistWifiOnly, is_5g);
#endif
}
void hal_btcoex_wifionly_scan_notify(PADAPTER padapter)
{
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
u8 is_5g = _FALSE;
if (pHalData->current_band_type == BAND_ON_5G)
is_5g = _TRUE;
if (IS_HARDWARE_TYPE_8822B(padapter)) {
#ifdef CONFIG_RTL8822B
ex_hal8822b_wifi_only_scannotify(&GLBtCoexistWifiOnly, is_5g);
#endif
}
#ifdef CONFIG_RTL8821C
else if (IS_HARDWARE_TYPE_8821C(padapter))
ex_hal8821c_wifi_only_scannotify(&GLBtCoexistWifiOnly, is_5g);
#endif
}
void hal_btcoex_wifionly_hw_config(PADAPTER padapter)
{
struct wifi_only_cfg *pwifionlycfg = &GLBtCoexistWifiOnly;
if (IS_HARDWARE_TYPE_8723B(padapter)) {
#ifdef CONFIG_RTL8723B
ex_hal8723b_wifi_only_hw_config(pwifionlycfg);
#endif
}
#ifdef CONFIG_RTL8822B
else if (IS_HARDWARE_TYPE_8822B(padapter))
ex_hal8822b_wifi_only_hw_config(pwifionlycfg);
#endif
#ifdef CONFIG_RTL8821C
else if (IS_HARDWARE_TYPE_8821C(padapter))
ex_hal8821c_wifi_only_hw_config(pwifionlycfg);
#endif
}
void hal_btcoex_wifionly_initlizevariables(PADAPTER padapter)
{
struct wifi_only_cfg *pwifionlycfg = &GLBtCoexistWifiOnly;
struct wifi_only_haldata *pwifionly_haldata = &pwifionlycfg->haldata_info;
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
_rtw_memset(&GLBtCoexistWifiOnly, 0, sizeof(GLBtCoexistWifiOnly));
pwifionlycfg->Adapter = padapter;
#ifdef CONFIG_PCI_HCI
pwifionlycfg->chip_interface = WIFIONLY_INTF_PCI;
#elif defined(CONFIG_USB_HCI)
pwifionlycfg->chip_interface = WIFIONLY_INTF_USB;
#elif defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
pwifionlycfg->chip_interface = WIFIONLY_INTF_SDIO;
#else
pwifionlycfg->chip_interface = WIFIONLY_INTF_UNKNOWN;
#endif
pwifionly_haldata->customer_id = CUSTOMER_NORMAL;
}
void hal_btcoex_wifionly_AntInfoSetting(PADAPTER padapter)
{
struct wifi_only_cfg *pwifionlycfg = &GLBtCoexistWifiOnly;
struct wifi_only_haldata *pwifionly_haldata = &pwifionlycfg->haldata_info;
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
pwifionly_haldata->efuse_pg_antnum = pHalData->EEPROMBluetoothAntNum;
pwifionly_haldata->efuse_pg_antpath = pHalData->ant_path;
pwifionly_haldata->rfe_type = pHalData->rfe_type;
pwifionly_haldata->ant_div_cfg = pHalData->AntDivCfg;
}
#endif

12831
hal/hal_com.c Normal file

File diff suppressed because it is too large Load Diff

123
hal/hal_com_c2h.h Normal file
View File

@ -0,0 +1,123 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#ifndef __COMMON_C2H_H__
#define __COMMON_C2H_H__
#define C2H_TYPE_REG 0
#define C2H_TYPE_PKT 1
/*
* C2H event format:
* Fields TRIGGER PAYLOAD SEQ PLEN ID
* BITS [127:120] [119:16] [15:8] [7:4] [3:0]
*/
#define C2H_ID(_c2h) LE_BITS_TO_1BYTE(((u8*)(_c2h)), 0, 4)
#define C2H_PLEN(_c2h) LE_BITS_TO_1BYTE(((u8*)(_c2h)), 4, 4)
#define C2H_SEQ(_c2h) LE_BITS_TO_1BYTE(((u8*)(_c2h)) + 1, 0, 8)
#define C2H_PAYLOAD(_c2h) (((u8*)(_c2h)) + 2)
#define SET_C2H_ID(_c2h, _val) SET_BITS_TO_LE_1BYTE(((u8*)(_c2h)), 0, 4, _val)
#define SET_C2H_PLEN(_c2h, _val) SET_BITS_TO_LE_1BYTE(((u8*)(_c2h)), 4, 4, _val)
#define SET_C2H_SEQ(_c2h, _val) SET_BITS_TO_LE_1BYTE(((u8*)(_c2h)) + 1 , 0, 8, _val)
/*
* C2H event format:
* Fields TRIGGER PLEN PAYLOAD SEQ ID
* BITS [127:120] [119:112] [111:16] [15:8] [7:0]
*/
#define C2H_ID_88XX(_c2h) LE_BITS_TO_1BYTE(((u8*)(_c2h)), 0, 8)
#define C2H_SEQ_88XX(_c2h) LE_BITS_TO_1BYTE(((u8*)(_c2h)) + 1, 0, 8)
#define C2H_PAYLOAD_88XX(_c2h) (((u8*)(_c2h)) + 2)
#define C2H_PLEN_88XX(_c2h) LE_BITS_TO_1BYTE(((u8*)(_c2h)) + 14, 0, 8)
#define C2H_TRIGGER_88XX(_c2h) LE_BITS_TO_1BYTE(((u8*)(_c2h)) + 15, 0, 8)
#define SET_C2H_ID_88XX(_c2h, _val) SET_BITS_TO_LE_1BYTE(((u8*)(_c2h)), 0, 8, _val)
#define SET_C2H_SEQ_88XX(_c2h, _val) SET_BITS_TO_LE_1BYTE(((u8*)(_c2h)) + 1, 0, 8, _val)
#define SET_C2H_PLEN_88XX(_c2h, _val) SET_BITS_TO_LE_1BYTE(((u8*)(_c2h)) + 14, 0, 8, _val)
typedef enum _C2H_EVT {
C2H_DBG = 0x00,
C2H_LB = 0x01,
C2H_TXBF = 0x02,
C2H_CCX_TX_RPT = 0x03,
C2H_AP_REQ_TXRPT = 0x04,
C2H_FW_SCAN_COMPLETE = 0x7,
C2H_BT_INFO = 0x09,
C2H_BT_MP_INFO = 0x0B,
C2H_RA_RPT = 0x0C,
C2H_SPC_STAT = 0x0D,
C2H_RA_PARA_RPT = 0x0E,
C2H_FW_CHNL_SWITCH_COMPLETE = 0x10,
C2H_IQK_FINISH = 0x11,
C2H_MAILBOX_STATUS = 0x15,
C2H_P2P_RPORT = 0x16,
C2H_MCC = 0x17,
C2H_MAC_HIDDEN_RPT = 0x19,
C2H_MAC_HIDDEN_RPT_2 = 0x1A,
C2H_BCN_EARLY_RPT = 0x1E,
C2H_DEFEATURE_DBG = 0x22,
C2H_CUSTOMER_STR_RPT = 0x24,
C2H_CUSTOMER_STR_RPT_2 = 0x25,
C2H_WLAN_INFO = 0x27,
#ifdef RTW_PER_CMD_SUPPORT_FW
C2H_PER_RATE_RPT = 0x2c,
#endif
C2H_DEFEATURE_RSVD = 0xFD,
C2H_EXTEND = 0xff,
} C2H_EVT;
typedef enum _EXTEND_C2H_EVT {
EXTEND_C2H_DBG_PRINT = 0
} EXTEND_C2H_EVT;
#define C2H_REG_LEN 16
/* C2H_IQK_FINISH, 0x11 */
#define IQK_OFFLOAD_LEN 1
void c2h_iqk_offload(_adapter *adapter, u8 *data, u8 len);
int c2h_iqk_offload_wait(_adapter *adapter, u32 timeout_ms);
#define rtl8812_iqk_wait c2h_iqk_offload_wait /* TODO: remove this after phydm call c2h_iqk_offload_wait instead */
#ifdef CONFIG_RTW_MAC_HIDDEN_RPT
/* C2H_MAC_HIDDEN_RPT, 0x19 */
#define MAC_HIDDEN_RPT_LEN 8
int c2h_mac_hidden_rpt_hdl(_adapter *adapter, u8 *data, u8 len);
/* C2H_MAC_HIDDEN_RPT_2, 0x1A */
#define MAC_HIDDEN_RPT_2_LEN 5
int c2h_mac_hidden_rpt_2_hdl(_adapter *adapter, u8 *data, u8 len);
int hal_read_mac_hidden_rpt(_adapter *adapter);
#endif /* CONFIG_RTW_MAC_HIDDEN_RPT */
/* C2H_DEFEATURE_DBG, 0x22 */
#define DEFEATURE_DBG_LEN 1
int c2h_defeature_dbg_hdl(_adapter *adapter, u8 *data, u8 len);
#ifdef CONFIG_RTW_CUSTOMER_STR
/* C2H_CUSTOMER_STR_RPT, 0x24 */
#define CUSTOMER_STR_RPT_LEN 8
int c2h_customer_str_rpt_hdl(_adapter *adapter, u8 *data, u8 len);
/* C2H_CUSTOMER_STR_RPT_2, 0x25 */
#define CUSTOMER_STR_RPT_2_LEN 8
int c2h_customer_str_rpt_2_hdl(_adapter *adapter, u8 *data, u8 len);
#endif /* CONFIG_RTW_CUSTOMER_STR */
#ifdef RTW_PER_CMD_SUPPORT_FW
/* C2H_PER_RATE_RPT, 0x2c */
int c2h_per_rate_rpt_hdl(_adapter *adapter, u8 *data, u8 len);
#endif
#endif /* __COMMON_C2H_H__ */

5467
hal/hal_com_phycfg.c Normal file

File diff suppressed because it is too large Load Diff

1265
hal/hal_dm.c Normal file

File diff suppressed because it is too large Load Diff

88
hal/hal_dm.h Normal file
View File

@ -0,0 +1,88 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#ifndef __HAL_DM_H__
#define __HAL_DM_H__
#define adapter_to_phydm(adapter) (&(GET_HAL_DATA(adapter)->odmpriv))
void Init_ODM_ComInfo(_adapter *adapter);
void rtw_phydm_init(_adapter *adapter);
void rtw_hal_turbo_edca(_adapter *adapter);
u8 rtw_phydm_is_iqk_in_progress(_adapter *adapter);
void GetHalODMVar(
PADAPTER Adapter,
HAL_ODM_VARIABLE eVariable,
PVOID pValue1,
PVOID pValue2);
void SetHalODMVar(
PADAPTER Adapter,
HAL_ODM_VARIABLE eVariable,
PVOID pValue1,
BOOLEAN bSet);
void rtw_phydm_ra_registed(_adapter *adapter, struct sta_info *psta);
#ifdef CONFIG_DYNAMIC_SOML
void rtw_dyn_soml_byte_update(_adapter *adapter, u8 data_rate, u32 size);
void rtw_dyn_soml_para_set(_adapter *adapter, u8 train_num, u8 intvl,
u8 period, u8 delay);
void rtw_dyn_soml_config(_adapter *adapter);
#endif
void rtw_phydm_watchdog(_adapter *adapter);
void rtw_hal_update_iqk_fw_offload_cap(_adapter *adapter);
void dump_sta_info(void *sel, struct sta_info *psta);
void dump_sta_traffic(void *sel, _adapter *adapter, struct sta_info *psta);
#ifdef CONFIG_DBG_RF_CAL
void rtw_hal_iqk_test(_adapter *adapter, bool recovery, bool clear, bool segment);
void rtw_hal_lck_test(_adapter *adapter);
#endif
s8 rtw_phydm_get_min_rssi(_adapter *adapter);
u8 rtw_phydm_get_cur_igi(_adapter *adapter);
#ifdef CONFIG_LPS_LCLK_WD_TIMER
extern void phydm_rssi_monitor_check(void *p_dm_void);
void rtw_phydm_wd_lps_lclk_hdl(_adapter *adapter);
void rtw_phydm_watchdog_in_lps_lclk(_adapter *adapter);
#endif
enum phy_cnt {
FA_OFDM,
FA_CCK,
FA_TOTAL,
CCA_OFDM,
CCA_CCK,
CCA_ALL,
CRC32_OK_VHT,
CRC32_OK_HT,
CRC32_OK_LEGACY,
CRC32_OK_CCK,
CRC32_ERROR_VHT,
CRC32_ERROR_HT,
CRC32_ERROR_LEGACY,
CRC32_ERROR_CCK,
};
u32 rtw_phydm_get_phy_cnt(_adapter *adapter, enum phy_cnt cnt);
#if ((RTL8822B_SUPPORT == 1) || (RTL8821C_SUPPORT == 1) || (RTL8814B_SUPPORT == 1))
void rtw_phydm_iqk_trigger(_adapter *adapter);
#endif
#endif /* __HAL_DM_H__ */

554
hal/hal_dm_acs.c Normal file
View File

@ -0,0 +1,554 @@
/******************************************************************************
*
* Copyright(c) 2014 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#include <drv_types.h>
#include <hal_data.h>
#if defined(CONFIG_RTW_ACS) || defined(CONFIG_BACKGROUND_NOISE_MONITOR)
static void _rtw_bss_nums_count(_adapter *adapter, u8 *pbss_nums)
{
struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
_queue *queue = &(pmlmepriv->scanned_queue);
struct wlan_network *pnetwork = NULL;
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
_list *plist, *phead;
_irqL irqL;
int chan_idx = -1;
if (pbss_nums == NULL) {
RTW_ERR("%s pbss_nums is null pointer\n", __func__);
return;
}
_rtw_memset(pbss_nums, 0, MAX_CHANNEL_NUM);
_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
phead = get_list_head(queue);
plist = get_next(phead);
while (1) {
if (rtw_end_of_queue_search(phead, plist) == _TRUE)
break;
pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
if (!pnetwork)
break;
chan_idx = rtw_chset_search_ch(adapter_to_chset(adapter), pnetwork->network.Configuration.DSConfig);
if ((chan_idx == -1) || (chan_idx >= MAX_CHANNEL_NUM)) {
RTW_ERR("%s can't get chan_idx(CH:%d)\n",
__func__, pnetwork->network.Configuration.DSConfig);
chan_idx = 0;
}
/*if (pnetwork->network.Reserved[0] != BSS_TYPE_PROB_REQ)*/
pbss_nums[chan_idx]++;
plist = get_next(plist);
}
_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
}
u8 rtw_get_ch_num_by_idx(_adapter *adapter, u8 idx)
{
struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
RT_CHANNEL_INFO *pch_set = rfctl->channel_set;
u8 max_chan_nums = rfctl->max_chan_nums;
if (idx >= max_chan_nums)
return 0;
return pch_set[idx].ChannelNum;
}
#endif /*defined(CONFIG_RTW_ACS) || defined(CONFIG_BACKGROUND_NOISE_MONITOR)*/
#ifdef CONFIG_RTW_ACS
void rtw_acs_version_dump(void *sel, _adapter *adapter)
{
_RTW_PRINT_SEL(sel, "RTK_ACS VER_%d\n", RTK_ACS_VERSION);
}
u8 rtw_phydm_clm_ratio(_adapter *adapter)
{
struct dm_struct *phydm = adapter_to_phydm(adapter);
return phydm_cmn_info_query(phydm, (enum phydm_info_query) PHYDM_INFO_CLM_RATIO);
}
u8 rtw_phydm_nhm_ratio(_adapter *adapter)
{
struct dm_struct *phydm = adapter_to_phydm(adapter);
return phydm_cmn_info_query(phydm, (enum phydm_info_query) PHYDM_INFO_NHM_RATIO);
}
void rtw_acs_reset(_adapter *adapter)
{
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
struct auto_chan_sel *pacs = &hal_data->acs;
_rtw_memset(pacs, 0, sizeof(struct auto_chan_sel));
#ifdef CONFIG_RTW_ACS_DBG
rtw_acs_adv_reset(adapter);
#endif /*CONFIG_RTW_ACS_DBG*/
}
#ifdef CONFIG_RTW_ACS_DBG
u8 rtw_is_acs_igi_valid(_adapter *adapter)
{
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
struct auto_chan_sel *pacs = &hal_data->acs;
if ((pacs->igi) && ((pacs->igi >= 0x1E) || (pacs->igi < 0x60)))
return _TRUE;
return _FALSE;
}
void rtw_acs_adv_setting(_adapter *adapter, RT_SCAN_TYPE scan_type, u16 scan_time, u8 igi, u8 bw)
{
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
struct auto_chan_sel *pacs = &hal_data->acs;
struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
pacs->scan_type = scan_type;
pacs->scan_time = scan_time;
pacs->igi = igi;
pacs->bw = bw;
RTW_INFO("[ACS] ADV setting - scan_type:%c, ch_ms:%d(ms), igi:0x%02x, bw:%d\n",
pacs->scan_type ? 'A' : 'P', pacs->scan_time, pacs->igi, pacs->bw);
}
void rtw_acs_adv_reset(_adapter *adapter)
{
rtw_acs_adv_setting(adapter, SCAN_ACTIVE, 0, 0, 0);
}
#endif /*CONFIG_RTW_ACS_DBG*/
void rtw_acs_trigger(_adapter *adapter, u16 scan_time_ms, u8 scan_chan, enum NHM_PID pid)
{
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
struct dm_struct *phydm = adapter_to_phydm(adapter);
#if (RTK_ACS_VERSION == 3)
struct clm_para_info clm_para;
struct nhm_para_info nhm_para;
struct env_trig_rpt trig_rpt;
scan_time_ms -= 10;
init_acs_clm(clm_para, scan_time_ms);
if (pid == NHM_PID_IEEE_11K_HIGH)
init_11K_high_nhm(nhm_para, scan_time_ms);
else if (pid == NHM_PID_IEEE_11K_LOW)
init_11K_low_nhm(nhm_para, scan_time_ms);
else
init_acs_nhm(nhm_para, scan_time_ms);
hal_data->acs.trig_rst = phydm_env_mntr_trigger(phydm, &nhm_para, &clm_para, &trig_rpt);
if (hal_data->acs.trig_rst == (NHM_SUCCESS | CLM_SUCCESS)) {
hal_data->acs.trig_rpt.clm_rpt_stamp = trig_rpt.clm_rpt_stamp;
hal_data->acs.trig_rpt.nhm_rpt_stamp = trig_rpt.nhm_rpt_stamp;
/*RTW_INFO("[ACS] trigger success (rst = 0x%02x, clm_stamp:%d, nhm_stamp:%d)\n",
hal_data->acs.trig_rst, hal_data->acs.trig_rpt.clm_rpt_stamp, hal_data->acs.trig_rpt.nhm_rpt_stamp);*/
} else
RTW_ERR("[ACS] trigger failed (rst = 0x%02x)\n", hal_data->acs.trig_rst);
#else
phydm_ccx_monitor_trigger(phydm, scan_time_ms);
#endif
hal_data->acs.trigger_ch = scan_chan;
hal_data->acs.triggered = _TRUE;
#ifdef CONFIG_RTW_ACS_DBG
RTW_INFO("[ACS] Trigger CH:%d, Times:%d\n", hal_data->acs.trigger_ch, scan_time_ms);
#endif
}
void rtw_acs_get_rst(_adapter *adapter)
{
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
struct dm_struct *phydm = adapter_to_phydm(adapter);
int chan_idx = -1;
u8 cur_chan = hal_data->acs.trigger_ch;
if (cur_chan == 0)
return;
if (!hal_data->acs.triggered)
return;
chan_idx = rtw_chset_search_ch(adapter_to_chset(adapter), cur_chan);
if ((chan_idx == -1) || (chan_idx >= MAX_CHANNEL_NUM)) {
RTW_ERR("[ACS] %s can't get chan_idx(CH:%d)\n", __func__, cur_chan);
return;
}
#if (RTK_ACS_VERSION == 3)
if (!(hal_data->acs.trig_rst == (NHM_SUCCESS | CLM_SUCCESS))) {
RTW_ERR("[ACS] get_rst return, due to acs trigger failed\n");
return;
}
{
struct env_mntr_rpt rpt = {0};
u8 rst;
rst = phydm_env_mntr_result(phydm, &rpt);
if ((rst == (NHM_SUCCESS | CLM_SUCCESS)) &&
(rpt.clm_rpt_stamp == hal_data->acs.trig_rpt.clm_rpt_stamp) &&
(rpt.nhm_rpt_stamp == hal_data->acs.trig_rpt.nhm_rpt_stamp)){
hal_data->acs.clm_ratio[chan_idx] = rpt.clm_ratio;
hal_data->acs.nhm_ratio[chan_idx] = rpt.nhm_ratio;
_rtw_memcpy(&hal_data->acs.nhm[chan_idx][0], rpt.nhm_result, NHM_RPT_NUM);
/*RTW_INFO("[ACS] get_rst success (rst = 0x%02x, clm_stamp:%d:%d, nhm_stamp:%d:%d)\n",
rst,
hal_data->acs.trig_rpt.clm_rpt_stamp, rpt.clm_rpt_stamp,
hal_data->acs.trig_rpt.nhm_rpt_stamp, rpt.nhm_rpt_stamp);*/
} else {
RTW_ERR("[ACS] get_rst failed (rst = 0x%02x, clm_stamp:%d:%d, nhm_stamp:%d:%d)\n",
rst,
hal_data->acs.trig_rpt.clm_rpt_stamp, rpt.clm_rpt_stamp,
hal_data->acs.trig_rpt.nhm_rpt_stamp, rpt.nhm_rpt_stamp);
}
}
#else
phydm_ccx_monitor_result(phydm);
hal_data->acs.clm_ratio[chan_idx] = rtw_phydm_clm_ratio(adapter);
hal_data->acs.nhm_ratio[chan_idx] = rtw_phydm_nhm_ratio(adapter);
#endif
hal_data->acs.triggered = _FALSE;
#ifdef CONFIG_RTW_ACS_DBG
RTW_INFO("[ACS] Result CH:%d, CLM:%d NHM:%d\n",
cur_chan, hal_data->acs.clm_ratio[chan_idx], hal_data->acs.nhm_ratio[chan_idx]);
#endif
}
void _rtw_phydm_acs_select_best_chan(_adapter *adapter)
{
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
u8 ch_idx;
u8 ch_idx_24g = 0xFF, ch_idx_5g = 0xFF;
u8 min_itf_24g = 0xFF, min_itf_5g = 0xFF;
u8 *pbss_nums = hal_data->acs.bss_nums;
u8 *pclm_ratio = hal_data->acs.clm_ratio;
u8 *pnhm_ratio = hal_data->acs.nhm_ratio;
u8 *pinterference_time = hal_data->acs.interference_time;
u8 max_chan_nums = rfctl->max_chan_nums;
for (ch_idx = 0; ch_idx < max_chan_nums; ch_idx++) {
if (pbss_nums[ch_idx])
pinterference_time[ch_idx] = (pclm_ratio[ch_idx] / 2) + pnhm_ratio[ch_idx];
else
pinterference_time[ch_idx] = pclm_ratio[ch_idx] + pnhm_ratio[ch_idx];
if (rtw_get_ch_num_by_idx(adapter, ch_idx) < 14) {
if (pinterference_time[ch_idx] < min_itf_24g) {
min_itf_24g = pinterference_time[ch_idx];
ch_idx_24g = ch_idx;
}
} else {
if (pinterference_time[ch_idx] < min_itf_5g) {
min_itf_5g = pinterference_time[ch_idx];
ch_idx_5g = ch_idx;
}
}
}
if (ch_idx_24g != 0xFF)
hal_data->acs.best_chan_24g = rtw_get_ch_num_by_idx(adapter, ch_idx_24g);
if (ch_idx_5g != 0xFF)
hal_data->acs.best_chan_5g = rtw_get_ch_num_by_idx(adapter, ch_idx_5g);
hal_data->acs.trigger_ch = 0;
}
void rtw_acs_info_dump(void *sel, _adapter *adapter)
{
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
u8 max_chan_nums = rfctl->max_chan_nums;
u8 ch_idx, ch_num;
_RTW_PRINT_SEL(sel, "========== ACS (VER-%d) ==========\n", RTK_ACS_VERSION);
_RTW_PRINT_SEL(sel, "Best 24G Channel:%d\n", hal_data->acs.best_chan_24g);
_RTW_PRINT_SEL(sel, "Best 5G Channel:%d\n\n", hal_data->acs.best_chan_5g);
#ifdef CONFIG_RTW_ACS_DBG
_RTW_PRINT_SEL(sel, "Advanced setting - scan_type:%c, ch_ms:%d(ms), igi:0x%02x, bw:%d\n",
hal_data->acs.scan_type ? 'A' : 'P', hal_data->acs.scan_time, hal_data->acs.igi, hal_data->acs.bw);
_RTW_PRINT_SEL(sel, "BW 20MHz\n");
_RTW_PRINT_SEL(sel, "%5s %3s %3s %3s(%%) %3s(%%) %3s\n",
"Index", "CH", "BSS", "CLM", "NHM", "ITF");
for (ch_idx = 0; ch_idx < max_chan_nums; ch_idx++) {
ch_num = rtw_get_ch_num_by_idx(adapter, ch_idx);
_RTW_PRINT_SEL(sel, "%5d %3d %3d %6d %6d %3d\n",
ch_idx, ch_num, hal_data->acs.bss_nums[ch_idx],
hal_data->acs.clm_ratio[ch_idx],
hal_data->acs.nhm_ratio[ch_idx],
hal_data->acs.interference_time[ch_idx]);
}
#endif
}
void rtw_acs_select_best_chan(_adapter *adapter)
{
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
_rtw_bss_nums_count(adapter, hal_data->acs.bss_nums);
_rtw_phydm_acs_select_best_chan(adapter);
rtw_acs_info_dump(RTW_DBGDUMP, adapter);
}
void rtw_acs_start(_adapter *adapter)
{
rtw_acs_reset(adapter);
if (GET_ACS_STATE(adapter) != ACS_ENABLE)
SET_ACS_STATE(adapter, ACS_ENABLE);
}
void rtw_acs_stop(_adapter *adapter)
{
SET_ACS_STATE(adapter, ACS_DISABLE);
}
u8 rtw_acs_get_clm_ratio_by_ch_num(_adapter *adapter, u8 chan)
{
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
int chan_idx = -1;
chan_idx = rtw_chset_search_ch(adapter_to_chset(adapter), chan);
if ((chan_idx == -1) || (chan_idx >= MAX_CHANNEL_NUM)) {
RTW_ERR("[ACS] Get CLM fail, can't get chan_idx(CH:%d)\n", chan);
return 0;
}
return hal_data->acs.clm_ratio[chan_idx];
}
u8 rtw_acs_get_clm_ratio_by_ch_idx(_adapter *adapter, u8 ch_idx)
{
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
if (ch_idx >= MAX_CHANNEL_NUM) {
RTW_ERR("%s [ACS] ch_idx(%d) is invalid\n", __func__, ch_idx);
return 0;
}
return hal_data->acs.clm_ratio[ch_idx];
}
u8 rtw_acs_get_nhm_ratio_by_ch_num(_adapter *adapter, u8 chan)
{
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
int chan_idx = -1;
chan_idx = rtw_chset_search_ch(adapter_to_chset(adapter), chan);
if ((chan_idx == -1) || (chan_idx >= MAX_CHANNEL_NUM)) {
RTW_ERR("[ACS] Get NHM fail, can't get chan_idx(CH:%d)\n", chan);
return 0;
}
return hal_data->acs.nhm_ratio[chan_idx];
}
u8 rtw_acs_get_num_ratio_by_ch_idx(_adapter *adapter, u8 ch_idx)
{
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
if (ch_idx >= MAX_CHANNEL_NUM) {
RTW_ERR("%s [ACS] ch_idx(%d) is invalid\n", __func__, ch_idx);
return 0;
}
return hal_data->acs.nhm_ratio[ch_idx];
}
void rtw_acs_chan_info_dump(void *sel, _adapter *adapter)
{
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
u8 max_chan_nums = rfctl->max_chan_nums;
u8 ch_idx, ch_num;
u8 utilization;
_RTW_PRINT_SEL(sel, "BW 20MHz\n");
_RTW_PRINT_SEL(sel, "%5s %3s %7s(%%) %12s(%%) %11s(%%) %9s(%%) %8s(%%)\n",
"Index", "CH", "Quality", "Availability", "Utilization",
"WIFI Util", "Interference Util");
for (ch_idx = 0; ch_idx < max_chan_nums; ch_idx++) {
ch_num = rtw_get_ch_num_by_idx(adapter, ch_idx);
utilization = hal_data->acs.clm_ratio[ch_idx] + hal_data->acs.nhm_ratio[ch_idx];
_RTW_PRINT_SEL(sel, "%5d %3d %7d %12d %12d %12d %12d\n",
ch_idx, ch_num,
(100-hal_data->acs.interference_time[ch_idx]),
(100-utilization),
utilization,
hal_data->acs.clm_ratio[ch_idx],
hal_data->acs.nhm_ratio[ch_idx]);
}
}
void rtw_acs_current_info_dump(void *sel, _adapter *adapter)
{
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
u8 ch, cen_ch, bw, offset;
_RTW_PRINT_SEL(sel, "========== ACS (VER-%d) ==========\n", RTK_ACS_VERSION);
ch = rtw_get_oper_ch(adapter);
bw = rtw_get_oper_bw(adapter);
offset = rtw_get_oper_choffset(adapter);
_RTW_PRINT_SEL(sel, "Current Channel:%d\n", ch);
if ((bw == CHANNEL_WIDTH_80) ||(bw == CHANNEL_WIDTH_40)) {
cen_ch = rtw_get_center_ch(ch, bw, offset);
_RTW_PRINT_SEL(sel, "Center Channel:%d\n", cen_ch);
}
_RTW_PRINT_SEL(sel, "Current BW %s\n", ch_width_str(bw));
if (0)
_RTW_PRINT_SEL(sel, "Current IGI 0x%02x\n", rtw_phydm_get_cur_igi(adapter));
_RTW_PRINT_SEL(sel, "CLM:%d, NHM:%d\n\n",
hal_data->acs.cur_ch_clm_ratio, hal_data->acs.cur_ch_nhm_ratio);
}
void rtw_acs_update_current_info(_adapter *adapter)
{
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
hal_data->acs.cur_ch_clm_ratio = rtw_phydm_clm_ratio(adapter);
hal_data->acs.cur_ch_nhm_ratio = rtw_phydm_nhm_ratio(adapter);
#ifdef CONFIG_RTW_ACS_DBG
rtw_acs_current_info_dump(RTW_DBGDUMP, adapter);
#endif
}
#endif /*CONFIG_RTW_ACS*/
#ifdef CONFIG_BACKGROUND_NOISE_MONITOR
void rtw_noise_monitor_version_dump(void *sel, _adapter *adapter)
{
_RTW_PRINT_SEL(sel, "RTK_NOISE_MONITOR VER_%d\n", RTK_NOISE_MONITOR_VERSION);
}
void rtw_nm_enable(_adapter *adapter)
{
SET_NM_STATE(adapter, NM_ENABLE);
}
void rtw_nm_disable(_adapter *adapter)
{
SET_NM_STATE(adapter, NM_DISABLE);
}
void rtw_noise_info_dump(void *sel, _adapter *adapter)
{
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
u8 max_chan_nums = rfctl->max_chan_nums;
u8 ch_idx, ch_num;
_RTW_PRINT_SEL(sel, "========== NM (VER-%d) ==========\n", RTK_NOISE_MONITOR_VERSION);
_RTW_PRINT_SEL(sel, "%5s %3s %3s %10s", "Index", "CH", "BSS", "Noise(dBm)\n");
_rtw_bss_nums_count(adapter, hal_data->nm.bss_nums);
for (ch_idx = 0; ch_idx < max_chan_nums; ch_idx++) {
ch_num = rtw_get_ch_num_by_idx(adapter, ch_idx);
_RTW_PRINT_SEL(sel, "%5d %3d %3d %10d\n",
ch_idx, ch_num, hal_data->nm.bss_nums[ch_idx],
hal_data->nm.noise[ch_idx]);
}
}
void rtw_noise_measure(_adapter *adapter, u8 chan, u8 is_pause_dig, u8 igi_value, u32 max_time)
{
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
struct dm_struct *phydm = &hal_data->odmpriv;
int chan_idx = -1;
s16 noise = 0;
#ifdef DBG_NOISE_MONITOR
RTW_INFO("[NM] chan(%d)-PauseDIG:%s, IGIValue:0x%02x, max_time:%d (ms)\n",
chan, (is_pause_dig) ? "Y" : "N", igi_value, max_time);
#endif
chan_idx = rtw_chset_search_ch(adapter_to_chset(adapter), chan);
if ((chan_idx == -1) || (chan_idx >= MAX_CHANNEL_NUM)) {
RTW_ERR("[NM] Get noise fail, can't get chan_idx(CH:%d)\n", chan);
return;
}
noise = odm_inband_noise_monitor(phydm, is_pause_dig, igi_value, max_time); /*dBm*/
hal_data->nm.noise[chan_idx] = noise;
#ifdef DBG_NOISE_MONITOR
RTW_INFO("[NM] %s chan_%d, noise = %d (dBm)\n", __func__, chan, hal_data->nm.noise[chan_idx]);
RTW_INFO("[NM] noise_a = %d, noise_b = %d noise_all:%d\n",
phydm->noise_level.noise[RF_PATH_A],
phydm->noise_level.noise[RF_PATH_B],
phydm->noise_level.noise_all);
#endif /*DBG_NOISE_MONITOR*/
}
s16 rtw_noise_query_by_chan_num(_adapter *adapter, u8 chan)
{
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
s16 noise = 0;
int chan_idx = -1;
chan_idx = rtw_chset_search_ch(adapter_to_chset(adapter), chan);
if ((chan_idx == -1) || (chan_idx >= MAX_CHANNEL_NUM)) {
RTW_ERR("[NM] Get noise fail, can't get chan_idx(CH:%d)\n", chan);
return noise;
}
noise = hal_data->nm.noise[chan_idx];
#ifdef DBG_NOISE_MONITOR
RTW_INFO("[NM] %s chan_%d, noise = %d (dBm)\n", __func__, chan, noise);
#endif/*DBG_NOISE_MONITOR*/
return noise;
}
s16 rtw_noise_query_by_chan_idx(_adapter *adapter, u8 ch_idx)
{
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
s16 noise = 0;
if (ch_idx >= MAX_CHANNEL_NUM) {
RTW_ERR("[NM] %s ch_idx(%d) is invalid\n", __func__, ch_idx);
return noise;
}
noise = hal_data->nm.noise[ch_idx];
#ifdef DBG_NOISE_MONITOR
RTW_INFO("[NM] %s ch_idx %d, noise = %d (dBm)\n", __func__, ch_idx, noise);
#endif/*DBG_NOISE_MONITOR*/
return noise;
}
s16 rtw_noise_measure_curchan(_adapter *padapter)
{
s16 noise = 0;
u8 igi_value = 0x1E;
u32 max_time = 100;/* ms */
u8 is_pause_dig = _TRUE;
u8 cur_chan = rtw_get_oper_ch(padapter);
if (rtw_linked_check(padapter) == _FALSE)
return noise;
rtw_ps_deny(padapter, PS_DENY_IOCTL);
LeaveAllPowerSaveModeDirect(padapter);
rtw_noise_measure(padapter, cur_chan, is_pause_dig, igi_value, max_time);
noise = rtw_noise_query_by_chan_num(padapter, cur_chan);
rtw_ps_deny_cancel(padapter, PS_DENY_IOCTL);
return noise;
}
#endif /*CONFIG_BACKGROUND_NOISE_MONITOR*/

167
hal/hal_dm_acs.h Normal file
View File

@ -0,0 +1,167 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#ifndef __HAL_DM_ACS_H__
#define __HAL_DM_ACS_H__
#ifdef CONFIG_RTW_ACS
#define RTK_ACS_VERSION 3
#if (RTK_ACS_VERSION == 3)
enum NHM_PID {
NHM_PID_ACS,
NHM_PID_IEEE_11K_HIGH,
NHM_PID_IEEE_11K_LOW,
};
#define init_clm_param(clm, app, lv, time) \
do {\
clm.clm_app = app;\
clm.clm_lv = lv;\
clm.mntr_time = time;\
} while (0)
#define init_nhm_param(nhm, txon, cca, cnt_opt, app, lv, time) \
do {\
nhm.incld_txon = txon;\
nhm.incld_cca = cca;\
nhm.div_opt = cnt_opt;\
nhm.nhm_app = app;\
nhm.nhm_lv = lv;\
nhm.mntr_time = time;\
} while (0)
#define init_acs_clm(clm, time) \
init_clm_param(clm, CLM_ACS, CLM_LV_2, time)
#define init_acs_nhm(nhm, time) \
init_nhm_param(nhm, NHM_EXCLUDE_TXON, NHM_EXCLUDE_CCA, NHM_CNT_ALL, NHM_ACS, NHM_LV_2, time)
#define init_11K_high_nhm(nhm, time) \
init_nhm_param(nhm, NHM_EXCLUDE_TXON, NHM_EXCLUDE_CCA, NHM_CNT_ALL, IEEE_11K_HIGH, NHM_LV_2, time)
#define init_11K_low_nhm(nhm, time) \
init_nhm_param(nhm, NHM_EXCLUDE_TXON, NHM_EXCLUDE_CCA, NHM_CNT_ALL, IEEE_11K_LOW, NHM_LV_2, time)
#endif /*(RTK_ACS_VERSION == 3)*/
void rtw_acs_version_dump(void *sel, _adapter *adapter);
extern void phydm_ccx_monitor_trigger(void *p_dm_void, u16 monitor_time);
extern void phydm_ccx_monitor_result(void *p_dm_void);
#define GET_ACS_STATE(padapter) (ATOMIC_READ(&GET_HAL_DATA(padapter)->acs.state))
#define SET_ACS_STATE(padapter, set_state) (ATOMIC_SET(&GET_HAL_DATA(padapter)->acs.state, set_state))
#define IS_ACS_ENABLE(padapter) ((GET_ACS_STATE(padapter) == ACS_ENABLE) ? _TRUE : _FALSE)
enum ACS_STATE {
ACS_DISABLE,
ACS_ENABLE,
};
#define ACS_BW_20M BIT(0)
#define ACS_BW_40M BIT(1)
#define ACS_BW_80M BIT(2)
#define ACS_BW_160M BIT(3)
struct auto_chan_sel {
ATOMIC_T state;
u8 trigger_ch;
bool triggered;
u8 clm_ratio[MAX_CHANNEL_NUM];
u8 nhm_ratio[MAX_CHANNEL_NUM];
#if (RTK_ACS_VERSION == 3)
u8 nhm[MAX_CHANNEL_NUM][NHM_RPT_NUM];
#endif
u8 bss_nums[MAX_CHANNEL_NUM];
u8 interference_time[MAX_CHANNEL_NUM];
u8 cur_ch_clm_ratio;
u8 cur_ch_nhm_ratio;
u8 best_chan_5g;
u8 best_chan_24g;
#if (RTK_ACS_VERSION == 3)
u8 trig_rst;
struct env_trig_rpt trig_rpt;
#endif
#ifdef CONFIG_RTW_ACS_DBG
RT_SCAN_TYPE scan_type;
u16 scan_time;
u8 igi;
u8 bw;
#endif
};
#define rtw_acs_get_best_chan_24g(adapter) (GET_HAL_DATA(adapter)->acs.best_chan_24g)
#define rtw_acs_get_best_chan_5g(adapter) (GET_HAL_DATA(adapter)->acs.best_chan_5g)
#ifdef CONFIG_RTW_ACS_DBG
#define rtw_is_acs_passiv_scan(adapter) (((GET_HAL_DATA(adapter)->acs.scan_type) == SCAN_PASSIVE) ? _TRUE : _FALSE)
#define rtw_acs_get_adv_st(adapter) (GET_HAL_DATA(adapter)->acs.scan_time)
#define rtw_is_acs_st_valid(adapter) ((GET_HAL_DATA(adapter)->acs.scan_time) ? _TRUE : _FALSE)
#define rtw_acs_get_adv_igi(adapter) (GET_HAL_DATA(adapter)->acs.igi)
u8 rtw_is_acs_igi_valid(_adapter *adapter);
#define rtw_acs_get_adv_bw(adapter) (GET_HAL_DATA(adapter)->acs.bw)
void rtw_acs_adv_setting(_adapter *adapter, RT_SCAN_TYPE scan_type, u16 scan_time, u8 igi, u8 bw);
void rtw_acs_adv_reset(_adapter *adapter);
#endif
u8 rtw_acs_get_clm_ratio_by_ch_num(_adapter *adapter, u8 chan);
u8 rtw_acs_get_clm_ratio_by_ch_idx(_adapter *adapter, u8 ch_idx);
u8 rtw_acs_get_nhm_ratio_by_ch_num(_adapter *adapter, u8 chan);
u8 rtw_acs_get_num_ratio_by_ch_idx(_adapter *adapter, u8 ch_idx);
void rtw_acs_reset(_adapter *adapter);
void rtw_acs_trigger(_adapter *adapter, u16 scan_time_ms, u8 scan_chan, enum NHM_PID pid);
void rtw_acs_get_rst(_adapter *adapter);
void rtw_acs_select_best_chan(_adapter *adapter);
void rtw_acs_info_dump(void *sel, _adapter *adapter);
void rtw_acs_update_current_info(_adapter *adapter);
void rtw_acs_chan_info_dump(void *sel, _adapter *adapter);
void rtw_acs_current_info_dump(void *sel, _adapter *adapter);
void rtw_acs_start(_adapter *adapter);
void rtw_acs_stop(_adapter *adapter);
#endif /*CONFIG_RTW_ACS*/
#ifdef CONFIG_BACKGROUND_NOISE_MONITOR
#define RTK_NOISE_MONITOR_VERSION 3
#define GET_NM_STATE(padapter) (ATOMIC_READ(&GET_HAL_DATA(padapter)->nm.state))
#define SET_NM_STATE(padapter, set_state) (ATOMIC_SET(&GET_HAL_DATA(padapter)->nm.state, set_state))
#define IS_NM_ENABLE(padapter) ((GET_NM_STATE(padapter) == NM_ENABLE) ? _TRUE : _FALSE)
enum NM_STATE {
NM_DISABLE,
NM_ENABLE,
};
struct noise_monitor {
ATOMIC_T state;
s16 noise[MAX_CHANNEL_NUM];
u8 bss_nums[MAX_CHANNEL_NUM];
};
void rtw_nm_enable(_adapter *adapter);
void rtw_nm_disable(_adapter *adapter);
void rtw_noise_measure(_adapter *adapter, u8 chan, u8 is_pause_dig, u8 igi_value, u32 max_time);
s16 rtw_noise_query_by_chan_num(_adapter *adapter, u8 chan);
s16 rtw_noise_query_by_chan_idx(_adapter *adapter, u8 ch_idx);
s16 rtw_noise_measure_curchan(_adapter *padapter);
void rtw_noise_info_dump(void *sel, _adapter *adapter);
#endif
#endif /* __HAL_DM_ACS_H__ */

5032
hal/hal_halmac.c Normal file

File diff suppressed because it is too large Load Diff

240
hal/hal_halmac.h Normal file
View File

@ -0,0 +1,240 @@
/******************************************************************************
*
* Copyright(c) 2015 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#ifndef _HAL_HALMAC_H_
#define _HAL_HALMAC_H_
#include <drv_types.h> /* adapter_to_dvobj(), struct intf_hdl and etc. */
#include <hal_data.h> /* struct hal_spec_t */
#include "halmac/halmac_api.h" /* struct halmac_adapter* and etc. */
/* HALMAC Definition for Driver */
#define RTW_HALMAC_H2C_MAX_SIZE 8
#define RTW_HALMAC_BA_SSN_RPT_SIZE 4
#define dvobj_set_halmac(d, mac) ((d)->halmac = (mac))
#define dvobj_to_halmac(d) ((struct halmac_adapter *)((d)->halmac))
#define adapter_to_halmac(p) dvobj_to_halmac(adapter_to_dvobj(p))
/* for H2C cmd */
#define MAX_H2C_BOX_NUMS 4
#define MESSAGE_BOX_SIZE 4
#define EX_MESSAGE_BOX_SIZE 4
typedef enum _RTW_HALMAC_MODE {
RTW_HALMAC_MODE_NORMAL,
RTW_HALMAC_MODE_WIFI_TEST,
} RTW_HALMAC_MODE;
union rtw_phy_para_data {
struct _mac {
u32 value; /* value to be set in bit mask(msk) */
u32 msk; /* bit mask */
u16 offset; /* address */
u8 msk_en; /* 0/1 for msk invalid/valid */
u8 size; /* Unit is bytes, and value should be 1/2/4 */
} mac;
struct _bb {
u32 value;
u32 msk;
u16 offset;
u8 msk_en;
u8 size;
} bb;
struct _rf {
u32 value;
u32 msk;
u8 offset;
u8 msk_en;
/*
* 0: path A
* 1: path B
* 2: path C
* 3: path D
*/
u8 path;
} rf;
struct _delay {
/*
* 0: microsecond (us)
* 1: millisecond (ms)
*/
u8 unit;
u16 value;
} delay;
};
struct rtw_phy_parameter {
/*
* 0: MAC register
* 1: BB register
* 2: RF register
* 3: Delay
* 0xFF: Latest(End) command
*/
u8 cmd;
union rtw_phy_para_data data;
};
struct rtw_halmac_bcn_ctrl {
u8 rx_bssid_fit:1; /* 0:HW handle beacon, 1:ignore */
u8 txbcn_rpt:1; /* Enable TXBCN report in ad hoc and AP mode */
u8 tsf_update:1; /* Update TSF when beacon or probe response */
u8 enable_bcn:1; /* Enable beacon related functions */
u8 rxbcn_rpt:1; /* Enable RXBCNOK report */
u8 p2p_ctwin:1; /* Enable P2P CTN WINDOWS function */
u8 p2p_bcn_area:1; /* Enable P2P BCN area on function */
};
extern struct halmac_platform_api rtw_halmac_platform_api;
/* HALMAC API for Driver(HAL) */
u8 rtw_halmac_read8(struct intf_hdl *, u32 addr);
u16 rtw_halmac_read16(struct intf_hdl *, u32 addr);
u32 rtw_halmac_read32(struct intf_hdl *, u32 addr);
void rtw_halmac_read_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
#ifdef CONFIG_SDIO_INDIRECT_ACCESS
u8 rtw_halmac_iread8(struct intf_hdl *pintfhdl, u32 addr);
u16 rtw_halmac_iread16(struct intf_hdl *pintfhdl, u32 addr);
u32 rtw_halmac_iread32(struct intf_hdl *pintfhdl, u32 addr);
#endif /* CONFIG_SDIO_INDIRECT_ACCESS */
int rtw_halmac_write8(struct intf_hdl *, u32 addr, u8 value);
int rtw_halmac_write16(struct intf_hdl *, u32 addr, u16 value);
int rtw_halmac_write32(struct intf_hdl *, u32 addr, u32 value);
/* Software Information */
void rtw_halmac_get_version(char *str, u32 len);
/* Software Initialization */
int rtw_halmac_init_adapter(struct dvobj_priv *d, struct halmac_platform_api *pf_api);
int rtw_halmac_deinit_adapter(struct dvobj_priv *);
/* Get operations */
int rtw_halmac_get_hw_value(struct dvobj_priv *d, enum halmac_hw_id hw_id, void *pvalue);
int rtw_halmac_get_tx_fifo_size(struct dvobj_priv *d, u32 *size);
int rtw_halmac_get_rx_fifo_size(struct dvobj_priv *d, u32 *size);
int rtw_halmac_get_rsvd_drv_pg_bndy(struct dvobj_priv *d, u16 *bndy);
int rtw_halmac_get_page_size(struct dvobj_priv *d, u32 *size);
int rtw_halmac_get_tx_agg_align_size(struct dvobj_priv *d, u16 *size);
int rtw_halmac_get_rx_agg_align_size(struct dvobj_priv *d, u8 *size);
int rtw_halmac_get_rx_drv_info_sz(struct dvobj_priv *, u8 *sz);
int rtw_halmac_get_tx_desc_size(struct dvobj_priv *d, u32 *size);
int rtw_halmac_get_rx_desc_size(struct dvobj_priv *d, u32 *size);
int rtw_halmac_get_ori_h2c_size(struct dvobj_priv *d, u32 *size);
int rtw_halmac_get_oqt_size(struct dvobj_priv *d, u8 *size);
int rtw_halmac_get_ac_queue_number(struct dvobj_priv *d, u8 *num);
int rtw_halmac_get_mac_address(struct dvobj_priv *d, enum _hw_port hwport, u8 *addr);
int rtw_halmac_get_network_type(struct dvobj_priv *d, enum _hw_port hwport, u8 *type);
int rtw_halmac_get_bcn_ctrl(struct dvobj_priv *d, enum _hw_port hwport, struct rtw_halmac_bcn_ctrl *bcn_ctrl);
/*int rtw_halmac_get_wow_reason(struct dvobj_priv *, u8 *reason);*/
/* Set operations */
int rtw_halmac_config_rx_info(struct dvobj_priv *d, enum halmac_drv_info info);
int rtw_halmac_set_max_dl_fw_size(struct dvobj_priv *d, u32 size);
int rtw_halmac_set_mac_address(struct dvobj_priv *d, enum _hw_port hwport, u8 *addr);
int rtw_halmac_set_bssid(struct dvobj_priv *d, enum _hw_port hwport, u8 *addr);
int rtw_halmac_set_tx_address(struct dvobj_priv *d, enum _hw_port hwport, u8 *addr);
int rtw_halmac_set_network_type(struct dvobj_priv *d, enum _hw_port hwport, u8 type);
int rtw_halmac_reset_tsf(struct dvobj_priv *d, enum _hw_port hwport);
int rtw_halmac_set_bcn_interval(struct dvobj_priv *d, enum _hw_port hwport, u32 space);
int rtw_halmac_set_bcn_ctrl(struct dvobj_priv *d, enum _hw_port hwport, struct rtw_halmac_bcn_ctrl *bcn_ctrl);
int rtw_halmac_set_aid(struct dvobj_priv *d, enum _hw_port hwport, u16 aid);
int rtw_halmac_set_bandwidth(struct dvobj_priv *d, u8 channel, u8 pri_ch_idx, u8 bw);
int rtw_halmac_set_edca(struct dvobj_priv *d, u8 queue, u8 aifs, u8 cw, u16 txop);
/* Functions */
int rtw_halmac_poweron(struct dvobj_priv *);
int rtw_halmac_poweroff(struct dvobj_priv *);
int rtw_halmac_init_hal(struct dvobj_priv *);
int rtw_halmac_init_hal_fw(struct dvobj_priv *, u8 *fw, u32 fwsize);
int rtw_halmac_init_hal_fw_file(struct dvobj_priv *, u8 *fwpath);
int rtw_halmac_deinit_hal(struct dvobj_priv *);
int rtw_halmac_self_verify(struct dvobj_priv *);
int rtw_halmac_txfifo_wait_empty(struct dvobj_priv *d, u32 timeout);
int rtw_halmac_dlfw(struct dvobj_priv *, u8 *fw, u32 fwsize);
int rtw_halmac_dlfw_from_file(struct dvobj_priv *, u8 *fwpath);
int rtw_halmac_dlfw_mem(struct dvobj_priv *d, u8 *fw, u32 fwsize, enum fw_mem mem);
int rtw_halmac_dlfw_mem_from_file(struct dvobj_priv *d, u8 *fwpath, enum fw_mem mem);
int rtw_halmac_phy_power_switch(struct dvobj_priv *, u8 enable);
int rtw_halmac_send_h2c(struct dvobj_priv *, u8 *h2c);
int rtw_halmac_c2h_handle(struct dvobj_priv *, u8 *c2h, u32 size);
/* eFuse */
int rtw_halmac_get_available_efuse_size(struct dvobj_priv *d, u32 *size);
int rtw_halmac_get_physical_efuse_size(struct dvobj_priv *, u32 *size);
int rtw_halmac_read_physical_efuse_map(struct dvobj_priv *, u8 *map, u32 size);
int rtw_halmac_read_physical_efuse(struct dvobj_priv *, u32 offset, u32 cnt, u8 *data);
int rtw_halmac_write_physical_efuse(struct dvobj_priv *, u32 offset, u32 cnt, u8 *data);
int rtw_halmac_get_logical_efuse_size(struct dvobj_priv *, u32 *size);
int rtw_halmac_read_logical_efuse_map(struct dvobj_priv *, u8 *map, u32 size, u8 *maskmap, u32 masksize);
int rtw_halmac_write_logical_efuse_map(struct dvobj_priv *, u8 *map, u32 size, u8 *maskmap, u32 masksize);
int rtw_halmac_read_logical_efuse(struct dvobj_priv *, u32 offset, u32 cnt, u8 *data);
int rtw_halmac_write_logical_efuse(struct dvobj_priv *, u32 offset, u32 cnt, u8 *data);
int rtw_halmac_write_bt_physical_efuse(struct dvobj_priv *, u32 offset, u32 cnt, u8 *data);
int rtw_halmac_read_bt_physical_efuse_map(struct dvobj_priv *, u8 *map, u32 size);
int rtw_halmac_dump_fifo(struct dvobj_priv *d, u8 fifo_sel, u32 addr, u32 size, u8 *buffer);
int rtw_halmac_rx_agg_switch(struct dvobj_priv *, u8 enable);
/* Specific function APIs*/
int rtw_halmac_download_rsvd_page(struct dvobj_priv *dvobj, u8 pg_offset, u8 *pbuf, u32 size);
int rtw_halmac_fill_hal_spec(struct dvobj_priv *, struct hal_spec_t *);
int rtw_halmac_p2pps(struct dvobj_priv *dvobj, PHAL_P2P_PS_PARA pp2p_ps_para);
int rtw_halmac_iqk(struct dvobj_priv *d, u8 clear, u8 segment);
int rtw_halmac_cfg_phy_para(struct dvobj_priv *d, struct rtw_phy_parameter *para);
int rtw_halmac_led_cfg(struct dvobj_priv *d, u8 enable, u8 mode);
void rtw_halmac_led_switch(struct dvobj_priv *d, u8 on);
#ifdef CONFIG_SDIO_HCI
int rtw_halmac_query_tx_page_num(struct dvobj_priv *);
int rtw_halmac_get_tx_queue_page_num(struct dvobj_priv *, u8 queue, u32 *page);
u32 rtw_halmac_sdio_get_tx_addr(struct dvobj_priv *, u8 *desc, u32 size);
int rtw_halmac_sdio_tx_allowed(struct dvobj_priv *, u8 *buf, u32 size);
u32 rtw_halmac_sdio_get_rx_addr(struct dvobj_priv *, u8 *seq);
#endif /* CONFIG_SDIO_HCI */
#ifdef CONFIG_USB_HCI
u8 rtw_halmac_usb_get_bulkout_id(struct dvobj_priv *, u8 *buf, u32 size);
int rtw_halmac_usb_get_txagg_desc_num(struct dvobj_priv *d, u8 *num);
u8 rtw_halmac_switch_usb_mode(struct dvobj_priv *d, enum RTW_USB_SPEED usb_mode);
#endif /* CONFIG_USB_HCI */
#ifdef CONFIG_SUPPORT_TRX_SHARED
void dump_trx_share_mode(void *sel, _adapter *adapter);
#endif
#ifdef CONFIG_BEAMFORMING
#ifdef RTW_BEAMFORMING_VERSION_2
int rtw_halmac_bf_add_mu_bfer(struct dvobj_priv *d, u16 paid, u16 csi_para,
u16 my_aid, enum halmac_csi_seg_len sel, u8 *addr);
int rtw_halmac_bf_del_mu_bfer(struct dvobj_priv *d);
int rtw_halmac_bf_cfg_sounding(struct dvobj_priv *d, enum halmac_snd_role role,
enum halmac_data_rate rate);
int rtw_halmac_bf_del_sounding(struct dvobj_priv *d, enum halmac_snd_role role);
int rtw_halmac_bf_cfg_csi_rate(struct dvobj_priv *d, u8 rssi, u8 current_rate,
u8 fixrate_en, u8 *new_rate);
int rtw_halmac_bf_cfg_mu_mimo(struct dvobj_priv *d, enum halmac_snd_role role,
u8 *sounding_sts, u16 grouping_bitmap, u8 mu_tx_en,
u32 *given_gid_tab, u32 *given_user_pos);
#define rtw_halmac_bf_cfg_mu_bfee(d, gid_tab, user_pos) \
rtw_halmac_bf_cfg_mu_mimo(d, HAL_BFEE, NULL, 0, 0, gid_tab, user_pos)
#endif /* RTW_BEAMFORMING_VERSION_2 */
#endif /* CONFIG_BEAMFORMING */
#endif /* _HAL_HALMAC_H_ */

524
hal/hal_hci/hal_usb.c Normal file
View File

@ -0,0 +1,524 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#define _HAL_USB_C_
#include <drv_types.h>
#include <hal_data.h>
int usb_init_recv_priv(_adapter *padapter, u16 ini_in_buf_sz)
{
struct recv_priv *precvpriv = &padapter->recvpriv;
int i, res = _SUCCESS;
struct recv_buf *precvbuf;
#ifdef PLATFORM_LINUX
tasklet_init(&precvpriv->recv_tasklet,
(void(*)(unsigned long))usb_recv_tasklet,
(unsigned long)padapter);
#endif /* PLATFORM_LINUX */
#ifdef PLATFORM_FREEBSD
#ifdef CONFIG_RX_INDICATE_QUEUE
TASK_INIT(&precvpriv->rx_indicate_tasklet, 0, rtw_rx_indicate_tasklet, padapter);
#endif /* CONFIG_RX_INDICATE_QUEUE */
#endif /* PLATFORM_FREEBSD */
#ifdef CONFIG_USB_INTERRUPT_IN_PIPE
#ifdef PLATFORM_LINUX
precvpriv->int_in_urb = usb_alloc_urb(0, GFP_KERNEL);
if (precvpriv->int_in_urb == NULL) {
res = _FAIL;
RTW_INFO("alloc_urb for interrupt in endpoint fail !!!!\n");
goto exit;
}
#endif /* PLATFORM_LINUX */
precvpriv->int_in_buf = rtw_zmalloc(ini_in_buf_sz);
if (precvpriv->int_in_buf == NULL) {
res = _FAIL;
RTW_INFO("alloc_mem for interrupt in endpoint fail !!!!\n");
goto exit;
}
#endif /* CONFIG_USB_INTERRUPT_IN_PIPE */
/* init recv_buf */
_rtw_init_queue(&precvpriv->free_recv_buf_queue);
_rtw_init_queue(&precvpriv->recv_buf_pending_queue);
#ifndef CONFIG_USE_USB_BUFFER_ALLOC_RX
/* this is used only when RX_IOBUF is sk_buff */
skb_queue_head_init(&precvpriv->free_recv_skb_queue);
#endif
RTW_INFO("NR_RECVBUFF: %d\n", NR_RECVBUFF);
RTW_INFO("MAX_RECVBUF_SZ: %d\n", MAX_RECVBUF_SZ);
precvpriv->pallocated_recv_buf = rtw_zmalloc(NR_RECVBUFF * sizeof(struct recv_buf) + 4);
if (precvpriv->pallocated_recv_buf == NULL) {
res = _FAIL;
goto exit;
}
precvpriv->precv_buf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(precvpriv->pallocated_recv_buf), 4);
precvbuf = (struct recv_buf *)precvpriv->precv_buf;
for (i = 0; i < NR_RECVBUFF ; i++) {
_rtw_init_listhead(&precvbuf->list);
_rtw_spinlock_init(&precvbuf->recvbuf_lock);
precvbuf->alloc_sz = MAX_RECVBUF_SZ;
res = rtw_os_recvbuf_resource_alloc(padapter, precvbuf);
if (res == _FAIL)
break;
precvbuf->ref_cnt = 0;
precvbuf->adapter = padapter;
/* rtw_list_insert_tail(&precvbuf->list, &(precvpriv->free_recv_buf_queue.queue)); */
precvbuf++;
}
precvpriv->free_recv_buf_queue_cnt = NR_RECVBUFF;
#if defined(PLATFORM_LINUX) || defined(PLATFORM_FREEBSD)
skb_queue_head_init(&precvpriv->rx_skb_queue);
#ifdef CONFIG_RX_INDICATE_QUEUE
memset(&precvpriv->rx_indicate_queue, 0, sizeof(struct ifqueue));
mtx_init(&precvpriv->rx_indicate_queue.ifq_mtx, "rx_indicate_queue", NULL, MTX_DEF);
#endif /* CONFIG_RX_INDICATE_QUEUE */
#ifdef CONFIG_PREALLOC_RECV_SKB
{
int i;
SIZE_PTR tmpaddr = 0;
SIZE_PTR alignment = 0;
struct sk_buff *pskb = NULL;
RTW_INFO("NR_PREALLOC_RECV_SKB: %d\n", NR_PREALLOC_RECV_SKB);
#ifdef CONFIG_FIX_NR_BULKIN_BUFFER
RTW_INFO("Enable CONFIG_FIX_NR_BULKIN_BUFFER\n");
#endif
for (i = 0; i < NR_PREALLOC_RECV_SKB; i++) {
#ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
pskb = rtw_alloc_skb_premem(MAX_RECVBUF_SZ);
#else
pskb = rtw_skb_alloc(MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ);
#endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
if (pskb) {
#ifdef PLATFORM_FREEBSD
pskb->dev = padapter->pifp;
#else
pskb->dev = padapter->pnetdev;
#endif /* PLATFORM_FREEBSD */
#ifndef CONFIG_PREALLOC_RX_SKB_BUFFER
tmpaddr = (SIZE_PTR)pskb->data;
alignment = tmpaddr & (RECVBUFF_ALIGN_SZ - 1);
skb_reserve(pskb, (RECVBUFF_ALIGN_SZ - alignment));
#endif
skb_queue_tail(&precvpriv->free_recv_skb_queue, pskb);
}
}
}
#endif /* CONFIG_PREALLOC_RECV_SKB */
#endif /* defined(PLATFORM_LINUX) || defined(PLATFORM_FREEBSD) */
exit:
return res;
}
void usb_free_recv_priv(_adapter *padapter, u16 ini_in_buf_sz)
{
int i;
struct recv_buf *precvbuf;
struct recv_priv *precvpriv = &padapter->recvpriv;
precvbuf = (struct recv_buf *)precvpriv->precv_buf;
for (i = 0; i < NR_RECVBUFF ; i++) {
rtw_os_recvbuf_resource_free(padapter, precvbuf);
precvbuf++;
}
if (precvpriv->pallocated_recv_buf)
rtw_mfree(precvpriv->pallocated_recv_buf, NR_RECVBUFF * sizeof(struct recv_buf) + 4);
#ifdef CONFIG_USB_INTERRUPT_IN_PIPE
#ifdef PLATFORM_LINUX
if (precvpriv->int_in_urb)
usb_free_urb(precvpriv->int_in_urb);
#endif
if (precvpriv->int_in_buf)
rtw_mfree(precvpriv->int_in_buf, ini_in_buf_sz);
#endif /* CONFIG_USB_INTERRUPT_IN_PIPE */
#ifdef PLATFORM_LINUX
if (skb_queue_len(&precvpriv->rx_skb_queue))
RTW_WARN("rx_skb_queue not empty\n");
rtw_skb_queue_purge(&precvpriv->rx_skb_queue);
if (skb_queue_len(&precvpriv->free_recv_skb_queue))
RTW_WARN("free_recv_skb_queue not empty, %d\n", skb_queue_len(&precvpriv->free_recv_skb_queue));
#if !defined(CONFIG_USE_USB_BUFFER_ALLOC_RX)
#if defined(CONFIG_PREALLOC_RECV_SKB) && defined(CONFIG_PREALLOC_RX_SKB_BUFFER)
{
struct sk_buff *skb;
while ((skb = skb_dequeue(&precvpriv->free_recv_skb_queue)) != NULL) {
if (rtw_free_skb_premem(skb) != 0)
rtw_skb_free(skb);
}
}
#else
rtw_skb_queue_purge(&precvpriv->free_recv_skb_queue);
#endif /* defined(CONFIG_PREALLOC_RX_SKB_BUFFER) && defined(CONFIG_PREALLOC_RECV_SKB) */
#endif /* !defined(CONFIG_USE_USB_BUFFER_ALLOC_RX) */
#endif /* PLATFORM_LINUX */
#ifdef PLATFORM_FREEBSD
struct sk_buff *pskb;
while (NULL != (pskb = skb_dequeue(&precvpriv->rx_skb_queue)))
rtw_skb_free(pskb);
#if !defined(CONFIG_USE_USB_BUFFER_ALLOC_RX)
rtw_skb_queue_purge(&precvpriv->free_recv_skb_queue);
#endif
#ifdef CONFIG_RX_INDICATE_QUEUE
struct mbuf *m;
for (;;) {
IF_DEQUEUE(&precvpriv->rx_indicate_queue, m);
if (m == NULL)
break;
rtw_os_pkt_free(m);
}
mtx_destroy(&precvpriv->rx_indicate_queue.ifq_mtx);
#endif /* CONFIG_RX_INDICATE_QUEUE */
#endif /* PLATFORM_FREEBSD */
}
#ifdef CONFIG_FW_C2H_REG
void usb_c2h_hisr_hdl(_adapter *adapter, u8 *buf)
{
u8 *c2h_evt = buf;
u8 id, seq, plen;
u8 *payload;
if (rtw_hal_c2h_reg_hdr_parse(adapter, buf, &id, &seq, &plen, &payload) != _SUCCESS)
return;
if (0)
RTW_PRINT("%s C2H == %d\n", __func__, id);
if (rtw_hal_c2h_id_handle_directly(adapter, id, seq, plen, payload)) {
/* Handle directly */
rtw_hal_c2h_handler(adapter, id, seq, plen, payload);
/* Replace with special pointer to trigger c2h_evt_clear only */
if (rtw_cbuf_push(adapter->evtpriv.c2h_queue, (void*)&adapter->evtpriv) != _SUCCESS)
RTW_ERR("%s rtw_cbuf_push fail\n", __func__);
} else {
c2h_evt = rtw_malloc(C2H_REG_LEN);
if (c2h_evt != NULL) {
_rtw_memcpy(c2h_evt, buf, C2H_REG_LEN);
if (rtw_cbuf_push(adapter->evtpriv.c2h_queue, (void*)c2h_evt) != _SUCCESS)
RTW_ERR("%s rtw_cbuf_push fail\n", __func__);
} else {
/* Error handling for malloc fail */
if (rtw_cbuf_push(adapter->evtpriv.c2h_queue, (void*)NULL) != _SUCCESS)
RTW_ERR("%s rtw_cbuf_push fail\n", __func__);
}
}
_set_workitem(&adapter->evtpriv.c2h_wk);
}
#endif
#ifdef CONFIG_USB_SUPPORT_ASYNC_VDN_REQ
int usb_write_async(struct usb_device *udev, u32 addr, void *pdata, u16 len)
{
u8 request;
u8 requesttype;
u16 wvalue;
u16 index;
int ret;
requesttype = VENDOR_WRITE;/* write_out */
request = REALTEK_USB_VENQT_CMD_REQ;
index = REALTEK_USB_VENQT_CMD_IDX;/* n/a */
wvalue = (u16)(addr & 0x0000ffff);
ret = _usbctrl_vendorreq_async_write(udev, request, wvalue, index, pdata, len, requesttype);
return ret;
}
int usb_async_write8(struct intf_hdl *pintfhdl, u32 addr, u8 val)
{
u8 data;
int ret;
struct dvobj_priv *pdvobjpriv = (struct dvobj_priv *)pintfhdl->pintf_dev;
struct usb_device *udev = pdvobjpriv->pusbdev;
data = val;
ret = usb_write_async(udev, addr, &data, 1);
return ret;
}
int usb_async_write16(struct intf_hdl *pintfhdl, u32 addr, u16 val)
{
u16 data;
int ret;
struct dvobj_priv *pdvobjpriv = (struct dvobj_priv *)pintfhdl->pintf_dev;
struct usb_device *udev = pdvobjpriv->pusbdev;
data = val;
ret = usb_write_async(udev, addr, &data, 2);
return ret;
}
int usb_async_write32(struct intf_hdl *pintfhdl, u32 addr, u32 val)
{
u32 data;
int ret;
struct dvobj_priv *pdvobjpriv = (struct dvobj_priv *)pintfhdl->pintf_dev;
struct usb_device *udev = pdvobjpriv->pusbdev;
data = val;
ret = usb_write_async(udev, addr, &data, 4);
return ret;
}
#endif /* CONFIG_USB_SUPPORT_ASYNC_VDN_REQ */
u8 usb_read8(struct intf_hdl *pintfhdl, u32 addr)
{
u8 request;
u8 requesttype;
u16 wvalue;
u16 index;
u16 len;
u8 data = 0;
request = 0x05;
requesttype = 0x01;/* read_in */
index = 0;/* n/a */
wvalue = (u16)(addr & 0x0000ffff);
len = 1;
usbctrl_vendorreq(pintfhdl, request, wvalue, index,
&data, len, requesttype);
return data;
}
u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr)
{
u8 request;
u8 requesttype;
u16 wvalue;
u16 index;
u16 len;
u16 data = 0;
request = 0x05;
requesttype = 0x01;/* read_in */
index = 0;/* n/a */
wvalue = (u16)(addr & 0x0000ffff);
len = 2;
usbctrl_vendorreq(pintfhdl, request, wvalue, index,
&data, len, requesttype);
return data;
}
u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
{
u8 request;
u8 requesttype;
u16 wvalue;
u16 index;
u16 len;
u32 data = 0;
request = 0x05;
requesttype = 0x01;/* read_in */
index = 0;/* n/a */
wvalue = (u16)(addr & 0x0000ffff);
len = 4;
usbctrl_vendorreq(pintfhdl, request, wvalue, index,
&data, len, requesttype);
return data;
}
int usb_write8(struct intf_hdl *pintfhdl, u32 addr, u8 val)
{
u8 request;
u8 requesttype;
u16 wvalue;
u16 index;
u16 len;
u8 data;
int ret;
request = 0x05;
requesttype = 0x00;/* write_out */
index = 0;/* n/a */
wvalue = (u16)(addr & 0x0000ffff);
len = 1;
data = val;
ret = usbctrl_vendorreq(pintfhdl, request, wvalue, index,
&data, len, requesttype);
return ret;
}
int usb_write16(struct intf_hdl *pintfhdl, u32 addr, u16 val)
{
u8 request;
u8 requesttype;
u16 wvalue;
u16 index;
u16 len;
u16 data;
int ret;
request = 0x05;
requesttype = 0x00;/* write_out */
index = 0;/* n/a */
wvalue = (u16)(addr & 0x0000ffff);
len = 2;
data = val;
ret = usbctrl_vendorreq(pintfhdl, request, wvalue, index,
&data, len, requesttype);
return ret;
}
int usb_write32(struct intf_hdl *pintfhdl, u32 addr, u32 val)
{
u8 request;
u8 requesttype;
u16 wvalue;
u16 index;
u16 len;
u32 data;
int ret;
request = 0x05;
requesttype = 0x00;/* write_out */
index = 0;/* n/a */
wvalue = (u16)(addr & 0x0000ffff);
len = 4;
data = val;
ret = usbctrl_vendorreq(pintfhdl, request, wvalue, index,
&data, len, requesttype);
return ret;
}
int usb_writeN(struct intf_hdl *pintfhdl, u32 addr, u32 length, u8 *pdata)
{
u8 request;
u8 requesttype;
u16 wvalue;
u16 index;
u16 len;
u8 buf[VENDOR_CMD_MAX_DATA_LEN] = {0};
int ret;
request = 0x05;
requesttype = 0x00;/* write_out */
index = 0;/* n/a */
wvalue = (u16)(addr & 0x0000ffff);
len = length;
_rtw_memcpy(buf, pdata, len);
ret = usbctrl_vendorreq(pintfhdl, request, wvalue, index,
buf, len, requesttype);
return ret;
}
void usb_set_intf_ops(_adapter *padapter, struct _io_ops *pops)
{
_rtw_memset((u8 *)pops, 0, sizeof(struct _io_ops));
pops->_read8 = &usb_read8;
pops->_read16 = &usb_read16;
pops->_read32 = &usb_read32;
pops->_read_mem = &usb_read_mem;
pops->_read_port = &usb_read_port;
pops->_write8 = &usb_write8;
pops->_write16 = &usb_write16;
pops->_write32 = &usb_write32;
pops->_writeN = &usb_writeN;
#ifdef CONFIG_USB_SUPPORT_ASYNC_VDN_REQ
pops->_write8_async = &usb_async_write8;
pops->_write16_async = &usb_async_write16;
pops->_write32_async = &usb_async_write32;
#endif
pops->_write_mem = &usb_write_mem;
pops->_write_port = &usb_write_port;
pops->_read_port_cancel = &usb_read_port_cancel;
pops->_write_port_cancel = &usb_write_port_cancel;
#ifdef CONFIG_USB_INTERRUPT_IN_PIPE
pops->_read_interrupt = &usb_read_interrupt;
#endif
}

1569
hal/hal_intf.c Normal file

File diff suppressed because it is too large Load Diff

3309
hal/hal_mcc.c Normal file

File diff suppressed because it is too large Load Diff

2270
hal/hal_mp.c Normal file

File diff suppressed because it is too large Load Diff

257
hal/hal_phy.c Normal file
View File

@ -0,0 +1,257 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#define _HAL_PHY_C_
#include <drv_types.h>
/**
* Function: PHY_CalculateBitShift
*
* OverView: Get shifted position of the BitMask
*
* Input:
* u4Byte BitMask,
*
* Output: none
* Return: u4Byte Return the shift bit bit position of the mask
*/
u32
PHY_CalculateBitShift(
u32 BitMask
)
{
u32 i;
for (i = 0; i <= 31; i++) {
if (((BitMask >> i) & 0x1) == 1)
break;
}
return i;
}
#ifdef CONFIG_RF_SHADOW_RW
/* ********************************************************************************
* Constant.
* ********************************************************************************
* 2008/11/20 MH For Debug only, RF */
static RF_SHADOW_T RF_Shadow[RF6052_MAX_PATH][RF6052_MAX_REG];
/*
* ==> RF shadow Operation API Code Section!!!
*
*-----------------------------------------------------------------------------
* Function: PHY_RFShadowRead
* PHY_RFShadowWrite
* PHY_RFShadowCompare
* PHY_RFShadowRecorver
* PHY_RFShadowCompareAll
* PHY_RFShadowRecorverAll
* PHY_RFShadowCompareFlagSet
* PHY_RFShadowRecorverFlagSet
*
* Overview: When we set RF register, we must write shadow at first.
* When we are running, we must compare shadow abd locate error addr.
* Decide to recorver or not.
*
* Input: NONE
*
* Output: NONE
*
* Return: NONE
*
* Revised History:
* When Who Remark
* 11/20/2008 MHC Create Version 0.
*
*---------------------------------------------------------------------------*/
u32
PHY_RFShadowRead(
IN PADAPTER Adapter,
IN enum rf_path eRFPath,
IN u32 Offset)
{
return RF_Shadow[eRFPath][Offset].Value;
} /* PHY_RFShadowRead */
VOID
PHY_RFShadowWrite(
IN PADAPTER Adapter,
IN enum rf_path eRFPath,
IN u32 Offset,
IN u32 Data)
{
RF_Shadow[eRFPath][Offset].Value = (Data & bRFRegOffsetMask);
RF_Shadow[eRFPath][Offset].Driver_Write = _TRUE;
} /* PHY_RFShadowWrite */
BOOLEAN
PHY_RFShadowCompare(
IN PADAPTER Adapter,
IN enum rf_path eRFPath,
IN u32 Offset)
{
u32 reg;
/* Check if we need to check the register */
if (RF_Shadow[eRFPath][Offset].Compare == _TRUE) {
reg = rtw_hal_read_rfreg(Adapter, eRFPath, Offset, bRFRegOffsetMask);
/* Compare shadow and real rf register for 20bits!! */
if (RF_Shadow[eRFPath][Offset].Value != reg) {
/* Locate error position. */
RF_Shadow[eRFPath][Offset].ErrorOrNot = _TRUE;
}
return RF_Shadow[eRFPath][Offset].ErrorOrNot ;
}
return _FALSE;
} /* PHY_RFShadowCompare */
VOID
PHY_RFShadowRecorver(
IN PADAPTER Adapter,
IN enum rf_path eRFPath,
IN u32 Offset)
{
/* Check if the address is error */
if (RF_Shadow[eRFPath][Offset].ErrorOrNot == _TRUE) {
/* Check if we need to recorver the register. */
if (RF_Shadow[eRFPath][Offset].Recorver == _TRUE) {
rtw_hal_write_rfreg(Adapter, eRFPath, Offset, bRFRegOffsetMask,
RF_Shadow[eRFPath][Offset].Value);
}
}
} /* PHY_RFShadowRecorver */
VOID
PHY_RFShadowCompareAll(
IN PADAPTER Adapter)
{
enum rf_path eRFPath = RF_PATH_A;
u32 Offset = 0, maxReg = GET_RF6052_REAL_MAX_REG(Adapter);
for (eRFPath = 0; eRFPath < RF6052_MAX_PATH; eRFPath++) {
for (Offset = 0; Offset < maxReg; Offset++)
PHY_RFShadowCompare(Adapter, eRFPath, Offset);
}
} /* PHY_RFShadowCompareAll */
VOID
PHY_RFShadowRecorverAll(
IN PADAPTER Adapter)
{
enum rf_path eRFPath = RF_PATH_A;
u32 Offset = 0, maxReg = GET_RF6052_REAL_MAX_REG(Adapter);
for (eRFPath = 0; eRFPath < RF6052_MAX_PATH; eRFPath++) {
for (Offset = 0; Offset < maxReg; Offset++)
PHY_RFShadowRecorver(Adapter, eRFPath, Offset);
}
} /* PHY_RFShadowRecorverAll */
VOID
PHY_RFShadowCompareFlagSet(
IN PADAPTER Adapter,
IN enum rf_path eRFPath,
IN u32 Offset,
IN u8 Type)
{
/* Set True or False!!! */
RF_Shadow[eRFPath][Offset].Compare = Type;
} /* PHY_RFShadowCompareFlagSet */
VOID
PHY_RFShadowRecorverFlagSet(
IN PADAPTER Adapter,
IN enum rf_path eRFPath,
IN u32 Offset,
IN u8 Type)
{
/* Set True or False!!! */
RF_Shadow[eRFPath][Offset].Recorver = Type;
} /* PHY_RFShadowRecorverFlagSet */
VOID
PHY_RFShadowCompareFlagSetAll(
IN PADAPTER Adapter)
{
enum rf_path eRFPath = RF_PATH_A;
u32 Offset = 0, maxReg = GET_RF6052_REAL_MAX_REG(Adapter);
for (eRFPath = 0; eRFPath < RF6052_MAX_PATH; eRFPath++) {
for (Offset = 0; Offset < maxReg; Offset++) {
/* 2008/11/20 MH For S3S4 test, we only check reg 26/27 now!!!! */
if (Offset != 0x26 && Offset != 0x27)
PHY_RFShadowCompareFlagSet(Adapter, eRFPath, Offset, _FALSE);
else
PHY_RFShadowCompareFlagSet(Adapter, eRFPath, Offset, _TRUE);
}
}
} /* PHY_RFShadowCompareFlagSetAll */
VOID
PHY_RFShadowRecorverFlagSetAll(
IN PADAPTER Adapter)
{
enum rf_path eRFPath = RF_PATH_A;
u32 Offset = 0, maxReg = GET_RF6052_REAL_MAX_REG(Adapter);
for (eRFPath = 0; eRFPath < RF6052_MAX_PATH; eRFPath++) {
for (Offset = 0; Offset < maxReg; Offset++) {
/* 2008/11/20 MH For S3S4 test, we only check reg 26/27 now!!!! */
if (Offset != 0x26 && Offset != 0x27)
PHY_RFShadowRecorverFlagSet(Adapter, eRFPath, Offset, _FALSE);
else
PHY_RFShadowRecorverFlagSet(Adapter, eRFPath, Offset, _TRUE);
}
}
} /* PHY_RFShadowCompareFlagSetAll */
VOID
PHY_RFShadowRefresh(
IN PADAPTER Adapter)
{
enum rf_path eRFPath = RF_PATH_A;
u32 Offset = 0, maxReg = GET_RF6052_REAL_MAX_REG(Adapter);
for (eRFPath = 0; eRFPath < RF6052_MAX_PATH; eRFPath++) {
for (Offset = 0; Offset < maxReg; Offset++) {
RF_Shadow[eRFPath][Offset].Value = 0;
RF_Shadow[eRFPath][Offset].Compare = _FALSE;
RF_Shadow[eRFPath][Offset].Recorver = _FALSE;
RF_Shadow[eRFPath][Offset].ErrorOrNot = _FALSE;
RF_Shadow[eRFPath][Offset].Driver_Write = _FALSE;
}
}
} /* PHY_RFShadowRead */
#endif /*CONFIG_RF_SHADOW_RW*/

254
hal/led/hal_led.c Normal file
View File

@ -0,0 +1,254 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#include <drv_types.h>
#include <hal_data.h>
#ifdef CONFIG_RTW_LED
void dump_led_config(void *sel, _adapter *adapter)
{
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
struct led_priv *ledpriv = adapter_to_led(adapter);
int i;
RTW_PRINT_SEL(sel, "strategy:%u\n", ledpriv->LedStrategy);
#ifdef CONFIG_RTW_SW_LED
RTW_PRINT_SEL(sel, "bRegUseLed:%u\n", ledpriv->bRegUseLed);
RTW_PRINT_SEL(sel, "iface_en_mask:0x%02X\n", ledpriv->iface_en_mask);
for (i = 0; i < dvobj->iface_nums; i++)
RTW_PRINT_SEL(sel, "ctl_en_mask[%d]:0x%08X\n", i, ledpriv->ctl_en_mask[i]);
#endif
}
void rtw_led_set_strategy(_adapter *adapter, u8 strategy)
{
struct led_priv *ledpriv = adapter_to_led(adapter);
_adapter *pri_adapter = GET_PRIMARY_ADAPTER(adapter);
#ifndef CONFIG_RTW_SW_LED
if (IS_SW_LED_STRATEGY(strategy)) {
RTW_WARN("CONFIG_RTW_SW_LED is not defined\n");
return;
}
#endif
#ifdef CONFIG_RTW_SW_LED
if (!ledpriv->bRegUseLed)
return;
#endif
if (ledpriv->LedStrategy == strategy)
return;
if (IS_HW_LED_STRATEGY(strategy) || IS_HW_LED_STRATEGY(ledpriv->LedStrategy)) {
RTW_WARN("switching on/off HW_LED strategy is not supported\n");
return;
}
ledpriv->LedStrategy = strategy;
#ifdef CONFIG_RTW_SW_LED
rtw_hal_sw_led_deinit(pri_adapter);
#endif
rtw_led_control(pri_adapter, RTW_LED_OFF);
}
#ifdef CONFIG_RTW_SW_LED
#if CONFIG_RTW_SW_LED_TRX_DA_CLASSIFY
void rtw_sw_led_blink_uc_trx_only(LED_DATA *led)
{
_adapter *adapter = led->padapter;
BOOLEAN bStopBlinking = _FALSE;
if (led->BlinkingLedState == RTW_LED_ON)
SwLedOn(adapter, led);
else
SwLedOff(adapter, led);
switch (led->CurrLedState) {
case RTW_LED_ON:
SwLedOn(adapter, led);
break;
case RTW_LED_OFF:
SwLedOff(adapter, led);
break;
case LED_BLINK_TXRX:
led->BlinkTimes--;
if (led->BlinkTimes == 0)
bStopBlinking = _TRUE;
if (adapter_to_pwrctl(adapter)->rf_pwrstate != rf_on
&& adapter_to_pwrctl(adapter)->rfoff_reason > RF_CHANGE_BY_PS
) {
SwLedOff(adapter, led);
led->bLedBlinkInProgress = _FALSE;
} else {
if (led->bLedOn)
led->BlinkingLedState = RTW_LED_OFF;
else
led->BlinkingLedState = RTW_LED_ON;
if (bStopBlinking) {
led->CurrLedState = RTW_LED_OFF;
led->bLedBlinkInProgress = _FALSE;
}
_set_timer(&(led->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
}
break;
default:
break;
}
}
void rtw_sw_led_ctl_mode_uc_trx_only(_adapter *adapter, LED_CTL_MODE ctl)
{
struct led_priv *ledpriv = adapter_to_led(adapter);
LED_DATA *led = &(ledpriv->SwLed0);
LED_DATA *led1 = &(ledpriv->SwLed1);
LED_DATA *led2 = &(ledpriv->SwLed2);
switch (ctl) {
case LED_CTL_UC_TX:
case LED_CTL_UC_RX:
if (led->bLedBlinkInProgress == _FALSE) {
led->bLedBlinkInProgress = _TRUE;
led->CurrLedState = LED_BLINK_TXRX;
led->BlinkTimes = 2;
if (led->bLedOn)
led->BlinkingLedState = RTW_LED_OFF;
else
led->BlinkingLedState = RTW_LED_ON;
_set_timer(&(led->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
}
break;
case LED_CTL_POWER_OFF:
led->CurrLedState = RTW_LED_OFF;
led->BlinkingLedState = RTW_LED_OFF;
if (led->bLedBlinkInProgress) {
_cancel_timer_ex(&(led->BlinkTimer));
led->bLedBlinkInProgress = _FALSE;
}
SwLedOff(adapter, led);
SwLedOff(adapter, led1);
SwLedOff(adapter, led2);
break;
default:
break;
}
}
#endif /* CONFIG_RTW_SW_LED_TRX_DA_CLASSIFY */
void rtw_led_control(_adapter *adapter, LED_CTL_MODE ctl)
{
struct led_priv *ledpriv = adapter_to_led(adapter);
if (ledpriv->LedControlHandler) {
#if CONFIG_RTW_SW_LED_TRX_DA_CLASSIFY
if (ledpriv->LedStrategy != SW_LED_MODE_UC_TRX_ONLY) {
if (ctl == LED_CTL_UC_TX || ctl == LED_CTL_BMC_TX) {
if (ledpriv->ctl_en_mask[adapter->iface_id] & BIT(LED_CTL_TX))
ctl = LED_CTL_TX; /* transform specific TX ctl to general TX ctl */
} else if (ctl == LED_CTL_UC_RX || ctl == LED_CTL_BMC_RX) {
if (ledpriv->ctl_en_mask[adapter->iface_id] & BIT(LED_CTL_RX))
ctl = LED_CTL_RX; /* transform specific RX ctl to general RX ctl */
}
}
#endif
if ((ledpriv->iface_en_mask & BIT(adapter->iface_id))
&& (ledpriv->ctl_en_mask[adapter->iface_id] & BIT(ctl)))
ledpriv->LedControlHandler(adapter, ctl);
}
}
void rtw_led_tx_control(_adapter *adapter, const u8 *da)
{
#if CONFIG_RTW_SW_LED_TRX_DA_CLASSIFY
if (IS_MCAST(da))
rtw_led_control(adapter, LED_CTL_BMC_TX);
else
rtw_led_control(adapter, LED_CTL_UC_TX);
#else
rtw_led_control(adapter, LED_CTL_TX);
#endif
}
void rtw_led_rx_control(_adapter *adapter, const u8 *da)
{
#if CONFIG_RTW_SW_LED_TRX_DA_CLASSIFY
if (IS_MCAST(da))
rtw_led_control(adapter, LED_CTL_BMC_RX);
else
rtw_led_control(adapter, LED_CTL_UC_RX);
#else
rtw_led_control(adapter, LED_CTL_RX);
#endif
}
void rtw_led_set_iface_en(_adapter *adapter, u8 en)
{
struct led_priv *ledpriv = adapter_to_led(adapter);
if (en)
ledpriv->iface_en_mask |= BIT(adapter->iface_id);
else
ledpriv->iface_en_mask &= ~BIT(adapter->iface_id);
}
void rtw_led_set_iface_en_mask(_adapter *adapter, u8 mask)
{
struct led_priv *ledpriv = adapter_to_led(adapter);
ledpriv->iface_en_mask = mask;
}
void rtw_led_set_ctl_en_mask(_adapter *adapter, u32 ctl_mask)
{
struct led_priv *ledpriv = adapter_to_led(adapter);
#if CONFIG_RTW_SW_LED_TRX_DA_CLASSIFY
if (ctl_mask & BIT(LED_CTL_TX))
ctl_mask |= BIT(LED_CTL_UC_TX) | BIT(LED_CTL_BMC_TX);
if (ctl_mask & BIT(LED_CTL_RX))
ctl_mask |= BIT(LED_CTL_UC_RX) | BIT(LED_CTL_BMC_RX);
#endif
ledpriv->ctl_en_mask[adapter->iface_id] = ctl_mask;
}
void rtw_led_set_ctl_en_mask_primary(_adapter *adapter)
{
rtw_led_set_ctl_en_mask(adapter, 0xFFFFFFFF);
}
void rtw_led_set_ctl_en_mask_virtual(_adapter *adapter)
{
rtw_led_set_ctl_en_mask(adapter
, BIT(LED_CTL_POWER_ON) | BIT(LED_CTL_POWER_OFF)
| BIT(LED_CTL_TX) | BIT(LED_CTL_RX)
);
}
#endif /* CONFIG_RTW_SW_LED */
#endif /* CONFIG_RTW_LED */

4290
hal/led/hal_usb_led.c Normal file

File diff suppressed because it is too large Load Diff

118
hal/phydm/ap_makefile.mk Normal file
View File

@ -0,0 +1,118 @@
_PHYDM_FILES :=\
phydm/phydm.o \
phydm/phydm_dig.o\
phydm/phydm_antdiv.o\
phydm/phydm_soml.o\
phydm/phydm_smt_ant.o\
phydm/phydm_pathdiv.o\
phydm/phydm_rainfo.o\
phydm/phydm_dynamictxpower.o\
phydm/phydm_adaptivity.o\
phydm/phydm_debug.o\
phydm/phydm_interface.o\
phydm/phydm_phystatus.o\
phydm/phydm_hwconfig.o\
phydm/phydm_dfs.o\
phydm/phydm_cfotracking.o\
phydm/phydm_adc_sampling.o\
phydm/phydm_ccx.o\
phydm/phydm_primary_cca.o\
phydm/phydm_cck_pd.o\
phydm/phydm_rssi_monitor.o\
phydm/phydm_auto_dbg.o\
phydm/phydm_math_lib.o\
phydm/phydm_noisemonitor.o\
phydm/phydm_api.o\
phydm/phydm_pow_train.o\
phydm/txbf/phydm_hal_txbf_api.o\
EdcaTurboCheck.o\
phydm/halrf/halrf.o\
phydm/halrf/halphyrf_ap.o\
phydm/halrf/halrf_powertracking_ap.o\
phydm/halrf/halrf_powertracking.o\
phydm/halrf/halrf_kfree.o
ifeq ($(CONFIG_RTL_88E_SUPPORT),y)
ifeq ($(CONFIG_RTL_ODM_WLAN_DRIVER),y)
_PHYDM_FILES += \
phydm/rtl8188e/halhwimg8188e_bb.o\
phydm/rtl8188e/halhwimg8188e_mac.o\
phydm/rtl8188e/halhwimg8188e_rf.o\
phydm/rtl8188e/phydm_regconfig8188e.o\
phydm/rtl8188e/hal8188erateadaptive.o\
phydm/rtl8188e/phydm_rtl8188e.o\
phydm/halrf/rtl8188e/halrf_8188e_ap.o
endif
endif
ifeq ($(CONFIG_RTL_8812_SUPPORT),y)
ifeq ($(CONFIG_RTL_ODM_WLAN_DRIVER),y)
_PHYDM_FILES += ./phydm/halrf/rtl8812a/halrf_8812a_ap.o
endif
endif
ifeq ($(CONFIG_WLAN_HAL_8881A),y)
_PHYDM_FILES += phydm/halrf/rtl8821a/halrf_iqk_8821a_ap.o
endif
ifeq ($(CONFIG_WLAN_HAL_8192EE),y)
_PHYDM_FILES += \
phydm/halrf/rtl8192e/halrf_8192e_ap.o\
phydm/rtl8192e/phydm_rtl8192e.o
endif
ifeq ($(CONFIG_WLAN_HAL_8814AE),y)
rtl8192cd-objs += phydm/halrf/rtl8814a/halrf_8814a_ap.o
rtl8192cd-objs += phydm/halrf/rtl8814a/halrf_iqk_8814a.o
ifeq ($(CONFIG_RTL_ODM_WLAN_DRIVER),y)
rtl8192cd-objs += \
phydm/rtl8814a/halhwimg8814a_bb.o\
phydm/rtl8814a/halhwimg8814a_mac.o\
phydm/rtl8814a/halhwimg8814a_rf.o\
phydm/rtl8814a/phydm_regconfig8814a.o\
phydm/rtl8814a/phydm_rtl8814a.o
endif
endif
ifeq ($(CONFIG_WLAN_HAL_8822BE),y)
_PHYDM_FILES += phydm/halrf/rtl8822b/halrf_8822b.o
_PHYDM_FILES += phydm/halrf/rtl8822b/halrf_iqk_8822b.o
ifeq ($(CONFIG_RTL_ODM_WLAN_DRIVER),y)
_PHYDM_FILES += \
phydm/rtl8822b/halhwimg8822b_bb.o\
phydm/rtl8822b/halhwimg8822b_mac.o\
phydm/rtl8822b/halhwimg8822b_rf.o\
phydm/rtl8822b/phydm_regconfig8822b.o\
phydm/rtl8822b/phydm_hal_api8822b.o\
phydm/rtl8822b/phydm_rtl8822b.o
endif
endif
ifeq ($(CONFIG_WLAN_HAL_8821CE),y)
_PHYDM_FILES += phydm/halrf/rtl8821c/halrf_8821c.o
_PHYDM_FILES += phydm/halrf/rtl8821c/halrf_iqk_8821c.o
ifeq ($(CONFIG_RTL_ODM_WLAN_DRIVER),y)
_PHYDM_FILES += \
phydm/rtl8821c/halhwimg8821c_bb.o\
phydm/rtl8821c/halhwimg8821c_mac.o\
phydm/rtl8821c/halhwimg8821c_rf.o\
phydm/rtl8821c/phydm_regconfig8821c.o\
phydm/rtl8821c/phydm_hal_api8821c.o
endif
endif
ifeq ($(CONFIG_WLAN_HAL_8197F),y)
_PHYDM_FILES += phydm/halrf/rtl8197f/halrf_8197f.o
_PHYDM_FILES += phydm/halrf/rtl8197f/halrf_iqk_8197f.o
_PHYDM_FILES += efuse_97f/efuse.o
ifeq ($(CONFIG_RTL_ODM_WLAN_DRIVER),y)
_PHYDM_FILES += \
phydm/rtl8197f/halhwimg8197f_bb.o\
phydm/rtl8197f/halhwimg8197f_mac.o\
phydm/rtl8197f/halhwimg8197f_rf.o\
phydm/rtl8197f/phydm_hal_api8197f.o\
phydm/rtl8197f/phydm_regconfig8197f.o\
phydm/rtl8197f/phydm_rtl8197f.o
endif
endif

137
hal/phydm/halhwimg.h Normal file
View File

@ -0,0 +1,137 @@
/******************************************************************************
*
* Copyright(c) 2016 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#pragma once
#ifndef __INC_HW_IMG_H
#define __INC_HW_IMG_H
/*
* 2011/03/15 MH Add for different IC HW image file selection. code size consideration.
* */
#if RT_PLATFORM == PLATFORM_LINUX
#if (DEV_BUS_TYPE == RT_PCI_INTERFACE)
/* For 92C */
#define RTL8192CE_HWIMG_SUPPORT 1
#define RTL8192CE_TEST_HWIMG_SUPPORT 0
#define RTL8192CU_HWIMG_SUPPORT 0
#define RTL8192CU_TEST_HWIMG_SUPPORT 0
/* For 92D */
#define RTL8192DE_HWIMG_SUPPORT 1
#define RTL8192DE_TEST_HWIMG_SUPPORT 0
#define RTL8192DU_HWIMG_SUPPORT 0
#define RTL8192DU_TEST_HWIMG_SUPPORT 0
/* For 8723 */
#define RTL8723E_HWIMG_SUPPORT 1
#define RTL8723U_HWIMG_SUPPORT 0
#define RTL8723S_HWIMG_SUPPORT 0
/* For 88E */
#define RTL8188EE_HWIMG_SUPPORT 0
#define RTL8188EU_HWIMG_SUPPORT 0
#define RTL8188ES_HWIMG_SUPPORT 0
#elif (DEV_BUS_TYPE == RT_USB_INTERFACE)
/* For 92C */
#define RTL8192CE_HWIMG_SUPPORT 0
#define RTL8192CE_TEST_HWIMG_SUPPORT 0
#define RTL8192CU_HWIMG_SUPPORT 1
#define RTL8192CU_TEST_HWIMG_SUPPORT 0
/* For 92D */
#define RTL8192DE_HWIMG_SUPPORT 0
#define RTL8192DE_TEST_HWIMG_SUPPORT 0
#define RTL8192DU_HWIMG_SUPPORT 1
#define RTL8192DU_TEST_HWIMG_SUPPORT 0
/* For 8723 */
#define RTL8723E_HWIMG_SUPPORT 0
#define RTL8723U_HWIMG_SUPPORT 1
#define RTL8723S_HWIMG_SUPPORT 0
/* For 88E */
#define RTL8188EE_HWIMG_SUPPORT 0
#define RTL8188EU_HWIMG_SUPPORT 0
#define RTL8188ES_HWIMG_SUPPORT 0
#elif (DEV_BUS_TYPE == RT_SDIO_INTERFACE)
/* For 92C */
#define RTL8192CE_HWIMG_SUPPORT 0
#define RTL8192CE_TEST_HWIMG_SUPPORT 0
#define RTL8192CU_HWIMG_SUPPORT 1
#define RTL8192CU_TEST_HWIMG_SUPPORT 0
/* For 92D */
#define RTL8192DE_HWIMG_SUPPORT 0
#define RTL8192DE_TEST_HWIMG_SUPPORT 0
#define RTL8192DU_HWIMG_SUPPORT 1
#define RTL8192DU_TEST_HWIMG_SUPPORT 0
/* For 8723 */
#define RTL8723E_HWIMG_SUPPORT 0
#define RTL8723U_HWIMG_SUPPORT 0
#define RTL8723S_HWIMG_SUPPORT 1
/* For 88E */
#define RTL8188EE_HWIMG_SUPPORT 0
#define RTL8188EU_HWIMG_SUPPORT 0
#define RTL8188ES_HWIMG_SUPPORT 0
#endif
#else /* PLATFORM_WINDOWS & MacOSX */
/* For 92C */
#define RTL8192CE_HWIMG_SUPPORT 1
#define RTL8192CE_TEST_HWIMG_SUPPORT 1
#define RTL8192CU_HWIMG_SUPPORT 1
#define RTL8192CU_TEST_HWIMG_SUPPORT 1
/* For 92D */
#define RTL8192DE_HWIMG_SUPPORT 1
#define RTL8192DE_TEST_HWIMG_SUPPORT 1
#define RTL8192DU_HWIMG_SUPPORT 1
#define RTL8192DU_TEST_HWIMG_SUPPORT 1
#if defined(UNDER_CE)
/* For 8723 */
#define RTL8723E_HWIMG_SUPPORT 0
#define RTL8723U_HWIMG_SUPPORT 0
#define RTL8723S_HWIMG_SUPPORT 1
/* For 88E */
#define RTL8188EE_HWIMG_SUPPORT 0
#define RTL8188EU_HWIMG_SUPPORT 0
#define RTL8188ES_HWIMG_SUPPORT 0
#else
/* For 8723 */
#define RTL8723E_HWIMG_SUPPORT 1
/* #define RTL_8723E_TEST_HWIMG_SUPPORT 1 */
#define RTL8723U_HWIMG_SUPPORT 1
/* #define RTL_8723U_TEST_HWIMG_SUPPORT 1 */
#define RTL8723S_HWIMG_SUPPORT 1
/* #define RTL_8723S_TEST_HWIMG_SUPPORT 1 */
/* For 88E */
#define RTL8188EE_HWIMG_SUPPORT 1
#define RTL8188EU_HWIMG_SUPPORT 1
#define RTL8188ES_HWIMG_SUPPORT 1
#endif
#endif
#endif /* __INC_HW_IMG_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,122 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#ifndef __HAL_PHY_RF_H__
#define __HAL_PHY_RF_H__
#include "halrf/halrf_powertracking_ap.h"
#include "halrf/halrf_kfree.h"
#if (RTL8814A_SUPPORT == 1)
#include "halrf/rtl8814a/halrf_iqk_8814a.h"
#endif
#if (RTL8822B_SUPPORT == 1)
#include "halrf/rtl8822b/halrf_iqk_8822b.h"
#endif
#if (RTL8821C_SUPPORT == 1)
#include "halrf/rtl8821c/halrf_iqk_8821c.h"
#endif
enum pwrtrack_method {
BBSWING,
TXAGC,
MIX_MODE,
TSSI_MODE
};
typedef void (*func_set_pwr)(void *, enum pwrtrack_method, u8, u8);
typedef void(*func_iqk)(void *, u8, u8, u8);
typedef void (*func_lck)(void *);
/* refine by YuChen for 8814A */
typedef void (*func_swing)(void *, u8 **, u8 **, u8 **, u8 **);
typedef void (*func_swing8814only)(void *, u8 **, u8 **, u8 **, u8 **);
typedef void (*func_all_swing)(void *, u8 **, u8 **, u8 **, u8 **, u8 **, u8 **, u8 **, u8 **);
struct txpwrtrack_cfg {
u8 swing_table_size_cck;
u8 swing_table_size_ofdm;
u8 threshold_iqk;
u8 threshold_dpk;
u8 average_thermal_num;
u8 rf_path_count;
u32 thermal_reg_addr;
func_set_pwr odm_tx_pwr_track_set_pwr;
func_iqk do_iqk;
func_lck phy_lc_calibrate;
func_swing get_delta_swing_table;
func_swing8814only get_delta_swing_table8814only;
func_all_swing get_delta_all_swing_table;
};
void
configure_txpower_track(
void *dm_void,
struct txpwrtrack_cfg *config
);
void
odm_txpowertracking_callback_thermal_meter(
void *dm_void
);
#if (RTL8192E_SUPPORT == 1)
void
odm_txpowertracking_callback_thermal_meter_92e(
void *dm_void
);
#endif
#if (RTL8814A_SUPPORT == 1)
void
odm_txpowertracking_callback_thermal_meter_jaguar_series2(
void *dm_void
);
#elif ODM_IC_11AC_SERIES_SUPPORT
void
odm_txpowertracking_callback_thermal_meter_jaguar_series(
void *dm_void
);
#elif (RTL8197F_SUPPORT == 1 || RTL8822B_SUPPORT == 1)
void
odm_txpowertracking_callback_thermal_meter_jaguar_series3(
void *dm_void
);
#endif
#define IS_CCK_RATE(_rate) (ODM_MGN_1M == _rate || _rate == ODM_MGN_2M || _rate == ODM_MGN_5_5M || _rate == ODM_MGN_11M)
#define ODM_TARGET_CHNL_NUM_2G_5G 59
void
odm_reset_iqk_result(
void *dm_void
);
u8
odm_get_right_chnl_place_for_iqk(
u8 chnl
);
void phydm_rf_init(void *dm_void);
void phydm_rf_watchdog(void *dm_void);
#endif /* #ifndef __HAL_PHY_RF_H__ */

Some files were not shown because too many files have changed in this diff Show More