2011-03-06 20:42:28

by Larry Finger

[permalink] [raw]
Subject: [RFC/RFT V2 11/11] rtlwifi: rtl8192se: Modify rtlwifi routines to handle rtl8192se and add Makefile and Kconfig

From: Chaoming Li <[email protected]>

Modify rtlwifi routines for rtl8192se and set up Kconfig
and Makefile for new driver.

Signed-off-by: Chaoming_Li <[email protected]>
Signed-off-by: Larry Finger <[email protected]>
---

Index: wireless-testing/drivers/net/wireless/rtlwifi/efuse.h
===================================================================
--- wireless-testing.orig/drivers/net/wireless/rtlwifi/efuse.h
+++ wireless-testing/drivers/net/wireless/rtlwifi/efuse.h
@@ -30,6 +30,7 @@
#ifndef __RTL_EFUSE_H_
#define __RTL_EFUSE_H_

+#define EFUSE_IC_ID_OFFSET 506
#define EFUSE_REAL_CONTENT_LEN 512
#define EFUSE_MAP_LEN 128
#define EFUSE_MAX_SECTION 16
@@ -117,5 +118,6 @@ extern bool efuse_shadow_update_chk(stru
extern void rtl_efuse_shadow_map_update(struct ieee80211_hw *hw);
extern void efuse_force_write_vendor_Id(struct ieee80211_hw *hw);
extern void efuse_re_pg_section(struct ieee80211_hw *hw, u8 section_idx);
+void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf);

#endif
Index: wireless-testing/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
+++ wireless-testing/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
@@ -152,6 +152,7 @@ static struct rtl_mod_params rtl92ce_mod
};

static struct rtl_hal_cfg rtl92ce_hal_cfg = {
+ .bar_id = 2,
.name = "rtl92c_pci",
.fw_name = "rtlwifi/rtl8192cfw.bin",
.ops = &rtl8192ce_hal_ops,
Index: wireless-testing/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
+++ wireless-testing/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
@@ -723,7 +723,8 @@ bool rtl92ce_rx_query_desc(struct ieee80
void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
struct ieee80211_hdr *hdr, u8 *pdesc_tx,
struct ieee80211_tx_info *info, struct sk_buff *skb,
- unsigned int queue_index)
+ unsigned int queue_index,
+ struct rtl_tcb_desc *ptcb_desc)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
@@ -861,7 +862,7 @@ void rtl92ce_tx_fill_desc(struct ieee802

SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len);

- SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping));
+ SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);

if (rtlpriv->dm.useramask) {
SET_TX_DESC_RATE_ID(pdesc, tcb_desc.ratr_index);
@@ -923,7 +924,7 @@ void rtl92ce_tx_fill_cmddesc(struct ieee

SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) (skb->len));

- SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping));
+ SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);

SET_TX_DESC_RATE_ID(pdesc, 7);
SET_TX_DESC_MACID(pdesc, 0);
Index: wireless-testing/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h
===================================================================
--- wireless-testing.orig/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h
+++ wireless-testing/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h
@@ -722,9 +722,10 @@ struct rx_desc_92c {
} __packed;

void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
- struct ieee80211_hdr *hdr,
- u8 *pdesc, struct ieee80211_tx_info *info,
- struct sk_buff *skb, unsigned int qsel);
+ struct ieee80211_hdr *hdr, u8 *pdesc_tx,
+ struct ieee80211_tx_info *info, struct sk_buff *skb,
+ unsigned int queue_index,
+ 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,
Index: wireless-testing/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
+++ wireless-testing/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
@@ -498,7 +498,8 @@ static void _rtl_tx_desc_checksum(u8 *tx
void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw,
struct ieee80211_hdr *hdr, u8 *pdesc_tx,
struct ieee80211_tx_info *info, struct sk_buff *skb,
- unsigned int queue_index)
+ unsigned int queue_index,
+ struct rtl_tcb_desc *ptcb_desc)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
Index: wireless-testing/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h
===================================================================
--- wireless-testing.orig/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h
+++ wireless-testing/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h
@@ -419,7 +419,8 @@ struct sk_buff *rtl8192c_tx_aggregate_hd
void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw,
struct ieee80211_hdr *hdr, u8 *pdesc_tx,
struct ieee80211_tx_info *info, struct sk_buff *skb,
- unsigned int queue_index);
+ unsigned int queue_index,
+ struct rtl_tcb_desc *ptcb_desc);
void rtl92cu_fill_fake_txdesc(struct ieee80211_hw *hw, u8 * pDesc,
u32 buffer_len, bool bIsPsPoll);
void rtl92cu_tx_fill_cmddesc(struct ieee80211_hw *hw,
Index: wireless-testing/drivers/net/wireless/rtlwifi/usb.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/rtlwifi/usb.c
+++ wireless-testing/drivers/net/wireless/rtlwifi/usb.c
@@ -852,6 +852,7 @@ static void _rtl_usb_tx_preprocess(struc
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct rtl_tx_desc *pdesc = NULL;
+ struct rtl_tcb_desc *ptcb_desc = NULL;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
__le16 fc = hdr->frame_control;
u8 *pda_addr = hdr->addr1;
@@ -878,7 +879,7 @@ static void _rtl_usb_tx_preprocess(struc
seq_number <<= 4;
}
rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *)pdesc, info, skb,
- hw_queue);
+ hw_queue, ptcb_desc);
if (!ieee80211_has_morefrags(hdr->frame_control)) {
if (qc)
mac->tids[tid].seq_number = seq_number;
@@ -887,7 +888,8 @@ static void _rtl_usb_tx_preprocess(struc
rtlpriv->cfg->ops->led_control(hw, LED_CTL_TX);
}

-static int rtl_usb_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+static int rtl_usb_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
+ struct rtl_tcb_desc *dummy)
{
struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw));
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
Index: wireless-testing/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h
===================================================================
--- wireless-testing.orig/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h
+++ wireless-testing/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h
@@ -242,5 +242,21 @@ static bool _rtl92c_phy_set_sw_chnl_cmda
static bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
u8 channel, u8 *stage, u8 *step,
u32 *delay);
+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);
+void _rtl92c_phy_set_rf_sleep(struct ieee80211_hw *hw);

#endif
Index: wireless-testing/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c
+++ wireless-testing/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c
@@ -39,7 +39,7 @@
#include "table.h"

u32 rtl92ce_phy_query_rf_reg(struct ieee80211_hw *hw,
- enum radio_path rfpath, u32 regaddr, u32 bitmask)
+ enum radio_path rfpath, u32 regaddr, u32 bitmask)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u32 original_value, readback_value, bitshift;
@@ -177,7 +177,7 @@ bool _rtl92ce_phy_config_mac_with_header
}

bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
- u8 configtype)
+ u8 configtype)
{
int i;
u32 *phy_regarray_table;
@@ -236,7 +236,7 @@ bool _rtl92ce_phy_config_bb_with_headerf
}

bool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
- u8 configtype)
+ u8 configtype)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
int i;
Index: wireless-testing/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h
===================================================================
--- wireless-testing.orig/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h
+++ wireless-testing/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h
@@ -250,5 +250,15 @@ bool _rtl92ce_phy_config_mac_with_header
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);
+u32 rtl92ce_phy_query_rf_reg(struct ieee80211_hw *hw,
+ enum radio_path rfpath, u32 regaddr, u32 bitmask);
+bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
+ u8 configtype);
+bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
+ u8 configtype);
+void rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw);
+void _rtl92ce_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t);
+bool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
+ u8 configtype);

#endif
Index: wireless-testing/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c
+++ wireless-testing/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c
@@ -62,7 +62,7 @@ void rtl92c_phy_rf6052_set_bandwidth(str
}

void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
- u8 *ppowerlevel)
+ u8 *ppowerlevel)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
@@ -411,7 +411,7 @@ static void _rtl92c_write_ofdm_power_reg
}

void rtl92ce_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
- u8 *ppowerlevel, u8 channel)
+ u8 *ppowerlevel, u8 channel)
{
u32 writeVal[2], powerBase0[2], powerBase1[2];
u8 index;
Index: wireless-testing/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h
===================================================================
--- wireless-testing.orig/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h
+++ wireless-testing/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h
@@ -43,5 +43,9 @@ extern void rtl92c_phy_rf6052_set_ofdm_t
bool rtl92ce_phy_rf6052_config(struct ieee80211_hw *hw);
bool rtl92ce_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
enum radio_path rfpath);
+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);

#endif
Index: wireless-testing/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c
+++ wireless-testing/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c
@@ -35,6 +35,7 @@
#include "phy.h"
#include "rf.h"
#include "dm.h"
+#include "sw.h"
#include "table.h"

u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw,
@@ -460,7 +461,7 @@ void _rtl92cu_phy_lc_calibrate(struct ie
}

bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw,
- enum rf_pwrstate rfpwr_state)
+ enum rf_pwrstate rfpwr_state)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
Index: wireless-testing/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h
===================================================================
--- wireless-testing.orig/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h
+++ wireless-testing/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h
@@ -34,3 +34,6 @@ bool rtl8192_phy_check_is_legal_rfpath(s
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);
+bool rtl92cu_phy_mac_config(struct ieee80211_hw *hw);
+bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw,
+ enum rf_pwrstate rfpwr_state);
Index: wireless-testing/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c
+++ wireless-testing/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c
@@ -62,7 +62,7 @@ void rtl92cu_phy_rf6052_set_bandwidth(st
}

void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
- u8 *ppowerlevel)
+ u8 *ppowerlevel)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
@@ -389,7 +389,7 @@ static void _rtl92c_write_ofdm_power_reg
}

void rtl92cu_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
- u8 *ppowerlevel, u8 channel)
+ u8 *ppowerlevel, u8 channel)
{
u32 writeVal[2], powerBase0[2], powerBase1[2];
u8 index = 0;
Index: wireless-testing/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h
===================================================================
--- wireless-testing.orig/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h
+++ wireless-testing/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h
@@ -43,5 +43,9 @@ extern void rtl92c_phy_rf6052_set_ofdm_t
bool rtl92cu_phy_rf6052_config(struct ieee80211_hw *hw);
bool rtl92cu_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
enum radio_path rfpath);
+void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
+ u8 *ppowerlevel);
+void rtl92cu_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
+ u8 *ppowerlevel, u8 channel);

#endif
Index: wireless-testing/drivers/net/wireless/rtlwifi/base.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/rtlwifi/base.c
+++ wireless-testing/drivers/net/wireless/rtlwifi/base.c
@@ -50,8 +50,9 @@
*3) functions called by core.c
*4) wq & timer callback functions
*5) frame process functions
- *6) sysfs functions
- *7) ...
+ *6) IOT functions
+ *7) sysfs functions
+ *8) ...
*/

/*********************************************************
@@ -59,7 +60,7 @@
* mac80211 init functions
*
*********************************************************/
-static struct ieee80211_channel rtl_channeltable[] = {
+static struct ieee80211_channel rtl_channeltable_2g[] = {
{.center_freq = 2412, .hw_value = 1,},
{.center_freq = 2417, .hw_value = 2,},
{.center_freq = 2422, .hw_value = 3,},
@@ -76,7 +77,34 @@ static struct ieee80211_channel rtl_chan
{.center_freq = 2484, .hw_value = 14,},
};

-static struct ieee80211_rate rtl_ratetable[] = {
+static struct ieee80211_channel rtl_channeltable_5g[] = {
+ {.center_freq = 5180, .hw_value = 36,},
+ {.center_freq = 5200, .hw_value = 40,},
+ {.center_freq = 5220, .hw_value = 44,},
+ {.center_freq = 5240, .hw_value = 48,},
+ {.center_freq = 5260, .hw_value = 52,},
+ {.center_freq = 5280, .hw_value = 56,},
+ {.center_freq = 5300, .hw_value = 60,},
+ {.center_freq = 5320, .hw_value = 64,},
+ {.center_freq = 5500, .hw_value = 100,},
+ {.center_freq = 5520, .hw_value = 104,},
+ {.center_freq = 5540, .hw_value = 108,},
+ {.center_freq = 5560, .hw_value = 112,},
+ {.center_freq = 5580, .hw_value = 116,},
+ {.center_freq = 5600, .hw_value = 120,},
+ {.center_freq = 5620, .hw_value = 124,},
+ {.center_freq = 5640, .hw_value = 128,},
+ {.center_freq = 5660, .hw_value = 132,},
+ {.center_freq = 5680, .hw_value = 136,},
+ {.center_freq = 5700, .hw_value = 140,},
+ {.center_freq = 5745, .hw_value = 149,},
+ {.center_freq = 5765, .hw_value = 153,},
+ {.center_freq = 5785, .hw_value = 157,},
+ {.center_freq = 5805, .hw_value = 161,},
+ {.center_freq = 5825, .hw_value = 165,},
+};
+
+static struct ieee80211_rate rtl_ratetable_2g[] = {
{.bitrate = 10, .hw_value = 0x00,},
{.bitrate = 20, .hw_value = 0x01,},
{.bitrate = 55, .hw_value = 0x02,},
@@ -91,14 +119,37 @@ static struct ieee80211_rate rtl_ratetab
{.bitrate = 540, .hw_value = 0x0b,},
};

+static struct ieee80211_rate rtl_ratetable_5g[] = {
+ {.bitrate = 60, .hw_value = 0x04,},
+ {.bitrate = 90, .hw_value = 0x05,},
+ {.bitrate = 120, .hw_value = 0x06,},
+ {.bitrate = 180, .hw_value = 0x07,},
+ {.bitrate = 240, .hw_value = 0x08,},
+ {.bitrate = 360, .hw_value = 0x09,},
+ {.bitrate = 480, .hw_value = 0x0a,},
+ {.bitrate = 540, .hw_value = 0x0b,},
+};
+
static const struct ieee80211_supported_band rtl_band_2ghz = {
.band = IEEE80211_BAND_2GHZ,

- .channels = rtl_channeltable,
- .n_channels = ARRAY_SIZE(rtl_channeltable),
+ .channels = rtl_channeltable_2g,
+ .n_channels = ARRAY_SIZE(rtl_channeltable_2g),

- .bitrates = rtl_ratetable,
- .n_bitrates = ARRAY_SIZE(rtl_ratetable),
+ .bitrates = rtl_ratetable_2g,
+ .n_bitrates = ARRAY_SIZE(rtl_ratetable_2g),
+
+ .ht_cap = {0},
+};
+
+static struct ieee80211_supported_band rtl_band_5ghz = {
+ .band = IEEE80211_BAND_5GHZ,
+
+ .channels = rtl_channeltable_5g,
+ .n_channels = ARRAY_SIZE(rtl_channeltable_5g),
+
+ .bitrates = rtl_ratetable_5g,
+ .n_bitrates = ARRAY_SIZE(rtl_ratetable_5g),

.ht_cap = {0},
};
@@ -115,6 +166,9 @@ static void _rtl_init_hw_ht_capab(struct
IEEE80211_HT_CAP_SGI_20 |
IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU;

+ if (rtlpriv->rtlhal.disable_amsdu_8k)
+ ht_cap->cap &= ~IEEE80211_HT_CAP_MAX_AMSDU;
+
/*
*Maximum length of AMPDU that the STA can receive.
*Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets)
@@ -159,35 +213,93 @@ static void _rtl_init_hw_ht_capab(struct

static void _rtl_init_mac80211(struct ieee80211_hw *hw)
{
- struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw));
- struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+ struct rtl_mac *rtlmac = rtl_mac(rtlpriv);
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
struct ieee80211_supported_band *sband;

- /* <1> use mac->bands as mem for hw->wiphy->bands */
- sband = &(rtlmac->bands[IEEE80211_BAND_2GHZ]);
+ if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY &&
+ rtlhal->bandset == BAND_ON_BOTH) {
+ /* 1: 2.4 G bands */
+ /* <1> use mac->bands as mem for hw->wiphy->bands */
+ sband = &(rtlmac->bands[IEEE80211_BAND_2GHZ]);
+
+ /* <2> set hw->wiphy->bands[IEEE80211_BAND_2GHZ]
+ * to default value(1T1R) */
+ memcpy(&(rtlmac->bands[IEEE80211_BAND_2GHZ]), &rtl_band_2ghz,
+ sizeof(struct ieee80211_supported_band));
+
+ /* <3> init ht cap base on ant_num */
+ _rtl_init_hw_ht_capab(hw, &sband->ht_cap);
+
+ /* <4> set mac->sband to wiphy->sband */
+ hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband;
+
+ /* 2: 5 G bands */
+ /* <1> use mac->bands as mem for hw->wiphy->bands */
+ sband = &(rtlmac->bands[IEEE80211_BAND_5GHZ]);
+
+ /* <2> set hw->wiphy->bands[IEEE80211_BAND_5GHZ]
+ * to default value(1T1R) */
+ memcpy(&(rtlmac->bands[IEEE80211_BAND_5GHZ]), &rtl_band_5ghz,
+ sizeof(struct ieee80211_supported_band));

- /*
- * <2> set hw->wiphy->bands[IEEE80211_BAND_2GHZ]
- * to default value(1T1R)
- */
- memcpy(&(rtlmac->bands[IEEE80211_BAND_2GHZ]), &rtl_band_2ghz,
- sizeof(struct ieee80211_supported_band));
+ /* <3> init ht cap base on ant_num */
+ _rtl_init_hw_ht_capab(hw, &sband->ht_cap);

- /* <3> init ht cap base on ant_num */
- _rtl_init_hw_ht_capab(hw, &sband->ht_cap);
+ /* <4> set mac->sband to wiphy->sband */
+ hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband;
+ } else {
+ if (rtlhal->current_bandtype == BAND_ON_2_4G) {
+ /* <1> use mac->bands as mem for hw->wiphy->bands */
+ sband = &(rtlmac->bands[IEEE80211_BAND_2GHZ]);
+
+ /* <2> set hw->wiphy->bands[IEEE80211_BAND_2GHZ]
+ * to default value(1T1R) */
+ memcpy(&(rtlmac->bands[IEEE80211_BAND_2GHZ]),
+ &rtl_band_2ghz,
+ sizeof(struct ieee80211_supported_band));
+
+ /* <3> init ht cap base on ant_num */
+ _rtl_init_hw_ht_capab(hw, &sband->ht_cap);
+
+ /* <4> set mac->sband to wiphy->sband */
+ hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband;
+ } else if (rtlhal->current_bandtype == BAND_ON_5G) {
+ /* <1> use mac->bands as mem for hw->wiphy->bands */
+ sband = &(rtlmac->bands[IEEE80211_BAND_5GHZ]);
+
+ /* <2> set hw->wiphy->bands[IEEE80211_BAND_5GHZ]
+ * to default value(1T1R) */
+ memcpy(&(rtlmac->bands[IEEE80211_BAND_5GHZ]),
+ &rtl_band_5ghz,
+ sizeof(struct ieee80211_supported_band));

- /* <4> set mac->sband to wiphy->sband */
- hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband;
+ /* <3> init ht cap base on ant_num */
+ _rtl_init_hw_ht_capab(hw, &sband->ht_cap);

+ /* <4> set mac->sband to wiphy->sband */
+ hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband;
+ } else {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
+ ("Err BAND %d\n", rtlhal->current_bandtype));
+ }
+ }
/* <5> set hw caps */
hw->flags = IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_RX_INCLUDES_FCS |
- IEEE80211_HW_BEACON_FILTER | IEEE80211_HW_AMPDU_AGGREGATION | /*PS*/
- /*IEEE80211_HW_SUPPORTS_PS | */
- /*IEEE80211_HW_PS_NULLFUNC_STACK | */
- /*IEEE80211_HW_SUPPORTS_DYNAMIC_PS | */
+ IEEE80211_HW_BEACON_FILTER |
+ IEEE80211_HW_AMPDU_AGGREGATION |
IEEE80211_HW_REPORTS_TX_ACK_STATUS | 0;

+ /* swlps or hwlps has been set in diff chip in init_sw_vars */
+ if (rtlpriv->psc.swctrl_lps)
+ hw->flags |= IEEE80211_HW_SUPPORTS_PS |
+ IEEE80211_HW_PS_NULLFUNC_STACK |
+ /* IEEE80211_HW_SUPPORTS_DYNAMIC_PS | */
+ 0;
+
hw->wiphy->interface_modes =
BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);

