mirror of
https://github.com/Dasharo/linux.git
synced 2026-03-06 15:25:10 -08: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:
committed by
John W. Linville
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
File diff suppressed because it is too large
Load Diff
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
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user