M7350v1_en_gpl

This commit is contained in:
T
2024-09-09 08:52:07 +00:00
commit f9cc65cfda
65988 changed files with 26357421 additions and 0 deletions

View File

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

View File

@ -0,0 +1,58 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "../rtl8192ce/def.h"
/*-------------------------------------------------------------------------
* Chip specific
*-------------------------------------------------------------------------*/
#define CHIP_8723 BIT(2) /* RTL8723 With BT feature */
#define CHIP_8723_DRV_REV BIT(3) /* RTL8723 Driver Revised */
#define NORMAL_CHIP BIT(4)
#define CHIP_VENDOR_UMC BIT(5)
#define CHIP_VENDOR_UMC_B_CUT BIT(6)
#define IS_NORMAL_CHIP(version) \
(((version) & NORMAL_CHIP) ? true : false)
#define IS_8723_SERIES(version) \
(((version) & CHIP_8723) ? true : false)
#define IS_92C_1T2R(version) \
(((version) & CHIP_92C) && ((version) & CHIP_92C_1T2R))
#define IS_VENDOR_UMC(version) \
(((version) & CHIP_VENDOR_UMC) ? true : false)
#define IS_VENDOR_8723_A_CUT(version) \
(((version) & CHIP_VENDOR_UMC) ? (((version) & (BIT(6))) ? \
false : true) : false)
#define CHIP_BONDING_92C_1T2R 0x1
#define CHIP_BONDING_IDENTIFIER(_value) (((_value) >> 22) & 0x3)

View File

@ -0,0 +1,113 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "../wifi.h"
#include "../base.h"
#include "reg.h"
#include "def.h"
#include "phy.h"
#include "dm.h"
void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
long undecorated_smoothed_pwdb;
if (!rtlpriv->dm.dynamic_txpower_enable)
return;
if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) {
rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
return;
}
if ((mac->link_state < MAC80211_LINKED) &&
(rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) {
RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
"Not connected to any\n");
rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
return;
}
if (mac->link_state >= MAC80211_LINKED) {
if (mac->opmode == NL80211_IFTYPE_ADHOC) {
undecorated_smoothed_pwdb =
rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
"AP Client PWDB = 0x%lx\n",
undecorated_smoothed_pwdb);
} else {
undecorated_smoothed_pwdb =
rtlpriv->dm.undecorated_smoothed_pwdb;
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
"STA Default Port PWDB = 0x%lx\n",
undecorated_smoothed_pwdb);
}
} else {
undecorated_smoothed_pwdb =
rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
"AP Ext Port PWDB = 0x%lx\n",
undecorated_smoothed_pwdb);
}
if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) {
rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
"TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n");
} else if ((undecorated_smoothed_pwdb <
(TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) &&
(undecorated_smoothed_pwdb >=
TX_POWER_NEAR_FIELD_THRESH_LVL1)) {
rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
"TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n");
} else if (undecorated_smoothed_pwdb <
(TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) {
rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
"TXHIGHPWRLEVEL_NORMAL\n");
}
if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) {
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
"PHY_SetTxPowerLevel8192S() Channel = %d\n",
rtlphy->current_channel);
rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel);
}
rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
}

View File

@ -0,0 +1,32 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "../rtl8192ce/dm.h"
void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw);

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -0,0 +1,141 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
*****************************************************************************/
#include "../wifi.h"
#include "../usb.h"
#include "reg.h"
#include "led.h"
static void _rtl92cu_init_led(struct ieee80211_hw *hw,
struct rtl_led *pled, enum rtl_led_pin ledpin)
{
pled->hw = hw;
pled->ledpin = ledpin;
pled->ledon = false;
}
static void _rtl92cu_deInit_led(struct rtl_led *pled)
{
}
void rtl92cu_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
{
u8 ledcfg;
struct rtl_priv *rtlpriv = rtl_priv(hw);
RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n",
REG_LEDCFG2, pled->ledpin);
ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
switch (pled->ledpin) {
case LED_PIN_GPIO0:
break;
case LED_PIN_LED0:
rtl_write_byte(rtlpriv,
REG_LEDCFG2, (ledcfg & 0xf0) | BIT(5) | BIT(6));
break;
case LED_PIN_LED1:
rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0x0f) | BIT(5));
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"switch case not processed\n");
break;
}
pled->ledon = true;
}
void rtl92cu_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_usb_priv *usbpriv = rtl_usbpriv(hw);
u8 ledcfg;
RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n",
REG_LEDCFG2, pled->ledpin);
ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
switch (pled->ledpin) {
case LED_PIN_GPIO0:
break;
case LED_PIN_LED0:
ledcfg &= 0xf0;
if (usbpriv->ledctl.led_opendrain)
rtl_write_byte(rtlpriv, REG_LEDCFG2,
(ledcfg | BIT(1) | BIT(5) | BIT(6)));
else
rtl_write_byte(rtlpriv, REG_LEDCFG2,
(ledcfg | BIT(3) | BIT(5) | BIT(6)));
break;
case LED_PIN_LED1:
ledcfg &= 0x0f;
rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg | BIT(3)));
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"switch case not processed\n");
break;
}
pled->ledon = false;
}
void rtl92cu_init_sw_leds(struct ieee80211_hw *hw)
{
struct rtl_usb_priv *usbpriv = rtl_usbpriv(hw);
_rtl92cu_init_led(hw, &(usbpriv->ledctl.sw_led0), LED_PIN_LED0);
_rtl92cu_init_led(hw, &(usbpriv->ledctl.sw_led1), LED_PIN_LED1);
}
void rtl92cu_deinit_sw_leds(struct ieee80211_hw *hw)
{
struct rtl_usb_priv *usbpriv = rtl_usbpriv(hw);
_rtl92cu_deInit_led(&(usbpriv->ledctl.sw_led0));
_rtl92cu_deInit_led(&(usbpriv->ledctl.sw_led1));
}
static void _rtl92cu_sw_led_control(struct ieee80211_hw *hw,
enum led_ctl_mode ledaction)
{
}
void rtl92cu_led_control(struct ieee80211_hw *hw,
enum led_ctl_mode ledaction)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) &&
(ledaction == LED_CTL_TX ||
ledaction == LED_CTL_RX ||
ledaction == LED_CTL_SITE_SURVEY ||
ledaction == LED_CTL_LINK ||
ledaction == LED_CTL_NO_LINK ||
ledaction == LED_CTL_START_TO_LINK ||
ledaction == LED_CTL_POWER_ON)) {
return;
}
RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d\n", ledaction);
_rtl92cu_sw_led_control(hw, ledaction);
}

View File

@ -0,0 +1,37 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
*****************************************************************************/
#ifndef __RTL92CU_LED_H__
#define __RTL92CU_LED_H__
void rtl92cu_init_sw_leds(struct ieee80211_hw *hw);
void rtl92cu_deinit_sw_leds(struct ieee80211_hw *hw);
void rtl92cu_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled);
void rtl92cu_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled);
void rtl92cu_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,174 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __RTL92C_MAC_H__
#define __RTL92C_MAC_H__
#define LLT_LAST_ENTRY_OF_TX_PKT_BUFFER 255
#define DRIVER_EARLY_INT_TIME 0x05
#define BCN_DMA_ATIME_INT_TIME 0x02
void rtl92c_read_chip_version(struct ieee80211_hw *hw);
bool rtl92c_llt_write(struct ieee80211_hw *hw, u32 address, u32 data);
bool rtl92c_init_llt_table(struct ieee80211_hw *hw, u32 boundary);
void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index,
u8 *p_macaddr, bool is_group, u8 enc_algo,
bool is_wepkey, bool clear_all);
void rtl92c_enable_interrupt(struct ieee80211_hw *hw);
void rtl92c_disable_interrupt(struct ieee80211_hw *hw);
void rtl92c_set_qos(struct ieee80211_hw *hw, int aci);
/*---------------------------------------------------------------
* Hardware init functions
*---------------------------------------------------------------*/
void rtl92c_set_mac_addr(struct ieee80211_hw *hw, const u8 *addr);
void rtl92c_init_interrupt(struct ieee80211_hw *hw);
void rtl92c_init_driver_info_size(struct ieee80211_hw *hw, u8 size);
int rtl92c_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type);
void rtl92c_init_network_type(struct ieee80211_hw *hw);
void rtl92c_init_adaptive_ctrl(struct ieee80211_hw *hw);
void rtl92c_init_rate_fallback(struct ieee80211_hw *hw);
void rtl92c_init_edca_param(struct ieee80211_hw *hw,
u16 queue,
u16 txop,
u8 ecwmax,
u8 ecwmin,
u8 aifs);
void rtl92c_init_edca(struct ieee80211_hw *hw);
void rtl92c_init_ampdu_aggregation(struct ieee80211_hw *hw);
void rtl92c_init_beacon_max_error(struct ieee80211_hw *hw, bool infra_mode);
void rtl92c_init_rdg_setting(struct ieee80211_hw *hw);
void rtl92c_init_retry_function(struct ieee80211_hw *hw);
void rtl92c_init_beacon_parameters(struct ieee80211_hw *hw,
enum version_8192c version);
void rtl92c_disable_fast_edca(struct ieee80211_hw *hw);
void rtl92c_set_min_space(struct ieee80211_hw *hw, bool is2T);
/* For filter */
u16 rtl92c_get_mgt_filter(struct ieee80211_hw *hw);
void rtl92c_set_mgt_filter(struct ieee80211_hw *hw, u16 filter);
u16 rtl92c_get_ctrl_filter(struct ieee80211_hw *hw);
void rtl92c_set_ctrl_filter(struct ieee80211_hw *hw, u16 filter);
u16 rtl92c_get_data_filter(struct ieee80211_hw *hw);
void rtl92c_set_data_filter(struct ieee80211_hw *hw, u16 filter);
u32 rtl92c_get_txdma_status(struct ieee80211_hw *hw);
struct rx_fwinfo_92c {
u8 gain_trsw[4];
u8 pwdb_all;
u8 cfosho[4];
u8 cfotail[4];
char rxevm[2];
char rxsnr[4];
u8 pdsnr[2];
u8 csi_current[2];
u8 csi_target[2];
u8 sigevm;
u8 max_ex_pwr;
u8 ex_intf_flag:1;
u8 sgi_en:1;
u8 rxsc:2;
u8 reserve:4;
} __packed;
struct rx_desc_92c {
u32 length:14;
u32 crc32:1;
u32 icverror:1;
u32 drv_infosize:4;
u32 security:3;
u32 qos:1;
u32 shift:2;
u32 phystatus:1;
u32 swdec:1;
u32 lastseg:1;
u32 firstseg:1;
u32 eor:1;
u32 own:1;
u32 macid:5; /* word 1 */
u32 tid:4;
u32 hwrsvd:5;
u32 paggr:1;
u32 faggr:1;
u32 a1_fit:4;
u32 a2_fit:4;
u32 pam:1;
u32 pwr:1;
u32 moredata:1;
u32 morefrag:1;
u32 type:2;
u32 mc:1;
u32 bc:1;
u32 seq:12; /* word 2 */
u32 frag:4;
u32 nextpktlen:14;
u32 nextind:1;
u32 rsvd:1;
u32 rxmcs:6; /* word 3 */
u32 rxht:1;
u32 amsdu:1;
u32 splcp:1;
u32 bandwidth:1;
u32 htc:1;
u32 tcpchk_rpt:1;
u32 ipcchk_rpt:1;
u32 tcpchk_valid:1;
u32 hwpcerr:1;
u32 hwpcind:1;
u32 iv0:16;
u32 iv1; /* word 4 */
u32 tsfl; /* word 5 */
u32 bufferaddress; /* word 6 */
u32 bufferaddress64; /* word 7 */
} __packed;
enum rtl_desc_qsel rtl92c_map_hwqueue_to_fwqueue(u16 fc,
unsigned int
skb_queue);
void rtl92c_translate_rx_signal_stuff(struct ieee80211_hw *hw,
struct sk_buff *skb,
struct rtl_stats *pstats,
struct rx_desc_92c *pdesc,
struct rx_fwinfo_92c *p_drvinfo);
/*---------------------------------------------------------------
* Card disable functions
*---------------------------------------------------------------*/
#endif