@@ -199,7 +311,7 @@ static void _rtl_init_mac80211(struct ie
/* TODO: Correct this value for our hw */
/* TODO: define these hard code value */
hw->channel_change_time = 100;
- hw->max_listen_interval = 5;
+ hw->max_listen_interval = 10;
hw->max_rate_tries = 4;
/* hw->max_rates = 1; */

@@ -230,6 +342,10 @@ static void _rtl_init_deferred_work(stru
(void *)rtl_watchdog_wq_callback);
INIT_DELAYED_WORK(&rtlpriv->works.ips_nic_off_wq,
(void *)rtl_ips_nic_off_wq_callback);
+ INIT_DELAYED_WORK(&rtlpriv->works.ps_work,
+ (void *)rtl_swlps_wq_callback);
+ INIT_DELAYED_WORK(&rtlpriv->works.ps_rfon_wq,
+ (void *)rtl_swlps_rfon_wq_callback);

}

@@ -241,6 +357,8 @@ void rtl_deinit_deferred_work(struct iee

cancel_delayed_work(&rtlpriv->works.watchdog_wq);
cancel_delayed_work(&rtlpriv->works.ips_nic_off_wq);
+ cancel_delayed_work(&rtlpriv->works.ps_work);
+ cancel_delayed_work(&rtlpriv->works.ps_rfon_wq);
}

void rtl_init_rfkill(struct ieee80211_hw *hw)
@@ -251,15 +369,18 @@ void rtl_init_rfkill(struct ieee80211_hw
bool blocked;
u8 valid = 0;

- radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid);
+ /*1. set init state to on */
+ rtlpriv->rfkill.rfkill_state = 1;
+ wiphy_rfkill_set_hw_state(hw->wiphy, 0);

- /*set init state to that of switch */
- rtlpriv->rfkill.rfkill_state = radio_state;
- printk(KERN_INFO "rtlwifi: wireless switch is %s\n",
- rtlpriv->rfkill.rfkill_state ? "on" : "off");
+ /*2. check gpio for rf state */
+ radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid);

+ /*3. if valid, change state based on gpio */
if (valid) {
rtlpriv->rfkill.rfkill_state = radio_state;
+ printk(KERN_INFO "rtlwifi: wireless switch is %s\n",
+ rtlpriv->rfkill.rfkill_state ? "on" : "off");

blocked = (rtlpriv->rfkill.rfkill_state == 1) ? 0 : 1;
wiphy_rfkill_set_hw_state(hw->wiphy, blocked);
@@ -308,6 +429,8 @@ int rtl_init_core(struct ieee80211_hw *h
spin_lock_init(&rtlpriv->locks.rf_ps_lock);
spin_lock_init(&rtlpriv->locks.rf_lock);
spin_lock_init(&rtlpriv->locks.lps_lock);
+ spin_lock_init(&rtlpriv->locks.waitq_lock);
+ spin_lock_init(&rtlpriv->locks.cck_and_rw_pagea_lock);

rtlmac->link_state = MAC80211_NOLINK;

@@ -327,12 +450,6 @@ void rtl_init_rx_config(struct ieee80211
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));

rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *) (&mac->rx_conf));
- rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_MGT_FILTER,
- (u8 *) (&mac->rx_mgt_filter));
- rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_CTRL_FILTER,
- (u8 *) (&mac->rx_ctrl_filter));
- rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_DATA_FILTER,
- (u8 *) (&mac->rx_data_filter));
}

/*********************************************************
@@ -435,14 +552,16 @@ static void _rtl_txrate_selectmode(struc
/* TODO adhoc and station handled differently in the future */
tcb_desc->mac_id = 0;

