New upstream version 5.3.9~20191129

This commit is contained in:
Sophie Brun 2019-12-17 17:14:15 +01:00
commit 64d530c26f
497 changed files with 379081 additions and 0 deletions

6
Kconfig Normal file
View File

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

2131
Makefile Executable file

File diff suppressed because it is too large Load Diff

73
README.md Normal file
View File

@ -0,0 +1,73 @@
## 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/kimocoder/rtl8188eus.svg)](https://github.com/kimocoder/rtl8188eus/issues)
[![GitHub forks](https://img.shields.io/github/forks/kimocoder/rtl8188eus.svg)](https://github.com/kimocoder/rtl8188eus/network)
[![GitHub stars](https://img.shields.io/github/stars/kimocoder/rtl8188eus.svg)](https://github.com/kimocoder/rtl8188eus/stargazers)
[![GitHub license](https://img.shields.io/github/license/kimocoder/rtl8812au.svg)](https://github.com/kimocoder/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)](#)
This is a pure Realtek release, not from vendor but from all the Realtek multichip "bases"
we've seen, this must be the newest, most stable and effective one.
The performance and code quality has been improved.
# Supports
* MESH Support
* Monitor mode
* Frame injection
* Up to kernel v5.3+
... And a bunch of various wifi chipsets
# Howto build/install
1. You will need to blacklist another driver in order to use this one.
2. "echo "blacklist r8188eu.ko" > "/etc/modprobe.d/realtek.conf"
3. "make && make install"<br>
4. Reboot in order to blacklist and load the new driver/module.
# MONITOR MODE howto
Use these steps to enter monitor mode.
```
airmon-ng check-kill
ip link set <interface> down
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!)
```
aireplay -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 therefor 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
```
# TODO
* Implement txpower control
* Finish up the elimination of the wrapper _rtw_memset.
I didn't have more time after "rtw_beamforming.c"
* Add more VID/PIDS for all 3 chipsets supported.

BIN
ReleaseNotes.pdf Normal file

Binary file not shown.

2215
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

1580
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

6165
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

16925
core/rtw_mlme_ext.c Normal file

File diff suppressed because it is too large Load Diff

3583
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

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~20191129"
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__ */

View File

@ -0,0 +1,907 @@
/******************************************************************************
*
* 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 full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "mp_precomp.h"
#include "phydm_precomp.h"
#define CALCULATE_SWINGTALBE_OFFSET(_offset, _direction, _size, _delta_thermal) \
do {\
for (_offset = 0; _offset < _size; _offset++) { \
if (_delta_thermal < thermal_threshold[_direction][_offset]) { \
if (_offset != 0)\
_offset--;\
break;\
} \
} \
if (_offset >= _size)\
_offset = _size-1;\
} while (0)
void configure_txpower_track(
void *dm_void,
struct txpwrtrack_cfg *config
)
{
struct dm_struct *dm = (struct dm_struct *)dm_void;
#if RTL8192E_SUPPORT
if (dm->support_ic_type == ODM_RTL8192E)
configure_txpower_track_8192e(config);
#endif
#if RTL8821A_SUPPORT
if (dm->support_ic_type == ODM_RTL8821)
configure_txpower_track_8821a(config);
#endif
#if RTL8812A_SUPPORT
if (dm->support_ic_type == ODM_RTL8812)
configure_txpower_track_8812a(config);
#endif
#if RTL8188E_SUPPORT
if (dm->support_ic_type == ODM_RTL8188E)
configure_txpower_track_8188e(config);
#endif
#if RTL8723B_SUPPORT
if (dm->support_ic_type == ODM_RTL8723B)
configure_txpower_track_8723b(config);
#endif
#if RTL8814A_SUPPORT
if (dm->support_ic_type == ODM_RTL8814A)
configure_txpower_track_8814a(config);
#endif
#if RTL8703B_SUPPORT
if (dm->support_ic_type == ODM_RTL8703B)
configure_txpower_track_8703b(config);
#endif
#if RTL8188F_SUPPORT
if (dm->support_ic_type == ODM_RTL8188F)
configure_txpower_track_8188f(config);
#endif
#if RTL8723D_SUPPORT
if (dm->support_ic_type == ODM_RTL8723D)
configure_txpower_track_8723d(config);
#endif
/* JJ ADD 20161014 */
#if RTL8710B_SUPPORT
if (dm->support_ic_type == ODM_RTL8710B)
configure_txpower_track_8710b(config);
#endif
#if RTL8822B_SUPPORT
if (dm->support_ic_type == ODM_RTL8822B)
configure_txpower_track_8822b(config);
#endif
#if RTL8821C_SUPPORT
if (dm->support_ic_type == ODM_RTL8821C)
configure_txpower_track_8821c(config);
#endif
}
/* **********************************************************************
* <20121113, Kordan> This function should be called when tx_agc changed.
* Otherwise the previous compensation is gone, because we record the
* delta of temperature between two TxPowerTracking watch dogs.
*
* NOTE: If Tx BB swing or Tx scaling is varified during run-time, still
* need to call this function.
* ********************************************************************** */
void
odm_clear_txpowertracking_state(
void *dm_void
)
{
struct dm_struct *dm = (struct dm_struct *)dm_void;
#if (DM_ODM_SUPPORT_TYPE == ODM_CE) && defined(DM_ODM_CE_MAC80211)
struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
struct rtl_efuse *rtlefu = rtl_efuse(rtlpriv);
#else
PHAL_DATA_TYPE hal_data = GET_HAL_DATA(dm->adapter);
#endif
u8 p = 0;
struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
cali_info->bb_swing_idx_cck_base = cali_info->default_cck_index;
cali_info->bb_swing_idx_cck = cali_info->default_cck_index;
dm->rf_calibrate_info.CCK_index = 0;
for (p = RF_PATH_A; p < MAX_RF_PATH; ++p) {
cali_info->bb_swing_idx_ofdm_base[p] = cali_info->default_ofdm_index;
cali_info->bb_swing_idx_ofdm[p] = cali_info->default_ofdm_index;
cali_info->OFDM_index[p] = cali_info->default_ofdm_index;
cali_info->power_index_offset[p] = 0;
cali_info->delta_power_index[p] = 0;
cali_info->delta_power_index_last[p] = 0;
cali_info->absolute_ofdm_swing_idx[p] = 0; /* Initial Mix mode power tracking*/
cali_info->remnant_ofdm_swing_idx[p] = 0;
cali_info->kfree_offset[p] = 0;
}
cali_info->modify_tx_agc_flag_path_a = false; /*Initial at Modify Tx Scaling mode*/
cali_info->modify_tx_agc_flag_path_b = false; /*Initial at Modify Tx Scaling mode*/
cali_info->modify_tx_agc_flag_path_c = false; /*Initial at Modify Tx Scaling mode*/
cali_info->modify_tx_agc_flag_path_d = false; /*Initial at Modify Tx Scaling mode*/
cali_info->remnant_cck_swing_idx = 0;
#if (DM_ODM_SUPPORT_TYPE == ODM_CE) && defined(DM_ODM_CE_MAC80211)
cali_info->thermal_value = rtlefu->eeprom_thermalmeter;
#else
cali_info->thermal_value = hal_data->eeprom_thermal_meter;
#endif
cali_info->modify_tx_agc_value_cck = 0; /* modify by Mingzhi.Guo */
cali_info->modify_tx_agc_value_ofdm = 0; /* modify by Mingzhi.Guo */
}
void
odm_txpowertracking_callback_thermal_meter(
#if (DM_ODM_SUPPORT_TYPE & ODM_AP)
struct dm_struct *dm
#elif (DM_ODM_SUPPORT_TYPE == ODM_CE)
void *dm_void
#else
void *adapter
#endif
)
{
#if (DM_ODM_SUPPORT_TYPE == ODM_CE) && defined(DM_ODM_CE_MAC80211)
struct dm_struct *dm = (struct dm_struct *)dm_void;
struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
struct rtl_efuse *rtlefu = rtl_efuse(rtlpriv);
void *adapter = dm->adapter;
#elif !(DM_ODM_SUPPORT_TYPE & ODM_AP)
#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(((PADAPTER)adapter));
struct dm_struct *dm = &hal_data->DM_OutSrc;
#elif (DM_ODM_SUPPORT_TYPE == ODM_CE)
struct dm_struct *dm = (struct dm_struct *)dm_void;
void *adapter = dm->adapter;
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(((PADAPTER)adapter));
#endif
#endif
struct dm_rf_calibration_struct *cali_info = &(dm->rf_calibrate_info);
struct dm_iqk_info *iqk_info = &dm->IQK_info;
u8 thermal_value = 0, delta, delta_LCK, delta_IQK, p = 0, i = 0;
s8 diff_DPK[4] = {0};
u8 thermal_value_avg_count = 0;
u32 thermal_value_avg = 0, regc80, regcd0, regcd4, regab4;
u8 OFDM_min_index = 0; /* OFDM BB Swing should be less than +3.0dB, which is required by Arthur */
u8 indexforchannel = 0; /* get_right_chnl_place_for_iqk(hal_data->current_channel) */
#if (DM_ODM_SUPPORT_TYPE == ODM_CE) && defined(DM_ODM_CE_MAC80211)
u8 power_tracking_type = 0; /* no specify type */
#else
u8 power_tracking_type = hal_data->rf_power_tracking_type;
#endif
u8 xtal_offset_eanble = 0;
s8 thermal_value_temp = 0;
struct txpwrtrack_cfg c = {0};
/* 4 1. The following TWO tables decide the final index of OFDM/CCK swing table. */
u8 *delta_swing_table_idx_tup_a = NULL;
u8 *delta_swing_table_idx_tdown_a = NULL;
u8 *delta_swing_table_idx_tup_b = NULL;
u8 *delta_swing_table_idx_tdown_b = NULL;
/*for 8814 add by Yu Chen*/
u8 *delta_swing_table_idx_tup_c = NULL;
u8 *delta_swing_table_idx_tdown_c = NULL;
u8 *delta_swing_table_idx_tup_d = NULL;
u8 *delta_swing_table_idx_tdown_d = NULL;
/*for Xtal Offset by James.Tung*/
s8 *delta_swing_table_xtal_up = NULL;
s8 *delta_swing_table_xtal_down = NULL;
/* 4 2. Initilization ( 7 steps in total ) */
configure_txpower_track(dm, &c);
(*c.get_delta_swing_table)(dm, (u8 **)&delta_swing_table_idx_tup_a, (u8 **)&delta_swing_table_idx_tdown_a,
(u8 **)&delta_swing_table_idx_tup_b, (u8 **)&delta_swing_table_idx_tdown_b);
if (dm->support_ic_type & ODM_RTL8814A) /*for 8814 path C & D*/
(*c.get_delta_swing_table8814only)(dm, (u8 **)&delta_swing_table_idx_tup_c, (u8 **)&delta_swing_table_idx_tdown_c,
(u8 **)&delta_swing_table_idx_tup_d, (u8 **)&delta_swing_table_idx_tdown_d);
/* JJ ADD 20161014 */
if (dm->support_ic_type & (ODM_RTL8703B | ODM_RTL8723D | ODM_RTL8710B)) /*for Xtal Offset*/
(*c.get_delta_swing_xtal_table)(dm, (s8 **)&delta_swing_table_xtal_up, (s8 **)&delta_swing_table_xtal_down);
cali_info->txpowertracking_callback_cnt++; /*cosa add for debug*/
cali_info->is_txpowertracking_init = true;
/*cali_info->txpowertrack_control = hal_data->txpowertrack_control;
<Kordan> We should keep updating the control variable according to HalData.
<Kordan> rf_calibrate_info.rega24 will be initialized when ODM HW configuring, but MP configures with para files. */
#if (DM_ODM_SUPPORT_TYPE & ODM_WIN)
#if (MP_DRIVER == 1)
cali_info->rega24 = 0x090e1317;
#endif
#elif (DM_ODM_SUPPORT_TYPE & ODM_CE)
if (*(dm->mp_mode) == true)
cali_info->rega24 = 0x090e1317;
#endif
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"===>odm_txpowertracking_callback_thermal_meter\n cali_info->bb_swing_idx_cck_base: %d, cali_info->bb_swing_idx_ofdm_base[A]: %d, cali_info->default_ofdm_index: %d\n",
cali_info->bb_swing_idx_cck_base, cali_info->bb_swing_idx_ofdm_base[RF_PATH_A], cali_info->default_ofdm_index);
#if (DM_ODM_SUPPORT_TYPE == ODM_CE) && defined(DM_ODM_CE_MAC80211)
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"cali_info->txpowertrack_control=%d, rtlefu->eeprom_thermalmeter %d\n", cali_info->txpowertrack_control, rtlefu->eeprom_thermalmeter);
#else
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"cali_info->txpowertrack_control=%d, hal_data->eeprom_thermal_meter %d\n", cali_info->txpowertrack_control, hal_data->eeprom_thermal_meter);
#endif
thermal_value = (u8)odm_get_rf_reg(dm, RF_PATH_A, c.thermal_reg_addr, 0xfc00); /* 0x42: RF Reg[15:10] 88E */
thermal_value_temp = thermal_value + phydm_get_thermal_offset(dm);
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"thermal_value_temp(%d) = thermal_value(%d) + power_trim_thermal(%d)\n", thermal_value_temp, thermal_value, phydm_get_thermal_offset(dm));
if (thermal_value_temp > 63)
thermal_value = 63;
else if (thermal_value_temp < 0)
thermal_value = 0;
else
thermal_value = thermal_value_temp;
/*add log by zhao he, check c80/c94/c14/ca0 value*/
if (dm->support_ic_type == ODM_RTL8723D) {
regc80 = odm_get_bb_reg(dm, 0xc80, MASKDWORD);
regcd0 = odm_get_bb_reg(dm, 0xcd0, MASKDWORD);
regcd4 = odm_get_bb_reg(dm, 0xcd4, MASKDWORD);
regab4 = odm_get_bb_reg(dm, 0xab4, 0x000007FF);
PHYDM_DBG(dm, ODM_COMP_CALIBRATION, "0xc80 = 0x%x 0xcd0 = 0x%x 0xcd4 = 0x%x 0xab4 = 0x%x\n", regc80, regcd0, regcd4, regab4);
}
/* JJ ADD 20161014 */
if (dm->support_ic_type == ODM_RTL8710B) {
regc80 = odm_get_bb_reg(dm, 0xc80, MASKDWORD);
regcd0 = odm_get_bb_reg(dm, 0xcd0, MASKDWORD);
regcd4 = odm_get_bb_reg(dm, 0xcd4, MASKDWORD);
regab4 = odm_get_bb_reg(dm, 0xab4, 0x000007FF);
PHYDM_DBG(dm, ODM_COMP_CALIBRATION, "0xc80 = 0x%x 0xcd0 = 0x%x 0xcd4 = 0x%x 0xab4 = 0x%x\n", regc80, regcd0, regcd4, regab4);
}
if (!cali_info->txpowertrack_control)
return;
#if (DM_ODM_SUPPORT_TYPE == ODM_CE) && defined(DM_ODM_CE_MAC80211)
if (rtlefu->eeprom_thermalmeter == 0xff) {
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK, "no pg, hal_data->eeprom_thermal_meter = 0x%x\n", rtlefu->eeprom_thermalmeter);
return;
}
#else
if (hal_data->eeprom_thermal_meter == 0xff) {
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK, "no pg, hal_data->eeprom_thermal_meter = 0x%x\n", hal_data->eeprom_thermal_meter);
return;
}
#endif
/*4 3. Initialize ThermalValues of rf_calibrate_info*/
if (cali_info->is_reloadtxpowerindex)
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK, "reload ofdm index for band switch\n");
/*4 4. Calculate average thermal meter*/
cali_info->thermal_value_avg[cali_info->thermal_value_avg_index] = thermal_value;
cali_info->thermal_value_avg_index++;
if (cali_info->thermal_value_avg_index == c.average_thermal_num) /*Average times = c.average_thermal_num*/
cali_info->thermal_value_avg_index = 0;
for (i = 0; i < c.average_thermal_num; i++) {
if (cali_info->thermal_value_avg[i]) {
thermal_value_avg += cali_info->thermal_value_avg[i];
thermal_value_avg_count++;
}
}
if (thermal_value_avg_count) { /* Calculate Average thermal_value after average enough times */
thermal_value = (u8)(thermal_value_avg / thermal_value_avg_count);
#if (DM_ODM_SUPPORT_TYPE == ODM_CE) && defined(DM_ODM_CE_MAC80211)
cali_info->thermal_value_delta = thermal_value - rtlefu->eeprom_thermalmeter;
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"AVG Thermal Meter = 0x%X, EFUSE Thermal base = 0x%X\n", thermal_value, rtlefu->eeprom_thermalmeter);
#else
cali_info->thermal_value_delta = thermal_value - hal_data->eeprom_thermal_meter;
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"AVG Thermal Meter = 0x%X, EFUSE Thermal base = 0x%X\n", thermal_value, hal_data->eeprom_thermal_meter);
#endif
}
/* 4 5. Calculate delta, delta_LCK, delta_IQK. */
/* "delta" here is used to determine whether thermal value changes or not. */
delta = (thermal_value > cali_info->thermal_value) ? (thermal_value - cali_info->thermal_value) : (cali_info->thermal_value - thermal_value);
delta_LCK = (thermal_value > cali_info->thermal_value_lck) ? (thermal_value - cali_info->thermal_value_lck) : (cali_info->thermal_value_lck - thermal_value);
delta_IQK = (thermal_value > cali_info->thermal_value_iqk) ? (thermal_value - cali_info->thermal_value_iqk) : (cali_info->thermal_value_iqk - thermal_value);
if (cali_info->thermal_value_iqk == 0xff) { /*no PG, use thermal value for IQK*/
cali_info->thermal_value_iqk = thermal_value;
delta_IQK = (thermal_value > cali_info->thermal_value_iqk) ? (thermal_value - cali_info->thermal_value_iqk) : (cali_info->thermal_value_iqk - thermal_value);
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK, "no PG, use thermal_value for IQK\n");
}
for (p = RF_PATH_A; p < c.rf_path_count; p++)
diff_DPK[p] = (s8)thermal_value - (s8)cali_info->dpk_thermal[p];
/*4 6. If necessary, do LCK.*/
if (!(dm->support_ic_type & ODM_RTL8821)) { /*no PG, do LCK at initial status*/
if (cali_info->thermal_value_lck == 0xff) {
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK, "no PG, do LCK\n");
cali_info->thermal_value_lck = thermal_value;
/*Use RTLCK, so close power tracking driver LCK*/
if (!(dm->support_ic_type & ODM_RTL8814A) && !(dm->support_ic_type & ODM_RTL8822B) && c.phy_lc_calibrate)
(*c.phy_lc_calibrate)(dm);
delta_LCK = (thermal_value > cali_info->thermal_value_lck) ? (thermal_value - cali_info->thermal_value_lck) : (cali_info->thermal_value_lck - thermal_value);
}
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK, "(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n", delta, delta_LCK, delta_IQK);
/* Wait sacn to do LCK by RF Jenyu*/
if ((*dm->is_scan_in_process == false) && (!iqk_info->rfk_forbidden)) {
/* Delta temperature is equal to or larger than 20 centigrade.*/
if (delta_LCK >= c.threshold_iqk) {
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK, "delta_LCK(%d) >= threshold_iqk(%d)\n", delta_LCK, c.threshold_iqk);
cali_info->thermal_value_lck = thermal_value;
/*Use RTLCK, so close power tracking driver LCK*/
if (!(dm->support_ic_type & ODM_RTL8814A) && !(dm->support_ic_type & ODM_RTL8822B) && c.phy_lc_calibrate)
(*c.phy_lc_calibrate)(dm);
}
}
}
/*3 7. If necessary, move the index of swing table to adjust Tx power.*/
if (delta > 0 && cali_info->txpowertrack_control) {
/* "delta" here is used to record the absolute value of differrence. */
#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
#if (DM_ODM_SUPPORT_TYPE == ODM_CE) && defined(DM_ODM_CE_MAC80211)
delta = thermal_value > rtlefu->eeprom_thermalmeter ? (thermal_value - rtlefu->eeprom_thermalmeter) : (rtlefu->eeprom_thermalmeter - thermal_value);
#else
delta = thermal_value > hal_data->eeprom_thermal_meter ? (thermal_value - hal_data->eeprom_thermal_meter) : (hal_data->eeprom_thermal_meter - thermal_value);
#endif
#else
delta = (thermal_value > dm->priv->pmib->dot11RFEntry.ther) ? (thermal_value - dm->priv->pmib->dot11RFEntry.ther) : (dm->priv->pmib->dot11RFEntry.ther - thermal_value);
#endif
if (delta >= TXPWR_TRACK_TABLE_SIZE)
delta = TXPWR_TRACK_TABLE_SIZE - 1;
/*4 7.1 The Final Power index = BaseIndex + power_index_offset*/
#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
#if (DM_ODM_SUPPORT_TYPE == ODM_CE) && defined(DM_ODM_CE_MAC80211)
if (thermal_value > rtlefu->eeprom_thermalmeter) {
#else
if (thermal_value > hal_data->eeprom_thermal_meter) {
#endif
#else
if (thermal_value > dm->priv->pmib->dot11RFEntry.ther) {
#endif
for (p = RF_PATH_A; p < c.rf_path_count; p++) {
cali_info->delta_power_index_last[p] = cali_info->delta_power_index[p]; /*recording poer index offset*/
switch (p) {
case RF_PATH_B:
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"delta_swing_table_idx_tup_b[%d] = %d\n", delta, delta_swing_table_idx_tup_b[delta]);
cali_info->delta_power_index[p] = delta_swing_table_idx_tup_b[delta];
cali_info->absolute_ofdm_swing_idx[p] = delta_swing_table_idx_tup_b[delta]; /*Record delta swing for mix mode power tracking*/
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"******Temp is higher and cali_info->absolute_ofdm_swing_idx[RF_PATH_B] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);
break;
case RF_PATH_C:
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"delta_swing_table_idx_tup_c[%d] = %d\n", delta, delta_swing_table_idx_tup_c[delta]);
cali_info->delta_power_index[p] = delta_swing_table_idx_tup_c[delta];
cali_info->absolute_ofdm_swing_idx[p] = delta_swing_table_idx_tup_c[delta]; /*Record delta swing for mix mode power tracking*/
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"******Temp is higher and cali_info->absolute_ofdm_swing_idx[RF_PATH_C] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);
break;
case RF_PATH_D:
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"delta_swing_table_idx_tup_d[%d] = %d\n", delta, delta_swing_table_idx_tup_d[delta]);
cali_info->delta_power_index[p] = delta_swing_table_idx_tup_d[delta];
cali_info->absolute_ofdm_swing_idx[p] = delta_swing_table_idx_tup_d[delta]; /*Record delta swing for mix mode power tracking*/
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"******Temp is higher and cali_info->absolute_ofdm_swing_idx[RF_PATH_D] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);
break;
default:
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"delta_swing_table_idx_tup_a[%d] = %d\n", delta, delta_swing_table_idx_tup_a[delta]);
cali_info->delta_power_index[p] = delta_swing_table_idx_tup_a[delta];
cali_info->absolute_ofdm_swing_idx[p] = delta_swing_table_idx_tup_a[delta]; /*Record delta swing for mix mode power tracking*/
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"******Temp is higher and cali_info->absolute_ofdm_swing_idx[RF_PATH_A] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);
break;
}
}
/* JJ ADD 20161014 */
if (dm->support_ic_type & (ODM_RTL8703B | ODM_RTL8723D | ODM_RTL8710B)) {
/*Save xtal_offset from Xtal table*/
cali_info->xtal_offset_last = cali_info->xtal_offset; /*recording last Xtal offset*/
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"[Xtal] delta_swing_table_xtal_up[%d] = %d\n", delta, delta_swing_table_xtal_up[delta]);
cali_info->xtal_offset = delta_swing_table_xtal_up[delta];
xtal_offset_eanble = (cali_info->xtal_offset_last != cali_info->xtal_offset);
}
} else {
for (p = RF_PATH_A; p < c.rf_path_count; p++) {
cali_info->delta_power_index_last[p] = cali_info->delta_power_index[p]; /*recording poer index offset*/
switch (p) {
case RF_PATH_B:
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"delta_swing_table_idx_tdown_b[%d] = %d\n", delta, delta_swing_table_idx_tdown_b[delta]);
cali_info->delta_power_index[p] = -1 * delta_swing_table_idx_tdown_b[delta];
cali_info->absolute_ofdm_swing_idx[p] = -1 * delta_swing_table_idx_tdown_b[delta]; /*Record delta swing for mix mode power tracking*/
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"******Temp is lower and cali_info->absolute_ofdm_swing_idx[RF_PATH_B] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);
break;
case RF_PATH_C:
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"delta_swing_table_idx_tdown_c[%d] = %d\n", delta, delta_swing_table_idx_tdown_c[delta]);
cali_info->delta_power_index[p] = -1 * delta_swing_table_idx_tdown_c[delta];
cali_info->absolute_ofdm_swing_idx[p] = -1 * delta_swing_table_idx_tdown_c[delta]; /*Record delta swing for mix mode power tracking*/
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"******Temp is lower and cali_info->absolute_ofdm_swing_idx[RF_PATH_C] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);
break;
case RF_PATH_D:
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"delta_swing_table_idx_tdown_d[%d] = %d\n", delta, delta_swing_table_idx_tdown_d[delta]);
cali_info->delta_power_index[p] = -1 * delta_swing_table_idx_tdown_d[delta];
cali_info->absolute_ofdm_swing_idx[p] = -1 * delta_swing_table_idx_tdown_d[delta]; /*Record delta swing for mix mode power tracking*/
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"******Temp is lower and cali_info->absolute_ofdm_swing_idx[RF_PATH_D] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);
break;
default:
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"delta_swing_table_idx_tdown_a[%d] = %d\n", delta, delta_swing_table_idx_tdown_a[delta]);
cali_info->delta_power_index[p] = -1 * delta_swing_table_idx_tdown_a[delta];
cali_info->absolute_ofdm_swing_idx[p] = -1 * delta_swing_table_idx_tdown_a[delta]; /*Record delta swing for mix mode power tracking*/
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"******Temp is lower and cali_info->absolute_ofdm_swing_idx[RF_PATH_A] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);
break;
}
}
/* JJ ADD 20161014 */
if (dm->support_ic_type & (ODM_RTL8703B | ODM_RTL8723D | ODM_RTL8710B)) {
/*Save xtal_offset from Xtal table*/
cali_info->xtal_offset_last = cali_info->xtal_offset; /*recording last Xtal offset*/
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"[Xtal] delta_swing_table_xtal_down[%d] = %d\n", delta, delta_swing_table_xtal_down[delta]);
cali_info->xtal_offset = delta_swing_table_xtal_down[delta];
xtal_offset_eanble = (cali_info->xtal_offset_last != cali_info->xtal_offset);
}
}
for (p = RF_PATH_A; p < c.rf_path_count; p++) {
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"\n\n=========================== [path-%d] Calculating power_index_offset===========================\n", p);
if (cali_info->delta_power_index[p] == cali_info->delta_power_index_last[p]) /*If Thermal value changes but lookup table value still the same*/
cali_info->power_index_offset[p] = 0;
else
cali_info->power_index_offset[p] = cali_info->delta_power_index[p] - cali_info->delta_power_index_last[p]; /*Power index diff between 2 times Power Tracking*/
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"[path-%d] power_index_offset(%d) = delta_power_index(%d) - delta_power_index_last(%d)\n", p, cali_info->power_index_offset[p], cali_info->delta_power_index[p], cali_info->delta_power_index_last[p]);
cali_info->OFDM_index[p] = cali_info->bb_swing_idx_ofdm_base[p] + cali_info->power_index_offset[p];
cali_info->CCK_index = cali_info->bb_swing_idx_cck_base + cali_info->power_index_offset[p];
cali_info->bb_swing_idx_cck = cali_info->CCK_index;
cali_info->bb_swing_idx_ofdm[p] = cali_info->OFDM_index[p];
/*************Print BB Swing base and index Offset*************/
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"The 'CCK' final index(%d) = BaseIndex(%d) + power_index_offset(%d)\n", cali_info->bb_swing_idx_cck, cali_info->bb_swing_idx_cck_base, cali_info->power_index_offset[p]);
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"The 'OFDM' final index(%d) = BaseIndex[%d](%d) + power_index_offset(%d)\n", cali_info->bb_swing_idx_ofdm[p], p, cali_info->bb_swing_idx_ofdm_base[p], cali_info->power_index_offset[p]);
/*4 7.1 Handle boundary conditions of index.*/
if (cali_info->OFDM_index[p] > c.swing_table_size_ofdm - 1)
cali_info->OFDM_index[p] = c.swing_table_size_ofdm - 1;
else if (cali_info->OFDM_index[p] <= OFDM_min_index)
cali_info->OFDM_index[p] = OFDM_min_index;
}
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"\n\n========================================================================================================\n");
if (cali_info->CCK_index > c.swing_table_size_cck - 1)
cali_info->CCK_index = c.swing_table_size_cck - 1;
else if (cali_info->CCK_index <= 0)
cali_info->CCK_index = 0;
} else {
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"The thermal meter is unchanged or TxPowerTracking OFF(%d): thermal_value: %d, cali_info->thermal_value: %d\n",
cali_info->txpowertrack_control, thermal_value, cali_info->thermal_value);
for (p = RF_PATH_A; p < c.rf_path_count; p++)
cali_info->power_index_offset[p] = 0;
}
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"TxPowerTracking: [CCK] Swing Current index: %d, Swing base index: %d\n",
cali_info->CCK_index, cali_info->bb_swing_idx_cck_base); /*Print Swing base & current*/
for (p = RF_PATH_A; p < c.rf_path_count; p++) {
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"TxPowerTracking: [OFDM] Swing Current index: %d, Swing base index[%d]: %d\n",
cali_info->OFDM_index[p], p, cali_info->bb_swing_idx_ofdm_base[p]);
}
if ((dm->support_ic_type & ODM_RTL8814A)) {
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK, "power_tracking_type=%d\n", power_tracking_type);
if (power_tracking_type == 0) {
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK, "**********Enter POWER Tracking MIX_MODE**********\n");
for (p = RF_PATH_A; p < c.rf_path_count; p++)
(*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0);
} else if (power_tracking_type == 1) {
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK, "**********Enter POWER Tracking MIX(2G) TSSI(5G) MODE**********\n");
for (p = RF_PATH_A; p < c.rf_path_count; p++)
(*c.odm_tx_pwr_track_set_pwr)(dm, MIX_2G_TSSI_5G_MODE, p, 0);
} else if (power_tracking_type == 2) {
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK, "**********Enter POWER Tracking MIX(5G) TSSI(2G)MODE**********\n");
for (p = RF_PATH_A; p < c.rf_path_count; p++)
(*c.odm_tx_pwr_track_set_pwr)(dm, MIX_5G_TSSI_2G_MODE, p, 0);
} else if (power_tracking_type == 3) {
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK, "**********Enter POWER Tracking TSSI MODE**********\n");
for (p = RF_PATH_A; p < c.rf_path_count; p++)
(*c.odm_tx_pwr_track_set_pwr)(dm, TSSI_MODE, p, 0);
}
cali_info->thermal_value = thermal_value; /*Record last Power Tracking Thermal value*/
} else if ((cali_info->power_index_offset[RF_PATH_A] != 0 ||
cali_info->power_index_offset[RF_PATH_B] != 0 ||
cali_info->power_index_offset[RF_PATH_C] != 0 ||
cali_info->power_index_offset[RF_PATH_D] != 0) &&
#if (DM_ODM_SUPPORT_TYPE == ODM_CE) && defined(DM_ODM_CE_MAC80211)
cali_info->txpowertrack_control && (rtlefu->eeprom_thermalmeter != 0xff)) {
#else
cali_info->txpowertrack_control && (hal_data->eeprom_thermal_meter != 0xff)) {
#endif
/* 4 7.2 Configure the Swing Table to adjust Tx Power. */
cali_info->is_tx_power_changed = true; /*Always true after Tx Power is adjusted by power tracking.*/
/* */
/* 2012/04/23 MH According to Luke's suggestion, we can not write BB digital */
/* to increase TX power. Otherwise, EVM will be bad. */
/* */
/* 2012/04/25 MH Add for tx power tracking to set tx power in tx agc for 88E. */
if (thermal_value > cali_info->thermal_value) {
for (p = RF_PATH_A; p < c.rf_path_count; p++) {
#if (DM_ODM_SUPPORT_TYPE == ODM_CE) && defined(DM_ODM_CE_MAC80211)
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"Temperature Increasing(%d): delta_pi: %d, delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
p, cali_info->power_index_offset[p], delta, thermal_value, rtlefu->eeprom_thermalmeter, cali_info->thermal_value);
#else
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"Temperature Increasing(%d): delta_pi: %d, delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
p, cali_info->power_index_offset[p], delta, thermal_value, hal_data->eeprom_thermal_meter, cali_info->thermal_value);
#endif
}
} else if (thermal_value < cali_info->thermal_value) { /*Low temperature*/
for (p = RF_PATH_A; p < c.rf_path_count; p++) {
#if (DM_ODM_SUPPORT_TYPE == ODM_CE) && defined(DM_ODM_CE_MAC80211)
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"Temperature Decreasing(%d): delta_pi: %d, delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
p, cali_info->power_index_offset[p], delta, thermal_value, rtlefu->eeprom_thermalmeter, cali_info->thermal_value);
#else
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"Temperature Decreasing(%d): delta_pi: %d, delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
p, cali_info->power_index_offset[p], delta, thermal_value, hal_data->eeprom_thermal_meter, cali_info->thermal_value);
#endif
}
}
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
#if (DM_ODM_SUPPORT_TYPE == ODM_CE) && defined(DM_ODM_CE_MAC80211)
if (thermal_value > rtlefu->eeprom_thermalmeter)
#else
if (thermal_value > hal_data->eeprom_thermal_meter)
#endif
#else
if (thermal_value > dm->priv->pmib->dot11RFEntry.ther)
#endif
{
#if (DM_ODM_SUPPORT_TYPE == ODM_CE) && defined(DM_ODM_CE_MAC80211)
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"Temperature(%d) higher than PG value(%d)\n", thermal_value, rtlefu->eeprom_thermalmeter);
#else
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"Temperature(%d) higher than PG value(%d)\n", thermal_value, hal_data->eeprom_thermal_meter);
#endif
if (dm->support_ic_type == ODM_RTL8188E || dm->support_ic_type == ODM_RTL8192E || dm->support_ic_type == ODM_RTL8821 ||
dm->support_ic_type == ODM_RTL8812 || dm->support_ic_type == ODM_RTL8723B || dm->support_ic_type == ODM_RTL8814A ||
dm->support_ic_type == ODM_RTL8703B || dm->support_ic_type == ODM_RTL8188F || dm->support_ic_type == ODM_RTL8822B ||
dm->support_ic_type == ODM_RTL8723D || dm->support_ic_type == ODM_RTL8821C || dm->support_ic_type == ODM_RTL8710B) {/* JJ ADD 20161014 */
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK, "**********Enter POWER Tracking MIX_MODE**********\n");
for (p = RF_PATH_A; p < c.rf_path_count; p++)
(*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0);
} else {
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK, "**********Enter POWER Tracking BBSWING_MODE**********\n");
for (p = RF_PATH_A; p < c.rf_path_count; p++)
(*c.odm_tx_pwr_track_set_pwr)(dm, BBSWING, p, indexforchannel);
}
} else {
#if (DM_ODM_SUPPORT_TYPE == ODM_CE) && defined(DM_ODM_CE_MAC80211)
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"Temperature(%d) lower than PG value(%d)\n", thermal_value, rtlefu->eeprom_thermalmeter);
#else
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"Temperature(%d) lower than PG value(%d)\n", thermal_value, hal_data->eeprom_thermal_meter);
#endif
if (dm->support_ic_type == ODM_RTL8188E || dm->support_ic_type == ODM_RTL8192E || dm->support_ic_type == ODM_RTL8821 ||
dm->support_ic_type == ODM_RTL8812 || dm->support_ic_type == ODM_RTL8723B || dm->support_ic_type == ODM_RTL8814A ||
dm->support_ic_type == ODM_RTL8703B || dm->support_ic_type == ODM_RTL8188F || dm->support_ic_type == ODM_RTL8822B ||
dm->support_ic_type == ODM_RTL8723D || dm->support_ic_type == ODM_RTL8821C || dm->support_ic_type == ODM_RTL8710B) {/* JJ ADD 20161014 */
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK, "**********Enter POWER Tracking MIX_MODE**********\n");
for (p = RF_PATH_A; p < c.rf_path_count; p++)
(*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, indexforchannel);
} else {
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK, "**********Enter POWER Tracking BBSWING_MODE**********\n");
for (p = RF_PATH_A; p < c.rf_path_count; p++)
(*c.odm_tx_pwr_track_set_pwr)(dm, BBSWING, p, indexforchannel);
}
}
cali_info->bb_swing_idx_cck_base = cali_info->bb_swing_idx_cck; /*Record last time Power Tracking result as base.*/
for (p = RF_PATH_A; p < c.rf_path_count; p++)
cali_info->bb_swing_idx_ofdm_base[p] = cali_info->bb_swing_idx_ofdm[p];
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"cali_info->thermal_value = %d thermal_value= %d\n", cali_info->thermal_value, thermal_value);
cali_info->thermal_value = thermal_value; /*Record last Power Tracking Thermal value*/
}
if (dm->support_ic_type == ODM_RTL8703B || dm->support_ic_type == ODM_RTL8723D || dm->support_ic_type == ODM_RTL8710B) {/* JJ ADD 20161014 */
#if (DM_ODM_SUPPORT_TYPE == ODM_CE) && defined(DM_ODM_CE_MAC80211)
if (xtal_offset_eanble != 0 && cali_info->txpowertrack_control && (rtlefu->eeprom_thermalmeter != 0xff)) {
#else
if (xtal_offset_eanble != 0 && cali_info->txpowertrack_control && (hal_data->eeprom_thermal_meter != 0xff)) {
#endif
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK, "**********Enter Xtal Tracking**********\n");
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
#if (DM_ODM_SUPPORT_TYPE == ODM_CE) && defined(DM_ODM_CE_MAC80211)
if (thermal_value > rtlefu->eeprom_thermalmeter) {
#else
if (thermal_value > hal_data->eeprom_thermal_meter) {
#endif
#else
if (thermal_value > dm->priv->pmib->dot11RFEntry.ther) {
#endif
#if (DM_ODM_SUPPORT_TYPE == ODM_CE) && defined(DM_ODM_CE_MAC80211)
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"Temperature(%d) higher than PG value(%d)\n", thermal_value, rtlefu->eeprom_thermalmeter);
#else
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"Temperature(%d) higher than PG value(%d)\n", thermal_value, hal_data->eeprom_thermal_meter);
#endif
(*c.odm_txxtaltrack_set_xtal)(dm);
} else {
#if (DM_ODM_SUPPORT_TYPE == ODM_CE) && defined(DM_ODM_CE_MAC80211)
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"Temperature(%d) lower than PG value(%d)\n", thermal_value, rtlefu->eeprom_thermalmeter);
#else
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"Temperature(%d) lower than PG value(%d)\n", thermal_value, hal_data->eeprom_thermal_meter);
#endif
(*c.odm_txxtaltrack_set_xtal)(dm);
}
}
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK, "**********End Xtal Tracking**********\n");
}
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
/* Wait sacn to do IQK by RF Jenyu*/
if ((*dm->is_scan_in_process == false) && (!iqk_info->rfk_forbidden)) {
if (!IS_HARDWARE_TYPE_8723B(adapter)) {
/*Delta temperature is equal to or larger than 20 centigrade (When threshold is 8).*/
if (delta_IQK >= c.threshold_iqk) {
cali_info->thermal_value_iqk = thermal_value;
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK, "delta_IQK(%d) >= threshold_iqk(%d)\n", delta_IQK, c.threshold_iqk);
if (!cali_info->is_iqk_in_progress)
(*c.do_iqk)(dm, delta_IQK, thermal_value, 8);
}
}
}
if (cali_info->dpk_thermal[RF_PATH_A] != 0) {
if (diff_DPK[RF_PATH_A] >= c.threshold_dpk) {
odm_set_bb_reg(dm, 0x82c, BIT(31), 0x1);
odm_set_bb_reg(dm, 0xcc4, BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), (diff_DPK[RF_PATH_A] / c.threshold_dpk));
odm_set_bb_reg(dm, 0x82c, BIT(31), 0x0);
} else if ((diff_DPK[RF_PATH_A] <= -1 * c.threshold_dpk)) {
s32 value = 0x20 + (diff_DPK[RF_PATH_A] / c.threshold_dpk);
odm_set_bb_reg(dm, 0x82c, BIT(31), 0x1);
odm_set_bb_reg(dm, 0xcc4, BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), value);
odm_set_bb_reg(dm, 0x82c, BIT(31), 0x0);
} else {
odm_set_bb_reg(dm, 0x82c, BIT(31), 0x1);
odm_set_bb_reg(dm, 0xcc4, BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), 0);
odm_set_bb_reg(dm, 0x82c, BIT(31), 0x0);
}
}
if (cali_info->dpk_thermal[RF_PATH_B] != 0) {
if (diff_DPK[RF_PATH_B] >= c.threshold_dpk) {
odm_set_bb_reg(dm, 0x82c, BIT(31), 0x1);
odm_set_bb_reg(dm, 0xec4, BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), (diff_DPK[RF_PATH_B] / c.threshold_dpk));
odm_set_bb_reg(dm, 0x82c, BIT(31), 0x0);
} else if ((diff_DPK[RF_PATH_B] <= -1 * c.threshold_dpk)) {
s32 value = 0x20 + (diff_DPK[RF_PATH_B] / c.threshold_dpk);
odm_set_bb_reg(dm, 0x82c, BIT(31), 0x1);
odm_set_bb_reg(dm, 0xec4, BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), value);
odm_set_bb_reg(dm, 0x82c, BIT(31), 0x0);
} else {
odm_set_bb_reg(dm, 0x82c, BIT(31), 0x1);
odm_set_bb_reg(dm, 0xec4, BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), 0);
odm_set_bb_reg(dm, 0x82c, BIT(31), 0x0);
}
}
#endif
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK, "<===odm_txpowertracking_callback_thermal_meter\n");
cali_info->tx_powercount = 0;
}
/* 3============================================================
* 3 IQ Calibration
* 3============================================================ */
void
odm_reset_iqk_result(
void *dm_void
)
{
return;
}
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
u8 odm_get_right_chnl_place_for_iqk(u8 chnl)
{
u8 channel_all[ODM_TARGET_CHNL_NUM_2G_5G] = {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 149, 151, 153, 155, 157, 159, 161, 163, 165
};
u8 place = chnl;
if (chnl > 14) {
for (place = 14; place < sizeof(channel_all); place++) {
if (channel_all[place] == chnl)
return place - 13;
}
}
return 0;
}
#endif
void
odm_iq_calibrate(
struct dm_struct *dm
)
{
void *adapter = dm->adapter;
struct dm_iqk_info *iqk_info = &dm->IQK_info;
#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
if (*dm->is_fcs_mode_enable)
return;
#endif
#if (DM_ODM_SUPPORT_TYPE & (ODM_CE))
if (IS_HARDWARE_TYPE_8812AU(adapter))
return;
#endif
if ((dm->is_linked) && (!iqk_info->rfk_forbidden)) {
if ((*dm->channel != dm->pre_channel) && (!*dm->is_scan_in_process)) {
dm->pre_channel = *dm->channel;
dm->linked_interval = 0;
}
if (dm->linked_interval < 3)
dm->linked_interval++;
if (dm->linked_interval == 2)
halrf_iqk_trigger(dm, false);
} else
dm->linked_interval = 0;
}
void phydm_rf_init(void *dm_void)
{
struct dm_struct *dm = (struct dm_struct *)dm_void;
odm_txpowertracking_init(dm);
#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
odm_clear_txpowertracking_state(dm);
#endif
#if (DM_ODM_SUPPORT_TYPE & (ODM_AP))
#if (RTL8814A_SUPPORT == 1)
if (dm->support_ic_type & ODM_RTL8814A)
phy_iq_calibrate_8814a_init(dm);
#endif
#endif
}
void phydm_rf_watchdog(void *dm_void)
{
struct dm_struct *dm = (struct dm_struct *)dm_void;
#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
odm_txpowertracking_check(dm);
/*if (dm->support_ic_type & ODM_IC_11AC_SERIES)*/
/*odm_iq_calibrate(dm);*/
#endif
}

View File

@ -0,0 +1,124 @@
/******************************************************************************
*
* 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 full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __HAL_PHY_RF_H__
#define __HAL_PHY_RF_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
#include "halrf/halrf_powertracking_ce.h"
enum spur_cal_method {
PLL_RESET,
AFE_PHASE_SEL
};
enum pwrtrack_method {
BBSWING,
TXAGC,
MIX_MODE,
TSSI_MODE,
MIX_2G_TSSI_5G_MODE,
MIX_5G_TSSI_2G_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 *);
typedef void (*func_swing)(void *, u8 **, u8 **, u8 **, u8 **);
typedef void (*func_swing8814only)(void *, u8 **, u8 **, u8 **, u8 **);
typedef void(*func_swing_xtal)(void *, s8 **, s8 **);
typedef void(*func_set_xtal)(void *);
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_swing_xtal get_delta_swing_xtal_table;
func_set_xtal odm_txxtaltrack_set_xtal;
};
void
configure_txpower_track(
void *dm_void,
struct txpwrtrack_cfg *config
);
void
odm_clear_txpowertracking_state(
void *dm_void
);
void
odm_txpowertracking_callback_thermal_meter(
#if (DM_ODM_SUPPORT_TYPE & ODM_AP)
void *dm_void
#elif (DM_ODM_SUPPORT_TYPE & ODM_CE)
void *dm
#else
void *adapter
#endif
);
#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__ */

View File

@ -0,0 +1,817 @@
/******************************************************************************
*
* 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 "phydm_precomp.h"
#define CALCULATE_SWINGTALBE_OFFSET(_offset, _direction, _size, _delta_thermal) \
do {\
for (_offset = 0; _offset < _size; _offset++) { \
\
if (_delta_thermal < thermal_threshold[_direction][_offset]) { \
\
if (_offset != 0)\
_offset--;\
break;\
} \
} \
if (_offset >= _size)\
_offset = _size-1;\
} while (0)
void configure_txpower_track(
struct dm_struct *dm,
struct txpwrtrack_cfg *config
)
{
#if RTL8192E_SUPPORT
if (dm->support_ic_type == ODM_RTL8192E)
configure_txpower_track_8192e(config);
#endif
#if RTL8821A_SUPPORT
if (dm->support_ic_type == ODM_RTL8821)
configure_txpower_track_8821a(config);
#endif
#if RTL8812A_SUPPORT
if (dm->support_ic_type == ODM_RTL8812)
configure_txpower_track_8812a(config);
#endif
#if RTL8188E_SUPPORT
if (dm->support_ic_type == ODM_RTL8188E)
configure_txpower_track_8188e(config);
#endif
#if RTL8188F_SUPPORT
if (dm->support_ic_type == ODM_RTL8188F)
configure_txpower_track_8188f(config);
#endif
#if RTL8723B_SUPPORT
if (dm->support_ic_type == ODM_RTL8723B)
configure_txpower_track_8723b(config);
#endif
#if RTL8814A_SUPPORT
if (dm->support_ic_type == ODM_RTL8814A)
configure_txpower_track_8814a(config);
#endif
#if RTL8703B_SUPPORT
if (dm->support_ic_type == ODM_RTL8703B)
configure_txpower_track_8703b(config);
#endif
#if RTL8822B_SUPPORT
if (dm->support_ic_type == ODM_RTL8822B)
configure_txpower_track_8822b(config);
#endif
#if RTL8723D_SUPPORT
if (dm->support_ic_type == ODM_RTL8723D)
configure_txpower_track_8723d(config);
#endif
/* JJ ADD 20161014 */
#if RTL8710B_SUPPORT
if (dm->support_ic_type == ODM_RTL8710B)
configure_txpower_track_8710b(config);
#endif
#if RTL8821C_SUPPORT
if (dm->support_ic_type == ODM_RTL8821C)
configure_txpower_track_8821c(config);
#endif
}
/* **********************************************************************
* <20121113, Kordan> This function should be called when tx_agc changed.
* Otherwise the previous compensation is gone, because we record the
* delta of temperature between two TxPowerTracking watch dogs.
*
* NOTE: If Tx BB swing or Tx scaling is varified during run-time, still
* need to call this function.
* ********************************************************************** */
void
odm_clear_txpowertracking_state(
struct dm_struct *dm
)
{
PHAL_DATA_TYPE hal_data = GET_HAL_DATA((PADAPTER)(dm->adapter));
u8 p = 0;
struct dm_rf_calibration_struct *cali_info = &(dm->rf_calibrate_info);
cali_info->bb_swing_idx_cck_base = cali_info->default_cck_index;
cali_info->bb_swing_idx_cck = cali_info->default_cck_index;
cali_info->CCK_index = 0;
for (p = RF_PATH_A; p < MAX_RF_PATH; ++p) {
cali_info->bb_swing_idx_ofdm_base[p] = cali_info->default_ofdm_index;
cali_info->bb_swing_idx_ofdm[p] = cali_info->default_ofdm_index;
cali_info->OFDM_index[p] = cali_info->default_ofdm_index;
cali_info->power_index_offset[p] = 0;
cali_info->delta_power_index[p] = 0;
cali_info->delta_power_index_last[p] = 0;
cali_info->absolute_ofdm_swing_idx[p] = 0; /* Initial Mix mode power tracking*/
cali_info->remnant_ofdm_swing_idx[p] = 0;
cali_info->kfree_offset[p] = 0;
}
cali_info->modify_tx_agc_flag_path_a = false; /*Initial at Modify Tx Scaling mode*/
cali_info->modify_tx_agc_flag_path_b = false; /*Initial at Modify Tx Scaling mode*/
cali_info->modify_tx_agc_flag_path_c = false; /*Initial at Modify Tx Scaling mode*/
cali_info->modify_tx_agc_flag_path_d = false; /*Initial at Modify Tx Scaling mode*/
cali_info->remnant_cck_swing_idx = 0;
cali_info->thermal_value = hal_data->eeprom_thermal_meter;
cali_info->modify_tx_agc_value_cck = 0; /* modify by Mingzhi.Guo */
cali_info->modify_tx_agc_value_ofdm = 0; /* modify by Mingzhi.Guo */
}
void
odm_txpowertracking_callback_thermal_meter(
#if (DM_ODM_SUPPORT_TYPE & ODM_AP)
struct dm_struct *dm
#else
void *adapter
#endif
)
{
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(((PADAPTER)adapter));
#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
struct dm_struct *dm = &hal_data->DM_OutSrc;
#elif (DM_ODM_SUPPORT_TYPE == ODM_CE)
struct dm_struct *dm = &hal_data->odmpriv;
#endif
#endif
struct dm_rf_calibration_struct *cali_info = &(dm->rf_calibrate_info);
struct dm_iqk_info *iqk_info = &dm->IQK_info;
u8 thermal_value = 0, delta, delta_LCK, delta_IQK, p = 0, i = 0;
s8 diff_DPK[4] = {0};
u8 thermal_value_avg_count = 0;
u32 thermal_value_avg = 0, regc80, regcd0, regcd4, regab4;
u8 OFDM_min_index = 0; /* OFDM BB Swing should be less than +3.0dB, which is required by Arthur */
u8 indexforchannel = 0; /* get_right_chnl_place_for_iqk(hal_data->current_channel) */
u8 power_tracking_type = hal_data->RfPowerTrackingType;
u8 xtal_offset_eanble = 0;
s8 thermal_value_temp = 0;
struct txpwrtrack_cfg c;
/* 4 1. The following TWO tables decide the final index of OFDM/CCK swing table. */
u8 *delta_swing_table_idx_tup_a = NULL;
u8 *delta_swing_table_idx_tdown_a = NULL;
u8 *delta_swing_table_idx_tup_b = NULL;
u8 *delta_swing_table_idx_tdown_b = NULL;
/*for 8814 add by Yu Chen*/
u8 *delta_swing_table_idx_tup_c = NULL;
u8 *delta_swing_table_idx_tdown_c = NULL;
u8 *delta_swing_table_idx_tup_d = NULL;
u8 *delta_swing_table_idx_tdown_d = NULL;
/*for Xtal Offset by James.Tung*/
s8 *delta_swing_table_xtal_up = NULL;
s8 *delta_swing_table_xtal_down = NULL;
/* 4 2. Initilization ( 7 steps in total ) */
configure_txpower_track(dm, &c);
(*c.get_delta_swing_table)(dm, (u8 **)&delta_swing_table_idx_tup_a, (u8 **)&delta_swing_table_idx_tdown_a,
(u8 **)&delta_swing_table_idx_tup_b, (u8 **)&delta_swing_table_idx_tdown_b);
if (dm->support_ic_type & ODM_RTL8814A) /*for 8814 path C & D*/
(*c.get_delta_swing_table8814only)(dm, (u8 **)&delta_swing_table_idx_tup_c, (u8 **)&delta_swing_table_idx_tdown_c,
(u8 **)&delta_swing_table_idx_tup_d, (u8 **)&delta_swing_table_idx_tdown_d);
/* JJ ADD 20161014 */
if (dm->support_ic_type & (ODM_RTL8703B | ODM_RTL8723D | ODM_RTL8710B)) /*for Xtal Offset*/
(*c.get_delta_swing_xtal_table)(dm, (s8 **)&delta_swing_table_xtal_up, (s8 **)&delta_swing_table_xtal_down);
cali_info->txpowertracking_callback_cnt++; /*cosa add for debug*/
cali_info->is_txpowertracking_init = true;
/*cali_info->txpowertrack_control = hal_data->txpowertrack_control;
<Kordan> We should keep updating the control variable according to HalData.
<Kordan> rf_calibrate_info.rega24 will be initialized when ODM HW configuring, but MP configures with para files. */
#if (DM_ODM_SUPPORT_TYPE & ODM_WIN)
#if (MP_DRIVER == 1)
cali_info->rega24 = 0x090e1317;
#endif
#elif (DM_ODM_SUPPORT_TYPE & ODM_CE)
if (*(dm->mp_mode) == true)
cali_info->rega24 = 0x090e1317;
#endif
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"===>odm_txpowertracking_callback_thermal_meter\n cali_info->bb_swing_idx_cck_base: %d, cali_info->bb_swing_idx_ofdm_base[A]: %d, cali_info->default_ofdm_index: %d\n",
cali_info->bb_swing_idx_cck_base, cali_info->bb_swing_idx_ofdm_base[RF_PATH_A], cali_info->default_ofdm_index);
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"cali_info->txpowertrack_control=%d, hal_data->eeprom_thermal_meter %d\n", cali_info->txpowertrack_control, hal_data->eeprom_thermal_meter);
thermal_value = (u8)odm_get_rf_reg(dm, RF_PATH_A, c.thermal_reg_addr, 0xfc00); /* 0x42: RF Reg[15:10] 88E */
thermal_value_temp = thermal_value + phydm_get_thermal_offset(dm);
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"thermal_value_temp(%d) = thermal_value(%d) + power_time_thermal(%d)\n", thermal_value_temp, thermal_value, phydm_get_thermal_offset(dm));
if (thermal_value_temp > 63)
thermal_value = 63;
else if (thermal_value_temp < 0)
thermal_value = 0;
else
thermal_value = thermal_value_temp;
/*add log by zhao he, check c80/c94/c14/ca0 value*/
if (dm->support_ic_type == ODM_RTL8723D) {
regc80 = odm_get_bb_reg(dm, 0xc80, MASKDWORD);
regcd0 = odm_get_bb_reg(dm, 0xcd0, MASKDWORD);
regcd4 = odm_get_bb_reg(dm, 0xcd4, MASKDWORD);
regab4 = odm_get_bb_reg(dm, 0xab4, 0x000007FF);
PHYDM_DBG(dm, ODM_COMP_CALIBRATION, "0xc80 = 0x%x 0xcd0 = 0x%x 0xcd4 = 0x%x 0xab4 = 0x%x\n", regc80, regcd0, regcd4, regab4);
}
/* JJ ADD 20161014 */
if (dm->support_ic_type == ODM_RTL8710B) {
regc80 = odm_get_bb_reg(dm, 0xc80, MASKDWORD);
regcd0 = odm_get_bb_reg(dm, 0xcd0, MASKDWORD);
regcd4 = odm_get_bb_reg(dm, 0xcd4, MASKDWORD);
regab4 = odm_get_bb_reg(dm, 0xab4, 0x000007FF);
PHYDM_DBG(dm, ODM_COMP_CALIBRATION, "0xc80 = 0x%x 0xcd0 = 0x%x 0xcd4 = 0x%x 0xab4 = 0x%x\n", regc80, regcd0, regcd4, regab4);
}
if (!cali_info->txpowertrack_control)
return;
if (hal_data->eeprom_thermal_meter == 0xff) {
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK, "no pg, hal_data->eeprom_thermal_meter = 0x%x\n", hal_data->eeprom_thermal_meter);
return;
}
/*4 3. Initialize ThermalValues of rf_calibrate_info*/
if (cali_info->is_reloadtxpowerindex)
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK, "reload ofdm index for band switch\n");
/*4 4. Calculate average thermal meter*/
cali_info->thermal_value_avg[cali_info->thermal_value_avg_index] = thermal_value;
cali_info->thermal_value_avg_index++;
if (cali_info->thermal_value_avg_index == c.average_thermal_num) /*Average times = c.average_thermal_num*/
cali_info->thermal_value_avg_index = 0;
for (i = 0; i < c.average_thermal_num; i++) {
if (cali_info->thermal_value_avg[i]) {
thermal_value_avg += cali_info->thermal_value_avg[i];
thermal_value_avg_count++;
}
}
if (thermal_value_avg_count) { /* Calculate Average thermal_value after average enough times */
thermal_value = (u8)(thermal_value_avg / thermal_value_avg_count);
cali_info->thermal_value_delta = thermal_value - hal_data->eeprom_thermal_meter;
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"AVG Thermal Meter = 0x%X, EFUSE Thermal base = 0x%X\n", thermal_value, hal_data->eeprom_thermal_meter);
}
/* 4 5. Calculate delta, delta_LCK, delta_IQK. */
/* "delta" here is used to determine whether thermal value changes or not. */
delta = (thermal_value > cali_info->thermal_value) ? (thermal_value - cali_info->thermal_value) : (cali_info->thermal_value - thermal_value);
delta_LCK = (thermal_value > cali_info->thermal_value_lck) ? (thermal_value - cali_info->thermal_value_lck) : (cali_info->thermal_value_lck - thermal_value);
delta_IQK = (thermal_value > cali_info->thermal_value_iqk) ? (thermal_value - cali_info->thermal_value_iqk) : (cali_info->thermal_value_iqk - thermal_value);
if (cali_info->thermal_value_iqk == 0xff) { /*no PG, use thermal value for IQK*/
cali_info->thermal_value_iqk = thermal_value;
delta_IQK = (thermal_value > cali_info->thermal_value_iqk) ? (thermal_value - cali_info->thermal_value_iqk) : (cali_info->thermal_value_iqk - thermal_value);
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK, "no PG, use thermal_value for IQK\n");
}
for (p = RF_PATH_A; p < c.rf_path_count; p++)
diff_DPK[p] = (s8)thermal_value - (s8)cali_info->dpk_thermal[p];
/*4 6. If necessary, do LCK.*/
if (!(dm->support_ic_type & ODM_RTL8821)) { /*no PG, do LCK at initial status*/
if (cali_info->thermal_value_lck == 0xff) {
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK, "no PG, do LCK\n");
cali_info->thermal_value_lck = thermal_value;
/*Use RTLCK, so close power tracking driver LCK*/
if ((!(dm->support_ic_type & ODM_RTL8814A)) && (!(dm->support_ic_type & ODM_RTL8822B))) {
if (c.phy_lc_calibrate)
(*c.phy_lc_calibrate)(dm);
}
delta_LCK = (thermal_value > cali_info->thermal_value_lck) ? (thermal_value - cali_info->thermal_value_lck) : (cali_info->thermal_value_lck - thermal_value);
}
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK, "(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n", delta, delta_LCK, delta_IQK);
/* Wait sacn to do LCK by RF Jenyu*/
if( (*dm->is_scan_in_process == false) && (!iqk_info->rfk_forbidden)) {
/* Delta temperature is equal to or larger than 20 centigrade.*/
if (delta_LCK >= c.threshold_iqk) {
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK, "delta_LCK(%d) >= threshold_iqk(%d)\n", delta_LCK, c.threshold_iqk);
cali_info->thermal_value_lck = thermal_value;
/*Use RTLCK, so close power tracking driver LCK*/
if ((!(dm->support_ic_type & ODM_RTL8814A)) && (!(dm->support_ic_type & ODM_RTL8822B))) {
if (c.phy_lc_calibrate)
(*c.phy_lc_calibrate)(dm);
}
}
}
}
/*3 7. If necessary, move the index of swing table to adjust Tx power.*/
if (delta > 0 && cali_info->txpowertrack_control) {
/* "delta" here is used to record the absolute value of differrence. */
#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
delta = thermal_value > hal_data->eeprom_thermal_meter ? (thermal_value - hal_data->eeprom_thermal_meter) : (hal_data->eeprom_thermal_meter - thermal_value);
#else
delta = (thermal_value > dm->priv->pmib->dot11RFEntry.ther) ? (thermal_value - dm->priv->pmib->dot11RFEntry.ther) : (dm->priv->pmib->dot11RFEntry.ther - thermal_value);
#endif
if (delta >= TXPWR_TRACK_TABLE_SIZE)
delta = TXPWR_TRACK_TABLE_SIZE - 1;
/*4 7.1 The Final Power index = BaseIndex + power_index_offset*/
#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
if (thermal_value > hal_data->eeprom_thermal_meter) {
#else
if (thermal_value > dm->priv->pmib->dot11RFEntry.ther) {
#endif
for (p = RF_PATH_A; p < c.rf_path_count; p++) {
cali_info->delta_power_index_last[p] = cali_info->delta_power_index[p]; /*recording poer index offset*/
switch (p) {
case RF_PATH_B:
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"delta_swing_table_idx_tup_b[%d] = %d\n", delta, delta_swing_table_idx_tup_b[delta]);
cali_info->delta_power_index[p] = delta_swing_table_idx_tup_b[delta];
cali_info->absolute_ofdm_swing_idx[p] = delta_swing_table_idx_tup_b[delta]; /*Record delta swing for mix mode power tracking*/
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"******Temp is higher and cali_info->absolute_ofdm_swing_idx[RF_PATH_B] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);
break;
case RF_PATH_C:
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"delta_swing_table_idx_tup_c[%d] = %d\n", delta, delta_swing_table_idx_tup_c[delta]);
cali_info->delta_power_index[p] = delta_swing_table_idx_tup_c[delta];
cali_info->absolute_ofdm_swing_idx[p] = delta_swing_table_idx_tup_c[delta]; /*Record delta swing for mix mode power tracking*/
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"******Temp is higher and cali_info->absolute_ofdm_swing_idx[RF_PATH_C] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);
break;
case RF_PATH_D:
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"delta_swing_table_idx_tup_d[%d] = %d\n", delta, delta_swing_table_idx_tup_d[delta]);
cali_info->delta_power_index[p] = delta_swing_table_idx_tup_d[delta];
cali_info->absolute_ofdm_swing_idx[p] = delta_swing_table_idx_tup_d[delta]; /*Record delta swing for mix mode power tracking*/
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"******Temp is higher and cali_info->absolute_ofdm_swing_idx[RF_PATH_D] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);
break;
default:
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"delta_swing_table_idx_tup_a[%d] = %d\n", delta, delta_swing_table_idx_tup_a[delta]);
cali_info->delta_power_index[p] = delta_swing_table_idx_tup_a[delta];
cali_info->absolute_ofdm_swing_idx[p] = delta_swing_table_idx_tup_a[delta]; /*Record delta swing for mix mode power tracking*/
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"******Temp is higher and cali_info->absolute_ofdm_swing_idx[RF_PATH_A] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);
break;
}
}
/* JJ ADD 20161014 */
if (dm->support_ic_type & (ODM_RTL8703B | ODM_RTL8723D | ODM_RTL8710B)) {
/*Save xtal_offset from Xtal table*/
cali_info->xtal_offset_last = cali_info->xtal_offset; /*recording last Xtal offset*/
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"[Xtal] delta_swing_table_xtal_up[%d] = %d\n", delta, delta_swing_table_xtal_up[delta]);
cali_info->xtal_offset = delta_swing_table_xtal_up[delta];
if (cali_info->xtal_offset_last == cali_info->xtal_offset)
xtal_offset_eanble = 0;
else
xtal_offset_eanble = 1;
}
} else {
for (p = RF_PATH_A; p < c.rf_path_count; p++) {
cali_info->delta_power_index_last[p] = cali_info->delta_power_index[p]; /*recording poer index offset*/
switch (p) {
case RF_PATH_B:
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"delta_swing_table_idx_tdown_b[%d] = %d\n", delta, delta_swing_table_idx_tdown_b[delta]);
cali_info->delta_power_index[p] = -1 * delta_swing_table_idx_tdown_b[delta];
cali_info->absolute_ofdm_swing_idx[p] = -1 * delta_swing_table_idx_tdown_b[delta]; /*Record delta swing for mix mode power tracking*/
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"******Temp is lower and cali_info->absolute_ofdm_swing_idx[RF_PATH_B] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);
break;
case RF_PATH_C:
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"delta_swing_table_idx_tdown_c[%d] = %d\n", delta, delta_swing_table_idx_tdown_c[delta]);
cali_info->delta_power_index[p] = -1 * delta_swing_table_idx_tdown_c[delta];
cali_info->absolute_ofdm_swing_idx[p] = -1 * delta_swing_table_idx_tdown_c[delta]; /*Record delta swing for mix mode power tracking*/
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"******Temp is lower and cali_info->absolute_ofdm_swing_idx[RF_PATH_C] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);
break;
case RF_PATH_D:
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"delta_swing_table_idx_tdown_d[%d] = %d\n", delta, delta_swing_table_idx_tdown_d[delta]);
cali_info->delta_power_index[p] = -1 * delta_swing_table_idx_tdown_d[delta];
cali_info->absolute_ofdm_swing_idx[p] = -1 * delta_swing_table_idx_tdown_d[delta]; /*Record delta swing for mix mode power tracking*/
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"******Temp is lower and cali_info->absolute_ofdm_swing_idx[RF_PATH_D] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);
break;
default:
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"delta_swing_table_idx_tdown_a[%d] = %d\n", delta, delta_swing_table_idx_tdown_a[delta]);
cali_info->delta_power_index[p] = -1 * delta_swing_table_idx_tdown_a[delta];
cali_info->absolute_ofdm_swing_idx[p] = -1 * delta_swing_table_idx_tdown_a[delta]; /*Record delta swing for mix mode power tracking*/
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"******Temp is lower and cali_info->absolute_ofdm_swing_idx[RF_PATH_A] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);
break;
}
}
/* JJ ADD 20161014 */
if (dm->support_ic_type & (ODM_RTL8703B | ODM_RTL8723D | ODM_RTL8710B)) {
/*Save xtal_offset from Xtal table*/
cali_info->xtal_offset_last = cali_info->xtal_offset; /*recording last Xtal offset*/
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"[Xtal] delta_swing_table_xtal_down[%d] = %d\n", delta, delta_swing_table_xtal_down[delta]);
cali_info->xtal_offset = delta_swing_table_xtal_down[delta];
if (cali_info->xtal_offset_last == cali_info->xtal_offset)
xtal_offset_eanble = 0;
else
xtal_offset_eanble = 1;
}
}
for (p = RF_PATH_A; p < c.rf_path_count; p++) {
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"\n\n=========================== [path-%d] Calculating power_index_offset===========================\n", p);
if (cali_info->delta_power_index[p] == cali_info->delta_power_index_last[p]) /*If Thermal value changes but lookup table value still the same*/
cali_info->power_index_offset[p] = 0;
else
cali_info->power_index_offset[p] = cali_info->delta_power_index[p] - cali_info->delta_power_index_last[p]; /*Power index diff between 2 times Power Tracking*/
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"[path-%d] power_index_offset(%d) = delta_power_index(%d) - delta_power_index_last(%d)\n", p, cali_info->power_index_offset[p], cali_info->delta_power_index[p], cali_info->delta_power_index_last[p]);
cali_info->OFDM_index[p] = cali_info->bb_swing_idx_ofdm_base[p] + cali_info->power_index_offset[p];
cali_info->CCK_index = cali_info->bb_swing_idx_cck_base + cali_info->power_index_offset[p];
cali_info->bb_swing_idx_cck = cali_info->CCK_index;
cali_info->bb_swing_idx_ofdm[p] = cali_info->OFDM_index[p];
/*************Print BB Swing base and index Offset*************/
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"The 'CCK' final index(%d) = BaseIndex(%d) + power_index_offset(%d)\n", cali_info->bb_swing_idx_cck, cali_info->bb_swing_idx_cck_base, cali_info->power_index_offset[p]);
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"The 'OFDM' final index(%d) = BaseIndex[%d](%d) + power_index_offset(%d)\n", cali_info->bb_swing_idx_ofdm[p], p, cali_info->bb_swing_idx_ofdm_base[p], cali_info->power_index_offset[p]);
/*4 7.1 Handle boundary conditions of index.*/
if (cali_info->OFDM_index[p] > c.swing_table_size_ofdm - 1)
cali_info->OFDM_index[p] = c.swing_table_size_ofdm - 1;
else if (cali_info->OFDM_index[p] <= OFDM_min_index)
cali_info->OFDM_index[p] = OFDM_min_index;
}
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"\n\n========================================================================================================\n");
if (cali_info->CCK_index > c.swing_table_size_cck - 1)
cali_info->CCK_index = c.swing_table_size_cck - 1;
else if (cali_info->CCK_index <= 0)
cali_info->CCK_index = 0;
} else {
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"The thermal meter is unchanged or TxPowerTracking OFF(%d): thermal_value: %d, cali_info->thermal_value: %d\n",
cali_info->txpowertrack_control, thermal_value, cali_info->thermal_value);
for (p = RF_PATH_A; p < c.rf_path_count; p++)
cali_info->power_index_offset[p] = 0;
}
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"TxPowerTracking: [CCK] Swing Current index: %d, Swing base index: %d\n",
cali_info->CCK_index, cali_info->bb_swing_idx_cck_base); /*Print Swing base & current*/
for (p = RF_PATH_A; p < c.rf_path_count; p++) {
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"TxPowerTracking: [OFDM] Swing Current index: %d, Swing base index[%d]: %d\n",
cali_info->OFDM_index[p], p, cali_info->bb_swing_idx_ofdm_base[p]);
}
if ((dm->support_ic_type & ODM_RTL8814A)) {
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK, "power_tracking_type=%d\n", power_tracking_type);
if (power_tracking_type == 0) {
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK, "**********Enter POWER Tracking MIX_MODE**********\n");
for (p = RF_PATH_A; p < c.rf_path_count; p++)
(*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0);
} else if (power_tracking_type == 1) {
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK, "**********Enter POWER Tracking MIX(2G) TSSI(5G) MODE**********\n");
for (p = RF_PATH_A; p < c.rf_path_count; p++)
(*c.odm_tx_pwr_track_set_pwr)(dm, MIX_2G_TSSI_5G_MODE, p, 0);
} else if (power_tracking_type == 2) {
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK, "**********Enter POWER Tracking MIX(5G) TSSI(2G)MODE**********\n");
for (p = RF_PATH_A; p < c.rf_path_count; p++)
(*c.odm_tx_pwr_track_set_pwr)(dm, MIX_5G_TSSI_2G_MODE, p, 0);
} else if (power_tracking_type == 3) {
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK, "**********Enter POWER Tracking TSSI MODE**********\n");
for (p = RF_PATH_A; p < c.rf_path_count; p++)
(*c.odm_tx_pwr_track_set_pwr)(dm, TSSI_MODE, p, 0);
}
cali_info->thermal_value = thermal_value; /*Record last Power Tracking Thermal value*/
} else if ((cali_info->power_index_offset[RF_PATH_A] != 0 ||
cali_info->power_index_offset[RF_PATH_B] != 0 ||
cali_info->power_index_offset[RF_PATH_C] != 0 ||
cali_info->power_index_offset[RF_PATH_D] != 0) &&
cali_info->txpowertrack_control && (hal_data->eeprom_thermal_meter != 0xff)) {
/* 4 7.2 Configure the Swing Table to adjust Tx Power. */
cali_info->is_tx_power_changed = true; /*Always true after Tx Power is adjusted by power tracking.*/
/* */
/* 2012/04/23 MH According to Luke's suggestion, we can not write BB digital */
/* to increase TX power. Otherwise, EVM will be bad. */
/* */
/* 2012/04/25 MH Add for tx power tracking to set tx power in tx agc for 88E. */
if (thermal_value > cali_info->thermal_value) {
for (p = RF_PATH_A; p < c.rf_path_count; p++) {
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"Temperature Increasing(%d): delta_pi: %d, delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
p, cali_info->power_index_offset[p], delta, thermal_value, hal_data->eeprom_thermal_meter, cali_info->thermal_value);
}
} else if (thermal_value < cali_info->thermal_value) { /*Low temperature*/
for (p = RF_PATH_A; p < c.rf_path_count; p++) {
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"Temperature Decreasing(%d): delta_pi: %d, delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
p, cali_info->power_index_offset[p], delta, thermal_value, hal_data->eeprom_thermal_meter, cali_info->thermal_value);
}
}
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
if (thermal_value > hal_data->eeprom_thermal_meter)
#else
if (thermal_value > dm->priv->pmib->dot11RFEntry.ther)
#endif
{
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"Temperature(%d) higher than PG value(%d)\n", thermal_value, hal_data->eeprom_thermal_meter);
if (dm->support_ic_type == ODM_RTL8188E || dm->support_ic_type == ODM_RTL8192E || dm->support_ic_type == ODM_RTL8821 ||
dm->support_ic_type == ODM_RTL8812 || dm->support_ic_type == ODM_RTL8723B || dm->support_ic_type == ODM_RTL8814A ||
dm->support_ic_type == ODM_RTL8703B || dm->support_ic_type == ODM_RTL8188F || dm->support_ic_type == ODM_RTL8822B ||
dm->support_ic_type == ODM_RTL8723D || dm->support_ic_type == ODM_RTL8821C || dm->support_ic_type == ODM_RTL8710B) {/* JJ ADD 20161014 */
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK, "**********Enter POWER Tracking MIX_MODE**********\n");
for (p = RF_PATH_A; p < c.rf_path_count; p++)
(*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0);
} else {
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK, "**********Enter POWER Tracking BBSWING_MODE**********\n");
for (p = RF_PATH_A; p < c.rf_path_count; p++)
(*c.odm_tx_pwr_track_set_pwr)(dm, BBSWING, p, indexforchannel);
}
} else {
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"Temperature(%d) lower than PG value(%d)\n", thermal_value, hal_data->eeprom_thermal_meter);
if (dm->support_ic_type == ODM_RTL8188E || dm->support_ic_type == ODM_RTL8192E || dm->support_ic_type == ODM_RTL8821 ||
dm->support_ic_type == ODM_RTL8812 || dm->support_ic_type == ODM_RTL8723B || dm->support_ic_type == ODM_RTL8814A ||
dm->support_ic_type == ODM_RTL8703B || dm->support_ic_type == ODM_RTL8188F || dm->support_ic_type == ODM_RTL8822B ||
dm->support_ic_type == ODM_RTL8723D || dm->support_ic_type == ODM_RTL8821C || dm->support_ic_type == ODM_RTL8710B) {/* JJ ADD 20161014 */
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK, "**********Enter POWER Tracking MIX_MODE**********\n");
for (p = RF_PATH_A; p < c.rf_path_count; p++)
(*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, indexforchannel);
} else {
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK, "**********Enter POWER Tracking BBSWING_MODE**********\n");
for (p = RF_PATH_A; p < c.rf_path_count; p++)
(*c.odm_tx_pwr_track_set_pwr)(dm, BBSWING, p, indexforchannel);
}
}
cali_info->bb_swing_idx_cck_base = cali_info->bb_swing_idx_cck; /*Record last time Power Tracking result as base.*/
for (p = RF_PATH_A; p < c.rf_path_count; p++)
cali_info->bb_swing_idx_ofdm_base[p] = cali_info->bb_swing_idx_ofdm[p];
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"cali_info->thermal_value = %d thermal_value= %d\n", cali_info->thermal_value, thermal_value);
cali_info->thermal_value = thermal_value; /*Record last Power Tracking Thermal value*/
}
if (dm->support_ic_type == ODM_RTL8703B || dm->support_ic_type == ODM_RTL8723D || dm->support_ic_type == ODM_RTL8710B) {/* JJ ADD 20161014 */
if (xtal_offset_eanble != 0 && cali_info->txpowertrack_control && (hal_data->eeprom_thermal_meter != 0xff)) {
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK, "**********Enter Xtal Tracking**********\n");
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
if (thermal_value > hal_data->eeprom_thermal_meter) {
#else
if (thermal_value > dm->priv->pmib->dot11RFEntry.ther) {
#endif
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"Temperature(%d) higher than PG value(%d)\n", thermal_value, hal_data->eeprom_thermal_meter);
(*c.odm_txxtaltrack_set_xtal)(dm);
} else {
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK,
"Temperature(%d) lower than PG value(%d)\n", thermal_value, hal_data->eeprom_thermal_meter);
(*c.odm_txxtaltrack_set_xtal)(dm);
}
}
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK, "**********End Xtal Tracking**********\n");
}
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
/* Wait sacn to do IQK by RF Jenyu*/
if ((*dm->is_scan_in_process == false) && (!iqk_info->rfk_forbidden)) {
if (!IS_HARDWARE_TYPE_8723B(adapter)) {
/*Delta temperature is equal to or larger than 20 centigrade (When threshold is 8).*/
if (delta_IQK >= c.threshold_iqk) {
cali_info->thermal_value_iqk = thermal_value;
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK, "delta_IQK(%d) >= threshold_iqk(%d)\n", delta_IQK, c.threshold_iqk);
if (!cali_info->is_iqk_in_progress)
(*c.do_iqk)(dm, delta_IQK, thermal_value, 8);
}
}
}
if (cali_info->dpk_thermal[RF_PATH_A] != 0) {
if (diff_DPK[RF_PATH_A] >= c.threshold_dpk) {
odm_set_bb_reg(dm, 0x82c, BIT(31), 0x1);
odm_set_bb_reg(dm, 0xcc4, BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), (diff_DPK[RF_PATH_A] / c.threshold_dpk));
odm_set_bb_reg(dm, 0x82c, BIT(31), 0x0);
} else if ((diff_DPK[RF_PATH_A] <= -1 * c.threshold_dpk)) {
s32 value = 0x20 + (diff_DPK[RF_PATH_A] / c.threshold_dpk);
odm_set_bb_reg(dm, 0x82c, BIT(31), 0x1);
odm_set_bb_reg(dm, 0xcc4, BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), value);
odm_set_bb_reg(dm, 0x82c, BIT(31), 0x0);
} else {
odm_set_bb_reg(dm, 0x82c, BIT(31), 0x1);
odm_set_bb_reg(dm, 0xcc4, BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), 0);
odm_set_bb_reg(dm, 0x82c, BIT(31), 0x0);
}
}
if (cali_info->dpk_thermal[RF_PATH_B] != 0) {
if (diff_DPK[RF_PATH_B] >= c.threshold_dpk) {
odm_set_bb_reg(dm, 0x82c, BIT(31), 0x1);
odm_set_bb_reg(dm, 0xec4, BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), (diff_DPK[RF_PATH_B] / c.threshold_dpk));
odm_set_bb_reg(dm, 0x82c, BIT(31), 0x0);
} else if ((diff_DPK[RF_PATH_B] <= -1 * c.threshold_dpk)) {
s32 value = 0x20 + (diff_DPK[RF_PATH_B] / c.threshold_dpk);
odm_set_bb_reg(dm, 0x82c, BIT(31), 0x1);
odm_set_bb_reg(dm, 0xec4, BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), value);
odm_set_bb_reg(dm, 0x82c, BIT(31), 0x0);
} else {
odm_set_bb_reg(dm, 0x82c, BIT(31), 0x1);
odm_set_bb_reg(dm, 0xec4, BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), 0);
odm_set_bb_reg(dm, 0x82c, BIT(31), 0x0);
}
}
#endif
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK, "<===odm_txpowertracking_callback_thermal_meter\n");
cali_info->tx_powercount = 0;
}
/* 3============================================================
* 3 IQ Calibration
* 3============================================================ */
void
odm_reset_iqk_result(
struct dm_struct *dm
)
{
return;
}
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
u8 odm_get_right_chnl_place_for_iqk(u8 chnl)
{
u8 channel_all[ODM_TARGET_CHNL_NUM_2G_5G] = {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 149, 151, 153, 155, 157, 159, 161, 163, 165
};
u8 place = chnl;
if (chnl > 14) {
for (place = 14; place < sizeof(channel_all); place++) {
if (channel_all[place] == chnl)
return place - 13;
}
}
return 0;
}
#endif
void
odm_iq_calibrate(
struct dm_struct *dm
)
{
void *adapter = dm->adapter;
struct dm_iqk_info *iqk_info = &dm->IQK_info;
RT_TRACE(COMP_SCAN, ODM_DBG_LOUD, ("=>%s\n" , __FUNCTION__));
#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
if (*dm->is_fcs_mode_enable)
return;
#endif
if ((dm->is_linked) && (!iqk_info->rfk_forbidden)) {
RT_TRACE(COMP_SCAN, ODM_DBG_LOUD, ("interval=%d ch=%d prech=%d scan=%s\n", dm->linked_interval,
*dm->channel, dm->pre_channel, *dm->is_scan_in_process == TRUE ? "TRUE":"FALSE"));
if (*dm->channel != dm->pre_channel) {
dm->pre_channel = *dm->channel;
dm->linked_interval = 0;
}
if ((dm->linked_interval < 3) && (!*dm->is_scan_in_process))
dm->linked_interval++;
if (dm->linked_interval == 2)
PHY_IQCalibrate((PADAPTER)adapter, false);
} else
dm->linked_interval = 0;
RT_TRACE(COMP_SCAN, ODM_DBG_LOUD, ("<=%s interval=%d ch=%d prech=%d scan=%s\n", __FUNCTION__, dm->linked_interval,
*dm->channel, dm->pre_channel, *dm->is_scan_in_process == TRUE?"TRUE":"FALSE"));
}
void phydm_rf_init(struct dm_struct *dm)
{
odm_txpowertracking_init(dm);
#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
odm_clear_txpowertracking_state(dm);
#endif
#if (DM_ODM_SUPPORT_TYPE & (ODM_AP))
#if (RTL8814A_SUPPORT == 1)
if (dm->support_ic_type & ODM_RTL8814A)
phy_iq_calibrate_8814a_init(dm);
#endif
#endif
}
void phydm_rf_watchdog(struct dm_struct *dm)
{
#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
odm_txpowertracking_check(dm);
if (dm->support_ic_type & ODM_IC_11AC_SERIES)
odm_iq_calibrate(dm);
#endif
}

View File

@ -0,0 +1,135 @@
/******************************************************************************
*
* 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__
#if (RTL8814A_SUPPORT == 1)
#if RT_PLATFORM == PLATFORM_MACOSX
#include "rtl8814a/halrf_iqk_8814a.h"
#else
#include "halrf/rtl8814a/halrf_iqk_8814a.h"
#endif
#endif
#if (RTL8822B_SUPPORT == 1)
#if RT_PLATFORM == PLATFORM_MACOSX
#include "rtl8822b/halrf_iqk_8822b.h"
#include "../../MAC/Halmac_type.h"
#else
#include "halrf/rtl8822b/halrf_iqk_8822b.h"
#include "../mac/Halmac_type.h"
#endif
#endif
#if RT_PLATFORM == PLATFORM_MACOSX
#include "halrf_powertracking_win.h"
#include "halrf_kfree.h"
#include "halrf_txgapcal.h"
#else
#include "halrf/halrf_powertracking_win.h"
#include "halrf/halrf_kfree.h"
#include "halrf/halrf_txgapcal.h"
#endif
#if (RTL8821C_SUPPORT == 1)
#if RT_PLATFORM == PLATFORM_MACOSX
#include "rtl8821c/halrf_iqk_8821c.h"
#else
#include "halrf/rtl8821c/halrf_iqk_8821c.h"
#endif
#endif
enum spur_cal_method {
PLL_RESET,
AFE_PHASE_SEL
};
enum pwrtrack_method {
BBSWING,
TXAGC,
MIX_MODE,
TSSI_MODE,
MIX_2G_TSSI_5G_MODE,
MIX_5G_TSSI_2G_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 *);
typedef void(*func_swing)(void *, u8 **, u8 **, u8 **, u8 **);
typedef void(*func_swing8814only)(void *, u8 **, u8 **, u8 **, u8 **);
typedef void (*func_swing_xtal)(void *, s8 **, s8 **);
typedef void (*func_set_xtal)(void *);
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_swing_xtal get_delta_swing_xtal_table;
func_set_xtal odm_txxtaltrack_set_xtal;
func_all_swing get_delta_all_swing_table;
};
void
configure_txpower_track(
struct dm_struct *dm,
struct txpwrtrack_cfg *config
);
void
odm_clear_txpowertracking_state(
struct dm_struct *dm
);
void
odm_txpowertracking_callback_thermal_meter(
#if (DM_ODM_SUPPORT_TYPE & ODM_AP)
struct dm_struct *dm
#else
void *adapter
#endif
);
#define ODM_TARGET_CHNL_NUM_2G_5G 59
void
odm_reset_iqk_result(
struct dm_struct *dm
);
u8
odm_get_right_chnl_place_for_iqk(
u8 chnl
);
void odm_iq_calibrate(struct dm_struct *dm);
void phydm_rf_init(struct dm_struct *dm);
void phydm_rf_watchdog(struct dm_struct *dm);
#endif /* #ifndef __HAL_PHY_RF_H__ */

1575
hal/phydm/halrf/halrf.c Normal file

File diff suppressed because it is too large Load Diff

455
hal/phydm/halrf/halrf.h Normal file
View File

@ -0,0 +1,455 @@
/******************************************************************************
*
* 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 full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef _HALRF_H__
#define _HALRF_H__
/*============================================================*/
/*include files*/
/*============================================================*/
#include "halrf/halrf_psd.h"
/*============================================================*/
/*Definition */
/*============================================================*/
/*IQK version*/
#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN))
#define IQK_VERSION_8188E "0x14"
#define IQK_VERSION_8192E "0x01"
#define IQK_VERSION_8723B "0x1e"
#define IQK_VERSION_8812A "0x01"
#define IQK_VERSION_8821A "0x01"
#elif (DM_ODM_SUPPORT_TYPE & (ODM_CE))
#define IQK_VERSION_8188E "0x01"
#define IQK_VERSION_8192E "0x01"
#define IQK_VERSION_8723B "0x1e"
#define IQK_VERSION_8812A "0x01"
#define IQK_VERSION_8821A "0x01"
#elif (DM_ODM_SUPPORT_TYPE & (ODM_AP))
#define IQK_VERSION_8188E "0x01"
#define IQK_VERSION_8192E "0x01"
#define IQK_VERSION_8723B "0x1e"
#define IQK_VERSION_8812A "0x01"
#define IQK_VERSION_8821A "0x01"
#endif
#define IQK_VERSION_8814A "0x0f"
#define IQK_VERSION_8188F "0x01"
#define IQK_VERSION_8197F "0x01"
#define IQK_VERSION_8703B "0x05"
#define IQK_VERSION_8710B "0x01"
#define IQK_VERSION_8723D "0x02"
#define IQK_VERSION_8822B "0x2f"
#define IQK_VERSION_8821C "0x23"
/*LCK version*/
#define LCK_VERSION_8188E "0x01"
#define LCK_VERSION_8192E "0x01"
#define LCK_VERSION_8723B "0x01"
#define LCK_VERSION_8812A "0x01"
#define LCK_VERSION_8821A "0x01"
#define LCK_VERSION_8814A "0x01"
#define LCK_VERSION_8188F "0x01"
#define LCK_VERSION_8197F "0x01"
#define LCK_VERSION_8703B "0x01"
#define LCK_VERSION_8710B "0x01"
#define LCK_VERSION_8723D "0x01"
#define LCK_VERSION_8822B "0x01"
#define LCK_VERSION_8821C "0x01"
/*power tracking version*/
#define POWERTRACKING_VERSION_8188E "0x01"
#define POWERTRACKING_VERSION_8192E "0x01"
#define POWERTRACKING_VERSION_8723B "0x01"
#define POWERTRACKING_VERSION_8812A "0x01"
#define POWERTRACKING_VERSION_8821A "0x01"
#define POWERTRACKING_VERSION_8814A "0x01"
#define POWERTRACKING_VERSION_8188F "0x01"
#define POWERTRACKING_VERSION_8197F "0x01"
#define POWERTRACKING_VERSION_8703B "0x01"
#define POWERTRACKING_VERSION_8710B "0x01"
#define POWERTRACKING_VERSION_8723D "0x01"
#define POWERTRACKING_VERSION_8822B "0x01"
#define POWERTRACKING_VERSION_8821C "0x01"
/*DPK tracking version*/
#define DPK_VERSION_8188E "NONE"
#define DPK_VERSION_8192E "NONE"
#define DPK_VERSION_8723B "NONE"
#define DPK_VERSION_8812A "NONE"
#define DPK_VERSION_8821A "NONE"
#define DPK_VERSION_8814A "NONE"
#define DPK_VERSION_8188F "NONE"
#define DPK_VERSION_8197F "NONE"
#define DPK_VERSION_8703B "NONE"
#define DPK_VERSION_8710B "NONE"
#define DPK_VERSION_8723D "NONE"
#define DPK_VERSION_8822B "NONE"
#define DPK_VERSION_8821C "NONE"
/*Kfree tracking version*/
#define KFREE_VERSION_8188E (dm->power_trim_data.flag & KFREE_FLAG_ON)? "0x01" : "NONE"
#define KFREE_VERSION_8192E (dm->power_trim_data.flag & KFREE_FLAG_ON)? "0x01" : "NONE"
#define KFREE_VERSION_8723B (dm->power_trim_data.flag & KFREE_FLAG_ON)? "0x01" : "NONE"
#define KFREE_VERSION_8812A (dm->power_trim_data.flag & KFREE_FLAG_ON)? "0x01" : "NONE"
#define KFREE_VERSION_8821A (dm->power_trim_data.flag & KFREE_FLAG_ON)? "0x01" : "NONE"
#define KFREE_VERSION_8814A (dm->power_trim_data.flag & KFREE_FLAG_ON)? "0x01" : "NONE"
#define KFREE_VERSION_8188F (dm->power_trim_data.flag & KFREE_FLAG_ON)? "0x01" : "NONE"
#define KFREE_VERSION_8197F (dm->power_trim_data.flag & KFREE_FLAG_ON)? "0x01" : "NONE"
#define KFREE_VERSION_8703B (dm->power_trim_data.flag & KFREE_FLAG_ON)? "0x01" : "NONE"
#define KFREE_VERSION_8710B (dm->power_trim_data.flag & KFREE_FLAG_ON)? "0x01" : "NONE"
#define KFREE_VERSION_8723D (dm->power_trim_data.flag & KFREE_FLAG_ON)? "0x01" : "NONE"
#define KFREE_VERSION_8822B (dm->power_trim_data.flag & KFREE_FLAG_ON)? "0x01" : "NONE"
#define KFREE_VERSION_8821C (dm->power_trim_data.flag & KFREE_FLAG_ON)? "0x01" : "NONE"
/*PA Bias Calibration version*/
#define PABIASK_VERSION_8188E (dm->power_trim_data.pa_bias_flag & PA_BIAS_FLAG_ON)? "0x01" : "NONE"
#define PABIASK_VERSION_8192E (dm->power_trim_data.pa_bias_flag & PA_BIAS_FLAG_ON)? "0x01" : "NONE"
#define PABIASK_VERSION_8723B (dm->power_trim_data.pa_bias_flag & PA_BIAS_FLAG_ON)? "0x01" : "NONE"
#define PABIASK_VERSION_8812A (dm->power_trim_data.pa_bias_flag & PA_BIAS_FLAG_ON)? "0x01" : "NONE"
#define PABIASK_VERSION_8821A (dm->power_trim_data.pa_bias_flag & PA_BIAS_FLAG_ON)? "0x01" : "NONE"
#define PABIASK_VERSION_8814A (dm->power_trim_data.pa_bias_flag & PA_BIAS_FLAG_ON)? "0x01" : "NONE"
#define PABIASK_VERSION_8188F (dm->power_trim_data.pa_bias_flag & PA_BIAS_FLAG_ON)? "0x01" : "NONE"
#define PABIASK_VERSION_8197F (dm->power_trim_data.pa_bias_flag & PA_BIAS_FLAG_ON)? "0x01" : "NONE"
#define PABIASK_VERSION_8703B (dm->power_trim_data.pa_bias_flag & PA_BIAS_FLAG_ON)? "0x01" : "NONE"
#define PABIASK_VERSION_8710B (dm->power_trim_data.pa_bias_flag & PA_BIAS_FLAG_ON)? "0x01" : "NONE"
#define PABIASK_VERSION_8723D (dm->power_trim_data.pa_bias_flag & PA_BIAS_FLAG_ON)? "0x01" : "NONE"
#define PABIASK_VERSION_8822B (dm->power_trim_data.pa_bias_flag & PA_BIAS_FLAG_ON)? "0x01" : "NONE"
#define PABIASK_VERSION_8821C (dm->power_trim_data.pa_bias_flag & PA_BIAS_FLAG_ON)? "0x01" : "NONE"
#define HALRF_IQK_VER (dm->support_ic_type == ODM_RTL8188E)? IQK_VERSION_8188E :\
(dm->support_ic_type == ODM_RTL8192E)? IQK_VERSION_8192E :\
(dm->support_ic_type == ODM_RTL8723B)? IQK_VERSION_8723B :\
(dm->support_ic_type == ODM_RTL8812)? IQK_VERSION_8812A :\
(dm->support_ic_type == ODM_RTL8821)? IQK_VERSION_8821A :\
(dm->support_ic_type == ODM_RTL8814A)? IQK_VERSION_8814A :\
(dm->support_ic_type == ODM_RTL8188F)? IQK_VERSION_8188F :\
(dm->support_ic_type == ODM_RTL8197F)? IQK_VERSION_8197F :\
(dm->support_ic_type == ODM_RTL8703B)? IQK_VERSION_8703B :\
(dm->support_ic_type == ODM_RTL8710B)? IQK_VERSION_8710B :\
(dm->support_ic_type == ODM_RTL8723D)? IQK_VERSION_8723D :\
(dm->support_ic_type == ODM_RTL8822B)? IQK_VERSION_8822B :\
(dm->support_ic_type == ODM_RTL8821C)? IQK_VERSION_8821C :"unknown"
#define HALRF_LCK_VER (dm->support_ic_type == ODM_RTL8188E)? LCK_VERSION_8188E :\
(dm->support_ic_type == ODM_RTL8192E)? LCK_VERSION_8192E :\
(dm->support_ic_type == ODM_RTL8723B)? LCK_VERSION_8723B :\
(dm->support_ic_type == ODM_RTL8812)? LCK_VERSION_8812A :\
(dm->support_ic_type == ODM_RTL8821)? LCK_VERSION_8821A :\
(dm->support_ic_type == ODM_RTL8814A)? LCK_VERSION_8814A :\
(dm->support_ic_type == ODM_RTL8188F)? LCK_VERSION_8188F :\
(dm->support_ic_type == ODM_RTL8197F)? LCK_VERSION_8197F :\
(dm->support_ic_type == ODM_RTL8703B)? LCK_VERSION_8703B :\
(dm->support_ic_type == ODM_RTL8710B)? LCK_VERSION_8710B :\
(dm->support_ic_type == ODM_RTL8723D)? LCK_VERSION_8723D :\
(dm->support_ic_type == ODM_RTL8822B)? LCK_VERSION_8822B :\
(dm->support_ic_type == ODM_RTL8821C)? LCK_VERSION_8821C :"unknown"
#define HALRF_POWRTRACKING_VER (dm->support_ic_type == ODM_RTL8188E)? POWERTRACKING_VERSION_8188E :\
(dm->support_ic_type == ODM_RTL8192E)? POWERTRACKING_VERSION_8192E :\
(dm->support_ic_type == ODM_RTL8723B)? POWERTRACKING_VERSION_8723B :\
(dm->support_ic_type == ODM_RTL8812)? POWERTRACKING_VERSION_8812A :\
(dm->support_ic_type == ODM_RTL8821)? POWERTRACKING_VERSION_8821A :\
(dm->support_ic_type == ODM_RTL8814A)? POWERTRACKING_VERSION_8814A :\
(dm->support_ic_type == ODM_RTL8188F)? POWERTRACKING_VERSION_8188F :\
(dm->support_ic_type == ODM_RTL8197F)? POWERTRACKING_VERSION_8197F :\
(dm->support_ic_type == ODM_RTL8703B)? POWERTRACKING_VERSION_8703B :\
(dm->support_ic_type == ODM_RTL8710B)? POWERTRACKING_VERSION_8710B :\
(dm->support_ic_type == ODM_RTL8723D)? POWERTRACKING_VERSION_8723D :\
(dm->support_ic_type == ODM_RTL8822B)? POWERTRACKING_VERSION_8822B :\
(dm->support_ic_type == ODM_RTL8821C)? POWERTRACKING_VERSION_8821C :"unknown"
#define HALRF_DPK_VER (dm->support_ic_type == ODM_RTL8188E)? DPK_VERSION_8188E :\
(dm->support_ic_type == ODM_RTL8192E)? DPK_VERSION_8192E :\
(dm->support_ic_type == ODM_RTL8723B)? DPK_VERSION_8723B :\
(dm->support_ic_type == ODM_RTL8812)? DPK_VERSION_8812A :\
(dm->support_ic_type == ODM_RTL8821)? DPK_VERSION_8821A :\
(dm->support_ic_type == ODM_RTL8814A)? DPK_VERSION_8814A :\
(dm->support_ic_type == ODM_RTL8188F)? DPK_VERSION_8188F :\
(dm->support_ic_type == ODM_RTL8197F)? DPK_VERSION_8197F :\
(dm->support_ic_type == ODM_RTL8703B)? DPK_VERSION_8703B :\
(dm->support_ic_type == ODM_RTL8710B)? DPK_VERSION_8710B :\
(dm->support_ic_type == ODM_RTL8723D)? DPK_VERSION_8723D :\
(dm->support_ic_type == ODM_RTL8822B)? DPK_VERSION_8822B :\
(dm->support_ic_type == ODM_RTL8821C)? DPK_VERSION_8821C :"unknown"
#define HALRF_KFREE_VER (dm->support_ic_type == ODM_RTL8188E)? KFREE_VERSION_8188E :\
(dm->support_ic_type == ODM_RTL8192E)? KFREE_VERSION_8192E :\
(dm->support_ic_type == ODM_RTL8723B)? KFREE_VERSION_8723B :\
(dm->support_ic_type == ODM_RTL8812)? KFREE_VERSION_8812A :\
(dm->support_ic_type == ODM_RTL8821)? KFREE_VERSION_8821A :\
(dm->support_ic_type == ODM_RTL8814A)? KFREE_VERSION_8814A :\
(dm->support_ic_type == ODM_RTL8188F)? KFREE_VERSION_8188F :\
(dm->support_ic_type == ODM_RTL8197F)? KFREE_VERSION_8197F :\
(dm->support_ic_type == ODM_RTL8703B)? KFREE_VERSION_8703B :\
(dm->support_ic_type == ODM_RTL8710B)? KFREE_VERSION_8710B :\
(dm->support_ic_type == ODM_RTL8723D)? KFREE_VERSION_8723D :\
(dm->support_ic_type == ODM_RTL8822B)? KFREE_VERSION_8822B :\
(dm->support_ic_type == ODM_RTL8821C)? KFREE_VERSION_8821C :"unknown"
#define HALRF_PABIASK_VER (dm->support_ic_type == ODM_RTL8188E)? PABIASK_VERSION_8188E :\
(dm->support_ic_type == ODM_RTL8192E)? PABIASK_VERSION_8192E :\
(dm->support_ic_type == ODM_RTL8723B)? PABIASK_VERSION_8723B :\
(dm->support_ic_type == ODM_RTL8812)? PABIASK_VERSION_8812A :\
(dm->support_ic_type == ODM_RTL8821)? PABIASK_VERSION_8821A :\
(dm->support_ic_type == ODM_RTL8814A)? PABIASK_VERSION_8814A :\
(dm->support_ic_type == ODM_RTL8188F)? PABIASK_VERSION_8188F :\
(dm->support_ic_type == ODM_RTL8197F)? PABIASK_VERSION_8197F :\
(dm->support_ic_type == ODM_RTL8703B)? PABIASK_VERSION_8703B :\
(dm->support_ic_type == ODM_RTL8710B)? PABIASK_VERSION_8710B :\
(dm->support_ic_type == ODM_RTL8723D)? PABIASK_VERSION_8723D :\
(dm->support_ic_type == ODM_RTL8822B)? PABIASK_VERSION_8822B :\
(dm->support_ic_type == ODM_RTL8821C)? PABIASK_VERSION_8821C :"unknown"
#define IQK_THRESHOLD 8
#define DPK_THRESHOLD 4
/*===========================================================*/
/*AGC RX High Power mode*/
/*===========================================================*/
#define lna_low_gain_1 0x64
#define lna_low_gain_2 0x5A
#define lna_low_gain_3 0x58
/*============================================================*/
/* enumeration */
/*============================================================*/
enum halrf_ability {
HAL_RF_TX_PWR_TRACK = BIT(0),
HAL_RF_IQK = BIT(1),
HAL_RF_LCK = BIT(2),
HAL_RF_DPK = BIT(3),
HAL_RF_TXGAPK = BIT(4)
};
enum halrf_cmninfo_init {
HALRF_CMNINFO_ABILITY = 0,
HALRF_CMNINFO_DPK_EN = 1,
HALRF_CMNINFO_EEPROM_THERMAL_VALUE,
HALRF_CMNINFO_FW_VER,
HALRF_CMNINFO_RFK_FORBIDDEN,
HALRF_CMNINFO_IQK_SEGMENT,
HALRF_CMNINFO_RATE_INDEX,
HALRF_CMNINFO_MP_PSD_POINT,
HALRF_CMNINFO_MP_PSD_START_POINT,
HALRF_CMNINFO_MP_PSD_STOP_POINT,
HALRF_CMNINFO_MP_PSD_AVERAGE
};
enum halrf_cmninfo_hook {
HALRF_CMNINFO_CON_TX,
HALRF_CMNINFO_SINGLE_TONE,
HALRF_CMNINFO_CARRIER_SUPPRESSION,
HALRF_CMNINFO_MP_RATE_INDEX
};
enum phydm_lna_set {
phydm_lna_disable = 0,
phydm_lna_enable = 1,
};
/*============================================================*/
/* structure */
/*============================================================*/
struct _hal_rf_ {
/*hook*/
u8 *test1;
/*update*/
u32 rf_supportability;
u8 eeprom_thermal;
u8 dpk_en; /*Enable Function DPK OFF/ON = 0/1*/
boolean dpk_done;
u32 fw_ver;
boolean *is_con_tx;
boolean *is_single_tone;
boolean *is_carrier_suppresion;
u8 *mp_rate_index;
u32 p_rate_index;
#if (DM_ODM_SUPPORT_TYPE & ODM_WIN)
struct _halrf_psd_data halrf_psd_data;
#endif
};
/*============================================================*/
/* function prototype */
/*============================================================*/
void halrf_basic_profile(
void *dm_void,
u32 *_used,
char *output,
u32 *_out_len
);
#if (RTL8822B_SUPPORT == 1 || RTL8821C_SUPPORT == 1)
void halrf_iqk_info_dump(
void *dm_void,
u32 *_used,
char *output,
u32 *_out_len
);
void
halrf_iqk_hwtx_check(
void *dm_void,
boolean is_check
);
#endif
u8
halrf_match_iqk_version(
void *dm_void
);
void
halrf_support_ability_debug(
void *dm_void,
char input[][16],
u32 *_used,
char *output,
u32 *_out_len
);
void
halrf_cmn_info_init(
void *dm_void,
enum halrf_cmninfo_init cmn_info,
u32 value
);
void
halrf_cmn_info_hook(
void *dm_void,
u32 cmn_info,
void *value
);
void
halrf_cmn_info_set(
void *dm_void,
u32 cmn_info,
u64 value
);
u64
halrf_cmn_info_get(
void *dm_void,
u32 cmn_info
);
void
halrf_watchdog(
void *dm_void
);
void
halrf_supportability_init(
void *dm_void
);
void
halrf_init(
void *dm_void
);
void
halrf_iqk_trigger(
void *dm_void,
boolean is_recovery
);
void
halrf_segment_iqk_trigger(
void *dm_void,
boolean clear,
boolean segment_iqk
);
void
halrf_lck_trigger(
void *dm_void
);
void
halrf_iqk_debug(
void *dm_void,
u32 *const dm_value,
u32 *_used,
char *output,
u32 *_out_len
);
void
phydm_get_iqk_cfir(
void *dm_void,
u8 idx,
u8 path,
boolean debug
);
void
halrf_iqk_xym_read(
void *dm_void,
u8 path,
u8 xym_type
);
void
halrf_rf_lna_setting(
void *dm_void,
enum phydm_lna_set type
);
void
halrf_do_imr_test(
void *dm_void,
u8 data
);
u32
halrf_psd_log2base(
u32 val
);
#if (RTL8822B_SUPPORT == 1 || RTL8821C_SUPPORT == 1)
void halrf_iqk_dbg(void *dm_void);
#endif
#endif

View File

@ -0,0 +1,43 @@
/******************************************************************************
*
* 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 full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __HALRF_FEATURES_H__
#define __HALRF_FEATURES
#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
#define CONFIG_HALRF_POWERTRACKING 1
#elif (DM_ODM_SUPPORT_TYPE == ODM_AP)
#define CONFIG_HALRF_POWERTRACKING 1
#elif (DM_ODM_SUPPORT_TYPE == ODM_CE)
#define CONFIG_HALRF_POWERTRACKING 1
#endif
#endif

View File

@ -0,0 +1,85 @@
/******************************************************************************
*
* 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 full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __PHYDMIQK_H__
#define __PHYDMIQK_H__
/*--------------------------Define Parameters-------------------------------*/
#define LOK_delay 1
#define WBIQK_delay 10
#define TX_IQK 0
#define RX_IQK 1
#define TXIQK 0
#define RXIQK1 1
#define RXIQK2 2
#define kcount_limit_80m 2
#define kcount_limit_others 4
#define rxiqk_gs_limit 10
#define NUM 4
/*---------------------------End Define Parameters-------------------------------*/
struct dm_iqk_info {
boolean lok_fail[NUM];
boolean iqk_fail[2][NUM];
u32 iqc_matrix[2][NUM];
u8 iqk_times;
u32 rf_reg18;
u32 lna_idx;
u8 rxiqk_step;
u8 tmp1bcc;
u8 kcount;
u8 rfk_ing; /*bit0:IQKing, bit1:LCKing, bit2:DPKing*/
boolean rfk_forbidden;
#if (RTL8814A_SUPPORT == 1 || RTL8822B_SUPPORT == 1 || RTL8821C_SUPPORT == 1)
u32 iqk_channel[2];
boolean iqk_fail_report[2][4][2]; /*channel/path/TRX(TX:0, RX:1) */
u32 iqk_cfir_real[3][4][2][8]; /*channel / path / TRX(TX:0, RX:1) / CFIR_real*/ /*channel index = 2 is just for debug*/
u32 iqk_cfir_imag[3][4][2][8]; /*channel / path / TRX(TX:0, RX:1) / CFIR_imag*/ /*channel index = 2 is just for debug*/
u8 retry_count[2][4][3]; /* channel / path / (TXK:0, RXK1:1, RXK2:2) */
u8 gs_retry_count[2][4][2]; /* channel / path / (GSRXK1:0, GSRXK2:1) */
u8 rxiqk_fail_code[2][4]; /* channel / path 0:SRXK1 fail, 1:RXK1 fail 2:RXK2 fail */
u32 lok_idac[2][4]; /*channel / path*/
u16 rxiqk_agc[2][4]; /*channel / path*/
u32 bypass_iqk[2][4]; /*channel / 0xc94/0xe94*/
u32 txgap_result[8]; /*txagpK result */
u32 tmp_gntwl;
boolean is_btg;
boolean isbnd;
boolean is_reload;
boolean segment_iqk;
boolean is_hwtx;
boolean xym_read;
boolean trximr_enable;
u32 rx_xym[2][10];
u32 tx_xym[2][10];
u32 gs1_xym[2][6];
u32 gs2_xym[2][6];
u32 rxk1_xym[2][6];
#endif
};
#endif

View File

@ -0,0 +1,883 @@
/******************************************************************************
*
* 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 full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
/*============================================================*/
/*include files*/
/*============================================================*/
#include "mp_precomp.h"
#include "phydm_precomp.h"
/*<YuChen, 150720> Add for KFree Feature Requested by RF David.*/
/*This is a phydm API*/
void
phydm_set_kfree_to_rf_8814a(
void *dm_void,
u8 e_rf_path,
u8 data
)
{
struct dm_struct *dm = (struct dm_struct *)dm_void;
struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
boolean is_odd;
if ((data % 2) != 0) { /*odd->positive*/
data = data - 1;
odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(19), 1);
is_odd = true;
} else { /*even->negative*/
odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(19), 0);
is_odd = false;
}
PHYDM_DBG(dm, ODM_COMP_MP, "phy_ConfigKFree8814A(): RF_0x55[19]= %d\n", is_odd);
switch (data) {
case 0:
odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), 0);
odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(17) | BIT(16) | BIT(15), 0);
cali_info->kfree_offset[e_rf_path] = 0;
break;
case 2:
odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), 1);
odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(17) | BIT(16) | BIT(15), 0);
cali_info->kfree_offset[e_rf_path] = 0;
break;
case 4:
odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), 0);
odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(17) | BIT(16) | BIT(15), 1);
cali_info->kfree_offset[e_rf_path] = 1;
break;
case 6:
odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), 1);
odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(17) | BIT(16) | BIT(15), 1);
cali_info->kfree_offset[e_rf_path] = 1;
break;
case 8:
odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), 0);
odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(17) | BIT(16) | BIT(15), 2);
cali_info->kfree_offset[e_rf_path] = 2;
break;
case 10:
odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), 1);
odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(17) | BIT(16) | BIT(15), 2);
cali_info->kfree_offset[e_rf_path] = 2;
break;
case 12:
odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), 0);
odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(17) | BIT(16) | BIT(15), 3);
cali_info->kfree_offset[e_rf_path] = 3;
break;
case 14:
odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), 1);
odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(17) | BIT(16) | BIT(15), 3);
cali_info->kfree_offset[e_rf_path] = 3;
break;
case 16:
odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), 0);
odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(17) | BIT(16) | BIT(15), 4);
cali_info->kfree_offset[e_rf_path] = 4;
break;
case 18:
odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), 1);
odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(17) | BIT(16) | BIT(15), 4);
cali_info->kfree_offset[e_rf_path] = 4;
break;
case 20:
odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), 0);
odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(17) | BIT(16) | BIT(15), 5);
cali_info->kfree_offset[e_rf_path] = 5;
break;
default:
break;
}
if (is_odd == false) {
/*that means Kfree offset is negative, we need to record it.*/
cali_info->kfree_offset[e_rf_path] = (-1) * cali_info->kfree_offset[e_rf_path];
PHYDM_DBG(dm, ODM_COMP_MP, "phy_ConfigKFree8814A(): kfree_offset = %d\n", cali_info->kfree_offset[e_rf_path]);
} else
PHYDM_DBG(dm, ODM_COMP_MP, "phy_ConfigKFree8814A(): kfree_offset = %d\n", cali_info->kfree_offset[e_rf_path]);
}
//
//
//
void
phydm_get_thermal_trim_offset_8821c(
void *dm_void
)
{
struct dm_struct *dm = (struct dm_struct *)dm_void;
struct odm_power_trim_data *power_trim_info = &dm->power_trim_data;
u8 pg_therm = 0xff;
odm_efuse_one_byte_read(dm, PPG_THERMAL_OFFSET_8821C, &pg_therm, false);
if (pg_therm != 0xff) {
pg_therm = pg_therm & 0x1f;
if ((pg_therm & BIT(0)) == 0)
power_trim_info->thermal = (-1 * (pg_therm >> 1));
else
power_trim_info->thermal = (pg_therm >> 1);
power_trim_info->flag |= KFREE_FLAG_THERMAL_K_ON;
}
PHYDM_DBG(dm, ODM_COMP_MP, "[kfree] 8821c thermal trim flag:0x%02x\n", power_trim_info->flag);
if (power_trim_info->flag & KFREE_FLAG_THERMAL_K_ON)
PHYDM_DBG(dm, ODM_COMP_MP, "[kfree] 8821c thermal:%d\n", power_trim_info->thermal);
}
void
phydm_get_power_trim_offset_8821c(
void *dm_void
)
{
struct dm_struct *dm = (struct dm_struct *)dm_void;
struct odm_power_trim_data *power_trim_info = &dm->power_trim_data;
u8 pg_power = 0xff, i;
odm_efuse_one_byte_read(dm, PPG_BB_GAIN_2G_TXAB_OFFSET_8821C, &pg_power, false);
if (pg_power != 0xff) {
power_trim_info->bb_gain[0][0] = pg_power;
odm_efuse_one_byte_read(dm, PPG_BB_GAIN_5GL1_TXA_OFFSET_8821C, &pg_power, false);
power_trim_info->bb_gain[1][0] = pg_power;
odm_efuse_one_byte_read(dm, PPG_BB_GAIN_5GL2_TXA_OFFSET_8821C, &pg_power, false);
power_trim_info->bb_gain[2][0] = pg_power;
odm_efuse_one_byte_read(dm, PPG_BB_GAIN_5GM1_TXA_OFFSET_8821C, &pg_power, false);
power_trim_info->bb_gain[3][0] = pg_power;
odm_efuse_one_byte_read(dm, PPG_BB_GAIN_5GM2_TXA_OFFSET_8821C, &pg_power, false);
power_trim_info->bb_gain[4][0] = pg_power;
odm_efuse_one_byte_read(dm, PPG_BB_GAIN_5GH1_TXA_OFFSET_8821C, &pg_power, false);
power_trim_info->bb_gain[5][0] = pg_power;
power_trim_info->flag = power_trim_info->flag | KFREE_FLAG_ON | KFREE_FLAG_ON_2G | KFREE_FLAG_ON_5G;
}
PHYDM_DBG(dm, ODM_COMP_MP, "[kfree] 8821c power trim flag:0x%02x\n", power_trim_info->flag);
if (power_trim_info->flag & KFREE_FLAG_ON) {
for (i = 0; i < KFREE_BAND_NUM; i++)
PHYDM_DBG(dm, ODM_COMP_MP, "[kfree] 8821c power_trim_data->bb_gain[%d][0]=0x%X\n", i, power_trim_info->bb_gain[i][0]);
}
}
void
phydm_set_kfree_to_rf_8821c(
void *dm_void,
u8 e_rf_path,
boolean wlg_btg,
u8 data
)
{
struct dm_struct *dm = (struct dm_struct *)dm_void;
struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
u8 wlg, btg;
odm_set_rf_reg(dm, e_rf_path, 0xde, BIT(0), 1);
odm_set_rf_reg(dm, e_rf_path, 0xde, BIT(5), 1);
odm_set_rf_reg(dm, e_rf_path, 0x55, BIT(6), 1);
odm_set_rf_reg(dm, e_rf_path, 0x65, BIT(6), 1);
if (wlg_btg == true) {
wlg = data & 0xf;
btg = (data & 0xf0) >> 4;
odm_set_rf_reg(dm, e_rf_path, 0x55, BIT(19), (wlg & BIT(0)));
odm_set_rf_reg(dm, e_rf_path, 0x55, (BIT(18) | BIT(17) | BIT(16) | BIT(15) | BIT(14)), (wlg >> 1));
odm_set_rf_reg(dm, e_rf_path, 0x65, BIT(19), (btg & BIT(0)));
odm_set_rf_reg(dm, e_rf_path, 0x65, (BIT(18) | BIT(17) | BIT(16) | BIT(15) | BIT(14)), (btg >> 1));
} else {
odm_set_rf_reg(dm, e_rf_path, 0x55, BIT(19), (data & BIT(0)));
odm_set_rf_reg(dm, e_rf_path, 0x55, (BIT(18) | BIT(17) | BIT(16) | BIT(15) | BIT(14)), ((data & 0x1f) >> 1));
}
PHYDM_DBG(dm, ODM_COMP_CALIBRATION,"[kfree] 8821c 0x55[19:14]=0x%X 0x65[19:14]=0x%X\n",
odm_get_rf_reg(dm, e_rf_path, 0x55, (BIT(19) | BIT(18) | BIT(17) | BIT(16) | BIT(15) | BIT(14))),
odm_get_rf_reg(dm, e_rf_path, 0x65, (BIT(19) | BIT(18) | BIT(17) | BIT(16) | BIT(15) | BIT(14)))
);
}
void
phydm_clear_kfree_to_rf_8821c(
void *dm_void,
u8 e_rf_path,
u8 data
)
{
struct dm_struct *dm = (struct dm_struct *)dm_void;
struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
odm_set_rf_reg(dm, e_rf_path, 0xde, BIT(0), 1);
odm_set_rf_reg(dm, e_rf_path, 0xde, BIT(5), 1);
odm_set_rf_reg(dm, e_rf_path, 0x55, BIT(6), 1);
odm_set_rf_reg(dm, e_rf_path, 0x65, BIT(6), 1);
odm_set_rf_reg(dm, e_rf_path, 0x55, BIT(19), (data & BIT(0)));
odm_set_rf_reg(dm, e_rf_path, 0x55, (BIT(18) | BIT(17) | BIT(16) | BIT(15) | BIT(14)), (data >> 1));
odm_set_rf_reg(dm, e_rf_path, 0x65, BIT(19), (data & BIT(0)));
odm_set_rf_reg(dm, e_rf_path, 0x65, (BIT(18) | BIT(17) | BIT(16) | BIT(15) | BIT(14)), (data >> 1));
odm_set_rf_reg(dm, e_rf_path, 0xde, BIT(0), 0);
odm_set_rf_reg(dm, e_rf_path, 0xde, BIT(5), 0);
odm_set_rf_reg(dm, e_rf_path, 0x55, BIT(6), 0);
odm_set_rf_reg(dm, e_rf_path, 0x65, BIT(6), 0);
PHYDM_DBG(dm, ODM_COMP_CALIBRATION,"[kfree] 8821c 0x55[19:14]=0x%X 0x65[19:14]=0x%X\n",
odm_get_rf_reg(dm, e_rf_path, 0x55, (BIT(19) | BIT(18) | BIT(17) | BIT(16) | BIT(15) | BIT(14))),
odm_get_rf_reg(dm, e_rf_path, 0x65, (BIT(19) | BIT(18) | BIT(17) | BIT(16) | BIT(15) | BIT(14)))
);
}
void
phydm_get_thermal_trim_offset_8822b(
void *dm_void
)
{
struct dm_struct *dm = (struct dm_struct *)dm_void;
struct odm_power_trim_data *power_trim_info = &dm->power_trim_data;
u8 pg_therm = 0xff;
#if 0
u32 thermal_trim_enable = 0xff;
odm_efuse_logical_map_read(dm, 1, 0xc8, &thermal_trim_enable);
PHYDM_DBG(dm, ODM_COMP_MP, "[kfree] 8822b 0xc8:0x%2x\n", thermal_trim_enable);
thermal_trim_enable = (thermal_trim_enable & BIT(5)) >> 5;
PHYDM_DBG(dm, ODM_COMP_MP, "[kfree] 8822b thermal trim Enable:%d\n", thermal_trim_enable);
if ((cali_info->reg_rf_kfree_enable == 0 && thermal_trim_enable == 1) ||
cali_info->reg_rf_kfree_enable == 1) {
#endif
odm_efuse_one_byte_read(dm, PPG_THERMAL_OFFSET, &pg_therm, false);
if (pg_therm != 0xff) {
pg_therm = pg_therm & 0x1f;
if ((pg_therm & BIT(0)) == 0)
power_trim_info->thermal = (-1 * (pg_therm >> 1));
else
power_trim_info->thermal = (pg_therm >> 1);
power_trim_info->flag |= KFREE_FLAG_THERMAL_K_ON;
}
PHYDM_DBG(dm, ODM_COMP_MP, "[kfree] 8822b thermal trim flag:0x%02x\n", power_trim_info->flag);
if (power_trim_info->flag & KFREE_FLAG_THERMAL_K_ON)
PHYDM_DBG(dm, ODM_COMP_MP, "[kfree] 8822b thermal:%d\n", power_trim_info->thermal);
#if 0
} else
return;
#endif
}
void
phydm_get_power_trim_offset_8822b(
void *dm_void
)
{
struct dm_struct *dm = (struct dm_struct *)dm_void;
struct odm_power_trim_data *power_trim_info = &dm->power_trim_data;
struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
u8 pg_power = 0xff, i, j;
#if 0
u32 power_trim_enable = 0xff;
odm_efuse_logical_map_read(dm, 1, 0xc8, &power_trim_enable);
PHYDM_DBG(dm, ODM_COMP_MP, "[kfree] 8822b 0xc8:0x%2x\n", power_trim_enable);
power_trim_enable = (power_trim_enable & BIT(4)) >> 4;
PHYDM_DBG(dm, ODM_COMP_MP, "[kfree] 8822b power trim Enable:%d\n", power_trim_enable);
if ((cali_info->reg_rf_kfree_enable == 0 && power_trim_enable == 1) ||
cali_info->reg_rf_kfree_enable == 1) {
#endif
odm_efuse_one_byte_read(dm, PPG_BB_GAIN_2G_TXAB_OFFSET, &pg_power, false);
if (pg_power != 0xff) {
/*Path A*/
odm_efuse_one_byte_read(dm, PPG_BB_GAIN_2G_TXAB_OFFSET, &pg_power, false);
power_trim_info->bb_gain[0][0] = (pg_power & 0xf);
/*Path B*/
odm_efuse_one_byte_read(dm, PPG_BB_GAIN_2G_TXAB_OFFSET, &pg_power, false);
power_trim_info->bb_gain[0][1] = ((pg_power & 0xf0) >> 4);
power_trim_info->flag |= KFREE_FLAG_ON_2G;
power_trim_info->flag |= KFREE_FLAG_ON;
}
odm_efuse_one_byte_read(dm, PPG_BB_GAIN_5GL1_TXA_OFFSET, &pg_power, false);
if (pg_power != 0xff) {
/*Path A*/
odm_efuse_one_byte_read(dm, PPG_BB_GAIN_5GL1_TXA_OFFSET, &pg_power, false);
power_trim_info->bb_gain[1][0] = pg_power;
odm_efuse_one_byte_read(dm, PPG_BB_GAIN_5GL2_TXA_OFFSET, &pg_power, false);
power_trim_info->bb_gain[2][0] = pg_power;
odm_efuse_one_byte_read(dm, PPG_BB_GAIN_5GM1_TXA_OFFSET, &pg_power, false);
power_trim_info->bb_gain[3][0] = pg_power;
odm_efuse_one_byte_read(dm, PPG_BB_GAIN_5GM2_TXA_OFFSET, &pg_power, false);
power_trim_info->bb_gain[4][0] = pg_power;
odm_efuse_one_byte_read(dm, PPG_BB_GAIN_5GH1_TXA_OFFSET, &pg_power, false);
power_trim_info->bb_gain[5][0] = pg_power;
/*Path B*/
odm_efuse_one_byte_read(dm, PPG_BB_GAIN_5GL1_TXB_OFFSET, &pg_power, false);
power_trim_info->bb_gain[1][1] = pg_power;
odm_efuse_one_byte_read(dm, PPG_BB_GAIN_5GL2_TXB_OFFSET, &pg_power, false);
power_trim_info->bb_gain[2][1] = pg_power;
odm_efuse_one_byte_read(dm, PPG_BB_GAIN_5GM1_TXB_OFFSET, &pg_power, false);
power_trim_info->bb_gain[3][1] = pg_power;
odm_efuse_one_byte_read(dm, PPG_BB_GAIN_5GM2_TXB_OFFSET, &pg_power, false);
power_trim_info->bb_gain[4][1] = pg_power;
odm_efuse_one_byte_read(dm, PPG_BB_GAIN_5GH1_TXB_OFFSET, &pg_power, false);
power_trim_info->bb_gain[5][1] = pg_power;
power_trim_info->flag |= KFREE_FLAG_ON_5G;
power_trim_info->flag |= KFREE_FLAG_ON;
}
PHYDM_DBG(dm, ODM_COMP_MP, "[kfree] 8822b power trim flag:0x%02x\n", power_trim_info->flag);
if (!(power_trim_info->flag & KFREE_FLAG_ON))
return;
for (i = 0; i < KFREE_BAND_NUM; i++) {
for (j = 0; j < 2; j++)
PHYDM_DBG(dm, ODM_COMP_MP, "[kfree] 8822b power_trim_data->bb_gain[%d][%d]=0x%X\n", i, j, power_trim_info->bb_gain[i][j]);
}
#if 0
} else
return;
#endif
}
void
phydm_set_pa_bias_to_rf_8822b(
void *dm_void,
u8 e_rf_path,
s8 tx_pa_bias
)
{
struct dm_struct *dm = (struct dm_struct *)dm_void;
struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
u32 rf_reg_51 = 0, rf_reg_52 = 0, rf_reg_3f = 0;
rf_reg_51 = odm_get_rf_reg(dm, e_rf_path, 0x51, RFREGOFFSETMASK);
rf_reg_52 = odm_get_rf_reg(dm, e_rf_path, 0x52, RFREGOFFSETMASK);
PHYDM_DBG(dm, ODM_COMP_MP, "[kfree] 8822b 2g rf(0x51)=0x%X rf(0x52)=0x%X path=%d\n",
rf_reg_51, rf_reg_52, e_rf_path);
/*rf3f => rf52[19:17] = rf3f[2:0] rf52[16:15] = rf3f[4:3] rf52[3:0] = rf3f[8:5]*/
/*rf3f => rf51[6:3] = rf3f[12:9] rf52[13] = rf3f[13]*/
rf_reg_3f = ((rf_reg_52 & 0xe0000) >> 17) |
(((rf_reg_52 & 0x18000) >> 15) << 3) |
((rf_reg_52 & 0xf) << 5) |
(((rf_reg_51 & 0x78) >> 3) << 9) |
(((rf_reg_52 & 0x2000) >> 13) << 13);
PHYDM_DBG(dm, ODM_COMP_MP,"[kfree] 8822b 2g original tx_pa_bias=%d rf_reg_3f=0x%X path=%d\n",
tx_pa_bias, rf_reg_3f, e_rf_path);
tx_pa_bias = (s8)((rf_reg_3f & (BIT(12) | BIT(11) | BIT(10) | BIT(9))) >> 9) + tx_pa_bias;
if (tx_pa_bias < 0)
tx_pa_bias = 0;
else if (tx_pa_bias > 7)
tx_pa_bias = 7;
rf_reg_3f = ((rf_reg_3f & 0xfe1ff) | (tx_pa_bias << 9));
PHYDM_DBG(dm, ODM_COMP_MP,"[kfree] 8822b 2g offset efuse 0x3d5 0x3d6 tx_pa_bias=%d rf_reg_3f=0x%X path=%d\n",
tx_pa_bias, rf_reg_3f, e_rf_path);
odm_set_rf_reg(dm, e_rf_path, 0xef, BIT(10), 0x1);
odm_set_rf_reg(dm, e_rf_path, 0x33, RFREGOFFSETMASK, 0x0);
odm_set_rf_reg(dm, e_rf_path, 0x3f, RFREGOFFSETMASK, rf_reg_3f);
odm_set_rf_reg(dm, e_rf_path, 0x33, BIT(0), 0x1);
odm_set_rf_reg(dm, e_rf_path, 0x3f, RFREGOFFSETMASK, rf_reg_3f);
odm_set_rf_reg(dm, e_rf_path, 0x33, BIT(1), 0x1);
odm_set_rf_reg(dm, e_rf_path, 0x3f, RFREGOFFSETMASK, rf_reg_3f);
odm_set_rf_reg(dm, e_rf_path, 0x33, (BIT(1) | BIT(0)), 0x3);
odm_set_rf_reg(dm, e_rf_path, 0x3f, RFREGOFFSETMASK, rf_reg_3f);
odm_set_rf_reg(dm, e_rf_path, 0xef, BIT(10), 0x0);
PHYDM_DBG(dm, ODM_COMP_MP,"[kfree] 8822b 2g tx pa bias rf_0x3f(0x%X) path=%d\n",
odm_get_rf_reg(dm, e_rf_path, 0x3f, (BIT(12) | BIT(11) | BIT(10) | BIT(9))), e_rf_path);
}
void
phydm_get_pa_bias_offset_8822b(
void *dm_void
)
{
struct dm_struct *dm = (struct dm_struct *)dm_void;
struct odm_power_trim_data *power_trim_info = &dm->power_trim_data;
u8 pg_pa_bias = 0xff, e_rf_path = 0;
s8 tx_pa_bias[2] = {0};
odm_efuse_one_byte_read(dm, PPG_PA_BIAS_2G_TXA_OFFSET, &pg_pa_bias, false);
if (pg_pa_bias != 0xff) {
/*paht a*/
odm_efuse_one_byte_read(dm, PPG_PA_BIAS_2G_TXA_OFFSET, &pg_pa_bias, false);
pg_pa_bias = pg_pa_bias & 0xf;
if ((pg_pa_bias & BIT(0)) == 0)
tx_pa_bias[0] = (-1 * (pg_pa_bias >> 1));
else
tx_pa_bias[0] = (pg_pa_bias >> 1);
/*paht b*/
odm_efuse_one_byte_read(dm, PPG_PA_BIAS_2G_TXB_OFFSET, &pg_pa_bias, false);
pg_pa_bias = pg_pa_bias & 0xf;
if ((pg_pa_bias & BIT(0)) == 0)
tx_pa_bias[1] = (-1 * (pg_pa_bias >> 1));
else
tx_pa_bias[1] = (pg_pa_bias >> 1);
PHYDM_DBG(dm, ODM_COMP_MP, "[kfree] 8822b 2g tx_patha_pa_bias:%d tx_pathb_pa_bias:%d\n", tx_pa_bias[0], tx_pa_bias[1]);
for (e_rf_path = RF_PATH_A; e_rf_path < 2; e_rf_path++)
phydm_set_pa_bias_to_rf_8822b(dm, e_rf_path, tx_pa_bias[e_rf_path]);
power_trim_info->pa_bias_flag |= PA_BIAS_FLAG_ON;
}
else
PHYDM_DBG(dm, ODM_COMP_MP, "[kfree] 8822b 2g tx pa bias no pg\n");
}
void
phydm_set_kfree_to_rf_8822b(
void *dm_void,
u8 e_rf_path,
u8 data
)
{
struct dm_struct *dm = (struct dm_struct *)dm_void;
struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
odm_set_rf_reg(dm, e_rf_path, 0xde, BIT(0), 1);
odm_set_rf_reg(dm, e_rf_path, 0xde, BIT(4), 1);
odm_set_rf_reg(dm, e_rf_path, 0x65, MASKLWORD, 0x9000);
odm_set_rf_reg(dm, e_rf_path, 0x55, BIT(5), 1);
odm_set_rf_reg(dm, e_rf_path, 0x55, BIT(19), (data & BIT(0)));
odm_set_rf_reg(dm, e_rf_path, 0x55, (BIT(18) | BIT(17) | BIT(16) | BIT(15) | BIT(14)), ((data & 0x1f) >> 1));
PHYDM_DBG(dm, ODM_COMP_MP,"[kfree] 8822b 0x55[19:14]=0x%X path=%d\n",
odm_get_rf_reg(dm, e_rf_path, 0x55, (BIT(19) | BIT(18) | BIT(17) | BIT(16) | BIT(15) | BIT(14))),
e_rf_path
);
}
void
phydm_clear_kfree_to_rf_8822b(
void *dm_void,
u8 e_rf_path,
u8 data
)
{
struct dm_struct *dm = (struct dm_struct *)dm_void;
struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
odm_set_rf_reg(dm, e_rf_path, 0xde, BIT(0), 1);
odm_set_rf_reg(dm, e_rf_path, 0xde, BIT(4), 1);
odm_set_rf_reg(dm, e_rf_path, 0x65, MASKLWORD, 0x9000);
odm_set_rf_reg(dm, e_rf_path, 0x55, BIT(5), 1);
odm_set_rf_reg(dm, e_rf_path, 0x55, BIT(19), (data & BIT(0)));
odm_set_rf_reg(dm, e_rf_path, 0x55, (BIT(18) | BIT(17) | BIT(16) | BIT(15) | BIT(14)), ((data & 0x1f) >> 1));
odm_set_rf_reg(dm, e_rf_path, 0xde, BIT(0), 0);
odm_set_rf_reg(dm, e_rf_path, 0xde, BIT(4), 1);
odm_set_rf_reg(dm, e_rf_path, 0x65, MASKLWORD, 0x9000);
odm_set_rf_reg(dm, e_rf_path, 0x55, BIT(5), 0);
odm_set_rf_reg(dm, e_rf_path, 0x55, BIT(7), 0);
PHYDM_DBG(dm, ODM_COMP_MP,"[kfree] 8822b clear power trim 0x55[19:14]=0x%X path=%d\n",
odm_get_rf_reg(dm, e_rf_path, 0x55, (BIT(19) | BIT(18) | BIT(17) | BIT(16) | BIT(15) | BIT(14))),
e_rf_path
);
}
void
phydm_get_thermal_trim_offset_8710b(
void *dm_void)
{
struct dm_struct *dm = (struct dm_struct *)dm_void;
struct odm_power_trim_data *power_trim_info = &(dm->power_trim_data);
u8 pg_therm = 0xff;
odm_efuse_one_byte_read(dm, 0x0EF, &pg_therm, false);
if (pg_therm != 0xff) {
pg_therm = pg_therm & 0x1f;
if ((pg_therm & BIT(0)) == 0)
power_trim_info->thermal = (-1 * (pg_therm >> 1));
else
power_trim_info->thermal = (pg_therm >> 1);
power_trim_info->flag |= KFREE_FLAG_THERMAL_K_ON;
}
ODM_RT_TRACE(dm, ODM_COMP_MP, ODM_DBG_LOUD, ("[kfree] 8710b thermal trim flag:0x%02x\n", power_trim_info->flag));
if (power_trim_info->flag & KFREE_FLAG_THERMAL_K_ON)
ODM_RT_TRACE(dm, ODM_COMP_MP, ODM_DBG_LOUD, ("[kfree] 8710b thermal:%d\n", power_trim_info->thermal));
}
void
phydm_get_power_trim_offset_8710b(
void *dm_void
)
{
struct dm_struct *dm = (struct dm_struct *)dm_void;
struct odm_power_trim_data *power_trim_info = &(dm->power_trim_data);
struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
u8 pg_power = 0xff;
odm_efuse_one_byte_read(dm, 0xEE, &pg_power, false);
if (pg_power != 0xff) {
/*Path A*/
odm_efuse_one_byte_read(dm, 0xEE, &pg_power, false);
power_trim_info->bb_gain[0][0] = (pg_power & 0xf);
power_trim_info->flag |= KFREE_FLAG_ON_2G;
power_trim_info->flag |= KFREE_FLAG_ON;
}
ODM_RT_TRACE(dm, ODM_COMP_MP, ODM_DBG_LOUD, ("[kfree] 8710b power trim flag:0x%02x\n", power_trim_info->flag));
if (power_trim_info->flag & KFREE_FLAG_ON)
ODM_RT_TRACE(dm, ODM_COMP_MP, ODM_DBG_LOUD, ("[kfree] 8710b power_trim_data->bb_gain[0][0]=0x%X\n", power_trim_info->bb_gain[0][0]));
}
void
phydm_set_kfree_to_rf_8710b(
void *dm_void,
u8 e_rf_path,
u8 data
)
{
struct dm_struct *dm = (struct dm_struct *)dm_void;
struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
odm_set_rf_reg(dm, e_rf_path, 0x55, BIT(19), (data & BIT(0)));
odm_set_rf_reg(dm, e_rf_path, 0x55, (BIT(18) | BIT(17) | BIT(16) | BIT(15)), ((data & 0xf) >> 1));
ODM_RT_TRACE(dm, ODM_COMP_MP, ODM_DBG_LOUD,
("[kfree] 8710b 0x55[19:14]=0x%X path=%d\n",
odm_get_rf_reg(dm, e_rf_path, 0x55, (BIT(19) | BIT(18) | BIT(17) | BIT(16) | BIT(15) | BIT(14))),
e_rf_path
));
}
void
phydm_clear_kfree_to_rf_8710b(
void *dm_void,
u8 e_rf_path,
u8 data
)
{
struct dm_struct *dm = (struct dm_struct *)dm_void;
struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
odm_set_rf_reg(dm, e_rf_path, 0x55, BIT(19), (data & BIT(0)));
odm_set_rf_reg(dm, e_rf_path, 0x55, (BIT(18) | BIT(17) | BIT(16) | BIT(15) | BIT(14)), ((data & 0x1f) >> 1));
ODM_RT_TRACE(dm, ODM_COMP_MP, ODM_DBG_LOUD,
("[kfree] 8710b clear power trim 0x55[19:14]=0x%X path=%d\n",
odm_get_rf_reg(dm, e_rf_path, 0x55, (BIT(19) | BIT(18) | BIT(17) | BIT(16) | BIT(15) | BIT(14))),
e_rf_path
));
}
void
phydm_set_kfree_to_rf(
void *dm_void,
u8 e_rf_path,
u8 data
)
{
struct dm_struct *dm = (struct dm_struct *)dm_void;
if (dm->support_ic_type & ODM_RTL8814A)
phydm_set_kfree_to_rf_8814a(dm, e_rf_path, data);
if ((dm->support_ic_type & ODM_RTL8821C) && (*dm->band_type == ODM_BAND_2_4G))
phydm_set_kfree_to_rf_8821c(dm, e_rf_path, true, data);
else if (dm->support_ic_type & ODM_RTL8821C)
phydm_set_kfree_to_rf_8821c(dm, e_rf_path, false, data);
if (dm->support_ic_type & ODM_RTL8822B)
phydm_set_kfree_to_rf_8822b(dm, e_rf_path, data);
if (dm->support_ic_type & ODM_RTL8710B)
phydm_set_kfree_to_rf_8710b(dm, e_rf_path, data);
}
void
phydm_clear_kfree_to_rf(
void *dm_void,
u8 e_rf_path,
u8 data
)
{
struct dm_struct *dm = (struct dm_struct *)dm_void;
if (dm->support_ic_type & ODM_RTL8822B)
phydm_clear_kfree_to_rf_8822b(dm, e_rf_path, 1);
if (dm->support_ic_type & ODM_RTL8821C)
phydm_clear_kfree_to_rf_8821c(dm, e_rf_path, 1);
if (dm->support_ic_type & ODM_RTL8710B)
phydm_set_kfree_to_rf_8710b(dm, e_rf_path, data);
}
void
phydm_get_thermal_trim_offset(
void *dm_void
)
{
struct dm_struct *dm = (struct dm_struct *)dm_void;
#if (DM_ODM_SUPPORT_TYPE & ODM_WIN)
void *adapter = dm->adapter;
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(((PADAPTER)adapter));
PEFUSE_HAL pEfuseHal = &hal_data->EfuseHal;
u1Byte eFuseContent[DCMD_EFUSE_MAX_SECTION_NUM * EFUSE_MAX_WORD_UNIT * 2];
if (HAL_MAC_Dump_EFUSE(&GET_HAL_MAC_INFO((PADAPTER)adapter), EFUSE_WIFI, eFuseContent, pEfuseHal->PhysicalLen_WiFi, HAL_MAC_EFUSE_PHYSICAL, HAL_MAC_EFUSE_PARSE_DRV) != RT_STATUS_SUCCESS)
PHYDM_DBG(dm, ODM_COMP_MP, "[kfree] dump efuse fail !!!\n");
#endif
if (dm->support_ic_type & ODM_RTL8821C)
phydm_get_thermal_trim_offset_8821c(dm_void);
else if (dm->support_ic_type & ODM_RTL8822B)
phydm_get_thermal_trim_offset_8822b(dm_void);
else if (dm->support_ic_type & ODM_RTL8710B)
phydm_get_thermal_trim_offset_8710b(dm_void);
}
void
phydm_get_power_trim_offset(
void *dm_void
)
{
struct dm_struct *dm = (struct dm_struct *)dm_void;
#if 0 //(DM_ODM_SUPPORT_TYPE & ODM_WIN) // 2017 MH DM Should use the same code.s
void *adapter = dm->adapter;
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(((PADAPTER)adapter));
PEFUSE_HAL pEfuseHal = &hal_data->EfuseHal;
u1Byte eFuseContent[DCMD_EFUSE_MAX_SECTION_NUM * EFUSE_MAX_WORD_UNIT * 2];
if (HAL_MAC_Dump_EFUSE(&GET_HAL_MAC_INFO(adapter), EFUSE_WIFI, eFuseContent, pEfuseHal->PhysicalLen_WiFi, HAL_MAC_EFUSE_PHYSICAL, HAL_MAC_EFUSE_PARSE_DRV) != RT_STATUS_SUCCESS)
PHYDM_DBG(dm, ODM_COMP_MP, "[kfree] dump efuse fail !!!\n");
#endif
if (dm->support_ic_type & ODM_RTL8821C)
phydm_get_power_trim_offset_8821c(dm_void);
else if (dm->support_ic_type & ODM_RTL8822B)
phydm_get_power_trim_offset_8822b(dm_void);
else if (dm->support_ic_type & ODM_RTL8710B)
phydm_get_power_trim_offset_8710b(dm_void);
}
void
phydm_get_pa_bias_offset(
void *dm_void
)
{
struct dm_struct *dm = (struct dm_struct *)dm_void;
#if (DM_ODM_SUPPORT_TYPE & ODM_WIN)
void *adapter = dm->adapter;
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(((PADAPTER)adapter));
PEFUSE_HAL pEfuseHal = &hal_data->EfuseHal;
u1Byte eFuseContent[DCMD_EFUSE_MAX_SECTION_NUM * EFUSE_MAX_WORD_UNIT * 2];
if (HAL_MAC_Dump_EFUSE(&GET_HAL_MAC_INFO((PADAPTER)adapter), EFUSE_WIFI, eFuseContent, pEfuseHal->PhysicalLen_WiFi, HAL_MAC_EFUSE_PHYSICAL, HAL_MAC_EFUSE_PARSE_DRV) != RT_STATUS_SUCCESS)
PHYDM_DBG(dm, ODM_COMP_MP, "[kfree] dump efuse fail !!!\n");
#endif
if (dm->support_ic_type & ODM_RTL8822B)
phydm_get_pa_bias_offset_8822b(dm_void);
}
s8
phydm_get_thermal_offset(
void *dm_void
)
{
struct dm_struct *dm = (struct dm_struct *)dm_void;
struct odm_power_trim_data *power_trim_info = &dm->power_trim_data;
if (power_trim_info->flag & KFREE_FLAG_THERMAL_K_ON)
return power_trim_info->thermal;
else
return 0;
}
void
phydm_config_kfree(
void *dm_void,
u8 channel_to_sw
)
{
struct dm_struct *dm = (struct dm_struct *)dm_void;
struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
struct odm_power_trim_data *power_trim_info = &dm->power_trim_data;
u8 rfpath = 0, max_rf_path = 0;
u8 channel_idx = 0, i, j;
if (dm->support_ic_type & ODM_RTL8814A)
max_rf_path = 4; /*0~3*/
else if (dm->support_ic_type & (ODM_RTL8812 | ODM_RTL8192E | ODM_RTL8822B))
max_rf_path = 2; /*0~1*/
else if (dm->support_ic_type & (ODM_RTL8821C| ODM_RTL8710B))
max_rf_path = 1;
PHYDM_DBG(dm, ODM_COMP_MP, "===>[kfree] phy_ConfigKFree()\n");
if (cali_info->reg_rf_kfree_enable == 2) {
PHYDM_DBG(dm, ODM_COMP_MP, "[kfree] phy_ConfigKFree(): reg_rf_kfree_enable == 2, Disable\n");
return;
} else if (cali_info->reg_rf_kfree_enable == 1 || cali_info->reg_rf_kfree_enable == 0) {
PHYDM_DBG(dm, ODM_COMP_MP, "[kfree] phy_ConfigKFree(): reg_rf_kfree_enable == true\n");
/*Make sure the targetval is defined*/
if (!(power_trim_info->flag & KFREE_FLAG_ON)) {
PHYDM_DBG(dm, ODM_COMP_MP, "[kfree] phy_ConfigKFree(): targetval not defined, Don't execute KFree Process.\n");
return;
}
/*if kfree_table[0] == 0xff, means no Kfree*/
if (dm->support_ic_type &ODM_RTL8710B)
ODM_RT_TRACE(dm, ODM_COMP_MP, ODM_DBG_LOUD, ("[kfree] power_trim_data->bb_gain[0][0]=0x%X\n", power_trim_info->bb_gain[0][0]));
else if (dm->support_ic_type & (ODM_RTL8812 | ODM_RTL8192E | ODM_RTL8822B |ODM_RTL8821C | ODM_RTL8814A)){
for (i = 0; i < KFREE_BAND_NUM; i++) {
for (j = 0; j < max_rf_path; j++)
PHYDM_DBG(dm, ODM_COMP_MP, "[kfree] power_trim_data->bb_gain[%d][%d]=0x%X\n", i, j, power_trim_info->bb_gain[i][j]);
}
}
if (*dm->band_type == ODM_BAND_2_4G && power_trim_info->flag & KFREE_FLAG_ON_2G) {
if (channel_to_sw >= 1 && channel_to_sw <= 14)
channel_idx = PHYDM_2G;
for (rfpath = RF_PATH_A; rfpath < max_rf_path; rfpath++) {
PHYDM_DBG(dm, ODM_COMP_MP, "[kfree] phydm_kfree(): channel_to_sw=%d PATH_%d bb_gain:0x%X\n", channel_to_sw, rfpath, power_trim_info->bb_gain[channel_idx][rfpath]);
phydm_set_kfree_to_rf(dm, rfpath, power_trim_info->bb_gain[channel_idx][rfpath]);
}
} else if (*dm->band_type == ODM_BAND_5G && power_trim_info->flag & KFREE_FLAG_ON_5G) {
if (channel_to_sw >= 36 && channel_to_sw <= 48)
channel_idx = PHYDM_5GLB1;
if (channel_to_sw >= 52 && channel_to_sw <= 64)
channel_idx = PHYDM_5GLB2;
if (channel_to_sw >= 100 && channel_to_sw <= 120)
channel_idx = PHYDM_5GMB1;
if (channel_to_sw >= 122 && channel_to_sw <= 144)
channel_idx = PHYDM_5GMB2;
if (channel_to_sw >= 149 && channel_to_sw <= 177)
channel_idx = PHYDM_5GHB;
for (rfpath = RF_PATH_A; rfpath < max_rf_path; rfpath++) {
PHYDM_DBG(dm, ODM_COMP_MP, "[kfree] phydm_kfree(): channel_to_sw=%d PATH_%d bb_gain:0x%X\n", channel_to_sw, rfpath, power_trim_info->bb_gain[channel_idx][rfpath]);
phydm_set_kfree_to_rf(dm, rfpath, power_trim_info->bb_gain[channel_idx][rfpath]);
}
} else {
PHYDM_DBG(dm, ODM_COMP_MP, "[kfree] Set default Register\n");
for (rfpath = RF_PATH_A; rfpath < max_rf_path; rfpath++)
phydm_clear_kfree_to_rf(dm, rfpath, power_trim_info->bb_gain[channel_idx][rfpath]);
}
}
PHYDM_DBG(dm, ODM_COMP_MP, "<===[kfree] phy_ConfigKFree()\n");
}

View File

@ -0,0 +1,142 @@
/******************************************************************************
*
* 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 full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __PHYDMKFREE_H__
#define __PHYDKFREE_H__
#define KFREE_VERSION "1.0"
#define KFREE_BAND_NUM 6
#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_AP))
#define BB_GAIN_NUM 6
#endif
#define KFREE_FLAG_ON BIT(0)
#define KFREE_FLAG_THERMAL_K_ON BIT(1)
#define KFREE_FLAG_ON_2G BIT(2)
#define KFREE_FLAG_ON_5G BIT(3)
#define PA_BIAS_FLAG_ON BIT(4)
#define PPG_THERMAL_OFFSET_8821C 0x1EF
#define PPG_BB_GAIN_2G_TXAB_OFFSET_8821C 0x1EE
#define PPG_BB_GAIN_5GL1_TXA_OFFSET_8821C 0x1EC
#define PPG_BB_GAIN_5GL2_TXA_OFFSET_8821C 0x1E8
#define PPG_BB_GAIN_5GM1_TXA_OFFSET_8821C 0x1E4
#define PPG_BB_GAIN_5GM2_TXA_OFFSET_8821C 0x1E0
#define PPG_BB_GAIN_5GH1_TXA_OFFSET_8821C 0x1DC
#define PPG_THERMAL_OFFSET 0x3EF
#define PPG_BB_GAIN_2G_TXAB_OFFSET 0x3EE
#define PPG_BB_GAIN_2G_TXCD_OFFSET 0x3ED
#define PPG_BB_GAIN_5GL1_TXA_OFFSET 0x3EC
#define PPG_BB_GAIN_5GL1_TXB_OFFSET 0x3EB
#define PPG_BB_GAIN_5GL1_TXC_OFFSET 0x3EA
#define PPG_BB_GAIN_5GL1_TXD_OFFSET 0x3E9
#define PPG_BB_GAIN_5GL2_TXA_OFFSET 0x3E8
#define PPG_BB_GAIN_5GL2_TXB_OFFSET 0x3E7
#define PPG_BB_GAIN_5GL2_TXC_OFFSET 0x3E6
#define PPG_BB_GAIN_5GL2_TXD_OFFSET 0x3E5
#define PPG_BB_GAIN_5GM1_TXA_OFFSET 0x3E4
#define PPG_BB_GAIN_5GM1_TXB_OFFSET 0x3E3
#define PPG_BB_GAIN_5GM1_TXC_OFFSET 0x3E2
#define PPG_BB_GAIN_5GM1_TXD_OFFSET 0x3E1
#define PPG_BB_GAIN_5GM2_TXA_OFFSET 0x3E0
#define PPG_BB_GAIN_5GM2_TXB_OFFSET 0x3DF
#define PPG_BB_GAIN_5GM2_TXC_OFFSET 0x3DE
#define PPG_BB_GAIN_5GM2_TXD_OFFSET 0x3DD
#define PPG_BB_GAIN_5GH1_TXA_OFFSET 0x3DC
#define PPG_BB_GAIN_5GH1_TXB_OFFSET 0x3DB
#define PPG_BB_GAIN_5GH1_TXC_OFFSET 0x3DA
#define PPG_BB_GAIN_5GH1_TXD_OFFSET 0x3D9
#define PPG_PA_BIAS_2G_TXA_OFFSET 0x3D5
#define PPG_PA_BIAS_2G_TXB_OFFSET 0x3D6
struct odm_power_trim_data {
u8 flag;
u8 pa_bias_flag;
s8 bb_gain[KFREE_BAND_NUM][MAX_RF_PATH];
s8 thermal;
};
enum phydm_kfree_channeltosw {
PHYDM_2G = 0,
PHYDM_5GLB1 = 1,
PHYDM_5GLB2 = 2,
PHYDM_5GMB1 = 3,
PHYDM_5GMB2 = 4,
PHYDM_5GHB = 5,
};
void
phydm_get_thermal_trim_offset(
void *dm_void
);
void
phydm_get_power_trim_offset(
void *dm_void
);
void
phydm_get_pa_bias_offset(
void *dm_void
);
s8
phydm_get_thermal_offset(
void *dm_void
);
void
phydm_clear_kfree_to_rf(
void *dm_void,
u8 e_rf_path,
u8 data
);
void
phydm_config_kfree(
void *dm_void,
u8 channel_to_sw
);
#endif

View File

@ -0,0 +1,159 @@
/******************************************************************************
*
* 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 full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
/* ************************************************************
* include files
* ************************************************************ */
#include "mp_precomp.h"
#include "phydm_precomp.h"
boolean
odm_check_power_status(
void *dm_void
)
{
#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
struct dm_struct *dm = (struct dm_struct *)dm_void;
PADAPTER adapter = (PADAPTER)dm->adapter;
RT_RF_POWER_STATE rt_state;
MGNT_INFO *mgnt_info = &adapter->MgntInfo;
/* 2011/07/27 MH We are not testing ready~~!! We may fail to get correct value when init sequence. */
if (mgnt_info->init_adpt_in_progress == true) {
PHYDM_DBG(dm, ODM_COMP_INIT, "check_pow_status Return true, due to initadapter\n");
return true;
}
/* */
/* 2011/07/19 MH We can not execute tx pwoer tracking/ LLC calibrate or IQK. */
/* */
adapter->HalFunc.GetHwRegHandler(adapter, HW_VAR_RF_STATE, (u8 *)(&rt_state));
if (adapter->bDriverStopped || adapter->bDriverIsGoingToPnpSetPowerSleep || rt_state == eRfOff) {
PHYDM_DBG(dm, ODM_COMP_INIT, "check_pow_status Return false, due to %d/%d/%d\n",
adapter->bDriverStopped, adapter->bDriverIsGoingToPnpSetPowerSleep, rt_state);
return false;
}
#endif
return true;
}
#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
void
halrf_update_pwr_track(
void *dm_void,
u8 rate
)
{
struct dm_struct *dm = (struct dm_struct *)dm_void;
#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
u8 path_idx = 0;
#endif
PHYDM_DBG(dm, ODM_COMP_TX_PWR_TRACK, "Pwr Track Get rate=0x%x\n", rate);
dm->tx_rate = rate;
#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
#if DEV_BUS_TYPE == RT_PCI_INTERFACE
#if USE_WORKITEM
odm_schedule_work_item(&dm->ra_rpt_workitem);
#else
if (dm->support_ic_type == ODM_RTL8821) {
#if (RTL8821A_SUPPORT == 1)
odm_tx_pwr_track_set_pwr8821a(dm, MIX_MODE, RF_PATH_A, 0);
#endif
} else if (dm->support_ic_type == ODM_RTL8812) {
for (path_idx = RF_PATH_A; path_idx < MAX_PATH_NUM_8812A; path_idx++) {
#if (RTL8812A_SUPPORT == 1)
odm_tx_pwr_track_set_pwr8812a(dm, MIX_MODE, path_idx, 0);
#endif
}
} else if (dm->support_ic_type == ODM_RTL8723B) {
#if (RTL8723B_SUPPORT == 1)
odm_tx_pwr_track_set_pwr_8723b(dm, MIX_MODE, RF_PATH_A, 0);
#endif
} else if (dm->support_ic_type == ODM_RTL8192E) {
for (path_idx = RF_PATH_A; path_idx < MAX_PATH_NUM_8192E; path_idx++) {
#if (RTL8192E_SUPPORT == 1)
odm_tx_pwr_track_set_pwr92_e(dm, MIX_MODE, path_idx, 0);
#endif
}
} else if (dm->support_ic_type == ODM_RTL8188E) {
#if (RTL8188E_SUPPORT == 1)
odm_tx_pwr_track_set_pwr88_e(dm, MIX_MODE, RF_PATH_A, 0);
#endif
}
#endif
#else
odm_schedule_work_item(&dm->ra_rpt_workitem);
#endif
#endif
}
#endif
#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
void
halrf_update_init_rate_work_item_callback(
void *context
)
{
void *adapter = (void *)context;
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(((PADAPTER)adapter));
struct dm_struct *dm = &hal_data->DM_OutSrc;
u8 p = 0;
if (dm->support_ic_type == ODM_RTL8821) {
odm_tx_pwr_track_set_pwr8821a(dm, MIX_MODE, RF_PATH_A, 0);
/**/
} else if (dm->support_ic_type == ODM_RTL8812) {
for (p = RF_PATH_A; p < MAX_PATH_NUM_8812A; p++) { /*DOn't know how to include &c*/
odm_tx_pwr_track_set_pwr8812a(dm, MIX_MODE, p, 0);
/**/
}
} else if (dm->support_ic_type == ODM_RTL8723B) {
odm_tx_pwr_track_set_pwr_8723b(dm, MIX_MODE, RF_PATH_A, 0);
/**/
} else if (dm->support_ic_type == ODM_RTL8192E) {
for (p = RF_PATH_A; p < MAX_PATH_NUM_8192E; p++) { /*DOn't know how to include &c*/
odm_tx_pwr_track_set_pwr92_e(dm, MIX_MODE, p, 0);
/**/
}
} else if (dm->support_ic_type == ODM_RTL8188E) {
odm_tx_pwr_track_set_pwr88_e(dm, MIX_MODE, RF_PATH_A, 0);
/**/
}
}
#endif

View File

@ -0,0 +1,50 @@
/******************************************************************************
*
* 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 full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __HALRF_POWER_TRACKING_H__
#define __HALRF_POWER_TRACKING_H__
boolean
odm_check_power_status(
void *dm_void
);
#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
void
halrf_update_pwr_track(
void *dm_void,
u8 rate
);
#endif
#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
void
halrf_update_init_rate_work_item_callback(
void *context
);
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,345 @@
/******************************************************************************
*
* 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 __PHYDMPOWERTRACKING_H__
#define __PHYDMPOWERTRACKING_H__
#if (DM_ODM_SUPPORT_TYPE == ODM_AP)
#ifdef RTK_AC_SUPPORT
#define ODM_IC_11AC_SERIES_SUPPORT 1
#else
#define ODM_IC_11AC_SERIES_SUPPORT 0
#endif
#else
#define ODM_IC_11AC_SERIES_SUPPORT 1
#endif
#define DPK_DELTA_MAPPING_NUM 13
#define index_mapping_HP_NUM 15
#define DELTA_SWINGIDX_SIZE 30
#define DELTA_SWINTSSI_SIZE 61
#define BAND_NUM 3
#define MAX_RF_PATH 4
#define TXSCALE_TABLE_SIZE 37
#define CCK_TABLE_SIZE_8723D 41
/* JJ ADD 20161014 */
#define CCK_TABLE_SIZE_8710B 41
#define IQK_MAC_REG_NUM 4
#define IQK_ADDA_REG_NUM 16
#define IQK_BB_REG_NUM_MAX 10
#define IQK_BB_REG_NUM 9
#define AVG_THERMAL_NUM 8
#define iqk_matrix_reg_num 8
/* #define IQK_MATRIX_SETTINGS_NUM 1+24+21 */
#define IQK_MATRIX_SETTINGS_NUM (14+24+21) /* Channels_2_4G_NUM + Channels_5G_20M_NUM + Channels_5G */
#if !defined(_OUTSRC_COEXIST)
#define OFDM_TABLE_SIZE_92D 43
#define OFDM_TABLE_SIZE 37
#define CCK_TABLE_SIZE 33
#define CCK_TABLE_SIZE_88F 21
/* #define OFDM_TABLE_SIZE_92E 54 */
/* #define CCK_TABLE_SIZE_92E 54 */
extern u32 ofdm_swing_table[OFDM_TABLE_SIZE_92D];
extern u8 cck_swing_table_ch1_ch13[CCK_TABLE_SIZE][8];
extern u8 cck_swing_table_ch14[CCK_TABLE_SIZE][8];
extern u32 ofdm_swing_table_new[OFDM_TABLE_SIZE_92D];
extern u8 cck_swing_table_ch1_ch13_new[CCK_TABLE_SIZE][8];
extern u8 cck_swing_table_ch14_new[CCK_TABLE_SIZE][8];
extern u8 cck_swing_table_ch1_ch14_88f[CCK_TABLE_SIZE_88F][16];
extern u8 cck_swing_table_ch1_ch13_88f[CCK_TABLE_SIZE_88F][16];
extern u8 cck_swing_table_ch14_88f[CCK_TABLE_SIZE_88F][16];
#endif
#define ODM_OFDM_TABLE_SIZE 37
#define ODM_CCK_TABLE_SIZE 33
/* <20140613, YuChen> In case fail to read TxPowerTrack.txt, we use the table of 88E as the default table. */
extern u8 delta_swing_table_idx_2ga_p_default[DELTA_SWINGIDX_SIZE];
extern u8 delta_swing_table_idx_2ga_n_default[DELTA_SWINGIDX_SIZE];
static u8 delta_swing_table_idx_2ga_p_8188e[] = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9};
static u8 delta_swing_table_idx_2ga_n_8188e[] = {0, 0, 0, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11};
/* extern u32 ofdm_swing_table_92e[OFDM_TABLE_SIZE_92E];
* extern u8 cck_swing_table_ch1_ch13_92e[CCK_TABLE_SIZE_92E][8];
* extern u8 cck_swing_table_ch14_92e[CCK_TABLE_SIZE_92E][8]; */
#ifdef CONFIG_WLAN_HAL_8192EE
#define OFDM_TABLE_SIZE_92E 54
#define CCK_TABLE_SIZE_92E 54
extern u32 ofdm_swing_table_92e[OFDM_TABLE_SIZE_92E];
extern u8 cck_swing_table_ch1_ch13_92e[CCK_TABLE_SIZE_92E][8];
extern u8 cck_swing_table_ch14_92e[CCK_TABLE_SIZE_92E][8];
#endif
#define OFDM_TABLE_SIZE_8812 43
#define AVG_THERMAL_NUM_8812 4
#if (RTL8814A_SUPPORT == 1 || RTL8822B_SUPPORT == 1 || RTL8821C_SUPPORT == 1)
extern u32 tx_scaling_table_jaguar[TXSCALE_TABLE_SIZE];
#elif(ODM_IC_11AC_SERIES_SUPPORT)
extern unsigned int ofdm_swing_table_8812[OFDM_TABLE_SIZE_8812];
#endif
extern u32 cck_swing_table_ch1_ch14_8723d[CCK_TABLE_SIZE_8723D];
/* JJ ADD 20161014 */
extern u32 cck_swing_table_ch1_ch14_8710b[CCK_TABLE_SIZE_8710B];
#define dm_check_txpowertracking odm_txpowertracking_check
struct iqk_matrix_regs_setting {
boolean is_iqk_done;
s32 value[1][iqk_matrix_reg_num];
};
struct dm_rf_calibration_struct {
/* for tx power tracking */
u32 rega24; /* for TempCCK */
s32 rege94;
s32 rege9c;
s32 regeb4;
s32 regebc;
/* u8 is_txpowertracking; */
u8 tx_powercount;
boolean is_txpowertracking_init;
boolean is_txpowertracking;
u8 txpowertrack_control; /* for mp mode, turn off txpwrtracking as default */
u8 tm_trigger;
u8 internal_pa_5g[2]; /* pathA / pathB */
u8 thermal_meter[2]; /* thermal_meter, index 0 for RFIC0, and 1 for RFIC1 */
u8 thermal_value;
u8 thermal_value_lck;
u8 thermal_value_iqk;
s8 thermal_value_delta; /* delta of thermal_value and efuse thermal */
u8 thermal_value_dpk;
u8 thermal_value_avg[AVG_THERMAL_NUM];
u8 thermal_value_avg_index;
u8 thermal_value_rx_gain;
u8 thermal_value_crystal;
u8 thermal_value_dpk_store;
u8 thermal_value_dpk_track;
boolean txpowertracking_in_progress;
boolean is_dpk_enable;
boolean is_reloadtxpowerindex;
u8 is_rf_pi_enable;
u32 txpowertracking_callback_cnt; /* cosa add for debug */
u8 is_cck_in_ch14;
u8 CCK_index;
u8 OFDM_index[MAX_RF_PATH];
s8 power_index_offset;
s8 delta_power_index;
s8 delta_power_index_last;
boolean is_tx_power_changed;
struct iqk_matrix_regs_setting iqk_matrix_reg_setting[IQK_MATRIX_SETTINGS_NUM];
u8 delta_lck;
u8 delta_swing_table_idx_2g_cck_a_p[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2g_cck_a_n[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2g_cck_b_p[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2g_cck_b_n[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2g_cck_c_p[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2g_cck_c_n[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2g_cck_d_p[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2g_cck_d_n[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2ga_p[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2ga_n[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2gb_p[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2gb_n[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2gc_p[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2gc_n[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2gd_p[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2gd_n[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_5ga_p[BAND_NUM][DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_5ga_n[BAND_NUM][DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_5gb_p[BAND_NUM][DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_5gb_n[BAND_NUM][DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_5gc_p[BAND_NUM][DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_5gc_n[BAND_NUM][DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_5gd_p[BAND_NUM][DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_5gd_n[BAND_NUM][DELTA_SWINGIDX_SIZE];
u8 delta_swing_tssi_table_2g_cck_a[DELTA_SWINTSSI_SIZE];
u8 delta_swing_tssi_table_2g_cck_b[DELTA_SWINTSSI_SIZE];
u8 delta_swing_tssi_table_2g_cck_c[DELTA_SWINTSSI_SIZE];
u8 delta_swing_tssi_table_2g_cck_d[DELTA_SWINTSSI_SIZE];
u8 delta_swing_tssi_table_2ga[DELTA_SWINTSSI_SIZE];
u8 delta_swing_tssi_table_2gb[DELTA_SWINTSSI_SIZE];
u8 delta_swing_tssi_table_2gc[DELTA_SWINTSSI_SIZE];
u8 delta_swing_tssi_table_2gd[DELTA_SWINTSSI_SIZE];
u8 delta_swing_tssi_table_5ga[BAND_NUM][DELTA_SWINTSSI_SIZE];
u8 delta_swing_tssi_table_5gb[BAND_NUM][DELTA_SWINTSSI_SIZE];
u8 delta_swing_tssi_table_5gc[BAND_NUM][DELTA_SWINTSSI_SIZE];
u8 delta_swing_tssi_table_5gd[BAND_NUM][DELTA_SWINTSSI_SIZE];
u8 delta_swing_table_idx_2ga_p_8188e[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2ga_n_8188e[DELTA_SWINGIDX_SIZE];
u8 bb_swing_idx_ofdm[MAX_RF_PATH];
u8 bb_swing_idx_ofdm_current;
#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
u8 bb_swing_idx_ofdm_base[MAX_RF_PATH];
#else
u8 bb_swing_idx_ofdm_base;
#endif
boolean bb_swing_flag_ofdm;
u8 bb_swing_idx_cck;
u8 bb_swing_idx_cck_current;
u8 bb_swing_idx_cck_base;
u8 default_ofdm_index;
u8 default_cck_index;
boolean bb_swing_flag_cck;
s8 absolute_ofdm_swing_idx[MAX_RF_PATH];
s8 remnant_ofdm_swing_idx[MAX_RF_PATH];
s8 absolute_cck_swing_idx[MAX_RF_PATH];
s8 remnant_cck_swing_idx;
s8 modify_tx_agc_value; /*Remnat compensate value at tx_agc */
boolean modify_tx_agc_flag_path_a;
boolean modify_tx_agc_flag_path_b;
boolean modify_tx_agc_flag_path_c;
boolean modify_tx_agc_flag_path_d;
boolean modify_tx_agc_flag_path_a_cck;
s8 kfree_offset[MAX_RF_PATH];
/* -------------------------------------------------------------------- */
/* for IQK */
u32 regc04;
u32 reg874;
u32 regc08;
u32 regb68;
u32 regb6c;
u32 reg870;
u32 reg860;
u32 reg864;
boolean is_iqk_initialized;
boolean is_lck_in_progress;
boolean is_antenna_detected;
boolean is_need_iqk;
boolean is_iqk_in_progress;
boolean is_iqk_pa_off;
u8 delta_iqk;
u32 ADDA_backup[IQK_ADDA_REG_NUM];
u32 IQK_MAC_backup[IQK_MAC_REG_NUM];
u32 IQK_BB_backup_recover[9];
u32 IQK_BB_backup[IQK_BB_REG_NUM];
u32 tx_iqc_8723b[2][3][2]; /* { {S1: 0xc94, 0xc80, 0xc4c} , {S0: 0xc9c, 0xc88, 0xc4c}} */
u32 rx_iqc_8723b[2][2][2]; /* { {S1: 0xc14, 0xca0} , {S0: 0xc14, 0xca0}} */
u32 tx_iqc_8703b[3][2]; /* { {S1: 0xc94, 0xc80, 0xc4c} , {S0: 0xc9c, 0xc88, 0xc4c}}*/
u32 rx_iqc_8703b[2][2]; /* { {S1: 0xc14, 0xca0} , {S0: 0xc14, 0xca0}}*/
u64 iqk_start_time;
u64 iqk_total_progressing_time;
u64 iqk_progressing_time;
u64 lck_progressing_time;
u32 lok_result;
u8 iqk_step;
u8 kcount;
u8 retry_count[4][2]; /* [4]: path ABCD, [2] TXK, RXK */
boolean is_mp_mode;
/* for APK */
u32 ap_koutput[2][2]; /* path A/B; output1_1a/output1_2a */
u8 is_ap_kdone;
u8 is_apk_thermal_meter_ignore;
u8 is_dp_done;
u8 is_dp_path_aok;
u8 is_dp_path_bok;
/*Add by Yuchen for Kfree Phydm*/
u8 reg_rf_kfree_enable; /*for registry*/
u8 rf_kfree_enable; /*for efuse enable check*/
u32 tx_lok[2];
};
void
odm_txpowertracking_check_ap(
void *dm_void
);
void
odm_txpowertracking_check(
void *dm_void
);
void
odm_txpowertracking_thermal_meter_init(
void *dm_void
);
void
odm_txpowertracking_init(
void *dm_void
);
void
odm_txpowertracking_check_mp(
void *dm_void
);
void
odm_txpowertracking_check_ce(
void *dm_void
);
#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN))
void
odm_txpowertracking_callback_thermal_meter92c(
void *adapter
);
void
odm_txpowertracking_callback_rx_gain_thermal_meter92d(
void *adapter
);
void
odm_txpowertracking_callback_thermal_meter92d(
void *adapter
);
void
odm_txpowertracking_direct_call92c(
void *adapter
);
void
odm_txpowertracking_thermal_meter_check(
void *adapter
);
#endif
#endif

View File

@ -0,0 +1,761 @@
/******************************************************************************
*
* 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 full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
/*============================================================ */
/* include files */
/*============================================================ */
#include "mp_precomp.h"
#include "phydm_precomp.h"
/* ************************************************************
* Global var
* ************************************************************ */
u32 ofdm_swing_table[OFDM_TABLE_SIZE] = {
0x7f8001fe, /* 0, +6.0dB */
0x788001e2, /* 1, +5.5dB */
0x71c001c7, /* 2, +5.0dB*/
0x6b8001ae, /* 3, +4.5dB*/
0x65400195, /* 4, +4.0dB*/
0x5fc0017f, /* 5, +3.5dB*/
0x5a400169, /* 6, +3.0dB*/
0x55400155, /* 7, +2.5dB*/
0x50800142, /* 8, +2.0dB*/
0x4c000130, /* 9, +1.5dB*/
0x47c0011f, /* 10, +1.0dB*/
0x43c0010f, /* 11, +0.5dB*/
0x40000100, /* 12, +0dB*/
0x3c8000f2, /* 13, -0.5dB*/
0x390000e4, /* 14, -1.0dB*/
0x35c000d7, /* 15, -1.5dB*/
0x32c000cb, /* 16, -2.0dB*/
0x300000c0, /* 17, -2.5dB*/
0x2d4000b5, /* 18, -3.0dB*/
0x2ac000ab, /* 19, -3.5dB*/
0x288000a2, /* 20, -4.0dB*/
0x26000098, /* 21, -4.5dB*/
0x24000090, /* 22, -5.0dB*/
0x22000088, /* 23, -5.5dB*/
0x20000080, /* 24, -6.0dB*/
0x1e400079, /* 25, -6.5dB*/
0x1c800072, /* 26, -7.0dB*/
0x1b00006c, /* 27. -7.5dB*/
0x19800066, /* 28, -8.0dB*/
0x18000060, /* 29, -8.5dB*/
0x16c0005b, /* 30, -9.0dB*/
0x15800056, /* 31, -9.5dB*/
0x14400051, /* 32, -10.0dB*/
0x1300004c, /* 33, -10.5dB*/
0x12000048, /* 34, -11.0dB*/
0x11000044, /* 35, -11.5dB*/
0x10000040, /* 36, -12.0dB*/
};
u8 cck_swing_table_ch1_ch13[CCK_TABLE_SIZE][8] = {
{0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, /* 0, +0dB */
{0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, /* 1, -0.5dB */
{0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, /* 2, -1.0dB*/
{0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, /* 3, -1.5dB*/
{0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, /* 4, -2.0dB */
{0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, /* 5, -2.5dB*/
{0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, /* 6, -3.0dB*/
{0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, /* 7, -3.5dB*/
{0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, /* 8, -4.0dB */
{0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, /* 9, -4.5dB*/
{0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, /* 10, -5.0dB */
{0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, /* 11, -5.5dB*/
{0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, /* 12, -6.0dB <== default */
{0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, /* 13, -6.5dB*/
{0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, /* 14, -7.0dB */
{0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, /* 15, -7.5dB*/
{0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, /* 16, -8.0dB */
{0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, /* 17, -8.5dB*/
{0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, /* 18, -9.0dB */
{0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 19, -9.5dB*/
{0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 20, -10.0dB*/
{0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 21, -10.5dB*/
{0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 22, -11.0dB*/
{0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, /* 23, -11.5dB*/
{0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, /* 24, -12.0dB*/
{0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, /* 25, -12.5dB*/
{0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, /* 26, -13.0dB*/
{0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 27, -13.5dB*/
{0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 28, -14.0dB*/
{0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 29, -14.5dB*/
{0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 30, -15.0dB*/
{0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, /* 31, -15.5dB*/
{0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01} /* 32, -16.0dB*/
};
u8 cck_swing_table_ch14[CCK_TABLE_SIZE][8] = {
{0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, /* 0, +0dB */
{0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, /* 1, -0.5dB */
{0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, /* 2, -1.0dB */
{0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, /* 3, -1.5dB*/
{0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, /* 4, -2.0dB */
{0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, /* 5, -2.5dB*/
{0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, /* 6, -3.0dB */
{0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, /* 7, -3.5dB */
{0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, /* 8, -4.0dB */
{0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, /* 9, -4.5dB*/
{0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, /* 10, -5.0dB */
{0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 11, -5.5dB*/
{0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 12, -6.0dB <== default*/
{0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, /* 13, -6.5dB */
{0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, /* 14, -7.0dB */
{0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 15, -7.5dB*/
{0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 16, -8.0dB */
{0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 17, -8.5dB*/
{0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 18, -9.0dB */
{0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 19, -9.5dB*/
{0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 20, -10.0dB*/
{0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 21, -10.5dB*/
{0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 22, -11.0dB*/
{0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 23, -11.5dB*/
{0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 24, -12.0dB*/
{0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 25, -12.5dB*/
{0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 26, -13.0dB*/
{0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 27, -13.5dB*/
{0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 28, -14.0dB*/
{0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 29, -14.5dB*/
{0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 30, -15.0dB*/
{0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 31, -15.5dB*/
{0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} /* 32, -16.0dB*/
};
u32 ofdm_swing_table_new[OFDM_TABLE_SIZE] = {
0x0b40002d, /* 0, -15.0dB */
0x0c000030, /* 1, -14.5dB*/
0x0cc00033, /* 2, -14.0dB*/
0x0d800036, /* 3, -13.5dB*/
0x0e400039, /* 4, -13.0dB */
0x0f00003c, /* 5, -12.5dB*/
0x10000040, /* 6, -12.0dB*/
0x11000044, /* 7, -11.5dB*/
0x12000048, /* 8, -11.0dB*/
0x1300004c, /* 9, -10.5dB*/
0x14400051, /* 10, -10.0dB*/
0x15800056, /* 11, -9.5dB*/
0x16c0005b, /* 12, -9.0dB*/
0x18000060, /* 13, -8.5dB*/
0x19800066, /* 14, -8.0dB*/
0x1b00006c, /* 15, -7.5dB*/
0x1c800072, /* 16, -7.0dB*/
0x1e400079, /* 17, -6.5dB*/
0x20000080, /* 18, -6.0dB*/
0x22000088, /* 19, -5.5dB*/
0x24000090, /* 20, -5.0dB*/
0x26000098, /* 21, -4.5dB*/
0x288000a2, /* 22, -4.0dB*/
0x2ac000ab, /* 23, -3.5dB*/
0x2d4000b5, /* 24, -3.0dB*/
0x300000c0, /* 25, -2.5dB*/
0x32c000cb, /* 26, -2.0dB*/
0x35c000d7, /* 27, -1.5dB*/
0x390000e4, /* 28, -1.0dB*/
0x3c8000f2, /* 29, -0.5dB*/
0x40000100, /* 30, +0dB*/
0x43c0010f, /* 31, +0.5dB*/
0x47c0011f, /* 32, +1.0dB*/
0x4c000130, /* 33, +1.5dB*/
0x50800142, /* 34, +2.0dB*/
0x55400155, /* 35, +2.5dB*/
0x5a400169, /* 36, +3.0dB*/
0x5fc0017f, /* 37, +3.5dB*/
0x65400195, /* 38, +4.0dB*/
0x6b8001ae, /* 39, +4.5dB*/
0x71c001c7, /* 40, +5.0dB*/
0x788001e2, /* 41, +5.5dB*/
0x7f8001fe /* 42, +6.0dB*/
};
u8 cck_swing_table_ch1_ch14_88f[CCK_TABLE_SIZE_88F][16] = {
{0x44, 0x42, 0x3C, 0x33, 0x28, 0x1C, 0x13, 0x0B, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-16dB*/
{0x48, 0x46, 0x3F, 0x36, 0x2A, 0x1E, 0x14, 0x0B, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-15.5dB*/
{0x4D, 0x4A, 0x43, 0x39, 0x2C, 0x20, 0x15, 0x0C, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-15dB*/
{0x51, 0x4F, 0x47, 0x3C, 0x2F, 0x22, 0x16, 0x0D, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-14.5dB*/
{0x56, 0x53, 0x4B, 0x40, 0x32, 0x24, 0x17, 0x0E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-14dB*/
{0x5B, 0x58, 0x50, 0x43, 0x35, 0x26, 0x19, 0x0E, 0x07, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-13.5dB*/
{0x60, 0x5D, 0x54, 0x47, 0x38, 0x28, 0x1A, 0x0F, 0x07, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-13dB*/
{0x66, 0x63, 0x59, 0x4C, 0x3B, 0x2B, 0x1C, 0x10, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-12.5dB*/
{0x6C, 0x69, 0x5F, 0x50, 0x3F, 0x2D, 0x1E, 0x11, 0x08, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-12dB*/
{0x73, 0x6F, 0x64, 0x55, 0x42, 0x30, 0x1F, 0x12, 0x08, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-11.5dB*/
{0x79, 0x76, 0x6A, 0x5A, 0x46, 0x33, 0x21, 0x13, 0x09, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-11dB*/
{0x81, 0x7C, 0x71, 0x5F, 0x4A, 0x36, 0x23, 0x14, 0x0A, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-10.5dB*/
{0x88, 0x84, 0x77, 0x65, 0x4F, 0x39, 0x25, 0x15, 0x0A, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-10dB*/
{0x90, 0x8C, 0x7E, 0x6B, 0x54, 0x3C, 0x27, 0x17, 0x0B, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-9.5dB*/
{0x99, 0x94, 0x86, 0x71, 0x58, 0x40, 0x2A, 0x18, 0x0B, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-9dB*/
{0xA2, 0x9D, 0x8E, 0x78, 0x5E, 0x43, 0x2C, 0x19, 0x0C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-8.5dB*/
{0xAC, 0xA6, 0x96, 0x7F, 0x63, 0x47, 0x2F, 0x1B, 0x0D, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-8dB*/
{0xB6, 0xB0, 0x9F, 0x87, 0x69, 0x4C, 0x32, 0x1D, 0x0D, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-7.5dB*/
{0xC1, 0xBA, 0xA8, 0x8F, 0x6F, 0x50, 0x35, 0x1E, 0x0E, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-7dB*/
{0xCC, 0xC5, 0xB2, 0x97, 0x76, 0x55, 0x38, 0x20, 0x0F, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-6.5dB*/
{0xD8, 0xD1, 0xBD, 0xA0, 0x7D, 0x5A, 0x3B, 0x22, 0x10, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /*-6dB*/
};
u8 cck_swing_table_ch1_ch13_88f[CCK_TABLE_SIZE_88F][16] = {
{0x44, 0x42, 0x3C, 0x33, 0x28, 0x1C, 0x13, 0x0B, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-16dB*/
{0x48, 0x46, 0x3F, 0x36, 0x2A, 0x1E, 0x14, 0x0B, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-15.5dB*/
{0x4D, 0x4A, 0x43, 0x39, 0x2C, 0x20, 0x15, 0x0C, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-15dB*/
{0x51, 0x4F, 0x47, 0x3C, 0x2F, 0x22, 0x16, 0x0D, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-14.5dB*/
{0x56, 0x53, 0x4B, 0x40, 0x32, 0x24, 0x17, 0x0E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-14dB*/
{0x5B, 0x58, 0x50, 0x43, 0x35, 0x26, 0x19, 0x0E, 0x07, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-13.5dB*/
{0x60, 0x5D, 0x54, 0x47, 0x38, 0x28, 0x1A, 0x0F, 0x07, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-13dB*/
{0x66, 0x63, 0x59, 0x4C, 0x3B, 0x2B, 0x1C, 0x10, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-12.5dB*/
{0x6C, 0x69, 0x5F, 0x50, 0x3F, 0x2D, 0x1E, 0x11, 0x08, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-12dB*/
{0x73, 0x6F, 0x64, 0x55, 0x42, 0x30, 0x1F, 0x12, 0x08, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-11.5dB*/
{0x79, 0x76, 0x6A, 0x5A, 0x46, 0x33, 0x21, 0x13, 0x09, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-11dB*/
{0x81, 0x7C, 0x71, 0x5F, 0x4A, 0x36, 0x23, 0x14, 0x0A, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-10.5dB*/
{0x88, 0x84, 0x77, 0x65, 0x4F, 0x39, 0x25, 0x15, 0x0A, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-10dB*/
{0x90, 0x8C, 0x7E, 0x6B, 0x54, 0x3C, 0x27, 0x17, 0x0B, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-9.5dB*/
{0x99, 0x94, 0x86, 0x71, 0x58, 0x40, 0x2A, 0x18, 0x0B, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-9dB*/
{0xA2, 0x9D, 0x8E, 0x78, 0x5E, 0x43, 0x2C, 0x19, 0x0C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-8.5dB*/
{0xAC, 0xA6, 0x96, 0x7F, 0x63, 0x47, 0x2F, 0x1B, 0x0D, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-8dB*/
{0xB6, 0xB0, 0x9F, 0x87, 0x69, 0x4C, 0x32, 0x1D, 0x0D, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-7.5dB*/
{0xC1, 0xBA, 0xA8, 0x8F, 0x6F, 0x50, 0x35, 0x1E, 0x0E, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-7dB*/
{0xCC, 0xC5, 0xB2, 0x97, 0x76, 0x55, 0x38, 0x20, 0x0F, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-6.5dB*/
{0xD8, 0xD1, 0xBD, 0xA0, 0x7D, 0x5A, 0x3B, 0x22, 0x10, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /*-6dB*/
};
u8 cck_swing_table_ch14_88f[CCK_TABLE_SIZE_88F][16] = {
{0x44, 0x42, 0x3C, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-16dB*/
{0x48, 0x46, 0x3F, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-15.5dB*/
{0x4D, 0x4A, 0x43, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-15dB*/
{0x51, 0x4F, 0x47, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-14.5dB*/
{0x56, 0x53, 0x4B, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-14dB*/
{0x5B, 0x58, 0x50, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-13.5dB*/
{0x60, 0x5D, 0x54, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-13dB*/
{0x66, 0x63, 0x59, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-12.5dB*/
{0x6C, 0x69, 0x5F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-12dB*/
{0x73, 0x6F, 0x64, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-11.5dB*/
{0x79, 0x76, 0x6A, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-11dB*/
{0x81, 0x7C, 0x71, 0x4A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-10.5dB*/
{0x88, 0x84, 0x77, 0x4F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-10dB*/
{0x90, 0x8C, 0x7E, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-9.5dB*/
{0x99, 0x94, 0x86, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-9dB*/
{0xA2, 0x9D, 0x8E, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-8.5dB*/
{0xAC, 0xA6, 0x96, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-8dB*/
{0xB6, 0xB0, 0x9F, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-7.5dB*/
{0xC1, 0xBA, 0xA8, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-7dB*/
{0xCC, 0xC5, 0xB2, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-6.5dB*/
{0xD8, 0xD1, 0xBD, 0x7D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /*-6dB*/
};
u8 cck_swing_table_ch1_ch13_new[CCK_TABLE_SIZE][8] = {
{0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01}, /* 0, -16.0dB*/
{0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, /* 1, -15.5dB*/
{0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 2, -15.0dB*/
{0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 3, -14.5dB*/
{0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 4, -14.0dB*/
{0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 5, -13.5dB*/
{0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, /* 6, -13.0dB*/
{0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, /* 7, -12.5dB*/
{0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, /* 8, -12.0dB*/
{0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, /* 9, -11.5dB*/
{0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 10, -11.0dB*/
{0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 11, -10.5dB*/
{0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 12, -10.0dB*/
{0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 13, -9.5dB*/
{0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, /* 14, -9.0dB */
{0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, /* 15, -8.5dB*/
{0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, /* 16, -8.0dB */
{0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, /* 17, -7.5dB*/
{0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, /* 18, -7.0dB */
{0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, /* 19, -6.5dB*/
{0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, /*20, -6.0dB */
{0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, /* 21, -5.5dB*/
{0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, /* 22, -5.0dB */
{0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, /* 23, -4.5dB*/
{0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, /* 24, -4.0dB */
{0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, /* 25, -3.5dB*/
{0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, /* 26, -3.0dB*/
{0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, /* 27, -2.5dB*/
{0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, /* 28, -2.0dB */
{0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, /* 29, -1.5dB*/
{0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, /* 30, -1.0dB*/
{0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, /* 31, -0.5dB*/
{0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04} /* 32, +0dB*/
};
u8 cck_swing_table_ch14_new[CCK_TABLE_SIZE][8] = {
{0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00}, /* 0, -16.0dB*/
{0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 1, -15.5dB*/
{0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 2, -15.0dB*/
{0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 3, -14.5dB*/
{0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 4, -14.0dB*/
{0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /*5, -13.5dB*/
{0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 6, -13.0dB*/
{0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 7, -12.5dB*/
{0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 8, -12.0dB*/
{0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 9, -11.5dB*/
{0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 10, -11.0dB*/
{0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, /*11, -10.5dB*/
{0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 12, -10.0dB*/
{0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 13, -9.5dB*/
{0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, /*14, -9.0dB */
{0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 15, -8.5dB*/
{0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 16, -8.0dB */
{0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 17, -7.5dB*/
{0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, /* 18, -7.0dB */
{0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, /* 19, -6.5dB */
{0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 20, -6.0dB */
{0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 21, -5.5dB*/
{0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, /* 22, -5.0dB */
{0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, /*23, -4.5dB*/
{0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, /* 24, -4.0dB */
{0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, /* 25, -3.5dB */
{0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, /* 26, -3.0dB */
{0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, /*27, -2.5dB*/
{0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, /* 28, -2.0dB */
{0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, /*29, -1.5dB*/
{0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, /* 30, -1.0dB */
{0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, /* 31, -0.5dB */
{0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00} /* 32, +0dB */
};
u32 cck_swing_table_ch1_ch14_8723d[CCK_TABLE_SIZE_8723D] = {
0x0CD, /*0 , -20dB*/
0x0D9,
0x0E6,
0x0F3,
0x102,
0x111,
0x121,
0x132,
0x144,
0x158,
0x16C,
0x182,
0x198,
0x1B1,
0x1CA,
0x1E5,
0x202,
0x221,
0x241,
0x263,
0x287,
0x2AE,
0x2D6,
0x301,
0x32F,
0x35F,
0x392,
0x3C9,
0x402,
0x43F,
0x47F,
0x4C3,
0x50C,
0x558,
0x5A9,
0x5FF,
0x65A,
0x6BA,
0x720,
0x78C,
0x7FF,
};
/* JJ ADD 20161014 */
u32 cck_swing_table_ch1_ch14_8710b[CCK_TABLE_SIZE_8710B] = {
0x0CD, /*0 , -20dB*/
0x0D9,
0x0E6,
0x0F3,
0x102,
0x111,
0x121,
0x132,
0x144,
0x158,
0x16C,
0x182,
0x198,
0x1B1,
0x1CA,
0x1E5,
0x202,
0x221,
0x241,
0x263,
0x287,
0x2AE,
0x2D6,
0x301,
0x32F,
0x35F,
0x392,
0x3C9,
0x402,
0x43F,
0x47F,
0x4C3,
0x50C,
0x558,
0x5A9,
0x5FF,
0x65A,
0x6BA,
0x720,
0x78C,
0x7FF,
};
u32 tx_scaling_table_jaguar[TXSCALE_TABLE_SIZE] = {
0x081, /* 0, -12.0dB*/
0x088, /* 1, -11.5dB*/
0x090, /* 2, -11.0dB*/
0x099, /* 3, -10.5dB*/
0x0A2, /* 4, -10.0dB*/
0x0AC, /* 5, -9.5dB*/
0x0B6, /* 6, -9.0dB*/
0x0C0, /*7, -8.5dB*/
0x0CC, /* 8, -8.0dB*/
0x0D8, /* 9, -7.5dB*/
0x0E5, /* 10, -7.0dB*/
0x0F2, /* 11, -6.5dB*/
0x101, /* 12, -6.0dB*/
0x110, /* 13, -5.5dB*/
0x120, /* 14, -5.0dB*/
0x131, /* 15, -4.5dB*/
0x143, /* 16, -4.0dB*/
0x156, /* 17, -3.5dB*/
0x16A, /* 18, -3.0dB*/
0x180, /* 19, -2.5dB*/
0x197, /* 20, -2.0dB*/
0x1AF, /* 21, -1.5dB*/
0x1C8, /* 22, -1.0dB*/
0x1E3, /* 23, -0.5dB*/
0x200, /* 24, +0 dB*/
0x21E, /* 25, +0.5dB*/
0x23E, /* 26, +1.0dB*/
0x261, /* 27, +1.5dB*/
0x285,/* 28, +2.0dB*/
0x2AB, /* 29, +2.5dB*/
0x2D3, /*30, +3.0dB*/
0x2FE, /* 31, +3.5dB*/
0x32B, /* 32, +4.0dB*/
0x35C, /* 33, +4.5dB*/
0x38E, /* 34, +5.0dB*/
0x3C4, /* 35, +5.5dB*/
0x3FE /* 36, +6.0dB */
};
void
odm_txpowertracking_init(
void *dm_void
)
{
struct dm_struct *dm = (struct dm_struct *)dm_void;
#if (DM_ODM_SUPPORT_TYPE & (ODM_AP))
if (!(dm->support_ic_type & (ODM_RTL8814A | ODM_IC_11N_SERIES | ODM_RTL8822B)))
return;
#endif
odm_txpowertracking_thermal_meter_init(dm);
}
u8
get_swing_index(
void *dm_void
)
{
struct dm_struct *dm = (struct dm_struct *)dm_void;
#if ((RTL8812A_SUPPORT == 1) || (RTL8821A_SUPPORT == 1))
void *adapter = dm->adapter;
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
#endif
u8 i = 0;
u32 bb_swing;
u32 swing_table_size;
u32 *swing_table;
if (dm->support_ic_type == ODM_RTL8188E || dm->support_ic_type == ODM_RTL8723B
|| dm->support_ic_type == ODM_RTL8192E || dm->support_ic_type == ODM_RTL8188F || dm->support_ic_type == ODM_RTL8703B || dm->support_ic_type == ODM_RTL8723D || dm->support_ic_type == ODM_RTL8710B
) {
bb_swing = odm_get_bb_reg(dm, REG_OFDM_0_XA_TX_IQ_IMBALANCE, 0xFFC00000);
swing_table = ofdm_swing_table_new;
swing_table_size = OFDM_TABLE_SIZE;
} else {
#if ((RTL8812A_SUPPORT == 1) || (RTL8821A_SUPPORT == 1))
if (dm->support_ic_type == ODM_RTL8812 || dm->support_ic_type == ODM_RTL8821) {
bb_swing = phy_get_tx_bb_swing_8812a(adapter, hal_data->current_band_type, RF_PATH_A);
swing_table = tx_scaling_table_jaguar;
swing_table_size = TXSCALE_TABLE_SIZE;
} else
#endif
{
bb_swing = 0;
swing_table = ofdm_swing_table;
swing_table_size = OFDM_TABLE_SIZE;
}
}
for (i = 0; i < swing_table_size; ++i) {
u32 table_value = swing_table[i];
if (table_value >= 0x100000)
table_value >>= 22;
if (bb_swing == table_value)
break;
}
return i;
}
u8
get_cck_swing_index(
void *dm_void
)
{
struct dm_struct *dm = (struct dm_struct *)dm_void;
u8 i = 0;
u32 bb_cck_swing;
if (dm->support_ic_type == ODM_RTL8188E || dm->support_ic_type == ODM_RTL8723B ||
dm->support_ic_type == ODM_RTL8192E) {
bb_cck_swing = odm_read_1byte(dm, 0xa22);
for (i = 0; i < CCK_TABLE_SIZE; i++) {
if (bb_cck_swing == cck_swing_table_ch1_ch13_new[i][0])
break;
}
} else if (dm->support_ic_type == ODM_RTL8703B) {
bb_cck_swing = odm_read_1byte(dm, 0xa22);
for (i = 0; i < CCK_TABLE_SIZE_88F; i++) {
if (bb_cck_swing == cck_swing_table_ch1_ch14_88f[i][0])
break;
}
}
return i;
}
void
odm_txpowertracking_thermal_meter_init(
void *dm_void
)
{
struct dm_struct *dm = (struct dm_struct *)dm_void;
u8 default_swing_index = get_swing_index(dm);
u8 default_cck_swing_index = get_cck_swing_index(dm);
u8 p = 0;
struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
void *adapter = dm->adapter;
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
if (*dm->mp_mode == false)
hal_data->txpowertrack_control = true;
#elif (DM_ODM_SUPPORT_TYPE == ODM_CE)
#ifdef DM_ODM_CE_MAC80211
struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
struct rtl_efuse *rtlefu = rtl_efuse(rtlpriv);
#else
void *adapter = dm->adapter;
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
#endif
cali_info->is_txpowertracking = true;
cali_info->tx_powercount = 0;
cali_info->is_txpowertracking_init = false;
if (*dm->mp_mode == false)
cali_info->txpowertrack_control = true;
else
cali_info->txpowertrack_control = false;
if (*dm->mp_mode == false)
cali_info->txpowertrack_control = true;
PHYDM_DBG(dm, ODM_COMP_CALIBRATION, "dm txpowertrack_control = %d\n", cali_info->txpowertrack_control);
#elif (DM_ODM_SUPPORT_TYPE & (ODM_AP))
#ifdef RTL8188E_SUPPORT
{
cali_info->is_txpowertracking = true;
cali_info->tx_powercount = 0;
cali_info->is_txpowertracking_init = false;
cali_info->txpowertrack_control = true;
}
#endif
#endif
/* dm->rf_calibrate_info.txpowertrack_control = true; */
#if (DM_ODM_SUPPORT_TYPE == ODM_CE) && defined(DM_ODM_CE_MAC80211)
cali_info->thermal_value = rtlefu->eeprom_thermalmeter;
cali_info->thermal_value_iqk = rtlefu->eeprom_thermalmeter;
cali_info->thermal_value_lck = rtlefu->eeprom_thermalmeter;
#else
cali_info->thermal_value = hal_data->eeprom_thermal_meter;
cali_info->thermal_value_iqk = hal_data->eeprom_thermal_meter;
cali_info->thermal_value_lck = hal_data->eeprom_thermal_meter;
#endif
if (cali_info->default_bb_swing_index_flag != true) {
/*The index of "0 dB" in SwingTable.*/
if (dm->support_ic_type == ODM_RTL8188E || dm->support_ic_type == ODM_RTL8723B ||
dm->support_ic_type == ODM_RTL8192E || dm->support_ic_type == ODM_RTL8703B) {
cali_info->default_ofdm_index = (default_swing_index >= OFDM_TABLE_SIZE) ? 30 : default_swing_index;
cali_info->default_cck_index = (default_cck_swing_index >= CCK_TABLE_SIZE) ? 20 : default_cck_swing_index;
} else if (dm->support_ic_type == ODM_RTL8188F) { /*add by Mingzhi.Guo 2015-03-23*/
cali_info->default_ofdm_index = 28; /*OFDM: -1dB*/
cali_info->default_cck_index = 20; /*CCK:-6dB*/
} else if (dm->support_ic_type == ODM_RTL8723D) { /*add by zhaohe 2015-10-27*/
cali_info->default_ofdm_index = 28; /*OFDM: -1dB*/
cali_info->default_cck_index = 28; /*CCK: -6dB*/
} else if (dm->support_ic_type == ODM_RTL8710B) { /* JJ ADD 20161014 */
cali_info->default_ofdm_index = 28; /*OFDM: -1dB*/
cali_info->default_cck_index = 28; /*CCK: -6dB*/
} else {
cali_info->default_ofdm_index = (default_swing_index >= TXSCALE_TABLE_SIZE) ? 24 : default_swing_index;
cali_info->default_cck_index = 24;
}
cali_info->default_bb_swing_index_flag = true;
}
cali_info->bb_swing_idx_cck_base = cali_info->default_cck_index;
cali_info->CCK_index = cali_info->default_cck_index;
for (p = RF_PATH_A; p < MAX_RF_PATH; ++p) {
cali_info->bb_swing_idx_ofdm_base[p] = cali_info->default_ofdm_index;
cali_info->OFDM_index[p] = cali_info->default_ofdm_index;
cali_info->delta_power_index[p] = 0;
cali_info->delta_power_index_last[p] = 0;
cali_info->power_index_offset[p] = 0;
}
cali_info->modify_tx_agc_value_ofdm = 0;
cali_info->modify_tx_agc_value_cck = 0;
cali_info->tm_trigger = 0;
}
void
odm_txpowertracking_check(
void *dm_void
)
{
/* 2011/09/29 MH In HW integration first stage, we provide 4 different handle to operate
at the same time. In the stage2/3, we need to prive universal interface and merge all
HW dynamic mechanism. */
struct dm_struct *dm = (struct dm_struct *)dm_void;
switch (dm->support_platform) {
case ODM_WIN:
odm_txpowertracking_check_mp(dm);
break;
case ODM_CE:
odm_txpowertracking_check_ce(dm);
break;
case ODM_AP:
odm_txpowertracking_check_ap(dm);
break;
default:
break;
}
}
void
odm_txpowertracking_check_ce(
void *dm_void
)
{
struct dm_struct *dm = (struct dm_struct *)dm_void;
struct _hal_rf_ *rf = &dm->rf_table;
#if (DM_ODM_SUPPORT_TYPE == ODM_CE)
void *adapter = dm->adapter;
if (!(rf->rf_supportability & HAL_RF_TX_PWR_TRACK))
return;
if (!dm->rf_calibrate_info.tm_trigger) {
if (dm->support_ic_type &
(ODM_RTL8188E | ODM_RTL8188F | ODM_RTL8192E |
ODM_RTL8723B | ODM_RTL8812 | ODM_RTL8821 |
ODM_RTL8814A | ODM_RTL8703B | ODM_RTL8723D |
ODM_RTL8822B | ODM_RTL8821C | ODM_RTL8710B))
odm_set_rf_reg(dm, RF_PATH_A, RF_T_METER_NEW, (BIT(17) | BIT(16)), 0x03);
else
odm_set_rf_reg(dm, RF_PATH_A, RF_T_METER_OLD, RFREGOFFSETMASK, 0x60);
dm->rf_calibrate_info.tm_trigger = 1;
return;
} else {
odm_txpowertracking_callback_thermal_meter(dm);
dm->rf_calibrate_info.tm_trigger = 0;
}
#endif
}
void
odm_txpowertracking_check_mp(
void *dm_void
)
{
#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
struct dm_struct *dm = (struct dm_struct *)dm_void;
void *adapter = dm->adapter;
if (odm_check_power_status(adapter) == false) {
RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD, ("check_pow_status, return false\n"));
return;
}
odm_txpowertracking_thermal_meter_check(adapter);
#endif
}
void
odm_txpowertracking_check_ap(
void *dm_void
)
{
#if (DM_ODM_SUPPORT_TYPE == ODM_AP)
struct dm_struct *dm = (struct dm_struct *)dm_void;
struct rtl8192cd_priv *priv = dm->priv;
return;
#endif
}

View File

@ -0,0 +1,348 @@
/******************************************************************************
*
* 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 full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __PHYDMPOWERTRACKING_H__
#define __PHYDMPOWERTRACKING_H__
#define DPK_DELTA_MAPPING_NUM 13
#define index_mapping_HP_NUM 15
#define OFDM_TABLE_SIZE 43
#define CCK_TABLE_SIZE 33
#define CCK_TABLE_SIZE_88F 21
#define TXSCALE_TABLE_SIZE 37
#define CCK_TABLE_SIZE_8723D 41
/* JJ ADD 20161014 */
#define CCK_TABLE_SIZE_8710B 41
#define TXPWR_TRACK_TABLE_SIZE 30
#define DELTA_SWINGIDX_SIZE 30
#define DELTA_SWINTSSI_SIZE 61
#define BAND_NUM 4
#define AVG_THERMAL_NUM 8
#define IQK_MAC_REG_NUM 4
#define IQK_ADDA_REG_NUM 16
#define IQK_BB_REG_NUM_MAX 10
#define IQK_BB_REG_NUM 9
#define iqk_matrix_reg_num 8
#if (DM_ODM_SUPPORT_TYPE == ODM_CE) && defined(DM_ODM_CE_MAC80211)
#else
#define IQK_MATRIX_SETTINGS_NUM (14+24+21) /* Channels_2_4G_NUM + Channels_5G_20M_NUM + Channels_5G */
#endif
extern u32 ofdm_swing_table[OFDM_TABLE_SIZE];
extern u8 cck_swing_table_ch1_ch13[CCK_TABLE_SIZE][8];
extern u8 cck_swing_table_ch14[CCK_TABLE_SIZE][8];
extern u32 ofdm_swing_table_new[OFDM_TABLE_SIZE];
extern u8 cck_swing_table_ch1_ch13_new[CCK_TABLE_SIZE][8];
extern u8 cck_swing_table_ch14_new[CCK_TABLE_SIZE][8];
extern u8 cck_swing_table_ch1_ch14_88f[CCK_TABLE_SIZE_88F][16];
extern u8 cck_swing_table_ch1_ch13_88f[CCK_TABLE_SIZE_88F][16];
extern u8 cck_swing_table_ch14_88f[CCK_TABLE_SIZE_88F][16];
extern u32 cck_swing_table_ch1_ch14_8723d[CCK_TABLE_SIZE_8723D];
/* JJ ADD 20161014 */
extern u32 cck_swing_table_ch1_ch14_8710b[CCK_TABLE_SIZE_8710B];
extern u32 tx_scaling_table_jaguar[TXSCALE_TABLE_SIZE];
/* <20121018, Kordan> In case fail to read TxPowerTrack.txt, we use the table of 88E as the default table. */
#if (DM_ODM_SUPPORT_TYPE == ODM_CE) && defined(DM_ODM_CE_MAC80211)
#else
static u8 delta_swing_table_idx_2ga_p_8188e[] = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9};
static u8 delta_swing_table_idx_2ga_n_8188e[] = {0, 0, 0, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11};
#endif
#define dm_check_txpowertracking odm_txpowertracking_check
struct iqk_matrix_regs_setting {
boolean is_iqk_done;
s32 value[3][iqk_matrix_reg_num];
boolean is_bw_iqk_result_saved[3];
};
struct dm_rf_calibration_struct {
/* for tx power tracking */
u32 rega24; /* for TempCCK */
s32 rege94;
s32 rege9c;
s32 regeb4;
s32 regebc;
u8 tx_powercount;
boolean is_txpowertracking_init;
boolean is_txpowertracking;
u8 txpowertrack_control; /* for mp mode, turn off txpwrtracking as default */
u8 tm_trigger;
u8 internal_pa_5g[2]; /* pathA / pathB */
u8 thermal_meter[2]; /* thermal_meter, index 0 for RFIC0, and 1 for RFIC1 */
u8 thermal_value;
u8 thermal_value_lck;
u8 thermal_value_iqk;
s8 thermal_value_delta; /* delta of thermal_value and efuse thermal */
u8 thermal_value_dpk;
u8 thermal_value_avg[AVG_THERMAL_NUM];
u8 thermal_value_avg_index;
u8 thermal_value_rx_gain;
u8 thermal_value_crystal;
u8 thermal_value_dpk_store;
u8 thermal_value_dpk_track;
boolean txpowertracking_in_progress;
boolean is_reloadtxpowerindex;
u8 is_rf_pi_enable;
u32 txpowertracking_callback_cnt; /* cosa add for debug */
/* ------------------------- Tx power Tracking ------------------------- */
u8 is_cck_in_ch14;
u8 CCK_index;
u8 OFDM_index[MAX_RF_PATH];
s8 power_index_offset[MAX_RF_PATH];
s8 delta_power_index[MAX_RF_PATH];
s8 delta_power_index_last[MAX_RF_PATH];
boolean is_tx_power_changed;
s8 xtal_offset;
s8 xtal_offset_last;
struct iqk_matrix_regs_setting iqk_matrix_reg_setting[IQK_MATRIX_SETTINGS_NUM];
u8 delta_lck;
s8 bb_swing_diff_2g, bb_swing_diff_5g; /* Unit: dB */
u8 delta_swing_table_idx_2g_cck_a_p[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2g_cck_a_n[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2g_cck_b_p[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2g_cck_b_n[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2g_cck_c_p[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2g_cck_c_n[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2g_cck_d_p[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2g_cck_d_n[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2ga_p[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2ga_n[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2gb_p[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2gb_n[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2gc_p[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2gc_n[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2gd_p[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2gd_n[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_5ga_p[BAND_NUM][DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_5ga_n[BAND_NUM][DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_5gb_p[BAND_NUM][DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_5gb_n[BAND_NUM][DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_5gc_p[BAND_NUM][DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_5gc_n[BAND_NUM][DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_5gd_p[BAND_NUM][DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_5gd_n[BAND_NUM][DELTA_SWINGIDX_SIZE];
u8 delta_swing_tssi_table_2g_cck_a[DELTA_SWINTSSI_SIZE];
u8 delta_swing_tssi_table_2g_cck_b[DELTA_SWINTSSI_SIZE];
u8 delta_swing_tssi_table_2g_cck_c[DELTA_SWINTSSI_SIZE];
u8 delta_swing_tssi_table_2g_cck_d[DELTA_SWINTSSI_SIZE];
u8 delta_swing_tssi_table_2ga[DELTA_SWINTSSI_SIZE];
u8 delta_swing_tssi_table_2gb[DELTA_SWINTSSI_SIZE];
u8 delta_swing_tssi_table_2gc[DELTA_SWINTSSI_SIZE];
u8 delta_swing_tssi_table_2gd[DELTA_SWINTSSI_SIZE];
u8 delta_swing_tssi_table_5ga[BAND_NUM][DELTA_SWINTSSI_SIZE];
u8 delta_swing_tssi_table_5gb[BAND_NUM][DELTA_SWINTSSI_SIZE];
u8 delta_swing_tssi_table_5gc[BAND_NUM][DELTA_SWINTSSI_SIZE];
u8 delta_swing_tssi_table_5gd[BAND_NUM][DELTA_SWINTSSI_SIZE];
s8 delta_swing_table_xtal_p[DELTA_SWINGIDX_SIZE];
s8 delta_swing_table_xtal_n[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2ga_p_8188e[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2ga_n_8188e[DELTA_SWINGIDX_SIZE];
u8 bb_swing_idx_ofdm[MAX_RF_PATH];
u8 bb_swing_idx_ofdm_current;
#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
u8 bb_swing_idx_ofdm_base[MAX_RF_PATH];
#else
u8 bb_swing_idx_ofdm_base;
#endif
boolean default_bb_swing_index_flag;
boolean bb_swing_flag_ofdm;
u8 bb_swing_idx_cck;
u8 bb_swing_idx_cck_current;
u8 bb_swing_idx_cck_base;
u8 default_ofdm_index;
u8 default_cck_index;
boolean bb_swing_flag_cck;
s8 absolute_ofdm_swing_idx[MAX_RF_PATH];
s8 remnant_ofdm_swing_idx[MAX_RF_PATH];
s8 absolute_cck_swing_idx[MAX_RF_PATH];
s8 remnant_cck_swing_idx;
s8 modify_tx_agc_value; /*Remnat compensate value at tx_agc */
boolean modify_tx_agc_flag_path_a;
boolean modify_tx_agc_flag_path_b;
boolean modify_tx_agc_flag_path_c;
boolean modify_tx_agc_flag_path_d;
boolean modify_tx_agc_flag_path_a_cck;
s8 kfree_offset[MAX_RF_PATH];
/* -------------------------------------------------------------------- */
/* for IQK */
u32 regc04;
u32 reg874;
u32 regc08;
u32 regb68;
u32 regb6c;
u32 reg870;
u32 reg860;
u32 reg864;
boolean is_iqk_initialized;
boolean is_lck_in_progress;
boolean is_antenna_detected;
boolean is_need_iqk;
boolean is_iqk_in_progress;
boolean is_iqk_pa_off;
u8 delta_iqk;
u32 ADDA_backup[IQK_ADDA_REG_NUM];
u32 IQK_MAC_backup[IQK_MAC_REG_NUM];
u32 IQK_BB_backup_recover[9];
u32 IQK_BB_backup[IQK_BB_REG_NUM];
u32 tx_iqc_8723b[2][3][2]; /* { {S1: 0xc94, 0xc80, 0xc4c} , {S0: 0xc9c, 0xc88, 0xc4c}} */
u32 rx_iqc_8723b[2][2][2]; /* { {S1: 0xc14, 0xca0} , {S0: 0xc14, 0xca0}} */
u32 tx_iqc_8703b[3][2]; /* { {S1: 0xc94, 0xc80, 0xc4c} , {S0: 0xc9c, 0xc88, 0xc4c}}*/
u32 rx_iqc_8703b[2][2]; /* { {S1: 0xc14, 0xca0} , {S0: 0xc14, 0xca0}}*/
u32 tx_iqc_8723d[2][3][2]; /* { {S1: 0xc94, 0xc80, 0xc4c} , {S0: 0xc9c, 0xc88, 0xc4c}}*/
u32 rx_iqc_8723d[2][2][2]; /* { {S1: 0xc14, 0xca0} , {S0: 0xc14, 0xca0}}*/
/* JJ ADD 20161014 */
u32 tx_iqc_8710b[2][3][2]; /* { {S1: 0xc94, 0xc80, 0xc4c} , {S0: 0xc9c, 0xc88, 0xc4c}}*/
u32 rx_iqc_8710b[2][2][2]; /* { {S1: 0xc14, 0xca0} , {S0: 0xc14, 0xca0}}*/
u8 iqk_step;
u8 kcount;
u8 retry_count[4][2]; /* [4]: path ABCD, [2] TXK, RXK */
boolean is_mp_mode;
/* <James> IQK time measurement */
u64 iqk_start_time;
u64 iqk_progressing_time;
u64 iqk_total_progressing_time;
u64 lck_progressing_time;
u32 lok_result;
/* for APK */
u32 ap_koutput[2][2]; /* path A/B; output1_1a/output1_2a */
u8 is_ap_kdone;
u8 is_apk_thermal_meter_ignore;
/* DPK */
boolean is_dpk_fail;
u8 is_dp_done;
u8 is_dp_path_aok;
u8 is_dp_path_bok;
u32 tx_lok[2];
u32 dpk_tx_agc;
s32 dpk_gain;
u32 dpk_thermal[4];
s8 modify_tx_agc_value_ofdm;
s8 modify_tx_agc_value_cck;
/*Add by Yuchen for Kfree Phydm*/
u8 reg_rf_kfree_enable; /*for registry*/
u8 rf_kfree_enable; /*for efuse enable check*/
};
void
odm_txpowertracking_check(
void *dm_void
);
void
odm_txpowertracking_init(
void *dm_void
);
void
odm_txpowertracking_check_ap(
void *dm_void
);
void
odm_txpowertracking_thermal_meter_init(
void *dm_void
);
void
odm_txpowertracking_init(
void *dm_void
);
void
odm_txpowertracking_check_mp(
void *dm_void
);
void
odm_txpowertracking_check_ce(
void *dm_void
);
#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN))
void
odm_txpowertracking_callback_thermal_meter92c(
void *adapter
);
void
odm_txpowertracking_callback_rx_gain_thermal_meter92d(
void *adapter
);
void
odm_txpowertracking_callback_thermal_meter92d(
void *adapter
);
void
odm_txpowertracking_direct_call92c(
void *adapter
);
void
odm_txpowertracking_thermal_meter_check(
void *adapter
);
#endif
#endif

View File

@ -0,0 +1,806 @@
/******************************************************************************
*
* 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 files */
/*============================================================ */
#include "mp_precomp.h"
#include "phydm_precomp.h"
/* ************************************************************
* Global var
* ************************************************************ */
u32 ofdm_swing_table[OFDM_TABLE_SIZE] = {
0x7f8001fe, /* 0, +6.0dB */
0x788001e2, /* 1, +5.5dB */
0x71c001c7, /* 2, +5.0dB */
0x6b8001ae, /* 3, +4.5dB */
0x65400195, /* 4, +4.0dB */
0x5fc0017f, /* 5, +3.5dB */
0x5a400169, /* 6, +3.0dB */
0x55400155, /* 7, +2.5dB */
0x50800142, /* 8, +2.0dB */
0x4c000130, /* 9, +1.5dB */
0x47c0011f, /* 10, +1.0dB */
0x43c0010f, /* 11, +0.5dB */
0x40000100, /* 12, +0dB */
0x3c8000f2, /* 13, -0.5dB */
0x390000e4, /* 14, -1.0dB */
0x35c000d7, /* 15, -1.5dB */
0x32c000cb, /* 16, -2.0dB */
0x300000c0, /* 17, -2.5dB */
0x2d4000b5, /* 18, -3.0dB */
0x2ac000ab, /* 19, -3.5dB */
0x288000a2, /* 20, -4.0dB */
0x26000098, /* 21, -4.5dB */
0x24000090, /* 22, -5.0dB */
0x22000088, /* 23, -5.5dB */
0x20000080, /* 24, -6.0dB */
0x1e400079, /* 25, -6.5dB */
0x1c800072, /* 26, -7.0dB */
0x1b00006c, /* 27. -7.5dB */
0x19800066, /* 28, -8.0dB */
0x18000060, /* 29, -8.5dB */
0x16c0005b, /* 30, -9.0dB */
0x15800056, /* 31, -9.5dB */
0x14400051, /* 32, -10.0dB */
0x1300004c, /* 33, -10.5dB */
0x12000048, /* 34, -11.0dB */
0x11000044, /* 35, -11.5dB */
0x10000040, /* 36, -12.0dB */
};
u8 cck_swing_table_ch1_ch13[CCK_TABLE_SIZE][8] = {
{0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, /* 0, +0dB */
{0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, /* 1, -0.5dB */
{0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, /* 2, -1.0dB */
{0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, /* 3, -1.5dB */
{0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, /* 4, -2.0dB */
{0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, /* 5, -2.5dB */
{0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, /* 6, -3.0dB */
{0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, /* 7, -3.5dB */
{0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, /* 8, -4.0dB */
{0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, /* 9, -4.5dB */
{0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, /* 10, -5.0dB */
{0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, /* 11, -5.5dB */
{0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, /* 12, -6.0dB <== default */
{0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, /* 13, -6.5dB */
{0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, /* 14, -7.0dB */
{0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, /* 15, -7.5dB */
{0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, /* 16, -8.0dB */
{0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, /* 17, -8.5dB */
{0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, /* 18, -9.0dB */
{0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 19, -9.5dB */
{0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 20, -10.0dB */
{0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 21, -10.5dB */
{0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 22, -11.0dB */
{0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, /* 23, -11.5dB */
{0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, /* 24, -12.0dB */
{0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, /* 25, -12.5dB */
{0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, /* 26, -13.0dB */
{0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 27, -13.5dB */
{0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 28, -14.0dB */
{0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 29, -14.5dB */
{0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 30, -15.0dB */
{0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, /* 31, -15.5dB */
{0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01} /* 32, -16.0dB */
};
u8 cck_swing_table_ch14[CCK_TABLE_SIZE][8] = {
{0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, /* 0, +0dB */
{0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, /* 1, -0.5dB */
{0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, /* 2, -1.0dB */
{0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, /* 3, -1.5dB */
{0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, /* 4, -2.0dB */
{0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, /* 5, -2.5dB */
{0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, /* 6, -3.0dB */
{0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, /* 7, -3.5dB */
{0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, /* 8, -4.0dB */
{0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, /* 9, -4.5dB */
{0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, /* 10, -5.0dB */
{0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 11, -5.5dB */
{0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 12, -6.0dB <== default */
{0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, /* 13, -6.5dB */
{0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, /* 14, -7.0dB */
{0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 15, -7.5dB */
{0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 16, -8.0dB */
{0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 17, -8.5dB */
{0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 18, -9.0dB */
{0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 19, -9.5dB */
{0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 20, -10.0dB */
{0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 21, -10.5dB */
{0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 22, -11.0dB */
{0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 23, -11.5dB */
{0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 24, -12.0dB */
{0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 25, -12.5dB */
{0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 26, -13.0dB */
{0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 27, -13.5dB */
{0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 28, -14.0dB */
{0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 29, -14.5dB */
{0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 30, -15.0dB */
{0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 31, -15.5dB */
{0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} /* 32, -16.0dB */
};
u32 ofdm_swing_table_new[OFDM_TABLE_SIZE] = {
0x0b40002d, /* 0, -15.0dB */
0x0c000030, /* 1, -14.5dB */
0x0cc00033, /* 2, -14.0dB */
0x0d800036, /* 3, -13.5dB */
0x0e400039, /* 4, -13.0dB */
0x0f00003c, /* 5, -12.5dB */
0x10000040, /* 6, -12.0dB */
0x11000044, /* 7, -11.5dB */
0x12000048, /* 8, -11.0dB */
0x1300004c, /* 9, -10.5dB */
0x14400051, /* 10, -10.0dB */
0x15800056, /* 11, -9.5dB */
0x16c0005b, /* 12, -9.0dB */
0x18000060, /* 13, -8.5dB */
0x19800066, /* 14, -8.0dB */
0x1b00006c, /* 15, -7.5dB */
0x1c800072, /* 16, -7.0dB */
0x1e400079, /* 17, -6.5dB */
0x20000080, /* 18, -6.0dB */
0x22000088, /* 19, -5.5dB */
0x24000090, /* 20, -5.0dB */
0x26000098, /* 21, -4.5dB */
0x288000a2, /* 22, -4.0dB */
0x2ac000ab, /* 23, -3.5dB */
0x2d4000b5, /* 24, -3.0dB */
0x300000c0, /* 25, -2.5dB */
0x32c000cb, /* 26, -2.0dB */
0x35c000d7, /* 27, -1.5dB */
0x390000e4, /* 28, -1.0dB */
0x3c8000f2, /* 29, -0.5dB */
0x40000100, /* 30, +0dB */
0x43c0010f, /* 31, +0.5dB */
0x47c0011f, /* 32, +1.0dB */
0x4c000130, /* 33, +1.5dB */
0x50800142, /* 34, +2.0dB */
0x55400155, /* 35, +2.5dB */
0x5a400169, /* 36, +3.0dB */
0x5fc0017f, /* 37, +3.5dB */
0x65400195, /* 38, +4.0dB */
0x6b8001ae, /* 39, +4.5dB */
0x71c001c7, /* 40, +5.0dB */
0x788001e2, /* 41, +5.5dB */
0x7f8001fe /* 42, +6.0dB */
};
u8 cck_swing_table_ch1_ch14_88f[CCK_TABLE_SIZE_88F][16] = {
{0x44, 0x42, 0x3C, 0x33, 0x28, 0x1C, 0x13, 0x0B, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-16dB*/
{0x48, 0x46, 0x3F, 0x36, 0x2A, 0x1E, 0x14, 0x0B, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-15.5dB*/
{0x4D, 0x4A, 0x43, 0x39, 0x2C, 0x20, 0x15, 0x0C, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-15dB*/
{0x51, 0x4F, 0x47, 0x3C, 0x2F, 0x22, 0x16, 0x0D, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-14.5dB*/
{0x56, 0x53, 0x4B, 0x40, 0x32, 0x24, 0x17, 0x0E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-14dB*/
{0x5B, 0x58, 0x50, 0x43, 0x35, 0x26, 0x19, 0x0E, 0x07, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-13.5dB*/
{0x60, 0x5D, 0x54, 0x47, 0x38, 0x28, 0x1A, 0x0F, 0x07, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-13dB*/
{0x66, 0x63, 0x59, 0x4C, 0x3B, 0x2B, 0x1C, 0x10, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-12.5dB*/
{0x6C, 0x69, 0x5F, 0x50, 0x3F, 0x2D, 0x1E, 0x11, 0x08, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-12dB*/
{0x73, 0x6F, 0x64, 0x55, 0x42, 0x30, 0x1F, 0x12, 0x08, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-11.5dB*/
{0x79, 0x76, 0x6A, 0x5A, 0x46, 0x33, 0x21, 0x13, 0x09, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-11dB*/
{0x81, 0x7C, 0x71, 0x5F, 0x4A, 0x36, 0x23, 0x14, 0x0A, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-10.5dB*/
{0x88, 0x84, 0x77, 0x65, 0x4F, 0x39, 0x25, 0x15, 0x0A, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-10dB*/
{0x90, 0x8C, 0x7E, 0x6B, 0x54, 0x3C, 0x27, 0x17, 0x0B, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-9.5dB*/
{0x99, 0x94, 0x86, 0x71, 0x58, 0x40, 0x2A, 0x18, 0x0B, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-9dB*/
{0xA2, 0x9D, 0x8E, 0x78, 0x5E, 0x43, 0x2C, 0x19, 0x0C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-8.5dB*/
{0xAC, 0xA6, 0x96, 0x7F, 0x63, 0x47, 0x2F, 0x1B, 0x0D, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-8dB*/
{0xB6, 0xB0, 0x9F, 0x87, 0x69, 0x4C, 0x32, 0x1D, 0x0D, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-7.5dB*/
{0xC1, 0xBA, 0xA8, 0x8F, 0x6F, 0x50, 0x35, 0x1E, 0x0E, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-7dB*/
{0xCC, 0xC5, 0xB2, 0x97, 0x76, 0x55, 0x38, 0x20, 0x0F, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-6.5dB*/
{0xD8, 0xD1, 0xBD, 0xA0, 0x7D, 0x5A, 0x3B, 0x22, 0x10, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /*-6dB*/
};
u8 cck_swing_table_ch1_ch13_88f[CCK_TABLE_SIZE_88F][16] = {
{0x44, 0x42, 0x3C, 0x33, 0x28, 0x1C, 0x13, 0x0B, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-16dB*/
{0x48, 0x46, 0x3F, 0x36, 0x2A, 0x1E, 0x14, 0x0B, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-15.5dB*/
{0x4D, 0x4A, 0x43, 0x39, 0x2C, 0x20, 0x15, 0x0C, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-15dB*/
{0x51, 0x4F, 0x47, 0x3C, 0x2F, 0x22, 0x16, 0x0D, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-14.5dB*/
{0x56, 0x53, 0x4B, 0x40, 0x32, 0x24, 0x17, 0x0E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-14dB*/
{0x5B, 0x58, 0x50, 0x43, 0x35, 0x26, 0x19, 0x0E, 0x07, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-13.5dB*/
{0x60, 0x5D, 0x54, 0x47, 0x38, 0x28, 0x1A, 0x0F, 0x07, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-13dB*/
{0x66, 0x63, 0x59, 0x4C, 0x3B, 0x2B, 0x1C, 0x10, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-12.5dB*/
{0x6C, 0x69, 0x5F, 0x50, 0x3F, 0x2D, 0x1E, 0x11, 0x08, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-12dB*/
{0x73, 0x6F, 0x64, 0x55, 0x42, 0x30, 0x1F, 0x12, 0x08, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-11.5dB*/
{0x79, 0x76, 0x6A, 0x5A, 0x46, 0x33, 0x21, 0x13, 0x09, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-11dB*/
{0x81, 0x7C, 0x71, 0x5F, 0x4A, 0x36, 0x23, 0x14, 0x0A, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-10.5dB*/
{0x88, 0x84, 0x77, 0x65, 0x4F, 0x39, 0x25, 0x15, 0x0A, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-10dB*/
{0x90, 0x8C, 0x7E, 0x6B, 0x54, 0x3C, 0x27, 0x17, 0x0B, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-9.5dB*/
{0x99, 0x94, 0x86, 0x71, 0x58, 0x40, 0x2A, 0x18, 0x0B, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-9dB*/
{0xA2, 0x9D, 0x8E, 0x78, 0x5E, 0x43, 0x2C, 0x19, 0x0C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-8.5dB*/
{0xAC, 0xA6, 0x96, 0x7F, 0x63, 0x47, 0x2F, 0x1B, 0x0D, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-8dB*/
{0xB6, 0xB0, 0x9F, 0x87, 0x69, 0x4C, 0x32, 0x1D, 0x0D, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-7.5dB*/
{0xC1, 0xBA, 0xA8, 0x8F, 0x6F, 0x50, 0x35, 0x1E, 0x0E, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-7dB*/
{0xCC, 0xC5, 0xB2, 0x97, 0x76, 0x55, 0x38, 0x20, 0x0F, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-6.5dB*/
{0xD8, 0xD1, 0xBD, 0xA0, 0x7D, 0x5A, 0x3B, 0x22, 0x10, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /*-6dB*/
};
u8 cck_swing_table_ch14_88f[CCK_TABLE_SIZE_88F][16] = {
{0x44, 0x42, 0x3C, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-16dB*/
{0x48, 0x46, 0x3F, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-15.5dB*/
{0x4D, 0x4A, 0x43, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-15dB*/
{0x51, 0x4F, 0x47, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-14.5dB*/
{0x56, 0x53, 0x4B, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-14dB*/
{0x5B, 0x58, 0x50, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-13.5dB*/
{0x60, 0x5D, 0x54, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-13dB*/
{0x66, 0x63, 0x59, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-12.5dB*/
{0x6C, 0x69, 0x5F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-12dB*/
{0x73, 0x6F, 0x64, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-11.5dB*/
{0x79, 0x76, 0x6A, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-11dB*/
{0x81, 0x7C, 0x71, 0x4A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-10.5dB*/
{0x88, 0x84, 0x77, 0x4F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-10dB*/
{0x90, 0x8C, 0x7E, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-9.5dB*/
{0x99, 0x94, 0x86, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-9dB*/
{0xA2, 0x9D, 0x8E, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-8.5dB*/
{0xAC, 0xA6, 0x96, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-8dB*/
{0xB6, 0xB0, 0x9F, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-7.5dB*/
{0xC1, 0xBA, 0xA8, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-7dB*/
{0xCC, 0xC5, 0xB2, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-6.5dB*/
{0xD8, 0xD1, 0xBD, 0x7D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /*-6dB*/
};
u8 cck_swing_table_ch1_ch13_new[CCK_TABLE_SIZE][8] = {
{0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01}, /* 0, -16.0dB */
{0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, /* 1, -15.5dB */
{0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 2, -15.0dB */
{0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 3, -14.5dB */
{0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 4, -14.0dB */
{0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 5, -13.5dB */
{0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, /* 6, -13.0dB */
{0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, /* 7, -12.5dB */
{0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, /* 8, -12.0dB */
{0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, /* 9, -11.5dB */
{0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 10, -11.0dB */
{0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 11, -10.5dB */
{0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 12, -10.0dB */
{0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 13, -9.5dB */
{0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, /* 14, -9.0dB */
{0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, /* 15, -8.5dB */
{0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, /* 16, -8.0dB */
{0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, /* 17, -7.5dB */
{0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, /* 18, -7.0dB */
{0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, /* 19, -6.5dB */
{0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, /* 20, -6.0dB */
{0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, /* 21, -5.5dB */
{0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, /* 22, -5.0dB */
{0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, /* 23, -4.5dB */
{0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, /* 24, -4.0dB */
{0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, /* 25, -3.5dB */
{0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, /* 26, -3.0dB */
{0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, /* 27, -2.5dB */
{0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, /* 28, -2.0dB */
{0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, /* 29, -1.5dB */
{0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, /* 30, -1.0dB */
{0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, /* 31, -0.5dB */
{0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04} /* 32, +0dB */
};
u8 cck_swing_table_ch14_new[CCK_TABLE_SIZE][8] = {
{0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00}, /* 0, -16.0dB */
{0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 1, -15.5dB */
{0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 2, -15.0dB */
{0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 3, -14.5dB */
{0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 4, -14.0dB */
{0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 5, -13.5dB */
{0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 6, -13.0dB */
{0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 7, -12.5dB */
{0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 8, -12.0dB */
{0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 9, -11.5dB */
{0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 10, -11.0dB */
{0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 11, -10.5dB */
{0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 12, -10.0dB */
{0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 13, -9.5dB */
{0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 14, -9.0dB */
{0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 15, -8.5dB */
{0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 16, -8.0dB */
{0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 17, -7.5dB */
{0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, /* 18, -7.0dB */
{0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, /* 19, -6.5dB */
{0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 20, -6.0dB */
{0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 21, -5.5dB */
{0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, /* 22, -5.0dB */
{0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, /* 23, -4.5dB */
{0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, /* 24, -4.0dB */
{0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, /* 25, -3.5dB */
{0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, /* 26, -3.0dB */
{0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, /* 27, -2.5dB */
{0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, /* 28, -2.0dB */
{0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, /* 29, -1.5dB */
{0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, /* 30, -1.0dB */
{0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, /* 31, -0.5dB */
{0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00} /* 32, +0dB */
};
u32 cck_swing_table_ch1_ch14_8723d[CCK_TABLE_SIZE_8723D] = {
0x0CD,
0x0D9,
0x0E6,
0x0F3,
0x102,
0x111,
0x121,
0x132,
0x144,
0x158,
0x16C,
0x182,
0x198,
0x1B1,
0x1CA,
0x1E5,
0x202,
0x221,
0x241,
0x263,
0x287,
0x2AE,
0x2D6,
0x301,
0x32F,
0x35F,
0x392,
0x3C9,
0x402,
0x43F,
0x47F,
0x4C3,
0x50C,
0x558,
0x5A9,
0x5FF,
0x65A,
0x6BA,
0x720,
0x78C,
0x7FF,
};
/* JJ ADD 20161014 */
u32 cck_swing_table_ch1_ch14_8710b[CCK_TABLE_SIZE_8710B] = {
0x0CD, /*0 , -20dB*/
0x0D9,
0x0E6,
0x0F3,
0x102,
0x111,
0x121,
0x132,
0x144,
0x158,
0x16C,
0x182,
0x198,
0x1B1,
0x1CA,
0x1E5,
0x202,
0x221,
0x241,
0x263, /*19*/
0x287, /*20*/
0x2AE, /*21*/
0x2D6, /*22*/
0x301, /*23*/
0x32F, /*24*/
0x35F, /*25*/
0x392, /*26*/
0x3C9, /*27*/
0x402, /*28*/
0x43F, /*29*/
0x47F, /*30*/
0x4C3, /*31*/
0x50C, /*32*/
0x558, /*33*/
0x5A9, /*34*/
0x5FF, /*35*/
0x65A, /*36*/
0x6BA,
0x720,
0x78C,
0x7FF,
};
u32 tx_scaling_table_jaguar[TXSCALE_TABLE_SIZE] = {
0x081, /* 0, -12.0dB */
0x088, /* 1, -11.5dB */
0x090, /* 2, -11.0dB */
0x099, /* 3, -10.5dB */
0x0A2, /* 4, -10.0dB */
0x0AC, /* 5, -9.5dB */
0x0B6, /* 6, -9.0dB */
0x0C0, /* 7, -8.5dB */
0x0CC, /* 8, -8.0dB */
0x0D8, /* 9, -7.5dB */
0x0E5, /* 10, -7.0dB */
0x0F2, /* 11, -6.5dB */
0x101, /* 12, -6.0dB */
0x110, /* 13, -5.5dB */
0x120, /* 14, -5.0dB */
0x131, /* 15, -4.5dB */
0x143, /* 16, -4.0dB */
0x156, /* 17, -3.5dB */
0x16A, /* 18, -3.0dB */
0x180, /* 19, -2.5dB */
0x197, /* 20, -2.0dB */
0x1AF, /* 21, -1.5dB */
0x1C8, /* 22, -1.0dB */
0x1E3, /* 23, -0.5dB */
0x200, /* 24, +0 dB */
0x21E, /* 25, +0.5dB */
0x23E, /* 26, +1.0dB */
0x261, /* 27, +1.5dB */
0x285, /* 28, +2.0dB */
0x2AB, /* 29, +2.5dB */
0x2D3, /* 30, +3.0dB */
0x2FE, /* 31, +3.5dB */
0x32B, /* 32, +4.0dB */
0x35C, /* 33, +4.5dB */
0x38E, /* 34, +5.0dB */
0x3C4, /* 35, +5.5dB */
0x3FE /* 36, +6.0dB */
};
void
odm_txpowertracking_init(
void *dm_void
)
{
struct dm_struct *dm = (struct dm_struct *)dm_void;
#if (DM_ODM_SUPPORT_TYPE & (ODM_AP))
if (!(dm->support_ic_type & (ODM_RTL8814A | ODM_IC_11N_SERIES | ODM_RTL8822B)))
return;
#endif
odm_txpowertracking_thermal_meter_init(dm);
}
u8
get_swing_index(
void *dm_void
)
{
struct dm_struct *dm = (struct dm_struct *)dm_void;
void *adapter = dm->adapter;
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(((PADAPTER)adapter));
u8 i = 0;
u32 bb_swing;
u32 swing_table_size;
u32 *swing_table;
if (dm->support_ic_type == ODM_RTL8188E || dm->support_ic_type == ODM_RTL8723B ||
dm->support_ic_type == ODM_RTL8192E || dm->support_ic_type == ODM_RTL8188F || dm->support_ic_type == ODM_RTL8703B || dm->support_ic_type == ODM_RTL8723D || dm->support_ic_type == ODM_RTL8710B) {
bb_swing = odm_get_bb_reg(dm, REG_OFDM_0_XA_TX_IQ_IMBALANCE, 0xFFC00000);
swing_table = ofdm_swing_table_new;
swing_table_size = OFDM_TABLE_SIZE;
} else {
bb_swing = PHY_GetTxBBSwing_8812A((PADAPTER)adapter, hal_data->CurrentBandType, RF_PATH_A);
swing_table = tx_scaling_table_jaguar;
swing_table_size = TXSCALE_TABLE_SIZE;
}
for (i = 0; i < swing_table_size; ++i) {
u32 table_value = swing_table[i];
if (table_value >= 0x100000)
table_value >>= 22;
if (bb_swing == table_value)
break;
}
return i;
}
u8
get_cck_swing_index(
void *dm_void
)
{
struct dm_struct *dm = (struct dm_struct *)dm_void;
u8 i = 0;
u32 bb_cck_swing;
if (dm->support_ic_type == ODM_RTL8188E || dm->support_ic_type == ODM_RTL8723B ||
dm->support_ic_type == ODM_RTL8192E) {
bb_cck_swing = odm_read_1byte(dm, 0xa22);
for (i = 0; i < CCK_TABLE_SIZE; i++) {
if (bb_cck_swing == cck_swing_table_ch1_ch13_new[i][0])
break;
}
} else if (dm->support_ic_type == ODM_RTL8703B) {
bb_cck_swing = odm_read_1byte(dm, 0xa22);
for (i = 0; i < CCK_TABLE_SIZE_88F; i++) {
if (bb_cck_swing == cck_swing_table_ch1_ch14_88f[i][0])
break;
}
}
return i;
}
void
odm_txpowertracking_thermal_meter_init(
void *dm_void
)
{
struct dm_struct *dm = (struct dm_struct *)dm_void;
u8 default_swing_index = get_swing_index(dm);
u8 default_cck_swing_index = get_cck_swing_index(dm);
struct dm_rf_calibration_struct *cali_info = &(dm->rf_calibrate_info);
#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
void *adapter = dm->adapter;
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(((PADAPTER)adapter));
u8 p = 0;
if (*(dm->mp_mode) == false)
cali_info->txpowertrack_control = true;
#elif (DM_ODM_SUPPORT_TYPE == ODM_CE)
#ifdef CONFIG_RTL8188E
{
cali_info->is_txpowertracking = true;
cali_info->tx_powercount = 0;
cali_info->is_txpowertracking_init = false;
if (*(dm->mp_mode) == false)
cali_info->txpowertrack_control = true;
MSG_8192C("dm txpowertrack_control = %d\n", cali_info->txpowertrack_control);
}
#else
{
void *adapter = dm->adapter;
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(((PADAPTER)adapter));
struct dm_priv *pdmpriv = &hal_data->dmpriv;
pdmpriv->is_txpowertracking = true;
pdmpriv->tx_powercount = 0;
pdmpriv->is_txpowertracking_init = false;
if (*(dm->mp_mode) == false)
pdmpriv->txpowertrack_control = true;
MSG_8192C("pdmpriv->txpowertrack_control = %d\n", pdmpriv->txpowertrack_control);
}
#endif
#elif (DM_ODM_SUPPORT_TYPE & (ODM_AP))
#ifdef RTL8188E_SUPPORT
{
cali_info->is_txpowertracking = true;
cali_info->tx_powercount = 0;
cali_info->is_txpowertracking_init = false;
cali_info->txpowertrack_control = true;
}
#endif
#endif
#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
#if (MP_DRIVER == 1)
cali_info->txpowertrack_control = false;
#else
cali_info->txpowertrack_control = true;
#endif
#else
cali_info->txpowertrack_control = true;
#endif
cali_info->thermal_value = hal_data->eeprom_thermal_meter;
cali_info->thermal_value_iqk = hal_data->eeprom_thermal_meter;
cali_info->thermal_value_lck = hal_data->eeprom_thermal_meter;
if (cali_info->default_bb_swing_index_flag != true) {
/*The index of "0 dB" in SwingTable.*/
if (dm->support_ic_type == ODM_RTL8188E || dm->support_ic_type == ODM_RTL8723B ||
dm->support_ic_type == ODM_RTL8192E || dm->support_ic_type == ODM_RTL8703B) {
cali_info->default_ofdm_index = (default_swing_index >= OFDM_TABLE_SIZE) ? 30 : default_swing_index;
cali_info->default_cck_index = (default_cck_swing_index >= CCK_TABLE_SIZE) ? 20 : default_cck_swing_index;
} else if (dm->support_ic_type == ODM_RTL8188F) { /*add by Mingzhi.Guo 2015-03-23*/
cali_info->default_ofdm_index = 28; /*OFDM: -1dB*/
cali_info->default_cck_index = 20; /*CCK:-6dB*/
} else if (dm->support_ic_type == ODM_RTL8723D) { /*add by zhaohe 2015-10-27*/
cali_info->default_ofdm_index = 28; /*OFDM: -1dB*/
cali_info->default_cck_index = 28; /*CCK: -6dB*/
/* JJ ADD 20161014 */
} else if (dm->support_ic_type == ODM_RTL8710B) {
cali_info->default_ofdm_index = 28; /*OFDM: -1dB*/
cali_info->default_cck_index = 28; /*CCK: -6dB*/
} else {
cali_info->default_ofdm_index = (default_swing_index >= TXSCALE_TABLE_SIZE) ? 24 : default_swing_index;
cali_info->default_cck_index = 24;
}
cali_info->default_bb_swing_index_flag = true;
}
cali_info->bb_swing_idx_cck_base = cali_info->default_cck_index;
cali_info->CCK_index = cali_info->default_cck_index;
for (p = RF_PATH_A; p < MAX_RF_PATH; ++p) {
cali_info->bb_swing_idx_ofdm_base[p] = cali_info->default_ofdm_index;
cali_info->OFDM_index[p] = cali_info->default_ofdm_index;
cali_info->delta_power_index[p] = 0;
cali_info->delta_power_index_last[p] = 0;
cali_info->power_index_offset[p] = 0;
cali_info->kfree_offset[p] = 0;
}
cali_info->modify_tx_agc_value_ofdm = 0;
cali_info->modify_tx_agc_value_cck = 0;
cali_info->tm_trigger = 0;
}
void
odm_txpowertracking_check(
void *dm_void
)
{
#if 0
/* 2011/09/29 MH In HW integration first stage, we provide 4 different handle to operate */
/* at the same time. In the stage2/3, we need to prive universal interface and merge all */
/* HW dynamic mechanism. */
#endif
struct dm_struct *dm = (struct dm_struct *)dm_void;
switch (dm->support_platform) {
case ODM_WIN:
odm_txpowertracking_check_mp(dm);
break;
case ODM_CE:
odm_txpowertracking_check_ce(dm);
break;
case ODM_AP:
odm_txpowertracking_check_ap(dm);
break;
default:
break;
}
}
void
odm_txpowertracking_check_ce(
void *dm_void
)
{
struct dm_struct *dm = (struct dm_struct *)dm_void;
struct _hal_rf_ *rf = &(dm->rf_table);
#if (DM_ODM_SUPPORT_TYPE == ODM_CE)
void *adapter = dm->adapter;
#if ((RTL8188F_SUPPORT == 1))
rtl8192c_odm_check_txpowertracking(adapter);
#endif
#if (RTL8188E_SUPPORT == 1)
if (!(rf->rf_supportability & HAL_RF_TX_PWR_TRACK))
return;
if (!cali_info->tm_trigger) {
odm_set_rf_reg(dm, RF_PATH_A, RF_T_METER, RFREGOFFSETMASK, 0x60);
/*DBG_8192C("Trigger 92C Thermal Meter!!\n");*/
cali_info->tm_trigger = 1;
return;
} else {
/*DBG_8192C("Schedule TxPowerTracking direct call!!\n");*/
odm_txpowertracking_callback_thermal_meter_8188e(adapter);
cali_info->tm_trigger = 0;
}
#endif
#endif
}
void
odm_txpowertracking_check_mp(
void *dm_void
)
{
struct dm_struct *dm = (struct dm_struct *)dm_void;
#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
void *adapter = dm->adapter;
if (*dm->is_fcs_mode_enable)
return;
if (odm_check_power_status(dm) == false) {
RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD, ("check_pow_status return false\n"));
return;
}
if (IS_HARDWARE_TYPE_8821B(adapter)) /* TODO: Don't Do PowerTracking*/
return;
odm_txpowertracking_thermal_meter_check(adapter);
#endif
}
void
odm_txpowertracking_check_ap(
void *dm_void
)
{
return;
}
#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
void
odm_txpowertracking_direct_call(
void *adapter
)
{
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(((PADAPTER)adapter));
struct dm_struct *dm = &hal_data->DM_OutSrc;
odm_txpowertracking_callback_thermal_meter(adapter);
}
void
odm_txpowertracking_thermal_meter_check(
void *adapter
)
{
static u8 tm_trigger = 0;
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(((PADAPTER)adapter));
struct dm_struct *dm = &(pHalData->DM_OutSrc);
struct _hal_rf_ *rf = &(dm->rf_table);
if (!(rf->rf_supportability & HAL_RF_TX_PWR_TRACK)) {
RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
("===>odm_txpowertracking_thermal_meter_check(),mgnt_info->is_txpowertracking is false, return!!\n"));
return;
}
if (!tm_trigger) {
if (IS_HARDWARE_TYPE_8188E(adapter) || IS_HARDWARE_TYPE_JAGUAR(adapter) || IS_HARDWARE_TYPE_8192E(adapter) ||
IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8814A(adapter) || IS_HARDWARE_TYPE_8188F(adapter) || IS_HARDWARE_TYPE_8703B(adapter)
|| IS_HARDWARE_TYPE_8822B(adapter) || IS_HARDWARE_TYPE_8723D(adapter) || IS_HARDWARE_TYPE_8821C(adapter) || IS_HARDWARE_TYPE_8710B(adapter))/* JJ ADD 20161014 */
PHY_SetRFReg((PADAPTER)adapter, RF_PATH_A, RF_T_METER_88E, BIT(17) | BIT(16), 0x03);
else
PHY_SetRFReg((PADAPTER)adapter, RF_PATH_A, RF_T_METER, RFREGOFFSETMASK, 0x60);
RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD, ("Trigger Thermal Meter!!\n"));
tm_trigger = 1;
return;
} else {
RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD, ("Schedule TxPowerTracking direct call!!\n"));
odm_txpowertracking_direct_call(adapter);
tm_trigger = 0;
}
}
#endif

View File

@ -0,0 +1,299 @@
/******************************************************************************
*
* 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 __PHYDMPOWERTRACKING_H__
#define __PHYDMPOWERTRACKING_H__
#define DPK_DELTA_MAPPING_NUM 13
#define index_mapping_HP_NUM 15
#define TXSCALE_TABLE_SIZE 37
#define OFDM_TABLE_SIZE 43
#define CCK_TABLE_SIZE 33
#define CCK_TABLE_SIZE_8723D 41
#define TXPWR_TRACK_TABLE_SIZE 30
#define DELTA_SWINGIDX_SIZE 30
#define DELTA_SWINTSSI_SIZE 61
#define BAND_NUM 3
#define MAX_RF_PATH 4
#define CCK_TABLE_SIZE_88F 21
/* JJ ADD 20161014 */
#define CCK_TABLE_SIZE_8710B 41
#define dm_check_txpowertracking odm_txpowertracking_check
#define IQK_MATRIX_SETTINGS_NUM (14+24+21) /* Channels_2_4G_NUM + Channels_5G_20M_NUM + Channels_5G */
#define AVG_THERMAL_NUM 8
#define iqk_matrix_reg_num 8
#define IQK_MAC_REG_NUM 4
#define IQK_ADDA_REG_NUM 16
#define IQK_BB_REG_NUM 9
extern u32 ofdm_swing_table[OFDM_TABLE_SIZE];
extern u8 cck_swing_table_ch1_ch13[CCK_TABLE_SIZE][8];
extern u8 cck_swing_table_ch14[CCK_TABLE_SIZE][8];
extern u32 ofdm_swing_table_new[OFDM_TABLE_SIZE];
extern u8 cck_swing_table_ch1_ch13_new[CCK_TABLE_SIZE][8];
extern u8 cck_swing_table_ch14_new[CCK_TABLE_SIZE][8];
extern u8 cck_swing_table_ch1_ch14_88f[CCK_TABLE_SIZE_88F][16];
extern u8 cck_swing_table_ch1_ch13_88f[CCK_TABLE_SIZE_88F][16];
extern u8 cck_swing_table_ch14_88f[CCK_TABLE_SIZE_88F][16];
extern u32 cck_swing_table_ch1_ch14_8723d[CCK_TABLE_SIZE_8723D];
/* JJ ADD 20161014 */
extern u32 cck_swing_table_ch1_ch14_8710b[CCK_TABLE_SIZE_8710B];
extern u32 tx_scaling_table_jaguar[TXSCALE_TABLE_SIZE];
/* <20121018, Kordan> In case fail to read TxPowerTrack.txt, we use the table of 88E as the default table. */
static u8 delta_swing_table_idx_2ga_p_8188e[] = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9};
static u8 delta_swing_table_idx_2ga_n_8188e[] = {0, 0, 0, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11};
void
odm_txpowertracking_check(
void *dm_void
);
void
odm_txpowertracking_check_ap(
void *dm_void
);
void
odm_txpowertracking_thermal_meter_init(
void *dm_void
);
void
odm_txpowertracking_init(
void *dm_void
);
void
odm_txpowertracking_check_mp(
void *dm_void
);
void
odm_txpowertracking_check_ce(
void *dm_void
);
#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN))
void
odm_txpowertracking_thermal_meter_check(
void *adapter
);
#endif
struct iqk_matrix_regs_setting {
boolean is_iqk_done;
s32 value[3][iqk_matrix_reg_num];
boolean is_bw_iqk_result_saved[3];
};
struct dm_rf_calibration_struct {
/* for tx power tracking */
u32 rega24; /* for TempCCK */
s32 rege94;
s32 rege9c;
s32 regeb4;
s32 regebc;
/* u8 is_txpowertracking; */
u8 tx_powercount;
boolean is_txpowertracking_init;
boolean is_txpowertracking;
u8 txpowertrack_control; /* for mp mode, turn off txpwrtracking as default */
u8 tm_trigger;
u8 internal_pa_5g[2]; /* pathA / pathB */
u8 thermal_meter[2]; /* thermal_meter, index 0 for RFIC0, and 1 for RFIC1 */
u8 thermal_value;
u8 thermal_value_lck;
u8 thermal_value_iqk;
u8 thermal_value_dpk;
s8 thermal_value_delta; /* delta of thermal_value and efuse thermal */
u8 thermal_value_avg[AVG_THERMAL_NUM];
u8 thermal_value_avg_index;
u8 thermal_value_rx_gain;
boolean is_reloadtxpowerindex;
u8 is_rf_pi_enable;
u32 txpowertracking_callback_cnt; /* cosa add for debug */
/* ------------------------- Tx power Tracking ------------------------- */
u8 is_cck_in_ch14;
u8 CCK_index;
u8 OFDM_index[MAX_RF_PATH];
s8 power_index_offset[MAX_RF_PATH];
s8 delta_power_index[MAX_RF_PATH];
s8 delta_power_index_last[MAX_RF_PATH];
boolean is_tx_power_changed;
s8 xtal_offset;
s8 xtal_offset_last;
struct iqk_matrix_regs_setting iqk_matrix_reg_setting[IQK_MATRIX_SETTINGS_NUM];
u8 delta_lck;
s8 bb_swing_diff_2g, bb_swing_diff_5g; /* Unit: dB */
u8 delta_swing_table_idx_2g_cck_a_p[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2g_cck_a_n[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2g_cck_b_p[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2g_cck_b_n[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2g_cck_c_p[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2g_cck_c_n[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2g_cck_d_p[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2g_cck_d_n[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2ga_p[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2ga_n[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2gb_p[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2gb_n[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2gc_p[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2gc_n[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2gd_p[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2gd_n[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_5ga_p[BAND_NUM][DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_5ga_n[BAND_NUM][DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_5gb_p[BAND_NUM][DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_5gb_n[BAND_NUM][DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_5gc_p[BAND_NUM][DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_5gc_n[BAND_NUM][DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_5gd_p[BAND_NUM][DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_5gd_n[BAND_NUM][DELTA_SWINGIDX_SIZE];
u8 delta_swing_tssi_table_2g_cck_a[DELTA_SWINTSSI_SIZE];
u8 delta_swing_tssi_table_2g_cck_b[DELTA_SWINTSSI_SIZE];
u8 delta_swing_tssi_table_2g_cck_c[DELTA_SWINTSSI_SIZE];
u8 delta_swing_tssi_table_2g_cck_d[DELTA_SWINTSSI_SIZE];
u8 delta_swing_tssi_table_2ga[DELTA_SWINTSSI_SIZE];
u8 delta_swing_tssi_table_2gb[DELTA_SWINTSSI_SIZE];
u8 delta_swing_tssi_table_2gc[DELTA_SWINTSSI_SIZE];
u8 delta_swing_tssi_table_2gd[DELTA_SWINTSSI_SIZE];
u8 delta_swing_tssi_table_5ga[BAND_NUM][DELTA_SWINTSSI_SIZE];
u8 delta_swing_tssi_table_5gb[BAND_NUM][DELTA_SWINTSSI_SIZE];
u8 delta_swing_tssi_table_5gc[BAND_NUM][DELTA_SWINTSSI_SIZE];
u8 delta_swing_tssi_table_5gd[BAND_NUM][DELTA_SWINTSSI_SIZE];
s8 delta_swing_table_xtal_p[DELTA_SWINGIDX_SIZE];
s8 delta_swing_table_xtal_n[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2ga_p_8188e[DELTA_SWINGIDX_SIZE];
u8 delta_swing_table_idx_2ga_n_8188e[DELTA_SWINGIDX_SIZE];
u8 bb_swing_idx_ofdm[MAX_RF_PATH];
u8 bb_swing_idx_ofdm_current;
#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
u8 bb_swing_idx_ofdm_base[MAX_RF_PATH];
#else
u8 bb_swing_idx_ofdm_base;
#endif
boolean default_bb_swing_index_flag;
boolean bb_swing_flag_ofdm;
u8 bb_swing_idx_cck;
u8 bb_swing_idx_cck_current;
u8 bb_swing_idx_cck_base;
u8 default_ofdm_index;
u8 default_cck_index;
boolean bb_swing_flag_cck;
s8 absolute_ofdm_swing_idx[MAX_RF_PATH];
s8 remnant_ofdm_swing_idx[MAX_RF_PATH];
s8 absolute_cck_swing_idx[MAX_RF_PATH];
s8 remnant_cck_swing_idx;
s8 modify_tx_agc_value; /*Remnat compensate value at tx_agc */
boolean modify_tx_agc_flag_path_a;
boolean modify_tx_agc_flag_path_b;
boolean modify_tx_agc_flag_path_c;
boolean modify_tx_agc_flag_path_d;
boolean modify_tx_agc_flag_path_a_cck;
s8 kfree_offset[MAX_RF_PATH];
/* -------------------------------------------------------------------- */
/* for IQK */
u32 regc04;
u32 reg874;
u32 regc08;
u32 regb68;
u32 regb6c;
u32 reg870;
u32 reg860;
u32 reg864;
boolean is_iqk_initialized;
boolean is_lck_in_progress;
boolean is_antenna_detected;
boolean is_need_iqk;
boolean is_iqk_in_progress;
boolean is_iqk_pa_off;
u8 delta_iqk;
u32 ADDA_backup[IQK_ADDA_REG_NUM];
u32 IQK_MAC_backup[IQK_MAC_REG_NUM];
u32 IQK_BB_backup_recover[9];
u32 IQK_BB_backup[IQK_BB_REG_NUM];
u32 tx_iqc_8723b[2][3][2]; /* { {S1: 0xc94, 0xc80, 0xc4c} , {S0: 0xc9c, 0xc88, 0xc4c}} */
u32 rx_iqc_8723b[2][2][2]; /* { {S1: 0xc14, 0xca0} , {S0: 0xc14, 0xca0}} */
u32 tx_iqc_8703b[3][2]; /* { {S1: 0xc94, 0xc80, 0xc4c} , {S0: 0xc9c, 0xc88, 0xc4c}}*/
u32 rx_iqc_8703b[2][2]; /* { {S1: 0xc14, 0xca0} , {S0: 0xc14, 0xca0}}*/
u32 tx_iqc_8723d[2][3][2]; /* { {S1: 0xc94, 0xc80, 0xc4c} , {S0: 0xc9c, 0xc88, 0xc4c}}*/
u32 rx_iqc_8723d[2][2][2]; /* { {S1: 0xc14, 0xca0} , {S0: 0xc14, 0xca0}}*/
/* JJ ADD 20161014 */
u32 tx_iqc_8710b[2][3][2]; /* { {S1: 0xc94, 0xc80, 0xc4c} , {S0: 0xc9c, 0xc88, 0xc4c}}*/
u32 rx_iqc_8710b[2][2][2]; /* { {S1: 0xc14, 0xca0} , {S0: 0xc14, 0xca0}}*/
u64 iqk_start_time;
u64 iqk_total_progressing_time;
u64 iqk_progressing_time;
u64 lck_progressing_time;
u32 lok_result;
u8 iqk_step;
u8 kcount;
u8 retry_count[4][2]; /* [4]: path ABCD, [2] TXK, RXK */
boolean is_mp_mode;
/* for APK */
u32 ap_koutput[2][2]; /* path A/B; output1_1a/output1_2a */
u8 is_ap_kdone;
u8 is_apk_thermal_meter_ignore;
/* DPK */
boolean is_dpk_fail;
u8 is_dp_done;
u8 is_dp_path_aok;
u8 is_dp_path_bok;
u32 tx_lok[2];
u32 dpk_tx_agc;
s32 dpk_gain;
u32 dpk_thermal[4];
s8 modify_tx_agc_value_ofdm;
s8 modify_tx_agc_value_cck;
/*Add by Yuchen for Kfree Phydm*/
u8 reg_rf_kfree_enable; /*for registry*/
u8 rf_kfree_enable; /*for efuse enable check*/
};
#endif

321
hal/phydm/halrf/halrf_psd.c Normal file
View File

@ -0,0 +1,321 @@
/******************************************************************************
*
* 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 files
//============================================================
#include "mp_precomp.h"
#include "phydm_precomp.h"
#if (DM_ODM_SUPPORT_TYPE & ODM_WIN)
#if 0
u32 _sqrt(u64 n)
{
u64 ans = 0, q = 0;
s64 i;
/*for (i = sizeof(n) * 8 - 2; i > -1; i = i - 2) {*/
for (i = 8 * 8 - 2; i > -1; i = i - 2) {
q = (q << 2) | ((n & (3 << i)) >> i);
if (q >= ((ans << 2) | 1))
{
q = q - ((ans << 2) | 1);
ans = (ans << 1) | 1;
}
else
ans = ans << 1;
}
DbgPrint("ans=0x%x\n", ans);
return (u32)ans;
}
#endif
u64 _sqrt(u64 x)
{
u64 i = 0;
u64 j = x / 2 + 1;
while (i <= j) {
u64 mid = (i + j) / 2;
u64 sq = mid * mid;
if (sq == x)
return mid;
else if (sq < x)
i = mid + 1;
else
j = mid - 1;
}
return j;
}
u32
halrf_get_psd_data(
struct dm_struct *dm,
u32 point
)
{
struct _hal_rf_ *rf = &(dm->rf_table);
struct _halrf_psd_data *psd = &(rf->halrf_psd_data);
u32 psd_val = 0, psd_reg, psd_report, psd_point, psd_start, i, delay_time;
#if (DEV_BUS_TYPE == RT_USB_INTERFACE) || (DEV_BUS_TYPE == RT_SDIO_INTERFACE)
if (psd->average == 0)
delay_time = 100;
else
delay_time = 0;
#else
if (psd->average == 0)
delay_time = 1000;
else
delay_time = 100;
#endif
if (dm->support_ic_type & (ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8814A | ODM_RTL8822B | ODM_RTL8821C)) {
psd_reg = 0x910;
psd_report = 0xf44;
} else {
psd_reg = 0x808;
psd_report = 0x8b4;
}
if (dm->support_ic_type & ODM_RTL8710B) {
psd_point = 0xeffffc00;
psd_start = 0x10000000;
} else {
psd_point = 0xffbffc00;
psd_start = 0x00400000;
}
psd_val = odm_get_bb_reg(dm, psd_reg, MASKDWORD);
psd_val &= psd_point;
psd_val |= point;
odm_set_bb_reg(dm, psd_reg, MASKDWORD, psd_val);
psd_val |= psd_start;
odm_set_bb_reg(dm, psd_reg, MASKDWORD, psd_val);
for (i = 0; i < delay_time; i++)
ODM_delay_us(1);
psd_val = odm_get_bb_reg(dm, psd_report, MASKDWORD);
if (dm->support_ic_type & (ODM_RTL8821C | ODM_RTL8710B)) {
psd_val &= MASKL3BYTES;
psd_val = psd_val / 32;
} else
psd_val &= MASKLWORD;
return psd_val;
}
void
halrf_psd(
struct dm_struct *dm,
u32 point,
u32 start_point,
u32 stop_point,
u32 average
)
{
struct _hal_rf_ *rf = &(dm->rf_table);
struct _halrf_psd_data *psd = &(rf->halrf_psd_data);
u32 i = 0, j = 0, k = 0;
u32 psd_reg, avg_org, point_temp, average_tmp;
u64 data_tatal = 0, data_temp[64] = {0};
psd->buf_size = 256;
if (average == 0)
average_tmp = 1;
else
average_tmp = average;
if (dm->support_ic_type & (ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8814A | ODM_RTL8822B | ODM_RTL8821C))
psd_reg = 0x910;
else
psd_reg = 0x808;
#if 0
dbg_print("[PSD]point=%d, start_point=%d, stop_point=%d, average=%d, average_tmp=%d, buf_size=%d\n",
point, start_point, stop_point, average, average_tmp, psd->buf_size);
#endif
for (i = 0; i < psd->buf_size; i++)
psd->psd_data[i] = 0;
if (dm->support_ic_type & ODM_RTL8710B)
avg_org = odm_get_bb_reg(dm, psd_reg, 0x30000);
else
avg_org = odm_get_bb_reg(dm, psd_reg, 0x3000);
if (average != 0)
{
if (dm->support_ic_type & ODM_RTL8710B)
odm_set_bb_reg(dm, psd_reg, 0x30000, 0x1);
else
odm_set_bb_reg(dm, psd_reg, 0x3000, 0x1);
}
#if 0
if (avg_temp == 0)
avg = 1;
else if (avg_temp == 1)
avg = 8;
else if (avg_temp == 2)
avg = 16;
else if (avg_temp == 3)
avg = 32;
#endif
i = start_point;
while (i < stop_point) {
data_tatal = 0;
if (i >= point)
point_temp = i - point;
else
point_temp = i;
for (k = 0; k < average_tmp; k++) {
data_temp[k] = halrf_get_psd_data(dm, point_temp);
data_tatal = data_tatal + (data_temp[k] * data_temp[k]);
#if 0
if ((k % 20) == 0)
dbg_print("\n ");
dbg_print("0x%x ", data_temp[k]);
#endif
}
/*dbg_print("\n");*/
data_tatal = ((data_tatal * 100) / average_tmp);
psd->psd_data[j] = (u32)_sqrt(data_tatal);
i++;
j++;
}
#if 0
for (i = 0; i < psd->buf_size; i++) {
if ((i % 20) == 0)
dbg_print("\n ");
dbg_print("0x%x ", psd->psd_data[i]);
}
dbg_print("\n\n");
#endif
if (dm->support_ic_type & ODM_RTL8710B)
odm_set_bb_reg(dm, psd_reg, 0x30000, avg_org);
else
odm_set_bb_reg(dm, psd_reg, 0x3000, avg_org);
}
enum rt_status
halrf_psd_init(
struct dm_struct *dm
)
{
enum rt_status ret_status = RT_STATUS_SUCCESS;
struct _hal_rf_ *rf = &(dm->rf_table);
struct _halrf_psd_data *psd = &(rf->halrf_psd_data);
if (psd->psd_progress)
ret_status = RT_STATUS_PENDING;
else {
psd->psd_progress = 1;
halrf_psd(dm, psd->point, psd->start_point, psd->stop_point, psd->average);
psd->psd_progress = 0;
}
return ret_status;
}
enum rt_status
halrf_psd_query(
struct dm_struct *dm,
u32 *outbuf,
u32 buf_size
)
{
enum rt_status ret_status = RT_STATUS_SUCCESS;
struct _hal_rf_ *rf = &(dm->rf_table);
struct _halrf_psd_data *psd = &(rf->halrf_psd_data);
if (psd->psd_progress)
ret_status = RT_STATUS_PENDING;
else
PlatformMoveMemory(outbuf, psd->psd_data, 0x400);
return ret_status;
}
enum rt_status
halrf_psd_init_query(
struct dm_struct *dm,
u32 *outbuf,
u32 point,
u32 start_point,
u32 stop_point,
u32 average,
u32 buf_size
)
{
enum rt_status ret_status = RT_STATUS_SUCCESS;
struct _hal_rf_ *rf = &(dm->rf_table);
struct _halrf_psd_data *psd = &(rf->halrf_psd_data);
psd->point = point;
psd->start_point = start_point;
psd->stop_point = stop_point;
psd->average = average;
if (psd->psd_progress)
ret_status = RT_STATUS_PENDING;
else {
psd->psd_progress = 1;
halrf_psd(dm, psd->point, psd->start_point, psd->stop_point, psd->average);
PlatformMoveMemory(outbuf, psd->psd_data, 0x400);
psd->psd_progress = 0;
}
return ret_status;
}
#endif /*#if (DM_ODM_SUPPORT_TYPE & ODM_WIN)*/

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 __HALRF_PSD_H__
#define __HALRF_PSD_H__
#if (DM_ODM_SUPPORT_TYPE & ODM_WIN)
struct _halrf_psd_data {
u32 point;
u32 start_point;
u32 stop_point;
u32 average;
u32 buf_size;
u32 psd_data[256];
u32 psd_progress;
};
enum rt_status
halrf_psd_init (
struct dm_struct *dm
);
enum rt_status
halrf_psd_query (
struct dm_struct *dm,
u32 *outbuf,
u32 buf_size
);
enum rt_status
halrf_psd_init_query(
struct dm_struct *dm,
u32 *outbuf,
u32 point,
u32 start_point,
u32 stop_point,
u32 average,
u32 buf_size
);
#endif /*#if (DM_ODM_SUPPORT_TYPE & ODM_WIN)*/
#endif /*#ifndef __HALRF_PSD_H__*/

View File

@ -0,0 +1,303 @@
/******************************************************************************
*
* 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 full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "mp_precomp.h"
#include "phydm_precomp.h"
void odm_bub_sort(pu4Byte data, u4Byte n)
{
int i, j, temp, sp;
for (i = n - 1;i >= 0;i--) {
sp = 1;
for (j = 0;j < i;j++) {
if (data[j] < data[j + 1]) {
temp = data[j];
data[j] = data[j + 1];
data[j + 1] = temp;
sp = 0;
}
}
if (sp == 1)
break;
}
}
#if (RTL8197F_SUPPORT == 1)
u4Byte
odm_tx_gain_gap_psd_8197f(
void *dm_void,
u1Byte rf_path,
u4Byte rf56
)
{
PDM_ODM_T dm = (PDM_ODM_T)dm_void;
u1Byte i, j;
u4Byte psd_vaule[5], psd_avg_time = 5, psd_vaule_temp;
u4Byte iqk_ctl_addr[2][6] = {{0xe30, 0xe34, 0xe50, 0xe54, 0xe38, 0xe3c},
{0xe50, 0xe54, 0xe30, 0xe34, 0xe58, 0xe5c}};
u4Byte psd_finish_bit[2] = {0x04000000, 0x20000000};
u4Byte psd_fail_bit[2] = {0x08000000, 0x40000000};
u4Byte psd_cntl_value[2][2] = {{0x38008c1c, 0x10008c1c},
{0x38008c2c, 0x10008c2c}};
u4Byte psd_report_addr[2] = {0xea0, 0xec0};
odm_set_rf_reg(dm, rf_path, 0xdf, bRFRegOffsetMask, 0x00e02);
ODM_delay_us(100);
odm_set_bb_reg(dm, 0xe28, 0xffffffff, 0x0);
odm_set_rf_reg(dm, rf_path, 0x56, 0xfff, rf56);
while(rf56 != (odm_get_rf_reg(dm, rf_path, 0x56, 0xfff)))
odm_set_rf_reg(dm, rf_path, 0x56, 0xfff, rf56);
odm_set_bb_reg(dm, 0xd94, 0xffffffff, 0x44FFBB44);
odm_set_bb_reg(dm, 0xe70, 0xffffffff, 0x00400040);
odm_set_bb_reg(dm, 0xc04, 0xffffffff, 0x6f005403);
odm_set_bb_reg(dm, 0xc08, 0xffffffff, 0x000804e4);
odm_set_bb_reg(dm, 0x874, 0xffffffff, 0x04203400);
odm_set_bb_reg(dm, 0xe28, 0xffffffff, 0x80800000);
odm_set_bb_reg(dm, iqk_ctl_addr[rf_path][0], 0xffffffff, psd_cntl_value[rf_path][0]);
odm_set_bb_reg(dm, iqk_ctl_addr[rf_path][1], 0xffffffff, psd_cntl_value[rf_path][1]);
odm_set_bb_reg(dm, iqk_ctl_addr[rf_path][2], 0xffffffff, psd_cntl_value[rf_path][0]);
odm_set_bb_reg(dm, iqk_ctl_addr[rf_path][3], 0xffffffff, psd_cntl_value[rf_path][0]);
odm_set_bb_reg(dm, iqk_ctl_addr[rf_path][4], 0xffffffff, 0x8215001F);
odm_set_bb_reg(dm, iqk_ctl_addr[rf_path][5], 0xffffffff, 0x2805001F);
odm_set_bb_reg(dm, 0xe40, 0xffffffff, 0x81007C00);
odm_set_bb_reg(dm, 0xe44, 0xffffffff, 0x81004800);
odm_set_bb_reg(dm, 0xe4c, 0xffffffff, 0x0046a8d0);
for (i = 0; i < psd_avg_time; i++) {
for(j = 0; j < 1000 ; j++) {
odm_set_bb_reg(dm, 0xe48, 0xffffffff, 0xfa005800);
odm_set_bb_reg(dm, 0xe48, 0xffffffff, 0xf8005800);
while(!odm_get_bb_reg(dm, 0xeac, psd_finish_bit[rf_path])); /*wait finish bit*/
if (!odm_get_bb_reg(dm, 0xeac, psd_fail_bit[rf_path])) { /*check fail bit*/
psd_vaule[i] = odm_get_bb_reg(dm, psd_report_addr[rf_path], 0xffffffff);
if (psd_vaule[i] > 0xffff)
break;
}
}
PHYDM_DBG(dm, ODM_COMP_CALIBRATION,"[TGGC] rf0=0x%x rf56=0x%x rf56_reg=0x%x time=%d psd_vaule=0x%x\n",
odm_get_rf_reg(dm, rf_path, 0x0, 0xff),
rf56, odm_get_rf_reg(dm, rf_path, 0x56, 0xfff), j, psd_vaule[i]);
}
odm_bub_sort(psd_vaule, psd_avg_time);
psd_vaule_temp = psd_vaule[(UINT)(psd_avg_time / 2)];
odm_set_bb_reg(dm, 0xd94, 0xffffffff, 0x44BBBB44);
odm_set_bb_reg(dm, 0xe70, 0xffffffff, 0x80408040);
odm_set_bb_reg(dm, 0xc04, 0xffffffff, 0x6f005433);
odm_set_bb_reg(dm, 0xc08, 0xffffffff, 0x000004e4);
odm_set_bb_reg(dm, 0x874, 0xffffffff, 0x04003400);
odm_set_bb_reg(dm, 0xe28, 0xffffffff, 0x00000000);
PHYDM_DBG(dm, ODM_COMP_CALIBRATION,"[TGGC] rf0=0x%x rf56=0x%x rf56_reg=0x%x psd_vaule_temp=0x%x\n",
odm_get_rf_reg(dm, rf_path, 0x0, 0xff),
rf56, odm_get_rf_reg(dm, rf_path, 0x56, 0xfff), psd_vaule_temp);
odm_set_rf_reg(dm, rf_path, 0xdf, bRFRegOffsetMask, 0x00602);
return psd_vaule_temp;
}
void
odm_tx_gain_gap_calibration_8197f(
void *dm_void
)
{
PDM_ODM_T dm = (PDM_ODM_T)dm_void;
u1Byte rf_path, rf0_idx, rf0_idx_current, rf0_idx_next, i, delta_gain_retry = 3;
s1Byte delta_gain_gap_pre, delta_gain_gap[2][11];
u4Byte rf56_current, rf56_next, psd_value_current, psd_value_next;
u4Byte psd_gap, rf56_current_temp[2][11];
s4Byte rf33[2][11];
memset(rf33, 0x0, sizeof(rf33));
for (rf_path = RF_PATH_A; rf_path <= RF_PATH_B; rf_path++) {
if (rf_path == RF_PATH_A)
odm_set_bb_reg(dm, 0x88c, (BIT(21) | BIT(20)), 0x3); /*disable 3-wire*/
else if (rf_path == RF_PATH_B)
odm_set_bb_reg(dm, 0x88c, (BIT(23) | BIT(22)), 0x3); /*disable 3-wire*/
ODM_delay_us(100);
for (rf0_idx = 1; rf0_idx <= 10; rf0_idx++) {
rf0_idx_current = 3 * (rf0_idx - 1) + 1;
odm_set_rf_reg(dm, rf_path, 0x0, 0xff, rf0_idx_current);
ODM_delay_us(100);
rf56_current_temp[rf_path][rf0_idx] = odm_get_rf_reg(dm, rf_path, 0x56, 0xfff);
rf56_current = rf56_current_temp[rf_path][rf0_idx];
rf0_idx_next = 3 * rf0_idx + 1;
odm_set_rf_reg(dm, rf_path, 0x0, 0xff, rf0_idx_next);
ODM_delay_us(100);
rf56_next= odm_get_rf_reg(dm, rf_path, 0x56, 0xfff);
PHYDM_DBG(dm, ODM_COMP_CALIBRATION,"[TGGC] rf56_current[%d][%d]=0x%x rf56_next[%d][%d]=0x%x\n",
rf_path, rf0_idx, rf56_current, rf_path, rf0_idx, rf56_next);
if ((rf56_current >> 5) == (rf56_next >> 5)) {
delta_gain_gap[rf_path][rf0_idx] = 0;
PHYDM_DBG(dm, ODM_COMP_CALIBRATION,"[TGGC] rf56_current[11:5] == rf56_next[%d][%d][11:5]=0x%x delta_gain_gap[%d][%d]=%d\n",
rf_path, rf0_idx, (rf56_next >> 5), rf_path, rf0_idx, delta_gain_gap[rf_path][rf0_idx]);
continue;
}
PHYDM_DBG(dm, ODM_COMP_CALIBRATION,"[TGGC] rf56_current[%d][%d][11:5]=0x%x != rf56_next[%d][%d][11:5]=0x%x\n",
rf_path, rf0_idx, (rf56_current >> 5), rf_path, rf0_idx, (rf56_next >> 5));
for (i = 0; i < delta_gain_retry; i++) {
psd_value_current = odm_tx_gain_gap_psd_8197f(dm, rf_path, rf56_current);
psd_value_next = odm_tx_gain_gap_psd_8197f(dm, rf_path, rf56_next - 2);
psd_gap = psd_value_next / (psd_value_current / 1000);
#if 0
if (psd_gap > 1413)
delta_gain_gap[rf_path][rf0_idx] = 1;
else if (psd_gap > 1122)
delta_gain_gap[rf_path][rf0_idx] = 0;
else
delta_gain_gap[rf_path][rf0_idx] = -1;
#endif
if (psd_gap > 1445)
delta_gain_gap[rf_path][rf0_idx] = 1;
else if (psd_gap > 1096)
delta_gain_gap[rf_path][rf0_idx] = 0;
else
delta_gain_gap[rf_path][rf0_idx] = -1;
if (i == 0)
delta_gain_gap_pre = delta_gain_gap[rf_path][rf0_idx];
PHYDM_DBG(dm, ODM_COMP_CALIBRATION,"[TGGC] psd_value_current=0x%x psd_value_next=0x%x psd_value_next/psd_value_current=%d delta_gain_gap[%d][%d]=%d\n",
psd_value_current, psd_value_next, psd_gap, rf_path, rf0_idx, delta_gain_gap[rf_path][rf0_idx]);
if ((i == 0) && (delta_gain_gap[rf_path][rf0_idx] == 0))
break;
if (delta_gain_gap_pre != delta_gain_gap[rf_path][rf0_idx]) {
delta_gain_gap[rf_path][rf0_idx] = 0;
PHYDM_DBG(dm, ODM_COMP_CALIBRATION,"[TGGC] delta_gain_gap_pre(%d) != delta_gain_gap[%d][%d](%d) time=%d\n",
delta_gain_gap_pre, rf_path, rf0_idx, delta_gain_gap[rf_path][rf0_idx], i);
break;
} else {
PHYDM_DBG(dm, ODM_COMP_CALIBRATION,"[TGGC] delta_gain_gap_pre(%d) == delta_gain_gap[%d][%d](%d) time=%d\n",
delta_gain_gap_pre, rf_path, rf0_idx, delta_gain_gap[rf_path][rf0_idx], i);
}
}
}
if (rf_path == RF_PATH_A)
odm_set_bb_reg(dm, 0x88c, (BIT(21) | BIT(20)), 0x0); /*enable 3-wire*/
else if (rf_path == RF_PATH_B)
odm_set_bb_reg(dm, 0x88c, (BIT(23) | BIT(22)), 0x0); /*enable 3-wire*/
ODM_delay_us(100);
}
/*odm_set_bb_reg(dm, 0x88c, (BIT(23) | BIT(22) | BIT(21) | BIT(20)), 0x0);*/ /*enable 3-wire*/
for (rf_path = RF_PATH_A; rf_path <= RF_PATH_B; rf_path++) {
odm_set_rf_reg(dm, rf_path, 0xef, bRFRegOffsetMask, 0x00100);
for (rf0_idx = 1; rf0_idx <= 10; rf0_idx++) {
rf33[rf_path][rf0_idx] = rf33[rf_path][rf0_idx] + (rf56_current_temp[rf_path][rf0_idx] & 0x1f);
for (i = rf0_idx; i <= 10; i++)
rf33[rf_path][rf0_idx] = rf33[rf_path][rf0_idx] + delta_gain_gap[rf_path][i];
if (rf33[rf_path][rf0_idx] >= 0x1d)
rf33[rf_path][rf0_idx] = 0x1d;
else if (rf33[rf_path][rf0_idx] <= 0x2)
rf33[rf_path][rf0_idx] = 0x2;
rf33[rf_path][rf0_idx] = rf33[rf_path][rf0_idx] + ((rf0_idx - 1) * 0x4000) + (rf56_current_temp[rf_path][rf0_idx] & 0xfffe0);
PHYDM_DBG(dm, ODM_COMP_CALIBRATION,"[TGGC] rf56[%d][%d]=0x%05x rf33[%d][%d]=0x%05x\n", rf_path, rf0_idx, rf56_current_temp[rf_path][rf0_idx], rf_path, rf0_idx, rf33[rf_path][rf0_idx]);
odm_set_rf_reg(dm, rf_path, 0x33, bRFRegOffsetMask, rf33[rf_path][rf0_idx]);
}
odm_set_rf_reg(dm, rf_path, 0xef, bRFRegOffsetMask, 0x00000);
}
}
#endif
void
odm_tx_gain_gap_calibration(
void *dm_void
)
{
PDM_ODM_T dm = (PDM_ODM_T)dm_void;
#if (RTL8197F_SUPPORT == 1)
if (dm->SupportICType & ODM_RTL8197F)
odm_tx_gain_gap_calibration_8197f(dm_void);
#endif
}

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