View File

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

View File

@ -0,0 +1,50 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "../rtl8192ce/phy.h"
void rtl92cu_bb_block_on(struct ieee80211_hw *hw);
bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, u32 rfpath);
void rtl92c_phy_set_io(struct ieee80211_hw *hw);
bool _rtl92cu_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);
bool rtl92cu_phy_bb_config(struct ieee80211_hw *hw);
u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw,
enum radio_path rfpath, u32 regaddr, u32 bitmask);
void rtl92cu_phy_set_rf_reg(struct ieee80211_hw *hw,
enum radio_path rfpath,
u32 regaddr, u32 bitmask, u32 data);
bool rtl92cu_phy_mac_config(struct ieee80211_hw *hw);
bool _rtl92cu_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
u8 configtype);
void _rtl92cu_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t);
bool _rtl92cu_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
u8 configtype);
void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw);
bool rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw,
enum rf_pwrstate rfpwr_state);

View File

@ -0,0 +1,30 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "../rtl8192ce/reg.h"

View File

@ -0,0 +1,492 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "../wifi.h"
#include "reg.h"
#include "def.h"
#include "phy.h"
#include "rf.h"
#include "dm.h"
static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw);
void rtl92cu_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 rtl92cu_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_hal *rtlhal = rtl_hal(rtlpriv);
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 = 0;
bool turbo_scanoff = false;
u8 idx1, idx2;
u8 *ptr;
if (rtlhal->interface == INTF_PCI) {
if (rtlefuse->eeprom_regulatory != 0)
turbo_scanoff = true;
} else {
if ((rtlefuse->eeprom_regulatory != 0) ||
(rtlefuse->external_pa))
turbo_scanoff = true;
}
if (mac->act_scanning) {
tx_agc[RF90_PATH_A] = 0x3f3f3f3f;
tx_agc[RF90_PATH_B] = 0x3f3f3f3f;
if (turbo_scanoff) {
for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
tx_agc[idx1] = ppowerlevel[idx1] |
(ppowerlevel[idx1] << 8) |
(ppowerlevel[idx1] << 16) |
(ppowerlevel[idx1] << 24);
if (rtlhal->interface == INTF_USB) {
if (tx_agc[idx1] > 0x20 &&
rtlefuse->external_pa)
tx_agc[idx1] = 0x20;
}
}
}
} else {
if (rtlpriv->dm.dynamic_txhighpower_lvl ==
TXHIGHPWRLEVEL_LEVEL1) {
tx_agc[RF90_PATH_A] = 0x10101010;
tx_agc[RF90_PATH_B] = 0x10101010;
} else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
TXHIGHPWRLEVEL_LEVEL1) {
tx_agc[RF90_PATH_A] = 0x00000000;
tx_agc[RF90_PATH_B] = 0x00000000;
} 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 = 0, ht20_pwrdiff = 0;
u8 i, powerlevel[2];
for (i = 0; i < 2; i++) {
powerlevel[i] = ppowerlevel[i];
legacy_pwrdiff = rtlefuse->txpwr_legacyhtdiff[i][channel - 1];
powerBase0 = powerlevel[i] + legacy_pwrdiff;
powerBase0 = (powerBase0 << 24) | (powerBase0 << 16) |
(powerBase0 << 8) | powerBase0;
*(ofdmbase + i) = powerBase0;
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
" [OFDM power base index rf(%c) = 0x%x]\n",
i == 0 ? 'A' : 'B', *(ofdmbase + i));
}
for (i = 0; i < 2; i++) {
if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) {
ht20_pwrdiff = rtlefuse->txpwr_ht20diff[i][channel - 1];
powerlevel[i] += ht20_pwrdiff;
}
powerBase1 = powerlevel[i];
powerBase1 = (powerBase1 << 24) |
(powerBase1 << 16) | (powerBase1 << 8) | powerBase1;
*(mcsbase + i) = powerBase1;
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
" [MCS power base index rf(%c) = 0x%x]\n",
i == 0 ? 'A' : 'B', *(mcsbase + i));
}
}
static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
u8 channel, u8 index,
u32 *powerBase0,
u32 *powerBase1,
u32 *p_outwriteval)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
u8 i, chnlgroup = 0, pwr_diff_limit[4];
u32 writeVal, customer_limit, rf;
for (rf = 0; rf < 2; rf++) {
switch (rtlefuse->eeprom_regulatory) {
case 0:
chnlgroup = 0;
writeVal = rtlphy->mcs_txpwrlevel_origoffset
[chnlgroup][index + (rf ? 8 : 0)]
+ ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
"RTK better performance,writeVal(%c) = 0x%x\n",
rf == 0 ? 'A' : 'B', writeVal);
break;
case 1:
if (rtlphy->pwrgroup_cnt == 1)
chnlgroup = 0;
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->current_chan_bw ==
HT_CHANNEL_WIDTH_20)
chnlgroup++;
else
chnlgroup += 4;
}
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, 40MHzrf(%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, writeValrf(%c) = 0x%x\n",
rf == 0 ? 'A' : 'B', writeVal);
break;
}
if (rtlpriv->dm.dynamic_txhighpower_lvl ==
TXHIGHPWRLEVEL_LEVEL1)
writeVal = 0x14141414;
else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
TXHIGHPWRLEVEL_LEVEL2)
writeVal = 0x00000000;
if (rtlpriv->dm.dynamic_txhighpower_lvl == TXHIGHPWRLEVEL_BT1)
writeVal = writeVal - 0x06060606;
else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
TXHIGHPWRLEVEL_BT2)
writeVal = writeVal;
*(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 rtl92cu_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
u8 *ppowerlevel, u8 channel)
{
u32 writeVal[2], powerBase0[2], powerBase1[2];
u8 index = 0;
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 rtl92cu_phy_rf6052_config(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
bool rtstatus = true;
u8 b_reg_hwparafile = 1;
if (rtlphy->rf_type == RF_1T1R)
rtlphy->num_total_rfpath = 1;
else
rtlphy->num_total_rfpath = 2;
if (b_reg_hwparafile == 1)
rtstatus = _rtl92c_phy_rf6052_config_parafile(hw);
return rtstatus;
}
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 = 0;
u8 rfpath;
bool rtstatus = true;
struct bb_reg_def *pphyreg;
for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) {
pphyreg = &rtlphy->phyreg_def[rfpath];
switch (rfpath) {
case RF90_PATH_A:
case RF90_PATH_C:
u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs,
BRFSI_RFENV);
break;
case RF90_PATH_B:
case RF90_PATH_D:
u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs,
BRFSI_RFENV << 16);
break;
}
rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1);
udelay(1);
rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1);
udelay(1);
rtl_set_bbreg(hw, pphyreg->rfhssi_para2,
B3WIREADDREAALENGTH, 0x0);
udelay(1);
rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0);
udelay(1);
switch (rfpath) {
case RF90_PATH_A:
rtstatus = rtl92cu_phy_config_rf_with_headerfile(hw,
(enum radio_path) rfpath);
break;
case RF90_PATH_B:
rtstatus = rtl92cu_phy_config_rf_with_headerfile(hw,
(enum radio_path) rfpath);
break;
case RF90_PATH_C:
break;
case RF90_PATH_D:
break;
}
switch (rfpath) {
case RF90_PATH_A:
case RF90_PATH_C:
rtl_set_bbreg(hw, pphyreg->rfintfs,
BRFSI_RFENV, u4_regvalue);
break;
case RF90_PATH_B:
case RF90_PATH_D:
rtl_set_bbreg(hw, pphyreg->rfintfs,
BRFSI_RFENV << 16, u4_regvalue);
break;
}
if (!rtstatus) {
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
"Radio[%d] Fail!!", rfpath);
goto phy_rf_cfg_fail;
}
}
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "<---\n");
return rtstatus;
phy_rf_cfg_fail:
return rtstatus;
}

View File

@ -0,0 +1,51 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __RTL92CU_RF_H__
#define __RTL92CU_RF_H__
#define RF6052_MAX_TX_PWR 0x3F
#define RF6052_MAX_REG 0x3F
#define RF6052_MAX_PATH 2
extern void rtl92cu_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);
bool rtl92cu_phy_rf6052_config(struct ieee80211_hw *hw);
bool rtl92cu_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
enum radio_path rfpath);
void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
u8 *ppowerlevel);
void rtl92cu_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
u8 *ppowerlevel, u8 channel);
#endif

View File