- if ((mac->mode == WIRELESS_MODE_N_24G) ||
- (mac->mode == WIRELESS_MODE_N_5G)) {
+ if (mac->mode == WIRELESS_MODE_N_24G)
tcb_desc->ratr_index = RATR_INX_WIRELESS_NGB;
- } else if (mac->mode & WIRELESS_MODE_G) {
+ else if (mac->mode == WIRELESS_MODE_N_5G)
+ tcb_desc->ratr_index = RATR_INX_WIRELESS_NG;
+ else if (mac->mode & WIRELESS_MODE_G)
tcb_desc->ratr_index = RATR_INX_WIRELESS_GB;
- } else if (mac->mode & WIRELESS_MODE_B) {
+ else if (mac->mode & WIRELESS_MODE_B)
tcb_desc->ratr_index = RATR_INX_WIRELESS_B;
- }
+ else if (mac->mode & WIRELESS_MODE_A)
+ tcb_desc->ratr_index = RATR_INX_WIRELESS_G;
}

}
@@ -492,14 +611,13 @@ void rtl_get_tcb_desc(struct ieee80211_h
struct ieee80211_rate *txrate;
__le16 fc = hdr->frame_control;

- memset(tcb_desc, 0, sizeof(struct rtl_tcb_desc));
+ txrate = ieee80211_get_tx_rate(hw, info);
+ tcb_desc->hw_rate = txrate->hw_value;

if (ieee80211_is_data(fc)) {
- txrate = ieee80211_get_tx_rate(hw, info);
- tcb_desc->hw_rate = txrate->hw_value;

/*
- *we set data rate RTL_RC_CCK_RATE1M
+ *we set data rate INX 0
*in rtl_rc.c if skb is special data or
*mgt which need low data rate.
*/
@@ -508,12 +626,10 @@ void rtl_get_tcb_desc(struct ieee80211_h
*So tcb_desc->hw_rate is just used for
*special data and mgt frames
*/
- if (tcb_desc->hw_rate < rtlpriv->cfg->maps[RTL_RC_CCK_RATE11M]) {
+ if (info->control.rates[0].idx == 0) {
tcb_desc->use_driver_rate = true;
- tcb_desc->ratr_index = 7;
+ tcb_desc->ratr_index = RATR_INX_WIRELESS_MC;

- tcb_desc->hw_rate =
- rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M];
tcb_desc->disable_ratefallback = 1;
} else {
/*
@@ -528,10 +644,12 @@ void rtl_get_tcb_desc(struct ieee80211_h
} else {
if (rtlmac->mode == WIRELESS_MODE_B) {
tcb_desc->hw_rate =
- rtlpriv->cfg->maps[RTL_RC_CCK_RATE11M];
+ rtlpriv->cfg->maps
+ [RTL_RC_CCK_RATE11M];
} else {
tcb_desc->hw_rate =
- rtlpriv->cfg->maps[RTL_RC_OFDM_RATE54M];
+ rtlpriv->cfg->maps
+ [RTL_RC_OFDM_RATE54M];
}
}
}
@@ -548,11 +666,11 @@ void rtl_get_tcb_desc(struct ieee80211_h
_rtl_query_protection_mode(hw, tcb_desc, info);
} else {
tcb_desc->use_driver_rate = true;
- tcb_desc->ratr_index = 7;
+ tcb_desc->ratr_index = RATR_INX_WIRELESS_MC;
tcb_desc->disable_ratefallback = 1;
tcb_desc->mac_id = 0;

- tcb_desc->hw_rate = rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M];
+ tcb_desc->packet_bw = false;
}
}
EXPORT_SYMBOL(rtl_get_tcb_desc);
@@ -569,6 +687,8 @@ bool rtl_tx_mgmt_proc(struct ieee80211_h
rtl_ips_nic_on(hw);

mac->link_state = MAC80211_LINKING;
+ /* Dual mac */
+ rtlpriv->phy.need_iqk = true;
}

return true;
@@ -792,11 +912,8 @@ void rtl_watchdog_wq_callback(void *data
mac->cnt_after_linked = 0;
}

- /* <2> DM */
- rtlpriv->cfg->ops->dm_watchdog(hw);
-
/*
- *<3> to check if traffic busy, if
+ *<2> to check if traffic busy, if
* busytraffic we don't change channel
*/
if (mac->link_state >= MAC80211_LINKED) {
@@ -858,6 +975,8 @@ void rtl_watchdog_wq_callback(void *data
rtlpriv->link_info.higher_busytraffic = higher_busytraffic;
rtlpriv->link_info.higher_busyrxtraffic = higher_busyrxtraffic;

+ /* <3> DM */
+ rtlpriv->cfg->ops->dm_watchdog(hw);
}

void rtl_watch_dog_timer_callback(unsigned long data)
@@ -874,6 +993,180 @@ void rtl_watch_dog_timer_callback(unsign

/*********************************************************
*
+ * frame process functions
+ *
+ *********************************************************/
+u8 *rtl_find_ie(u8 *data, unsigned int len, u8 ie)
+{
+ struct ieee80211_mgmt *mgmt = (void *)data;
+ u8 *pos, *end;
+
+ pos = (u8 *)mgmt->u.beacon.variable;
+ end = data + len;
+ while (pos < end) {
+ if (pos + 2 + pos[1] > end)
+ return NULL;
+
+ if (pos[0] == ie)
+ return pos;
+
+ pos += 2 + pos[1];
+ }
+ return NULL;
+}
+
+/*********************************************************
+ *
+ * IOT functions
+ *
+ *********************************************************/
+static bool rtl_chk_vendor_ouisub(struct ieee80211_hw *hw,
+ struct octet_string vendor_ie)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ bool matched = false;
+ static u8 athcap_1[] = { 0x00, 0x03, 0x7F };
+ static u8 athcap_2[] = { 0x00, 0x13, 0x74 };
+ static u8 broadcap_1[] = { 0x00, 0x10, 0x18 };
+ static u8 broadcap_2[] = { 0x00, 0x0a, 0xf7 };
+ static u8 broadcap_3[] = { 0x00, 0x05, 0xb5 };
+ static u8 racap[] = { 0x00, 0x0c, 0x43 };
+ static u8 ciscocap[] = { 0x00, 0x40, 0x96 };
+ static u8 marvcap[] = { 0x00, 0x50, 0x43 };
+
+ if (memcmp(vendor_ie.octet, athcap_1, 3) == 0 ||
+ memcmp(vendor_ie.octet, athcap_2, 3) == 0) {
+ rtlpriv->mac80211.vendor = PEER_ATH;
+ matched = true;
+ } else if (memcmp(vendor_ie.octet, broadcap_1, 3) == 0 ||
+ memcmp(vendor_ie.octet, broadcap_2, 3) == 0 ||
+ memcmp(vendor_ie.octet, broadcap_3, 3) == 0) {
+ rtlpriv->mac80211.vendor = PEER_BROAD;
+ matched = true;
+ } else if (memcmp(vendor_ie.octet, racap, 3) == 0) {
+ rtlpriv->mac80211.vendor = PEER_RAL;
+ matched = true;
+ } else if (memcmp(vendor_ie.octet, ciscocap, 3) == 0) {
+ rtlpriv->mac80211.vendor = PEER_CISCO;
+ matched = true;
+ } else if (memcmp(vendor_ie.octet, marvcap, 3) == 0) {
+ rtlpriv->mac80211.vendor = PEER_MARV;
+ matched = true;
+ }
+
+ return matched;
+}
+
+static bool rtl_find_221_ie(struct ieee80211_hw *hw, u8 *data,
+ unsigned int len)
+{
+ struct ieee80211_mgmt *mgmt = (void *)data;
+ struct octet_string vendor_ie;
+ u8 *pos, *end;
+
+ pos = (u8 *)mgmt->u.beacon.variable;
+ end = data + len;
+ while (pos < end) {
+ if (pos[0] == 221) {
+ vendor_ie.length = pos[1];
+ vendor_ie.octet = &pos[2];
+ if (rtl_chk_vendor_ouisub(hw, vendor_ie))
+ return true;
+ }
+
+ if (pos + 2 + pos[1] > end)
+ return false;
+
+ pos += 2 + pos[1];
+ }
+ return false;
+}
+
+void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct ieee80211_hdr *hdr = (void *)data;
+ u32 vendor = PEER_UNKNOWN;
+
+ static u8 ap3_1[3] = { 0x00, 0x14, 0xbf };
+ static u8 ap3_2[3] = { 0x00, 0x1a, 0x70 };
+ static u8 ap3_3[3] = { 0x00, 0x1d, 0x7e };
+ static u8 ap4_1[3] = { 0x00, 0x90, 0xcc };
+ static u8 ap4_2[3] = { 0x00, 0x0e, 0x2e };
+ static u8 ap4_3[3] = { 0x00, 0x18, 0x02 };
+ static u8 ap4_4[3] = { 0x00, 0x17, 0x3f };
+ static u8 ap4_5[3] = { 0x00, 0x1c, 0xdf };
+ static u8 ap5_1[3] = { 0x00, 0x1c, 0xf0 };
+ static u8 ap5_2[3] = { 0x00, 0x21, 0x91 };
+ static u8 ap5_3[3] = { 0x00, 0x24, 0x01 };
+ static u8 ap5_4[3] = { 0x00, 0x15, 0xe9 };
+ static u8 ap5_5[3] = { 0x00, 0x17, 0x9A };
+ static u8 ap5_6[3] = { 0x00, 0x18, 0xE7 };
+ static u8 ap6_1[3] = { 0x00, 0x17, 0x94 };
+ static u8 ap7_1[3] = { 0x00, 0x14, 0xa4 };
+
+ if (mac->link_state == MAC80211_NOLINK) {
+ mac->vendor = PEER_UNKNOWN;
+ return;
+ }
+
+ if (mac->cnt_after_linked > 2)
+ return;
+
+ /* check if this really is a beacon */
+ if (!ieee80211_is_beacon(hdr->frame_control))
+ return;
+
+ /* min. beacon length + FCS_LEN */
+ if (len <= 40 + FCS_LEN)
+ return;
+
+ /* and only beacons from the associated BSSID, please */
+ if (compare_ether_addr(hdr->addr3, rtlpriv->mac80211.bssid))
+ return;
+
+ if (rtl_find_221_ie(hw, data, len))
+ vendor = mac->vendor;
+
+ if ((memcmp(mac->bssid, ap5_1, 3) == 0) ||
+ (memcmp(mac->bssid, ap5_2, 3) == 0) ||
+ (memcmp(mac->bssid, ap5_3, 3) == 0) ||
+ (memcmp(mac->bssid, ap5_4, 3) == 0) ||
+ (memcmp(mac->bssid, ap5_5, 3) == 0) ||
+ (memcmp(mac->bssid, ap5_6, 3) == 0) ||
+ vendor == PEER_ATH) {
+ vendor = PEER_ATH;
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>ath find\n"));
+ } else if ((memcmp(mac->bssid, ap4_4, 3) == 0) ||
+ (memcmp(mac->bssid, ap4_5, 3) == 0) ||
+ (memcmp(mac->bssid, ap4_1, 3) == 0) ||
+ (memcmp(mac->bssid, ap4_2, 3) == 0) ||
+ (memcmp(mac->bssid, ap4_3, 3) == 0) ||
+ vendor == PEER_RAL) {
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>ral findn\n"));
+ vendor = PEER_RAL;
+ } else if (memcmp(mac->bssid, ap6_1, 3) == 0 ||
+ vendor == PEER_CISCO) {
+ vendor = PEER_CISCO;
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>cisco find\n"));
+ } else if ((memcmp(mac->bssid, ap3_1, 3) == 0) ||
+ (memcmp(mac->bssid, ap3_2, 3) == 0) ||
+ (memcmp(mac->bssid, ap3_3, 3) == 0) ||
+ vendor == PEER_BROAD) {
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>broad find\n"));
+ vendor = PEER_BROAD;
+ } else if (memcmp(mac->bssid, ap7_1, 3) == 0 ||
+ vendor == PEER_MARV) {
+ vendor = PEER_MARV;
+ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>marv find\n"));
+ }
+
+ mac->vendor = vendor;
+}
+
+/*********************************************************
+ *
* sysfs functions
*
*********************************************************/
@@ -939,6 +1232,9 @@ static int __init rtl_core_module_init(v
if (rtl_rate_control_register())
printk(KERN_ERR "rtlwifi: Unable to register rtl_rc,"
"use default RC !!\n");
+ /* add proc for debug */
+ rtl_proc_add_topdir();
+
return 0;
}

@@ -946,6 +1242,9 @@ static void __exit rtl_core_module_exit(
{
/*RC*/
rtl_rate_control_unregister();
+
+ /* remove proc for debug */
+ rtl_proc_remove_topdir();
}

module_init(rtl_core_module_init);
Index: wireless-testing/drivers/net/wireless/rtlwifi/debug.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/rtlwifi/debug.c
+++ wireless-testing/drivers/net/wireless/rtlwifi/debug.c
@@ -27,6 +27,7 @@
*****************************************************************************/

#include "wifi.h"
+#include "cam.h"

void rtl_dbgp_flag_init(struct ieee80211_hw *hw)
{
@@ -48,3 +49,804 @@ void rtl_dbgp_flag_init(struct ieee80211

/*Init Debug flag enable condition */
}
+
+static struct proc_dir_entry *proc_topdir;
+
+static int rtl_proc_get_mac_0(char *page, char **start,
+ off_t offset, int count, int *eof, void *data)
+{
+ struct ieee80211_hw *hw = data;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ int len = 0;
+ int i, n, page0;
+ int max = 0xff;
+ page0 = 0x000;
+
+ for (n = 0; n <= max; ) {
+ len += snprintf(page + len, count - len, "\n%8.8x ",
+ n + page0);
+ for (i = 0; i < 4 && n <= max; i++, n += 4)
+ len += snprintf(page + len, count - len,
+ "%8.8x ",
+ rtl_read_dword(rtlpriv, (page0 | n)));
+ }
+
+ len += snprintf(page + len, count - len, "\n");
+ *eof = 1;
+ return len;
+
+}
+
+static int rtl_proc_get_mac_1(char *page, char **start,
+ off_t offset, int count, int *eof, void *data)
+{
+ struct ieee80211_hw *hw = data;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ int len = 0;
+ int i, n, page0;
+ int max = 0xff;
+ page0 = 0x100;
+
+ for (n = 0; n <= max; ) {
+ len += snprintf(page + len, count - len, "\n%8.8x ",
+ n + page0);
+ for (i = 0; i < 4 && n <= max; i++, n += 4)
+ len += snprintf(page + len, count - len,
+ "%8.8x ",
+ rtl_read_dword(rtlpriv, (page0 | n)));
+ }
+
+ len += snprintf(page + len, count - len, "\n");
+ *eof = 1;
+ return len;
+
+}
+static int rtl_proc_get_mac_2(char *page, char **start,
+ off_t offset, int count, int *eof, void *data)
+{
+ struct ieee80211_hw *hw = data;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ int len = 0;
+ int i, n, page0;
+ int max = 0xff;
+ page0 = 0x200;
+
+ for (n = 0; n <= max; ) {
+ len += snprintf(page + len, count - len, "\n%8.8x ",
+ n + page0);
+ for (i = 0; i < 4 && n <= max; i++, n += 4)
+ len += snprintf(page + len, count - len,
+ "%8.8x ",
+ rtl_read_dword(rtlpriv, (page0 | n)));
+ }
+
+ len += snprintf(page + len, count - len, "\n");
+ *eof = 1;
+ return len;
+
+}
+
+static int rtl_proc_get_mac_3(char *page, char **start,
+ off_t offset, int count, int *eof, void *data)
+{
+ struct ieee80211_hw *hw = data;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ int len = 0;
+ int i, n, page0;
+ int max = 0xff;
+ page0 = 0x300;
+
+ for (n = 0; n <= max; ) {
+ len += snprintf(page + len, count - len, "\n%8.8x ",
+ n + page0);
+ for (i = 0; i < 4 && n <= max; i++, n += 4)
+ len += snprintf(page + len, count - len,
+ "%8.8x ",
+ rtl_read_dword(rtlpriv, (page0 | n)));
+ }
+
+ len += snprintf(page + len, count - len, "\n");
+ *eof = 1;
+ return len;
+
+}
+
+static int rtl_proc_get_mac_4(char *page, char **start,
+ off_t offset, int count, int *eof, void *data)
+{
+ struct ieee80211_hw *hw = data;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ int len = 0;
+ int i, n, page0;
+ int max = 0xff;
+ page0 = 0x400;
+
+ for (n = 0; n <= max; ) {
+ len += snprintf(page + len, count - len, "\n%8.8x ",
+ n + page0);
+ for (i = 0; i < 4 && n <= max; i++, n += 4)
+ len += snprintf(page + len, count - len,
+ "%8.8x ",
+ rtl_read_dword(rtlpriv, (page0 | n)));
+ }
+
+ len += snprintf(page + len, count - len, "\n");
+ *eof = 1;
+ return len;
+
+}
+
+static int rtl_proc_get_mac_5(char *page, char **start,
+ off_t offset, int count, int *eof, void *data)
+{
+ struct ieee80211_hw *hw = data;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ int len = 0;
+ int i, n, page0;
+ int max = 0xff;
+ page0 = 0x500;
+
+ for (n = 0; n <= max; ) {
+ len += snprintf(page + len, count - len, "\n%8.8x ",
+ n + page0);
+ for (i = 0; i < 4 && n <= max; i++, n += 4)
+ len += snprintf(page + len, count - len,
+ "%8.8x ",
+ rtl_read_dword(rtlpriv, (page0 | n)));
+ }
+
+ len += snprintf(page + len, count - len, "\n");
+ *eof = 1;
+ return len;
+
+}
+
+static int rtl_proc_get_mac_6(char *page, char **start,
+ off_t offset, int count,
+ int *eof, void *data)
+{
+ struct ieee80211_hw *hw = data;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ int len = 0;
+ int i, n, page0;
+ int max = 0xff;
+ page0 = 0x600;
+
+ for (n = 0; n <= max; ) {
+ len += snprintf(page + len, count - len, "\n%8.8x ",
+ n + page0);
+ for (i = 0; i < 4 && n <= max; i++, n += 4)
+ len += snprintf(page + len, count - len,
+ "%8.8x ",
+ rtl_read_dword(rtlpriv, (page0 | n)));
+ }
+
+ len += snprintf(page + len, count - len, "\n");
+ *eof = 1;
+ return len;
+
+}
+static int rtl_proc_get_mac_7(char *page, char **start,
+ off_t offset, int count, int *eof, void *data)
+{
+ struct ieee80211_hw *hw = data;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ int len = 0;
+ int i, n, page0;
+ int max = 0xff;
+ page0 = 0x700;
+
+ for (n = 0; n <= max; ) {
+ len += snprintf(page + len, count - len, "\n%8.8x ",
+ n + page0);
+ for (i = 0; i < 4 && n <= max; i++, n += 4)
+ len += snprintf(page + len, count - len,
+ "%8.8x ",
+ rtl_read_dword(rtlpriv, (page0 | n)));
+ }
+
+ len += snprintf(page + len, count - len, "\n");
+ *eof = 1;
+ return len;
+
+}
+
+static int rtl_proc_get_bb_8(char *page, char **start,
+ off_t offset, int count, int *eof, void *data)
+{
+ struct ieee80211_hw *hw = data;
+ int len = 0;
+ int i, n, page0;
+ int max = 0xff;
+ page0 = 0x800;
+
+ for (n = 0; n <= max; ) {
+ len += snprintf(page + len, count - len, "\n%#8.8x ",
+ n + page0);
+ for (i = 0; i < 4 && n <= max; n += 4, i++)
+ len += snprintf(page + len, count - len,
+ "%8.8x ",
+ rtl_get_bbreg(hw, (page0 | n),
+ 0xffffffff));
+ }
+
+ len += snprintf(page + len, count - len, "\n");
+ *eof = 1;
+ return len;
+
+}
+static int rtl_proc_get_bb_9(char *page, char **start,
+ off_t offset, int count, int *eof, void *data)
+{
+ struct ieee80211_hw *hw = data;
+ int len = 0;
+ int i, n, page0;
+ int max = 0xff;
+ page0 = 0x900;
+
+ for (n = 0; n <= max; ) {
+ len += snprintf(page + len, count - len, "\n%#8.8x ",
+ n + page0);
+ for (i = 0; i < 4 && n <= max; n += 4, i++)
+ len += snprintf(page + len, count - len,
+ "%8.8x ",
+ rtl_get_bbreg(hw, (page0 | n),
+ 0xffffffff));
+ }
+
+ len += snprintf(page + len, count - len, "\n");
+ *eof = 1;
+ return len;
+}
+
+static int rtl_proc_get_bb_a(char *page, char **start,
+ off_t offset, int count, int *eof, void *data)
+{
+ struct ieee80211_hw *hw = data;
+ int len = 0;
+ int i, n, page0;
+ int max = 0xff;
+ page0 = 0xa00;
+
+ for (n = 0; n <= max; ) {
+ len += snprintf(page + len, count - len, "\n%#8.8x ",
+ n + page0);
+ for (i = 0; i < 4 && n <= max; n += 4, i++)
+ len += snprintf(page + len, count - len,
+ "%8.8x ",
+ rtl_get_bbreg(hw, (page0 | n),
+ 0xffffffff));
+ }
+
+ len += snprintf(page + len, count - len, "\n");
+ *eof = 1;
+ return len;
+}
+
+static int rtl_proc_get_bb_b(char *page, char **start,
+ off_t offset, int count, int *eof, void *data)
+{
+ struct ieee80211_hw *hw = data;
+ int len = 0;
+ int i, n, page0;
+ int max = 0xff;
+ page0 = 0xb00;
+
+ for (n = 0; n <= max; ) {
+ len += snprintf(page + len, count - len, "\n%#8.8x ",
+ n + page0);
+ for (i = 0; i < 4 && n <= max; n += 4, i++)
+ len += snprintf(page + len, count - len,
+ "%8.8x ",
+ rtl_get_bbreg(hw, (page0 | n),
+ 0xffffffff));
+ }
+
+ len += snprintf(page + len, count - len, "\n");
+ *eof = 1;
+ return len;
+}
+static int rtl_proc_get_bb_c(char *page, char **start,
+ off_t offset, int count, int *eof, void *data)
+{
+ struct ieee80211_hw *hw = data;
+ int len = 0;
+ int i, n, page0;
+ int max = 0xff;
+ page0 = 0xc00;
+
+ for (n = 0; n <= max; ) {
+ len += snprintf(page + len, count - len, "\n%#8.8x ",
+ n + page0);
+ for (i = 0; i < 4 && n <= max; n += 4, i++)
+ len += snprintf(page + len, count - len,
+ "%8.8x ",
+ rtl_get_bbreg(hw, (page0 | n),
+ 0xffffffff));
+ }
+
+ len += snprintf(page + len, count - len, "\n");
+ *eof = 1;
+ return len;
+}
+static int rtl_proc_get_bb_d(char *page, char **start,
+ off_t offset, int count, int *eof, void *data)
+{
+ struct ieee80211_hw *hw = data;
+ int len = 0;
+ int i, n, page0;
+ int max = 0xff;
+ page0 = 0xd00;
+
+ for (n = 0; n <= max; ) {
+ len += snprintf(page + len, count - len, "\n%#8.8x ",
+ n + page0);
+ for (i = 0; i < 4 && n <= max; n += 4, i++)
+ len += snprintf(page + len, count - len,
+ "%8.8x ",
+ rtl_get_bbreg(hw, (page0 | n),
+ 0xffffffff));
+ }
+
+ len += snprintf(page + len, count - len, "\n");
+ *eof = 1;
+ return len;
+}
+
+static int rtl_proc_get_bb_e(char *page, char **start,
+ off_t offset, int count, int *eof, void *data)
+{
+ struct ieee80211_hw *hw = data;
+ int len = 0;
+ int i, n, page0;
+ int max = 0xff;
+ page0 = 0xe00;
+
+ for (n = 0; n <= max; ) {
+ len += snprintf(page + len, count - len, "\n%#8.8x ",
+ n + page0);
+ for (i = 0; i < 4 && n <= max; n += 4, i++)
+ len += snprintf(page + len, count - len,
+ "%8.8x ",
+ rtl_get_bbreg(hw, (page0 | n),
+ 0xffffffff));
+ }
+
+ len += snprintf(page + len, count - len, "\n");
+ *eof = 1;
+ return len;
+}
+
+static int rtl_proc_get_bb_f(char *page, char **start,
+ off_t offset, int count, int *eof, void *data)
+{
+ struct ieee80211_hw *hw = data;
+ int len = 0;
+ int i, n, page0;
+ int max = 0xff;
+ page0 = 0xf00;
+
+ for (n = 0; n <= max; ) {
+ len += snprintf(page + len, count - len, "\n%#8.8x ",
+ n + page0);
+ for (i = 0; i < 4 && n <= max; n += 4, i++)
+ len += snprintf(page + len, count - len,
+ "%8.8x ",
+ rtl_get_bbreg(hw, (page0 | n),
+ 0xffffffff));
+ }
+
+ len += snprintf(page + len, count - len, "\n");
+ *eof = 1;
+ return len;
+}
+
+static int rtl_proc_get_reg_rf_a(char *page, char **start,
+ off_t offset, int count, int *eof, void *data)
+{
+ struct ieee80211_hw *hw = data;
+ int len = 0;
+ int i, n;
+ int max = 0x40;
+
+ for (n = 0; n <= max; ) {
+ len += snprintf(page + len, count - len, "\n%#8.8x ", n);
+ for (i = 0; i < 4 && n <= max; n += 1, i++)
+ len += snprintf(page + len, count - len,
+ "%8.8x ",
+ rtl_get_rfreg(hw, RF90_PATH_A, n,
+ 0xffffffff));
+ }
+
+ len += snprintf(page + len, count - len, "\n");
+ *eof = 1;
+ return len;
+}
+
+static int rtl_proc_get_reg_rf_b(char *page, char **start,
+ off_t offset, int count, int *eof, void *data)
+{
+ struct ieee80211_hw *hw = data;
+ int len = 0;
+ int i, n;
+ int max = 0x40;
+
+ for (n = 0; n <= max; ) {
+ len += snprintf(page + len, count - len, "\n%#8.8x ", n);
+ for (i = 0; i < 4 && n <= max; n += 1, i++)
+ len += snprintf(page + len, count - len,
+ "%8.8x ",
+ rtl_get_rfreg(hw, RF90_PATH_B, n,
+ 0xffffffff));
+ }
+
+ len += snprintf(page + len, count - len, "\n");
+ *eof = 1;
+ return len;
+}
+
+static int rtl_proc_get_cam_register_1(char *page, char **start,
+ off_t offset, int count, int *eof, void *data)
+{
+ struct ieee80211_hw *hw = data;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u32 target_cmd = 0;
+ u32 target_val = 0;
+ u8 entry_i = 0;
+ u32 ulstatus;
+ int len = 0;
+ int i = 100, j = 0;
+
+ /* This dump the current register page */
+ len += snprintf(page + len, count - len,
+ "\n################# SECURITY CAM (0-10) ################\n ");
+
+ for (j = 0; j < 11; j++) {
+ len += snprintf(page + len, count - len, "\nD: %2x > ", j);
+ for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
+ /* polling bit, and No Write enable, and address */
+ target_cmd = entry_i + CAM_CONTENT_COUNT * j;
+ target_cmd = target_cmd | BIT(31);
+
+ /* Check polling bit is clear */
+ while ((i--) >= 0) {
+ ulstatus = rtl_read_dword(rtlpriv,
+ rtlpriv->cfg->maps[RWCAM]);
+ if (ulstatus & BIT(31))
+ continue;
+ else
+ break;
+ }
+
+ rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
+ target_cmd);
+ target_val = rtl_read_dword(rtlpriv,
+ rtlpriv->cfg->maps[RCAMO]);
+ len += snprintf(page + len, count - len, "%8.8x ",
+ target_val);
+ }
+ }
+
+ len += snprintf(page + len, count - len, "\n");
+ *eof = 1;
+ return len;
+}
+
+static int rtl_proc_get_cam_register_2(char *page, char **start,
+ off_t offset, int count, int *eof, void *data)
+{
+ struct ieee80211_hw *hw = data;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u32 target_cmd = 0;
+ u32 target_val = 0;
+ u8 entry_i = 0;
+ u32 ulstatus;
+ int len = 0;
+ int i = 100, j = 0;
+
+ /* This dump the current register page */
+ len += snprintf(page + len, count - len,
+ "\n################# SECURITY CAM (11-21) ###############\n ");
+
+ for (j = 11; j < 22; j++) {
+ len += snprintf(page + len, count - len, "\nD: %2x > ", j);
+ for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
+ target_cmd = entry_i + CAM_CONTENT_COUNT * j;
+ target_cmd = target_cmd | BIT(31);
+
+ while ((i--) >= 0) {
+ ulstatus = rtl_read_dword(rtlpriv,
+ rtlpriv->cfg->maps[RWCAM]);
+ if (ulstatus & BIT(31))
+ continue;
+ else
+ break;
+ }
+
+ rtl_write_dword(rtlpriv,
+ rtlpriv->cfg->maps[RWCAM], target_cmd);
+ target_val = rtl_read_dword(rtlpriv,
+ rtlpriv->cfg->maps[RCAMO]);
+ len += snprintf(page + len, count - len, "%8.8x ",
+ target_val);
+ }
+ }
+
+ len += snprintf(page + len, count - len, "\n");
+ *eof = 1;
+ return len;
+}
+
+static int rtl_proc_get_cam_register_3(char *page, char **start,
+ off_t offset, int count, int *eof, void *data)
+{
+ struct ieee80211_hw *hw = data;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u32 target_cmd = 0;
+ u32 target_val = 0;
+ u8 entry_i = 0;
+ u32 ulstatus;
+ int len = 0;
+ int i = 100, j = 0;
+
+ /* This dump the current register page */
+ len += snprintf(page + len, count - len,
+ "\n################## SECURITY CAM (22-31) ##############\n ");
+
+ for (j = 22; j < TOTAL_CAM_ENTRY; j++) {
+ len += snprintf(page + len, count - len, "\nD: %2x > ", j);
+ for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
+ target_cmd = entry_i+CAM_CONTENT_COUNT*j;
+ target_cmd = target_cmd | BIT(31);
+
+ while ((i--) >= 0) {
+ ulstatus = rtl_read_dword(rtlpriv,
+ rtlpriv->cfg->maps[RWCAM]);
+ if (ulstatus & BIT(31))
+ continue;
+ else
+ break;
+ }
+
+ rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
+ target_cmd);
+ target_val = rtl_read_dword(rtlpriv,
+ rtlpriv->cfg->maps[RCAMO]);
+ len += snprintf(page + len, count - len,
+ "%8.8x ", target_val);
+ }
+ }
+
+ len += snprintf(page + len, count - len, "\n");
+ *eof = 1;
+ return len;
+}
+
+void rtl_proc_add_one(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ struct proc_dir_entry *entry;
+
+ snprintf(rtlpriv->dbg.proc_name, 18, "%x-%x-%x-%x-%x-%x",
+ rtlefuse->dev_addr[0], rtlefuse->dev_addr[1],
+ rtlefuse->dev_addr[2], rtlefuse->dev_addr[3],
+ rtlefuse->dev_addr[4], rtlefuse->dev_addr[5]);
+
+ rtlpriv->dbg.proc_dir = create_proc_entry(rtlpriv->dbg.proc_name,
+ S_IFDIR | S_IRUGO | S_IXUGO, proc_topdir);
+ if (!rtlpriv->dbg.proc_dir) {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, ("Unable to init "
+ "/proc/net/%s/%s\n", rtlpriv->cfg->name,
+ rtlpriv->dbg.proc_name));
+ return;
+ }
+
+ entry = create_proc_read_entry("mac-0", S_IFREG | S_IRUGO,
+ rtlpriv->dbg.proc_dir,
+ rtl_proc_get_mac_0, hw);
+ if (!entry)
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, ("Unable to initialize "
+ "/proc/net/%s/%s/mac-0\n",
+ rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+
+ entry = create_proc_read_entry("mac-1", S_IFREG | S_IRUGO,
+ rtlpriv->dbg.proc_dir,
+ rtl_proc_get_mac_1, hw);
+ if (!entry)
+ RT_TRACE(rtlpriv, COMP_INIT, COMP_ERR, ("Unable to initialize "
+ "/proc/net/%s/%s/mac-1\n",
+ rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+
+ entry = create_proc_read_entry("mac-2", S_IFREG | S_IRUGO,
+ rtlpriv->dbg.proc_dir,
+ rtl_proc_get_mac_2, hw);
+ if (!entry)
+ RT_TRACE(rtlpriv, COMP_INIT, COMP_ERR, ("Unable to initialize "
+ "/proc/net/%s/%s/mac-2\n",
+ rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+
+ entry = create_proc_read_entry("mac-3", S_IFREG | S_IRUGO,
+ rtlpriv->dbg.proc_dir,
+ rtl_proc_get_mac_3, hw);
+ if (!entry)
+ RT_TRACE(rtlpriv, COMP_INIT, COMP_ERR, ("Unable to initialize "
+ "/proc/net/%s/%s/mac-3\n",
+ rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+
+ entry = create_proc_read_entry("mac-4", S_IFREG | S_IRUGO,
+ rtlpriv->dbg.proc_dir,
+ rtl_proc_get_mac_4, hw);
+ if (!entry)
+ RT_TRACE(rtlpriv, COMP_INIT, COMP_ERR, ("Unable to initialize "
+ "/proc/net/%s/%s/mac-4\n",
+ rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+
+ entry = create_proc_read_entry("mac-5", S_IFREG | S_IRUGO,
+ rtlpriv->dbg.proc_dir,
+ rtl_proc_get_mac_5, hw);
+ if (!entry)
+ RT_TRACE(rtlpriv, COMP_INIT, COMP_ERR, ("Unable to initialize "
+ "/proc/net/%s/%s/mac-5\n",
+ rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+
+ entry = create_proc_read_entry("mac-6", S_IFREG | S_IRUGO,
+ rtlpriv->dbg.proc_dir,
+ rtl_proc_get_mac_6, hw);
+ if (!entry)
+ RT_TRACE(rtlpriv, COMP_INIT, COMP_ERR, ("Unable to initialize "
+ "/proc/net/%s/%s/mac-6\n",
+ rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+
+ entry = create_proc_read_entry("mac-7", S_IFREG | S_IRUGO,
+ rtlpriv->dbg.proc_dir,
+ rtl_proc_get_mac_7, hw);
+ if (!entry)
+ RT_TRACE(rtlpriv, COMP_INIT, COMP_ERR, ("Unable to initialize "
+ "/proc/net/%s/%s/mac-7\n",
+ rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+
+ entry = create_proc_read_entry("bb-8", S_IFREG | S_IRUGO,
+ rtlpriv->dbg.proc_dir,
+ rtl_proc_get_bb_8, hw);
+ if (!entry)
+ RT_TRACE(rtlpriv, COMP_INIT, COMP_ERR, ("Unable to initialize "
+ "/proc/net/%s/%s/bb-8\n",
+ rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+
+ entry = create_proc_read_entry("bb-9", S_IFREG | S_IRUGO,
+ rtlpriv->dbg.proc_dir,
+ rtl_proc_get_bb_9, hw);
+ if (!entry)
+ RT_TRACE(rtlpriv, COMP_INIT, COMP_ERR, ("Unable to initialize "
+ "/proc/net/%s/%s/bb-9\n",
+ rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+
+ entry = create_proc_read_entry("bb-a", S_IFREG | S_IRUGO,
+ rtlpriv->dbg.proc_dir, rtl_proc_get_bb_a, hw);
+ if (!entry)
+ RT_TRACE(rtlpriv, COMP_INIT, COMP_ERR, ("Unable to initialize "
+ "/proc/net/%s/%s/bb-a\n",
+ rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+
+ entry = create_proc_read_entry("bb-b", S_IFREG | S_IRUGO,
+ rtlpriv->dbg.proc_dir, rtl_proc_get_bb_b, hw);
+ if (!entry)
+ RT_TRACE(rtlpriv, COMP_INIT, COMP_ERR, ("Unable to initialize "
+ "/proc/net/%s/%s/bb-b\n",
+ rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+
+ entry = create_proc_read_entry("bb-c", S_IFREG | S_IRUGO,
+ rtlpriv->dbg.proc_dir, rtl_proc_get_bb_c, hw);
+ if (!entry)
+ RT_TRACE(rtlpriv, COMP_INIT, COMP_ERR, ("Unable to initialize "
+ "/proc/net/%s/%s/bb-c\n",
+ rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+
+ entry = create_proc_read_entry("bb-d", S_IFREG | S_IRUGO,
+ rtlpriv->dbg.proc_dir, rtl_proc_get_bb_d, hw);
+ if (!entry)
+ RT_TRACE(rtlpriv, COMP_INIT, COMP_ERR, ("Unable to initialize "
+ "/proc/net/%s/%s/bb-d\n",
+ rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+
+ entry = create_proc_read_entry("bb-e", S_IFREG | S_IRUGO,
+ rtlpriv->dbg.proc_dir, rtl_proc_get_bb_e, hw);
+ if (!entry)
+ RT_TRACE(rtlpriv, COMP_INIT, COMP_ERR, ("Unable to initialize "
+ "/proc/net/%s/%s/bb-e\n",
+ rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+
+ entry = create_proc_read_entry("bb-f", S_IFREG | S_IRUGO,
+ rtlpriv->dbg.proc_dir, rtl_proc_get_bb_f, hw);
+ if (!entry)
+ RT_TRACE(rtlpriv, COMP_INIT, COMP_ERR, ("Unable to initialize "
+ "/proc/net/%s/%s/bb-f\n",
+ rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+
+ entry = create_proc_read_entry("rf-a", S_IFREG | S_IRUGO,
+ rtlpriv->dbg.proc_dir,
+ rtl_proc_get_reg_rf_a, hw);
+ if (!entry)
+ RT_TRACE(rtlpriv, COMP_INIT, COMP_ERR, ("Unable to initialize "
+ "/proc/net/%s/%s/rf-a\n",
+ rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+
+ entry = create_proc_read_entry("rf-b", S_IFREG | S_IRUGO,
+ rtlpriv->dbg.proc_dir,
+ rtl_proc_get_reg_rf_b, hw);
+ if (!entry)
+ RT_TRACE(rtlpriv, COMP_INIT, COMP_ERR, ("Unable to initialize "
+ "/proc/net/%s/%s/rf-b\n",
+ rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+
+ entry = create_proc_read_entry("cam-1", S_IFREG | S_IRUGO,
+ rtlpriv->dbg.proc_dir,
+ rtl_proc_get_cam_register_1, hw);
+ if (!entry)
+ RT_TRACE(rtlpriv, COMP_INIT, COMP_ERR, ("Unable to initialize "
+ "/proc/net/%s/%s/cam-1\n",
+ rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+
+ entry = create_proc_read_entry("cam-2", S_IFREG | S_IRUGO,
+ rtlpriv->dbg.proc_dir,
+ rtl_proc_get_cam_register_2, hw);
+ if (!entry)
+ RT_TRACE(rtlpriv, COMP_INIT, COMP_ERR, ("Unable to initialize "
+ "/proc/net/%s/%s/cam-2\n",
+ rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+
+ entry = create_proc_read_entry("cam-3", S_IFREG | S_IRUGO,
+ rtlpriv->dbg.proc_dir,
+ rtl_proc_get_cam_register_3, hw);
+ if (!entry)
+ RT_TRACE(rtlpriv, COMP_INIT, COMP_ERR, ("Unable to initialize "
+ "/proc/net/%s/%s/cam-3\n",
+ rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+}
+
+void rtl_proc_remove_one(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ if (rtlpriv->dbg.proc_dir) {
+ remove_proc_entry("mac-0", rtlpriv->dbg.proc_dir);
+ remove_proc_entry("mac-1", rtlpriv->dbg.proc_dir);
+ remove_proc_entry("mac-2", rtlpriv->dbg.proc_dir);
+ remove_proc_entry("mac-3", rtlpriv->dbg.proc_dir);
+ remove_proc_entry("mac-4", rtlpriv->dbg.proc_dir);
+ remove_proc_entry("mac-5", rtlpriv->dbg.proc_dir);
+ remove_proc_entry("mac-6", rtlpriv->dbg.proc_dir);
+ remove_proc_entry("mac-7", rtlpriv->dbg.proc_dir);
+ remove_proc_entry("bb-8", rtlpriv->dbg.proc_dir);
+ remove_proc_entry("bb-9", rtlpriv->dbg.proc_dir);
+ remove_proc_entry("bb-a", rtlpriv->dbg.proc_dir);
+ remove_proc_entry("bb-b", rtlpriv->dbg.proc_dir);
+ remove_proc_entry("bb-c", rtlpriv->dbg.proc_dir);
+ remove_proc_entry("bb-d", rtlpriv->dbg.proc_dir);
+ remove_proc_entry("bb-e", rtlpriv->dbg.proc_dir);
+ remove_proc_entry("bb-f", rtlpriv->dbg.proc_dir);
+ remove_proc_entry("rf-a", rtlpriv->dbg.proc_dir);
+ remove_proc_entry("rf-b", rtlpriv->dbg.proc_dir);
+ remove_proc_entry("cam-1", rtlpriv->dbg.proc_dir);
+ remove_proc_entry("cam-2", rtlpriv->dbg.proc_dir);
+ remove_proc_entry("cam-3", rtlpriv->dbg.proc_dir);
+
+ remove_proc_entry(rtlpriv->dbg.proc_name, proc_topdir);
+
+ rtlpriv->dbg.proc_dir = NULL;
+ }
+}
+
+void rtl_proc_add_topdir(void)
+{
+ proc_topdir = create_proc_entry("rtlwifi",
+ S_IFDIR, init_net.proc_net);
+}
+
+void rtl_proc_remove_topdir(void)
+{
+ if (proc_topdir)
+ remove_proc_entry("rtlwifi", init_net.proc_net);
+}
+
Index: wireless-testing/drivers/net/wireless/rtlwifi/debug.h
===================================================================
--- wireless-testing.orig/drivers/net/wireless/rtlwifi/debug.h
+++ wireless-testing/drivers/net/wireless/rtlwifi/debug.h
@@ -210,4 +210,9 @@ enum dbgp_flag_e {
((u8 *)(x))[3], ((u8 *)(x))[4], ((u8 *)(x))[5]

void rtl_dbgp_flag_init(struct ieee80211_hw *hw);
+void rtl_proc_add_one(struct ieee80211_hw *hw);
+void rtl_proc_remove_one(struct ieee80211_hw *hw);
+void rtl_proc_add_topdir(void);
+void rtl_proc_remove_topdir(void);
+
#endif
Index: wireless-testing/drivers/net/wireless/rtlwifi/efuse.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/rtlwifi/efuse.c
+++ wireless-testing/drivers/net/wireless/rtlwifi/efuse.c
@@ -52,8 +52,6 @@ static const struct efuse_map RTL8712_SD
{11, 0, 0, 28}
};

-static void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset,
- u8 *pbuf);
static void efuse_shadow_read_1byte(struct ieee80211_hw *hw, u16 offset,
u8 *value);
static void efuse_shadow_read_2byte(struct ieee80211_hw *hw, u16 offset,
@@ -115,8 +113,10 @@ u8 efuse_read_1byte(struct ieee80211_hw
u8 bytetemp;
u8 temp;
u32 k = 0;
+ const u32 efuse_real_content_len =
+ rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE];

- if (address < EFUSE_REAL_CONTENT_LEN) {
+ if (address < efuse_real_content_len) {
temp = address & 0xFF;
rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
temp);
@@ -158,11 +158,13 @@ void efuse_write_1byte(struct ieee80211_
u8 bytetemp;
u8 temp;
u32 k = 0;
+ const u32 efuse_real_content_len =
+ rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE];

RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
("Addr=%x Data =%x\n", address, value));

- if (address < EFUSE_REAL_CONTENT_LEN) {
+ if (address < efuse_real_content_len) {
rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL], value);

temp = address & 0xFF;
@@ -198,7 +200,7 @@ void efuse_write_1byte(struct ieee80211_

}

-static void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf)
+void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u32 value32;
@@ -239,18 +241,22 @@ void read_efuse(struct ieee80211_hw *hw,
u8 offset, wren;
u16 i;
u16 j;
+ const u16 efuse_max_section =
+ rtlpriv->cfg->maps[EFUSE_MAX_SECTION_MAP];
+ const u32 efuse_real_content_len =
+ rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE];
u16 efuse_word[EFUSE_MAX_SECTION][EFUSE_MAX_WORD_UNIT];
u16 efuse_utilized = 0;
u8 efuse_usage;

- if ((_offset + _size_byte) > EFUSE_MAP_LEN) {
+ if ((_offset + _size_byte) > rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]) {
RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
("read_efuse(): Invalid offset(%#x) with read "
"bytes(%#x)!!\n", _offset, _size_byte));
return;
}

- for (i = 0; i < EFUSE_MAX_SECTION; i++)
+ for (i = 0; i < efuse_max_section; i++)
for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++)
efuse_word[i][j] = 0xFFFF;

@@ -262,10 +268,10 @@ void read_efuse(struct ieee80211_hw *hw,
efuse_addr++;
}

- while ((*rtemp8 != 0xFF) && (efuse_addr < EFUSE_REAL_CONTENT_LEN)) {
+ while ((*rtemp8 != 0xFF) && (efuse_addr < efuse_real_content_len)) {
offset = ((*rtemp8 >> 4) & 0x0f);

- if (offset < EFUSE_MAX_SECTION) {
+ if (offset < efuse_max_section) {
wren = (*rtemp8 & 0x0f);
RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL,
("offset-%d Worden=%x\n", offset, wren));
@@ -281,7 +287,8 @@ void read_efuse(struct ieee80211_hw *hw,
efuse_utilized++;
efuse_word[offset][i] = (*rtemp8 & 0xff);

- if (efuse_addr >= EFUSE_REAL_CONTENT_LEN)
+ if (efuse_addr >=
+ efuse_real_content_len)
break;

RTPRINT(rtlpriv, FEEPROM,
@@ -294,7 +301,8 @@ void read_efuse(struct ieee80211_hw *hw,
efuse_word[offset][i] |=
(((u16)*rtemp8 << 8) & 0xff00);

- if (efuse_addr >= EFUSE_REAL_CONTENT_LEN)
+ if (efuse_addr >=
+ efuse_real_content_len)
break;
}

@@ -305,13 +313,13 @@ void read_efuse(struct ieee80211_hw *hw,
RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL,
("Addr=%d\n", efuse_addr));
read_efuse_byte(hw, efuse_addr, rtemp8);
- if (*rtemp8 != 0xFF && (efuse_addr < 512)) {
+ if (*rtemp8 != 0xFF && (efuse_addr < efuse_real_content_len)) {
efuse_utilized++;
efuse_addr++;
}
}

- for (i = 0; i < EFUSE_MAX_SECTION; i++) {
+ for (i = 0; i < efuse_max_section; i++) {
for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) {
efuse_tbl[(i * 8) + (j * 2)] =
(efuse_word[i][j] & 0xff);
@@ -324,7 +332,7 @@ void read_efuse(struct ieee80211_hw *hw,
pbuf[i] = efuse_tbl[_offset + i];

rtlefuse->efuse_usedbytes = efuse_utilized;
- efuse_usage = (u8)((efuse_utilized * 100) / EFUSE_REAL_CONTENT_LEN);
+ efuse_usage = (u8) ((efuse_utilized * 100) / efuse_real_content_len);
rtlefuse->efuse_usedpercentage = efuse_usage;
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_EFUSE_BYTES,
(u8 *)&efuse_utilized);
@@ -338,11 +346,11 @@ bool efuse_shadow_update_chk(struct ieee
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
u8 section_idx, i, Base;
u16 words_need = 0, hdr_num = 0, totalbytes, efuse_used;
- bool wordchanged, result = true;
+ bool bwordchanged, result = true;

for (section_idx = 0; section_idx < 16; section_idx++) {
Base = section_idx * 8;
- wordchanged = false;
+ bwordchanged = false;

for (i = 0; i < 8; i = i + 2) {
if ((rtlefuse->efuse_map[EFUSE_INIT_MAP][Base + i] !=
@@ -351,11 +359,11 @@ bool efuse_shadow_update_chk(struct ieee
rtlefuse->efuse_map[EFUSE_MODIFY_MAP][Base + i +
1])) {
words_need++;
- wordchanged = true;
+ bwordchanged = true;
}
}

- if (wordchanged == true)
+ if (bwordchanged == true)
hdr_num++;
}

@@ -394,7 +402,7 @@ void efuse_shadow_write(struct ieee80211
else if (type == 2)
efuse_shadow_write_2byte(hw, offset, (u16) value);
else if (type == 4)
- efuse_shadow_write_4byte(hw, offset, value);
+ efuse_shadow_write_4byte(hw, offset, (u32) value);

}

@@ -478,15 +486,15 @@ void rtl_efuse_shadow_map_update(struct
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));

- if (rtlefuse->autoload_failflag == true) {
- memset((void *)(&rtlefuse->efuse_map[EFUSE_INIT_MAP][0]), 128,
- 0xFF);
- } else
+ if (rtlefuse->autoload_failflag == true)
+ memset((void *)(&rtlefuse->efuse_map[EFUSE_INIT_MAP][0]),
+ rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE], 0xFF);
+ else
efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]);

memcpy((void *)&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0],
- (void *)&rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
- rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]);
+ (void *)&rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
+ rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]);

}
EXPORT_SYMBOL(rtl_efuse_shadow_map_update);
@@ -605,6 +613,7 @@ static int efuse_one_byte_write(struct i
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u8 tmpidx = 0;
+ bool result;

RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
("Addr = %x Data=%x\n", addr, data));
@@ -626,15 +635,18 @@ static int efuse_one_byte_write(struct i
}

if (tmpidx < 100)
- return true;
+ result = true;
+ else
+ result = false;

- return false;
+ return result;
}

-static void efuse_read_all_map(struct ieee80211_hw *hw, u8 * efuse)
+static void efuse_read_all_map(struct ieee80211_hw *hw, u8 *efuse)
{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
efuse_power_switch(hw, false, true);
- read_efuse(hw, 0, 128, efuse);
+ read_efuse(hw, 0, rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE], efuse);
efuse_power_switch(hw, false, false);
}

@@ -655,16 +667,16 @@ static void efuse_read_data_case1(struct
if (hoffset == offset) {
for (tmpidx = 0; tmpidx < word_cnts * 2; tmpidx++) {
if (efuse_one_byte_read(hw, *efuse_addr + 1 + tmpidx,
- &efuse_data)) {
+ &efuse_data)) {
tmpdata[tmpidx] = efuse_data;
if (efuse_data != 0xff)
bdataempty = true;
}
}

- if (bdataempty == true)
+ if (bdataempty == true) {
*readstate = PG_STATE_DATA;
- else {
+ } else {
*efuse_addr = *efuse_addr + (word_cnts * 2) + 1;
*readstate = PG_STATE_HEADER;
}
@@ -683,6 +695,7 @@ static int efuse_pg_packet_read(struct i

u8 efuse_data, word_cnts = 0;
u16 efuse_addr = 0;
+ u8 hworden = 0;
u8 tmpdata[8];

if (data == NULL)
@@ -698,13 +711,12 @@ static int efuse_pg_packet_read(struct i
if (efuse_one_byte_read(hw, efuse_addr, &efuse_data)
&& (efuse_data != 0xFF))
efuse_read_data_case1(hw, &efuse_addr,
- efuse_data,
- offset, tmpdata,
- &readstate);
+ efuse_data, offset,
+ tmpdata, &readstate);
else
continual = false;
} else if (readstate & PG_STATE_DATA) {
- efuse_word_enable_data_read(0, tmpdata, data);
+ efuse_word_enable_data_read(hworden, tmpdata, data);
efuse_addr = efuse_addr + (word_cnts * 2) + 1;
readstate = PG_STATE_HEADER;
}
@@ -722,13 +734,14 @@ static int efuse_pg_packet_read(struct i
}

static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
- u8 efuse_data, u8 offset, int *continual,
- u8 *write_state, struct pgpkt_struct *target_pkt,
- int *repeat_times, int *result, u8 word_en)
+ u8 efuse_data, u8 offset, int *continual,
+ u8 *write_state,
+ struct pgpkt_struct *target_pkt,
+ int *repeat_times, int *result, u8 word_en)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct pgpkt_struct tmp_pkt;
- bool dataempty = true;
+ int bdataempty = true;
u8 originaldata[8 * sizeof(u8)];
u8 badworden = 0x0F;
u8 match_word_en, tmp_word_en;
@@ -745,70 +758,69 @@ static void efuse_write_data_case1(struc
*write_state = PG_STATE_HEADER;
} else {
for (tmpindex = 0; tmpindex < (tmp_word_cnts * 2); tmpindex++) {
- u16 address = *efuse_addr + 1 + tmpindex;
- if (efuse_one_byte_read(hw, address,
- &efuse_data) && (efuse_data != 0xFF))
- dataempty = false;
+ if (efuse_one_byte_read(hw, (*efuse_addr+1+tmpindex),
+ &efuse_data) && (efuse_data != 0xFF))
+ bdataempty = false;
}

- if (dataempty == false) {
+ if (bdataempty == false) {
*efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1;
*write_state = PG_STATE_HEADER;
} else {
match_word_en = 0x0F;
if (!((target_pkt->word_en & BIT(0)) |
- (tmp_pkt.word_en & BIT(0))))
+ (tmp_pkt.word_en & BIT(0))))
match_word_en &= (~BIT(0));

if (!((target_pkt->word_en & BIT(1)) |
- (tmp_pkt.word_en & BIT(1))))
+ (tmp_pkt.word_en & BIT(1))))
match_word_en &= (~BIT(1));

if (!((target_pkt->word_en & BIT(2)) |
- (tmp_pkt.word_en & BIT(2))))
+ (tmp_pkt.word_en & BIT(2))))
match_word_en &= (~BIT(2));

if (!((target_pkt->word_en & BIT(3)) |
- (tmp_pkt.word_en & BIT(3))))
+ (tmp_pkt.word_en & BIT(3))))
match_word_en &= (~BIT(3));

if ((match_word_en & 0x0F) != 0x0F) {
- badworden = efuse_word_enable_data_write(
- hw, *efuse_addr + 1,
- tmp_pkt.word_en,
- target_pkt->data);
+ badworden = efuse_word_enable_data_write(hw,
+ *efuse_addr + 1,
+ tmp_pkt.word_en, target_pkt->data);

- if (0x0F != (badworden & 0x0F)) {
+ if (0x0F != (badworden & 0x0F)) {
u8 reorg_offset = offset;
u8 reorg_worden = badworden;
efuse_pg_packet_write(hw, reorg_offset,
- reorg_worden,
- originaldata);
+ reorg_worden, originaldata);
}

tmp_word_en = 0x0F;
if ((target_pkt->word_en & BIT(0)) ^
- (match_word_en & BIT(0)))
+ (match_word_en & BIT(0)))
tmp_word_en &= (~BIT(0));

if ((target_pkt->word_en & BIT(1)) ^
- (match_word_en & BIT(1)))
+ (match_word_en & BIT(1)))
tmp_word_en &= (~BIT(1));

if ((target_pkt->word_en & BIT(2)) ^
- (match_word_en & BIT(2)))
+ (match_word_en & BIT(2)))
tmp_word_en &= (~BIT(2));

if ((target_pkt->word_en & BIT(3)) ^
- (match_word_en & BIT(3)))
+ (match_word_en & BIT(3)))
tmp_word_en &= (~BIT(3));

if ((tmp_word_en & 0x0F) != 0x0F) {
- *efuse_addr = efuse_get_current_size(hw);
+ *efuse_addr =
+ efuse_get_current_size(hw);
target_pkt->offset = offset;
target_pkt->word_en = tmp_word_en;
- } else
+ } else {
*continual = false;
+ }
*write_state = PG_STATE_HEADER;
*repeat_times += 1;
if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) {
@@ -843,9 +855,9 @@ static void efuse_write_data_case2(struc
efuse_one_byte_write(hw, *efuse_addr, pg_header);
efuse_one_byte_read(hw, *efuse_addr, &tmp_header);

- if (tmp_header == pg_header)
+ if (tmp_header == pg_header) {
*write_state = PG_STATE_DATA;
- else if (tmp_header == 0xFF) {
+ } else if (tmp_header == 0xFF) {
*write_state = PG_STATE_HEADER;
*repeat_times += 1;
if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) {
@@ -858,25 +870,27 @@ static void efuse_write_data_case2(struc

tmp_word_cnts = efuse_calculate_word_cnts(tmp_pkt.word_en);

- memset((void *)originaldata, 8 * sizeof(u8), 0xff);
+ memset((void *)originaldata, 8 * sizeof(u8), 0xff);

if (efuse_pg_packet_read(hw, tmp_pkt.offset, originaldata)) {
badworden = efuse_word_enable_data_write(hw,
- *efuse_addr + 1, tmp_pkt.word_en,
- originaldata);
+ *efuse_addr + 1,
+ tmp_pkt.word_en, originaldata);

if (0x0F != (badworden & 0x0F)) {
u8 reorg_offset = tmp_pkt.offset;
u8 reorg_worden = badworden;
efuse_pg_packet_write(hw, reorg_offset,
- reorg_worden,
- originaldata);
+ reorg_worden,
+ originaldata);
*efuse_addr = efuse_get_current_size(hw);
- } else
+ } else {
*efuse_addr = *efuse_addr + (tmp_word_cnts * 2)
+ 1;
- } else
+ }
+ } else {
*efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1;
+ }

*write_state = PG_STATE_HEADER;
*repeat_times += 1;
@@ -896,7 +910,7 @@ static int efuse_pg_packet_write(struct
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct pgpkt_struct target_pkt;
u8 write_state = PG_STATE_HEADER;
- int continual = true, dataempty = true, result = true;
+ int continual = true, bdataempty = true, result = true;
u16 efuse_addr = 0;
u8 efuse_data;
u8 target_word_cnts = 0;
@@ -913,7 +927,7 @@ static int efuse_pg_packet_write(struct
target_pkt.offset = offset;
target_pkt.word_en = word_en;

- memset((void *)target_pkt.data, 8 * sizeof(u8), 0xFF);
+ memset((void *)target_pkt.data, 8 * sizeof(u8), 0xFF);

efuse_word_enable_data_read(word_en, data, target_pkt.data);
target_word_cnts = efuse_calculate_word_cnts(target_pkt.word_en);
@@ -921,10 +935,10 @@ static int efuse_pg_packet_write(struct
RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, ("efuse Power ON\n"));

while (continual && (efuse_addr <
- (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES))) {
+ (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES))) {

if (write_state == PG_STATE_HEADER) {
- dataempty = true;
+ bdataempty = true;
badworden = 0x0F;
RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
("efuse PG_STATE_HEADER\n"));
@@ -932,22 +946,23 @@ static int efuse_pg_packet_write(struct
if (efuse_one_byte_read(hw, efuse_addr, &efuse_data) &&
(efuse_data != 0xFF))
efuse_write_data_case1(hw, &efuse_addr,
- efuse_data, offset,
- &continual,
- &write_state, &target_pkt,
- &repeat_times, &result,
- word_en);
+ efuse_data, offset,
+ &continual,
+ &write_state, &target_pkt,
+ &repeat_times, &result,
+ word_en);
else
efuse_write_data_case2(hw, &efuse_addr,
- &continual,
- &write_state,
- target_pkt,
- &repeat_times,
- &result);
+ &continual,
+ &write_state,
+ target_pkt,
+ &repeat_times,
+ &result);

} else if (write_state == PG_STATE_DATA) {
RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
("efuse PG_STATE_DATA\n"));
+ badworden = 0x0f;
badworden =
efuse_word_enable_data_write(hw, efuse_addr + 1,
target_pkt.word_en,
@@ -956,7 +971,8 @@ static int efuse_pg_packet_write(struct
if ((badworden & 0x0F) == 0x0F) {
continual = false;
} else {
- efuse_addr += (2 * target_word_cnts) + 1;
+ efuse_addr =
+ efuse_addr + (2 * target_word_cnts) + 1;

target_pkt.offset = offset;
target_pkt.word_en = badworden;
@@ -1067,13 +1083,15 @@ static u8 efuse_word_enable_data_write(s
return badworden;
}

-static void efuse_power_switch(struct ieee80211_hw *hw, u8 write, u8 pwrstate)
+static void efuse_power_switch(struct ieee80211_hw *hw, u8 bwrite, u8 pwrstate)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
u8 tempval;
u16 tmpV16;

- if (pwrstate) {
+ if (pwrstate == true && (rtlhal->hw_type !=
+ HARDWARE_TYPE_RTL8192SE)) {
tmpV16 = rtl_read_word(rtlpriv,
rtlpriv->cfg->maps[SYS_ISO_CTRL]);
if (!(tmpV16 & rtlpriv->cfg->maps[EFUSE_PWC_EV12V])) {
@@ -1101,20 +1119,29 @@ static void efuse_power_switch(struct ie
}
}

- if (pwrstate) {
- if (write) {
+ if (pwrstate == true) {
+ if (bwrite == true) {
tempval = rtl_read_byte(rtlpriv,
rtlpriv->cfg->maps[EFUSE_TEST] +
3);
- tempval &= 0x0F;
- tempval |= (VOLTAGE_V25 << 4);
+
+ if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192SE) {
+ tempval &= 0x0F;
+ tempval |= (VOLTAGE_V25 << 4);
+ }
+
rtl_write_byte(rtlpriv,
rtlpriv->cfg->maps[EFUSE_TEST] + 3,
(tempval | 0x80));
}

+ if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) {
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CLK],
+ 0x03);
+ }
+
} else {
- if (write) {
+ if (bwrite == true) {
tempval = rtl_read_byte(rtlpriv,
rtlpriv->cfg->maps[EFUSE_TEST] +
3);
@@ -1123,6 +1150,11 @@ static void efuse_power_switch(struct ie
(tempval & 0x7F));
}

+ if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) {
+ rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CLK],
+ 0x02);
+ }
+
}

}
Index: wireless-testing/drivers/net/wireless/rtlwifi/ps.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/rtlwifi/ps.c
+++ wireless-testing/drivers/net/wireless/rtlwifi/ps.c
@@ -194,10 +194,10 @@ static void _rtl_ps_inactive_ps(struct i

if (ppsc->inactive_pwrstate == ERFON && rtlhal->interface == INTF_PCI) {
if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) &&
- RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM) &&
+ RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM) &&
rtlhal->interface == INTF_PCI) {
rtlpriv->intf_ops->disable_aspm(hw);
- RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM);
+ RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
}
}

@@ -206,9 +206,10 @@ static void _rtl_ps_inactive_ps(struct i

if (ppsc->inactive_pwrstate == ERFOFF &&
rtlhal->interface == INTF_PCI) {
- if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) {
+ if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM &&
+ !RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) {
rtlpriv->intf_ops->enable_aspm(hw);
- RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM);
+ RT_SET_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
}
}

@@ -232,6 +233,9 @@ void rtl_ips_nic_off_wq_callback(void *d
return;
}

+ if (mac->link_state > MAC80211_NOLINK)
+ return;
+
if (is_hal_stop(rtlhal))
return;

@@ -369,8 +373,7 @@ static void rtl_lps_set_psmode(struct ie
* mode and set RPWM to turn RF on.
*/

- if ((ppsc->fwctrl_lps) && (ppsc->leisure_ps) &&
- ppsc->report_linked) {
+ if ((ppsc->fwctrl_lps) && ppsc->report_linked) {
bool fw_current_inps;
if (ppsc->dot11_psmode == EACTIVE) {
RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
@@ -424,7 +427,7 @@ void rtl_lps_enter(struct ieee80211_hw *
struct rtl_priv *rtlpriv = rtl_priv(hw);
unsigned long flag;

- if (!(ppsc->fwctrl_lps && ppsc->leisure_ps))
+ if (!ppsc->fwctrl_lps)
return;

if (rtlpriv->sec.being_setkey)
@@ -445,15 +448,13 @@ void rtl_lps_enter(struct ieee80211_hw *

spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag);

- if (ppsc->leisure_ps) {
- /* Idle for a while if we connect to AP a while ago. */
- if (mac->cnt_after_linked >= 2) {
- if (ppsc->dot11_psmode == EACTIVE) {
- RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
- ("Enter 802.11 power save mode...\n"));
+ /* Idle for a while if we connect to AP a while ago. */
+ if (mac->cnt_after_linked >= 2) {
+ if (ppsc->dot11_psmode == EACTIVE) {
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+ ("Enter 802.11 power save mode...\n"));

- rtl_lps_set_psmode(hw, EAUTOPS);
- }
+ rtl_lps_set_psmode(hw, EAUTOPS);
}
}
spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
@@ -469,17 +470,17 @@ void rtl_lps_leave(struct ieee80211_hw *

spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag);

- if (ppsc->fwctrl_lps && ppsc->leisure_ps) {
+ if (ppsc->fwctrl_lps) {
if (ppsc->dot11_psmode != EACTIVE) {

/*FIX ME */
rtlpriv->cfg->ops->enable_interrupt(hw);

if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM &&
- RT_IN_PS_LEVEL(ppsc, RT_RF_LPS_LEVEL_ASPM) &&
+ RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM) &&
rtlhal->interface == INTF_PCI) {
rtlpriv->intf_ops->disable_aspm(hw);
- RT_CLEAR_PS_LEVEL(ppsc, RT_RF_LPS_LEVEL_ASPM);
+ RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
}

RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
@@ -490,3 +491,211 @@ void rtl_lps_leave(struct ieee80211_hw *
}
spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
}
+
+/* For sw LPS*/
+void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct ieee80211_hdr *hdr = (void *) data;
+ struct ieee80211_tim_ie *tim_ie;
+ u8 *tim;
+ u8 tim_len;
+ bool u_buffed;
+ bool m_buffed;
+
+ if (!rtlpriv->psc.swctrl_lps)
+ return;
+
+ if (rtlpriv->mac80211.link_state != MAC80211_LINKED)
+ return;
+
+ if (!rtlpriv->psc.sw_ps_enabled)
+ return;
+
+ if (rtlpriv->psc.fwctrl_lps)
+ return;
+
+ if (likely(!(hw->conf.flags & IEEE80211_CONF_PS)))
+ return;
+
+ /* check if this really is a beacon */
+ if (!ieee80211_is_beacon(hdr->frame_control))
+ return;
+
+ /* min. beacon length + FCS_LEN */
+ if (len <= 40 + FCS_LEN)
+ return;
+
+ /* and only beacons from the associated BSSID, please */
+ if (compare_ether_addr(hdr->addr3, rtlpriv->mac80211.bssid))
+ return;
+
+ rtlpriv->psc.last_beacon = jiffies;
+
+ tim = rtl_find_ie(data, len - FCS_LEN, WLAN_EID_TIM);
+ if (!tim)
+ return;
+
+ if (tim[1] < sizeof(*tim_ie))
+ return;
+
+ tim_len = tim[1];
+ tim_ie = (struct ieee80211_tim_ie *) &tim[2];
+
+ if (!WARN_ON_ONCE(!hw->conf.ps_dtim_period))
+ rtlpriv->psc.dtim_counter = tim_ie->dtim_count;
+
+ /* Check whenever the PHY can be turned off again. */
+
+ /* 1. What about buffered unicast traffic for our AID? */
+ u_buffed = ieee80211_check_tim(tim_ie, tim_len,
+ rtlpriv->mac80211.assoc_id);
+
+ /* 2. Maybe the AP wants to send multicast/broadcast data? */
+ m_buffed = tim_ie->bitmap_ctrl & 0x01;
+ rtlpriv->psc.multi_buffered = m_buffed;
+
+ /* unicast will process by mac80211 through
+ * set ~IEEE80211_CONF_PS, So we just check
+ * multicast frames here */
+ if (!m_buffed) {/*&&) {// !rtlpriv->psc.tx_doing) { */
+ /* back to low-power land. and delay is
+ * prevent null power save frame tx fail */
+ queue_delayed_work(rtlpriv->works.rtl_wq,
+ &rtlpriv->works.ps_work, MSECS(5));
+ } else {
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, ("u_bufferd: %x, "
+ "m_buffered: %x\n", u_buffed, m_buffed));
+ }
+}
+
+void rtl_swlps_rf_awake(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ unsigned long flag;
+
+ if (!rtlpriv->psc.swctrl_lps)
+ return;
+ if (mac->link_state != MAC80211_LINKED)
+ return;
+
+ if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM &&
+ RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) {
+ rtlpriv->intf_ops->disable_aspm(hw);
+ RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
+ }
+
+ spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag);
+ rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS, false);
+ spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
+}
+
+void rtl_swlps_rfon_wq_callback(void *data)
+{
+ struct rtl_works *rtlworks =
+ container_of_dwork_rtl(data, struct rtl_works, ps_rfon_wq);
+ struct ieee80211_hw *hw = rtlworks->hw;
+
+ rtl_swlps_rf_awake(hw);
+}
+
+void rtl_swlps_rf_sleep(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ unsigned long flag;
+ u8 sleep_intv;
+
+ if (!rtlpriv->psc.sw_ps_enabled)
+ return;
+
+ if ((rtlpriv->sec.being_setkey) ||
+ (mac->opmode == NL80211_IFTYPE_ADHOC))
+ return;
+
+ /*sleep after linked 10s, to let DHCP and 4-way handshake ok enough!! */
+ if ((mac->link_state != MAC80211_LINKED) || (mac->cnt_after_linked < 5))
+ return;
+
+ if (rtlpriv->link_info.busytraffic)
+ return;
+
+ spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
+ if (rtlpriv->psc.rfchange_inprogress) {
+ spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
+ return;
+ }
+ spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
+
+ spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag);
+ rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS, false);
+ spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
+
+ if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM &&
+ !RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) {
+ rtlpriv->intf_ops->enable_aspm(hw);
+ RT_SET_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
+ }
+
+ /* here is power save alg, when this beacon is DTIM
+ * we will set sleep time to dtim_period * n;
+ * when this beacon is not DTIM, we will set sleep
+ * time to sleep_intv = rtlpriv->psc.dtim_counter or
+ * MAX_SW_LPS_SLEEP_INTV(default set to 5) */
+
+ if (rtlpriv->psc.dtim_counter == 0) {
+ if (hw->conf.ps_dtim_period == 1)
+ sleep_intv = hw->conf.ps_dtim_period * 2;
+ else
+ sleep_intv = hw->conf.ps_dtim_period;
+ } else {
+ sleep_intv = rtlpriv->psc.dtim_counter;
+ }
+
+ if (sleep_intv > MAX_SW_LPS_SLEEP_INTV)
+ sleep_intv = MAX_SW_LPS_SLEEP_INTV;
+
+ /* this print should always be dtim_conter = 0 &
+ * sleep = dtim_period, that meaons, we should
+ * awake before every dtim */
+ RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
+ ("dtim_counter:%x will sleep :%d"
+ " beacon_intv\n", rtlpriv->psc.dtim_counter, sleep_intv));
+
+ /* we tested that 40ms is enough for sw & hw sw delay */
+ queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.ps_rfon_wq,
+ MSECS(sleep_intv * mac->vif->bss_conf.beacon_int - 40));
+}
+
+
+void rtl_swlps_wq_callback(void *data)
+{
+ struct rtl_works *rtlworks = container_of_dwork_rtl(data,
+ struct rtl_works,
+ ps_work);
+ struct ieee80211_hw *hw = rtlworks->hw;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ bool ps = false;
+
+ ps = (hw->conf.flags & IEEE80211_CONF_PS);
+
+ /* we can sleep after ps null send ok */
+ if (rtlpriv->psc.state_inap) {
+ rtl_swlps_rf_sleep(hw);
+
+ if (rtlpriv->psc.state && !ps) {
+ rtlpriv->psc.sleep_ms = jiffies_to_msecs(jiffies -
+ rtlpriv->psc.last_action);
+ }
+
+ if (ps)
+ rtlpriv->psc.last_slept = jiffies;
+
+ rtlpriv->psc.last_action = jiffies;
+ rtlpriv->psc.state = ps;
+ }
+}
+
Index: wireless-testing/drivers/net/wireless/rtlwifi/ps.h
===================================================================
--- wireless-testing.orig/drivers/net/wireless/rtlwifi/ps.h
+++ wireless-testing/drivers/net/wireless/rtlwifi/ps.h
@@ -30,6 +30,8 @@
#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);
@@ -40,4 +42,10 @@ void rtl_ips_nic_on(struct ieee80211_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_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);
+
#endif
Index: wireless-testing/drivers/net/wireless/rtlwifi/pci.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/rtlwifi/pci.c
+++ wireless-testing/drivers/net/wireless/rtlwifi/pci.c
@@ -32,6 +32,7 @@
#include "pci.h"
#include "base.h"
#include "ps.h"
+#include "efuse.h"

static const u16 pcibridge_vendors[PCI_BRIDGE_VENDOR_MAX] = {
INTEL_VENDOR_ID,
@@ -48,6 +49,7 @@ static void _rtl_pci_update_default_sett
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor;
+ u8 init_aspm;

ppsc->reg_rfps_level = 0;
ppsc->support_aspm = 0;
@@ -129,9 +131,16 @@ static void _rtl_pci_update_default_sett
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
- ("switch case not process\n"));
+ ("switch case not processed\n"));
break;
}
+
+ /* toshiba aspm issue, toshiba will set aspm selfly
+ * so we should not set aspm in driver */
+ pci_read_config_byte(rtlpci->pdev, 0x80, &init_aspm);
+ if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8192SE &&
+ init_aspm == 0x43)
+ ppsc->support_aspm = false;
}

static bool _rtl_pci_platform_switch_device_pci_aspm(
@@ -139,8 +148,11 @@ static bool _rtl_pci_platform_switch_dev
u8 value)
{
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+ if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192SE)
+ value |= 0x40;

- value |= 0x40;
pci_write_config_byte(rtlpci->pdev, 0x80, value);

return false;
@@ -150,10 +162,11 @@ static bool _rtl_pci_platform_switch_dev
static bool _rtl_pci_switch_clk_req(struct ieee80211_hw *hw, u8 value)
{
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
- u8 buffer;
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));

- buffer = value;
pci_write_config_byte(rtlpci->pdev, 0x81, value);
+ if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE)
+ udelay(100);

return true;
}
@@ -173,7 +186,10 @@ static void rtl_pci_disable_aspm(struct
u16 pcibridge_linkctrlreg = pcipriv->ndis_adapter.
pcibridge_linkctrlreg;
u16 aspmlevel = 0;
- u8 tmp_u1b = 0;
+ u8 tmp = 0;
+
+ if (!ppsc->support_aspm)
+ return;

if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) {
RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
@@ -188,7 +204,7 @@ static void rtl_pci_disable_aspm(struct
}

/*for promising device will in L0 state after an I/O. */
- pci_read_config_byte(rtlpci->pdev, 0x80, &tmp_u1b);
+ pci_read_config_byte(rtlpci->pdev, 0x80, &tmp);

/*Set corresponding value. */
aspmlevel |= BIT(0) | BIT(1);
@@ -228,6 +244,9 @@ static void rtl_pci_enable_aspm(struct i
u8 u_pcibridge_aspmsetting;
u8 u_device_aspmsetting;

+ if (!ppsc->support_aspm)
+ return;
+
if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) {
RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
("PCI(Bridge) UNKNOWN.\n"));
@@ -272,7 +291,7 @@ static void rtl_pci_enable_aspm(struct i
RT_RF_OFF_LEVL_CLK_REQ) ? 1 : 0);
RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_CLK_REQ);
}
- udelay(200);
+ udelay(100);
}

static bool rtl_pci_get_amd_l1_patch(struct ieee80211_hw *hw)
@@ -309,13 +328,13 @@ static void rtl_pci_get_linkcontrol_fiel
u8 capabilityoffset = pcipriv->ndis_adapter.pcibridge_pciehdr_offset;
u32 pcicfg_addrport = pcipriv->ndis_adapter.pcicfg_addrport;
u8 linkctrl_reg;
- u8 num4bBytes;
+ u8 num4bbytes;

- num4bBytes = (capabilityoffset + 0x10) / 4;
+ num4bbytes = (capabilityoffset + 0x10) / 4;

/*Read Link Control Register */
rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS,
- pcicfg_addrport + (num4bBytes << 2));
+ pcicfg_addrport + (num4bbytes << 2));
rtl_pci_raw_read_port_uchar(PCI_CONF_DATA, &linkctrl_reg);

pcipriv->ndis_adapter.pcibridge_linkctrlreg = linkctrl_reg;
@@ -348,7 +367,7 @@ static void rtl_pci_parse_configuration(
pci_write_config_byte(pdev, 0x70f, tmp);
}

-static void _rtl_pci_initialize_adapter_common(struct ieee80211_hw *hw)
+static void rtl_pci_init_aspm(struct ieee80211_hw *hw)
{
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));

@@ -359,53 +378,6 @@ static void _rtl_pci_initialize_adapter_
rtl_pci_enable_aspm(hw);
RT_SET_PS_LEVEL(ppsc, RT_RF_PS_LEVEL_ALWAYS_ASPM);
}
-
-}
-
-static void rtl_pci_init_aspm(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;
-
- _rtl_pci_initialize_adapter_common(hw);
}

static void _rtl_pci_io_handler_init(struct device *dev,
@@ -429,17 +401,131 @@ static void _rtl_pci_io_handler_release(
{
}

+static bool _rtl_update_earlymode_info(struct ieee80211_hw *hw,
+ struct sk_buff *skb,
+ struct rtl_tcb_desc *tcb_desc)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ enum rt_enc_alg pairwise_enc = rtlpriv->sec.pairwise_enc_algorithm;
+ u8 additionlen = 0;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
+ __le16 fc = hdr->frame_control;
+ struct sk_buff *next_skb;
+ unsigned int queue_index = skb_get_queue_mapping(skb);
+ u8 *da = ieee80211_get_DA(hdr);
+
+ if (rtlpriv->rtlhal.hw_type != HARDWARE_TYPE_RTL8192DE)
+ return false;
+
+ switch (pairwise_enc) {
+ case NO_ENCRYPTION:
+ additionlen = 4;
+ break;
+
+ case WEP40_ENCRYPTION:
+ case WEP104_ENCRYPTION:
+ additionlen = 8;
+ break;
+
+ case TKIP_ENCRYPTION:
+ additionlen = 16;
+ break;
+
+ case AESCCMP_ENCRYPTION:
+ additionlen = 12;
+ break;
+
+ default:
+ break;
+ }
+
+ /* Some macaddr can't do early mode. */
+ if (is_multicast_ether_addr(da) || is_broadcast_ether_addr(da) ||
+ !ieee80211_is_data_qos(fc))
+ return false;
+
+ /* The most skb num is 6 */
+ tcb_desc->empkt_num = 0;
+ skb_queue_walk(&mac->skb_waitq[queue_index], next_skb) {
+ hdr = (struct ieee80211_hdr *)(next_skb->data);
+
+ /* rdg is not used now */
+ if (memcmp(ieee80211_get_DA(hdr), da, ETH_ALEN) == 0 &&
+ (queue_index == skb_get_queue_mapping(next_skb))) {
+ tcb_desc->empkt_len[tcb_desc->empkt_num] =
+ next_skb->len + additionlen;
+ tcb_desc->empkt_num++;
+ }
+
+ if (skb_queue_is_last(&mac->skb_waitq[queue_index], next_skb))
+ break;
+
+ if (tcb_desc->empkt_num >= 5)
+ break;
+ }
+
+ return true;
+}
+
+/* just for early mode now */
+static void _rtl_pci_tx_chk_waitq(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ int queue_idx;
+ struct sk_buff *skb = NULL;
+ struct ieee80211_hdr *hdr = NULL;
+ struct ieee80211_tx_info *info = NULL;
+ u8 *qc = NULL;
+ u8 tid = 0;
+ struct rtl_tcb_desc tcb_desc;
+ memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc));
+
+ if (!rtlpriv->rtlhal.earlymode_enable)
+ return;
+
+ if (rtlpriv->rtlhal.hw_type != HARDWARE_TYPE_RTL8192DE)
+ return;
+
+ for (queue_idx = 0; queue_idx < RTL_PCI_MAX_TX_QUEUE_COUNT;
+ queue_idx++) {
+ if (queue_idx >= BEACON_QUEUE)
+ break;
+
+ while (!skb_queue_empty(&mac->skb_waitq[queue_idx]) &&
+ !mac->act_scanning &&
+ rtlpriv->psc.rfpwr_state == ERFON) {
+ tcb_desc.empkt_num = 0;
+ memset(tcb_desc.empkt_len, 0, 20);
+
+ skb = skb_dequeue(&mac->skb_waitq[queue_idx]);
+ info = IEEE80211_SKB_CB(skb);
+ hdr = (struct ieee80211_hdr *)(skb->data);
+ qc = ieee80211_get_qos_ctl(hdr);
+ tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
+
+ if (mac->tids[tid].agg.agg_state == RTL_AGG_ON &&
+ info->flags & IEEE80211_TX_CTL_AMPDU)
+ _rtl_update_earlymode_info(hw, skb, &tcb_desc);
+
+ rtlpriv->intf_ops->adapter_tx(hw, skb, &tcb_desc);
+ }
+ }
+}
+
static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
-
struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[prio];

