Fixed MTP to work with TWRP

This commit is contained in:
awab228 2018-06-19 23:16:04 +02:00
commit f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions

View file

@ -0,0 +1,154 @@
menuconfig RTL_CARDS
tristate "Realtek rtlwifi family of devices"
depends on MAC80211 && (PCI || USB)
default y
---help---
This option will enable support for the Realtek mac80211-based
wireless drivers. Drivers rtl8192ce, rtl8192cu, rtl8192se, rtl8192de,
rtl8723ae, rtl8723be, rtl8188ee, rtl8192ee, and rtl8821ae share
some common code.
if RTL_CARDS
config RTL8192CE
tristate "Realtek RTL8192CE/RTL8188CE Wireless Network Adapter"
depends on PCI
select RTL8192C_COMMON
select RTLWIFI
select RTLWIFI_PCI
---help---
This is the driver for Realtek RTL8192CE/RTL8188CE 802.11n PCIe
wireless network adapters.
If you choose to build it as a module, it will be called rtl8192ce
config RTL8192SE
tristate "Realtek RTL8192SE/RTL8191SE PCIe Wireless Network Adapter"
depends on PCI
select RTLWIFI
select RTLWIFI_PCI
---help---
This is the driver for Realtek RTL8192SE/RTL8191SE 802.11n PCIe
wireless network adapters.
If you choose to build it as a module, it will be called rtl8192se
config RTL8192DE
tristate "Realtek RTL8192DE/RTL8188DE PCIe Wireless Network Adapter"
depends on PCI
select RTLWIFI
select RTLWIFI_PCI
---help---
This is the driver for Realtek RTL8192DE/RTL8188DE 802.11n PCIe
wireless network adapters.
If you choose to build it as a module, it will be called rtl8192de
config RTL8723AE
tristate "Realtek RTL8723AE PCIe Wireless Network Adapter"
depends on PCI
select RTLWIFI
select RTLWIFI_PCI
select RTL8723_COMMON
select RTLBTCOEXIST
---help---
This is the driver for Realtek RTL8723AE 802.11n PCIe
wireless network adapters.
If you choose to build it as a module, it will be called rtl8723ae
config RTL8723BE
tristate "Realtek RTL8723BE PCIe Wireless Network Adapter"
depends on PCI
select RTLWIFI
select RTLWIFI_PCI
select RTL8723_COMMON
select RTLBTCOEXIST
---help---
This is the driver for Realtek RTL8723BE 802.11n PCIe
wireless network adapters.
If you choose to build it as a module, it will be called rtl8723be
config RTL8188EE
tristate "Realtek RTL8188EE Wireless Network Adapter"
depends on PCI
select RTLWIFI
select RTLWIFI_PCI
---help---
This is the driver for Realtek RTL8188EE 802.11n PCIe
wireless network adapters.
If you choose to build it as a module, it will be called rtl8188ee
config RTL8192EE
tristate "Realtek RTL8192EE Wireless Network Adapter"
depends on PCI
select RTLWIFI
select RTLWIFI_PCI
select RTLBTCOEXIST
---help---
This is the driver for Realtek RTL8192EE 802.11n PCIe
wireless network adapters.
If you choose to build it as a module, it will be called rtl8192ee
config RTL8821AE
tristate "Realtek RTL8821AE/RTL8812AE Wireless Network Adapter"
depends on PCI
select RTLWIFI
select RTLWIFI_PCI
select RTLBTCOEXIST
---help---
This is the driver for Realtek RTL8i821AE/RTL8812AE 802.11av PCIe
wireless network adapters.
If you choose to build it as a module, it will be called rtl8821ae
config RTL8192CU
tristate "Realtek RTL8192CU/RTL8188CU USB Wireless Network Adapter"
depends on USB
select RTLWIFI
select RTLWIFI_USB
select RTL8192C_COMMON
---help---
This is the driver for Realtek RTL8192CU/RTL8188CU 802.11n USB
wireless network adapters.
If you choose to build it as a module, it will be called rtl8192cu
config RTLWIFI
tristate
select FW_LOADER
config RTLWIFI_PCI
tristate
config RTLWIFI_USB
tristate
config RTLWIFI_DEBUG
bool "Debugging output for rtlwifi driver family"
depends on RTLWIFI
default y
---help---
To use the module option that sets the dynamic-debugging level for,
the front-end driver, this parameter must be "Y". For memory-limited
systems, choose "N". If in doubt, choose "Y".
config RTL8192C_COMMON
tristate
depends on RTL8192CE || RTL8192CU
default y
config RTL8723_COMMON
tristate
depends on RTL8723AE || RTL8723BE
default y
config RTLBTCOEXIST
tristate
depends on RTL8723AE || RTL8723BE || RTL8821AE || RTL8192EE
default y
endif

View file

@ -0,0 +1,34 @@
obj-$(CONFIG_RTLWIFI) += rtlwifi.o
rtlwifi-objs := \
base.o \
cam.o \
core.o \
debug.o \
efuse.o \
ps.o \
rc.o \
regd.o \
stats.o
rtl8192c_common-objs += \
obj-$(CONFIG_RTLWIFI_PCI) += rtl_pci.o
rtl_pci-objs := pci.o
obj-$(CONFIG_RTLWIFI_USB) += rtl_usb.o
rtl_usb-objs := usb.o
obj-$(CONFIG_RTL8192C_COMMON) += rtl8192c/
obj-$(CONFIG_RTL8192CE) += rtl8192ce/
obj-$(CONFIG_RTL8192CU) += rtl8192cu/
obj-$(CONFIG_RTL8192SE) += rtl8192se/
obj-$(CONFIG_RTL8192DE) += rtl8192de/
obj-$(CONFIG_RTL8723AE) += rtl8723ae/
obj-$(CONFIG_RTL8723BE) += rtl8723be/
obj-$(CONFIG_RTL8188EE) += rtl8188ee/
obj-$(CONFIG_RTLBTCOEXIST) += btcoexist/
obj-$(CONFIG_RTL8723_COMMON) += rtl8723com/
obj-$(CONFIG_RTL8821AE) += rtl8821ae/
obj-$(CONFIG_RTL8192EE) += rtl8192ee/
ccflags-y += -D__CHECK_ENDIAN__

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,162 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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 __RTL_BASE_H__
#define __RTL_BASE_H__
enum ap_peer {
PEER_UNKNOWN = 0,
PEER_RTL = 1,
PEER_RTL_92SE = 2,
PEER_BROAD = 3,
PEER_RAL = 4,
PEER_ATH = 5,
PEER_CISCO = 6,
PEER_MARV = 7,
PEER_AIRGO = 9,
PEER_MAX = 10,
};
#define RTL_DUMMY_OFFSET 0
#define RTL_DUMMY_UNIT 8
#define RTL_TX_DUMMY_SIZE (RTL_DUMMY_OFFSET * RTL_DUMMY_UNIT)
#define RTL_TX_DESC_SIZE 32
#define RTL_TX_HEADER_SIZE (RTL_TX_DESC_SIZE + RTL_TX_DUMMY_SIZE)
#define HT_AMSDU_SIZE_4K 3839
#define HT_AMSDU_SIZE_8K 7935
#define MAX_BIT_RATE_40MHZ_MCS15 300 /* Mbps */
#define MAX_BIT_RATE_40MHZ_MCS7 150 /* Mbps */
#define MAX_BIT_RATE_SHORT_GI_2NSS_80MHZ_MCS9 867 /* Mbps */
#define MAX_BIT_RATE_SHORT_GI_2NSS_80MHZ_MCS7 650 /* Mbps */
#define MAX_BIT_RATE_LONG_GI_2NSS_80MHZ_MCS9 780 /* Mbps */
#define MAX_BIT_RATE_LONG_GI_2NSS_80MHZ_MCS7 585 /* Mbps */
#define MAX_BIT_RATE_SHORT_GI_1NSS_80MHZ_MCS9 434 /* Mbps */
#define MAX_BIT_RATE_SHORT_GI_1NSS_80MHZ_MCS7 325 /* Mbps */
#define MAX_BIT_RATE_LONG_GI_1NSS_80MHZ_MCS9 390 /* Mbps */
#define MAX_BIT_RATE_LONG_GI_1NSS_80MHZ_MCS7 293 /* Mbps */
#define RTL_RATE_COUNT_LEGACY 12
#define RTL_CHANNEL_COUNT 14
#define FRAME_OFFSET_FRAME_CONTROL 0
#define FRAME_OFFSET_DURATION 2
#define FRAME_OFFSET_ADDRESS1 4
#define FRAME_OFFSET_ADDRESS2 10
#define FRAME_OFFSET_ADDRESS3 16
#define FRAME_OFFSET_SEQUENCE 22
#define FRAME_OFFSET_ADDRESS4 24
#define SET_80211_HDR_FRAME_CONTROL(_hdr, _val) \
WRITEEF2BYTE(_hdr, _val)
#define SET_80211_HDR_TYPE_AND_SUBTYPE(_hdr, _val) \
WRITEEF1BYTE(_hdr, _val)
#define SET_80211_HDR_PWR_MGNT(_hdr, _val) \
SET_BITS_TO_LE_2BYTE(_hdr, 12, 1, _val)
#define SET_80211_HDR_TO_DS(_hdr, _val) \
SET_BITS_TO_LE_2BYTE(_hdr, 8, 1, _val)
#define SET_80211_PS_POLL_AID(_hdr, _val) \
(*(u16 *)((u8 *)(_hdr) + 2) = _val)
#define SET_80211_PS_POLL_BSSID(_hdr, _val) \
ether_addr_copy(((u8 *)(_hdr)) + 4, (u8 *)(_val))
#define SET_80211_PS_POLL_TA(_hdr, _val) \
ether_addr_copy(((u8 *)(_hdr))+10, (u8 *)(_val))
#define SET_80211_HDR_DURATION(_hdr, _val) \
(*(u16 *)((u8 *)(_hdr) + FRAME_OFFSET_DURATION) = le16_to_cpu(_val))
#define SET_80211_HDR_ADDRESS1(_hdr, _val) \
CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS1, (u8 *)(_val))
#define SET_80211_HDR_ADDRESS2(_hdr, _val) \
CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS2, (u8 *)(_val))
#define SET_80211_HDR_ADDRESS3(_hdr, _val) \
CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS3, (u8 *)(_val))
#define SET_80211_HDR_FRAGMENT_SEQUENCE(_hdr, _val) \
WRITEEF2BYTE((u8 *)(_hdr)+FRAME_OFFSET_SEQUENCE, _val)
#define SET_BEACON_PROBE_RSP_TIME_STAMP_LOW(__phdr, __val) \
WRITEEF4BYTE(((u8 *)(__phdr)) + 24, __val)
#define SET_BEACON_PROBE_RSP_TIME_STAMP_HIGH(__phdr, __val) \
WRITEEF4BYTE(((u8 *)(__phdr)) + 28, __val)
#define SET_BEACON_PROBE_RSP_BEACON_INTERVAL(__phdr, __val) \
WRITEEF2BYTE(((u8 *)(__phdr)) + 32, __val)
#define GET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr) \
READEF2BYTE(((u8 *)(__phdr)) + 34)
#define SET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, __val) \
WRITEEF2BYTE(((u8 *)(__phdr)) + 34, __val)
#define MASK_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, __val) \
SET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, \
(GET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr) & (~(__val))))
int rtl_init_core(struct ieee80211_hw *hw);
void rtl_deinit_core(struct ieee80211_hw *hw);
void rtl_init_rx_config(struct ieee80211_hw *hw);
void rtl_init_rfkill(struct ieee80211_hw *hw);
void rtl_deinit_rfkill(struct ieee80211_hw *hw);
void rtl_watch_dog_timer_callback(unsigned long data);
void rtl_deinit_deferred_work(struct ieee80211_hw *hw);
bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx);
int rtlwifi_rate_mapping(struct ieee80211_hw *hw,
bool isht, u8 desc_rate, bool first_ampdu);
bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb);
u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx);
void rtl_beacon_statistic(struct ieee80211_hw *hw, struct sk_buff *skb);
void rtl_watch_dog_timer_callback(unsigned long data);
int rtl_tx_agg_start(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, u16 tid, u16 *ssn);
int rtl_tx_agg_stop(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, u16 tid);
int rtl_tx_agg_oper(struct ieee80211_hw *hw,
struct ieee80211_sta *sta, u16 tid);
int rtl_rx_agg_start(struct ieee80211_hw *hw,
struct ieee80211_sta *sta, u16 tid);
int rtl_rx_agg_stop(struct ieee80211_hw *hw,
struct ieee80211_sta *sta, u16 tid);
void rtl_watchdog_wq_callback(void *data);
void rtl_fwevt_wq_callback(void *data);
void rtl_get_tcb_desc(struct ieee80211_hw *hw,
struct ieee80211_tx_info *info,
struct ieee80211_sta *sta,
struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc);
int rtl_send_smps_action(struct ieee80211_hw *hw,
struct ieee80211_sta *sta,
enum ieee80211_smps_mode smps);
u8 *rtl_find_ie(u8 *data, unsigned int len, u8 ie);
void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len);
u8 rtl_tid_to_ac(u8 tid);
extern struct attribute_group rtl_attribute_group;
void rtl_easy_concurrent_retrytimer_callback(unsigned long data);
extern struct rtl_global_var rtl_global_var;
void rtl_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation);
#endif

View file

@ -0,0 +1,7 @@
btcoexist-objs := halbtc8723b2ant.o \
halbtcoutsrc.o \
rtl_btc.o
obj-$(CONFIG_RTLBTCOEXIST) += btcoexist.o
ccflags-y += -D__CHECK_ENDIAN__

View file

@ -0,0 +1,81 @@
/******************************************************************************
*
* 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.
*
* 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 __HALBT_PRECOMP_H__
#define __HALBT_PRECOMP_H__
/*************************************************************
* include files
*************************************************************/
#include "../wifi.h"
#include "../efuse.h"
#include "../base.h"
#include "../regd.h"
#include "../cam.h"
#include "../ps.h"
#include "../pci.h"
#include "halbtcoutsrc.h"
#include "halbtc8192e2ant.h"
#include "halbtc8723b1ant.h"
#include "halbtc8723b2ant.h"
#include "halbtc8821a2ant.h"
#include "halbtc8821a1ant.h"
#define GetDefaultAdapter(padapter) padapter
#define BIT0 0x00000001
#define BIT1 0x00000002
#define BIT2 0x00000004
#define BIT3 0x00000008
#define BIT4 0x00000010
#define BIT5 0x00000020
#define BIT6 0x00000040
#define BIT7 0x00000080
#define BIT8 0x00000100
#define BIT9 0x00000200
#define BIT10 0x00000400
#define BIT11 0x00000800
#define BIT12 0x00001000
#define BIT13 0x00002000
#define BIT14 0x00004000
#define BIT15 0x00008000
#define BIT16 0x00010000
#define BIT17 0x00020000
#define BIT18 0x00040000
#define BIT19 0x00080000
#define BIT20 0x00100000
#define BIT21 0x00200000
#define BIT22 0x00400000
#define BIT23 0x00800000
#define BIT24 0x01000000
#define BIT25 0x02000000
#define BIT26 0x04000000
#define BIT27 0x08000000
#define BIT28 0x10000000
#define BIT29 0x20000000
#define BIT30 0x40000000
#define BIT31 0x80000000
#endif /* __HALBT_PRECOMP_H__ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,185 @@
/******************************************************************************
*
* Copyright(c) 2012 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>
*
*****************************************************************************/
/*****************************************************************
* The following is for 8192E 2Ant BT Co-exist definition
*****************************************************************/
#define BT_AUTO_REPORT_ONLY_8192E_2ANT 0
#define BT_INFO_8192E_2ANT_B_FTP BIT7
#define BT_INFO_8192E_2ANT_B_A2DP BIT6
#define BT_INFO_8192E_2ANT_B_HID BIT5
#define BT_INFO_8192E_2ANT_B_SCO_BUSY BIT4
#define BT_INFO_8192E_2ANT_B_ACL_BUSY BIT3
#define BT_INFO_8192E_2ANT_B_INQ_PAGE BIT2
#define BT_INFO_8192E_2ANT_B_SCO_ESCO BIT1
#define BT_INFO_8192E_2ANT_B_CONNECTION BIT0
#define BTC_RSSI_COEX_THRESH_TOL_8192E_2ANT 2
enum bt_info_src_8192e_2ant {
BT_INFO_SRC_8192E_2ANT_WIFI_FW = 0x0,
BT_INFO_SRC_8192E_2ANT_BT_RSP = 0x1,
BT_INFO_SRC_8192E_2ANT_BT_ACTIVE_SEND = 0x2,
BT_INFO_SRC_8192E_2ANT_MAX
};
enum bt_8192e_2ant_bt_status {
BT_8192E_2ANT_BT_STATUS_NON_CONNECTED_IDLE = 0x0,
BT_8192E_2ANT_BT_STATUS_CONNECTED_IDLE = 0x1,
BT_8192E_2ANT_BT_STATUS_INQ_PAGE = 0x2,
BT_8192E_2ANT_BT_STATUS_ACL_BUSY = 0x3,
BT_8192E_2ANT_BT_STATUS_SCO_BUSY = 0x4,
BT_8192E_2ANT_BT_STATUS_ACL_SCO_BUSY = 0x5,
BT_8192E_2ANT_BT_STATUS_MAX
};
enum bt_8192e_2ant_coex_algo {
BT_8192E_2ANT_COEX_ALGO_UNDEFINED = 0x0,
BT_8192E_2ANT_COEX_ALGO_SCO = 0x1,
BT_8192E_2ANT_COEX_ALGO_SCO_PAN = 0x2,
BT_8192E_2ANT_COEX_ALGO_HID = 0x3,
BT_8192E_2ANT_COEX_ALGO_A2DP = 0x4,
BT_8192E_2ANT_COEX_ALGO_A2DP_PANHS = 0x5,
BT_8192E_2ANT_COEX_ALGO_PANEDR = 0x6,
BT_8192E_2ANT_COEX_ALGO_PANHS = 0x7,
BT_8192E_2ANT_COEX_ALGO_PANEDR_A2DP = 0x8,
BT_8192E_2ANT_COEX_ALGO_PANEDR_HID = 0x9,
BT_8192E_2ANT_COEX_ALGO_HID_A2DP_PANEDR = 0xa,
BT_8192E_2ANT_COEX_ALGO_HID_A2DP = 0xb,
BT_8192E_2ANT_COEX_ALGO_MAX = 0xc
};
struct coex_dm_8192e_2ant {
/* fw mechanism */
u8 pre_dec_bt_pwr;
u8 cur_dec_bt_pwr;
u8 pre_fw_dac_swing_lvl;
u8 cur_fw_dac_swing_lvl;
bool cur_ignore_wlan_act;
bool pre_ignore_wlan_act;
u8 pre_ps_tdma;
u8 cur_ps_tdma;
u8 ps_tdma_para[5];
u8 tdma_adj_type;
bool reset_tdma_adjust;
bool auto_tdma_adjust;
bool pre_ps_tdma_on;
bool cur_ps_tdma_on;
bool pre_bt_auto_report;
bool cur_bt_auto_report;
/* sw mechanism */
bool pre_rf_rx_lpf_shrink;
bool cur_rf_rx_lpf_shrink;
u32 bt_rf0x1e_backup;
bool pre_low_penalty_ra;
bool cur_low_penalty_ra;
bool pre_dac_swing_on;
u32 pre_dac_swing_lvl;
bool cur_dac_swing_on;
u32 cur_dac_swing_lvl;
bool pre_adc_back_off;
bool cur_adc_back_off;
bool pre_agc_table_en;
bool cur_agc_table_en;
u32 pre_val0x6c0;
u32 cur_val0x6c0;
u32 pre_val0x6c4;
u32 cur_val0x6c4;
u32 pre_val0x6c8;
u32 cur_val0x6c8;
u8 pre_val0x6cc;
u8 cur_val0x6cc;
bool limited_dig;
u32 backup_arfr_cnt1; /* Auto Rate Fallback Retry cnt */
u32 backup_arfr_cnt2; /* Auto Rate Fallback Retry cnt */
u16 backup_retrylimit;
u8 backup_ampdu_maxtime;
/* algorithm related */
u8 pre_algorithm;
u8 cur_algorithm;
u8 bt_status;
u8 wifi_chnl_info[3];
u8 pre_sstype;
u8 cur_sstype;
u32 prera_mask;
u32 curra_mask;
u8 curra_masktype;
u8 pre_arfrtype;
u8 cur_arfrtype;
u8 pre_retrylimit_type;
u8 cur_retrylimit_type;
u8 pre_ampdutime_type;
u8 cur_ampdutime_type;
};
struct coex_sta_8192e_2ant {
bool bt_link_exist;
bool sco_exist;
bool a2dp_exist;
bool hid_exist;
bool pan_exist;
bool under_lps;
bool under_ips;
u32 high_priority_tx;
u32 high_priority_rx;
u32 low_priority_tx;
u32 low_priority_rx;
u8 bt_rssi;
u8 pre_bt_rssi_state;
u8 pre_wifi_rssi_state[4];
bool c2h_bt_info_req_sent;
u8 bt_info_c2h[BT_INFO_SRC_8192E_2ANT_MAX][10];
u32 bt_info_c2h_cnt[BT_INFO_SRC_8192E_2ANT_MAX];
bool c2h_bt_inquiry_page;
u8 bt_retry_cnt;
u8 bt_info_ext;
};
/****************************************************************
* The following is interface which will notify coex module.
****************************************************************/
void ex_halbtc8192e2ant_init_hwconfig(struct btc_coexist *btcoexist);
void ex_halbtc8192e2ant_init_coex_dm(struct btc_coexist *btcoexist);
void ex_halbtc8192e2ant_ips_notify(struct btc_coexist *btcoexist, u8 type);
void ex_halbtc8192e2ant_lps_notify(struct btc_coexist *btcoexist, u8 type);
void ex_halbtc8192e2ant_scan_notify(struct btc_coexist *btcoexist, u8 type);
void ex_halbtc8192e2ant_connect_notify(struct btc_coexist *btcoexist, u8 type);
void ex_halbtc8192e2ant_media_status_notify(struct btc_coexist *btcoexist,
u8 type);
void ex_halbtc8192e2ant_special_packet_notify(struct btc_coexist *btcoexist,
u8 type);
void ex_halbtc8192e2ant_bt_info_notify(struct btc_coexist *btcoexist,
u8 *tmpbuf, u8 length);
void ex_halbtc8192e2ant_stack_operation_notify(struct btc_coexist *btcoexist,
u8 type);
void ex_halbtc8192e2ant_halt_notify(struct btc_coexist *btcoexist);
void ex_halbtc8192e2ant_periodical(struct btc_coexist *btcoexist);
void ex_halbtc8192e2ant_display_coex_info(struct btc_coexist *btcoexist);

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,184 @@
/******************************************************************************
*
* Copyright(c) 2012 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>
*
*****************************************************************************/
/**********************************************************************
* The following is for 8723B 1ANT BT Co-exist definition
**********************************************************************/
#define BT_AUTO_REPORT_ONLY_8723B_1ANT 1
#define BT_INFO_8723B_1ANT_B_FTP BIT7
#define BT_INFO_8723B_1ANT_B_A2DP BIT6
#define BT_INFO_8723B_1ANT_B_HID BIT5
#define BT_INFO_8723B_1ANT_B_SCO_BUSY BIT4
#define BT_INFO_8723B_1ANT_B_ACL_BUSY BIT3
#define BT_INFO_8723B_1ANT_B_INQ_PAGE BIT2
#define BT_INFO_8723B_1ANT_B_SCO_ESCO BIT1
#define BT_INFO_8723B_1ANT_B_CONNECTION BIT0
#define BT_INFO_8723B_1ANT_A2DP_BASIC_RATE(_BT_INFO_EXT_) \
(((_BT_INFO_EXT_&BIT0)) ? true : false)
#define BTC_RSSI_COEX_THRESH_TOL_8723B_1ANT 2
enum _BT_INFO_SRC_8723B_1ANT {
BT_INFO_SRC_8723B_1ANT_WIFI_FW = 0x0,
BT_INFO_SRC_8723B_1ANT_BT_RSP = 0x1,
BT_INFO_SRC_8723B_1ANT_BT_ACTIVE_SEND = 0x2,
BT_INFO_SRC_8723B_1ANT_MAX
};
enum _BT_8723B_1ANT_BT_STATUS {
BT_8723B_1ANT_BT_STATUS_NON_CONNECTED_IDLE = 0x0,
BT_8723B_1ANT_BT_STATUS_CONNECTED_IDLE = 0x1,
BT_8723B_1ANT_BT_STATUS_INQ_PAGE = 0x2,
BT_8723B_1ANT_BT_STATUS_ACL_BUSY = 0x3,
BT_8723B_1ANT_BT_STATUS_SCO_BUSY = 0x4,
BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY = 0x5,
BT_8723B_1ANT_BT_STATUS_MAX
};
enum _BT_8723B_1ANT_WIFI_STATUS {
BT_8723B_1ANT_WIFI_STATUS_NON_CONNECTED_IDLE = 0x0,
BT_8723B_1ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN = 0x1,
BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SCAN = 0x2,
BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SPECIAL_PKT = 0x3,
BT_8723B_1ANT_WIFI_STATUS_CONNECTED_IDLE = 0x4,
BT_8723B_1ANT_WIFI_STATUS_CONNECTED_BUSY = 0x5,
BT_8723B_1ANT_WIFI_STATUS_MAX
};
enum _BT_8723B_1ANT_COEX_ALGO {
BT_8723B_1ANT_COEX_ALGO_UNDEFINED = 0x0,
BT_8723B_1ANT_COEX_ALGO_SCO = 0x1,
BT_8723B_1ANT_COEX_ALGO_HID = 0x2,
BT_8723B_1ANT_COEX_ALGO_A2DP = 0x3,
BT_8723B_1ANT_COEX_ALGO_A2DP_PANHS = 0x4,
BT_8723B_1ANT_COEX_ALGO_PANEDR = 0x5,
BT_8723B_1ANT_COEX_ALGO_PANHS = 0x6,
BT_8723B_1ANT_COEX_ALGO_PANEDR_A2DP = 0x7,
BT_8723B_1ANT_COEX_ALGO_PANEDR_HID = 0x8,
BT_8723B_1ANT_COEX_ALGO_HID_A2DP_PANEDR = 0x9,
BT_8723B_1ANT_COEX_ALGO_HID_A2DP = 0xa,
BT_8723B_1ANT_COEX_ALGO_MAX = 0xb,
};
struct coex_dm_8723b_1ant {
/* fw mechanism */
bool cur_ignore_wlan_act;
bool pre_ignore_wlan_act;
u8 pre_ps_tdma;
u8 cur_ps_tdma;
u8 ps_tdma_para[5];
u8 tdma_adj_type;
bool auto_tdma_adjust;
bool pre_ps_tdma_on;
bool cur_ps_tdma_on;
bool pre_bt_auto_report;
bool cur_bt_auto_report;
u8 pre_lps;
u8 cur_lps;
u8 pre_rpwm;
u8 cur_rpwm;
/* sw mechanism */
bool pre_low_penalty_ra;
bool cur_low_penalty_ra;
u32 pre_val0x6c0;
u32 cur_val0x6c0;
u32 pre_val0x6c4;
u32 cur_val0x6c4;
u32 pre_val0x6c8;
u32 cur_val0x6c8;
u8 pre_val0x6cc;
u8 cur_val0x6cc;
bool limited_dig;
u32 backup_arfr_cnt1; /* Auto Rate Fallback Retry cnt */
u32 backup_arfr_cnt2; /* Auto Rate Fallback Retry cnt */
u16 backup_retry_limit;
u8 backup_ampdu_max_time;
/* algorithm related */
u8 pre_algorithm;
u8 cur_algorithm;
u8 bt_status;
u8 wifi_chnl_info[3];
u32 prera_mask;
u32 curra_mask;
u8 pre_arfr_type;
u8 cur_arfr_type;
u8 pre_retry_limit_type;
u8 cur_retry_limit_type;
u8 pre_ampdu_time_type;
u8 cur_ampdu_time_type;
u8 error_condition;
};
struct coex_sta_8723b_1ant {
bool bt_link_exist;
bool sco_exist;
bool a2dp_exist;
bool hid_exist;
bool pan_exist;
bool under_lps;
bool under_ips;
u32 special_pkt_period_cnt;
u32 high_priority_tx;
u32 high_priority_rx;
u32 low_priority_tx;
u32 low_priority_rx;
u8 bt_rssi;
u8 pre_bt_rssi_state;
u8 pre_wifi_rssi_state[4];
bool c2h_bt_info_req_sent;
u8 bt_info_c2h[BT_INFO_SRC_8723B_1ANT_MAX][10];
u32 bt_info_c2h_cnt[BT_INFO_SRC_8723B_1ANT_MAX];
bool c2h_bt_inquiry_page;
u8 bt_retry_cnt;
u8 bt_info_ext;
};
/*************************************************************************
* The following is interface which will notify coex module.
*************************************************************************/
void ex_halbtc8723b1ant_init_hwconfig(struct btc_coexist *btcoexist);
void ex_halbtc8723b1ant_init_coex_dm(struct btc_coexist *btcoexist);
void ex_halbtc8723b1ant_ips_notify(struct btc_coexist *btcoexist, u8 type);
void ex_halbtc8723b1ant_lps_notify(struct btc_coexist *btcoexist, u8 type);
void ex_halbtc8723b1ant_scan_notify(struct btc_coexist *btcoexist, u8 type);
void ex_halbtc8723b1ant_connect_notify(struct btc_coexist *btcoexist, u8 type);
void ex_halbtc8723b1ant_media_status_notify(struct btc_coexist *btcoexist,
u8 type);
void ex_halbtc8723b1ant_special_packet_notify(struct btc_coexist *btcoexist,
u8 type);
void ex_halbtc8723b1ant_bt_info_notify(struct btc_coexist *btcoexist,
u8 *tmpbuf, u8 length);
void ex_halbtc8723b1ant_halt_notify(struct btc_coexist *btcoexist);
void ex_halbtc8723b1ant_pnp_notify(struct btc_coexist *btcoexist, u8 pnpstate);
void ex_halbtc8723b1ant_coex_dm_reset(struct btc_coexist *btcoexist);
void ex_halbtc8723b1ant_periodical(struct btc_coexist *btcoexist);
void ex_halbtc8723b1ant_display_coex_info(struct btc_coexist *btcoexist);

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,172 @@
/******************************************************************************
*
* Copyright(c) 2012 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 _HAL8723B_2_ANT
#define _HAL8723B_2_ANT
/************************************************************************
* The following is for 8723B 2Ant BT Co-exist definition
************************************************************************/
#define BT_AUTO_REPORT_ONLY_8723B_2ANT 1
#define BT_INFO_8723B_2ANT_B_FTP BIT7
#define BT_INFO_8723B_2ANT_B_A2DP BIT6
#define BT_INFO_8723B_2ANT_B_HID BIT5
#define BT_INFO_8723B_2ANT_B_SCO_BUSY BIT4
#define BT_INFO_8723B_2ANT_B_ACL_BUSY BIT3
#define BT_INFO_8723B_2ANT_B_INQ_PAGE BIT2
#define BT_INFO_8723B_2ANT_B_SCO_ESCO BIT1
#define BT_INFO_8723B_2ANT_B_CONNECTION BIT0
#define BTC_RSSI_COEX_THRESH_TOL_8723B_2ANT 2
enum BT_INFO_SRC_8723B_2ANT {
BT_INFO_SRC_8723B_2ANT_WIFI_FW = 0x0,
BT_INFO_SRC_8723B_2ANT_BT_RSP = 0x1,
BT_INFO_SRC_8723B_2ANT_BT_ACTIVE_SEND = 0x2,
BT_INFO_SRC_8723B_2ANT_MAX
};
enum BT_8723B_2ANT_BT_STATUS {
BT_8723B_2ANT_BT_STATUS_NON_CONNECTED_IDLE = 0x0,
BT_8723B_2ANT_BT_STATUS_CONNECTED_IDLE = 0x1,
BT_8723B_2ANT_BT_STATUS_INQ_PAGE = 0x2,
BT_8723B_2ANT_BT_STATUS_ACL_BUSY = 0x3,
BT_8723B_2ANT_BT_STATUS_SCO_BUSY = 0x4,
BT_8723B_2ANT_BT_STATUS_ACL_SCO_BUSY = 0x5,
BT_8723B_2ANT_BT_STATUS_MAX
};
enum BT_8723B_2ANT_COEX_ALGO {
BT_8723B_2ANT_COEX_ALGO_UNDEFINED = 0x0,
BT_8723B_2ANT_COEX_ALGO_SCO = 0x1,
BT_8723B_2ANT_COEX_ALGO_HID = 0x2,
BT_8723B_2ANT_COEX_ALGO_A2DP = 0x3,
BT_8723B_2ANT_COEX_ALGO_A2DP_PANHS = 0x4,
BT_8723B_2ANT_COEX_ALGO_PANEDR = 0x5,
BT_8723B_2ANT_COEX_ALGO_PANHS = 0x6,
BT_8723B_2ANT_COEX_ALGO_PANEDR_A2DP = 0x7,
BT_8723B_2ANT_COEX_ALGO_PANEDR_HID = 0x8,
BT_8723B_2ANT_COEX_ALGO_HID_A2DP_PANEDR = 0x9,
BT_8723B_2ANT_COEX_ALGO_HID_A2DP = 0xa,
BT_8723B_2ANT_COEX_ALGO_MAX = 0xb,
};
struct coex_dm_8723b_2ant {
/* fw mechanism */
bool pre_dec_bt_pwr;
bool cur_dec_bt_pwr;
u8 pre_fw_dac_swing_lvl;
u8 cur_fw_dac_swing_lvl;
bool cur_ignore_wlan_act;
bool pre_ignore_wlan_act;
u8 pre_ps_tdma;
u8 cur_ps_tdma;
u8 ps_tdma_para[5];
u8 tdma_adj_type;
bool reset_tdma_adjust;
bool auto_tdma_adjust;
bool pre_ps_tdma_on;
bool cur_ps_tdma_on;
bool pre_bt_auto_report;
bool cur_bt_auto_report;
/* sw mechanism */
bool pre_rf_rx_lpf_shrink;
bool cur_rf_rx_lpf_shrink;
u32 bt_rf0x1e_backup;
bool pre_low_penalty_ra;
bool cur_low_penalty_ra;
bool pre_dac_swing_on;
u32 pre_dac_swing_lvl;
bool cur_dac_swing_on;
u32 cur_dac_swing_lvl;
bool pre_adc_back_off;
bool cur_adc_back_off;
bool pre_agc_table_en;
bool cur_agc_table_en;
u32 pre_val0x6c0;
u32 cur_val0x6c0;
u32 pre_val0x6c4;
u32 cur_val0x6c4;
u32 pre_val0x6c8;
u32 cur_val0x6c8;
u8 pre_val0x6cc;
u8 cur_val0x6cc;
bool limited_dig;
/* algorithm related */
u8 pre_algorithm;
u8 cur_algorithm;
u8 bt_status;
u8 wifi_chnl_info[3];
bool need_recover_0x948;
u16 backup_0x948;
};
struct coex_sta_8723b_2ant {
bool bt_link_exist;
bool sco_exist;
bool a2dp_exist;
bool hid_exist;
bool pan_exist;
bool under_lps;
bool under_ips;
u32 high_priority_tx;
u32 high_priority_rx;
u32 low_priority_tx;
u32 low_priority_rx;
u8 bt_rssi;
u8 pre_bt_rssi_state;
u8 pre_wifi_rssi_state[4];
bool c2h_bt_info_req_sent;
u8 bt_info_c2h[BT_INFO_SRC_8723B_2ANT_MAX][10];
u32 bt_info_c2h_cnt[BT_INFO_SRC_8723B_2ANT_MAX];
bool c2h_bt_inquiry_page;
u8 bt_retry_cnt;
u8 bt_info_ext;
};
/*********************************************************************
* The following is interface which will notify coex module.
*********************************************************************/
void ex_btc8723b2ant_init_hwconfig(struct btc_coexist *btcoexist);
void ex_btc8723b2ant_init_coex_dm(struct btc_coexist *btcoexist);
void ex_btc8723b2ant_ips_notify(struct btc_coexist *btcoexist, u8 type);
void ex_btc8723b2ant_lps_notify(struct btc_coexist *btcoexist, u8 type);
void ex_btc8723b2ant_scan_notify(struct btc_coexist *btcoexist, u8 type);
void ex_btc8723b2ant_connect_notify(struct btc_coexist *btcoexist, u8 type);
void ex_btc8723b2ant_media_status_notify(struct btc_coexist *btcoexist,
u8 type);
void ex_btc8723b2ant_special_packet_notify(struct btc_coexist *btcoexist,
u8 type);
void ex_btc8723b2ant_bt_info_notify(struct btc_coexist *btcoexist,
u8 *tmpbuf, u8 length);
void ex_btc8723b2ant_halt_notify(struct btc_coexist *btcoexist);
void ex_btc8723b2ant_periodical(struct btc_coexist *btcoexist);
void ex_btc8723b2ant_display_coex_info(struct btc_coexist *btcoexist);
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,188 @@
/******************************************************************************
*
* Copyright(c) 2012 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>
*
*****************************************************************************/
/*===========================================
* The following is for 8821A 1ANT BT Co-exist definition
*===========================================
*/
#define BT_AUTO_REPORT_ONLY_8821A_1ANT 0
#define BT_INFO_8821A_1ANT_B_FTP BIT7
#define BT_INFO_8821A_1ANT_B_A2DP BIT6
#define BT_INFO_8821A_1ANT_B_HID BIT5
#define BT_INFO_8821A_1ANT_B_SCO_BUSY BIT4
#define BT_INFO_8821A_1ANT_B_ACL_BUSY BIT3
#define BT_INFO_8821A_1ANT_B_INQ_PAGE BIT2
#define BT_INFO_8821A_1ANT_B_SCO_ESCO BIT1
#define BT_INFO_8821A_1ANT_B_CONNECTION BIT0
#define BT_INFO_8821A_1ANT_A2DP_BASIC_RATE(_BT_INFO_EXT_) \
(((_BT_INFO_EXT_&BIT0)) ? true : false)
#define BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT 2
enum _BT_INFO_SRC_8821A_1ANT {
BT_INFO_SRC_8821A_1ANT_WIFI_FW = 0x0,
BT_INFO_SRC_8821A_1ANT_BT_RSP = 0x1,
BT_INFO_SRC_8821A_1ANT_BT_ACTIVE_SEND = 0x2,
BT_INFO_SRC_8821A_1ANT_MAX
};
enum _BT_8821A_1ANT_BT_STATUS {
BT_8821A_1ANT_BT_STATUS_NON_CONNECTED_IDLE = 0x0,
BT_8821A_1ANT_BT_STATUS_CONNECTED_IDLE = 0x1,
BT_8821A_1ANT_BT_STATUS_INQ_PAGE = 0x2,
BT_8821A_1ANT_BT_STATUS_ACL_BUSY = 0x3,
BT_8821A_1ANT_BT_STATUS_SCO_BUSY = 0x4,
BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY = 0x5,
BT_8821A_1ANT_BT_STATUS_MAX
};
enum _BT_8821A_1ANT_WIFI_STATUS {
BT_8821A_1ANT_WIFI_STATUS_NON_CONNECTED_IDLE = 0x0,
BT_8821A_1ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN = 0x1,
BT_8821A_1ANT_WIFI_STATUS_CONNECTED_SCAN = 0x2,
BT_8821A_1ANT_WIFI_STATUS_CONNECTED_SPECIAL_PKT = 0x3,
BT_8821A_1ANT_WIFI_STATUS_CONNECTED_IDLE = 0x4,
BT_8821A_1ANT_WIFI_STATUS_CONNECTED_BUSY = 0x5,
BT_8821A_1ANT_WIFI_STATUS_MAX
};
enum BT_8821A_1ANT_COEX_ALGO {
BT_8821A_1ANT_COEX_ALGO_UNDEFINED = 0x0,
BT_8821A_1ANT_COEX_ALGO_SCO = 0x1,
BT_8821A_1ANT_COEX_ALGO_HID = 0x2,
BT_8821A_1ANT_COEX_ALGO_A2DP = 0x3,
BT_8821A_1ANT_COEX_ALGO_A2DP_PANHS = 0x4,
BT_8821A_1ANT_COEX_ALGO_PANEDR = 0x5,
BT_8821A_1ANT_COEX_ALGO_PANHS = 0x6,
BT_8821A_1ANT_COEX_ALGO_PANEDR_A2DP = 0x7,
BT_8821A_1ANT_COEX_ALGO_PANEDR_HID = 0x8,
BT_8821A_1ANT_COEX_ALGO_HID_A2DP_PANEDR = 0x9,
BT_8821A_1ANT_COEX_ALGO_HID_A2DP = 0xa,
BT_8821A_1ANT_COEX_ALGO_MAX = 0xb,
};
struct coex_dm_8821a_1ant {
/* fw mechanism */
bool cur_ignore_wlan_act;
bool pre_ignore_wlan_act;
u8 pre_ps_tdma;
u8 cur_ps_tdma;
u8 ps_tdma_para[5];
u8 tdma_adj_type;
bool auto_tdma_adjust;
bool pre_ps_tdma_on;
bool cur_ps_tdma_on;
bool pre_bt_auto_report;
bool cur_bt_auto_report;
u8 pre_lps;
u8 cur_lps;
u8 pre_rpwm;
u8 cur_rpwm;
/* sw mechanism */
bool pre_low_penalty_ra;
bool cur_low_penalty_ra;
u32 pre_val_0x6c0;
u32 cur_val_0x6c0;
u32 pre_val_0x6c4;
u32 cur_val_0x6c4;
u32 pre_val_0x6c8;
u32 cur_val_0x6c8;
u8 pre_val_0x6cc;
u8 cur_val_0x6cc;
/* Auto Rate Fallback Retry cnt */
u32 backup_arfr_cnt1;
/* Auto Rate Fallback Retry cnt */
u32 backup_arfr_cnt2;
u16 backup_retry_limit;
u8 backup_ampdu_max_time;
/* algorithm related */
u8 pre_algorithm;
u8 cur_algorithm;
u8 bt_status;
u8 wifi_chnl_info[3];
u32 pre_ra_mask;
u32 cur_ra_mask;
u8 pre_arfr_type;
u8 cur_arfr_type;
u8 pre_retry_limit_type;
u8 cur_retry_limit_type;
u8 pre_ampdu_time_type;
u8 cur_ampdu_time_type;
u8 error_condition;
};
struct coex_sta_8821a_1ant {
bool bt_link_exist;
bool sco_exist;
bool a2dp_exist;
bool hid_exist;
bool pan_exist;
bool under_Lps;
bool under_ips;
u32 special_pkt_period_cnt;
u32 high_priority_tx;
u32 high_priority_rx;
u32 low_priority_tx;
u32 low_priority_rx;
u8 bt_rssi;
u8 pre_bt_rssi_state;
u8 pre_wifi_rssi_state[4];
bool c2h_bt_info_req_sent;
u8 bt_info_c2h[BT_INFO_SRC_8821A_1ANT_MAX][10];
u32 bt_info_c2h_cnt[BT_INFO_SRC_8821A_1ANT_MAX];
bool c2h_bt_inquiry_page;
u8 bt_retry_cnt;
u8 bt_info_ext;
};
/*===========================================
* The following is interface which will notify coex module.
*===========================================
*/
void ex_halbtc8821a1ant_init_hwconfig(struct btc_coexist *btcoexist);
void ex_halbtc8821a1ant_init_coex_dm(struct btc_coexist *btcoexist);
void ex_halbtc8821a1ant_ips_notify(struct btc_coexist *btcoexist, u8 type);
void ex_halbtc8821a1ant_lps_notify(struct btc_coexist *btcoexist, u8 type);
void ex_halbtc8821a1ant_scan_notify(struct btc_coexist *btcoexist, u8 type);
void ex_halbtc8821a1ant_connect_notify(struct btc_coexist *btcoexist, u8 type);
void ex_halbtc8821a1ant_media_status_notify(struct btc_coexist *btcoexist,
u8 type);
void ex_halbtc8821a1ant_special_packet_notify(struct btc_coexist *btcoexist,
u8 type);
void ex_halbtc8821a1ant_bt_info_notify(struct btc_coexist *btcoexist,
u8 *tmpbuf, u8 length);
void ex_halbtc8821a1ant_halt_notify(struct btc_coexist *btcoexist);
void ex_halbtc8821a1ant_pnp_notify(struct btc_coexist *btcoexist, u8 pnpstate);
void ex_halbtc8821a1ant_periodical(struct btc_coexist *btcoexist);
void ex_halbtc8821a1ant_display_coex_info(struct btc_coexist *btcoexist);
void ex_halbtc8821a1ant_dbg_control(struct btc_coexist *btcoexist, u8 op_code,
u8 op_len, u8 *data);

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,205 @@
/******************************************************************************
*
* Copyright(c) 2012 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>
*
*****************************************************************************/
/*===========================================
* The following is for 8821A 2Ant BT Co-exist definition
*===========================================
*/
#define BT_INFO_8821A_2ANT_B_FTP BIT7
#define BT_INFO_8821A_2ANT_B_A2DP BIT6
#define BT_INFO_8821A_2ANT_B_HID BIT5
#define BT_INFO_8821A_2ANT_B_SCO_BUSY BIT4
#define BT_INFO_8821A_2ANT_B_ACL_BUSY BIT3
#define BT_INFO_8821A_2ANT_B_INQ_PAGE BIT2
#define BT_INFO_8821A_2ANT_B_SCO_ESCO BIT1
#define BT_INFO_8821A_2ANT_B_CONNECTION BIT0
#define BTC_RSSI_COEX_THRESH_TOL_8821A_2ANT 2
enum _BT_INFO_SRC_8821A_2ANT {
BT_INFO_SRC_8821A_2ANT_WIFI_FW = 0x0,
BT_INFO_SRC_8821A_2ANT_BT_RSP = 0x1,
BT_INFO_SRC_8821A_2ANT_BT_ACTIVE_SEND = 0x2,
BT_INFO_SRC_8821A_2ANT_MAX
};
enum _BT_8821A_2ANT_BT_STATUS {
BT_8821A_2ANT_BT_STATUS_IDLE = 0x0,
BT_8821A_2ANT_BT_STATUS_CON_IDLE = 0x1,
BT_8821A_2ANT_BT_STATUS_NON_IDLE = 0x2,
BT_8821A_2ANT_BT_STATUS_MAX
};
enum _BT_8821A_2ANT_COEX_ALGO {
BT_8821A_2ANT_COEX_ALGO_UNDEFINED = 0x0,
BT_8821A_2ANT_COEX_ALGO_SCO = 0x1,
BT_8821A_2ANT_COEX_ALGO_HID = 0x2,
BT_8821A_2ANT_COEX_ALGO_A2DP = 0x3,
BT_8821A_2ANT_COEX_ALGO_A2DP_PANHS = 0x4,
BT_8821A_2ANT_COEX_ALGO_PANEDR = 0x5,
BT_8821A_2ANT_COEX_ALGO_PANHS = 0x6,
BT_8821A_2ANT_COEX_ALGO_PANEDR_A2DP = 0x7,
BT_8821A_2ANT_COEX_ALGO_PANEDR_HID = 0x8,
BT_8821A_2ANT_COEX_ALGO_HID_A2DP_PANEDR = 0x9,
BT_8821A_2ANT_COEX_ALGO_HID_A2DP = 0xa,
BT_8821A_2ANT_COEX_ALGO_MAX = 0xb,
};
struct coex_dm_8821a_2ant {
/* fw mechanism */
bool pre_dec_bt_pwr;
bool cur_dec_bt_pwr;
bool pre_bt_lna_constrain;
bool cur_bt_lna_constrain;
u8 pre_bt_psd_mode;
u8 cur_bt_psd_mode;
u8 pre_fw_dac_swing_lvl;
u8 cur_fw_dac_swing_lvl;
bool cur_ignore_wlan_act;
bool pre_ignore_wlan_act;
u8 pre_ps_tdma;
u8 cur_ps_tdma;
u8 ps_tdma_para[5];
u8 tdma_adj_type;
bool reset_tdma_adjust;
bool pre_ps_tdma_on;
bool cur_ps_tdma_on;
bool pre_bt_auto_report;
bool cur_bt_auto_report;
/* sw mechanism */
bool pre_rf_rx_lpf_shrink;
bool cur_rf_rx_lpf_shrink;
u32 bt_rf0x1e_backup;
bool pre_low_penalty_ra;
bool cur_low_penalty_ra;
bool pre_dac_swing_on;
u32 pre_dac_swing_lvl;
bool cur_dac_swing_on;
u32 cur_dac_swing_lvl;
bool pre_adc_back_off;
bool cur_adc_back_off;
bool pre_agc_table_en;
bool cur_agc_table_en;
u32 pre_val0x6c0;
u32 cur_val0x6c0;
u32 pre_val0x6c4;
u32 cur_val0x6c4;
u32 pre_val0x6c8;
u32 cur_val0x6c8;
u8 pre_val0x6cc;
u8 cur_val0x6cc;
bool limited_dig;
/* algorithm related */
u8 pre_algorithm;
u8 cur_algorithm;
u8 bt_status;
u8 wifi_chnl_info[3];
};
struct coex_sta_8821a_2ant {
bool bt_link_exist;
bool sco_exist;
bool a2dp_exist;
bool hid_exist;
bool pan_exist;
bool under_lps;
bool under_ips;
u32 high_priority_tx;
u32 high_priority_rx;
u32 low_priority_tx;
u32 low_priority_rx;
u8 bt_rssi;
u8 pre_bt_rssi_state;
u8 pre_wifi_rssi_state[4];
bool c2h_bt_info_req_sent;
u8 bt_info_c2h[BT_INFO_SRC_8821A_2ANT_MAX][10];
u32 bt_info_c2h_cnt[BT_INFO_SRC_8821A_2ANT_MAX];
bool c2h_bt_inquiry_page;
u8 bt_retry_cnt;
u8 bt_info_ext;
};
/*===========================================
* The following is interface which will notify coex module.
*===========================================
*/
void
ex_halbtc8821a2ant_init_hwconfig(
struct btc_coexist *btcoexist
);
void
ex_halbtc8821a2ant_init_coex_dm(
struct btc_coexist *btcoexist
);
void
ex_halbtc8821a2ant_ips_notify(
struct btc_coexist *btcoexist,
u8 type
);
void
ex_halbtc8821a2ant_lps_notify(
struct btc_coexist *btcoexist,
u8 type
);
void
ex_halbtc8821a2ant_scan_notify(
struct btc_coexist *btcoexist,
u8 type
);
void
ex_halbtc8821a2ant_connect_notify(
struct btc_coexist *btcoexist,
u8 type
);
void
ex_halbtc8821a2ant_media_status_notify(
struct btc_coexist *btcoexist,
u8 type
);
void
ex_halbtc8821a2ant_special_packet_notify(
struct btc_coexist *btcoexist,
u8 type
);
void
ex_halbtc8821a2ant_bt_info_notify(
struct btc_coexist *btcoexist,
u8 *tmp_buf,
u8 length
);
void
ex_halbtc8821a2ant_halt_notify(
struct btc_coexist *btcoexist
);
void
ex_halbtc8821a2ant_periodical(
struct btc_coexist *btcoexist
);
void
ex_halbtc8821a2ant_display_coex_info(
struct btc_coexist *btcoexist
);

View file

@ -0,0 +1,987 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2013 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.
*
* 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 "halbt_precomp.h"
/***********************************************
* Global variables
***********************************************/
struct btc_coexist gl_bt_coexist;
u32 btc_dbg_type[BTC_MSG_MAX];
/***************************************************
* Debug related function
***************************************************/
static bool halbtc_is_bt_coexist_available(struct btc_coexist *btcoexist)
{
if (!btcoexist->binded || NULL == btcoexist->adapter)
return false;
return true;
}
static bool halbtc_is_wifi_busy(struct rtl_priv *rtlpriv)
{
if (rtlpriv->link_info.busytraffic)
return true;
else
return false;
}
static void halbtc_dbg_init(void)
{
u8 i;
for (i = 0; i < BTC_MSG_MAX; i++)
btc_dbg_type[i] = 0;
btc_dbg_type[BTC_MSG_INTERFACE] =
/* INTF_INIT | */
/* INTF_NOTIFY | */
0;
btc_dbg_type[BTC_MSG_ALGORITHM] =
/* ALGO_BT_RSSI_STATE | */
/* ALGO_WIFI_RSSI_STATE | */
/* ALGO_BT_MONITOR | */
/* ALGO_TRACE | */
/* ALGO_TRACE_FW | */
/* ALGO_TRACE_FW_DETAIL | */
/* ALGO_TRACE_FW_EXEC | */
/* ALGO_TRACE_SW | */
/* ALGO_TRACE_SW_DETAIL | */
/* ALGO_TRACE_SW_EXEC | */
0;
}
static bool halbtc_is_bt40(struct rtl_priv *adapter)
{
struct rtl_priv *rtlpriv = adapter;
struct rtl_phy *rtlphy = &(rtlpriv->phy);
bool is_ht40 = true;
enum ht_channel_width bw = rtlphy->current_chan_bw;
if (bw == HT_CHANNEL_WIDTH_20)
is_ht40 = false;
else if (bw == HT_CHANNEL_WIDTH_20_40)
is_ht40 = true;
return is_ht40;
}
static bool halbtc_legacy(struct rtl_priv *adapter)
{
struct rtl_priv *rtlpriv = adapter;
struct rtl_mac *mac = rtl_mac(rtlpriv);
bool is_legacy = false;
if ((mac->mode == WIRELESS_MODE_B) || (mac->mode == WIRELESS_MODE_G))
is_legacy = true;
return is_legacy;
}
bool halbtc_is_wifi_uplink(struct rtl_priv *adapter)
{
struct rtl_priv *rtlpriv = adapter;
if (rtlpriv->link_info.tx_busy_traffic)
return true;
else
return false;
}
static u32 halbtc_get_wifi_bw(struct btc_coexist *btcoexist)
{
struct rtl_priv *rtlpriv =
(struct rtl_priv *)btcoexist->adapter;
u32 wifi_bw = BTC_WIFI_BW_HT20;
if (halbtc_is_bt40(rtlpriv)) {
wifi_bw = BTC_WIFI_BW_HT40;
} else {
if (halbtc_legacy(rtlpriv))
wifi_bw = BTC_WIFI_BW_LEGACY;
else
wifi_bw = BTC_WIFI_BW_HT20;
}
return wifi_bw;
}
static u8 halbtc_get_wifi_central_chnl(struct btc_coexist *btcoexist)
{
struct rtl_priv *rtlpriv = btcoexist->adapter;
struct rtl_phy *rtlphy = &(rtlpriv->phy);
u8 chnl = 1;
if (rtlphy->current_channel != 0)
chnl = rtlphy->current_channel;
BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
"static halbtc_get_wifi_central_chnl:%d\n", chnl);
return chnl;
}
static void halbtc_leave_lps(struct btc_coexist *btcoexist)
{
struct rtl_priv *rtlpriv;
struct rtl_ps_ctl *ppsc;
bool ap_enable = false;
rtlpriv = btcoexist->adapter;
ppsc = rtl_psc(rtlpriv);
btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE,
&ap_enable);
if (ap_enable) {
pr_info("halbtc_leave_lps()<--dont leave lps under AP mode\n");
return;
}
btcoexist->bt_info.bt_ctrl_lps = true;
btcoexist->bt_info.bt_lps_on = false;
}
static void halbtc_enter_lps(struct btc_coexist *btcoexist)
{
struct rtl_priv *rtlpriv;
struct rtl_ps_ctl *ppsc;
bool ap_enable = false;
rtlpriv = btcoexist->adapter;
ppsc = rtl_psc(rtlpriv);
btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE,
&ap_enable);
if (ap_enable) {
pr_info("halbtc_enter_lps()<--dont enter lps under AP mode\n");
return;
}
btcoexist->bt_info.bt_ctrl_lps = true;
btcoexist->bt_info.bt_lps_on = false;
}
static void halbtc_normal_lps(struct btc_coexist *btcoexist)
{
if (btcoexist->bt_info.bt_ctrl_lps) {
btcoexist->bt_info.bt_lps_on = false;
btcoexist->bt_info.bt_ctrl_lps = false;
}
}
static void halbtc_leave_low_power(void)
{
}
static void halbtc_nomal_low_power(void)
{
}
static void halbtc_disable_low_power(void)
{
}
static void halbtc_aggregation_check(void)
{
}
static u32 halbtc_get_bt_patch_version(struct btc_coexist *btcoexist)
{
return 0;
}
static s32 halbtc_get_wifi_rssi(struct rtl_priv *adapter)
{
struct rtl_priv *rtlpriv = adapter;
s32 undec_sm_pwdb = 0;
if (rtlpriv->mac80211.link_state >= MAC80211_LINKED)
undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb;
else /* associated entry pwdb */
undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb;
return undec_sm_pwdb;
}
static bool halbtc_get(void *void_btcoexist, u8 get_type, void *out_buf)
{
struct btc_coexist *btcoexist = (struct btc_coexist *)void_btcoexist;
struct rtl_priv *rtlpriv = btcoexist->adapter;
struct rtl_phy *rtlphy = &(rtlpriv->phy);
struct rtl_mac *mac = rtl_mac(rtlpriv);
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
bool *bool_tmp = (bool *)out_buf;
int *s32_tmp = (int *)out_buf;
u32 *u32_tmp = (u32 *)out_buf;
u8 *u8_tmp = (u8 *)out_buf;
bool tmp = false;
if (!halbtc_is_bt_coexist_available(btcoexist))
return false;
switch (get_type) {
case BTC_GET_BL_HS_OPERATION:
*bool_tmp = false;
break;
case BTC_GET_BL_HS_CONNECTING:
*bool_tmp = false;
break;
case BTC_GET_BL_WIFI_CONNECTED:
if (rtlpriv->mac80211.link_state >= MAC80211_LINKED)
tmp = true;
*bool_tmp = tmp;
break;
case BTC_GET_BL_WIFI_BUSY:
if (halbtc_is_wifi_busy(rtlpriv))
*bool_tmp = true;
else
*bool_tmp = false;
break;
case BTC_GET_BL_WIFI_SCAN:
if (mac->act_scanning)
*bool_tmp = true;
else
*bool_tmp = false;
break;
case BTC_GET_BL_WIFI_LINK:
if (mac->link_state == MAC80211_LINKING)
*bool_tmp = true;
else
*bool_tmp = false;
break;
case BTC_GET_BL_WIFI_ROAM: /*TODO*/
if (mac->link_state == MAC80211_LINKING)
*bool_tmp = true;
else
*bool_tmp = false;
break;
case BTC_GET_BL_WIFI_4_WAY_PROGRESS: /*TODO*/
*bool_tmp = false;
break;
case BTC_GET_BL_WIFI_UNDER_5G:
*bool_tmp = false; /*TODO*/
case BTC_GET_BL_WIFI_DHCP: /*TODO*/
break;
case BTC_GET_BL_WIFI_SOFTAP_IDLE:
*bool_tmp = true;
break;
case BTC_GET_BL_WIFI_SOFTAP_LINKING:
*bool_tmp = false;
break;
case BTC_GET_BL_WIFI_IN_EARLY_SUSPEND:
*bool_tmp = false;
break;
case BTC_GET_BL_WIFI_AP_MODE_ENABLE:
*bool_tmp = false;
break;
case BTC_GET_BL_WIFI_ENABLE_ENCRYPTION:
if (NO_ENCRYPTION == rtlpriv->sec.pairwise_enc_algorithm)
*bool_tmp = false;
else
*bool_tmp = true;
break;
case BTC_GET_BL_WIFI_UNDER_B_MODE:
*bool_tmp = false; /*TODO*/
break;
case BTC_GET_BL_EXT_SWITCH:
*bool_tmp = false;
break;
case BTC_GET_S4_WIFI_RSSI:
*s32_tmp = halbtc_get_wifi_rssi(rtlpriv);
break;
case BTC_GET_S4_HS_RSSI: /*TODO*/
*s32_tmp = halbtc_get_wifi_rssi(rtlpriv);
break;
case BTC_GET_U4_WIFI_BW:
*u32_tmp = halbtc_get_wifi_bw(btcoexist);
break;
case BTC_GET_U4_WIFI_TRAFFIC_DIRECTION:
if (halbtc_is_wifi_uplink(rtlpriv))
*u32_tmp = BTC_WIFI_TRAFFIC_TX;
else
*u32_tmp = BTC_WIFI_TRAFFIC_RX;
break;
case BTC_GET_U4_WIFI_FW_VER:
*u32_tmp = rtlhal->fw_version;
break;
case BTC_GET_U4_BT_PATCH_VER:
*u32_tmp = halbtc_get_bt_patch_version(btcoexist);
break;
case BTC_GET_U1_WIFI_DOT11_CHNL:
*u8_tmp = rtlphy->current_channel;
break;
case BTC_GET_U1_WIFI_CENTRAL_CHNL:
*u8_tmp = halbtc_get_wifi_central_chnl(btcoexist);
break;
case BTC_GET_U1_WIFI_HS_CHNL:
*u8_tmp = 1;/*BT_OperateChnl(rtlpriv);*/
break;
case BTC_GET_U1_MAC_PHY_MODE:
*u8_tmp = BTC_MP_UNKNOWN;
break;
/************* 1Ant **************/
case BTC_GET_U1_LPS_MODE:
*u8_tmp = btcoexist->pwr_mode_val[0];
break;
default:
break;
}
return true;
}
static bool halbtc_set(void *void_btcoexist, u8 set_type, void *in_buf)
{
struct btc_coexist *btcoexist = (struct btc_coexist *)void_btcoexist;
bool *bool_tmp = (bool *)in_buf;
u8 *u8_tmp = (u8 *)in_buf;
u32 *u32_tmp = (u32 *)in_buf;
if (!halbtc_is_bt_coexist_available(btcoexist))
return false;
switch (set_type) {
/* set some bool type variables. */
case BTC_SET_BL_BT_DISABLE:
btcoexist->bt_info.bt_disabled = *bool_tmp;
break;
case BTC_SET_BL_BT_TRAFFIC_BUSY:
btcoexist->bt_info.bt_busy = *bool_tmp;
break;
case BTC_SET_BL_BT_LIMITED_DIG:
btcoexist->bt_info.limited_dig = *bool_tmp;
break;
case BTC_SET_BL_FORCE_TO_ROAM:
btcoexist->bt_info.force_to_roam = *bool_tmp;
break;
case BTC_SET_BL_TO_REJ_AP_AGG_PKT:
btcoexist->bt_info.reject_agg_pkt = *bool_tmp;
break;
case BTC_SET_BL_BT_CTRL_AGG_SIZE:
btcoexist->bt_info.bt_ctrl_buf_size = *bool_tmp;
break;
case BTC_SET_BL_INC_SCAN_DEV_NUM:
btcoexist->bt_info.increase_scan_dev_num = *bool_tmp;
break;
/* set some u1Byte type variables. */
case BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON:
btcoexist->bt_info.rssi_adjust_for_agc_table_on = *u8_tmp;
break;
case BTC_SET_U1_AGG_BUF_SIZE:
btcoexist->bt_info.agg_buf_size = *u8_tmp;
break;
/* the following are some action which will be triggered */
case BTC_SET_ACT_GET_BT_RSSI:
/*BTHCI_SendGetBtRssiEvent(rtlpriv);*/
break;
case BTC_SET_ACT_AGGREGATE_CTRL:
halbtc_aggregation_check();
break;
/* 1Ant */
case BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE:
btcoexist->bt_info.rssi_adjust_for_1ant_coex_type = *u8_tmp;
break;
case BTC_SET_UI_SCAN_SIG_COMPENSATION:
/* rtlpriv->mlmepriv.scan_compensation = *u8_tmp; */
break;
case BTC_SET_U1_1ANT_LPS:
btcoexist->bt_info.lps_val = *u8_tmp;
break;
case BTC_SET_U1_1ANT_RPWM:
btcoexist->bt_info.rpwm_val = *u8_tmp;
break;
/* the following are some action which will be triggered */
case BTC_SET_ACT_LEAVE_LPS:
halbtc_leave_lps(btcoexist);
break;
case BTC_SET_ACT_ENTER_LPS:
halbtc_enter_lps(btcoexist);
break;
case BTC_SET_ACT_NORMAL_LPS:
halbtc_normal_lps(btcoexist);
break;
case BTC_SET_ACT_DISABLE_LOW_POWER:
halbtc_disable_low_power();
break;
case BTC_SET_ACT_UPDATE_ra_mask:
btcoexist->bt_info.ra_mask = *u32_tmp;
break;
case BTC_SET_ACT_SEND_MIMO_PS:
break;
case BTC_SET_ACT_INC_FORCE_EXEC_PWR_CMD_CNT:
btcoexist->bt_info.force_exec_pwr_cmd_cnt++;
break;
case BTC_SET_ACT_CTRL_BT_INFO: /*wait for 8812/8821*/
break;
case BTC_SET_ACT_CTRL_BT_COEX:
break;
default:
break;
}
return true;
}
static void halbtc_display_coex_statistics(struct btc_coexist *btcoexist)
{
}
static void halbtc_display_bt_link_info(struct btc_coexist *btcoexist)
{
}
static void halbtc_display_bt_fw_info(struct btc_coexist *btcoexist)
{
}
static void halbtc_display_fw_pwr_mode_cmd(struct btc_coexist *btcoexist)
{
}
/************************************************************
* IO related function
************************************************************/
static u8 halbtc_read_1byte(void *bt_context, u32 reg_addr)
{
struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
struct rtl_priv *rtlpriv = btcoexist->adapter;
return rtl_read_byte(rtlpriv, reg_addr);
}
static u16 halbtc_read_2byte(void *bt_context, u32 reg_addr)
{
struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
struct rtl_priv *rtlpriv = btcoexist->adapter;
return rtl_read_word(rtlpriv, reg_addr);
}
static u32 halbtc_read_4byte(void *bt_context, u32 reg_addr)
{
struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
struct rtl_priv *rtlpriv = btcoexist->adapter;
return rtl_read_dword(rtlpriv, reg_addr);
}
static void halbtc_write_1byte(void *bt_context, u32 reg_addr, u32 data)
{
struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
struct rtl_priv *rtlpriv = btcoexist->adapter;
rtl_write_byte(rtlpriv, reg_addr, data);
}
static void halbtc_bitmask_write_1byte(void *bt_context, u32 reg_addr,
u32 bit_mask, u8 data)
{
struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
struct rtl_priv *rtlpriv = btcoexist->adapter;
u8 original_value, bit_shift = 0;
u8 i;
if (bit_mask != MASKDWORD) {/*if not "double word" write*/
original_value = rtl_read_byte(rtlpriv, reg_addr);
for (i = 0; i <= 7; i++) {
if ((bit_mask>>i) & 0x1)
break;
}
bit_shift = i;
data = (original_value & (~bit_mask)) |
((data << bit_shift) & bit_mask);
}
rtl_write_byte(rtlpriv, reg_addr, data);
}
static void halbtc_write_2byte(void *bt_context, u32 reg_addr, u16 data)
{
struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
struct rtl_priv *rtlpriv = btcoexist->adapter;
rtl_write_word(rtlpriv, reg_addr, data);
}
static void halbtc_write_4byte(void *bt_context, u32 reg_addr, u32 data)
{
struct btc_coexist *btcoexist =
(struct btc_coexist *)bt_context;
struct rtl_priv *rtlpriv = btcoexist->adapter;
rtl_write_dword(rtlpriv, reg_addr, data);
}
static void halbtc_set_bbreg(void *bt_context, u32 reg_addr, u32 bit_mask,
u32 data)
{
struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
struct rtl_priv *rtlpriv = btcoexist->adapter;
rtl_set_bbreg(rtlpriv->mac80211.hw, reg_addr, bit_mask, data);
}
static u32 halbtc_get_bbreg(void *bt_context, u32 reg_addr, u32 bit_mask)
{
struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
struct rtl_priv *rtlpriv = btcoexist->adapter;
return rtl_get_bbreg(rtlpriv->mac80211.hw, reg_addr, bit_mask);
}
static void halbtc_set_rfreg(void *bt_context, u8 rf_path, u32 reg_addr,
u32 bit_mask, u32 data)
{
struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
struct rtl_priv *rtlpriv = btcoexist->adapter;
rtl_set_rfreg(rtlpriv->mac80211.hw, rf_path, reg_addr, bit_mask, data);
}
static u32 halbtc_get_rfreg(void *bt_context, u8 rf_path, u32 reg_addr,
u32 bit_mask)
{
struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
struct rtl_priv *rtlpriv = btcoexist->adapter;
return rtl_get_rfreg(rtlpriv->mac80211.hw, rf_path, reg_addr, bit_mask);
}
static void halbtc_fill_h2c_cmd(void *bt_context, u8 element_id,
u32 cmd_len, u8 *cmd_buf)
{
struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
struct rtl_priv *rtlpriv = btcoexist->adapter;
rtlpriv->cfg->ops->fill_h2c_cmd(rtlpriv->mac80211.hw, element_id,
cmd_len, cmd_buf);
}
static void halbtc_display_dbg_msg(void *bt_context, u8 disp_type)
{
struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
switch (disp_type) {
case BTC_DBG_DISP_COEX_STATISTICS:
halbtc_display_coex_statistics(btcoexist);
break;
case BTC_DBG_DISP_BT_LINK_INFO:
halbtc_display_bt_link_info(btcoexist);
break;
case BTC_DBG_DISP_BT_FW_VER:
halbtc_display_bt_fw_info(btcoexist);
break;
case BTC_DBG_DISP_FW_PWR_MODE_CMD:
halbtc_display_fw_pwr_mode_cmd(btcoexist);
break;
default:
break;
}
}
/*****************************************************************
* Extern functions called by other module
*****************************************************************/
bool exhalbtc_initlize_variables(struct rtl_priv *adapter)
{
struct btc_coexist *btcoexist = &gl_bt_coexist;
btcoexist->statistics.cnt_bind++;
halbtc_dbg_init();
if (btcoexist->binded)
return false;
else
btcoexist->binded = true;
btcoexist->chip_interface = BTC_INTF_UNKNOWN;
if (NULL == btcoexist->adapter)
btcoexist->adapter = adapter;
btcoexist->stack_info.profile_notified = false;
btcoexist->btc_read_1byte = halbtc_read_1byte;
btcoexist->btc_write_1byte = halbtc_write_1byte;
btcoexist->btc_write_1byte_bitmask = halbtc_bitmask_write_1byte;
btcoexist->btc_read_2byte = halbtc_read_2byte;
btcoexist->btc_write_2byte = halbtc_write_2byte;
btcoexist->btc_read_4byte = halbtc_read_4byte;
btcoexist->btc_write_4byte = halbtc_write_4byte;
btcoexist->btc_set_bb_reg = halbtc_set_bbreg;
btcoexist->btc_get_bb_reg = halbtc_get_bbreg;
btcoexist->btc_set_rf_reg = halbtc_set_rfreg;
btcoexist->btc_get_rf_reg = halbtc_get_rfreg;
btcoexist->btc_fill_h2c = halbtc_fill_h2c_cmd;
btcoexist->btc_disp_dbg_msg = halbtc_display_dbg_msg;
btcoexist->btc_get = halbtc_get;
btcoexist->btc_set = halbtc_set;
btcoexist->bt_info.bt_ctrl_buf_size = false;
btcoexist->bt_info.agg_buf_size = 5;
btcoexist->bt_info.increase_scan_dev_num = false;
return true;
}
void exhalbtc_init_hw_config(struct btc_coexist *btcoexist)
{
struct rtl_priv *rtlpriv = btcoexist->adapter;
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
if (!halbtc_is_bt_coexist_available(btcoexist))
return;
btcoexist->statistics.cnt_init_hw_config++;
if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE)
ex_btc8723b2ant_init_hwconfig(btcoexist);
}
void exhalbtc_init_coex_dm(struct btc_coexist *btcoexist)
{
struct rtl_priv *rtlpriv = btcoexist->adapter;
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
if (!halbtc_is_bt_coexist_available(btcoexist))
return;
btcoexist->statistics.cnt_init_coex_dm++;
if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE)
ex_btc8723b2ant_init_coex_dm(btcoexist);
btcoexist->initilized = true;
}
void exhalbtc_ips_notify(struct btc_coexist *btcoexist, u8 type)
{
struct rtl_priv *rtlpriv = btcoexist->adapter;
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
u8 ips_type;
if (!halbtc_is_bt_coexist_available(btcoexist))
return;
btcoexist->statistics.cnt_ips_notify++;
if (btcoexist->manual_control)
return;
if (ERFOFF == type)
ips_type = BTC_IPS_ENTER;
else
ips_type = BTC_IPS_LEAVE;
halbtc_leave_low_power();
if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE)
ex_btc8723b2ant_ips_notify(btcoexist, ips_type);
halbtc_nomal_low_power();
}
void exhalbtc_lps_notify(struct btc_coexist *btcoexist, u8 type)
{
struct rtl_priv *rtlpriv = btcoexist->adapter;
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
u8 lps_type;
if (!halbtc_is_bt_coexist_available(btcoexist))
return;
btcoexist->statistics.cnt_lps_notify++;
if (btcoexist->manual_control)
return;
if (EACTIVE == type)
lps_type = BTC_LPS_DISABLE;
else
lps_type = BTC_LPS_ENABLE;
if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE)
ex_btc8723b2ant_lps_notify(btcoexist, lps_type);
}
void exhalbtc_scan_notify(struct btc_coexist *btcoexist, u8 type)
{
struct rtl_priv *rtlpriv = btcoexist->adapter;
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
u8 scan_type;
if (!halbtc_is_bt_coexist_available(btcoexist))
return;
btcoexist->statistics.cnt_scan_notify++;
if (btcoexist->manual_control)
return;
if (type)
scan_type = BTC_SCAN_START;
else
scan_type = BTC_SCAN_FINISH;
halbtc_leave_low_power();
if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE)
ex_btc8723b2ant_scan_notify(btcoexist, scan_type);
halbtc_nomal_low_power();
}
void exhalbtc_connect_notify(struct btc_coexist *btcoexist, u8 action)
{
struct rtl_priv *rtlpriv = btcoexist->adapter;
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
u8 asso_type;
if (!halbtc_is_bt_coexist_available(btcoexist))
return;
btcoexist->statistics.cnt_connect_notify++;
if (btcoexist->manual_control)
return;
if (action)
asso_type = BTC_ASSOCIATE_START;
else
asso_type = BTC_ASSOCIATE_FINISH;
halbtc_leave_low_power();
if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE)
ex_btc8723b2ant_connect_notify(btcoexist, asso_type);
}
void exhalbtc_mediastatus_notify(struct btc_coexist *btcoexist,
enum rt_media_status media_status)
{
u8 status;
if (!halbtc_is_bt_coexist_available(btcoexist))
return;
btcoexist->statistics.cnt_media_status_notify++;
if (btcoexist->manual_control)
return;
if (RT_MEDIA_CONNECT == media_status)
status = BTC_MEDIA_CONNECT;
else
status = BTC_MEDIA_DISCONNECT;
halbtc_leave_low_power();
halbtc_nomal_low_power();
}
void exhalbtc_special_packet_notify(struct btc_coexist *btcoexist, u8 pkt_type)
{
struct rtl_priv *rtlpriv = btcoexist->adapter;
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
u8 packet_type;
if (!halbtc_is_bt_coexist_available(btcoexist))
return;
btcoexist->statistics.cnt_special_packet_notify++;
if (btcoexist->manual_control)
return;
packet_type = BTC_PACKET_DHCP;
halbtc_leave_low_power();
if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE)
ex_btc8723b2ant_special_packet_notify(btcoexist,
packet_type);
halbtc_nomal_low_power();
}
void exhalbtc_bt_info_notify(struct btc_coexist *btcoexist,
u8 *tmp_buf, u8 length)
{
struct rtl_priv *rtlpriv = btcoexist->adapter;
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
if (!halbtc_is_bt_coexist_available(btcoexist))
return;
btcoexist->statistics.cnt_bt_info_notify++;
if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE)
ex_btc8723b2ant_bt_info_notify(btcoexist, tmp_buf, length);
}
void exhalbtc_stack_operation_notify(struct btc_coexist *btcoexist, u8 type)
{
u8 stack_op_type;
if (!halbtc_is_bt_coexist_available(btcoexist))
return;
btcoexist->statistics.cnt_stack_operation_notify++;
if (btcoexist->manual_control)
return;
stack_op_type = BTC_STACK_OP_NONE;
halbtc_leave_low_power();
halbtc_nomal_low_power();
}
void exhalbtc_halt_notify(struct btc_coexist *btcoexist)
{
struct rtl_priv *rtlpriv = btcoexist->adapter;
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
if (!halbtc_is_bt_coexist_available(btcoexist))
return;
if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE)
ex_btc8723b2ant_halt_notify(btcoexist);
}
void exhalbtc_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state)
{
if (!halbtc_is_bt_coexist_available(btcoexist))
return;
}
void exhalbtc_periodical(struct btc_coexist *btcoexist)
{
struct rtl_priv *rtlpriv = btcoexist->adapter;
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
if (!halbtc_is_bt_coexist_available(btcoexist))
return;
btcoexist->statistics.cnt_periodical++;
halbtc_leave_low_power();
if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE)
ex_btc8723b2ant_periodical(btcoexist);
halbtc_nomal_low_power();
}
void exhalbtc_dbg_control(struct btc_coexist *btcoexist,
u8 code, u8 len, u8 *data)
{
if (!halbtc_is_bt_coexist_available(btcoexist))
return;
btcoexist->statistics.cnt_dbg_ctrl++;
}
void exhalbtc_stack_update_profile_info(void)
{
}
void exhalbtc_update_min_bt_rssi(char bt_rssi)
{
struct btc_coexist *btcoexist = &gl_bt_coexist;
if (!halbtc_is_bt_coexist_available(btcoexist))
return;
btcoexist->stack_info.min_bt_rssi = bt_rssi;
}
void exhalbtc_set_hci_version(u16 hci_version)
{
struct btc_coexist *btcoexist = &gl_bt_coexist;
if (!halbtc_is_bt_coexist_available(btcoexist))
return;
btcoexist->stack_info.hci_version = hci_version;
}
void exhalbtc_set_bt_patch_version(u16 bt_hci_version, u16 bt_patch_version)
{
struct btc_coexist *btcoexist = &gl_bt_coexist;
if (!halbtc_is_bt_coexist_available(btcoexist))
return;
btcoexist->bt_info.bt_real_fw_ver = bt_patch_version;
btcoexist->bt_info.bt_hci_ver = bt_hci_version;
}
void exhalbtc_set_bt_exist(bool bt_exist)
{
gl_bt_coexist.board_info.bt_exist = bt_exist;
}
void exhalbtc_set_chip_type(u8 chip_type)
{
switch (chip_type) {
default:
case BT_2WIRE:
case BT_ISSC_3WIRE:
case BT_ACCEL:
case BT_RTL8756:
gl_bt_coexist.board_info.bt_chip_type = BTC_CHIP_UNDEF;
break;
case BT_CSR_BC4:
gl_bt_coexist.board_info.bt_chip_type = BTC_CHIP_CSR_BC4;
break;
case BT_CSR_BC8:
gl_bt_coexist.board_info.bt_chip_type = BTC_CHIP_CSR_BC8;
break;
case BT_RTL8723A:
gl_bt_coexist.board_info.bt_chip_type = BTC_CHIP_RTL8723A;
break;
case BT_RTL8821A:
gl_bt_coexist.board_info.bt_chip_type = BTC_CHIP_RTL8821;
break;
case BT_RTL8723B:
gl_bt_coexist.board_info.bt_chip_type = BTC_CHIP_RTL8723B;
break;
}
}
void exhalbtc_set_ant_num(u8 type, u8 ant_num)
{
if (BT_COEX_ANT_TYPE_PG == type) {
gl_bt_coexist.board_info.pg_ant_num = ant_num;
gl_bt_coexist.board_info.btdm_ant_num = ant_num;
} else if (BT_COEX_ANT_TYPE_ANTDIV == type) {
gl_bt_coexist.board_info.btdm_ant_num = ant_num;
}
}
void exhalbtc_display_bt_coex_info(struct btc_coexist *btcoexist)
{
struct rtl_priv *rtlpriv = btcoexist->adapter;
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
if (!halbtc_is_bt_coexist_available(btcoexist))
return;
if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE)
ex_btc8723b2ant_display_coex_info(btcoexist);
}

View file

@ -0,0 +1,545 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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 __HALBTC_OUT_SRC_H__
#define __HALBTC_OUT_SRC_H__
#include "../wifi.h"
#define NORMAL_EXEC false
#define FORCE_EXEC true
#define BTC_RF_A RF90_PATH_A
#define BTC_RF_B RF90_PATH_B
#define BTC_RF_C RF90_PATH_C
#define BTC_RF_D RF90_PATH_D
#define BTC_SMSP SINGLEMAC_SINGLEPHY
#define BTC_DMDP DUALMAC_DUALPHY
#define BTC_DMSP DUALMAC_SINGLEPHY
#define BTC_MP_UNKNOWN 0xff
#define IN
#define OUT
#define BT_TMP_BUF_SIZE 100
#define BT_COEX_ANT_TYPE_PG 0
#define BT_COEX_ANT_TYPE_ANTDIV 1
#define BT_COEX_ANT_TYPE_DETECTED 2
#define BTC_MIMO_PS_STATIC 0
#define BTC_MIMO_PS_DYNAMIC 1
#define BTC_RATE_DISABLE 0
#define BTC_RATE_ENABLE 1
/* single Antenna definition */
#define BTC_ANT_PATH_WIFI 0
#define BTC_ANT_PATH_BT 1
#define BTC_ANT_PATH_PTA 2
/* dual Antenna definition */
#define BTC_ANT_WIFI_AT_MAIN 0
#define BTC_ANT_WIFI_AT_AUX 1
/* coupler Antenna definition */
#define BTC_ANT_WIFI_AT_CPL_MAIN 0
#define BTC_ANT_WIFI_AT_CPL_AUX 1
enum btc_chip_interface {
BTC_INTF_UNKNOWN = 0,
BTC_INTF_PCI = 1,
BTC_INTF_USB = 2,
BTC_INTF_SDIO = 3,
BTC_INTF_GSPI = 4,
BTC_INTF_MAX
};
enum btc_chip_type {
BTC_CHIP_UNDEF = 0,
BTC_CHIP_CSR_BC4 = 1,
BTC_CHIP_CSR_BC8 = 2,
BTC_CHIP_RTL8723A = 3,
BTC_CHIP_RTL8821 = 4,
BTC_CHIP_RTL8723B = 5,
BTC_CHIP_MAX
};
enum btc_msg_type {
BTC_MSG_INTERFACE = 0x0,
BTC_MSG_ALGORITHM = 0x1,
BTC_MSG_MAX
};
extern u32 btc_dbg_type[];
/* following is for BTC_MSG_INTERFACE */
#define INTF_INIT BIT0
#define INTF_NOTIFY BIT2
/* following is for BTC_ALGORITHM */
#define ALGO_BT_RSSI_STATE BIT0
#define ALGO_WIFI_RSSI_STATE BIT1
#define ALGO_BT_MONITOR BIT2
#define ALGO_TRACE BIT3
#define ALGO_TRACE_FW BIT4
#define ALGO_TRACE_FW_DETAIL BIT5
#define ALGO_TRACE_FW_EXEC BIT6
#define ALGO_TRACE_SW BIT7
#define ALGO_TRACE_SW_DETAIL BIT8
#define ALGO_TRACE_SW_EXEC BIT9
/* following is for wifi link status */
#define WIFI_STA_CONNECTED BIT0
#define WIFI_AP_CONNECTED BIT1
#define WIFI_HS_CONNECTED BIT2
#define WIFI_P2P_GO_CONNECTED BIT3
#define WIFI_P2P_GC_CONNECTED BIT4
#define BTC_PRINT(dbgtype, dbgflag, printstr, ...) \
do { \
if (unlikely(btc_dbg_type[dbgtype] & dbgflag)) {\
printk(printstr, ##__VA_ARGS__); \
} \
} while (0)
#define BTC_RSSI_HIGH(_rssi_) \
((_rssi_ == BTC_RSSI_STATE_HIGH || \
_rssi_ == BTC_RSSI_STATE_STAY_HIGH) ? true : false)
#define BTC_RSSI_MEDIUM(_rssi_) \
((_rssi_ == BTC_RSSI_STATE_MEDIUM || \
_rssi_ == BTC_RSSI_STATE_STAY_MEDIUM) ? true : false)
#define BTC_RSSI_LOW(_rssi_) \
((_rssi_ == BTC_RSSI_STATE_LOW || \
_rssi_ == BTC_RSSI_STATE_STAY_LOW) ? true : false)
enum btc_power_save_type {
BTC_PS_WIFI_NATIVE = 0,
BTC_PS_LPS_ON = 1,
BTC_PS_LPS_OFF = 2,
BTC_PS_LPS_MAX
};
struct btc_board_info {
/* The following is some board information */
u8 bt_chip_type;
u8 pg_ant_num; /* pg ant number */
u8 btdm_ant_num; /* ant number for btdm */
u8 btdm_ant_pos;
bool bt_exist;
};
enum btc_dbg_opcode {
BTC_DBG_SET_COEX_NORMAL = 0x0,
BTC_DBG_SET_COEX_WIFI_ONLY = 0x1,
BTC_DBG_SET_COEX_BT_ONLY = 0x2,
BTC_DBG_MAX
};
enum btc_rssi_state {
BTC_RSSI_STATE_HIGH = 0x0,
BTC_RSSI_STATE_MEDIUM = 0x1,
BTC_RSSI_STATE_LOW = 0x2,
BTC_RSSI_STATE_STAY_HIGH = 0x3,
BTC_RSSI_STATE_STAY_MEDIUM = 0x4,
BTC_RSSI_STATE_STAY_LOW = 0x5,
BTC_RSSI_MAX
};
enum btc_wifi_role {
BTC_ROLE_STATION = 0x0,
BTC_ROLE_AP = 0x1,
BTC_ROLE_IBSS = 0x2,
BTC_ROLE_HS_MODE = 0x3,
BTC_ROLE_MAX
};
enum btc_wifi_bw_mode {
BTC_WIFI_BW_LEGACY = 0x0,
BTC_WIFI_BW_HT20 = 0x1,
BTC_WIFI_BW_HT40 = 0x2,
BTC_WIFI_BW_MAX
};
enum btc_wifi_traffic_dir {
BTC_WIFI_TRAFFIC_TX = 0x0,
BTC_WIFI_TRAFFIC_RX = 0x1,
BTC_WIFI_TRAFFIC_MAX
};
enum btc_wifi_pnp {
BTC_WIFI_PNP_WAKE_UP = 0x0,
BTC_WIFI_PNP_SLEEP = 0x1,
BTC_WIFI_PNP_MAX
};
enum btc_get_type {
/* type bool */
BTC_GET_BL_HS_OPERATION,
BTC_GET_BL_HS_CONNECTING,
BTC_GET_BL_WIFI_CONNECTED,
BTC_GET_BL_WIFI_BUSY,
BTC_GET_BL_WIFI_SCAN,
BTC_GET_BL_WIFI_LINK,
BTC_GET_BL_WIFI_DHCP,
BTC_GET_BL_WIFI_SOFTAP_IDLE,
BTC_GET_BL_WIFI_SOFTAP_LINKING,
BTC_GET_BL_WIFI_IN_EARLY_SUSPEND,
BTC_GET_BL_WIFI_ROAM,
BTC_GET_BL_WIFI_4_WAY_PROGRESS,
BTC_GET_BL_WIFI_UNDER_5G,
BTC_GET_BL_WIFI_AP_MODE_ENABLE,
BTC_GET_BL_WIFI_ENABLE_ENCRYPTION,
BTC_GET_BL_WIFI_UNDER_B_MODE,
BTC_GET_BL_EXT_SWITCH,
/* type s4Byte */
BTC_GET_S4_WIFI_RSSI,
BTC_GET_S4_HS_RSSI,
/* type u32 */
BTC_GET_U4_WIFI_BW,
BTC_GET_U4_WIFI_TRAFFIC_DIRECTION,
BTC_GET_U4_WIFI_FW_VER,
BTC_GET_U4_WIFI_LINK_STATUS,
BTC_GET_U4_BT_PATCH_VER,
/* type u1Byte */
BTC_GET_U1_WIFI_DOT11_CHNL,
BTC_GET_U1_WIFI_CENTRAL_CHNL,
BTC_GET_U1_WIFI_HS_CHNL,
BTC_GET_U1_MAC_PHY_MODE,
BTC_GET_U1_AP_NUM,
/* for 1Ant */
BTC_GET_U1_LPS_MODE,
BTC_GET_BL_BT_SCO_BUSY,
/* for test mode */
BTC_GET_DRIVER_TEST_CFG,
BTC_GET_MAX
};
enum btc_set_type {
/* type bool */
BTC_SET_BL_BT_DISABLE,
BTC_SET_BL_BT_TRAFFIC_BUSY,
BTC_SET_BL_BT_LIMITED_DIG,
BTC_SET_BL_FORCE_TO_ROAM,
BTC_SET_BL_TO_REJ_AP_AGG_PKT,
BTC_SET_BL_BT_CTRL_AGG_SIZE,
BTC_SET_BL_INC_SCAN_DEV_NUM,
/* type u1Byte */
BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON,
BTC_SET_UI_SCAN_SIG_COMPENSATION,
BTC_SET_U1_AGG_BUF_SIZE,
/* type trigger some action */
BTC_SET_ACT_GET_BT_RSSI,
BTC_SET_ACT_AGGREGATE_CTRL,
/********* for 1Ant **********/
/* type bool */
BTC_SET_BL_BT_SCO_BUSY,
/* type u1Byte */
BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE,
BTC_SET_U1_LPS_VAL,
BTC_SET_U1_RPWM_VAL,
BTC_SET_U1_1ANT_LPS,
BTC_SET_U1_1ANT_RPWM,
/* type trigger some action */
BTC_SET_ACT_LEAVE_LPS,
BTC_SET_ACT_ENTER_LPS,
BTC_SET_ACT_NORMAL_LPS,
BTC_SET_ACT_INC_FORCE_EXEC_PWR_CMD_CNT,
BTC_SET_ACT_DISABLE_LOW_POWER,
BTC_SET_ACT_UPDATE_ra_mask,
BTC_SET_ACT_SEND_MIMO_PS,
/* BT Coex related */
BTC_SET_ACT_CTRL_BT_INFO,
BTC_SET_ACT_CTRL_BT_COEX,
/***************************/
BTC_SET_MAX
};
enum btc_dbg_disp_type {
BTC_DBG_DISP_COEX_STATISTICS = 0x0,
BTC_DBG_DISP_BT_LINK_INFO = 0x1,
BTC_DBG_DISP_BT_FW_VER = 0x2,
BTC_DBG_DISP_FW_PWR_MODE_CMD = 0x3,
BTC_DBG_DISP_MAX
};
enum btc_notify_type_ips {
BTC_IPS_LEAVE = 0x0,
BTC_IPS_ENTER = 0x1,
BTC_IPS_MAX
};
enum btc_notify_type_lps {
BTC_LPS_DISABLE = 0x0,
BTC_LPS_ENABLE = 0x1,
BTC_LPS_MAX
};
enum btc_notify_type_scan {
BTC_SCAN_FINISH = 0x0,
BTC_SCAN_START = 0x1,
BTC_SCAN_MAX
};
enum btc_notify_type_associate {
BTC_ASSOCIATE_FINISH = 0x0,
BTC_ASSOCIATE_START = 0x1,
BTC_ASSOCIATE_MAX
};
enum btc_notify_type_media_status {
BTC_MEDIA_DISCONNECT = 0x0,
BTC_MEDIA_CONNECT = 0x1,
BTC_MEDIA_MAX
};
enum btc_notify_type_special_packet {
BTC_PACKET_UNKNOWN = 0x0,
BTC_PACKET_DHCP = 0x1,
BTC_PACKET_ARP = 0x2,
BTC_PACKET_EAPOL = 0x3,
BTC_PACKET_MAX
};
enum hci_ext_bt_operation {
HCI_BT_OP_NONE = 0x0,
HCI_BT_OP_INQUIRY_START = 0x1,
HCI_BT_OP_INQUIRY_FINISH = 0x2,
HCI_BT_OP_PAGING_START = 0x3,
HCI_BT_OP_PAGING_SUCCESS = 0x4,
HCI_BT_OP_PAGING_UNSUCCESS = 0x5,
HCI_BT_OP_PAIRING_START = 0x6,
HCI_BT_OP_PAIRING_FINISH = 0x7,
HCI_BT_OP_BT_DEV_ENABLE = 0x8,
HCI_BT_OP_BT_DEV_DISABLE = 0x9,
HCI_BT_OP_MAX
};
enum btc_notify_type_stack_operation {
BTC_STACK_OP_NONE = 0x0,
BTC_STACK_OP_INQ_PAGE_PAIR_START = 0x1,
BTC_STACK_OP_INQ_PAGE_PAIR_FINISH = 0x2,
BTC_STACK_OP_MAX
};
typedef u8 (*bfp_btc_r1)(void *btc_context, u32 reg_addr);
typedef u16 (*bfp_btc_r2)(void *btc_context, u32 reg_addr);
typedef u32 (*bfp_btc_r4)(void *btc_context, u32 reg_addr);
typedef void (*bfp_btc_w1)(void *btc_context, u32 reg_addr, u32 data);
typedef void (*bfp_btc_w1_bit_mak)(void *btc_context, u32 reg_addr,
u32 bit_mask, u8 data1b);
typedef void (*bfp_btc_w2)(void *btc_context, u32 reg_addr, u16 data);
typedef void (*bfp_btc_w4)(void *btc_context, u32 reg_addr, u32 data);
typedef void (*bfp_btc_wr_1byte_bit_mask)(void *btc_context, u32 reg_addr,
u8 bit_mask, u8 data);
typedef void (*bfp_btc_set_bb_reg)(void *btc_context, u32 reg_addr,
u32 bit_mask, u32 data);
typedef u32 (*bfp_btc_get_bb_reg)(void *btc_context, u32 reg_addr,
u32 bit_mask);
typedef void (*bfp_btc_set_rf_reg)(void *btc_context, u8 rf_path, u32 reg_addr,
u32 bit_mask, u32 data);
typedef u32 (*bfp_btc_get_rf_reg)(void *btc_context, u8 rf_path,
u32 reg_addr, u32 bit_mask);
typedef void (*bfp_btc_fill_h2c)(void *btc_context, u8 element_id,
u32 cmd_len, u8 *cmd_buffer);
typedef bool (*bfp_btc_get)(void *btcoexist, u8 get_type, void *out_buf);
typedef bool (*bfp_btc_set)(void *btcoexist, u8 set_type, void *in_buf);
typedef void (*bfp_btc_disp_dbg_msg)(void *btcoexist, u8 disp_type);
struct btc_bt_info {
bool bt_disabled;
u8 rssi_adjust_for_agc_table_on;
u8 rssi_adjust_for_1ant_coex_type;
bool bt_busy;
u8 agg_buf_size;
bool limited_dig;
bool reject_agg_pkt;
bool bt_ctrl_buf_size;
bool increase_scan_dev_num;
u16 bt_hci_ver;
u16 bt_real_fw_ver;
u8 bt_fw_ver;
bool bt_disable_low_pwr;
/* the following is for 1Ant solution */
bool bt_ctrl_lps;
bool bt_pwr_save_mode;
bool bt_lps_on;
bool force_to_roam;
u8 force_exec_pwr_cmd_cnt;
u8 lps_val;
u8 rpwm_val;
u32 ra_mask;
};
struct btc_stack_info {
bool profile_notified;
u16 hci_version; /* stack hci version */
u8 num_of_link;
bool bt_link_exist;
bool sco_exist;
bool acl_exist;
bool a2dp_exist;
bool hid_exist;
u8 num_of_hid;
bool pan_exist;
bool unknown_acl_exist;
char min_bt_rssi;
};
struct btc_statistics {
u32 cnt_bind;
u32 cnt_init_hw_config;
u32 cnt_init_coex_dm;
u32 cnt_ips_notify;
u32 cnt_lps_notify;
u32 cnt_scan_notify;
u32 cnt_connect_notify;
u32 cnt_media_status_notify;
u32 cnt_special_packet_notify;
u32 cnt_bt_info_notify;
u32 cnt_periodical;
u32 cnt_coex_dm_switch;
u32 cnt_stack_operation_notify;
u32 cnt_dbg_ctrl;
};
struct btc_bt_link_info {
bool bt_link_exist;
bool sco_exist;
bool sco_only;
bool a2dp_exist;
bool a2dp_only;
bool hid_exist;
bool hid_only;
bool pan_exist;
bool pan_only;
};
enum btc_antenna_pos {
BTC_ANTENNA_AT_MAIN_PORT = 0x1,
BTC_ANTENNA_AT_AUX_PORT = 0x2,
};
struct btc_coexist {
/* make sure only one adapter can bind the data context */
bool binded;
/* default adapter */
void *adapter;
struct btc_board_info board_info;
/* some bt info referenced by non-bt module */
struct btc_bt_info bt_info;
struct btc_stack_info stack_info;
enum btc_chip_interface chip_interface;
struct btc_bt_link_info bt_link_info;
bool initilized;
bool stop_coex_dm;
bool manual_control;
struct btc_statistics statistics;
u8 pwr_mode_val[10];
/* function pointers - io related */
bfp_btc_r1 btc_read_1byte;
bfp_btc_w1 btc_write_1byte;
bfp_btc_w1_bit_mak btc_write_1byte_bitmask;
bfp_btc_r2 btc_read_2byte;
bfp_btc_w2 btc_write_2byte;
bfp_btc_r4 btc_read_4byte;
bfp_btc_w4 btc_write_4byte;
bfp_btc_set_bb_reg btc_set_bb_reg;
bfp_btc_get_bb_reg btc_get_bb_reg;
bfp_btc_set_rf_reg btc_set_rf_reg;
bfp_btc_get_rf_reg btc_get_rf_reg;
bfp_btc_fill_h2c btc_fill_h2c;
bfp_btc_disp_dbg_msg btc_disp_dbg_msg;
bfp_btc_get btc_get;
bfp_btc_set btc_set;
};
bool halbtc_is_wifi_uplink(struct rtl_priv *adapter);
extern struct btc_coexist gl_bt_coexist;
bool exhalbtc_initlize_variables(struct rtl_priv *adapter);
void exhalbtc_init_hw_config(struct btc_coexist *btcoexist);
void exhalbtc_init_coex_dm(struct btc_coexist *btcoexist);
void exhalbtc_ips_notify(struct btc_coexist *btcoexist, u8 type);
void exhalbtc_lps_notify(struct btc_coexist *btcoexist, u8 type);
void exhalbtc_scan_notify(struct btc_coexist *btcoexist, u8 type);
void exhalbtc_connect_notify(struct btc_coexist *btcoexist, u8 action);
void exhalbtc_mediastatus_notify(struct btc_coexist *btcoexist,
enum rt_media_status media_status);
void exhalbtc_special_packet_notify(struct btc_coexist *btcoexist, u8 pkt_type);
void exhalbtc_bt_info_notify(struct btc_coexist *btcoexist, u8 *tmp_buf,
u8 length);
void exhalbtc_stack_operation_notify(struct btc_coexist *btcoexist, u8 type);
void exhalbtc_halt_notify(struct btc_coexist *btcoexist);
void exhalbtc_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state);
void exhalbtc_coex_dm_switch(struct btc_coexist *btcoexist);
void exhalbtc_periodical(struct btc_coexist *btcoexist);
void exhalbtc_dbg_control(struct btc_coexist *btcoexist, u8 code, u8 len,
u8 *data);
void exhalbtc_stack_update_profile_info(void);
void exhalbtc_set_hci_version(u16 hci_version);
void exhalbtc_set_bt_patch_version(u16 bt_hci_version, u16 bt_patch_version);
void exhalbtc_update_min_bt_rssi(char bt_rssi);
void exhalbtc_set_bt_exist(bool bt_exist);
void exhalbtc_set_chip_type(u8 chip_type);
void exhalbtc_set_ant_num(u8 type, u8 ant_num);
void exhalbtc_display_bt_coex_info(struct btc_coexist *btcoexist);
void exhalbtc_signal_compensation(struct btc_coexist *btcoexist,
u8 *rssi_wifi, u8 *rssi_bt);
void exhalbtc_lps_leave(struct btc_coexist *btcoexist);
void exhalbtc_low_wifi_traffic_notify(struct btc_coexist *btcoexist);
#endif

View file

@ -0,0 +1,231 @@
/******************************************************************************
*
* Copyright(c) 2009-2013 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 "../wifi.h"
#include <linux/vmalloc.h>
#include <linux/module.h>
#include "rtl_btc.h"
#include "halbt_precomp.h"
static struct rtl_btc_ops rtl_btc_operation = {
.btc_init_variables = rtl_btc_init_variables,
.btc_init_hal_vars = rtl_btc_init_hal_vars,
.btc_init_hw_config = rtl_btc_init_hw_config,
.btc_ips_notify = rtl_btc_ips_notify,
.btc_lps_notify = rtl_btc_lps_notify,
.btc_scan_notify = rtl_btc_scan_notify,
.btc_connect_notify = rtl_btc_connect_notify,
.btc_mediastatus_notify = rtl_btc_mediastatus_notify,
.btc_periodical = rtl_btc_periodical,
.btc_halt_notify = rtl_btc_halt_notify,
.btc_btinfo_notify = rtl_btc_btinfo_notify,
.btc_is_limited_dig = rtl_btc_is_limited_dig,
.btc_is_disable_edca_turbo = rtl_btc_is_disable_edca_turbo,
.btc_is_bt_disabled = rtl_btc_is_bt_disabled,
.btc_special_packet_notify = rtl_btc_special_packet_notify,
};
void rtl_btc_init_variables(struct rtl_priv *rtlpriv)
{
exhalbtc_initlize_variables(rtlpriv);
}
void rtl_btc_init_hal_vars(struct rtl_priv *rtlpriv)
{
u8 ant_num;
u8 bt_exist;
u8 bt_type;
ant_num = rtl_get_hwpg_ant_num(rtlpriv);
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"%s, antNum is %d\n", __func__, ant_num);
bt_exist = rtl_get_hwpg_bt_exist(rtlpriv);
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"%s, bt_exist is %d\n", __func__, bt_exist);
exhalbtc_set_bt_exist(bt_exist);
bt_type = rtl_get_hwpg_bt_type(rtlpriv);
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "%s, bt_type is %d\n",
__func__, bt_type);
exhalbtc_set_chip_type(bt_type);
exhalbtc_set_ant_num(BT_COEX_ANT_TYPE_PG, ant_num);
}
void rtl_btc_init_hw_config(struct rtl_priv *rtlpriv)
{
exhalbtc_init_hw_config(&gl_bt_coexist);
exhalbtc_init_coex_dm(&gl_bt_coexist);
}
void rtl_btc_ips_notify(struct rtl_priv *rtlpriv, u8 type)
{
exhalbtc_ips_notify(&gl_bt_coexist, type);
}
void rtl_btc_lps_notify(struct rtl_priv *rtlpriv, u8 type)
{
exhalbtc_lps_notify(&gl_bt_coexist, type);
}
void rtl_btc_scan_notify(struct rtl_priv *rtlpriv, u8 scantype)
{
exhalbtc_scan_notify(&gl_bt_coexist, scantype);
}
void rtl_btc_connect_notify(struct rtl_priv *rtlpriv, u8 action)
{
exhalbtc_connect_notify(&gl_bt_coexist, action);
}
void rtl_btc_mediastatus_notify(struct rtl_priv *rtlpriv,
enum rt_media_status mstatus)
{
exhalbtc_mediastatus_notify(&gl_bt_coexist, mstatus);
}
void rtl_btc_periodical(struct rtl_priv *rtlpriv)
{
/*rtl_bt_dm_monitor();*/
exhalbtc_periodical(&gl_bt_coexist);
}
void rtl_btc_halt_notify(void)
{
exhalbtc_halt_notify(&gl_bt_coexist);
}
void rtl_btc_btinfo_notify(struct rtl_priv *rtlpriv, u8 *tmp_buf, u8 length)
{
exhalbtc_bt_info_notify(&gl_bt_coexist, tmp_buf, length);
}
bool rtl_btc_is_limited_dig(struct rtl_priv *rtlpriv)
{
return gl_bt_coexist.bt_info.limited_dig;
}
bool rtl_btc_is_disable_edca_turbo(struct rtl_priv *rtlpriv)
{
bool bt_change_edca = false;
u32 cur_edca_val;
u32 edca_bt_hs_uplink = 0x5ea42b, edca_bt_hs_downlink = 0x5ea42b;
u32 edca_hs;
u32 edca_addr = 0x504;
cur_edca_val = rtl_read_dword(rtlpriv, edca_addr);
if (halbtc_is_wifi_uplink(rtlpriv)) {
if (cur_edca_val != edca_bt_hs_uplink) {
edca_hs = edca_bt_hs_uplink;
bt_change_edca = true;
}
} else {
if (cur_edca_val != edca_bt_hs_downlink) {
edca_hs = edca_bt_hs_downlink;
bt_change_edca = true;
}
}
if (bt_change_edca)
rtl_write_dword(rtlpriv, edca_addr, edca_hs);
return true;
}
bool rtl_btc_is_bt_disabled(struct rtl_priv *rtlpriv)
{
/* It seems 'bt_disabled' is never be initialized or set. */
if (gl_bt_coexist.bt_info.bt_disabled)
return true;
else
return false;
}
void rtl_btc_special_packet_notify(struct rtl_priv *rtlpriv, u8 pkt_type)
{
return exhalbtc_special_packet_notify(&gl_bt_coexist, pkt_type);
}
struct rtl_btc_ops *rtl_btc_get_ops_pointer(void)
{
return &rtl_btc_operation;
}
EXPORT_SYMBOL(rtl_btc_get_ops_pointer);
u8 rtl_get_hwpg_ant_num(struct rtl_priv *rtlpriv)
{
u8 num;
if (rtlpriv->btcoexist.btc_info.ant_num == ANT_X2)
num = 2;
else
num = 1;
return num;
}
enum rt_media_status mgnt_link_status_query(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
enum rt_media_status m_status = RT_MEDIA_DISCONNECT;
u8 bibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? 1 : 0;
if (bibss || rtlpriv->mac80211.link_state >= MAC80211_LINKED)
m_status = RT_MEDIA_CONNECT;
return m_status;
}
u8 rtl_get_hwpg_bt_exist(struct rtl_priv *rtlpriv)
{
return rtlpriv->btcoexist.btc_info.btcoexist;
}
u8 rtl_get_hwpg_bt_type(struct rtl_priv *rtlpriv)
{
return rtlpriv->btcoexist.btc_info.bt_type;
}
MODULE_AUTHOR("Page He <page_he@realsil.com.cn>");
MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
MODULE_AUTHOR("Larry Finger <Larry.FInger@lwfinger.net>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Realtek 802.11n PCI wireless core");
static int __init rtl_btcoexist_module_init(void)
{
return 0;
}
static void __exit rtl_btcoexist_module_exit(void)
{
return;
}
module_init(rtl_btcoexist_module_init);
module_exit(rtl_btcoexist_module_exit);

View file

@ -0,0 +1,54 @@
/******************************************************************************
*
* Copyright(c) 2009-2010 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 __RTL_BTC_H__
#define __RTL_BTC_H__
#include "halbt_precomp.h"
void rtl_btc_init_variables(struct rtl_priv *rtlpriv);
void rtl_btc_init_hal_vars(struct rtl_priv *rtlpriv);
void rtl_btc_init_hw_config(struct rtl_priv *rtlpriv);
void rtl_btc_ips_notify(struct rtl_priv *rtlpriv, u8 type);
void rtl_btc_lps_notify(struct rtl_priv *rtlpriv, u8 type);
void rtl_btc_scan_notify(struct rtl_priv *rtlpriv, u8 scantype);
void rtl_btc_connect_notify(struct rtl_priv *rtlpriv, u8 action);
void rtl_btc_mediastatus_notify(struct rtl_priv *rtlpriv,
enum rt_media_status mstatus);
void rtl_btc_periodical(struct rtl_priv *rtlpriv);
void rtl_btc_halt_notify(void);
void rtl_btc_btinfo_notify(struct rtl_priv *rtlpriv, u8 *tmpbuf, u8 length);
bool rtl_btc_is_limited_dig(struct rtl_priv *rtlpriv);
bool rtl_btc_is_disable_edca_turbo(struct rtl_priv *rtlpriv);
bool rtl_btc_is_bt_disabled(struct rtl_priv *rtlpriv);
void rtl_btc_special_packet_notify(struct rtl_priv *rtlpriv, u8 pkt_type);
struct rtl_btc_ops *rtl_btc_get_ops_pointer(void);
u8 rtl_get_hwpg_ant_num(struct rtl_priv *rtlpriv);
u8 rtl_get_hwpg_bt_exist(struct rtl_priv *rtlpriv);
u8 rtl_get_hwpg_bt_type(struct rtl_priv *rtlpriv);
enum rt_media_status mgnt_link_status_query(struct ieee80211_hw *hw);
#endif

View file

@ -0,0 +1,347 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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 "wifi.h"
#include "cam.h"
#include <linux/export.h>
void rtl_cam_reset_sec_info(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
rtlpriv->sec.use_defaultkey = false;
rtlpriv->sec.pairwise_enc_algorithm = NO_ENCRYPTION;
rtlpriv->sec.group_enc_algorithm = NO_ENCRYPTION;
memset(rtlpriv->sec.key_buf, 0, KEY_BUF_SIZE * MAX_KEY_LEN);
memset(rtlpriv->sec.key_len, 0, KEY_BUF_SIZE);
rtlpriv->sec.pairwise_key = NULL;
}
static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no,
u8 *mac_addr, u8 *key_cont_128, u16 us_config)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u32 target_command;
u32 target_content = 0;
u8 entry_i;
RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_DMESG, "Key content :",
key_cont_128, 16);
for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
target_command = entry_i + CAM_CONTENT_COUNT * entry_no;
target_command = target_command | BIT(31) | BIT(16);
if (entry_i == 0) {
target_content = (u32) (*(mac_addr + 0)) << 16 |
(u32) (*(mac_addr + 1)) << 24 | (u32) us_config;
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI],
target_content);
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
target_command);
RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
"WRITE %x: %x\n",
rtlpriv->cfg->maps[WCAMI], target_content);
RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
"The Key ID is %d\n", entry_no);
RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
"WRITE %x: %x\n",
rtlpriv->cfg->maps[RWCAM], target_command);
} else if (entry_i == 1) {
target_content = (u32) (*(mac_addr + 5)) << 24 |
(u32) (*(mac_addr + 4)) << 16 |
(u32) (*(mac_addr + 3)) << 8 |
(u32) (*(mac_addr + 2));
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI],
target_content);
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
target_command);
RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
"WRITE A4: %x\n", target_content);
RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
"WRITE A0: %x\n", target_command);
} else {
target_content =
(u32) (*(key_cont_128 + (entry_i * 4 - 8) + 3)) <<
24 | (u32) (*(key_cont_128 + (entry_i * 4 - 8) + 2))
<< 16 |
(u32) (*(key_cont_128 + (entry_i * 4 - 8) + 1)) << 8
| (u32) (*(key_cont_128 + (entry_i * 4 - 8) + 0));
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI],
target_content);
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
target_command);
udelay(100);
RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
"WRITE A4: %x\n", target_content);
RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
"WRITE A0: %x\n", target_command);
}
}
RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
"after set key, usconfig:%x\n", us_config);
}
u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr,
u32 ul_key_id, u32 ul_entry_idx, u32 ul_enc_alg,
u32 ul_default_key, u8 *key_content)
{
u32 us_config;
struct rtl_priv *rtlpriv = rtl_priv(hw);
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
"EntryNo:%x, ulKeyId=%x, ulEncAlg=%x, ulUseDK=%x MacAddr %pM\n",
ul_entry_idx, ul_key_id, ul_enc_alg,
ul_default_key, mac_addr);
if (ul_key_id == TOTAL_CAM_ENTRY) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
"ulKeyId exceed!\n");
return 0;
}
if (ul_default_key == 1)
us_config = CFG_VALID | ((u16) (ul_enc_alg) << 2);
else
us_config = CFG_VALID | ((ul_enc_alg) << 2) | ul_key_id;
rtl_cam_program_entry(hw, ul_entry_idx, mac_addr,
(u8 *)key_content, us_config);
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "end\n");
return 1;
}
EXPORT_SYMBOL(rtl_cam_add_one_entry);
int rtl_cam_delete_one_entry(struct ieee80211_hw *hw,
u8 *mac_addr, u32 ul_key_id)
{
u32 ul_command;
struct rtl_priv *rtlpriv = rtl_priv(hw);
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "key_idx:%d\n", ul_key_id);
ul_command = ul_key_id * CAM_CONTENT_COUNT;
ul_command = ul_command | BIT(31) | BIT(16);
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], 0);
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command);
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
"rtl_cam_delete_one_entry(): WRITE A4: %x\n", 0);
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
"rtl_cam_delete_one_entry(): WRITE A0: %x\n", ul_command);
return 0;
}
EXPORT_SYMBOL(rtl_cam_delete_one_entry);
void rtl_cam_reset_all_entry(struct ieee80211_hw *hw)
{
u32 ul_command;
struct rtl_priv *rtlpriv = rtl_priv(hw);
ul_command = BIT(31) | BIT(30);
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command);
}
EXPORT_SYMBOL(rtl_cam_reset_all_entry);
void rtl_cam_mark_invalid(struct ieee80211_hw *hw, u8 uc_index)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u32 ul_command;
u32 ul_content;
u32 ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_AES];
switch (rtlpriv->sec.pairwise_enc_algorithm) {
case WEP40_ENCRYPTION:
ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_WEP40];
break;
case WEP104_ENCRYPTION:
ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_WEP104];
break;
case TKIP_ENCRYPTION:
ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_TKIP];
break;
case AESCCMP_ENCRYPTION:
ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_AES];
break;
default:
ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_AES];
}
ul_content = (uc_index & 3) | ((u16) (ul_enc_algo) << 2);
ul_content |= BIT(15);
ul_command = CAM_CONTENT_COUNT * uc_index;
ul_command = ul_command | BIT(31) | BIT(16);
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], ul_content);
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command);
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
"rtl_cam_mark_invalid(): WRITE A4: %x\n", ul_content);
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
"rtl_cam_mark_invalid(): WRITE A0: %x\n", ul_command);
}
EXPORT_SYMBOL(rtl_cam_mark_invalid);
void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u32 ul_command;
u32 ul_content;
u32 ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_AES];
u8 entry_i;
switch (rtlpriv->sec.pairwise_enc_algorithm) {
case WEP40_ENCRYPTION:
ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_WEP40];
break;
case WEP104_ENCRYPTION:
ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_WEP104];
break;
case TKIP_ENCRYPTION:
ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_TKIP];
break;
case AESCCMP_ENCRYPTION:
ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_AES];
break;
default:
ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_AES];
}
for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
if (entry_i == 0) {
ul_content =
(uc_index & 0x03) | ((u16) (ul_encalgo) << 2);
ul_content |= BIT(15);
} else {
ul_content = 0;
}
ul_command = CAM_CONTENT_COUNT * uc_index + entry_i;
ul_command = ul_command | BIT(31) | BIT(16);
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], ul_content);
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command);
RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
"rtl_cam_empty_entry(): WRITE A4: %x\n",
ul_content);
RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
"rtl_cam_empty_entry(): WRITE A0: %x\n",
ul_command);
}
}
EXPORT_SYMBOL(rtl_cam_empty_entry);
u8 rtl_cam_get_free_entry(struct ieee80211_hw *hw, u8 *sta_addr)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u32 bitmap = (rtlpriv->sec.hwsec_cam_bitmap) >> 4;
u8 entry_idx = 0;
u8 i, *addr;
if (NULL == sta_addr) {
RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG,
"sta_addr is NULL.\n");
return TOTAL_CAM_ENTRY;
}
/* Does STA already exist? */
for (i = 4; i < TOTAL_CAM_ENTRY; i++) {
addr = rtlpriv->sec.hwsec_cam_sta_addr[i];
if (ether_addr_equal_unaligned(addr, sta_addr))
return i;
}
/* Get a free CAM entry. */
for (entry_idx = 4; entry_idx < TOTAL_CAM_ENTRY; entry_idx++) {
if ((bitmap & BIT(0)) == 0) {
RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG,
"-----hwsec_cam_bitmap: 0x%x entry_idx=%d\n",
rtlpriv->sec.hwsec_cam_bitmap, entry_idx);
rtlpriv->sec.hwsec_cam_bitmap |= BIT(0) << entry_idx;
memcpy(rtlpriv->sec.hwsec_cam_sta_addr[entry_idx],
sta_addr, ETH_ALEN);
return entry_idx;
}
bitmap = bitmap >> 1;
}
return TOTAL_CAM_ENTRY;
}
EXPORT_SYMBOL(rtl_cam_get_free_entry);
void rtl_cam_del_entry(struct ieee80211_hw *hw, u8 *sta_addr)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u32 bitmap;
u8 i, *addr;
if (NULL == sta_addr) {
RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG,
"sta_addr is NULL.\n");
return;
}
if (is_zero_ether_addr(sta_addr)) {
RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG,
"sta_addr is %pM\n", sta_addr);
return;
}
/* Does STA already exist? */
for (i = 4; i < TOTAL_CAM_ENTRY; i++) {
addr = rtlpriv->sec.hwsec_cam_sta_addr[i];
bitmap = (rtlpriv->sec.hwsec_cam_bitmap) >> i;
if (((bitmap & BIT(0)) == BIT(0)) &&
(ether_addr_equal_unaligned(addr, sta_addr))) {
/* Remove from HW Security CAM */
eth_zero_addr(rtlpriv->sec.hwsec_cam_sta_addr[i]);
rtlpriv->sec.hwsec_cam_bitmap &= ~(BIT(0) << i);
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
"&&&&&&&&&del entry %d\n", i);
}
}
return;
}
EXPORT_SYMBOL(rtl_cam_del_entry);

View file

@ -0,0 +1,52 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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 __RTL_CAM_H_
#define __RTL_CAM_H_
#define CAM_CONTENT_COUNT 8
#define CFG_DEFAULT_KEY BIT(5)
#define CFG_VALID BIT(15)
#define PAIRWISE_KEYIDX 0
#define CAM_PAIRWISE_KEY_POSITION 4
#define CAM_CONFIG_USEDK 1
#define CAM_CONFIG_NO_USEDK 0
void rtl_cam_reset_all_entry(struct ieee80211_hw *hw);
u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr,
u32 ul_key_id, u32 ul_entry_idx, u32 ul_enc_alg,
u32 ul_default_key, u8 *key_content);
int rtl_cam_delete_one_entry(struct ieee80211_hw *hw, u8 *mac_addr,
u32 ul_key_id);
void rtl_cam_mark_invalid(struct ieee80211_hw *hw, u8 uc_index);
void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index);
void rtl_cam_reset_sec_info(struct ieee80211_hw *hw);
u8 rtl_cam_get_free_entry(struct ieee80211_hw *hw, u8 *sta_addr);
void rtl_cam_del_entry(struct ieee80211_hw *hw, u8 *sta_addr);
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,47 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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 __RTL_CORE_H__
#define __RTL_CORE_H__
#define RTL_SUPPORTED_FILTERS \
(FIF_PROMISC_IN_BSS | \
FIF_ALLMULTI | FIF_CONTROL | \
FIF_OTHER_BSS | \
FIF_FCSFAIL | \
FIF_BCN_PRBRESP_PROMISC)
#define RTL_SUPPORTED_CTRL_FILTER 0xFF
extern const struct ieee80211_ops rtl_ops;
void rtl_fw_cb(const struct firmware *firmware, void *context);
void rtl_addr_delay(u32 addr);
void rtl_rfreg_delay(struct ieee80211_hw *hw, enum radio_path rfpath, u32 addr,
u32 mask, u32 data);
void rtl_bb_delay(struct ieee80211_hw *hw, u32 addr, u32 data);
bool rtl_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb);
bool rtl_btc_status_false(void);
#endif

View file

@ -0,0 +1,50 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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 "wifi.h"
#include <linux/moduleparam.h>
void rtl_dbgp_flag_init(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u8 i;
rtlpriv->dbg.global_debugcomponents =
COMP_ERR | COMP_FW | COMP_INIT | COMP_RECV | COMP_SEND |
COMP_MLME | COMP_SCAN | COMP_INTR | COMP_LED | COMP_SEC |
COMP_BEACON | COMP_RATE | COMP_RXDESC | COMP_DIG | COMP_TXAGC |
COMP_POWER | COMP_POWER_TRACKING | COMP_BB_POWERSAVING | COMP_SWAS |
COMP_RF | COMP_TURBO | COMP_RATR | COMP_CMD |
COMP_EFUSE | COMP_QOS | COMP_MAC80211 | COMP_REGD | COMP_CHAN |
COMP_EASY_CONCURRENT | COMP_EFUSE | COMP_QOS | COMP_MAC80211 |
COMP_REGD | COMP_CHAN | COMP_BT_COEXIST;
for (i = 0; i < DBGP_TYPE_MAX; i++)
rtlpriv->dbg.dbgp_type[i] = 0;
/*Init Debug flag enable condition */
}
EXPORT_SYMBOL_GPL(rtl_dbgp_flag_init);

View file

@ -0,0 +1,241 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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 __RTL_DEBUG_H__
#define __RTL_DEBUG_H__
/*--------------------------------------------------------------
Debug level
--------------------------------------------------------------*/
/*
*Fatal bug.
*For example, Tx/Rx/IO locked up,
*memory access violation,
*resource allocation failed,
*unexpected HW behavior, HW BUG
*and so on.
*/
#define DBG_EMERG 0
/*
*Abnormal, rare, or unexpeted cases.
*For example, Packet/IO Ctl canceled,
*device suprisely unremoved and so on.
*/
#define DBG_WARNING 2
/*
*Normal case driver developer should
*open, we can see link status like
*assoc/AddBA/DHCP/adapter start and
*so on basic and useful infromations.
*/
#define DBG_DMESG 3
/*
*Normal case with useful information
*about current SW or HW state.
*For example, Tx/Rx descriptor to fill,
*Tx/Rx descriptor completed status,
*SW protocol state change, dynamic
*mechanism state change and so on.
*/
#define DBG_LOUD 4
/*
*Normal case with detail execution
*flow or information.
*/
#define DBG_TRACE 5
/*--------------------------------------------------------------
Define the rt_trace components
--------------------------------------------------------------*/
#define COMP_ERR BIT(0)
#define COMP_FW BIT(1)
#define COMP_INIT BIT(2) /*For init/deinit */
#define COMP_RECV BIT(3) /*For Rx. */
#define COMP_SEND BIT(4) /*For Tx. */
#define COMP_MLME BIT(5) /*For MLME. */
#define COMP_SCAN BIT(6) /*For Scan. */
#define COMP_INTR BIT(7) /*For interrupt Related. */
#define COMP_LED BIT(8) /*For LED. */
#define COMP_SEC BIT(9) /*For sec. */
#define COMP_BEACON BIT(10) /*For beacon. */
#define COMP_RATE BIT(11) /*For rate. */
#define COMP_RXDESC BIT(12) /*For rx desc. */
#define COMP_DIG BIT(13) /*For DIG */
#define COMP_TXAGC BIT(14) /*For Tx power */
#define COMP_HIPWR BIT(15) /*For High Power Mechanism */
#define COMP_POWER BIT(16) /*For lps/ips/aspm. */
#define COMP_POWER_TRACKING BIT(17) /*For TX POWER TRACKING */
#define COMP_BB_POWERSAVING BIT(18)
#define COMP_SWAS BIT(19) /*For SW Antenna Switch */
#define COMP_RF BIT(20) /*For RF. */
#define COMP_TURBO BIT(21) /*For EDCA TURBO. */
#define COMP_RATR BIT(22)
#define COMP_CMD BIT(23)
#define COMP_EFUSE BIT(24)
#define COMP_QOS BIT(25)
#define COMP_MAC80211 BIT(26)
#define COMP_REGD BIT(27)
#define COMP_CHAN BIT(28)
#define COMP_USB BIT(29)
#define COMP_EASY_CONCURRENT COMP_USB /* reuse of this bit is OK */
#define COMP_BT_COEXIST BIT(30)
#define COMP_IQK BIT(31)
/*--------------------------------------------------------------
Define the rt_print components
--------------------------------------------------------------*/
/* Define EEPROM and EFUSE check module bit*/
#define EEPROM_W BIT(0)
#define EFUSE_PG BIT(1)
#define EFUSE_READ_ALL BIT(2)
/* Define init check for module bit*/
#define INIT_EEPROM BIT(0)
#define INIT_TXPOWER BIT(1)
#define INIT_IQK BIT(2)
#define INIT_RF BIT(3)
/* Define PHY-BB/RF/MAC check module bit */
#define PHY_BBR BIT(0)
#define PHY_BBW BIT(1)
#define PHY_RFR BIT(2)
#define PHY_RFW BIT(3)
#define PHY_MACR BIT(4)
#define PHY_MACW BIT(5)
#define PHY_ALLR BIT(6)
#define PHY_ALLW BIT(7)
#define PHY_TXPWR BIT(8)
#define PHY_PWRDIFF BIT(9)
/* Define Dynamic Mechanism check module bit --> FDM */
#define WA_IOT BIT(0)
#define DM_PWDB BIT(1)
#define DM_MONITOR BIT(2)
#define DM_DIG BIT(3)
#define DM_EDCA_TURBO BIT(4)
#define DM_PWDB BIT(1)
enum dbgp_flag_e {
FQOS = 0,
FTX = 1,
FRX = 2,
FSEC = 3,
FMGNT = 4,
FMLME = 5,
FRESOURCE = 6,
FBEACON = 7,
FISR = 8,
FPHY = 9,
FMP = 10,
FEEPROM = 11,
FPWR = 12,
FDM = 13,
FDBGCtrl = 14,
FC2H = 15,
FBT = 16,
FINIT = 17,
FIOCTL = 18,
DBGP_TYPE_MAX
};
#ifdef CONFIG_RTLWIFI_DEBUG
#define RT_ASSERT(_exp, fmt, ...) \
do { \
if (!(_exp)) { \
printk(KERN_DEBUG KBUILD_MODNAME ":%s(): " fmt, \
__func__, ##__VA_ARGS__); \
} \
} while (0)
#define RT_TRACE(rtlpriv, comp, level, fmt, ...) \
do { \
if (unlikely(((comp) & rtlpriv->dbg.global_debugcomponents) && \
((level) <= rtlpriv->dbg.global_debuglevel))) { \
printk(KERN_DEBUG KBUILD_MODNAME ":%s():<%lx-%x> " fmt, \
__func__, in_interrupt(), in_atomic(), \
##__VA_ARGS__); \
} \
} while (0)
#define RTPRINT(rtlpriv, dbgtype, dbgflag, fmt, ...) \
do { \
if (unlikely(rtlpriv->dbg.dbgp_type[dbgtype] & dbgflag)) { \
printk(KERN_DEBUG KBUILD_MODNAME ": " fmt, \
##__VA_ARGS__); \
} \
} while (0)
#define RT_PRINT_DATA(rtlpriv, _comp, _level, _titlestring, _hexdata, \
_hexdatalen) \
do { \
if (unlikely(((_comp) & rtlpriv->dbg.global_debugcomponents) && \
(_level <= rtlpriv->dbg.global_debuglevel))) { \
printk(KERN_DEBUG "%s: In process \"%s\" (pid %i): %s\n", \
KBUILD_MODNAME, current->comm, current->pid, \
_titlestring); \
print_hex_dump_bytes("", DUMP_PREFIX_NONE, \
_hexdata, _hexdatalen); \
} \
} while (0)
#else
struct rtl_priv;
__printf(2, 3)
static inline void RT_ASSERT(int exp, const char *fmt, ...)
{
}
__printf(4, 5)
static inline void RT_TRACE(struct rtl_priv *rtlpriv,
int comp, int level,
const char *fmt, ...)
{
}
__printf(4, 5)
static inline void RTPRINT(struct rtl_priv *rtlpriv,
int dbgtype, int dbgflag,
const char *fmt, ...)
{
}
static inline void RT_PRINT_DATA(struct rtl_priv *rtlpriv,
int comp, int level,
const char *titlestring,
const void *hexdata, size_t hexdatalen)
{
}
#endif
void rtl_dbgp_flag_init(struct ieee80211_hw *hw);
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,119 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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 __RTL_EFUSE_H_
#define __RTL_EFUSE_H_
#define EFUSE_IC_ID_OFFSET 506
#define EFUSE_MAX_WORD_UNIT 4
#define EFUSE_INIT_MAP 0
#define EFUSE_MODIFY_MAP 1
#define PG_STATE_HEADER 0x01
#define PG_STATE_WORD_0 0x02
#define PG_STATE_WORD_1 0x04
#define PG_STATE_WORD_2 0x08
#define PG_STATE_WORD_3 0x10
#define PG_STATE_DATA 0x20
#define PG_SWBYTE_H 0x01
#define PG_SWBYTE_L 0x02
#define _POWERON_DELAY_
#define _PRE_EXECUTE_READ_CMD_
#define EFUSE_REPEAT_THRESHOLD_ 3
#define EFUSE_ERROE_HANDLE 1
struct efuse_map {
u8 offset;
u8 word_start;
u8 byte_start;
u8 byte_cnts;
};
struct pgpkt_struct {
u8 offset;
u8 word_en;
u8 data[8];
};
enum efuse_data_item {
EFUSE_CHIP_ID = 0,
EFUSE_LDO_SETTING,
EFUSE_CLK_SETTING,
EFUSE_SDIO_SETTING,
EFUSE_CCCR,
EFUSE_SDIO_MODE,
EFUSE_OCR,
EFUSE_F0CIS,
EFUSE_F1CIS,
EFUSE_MAC_ADDR,
EFUSE_EEPROM_VER,
EFUSE_CHAN_PLAN,
EFUSE_TXPW_TAB
};
enum {
VOLTAGE_V25 = 0x03,
LDOE25_SHIFT = 28,
};
struct efuse_priv {
u8 id[2];
u8 ldo_setting[2];
u8 clk_setting[2];
u8 cccr;
u8 sdio_mode;
u8 ocr[3];
u8 cis0[17];
u8 cis1[48];
u8 mac_addr[6];
u8 eeprom_verno;
u8 channel_plan;
u8 tx_power_b[14];
u8 tx_power_g[14];
};
void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf);
void efuse_initialize(struct ieee80211_hw *hw);
u8 efuse_read_1byte(struct ieee80211_hw *hw, u16 address);
int efuse_one_byte_read(struct ieee80211_hw *hw, u16 addr, u8 *data);
void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value);
void read_efuse(struct ieee80211_hw *hw, u16 _offset,
u16 _size_byte, u8 *pbuf);
void efuse_shadow_read(struct ieee80211_hw *hw, u8 type,
u16 offset, u32 *value);
void efuse_shadow_write(struct ieee80211_hw *hw, u8 type,
u16 offset, u32 value);
bool efuse_shadow_update(struct ieee80211_hw *hw);
bool efuse_shadow_update_chk(struct ieee80211_hw *hw);
void rtl_efuse_shadow_map_update(struct ieee80211_hw *hw);
void efuse_force_write_vendor_Id(struct ieee80211_hw *hw);
void efuse_re_pg_section(struct ieee80211_hw *hw, u8 section_idx);
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,335 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __RTL_PCI_H__
#define __RTL_PCI_H__
#include <linux/pci.h>
/*
1: MSDU packet queue,
2: Rx Command Queue
*/
#define RTL_PCI_RX_MPDU_QUEUE 0
#define RTL_PCI_RX_CMD_QUEUE 1
#define RTL_PCI_MAX_RX_QUEUE 2
#define RTL_PCI_MAX_RX_COUNT 512/*64*/
#define RTL_PCI_MAX_TX_QUEUE_COUNT 9
#define RT_TXDESC_NUM 128
#define TX_DESC_NUM_92E 512
#define RT_TXDESC_NUM_BE_QUEUE 256
#define BK_QUEUE 0
#define BE_QUEUE 1
#define VI_QUEUE 2
#define VO_QUEUE 3
#define BEACON_QUEUE 4
#define TXCMD_QUEUE 5
#define MGNT_QUEUE 6
#define HIGH_QUEUE 7
#define HCCA_QUEUE 8
#define RTL_PCI_DEVICE(vend, dev, cfg) \
.vendor = (vend), \
.device = (dev), \
.subvendor = PCI_ANY_ID, \
.subdevice = PCI_ANY_ID,\
.driver_data = (kernel_ulong_t)&(cfg)
#define INTEL_VENDOR_ID 0x8086
#define SIS_VENDOR_ID 0x1039
#define ATI_VENDOR_ID 0x1002
#define ATI_DEVICE_ID 0x7914
#define AMD_VENDOR_ID 0x1022
#define PCI_MAX_BRIDGE_NUMBER 255
#define PCI_MAX_DEVICES 32
#define PCI_MAX_FUNCTION 8
#define PCI_CONF_ADDRESS 0x0CF8 /*PCI Configuration Space Address */
#define PCI_CONF_DATA 0x0CFC /*PCI Configuration Space Data */
#define PCI_CLASS_BRIDGE_DEV 0x06
#define PCI_SUBCLASS_BR_PCI_TO_PCI 0x04
#define PCI_CAPABILITY_ID_PCI_EXPRESS 0x10
#define PCI_CAP_ID_EXP 0x10
#define U1DONTCARE 0xFF
#define U2DONTCARE 0xFFFF
#define U4DONTCARE 0xFFFFFFFF
#define RTL_PCI_8192_DID 0x8192 /*8192 PCI-E */
#define RTL_PCI_8192SE_DID 0x8192 /*8192 SE */
#define RTL_PCI_8174_DID 0x8174 /*8192 SE */
#define RTL_PCI_8173_DID 0x8173 /*8191 SE Crab */
#define RTL_PCI_8172_DID 0x8172 /*8191 SE RE */
#define RTL_PCI_8171_DID 0x8171 /*8191 SE Unicron */
#define RTL_PCI_8723AE_DID 0x8723 /*8723AE */
#define RTL_PCI_0045_DID 0x0045 /*8190 PCI for Ceraga */
#define RTL_PCI_0046_DID 0x0046 /*8190 Cardbus for Ceraga */
#define RTL_PCI_0044_DID 0x0044 /*8192e PCIE for Ceraga */
#define RTL_PCI_0047_DID 0x0047 /*8192e Express Card for Ceraga */
#define RTL_PCI_700F_DID 0x700F
#define RTL_PCI_701F_DID 0x701F
#define RTL_PCI_DLINK_DID 0x3304
#define RTL_PCI_8723AE_DID 0x8723 /*8723e */
#define RTL_PCI_8192CET_DID 0x8191 /*8192ce */
#define RTL_PCI_8192CE_DID 0x8178 /*8192ce */
#define RTL_PCI_8191CE_DID 0x8177 /*8192ce */
#define RTL_PCI_8188CE_DID 0x8176 /*8192ce */
#define RTL_PCI_8192CU_DID 0x8191 /*8192ce */
#define RTL_PCI_8192DE_DID 0x8193 /*8192de */
#define RTL_PCI_8192DE_DID2 0x002B /*92DE*/
#define RTL_PCI_8188EE_DID 0x8179 /*8188ee*/
#define RTL_PCI_8723BE_DID 0xB723 /*8723be*/
#define RTL_PCI_8192EE_DID 0x818B /*8192ee*/
#define RTL_PCI_8821AE_DID 0x8821 /*8821ae*/
#define RTL_PCI_8812AE_DID 0x8812 /*8812ae*/
/*8192 support 16 pages of IO registers*/
#define RTL_MEM_MAPPED_IO_RANGE_8190PCI 0x1000
#define RTL_MEM_MAPPED_IO_RANGE_8192PCIE 0x4000
#define RTL_MEM_MAPPED_IO_RANGE_8192SE 0x4000
#define RTL_MEM_MAPPED_IO_RANGE_8192CE 0x4000
#define RTL_MEM_MAPPED_IO_RANGE_8192DE 0x4000
#define RTL_PCI_REVISION_ID_8190PCI 0x00
#define RTL_PCI_REVISION_ID_8192PCIE 0x01
#define RTL_PCI_REVISION_ID_8192SE 0x10
#define RTL_PCI_REVISION_ID_8192CE 0x1
#define RTL_PCI_REVISION_ID_8192DE 0x0
#define RTL_DEFAULT_HARDWARE_TYPE HARDWARE_TYPE_RTL8192CE
enum pci_bridge_vendor {
PCI_BRIDGE_VENDOR_INTEL = 0x0, /*0b'0000,0001 */
PCI_BRIDGE_VENDOR_ATI, /*0b'0000,0010*/
PCI_BRIDGE_VENDOR_AMD, /*0b'0000,0100*/
PCI_BRIDGE_VENDOR_SIS, /*0b'0000,1000*/
PCI_BRIDGE_VENDOR_UNKNOWN, /*0b'0100,0000*/
PCI_BRIDGE_VENDOR_MAX,
};
struct rtl_pci_capabilities_header {
u8 capability_id;
u8 next;
};
/* In new TRX flow, Buffer_desc is new concept
* But TX wifi info == TX descriptor in old flow
* RX wifi info == RX descriptor in old flow
*/
struct rtl_tx_buffer_desc {
#if (RTL8192EE_SEG_NUM == 2)
u32 dword[2*(DMA_IS_64BIT + 1)*8]; /*seg = 8*/
#elif (RTL8192EE_SEG_NUM == 1)
u32 dword[2*(DMA_IS_64BIT + 1)*4]; /*seg = 4*/
#elif (RTL8192EE_SEG_NUM == 0)
u32 dword[2*(DMA_IS_64BIT + 1)*2]; /*seg = 2*/
#endif
} __packed;
struct rtl_tx_desc {
u32 dword[16];
} __packed;
struct rtl_rx_buffer_desc { /*rx buffer desc*/
u32 dword[2];
} __packed;
struct rtl_rx_desc { /*old: rx desc new: rx wifi info*/
u32 dword[8];
} __packed;
struct rtl_tx_cmd_desc {
u32 dword[16];
} __packed;
struct rtl8192_tx_ring {
struct rtl_tx_desc *desc;
dma_addr_t dma;
unsigned int idx;
unsigned int entries;
struct sk_buff_head queue;
/*add for new trx flow*/
struct rtl_tx_buffer_desc *buffer_desc; /*tx buffer descriptor*/
dma_addr_t buffer_desc_dma; /*tx bufferd desc dma memory*/
u16 avl_desc; /* available_desc_to_write */
u16 cur_tx_wp; /* current_tx_write_point */
u16 cur_tx_rp; /* current_tx_read_point */
};
struct rtl8192_rx_ring {
struct rtl_rx_desc *desc;
dma_addr_t dma;
unsigned int idx;
struct sk_buff *rx_buf[RTL_PCI_MAX_RX_COUNT];
/*add for new trx flow*/
struct rtl_rx_buffer_desc *buffer_desc; /*rx buffer descriptor*/
u16 next_rx_rp; /* next_rx_read_point */
};
struct rtl_pci {
struct pci_dev *pdev;
bool irq_enabled;
bool driver_is_goingto_unload;
bool up_first_time;
bool first_init;
bool being_init_adapter;
bool init_ready;
/*Tx */
struct rtl8192_tx_ring tx_ring[RTL_PCI_MAX_TX_QUEUE_COUNT];
int txringcount[RTL_PCI_MAX_TX_QUEUE_COUNT];
u32 transmit_config;
/*Rx */
struct rtl8192_rx_ring rx_ring[RTL_PCI_MAX_RX_QUEUE];
int rxringcount;
u16 rxbuffersize;
u32 receive_config;
/*irq */
u8 irq_alloc;
u32 irq_mask[2];
u32 sys_irq_mask;
/*Bcn control register setting */
u32 reg_bcn_ctrl_val;
/*ASPM*/ u8 const_pci_aspm;
u8 const_amdpci_aspm;
u8 const_hwsw_rfoff_d3;
u8 const_support_pciaspm;
/*pci-e bridge */
u8 const_hostpci_aspm_setting;
/*pci-e device */
u8 const_devicepci_aspm_setting;
/*If it supports ASPM, Offset[560h] = 0x40,
otherwise Offset[560h] = 0x00. */
bool support_aspm;
bool support_backdoor;
/*QOS & EDCA */
enum acm_method acm_method;
u16 shortretry_limit;
u16 longretry_limit;
/* MSI support */
bool msi_support;
bool using_msi;
};
struct mp_adapter {
u8 linkctrl_reg;
u8 busnumber;
u8 devnumber;
u8 funcnumber;
u8 pcibridge_busnum;
u8 pcibridge_devnum;
u8 pcibridge_funcnum;
u8 pcibridge_vendor;
u16 pcibridge_vendorid;
u16 pcibridge_deviceid;
u8 num4bytes;
u8 pcibridge_pciehdr_offset;
u8 pcibridge_linkctrlreg;
bool amd_l1_patch;
};
struct rtl_pci_priv {
struct rtl_pci dev;
struct mp_adapter ndis_adapter;
struct rtl_led_ctl ledctl;
struct bt_coexist_info bt_coexist;
};
#define rtl_pcipriv(hw) (((struct rtl_pci_priv *)(rtl_priv(hw))->priv))
#define rtl_pcidev(pcipriv) (&((pcipriv)->dev))
int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw);
extern struct rtl_intf_ops rtl_pci_ops;
int rtl_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *id);
void rtl_pci_disconnect(struct pci_dev *pdev);
#ifdef CONFIG_PM_SLEEP
int rtl_pci_suspend(struct device *dev);
int rtl_pci_resume(struct device *dev);
#endif /* CONFIG_PM_SLEEP */
static inline u8 pci_read8_sync(struct rtl_priv *rtlpriv, u32 addr)
{
return readb((u8 __iomem *) rtlpriv->io.pci_mem_start + addr);
}
static inline u16 pci_read16_sync(struct rtl_priv *rtlpriv, u32 addr)
{
return readw((u8 __iomem *) rtlpriv->io.pci_mem_start + addr);
}
static inline u32 pci_read32_sync(struct rtl_priv *rtlpriv, u32 addr)
{
return readl((u8 __iomem *) rtlpriv->io.pci_mem_start + addr);
}
static inline void pci_write8_async(struct rtl_priv *rtlpriv, u32 addr, u8 val)
{
writeb(val, (u8 __iomem *) rtlpriv->io.pci_mem_start + addr);
}
static inline void pci_write16_async(struct rtl_priv *rtlpriv,
u32 addr, u16 val)
{
writew(val, (u8 __iomem *) rtlpriv->io.pci_mem_start + addr);
}
static inline void pci_write32_async(struct rtl_priv *rtlpriv,
u32 addr, u32 val)
{
writel(val, (u8 __iomem *) rtlpriv->io.pci_mem_start + addr);
}
static inline u16 calc_fifo_space(u16 rp, u16 wp)
{
if (rp <= wp)
return RTL_PCI_MAX_RX_COUNT - 1 + rp - wp;
return rp - wp - 1;
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,53 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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 __REALTEK_RTL_PCI_PS_H__
#define __REALTEK_RTL_PCI_PS_H__
#define MAX_SW_LPS_SLEEP_INTV 5
bool rtl_ps_set_rf_state(struct ieee80211_hw *hw,
enum rf_pwrstate state_toset, u32 changesource,
bool protect_or_not);
bool rtl_ps_enable_nic(struct ieee80211_hw *hw);
bool rtl_ps_disable_nic(struct ieee80211_hw *hw);
void rtl_ips_nic_off(struct ieee80211_hw *hw);
void rtl_ips_nic_on(struct ieee80211_hw *hw);
void rtl_ips_nic_off_wq_callback(void *data);
void rtl_lps_enter(struct ieee80211_hw *hw);
void rtl_lps_leave(struct ieee80211_hw *hw);
void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode);
void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len);
void rtl_swlps_wq_callback(void *data);
void rtl_swlps_rfon_wq_callback(void *data);
void rtl_swlps_rf_awake(struct ieee80211_hw *hw);
void rtl_swlps_rf_sleep(struct ieee80211_hw *hw);
void rtl_p2p_ps_cmd(struct ieee80211_hw *hw , u8 p2p_ps_state);
void rtl_p2p_info(struct ieee80211_hw *hw, void *data, unsigned int len);
void rtl_lps_change_work_callback(struct work_struct *work);
#endif

View file

@ -0,0 +1,94 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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 __RTL8723E_PWRSEQCMD_H__
#define __RTL8723E_PWRSEQCMD_H__
#include "wifi.h"
/*---------------------------------------------
* 3 The value of cmd: 4 bits
*---------------------------------------------
*/
#define PWR_CMD_READ 0x00
#define PWR_CMD_WRITE 0x01
#define PWR_CMD_POLLING 0x02
#define PWR_CMD_DELAY 0x03
#define PWR_CMD_END 0x04
/* define the base address of each block */
#define PWR_BASEADDR_MAC 0x00
#define PWR_BASEADDR_USB 0x01
#define PWR_BASEADDR_PCIE 0x02
#define PWR_BASEADDR_SDIO 0x03
#define PWR_INTF_SDIO_MSK BIT(0)
#define PWR_INTF_USB_MSK BIT(1)
#define PWR_INTF_PCI_MSK BIT(2)
#define PWR_INTF_ALL_MSK (BIT(0)|BIT(1)|BIT(2)|BIT(3))
#define PWR_FAB_TSMC_MSK BIT(0)
#define PWR_FAB_UMC_MSK BIT(1)
#define PWR_FAB_ALL_MSK (BIT(0)|BIT(1)|BIT(2)|BIT(3))
#define PWR_CUT_TESTCHIP_MSK BIT(0)
#define PWR_CUT_A_MSK BIT(1)
#define PWR_CUT_B_MSK BIT(2)
#define PWR_CUT_C_MSK BIT(3)
#define PWR_CUT_D_MSK BIT(4)
#define PWR_CUT_E_MSK BIT(5)
#define PWR_CUT_F_MSK BIT(6)
#define PWR_CUT_G_MSK BIT(7)
#define PWR_CUT_ALL_MSK 0xFF
enum pwrseq_delay_unit {
PWRSEQ_DELAY_US,
PWRSEQ_DELAY_MS,
};
struct wlan_pwr_cfg {
u16 offset;
u8 cut_msk;
u8 fab_msk:4;
u8 interface_msk:4;
u8 base:4;
u8 cmd:4;
u8 msk;
u8 value;
};
#define GET_PWR_CFG_OFFSET(__PWR_CMD) (__PWR_CMD.offset)
#define GET_PWR_CFG_CUT_MASK(__PWR_CMD) (__PWR_CMD.cut_msk)
#define GET_PWR_CFG_FAB_MASK(__PWR_CMD) (__PWR_CMD.fab_msk)
#define GET_PWR_CFG_INTF_MASK(__PWR_CMD) (__PWR_CMD.interface_msk)
#define GET_PWR_CFG_BASE(__PWR_CMD) (__PWR_CMD.base)
#define GET_PWR_CFG_CMD(__PWR_CMD) (__PWR_CMD.cmd)
#define GET_PWR_CFG_MASK(__PWR_CMD) (__PWR_CMD.msk)
#define GET_PWR_CFG_VALUE(__PWR_CMD) (__PWR_CMD.value)
bool rtl_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version,
u8 fab_version, u8 interface_type,
struct wlan_pwr_cfg pwrcfgcmd[]);
#endif

View file

@ -0,0 +1,301 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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 "wifi.h"
#include "base.h"
#include "rc.h"
/*
*Finds the highest rate index we can use
*if skb is special data like DHCP/EAPOL, we set should
*it to lowest rate CCK_1M, otherwise we set rate to
*highest rate based on wireless mode used for iwconfig
*show Tx rate.
*/
static u8 _rtl_rc_get_highest_rix(struct rtl_priv *rtlpriv,
struct ieee80211_sta *sta,
struct sk_buff *skb, bool not_data)
{
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
struct rtl_sta_info *sta_entry = NULL;
u8 wireless_mode = 0;
/*
*this rate is no use for true rate, firmware
*will control rate at all it just used for
*1.show in iwconfig in B/G mode
*2.in rtl_get_tcb_desc when we check rate is
* 1M we will not use FW rate but user rate.
*/
if (sta) {
sta_entry = (struct rtl_sta_info *)sta->drv_priv;
wireless_mode = sta_entry->wireless_mode;
}
if (rtl_is_special_data(rtlpriv->mac80211.hw, skb, true) || not_data) {
return 0;
} else {
if (rtlhal->current_bandtype == BAND_ON_2_4G) {
if (wireless_mode == WIRELESS_MODE_B) {
return B_MODE_MAX_RIX;
} else if (wireless_mode == WIRELESS_MODE_G) {
return G_MODE_MAX_RIX;
} else if (wireless_mode == WIRELESS_MODE_N_24G) {
if (get_rf_type(rtlphy) != RF_2T2R)
return N_MODE_MCS7_RIX;
else
return N_MODE_MCS15_RIX;
} else if (wireless_mode == WIRELESS_MODE_AC_24G) {
return AC_MODE_MCS9_RIX;
}
return 0;
} else {
if (wireless_mode == WIRELESS_MODE_A) {
return A_MODE_MAX_RIX;
} else if (wireless_mode == WIRELESS_MODE_N_5G) {
if (get_rf_type(rtlphy) != RF_2T2R)
return N_MODE_MCS7_RIX;
else
return N_MODE_MCS15_RIX;
} else if (wireless_mode == WIRELESS_MODE_AC_5G) {
return AC_MODE_MCS9_RIX;
}
return 0;
}
}
}
static void _rtl_rc_rate_set_series(struct rtl_priv *rtlpriv,
struct ieee80211_sta *sta,
struct ieee80211_tx_rate *rate,
struct ieee80211_tx_rate_control *txrc,
u8 tries, char rix, int rtsctsenable,
bool not_data)
{
struct rtl_mac *mac = rtl_mac(rtlpriv);
struct rtl_sta_info *sta_entry = NULL;
u8 wireless_mode = 0;
u8 sgi_20 = 0, sgi_40 = 0, sgi_80 = 0;
if (sta) {
sgi_20 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20;
sgi_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40;
sgi_80 = sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80;
sta_entry = (struct rtl_sta_info *)sta->drv_priv;
wireless_mode = sta_entry->wireless_mode;
}
rate->count = tries;
rate->idx = rix >= 0x00 ? rix : 0x00;
if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8812AE &&
wireless_mode == WIRELESS_MODE_AC_5G)
rate->idx += 0x10;/*2NSS for 8812AE*/
if (!not_data) {
if (txrc->short_preamble)
rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE;
if (mac->opmode == NL80211_IFTYPE_AP ||
mac->opmode == NL80211_IFTYPE_ADHOC) {
if (sta && (sta->ht_cap.cap &
IEEE80211_HT_CAP_SUP_WIDTH_20_40))
rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
if (sta && (sta->vht_cap.vht_supported))
rate->flags |= IEEE80211_TX_RC_80_MHZ_WIDTH;
} else {
if (mac->bw_40)
rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
if (mac->bw_80)
rate->flags |= IEEE80211_TX_RC_80_MHZ_WIDTH;
}
if (sgi_20 || sgi_40 || sgi_80)
rate->flags |= IEEE80211_TX_RC_SHORT_GI;
if (sta && sta->ht_cap.ht_supported &&
((wireless_mode == WIRELESS_MODE_N_5G) ||
(wireless_mode == WIRELESS_MODE_N_24G)))
rate->flags |= IEEE80211_TX_RC_MCS;
}
}
static void rtl_get_rate(void *ppriv, struct ieee80211_sta *sta,
void *priv_sta,
struct ieee80211_tx_rate_control *txrc)
{
struct rtl_priv *rtlpriv = ppriv;
struct sk_buff *skb = txrc->skb;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ieee80211_tx_rate *rates = tx_info->control.rates;
__le16 fc = rtl_get_fc(skb);
u8 try_per_rate, i, rix;
bool not_data = !ieee80211_is_data(fc);
if (rate_control_send_low(sta, priv_sta, txrc))
return;
rix = _rtl_rc_get_highest_rix(rtlpriv, sta, skb, not_data);
try_per_rate = 1;
_rtl_rc_rate_set_series(rtlpriv, sta, &rates[0], txrc,
try_per_rate, rix, 1, not_data);
if (!not_data) {
for (i = 1; i < 4; i++)
_rtl_rc_rate_set_series(rtlpriv, sta, &rates[i],
txrc, i, (rix - i), 1,
not_data);
}
}
static bool _rtl_tx_aggr_check(struct rtl_priv *rtlpriv,
struct rtl_sta_info *sta_entry, u16 tid)
{
struct rtl_mac *mac = rtl_mac(rtlpriv);
if (mac->act_scanning)
return false;
if (mac->opmode == NL80211_IFTYPE_STATION &&
mac->cnt_after_linked < 3)
return false;
if (sta_entry->tids[tid].agg.agg_state == RTL_AGG_STOP)
return true;
return false;
}
/*mac80211 Rate Control callbacks*/
static void rtl_tx_status(void *ppriv,
struct ieee80211_supported_band *sband,
struct ieee80211_sta *sta, void *priv_sta,
struct sk_buff *skb)
{
struct rtl_priv *rtlpriv = ppriv;
struct rtl_mac *mac = rtl_mac(rtlpriv);
struct ieee80211_hdr *hdr = rtl_get_hdr(skb);
__le16 fc = rtl_get_fc(skb);
struct rtl_sta_info *sta_entry;
if (!priv_sta || !ieee80211_is_data(fc))
return;
if (rtl_is_special_data(mac->hw, skb, true))
return;
if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) ||
is_broadcast_ether_addr(ieee80211_get_DA(hdr)))
return;
if (sta) {
/* Check if aggregation has to be enabled for this tid */
sta_entry = (struct rtl_sta_info *) sta->drv_priv;
if ((sta->ht_cap.ht_supported) &&
!(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
if (ieee80211_is_data_qos(fc)) {
u8 tid = rtl_get_tid(skb);
if (_rtl_tx_aggr_check(rtlpriv, sta_entry,
tid)) {
sta_entry->tids[tid].agg.agg_state =
RTL_AGG_PROGRESS;
ieee80211_start_tx_ba_session(sta, tid,
5000);
}
}
}
}
}
static void rtl_rate_init(void *ppriv,
struct ieee80211_supported_band *sband,
struct cfg80211_chan_def *chandef,
struct ieee80211_sta *sta, void *priv_sta)
{
}
static void rtl_rate_update(void *ppriv,
struct ieee80211_supported_band *sband,
struct cfg80211_chan_def *chandef,
struct ieee80211_sta *sta, void *priv_sta,
u32 changed)
{
}
static void *rtl_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
return rtlpriv;
}
static void rtl_rate_free(void *rtlpriv)
{
return;
}
static void *rtl_rate_alloc_sta(void *ppriv,
struct ieee80211_sta *sta, gfp_t gfp)
{
struct rtl_priv *rtlpriv = ppriv;
struct rtl_rate_priv *rate_priv;
rate_priv = kzalloc(sizeof(struct rtl_rate_priv), gfp);
if (!rate_priv) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"Unable to allocate private rc structure\n");
return NULL;
}
rtlpriv->rate_priv = rate_priv;
return rate_priv;
}
static void rtl_rate_free_sta(void *rtlpriv,
struct ieee80211_sta *sta, void *priv_sta)
{
struct rtl_rate_priv *rate_priv = priv_sta;
kfree(rate_priv);
}
static struct rate_control_ops rtl_rate_ops = {
.name = "rtl_rc",
.alloc = rtl_rate_alloc,
.free = rtl_rate_free,
.alloc_sta = rtl_rate_alloc_sta,
.free_sta = rtl_rate_free_sta,
.rate_init = rtl_rate_init,
.rate_update = rtl_rate_update,
.tx_status = rtl_tx_status,
.get_rate = rtl_get_rate,
};
int rtl_rate_control_register(void)
{
return ieee80211_rate_control_register(&rtl_rate_ops);
}
void rtl_rate_control_unregister(void)
{
ieee80211_rate_control_unregister(&rtl_rate_ops);
}

View file

@ -0,0 +1,48 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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 __RTL_RC_H__
#define __RTL_RC_H__
#define B_MODE_MAX_RIX 3
#define G_MODE_MAX_RIX 11
#define A_MODE_MAX_RIX 7
/* in mac80211 mcs0-mcs15 is idx0-idx15*/
#define N_MODE_MCS7_RIX 7
#define N_MODE_MCS15_RIX 15
#define AC_MODE_MCS7_RIX 7
#define AC_MODE_MCS8_RIX 8
#define AC_MODE_MCS9_RIX 9
struct rtl_rate_priv {
u8 ht_cap;
};
int rtl_rate_control_register(void);
void rtl_rate_control_unregister(void);
#endif

View file

@ -0,0 +1,439 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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 "wifi.h"
#include "regd.h"
static struct country_code_to_enum_rd allCountries[] = {
{COUNTRY_CODE_FCC, "US"},
{COUNTRY_CODE_IC, "US"},
{COUNTRY_CODE_ETSI, "EC"},
{COUNTRY_CODE_SPAIN, "EC"},
{COUNTRY_CODE_FRANCE, "EC"},
{COUNTRY_CODE_MKK, "JP"},
{COUNTRY_CODE_MKK1, "JP"},
{COUNTRY_CODE_ISRAEL, "EC"},
{COUNTRY_CODE_TELEC, "JP"},
{COUNTRY_CODE_MIC, "JP"},
{COUNTRY_CODE_GLOBAL_DOMAIN, "JP"},
{COUNTRY_CODE_WORLD_WIDE_13, "EC"},
{COUNTRY_CODE_TELEC_NETGEAR, "EC"},
};
/*
*Only these channels all allow active
*scan on all world regulatory domains
*/
#define RTL819x_2GHZ_CH01_11 \
REG_RULE(2412-10, 2462+10, 40, 0, 20, 0)
/*
*We enable active scan on these a case
*by case basis by regulatory domain
*/
#define RTL819x_2GHZ_CH12_13 \
REG_RULE(2467-10, 2472+10, 40, 0, 20,\
NL80211_RRF_PASSIVE_SCAN)
#define RTL819x_2GHZ_CH14 \
REG_RULE(2484-10, 2484+10, 40, 0, 20, \
NL80211_RRF_PASSIVE_SCAN | \
NL80211_RRF_NO_OFDM)
/* 5G chan 36 - chan 64*/
#define RTL819x_5GHZ_5150_5350 \
REG_RULE(5150-10, 5350+10, 80, 0, 30, 0)
/* 5G chan 100 - chan 165*/
#define RTL819x_5GHZ_5470_5850 \
REG_RULE(5470-10, 5850+10, 80, 0, 30, 0)
/* 5G chan 149 - chan 165*/
#define RTL819x_5GHZ_5725_5850 \
REG_RULE(5725-10, 5850+10, 80, 0, 30, 0)
#define RTL819x_5GHZ_ALL \
(RTL819x_5GHZ_5150_5350, RTL819x_5GHZ_5470_5850)
static const struct ieee80211_regdomain rtl_regdom_11 = {
.n_reg_rules = 1,
.alpha2 = "99",
.reg_rules = {
RTL819x_2GHZ_CH01_11,
}
};
static const struct ieee80211_regdomain rtl_regdom_12_13 = {
.n_reg_rules = 2,
.alpha2 = "99",
.reg_rules = {
RTL819x_2GHZ_CH01_11,
RTL819x_2GHZ_CH12_13,
}
};
static const struct ieee80211_regdomain rtl_regdom_no_midband = {
.n_reg_rules = 3,
.alpha2 = "99",
.reg_rules = {
RTL819x_2GHZ_CH01_11,
RTL819x_5GHZ_5150_5350,
RTL819x_5GHZ_5725_5850,
}
};
static const struct ieee80211_regdomain rtl_regdom_60_64 = {
.n_reg_rules = 3,
.alpha2 = "99",
.reg_rules = {
RTL819x_2GHZ_CH01_11,
RTL819x_2GHZ_CH12_13,
RTL819x_5GHZ_5725_5850,
}
};
static const struct ieee80211_regdomain rtl_regdom_14_60_64 = {
.n_reg_rules = 4,
.alpha2 = "99",
.reg_rules = {
RTL819x_2GHZ_CH01_11,
RTL819x_2GHZ_CH12_13,
RTL819x_2GHZ_CH14,
RTL819x_5GHZ_5725_5850,
}
};
static const struct ieee80211_regdomain rtl_regdom_14 = {
.n_reg_rules = 3,
.alpha2 = "99",
.reg_rules = {
RTL819x_2GHZ_CH01_11,
RTL819x_2GHZ_CH12_13,
RTL819x_2GHZ_CH14,
}
};
static bool _rtl_is_radar_freq(u16 center_freq)
{
return center_freq >= 5260 && center_freq <= 5700;
}
static void _rtl_reg_apply_beaconing_flags(struct wiphy *wiphy,
enum nl80211_reg_initiator initiator)
{
enum ieee80211_band band;
struct ieee80211_supported_band *sband;
const struct ieee80211_reg_rule *reg_rule;
struct ieee80211_channel *ch;
unsigned int i;
for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
if (!wiphy->bands[band])
continue;
sband = wiphy->bands[band];
for (i = 0; i < sband->n_channels; i++) {
ch = &sband->channels[i];
if (_rtl_is_radar_freq(ch->center_freq) ||
(ch->flags & IEEE80211_CHAN_RADAR))
continue;
if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) {
reg_rule = freq_reg_info(wiphy,
ch->center_freq);
if (IS_ERR(reg_rule))
continue;
/*
*If 11d had a rule for this channel ensure
*we enable adhoc/beaconing if it allows us to
*use it. Note that we would have disabled it
*by applying our static world regdomain by
*default during init, prior to calling our
*regulatory_hint().
*/
if (!(reg_rule->flags & NL80211_RRF_NO_IBSS))
ch->flags &= ~IEEE80211_CHAN_NO_IBSS;
if (!(reg_rule->flags &
NL80211_RRF_PASSIVE_SCAN))
ch->flags &=
~IEEE80211_CHAN_PASSIVE_SCAN;
} else {
if (ch->beacon_found)
ch->flags &= ~(IEEE80211_CHAN_NO_IBSS |
IEEE80211_CHAN_PASSIVE_SCAN);
}
}
}
}
/* Allows active scan scan on Ch 12 and 13 */
static void _rtl_reg_apply_active_scan_flags(struct wiphy *wiphy,
enum nl80211_reg_initiator
initiator)
{
struct ieee80211_supported_band *sband;
struct ieee80211_channel *ch;
const struct ieee80211_reg_rule *reg_rule;
if (!wiphy->bands[IEEE80211_BAND_2GHZ])
return;
sband = wiphy->bands[IEEE80211_BAND_2GHZ];
/*
*If no country IE has been received always enable active scan
*on these channels. This is only done for specific regulatory SKUs
*/
if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) {
ch = &sband->channels[11]; /* CH 12 */
if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
ch = &sband->channels[12]; /* CH 13 */
if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
return;
}
/*
*If a country IE has been recieved check its rule for this
*channel first before enabling active scan. The passive scan
*would have been enforced by the initial processing of our
*custom regulatory domain.
*/
ch = &sband->channels[11]; /* CH 12 */
reg_rule = freq_reg_info(wiphy, ch->center_freq);
if (!IS_ERR(reg_rule)) {
if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
}
ch = &sband->channels[12]; /* CH 13 */
reg_rule = freq_reg_info(wiphy, ch->center_freq);
if (!IS_ERR(reg_rule)) {
if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
}
}
/*
*Always apply Radar/DFS rules on
*freq range 5260 MHz - 5700 MHz
*/
static void _rtl_reg_apply_radar_flags(struct wiphy *wiphy)
{
struct ieee80211_supported_band *sband;
struct ieee80211_channel *ch;
unsigned int i;
if (!wiphy->bands[IEEE80211_BAND_5GHZ])
return;
sband = wiphy->bands[IEEE80211_BAND_5GHZ];
for (i = 0; i < sband->n_channels; i++) {
ch = &sband->channels[i];
if (!_rtl_is_radar_freq(ch->center_freq))
continue;
/*
*We always enable radar detection/DFS on this
*frequency range. Additionally we also apply on
*this frequency range:
*- If STA mode does not yet have DFS supports disable
* active scanning
*- If adhoc mode does not support DFS yet then disable
* adhoc in the frequency.
*- If AP mode does not yet support radar detection/DFS
*do not allow AP mode
*/
if (!(ch->flags & IEEE80211_CHAN_DISABLED))
ch->flags |= IEEE80211_CHAN_RADAR |
IEEE80211_CHAN_NO_IBSS |
IEEE80211_CHAN_PASSIVE_SCAN;
}
}
static void _rtl_reg_apply_world_flags(struct wiphy *wiphy,
enum nl80211_reg_initiator initiator,
struct rtl_regulatory *reg)
{
_rtl_reg_apply_beaconing_flags(wiphy, initiator);
_rtl_reg_apply_active_scan_flags(wiphy, initiator);
return;
}
static void _rtl_dump_channel_map(struct wiphy *wiphy)
{
enum ieee80211_band band;
struct ieee80211_supported_band *sband;
struct ieee80211_channel *ch;
unsigned int i;
for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
if (!wiphy->bands[band])
continue;
sband = wiphy->bands[band];
for (i = 0; i < sband->n_channels; i++)
ch = &sband->channels[i];
}
}
static int _rtl_reg_notifier_apply(struct wiphy *wiphy,
struct regulatory_request *request,
struct rtl_regulatory *reg)
{
/* We always apply this */
_rtl_reg_apply_radar_flags(wiphy);
switch (request->initiator) {
case NL80211_REGDOM_SET_BY_DRIVER:
case NL80211_REGDOM_SET_BY_CORE:
case NL80211_REGDOM_SET_BY_USER:
break;
case NL80211_REGDOM_SET_BY_COUNTRY_IE:
_rtl_reg_apply_world_flags(wiphy, request->initiator, reg);
break;
}
_rtl_dump_channel_map(wiphy);
return 0;
}
static const struct ieee80211_regdomain *_rtl_regdomain_select(
struct rtl_regulatory *reg)
{
switch (reg->country_code) {
case COUNTRY_CODE_FCC:
return &rtl_regdom_no_midband;
case COUNTRY_CODE_IC:
return &rtl_regdom_11;
case COUNTRY_CODE_ETSI:
case COUNTRY_CODE_TELEC_NETGEAR:
return &rtl_regdom_60_64;
case COUNTRY_CODE_SPAIN:
case COUNTRY_CODE_FRANCE:
case COUNTRY_CODE_ISRAEL:
case COUNTRY_CODE_WORLD_WIDE_13:
return &rtl_regdom_12_13;
case COUNTRY_CODE_MKK:
case COUNTRY_CODE_MKK1:
case COUNTRY_CODE_TELEC:
case COUNTRY_CODE_MIC:
return &rtl_regdom_14_60_64;
case COUNTRY_CODE_GLOBAL_DOMAIN:
return &rtl_regdom_14;
default:
return &rtl_regdom_no_midband;
}
}
static int _rtl_regd_init_wiphy(struct rtl_regulatory *reg,
struct wiphy *wiphy,
void (*reg_notifier)(struct wiphy *wiphy,
struct regulatory_request *
request))
{
const struct ieee80211_regdomain *regd;
wiphy->reg_notifier = reg_notifier;
wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
wiphy->regulatory_flags &= ~REGULATORY_STRICT_REG;
wiphy->regulatory_flags &= ~REGULATORY_DISABLE_BEACON_HINTS;
regd = _rtl_regdomain_select(reg);
wiphy_apply_custom_regulatory(wiphy, regd);
_rtl_reg_apply_radar_flags(wiphy);
_rtl_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, reg);
return 0;
}
static struct country_code_to_enum_rd *_rtl_regd_find_country(u16 countrycode)
{
int i;
for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
if (allCountries[i].countrycode == countrycode)
return &allCountries[i];
}
return NULL;
}
int rtl_regd_init(struct ieee80211_hw *hw,
void (*reg_notifier)(struct wiphy *wiphy,
struct regulatory_request *request))
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct wiphy *wiphy = hw->wiphy;
struct country_code_to_enum_rd *country = NULL;
if (wiphy == NULL || &rtlpriv->regd == NULL)
return -EINVAL;
/* init country_code from efuse channel plan */
rtlpriv->regd.country_code = rtlpriv->efuse.channel_plan;
RT_TRACE(rtlpriv, COMP_REGD, DBG_TRACE,
"rtl: EEPROM regdomain: 0x%0x\n",
rtlpriv->regd.country_code);
if (rtlpriv->regd.country_code >= COUNTRY_CODE_MAX) {
RT_TRACE(rtlpriv, COMP_REGD, DBG_DMESG,
"rtl: EEPROM indicates invalid contry code, world wide 13 should be used\n");
rtlpriv->regd.country_code = COUNTRY_CODE_WORLD_WIDE_13;
}
country = _rtl_regd_find_country(rtlpriv->regd.country_code);
if (country) {
rtlpriv->regd.alpha2[0] = country->iso_name[0];
rtlpriv->regd.alpha2[1] = country->iso_name[1];
} else {
rtlpriv->regd.alpha2[0] = '0';
rtlpriv->regd.alpha2[1] = '0';
}
RT_TRACE(rtlpriv, COMP_REGD, DBG_TRACE,
"rtl: Country alpha2 being used: %c%c\n",
rtlpriv->regd.alpha2[0], rtlpriv->regd.alpha2[1]);
_rtl_regd_init_wiphy(&rtlpriv->regd, wiphy, reg_notifier);
return 0;
}
void rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
{
struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
struct rtl_priv *rtlpriv = rtl_priv(hw);
RT_TRACE(rtlpriv, COMP_REGD, DBG_LOUD, "\n");
_rtl_reg_notifier_apply(wiphy, request, &rtlpriv->regd);
}

View file

@ -0,0 +1,62 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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 __RTL_REGD_H__
#define __RTL_REGD_H__
/* for kernel 3.14 , both value are changed to IEEE80211_CHAN_NO_IR*/
#define IEEE80211_CHAN_NO_IBSS IEEE80211_CHAN_NO_IR
#define IEEE80211_CHAN_PASSIVE_SCAN IEEE80211_CHAN_NO_IR
struct country_code_to_enum_rd {
u16 countrycode;
const char *iso_name;
};
enum country_code_type_t {
COUNTRY_CODE_FCC = 0,
COUNTRY_CODE_IC = 1,
COUNTRY_CODE_ETSI = 2,
COUNTRY_CODE_SPAIN = 3,
COUNTRY_CODE_FRANCE = 4,
COUNTRY_CODE_MKK = 5,
COUNTRY_CODE_MKK1 = 6,
COUNTRY_CODE_ISRAEL = 7,
COUNTRY_CODE_TELEC = 8,
COUNTRY_CODE_MIC = 9,
COUNTRY_CODE_GLOBAL_DOMAIN = 10,
COUNTRY_CODE_WORLD_WIDE_13 = 11,
COUNTRY_CODE_TELEC_NETGEAR = 12,
/*add new channel plan above this line */
COUNTRY_CODE_MAX
};
int rtl_regd_init(struct ieee80211_hw *hw,
void (*reg_notifier) (struct wiphy *wiphy,
struct regulatory_request *request));
void rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request);
#endif

View file

@ -0,0 +1,15 @@
rtl8188ee-objs := \
dm.o \
fw.o \
hw.o \
led.o \
phy.o \
pwrseq.o \
rf.o \
sw.o \
table.o \
trx.o
obj-$(CONFIG_RTL8188EE) += rtl8188ee.o
ccflags-y += -Idrivers/net/wireless/rtlwifi -D__CHECK_ENDIAN__

View file

@ -0,0 +1,310 @@
/******************************************************************************
*
* Copyright(c) 2009-2013 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 __RTL92C_DEF_H__
#define __RTL92C_DEF_H__
#define HAL_RETRY_LIMIT_INFRA 48
#define HAL_RETRY_LIMIT_AP_ADHOC 7
#define RESET_DELAY_8185 20
#define RT_IBSS_INT_MASKS (IMR_BCNINT | IMR_TBDOK | IMR_TBDER)
#define RT_AC_INT_MASKS (IMR_VIDOK | IMR_VODOK | IMR_BEDOK|IMR_BKDOK)
#define NUM_OF_FIRMWARE_QUEUE 10
#define NUM_OF_PAGES_IN_FW 0x100
#define NUM_OF_PAGE_IN_FW_QUEUE_BK 0x07
#define NUM_OF_PAGE_IN_FW_QUEUE_BE 0x07
#define NUM_OF_PAGE_IN_FW_QUEUE_VI 0x07
#define NUM_OF_PAGE_IN_FW_QUEUE_VO 0x07
#define NUM_OF_PAGE_IN_FW_QUEUE_HCCA 0x0
#define NUM_OF_PAGE_IN_FW_QUEUE_CMD 0x0
#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT 0x02
#define NUM_OF_PAGE_IN_FW_QUEUE_HIGH 0x02
#define NUM_OF_PAGE_IN_FW_QUEUE_BCN 0x2
#define NUM_OF_PAGE_IN_FW_QUEUE_PUB 0xA1
#define NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM 0x026
#define NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM 0x048
#define NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM 0x048
#define NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM 0x026
#define NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM 0x00
#define MAX_LINES_HWCONFIG_TXT 1000
#define MAX_BYTES_LINE_HWCONFIG_TXT 256
#define SW_THREE_WIRE 0
#define HW_THREE_WIRE 2
#define BT_DEMO_BOARD 0
#define BT_QA_BOARD 1
#define BT_FPGA 2
#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0
#define HAL_PRIME_CHNL_OFFSET_LOWER 1
#define HAL_PRIME_CHNL_OFFSET_UPPER 2
#define MAX_H2C_QUEUE_NUM 10
#define RX_MPDU_QUEUE 0
#define RX_CMD_QUEUE 1
#define RX_MAX_QUEUE 2
#define AC2QUEUEID(_AC) (_AC)
#define C2H_RX_CMD_HDR_LEN 8
#define GET_C2H_CMD_CMD_LEN(__prxhdr) \
LE_BITS_TO_4BYTE((__prxhdr), 0, 16)
#define GET_C2H_CMD_ELEMENT_ID(__prxhdr) \
LE_BITS_TO_4BYTE((__prxhdr), 16, 8)
#define GET_C2H_CMD_CMD_SEQ(__prxhdr) \
LE_BITS_TO_4BYTE((__prxhdr), 24, 7)
#define GET_C2H_CMD_CONTINUE(__prxhdr) \
LE_BITS_TO_4BYTE((__prxhdr), 31, 1)
#define GET_C2H_CMD_CONTENT(__prxhdr) \
((u8 *)(__prxhdr) + C2H_RX_CMD_HDR_LEN)
#define GET_C2H_CMD_FEEDBACK_ELEMENT_ID(__pcmdfbhdr) \
LE_BITS_TO_4BYTE((__pcmdfbhdr), 0, 8)
#define GET_C2H_CMD_FEEDBACK_CCX_LEN(__pcmdfbhdr) \
LE_BITS_TO_4BYTE((__pcmdfbhdr), 8, 8)
#define GET_C2H_CMD_FEEDBACK_CCX_CMD_CNT(__pcmdfbhdr) \
LE_BITS_TO_4BYTE((__pcmdfbhdr), 16, 16)
#define GET_C2H_CMD_FEEDBACK_CCX_MAC_ID(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 0, 5)
#define GET_C2H_CMD_FEEDBACK_CCX_VALID(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 7, 1)
#define GET_C2H_CMD_FEEDBACK_CCX_RETRY_CNT(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 8, 5)
#define GET_C2H_CMD_FEEDBACK_CCX_TOK(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 15, 1)
#define GET_C2H_CMD_FEEDBACK_CCX_QSEL(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 16, 4)
#define GET_C2H_CMD_FEEDBACK_CCX_SEQ(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 20, 12)
#define CHIP_BONDING_IDENTIFIER(_value) (((_value)>>22)&0x3)
/* [15:12] IC version(CUT): A-cut=0, B-cut=1, C-cut=2, D-cut=3
* [7] Manufacturer: TSMC=0, UMC=1
* [6:4] RF type: 1T1R=0, 1T2R=1, 2T2R=2
* [3] Chip type: TEST=0, NORMAL=1
* [2:0] IC type: 81xxC=0, 8723=1, 92D=2
*/
#define CHIP_8723 BIT(0)
#define CHIP_92D BIT(1)
#define NORMAL_CHIP BIT(3)
#define RF_TYPE_1T1R (~(BIT(4)|BIT(5)|BIT(6)))
#define RF_TYPE_1T2R BIT(4)
#define RF_TYPE_2T2R BIT(5)
#define CHIP_VENDOR_UMC BIT(7)
#define B_CUT_VERSION BIT(12)
#define C_CUT_VERSION BIT(13)
#define D_CUT_VERSION ((BIT(12)|BIT(13)))
#define E_CUT_VERSION BIT(14)
/* MASK */
#define IC_TYPE_MASK (BIT(0)|BIT(1)|BIT(2))
#define CHIP_TYPE_MASK BIT(3)
#define RF_TYPE_MASK (BIT(4)|BIT(5)|BIT(6))
#define MANUFACTUER_MASK BIT(7)
#define ROM_VERSION_MASK (BIT(11)|BIT(10)|BIT(9)|BIT(8))
#define CUT_VERSION_MASK (BIT(15)|BIT(14)|BIT(13)|BIT(12))
/* Get element */
#define GET_CVID_IC_TYPE(version) ((version) & IC_TYPE_MASK)
#define GET_CVID_CHIP_TYPE(version) ((version) & CHIP_TYPE_MASK)
#define GET_CVID_RF_TYPE(version) ((version) & RF_TYPE_MASK)
#define GET_CVID_MANUFACTUER(version) ((version) & MANUFACTUER_MASK)
#define GET_CVID_ROM_VERSION(version) ((version) & ROM_VERSION_MASK)
#define GET_CVID_CUT_VERSION(version) ((version) & CUT_VERSION_MASK)
#define IS_81XXC(version) \
((GET_CVID_IC_TYPE(version) == 0) ? true : false)
#define IS_8723_SERIES(version) \
((GET_CVID_IC_TYPE(version) == CHIP_8723) ? true : false)
#define IS_92D(version) \
((GET_CVID_IC_TYPE(version) == CHIP_92D) ? true : false)
#define IS_NORMAL_CHIP(version) \
((GET_CVID_CHIP_TYPE(version)) ? true : false)
#define IS_NORMAL_CHIP92D(version) \
((GET_CVID_CHIP_TYPE(version)) ? true : false)
#define IS_1T1R(version) \
((GET_CVID_RF_TYPE(version)) ? false : true)
#define IS_1T2R(version) \
((GET_CVID_RF_TYPE(version) == RF_TYPE_1T2R) ? true : false)
#define IS_2T2R(version) \
((GET_CVID_RF_TYPE(version) == RF_TYPE_2T2R) ? true : false)
#define IS_CHIP_VENDOR_UMC(version) \
((GET_CVID_MANUFACTUER(version)) ? true : false)
#define IS_92C_SERIAL(version) \
((IS_81XXC(version) && IS_2T2R(version)) ? true : false)
#define IS_81xxC_VENDOR_UMC_A_CUT(version) \
(IS_81XXC(version) ? ((IS_CHIP_VENDOR_UMC(version)) ? \
((GET_CVID_CUT_VERSION(version)) ? false : true) : false) : false)
#define IS_81XXC_VENDOR_UMC_B_CUT(version) \
(IS_81XXC(version) ? (IS_CHIP_VENDOR_UMC(version) ? \
((GET_CVID_CUT_VERSION(version) == B_CUT_VERSION) ? true \
: false) : false) : false)
enum version_8188e {
VERSION_TEST_CHIP_88E = 0x00,
VERSION_NORMAL_CHIP_88E = 0x01,
VERSION_UNKNOWN = 0xFF,
};
enum rx_packet_type {
NORMAL_RX,
TX_REPORT1,
TX_REPORT2,
HIS_REPORT,
};
enum rtl819x_loopback_e {
RTL819X_NO_LOOPBACK = 0,
RTL819X_MAC_LOOPBACK = 1,
RTL819X_DMA_LOOPBACK = 2,
RTL819X_CCK_LOOPBACK = 3,
};
enum rf_optype {
RF_OP_BY_SW_3WIRE = 0,
RF_OP_BY_FW,
RF_OP_MAX
};
enum rf_power_state {
RF_ON,
RF_OFF,
RF_SLEEP,
RF_SHUT_DOWN,
};
enum power_save_mode {
POWER_SAVE_MODE_ACTIVE,
POWER_SAVE_MODE_SAVE,
};
enum power_polocy_config {
POWERCFG_MAX_POWER_SAVINGS,
POWERCFG_GLOBAL_POWER_SAVINGS,
POWERCFG_LOCAL_POWER_SAVINGS,
POWERCFG_LENOVO,
};
enum interface_select_pci {
INTF_SEL1_MINICARD = 0,
INTF_SEL0_PCIE = 1,
INTF_SEL2_RSV = 2,
INTF_SEL3_RSV = 3,
};
enum hal_fw_c2h_cmd_id {
HAL_FW_C2H_CMD_READ_MACREG = 0,
HAL_FW_C2H_CMD_READ_BBREG = 1,
HAL_FW_C2H_CMD_READ_RFREG = 2,
HAL_FW_C2H_CMD_READ_EEPROM = 3,
HAL_FW_C2H_CMD_READ_EFUSE = 4,
HAL_FW_C2H_CMD_READ_CAM = 5,
HAL_FW_C2H_CMD_GET_BASICRATE = 6,
HAL_FW_C2H_CMD_GET_DATARATE = 7,
HAL_FW_C2H_CMD_SURVEY = 8,
HAL_FW_C2H_CMD_SURVEYDONE = 9,
HAL_FW_C2H_CMD_JOINBSS = 10,
HAL_FW_C2H_CMD_ADDSTA = 11,
HAL_FW_C2H_CMD_DELSTA = 12,
HAL_FW_C2H_CMD_ATIMDONE = 13,
HAL_FW_C2H_CMD_TX_REPORT = 14,
HAL_FW_C2H_CMD_CCX_REPORT = 15,
HAL_FW_C2H_CMD_DTM_REPORT = 16,
HAL_FW_C2H_CMD_TX_RATE_STATISTICS = 17,
HAL_FW_C2H_CMD_C2HLBK = 18,
HAL_FW_C2H_CMD_C2HDBG = 19,
HAL_FW_C2H_CMD_C2HFEEDBACK = 20,
HAL_FW_C2H_CMD_MAX
};
enum rtl_desc_qsel {
QSLT_BK = 0x2,
QSLT_BE = 0x0,
QSLT_VI = 0x5,
QSLT_VO = 0x7,
QSLT_BEACON = 0x10,
QSLT_HIGH = 0x11,
QSLT_MGNT = 0x12,
QSLT_CMD = 0x13,
};
enum rtl_desc92c_rate {
DESC92C_RATE1M = 0x00,
DESC92C_RATE2M = 0x01,
DESC92C_RATE5_5M = 0x02,
DESC92C_RATE11M = 0x03,
DESC92C_RATE6M = 0x04,
DESC92C_RATE9M = 0x05,
DESC92C_RATE12M = 0x06,
DESC92C_RATE18M = 0x07,
DESC92C_RATE24M = 0x08,
DESC92C_RATE36M = 0x09,
DESC92C_RATE48M = 0x0a,
DESC92C_RATE54M = 0x0b,
DESC92C_RATEMCS0 = 0x0c,
DESC92C_RATEMCS1 = 0x0d,
DESC92C_RATEMCS2 = 0x0e,
DESC92C_RATEMCS3 = 0x0f,
DESC92C_RATEMCS4 = 0x10,
DESC92C_RATEMCS5 = 0x11,
DESC92C_RATEMCS6 = 0x12,
DESC92C_RATEMCS7 = 0x13,
DESC92C_RATEMCS8 = 0x14,
DESC92C_RATEMCS9 = 0x15,
DESC92C_RATEMCS10 = 0x16,
DESC92C_RATEMCS11 = 0x17,
DESC92C_RATEMCS12 = 0x18,
DESC92C_RATEMCS13 = 0x19,
DESC92C_RATEMCS14 = 0x1a,
DESC92C_RATEMCS15 = 0x1b,
DESC92C_RATEMCS15_SG = 0x1c,
DESC92C_RATEMCS32 = 0x20,
};
struct phy_sts_cck_8192s_t {
u8 adc_pwdb_X[4];
u8 sq_rpt;
u8 cck_agc_rpt;
};
struct h2c_cmd_8192c {
u8 element_id;
u32 cmd_len;
u8 *p_cmdbuffer;
};
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,327 @@
/******************************************************************************
*
* Copyright(c) 2009-2013 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __RTL88E_DM_H__
#define __RTL88E_DM_H__
#define MAIN_ANT 0
#define AUX_ANT 1
#define MAIN_ANT_CG_TRX 1
#define AUX_ANT_CG_TRX 0
#define MAIN_ANT_CGCS_RX 0
#define AUX_ANT_CGCS_RX 1
/*RF REG LIST*/
#define DM_REG_RF_MODE_11N 0x00
#define DM_REG_RF_0B_11N 0x0B
#define DM_REG_CHNBW_11N 0x18
#define DM_REG_T_METER_11N 0x24
#define DM_REG_RF_25_11N 0x25
#define DM_REG_RF_26_11N 0x26
#define DM_REG_RF_27_11N 0x27
#define DM_REG_RF_2B_11N 0x2B
#define DM_REG_RF_2C_11N 0x2C
#define DM_REG_RXRF_A3_11N 0x3C
#define DM_REG_T_METER_92D_11N 0x42
#define DM_REG_T_METER_88E_11N 0x42
/*BB REG LIST*/
/*PAGE 8 */
#define DM_REG_BB_CTRL_11N 0x800
#define DM_REG_RF_PIN_11N 0x804
#define DM_REG_PSD_CTRL_11N 0x808
#define DM_REG_TX_ANT_CTRL_11N 0x80C
#define DM_REG_BB_PWR_SAV5_11N 0x818
#define DM_REG_CCK_RPT_FORMAT_11N 0x824
#define DM_REG_RX_DEFAULT_A_11N 0x858
#define DM_REG_RX_DEFAULT_B_11N 0x85A
#define DM_REG_BB_PWR_SAV3_11N 0x85C
#define DM_REG_ANTSEL_CTRL_11N 0x860
#define DM_REG_RX_ANT_CTRL_11N 0x864
#define DM_REG_PIN_CTRL_11N 0x870
#define DM_REG_BB_PWR_SAV1_11N 0x874
#define DM_REG_ANTSEL_PATH_11N 0x878
#define DM_REG_BB_3WIRE_11N 0x88C
#define DM_REG_SC_CNT_11N 0x8C4
#define DM_REG_PSD_DATA_11N 0x8B4
/*PAGE 9*/
#define DM_REG_ANT_MAPPING1_11N 0x914
#define DM_REG_ANT_MAPPING2_11N 0x918
/*PAGE A*/
#define DM_REG_CCK_ANTDIV_PARA1_11N 0xA00
#define DM_REG_CCK_CCA_11N 0xA0A
#define DM_REG_CCK_ANTDIV_PARA2_11N 0xA0C
#define DM_REG_CCK_ANTDIV_PARA3_11N 0xA10
#define DM_REG_CCK_ANTDIV_PARA4_11N 0xA14
#define DM_REG_CCK_FILTER_PARA1_11N 0xA22
#define DM_REG_CCK_FILTER_PARA2_11N 0xA23
#define DM_REG_CCK_FILTER_PARA3_11N 0xA24
#define DM_REG_CCK_FILTER_PARA4_11N 0xA25
#define DM_REG_CCK_FILTER_PARA5_11N 0xA26
#define DM_REG_CCK_FILTER_PARA6_11N 0xA27
#define DM_REG_CCK_FILTER_PARA7_11N 0xA28
#define DM_REG_CCK_FILTER_PARA8_11N 0xA29
#define DM_REG_CCK_FA_RST_11N 0xA2C
#define DM_REG_CCK_FA_MSB_11N 0xA58
#define DM_REG_CCK_FA_LSB_11N 0xA5C
#define DM_REG_CCK_CCA_CNT_11N 0xA60
#define DM_REG_BB_PWR_SAV4_11N 0xA74
/*PAGE B */
#define DM_REG_LNA_SWITCH_11N 0xB2C
#define DM_REG_PATH_SWITCH_11N 0xB30
#define DM_REG_RSSI_CTRL_11N 0xB38
#define DM_REG_CONFIG_ANTA_11N 0xB68
#define DM_REG_RSSI_BT_11N 0xB9C
/*PAGE C */
#define DM_REG_OFDM_FA_HOLDC_11N 0xC00
#define DM_REG_RX_PATH_11N 0xC04
#define DM_REG_TRMUX_11N 0xC08
#define DM_REG_OFDM_FA_RSTC_11N 0xC0C
#define DM_REG_RXIQI_MATRIX_11N 0xC14
#define DM_REG_TXIQK_MATRIX_LSB1_11N 0xC4C
#define DM_REG_IGI_A_11N 0xC50
#define DM_REG_ANTDIV_PARA2_11N 0xC54
#define DM_REG_IGI_B_11N 0xC58
#define DM_REG_ANTDIV_PARA3_11N 0xC5C
#define DM_REG_BB_PWR_SAV2_11N 0xC70
#define DM_REG_RX_OFF_11N 0xC7C
#define DM_REG_TXIQK_MATRIXA_11N 0xC80
#define DM_REG_TXIQK_MATRIXB_11N 0xC88
#define DM_REG_TXIQK_MATRIXA_LSB2_11N 0xC94
#define DM_REG_TXIQK_MATRIXB_LSB2_11N 0xC9C
#define DM_REG_RXIQK_MATRIX_LSB_11N 0xCA0
#define DM_REG_ANTDIV_PARA1_11N 0xCA4
#define DM_REG_OFDM_FA_TYPE1_11N 0xCF0
/*PAGE D */
#define DM_REG_OFDM_FA_RSTD_11N 0xD00
#define DM_REG_OFDM_FA_TYPE2_11N 0xDA0
#define DM_REG_OFDM_FA_TYPE3_11N 0xDA4
#define DM_REG_OFDM_FA_TYPE4_11N 0xDA8
/*PAGE E */
#define DM_REG_TXAGC_A_6_18_11N 0xE00
#define DM_REG_TXAGC_A_24_54_11N 0xE04
#define DM_REG_TXAGC_A_1_MCS32_11N 0xE08
#define DM_REG_TXAGC_A_MCS0_3_11N 0xE10
#define DM_REG_TXAGC_A_MCS4_7_11N 0xE14
#define DM_REG_TXAGC_A_MCS8_11_11N 0xE18
#define DM_REG_TXAGC_A_MCS12_15_11N 0xE1C
#define DM_REG_FPGA0_IQK_11N 0xE28
#define DM_REG_TXIQK_TONE_A_11N 0xE30
#define DM_REG_RXIQK_TONE_A_11N 0xE34
#define DM_REG_TXIQK_PI_A_11N 0xE38
#define DM_REG_RXIQK_PI_A_11N 0xE3C
#define DM_REG_TXIQK_11N 0xE40
#define DM_REG_RXIQK_11N 0xE44
#define DM_REG_IQK_AGC_PTS_11N 0xE48
#define DM_REG_IQK_AGC_RSP_11N 0xE4C
#define DM_REG_BLUETOOTH_11N 0xE6C
#define DM_REG_RX_WAIT_CCA_11N 0xE70
#define DM_REG_TX_CCK_RFON_11N 0xE74
#define DM_REG_TX_CCK_BBON_11N 0xE78
#define DM_REG_OFDM_RFON_11N 0xE7C
#define DM_REG_OFDM_BBON_11N 0xE80
#define DM_REG_TX2RX_11N 0xE84
#define DM_REG_TX2TX_11N 0xE88
#define DM_REG_RX_CCK_11N 0xE8C
#define DM_REG_RX_OFDM_11N 0xED0
#define DM_REG_RX_WAIT_RIFS_11N 0xED4
#define DM_REG_RX2RX_11N 0xED8
#define DM_REG_STANDBY_11N 0xEDC
#define DM_REG_SLEEP_11N 0xEE0
#define DM_REG_PMPD_ANAEN_11N 0xEEC
/*MAC REG LIST*/
#define DM_REG_BB_RST_11N 0x02
#define DM_REG_ANTSEL_PIN_11N 0x4C
#define DM_REG_EARLY_MODE_11N 0x4D0
#define DM_REG_RSSI_MONITOR_11N 0x4FE
#define DM_REG_EDCA_VO_11N 0x500
#define DM_REG_EDCA_VI_11N 0x504
#define DM_REG_EDCA_BE_11N 0x508
#define DM_REG_EDCA_BK_11N 0x50C
#define DM_REG_TXPAUSE_11N 0x522
#define DM_REG_RESP_TX_11N 0x6D8
#define DM_REG_ANT_TRAIN_PARA1_11N 0x7b0
#define DM_REG_ANT_TRAIN_PARA2_11N 0x7b4
/*DIG Related*/
#define DM_BIT_IGI_11N 0x0000007F
#define HAL_DM_DIG_DISABLE BIT(0)
#define HAL_DM_HIPWR_DISABLE BIT(1)
#define OFDM_TABLE_LENGTH 43
#define CCK_TABLE_LENGTH 33
#define OFDM_TABLE_SIZE 43
#define CCK_TABLE_SIZE 33
#define BW_AUTO_SWITCH_HIGH_LOW 25
#define BW_AUTO_SWITCH_LOW_HIGH 30
#define DM_DIG_THRESH_HIGH 40
#define DM_DIG_THRESH_LOW 35
#define DM_FALSEALARM_THRESH_LOW 400
#define DM_FALSEALARM_THRESH_HIGH 1000
#define DM_DIG_MAX 0x3e
#define DM_DIG_MIN 0x1e
#define DM_DIG_MAX_AP 0x32
#define DM_DIG_MIN_AP 0x20
#define DM_DIG_FA_UPPER 0x3e
#define DM_DIG_FA_LOWER 0x1e
#define DM_DIG_FA_TH0 0x200
#define DM_DIG_FA_TH1 0x300
#define DM_DIG_FA_TH2 0x400
#define DM_DIG_BACKOFF_MAX 12
#define DM_DIG_BACKOFF_MIN -4
#define DM_DIG_BACKOFF_DEFAULT 10
#define RXPATHSELECTION_SS_TH_W 30
#define RXPATHSELECTION_DIFF_TH 18
#define DM_RATR_STA_INIT 0
#define DM_RATR_STA_HIGH 1
#define DM_RATR_STA_MIDDLE 2
#define DM_RATR_STA_LOW 3
#define CTS2SELF_THVAL 30
#define REGC38_TH 20
#define WAIOTTHVAL 25
#define TXHIGHPWRLEVEL_NORMAL 0
#define TXHIGHPWRLEVEL_LEVEL1 1
#define TXHIGHPWRLEVEL_LEVEL2 2
#define TXHIGHPWRLEVEL_BT1 3
#define TXHIGHPWRLEVEL_BT2 4
#define DM_TYPE_BYFW 0
#define DM_TYPE_BYDRIVER 1
#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74
#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67
#define TXPWRTRACK_MAX_IDX 6
struct swat_t {
u8 failure_cnt;
u8 try_flag;
u8 stop_trying;
long pre_rssi;
long trying_threshold;
u8 cur_antenna;
u8 pre_antenna;
};
enum FAT_STATE {
FAT_NORMAL_STATE = 0,
FAT_TRAINING_STATE = 1,
};
enum tag_dynamic_init_gain_operation_type_definition {
DIG_TYPE_THRESH_HIGH = 0,
DIG_TYPE_THRESH_LOW = 1,
DIG_TYPE_BACKOFF = 2,
DIG_TYPE_RX_GAIN_MIN = 3,
DIG_TYPE_RX_GAIN_MAX = 4,
DIG_TYPE_ENABLE = 5,
DIG_TYPE_DISABLE = 6,
DIG_OP_TYPE_MAX
};
enum tag_cck_packet_detection_threshold_type_definition {
CCK_PD_STAGE_LOWRSSI = 0,
CCK_PD_STAGE_HIGHRSSI = 1,
CCK_FA_STAGE_LOW = 2,
CCK_FA_STAGE_HIGH = 3,
CCK_PD_STAGE_MAX = 4,
};
enum dm_1r_cca_e {
CCA_1R = 0,
CCA_2R = 1,
CCA_MAX = 2,
};
enum dm_rf_e {
RF_SAVE = 0,
RF_NORMAL = 1,
RF_MAX = 2,
};
enum dm_sw_ant_switch_e {
ANS_ANTENNA_B = 1,
ANS_ANTENNA_A = 2,
ANS_ANTENNA_MAX = 3,
};
enum dm_dig_ext_port_alg_e {
DIG_EXT_PORT_STAGE_0 = 0,
DIG_EXT_PORT_STAGE_1 = 1,
DIG_EXT_PORT_STAGE_2 = 2,
DIG_EXT_PORT_STAGE_3 = 3,
DIG_EXT_PORT_STAGE_MAX = 4,
};
enum dm_dig_connect_e {
DIG_STA_DISCONNECT = 0,
DIG_STA_CONNECT = 1,
DIG_STA_BEFORE_CONNECT = 2,
DIG_MULTISTA_DISCONNECT = 3,
DIG_MULTISTA_CONNECT = 4,
DIG_CONNECT_MAX
};
enum pwr_track_control_method {
BBSWING,
TXAGC
};
void rtl88e_dm_set_tx_ant_by_tx_info(struct ieee80211_hw *hw,
u8 *pdesc, u32 mac_id);
void rtl88e_dm_ant_sel_statistics(struct ieee80211_hw *hw,
u8 antsel_tr_mux, u32 mac_id,
u32 rx_pwdb_all);
void rtl88e_dm_fast_antenna_training_callback(unsigned long data);
void rtl88e_dm_init(struct ieee80211_hw *hw);
void rtl88e_dm_watchdog(struct ieee80211_hw *hw);
void rtl88e_dm_write_dig(struct ieee80211_hw *hw);
void rtl88e_dm_init_edca_turbo(struct ieee80211_hw *hw);
void rtl88e_dm_check_txpower_tracking(struct ieee80211_hw *hw);
void rtl88e_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw);
void rtl88e_dm_txpower_track_adjust(struct ieee80211_hw *hw,
u8 type, u8 *pdirection, u32 *poutwrite_val);
#endif

View file

@ -0,0 +1,815 @@
/******************************************************************************
*
* Copyright(c) 2009-2013 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 "../wifi.h"
#include "../pci.h"
#include "../base.h"
#include "../core.h"
#include "reg.h"
#include "def.h"
#include "fw.h"
static void _rtl88e_enable_fw_download(struct ieee80211_hw *hw, bool enable)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u8 tmp;
if (enable) {
tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp | 0x04);
tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01);
tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2);
rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7);
} else {
tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe);
rtl_write_byte(rtlpriv, REG_MCUFWDL + 1, 0x00);
}
}
static void _rtl88e_fw_block_write(struct ieee80211_hw *hw,
const u8 *buffer, u32 size)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u32 blocksize = sizeof(u32);
u8 *bufferptr = (u8 *)buffer;
u32 *pu4BytePtr = (u32 *)buffer;
u32 i, offset, blockcount, remainsize;
blockcount = size / blocksize;
remainsize = size % blocksize;
for (i = 0; i < blockcount; i++) {
offset = i * blocksize;
rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset),
*(pu4BytePtr + i));
}
if (remainsize) {
offset = blockcount * blocksize;
bufferptr += offset;
for (i = 0; i < remainsize; i++) {
rtl_write_byte(rtlpriv, (FW_8192C_START_ADDRESS +
offset + i), *(bufferptr + i));
}
}
}
static void _rtl88e_fw_page_write(struct ieee80211_hw *hw,
u32 page, const u8 *buffer, u32 size)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u8 value8;
u8 u8page = (u8) (page & 0x07);
value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page;
rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8);
_rtl88e_fw_block_write(hw, buffer, size);
}
static void _rtl88e_fill_dummy(u8 *pfwbuf, u32 *pfwlen)
{
u32 fwlen = *pfwlen;
u8 remain = (u8) (fwlen % 4);
remain = (remain == 0) ? 0 : (4 - remain);
while (remain > 0) {
pfwbuf[fwlen] = 0;
fwlen++;
remain--;
}
*pfwlen = fwlen;
}
static void _rtl88e_write_fw(struct ieee80211_hw *hw,
enum version_8188e version, u8 *buffer, u32 size)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u8 *bufferptr = (u8 *)buffer;
u32 pagenums, remainsize;
u32 page, offset;
RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "FW size is %d bytes,\n", size);
_rtl88e_fill_dummy(bufferptr, &size);
pagenums = size / FW_8192C_PAGE_SIZE;
remainsize = size % FW_8192C_PAGE_SIZE;
if (pagenums > 8) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"Page numbers should not greater then 8\n");
}
for (page = 0; page < pagenums; page++) {
offset = page * FW_8192C_PAGE_SIZE;
_rtl88e_fw_page_write(hw, page, (bufferptr + offset),
FW_8192C_PAGE_SIZE);
}
if (remainsize) {
offset = pagenums * FW_8192C_PAGE_SIZE;
page = pagenums;
_rtl88e_fw_page_write(hw, page, (bufferptr + offset),
remainsize);
}
}
static int _rtl88e_fw_free_to_go(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
int err = -EIO;
u32 counter = 0;
u32 value32;
do {
value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
} while ((counter++ < FW_8192C_POLLING_TIMEOUT_COUNT) &&
(!(value32 & FWDL_CHKSUM_RPT)));
if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"chksum report faill ! REG_MCUFWDL:0x%08x .\n",
value32);
goto exit;
}
RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
"Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32);
value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
value32 |= MCUFWDL_RDY;
value32 &= ~WINTINI_RDY;
rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
rtl88e_firmware_selfreset(hw);
counter = 0;
do {
value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
if (value32 & WINTINI_RDY) {
RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
"Polling FW ready success!! REG_MCUFWDL:0x%08x.\n",
value32);
err = 0;
goto exit;
}
udelay(FW_8192C_POLLING_DELAY);
} while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT);
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", value32);
exit:
return err;
}
int rtl88e_download_fw(struct ieee80211_hw *hw,
bool buse_wake_on_wlan_fw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
struct rtl92c_firmware_header *pfwheader;
u8 *pfwdata;
u32 fwsize;
int err;
enum version_8188e version = rtlhal->version;
if (!rtlhal->pfirmware)
return 1;
pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware;
pfwdata = rtlhal->pfirmware;
fwsize = rtlhal->fwsize;
RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
"normal Firmware SIZE %d\n", fwsize);
if (IS_FW_HEADER_EXIST(pfwheader)) {
RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
"Firmware Version(%d), Signature(%#x), Size(%d)\n",
pfwheader->version, pfwheader->signature,
(int)sizeof(struct rtl92c_firmware_header));
pfwdata = pfwdata + sizeof(struct rtl92c_firmware_header);
fwsize = fwsize - sizeof(struct rtl92c_firmware_header);
}
if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) {
rtl_write_byte(rtlpriv, REG_MCUFWDL, 0);
rtl88e_firmware_selfreset(hw);
}
_rtl88e_enable_fw_download(hw, true);
_rtl88e_write_fw(hw, version, pfwdata, fwsize);
_rtl88e_enable_fw_download(hw, false);
err = _rtl88e_fw_free_to_go(hw);
if (err) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"Firmware is not ready to run!\n");
} else {
RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD,
"Firmware is ready to run!\n");
}
return 0;
}
static bool _rtl88e_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u8 val_hmetfr;
val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
if (((val_hmetfr >> boxnum) & BIT(0)) == 0)
return true;
return false;
}
static void _rtl88e_fill_h2c_command(struct ieee80211_hw *hw,
u8 element_id, u32 cmd_len,
u8 *cmd_b)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
u8 boxnum;
u16 box_reg = 0, box_extreg = 0;
u8 u1b_tmp;
bool isfw_read = false;
u8 buf_index = 0;
bool write_sucess = false;
u8 wait_h2c_limmit = 100;
u8 wait_writeh2c_limit = 100;
u8 boxcontent[4], boxextcontent[4];
u32 h2c_waitcounter = 0;
unsigned long flag;
u8 idx;
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n");
while (true) {
spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
if (rtlhal->h2c_setinprogress) {
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
"H2C set in progress! Wait to set..element_id(%d).\n",
element_id);
while (rtlhal->h2c_setinprogress) {
spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
flag);
h2c_waitcounter++;
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
"Wait 100 us (%d times)...\n",
h2c_waitcounter);
udelay(100);
if (h2c_waitcounter > 1000)
return;
spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
flag);
}
spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
} else {
rtlhal->h2c_setinprogress = true;
spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
break;
}
}
while (!write_sucess) {
wait_writeh2c_limit--;
if (wait_writeh2c_limit == 0) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"Write H2C fail because no trigger for FW INT!\n");
break;
}
boxnum = rtlhal->last_hmeboxnum;
switch (boxnum) {
case 0:
box_reg = REG_HMEBOX_0;
box_extreg = REG_HMEBOX_EXT_0;
break;
case 1:
box_reg = REG_HMEBOX_1;
box_extreg = REG_HMEBOX_EXT_1;
break;
case 2:
box_reg = REG_HMEBOX_2;
box_extreg = REG_HMEBOX_EXT_2;
break;
case 3:
box_reg = REG_HMEBOX_3;
box_extreg = REG_HMEBOX_EXT_3;
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
"switch case not process\n");
break;
}
isfw_read = _rtl88e_check_fw_read_last_h2c(hw, boxnum);
while (!isfw_read) {
wait_h2c_limmit--;
if (wait_h2c_limmit == 0) {
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
"Waiting too long for FW read clear HMEBox(%d)!\n",
boxnum);
break;
}
udelay(10);
isfw_read = _rtl88e_check_fw_read_last_h2c(hw, boxnum);
u1b_tmp = rtl_read_byte(rtlpriv, 0x130);
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
"Waiting for FW read clear HMEBox(%d)!!! 0x130 = %2x\n",
boxnum, u1b_tmp);
}
if (!isfw_read) {
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
"Write H2C register BOX[%d] fail!!!!! Fw do not read.\n",
boxnum);
break;
}
memset(boxcontent, 0, sizeof(boxcontent));
memset(boxextcontent, 0, sizeof(boxextcontent));
boxcontent[0] = element_id;
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
"Write element_id box_reg(%4x) = %2x\n",
box_reg, element_id);
switch (cmd_len) {
case 1:
case 2:
case 3:
/*boxcontent[0] &= ~(BIT(7));*/
memcpy((u8 *)(boxcontent) + 1,
cmd_b + buf_index, cmd_len);
for (idx = 0; idx < 4; idx++) {
rtl_write_byte(rtlpriv, box_reg + idx,
boxcontent[idx]);
}
break;
case 4:
case 5:
case 6:
case 7:
/*boxcontent[0] |= (BIT(7));*/
memcpy((u8 *)(boxextcontent),
cmd_b + buf_index+3, cmd_len-3);
memcpy((u8 *)(boxcontent) + 1,
cmd_b + buf_index, 3);
for (idx = 0; idx < 2; idx++) {
rtl_write_byte(rtlpriv, box_extreg + idx,
boxextcontent[idx]);
}
for (idx = 0; idx < 4; idx++) {
rtl_write_byte(rtlpriv, box_reg + idx,
boxcontent[idx]);
}
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
"switch case not process\n");
break;
}
write_sucess = true;
rtlhal->last_hmeboxnum = boxnum + 1;
if (rtlhal->last_hmeboxnum == 4)
rtlhal->last_hmeboxnum = 0;
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
"pHalData->last_hmeboxnum = %d\n",
rtlhal->last_hmeboxnum);
}
spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
rtlhal->h2c_setinprogress = false;
spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n");
}
void rtl88e_fill_h2c_cmd(struct ieee80211_hw *hw,
u8 element_id, u32 cmd_len, u8 *cmdbuffer)
{
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
u32 tmp_cmdbuf[2];
if (!rtlhal->fw_ready) {
RT_ASSERT(false,
"return H2C cmd because of Fw download fail!!!\n");
return;
}
memset(tmp_cmdbuf, 0, 8);
memcpy(tmp_cmdbuf, cmdbuffer, cmd_len);
_rtl88e_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf);
return;
}
void rtl88e_firmware_selfreset(struct ieee80211_hw *hw)
{
u8 u1b_tmp;
struct rtl_priv *rtlpriv = rtl_priv(hw);
u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN+1);
rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN+1, (u1b_tmp & (~BIT(2))));
rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN+1, (u1b_tmp | BIT(2)));
RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
"8051Reset88E(): 8051 reset success\n");
}
void rtl88e_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u8 u1_h2c_set_pwrmode[H2C_88E_PWEMODE_LENGTH] = { 0 };
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
u8 rlbm, power_state = 0;
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode);
SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, ((mode) ? 1 : 0));
rlbm = 0;/*YJ, temp, 120316. FW now not support RLBM=2.*/
SET_H2CCMD_PWRMODE_PARM_RLBM(u1_h2c_set_pwrmode, rlbm);
SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode,
(rtlpriv->mac80211.p2p) ? ppsc->smart_ps : 1);
SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(u1_h2c_set_pwrmode,
ppsc->reg_max_lps_awakeintvl);
SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1_h2c_set_pwrmode, 0);
if (mode == FW_PS_ACTIVE_MODE)
power_state |= FW_PWR_STATE_ACTIVE;
else
power_state |= FW_PWR_STATE_RF_OFF;
SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1_h2c_set_pwrmode, power_state);
RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
"rtl92c_set_fw_pwrmode(): u1_h2c_set_pwrmode\n",
u1_h2c_set_pwrmode, H2C_88E_PWEMODE_LENGTH);
rtl88e_fill_h2c_cmd(hw, H2C_88E_SETPWRMODE,
H2C_88E_PWEMODE_LENGTH, u1_h2c_set_pwrmode);
}
void rtl88e_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus)
{
u8 u1_joinbssrpt_parm[1] = { 0 };
SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus);
rtl88e_fill_h2c_cmd(hw, H2C_88E_JOINBSSRPT, 1, u1_joinbssrpt_parm);
}
void rtl88e_set_fw_ap_off_load_cmd(struct ieee80211_hw *hw,
u8 ap_offload_enable)
{
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
u8 u1_apoffload_parm[H2C_88E_AP_OFFLOAD_LENGTH] = { 0 };
SET_H2CCMD_AP_OFFLOAD_ON(u1_apoffload_parm, ap_offload_enable);
SET_H2CCMD_AP_OFFLOAD_HIDDEN(u1_apoffload_parm, mac->hiddenssid);
SET_H2CCMD_AP_OFFLOAD_DENYANY(u1_apoffload_parm, 0);
rtl88e_fill_h2c_cmd(hw, H2C_88E_AP_OFFLOAD,
H2C_88E_AP_OFFLOAD_LENGTH, u1_apoffload_parm);
}
#define BEACON_PG 0 /* ->1 */
#define PSPOLL_PG 2
#define NULL_PG 3
#define PROBERSP_PG 4 /* ->5 */
#define TOTAL_RESERVED_PKT_LEN 768
static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
/* page 0 beacon */
0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* page 1 beacon */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* page 2 ps-poll */
0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10,
0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* page 3 null */
0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* page 4 probe_resp */
0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* page 5 probe_resp */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
void rtl88e_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
struct sk_buff *skb = NULL;
u32 totalpacketlen;
bool rtstatus;
u8 u1rsvdpageloc[5] = { 0 };
bool b_dlok = false;
u8 *beacon;
u8 *p_pspoll;
u8 *nullfunc;
u8 *p_probersp;
/*---------------------------------------------------------
* (1) beacon
*---------------------------------------------------------
*/
beacon = &reserved_page_packet[BEACON_PG * 128];
SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
/*-------------------------------------------------------
* (2) ps-poll
*--------------------------------------------------------
*/
p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1rsvdpageloc, PSPOLL_PG);
/*--------------------------------------------------------
* (3) null data
*---------------------------------------------------------
*/
nullfunc = &reserved_page_packet[NULL_PG * 128];
SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1rsvdpageloc, NULL_PG);
/*---------------------------------------------------------
* (4) probe response
*----------------------------------------------------------
*/
p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1rsvdpageloc, PROBERSP_PG);
totalpacketlen = TOTAL_RESERVED_PKT_LEN;
RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
"rtl88e_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
&reserved_page_packet[0], totalpacketlen);
RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
"rtl88e_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
u1rsvdpageloc, 3);
skb = dev_alloc_skb(totalpacketlen);
memcpy(skb_put(skb, totalpacketlen),
&reserved_page_packet, totalpacketlen);
rtstatus = rtl_cmd_send_packet(hw, skb);
if (rtstatus)
b_dlok = true;
if (b_dlok) {
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
"Set RSVD page location to Fw.\n");
RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
"H2C_RSVDPAGE:\n", u1rsvdpageloc, 3);
rtl88e_fill_h2c_cmd(hw, H2C_88E_RSVDPAGE,
sizeof(u1rsvdpageloc), u1rsvdpageloc);
} else
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
"Set RSVD page location to Fw FAIL!!!!!!.\n");
}
/*Should check FW support p2p or not.*/
static void rtl88e_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw, u8 ctwindow)
{
u8 u1_ctwindow_period[1] = { ctwindow};
rtl88e_fill_h2c_cmd(hw, H2C_88E_P2P_PS_CTW_CMD, 1, u1_ctwindow_period);
}
void rtl88e_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw));
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
struct rtl_p2p_ps_info *p2pinfo = &(rtlps->p2p_ps_info);
struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload;
u8 i;
u16 ctwindow;
u32 start_time, tsf_low;
switch (p2p_ps_state) {
case P2P_PS_DISABLE:
RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_DISABLE\n");
memset(p2p_ps_offload, 0, sizeof(*p2p_ps_offload));
break;
case P2P_PS_ENABLE:
RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_ENABLE\n");
/* update CTWindow value. */
if (p2pinfo->ctwindow > 0) {
p2p_ps_offload->ctwindow_en = 1;
ctwindow = p2pinfo->ctwindow;
rtl88e_set_p2p_ctw_period_cmd(hw, ctwindow);
}
/* hw only support 2 set of NoA */
for (i = 0 ; i < p2pinfo->noa_num; i++) {
/* To control the register setting for which NOA*/
rtl_write_byte(rtlpriv, 0x5cf, (i << 4));
if (i == 0)
p2p_ps_offload->noa0_en = 1;
else
p2p_ps_offload->noa1_en = 1;
/* config P2P NoA Descriptor Register */
rtl_write_dword(rtlpriv, 0x5E0,
p2pinfo->noa_duration[i]);
rtl_write_dword(rtlpriv, 0x5E4,
p2pinfo->noa_interval[i]);
/*Get Current TSF value */
tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
start_time = p2pinfo->noa_start_time[i];
if (p2pinfo->noa_count_type[i] != 1) {
while (start_time <= (tsf_low+(50*1024))) {
start_time += p2pinfo->noa_interval[i];
if (p2pinfo->noa_count_type[i] != 255)
p2pinfo->noa_count_type[i]--;
}
}
rtl_write_dword(rtlpriv, 0x5E8, start_time);
rtl_write_dword(rtlpriv, 0x5EC,
p2pinfo->noa_count_type[i]);
}
if ((p2pinfo->opp_ps == 1) || (p2pinfo->noa_num > 0)) {
/* rst p2p circuit */
rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, BIT(4));
p2p_ps_offload->offload_en = 1;
if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) {
p2p_ps_offload->role = 1;
p2p_ps_offload->allstasleep = -1;
} else {
p2p_ps_offload->role = 0;
}
p2p_ps_offload->discovery = 0;
}
break;
case P2P_PS_SCAN:
RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n");
p2p_ps_offload->discovery = 1;
break;
case P2P_PS_SCAN_DONE:
RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN_DONE\n");
p2p_ps_offload->discovery = 0;
p2pinfo->p2p_ps_state = P2P_PS_ENABLE;
break;
default:
break;
}
rtl88e_fill_h2c_cmd(hw, H2C_88E_P2P_PS_OFFLOAD, 1,
(u8 *)p2p_ps_offload);
}

View file

@ -0,0 +1,304 @@
/******************************************************************************
*
* Copyright(c) 2009-2013 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __RTL92C__FW__H__
#define __RTL92C__FW__H__
#define FW_8192C_SIZE 0x8000
#define FW_8192C_START_ADDRESS 0x1000
#define FW_8192C_END_ADDRESS 0x5FFF
#define FW_8192C_PAGE_SIZE 4096
#define FW_8192C_POLLING_DELAY 5
#define FW_8192C_POLLING_TIMEOUT_COUNT 3000
#define IS_FW_HEADER_EXIST(_pfwhdr) \
((_pfwhdr->signature&0xFFFF) == 0x88E1)
#define USE_OLD_WOWLAN_DEBUG_FW 0
#define H2C_88E_RSVDPAGE_LOC_LEN 5
#define H2C_88E_PWEMODE_LENGTH 5
#define H2C_88E_JOINBSSRPT_LENGTH 1
#define H2C_88E_AP_OFFLOAD_LENGTH 3
#define H2C_88E_WOWLAN_LENGTH 3
#define H2C_88E_KEEP_ALIVE_CTRL_LENGTH 3
#if (USE_OLD_WOWLAN_DEBUG_FW == 0)
#define H2C_88E_REMOTE_WAKE_CTRL_LEN 1
#else
#define H2C_88E_REMOTE_WAKE_CTRL_LEN 3
#endif
#define H2C_88E_AOAC_GLOBAL_INFO_LEN 2
#define H2C_88E_AOAC_RSVDPAGE_LOC_LEN 7
/* Fw PS state for RPWM.
*BIT[2:0] = HW state
*BIT[3] = Protocol PS state,
*1: register active state , 0: register sleep state
*BIT[4] = sub-state
*/
#define FW_PS_GO_ON BIT(0)
#define FW_PS_TX_NULL BIT(1)
#define FW_PS_RF_ON BIT(2)
#define FW_PS_REGISTER_ACTIVE BIT(3)
#define FW_PS_DPS BIT(0)
#define FW_PS_LCLK (FW_PS_DPS)
#define FW_PS_RF_OFF BIT(1)
#define FW_PS_ALL_ON BIT(2)
#define FW_PS_ST_ACTIVE BIT(3)
#define FW_PS_ISR_ENABLE BIT(4)
#define FW_PS_IMR_ENABLE BIT(5)
#define FW_PS_ACK BIT(6)
#define FW_PS_TOGGLE BIT(7)
/* 88E RPWM value*/
/* BIT[0] = 1: 32k, 0: 40M*/
#define FW_PS_CLOCK_OFF BIT(0) /* 32k*/
#define FW_PS_CLOCK_ON 0 /*40M*/
#define FW_PS_STATE_MASK (0x0F)
#define FW_PS_STATE_HW_MASK (0x07)
/*ISR_ENABLE, IMR_ENABLE, and PS mode should be inherited.*/
#define FW_PS_STATE_INT_MASK (0x3F)
#define FW_PS_STATE(x) (FW_PS_STATE_MASK & (x))
#define FW_PS_STATE_HW(x) (FW_PS_STATE_HW_MASK & (x))
#define FW_PS_STATE_INT(x) (FW_PS_STATE_INT_MASK & (x))
#define FW_PS_ISR_VAL(x) ((x) & 0x70)
#define FW_PS_IMR_MASK(x) ((x) & 0xDF)
#define FW_PS_KEEP_IMR(x) ((x) & 0x20)
#define FW_PS_STATE_S0 (FW_PS_DPS)
#define FW_PS_STATE_S1 (FW_PS_LCLK)
#define FW_PS_STATE_S2 (FW_PS_RF_OFF)
#define FW_PS_STATE_S3 (FW_PS_ALL_ON)
#define FW_PS_STATE_S4 ((FW_PS_ST_ACTIVE) | (FW_PS_ALL_ON))
/* ((FW_PS_RF_ON) | (FW_PS_REGISTER_ACTIVE))*/
#define FW_PS_STATE_ALL_ON_88E (FW_PS_CLOCK_ON)
/* (FW_PS_RF_ON)*/
#define FW_PS_STATE_RF_ON_88E (FW_PS_CLOCK_ON)
/* 0x0*/
#define FW_PS_STATE_RF_OFF_88E (FW_PS_CLOCK_ON)
/* (FW_PS_STATE_RF_OFF)*/
#define FW_PS_STATE_RF_OFF_LOW_PWR_88E (FW_PS_CLOCK_OFF)
#define FW_PS_STATE_ALL_ON_92C (FW_PS_STATE_S4)
#define FW_PS_STATE_RF_ON_92C (FW_PS_STATE_S3)
#define FW_PS_STATE_RF_OFF_92C (FW_PS_STATE_S2)
#define FW_PS_STATE_RF_OFF_LOW_PWR_92C (FW_PS_STATE_S1)
/* For 88E H2C PwrMode Cmd ID 5.*/
#define FW_PWR_STATE_ACTIVE ((FW_PS_RF_ON) | (FW_PS_REGISTER_ACTIVE))
#define FW_PWR_STATE_RF_OFF 0
#define FW_PS_IS_ACK(x) ((x) & FW_PS_ACK)
#define FW_PS_IS_CLK_ON(x) ((x) & (FW_PS_RF_OFF | FW_PS_ALL_ON))
#define FW_PS_IS_RF_ON(x) ((x) & (FW_PS_ALL_ON))
#define FW_PS_IS_ACTIVE(x) ((x) & (FW_PS_ST_ACTIVE))
#define FW_PS_IS_CPWM_INT(x) ((x) & 0x40)
#define FW_CLR_PS_STATE(x) ((x) = ((x) & (0xF0)))
#define IS_IN_LOW_POWER_STATE_88E(fwpsstate) \
(FW_PS_STATE(fwpsstate) == FW_PS_CLOCK_OFF)
#define FW_PWR_STATE_ACTIVE ((FW_PS_RF_ON) | (FW_PS_REGISTER_ACTIVE))
#define FW_PWR_STATE_RF_OFF 0
struct rtl92c_firmware_header {
u16 signature;
u8 category;
u8 function;
u16 version;
u8 subversion;
u8 rsvd1;
u8 month;
u8 date;
u8 hour;
u8 minute;
u16 ramcodesize;
u16 rsvd2;
u32 svnindex;
u32 rsvd3;
u32 rsvd4;
u32 rsvd5;
};
enum rtl8188e_h2c_cmd {
H2C_88E_RSVDPAGE = 0,
H2C_88E_JOINBSSRPT = 1,
H2C_88E_SCAN = 2,
H2C_88E_KEEP_ALIVE_CTRL = 3,
H2C_88E_DISCONNECT_DECISION = 4,
#if (USE_OLD_WOWLAN_DEBUG_FW == 1)
H2C_88E_WO_WLAN = 5,
#endif
H2C_88E_INIT_OFFLOAD = 6,
#if (USE_OLD_WOWLAN_DEBUG_FW == 1)
H2C_88E_REMOTE_WAKE_CTRL = 7,
#endif
H2C_88E_AP_OFFLOAD = 8,
H2C_88E_BCN_RSVDPAGE = 9,
H2C_88E_PROBERSP_RSVDPAGE = 10,
H2C_88E_SETPWRMODE = 0x20,
H2C_88E_PS_TUNING_PARA = 0x21,
H2C_88E_PS_TUNING_PARA2 = 0x22,
H2C_88E_PS_LPS_PARA = 0x23,
H2C_88E_P2P_PS_OFFLOAD = 024,
#if (USE_OLD_WOWLAN_DEBUG_FW == 0)
H2C_88E_WO_WLAN = 0x80,
H2C_88E_REMOTE_WAKE_CTRL = 0x81,
H2C_88E_AOAC_GLOBAL_INFO = 0x82,
H2C_88E_AOAC_RSVDPAGE = 0x83,
#endif
/*Not defined in new 88E H2C CMD Format*/
H2C_88E_RA_MASK,
H2C_88E_SELECTIVE_SUSPEND_ROF_CMD,
H2C_88E_P2P_PS_MODE,
H2C_88E_PSD_RESULT,
/*Not defined CTW CMD for P2P yet*/
H2C_88E_P2P_PS_CTW_CMD,
MAX_88E_H2CCMD
};
#define pagenum_128(_len) (u32)(((_len)>>7) + ((_len)&0x7F ? 1 : 0))
#define SET_88E_H2CCMD_WOWLAN_FUNC_ENABLE(__cmd, __value) \
SET_BITS_TO_LE_1BYTE(__cmd, 0, 1, __value)
#define SET_88E_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(__cmd, __value) \
SET_BITS_TO_LE_1BYTE(__cmd, 1, 1, __value)
#define SET_88E_H2CCMD_WOWLAN_MAGIC_PKT_ENABLE(__cmd, __value) \
SET_BITS_TO_LE_1BYTE(__cmd, 2, 1, __value)
#define SET_88E_H2CCMD_WOWLAN_UNICAST_PKT_ENABLE(__cmd, __value) \
SET_BITS_TO_LE_1BYTE(__cmd, 3, 1, __value)
#define SET_88E_H2CCMD_WOWLAN_ALL_PKT_DROP(__cmd, __value) \
SET_BITS_TO_LE_1BYTE(__cmd, 4, 1, __value)
#define SET_88E_H2CCMD_WOWLAN_GPIO_ACTIVE(__cmd, __value) \
SET_BITS_TO_LE_1BYTE(__cmd, 5, 1, __value)
#define SET_88E_H2CCMD_WOWLAN_REKEY_WAKE_UP(__cmd, __value) \
SET_BITS_TO_LE_1BYTE(__cmd, 6, 1, __value)
#define SET_88E_H2CCMD_WOWLAN_DISCONNECT_WAKE_UP(__cmd, __value) \
SET_BITS_TO_LE_1BYTE(__cmd, 7, 1, __value)
#define SET_88E_H2CCMD_WOWLAN_GPIONUM(__cmd, __value) \
SET_BITS_TO_LE_1BYTE((__cmd)+1, 0, 8, __value)
#define SET_88E_H2CCMD_WOWLAN_GPIO_DURATION(__cmd, __value) \
SET_BITS_TO_LE_1BYTE((__cmd)+2, 0, 8, __value)
#define SET_H2CCMD_PWRMODE_PARM_MODE(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
#define SET_H2CCMD_PWRMODE_PARM_RLBM(__cmd, __value) \
SET_BITS_TO_LE_1BYTE((__cmd)+1, 0, 4, __value)
#define SET_H2CCMD_PWRMODE_PARM_SMART_PS(__cmd, __value) \
SET_BITS_TO_LE_1BYTE((__cmd)+1, 4, 4, __value)
#define SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(__cmd, __value) \
SET_BITS_TO_LE_1BYTE((__cmd)+2, 0, 8, __value)
#define SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(__cmd, __value) \
SET_BITS_TO_LE_1BYTE((__cmd)+3, 0, 8, __value)
#define SET_H2CCMD_PWRMODE_PARM_PWR_STATE(__cmd, __value) \
SET_BITS_TO_LE_1BYTE((__cmd)+4, 0, 8, __value)
#define GET_88E_H2CCMD_PWRMODE_PARM_MODE(__cmd) \
LE_BITS_TO_1BYTE(__cmd, 0, 8)
#define SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
#define SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
#define SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val)
#define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val)
/* AP_OFFLOAD */
#define SET_H2CCMD_AP_OFFLOAD_ON(__cmd, __value) \
SET_BITS_TO_LE_1BYTE(__cmd, 0, 8, __value)
#define SET_H2CCMD_AP_OFFLOAD_HIDDEN(__cmd, __value) \
SET_BITS_TO_LE_1BYTE((__cmd)+1, 0, 8, __value)
#define SET_H2CCMD_AP_OFFLOAD_DENYANY(__cmd, __value) \
SET_BITS_TO_LE_1BYTE((__cmd)+2, 0, 8, __value)
#define SET_H2CCMD_AP_OFFLOAD_WAKEUP_EVT_RPT(__cmd, __value) \
SET_BITS_TO_LE_1BYTE((__cmd)+3, 0, 8, __value)
/* Keep Alive Control*/
#define SET_88E_H2CCMD_KEEP_ALIVE_ENABLE(__cmd, __value) \
SET_BITS_TO_LE_1BYTE(__cmd, 0, 1, __value)
#define SET_88E_H2CCMD_KEEP_ALIVE_ACCPEPT_USER_DEFINED(__cmd, __value) \
SET_BITS_TO_LE_1BYTE(__cmd, 1, 1, __value)
#define SET_88E_H2CCMD_KEEP_ALIVE_PERIOD(__cmd, __value) \
SET_BITS_TO_LE_1BYTE((__cmd)+1, 0, 8, __value)
/*REMOTE_WAKE_CTRL */
#define SET_88E_H2CCMD_REMOTE_WAKE_CTRL_EN(__cmd, __value) \
SET_BITS_TO_LE_1BYTE(__cmd, 0, 1, __value)
#if (USE_OLD_WOWLAN_DEBUG_FW == 0)
#define SET_88E_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(__cmd, __value) \
SET_BITS_TO_LE_1BYTE(__cmd, 1, 1, __value)
#define SET_88E_H2CCMD_REMOTE_WAKE_CTRL_NDP_OFFLOAD_EN(__cmd, __value) \
SET_BITS_TO_LE_1BYTE(__cmd, 2, 1, __value)
#define SET_88E_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(__cmd, __value) \
SET_BITS_TO_LE_1BYTE(__cmd, 3, 1, __value)
#else
#define SET_88E_H2_REM_WAKE_ENC_ALG(__cmd, __value) \
SET_BITS_TO_LE_1BYTE((__cmd)+1, 0, 8, __value)
#define SET_88E_H2CCMD_REMOTE_WAKE_CTRL_GROUP_ENC_ALG(__cmd, __value) \
SET_BITS_TO_LE_1BYTE((__cmd)+2, 0, 8, __value)
#endif
/* GTK_OFFLOAD */
#define SET_88E_H2CCMD_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(__cmd, __value) \
SET_BITS_TO_LE_1BYTE(__cmd, 0, 8, __value)
#define SET_88E_H2CCMD_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(__cmd, __value) \
SET_BITS_TO_LE_1BYTE((__cmd)+1, 0, 8, __value)
/* AOAC_RSVDPAGE_LOC */
#define SET_88E_H2CCMD_AOAC_RSVD_LOC_REM_WAKE_CTRL_INFO(__cmd, __value) \
SET_BITS_TO_LE_1BYTE((__cmd), 0, 8, __value)
#define SET_88E_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(__cmd, __value) \
SET_BITS_TO_LE_1BYTE((__cmd)+1, 0, 8, __value)
#define SET_88E_H2CCMD_AOAC_RSVDPAGE_LOC_NEIGHBOR_ADV(__cmd, __value) \
SET_BITS_TO_LE_1BYTE((__cmd)+2, 0, 8, __value)
#define SET_88E_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_RSP(__cmd, __value) \
SET_BITS_TO_LE_1BYTE((__cmd)+3, 0, 8, __value)
#define SET_88E_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_INFO(__cmd, __value) \
SET_BITS_TO_LE_1BYTE((__cmd)+4, 0, 8, __value)
int rtl88e_download_fw(struct ieee80211_hw *hw,
bool buse_wake_on_wlan_fw);
void rtl88e_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id,
u32 cmd_len, u8 *cmdbuffer);
void rtl88e_firmware_selfreset(struct ieee80211_hw *hw);
void rtl88e_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode);
void rtl88e_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus);
void rtl88e_set_fw_ap_off_load_cmd(struct ieee80211_hw *hw,
u8 ap_offload_enable);
void rtl88e_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished);
void rtl88e_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state);
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,66 @@
/******************************************************************************
*
* Copyright(c) 2009-2013 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __RTL92CE_HW_H__
#define __RTL92CE_HW_H__
void rtl88ee_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
void rtl88ee_read_eeprom_info(struct ieee80211_hw *hw);
void rtl88ee_interrupt_recognized(struct ieee80211_hw *hw,
u32 *p_inta, u32 *p_intb);
int rtl88ee_hw_init(struct ieee80211_hw *hw);
void rtl88ee_card_disable(struct ieee80211_hw *hw);
void rtl88ee_enable_interrupt(struct ieee80211_hw *hw);
void rtl88ee_disable_interrupt(struct ieee80211_hw *hw);
int rtl88ee_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type);
void rtl88ee_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid);
void rtl88ee_set_qos(struct ieee80211_hw *hw, int aci);
void rtl88ee_set_beacon_related_registers(struct ieee80211_hw *hw);
void rtl88ee_set_beacon_interval(struct ieee80211_hw *hw);
void rtl88ee_update_interrupt_mask(struct ieee80211_hw *hw,
u32 add_msr, u32 rm_msr);
void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
void rtl88ee_update_hal_rate_tbl(struct ieee80211_hw *hw,
struct ieee80211_sta *sta, u8 rssi_level);
void rtl88ee_update_channel_access_setting(struct ieee80211_hw *hw);
bool rtl88ee_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid);
void rtl88ee_enable_hw_security_config(struct ieee80211_hw *hw);
void rtl88ee_set_key(struct ieee80211_hw *hw, u32 key_index,
u8 *p_macaddr, bool is_group, u8 enc_algo,
bool is_wepkey, bool clear_all);
void rtl8188ee_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
bool autoload_fail, u8 *hwinfo);
void rtl8188ee_bt_reg_init(struct ieee80211_hw *hw);
void rtl8188ee_bt_hw_init(struct ieee80211_hw *hw);
void rtl88ee_suspend(struct ieee80211_hw *hw);
void rtl88ee_resume(struct ieee80211_hw *hw);
void rtl88ee_fw_clk_off_timer_callback(unsigned long data);
#endif

View file

@ -0,0 +1,154 @@
/******************************************************************************
*
* Copyright(c) 2009-2013 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "../wifi.h"
#include "../pci.h"
#include "reg.h"
#include "led.h"
static void _rtl88ee_init_led(struct ieee80211_hw *hw,
struct rtl_led *pled, enum rtl_led_pin ledpin)
{
pled->hw = hw;
pled->ledpin = ledpin;
pled->ledon = false;
}
void rtl88ee_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
{
u8 ledcfg;
struct rtl_priv *rtlpriv = rtl_priv(hw);
RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
"LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin);
switch (pled->ledpin) {
case LED_PIN_GPIO0:
break;
case LED_PIN_LED0:
ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
rtl_write_byte(rtlpriv,
REG_LEDCFG2, (ledcfg & 0xf0) | BIT(5) | BIT(6));
break;
case LED_PIN_LED1:
ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1);
rtl_write_byte(rtlpriv, REG_LEDCFG1, ledcfg & 0x10);
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
"switch case not process\n");
break;
}
pled->ledon = true;
}
void rtl88ee_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
u8 ledcfg;
RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
"LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin);
switch (pled->ledpin) {
case LED_PIN_GPIO0:
break;
case LED_PIN_LED0:
ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
ledcfg &= 0xf0;
if (pcipriv->ledctl.led_opendrain) {
rtl_write_byte(rtlpriv, REG_LEDCFG2,
(ledcfg | BIT(3) | BIT(5) | BIT(6)));
ledcfg = rtl_read_byte(rtlpriv, REG_MAC_PINMUX_CFG);
rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG,
(ledcfg & 0xFE));
} else
rtl_write_byte(rtlpriv, REG_LEDCFG2,
(ledcfg | BIT(3) | BIT(5) | BIT(6)));
break;
case LED_PIN_LED1:
ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1);
ledcfg &= 0x10;
rtl_write_byte(rtlpriv, REG_LEDCFG1, (ledcfg | BIT(3)));
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
"switch case not process\n");
break;
}
pled->ledon = false;
}
void rtl88ee_init_sw_leds(struct ieee80211_hw *hw)
{
struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
_rtl88ee_init_led(hw, &pcipriv->ledctl.sw_led0, LED_PIN_LED0);
_rtl88ee_init_led(hw, &pcipriv->ledctl.sw_led1, LED_PIN_LED1);
}
static void _rtl88ee_sw_led_control(struct ieee80211_hw *hw,
enum led_ctl_mode ledaction)
{
struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0);
switch (ledaction) {
case LED_CTL_POWER_ON:
case LED_CTL_LINK:
case LED_CTL_NO_LINK:
rtl88ee_sw_led_on(hw, pLed0);
break;
case LED_CTL_POWER_OFF:
rtl88ee_sw_led_off(hw, pLed0);
break;
default:
break;
}
}
void rtl88ee_led_control(struct ieee80211_hw *hw,
enum led_ctl_mode ledaction)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) &&
(ledaction == LED_CTL_TX ||
ledaction == LED_CTL_RX ||
ledaction == LED_CTL_SITE_SURVEY ||
ledaction == LED_CTL_LINK ||
ledaction == LED_CTL_NO_LINK ||
ledaction == LED_CTL_START_TO_LINK ||
ledaction == LED_CTL_POWER_ON)) {
return;
}
RT_TRACE(rtlpriv, COMP_LED, DBG_TRACE, "ledaction %d,\n",
ledaction);
_rtl88ee_sw_led_control(hw, ledaction);
}

View file

@ -0,0 +1,34 @@
/******************************************************************************
*
* Copyright(c) 2009-2013 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 __RTL92CE_LED_H__
#define __RTL92CE_LED_H__
void rtl88ee_init_sw_leds(struct ieee80211_hw *hw);
void rtl88ee_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled);
void rtl88ee_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled);
void rtl88ee_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction);
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,233 @@
/******************************************************************************
*
* Copyright(c) 2009-2013 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 __RTL92C_PHY_H__
#define __RTL92C_PHY_H__
/* MAX_TX_COUNT must always set to 4, otherwise read efuse
* table secquence will be wrong.
*/
#define MAX_TX_COUNT 4
#define MAX_PRECMD_CNT 16
#define MAX_RFDEPENDCMD_CNT 16
#define MAX_POSTCMD_CNT 16
#define MAX_DOZE_WAITING_TIMES_9x 64
#define RT_CANNOT_IO(hw) false
#define HIGHPOWER_RADIOA_ARRAYLEN 22
#define IQK_ADDA_REG_NUM 16
#define IQK_BB_REG_NUM 9
#define MAX_TOLERANCE 5
#define IQK_DELAY_TIME 10
#define INDEX_MAPPING_NUM 15
#define APK_BB_REG_NUM 5
#define APK_AFE_REG_NUM 16
#define APK_CURVE_REG_NUM 4
#define PATH_NUM 2
#define LOOP_LIMIT 5
#define MAX_STALL_TIME 50
#define ANTENNADIVERSITYVALUE 0x80
#define MAX_TXPWR_IDX_NMODE_92S 63
#define RESET_CNT_LIMIT 3
#define IQK_ADDA_REG_NUM 16
#define IQK_MAC_REG_NUM 4
#define RF6052_MAX_PATH 2
#define CT_OFFSET_MAC_ADDR 0X16
#define CT_OFFSET_CCK_TX_PWR_IDX 0x5A
#define CT_OFFSET_HT401S_TX_PWR_IDX 0x60
#define CT_OFFSET_HT402S_TX_PWR_IDX_DIFF 0x66
#define CT_OFFSET_HT20_TX_PWR_IDX_DIFF 0x69
#define CT_OFFSET_OFDM_TX_PWR_IDX_DIFF 0x6C
#define CT_OFFSET_HT40_MAX_PWR_OFFSET 0x6F
#define CT_OFFSET_HT20_MAX_PWR_OFFSET 0x72
#define CT_OFFSET_CHANNEL_PLAH 0x75
#define CT_OFFSET_THERMAL_METER 0x78
#define CT_OFFSET_RF_OPTION 0x79
#define CT_OFFSET_VERSION 0x7E
#define CT_OFFSET_CUSTOMER_ID 0x7F
#define RTL92C_MAX_PATH_NUM 2
enum swchnlcmd_id {
CMDID_END,
CMDID_SET_TXPOWEROWER_LEVEL,
CMDID_BBREGWRITE10,
CMDID_WRITEPORT_ULONG,
CMDID_WRITEPORT_USHORT,
CMDID_WRITEPORT_UCHAR,
CMDID_RF_WRITEREG,
};
struct swchnlcmd {
enum swchnlcmd_id cmdid;
u32 para1;
u32 para2;
u32 msdelay;
};
enum hw90_block_e {
HW90_BLOCK_MAC = 0,
HW90_BLOCK_PHY0 = 1,
HW90_BLOCK_PHY1 = 2,
HW90_BLOCK_RF = 3,
HW90_BLOCK_MAXIMUM = 4,
};
enum baseband_config_type {
BASEBAND_CONFIG_PHY_REG = 0,
BASEBAND_CONFIG_AGC_TAB = 1,
};
enum ra_offset_area {
RA_OFFSET_LEGACY_OFDM1,
RA_OFFSET_LEGACY_OFDM2,
RA_OFFSET_HT_OFDM1,
RA_OFFSET_HT_OFDM2,
RA_OFFSET_HT_OFDM3,
RA_OFFSET_HT_OFDM4,
RA_OFFSET_HT_CCK,
};
enum antenna_path {
ANTENNA_NONE,
ANTENNA_D,
ANTENNA_C,
ANTENNA_CD,
ANTENNA_B,
ANTENNA_BD,
ANTENNA_BC,
ANTENNA_BCD,
ANTENNA_A,
ANTENNA_AD,
ANTENNA_AC,
ANTENNA_ACD,
ANTENNA_AB,
ANTENNA_ABD,
ANTENNA_ABC,
ANTENNA_ABCD
};
struct r_antenna_select_ofdm {
u32 r_tx_antenna:4;
u32 r_ant_l:4;
u32 r_ant_non_ht:4;
u32 r_ant_ht1:4;
u32 r_ant_ht2:4;
u32 r_ant_ht_s1:4;
u32 r_ant_non_ht_s1:4;
u32 ofdm_txsc:2;
u32 reserved:2;
};
struct r_antenna_select_cck {
u8 r_cckrx_enable_2:2;
u8 r_cckrx_enable:2;
u8 r_ccktx_enable:4;
};
struct efuse_contents {
u8 mac_addr[ETH_ALEN];
u8 cck_tx_power_idx[6];
u8 ht40_1s_tx_power_idx[6];
u8 ht40_2s_tx_power_idx_diff[3];
u8 ht20_tx_power_idx_diff[3];
u8 ofdm_tx_power_idx_diff[3];
u8 ht40_max_power_offset[3];
u8 ht20_max_power_offset[3];
u8 channel_plan;
u8 thermal_meter;
u8 rf_option[5];
u8 version;
u8 oem_id;
u8 regulatory;
};
struct tx_power_struct {
u8 cck[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
u8 ht40_1s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
u8 ht40_2s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
u8 ht20_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
u8 legacy_ht_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
u8 legacy_ht_txpowerdiff;
u8 groupht20[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
u8 groupht40[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
u8 pwrgroup_cnt;
u32 mcs_original_offset[4][16];
};
enum _ANT_DIV_TYPE {
NO_ANTDIV = 0xFF,
CG_TRX_HW_ANTDIV = 0x01,
CGCS_RX_HW_ANTDIV = 0x02,
FIXED_HW_ANTDIV = 0x03,
CG_TRX_SMART_ANTDIV = 0x04,
CGCS_RX_SW_ANTDIV = 0x05,
};
u32 rtl88e_phy_query_bb_reg(struct ieee80211_hw *hw,
u32 regaddr, u32 bitmask);
void rtl88e_phy_set_bb_reg(struct ieee80211_hw *hw,
u32 regaddr, u32 bitmask, u32 data);
u32 rtl88e_phy_query_rf_reg(struct ieee80211_hw *hw,
enum radio_path rfpath, u32 regaddr,
u32 bitmask);
void rtl88e_phy_set_rf_reg(struct ieee80211_hw *hw,
enum radio_path rfpath, u32 regaddr,
u32 bitmask, u32 data);
bool rtl88e_phy_mac_config(struct ieee80211_hw *hw);
bool rtl88e_phy_bb_config(struct ieee80211_hw *hw);
bool rtl88e_phy_rf_config(struct ieee80211_hw *hw);
void rtl88e_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw);
void rtl88e_phy_get_txpower_level(struct ieee80211_hw *hw,
long *powerlevel);
void rtl88e_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel);
void rtl88e_phy_scan_operation_backup(struct ieee80211_hw *hw,
u8 operation);
void rtl88e_phy_set_bw_mode_callback(struct ieee80211_hw *hw);
void rtl88e_phy_set_bw_mode(struct ieee80211_hw *hw,
enum nl80211_channel_type ch_type);
void rtl88e_phy_sw_chnl_callback(struct ieee80211_hw *hw);
u8 rtl88e_phy_sw_chnl(struct ieee80211_hw *hw);
void rtl88e_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery);
void rtl88e_phy_lc_calibrate(struct ieee80211_hw *hw);
void rtl88e_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain);
bool rtl88e_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
enum radio_path rfpath);
bool rtl88e_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype);
bool rtl88e_phy_set_rf_power_state(struct ieee80211_hw *hw,
enum rf_pwrstate rfpwr_state);
#endif

View file

@ -0,0 +1,105 @@
/******************************************************************************
*
* Copyright(c) 2009-2013 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 "pwrseqcmd.h"
#include "pwrseq.h"
/* drivers should parse below arrays and do the corresponding actions */
/*3 Power on Array*/
struct wlan_pwr_cfg rtl8188ee_power_on_flow[RTL8188EE_TRANS_CARDEMU_TO_ACT_STEPS
+ RTL8188EE_TRANS_END_STEPS] = {
RTL8188EE_TRANS_CARDEMU_TO_ACT
RTL8188EE_TRANS_END
};
/*3Radio off GPIO Array */
struct wlan_pwr_cfg rtl8188ee_radio_off_flow[RTL8188EE_TRANS_ACT_TO_CARDEMU_STEPS
+ RTL8188EE_TRANS_END_STEPS] = {
RTL8188EE_TRANS_ACT_TO_CARDEMU
RTL8188EE_TRANS_END
};
/*3Card Disable Array*/
struct wlan_pwr_cfg rtl8188ee_card_disable_flow
[RTL8188EE_TRANS_ACT_TO_CARDEMU_STEPS +
RTL8188EE_TRANS_CARDEMU_TO_PDN_STEPS +
RTL8188EE_TRANS_END_STEPS] = {
RTL8188EE_TRANS_ACT_TO_CARDEMU
RTL8188EE_TRANS_CARDEMU_TO_CARDDIS
RTL8188EE_TRANS_END
};
/*3 Card Enable Array*/
struct wlan_pwr_cfg rtl8188ee_card_enable_flow
[RTL8188EE_TRANS_ACT_TO_CARDEMU_STEPS +
RTL8188EE_TRANS_CARDEMU_TO_PDN_STEPS +
RTL8188EE_TRANS_END_STEPS] = {
RTL8188EE_TRANS_CARDDIS_TO_CARDEMU
RTL8188EE_TRANS_CARDEMU_TO_ACT
RTL8188EE_TRANS_END
};
/*3Suspend Array*/
struct wlan_pwr_cfg rtl8188ee_suspend_flow[RTL8188EE_TRANS_ACT_TO_CARDEMU_STEPS
+ RTL8188EE_TRANS_CARDEMU_TO_SUS_STEPS
+ RTL8188EE_TRANS_END_STEPS] = {
RTL8188EE_TRANS_ACT_TO_CARDEMU
RTL8188EE_TRANS_CARDEMU_TO_SUS
RTL8188EE_TRANS_END
};
/*3 Resume Array*/
struct wlan_pwr_cfg rtl8188ee_resume_flow[RTL8188EE_TRANS_ACT_TO_CARDEMU_STEPS
+ RTL8188EE_TRANS_CARDEMU_TO_SUS_STEPS
+ RTL8188EE_TRANS_END_STEPS] = {
RTL8188EE_TRANS_SUS_TO_CARDEMU
RTL8188EE_TRANS_CARDEMU_TO_ACT
RTL8188EE_TRANS_END
};
/*3HWPDN Array*/
struct wlan_pwr_cfg rtl8188ee_hwpdn_flow[RTL8188EE_TRANS_ACT_TO_CARDEMU_STEPS
+ RTL8188EE_TRANS_CARDEMU_TO_PDN_STEPS
+ RTL8188EE_TRANS_END_STEPS] = {
RTL8188EE_TRANS_ACT_TO_CARDEMU
RTL8188EE_TRANS_CARDEMU_TO_PDN
RTL8188EE_TRANS_END
};
/*3 Enter LPS */
struct wlan_pwr_cfg rtl8188ee_enter_lps_flow[RTL8188EE_TRANS_ACT_TO_LPS_STEPS
+ RTL8188EE_TRANS_END_STEPS] = {
/*FW behavior*/
RTL8188EE_TRANS_ACT_TO_LPS
RTL8188EE_TRANS_END
};
/*3 Leave LPS */
struct wlan_pwr_cfg rtl8188ee_leave_lps_flow[RTL8188EE_TRANS_LPS_TO_ACT_STEPS
+ RTL8188EE_TRANS_END_STEPS] = {
/*FW behavior*/
RTL8188EE_TRANS_LPS_TO_ACT
RTL8188EE_TRANS_END
};

View file

@ -0,0 +1,311 @@
/******************************************************************************
*
* Copyright(c) 2009-2013 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 __RTL8723E_PWRSEQ_H__
#define __RTL8723E_PWRSEQ_H__
#include "pwrseqcmd.h"
/* Check document WM-20110607-Paul-RTL8188EE_Power_Architecture-R02.vsd
* There are 6 HW Power States:
* 0: POFF--Power Off
* 1: PDN--Power Down
* 2: CARDEMU--Card Emulation
* 3: ACT--Active Mode
* 4: LPS--Low Power State
* 5: SUS--Suspend
*
* The transision from different states are defined below
* TRANS_CARDEMU_TO_ACT
* TRANS_ACT_TO_CARDEMU
* TRANS_CARDEMU_TO_SUS
* TRANS_SUS_TO_CARDEMU
* TRANS_CARDEMU_TO_PDN
* TRANS_ACT_TO_LPS
* TRANS_LPS_TO_ACT
*
* TRANS_END
* PWR SEQ Version: rtl8188ee_PwrSeq_V09.h
*/
#define RTL8188EE_TRANS_CARDEMU_TO_ACT_STEPS 10
#define RTL8188EE_TRANS_ACT_TO_CARDEMU_STEPS 10
#define RTL8188EE_TRANS_CARDEMU_TO_SUS_STEPS 10
#define RTL8188EE_TRANS_SUS_TO_CARDEMU_STEPS 10
#define RTL8188EE_TRANS_CARDEMU_TO_PDN_STEPS 10
#define RTL8188EE_TRANS_PDN_TO_CARDEMU_STEPS 10
#define RTL8188EE_TRANS_ACT_TO_LPS_STEPS 15
#define RTL8188EE_TRANS_LPS_TO_ACT_STEPS 15
#define RTL8188EE_TRANS_END_STEPS 1
/* The following macros have the following format:
* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value
* comments },
*/
#define RTL8188EE_TRANS_CARDEMU_TO_ACT \
{0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(1), BIT(1) \
/* wait till 0x04[17] = 1 power ready*/}, \
{0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0)|BIT(1), 0 \
/* 0x02[1:0] = 0 reset BB*/}, \
{0x0026, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), BIT(7) \
/*0x24[23] = 2b'01 schmit trigger */}, \
{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0 \
/* 0x04[15] = 0 disable HWPDN (control by DRV)*/}, \
{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4)|BIT(3), 0 \
/*0x04[12:11] = 2b'00 disable WL suspend*/}, \
{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0) \
/*0x04[8] = 1 polling until return 0*/}, \
{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(0), 0 \
/*wait till 0x04[8] = 0*/}, \
{0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0 \
/*LDO normal mode*/}, \
{0x0074, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), BIT(4) \
/*SDIO Driving*/},
#define RTL8188EE_TRANS_ACT_TO_CARDEMU \
{0x001F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0 \
/*0x1F[7:0] = 0 turn off RF*/}, \
{0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), BIT(4) \
/*LDO Sleep mode*/}, \
{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1) \
/*0x04[9] = 1 turn off MAC by HW state machine*/}, \
{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(1), 0 \
/*wait till 0x04[9] = 0 polling until return 0 to disable*/},
#define RTL8188EE_TRANS_CARDEMU_TO_SUS \
{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \
PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3) \
/*0x04[12:11] = 2b'01enable WL suspend*/}, \
{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)|BIT(4) \
/*0x04[12:11] = 2b'11enable WL suspend for PCIe*/}, \
{0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \
PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, BIT(7) \
/* 0x04[31:30] = 2b'10 enable enable bandgap mbias in suspend */},\
{0x0041, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \
PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0 \
/*Clear SIC_EN register 0x40[12] = 1'b0 */}, \
{0xfe10, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \
PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), BIT(4) \
/*Set USB suspend enable local register 0xfe10[4]=1 */}, \
{0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), BIT(0) \
/*Set SDIO suspend local register*/}, \
{0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), 0 \
/*wait power state to suspend*/},
#define RTL8188EE_TRANS_SUS_TO_CARDEMU \
{0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), 0 \
/*Set SDIO suspend local register*/}, \
{0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), BIT(1) \
/*wait power state to suspend*/}, \
{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3) | BIT(4), 0 \
/*0x04[12:11] = 2b'01enable WL suspend*/},
#define RTL8188EE_TRANS_CARDEMU_TO_CARDDIS \
{0x0026, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), BIT(7) \
/*0x24[23] = 2b'01 schmit trigger */}, \
{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \
PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3) \
/*0x04[12:11] = 2b'01 enable WL suspend*/}, \
{0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \
PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0 \
/* 0x04[31:30] = 2b'10 enable enable bandgap mbias in suspend */},\
{0x0041, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \
PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0 \
/*Clear SIC_EN register 0x40[12] = 1'b0 */}, \
{0xfe10, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), BIT(4) \
/*Set USB suspend enable local register 0xfe10[4]=1 */}, \
{0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), BIT(0) \
/*Set SDIO suspend local register*/}, \
{0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), 0 \
/*wait power state to suspend*/},
#define RTL8188EE_TRANS_CARDDIS_TO_CARDEMU \
{0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), 0 \
/*Set SDIO suspend local register*/}, \
{0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), BIT(1) \
/*wait power state to suspend*/}, \
{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0 \
/*0x04[12:11] = 2b'01enable WL suspend*/},
#define RTL8188EE_TRANS_CARDEMU_TO_PDN \
{0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0/* 0x04[16] = 0*/}, \
{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), BIT(7) \
/* 0x04[15] = 1*/},
#define RTL8188EE_TRANS_PDN_TO_CARDEMU \
{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0/* 0x04[15] = 0*/},
#define RTL8188EE_TRANS_ACT_TO_LPS \
{0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x7F \
/*Tx Pause*/}, \
{0x05F8, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0 \
/*Should be zero if no packet is transmitting*/}, \
{0x05F9, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0 \
/*Should be zero if no packet is transmitting*/}, \
{0x05FA, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0 \
/*Should be zero if no packet is transmitting*/}, \
{0x05FB, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0 \
/*Should be zero if no packet is transmitting*/}, \
{0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0 \
/*CCK and OFDM are disabled,and clock are gated*/}, \
{0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US \
/*Delay 1us*/}, \
{0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x3F \
/*Reset MAC TRX*/}, \
{0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), 0 \
/*check if removed later*/}, \
{0x0553, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(5), BIT(5) \
/*Respond TxOK to scheduler*/},
#define RTL8188EE_TRANS_LPS_TO_ACT \
{0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
PWR_BASEADDR_SDIO, PWR_CMD_WRITE, 0xFF, 0x84 \
/*SDIO RPWM*/}, \
{0xFE58, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x84 \
/*USB RPWM*/}, \
{0x0361, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x84 \
/*PCIe RPWM*/}, \
{0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_MS \
/*Delay*/}, \
{0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0 \
/*. 0x08[4] = 0 switch TSF to 40M*/}, \
{0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(7), 0 \
/*Polling 0x109[7]=0 TSF in 40M*/}, \
{0x0029, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(6)|BIT(7), 0 \
/*. 0x29[7:6] = 2b'00 enable BB clock*/}, \
{0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1) \
/*. 0x101[1] = 1*/}, \
{0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF \
/*. 0x100[7:0] = 0xFF enable WMAC TRX*/}, \
{0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1)|BIT(0), BIT(1)|BIT(0) \
/*. 0x02[1:0] = 2b'11 enable BB macro*/}, \
{0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0 \
/*. 0x522 = 0*/},
#define RTL8188EE_TRANS_END \
{0xFFFF, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\
0, PWR_CMD_END, 0, 0}
extern struct wlan_pwr_cfg rtl8188ee_power_on_flow
[RTL8188EE_TRANS_CARDEMU_TO_ACT_STEPS +
RTL8188EE_TRANS_END_STEPS];
extern struct wlan_pwr_cfg rtl8188ee_radio_off_flow
[RTL8188EE_TRANS_ACT_TO_CARDEMU_STEPS +
RTL8188EE_TRANS_END_STEPS];
extern struct wlan_pwr_cfg rtl8188ee_card_disable_flow
[RTL8188EE_TRANS_ACT_TO_CARDEMU_STEPS +
RTL8188EE_TRANS_CARDEMU_TO_PDN_STEPS +
RTL8188EE_TRANS_END_STEPS];
extern struct wlan_pwr_cfg rtl8188ee_card_enable_flow
[RTL8188EE_TRANS_ACT_TO_CARDEMU_STEPS +
RTL8188EE_TRANS_CARDEMU_TO_PDN_STEPS +
RTL8188EE_TRANS_END_STEPS];
extern struct wlan_pwr_cfg rtl8188ee_suspend_flow
[RTL8188EE_TRANS_ACT_TO_CARDEMU_STEPS +
RTL8188EE_TRANS_CARDEMU_TO_SUS_STEPS +
RTL8188EE_TRANS_END_STEPS];
extern struct wlan_pwr_cfg rtl8188ee_resume_flow
[RTL8188EE_TRANS_ACT_TO_CARDEMU_STEPS +
RTL8188EE_TRANS_CARDEMU_TO_SUS_STEPS +
RTL8188EE_TRANS_END_STEPS];
extern struct wlan_pwr_cfg rtl8188ee_hwpdn_flow
[RTL8188EE_TRANS_ACT_TO_CARDEMU_STEPS +
RTL8188EE_TRANS_CARDEMU_TO_PDN_STEPS +
RTL8188EE_TRANS_END_STEPS];
extern struct wlan_pwr_cfg rtl8188ee_enter_lps_flow
[RTL8188EE_TRANS_ACT_TO_LPS_STEPS +
RTL8188EE_TRANS_END_STEPS];
extern struct wlan_pwr_cfg rtl8188ee_leave_lps_flow
[RTL8188EE_TRANS_LPS_TO_ACT_STEPS +
RTL8188EE_TRANS_END_STEPS];
/* RTL8723 Power Configuration CMDs for PCIe interface */
#define RTL8188EE_NIC_PWR_ON_FLOW rtl8188ee_power_on_flow
#define RTL8188EE_NIC_RF_OFF_FLOW rtl8188ee_radio_off_flow
#define RTL8188EE_NIC_DISABLE_FLOW rtl8188ee_card_disable_flow
#define RTL8188EE_NIC_ENABLE_FLOW rtl8188ee_card_enable_flow
#define RTL8188EE_NIC_SUSPEND_FLOW rtl8188ee_suspend_flow
#define RTL8188EE_NIC_RESUME_FLOW rtl8188ee_resume_flow
#define RTL8188EE_NIC_PDN_FLOW rtl8188ee_hwpdn_flow
#define RTL8188EE_NIC_LPS_ENTER_FLOW rtl8188ee_enter_lps_flow
#define RTL8188EE_NIC_LPS_LEAVE_FLOW rtl8188ee_leave_lps_flow
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,509 @@
/******************************************************************************
*
* Copyright(c) 2009-2013 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 "../wifi.h"
#include "reg.h"
#include "def.h"
#include "phy.h"
#include "rf.h"
#include "dm.h"
static bool _rtl88e_phy_rf6052_config_parafile(struct ieee80211_hw *hw);
void rtl88e_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
switch (bandwidth) {
case HT_CHANNEL_WIDTH_20:
rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] &
0xfffff3ff) | BIT(10) | BIT(11));
rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK,
rtlphy->rfreg_chnlval[0]);
break;
case HT_CHANNEL_WIDTH_20_40:
rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] &
0xfffff3ff) | BIT(10));
rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK,
rtlphy->rfreg_chnlval[0]);
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"unknown bandwidth: %#X\n", bandwidth);
break;
}
}
void rtl88e_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
u8 *ppowerlevel)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
u32 tx_agc[2] = {0, 0}, tmpval;
bool turbo_scanoff = false;
u8 idx1, idx2;
u8 *ptr;
u8 direction;
u32 pwrtrac_value;
if (rtlefuse->eeprom_regulatory != 0)
turbo_scanoff = true;
if (mac->act_scanning == true) {
tx_agc[RF90_PATH_A] = 0x3f3f3f3f;
tx_agc[RF90_PATH_B] = 0x3f3f3f3f;
if (turbo_scanoff) {
for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
tx_agc[idx1] = ppowerlevel[idx1] |
(ppowerlevel[idx1] << 8) |
(ppowerlevel[idx1] << 16) |
(ppowerlevel[idx1] << 24);
}
}
} else {
for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
tx_agc[idx1] = ppowerlevel[idx1] |
(ppowerlevel[idx1] << 8) |
(ppowerlevel[idx1] << 16) |
(ppowerlevel[idx1] << 24);
}
if (rtlefuse->eeprom_regulatory == 0) {
tmpval =
(rtlphy->mcs_txpwrlevel_origoffset[0][6]) +
(rtlphy->mcs_txpwrlevel_origoffset[0][7] <<
8);
tx_agc[RF90_PATH_A] += tmpval;
tmpval = (rtlphy->mcs_txpwrlevel_origoffset[0][14]) +
(rtlphy->mcs_txpwrlevel_origoffset[0][15] <<
24);
tx_agc[RF90_PATH_B] += tmpval;
}
}
for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
ptr = (u8 *)(&tx_agc[idx1]);
for (idx2 = 0; idx2 < 4; idx2++) {
if (*ptr > RF6052_MAX_TX_PWR)
*ptr = RF6052_MAX_TX_PWR;
ptr++;
}
}
rtl88e_dm_txpower_track_adjust(hw, 1, &direction, &pwrtrac_value);
if (direction == 1) {
tx_agc[0] += pwrtrac_value;
tx_agc[1] += pwrtrac_value;
} else if (direction == 2) {
tx_agc[0] -= pwrtrac_value;
tx_agc[1] -= pwrtrac_value;
}
tmpval = tx_agc[RF90_PATH_A] & 0xff;
rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval,
RTXAGC_A_CCK1_MCS32);
tmpval = tx_agc[RF90_PATH_A] >> 8;
/*tmpval = tmpval & 0xff00ffff;*/
rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval,
RTXAGC_B_CCK11_A_CCK2_11);
tmpval = tx_agc[RF90_PATH_B] >> 24;
rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval,
RTXAGC_B_CCK11_A_CCK2_11);
tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff;
rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval,
RTXAGC_B_CCK1_55_MCS32);
}
static void rtl88e_phy_get_power_base(struct ieee80211_hw *hw,
u8 *ppowerlevel_ofdm,
u8 *ppowerlevel_bw20,
u8 *ppowerlevel_bw40, u8 channel,
u32 *ofdmbase, u32 *mcsbase)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
u32 powerbase0, powerbase1;
u8 i, powerlevel[2];
for (i = 0; i < 2; i++) {
powerbase0 = ppowerlevel_ofdm[i];
powerbase0 = (powerbase0 << 24) | (powerbase0 << 16) |
(powerbase0 << 8) | powerbase0;
*(ofdmbase + i) = powerbase0;
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
" [OFDM power base index rf(%c) = 0x%x]\n",
((i == 0) ? 'A' : 'B'), *(ofdmbase + i));
}
for (i = 0; i < 2; i++) {
if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20)
powerlevel[i] = ppowerlevel_bw20[i];
else
powerlevel[i] = ppowerlevel_bw40[i];
powerbase1 = powerlevel[i];
powerbase1 = (powerbase1 << 24) |
(powerbase1 << 16) | (powerbase1 << 8) | powerbase1;
*(mcsbase + i) = powerbase1;
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
" [MCS power base index rf(%c) = 0x%x]\n",
((i == 0) ? 'A' : 'B'), *(mcsbase + i));
}
}
static void _rtl88e_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
u8 channel, u8 index,
u32 *powerbase0,
u32 *powerbase1,
u32 *p_outwriteval)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
u8 i, chnlgroup = 0, pwr_diff_limit[4], pwr_diff = 0, customer_pwr_diff;
u32 writeval, customer_limit, rf;
for (rf = 0; rf < 2; rf++) {
switch (rtlefuse->eeprom_regulatory) {
case 0:
chnlgroup = 0;
writeval =
rtlphy->mcs_txpwrlevel_origoffset
[chnlgroup][index + (rf ? 8 : 0)]
+ ((index < 2) ? powerbase0[rf] : powerbase1[rf]);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"RTK better performance, writeval(%c) = 0x%x\n",
((rf == 0) ? 'A' : 'B'), writeval);
break;
case 1:
if (rtlphy->pwrgroup_cnt == 1) {
chnlgroup = 0;
} else {
if (channel < 3)
chnlgroup = 0;
else if (channel < 6)
chnlgroup = 1;
else if (channel < 9)
chnlgroup = 2;
else if (channel < 12)
chnlgroup = 3;
else if (channel < 14)
chnlgroup = 4;
else if (channel == 14)
chnlgroup = 5;
}
writeval =
rtlphy->mcs_txpwrlevel_origoffset[chnlgroup]
[index + (rf ? 8 : 0)] + ((index < 2) ?
powerbase0[rf] :
powerbase1[rf]);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"Realtek regulatory, 20MHz, writeval(%c) = 0x%x\n",
((rf == 0) ? 'A' : 'B'), writeval);
break;
case 2:
writeval =
((index < 2) ? powerbase0[rf] : powerbase1[rf]);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"Better regulatory, writeval(%c) = 0x%x\n",
((rf == 0) ? 'A' : 'B'), writeval);
break;
case 3:
chnlgroup = 0;
if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"customer's limit, 40MHz rf(%c) = 0x%x\n",
((rf == 0) ? 'A' : 'B'),
rtlefuse->pwrgroup_ht40[rf][channel -
1]);
} else {
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"customer's limit, 20MHz rf(%c) = 0x%x\n",
((rf == 0) ? 'A' : 'B'),
rtlefuse->pwrgroup_ht20[rf][channel -
1]);
}
if (index < 2)
pwr_diff =
rtlefuse->txpwr_legacyhtdiff[rf][channel-1];
else if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20)
pwr_diff =
rtlefuse->txpwr_ht20diff[rf][channel-1];
if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40)
customer_pwr_diff =
rtlefuse->pwrgroup_ht40[rf][channel-1];
else
customer_pwr_diff =
rtlefuse->pwrgroup_ht20[rf][channel-1];
if (pwr_diff > customer_pwr_diff)
pwr_diff = 0;
else
pwr_diff = customer_pwr_diff - pwr_diff;
for (i = 0; i < 4; i++) {
pwr_diff_limit[i] =
(u8)((rtlphy->mcs_txpwrlevel_origoffset
[chnlgroup][index +
(rf ? 8 : 0)] & (0x7f <<
(i * 8))) >> (i * 8));
if (pwr_diff_limit[i] > pwr_diff)
pwr_diff_limit[i] = pwr_diff;
}
customer_limit = (pwr_diff_limit[3] << 24) |
(pwr_diff_limit[2] << 16) |
(pwr_diff_limit[1] << 8) | (pwr_diff_limit[0]);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"Customer's limit rf(%c) = 0x%x\n",
((rf == 0) ? 'A' : 'B'), customer_limit);
writeval = customer_limit +
((index < 2) ? powerbase0[rf] : powerbase1[rf]);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"Customer, writeval rf(%c)= 0x%x\n",
((rf == 0) ? 'A' : 'B'), writeval);
break;
default:
chnlgroup = 0;
writeval =
rtlphy->mcs_txpwrlevel_origoffset[chnlgroup]
[index + (rf ? 8 : 0)]
+ ((index < 2) ? powerbase0[rf] : powerbase1[rf]);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"RTK better performance, writeval rf(%c) = 0x%x\n",
((rf == 0) ? 'A' : 'B'), writeval);
break;
}
if (rtlpriv->dm.dynamic_txhighpower_lvl == TXHIGHPWRLEVEL_BT1)
writeval = writeval - 0x06060606;
else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
TXHIGHPWRLEVEL_BT2)
writeval = writeval - 0x0c0c0c0c;
*(p_outwriteval + rf) = writeval;
}
}
static void _rtl88e_write_ofdm_power_reg(struct ieee80211_hw *hw,
u8 index, u32 *value)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u16 regoffset_a[6] = {
RTXAGC_A_RATE18_06, RTXAGC_A_RATE54_24,
RTXAGC_A_MCS03_MCS00, RTXAGC_A_MCS07_MCS04,
RTXAGC_A_MCS11_MCS08, RTXAGC_A_MCS15_MCS12
};
u16 regoffset_b[6] = {
RTXAGC_B_RATE18_06, RTXAGC_B_RATE54_24,
RTXAGC_B_MCS03_MCS00, RTXAGC_B_MCS07_MCS04,
RTXAGC_B_MCS11_MCS08, RTXAGC_B_MCS15_MCS12
};
u8 i, rf, pwr_val[4];
u32 writeval;
u16 regoffset;
for (rf = 0; rf < 2; rf++) {
writeval = value[rf];
for (i = 0; i < 4; i++) {
pwr_val[i] = (u8)((writeval & (0x7f <<
(i * 8))) >> (i * 8));
if (pwr_val[i] > RF6052_MAX_TX_PWR)
pwr_val[i] = RF6052_MAX_TX_PWR;
}
writeval = (pwr_val[3] << 24) | (pwr_val[2] << 16) |
(pwr_val[1] << 8) | pwr_val[0];
if (rf == 0)
regoffset = regoffset_a[index];
else
regoffset = regoffset_b[index];
rtl_set_bbreg(hw, regoffset, MASKDWORD, writeval);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"Set 0x%x = %08x\n", regoffset, writeval);
}
}
void rtl88e_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
u8 *ppowerlevel_ofdm,
u8 *ppowerlevel_bw20,
u8 *ppowerlevel_bw40, u8 channel)
{
u32 writeval[2], powerbase0[2], powerbase1[2];
u8 index;
u8 direction;
u32 pwrtrac_value;
rtl88e_phy_get_power_base(hw, ppowerlevel_ofdm,
ppowerlevel_bw20, ppowerlevel_bw40,
channel, &powerbase0[0], &powerbase1[0]);
rtl88e_dm_txpower_track_adjust(hw, 1, &direction, &pwrtrac_value);
for (index = 0; index < 6; index++) {
_rtl88e_get_txpower_writeval_by_regulatory(hw,
channel, index,
&powerbase0[0],
&powerbase1[0],
&writeval[0]);
if (direction == 1) {
writeval[0] += pwrtrac_value;
writeval[1] += pwrtrac_value;
} else if (direction == 2) {
writeval[0] -= pwrtrac_value;
writeval[1] -= pwrtrac_value;
}
_rtl88e_write_ofdm_power_reg(hw, index, &writeval[0]);
}
}
bool rtl88e_phy_rf6052_config(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
if (rtlphy->rf_type == RF_1T1R)
rtlphy->num_total_rfpath = 1;
else
rtlphy->num_total_rfpath = 2;
return _rtl88e_phy_rf6052_config_parafile(hw);
}
static bool _rtl88e_phy_rf6052_config_parafile(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &rtlpriv->phy;
u32 u4_regvalue = 0;
u8 rfpath;
bool rtstatus = true;
struct bb_reg_def *pphyreg;
for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) {
pphyreg = &rtlphy->phyreg_def[rfpath];
switch (rfpath) {
case RF90_PATH_A:
case RF90_PATH_C:
u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs,
BRFSI_RFENV);
break;
case RF90_PATH_B:
case RF90_PATH_D:
u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs,
BRFSI_RFENV << 16);
break;
}
rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1);
udelay(1);
rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1);
udelay(1);
rtl_set_bbreg(hw, pphyreg->rfhssi_para2,
B3WIREADDREAALENGTH, 0x0);
udelay(1);
rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0);
udelay(1);
switch (rfpath) {
case RF90_PATH_A:
rtstatus = rtl88e_phy_config_rf_with_headerfile(hw,
(enum radio_path)rfpath);
break;
case RF90_PATH_B:
rtstatus = rtl88e_phy_config_rf_with_headerfile(hw,
(enum radio_path)rfpath);
break;
case RF90_PATH_C:
break;
case RF90_PATH_D:
break;
}
switch (rfpath) {
case RF90_PATH_A:
case RF90_PATH_C:
rtl_set_bbreg(hw, pphyreg->rfintfs,
BRFSI_RFENV, u4_regvalue);
break;
case RF90_PATH_B:
case RF90_PATH_D:
rtl_set_bbreg(hw, pphyreg->rfintfs,
BRFSI_RFENV << 16, u4_regvalue);
break;
}
if (rtstatus != true) {
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
"Radio[%d] Fail!!", rfpath);
return false;
}
}
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "\n");
return rtstatus;
}

View file

@ -0,0 +1,43 @@
/******************************************************************************
*
* Copyright(c) 2009-2013 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 __RTL92C_RF_H__
#define __RTL92C_RF_H__
#define RF6052_MAX_TX_PWR 0x3F
#define RF6052_MAX_REG 0x3F
void rtl88e_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw,
u8 bandwidth);
void rtl88e_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
u8 *ppowerlevel);
void rtl88e_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
u8 *ppowerlevel_ofdm,
u8 *ppowerlevel_bw20,
u8 *ppowerlevel_bw40,
u8 channel);
bool rtl88e_phy_rf6052_config(struct ieee80211_hw *hw);
#endif

View file

@ -0,0 +1,419 @@
/******************************************************************************
*
* Copyright(c) 2009-2013 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 "../wifi.h"
#include "../core.h"
#include "../pci.h"
#include "reg.h"
#include "def.h"
#include "phy.h"
#include "dm.h"
#include "hw.h"
#include "sw.h"
#include "trx.h"
#include "led.h"
#include "table.h"
#include <linux/vmalloc.h>
#include <linux/module.h>
static void rtl88e_init_aspm_vars(struct ieee80211_hw *hw)
{
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
/*close ASPM for AMD defaultly */
rtlpci->const_amdpci_aspm = 0;
/* ASPM PS mode.
* 0 - Disable ASPM,
* 1 - Enable ASPM without Clock Req,
* 2 - Enable ASPM with Clock Req,
* 3 - Alwyas Enable ASPM with Clock Req,
* 4 - Always Enable ASPM without Clock Req.
* set defult to RTL8192CE:3 RTL8192E:2
*/
rtlpci->const_pci_aspm = 3;
/*Setting for PCI-E device */
rtlpci->const_devicepci_aspm_setting = 0x03;
/*Setting for PCI-E bridge */
rtlpci->const_hostpci_aspm_setting = 0x02;
/* In Hw/Sw Radio Off situation.
* 0 - Default,
* 1 - From ASPM setting without low Mac Pwr,
* 2 - From ASPM setting with low Mac Pwr,
* 3 - Bus D3
* set default to RTL8192CE:0 RTL8192SE:2
*/
rtlpci->const_hwsw_rfoff_d3 = 0;
/* This setting works for those device with
* backdoor ASPM setting such as EPHY setting.
* 0 - Not support ASPM,
* 1 - Support ASPM,
* 2 - According to chipset.
*/
rtlpci->const_support_pciaspm = 1;
}
int rtl88e_init_sw_vars(struct ieee80211_hw *hw)
{
int err = 0;
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
u8 tid;
rtl8188ee_bt_reg_init(hw);
rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support;
rtlpriv->dm.dm_initialgain_enable = 1;
rtlpriv->dm.dm_flag = 0;
rtlpriv->dm.disable_framebursting = 0;
rtlpriv->dm.thermalvalue = 0;
rtlpci->transmit_config = CFENDFORM | BIT(15);
/* compatible 5G band 88ce just 2.4G band & smsp */
rtlpriv->rtlhal.current_bandtype = BAND_ON_2_4G;
rtlpriv->rtlhal.bandset = BAND_ON_2_4G;
rtlpriv->rtlhal.macphymode = SINGLEMAC_SINGLEPHY;
rtlpci->receive_config = (RCR_APPFCS |
RCR_APP_MIC |
RCR_APP_ICV |
RCR_APP_PHYST_RXFF |
RCR_HTC_LOC_CTRL |
RCR_AMF |
RCR_ACF |
RCR_ADF |
RCR_AICV |
RCR_ACRC32 |
RCR_AB |
RCR_AM |
RCR_APM |
0);
rtlpci->irq_mask[0] =
(u32)(IMR_PSTIMEOUT |
IMR_HSISR_IND_ON_INT |
IMR_C2HCMD |
IMR_HIGHDOK |
IMR_MGNTDOK |
IMR_BKDOK |
IMR_BEDOK |
IMR_VIDOK |
IMR_VODOK |
IMR_RDU |
IMR_ROK |
0);
rtlpci->irq_mask[1] = (u32) (IMR_RXFOVW | 0);
rtlpci->sys_irq_mask = (u32) (HSIMR_PDN_INT_EN | HSIMR_RON_INT_EN);
/* for debug level */
rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
/* for LPS & IPS */
rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps;
if (rtlpriv->cfg->mod_params->disable_watchdog)
pr_info("watchdog disabled\n");
if (!rtlpriv->psc.inactiveps)
pr_info("rtl8188ee: Power Save off (module option)\n");
if (!rtlpriv->psc.fwctrl_lps)
pr_info("rtl8188ee: FW Power Save off (module option)\n");
rtlpriv->psc.reg_fwctrl_lps = 3;
rtlpriv->psc.reg_max_lps_awakeintvl = 5;
/* for ASPM, you can close aspm through
* set const_support_pciaspm = 0
*/
rtl88e_init_aspm_vars(hw);
if (rtlpriv->psc.reg_fwctrl_lps == 1)
rtlpriv->psc.fwctrl_psmode = FW_PS_MIN_MODE;
else if (rtlpriv->psc.reg_fwctrl_lps == 2)
rtlpriv->psc.fwctrl_psmode = FW_PS_MAX_MODE;
else if (rtlpriv->psc.reg_fwctrl_lps == 3)
rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE;
/* for firmware buf */
rtlpriv->rtlhal.pfirmware = vzalloc(0x8000);
if (!rtlpriv->rtlhal.pfirmware) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"Can't alloc buffer for fw.\n");
return 1;
}
rtlpriv->cfg->fw_name = "rtlwifi/rtl8188efw.bin";
rtlpriv->max_fw_size = 0x8000;
pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name);
err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name,
rtlpriv->io.dev, GFP_KERNEL, hw,
rtl_fw_cb);
if (err) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"Failed to request firmware!\n");
return 1;
}
/* for early mode */
rtlpriv->rtlhal.earlymode_enable = false;
rtlpriv->rtlhal.max_earlymode_num = 10;
for (tid = 0; tid < 8; tid++)
skb_queue_head_init(&rtlpriv->mac80211.skb_waitq[tid]);
/*low power */
rtlpriv->psc.low_power_enable = false;
if (rtlpriv->psc.low_power_enable) {
init_timer(&rtlpriv->works.fw_clockoff_timer);
setup_timer(&rtlpriv->works.fw_clockoff_timer,
rtl88ee_fw_clk_off_timer_callback,
(unsigned long)hw);
}
init_timer(&rtlpriv->works.fast_antenna_training_timer);
setup_timer(&rtlpriv->works.fast_antenna_training_timer,
rtl88e_dm_fast_antenna_training_callback,
(unsigned long)hw);
return err;
}
void rtl88e_deinit_sw_vars(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
if (rtlpriv->rtlhal.pfirmware) {
vfree(rtlpriv->rtlhal.pfirmware);
rtlpriv->rtlhal.pfirmware = NULL;
}
if (rtlpriv->psc.low_power_enable)
del_timer_sync(&rtlpriv->works.fw_clockoff_timer);
del_timer_sync(&rtlpriv->works.fast_antenna_training_timer);
}
/* get bt coexist status */
bool rtl88e_get_btc_status(void)
{
return false;
}
static struct rtl_hal_ops rtl8188ee_hal_ops = {
.init_sw_vars = rtl88e_init_sw_vars,
.deinit_sw_vars = rtl88e_deinit_sw_vars,
.read_eeprom_info = rtl88ee_read_eeprom_info,
.interrupt_recognized = rtl88ee_interrupt_recognized,/*need check*/
.hw_init = rtl88ee_hw_init,
.hw_disable = rtl88ee_card_disable,
.hw_suspend = rtl88ee_suspend,
.hw_resume = rtl88ee_resume,
.enable_interrupt = rtl88ee_enable_interrupt,
.disable_interrupt = rtl88ee_disable_interrupt,
.set_network_type = rtl88ee_set_network_type,
.set_chk_bssid = rtl88ee_set_check_bssid,
.set_qos = rtl88ee_set_qos,
.set_bcn_reg = rtl88ee_set_beacon_related_registers,
.set_bcn_intv = rtl88ee_set_beacon_interval,
.update_interrupt_mask = rtl88ee_update_interrupt_mask,
.get_hw_reg = rtl88ee_get_hw_reg,
.set_hw_reg = rtl88ee_set_hw_reg,
.update_rate_tbl = rtl88ee_update_hal_rate_tbl,
.fill_tx_desc = rtl88ee_tx_fill_desc,
.fill_tx_cmddesc = rtl88ee_tx_fill_cmddesc,
.query_rx_desc = rtl88ee_rx_query_desc,
.set_channel_access = rtl88ee_update_channel_access_setting,
.radio_onoff_checking = rtl88ee_gpio_radio_on_off_checking,
.set_bw_mode = rtl88e_phy_set_bw_mode,
.switch_channel = rtl88e_phy_sw_chnl,
.dm_watchdog = rtl88e_dm_watchdog,
.scan_operation_backup = rtl88e_phy_scan_operation_backup,
.set_rf_power_state = rtl88e_phy_set_rf_power_state,
.led_control = rtl88ee_led_control,
.set_desc = rtl88ee_set_desc,
.get_desc = rtl88ee_get_desc,
.is_tx_desc_closed = rtl88ee_is_tx_desc_closed,
.tx_polling = rtl88ee_tx_polling,
.enable_hw_sec = rtl88ee_enable_hw_security_config,
.set_key = rtl88ee_set_key,
.init_sw_leds = rtl88ee_init_sw_leds,
.get_bbreg = rtl88e_phy_query_bb_reg,
.set_bbreg = rtl88e_phy_set_bb_reg,
.get_rfreg = rtl88e_phy_query_rf_reg,
.set_rfreg = rtl88e_phy_set_rf_reg,
.get_btc_status = rtl88e_get_btc_status,
.rx_command_packet = rtl88ee_rx_command_packet,
};
static struct rtl_mod_params rtl88ee_mod_params = {
.sw_crypto = false,
.inactiveps = false,
.swctrl_lps = false,
.fwctrl_lps = false,
.msi_support = true,
.debug = DBG_EMERG,
};
static struct rtl_hal_cfg rtl88ee_hal_cfg = {
.bar_id = 2,
.write_readback = true,
.name = "rtl88e_pci",
.fw_name = "rtlwifi/rtl8188efw.bin",
.ops = &rtl8188ee_hal_ops,
.mod_params = &rtl88ee_mod_params,
.maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL,
.maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN,
.maps[SYS_CLK] = REG_SYS_CLKR,
.maps[MAC_RCR_AM] = AM,
.maps[MAC_RCR_AB] = AB,
.maps[MAC_RCR_ACRC32] = ACRC32,
.maps[MAC_RCR_ACF] = ACF,
.maps[MAC_RCR_AAP] = AAP,
.maps[MAC_HIMR] = REG_HIMR,
.maps[MAC_HIMRE] = REG_HIMRE,
.maps[MAC_HSISR] = REG_HSISR,
.maps[EFUSE_ACCESS] = REG_EFUSE_ACCESS,
.maps[EFUSE_TEST] = REG_EFUSE_TEST,
.maps[EFUSE_CTRL] = REG_EFUSE_CTRL,
.maps[EFUSE_CLK] = 0,
.maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL,
.maps[EFUSE_PWC_EV12V] = PWC_EV12V,
.maps[EFUSE_FEN_ELDR] = FEN_ELDR,
.maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN,
.maps[EFUSE_ANA8M] = ANA8M,
.maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE,
.maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION,
.maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN,
.maps[EFUSE_OOB_PROTECT_BYTES_LEN] = EFUSE_OOB_PROTECT_BYTES,
.maps[RWCAM] = REG_CAMCMD,
.maps[WCAMI] = REG_CAMWRITE,
.maps[RCAMO] = REG_CAMREAD,
.maps[CAMDBG] = REG_CAMDBG,
.maps[SECR] = REG_SECCFG,
.maps[SEC_CAM_NONE] = CAM_NONE,
.maps[SEC_CAM_WEP40] = CAM_WEP40,
.maps[SEC_CAM_TKIP] = CAM_TKIP,
.maps[SEC_CAM_AES] = CAM_AES,
.maps[SEC_CAM_WEP104] = CAM_WEP104,
.maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6,
.maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5,
.maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4,
.maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3,
.maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2,
.maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1,
/* .maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8, */ /*need check*/
.maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7,
.maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6,
.maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5,
.maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4,
.maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3,
.maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2,
.maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1,
/* .maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2,*/
/* .maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1,*/
.maps[RTL_IMR_TXFOVW] = IMR_TXFOVW,
.maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT,
.maps[RTL_IMR_BCNINT] = IMR_BCNDMAINT0,
.maps[RTL_IMR_RXFOVW] = IMR_RXFOVW,
.maps[RTL_IMR_RDU] = IMR_RDU,
.maps[RTL_IMR_ATIMEND] = IMR_ATIMEND,
.maps[RTL_IMR_BDOK] = IMR_BCNDOK0,
.maps[RTL_IMR_MGNTDOK] = IMR_MGNTDOK,
.maps[RTL_IMR_TBDER] = IMR_TBDER,
.maps[RTL_IMR_HIGHDOK] = IMR_HIGHDOK,
.maps[RTL_IMR_TBDOK] = IMR_TBDOK,
.maps[RTL_IMR_BKDOK] = IMR_BKDOK,
.maps[RTL_IMR_BEDOK] = IMR_BEDOK,
.maps[RTL_IMR_VIDOK] = IMR_VIDOK,
.maps[RTL_IMR_VODOK] = IMR_VODOK,
.maps[RTL_IMR_ROK] = IMR_ROK,
.maps[RTL_IMR_HSISR_IND] = IMR_HSISR_IND_ON_INT,
.maps[RTL_IBSS_INT_MASKS] = (IMR_BCNDMAINT0 | IMR_TBDOK | IMR_TBDER),
.maps[RTL_RC_CCK_RATE1M] = DESC92C_RATE1M,
.maps[RTL_RC_CCK_RATE2M] = DESC92C_RATE2M,
.maps[RTL_RC_CCK_RATE5_5M] = DESC92C_RATE5_5M,
.maps[RTL_RC_CCK_RATE11M] = DESC92C_RATE11M,
.maps[RTL_RC_OFDM_RATE6M] = DESC92C_RATE6M,
.maps[RTL_RC_OFDM_RATE9M] = DESC92C_RATE9M,
.maps[RTL_RC_OFDM_RATE12M] = DESC92C_RATE12M,
.maps[RTL_RC_OFDM_RATE18M] = DESC92C_RATE18M,
.maps[RTL_RC_OFDM_RATE24M] = DESC92C_RATE24M,
.maps[RTL_RC_OFDM_RATE36M] = DESC92C_RATE36M,
.maps[RTL_RC_OFDM_RATE48M] = DESC92C_RATE48M,
.maps[RTL_RC_OFDM_RATE54M] = DESC92C_RATE54M,
.maps[RTL_RC_HT_RATEMCS7] = DESC92C_RATEMCS7,
.maps[RTL_RC_HT_RATEMCS15] = DESC92C_RATEMCS15,
};
static struct pci_device_id rtl88ee_pci_ids[] = {
{RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8179, rtl88ee_hal_cfg)},
{},
};
MODULE_DEVICE_TABLE(pci, rtl88ee_pci_ids);
MODULE_AUTHOR("zhiyuan_yang <zhiyuan_yang@realsil.com.cn>");
MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Realtek 8188E 802.11n PCI wireless");
MODULE_FIRMWARE("rtlwifi/rtl8188efw.bin");
module_param_named(swenc, rtl88ee_mod_params.sw_crypto, bool, 0444);
module_param_named(debug, rtl88ee_mod_params.debug, int, 0444);
module_param_named(ips, rtl88ee_mod_params.inactiveps, bool, 0444);
module_param_named(swlps, rtl88ee_mod_params.swctrl_lps, bool, 0444);
module_param_named(fwlps, rtl88ee_mod_params.fwctrl_lps, bool, 0444);
module_param_named(msi, rtl88ee_mod_params.msi_support, bool, 0444);
module_param_named(disable_watchdog, rtl88ee_mod_params.disable_watchdog,
bool, 0444);
MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n");
MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n");
MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 1)\n");
MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
MODULE_PARM_DESC(disable_watchdog, "Set to 1 to disable the watchdog (default 0)\n");
static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
static struct pci_driver rtl88ee_driver = {
.name = KBUILD_MODNAME,
.id_table = rtl88ee_pci_ids,
.probe = rtl_pci_probe,
.remove = rtl_pci_disconnect,
.driver.pm = &rtlwifi_pm_ops,
};
module_pci_driver(rtl88ee_driver);

View file

@ -0,0 +1,34 @@
/******************************************************************************
*
* Copyright(c) 2009-2013 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 __RTL92CE_SW_H__
#define __RTL92CE_SW_H__
int rtl88e_init_sw_vars(struct ieee80211_hw *hw);
void rtl88e_deinit_sw_vars(struct ieee80211_hw *hw);
bool rtl88e_get_btc_status(void);
#endif

View file

@ -0,0 +1,639 @@
/******************************************************************************
*
* Copyright(c) 2009-2013 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.
*
* Created on 2010/ 5/18, 1:41
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "table.h"
u32 RTL8188EEPHY_REG_1TARRAY[] = {
0x800, 0x80040000,
0x804, 0x00000003,
0x808, 0x0000FC00,
0x80C, 0x0000000A,
0x810, 0x10001331,
0x814, 0x020C3D10,
0x818, 0x02200385,
0x81C, 0x00000000,
0x820, 0x01000100,
0x824, 0x00390204,
0x828, 0x00000000,
0x82C, 0x00000000,
0x830, 0x00000000,
0x834, 0x00000000,
0x838, 0x00000000,
0x83C, 0x00000000,
0x840, 0x00010000,
0x844, 0x00000000,
0x848, 0x00000000,
0x84C, 0x00000000,
0x850, 0x00000000,
0x854, 0x00000000,
0x858, 0x569A11A9,
0x85C, 0x01000014,
0x860, 0x66F60110,
0x864, 0x061F0649,
0x868, 0x00000000,
0x86C, 0x27272700,
0x870, 0x07000760,
0x874, 0x25004000,
0x878, 0x00000808,
0x87C, 0x00000000,
0x880, 0xB0000C1C,
0x884, 0x00000001,
0x888, 0x00000000,
0x88C, 0xCCC000C0,
0x890, 0x00000800,
0x894, 0xFFFFFFFE,
0x898, 0x40302010,
0x89C, 0x00706050,
0x900, 0x00000000,
0x904, 0x00000023,
0x908, 0x00000000,
0x90C, 0x81121111,
0x910, 0x00000002,
0x914, 0x00000201,
0xA00, 0x00D047C8,
0xA04, 0x80FF000C,
0xA08, 0x8C838300,
0xA0C, 0x2E7F120F,
0xA10, 0x9500BB78,
0xA14, 0x1114D028,
0xA18, 0x00881117,
0xA1C, 0x89140F00,
0xA20, 0x1A1B0000,
0xA24, 0x090E1317,
0xA28, 0x00000204,
0xA2C, 0x00D30000,
0xA70, 0x101FBF00,
0xA74, 0x00000007,
0xA78, 0x00000900,
0xA7C, 0x225B0606,
0xA80, 0x218075B1,
0xB2C, 0x80000000,
0xC00, 0x48071D40,
0xC04, 0x03A05611,
0xC08, 0x000000E4,
0xC0C, 0x6C6C6C6C,
0xC10, 0x08800000,
0xC14, 0x40000100,
0xC18, 0x08800000,
0xC1C, 0x40000100,
0xC20, 0x00000000,
0xC24, 0x00000000,
0xC28, 0x00000000,
0xC2C, 0x00000000,
0xC30, 0x69E9AC47,
0xC34, 0x469652AF,
0xC38, 0x49795994,
0xC3C, 0x0A97971C,
0xC40, 0x1F7C403F,
0xC44, 0x000100B7,
0xC48, 0xEC020107,
0xC4C, 0x007F037F,
0xC50, 0x69553420,
0xC54, 0x43BC0094,
0xC58, 0x00013169,
0xC5C, 0x00250492,
0xC60, 0x00000000,
0xC64, 0x7112848B,
0xC68, 0x47C00BFF,
0xC6C, 0x00000036,
0xC70, 0x2C7F000D,
0xC74, 0x020610DB,
0xC78, 0x0000001F,
0xC7C, 0x00B91612,
0xC80, 0x390000E4,
0xC84, 0x20F60000,
0xC88, 0x40000100,
0xC8C, 0x20200000,
0xC90, 0x00091521,
0xC94, 0x00000000,
0xC98, 0x00121820,
0xC9C, 0x00007F7F,
0xCA0, 0x00000000,
0xCA4, 0x000300A0,
0xCA8, 0x00000000,
0xCAC, 0x00000000,
0xCB0, 0x00000000,
0xCB4, 0x00000000,
0xCB8, 0x00000000,
0xCBC, 0x28000000,
0xCC0, 0x00000000,
0xCC4, 0x00000000,
0xCC8, 0x00000000,
0xCCC, 0x00000000,
0xCD0, 0x00000000,
0xCD4, 0x00000000,
0xCD8, 0x64B22427,
0xCDC, 0x00766932,
0xCE0, 0x00222222,
0xCE4, 0x00000000,
0xCE8, 0x37644302,
0xCEC, 0x2F97D40C,
0xD00, 0x00000740,
0xD04, 0x00020401,
0xD08, 0x0000907F,
0xD0C, 0x20010201,
0xD10, 0xA0633333,
0xD14, 0x3333BC43,
0xD18, 0x7A8F5B6F,
0xD2C, 0xCC979975,
0xD30, 0x00000000,
0xD34, 0x80608000,
0xD38, 0x00000000,
0xD3C, 0x00127353,
0xD40, 0x00000000,
0xD44, 0x00000000,
0xD48, 0x00000000,
0xD4C, 0x00000000,
0xD50, 0x6437140A,
0xD54, 0x00000000,
0xD58, 0x00000282,
0xD5C, 0x30032064,
0xD60, 0x4653DE68,
0xD64, 0x04518A3C,
0xD68, 0x00002101,
0xD6C, 0x2A201C16,
0xD70, 0x1812362E,
0xD74, 0x322C2220,
0xD78, 0x000E3C24,
0xE00, 0x2D2D2D2D,
0xE04, 0x2D2D2D2D,
0xE08, 0x0390272D,
0xE10, 0x2D2D2D2D,
0xE14, 0x2D2D2D2D,
0xE18, 0x2D2D2D2D,
0xE1C, 0x2D2D2D2D,
0xE28, 0x00000000,
0xE30, 0x1000DC1F,
0xE34, 0x10008C1F,
0xE38, 0x02140102,
0xE3C, 0x681604C2,
0xE40, 0x01007C00,
0xE44, 0x01004800,
0xE48, 0xFB000000,
0xE4C, 0x000028D1,
0xE50, 0x1000DC1F,
0xE54, 0x10008C1F,
0xE58, 0x02140102,
0xE5C, 0x28160D05,
0xE60, 0x00000008,
0xE68, 0x001B25A4,
0xE6C, 0x00C00014,
0xE70, 0x00C00014,
0xE74, 0x01000014,
0xE78, 0x01000014,
0xE7C, 0x01000014,
0xE80, 0x01000014,
0xE84, 0x00C00014,
0xE88, 0x01000014,
0xE8C, 0x00C00014,
0xED0, 0x00C00014,
0xED4, 0x00C00014,
0xED8, 0x00C00014,
0xEDC, 0x00000014,
0xEE0, 0x00000014,
0xEEC, 0x01C00014,
0xF14, 0x00000003,
0xF4C, 0x00000000,
0xF00, 0x00000300,
};
u32 RTL8188EEPHY_REG_ARRAY_PG[] = {
0xE00, 0xFFFFFFFF, 0x06070809,
0xE04, 0xFFFFFFFF, 0x02020405,
0xE08, 0x0000FF00, 0x00000006,
0x86C, 0xFFFFFF00, 0x00020400,
0xE10, 0xFFFFFFFF, 0x08090A0B,
0xE14, 0xFFFFFFFF, 0x01030607,
0xE18, 0xFFFFFFFF, 0x08090A0B,
0xE1C, 0xFFFFFFFF, 0x01030607,
0xE00, 0xFFFFFFFF, 0x00000000,
0xE04, 0xFFFFFFFF, 0x00000000,
0xE08, 0x0000FF00, 0x00000000,
0x86C, 0xFFFFFF00, 0x00000000,
0xE10, 0xFFFFFFFF, 0x00000000,
0xE14, 0xFFFFFFFF, 0x00000000,
0xE18, 0xFFFFFFFF, 0x00000000,
0xE1C, 0xFFFFFFFF, 0x00000000,
0xE00, 0xFFFFFFFF, 0x02020202,
0xE04, 0xFFFFFFFF, 0x00020202,
0xE08, 0x0000FF00, 0x00000000,
0x86C, 0xFFFFFF00, 0x00000000,
0xE10, 0xFFFFFFFF, 0x04040404,
0xE14, 0xFFFFFFFF, 0x00020404,
0xE18, 0xFFFFFFFF, 0x00000000,
0xE1C, 0xFFFFFFFF, 0x00000000,
0xE00, 0xFFFFFFFF, 0x02020202,
0xE04, 0xFFFFFFFF, 0x00020202,
0xE08, 0x0000FF00, 0x00000000,
0x86C, 0xFFFFFF00, 0x00000000,
0xE10, 0xFFFFFFFF, 0x04040404,
0xE14, 0xFFFFFFFF, 0x00020404,
0xE18, 0xFFFFFFFF, 0x00000000,
0xE1C, 0xFFFFFFFF, 0x00000000,
0xE00, 0xFFFFFFFF, 0x00000000,
0xE04, 0xFFFFFFFF, 0x00000000,
0xE08, 0x0000FF00, 0x00000000,
0x86C, 0xFFFFFF00, 0x00000000,
0xE10, 0xFFFFFFFF, 0x00000000,
0xE14, 0xFFFFFFFF, 0x00000000,
0xE18, 0xFFFFFFFF, 0x00000000,
0xE1C, 0xFFFFFFFF, 0x00000000,
0xE00, 0xFFFFFFFF, 0x02020202,
0xE04, 0xFFFFFFFF, 0x00020202,
0xE08, 0x0000FF00, 0x00000000,
0x86C, 0xFFFFFF00, 0x00000000,
0xE10, 0xFFFFFFFF, 0x04040404,
0xE14, 0xFFFFFFFF, 0x00020404,
0xE18, 0xFFFFFFFF, 0x00000000,
0xE1C, 0xFFFFFFFF, 0x00000000,
0xE00, 0xFFFFFFFF, 0x00000000,
0xE04, 0xFFFFFFFF, 0x00000000,
0xE08, 0x0000FF00, 0x00000000,
0x86C, 0xFFFFFF00, 0x00000000,
0xE10, 0xFFFFFFFF, 0x00000000,
0xE14, 0xFFFFFFFF, 0x00000000,
0xE18, 0xFFFFFFFF, 0x00000000,
0xE1C, 0xFFFFFFFF, 0x00000000,
0xE00, 0xFFFFFFFF, 0x00000000,
0xE04, 0xFFFFFFFF, 0x00000000,
0xE08, 0x0000FF00, 0x00000000,
0x86C, 0xFFFFFF00, 0x00000000,
0xE10, 0xFFFFFFFF, 0x00000000,
0xE14, 0xFFFFFFFF, 0x00000000,
0xE18, 0xFFFFFFFF, 0x00000000,
0xE1C, 0xFFFFFFFF, 0x00000000,
0xE00, 0xFFFFFFFF, 0x00000000,
0xE04, 0xFFFFFFFF, 0x00000000,
0xE08, 0x0000FF00, 0x00000000,
0x86C, 0xFFFFFF00, 0x00000000,
0xE10, 0xFFFFFFFF, 0x00000000,
0xE14, 0xFFFFFFFF, 0x00000000,
0xE18, 0xFFFFFFFF, 0x00000000,
0xE1C, 0xFFFFFFFF, 0x00000000,
0xE00, 0xFFFFFFFF, 0x00000000,
0xE04, 0xFFFFFFFF, 0x00000000,
0xE08, 0x0000FF00, 0x00000000,
0x86C, 0xFFFFFF00, 0x00000000,
0xE10, 0xFFFFFFFF, 0x00000000,
0xE14, 0xFFFFFFFF, 0x00000000,
0xE18, 0xFFFFFFFF, 0x00000000,
0xE1C, 0xFFFFFFFF, 0x00000000,
0xE00, 0xFFFFFFFF, 0x00000000,
0xE04, 0xFFFFFFFF, 0x00000000,
0xE08, 0x0000FF00, 0x00000000,
0x86C, 0xFFFFFF00, 0x00000000,
0xE10, 0xFFFFFFFF, 0x00000000,
0xE14, 0xFFFFFFFF, 0x00000000,
0xE18, 0xFFFFFFFF, 0x00000000,
0xE1C, 0xFFFFFFFF, 0x00000000,
};
u32 RTL8188EE_RADIOA_1TARRAY[] = {
0x000, 0x00030000,
0x008, 0x00084000,
0x018, 0x00000407,
0x019, 0x00000012,
0x01E, 0x00080009,
0x01F, 0x00000880,
0x02F, 0x0001A060,
0x03F, 0x00000000,
0x042, 0x000060C0,
0x057, 0x000D0000,
0x058, 0x000BE180,
0x067, 0x00001552,
0x083, 0x00000000,
0x0B0, 0x000FF8FC,
0x0B1, 0x00054400,
0x0B2, 0x000CCC19,
0x0B4, 0x00043003,
0x0B6, 0x0004953E,
0x0B7, 0x0001C718,
0x0B8, 0x000060FF,
0x0B9, 0x00080001,
0x0BA, 0x00040000,
0x0BB, 0x00000400,
0x0BF, 0x000C0000,
0x0C2, 0x00002400,
0x0C3, 0x00000009,
0x0C4, 0x00040C91,
0x0C5, 0x00099999,
0x0C6, 0x000000A3,
0x0C7, 0x00088820,
0x0C8, 0x00076C06,
0x0C9, 0x00000000,
0x0CA, 0x00080000,
0x0DF, 0x00000180,
0x0EF, 0x000001A0,
0x051, 0x0006B27D,
0x052, 0x0007E49D,
0x053, 0x00000073,
0x056, 0x00051FF3,
0x035, 0x00000086,
0x035, 0x00000186,
0x035, 0x00000286,
0x036, 0x00001C25,
0x036, 0x00009C25,
0x036, 0x00011C25,
0x036, 0x00019C25,
0x0B6, 0x00048538,
0x018, 0x00000C07,
0x05A, 0x0004BD00,
0x019, 0x000739D0,
0x034, 0x0000ADF3,
0x034, 0x00009DF0,
0x034, 0x00008DED,
0x034, 0x00007DEA,
0x034, 0x00006DE7,
0x034, 0x000054EE,
0x034, 0x000044EB,
0x034, 0x000034E8,
0x034, 0x0000246B,
0x034, 0x00001468,
0x034, 0x0000006D,
0x000, 0x00030159,
0x084, 0x00068200,
0x086, 0x000000CE,
0x087, 0x00048A00,
0x08E, 0x00065540,
0x08F, 0x00088000,
0x0EF, 0x000020A0,
0x03B, 0x000F02B0,
0x03B, 0x000EF7B0,
0x03B, 0x000D4FB0,
0x03B, 0x000CF060,
0x03B, 0x000B0090,
0x03B, 0x000A0080,
0x03B, 0x00090080,
0x03B, 0x0008F780,
0x03B, 0x000722B0,
0x03B, 0x0006F7B0,
0x03B, 0x00054FB0,
0x03B, 0x0004F060,
0x03B, 0x00030090,
0x03B, 0x00020080,
0x03B, 0x00010080,
0x03B, 0x0000F780,
0x0EF, 0x000000A0,
0x000, 0x00010159,
0x018, 0x0000F407,
0xFFE, 0x00000000,
0xFFE, 0x00000000,
0x01F, 0x00080003,
0xFFE, 0x00000000,
0xFFE, 0x00000000,
0x01E, 0x00000001,
0x01F, 0x00080000,
0x000, 0x00033E60,
};
u32 RTL8188EEMAC_1T_ARRAY[] = {
0x026, 0x00000041,
0x027, 0x00000035,
0x428, 0x0000000A,
0x429, 0x00000010,
0x430, 0x00000000,
0x431, 0x00000001,
0x432, 0x00000002,
0x433, 0x00000004,
0x434, 0x00000005,
0x435, 0x00000006,
0x436, 0x00000007,
0x437, 0x00000008,
0x438, 0x00000000,
0x439, 0x00000000,
0x43A, 0x00000001,
0x43B, 0x00000002,
0x43C, 0x00000004,
0x43D, 0x00000005,
0x43E, 0x00000006,
0x43F, 0x00000007,
0x440, 0x0000005D,
0x441, 0x00000001,
0x442, 0x00000000,
0x444, 0x00000015,
0x445, 0x000000F0,
0x446, 0x0000000F,
0x447, 0x00000000,
0x458, 0x00000041,
0x459, 0x000000A8,
0x45A, 0x00000072,
0x45B, 0x000000B9,
0x460, 0x00000066,
0x461, 0x00000066,
0x480, 0x00000008,
0x4C8, 0x000000FF,
0x4C9, 0x00000008,
0x4CC, 0x000000FF,
0x4CD, 0x000000FF,
0x4CE, 0x00000001,
0x4D3, 0x00000001,
0x500, 0x00000026,
0x501, 0x000000A2,
0x502, 0x0000002F,
0x503, 0x00000000,
0x504, 0x00000028,
0x505, 0x000000A3,
0x506, 0x0000005E,
0x507, 0x00000000,
0x508, 0x0000002B,
0x509, 0x000000A4,
0x50A, 0x0000005E,
0x50B, 0x00000000,
0x50C, 0x0000004F,
0x50D, 0x000000A4,
0x50E, 0x00000000,
0x50F, 0x00000000,
0x512, 0x0000001C,
0x514, 0x0000000A,
0x516, 0x0000000A,
0x525, 0x0000004F,
0x550, 0x00000010,
0x551, 0x00000010,
0x559, 0x00000002,
0x55D, 0x000000FF,
0x605, 0x00000030,
0x608, 0x0000000E,
0x609, 0x0000002A,
0x620, 0x000000FF,
0x621, 0x000000FF,
0x622, 0x000000FF,
0x623, 0x000000FF,
0x624, 0x000000FF,
0x625, 0x000000FF,
0x626, 0x000000FF,
0x627, 0x000000FF,
0x652, 0x00000020,
0x63C, 0x0000000A,
0x63D, 0x0000000A,
0x63E, 0x0000000E,
0x63F, 0x0000000E,
0x640, 0x00000040,
0x66E, 0x00000005,
0x700, 0x00000021,
0x701, 0x00000043,
0x702, 0x00000065,
0x703, 0x00000087,
0x708, 0x00000021,
0x709, 0x00000043,
0x70A, 0x00000065,
0x70B, 0x00000087,
};
u32 RTL8188EEAGCTAB_1TARRAY[] = {
0xC78, 0xFB000001,
0xC78, 0xFB010001,
0xC78, 0xFB020001,
0xC78, 0xFB030001,
0xC78, 0xFB040001,
0xC78, 0xFB050001,
0xC78, 0xFA060001,
0xC78, 0xF9070001,
0xC78, 0xF8080001,
0xC78, 0xF7090001,
0xC78, 0xF60A0001,
0xC78, 0xF50B0001,
0xC78, 0xF40C0001,
0xC78, 0xF30D0001,
0xC78, 0xF20E0001,
0xC78, 0xF10F0001,
0xC78, 0xF0100001,
0xC78, 0xEF110001,
0xC78, 0xEE120001,
0xC78, 0xED130001,
0xC78, 0xEC140001,
0xC78, 0xEB150001,
0xC78, 0xEA160001,
0xC78, 0xE9170001,
0xC78, 0xE8180001,
0xC78, 0xE7190001,
0xC78, 0xE61A0001,
0xC78, 0xE51B0001,
0xC78, 0xE41C0001,
0xC78, 0xE31D0001,
0xC78, 0xE21E0001,
0xC78, 0xE11F0001,
0xC78, 0x8A200001,
0xC78, 0x89210001,
0xC78, 0x88220001,
0xC78, 0x87230001,
0xC78, 0x86240001,
0xC78, 0x85250001,
0xC78, 0x84260001,
0xC78, 0x83270001,
0xC78, 0x82280001,
0xC78, 0x6B290001,
0xC78, 0x6A2A0001,
0xC78, 0x692B0001,
0xC78, 0x682C0001,
0xC78, 0x672D0001,
0xC78, 0x662E0001,
0xC78, 0x652F0001,
0xC78, 0x64300001,
0xC78, 0x63310001,
0xC78, 0x62320001,
0xC78, 0x61330001,
0xC78, 0x46340001,
0xC78, 0x45350001,
0xC78, 0x44360001,
0xC78, 0x43370001,
0xC78, 0x42380001,
0xC78, 0x41390001,
0xC78, 0x403A0001,
0xC78, 0x403B0001,
0xC78, 0x403C0001,
0xC78, 0x403D0001,
0xC78, 0x403E0001,
0xC78, 0x403F0001,
0xC78, 0xFB400001,
0xC78, 0xFB410001,
0xC78, 0xFB420001,
0xC78, 0xFB430001,
0xC78, 0xFB440001,
0xC78, 0xFB450001,
0xC78, 0xFB460001,
0xC78, 0xFB470001,
0xC78, 0xFB480001,
0xC78, 0xFA490001,
0xC78, 0xF94A0001,
0xC78, 0xF84B0001,
0xC78, 0xF74C0001,
0xC78, 0xF64D0001,
0xC78, 0xF54E0001,
0xC78, 0xF44F0001,
0xC78, 0xF3500001,
0xC78, 0xF2510001,
0xC78, 0xF1520001,
0xC78, 0xF0530001,
0xC78, 0xEF540001,
0xC78, 0xEE550001,
0xC78, 0xED560001,
0xC78, 0xEC570001,
0xC78, 0xEB580001,
0xC78, 0xEA590001,
0xC78, 0xE95A0001,
0xC78, 0xE85B0001,
0xC78, 0xE75C0001,
0xC78, 0xE65D0001,
0xC78, 0xE55E0001,
0xC78, 0xE45F0001,
0xC78, 0xE3600001,
0xC78, 0xE2610001,
0xC78, 0xC3620001,
0xC78, 0xC2630001,
0xC78, 0xC1640001,
0xC78, 0x8B650001,
0xC78, 0x8A660001,
0xC78, 0x89670001,
0xC78, 0x88680001,
0xC78, 0x87690001,
0xC78, 0x866A0001,
0xC78, 0x856B0001,
0xC78, 0x846C0001,
0xC78, 0x676D0001,
0xC78, 0x666E0001,
0xC78, 0x656F0001,
0xC78, 0x64700001,
0xC78, 0x63710001,
0xC78, 0x62720001,
0xC78, 0x61730001,
0xC78, 0x60740001,
0xC78, 0x46750001,
0xC78, 0x45760001,
0xC78, 0x44770001,
0xC78, 0x43780001,
0xC78, 0x42790001,
0xC78, 0x417A0001,
0xC78, 0x407B0001,
0xC78, 0x407C0001,
0xC78, 0x407D0001,
0xC78, 0x407E0001,
0xC78, 0x407F0001,
};

View file

@ -0,0 +1,43 @@
/******************************************************************************
*
* Copyright(c) 2009-2013 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.
*
* Created on 2010/ 5/18, 1:41
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __RTL92CE_TABLE__H_
#define __RTL92CE_TABLE__H_
#include <linux/types.h>
#define RTL8188EEPHY_REG_1TARRAYLEN 382
extern u32 RTL8188EEPHY_REG_1TARRAY[];
#define RTL8188EEPHY_REG_ARRAY_PGLEN 264
extern u32 RTL8188EEPHY_REG_ARRAY_PG[];
#define RTL8188EE_RADIOA_1TARRAYLEN 190
extern u32 RTL8188EE_RADIOA_1TARRAY[];
#define RTL8188EEMAC_1T_ARRAYLEN 180
extern u32 RTL8188EEMAC_1T_ARRAY[];
#define RTL8188EEAGCTAB_1TARRAYLEN 256
extern u32 RTL8188EEAGCTAB_1TARRAY[];
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,796 @@
/******************************************************************************
*
* Copyright(c) 2009-2013 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 __RTL92CE_TRX_H__
#define __RTL92CE_TRX_H__
#define TX_DESC_SIZE 64
#define TX_DESC_AGGR_SUBFRAME_SIZE 32
#define RX_DESC_SIZE 32
#define RX_DRV_INFO_SIZE_UNIT 8
#define TX_DESC_NEXT_DESC_OFFSET 40
#define USB_HWDESC_HEADER_LEN 32
#define CRCLENGTH 4
#define SET_TX_DESC_PKT_SIZE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 0, 16, __val)
#define SET_TX_DESC_OFFSET(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 16, 8, __val)
#define SET_TX_DESC_BMC(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 24, 1, __val)
#define SET_TX_DESC_HTC(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 25, 1, __val)
#define SET_TX_DESC_LAST_SEG(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 26, 1, __val)
#define SET_TX_DESC_FIRST_SEG(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 27, 1, __val)
#define SET_TX_DESC_LINIP(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 28, 1, __val)
#define SET_TX_DESC_NO_ACM(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 29, 1, __val)
#define SET_TX_DESC_GF(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val)
#define SET_TX_DESC_OWN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val)
#define GET_TX_DESC_PKT_SIZE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 0, 16)
#define GET_TX_DESC_OFFSET(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 16, 8)
#define GET_TX_DESC_BMC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 24, 1)
#define GET_TX_DESC_HTC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 25, 1)
#define GET_TX_DESC_LAST_SEG(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 26, 1)
#define GET_TX_DESC_FIRST_SEG(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 27, 1)
#define GET_TX_DESC_LINIP(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 28, 1)
#define GET_TX_DESC_NO_ACM(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 29, 1)
#define GET_TX_DESC_GF(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 30, 1)
#define GET_TX_DESC_OWN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 31, 1)
#define SET_TX_DESC_MACID(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 0, 6, __val)
#define SET_TX_DESC_QUEUE_SEL(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 8, 5, __val)
#define SET_TX_DESC_RDG_NAV_EXT(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 13, 1, __val)
#define SET_TX_DESC_LSIG_TXOP_EN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 14, 1, __val)
#define SET_TX_DESC_PIFS(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 15, 1, __val)
#define SET_TX_DESC_RATE_ID(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 16, 4, __val)
#define SET_TX_DESC_NAV_USE_HDR(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 20, 1, __val)
#define SET_TX_DESC_EN_DESC_ID(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 21, 1, __val)
#define SET_TX_DESC_SEC_TYPE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 22, 2, __val)
#define SET_TX_DESC_PKT_OFFSET(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 26, 5, __val)
#define SET_TX_DESC_PADDING_LEN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 24, 8, __val)
#define GET_TX_DESC_MACID(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 0, 5)
#define GET_TX_DESC_AGG_ENABLE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 5, 1)
#define GET_TX_DESC_AGG_BREAK(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 6, 1)
#define GET_TX_DESC_RDG_ENABLE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 7, 1)
#define GET_TX_DESC_QUEUE_SEL(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 8, 5)
#define GET_TX_DESC_RDG_NAV_EXT(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 13, 1)
#define GET_TX_DESC_LSIG_TXOP_EN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 14, 1)
#define GET_TX_DESC_PIFS(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 15, 1)
#define GET_TX_DESC_RATE_ID(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 16, 4)
#define GET_TX_DESC_NAV_USE_HDR(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 20, 1)
#define GET_TX_DESC_EN_DESC_ID(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 21, 1)
#define GET_TX_DESC_SEC_TYPE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 22, 2)
#define GET_TX_DESC_PKT_OFFSET(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 24, 8)
#define SET_TX_DESC_RTS_RC(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 0, 6, __val)
#define SET_TX_DESC_DATA_RC(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 6, 6, __val)
#define SET_TX_DESC_AGG_ENABLE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 12, 1, __val)
#define SET_TX_DESC_RDG_ENABLE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 13, 1, __val)
#define SET_TX_DESC_BAR_RTY_TH(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 14, 2, __val)
#define SET_TX_DESC_AGG_BREAK(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 16, 1, __val)
#define SET_TX_DESC_MORE_FRAG(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 17, 1, __val)
#define SET_TX_DESC_RAW(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 18, 1, __val)
#define SET_TX_DESC_CCX(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 19, 1, __val)
#define SET_TX_DESC_AMPDU_DENSITY(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 20, 3, __val)
#define SET_TX_DESC_BT_INT(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 23, 1, __val)
#define SET_TX_DESC_ANTSEL_A(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 24, 1, __val)
#define SET_TX_DESC_ANTSEL_B(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 25, 1, __val)
#define SET_TX_DESC_TX_ANT_CCK(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 26, 2, __val)
#define SET_TX_DESC_TX_ANTL(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 28, 2, __val)
#define SET_TX_DESC_TX_ANT_HT(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 30, 2, __val)
#define GET_TX_DESC_RTS_RC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 0, 6)
#define GET_TX_DESC_DATA_RC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 6, 6)
#define GET_TX_DESC_BAR_RTY_TH(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 14, 2)
#define GET_TX_DESC_MORE_FRAG(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 17, 1)
#define GET_TX_DESC_RAW(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 18, 1)
#define GET_TX_DESC_CCX(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 19, 1)
#define GET_TX_DESC_AMPDU_DENSITY(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 20, 3)
#define GET_TX_DESC_ANTSEL_A(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 24, 1)
#define GET_TX_DESC_ANTSEL_B(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 25, 1)
#define GET_TX_DESC_TX_ANT_CCK(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 26, 2)
#define GET_TX_DESC_TX_ANTL(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 28, 2)
#define GET_TX_DESC_TX_ANT_HT(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 30, 2)
#define SET_TX_DESC_NEXT_HEAP_PAGE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+12, 0, 8, __val)
#define SET_TX_DESC_TAIL_PAGE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+12, 8, 8, __val)
#define SET_TX_DESC_SEQ(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+12, 16, 12, __val)
#define SET_TX_DESC_CPU_HANDLE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+12, 28, 1, __val)
#define SET_TX_DESC_TAG1(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+12, 29, 1, __val)
#define SET_TX_DESC_TRIGGER_INT(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+12, 30, 1, __val)
#define SET_TX_DESC_HWSEQ_EN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+12, 31, 1, __val)
#define GET_TX_DESC_NEXT_HEAP_PAGE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 0, 8)
#define GET_TX_DESC_TAIL_PAGE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 8, 8)
#define GET_TX_DESC_SEQ(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 16, 12)
#define SET_TX_DESC_RTS_RATE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 0, 5, __val)
#define SET_TX_DESC_AP_DCFE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 5, 1, __val)
#define SET_TX_DESC_QOS(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 6, 1, __val)
#define SET_TX_DESC_HWSEQ_SSN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 7, 1, __val)
#define SET_TX_DESC_USE_RATE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 8, 1, __val)
#define SET_TX_DESC_DISABLE_RTS_FB(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 9, 1, __val)
#define SET_TX_DESC_DISABLE_FB(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 10, 1, __val)
#define SET_TX_DESC_CTS2SELF(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 11, 1, __val)
#define SET_TX_DESC_RTS_ENABLE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 12, 1, __val)
#define SET_TX_DESC_HW_RTS_ENABLE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 13, 1, __val)
#define SET_TX_DESC_PORT_ID(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 14, 1, __val)
#define SET_TX_DESC_PWR_STATUS(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 15, 3, __val)
#define SET_TX_DESC_WAIT_DCTS(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 18, 1, __val)
#define SET_TX_DESC_CTS2AP_EN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 19, 1, __val)
#define SET_TX_DESC_TX_SUB_CARRIER(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 20, 2, __val)
#define SET_TX_DESC_TX_STBC(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 22, 2, __val)
#define SET_TX_DESC_DATA_SHORT(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 24, 1, __val)
#define SET_TX_DESC_DATA_BW(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 25, 1, __val)
#define SET_TX_DESC_RTS_SHORT(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 26, 1, __val)
#define SET_TX_DESC_RTS_BW(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 27, 1, __val)
#define SET_TX_DESC_RTS_SC(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 28, 2, __val)
#define SET_TX_DESC_RTS_STBC(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 30, 2, __val)
#define GET_TX_DESC_RTS_RATE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 0, 5)
#define GET_TX_DESC_AP_DCFE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 5, 1)
#define GET_TX_DESC_QOS(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 6, 1)
#define GET_TX_DESC_HWSEQ_EN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 7, 1)
#define GET_TX_DESC_USE_RATE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 8, 1)
#define GET_TX_DESC_DISABLE_RTS_FB(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 9, 1)
#define GET_TX_DESC_DISABLE_FB(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 10, 1)
#define GET_TX_DESC_CTS2SELF(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 11, 1)
#define GET_TX_DESC_RTS_ENABLE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 12, 1)
#define GET_TX_DESC_HW_RTS_ENABLE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 13, 1)
#define GET_TX_DESC_PORT_ID(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 14, 1)
#define GET_TX_DESC_WAIT_DCTS(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 18, 1)
#define GET_TX_DESC_CTS2AP_EN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 19, 1)
#define GET_TX_DESC_TX_SUB_CARRIER(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 20, 2)
#define GET_TX_DESC_TX_STBC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 22, 2)
#define GET_TX_DESC_DATA_SHORT(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 24, 1)
#define GET_TX_DESC_DATA_BW(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 25, 1)
#define GET_TX_DESC_RTS_SHORT(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 26, 1)
#define GET_TX_DESC_RTS_BW(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 27, 1)
#define GET_TX_DESC_RTS_SC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 28, 2)
#define GET_TX_DESC_RTS_STBC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 30, 2)
#define SET_TX_DESC_TX_RATE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+20, 0, 6, __val)
#define SET_TX_DESC_DATA_SHORTGI(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+20, 6, 1, __val)
#define SET_TX_DESC_CCX_TAG(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+20, 7, 1, __val)
#define SET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+20, 8, 5, __val)
#define SET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+20, 13, 4, __val)
#define SET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+20, 17, 1, __val)
#define SET_TX_DESC_DATA_RETRY_LIMIT(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+20, 18, 6, __val)
#define SET_TX_DESC_USB_TXAGG_NUM(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+20, 24, 8, __val)
#define GET_TX_DESC_TX_RATE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+20, 0, 6)
#define GET_TX_DESC_DATA_SHORTGI(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+20, 6, 1)
#define GET_TX_DESC_CCX_TAG(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+20, 7, 1)
#define GET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+20, 8, 5)
#define GET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+20, 13, 4)
#define GET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+20, 17, 1)
#define GET_TX_DESC_DATA_RETRY_LIMIT(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+20, 18, 6)
#define GET_TX_DESC_USB_TXAGG_NUM(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+20, 24, 8)
#define SET_TX_DESC_TXAGC_A(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+24, 0, 5, __val)
#define SET_TX_DESC_TXAGC_B(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+24, 5, 5, __val)
#define SET_TX_DESC_USE_MAX_LEN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+24, 10, 1, __val)
#define SET_TX_DESC_MAX_AGG_NUM(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+24, 11, 5, __val)
#define SET_TX_DESC_MCSG1_MAX_LEN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+24, 16, 4, __val)
#define SET_TX_DESC_MCSG2_MAX_LEN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+24, 20, 4, __val)
#define SET_TX_DESC_MCSG3_MAX_LEN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+24, 24, 4, __val)
#define SET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+24, 28, 4, __val)
#define GET_TX_DESC_TXAGC_A(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+24, 0, 5)
#define GET_TX_DESC_TXAGC_B(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+24, 5, 5)
#define GET_TX_DESC_USE_MAX_LEN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+24, 10, 1)
#define GET_TX_DESC_MAX_AGG_NUM(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+24, 11, 5)
#define GET_TX_DESC_MCSG1_MAX_LEN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+24, 16, 4)
#define GET_TX_DESC_MCSG2_MAX_LEN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+24, 20, 4)
#define GET_TX_DESC_MCSG3_MAX_LEN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+24, 24, 4)
#define GET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+24, 28, 4)
#define SET_TX_DESC_TX_BUFFER_SIZE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 16, __val)
#define SET_TX_DESC_SW_OFFSET30(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+28, 16, 8, __val)
#define SET_TX_DESC_SW_OFFSET31(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+28, 24, 4, __val)
#define SET_TX_DESC_ANTSEL_C(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+28, 29, 1, __val)
#define SET_TX_DESC_NULL_0(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+28, 30, 1, __val)
#define SET_TX_DESC_NULL_1(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+28, 30, 1, __val)
#define GET_TX_DESC_TX_BUFFER_SIZE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+28, 0, 16)
#define SET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+32, 0, 32, __val)
#define SET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+36, 0, 32, __val)
#define GET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+32, 0, 32)
#define GET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+36, 0, 32)
#define SET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+40, 0, 32, __val)
#define SET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+44, 0, 32, __val)
#define GET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+40, 0, 32)
#define GET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+44, 0, 32)
#define GET_RX_DESC_PKT_LEN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 0, 14)
#define GET_RX_DESC_CRC32(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 14, 1)
#define GET_RX_DESC_ICV(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 15, 1)
#define GET_RX_DESC_DRV_INFO_SIZE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 16, 4)
#define GET_RX_DESC_SECURITY(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 20, 3)
#define GET_RX_DESC_QOS(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 23, 1)
#define GET_RX_DESC_SHIFT(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 24, 2)
#define GET_RX_DESC_PHYST(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 26, 1)
#define GET_RX_DESC_SWDEC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 27, 1)
#define GET_RX_DESC_LS(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 28, 1)
#define GET_RX_DESC_FS(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 29, 1)
#define GET_RX_DESC_EOR(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 30, 1)
#define GET_RX_DESC_OWN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 31, 1)
#define SET_RX_DESC_PKT_LEN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 0, 14, __val)
#define SET_RX_DESC_EOR(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val)
#define SET_RX_DESC_OWN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val)
#define GET_RX_DESC_MACID(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 0, 6)
#define GET_RX_DESC_PAGGR(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 14, 1)
#define GET_RX_DESC_FAGGR(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 15, 1)
#define GET_RX_DESC_A1_FIT(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 16, 4)
#define GET_RX_DESC_A2_FIT(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 20, 4)
#define GET_RX_DESC_PAM(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 24, 1)
#define GET_RX_DESC_PWR(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 25, 1)
#define GET_RX_DESC_MD(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 26, 1)
#define GET_RX_DESC_MF(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 27, 1)
#define GET_RX_DESC_TYPE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 28, 2)
#define GET_RX_DESC_MC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 30, 1)
#define GET_RX_DESC_BC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 31, 1)
#define GET_RX_DESC_SEQ(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 0, 12)
#define GET_RX_DESC_FRAG(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 12, 4)
#define GET_RX_DESC_RXMCS(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 0, 6)
#define GET_RX_DESC_RXHT(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 6, 1)
#define GET_RX_STATUS_DESC_RX_GF(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 7, 1)
#define GET_RX_DESC_SPLCP(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 8, 1)
#define GET_RX_DESC_BW(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 9, 1)
#define GET_RX_DESC_HTC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 10, 1)
#define GET_RX_STATUS_DESC_EOSP(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 11, 1)
#define GET_RX_STATUS_DESC_BSSID_FIT(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 12, 2)
#define GET_RX_STATUS_DESC_RPT_SEL(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 14, 2)
#define GET_RX_STATUS_DESC_PATTERN_MATCH(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 29, 1)
#define GET_RX_STATUS_DESC_UNICAST_MATCH(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 30, 1)
#define GET_RX_STATUS_DESC_MAGIC_MATCH(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 31, 1)
#define GET_RX_DESC_IV1(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 0, 32)
#define GET_RX_DESC_TSFL(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+20, 0, 32)
#define GET_RX_DESC_BUFF_ADDR(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+24, 0, 32)
#define GET_RX_DESC_BUFF_ADDR64(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+28, 0, 32)
#define SET_RX_DESC_BUFF_ADDR(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+24, 0, 32, __val)
#define SET_RX_DESC_BUFF_ADDR64(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 32, __val)
/* TX report 2 format in Rx desc*/
#define GET_RX_RPT2_DESC_PKT_LEN(__status) \
LE_BITS_TO_4BYTE(__status, 0, 9)
#define GET_RX_RPT2_DESC_MACID_VALID_1(__status) \
LE_BITS_TO_4BYTE(__status+16, 0, 32)
#define GET_RX_RPT2_DESC_MACID_VALID_2(__status) \
LE_BITS_TO_4BYTE(__status+20, 0, 32)
#define SET_EARLYMODE_PKTNUM(__paddr, __value) \
SET_BITS_TO_LE_4BYTE(__paddr, 0, 4, __value)
#define SET_EARLYMODE_LEN0(__paddr, __value) \
SET_BITS_TO_LE_4BYTE(__paddr, 4, 12, __value)
#define SET_EARLYMODE_LEN1(__paddr, __value) \
SET_BITS_TO_LE_4BYTE(__paddr, 16, 12, __value)
#define SET_EARLYMODE_LEN2_1(__paddr, __value) \
SET_BITS_TO_LE_4BYTE(__paddr, 28, 4, __value)
#define SET_EARLYMODE_LEN2_2(__paddr, __value) \
SET_BITS_TO_LE_4BYTE(__paddr+4, 0, 8, __value)
#define SET_EARLYMODE_LEN3(__paddr, __value) \
SET_BITS_TO_LE_4BYTE(__paddr+4, 8, 12, __value)
#define SET_EARLYMODE_LEN4(__paddr, __value) \
SET_BITS_TO_LE_4BYTE(__paddr+4, 20, 12, __value)
#define CLEAR_PCI_TX_DESC_CONTENT(__pdesc, _size) \
do { \
if (_size > TX_DESC_NEXT_DESC_OFFSET) \
memset(__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET); \
else \
memset(__pdesc, 0, _size); \
} while (0)
#define RTL8188_RX_HAL_IS_CCK_RATE(rxmcs)\
(rxmcs == DESC92C_RATE1M ||\
rxmcs == DESC92C_RATE2M ||\
rxmcs == DESC92C_RATE5_5M ||\
rxmcs == DESC92C_RATE11M)
#define IS_LITTLE_ENDIAN 1
struct phy_rx_agc_info_t {
#if IS_LITTLE_ENDIAN
u8 gain:7, trsw:1;
#else
u8 trsw:1, gain:7;
#endif
};
struct phy_status_rpt {
struct phy_rx_agc_info_t path_agc[2];
u8 ch_corr[2];
u8 cck_sig_qual_ofdm_pwdb_all;
u8 cck_agc_rpt_ofdm_cfosho_a;
u8 cck_rpt_b_ofdm_cfosho_b;
u8 rsvd_1;/* ch_corr_msb; */
u8 noise_power_db_msb;
u8 path_cfotail[2];
u8 pcts_mask[2];
u8 stream_rxevm[2];
u8 path_rxsnr[2];
u8 noise_power_db_lsb;
u8 rsvd_2[3];
u8 stream_csi[2];
u8 stream_target_csi[2];
u8 sig_evm;
u8 rsvd_3;
#if IS_LITTLE_ENDIAN
u8 antsel_rx_keep_2:1; /*ex_intf_flg:1;*/
u8 sgi_en:1;
u8 rxsc:2;
u8 idle_long:1;
u8 r_ant_train_en:1;
u8 ant_sel_b:1;
u8 ant_sel:1;
#else /* _BIG_ENDIAN_ */
u8 ant_sel:1;
u8 ant_sel_b:1;
u8 r_ant_train_en:1;
u8 idle_long:1;
u8 rxsc:2;
u8 sgi_en:1;
u8 antsel_rx_keep_2:1; /*ex_intf_flg:1;*/
#endif
} __packed;
struct rx_fwinfo_88e {
u8 gain_trsw[4];
u8 pwdb_all;
u8 cfosho[4];
u8 cfotail[4];
char rxevm[2];
char rxsnr[4];
u8 pdsnr[2];
u8 csi_current[2];
u8 csi_target[2];
u8 sigevm;
u8 max_ex_pwr;
u8 ex_intf_flag:1;
u8 sgi_en:1;
u8 rxsc:2;
u8 reserve:4;
} __packed;
struct tx_desc_88e {
u32 pktsize:16;
u32 offset:8;
u32 bmc:1;
u32 htc:1;
u32 lastseg:1;
u32 firstseg:1;
u32 linip:1;
u32 noacm:1;
u32 gf:1;
u32 own:1;
u32 macid:6;
u32 rsvd0:2;
u32 queuesel:5;
u32 rd_nav_ext:1;
u32 lsig_txop_en:1;
u32 pifs:1;
u32 rateid:4;
u32 nav_usehdr:1;
u32 en_descid:1;
u32 sectype:2;
u32 pktoffset:8;
u32 rts_rc:6;
u32 data_rc:6;
u32 agg_en:1;
u32 rdg_en:1;
u32 bar_retryht:2;
u32 agg_break:1;
u32 morefrag:1;
u32 raw:1;
u32 ccx:1;
u32 ampdudensity:3;
u32 bt_int:1;
u32 ant_sela:1;
u32 ant_selb:1;
u32 txant_cck:2;
u32 txant_l:2;
u32 txant_ht:2;
u32 nextheadpage:8;
u32 tailpage:8;
u32 seq:12;
u32 cpu_handle:1;
u32 tag1:1;
u32 trigger_int:1;
u32 hwseq_en:1;
u32 rtsrate:5;
u32 apdcfe:1;
u32 qos:1;
u32 hwseq_ssn:1;
u32 userrate:1;
u32 dis_rtsfb:1;
u32 dis_datafb:1;
u32 cts2self:1;
u32 rts_en:1;
u32 hwrts_en:1;
u32 portid:1;
u32 pwr_status:3;
u32 waitdcts:1;
u32 cts2ap_en:1;
u32 txsc:2;
u32 stbc:2;
u32 txshort:1;
u32 txbw:1;
u32 rtsshort:1;
u32 rtsbw:1;
u32 rtssc:2;
u32 rtsstbc:2;
u32 txrate:6;
u32 shortgi:1;
u32 ccxt:1;
u32 txrate_fb_lmt:5;
u32 rtsrate_fb_lmt:4;
u32 retrylmt_en:1;
u32 txretrylmt:6;
u32 usb_txaggnum:8;
u32 txagca:5;
u32 txagcb:5;
u32 usemaxlen:1;
u32 maxaggnum:5;
u32 mcsg1maxlen:4;
u32 mcsg2maxlen:4;
u32 mcsg3maxlen:4;
u32 mcs7sgimaxlen:4;
u32 txbuffersize:16;
u32 sw_offset30:8;
u32 sw_offset31:4;
u32 rsvd1:1;
u32 antsel_c:1;
u32 null_0:1;
u32 null_1:1;
u32 txbuffaddr;
u32 txbufferaddr64;
u32 nextdescaddress;
u32 nextdescaddress64;
u32 reserve_pass_pcie_mm_limit[4];
} __packed;
struct rx_desc_88e {
u32 length:14;
u32 crc32:1;
u32 icverror:1;
u32 drv_infosize:4;
u32 security:3;
u32 qos:1;
u32 shift:2;
u32 phystatus:1;
u32 swdec:1;
u32 lastseg:1;
u32 firstseg:1;
u32 eor:1;
u32 own:1;
u32 macid:6;
u32 tid:4;
u32 hwrsvd:5;
u32 paggr:1;
u32 faggr:1;
u32 a1_fit:4;
u32 a2_fit:4;
u32 pam:1;
u32 pwr:1;
u32 moredata:1;
u32 morefrag:1;
u32 type:2;
u32 mc:1;
u32 bc:1;
u32 seq:12;
u32 frag:4;
u32 nextpktlen:14;
u32 nextind:1;
u32 rsvd:1;
u32 rxmcs:6;
u32 rxht:1;
u32 amsdu:1;
u32 splcp:1;
u32 bandwidth:1;
u32 htc:1;
u32 tcpchk_rpt:1;
u32 ipcchk_rpt:1;
u32 tcpchk_valid:1;
u32 hwpcerr:1;
u32 hwpcind:1;
u32 iv0:16;
u32 iv1;
u32 tsfl;
u32 bufferaddress;
u32 bufferaddress64;
} __packed;
void rtl88ee_tx_fill_desc(struct ieee80211_hw *hw,
struct ieee80211_hdr *hdr, u8 *pdesc_tx,
u8 *txbd, struct ieee80211_tx_info *info,
struct ieee80211_sta *sta,
struct sk_buff *skb,
u8 hw_queue, struct rtl_tcb_desc *ptcb_desc);
bool rtl88ee_rx_query_desc(struct ieee80211_hw *hw,
struct rtl_stats *status,
struct ieee80211_rx_status *rx_status,
u8 *pdesc, struct sk_buff *skb);
void rtl88ee_set_desc(struct ieee80211_hw *hw, u8 *pdesc,
bool istx, u8 desc_name, u8 *val);
u32 rtl88ee_get_desc(u8 *pdesc, bool istx, u8 desc_name);
bool rtl88ee_is_tx_desc_closed(struct ieee80211_hw *hw,
u8 hw_queue, u16 index);
void rtl88ee_tx_polling(struct ieee80211_hw *hw, u8 hw_queue);
void rtl88ee_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
bool firstseg, bool lastseg,
struct sk_buff *skb);
u32 rtl88ee_rx_command_packet(struct ieee80211_hw *hw,
struct rtl_stats status,
struct sk_buff *skb);
#endif

View file

@ -0,0 +1,9 @@
rtl8192c-common-objs := \
main.o \
dm_common.o \
fw_common.o \
phy_common.o
obj-$(CONFIG_RTL8192C_COMMON) += rtl8192c-common.o
ccflags-y += -D__CHECK_ENDIAN__

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,185 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __RTL92COMMON_DM_H__
#define __RTL92COMMON_DM_H__
#include "../wifi.h"
#include "../rtl8192ce/def.h"
#include "../rtl8192ce/reg.h"
#include "fw_common.h"
#define HAL_DM_DIG_DISABLE BIT(0)
#define HAL_DM_HIPWR_DISABLE BIT(1)
#define OFDM_TABLE_LENGTH 37
#define CCK_TABLE_LENGTH 33
#define OFDM_TABLE_SIZE 37
#define CCK_TABLE_SIZE 33
#define BW_AUTO_SWITCH_HIGH_LOW 25
#define BW_AUTO_SWITCH_LOW_HIGH 30
#define DM_DIG_THRESH_HIGH 40
#define DM_DIG_THRESH_LOW 35
#define DM_FALSEALARM_THRESH_LOW 400
#define DM_FALSEALARM_THRESH_HIGH 1000
#define DM_DIG_MAX 0x3e
#define DM_DIG_MIN 0x1e
#define DM_DIG_FA_UPPER 0x32
#define DM_DIG_FA_LOWER 0x20
#define DM_DIG_FA_TH0 0x20
#define DM_DIG_FA_TH1 0x100
#define DM_DIG_FA_TH2 0x200
#define DM_DIG_BACKOFF_MAX 12
#define DM_DIG_BACKOFF_MIN -4
#define DM_DIG_BACKOFF_DEFAULT 10
#define RXPATHSELECTION_SS_TH_lOW 30
#define RXPATHSELECTION_DIFF_TH 18
#define DM_RATR_STA_INIT 0
#define DM_RATR_STA_HIGH 1
#define DM_RATR_STA_MIDDLE 2
#define DM_RATR_STA_LOW 3
#define CTS2SELF_THVAL 30
#define REGC38_TH 20
#define WAIOTTHVal 25
#define TXHIGHPWRLEVEL_NORMAL 0
#define TXHIGHPWRLEVEL_LEVEL1 1
#define TXHIGHPWRLEVEL_LEVEL2 2
#define TXHIGHPWRLEVEL_BT1 3
#define TXHIGHPWRLEVEL_BT2 4
#define DM_TYPE_BYFW 0
#define DM_TYPE_BYDRIVER 1
#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74
#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67
#define DYNAMIC_FUNC_DISABLE 0x0
#define DYNAMIC_FUNC_DIG BIT(0)
#define DYNAMIC_FUNC_HP BIT(1)
#define DYNAMIC_FUNC_SS BIT(2) /*Tx Power Tracking*/
#define DYNAMIC_FUNC_BT BIT(3)
#define DYNAMIC_FUNC_ANT_DIV BIT(4)
#define RSSI_CCK 0
#define RSSI_OFDM 1
#define RSSI_DEFAULT 2
struct swat_t {
u8 failure_cnt;
u8 try_flag;
u8 stop_trying;
long pre_rssi;
long trying_threshold;
u8 cur_antenna;
u8 pre_antenna;
};
enum tag_dynamic_init_gain_operation_type_definition {
DIG_TYPE_THRESH_HIGH = 0,
DIG_TYPE_THRESH_LOW = 1,
DIG_TYPE_BACKOFF = 2,
DIG_TYPE_RX_GAIN_MIN = 3,
DIG_TYPE_RX_GAIN_MAX = 4,
DIG_TYPE_ENABLE = 5,
DIG_TYPE_DISABLE = 6,
DIG_OP_TYPE_MAX
};
enum tag_cck_packet_detection_threshold_type_definition {
CCK_PD_STAGE_LowRssi = 0,
CCK_PD_STAGE_HighRssi = 1,
CCK_FA_STAGE_Low = 2,
CCK_FA_STAGE_High = 3,
CCK_PD_STAGE_MAX = 4,
};
enum dm_1r_cca_e {
CCA_1R = 0,
CCA_2R = 1,
CCA_MAX = 2,
};
enum dm_rf_e {
RF_SAVE = 0,
RF_NORMAL = 1,
RF_MAX = 2,
};
enum dm_sw_ant_switch_e {
ANS_ANTENNA_B = 1,
ANS_ANTENNA_A = 2,
ANS_ANTENNA_MAX = 3,
};
enum dm_dig_ext_port_alg_e {
DIG_EXT_PORT_STAGE_0 = 0,
DIG_EXT_PORT_STAGE_1 = 1,
DIG_EXT_PORT_STAGE_2 = 2,
DIG_EXT_PORT_STAGE_3 = 3,
DIG_EXT_PORT_STAGE_MAX = 4,
};
enum dm_dig_connect_e {
DIG_STA_DISCONNECT = 0,
DIG_STA_CONNECT = 1,
DIG_STA_BEFORE_CONNECT = 2,
DIG_MULTISTA_DISCONNECT = 3,
DIG_MULTISTA_CONNECT = 4,
DIG_CONNECT_MAX
};
void rtl92c_dm_init(struct ieee80211_hw *hw);
void rtl92c_dm_watchdog(struct ieee80211_hw *hw);
void rtl92c_dm_write_dig(struct ieee80211_hw *hw);
void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw);
void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw);
void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw);
void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal);
void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta);
void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw);
void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery);
void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw);
void rtl92c_dm_bt_coexist(struct ieee80211_hw *hw);
void dm_savepowerindex(struct ieee80211_hw *hw);
void dm_writepowerindex(struct ieee80211_hw *hw, u8 value);
void dm_restorepowerindex(struct ieee80211_hw *hw);
#endif

View file

@ -0,0 +1,866 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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 "../wifi.h"
#include "../pci.h"
#include "../base.h"
#include "../core.h"
#include "../rtl8192ce/reg.h"
#include "../rtl8192ce/def.h"
#include "fw_common.h"
#include <linux/export.h>
#include <linux/kmemleak.h>
static void _rtl92c_enable_fw_download(struct ieee80211_hw *hw, bool enable)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CU) {
u32 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
if (enable)
value32 |= MCUFWDL_EN;
else
value32 &= ~MCUFWDL_EN;
rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
} else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CE) {
u8 tmp;
if (enable) {
tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1,
tmp | 0x04);
tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01);
tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2);
rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7);
} else {
tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe);
rtl_write_byte(rtlpriv, REG_MCUFWDL + 1, 0x00);
}
}
}
static void _rtl92c_fw_block_write(struct ieee80211_hw *hw,
const u8 *buffer, u32 size)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u32 blocksize = sizeof(u32);
u8 *bufferptr = (u8 *)buffer;
u32 *pu4byteptr = (u32 *)buffer;
u32 i, offset, blockcount, remainsize;
blockcount = size / blocksize;
remainsize = size % blocksize;
for (i = 0; i < blockcount; i++) {
offset = i * blocksize;
rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset),
*(pu4byteptr + i));
}
if (remainsize) {
offset = blockcount * blocksize;
bufferptr += offset;
for (i = 0; i < remainsize; i++) {
rtl_write_byte(rtlpriv, (FW_8192C_START_ADDRESS +
offset + i), *(bufferptr + i));
}
}
}
static void _rtl92c_fw_page_write(struct ieee80211_hw *hw,
u32 page, const u8 *buffer, u32 size)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u8 value8;
u8 u8page = (u8) (page & 0x07);
value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page;
rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8);
_rtl92c_fw_block_write(hw, buffer, size);
}
static void _rtl92c_fill_dummy(u8 *pfwbuf, u32 *pfwlen)
{
u32 fwlen = *pfwlen;
u8 remain = (u8) (fwlen % 4);
remain = (remain == 0) ? 0 : (4 - remain);
while (remain > 0) {
pfwbuf[fwlen] = 0;
fwlen++;
remain--;
}
*pfwlen = fwlen;
}
static void _rtl92c_write_fw(struct ieee80211_hw *hw,
enum version_8192c version, u8 *buffer, u32 size)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
bool is_version_b;
u8 *bufferptr = (u8 *)buffer;
RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes,\n", size);
is_version_b = IS_NORMAL_CHIP(version);
if (is_version_b) {
u32 pageNums, remainsize;
u32 page, offset;
if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CE)
_rtl92c_fill_dummy(bufferptr, &size);
pageNums = size / FW_8192C_PAGE_SIZE;
remainsize = size % FW_8192C_PAGE_SIZE;
if (pageNums > 4) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"Page numbers should not greater then 4\n");
}
for (page = 0; page < pageNums; page++) {
offset = page * FW_8192C_PAGE_SIZE;
_rtl92c_fw_page_write(hw, page, (bufferptr + offset),
FW_8192C_PAGE_SIZE);
}
if (remainsize) {
offset = pageNums * FW_8192C_PAGE_SIZE;
page = pageNums;
_rtl92c_fw_page_write(hw, page, (bufferptr + offset),
remainsize);
}
} else {
_rtl92c_fw_block_write(hw, buffer, size);
}
}
static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
int err = -EIO;
u32 counter = 0;
u32 value32;
do {
value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
} while ((counter++ < FW_8192C_POLLING_TIMEOUT_COUNT) &&
(!(value32 & FWDL_ChkSum_rpt)));
if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"chksum report faill ! REG_MCUFWDL:0x%08x .\n",
value32);
goto exit;
}
RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
"Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32);
value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
value32 |= MCUFWDL_RDY;
value32 &= ~WINTINI_RDY;
rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
counter = 0;
do {
value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
if (value32 & WINTINI_RDY) {
RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
"Polling FW ready success!! REG_MCUFWDL:0x%08x .\n",
value32);
err = 0;
goto exit;
}
mdelay(FW_8192C_POLLING_DELAY);
} while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT);
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", value32);
exit:
return err;
}
int rtl92c_download_fw(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
struct rtl92c_firmware_header *pfwheader;
u8 *pfwdata;
u32 fwsize;
int err;
enum version_8192c version = rtlhal->version;
if (!rtlhal->pfirmware)
return 1;
pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware;
pfwdata = (u8 *)rtlhal->pfirmware;
fwsize = rtlhal->fwsize;
if (IS_FW_HEADER_EXIST(pfwheader)) {
RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
"Firmware Version(%d), Signature(%#x),Size(%d)\n",
pfwheader->version, pfwheader->signature,
(int)sizeof(struct rtl92c_firmware_header));
pfwdata = pfwdata + sizeof(struct rtl92c_firmware_header);
fwsize = fwsize - sizeof(struct rtl92c_firmware_header);
}
_rtl92c_enable_fw_download(hw, true);
_rtl92c_write_fw(hw, version, pfwdata, fwsize);
_rtl92c_enable_fw_download(hw, false);
err = _rtl92c_fw_free_to_go(hw);
if (err) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"Firmware is not ready to run!\n");
} else {
RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
"Firmware is ready to run!\n");
}
return 0;
}
EXPORT_SYMBOL(rtl92c_download_fw);
static bool _rtl92c_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u8 val_hmetfr, val_mcutst_1;
bool result = false;
val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
val_mcutst_1 = rtl_read_byte(rtlpriv, (REG_MCUTST_1 + boxnum));
if (((val_hmetfr >> boxnum) & BIT(0)) == 0 && val_mcutst_1 == 0)
result = true;
return result;
}
static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
u8 element_id, u32 cmd_len, u8 *cmdbuffer)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
u8 boxnum;
u16 box_reg = 0, box_extreg = 0;
u8 u1b_tmp;
bool isfw_read = false;
u8 buf_index = 0;
bool bwrite_sucess = false;
u8 wait_h2c_limmit = 100;
u8 wait_writeh2c_limmit = 100;
u8 boxcontent[4], boxextcontent[2];
u32 h2c_waitcounter = 0;
unsigned long flag;
u8 idx;
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n");
while (true) {
spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
if (rtlhal->h2c_setinprogress) {
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
"H2C set in progress! Wait to set..element_id(%d).\n",
element_id);
while (rtlhal->h2c_setinprogress) {
spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
flag);
h2c_waitcounter++;
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
"Wait 100 us (%d times)...\n",
h2c_waitcounter);
udelay(100);
if (h2c_waitcounter > 1000)
return;
spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
flag);
}
spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
} else {
rtlhal->h2c_setinprogress = true;
spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
break;
}
}
while (!bwrite_sucess) {
wait_writeh2c_limmit--;
if (wait_writeh2c_limmit == 0) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"Write H2C fail because no trigger for FW INT!\n");
break;
}
boxnum = rtlhal->last_hmeboxnum;
switch (boxnum) {
case 0:
box_reg = REG_HMEBOX_0;
box_extreg = REG_HMEBOX_EXT_0;
break;
case 1:
box_reg = REG_HMEBOX_1;
box_extreg = REG_HMEBOX_EXT_1;
break;
case 2:
box_reg = REG_HMEBOX_2;
box_extreg = REG_HMEBOX_EXT_2;
break;
case 3:
box_reg = REG_HMEBOX_3;
box_extreg = REG_HMEBOX_EXT_3;
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
"switch case not process\n");
break;
}
isfw_read = _rtl92c_check_fw_read_last_h2c(hw, boxnum);
while (!isfw_read) {
wait_h2c_limmit--;
if (wait_h2c_limmit == 0) {
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
"Waiting too long for FW read clear HMEBox(%d)!\n",
boxnum);
break;
}
udelay(10);
isfw_read = _rtl92c_check_fw_read_last_h2c(hw, boxnum);
u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF);
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
"Waiting for FW read clear HMEBox(%d)!!! 0x1BF = %2x\n",
boxnum, u1b_tmp);
}
if (!isfw_read) {
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
"Write H2C register BOX[%d] fail!!!!! Fw do not read.\n",
boxnum);
break;
}
memset(boxcontent, 0, sizeof(boxcontent));
memset(boxextcontent, 0, sizeof(boxextcontent));
boxcontent[0] = element_id;
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
"Write element_id box_reg(%4x) = %2x\n",
box_reg, element_id);
switch (cmd_len) {
case 1:
boxcontent[0] &= ~(BIT(7));
memcpy((u8 *)(boxcontent) + 1,
cmdbuffer + buf_index, 1);
for (idx = 0; idx < 4; idx++) {
rtl_write_byte(rtlpriv, box_reg + idx,
boxcontent[idx]);
}
break;
case 2:
boxcontent[0] &= ~(BIT(7));
memcpy((u8 *)(boxcontent) + 1,
cmdbuffer + buf_index, 2);
for (idx = 0; idx < 4; idx++) {
rtl_write_byte(rtlpriv, box_reg + idx,
boxcontent[idx]);
}
break;
case 3:
boxcontent[0] &= ~(BIT(7));
memcpy((u8 *)(boxcontent) + 1,
cmdbuffer + buf_index, 3);
for (idx = 0; idx < 4; idx++) {
rtl_write_byte(rtlpriv, box_reg + idx,
boxcontent[idx]);
}
break;
case 4:
boxcontent[0] |= (BIT(7));
memcpy((u8 *)(boxextcontent),
cmdbuffer + buf_index, 2);
memcpy((u8 *)(boxcontent) + 1,
cmdbuffer + buf_index + 2, 2);
for (idx = 0; idx < 2; idx++) {
rtl_write_byte(rtlpriv, box_extreg + idx,
boxextcontent[idx]);
}
for (idx = 0; idx < 4; idx++) {
rtl_write_byte(rtlpriv, box_reg + idx,
boxcontent[idx]);
}
break;
case 5:
boxcontent[0] |= (BIT(7));
memcpy((u8 *)(boxextcontent),
cmdbuffer + buf_index, 2);
memcpy((u8 *)(boxcontent) + 1,
cmdbuffer + buf_index + 2, 3);
for (idx = 0; idx < 2; idx++) {
rtl_write_byte(rtlpriv, box_extreg + idx,
boxextcontent[idx]);
}
for (idx = 0; idx < 4; idx++) {
rtl_write_byte(rtlpriv, box_reg + idx,
boxcontent[idx]);
}
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
"switch case not process\n");
break;
}
bwrite_sucess = true;
rtlhal->last_hmeboxnum = boxnum + 1;
if (rtlhal->last_hmeboxnum == 4)
rtlhal->last_hmeboxnum = 0;
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
"pHalData->last_hmeboxnum = %d\n",
rtlhal->last_hmeboxnum);
}
spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
rtlhal->h2c_setinprogress = false;
spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n");
}
void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw,
u8 element_id, u32 cmd_len, u8 *cmdbuffer)
{
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
u32 tmp_cmdbuf[2];
if (!rtlhal->fw_ready) {
RT_ASSERT(false,
"return H2C cmd because of Fw download fail!!!\n");
return;
}
memset(tmp_cmdbuf, 0, 8);
memcpy(tmp_cmdbuf, cmdbuffer, cmd_len);
_rtl92c_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf);
return;
}
EXPORT_SYMBOL(rtl92c_fill_h2c_cmd);
void rtl92c_firmware_selfreset(struct ieee80211_hw *hw)
{
u8 u1b_tmp;
u8 delay = 100;
struct rtl_priv *rtlpriv = rtl_priv(hw);
rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20);
u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
while (u1b_tmp & BIT(2)) {
delay--;
if (delay == 0) {
RT_ASSERT(false, "8051 reset fail.\n");
break;
}
udelay(50);
u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
}
}
EXPORT_SYMBOL(rtl92c_firmware_selfreset);
void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u8 u1_h2c_set_pwrmode[3] = { 0 };
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode);
SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode);
SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode,
(rtlpriv->mac80211.p2p) ? ppsc->smart_ps : 1);
SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode,
ppsc->reg_max_lps_awakeintvl);
RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
"rtl92c_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n",
u1_h2c_set_pwrmode, 3);
rtl92c_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode);
}
EXPORT_SYMBOL(rtl92c_set_fw_pwrmode_cmd);
#define BEACON_PG 0 /*->1*/
#define PSPOLL_PG 2
#define NULL_PG 3
#define PROBERSP_PG 4 /*->5*/
#define TOTAL_RESERVED_PKT_LEN 768
static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
/* page 0 beacon */
0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* page 1 beacon */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* page 2 ps-poll */
0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10,
0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* page 3 null */
0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* page 4 probe_resp */
0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* page 5 probe_resp */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw,
bool (*cmd_send_packet)(struct ieee80211_hw *, struct sk_buff *))
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
struct sk_buff *skb = NULL;
u32 totalpacketlen;
bool rtstatus;
u8 u1rsvdpageloc[3] = { 0 };
bool b_dlok = false;
u8 *beacon;
u8 *p_pspoll;
u8 *nullfunc;
u8 *p_probersp;
/*---------------------------------------------------------
(1) beacon
---------------------------------------------------------*/
beacon = &reserved_page_packet[BEACON_PG * 128];
SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
/*-------------------------------------------------------
(2) ps-poll
--------------------------------------------------------*/
p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1rsvdpageloc, PSPOLL_PG);
/*--------------------------------------------------------
(3) null data
---------------------------------------------------------*/
nullfunc = &reserved_page_packet[NULL_PG * 128];
SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1rsvdpageloc, NULL_PG);
/*---------------------------------------------------------
(4) probe response
----------------------------------------------------------*/
p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1rsvdpageloc, PROBERSP_PG);
totalpacketlen = TOTAL_RESERVED_PKT_LEN;
RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
"rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
&reserved_page_packet[0], totalpacketlen);
RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
"rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
u1rsvdpageloc, 3);
skb = dev_alloc_skb(totalpacketlen);
memcpy((u8 *)skb_put(skb, totalpacketlen),
&reserved_page_packet, totalpacketlen);
if (cmd_send_packet)
rtstatus = cmd_send_packet(hw, skb);
else
rtstatus = rtl_cmd_send_packet(hw, skb);
if (rtstatus)
b_dlok = true;
if (b_dlok) {
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
"Set RSVD page location to Fw.\n");
RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
"H2C_RSVDPAGE:\n",
u1rsvdpageloc, 3);
rtl92c_fill_h2c_cmd(hw, H2C_RSVDPAGE,
sizeof(u1rsvdpageloc), u1rsvdpageloc);
} else
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
"Set RSVD page location to Fw FAIL!!!!!!.\n");
}
EXPORT_SYMBOL(rtl92c_set_fw_rsvdpagepkt);
void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus)
{
u8 u1_joinbssrpt_parm[1] = { 0 };
SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus);
rtl92c_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm);
}
EXPORT_SYMBOL(rtl92c_set_fw_joinbss_report_cmd);
static void rtl92c_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw, u8 ctwindow)
{
u8 u1_ctwindow_period[1] = { ctwindow};
rtl92c_fill_h2c_cmd(hw, H2C_P2P_PS_CTW_CMD, 1, u1_ctwindow_period);
}
/* refactored routine */
static void set_noa_data(struct rtl_priv *rtlpriv,
struct rtl_p2p_ps_info *p2pinfo,
struct p2p_ps_offload_t *p2p_ps_offload)
{
int i;
u32 start_time, tsf_low;
/* hw only support 2 set of NoA */
for (i = 0 ; i < p2pinfo->noa_num ; i++) {
/* To control the reg setting for which NOA*/
rtl_write_byte(rtlpriv, 0x5cf, (i << 4));
if (i == 0)
p2p_ps_offload->noa0_en = 1;
else
p2p_ps_offload->noa1_en = 1;
/* config P2P NoA Descriptor Register */
rtl_write_dword(rtlpriv, 0x5E0,
p2pinfo->noa_duration[i]);
rtl_write_dword(rtlpriv, 0x5E4,
p2pinfo->noa_interval[i]);
/*Get Current TSF value */
tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
start_time = p2pinfo->noa_start_time[i];
if (p2pinfo->noa_count_type[i] != 1) {
while (start_time <= (tsf_low+(50*1024))) {
start_time += p2pinfo->noa_interval[i];
if (p2pinfo->noa_count_type[i] != 255)
p2pinfo->noa_count_type[i]--;
}
}
rtl_write_dword(rtlpriv, 0x5E8, start_time);
rtl_write_dword(rtlpriv, 0x5EC,
p2pinfo->noa_count_type[i]);
}
}
void rtl92c_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw));
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
struct rtl_p2p_ps_info *p2pinfo = &(rtlps->p2p_ps_info);
struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload;
u16 ctwindow;
switch (p2p_ps_state) {
case P2P_PS_DISABLE:
RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD,
"P2P_PS_DISABLE\n");
memset(p2p_ps_offload, 0, sizeof(*p2p_ps_offload));
break;
case P2P_PS_ENABLE:
RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD,
"P2P_PS_ENABLE\n");
/* update CTWindow value. */
if (p2pinfo->ctwindow > 0) {
p2p_ps_offload->ctwindow_en = 1;
ctwindow = p2pinfo->ctwindow;
rtl92c_set_p2p_ctw_period_cmd(hw, ctwindow);
}
/* call refactored routine */
set_noa_data(rtlpriv, p2pinfo, p2p_ps_offload);
if ((p2pinfo->opp_ps == 1) || (p2pinfo->noa_num > 0)) {
/* rst p2p circuit */
rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST,
BIT(4));
p2p_ps_offload->offload_en = 1;
if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) {
p2p_ps_offload->role = 1;
p2p_ps_offload->allstasleep = 0;
} else {
p2p_ps_offload->role = 0;
}
p2p_ps_offload->discovery = 0;
}
break;
case P2P_PS_SCAN:
RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n");
p2p_ps_offload->discovery = 1;
break;
case P2P_PS_SCAN_DONE:
RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD,
"P2P_PS_SCAN_DONE\n");
p2p_ps_offload->discovery = 0;
p2pinfo->p2p_ps_state = P2P_PS_ENABLE;
break;
default:
break;
}
rtl92c_fill_h2c_cmd(hw, H2C_P2P_PS_OFFLOAD, 1, (u8 *)p2p_ps_offload);
}
EXPORT_SYMBOL_GPL(rtl92c_set_p2p_ps_offload_cmd);

View file

@ -0,0 +1,119 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __RTL92C__FW__COMMON__H__
#define __RTL92C__FW__COMMON__H__
#define FW_8192C_SIZE 0x3000
#define FW_8192C_START_ADDRESS 0x1000
#define FW_8192C_END_ADDRESS 0x1FFF
#define FW_8192C_PAGE_SIZE 4096
#define FW_8192C_POLLING_DELAY 5
#define FW_8192C_POLLING_TIMEOUT_COUNT 100
#define NORMAL_CHIP BIT(4)
#define IS_FW_HEADER_EXIST(_pfwhdr) \
((le16_to_cpu(_pfwhdr->signature)&0xFFF0) == 0x92C0 ||\
(le16_to_cpu(_pfwhdr->signature)&0xFFF0) == 0x88C0)
#define CUT_VERSION_MASK (BIT(6)|BIT(7))
#define CHIP_VENDOR_UMC BIT(5)
#define CHIP_VENDOR_UMC_B_CUT BIT(6) /* Chip version for ECO */
#define IS_CHIP_VER_B(version) ((version & CHIP_VER_B) ? true : false)
#define RF_TYPE_MASK (BIT(0)|BIT(1))
#define GET_CVID_RF_TYPE(version) \
((version) & RF_TYPE_MASK)
#define GET_CVID_CUT_VERSION(version) \
((version) & CUT_VERSION_MASK)
#define IS_NORMAL_CHIP(version) \
((version & NORMAL_CHIP) ? true : false)
#define IS_2T2R(version) \
(((GET_CVID_RF_TYPE(version)) == \
CHIP_92C_BITMASK) ? true : false)
#define IS_92C_SERIAL(version) \
((IS_2T2R(version)) ? true : false)
#define IS_CHIP_VENDOR_UMC(version) \
((version & CHIP_VENDOR_UMC) ? true : false)
#define IS_VENDOR_UMC_A_CUT(version) \
((IS_CHIP_VENDOR_UMC(version)) ? \
((GET_CVID_CUT_VERSION(version)) ? false : true) : false)
#define IS_81XXC_VENDOR_UMC_B_CUT(version) \
((IS_CHIP_VENDOR_UMC(version)) ? \
((GET_CVID_CUT_VERSION(version) == \
CHIP_VENDOR_UMC_B_CUT) ? true : false) : false)
struct rtl92c_firmware_header {
__le16 signature;
u8 category;
u8 function;
__le16 version;
u8 subversion;
u8 rsvd1;
u8 month;
u8 date;
u8 hour;
u8 minute;
__le16 ramcodeSize;
__le16 rsvd2;
__le32 svnindex;
__le32 rsvd3;
__le32 rsvd4;
__le32 rsvd5;
};
#define pagenum_128(_len) (u32)(((_len)>>7) + ((_len)&0x7F ? 1 : 0))
#define SET_H2CCMD_PWRMODE_PARM_MODE(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
#define SET_H2CCMD_PWRMODE_PARM_SMART_PS(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val)
#define SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val)
#define SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
#define SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
#define SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val)
#define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val)
int rtl92c_download_fw(struct ieee80211_hw *hw);
void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id,
u32 cmd_len, u8 *p_cmdbuffer);
void rtl92c_firmware_selfreset(struct ieee80211_hw *hw);
void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode);
void rtl92c_set_fw_rsvdpagepkt
(struct ieee80211_hw *hw,
bool (*cmd_send_packet)(struct ieee80211_hw *, struct sk_buff *));
void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus);
void usb_writeN_async(struct rtl_priv *rtlpriv, u32 addr, void *data, u16 len);
void rtl92c_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state);
#endif

View file

@ -0,0 +1,40 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "../wifi.h"
#include <linux/module.h>
MODULE_AUTHOR("lizhaoming <chaoming_li@realsil.com.cn>");
MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
MODULE_AUTHOR("Georgia <georgia@realtek.com>");
MODULE_AUTHOR("Ziv Huang <ziv_huang@realtek.com>");
MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Realtek 8192C/8188C 802.11n PCI wireless");

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,254 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __RTL92C_PHY_COMMON_H__
#define __RTL92C_PHY_COMMON_H__
#define MAX_PRECMD_CNT 16
#define MAX_RFDEPENDCMD_CNT 16
#define MAX_POSTCMD_CNT 16
#define MAX_DOZE_WAITING_TIMES_9x 64
#define RT_CANNOT_IO(hw) false
#define HIGHPOWER_RADIOA_ARRAYLEN 22
#define MAX_TOLERANCE 5
#define APK_BB_REG_NUM 5
#define APK_AFE_REG_NUM 16
#define APK_CURVE_REG_NUM 4
#define PATH_NUM 2
#define LOOP_LIMIT 5
#define MAX_STALL_TIME 50
#define AntennaDiversityValue 0x80
#define MAX_TXPWR_IDX_NMODE_92S 63
#define Reset_Cnt_Limit 3
#define IQK_ADDA_REG_NUM 16
#define IQK_MAC_REG_NUM 4
#define IQK_DELAY_TIME 1
#define RF90_PATH_MAX 2
#define CT_OFFSET_MAC_ADDR 0X16
#define CT_OFFSET_CCK_TX_PWR_IDX 0x5A
#define CT_OFFSET_HT401S_TX_PWR_IDX 0x60
#define CT_OFFSET_HT402S_TX_PWR_IDX_DIF 0x66
#define CT_OFFSET_HT20_TX_PWR_IDX_DIFF 0x69
#define CT_OFFSET_OFDM_TX_PWR_IDX_DIFF 0x6C
#define CT_OFFSET_HT40_MAX_PWR_OFFSET 0x6F
#define CT_OFFSET_HT20_MAX_PWR_OFFSET 0x72
#define CT_OFFSET_CHANNEL_PLAH 0x75
#define CT_OFFSET_THERMAL_METER 0x78
#define CT_OFFSET_RF_OPTION 0x79
#define CT_OFFSET_VERSION 0x7E
#define CT_OFFSET_CUSTOMER_ID 0x7F
#define RTL92C_MAX_PATH_NUM 2
#define LLT_LAST_ENTRY_OF_TX_PKT_BUFFER 255
enum swchnlcmd_id {
CMDID_END,
CMDID_SET_TXPOWEROWER_LEVEL,
CMDID_BBREGWRITE10,
CMDID_WRITEPORT_ULONG,
CMDID_WRITEPORT_USHORT,
CMDID_WRITEPORT_UCHAR,
CMDID_RF_WRITEREG,
};
struct swchnlcmd {
enum swchnlcmd_id cmdid;
u32 para1;
u32 para2;
u32 msdelay;
};
enum hw90_block_e {
HW90_BLOCK_MAC = 0,
HW90_BLOCK_PHY0 = 1,
HW90_BLOCK_PHY1 = 2,
HW90_BLOCK_RF = 3,
HW90_BLOCK_MAXIMUM = 4,
};
enum baseband_config_type {
BASEBAND_CONFIG_PHY_REG = 0,
BASEBAND_CONFIG_AGC_TAB = 1,
};
enum ra_offset_area {
RA_OFFSET_LEGACY_OFDM1,
RA_OFFSET_LEGACY_OFDM2,
RA_OFFSET_HT_OFDM1,
RA_OFFSET_HT_OFDM2,
RA_OFFSET_HT_OFDM3,
RA_OFFSET_HT_OFDM4,
RA_OFFSET_HT_CCK,
};
enum antenna_path {
ANTENNA_NONE,
ANTENNA_D,
ANTENNA_C,
ANTENNA_CD,
ANTENNA_B,
ANTENNA_BD,
ANTENNA_BC,
ANTENNA_BCD,
ANTENNA_A,
ANTENNA_AD,
ANTENNA_AC,
ANTENNA_ACD,
ANTENNA_AB,
ANTENNA_ABD,
ANTENNA_ABC,
ANTENNA_ABCD
};
struct r_antenna_select_ofdm {
u32 r_tx_antenna:4;
u32 r_ant_l:4;
u32 r_ant_non_ht:4;
u32 r_ant_ht1:4;
u32 r_ant_ht2:4;
u32 r_ant_ht_s1:4;
u32 r_ant_non_ht_s1:4;
u32 ofdm_txsc:2;
u32 reserved:2;
};
struct r_antenna_select_cck {
u8 r_cckrx_enable_2:2;
u8 r_cckrx_enable:2;
u8 r_ccktx_enable:4;
};
struct efuse_contents {
u8 mac_addr[ETH_ALEN];
u8 cck_tx_power_idx[6];
u8 ht40_1s_tx_power_idx[6];
u8 ht40_2s_tx_power_idx_diff[3];
u8 ht20_tx_power_idx_diff[3];
u8 ofdm_tx_power_idx_diff[3];
u8 ht40_max_power_offset[3];
u8 ht20_max_power_offset[3];
u8 channel_plan;
u8 thermal_meter;
u8 rf_option[5];
u8 version;
u8 oem_id;
u8 regulatory;
};
struct tx_power_struct {
u8 cck[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
u8 ht40_1s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
u8 ht40_2s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
u8 ht20_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
u8 legacy_ht_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
u8 legacy_ht_txpowerdiff;
u8 groupht20[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
u8 groupht40[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
u8 pwrgroup_cnt;
u32 mcs_original_offset[4][16];
};
u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw,
u32 regaddr, u32 bitmask);
void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw,
u32 regaddr, u32 bitmask, u32 data);
u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw,
enum radio_path rfpath, u32 regaddr,
u32 bitmask);
bool rtl92c_phy_mac_config(struct ieee80211_hw *hw);
bool rtl92c_phy_bb_config(struct ieee80211_hw *hw);
bool rtl92c_phy_rf_config(struct ieee80211_hw *hw);
bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw,
enum radio_path rfpath);
void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw);
void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw,
long *powerlevel);
void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel);
bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw,
long power_indbm);
void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw,
enum nl80211_channel_type ch_type);
void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw);
u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw);
void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery);
void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw,
u16 beaconinterval);
void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta);
void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw);
void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain);
bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
enum radio_path rfpath);
bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw,
u32 rfpath);
bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw,
enum rf_pwrstate rfpwr_state);
void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw);
void rtl92c_phy_set_io(struct ieee80211_hw *hw);
void rtl92c_bb_block_on(struct ieee80211_hw *hw);
u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask);
long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
enum wireless_mode wirelessmode,
u8 txpwridx);
u8 _rtl92c_phy_dbm_to_txpwr_idx(struct ieee80211_hw *hw,
enum wireless_mode wirelessmode,
long power_indbm);
void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw);
void _rtl92c_phy_set_rf_sleep(struct ieee80211_hw *hw);
bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
u8 channel, u8 *stage, u8 *step,
u32 *delay);
u8 rtl92c_bt_rssi_state_change(struct ieee80211_hw *hw);
u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw,
enum radio_path rfpath, u32 offset);
void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw,
enum radio_path rfpath, u32 offset,
u32 data);
u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw,
enum radio_path rfpath, u32 offset);
void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw,
enum radio_path rfpath, u32 offset,
u32 data);
bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw);
void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw,
u32 regaddr, u32 bitmask,
u32 data);
bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype);
#endif

View file

@ -0,0 +1,13 @@
rtl8192ce-objs := \
dm.o \
hw.o \
led.o \
phy.o \
rf.o \
sw.o \
table.o \
trx.o
obj-$(CONFIG_RTL8192CE) += rtl8192ce.o
ccflags-y += -D__CHECK_ENDIAN__

View file

@ -0,0 +1,238 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __RTL92C_DEF_H__
#define __RTL92C_DEF_H__
#define HAL_RETRY_LIMIT_INFRA 48
#define HAL_RETRY_LIMIT_AP_ADHOC 7
#define PHY_RSSI_SLID_WIN_MAX 100
#define PHY_LINKQUALITY_SLID_WIN_MAX 20
#define PHY_BEACON_RSSI_SLID_WIN_MAX 10
#define RESET_DELAY_8185 20
#define RT_IBSS_INT_MASKS (IMR_BCNINT | IMR_TBDOK | IMR_TBDER)
#define RT_AC_INT_MASKS (IMR_VIDOK | IMR_VODOK | IMR_BEDOK|IMR_BKDOK)
#define NUM_OF_FIRMWARE_QUEUE 10
#define NUM_OF_PAGES_IN_FW 0x100
#define NUM_OF_PAGE_IN_FW_QUEUE_BK 0x07
#define NUM_OF_PAGE_IN_FW_QUEUE_BE 0x07
#define NUM_OF_PAGE_IN_FW_QUEUE_VI 0x07
#define NUM_OF_PAGE_IN_FW_QUEUE_VO 0x07
#define NUM_OF_PAGE_IN_FW_QUEUE_HCCA 0x0
#define NUM_OF_PAGE_IN_FW_QUEUE_CMD 0x0
#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT 0x02
#define NUM_OF_PAGE_IN_FW_QUEUE_HIGH 0x02
#define NUM_OF_PAGE_IN_FW_QUEUE_BCN 0x2
#define NUM_OF_PAGE_IN_FW_QUEUE_PUB 0xA1
#define NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM 0x026
#define NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM 0x048
#define NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM 0x048
#define NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM 0x026
#define NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM 0x00
#define MAX_LINES_HWCONFIG_TXT 1000
#define MAX_BYTES_LINE_HWCONFIG_TXT 256
#define SW_THREE_WIRE 0
#define HW_THREE_WIRE 2
#define BT_DEMO_BOARD 0
#define BT_QA_BOARD 1
#define BT_FPGA 2
#define RX_SMOOTH_FACTOR 20
#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0
#define HAL_PRIME_CHNL_OFFSET_LOWER 1
#define HAL_PRIME_CHNL_OFFSET_UPPER 2
#define MAX_H2C_QUEUE_NUM 10
#define RX_MPDU_QUEUE 0
#define RX_CMD_QUEUE 1
#define RX_MAX_QUEUE 2
#define AC2QUEUEID(_AC) (_AC)
#define C2H_RX_CMD_HDR_LEN 8
#define GET_C2H_CMD_CMD_LEN(__prxhdr) \
LE_BITS_TO_4BYTE((__prxhdr), 0, 16)
#define GET_C2H_CMD_ELEMENT_ID(__prxhdr) \
LE_BITS_TO_4BYTE((__prxhdr), 16, 8)
#define GET_C2H_CMD_CMD_SEQ(__prxhdr) \
LE_BITS_TO_4BYTE((__prxhdr), 24, 7)
#define GET_C2H_CMD_CONTINUE(__prxhdr) \
LE_BITS_TO_4BYTE((__prxhdr), 31, 1)
#define GET_C2H_CMD_CONTENT(__prxhdr) \
((u8 *)(__prxhdr) + C2H_RX_CMD_HDR_LEN)
#define GET_C2H_CMD_FEEDBACK_ELEMENT_ID(__pcmdfbhdr) \
LE_BITS_TO_4BYTE((__pcmdfbhdr), 0, 8)
#define GET_C2H_CMD_FEEDBACK_CCX_LEN(__pcmdfbhdr) \
LE_BITS_TO_4BYTE((__pcmdfbhdr), 8, 8)
#define GET_C2H_CMD_FEEDBACK_CCX_CMD_CNT(__pcmdfbhdr) \
LE_BITS_TO_4BYTE((__pcmdfbhdr), 16, 16)
#define GET_C2H_CMD_FEEDBACK_CCX_MAC_ID(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 0, 5)
#define GET_C2H_CMD_FEEDBACK_CCX_VALID(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 7, 1)
#define GET_C2H_CMD_FEEDBACK_CCX_RETRY_CNT(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 8, 5)
#define GET_C2H_CMD_FEEDBACK_CCX_TOK(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 15, 1)
#define GET_C2H_CMD_FEEDBACK_CCX_QSEL(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 16, 4)
#define GET_C2H_CMD_FEEDBACK_CCX_SEQ(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 20, 12)
#define GET_RX_STATUS_DESC_BUFF_ADDR(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc + 24, 0, 32)
#define CHIP_VER_B BIT(4)
#define CHIP_BONDING_IDENTIFIER(_value) (((_value) >> 22) & 0x3)
#define CHIP_BONDING_92C_1T2R 0x1
#define RF_TYPE_1T2R BIT(1)
#define CHIP_92C_BITMASK BIT(0)
#define CHIP_UNKNOWN BIT(7)
#define CHIP_92C_1T2R 0x03
#define CHIP_92C 0x01
#define CHIP_88C 0x00
enum version_8192c {
VERSION_A_CHIP_92C = 0x01,
VERSION_A_CHIP_88C = 0x00,
VERSION_B_CHIP_92C = 0x11,
VERSION_B_CHIP_88C = 0x10,
VERSION_TEST_CHIP_88C = 0x00,
VERSION_TEST_CHIP_92C = 0x01,
VERSION_NORMAL_TSMC_CHIP_88C = 0x10,
VERSION_NORMAL_TSMC_CHIP_92C = 0x11,
VERSION_NORMAL_TSMC_CHIP_92C_1T2R = 0x13,
VERSION_NORMAL_UMC_CHIP_88C_A_CUT = 0x30,
VERSION_NORMAL_UMC_CHIP_92C_A_CUT = 0x31,
VERSION_NORMAL_UMC_CHIP_92C_1T2R_A_CUT = 0x33,
VERSION_NORMA_UMC_CHIP_8723_1T1R_A_CUT = 0x34,
VERSION_NORMA_UMC_CHIP_8723_1T1R_B_CUT = 0x3c,
VERSION_NORMAL_UMC_CHIP_88C_B_CUT = 0x70,
VERSION_NORMAL_UMC_CHIP_92C_B_CUT = 0x71,
VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT = 0x73,
VERSION_UNKNOWN = 0x88,
};
enum rtl819x_loopback_e {
RTL819X_NO_LOOPBACK = 0,
RTL819X_MAC_LOOPBACK = 1,
RTL819X_DMA_LOOPBACK = 2,
RTL819X_CCK_LOOPBACK = 3,
};
enum rf_optype {
RF_OP_BY_SW_3WIRE = 0,
RF_OP_BY_FW,
RF_OP_MAX
};
enum rf_power_state {
RF_ON,
RF_OFF,
RF_SLEEP,
RF_SHUT_DOWN,
};
enum power_save_mode {
POWER_SAVE_MODE_ACTIVE,
POWER_SAVE_MODE_SAVE,
};
enum power_polocy_config {
POWERCFG_MAX_POWER_SAVINGS,
POWERCFG_GLOBAL_POWER_SAVINGS,
POWERCFG_LOCAL_POWER_SAVINGS,
POWERCFG_LENOVO,
};
enum interface_select_pci {
INTF_SEL1_MINICARD = 0,
INTF_SEL0_PCIE = 1,
INTF_SEL2_RSV = 2,
INTF_SEL3_RSV = 3,
};
enum hal_fw_c2h_cmd_id {
HAL_FW_C2H_CMD_Read_MACREG = 0,
HAL_FW_C2H_CMD_Read_BBREG = 1,
HAL_FW_C2H_CMD_Read_RFREG = 2,
HAL_FW_C2H_CMD_Read_EEPROM = 3,
HAL_FW_C2H_CMD_Read_EFUSE = 4,
HAL_FW_C2H_CMD_Read_CAM = 5,
HAL_FW_C2H_CMD_Get_BasicRate = 6,
HAL_FW_C2H_CMD_Get_DataRate = 7,
HAL_FW_C2H_CMD_Survey = 8,
HAL_FW_C2H_CMD_SurveyDone = 9,
HAL_FW_C2H_CMD_JoinBss = 10,
HAL_FW_C2H_CMD_AddSTA = 11,
HAL_FW_C2H_CMD_DelSTA = 12,
HAL_FW_C2H_CMD_AtimDone = 13,
HAL_FW_C2H_CMD_TX_Report = 14,
HAL_FW_C2H_CMD_CCX_Report = 15,
HAL_FW_C2H_CMD_DTM_Report = 16,
HAL_FW_C2H_CMD_TX_Rate_Statistics = 17,
HAL_FW_C2H_CMD_C2HLBK = 18,
HAL_FW_C2H_CMD_C2HDBG = 19,
HAL_FW_C2H_CMD_C2HFEEDBACK = 20,
HAL_FW_C2H_CMD_MAX
};
enum rtl_desc_qsel {
QSLT_BK = 0x2,
QSLT_BE = 0x0,
QSLT_VI = 0x5,
QSLT_VO = 0x7,
QSLT_BEACON = 0x10,
QSLT_HIGH = 0x11,
QSLT_MGNT = 0x12,
QSLT_CMD = 0x13,
};
struct phy_sts_cck_8192s_t {
u8 adc_pwdb_X[4];
u8 sq_rpt;
u8 cck_agc_rpt;
};
struct h2c_cmd_8192c {
u8 element_id;
u32 cmd_len;
u8 *p_cmdbuffer;
};
#endif

View file

@ -0,0 +1,109 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "../wifi.h"
#include "../base.h"
#include "../pci.h"
#include "reg.h"
#include "def.h"
#include "phy.h"
#include "dm.h"
#include "../rtl8192c/fw_common.h"
void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
long undec_sm_pwdb;
if (!rtlpriv->dm.dynamic_txpower_enable)
return;
if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) {
rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
return;
}
if ((mac->link_state < MAC80211_LINKED) &&
(rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
"Not connected to any\n");
rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
return;
}
if (mac->link_state >= MAC80211_LINKED) {
if (mac->opmode == NL80211_IFTYPE_ADHOC) {
undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb;
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
"AP Client PWDB = 0x%lx\n",
undec_sm_pwdb);
} else {
undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb;
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
"STA Default Port PWDB = 0x%lx\n",
undec_sm_pwdb);
}
} else {
undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb;
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
"AP Ext Port PWDB = 0x%lx\n",
undec_sm_pwdb);
}
if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) {
rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
"TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n");
} else if ((undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) &&
(undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL1)) {
rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
"TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n");
} else if (undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) {
rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
"TXHIGHPWRLEVEL_NORMAL\n");
}
if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) {
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
"PHY_SetTxPowerLevel8192S() Channel = %d\n",
rtlphy->current_channel);
rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel);
}
rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
}

View file

@ -0,0 +1,99 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __RTL92C_DM_H__
#define __RTL92C_DM_H__
#define HAL_DM_DIG_DISABLE BIT(0)
#define HAL_DM_HIPWR_DISABLE BIT(1)
#define OFDM_TABLE_LENGTH 37
#define CCK_TABLE_LENGTH 33
#define OFDM_TABLE_SIZE 37
#define CCK_TABLE_SIZE 33
#define BW_AUTO_SWITCH_HIGH_LOW 25
#define BW_AUTO_SWITCH_LOW_HIGH 30
#define DM_DIG_THRESH_HIGH 40
#define DM_DIG_THRESH_LOW 35
#define DM_FALSEALARM_THRESH_LOW 400
#define DM_FALSEALARM_THRESH_HIGH 1000
#define DM_DIG_MAX 0x3e
#define DM_DIG_MIN 0x1e
#define DM_DIG_FA_UPPER 0x32
#define DM_DIG_FA_LOWER 0x20
#define DM_DIG_FA_TH0 0x20
#define DM_DIG_FA_TH1 0x100
#define DM_DIG_FA_TH2 0x200
#define DM_DIG_BACKOFF_MAX 12
#define DM_DIG_BACKOFF_MIN -4
#define DM_DIG_BACKOFF_DEFAULT 10
#define RXPATHSELECTION_SS_TH_lOW 30
#define RXPATHSELECTION_DIFF_TH 18
#define DM_RATR_STA_INIT 0
#define DM_RATR_STA_HIGH 1
#define DM_RATR_STA_MIDDLE 2
#define DM_RATR_STA_LOW 3
#define CTS2SELF_THVAL 30
#define REGC38_TH 20
#define WAIOTTHVal 25
#define TXHIGHPWRLEVEL_NORMAL 0
#define TXHIGHPWRLEVEL_LEVEL1 1
#define TXHIGHPWRLEVEL_LEVEL2 2
#define TXHIGHPWRLEVEL_BT1 3
#define TXHIGHPWRLEVEL_BT2 4
#define DM_TYPE_BYFW 0
#define DM_TYPE_BYDRIVER 1
#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74
#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67
void rtl92c_dm_init(struct ieee80211_hw *hw);
void rtl92c_dm_watchdog(struct ieee80211_hw *hw);
void rtl92c_dm_write_dig(struct ieee80211_hw *hw);
void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw);
void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw);
void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw);
void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal);
void rtl92c_dm_bt_coexist(struct ieee80211_hw *hw);
void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw);
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,80 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __RTL92CE_HW_H__
#define __RTL92CE_HW_H__
static inline u8 rtl92c_get_chnl_group(u8 chnl)
{
u8 group;
if (chnl < 3)
group = 0;
else if (chnl < 9)
group = 1;
else
group = 2;
return group;
}
void rtl92ce_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
void rtl92ce_read_eeprom_info(struct ieee80211_hw *hw);
void rtl92ce_interrupt_recognized(struct ieee80211_hw *hw,
u32 *p_inta, u32 *p_intb);
int rtl92ce_hw_init(struct ieee80211_hw *hw);
void rtl92ce_card_disable(struct ieee80211_hw *hw);
void rtl92ce_enable_interrupt(struct ieee80211_hw *hw);
void rtl92ce_disable_interrupt(struct ieee80211_hw *hw);
int rtl92ce_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type);
void rtl92ce_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid);
void rtl92ce_set_qos(struct ieee80211_hw *hw, int aci);
void rtl92ce_set_beacon_related_registers(struct ieee80211_hw *hw);
void rtl92ce_set_beacon_interval(struct ieee80211_hw *hw);
void rtl92ce_update_interrupt_mask(struct ieee80211_hw *hw,
u32 add_msr, u32 rm_msr);
void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
void rtl92ce_update_hal_rate_tbl(struct ieee80211_hw *hw,
struct ieee80211_sta *sta, u8 rssi_level);
void rtl92ce_update_hal_rate_tbl(struct ieee80211_hw *hw,
struct ieee80211_sta *sta, u8 rssi_level);
void rtl92ce_update_channel_access_setting(struct ieee80211_hw *hw);
bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid);
void rtl92ce_enable_hw_security_config(struct ieee80211_hw *hw);
void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index,
u8 *p_macaddr, bool is_group, u8 enc_algo,
bool is_wepkey, bool clear_all);
void rtl8192ce_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
bool autoload_fail, u8 *hwinfo);
void rtl8192ce_bt_reg_init(struct ieee80211_hw *hw);
void rtl8192ce_bt_hw_init(struct ieee80211_hw *hw);
void rtl92ce_suspend(struct ieee80211_hw *hw);
void rtl92ce_resume(struct ieee80211_hw *hw);
#endif

View file

@ -0,0 +1,151 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "../wifi.h"
#include "../pci.h"
#include "reg.h"
#include "led.h"
static void _rtl92ce_init_led(struct ieee80211_hw *hw,
struct rtl_led *pled, enum rtl_led_pin ledpin)
{
pled->hw = hw;
pled->ledpin = ledpin;
pled->ledon = false;
}
void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
{
u8 ledcfg;
struct rtl_priv *rtlpriv = rtl_priv(hw);
RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n",
REG_LEDCFG2, pled->ledpin);
ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
switch (pled->ledpin) {
case LED_PIN_GPIO0:
break;
case LED_PIN_LED0:
rtl_write_byte(rtlpriv,
REG_LEDCFG2, (ledcfg & 0xf0) | BIT(5) | BIT(6));
break;
case LED_PIN_LED1:
rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0x0f) | BIT(5));
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"switch case not processed\n");
break;
}
pled->ledon = true;
}
void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
u8 ledcfg;
RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n",
REG_LEDCFG2, pled->ledpin);
ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
switch (pled->ledpin) {
case LED_PIN_GPIO0:
break;
case LED_PIN_LED0:
ledcfg &= 0xf0;
if (pcipriv->ledctl.led_opendrain)
rtl_write_byte(rtlpriv, REG_LEDCFG2,
(ledcfg | BIT(1) | BIT(5) | BIT(6)));
else
rtl_write_byte(rtlpriv, REG_LEDCFG2,
(ledcfg | BIT(3) | BIT(5) | BIT(6)));
break;
case LED_PIN_LED1:
ledcfg &= 0x0f;
rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg | BIT(3)));
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"switch case not processed\n");
break;
}
pled->ledon = false;
}
void rtl92ce_init_sw_leds(struct ieee80211_hw *hw)
{
struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
_rtl92ce_init_led(hw, &(pcipriv->ledctl.sw_led0), LED_PIN_LED0);
_rtl92ce_init_led(hw, &(pcipriv->ledctl.sw_led1), LED_PIN_LED1);
}
static void _rtl92ce_sw_led_control(struct ieee80211_hw *hw,
enum led_ctl_mode ledaction)
{
struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0);
switch (ledaction) {
case LED_CTL_POWER_ON:
case LED_CTL_LINK:
case LED_CTL_NO_LINK:
rtl92ce_sw_led_on(hw, pLed0);
break;
case LED_CTL_POWER_OFF:
rtl92ce_sw_led_off(hw, pLed0);
break;
default:
break;
}
}
void rtl92ce_led_control(struct ieee80211_hw *hw,
enum led_ctl_mode ledaction)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) &&
(ledaction == LED_CTL_TX ||
ledaction == LED_CTL_RX ||
ledaction == LED_CTL_SITE_SURVEY ||
ledaction == LED_CTL_LINK ||
ledaction == LED_CTL_NO_LINK ||
ledaction == LED_CTL_START_TO_LINK ||
ledaction == LED_CTL_POWER_ON)) {
return;
}
RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d\n",
ledaction);
_rtl92ce_sw_led_control(hw, ledaction);
}

View file

@ -0,0 +1,38 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __RTL92CE_LED_H__
#define __RTL92CE_LED_H__
void rtl92ce_init_sw_leds(struct ieee80211_hw *hw);
void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled);
void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled);
void rtl92ce_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction);
#endif

View file

@ -0,0 +1,576 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "../wifi.h"
#include "../pci.h"
#include "../ps.h"
#include "../core.h"
#include "reg.h"
#include "def.h"
#include "hw.h"
#include "phy.h"
#include "../rtl8192c/phy_common.h"
#include "rf.h"
#include "dm.h"
#include "../rtl8192c/dm_common.h"
#include "../rtl8192c/fw_common.h"
#include "table.h"
static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);
u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw,
enum radio_path rfpath, u32 regaddr, u32 bitmask)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u32 original_value, readback_value, bitshift;
struct rtl_phy *rtlphy = &(rtlpriv->phy);
RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
"regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
regaddr, rfpath, bitmask);
spin_lock(&rtlpriv->locks.rf_lock);
if (rtlphy->rf_mode != RF_OP_BY_FW) {
original_value = _rtl92c_phy_rf_serial_read(hw,
rfpath, regaddr);
} else {
original_value = _rtl92c_phy_fw_rf_serial_read(hw,
rfpath, regaddr);
}
bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
readback_value = (original_value & bitmask) >> bitshift;
spin_unlock(&rtlpriv->locks.rf_lock);
RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
"regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n",
regaddr, rfpath, bitmask, original_value);
return readback_value;
}
bool rtl92c_phy_mac_config(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
bool is92c = IS_92C_SERIAL(rtlhal->version);
bool rtstatus = _rtl92c_phy_config_mac_with_headerfile(hw);
if (is92c)
rtl_write_byte(rtlpriv, 0x14, 0x71);
else
rtl_write_byte(rtlpriv, 0x04CA, 0x0A);
return rtstatus;
}
bool rtl92c_phy_bb_config(struct ieee80211_hw *hw)
{
bool rtstatus = true;
struct rtl_priv *rtlpriv = rtl_priv(hw);
u16 regval;
u32 regvaldw;
u8 reg_hwparafile = 1;
_rtl92c_phy_init_bb_rf_register_definition(hw);
regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
rtl_write_word(rtlpriv, REG_SYS_FUNC_EN,
regval | BIT(13) | BIT(0) | BIT(1));
rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x83);
rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL + 1, 0xdb);
rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB);
rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN,
FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE |
FEN_BB_GLB_RSTn | FEN_BBRSTB);
rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80);
regvaldw = rtl_read_dword(rtlpriv, REG_LEDCFG0);
rtl_write_dword(rtlpriv, REG_LEDCFG0, regvaldw | BIT(23));
if (reg_hwparafile == 1)
rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw);
return rtstatus;
}
void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw,
enum radio_path rfpath,
u32 regaddr, u32 bitmask, u32 data)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
u32 original_value, bitshift;
RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
"regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
regaddr, bitmask, data, rfpath);
spin_lock(&rtlpriv->locks.rf_lock);
if (rtlphy->rf_mode != RF_OP_BY_FW) {
if (bitmask != RFREG_OFFSET_MASK) {
original_value = _rtl92c_phy_rf_serial_read(hw,
rfpath,
regaddr);
bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
data =
((original_value & (~bitmask)) |
(data << bitshift));
}
_rtl92c_phy_rf_serial_write(hw, rfpath, regaddr, data);
} else {
if (bitmask != RFREG_OFFSET_MASK) {
original_value = _rtl92c_phy_fw_rf_serial_read(hw,
rfpath,
regaddr);
bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
data =
((original_value & (~bitmask)) |
(data << bitshift));
}
_rtl92c_phy_fw_rf_serial_write(hw, rfpath, regaddr, data);
}
spin_unlock(&rtlpriv->locks.rf_lock);
RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
"regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
regaddr, bitmask, data, rfpath);
}
static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u32 i;
u32 arraylength;
u32 *ptrarray;
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl819XMACPHY_Array\n");
arraylength = MAC_2T_ARRAYLENGTH;
ptrarray = RTL8192CEMAC_2T_ARRAY;
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Img:RTL8192CEMAC_2T_ARRAY\n");
for (i = 0; i < arraylength; i = i + 2)
rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]);
return true;
}
bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
u8 configtype)
{
int i;
u32 *phy_regarray_table;
u32 *agctab_array_table;
u16 phy_reg_arraylen, agctab_arraylen;
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
if (IS_92C_SERIAL(rtlhal->version)) {
agctab_arraylen = AGCTAB_2TARRAYLENGTH;
agctab_array_table = RTL8192CEAGCTAB_2TARRAY;
phy_reg_arraylen = PHY_REG_2TARRAY_LENGTH;
phy_regarray_table = RTL8192CEPHY_REG_2TARRAY;
} else {
agctab_arraylen = AGCTAB_1TARRAYLENGTH;
agctab_array_table = RTL8192CEAGCTAB_1TARRAY;
phy_reg_arraylen = PHY_REG_1TARRAY_LENGTH;
phy_regarray_table = RTL8192CEPHY_REG_1TARRAY;
}
if (configtype == BASEBAND_CONFIG_PHY_REG) {
for (i = 0; i < phy_reg_arraylen; i = i + 2) {
rtl_addr_delay(phy_regarray_table[i]);
rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD,
phy_regarray_table[i + 1]);
udelay(1);
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
"The phy_regarray_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n",
phy_regarray_table[i],
phy_regarray_table[i + 1]);
}
} else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
for (i = 0; i < agctab_arraylen; i = i + 2) {
rtl_set_bbreg(hw, agctab_array_table[i], MASKDWORD,
agctab_array_table[i + 1]);
udelay(1);
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
"The agctab_array_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n",
agctab_array_table[i],
agctab_array_table[i + 1]);
}
}
return true;
}
bool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
u8 configtype)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
int i;
u32 *phy_regarray_table_pg;
u16 phy_regarray_pg_len;
phy_regarray_pg_len = PHY_REG_ARRAY_PGLENGTH;
phy_regarray_table_pg = RTL8192CEPHY_REG_ARRAY_PG;
if (configtype == BASEBAND_CONFIG_PHY_REG) {
for (i = 0; i < phy_regarray_pg_len; i = i + 3) {
rtl_addr_delay(phy_regarray_table_pg[i]);
_rtl92c_store_pwrIndex_diffrate_offset(hw,
phy_regarray_table_pg[i],
phy_regarray_table_pg[i + 1],
phy_regarray_table_pg[i + 2]);
}
} else {
RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
"configtype != BaseBand_Config_PHY_REG\n");
}
return true;
}
bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
enum radio_path rfpath)
{
int i;
u32 *radioa_array_table;
u32 *radiob_array_table;
u16 radioa_arraylen, radiob_arraylen;
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
if (IS_92C_SERIAL(rtlhal->version)) {
radioa_arraylen = RADIOA_2TARRAYLENGTH;
radioa_array_table = RTL8192CERADIOA_2TARRAY;
radiob_arraylen = RADIOB_2TARRAYLENGTH;
radiob_array_table = RTL8192CE_RADIOB_2TARRAY;
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
"Radio_A:RTL8192CERADIOA_2TARRAY\n");
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
"Radio_B:RTL8192CE_RADIOB_2TARRAY\n");
} else {
radioa_arraylen = RADIOA_1TARRAYLENGTH;
radioa_array_table = RTL8192CE_RADIOA_1TARRAY;
radiob_arraylen = RADIOB_1TARRAYLENGTH;
radiob_array_table = RTL8192CE_RADIOB_1TARRAY;
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
"Radio_A:RTL8192CE_RADIOA_1TARRAY\n");
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
"Radio_B:RTL8192CE_RADIOB_1TARRAY\n");
}
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Radio No %x\n", rfpath);
switch (rfpath) {
case RF90_PATH_A:
for (i = 0; i < radioa_arraylen; i = i + 2) {
rtl_rfreg_delay(hw, rfpath, radioa_array_table[i],
RFREG_OFFSET_MASK,
radioa_array_table[i + 1]);
}
break;
case RF90_PATH_B:
for (i = 0; i < radiob_arraylen; i = i + 2) {
rtl_rfreg_delay(hw, rfpath, radiob_array_table[i],
RFREG_OFFSET_MASK,
radiob_array_table[i + 1]);
}
break;
case RF90_PATH_C:
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"switch case not processed\n");
break;
case RF90_PATH_D:
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"switch case not processed\n");
break;
default:
break;
}
return true;
}
void rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
struct rtl_phy *rtlphy = &(rtlpriv->phy);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
u8 reg_bw_opmode;
u8 reg_prsr_rsc;
RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n",
rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
"20MHz" : "40MHz");
if (is_hal_stop(rtlhal)) {
rtlphy->set_bwmode_inprogress = false;
return;
}
reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
switch (rtlphy->current_chan_bw) {
case HT_CHANNEL_WIDTH_20:
reg_bw_opmode |= BW_OPMODE_20MHZ;
rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
break;
case HT_CHANNEL_WIDTH_20_40:
reg_bw_opmode &= ~BW_OPMODE_20MHZ;
rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
reg_prsr_rsc =
(reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5);
rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
break;
}
switch (rtlphy->current_chan_bw) {
case HT_CHANNEL_WIDTH_20:
rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);
break;
case HT_CHANNEL_WIDTH_20_40:
rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
(mac->cur_40_prime_sc >> 1));
rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0);
rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
(mac->cur_40_prime_sc ==
HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
break;
}
rtl92ce_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
rtlphy->set_bwmode_inprogress = false;
RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
}
void _rtl92ce_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
{
u8 tmpreg;
u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
struct rtl_priv *rtlpriv = rtl_priv(hw);
tmpreg = rtl_read_byte(rtlpriv, 0xd03);
if ((tmpreg & 0x70) != 0)
rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
else
rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
if ((tmpreg & 0x70) != 0) {
rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS);
if (is2t)
rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00,
MASK12BITS);
rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS,
(rf_a_mode & 0x8FFFF) | 0x10000);
if (is2t)
rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
(rf_b_mode & 0x8FFFF) | 0x10000);
}
lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS);
rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000);
mdelay(100);
if ((tmpreg & 0x70) != 0) {
rtl_write_byte(rtlpriv, 0xd03, tmpreg);
rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode);
if (is2t)
rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
rf_b_mode);
} else {
rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
}
}
static void _rtl92ce_phy_set_rf_sleep(struct ieee80211_hw *hw)
{
u32 u4b_tmp;
u8 delay = 5;
struct rtl_priv *rtlpriv = rtl_priv(hw);
rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
while (u4b_tmp != 0 && delay > 0) {
rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0);
rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
delay--;
}
if (delay == 0) {
rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
"Switch RF timeout !!!\n");
return;
}
rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
}
static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw,
enum rf_pwrstate rfpwr_state)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
bool bresult = true;
u8 i, queue_id;
struct rtl8192_tx_ring *ring = NULL;
switch (rfpwr_state) {
case ERFON:{
if ((ppsc->rfpwr_state == ERFOFF) &&
RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
bool rtstatus;
u32 InitializeCount = 0;
do {
InitializeCount++;
RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
"IPS Set eRf nic enable\n");
rtstatus = rtl_ps_enable_nic(hw);
} while (!rtstatus && (InitializeCount < 10));
RT_CLEAR_PS_LEVEL(ppsc,
RT_RF_OFF_LEVL_HALT_NIC);
} else {
RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
"Set ERFON sleeped:%d ms\n",
jiffies_to_msecs(jiffies -
ppsc->
last_sleep_jiffies));
ppsc->last_awake_jiffies = jiffies;
rtl92ce_phy_set_rf_on(hw);
}
if (mac->link_state == MAC80211_LINKED) {
rtlpriv->cfg->ops->led_control(hw,
LED_CTL_LINK);
} else {
rtlpriv->cfg->ops->led_control(hw,
LED_CTL_NO_LINK);
}
break;
}
case ERFOFF:{
if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
"IPS Set eRf nic disable\n");
rtl_ps_disable_nic(hw);
RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
} else {
if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
rtlpriv->cfg->ops->led_control(hw,
LED_CTL_NO_LINK);
} else {
rtlpriv->cfg->ops->led_control(hw,
LED_CTL_POWER_OFF);
}
}
break;
}
case ERFSLEEP:{
if (ppsc->rfpwr_state == ERFOFF)
return false;
for (queue_id = 0, i = 0;
queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
ring = &pcipriv->dev.tx_ring[queue_id];
if (skb_queue_len(&ring->queue) == 0) {
queue_id++;
continue;
} else {
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
"eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
i + 1, queue_id,
skb_queue_len(&ring->queue));
udelay(10);
i++;
}
if (i >= MAX_DOZE_WAITING_TIMES_9x) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
"ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
MAX_DOZE_WAITING_TIMES_9x,
queue_id,
skb_queue_len(&ring->queue));
break;
}
}
RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
"Set ERFSLEEP awaked:%d ms\n",
jiffies_to_msecs(jiffies -
ppsc->last_awake_jiffies));
ppsc->last_sleep_jiffies = jiffies;
_rtl92ce_phy_set_rf_sleep(hw);
break;
}
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"switch case not processed\n");
bresult = false;
break;
}
if (bresult)
ppsc->rfpwr_state = rfpwr_state;
return bresult;
}
bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw,
enum rf_pwrstate rfpwr_state)
{
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
bool bresult = false;
if (rfpwr_state == ppsc->rfpwr_state)
return bresult;
bresult = _rtl92ce_phy_set_rf_power_state(hw, rfpwr_state);
return bresult;
}

View file

@ -0,0 +1,143 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __RTL92C_PHY_H__
#define __RTL92C_PHY_H__
#define MAX_PRECMD_CNT 16
#define MAX_RFDEPENDCMD_CNT 16
#define MAX_POSTCMD_CNT 16
#define MAX_DOZE_WAITING_TIMES_9x 64
#define RT_CANNOT_IO(hw) false
#define HIGHPOWER_RADIOA_ARRAYLEN 22
#define MAX_TOLERANCE 5
#define APK_BB_REG_NUM 5
#define APK_AFE_REG_NUM 16
#define APK_CURVE_REG_NUM 4
#define PATH_NUM 2
#define LOOP_LIMIT 5
#define MAX_STALL_TIME 50
#define AntennaDiversityValue 0x80
#define MAX_TXPWR_IDX_NMODE_92S 63
#define Reset_Cnt_Limit 3
#define IQK_ADDA_REG_NUM 16
#define IQK_MAC_REG_NUM 4
#define IQK_DELAY_TIME 1
#define RF90_PATH_MAX 2
#define CT_OFFSET_MAC_ADDR 0X16
#define CT_OFFSET_CCK_TX_PWR_IDX 0x5A
#define CT_OFFSET_HT401S_TX_PWR_IDX 0x60
#define CT_OFFSET_HT402S_TX_PWR_IDX_DIF 0x66
#define CT_OFFSET_HT20_TX_PWR_IDX_DIFF 0x69
#define CT_OFFSET_OFDM_TX_PWR_IDX_DIFF 0x6C
#define CT_OFFSET_HT40_MAX_PWR_OFFSET 0x6F
#define CT_OFFSET_HT20_MAX_PWR_OFFSET 0x72
#define CT_OFFSET_CHANNEL_PLAH 0x75
#define CT_OFFSET_THERMAL_METER 0x78
#define CT_OFFSET_RF_OPTION 0x79
#define CT_OFFSET_VERSION 0x7E
#define CT_OFFSET_CUSTOMER_ID 0x7F
#define RTL92C_MAX_PATH_NUM 2
bool rtl92c_phy_bb_config(struct ieee80211_hw *hw);
u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask);
void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask,
u32 data);
u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
u32 regaddr, u32 bitmask);
void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
u32 regaddr, u32 bitmask, u32 data);
bool rtl92c_phy_mac_config(struct ieee80211_hw *hw);
bool rtl92ce_phy_bb_config(struct ieee80211_hw *hw);
bool rtl92c_phy_rf_config(struct ieee80211_hw *hw);
bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw,
enum radio_path rfpath);
void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw);
void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel);
void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel);
bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw,
long power_indbm);
void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw,
enum nl80211_channel_type ch_type);
void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw);
u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw);
void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery);
void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw, u16 beaconinterval);
void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta);
void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw);
void _rtl92ce_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t);
void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain);
bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
enum radio_path rfpath);
bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw,
u32 rfpath);
bool rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw,
enum rf_pwrstate rfpwr_state);
void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw);
bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype);
void rtl92c_phy_set_io(struct ieee80211_hw *hw);
void rtl92c_bb_block_on(struct ieee80211_hw *hw);
u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, enum radio_path rfpath,
u32 offset);
u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw,
enum radio_path rfpath, u32 offset);
u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask);
void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw,
enum radio_path rfpath, u32 offset, u32 data);
void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw,
enum radio_path rfpath, u32 offset,
u32 data);
void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw,
u32 regaddr, u32 bitmask, u32 data);
bool _rtl92ce_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);
void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw);
bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw);
void _rtl92c_phy_set_rf_sleep(struct ieee80211_hw *hw);
bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw,
enum rf_pwrstate rfpwr_state);
bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
u8 configtype);
bool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
u8 configtype);
void rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw);
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,509 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "../wifi.h"
#include "reg.h"
#include "def.h"
#include "phy.h"
#include "rf.h"
#include "dm.h"
static bool _rtl92ce_phy_rf6052_config_parafile(struct ieee80211_hw *hw);
void rtl92ce_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
switch (bandwidth) {
case HT_CHANNEL_WIDTH_20:
rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] &
0xfffff3ff) | 0x0400);
rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK,
rtlphy->rfreg_chnlval[0]);
break;
case HT_CHANNEL_WIDTH_20_40:
rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] &
0xfffff3ff));
rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK,
rtlphy->rfreg_chnlval[0]);
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"unknown bandwidth: %#X\n", bandwidth);
break;
}
}
void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
u8 *ppowerlevel)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
u32 tx_agc[2] = {0, 0}, tmpval;
bool turbo_scanoff = false;
u8 idx1, idx2;
u8 *ptr;
if (rtlefuse->eeprom_regulatory != 0)
turbo_scanoff = true;
if (mac->act_scanning) {
tx_agc[RF90_PATH_A] = 0x3f3f3f3f;
tx_agc[RF90_PATH_B] = 0x3f3f3f3f;
if (turbo_scanoff) {
for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
tx_agc[idx1] = ppowerlevel[idx1] |
(ppowerlevel[idx1] << 8) |
(ppowerlevel[idx1] << 16) |
(ppowerlevel[idx1] << 24);
}
}
} else {
for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
tx_agc[idx1] = ppowerlevel[idx1] |
(ppowerlevel[idx1] << 8) |
(ppowerlevel[idx1] << 16) |
(ppowerlevel[idx1] << 24);
}
if (rtlefuse->eeprom_regulatory == 0) {
tmpval = (rtlphy->mcs_offset[0][6]) +
(rtlphy->mcs_offset[0][7] << 8);
tx_agc[RF90_PATH_A] += tmpval;
tmpval = (rtlphy->mcs_offset[0][14]) +
(rtlphy->mcs_offset[0][15] << 24);
tx_agc[RF90_PATH_B] += tmpval;
}
}
for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
ptr = (u8 *) (&(tx_agc[idx1]));
for (idx2 = 0; idx2 < 4; idx2++) {
if (*ptr > RF6052_MAX_TX_PWR)
*ptr = RF6052_MAX_TX_PWR;
ptr++;
}
}
tmpval = tx_agc[RF90_PATH_A] & 0xff;
rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n",
tmpval, RTXAGC_A_CCK1_MCS32);
tmpval = tx_agc[RF90_PATH_A] >> 8;
tmpval = tmpval & 0xff00ffff;
rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n",
tmpval, RTXAGC_B_CCK11_A_CCK2_11);
tmpval = tx_agc[RF90_PATH_B] >> 24;
rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n",
tmpval, RTXAGC_B_CCK11_A_CCK2_11);
tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff;
rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n",
tmpval, RTXAGC_B_CCK1_55_MCS32);
}
static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw,
u8 *ppowerlevel, u8 channel,
u32 *ofdmbase, u32 *mcsbase)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
u32 powerBase0, powerBase1;
u8 legacy_pwrdiff, ht20_pwrdiff;
u8 i, powerlevel[2];
for (i = 0; i < 2; i++) {
powerlevel[i] = ppowerlevel[i];
legacy_pwrdiff = rtlefuse->txpwr_legacyhtdiff[i][channel - 1];
powerBase0 = powerlevel[i] + legacy_pwrdiff;
powerBase0 = (powerBase0 << 24) | (powerBase0 << 16) |
(powerBase0 << 8) | powerBase0;
*(ofdmbase + i) = powerBase0;
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
" [OFDM power base index rf(%c) = 0x%x]\n",
i == 0 ? 'A' : 'B', *(ofdmbase + i));
}
for (i = 0; i < 2; i++) {
if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) {
ht20_pwrdiff = rtlefuse->txpwr_ht20diff[i][channel - 1];
powerlevel[i] += ht20_pwrdiff;
}
powerBase1 = powerlevel[i];
powerBase1 = (powerBase1 << 24) |
(powerBase1 << 16) | (powerBase1 << 8) | powerBase1;
*(mcsbase + i) = powerBase1;
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
" [MCS power base index rf(%c) = 0x%x]\n",
i == 0 ? 'A' : 'B', *(mcsbase + i));
}
}
static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
u8 channel, u8 index,
u32 *powerBase0,
u32 *powerBase1,
u32 *p_outwriteval)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
u8 i, chnlgroup = 0, pwr_diff_limit[4];
u32 writeVal, customer_limit, rf;
for (rf = 0; rf < 2; rf++) {
switch (rtlefuse->eeprom_regulatory) {
case 0:
chnlgroup = 0;
writeVal = rtlphy->mcs_offset[chnlgroup][index +
(rf ? 8 : 0)]
+ ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"RTK better performance, writeVal(%c) = 0x%x\n",
rf == 0 ? 'A' : 'B', writeVal);
break;
case 1:
if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
writeVal = ((index < 2) ? powerBase0[rf] :
powerBase1[rf]);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"Realtek regulatory, 40MHz, writeVal(%c) = 0x%x\n",
rf == 0 ? 'A' : 'B', writeVal);
} else {
if (rtlphy->pwrgroup_cnt == 1)
chnlgroup = 0;
if (rtlphy->pwrgroup_cnt >= 3) {
if (channel <= 3)
chnlgroup = 0;
else if (channel >= 4 && channel <= 9)
chnlgroup = 1;
else if (channel > 9)
chnlgroup = 2;
if (rtlphy->pwrgroup_cnt == 4)
chnlgroup++;
}
writeVal = rtlphy->mcs_offset[chnlgroup]
[index + (rf ? 8 : 0)] + ((index < 2) ?
powerBase0[rf] :
powerBase1[rf]);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"Realtek regulatory, 20MHz, writeVal(%c) = 0x%x\n",
rf == 0 ? 'A' : 'B', writeVal);
}
break;
case 2:
writeVal =
((index < 2) ? powerBase0[rf] : powerBase1[rf]);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"Better regulatory, writeVal(%c) = 0x%x\n",
rf == 0 ? 'A' : 'B', writeVal);
break;
case 3:
chnlgroup = 0;
if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"customer's limit, 40MHz rf(%c) = 0x%x\n",
rf == 0 ? 'A' : 'B',
rtlefuse->pwrgroup_ht40[rf][channel -
1]);
} else {
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"customer's limit, 20MHz rf(%c) = 0x%x\n",
rf == 0 ? 'A' : 'B',
rtlefuse->pwrgroup_ht20[rf][channel -
1]);
}
for (i = 0; i < 4; i++) {
pwr_diff_limit[i] = (u8) ((rtlphy->mcs_offset
[chnlgroup][index +
(rf ? 8 : 0)] & (0x7f << (i * 8))) >>
(i * 8));
if (rtlphy->current_chan_bw ==
HT_CHANNEL_WIDTH_20_40) {
if (pwr_diff_limit[i] >
rtlefuse->
pwrgroup_ht40[rf][channel - 1])
pwr_diff_limit[i] =
rtlefuse->pwrgroup_ht40[rf]
[channel - 1];
} else {
if (pwr_diff_limit[i] >
rtlefuse->
pwrgroup_ht20[rf][channel - 1])
pwr_diff_limit[i] =
rtlefuse->pwrgroup_ht20[rf]
[channel - 1];
}
}
customer_limit = (pwr_diff_limit[3] << 24) |
(pwr_diff_limit[2] << 16) |
(pwr_diff_limit[1] << 8) | (pwr_diff_limit[0]);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"Customer's limit rf(%c) = 0x%x\n",
rf == 0 ? 'A' : 'B', customer_limit);
writeVal = customer_limit +
((index < 2) ? powerBase0[rf] : powerBase1[rf]);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"Customer, writeVal rf(%c)= 0x%x\n",
rf == 0 ? 'A' : 'B', writeVal);
break;
default:
chnlgroup = 0;
writeVal = rtlphy->mcs_offset[chnlgroup]
[index + (rf ? 8 : 0)]
+ ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"RTK better performance, writeVal rf(%c) = 0x%x\n",
rf == 0 ? 'A' : 'B', writeVal);
break;
}
if (rtlpriv->dm.dynamic_txhighpower_lvl == TXHIGHPWRLEVEL_BT1)
writeVal = writeVal - 0x06060606;
else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
TXHIGHPWRLEVEL_BT2)
writeVal = writeVal - 0x0c0c0c0c;
*(p_outwriteval + rf) = writeVal;
}
}
static void _rtl92c_write_ofdm_power_reg(struct ieee80211_hw *hw,
u8 index, u32 *pValue)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
u16 regoffset_a[6] = {
RTXAGC_A_RATE18_06, RTXAGC_A_RATE54_24,
RTXAGC_A_MCS03_MCS00, RTXAGC_A_MCS07_MCS04,
RTXAGC_A_MCS11_MCS08, RTXAGC_A_MCS15_MCS12
};
u16 regoffset_b[6] = {
RTXAGC_B_RATE18_06, RTXAGC_B_RATE54_24,
RTXAGC_B_MCS03_MCS00, RTXAGC_B_MCS07_MCS04,
RTXAGC_B_MCS11_MCS08, RTXAGC_B_MCS15_MCS12
};
u8 i, rf, pwr_val[4];
u32 writeVal;
u16 regoffset;
for (rf = 0; rf < 2; rf++) {
writeVal = pValue[rf];
for (i = 0; i < 4; i++) {
pwr_val[i] = (u8) ((writeVal & (0x7f <<
(i * 8))) >> (i * 8));
if (pwr_val[i] > RF6052_MAX_TX_PWR)
pwr_val[i] = RF6052_MAX_TX_PWR;
}
writeVal = (pwr_val[3] << 24) | (pwr_val[2] << 16) |
(pwr_val[1] << 8) | pwr_val[0];
if (rf == 0)
regoffset = regoffset_a[index];
else
regoffset = regoffset_b[index];
rtl_set_bbreg(hw, regoffset, MASKDWORD, writeVal);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"Set 0x%x = %08x\n", regoffset, writeVal);
if (((get_rf_type(rtlphy) == RF_2T2R) &&
(regoffset == RTXAGC_A_MCS15_MCS12 ||
regoffset == RTXAGC_B_MCS15_MCS12)) ||
((get_rf_type(rtlphy) != RF_2T2R) &&
(regoffset == RTXAGC_A_MCS07_MCS04 ||
regoffset == RTXAGC_B_MCS07_MCS04))) {
writeVal = pwr_val[3];
if (regoffset == RTXAGC_A_MCS15_MCS12 ||
regoffset == RTXAGC_A_MCS07_MCS04)
regoffset = 0xc90;
if (regoffset == RTXAGC_B_MCS15_MCS12 ||
regoffset == RTXAGC_B_MCS07_MCS04)
regoffset = 0xc98;
for (i = 0; i < 3; i++) {
writeVal = (writeVal > 6) ? (writeVal - 6) : 0;
rtl_write_byte(rtlpriv, (u32) (regoffset + i),
(u8) writeVal);
}
}
}
}
void rtl92ce_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
u8 *ppowerlevel, u8 channel)
{
u32 writeVal[2], powerBase0[2], powerBase1[2];
u8 index;
rtl92c_phy_get_power_base(hw, ppowerlevel,
channel, &powerBase0[0], &powerBase1[0]);
for (index = 0; index < 6; index++) {
_rtl92c_get_txpower_writeval_by_regulatory(hw,
channel, index,
&powerBase0[0],
&powerBase1[0],
&writeVal[0]);
_rtl92c_write_ofdm_power_reg(hw, index, &writeVal[0]);
}
}
bool rtl92ce_phy_rf6052_config(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
if (rtlphy->rf_type == RF_1T1R)
rtlphy->num_total_rfpath = 1;
else
rtlphy->num_total_rfpath = 2;
return _rtl92ce_phy_rf6052_config_parafile(hw);
}
static bool _rtl92ce_phy_rf6052_config_parafile(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
u32 u4_regvalue = 0;
u8 rfpath;
bool rtstatus = true;
struct bb_reg_def *pphyreg;
for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) {
pphyreg = &rtlphy->phyreg_def[rfpath];
switch (rfpath) {
case RF90_PATH_A:
case RF90_PATH_C:
u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs,
BRFSI_RFENV);
break;
case RF90_PATH_B:
case RF90_PATH_D:
u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs,
BRFSI_RFENV << 16);
break;
}
rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1);
udelay(1);
rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1);
udelay(1);
rtl_set_bbreg(hw, pphyreg->rfhssi_para2,
B3WIREADDREAALENGTH, 0x0);
udelay(1);
rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0);
udelay(1);
switch (rfpath) {
case RF90_PATH_A:
rtstatus = rtl92c_phy_config_rf_with_headerfile(hw,
(enum radio_path)rfpath);
break;
case RF90_PATH_B:
rtstatus = rtl92c_phy_config_rf_with_headerfile(hw,
(enum radio_path)rfpath);
break;
case RF90_PATH_C:
break;
case RF90_PATH_D:
break;
}
switch (rfpath) {
case RF90_PATH_A:
case RF90_PATH_C:
rtl_set_bbreg(hw, pphyreg->rfintfs,
BRFSI_RFENV, u4_regvalue);
break;
case RF90_PATH_B:
case RF90_PATH_D:
rtl_set_bbreg(hw, pphyreg->rfintfs,
BRFSI_RFENV << 16, u4_regvalue);
break;
}
if (!rtstatus) {
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
"Radio[%d] Fail!!\n", rfpath);
return false;
}
}
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "<---\n");
return rtstatus;
}

View file

@ -0,0 +1,43 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __RTL92C_RF_H__
#define __RTL92C_RF_H__
#define RF6052_MAX_TX_PWR 0x3F
#define RF6052_MAX_REG 0x3F
#define RF6052_MAX_PATH 2
void rtl92ce_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth);
void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
u8 *ppowerlevel);
void rtl92ce_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
u8 *ppowerlevel, u8 channel);
bool rtl92ce_phy_rf6052_config(struct ieee80211_hw *hw);
#endif

View file

@ -0,0 +1,394 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "../wifi.h"
#include "../core.h"
#include "../pci.h"
#include "../base.h"
#include "reg.h"
#include "def.h"
#include "phy.h"
#include "dm.h"
#include "../rtl8192c/dm_common.h"
#include "../rtl8192c/fw_common.h"
#include "../rtl8192c/phy_common.h"
#include "hw.h"
#include "rf.h"
#include "sw.h"
#include "trx.h"
#include "led.h"
#include <linux/module.h>
static void rtl92c_init_aspm_vars(struct ieee80211_hw *hw)
{
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
/*close ASPM for AMD defaultly */
rtlpci->const_amdpci_aspm = 0;
/*
* ASPM PS mode.
* 0 - Disable ASPM,
* 1 - Enable ASPM without Clock Req,
* 2 - Enable ASPM with Clock Req,
* 3 - Alwyas Enable ASPM with Clock Req,
* 4 - Always Enable ASPM without Clock Req.
* set defult to RTL8192CE:3 RTL8192E:2
* */
rtlpci->const_pci_aspm = 3;
/*Setting for PCI-E device */
rtlpci->const_devicepci_aspm_setting = 0x03;
/*Setting for PCI-E bridge */
rtlpci->const_hostpci_aspm_setting = 0x02;
/*
* In Hw/Sw Radio Off situation.
* 0 - Default,
* 1 - From ASPM setting without low Mac Pwr,
* 2 - From ASPM setting with low Mac Pwr,
* 3 - Bus D3
* set default to RTL8192CE:0 RTL8192SE:2
*/
rtlpci->const_hwsw_rfoff_d3 = 0;
/*
* This setting works for those device with
* backdoor ASPM setting such as EPHY setting.
* 0 - Not support ASPM,
* 1 - Support ASPM,
* 2 - According to chipset.
*/
rtlpci->const_support_pciaspm = 1;
}
int rtl92c_init_sw_vars(struct ieee80211_hw *hw)
{
int err;
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
rtl8192ce_bt_reg_init(hw);
rtlpriv->dm.dm_initialgain_enable = true;
rtlpriv->dm.dm_flag = 0;
rtlpriv->dm.disable_framebursting = false;
rtlpriv->dm.thermalvalue = 0;
rtlpci->transmit_config = CFENDFORM | BIT(12) | BIT(13);
/* compatible 5G band 88ce just 2.4G band & smsp */
rtlpriv->rtlhal.current_bandtype = BAND_ON_2_4G;
rtlpriv->rtlhal.bandset = BAND_ON_2_4G;
rtlpriv->rtlhal.macphymode = SINGLEMAC_SINGLEPHY;
rtlpci->receive_config = (RCR_APPFCS |
RCR_AMF |
RCR_ADF |
RCR_APP_MIC |
RCR_APP_ICV |
RCR_AICV |
RCR_ACRC32 |
RCR_AB |
RCR_AM |
RCR_APM |
RCR_APP_PHYST_RXFF | RCR_HTC_LOC_CTRL | 0);
rtlpci->irq_mask[0] =
(u32) (IMR_ROK |
IMR_VODOK |
IMR_VIDOK |
IMR_BEDOK |
IMR_BKDOK |
IMR_MGNTDOK |
IMR_HIGHDOK | IMR_BDOK | IMR_RDU | IMR_RXFOVW | 0);
rtlpci->irq_mask[1] = (u32) (IMR_CPWM | IMR_C2HCMD | 0);
/* for debug level */
rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
/* for LPS & IPS */
rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps;
if (!rtlpriv->psc.inactiveps)
pr_info("rtl8192ce: Power Save off (module option)\n");
if (!rtlpriv->psc.fwctrl_lps)
pr_info("rtl8192ce: FW Power Save off (module option)\n");
rtlpriv->psc.reg_fwctrl_lps = 3;
rtlpriv->psc.reg_max_lps_awakeintvl = 5;
/* for ASPM, you can close aspm through
* set const_support_pciaspm = 0 */
rtl92c_init_aspm_vars(hw);
if (rtlpriv->psc.reg_fwctrl_lps == 1)
rtlpriv->psc.fwctrl_psmode = FW_PS_MIN_MODE;
else if (rtlpriv->psc.reg_fwctrl_lps == 2)
rtlpriv->psc.fwctrl_psmode = FW_PS_MAX_MODE;
else if (rtlpriv->psc.reg_fwctrl_lps == 3)
rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE;
/* for firmware buf */
rtlpriv->rtlhal.pfirmware = vzalloc(0x4000);
if (!rtlpriv->rtlhal.pfirmware) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"Can't alloc buffer for fw\n");
return 1;
}
/* request fw */
if (IS_VENDOR_UMC_A_CUT(rtlhal->version) &&
!IS_92C_SERIAL(rtlhal->version))
rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU.bin";
else if (IS_81XXC_VENDOR_UMC_B_CUT(rtlhal->version))
rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU_B.bin";
rtlpriv->max_fw_size = 0x4000;
pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name);
err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name,
rtlpriv->io.dev, GFP_KERNEL, hw,
rtl_fw_cb);
if (err) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"Failed to request firmware!\n");
return 1;
}
return 0;
}
void rtl92c_deinit_sw_vars(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
if (rtlpriv->rtlhal.pfirmware) {
vfree(rtlpriv->rtlhal.pfirmware);
rtlpriv->rtlhal.pfirmware = NULL;
}
}
static struct rtl_hal_ops rtl8192ce_hal_ops = {
.init_sw_vars = rtl92c_init_sw_vars,
.deinit_sw_vars = rtl92c_deinit_sw_vars,
.read_eeprom_info = rtl92ce_read_eeprom_info,
.interrupt_recognized = rtl92ce_interrupt_recognized,
.hw_init = rtl92ce_hw_init,
.hw_disable = rtl92ce_card_disable,
.hw_suspend = rtl92ce_suspend,
.hw_resume = rtl92ce_resume,
.enable_interrupt = rtl92ce_enable_interrupt,
.disable_interrupt = rtl92ce_disable_interrupt,
.set_network_type = rtl92ce_set_network_type,
.set_chk_bssid = rtl92ce_set_check_bssid,
.set_qos = rtl92ce_set_qos,
.set_bcn_reg = rtl92ce_set_beacon_related_registers,
.set_bcn_intv = rtl92ce_set_beacon_interval,
.update_interrupt_mask = rtl92ce_update_interrupt_mask,
.get_hw_reg = rtl92ce_get_hw_reg,
.set_hw_reg = rtl92ce_set_hw_reg,
.update_rate_tbl = rtl92ce_update_hal_rate_tbl,
.fill_tx_desc = rtl92ce_tx_fill_desc,
.fill_tx_cmddesc = rtl92ce_tx_fill_cmddesc,
.query_rx_desc = rtl92ce_rx_query_desc,
.set_channel_access = rtl92ce_update_channel_access_setting,
.radio_onoff_checking = rtl92ce_gpio_radio_on_off_checking,
.set_bw_mode = rtl92c_phy_set_bw_mode,
.switch_channel = rtl92c_phy_sw_chnl,
.dm_watchdog = rtl92c_dm_watchdog,
.scan_operation_backup = rtl_phy_scan_operation_backup,
.set_rf_power_state = rtl92c_phy_set_rf_power_state,
.led_control = rtl92ce_led_control,
.set_desc = rtl92ce_set_desc,
.get_desc = rtl92ce_get_desc,
.is_tx_desc_closed = rtl92ce_is_tx_desc_closed,
.tx_polling = rtl92ce_tx_polling,
.enable_hw_sec = rtl92ce_enable_hw_security_config,
.set_key = rtl92ce_set_key,
.init_sw_leds = rtl92ce_init_sw_leds,
.get_bbreg = rtl92c_phy_query_bb_reg,
.set_bbreg = rtl92c_phy_set_bb_reg,
.set_rfreg = rtl92ce_phy_set_rf_reg,
.get_rfreg = rtl92c_phy_query_rf_reg,
.phy_rf6052_config = rtl92ce_phy_rf6052_config,
.phy_rf6052_set_cck_txpower = rtl92ce_phy_rf6052_set_cck_txpower,
.phy_rf6052_set_ofdm_txpower = rtl92ce_phy_rf6052_set_ofdm_txpower,
.config_bb_with_headerfile = _rtl92ce_phy_config_bb_with_headerfile,
.config_bb_with_pgheaderfile = _rtl92ce_phy_config_bb_with_pgheaderfile,
.phy_lc_calibrate = _rtl92ce_phy_lc_calibrate,
.phy_set_bw_mode_callback = rtl92ce_phy_set_bw_mode_callback,
.dm_dynamic_txpower = rtl92ce_dm_dynamic_txpower,
.get_btc_status = rtl_btc_status_false,
};
static struct rtl_mod_params rtl92ce_mod_params = {
.sw_crypto = false,
.inactiveps = true,
.swctrl_lps = false,
.fwctrl_lps = true,
.debug = DBG_EMERG,
};
static struct rtl_hal_cfg rtl92ce_hal_cfg = {
.bar_id = 2,
.write_readback = true,
.name = "rtl92c_pci",
.fw_name = "rtlwifi/rtl8192cfw.bin",
.ops = &rtl8192ce_hal_ops,
.mod_params = &rtl92ce_mod_params,
.maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL,
.maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN,
.maps[SYS_CLK] = REG_SYS_CLKR,
.maps[MAC_RCR_AM] = AM,
.maps[MAC_RCR_AB] = AB,
.maps[MAC_RCR_ACRC32] = ACRC32,
.maps[MAC_RCR_ACF] = ACF,
.maps[MAC_RCR_AAP] = AAP,
.maps[MAC_HIMR] = REG_HIMR,
.maps[MAC_HIMRE] = REG_HIMRE,
.maps[EFUSE_TEST] = REG_EFUSE_TEST,
.maps[EFUSE_CTRL] = REG_EFUSE_CTRL,
.maps[EFUSE_CLK] = 0,
.maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL,
.maps[EFUSE_PWC_EV12V] = PWC_EV12V,
.maps[EFUSE_FEN_ELDR] = FEN_ELDR,
.maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN,
.maps[EFUSE_ANA8M] = EFUSE_ANA8M,
.maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE,
.maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION,
.maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN,
.maps[EFUSE_OOB_PROTECT_BYTES_LEN] = EFUSE_OOB_PROTECT_BYTES,
.maps[RWCAM] = REG_CAMCMD,
.maps[WCAMI] = REG_CAMWRITE,
.maps[RCAMO] = REG_CAMREAD,
.maps[CAMDBG] = REG_CAMDBG,
.maps[SECR] = REG_SECCFG,
.maps[SEC_CAM_NONE] = CAM_NONE,
.maps[SEC_CAM_WEP40] = CAM_WEP40,
.maps[SEC_CAM_TKIP] = CAM_TKIP,
.maps[SEC_CAM_AES] = CAM_AES,
.maps[SEC_CAM_WEP104] = CAM_WEP104,
.maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6,
.maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5,
.maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4,
.maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3,
.maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2,
.maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1,
.maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8,
.maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7,
.maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6,
.maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5,
.maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4,
.maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3,
.maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2,
.maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1,
.maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2,
.maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1,
.maps[RTL_IMR_TXFOVW] = IMR_TXFOVW,
.maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT,
.maps[RTL_IMR_BCNINT] = IMR_BCNINT,
.maps[RTL_IMR_RXFOVW] = IMR_RXFOVW,
.maps[RTL_IMR_RDU] = IMR_RDU,
.maps[RTL_IMR_ATIMEND] = IMR_ATIMEND,
.maps[RTL_IMR_BDOK] = IMR_BDOK,
.maps[RTL_IMR_MGNTDOK] = IMR_MGNTDOK,
.maps[RTL_IMR_TBDER] = IMR_TBDER,
.maps[RTL_IMR_HIGHDOK] = IMR_HIGHDOK,
.maps[RTL_IMR_TBDOK] = IMR_TBDOK,
.maps[RTL_IMR_BKDOK] = IMR_BKDOK,
.maps[RTL_IMR_BEDOK] = IMR_BEDOK,
.maps[RTL_IMR_VIDOK] = IMR_VIDOK,
.maps[RTL_IMR_VODOK] = IMR_VODOK,
.maps[RTL_IMR_ROK] = IMR_ROK,
.maps[RTL_IBSS_INT_MASKS] = (IMR_BCNINT | IMR_TBDOK | IMR_TBDER),
.maps[RTL_RC_CCK_RATE1M] = DESC92_RATE1M,
.maps[RTL_RC_CCK_RATE2M] = DESC92_RATE2M,
.maps[RTL_RC_CCK_RATE5_5M] = DESC92_RATE5_5M,
.maps[RTL_RC_CCK_RATE11M] = DESC92_RATE11M,
.maps[RTL_RC_OFDM_RATE6M] = DESC92_RATE6M,
.maps[RTL_RC_OFDM_RATE9M] = DESC92_RATE9M,
.maps[RTL_RC_OFDM_RATE12M] = DESC92_RATE12M,
.maps[RTL_RC_OFDM_RATE18M] = DESC92_RATE18M,
.maps[RTL_RC_OFDM_RATE24M] = DESC92_RATE24M,
.maps[RTL_RC_OFDM_RATE36M] = DESC92_RATE36M,
.maps[RTL_RC_OFDM_RATE48M] = DESC92_RATE48M,
.maps[RTL_RC_OFDM_RATE54M] = DESC92_RATE54M,
.maps[RTL_RC_HT_RATEMCS7] = DESC92_RATEMCS7,
.maps[RTL_RC_HT_RATEMCS15] = DESC92_RATEMCS15,
};
static const struct pci_device_id rtl92ce_pci_ids[] = {
{RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8191, rtl92ce_hal_cfg)},
{RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8178, rtl92ce_hal_cfg)},
{RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8177, rtl92ce_hal_cfg)},
{RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8176, rtl92ce_hal_cfg)},
{},
};
MODULE_DEVICE_TABLE(pci, rtl92ce_pci_ids);
MODULE_AUTHOR("lizhaoming <chaoming_li@realsil.com.cn>");
MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Realtek 8192C/8188C 802.11n PCI wireless");
MODULE_FIRMWARE("rtlwifi/rtl8192cfw.bin");
MODULE_FIRMWARE("rtlwifi/rtl8192cfwU.bin");
MODULE_FIRMWARE("rtlwifi/rtl8192cfwU_B.bin");
module_param_named(swenc, rtl92ce_mod_params.sw_crypto, bool, 0444);
module_param_named(debug, rtl92ce_mod_params.debug, int, 0444);
module_param_named(ips, rtl92ce_mod_params.inactiveps, bool, 0444);
module_param_named(swlps, rtl92ce_mod_params.swctrl_lps, bool, 0444);
module_param_named(fwlps, rtl92ce_mod_params.fwctrl_lps, bool, 0444);
MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n");
MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n");
MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
static struct pci_driver rtl92ce_driver = {
.name = KBUILD_MODNAME,
.id_table = rtl92ce_pci_ids,
.probe = rtl_pci_probe,
.remove = rtl_pci_disconnect,
.driver.pm = &rtlwifi_pm_ops,
};
module_pci_driver(rtl92ce_driver);

View file

@ -0,0 +1,41 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __RTL92CE_SW_H__
#define __RTL92CE_SW_H__
int rtl92c_init_sw_vars(struct ieee80211_hw *hw);
void rtl92c_deinit_sw_vars(struct ieee80211_hw *hw);
void rtl92c_init_var_map(struct ieee80211_hw *hw);
bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
u8 configtype);
bool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
u8 configtype);
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,58 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Created on 2010/ 5/18, 1:41
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __RTL92CE_TABLE__H_
#define __RTL92CE_TABLE__H_
#include <linux/types.h>
#define PHY_REG_2TARRAY_LENGTH 374
extern u32 RTL8192CEPHY_REG_2TARRAY[PHY_REG_2TARRAY_LENGTH];
#define PHY_REG_1TARRAY_LENGTH 374
extern u32 RTL8192CEPHY_REG_1TARRAY[PHY_REG_1TARRAY_LENGTH];
#define PHY_REG_ARRAY_PGLENGTH 192
extern u32 RTL8192CEPHY_REG_ARRAY_PG[PHY_REG_ARRAY_PGLENGTH];
#define RADIOA_2TARRAYLENGTH 282
extern u32 RTL8192CERADIOA_2TARRAY[RADIOA_2TARRAYLENGTH];
#define RADIOB_2TARRAYLENGTH 78
extern u32 RTL8192CE_RADIOB_2TARRAY[RADIOB_2TARRAYLENGTH];
#define RADIOA_1TARRAYLENGTH 282
extern u32 RTL8192CE_RADIOA_1TARRAY[RADIOA_1TARRAYLENGTH];
#define RADIOB_1TARRAYLENGTH 1
extern u32 RTL8192CE_RADIOB_1TARRAY[RADIOB_1TARRAYLENGTH];
#define MAC_2T_ARRAYLENGTH 162
extern u32 RTL8192CEMAC_2T_ARRAY[MAC_2T_ARRAYLENGTH];
#define AGCTAB_2TARRAYLENGTH 320
extern u32 RTL8192CEAGCTAB_2TARRAY[AGCTAB_2TARRAYLENGTH];
#define AGCTAB_1TARRAYLENGTH 320
extern u32 RTL8192CEAGCTAB_1TARRAY[AGCTAB_1TARRAYLENGTH];
#endif

View file

@ -0,0 +1,769 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "../wifi.h"
#include "../pci.h"
#include "../base.h"
#include "../stats.h"
#include "reg.h"
#include "def.h"
#include "phy.h"
#include "trx.h"
#include "led.h"
static u8 _rtl92ce_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue)
{
__le16 fc = rtl_get_fc(skb);
if (unlikely(ieee80211_is_beacon(fc)))
return QSLT_BEACON;
if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc))
return QSLT_MGNT;
return skb->priority;
}
static u8 _rtl92c_query_rxpwrpercentage(char antpower)
{
if ((antpower <= -100) || (antpower >= 20))
return 0;
else if (antpower >= 0)
return 100;
else
return 100 + antpower;
}
static u8 _rtl92c_evm_db_to_percentage(char value)
{
char ret_val;
ret_val = value;
if (ret_val >= 0)
ret_val = 0;
if (ret_val <= -33)
ret_val = -33;
ret_val = 0 - ret_val;
ret_val *= 3;
if (ret_val == 99)
ret_val = 100;
return ret_val;
}
static long _rtl92ce_signal_scale_mapping(struct ieee80211_hw *hw,
long currsig)
{
long retsig;
if (currsig >= 61 && currsig <= 100)
retsig = 90 + ((currsig - 60) / 4);
else if (currsig >= 41 && currsig <= 60)
retsig = 78 + ((currsig - 40) / 2);
else if (currsig >= 31 && currsig <= 40)
retsig = 66 + (currsig - 30);
else if (currsig >= 21 && currsig <= 30)
retsig = 54 + (currsig - 20);
else if (currsig >= 5 && currsig <= 20)
retsig = 42 + (((currsig - 5) * 2) / 3);
else if (currsig == 4)
retsig = 36;
else if (currsig == 3)
retsig = 27;
else if (currsig == 2)
retsig = 18;
else if (currsig == 1)
retsig = 9;
else
retsig = currsig;
return retsig;
}
static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw,
struct rtl_stats *pstats,
struct rx_desc_92c *pdesc,
struct rx_fwinfo_92c *p_drvinfo,
bool packet_match_bssid,
bool packet_toself,
bool packet_beacon)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct phy_sts_cck_8192s_t *cck_buf;
struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
s8 rx_pwr_all = 0, rx_pwr[4];
u8 evm, pwdb_all, rf_rx_num = 0;
u8 i, max_spatial_stream;
u32 rssi, total_rssi = 0;
bool is_cck_rate;
is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc->rxmcs);
pstats->packet_matchbssid = packet_match_bssid;
pstats->packet_toself = packet_toself;
pstats->is_cck = is_cck_rate;
pstats->packet_beacon = packet_beacon;
pstats->rx_mimo_sig_qual[0] = -1;
pstats->rx_mimo_sig_qual[1] = -1;
if (is_cck_rate) {
u8 report, cck_highpwr;
cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo;
if (ppsc->rfpwr_state == ERFON)
cck_highpwr = (u8) rtl_get_bbreg(hw,
RFPGA0_XA_HSSIPARAMETER2,
BIT(9));
else
cck_highpwr = false;
if (!cck_highpwr) {
u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
report = cck_buf->cck_agc_rpt & 0xc0;
report = report >> 6;
switch (report) {
case 0x3:
rx_pwr_all = -46 - (cck_agc_rpt & 0x3e);
break;
case 0x2:
rx_pwr_all = -26 - (cck_agc_rpt & 0x3e);
break;
case 0x1:
rx_pwr_all = -12 - (cck_agc_rpt & 0x3e);
break;
case 0x0:
rx_pwr_all = 16 - (cck_agc_rpt & 0x3e);
break;
}
} else {
u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
report = p_drvinfo->cfosho[0] & 0x60;
report = report >> 5;
switch (report) {
case 0x3:
rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f) << 1);
break;
case 0x2:
rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f) << 1);
break;
case 0x1:
rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f) << 1);
break;
case 0x0:
rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f) << 1);
break;
}
}
pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all);
/* CCK gain is smaller than OFDM/MCS gain,
* so we add gain diff by experiences,
* the val is 6
*/
pwdb_all += 6;
if (pwdb_all > 100)
pwdb_all = 100;
/* modify the offset to make the same
* gain index with OFDM.
*/
if (pwdb_all > 34 && pwdb_all <= 42)
pwdb_all -= 2;
else if (pwdb_all > 26 && pwdb_all <= 34)
pwdb_all -= 6;
else if (pwdb_all > 14 && pwdb_all <= 26)
pwdb_all -= 8;
else if (pwdb_all > 4 && pwdb_all <= 14)
pwdb_all -= 4;
pstats->rx_pwdb_all = pwdb_all;
pstats->recvsignalpower = rx_pwr_all;
/* (3) Get Signal Quality (EVM) */
if (packet_match_bssid) {
u8 sq;
if (pstats->rx_pwdb_all > 40)
sq = 100;
else {
sq = cck_buf->sq_rpt;
if (sq > 64)
sq = 0;
else if (sq < 20)
sq = 100;
else
sq = ((64 - sq) * 100) / 44;
}
pstats->signalquality = sq;
pstats->rx_mimo_sig_qual[0] = sq;
pstats->rx_mimo_sig_qual[1] = -1;
}
} else {
rtlpriv->dm.rfpath_rxenable[0] =
rtlpriv->dm.rfpath_rxenable[1] = true;
/* (1)Get RSSI for HT rate */
for (i = RF90_PATH_A; i < RF90_PATH_MAX; i++) {
/* we will judge RF RX path now. */
if (rtlpriv->dm.rfpath_rxenable[i])
rf_rx_num++;
rx_pwr[i] =
((p_drvinfo->gain_trsw[i] & 0x3f) * 2) - 110;
/* Translate DBM to percentage. */
rssi = _rtl92c_query_rxpwrpercentage(rx_pwr[i]);
total_rssi += rssi;
/* Get Rx snr value in DB */
rtlpriv->stats.rx_snr_db[i] =
(long)(p_drvinfo->rxsnr[i] / 2);
/* Record Signal Strength for next packet */
if (packet_match_bssid)
pstats->rx_mimo_signalstrength[i] = (u8) rssi;
}
/* (2)PWDB, Average PWDB cacluated by
* hardware (for rate adaptive)
*/
rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110;
pwdb_all = _rtl92c_query_rxpwrpercentage(rx_pwr_all);
pstats->rx_pwdb_all = pwdb_all;
pstats->rxpower = rx_pwr_all;
pstats->recvsignalpower = rx_pwr_all;
/* (3)EVM of HT rate */
if (pstats->is_ht && pstats->rate >= DESC92_RATEMCS8 &&
pstats->rate <= DESC92_RATEMCS15)
max_spatial_stream = 2;
else
max_spatial_stream = 1;
for (i = 0; i < max_spatial_stream; i++) {
evm = _rtl92c_evm_db_to_percentage(p_drvinfo->rxevm[i]);
if (packet_match_bssid) {
/* Fill value in RFD, Get the first
* spatial stream only
*/
if (i == 0)
pstats->signalquality =
(u8) (evm & 0xff);
pstats->rx_mimo_sig_qual[i] = (u8) (evm & 0xff);
}
}
}
/* UI BSS List signal strength(in percentage),
* make it good looking, from 0~100.
*/
if (is_cck_rate)
pstats->signalstrength =
(u8) (_rtl92ce_signal_scale_mapping(hw, pwdb_all));
else if (rf_rx_num != 0)
pstats->signalstrength =
(u8) (_rtl92ce_signal_scale_mapping
(hw, total_rssi /= rf_rx_num));
}
static void _rtl92ce_translate_rx_signal_stuff(struct ieee80211_hw *hw,
struct sk_buff *skb,
struct rtl_stats *pstats,
struct rx_desc_92c *pdesc,
struct rx_fwinfo_92c *p_drvinfo)
{
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
struct ieee80211_hdr *hdr;
u8 *tmp_buf;
u8 *praddr;
__le16 fc;
u16 type, c_fc;
bool packet_matchbssid, packet_toself, packet_beacon = false;
tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift;
hdr = (struct ieee80211_hdr *)tmp_buf;
fc = hdr->frame_control;
c_fc = le16_to_cpu(fc);
type = WLAN_FC_GET_TYPE(fc);
praddr = hdr->addr1;
packet_matchbssid =
((IEEE80211_FTYPE_CTL != type) &&
ether_addr_equal(mac->bssid,
(c_fc & IEEE80211_FCTL_TODS) ? hdr->addr1 :
(c_fc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 :
hdr->addr3) &&
(!pstats->hwerror) && (!pstats->crc) && (!pstats->icv));
packet_toself = packet_matchbssid &&
ether_addr_equal(praddr, rtlefuse->dev_addr);
if (ieee80211_is_beacon(fc))
packet_beacon = true;
_rtl92ce_query_rxphystatus(hw, pstats, pdesc, p_drvinfo,
packet_matchbssid, packet_toself,
packet_beacon);
rtl_process_phyinfo(hw, tmp_buf, pstats);
}
bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,
struct rtl_stats *stats,
struct ieee80211_rx_status *rx_status,
u8 *p_desc, struct sk_buff *skb)
{
struct rx_fwinfo_92c *p_drvinfo;
struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc;
struct ieee80211_hdr *hdr;
u32 phystatus = GET_RX_DESC_PHYST(pdesc);
stats->length = (u16) GET_RX_DESC_PKT_LEN(pdesc);
stats->rx_drvinfo_size = (u8) GET_RX_DESC_DRV_INFO_SIZE(pdesc) *
RX_DRV_INFO_SIZE_UNIT;
stats->rx_bufshift = (u8) (GET_RX_DESC_SHIFT(pdesc) & 0x03);
stats->icv = (u16) GET_RX_DESC_ICV(pdesc);
stats->crc = (u16) GET_RX_DESC_CRC32(pdesc);
stats->hwerror = (stats->crc | stats->icv);
stats->decrypted = !GET_RX_DESC_SWDEC(pdesc);
stats->rate = (u8) GET_RX_DESC_RXMCS(pdesc);
stats->shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc);
stats->isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1);
stats->isfirst_ampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1)
&& (GET_RX_DESC_FAGGR(pdesc) == 1));
stats->timestamp_low = GET_RX_DESC_TSFL(pdesc);
stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc);
stats->is_ht = (bool)GET_RX_DESC_RXHT(pdesc);
stats->is_cck = RX_HAL_IS_CCK_RATE(pdesc->rxmcs);
rx_status->freq = hw->conf.chandef.chan->center_freq;
rx_status->band = hw->conf.chandef.chan->band;
hdr = (struct ieee80211_hdr *)(skb->data + stats->rx_drvinfo_size
+ stats->rx_bufshift);
if (stats->crc)
rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
if (stats->rx_is40Mhzpacket)
rx_status->flag |= RX_FLAG_40MHZ;
if (stats->is_ht)
rx_status->flag |= RX_FLAG_HT;
rx_status->flag |= RX_FLAG_MACTIME_START;
/* hw will set stats->decrypted true, if it finds the
* frame is open data frame or mgmt frame.
* So hw will not decryption robust managment frame
* for IEEE80211w but still set status->decrypted
* true, so here we should set it back to undecrypted
* for IEEE80211w frame, and mac80211 sw will help
* to decrypt it
*/
if (stats->decrypted) {
if ((_ieee80211_is_robust_mgmt_frame(hdr)) &&
(ieee80211_has_protected(hdr->frame_control)))
rx_status->flag &= ~RX_FLAG_DECRYPTED;
else
rx_status->flag |= RX_FLAG_DECRYPTED;
}
/* rate_idx: index of data rate into band's
* supported rates or MCS index if HT rates
* are use (RX_FLAG_HT)
* Notice: this is diff with windows define
*/
rx_status->rate_idx = rtlwifi_rate_mapping(hw,
stats->is_ht, stats->rate,
stats->isfirst_ampdu);
rx_status->mactime = stats->timestamp_low;
if (phystatus) {
p_drvinfo = (struct rx_fwinfo_92c *)(skb->data +
stats->rx_bufshift);
_rtl92ce_translate_rx_signal_stuff(hw,
skb, stats, pdesc,
p_drvinfo);
}
/*rx_status->qual = stats->signal; */
rx_status->signal = stats->recvsignalpower + 10;
return true;
}
void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
struct ieee80211_hdr *hdr, u8 *pdesc_tx,
u8 *pbd_desc_tx, struct ieee80211_tx_info *info,
struct ieee80211_sta *sta,
struct sk_buff *skb,
u8 hw_queue, struct rtl_tcb_desc *tcb_desc)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
bool defaultadapter = true;
u8 *pdesc = pdesc_tx;
u16 seq_number;
__le16 fc = hdr->frame_control;
u8 fw_qsel = _rtl92ce_map_hwqueue_to_fwqueue(skb, hw_queue);
bool firstseg = ((hdr->seq_ctrl &
cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0);
bool lastseg = ((hdr->frame_control &
cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0);
dma_addr_t mapping = pci_map_single(rtlpci->pdev,
skb->data, skb->len,
PCI_DMA_TODEVICE);
u8 bw_40 = 0;
if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
"DMA mapping error");
return;
}
rcu_read_lock();
sta = get_sta(hw, mac->vif, mac->bssid);
if (mac->opmode == NL80211_IFTYPE_STATION) {
bw_40 = mac->bw_40;
} else if (mac->opmode == NL80211_IFTYPE_AP ||
mac->opmode == NL80211_IFTYPE_ADHOC ||
mac->opmode == NL80211_IFTYPE_MESH_POINT) {
if (sta)
bw_40 = sta->bandwidth >= IEEE80211_STA_RX_BW_40;
}
seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
rtl_get_tcb_desc(hw, info, sta, skb, tcb_desc);
CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_92c));
if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) {
firstseg = true;
lastseg = true;
}
if (firstseg) {
SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
SET_TX_DESC_TX_RATE(pdesc, tcb_desc->hw_rate);
if (tcb_desc->use_shortgi || tcb_desc->use_shortpreamble)
SET_TX_DESC_DATA_SHORTGI(pdesc, 1);
if (info->flags & IEEE80211_TX_CTL_AMPDU) {
SET_TX_DESC_AGG_BREAK(pdesc, 1);
SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x14);
}
SET_TX_DESC_SEQ(pdesc, seq_number);
SET_TX_DESC_RTS_ENABLE(pdesc, ((tcb_desc->rts_enable &&
!tcb_desc->
cts_enable) ? 1 : 0));
SET_TX_DESC_HW_RTS_ENABLE(pdesc,
((tcb_desc->rts_enable
|| tcb_desc->cts_enable) ? 1 : 0));
SET_TX_DESC_CTS2SELF(pdesc, ((tcb_desc->cts_enable) ? 1 : 0));
SET_TX_DESC_RTS_STBC(pdesc, ((tcb_desc->rts_stbc) ? 1 : 0));
SET_TX_DESC_RTS_RATE(pdesc, tcb_desc->rts_rate);
SET_TX_DESC_RTS_BW(pdesc, 0);
SET_TX_DESC_RTS_SC(pdesc, tcb_desc->rts_sc);
SET_TX_DESC_RTS_SHORT(pdesc,
((tcb_desc->rts_rate <= DESC92_RATE54M) ?
(tcb_desc->rts_use_shortpreamble ? 1 : 0)
: (tcb_desc->rts_use_shortgi ? 1 : 0)));
if (bw_40) {
if (tcb_desc->packet_bw) {
SET_TX_DESC_DATA_BW(pdesc, 1);
SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3);
} else {
SET_TX_DESC_DATA_BW(pdesc, 0);
SET_TX_DESC_TX_SUB_CARRIER(pdesc,
mac->cur_40_prime_sc);
}
} else {
SET_TX_DESC_DATA_BW(pdesc, 0);
SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0);
}
SET_TX_DESC_LINIP(pdesc, 0);
SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb->len);
if (sta) {
u8 ampdu_density = sta->ht_cap.ampdu_density;
SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density);
}
if (info->control.hw_key) {
struct ieee80211_key_conf *keyconf =
info->control.hw_key;
switch (keyconf->cipher) {
case WLAN_CIPHER_SUITE_WEP40:
case WLAN_CIPHER_SUITE_WEP104:
case WLAN_CIPHER_SUITE_TKIP:
SET_TX_DESC_SEC_TYPE(pdesc, 0x1);
break;
case WLAN_CIPHER_SUITE_CCMP:
SET_TX_DESC_SEC_TYPE(pdesc, 0x3);
break;
default:
SET_TX_DESC_SEC_TYPE(pdesc, 0x0);
break;
}
}
SET_TX_DESC_PKT_ID(pdesc, 0);
SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel);
SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F);
SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF);
SET_TX_DESC_DISABLE_FB(pdesc, 0);
SET_TX_DESC_USE_RATE(pdesc, tcb_desc->use_driver_rate ? 1 : 0);
if (ieee80211_is_data_qos(fc)) {
if (mac->rdg_en) {
RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
"Enable RDG function\n");
SET_TX_DESC_RDG_ENABLE(pdesc, 1);
SET_TX_DESC_HTC(pdesc, 1);
}
}
}
rcu_read_unlock();
SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0));
SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0));
SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len);
SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
if (rtlpriv->dm.useramask) {
SET_TX_DESC_RATE_ID(pdesc, tcb_desc->ratr_index);
SET_TX_DESC_MACID(pdesc, tcb_desc->mac_id);
} else {
SET_TX_DESC_RATE_ID(pdesc, 0xC + tcb_desc->ratr_index);
SET_TX_DESC_MACID(pdesc, tcb_desc->ratr_index);
}
if ((!ieee80211_is_data_qos(fc)) && ppsc->fwctrl_lps) {
SET_TX_DESC_HWSEQ_EN(pdesc, 1);
SET_TX_DESC_PKT_ID(pdesc, 8);
if (!defaultadapter)
SET_TX_DESC_QOS(pdesc, 1);
}
SET_TX_DESC_MORE_FRAG(pdesc, (lastseg ? 0 : 1));
if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) ||
is_broadcast_ether_addr(ieee80211_get_DA(hdr))) {
SET_TX_DESC_BMC(pdesc, 1);
}
RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n");
}
void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw,
u8 *pdesc, bool firstseg,
bool lastseg, struct sk_buff *skb)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
u8 fw_queue = QSLT_BEACON;
dma_addr_t mapping = pci_map_single(rtlpci->pdev,
skb->data, skb->len,
PCI_DMA_TODEVICE);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
__le16 fc = hdr->frame_control;
if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
"DMA mapping error");
return;
}
CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE);
if (firstseg)
SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
SET_TX_DESC_TX_RATE(pdesc, DESC92_RATE1M);
SET_TX_DESC_SEQ(pdesc, 0);
SET_TX_DESC_LINIP(pdesc, 0);
SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue);
SET_TX_DESC_FIRST_SEG(pdesc, 1);
SET_TX_DESC_LAST_SEG(pdesc, 1);
SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) (skb->len));
SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
SET_TX_DESC_RATE_ID(pdesc, 7);
SET_TX_DESC_MACID(pdesc, 0);
SET_TX_DESC_OWN(pdesc, 1);
SET_TX_DESC_PKT_SIZE(pdesc, (u16) (skb->len));
SET_TX_DESC_FIRST_SEG(pdesc, 1);
SET_TX_DESC_LAST_SEG(pdesc, 1);
SET_TX_DESC_OFFSET(pdesc, 0x20);
SET_TX_DESC_USE_RATE(pdesc, 1);
if (!ieee80211_is_data_qos(fc)) {
SET_TX_DESC_HWSEQ_EN(pdesc, 1);
SET_TX_DESC_PKT_ID(pdesc, 8);
}
RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
"H2C Tx Cmd Content", pdesc, TX_DESC_SIZE);
}
void rtl92ce_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx,
u8 desc_name, u8 *val)
{
if (istx) {
switch (desc_name) {
case HW_DESC_OWN:
wmb();
SET_TX_DESC_OWN(pdesc, 1);
break;
case HW_DESC_TX_NEXTDESC_ADDR:
SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val);
break;
default:
RT_ASSERT(false, "ERR txdesc :%d not process\n",
desc_name);
break;
}
} else {
switch (desc_name) {
case HW_DESC_RXOWN:
wmb();
SET_RX_DESC_OWN(pdesc, 1);
break;
case HW_DESC_RXBUFF_ADDR:
SET_RX_DESC_BUFF_ADDR(pdesc, *(u32 *) val);
break;
case HW_DESC_RXPKT_LEN:
SET_RX_DESC_PKT_LEN(pdesc, *(u32 *) val);
break;
case HW_DESC_RXERO:
SET_RX_DESC_EOR(pdesc, 1);
break;
default:
RT_ASSERT(false, "ERR rxdesc :%d not process\n",
desc_name);
break;
}
}
}
u32 rtl92ce_get_desc(u8 *p_desc, bool istx, u8 desc_name)
{
u32 ret = 0;
if (istx) {
switch (desc_name) {
case HW_DESC_OWN:
ret = GET_TX_DESC_OWN(p_desc);
break;
case HW_DESC_TXBUFF_ADDR:
ret = GET_TX_DESC_TX_BUFFER_ADDRESS(p_desc);
break;
default:
RT_ASSERT(false, "ERR txdesc :%d not process\n",
desc_name);
break;
}
} else {
switch (desc_name) {
case HW_DESC_OWN:
ret = GET_RX_DESC_OWN(p_desc);
break;
case HW_DESC_RXPKT_LEN:
ret = GET_RX_DESC_PKT_LEN(p_desc);
break;
case HW_DESC_RXBUFF_ADDR:
ret = GET_RX_DESC_BUFF_ADDR(p_desc);
break;
default:
RT_ASSERT(false, "ERR rxdesc :%d not process\n",
desc_name);
break;
}
}
return ret;
}
bool rtl92ce_is_tx_desc_closed(struct ieee80211_hw *hw,
u8 hw_queue, u16 index)
{
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue];
u8 *entry = (u8 *)(&ring->desc[ring->idx]);
u8 own = (u8)rtl92ce_get_desc(entry, true, HW_DESC_OWN);
/*beacon packet will only use the first
*descriptor defautly,and the own may not
*be cleared by the hardware
*/
if (own)
return false;
return true;
}
void rtl92ce_tx_polling(struct ieee80211_hw *hw, u8 hw_queue)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
if (hw_queue == BEACON_QUEUE) {
rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4));
} else {
rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG,
BIT(0) << (hw_queue));
}
}

View file

@ -0,0 +1,732 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __RTL92CE_TRX_H__
#define __RTL92CE_TRX_H__
#define TX_DESC_SIZE 64
#define TX_DESC_AGGR_SUBFRAME_SIZE 32
#define RX_DESC_SIZE 32
#define RX_DRV_INFO_SIZE_UNIT 8
#define TX_DESC_NEXT_DESC_OFFSET 40
#define USB_HWDESC_HEADER_LEN 32
#define CRCLENGTH 4
/* Define a macro that takes a le32 word, converts it to host ordering,
* right shifts by a specified count, creates a mask of the specified
* bit count, and extracts that number of bits.
*/
#define SHIFT_AND_MASK_LE(__pdesc, __shift, __mask) \
((le32_to_cpu(*(((__le32 *)(__pdesc)))) >> (__shift)) & \
BIT_LEN_MASK_32(__mask))
/* Define a macro that clears a bit field in an le32 word and
* sets the specified value into that bit field. The resulting
* value remains in le32 ordering; however, it is properly converted
* to host ordering for the clear and set operations before conversion
* back to le32.
*/
#define SET_BITS_OFFSET_LE(__pdesc, __shift, __len, __val) \
(*(__le32 *)(__pdesc) = \
(cpu_to_le32((le32_to_cpu(*((__le32 *)(__pdesc))) & \
(~(BIT_OFFSET_LEN_MASK_32((__shift), __len)))) | \
(((u32)(__val) & BIT_LEN_MASK_32(__len)) << (__shift)))));
/* macros to read/write various fields in RX or TX descriptors */
#define SET_TX_DESC_PKT_SIZE(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc, 0, 16, __val)
#define SET_TX_DESC_OFFSET(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc, 16, 8, __val)
#define SET_TX_DESC_BMC(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc, 24, 1, __val)
#define SET_TX_DESC_HTC(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc, 25, 1, __val)
#define SET_TX_DESC_LAST_SEG(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc, 26, 1, __val)
#define SET_TX_DESC_FIRST_SEG(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc, 27, 1, __val)
#define SET_TX_DESC_LINIP(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc, 28, 1, __val)
#define SET_TX_DESC_NO_ACM(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc, 29, 1, __val)
#define SET_TX_DESC_GF(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc, 30, 1, __val)
#define SET_TX_DESC_OWN(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc, 31, 1, __val)
#define GET_TX_DESC_PKT_SIZE(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 0, 16)
#define GET_TX_DESC_OFFSET(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 16, 8)
#define GET_TX_DESC_BMC(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 24, 1)
#define GET_TX_DESC_HTC(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 25, 1)
#define GET_TX_DESC_LAST_SEG(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 26, 1)
#define GET_TX_DESC_FIRST_SEG(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 27, 1)
#define GET_TX_DESC_LINIP(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 28, 1)
#define GET_TX_DESC_NO_ACM(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 29, 1)
#define GET_TX_DESC_GF(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 30, 1)
#define GET_TX_DESC_OWN(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 31, 1)
#define SET_TX_DESC_MACID(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+4, 0, 5, __val)
#define SET_TX_DESC_AGG_BREAK(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+4, 5, 1, __val)
#define SET_TX_DESC_BK(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+4, 6, 1, __val)
#define SET_TX_DESC_RDG_ENABLE(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+4, 7, 1, __val)
#define SET_TX_DESC_QUEUE_SEL(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+4, 8, 5, __val)
#define SET_TX_DESC_RDG_NAV_EXT(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+4, 13, 1, __val)
#define SET_TX_DESC_LSIG_TXOP_EN(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+4, 14, 1, __val)
#define SET_TX_DESC_PIFS(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+4, 15, 1, __val)
#define SET_TX_DESC_RATE_ID(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+4, 16, 4, __val)
#define SET_TX_DESC_NAV_USE_HDR(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+4, 20, 1, __val)
#define SET_TX_DESC_EN_DESC_ID(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+4, 21, 1, __val)
#define SET_TX_DESC_SEC_TYPE(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+4, 22, 2, __val)
#define SET_TX_DESC_PKT_OFFSET(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+4, 24, 8, __val)
#define GET_TX_DESC_MACID(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 0, 5)
#define GET_TX_DESC_AGG_ENABLE(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 5, 1)
#define GET_TX_DESC_AGG_BREAK(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 6, 1)
#define GET_TX_DESC_RDG_ENABLE(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 7, 1)
#define GET_TX_DESC_QUEUE_SEL(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 8, 5)
#define GET_TX_DESC_RDG_NAV_EXT(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 13, 1)
#define GET_TX_DESC_LSIG_TXOP_EN(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 14, 1)
#define GET_TX_DESC_PIFS(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 15, 1)
#define GET_TX_DESC_RATE_ID(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 16, 4)
#define GET_TX_DESC_NAV_USE_HDR(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 20, 1)
#define GET_TX_DESC_EN_DESC_ID(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 21, 1)
#define GET_TX_DESC_SEC_TYPE(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 22, 2)
#define GET_TX_DESC_PKT_OFFSET(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 24, 8)
#define SET_TX_DESC_RTS_RC(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+8, 0, 6, __val)
#define SET_TX_DESC_DATA_RC(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+8, 6, 6, __val)
#define SET_TX_DESC_BAR_RTY_TH(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+8, 14, 2, __val)
#define SET_TX_DESC_MORE_FRAG(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+8, 17, 1, __val)
#define SET_TX_DESC_RAW(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+8, 18, 1, __val)
#define SET_TX_DESC_CCX(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+8, 19, 1, __val)
#define SET_TX_DESC_AMPDU_DENSITY(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+8, 20, 3, __val)
#define SET_TX_DESC_ANTSEL_A(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+8, 24, 1, __val)
#define SET_TX_DESC_ANTSEL_B(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+8, 25, 1, __val)
#define SET_TX_DESC_TX_ANT_CCK(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+8, 26, 2, __val)
#define SET_TX_DESC_TX_ANTL(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+8, 28, 2, __val)
#define SET_TX_DESC_TX_ANT_HT(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+8, 30, 2, __val)
#define GET_TX_DESC_RTS_RC(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+8, 0, 6)
#define GET_TX_DESC_DATA_RC(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+8, 6, 6)
#define GET_TX_DESC_BAR_RTY_TH(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+8, 14, 2)
#define GET_TX_DESC_MORE_FRAG(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+8, 17, 1)
#define GET_TX_DESC_RAW(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+8, 18, 1)
#define GET_TX_DESC_CCX(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+8, 19, 1)
#define GET_TX_DESC_AMPDU_DENSITY(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+8, 20, 3)
#define GET_TX_DESC_ANTSEL_A(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+8, 24, 1)
#define GET_TX_DESC_ANTSEL_B(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+8, 25, 1)
#define GET_TX_DESC_TX_ANT_CCK(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+8, 26, 2)
#define GET_TX_DESC_TX_ANTL(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+8, 28, 2)
#define GET_TX_DESC_TX_ANT_HT(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+8, 30, 2)
#define SET_TX_DESC_NEXT_HEAP_PAGE(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+12, 0, 8, __val)
#define SET_TX_DESC_TAIL_PAGE(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+12, 8, 8, __val)
#define SET_TX_DESC_SEQ(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+12, 16, 12, __val)
#define SET_TX_DESC_PKT_ID(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+12, 28, 4, __val)
#define GET_TX_DESC_NEXT_HEAP_PAGE(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+12, 0, 8)
#define GET_TX_DESC_TAIL_PAGE(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+12, 8, 8)
#define GET_TX_DESC_SEQ(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+12, 16, 12)
#define GET_TX_DESC_PKT_ID(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+12, 28, 4)
#define SET_TX_DESC_RTS_RATE(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 0, 5, __val)
#define SET_TX_DESC_AP_DCFE(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 5, 1, __val)
#define SET_TX_DESC_QOS(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 6, 1, __val)
#define SET_TX_DESC_HWSEQ_EN(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 7, 1, __val)
#define SET_TX_DESC_USE_RATE(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 8, 1, __val)
#define SET_TX_DESC_DISABLE_RTS_FB(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 9, 1, __val)
#define SET_TX_DESC_DISABLE_FB(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 10, 1, __val)
#define SET_TX_DESC_CTS2SELF(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 11, 1, __val)
#define SET_TX_DESC_RTS_ENABLE(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 12, 1, __val)
#define SET_TX_DESC_HW_RTS_ENABLE(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 13, 1, __val)
#define SET_TX_DESC_PORT_ID(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 14, 1, __val)
#define SET_TX_DESC_WAIT_DCTS(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 18, 1, __val)
#define SET_TX_DESC_CTS2AP_EN(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 19, 1, __val)
#define SET_TX_DESC_TX_SUB_CARRIER(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 20, 2, __val)
#define SET_TX_DESC_TX_STBC(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 22, 2, __val)
#define SET_TX_DESC_DATA_SHORT(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 24, 1, __val)
#define SET_TX_DESC_DATA_BW(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 25, 1, __val)
#define SET_TX_DESC_RTS_SHORT(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 26, 1, __val)
#define SET_TX_DESC_RTS_BW(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 27, 1, __val)
#define SET_TX_DESC_RTS_SC(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 28, 2, __val)
#define SET_TX_DESC_RTS_STBC(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+16, 30, 2, __val)
#define GET_TX_DESC_RTS_RATE(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 0, 5)
#define GET_TX_DESC_AP_DCFE(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 5, 1)
#define GET_TX_DESC_QOS(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 6, 1)
#define GET_TX_DESC_HWSEQ_EN(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 7, 1)
#define GET_TX_DESC_USE_RATE(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 8, 1)
#define GET_TX_DESC_DISABLE_RTS_FB(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 9, 1)
#define GET_TX_DESC_DISABLE_FB(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 10, 1)
#define GET_TX_DESC_CTS2SELF(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 11, 1)
#define GET_TX_DESC_RTS_ENABLE(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 12, 1)
#define GET_TX_DESC_HW_RTS_ENABLE(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 13, 1)
#define GET_TX_DESC_PORT_ID(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 14, 1)
#define GET_TX_DESC_WAIT_DCTS(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 18, 1)
#define GET_TX_DESC_CTS2AP_EN(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 19, 1)
#define GET_TX_DESC_TX_SUB_CARRIER(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 20, 2)
#define GET_TX_DESC_TX_STBC(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 22, 2)
#define GET_TX_DESC_DATA_SHORT(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 24, 1)
#define GET_TX_DESC_DATA_BW(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 25, 1)
#define GET_TX_DESC_RTS_SHORT(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 26, 1)
#define GET_TX_DESC_RTS_BW(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 27, 1)
#define GET_TX_DESC_RTS_SC(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 28, 2)
#define GET_TX_DESC_RTS_STBC(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 30, 2)
#define SET_TX_DESC_TX_RATE(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+20, 0, 6, __val)
#define SET_TX_DESC_DATA_SHORTGI(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+20, 6, 1, __val)
#define SET_TX_DESC_CCX_TAG(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+20, 7, 1, __val)
#define SET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+20, 8, 5, __val)
#define SET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+20, 13, 4, __val)
#define SET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+20, 17, 1, __val)
#define SET_TX_DESC_DATA_RETRY_LIMIT(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+20, 18, 6, __val)
#define SET_TX_DESC_USB_TXAGG_NUM(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+20, 24, 8, __val)
#define GET_TX_DESC_TX_RATE(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+20, 0, 6)
#define GET_TX_DESC_DATA_SHORTGI(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+20, 6, 1)
#define GET_TX_DESC_CCX_TAG(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+20, 7, 1)
#define GET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+20, 8, 5)
#define GET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+20, 13, 4)
#define GET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+20, 17, 1)
#define GET_TX_DESC_DATA_RETRY_LIMIT(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+20, 18, 6)
#define GET_TX_DESC_USB_TXAGG_NUM(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+20, 24, 8)
#define SET_TX_DESC_TXAGC_A(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+24, 0, 5, __val)
#define SET_TX_DESC_TXAGC_B(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+24, 5, 5, __val)
#define SET_TX_DESC_USE_MAX_LEN(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+24, 10, 1, __val)
#define SET_TX_DESC_MAX_AGG_NUM(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+24, 11, 5, __val)
#define SET_TX_DESC_MCSG1_MAX_LEN(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+24, 16, 4, __val)
#define SET_TX_DESC_MCSG2_MAX_LEN(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+24, 20, 4, __val)
#define SET_TX_DESC_MCSG3_MAX_LEN(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+24, 24, 4, __val)
#define SET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+24, 28, 4, __val)
#define GET_TX_DESC_TXAGC_A(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+24, 0, 5)
#define GET_TX_DESC_TXAGC_B(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+24, 5, 5)
#define GET_TX_DESC_USE_MAX_LEN(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+24, 10, 1)
#define GET_TX_DESC_MAX_AGG_NUM(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+24, 11, 5)
#define GET_TX_DESC_MCSG1_MAX_LEN(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+24, 16, 4)
#define GET_TX_DESC_MCSG2_MAX_LEN(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+24, 20, 4)
#define GET_TX_DESC_MCSG3_MAX_LEN(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+24, 24, 4)
#define GET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+24, 28, 4)
#define SET_TX_DESC_TX_BUFFER_SIZE(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+28, 0, 16, __val)
#define SET_TX_DESC_MCSG4_MAX_LEN(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+28, 16, 4, __val)
#define SET_TX_DESC_MCSG5_MAX_LEN(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+28, 20, 4, __val)
#define SET_TX_DESC_MCSG6_MAX_LEN(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+28, 24, 4, __val)
#define SET_TX_DESC_MCS15_SGI_MAX_LEN(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+28, 28, 4, __val)
#define GET_TX_DESC_TX_BUFFER_SIZE(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+28, 0, 16)
#define GET_TX_DESC_MCSG4_MAX_LEN(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+28, 16, 4)
#define GET_TX_DESC_MCSG5_MAX_LEN(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+28, 20, 4)
#define GET_TX_DESC_MCSG6_MAX_LEN(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+28, 24, 4)
#define GET_TX_DESC_MCS15_SGI_MAX_LEN(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+28, 28, 4)
#define SET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+32, 0, 32, __val)
#define SET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+36, 0, 32, __val)
#define GET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+32, 0, 32)
#define GET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+36, 0, 32)
#define SET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+40, 0, 32, __val)
#define SET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+44, 0, 32, __val)
#define GET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+40, 0, 32)
#define GET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+44, 0, 32)
#define GET_RX_DESC_PKT_LEN(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 0, 14)
#define GET_RX_DESC_CRC32(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 14, 1)
#define GET_RX_DESC_ICV(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 15, 1)
#define GET_RX_DESC_DRV_INFO_SIZE(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 16, 4)
#define GET_RX_DESC_SECURITY(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 20, 3)
#define GET_RX_DESC_QOS(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 23, 1)
#define GET_RX_DESC_SHIFT(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 24, 2)
#define GET_RX_DESC_PHYST(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 26, 1)
#define GET_RX_DESC_SWDEC(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 27, 1)
#define GET_RX_DESC_LS(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 28, 1)
#define GET_RX_DESC_FS(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 29, 1)
#define GET_RX_DESC_EOR(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 30, 1)
#define GET_RX_DESC_OWN(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc, 31, 1)
#define SET_RX_DESC_PKT_LEN(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc, 0, 14, __val)
#define SET_RX_DESC_EOR(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc, 30, 1, __val)
#define SET_RX_DESC_OWN(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc, 31, 1, __val)
#define GET_RX_DESC_MACID(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 0, 5)
#define GET_RX_DESC_TID(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 5, 4)
#define GET_RX_DESC_HWRSVD(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 9, 5)
#define GET_RX_DESC_PAGGR(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 14, 1)
#define GET_RX_DESC_FAGGR(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 15, 1)
#define GET_RX_DESC_A1_FIT(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 16, 4)
#define GET_RX_DESC_A2_FIT(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 20, 4)
#define GET_RX_DESC_PAM(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 24, 1)
#define GET_RX_DESC_PWR(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 25, 1)
#define GET_RX_DESC_MD(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 26, 1)
#define GET_RX_DESC_MF(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 27, 1)
#define GET_RX_DESC_TYPE(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 28, 2)
#define GET_RX_DESC_MC(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 30, 1)
#define GET_RX_DESC_BC(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+4, 31, 1)
#define GET_RX_DESC_SEQ(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+8, 0, 12)
#define GET_RX_DESC_FRAG(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+8, 12, 4)
#define GET_RX_DESC_NEXT_PKT_LEN(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+8, 16, 14)
#define GET_RX_DESC_NEXT_IND(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+8, 30, 1)
#define GET_RX_DESC_RSVD(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+8, 31, 1)
#define GET_RX_DESC_RXMCS(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+12, 0, 6)
#define GET_RX_DESC_RXHT(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+12, 6, 1)
#define GET_RX_DESC_SPLCP(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+12, 8, 1)
#define GET_RX_DESC_BW(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+12, 9, 1)
#define GET_RX_DESC_HTC(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+12, 10, 1)
#define GET_RX_DESC_HWPC_ERR(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+12, 14, 1)
#define GET_RX_DESC_HWPC_IND(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+12, 15, 1)
#define GET_RX_DESC_IV0(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+12, 16, 16)
#define GET_RX_DESC_IV1(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+16, 0, 32)
#define GET_RX_DESC_TSFL(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+20, 0, 32)
#define GET_RX_DESC_BUFF_ADDR(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+24, 0, 32)
#define GET_RX_DESC_BUFF_ADDR64(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc+28, 0, 32)
#define SET_RX_DESC_BUFF_ADDR(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+24, 0, 32, __val)
#define SET_RX_DESC_BUFF_ADDR64(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+28, 0, 32, __val)
#define CLEAR_PCI_TX_DESC_CONTENT(__pdesc, _size) \
memset(__pdesc, 0, min_t(size_t, _size, TX_DESC_NEXT_DESC_OFFSET))
struct rx_fwinfo_92c {
u8 gain_trsw[4];
u8 pwdb_all;
u8 cfosho[4];
u8 cfotail[4];
char rxevm[2];
char rxsnr[4];
u8 pdsnr[2];
u8 csi_current[2];
u8 csi_target[2];
u8 sigevm;
u8 max_ex_pwr;
u8 ex_intf_flag:1;
u8 sgi_en:1;
u8 rxsc:2;
u8 reserve:4;
} __packed;
struct tx_desc_92c {
u32 pktsize:16;
u32 offset:8;
u32 bmc:1;
u32 htc:1;
u32 lastseg:1;
u32 firstseg:1;
u32 linip:1;
u32 noacm:1;
u32 gf:1;
u32 own:1;
u32 macid:5;
u32 agg_en:1;
u32 bk:1;
u32 rdg_en:1;
u32 queuesel:5;
u32 rd_nav_ext:1;
u32 lsig_txop_en:1;
u32 pifs:1;
u32 rateid:4;
u32 nav_usehdr:1;
u32 en_descid:1;
u32 sectype:2;
u32 pktoffset:8;
u32 rts_rc:6;
u32 data_rc:6;
u32 rsvd0:2;
u32 bar_retryht:2;
u32 rsvd1:1;
u32 morefrag:1;
u32 raw:1;
u32 ccx:1;
u32 ampdudensity:3;
u32 rsvd2:1;
u32 ant_sela:1;
u32 ant_selb:1;
u32 txant_cck:2;
u32 txant_l:2;
u32 txant_ht:2;
u32 nextheadpage:8;
u32 tailpage:8;
u32 seq:12;
u32 pktid:4;
u32 rtsrate:5;
u32 apdcfe:1;
u32 qos:1;
u32 hwseq_enable:1;
u32 userrate:1;
u32 dis_rtsfb:1;
u32 dis_datafb:1;
u32 cts2self:1;
u32 rts_en:1;
u32 hwrts_en:1;
u32 portid:1;
u32 rsvd3:3;
u32 waitdcts:1;
u32 cts2ap_en:1;
u32 txsc:2;
u32 stbc:2;
u32 txshort:1;
u32 txbw:1;
u32 rtsshort:1;
u32 rtsbw:1;
u32 rtssc:2;
u32 rtsstbc:2;
u32 txrate:6;
u32 shortgi:1;
u32 ccxt:1;
u32 txrate_fb_lmt:5;
u32 rtsrate_fb_lmt:4;
u32 retrylmt_en:1;
u32 txretrylmt:6;
u32 usb_txaggnum:8;
u32 txagca:5;
u32 txagcb:5;
u32 usemaxlen:1;
u32 maxaggnum:5;
u32 mcsg1maxlen:4;
u32 mcsg2maxlen:4;
u32 mcsg3maxlen:4;
u32 mcs7sgimaxlen:4;
u32 txbuffersize:16;
u32 mcsg4maxlen:4;
u32 mcsg5maxlen:4;
u32 mcsg6maxlen:4;
u32 mcsg15sgimaxlen:4;
u32 txbuffaddr;
u32 txbufferaddr64;
u32 nextdescaddress;
u32 nextdescaddress64;
u32 reserve_pass_pcie_mm_limit[4];
} __packed;
struct rx_desc_92c {
u32 length:14;
u32 crc32:1;
u32 icverror:1;
u32 drv_infosize:4;
u32 security:3;
u32 qos:1;
u32 shift:2;
u32 phystatus:1;
u32 swdec:1;
u32 lastseg:1;
u32 firstseg:1;
u32 eor:1;
u32 own:1;
u32 macid:5;
u32 tid:4;
u32 hwrsvd:5;
u32 paggr:1;
u32 faggr:1;
u32 a1_fit:4;
u32 a2_fit:4;
u32 pam:1;
u32 pwr:1;
u32 moredata:1;
u32 morefrag:1;
u32 type:2;
u32 mc:1;
u32 bc:1;
u32 seq:12;
u32 frag:4;
u32 nextpktlen:14;
u32 nextind:1;
u32 rsvd:1;
u32 rxmcs:6;
u32 rxht:1;
u32 amsdu:1;
u32 splcp:1;
u32 bandwidth:1;
u32 htc:1;
u32 tcpchk_rpt:1;
u32 ipcchk_rpt:1;
u32 tcpchk_valid:1;
u32 hwpcerr:1;
u32 hwpcind:1;
u32 iv0:16;
u32 iv1;
u32 tsfl;
u32 bufferaddress;
u32 bufferaddress64;
} __packed;
void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
struct ieee80211_hdr *hdr, u8 *pdesc,
u8 *pbd_desc_tx, struct ieee80211_tx_info *info,
struct ieee80211_sta *sta,
struct sk_buff *skb, u8 hw_queue,
struct rtl_tcb_desc *ptcb_desc);
bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,
struct rtl_stats *stats,
struct ieee80211_rx_status *rx_status,
u8 *pdesc, struct sk_buff *skb);
void rtl92ce_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx,
u8 desc_name, u8 *val);
u32 rtl92ce_get_desc(u8 *pdesc, bool istx, u8 desc_name);
bool rtl92ce_is_tx_desc_closed(struct ieee80211_hw *hw,
u8 hw_queue, u16 index);
void rtl92ce_tx_polling(struct ieee80211_hw *hw, u8 hw_queue);
void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
bool b_firstseg, bool b_lastseg,
struct sk_buff *skb);
#endif

View file

@ -0,0 +1,14 @@
rtl8192cu-objs := \
dm.o \
hw.o \
led.o \
mac.o \
phy.o \
rf.o \
sw.o \
table.o \
trx.o
obj-$(CONFIG_RTL8192CU) += rtl8192cu.o
ccflags-y += -D__CHECK_ENDIAN__

View file

@ -0,0 +1,55 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "../rtl8192ce/def.h"
/*-------------------------------------------------------------------------
* Chip specific
*-------------------------------------------------------------------------*/
#define CHIP_8723 BIT(2) /* RTL8723 With BT feature */
#define CHIP_8723_DRV_REV BIT(3) /* RTL8723 Driver Revised */
#define NORMAL_CHIP BIT(4)
#define CHIP_VENDOR_UMC BIT(5)
#define CHIP_VENDOR_UMC_B_CUT BIT(6)
#define IS_8723_SERIES(version) \
(((version) & CHIP_8723) ? true : false)
#define IS_92C_1T2R(version) \
(((version) & CHIP_92C) && ((version) & CHIP_92C_1T2R))
#define IS_VENDOR_UMC(version) \
(((version) & CHIP_VENDOR_UMC) ? true : false)
#define IS_VENDOR_8723_A_CUT(version) \
(((version) & CHIP_VENDOR_UMC) ? (((version) & (BIT(6))) ? \
false : true) : false)
#define CHIP_BONDING_92C_1T2R 0x1
#define CHIP_BONDING_IDENTIFIER(_value) (((_value) >> 22) & 0x3)

View file

@ -0,0 +1,116 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "../wifi.h"
#include "../base.h"
#include "reg.h"
#include "def.h"
#include "phy.h"
#include "dm.h"
void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
long undec_sm_pwdb;
if (!rtlpriv->dm.dynamic_txpower_enable)
return;
if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) {
rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
return;
}
if ((mac->link_state < MAC80211_LINKED) &&
(rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
"Not connected to any\n");
rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
return;
}
if (mac->link_state >= MAC80211_LINKED) {
if (mac->opmode == NL80211_IFTYPE_ADHOC) {
undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb;
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
"AP Client PWDB = 0x%lx\n",
undec_sm_pwdb);
} else {
undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb;
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
"STA Default Port PWDB = 0x%lx\n",
undec_sm_pwdb);
}
} else {
undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb;
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
"AP Ext Port PWDB = 0x%lx\n",
undec_sm_pwdb);
}
if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) {
rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
"TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n");
} else if ((undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) &&
(undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL1)) {
rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
"TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n");
} else if (undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) {
rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
"TXHIGHPWRLEVEL_NORMAL\n");
}
if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) {
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
"PHY_SetTxPowerLevel8192S() Channel = %d\n",
rtlphy->current_channel);
rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel);
if (rtlpriv->dm.dynamic_txhighpower_lvl ==
TXHIGHPWRLEVEL_NORMAL)
dm_restorepowerindex(hw);
else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
TXHIGHPWRLEVEL_LEVEL1)
dm_writepowerindex(hw, 0x14);
else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
TXHIGHPWRLEVEL_LEVEL2)
dm_writepowerindex(hw, 0x10);
}
rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
}

View file

@ -0,0 +1,35 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "../rtl8192ce/dm.h"
void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw);
void dm_savepowerindex(struct ieee80211_hw *hw);
void dm_writepowerindex(struct ieee80211_hw *hw, u8 value);
void dm_restorepowerindex(struct ieee80211_hw *hw);

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,115 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __RTL92CU_HW_H__
#define __RTL92CU_HW_H__
#define H2C_RA_MASK 6
#define LLT_POLLING_LLT_THRESHOLD 20
#define LLT_POLLING_READY_TIMEOUT_COUNT 100
#define LLT_LAST_ENTRY_OF_TX_PKT_BUFFER 255
#define RX_PAGE_SIZE_REG_VALUE PBP_128
/* Note: We will divide number of page equally for each queue
* other than public queue! */
#define TX_TOTAL_PAGE_NUMBER 0xF8
#define TX_PAGE_BOUNDARY (TX_TOTAL_PAGE_NUMBER + 1)
#define CHIP_B_PAGE_NUM_PUBQ 0xE7
/* For Test Chip Setting
* (HPQ + LPQ + PUBQ) shall be TX_TOTAL_PAGE_NUMBER */
#define CHIP_A_PAGE_NUM_PUBQ 0x7E
/* For Chip A Setting */
#define WMM_CHIP_A_TX_TOTAL_PAGE_NUMBER 0xF5
#define WMM_CHIP_A_TX_PAGE_BOUNDARY \
(WMM_CHIP_A_TX_TOTAL_PAGE_NUMBER + 1) /* F6 */
#define WMM_CHIP_A_PAGE_NUM_PUBQ 0xA3
#define WMM_CHIP_A_PAGE_NUM_HPQ 0x29
#define WMM_CHIP_A_PAGE_NUM_LPQ 0x29
/* Note: For Chip B Setting ,modify later */
#define WMM_CHIP_B_TX_TOTAL_PAGE_NUMBER 0xF5
#define WMM_CHIP_B_TX_PAGE_BOUNDARY \
(WMM_CHIP_B_TX_TOTAL_PAGE_NUMBER + 1) /* F6 */
#define WMM_CHIP_B_PAGE_NUM_PUBQ 0xB0
#define WMM_CHIP_B_PAGE_NUM_HPQ 0x29
#define WMM_CHIP_B_PAGE_NUM_LPQ 0x1C
#define WMM_CHIP_B_PAGE_NUM_NPQ 0x1C
#define BOARD_TYPE_NORMAL_MASK 0xE0
#define BOARD_TYPE_TEST_MASK 0x0F
/* should be renamed and moved to another file */
enum _BOARD_TYPE_8192CUSB {
BOARD_USB_DONGLE = 0, /* USB dongle */
BOARD_USB_High_PA = 1, /* USB dongle - high power PA */
BOARD_MINICARD = 2, /* Minicard */
BOARD_USB_SOLO = 3, /* USB solo-Slim module */
BOARD_USB_COMBO = 4, /* USB Combo-Slim module */
};
#define IS_HIGHT_PA(boardtype) \
((boardtype == BOARD_USB_High_PA) ? true : false)
#define RTL92C_DRIVER_INFO_SIZE 4
void rtl92cu_read_eeprom_info(struct ieee80211_hw *hw);
void rtl92cu_enable_hw_security_config(struct ieee80211_hw *hw);
int rtl92cu_hw_init(struct ieee80211_hw *hw);
void rtl92cu_card_disable(struct ieee80211_hw *hw);
int rtl92cu_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type);
void rtl92cu_set_beacon_related_registers(struct ieee80211_hw *hw);
void rtl92cu_set_beacon_interval(struct ieee80211_hw *hw);
void rtl92cu_update_interrupt_mask(struct ieee80211_hw *hw,
u32 add_msr, u32 rm_msr);
void rtl92cu_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
void rtl92cu_update_channel_access_setting(struct ieee80211_hw *hw);
bool rtl92cu_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid);
void rtl92cu_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid);
int rtl92c_download_fw(struct ieee80211_hw *hw);
void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode);
void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus);
void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw,
u8 element_id, u32 cmd_len, u8 *p_cmdbuffer);
bool rtl92cu_phy_mac_config(struct ieee80211_hw *hw);
void rtl92cu_update_hal_rate_tbl(struct ieee80211_hw *hw,
struct ieee80211_sta *sta,
u8 rssi_level);
#endif

View file

@ -0,0 +1,141 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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
*
* 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.
*
*****************************************************************************/
#include "../wifi.h"
#include "../usb.h"
#include "reg.h"
#include "led.h"
static void _rtl92cu_init_led(struct ieee80211_hw *hw,
struct rtl_led *pled, enum rtl_led_pin ledpin)
{
pled->hw = hw;
pled->ledpin = ledpin;
pled->ledon = false;
}
static void _rtl92cu_deInit_led(struct rtl_led *pled)
{
}
void rtl92cu_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
{
u8 ledcfg;
struct rtl_priv *rtlpriv = rtl_priv(hw);
RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n",
REG_LEDCFG2, pled->ledpin);
ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
switch (pled->ledpin) {
case LED_PIN_GPIO0:
break;
case LED_PIN_LED0:
rtl_write_byte(rtlpriv,
REG_LEDCFG2, (ledcfg & 0xf0) | BIT(5) | BIT(6));
break;
case LED_PIN_LED1:
rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0x0f) | BIT(5));
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"switch case not processed\n");
break;
}
pled->ledon = true;
}
void rtl92cu_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_usb_priv *usbpriv = rtl_usbpriv(hw);
u8 ledcfg;
RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n",
REG_LEDCFG2, pled->ledpin);
ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
switch (pled->ledpin) {
case LED_PIN_GPIO0:
break;
case LED_PIN_LED0:
ledcfg &= 0xf0;
if (usbpriv->ledctl.led_opendrain)
rtl_write_byte(rtlpriv, REG_LEDCFG2,
(ledcfg | BIT(1) | BIT(5) | BIT(6)));
else
rtl_write_byte(rtlpriv, REG_LEDCFG2,
(ledcfg | BIT(3) | BIT(5) | BIT(6)));
break;
case LED_PIN_LED1:
ledcfg &= 0x0f;
rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg | BIT(3)));
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"switch case not processed\n");
break;
}
pled->ledon = false;
}
void rtl92cu_init_sw_leds(struct ieee80211_hw *hw)
{
struct rtl_usb_priv *usbpriv = rtl_usbpriv(hw);
_rtl92cu_init_led(hw, &(usbpriv->ledctl.sw_led0), LED_PIN_LED0);
_rtl92cu_init_led(hw, &(usbpriv->ledctl.sw_led1), LED_PIN_LED1);
}
void rtl92cu_deinit_sw_leds(struct ieee80211_hw *hw)
{
struct rtl_usb_priv *usbpriv = rtl_usbpriv(hw);
_rtl92cu_deInit_led(&(usbpriv->ledctl.sw_led0));
_rtl92cu_deInit_led(&(usbpriv->ledctl.sw_led1));
}
static void _rtl92cu_sw_led_control(struct ieee80211_hw *hw,
enum led_ctl_mode ledaction)
{
}
void rtl92cu_led_control(struct ieee80211_hw *hw,
enum led_ctl_mode ledaction)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) &&
(ledaction == LED_CTL_TX ||
ledaction == LED_CTL_RX ||
ledaction == LED_CTL_SITE_SURVEY ||
ledaction == LED_CTL_LINK ||
ledaction == LED_CTL_NO_LINK ||
ledaction == LED_CTL_START_TO_LINK ||
ledaction == LED_CTL_POWER_ON)) {
return;
}
RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d\n", ledaction);
_rtl92cu_sw_led_control(hw, ledaction);
}

View file

@ -0,0 +1,37 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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
*
* 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.
*
*****************************************************************************/
#ifndef __RTL92CU_LED_H__
#define __RTL92CU_LED_H__
void rtl92cu_init_sw_leds(struct ieee80211_hw *hw);
void rtl92cu_deinit_sw_leds(struct ieee80211_hw *hw);
void rtl92cu_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled);
void rtl92cu_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled);
void rtl92cu_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction);
#endif

View file

@ -0,0 +1,945 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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
*
* 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 "../wifi.h"
#include "../pci.h"
#include "../usb.h"
#include "../ps.h"
#include "../cam.h"
#include "../stats.h"
#include "reg.h"
#include "def.h"
#include "phy.h"
#include "rf.h"
#include "dm.h"
#include "mac.h"
#include "trx.h"
#include "../rtl8192c/fw_common.h"
#include <linux/module.h>
/* macro to shorten lines */
#define LINK_Q ui_link_quality
#define RX_EVM rx_evm_percentage
#define RX_SIGQ rx_mimo_sig_qual
void rtl92c_read_chip_version(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
enum version_8192c chip_version = VERSION_UNKNOWN;
const char *versionid;
u32 value32;
value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG);
if (value32 & TRP_VAUX_EN) {
chip_version = (value32 & TYPE_ID) ? VERSION_TEST_CHIP_92C :
VERSION_TEST_CHIP_88C;
} else {
/* Normal mass production chip. */
chip_version = NORMAL_CHIP;
chip_version |= ((value32 & TYPE_ID) ? CHIP_92C : 0);
chip_version |= ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : 0);
/* RTL8723 with BT function. */
chip_version |= ((value32 & BT_FUNC) ? CHIP_8723 : 0);
if (IS_VENDOR_UMC(chip_version))
chip_version |= ((value32 & CHIP_VER_RTL_MASK) ?
CHIP_VENDOR_UMC_B_CUT : 0);
if (IS_92C_SERIAL(chip_version)) {
value32 = rtl_read_dword(rtlpriv, REG_HPON_FSM);
chip_version |= ((CHIP_BONDING_IDENTIFIER(value32) ==
CHIP_BONDING_92C_1T2R) ? CHIP_92C_1T2R : 0);
} else if (IS_8723_SERIES(chip_version)) {
value32 = rtl_read_dword(rtlpriv, REG_GPIO_OUTSTS);
chip_version |= ((value32 & RF_RL_ID) ?
CHIP_8723_DRV_REV : 0);
}
}
rtlhal->version = (enum version_8192c)chip_version;
pr_info("Chip version 0x%x\n", chip_version);
switch (rtlhal->version) {
case VERSION_NORMAL_TSMC_CHIP_92C_1T2R:
versionid = "NORMAL_B_CHIP_92C";
break;
case VERSION_NORMAL_TSMC_CHIP_92C:
versionid = "NORMAL_TSMC_CHIP_92C";
break;
case VERSION_NORMAL_TSMC_CHIP_88C:
versionid = "NORMAL_TSMC_CHIP_88C";
break;
case VERSION_NORMAL_UMC_CHIP_92C_1T2R_A_CUT:
versionid = "NORMAL_UMC_CHIP_i92C_1T2R_A_CUT";
break;
case VERSION_NORMAL_UMC_CHIP_92C_A_CUT:
versionid = "NORMAL_UMC_CHIP_92C_A_CUT";
break;
case VERSION_NORMAL_UMC_CHIP_88C_A_CUT:
versionid = "NORMAL_UMC_CHIP_88C_A_CUT";
break;
case VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT:
versionid = "NORMAL_UMC_CHIP_92C_1T2R_B_CUT";
break;
case VERSION_NORMAL_UMC_CHIP_92C_B_CUT:
versionid = "NORMAL_UMC_CHIP_92C_B_CUT";
break;
case VERSION_NORMAL_UMC_CHIP_88C_B_CUT:
versionid = "NORMAL_UMC_CHIP_88C_B_CUT";
break;
case VERSION_NORMA_UMC_CHIP_8723_1T1R_A_CUT:
versionid = "NORMAL_UMC_CHIP_8723_1T1R_A_CUT";
break;
case VERSION_NORMA_UMC_CHIP_8723_1T1R_B_CUT:
versionid = "NORMAL_UMC_CHIP_8723_1T1R_B_CUT";
break;
case VERSION_TEST_CHIP_92C:
versionid = "TEST_CHIP_92C";
break;
case VERSION_TEST_CHIP_88C:
versionid = "TEST_CHIP_88C";
break;
default:
versionid = "UNKNOWN";
break;
}
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
"Chip Version ID: %s\n", versionid);
if (IS_92C_SERIAL(rtlhal->version))
rtlphy->rf_type =
(IS_92C_1T2R(rtlhal->version)) ? RF_1T2R : RF_2T2R;
else
rtlphy->rf_type = RF_1T1R;
RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
"Chip RF Type: %s\n",
rtlphy->rf_type == RF_2T2R ? "RF_2T2R" : "RF_1T1R");
if (get_rf_type(rtlphy) == RF_1T1R)
rtlpriv->dm.rfpath_rxenable[0] = true;
else
rtlpriv->dm.rfpath_rxenable[0] =
rtlpriv->dm.rfpath_rxenable[1] = true;
RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n",
rtlhal->version);
}
/**
* writeLLT - LLT table write access
* @io: io callback
* @address: LLT logical address.
* @data: LLT data content
*
* Realtek hardware access function.
*
*/
bool rtl92c_llt_write(struct ieee80211_hw *hw, u32 address, u32 data)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
bool status = true;
long count = 0;
u32 value = _LLT_INIT_ADDR(address) |
_LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS);
rtl_write_dword(rtlpriv, REG_LLT_INIT, value);
do {
value = rtl_read_dword(rtlpriv, REG_LLT_INIT);
if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
break;
if (count > POLLING_LLT_THRESHOLD) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"Failed to polling write LLT done at address %d! _LLT_OP_VALUE(%x)\n",
address, _LLT_OP_VALUE(value));
status = false;
break;
}
} while (++count);
return status;
}
/**
* rtl92c_init_LLT_table - Init LLT table
* @io: io callback
* @boundary:
*
* Realtek hardware access function.
*
*/
bool rtl92c_init_llt_table(struct ieee80211_hw *hw, u32 boundary)
{
bool rst = true;
u32 i;
for (i = 0; i < (boundary - 1); i++) {
rst = rtl92c_llt_write(hw, i , i + 1);
if (true != rst) {
pr_err("===> %s #1 fail\n", __func__);
return rst;
}
}
/* end of list */
rst = rtl92c_llt_write(hw, (boundary - 1), 0xFF);
if (true != rst) {
pr_err("===> %s #2 fail\n", __func__);
return rst;
}
/* Make the other pages as ring buffer
* This ring buffer is used as beacon buffer if we config this MAC
* as two MAC transfer.
* Otherwise used as local loopback buffer.
*/
for (i = boundary; i < LLT_LAST_ENTRY_OF_TX_PKT_BUFFER; i++) {
rst = rtl92c_llt_write(hw, i, (i + 1));
if (true != rst) {
pr_err("===> %s #3 fail\n", __func__);
return rst;
}
}
/* Let last entry point to the start entry of ring buffer */
rst = rtl92c_llt_write(hw, LLT_LAST_ENTRY_OF_TX_PKT_BUFFER, boundary);
if (true != rst) {
pr_err("===> %s #4 fail\n", __func__);
return rst;
}
return rst;
}
void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index,
u8 *p_macaddr, bool is_group, u8 enc_algo,
bool is_wepkey, bool clear_all)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
u8 *macaddr = p_macaddr;
u32 entry_id = 0;
bool is_pairwise = false;
static u8 cam_const_addr[4][6] = {
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x03}
};
static u8 cam_const_broad[] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};
if (clear_all) {
u8 idx = 0;
u8 cam_offset = 0;
u8 clear_number = 5;
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n");
for (idx = 0; idx < clear_number; idx++) {
rtl_cam_mark_invalid(hw, cam_offset + idx);
rtl_cam_empty_entry(hw, cam_offset + idx);
if (idx < 5) {
memset(rtlpriv->sec.key_buf[idx], 0,
MAX_KEY_LEN);
rtlpriv->sec.key_len[idx] = 0;
}
}
} else {
switch (enc_algo) {
case WEP40_ENCRYPTION:
enc_algo = CAM_WEP40;
break;
case WEP104_ENCRYPTION:
enc_algo = CAM_WEP104;
break;
case TKIP_ENCRYPTION:
enc_algo = CAM_TKIP;
break;
case AESCCMP_ENCRYPTION:
enc_algo = CAM_AES;
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"illegal switch case\n");
enc_algo = CAM_TKIP;
break;
}
if (is_wepkey || rtlpriv->sec.use_defaultkey) {
macaddr = cam_const_addr[key_index];
entry_id = key_index;
} else {
if (is_group) {
macaddr = cam_const_broad;
entry_id = key_index;
} else {
if (mac->opmode == NL80211_IFTYPE_AP ||
mac->opmode == NL80211_IFTYPE_MESH_POINT) {
entry_id = rtl_cam_get_free_entry(hw,
p_macaddr);
if (entry_id >= TOTAL_CAM_ENTRY) {
RT_TRACE(rtlpriv, COMP_SEC,
DBG_EMERG,
"Can not find free hw security cam entry\n");
return;
}
} else {
entry_id = CAM_PAIRWISE_KEY_POSITION;
}
key_index = PAIRWISE_KEYIDX;
is_pairwise = true;
}
}
if (rtlpriv->sec.key_len[key_index] == 0) {
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
"delete one entry\n");
if (mac->opmode == NL80211_IFTYPE_AP ||
mac->opmode == NL80211_IFTYPE_MESH_POINT)
rtl_cam_del_entry(hw, p_macaddr);
rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
} else {
RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
"The insert KEY length is %d\n",
rtlpriv->sec.key_len[PAIRWISE_KEYIDX]);
RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
"The insert KEY is %x %x\n",
rtlpriv->sec.key_buf[0][0],
rtlpriv->sec.key_buf[0][1]);
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
"add one entry\n");
if (is_pairwise) {
RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD,
"Pairwise Key content",
rtlpriv->sec.pairwise_key,
rtlpriv->sec.
key_len[PAIRWISE_KEYIDX]);
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
"set Pairwise key\n");
rtl_cam_add_one_entry(hw, macaddr, key_index,
entry_id, enc_algo,
CAM_CONFIG_NO_USEDK,
rtlpriv->sec.
key_buf[key_index]);
} else {
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
"set group key\n");
if (mac->opmode == NL80211_IFTYPE_ADHOC) {
rtl_cam_add_one_entry(hw,
rtlefuse->dev_addr,
PAIRWISE_KEYIDX,
CAM_PAIRWISE_KEY_POSITION,
enc_algo,
CAM_CONFIG_NO_USEDK,
rtlpriv->sec.key_buf
[entry_id]);
}
rtl_cam_add_one_entry(hw, macaddr, key_index,
entry_id, enc_algo,
CAM_CONFIG_NO_USEDK,
rtlpriv->sec.key_buf[entry_id]);
}
}
}
}
u32 rtl92c_get_txdma_status(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
return rtl_read_dword(rtlpriv, REG_TXDMA_STATUS);
}
void rtl92c_enable_interrupt(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw));
if (IS_HARDWARE_TYPE_8192CE(rtlhal)) {
rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] &
0xFFFFFFFF);
rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] &
0xFFFFFFFF);
} else {
rtl_write_dword(rtlpriv, REG_HIMR, rtlusb->irq_mask[0] &
0xFFFFFFFF);
rtl_write_dword(rtlpriv, REG_HIMRE, rtlusb->irq_mask[1] &
0xFFFFFFFF);
}
}
void rtl92c_init_interrupt(struct ieee80211_hw *hw)
{
rtl92c_enable_interrupt(hw);
}
void rtl92c_disable_interrupt(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
rtl_write_dword(rtlpriv, REG_HIMR, IMR8190_DISABLED);
rtl_write_dword(rtlpriv, REG_HIMRE, IMR8190_DISABLED);
}
void rtl92c_set_qos(struct ieee80211_hw *hw, int aci)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
u32 u4b_ac_param;
rtl92c_dm_init_edca_turbo(hw);
u4b_ac_param = (u32) mac->ac[aci].aifs;
u4b_ac_param |=
((u32) le16_to_cpu(mac->ac[aci].cw_min) & 0xF) <<
AC_PARAM_ECW_MIN_OFFSET;
u4b_ac_param |=
((u32) le16_to_cpu(mac->ac[aci].cw_max) & 0xF) <<
AC_PARAM_ECW_MAX_OFFSET;
u4b_ac_param |= (u32) le16_to_cpu(mac->ac[aci].tx_op) <<
AC_PARAM_TXOP_OFFSET;
RT_TRACE(rtlpriv, COMP_QOS, DBG_LOUD, "queue:%x, ac_param:%x\n",
aci, u4b_ac_param);
switch (aci) {
case AC1_BK:
rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, u4b_ac_param);
break;
case AC0_BE:
rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, u4b_ac_param);
break;
case AC2_VI:
rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, u4b_ac_param);
break;
case AC3_VO:
rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, u4b_ac_param);
break;
default:
RT_ASSERT(false, "invalid aci: %d !\n", aci);
break;
}
}
/*-------------------------------------------------------------------------
* HW MAC Address
*-------------------------------------------------------------------------*/
void rtl92c_set_mac_addr(struct ieee80211_hw *hw, const u8 *addr)
{
u32 i;
struct rtl_priv *rtlpriv = rtl_priv(hw);
for (i = 0 ; i < ETH_ALEN ; i++)
rtl_write_byte(rtlpriv, (REG_MACID + i), *(addr+i));
RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
"MAC Address: %02X-%02X-%02X-%02X-%02X-%02X\n",
rtl_read_byte(rtlpriv, REG_MACID),
rtl_read_byte(rtlpriv, REG_MACID+1),
rtl_read_byte(rtlpriv, REG_MACID+2),
rtl_read_byte(rtlpriv, REG_MACID+3),
rtl_read_byte(rtlpriv, REG_MACID+4),
rtl_read_byte(rtlpriv, REG_MACID+5));
}
void rtl92c_init_driver_info_size(struct ieee80211_hw *hw, u8 size)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, size);
}
int rtl92c_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type)
{
u8 value;
struct rtl_priv *rtlpriv = rtl_priv(hw);
switch (type) {
case NL80211_IFTYPE_UNSPECIFIED:
value = NT_NO_LINK;
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"Set Network type to NO LINK!\n");
break;
case NL80211_IFTYPE_ADHOC:
value = NT_LINK_AD_HOC;
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"Set Network type to Ad Hoc!\n");
break;
case NL80211_IFTYPE_STATION:
value = NT_LINK_AP;
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"Set Network type to STA!\n");
break;
case NL80211_IFTYPE_AP:
value = NT_AS_AP;
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"Set Network type to AP!\n");
break;
default:
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"Network type %d not supported!\n", type);
return -EOPNOTSUPP;
}
rtl_write_byte(rtlpriv, (REG_CR + 2), value);
return 0;
}
void rtl92c_init_network_type(struct ieee80211_hw *hw)
{
rtl92c_set_network_type(hw, NL80211_IFTYPE_UNSPECIFIED);
}
void rtl92c_init_adaptive_ctrl(struct ieee80211_hw *hw)
{
u16 value16;
u32 value32;
struct rtl_priv *rtlpriv = rtl_priv(hw);
/* Response Rate Set */
value32 = rtl_read_dword(rtlpriv, REG_RRSR);
value32 &= ~RATE_BITMAP_ALL;
value32 |= RATE_RRSR_CCK_ONLY_1M;
rtl_write_dword(rtlpriv, REG_RRSR, value32);
/* SIFS (used in NAV) */
value16 = _SPEC_SIFS_CCK(0x10) | _SPEC_SIFS_OFDM(0x10);
rtl_write_word(rtlpriv, REG_SPEC_SIFS, value16);
/* Retry Limit */
value16 = _LRL(0x30) | _SRL(0x30);
rtl_write_dword(rtlpriv, REG_RL, value16);
}
void rtl92c_init_rate_fallback(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
/* Set Data Auto Rate Fallback Retry Count register. */
rtl_write_dword(rtlpriv, REG_DARFRC, 0x00000000);
rtl_write_dword(rtlpriv, REG_DARFRC+4, 0x10080404);
rtl_write_dword(rtlpriv, REG_RARFRC, 0x04030201);
rtl_write_dword(rtlpriv, REG_RARFRC+4, 0x08070605);
}
static void rtl92c_set_cck_sifs(struct ieee80211_hw *hw, u8 trx_sifs,
u8 ctx_sifs)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
rtl_write_byte(rtlpriv, REG_SIFS_CCK, trx_sifs);
rtl_write_byte(rtlpriv, (REG_SIFS_CCK + 1), ctx_sifs);
}
static void rtl92c_set_ofdm_sifs(struct ieee80211_hw *hw, u8 trx_sifs,
u8 ctx_sifs)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
rtl_write_byte(rtlpriv, REG_SIFS_OFDM, trx_sifs);
rtl_write_byte(rtlpriv, (REG_SIFS_OFDM + 1), ctx_sifs);
}
void rtl92c_init_edca_param(struct ieee80211_hw *hw,
u16 queue, u16 txop, u8 cw_min, u8 cw_max, u8 aifs)
{
/* sequence: VO, VI, BE, BK ==> the same as 92C hardware design.
* referenc : enum nl80211_txq_q or ieee80211_set_wmm_default function.
*/
u32 value;
struct rtl_priv *rtlpriv = rtl_priv(hw);
value = (u32)aifs;
value |= ((u32)cw_min & 0xF) << 8;
value |= ((u32)cw_max & 0xF) << 12;
value |= (u32)txop << 16;
/* 92C hardware register sequence is the same as queue number. */
rtl_write_dword(rtlpriv, (REG_EDCA_VO_PARAM + (queue * 4)), value);
}
void rtl92c_init_edca(struct ieee80211_hw *hw)
{
u16 value16;
struct rtl_priv *rtlpriv = rtl_priv(hw);
/* disable EDCCA count down, to reduce collison and retry */
value16 = rtl_read_word(rtlpriv, REG_RD_CTRL);
value16 |= DIS_EDCA_CNT_DWN;
rtl_write_word(rtlpriv, REG_RD_CTRL, value16);
/* Update SIFS timing. ??????????
* pHalData->SifsTime = 0x0e0e0a0a; */
rtl92c_set_cck_sifs(hw, 0xa, 0xa);
rtl92c_set_ofdm_sifs(hw, 0xe, 0xe);
/* Set CCK/OFDM SIFS to be 10us. */
rtl_write_word(rtlpriv, REG_SIFS_CCK, 0x0a0a);
rtl_write_word(rtlpriv, REG_SIFS_OFDM, 0x1010);
rtl_write_word(rtlpriv, REG_PROT_MODE_CTRL, 0x0204);
rtl_write_dword(rtlpriv, REG_BAR_MODE_CTRL, 0x014004);
/* TXOP */
rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, 0x005EA42B);
rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0x0000A44F);
rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x005EA324);
rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x002FA226);
/* PIFS */
rtl_write_byte(rtlpriv, REG_PIFS, 0x1C);
/* AGGR BREAK TIME Register */
rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16);
rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0040);
rtl_write_byte(rtlpriv, REG_BCNDMATIM, 0x02);
rtl_write_byte(rtlpriv, REG_ATIMWND, 0x02);
}
void rtl92c_init_ampdu_aggregation(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0x99997631);
rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16);
/* init AMPDU aggregation number, tuning for Tx's TP, */
rtl_write_word(rtlpriv, 0x4CA, 0x0708);
}
void rtl92c_init_beacon_max_error(struct ieee80211_hw *hw, bool infra_mode)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0xFF);
}
void rtl92c_init_rdg_setting(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
rtl_write_byte(rtlpriv, REG_RD_CTRL, 0xFF);
rtl_write_word(rtlpriv, REG_RD_NAV_NXT, 0x200);
rtl_write_byte(rtlpriv, REG_RD_RESP_PKT_TH, 0x05);
}
void rtl92c_init_retry_function(struct ieee80211_hw *hw)
{
u8 value8;
struct rtl_priv *rtlpriv = rtl_priv(hw);
value8 = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL);
value8 |= EN_AMPDU_RTY_NEW;
rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL, value8);
/* Set ACK timeout */
rtl_write_byte(rtlpriv, REG_ACKTO, 0x40);
}
void rtl92c_init_beacon_parameters(struct ieee80211_hw *hw,
enum version_8192c version)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
rtl_write_word(rtlpriv, REG_TBTT_PROHIBIT, 0x6404);/* ms */
rtl_write_byte(rtlpriv, REG_DRVERLYINT, DRIVER_EARLY_INT_TIME);/*ms*/
rtl_write_byte(rtlpriv, REG_BCNDMATIM, BCN_DMA_ATIME_INT_TIME);
if (IS_NORMAL_CHIP(rtlhal->version))
rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660F);
else
rtl_write_word(rtlpriv, REG_BCNTCFG, 0x66FF);
}
void rtl92c_disable_fast_edca(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
rtl_write_word(rtlpriv, REG_FAST_EDCA_CTRL, 0);
}
void rtl92c_set_min_space(struct ieee80211_hw *hw, bool is2T)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u8 value = is2T ? MAX_MSS_DENSITY_2T : MAX_MSS_DENSITY_1T;
rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, value);
}
u16 rtl92c_get_mgt_filter(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
return rtl_read_word(rtlpriv, REG_RXFLTMAP0);
}
void rtl92c_set_mgt_filter(struct ieee80211_hw *hw, u16 filter)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
rtl_write_word(rtlpriv, REG_RXFLTMAP0, filter);
}
u16 rtl92c_get_ctrl_filter(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
return rtl_read_word(rtlpriv, REG_RXFLTMAP1);
}
void rtl92c_set_ctrl_filter(struct ieee80211_hw *hw, u16 filter)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
rtl_write_word(rtlpriv, REG_RXFLTMAP1, filter);
}
u16 rtl92c_get_data_filter(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
return rtl_read_word(rtlpriv, REG_RXFLTMAP2);
}
void rtl92c_set_data_filter(struct ieee80211_hw *hw, u16 filter)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
rtl_write_word(rtlpriv, REG_RXFLTMAP2, filter);
}
/*==============================================================*/
static u8 _rtl92c_query_rxpwrpercentage(char antpower)
{
if ((antpower <= -100) || (antpower >= 20))
return 0;
else if (antpower >= 0)
return 100;
else
return 100 + antpower;
}
static u8 _rtl92c_evm_db_to_percentage(char value)
{
char ret_val;
ret_val = value;
if (ret_val >= 0)
ret_val = 0;
if (ret_val <= -33)
ret_val = -33;
ret_val = 0 - ret_val;
ret_val *= 3;
if (ret_val == 99)
ret_val = 100;
return ret_val;
}
static long _rtl92c_signal_scale_mapping(struct ieee80211_hw *hw,
long currsig)
{
long retsig;
if (currsig >= 61 && currsig <= 100)
retsig = 90 + ((currsig - 60) / 4);
else if (currsig >= 41 && currsig <= 60)
retsig = 78 + ((currsig - 40) / 2);
else if (currsig >= 31 && currsig <= 40)
retsig = 66 + (currsig - 30);
else if (currsig >= 21 && currsig <= 30)
retsig = 54 + (currsig - 20);
else if (currsig >= 5 && currsig <= 20)
retsig = 42 + (((currsig - 5) * 2) / 3);
else if (currsig == 4)
retsig = 36;
else if (currsig == 3)
retsig = 27;
else if (currsig == 2)
retsig = 18;
else if (currsig == 1)
retsig = 9;
else
retsig = currsig;
return retsig;
}
static void _rtl92c_query_rxphystatus(struct ieee80211_hw *hw,
struct rtl_stats *pstats,
struct rx_desc_92c *p_desc,
struct rx_fwinfo_92c *p_drvinfo,
bool packet_match_bssid,
bool packet_toself,
bool packet_beacon)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
struct phy_sts_cck_8192s_t *cck_buf;
s8 rx_pwr_all = 0, rx_pwr[4];
u8 rf_rx_num = 0, evm, pwdb_all;
u8 i, max_spatial_stream;
u32 rssi, total_rssi = 0;
bool in_powersavemode = false;
bool is_cck_rate;
u8 *pdesc = (u8 *)p_desc;
is_cck_rate = RX_HAL_IS_CCK_RATE(p_desc->rxmcs);
pstats->packet_matchbssid = packet_match_bssid;
pstats->packet_toself = packet_toself;
pstats->packet_beacon = packet_beacon;
pstats->is_cck = is_cck_rate;
pstats->RX_SIGQ[0] = -1;
pstats->RX_SIGQ[1] = -1;
if (is_cck_rate) {
u8 report, cck_highpwr;
cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo;
if (!in_powersavemode)
cck_highpwr = rtlphy->cck_high_power;
else
cck_highpwr = false;
if (!cck_highpwr) {
u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
report = cck_buf->cck_agc_rpt & 0xc0;
report = report >> 6;
switch (report) {
case 0x3:
rx_pwr_all = -46 - (cck_agc_rpt & 0x3e);
break;
case 0x2:
rx_pwr_all = -26 - (cck_agc_rpt & 0x3e);
break;
case 0x1:
rx_pwr_all = -12 - (cck_agc_rpt & 0x3e);
break;
case 0x0:
rx_pwr_all = 16 - (cck_agc_rpt & 0x3e);
break;
}
} else {
u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
report = p_drvinfo->cfosho[0] & 0x60;
report = report >> 5;
switch (report) {
case 0x3:
rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f) << 1);
break;
case 0x2:
rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f) << 1);
break;
case 0x1:
rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f) << 1);
break;
case 0x0:
rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f) << 1);
break;
}
}
pwdb_all = _rtl92c_query_rxpwrpercentage(rx_pwr_all);
pstats->rx_pwdb_all = pwdb_all;
pstats->recvsignalpower = rx_pwr_all;
if (packet_match_bssid) {
u8 sq;
if (pstats->rx_pwdb_all > 40)
sq = 100;
else {
sq = cck_buf->sq_rpt;
if (sq > 64)
sq = 0;
else if (sq < 20)
sq = 100;
else
sq = ((64 - sq) * 100) / 44;
}
pstats->signalquality = sq;
pstats->RX_SIGQ[0] = sq;
pstats->RX_SIGQ[1] = -1;
}
} else {
rtlpriv->dm.rfpath_rxenable[0] =
rtlpriv->dm.rfpath_rxenable[1] = true;
for (i = RF90_PATH_A; i < RF90_PATH_MAX; i++) {
if (rtlpriv->dm.rfpath_rxenable[i])
rf_rx_num++;
rx_pwr[i] =
((p_drvinfo->gain_trsw[i] & 0x3f) * 2) - 110;
rssi = _rtl92c_query_rxpwrpercentage(rx_pwr[i]);
total_rssi += rssi;
rtlpriv->stats.rx_snr_db[i] =
(long)(p_drvinfo->rxsnr[i] / 2);
if (packet_match_bssid)
pstats->rx_mimo_signalstrength[i] = (u8) rssi;
}
rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110;
pwdb_all = _rtl92c_query_rxpwrpercentage(rx_pwr_all);
pstats->rx_pwdb_all = pwdb_all;
pstats->rxpower = rx_pwr_all;
pstats->recvsignalpower = rx_pwr_all;
if (GET_RX_DESC_RX_MCS(pdesc) &&
GET_RX_DESC_RX_MCS(pdesc) >= DESC92_RATEMCS8 &&
GET_RX_DESC_RX_MCS(pdesc) <= DESC92_RATEMCS15)
max_spatial_stream = 2;
else
max_spatial_stream = 1;
for (i = 0; i < max_spatial_stream; i++) {
evm = _rtl92c_evm_db_to_percentage(p_drvinfo->rxevm[i]);
if (packet_match_bssid) {
if (i == 0)
pstats->signalquality =
(u8) (evm & 0xff);
pstats->RX_SIGQ[i] =
(u8) (evm & 0xff);
}
}
}
if (is_cck_rate)
pstats->signalstrength =
(u8) (_rtl92c_signal_scale_mapping(hw, pwdb_all));
else if (rf_rx_num != 0)
pstats->signalstrength =
(u8) (_rtl92c_signal_scale_mapping
(hw, total_rssi /= rf_rx_num));
}
void rtl92c_translate_rx_signal_stuff(struct ieee80211_hw *hw,
struct sk_buff *skb,
struct rtl_stats *pstats,
struct rx_desc_92c *pdesc,
struct rx_fwinfo_92c *p_drvinfo)
{
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
struct ieee80211_hdr *hdr;
u8 *tmp_buf;
u8 *praddr;
__le16 fc;
u16 type, cpu_fc;
bool packet_matchbssid, packet_toself, packet_beacon = false;
tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift;
hdr = (struct ieee80211_hdr *)tmp_buf;
fc = hdr->frame_control;
cpu_fc = le16_to_cpu(fc);
type = WLAN_FC_GET_TYPE(fc);
praddr = hdr->addr1;
packet_matchbssid =
((IEEE80211_FTYPE_CTL != type) &&
ether_addr_equal(mac->bssid,
(cpu_fc & IEEE80211_FCTL_TODS) ? hdr->addr1 :
(cpu_fc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 :
hdr->addr3) &&
(!pstats->hwerror) && (!pstats->crc) && (!pstats->icv));
packet_toself = packet_matchbssid &&
ether_addr_equal(praddr, rtlefuse->dev_addr);
if (ieee80211_is_beacon(fc))
packet_beacon = true;
_rtl92c_query_rxphystatus(hw, pstats, pdesc, p_drvinfo,
packet_matchbssid, packet_toself,
packet_beacon);
rtl_process_phyinfo(hw, tmp_buf, pstats);
}

View file

@ -0,0 +1,174 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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
*
* 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 __RTL92C_MAC_H__
#define __RTL92C_MAC_H__
#define LLT_LAST_ENTRY_OF_TX_PKT_BUFFER 255
#define DRIVER_EARLY_INT_TIME 0x05
#define BCN_DMA_ATIME_INT_TIME 0x02
void rtl92c_read_chip_version(struct ieee80211_hw *hw);
bool rtl92c_llt_write(struct ieee80211_hw *hw, u32 address, u32 data);
bool rtl92c_init_llt_table(struct ieee80211_hw *hw, u32 boundary);
void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index,
u8 *p_macaddr, bool is_group, u8 enc_algo,
bool is_wepkey, bool clear_all);
void rtl92c_enable_interrupt(struct ieee80211_hw *hw);
void rtl92c_disable_interrupt(struct ieee80211_hw *hw);
void rtl92c_set_qos(struct ieee80211_hw *hw, int aci);
/*---------------------------------------------------------------
* Hardware init functions
*---------------------------------------------------------------*/
void rtl92c_set_mac_addr(struct ieee80211_hw *hw, const u8 *addr);
void rtl92c_init_interrupt(struct ieee80211_hw *hw);
void rtl92c_init_driver_info_size(struct ieee80211_hw *hw, u8 size);
int rtl92c_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type);
void rtl92c_init_network_type(struct ieee80211_hw *hw);
void rtl92c_init_adaptive_ctrl(struct ieee80211_hw *hw);
void rtl92c_init_rate_fallback(struct ieee80211_hw *hw);
void rtl92c_init_edca_param(struct ieee80211_hw *hw,
u16 queue,
u16 txop,
u8 ecwmax,
u8 ecwmin,
u8 aifs);
void rtl92c_init_edca(struct ieee80211_hw *hw);
void rtl92c_init_ampdu_aggregation(struct ieee80211_hw *hw);
void rtl92c_init_beacon_max_error(struct ieee80211_hw *hw, bool infra_mode);
void rtl92c_init_rdg_setting(struct ieee80211_hw *hw);
void rtl92c_init_retry_function(struct ieee80211_hw *hw);
void rtl92c_init_beacon_parameters(struct ieee80211_hw *hw,
enum version_8192c version);
void rtl92c_disable_fast_edca(struct ieee80211_hw *hw);
void rtl92c_set_min_space(struct ieee80211_hw *hw, bool is2T);
/* For filter */
u16 rtl92c_get_mgt_filter(struct ieee80211_hw *hw);
void rtl92c_set_mgt_filter(struct ieee80211_hw *hw, u16 filter);
u16 rtl92c_get_ctrl_filter(struct ieee80211_hw *hw);
void rtl92c_set_ctrl_filter(struct ieee80211_hw *hw, u16 filter);
u16 rtl92c_get_data_filter(struct ieee80211_hw *hw);
void rtl92c_set_data_filter(struct ieee80211_hw *hw, u16 filter);
u32 rtl92c_get_txdma_status(struct ieee80211_hw *hw);
struct rx_fwinfo_92c {
u8 gain_trsw[4];
u8 pwdb_all;
u8 cfosho[4];
u8 cfotail[4];
char rxevm[2];
char rxsnr[4];
u8 pdsnr[2];
u8 csi_current[2];
u8 csi_target[2];
u8 sigevm;
u8 max_ex_pwr;
u8 ex_intf_flag:1;
u8 sgi_en:1;
u8 rxsc:2;
u8 reserve:4;
} __packed;
struct rx_desc_92c {
u32 length:14;
u32 crc32:1;
u32 icverror:1;
u32 drv_infosize:4;
u32 security:3;
u32 qos:1;
u32 shift:2;
u32 phystatus:1;
u32 swdec:1;
u32 lastseg:1;
u32 firstseg:1;
u32 eor:1;
u32 own:1;
u32 macid:5; /* word 1 */
u32 tid:4;
u32 hwrsvd:5;
u32 paggr:1;
u32 faggr:1;
u32 a1_fit:4;
u32 a2_fit:4;
u32 pam:1;
u32 pwr:1;
u32 moredata:1;
u32 morefrag:1;
u32 type:2;
u32 mc:1;
u32 bc:1;
u32 seq:12; /* word 2 */
u32 frag:4;
u32 nextpktlen:14;
u32 nextind:1;
u32 rsvd:1;
u32 rxmcs:6; /* word 3 */
u32 rxht:1;
u32 amsdu:1;
u32 splcp:1;
u32 bandwidth:1;
u32 htc:1;
u32 tcpchk_rpt:1;
u32 ipcchk_rpt:1;
u32 tcpchk_valid:1;
u32 hwpcerr:1;
u32 hwpcind:1;
u32 iv0:16;
u32 iv1; /* word 4 */
u32 tsfl; /* word 5 */
u32 bufferaddress; /* word 6 */
u32 bufferaddress64; /* word 7 */
} __packed;
enum rtl_desc_qsel rtl92c_map_hwqueue_to_fwqueue(u16 fc,
unsigned int
skb_queue);
void rtl92c_translate_rx_signal_stuff(struct ieee80211_hw *hw,
struct sk_buff *skb,
struct rtl_stats *pstats,
struct rx_desc_92c *pdesc,
struct rx_fwinfo_92c *p_drvinfo);
/*---------------------------------------------------------------
* Card disable functions
*---------------------------------------------------------------*/
#endif

View file

@ -0,0 +1,551 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "../wifi.h"
#include "../pci.h"
#include "../ps.h"
#include "../core.h"
#include "reg.h"
#include "def.h"
#include "phy.h"
#include "../rtl8192c/phy_common.h"
#include "rf.h"
#include "dm.h"
#include "../rtl8192c/dm_common.h"
#include "../rtl8192c/fw_common.h"
#include "table.h"
u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw,
enum radio_path rfpath, u32 regaddr, u32 bitmask)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u32 original_value, readback_value, bitshift;
struct rtl_phy *rtlphy = &(rtlpriv->phy);
RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
"regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
regaddr, rfpath, bitmask);
if (rtlphy->rf_mode != RF_OP_BY_FW) {
original_value = _rtl92c_phy_rf_serial_read(hw,
rfpath, regaddr);
} else {
original_value = _rtl92c_phy_fw_rf_serial_read(hw,
rfpath, regaddr);
}
bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
readback_value = (original_value & bitmask) >> bitshift;
RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
"regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n",
regaddr, rfpath, bitmask, original_value);
return readback_value;
}
void rtl92cu_phy_set_rf_reg(struct ieee80211_hw *hw,
enum radio_path rfpath,
u32 regaddr, u32 bitmask, u32 data)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
u32 original_value, bitshift;
RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
"regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
regaddr, bitmask, data, rfpath);
if (rtlphy->rf_mode != RF_OP_BY_FW) {
if (bitmask != RFREG_OFFSET_MASK) {
original_value = _rtl92c_phy_rf_serial_read(hw,
rfpath,
regaddr);
bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
data =
((original_value & (~bitmask)) |
(data << bitshift));
}
_rtl92c_phy_rf_serial_write(hw, rfpath, regaddr, data);
} else {
if (bitmask != RFREG_OFFSET_MASK) {
original_value = _rtl92c_phy_fw_rf_serial_read(hw,
rfpath,
regaddr);
bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
data =
((original_value & (~bitmask)) |
(data << bitshift));
}
_rtl92c_phy_fw_rf_serial_write(hw, rfpath, regaddr, data);
}
RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
"regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
regaddr, bitmask, data, rfpath);
}
bool rtl92cu_phy_mac_config(struct ieee80211_hw *hw)
{
bool rtstatus;
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
bool is92c = IS_92C_SERIAL(rtlhal->version);
rtstatus = _rtl92cu_phy_config_mac_with_headerfile(hw);
if (is92c && IS_HARDWARE_TYPE_8192CE(rtlhal))
rtl_write_byte(rtlpriv, 0x14, 0x71);
return rtstatus;
}
bool rtl92cu_phy_bb_config(struct ieee80211_hw *hw)
{
bool rtstatus = true;
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
u16 regval;
u32 regval32;
u8 b_reg_hwparafile = 1;
_rtl92c_phy_init_bb_rf_register_definition(hw);
regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, regval | BIT(13) |
BIT(0) | BIT(1));
rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x83);
rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL + 1, 0xdb);
rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB);
if (IS_HARDWARE_TYPE_8192CE(rtlhal)) {
rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, FEN_PPLL | FEN_PCIEA |
FEN_DIO_PCIE | FEN_BB_GLB_RSTn | FEN_BBRSTB);
} else if (IS_HARDWARE_TYPE_8192CU(rtlhal)) {
rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, FEN_USBA | FEN_USBD |
FEN_BB_GLB_RSTn | FEN_BBRSTB);
}
regval32 = rtl_read_dword(rtlpriv, 0x87c);
rtl_write_dword(rtlpriv, 0x87c, regval32 & (~BIT(31)));
if (IS_HARDWARE_TYPE_8192CU(rtlhal))
rtl_write_byte(rtlpriv, REG_LDOHCI12_CTRL, 0x0f);
rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80);
if (b_reg_hwparafile == 1)
rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw);
return rtstatus;
}
bool _rtl92cu_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
u32 i;
u32 arraylength;
u32 *ptrarray;
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl819XMACPHY_Array\n");
arraylength = rtlphy->hwparam_tables[MAC_REG].length ;
ptrarray = rtlphy->hwparam_tables[MAC_REG].pdata;
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Img:RTL8192CEMAC_2T_ARRAY\n");
for (i = 0; i < arraylength; i = i + 2)
rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]);
return true;
}
bool _rtl92cu_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
u8 configtype)
{
int i;
u32 *phy_regarray_table;
u32 *agctab_array_table;
u16 phy_reg_arraylen, agctab_arraylen;
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
struct rtl_phy *rtlphy = &(rtlpriv->phy);
if (IS_92C_SERIAL(rtlhal->version)) {
agctab_arraylen = rtlphy->hwparam_tables[AGCTAB_2T].length;
agctab_array_table = rtlphy->hwparam_tables[AGCTAB_2T].pdata;
phy_reg_arraylen = rtlphy->hwparam_tables[PHY_REG_2T].length;
phy_regarray_table = rtlphy->hwparam_tables[PHY_REG_2T].pdata;
} else {
agctab_arraylen = rtlphy->hwparam_tables[AGCTAB_1T].length;
agctab_array_table = rtlphy->hwparam_tables[AGCTAB_1T].pdata;
phy_reg_arraylen = rtlphy->hwparam_tables[PHY_REG_1T].length;
phy_regarray_table = rtlphy->hwparam_tables[PHY_REG_1T].pdata;
}
if (configtype == BASEBAND_CONFIG_PHY_REG) {
for (i = 0; i < phy_reg_arraylen; i = i + 2) {
rtl_addr_delay(phy_regarray_table[i]);
rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD,
phy_regarray_table[i + 1]);
udelay(1);
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
"The phy_regarray_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n",
phy_regarray_table[i],
phy_regarray_table[i + 1]);
}
} else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
for (i = 0; i < agctab_arraylen; i = i + 2) {
rtl_set_bbreg(hw, agctab_array_table[i], MASKDWORD,
agctab_array_table[i + 1]);
udelay(1);
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
"The agctab_array_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n",
agctab_array_table[i],
agctab_array_table[i + 1]);
}
}
return true;
}
bool _rtl92cu_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
u8 configtype)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
int i;
u32 *phy_regarray_table_pg;
u16 phy_regarray_pg_len;
rtlphy->pwrgroup_cnt = 0;
phy_regarray_pg_len = rtlphy->hwparam_tables[PHY_REG_PG].length;
phy_regarray_table_pg = rtlphy->hwparam_tables[PHY_REG_PG].pdata;
if (configtype == BASEBAND_CONFIG_PHY_REG) {
for (i = 0; i < phy_regarray_pg_len; i = i + 3) {
rtl_addr_delay(phy_regarray_table_pg[i]);
_rtl92c_store_pwrIndex_diffrate_offset(hw,
phy_regarray_table_pg[i],
phy_regarray_table_pg[i + 1],
phy_regarray_table_pg[i + 2]);
}
} else {
RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
"configtype != BaseBand_Config_PHY_REG\n");
}
return true;
}
bool rtl92cu_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
enum radio_path rfpath)
{
int i;
u32 *radioa_array_table;
u32 *radiob_array_table;
u16 radioa_arraylen, radiob_arraylen;
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
struct rtl_phy *rtlphy = &(rtlpriv->phy);
if (IS_92C_SERIAL(rtlhal->version)) {
radioa_arraylen = rtlphy->hwparam_tables[RADIOA_2T].length;
radioa_array_table = rtlphy->hwparam_tables[RADIOA_2T].pdata;
radiob_arraylen = rtlphy->hwparam_tables[RADIOB_2T].length;
radiob_array_table = rtlphy->hwparam_tables[RADIOB_2T].pdata;
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
"Radio_A:RTL8192CERADIOA_2TARRAY\n");
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
"Radio_B:RTL8192CE_RADIOB_2TARRAY\n");
} else {
radioa_arraylen = rtlphy->hwparam_tables[RADIOA_1T].length;
radioa_array_table = rtlphy->hwparam_tables[RADIOA_1T].pdata;
radiob_arraylen = rtlphy->hwparam_tables[RADIOB_1T].length;
radiob_array_table = rtlphy->hwparam_tables[RADIOB_1T].pdata;
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
"Radio_A:RTL8192CE_RADIOA_1TARRAY\n");
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
"Radio_B:RTL8192CE_RADIOB_1TARRAY\n");
}
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Radio No %x\n", rfpath);
switch (rfpath) {
case RF90_PATH_A:
for (i = 0; i < radioa_arraylen; i = i + 2) {
rtl_rfreg_delay(hw, rfpath, radioa_array_table[i],
RFREG_OFFSET_MASK,
radioa_array_table[i + 1]);
}
break;
case RF90_PATH_B:
for (i = 0; i < radiob_arraylen; i = i + 2) {
rtl_rfreg_delay(hw, rfpath, radiob_array_table[i],
RFREG_OFFSET_MASK,
radiob_array_table[i + 1]);
}
break;
case RF90_PATH_C:
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"switch case not processed\n");
break;
case RF90_PATH_D:
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"switch case not processed\n");
break;
default:
break;
}
return true;
}
void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
struct rtl_phy *rtlphy = &(rtlpriv->phy);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
u8 reg_bw_opmode;
u8 reg_prsr_rsc;
RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n",
rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
"20MHz" : "40MHz");
if (is_hal_stop(rtlhal)) {
rtlphy->set_bwmode_inprogress = false;
return;
}
reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
switch (rtlphy->current_chan_bw) {
case HT_CHANNEL_WIDTH_20:
reg_bw_opmode |= BW_OPMODE_20MHZ;
rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
break;
case HT_CHANNEL_WIDTH_20_40:
reg_bw_opmode &= ~BW_OPMODE_20MHZ;
rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
reg_prsr_rsc =
(reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5);
rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
break;
}
switch (rtlphy->current_chan_bw) {
case HT_CHANNEL_WIDTH_20:
rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);
break;
case HT_CHANNEL_WIDTH_20_40:
rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
(mac->cur_40_prime_sc >> 1));
rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0);
rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
(mac->cur_40_prime_sc ==
HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
break;
}
rtl92cu_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
rtlphy->set_bwmode_inprogress = false;
RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
}
void rtl92cu_bb_block_on(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
mutex_lock(&rtlpriv->io.bb_mutex);
rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1);
rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1);
mutex_unlock(&rtlpriv->io.bb_mutex);
}
void _rtl92cu_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
{
u8 tmpreg;
u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
struct rtl_priv *rtlpriv = rtl_priv(hw);
tmpreg = rtl_read_byte(rtlpriv, 0xd03);
if ((tmpreg & 0x70) != 0)
rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
else
rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
if ((tmpreg & 0x70) != 0) {
rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS);
if (is2t)
rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00,
MASK12BITS);
rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS,
(rf_a_mode & 0x8FFFF) | 0x10000);
if (is2t)
rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
(rf_b_mode & 0x8FFFF) | 0x10000);
}
lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS);
rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000);
mdelay(100);
if ((tmpreg & 0x70) != 0) {
rtl_write_byte(rtlpriv, 0xd03, tmpreg);
rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode);
if (is2t)
rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
rf_b_mode);
} else {
rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
}
}
static bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw,
enum rf_pwrstate rfpwr_state)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
bool bresult = true;
u8 i, queue_id;
struct rtl8192_tx_ring *ring = NULL;
switch (rfpwr_state) {
case ERFON:
if ((ppsc->rfpwr_state == ERFOFF) &&
RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
bool rtstatus;
u32 InitializeCount = 0;
do {
InitializeCount++;
RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
"IPS Set eRf nic enable\n");
rtstatus = rtl_ps_enable_nic(hw);
} while (!rtstatus && (InitializeCount < 10));
RT_CLEAR_PS_LEVEL(ppsc,
RT_RF_OFF_LEVL_HALT_NIC);
} else {
RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
"Set ERFON sleeped:%d ms\n",
jiffies_to_msecs(jiffies -
ppsc->last_sleep_jiffies));
ppsc->last_awake_jiffies = jiffies;
rtl92ce_phy_set_rf_on(hw);
}
if (mac->link_state == MAC80211_LINKED) {
rtlpriv->cfg->ops->led_control(hw,
LED_CTL_LINK);
} else {
rtlpriv->cfg->ops->led_control(hw,
LED_CTL_NO_LINK);
}
break;
case ERFOFF:
for (queue_id = 0, i = 0;
queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
ring = &pcipriv->dev.tx_ring[queue_id];
if (skb_queue_len(&ring->queue) == 0 ||
queue_id == BEACON_QUEUE) {
queue_id++;
continue;
} else {
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
"eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
i + 1,
queue_id,
skb_queue_len(&ring->queue));
udelay(10);
i++;
}
if (i >= MAX_DOZE_WAITING_TIMES_9x) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
"ERFOFF: %d times TcbBusyQueue[%d] = %d !\n",
MAX_DOZE_WAITING_TIMES_9x,
queue_id,
skb_queue_len(&ring->queue));
break;
}
}
if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
"IPS Set eRf nic disable\n");
rtl_ps_disable_nic(hw);
RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
} else {
if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
rtlpriv->cfg->ops->led_control(hw,
LED_CTL_NO_LINK);
} else {
rtlpriv->cfg->ops->led_control(hw,
LED_CTL_POWER_OFF);
}
}
break;
case ERFSLEEP:
if (ppsc->rfpwr_state == ERFOFF)
return false;
for (queue_id = 0, i = 0;
queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
ring = &pcipriv->dev.tx_ring[queue_id];
if (skb_queue_len(&ring->queue) == 0) {
queue_id++;
continue;
} else {
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
"eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
i + 1, queue_id,
skb_queue_len(&ring->queue));
udelay(10);
i++;
}
if (i >= MAX_DOZE_WAITING_TIMES_9x) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
"ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
MAX_DOZE_WAITING_TIMES_9x,
queue_id,
skb_queue_len(&ring->queue));
break;
}
}
RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
"Set ERFSLEEP awaked:%d ms\n",
jiffies_to_msecs(jiffies - ppsc->last_awake_jiffies));
ppsc->last_sleep_jiffies = jiffies;
_rtl92c_phy_set_rf_sleep(hw);
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"switch case not processed\n");
bresult = false;
break;
}
if (bresult)
ppsc->rfpwr_state = rfpwr_state;
return bresult;
}
bool rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw,
enum rf_pwrstate rfpwr_state)
{
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
bool bresult = false;
if (rfpwr_state == ppsc->rfpwr_state)
return bresult;
bresult = _rtl92cu_phy_set_rf_power_state(hw, rfpwr_state);
return bresult;
}

View file

@ -0,0 +1,50 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "../rtl8192ce/phy.h"
void rtl92cu_bb_block_on(struct ieee80211_hw *hw);
bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, u32 rfpath);
void rtl92c_phy_set_io(struct ieee80211_hw *hw);
bool _rtl92cu_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);
bool rtl92cu_phy_bb_config(struct ieee80211_hw *hw);
u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw,
enum radio_path rfpath, u32 regaddr, u32 bitmask);
void rtl92cu_phy_set_rf_reg(struct ieee80211_hw *hw,
enum radio_path rfpath,
u32 regaddr, u32 bitmask, u32 data);
bool rtl92cu_phy_mac_config(struct ieee80211_hw *hw);
bool _rtl92cu_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
u8 configtype);
void _rtl92cu_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t);
bool _rtl92cu_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
u8 configtype);
void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw);
bool rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw,
enum rf_pwrstate rfpwr_state);

View file

@ -0,0 +1,30 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "../rtl8192ce/reg.h"

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