@ -0,0 +1,384 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "../wifi.h"
#include "../core.h"
#include "../usb.h"
#include "../efuse.h"
#include "reg.h"
#include "def.h"
#include "phy.h"
#include "mac.h"
#include "dm.h"
#include "rf.h"
#include "sw.h"
#include "trx.h"
#include "led.h"
#include "hw.h"
#include <linux/module.h>
MODULE_AUTHOR("Georgia <georgia@realtek.com>");
MODULE_AUTHOR("Ziv Huang <ziv_huang@realtek.com>");
MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Realtek 8192C/8188C 802.11n USB wireless");
MODULE_FIRMWARE("rtlwifi/rtl8192cufw.bin");
static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
int err;
rtlpriv->dm.dm_initialgain_enable = true;
rtlpriv->dm.dm_flag = 0;
rtlpriv->dm.disable_framebursting = false;
rtlpriv->dm.thermalvalue = 0;
rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
/* for firmware buf */
rtlpriv->rtlhal.pfirmware = vzalloc(0x4000);
if (!rtlpriv->rtlhal.pfirmware) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"Can't alloc buffer for fw\n");
return 1;
}
pr_info("Loading firmware %s\n", rtlpriv->cfg->fw_name);
rtlpriv->max_fw_size = 0x4000;
err = request_firmware_nowait(THIS_MODULE, 1,
rtlpriv->cfg->fw_name, rtlpriv->io.dev,
GFP_KERNEL, hw, rtl_fw_cb);
return 0;
}
static void rtl92cu_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 rtl8192cu_hal_ops = {
.init_sw_vars = rtl92cu_init_sw_vars,
.deinit_sw_vars = rtl92cu_deinit_sw_vars,
.read_chip_version = rtl92c_read_chip_version,
.read_eeprom_info = rtl92cu_read_eeprom_info,
.enable_interrupt = rtl92c_enable_interrupt,
.disable_interrupt = rtl92c_disable_interrupt,
.hw_init = rtl92cu_hw_init,
.hw_disable = rtl92cu_card_disable,
.set_network_type = rtl92cu_set_network_type,
.set_chk_bssid = rtl92cu_set_check_bssid,
.set_qos = rtl92c_set_qos,
.set_bcn_reg = rtl92cu_set_beacon_related_registers,
.set_bcn_intv = rtl92cu_set_beacon_interval,
.update_interrupt_mask = rtl92cu_update_interrupt_mask,
.get_hw_reg = rtl92cu_get_hw_reg,
.set_hw_reg = rtl92cu_set_hw_reg,
.update_rate_tbl = rtl92cu_update_hal_rate_table,
.update_rate_mask = rtl92cu_update_hal_rate_mask,
.fill_tx_desc = rtl92cu_tx_fill_desc,
.fill_fake_txdesc = rtl92cu_fill_fake_txdesc,
.fill_tx_cmddesc = rtl92cu_tx_fill_cmddesc,
.cmd_send_packet = rtl92cu_cmd_send_packet,
.query_rx_desc = rtl92cu_rx_query_desc,
.set_channel_access = rtl92cu_update_channel_access_setting,
.radio_onoff_checking = rtl92cu_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 = rtl92cu_phy_set_rf_power_state,
.led_control = rtl92cu_led_control,
.enable_hw_sec = rtl92cu_enable_hw_security_config,
.set_key = rtl92c_set_key,
.init_sw_leds = rtl92cu_init_sw_leds,
.deinit_sw_leds = rtl92cu_deinit_sw_leds,
.get_bbreg = rtl92c_phy_query_bb_reg,
.set_bbreg = rtl92c_phy_set_bb_reg,
.get_rfreg = rtl92cu_phy_query_rf_reg,
.set_rfreg = rtl92cu_phy_set_rf_reg,
.phy_rf6052_config = rtl92cu_phy_rf6052_config,
.phy_rf6052_set_cck_txpower = rtl92cu_phy_rf6052_set_cck_txpower,
.phy_rf6052_set_ofdm_txpower = rtl92cu_phy_rf6052_set_ofdm_txpower,
.config_bb_with_headerfile = _rtl92cu_phy_config_bb_with_headerfile,
.config_bb_with_pgheaderfile = _rtl92cu_phy_config_bb_with_pgheaderfile,
.phy_lc_calibrate = _rtl92cu_phy_lc_calibrate,
.phy_set_bw_mode_callback = rtl92cu_phy_set_bw_mode_callback,
.dm_dynamic_txpower = rtl92cu_dm_dynamic_txpower,
};
static struct rtl_mod_params rtl92cu_mod_params = {
.sw_crypto = 0,
.debug = DBG_EMERG,
};
module_param_named(swenc, rtl92cu_mod_params.sw_crypto, bool, 0444);
module_param_named(debug, rtl92cu_mod_params.debug, int, 0444);
MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n");
MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
static struct rtl_hal_usbint_cfg rtl92cu_interface_cfg = {
/* rx */
.in_ep_num = RTL92C_USB_BULK_IN_NUM,
.rx_urb_num = RTL92C_NUM_RX_URBS,
.rx_max_size = RTL92C_SIZE_MAX_RX_BUFFER,
.usb_rx_hdl = rtl8192cu_rx_hdl,
.usb_rx_segregate_hdl = NULL, /* rtl8192c_rx_segregate_hdl; */
/* tx */
.usb_tx_cleanup = rtl8192c_tx_cleanup,
.usb_tx_post_hdl = rtl8192c_tx_post_hdl,
.usb_tx_aggregate_hdl = rtl8192c_tx_aggregate_hdl,
/* endpoint mapping */
.usb_endpoint_mapping = rtl8192cu_endpoint_mapping,
.usb_mq_to_hwq = rtl8192cu_mq_to_hwq,
};
static struct rtl_hal_cfg rtl92cu_hal_cfg = {
.name = "rtl92c_usb",
.fw_name = "rtlwifi/rtl8192cufw.bin",
.ops = &rtl8192cu_hal_ops,
.mod_params = &rtl92cu_mod_params,
.usb_interface_cfg = &rtl92cu_interface_cfg,
.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[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION,
.maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN,
.maps[RWCAM] = REG_CAMCMD,
.maps[WCAMI] = REG_CAMWRITE,
.maps[RCAMO] = REG_CAMREAD,
.maps[CAMDBG] = REG_CAMDBG,
.maps[SECR] = REG_SECCFG,
.maps[SEC_CAM_NONE] = CAM_NONE,
.maps[SEC_CAM_WEP40] = CAM_WEP40,
.maps[SEC_CAM_TKIP] = CAM_TKIP,
.maps[SEC_CAM_AES] = CAM_AES,
.maps[SEC_CAM_WEP104] = CAM_WEP104,
.maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6,
.maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5,
.maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4,
.maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3,
.maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2,
.maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1,
.maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8,
.maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7,
.maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6,
.maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5,
.maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4,
.maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3,
.maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2,
.maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1,
.maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2,
.maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1,
.maps[RTL_IMR_TXFOVW] = IMR_TXFOVW,
.maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT,
.maps[RTL_IMR_BcnInt] = IMR_BCNINT,
.maps[RTL_IMR_RXFOVW] = IMR_RXFOVW,
.maps[RTL_IMR_RDU] = IMR_RDU,
.maps[RTL_IMR_ATIMEND] = IMR_ATIMEND,
.maps[RTL_IMR_BDOK] = IMR_BDOK,
.maps[RTL_IMR_MGNTDOK] = IMR_MGNTDOK,
.maps[RTL_IMR_TBDER] = IMR_TBDER,
.maps[RTL_IMR_HIGHDOK] = IMR_HIGHDOK,
.maps[RTL_IMR_TBDOK] = IMR_TBDOK,
.maps[RTL_IMR_BKDOK] = IMR_BKDOK,
.maps[RTL_IMR_BEDOK] = IMR_BEDOK,
.maps[RTL_IMR_VIDOK] = IMR_VIDOK,
.maps[RTL_IMR_VODOK] = IMR_VODOK,
.maps[RTL_IMR_ROK] = IMR_ROK,
.maps[RTL_IBSS_INT_MASKS] = (IMR_BCNINT | IMR_TBDOK | IMR_TBDER),
.maps[RTL_RC_CCK_RATE1M] = DESC92_RATE1M,
.maps[RTL_RC_CCK_RATE2M] = DESC92_RATE2M,
.maps[RTL_RC_CCK_RATE5_5M] = DESC92_RATE5_5M,
.maps[RTL_RC_CCK_RATE11M] = DESC92_RATE11M,
.maps[RTL_RC_OFDM_RATE6M] = DESC92_RATE6M,
.maps[RTL_RC_OFDM_RATE9M] = DESC92_RATE9M,
.maps[RTL_RC_OFDM_RATE12M] = DESC92_RATE12M,
.maps[RTL_RC_OFDM_RATE18M] = DESC92_RATE18M,
.maps[RTL_RC_OFDM_RATE24M] = DESC92_RATE24M,
.maps[RTL_RC_OFDM_RATE36M] = DESC92_RATE36M,
.maps[RTL_RC_OFDM_RATE48M] = DESC92_RATE48M,
.maps[RTL_RC_OFDM_RATE54M] = DESC92_RATE54M,
.maps[RTL_RC_HT_RATEMCS7] = DESC92_RATEMCS7,
.maps[RTL_RC_HT_RATEMCS15] = DESC92_RATEMCS15,
};
#define USB_VENDER_ID_REALTEK 0x0bda
/* 2010-10-19 DID_USB_V3.4 */
static struct usb_device_id rtl8192c_usb_ids[] = {
/*=== Realtek demoboard ===*/
/* Default ID */
{RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8191, rtl92cu_hal_cfg)},
/****** 8188CU ********/
/* RTL8188CTV */
{RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x018a, rtl92cu_hal_cfg)},
/* 8188CE-VAU USB minCard */
{RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8170, rtl92cu_hal_cfg)},
/* 8188cu 1*1 dongle */
{RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8176, rtl92cu_hal_cfg)},
/* 8188cu 1*1 dongle, (b/g mode only) */
{RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8177, rtl92cu_hal_cfg)},
/* 8188cu Slim Solo */
{RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817a, rtl92cu_hal_cfg)},
/* 8188cu Slim Combo */
{RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817b, rtl92cu_hal_cfg)},
/* 8188RU High-power USB Dongle */
{RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817d, rtl92cu_hal_cfg)},
/* 8188CE-VAU USB minCard (b/g mode only) */
{RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817e, rtl92cu_hal_cfg)},
/* 8188RU in Alfa AWUS036NHR */
{RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817f, rtl92cu_hal_cfg)},
/* RTL8188CUS-VL */
{RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x818a, rtl92cu_hal_cfg)},
/* 8188 Combo for BC4 */
{RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8754, rtl92cu_hal_cfg)},
/****** 8192CU ********/
/* 8192cu 2*2 */
{RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8178, rtl92cu_hal_cfg)},
/* 8192CE-VAU USB minCard */
{RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817c, rtl92cu_hal_cfg)},
/*=== Customer ID ===*/
/****** 8188CU ********/
{RTL_USB_DEVICE(0x050d, 0x1102, rtl92cu_hal_cfg)}, /*Belkin - Edimax*/
{RTL_USB_DEVICE(0x06f8, 0xe033, rtl92cu_hal_cfg)}, /*Hercules - Edimax*/
{RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/
{RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/
{RTL_USB_DEVICE(0x0846, 0x9041, rtl92cu_hal_cfg)}, /*NetGear WNA1000M*/
{RTL_USB_DEVICE(0x0bda, 0x5088, rtl92cu_hal_cfg)}, /*Thinkware-CC&C*/
{RTL_USB_DEVICE(0x0df6, 0x0052, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/
{RTL_USB_DEVICE(0x0df6, 0x005c, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/
{RTL_USB_DEVICE(0x0eb0, 0x9071, rtl92cu_hal_cfg)}, /*NO Brand - Etop*/
{RTL_USB_DEVICE(0x4856, 0x0091, rtl92cu_hal_cfg)}, /*NetweeN - Feixun*/
/* HP - Lite-On ,8188CUS Slim Combo */
{RTL_USB_DEVICE(0x103c, 0x1629, rtl92cu_hal_cfg)},
{RTL_USB_DEVICE(0x13d3, 0x3357, rtl92cu_hal_cfg)}, /* AzureWave */
{RTL_USB_DEVICE(0x2001, 0x3308, rtl92cu_hal_cfg)}, /*D-Link - Alpha*/
{RTL_USB_DEVICE(0x2019, 0x4902, rtl92cu_hal_cfg)}, /*Planex - Etop*/
{RTL_USB_DEVICE(0x2019, 0xab2a, rtl92cu_hal_cfg)}, /*Planex - Abocom*/
/*SW-WF02-AD15 -Abocom*/
{RTL_USB_DEVICE(0x2019, 0xab2e, rtl92cu_hal_cfg)},
{RTL_USB_DEVICE(0x2019, 0xed17, rtl92cu_hal_cfg)}, /*PCI - Edimax*/
{RTL_USB_DEVICE(0x20f4, 0x648b, rtl92cu_hal_cfg)}, /*TRENDnet - Cameo*/
{RTL_USB_DEVICE(0x7392, 0x7811, rtl92cu_hal_cfg)}, /*Edimax - Edimax*/
{RTL_USB_DEVICE(0x13d3, 0x3358, rtl92cu_hal_cfg)}, /*Azwave 8188CE-VAU*/
/* Russian customer -Azwave (8188CE-VAU b/g mode only) */
{RTL_USB_DEVICE(0x13d3, 0x3359, rtl92cu_hal_cfg)},
{RTL_USB_DEVICE(0x4855, 0x0090, rtl92cu_hal_cfg)}, /* Feixun */
{RTL_USB_DEVICE(0x4855, 0x0091, rtl92cu_hal_cfg)}, /* NetweeN-Feixun */
{RTL_USB_DEVICE(0x9846, 0x9041, rtl92cu_hal_cfg)}, /* Netgear Cameo */
/****** 8188 RU ********/
/* Netcore */
{RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x317f, rtl92cu_hal_cfg)},
/****** 8188CUS Slim Solo********/
{RTL_USB_DEVICE(0x04f2, 0xaff7, rtl92cu_hal_cfg)}, /*Xavi*/
{RTL_USB_DEVICE(0x04f2, 0xaff9, rtl92cu_hal_cfg)}, /*Xavi*/
{RTL_USB_DEVICE(0x04f2, 0xaffa, rtl92cu_hal_cfg)}, /*Xavi*/
/****** 8188CUS Slim Combo ********/
{RTL_USB_DEVICE(0x04f2, 0xaff8, rtl92cu_hal_cfg)}, /*Xavi*/
{RTL_USB_DEVICE(0x04f2, 0xaffb, rtl92cu_hal_cfg)}, /*Xavi*/
{RTL_USB_DEVICE(0x04f2, 0xaffc, rtl92cu_hal_cfg)}, /*Xavi*/
{RTL_USB_DEVICE(0x2019, 0x1201, rtl92cu_hal_cfg)}, /*Planex-Vencer*/
/****** 8192CU ********/
{RTL_USB_DEVICE(0x050d, 0x1004, rtl92cu_hal_cfg)}, /*Belcom-SurfN300*/
{RTL_USB_DEVICE(0x050d, 0x2102, rtl92cu_hal_cfg)}, /*Belcom-Sercomm*/
{RTL_USB_DEVICE(0x050d, 0x2103, rtl92cu_hal_cfg)}, /*Belcom-Edimax*/
{RTL_USB_DEVICE(0x0586, 0x341f, rtl92cu_hal_cfg)}, /*Zyxel -Abocom*/
{RTL_USB_DEVICE(0x07aa, 0x0056, rtl92cu_hal_cfg)}, /*ATKK-Gemtek*/
{RTL_USB_DEVICE(0x07b8, 0x8178, rtl92cu_hal_cfg)}, /*Funai -Abocom*/
{RTL_USB_DEVICE(0x0846, 0x9021, rtl92cu_hal_cfg)}, /*Netgear-Sercomm*/
{RTL_USB_DEVICE(0x0b05, 0x17ab, rtl92cu_hal_cfg)}, /*ASUS-Edimax*/
{RTL_USB_DEVICE(0x0bda, 0x8186, rtl92cu_hal_cfg)}, /*Realtek 92CE-VAU*/
{RTL_USB_DEVICE(0x0df6, 0x0061, rtl92cu_hal_cfg)}, /*Sitecom-Edimax*/
{RTL_USB_DEVICE(0x0e66, 0x0019, rtl92cu_hal_cfg)}, /*Hawking-Edimax*/
{RTL_USB_DEVICE(0x2001, 0x3307, rtl92cu_hal_cfg)}, /*D-Link-Cameo*/
{RTL_USB_DEVICE(0x2001, 0x3309, rtl92cu_hal_cfg)}, /*D-Link-Alpha*/
{RTL_USB_DEVICE(0x2001, 0x330a, rtl92cu_hal_cfg)}, /*D-Link-Alpha*/
{RTL_USB_DEVICE(0x2019, 0xab2b, rtl92cu_hal_cfg)}, /*Planex -Abocom*/
{RTL_USB_DEVICE(0x20f4, 0x624d, rtl92cu_hal_cfg)}, /*TRENDNet*/
{RTL_USB_DEVICE(0x7392, 0x7822, rtl92cu_hal_cfg)}, /*Edimax -Edimax*/
{}
};
MODULE_DEVICE_TABLE(usb, rtl8192c_usb_ids);
static struct usb_driver rtl8192cu_driver = {
.name = "rtl8192cu",
.probe = rtl_usb_probe,
.disconnect = rtl_usb_disconnect,
.id_table = rtl8192c_usb_ids,
#ifdef CONFIG_PM
/* .suspend = rtl_usb_suspend, */
/* .resume = rtl_usb_resume, */
/* .reset_resume = rtl8192c_resume, */
#endif /* CONFIG_PM */
#ifdef CONFIG_AUTOSUSPEND
.supports_autosuspend = 1,
#endif
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0))
.disable_hub_initiated_lpm = 1,
#endif
};
module_usb_driver(rtl8192cu_driver);

View File

@ -0,0 +1,53 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __RTL92CU_SW_H__
#define __RTL92CU_SW_H__
#define EFUSE_MAX_SECTION 16
void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
u8 *powerlevel);
void rtl92cu_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
u8 *ppowerlevel, u8 channel);
bool _rtl92cu_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
u8 configtype);
bool _rtl92cu_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
u8 configtype);
void _rtl92cu_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t);
void rtl92cu_phy_set_rf_reg(struct ieee80211_hw *hw,
enum radio_path rfpath,
u32 regaddr, u32 bitmask, u32 data);
bool rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw,
enum rf_pwrstate rfpwr_state);
u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw,
enum radio_path rfpath, u32 regaddr, u32 bitmask);
void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,71 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __RTL92CU_TABLE__H_
#define __RTL92CU_TABLE__H_
#include <linux/types.h>
#define RTL8192CUPHY_REG_2TARRAY_LENGTH 374
extern u32 RTL8192CUPHY_REG_2TARRAY[RTL8192CUPHY_REG_2TARRAY_LENGTH];
#define RTL8192CUPHY_REG_1TARRAY_LENGTH 374
extern u32 RTL8192CUPHY_REG_1TARRAY[RTL8192CUPHY_REG_1TARRAY_LENGTH];
#define RTL8192CUPHY_REG_ARRAY_PGLENGTH 336
extern u32 RTL8192CUPHY_REG_ARRAY_PG[RTL8192CUPHY_REG_ARRAY_PGLENGTH];
#define RTL8192CURADIOA_2TARRAYLENGTH 282
extern u32 RTL8192CURADIOA_2TARRAY[RTL8192CURADIOA_2TARRAYLENGTH];
#define RTL8192CURADIOB_2TARRAYLENGTH 78
extern u32 RTL8192CU_RADIOB_2TARRAY[RTL8192CURADIOB_2TARRAYLENGTH];
#define RTL8192CURADIOA_1TARRAYLENGTH 282
extern u32 RTL8192CU_RADIOA_1TARRAY[RTL8192CURADIOA_1TARRAYLENGTH];
#define RTL8192CURADIOB_1TARRAYLENGTH 1
extern u32 RTL8192CU_RADIOB_1TARRAY[RTL8192CURADIOB_1TARRAYLENGTH];
#define RTL8192CUMAC_2T_ARRAYLENGTH 172
extern u32 RTL8192CUMAC_2T_ARRAY[RTL8192CUMAC_2T_ARRAYLENGTH];
#define RTL8192CUAGCTAB_2TARRAYLENGTH 320
extern u32 RTL8192CUAGCTAB_2TARRAY[RTL8192CUAGCTAB_2TARRAYLENGTH];
#define RTL8192CUAGCTAB_1TARRAYLENGTH 320
extern u32 RTL8192CUAGCTAB_1TARRAY[RTL8192CUAGCTAB_1TARRAYLENGTH];
#define RTL8192CUPHY_REG_1T_HPArrayLength 378
extern u32 RTL8192CUPHY_REG_1T_HPArray[RTL8192CUPHY_REG_1T_HPArrayLength];
#define RTL8192CUPHY_REG_Array_PG_HPLength 336
extern u32 RTL8192CUPHY_REG_Array_PG_HP[RTL8192CUPHY_REG_Array_PG_HPLength];
#define RTL8192CURadioA_1T_HPArrayLength 282
extern u32 RTL8192CURadioA_1T_HPArray[RTL8192CURadioA_1T_HPArrayLength];
#define RTL8192CUAGCTAB_1T_HPArrayLength 320
extern u32 Rtl8192CUAGCTAB_1T_HPArray[RTL8192CUAGCTAB_1T_HPArrayLength];
#endif