while (skb_queue_len(&ring->queue)) {
struct rtl_tx_desc *entry = &ring->desc[ring->idx];
struct sk_buff *skb;
struct ieee80211_tx_info *info;
+ struct ieee80211_hdr *hdr;
+ __le16 fc;

u8 own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) entry, true,
HW_DESC_OWN);
@@ -460,6 +546,10 @@ static void _rtl_pci_tx_isr(struct ieee8
HW_DESC_TXBUFF_ADDR),
skb->len, PCI_DMA_TODEVICE);

+ /* remove early mode header */
+ if (rtlpriv->rtlhal.earlymode_enable)
+ skb_pull(skb, EM_HDR_LEN);
+
RT_TRACE(rtlpriv, (COMP_INTR | COMP_SEND), DBG_TRACE,
("new ring->idx:%d, "
"free: skb_queue_len:%d, free: seq:%x\n",
@@ -467,6 +557,24 @@ static void _rtl_pci_tx_isr(struct ieee8
skb_queue_len(&ring->queue),
*(u16 *) (skb->data + 22)));

+ if (prio == TXCMD_QUEUE) {
+ dev_kfree_skb(skb);
+ goto tx_status_ok;
+
+ }
+
+ /* for sw LPS, just after NULL skb send out, we can
+ * sure AP kown we are sleeped, our we should not let
+ * rf to sleep*/
+ hdr = (struct ieee80211_hdr *)(skb->data);
+ fc = hdr->frame_control;
+ if (ieee80211_is_nullfunc(fc)) {
+ if (ieee80211_has_pm(fc))
+ rtlpriv->psc.state_inap = 1;
+ else
+ rtlpriv->psc.state_inap = 0;
+ }
+
info = IEEE80211_SKB_CB(skb);
ieee80211_tx_info_clear_status(info);

@@ -490,6 +598,7 @@ static void _rtl_pci_tx_isr(struct ieee8
(skb));
}

