mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-25 11:30:54 +07:00
rtl8192ce: Add new driver
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
412b31334b
commit
0c8173385e
@ -279,6 +279,7 @@ source "drivers/net/wireless/libertas/Kconfig"
|
||||
source "drivers/net/wireless/orinoco/Kconfig"
|
||||
source "drivers/net/wireless/p54/Kconfig"
|
||||
source "drivers/net/wireless/rt2x00/Kconfig"
|
||||
source "drivers/net/wireless/rtlwifi/Kconfig"
|
||||
source "drivers/net/wireless/wl1251/Kconfig"
|
||||
source "drivers/net/wireless/wl12xx/Kconfig"
|
||||
source "drivers/net/wireless/zd1211rw/Kconfig"
|
||||
|
@ -24,6 +24,7 @@ obj-$(CONFIG_B43LEGACY) += b43legacy/
|
||||
obj-$(CONFIG_ZD1211RW) += zd1211rw/
|
||||
obj-$(CONFIG_RTL8180) += rtl818x/
|
||||
obj-$(CONFIG_RTL8187) += rtl818x/
|
||||
obj-$(CONFIG_RTL8192CE) += rtlwifi/
|
||||
|
||||
# 16-bit wireless PCMCIA client drivers
|
||||
obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o
|
||||
|
15
drivers/net/wireless/rtlwifi/Kconfig
Normal file
15
drivers/net/wireless/rtlwifi/Kconfig
Normal file
@ -0,0 +1,15 @@
|
||||
config RTL8192CE
|
||||
tristate "Realtek RTL8192CE/RTL8188SE Wireless Network Adapter"
|
||||
depends on MAC80211 && EXPERIMENTAL
|
||||
select FW_LOADER
|
||||
select RTLWIFI
|
||||
---help---
|
||||
This is the driver for Realtek RTL8192CE/RTL8188CE 802.11n PCIe
|
||||
wireless network adapters.
|
||||
|
||||
If you choose to build it as a module, it will be calledrtl8192ce.
|
||||
|
||||
config RTLWIFI
|
||||
tristate
|
||||
depends on RTL8192CE
|
||||
default m
|
13
drivers/net/wireless/rtlwifi/Makefile
Normal file
13
drivers/net/wireless/rtlwifi/Makefile
Normal file
@ -0,0 +1,13 @@
|
||||
obj-$(CONFIG_RTLWIFI) += rtlwifi.o
|
||||
rtlwifi-objs := \
|
||||
base.o \
|
||||
cam.o \
|
||||
core.o \
|
||||
debug.o \
|
||||
efuse.o \
|
||||
pci.o \
|
||||
ps.o \
|
||||
rc.o \
|
||||
regd.o
|
||||
|
||||
obj-$(CONFIG_RTL8192CE) += rtl8192ce/
|
958
drivers/net/wireless/rtlwifi/base.c
Normal file
958
drivers/net/wireless/rtlwifi/base.c
Normal file
@ -0,0 +1,958 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2009-2010 Realtek Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* wlanfae <wlanfae@realtek.com>
|
||||
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
|
||||
* Hsinchu 300, Taiwan.
|
||||
*
|
||||
* Larry Finger <Larry.Finger@lwfinger.net>
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include <linux/ip.h>
|
||||
#include "wifi.h"
|
||||
#include "rc.h"
|
||||
#include "base.h"
|
||||
#include "efuse.h"
|
||||
#include "cam.h"
|
||||
#include "ps.h"
|
||||
#include "regd.h"
|
||||
|
||||
/*
|
||||
*NOTICE!!!: This file will be very big, we hsould
|
||||
*keep it clear under follwing roles:
|
||||
*
|
||||
*This file include follwing part, so, if you add new
|
||||
*functions into this file, please check which part it
|
||||
*should includes. or check if you should add new part
|
||||
*for this file:
|
||||
*
|
||||
*1) mac80211 init functions
|
||||
*2) tx information functions
|
||||
*3) functions called by core.c
|
||||
*4) wq & timer callback functions
|
||||
*5) frame process functions
|
||||
*6) sysfs functions
|
||||
*7) ...
|
||||
*/
|
||||
|
||||
/*********************************************************
|
||||
*
|
||||
* mac80211 init functions
|
||||
*
|
||||
*********************************************************/
|
||||
static struct ieee80211_channel rtl_channeltable[] = {
|
||||
{.center_freq = 2412, .hw_value = 1,},
|
||||
{.center_freq = 2417, .hw_value = 2,},
|
||||
{.center_freq = 2422, .hw_value = 3,},
|
||||
{.center_freq = 2427, .hw_value = 4,},
|
||||
{.center_freq = 2432, .hw_value = 5,},
|
||||
{.center_freq = 2437, .hw_value = 6,},
|
||||
{.center_freq = 2442, .hw_value = 7,},
|
||||
{.center_freq = 2447, .hw_value = 8,},
|
||||
{.center_freq = 2452, .hw_value = 9,},
|
||||
{.center_freq = 2457, .hw_value = 10,},
|
||||
{.center_freq = 2462, .hw_value = 11,},
|
||||
{.center_freq = 2467, .hw_value = 12,},
|
||||
{.center_freq = 2472, .hw_value = 13,},
|
||||
{.center_freq = 2484, .hw_value = 14,},
|
||||
};
|
||||
|
||||
static struct ieee80211_rate rtl_ratetable[] = {
|
||||
{.bitrate = 10, .hw_value = 0x00,},
|
||||
{.bitrate = 20, .hw_value = 0x01,},
|
||||
{.bitrate = 55, .hw_value = 0x02,},
|
||||
{.bitrate = 110, .hw_value = 0x03,},
|
||||
{.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),
|
||||
|
||||
.bitrates = rtl_ratetable,
|
||||
.n_bitrates = ARRAY_SIZE(rtl_ratetable),
|
||||
|
||||
.ht_cap = {0},
|
||||
};
|
||||
|
||||
static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw,
|
||||
struct ieee80211_sta_ht_cap *ht_cap)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &(rtlpriv->phy);
|
||||
|
||||
ht_cap->ht_supported = true;
|
||||
ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
|
||||
IEEE80211_HT_CAP_SGI_40 |
|
||||
IEEE80211_HT_CAP_SGI_20 |
|
||||
IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU;
|
||||
|
||||
/*
|
||||
*Maximum length of AMPDU that the STA can receive.
|
||||
*Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets)
|
||||
*/
|
||||
ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
|
||||
|
||||
/*Minimum MPDU start spacing , */
|
||||
ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
|
||||
|
||||
ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
|
||||
|
||||
/*
|
||||
*hw->wiphy->bands[IEEE80211_BAND_2GHZ]
|
||||
*base on ant_num
|
||||
*rx_mask: RX mask
|
||||
*if rx_ant =1 rx_mask[0]=0xff;==>MCS0-MCS7
|
||||
*if rx_ant =2 rx_mask[1]=0xff;==>MCS8-MCS15
|
||||
*if rx_ant >=3 rx_mask[2]=0xff;
|
||||
*if BW_40 rx_mask[4]=0x01;
|
||||
*highest supported RX rate
|
||||
*/
|
||||
if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_2T2R) {
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("1T2R or 2T2R\n"));
|
||||
|
||||
ht_cap->mcs.rx_mask[0] = 0xFF;
|
||||
ht_cap->mcs.rx_mask[1] = 0xFF;
|
||||
ht_cap->mcs.rx_mask[4] = 0x01;
|
||||
|
||||
ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS15;
|
||||
} else if (get_rf_type(rtlphy) == RF_1T1R) {
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("1T1R\n"));
|
||||
|
||||
ht_cap->mcs.rx_mask[0] = 0xFF;
|
||||
ht_cap->mcs.rx_mask[1] = 0x00;
|
||||
ht_cap->mcs.rx_mask[4] = 0x01;
|
||||
|
||||
ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS7;
|
||||
}
|
||||
}
|
||||
|
||||
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 ieee80211_supported_band *sband;
|
||||
|
||||
/* <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;
|
||||
|
||||
/* <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_REPORTS_TX_ACK_STATUS | 0;
|
||||
|
||||
hw->wiphy->interface_modes =
|
||||
BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
|
||||
|
||||
hw->wiphy->rts_threshold = 2347;
|
||||
|
||||
hw->queues = AC_MAX;
|
||||
hw->extra_tx_headroom = RTL_TX_HEADER_SIZE;
|
||||
|
||||
/* 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_rate_tries = 4;
|
||||
/* hw->max_rates = 1; */
|
||||
|
||||
/* <6> mac address */
|
||||
if (is_valid_ether_addr(rtlefuse->dev_addr)) {
|
||||
SET_IEEE80211_PERM_ADDR(hw, rtlefuse->dev_addr);
|
||||
} else {
|
||||
u8 rtlmac[] = { 0x00, 0xe0, 0x4c, 0x81, 0x92, 0x00 };
|
||||
get_random_bytes((rtlmac + (ETH_ALEN - 1)), 1);
|
||||
SET_IEEE80211_PERM_ADDR(hw, rtlmac);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void _rtl_init_deferred_work(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
/* <1> timer */
|
||||
init_timer(&rtlpriv->works.watchdog_timer);
|
||||
setup_timer(&rtlpriv->works.watchdog_timer,
|
||||
rtl_watch_dog_timer_callback, (unsigned long)hw);
|
||||
|
||||
/* <2> work queue */
|
||||
rtlpriv->works.hw = hw;
|
||||
rtlpriv->works.rtl_wq = create_workqueue(rtlpriv->cfg->name);
|
||||
INIT_DELAYED_WORK(&rtlpriv->works.watchdog_wq,
|
||||
(void *)rtl_watchdog_wq_callback);
|
||||
INIT_DELAYED_WORK(&rtlpriv->works.ips_nic_off_wq,
|
||||
(void *)rtl_ips_nic_off_wq_callback);
|
||||
|
||||
}
|
||||
|
||||
void rtl_deinit_deferred_work(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
del_timer_sync(&rtlpriv->works.watchdog_timer);
|
||||
|
||||
cancel_delayed_work(&rtlpriv->works.watchdog_wq);
|
||||
cancel_delayed_work(&rtlpriv->works.ips_nic_off_wq);
|
||||
}
|
||||
|
||||
void rtl_init_rfkill(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
bool radio_state;
|
||||
bool blocked;
|
||||
u8 valid = 0;
|
||||
|
||||
/*set init state to rf on */
|
||||
rtlpriv->rfkill.rfkill_state = 1;
|
||||
|
||||
radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid);
|
||||
|
||||
if (valid) {
|
||||
RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
|
||||
(KERN_INFO "wireless switch is %s\n",
|
||||
rtlpriv->rfkill.rfkill_state ? "on" : "off"));
|
||||
|
||||
rtlpriv->rfkill.rfkill_state = radio_state;
|
||||
|
||||
blocked = (rtlpriv->rfkill.rfkill_state == 1) ? 0 : 1;
|
||||
wiphy_rfkill_set_hw_state(hw->wiphy, blocked);
|
||||
}
|
||||
|
||||
wiphy_rfkill_start_polling(hw->wiphy);
|
||||
}
|
||||
|
||||
void rtl_deinit_rfkill(struct ieee80211_hw *hw)
|
||||
{
|
||||
wiphy_rfkill_stop_polling(hw->wiphy);
|
||||
}
|
||||
|
||||
int rtl_init_core(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw));
|
||||
|
||||
/* <1> init mac80211 */
|
||||
_rtl_init_mac80211(hw);
|
||||
rtlmac->hw = hw;
|
||||
|
||||
/* <2> rate control register */
|
||||
if (rtl_rate_control_register()) {
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
||||
("rtl: Unable to register rtl_rc,"
|
||||
"use default RC !!\n"));
|
||||
} else {
|
||||
hw->rate_control_algorithm = "rtl_rc";
|
||||
}
|
||||
|
||||
/*
|
||||
* <3> init CRDA must come after init
|
||||
* mac80211 hw in _rtl_init_mac80211.
|
||||
*/
|
||||
if (rtl_regd_init(hw, rtl_reg_notifier)) {
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("REGD init failed\n"));
|
||||
return 1;
|
||||
} else {
|
||||
/* CRDA regd hint must after init CRDA */
|
||||
if (regulatory_hint(hw->wiphy, rtlpriv->regd.alpha2)) {
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
|
||||
("regulatory_hint fail\n"));
|
||||
}
|
||||
}
|
||||
|
||||
/* <4> locks */
|
||||
sema_init(&rtlpriv->locks.ips_sem, 1);
|
||||
sema_init(&rtlpriv->locks.conf_sem, 1);
|
||||
spin_lock_init(&rtlpriv->locks.irq_th_lock);
|
||||
spin_lock_init(&rtlpriv->locks.h2c_lock);
|
||||
spin_lock_init(&rtlpriv->locks.rf_ps_lock);
|
||||
spin_lock_init(&rtlpriv->locks.rf_lock);
|
||||
spin_lock_init(&rtlpriv->locks.lps_lock);
|
||||
|
||||
rtlmac->link_state = MAC80211_NOLINK;
|
||||
|
||||
/* <5> init deferred work */
|
||||
_rtl_init_deferred_work(hw);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rtl_deinit_core(struct ieee80211_hw *hw)
|
||||
{
|
||||
/*RC*/
|
||||
rtl_rate_control_unregister();
|
||||
}
|
||||
|
||||
void rtl_init_rx_config(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
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));
|
||||
}
|
||||
|
||||
/*********************************************************
|
||||
*
|
||||
* tx information functions
|
||||
*
|
||||
*********************************************************/
|
||||
static void _rtl_qurey_shortpreamble_mode(struct ieee80211_hw *hw,
|
||||
struct rtl_tcb_desc *tcb_desc,
|
||||
struct ieee80211_tx_info *info)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
u8 rate_flag = info->control.rates[0].flags;
|
||||
|
||||
tcb_desc->use_shortpreamble = false;
|
||||
|
||||
/* 1M can only use Long Preamble. 11B spec */
|
||||
if (tcb_desc->hw_rate == rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M])
|
||||
return;
|
||||
else if (rate_flag & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
|
||||
tcb_desc->use_shortpreamble = true;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void _rtl_query_shortgi(struct ieee80211_hw *hw,
|
||||
struct rtl_tcb_desc *tcb_desc,
|
||||
struct ieee80211_tx_info *info)
|
||||
{
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
u8 rate_flag = info->control.rates[0].flags;
|
||||
|
||||
tcb_desc->use_shortgi = false;
|
||||
|
||||
if (!mac->ht_enable)
|
||||
return;
|
||||
|
||||
if (!mac->sgi_40 && !mac->sgi_20)
|
||||
return;
|
||||
|
||||
if ((mac->bw_40 == true) && mac->sgi_40)
|
||||
tcb_desc->use_shortgi = true;
|
||||
else if ((mac->bw_40 == false) && mac->sgi_20)
|
||||
tcb_desc->use_shortgi = true;
|
||||
|
||||
if (!(rate_flag & IEEE80211_TX_RC_SHORT_GI))
|
||||
tcb_desc->use_shortgi = false;
|
||||
|
||||
}
|
||||
|
||||
static void _rtl_query_protection_mode(struct ieee80211_hw *hw,
|
||||
struct rtl_tcb_desc *tcb_desc,
|
||||
struct ieee80211_tx_info *info)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
u8 rate_flag = info->control.rates[0].flags;
|
||||
|
||||
/* Common Settings */
|
||||
tcb_desc->b_rts_stbc = false;
|
||||
tcb_desc->b_cts_enable = false;
|
||||
tcb_desc->rts_sc = 0;
|
||||
tcb_desc->b_rts_bw = false;
|
||||
tcb_desc->b_rts_use_shortpreamble = false;
|
||||
tcb_desc->b_rts_use_shortgi = false;
|
||||
|
||||
if (rate_flag & IEEE80211_TX_RC_USE_CTS_PROTECT) {
|
||||
/* Use CTS-to-SELF in protection mode. */
|
||||
tcb_desc->b_rts_enable = true;
|
||||
tcb_desc->b_cts_enable = true;
|
||||
tcb_desc->rts_rate = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE24M];
|
||||
} else if (rate_flag & IEEE80211_TX_RC_USE_RTS_CTS) {
|
||||
/* Use RTS-CTS in protection mode. */
|
||||
tcb_desc->b_rts_enable = true;
|
||||
tcb_desc->rts_rate = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE24M];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void _rtl_txrate_selectmode(struct ieee80211_hw *hw,
|
||||
struct rtl_tcb_desc *tcb_desc)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
|
||||
if (!tcb_desc->disable_ratefallback || !tcb_desc->use_driver_rate) {
|
||||
if (mac->opmode == NL80211_IFTYPE_STATION)
|
||||
tcb_desc->ratr_index = 0;
|
||||
else if (mac->opmode == NL80211_IFTYPE_ADHOC) {
|
||||
if (tcb_desc->b_multicast || tcb_desc->b_broadcast) {
|
||||
tcb_desc->hw_rate =
|
||||
rtlpriv->cfg->maps[RTL_RC_CCK_RATE2M];
|
||||
tcb_desc->use_driver_rate = 1;
|
||||
} else {
|
||||
/* TODO */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rtlpriv->dm.b_useramask) {
|
||||
/* TODO we will differentiate adhoc and station futrue */
|
||||
tcb_desc->mac_id = 0;
|
||||
|
||||
if ((mac->mode == WIRELESS_MODE_N_24G) ||
|
||||
(mac->mode == WIRELESS_MODE_N_5G)) {
|
||||
tcb_desc->ratr_index = RATR_INX_WIRELESS_NGB;
|
||||
} else if (mac->mode & WIRELESS_MODE_G) {
|
||||
tcb_desc->ratr_index = RATR_INX_WIRELESS_GB;
|
||||
} else if (mac->mode & WIRELESS_MODE_B) {
|
||||
tcb_desc->ratr_index = RATR_INX_WIRELESS_B;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void _rtl_query_bandwidth_mode(struct ieee80211_hw *hw,
|
||||
struct rtl_tcb_desc *tcb_desc)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
|
||||
tcb_desc->b_packet_bw = false;
|
||||
|
||||
if (!mac->bw_40 || !mac->ht_enable)
|
||||
return;
|
||||
|
||||
if (tcb_desc->b_multicast || tcb_desc->b_broadcast)
|
||||
return;
|
||||
|
||||
/*use legency rate, shall use 20MHz */
|
||||
if (tcb_desc->hw_rate <= rtlpriv->cfg->maps[RTL_RC_OFDM_RATE54M])
|
||||
return;
|
||||
|
||||
tcb_desc->b_packet_bw = true;
|
||||
}
|
||||
|
||||
static u8 _rtl_get_highest_n_rate(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &(rtlpriv->phy);
|
||||
u8 hw_rate;
|
||||
|
||||
if (get_rf_type(rtlphy) == RF_2T2R)
|
||||
hw_rate = rtlpriv->cfg->maps[RTL_RC_HT_RATEMCS15];
|
||||
else
|
||||
hw_rate = rtlpriv->cfg->maps[RTL_RC_HT_RATEMCS7];
|
||||
|
||||
return hw_rate;
|
||||
}
|
||||
|
||||
void rtl_get_tcb_desc(struct ieee80211_hw *hw,
|
||||
struct ieee80211_tx_info *info,
|
||||
struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw));
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
|
||||
struct ieee80211_rate *txrate;
|
||||
u16 fc = le16_to_cpu(hdr->frame_control);
|
||||
|
||||
memset(tcb_desc, 0, sizeof(struct rtl_tcb_desc));
|
||||
|
||||
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
|
||||
*in rtl_rc.c if skb is special data or
|
||||
*mgt which need low data rate.
|
||||
*/
|
||||
|
||||
/*
|
||||
*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]) {
|
||||
tcb_desc->use_driver_rate = true;
|
||||
tcb_desc->ratr_index = 7;
|
||||
|
||||
tcb_desc->hw_rate =
|
||||
rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M];
|
||||
tcb_desc->disable_ratefallback = 1;
|
||||
} else {
|
||||
/*
|
||||
*because hw will nerver use hw_rate
|
||||
*when tcb_desc->use_driver_rate = false
|
||||
*so we never set highest N rate here,
|
||||
*and N rate will all be controled by FW
|
||||
*when tcb_desc->use_driver_rate = false
|
||||
*/
|
||||
if (rtlmac->ht_enable) {
|
||||
tcb_desc->hw_rate = _rtl_get_highest_n_rate(hw);
|
||||
} else {
|
||||
if (rtlmac->mode == WIRELESS_MODE_B) {
|
||||
tcb_desc->hw_rate =
|
||||
rtlpriv->cfg->maps[RTL_RC_CCK_RATE11M];
|
||||
} else {
|
||||
tcb_desc->hw_rate =
|
||||
rtlpriv->cfg->maps[RTL_RC_OFDM_RATE54M];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_multicast_ether_addr(ieee80211_get_DA(hdr)))
|
||||
tcb_desc->b_multicast = 1;
|
||||
else if (is_broadcast_ether_addr(ieee80211_get_DA(hdr)))
|
||||
tcb_desc->b_broadcast = 1;
|
||||
|
||||
_rtl_txrate_selectmode(hw, tcb_desc);
|
||||
_rtl_query_bandwidth_mode(hw, tcb_desc);
|
||||
_rtl_qurey_shortpreamble_mode(hw, tcb_desc, info);
|
||||
_rtl_query_shortgi(hw, tcb_desc, info);
|
||||
_rtl_query_protection_mode(hw, tcb_desc, info);
|
||||
} else {
|
||||
tcb_desc->use_driver_rate = true;
|
||||
tcb_desc->ratr_index = 7;
|
||||
tcb_desc->disable_ratefallback = 1;
|
||||
tcb_desc->mac_id = 0;
|
||||
|
||||
tcb_desc->hw_rate = rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M];
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(rtl_get_tcb_desc);
|
||||
|
||||
bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
{
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
|
||||
u16 fc = le16_to_cpu(hdr->frame_control);
|
||||
|
||||
if (ieee80211_is_auth(fc)) {
|
||||
RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, ("MAC80211_LINKING\n"));
|
||||
rtl_ips_nic_on(hw);
|
||||
|
||||
mac->link_state = MAC80211_LINKING;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
|
||||
{
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
u16 fc = le16_to_cpu(hdr->frame_control);
|
||||
u8 *act = (u8 *) (((u8 *) skb->data + MAC80211_3ADDR_LEN));
|
||||
u8 category;
|
||||
|
||||
if (!ieee80211_is_action(fc))
|
||||
return true;
|
||||
|
||||
category = *act;
|
||||
act++;
|
||||
switch (category) {
|
||||
case ACT_CAT_BA:
|
||||
switch (*act) {
|
||||
case ACT_ADDBAREQ:
|
||||
if (mac->act_scanning)
|
||||
return false;
|
||||
|
||||
RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG,
|
||||
("%s ACT_ADDBAREQ From :" MAC_FMT "\n",
|
||||
is_tx ? "Tx" : "Rx", MAC_ARG(hdr->addr2)));
|
||||
break;
|
||||
case ACT_ADDBARSP:
|
||||
RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG,
|
||||
("%s ACT_ADDBARSP From :" MAC_FMT "\n",
|
||||
is_tx ? "Tx" : "Rx", MAC_ARG(hdr->addr2)));
|
||||
break;
|
||||
case ACT_DELBA:
|
||||
RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG,
|
||||
("ACT_ADDBADEL From :" MAC_FMT "\n",
|
||||
MAC_ARG(hdr->addr2)));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*should call before software enc*/
|
||||
u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
|
||||
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
|
||||
u16 fc = le16_to_cpu(hdr->frame_control);
|
||||
u16 ether_type;
|
||||
u8 mac_hdr_len = ieee80211_get_hdrlen_from_skb(skb);
|
||||
const struct iphdr *ip;
|
||||
|
||||
if (!ieee80211_is_data(fc))
|
||||
goto end;
|
||||
|
||||
if (ieee80211_is_nullfunc(fc))
|
||||
return true;
|
||||
|
||||
ip = (struct iphdr *)((u8 *) skb->data + mac_hdr_len +
|
||||
SNAP_SIZE + PROTOC_TYPE_SIZE);
|
||||
ether_type = *(u16 *) ((u8 *) skb->data + mac_hdr_len + SNAP_SIZE);
|
||||
ether_type = ntohs(ether_type);
|
||||
|
||||
if (ETH_P_IP == ether_type) {
|
||||
if (IPPROTO_UDP == ip->protocol) {
|
||||
struct udphdr *udp = (struct udphdr *)((u8 *) ip +
|
||||
(ip->ihl << 2));
|
||||
if (((((u8 *) udp)[1] == 68) &&
|
||||
(((u8 *) udp)[3] == 67)) ||
|
||||
((((u8 *) udp)[1] == 67) &&
|
||||
(((u8 *) udp)[3] == 68))) {
|
||||
/*
|
||||
* 68 : UDP BOOTP client
|
||||
* 67 : UDP BOOTP server
|
||||
*/
|
||||
RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV),
|
||||
DBG_DMESG, ("dhcp %s !!\n",
|
||||
(is_tx) ? "Tx" : "Rx"));
|
||||
|
||||
if (is_tx) {
|
||||
rtl_lps_leave(hw);
|
||||
ppsc->last_delaylps_stamp_jiffies =
|
||||
jiffies;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (ETH_P_ARP == ether_type) {
|
||||
if (is_tx) {
|
||||
rtl_lps_leave(hw);
|
||||
ppsc->last_delaylps_stamp_jiffies = jiffies;
|
||||
}
|
||||
|
||||
return true;
|
||||
} else if (ETH_P_PAE == ether_type) {
|
||||
RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG,
|
||||
("802.1X %s EAPOL pkt!!\n", (is_tx) ? "Tx" : "Rx"));
|
||||
|
||||
if (is_tx) {
|
||||
rtl_lps_leave(hw);
|
||||
ppsc->last_delaylps_stamp_jiffies = jiffies;
|
||||
}
|
||||
|
||||
return true;
|
||||
} else if (0x86DD == ether_type) {
|
||||
return true;
|
||||
}
|
||||
|
||||
end:
|
||||
return false;
|
||||
}
|
||||
|
||||
/*********************************************************
|
||||
*
|
||||
* functions called by core.c
|
||||
*
|
||||
*********************************************************/
|
||||
int rtl_tx_agg_start(struct ieee80211_hw *hw, const u8 *ra, u16 tid, u16 *ssn)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_tid_data *tid_data;
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG,
|
||||
("on ra = %pM tid = %d\n", ra, tid));
|
||||
|
||||
if (unlikely(tid >= MAX_TID_COUNT))
|
||||
return -EINVAL;
|
||||
|
||||
if (mac->tids[tid].agg.agg_state != RTL_AGG_OFF) {
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
|
||||
("Start AGG when state is not RTL_AGG_OFF !\n"));
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
tid_data = &mac->tids[tid];
|
||||
*ssn = SEQ_TO_SN(tid_data->seq_number);
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG,
|
||||
("HW queue is empty tid:%d\n", tid));
|
||||
tid_data->agg.agg_state = RTL_AGG_ON;
|
||||
|
||||
ieee80211_start_tx_ba_cb_irqsafe(mac->vif, ra, tid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtl_tx_agg_stop(struct ieee80211_hw *hw, const u8 * ra, u16 tid)
|
||||
{
|
||||
int ssn = -1;
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
struct rtl_tid_data *tid_data;
|
||||
|
||||
if (!ra) {
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("ra = NULL\n"));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (unlikely(tid >= MAX_TID_COUNT))
|
||||
return -EINVAL;
|
||||
|
||||
if (mac->tids[tid].agg.agg_state != RTL_AGG_ON)
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
|
||||
("Stopping AGG while state not ON or starting\n"));
|
||||
|
||||
tid_data = &mac->tids[tid];
|
||||
ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4;
|
||||
|
||||
mac->tids[tid].agg.agg_state = RTL_AGG_OFF;
|
||||
|
||||
ieee80211_stop_tx_ba_cb_irqsafe(mac->vif, ra, tid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************
|
||||
*
|
||||
* wq & timer callback functions
|
||||
*
|
||||
*********************************************************/
|
||||
void rtl_watchdog_wq_callback(void *data)
|
||||
{
|
||||
struct rtl_works *rtlworks = container_of_dwork_rtl(data,
|
||||
struct rtl_works,
|
||||
watchdog_wq);
|
||||
struct ieee80211_hw *hw = rtlworks->hw;
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
|
||||
bool b_busytraffic = false;
|
||||
bool b_higher_busytraffic = false;
|
||||
bool b_higher_busyrxtraffic = false;
|
||||
bool b_higher_busytxtraffic = false;
|
||||
|
||||
u8 idx = 0;
|
||||
u32 rx_cnt_inp4eriod = 0;
|
||||
u32 tx_cnt_inp4eriod = 0;
|
||||
u32 aver_rx_cnt_inperiod = 0;
|
||||
u32 aver_tx_cnt_inperiod = 0;
|
||||
|
||||
bool benter_ps = false;
|
||||
|
||||
if (is_hal_stop(rtlhal))
|
||||
return;
|
||||
|
||||
/* <1> Determine if action frame is allowed */
|
||||
if (mac->link_state > MAC80211_NOLINK) {
|
||||
if (mac->cnt_after_linked < 20)
|
||||
mac->cnt_after_linked++;
|
||||
} else {
|
||||
mac->cnt_after_linked = 0;
|
||||
}
|
||||
|
||||
/* <2> DM */
|
||||
rtlpriv->cfg->ops->dm_watchdog(hw);
|
||||
|
||||
/*
|
||||
*<3> to check if traffic busy, if
|
||||
* busytraffic we don't change channel
|
||||
*/
|
||||
if (mac->link_state >= MAC80211_LINKED) {
|
||||
|
||||
/* (1) get aver_rx_cnt_inperiod & aver_tx_cnt_inperiod */
|
||||
for (idx = 0; idx <= 2; idx++) {
|
||||
rtlpriv->link_info.num_rx_in4period[idx] =
|
||||
rtlpriv->link_info.num_rx_in4period[idx + 1];
|
||||
rtlpriv->link_info.num_tx_in4period[idx] =
|
||||
rtlpriv->link_info.num_tx_in4period[idx + 1];
|
||||
}
|
||||
rtlpriv->link_info.num_rx_in4period[3] =
|
||||
rtlpriv->link_info.num_rx_inperiod;
|
||||
rtlpriv->link_info.num_tx_in4period[3] =
|
||||
rtlpriv->link_info.num_tx_inperiod;
|
||||
for (idx = 0; idx <= 3; idx++) {
|
||||
rx_cnt_inp4eriod +=
|
||||
rtlpriv->link_info.num_rx_in4period[idx];
|
||||
tx_cnt_inp4eriod +=
|
||||
rtlpriv->link_info.num_tx_in4period[idx];
|
||||
}
|
||||
aver_rx_cnt_inperiod = rx_cnt_inp4eriod / 4;
|
||||
aver_tx_cnt_inperiod = tx_cnt_inp4eriod / 4;
|
||||
|
||||
/* (2) check traffic busy */
|
||||
if (aver_rx_cnt_inperiod > 100 || aver_tx_cnt_inperiod > 100)
|
||||
b_busytraffic = true;
|
||||
|
||||
/* Higher Tx/Rx data. */
|
||||
if (aver_rx_cnt_inperiod > 4000 ||
|
||||
aver_tx_cnt_inperiod > 4000) {
|
||||
b_higher_busytraffic = true;
|
||||
|
||||
/* Extremely high Rx data. */
|
||||
if (aver_rx_cnt_inperiod > 5000)
|
||||
b_higher_busyrxtraffic = true;
|
||||
else
|
||||
b_higher_busytxtraffic = false;
|
||||
}
|
||||
|
||||
if (((rtlpriv->link_info.num_rx_inperiod +
|
||||
rtlpriv->link_info.num_tx_inperiod) > 8) ||
|
||||
(rtlpriv->link_info.num_rx_inperiod > 2))
|
||||
benter_ps = false;
|
||||
else
|
||||
benter_ps = true;
|
||||
|
||||
/* LeisurePS only work in infra mode. */
|
||||
if (benter_ps)
|
||||
rtl_lps_enter(hw);
|
||||
else
|
||||
rtl_lps_leave(hw);
|
||||
}
|
||||
|
||||
rtlpriv->link_info.num_rx_inperiod = 0;
|
||||
rtlpriv->link_info.num_tx_inperiod = 0;
|
||||
|
||||
rtlpriv->link_info.b_busytraffic = b_busytraffic;
|
||||
rtlpriv->link_info.b_higher_busytraffic = b_higher_busytraffic;
|
||||
rtlpriv->link_info.b_higher_busyrxtraffic = b_higher_busyrxtraffic;
|
||||
|
||||
}
|
||||
|
||||
void rtl_watch_dog_timer_callback(unsigned long data)
|
||||
{
|
||||
struct ieee80211_hw *hw = (struct ieee80211_hw *)data;
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
queue_delayed_work(rtlpriv->works.rtl_wq,
|
||||
&rtlpriv->works.watchdog_wq, 0);
|
||||
|
||||
mod_timer(&rtlpriv->works.watchdog_timer,
|
||||
jiffies + MSECS(RTL_WATCH_DOG_TIME));
|
||||
}
|
||||
|
||||
/*********************************************************
|
||||
*
|
||||
* sysfs functions
|
||||
*
|
||||
*********************************************************/
|
||||
static ssize_t rtl_show_debug_level(struct device *d,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct ieee80211_hw *hw = dev_get_drvdata(d);
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
return sprintf(buf, "0x%08X\n", rtlpriv->dbg.global_debuglevel);
|
||||
}
|
||||
|
||||
static ssize_t rtl_store_debug_level(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct ieee80211_hw *hw = dev_get_drvdata(d);
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
unsigned long val;
|
||||
int ret;
|
||||
|
||||
ret = strict_strtoul(buf, 0, &val);
|
||||
if (ret) {
|
||||
printk(KERN_DEBUG "%s is not in hex or decimal form.\n", buf);
|
||||
} else {
|
||||
rtlpriv->dbg.global_debuglevel = val;
|
||||
printk(KERN_DEBUG "debuglevel:%x\n",
|
||||
rtlpriv->dbg.global_debuglevel);
|
||||
}
|
||||
|
||||
return strnlen(buf, count);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO,
|
||||
rtl_show_debug_level, rtl_store_debug_level);
|
||||
|
||||
static struct attribute *rtl_sysfs_entries[] = {
|
||||
|
||||
&dev_attr_debug_level.attr,
|
||||
|
||||
NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* "name" is folder name witch will be
|
||||
* put in device directory like :
|
||||
* sys/devices/pci0000:00/0000:00:1c.4/
|
||||
* 0000:06:00.0/rtl_sysfs
|
||||
*/
|
||||
struct attribute_group rtl_attribute_group = {
|
||||
.name = "rtlsysfs",
|
||||
.attrs = rtl_sysfs_entries,
|
||||
};
|
||||
|
||||
MODULE_AUTHOR("lizhaoming <chaoming_li@realsil.com.cn>");
|
||||
MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
|
||||
MODULE_AUTHOR("Larry Finger <Larry.FInger@lwfinger.net>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("Realtek 802.11n PCI wireless core");
|
||||
|
||||
static int __init rtl_core_module_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit rtl_core_module_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
module_init(rtl_core_module_init);
|
||||
module_exit(rtl_core_module_exit);
|
120
drivers/net/wireless/rtlwifi/base.h
Normal file
120
drivers/net/wireless/rtlwifi/base.h
Normal file
@ -0,0 +1,120 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2009-2010 Realtek Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* wlanfae <wlanfae@realtek.com>
|
||||
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
|
||||
* Hsinchu 300, Taiwan.
|
||||
*
|
||||
* Larry Finger <Larry.Finger@lwfinger.net>
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __RTL_BASE_H__
|
||||
#define __RTL_BASE_H__
|
||||
|
||||
#define RTL_DUMMY_OFFSET 0
|
||||
#define RTL_DUMMY_UNIT 8
|
||||
#define RTL_TX_DUMMY_SIZE (RTL_DUMMY_OFFSET * RTL_DUMMY_UNIT)
|
||||
#define RTL_TX_DESC_SIZE 32
|
||||
#define RTL_TX_HEADER_SIZE (RTL_TX_DESC_SIZE + RTL_TX_DUMMY_SIZE)
|
||||
|
||||
#define HT_AMSDU_SIZE_4K 3839
|
||||
#define HT_AMSDU_SIZE_8K 7935
|
||||
|
||||
#define MAX_BIT_RATE_40MHZ_MCS15 300 /* Mbps */
|
||||
#define MAX_BIT_RATE_40MHZ_MCS7 150 /* Mbps */
|
||||
|
||||
#define RTL_RATE_COUNT_LEGACY 12
|
||||
#define RTL_CHANNEL_COUNT 14
|
||||
|
||||
#define FRAME_OFFSET_FRAME_CONTROL 0
|
||||
#define FRAME_OFFSET_DURATION 2
|
||||
#define FRAME_OFFSET_ADDRESS1 4
|
||||
#define FRAME_OFFSET_ADDRESS2 10
|
||||
#define FRAME_OFFSET_ADDRESS3 16
|
||||
#define FRAME_OFFSET_SEQUENCE 22
|
||||
#define FRAME_OFFSET_ADDRESS4 24
|
||||
|
||||
#define SET_80211_HDR_FRAME_CONTROL(_hdr, _val) \
|
||||
WRITEEF2BYTE(_hdr, _val)
|
||||
#define SET_80211_HDR_TYPE_AND_SUBTYPE(_hdr, _val) \
|
||||
WRITEEF1BYTE(_hdr, _val)
|
||||
#define SET_80211_HDR_PWR_MGNT(_hdr, _val) \
|
||||
SET_BITS_TO_LE_2BYTE(_hdr, 12, 1, _val)
|
||||
#define SET_80211_HDR_TO_DS(_hdr, _val) \
|
||||
SET_BITS_TO_LE_2BYTE(_hdr, 8, 1, _val)
|
||||
|
||||
#define SET_80211_PS_POLL_AID(_hdr, _val) \
|
||||
WRITEEF2BYTE(((u8 *)(_hdr)) + 2, _val)
|
||||
#define SET_80211_PS_POLL_BSSID(_hdr, _val) \
|
||||
CP_MACADDR(((u8 *)(_hdr)) + 4, (u8 *)(_val))
|
||||
#define SET_80211_PS_POLL_TA(_hdr, _val) \
|
||||
CP_MACADDR(((u8 *)(_hdr)) + 10, (u8 *)(_val))
|
||||
|
||||
#define SET_80211_HDR_DURATION(_hdr, _val) \
|
||||
WRITEEF2BYTE((u8 *)(_hdr)+FRAME_OFFSET_DURATION, _val)
|
||||
#define SET_80211_HDR_ADDRESS1(_hdr, _val) \
|
||||
CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS1, (u8*)(_val))
|
||||
#define SET_80211_HDR_ADDRESS2(_hdr, _val) \
|
||||
CP_MACADDR((u8 *)(_hdr) + FRAME_OFFSET_ADDRESS2, (u8 *)(_val))
|
||||
#define SET_80211_HDR_ADDRESS3(_hdr, _val) \
|
||||
CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS3, (u8 *)(_val))
|
||||
#define SET_80211_HDR_FRAGMENT_SEQUENCE(_hdr, _val) \
|
||||
WRITEEF2BYTE((u8 *)(_hdr)+FRAME_OFFSET_SEQUENCE, _val)
|
||||
|
||||
#define SET_BEACON_PROBE_RSP_TIME_STAMP_LOW(__phdr, __val) \
|
||||
WRITEEF4BYTE(((u8 *)(__phdr)) + 24, __val)
|
||||
#define SET_BEACON_PROBE_RSP_TIME_STAMP_HIGH(__phdr, __val) \
|
||||
WRITEEF4BYTE(((u8 *)(__phdr)) + 28, __val)
|
||||
#define SET_BEACON_PROBE_RSP_BEACON_INTERVAL(__phdr, __val) \
|
||||
WRITEEF2BYTE(((u8 *)(__phdr)) + 32, __val)
|
||||
#define GET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr) \
|
||||
READEF2BYTE(((u8 *)(__phdr)) + 34)
|
||||
#define SET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, __val) \
|
||||
WRITEEF2BYTE(((u8 *)(__phdr)) + 34, __val)
|
||||
#define MASK_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, __val) \
|
||||
SET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, \
|
||||
(GET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr) & (~(__val))))
|
||||
|
||||
int rtl_init_core(struct ieee80211_hw *hw);
|
||||
void rtl_deinit_core(struct ieee80211_hw *hw);
|
||||
void rtl_init_rx_config(struct ieee80211_hw *hw);
|
||||
void rtl_init_rfkill(struct ieee80211_hw *hw);
|
||||
void rtl_deinit_rfkill(struct ieee80211_hw *hw);
|
||||
|
||||
void rtl_watch_dog_timer_callback(unsigned long data);
|
||||
void rtl_deinit_deferred_work(struct ieee80211_hw *hw);
|
||||
|
||||
bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx);
|
||||
bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb);
|
||||
u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx);
|
||||
|
||||
void rtl_watch_dog_timer_callback(unsigned long data);
|
||||
int rtl_tx_agg_start(struct ieee80211_hw *hw, const u8 *ra,
|
||||
u16 tid, u16 *ssn);
|
||||
int rtl_tx_agg_stop(struct ieee80211_hw *hw, const u8 *ra, u16 tid);
|
||||
void rtl_watchdog_wq_callback(void *data);
|
||||
|
||||
void rtl_get_tcb_desc(struct ieee80211_hw *hw,
|
||||
struct ieee80211_tx_info *info,
|
||||
struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc);
|
||||
|
||||
extern struct attribute_group rtl_attribute_group;
|
||||
#endif
|
291
drivers/net/wireless/rtlwifi/cam.c
Normal file
291
drivers/net/wireless/rtlwifi/cam.c
Normal file
@ -0,0 +1,291 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2009-2010 Realtek Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* wlanfae <wlanfae@realtek.com>
|
||||
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
|
||||
* Hsinchu 300, Taiwan.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "wifi.h"
|
||||
#include "cam.h"
|
||||
|
||||
void rtl_cam_reset_sec_info(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
rtlpriv->sec.use_defaultkey = false;
|
||||
rtlpriv->sec.pairwise_enc_algorithm = NO_ENCRYPTION;
|
||||
rtlpriv->sec.group_enc_algorithm = NO_ENCRYPTION;
|
||||
memset(rtlpriv->sec.key_buf, 0, KEY_BUF_SIZE * MAX_KEY_LEN);
|
||||
memset(rtlpriv->sec.key_len, 0, KEY_BUF_SIZE);
|
||||
rtlpriv->sec.pairwise_key = NULL;
|
||||
}
|
||||
|
||||
static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no,
|
||||
u8 *mac_addr, u8 *key_cont_128, u16 us_config)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
u32 target_command;
|
||||
u32 target_content = 0;
|
||||
u8 entry_i;
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
|
||||
("key_cont_128:\n %x:%x:%x:%x:%x:%x\n",
|
||||
key_cont_128[0], key_cont_128[1],
|
||||
key_cont_128[2], key_cont_128[3],
|
||||
key_cont_128[4], key_cont_128[5]));
|
||||
|
||||
for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
|
||||
target_command = entry_i + CAM_CONTENT_COUNT * entry_no;
|
||||
target_command = target_command | BIT(31) | BIT(16);
|
||||
|
||||
if (entry_i == 0) {
|
||||
target_content = (u32) (*(mac_addr + 0)) << 16 |
|
||||
(u32) (*(mac_addr + 1)) << 24 | (u32) us_config;
|
||||
|
||||
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI],
|
||||
target_content);
|
||||
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
|
||||
target_command);
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
|
||||
("rtl_cam_program_entry(): "
|
||||
"WRITE %x: %x\n",
|
||||
rtlpriv->cfg->maps[WCAMI], target_content));
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
|
||||
("The Key ID is %d\n", entry_no));
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
|
||||
("rtl_cam_program_entry(): "
|
||||
"WRITE %x: %x\n",
|
||||
rtlpriv->cfg->maps[RWCAM], target_command));
|
||||
|
||||
} else if (entry_i == 1) {
|
||||
|
||||
target_content = (u32) (*(mac_addr + 5)) << 24 |
|
||||
(u32) (*(mac_addr + 4)) << 16 |
|
||||
(u32) (*(mac_addr + 3)) << 8 |
|
||||
(u32) (*(mac_addr + 2));
|
||||
|
||||
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI],
|
||||
target_content);
|
||||
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
|
||||
target_command);
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
|
||||
("rtl_cam_program_entry(): WRITE A4: %x\n",
|
||||
target_content));
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
|
||||
("rtl_cam_program_entry(): WRITE A0: %x\n",
|
||||
target_command));
|
||||
|
||||
} else {
|
||||
|
||||
target_content =
|
||||
(u32) (*(key_cont_128 + (entry_i * 4 - 8) + 3)) <<
|
||||
24 | (u32) (*(key_cont_128 + (entry_i * 4 - 8) + 2))
|
||||
<< 16 |
|
||||
(u32) (*(key_cont_128 + (entry_i * 4 - 8) + 1)) << 8
|
||||
| (u32) (*(key_cont_128 + (entry_i * 4 - 8) + 0));
|
||||
|
||||
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI],
|
||||
target_content);
|
||||
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
|
||||
target_command);
|
||||
udelay(100);
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
|
||||
("rtl_cam_program_entry(): WRITE A4: %x\n",
|
||||
target_content));
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
|
||||
("rtl_cam_program_entry(): WRITE A0: %x\n",
|
||||
target_command));
|
||||
}
|
||||
}
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
|
||||
("after set key, usconfig:%x\n", us_config));
|
||||
}
|
||||
|
||||
u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr,
|
||||
u32 ul_key_id, u32 ul_entry_idx, u32 ul_enc_alg,
|
||||
u32 ul_default_key, u8 *key_content)
|
||||
{
|
||||
u32 us_config;
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
|
||||
("EntryNo:%x, ulKeyId=%x, ulEncAlg=%x, "
|
||||
"ulUseDK=%x MacAddr" MAC_FMT "\n",
|
||||
ul_entry_idx, ul_key_id, ul_enc_alg,
|
||||
ul_default_key, MAC_ARG(mac_addr)));
|
||||
|
||||
if (ul_key_id == TOTAL_CAM_ENTRY) {
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
|
||||
("<=== ulKeyId exceed!\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ul_default_key == 1) {
|
||||
us_config = CFG_VALID | ((u16) (ul_enc_alg) << 2);
|
||||
} else {
|
||||
us_config = CFG_VALID | ((ul_enc_alg) << 2) | ul_key_id;
|
||||
}
|
||||
|
||||
rtl_cam_program_entry(hw, ul_entry_idx, mac_addr,
|
||||
(u8 *) key_content, us_config);
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("<===\n"));
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL(rtl_cam_add_one_entry);
|
||||
|
||||
int rtl_cam_delete_one_entry(struct ieee80211_hw *hw,
|
||||
u8 *mac_addr, u32 ul_key_id)
|
||||
{
|
||||
u32 ul_command;
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("key_idx:%d\n", ul_key_id));
|
||||
|
||||
ul_command = ul_key_id * CAM_CONTENT_COUNT;
|
||||
ul_command = ul_command | BIT(31) | BIT(16);
|
||||
|
||||
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], 0);
|
||||
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command);
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
|
||||
("rtl_cam_delete_one_entry(): WRITE A4: %x\n", 0));
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
|
||||
("rtl_cam_delete_one_entry(): WRITE A0: %x\n", ul_command));
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL(rtl_cam_delete_one_entry);
|
||||
|
||||
void rtl_cam_reset_all_entry(struct ieee80211_hw *hw)
|
||||
{
|
||||
u32 ul_command;
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
ul_command = BIT(31) | BIT(30);
|
||||
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command);
|
||||
}
|
||||
EXPORT_SYMBOL(rtl_cam_reset_all_entry);
|
||||
|
||||
void rtl_cam_mark_invalid(struct ieee80211_hw *hw, u8 uc_index)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
u32 ul_command;
|
||||
u32 ul_content;
|
||||
u32 ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_AES];
|
||||
|
||||
switch (rtlpriv->sec.pairwise_enc_algorithm) {
|
||||
case WEP40_ENCRYPTION:
|
||||
ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_WEP40];
|
||||
break;
|
||||
case WEP104_ENCRYPTION:
|
||||
ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_WEP104];
|
||||
break;
|
||||
case TKIP_ENCRYPTION:
|
||||
ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_TKIP];
|
||||
break;
|
||||
case AESCCMP_ENCRYPTION:
|
||||
ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_AES];
|
||||
break;
|
||||
default:
|
||||
ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_AES];
|
||||
}
|
||||
|
||||
ul_content = (uc_index & 3) | ((u16) (ul_enc_algo) << 2);
|
||||
|
||||
ul_content |= BIT(15);
|
||||
ul_command = CAM_CONTENT_COUNT * uc_index;
|
||||
ul_command = ul_command | BIT(31) | BIT(16);
|
||||
|
||||
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], ul_content);
|
||||
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command);
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
|
||||
("rtl_cam_mark_invalid(): WRITE A4: %x\n", ul_content));
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
|
||||
("rtl_cam_mark_invalid(): WRITE A0: %x\n", ul_command));
|
||||
}
|
||||
EXPORT_SYMBOL(rtl_cam_mark_invalid);
|
||||
|
||||
void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
u32 ul_command;
|
||||
u32 ul_content;
|
||||
u32 ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_AES];
|
||||
u8 entry_i;
|
||||
|
||||
switch (rtlpriv->sec.pairwise_enc_algorithm) {
|
||||
case WEP40_ENCRYPTION:
|
||||
ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_WEP40];
|
||||
break;
|
||||
case WEP104_ENCRYPTION:
|
||||
ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_WEP104];
|
||||
break;
|
||||
case TKIP_ENCRYPTION:
|
||||
ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_TKIP];
|
||||
break;
|
||||
case AESCCMP_ENCRYPTION:
|
||||
ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_AES];
|
||||
break;
|
||||
default:
|
||||
ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_AES];
|
||||
}
|
||||
|
||||
for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
|
||||
|
||||
if (entry_i == 0) {
|
||||
ul_content =
|
||||
(uc_index & 0x03) | ((u16) (ul_encalgo) << 2);
|
||||
ul_content |= BIT(15);
|
||||
|
||||
} else {
|
||||
ul_content = 0;
|
||||
}
|
||||
|
||||
ul_command = CAM_CONTENT_COUNT * uc_index + entry_i;
|
||||
ul_command = ul_command | BIT(31) | BIT(16);
|
||||
|
||||
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], ul_content);
|
||||
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command);
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
|
||||
("rtl_cam_empty_entry(): WRITE A4: %x\n",
|
||||
ul_content));
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
|
||||
("rtl_cam_empty_entry(): WRITE A0: %x\n",
|
||||
ul_command));
|
||||
}
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL(rtl_cam_empty_entry);
|
53
drivers/net/wireless/rtlwifi/cam.h
Normal file
53
drivers/net/wireless/rtlwifi/cam.h
Normal file
@ -0,0 +1,53 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2009-2010 Realtek Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* wlanfae <wlanfae@realtek.com>
|
||||
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
|
||||
* Hsinchu 300, Taiwan.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __RTL_CAM_H_
|
||||
#define __RTL_CAM_H_
|
||||
|
||||
#define TOTAL_CAM_ENTRY 32
|
||||
#define CAM_CONTENT_COUNT 8
|
||||
|
||||
#define CFG_DEFAULT_KEY BIT(5)
|
||||
#define CFG_VALID BIT(15)
|
||||
|
||||
#define PAIRWISE_KEYIDX 0
|
||||
#define CAM_PAIRWISE_KEY_POSITION 4
|
||||
|
||||
#define CAM_CONFIG_USEDK 1
|
||||
#define CAM_CONFIG_NO_USEDK 0
|
||||
|
||||
extern void rtl_cam_reset_all_entry(struct ieee80211_hw *hw);
|
||||
extern u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr,
|
||||
u32 ul_key_id, u32 ul_entry_idx, u32 ul_enc_alg,
|
||||
u32 ul_default_key, u8 *key_content);
|
||||
int rtl_cam_delete_one_entry(struct ieee80211_hw *hw, u8 *mac_addr,
|
||||
u32 ul_key_id);
|
||||
void rtl_cam_mark_invalid(struct ieee80211_hw *hw, u8 uc_index);
|
||||
void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index);
|
||||
void rtl_cam_reset_sec_info(struct ieee80211_hw *hw);
|
||||
|
||||
#endif
|
1029
drivers/net/wireless/rtlwifi/core.c
Normal file
1029
drivers/net/wireless/rtlwifi/core.c
Normal file
File diff suppressed because it is too large
Load Diff
42
drivers/net/wireless/rtlwifi/core.h
Normal file
42
drivers/net/wireless/rtlwifi/core.h
Normal file
@ -0,0 +1,42 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2009-2010 Realtek Corporation.
|
||||
*
|
||||
* Tmis program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* Tmis program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* tmis program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* Tme full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* wlanfae <wlanfae@realtek.com>
|
||||
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
|
||||
* Hsinchu 300, Taiwan.
|
||||
*
|
||||
* Larry Finger <Larry.Finger@lwfinger.net>
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __RTL_CORE_H__
|
||||
#define __RTL_CORE_H__
|
||||
|
||||
#define RTL_SUPPORTED_FILTERS \
|
||||
(FIF_PROMISC_IN_BSS | \
|
||||
FIF_ALLMULTI | FIF_CONTROL | \
|
||||
FIF_OTHER_BSS | \
|
||||
FIF_FCSFAIL | \
|
||||
FIF_BCN_PRBRESP_PROMISC)
|
||||
|
||||
#define RTL_SUPPORTED_CTRL_FILTER 0xFF
|
||||
|
||||
extern const struct ieee80211_ops rtl_ops;
|
||||
#endif
|
50
drivers/net/wireless/rtlwifi/debug.c
Normal file
50
drivers/net/wireless/rtlwifi/debug.c
Normal file
@ -0,0 +1,50 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2009-2010 Realtek Corporation.
|
||||
*
|
||||
* Tmis program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* Tmis program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* tmis program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* Tme full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* wlanfae <wlanfae@realtek.com>
|
||||
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
|
||||
* Hsinchu 300, Taiwan.
|
||||
*
|
||||
* Larry Finger <Larry.Finger@lwfinger.net>
|
||||
*****************************************************************************/
|
||||
|
||||
#include "wifi.h"
|
||||
|
||||
void rtl_dbgp_flag_init(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
u8 i;
|
||||
|
||||
rtlpriv->dbg.global_debuglevel = DBG_EMERG;
|
||||
|
||||
rtlpriv->dbg.global_debugcomponents =
|
||||
COMP_ERR | COMP_FW | COMP_INIT | COMP_RECV | COMP_SEND |
|
||||
COMP_MLME | COMP_SCAN | COMP_INTR | COMP_LED | COMP_SEC |
|
||||
COMP_BEACON | COMP_RATE | COMP_RXDESC | COMP_DIG | COMP_TXAGC |
|
||||
COMP_POWER | COMP_POWER_TRACKING | COMP_BB_POWERSAVING | COMP_SWAS |
|
||||
COMP_RF | COMP_TURBO | COMP_RATR | COMP_CMD |
|
||||
COMP_EFUSE | COMP_QOS | COMP_MAC80211 | COMP_REGD | COMP_CHAN;
|
||||
|
||||
for (i = 0; i < DBGP_TYPE_MAX; i++)
|
||||
rtlpriv->dbg.dbgp_type[i] = 0;
|
||||
|
||||
/*Init Debug flag enable condition */
|
||||
}
|
212
drivers/net/wireless/rtlwifi/debug.h
Normal file
212
drivers/net/wireless/rtlwifi/debug.h
Normal file
@ -0,0 +1,212 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2009-2010 Realtek Corporation.
|
||||
*
|
||||
* Tmis program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* Tmis program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* tmis program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* Tme full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* wlanfae <wlanfae@realtek.com>
|
||||
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
|
||||
* Hsinchu 300, Taiwan.
|
||||
*
|
||||
* Larry Finger <Larry.Finger@lwfinger.net>
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __RTL_DEBUG_H__
|
||||
#define __RTL_DEBUG_H__
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
Debug level
|
||||
--------------------------------------------------------------*/
|
||||
/*
|
||||
*Fatal bug.
|
||||
*For example, Tx/Rx/IO locked up,
|
||||
*memory access violation,
|
||||
*resource allocation failed,
|
||||
*unexpected HW behavior, HW BUG
|
||||
*and so on.
|
||||
*/
|
||||
#define DBG_EMERG 0
|
||||
|
||||
/*
|
||||
*Abnormal, rare, or unexpeted cases.
|
||||
*For example, Packet/IO Ctl canceled,
|
||||
*device suprisely unremoved and so on.
|
||||
*/
|
||||
#define DBG_WARNING 2
|
||||
|
||||
/*
|
||||
*Normal case driver developer should
|
||||
*open, we can see link status like
|
||||
*assoc/AddBA/DHCP/adapter start and
|
||||
*so on basic and useful infromations.
|
||||
*/
|
||||
#define DBG_DMESG 3
|
||||
|
||||
/*
|
||||
*Normal case with useful information
|
||||
*about current SW or HW state.
|
||||
*For example, Tx/Rx descriptor to fill,
|
||||
*Tx/Rx descriptor completed status,
|
||||
*SW protocol state change, dynamic
|
||||
*mechanism state change and so on.
|
||||
*/
|
||||
#define DBG_LOUD 4
|
||||
|
||||
/*
|
||||
*Normal case with detail execution
|
||||
*flow or information.
|
||||
*/
|
||||
#define DBG_TRACE 5
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
Define the rt_trace components
|
||||
--------------------------------------------------------------*/
|
||||
#define COMP_ERR BIT(0)
|
||||
#define COMP_FW BIT(1)
|
||||
#define COMP_INIT BIT(2) /*For init/deinit */
|
||||
#define COMP_RECV BIT(3) /*For Rx. */
|
||||
#define COMP_SEND BIT(4) /*For Tx. */
|
||||
#define COMP_MLME BIT(5) /*For MLME. */
|
||||
#define COMP_SCAN BIT(6) /*For Scan. */
|
||||
#define COMP_INTR BIT(7) /*For interrupt Related. */
|
||||
#define COMP_LED BIT(8) /*For LED. */
|
||||
#define COMP_SEC BIT(9) /*For sec. */
|
||||
#define COMP_BEACON BIT(10) /*For beacon. */
|
||||
#define COMP_RATE BIT(11) /*For rate. */
|
||||
#define COMP_RXDESC BIT(12) /*For rx desc. */
|
||||
#define COMP_DIG BIT(13) /*For DIG */
|
||||
#define COMP_TXAGC BIT(14) /*For Tx power */
|
||||
#define COMP_HIPWR BIT(15) /*For High Power Mechanism */
|
||||
#define COMP_POWER BIT(16) /*For lps/ips/aspm. */
|
||||
#define COMP_POWER_TRACKING BIT(17) /*For TX POWER TRACKING */
|
||||
#define COMP_BB_POWERSAVING BIT(18)
|
||||
#define COMP_SWAS BIT(19) /*For SW Antenna Switch */
|
||||
#define COMP_RF BIT(20) /*For RF. */
|
||||
#define COMP_TURBO BIT(21) /*For EDCA TURBO. */
|
||||
#define COMP_RATR BIT(22)
|
||||
#define COMP_CMD BIT(23)
|
||||
#define COMP_EFUSE BIT(24)
|
||||
#define COMP_QOS BIT(25)
|
||||
#define COMP_MAC80211 BIT(26)
|
||||
#define COMP_REGD BIT(27)
|
||||
#define COMP_CHAN BIT(28)
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
Define the rt_print components
|
||||
--------------------------------------------------------------*/
|
||||
/* Define EEPROM and EFUSE check module bit*/
|
||||
#define EEPROM_W BIT(0)
|
||||
#define EFUSE_PG BIT(1)
|
||||
#define EFUSE_READ_ALL BIT(2)
|
||||
|
||||
/* Define init check for module bit*/
|
||||
#define INIT_EEPROM BIT(0)
|
||||
#define INIT_TxPower BIT(1)
|
||||
#define INIT_IQK BIT(2)
|
||||
#define INIT_RF BIT(3)
|
||||
|
||||
/* Define PHY-BB/RF/MAC check module bit */
|
||||
#define PHY_BBR BIT(0)
|
||||
#define PHY_BBW BIT(1)
|
||||
#define PHY_RFR BIT(2)
|
||||
#define PHY_RFW BIT(3)
|
||||
#define PHY_MACR BIT(4)
|
||||
#define PHY_MACW BIT(5)
|
||||
#define PHY_ALLR BIT(6)
|
||||
#define PHY_ALLW BIT(7)
|
||||
#define PHY_TXPWR BIT(8)
|
||||
#define PHY_PWRDIFF BIT(9)
|
||||
|
||||
enum dbgp_flag_e {
|
||||
FQOS = 0,
|
||||
FTX = 1,
|
||||
FRX = 2,
|
||||
FSEC = 3,
|
||||
FMGNT = 4,
|
||||
FMLME = 5,
|
||||
FRESOURCE = 6,
|
||||
FBEACON = 7,
|
||||
FISR = 8,
|
||||
FPHY = 9,
|
||||
FMP = 10,
|
||||
FEEPROM = 11,
|
||||
FPWR = 12,
|
||||
FDM = 13,
|
||||
FDBGCtrl = 14,
|
||||
FC2H = 15,
|
||||
FBT = 16,
|
||||
FINIT = 17,
|
||||
FIOCTL = 18,
|
||||
DBGP_TYPE_MAX
|
||||
};
|
||||
|
||||
#define RT_ASSERT(_exp, fmt) \
|
||||
do { \
|
||||
if (!(_exp)) { \
|
||||
printk(KERN_DEBUG "%s:%s(): ", KBUILD_MODNAME, \
|
||||
__func__); \
|
||||
printk fmt; \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
#define RT_TRACE(rtlpriv, comp, level, fmt)\
|
||||
do { \
|
||||
if (unlikely(((comp) & rtlpriv->dbg.global_debugcomponents) && \
|
||||
((level) <= rtlpriv->dbg.global_debuglevel))) {\
|
||||
printk(KERN_DEBUG "%s:%s():<%lx-%x> ", KBUILD_MODNAME, \
|
||||
__func__, in_interrupt(), in_atomic()); \
|
||||
printk fmt; \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
#define RTPRINT(rtlpriv, dbgtype, dbgflag, printstr) \
|
||||
do { \
|
||||
if (unlikely(rtlpriv->dbg.dbgp_type[dbgtype] & dbgflag)) { \
|
||||
printk(KERN_DEBUG "%s: ", KBUILD_MODNAME); \
|
||||
printk printstr; \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
#define RT_PRINT_DATA(rtlpriv, _comp, _level, _titlestring, _hexdata, \
|
||||
_hexdatalen) \
|
||||
do {\
|
||||
if (unlikely(((_comp) & rtlpriv->dbg.global_debugcomponents) &&\
|
||||
(_level <= rtlpriv->dbg.global_debuglevel))) { \
|
||||
int __i; \
|
||||
u8* ptr = (u8 *)_hexdata; \
|
||||
printk(KERN_DEBUG "%s: ", KBUILD_MODNAME); \
|
||||
printk("In process \"%s\" (pid %i):", current->comm,\
|
||||
current->pid); \
|
||||
printk(_titlestring); \
|
||||
for (__i = 0; __i < (int)_hexdatalen; __i++) { \
|
||||
printk("%02X%s", ptr[__i], (((__i + 1) % 4)\
|
||||
== 0) ? " " : " ");\
|
||||
if (((__i + 1) % 16) == 0) \
|
||||
printk("\n"); \
|
||||
} \
|
||||
printk(KERN_DEBUG "\n"); \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
|
||||
#define MAC_ARG(x) \
|
||||
((u8 *)(x))[0], ((u8 *)(x))[1], ((u8 *)(x))[2],\
|
||||
((u8 *)(x))[3], ((u8 *)(x))[4], ((u8 *)(x))[5]
|
||||
|
||||
void rtl_dbgp_flag_init(struct ieee80211_hw *hw);
|
||||
#endif
|
1189
drivers/net/wireless/rtlwifi/efuse.c
Normal file
1189
drivers/net/wireless/rtlwifi/efuse.c
Normal file
File diff suppressed because it is too large
Load Diff
124
drivers/net/wireless/rtlwifi/efuse.h
Normal file
124
drivers/net/wireless/rtlwifi/efuse.h
Normal file
@ -0,0 +1,124 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2009-2010 Realtek Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* wlanfae <wlanfae@realtek.com>
|
||||
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
|
||||
* Hsinchu 300, Taiwan.
|
||||
*
|
||||
* Larry Finger <Larry.Finger@lwfinger.net>
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __RTL_EFUSE_H_
|
||||
#define __RTL_EFUSE_H_
|
||||
|
||||
#define EFUSE_REAL_CONTENT_LEN 512
|
||||
#define EFUSE_MAP_LEN 128
|
||||
#define EFUSE_MAX_SECTION 16
|
||||
#define EFUSE_MAX_WORD_UNIT 4
|
||||
|
||||
#define EFUSE_INIT_MAP 0
|
||||
#define EFUSE_MODIFY_MAP 1
|
||||
|
||||
#define PG_STATE_HEADER 0x01
|
||||
#define PG_STATE_WORD_0 0x02
|
||||
#define PG_STATE_WORD_1 0x04
|
||||
#define PG_STATE_WORD_2 0x08
|
||||
#define PG_STATE_WORD_3 0x10
|
||||
#define PG_STATE_DATA 0x20
|
||||
|
||||
#define PG_SWBYTE_H 0x01
|
||||
#define PG_SWBYTE_L 0x02
|
||||
|
||||
#define _POWERON_DELAY_
|
||||
#define _PRE_EXECUTE_READ_CMD_
|
||||
|
||||
#define EFUSE_REPEAT_THRESHOLD_ 3
|
||||
|
||||
struct efuse_map {
|
||||
u8 offset;
|
||||
u8 word_start;
|
||||
u8 byte_start;
|
||||
u8 byte_cnts;
|
||||
};
|
||||
|
||||
struct pgpkt_struct {
|
||||
u8 offset;
|
||||
u8 word_en;
|
||||
u8 data[8];
|
||||
};
|
||||
|
||||
enum efuse_data_item {
|
||||
EFUSE_CHIP_ID = 0,
|
||||
EFUSE_LDO_SETTING,
|
||||
EFUSE_CLK_SETTING,
|
||||
EFUSE_SDIO_SETTING,
|
||||
EFUSE_CCCR,
|
||||
EFUSE_SDIO_MODE,
|
||||
EFUSE_OCR,
|
||||
EFUSE_F0CIS,
|
||||
EFUSE_F1CIS,
|
||||
EFUSE_MAC_ADDR,
|
||||
EFUSE_EEPROM_VER,
|
||||
EFUSE_CHAN_PLAN,
|
||||
EFUSE_TXPW_TAB
|
||||
};
|
||||
|
||||
enum {
|
||||
VOLTAGE_V25 = 0x03,
|
||||
LDOE25_SHIFT = 28,
|
||||
};
|
||||
|
||||
struct efuse_priv {
|
||||
u8 id[2];
|
||||
u8 ldo_setting[2];
|
||||
u8 clk_setting[2];
|
||||
u8 cccr;
|
||||
u8 sdio_mode;
|
||||
u8 ocr[3];
|
||||
u8 cis0[17];
|
||||
u8 cis1[48];
|
||||
u8 mac_addr[6];
|
||||
u8 eeprom_verno;
|
||||
u8 channel_plan;
|
||||
u8 tx_power_b[14];
|
||||
u8 tx_power_g[14];
|
||||
};
|
||||
|
||||
extern void efuse_initialize(struct ieee80211_hw *hw);
|
||||
extern u8 efuse_read_1byte(struct ieee80211_hw *hw, u16 address);
|
||||
extern void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value);
|
||||
extern void read_efuse(struct ieee80211_hw *hw, u16 _offset,
|
||||
u16 _size_byte, u8 *pbuf);
|
||||
extern void efuse_shadow_read(struct ieee80211_hw *hw, u8 type,
|
||||
u16 offset, u32 *value);
|
||||
extern void efuse_shadow_write(struct ieee80211_hw *hw, u8 type,
|
||||
u16 offset, u32 value);
|
||||
extern bool efuse_shadow_update(struct ieee80211_hw *hw);
|
||||
extern bool efuse_shadow_update_chk(struct ieee80211_hw *hw);
|
||||
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);
|
||||
extern bool efuse_program_map(struct ieee80211_hw *hw,
|
||||
char *p_filename, u8 tabletype);
|
||||
extern void efuse_reset_loader(struct ieee80211_hw *hw);
|
||||
|
||||
#endif
|
1933
drivers/net/wireless/rtlwifi/pci.c
Normal file
1933
drivers/net/wireless/rtlwifi/pci.c
Normal file
File diff suppressed because it is too large
Load Diff
302
drivers/net/wireless/rtlwifi/pci.h
Normal file
302
drivers/net/wireless/rtlwifi/pci.h
Normal file
@ -0,0 +1,302 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2009-2010 Realtek Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* wlanfae <wlanfae@realtek.com>
|
||||
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
|
||||
* Hsinchu 300, Taiwan.
|
||||
*
|
||||
* Larry Finger <Larry.Finger@lwfinger.net>
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __RTL_PCI_H__
|
||||
#define __RTL_PCI_H__
|
||||
|
||||
#include <linux/pci.h>
|
||||
/*
|
||||
1: MSDU packet queue,
|
||||
2: Rx Command Queue
|
||||
*/
|
||||
#define RTL_PCI_RX_MPDU_QUEUE 0
|
||||
#define RTL_PCI_RX_CMD_QUEUE 1
|
||||
#define RTL_PCI_MAX_RX_QUEUE 2
|
||||
|
||||
#define RTL_PCI_MAX_RX_COUNT 64
|
||||
#define RTL_PCI_MAX_TX_QUEUE_COUNT 9
|
||||
|
||||
#define RT_TXDESC_NUM 128
|
||||
#define RT_TXDESC_NUM_BE_QUEUE 256
|
||||
|
||||
#define BK_QUEUE 0
|
||||
#define BE_QUEUE 1
|
||||
#define VI_QUEUE 2
|
||||
#define VO_QUEUE 3
|
||||
#define BEACON_QUEUE 4
|
||||
#define TXCMD_QUEUE 5
|
||||
#define MGNT_QUEUE 6
|
||||
#define HIGH_QUEUE 7
|
||||
#define HCCA_QUEUE 8
|
||||
|
||||
#define RTL_PCI_DEVICE(vend, dev, cfg) \
|
||||
.vendor = (vend), \
|
||||
.device = (dev), \
|
||||
.subvendor = PCI_ANY_ID, \
|
||||
.subdevice = PCI_ANY_ID,\
|
||||
.driver_data = (kernel_ulong_t)&(cfg)
|
||||
|
||||
#define INTEL_VENDOR_ID 0x8086
|
||||
#define SIS_VENDOR_ID 0x1039
|
||||
#define ATI_VENDOR_ID 0x1002
|
||||
#define ATI_DEVICE_ID 0x7914
|
||||
#define AMD_VENDOR_ID 0x1022
|
||||
|
||||
#define PCI_MAX_BRIDGE_NUMBER 255
|
||||
#define PCI_MAX_DEVICES 32
|
||||
#define PCI_MAX_FUNCTION 8
|
||||
|
||||
#define PCI_CONF_ADDRESS 0x0CF8 /*PCI Configuration Space Address */
|
||||
#define PCI_CONF_DATA 0x0CFC /*PCI Configuration Space Data */
|
||||
|
||||
#define PCI_CLASS_BRIDGE_DEV 0x06
|
||||
#define PCI_SUBCLASS_BR_PCI_TO_PCI 0x04
|
||||
#define PCI_CAPABILITY_ID_PCI_EXPRESS 0x10
|
||||
#define PCI_CAP_ID_EXP 0x10
|
||||
|
||||
#define U1DONTCARE 0xFF
|
||||
#define U2DONTCARE 0xFFFF
|
||||
#define U4DONTCARE 0xFFFFFFFF
|
||||
|
||||
#define RTL_PCI_8192_DID 0x8192 /*8192 PCI-E */
|
||||
#define RTL_PCI_8192SE_DID 0x8192 /*8192 SE */
|
||||
#define RTL_PCI_8174_DID 0x8174 /*8192 SE */
|
||||
#define RTL_PCI_8173_DID 0x8173 /*8191 SE Crab */
|
||||
#define RTL_PCI_8172_DID 0x8172 /*8191 SE RE */
|
||||
#define RTL_PCI_8171_DID 0x8171 /*8191 SE Unicron */
|
||||
#define RTL_PCI_0045_DID 0x0045 /*8190 PCI for Ceraga */
|
||||
#define RTL_PCI_0046_DID 0x0046 /*8190 Cardbus for Ceraga */
|
||||
#define RTL_PCI_0044_DID 0x0044 /*8192e PCIE for Ceraga */
|
||||
#define RTL_PCI_0047_DID 0x0047 /*8192e Express Card for Ceraga */
|
||||
#define RTL_PCI_700F_DID 0x700F
|
||||
#define RTL_PCI_701F_DID 0x701F
|
||||
#define RTL_PCI_DLINK_DID 0x3304
|
||||
#define RTL_PCI_8192CET_DID 0x8191 /*8192ce */
|
||||
#define RTL_PCI_8192CE_DID 0x8178 /*8192ce */
|
||||
#define RTL_PCI_8191CE_DID 0x8177 /*8192ce */
|
||||
#define RTL_PCI_8188CE_DID 0x8176 /*8192ce */
|
||||
#define RTL_PCI_8192CU_DID 0x8191 /*8192ce */
|
||||
#define RTL_PCI_8192DE_DID 0x092D /*8192ce */
|
||||
#define RTL_PCI_8192DU_DID 0x092D /*8192ce */
|
||||
|
||||
/*8192 support 16 pages of IO registers*/
|
||||
#define RTL_MEM_MAPPED_IO_RANGE_8190PCI 0x1000
|
||||
#define RTL_MEM_MAPPED_IO_RANGE_8192PCIE 0x4000
|
||||
#define RTL_MEM_MAPPED_IO_RANGE_8192SE 0x4000
|
||||
#define RTL_MEM_MAPPED_IO_RANGE_8192CE 0x4000
|
||||
#define RTL_MEM_MAPPED_IO_RANGE_8192DE 0x4000
|
||||
|
||||
#define RTL_PCI_REVISION_ID_8190PCI 0x00
|
||||
#define RTL_PCI_REVISION_ID_8192PCIE 0x01
|
||||
#define RTL_PCI_REVISION_ID_8192SE 0x10
|
||||
#define RTL_PCI_REVISION_ID_8192CE 0x1
|
||||
#define RTL_PCI_REVISION_ID_8192DE 0x0
|
||||
|
||||
#define RTL_DEFAULT_HARDWARE_TYPE HARDWARE_TYPE_RTL8192CE
|
||||
|
||||
enum pci_bridge_vendor {
|
||||
PCI_BRIDGE_VENDOR_INTEL = 0x0, /*0b'0000,0001 */
|
||||
PCI_BRIDGE_VENDOR_ATI, /*0b'0000,0010*/
|
||||
PCI_BRIDGE_VENDOR_AMD, /*0b'0000,0100*/
|
||||
PCI_BRIDGE_VENDOR_SIS, /*0b'0000,1000*/
|
||||
PCI_BRIDGE_VENDOR_UNKNOWN, /*0b'0100,0000*/
|
||||
PCI_BRIDGE_VENDOR_MAX,
|
||||
};
|
||||
|
||||
struct rtl_rx_desc {
|
||||
u32 dword[8];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct rtl_tx_desc {
|
||||
u32 dword[16];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct rtl_tx_cmd_desc {
|
||||
u32 dword[16];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct rtl8192_tx_ring {
|
||||
struct rtl_tx_desc *desc;
|
||||
dma_addr_t dma;
|
||||
unsigned int idx;
|
||||
unsigned int entries;
|
||||
struct sk_buff_head queue;
|
||||
};
|
||||
|
||||
struct rtl8192_rx_ring {
|
||||
struct rtl_rx_desc *desc;
|
||||
dma_addr_t dma;
|
||||
unsigned int idx;
|
||||
struct sk_buff *rx_buf[RTL_PCI_MAX_RX_COUNT];
|
||||
};
|
||||
|
||||
struct rtl_pci {
|
||||
struct pci_dev *pdev;
|
||||
|
||||
bool driver_is_goingto_unload;
|
||||
bool up_first_time;
|
||||
bool being_init_adapter;
|
||||
bool irq_enabled;
|
||||
|
||||
/*Tx */
|
||||
struct rtl8192_tx_ring tx_ring[RTL_PCI_MAX_TX_QUEUE_COUNT];
|
||||
int txringcount[RTL_PCI_MAX_TX_QUEUE_COUNT];
|
||||
u32 transmit_config;
|
||||
|
||||
/*Rx */
|
||||
struct rtl8192_rx_ring rx_ring[RTL_PCI_MAX_RX_QUEUE];
|
||||
int rxringcount;
|
||||
u16 rxbuffersize;
|
||||
u32 receive_config;
|
||||
|
||||
/*irq */
|
||||
u8 irq_alloc;
|
||||
u32 irq_mask[2];
|
||||
|
||||
/*Bcn control register setting */
|
||||
u32 reg_bcn_ctrl_val;
|
||||
|
||||
/*ASPM*/ u8 const_pci_aspm;
|
||||
u8 const_amdpci_aspm;
|
||||
u8 const_hwsw_rfoff_d3;
|
||||
u8 const_support_pciaspm;
|
||||
/*pci-e bridge */
|
||||
u8 const_hostpci_aspm_setting;
|
||||
/*pci-e device */
|
||||
u8 const_devicepci_aspm_setting;
|
||||
/*If it supports ASPM, Offset[560h] = 0x40,
|
||||
otherwise Offset[560h] = 0x00. */
|
||||
bool b_support_aspm;
|
||||
bool b_support_backdoor;
|
||||
|
||||
/*QOS & EDCA */
|
||||
enum acm_method acm_method;
|
||||
};
|
||||
|
||||
struct mp_adapter {
|
||||
u8 linkctrl_reg;
|
||||
|
||||
u8 busnumber;
|
||||
u8 devnumber;
|
||||
u8 funcnumber;
|
||||
|
||||
u8 pcibridge_busnum;
|
||||
u8 pcibridge_devnum;
|
||||
u8 pcibridge_funcnum;
|
||||
|
||||
u8 pcibridge_vendor;
|
||||
u16 pcibridge_vendorid;
|
||||
u16 pcibridge_deviceid;
|
||||
|
||||
u32 pcicfg_addrport;
|
||||
u8 num4bytes;
|
||||
|
||||
u8 pcibridge_pciehdr_offset;
|
||||
u8 pcibridge_linkctrlreg;
|
||||
|
||||
bool amd_l1_patch;
|
||||
};
|
||||
|
||||
struct rtl_pci_priv {
|
||||
struct rtl_pci dev;
|
||||
struct mp_adapter ndis_adapter;
|
||||
struct rtl_led_ctl ledctl;
|
||||
};
|
||||
|
||||
#define rtl_pcipriv(hw) (((struct rtl_pci_priv *)(rtl_priv(hw))->priv))
|
||||
#define rtl_pcidev(pcipriv) (&((pcipriv)->dev))
|
||||
|
||||
int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw);
|
||||
|
||||
extern struct rtl_intf_ops rtl_pci_ops;
|
||||
|
||||
int __devinit rtl_pci_probe(struct pci_dev *pdev,
|
||||
const struct pci_device_id *id);
|
||||
void rtl_pci_disconnect(struct pci_dev *pdev);
|
||||
int rtl_pci_suspend(struct pci_dev *pdev, pm_message_t state);
|
||||
int rtl_pci_resume(struct pci_dev *pdev);
|
||||
|
||||
static inline u8 pci_read8_sync(struct rtl_priv *rtlpriv, u32 addr)
|
||||
{
|
||||
return 0xff & readb((u8 *) rtlpriv->io.pci_mem_start + addr);
|
||||
}
|
||||
|
||||
static inline u16 pci_read16_sync(struct rtl_priv *rtlpriv, u32 addr)
|
||||
{
|
||||
return readw((u8 *) rtlpriv->io.pci_mem_start + addr);
|
||||
}
|
||||
|
||||
static inline u32 pci_read32_sync(struct rtl_priv *rtlpriv, u32 addr)
|
||||
{
|
||||
return readl((u8 *) rtlpriv->io.pci_mem_start + addr);
|
||||
}
|
||||
|
||||
static inline void pci_write8_async(struct rtl_priv *rtlpriv, u32 addr, u8 val)
|
||||
{
|
||||
writeb(val, (u8 *) rtlpriv->io.pci_mem_start + addr);
|
||||
}
|
||||
|
||||
static inline void pci_write16_async(struct rtl_priv *rtlpriv,
|
||||
u32 addr, u16 val)
|
||||
{
|
||||
writew(val, (u8 *) rtlpriv->io.pci_mem_start + addr);
|
||||
}
|
||||
|
||||
static inline void pci_write32_async(struct rtl_priv *rtlpriv,
|
||||
u32 addr, u32 val)
|
||||
{
|
||||
writel(val, (u8 *) rtlpriv->io.pci_mem_start + addr);
|
||||
}
|
||||
|
||||
static inline void rtl_pci_raw_write_port_ulong(u32 port, u32 val)
|
||||
{
|
||||
outl(val, port);
|
||||
}
|
||||
|
||||
static inline void rtl_pci_raw_write_port_uchar(u32 port, u8 val)
|
||||
{
|
||||
outb(val, port);
|
||||
}
|
||||
|
||||
static inline void rtl_pci_raw_read_port_uchar(u32 port, u8 *pval)
|
||||
{
|
||||
*pval = inb(port);
|
||||
}
|
||||
|
||||
static inline void rtl_pci_raw_read_port_ushort(u32 port, u16 *pval)
|
||||
{
|
||||
*pval = inw(port);
|
||||
}
|
||||
|
||||
static inline void rtl_pci_raw_read_port_ulong(u32 port, u32 *pval)
|
||||
{
|
||||
*pval = inl(port);
|
||||
}
|
||||
|
||||
#endif
|
492
drivers/net/wireless/rtlwifi/ps.c
Normal file
492
drivers/net/wireless/rtlwifi/ps.c
Normal file
@ -0,0 +1,492 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2009-2010 Realtek Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* wlanfae <wlanfae@realtek.com>
|
||||
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
|
||||
* Hsinchu 300, Taiwan.
|
||||
*
|
||||
* Larry Finger <Larry.Finger@lwfinger.net>
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "wifi.h"
|
||||
#include "base.h"
|
||||
#include "ps.h"
|
||||
|
||||
bool rtl_ps_enable_nic(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
|
||||
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
|
||||
bool init_status = true;
|
||||
|
||||
/*<1> reset trx ring */
|
||||
if (rtlhal->interface == INTF_PCI)
|
||||
rtlpriv->intf_ops->reset_trx_ring(hw);
|
||||
|
||||
if (is_hal_stop(rtlhal))
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
|
||||
("Driver is already down!\n"));
|
||||
|
||||
/*<2> Enable Adapter */
|
||||
rtlpriv->cfg->ops->hw_init(hw);
|
||||
RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
|
||||
/*init_status = false; */
|
||||
|
||||
/*<3> Enable Interrupt */
|
||||
rtlpriv->cfg->ops->enable_interrupt(hw);
|
||||
|
||||
/*<enable timer> */
|
||||
rtl_watch_dog_timer_callback((unsigned long)hw);
|
||||
|
||||
return init_status;
|
||||
}
|
||||
EXPORT_SYMBOL(rtl_ps_enable_nic);
|
||||
|
||||
bool rtl_ps_disable_nic(struct ieee80211_hw *hw)
|
||||
{
|
||||
bool status = true;
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
/*<1> Stop all timer */
|
||||
rtl_deinit_deferred_work(hw);
|
||||
|
||||
/*<2> Disable Interrupt */
|
||||
rtlpriv->cfg->ops->disable_interrupt(hw);
|
||||
|
||||
/*<3> Disable Adapter */
|
||||
rtlpriv->cfg->ops->hw_disable(hw);
|
||||
|
||||
return status;
|
||||
}
|
||||
EXPORT_SYMBOL(rtl_ps_disable_nic);
|
||||
|
||||
bool rtl_ps_set_rf_state(struct ieee80211_hw *hw,
|
||||
enum rf_pwrstate state_toset,
|
||||
u32 changesource, bool protect_or_not)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
|
||||
enum rf_pwrstate rtstate;
|
||||
bool b_actionallowed = false;
|
||||
u16 rfwait_cnt = 0;
|
||||
unsigned long flag;
|
||||
|
||||
/*protect_or_not = true; */
|
||||
|
||||
if (protect_or_not)
|
||||
goto no_protect;
|
||||
|
||||
/*
|
||||
*Only one thread can change
|
||||
*the RF state at one time, and others
|
||||
*should wait to be executed.
|
||||
*/
|
||||
while (true) {
|
||||
spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
|
||||
if (ppsc->rfchange_inprogress) {
|
||||
spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock,
|
||||
flag);
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
|
||||
("RF Change in progress!"
|
||||
"Wait to set..state_toset(%d).\n",
|
||||
state_toset));
|
||||
|
||||
/* Set RF after the previous action is done. */
|
||||
while (ppsc->rfchange_inprogress) {
|
||||
rfwait_cnt++;
|
||||
mdelay(1);
|
||||
|
||||
/*
|
||||
*Wait too long, return false to avoid
|
||||
*to be stuck here.
|
||||
*/
|
||||
if (rfwait_cnt > 100)
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
ppsc->rfchange_inprogress = true;
|
||||
spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock,
|
||||
flag);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
no_protect:
|
||||
rtstate = ppsc->rfpwr_state;
|
||||
|
||||
switch (state_toset) {
|
||||
case ERFON:
|
||||
ppsc->rfoff_reason &= (~changesource);
|
||||
|
||||
if ((changesource == RF_CHANGE_BY_HW) &&
|
||||
(ppsc->b_hwradiooff == true)) {
|
||||
ppsc->b_hwradiooff = false;
|
||||
}
|
||||
|
||||
if (!ppsc->rfoff_reason) {
|
||||
ppsc->rfoff_reason = 0;
|
||||
b_actionallowed = true;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case ERFOFF:
|
||||
|
||||
if ((changesource == RF_CHANGE_BY_HW)
|
||||
&& (ppsc->b_hwradiooff == false)) {
|
||||
ppsc->b_hwradiooff = true;
|
||||
}
|
||||
|
||||
ppsc->rfoff_reason |= changesource;
|
||||
b_actionallowed = true;
|
||||
break;
|
||||
|
||||
case ERFSLEEP:
|
||||
ppsc->rfoff_reason |= changesource;
|
||||
b_actionallowed = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
||||
("switch case not process\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
if (b_actionallowed)
|
||||
rtlpriv->cfg->ops->set_rf_power_state(hw, state_toset);
|
||||
|
||||
if (!protect_or_not) {
|
||||
spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
|
||||
ppsc->rfchange_inprogress = false;
|
||||
spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
|
||||
}
|
||||
|
||||
return b_actionallowed;
|
||||
}
|
||||
EXPORT_SYMBOL(rtl_ps_set_rf_state);
|
||||
|
||||
static void _rtl_ps_inactive_ps(struct ieee80211_hw *hw)
|
||||
{
|
||||
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));
|
||||
|
||||
ppsc->b_swrf_processing = true;
|
||||
|
||||
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) &&
|
||||
rtlhal->interface == INTF_PCI) {
|
||||
rtlpriv->intf_ops->disable_aspm(hw);
|
||||
RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM);
|
||||
}
|
||||
}
|
||||
|
||||
rtl_ps_set_rf_state(hw, ppsc->inactive_pwrstate,
|
||||
RF_CHANGE_BY_IPS, false);
|
||||
|
||||
if (ppsc->inactive_pwrstate == ERFOFF &&
|
||||
rtlhal->interface == INTF_PCI) {
|
||||
if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) {
|
||||
rtlpriv->intf_ops->enable_aspm(hw);
|
||||
RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM);
|
||||
}
|
||||
}
|
||||
|
||||
ppsc->b_swrf_processing = false;
|
||||
}
|
||||
|
||||
void rtl_ips_nic_off_wq_callback(void *data)
|
||||
{
|
||||
struct rtl_works *rtlworks =
|
||||
container_of_dwork_rtl(data, struct rtl_works, ips_nic_off_wq);
|
||||
struct ieee80211_hw *hw = rtlworks->hw;
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
|
||||
enum rf_pwrstate rtstate;
|
||||
|
||||
if (mac->opmode != NL80211_IFTYPE_STATION) {
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
|
||||
("not station return\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_hal_stop(rtlhal))
|
||||
return;
|
||||
|
||||
if (rtlpriv->sec.being_setkey)
|
||||
return;
|
||||
|
||||
if (ppsc->b_inactiveps) {
|
||||
rtstate = ppsc->rfpwr_state;
|
||||
|
||||
/*
|
||||
*Do not enter IPS in the following conditions:
|
||||
*(1) RF is already OFF or Sleep
|
||||
*(2) b_swrf_processing (indicates the IPS is still under going)
|
||||
*(3) Connectted (only disconnected can trigger IPS)
|
||||
*(4) IBSS (send Beacon)
|
||||
*(5) AP mode (send Beacon)
|
||||
*(6) monitor mode (rcv packet)
|
||||
*/
|
||||
|
||||
if (rtstate == ERFON &&
|
||||
!ppsc->b_swrf_processing &&
|
||||
(mac->link_state == MAC80211_NOLINK) &&
|
||||
!mac->act_scanning) {
|
||||
RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
|
||||
("IPSEnter(): Turn off RF.\n"));
|
||||
|
||||
ppsc->inactive_pwrstate = ERFOFF;
|
||||
ppsc->b_in_powersavemode = true;
|
||||
|
||||
/*rtl_pci_reset_trx_ring(hw); */
|
||||
_rtl_ps_inactive_ps(hw);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rtl_ips_nic_off(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
/*
|
||||
*because when link with ap, mac80211 will ask us
|
||||
*to disable nic quickly after scan before linking,
|
||||
*this will cause link failed, so we delay 100ms here
|
||||
*/
|
||||
queue_delayed_work(rtlpriv->works.rtl_wq,
|
||||
&rtlpriv->works.ips_nic_off_wq, MSECS(100));
|
||||
}
|
||||
|
||||
void rtl_ips_nic_on(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
|
||||
enum rf_pwrstate rtstate;
|
||||
|
||||
down(&rtlpriv->locks.ips_sem);
|
||||
|
||||
if (ppsc->b_inactiveps) {
|
||||
rtstate = ppsc->rfpwr_state;
|
||||
|
||||
if (rtstate != ERFON &&
|
||||
!ppsc->b_swrf_processing &&
|
||||
ppsc->rfoff_reason <= RF_CHANGE_BY_IPS) {
|
||||
|
||||
ppsc->inactive_pwrstate = ERFON;
|
||||
ppsc->b_in_powersavemode = false;
|
||||
|
||||
_rtl_ps_inactive_ps(hw);
|
||||
}
|
||||
}
|
||||
|
||||
up(&rtlpriv->locks.ips_sem);
|
||||
}
|
||||
|
||||
/*for FW LPS*/
|
||||
|
||||
/*
|
||||
*Determine if we can set Fw into PS mode
|
||||
*in current condition.Return TRUE if it
|
||||
*can enter PS mode.
|
||||
*/
|
||||
static bool rtl_get_fwlps_doze(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));
|
||||
u32 ps_timediff;
|
||||
|
||||
ps_timediff = jiffies_to_msecs(jiffies -
|
||||
ppsc->last_delaylps_stamp_jiffies);
|
||||
|
||||
if (ps_timediff < 2000) {
|
||||
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
|
||||
("Delay enter Fw LPS for DHCP, ARP,"
|
||||
" or EAPOL exchanging state.\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mac->link_state != MAC80211_LINKED)
|
||||
return false;
|
||||
|
||||
if (mac->opmode == NL80211_IFTYPE_ADHOC)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Change current and default preamble mode.*/
|
||||
static void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode)
|
||||
{
|
||||
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));
|
||||
u8 rpwm_val, fw_pwrmode;
|
||||
|
||||
if (mac->opmode == NL80211_IFTYPE_ADHOC)
|
||||
return;
|
||||
|
||||
if (mac->link_state != MAC80211_LINKED)
|
||||
return;
|
||||
|
||||
if (ppsc->dot11_psmode == rt_psmode)
|
||||
return;
|
||||
|
||||
/* Update power save mode configured. */
|
||||
ppsc->dot11_psmode = rt_psmode;
|
||||
|
||||
/*
|
||||
*<FW control LPS>
|
||||
*1. Enter PS mode
|
||||
* Set RPWM to Fw to turn RF off and send H2C fw_pwrmode
|
||||
* cmd to set Fw into PS mode.
|
||||
*2. Leave PS mode
|
||||
* Send H2C fw_pwrmode cmd to Fw to set Fw into Active
|
||||
* mode and set RPWM to turn RF on.
|
||||
*/
|
||||
|
||||
if ((ppsc->b_fwctrl_lps) && (ppsc->b_leisure_ps) &&
|
||||
ppsc->report_linked) {
|
||||
bool b_fw_current_inps;
|
||||
if (ppsc->dot11_psmode == EACTIVE) {
|
||||
RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
|
||||
("FW LPS leave ps_mode:%x\n",
|
||||
FW_PS_ACTIVE_MODE));
|
||||
|
||||
rpwm_val = 0x0C; /* RF on */
|
||||
fw_pwrmode = FW_PS_ACTIVE_MODE;
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
|
||||
(u8 *) (&rpwm_val));
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw,
|
||||
HW_VAR_H2C_FW_PWRMODE,
|
||||
(u8 *) (&fw_pwrmode));
|
||||
b_fw_current_inps = false;
|
||||
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw,
|
||||
HW_VAR_FW_PSMODE_STATUS,
|
||||
(u8 *) (&b_fw_current_inps));
|
||||
|
||||
} else {
|
||||
if (rtl_get_fwlps_doze(hw)) {
|
||||
RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
|
||||
("FW LPS enter ps_mode:%x\n",
|
||||
ppsc->fwctrl_psmode));
|
||||
|
||||
rpwm_val = 0x02; /* RF off */
|
||||
b_fw_current_inps = true;
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw,
|
||||
HW_VAR_FW_PSMODE_STATUS,
|
||||
(u8 *) (&b_fw_current_inps));
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw,
|
||||
HW_VAR_H2C_FW_PWRMODE,
|
||||
(u8 *) (&ppsc->fwctrl_psmode));
|
||||
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw,
|
||||
HW_VAR_SET_RPWM,
|
||||
(u8 *) (&rpwm_val));
|
||||
} else {
|
||||
/* Reset the power save related parameters. */
|
||||
ppsc->dot11_psmode = EACTIVE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*Enter the leisure power save mode.*/
|
||||
void rtl_lps_enter(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
unsigned long flag;
|
||||
|
||||
if (!(ppsc->b_fwctrl_lps && ppsc->b_leisure_ps))
|
||||
return;
|
||||
|
||||
if (rtlpriv->sec.being_setkey)
|
||||
return;
|
||||
|
||||
if (rtlpriv->link_info.b_busytraffic)
|
||||
return;
|
||||
|
||||
/*sleep after linked 10s, to let DHCP and 4-way handshake ok enough!! */
|
||||
if (mac->cnt_after_linked < 5)
|
||||
return;
|
||||
|
||||
if (mac->opmode == NL80211_IFTYPE_ADHOC)
|
||||
return;
|
||||
|
||||
if (mac->link_state != MAC80211_LINKED)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag);
|
||||
|
||||
if (ppsc->b_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"));
|
||||
|
||||
rtl_lps_set_psmode(hw, EAUTOPS);
|
||||
}
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
|
||||
}
|
||||
|
||||
/*Leave the leisure power save mode.*/
|
||||
void rtl_lps_leave(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
|
||||
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
|
||||
unsigned long flag;
|
||||
|
||||
spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag);
|
||||
|
||||
if (ppsc->b_fwctrl_lps && ppsc->b_leisure_ps) {
|
||||
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) &&
|
||||
rtlhal->interface == INTF_PCI) {
|
||||
rtlpriv->intf_ops->disable_aspm(hw);
|
||||
RT_CLEAR_PS_LEVEL(ppsc, RT_RF_LPS_LEVEL_ASPM);
|
||||
}
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
|
||||
("Busy Traffic,Leave 802.11 power save..\n"));
|
||||
|
||||
rtl_lps_set_psmode(hw, EACTIVE);
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
|
||||
}
|
43
drivers/net/wireless/rtlwifi/ps.h
Normal file
43
drivers/net/wireless/rtlwifi/ps.h
Normal file
@ -0,0 +1,43 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2009-2010 Realtek Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* wlanfae <wlanfae@realtek.com>
|
||||
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
|
||||
* Hsinchu 300, Taiwan.
|
||||
*
|
||||
* Larry Finger <Larry.Finger@lwfinger.net>
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __REALTEK_RTL_PCI_PS_H__
|
||||
#define __REALTEK_RTL_PCI_PS_H__
|
||||
|
||||
bool rtl_ps_set_rf_state(struct ieee80211_hw *hw,
|
||||
enum rf_pwrstate state_toset, u32 changesource,
|
||||
bool protect_or_not);
|
||||
bool rtl_ps_enable_nic(struct ieee80211_hw *hw);
|
||||
bool rtl_ps_disable_nic(struct ieee80211_hw *hw);
|
||||
void rtl_ips_nic_off(struct ieee80211_hw *hw);
|
||||
void rtl_ips_nic_on(struct ieee80211_hw *hw);
|
||||
void rtl_ips_nic_off_wq_callback(void *data);
|
||||
void rtl_lps_enter(struct ieee80211_hw *hw);
|
||||
void rtl_lps_leave(struct ieee80211_hw *hw);
|
||||
#endif
|
329
drivers/net/wireless/rtlwifi/rc.c
Normal file
329
drivers/net/wireless/rtlwifi/rc.c
Normal file
@ -0,0 +1,329 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2009-2010 Realtek Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* wlanfae <wlanfae@realtek.com>
|
||||
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
|
||||
* Hsinchu 300, Taiwan.
|
||||
*
|
||||
* Larry Finger <Larry.Finger@lwfinger.net>
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "wifi.h"
|
||||
#include "base.h"
|
||||
#include "rc.h"
|
||||
|
||||
/*
|
||||
*Finds the highest rate index we can use
|
||||
*if skb is special data like DHCP/EAPOL, we set should
|
||||
*it to lowest rate CCK_1M, otherwise we set rate to
|
||||
*CCK11M or OFDM_54M based on wireless mode.
|
||||
*/
|
||||
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];
|
||||
|
||||
/*
|
||||
*this rate is no use for true rate, firmware
|
||||
*will control rate at all it just used for
|
||||
*1.show in iwconfig in B/G mode
|
||||
*2.in rtl_get_tcb_desc when we check rate is
|
||||
* 1M we will not use FW rate but user rate.
|
||||
*/
|
||||
if (rtl_is_special_data(rtlpriv->mac80211.hw, skb, true)) {
|
||||
return rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M];
|
||||
} else {
|
||||
if (rtlmac->mode == WIRELESS_MODE_B)
|
||||
return rtlpriv->cfg->maps[RTL_RC_CCK_RATE11M];
|
||||
else
|
||||
return rtlpriv->cfg->maps[RTL_RC_OFDM_RATE54M];
|
||||
}
|
||||
}
|
||||
|
||||
static void _rtl_rc_rate_set_series(struct rtl_priv *rtlpriv,
|
||||
struct ieee80211_tx_rate *rate,
|
||||
struct ieee80211_tx_rate_control *txrc,
|
||||
u8 tries, u8 rix, int rtsctsenable,
|
||||
bool not_data)
|
||||
{
|
||||
struct rtl_mac *mac = rtl_mac(rtlpriv);
|
||||
|
||||
rate->count = tries;
|
||||
rate->idx = (rix > 0x2) ? rix : 0x2;
|
||||
|
||||
if (!not_data) {
|
||||
if (txrc->short_preamble)
|
||||
rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE;
|
||||
if (mac->bw_40)
|
||||
rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
|
||||
if (mac->sgi_20 || mac->sgi_40)
|
||||
rate->flags |= IEEE80211_TX_RC_SHORT_GI;
|
||||
if (mac->ht_enable)
|
||||
rate->flags |= IEEE80211_TX_RC_MCS;
|
||||
}
|
||||
}
|
||||
|
||||
static void rtl_get_rate(void *ppriv, struct ieee80211_sta *sta,
|
||||
void *priv_sta, struct ieee80211_tx_rate_control *txrc)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = ppriv;
|
||||
struct sk_buff *skb = txrc->skb;
|
||||
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
|
||||
struct ieee80211_tx_rate *rates = tx_info->control.rates;
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||||
__le16 fc = hdr->frame_control;
|
||||
u8 try_per_rate, i, rix;
|
||||
bool not_data = !ieee80211_is_data(fc);
|
||||
|
||||
if (rate_control_send_low(sta, priv_sta, txrc))
|
||||
return;
|
||||
|
||||
rix = _rtl_rc_get_highest_rix(rtlpriv, skb, not_data);
|
||||
|
||||
try_per_rate = 1;
|
||||
_rtl_rc_rate_set_series(rtlpriv, &rates[0], txrc,
|
||||
try_per_rate, rix, 1, not_data);
|
||||
|
||||
if (!not_data) {
|
||||
for (i = 1; i < 4; i++)
|
||||
_rtl_rc_rate_set_series(rtlpriv, &rates[i],
|
||||
txrc, i, (rix - i), 1,
|
||||
not_data);
|
||||
}
|
||||
}
|
||||
|
||||
static bool _rtl_tx_aggr_check(struct rtl_priv *rtlpriv, u16 tid)
|
||||
{
|
||||
struct rtl_mac *mac = rtl_mac(rtlpriv);
|
||||
|
||||
if (mac->act_scanning)
|
||||
return false;
|
||||
|
||||
if (mac->cnt_after_linked < 3)
|
||||
return false;
|
||||
|
||||
if (mac->tids[tid].agg.agg_state == RTL_AGG_OFF)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*mac80211 Rate Control callbacks*/
|
||||
static void rtl_tx_status(void *ppriv,
|
||||
struct ieee80211_supported_band *sband,
|
||||
struct ieee80211_sta *sta, void *priv_sta,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = ppriv;
|
||||
struct rtl_mac *mac = rtl_mac(rtlpriv);
|
||||
struct ieee80211_hdr *hdr;
|
||||
__le16 fc;
|
||||
|
||||
hdr = (struct ieee80211_hdr *)skb->data;
|
||||
fc = hdr->frame_control;
|
||||
|
||||
if (!priv_sta || !ieee80211_is_data(fc))
|
||||
return;
|
||||
|
||||
if (rtl_is_special_data(mac->hw, skb, true))
|
||||
return;
|
||||
|
||||
if (is_multicast_ether_addr(ieee80211_get_DA(hdr))
|
||||
|| is_broadcast_ether_addr(ieee80211_get_DA(hdr)))
|
||||
return;
|
||||
|
||||
/* Check if aggregation has to be enabled for this tid */
|
||||
if (conf_is_ht(&mac->hw->conf) &&
|
||||
!(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
|
||||
if (ieee80211_is_data_qos(fc)) {
|
||||
u8 *qc, tid;
|
||||
|
||||
qc = ieee80211_get_qos_ctl(hdr);
|
||||
tid = qc[0] & 0xf;
|
||||
|
||||
if (_rtl_tx_aggr_check(rtlpriv, tid))
|
||||
ieee80211_start_tx_ba_session(sta, tid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void rtl_rate_init(void *ppriv,
|
||||
struct ieee80211_supported_band *sband,
|
||||
struct ieee80211_sta *sta, void *priv_sta)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = ppriv;
|
||||
struct rtl_mac *mac = rtl_mac(rtlpriv);
|
||||
u8 is_ht = conf_is_ht(&mac->hw->conf);
|
||||
|
||||
if ((mac->opmode == NL80211_IFTYPE_STATION) ||
|
||||
(mac->opmode == NL80211_IFTYPE_MESH_POINT) ||
|
||||
(mac->opmode == NL80211_IFTYPE_ADHOC)) {
|
||||
|
||||
switch (sband->band) {
|
||||
case IEEE80211_BAND_2GHZ:
|
||||
rtlpriv->rate_priv->cur_ratetab_idx =
|
||||
RATR_INX_WIRELESS_G;
|
||||
if (is_ht)
|
||||
rtlpriv->rate_priv->cur_ratetab_idx =
|
||||
RATR_INX_WIRELESS_NGB;
|
||||
break;
|
||||
case IEEE80211_BAND_5GHZ:
|
||||
rtlpriv->rate_priv->cur_ratetab_idx =
|
||||
RATR_INX_WIRELESS_A;
|
||||
if (is_ht)
|
||||
rtlpriv->rate_priv->cur_ratetab_idx =
|
||||
RATR_INX_WIRELESS_NGB;
|
||||
break;
|
||||
default:
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
|
||||
("Invalid band\n"));
|
||||
rtlpriv->rate_priv->cur_ratetab_idx =
|
||||
RATR_INX_WIRELESS_NGB;
|
||||
break;
|
||||
}
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_RATE, DBG_DMESG,
|
||||
("Choosing rate table index: %d\n",
|
||||
rtlpriv->rate_priv->cur_ratetab_idx));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void rtl_rate_update(void *ppriv,
|
||||
struct ieee80211_supported_band *sband,
|
||||
struct ieee80211_sta *sta, void *priv_sta,
|
||||
u32 changed,
|
||||
enum nl80211_channel_type oper_chan_type)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = ppriv;
|
||||
struct rtl_mac *mac = rtl_mac(rtlpriv);
|
||||
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
|
||||
bool oper_cw40 = false, oper_sgi40;
|
||||
bool local_cw40 = mac->bw_40;
|
||||
bool local_sgi40 = mac->sgi_40;
|
||||
u8 is_ht = conf_is_ht(&mac->hw->conf);
|
||||
|
||||
if (changed & IEEE80211_RC_HT_CHANGED) {
|
||||
if (mac->opmode != NL80211_IFTYPE_STATION)
|
||||
return;
|
||||
|
||||
if (rtlhal->hw->conf.channel_type == NL80211_CHAN_HT40MINUS ||
|
||||
rtlhal->hw->conf.channel_type == NL80211_CHAN_HT40PLUS)
|
||||
oper_cw40 = true;
|
||||
|
||||
oper_sgi40 = mac->sgi_40;
|
||||
|
||||
if ((local_cw40 != oper_cw40) || (local_sgi40 != oper_sgi40)) {
|
||||
switch (sband->band) {
|
||||
case IEEE80211_BAND_2GHZ:
|
||||
rtlpriv->rate_priv->cur_ratetab_idx =
|
||||
RATR_INX_WIRELESS_G;
|
||||
if (is_ht)
|
||||
rtlpriv->rate_priv->cur_ratetab_idx =
|
||||
RATR_INX_WIRELESS_NGB;
|
||||
break;
|
||||
case IEEE80211_BAND_5GHZ:
|
||||
rtlpriv->rate_priv->cur_ratetab_idx =
|
||||
RATR_INX_WIRELESS_A;
|
||||
if (is_ht)
|
||||
rtlpriv->rate_priv->cur_ratetab_idx =
|
||||
RATR_INX_WIRELESS_NGB;
|
||||
break;
|
||||
default:
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
||||
("Invalid band\n"));
|
||||
rtlpriv->rate_priv->cur_ratetab_idx =
|
||||
RATR_INX_WIRELESS_NGB;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void *rtl_rate_alloc(struct ieee80211_hw *hw,
|
||||
struct dentry *debugfsdir)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
return rtlpriv;
|
||||
}
|
||||
|
||||
static void rtl_rate_free(void *rtlpriv)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static void *rtl_rate_alloc_sta(void *ppriv,
|
||||
struct ieee80211_sta *sta, gfp_t gfp)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = ppriv;
|
||||
struct rtl_rate_priv *rate_priv;
|
||||
|
||||
rate_priv = kzalloc(sizeof(struct rtl_rate_priv), gfp);
|
||||
if (!rate_priv) {
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
||||
("Unable to allocate private rc structure\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rtlpriv->rate_priv = rate_priv;
|
||||
|
||||
return rate_priv;
|
||||
}
|
||||
|
||||
static void rtl_rate_free_sta(void *rtlpriv,
|
||||
struct ieee80211_sta *sta, void *priv_sta)
|
||||
{
|
||||
struct rtl_rate_priv *rate_priv = priv_sta;
|
||||
kfree(rate_priv);
|
||||
}
|
||||
|
||||
static struct rate_control_ops rtl_rate_ops = {
|
||||
.module = NULL,
|
||||
.name = "rtl_rc",
|
||||
.alloc = rtl_rate_alloc,
|
||||
.free = rtl_rate_free,
|
||||
.alloc_sta = rtl_rate_alloc_sta,
|
||||
.free_sta = rtl_rate_free_sta,
|
||||
.rate_init = rtl_rate_init,
|
||||
.rate_update = rtl_rate_update,
|
||||
.tx_status = rtl_tx_status,
|
||||
.get_rate = rtl_get_rate,
|
||||
};
|
||||
|
||||
int rtl_rate_control_register(void)
|
||||
{
|
||||
return ieee80211_rate_control_register(&rtl_rate_ops);
|
||||
}
|
||||
|
||||
void rtl_rate_control_unregister(void)
|
||||
{
|
||||
ieee80211_rate_control_unregister(&rtl_rate_ops);
|
||||
}
|
40
drivers/net/wireless/rtlwifi/rc.h
Normal file
40
drivers/net/wireless/rtlwifi/rc.h
Normal file
@ -0,0 +1,40 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2009-2010 Realtek Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* wlanfae <wlanfae@realtek.com>
|
||||
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
|
||||
* Hsinchu 300, Taiwan.
|
||||
*
|
||||
* Larry Finger <Larry.Finger@lwfinger.net>
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __RTL_RC_H__
|
||||
#define __RTL_RC_H__
|
||||
|
||||
struct rtl_rate_priv {
|
||||
u8 cur_ratetab_idx;
|
||||
u8 ht_cap;
|
||||
};
|
||||
|
||||
int rtl_rate_control_register(void);
|
||||
void rtl_rate_control_unregister(void);
|
||||
#endif
|
400
drivers/net/wireless/rtlwifi/regd.c
Normal file
400
drivers/net/wireless/rtlwifi/regd.c
Normal file
@ -0,0 +1,400 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2009-2010 Realtek Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* wlanfae <wlanfae@realtek.com>
|
||||
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
|
||||
* Hsinchu 300, Taiwan.
|
||||
*
|
||||
* Larry Finger <Larry.Finger@lwfinger.net>
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "wifi.h"
|
||||
#include "regd.h"
|
||||
|
||||
static struct country_code_to_enum_rd allCountries[] = {
|
||||
{COUNTRY_CODE_FCC, "US"},
|
||||
{COUNTRY_CODE_IC, "US"},
|
||||
{COUNTRY_CODE_ETSI, "EC"},
|
||||
{COUNTRY_CODE_SPAIN, "EC"},
|
||||
{COUNTRY_CODE_FRANCE, "EC"},
|
||||
{COUNTRY_CODE_MKK, "JP"},
|
||||
{COUNTRY_CODE_MKK1, "JP"},
|
||||
{COUNTRY_CODE_ISRAEL, "EC"},
|
||||
{COUNTRY_CODE_TELEC, "JP"},
|
||||
{COUNTRY_CODE_MIC, "JP"},
|
||||
{COUNTRY_CODE_GLOBAL_DOMAIN, "JP"},
|
||||
{COUNTRY_CODE_WORLD_WIDE_13, "EC"},
|
||||
{COUNTRY_CODE_TELEC_NETGEAR, "EC"},
|
||||
};
|
||||
|
||||
/*
|
||||
*Only these channels all allow active
|
||||
*scan on all world regulatory domains
|
||||
*/
|
||||
#define RTL819x_2GHZ_CH01_11 \
|
||||
REG_RULE(2412-10, 2462+10, 40, 0, 20, 0)
|
||||
|
||||
/*
|
||||
*We enable active scan on these a case
|
||||
*by case basis by regulatory domain
|
||||
*/
|
||||
#define RTL819x_2GHZ_CH12_13 \
|
||||
REG_RULE(2467-10, 2472+10, 40, 0, 20,\
|
||||
NL80211_RRF_PASSIVE_SCAN)
|
||||
|
||||
#define RTL819x_2GHZ_CH14 \
|
||||
REG_RULE(2484-10, 2484+10, 40, 0, 20, \
|
||||
NL80211_RRF_PASSIVE_SCAN | \
|
||||
NL80211_RRF_NO_OFDM)
|
||||
|
||||
static const struct ieee80211_regdomain rtl_regdom_11 = {
|
||||
.n_reg_rules = 1,
|
||||
.alpha2 = "99",
|
||||
.reg_rules = {
|
||||
RTL819x_2GHZ_CH01_11,
|
||||
}
|
||||
};
|
||||
|
||||
static const struct ieee80211_regdomain rtl_regdom_global = {
|
||||
.n_reg_rules = 3,
|
||||
.alpha2 = "99",
|
||||
.reg_rules = {
|
||||
RTL819x_2GHZ_CH01_11,
|
||||
RTL819x_2GHZ_CH12_13,
|
||||
RTL819x_2GHZ_CH14,
|
||||
}
|
||||
};
|
||||
|
||||
static const struct ieee80211_regdomain rtl_regdom_world = {
|
||||
.n_reg_rules = 2,
|
||||
.alpha2 = "99",
|
||||
.reg_rules = {
|
||||
RTL819x_2GHZ_CH01_11,
|
||||
RTL819x_2GHZ_CH12_13,
|
||||
}
|
||||
};
|
||||
|
||||
static bool _rtl_is_radar_freq(u16 center_freq)
|
||||
{
|
||||
return (center_freq >= 5260 && center_freq <= 5700);
|
||||
}
|
||||
|
||||
static void _rtl_reg_apply_beaconing_flags(struct wiphy *wiphy,
|
||||
enum nl80211_reg_initiator initiator)
|
||||
{
|
||||
enum ieee80211_band band;
|
||||
struct ieee80211_supported_band *sband;
|
||||
const struct ieee80211_reg_rule *reg_rule;
|
||||
struct ieee80211_channel *ch;
|
||||
unsigned int i;
|
||||
u32 bandwidth = 0;
|
||||
int r;
|
||||
|
||||
for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
|
||||
|
||||
if (!wiphy->bands[band])
|
||||
continue;
|
||||
|
||||
sband = wiphy->bands[band];
|
||||
|
||||
for (i = 0; i < sband->n_channels; i++) {
|
||||
ch = &sband->channels[i];
|
||||
if (_rtl_is_radar_freq(ch->center_freq) ||
|
||||
(ch->flags & IEEE80211_CHAN_RADAR))
|
||||
continue;
|
||||
if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) {
|
||||
r = freq_reg_info(wiphy, ch->center_freq,
|
||||
bandwidth, ®_rule);
|
||||
if (r)
|
||||
continue;
|
||||
|
||||
/*
|
||||
*If 11d had a rule for this channel ensure
|
||||
*we enable adhoc/beaconing if it allows us to
|
||||
*use it. Note that we would have disabled it
|
||||
*by applying our static world regdomain by
|
||||
*default during init, prior to calling our
|
||||
*regulatory_hint().
|
||||
*/
|
||||
|
||||
if (!(reg_rule->flags & NL80211_RRF_NO_IBSS))
|
||||
ch->flags &= ~IEEE80211_CHAN_NO_IBSS;
|
||||
if (!(reg_rule->
|
||||
flags & NL80211_RRF_PASSIVE_SCAN))
|
||||
ch->flags &=
|
||||
~IEEE80211_CHAN_PASSIVE_SCAN;
|
||||
} else {
|
||||
if (ch->beacon_found)
|
||||
ch->flags &= ~(IEEE80211_CHAN_NO_IBSS |
|
||||
IEEE80211_CHAN_PASSIVE_SCAN);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Allows active scan scan on Ch 12 and 13 */
|
||||
static void _rtl_reg_apply_active_scan_flags(struct wiphy *wiphy,
|
||||
enum nl80211_reg_initiator
|
||||
initiator)
|
||||
{
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct ieee80211_channel *ch;
|
||||
const struct ieee80211_reg_rule *reg_rule;
|
||||
u32 bandwidth = 0;
|
||||
int r;
|
||||
|
||||
sband = wiphy->bands[IEEE80211_BAND_2GHZ];
|
||||
|
||||
/*
|
||||
*If no country IE has been received always enable active scan
|
||||
*on these channels. This is only done for specific regulatory SKUs
|
||||
*/
|
||||
if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) {
|
||||
ch = &sband->channels[11]; /* CH 12 */
|
||||
if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
|
||||
ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
|
||||
ch = &sband->channels[12]; /* CH 13 */
|
||||
if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
|
||||
ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
*If a country IE has been recieved check its rule for this
|
||||
*channel first before enabling active scan. The passive scan
|
||||
*would have been enforced by the initial processing of our
|
||||
*custom regulatory domain.
|
||||
*/
|
||||
|
||||
ch = &sband->channels[11]; /* CH 12 */
|
||||
r = freq_reg_info(wiphy, ch->center_freq, bandwidth, ®_rule);
|
||||
if (!r) {
|
||||
if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
|
||||
if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
|
||||
ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
|
||||
}
|
||||
|
||||
ch = &sband->channels[12]; /* CH 13 */
|
||||
r = freq_reg_info(wiphy, ch->center_freq, bandwidth, ®_rule);
|
||||
if (!r) {
|
||||
if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
|
||||
if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
|
||||
ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*Always apply Radar/DFS rules on
|
||||
*freq range 5260 MHz - 5700 MHz
|
||||
*/
|
||||
static void _rtl_reg_apply_radar_flags(struct wiphy *wiphy)
|
||||
{
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct ieee80211_channel *ch;
|
||||
unsigned int i;
|
||||
|
||||
if (!wiphy->bands[IEEE80211_BAND_5GHZ])
|
||||
return;
|
||||
|
||||
sband = wiphy->bands[IEEE80211_BAND_5GHZ];
|
||||
|
||||
for (i = 0; i < sband->n_channels; i++) {
|
||||
ch = &sband->channels[i];
|
||||
if (!_rtl_is_radar_freq(ch->center_freq))
|
||||
continue;
|
||||
|
||||
/*
|
||||
*We always enable radar detection/DFS on this
|
||||
*frequency range. Additionally we also apply on
|
||||
*this frequency range:
|
||||
*- If STA mode does not yet have DFS supports disable
|
||||
* active scanning
|
||||
*- If adhoc mode does not support DFS yet then disable
|
||||
* adhoc in the frequency.
|
||||
*- If AP mode does not yet support radar detection/DFS
|
||||
*do not allow AP mode
|
||||
*/
|
||||
if (!(ch->flags & IEEE80211_CHAN_DISABLED))
|
||||
ch->flags |= IEEE80211_CHAN_RADAR |
|
||||
IEEE80211_CHAN_NO_IBSS |
|
||||
IEEE80211_CHAN_PASSIVE_SCAN;
|
||||
}
|
||||
}
|
||||
|
||||
static void _rtl_reg_apply_world_flags(struct wiphy *wiphy,
|
||||
enum nl80211_reg_initiator initiator,
|
||||
struct rtl_regulatory *reg)
|
||||
{
|
||||
_rtl_reg_apply_beaconing_flags(wiphy, initiator);
|
||||
_rtl_reg_apply_active_scan_flags(wiphy, initiator);
|
||||
return;
|
||||
}
|
||||
|
||||
static void _rtl_dump_channel_map(struct wiphy *wiphy)
|
||||
{
|
||||
enum ieee80211_band band;
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct ieee80211_channel *ch;
|
||||
unsigned int i;
|
||||
|
||||
for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
|
||||
if (!wiphy->bands[band])
|
||||
continue;
|
||||
sband = wiphy->bands[band];
|
||||
for (i = 0; i < sband->n_channels; i++)
|
||||
ch = &sband->channels[i];
|
||||
}
|
||||
}
|
||||
|
||||
static int _rtl_reg_notifier_apply(struct wiphy *wiphy,
|
||||
struct regulatory_request *request,
|
||||
struct rtl_regulatory *reg)
|
||||
{
|
||||
/* We always apply this */
|
||||
_rtl_reg_apply_radar_flags(wiphy);
|
||||
|
||||
switch (request->initiator) {
|
||||
case NL80211_REGDOM_SET_BY_DRIVER:
|
||||
case NL80211_REGDOM_SET_BY_CORE:
|
||||
case NL80211_REGDOM_SET_BY_USER:
|
||||
break;
|
||||
case NL80211_REGDOM_SET_BY_COUNTRY_IE:
|
||||
_rtl_reg_apply_world_flags(wiphy, request->initiator, reg);
|
||||
break;
|
||||
}
|
||||
|
||||
_rtl_dump_channel_map(wiphy);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct ieee80211_regdomain *_rtl_regdomain_select(
|
||||
struct rtl_regulatory *reg)
|
||||
{
|
||||
switch (reg->country_code) {
|
||||
case COUNTRY_CODE_FCC:
|
||||
case COUNTRY_CODE_IC:
|
||||
return &rtl_regdom_11;
|
||||
case COUNTRY_CODE_ETSI:
|
||||
case COUNTRY_CODE_SPAIN:
|
||||
case COUNTRY_CODE_FRANCE:
|
||||
case COUNTRY_CODE_ISRAEL:
|
||||
case COUNTRY_CODE_TELEC_NETGEAR:
|
||||
return &rtl_regdom_world;
|
||||
case COUNTRY_CODE_MKK:
|
||||
case COUNTRY_CODE_MKK1:
|
||||
case COUNTRY_CODE_TELEC:
|
||||
case COUNTRY_CODE_MIC:
|
||||
return &rtl_regdom_global;
|
||||
case COUNTRY_CODE_GLOBAL_DOMAIN:
|
||||
return &rtl_regdom_global;
|
||||
case COUNTRY_CODE_WORLD_WIDE_13:
|
||||
return &rtl_regdom_world;
|
||||
default:
|
||||
return &rtl_regdom_world;
|
||||
}
|
||||
}
|
||||
|
||||
static int _rtl_regd_init_wiphy(struct rtl_regulatory *reg,
|
||||
struct wiphy *wiphy,
|
||||
int (*reg_notifier) (struct wiphy *wiphy,
|
||||
struct regulatory_request *
|
||||
request))
|
||||
{
|
||||
const struct ieee80211_regdomain *regd;
|
||||
|
||||
wiphy->reg_notifier = reg_notifier;
|
||||
wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
|
||||
wiphy->flags &= ~WIPHY_FLAG_STRICT_REGULATORY;
|
||||
wiphy->flags &= ~WIPHY_FLAG_DISABLE_BEACON_HINTS;
|
||||
regd = _rtl_regdomain_select(reg);
|
||||
wiphy_apply_custom_regulatory(wiphy, regd);
|
||||
_rtl_reg_apply_radar_flags(wiphy);
|
||||
_rtl_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, reg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct country_code_to_enum_rd *_rtl_regd_find_country(u16 countrycode)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
|
||||
if (allCountries[i].countrycode == countrycode)
|
||||
return &allCountries[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int rtl_regd_init(struct ieee80211_hw *hw,
|
||||
int (*reg_notifier) (struct wiphy *wiphy,
|
||||
struct regulatory_request *request))
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct wiphy *wiphy = hw->wiphy;
|
||||
struct country_code_to_enum_rd *country = NULL;
|
||||
|
||||
if (wiphy == NULL || &rtlpriv->regd == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
/* force the channel plan to world wide 13 */
|
||||
rtlpriv->regd.country_code = COUNTRY_CODE_WORLD_WIDE_13;
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_REGD, DBG_TRACE,
|
||||
(KERN_DEBUG "rtl: EEPROM regdomain: 0x%0x\n",
|
||||
rtlpriv->regd.country_code));
|
||||
|
||||
if (rtlpriv->regd.country_code >= COUNTRY_CODE_MAX) {
|
||||
RT_TRACE(rtlpriv, COMP_REGD, DBG_DMESG,
|
||||
(KERN_DEBUG "rtl: EEPROM indicates invalid contry code"
|
||||
"world wide 13 should be used\n"));
|
||||
|
||||
rtlpriv->regd.country_code = COUNTRY_CODE_WORLD_WIDE_13;
|
||||
}
|
||||
|
||||
country = _rtl_regd_find_country(rtlpriv->regd.country_code);
|
||||
|
||||
if (country) {
|
||||
rtlpriv->regd.alpha2[0] = country->isoName[0];
|
||||
rtlpriv->regd.alpha2[1] = country->isoName[1];
|
||||
} else {
|
||||
rtlpriv->regd.alpha2[0] = '0';
|
||||
rtlpriv->regd.alpha2[1] = '0';
|
||||
}
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_REGD, DBG_TRACE,
|
||||
(KERN_DEBUG "rtl: Country alpha2 being used: %c%c\n",
|
||||
rtlpriv->regd.alpha2[0], rtlpriv->regd.alpha2[1]));
|
||||
|
||||
_rtl_regd_init_wiphy(&rtlpriv->regd, wiphy, reg_notifier);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
|
||||
{
|
||||
struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_REGD, DBG_LOUD, ("\n"));
|
||||
|
||||
return _rtl_reg_notifier_apply(wiphy, request, &rtlpriv->regd);
|
||||
}
|
61
drivers/net/wireless/rtlwifi/regd.h
Normal file
61
drivers/net/wireless/rtlwifi/regd.h
Normal file
@ -0,0 +1,61 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2009-2010 Realtek Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* wlanfae <wlanfae@realtek.com>
|
||||
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
|
||||
* Hsinchu 300, Taiwan.
|
||||
*
|
||||
* Larry Finger <Larry.Finger@lwfinger.net>
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __RTL_REGD_H__
|
||||
#define __RTL_REGD_H__
|
||||
|
||||
struct country_code_to_enum_rd {
|
||||
u16 countrycode;
|
||||
const char *isoName;
|
||||
};
|
||||
|
||||
enum country_code_type_t {
|
||||
COUNTRY_CODE_FCC = 0,
|
||||
COUNTRY_CODE_IC = 1,
|
||||
COUNTRY_CODE_ETSI = 2,
|
||||
COUNTRY_CODE_SPAIN = 3,
|
||||
COUNTRY_CODE_FRANCE = 4,
|
||||
COUNTRY_CODE_MKK = 5,
|
||||
COUNTRY_CODE_MKK1 = 6,
|
||||
COUNTRY_CODE_ISRAEL = 7,
|
||||
COUNTRY_CODE_TELEC = 8,
|
||||
COUNTRY_CODE_MIC = 9,
|
||||
COUNTRY_CODE_GLOBAL_DOMAIN = 10,
|
||||
COUNTRY_CODE_WORLD_WIDE_13 = 11,
|
||||
COUNTRY_CODE_TELEC_NETGEAR = 12,
|
||||
|
||||
/*add new channel plan above this line */
|
||||
COUNTRY_CODE_MAX
|
||||
};
|
||||
|
||||
int rtl_regd_init(struct ieee80211_hw *hw,
|
||||
int (*reg_notifier) (struct wiphy *wiphy,
|
||||
struct regulatory_request *request));
|
||||
int rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request);
|
||||
#endif
|
12
drivers/net/wireless/rtlwifi/rtl8192ce/Makefile
Normal file
12
drivers/net/wireless/rtlwifi/rtl8192ce/Makefile
Normal file
@ -0,0 +1,12 @@
|
||||
rtl8192ce-objs := \
|
||||
rtl8192c-dm.o \
|
||||
rtl8192c-fw.o \
|
||||
rtl8192c-hw.o \
|
||||
rtl8192c-led.o \
|
||||
rtl8192c-phy.o \
|
||||
rtl8192c-rf.o \
|
||||
rtl8192c-sw.o \
|
||||
rtl8192c-table.o \
|
||||
rtl8192c-trx.o
|
||||
|
||||
obj-$(CONFIG_RTL8192CE) += rtl8192ce.o
|
257
drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-def.h
Normal file
257
drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-def.h
Normal file
@ -0,0 +1,257 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2009-2010 Realtek Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* wlanfae <wlanfae@realtek.com>
|
||||
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
|
||||
* Hsinchu 300, Taiwan.
|
||||
*
|
||||
* Larry Finger <Larry.Finger@lwfinger.net>
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __RTL92C_DEF_H__
|
||||
#define __RTL92C_DEF_H__
|
||||
|
||||
#define HAL_RETRY_LIMIT_INFRA 48
|
||||
#define HAL_RETRY_LIMIT_AP_ADHOC 7
|
||||
|
||||
#define PHY_RSSI_SLID_WIN_MAX 100
|
||||
#define PHY_LINKQUALITY_SLID_WIN_MAX 20
|
||||
#define PHY_BEACON_RSSI_SLID_WIN_MAX 10
|
||||
|
||||
#define RESET_DELAY_8185 20
|
||||
|
||||
#define RT_IBSS_INT_MASKS (IMR_BCNINT | IMR_TBDOK | IMR_TBDER)
|
||||
#define RT_AC_INT_MASKS (IMR_VIDOK | IMR_VODOK | IMR_BEDOK|IMR_BKDOK)
|
||||
|
||||
#define NUM_OF_FIRMWARE_QUEUE 10
|
||||
#define NUM_OF_PAGES_IN_FW 0x100
|
||||
#define NUM_OF_PAGE_IN_FW_QUEUE_BK 0x07
|
||||
#define NUM_OF_PAGE_IN_FW_QUEUE_BE 0x07
|
||||
#define NUM_OF_PAGE_IN_FW_QUEUE_VI 0x07
|
||||
#define NUM_OF_PAGE_IN_FW_QUEUE_VO 0x07
|
||||
#define NUM_OF_PAGE_IN_FW_QUEUE_HCCA 0x0
|
||||
#define NUM_OF_PAGE_IN_FW_QUEUE_CMD 0x0
|
||||
#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT 0x02
|
||||
#define NUM_OF_PAGE_IN_FW_QUEUE_HIGH 0x02
|
||||
#define NUM_OF_PAGE_IN_FW_QUEUE_BCN 0x2
|
||||
#define NUM_OF_PAGE_IN_FW_QUEUE_PUB 0xA1
|
||||
|
||||
#define NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM 0x026
|
||||
#define NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM 0x048
|
||||
#define NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM 0x048
|
||||
#define NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM 0x026
|
||||
#define NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM 0x00
|
||||
|
||||
#define MAX_LINES_HWCONFIG_TXT 1000
|
||||
#define MAX_BYTES_LINE_HWCONFIG_TXT 256
|
||||
|
||||
#define SW_THREE_WIRE 0
|
||||
#define HW_THREE_WIRE 2
|
||||
|
||||
#define BT_DEMO_BOARD 0
|
||||
#define BT_QA_BOARD 1
|
||||
#define BT_FPGA 2
|
||||
|
||||
#define RX_SMOOTH_FACTOR 20
|
||||
|
||||
#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0
|
||||
#define HAL_PRIME_CHNL_OFFSET_LOWER 1
|
||||
#define HAL_PRIME_CHNL_OFFSET_UPPER 2
|
||||
|
||||
#define MAX_H2C_QUEUE_NUM 10
|
||||
|
||||
#define RX_MPDU_QUEUE 0
|
||||
#define RX_CMD_QUEUE 1
|
||||
#define RX_MAX_QUEUE 2
|
||||
#define AC2QUEUEID(_AC) (_AC)
|
||||
|
||||
#define C2H_RX_CMD_HDR_LEN 8
|
||||
#define GET_C2H_CMD_CMD_LEN(__prxhdr) \
|
||||
LE_BITS_TO_4BYTE((__prxhdr), 0, 16)
|
||||
#define GET_C2H_CMD_ELEMENT_ID(__prxhdr) \
|
||||
LE_BITS_TO_4BYTE((__prxhdr), 16, 8)
|
||||
#define GET_C2H_CMD_CMD_SEQ(__prxhdr) \
|
||||
LE_BITS_TO_4BYTE((__prxhdr), 24, 7)
|
||||
#define GET_C2H_CMD_CONTINUE(__prxhdr) \
|
||||
LE_BITS_TO_4BYTE((__prxhdr), 31, 1)
|
||||
#define GET_C2H_CMD_CONTENT(__prxhdr) \
|
||||
((u8 *)(__prxhdr) + C2H_RX_CMD_HDR_LEN)
|
||||
|
||||
#define GET_C2H_CMD_FEEDBACK_ELEMENT_ID(__pcmdfbhdr) \
|
||||
LE_BITS_TO_4BYTE((__pcmdfbhdr), 0, 8)
|
||||
#define GET_C2H_CMD_FEEDBACK_CCX_LEN(__pcmdfbhdr) \
|
||||
LE_BITS_TO_4BYTE((__pcmdfbhdr), 8, 8)
|
||||
#define GET_C2H_CMD_FEEDBACK_CCX_CMD_CNT(__pcmdfbhdr) \
|
||||
LE_BITS_TO_4BYTE((__pcmdfbhdr), 16, 16)
|
||||
#define GET_C2H_CMD_FEEDBACK_CCX_MAC_ID(__pcmdfbhdr) \
|
||||
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 0, 5)
|
||||
#define GET_C2H_CMD_FEEDBACK_CCX_VALID(__pcmdfbhdr) \
|
||||
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 7, 1)
|
||||
#define GET_C2H_CMD_FEEDBACK_CCX_RETRY_CNT(__pcmdfbhdr) \
|
||||
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 8, 5)
|
||||
#define GET_C2H_CMD_FEEDBACK_CCX_TOK(__pcmdfbhdr) \
|
||||
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 15, 1)
|
||||
#define GET_C2H_CMD_FEEDBACK_CCX_QSEL(__pcmdfbhdr) \
|
||||
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 16, 4)
|
||||
#define GET_C2H_CMD_FEEDBACK_CCX_SEQ(__pcmdfbhdr) \
|
||||
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 20, 12)
|
||||
|
||||
#define CHIP_VER_B BIT(4)
|
||||
#define CHIP_92C_BITMASK BIT(0)
|
||||
#define CHIP_92C_1T2R 0x03
|
||||
#define CHIP_92C 0x01
|
||||
#define CHIP_88C 0x00
|
||||
|
||||
enum version_8192c {
|
||||
VERSION_A_CHIP_92C = 0x01,
|
||||
VERSION_A_CHIP_88C = 0x00,
|
||||
VERSION_B_CHIP_92C = 0x11,
|
||||
VERSION_B_CHIP_88C = 0x10,
|
||||
VERSION_UNKNOWN = 0x88,
|
||||
};
|
||||
|
||||
#define IS_CHIP_VER_B(version) ((version & CHIP_VER_B) ? true : false)
|
||||
#define IS_92C_SERIAL(version) ((version & CHIP_92C_BITMASK) ? true : false)
|
||||
|
||||
enum rtl819x_loopback_e {
|
||||
RTL819X_NO_LOOPBACK = 0,
|
||||
RTL819X_MAC_LOOPBACK = 1,
|
||||
RTL819X_DMA_LOOPBACK = 2,
|
||||
RTL819X_CCK_LOOPBACK = 3,
|
||||
};
|
||||
|
||||
enum rf_optype {
|
||||
RF_OP_BY_SW_3WIRE = 0,
|
||||
RF_OP_BY_FW,
|
||||
RF_OP_MAX
|
||||
};
|
||||
|
||||
enum rf_power_state {
|
||||
RF_ON,
|
||||
RF_OFF,
|
||||
RF_SLEEP,
|
||||
RF_SHUT_DOWN,
|
||||
};
|
||||
|
||||
enum power_save_mode {
|
||||
POWER_SAVE_MODE_ACTIVE,
|
||||
POWER_SAVE_MODE_SAVE,
|
||||
};
|
||||
|
||||
enum power_polocy_config {
|
||||
POWERCFG_MAX_POWER_SAVINGS,
|
||||
POWERCFG_GLOBAL_POWER_SAVINGS,
|
||||
POWERCFG_LOCAL_POWER_SAVINGS,
|
||||
POWERCFG_LENOVO,
|
||||
};
|
||||
|
||||
enum interface_select_pci {
|
||||
INTF_SEL1_MINICARD = 0,
|
||||
INTF_SEL0_PCIE = 1,
|
||||
INTF_SEL2_RSV = 2,
|
||||
INTF_SEL3_RSV = 3,
|
||||
};
|
||||
|
||||
enum hal_fw_c2h_cmd_id {
|
||||
HAL_FW_C2H_CMD_Read_MACREG = 0,
|
||||
HAL_FW_C2H_CMD_Read_BBREG = 1,
|
||||
HAL_FW_C2H_CMD_Read_RFREG = 2,
|
||||
HAL_FW_C2H_CMD_Read_EEPROM = 3,
|
||||
HAL_FW_C2H_CMD_Read_EFUSE = 4,
|
||||
HAL_FW_C2H_CMD_Read_CAM = 5,
|
||||
HAL_FW_C2H_CMD_Get_BasicRate = 6,
|
||||
HAL_FW_C2H_CMD_Get_DataRate = 7,
|
||||
HAL_FW_C2H_CMD_Survey = 8,
|
||||
HAL_FW_C2H_CMD_SurveyDone = 9,
|
||||
HAL_FW_C2H_CMD_JoinBss = 10,
|
||||
HAL_FW_C2H_CMD_AddSTA = 11,
|
||||
HAL_FW_C2H_CMD_DelSTA = 12,
|
||||
HAL_FW_C2H_CMD_AtimDone = 13,
|
||||
HAL_FW_C2H_CMD_TX_Report = 14,
|
||||
HAL_FW_C2H_CMD_CCX_Report = 15,
|
||||
HAL_FW_C2H_CMD_DTM_Report = 16,
|
||||
HAL_FW_C2H_CMD_TX_Rate_Statistics = 17,
|
||||
HAL_FW_C2H_CMD_C2HLBK = 18,
|
||||
HAL_FW_C2H_CMD_C2HDBG = 19,
|
||||
HAL_FW_C2H_CMD_C2HFEEDBACK = 20,
|
||||
HAL_FW_C2H_CMD_MAX
|
||||
};
|
||||
|
||||
enum rtl_desc_qsel {
|
||||
QSLT_BK = 0x2,
|
||||
QSLT_BE = 0x0,
|
||||
QSLT_VI = 0x5,
|
||||
QSLT_VO = 0x7,
|
||||
QSLT_BEACON = 0x10,
|
||||
QSLT_HIGH = 0x11,
|
||||
QSLT_MGNT = 0x12,
|
||||
QSLT_CMD = 0x13,
|
||||
};
|
||||
|
||||
enum rtl_desc92c_rate {
|
||||
DESC92C_RATE1M = 0x00,
|
||||
DESC92C_RATE2M = 0x01,
|
||||
DESC92C_RATE5_5M = 0x02,
|
||||
DESC92C_RATE11M = 0x03,
|
||||
|
||||
DESC92C_RATE6M = 0x04,
|
||||
DESC92C_RATE9M = 0x05,
|
||||
DESC92C_RATE12M = 0x06,
|
||||
DESC92C_RATE18M = 0x07,
|
||||
DESC92C_RATE24M = 0x08,
|
||||
DESC92C_RATE36M = 0x09,
|
||||
DESC92C_RATE48M = 0x0a,
|
||||
DESC92C_RATE54M = 0x0b,
|
||||
|
||||
DESC92C_RATEMCS0 = 0x0c,
|
||||
DESC92C_RATEMCS1 = 0x0d,
|
||||
DESC92C_RATEMCS2 = 0x0e,
|
||||
DESC92C_RATEMCS3 = 0x0f,
|
||||
DESC92C_RATEMCS4 = 0x10,
|
||||
DESC92C_RATEMCS5 = 0x11,
|
||||
DESC92C_RATEMCS6 = 0x12,
|
||||
DESC92C_RATEMCS7 = 0x13,
|
||||
DESC92C_RATEMCS8 = 0x14,
|
||||
DESC92C_RATEMCS9 = 0x15,
|
||||
DESC92C_RATEMCS10 = 0x16,
|
||||
DESC92C_RATEMCS11 = 0x17,
|
||||
DESC92C_RATEMCS12 = 0x18,
|
||||
DESC92C_RATEMCS13 = 0x19,
|
||||
DESC92C_RATEMCS14 = 0x1a,
|
||||
DESC92C_RATEMCS15 = 0x1b,
|
||||
DESC92C_RATEMCS15_SG = 0x1c,
|
||||
DESC92C_RATEMCS32 = 0x20,
|
||||
};
|
||||
|
||||
struct phy_sts_cck_8192s_t {
|
||||
u8 adc_pwdb_X[4];
|
||||
u8 sq_rpt;
|
||||
u8 cck_agc_rpt;
|
||||
};
|
||||
|
||||
struct h2c_cmd_8192c {
|
||||
u8 element_id;
|
||||
u32 cmd_len;
|
||||
u8 *p_cmdbuffer;
|
||||
};
|
||||
|
||||
#endif
|
1473
drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-dm.c
Normal file
1473
drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-dm.c
Normal file
File diff suppressed because it is too large
Load Diff
196
drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-dm.h
Normal file
196
drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-dm.h
Normal file
@ -0,0 +1,196 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2009-2010 Realtek Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* wlanfae <wlanfae@realtek.com>
|
||||
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
|
||||
* Hsinchu 300, Taiwan.
|
||||
*
|
||||
* Larry Finger <Larry.Finger@lwfinger.net>
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __RTL92C_DM_H__
|
||||
#define __RTL92C_DM_H__
|
||||
|
||||
#define HAL_DM_DIG_DISABLE BIT(0)
|
||||
#define HAL_DM_HIPWR_DISABLE BIT(1)
|
||||
|
||||
#define OFDM_TABLE_LENGTH 37
|
||||
#define CCK_TABLE_LENGTH 33
|
||||
|
||||
#define OFDM_TABLE_SIZE 37
|
||||
#define CCK_TABLE_SIZE 33
|
||||
|
||||
#define BW_AUTO_SWITCH_HIGH_LOW 25
|
||||
#define BW_AUTO_SWITCH_LOW_HIGH 30
|
||||
|
||||
#define DM_DIG_THRESH_HIGH 40
|
||||
#define DM_DIG_THRESH_LOW 35
|
||||
|
||||
#define DM_FALSEALARM_THRESH_LOW 400
|
||||
#define DM_FALSEALARM_THRESH_HIGH 1000
|
||||
|
||||
#define DM_DIG_MAX 0x3e
|
||||
#define DM_DIG_MIN 0x1e
|
||||
|
||||
#define DM_DIG_FA_UPPER 0x32
|
||||
#define DM_DIG_FA_LOWER 0x20
|
||||
#define DM_DIG_FA_TH0 0x20
|
||||
#define DM_DIG_FA_TH1 0x100
|
||||
#define DM_DIG_FA_TH2 0x200
|
||||
|
||||
#define DM_DIG_BACKOFF_MAX 12
|
||||
#define DM_DIG_BACKOFF_MIN -4
|
||||
#define DM_DIG_BACKOFF_DEFAULT 10
|
||||
|
||||
#define RXPATHSELECTION_SS_TH_lOW 30
|
||||
#define RXPATHSELECTION_DIFF_TH 18
|
||||
|
||||
#define DM_RATR_STA_INIT 0
|
||||
#define DM_RATR_STA_HIGH 1
|
||||
#define DM_RATR_STA_MIDDLE 2
|
||||
#define DM_RATR_STA_LOW 3
|
||||
|
||||
#define CTS2SELF_THVAL 30
|
||||
#define REGC38_TH 20
|
||||
|
||||
#define WAIOTTHVal 25
|
||||
|
||||
#define TXHIGHPWRLEVEL_NORMAL 0
|
||||
#define TXHIGHPWRLEVEL_LEVEL1 1
|
||||
#define TXHIGHPWRLEVEL_LEVEL2 2
|
||||
#define TXHIGHPWRLEVEL_BT1 3
|
||||
#define TXHIGHPWRLEVEL_BT2 4
|
||||
|
||||
#define DM_TYPE_BYFW 0
|
||||
#define DM_TYPE_BYDRIVER 1
|
||||
|
||||
#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74
|
||||
#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67
|
||||
|
||||
struct ps_t {
|
||||
u8 pre_ccastate;
|
||||
u8 cur_ccasate;
|
||||
u8 pre_rfstate;
|
||||
u8 cur_rfstate;
|
||||
long rssi_val_min;
|
||||
};
|
||||
|
||||
struct dig_t {
|
||||
u8 dig_enable_flag;
|
||||
u8 dig_ext_port_stage;
|
||||
u32 rssi_lowthresh;
|
||||
u32 rssi_highthresh;
|
||||
u32 fa_lowthresh;
|
||||
u32 fa_highthresh;
|
||||
u8 cursta_connectctate;
|
||||
u8 presta_connectstate;
|
||||
u8 curmultista_connectstate;
|
||||
u8 pre_igvalue;
|
||||
u8 cur_igvalue;
|
||||
char backoff_val;
|
||||
char backoff_val_range_max;
|
||||
char backoff_val_range_min;
|
||||
u8 rx_gain_range_max;
|
||||
u8 rx_gain_range_min;
|
||||
u8 rssi_val_min;
|
||||
u8 pre_cck_pd_state;
|
||||
u8 cur_cck_pd_state;
|
||||
u8 pre_cck_fa_state;
|
||||
u8 cur_cck_fa_state;
|
||||
u8 pre_ccastate;
|
||||
u8 cur_ccasate;
|
||||
};
|
||||
|
||||
struct swat_t {
|
||||
u8 failure_cnt;
|
||||
u8 try_flag;
|
||||
u8 stop_trying;
|
||||
long pre_rssi;
|
||||
long trying_threshold;
|
||||
u8 cur_antenna;
|
||||
u8 pre_antenna;
|
||||
};
|
||||
|
||||
enum tag_dynamic_init_gain_operation_type_definition {
|
||||
DIG_TYPE_THRESH_HIGH = 0,
|
||||
DIG_TYPE_THRESH_LOW = 1,
|
||||
DIG_TYPE_BACKOFF = 2,
|
||||
DIG_TYPE_RX_GAIN_MIN = 3,
|
||||
DIG_TYPE_RX_GAIN_MAX = 4,
|
||||
DIG_TYPE_ENABLE = 5,
|
||||
DIG_TYPE_DISABLE = 6,
|
||||
DIG_OP_TYPE_MAX
|
||||
};
|
||||
|
||||
enum tag_cck_packet_detection_threshold_type_definition {
|
||||
CCK_PD_STAGE_LowRssi = 0,
|
||||
CCK_PD_STAGE_HighRssi = 1,
|
||||
CCK_FA_STAGE_Low = 2,
|
||||
CCK_FA_STAGE_High = 3,
|
||||
CCK_PD_STAGE_MAX = 4,
|
||||
};
|
||||
|
||||
enum dm_1r_cca_e {
|
||||
CCA_1R = 0,
|
||||
CCA_2R = 1,
|
||||
CCA_MAX = 2,
|
||||
};
|
||||
|
||||
enum dm_rf_e {
|
||||
RF_SAVE = 0,
|
||||
RF_NORMAL = 1,
|
||||
RF_MAX = 2,
|
||||
};
|
||||
|
||||
enum dm_sw_ant_switch_e {
|
||||
ANS_ANTENNA_B = 1,
|
||||
ANS_ANTENNA_A = 2,
|
||||
ANS_ANTENNA_MAX = 3,
|
||||
};
|
||||
|
||||
enum dm_dig_ext_port_alg_e {
|
||||
DIG_EXT_PORT_STAGE_0 = 0,
|
||||
DIG_EXT_PORT_STAGE_1 = 1,
|
||||
DIG_EXT_PORT_STAGE_2 = 2,
|
||||
DIG_EXT_PORT_STAGE_3 = 3,
|
||||
DIG_EXT_PORT_STAGE_MAX = 4,
|
||||
};
|
||||
|
||||
enum dm_dig_connect_e {
|
||||
DIG_STA_DISCONNECT = 0,
|
||||
DIG_STA_CONNECT = 1,
|
||||
DIG_STA_BEFORE_CONNECT = 2,
|
||||
DIG_MULTISTA_DISCONNECT = 3,
|
||||
DIG_MULTISTA_CONNECT = 4,
|
||||
DIG_CONNECT_MAX
|
||||
};
|
||||
|
||||
extern struct dig_t dm_digtable;
|
||||
void rtl92c_dm_init(struct ieee80211_hw *hw);
|
||||
void rtl92c_dm_watchdog(struct ieee80211_hw *hw);
|
||||
void rtl92c_dm_write_dig(struct ieee80211_hw *hw);
|
||||
void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw);
|
||||
void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw);
|
||||
void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw);
|
||||
void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal);
|
||||
|
||||
#endif
|
804
drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-fw.c
Normal file
804
drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-fw.c
Normal file
@ -0,0 +1,804 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2009-2010 Realtek Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* wlanfae <wlanfae@realtek.com>
|
||||
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
|
||||
* Hsinchu 300, Taiwan.
|
||||
*
|
||||
* Larry Finger <Larry.Finger@lwfinger.net>
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include <linux/firmware.h>
|
||||
#include "../wifi.h"
|
||||
#include "../pci.h"
|
||||
#include "../base.h"
|
||||
#include "rtl8192c-reg.h"
|
||||
#include "rtl8192c-def.h"
|
||||
#include "rtl8192c-fw.h"
|
||||
#include "rtl8192c-table.h"
|
||||
|
||||
static void _rtl92c_enable_fw_download(struct ieee80211_hw *hw, bool enable)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
|
||||
|
||||
if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CU) {
|
||||
u32 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
|
||||
if (enable)
|
||||
value32 |= MCUFWDL_EN;
|
||||
else
|
||||
value32 &= ~MCUFWDL_EN;
|
||||
rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
|
||||
} else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CE) {
|
||||
u8 tmp;
|
||||
if (enable) {
|
||||
|
||||
tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
|
||||
rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1,
|
||||
tmp | 0x04);
|
||||
|
||||
tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
|
||||
rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01);
|
||||
|
||||
tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2);
|
||||
rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7);
|
||||
} else {
|
||||
|
||||
tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
|
||||
rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe);
|
||||
|
||||
rtl_write_byte(rtlpriv, REG_MCUFWDL + 1, 0x00);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void _rtl92c_fw_block_write(struct ieee80211_hw *hw,
|
||||
const u8 *buffer, u32 size)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
u32 blockSize = sizeof(u32);
|
||||
u8 *bufferPtr = (u8 *) buffer;
|
||||
u32 *pu4BytePtr = (u32 *) buffer;
|
||||
u32 i, offset, blockCount, remainSize;
|
||||
|
||||
blockCount = size / blockSize;
|
||||
remainSize = size % blockSize;
|
||||
|
||||
for (i = 0; i < blockCount; i++) {
|
||||
offset = i * blockSize;
|
||||
rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset),
|
||||
*(pu4BytePtr + i));
|
||||
}
|
||||
|
||||
if (remainSize) {
|
||||
offset = blockCount * blockSize;
|
||||
bufferPtr += offset;
|
||||
for (i = 0; i < remainSize; i++) {
|
||||
rtl_write_byte(rtlpriv, (FW_8192C_START_ADDRESS +
|
||||
offset + i), *(bufferPtr + i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void _rtl92c_fw_page_write(struct ieee80211_hw *hw,
|
||||
u32 page, const u8 *buffer, u32 size)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
u8 value8;
|
||||
u8 u8page = (u8) (page & 0x07);
|
||||
|
||||
value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page;
|
||||
|
||||
rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8);
|
||||
_rtl92c_fw_block_write(hw, buffer, size);
|
||||
}
|
||||
|
||||
static void _rtl92c_fill_dummy(u8 *pfwbuf, u32 *pfwlen)
|
||||
{
|
||||
u32 fwlen = *pfwlen;
|
||||
u8 remain = (u8) (fwlen % 4);
|
||||
|
||||
remain = (remain == 0) ? 0 : (4 - remain);
|
||||
|
||||
while (remain > 0) {
|
||||
pfwbuf[fwlen] = 0;
|
||||
fwlen++;
|
||||
remain--;
|
||||
}
|
||||
|
||||
*pfwlen = fwlen;
|
||||
}
|
||||
|
||||
static void _rtl92c_write_fw(struct ieee80211_hw *hw,
|
||||
enum version_8192c version, u8 *buffer, u32 size)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
|
||||
bool is_version_b;
|
||||
u8 *bufferPtr = (u8 *) buffer;
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, ("FW size is %d bytes,\n", size));
|
||||
|
||||
is_version_b = IS_CHIP_VER_B(version);
|
||||
if (is_version_b) {
|
||||
u32 pageNums, remainSize;
|
||||
u32 page, offset;
|
||||
|
||||
if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CE)
|
||||
_rtl92c_fill_dummy(bufferPtr, &size);
|
||||
|
||||
pageNums = size / FW_8192C_PAGE_SIZE;
|
||||
remainSize = size % FW_8192C_PAGE_SIZE;
|
||||
|
||||
if (pageNums > 4) {
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
||||
("Page numbers should not greater then 4\n"));
|
||||
}
|
||||
|
||||
for (page = 0; page < pageNums; page++) {
|
||||
offset = page * FW_8192C_PAGE_SIZE;
|
||||
_rtl92c_fw_page_write(hw, page, (bufferPtr + offset),
|
||||
FW_8192C_PAGE_SIZE);
|
||||
}
|
||||
|
||||
if (remainSize) {
|
||||
offset = pageNums * FW_8192C_PAGE_SIZE;
|
||||
page = pageNums;
|
||||
_rtl92c_fw_page_write(hw, page, (bufferPtr + offset),
|
||||
remainSize);
|
||||
}
|
||||
} else {
|
||||
_rtl92c_fw_block_write(hw, buffer, size);
|
||||
}
|
||||
}
|
||||
|
||||
static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
int err = -EIO;
|
||||
u32 counter = 0;
|
||||
u32 value32;
|
||||
|
||||
do {
|
||||
value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
|
||||
} while ((counter++ < FW_8192C_POLLING_TIMEOUT_COUNT) &&
|
||||
(!(value32 & FWDL_ChkSum_rpt)));
|
||||
|
||||
if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) {
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
||||
("chksum report faill ! REG_MCUFWDL:0x%08x .\n",
|
||||
value32));
|
||||
goto exit;
|
||||
}
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
|
||||
("Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32));
|
||||
|
||||
value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
|
||||
value32 |= MCUFWDL_RDY;
|
||||
value32 &= ~WINTINI_RDY;
|
||||
rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
|
||||
|
||||
counter = 0;
|
||||
|
||||
do {
|
||||
value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
|
||||
if (value32 & WINTINI_RDY) {
|
||||
RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
|
||||
("Polling FW ready success!!"
|
||||
" REG_MCUFWDL:0x%08x .\n",
|
||||
value32));
|
||||
err = 0;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mdelay(FW_8192C_POLLING_DELAY);
|
||||
|
||||
} while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT);
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
||||
("Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", value32));
|
||||
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
int rtl92c_download_fw(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
|
||||
struct rtl92c_firmware_header *pfwheader;
|
||||
u8 *pfwdata;
|
||||
u32 fwsize;
|
||||
int err;
|
||||
enum version_8192c version = rtlhal->version;
|
||||
|
||||
const struct firmware *firmware = NULL;
|
||||
|
||||
err = request_firmware(&firmware, rtlpriv->cfg->fw_name,
|
||||
rtlpriv->io.dev);
|
||||
if (err) {
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
||||
("Failed to request firmware!\n"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (firmware->size > 0x4000) {
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
||||
("Firmware is too big!\n"));
|
||||
release_firmware(firmware);
|
||||
return 1;
|
||||
}
|
||||
|
||||
memcpy(rtlhal->pfirmware, firmware->data, firmware->size);
|
||||
fwsize = firmware->size;
|
||||
release_firmware(firmware);
|
||||
|
||||
pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware;
|
||||
pfwdata = (u8 *) rtlhal->pfirmware;
|
||||
|
||||
if (IS_FW_HEADER_EXIST(pfwheader)) {
|
||||
RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
|
||||
("Firmware Version(%d), Signature(%#x),Size(%d)\n",
|
||||
pfwheader->version, pfwheader->signature,
|
||||
(uint)sizeof(struct rtl92c_firmware_header)));
|
||||
|
||||
pfwdata = pfwdata + sizeof(struct rtl92c_firmware_header);
|
||||
fwsize = fwsize - sizeof(struct rtl92c_firmware_header);
|
||||
}
|
||||
|
||||
_rtl92c_enable_fw_download(hw, true);
|
||||
_rtl92c_write_fw(hw, version, pfwdata, fwsize);
|
||||
_rtl92c_enable_fw_download(hw, false);
|
||||
|
||||
err = _rtl92c_fw_free_to_go(hw);
|
||||
if (err) {
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
||||
("Firmware is not ready to run!\n"));
|
||||
} else {
|
||||
RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
|
||||
("Firmware is ready to run!\n"));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool _rtl92c_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
u8 val_hmetfr, val_mcutst_1;
|
||||
bool result = false;
|
||||
|
||||
val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
|
||||
val_mcutst_1 = rtl_read_byte(rtlpriv, (REG_MCUTST_1 + boxnum));
|
||||
|
||||
if (((val_hmetfr >> boxnum) & BIT(0)) == 0 && val_mcutst_1 == 0)
|
||||
result = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
|
||||
u8 element_id, u32 cmd_len, u8 *p_cmdbuffer)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
|
||||
u8 boxnum;
|
||||
u16 box_reg, box_extreg;
|
||||
u8 u1b_tmp;
|
||||
bool isfw_read = false;
|
||||
u8 buf_index;
|
||||
bool bwrite_sucess = false;
|
||||
u8 wait_h2c_limmit = 100;
|
||||
u8 wait_writeh2c_limmit = 100;
|
||||
u8 boxcontent[4], boxextcontent[2];
|
||||
u32 h2c_waitcounter = 0;
|
||||
unsigned long flag;
|
||||
u8 idx;
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("come in\n"));
|
||||
|
||||
while (true) {
|
||||
spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
|
||||
if (rtlhal->b_h2c_setinprogress) {
|
||||
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
|
||||
("H2C set in progress! Wait to set.."
|
||||
"element_id(%d).\n", element_id));
|
||||
|
||||
while (rtlhal->b_h2c_setinprogress) {
|
||||
spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
|
||||
flag);
|
||||
h2c_waitcounter++;
|
||||
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
|
||||
("Wait 100 us (%d times)...\n",
|
||||
h2c_waitcounter));
|
||||
udelay(100);
|
||||
|
||||
if (h2c_waitcounter > 1000)
|
||||
return;
|
||||
spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
|
||||
flag);
|
||||
}
|
||||
spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
|
||||
} else {
|
||||
rtlhal->b_h2c_setinprogress = true;
|
||||
spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (!bwrite_sucess) {
|
||||
wait_writeh2c_limmit--;
|
||||
if (wait_writeh2c_limmit == 0) {
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
||||
("Write H2C fail because no trigger "
|
||||
"for FW INT!\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
boxnum = rtlhal->last_hmeboxnum;
|
||||
switch (boxnum) {
|
||||
case 0:
|
||||
box_reg = REG_HMEBOX_0;
|
||||
box_extreg = REG_HMEBOX_EXT_0;
|
||||
break;
|
||||
case 1:
|
||||
box_reg = REG_HMEBOX_1;
|
||||
box_extreg = REG_HMEBOX_EXT_1;
|
||||
break;
|
||||
case 2:
|
||||
box_reg = REG_HMEBOX_2;
|
||||
box_extreg = REG_HMEBOX_EXT_2;
|
||||
break;
|
||||
case 3:
|
||||
box_reg = REG_HMEBOX_3;
|
||||
box_extreg = REG_HMEBOX_EXT_3;
|
||||
break;
|
||||
default:
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
||||
("switch case not process\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
isfw_read = _rtl92c_check_fw_read_last_h2c(hw, boxnum);
|
||||
while (!isfw_read) {
|
||||
|
||||
wait_h2c_limmit--;
|
||||
if (wait_h2c_limmit == 0) {
|
||||
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
|
||||
("Wating too long for FW read "
|
||||
"clear HMEBox(%d)!\n", boxnum));
|
||||
break;
|
||||
}
|
||||
|
||||
udelay(10);
|
||||
|
||||
isfw_read = _rtl92c_check_fw_read_last_h2c(hw, boxnum);
|
||||
u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF);
|
||||
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
|
||||
("Wating for FW read clear HMEBox(%d)!!! "
|
||||
"0x1BF = %2x\n", boxnum, u1b_tmp));
|
||||
}
|
||||
|
||||
if (!isfw_read) {
|
||||
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
|
||||
("Write H2C register BOX[%d] fail!!!!! "
|
||||
"Fw do not read.\n", boxnum));
|
||||
break;
|
||||
}
|
||||
|
||||
memset(boxcontent, 0, sizeof(boxcontent));
|
||||
memset(boxextcontent, 0, sizeof(boxextcontent));
|
||||
boxcontent[0] = element_id;
|
||||
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
|
||||
("Write element_id box_reg(%4x) = %2x\n",
|
||||
box_reg, element_id));
|
||||
|
||||
switch (cmd_len) {
|
||||
case 1:
|
||||
boxcontent[0] &= ~(BIT(7));
|
||||
memcpy((u8 *) (boxcontent) + 1,
|
||||
p_cmdbuffer + buf_index, 1);
|
||||
|
||||
for (idx = 0; idx < 4; idx++) {
|
||||
rtl_write_byte(rtlpriv, box_reg + idx,
|
||||
boxcontent[idx]);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
boxcontent[0] &= ~(BIT(7));
|
||||
memcpy((u8 *) (boxcontent) + 1,
|
||||
p_cmdbuffer + buf_index, 2);
|
||||
|
||||
for (idx = 0; idx < 4; idx++) {
|
||||
rtl_write_byte(rtlpriv, box_reg + idx,
|
||||
boxcontent[idx]);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
boxcontent[0] &= ~(BIT(7));
|
||||
memcpy((u8 *) (boxcontent) + 1,
|
||||
p_cmdbuffer + buf_index, 3);
|
||||
|
||||
for (idx = 0; idx < 4; idx++) {
|
||||
rtl_write_byte(rtlpriv, box_reg + idx,
|
||||
boxcontent[idx]);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
boxcontent[0] |= (BIT(7));
|
||||
memcpy((u8 *) (boxextcontent),
|
||||
p_cmdbuffer + buf_index, 2);
|
||||
memcpy((u8 *) (boxcontent) + 1,
|
||||
p_cmdbuffer + buf_index + 2, 2);
|
||||
|
||||
for (idx = 0; idx < 2; idx++) {
|
||||
rtl_write_byte(rtlpriv, box_extreg + idx,
|
||||
boxextcontent[idx]);
|
||||
}
|
||||
|
||||
for (idx = 0; idx < 4; idx++) {
|
||||
rtl_write_byte(rtlpriv, box_reg + idx,
|
||||
boxcontent[idx]);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
boxcontent[0] |= (BIT(7));
|
||||
memcpy((u8 *) (boxextcontent),
|
||||
p_cmdbuffer + buf_index, 2);
|
||||
memcpy((u8 *) (boxcontent) + 1,
|
||||
p_cmdbuffer + buf_index + 2, 3);
|
||||
|
||||
for (idx = 0; idx < 2; idx++) {
|
||||
rtl_write_byte(rtlpriv, box_extreg + idx,
|
||||
boxextcontent[idx]);
|
||||
}
|
||||
|
||||
for (idx = 0; idx < 4; idx++) {
|
||||
rtl_write_byte(rtlpriv, box_reg + idx,
|
||||
boxcontent[idx]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
||||
("switch case not process\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
bwrite_sucess = true;
|
||||
|
||||
rtlhal->last_hmeboxnum = boxnum + 1;
|
||||
if (rtlhal->last_hmeboxnum == 4)
|
||||
rtlhal->last_hmeboxnum = 0;
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
|
||||
("pHalData->last_hmeboxnum = %d\n",
|
||||
rtlhal->last_hmeboxnum));
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
|
||||
rtlhal->b_h2c_setinprogress = false;
|
||||
spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("go out\n"));
|
||||
}
|
||||
|
||||
void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw,
|
||||
u8 element_id, u32 cmd_len, u8 *p_cmdbuffer)
|
||||
{
|
||||
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
|
||||
u32 tmp_cmdbuf[2];
|
||||
|
||||
if (rtlhal->bfw_ready == false) {
|
||||
RT_ASSERT(false, ("return H2C cmd because of Fw "
|
||||
"download fail!!!\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
memset(tmp_cmdbuf, 0, 8);
|
||||
memcpy(tmp_cmdbuf, p_cmdbuffer, cmd_len);
|
||||
_rtl92c_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void rtl92c_firmware_selfreset(struct ieee80211_hw *hw)
|
||||
{
|
||||
u8 u1b_tmp;
|
||||
u8 delay = 100;
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20);
|
||||
u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
|
||||
|
||||
while (u1b_tmp & BIT(2)) {
|
||||
delay--;
|
||||
if (delay == 0) {
|
||||
RT_ASSERT(false, ("8051 reset fail.\n"));
|
||||
break;
|
||||
}
|
||||
udelay(50);
|
||||
u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
u8 u1_h2c_set_pwrmode[3] = {0};
|
||||
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("FW LPS mode = %d\n", mode));
|
||||
|
||||
SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode);
|
||||
SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 1);
|
||||
SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode,
|
||||
ppsc->reg_max_lps_awakeintvl);
|
||||
|
||||
RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
|
||||
"rtl92c_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n",
|
||||
u1_h2c_set_pwrmode, 3);
|
||||
rtl92c_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode);
|
||||
|
||||
}
|
||||
|
||||
static bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
|
||||
struct rtl8192_tx_ring *ring;
|
||||
struct rtl_tx_desc *pdesc;
|
||||
u8 own;
|
||||
unsigned long flags;
|
||||
struct sk_buff *pskb = NULL;
|
||||
|
||||
ring = &rtlpci->tx_ring[BEACON_QUEUE];
|
||||
|
||||
pskb = __skb_dequeue(&ring->queue);
|
||||
if (pskb)
|
||||
kfree_skb(pskb);
|
||||
|
||||
spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
|
||||
|
||||
pdesc = &ring->desc[0];
|
||||
own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN);
|
||||
|
||||
rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb);
|
||||
|
||||
__skb_queue_tail(&ring->queue, skb);
|
||||
|
||||
spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
|
||||
|
||||
rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#define BEACON_PG 0 /*->1*/
|
||||
#define PSPOLL_PG 2
|
||||
#define NULL_PG 3
|
||||
#define PROBERSP_PG 4 /*->5*/
|
||||
|
||||
#define TOTAL_RESERVED_PKT_LEN 768
|
||||
|
||||
static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
|
||||
/* page 0 beacon */
|
||||
0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
|
||||
0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
|
||||
0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
|
||||
0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
|
||||
0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
|
||||
0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
|
||||
0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
|
||||
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
|
||||
0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
/* page 1 beacon */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
/* page 2 ps-poll */
|
||||
0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10,
|
||||
0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
|
||||
0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
/* page 3 null */
|
||||
0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
|
||||
0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
|
||||
0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
|
||||
0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
/* page 4 probe_resp */
|
||||
0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
|
||||
0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
|
||||
0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
|
||||
0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
|
||||
0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
|
||||
0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
|
||||
0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
|
||||
0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
|
||||
0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
|
||||
0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
|
||||
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
|
||||
0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
/* page 5 probe_resp */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
struct sk_buff *skb = NULL;
|
||||
|
||||
u32 totalpacketlen;
|
||||
bool rtstatus;
|
||||
u8 u1RsvdPageLoc[3] = {0};
|
||||
bool b_dlok = false;
|
||||
|
||||
u8 *beacon;
|
||||
u8 *p_pspoll;
|
||||
u8 *nullfunc;
|
||||
u8 *p_probersp;
|
||||
/*---------------------------------------------------------
|
||||
(1) beacon
|
||||
---------------------------------------------------------*/
|
||||
beacon = &reserved_page_packet[BEACON_PG * 128];
|
||||
SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
|
||||
SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
|
||||
|
||||
/*-------------------------------------------------------
|
||||
(2) ps-poll
|
||||
--------------------------------------------------------*/
|
||||
p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
|
||||
SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
|
||||
SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
|
||||
SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
|
||||
|
||||
SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1RsvdPageLoc, PSPOLL_PG);
|
||||
|
||||
/*--------------------------------------------------------
|
||||
(3) null data
|
||||
---------------------------------------------------------*/
|
||||
nullfunc = &reserved_page_packet[NULL_PG * 128];
|
||||
SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
|
||||
SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
|
||||
SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
|
||||
|
||||
SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1RsvdPageLoc, NULL_PG);
|
||||
|
||||
/*---------------------------------------------------------
|
||||
(4) probe response
|
||||
----------------------------------------------------------*/
|
||||
p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
|
||||
SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
|
||||
SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
|
||||
SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
|
||||
|
||||
SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc, PROBERSP_PG);
|
||||
|
||||
totalpacketlen = TOTAL_RESERVED_PKT_LEN;
|
||||
|
||||
RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
|
||||
"rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
|
||||
&reserved_page_packet[0], totalpacketlen);
|
||||
RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
|
||||
"rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
|
||||
u1RsvdPageLoc, 3);
|
||||
|
||||
|
||||
skb = dev_alloc_skb(totalpacketlen);
|
||||
memcpy((u8 *) skb_put(skb, totalpacketlen),
|
||||
&reserved_page_packet, totalpacketlen);
|
||||
|
||||
rtstatus = _rtl92c_cmd_send_packet(hw, skb);
|
||||
|
||||
if (rtstatus)
|
||||
b_dlok = true;
|
||||
|
||||
if (b_dlok) {
|
||||
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
|
||||
("Set RSVD page location to Fw.\n"));
|
||||
RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
|
||||
"H2C_RSVDPAGE:\n",
|
||||
u1RsvdPageLoc, 3);
|
||||
rtl92c_fill_h2c_cmd(hw, H2C_RSVDPAGE,
|
||||
sizeof(u1RsvdPageLoc), u1RsvdPageLoc);
|
||||
} else
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
|
||||
("Set RSVD page location to Fw FAIL!!!!!!.\n"));
|
||||
}
|
||||
|
||||
void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus)
|
||||
{
|
||||
u8 u1_joinbssrpt_parm[1] = {0};
|
||||
|
||||
SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus);
|
||||
|
||||
rtl92c_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm);
|
||||
}
|
98
drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-fw.h
Normal file
98
drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-fw.h
Normal file
@ -0,0 +1,98 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2009-2010 Realtek Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* wlanfae <wlanfae@realtek.com>
|
||||
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
|
||||
* Hsinchu 300, Taiwan.
|
||||
*
|
||||
* Larry Finger <Larry.Finger@lwfinger.net>
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __RTL92C__FW__H__
|
||||
#define __RTL92C__FW__H__
|
||||
|
||||
#define FW_8192C_SIZE 0x3000
|
||||
#define FW_8192C_START_ADDRESS 0x1000
|
||||
#define FW_8192C_END_ADDRESS 0x3FFF
|
||||
#define FW_8192C_PAGE_SIZE 4096
|
||||
#define FW_8192C_POLLING_DELAY 5
|
||||
#define FW_8192C_POLLING_TIMEOUT_COUNT 100
|
||||
|
||||
#define IS_FW_HEADER_EXIST(_pfwhdr) \
|
||||
((_pfwhdr->signature&0xFFF0) == 0x92C0 ||\
|
||||
(_pfwhdr->signature&0xFFF0) == 0x88C0)
|
||||
|
||||
struct rtl92c_firmware_header {
|
||||
u16 signature;
|
||||
u8 category;
|
||||
u8 function;
|
||||
u16 version;
|
||||
u8 subversion;
|
||||
u8 rsvd1;
|
||||
u8 month;
|
||||
u8 date;
|
||||
u8 hour;
|
||||
u8 minute;
|
||||
u16 ramcodeSize;
|
||||
u16 rsvd2;
|
||||
u32 svnindex;
|
||||
u32 rsvd3;
|
||||
u32 rsvd4;
|
||||
u32 rsvd5;
|
||||
};
|
||||
|
||||
enum rtl8192c_h2c_cmd {
|
||||
H2C_AP_OFFLOAD = 0,
|
||||
H2C_SETPWRMODE = 1,
|
||||
H2C_JOINBSSRPT = 2,
|
||||
H2C_RSVDPAGE = 3,
|
||||
H2C_RSSI_REPORT = 5,
|
||||
H2C_RA_MASK = 6,
|
||||
MAX_H2CCMD
|
||||
};
|
||||
|
||||
#define pagenum_128(_len) (u32)(((_len)>>7) + ((_len)&0x7F ? 1 : 0))
|
||||
|
||||
#define SET_H2CCMD_PWRMODE_PARM_MODE(__ph2ccmd, __val) \
|
||||
SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
|
||||
#define SET_H2CCMD_PWRMODE_PARM_SMART_PS(__ph2ccmd, __val) \
|
||||
SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val)
|
||||
#define SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(__ph2ccmd, __val) \
|
||||
SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val)
|
||||
#define SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(__ph2ccmd, __val) \
|
||||
SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
|
||||
#define SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__ph2ccmd, __val) \
|
||||
SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
|
||||
#define SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(__ph2ccmd, __val) \
|
||||
SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val)
|
||||
#define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__ph2ccmd, __val) \
|
||||
SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val)
|
||||
|
||||
int rtl92c_download_fw(struct ieee80211_hw *hw);
|
||||
void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id,
|
||||
u32 cmd_len, u8 *p_cmdbuffer);
|
||||
void rtl92c_firmware_selfreset(struct ieee80211_hw *hw);
|
||||
void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode);
|
||||
void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished);
|
||||
void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus);
|
||||
|
||||
#endif
|
2173
drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-hw.c
Normal file
2173
drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-hw.c
Normal file
File diff suppressed because it is too large
Load Diff
57
drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-hw.h
Normal file
57
drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-hw.h
Normal file
@ -0,0 +1,57 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2009-2010 Realtek Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* wlanfae <wlanfae@realtek.com>
|
||||
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
|
||||
* Hsinchu 300, Taiwan.
|
||||
*
|
||||
* Larry Finger <Larry.Finger@lwfinger.net>
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __RTL92CE_HW_H__
|
||||
#define __RTL92CE_HW_H__
|
||||
|
||||
void rtl92ce_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
|
||||
void rtl92ce_read_eeprom_info(struct ieee80211_hw *hw);
|
||||
void rtl92ce_interrupt_recognized(struct ieee80211_hw *hw,
|
||||
u32 *p_inta, u32 *p_intb);
|
||||
int rtl92ce_hw_init(struct ieee80211_hw *hw);
|
||||
void rtl92ce_card_disable(struct ieee80211_hw *hw);
|
||||
void rtl92ce_enable_interrupt(struct ieee80211_hw *hw);
|
||||
void rtl92ce_disable_interrupt(struct ieee80211_hw *hw);
|
||||
int rtl92ce_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type);
|
||||
void rtl92ce_set_qos(struct ieee80211_hw *hw, int aci);
|
||||
void rtl92ce_set_beacon_related_registers(struct ieee80211_hw *hw);
|
||||
void rtl92ce_set_beacon_interval(struct ieee80211_hw *hw);
|
||||
void rtl92ce_update_interrupt_mask(struct ieee80211_hw *hw,
|
||||
u32 add_msr, u32 rm_msr);
|
||||
void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
|
||||
void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw);
|
||||
void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level);
|
||||
void rtl92ce_update_channel_access_setting(struct ieee80211_hw *hw);
|
||||
bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid);
|
||||
void rtl92ce_enable_hw_security_config(struct ieee80211_hw *hw);
|
||||
void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index,
|
||||
u8 *p_macaddr, bool is_group, u8 enc_algo,
|
||||
bool is_wepkey, bool clear_all);
|
||||
|
||||
#endif
|
144
drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-led.c
Normal file
144
drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-led.c
Normal file
@ -0,0 +1,144 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2009-2010 Realtek Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* wlanfae <wlanfae@realtek.com>
|
||||
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
|
||||
* Hsinchu 300, Taiwan.
|
||||
*
|
||||
* Larry Finger <Larry.Finger@lwfinger.net>
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "../wifi.h"
|
||||
#include "../pci.h"
|
||||
#include "rtl8192c-reg.h"
|
||||
#include "rtl8192c-led.h"
|
||||
|
||||
void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
|
||||
{
|
||||
u8 ledcfg;
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
|
||||
("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin));
|
||||
|
||||
ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
|
||||
|
||||
switch (pled->ledpin) {
|
||||
case LED_PIN_GPIO0:
|
||||
break;
|
||||
case LED_PIN_LED0:
|
||||
rtl_write_byte(rtlpriv,
|
||||
REG_LEDCFG2, (ledcfg & 0xf0) | BIT(5) | BIT(6));
|
||||
break;
|
||||
case LED_PIN_LED1:
|
||||
rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0x0f) | BIT(5));
|
||||
break;
|
||||
default:
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
||||
("switch case not process\n"));
|
||||
break;
|
||||
}
|
||||
pled->b_ledon = true;
|
||||
}
|
||||
|
||||
void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
|
||||
u8 ledcfg;
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
|
||||
("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin));
|
||||
|
||||
ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
|
||||
|
||||
switch (pled->ledpin) {
|
||||
case LED_PIN_GPIO0:
|
||||
break;
|
||||
case LED_PIN_LED0:
|
||||
ledcfg &= 0xf0;
|
||||
if (pcipriv->ledctl.bled_opendrain == true)
|
||||
rtl_write_byte(rtlpriv, REG_LEDCFG2,
|
||||
(ledcfg | BIT(1) | BIT(5) | BIT(6)));
|
||||
else
|
||||
rtl_write_byte(rtlpriv, REG_LEDCFG2,
|
||||
(ledcfg | BIT(3) | BIT(5) | BIT(6)));
|
||||
break;
|
||||
case LED_PIN_LED1:
|
||||
ledcfg &= 0x0f;
|
||||
rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg | BIT(3)));
|
||||
break;
|
||||
default:
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
||||
("switch case not process\n"));
|
||||
break;
|
||||
}
|
||||
pled->b_ledon = false;
|
||||
}
|
||||
|
||||
void rtl92ce_init_sw_leds(struct ieee80211_hw *hw)
|
||||
{
|
||||
}
|
||||
|
||||
void rtl92ce_deinit_sw_leds(struct ieee80211_hw *hw)
|
||||
{
|
||||
}
|
||||
|
||||
void _rtl92ce_sw_led_control(struct ieee80211_hw *hw,
|
||||
enum led_ctl_mode ledaction)
|
||||
{
|
||||
struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
|
||||
struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0);
|
||||
switch (ledaction) {
|
||||
case LED_CTL_POWER_ON:
|
||||
case LED_CTL_LINK:
|
||||
case LED_CTL_NO_LINK:
|
||||
rtl92ce_sw_led_on(hw, pLed0);
|
||||
break;
|
||||
case LED_CTL_POWER_OFF:
|
||||
rtl92ce_sw_led_off(hw, pLed0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void rtl92ce_led_control(struct ieee80211_hw *hw,
|
||||
enum led_ctl_mode ledaction)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
|
||||
|
||||
if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) &&
|
||||
(ledaction == LED_CTL_TX ||
|
||||
ledaction == LED_CTL_RX ||
|
||||
ledaction == LED_CTL_SITE_SURVEY ||
|
||||
ledaction == LED_CTL_LINK ||
|
||||
ledaction == LED_CTL_NO_LINK ||
|
||||
ledaction == LED_CTL_START_TO_LINK ||
|
||||
ledaction == LED_CTL_POWER_ON)) {
|
||||
return;
|
||||
}
|
||||
RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d,\n",
|
||||
ledaction));
|
||||
_rtl92ce_sw_led_control(hw, ledaction);
|
||||
}
|
41
drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-led.h
Normal file
41
drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-led.h
Normal file
@ -0,0 +1,41 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2009-2010 Realtek Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* wlanfae <wlanfae@realtek.com>
|
||||
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
|
||||
* Hsinchu 300, Taiwan.
|
||||
*
|
||||
* Larry Finger <Larry.Finger@lwfinger.net>
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __RTL92CE_LED_H__
|
||||
#define __RTL92CE_LED_H__
|
||||
|
||||
void rtl92ce_init_sw_leds(struct ieee80211_hw *hw);
|
||||
void rtl92ce_deinit_sw_leds(struct ieee80211_hw *hw);
|
||||
void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled);
|
||||
void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled);
|
||||
void rtl92ce_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction);
|
||||
void _rtl92ce_sw_led_control(struct ieee80211_hw *hw,
|
||||
enum led_ctl_mode ledaction);
|
||||
|
||||
#endif
|
2676
drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-phy.c
Normal file
2676
drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-phy.c
Normal file
File diff suppressed because it is too large
Load Diff
237
drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-phy.h
Normal file
237
drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-phy.h
Normal file
@ -0,0 +1,237 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2009-2010 Realtek Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* wlanfae <wlanfae@realtek.com>
|
||||
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
|
||||
* Hsinchu 300, Taiwan.
|
||||
*
|
||||
* Larry Finger <Larry.Finger@lwfinger.net>
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __RTL92C_PHY_H__
|
||||
#define __RTL92C_PHY_H__
|
||||
|
||||
#define MAX_PRECMD_CNT 16
|
||||
#define MAX_RFDEPENDCMD_CNT 16
|
||||
#define MAX_POSTCMD_CNT 16
|
||||
|
||||
#define MAX_DOZE_WAITING_TIMES_9x 64
|
||||
|
||||
#define RT_CANNOT_IO(hw) false
|
||||
#define HIGHPOWER_RADIOA_ARRAYLEN 22
|
||||
|
||||
#define MAX_TOLERANCE 5
|
||||
#define IQK_DELAY_TIME 1
|
||||
|
||||
#define APK_BB_REG_NUM 5
|
||||
#define APK_AFE_REG_NUM 16
|
||||
#define APK_CURVE_REG_NUM 4
|
||||
#define PATH_NUM 2
|
||||
|
||||
#define LOOP_LIMIT 5
|
||||
#define MAX_STALL_TIME 50
|
||||
#define AntennaDiversityValue 0x80
|
||||
#define MAX_TXPWR_IDX_NMODE_92S 63
|
||||
#define Reset_Cnt_Limit 3
|
||||
|
||||
#define IQK_ADDA_REG_NUM 16
|
||||
#define IQK_MAC_REG_NUM 4
|
||||
|
||||
#define RF90_PATH_MAX 2
|
||||
#define CHANNEL_MAX_NUMBER 14
|
||||
#define CHANNEL_GROUP_MAX 3
|
||||
|
||||
#define CT_OFFSET_MAC_ADDR 0X16
|
||||
|
||||
#define CT_OFFSET_CCK_TX_PWR_IDX 0x5A
|
||||
#define CT_OFFSET_HT401S_TX_PWR_IDX 0x60
|
||||
#define CT_OFFSET_HT402S_TX_PWR_IDX_DIF 0x66
|
||||
#define CT_OFFSET_HT20_TX_PWR_IDX_DIFF 0x69
|
||||
#define CT_OFFSET_OFDM_TX_PWR_IDX_DIFF 0x6C
|
||||
|
||||
#define CT_OFFSET_HT40_MAX_PWR_OFFSET 0x6F
|
||||
#define CT_OFFSET_HT20_MAX_PWR_OFFSET 0x72
|
||||
|
||||
#define CT_OFFSET_CHANNEL_PLAH 0x75
|
||||
#define CT_OFFSET_THERMAL_METER 0x78
|
||||
#define CT_OFFSET_RF_OPTION 0x79
|
||||
#define CT_OFFSET_VERSION 0x7E
|
||||
#define CT_OFFSET_CUSTOMER_ID 0x7F
|
||||
|
||||
#define RTL92C_MAX_PATH_NUM 2
|
||||
#define CHANNEL_MAX_NUMBER 14
|
||||
#define CHANNEL_GROUP_MAX 3
|
||||
|
||||
enum swchnlcmd_id {
|
||||
CMDID_END,
|
||||
CMDID_SET_TXPOWEROWER_LEVEL,
|
||||
CMDID_BBREGWRITE10,
|
||||
CMDID_WRITEPORT_ULONG,
|
||||
CMDID_WRITEPORT_USHORT,
|
||||
CMDID_WRITEPORT_UCHAR,
|
||||
CMDID_RF_WRITEREG,
|
||||
};
|
||||
|
||||
struct swchnlcmd {
|
||||
enum swchnlcmd_id cmdid;
|
||||
u32 para1;
|
||||
u32 para2;
|
||||
u32 msdelay;
|
||||
};
|
||||
|
||||
enum hw90_block_e {
|
||||
HW90_BLOCK_MAC = 0,
|
||||
HW90_BLOCK_PHY0 = 1,
|
||||
HW90_BLOCK_PHY1 = 2,
|
||||
HW90_BLOCK_RF = 3,
|
||||
HW90_BLOCK_MAXIMUM = 4,
|
||||
};
|
||||
|
||||
enum baseband_config_type {
|
||||
BASEBAND_CONFIG_PHY_REG = 0,
|
||||
BASEBAND_CONFIG_AGC_TAB = 1,
|
||||
};
|
||||
|
||||
enum ra_offset_area {
|
||||
RA_OFFSET_LEGACY_OFDM1,
|
||||
RA_OFFSET_LEGACY_OFDM2,
|
||||
RA_OFFSET_HT_OFDM1,
|
||||
RA_OFFSET_HT_OFDM2,
|
||||
RA_OFFSET_HT_OFDM3,
|
||||
RA_OFFSET_HT_OFDM4,
|
||||
RA_OFFSET_HT_CCK,
|
||||
};
|
||||
|
||||
enum antenna_path {
|
||||
ANTENNA_NONE,
|
||||
ANTENNA_D,
|
||||
ANTENNA_C,
|
||||
ANTENNA_CD,
|
||||
ANTENNA_B,
|
||||
ANTENNA_BD,
|
||||
ANTENNA_BC,
|
||||
ANTENNA_BCD,
|
||||
ANTENNA_A,
|
||||
ANTENNA_AD,
|
||||
ANTENNA_AC,
|
||||
ANTENNA_ACD,
|
||||
ANTENNA_AB,
|
||||
ANTENNA_ABD,
|
||||
ANTENNA_ABC,
|
||||
ANTENNA_ABCD
|
||||
};
|
||||
|
||||
struct r_antenna_select_ofdm {
|
||||
u32 r_tx_antenna:4;
|
||||
u32 r_ant_l:4;
|
||||
u32 r_ant_non_ht:4;
|
||||
u32 r_ant_ht1:4;
|
||||
u32 r_ant_ht2:4;
|
||||
u32 r_ant_ht_s1:4;
|
||||
u32 r_ant_non_ht_s1:4;
|
||||
u32 ofdm_txsc:2;
|
||||
u32 reserved:2;
|
||||
};
|
||||
|
||||
struct r_antenna_select_cck {
|
||||
u8 r_cckrx_enable_2:2;
|
||||
u8 r_cckrx_enable:2;
|
||||
u8 r_ccktx_enable:4;
|
||||
};
|
||||
|
||||
struct efuse_contents {
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
u8 cck_tx_power_idx[6];
|
||||
u8 ht40_1s_tx_power_idx[6];
|
||||
u8 ht40_2s_tx_power_idx_diff[3];
|
||||
u8 ht20_tx_power_idx_diff[3];
|
||||
u8 ofdm_tx_power_idx_diff[3];
|
||||
u8 ht40_max_power_offset[3];
|
||||
u8 ht20_max_power_offset[3];
|
||||
u8 channel_plan;
|
||||
u8 thermal_meter;
|
||||
u8 rf_option[5];
|
||||
u8 version;
|
||||
u8 oem_id;
|
||||
u8 regulatory;
|
||||
};
|
||||
|
||||
struct tx_power_struct {
|
||||
u8 cck[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
|
||||
u8 ht40_1s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
|
||||
u8 ht40_2s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
|
||||
u8 ht20_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
|
||||
u8 legacy_ht_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
|
||||
u8 legacy_ht_txpowerdiff;
|
||||
u8 groupht20[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
|
||||
u8 groupht40[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
|
||||
u8 pwrgroup_cnt;
|
||||
u32 mcs_original_offset[4][16];
|
||||
};
|
||||
|
||||
extern u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw,
|
||||
u32 regaddr, u32 bitmask);
|
||||
extern void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw,
|
||||
u32 regaddr, u32 bitmask, u32 data);
|
||||
extern u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw,
|
||||
enum radio_path rfpath, u32 regaddr,
|
||||
u32 bitmask);
|
||||
extern void rtl92c_phy_set_rf_reg(struct ieee80211_hw *hw,
|
||||
enum radio_path rfpath, u32 regaddr,
|
||||
u32 bitmask, u32 data);
|
||||
extern bool rtl92c_phy_mac_config(struct ieee80211_hw *hw);
|
||||
extern bool rtl92c_phy_bb_config(struct ieee80211_hw *hw);
|
||||
extern bool rtl92c_phy_rf_config(struct ieee80211_hw *hw);
|
||||
extern bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw,
|
||||
enum radio_path rfpath);
|
||||
extern void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw);
|
||||
extern void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw,
|
||||
long *powerlevel);
|
||||
extern void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel);
|
||||
extern bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw,
|
||||
long power_indbm);
|
||||
extern void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw,
|
||||
u8 operation);
|
||||
extern void rtl92c_phy_set_bw_mode_callback(struct ieee80211_hw *hw);
|
||||
extern void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw,
|
||||
enum nl80211_channel_type ch_type);
|
||||
extern void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw);
|
||||
extern u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw);
|
||||
extern void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery);
|
||||
extern void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw,
|
||||
u16 beaconinterval);
|
||||
void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta);
|
||||
void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw);
|
||||
void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain);
|
||||
bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
|
||||
enum radio_path rfpath);
|
||||
extern bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw,
|
||||
u32 rfpath);
|
||||
bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype);
|
||||
extern bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw,
|
||||
enum rf_pwrstate rfpwr_state);
|
||||
void rtl92c_phy_config_bb_external_pa(struct ieee80211_hw *hw);
|
||||
void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw);
|
||||
bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype);
|
||||
void rtl92c_phy_set_io(struct ieee80211_hw *hw);
|
||||
|
||||
#endif
|
2065
drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-reg.h
Normal file
2065
drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-reg.h
Normal file
File diff suppressed because it is too large
Load Diff
523
drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-rf.c
Normal file
523
drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-rf.c
Normal file
@ -0,0 +1,523 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2009-2010 Realtek Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* wlanfae <wlanfae@realtek.com>
|
||||
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
|
||||
* Hsinchu 300, Taiwan.
|
||||
*
|
||||
* Larry Finger <Larry.Finger@lwfinger.net>
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "../wifi.h"
|
||||
#include "rtl8192c-reg.h"
|
||||
#include "rtl8192c-def.h"
|
||||
#include "rtl8192c-phy.h"
|
||||
#include "rtl8192c-rf.h"
|
||||
#include "rtl8192c-dm.h"
|
||||
|
||||
static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw);
|
||||
|
||||
void rtl92c_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &(rtlpriv->phy);
|
||||
|
||||
switch (bandwidth) {
|
||||
case HT_CHANNEL_WIDTH_20:
|
||||
rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] &
|
||||
0xfffff3ff) | 0x0400);
|
||||
rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK,
|
||||
rtlphy->rfreg_chnlval[0]);
|
||||
break;
|
||||
case HT_CHANNEL_WIDTH_20_40:
|
||||
rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] &
|
||||
0xfffff3ff));
|
||||
rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK,
|
||||
rtlphy->rfreg_chnlval[0]);
|
||||
break;
|
||||
default:
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
||||
("unknown bandwidth: %#X\n", bandwidth));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void rtl92c_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
|
||||
u8 *ppowerlevel)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &(rtlpriv->phy);
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
|
||||
u32 tx_agc[2] = {0, 0}, tmpval;
|
||||
bool turbo_scanoff = false;
|
||||
u8 idx1, idx2;
|
||||
u8 *ptr;
|
||||
|
||||
if (rtlefuse->eeprom_regulatory != 0)
|
||||
turbo_scanoff = true;
|
||||
|
||||
if (mac->act_scanning == true) {
|
||||
tx_agc[RF90_PATH_A] = 0x3f3f3f3f;
|
||||
tx_agc[RF90_PATH_B] = 0x3f3f3f3f;
|
||||
|
||||
if (turbo_scanoff) {
|
||||
for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
|
||||
tx_agc[idx1] = ppowerlevel[idx1] |
|
||||
(ppowerlevel[idx1] << 8) |
|
||||
(ppowerlevel[idx1] << 16) |
|
||||
(ppowerlevel[idx1] << 24);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
|
||||
tx_agc[idx1] = ppowerlevel[idx1] |
|
||||
(ppowerlevel[idx1] << 8) |
|
||||
(ppowerlevel[idx1] << 16) |
|
||||
(ppowerlevel[idx1] << 24);
|
||||
}
|
||||
|
||||
if (rtlefuse->eeprom_regulatory == 0) {
|
||||
tmpval =
|
||||
(rtlphy->mcs_txpwrlevel_origoffset[0][6]) +
|
||||
(rtlphy->mcs_txpwrlevel_origoffset[0][7] <<
|
||||
8);
|
||||
tx_agc[RF90_PATH_A] += tmpval;
|
||||
|
||||
tmpval = (rtlphy->mcs_txpwrlevel_origoffset[0][14]) +
|
||||
(rtlphy->mcs_txpwrlevel_origoffset[0][15] <<
|
||||
24);
|
||||
tx_agc[RF90_PATH_B] += tmpval;
|
||||
}
|
||||
}
|
||||
|
||||
for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
|
||||
ptr = (u8 *) (&(tx_agc[idx1]));
|
||||
for (idx2 = 0; idx2 < 4; idx2++) {
|
||||
if (*ptr > RF6052_MAX_TX_PWR)
|
||||
*ptr = RF6052_MAX_TX_PWR;
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
tmpval = tx_agc[RF90_PATH_A] & 0xff;
|
||||
rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval);
|
||||
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
("CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval,
|
||||
RTXAGC_A_CCK1_MCS32));
|
||||
|
||||
tmpval = tx_agc[RF90_PATH_A] >> 8;
|
||||
|
||||
if (mac->mode == WIRELESS_MODE_B)
|
||||
tmpval = tmpval & 0xff00ffff;
|
||||
|
||||
rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval);
|
||||
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
("CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval,
|
||||
RTXAGC_B_CCK11_A_CCK2_11));
|
||||
|
||||
tmpval = tx_agc[RF90_PATH_B] >> 24;
|
||||
rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval);
|
||||
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
("CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval,
|
||||
RTXAGC_B_CCK11_A_CCK2_11));
|
||||
|
||||
tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff;
|
||||
rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval);
|
||||
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
("CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval,
|
||||
RTXAGC_B_CCK1_55_MCS32));
|
||||
}
|
||||
|
||||
static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw,
|
||||
u8 *ppowerlevel, u8 channel,
|
||||
u32 *ofdmbase, u32 *mcsbase)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &(rtlpriv->phy);
|
||||
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
|
||||
u32 powerBase0, powerBase1;
|
||||
u8 legacy_pwrdiff, ht20_pwrdiff;
|
||||
u8 i, powerlevel[2];
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
powerlevel[i] = ppowerlevel[i];
|
||||
legacy_pwrdiff = rtlefuse->txpwr_legacyhtdiff[i][channel - 1];
|
||||
powerBase0 = powerlevel[i] + legacy_pwrdiff;
|
||||
|
||||
powerBase0 = (powerBase0 << 24) | (powerBase0 << 16) |
|
||||
(powerBase0 << 8) | powerBase0;
|
||||
*(ofdmbase + i) = powerBase0;
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
(" [OFDM power base index rf(%c) = 0x%x]\n",
|
||||
((i == 0) ? 'A' : 'B'), *(ofdmbase + i)));
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) {
|
||||
ht20_pwrdiff = rtlefuse->txpwr_ht20diff[i][channel - 1];
|
||||
powerlevel[i] += ht20_pwrdiff;
|
||||
}
|
||||
powerBase1 = powerlevel[i];
|
||||
powerBase1 = (powerBase1 << 24) |
|
||||
(powerBase1 << 16) | (powerBase1 << 8) | powerBase1;
|
||||
|
||||
*(mcsbase + i) = powerBase1;
|
||||
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
(" [MCS power base index rf(%c) = 0x%x]\n",
|
||||
((i == 0) ? 'A' : 'B'), *(mcsbase + i)));
|
||||
}
|
||||
}
|
||||
|
||||
static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
|
||||
u8 channel, u8 index,
|
||||
u32 *powerBase0,
|
||||
u32 *powerBase1,
|
||||
u32 *p_outwriteval)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &(rtlpriv->phy);
|
||||
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
|
||||
u8 i, chnlgroup, pwr_diff_limit[4];
|
||||
u32 writeVal, customer_limit, rf;
|
||||
|
||||
for (rf = 0; rf < 2; rf++) {
|
||||
switch (rtlefuse->eeprom_regulatory) {
|
||||
case 0:
|
||||
chnlgroup = 0;
|
||||
|
||||
writeVal =
|
||||
rtlphy->mcs_txpwrlevel_origoffset[chnlgroup][index +
|
||||
(rf ? 8 : 0)]
|
||||
+ ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
|
||||
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
("RTK better performance, "
|
||||
"writeVal(%c) = 0x%x\n",
|
||||
((rf == 0) ? 'A' : 'B'), writeVal));
|
||||
break;
|
||||
case 1:
|
||||
if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
|
||||
writeVal = ((index < 2) ? powerBase0[rf] :
|
||||
powerBase1[rf]);
|
||||
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
("Realtek regulatory, 40MHz, "
|
||||
"writeVal(%c) = 0x%x\n",
|
||||
((rf == 0) ? 'A' : 'B'), writeVal));
|
||||
} else {
|
||||
if (rtlphy->pwrgroup_cnt == 1)
|
||||
chnlgroup = 0;
|
||||
if (rtlphy->pwrgroup_cnt >= 3) {
|
||||
if (channel <= 3)
|
||||
chnlgroup = 0;
|
||||
else if (channel >= 4 && channel <= 9)
|
||||
chnlgroup = 1;
|
||||
else if (channel > 9)
|
||||
chnlgroup = 2;
|
||||
if (rtlphy->pwrgroup_cnt == 4)
|
||||
chnlgroup++;
|
||||
}
|
||||
|
||||
writeVal =
|
||||
rtlphy->mcs_txpwrlevel_origoffset[chnlgroup]
|
||||
[index + (rf ? 8 : 0)] + ((index < 2) ?
|
||||
powerBase0[rf] :
|
||||
powerBase1[rf]);
|
||||
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
("Realtek regulatory, 20MHz, "
|
||||
"writeVal(%c) = 0x%x\n",
|
||||
((rf == 0) ? 'A' : 'B'), writeVal));
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
writeVal =
|
||||
((index < 2) ? powerBase0[rf] : powerBase1[rf]);
|
||||
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
("Better regulatory, "
|
||||
"writeVal(%c) = 0x%x\n",
|
||||
((rf == 0) ? 'A' : 'B'), writeVal));
|
||||
break;
|
||||
case 3:
|
||||
chnlgroup = 0;
|
||||
|
||||
if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
("customer's limit, 40MHz "
|
||||
"rf(%c) = 0x%x\n",
|
||||
((rf == 0) ? 'A' : 'B'),
|
||||
rtlefuse->pwrgroup_ht40[rf][channel -
|
||||
1]));
|
||||
} else {
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
("customer's limit, 20MHz "
|
||||
"rf(%c) = 0x%x\n",
|
||||
((rf == 0) ? 'A' : 'B'),
|
||||
rtlefuse->pwrgroup_ht20[rf][channel -
|
||||
1]));
|
||||
}
|
||||
for (i = 0; i < 4; i++) {
|
||||
pwr_diff_limit[i] =
|
||||
(u8) ((rtlphy->mcs_txpwrlevel_origoffset
|
||||
[chnlgroup][index +
|
||||
(rf ? 8 : 0)] & (0x7f << (i * 8))) >>
|
||||
(i * 8));
|
||||
|
||||
if (rtlphy->current_chan_bw ==
|
||||
HT_CHANNEL_WIDTH_20_40) {
|
||||
if (pwr_diff_limit[i] >
|
||||
rtlefuse->
|
||||
pwrgroup_ht40[rf][channel - 1])
|
||||
pwr_diff_limit[i] =
|
||||
rtlefuse->pwrgroup_ht40[rf]
|
||||
[channel - 1];
|
||||
} else {
|
||||
if (pwr_diff_limit[i] >
|
||||
rtlefuse->
|
||||
pwrgroup_ht20[rf][channel - 1])
|
||||
pwr_diff_limit[i] =
|
||||
rtlefuse->pwrgroup_ht20[rf]
|
||||
[channel - 1];
|
||||
}
|
||||
}
|
||||
|
||||
customer_limit = (pwr_diff_limit[3] << 24) |
|
||||
(pwr_diff_limit[2] << 16) |
|
||||
(pwr_diff_limit[1] << 8) | (pwr_diff_limit[0]);
|
||||
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
("Customer's limit rf(%c) = 0x%x\n",
|
||||
((rf == 0) ? 'A' : 'B'), customer_limit));
|
||||
|
||||
writeVal = customer_limit +
|
||||
((index < 2) ? powerBase0[rf] : powerBase1[rf]);
|
||||
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
("Customer, writeVal rf(%c)= 0x%x\n",
|
||||
((rf == 0) ? 'A' : 'B'), writeVal));
|
||||
break;
|
||||
default:
|
||||
chnlgroup = 0;
|
||||
writeVal =
|
||||
rtlphy->mcs_txpwrlevel_origoffset[chnlgroup]
|
||||
[index + (rf ? 8 : 0)]
|
||||
+ ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
|
||||
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
("RTK better performance, writeVal "
|
||||
"rf(%c) = 0x%x\n",
|
||||
((rf == 0) ? 'A' : 'B'), writeVal));
|
||||
break;
|
||||
}
|
||||
|
||||
if (rtlpriv->dm.dynamic_txhighpower_lvl == TXHIGHPWRLEVEL_BT1)
|
||||
writeVal = writeVal - 0x06060606;
|
||||
else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
|
||||
TXHIGHPWRLEVEL_BT2)
|
||||
writeVal = writeVal - 0x0c0c0c0c;
|
||||
*(p_outwriteval + rf) = writeVal;
|
||||
}
|
||||
}
|
||||
|
||||
static void _rtl92c_write_ofdm_power_reg(struct ieee80211_hw *hw,
|
||||
u8 index, u32 *pValue)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &(rtlpriv->phy);
|
||||
|
||||
u16 regoffset_a[6] = {
|
||||
RTXAGC_A_RATE18_06, RTXAGC_A_RATE54_24,
|
||||
RTXAGC_A_MCS03_MCS00, RTXAGC_A_MCS07_MCS04,
|
||||
RTXAGC_A_MCS11_MCS08, RTXAGC_A_MCS15_MCS12
|
||||
};
|
||||
u16 regoffset_b[6] = {
|
||||
RTXAGC_B_RATE18_06, RTXAGC_B_RATE54_24,
|
||||
RTXAGC_B_MCS03_MCS00, RTXAGC_B_MCS07_MCS04,
|
||||
RTXAGC_B_MCS11_MCS08, RTXAGC_B_MCS15_MCS12
|
||||
};
|
||||
u8 i, rf, pwr_val[4];
|
||||
u32 writeVal;
|
||||
u16 regoffset;
|
||||
|
||||
for (rf = 0; rf < 2; rf++) {
|
||||
writeVal = pValue[rf];
|
||||
for (i = 0; i < 4; i++) {
|
||||
pwr_val[i] = (u8) ((writeVal & (0x7f <<
|
||||
(i * 8))) >> (i * 8));
|
||||
|
||||
if (pwr_val[i] > RF6052_MAX_TX_PWR)
|
||||
pwr_val[i] = RF6052_MAX_TX_PWR;
|
||||
}
|
||||
writeVal = (pwr_val[3] << 24) | (pwr_val[2] << 16) |
|
||||
(pwr_val[1] << 8) | pwr_val[0];
|
||||
|
||||
if (rf == 0)
|
||||
regoffset = regoffset_a[index];
|
||||
else
|
||||
regoffset = regoffset_b[index];
|
||||
rtl_set_bbreg(hw, regoffset, MASKDWORD, writeVal);
|
||||
|
||||
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
|
||||
("Set 0x%x = %08x\n", regoffset, writeVal));
|
||||
|
||||
if (((get_rf_type(rtlphy) == RF_2T2R) &&
|
||||
(regoffset == RTXAGC_A_MCS15_MCS12 ||
|
||||
regoffset == RTXAGC_B_MCS15_MCS12)) ||
|
||||
((get_rf_type(rtlphy) != RF_2T2R) &&
|
||||
(regoffset == RTXAGC_A_MCS07_MCS04 ||
|
||||
regoffset == RTXAGC_B_MCS07_MCS04))) {
|
||||
|
||||
writeVal = pwr_val[3];
|
||||
if (regoffset == RTXAGC_A_MCS15_MCS12 ||
|
||||
regoffset == RTXAGC_A_MCS07_MCS04)
|
||||
regoffset = 0xc90;
|
||||
if (regoffset == RTXAGC_B_MCS15_MCS12 ||
|
||||
regoffset == RTXAGC_B_MCS07_MCS04)
|
||||
regoffset = 0xc98;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
writeVal = (writeVal > 6) ? (writeVal - 6) : 0;
|
||||
rtl_write_byte(rtlpriv, (u32) (regoffset + i),
|
||||
(u8) writeVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rtl92c_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
|
||||
u8 *ppowerlevel, u8 channel)
|
||||
{
|
||||
u32 writeVal[2], powerBase0[2], powerBase1[2];
|
||||
u8 index;
|
||||
|
||||
rtl92c_phy_get_power_base(hw, ppowerlevel,
|
||||
channel, &powerBase0[0], &powerBase1[0]);
|
||||
|
||||
for (index = 0; index < 6; index++) {
|
||||
_rtl92c_get_txpower_writeval_by_regulatory(hw,
|
||||
channel, index,
|
||||
&powerBase0[0],
|
||||
&powerBase1[0],
|
||||
&writeVal[0]);
|
||||
|
||||
_rtl92c_write_ofdm_power_reg(hw, index, &writeVal[0]);
|
||||
}
|
||||
}
|
||||
|
||||
bool rtl92c_phy_rf6052_config(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &(rtlpriv->phy);
|
||||
|
||||
if (rtlphy->rf_type == RF_1T1R)
|
||||
rtlphy->num_total_rfpath = 1;
|
||||
else
|
||||
rtlphy->num_total_rfpath = 2;
|
||||
|
||||
return _rtl92c_phy_rf6052_config_parafile(hw);
|
||||
}
|
||||
|
||||
static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &(rtlpriv->phy);
|
||||
u32 u4_regvalue;
|
||||
u8 rfpath;
|
||||
bool rtstatus;
|
||||
struct bb_reg_def *pphyreg;
|
||||
|
||||
for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) {
|
||||
|
||||
pphyreg = &rtlphy->phyreg_def[rfpath];
|
||||
|
||||
switch (rfpath) {
|
||||
case RF90_PATH_A:
|
||||
case RF90_PATH_C:
|
||||
u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs,
|
||||
BRFSI_RFENV);
|
||||
break;
|
||||
case RF90_PATH_B:
|
||||
case RF90_PATH_D:
|
||||
u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs,
|
||||
BRFSI_RFENV << 16);
|
||||
break;
|
||||
}
|
||||
|
||||
rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1);
|
||||
udelay(1);
|
||||
|
||||
rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1);
|
||||
udelay(1);
|
||||
|
||||
rtl_set_bbreg(hw, pphyreg->rfhssi_para2,
|
||||
B3WIREADDREAALENGTH, 0x0);
|
||||
udelay(1);
|
||||
|
||||
rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0);
|
||||
udelay(1);
|
||||
|
||||
switch (rfpath) {
|
||||
case RF90_PATH_A:
|
||||
rtstatus = rtl92c_phy_config_rf_with_headerfile(hw,
|
||||
(enum radio_path) rfpath);
|
||||
break;
|
||||
case RF90_PATH_B:
|
||||
rtstatus = rtl92c_phy_config_rf_with_headerfile(hw,
|
||||
(enum radio_path) rfpath);
|
||||
break;
|
||||
case RF90_PATH_C:
|
||||
break;
|
||||
case RF90_PATH_D:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (rfpath) {
|
||||
case RF90_PATH_A:
|
||||
case RF90_PATH_C:
|
||||
rtl_set_bbreg(hw, pphyreg->rfintfs,
|
||||
BRFSI_RFENV, u4_regvalue);
|
||||
break;
|
||||
case RF90_PATH_B:
|
||||
case RF90_PATH_D:
|
||||
rtl_set_bbreg(hw, pphyreg->rfintfs,
|
||||
BRFSI_RFENV << 16, u4_regvalue);
|
||||
break;
|
||||
}
|
||||
|
||||
if (rtstatus != true) {
|
||||
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
|
||||
("Radio[%d] Fail!!", rfpath));
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("<---\n"));
|
||||
return rtstatus;
|
||||
}
|
44
drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-rf.h
Normal file
44
drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-rf.h
Normal file
@ -0,0 +1,44 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2009-2010 Realtek Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* wlanfae <wlanfae@realtek.com>
|
||||
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
|
||||
* Hsinchu 300, Taiwan.
|
||||
*
|
||||
* Larry Finger <Larry.Finger@lwfinger.net>
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __RTL92C_RF_H__
|
||||
#define __RTL92C_RF_H__
|
||||
|
||||
#define RF6052_MAX_TX_PWR 0x3F
|
||||
#define RF6052_MAX_REG 0x3F
|
||||
#define RF6052_MAX_PATH 2
|
||||
|
||||
extern void rtl92c_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw,
|
||||
u8 bandwidth);
|
||||
extern void rtl92c_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
|
||||
u8 *ppowerlevel);
|
||||
extern void rtl92c_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
|
||||
u8 *ppowerlevel, u8 channel);
|
||||
extern bool rtl92c_phy_rf6052_config(struct ieee80211_hw *hw);
|
||||
#endif
|
280
drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.c
Normal file
280
drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.c
Normal file
@ -0,0 +1,280 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2009-2010 Realtek Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* wlanfae <wlanfae@realtek.com>
|
||||
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
|
||||
* Hsinchu 300, Taiwan.
|
||||
*
|
||||
* Larry Finger <Larry.Finger@lwfinger.net>
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "../wifi.h"
|
||||
#include "../core.h"
|
||||
#include "../pci.h"
|
||||
#include "rtl8192c-reg.h"
|
||||
#include "rtl8192c-def.h"
|
||||
#include "rtl8192c-phy.h"
|
||||
#include "rtl8192c-dm.h"
|
||||
#include "rtl8192c-hw.h"
|
||||
#include "rtl8192c-sw.h"
|
||||
#include "rtl8192c-trx.h"
|
||||
#include "rtl8192c-led.h"
|
||||
|
||||
int rtl92c_init_sw_vars(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
|
||||
|
||||
rtlpriv->dm.b_dm_initialgain_enable = 1;
|
||||
rtlpriv->dm.dm_flag = 0;
|
||||
rtlpriv->dm.b_disable_framebursting = 0;;
|
||||
rtlpriv->dm.thermalvalue = 0;
|
||||
rtlpci->transmit_config = CFENDFORM | BIT(12) | BIT(13);
|
||||
|
||||
rtlpci->receive_config = (RCR_APPFCS |
|
||||
RCR_AMF |
|
||||
RCR_ADF |
|
||||
RCR_APP_MIC |
|
||||
RCR_APP_ICV |
|
||||
RCR_AICV |
|
||||
RCR_ACRC32 |
|
||||
RCR_AB |
|
||||
RCR_AM |
|
||||
RCR_APM |
|
||||
RCR_APP_PHYST_RXFF | RCR_HTC_LOC_CTRL | 0);
|
||||
|
||||
rtlpci->irq_mask[0] =
|
||||
(u32) (IMR_ROK |
|
||||
IMR_VODOK |
|
||||
IMR_VIDOK |
|
||||
IMR_BEDOK |
|
||||
IMR_BKDOK |
|
||||
IMR_MGNTDOK |
|
||||
IMR_HIGHDOK | IMR_BDOK | IMR_RDU | IMR_RXFOVW | 0);
|
||||
|
||||
rtlpci->irq_mask[1] = (u32) (IMR_CPWM | IMR_C2HCMD | 0);
|
||||
|
||||
rtlpriv->rtlhal.pfirmware = (u8 *) vmalloc(0x4000);
|
||||
if (!rtlpriv->rtlhal.pfirmware) {
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
||||
("Can't alloc buffer for fw.\n"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rtl92c_deinit_sw_vars(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
if (rtlpriv->rtlhal.pfirmware) {
|
||||
vfree(rtlpriv->rtlhal.pfirmware);
|
||||
rtlpriv->rtlhal.pfirmware = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static struct rtl_hal_ops rtl8192ce_hal_ops = {
|
||||
.init_sw_vars = rtl92c_init_sw_vars,
|
||||
.deinit_sw_vars = rtl92c_deinit_sw_vars,
|
||||
.read_eeprom_info = rtl92ce_read_eeprom_info,
|
||||
.interrupt_recognized = rtl92ce_interrupt_recognized,
|
||||
.hw_init = rtl92ce_hw_init,
|
||||
.hw_disable = rtl92ce_card_disable,
|
||||
.enable_interrupt = rtl92ce_enable_interrupt,
|
||||
.disable_interrupt = rtl92ce_disable_interrupt,
|
||||
.set_network_type = rtl92ce_set_network_type,
|
||||
.set_qos = rtl92ce_set_qos,
|
||||
.set_bcn_reg = rtl92ce_set_beacon_related_registers,
|
||||
.set_bcn_intv = rtl92ce_set_beacon_interval,
|
||||
.update_interrupt_mask = rtl92ce_update_interrupt_mask,
|
||||
.get_hw_reg = rtl92ce_get_hw_reg,
|
||||
.set_hw_reg = rtl92ce_set_hw_reg,
|
||||
.update_rate_table = rtl92ce_update_hal_rate_table,
|
||||
.update_rate_mask = rtl92ce_update_hal_rate_mask,
|
||||
.fill_tx_desc = rtl92ce_tx_fill_desc,
|
||||
.fill_tx_cmddesc = rtl92ce_tx_fill_cmddesc,
|
||||
.query_rx_desc = rtl92ce_rx_query_desc,
|
||||
.set_channel_access = rtl92ce_update_channel_access_setting,
|
||||
.radio_onoff_checking = rtl92ce_gpio_radio_on_off_checking,
|
||||
.set_bw_mode = rtl92c_phy_set_bw_mode,
|
||||
.switch_channel = rtl92c_phy_sw_chnl,
|
||||
.dm_watchdog = rtl92c_dm_watchdog,
|
||||
.scan_operation_backup = rtl92c_phy_scan_operation_backup,
|
||||
.set_rf_power_state = rtl92c_phy_set_rf_power_state,
|
||||
.led_control = rtl92ce_led_control,
|
||||
.set_desc = rtl92ce_set_desc,
|
||||
.get_desc = rtl92ce_get_desc,
|
||||
.tx_polling = rtl92ce_tx_polling,
|
||||
.enable_hw_sec = rtl92ce_enable_hw_security_config,
|
||||
.set_key = rtl92ce_set_key,
|
||||
.init_sw_leds = rtl92ce_init_sw_leds,
|
||||
.deinit_sw_leds = rtl92ce_deinit_sw_leds,
|
||||
.get_bbreg = rtl92c_phy_query_bb_reg,
|
||||
.set_bbreg = rtl92c_phy_set_bb_reg,
|
||||
.get_rfreg = rtl92c_phy_query_rf_reg,
|
||||
.set_rfreg = rtl92c_phy_set_rf_reg,
|
||||
};
|
||||
|
||||
static struct rtl_mod_params rtl92ce_mod_params = {
|
||||
.sw_crypto = 0,
|
||||
};
|
||||
|
||||
static struct rtl_hal_cfg rtl92ce_hal_cfg = {
|
||||
.name = "rtl92c_pci",
|
||||
.fw_name = "rtlwifi/rtl8192cfw.bin",
|
||||
.ops = &rtl8192ce_hal_ops,
|
||||
.mod_params = &rtl92ce_mod_params,
|
||||
|
||||
.maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL,
|
||||
.maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN,
|
||||
.maps[SYS_CLK] = REG_SYS_CLKR,
|
||||
.maps[MAC_RCR_AM] = AM,
|
||||
.maps[MAC_RCR_AB] = AB,
|
||||
.maps[MAC_RCR_ACRC32] = ACRC32,
|
||||
.maps[MAC_RCR_ACF] = ACF,
|
||||
.maps[MAC_RCR_AAP] = AAP,
|
||||
|
||||
.maps[EFUSE_TEST] = REG_EFUSE_TEST,
|
||||
.maps[EFUSE_CTRL] = REG_EFUSE_CTRL,
|
||||
.maps[EFUSE_CLK] = 0,
|
||||
.maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL,
|
||||
.maps[EFUSE_PWC_EV12V] = PWC_EV12V,
|
||||
.maps[EFUSE_FEN_ELDR] = FEN_ELDR,
|
||||
.maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN,
|
||||
.maps[EFUSE_ANA8M] = EFUSE_ANA8M,
|
||||
.maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE,
|
||||
|
||||
.maps[RWCAM] = REG_CAMCMD,
|
||||
.maps[WCAMI] = REG_CAMWRITE,
|
||||
.maps[RCAMO] = REG_CAMREAD,
|
||||
.maps[CAMDBG] = REG_CAMDBG,
|
||||
.maps[SECR] = REG_SECCFG,
|
||||
.maps[SEC_CAM_NONE] = CAM_NONE,
|
||||
.maps[SEC_CAM_WEP40] = CAM_WEP40,
|
||||
.maps[SEC_CAM_TKIP] = CAM_TKIP,
|
||||
.maps[SEC_CAM_AES] = CAM_AES,
|
||||
.maps[SEC_CAM_WEP104] = CAM_WEP104,
|
||||
|
||||
.maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6,
|
||||
.maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5,
|
||||
.maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4,
|
||||
.maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3,
|
||||
.maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2,
|
||||
.maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1,
|
||||
.maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8,
|
||||
.maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7,
|
||||
.maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6,
|
||||
.maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5,
|
||||
.maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4,
|
||||
.maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3,
|
||||
.maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2,
|
||||
.maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1,
|
||||
.maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2,
|
||||
.maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1,
|
||||
|
||||
.maps[RTL_IMR_TXFOVW] = IMR_TXFOVW,
|
||||
.maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT,
|
||||
.maps[RTL_IMR_BcnInt] = IMR_BCNINT,
|
||||
.maps[RTL_IMR_RXFOVW] = IMR_RXFOVW,
|
||||
.maps[RTL_IMR_RDU] = IMR_RDU,
|
||||
.maps[RTL_IMR_ATIMEND] = IMR_ATIMEND,
|
||||
.maps[RTL_IMR_BDOK] = IMR_BDOK,
|
||||
.maps[RTL_IMR_MGNTDOK] = IMR_MGNTDOK,
|
||||
.maps[RTL_IMR_TBDER] = IMR_TBDER,
|
||||
.maps[RTL_IMR_HIGHDOK] = IMR_HIGHDOK,
|
||||
.maps[RTL_IMR_TBDOK] = IMR_TBDOK,
|
||||
.maps[RTL_IMR_BKDOK] = IMR_BKDOK,
|
||||
.maps[RTL_IMR_BEDOK] = IMR_BEDOK,
|
||||
.maps[RTL_IMR_VIDOK] = IMR_VIDOK,
|
||||
.maps[RTL_IMR_VODOK] = IMR_VODOK,
|
||||
.maps[RTL_IMR_ROK] = IMR_ROK,
|
||||
.maps[RTL_IBSS_INT_MASKS] = (IMR_BCNINT | IMR_TBDOK | IMR_TBDER),
|
||||
|
||||
.maps[RTL_RC_CCK_RATE1M] = DESC92C_RATE1M,
|
||||
.maps[RTL_RC_CCK_RATE2M] = DESC92C_RATE2M,
|
||||
.maps[RTL_RC_CCK_RATE5_5M] = DESC92C_RATE5_5M,
|
||||
.maps[RTL_RC_CCK_RATE11M] = DESC92C_RATE11M,
|
||||
.maps[RTL_RC_OFDM_RATE6M] = DESC92C_RATE6M,
|
||||
.maps[RTL_RC_OFDM_RATE9M] = DESC92C_RATE9M,
|
||||
.maps[RTL_RC_OFDM_RATE12M] = DESC92C_RATE12M,
|
||||
.maps[RTL_RC_OFDM_RATE18M] = DESC92C_RATE18M,
|
||||
.maps[RTL_RC_OFDM_RATE24M] = DESC92C_RATE24M,
|
||||
.maps[RTL_RC_OFDM_RATE36M] = DESC92C_RATE36M,
|
||||
.maps[RTL_RC_OFDM_RATE48M] = DESC92C_RATE48M,
|
||||
.maps[RTL_RC_OFDM_RATE54M] = DESC92C_RATE54M,
|
||||
|
||||
.maps[RTL_RC_HT_RATEMCS7] = DESC92C_RATEMCS7,
|
||||
.maps[RTL_RC_HT_RATEMCS15] = DESC92C_RATEMCS15,
|
||||
};
|
||||
|
||||
static struct pci_device_id rtl92ce_pci_ids[] __devinitdata = {
|
||||
{RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8191, rtl92ce_hal_cfg)},
|
||||
{RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8178, rtl92ce_hal_cfg)},
|
||||
{RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8177, rtl92ce_hal_cfg)},
|
||||
{RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8176, rtl92ce_hal_cfg)},
|
||||
{},
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, rtl92ce_pci_ids);
|
||||
|
||||
MODULE_AUTHOR("lizhaoming <chaoming_li@realsil.com.cn>");
|
||||
MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
|
||||
MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("Realtek 8192C/8188C 802.11n PCI wireless");
|
||||
MODULE_FIRMWARE("rtlwifi/rtl8192cfw.bin");
|
||||
|
||||
module_param_named(swenc, rtl92ce_mod_params.sw_crypto, bool, 0444);
|
||||
MODULE_PARM_DESC(swenc, "using hardware crypto (default 0 [hardware])\n");
|
||||
|
||||
static struct pci_driver rtl92ce_driver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = rtl92ce_pci_ids,
|
||||
.probe = rtl_pci_probe,
|
||||
.remove = rtl_pci_disconnect,
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = rtl_pci_suspend,
|
||||
.resume = rtl_pci_resume,
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
static int __init rtl92ce_module_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = pci_register_driver(&rtl92ce_driver);
|
||||
if (ret)
|
||||
RT_ASSERT(false, (": No device found\n"));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit rtl92ce_module_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&rtl92ce_driver);
|
||||
}
|
||||
|
||||
module_init(rtl92ce_module_init);
|
||||
module_exit(rtl92ce_module_exit);
|
37
drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.h
Normal file
37
drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.h
Normal file
@ -0,0 +1,37 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2009-2010 Realtek Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* wlanfae <wlanfae@realtek.com>
|
||||
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
|
||||
* Hsinchu 300, Taiwan.
|
||||
*
|
||||
* Larry Finger <Larry.Finger@lwfinger.net>
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __RTL92CE_SW_H__
|
||||
#define __RTL92CE_SW_H__
|
||||
|
||||
int rtl92c_init_sw_vars(struct ieee80211_hw *hw);
|
||||
void rtl92c_deinit_sw_vars(struct ieee80211_hw *hw);
|
||||
void rtl92c_init_var_map(struct ieee80211_hw *hw);
|
||||
|
||||
#endif
|
1224
drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-table.c
Normal file
1224
drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-table.c
Normal file
File diff suppressed because it is too large
Load Diff
58
drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-table.h
Normal file
58
drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-table.h
Normal file
@ -0,0 +1,58 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2009-2010 Realtek Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* wlanfae <wlanfae@realtek.com>
|
||||
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
|
||||
* Hsinchu 300, Taiwan.
|
||||
*
|
||||
* Created on 2010/ 5/18, 1:41
|
||||
*
|
||||
* Larry Finger <Larry.Finger@lwfinger.net>
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __RTL92CE_TABLE__H_
|
||||
#define __RTL92CE_TABLE__H_
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#define PHY_REG_2TARRAY_LENGTH 374
|
||||
extern u32 RTL8192CEPHY_REG_2TARRAY[PHY_REG_2TARRAY_LENGTH];
|
||||
#define PHY_REG_1TARRAY_LENGTH 374
|
||||
extern u32 RTL8192CEPHY_REG_1TARRAY[PHY_REG_1TARRAY_LENGTH];
|
||||
#define PHY_REG_ARRAY_PGLENGTH 192
|
||||
extern u32 RTL8192CEPHY_REG_ARRAY_PG[PHY_REG_ARRAY_PGLENGTH];
|
||||
#define RADIOA_2TARRAYLENGTH 282
|
||||
extern u32 RTL8192CERADIOA_2TARRAY[RADIOA_2TARRAYLENGTH];
|
||||
#define RADIOB_2TARRAYLENGTH 78
|
||||
extern u32 RTL8192CE_RADIOB_2TARRAY[RADIOB_2TARRAYLENGTH];
|
||||
#define RADIOA_1TARRAYLENGTH 282
|
||||
extern u32 RTL8192CE_RADIOA_1TARRAY[RADIOA_1TARRAYLENGTH];
|
||||
#define RADIOB_1TARRAYLENGTH 1
|
||||
extern u32 RTL8192CE_RADIOB_1TARRAY[RADIOB_1TARRAYLENGTH];
|
||||
#define MAC_2T_ARRAYLENGTH 162
|
||||
extern u32 RTL8192CEMAC_2T_ARRAY[MAC_2T_ARRAYLENGTH];
|
||||
#define AGCTAB_2TARRAYLENGTH 320
|
||||
extern u32 RTL8192CEAGCTAB_2TARRAY[AGCTAB_2TARRAYLENGTH];
|
||||
#define AGCTAB_1TARRAYLENGTH 320
|
||||
extern u32 RTL8192CEAGCTAB_1TARRAY[AGCTAB_1TARRAYLENGTH];
|
||||
|
||||
#endif
|
1031
drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.c
Normal file
1031
drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.c
Normal file
File diff suppressed because it is too large
Load Diff
714
drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.h
Normal file
714
drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.h
Normal file
@ -0,0 +1,714 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2009-2010 Realtek Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* wlanfae <wlanfae@realtek.com>
|
||||
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
|
||||
* Hsinchu 300, Taiwan.
|
||||
*
|
||||
* Larry Finger <Larry.Finger@lwfinger.net>
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __RTL92CE_TRX_H__
|
||||
#define __RTL92CE_TRX_H__
|
||||
|
||||
#define TX_DESC_SIZE 64
|
||||
#define TX_DESC_AGGR_SUBFRAME_SIZE 32
|
||||
|
||||
#define RX_DESC_SIZE 32
|
||||
#define RX_DRV_INFO_SIZE_UNIT 8
|
||||
|
||||
#define TX_DESC_NEXT_DESC_OFFSET 40
|
||||
#define USB_HWDESC_HEADER_LEN 32
|
||||
#define CRCLENGTH 4
|
||||
|
||||
#define SET_TX_DESC_PKT_SIZE(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc, 0, 16, __val)
|
||||
#define SET_TX_DESC_OFFSET(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc, 16, 8, __val)
|
||||
#define SET_TX_DESC_BMC(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc, 24, 1, __val)
|
||||
#define SET_TX_DESC_HTC(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc, 25, 1, __val)
|
||||
#define SET_TX_DESC_LAST_SEG(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc, 26, 1, __val)
|
||||
#define SET_TX_DESC_FIRST_SEG(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc, 27, 1, __val)
|
||||
#define SET_TX_DESC_LINIP(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc, 28, 1, __val)
|
||||
#define SET_TX_DESC_NO_ACM(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc, 29, 1, __val)
|
||||
#define SET_TX_DESC_GF(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val)
|
||||
#define SET_TX_DESC_OWN(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val)
|
||||
|
||||
#define GET_TX_DESC_PKT_SIZE(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc, 0, 16)
|
||||
#define GET_TX_DESC_OFFSET(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc, 16, 8)
|
||||
#define GET_TX_DESC_BMC(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc, 24, 1)
|
||||
#define GET_TX_DESC_HTC(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc, 25, 1)
|
||||
#define GET_TX_DESC_LAST_SEG(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc, 26, 1)
|
||||
#define GET_TX_DESC_FIRST_SEG(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc, 27, 1)
|
||||
#define GET_TX_DESC_LINIP(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc, 28, 1)
|
||||
#define GET_TX_DESC_NO_ACM(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc, 29, 1)
|
||||
#define GET_TX_DESC_GF(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc, 30, 1)
|
||||
#define GET_TX_DESC_OWN(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc, 31, 1)
|
||||
|
||||
#define SET_TX_DESC_MACID(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+4, 0, 5, __val)
|
||||
#define SET_TX_DESC_AGG_BREAK(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+4, 5, 1, __val)
|
||||
#define SET_TX_DESC_BK(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+4, 6, 1, __val)
|
||||
#define SET_TX_DESC_RDG_ENABLE(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+4, 7, 1, __val)
|
||||
#define SET_TX_DESC_QUEUE_SEL(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+4, 8, 5, __val)
|
||||
#define SET_TX_DESC_RDG_NAV_EXT(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+4, 13, 1, __val)
|
||||
#define SET_TX_DESC_LSIG_TXOP_EN(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+4, 14, 1, __val)
|
||||
#define SET_TX_DESC_PIFS(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+4, 15, 1, __val)
|
||||
#define SET_TX_DESC_RATE_ID(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+4, 16, 4, __val)
|
||||
#define SET_TX_DESC_NAV_USE_HDR(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+4, 20, 1, __val)
|
||||
#define SET_TX_DESC_EN_DESC_ID(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+4, 21, 1, __val)
|
||||
#define SET_TX_DESC_SEC_TYPE(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+4, 22, 2, __val)
|
||||
#define SET_TX_DESC_PKT_OFFSET(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+4, 24, 8, __val)
|
||||
|
||||
#define GET_TX_DESC_MACID(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+4, 0, 5)
|
||||
#define GET_TX_DESC_AGG_ENABLE(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+4, 5, 1)
|
||||
#define GET_TX_DESC_AGG_BREAK(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+4, 6, 1)
|
||||
#define GET_TX_DESC_RDG_ENABLE(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+4, 7, 1)
|
||||
#define GET_TX_DESC_QUEUE_SEL(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+4, 8, 5)
|
||||
#define GET_TX_DESC_RDG_NAV_EXT(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+4, 13, 1)
|
||||
#define GET_TX_DESC_LSIG_TXOP_EN(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+4, 14, 1)
|
||||
#define GET_TX_DESC_PIFS(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+4, 15, 1)
|
||||
#define GET_TX_DESC_RATE_ID(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+4, 16, 4)
|
||||
#define GET_TX_DESC_NAV_USE_HDR(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+4, 20, 1)
|
||||
#define GET_TX_DESC_EN_DESC_ID(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+4, 21, 1)
|
||||
#define GET_TX_DESC_SEC_TYPE(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+4, 22, 2)
|
||||
#define GET_TX_DESC_PKT_OFFSET(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+4, 24, 8)
|
||||
|
||||
#define SET_TX_DESC_RTS_RC(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+8, 0, 6, __val)
|
||||
#define SET_TX_DESC_DATA_RC(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+8, 6, 6, __val)
|
||||
#define SET_TX_DESC_BAR_RTY_TH(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+8, 14, 2, __val)
|
||||
#define SET_TX_DESC_MORE_FRAG(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+8, 17, 1, __val)
|
||||
#define SET_TX_DESC_RAW(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+8, 18, 1, __val)
|
||||
#define SET_TX_DESC_CCX(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+8, 19, 1, __val)
|
||||
#define SET_TX_DESC_AMPDU_DENSITY(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+8, 20, 3, __val)
|
||||
#define SET_TX_DESC_ANTSEL_A(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+8, 24, 1, __val)
|
||||
#define SET_TX_DESC_ANTSEL_B(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+8, 25, 1, __val)
|
||||
#define SET_TX_DESC_TX_ANT_CCK(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+8, 26, 2, __val)
|
||||
#define SET_TX_DESC_TX_ANTL(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+8, 28, 2, __val)
|
||||
#define SET_TX_DESC_TX_ANT_HT(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+8, 30, 2, __val)
|
||||
|
||||
#define GET_TX_DESC_RTS_RC(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+8, 0, 6)
|
||||
#define GET_TX_DESC_DATA_RC(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+8, 6, 6)
|
||||
#define GET_TX_DESC_BAR_RTY_TH(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+8, 14, 2)
|
||||
#define GET_TX_DESC_MORE_FRAG(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+8, 17, 1)
|
||||
#define GET_TX_DESC_RAW(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+8, 18, 1)
|
||||
#define GET_TX_DESC_CCX(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+8, 19, 1)
|
||||
#define GET_TX_DESC_AMPDU_DENSITY(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+8, 20, 3)
|
||||
#define GET_TX_DESC_ANTSEL_A(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+8, 24, 1)
|
||||
#define GET_TX_DESC_ANTSEL_B(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+8, 25, 1)
|
||||
#define GET_TX_DESC_TX_ANT_CCK(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+8, 26, 2)
|
||||
#define GET_TX_DESC_TX_ANTL(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+8, 28, 2)
|
||||
#define GET_TX_DESC_TX_ANT_HT(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+8, 30, 2)
|
||||
|
||||
#define SET_TX_DESC_NEXT_HEAP_PAGE(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+12, 0, 8, __val)
|
||||
#define SET_TX_DESC_TAIL_PAGE(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+12, 8, 8, __val)
|
||||
#define SET_TX_DESC_SEQ(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+12, 16, 12, __val)
|
||||
#define SET_TX_DESC_PKT_ID(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+12, 28, 4, __val)
|
||||
|
||||
#define GET_TX_DESC_NEXT_HEAP_PAGE(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+12, 0, 8)
|
||||
#define GET_TX_DESC_TAIL_PAGE(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+12, 8, 8)
|
||||
#define GET_TX_DESC_SEQ(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+12, 16, 12)
|
||||
#define GET_TX_DESC_PKT_ID(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+12, 28, 4)
|
||||
|
||||
#define SET_TX_DESC_RTS_RATE(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+16, 0, 5, __val)
|
||||
#define SET_TX_DESC_AP_DCFE(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+16, 5, 1, __val)
|
||||
#define SET_TX_DESC_QOS(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+16, 6, 1, __val)
|
||||
#define SET_TX_DESC_HWSEQ_EN(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+16, 7, 1, __val)
|
||||
#define SET_TX_DESC_USE_RATE(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+16, 8, 1, __val)
|
||||
#define SET_TX_DESC_DISABLE_RTS_FB(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+16, 9, 1, __val)
|
||||
#define SET_TX_DESC_DISABLE_FB(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+16, 10, 1, __val)
|
||||
#define SET_TX_DESC_CTS2SELF(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+16, 11, 1, __val)
|
||||
#define SET_TX_DESC_RTS_ENABLE(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+16, 12, 1, __val)
|
||||
#define SET_TX_DESC_HW_RTS_ENABLE(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+16, 13, 1, __val)
|
||||
#define SET_TX_DESC_PORT_ID(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+16, 14, 1, __val)
|
||||
#define SET_TX_DESC_WAIT_DCTS(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+16, 18, 1, __val)
|
||||
#define SET_TX_DESC_CTS2AP_EN(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+16, 19, 1, __val)
|
||||
#define SET_TX_DESC_TX_SUB_CARRIER(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+16, 20, 2, __val)
|
||||
#define SET_TX_DESC_TX_STBC(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+16, 22, 2, __val)
|
||||
#define SET_TX_DESC_DATA_SHORT(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+16, 24, 1, __val)
|
||||
#define SET_TX_DESC_DATA_BW(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+16, 25, 1, __val)
|
||||
#define SET_TX_DESC_RTS_SHORT(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+16, 26, 1, __val)
|
||||
#define SET_TX_DESC_RTS_BW(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+16, 27, 1, __val)
|
||||
#define SET_TX_DESC_RTS_SC(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+16, 28, 2, __val)
|
||||
#define SET_TX_DESC_RTS_STBC(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+16, 30, 2, __val)
|
||||
|
||||
#define GET_TX_DESC_RTS_RATE(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+16, 0, 5)
|
||||
#define GET_TX_DESC_AP_DCFE(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+16, 5, 1)
|
||||
#define GET_TX_DESC_QOS(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+16, 6, 1)
|
||||
#define GET_TX_DESC_HWSEQ_EN(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+16, 7, 1)
|
||||
#define GET_TX_DESC_USE_RATE(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+16, 8, 1)
|
||||
#define GET_TX_DESC_DISABLE_RTS_FB(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+16, 9, 1)
|
||||
#define GET_TX_DESC_DISABLE_FB(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+16, 10, 1)
|
||||
#define GET_TX_DESC_CTS2SELF(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+16, 11, 1)
|
||||
#define GET_TX_DESC_RTS_ENABLE(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+16, 12, 1)
|
||||
#define GET_TX_DESC_HW_RTS_ENABLE(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+16, 13, 1)
|
||||
#define GET_TX_DESC_PORT_ID(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+16, 14, 1)
|
||||
#define GET_TX_DESC_WAIT_DCTS(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+16, 18, 1)
|
||||
#define GET_TX_DESC_CTS2AP_EN(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+16, 19, 1)
|
||||
#define GET_TX_DESC_TX_SUB_CARRIER(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+16, 20, 2)
|
||||
#define GET_TX_DESC_TX_STBC(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+16, 22, 2)
|
||||
#define GET_TX_DESC_DATA_SHORT(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+16, 24, 1)
|
||||
#define GET_TX_DESC_DATA_BW(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+16, 25, 1)
|
||||
#define GET_TX_DESC_RTS_SHORT(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+16, 26, 1)
|
||||
#define GET_TX_DESC_RTS_BW(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+16, 27, 1)
|
||||
#define GET_TX_DESC_RTS_SC(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+16, 28, 2)
|
||||
#define GET_TX_DESC_RTS_STBC(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+16, 30, 2)
|
||||
|
||||
#define SET_TX_DESC_TX_RATE(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+20, 0, 6, __val)
|
||||
#define SET_TX_DESC_DATA_SHORTGI(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+20, 6, 1, __val)
|
||||
#define SET_TX_DESC_CCX_TAG(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+20, 7, 1, __val)
|
||||
#define SET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+20, 8, 5, __val)
|
||||
#define SET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+20, 13, 4, __val)
|
||||
#define SET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+20, 17, 1, __val)
|
||||
#define SET_TX_DESC_DATA_RETRY_LIMIT(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+20, 18, 6, __val)
|
||||
#define SET_TX_DESC_USB_TXAGG_NUM(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+20, 24, 8, __val)
|
||||
|
||||
#define GET_TX_DESC_TX_RATE(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+20, 0, 6)
|
||||
#define GET_TX_DESC_DATA_SHORTGI(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+20, 6, 1)
|
||||
#define GET_TX_DESC_CCX_TAG(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+20, 7, 1)
|
||||
#define GET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+20, 8, 5)
|
||||
#define GET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+20, 13, 4)
|
||||
#define GET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+20, 17, 1)
|
||||
#define GET_TX_DESC_DATA_RETRY_LIMIT(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+20, 18, 6)
|
||||
#define GET_TX_DESC_USB_TXAGG_NUM(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+20, 24, 8)
|
||||
|
||||
#define SET_TX_DESC_TXAGC_A(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+24, 0, 5, __val)
|
||||
#define SET_TX_DESC_TXAGC_B(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+24, 5, 5, __val)
|
||||
#define SET_TX_DESC_USE_MAX_LEN(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+24, 10, 1, __val)
|
||||
#define SET_TX_DESC_MAX_AGG_NUM(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+24, 11, 5, __val)
|
||||
#define SET_TX_DESC_MCSG1_MAX_LEN(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+24, 16, 4, __val)
|
||||
#define SET_TX_DESC_MCSG2_MAX_LEN(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+24, 20, 4, __val)
|
||||
#define SET_TX_DESC_MCSG3_MAX_LEN(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+24, 24, 4, __val)
|
||||
#define SET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+24, 28, 4, __val)
|
||||
|
||||
#define GET_TX_DESC_TXAGC_A(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+24, 0, 5)
|
||||
#define GET_TX_DESC_TXAGC_B(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+24, 5, 5)
|
||||
#define GET_TX_DESC_USE_MAX_LEN(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+24, 10, 1)
|
||||
#define GET_TX_DESC_MAX_AGG_NUM(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+24, 11, 5)
|
||||
#define GET_TX_DESC_MCSG1_MAX_LEN(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+24, 16, 4)
|
||||
#define GET_TX_DESC_MCSG2_MAX_LEN(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+24, 20, 4)
|
||||
#define GET_TX_DESC_MCSG3_MAX_LEN(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+24, 24, 4)
|
||||
#define GET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+24, 28, 4)
|
||||
|
||||
#define SET_TX_DESC_TX_BUFFER_SIZE(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 16, __val)
|
||||
#define SET_TX_DESC_MCSG4_MAX_LEN(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+28, 16, 4, __val)
|
||||
#define SET_TX_DESC_MCSG5_MAX_LEN(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+28, 20, 4, __val)
|
||||
#define SET_TX_DESC_MCSG6_MAX_LEN(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+28, 24, 4, __val)
|
||||
#define SET_TX_DESC_MCS15_SGI_MAX_LEN(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+28, 28, 4, __val)
|
||||
|
||||
#define GET_TX_DESC_TX_BUFFER_SIZE(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+28, 0, 16)
|
||||
#define GET_TX_DESC_MCSG4_MAX_LEN(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+28, 16, 4)
|
||||
#define GET_TX_DESC_MCSG5_MAX_LEN(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+28, 20, 4)
|
||||
#define GET_TX_DESC_MCSG6_MAX_LEN(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+28, 24, 4)
|
||||
#define GET_TX_DESC_MCS15_SGI_MAX_LEN(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+28, 28, 4)
|
||||
|
||||
#define SET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+32, 0, 32, __val)
|
||||
#define SET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+36, 0, 32, __val)
|
||||
|
||||
#define GET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+32, 0, 32)
|
||||
#define GET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+36, 0, 32)
|
||||
|
||||
#define SET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+40, 0, 32, __val)
|
||||
#define SET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+44, 0, 32, __val)
|
||||
|
||||
#define GET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+40, 0, 32)
|
||||
#define GET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+44, 0, 32)
|
||||
|
||||
#define GET_RX_DESC_PKT_LEN(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc, 0, 14)
|
||||
#define GET_RX_DESC_CRC32(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc, 14, 1)
|
||||
#define GET_RX_DESC_ICV(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc, 15, 1)
|
||||
#define GET_RX_DESC_DRV_INFO_SIZE(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc, 16, 4)
|
||||
#define GET_RX_DESC_SECURITY(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc, 20, 3)
|
||||
#define GET_RX_DESC_QOS(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc, 23, 1)
|
||||
#define GET_RX_DESC_SHIFT(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc, 24, 2)
|
||||
#define GET_RX_DESC_PHYST(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc, 26, 1)
|
||||
#define GET_RX_DESC_SWDEC(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc, 27, 1)
|
||||
#define GET_RX_DESC_LS(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc, 28, 1)
|
||||
#define GET_RX_DESC_FS(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc, 29, 1)
|
||||
#define GET_RX_DESC_EOR(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc, 30, 1)
|
||||
#define GET_RX_DESC_OWN(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc, 31, 1)
|
||||
|
||||
#define SET_RX_DESC_PKT_LEN(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc, 0, 14, __val)
|
||||
#define SET_RX_DESC_EOR(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val)
|
||||
#define SET_RX_DESC_OWN(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val)
|
||||
|
||||
#define GET_RX_DESC_MACID(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+4, 0, 5)
|
||||
#define GET_RX_DESC_TID(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+4, 5, 4)
|
||||
#define GET_RX_DESC_HWRSVD(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+4, 9, 5)
|
||||
#define GET_RX_DESC_PAGGR(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+4, 14, 1)
|
||||
#define GET_RX_DESC_FAGGR(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+4, 15, 1)
|
||||
#define GET_RX_DESC_A1_FIT(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+4, 16, 4)
|
||||
#define GET_RX_DESC_A2_FIT(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+4, 20, 4)
|
||||
#define GET_RX_DESC_PAM(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+4, 24, 1)
|
||||
#define GET_RX_DESC_PWR(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+4, 25, 1)
|
||||
#define GET_RX_DESC_MD(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+4, 26, 1)
|
||||
#define GET_RX_DESC_MF(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+4, 27, 1)
|
||||
#define GET_RX_DESC_TYPE(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+4, 28, 2)
|
||||
#define GET_RX_DESC_MC(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+4, 30, 1)
|
||||
#define GET_RX_DESC_BC(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+4, 31, 1)
|
||||
#define GET_RX_DESC_SEQ(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+8, 0, 12)
|
||||
#define GET_RX_DESC_FRAG(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+8, 12, 4)
|
||||
#define GET_RX_DESC_NEXT_PKT_LEN(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+8, 16, 14)
|
||||
#define GET_RX_DESC_NEXT_IND(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+8, 30, 1)
|
||||
#define GET_RX_DESC_RSVD(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+8, 31, 1)
|
||||
|
||||
#define GET_RX_DESC_RXMCS(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+12, 0, 6)
|
||||
#define GET_RX_DESC_RXHT(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+12, 6, 1)
|
||||
#define GET_RX_DESC_SPLCP(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+12, 8, 1)
|
||||
#define GET_RX_DESC_BW(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+12, 9, 1)
|
||||
#define GET_RX_DESC_HTC(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+12, 10, 1)
|
||||
#define GET_RX_DESC_HWPC_ERR(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+12, 14, 1)
|
||||
#define GET_RX_DESC_HWPC_IND(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+12, 15, 1)
|
||||
#define GET_RX_DESC_IV0(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+12, 16, 16)
|
||||
|
||||
#define GET_RX_DESC_IV1(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+16, 0, 32)
|
||||
#define GET_RX_DESC_TSFL(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+20, 0, 32)
|
||||
|
||||
#define GET_RX_DESC_BUFF_ADDR(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+24, 0, 32)
|
||||
#define GET_RX_DESC_BUFF_ADDR64(__pdesc) \
|
||||
LE_BITS_TO_4BYTE(__pdesc+28, 0, 32)
|
||||
|
||||
#define SET_RX_DESC_BUFF_ADDR(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+24, 0, 32, __val)
|
||||
#define SET_RX_DESC_BUFF_ADDR64(__pdesc, __val) \
|
||||
SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 32, __val)
|
||||
|
||||
#define CLEAR_PCI_TX_DESC_CONTENT(__pdesc, _size) \
|
||||
do { \
|
||||
if (_size > TX_DESC_NEXT_DESC_OFFSET) \
|
||||
memset((void *)__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET); \
|
||||
else \
|
||||
memset((void *)__pdesc, 0, _size); \
|
||||
} while (0);
|
||||
|
||||
#define RX_HAL_IS_CCK_RATE(_pdesc)\
|
||||
(_pdesc->rxmcs == DESC92C_RATE1M || \
|
||||
_pdesc->rxmcs == DESC92C_RATE2M || \
|
||||
_pdesc->rxmcs == DESC92C_RATE5_5M || \
|
||||
_pdesc->rxmcs == DESC92C_RATE11M)
|
||||
|
||||
struct rx_fwinfo_92c {
|
||||
u8 gain_trsw[4];
|
||||
u8 pwdb_all;
|
||||
u8 cfosho[4];
|
||||
u8 cfotail[4];
|
||||
char rxevm[2];
|
||||
char rxsnr[4];
|
||||
u8 pdsnr[2];
|
||||
u8 csi_current[2];
|
||||
u8 csi_target[2];
|
||||
u8 sigevm;
|
||||
u8 max_ex_pwr;
|
||||
u8 ex_intf_flag:1;
|
||||
u8 sgi_en:1;
|
||||
u8 rxsc:2;
|
||||
u8 reserve:4;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct tx_desc_92c {
|
||||
u32 pktsize:16;
|
||||
u32 offset:8;
|
||||
u32 bmc:1;
|
||||
u32 htc:1;
|
||||
u32 lastseg:1;
|
||||
u32 firstseg:1;
|
||||
u32 linip:1;
|
||||
u32 noacm:1;
|
||||
u32 gf:1;
|
||||
u32 own:1;
|
||||
|
||||
u32 macid:5;
|
||||
u32 agg_en:1;
|
||||
u32 bk:1;
|
||||
u32 rdg_en:1;
|
||||
u32 queuesel:5;
|
||||
u32 rd_nav_ext:1;
|
||||
u32 lsig_txop_en:1;
|
||||
u32 pifs:1;
|
||||
u32 rateid:4;
|
||||
u32 nav_usehdr:1;
|
||||
u32 en_descid:1;
|
||||
u32 sectype:2;
|
||||
u32 pktoffset:8;
|
||||
|
||||
u32 rts_rc:6;
|
||||
u32 data_rc:6;
|
||||
u32 rsvd0:2;
|
||||
u32 bar_retryht:2;
|
||||
u32 rsvd1:1;
|
||||
u32 morefrag:1;
|
||||
u32 raw:1;
|
||||
u32 ccx:1;
|
||||
u32 ampdudensity:3;
|
||||
u32 rsvd2:1;
|
||||
u32 ant_sela:1;
|
||||
u32 ant_selb:1;
|
||||
u32 txant_cck:2;
|
||||
u32 txant_l:2;
|
||||
u32 txant_ht:2;
|
||||
|
||||
u32 nextheadpage:8;
|
||||
u32 tailpage:8;
|
||||
u32 seq:12;
|
||||
u32 pktid:4;
|
||||
|
||||
u32 rtsrate:5;
|
||||
u32 apdcfe:1;
|
||||
u32 qos:1;
|
||||
u32 hwseq_enable:1;
|
||||
u32 userrate:1;
|
||||
u32 dis_rtsfb:1;
|
||||
u32 dis_datafb:1;
|
||||
u32 cts2self:1;
|
||||
u32 rts_en:1;
|
||||
u32 hwrts_en:1;
|
||||
u32 portid:1;
|
||||
u32 rsvd3:3;
|
||||
u32 waitdcts:1;
|
||||
u32 cts2ap_en:1;
|
||||
u32 txsc:2;
|
||||
u32 stbc:2;
|
||||
u32 txshort:1;
|
||||
u32 txbw:1;
|
||||
u32 rtsshort:1;
|
||||
u32 rtsbw:1;
|
||||
u32 rtssc:2;
|
||||
u32 rtsstbc:2;
|
||||
|
||||
u32 txrate:6;
|
||||
u32 shortgi:1;
|
||||
u32 ccxt:1;
|
||||
u32 txrate_fb_lmt:5;
|
||||
u32 rtsrate_fb_lmt:4;
|
||||
u32 retrylmt_en:1;
|
||||
u32 txretrylmt:6;
|
||||
u32 usb_txaggnum:8;
|
||||
|
||||
u32 txagca:5;
|
||||
u32 txagcb:5;
|
||||
u32 usemaxlen:1;
|
||||
u32 maxaggnum:5;
|
||||
u32 mcsg1maxlen:4;
|
||||
u32 mcsg2maxlen:4;
|
||||
u32 mcsg3maxlen:4;
|
||||
u32 mcs7sgimaxlen:4;
|
||||
|
||||
u32 txbuffersize:16;
|
||||
u32 mcsg4maxlen:4;
|
||||
u32 mcsg5maxlen:4;
|
||||
u32 mcsg6maxlen:4;
|
||||
u32 mcsg15sgimaxlen:4;
|
||||
|
||||
u32 txbuffaddr;
|
||||
u32 txbufferaddr64;
|
||||
u32 nextdescaddress;
|
||||
u32 nextdescaddress64;
|
||||
|
||||
u32 reserve_pass_pcie_mm_limit[4];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct rx_desc_92c {
|
||||
u32 length:14;
|
||||
u32 crc32:1;
|
||||
u32 icverror:1;
|
||||
u32 drv_infosize:4;
|
||||
u32 security:3;
|
||||
u32 qos:1;
|
||||
u32 shift:2;
|
||||
u32 phystatus:1;
|
||||
u32 swdec:1;
|
||||
u32 lastseg:1;
|
||||
u32 firstseg:1;
|
||||
u32 eor:1;
|
||||
u32 own:1;
|
||||
|
||||
u32 macid:5;
|
||||
u32 tid:4;
|
||||
u32 hwrsvd:5;
|
||||
u32 paggr:1;
|
||||
u32 faggr:1;
|
||||
u32 a1_fit:4;
|
||||
u32 a2_fit:4;
|
||||
u32 pam:1;
|
||||
u32 pwr:1;
|
||||
u32 moredata:1;
|
||||
u32 morefrag:1;
|
||||
u32 type:2;
|
||||
u32 mc:1;
|
||||
u32 bc:1;
|
||||
|
||||
u32 seq:12;
|
||||
u32 frag:4;
|
||||
u32 nextpktlen:14;
|
||||
u32 nextind:1;
|
||||
u32 rsvd:1;
|
||||
|
||||
u32 rxmcs:6;
|
||||
u32 rxht:1;
|
||||
u32 amsdu:1;
|
||||
u32 splcp:1;
|
||||
u32 bandwidth:1;
|
||||
u32 htc:1;
|
||||
u32 tcpchk_rpt:1;
|
||||
u32 ipcchk_rpt:1;
|
||||
u32 tcpchk_valid:1;
|
||||
u32 hwpcerr:1;
|
||||
u32 hwpcind:1;
|
||||
u32 iv0:16;
|
||||
|
||||
u32 iv1;
|
||||
|
||||
u32 tsfl;
|
||||
|
||||
u32 bufferaddress;
|
||||
u32 bufferaddress64;
|
||||
|
||||
} __attribute__ ((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);
|
||||
bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,
|
||||
struct rtl_stats *stats,
|
||||
struct ieee80211_rx_status *rx_status,
|
||||
u8 *pdesc, struct sk_buff *skb);
|
||||
void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val);
|
||||
u32 rtl92ce_get_desc(u8 *pdesc, bool istx, u8 desc_name);
|
||||
void rtl92ce_tx_polling(struct ieee80211_hw *hw, unsigned int hw_queue);
|
||||
void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
|
||||
bool b_firstseg, bool b_lastseg,
|
||||
struct sk_buff *skb);
|
||||
#endif
|
1532
drivers/net/wireless/rtlwifi/wifi.h
Normal file
1532
drivers/net/wireless/rtlwifi/wifi.h
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user