View File

@ -0,0 +1,687 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "../wifi.h"
#include "../usb.h"
#include "../ps.h"
#include "../base.h"
#include "reg.h"
#include "def.h"
#include "phy.h"
#include "rf.h"
#include "dm.h"
#include "mac.h"
#include "trx.h"
static int _ConfigVerTOutEP(struct ieee80211_hw *hw)
{
u8 ep_cfg, txqsele;
u8 ep_nums = 0;
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw);
struct rtl_usb *rtlusb = rtl_usbdev(usb_priv);
rtlusb->out_queue_sel = 0;
ep_cfg = rtl_read_byte(rtlpriv, REG_TEST_SIE_OPTIONAL);
ep_cfg = (ep_cfg & USB_TEST_EP_MASK) >> USB_TEST_EP_SHIFT;
switch (ep_cfg) {
case 0: /* 2 bulk OUT, 1 bulk IN */
case 3:
rtlusb->out_queue_sel = TX_SELE_HQ | TX_SELE_LQ;
ep_nums = 2;
break;
case 1: /* 1 bulk IN/OUT => map all endpoint to Low queue */
case 2: /* 1 bulk IN, 1 bulk OUT => map all endpoint to High queue */
txqsele = rtl_read_byte(rtlpriv, REG_TEST_USB_TXQS);
if (txqsele & 0x0F) /* /map all endpoint to High queue */
rtlusb->out_queue_sel = TX_SELE_HQ;
else if (txqsele&0xF0) /* map all endpoint to Low queue */
rtlusb->out_queue_sel = TX_SELE_LQ;
ep_nums = 1;
break;
default:
break;
}
return (rtlusb->out_ep_nums == ep_nums) ? 0 : -EINVAL;
}
static int _ConfigVerNOutEP(struct ieee80211_hw *hw)
{
u8 ep_cfg;
u8 ep_nums = 0;
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw);
struct rtl_usb *rtlusb = rtl_usbdev(usb_priv);
rtlusb->out_queue_sel = 0;
/* Normal and High queue */
ep_cfg = rtl_read_byte(rtlpriv, (REG_NORMAL_SIE_EP + 1));
if (ep_cfg & USB_NORMAL_SIE_EP_MASK) {
rtlusb->out_queue_sel |= TX_SELE_HQ;
ep_nums++;
}
if ((ep_cfg >> USB_NORMAL_SIE_EP_SHIFT) & USB_NORMAL_SIE_EP_MASK) {
rtlusb->out_queue_sel |= TX_SELE_NQ;
ep_nums++;
}
/* Low queue */
ep_cfg = rtl_read_byte(rtlpriv, (REG_NORMAL_SIE_EP + 2));
if (ep_cfg & USB_NORMAL_SIE_EP_MASK) {
rtlusb->out_queue_sel |= TX_SELE_LQ;
ep_nums++;
}
return (rtlusb->out_ep_nums == ep_nums) ? 0 : -EINVAL;
}
static void _TwoOutEpMapping(struct ieee80211_hw *hw, bool bIsChipB,
bool bwificfg, struct rtl_ep_map *ep_map)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
if (bwificfg) { /* for WMM */
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"USB Chip-B & WMM Setting.....\n");
ep_map->ep_mapping[RTL_TXQ_BE] = 2;
ep_map->ep_mapping[RTL_TXQ_BK] = 3;
ep_map->ep_mapping[RTL_TXQ_VI] = 3;
ep_map->ep_mapping[RTL_TXQ_VO] = 2;
ep_map->ep_mapping[RTL_TXQ_MGT] = 2;
ep_map->ep_mapping[RTL_TXQ_BCN] = 2;
ep_map->ep_mapping[RTL_TXQ_HI] = 2;
} else { /* typical setting */
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"USB typical Setting.....\n");
ep_map->ep_mapping[RTL_TXQ_BE] = 3;
ep_map->ep_mapping[RTL_TXQ_BK] = 3;
ep_map->ep_mapping[RTL_TXQ_VI] = 2;
ep_map->ep_mapping[RTL_TXQ_VO] = 2;
ep_map->ep_mapping[RTL_TXQ_MGT] = 2;
ep_map->ep_mapping[RTL_TXQ_BCN] = 2;
ep_map->ep_mapping[RTL_TXQ_HI] = 2;
}
}
static void _ThreeOutEpMapping(struct ieee80211_hw *hw, bool bwificfg,
struct rtl_ep_map *ep_map)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
if (bwificfg) { /* for WMM */
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"USB 3EP Setting for WMM.....\n");
ep_map->ep_mapping[RTL_TXQ_BE] = 5;
ep_map->ep_mapping[RTL_TXQ_BK] = 3;
ep_map->ep_mapping[RTL_TXQ_VI] = 3;
ep_map->ep_mapping[RTL_TXQ_VO] = 2;
ep_map->ep_mapping[RTL_TXQ_MGT] = 2;
ep_map->ep_mapping[RTL_TXQ_BCN] = 2;
ep_map->ep_mapping[RTL_TXQ_HI] = 2;
} else { /* typical setting */
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"USB 3EP Setting for typical.....\n");
ep_map->ep_mapping[RTL_TXQ_BE] = 5;
ep_map->ep_mapping[RTL_TXQ_BK] = 5;
ep_map->ep_mapping[RTL_TXQ_VI] = 3;
ep_map->ep_mapping[RTL_TXQ_VO] = 2;
ep_map->ep_mapping[RTL_TXQ_MGT] = 2;
ep_map->ep_mapping[RTL_TXQ_BCN] = 2;
ep_map->ep_mapping[RTL_TXQ_HI] = 2;
}
}
static void _OneOutEpMapping(struct ieee80211_hw *hw, struct rtl_ep_map *ep_map)
{
ep_map->ep_mapping[RTL_TXQ_BE] = 2;
ep_map->ep_mapping[RTL_TXQ_BK] = 2;
ep_map->ep_mapping[RTL_TXQ_VI] = 2;
ep_map->ep_mapping[RTL_TXQ_VO] = 2;
ep_map->ep_mapping[RTL_TXQ_MGT] = 2;
ep_map->ep_mapping[RTL_TXQ_BCN] = 2;
ep_map->ep_mapping[RTL_TXQ_HI] = 2;
}
static int _out_ep_mapping(struct ieee80211_hw *hw)
{
int err = 0;
bool bIsChipN, bwificfg = false;
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw);
struct rtl_usb *rtlusb = rtl_usbdev(usb_priv);
struct rtl_ep_map *ep_map = &(rtlusb->ep_map);
bIsChipN = IS_NORMAL_CHIP(rtlhal->version);
switch (rtlusb->out_ep_nums) {
case 2:
_TwoOutEpMapping(hw, bIsChipN, bwificfg, ep_map);
break;
case 3:
/* Test chip doesn't support three out EPs. */
if (!bIsChipN) {
err = -EINVAL;
goto err_out;
}
_ThreeOutEpMapping(hw, bIsChipN, ep_map);
break;
case 1:
_OneOutEpMapping(hw, ep_map);
break;
default:
err = -EINVAL;
break;
}
err_out:
return err;
}
/* endpoint mapping */
int rtl8192cu_endpoint_mapping(struct ieee80211_hw *hw)
{
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
int error = 0;
if (likely(IS_NORMAL_CHIP(rtlhal->version)))
error = _ConfigVerNOutEP(hw);
else
error = _ConfigVerTOutEP(hw);
if (error)
goto err_out;
error = _out_ep_mapping(hw);
if (error)
goto err_out;
err_out:
return error;
}
u16 rtl8192cu_mq_to_hwq(__le16 fc, u16 mac80211_queue_index)
{
u16 hw_queue_index;
if (unlikely(ieee80211_is_beacon(fc))) {
hw_queue_index = RTL_TXQ_BCN;
goto out;
}
if (ieee80211_is_mgmt(fc)) {
hw_queue_index = RTL_TXQ_MGT;
goto out;
}
switch (mac80211_queue_index) {
case 0:
hw_queue_index = RTL_TXQ_VO;
break;
case 1:
hw_queue_index = RTL_TXQ_VI;
break;
case 2:
hw_queue_index = RTL_TXQ_BE;
break;
case 3:
hw_queue_index = RTL_TXQ_BK;
break;
default:
hw_queue_index = RTL_TXQ_BE;
RT_ASSERT(false, "QSLT_BE queue, skb_queue:%d\n",
mac80211_queue_index);
break;
}
out:
return hw_queue_index;
}
static enum rtl_desc_qsel _rtl8192cu_mq_to_descq(struct ieee80211_hw *hw,
__le16 fc, u16 mac80211_queue_index)
{
enum rtl_desc_qsel qsel;
struct rtl_priv *rtlpriv = rtl_priv(hw);
if (unlikely(ieee80211_is_beacon(fc))) {
qsel = QSLT_BEACON;
goto out;
}
if (ieee80211_is_mgmt(fc)) {
qsel = QSLT_MGNT;
goto out;
}
switch (mac80211_queue_index) {
case 0: /* VO */
qsel = QSLT_VO;
RT_TRACE(rtlpriv, COMP_USB, DBG_DMESG,
"VO queue, set qsel = 0x%x\n", QSLT_VO);
break;
case 1: /* VI */
qsel = QSLT_VI;
RT_TRACE(rtlpriv, COMP_USB, DBG_DMESG,
"VI queue, set qsel = 0x%x\n", QSLT_VI);
break;
case 3: /* BK */
qsel = QSLT_BK;
RT_TRACE(rtlpriv, COMP_USB, DBG_DMESG,
"BK queue, set qsel = 0x%x\n", QSLT_BK);
break;
case 2: /* BE */
default:
qsel = QSLT_BE;
RT_TRACE(rtlpriv, COMP_USB, DBG_DMESG,
"BE queue, set qsel = 0x%x\n", QSLT_BE);
break;
}
out:
return qsel;
}
/* =============================================================== */
/*----------------------------------------------------------------------
*
* Rx handler
*
*---------------------------------------------------------------------- */
bool rtl92cu_rx_query_desc(struct ieee80211_hw *hw,
struct rtl_stats *stats,
struct ieee80211_rx_status *rx_status,
u8 *p_desc, struct sk_buff *skb)
{
struct rx_fwinfo_92c *p_drvinfo;
struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc;
u32 phystatus = GET_RX_DESC_PHY_STATUS(pdesc);
stats->length = (u16) GET_RX_DESC_PKT_LEN(pdesc);
stats->rx_drvinfo_size = (u8)GET_RX_DESC_DRVINFO_SIZE(pdesc) *
RX_DRV_INFO_SIZE_UNIT;
stats->rx_bufshift = (u8) (GET_RX_DESC_SHIFT(pdesc) & 0x03);
stats->icv = (u16) GET_RX_DESC_ICV(pdesc);
stats->crc = (u16) GET_RX_DESC_CRC32(pdesc);
stats->hwerror = (stats->crc | stats->icv);
stats->decrypted = !GET_RX_DESC_SWDEC(pdesc);
stats->rate = (u8) GET_RX_DESC_RX_MCS(pdesc);
stats->shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc);
stats->isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1);
stats->isampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1)
&& (GET_RX_DESC_FAGGR(pdesc) == 1));
stats->timestamp_low = GET_RX_DESC_TSFL(pdesc);
stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc);
rx_status->freq = hw->conf.channel->center_freq;
rx_status->band = hw->conf.channel->band;
if (GET_RX_DESC_CRC32(pdesc))
rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
if (!GET_RX_DESC_SWDEC(pdesc))
rx_status->flag |= RX_FLAG_DECRYPTED;
if (GET_RX_DESC_BW(pdesc))
rx_status->flag |= RX_FLAG_40MHZ;
if (GET_RX_DESC_RX_HT(pdesc))
rx_status->flag |= RX_FLAG_HT;
rx_status->flag |= RX_FLAG_MACTIME_MPDU;
if (stats->decrypted)
rx_status->flag |= RX_FLAG_DECRYPTED;
rx_status->rate_idx = rtlwifi_rate_mapping(hw,
(bool)GET_RX_DESC_RX_HT(pdesc),
(u8)GET_RX_DESC_RX_MCS(pdesc),
(bool)GET_RX_DESC_PAGGR(pdesc));
rx_status->mactime = GET_RX_DESC_TSFL(pdesc);
if (phystatus) {
p_drvinfo = (struct rx_fwinfo_92c *)(pdesc + RTL_RX_DESC_SIZE);
rtl92c_translate_rx_signal_stuff(hw, skb, stats, pdesc,
p_drvinfo);
}
/*rx_status->qual = stats->signal; */
rx_status->signal = stats->rssi + 10;
/*rx_status->noise = -stats->noise; */
return true;
}
#define RTL_RX_DRV_INFO_UNIT 8
static void _rtl_rx_process(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct ieee80211_rx_status *rx_status =
(struct ieee80211_rx_status *)IEEE80211_SKB_RXCB(skb);
u32 skb_len, pkt_len, drvinfo_len;
struct rtl_priv *rtlpriv = rtl_priv(hw);
u8 *rxdesc;
struct rtl_stats stats = {
.signal = 0,
.noise = -98,
.rate = 0,
};
struct rx_fwinfo_92c *p_drvinfo;
bool bv;
__le16 fc;
struct ieee80211_hdr *hdr;
memset(rx_status, 0, sizeof(*rx_status));
rxdesc = skb->data;
skb_len = skb->len;
drvinfo_len = (GET_RX_DESC_DRVINFO_SIZE(rxdesc) * RTL_RX_DRV_INFO_UNIT);
pkt_len = GET_RX_DESC_PKT_LEN(rxdesc);
/* TODO: Error recovery. drop this skb or something. */
WARN_ON(skb_len < (pkt_len + RTL_RX_DESC_SIZE + drvinfo_len));
stats.length = (u16) GET_RX_DESC_PKT_LEN(rxdesc);
stats.rx_drvinfo_size = (u8)GET_RX_DESC_DRVINFO_SIZE(rxdesc) *
RX_DRV_INFO_SIZE_UNIT;
stats.rx_bufshift = (u8) (GET_RX_DESC_SHIFT(rxdesc) & 0x03);
stats.icv = (u16) GET_RX_DESC_ICV(rxdesc);
stats.crc = (u16) GET_RX_DESC_CRC32(rxdesc);
stats.hwerror = (stats.crc | stats.icv);
stats.decrypted = !GET_RX_DESC_SWDEC(rxdesc);
stats.rate = (u8) GET_RX_DESC_RX_MCS(rxdesc);
stats.shortpreamble = (u16) GET_RX_DESC_SPLCP(rxdesc);
stats.isampdu = (bool) ((GET_RX_DESC_PAGGR(rxdesc) == 1)
&& (GET_RX_DESC_FAGGR(rxdesc) == 1));
stats.timestamp_low = GET_RX_DESC_TSFL(rxdesc);
stats.rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(rxdesc);
/* TODO: is center_freq changed when doing scan? */
/* TODO: Shall we add protection or just skip those two step? */
rx_status->freq = hw->conf.channel->center_freq;
rx_status->band = hw->conf.channel->band;
if (GET_RX_DESC_CRC32(rxdesc))
rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
if (!GET_RX_DESC_SWDEC(rxdesc))
rx_status->flag |= RX_FLAG_DECRYPTED;
if (GET_RX_DESC_BW(rxdesc))
rx_status->flag |= RX_FLAG_40MHZ;
if (GET_RX_DESC_RX_HT(rxdesc))
rx_status->flag |= RX_FLAG_HT;
/* Data rate */
rx_status->rate_idx = rtlwifi_rate_mapping(hw,
(bool)GET_RX_DESC_RX_HT(rxdesc),
(u8)GET_RX_DESC_RX_MCS(rxdesc),
(bool)GET_RX_DESC_PAGGR(rxdesc));
/* There is a phy status after this rx descriptor. */
if (GET_RX_DESC_PHY_STATUS(rxdesc)) {
p_drvinfo = (struct rx_fwinfo_92c *)(rxdesc + RTL_RX_DESC_SIZE);
rtl92c_translate_rx_signal_stuff(hw, skb, &stats,
(struct rx_desc_92c *)rxdesc, p_drvinfo);
}
skb_pull(skb, (drvinfo_len + RTL_RX_DESC_SIZE));
hdr = (struct ieee80211_hdr *)(skb->data);
fc = hdr->frame_control;
bv = ieee80211_is_probe_resp(fc);
if (bv)
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"Got probe response frame\n");
if (ieee80211_is_beacon(fc))
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Got beacon frame\n");
if (ieee80211_is_data(fc))
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Got data frame\n");
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"Fram: fc = 0x%X addr1 = 0x%02X:0x%02X:0x%02X:0x%02X:0x%02X:0x%02X\n",
fc,
(u32)hdr->addr1[0], (u32)hdr->addr1[1],
(u32)hdr->addr1[2], (u32)hdr->addr1[3],
(u32)hdr->addr1[4], (u32)hdr->addr1[5]);
memcpy(IEEE80211_SKB_RXCB(skb), rx_status, sizeof(*rx_status));
ieee80211_rx_irqsafe(hw, skb);
}
void rtl8192cu_rx_hdl(struct ieee80211_hw *hw, struct sk_buff * skb)
{
_rtl_rx_process(hw, skb);
}
void rtl8192c_rx_segregate_hdl(
struct ieee80211_hw *hw,
struct sk_buff *skb,
struct sk_buff_head *skb_list)
{
}
/*----------------------------------------------------------------------
*
* Tx handler
*
*---------------------------------------------------------------------- */
void rtl8192c_tx_cleanup(struct ieee80211_hw *hw, struct sk_buff *skb)
{
}
int rtl8192c_tx_post_hdl(struct ieee80211_hw *hw, struct urb *urb,
struct sk_buff *skb)
{
return 0;
}
struct sk_buff *rtl8192c_tx_aggregate_hdl(struct ieee80211_hw *hw,
struct sk_buff_head *list)
{
return skb_dequeue(list);
}
/*======================================== trx ===============================*/
static void _rtl_fill_usb_tx_desc(u8 *txdesc)
{
SET_TX_DESC_OWN(txdesc, 1);
SET_TX_DESC_LAST_SEG(txdesc, 1);
SET_TX_DESC_FIRST_SEG(txdesc, 1);
}
/**
* For HW recovery information
*/
static void _rtl_tx_desc_checksum(u8 *txdesc)
{
u16 *ptr = (u16 *)txdesc;
u16 checksum = 0;
u32 index;
/* Clear first */
SET_TX_DESC_TX_DESC_CHECKSUM(txdesc, 0);
for (index = 0; index < 16; index++)
checksum = checksum ^ (*(ptr + index));
SET_TX_DESC_TX_DESC_CHECKSUM(txdesc, cpu_to_le16(checksum));
}
void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw,
struct ieee80211_hdr *hdr, u8 *pdesc_tx,
struct ieee80211_tx_info *info, struct sk_buff *skb,
u8 queue_index,
struct rtl_tcb_desc *tcb_desc)
{
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));
bool defaultadapter = true;
struct ieee80211_sta *sta = info->control.sta = info->control.sta;
u8 *qc = ieee80211_get_qos_ctl(hdr);
u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
u16 seq_number;
__le16 fc = hdr->frame_control;
u8 rate_flag = info->control.rates[0].flags;
u16 pktlen = skb->len;
enum rtl_desc_qsel fw_qsel = _rtl8192cu_mq_to_descq(hw, fc,
skb_get_queue_mapping(skb));
u8 *txdesc;
seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
rtl_get_tcb_desc(hw, info, sta, skb, tcb_desc);
txdesc = (u8 *)skb_push(skb, RTL_TX_HEADER_SIZE);
memset(txdesc, 0, RTL_TX_HEADER_SIZE);
SET_TX_DESC_PKT_SIZE(txdesc, pktlen);
SET_TX_DESC_LINIP(txdesc, 0);
SET_TX_DESC_PKT_OFFSET(txdesc, RTL_DUMMY_OFFSET);
SET_TX_DESC_OFFSET(txdesc, RTL_TX_HEADER_SIZE);
SET_TX_DESC_TX_RATE(txdesc, tcb_desc->hw_rate);
if (tcb_desc->use_shortgi || tcb_desc->use_shortpreamble)
SET_TX_DESC_DATA_SHORTGI(txdesc, 1);
if (mac->tids[tid].agg.agg_state == RTL_AGG_ON &&
info->flags & IEEE80211_TX_CTL_AMPDU) {
SET_TX_DESC_AGG_ENABLE(txdesc, 1);
SET_TX_DESC_MAX_AGG_NUM(txdesc, 0x14);
} else {
SET_TX_DESC_AGG_BREAK(txdesc, 1);
}
SET_TX_DESC_SEQ(txdesc, seq_number);
SET_TX_DESC_RTS_ENABLE(txdesc, ((tcb_desc->rts_enable &&
!tcb_desc->cts_enable) ? 1 : 0));
SET_TX_DESC_HW_RTS_ENABLE(txdesc, ((tcb_desc->rts_enable ||
tcb_desc->cts_enable) ? 1 : 0));
SET_TX_DESC_CTS2SELF(txdesc, ((tcb_desc->cts_enable) ? 1 : 0));
SET_TX_DESC_RTS_STBC(txdesc, ((tcb_desc->rts_stbc) ? 1 : 0));
SET_TX_DESC_RTS_RATE(txdesc, tcb_desc->rts_rate);
SET_TX_DESC_RTS_BW(txdesc, 0);
SET_TX_DESC_RTS_SC(txdesc, tcb_desc->rts_sc);
SET_TX_DESC_RTS_SHORT(txdesc,
((tcb_desc->rts_rate <= DESC92_RATE54M) ?
(tcb_desc->rts_use_shortpreamble ? 1 : 0)
: (tcb_desc->rts_use_shortgi ? 1 : 0)));
if (mac->bw_40) {
if (rate_flag & IEEE80211_TX_RC_DUP_DATA) {
SET_TX_DESC_DATA_BW(txdesc, 1);
SET_TX_DESC_DATA_SC(txdesc, 3);
} else if(rate_flag & IEEE80211_TX_RC_40_MHZ_WIDTH){
SET_TX_DESC_DATA_BW(txdesc, 1);
SET_TX_DESC_DATA_SC(txdesc, mac->cur_40_prime_sc);
} else {
SET_TX_DESC_DATA_BW(txdesc, 0);
SET_TX_DESC_DATA_SC(txdesc, 0);
}
} else {
SET_TX_DESC_DATA_BW(txdesc, 0);
SET_TX_DESC_DATA_SC(txdesc, 0);
}
rcu_read_lock();
sta = ieee80211_find_sta(mac->vif, mac->bssid);
if (sta) {
u8 ampdu_density = sta->ht_cap.ampdu_density;
SET_TX_DESC_AMPDU_DENSITY(txdesc, ampdu_density);
}
rcu_read_unlock();
if (info->control.hw_key) {
struct ieee80211_key_conf *keyconf = info->control.hw_key;
switch (keyconf->cipher) {
case WLAN_CIPHER_SUITE_WEP40:
case WLAN_CIPHER_SUITE_WEP104:
case WLAN_CIPHER_SUITE_TKIP:
SET_TX_DESC_SEC_TYPE(txdesc, 0x1);
break;
case WLAN_CIPHER_SUITE_CCMP:
SET_TX_DESC_SEC_TYPE(txdesc, 0x3);
break;
default:
SET_TX_DESC_SEC_TYPE(txdesc, 0x0);
break;
}
}
SET_TX_DESC_PKT_ID(txdesc, 0);
SET_TX_DESC_QUEUE_SEL(txdesc, fw_qsel);
SET_TX_DESC_DATA_RATE_FB_LIMIT(txdesc, 0x1F);
SET_TX_DESC_RTS_RATE_FB_LIMIT(txdesc, 0xF);
SET_TX_DESC_DISABLE_FB(txdesc, 0);
SET_TX_DESC_USE_RATE(txdesc, tcb_desc->use_driver_rate ? 1 : 0);
if (ieee80211_is_data_qos(fc)) {
if (mac->rdg_en) {
RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
"Enable RDG function\n");
SET_TX_DESC_RDG_ENABLE(txdesc, 1);
SET_TX_DESC_HTC(txdesc, 1);
}
}
if (rtlpriv->dm.useramask) {
SET_TX_DESC_RATE_ID(txdesc, tcb_desc->ratr_index);
SET_TX_DESC_MACID(txdesc, tcb_desc->mac_id);
} else {
SET_TX_DESC_RATE_ID(txdesc, 0xC + tcb_desc->ratr_index);
SET_TX_DESC_MACID(txdesc, tcb_desc->ratr_index);
}
if ((!ieee80211_is_data_qos(fc)) && ppsc->leisure_ps &&
ppsc->fwctrl_lps) {
SET_TX_DESC_HWSEQ_EN(txdesc, 1);
SET_TX_DESC_PKT_ID(txdesc, 8);
if (!defaultadapter)
SET_TX_DESC_QOS(txdesc, 1);
}
if (ieee80211_has_morefrags(fc))
SET_TX_DESC_MORE_FRAG(txdesc, 1);
if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) ||
is_broadcast_ether_addr(ieee80211_get_DA(hdr)))
SET_TX_DESC_BMC(txdesc, 1);
_rtl_fill_usb_tx_desc(txdesc);
_rtl_tx_desc_checksum(txdesc);
RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "==>\n");
}
void rtl92cu_fill_fake_txdesc(struct ieee80211_hw *hw, u8 * pDesc,
u32 buffer_len, bool bIsPsPoll)
{
/* Clear all status */
memset(pDesc, 0, RTL_TX_HEADER_SIZE);
SET_TX_DESC_FIRST_SEG(pDesc, 1); /* bFirstSeg; */
SET_TX_DESC_LAST_SEG(pDesc, 1); /* bLastSeg; */
SET_TX_DESC_OFFSET(pDesc, RTL_TX_HEADER_SIZE); /* Offset = 32 */
SET_TX_DESC_PKT_SIZE(pDesc, buffer_len); /* Buffer size + command hdr */
SET_TX_DESC_QUEUE_SEL(pDesc, QSLT_MGNT); /* Fixed queue of Mgnt queue */
/* Set NAVUSEHDR to prevent Ps-poll AId filed to be changed to error
* vlaue by Hw. */
if (bIsPsPoll) {
SET_TX_DESC_NAV_USE_HDR(pDesc, 1);
} else {
SET_TX_DESC_HWSEQ_EN(pDesc, 1); /* Hw set sequence number */
SET_TX_DESC_PKT_ID(pDesc, 0x100); /* set bit3 to 1. */
}
SET_TX_DESC_USE_RATE(pDesc, 1); /* use data rate which is set by Sw */
SET_TX_DESC_OWN(pDesc, 1);
SET_TX_DESC_TX_RATE(pDesc, DESC92_RATE1M);
_rtl_tx_desc_checksum(pDesc);
}
void rtl92cu_tx_fill_cmddesc(struct ieee80211_hw *hw,
u8 *pdesc, bool firstseg,
bool lastseg, struct sk_buff *skb)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u8 fw_queue = QSLT_BEACON;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
__le16 fc = hdr->frame_control;
memset((void *)pdesc, 0, RTL_TX_HEADER_SIZE);
if (firstseg)
SET_TX_DESC_OFFSET(pdesc, RTL_TX_HEADER_SIZE);
SET_TX_DESC_TX_RATE(pdesc, DESC92_RATE1M);
SET_TX_DESC_SEQ(pdesc, 0);
SET_TX_DESC_LINIP(pdesc, 0);
SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue);
SET_TX_DESC_FIRST_SEG(pdesc, 1);
SET_TX_DESC_LAST_SEG(pdesc, 1);
SET_TX_DESC_RATE_ID(pdesc, 7);
SET_TX_DESC_MACID(pdesc, 0);
SET_TX_DESC_OWN(pdesc, 1);
SET_TX_DESC_PKT_SIZE((u8 *) pdesc, (u16) (skb->len));
SET_TX_DESC_FIRST_SEG(pdesc, 1);
SET_TX_DESC_LAST_SEG(pdesc, 1);
SET_TX_DESC_OFFSET(pdesc, 0x20);
SET_TX_DESC_USE_RATE(pdesc, 1);
if (!ieee80211_is_data_qos(fc)) {
SET_TX_DESC_HWSEQ_EN(pdesc, 1);
SET_TX_DESC_PKT_ID(pdesc, 8);
}
RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, "H2C Tx Cmd Content",
pdesc, RTL_TX_DESC_SIZE);
}
bool rtl92cu_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb)
{
return true;
}