+tx_status_ok:
skb = NULL;
}

@@ -564,20 +673,18 @@ static void _rtl_pci_rx_interrupt(struct
hdr = (struct ieee80211_hdr *)(skb->data);
fc = hdr->frame_control;

- if (!stats.crc) {
+ if (!stats.crc || !stats.hwerror) {
memcpy(IEEE80211_SKB_RXCB(skb), &rx_status,
sizeof(rx_status));

- if (is_broadcast_ether_addr(hdr->addr1))
+ if (is_broadcast_ether_addr(hdr->addr1)) {
;/*TODO*/
- else {
- if (is_multicast_ether_addr(hdr->addr1))
- ;/*TODO*/
- else {
- unicast = true;
- rtlpriv->stats.rxbytesunicast +=
- skb->len;
- }
+ } else if (is_multicast_ether_addr(hdr->addr1)) {
+ ;/*TODO*/
+ } else {
+ unicast = true;
+ rtlpriv->stats.rxbytesunicast +=
+ skb->len;
}

rtl_is_special_data(hw, skb, false);
@@ -591,8 +698,15 @@ static void _rtl_pci_rx_interrupt(struct
num_rx_inperiod++;
}

+ /* for sw lps */
+ rtl_swlps_beacon(hw,
+ (void *)skb->data, skb->len);
+
+ rtl_recognize_peer(hw,
+ (void *)skb->data, skb->len);
+
if (unlikely(!rtl_action_proc(hw, skb,
- false))) {
+ false))) {
dev_kfree_skb_any(skb);
} else {
struct sk_buff *uskb = NULL;
@@ -674,6 +788,7 @@ static irqreturn_t _rtl_pci_interrupt(in
struct ieee80211_hw *hw = dev_id;
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));
unsigned long flags;
u32 inta = 0;
u32 intb = 0;
@@ -760,23 +875,36 @@ static irqreturn_t _rtl_pci_interrupt(in
_rtl_pci_tx_isr(hw, VO_QUEUE);
}

+ if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) {
+ if (inta & rtlpriv->cfg->maps[RTL_IMR_COMDOK]) {
+ rtlpriv->link_info.num_tx_inperiod++;
+
+ RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
+ ("CMD TX OK interrupt!\n"));
+ _rtl_pci_tx_isr(hw, TXCMD_QUEUE);
+ }
+ }
+
/*<2> Rx related */
if (inta & rtlpriv->cfg->maps[RTL_IMR_ROK]) {
RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, ("Rx ok interrupt!\n"));
- tasklet_schedule(&rtlpriv->works.irq_tasklet);
+ _rtl_pci_rx_interrupt(hw);
}

