Resguardo inicial

This commit is contained in:
lastdragon
2026-09-06 12:53:21 -06:00
parent 662efe3c2a
commit ad2088d178
94853 changed files with 43200404 additions and 0 deletions
@@ -0,0 +1,13 @@
# SPDX-License-Identifier: GPL-2.0
rtl8192de-objs := \
dm.o \
fw.o \
hw.o \
led.o \
phy.o \
rf.o \
sw.o \
table.o \
trx.o
obj-$(CONFIG_RTL8192DE) += rtl8192de.o
@@ -0,0 +1,184 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2009-2012 Realtek Corporation.*/
#include "../wifi.h"
#include "../base.h"
#include "../core.h"
#include "../rtl8192d/reg.h"
#include "../rtl8192d/def.h"
#include "../rtl8192d/dm_common.h"
#include "../rtl8192d/phy_common.h"
#include "../rtl8192d/fw_common.h"
#include "phy.h"
#include "dm.h"
#define UNDEC_SM_PWDB entry_min_undec_sm_pwdb
static void rtl92d_dm_init_dynamic_txpower(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
rtlpriv->dm.dynamic_txpower_enable = true;
rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
}
static void rtl92d_dm_dynamic_txpower(struct ieee80211_hw *hw)
{
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));
long undec_sm_pwdb;
if ((!rtlpriv->dm.dynamic_txpower_enable)
|| rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) {
rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
return;
}
if ((mac->link_state < MAC80211_LINKED) &&
(rtlpriv->dm.UNDEC_SM_PWDB == 0)) {
rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE,
"Not connected to any\n");
rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
return;
}
if (mac->link_state >= MAC80211_LINKED) {
if (mac->opmode == NL80211_IFTYPE_ADHOC) {
undec_sm_pwdb =
rtlpriv->dm.UNDEC_SM_PWDB;
rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
"IBSS Client PWDB = 0x%lx\n",
undec_sm_pwdb);
} else {
undec_sm_pwdb =
rtlpriv->dm.undec_sm_pwdb;
rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
"STA Default Port PWDB = 0x%lx\n",
undec_sm_pwdb);
}
} else {
undec_sm_pwdb =
rtlpriv->dm.UNDEC_SM_PWDB;
rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
"AP Ext Port PWDB = 0x%lx\n",
undec_sm_pwdb);
}
if (rtlhal->current_bandtype == BAND_ON_5G) {
if (undec_sm_pwdb >= 0x33) {
rtlpriv->dm.dynamic_txhighpower_lvl =
TXHIGHPWRLEVEL_LEVEL2;
rtl_dbg(rtlpriv, COMP_HIPWR, DBG_LOUD,
"5G:TxHighPwrLevel_Level2 (TxPwr=0x0)\n");
} else if ((undec_sm_pwdb < 0x33)
&& (undec_sm_pwdb >= 0x2b)) {
rtlpriv->dm.dynamic_txhighpower_lvl =
TXHIGHPWRLEVEL_LEVEL1;
rtl_dbg(rtlpriv, COMP_HIPWR, DBG_LOUD,
"5G:TxHighPwrLevel_Level1 (TxPwr=0x10)\n");
} else if (undec_sm_pwdb < 0x2b) {
rtlpriv->dm.dynamic_txhighpower_lvl =
TXHIGHPWRLEVEL_NORMAL;
rtl_dbg(rtlpriv, COMP_HIPWR, DBG_LOUD,
"5G:TxHighPwrLevel_Normal\n");
}
} else {
if (undec_sm_pwdb >=
TX_POWER_NEAR_FIELD_THRESH_LVL2) {
rtlpriv->dm.dynamic_txhighpower_lvl =
TXHIGHPWRLEVEL_LEVEL2;
rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
"TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n");
} else
if ((undec_sm_pwdb <
(TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3))
&& (undec_sm_pwdb >=
TX_POWER_NEAR_FIELD_THRESH_LVL1)) {
rtlpriv->dm.dynamic_txhighpower_lvl =
TXHIGHPWRLEVEL_LEVEL1;
rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
"TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n");
} else if (undec_sm_pwdb <
(TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) {
rtlpriv->dm.dynamic_txhighpower_lvl =
TXHIGHPWRLEVEL_NORMAL;
rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
"TXHIGHPWRLEVEL_NORMAL\n");
}
}
if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) {
rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
"PHY_SetTxPowerLevel8192S() Channel = %d\n",
rtlphy->current_channel);
rtl92d_phy_set_txpower_level(hw, rtlphy->current_channel);
}
rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
}
static void rtl92d_dm_pwdb_monitor(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
/* AP & ADHOC & MESH will return tmp */
if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION)
return;
/* Indicate Rx signal strength to FW. */
if (rtlpriv->dm.useramask) {
u32 temp = rtlpriv->dm.undec_sm_pwdb;
temp <<= 16;
temp |= 0x100;
/* fw v12 cmdid 5:use max macid ,for nic ,
* default macid is 0 ,max macid is 1 */
rtl92d_fill_h2c_cmd(hw, H2C_RSSI_REPORT, 3, (u8 *) (&temp));
} else {
rtl_write_byte(rtlpriv, 0x4fe,
(u8) rtlpriv->dm.undec_sm_pwdb);
}
}
void rtl92de_dm_init(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
rtl_dm_diginit(hw, 0x20);
rtlpriv->dm_digtable.rx_gain_max = DM_DIG_FA_UPPER;
rtlpriv->dm_digtable.rx_gain_min = DM_DIG_FA_LOWER;
rtl92d_dm_init_dynamic_txpower(hw);
rtl92d_dm_init_edca_turbo(hw);
rtl92d_dm_init_rate_adaptive_mask(hw);
rtl92d_dm_initialize_txpower_tracking(hw);
}
void rtl92de_dm_watchdog(struct ieee80211_hw *hw)
{
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
bool fw_current_inpsmode = false;
bool fwps_awake = true;
/* 1. RF is OFF. (No need to do DM.)
* 2. Fw is under power saving mode for FwLPS.
* (Prevent from SW/FW I/O racing.)
* 3. IPS workitem is scheduled. (Prevent from IPS sequence
* to be swapped with DM.
* 4. RFChangeInProgress is TRUE.
* (Prevent from broken by IPS/HW/SW Rf off.) */
if ((ppsc->rfpwr_state == ERFON) && ((!fw_current_inpsmode) &&
fwps_awake) && (!ppsc->rfchange_inprogress)) {
rtl92d_dm_pwdb_monitor(hw);
rtl92d_dm_false_alarm_counter_statistics(hw);
rtl92d_dm_find_minimum_rssi(hw);
rtl92d_dm_dig(hw);
/* rtl92d_dm_dynamic_bb_powersaving(hw); */
rtl92d_dm_dynamic_txpower(hw);
/* rtl92d_dm_check_txpower_tracking_thermal_meter(hw); */
/* rtl92d_dm_refresh_rate_adaptive_mask(hw); */
/* rtl92d_dm_interrupt_migration(hw); */
rtl92d_dm_check_edca_turbo(hw);
}
}
@@ -0,0 +1,10 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 2009-2012 Realtek Corporation.*/
#ifndef __RTL92C_DM_H__
#define __RTL92C_DM_H__
void rtl92de_dm_init(struct ieee80211_hw *hw);
void rtl92de_dm_watchdog(struct ieee80211_hw *hw);
#endif
@@ -0,0 +1,320 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2009-2012 Realtek Corporation.*/
#include "../wifi.h"
#include "../pci.h"
#include "../base.h"
#include "../efuse.h"
#include "../rtl8192d/reg.h"
#include "../rtl8192d/def.h"
#include "../rtl8192d/fw_common.h"
#include "fw.h"
#include "sw.h"
int rtl92d_download_fw(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
u8 *pfwheader;
u8 *pfwdata;
u32 fwsize;
int err;
enum version_8192d version = rtlhal->version;
u8 value;
u32 count;
bool fw_downloaded = false, fwdl_in_process = false;
unsigned long flags;
if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware)
return 1;
fwsize = rtlhal->fwsize;
pfwheader = rtlhal->pfirmware;
pfwdata = rtlhal->pfirmware;
rtlhal->fw_version = (u16) GET_FIRMWARE_HDR_VERSION(pfwheader);
rtlhal->fw_subversion = (u16) GET_FIRMWARE_HDR_SUB_VER(pfwheader);
rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
"FirmwareVersion(%d), FirmwareSubVersion(%d), Signature(%#x)\n",
rtlhal->fw_version, rtlhal->fw_subversion,
GET_FIRMWARE_HDR_SIGNATURE(pfwheader));
if (IS_FW_HEADER_EXIST(pfwheader)) {
rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
"Shift 32 bytes for FW header!!\n");
pfwdata = pfwdata + 32;
fwsize = fwsize - 32;
}
spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
fw_downloaded = rtl92d_is_fw_downloaded(rtlpriv);
if ((rtl_read_byte(rtlpriv, 0x1f) & BIT(5)) == BIT(5))
fwdl_in_process = true;
else
fwdl_in_process = false;
if (fw_downloaded) {
spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
goto exit;
} else if (fwdl_in_process) {
spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
for (count = 0; count < 5000; count++) {
udelay(500);
spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
fw_downloaded = rtl92d_is_fw_downloaded(rtlpriv);
if ((rtl_read_byte(rtlpriv, 0x1f) & BIT(5)) == BIT(5))
fwdl_in_process = true;
else
fwdl_in_process = false;
spin_unlock_irqrestore(&globalmutex_for_fwdownload,
flags);
if (fw_downloaded)
goto exit;
else if (!fwdl_in_process)
break;
else
rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
"Wait for another mac download fw\n");
}
spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
value = rtl_read_byte(rtlpriv, 0x1f);
value |= BIT(5);
rtl_write_byte(rtlpriv, 0x1f, value);
spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
} else {
value = rtl_read_byte(rtlpriv, 0x1f);
value |= BIT(5);
rtl_write_byte(rtlpriv, 0x1f, value);
spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
}
/* If 8051 is running in RAM code, driver should
* inform Fw to reset by itself, or it will cause
* download Fw fail.*/
/* 8051 RAM code */
if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) {
rtl92d_firmware_selfreset(hw);
rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
}
rtl92d_enable_fw_download(hw, true);
rtl92d_write_fw(hw, version, pfwdata, fwsize);
rtl92d_enable_fw_download(hw, false);
spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
err = rtl92d_fw_free_to_go(hw);
/* download fw over,clear 0x1f[5] */
value = rtl_read_byte(rtlpriv, 0x1f);
value &= (~BIT(5));
rtl_write_byte(rtlpriv, 0x1f, value);
spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
if (err)
pr_err("fw is not ready to run!\n");
exit:
err = rtl92d_fw_init(hw);
return err;
}
static bool _rtl92d_cmd_send_packet(struct ieee80211_hw *hw,
struct sk_buff *skb)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
struct rtl8192_tx_ring *ring;
struct rtl_tx_desc *pdesc;
u8 idx = 0;
unsigned long flags;
struct sk_buff *pskb;
ring = &rtlpci->tx_ring[BEACON_QUEUE];
pskb = __skb_dequeue(&ring->queue);
kfree_skb(pskb);
spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
pdesc = &ring->desc[idx];
/* discard output from call below */
rtlpriv->cfg->ops->get_desc(hw, (u8 *)pdesc, true, HW_DESC_OWN);
rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *)pdesc, skb);
__skb_queue_tail(&ring->queue, skb);
spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
return true;
}
#define BEACON_PG 0 /*->1 */
#define PSPOLL_PG 2
#define NULL_PG 3
#define PROBERSP_PG 4 /*->5 */
#define TOTAL_RESERVED_PKT_LEN 768
static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
/* page 0 beacon */
0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* page 1 beacon */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* page 2 ps-poll */
0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10,
0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* page 3 null */
0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* page 4 probe_resp */
0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* page 5 probe_resp */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
void rtl92d_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
struct sk_buff *skb = NULL;
u32 totalpacketlen;
bool rtstatus;
u8 u1rsvdpageloc[3] = { PROBERSP_PG, PSPOLL_PG, NULL_PG };
bool dlok = false;
u8 *beacon;
u8 *p_pspoll;
u8 *nullfunc;
u8 *p_probersp;
/*---------------------------------------------------------
(1) beacon
---------------------------------------------------------*/
beacon = &reserved_page_packet[BEACON_PG * 128];
SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
/*-------------------------------------------------------
(2) ps-poll
--------------------------------------------------------*/
p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
/*--------------------------------------------------------
(3) null data
---------------------------------------------------------*/
nullfunc = &reserved_page_packet[NULL_PG * 128];
SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
/*---------------------------------------------------------
(4) probe response
----------------------------------------------------------*/
p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
totalpacketlen = TOTAL_RESERVED_PKT_LEN;
RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
"rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL",
&reserved_page_packet[0], totalpacketlen);
RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
"rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL",
u1rsvdpageloc, 3);
skb = dev_alloc_skb(totalpacketlen);
if (!skb) {
dlok = false;
} else {
skb_put_data(skb, &reserved_page_packet, totalpacketlen);
rtstatus = _rtl92d_cmd_send_packet(hw, skb);
if (rtstatus)
dlok = true;
}
if (dlok) {
rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
"Set RSVD page location to Fw\n");
RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
"H2C_RSVDPAGE", u1rsvdpageloc, 3);
rtl92d_fill_h2c_cmd(hw, H2C_RSVDPAGE,
sizeof(u1rsvdpageloc), u1rsvdpageloc);
} else
rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
"Set RSVD page location to Fw FAIL!!!!!!\n");
}
@@ -0,0 +1,10 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 2009-2012 Realtek Corporation.*/
#ifndef __RTL92D__FW__H__
#define __RTL92D__FW__H__
int rtl92d_download_fw(struct ieee80211_hw *hw);
void rtl92d_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished);
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,29 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 2009-2012 Realtek Corporation.*/
#ifndef __RTL92DE_HW_H__
#define __RTL92DE_HW_H__
void rtl92de_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
void rtl92de_interrupt_recognized(struct ieee80211_hw *hw,
struct rtl_int *int_vec);
int rtl92de_hw_init(struct ieee80211_hw *hw);
void rtl92de_card_disable(struct ieee80211_hw *hw);
void rtl92de_enable_interrupt(struct ieee80211_hw *hw);
void rtl92de_disable_interrupt(struct ieee80211_hw *hw);
int rtl92de_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type);
void rtl92de_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid);
void rtl92de_set_beacon_related_registers(struct ieee80211_hw *hw);
void rtl92de_set_beacon_interval(struct ieee80211_hw *hw);
void rtl92de_update_interrupt_mask(struct ieee80211_hw *hw,
u32 add_msr, u32 rm_msr);
void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
void rtl92de_write_dword_dbi(struct ieee80211_hw *hw, u16 offset, u32 value,
u8 direct);
u32 rtl92de_read_dword_dbi(struct ieee80211_hw *hw, u16 offset, u8 direct);
void rtl92de_suspend(struct ieee80211_hw *hw);
void rtl92de_resume(struct ieee80211_hw *hw);
void rtl92d_linked_set_reg(struct ieee80211_hw *hw);
#endif
@@ -0,0 +1,114 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2009-2012 Realtek Corporation.*/
#include "../wifi.h"
#include "../pci.h"
#include "../rtl8192d/reg.h"
#include "led.h"
void rtl92de_sw_led_on(struct ieee80211_hw *hw, enum rtl_led_pin pin)
{
u8 ledcfg;
struct rtl_priv *rtlpriv = rtl_priv(hw);
rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n",
REG_LEDCFG2, pin);
switch (pin) {
case LED_PIN_GPIO0:
break;
case LED_PIN_LED0:
ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
if ((rtlpriv->efuse.eeprom_did == 0x8176) ||
(rtlpriv->efuse.eeprom_did == 0x8193))
/* BIT7 of REG_LEDCFG2 should be set to
* make sure we could emit the led2. */
rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0xf0) |
BIT(7) | BIT(5) | BIT(6));
else
rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0xf0) |
BIT(7) | BIT(5));
break;
case LED_PIN_LED1:
ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1);
rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0x0f) | BIT(5));
break;
default:
pr_err("switch case %#x not processed\n", pin);
break;
}
}
void rtl92de_sw_led_off(struct ieee80211_hw *hw, enum rtl_led_pin pin)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u8 ledcfg;
rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n",
REG_LEDCFG2, pin);
ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
switch (pin) {
case LED_PIN_GPIO0:
break;
case LED_PIN_LED0:
ledcfg &= 0xf0;
if (rtlpriv->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:
pr_err("switch case %#x not processed\n", pin);
break;
}
}
static void _rtl92ce_sw_led_control(struct ieee80211_hw *hw,
enum led_ctl_mode ledaction)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
enum rtl_led_pin pin0 = rtlpriv->ledctl.sw_led0;
switch (ledaction) {
case LED_CTL_POWER_ON:
case LED_CTL_LINK:
case LED_CTL_NO_LINK:
rtl92de_sw_led_on(hw, pin0);
break;
case LED_CTL_POWER_OFF:
rtl92de_sw_led_off(hw, pin0);
break;
default:
break;
}
}
void rtl92de_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;
}
rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d,\n", ledaction);
_rtl92ce_sw_led_control(hw, ledaction);
}
@@ -0,0 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 2009-2012 Realtek Corporation.*/
#ifndef __RTL92CE_LED_H__
#define __RTL92CE_LED_H__
void rtl92de_sw_led_on(struct ieee80211_hw *hw, enum rtl_led_pin pin);
void rtl92de_sw_led_off(struct ieee80211_hw *hw, enum rtl_led_pin pin);
void rtl92de_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction);
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,89 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 2009-2012 Realtek Corporation.*/
#ifndef __RTL92D_PHY_H__
#define __RTL92D_PHY_H__
#define MAX_PRECMD_CNT 16
#define MAX_RFDEPENDCMD_CNT 16
#define MAX_POSTCMD_CNT 16
#define MAX_DOZE_WAITING_TIMES_9x 64
#define HIGHPOWER_RADIOA_ARRAYLEN 22
#define APK_BB_REG_NUM 5
#define APK_AFE_REG_NUM 16
#define APK_CURVE_REG_NUM 4
#define PATH_NUM 2
#define LOOP_LIMIT 5
#define MAX_STALL_TIME 50
#define ANTENNA_DIVERSITY_VALUE 0x80
#define MAX_TXPWR_IDX_NMODE_92S 63
#define RESET_CNT_LIMIT 3
#define IQK_ADDA_REG_NUM 16
#define IQK_BB_REG_NUM_test 6
#define IQK_MAC_REG_NUM 4
#define CT_OFFSET_MAC_ADDR 0X16
#define CT_OFFSET_CCK_TX_PWR_IDX 0x5A
#define CT_OFFSET_HT401S_TX_PWR_IDX 0x60
#define CT_OFFSET_HT402S_TX_PWR_IDX_DIFF 0x66
#define CT_OFFSET_HT20_TX_PWR_IDX_DIFF 0x69
#define CT_OFFSET_OFDM_TX_PWR_IDX_DIFF 0x6C
#define CT_OFFSET_HT40_MAX_PWR_OFFSET 0x6F
#define CT_OFFSET_HT20_MAX_PWR_OFFSET 0x72
#define CT_OFFSET_CHANNEL_PLAH 0x75
#define CT_OFFSET_THERMAL_METER 0x78
#define CT_OFFSET_RF_OPTION 0x79
#define CT_OFFSET_VERSION 0x7E
#define CT_OFFSET_CUSTOMER_ID 0x7F
enum swchnlcmd_id {
CMDID_END,
CMDID_SET_TXPOWEROWER_LEVEL,
CMDID_BBREGWRITE10,
CMDID_WRITEPORT_ULONG,
CMDID_WRITEPORT_USHORT,
CMDID_WRITEPORT_UCHAR,
CMDID_RF_WRITEREG,
};
struct swchnlcmd {
enum swchnlcmd_id cmdid;
u32 para1;
u32 para2;
u32 msdelay;
};
u32 rtl92d_phy_query_bb_reg(struct ieee80211_hw *hw,
u32 regaddr, u32 bitmask);
void rtl92d_phy_set_bb_reg(struct ieee80211_hw *hw,
u32 regaddr, u32 bitmask, u32 data);
bool rtl92d_phy_mac_config(struct ieee80211_hw *hw);
bool rtl92d_phy_bb_config(struct ieee80211_hw *hw);
bool rtl92d_phy_rf_config(struct ieee80211_hw *hw);
bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw,
enum radio_path rfpath);
void rtl92d_phy_set_bw_mode(struct ieee80211_hw *hw,
enum nl80211_channel_type ch_type);
u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw);
bool rtl92d_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
enum rf_content content,
enum radio_path rfpath);
bool rtl92d_phy_set_rf_power_state(struct ieee80211_hw *hw,
enum rf_pwrstate rfpwr_state);
void rtl92d_phy_set_poweron(struct ieee80211_hw *hw);
bool rtl92d_phy_check_poweroff(struct ieee80211_hw *hw);
void rtl92d_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t);
void rtl92d_update_bbrf_configuration(struct ieee80211_hw *hw);
void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw);
void rtl92d_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel);
#endif
@@ -0,0 +1,227 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2009-2012 Realtek Corporation.*/
#include "../wifi.h"
#include "../rtl8192d/reg.h"
#include "../rtl8192d/def.h"
#include "../rtl8192d/phy_common.h"
#include "phy.h"
#include "rf.h"
#include "dm.h"
#include "hw.h"
bool rtl92d_phy_enable_anotherphy(struct ieee80211_hw *hw, bool bmac0)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
u8 u1btmp;
u8 direct = bmac0 ? BIT(3) | BIT(2) : BIT(3);
u8 mac_reg = bmac0 ? REG_MAC1 : REG_MAC0;
u8 mac_on_bit = bmac0 ? MAC1_ON : MAC0_ON;
bool bresult = true; /* true: need to enable BB/RF power */
rtlhal->during_mac0init_radiob = false;
rtlhal->during_mac1init_radioa = false;
rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, "===>\n");
/* MAC0 Need PHY1 load radio_b.txt . Driver use DBI to write. */
u1btmp = rtl_read_byte(rtlpriv, mac_reg);
if (!(u1btmp & mac_on_bit)) {
rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "enable BB & RF\n");
/* Enable BB and RF power */
rtl92de_write_dword_dbi(hw, REG_SYS_ISO_CTRL,
rtl92de_read_dword_dbi(hw, REG_SYS_ISO_CTRL, direct) |
BIT(29) | BIT(16) | BIT(17), direct);
} else {
/* We think if MAC1 is ON,then radio_a.txt
* and radio_b.txt has been load. */
bresult = false;
}
rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, "<===\n");
return bresult;
}
void rtl92d_phy_powerdown_anotherphy(struct ieee80211_hw *hw, bool bmac0)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
u8 u1btmp;
u8 direct = bmac0 ? BIT(3) | BIT(2) : BIT(3);
u8 mac_reg = bmac0 ? REG_MAC1 : REG_MAC0;
u8 mac_on_bit = bmac0 ? MAC1_ON : MAC0_ON;
rtlhal->during_mac0init_radiob = false;
rtlhal->during_mac1init_radioa = false;
rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, "====>\n");
/* check MAC0 enable or not again now, if
* enabled, not power down radio A. */
u1btmp = rtl_read_byte(rtlpriv, mac_reg);
if (!(u1btmp & mac_on_bit)) {
rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "power down\n");
/* power down RF radio A according to YuNan's advice. */
rtl92de_write_dword_dbi(hw, RFPGA0_XA_LSSIPARAMETER,
0x00000000, direct);
}
rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, "<====\n");
}
bool rtl92d_phy_rf6052_config(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
bool rtstatus = true;
struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
u32 u4_regvalue = 0;
u8 rfpath;
struct bb_reg_def *pphyreg;
bool mac1_initradioa_first = false, mac0_initradiob_first = false;
bool need_pwrdown_radioa = false, need_pwrdown_radiob = false;
bool true_bpath = false;
if (rtlphy->rf_type == RF_1T1R)
rtlphy->num_total_rfpath = 1;
else
rtlphy->num_total_rfpath = 2;
/* Single phy mode: use radio_a radio_b config path_A path_B */
/* separately by MAC0, and MAC1 needn't configure RF; */
/* Dual PHY mode:MAC0 use radio_a config 1st phy path_A, */
/* MAC1 use radio_b config 2nd PHY path_A. */
/* DMDP,MAC0 on G band,MAC1 on A band. */
if (rtlhal->macphymode == DUALMAC_DUALPHY) {
if (rtlhal->current_bandtype == BAND_ON_2_4G &&
rtlhal->interfaceindex == 0) {
/* MAC0 needs PHY1 load radio_b.txt.
* Driver use DBI to write. */
if (rtl92d_phy_enable_anotherphy(hw, true)) {
rtlphy->num_total_rfpath = 2;
mac0_initradiob_first = true;
} else {
/* We think if MAC1 is ON,then radio_a.txt and
* radio_b.txt has been load. */
return rtstatus;
}
} else if (rtlhal->current_bandtype == BAND_ON_5G &&
rtlhal->interfaceindex == 1) {
/* MAC1 needs PHY0 load radio_a.txt.
* Driver use DBI to write. */
if (rtl92d_phy_enable_anotherphy(hw, false)) {
rtlphy->num_total_rfpath = 2;
mac1_initradioa_first = true;
} else {
/* We think if MAC0 is ON,then radio_a.txt and
* radio_b.txt has been load. */
return rtstatus;
}
} else if (rtlhal->interfaceindex == 1) {
/* MAC0 enabled, only init radia B. */
true_bpath = true;
}
}
for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) {
/* Mac1 use PHY0 write */
if (mac1_initradioa_first) {
if (rfpath == RF90_PATH_A) {
rtlhal->during_mac1init_radioa = true;
need_pwrdown_radioa = true;
} else if (rfpath == RF90_PATH_B) {
rtlhal->during_mac1init_radioa = false;
mac1_initradioa_first = false;
rfpath = RF90_PATH_A;
true_bpath = true;
rtlphy->num_total_rfpath = 1;
}
} else if (mac0_initradiob_first) {
/* Mac0 use PHY1 write */
if (rfpath == RF90_PATH_A)
rtlhal->during_mac0init_radiob = false;
if (rfpath == RF90_PATH_B) {
rtlhal->during_mac0init_radiob = true;
mac0_initradiob_first = false;
need_pwrdown_radiob = true;
rfpath = RF90_PATH_A;
true_bpath = true;
rtlphy->num_total_rfpath = 1;
}
}
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);
/* Set bit number of Address and Data for RF register */
/* Set 1 to 4 bits for 8255 */
rtl_set_bbreg(hw, pphyreg->rfhssi_para2,
B3WIREADDRESSLENGTH, 0x0);
udelay(1);
/* Set 0 to 12 bits for 8255 */
rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0);
udelay(1);
switch (rfpath) {
case RF90_PATH_A:
if (true_bpath)
rtstatus = rtl92d_phy_config_rf_with_headerfile(
hw, radiob_txt,
(enum radio_path)rfpath);
else
rtstatus = rtl92d_phy_config_rf_with_headerfile(
hw, radioa_txt,
(enum radio_path)rfpath);
break;
case RF90_PATH_B:
rtstatus =
rtl92d_phy_config_rf_with_headerfile(hw, radiob_txt,
(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) {
rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
"Radio[%d] Fail!!\n", rfpath);
goto phy_rf_cfg_fail;
}
}
/* check MAC0 enable or not again, if enabled,
* not power down radio A. */
/* check MAC1 enable or not again, if enabled,
* not power down radio B. */
if (need_pwrdown_radioa)
rtl92d_phy_powerdown_anotherphy(hw, false);
else if (need_pwrdown_radiob)
rtl92d_phy_powerdown_anotherphy(hw, true);
rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "<---\n");
return rtstatus;
phy_rf_cfg_fail:
return rtstatus;
}
@@ -0,0 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 2009-2012 Realtek Corporation.*/
#ifndef __RTL92D_RF_H__
#define __RTL92D_RF_H__
bool rtl92d_phy_rf6052_config(struct ieee80211_hw *hw);
bool rtl92d_phy_enable_anotherphy(struct ieee80211_hw *hw, bool bmac0);
void rtl92d_phy_powerdown_anotherphy(struct ieee80211_hw *hw, bool bmac0);
#endif
@@ -0,0 +1,397 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2009-2012 Realtek Corporation.*/
#include "../wifi.h"
#include "../core.h"
#include "../pci.h"
#include "../base.h"
#include "../rtl8192d/reg.h"
#include "../rtl8192d/def.h"
#include "../rtl8192d/dm_common.h"
#include "../rtl8192d/hw_common.h"
#include "../rtl8192d/phy_common.h"
#include "../rtl8192d/trx_common.h"
#include "phy.h"
#include "dm.h"
#include "hw.h"
#include "sw.h"
#include "trx.h"
#include "led.h"
#include <linux/module.h>
static void rtl92d_init_aspm_vars(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
/*
* ASPM PS mode.
* 0 - Disable ASPM,
* 1 - Enable ASPM without Clock Req,
* 2 - Enable ASPM with Clock Req,
* 3 - Alwyas Enable ASPM with Clock Req,
* 4 - Always Enable ASPM without Clock Req.
* set default to RTL8192CE:3 RTL8192E:2
* */
rtlpci->const_pci_aspm = 3;
/*Setting for PCI-E device */
rtlpci->const_devicepci_aspm_setting = 0x03;
/*Setting for PCI-E bridge */
rtlpci->const_hostpci_aspm_setting = 0x02;
/*
* In Hw/Sw Radio Off situation.
* 0 - Default,
* 1 - From ASPM setting without low Mac Pwr,
* 2 - From ASPM setting with low Mac Pwr,
* 3 - Bus D3
* set default to RTL8192CE:0 RTL8192SE:2
*/
rtlpci->const_hwsw_rfoff_d3 = 0;
/*
* This setting works for those device with
* backdoor ASPM setting such as EPHY setting.
* 0 - Not support ASPM,
* 1 - Support ASPM,
* 2 - According to chipset.
*/
rtlpci->const_support_pciaspm = rtlpriv->cfg->mod_params->aspm_support;
}
static int rtl92d_init_sw_vars(struct ieee80211_hw *hw)
{
int err;
u8 tid;
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
char *fw_name = "rtlwifi/rtl8192defw.bin";
rtlpriv->dm.dm_initialgain_enable = true;
rtlpriv->dm.dm_flag = 0;
rtlpriv->dm.disable_framebursting = false;
rtlpriv->dm.thermalvalue = 0;
rtlpriv->dm.useramask = true;
/* dual mac */
if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G)
rtlpriv->phy.current_channel = 36;
else
rtlpriv->phy.current_channel = 1;
if (rtlpriv->rtlhal.macphymode != SINGLEMAC_SINGLEPHY) {
rtlpriv->rtlhal.disable_amsdu_8k = true;
/* No long RX - reduce fragmentation */
rtlpci->rxbuffersize = 4096;
}
rtlpci->transmit_config = CFENDFORM | BIT(12) | BIT(13);
rtlpci->receive_config = (
RCR_APPFCS
| RCR_AMF
| RCR_ADF
| RCR_APP_MIC
| RCR_APP_ICV
| RCR_AICV
| RCR_ACRC32
| RCR_AB
| RCR_AM
| RCR_APM
| RCR_APP_PHYST_RXFF
| RCR_HTC_LOC_CTRL
);
rtlpci->irq_mask[0] = (u32) (
IMR_ROK
| IMR_VODOK
| IMR_VIDOK
| IMR_BEDOK
| IMR_BKDOK
| IMR_MGNTDOK
| IMR_HIGHDOK
| IMR_BDOK
| IMR_RDU
| IMR_RXFOVW
);
rtlpci->irq_mask[1] = (u32) (IMR_CPWM | IMR_C2HCMD);
/* for LPS & IPS */
rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps;
if (!rtlpriv->psc.inactiveps)
pr_info("Power Save off (module option)\n");
if (!rtlpriv->psc.fwctrl_lps)
pr_info("FW Power Save off (module option)\n");
rtlpriv->psc.reg_fwctrl_lps = 3;
rtlpriv->psc.reg_max_lps_awakeintvl = 5;
/* for ASPM, you can close aspm through
* set const_support_pciaspm = 0 */
rtl92d_init_aspm_vars(hw);
if (rtlpriv->psc.reg_fwctrl_lps == 1)
rtlpriv->psc.fwctrl_psmode = FW_PS_MIN_MODE;
else if (rtlpriv->psc.reg_fwctrl_lps == 2)
rtlpriv->psc.fwctrl_psmode = FW_PS_MAX_MODE;
else if (rtlpriv->psc.reg_fwctrl_lps == 3)
rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE;
/* for early mode */
rtlpriv->rtlhal.earlymode_enable = false;
for (tid = 0; tid < 8; tid++)
skb_queue_head_init(&rtlpriv->mac80211.skb_waitq[tid]);
/* for firmware buf */
rtlpriv->rtlhal.pfirmware = vzalloc(0x8000);
if (!rtlpriv->rtlhal.pfirmware) {
pr_err("Can't alloc buffer for fw\n");
return 1;
}
rtlpriv->max_fw_size = 0x8000;
pr_info("Driver for Realtek RTL8192DE WLAN interface\n");
pr_info("Loading firmware file %s\n", fw_name);
/* request fw */
err = request_firmware_nowait(THIS_MODULE, 1, fw_name,
rtlpriv->io.dev, GFP_KERNEL, hw,
rtl_fw_cb);
if (err) {
pr_err("Failed to request firmware!\n");
vfree(rtlpriv->rtlhal.pfirmware);
rtlpriv->rtlhal.pfirmware = NULL;
return 1;
}
return 0;
}
static void rtl92d_deinit_sw_vars(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u8 tid;
if (rtlpriv->rtlhal.pfirmware) {
vfree(rtlpriv->rtlhal.pfirmware);
rtlpriv->rtlhal.pfirmware = NULL;
}
for (tid = 0; tid < 8; tid++)
skb_queue_purge(&rtlpriv->mac80211.skb_waitq[tid]);
}
static const struct rtl_hal_ops rtl8192de_hal_ops = {
.init_sw_vars = rtl92d_init_sw_vars,
.deinit_sw_vars = rtl92d_deinit_sw_vars,
.read_eeprom_info = rtl92d_read_eeprom_info,
.interrupt_recognized = rtl92de_interrupt_recognized,
.hw_init = rtl92de_hw_init,
.hw_disable = rtl92de_card_disable,
.hw_suspend = rtl92de_suspend,
.hw_resume = rtl92de_resume,
.enable_interrupt = rtl92de_enable_interrupt,
.disable_interrupt = rtl92de_disable_interrupt,
.set_network_type = rtl92de_set_network_type,
.set_chk_bssid = rtl92de_set_check_bssid,
.set_qos = rtl92d_set_qos,
.set_bcn_reg = rtl92de_set_beacon_related_registers,
.set_bcn_intv = rtl92de_set_beacon_interval,
.update_interrupt_mask = rtl92de_update_interrupt_mask,
.get_hw_reg = rtl92de_get_hw_reg,
.set_hw_reg = rtl92de_set_hw_reg,
.update_rate_tbl = rtl92d_update_hal_rate_tbl,
.fill_tx_desc = rtl92de_tx_fill_desc,
.fill_tx_cmddesc = rtl92de_tx_fill_cmddesc,
.query_rx_desc = rtl92d_rx_query_desc,
.set_channel_access = rtl92d_update_channel_access_setting,
.radio_onoff_checking = rtl92d_gpio_radio_on_off_checking,
.set_bw_mode = rtl92d_phy_set_bw_mode,
.switch_channel = rtl92d_phy_sw_chnl,
.dm_watchdog = rtl92de_dm_watchdog,
.scan_operation_backup = rtl_phy_scan_operation_backup,
.set_rf_power_state = rtl92d_phy_set_rf_power_state,
.led_control = rtl92de_led_control,
.set_desc = rtl92d_set_desc,
.get_desc = rtl92d_get_desc,
.is_tx_desc_closed = rtl92de_is_tx_desc_closed,
.tx_polling = rtl92de_tx_polling,
.enable_hw_sec = rtl92d_enable_hw_security_config,
.set_key = rtl92d_set_key,
.get_bbreg = rtl92d_phy_query_bb_reg,
.set_bbreg = rtl92d_phy_set_bb_reg,
.get_rfreg = rtl92d_phy_query_rf_reg,
.set_rfreg = rtl92d_phy_set_rf_reg,
.linked_set_reg = rtl92d_linked_set_reg,
.get_btc_status = rtl_btc_status_false,
.phy_iq_calibrate = rtl92d_phy_iq_calibrate,
.phy_lc_calibrate = rtl92d_phy_lc_calibrate,
};
static struct rtl_mod_params rtl92de_mod_params = {
.sw_crypto = false,
.inactiveps = true,
.swctrl_lps = true,
.fwctrl_lps = false,
.aspm_support = 1,
.debug_level = 0,
.debug_mask = 0,
};
static const struct rtl_hal_cfg rtl92de_hal_cfg = {
.bar_id = 2,
.write_readback = true,
.name = "rtl8192de",
.ops = &rtl8192de_hal_ops,
.mod_params = &rtl92de_mod_params,
.maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL,
.maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN,
.maps[SYS_CLK] = REG_SYS_CLKR,
.maps[MAC_RCR_AM] = RCR_AM,
.maps[MAC_RCR_AB] = RCR_AB,
.maps[MAC_RCR_ACRC32] = RCR_ACRC32,
.maps[MAC_RCR_ACF] = RCR_ACF,
.maps[MAC_RCR_AAP] = RCR_AAP,
.maps[EFUSE_TEST] = REG_EFUSE_TEST,
.maps[EFUSE_CTRL] = REG_EFUSE_CTRL,
.maps[EFUSE_CLK] = 0, /* just for 92se */
.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] = 0, /* just for 92se */
.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] = DESC_RATE1M,
.maps[RTL_RC_CCK_RATE2M] = DESC_RATE2M,
.maps[RTL_RC_CCK_RATE5_5M] = DESC_RATE5_5M,
.maps[RTL_RC_CCK_RATE11M] = DESC_RATE11M,
.maps[RTL_RC_OFDM_RATE6M] = DESC_RATE6M,
.maps[RTL_RC_OFDM_RATE9M] = DESC_RATE9M,
.maps[RTL_RC_OFDM_RATE12M] = DESC_RATE12M,
.maps[RTL_RC_OFDM_RATE18M] = DESC_RATE18M,
.maps[RTL_RC_OFDM_RATE24M] = DESC_RATE24M,
.maps[RTL_RC_OFDM_RATE36M] = DESC_RATE36M,
.maps[RTL_RC_OFDM_RATE48M] = DESC_RATE48M,
.maps[RTL_RC_OFDM_RATE54M] = DESC_RATE54M,
.maps[RTL_RC_HT_RATEMCS7] = DESC_RATEMCS7,
.maps[RTL_RC_HT_RATEMCS15] = DESC_RATEMCS15,
};
static const struct pci_device_id rtl92de_pci_ids[] = {
{RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8193, rtl92de_hal_cfg)},
{RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x002B, rtl92de_hal_cfg)},
{},
};
MODULE_DEVICE_TABLE(pci, rtl92de_pci_ids);
MODULE_AUTHOR("lizhaoming <chaoming_li@realsil.com.cn>");
MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Realtek 8192DE 802.11n Dual Mac PCI wireless");
MODULE_FIRMWARE("rtlwifi/rtl8192defw.bin");
module_param_named(swenc, rtl92de_mod_params.sw_crypto, bool, 0444);
module_param_named(debug_level, rtl92de_mod_params.debug_level, int, 0644);
module_param_named(ips, rtl92de_mod_params.inactiveps, bool, 0444);
module_param_named(swlps, rtl92de_mod_params.swctrl_lps, bool, 0444);
module_param_named(fwlps, rtl92de_mod_params.fwctrl_lps, bool, 0444);
module_param_named(aspm, rtl92de_mod_params.aspm_support, int, 0444);
module_param_named(debug_mask, rtl92de_mod_params.debug_mask, ullong, 0644);
MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n");
MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n");
MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 1)\n");
MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 0)\n");
MODULE_PARM_DESC(aspm, "Set to 1 to enable ASPM (default 1)\n");
MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)");
MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)");
static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
static struct pci_driver rtl92de_driver = {
.name = KBUILD_MODNAME,
.id_table = rtl92de_pci_ids,
.probe = rtl_pci_probe,
.remove = rtl_pci_disconnect,
.driver.pm = &rtlwifi_pm_ops,
};
/* add global spin lock to solve the problem that
* Dul mac register operation on the same time */
DEFINE_SPINLOCK(globalmutex_power);
DEFINE_SPINLOCK(globalmutex_for_fwdownload);
DEFINE_SPINLOCK(globalmutex_for_power_and_efuse);
static int __init rtl92de_module_init(void)
{
int ret = 0;
ret = pci_register_driver(&rtl92de_driver);
if (ret)
WARN_ONCE(true, "rtl8192de: No device found\n");
return ret;
}
static void __exit rtl92de_module_exit(void)
{
pci_unregister_driver(&rtl92de_driver);
}
module_init(rtl92de_module_init);
module_exit(rtl92de_module_exit);
@@ -0,0 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 2009-2012 Realtek Corporation.*/
#ifndef __RTL92DE_SW_H__
#define __RTL92DE_SW_H__
extern spinlock_t globalmutex_power;
extern spinlock_t globalmutex_for_fwdownload;
extern spinlock_t globalmutex_for_power_and_efuse;
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,30 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 2009-2012 Realtek Corporation.*/
#ifndef __RTL92DE_TABLE__H_
#define __RTL92DE_TABLE__H_
/*Created on 2011/ 1/14, 1:35*/
#define PHY_REG_2T_ARRAYLENGTH 380
extern u32 rtl8192de_phy_reg_2tarray[PHY_REG_2T_ARRAYLENGTH];
#define PHY_REG_ARRAY_PG_LENGTH 624
extern u32 rtl8192de_phy_reg_array_pg[PHY_REG_ARRAY_PG_LENGTH];
#define RADIOA_2T_ARRAYLENGTH 378
extern u32 rtl8192de_radioa_2tarray[RADIOA_2T_ARRAYLENGTH];
#define RADIOB_2T_ARRAYLENGTH 384
extern u32 rtl8192de_radiob_2tarray[RADIOB_2T_ARRAYLENGTH];
#define RADIOA_2T_INT_PA_ARRAYLENGTH 378
extern u32 rtl8192de_radioa_2t_int_paarray[RADIOA_2T_INT_PA_ARRAYLENGTH];
#define RADIOB_2T_INT_PA_ARRAYLENGTH 384
extern u32 rtl8192de_radiob_2t_int_paarray[RADIOB_2T_INT_PA_ARRAYLENGTH];
#define MAC_2T_ARRAYLENGTH 160
extern u32 rtl8192de_mac_2tarray[MAC_2T_ARRAYLENGTH];
#define AGCTAB_ARRAYLENGTH 386
extern u32 rtl8192de_agctab_array[AGCTAB_ARRAYLENGTH];
#define AGCTAB_5G_ARRAYLENGTH 194
extern u32 rtl8192de_agctab_5garray[AGCTAB_5G_ARRAYLENGTH];
#define AGCTAB_2G_ARRAYLENGTH 194
extern u32 rtl8192de_agctab_2garray[AGCTAB_2G_ARRAYLENGTH];
#endif
@@ -0,0 +1,314 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2009-2012 Realtek Corporation.*/
#include "../wifi.h"
#include "../pci.h"
#include "../base.h"
#include "../stats.h"
#include "../rtl8192d/reg.h"
#include "../rtl8192d/def.h"
#include "../rtl8192d/phy_common.h"
#include "../rtl8192d/trx_common.h"
#include "phy.h"
#include "trx.h"
#include "led.h"
static u8 _rtl92de_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue)
{
__le16 fc = rtl_get_fc(skb);
if (unlikely(ieee80211_is_beacon(fc)))
return QSLT_BEACON;
if (ieee80211_is_mgmt(fc))
return QSLT_MGNT;
return skb->priority;
}
static void _rtl92de_insert_emcontent(struct rtl_tcb_desc *ptcb_desc,
u8 *virtualaddress8)
{
__le32 *virtualaddress = (__le32 *)virtualaddress8;
memset(virtualaddress, 0, 8);
set_earlymode_pktnum(virtualaddress, ptcb_desc->empkt_num);
set_earlymode_len0(virtualaddress, ptcb_desc->empkt_len[0]);
set_earlymode_len1(virtualaddress, ptcb_desc->empkt_len[1]);
set_earlymode_len2_1(virtualaddress, ptcb_desc->empkt_len[2] & 0xF);
set_earlymode_len2_2(virtualaddress, ptcb_desc->empkt_len[2] >> 4);
set_earlymode_len3(virtualaddress, ptcb_desc->empkt_len[3]);
set_earlymode_len4(virtualaddress, ptcb_desc->empkt_len[4]);
}
void rtl92de_tx_fill_desc(struct ieee80211_hw *hw,
struct ieee80211_hdr *hdr, u8 *pdesc8,
u8 *pbd_desc_tx, struct ieee80211_tx_info *info,
struct ieee80211_sta *sta,
struct sk_buff *skb,
u8 hw_queue, struct rtl_tcb_desc *ptcb_desc)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
__le32 *pdesc = (__le32 *)pdesc8;
u16 seq_number;
__le16 fc = hdr->frame_control;
unsigned int buf_len = 0;
unsigned int skb_len = skb->len;
u8 fw_qsel = _rtl92de_map_hwqueue_to_fwqueue(skb, hw_queue);
bool firstseg = ((hdr->seq_ctrl &
cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0);
bool lastseg = ((hdr->frame_control &
cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0);
dma_addr_t mapping;
u8 bw_40 = 0;
if (mac->opmode == NL80211_IFTYPE_STATION) {
bw_40 = mac->bw_40;
} else if (mac->opmode == NL80211_IFTYPE_AP ||
mac->opmode == NL80211_IFTYPE_ADHOC) {
if (sta)
bw_40 = sta->deflink.bandwidth >= IEEE80211_STA_RX_BW_40;
}
seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
rtl_get_tcb_desc(hw, info, sta, skb, ptcb_desc);
/* reserve 8 byte for AMPDU early mode */
if (rtlhal->earlymode_enable) {
skb_push(skb, EM_HDR_LEN);
memset(skb->data, 0, EM_HDR_LEN);
}
buf_len = skb->len;
mapping = dma_map_single(&rtlpci->pdev->dev, skb->data, skb->len,
DMA_TO_DEVICE);
if (dma_mapping_error(&rtlpci->pdev->dev, mapping)) {
rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE,
"DMA mapping error\n");
return;
}
clear_pci_tx_desc_content(pdesc, sizeof(struct tx_desc_92d));
if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) {
firstseg = true;
lastseg = true;
}
if (firstseg) {
if (rtlhal->earlymode_enable) {
set_tx_desc_pkt_offset(pdesc, 1);
set_tx_desc_offset(pdesc, USB_HWDESC_HEADER_LEN +
EM_HDR_LEN);
if (ptcb_desc->empkt_num) {
rtl_dbg(rtlpriv, COMP_SEND, DBG_LOUD,
"Insert 8 byte.pTcb->EMPktNum:%d\n",
ptcb_desc->empkt_num);
_rtl92de_insert_emcontent(ptcb_desc,
(u8 *)(skb->data));
}
} else {
set_tx_desc_offset(pdesc, USB_HWDESC_HEADER_LEN);
}
/* 5G have no CCK rate */
if (rtlhal->current_bandtype == BAND_ON_5G)
if (ptcb_desc->hw_rate < DESC_RATE6M)
ptcb_desc->hw_rate = DESC_RATE6M;
set_tx_desc_tx_rate(pdesc, ptcb_desc->hw_rate);
if (ptcb_desc->use_shortgi || ptcb_desc->use_shortpreamble)
set_tx_desc_data_shortgi(pdesc, 1);
if (rtlhal->macphymode == DUALMAC_DUALPHY &&
ptcb_desc->hw_rate == DESC_RATEMCS7)
set_tx_desc_data_shortgi(pdesc, 1);
if (info->flags & IEEE80211_TX_CTL_AMPDU) {
set_tx_desc_agg_enable(pdesc, 1);
set_tx_desc_max_agg_num(pdesc, 0x14);
}
set_tx_desc_seq(pdesc, seq_number);
set_tx_desc_rts_enable(pdesc,
((ptcb_desc->rts_enable &&
!ptcb_desc->cts_enable) ? 1 : 0));
set_tx_desc_hw_rts_enable(pdesc, ((ptcb_desc->rts_enable
|| ptcb_desc->cts_enable) ? 1 : 0));
set_tx_desc_cts2self(pdesc, ((ptcb_desc->cts_enable) ? 1 : 0));
set_tx_desc_rts_stbc(pdesc, ((ptcb_desc->rts_stbc) ? 1 : 0));
/* 5G have no CCK rate */
if (rtlhal->current_bandtype == BAND_ON_5G)
if (ptcb_desc->rts_rate < DESC_RATE6M)
ptcb_desc->rts_rate = DESC_RATE6M;
set_tx_desc_rts_rate(pdesc, ptcb_desc->rts_rate);
set_tx_desc_rts_bw(pdesc, 0);
set_tx_desc_rts_sc(pdesc, ptcb_desc->rts_sc);
set_tx_desc_rts_short(pdesc, ((ptcb_desc->rts_rate <=
DESC_RATE54M) ?
(ptcb_desc->rts_use_shortpreamble ? 1 : 0) :
(ptcb_desc->rts_use_shortgi ? 1 : 0)));
if (bw_40) {
if (ptcb_desc->packet_bw) {
set_tx_desc_data_bw(pdesc, 1);
set_tx_desc_tx_sub_carrier(pdesc, 3);
} else {
set_tx_desc_data_bw(pdesc, 0);
set_tx_desc_tx_sub_carrier(pdesc,
mac->cur_40_prime_sc);
}
} else {
set_tx_desc_data_bw(pdesc, 0);
set_tx_desc_tx_sub_carrier(pdesc, 0);
}
set_tx_desc_linip(pdesc, 0);
set_tx_desc_pkt_size(pdesc, (u16)skb_len);
if (sta) {
u8 ampdu_density = sta->deflink.ht_cap.ampdu_density;
set_tx_desc_ampdu_density(pdesc, ampdu_density);
}
if (info->control.hw_key) {
struct ieee80211_key_conf *keyconf;
keyconf = info->control.hw_key;
switch (keyconf->cipher) {
case WLAN_CIPHER_SUITE_WEP40:
case WLAN_CIPHER_SUITE_WEP104:
case WLAN_CIPHER_SUITE_TKIP:
set_tx_desc_sec_type(pdesc, 0x1);
break;
case WLAN_CIPHER_SUITE_CCMP:
set_tx_desc_sec_type(pdesc, 0x3);
break;
default:
set_tx_desc_sec_type(pdesc, 0x0);
break;
}
}
set_tx_desc_pkt_id(pdesc, 0);
set_tx_desc_queue_sel(pdesc, fw_qsel);
set_tx_desc_data_rate_fb_limit(pdesc, 0x1F);
set_tx_desc_rts_rate_fb_limit(pdesc, 0xF);
set_tx_desc_disable_fb(pdesc, ptcb_desc->disable_ratefallback ?
1 : 0);
set_tx_desc_use_rate(pdesc, ptcb_desc->use_driver_rate ? 1 : 0);
/* Set TxRate and RTSRate in TxDesc */
/* This prevent Tx initial rate of new-coming packets */
/* from being overwritten by retried packet rate.*/
if (!ptcb_desc->use_driver_rate) {
set_tx_desc_rts_rate(pdesc, 0x08);
/* set_tx_desc_tx_rate(pdesc, 0x0b); */
}
if (ieee80211_is_data_qos(fc)) {
if (mac->rdg_en) {
rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE,
"Enable RDG function\n");
set_tx_desc_rdg_enable(pdesc, 1);
set_tx_desc_htc(pdesc, 1);
}
}
}
set_tx_desc_first_seg(pdesc, (firstseg ? 1 : 0));
set_tx_desc_last_seg(pdesc, (lastseg ? 1 : 0));
set_tx_desc_tx_buffer_size(pdesc, (u16)buf_len);
set_tx_desc_tx_buffer_address(pdesc, mapping);
if (rtlpriv->dm.useramask) {
set_tx_desc_rate_id(pdesc, ptcb_desc->ratr_index);
set_tx_desc_macid(pdesc, ptcb_desc->mac_id);
} else {
set_tx_desc_rate_id(pdesc, 0xC + ptcb_desc->ratr_index);
set_tx_desc_macid(pdesc, ptcb_desc->ratr_index);
}
if (ieee80211_is_data_qos(fc))
set_tx_desc_qos(pdesc, 1);
if ((!ieee80211_is_data_qos(fc)) && ppsc->fwctrl_lps) {
set_tx_desc_hwseq_en(pdesc, 1);
set_tx_desc_pkt_id(pdesc, 8);
}
set_tx_desc_more_frag(pdesc, (lastseg ? 0 : 1));
rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, "\n");
}
void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc8,
struct sk_buff *skb)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
u8 fw_queue = QSLT_BEACON;
struct ieee80211_hdr *hdr = rtl_get_hdr(skb);
__le16 fc = hdr->frame_control;
__le32 *pdesc = (__le32 *)pdesc8;
dma_addr_t mapping = dma_map_single(&rtlpci->pdev->dev, skb->data,
skb->len, DMA_TO_DEVICE);
if (dma_mapping_error(&rtlpci->pdev->dev, mapping)) {
rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE,
"DMA mapping error\n");
return;
}
clear_pci_tx_desc_content(pdesc, TX_DESC_SIZE);
set_tx_desc_offset(pdesc, USB_HWDESC_HEADER_LEN);
/* 5G have no CCK rate
* Caution: The macros below are multi-line expansions.
* The braces are needed no matter what checkpatch says
*/
if (rtlhal->current_bandtype == BAND_ON_5G) {
set_tx_desc_tx_rate(pdesc, DESC_RATE6M);
} else {
set_tx_desc_tx_rate(pdesc, DESC_RATE1M);
}
set_tx_desc_seq(pdesc, 0);
set_tx_desc_linip(pdesc, 0);
set_tx_desc_queue_sel(pdesc, fw_queue);
set_tx_desc_first_seg(pdesc, 1);
set_tx_desc_last_seg(pdesc, 1);
set_tx_desc_tx_buffer_size(pdesc, (u16)skb->len);
set_tx_desc_tx_buffer_address(pdesc, mapping);
set_tx_desc_rate_id(pdesc, 7);
set_tx_desc_macid(pdesc, 0);
set_tx_desc_pkt_size(pdesc, (u16)(skb->len));
set_tx_desc_first_seg(pdesc, 1);
set_tx_desc_last_seg(pdesc, 1);
set_tx_desc_offset(pdesc, 0x20);
set_tx_desc_use_rate(pdesc, 1);
if (!ieee80211_is_data_qos(fc) && ppsc->fwctrl_lps) {
set_tx_desc_hwseq_en(pdesc, 1);
set_tx_desc_pkt_id(pdesc, 8);
}
RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
"H2C Tx Cmd Content", pdesc, TX_DESC_SIZE);
wmb();
set_tx_desc_own(pdesc, 1);
}
bool rtl92de_is_tx_desc_closed(struct ieee80211_hw *hw,
u8 hw_queue, u16 index)
{
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue];
u8 *entry = (u8 *)(&ring->desc[ring->idx]);
u8 own = (u8)rtl92d_get_desc(hw, entry, true, HW_DESC_OWN);
/* a beacon packet will only use the first
* descriptor by defaut, and the own bit may not
* be cleared by the hardware
*/
if (own)
return false;
return true;
}
void rtl92de_tx_polling(struct ieee80211_hw *hw, u8 hw_queue)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
if (hw_queue == BEACON_QUEUE)
rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4));
else
rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG,
BIT(0) << (hw_queue));
}
@@ -0,0 +1,136 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 2009-2012 Realtek Corporation.*/
#ifndef __RTL92DE_TRX_H__
#define __RTL92DE_TRX_H__
#define TX_DESC_SIZE 64
#define TX_DESC_AGGR_SUBFRAME_SIZE 32
#define RX_DESC_SIZE 32
#define TX_DESC_NEXT_DESC_OFFSET 40
#define USB_HWDESC_HEADER_LEN 32
#define CRCLENGTH 4
static inline void clear_pci_tx_desc_content(__le32 *__pdesc, u32 _size)
{
memset((void *)__pdesc, 0,
min_t(size_t, _size, TX_DESC_NEXT_DESC_OFFSET));
}
struct tx_desc_92d {
u32 pktsize:16;
u32 offset:8;
u32 bmc:1;
u32 htc:1;
u32 lastseg:1;
u32 firstseg:1;
u32 linip:1;
u32 noacm:1;
u32 gf:1;
u32 own:1;
u32 macid:5;
u32 agg_en:1;
u32 bk:1;
u32 rdg_en:1;
u32 queuesel:5;
u32 rd_nav_ext:1;
u32 lsig_txop_en:1;
u32 pifs:1;
u32 rateid:4;
u32 nav_usehdr:1;
u32 en_descid:1;
u32 sectype:2;
u32 pktoffset:8;
u32 rts_rc:6;
u32 data_rc:6;
u32 rsvd0:2;
u32 bar_retryht:2;
u32 rsvd1:1;
u32 morefrag:1;
u32 raw:1;
u32 ccx:1;
u32 ampdudensity:3;
u32 rsvd2:1;
u32 ant_sela:1;
u32 ant_selb:1;
u32 txant_cck:2;
u32 txant_l:2;
u32 txant_ht:2;
u32 nextheadpage:8;
u32 tailpage:8;
u32 seq:12;
u32 pktid:4;
u32 rtsrate:5;
u32 apdcfe:1;
u32 qos:1;
u32 hwseq_enable:1;
u32 userrate:1;
u32 dis_rtsfb:1;
u32 dis_datafb:1;
u32 cts2self:1;
u32 rts_en:1;
u32 hwrts_en:1;
u32 portid:1;
u32 rsvd3:3;
u32 waitdcts:1;
u32 cts2ap_en:1;
u32 txsc:2;
u32 stbc:2;
u32 txshort:1;
u32 txbw:1;
u32 rtsshort:1;
u32 rtsbw:1;
u32 rtssc:2;
u32 rtsstbc:2;
u32 txrate:6;
u32 shortgi:1;
u32 ccxt:1;
u32 txrate_fb_lmt:5;
u32 rtsrate_fb_lmt:4;
u32 retrylmt_en:1;
u32 txretrylmt:6;
u32 usb_txaggnum:8;
u32 txagca:5;
u32 txagcb:5;
u32 usemaxlen:1;
u32 maxaggnum:5;
u32 mcsg1maxlen:4;
u32 mcsg2maxlen:4;
u32 mcsg3maxlen:4;
u32 mcs7sgimaxlen:4;
u32 txbuffersize:16;
u32 mcsg4maxlen:4;
u32 mcsg5maxlen:4;
u32 mcsg6maxlen:4;
u32 mcsg15sgimaxlen:4;
u32 txbuffaddr;
u32 txbufferaddr64;
u32 nextdescaddress;
u32 nextdescaddress64;
u32 reserve_pass_pcie_mm_limit[4];
} __packed;
void rtl92de_tx_fill_desc(struct ieee80211_hw *hw,
struct ieee80211_hdr *hdr, u8 *pdesc,
u8 *pbd_desc_tx, struct ieee80211_tx_info *info,
struct ieee80211_sta *sta,
struct sk_buff *skb, u8 hw_queue,
struct rtl_tcb_desc *ptcb_desc);
bool rtl92de_is_tx_desc_closed(struct ieee80211_hw *hw,
u8 hw_queue, u16 index);
void rtl92de_tx_polling(struct ieee80211_hw *hw, u8 hw_queue);
void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
struct sk_buff *skb);
#endif