View File

@ -0,0 +1,433 @@
/******************************************************************************
*
* Copyright(c) 2009-2012 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __RTL92CU_TRX_H__
#define __RTL92CU_TRX_H__
#define RTL92C_USB_BULK_IN_NUM 1
#define RTL92C_NUM_RX_URBS 8
#define RTL92C_NUM_TX_URBS 32
#define RTL92C_SIZE_MAX_RX_BUFFER 15360 /* 8192 */
#define RX_DRV_INFO_SIZE_UNIT 8
#define RTL_AGG_ON 1
enum usb_rx_agg_mode {
USB_RX_AGG_DISABLE,
USB_RX_AGG_DMA,
USB_RX_AGG_USB,
USB_RX_AGG_DMA_USB
};
#define TX_SELE_HQ BIT(0) /* High Queue */
#define TX_SELE_LQ BIT(1) /* Low Queue */
#define TX_SELE_NQ BIT(2) /* Normal Queue */
#define RTL_USB_TX_AGG_NUM_DESC 5
#define RTL_USB_RX_AGG_PAGE_NUM 4
#define RTL_USB_RX_AGG_PAGE_TIMEOUT 3
#define RTL_USB_RX_AGG_BLOCK_NUM 5
#define RTL_USB_RX_AGG_BLOCK_TIMEOUT 3
/*======================== rx status =========================================*/
struct rx_drv_info_92c {
/*
* Driver info contain PHY status and other variabel size info
* PHY Status content as below
*/
/* DWORD 0 */
u8 gain_trsw[4];
/* DWORD 1 */
u8 pwdb_all;
u8 cfosho[4];
/* DWORD 2 */
u8 cfotail[4];
/* DWORD 3 */
s8 rxevm[2];
s8 rxsnr[4];
/* DWORD 4 */
u8 pdsnr[2];
/* DWORD 5 */
u8 csi_current[2];
u8 csi_target[2];
/* DWORD 6 */
u8 sigevm;
u8 max_ex_pwr;
u8 ex_intf_flag:1;
u8 sgi_en:1;
u8 rxsc:2;
u8 reserve:4;
} __packed;
/* Define a macro that takes a le32 word, converts it to host ordering,
* right shifts by a specified count, creates a mask of the specified
* bit count, and extracts that number of bits.
*/
#define SHIFT_AND_MASK_LE(__pdesc, __shift, __bits) \
((le32_to_cpu(*(((__le32 *)(__pdesc)))) >> (__shift)) & \
BIT_LEN_MASK_32(__bits))
/* Define a macro that clears a bit field in an le32 word and
* sets the specified value into that bit field. The resulting
* value remains in le32 ordering; however, it is properly converted
* to host ordering for the clear and set operations before conversion
* back to le32.
*/
#define SET_BITS_OFFSET_LE(__pdesc, __shift, __len, __val) \
(*(__le32 *)(__pdesc) = \
(cpu_to_le32((le32_to_cpu(*((__le32 *)(__pdesc))) & \
(~(BIT_OFFSET_LEN_MASK_32((__shift), __len)))) | \
(((u32)(__val) & BIT_LEN_MASK_32(__len)) << (__shift)))));
/* macros to read various fields in RX descriptor */
/* DWORD 0 */
#define GET_RX_DESC_PKT_LEN(__rxdesc) \
SHIFT_AND_MASK_LE((__rxdesc), 0, 14)
#define GET_RX_DESC_CRC32(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc, 14, 1)
#define GET_RX_DESC_ICV(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc, 15, 1)
#define GET_RX_DESC_DRVINFO_SIZE(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc, 16, 4)
#define GET_RX_DESC_SECURITY(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc, 20, 3)
#define GET_RX_DESC_QOS(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc, 23, 1)
#define GET_RX_DESC_SHIFT(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc, 24, 2)
#define GET_RX_DESC_PHY_STATUS(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc, 26, 1)
#define GET_RX_DESC_SWDEC(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc, 27, 1)
#define GET_RX_DESC_LAST_SEG(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc, 28, 1)
#define GET_RX_DESC_FIRST_SEG(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc, 29, 1)
#define GET_RX_DESC_EOR(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc, 30, 1)
#define GET_RX_DESC_OWN(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc, 31, 1)
/* DWORD 1 */
#define GET_RX_DESC_MACID(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+4, 0, 5)
#define GET_RX_DESC_TID(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+4, 5, 4)
#define GET_RX_DESC_PAGGR(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+4, 14, 1)
#define GET_RX_DESC_FAGGR(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+4, 15, 1)
#define GET_RX_DESC_A1_FIT(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+4, 16, 4)
#define GET_RX_DESC_A2_FIT(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+4, 20, 4)
#define GET_RX_DESC_PAM(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+4, 24, 1)
#define GET_RX_DESC_PWR(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+4, 25, 1)
#define GET_RX_DESC_MORE_DATA(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+4, 26, 1)
#define GET_RX_DESC_MORE_FRAG(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+4, 27, 1)
#define GET_RX_DESC_TYPE(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+4, 28, 2)
#define GET_RX_DESC_MC(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+4, 30, 1)
#define GET_RX_DESC_BC(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+4, 31, 1)
/* DWORD 2 */
#define GET_RX_DESC_SEQ(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+8, 0, 12)
#define GET_RX_DESC_FRAG(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+8, 12, 4)
#define GET_RX_DESC_USB_AGG_PKTNUM(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+8, 16, 8)
#define GET_RX_DESC_NEXT_IND(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+8, 30, 1)
/* DWORD 3 */
#define GET_RX_DESC_RX_MCS(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+12, 0, 6)
#define GET_RX_DESC_RX_HT(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+12, 6, 1)
#define GET_RX_DESC_AMSDU(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+12, 7, 1)
#define GET_RX_DESC_SPLCP(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+12, 8, 1)
#define GET_RX_DESC_BW(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+12, 9, 1)
#define GET_RX_DESC_HTC(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+12, 10, 1)
#define GET_RX_DESC_TCP_CHK_RPT(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+12, 11, 1)
#define GET_RX_DESC_IP_CHK_RPT(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+12, 12, 1)
#define GET_RX_DESC_TCP_CHK_VALID(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+12, 13, 1)
#define GET_RX_DESC_HWPC_ERR(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+12, 14, 1)
#define GET_RX_DESC_HWPC_IND(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+12, 15, 1)
#define GET_RX_DESC_IV0(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+12, 16, 16)
/* DWORD 4 */
#define GET_RX_DESC_IV1(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+16, 0, 32)
/* DWORD 5 */
#define GET_RX_DESC_TSFL(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+20, 0, 32)
/*======================= tx desc ============================================*/
/* macros to set various fields in TX descriptor */
/* Dword 0 */
#define SET_TX_DESC_PKT_SIZE(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc, 0, 16, __value)
#define SET_TX_DESC_OFFSET(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc, 16, 8, __value)
#define SET_TX_DESC_BMC(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc, 24, 1, __value)
#define SET_TX_DESC_HTC(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc, 25, 1, __value)
#define SET_TX_DESC_LAST_SEG(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc, 26, 1, __value)
#define SET_TX_DESC_FIRST_SEG(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc, 27, 1, __value)
#define SET_TX_DESC_LINIP(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc, 28, 1, __value)
#define SET_TX_DESC_NO_ACM(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc, 29, 1, __value)
#define SET_TX_DESC_GF(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc, 30, 1, __value)
#define SET_TX_DESC_OWN(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc, 31, 1, __value)
/* Dword 1 */
#define SET_TX_DESC_MACID(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+4, 0, 5, __value)
#define SET_TX_DESC_AGG_ENABLE(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+4, 5, 1, __value)
#define SET_TX_DESC_AGG_BREAK(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+4, 6, 1, __value)
#define SET_TX_DESC_RDG_ENABLE(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+4, 7, 1, __value)
#define SET_TX_DESC_QUEUE_SEL(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+4, 8, 5, __value)
#define SET_TX_DESC_RDG_NAV_EXT(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+4, 13, 1, __value)
#define SET_TX_DESC_LSIG_TXOP_EN(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+4, 14, 1, __value)
#define SET_TX_DESC_PIFS(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+4, 15, 1, __value)
#define SET_TX_DESC_RATE_ID(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+4, 16, 4, __value)
#define SET_TX_DESC_RA_BRSR_ID(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+4, 16, 4, __value)
#define SET_TX_DESC_NAV_USE_HDR(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+4, 20, 1, __value)
#define SET_TX_DESC_EN_DESC_ID(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+4, 21, 1, __value)
#define SET_TX_DESC_SEC_TYPE(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+4, 22, 2, __value)
#define SET_TX_DESC_PKT_OFFSET(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+4, 26, 5, __value)
/* Dword 2 */
#define SET_TX_DESC_RTS_RC(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+8, 0, 6, __value)
#define SET_TX_DESC_DATA_RC(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+8, 6, 6, __value)
#define SET_TX_DESC_BAR_RTY_TH(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+8, 14, 2, __value)
#define SET_TX_DESC_MORE_FRAG(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+8, 17, 1, __value)
#define SET_TX_DESC_RAW(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+8, 18, 1, __value)
#define SET_TX_DESC_CCX(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+8, 19, 1, __value)
#define SET_TX_DESC_AMPDU_DENSITY(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+8, 20, 3, __value)
#define SET_TX_DESC_ANTSEL_A(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+8, 24, 1, __value)
#define SET_TX_DESC_ANTSEL_B(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+8, 25, 1, __value)
#define SET_TX_DESC_TX_ANT_CCK(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+8, 26, 2, __value)
#define SET_TX_DESC_TX_ANTL(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+8, 28, 2, __value)
#define SET_TX_DESC_TX_ANT_HT(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+8, 30, 2, __value)
/* Dword 3 */
#define SET_TX_DESC_NEXT_HEAP_PAGE(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+12, 0, 8, __value)
#define SET_TX_DESC_TAIL_PAGE(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+12, 8, 8, __value)
#define SET_TX_DESC_SEQ(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+12, 16, 12, __value)
#define SET_TX_DESC_PKT_ID(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+12, 28, 4, __value)
/* Dword 4 */
#define SET_TX_DESC_RTS_RATE(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+16, 0, 5, __value)
#define SET_TX_DESC_AP_DCFE(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+16, 5, 1, __value)
#define SET_TX_DESC_QOS(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+16, 6, 1, __value)
#define SET_TX_DESC_HWSEQ_EN(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+16, 7, 1, __value)
#define SET_TX_DESC_USE_RATE(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+16, 8, 1, __value)
#define SET_TX_DESC_DISABLE_RTS_FB(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+16, 9, 1, __value)
#define SET_TX_DESC_DISABLE_FB(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+16, 10, 1, __value)
#define SET_TX_DESC_CTS2SELF(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+16, 11, 1, __value)
#define SET_TX_DESC_RTS_ENABLE(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+16, 12, 1, __value)
#define SET_TX_DESC_HW_RTS_ENABLE(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+16, 13, 1, __value)
#define SET_TX_DESC_WAIT_DCTS(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+16, 18, 1, __value)
#define SET_TX_DESC_CTS2AP_EN(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+16, 19, 1, __value)
#define SET_TX_DESC_DATA_SC(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+16, 20, 2, __value)
#define SET_TX_DESC_DATA_STBC(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+16, 22, 2, __value)
#define SET_TX_DESC_DATA_SHORT(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+16, 24, 1, __value)
#define SET_TX_DESC_DATA_BW(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+16, 25, 1, __value)
#define SET_TX_DESC_RTS_SHORT(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+16, 26, 1, __value)
#define SET_TX_DESC_RTS_BW(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+16, 27, 1, __value)
#define SET_TX_DESC_RTS_SC(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+16, 28, 2, __value)
#define SET_TX_DESC_RTS_STBC(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+16, 30, 2, __value)
/* Dword 5 */
#define SET_TX_DESC_TX_RATE(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+20, 0, 6, __val)
#define SET_TX_DESC_DATA_SHORTGI(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+20, 6, 1, __val)
#define SET_TX_DESC_CCX_TAG(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+20, 7, 1, __val)
#define SET_TX_DESC_DATA_RATE_FB_LIMIT(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+20, 8, 5, __value)
#define SET_TX_DESC_RTS_RATE_FB_LIMIT(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+20, 13, 4, __value)
#define SET_TX_DESC_RETRY_LIMIT_ENABLE(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+20, 17, 1, __value)
#define SET_TX_DESC_DATA_RETRY_LIMIT(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+20, 18, 6, __value)
#define SET_TX_DESC_USB_TXAGG_NUM(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+20, 24, 8, __value)
/* Dword 6 */
#define SET_TX_DESC_TXAGC_A(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+24, 0, 5, __value)
#define SET_TX_DESC_TXAGC_B(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+24, 5, 5, __value)
#define SET_TX_DESC_USB_MAX_LEN(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+24, 10, 1, __value)
#define SET_TX_DESC_MAX_AGG_NUM(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+24, 11, 5, __value)
#define SET_TX_DESC_MCSG1_MAX_LEN(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+24, 16, 4, __value)
#define SET_TX_DESC_MCSG2_MAX_LEN(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+24, 20, 4, __value)
#define SET_TX_DESC_MCSG3_MAX_LEN(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+24, 24, 4, __value)
#define SET_TX_DESC_MCSG7_MAX_LEN(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+24, 28, 4, __value)
/* Dword 7 */
#define SET_TX_DESC_TX_DESC_CHECKSUM(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+28, 0, 16, __value)
#define SET_TX_DESC_MCSG4_MAX_LEN(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+28, 16, 4, __value)
#define SET_TX_DESC_MCSG5_MAX_LEN(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+28, 20, 4, __value)
#define SET_TX_DESC_MCSG6_MAX_LEN(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+28, 24, 4, __value)
#define SET_TX_DESC_MCSG15_MAX_LEN(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+28, 28, 4, __value)
int rtl8192cu_endpoint_mapping(struct ieee80211_hw *hw);
u16 rtl8192cu_mq_to_hwq(__le16 fc, u16 mac80211_queue_index);
bool rtl92cu_rx_query_desc(struct ieee80211_hw *hw,
struct rtl_stats *stats,
struct ieee80211_rx_status *rx_status,
u8 *p_desc, struct sk_buff *skb);
void rtl8192cu_rx_hdl(struct ieee80211_hw *hw, struct sk_buff * skb);
void rtl8192c_rx_segregate_hdl(struct ieee80211_hw *, struct sk_buff *,
struct sk_buff_head *);
void rtl8192c_tx_cleanup(struct ieee80211_hw *hw, struct sk_buff *skb);
int rtl8192c_tx_post_hdl(struct ieee80211_hw *hw, struct urb *urb,
struct sk_buff *skb);
struct sk_buff *rtl8192c_tx_aggregate_hdl(struct ieee80211_hw *,
struct sk_buff_head *);
void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw,
struct ieee80211_hdr *hdr, u8 *pdesc_tx,
struct ieee80211_tx_info *info, struct sk_buff *skb,
u8 queue_index,
struct rtl_tcb_desc *tcb_desc);
void rtl92cu_fill_fake_txdesc(struct ieee80211_hw *hw, u8 * pDesc,
u32 buffer_len, bool bIsPsPoll);
void rtl92cu_tx_fill_cmddesc(struct ieee80211_hw *hw,
u8 *pdesc, bool b_firstseg,
bool b_lastseg, struct sk_buff *skb);
bool rtl92cu_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb);
#endif