if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_RDU])) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
("rx descriptor unavailable!\n"));
- tasklet_schedule(&rtlpriv->works.irq_tasklet);
+ _rtl_pci_rx_interrupt(hw);
}

if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_RXFOVW])) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, ("rx overflow !\n"));
- tasklet_schedule(&rtlpriv->works.irq_tasklet);
+ _rtl_pci_rx_interrupt(hw);
}

+ if (rtlpriv->rtlhal.earlymode_enable)
+ tasklet_schedule(&rtlpriv->works.irq_tasklet);
+
spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
return IRQ_HANDLED;

@@ -787,7 +915,7 @@ done:

static void _rtl_pci_irq_tasklet(struct ieee80211_hw *hw)
{
- _rtl_pci_rx_interrupt(hw);
+ _rtl_pci_tx_chk_waitq(hw);
}

static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw)
@@ -799,10 +927,12 @@ static void _rtl_pci_prepare_bcn_tasklet
struct ieee80211_hdr *hdr = NULL;
struct ieee80211_tx_info *info = NULL;
struct sk_buff *pskb = NULL;
+ struct rtl_tcb_desc tcb_desc;
struct rtl_tx_desc *pdesc = NULL;
unsigned int queue_index;
u8 temp_one = 1;

+ memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc));
ring = &rtlpci->tx_ring[BEACON_QUEUE];
pskb = __skb_dequeue(&ring->queue);
if (pskb)
@@ -819,7 +949,8 @@ static void _rtl_pci_prepare_bcn_tasklet

pdesc = &ring->desc[0];
rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *) pdesc,
- info, pskb, queue_index);
+ info, pskb, queue_index,
+ &tcb_desc);

__skb_queue_tail(&ring->queue, pskb);

@@ -861,7 +992,6 @@ static void _rtl_pci_init_struct(struct
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
- struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));

rtlpci->up_first_time = true;
rtlpci->being_init_adapter = false;
@@ -869,31 +999,21 @@ static void _rtl_pci_init_struct(struct
rtlhal->hw = hw;
rtlpci->pdev = pdev;

- ppsc->inactiveps = false;
- ppsc->leisure_ps = true;
- ppsc->fwctrl_lps = true;
- ppsc->reg_fwctrl_lps = 3;
- ppsc->reg_max_lps_awakeintvl = 5;
-
- if (ppsc->reg_fwctrl_lps == 1)
- ppsc->fwctrl_psmode = FW_PS_MIN_MODE;
- else if (ppsc->reg_fwctrl_lps == 2)
- ppsc->fwctrl_psmode = FW_PS_MAX_MODE;
- else if (ppsc->reg_fwctrl_lps == 3)
- ppsc->fwctrl_psmode = FW_PS_DTIM_MODE;
-
/*Tx/Rx related var */
_rtl_pci_init_trx_var(hw);

- /*IBSS*/ mac->beacon_interval = 100;
+ /*IBSS*/
+ mac->beacon_interval = 100;

- /*AMPDU*/ mac->min_space_cfg = 0;
+ /*AMPDU*/
+ mac->min_space_cfg = 0;
mac->max_mss_density = 0;
/*set sane AMPDU defaults */
mac->current_ampdu_density = 7;
mac->current_ampdu_factor = 3;

- /*QOS*/ rtlpci->acm_method = eAcmWay2_SW;
+ /*QOS*/
+ rtlpci->acm_method = eAcmWay2_SW;

/*task */
tasklet_init(&rtlpriv->works.irq_tasklet,
@@ -1182,9 +1302,10 @@ int rtl_pci_reset_trx_ring(struct ieee80
return 0;
}

-static unsigned int _rtl_mac_to_hwqueue(__le16 fc,
- unsigned int mac80211_queue_index)
+static unsigned int _rtl_mac_to_hwqueue(struct ieee80211_hw *hw, __le16 fc,
+ unsigned int mac80211_queue_index)
{
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
unsigned int hw_queue_index;

if (unlikely(ieee80211_is_beacon(fc))) {
@@ -1197,6 +1318,13 @@ static unsigned int _rtl_mac_to_hwqueue(
goto out;
}

+ if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) {
+ if (ieee80211_is_nullfunc(fc)) {
+ hw_queue_index = HIGH_QUEUE;
+ goto out;
+ }
+ }
+
switch (mac80211_queue_index) {
case 0:
hw_queue_index = VO_QUEUE;
@@ -1205,7 +1333,7 @@ static unsigned int _rtl_mac_to_hwqueue(
hw_queue_index = VI_QUEUE;
break;
case 2:
- hw_queue_index = BE_QUEUE;;
+ hw_queue_index = BE_QUEUE;
break;
case 3:
hw_queue_index = BK_QUEUE;
@@ -1221,7 +1349,49 @@ out:
return hw_queue_index;
}

-static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+static bool rtl_pci_tx_chk_waitq_insert(struct ieee80211_hw *hw,
+ struct sk_buff *skb)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
+ __le16 fc = hdr->frame_control;
+ unsigned int queue_index = skb_get_queue_mapping(skb);
+ unsigned int hw_queue = _rtl_mac_to_hwqueue(hw, fc, queue_index);
+ struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue];
+ u8 *qc = ieee80211_get_qos_ctl(hdr);
+ u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
+
+ if (!rtlhal->earlymode_enable)
+ return 0;
+
+ if (!ieee80211_is_data_qos(fc))
+ return 0;
+
+ if (mac->tids[tid].agg.agg_state != RTL_AGG_ON)
+ return 0;
+
+ RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, ("===insert to skb_waitq "
+ "for early mode desc_used_num[%d]:%d\n", queue_index,
+ skb_queue_len(&ring->queue)));
+ if (skb_queue_len(&ring->queue) > mac->earlymode_threshold ||
+ !skb_queue_empty(&mac->skb_waitq[queue_index])) {
+ skb_queue_tail(&mac->skb_waitq[queue_index], skb);
+
+ RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, ("insert to skb_waitq "
+ "for early mode desc_used_num[%d]:%d\n",
+ queue_index, skb_queue_len(&ring->queue)));
+
+ return 1;
+ }
+
+ return 0;
+}
+
+static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
+ struct rtl_tcb_desc *ptcb_desc)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
@@ -1244,10 +1414,17 @@ static int rtl_pci_tx(struct ieee80211_h

if (ieee80211_is_mgmt(fc))
rtl_tx_mgmt_proc(hw, skb);
+
+ if (rtlpriv->psc.sw_ps_enabled) {
+ if (ieee80211_is_data(fc) && !ieee80211_is_nullfunc(fc) &&
+ !ieee80211_has_pm(fc))
+ hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
+ }
+
rtl_action_proc(hw, skb, true);

queue_index = skb_get_queue_mapping(skb);
- hw_queue = _rtl_mac_to_hwqueue(fc, queue_index);
+ hw_queue = _rtl_mac_to_hwqueue(hw, fc, queue_index);

if (is_multicast_ether_addr(pda_addr))
rtlpriv->stats.txbytesmulticast += skb->len;
@@ -1280,13 +1457,6 @@ static int rtl_pci_tx(struct ieee80211_h
return skb->len;
}

- /*
- *if(ieee80211_is_nullfunc(fc)) {
- * spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
- * return 1;
- *}
- */
-
if (ieee80211_is_data_qos(fc)) {
qc = ieee80211_get_qos_ctl(hdr);
tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
@@ -1306,7 +1476,8 @@ static int rtl_pci_tx(struct ieee80211_h
rtlpriv->cfg->ops->led_control(hw, LED_CTL_TX);

rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *) pdesc,
- info, skb, hw_queue);
+ info, skb, hw_queue,
+ ptcb_desc);

__skb_queue_tail(&ring->queue, skb);

@@ -1328,7 +1499,7 @@ static int rtl_pci_tx(struct ieee80211_h
hw_queue, ring->idx, idx,
skb_queue_len(&ring->queue)));

- ieee80211_stop_queue(hw, skb_get_queue_mapping(skb));
+ ieee80211_stop_queue(hw, queue_index);
}

spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
@@ -1454,14 +1625,13 @@ static bool _rtl_pci_find_adapter(struct
struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
struct pci_dev *bridge_pdev = pdev->bus->self;
- u16 venderid;
- u16 deviceid;
+ u16 venderid = pdev->vendor;
+ u16 deviceid = pdev->device;
+ u8 revisionid = pdev->revision;
u16 irqline;
u8 tmp;

- venderid = pdev->vendor;
- deviceid = pdev->device;
- pci_read_config_word(pdev, 0x3C, &irqline);
+ pci_read_config_word(pdev, PCI_INTERRUPT_LINE, &irqline);

if (deviceid == RTL_PCI_8192_DID ||
deviceid == RTL_PCI_0044_DID ||
@@ -1471,7 +1641,7 @@ static bool _rtl_pci_find_adapter(struct
deviceid == RTL_PCI_8173_DID ||
deviceid == RTL_PCI_8172_DID ||
deviceid == RTL_PCI_8171_DID) {
- switch (pdev->revision) {
+ switch (revisionid) {
case RTL_PCI_REVISION_ID_8192PCIE:
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
("8192 PCI-E is found - "
@@ -1500,6 +1670,12 @@ static bool _rtl_pci_find_adapter(struct
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
("8192C PCI-E is found - "
"vid/did=%x/%x\n", venderid, deviceid));
+ } else if (deviceid == RTL_PCI_8192DE_DID ||
+ deviceid == RTL_PCI_8192DE_DID2) {
+ rtlhal->hw_type = HARDWARE_TYPE_RTL8192DE;
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
+ ("8192D PCI-E is found - "
+ "vid/did=%x/%x\n", venderid, deviceid));
} else {
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
("Err: Unknown device -"
@@ -1508,6 +1684,25 @@ static bool _rtl_pci_find_adapter(struct
rtlhal->hw_type = RTL_DEFAULT_HARDWARE_TYPE;
}

+ if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192DE) {
+ if (revisionid == 0 || revisionid == 1) {
+ if (revisionid == 0) {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ ("Find 92DE MAC0.\n"));
+ rtlhal->interfaceindex = 0;
+ } else if (revisionid == 1) {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ ("Find 92DE MAC1.\n"));
+ rtlhal->interfaceindex = 1;
+ }
+ } else {
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+ ("Unknown device - "
+ "VendorID/DeviceID=%x/%x, Revision=%x\n",
+ venderid, deviceid, revisionid));
+ rtlhal->interfaceindex = 0;
+ }
+ }
/*find bus info */
pcipriv->ndis_adapter.busnumber = pdev->bus->number;
pcipriv->ndis_adapter.devnumber = PCI_SLOT(pdev->devfn);
@@ -1533,12 +1728,12 @@ static bool _rtl_pci_find_adapter(struct
PCI_SLOT(bridge_pdev->devfn);
pcipriv->ndis_adapter.pcibridge_funcnum =
PCI_FUNC(bridge_pdev->devfn);
- pcipriv->ndis_adapter.pcibridge_pciehdr_offset =
- pci_pcie_cap(bridge_pdev);
pcipriv->ndis_adapter.pcicfg_addrport =
(pcipriv->ndis_adapter.pcibridge_busnum << 16) |
(pcipriv->ndis_adapter.pcibridge_devnum << 11) |
(pcipriv->ndis_adapter.pcibridge_funcnum << 8) | (1 << 31);
+ pcipriv->ndis_adapter.pcibridge_pciehdr_offset =
+ pci_pcie_cap(bridge_pdev);
pcipriv->ndis_adapter.num4bytes =
(pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10) / 4;

@@ -1621,6 +1816,11 @@ int __devinit rtl_pci_probe(struct pci_d
pcipriv = (void *)rtlpriv->priv;
pcipriv->dev.pdev = pdev;

+ /* init cfg & intf_ops */
+ rtlpriv->rtlhal.interface = INTF_PCI;
+ rtlpriv->cfg = (struct rtl_hal_cfg *)(id->driver_data);
+ rtlpriv->intf_ops = &rtl_pci_ops;
+
/*
*init dbgp flags before all
*other functions, because we will
@@ -1638,13 +1838,14 @@ int __devinit rtl_pci_probe(struct pci_d
return err;
}

- pmem_start = pci_resource_start(pdev, 2);
- pmem_len = pci_resource_len(pdev, 2);
- pmem_flags = pci_resource_flags(pdev, 2);
+ pmem_start = pci_resource_start(pdev, rtlpriv->cfg->bar_id);
+ pmem_len = pci_resource_len(pdev, rtlpriv->cfg->bar_id);
+ pmem_flags = pci_resource_flags(pdev, rtlpriv->cfg->bar_id);

/*shared mem start */
rtlpriv->io.pci_mem_start =
- (unsigned long)pci_iomap(pdev, 2, pmem_len);
+ (unsigned long)pci_iomap(pdev,
+ rtlpriv->cfg->bar_id, pmem_len);
if (rtlpriv->io.pci_mem_start == 0) {
RT_ASSERT(false, ("Can't map PCI mem\n"));
goto fail2;
@@ -1663,11 +1864,6 @@ int __devinit rtl_pci_probe(struct pci_d
pci_write_config_byte(pdev, 0x04, 0x06);
pci_write_config_byte(pdev, 0x04, 0x07);

- /* init cfg & intf_ops */
- rtlpriv->rtlhal.interface = INTF_PCI;
- rtlpriv->cfg = (struct rtl_hal_cfg *)(id->driver_data);
- rtlpriv->intf_ops = &rtl_pci_ops;
-
/* find adapter */
_rtl_pci_find_adapter(pdev, hw);

@@ -1720,6 +1916,9 @@ int __devinit rtl_pci_probe(struct pci_d
goto fail3;
}

+ /* add for prov */
+ rtl_proc_add_one(hw);
+
/*init rfkill */
rtl_init_rfkill(hw);

@@ -1771,6 +1970,9 @@ void rtl_pci_disconnect(struct pci_dev *

sysfs_remove_group(&pdev->dev.kobj, &rtl_attribute_group);

+ /* add for prov */
+ rtl_proc_remove_one(hw);
+
/*ieee80211_unregister_hw will call ops_stop */
if (rtlmac->mac80211_registered == 1) {
ieee80211_unregister_hw(hw);
@@ -1785,7 +1987,6 @@ void rtl_pci_disconnect(struct pci_dev *

rtl_pci_deinit(hw);
rtl_deinit_core(hw);
- rtlpriv->cfg->ops->deinit_sw_leds(hw);
_rtl_pci_io_handler_release(hw);
rtlpriv->cfg->ops->deinit_sw_vars(hw);

@@ -1800,6 +2001,7 @@ void rtl_pci_disconnect(struct pci_dev *
}

pci_disable_device(pdev);
+ rtl_pci_disable_aspm(hw);
pci_set_drvdata(pdev, NULL);

ieee80211_free_hw(hw);
@@ -1823,6 +2025,11 @@ no need to call hw_disable here.
****************************************/
int rtl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
{
+ struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ rtlpriv->cfg->ops->hw_suspend(hw);
+ rtl_deinit_rfkill(hw);
pci_save_state(pdev);
pci_disable_device(pdev);
pci_set_power_state(pdev, PCI_D3hot);
@@ -1833,6 +2040,8 @@ EXPORT_SYMBOL(rtl_pci_suspend);

int rtl_pci_resume(struct pci_dev *pdev)
{
+ struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
int ret;

pci_set_power_state(pdev, PCI_D0);
@@ -1843,16 +2052,20 @@ int rtl_pci_resume(struct pci_dev *pdev)
}

pci_restore_state(pdev);
+ rtlpriv->cfg->ops->hw_resume(hw);
+ rtl_init_rfkill(hw);

return 0;
}
EXPORT_SYMBOL(rtl_pci_resume);

struct rtl_intf_ops rtl_pci_ops = {
+ .read_efuse_byte = read_efuse_byte,
.adapter_start = rtl_pci_start,
.adapter_stop = rtl_pci_stop,
.adapter_tx = rtl_pci_tx,
.reset_trx_ring = rtl_pci_reset_trx_ring,
+ .waitq_insert = rtl_pci_tx_chk_waitq_insert,

.disable_aspm = rtl_pci_disable_aspm,
.enable_aspm = rtl_pci_enable_aspm,
Index: wireless-testing/drivers/net/wireless/rtlwifi/pci.h
===================================================================
--- wireless-testing.orig/drivers/net/wireless/rtlwifi/pci.h
+++ wireless-testing/drivers/net/wireless/rtlwifi/pci.h
@@ -102,8 +102,8 @@
#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 0x092D /*8192ce */
-#define RTL_PCI_8192DU_DID 0x092D /*8192ce */
+#define RTL_PCI_8192DE_DID 0x8193 /*8192de */
+#define RTL_PCI_8192DE_DID2 0x002B /*92DE */

/*8192 support 16 pages of IO registers*/
#define RTL_MEM_MAPPED_IO_RANGE_8190PCI 0x1000
@@ -129,6 +129,11 @@ enum pci_bridge_vendor {
PCI_BRIDGE_VENDOR_MAX,
};

+struct rtl_pci_capabilities_header {
+ u8 capability_id;
+ u8 next;
+};
+
struct rtl_rx_desc {
u32 dword[8];
} __packed;
@@ -161,6 +166,7 @@ struct rtl_pci {

bool driver_is_goingto_unload;
bool up_first_time;
+ bool first_init;
bool being_init_adapter;
bool irq_enabled;

@@ -197,6 +203,8 @@ struct rtl_pci {

/*QOS & EDCA */
enum acm_method acm_method;
+ u16 shortretry_limit;
+ u16 longretry_limit;
};

struct mp_adapter {
@@ -227,6 +235,7 @@ 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))
Index: wireless-testing/drivers/net/wireless/rtlwifi/Kconfig
===================================================================
--- wireless-testing.orig/drivers/net/wireless/rtlwifi/Kconfig
+++ wireless-testing/drivers/net/wireless/rtlwifi/Kconfig
@@ -10,6 +10,17 @@ config RTL8192CE

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 MAC80211 && EXPERIMENTAL
+ select FW_LOADER
+ select RTLWIFI
+ ---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 RTL8192CU
tristate "Realtek RTL8192CU/RTL8188CU USB Wireless Network Adapter"
depends on MAC80211 && USB && EXPERIMENTAL
@@ -24,10 +35,10 @@ config RTL8192CU

config RTLWIFI
tristate
- depends on RTL8192CE || RTL8192CU
+ depends on RTL8192CE || RTL8192CU || RTL8192SE
default m

config RTL8192C_COMMON
tristate
- depends on RTL8192CE || RTL8192CU
+ depends on RTL8192CE || RTL8192CU || RTL8192SE
default m
Index: wireless-testing/drivers/net/wireless/rtlwifi/Makefile
===================================================================
--- wireless-testing.orig/drivers/net/wireless/rtlwifi/Makefile
+++ wireless-testing/drivers/net/wireless/rtlwifi/Makefile
@@ -22,5 +22,6 @@ endif
obj-$(CONFIG_RTL8192C_COMMON) += rtl8192c/
obj-$(CONFIG_RTL8192CE) += rtl8192ce/
obj-$(CONFIG_RTL8192CU) += rtl8192cu/
+obj-$(CONFIG_RTL8192SE) += rtl8192se/

ccflags-y += -D__CHECK_ENDIAN__
Index: wireless-testing/drivers/net/wireless/rtlwifi/rtl8192se/Makefile
===================================================================
--- /dev/null
+++ wireless-testing/drivers/net/wireless/rtlwifi/rtl8192se/Makefile
@@ -0,0 +1,13 @@
+rtl8192se-objs := \
+ dm.o \
+ fw.o \
+ hw.o \
+ led.o \
+ phy.o \
+ rf.o \
+ sw.o \
+ table.o \
+ trx.o
+
+obj-$(CONFIG_RTL8192SE) += rtl8192se.o
+
Index: wireless-testing/drivers/net/wireless/rtlwifi/cam.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/rtlwifi/cam.c
+++ wireless-testing/drivers/net/wireless/rtlwifi/cam.c
@@ -23,6 +23,8 @@
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
+ * Larry Finger <[email protected]>
+ *
*****************************************************************************/

#include "wifi.h"
Index: wireless-testing/drivers/net/wireless/rtlwifi/core.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/rtlwifi/core.c
+++ wireless-testing/drivers/net/wireless/rtlwifi/core.c
@@ -24,6 +24,7 @@
* Hsinchu 300, Taiwan.
*
* Larry Finger <[email protected]>
+ *
*****************************************************************************/

#include "wifi.h"
@@ -70,6 +71,7 @@ static void rtl_op_stop(struct ieee80211

mac->link_state = MAC80211_NOLINK;
memset(mac->bssid, 0, 6);
+ mac->vendor = PEER_UNKNOWN;

/*reset sec info */
rtl_cam_reset_sec_info(hw);
@@ -85,7 +87,9 @@ static void rtl_op_tx(struct ieee80211_h
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct rtl_tcb_desc tcb_desc;

+ memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc));
if (unlikely(is_hal_stop(rtlhal) || ppsc->rfpwr_state != ERFON))
goto err_free;

@@ -93,12 +97,14 @@ static void rtl_op_tx(struct ieee80211_h
goto err_free;


- rtlpriv->intf_ops->adapter_tx(hw, skb);
+ if (!rtlpriv->intf_ops->waitq_insert(hw, skb))
+ rtlpriv->intf_ops->adapter_tx(hw, skb, &tcb_desc);

return;

err_free:
dev_kfree_skb_any(skb);
+ return;
}

static int rtl_op_add_interface(struct ieee80211_hw *hw,
@@ -134,6 +140,9 @@ static int rtl_op_add_interface(struct i

mac->link_state = MAC80211_LINKED;
rtlpriv->cfg->ops->set_bcn_reg(hw);
+ mac->basic_rates = 0xfff;
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
+ (u8 *) (&mac->basic_rates));
break;
case NL80211_IFTYPE_AP:
RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
@@ -184,6 +193,7 @@ static void rtl_op_remove_interface(stru
mac->vif = NULL;
mac->link_state = MAC80211_NOLINK;
memset(mac->bssid, 0, 6);
+ mac->vendor = PEER_UNKNOWN;
mac->opmode = NL80211_IFTYPE_UNSPECIFIED;
rtlpriv->cfg->ops->set_network_type(hw, mac->opmode);

@@ -222,10 +232,25 @@ static int rtl_op_config(struct ieee8021

/*For LPS */
if (changed & IEEE80211_CONF_CHANGE_PS) {
- if (conf->flags & IEEE80211_CONF_PS)
- rtl_lps_enter(hw);
- else
- rtl_lps_leave(hw);
+ cancel_delayed_work(&rtlpriv->works.ps_work);
+ cancel_delayed_work(&rtlpriv->works.ps_rfon_wq);
+ if (conf->flags & IEEE80211_CONF_PS) {
+ rtlpriv->psc.sw_ps_enabled = true;
+ /* sleep here is must, or we may recv the beacon and
+ * cause mac80211 into wrong ps state, this will cause
+ * power save nullfunc send fail, and further cause
+ * pkt loss, So sleep must quickly but not immediatly
+ * because that will cause nullfunc send by mac80211
+ * fail, and cause pkt loss, we have tested that 5mA
+ * is worked very well */
+ if (!rtlpriv->psc.multi_buffered)
+ queue_delayed_work(rtlpriv->works.rtl_wq,
+ &rtlpriv->works.ps_work,
+ MSECS(5));
+ } else {
+ rtl_swlps_rf_awake(hw);
+ rtlpriv->psc.sw_ps_enabled = false;
+ }
}

if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
@@ -235,8 +260,7 @@ static int rtl_op_config(struct ieee8021
mac->retry_long = hw->conf.long_frame_max_tx_count;
mac->retry_short = hw->conf.long_frame_max_tx_count;
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT,
- (u8 *) (&hw->conf.
- long_frame_max_tx_count));
+ (u8 *) (&hw->conf.long_frame_max_tx_count));
}

if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
@@ -294,8 +318,8 @@ static int rtl_op_config(struct ieee8021
wide_chan = 1;
rtlphy->current_channel = wide_chan;

- rtlpriv->cfg->ops->set_channel_access(hw);
rtlpriv->cfg->ops->switch_channel(hw);
+ rtlpriv->cfg->ops->set_channel_access(hw);
rtlpriv->cfg->ops->set_bw_mode(hw,
hw->conf.channel_type);
}
@@ -343,27 +367,25 @@ static void rtl_op_configure_filter(stru
}
}

- if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
- /*
- *TODO: BIT(5) is probe response BIT(8) is beacon
- *TODO: Use define for BIT(5) and BIT(8)
- */
+ /* if ssid not set to hw don't check bssid
+ * here just used for linked scanning, & linked
+ * and nolink check bssid is set in set network_type */
+ if ((changed_flags & FIF_BCN_PRBRESP_PROMISC) &&
+ (mac->link_state >= MAC80211_LINKED)) {
if (*new_flags & FIF_BCN_PRBRESP_PROMISC)
- mac->rx_mgt_filter |= (BIT(5) | BIT(8));
+ rtlpriv->cfg->ops->set_chk_bssid(hw, false);
else
- mac->rx_mgt_filter &= ~(BIT(5) | BIT(8));
+ rtlpriv->cfg->ops->set_chk_bssid(hw, true);
}

if (changed_flags & FIF_CONTROL) {
if (*new_flags & FIF_CONTROL) {
mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACF];
- mac->rx_ctrl_filter |= RTL_SUPPORTED_CTRL_FILTER;

RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
("Enable receive control frame.\n"));
} else {
mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACF];
- mac->rx_ctrl_filter &= ~RTL_SUPPORTED_CTRL_FILTER;
RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
("Disable receive control frame.\n"));
}
@@ -380,12 +402,6 @@ static void rtl_op_configure_filter(stru
("Disable receive other BSS's frame.\n"));
}
}
-
- rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *) (&mac->rx_conf));
- rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_MGT_FILTER,
- (u8 *) (&mac->rx_mgt_filter));
- rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_CTRL_FILTER,
- (u8 *) (&mac->rx_ctrl_filter));
}

static int _rtl_get_hal_qnum(u16 queue)
@@ -444,8 +460,9 @@ static void rtl_op_bss_info_changed(stru
struct ieee80211_bss_conf *bss_conf, u32 changed)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
- struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
- struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+ struct rtl_mac *mac = rtl_mac(rtlpriv);
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);

mutex_lock(&rtlpriv->locks.conf_mutex);

@@ -492,6 +509,16 @@ static void rtl_op_bss_info_changed(stru
/*TODO: reference to enum ieee80211_bss_change */
if (changed & BSS_CHANGED_ASSOC) {
if (bss_conf->assoc) {
+ /* we should reset all sec info & cam
+ * before set cam after linked, we should not
+ * reset in disassoc, that will cause tkip->wep
+ * fail because some flag will be wrong */
+ /* reset sec info */
+ rtl_cam_reset_sec_info(hw);
+ /* reset cam to fix wep fail issue
+ * when change from wpa to wep */
+ rtl_cam_reset_all_entry(hw);
+
mac->link_state = MAC80211_LINKED;
mac->cnt_after_linked = 0;
mac->assoc_id = bss_conf->aid;
@@ -506,8 +533,7 @@ static void rtl_op_bss_info_changed(stru
mac->link_state = MAC80211_NOLINK;
memset(mac->bssid, 0, 6);

- /* reset sec info */
- rtl_cam_reset_sec_info(hw);
+ mac->vendor = PEER_UNKNOWN;

RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
("BSS_CHANGED_UN_ASSOC\n"));
@@ -583,6 +609,7 @@ static void rtl_op_bss_info_changed(stru
RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
(MAC_FMT "\n", MAC_ARG(bss_conf->bssid)));

+ mac->vendor = PEER_UNKNOWN;
memcpy(mac->bssid, bss_conf->bssid, 6);
if (is_valid_ether_addr(bss_conf->bssid)) {
switch (vif->type) {
@@ -609,17 +636,31 @@ static void rtl_op_bss_info_changed(stru
mac->sgi_40 = false;
mac->sgi_20 = false;

- if (!bss_conf->use_short_slot)
- mac->mode = WIRELESS_MODE_B;
- else
+ if (vif->type == NL80211_IFTYPE_ADHOC) {
mac->mode = WIRELESS_MODE_G;
+ if (rtlpriv->dm.useramask)
+ rtlpriv->cfg->ops->update_rate_mask(hw, 0);
+ else
+ rtlpriv->cfg->ops->update_rate_table(hw);
+ } else {
+ if (!bss_conf->use_short_slot)
+ mac->mode = WIRELESS_MODE_B;
+ else
+ mac->mode = WIRELESS_MODE_G;
+ }
+
+ if (rtlhal->current_bandtype == BAND_ON_5G)
+ mac->mode = WIRELESS_MODE_A;

rcu_read_lock();
sta = ieee80211_find_sta(mac->vif, mac->bssid);

if (sta) {
if (sta->ht_cap.ht_supported) {
- mac->mode = WIRELESS_MODE_N_24G;
+ if (rtlhal->current_bandtype == BAND_ON_2_4G)
+ mac->mode = WIRELESS_MODE_N_24G;
+ else
+ mac->mode = WIRELESS_MODE_N_5G;
mac->ht_enable = true;
}

@@ -657,6 +698,9 @@ static void rtl_op_bss_info_changed(stru
if (changed & BSS_CHANGED_BASIC_RATES) {
if (mac->mode == WIRELESS_MODE_B)
basic_rates = bss_conf->basic_rates | 0x00f;
+ else if (mac->mode == WIRELESS_MODE_G ||
+ mac->mode == WIRELESS_MODE_N_24G)
+ basic_rates = bss_conf->basic_rates | 0xfff;
else
basic_rates = bss_conf->basic_rates | 0xff0;

@@ -797,8 +841,12 @@ static void rtl_op_sw_scan_start(struct
if (mac->link_state == MAC80211_LINKED) {
rtl_lps_leave(hw);
mac->link_state = MAC80211_LINKED_SCANNING;
- } else
+ } else {
rtl_ips_nic_on(hw);
+ }
+
+ /* Dual mac */
+ rtlpriv->rtlhal.load_imrandiqk_setting_for2g = false;

rtlpriv->cfg->ops->led_control(hw, LED_CTL_SITE_SURVEY);
rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_BACKUP);
@@ -811,8 +859,10 @@ static void rtl_op_sw_scan_complete(stru

RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("\n"));

- rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_RESTORE);
mac->act_scanning = false;
+ /* Dual mac */
+ rtlpriv->rtlhal.load_imrandiqk_setting_for2g = false;
+
if (mac->link_state == MAC80211_LINKED_SCANNING) {
mac->link_state = MAC80211_LINKED;

@@ -825,7 +875,7 @@ static void rtl_op_sw_scan_complete(stru
rtlpriv->cfg->ops->update_rate_table(hw);

}
-
+ rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_RESTORE);
}

static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
@@ -866,31 +916,41 @@ static int rtl_op_set_key(struct ieee802
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
("alg:WEP104\n"));
key_type = WEP104_ENCRYPTION;
- rtlpriv->sec.use_defaultkey = true;
break;
case WLAN_CIPHER_SUITE_TKIP:
key_type = TKIP_ENCRYPTION;
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:TKIP\n"));
- if (mac->opmode == NL80211_IFTYPE_ADHOC)
- rtlpriv->sec.use_defaultkey = true;
break;
case WLAN_CIPHER_SUITE_CCMP:
key_type = AESCCMP_ENCRYPTION;
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:CCMP\n"));
- if (mac->opmode == NL80211_IFTYPE_ADHOC)
- rtlpriv->sec.use_defaultkey = true;
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
("alg_err:%x!!!!:\n", key->cipher));
goto out_unlock;
}
+ if (key_type == WEP40_ENCRYPTION ||
+ key_type == WEP104_ENCRYPTION ||
+ mac->opmode == NL80211_IFTYPE_ADHOC)
+ rtlpriv->sec.use_defaultkey = true;
/* <2> get key_idx */
key_idx = (u8) (key->keyidx);
if (key_idx > 3)
goto out_unlock;
/* <3> if pairwise key enable_hw_sec */
group_key = !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE);
+
+ /* WEP will always be group key, but there are two conditions:
+ * 1) WEP only: is just for WEP enc, in this condition
+ * rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION
+ * will be true & enable_hw_sec will be set when WEP
+ * key setting.
+ * 2) WEP(group) + AES(pairwise): some APs like Cisco
+ * may use it, in this condition enable_hw_sec will not
+ * be set when WEP key setting */
+ /* we must reset sec_info after linked before set key,
+ * or some flags will be wrong */
if ((!group_key) || (mac->opmode == NL80211_IFTYPE_ADHOC) ||
rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION) {
if (rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION &&
@@ -898,6 +958,9 @@ static int rtl_op_set_key(struct ieee802
key_type == WEP104_ENCRYPTION))
wep_only = true;
rtlpriv->sec.pairwise_enc_algorithm = key_type;
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ ("set enable_hw_sec, key_type:%x(OPEN:0 WEP40:1 "
+ "TKIP:2 AES:4 WEP104:5)\n", key_type));
rtlpriv->cfg->ops->enable_hw_sec(hw);
}
/* <4> set key based on cmd */
@@ -980,10 +1043,10 @@ out_unlock:
static void rtl_op_rfkill_poll(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
-
bool radio_state;
bool blocked;
u8 valid = 0;
+ static bool init;

if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status))
return;
@@ -993,7 +1056,8 @@ static void rtl_op_rfkill_poll(struct ie
/*if Radio On return true here */
radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid);

- if (valid) {
+ if (valid || !init) {
+ init = true;
if (unlikely(radio_state != rtlpriv->rfkill.rfkill_state)) {
rtlpriv->rfkill.rfkill_state = radio_state;

Index: wireless-testing/drivers/net/wireless/rtlwifi/rc.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/rtlwifi/rc.c
+++ wireless-testing/drivers/net/wireless/rtlwifi/rc.c
@@ -35,20 +35,15 @@
*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
- *CCK11M or OFDM_54M based on wireless mode.
+ *highest rate based on wireless mode used for iwconfig
+ *show Tx rate.
*/
static u8 _rtl_rc_get_highest_rix(struct rtl_priv *rtlpriv,
struct sk_buff *skb, bool not_data)
{
struct rtl_mac *rtlmac = rtl_mac(rtlpriv);
-
- /*
- *mgt use 1M, although we have check it
- *before this function use rate_control_send_low,
- *we still check it here
- */
- if (not_data)
- return rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M];
+ struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);

/*
*this rate is no use for true rate, firmware
@@ -57,13 +52,31 @@ static u8 _rtl_rc_get_highest_rix(struct
*2.in rtl_get_tcb_desc when we check rate is
* 1M we will not use FW rate but user rate.
*/
- if (rtl_is_special_data(rtlpriv->mac80211.hw, skb, true)) {
- return rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M];
+ if (rtl_is_special_data(rtlpriv->mac80211.hw, skb, true) ||
+ not_data) {
+ return 0;
} else {
- if (rtlmac->mode == WIRELESS_MODE_B)
- return rtlpriv->cfg->maps[RTL_RC_CCK_RATE11M];
- else
- return rtlpriv->cfg->maps[RTL_RC_OFDM_RATE54M];
+ if (rtlhal->current_bandtype == BAND_ON_2_4G) {
+ if (rtlmac->mode == WIRELESS_MODE_B) {
+ return B_MODE_MAX_RIX;
+ } else if (rtlmac->mode == WIRELESS_MODE_G) {
+ return G_MODE_MAX_RIX;
+ } else {
+ if (get_rf_type(rtlphy) != RF_2T2R)
+ return N_MODE_MCS7_RIX;
+ else
+ return N_MODE_MCS15_RIX;
+ }
+ } else {
+ if (rtlmac->mode == WIRELESS_MODE_A) {
+ return A_MODE_MAX_RIX;
+ } else {
+ if (get_rf_type(rtlphy) != RF_2T2R)
+ return N_MODE_MCS7_RIX;
+ else
+ return N_MODE_MCS15_RIX;
+ }
+ }
}
}

@@ -76,7 +89,7 @@ static void _rtl_rc_rate_set_series(stru
struct rtl_mac *mac = rtl_mac(rtlpriv);

rate->count = tries;
- rate->idx = (rix > 0x2) ? rix : 0x2;
+ rate->idx = rix >= 0x00 ? rix : 0x00;

if (!not_data) {
if (txrc->short_preamble)
Index: wireless-testing/drivers/net/wireless/rtlwifi/rc.h
===================================================================
--- wireless-testing.orig/drivers/net/wireless/rtlwifi/rc.h
+++ wireless-testing/drivers/net/wireless/rtlwifi/rc.h
@@ -30,6 +30,14 @@
#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
+
struct rtl_rate_priv {
u8 cur_ratetab_idx;
u8 ht_cap;
@@ -37,4 +45,5 @@ struct rtl_rate_priv {

int rtl_rate_control_register(void);
void rtl_rate_control_unregister(void);
+
#endif
Index: wireless-testing/drivers/net/wireless/rtlwifi/regd.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/rtlwifi/regd.c
+++ wireless-testing/drivers/net/wireless/rtlwifi/regd.c
@@ -66,6 +66,27 @@ static struct country_code_to_enum_rd al
NL80211_RRF_PASSIVE_SCAN | \
NL80211_RRF_NO_OFDM)

+/* 5G chan 36 - chan 64*/
+#define RTL819x_5GHZ_5150_5350 \
+ REG_RULE(5150-10, 5350+10, 40, 0, 30, \
+ NL80211_RRF_PASSIVE_SCAN | \
+ NL80211_RRF_NO_IBSS)
+
+/* 5G chan 100 - chan 165*/
+#define RTL819x_5GHZ_5470_5850 \
+ REG_RULE(5470-10, 5850+10, 40, 0, 30, \
+ NL80211_RRF_PASSIVE_SCAN | \
+ NL80211_RRF_NO_IBSS)
+
+/* 5G chan 149 - chan 165*/
+#define RTL819x_5GHZ_5725_5850 \
+ REG_RULE(5725-10, 5850+10, 40, 0, 30, \
+ NL80211_RRF_PASSIVE_SCAN | \
+ NL80211_RRF_NO_IBSS)
+
+#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",
@@ -74,22 +95,53 @@ static const struct ieee80211_regdomain
}
};

-static const struct ieee80211_regdomain rtl_regdom_global = {
- .n_reg_rules = 3,
+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,
- RTL819x_2GHZ_CH14,
+ 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_world = {
- .n_reg_rules = 2,
+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_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,
}
};

@@ -162,6 +214,8 @@ static void _rtl_reg_apply_active_scan_f
u32 bandwidth = 0;
int r;

+ if (!wiphy->bands[IEEE80211_BAND_2GHZ])
+ return;
sband = wiphy->bands[IEEE80211_BAND_2GHZ];

/*
@@ -292,25 +346,26 @@ static const struct ieee80211_regdomain
{
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_TELEC_NETGEAR:
- return &rtl_regdom_world;
+ 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_global;
+ return &rtl_regdom_14_60_64;
case COUNTRY_CODE_GLOBAL_DOMAIN:
- return &rtl_regdom_global;
- case COUNTRY_CODE_WORLD_WIDE_13:
- return &rtl_regdom_world;
+ return &rtl_regdom_14;
default:
- return &rtl_regdom_world;
+ return &rtl_regdom_no_midband;
}
}

@@ -355,8 +410,8 @@ int rtl_regd_init(struct ieee80211_hw *h
if (wiphy == NULL || &rtlpriv->regd == NULL)
return -EINVAL;

- /* force the channel plan to world wide 13 */
- rtlpriv->regd.country_code = COUNTRY_CODE_WORLD_WIDE_13;
+ /* init country_code from efuse channel plan */
+ rtlpriv->regd.country_code = rtlpriv->efuse.channel_plan;

RT_TRACE(rtlpriv, COMP_REGD, DBG_TRACE,
(KERN_DEBUG "rtl: EEPROM regdomain: 0x%0x\n",
@@ -373,8 +428,8 @@ int rtl_regd_init(struct ieee80211_hw *h
country = _rtl_regd_find_country(rtlpriv->regd.country_code);

if (country) {
- rtlpriv->regd.alpha2[0] = country->isoName[0];
- rtlpriv->regd.alpha2[1] = country->isoName[1];
+ 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';
Index: wireless-testing/drivers/net/wireless/rtlwifi/regd.h
===================================================================
--- wireless-testing.orig/drivers/net/wireless/rtlwifi/regd.h
+++ wireless-testing/drivers/net/wireless/rtlwifi/regd.h
@@ -32,7 +32,7 @@

struct country_code_to_enum_rd {
u16 countrycode;
- const char *isoName;
+ const char *iso_name;
};

enum country_code_type_t {
@@ -58,4 +58,5 @@ int rtl_regd_init(struct ieee80211_hw *h
int (*reg_notifier) (struct wiphy *wiphy,
struct regulatory_request *request));
int rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request);
+
#endif
Index: wireless-testing/drivers/net/wireless/rtlwifi/wifi.h
===================================================================
--- wireless-testing.orig/drivers/net/wireless/rtlwifi/wifi.h
+++ wireless-testing/drivers/net/wireless/rtlwifi/wifi.h
@@ -1404,7 +1404,8 @@ struct rtl_intf_ops {
int (*adapter_start) (struct ieee80211_hw *hw);
void (*adapter_stop) (struct ieee80211_hw *hw);

- int (*adapter_tx) (struct ieee80211_hw *hw, struct sk_buff *skb);
+ int (*adapter_tx) (struct ieee80211_hw *hw, struct sk_buff *skb,
+ struct rtl_tcb_desc *ptcb_desc);
int (*reset_trx_ring) (struct ieee80211_hw *hw);
bool (*waitq_insert) (struct ieee80211_hw *hw, struct sk_buff *skb);