wireless-drivers-next patches for 4.12

Lots of bugfixes as usual but also some new features.
 
 Major changes:
 
 ath10k
 
 * improve firmware download time for QCA6174 and QCA9377, especially
   helps resume time
 
 ath9k_htc
 
 * add support AirTies 1eda:2315 AR9271 device
 
 rt2x00
 
 * add support MT7620
 
 mwifiex
 
 * enable auto deep sleep mode for USB chipsets
 
 brcmfmac
 
 * add support for network namespaces (WIPHY_FLAG_NETNS_OK)
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQEcBAABAgAGBQJY55+nAAoJEG4XJFUm622bRUAIAJfCM5YFyh9Y/XV147JshdGi
 xScDAgwIA1/o+iHfvTsjSH3/uoH3JhsiqfcXN7R80kyvG7HrUeXaebmUDgbBvOOj
 FTMuytiD+xkgEKVjWIwtXUYqctyzQ8ofxIQJ2W5E9CbEYAZ43uEcXzdnhBKVaVuY
 XPw59MF5vRGDDXTnTf4af4OC+L1QqwUqsyi4j7oMIfexieMGQxQL0JYOyHweCnCV
 gMz/kTxAIcmC1yOiunu8VyU4kK8borW36wC7XEE3MOXhqSKnQjyhI/efA76AKX0j
 O7sfEKCFlZU1xXQbkB9ecbKc2jyMefiE0gwLWWI5dwKhnUS2qQ6GS8ML+NMfV0g=
 =B2X+
 -----END PGP SIGNATURE-----

Merge tag 'wireless-drivers-next-for-davem-2017-04-07' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next

Kalle Valo says:

====================
wireless-drivers-next patches for 4.12

Lots of bugfixes as usual but also some new features.

Major changes:

ath10k

* improve firmware download time for QCA6174 and QCA9377, especially
  helps resume time

ath9k_htc

* add support AirTies 1eda:2315 AR9271 device

rt2x00

* add support MT7620

mwifiex

* enable auto deep sleep mode for USB chipsets

brcmfmac

* add support for network namespaces (WIPHY_FLAG_NETNS_OK)
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2017-04-09 18:13:12 -07:00
commit cdd3210c3d
99 changed files with 6998 additions and 8327 deletions

View File

@ -185,8 +185,7 @@ int bcma_gpio_init(struct bcma_drv_cc *cc)
chip->owner = THIS_MODULE;
chip->parent = bcma_bus_get_host_dev(bus);
#if IS_BUILTIN(CONFIG_OF)
if (cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC)
chip->of_node = cc->core->dev.of_node;
chip->of_node = cc->core->dev.of_node;
#endif
switch (bus->chipinfo.id) {
case BCMA_CHIP_ID_BCM4707:

View File

@ -201,9 +201,6 @@ static void bcma_of_fill_device(struct device *parent,
{
struct device_node *node;
if (!IS_ENABLED(CONFIG_OF_IRQ))
return;
node = bcma_of_find_child_device(parent, core);
if (node)
core->dev.of_node = node;
@ -242,19 +239,18 @@ void bcma_prepare_core(struct bcma_bus *bus, struct bcma_device *core)
core->dev.release = bcma_release_core_dev;
core->dev.bus = &bcma_bus_type;
dev_set_name(&core->dev, "bcma%d:%d", bus->num, core->core_index);
core->dev.parent = bcma_bus_get_host_dev(bus);
if (core->dev.parent)
bcma_of_fill_device(core->dev.parent, core);
switch (bus->hosttype) {
case BCMA_HOSTTYPE_PCI:
core->dev.parent = &bus->host_pci->dev;
core->dma_dev = &bus->host_pci->dev;
core->irq = bus->host_pci->irq;
break;
case BCMA_HOSTTYPE_SOC:
if (IS_ENABLED(CONFIG_OF) && bus->host_pdev) {
core->dma_dev = &bus->host_pdev->dev;
core->dev.parent = &bus->host_pdev->dev;
if (core->dev.parent)
bcma_of_fill_device(core->dev.parent, core);
} else {
core->dev.dma_mask = &core->dev.coherent_dma_mask;
core->dma_dev = &core->dev;

View File

@ -19,12 +19,21 @@
#include "hif.h"
#include "debug.h"
#include "htc.h"
#include "hw.h"
void ath10k_bmi_start(struct ath10k *ar)
{
int ret;
ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi start\n");
ar->bmi.done_sent = false;
/* Enable hardware clock to speed up firmware download */
if (ar->hw_params.hw_ops->enable_pll_clk) {
ret = ar->hw_params.hw_ops->enable_pll_clk(ar);
ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi enable pll ret %d\n", ret);
}
}
int ath10k_bmi_done(struct ath10k *ar)
@ -129,6 +138,69 @@ int ath10k_bmi_read_memory(struct ath10k *ar,
return 0;
}
int ath10k_bmi_write_soc_reg(struct ath10k *ar, u32 address, u32 reg_val)
{
struct bmi_cmd cmd;
u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.write_soc_reg);
int ret;
ath10k_dbg(ar, ATH10K_DBG_BMI,
"bmi write soc register 0x%08x val 0x%08x\n",
address, reg_val);
if (ar->bmi.done_sent) {
ath10k_warn(ar, "bmi write soc register command in progress\n");
return -EBUSY;
}
cmd.id = __cpu_to_le32(BMI_WRITE_SOC_REGISTER);
cmd.write_soc_reg.addr = __cpu_to_le32(address);
cmd.write_soc_reg.value = __cpu_to_le32(reg_val);
ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, NULL, NULL);
if (ret) {
ath10k_warn(ar, "Unable to write soc register to device: %d\n",
ret);
return ret;
}
return 0;
}
int ath10k_bmi_read_soc_reg(struct ath10k *ar, u32 address, u32 *reg_val)
{
struct bmi_cmd cmd;
union bmi_resp resp;
u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.read_soc_reg);
u32 resplen = sizeof(resp.read_soc_reg);
int ret;
ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi read soc register 0x%08x\n",
address);
if (ar->bmi.done_sent) {
ath10k_warn(ar, "bmi read soc register command in progress\n");
return -EBUSY;
}
cmd.id = __cpu_to_le32(BMI_READ_SOC_REGISTER);
cmd.read_soc_reg.addr = __cpu_to_le32(address);
ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, &resp, &resplen);
if (ret) {
ath10k_warn(ar, "Unable to read soc register from device: %d\n",
ret);
return ret;
}
*reg_val = __le32_to_cpu(resp.read_soc_reg.value);
ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi read soc register value 0x%08x\n",
*reg_val);
return 0;
}
int ath10k_bmi_write_memory(struct ath10k *ar,
u32 address, const void *buffer, u32 length)
{

View File

@ -232,4 +232,6 @@ int ath10k_bmi_lz_stream_start(struct ath10k *ar, u32 address);
int ath10k_bmi_lz_data(struct ath10k *ar, const void *buffer, u32 length);
int ath10k_bmi_fast_download(struct ath10k *ar, u32 address,
const void *buffer, u32 length);
int ath10k_bmi_read_soc_reg(struct ath10k *ar, u32 address, u32 *reg_val);
int ath10k_bmi_write_soc_reg(struct ath10k *ar, u32 address, u32 reg_val);
#endif /* _BMI_H_ */

View File

@ -166,7 +166,9 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
.board_size = QCA6174_BOARD_DATA_SZ,
.board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
},
.hw_ops = &qca988x_ops,
.hw_ops = &qca6174_ops,
.hw_clk = qca6174_clk,
.target_cpu_freq = 176000000,
.decap_align_bytes = 4,
},
{
@ -280,7 +282,9 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
.board_size = QCA9377_BOARD_DATA_SZ,
.board_ext_size = QCA9377_BOARD_EXT_DATA_SZ,
},
.hw_ops = &qca988x_ops,
.hw_ops = &qca6174_ops,
.hw_clk = qca6174_clk,
.target_cpu_freq = 176000000,
.decap_align_bytes = 4,
},
{

View File

@ -775,6 +775,8 @@ struct ath10k {
u32 num_rf_chains;
u32 max_spatial_stream;
/* protected by conf_mutex */
u32 low_5ghz_chan;
u32 high_5ghz_chan;
bool ani_enabled;
bool p2p;

View File

@ -249,9 +249,6 @@ static ssize_t ath10k_read_wmi_services(struct file *file,
mutex_lock(&ar->conf_mutex);
if (len > buf_len)
len = buf_len;
spin_lock_bh(&ar->data_lock);
for (i = 0; i < WMI_SERVICE_MAX; i++) {
enabled = test_bit(i, ar->wmi.svc_map);
@ -1997,6 +1994,15 @@ static ssize_t ath10k_write_simulate_radar(struct file *file,
size_t count, loff_t *ppos)
{
struct ath10k *ar = file->private_data;
struct ath10k_vif *arvif;
/* Just check for for the first vif alone, as all the vifs will be
* sharing the same channel and if the channel is disabled, all the
* vifs will share the same 'is_started' state.
*/
arvif = list_first_entry(&ar->arvifs, typeof(*arvif), list);
if (!arvif->is_started)
return -EINVAL;
ieee80211_radar_detected(ar->hw);

View File

@ -19,6 +19,7 @@
#include "hw.h"
#include "hif.h"
#include "wmi-ops.h"
#include "bmi.h"
const struct ath10k_hw_regs qca988x_regs = {
.rtc_soc_base_address = 0x00004000,
@ -72,6 +73,9 @@ const struct ath10k_hw_regs qca6174_regs = {
.pcie_intr_fw_mask = 0x00000400,
.pcie_intr_ce_mask_all = 0x0007f800,
.pcie_intr_clr_address = 0x00000014,
.cpu_pll_init_address = 0x00404020,
.cpu_speed_address = 0x00404024,
.core_clk_div_address = 0x00404028,
};
const struct ath10k_hw_regs qca99x0_regs = {
@ -187,6 +191,73 @@ const struct ath10k_hw_values qca4019_values = {
.ce_desc_meta_data_lsb = 4,
};
const struct ath10k_hw_clk_params qca6174_clk[ATH10K_HW_REFCLK_COUNT] = {
{
.refclk = 48000000,
.div = 0xe,
.rnfrac = 0x2aaa8,
.settle_time = 2400,
.refdiv = 0,
.outdiv = 1,
},
{
.refclk = 19200000,
.div = 0x24,
.rnfrac = 0x2aaa8,
.settle_time = 960,
.refdiv = 0,
.outdiv = 1,
},
{
.refclk = 24000000,
.div = 0x1d,
.rnfrac = 0x15551,
.settle_time = 1200,
.refdiv = 0,
.outdiv = 1,
},
{
.refclk = 26000000,
.div = 0x1b,
.rnfrac = 0x4ec4,
.settle_time = 1300,
.refdiv = 0,
.outdiv = 1,
},
{
.refclk = 37400000,
.div = 0x12,
.rnfrac = 0x34b49,
.settle_time = 1870,
.refdiv = 0,
.outdiv = 1,
},
{
.refclk = 38400000,
.div = 0x12,
.rnfrac = 0x15551,
.settle_time = 1920,
.refdiv = 0,
.outdiv = 1,
},
{
.refclk = 40000000,
.div = 0x12,
.rnfrac = 0x26665,
.settle_time = 2000,
.refdiv = 0,
.outdiv = 1,
},
{
.refclk = 52000000,
.div = 0x1b,
.rnfrac = 0x4ec4,
.settle_time = 2600,
.refdiv = 0,
.outdiv = 1,
},
};
void ath10k_hw_fill_survey_time(struct ath10k *ar, struct survey_info *survey,
u32 cc, u32 rcc, u32 cc_prev, u32 rcc_prev)
{
@ -361,6 +432,195 @@ static void ath10k_hw_qca988x_set_coverage_class(struct ath10k *ar,
mutex_unlock(&ar->conf_mutex);
}
/**
* ath10k_hw_qca6174_enable_pll_clock() - enable the qca6174 hw pll clock
* @ar: the ath10k blob
*
* This function is very hardware specific, the clock initialization
* steps is very sensitive and could lead to unknown crash, so they
* should be done in sequence.
*
* *** Be aware if you planned to refactor them. ***
*
* Return: 0 if successfully enable the pll, otherwise EINVAL
*/
static int ath10k_hw_qca6174_enable_pll_clock(struct ath10k *ar)
{
int ret, wait_limit;
u32 clk_div_addr, pll_init_addr, speed_addr;
u32 addr, reg_val, mem_val;
struct ath10k_hw_params *hw;
const struct ath10k_hw_clk_params *hw_clk;
hw = &ar->hw_params;
if (ar->regs->core_clk_div_address == 0 ||
ar->regs->cpu_pll_init_address == 0 ||
ar->regs->cpu_speed_address == 0)
return -EINVAL;
clk_div_addr = ar->regs->core_clk_div_address;
pll_init_addr = ar->regs->cpu_pll_init_address;
speed_addr = ar->regs->cpu_speed_address;
/* Read efuse register to find out the right hw clock configuration */
addr = (RTC_SOC_BASE_ADDRESS | EFUSE_OFFSET);
ret = ath10k_bmi_read_soc_reg(ar, addr, &reg_val);
if (ret)
return -EINVAL;
/* sanitize if the hw refclk index is out of the boundary */
if (MS(reg_val, EFUSE_XTAL_SEL) > ATH10K_HW_REFCLK_COUNT)
return -EINVAL;
hw_clk = &hw->hw_clk[MS(reg_val, EFUSE_XTAL_SEL)];
/* Set the rnfrac and outdiv params to bb_pll register */
addr = (RTC_SOC_BASE_ADDRESS | BB_PLL_CONFIG_OFFSET);
ret = ath10k_bmi_read_soc_reg(ar, addr, &reg_val);
if (ret)
return -EINVAL;
reg_val &= ~(BB_PLL_CONFIG_FRAC_MASK | BB_PLL_CONFIG_OUTDIV_MASK);
reg_val |= (SM(hw_clk->rnfrac, BB_PLL_CONFIG_FRAC) |
SM(hw_clk->outdiv, BB_PLL_CONFIG_OUTDIV));
ret = ath10k_bmi_write_soc_reg(ar, addr, reg_val);
if (ret)
return -EINVAL;
/* Set the correct settle time value to pll_settle register */
addr = (RTC_WMAC_BASE_ADDRESS | WLAN_PLL_SETTLE_OFFSET);
ret = ath10k_bmi_read_soc_reg(ar, addr, &reg_val);
if (ret)
return -EINVAL;
reg_val &= ~WLAN_PLL_SETTLE_TIME_MASK;
reg_val |= SM(hw_clk->settle_time, WLAN_PLL_SETTLE_TIME);
ret = ath10k_bmi_write_soc_reg(ar, addr, reg_val);
if (ret)
return -EINVAL;
/* Set the clock_ctrl div to core_clk_ctrl register */
addr = (RTC_SOC_BASE_ADDRESS | SOC_CORE_CLK_CTRL_OFFSET);
ret = ath10k_bmi_read_soc_reg(ar, addr, &reg_val);
if (ret)
return -EINVAL;
reg_val &= ~SOC_CORE_CLK_CTRL_DIV_MASK;
reg_val |= SM(1, SOC_CORE_CLK_CTRL_DIV);
ret = ath10k_bmi_write_soc_reg(ar, addr, reg_val);
if (ret)
return -EINVAL;
/* Set the clock_div register */
mem_val = 1;
ret = ath10k_bmi_write_memory(ar, clk_div_addr, &mem_val,
sizeof(mem_val));
if (ret)
return -EINVAL;
/* Configure the pll_control register */
addr = (RTC_WMAC_BASE_ADDRESS | WLAN_PLL_CONTROL_OFFSET);
ret = ath10k_bmi_read_soc_reg(ar, addr, &reg_val);
if (ret)
return -EINVAL;
reg_val |= (SM(hw_clk->refdiv, WLAN_PLL_CONTROL_REFDIV) |
SM(hw_clk->div, WLAN_PLL_CONTROL_DIV) |
SM(1, WLAN_PLL_CONTROL_NOPWD));
ret = ath10k_bmi_write_soc_reg(ar, addr, reg_val);
if (ret)
return -EINVAL;
/* busy wait (max 1s) the rtc_sync status register indicate ready */
wait_limit = 100000;
addr = (RTC_WMAC_BASE_ADDRESS | RTC_SYNC_STATUS_OFFSET);
do {
ret = ath10k_bmi_read_soc_reg(ar, addr, &reg_val);
if (ret)
return -EINVAL;
if (!MS(reg_val, RTC_SYNC_STATUS_PLL_CHANGING))
break;
wait_limit--;
udelay(10);
} while (wait_limit > 0);
if (MS(reg_val, RTC_SYNC_STATUS_PLL_CHANGING))
return -EINVAL;
/* Unset the pll_bypass in pll_control register */
addr = (RTC_WMAC_BASE_ADDRESS | WLAN_PLL_CONTROL_OFFSET);
ret = ath10k_bmi_read_soc_reg(ar, addr, &reg_val);
if (ret)
return -EINVAL;
reg_val &= ~WLAN_PLL_CONTROL_BYPASS_MASK;
reg_val |= SM(0, WLAN_PLL_CONTROL_BYPASS);
ret = ath10k_bmi_write_soc_reg(ar, addr, reg_val);
if (ret)
return -EINVAL;
/* busy wait (max 1s) the rtc_sync status register indicate ready */
wait_limit = 100000;
addr = (RTC_WMAC_BASE_ADDRESS | RTC_SYNC_STATUS_OFFSET);
do {
ret = ath10k_bmi_read_soc_reg(ar, addr, &reg_val);
if (ret)
return -EINVAL;
if (!MS(reg_val, RTC_SYNC_STATUS_PLL_CHANGING))
break;
wait_limit--;
udelay(10);
} while (wait_limit > 0);
if (MS(reg_val, RTC_SYNC_STATUS_PLL_CHANGING))
return -EINVAL;
/* Enable the hardware cpu clock register */
addr = (RTC_SOC_BASE_ADDRESS | SOC_CPU_CLOCK_OFFSET);
ret = ath10k_bmi_read_soc_reg(ar, addr, &reg_val);
if (ret)
return -EINVAL;
reg_val &= ~SOC_CPU_CLOCK_STANDARD_MASK;
reg_val |= SM(1, SOC_CPU_CLOCK_STANDARD);
ret = ath10k_bmi_write_soc_reg(ar, addr, reg_val);
if (ret)
return -EINVAL;
/* unset the nopwd from pll_control register */
addr = (RTC_WMAC_BASE_ADDRESS | WLAN_PLL_CONTROL_OFFSET);
ret = ath10k_bmi_read_soc_reg(ar, addr, &reg_val);
if (ret)
return -EINVAL;
reg_val &= ~WLAN_PLL_CONTROL_NOPWD_MASK;
ret = ath10k_bmi_write_soc_reg(ar, addr, reg_val);
if (ret)
return -EINVAL;
/* enable the pll_init register */
mem_val = 1;
ret = ath10k_bmi_write_memory(ar, pll_init_addr, &mem_val,
sizeof(mem_val));
if (ret)
return -EINVAL;
/* set the target clock frequency to speed register */
ret = ath10k_bmi_write_memory(ar, speed_addr, &hw->target_cpu_freq,
sizeof(hw->target_cpu_freq));
if (ret)
return -EINVAL;
return 0;
}
const struct ath10k_hw_ops qca988x_ops = {
.set_coverage_class = ath10k_hw_qca988x_set_coverage_class,
};
@ -374,3 +634,8 @@ static int ath10k_qca99x0_rx_desc_get_l3_pad_bytes(struct htt_rx_desc *rxd)
const struct ath10k_hw_ops qca99x0_ops = {
.rx_desc_get_l3_pad_bytes = ath10k_qca99x0_rx_desc_get_l3_pad_bytes,
};
const struct ath10k_hw_ops qca6174_ops = {
.set_coverage_class = ath10k_hw_qca988x_set_coverage_class,
.enable_pll_clk = ath10k_hw_qca6174_enable_pll_clock,
};

View File

@ -255,6 +255,9 @@ struct ath10k_hw_regs {
u32 pcie_intr_fw_mask;
u32 pcie_intr_ce_mask_all;
u32 pcie_intr_clr_address;
u32 cpu_pll_init_address;
u32 cpu_speed_address;
u32 core_clk_div_address;
};
extern const struct ath10k_hw_regs qca988x_regs;
@ -363,6 +366,30 @@ enum ath10k_hw_cc_wraparound_type {
ATH10K_HW_CC_WRAP_SHIFTED_EACH = 2,
};
enum ath10k_hw_refclk_speed {
ATH10K_HW_REFCLK_UNKNOWN = -1,
ATH10K_HW_REFCLK_48_MHZ = 0,
ATH10K_HW_REFCLK_19_2_MHZ = 1,
ATH10K_HW_REFCLK_24_MHZ = 2,
ATH10K_HW_REFCLK_26_MHZ = 3,
ATH10K_HW_REFCLK_37_4_MHZ = 4,
ATH10K_HW_REFCLK_38_4_MHZ = 5,
ATH10K_HW_REFCLK_40_MHZ = 6,
ATH10K_HW_REFCLK_52_MHZ = 7,
/* must be the last one */
ATH10K_HW_REFCLK_COUNT,
};
struct ath10k_hw_clk_params {
u32 refclk;
u32 div;
u32 rnfrac;
u32 settle_time;
u32 refdiv;
u32 outdiv;
};
struct ath10k_hw_params {
u32 id;
u16 dev_id;
@ -416,6 +443,10 @@ struct ath10k_hw_params {
/* Number of bytes used for alignment in rx_hdr_status of rx desc. */
int decap_align_bytes;
/* hw specific clock control parameters */
const struct ath10k_hw_clk_params *hw_clk;
int target_cpu_freq;
};
struct htt_rx_desc;
@ -424,10 +455,14 @@ struct htt_rx_desc;
struct ath10k_hw_ops {
int (*rx_desc_get_l3_pad_bytes)(struct htt_rx_desc *rxd);
void (*set_coverage_class)(struct ath10k *ar, s16 value);
int (*enable_pll_clk)(struct ath10k *ar);
};
extern const struct ath10k_hw_ops qca988x_ops;
extern const struct ath10k_hw_ops qca99x0_ops;
extern const struct ath10k_hw_ops qca6174_ops;
extern const struct ath10k_hw_clk_params qca6174_clk[];
static inline int
ath10k_rx_desc_get_l3_pad_bytes(struct ath10k_hw_params *hw,
@ -847,4 +882,38 @@ ath10k_rx_desc_get_l3_pad_bytes(struct ath10k_hw_params *hw,
#define WAVE1_PHYCLK_USEC_MASK 0x0000007F
#define WAVE1_PHYCLK_USEC_LSB 0
/* qca6174 PLL offset/mask */
#define SOC_CORE_CLK_CTRL_OFFSET 0x00000114
#define SOC_CORE_CLK_CTRL_DIV_LSB 0
#define SOC_CORE_CLK_CTRL_DIV_MASK 0x00000007
#define EFUSE_OFFSET 0x0000032c
#define EFUSE_XTAL_SEL_LSB 8
#define EFUSE_XTAL_SEL_MASK 0x00000700
#define BB_PLL_CONFIG_OFFSET 0x000002f4
#define BB_PLL_CONFIG_FRAC_LSB 0
#define BB_PLL_CONFIG_FRAC_MASK 0x0003ffff
#define BB_PLL_CONFIG_OUTDIV_LSB 18
#define BB_PLL_CONFIG_OUTDIV_MASK 0x001c0000
#define WLAN_PLL_SETTLE_OFFSET 0x0018
#define WLAN_PLL_SETTLE_TIME_LSB 0
#define WLAN_PLL_SETTLE_TIME_MASK 0x000007ff
#define WLAN_PLL_CONTROL_OFFSET 0x0014
#define WLAN_PLL_CONTROL_DIV_LSB 0
#define WLAN_PLL_CONTROL_DIV_MASK 0x000003ff
#define WLAN_PLL_CONTROL_REFDIV_LSB 10
#define WLAN_PLL_CONTROL_REFDIV_MASK 0x00003c00
#define WLAN_PLL_CONTROL_BYPASS_LSB 16
#define WLAN_PLL_CONTROL_BYPASS_MASK 0x00010000
#define WLAN_PLL_CONTROL_NOPWD_LSB 18
#define WLAN_PLL_CONTROL_NOPWD_MASK 0x00040000
#define RTC_SYNC_STATUS_OFFSET 0x0244
#define RTC_SYNC_STATUS_PLL_CHANGING_LSB 5
#define RTC_SYNC_STATUS_PLL_CHANGING_MASK 0x00000020
/* qca6174 PLL offset/mask end */
#endif /* _HW_H_ */

View File

@ -3126,6 +3126,21 @@ static void ath10k_regd_update(struct ath10k *ar)
ath10k_warn(ar, "failed to set pdev regdomain: %d\n", ret);
}
static void ath10k_mac_update_channel_list(struct ath10k *ar,
struct ieee80211_supported_band *band)
{
int i;
if (ar->low_5ghz_chan && ar->high_5ghz_chan) {
for (i = 0; i < band->n_channels; i++) {
if (band->channels[i].center_freq < ar->low_5ghz_chan ||
band->channels[i].center_freq > ar->high_5ghz_chan)
band->channels[i].flags |=
IEEE80211_CHAN_DISABLED;
}
}
}
static void ath10k_reg_notifier(struct wiphy *wiphy,
struct regulatory_request *request)
{
@ -3149,6 +3164,10 @@ static void ath10k_reg_notifier(struct wiphy *wiphy,
if (ar->state == ATH10K_STATE_ON)
ath10k_regd_update(ar);
mutex_unlock(&ar->conf_mutex);
if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY)
ath10k_mac_update_channel_list(ar,
ar->hw->wiphy->bands[NL80211_BAND_5GHZ]);
}
/***************/
@ -7129,7 +7148,7 @@ ath10k_mac_update_rx_channel(struct ath10k *ar,
lockdep_assert_held(&ar->data_lock);
WARN_ON(ctx && vifs);
WARN_ON(vifs && n_vifs != 1);
WARN_ON(vifs && !n_vifs);
/* FIXME: Sort of an optimization and a workaround. Peers and vifs are
* on a linked list now. Doing a lookup peer -> vif -> chanctx for each

View File

@ -970,12 +970,6 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data,
}
remaining_bytes -= nbytes;
if (ret) {
ath10k_warn(ar, "failed to read diag value at 0x%x: %d\n",
address, ret);
break;
}
memcpy(data, data_buf, nbytes);
address += nbytes;

View File

@ -3643,6 +3643,11 @@ static void ath10k_dfs_radar_report(struct ath10k *ar,
spin_lock_bh(&ar->data_lock);
ch = ar->rx_channel;
/* fetch target operating channel during channel change */
if (!ch)
ch = ar->tgt_oper_chan;
spin_unlock_bh(&ar->data_lock);
if (!ch) {
@ -4593,6 +4598,8 @@ ath10k_wmi_main_op_pull_svc_rdy_ev(struct ath10k *ar, struct sk_buff *skb,
arg->phy_capab = ev->phy_capability;
arg->num_rf_chains = ev->num_rf_chains;
arg->eeprom_rd = ev->hal_reg_capabilities.eeprom_rd;
arg->low_5ghz_chan = ev->hal_reg_capabilities.low_5ghz_chan;
arg->high_5ghz_chan = ev->hal_reg_capabilities.high_5ghz_chan;
arg->num_mem_reqs = ev->num_mem_reqs;
arg->service_map = ev->wmi_service_bitmap;
arg->service_map_len = sizeof(ev->wmi_service_bitmap);
@ -4629,6 +4636,8 @@ ath10k_wmi_10x_op_pull_svc_rdy_ev(struct ath10k *ar, struct sk_buff *skb,
arg->phy_capab = ev->phy_capability;
arg->num_rf_chains = ev->num_rf_chains;
arg->eeprom_rd = ev->hal_reg_capabilities.eeprom_rd;
arg->low_5ghz_chan = ev->hal_reg_capabilities.low_5ghz_chan;
arg->high_5ghz_chan = ev->hal_reg_capabilities.high_5ghz_chan;
arg->num_mem_reqs = ev->num_mem_reqs;
arg->service_map = ev->wmi_service_bitmap;
arg->service_map_len = sizeof(ev->wmi_service_bitmap);
@ -4682,6 +4691,8 @@ static void ath10k_wmi_event_service_ready_work(struct work_struct *work)
ar->phy_capability = __le32_to_cpu(arg.phy_capab);
ar->num_rf_chains = __le32_to_cpu(arg.num_rf_chains);
ar->hw_eeprom_rd = __le32_to_cpu(arg.eeprom_rd);
ar->low_5ghz_chan = __le32_to_cpu(arg.low_5ghz_chan);
ar->high_5ghz_chan = __le32_to_cpu(arg.high_5ghz_chan);
ath10k_dbg_dump(ar, ATH10K_DBG_WMI, NULL, "wmi svc: ",
arg.service_map, arg.service_map_len);

View File

@ -3182,7 +3182,7 @@ struct wmi_10_4_phyerr_event {
struct phyerr_radar_report {
__le32 reg0; /* RADAR_REPORT_REG0_* */
__le32 reg1; /* REDAR_REPORT_REG1_* */
__le32 reg1; /* RADAR_REPORT_REG1_* */
} __packed;
#define RADAR_REPORT_REG0_PULSE_IS_CHIRP_MASK 0x80000000
@ -6335,6 +6335,8 @@ struct wmi_svc_rdy_ev_arg {
__le32 num_rf_chains;
__le32 eeprom_rd;
__le32 num_mem_reqs;
__le32 low_5ghz_chan;
__le32 high_5ghz_chan;
const __le32 *service_map;
size_t service_map_len;
const struct wlan_host_mem_req *mem_reqs[WMI_MAX_MEM_REQS];

View File

@ -102,10 +102,8 @@ static struct ieee80211_channel ath6kl_2ghz_channels[] = {
};
static struct ieee80211_channel ath6kl_5ghz_a_channels[] = {
CHAN5G(34, 0), CHAN5G(36, 0),
CHAN5G(38, 0), CHAN5G(40, 0),
CHAN5G(42, 0), CHAN5G(44, 0),
CHAN5G(46, 0), CHAN5G(48, 0),
CHAN5G(36, 0), CHAN5G(40, 0),
CHAN5G(44, 0), CHAN5G(48, 0),
CHAN5G(52, 0), CHAN5G(56, 0),
CHAN5G(60, 0), CHAN5G(64, 0),
CHAN5G(100, 0), CHAN5G(104, 0),

View File

@ -742,6 +742,9 @@ void ath9k_cmn_spectral_scan_trigger(struct ath_common *common,
return;
}
if (!spec_priv->spec_config.enabled)
return;
ath_ps_ops(common)->wakeup(common);
rxfilter = ath9k_hw_getrxfilter(ah);
ath9k_hw_setrxfilter(ah, rxfilter |

View File

@ -37,6 +37,7 @@ static struct usb_device_id ath9k_hif_usb_ids[] = {
{ USB_DEVICE(0x0cf3, 0xb002) }, /* Ubiquiti WifiStation */
{ USB_DEVICE(0x057c, 0x8403) }, /* AVM FRITZ!WLAN 11N v2 USB */
{ USB_DEVICE(0x0471, 0x209e) }, /* Philips (or NXP) PTA01 */
{ USB_DEVICE(0x1eda, 0x2315) }, /* AirTies */
{ USB_DEVICE(0x0cf3, 0x7015),
.driver_info = AR9287_USB }, /* Atheros */

View File

@ -337,10 +337,10 @@ static int wcn36xx_start(struct ieee80211_hw *hw)
wcn36xx_smd_stop(wcn);
out_free_smd_buf:
kfree(wcn->hal_buf);
out_free_dxe_pool:
wcn36xx_dxe_free_mem_pools(wcn);
out_free_dxe_ctl:
wcn36xx_dxe_free_ctl_blks(wcn);
out_free_dxe_pool:
wcn36xx_dxe_free_mem_pools(wcn);
out_smd_close:
wcn36xx_smd_close(wcn);
out_err:

View File

@ -390,22 +390,23 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
}
mutex_unlock(&wil->p2p_wdev_mutex);
/* social scan on P2P_DEVICE is handled as p2p search */
if (wdev->iftype == NL80211_IFTYPE_P2P_DEVICE &&
wil_p2p_is_social_scan(request)) {
if (wdev->iftype == NL80211_IFTYPE_P2P_DEVICE) {
if (!wil->p2p.p2p_dev_started) {
wil_err(wil, "P2P search requested on stopped P2P device\n");
rc = -EIO;
goto out;
}
wil->scan_request = request;
wil->radio_wdev = wdev;
rc = wil_p2p_search(wil, request);
if (rc) {
wil->radio_wdev = wil_to_wdev(wil);
wil->scan_request = NULL;
/* social scan on P2P_DEVICE is handled as p2p search */
if (wil_p2p_is_social_scan(request)) {
wil->scan_request = request;
wil->radio_wdev = wdev;
rc = wil_p2p_search(wil, request);
if (rc) {
wil->radio_wdev = wil_to_wdev(wil);
wil->scan_request = NULL;
}
goto out;
}
goto out;
}
(void)wil_p2p_stop_discovery(wil);
@ -415,9 +416,9 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
for (i = 0; i < request->n_ssids; i++) {
wil_dbg_misc(wil, "SSID[%d]", i);
print_hex_dump_bytes("SSID ", DUMP_PREFIX_OFFSET,
request->ssids[i].ssid,
request->ssids[i].ssid_len);
wil_hex_dump_misc("SSID ", DUMP_PREFIX_OFFSET, 16, 1,
request->ssids[i].ssid,
request->ssids[i].ssid_len, true);
}
if (request->n_ssids)
@ -454,8 +455,8 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
}
if (request->ie_len)
print_hex_dump_bytes("Scan IE ", DUMP_PREFIX_OFFSET,
request->ie, request->ie_len);
wil_hex_dump_misc("Scan IE ", DUMP_PREFIX_OFFSET, 16, 1,
request->ie, request->ie_len, true);
else
wil_dbg_misc(wil, "Scan has no IE's\n");
@ -679,6 +680,8 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
rc = wmi_send(wil, WMI_CONNECT_CMDID, &conn, sizeof(conn));
if (rc == 0) {
netif_carrier_on(ndev);
wil6210_bus_request(wil, WIL_MAX_BUS_REQUEST_KBPS);
wil->bss = bss;
/* Connect can take lots of time */
mod_timer(&wil->connect_timer,
jiffies + msecs_to_jiffies(2000));
@ -707,6 +710,7 @@ static int wil_cfg80211_disconnect(struct wiphy *wiphy,
return 0;
}
wil->locally_generated_disc = true;
rc = wmi_call(wil, WMI_DISCONNECT_CMDID, NULL, 0,
WMI_DISCONNECT_EVENTID, NULL, 0,
WIL6210_DISCONNECT_TO_MS);
@ -760,7 +764,8 @@ int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
*/
wil_dbg_misc(wil, "mgmt_tx\n");
print_hex_dump_bytes("mgmt tx frame ", DUMP_PREFIX_OFFSET, buf, len);
wil_hex_dump_misc("mgmt tx frame ", DUMP_PREFIX_OFFSET, 16, 1, buf,
len, true);
cmd = kmalloc(sizeof(*cmd) + len, GFP_KERNEL);
if (!cmd) {
@ -1093,18 +1098,18 @@ static int _wil_cfg80211_merge_extra_ies(const u8 *ies1, u16 ies1_len,
static void wil_print_bcon_data(struct cfg80211_beacon_data *b)
{
print_hex_dump_bytes("head ", DUMP_PREFIX_OFFSET,
b->head, b->head_len);
print_hex_dump_bytes("tail ", DUMP_PREFIX_OFFSET,
b->tail, b->tail_len);
print_hex_dump_bytes("BCON IE ", DUMP_PREFIX_OFFSET,
b->beacon_ies, b->beacon_ies_len);
print_hex_dump_bytes("PROBE ", DUMP_PREFIX_OFFSET,
b->probe_resp, b->probe_resp_len);
print_hex_dump_bytes("PROBE IE ", DUMP_PREFIX_OFFSET,
b->proberesp_ies, b->proberesp_ies_len);
print_hex_dump_bytes("ASSOC IE ", DUMP_PREFIX_OFFSET,
b->assocresp_ies, b->assocresp_ies_len);
wil_hex_dump_misc("head ", DUMP_PREFIX_OFFSET, 16, 1,
b->head, b->head_len, true);
wil_hex_dump_misc("tail ", DUMP_PREFIX_OFFSET, 16, 1,
b->tail, b->tail_len, true);
wil_hex_dump_misc("BCON IE ", DUMP_PREFIX_OFFSET, 16, 1,
b->beacon_ies, b->beacon_ies_len, true);
wil_hex_dump_misc("PROBE ", DUMP_PREFIX_OFFSET, 16, 1,
b->probe_resp, b->probe_resp_len, true);
wil_hex_dump_misc("PROBE IE ", DUMP_PREFIX_OFFSET, 16, 1,
b->proberesp_ies, b->proberesp_ies_len, true);
wil_hex_dump_misc("ASSOC IE ", DUMP_PREFIX_OFFSET, 16, 1,
b->assocresp_ies, b->assocresp_ies_len, true);
}
/* internal functions for device reset and starting AP */
@ -1198,6 +1203,7 @@ static int _wil_cfg80211_start_ap(struct wiphy *wiphy,
wil->pbss = pbss;
netif_carrier_on(ndev);
wil6210_bus_request(wil, WIL_MAX_BUS_REQUEST_KBPS);
rc = wmi_pcp_start(wil, bi, wmi_nettype, chan, hidden_ssid, is_go);
if (rc)
@ -1213,6 +1219,7 @@ static int _wil_cfg80211_start_ap(struct wiphy *wiphy,
wmi_pcp_stop(wil);
err_pcp_start:
netif_carrier_off(ndev);
wil6210_bus_request(wil, WIL_DEFAULT_BUS_REQUEST_KBPS);
out:
mutex_unlock(&wil->mutex);
return rc;
@ -1298,8 +1305,8 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy,
wil_dbg_misc(wil, "BI %d DTIM %d\n", info->beacon_interval,
info->dtim_period);
wil_dbg_misc(wil, "PBSS %d\n", info->pbss);
print_hex_dump_bytes("SSID ", DUMP_PREFIX_OFFSET,
info->ssid, info->ssid_len);
wil_hex_dump_misc("SSID ", DUMP_PREFIX_OFFSET, 16, 1,
info->ssid, info->ssid_len, true);
wil_print_bcon_data(bcon);
wil_print_crypto(wil, crypto);
@ -1319,6 +1326,7 @@ static int wil_cfg80211_stop_ap(struct wiphy *wiphy,
wil_dbg_misc(wil, "stop_ap\n");
netif_carrier_off(ndev);
wil6210_bus_request(wil, WIL_DEFAULT_BUS_REQUEST_KBPS);
wil_set_recovery_state(wil, fw_recovery_idle);
mutex_lock(&wil->mutex);

View File

@ -30,8 +30,8 @@ bool debug_fw; /* = false; */
module_param(debug_fw, bool, 0444);
MODULE_PARM_DESC(debug_fw, " do not perform card reset. For FW debug");
static bool oob_mode;
module_param(oob_mode, bool, 0444);
static u8 oob_mode;
module_param(oob_mode, byte, 0444);
MODULE_PARM_DESC(oob_mode,
" enable out of the box (OOB) mode in FW, for diagnostics and certification");
@ -274,15 +274,20 @@ static void _wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid,
wil_bcast_fini(wil);
wil_update_net_queues_bh(wil, NULL, true);
netif_carrier_off(ndev);
wil6210_bus_request(wil, WIL_DEFAULT_BUS_REQUEST_KBPS);
if (test_bit(wil_status_fwconnected, wil->status)) {
clear_bit(wil_status_fwconnected, wil->status);
cfg80211_disconnected(ndev, reason_code,
NULL, 0, false, GFP_KERNEL);
NULL, 0,
wil->locally_generated_disc,
GFP_KERNEL);
wil->locally_generated_disc = false;
} else if (test_bit(wil_status_fwconnecting, wil->status)) {
cfg80211_connect_result(ndev, bssid, NULL, 0, NULL, 0,
WLAN_STATUS_UNSPECIFIED_FAILURE,
GFP_KERNEL);
wil->bss = NULL;
}
clear_bit(wil_status_fwconnecting, wil->status);
break;
@ -304,10 +309,34 @@ static void wil_disconnect_worker(struct work_struct *work)
{
struct wil6210_priv *wil = container_of(work,
struct wil6210_priv, disconnect_worker);
struct net_device *ndev = wil_to_ndev(wil);
int rc;
struct {
struct wmi_cmd_hdr wmi;
struct wmi_disconnect_event evt;
} __packed reply;
mutex_lock(&wil->mutex);
_wil6210_disconnect(wil, NULL, WLAN_REASON_UNSPECIFIED, false);
mutex_unlock(&wil->mutex);
if (test_bit(wil_status_fwconnected, wil->status))
/* connect succeeded after all */
return;
if (!test_bit(wil_status_fwconnecting, wil->status))
/* already disconnected */
return;
rc = wmi_call(wil, WMI_DISCONNECT_CMDID, NULL, 0,
WMI_DISCONNECT_EVENTID, &reply, sizeof(reply),
WIL6210_DISCONNECT_TO_MS);
if (rc) {
wil_err(wil, "disconnect error %d\n", rc);
return;
}
wil_update_net_queues_bh(wil, NULL, true);
netif_carrier_off(ndev);
cfg80211_connect_result(ndev, NULL, NULL, 0, NULL, 0,
WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_KERNEL);
clear_bit(wil_status_fwconnecting, wil->status);
}
static void wil_connect_timer_fn(ulong x)
@ -555,6 +584,12 @@ int wil_priv_init(struct wil6210_priv *wil)
return -EAGAIN;
}
void wil6210_bus_request(struct wil6210_priv *wil, u32 kbps)
{
if (wil->platform_ops.bus_request)
wil->platform_ops.bus_request(wil->platform_handle, kbps);
}
/**
* wil6210_disconnect - disconnect one connection
* @wil: driver context
@ -607,13 +642,25 @@ static inline void wil_release_cpu(struct wil6210_priv *wil)
wil_w(wil, RGF_USER_USER_CPU_0, 1);
}
static void wil_set_oob_mode(struct wil6210_priv *wil, bool enable)
static void wil_set_oob_mode(struct wil6210_priv *wil, u8 mode)
{
wil_info(wil, "enable=%d\n", enable);
if (enable)
wil_info(wil, "oob_mode to %d\n", mode);
switch (mode) {
case 0:
wil_c(wil, RGF_USER_USAGE_6, BIT_USER_OOB_MODE |
BIT_USER_OOB_R2_MODE);
break;
case 1:
wil_c(wil, RGF_USER_USAGE_6, BIT_USER_OOB_R2_MODE);
wil_s(wil, RGF_USER_USAGE_6, BIT_USER_OOB_MODE);
else
break;
case 2:
wil_c(wil, RGF_USER_USAGE_6, BIT_USER_OOB_MODE);
wil_s(wil, RGF_USER_USAGE_6, BIT_USER_OOB_R2_MODE);
break;
default:
wil_err(wil, "invalid oob_mode: %d\n", mode);
}
}
static int wil_target_reset(struct wil6210_priv *wil)
@ -1066,9 +1113,7 @@ int __wil_up(struct wil6210_priv *wil)
napi_enable(&wil->napi_tx);
set_bit(wil_status_napi_en, wil->status);
if (wil->platform_ops.bus_request)
wil->platform_ops.bus_request(wil->platform_handle,
WIL_MAX_BUS_REQUEST_KBPS);
wil6210_bus_request(wil, WIL_DEFAULT_BUS_REQUEST_KBPS);
return 0;
}
@ -1092,8 +1137,7 @@ int __wil_down(struct wil6210_priv *wil)
set_bit(wil_status_resetting, wil->status);
if (wil->platform_ops.bus_request)
wil->platform_ops.bus_request(wil->platform_handle, 0);
wil6210_bus_request(wil, 0);
wil_disable_irq(wil);
if (test_and_clear_bit(wil_status_napi_en, wil->status)) {
@ -1154,6 +1198,7 @@ void wil_halp_vote(struct wil6210_priv *wil)
wil->halp.ref_cnt);
if (++wil->halp.ref_cnt == 1) {
reinit_completion(&wil->halp.comp);
wil6210_set_halp(wil);
rc = wait_for_completion_timeout(&wil->halp.comp, to_jiffies);
if (!rc) {

View File

@ -211,6 +211,7 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
dev_err(dev, "wil_if_alloc failed: %d\n", rc);
return rc;
}
wil->pdev = pdev;
pci_set_drvdata(pdev, wil);
/* rollback to if_free */
@ -224,6 +225,21 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
}
/* rollback to err_plat */
/* device supports 48bit addresses */
rc = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48));
if (rc) {
dev_err(dev, "dma_set_mask_and_coherent(48) failed: %d\n", rc);
rc = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
if (rc) {
dev_err(dev,
"dma_set_mask_and_coherent(32) failed: %d\n",
rc);
goto err_plat;
}
} else {
wil->use_extended_dma_addr = 1;
}
rc = pci_enable_device(pdev);
if (rc) {
wil_err(wil,

View File

@ -107,13 +107,28 @@ void wil_pmc_alloc(struct wil6210_priv *wil,
/* Allocate pring buffer and descriptors.
* vring->va should be aligned on its size rounded up to power of 2
* This is granted by the dma_alloc_coherent
* This is granted by the dma_alloc_coherent.
*
* HW has limitation that all vrings addresses must share the same
* upper 16 msb bits part of 48 bits address. To workaround that,
* if we are using 48 bit addresses switch to 32 bit allocation
* before allocating vring memory.
*
* There's no check for the return value of dma_set_mask_and_coherent,
* since we assume if we were able to set the mask during
* initialization in this system it will not fail if we set it again
*/
if (wil->use_extended_dma_addr)
dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
pmc->pring_va = dma_alloc_coherent(dev,
sizeof(struct vring_tx_desc) * num_descriptors,
&pmc->pring_pa,
GFP_KERNEL);
if (wil->use_extended_dma_addr)
dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48));
wil_dbg_misc(wil,
"pmc_alloc: allocated pring %p => %pad. %zd x %d = total %zd bytes\n",
pmc->pring_va, &pmc->pring_pa,

View File

@ -123,15 +123,32 @@ static int wil_vring_alloc(struct wil6210_priv *wil, struct vring *vring)
vring->va = NULL;
return -ENOMEM;
}
/* vring->va should be aligned on its size rounded up to power of 2
* This is granted by the dma_alloc_coherent
* This is granted by the dma_alloc_coherent.
*
* HW has limitation that all vrings addresses must share the same
* upper 16 msb bits part of 48 bits address. To workaround that,
* if we are using 48 bit addresses switch to 32 bit allocation
* before allocating vring memory.
*
* There's no check for the return value of dma_set_mask_and_coherent,
* since we assume if we were able to set the mask during
* initialization in this system it will not fail if we set it again
*/
if (wil->use_extended_dma_addr)
dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
vring->va = dma_alloc_coherent(dev, sz, &vring->pa, GFP_KERNEL);
if (!vring->va) {
kfree(vring->ctx);
vring->ctx = NULL;
return -ENOMEM;
}
if (wil->use_extended_dma_addr)
dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48));
/* initially, all descriptors are SW owned
* For Tx and Rx, ownership bit is at the same location, thus
* we can use any

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2016 Qualcomm Atheros, Inc.
* Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -40,6 +40,7 @@ extern bool disable_ap_sme;
#define WIL_FW_NAME_SPARROW_PLUS "wil6210_sparrow_plus.fw" /* code Sparrow D0 */
#define WIL_BOARD_FILE_NAME "wil6210.brd" /* board & radio parameters */
#define WIL_DEFAULT_BUS_REQUEST_KBPS 128000 /* ~1Gbps */
#define WIL_MAX_BUS_REQUEST_KBPS 800000 /* ~6.1Gbps */
/**
@ -139,6 +140,7 @@ struct RGF_ICR {
#define RGF_USER_USAGE_1 (0x880004)
#define RGF_USER_USAGE_6 (0x880018)
#define BIT_USER_OOB_MODE BIT(31)
#define BIT_USER_OOB_R2_MODE BIT(30)
#define RGF_USER_HW_MACHINE_STATE (0x8801dc)
#define HW_MACHINE_BOOT_DONE (0x3fffffd)
#define RGF_USER_USER_CPU_0 (0x8801e0)
@ -612,6 +614,8 @@ struct wil6210_priv {
u16 channel; /* relevant in AP mode */
int sinfo_gen;
u32 ap_isolate; /* no intra-BSS communication */
struct cfg80211_bss *bss; /* connected bss, relevant in STA mode */
int locally_generated_disc; /* relevant in STA mode */
/* interrupt moderation */
u32 tx_max_burst_duration;
u32 tx_interframe_timeout;
@ -657,6 +661,7 @@ struct wil6210_priv {
u8 vring2cid_tid[WIL6210_MAX_TX_RINGS][2]; /* [0] - CID, [1] - TID */
struct wil_sta_info sta[WIL6210_MAX_CID];
int bcast_vring;
bool use_extended_dma_addr; /* indicates whether we are using 48 bits */
/* scan */
struct cfg80211_scan_request *scan_request;
@ -764,6 +769,12 @@ static inline void wil_c(struct wil6210_priv *wil, u32 reg, u32 val)
print_hex_dump_debug("DBG[ WMI]" prefix_str,\
prefix_type, rowsize, \
groupsize, buf, len, ascii)
#define wil_hex_dump_misc(prefix_str, prefix_type, rowsize, \
groupsize, buf, len, ascii) \
print_hex_dump_debug("DBG[MISC]" prefix_str,\
prefix_type, rowsize, \
groupsize, buf, len, ascii)
#else /* defined(CONFIG_DYNAMIC_DEBUG) */
static inline
void wil_hex_dump_txrx(const char *prefix_str, int prefix_type, int rowsize,
@ -776,6 +787,12 @@ void wil_hex_dump_wmi(const char *prefix_str, int prefix_type, int rowsize,
int groupsize, const void *buf, size_t len, bool ascii)
{
}
static inline
void wil_hex_dump_misc(const char *prefix_str, int prefix_type, int rowsize,
int groupsize, const void *buf, size_t len, bool ascii)
{
}
#endif /* defined(CONFIG_DYNAMIC_DEBUG) */
void wil_memcpy_fromio_32(void *dst, const volatile void __iomem *src,
@ -899,7 +916,7 @@ int wmi_pcp_stop(struct wil6210_priv *wil);
int wmi_led_cfg(struct wil6210_priv *wil, bool enable);
int wmi_abort_scan(struct wil6210_priv *wil);
void wil_abort_scan(struct wil6210_priv *wil, bool sync);
void wil6210_bus_request(struct wil6210_priv *wil, u32 kbps);
void wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid,
u16 reason_code, bool from_event);
void wil_probe_client_flush(struct wil6210_priv *wil);

View File

@ -565,6 +565,7 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
(wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)) {
if (rc) {
netif_carrier_off(ndev);
wil6210_bus_request(wil, WIL_DEFAULT_BUS_REQUEST_KBPS);
wil_err(wil, "cfg80211_connect_result with failure\n");
cfg80211_connect_result(ndev, evt->bssid, NULL, 0,
NULL, 0,
@ -572,12 +573,16 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
GFP_KERNEL);
goto out;
} else {
cfg80211_connect_result(ndev, evt->bssid,
assoc_req_ie, assoc_req_ielen,
assoc_resp_ie, assoc_resp_ielen,
WLAN_STATUS_SUCCESS,
GFP_KERNEL);
struct wiphy *wiphy = wil_to_wiphy(wil);
cfg80211_ref_bss(wiphy, wil->bss);
cfg80211_connect_bss(ndev, evt->bssid, wil->bss,
assoc_req_ie, assoc_req_ielen,
assoc_resp_ie, assoc_resp_ielen,
WLAN_STATUS_SUCCESS, GFP_KERNEL,
NL80211_TIMEOUT_UNSPECIFIED);
}
wil->bss = NULL;
} else if ((wdev->iftype == NL80211_IFTYPE_AP) ||
(wdev->iftype == NL80211_IFTYPE_P2P_GO)) {
if (rc) {
@ -1492,6 +1497,7 @@ int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac,
wil_dbg_wmi(wil, "disconnect_sta: (%pM, reason %d)\n", mac, reason);
wil->locally_generated_disc = true;
if (del_sta) {
ether_addr_copy(del_sta_cmd.dst_mac, mac);
rc = wmi_call(wil, WMI_DEL_STA_CMDID, &del_sta_cmd,
@ -1733,14 +1739,19 @@ int wmi_new_sta(struct wil6210_priv *wil, const u8 *mac, u8 aid)
void wmi_event_flush(struct wil6210_priv *wil)
{
ulong flags;
struct pending_wmi_event *evt, *t;
wil_dbg_wmi(wil, "event_flush\n");
spin_lock_irqsave(&wil->wmi_ev_lock, flags);
list_for_each_entry_safe(evt, t, &wil->pending_wmi_ev, list) {
list_del(&evt->list);
kfree(evt);
}
spin_unlock_irqrestore(&wil->wmi_ev_lock, flags);
}
static bool wmi_evt_call_handler(struct wil6210_priv *wil, int id,

View File

@ -513,7 +513,7 @@ struct atmel_private {
} station_state;
int operating_mode, power_mode;
time_t last_qual;
unsigned long last_qual;
int beacons_this_sec;
int channel;
int reg_domain, config_reg_domain;

View File

@ -18,14 +18,14 @@ config BRCMSMAC
module, the driver will be called brcmsmac.ko.
config BRCMFMAC
tristate "Broadcom IEEE802.11n embedded FullMAC WLAN driver"
tristate "Broadcom FullMAC WLAN driver"
depends on CFG80211
select BRCMUTIL
---help---
This module adds support for embedded wireless adapters based on
Broadcom IEEE802.11n FullMAC chipsets. It has to work with at least
one of the bus interface support. If you choose to build a module,
it'll be called brcmfmac.ko.
This module adds support for wireless adapters based on Broadcom
FullMAC chipsets. It has to work with at least one of the bus
interface support. If you choose to build a module, it'll be called
brcmfmac.ko.
config BRCMFMAC_PROTO_BCDC
bool

View File

@ -345,6 +345,36 @@ brcmf_proto_bcdc_txdata(struct brcmf_pub *drvr, int ifidx, u8 offset,
return brcmf_bus_txdata(drvr->bus_if, pktbuf);
}
void brcmf_proto_bcdc_txflowblock(struct device *dev, bool state)
{
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
struct brcmf_pub *drvr = bus_if->drvr;
brcmf_dbg(TRACE, "Enter\n");
brcmf_fws_bus_blocked(drvr, state);
}
void
brcmf_proto_bcdc_txcomplete(struct device *dev, struct sk_buff *txp,
bool success)
{
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
struct brcmf_pub *drvr = bus_if->drvr;
struct brcmf_if *ifp;
/* await txstatus signal for firmware if active */
if (brcmf_fws_fc_active(drvr->fws)) {
if (!success)
brcmf_fws_bustxfail(drvr->fws, txp);
} else {
if (brcmf_proto_bcdc_hdrpull(drvr, false, txp, &ifp))
brcmu_pkt_buf_free_skb(txp);
else
brcmf_txfinalize(ifp, txp, success);
}
}
static void
brcmf_proto_bcdc_configure_addr_mode(struct brcmf_pub *drvr, int ifidx,
enum proto_addr_mode addr_mode)
@ -369,6 +399,30 @@ static void brcmf_proto_bcdc_rxreorder(struct brcmf_if *ifp,
brcmf_fws_rxreorder(ifp, skb);
}
static void
brcmf_proto_bcdc_add_if(struct brcmf_if *ifp)
{
brcmf_fws_add_interface(ifp);
}
static void
brcmf_proto_bcdc_del_if(struct brcmf_if *ifp)
{
brcmf_fws_del_interface(ifp);
}
static void
brcmf_proto_bcdc_reset_if(struct brcmf_if *ifp)
{
brcmf_fws_reset_interface(ifp);
}
static int
brcmf_proto_bcdc_init_done(struct brcmf_pub *drvr)
{
return brcmf_fws_init(drvr);
}
int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr)
{
struct brcmf_bcdc *bcdc;
@ -392,6 +446,10 @@ int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr)
drvr->proto->delete_peer = brcmf_proto_bcdc_delete_peer;
drvr->proto->add_tdls_peer = brcmf_proto_bcdc_add_tdls_peer;
drvr->proto->rxreorder = brcmf_proto_bcdc_rxreorder;
drvr->proto->add_if = brcmf_proto_bcdc_add_if;
drvr->proto->del_if = brcmf_proto_bcdc_del_if;
drvr->proto->reset_if = brcmf_proto_bcdc_reset_if;
drvr->proto->init_done = brcmf_proto_bcdc_init_done;
drvr->proto->pd = bcdc;
drvr->hdrlen += BCDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES;
@ -406,6 +464,7 @@ int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr)
void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr)
{
brcmf_fws_deinit(drvr);
kfree(drvr->proto->pd);
drvr->proto->pd = NULL;
}

View File

@ -19,6 +19,9 @@
#ifdef CONFIG_BRCMFMAC_PROTO_BCDC
int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr);
void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr);
void brcmf_proto_bcdc_txflowblock(struct device *dev, bool state);
void brcmf_proto_bcdc_txcomplete(struct device *dev, struct sk_buff *txp,
bool success);
#else
static inline int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr) { return 0; }
static inline void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr) {}

View File

@ -229,11 +229,6 @@ int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings);
void brcmf_detach(struct device *dev);
/* Indication from bus module that dongle should be reset */
void brcmf_dev_reset(struct device *dev);
/* Indication from bus module to change flow-control state */
void brcmf_txflowblock(struct device *dev, bool state);
/* Notify the bus has transferred the tx packet to firmware */
void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success);
/* Configure the "global" bus state used by upper layers */
void brcmf_bus_change_state(struct brcmf_bus *bus, enum brcmf_bus_state state);

View File

@ -3097,6 +3097,9 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
status = e->status;
if (status == BRCMF_E_STATUS_ABORT)
goto exit;
if (!test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
brcmf_err("scan not ready, bsscfgidx=%d\n", ifp->bsscfgidx);
return -EPERM;
@ -6450,7 +6453,8 @@ static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
BIT(NL80211_BSS_SELECT_ATTR_BAND_PREF) |
BIT(NL80211_BSS_SELECT_ATTR_RSSI_ADJUST);
wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT |
wiphy->flags |= WIPHY_FLAG_NETNS_OK |
WIPHY_FLAG_PS_ON_BY_DEFAULT |
WIPHY_FLAG_OFFCHAN_TX |
WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_TDLS))
@ -6736,6 +6740,10 @@ static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy,
s32 err;
int i;
/* The country code gets set to "00" by default at boot, ignore */
if (req->alpha2[0] == '0' && req->alpha2[1] == '0')
return;
/* ignore non-ISO3166 country codes */
for (i = 0; i < sizeof(req->alpha2); i++)
if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') {

View File

@ -161,7 +161,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
strsep(&ptr, "\n");
/* Print fw version info */
brcmf_err("Firmware version = %s\n", buf);
brcmf_info("Firmware version = %s\n", buf);
/* locate firmware version number for ethtool */
ptr = strrchr(buf, ' ') + 1;

View File

@ -32,7 +32,6 @@
#include "p2p.h"
#include "cfg80211.h"
#include "fwil.h"
#include "fwsignal.h"
#include "feature.h"
#include "proto.h"
#include "pcie.h"
@ -283,16 +282,6 @@ void brcmf_txflowblock_if(struct brcmf_if *ifp,
spin_unlock_irqrestore(&ifp->netif_stop_lock, flags);
}
void brcmf_txflowblock(struct device *dev, bool state)
{
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
struct brcmf_pub *drvr = bus_if->drvr;
brcmf_dbg(TRACE, "Enter\n");
brcmf_fws_bus_blocked(drvr, state);
}
void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb)
{
if (skb->pkt_type == PACKET_MULTICAST)
@ -393,24 +382,6 @@ void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success)
brcmu_pkt_buf_free_skb(txp);
}
void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success)
{
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
struct brcmf_pub *drvr = bus_if->drvr;
struct brcmf_if *ifp;
/* await txstatus signal for firmware if active */
if (brcmf_fws_fc_active(drvr->fws)) {
if (!success)
brcmf_fws_bustxfail(drvr->fws, txp);
} else {
if (brcmf_proto_hdrpull(drvr, false, txp, &ifp))
brcmu_pkt_buf_free_skb(txp);
else
brcmf_txfinalize(ifp, txp, success);
}
}
static void brcmf_ethtool_get_drvinfo(struct net_device *ndev,
struct ethtool_drvinfo *info)
{
@ -504,8 +475,9 @@ int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked)
ndev->needed_headroom += drvr->hdrlen;
ndev->ethtool_ops = &brcmf_ethtool_ops;
/* set the mac address */
/* set the mac address & netns */
memcpy(ndev->dev_addr, ifp->mac_addr, ETH_ALEN);
dev_net_set(ndev, wiphy_net(cfg_to_wiphy(drvr->config)));
INIT_WORK(&ifp->multicast_work, _brcmf_set_multicast_list);
INIT_WORK(&ifp->ndoffload_work, _brcmf_update_ndtable);
@ -734,10 +706,28 @@ void brcmf_remove_interface(struct brcmf_if *ifp, bool rtnl_locked)
return;
brcmf_dbg(TRACE, "Enter, bsscfgidx=%d, ifidx=%d\n", ifp->bsscfgidx,
ifp->ifidx);
brcmf_fws_del_interface(ifp);
brcmf_proto_del_if(ifp->drvr, ifp);
brcmf_del_if(ifp->drvr, ifp->bsscfgidx, rtnl_locked);
}
static int brcmf_psm_watchdog_notify(struct brcmf_if *ifp,
const struct brcmf_event_msg *evtmsg,
void *data)
{
int err;
brcmf_dbg(TRACE, "enter: bsscfgidx=%d\n", ifp->bsscfgidx);
brcmf_err("PSM's watchdog has fired!\n");
err = brcmf_debug_create_memdump(ifp->drvr->bus_if, data,
evtmsg->datalen);
if (err)
brcmf_err("Failed to get memory dump, %d\n", err);
return err;
}
#ifdef CONFIG_INET
#define ARPOL_MAX_ENTRIES 8
static int brcmf_inetaddr_changed(struct notifier_block *nb,
@ -917,6 +907,10 @@ int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings)
goto fail;
}
/* Attach to events important for core code */
brcmf_fweh_register(drvr, BRCMF_E_PSM_WATCHDOG,
brcmf_psm_watchdog_notify);
/* attach firmware event handler */
brcmf_fweh_attach(drvr);
@ -992,11 +986,11 @@ int brcmf_bus_started(struct device *dev)
}
brcmf_feat_attach(drvr);
ret = brcmf_fws_init(drvr);
ret = brcmf_proto_init_done(drvr);
if (ret < 0)
goto fail;
brcmf_fws_add_interface(ifp);
brcmf_proto_add_if(drvr, ifp);
drvr->config = brcmf_cfg80211_attach(drvr, bus_if->dev,
drvr->settings->p2p_enable);
@ -1040,10 +1034,6 @@ int brcmf_bus_started(struct device *dev)
brcmf_cfg80211_detach(drvr->config);
drvr->config = NULL;
}
if (drvr->fws) {
brcmf_fws_del_interface(ifp);
brcmf_fws_deinit(drvr);
}
brcmf_net_detach(ifp->ndev, false);
if (p2p_ifp)
brcmf_net_detach(p2p_ifp->ndev, false);
@ -1109,8 +1099,6 @@ void brcmf_detach(struct device *dev)
brcmf_cfg80211_detach(drvr->config);
brcmf_fws_deinit(drvr);
brcmf_bus_stop(drvr->bus_if);
brcmf_proto_detach(drvr);

View File

@ -27,8 +27,8 @@
static struct dentry *root_folder;
static int brcmf_debug_create_memdump(struct brcmf_bus *bus, const void *data,
size_t len)
int brcmf_debug_create_memdump(struct brcmf_bus *bus, const void *data,
size_t len)
{
void *dump;
size_t ramsize;
@ -54,24 +54,6 @@ static int brcmf_debug_create_memdump(struct brcmf_bus *bus, const void *data,
return 0;
}
static int brcmf_debug_psm_watchdog_notify(struct brcmf_if *ifp,
const struct brcmf_event_msg *evtmsg,
void *data)
{
int err;
brcmf_dbg(TRACE, "enter: bsscfgidx=%d\n", ifp->bsscfgidx);
brcmf_err("PSM's watchdog has fired!\n");
err = brcmf_debug_create_memdump(ifp->drvr->bus_if, data,
evtmsg->datalen);
if (err)
brcmf_err("Failed to get memory dump, %d\n", err);
return err;
}
void brcmf_debugfs_init(void)
{
root_folder = debugfs_create_dir(KBUILD_MODNAME, NULL);
@ -99,9 +81,7 @@ int brcmf_debug_attach(struct brcmf_pub *drvr)
if (IS_ERR(drvr->dbgfs_dir))
return PTR_ERR(drvr->dbgfs_dir);
return brcmf_fweh_register(drvr, BRCMF_E_PSM_WATCHDOG,
brcmf_debug_psm_watchdog_notify);
return 0;
}
void brcmf_debug_detach(struct brcmf_pub *drvr)

View File

@ -59,6 +59,10 @@ void __brcmf_err(const char *func, const char *fmt, ...);
} while (0)
#if defined(DEBUG) || defined(CONFIG_BRCM_TRACING)
/* For debug/tracing purposes treat info messages as errors */
#define brcmf_info brcmf_err
__printf(3, 4)
void __brcmf_dbg(u32 level, const char *func, const char *fmt, ...);
#define brcmf_dbg(level, fmt, ...) \
@ -77,6 +81,11 @@ do { \
#else /* defined(DEBUG) || defined(CONFIG_BRCM_TRACING) */
#define brcmf_info(fmt, ...) \
do { \
pr_info("%s: " fmt, __func__, ##__VA_ARGS__); \
} while (0)
#define brcmf_dbg(level, fmt, ...) no_printk(fmt, ##__VA_ARGS__)
#define BRCMF_DATA_ON() 0
@ -99,6 +108,7 @@ do { \
extern int brcmf_msg_level;
struct brcmf_bus;
struct brcmf_pub;
#ifdef DEBUG
void brcmf_debugfs_init(void);
@ -108,6 +118,8 @@ void brcmf_debug_detach(struct brcmf_pub *drvr);
struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr);
int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn,
int (*read_fn)(struct seq_file *seq, void *data));
int brcmf_debug_create_memdump(struct brcmf_bus *bus, const void *data,
size_t len);
#else
static inline void brcmf_debugfs_init(void)
{
@ -128,6 +140,12 @@ int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn,
{
return 0;
}
static inline
int brcmf_debug_create_memdump(struct brcmf_bus *bus, const void *data,
size_t len)
{
return 0;
}
#endif
#endif /* BRCMFMAC_DEBUG_H */

View File

@ -22,9 +22,9 @@
#include "core.h"
#include "debug.h"
#include "tracepoint.h"
#include "fwsignal.h"
#include "fweh.h"
#include "fwil.h"
#include "proto.h"
/**
* struct brcmf_fweh_queue_item - event item on event queue.
@ -172,14 +172,14 @@ static void brcmf_fweh_handle_if_event(struct brcmf_pub *drvr,
if (IS_ERR(ifp))
return;
if (!is_p2pdev)
brcmf_fws_add_interface(ifp);
brcmf_proto_add_if(drvr, ifp);
if (!drvr->fweh.evt_handler[BRCMF_E_IF])
if (brcmf_net_attach(ifp, false) < 0)
return;
}
if (ifp && ifevent->action == BRCMF_E_IF_CHANGE)
brcmf_fws_reset_interface(ifp);
brcmf_proto_reset_if(drvr, ifp);
err = brcmf_fweh_call_event_handler(ifp, emsg->event_code, emsg, data);

View File

@ -1877,6 +1877,7 @@ static int brcmf_pcie_pm_enter_D3(struct device *dev)
BRCMF_PCIE_MBDATA_TIMEOUT);
if (!devinfo->mbdata_completed) {
brcmf_err("Timeout on response for entering D3 substate\n");
brcmf_bus_change_state(bus, BRCMF_BUS_UP);
return -EIO;
}

View File

@ -182,7 +182,6 @@ int brcmf_pno_clean(struct brcmf_if *ifp)
int brcmf_pno_start_sched_scan(struct brcmf_if *ifp,
struct cfg80211_sched_scan_request *req)
{
struct brcmu_d11inf *d11inf;
struct brcmf_pno_config_le pno_cfg;
struct cfg80211_ssid *ssid;
u16 chan;
@ -209,7 +208,6 @@ int brcmf_pno_start_sched_scan(struct brcmf_if *ifp,
}
/* configure channels to use */
d11inf = &ifp->drvr->config->d11inf;
for (i = 0; i < req->n_channels; i++) {
chan = req->channels[i]->hw_value;
pno_cfg.channel_list[i] = cpu_to_le16(chan);

View File

@ -44,6 +44,10 @@ struct brcmf_proto {
void (*add_tdls_peer)(struct brcmf_pub *drvr, int ifidx,
u8 peer[ETH_ALEN]);
void (*rxreorder)(struct brcmf_if *ifp, struct sk_buff *skb);
void (*add_if)(struct brcmf_if *ifp);
void (*del_if)(struct brcmf_if *ifp);
void (*reset_if)(struct brcmf_if *ifp);
int (*init_done)(struct brcmf_pub *drvr);
void *pd;
};
@ -118,4 +122,36 @@ brcmf_proto_rxreorder(struct brcmf_if *ifp, struct sk_buff *skb)
ifp->drvr->proto->rxreorder(ifp, skb);
}
static inline void
brcmf_proto_add_if(struct brcmf_pub *drvr, struct brcmf_if *ifp)
{
if (!drvr->proto->add_if)
return;
drvr->proto->add_if(ifp);
}
static inline void
brcmf_proto_del_if(struct brcmf_pub *drvr, struct brcmf_if *ifp)
{
if (!drvr->proto->del_if)
return;
drvr->proto->del_if(ifp);
}
static inline void
brcmf_proto_reset_if(struct brcmf_pub *drvr, struct brcmf_if *ifp)
{
if (!drvr->proto->reset_if)
return;
drvr->proto->reset_if(ifp);
}
static inline int
brcmf_proto_init_done(struct brcmf_pub *drvr)
{
if (!drvr->proto->init_done)
return 0;
return drvr->proto->init_done(drvr);
}
#endif /* BRCMFMAC_PROTO_H */

View File

@ -44,6 +44,7 @@
#include "firmware.h"
#include "core.h"
#include "common.h"
#include "bcdc.h"
#define DCMD_RESP_TIMEOUT msecs_to_jiffies(2500)
#define CTL_DONE_TIMEOUT msecs_to_jiffies(2500)
@ -2265,7 +2266,8 @@ static int brcmf_sdio_txpkt(struct brcmf_sdio *bus, struct sk_buff_head *pktq,
bus->tx_seq = (bus->tx_seq + pktq->qlen) % SDPCM_SEQ_WRAP;
skb_queue_walk_safe(pktq, pkt_next, tmp) {
__skb_unlink(pkt_next, pktq);
brcmf_txcomplete(bus->sdiodev->dev, pkt_next, ret == 0);
brcmf_proto_bcdc_txcomplete(bus->sdiodev->dev, pkt_next,
ret == 0);
}
return ret;
}
@ -2328,7 +2330,7 @@ static uint brcmf_sdio_sendfromq(struct brcmf_sdio *bus, uint maxframes)
if ((bus->sdiodev->state == BRCMF_SDIOD_DATA) &&
bus->txoff && (pktq_len(&bus->txq) < TXLOW)) {
bus->txoff = false;
brcmf_txflowblock(bus->sdiodev->dev, false);
brcmf_proto_bcdc_txflowblock(bus->sdiodev->dev, false);
}
return cnt;
@ -2753,7 +2755,7 @@ static int brcmf_sdio_bus_txdata(struct device *dev, struct sk_buff *pkt)
if (pktq_len(&bus->txq) >= TXHI) {
bus->txoff = true;
brcmf_txflowblock(dev, true);
brcmf_proto_bcdc_txflowblock(dev, true);
}
spin_unlock_bh(&bus->txq_lock);

View File

@ -29,6 +29,7 @@
#include "usb.h"
#include "core.h"
#include "common.h"
#include "bcdc.h"
#define IOCTL_RESP_TIMEOUT msecs_to_jiffies(2000)
@ -482,13 +483,13 @@ static void brcmf_usb_tx_complete(struct urb *urb)
req->skb);
brcmf_usb_del_fromq(devinfo, req);
brcmf_txcomplete(devinfo->dev, req->skb, urb->status == 0);
brcmf_proto_bcdc_txcomplete(devinfo->dev, req->skb, urb->status == 0);
req->skb = NULL;
brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req, &devinfo->tx_freecount);
spin_lock_irqsave(&devinfo->tx_flowblock_lock, flags);
if (devinfo->tx_freecount > devinfo->tx_high_watermark &&
devinfo->tx_flowblock) {
brcmf_txflowblock(devinfo->dev, false);
brcmf_proto_bcdc_txflowblock(devinfo->dev, false);
devinfo->tx_flowblock = false;
}
spin_unlock_irqrestore(&devinfo->tx_flowblock_lock, flags);
@ -635,7 +636,7 @@ static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb)
spin_lock_irqsave(&devinfo->tx_flowblock_lock, flags);
if (devinfo->tx_freecount < devinfo->tx_low_watermark &&
!devinfo->tx_flowblock) {
brcmf_txflowblock(dev, true);
brcmf_proto_bcdc_txflowblock(dev, true);
devinfo->tx_flowblock = true;
}
spin_unlock_irqrestore(&devinfo->tx_flowblock_lock, flags);

View File

@ -3539,9 +3539,6 @@ static int ipw_load(struct ipw_priv *priv)
fw_img = &fw->data[le32_to_cpu(fw->boot_size) +
le32_to_cpu(fw->ucode_size)];
if (rc < 0)
goto error;
if (!priv->rxq)
priv->rxq = ipw_rx_queue_alloc(priv);
else

View File

@ -153,7 +153,8 @@ int mwifiex_cmd_issue_chan_report_request(struct mwifiex_private *priv,
cmd->command = cpu_to_le16(HostCmd_CMD_CHAN_REPORT_REQUEST);
cmd->size = cpu_to_le16(S_DS_GEN);
le16_add_cpu(&cmd->size, sizeof(struct host_cmd_ds_chan_rpt_req));
le16_unaligned_add_cpu(&cmd->size,
sizeof(struct host_cmd_ds_chan_rpt_req));
cr_req->chan_desc.start_freq = cpu_to_le16(MWIFIEX_A_BAND_START_FREQ);
cr_req->chan_desc.chan_num = radar_params->chandef->chan->hw_value;

View File

@ -594,6 +594,24 @@ int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy)
return 0;
}
static void mwifiex_reg_apply_radar_flags(struct wiphy *wiphy)
{
struct ieee80211_supported_band *sband;
struct ieee80211_channel *chan;
unsigned int i;
if (!wiphy->bands[NL80211_BAND_5GHZ])
return;
sband = wiphy->bands[NL80211_BAND_5GHZ];
for (i = 0; i < sband->n_channels; i++) {
chan = &sband->channels[i];
if ((!(chan->flags & IEEE80211_CHAN_DISABLED)) &&
(chan->flags & IEEE80211_CHAN_RADAR))
chan->flags |= IEEE80211_CHAN_NO_IR;
}
}
/*
* CFG802.11 regulatory domain callback function.
*
@ -613,6 +631,7 @@ static void mwifiex_reg_notifier(struct wiphy *wiphy,
mwifiex_dbg(adapter, INFO,
"info: cfg80211 regulatory domain callback for %c%c\n",
request->alpha2[0], request->alpha2[1]);
mwifiex_reg_apply_radar_flags(wiphy);
switch (request->initiator) {
case NL80211_REGDOM_SET_BY_DRIVER:

View File

@ -242,7 +242,7 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
mwifiex_dbg(adapter, CMD,
"cmd: DNLD_CMD: %#x, act %#x, len %d, seqno %#x\n",
cmd_code,
le16_to_cpu(*(__le16 *)((u8 *)host_cmd + S_DS_GEN)),
get_unaligned_le16((u8 *)host_cmd + S_DS_GEN),
cmd_size, le16_to_cpu(host_cmd->seq_num));
mwifiex_dbg_dump(adapter, CMD_D, "cmd buffer:", host_cmd, cmd_size);
@ -286,7 +286,7 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
(adapter->dbg.last_cmd_index + 1) % DBG_CMD_NUM;
adapter->dbg.last_cmd_id[adapter->dbg.last_cmd_index] = cmd_code;
adapter->dbg.last_cmd_act[adapter->dbg.last_cmd_index] =
le16_to_cpu(*(__le16 *) ((u8 *) host_cmd + S_DS_GEN));
get_unaligned_le16((u8 *)host_cmd + S_DS_GEN);
/* Clear BSS_NO_BITS from HostCmd */
cmd_code &= HostCmd_CMD_ID_MASK;

View File

@ -31,17 +31,17 @@ struct rfc_1042_hdr {
u8 llc_ctrl;
u8 snap_oui[3];
__be16 snap_type;
};
} __packed;
struct rx_packet_hdr {
struct ethhdr eth803_hdr;
struct rfc_1042_hdr rfc1042_hdr;
};
} __packed;
struct tx_packet_hdr {
struct ethhdr eth803_hdr;
struct rfc_1042_hdr rfc1042_hdr;
};
} __packed;
#define B_SUPPORTED_RATES 5
#define G_SUPPORTED_RATES 9
@ -707,7 +707,7 @@ struct uap_txpd {
u8 reserved1[2];
u8 tx_token_id;
u8 reserved[2];
};
} __packed;
struct uap_rxpd {
u8 bss_type;
@ -723,7 +723,7 @@ struct uap_rxpd {
u8 ht_info;
u8 reserved[3];
u8 flags;
};
} __packed;
struct mwifiex_fw_chan_stats {
u8 chan_num;
@ -987,7 +987,7 @@ struct mwifiex_ps_param {
__le16 adhoc_wake_period;
__le16 mode;
__le16 delay_to_ps;
};
} __packed;
#define HS_DEF_WAKE_INTERVAL 100
#define HS_DEF_INACTIVITY_TIMEOUT 50
@ -996,7 +996,7 @@ struct mwifiex_ps_param_in_hs {
struct mwifiex_ie_types_header header;
__le32 hs_wake_int;
__le32 hs_inact_timeout;
};
} __packed;
#define BITMAP_AUTO_DS 0x01
#define BITMAP_STA_PS 0x10
@ -1062,7 +1062,7 @@ struct host_cmd_ds_802_11_rssi_info {
__le16 nbcn;
__le16 reserved[9];
long long reserved_1;
};
} __packed;
struct host_cmd_ds_802_11_rssi_info_rsp {
__le16 action;
@ -1077,12 +1077,12 @@ struct host_cmd_ds_802_11_rssi_info_rsp {
__le16 bcn_rssi_avg;
__le16 bcn_nf_avg;
long long tsf_bcn;
};
} __packed;
struct host_cmd_ds_802_11_mac_address {
__le16 action;
u8 mac_addr[ETH_ALEN];
};
} __packed;
struct host_cmd_ds_mac_control {
__le32 action;
@ -1230,7 +1230,7 @@ struct host_cmd_ds_802_11_get_log {
__le32 wep_icv_err_cnt[4];
__le32 bcn_rcv_cnt;
__le32 bcn_miss_cnt;
};
} __packed;
/* Enumeration for rate format */
enum _mwifiex_rate_format {
@ -1368,12 +1368,12 @@ struct host_cmd_ds_rf_ant_mimo {
__le16 tx_ant_mode;
__le16 action_rx;
__le16 rx_ant_mode;
};
} __packed;
struct host_cmd_ds_rf_ant_siso {
__le16 action;
__le16 ant_mode;
};
} __packed;
struct host_cmd_ds_tdls_oper {
__le16 tdls_action;
@ -1383,13 +1383,13 @@ struct host_cmd_ds_tdls_oper {
struct mwifiex_tdls_config {
__le16 enable;
};
} __packed;
struct mwifiex_tdls_config_cs_params {
u8 unit_time;
u8 thr_otherlink;
u8 thr_directlink;
};
} __packed;
struct mwifiex_tdls_init_cs_params {
u8 peer_mac[ETH_ALEN];
@ -1404,7 +1404,7 @@ struct mwifiex_tdls_init_cs_params {
struct mwifiex_tdls_stop_cs_params {
u8 peer_mac[ETH_ALEN];
};
} __packed;
struct host_cmd_ds_tdls_config {
__le16 tdls_action;
@ -1709,7 +1709,7 @@ struct mwifiex_ie_types_local_pwr_constraint {
struct mwifiex_ie_types_wmm_param_set {
struct mwifiex_ie_types_header header;
u8 wmm_ie[1];
};
} __packed;
struct mwifiex_ie_types_mgmt_frame {
struct mwifiex_ie_types_header header;
@ -1834,7 +1834,7 @@ struct host_cmd_ds_mem_access {
__le16 reserved;
__le32 addr;
__le32 value;
};
} __packed;
struct mwifiex_ie_types_qos_info {
struct mwifiex_ie_types_header header;

View File

@ -131,9 +131,10 @@ mwifiex_update_autoindex_ies(struct mwifiex_private *priv,
sizeof(struct mwifiex_ie));
}
le16_add_cpu(&ie_list->len,
le16_to_cpu(priv->mgmt_ie[index].ie_length) +
MWIFIEX_IE_HDR_SIZE);
le16_unaligned_add_cpu(&ie_list->len,
le16_to_cpu(
priv->mgmt_ie[index].ie_length) +
MWIFIEX_IE_HDR_SIZE);
input_len -= tlv_len + MWIFIEX_IE_HDR_SIZE;
}
@ -172,21 +173,21 @@ mwifiex_update_uap_custom_ie(struct mwifiex_private *priv,
le16_to_cpu(beacon_ie->ie_length);
memcpy(pos, beacon_ie, len);
pos += len;
le16_add_cpu(&ap_custom_ie->len, len);
le16_unaligned_add_cpu(&ap_custom_ie->len, len);
}
if (pr_ie) {
len = sizeof(struct mwifiex_ie) - IEEE_MAX_IE_SIZE +
le16_to_cpu(pr_ie->ie_length);
memcpy(pos, pr_ie, len);
pos += len;
le16_add_cpu(&ap_custom_ie->len, len);
le16_unaligned_add_cpu(&ap_custom_ie->len, len);
}
if (ar_ie) {
len = sizeof(struct mwifiex_ie) - IEEE_MAX_IE_SIZE +
le16_to_cpu(ar_ie->ie_length);
memcpy(pos, ar_ie, len);
pos += len;
le16_add_cpu(&ap_custom_ie->len, len);
le16_unaligned_add_cpu(&ap_custom_ie->len, len);
}
ret = mwifiex_update_autoindex_ies(priv, ap_custom_ie);
@ -242,7 +243,7 @@ static int mwifiex_update_vs_ie(const u8 *ies, int ies_len,
vs_ie = (struct ieee_types_header *)vendor_ie;
memcpy(ie->ie_buffer + le16_to_cpu(ie->ie_length),
vs_ie, vs_ie->len + 2);
le16_add_cpu(&ie->ie_length, vs_ie->len + 2);
le16_unaligned_add_cpu(&ie->ie_length, vs_ie->len + 2);
ie->mgmt_subtype_mask = cpu_to_le16(mask);
ie->ie_index = cpu_to_le16(MWIFIEX_AUTO_IDX_MASK);
}

View File

@ -91,6 +91,8 @@ struct wep_key {
#define MWIFIEX_TDLS_DEF_QOS_CAPAB 0xf
#define MWIFIEX_PRIO_BK 2
#define MWIFIEX_PRIO_VI 5
#define MWIFIEX_SUPPORTED_CHANNELS 2
#define MWIFIEX_OPERATING_CLASSES 16
struct mwifiex_uap_bss_param {
u8 channel;

View File

@ -17,6 +17,8 @@
* this warranty disclaimer.
*/
#include <linux/suspend.h>
#include "main.h"
#include "wmm.h"
#include "cfg80211.h"
@ -511,7 +513,7 @@ static void mwifiex_terminate_workqueue(struct mwifiex_adapter *adapter)
* - Download the correct firmware to card
* - Issue the init commands to firmware
*/
static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
static int _mwifiex_fw_dpc(const struct firmware *firmware, void *context)
{
int ret;
char fmt[64];
@ -664,11 +666,18 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
mwifiex_free_adapter(adapter);
/* Tell all current and future waiters we're finished */
complete_all(fw_done);
return;
return init_failed ? -EIO : 0;
}
static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
{
_mwifiex_fw_dpc(firmware, context);
}
/*
* This function initializes the hardware and gets firmware.
* This function gets the firmware and (if called asynchronously) kicks off the
* HW init when done.
*/
static int mwifiex_init_hw_fw(struct mwifiex_adapter *adapter,
bool req_fw_nowait)
@ -691,20 +700,15 @@ static int mwifiex_init_hw_fw(struct mwifiex_adapter *adapter,
ret = request_firmware_nowait(THIS_MODULE, 1, adapter->fw_name,
adapter->dev, GFP_KERNEL, adapter,
mwifiex_fw_dpc);
if (ret < 0)
mwifiex_dbg(adapter, ERROR,
"request_firmware_nowait error %d\n", ret);
} else {
ret = request_firmware(&adapter->firmware,
adapter->fw_name,
adapter->dev);
if (ret < 0)
mwifiex_dbg(adapter, ERROR,
"request_firmware error %d\n", ret);
else
mwifiex_fw_dpc(adapter->firmware, (void *)adapter);
}
if (ret < 0)
mwifiex_dbg(adapter, ERROR, "request_firmware%s error %d\n",
req_fw_nowait ? "_nowait" : "", ret);
return ret;
}
@ -1426,6 +1430,8 @@ EXPORT_SYMBOL_GPL(mwifiex_shutdown_sw);
int
mwifiex_reinit_sw(struct mwifiex_adapter *adapter)
{
int ret;
mwifiex_init_lock_list(adapter);
if (adapter->if_ops.up_dev)
adapter->if_ops.up_dev(adapter);
@ -1472,9 +1478,15 @@ mwifiex_reinit_sw(struct mwifiex_adapter *adapter)
"%s: firmware init failed\n", __func__);
goto err_init_fw;
}
/* _mwifiex_fw_dpc() does its own cleanup */
ret = _mwifiex_fw_dpc(adapter->firmware, adapter);
if (ret) {
pr_err("Failed to bring up adapter: %d\n", ret);
return ret;
}
mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__);
complete_all(adapter->fw_done);
return 0;
err_init_fw:
@ -1510,6 +1522,7 @@ static irqreturn_t mwifiex_irq_wakeup_handler(int irq, void *priv)
/* Notify PM core we are wakeup source */
pm_wakeup_event(adapter->dev, 0);
pm_system_wakeup();
return IRQ_HANDLED;
}

View File

@ -1359,7 +1359,7 @@ mwifiex_netdev_get_priv(struct net_device *dev)
*/
static inline bool mwifiex_is_skb_mgmt_frame(struct sk_buff *skb)
{
return (le32_to_cpu(*(__le32 *)skb->data) == PKT_TYPE_MGMT);
return (get_unaligned_le32(skb->data) == PKT_TYPE_MGMT);
}
/* This function retrieves channel closed for operation by Channel

View File

@ -119,7 +119,7 @@ static int mwifiex_read_reg_byte(struct mwifiex_adapter *adapter,
*/
static bool mwifiex_pcie_ok_to_access_hw(struct mwifiex_adapter *adapter)
{
u32 *cookie_addr;
u32 cookie_value;
struct pcie_service_card *card = adapter->card;
const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
@ -127,11 +127,11 @@ static bool mwifiex_pcie_ok_to_access_hw(struct mwifiex_adapter *adapter)
return true;
if (card->sleep_cookie_vbase) {
cookie_addr = (u32 *)card->sleep_cookie_vbase;
cookie_value = get_unaligned_le32(card->sleep_cookie_vbase);
mwifiex_dbg(adapter, INFO,
"info: ACCESS_HW: sleep cookie=0x%x\n",
*cookie_addr);
if (*cookie_addr == FW_AWAKE_COOKIE)
cookie_value);
if (cookie_value == FW_AWAKE_COOKIE)
return true;
}
@ -294,8 +294,6 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev)
if (!adapter || !adapter->priv_num)
return;
cancel_work_sync(&card->work);
reg = card->pcie.reg;
if (reg)
ret = mwifiex_read_reg(adapter, reg->fw_status, &fw_status);
@ -350,22 +348,16 @@ MODULE_DEVICE_TABLE(pci, mwifiex_ids);
static void mwifiex_pcie_reset_notify(struct pci_dev *pdev, bool prepare)
{
struct mwifiex_adapter *adapter;
struct pcie_service_card *card;
struct pcie_service_card *card = pci_get_drvdata(pdev);
struct mwifiex_adapter *adapter = card->adapter;
int ret;
if (!pdev) {
pr_err("%s: PCIe device is not specified\n", __func__);
if (!adapter) {
dev_err(&pdev->dev, "%s: adapter structure is not valid\n",
__func__);
return;
}
card = (struct pcie_service_card *)pci_get_drvdata(pdev);
if (!card || !card->adapter) {
pr_err("%s: Card or adapter structure is not valid (%ld)\n",
__func__, (long)card);
return;
}
adapter = card->adapter;
mwifiex_dbg(adapter, INFO,
"%s: vendor=0x%4.04x device=0x%4.04x rev=%d %s\n",
__func__, pdev->vendor, pdev->device,
@ -385,7 +377,11 @@ static void mwifiex_pcie_reset_notify(struct pci_dev *pdev, bool prepare)
* and firmware including firmware redownload
*/
adapter->surprise_removed = false;
mwifiex_reinit_sw(adapter);
ret = mwifiex_reinit_sw(adapter);
if (ret) {
dev_err(&pdev->dev, "reinit failed: %d\n", ret);
return;
}
}
mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__);
}
@ -447,7 +443,7 @@ static void mwifiex_delay_for_sleep_cookie(struct mwifiex_adapter *adapter,
sizeof(sleep_cookie),
PCI_DMA_FROMDEVICE);
buffer = cmdrsp->data;
sleep_cookie = READ_ONCE(*(u32 *)buffer);
sleep_cookie = get_unaligned_le32(buffer);
if (sleep_cookie == MWIFIEX_DEF_SLEEP_COOKIE) {
mwifiex_dbg(adapter, INFO,
@ -1049,6 +1045,7 @@ static int mwifiex_pcie_delete_cmdrsp_buf(struct mwifiex_adapter *adapter)
static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter)
{
struct pcie_service_card *card = adapter->card;
u32 tmp;
card->sleep_cookie_vbase = pci_alloc_consistent(card->dev, sizeof(u32),
&card->sleep_cookie_pbase);
@ -1058,11 +1055,12 @@ static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter)
return -ENOMEM;
}
/* Init val of Sleep Cookie */
*(u32 *)card->sleep_cookie_vbase = FW_AWAKE_COOKIE;
tmp = FW_AWAKE_COOKIE;
put_unaligned(tmp, card->sleep_cookie_vbase);
mwifiex_dbg(adapter, INFO,
"alloc_scook: sleep cookie=0x%x\n",
*((u32 *)card->sleep_cookie_vbase));
get_unaligned(card->sleep_cookie_vbase));
return 0;
}
@ -1223,7 +1221,6 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb,
dma_addr_t buf_pa;
struct mwifiex_pcie_buf_desc *desc = NULL;
struct mwifiex_pfu_buf_desc *desc2 = NULL;
__le16 *tmp;
if (!(skb->data && skb->len)) {
mwifiex_dbg(adapter, ERROR,
@ -1244,10 +1241,8 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb,
adapter->data_sent = true;
payload = skb->data;
tmp = (__le16 *)&payload[0];
*tmp = cpu_to_le16((u16)skb->len);
tmp = (__le16 *)&payload[2];
*tmp = cpu_to_le16(MWIFIEX_TYPE_DATA);
put_unaligned_le16((u16)skb->len, payload + 0);
put_unaligned_le16(MWIFIEX_TYPE_DATA, payload + 2);
if (mwifiex_map_pci_memory(adapter, skb, skb->len,
PCI_DMA_TODEVICE))
@ -1376,7 +1371,6 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
(card->rxbd_rdptr & reg->rx_rollover_ind))) {
struct sk_buff *skb_data;
u16 rx_len;
__le16 pkt_len;
rd_index = card->rxbd_rdptr & reg->rx_mask;
skb_data = card->rx_buf_list[rd_index];
@ -1393,8 +1387,7 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
/* Get data length from interface header -
* first 2 bytes for len, next 2 bytes is for type
*/
pkt_len = *((__le16 *)skb_data->data);
rx_len = le16_to_cpu(pkt_len);
rx_len = get_unaligned_le16(skb_data->data);
if (WARN_ON(rx_len <= INTF_HEADER_LEN ||
rx_len > MWIFIEX_RX_DATA_BUF_SIZE)) {
mwifiex_dbg(adapter, ERROR,
@ -1601,8 +1594,8 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
adapter->cmd_sent = true;
*(__le16 *)&payload[0] = cpu_to_le16((u16)skb->len);
*(__le16 *)&payload[2] = cpu_to_le16(MWIFIEX_TYPE_CMD);
put_unaligned_le16((u16)skb->len, &payload[0]);
put_unaligned_le16(MWIFIEX_TYPE_CMD, &payload[2]);
if (mwifiex_map_pci_memory(adapter, skb, skb->len, PCI_DMA_TODEVICE))
return -1;
@ -1694,7 +1687,6 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
struct sk_buff *skb = card->cmdrsp_buf;
int count = 0;
u16 rx_len;
__le16 pkt_len;
mwifiex_dbg(adapter, CMD,
"info: Rx CMD Response\n");
@ -1714,8 +1706,7 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
card->cmd_buf = NULL;
}
pkt_len = *((__le16 *)skb->data);
rx_len = le16_to_cpu(pkt_len);
rx_len = get_unaligned_le16(skb->data);
skb_put(skb, MWIFIEX_UPLD_SIZE - skb->len);
skb_trim(skb, rx_len);
@ -1856,7 +1847,7 @@ static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter)
desc = card->evtbd_ring[rdptr];
memset(desc, 0, sizeof(*desc));
event = *(u32 *) &skb_cmd->data[INTF_HEADER_LEN];
event = get_unaligned_le32(&skb_cmd->data[INTF_HEADER_LEN]);
adapter->event_cause = event;
/* The first 4bytes will be the event transfer header
len is 2 bytes followed by type which is 2 bytes */
@ -2874,6 +2865,8 @@ static void mwifiex_cleanup_pcie(struct mwifiex_adapter *adapter)
int ret;
u32 fw_status;
cancel_work_sync(&card->work);
ret = mwifiex_read_reg(adapter, reg->fw_status, &fw_status);
if (fw_status == FIRMWARE_READY_PCIE) {
mwifiex_dbg(adapter, INFO,

View File

@ -691,8 +691,9 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv,
/* Increment the TLV header length by the size
appended */
le16_add_cpu(&chan_tlv_out->header.len,
sizeof(chan_tlv_out->chan_scan_param));
le16_unaligned_add_cpu(&chan_tlv_out->header.len,
sizeof(
chan_tlv_out->chan_scan_param));
/*
* The tlv buffer length is set to the number of bytes
@ -859,6 +860,7 @@ mwifiex_config_scan(struct mwifiex_private *priv,
*scan_current_only = false;
if (user_scan_in) {
u8 tmpaddr[ETH_ALEN];
/* Default the ssid_filter flag to TRUE, set false under
certain wildcard conditions and qualified by the existence
@ -883,8 +885,10 @@ mwifiex_config_scan(struct mwifiex_private *priv,
user_scan_in->specific_bssid,
sizeof(scan_cfg_out->specific_bssid));
memcpy(tmpaddr, scan_cfg_out->specific_bssid, ETH_ALEN);
if (adapter->ext_scan &&
!is_zero_ether_addr(scan_cfg_out->specific_bssid)) {
!is_zero_ether_addr(tmpaddr)) {
bssid_tlv =
(struct mwifiex_ie_types_bssid_list *)tlv_pos;
bssid_tlv->header.type = cpu_to_le16(TLV_TYPE_BSSID);
@ -947,8 +951,9 @@ mwifiex_config_scan(struct mwifiex_private *priv,
* truncate scan results. That is not an issue with an SSID
* or BSSID filter applied to the scan results in the firmware.
*/
memcpy(tmpaddr, scan_cfg_out->specific_bssid, ETH_ALEN);
if ((i && ssid_filter) ||
!is_zero_ether_addr(scan_cfg_out->specific_bssid))
!is_zero_ether_addr(tmpaddr))
*filtered_scan = true;
if (user_scan_in->scan_chan_gap) {
@ -989,10 +994,15 @@ mwifiex_config_scan(struct mwifiex_private *priv,
* If a specific BSSID or SSID is used, the number of channels in the
* scan command will be increased to the absolute maximum.
*/
if (*filtered_scan)
if (*filtered_scan) {
*max_chan_per_scan = MWIFIEX_MAX_CHANNELS_PER_SPECIFIC_SCAN;
else
*max_chan_per_scan = MWIFIEX_DEF_CHANNELS_PER_SCAN_CMD;
} else {
if (!priv->media_connected)
*max_chan_per_scan = MWIFIEX_DEF_CHANNELS_PER_SCAN_CMD;
else
*max_chan_per_scan =
MWIFIEX_DEF_CHANNELS_PER_SCAN_CMD / 2;
}
if (adapter->ext_scan) {
bss_mode = (struct mwifiex_ie_types_bss_mode *)tlv_pos;
@ -1742,7 +1752,7 @@ mwifiex_parse_single_response_buf(struct mwifiex_private *priv, u8 **bss_info,
if (*bytes_left >= sizeof(beacon_size)) {
/* Extract & convert beacon size from command buffer */
beacon_size = le16_to_cpu(*(__le16 *)(*bss_info));
beacon_size = get_unaligned_le16((*bss_info));
*bytes_left -= sizeof(beacon_size);
*bss_info += sizeof(beacon_size);
}
@ -2369,8 +2379,9 @@ int mwifiex_cmd_802_11_bg_scan_config(struct mwifiex_private *priv,
temp_chan = chan_list_tlv->chan_scan_param + chan_idx;
/* Increment the TLV header length by size appended */
le16_add_cpu(&chan_list_tlv->header.len,
sizeof(chan_list_tlv->chan_scan_param));
le16_unaligned_add_cpu(&chan_list_tlv->header.len,
sizeof(
chan_list_tlv->chan_scan_param));
temp_chan->chan_number =
bgscan_cfg_in->chan_list[chan_idx].chan_number;
@ -2407,8 +2418,8 @@ int mwifiex_cmd_802_11_bg_scan_config(struct mwifiex_private *priv,
mwifiex_bgscan_create_channel_list(priv, bgscan_cfg_in,
chan_list_tlv->
chan_scan_param);
le16_add_cpu(&chan_list_tlv->header.len,
chan_num *
le16_unaligned_add_cpu(&chan_list_tlv->header.len,
chan_num *
sizeof(chan_list_tlv->chan_scan_param[0]));
}
@ -2432,7 +2443,7 @@ int mwifiex_cmd_802_11_bg_scan_config(struct mwifiex_private *priv,
/* Append vendor specific IE TLV */
mwifiex_cmd_append_vsie_tlv(priv, MWIFIEX_VSIE_MASK_BGSCAN, &tlv_pos);
le16_add_cpu(&cmd->size, tlv_pos - bgscan_config->tlv);
le16_unaligned_add_cpu(&cmd->size, tlv_pos - bgscan_config->tlv);
return 0;
}

View File

@ -387,8 +387,6 @@ mwifiex_sdio_remove(struct sdio_func *func)
if (!adapter || !adapter->priv_num)
return;
cancel_work_sync(&card->work);
mwifiex_dbg(adapter, INFO, "info: SDIO func num=%d\n", func->num);
ret = mwifiex_sdio_read_fw_status(adapter, &firmware_stat);
@ -943,7 +941,7 @@ static int mwifiex_sdio_card_to_host(struct mwifiex_adapter *adapter,
return -1;
}
nb = le16_to_cpu(*(__le16 *) (buffer));
nb = get_unaligned_le16((buffer));
if (nb > npayload) {
mwifiex_dbg(adapter, ERROR,
"%s: invalid packet, nb=%d npayload=%d\n",
@ -951,7 +949,7 @@ static int mwifiex_sdio_card_to_host(struct mwifiex_adapter *adapter,
return -1;
}
*type = le16_to_cpu(*(__le16 *) (buffer + 2));
*type = get_unaligned_le16((buffer + 2));
return ret;
}
@ -1139,7 +1137,8 @@ static void mwifiex_deaggr_sdio_pkt(struct mwifiex_adapter *adapter,
__func__, blk_num, blk_size, total_pkt_len);
break;
}
pkt_len = le16_to_cpu(*(__le16 *)(data + SDIO_HEADER_OFFSET));
pkt_len = get_unaligned_le16((data +
SDIO_HEADER_OFFSET));
if ((pkt_len + SDIO_HEADER_OFFSET) > blk_size) {
mwifiex_dbg(adapter, ERROR,
"%s: error in pkt_len,\t"
@ -1172,10 +1171,11 @@ static int mwifiex_decode_rx_packet(struct mwifiex_adapter *adapter,
struct sk_buff *skb, u32 upld_typ)
{
u8 *cmd_buf;
__le16 *curr_ptr = (__le16 *)skb->data;
u16 pkt_len = le16_to_cpu(*curr_ptr);
u16 pkt_len;
struct mwifiex_rxinfo *rx_info;
pkt_len = get_unaligned_le16(skb->data);
if (upld_typ != MWIFIEX_TYPE_AGGR_DATA) {
skb_trim(skb, pkt_len);
skb_pull(skb, INTF_HEADER_LEN);
@ -1235,7 +1235,7 @@ static int mwifiex_decode_rx_packet(struct mwifiex_adapter *adapter,
case MWIFIEX_TYPE_EVENT:
mwifiex_dbg(adapter, EVENT,
"info: --- Rx: Event ---\n");
adapter->event_cause = le32_to_cpu(*(__le32 *) skb->data);
adapter->event_cause = get_unaligned_le32(skb->data);
if ((skb->len > 0) && (skb->len < MAX_EVENT_SIZE))
memcpy(adapter->event_body,
@ -1392,8 +1392,8 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
u32 *len_arr = card->mpa_rx.len_arr;
/* get curr PKT len & type */
pkt_len = le16_to_cpu(*(__le16 *) &curr_ptr[0]);
pkt_type = le16_to_cpu(*(__le16 *) &curr_ptr[2]);
pkt_len = get_unaligned_le16(&curr_ptr[0]);
pkt_type = get_unaligned_le16(&curr_ptr[2]);
/* copy pkt to deaggr buf */
skb_deaggr = mwifiex_alloc_dma_align_buf(len_arr[pind],
@ -1874,8 +1874,9 @@ static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter,
/* Allocate buffer and copy payload */
blk_size = MWIFIEX_SDIO_BLOCK_SIZE;
buf_block_len = (pkt_len + blk_size - 1) / blk_size;
*(__le16 *)&payload[0] = cpu_to_le16((u16)pkt_len);
*(__le16 *)&payload[2] = cpu_to_le16(type);
put_unaligned_le16((u16)pkt_len, payload + 0);
put_unaligned_le16((u32)type, payload + 2);
/*
* This is SDIO specific header
@ -2155,6 +2156,8 @@ static void mwifiex_cleanup_sdio(struct mwifiex_adapter *adapter)
{
struct sdio_mmc_card *card = adapter->card;
cancel_work_sync(&card->work);
kfree(card->mp_regs);
kfree(card->mpa_rx.skb_arr);
kfree(card->mpa_rx.len_arr);
@ -2193,6 +2196,7 @@ static void mwifiex_sdio_card_reset_work(struct mwifiex_adapter *adapter)
{
struct sdio_mmc_card *card = adapter->card;
struct sdio_func *func = card->func;
int ret;
mwifiex_shutdown_sw(adapter);
@ -2207,7 +2211,9 @@ static void mwifiex_sdio_card_reset_work(struct mwifiex_adapter *adapter)
clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &card->work_flags);
clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &card->work_flags);
mwifiex_reinit_sw(adapter);
ret = mwifiex_reinit_sw(adapter);
if (ret)
dev_err(&func->dev, "reinit failed: %d\n", ret);
}
/* This function read/write firmware */

View File

@ -126,19 +126,19 @@ static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv,
if (cmd_action == HostCmd_ACT_GEN_GET) {
snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_GET);
snmp_mib->buf_size = cpu_to_le16(MAX_SNMP_BUF_SIZE);
le16_add_cpu(&cmd->size, MAX_SNMP_BUF_SIZE);
le16_unaligned_add_cpu(&cmd->size, MAX_SNMP_BUF_SIZE);
} else if (cmd_action == HostCmd_ACT_GEN_SET) {
snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET);
snmp_mib->buf_size = cpu_to_le16(sizeof(u16));
*((__le16 *) (snmp_mib->value)) = cpu_to_le16(*ul_temp);
le16_add_cpu(&cmd->size, sizeof(u16));
put_unaligned_le16(*ul_temp, snmp_mib->value);
le16_unaligned_add_cpu(&cmd->size, sizeof(u16));
}
mwifiex_dbg(priv->adapter, CMD,
"cmd: SNMP_CMD: Action=0x%x, OID=0x%x,\t"
"OIDSize=0x%x, Value=0x%x\n",
cmd_action, cmd_oid, le16_to_cpu(snmp_mib->buf_size),
le16_to_cpu(*(__le16 *)snmp_mib->value));
get_unaligned_le16(snmp_mib->value));
return 0;
}
@ -1357,8 +1357,9 @@ mwifiex_cmd_802_11_subsc_evt(struct mwifiex_private *priv,
subsc_evt_cfg->bcn_l_rssi_cfg.evt_freq);
pos += sizeof(struct mwifiex_ie_types_rssi_threshold);
le16_add_cpu(&cmd->size,
sizeof(struct mwifiex_ie_types_rssi_threshold));
le16_unaligned_add_cpu(&cmd->size,
sizeof(
struct mwifiex_ie_types_rssi_threshold));
}
if (event_bitmap & BITMASK_BCN_RSSI_HIGH) {
@ -1378,8 +1379,9 @@ mwifiex_cmd_802_11_subsc_evt(struct mwifiex_private *priv,
subsc_evt_cfg->bcn_h_rssi_cfg.evt_freq);
pos += sizeof(struct mwifiex_ie_types_rssi_threshold);
le16_add_cpu(&cmd->size,
sizeof(struct mwifiex_ie_types_rssi_threshold));
le16_unaligned_add_cpu(&cmd->size,
sizeof(
struct mwifiex_ie_types_rssi_threshold));
}
return 0;
@ -1398,7 +1400,7 @@ mwifiex_cmd_append_rpn_expression(struct mwifiex_private *priv,
filter = &mef_entry->filter[i];
if (!filter->filt_type)
break;
*(__le32 *)stack_ptr = cpu_to_le32((u32)filter->repeat);
put_unaligned_le32((u32)filter->repeat, stack_ptr);
stack_ptr += 4;
*stack_ptr = TYPE_DNUM;
stack_ptr += 1;
@ -1410,8 +1412,7 @@ mwifiex_cmd_append_rpn_expression(struct mwifiex_private *priv,
stack_ptr += 1;
*stack_ptr = TYPE_BYTESEQ;
stack_ptr += 1;
*(__le32 *)stack_ptr = cpu_to_le32((u32)filter->offset);
put_unaligned_le32((u32)filter->offset, stack_ptr);
stack_ptr += 4;
*stack_ptr = TYPE_DNUM;
stack_ptr += 1;
@ -1683,14 +1684,15 @@ mwifiex_cmd_coalesce_cfg(struct mwifiex_private *priv,
sizeof(u8) + sizeof(u8));
/* Add the rule length to the command size*/
le16_add_cpu(&cmd->size, le16_to_cpu(rule->header.len) +
sizeof(struct mwifiex_ie_types_header));
le16_unaligned_add_cpu(&cmd->size,
le16_to_cpu(rule->header.len) +
sizeof(struct mwifiex_ie_types_header));
rule = (void *)((u8 *)rule->params + length);
}
/* Add sizeof action, num_of_rules to total command length */
le16_add_cpu(&cmd->size, sizeof(u16) + sizeof(u16));
le16_unaligned_add_cpu(&cmd->size, sizeof(u16) + sizeof(u16));
return 0;
}
@ -1708,7 +1710,7 @@ mwifiex_cmd_tdls_config(struct mwifiex_private *priv,
cmd->command = cpu_to_le16(HostCmd_CMD_TDLS_CONFIG);
cmd->size = cpu_to_le16(S_DS_GEN);
tdls_config->tdls_action = cpu_to_le16(cmd_action);
le16_add_cpu(&cmd->size, sizeof(tdls_config->tdls_action));
le16_unaligned_add_cpu(&cmd->size, sizeof(tdls_config->tdls_action));
switch (cmd_action) {
case ACT_TDLS_CS_ENABLE_CONFIG:
@ -1735,7 +1737,7 @@ mwifiex_cmd_tdls_config(struct mwifiex_private *priv,
return -ENOTSUPP;
}
le16_add_cpu(&cmd->size, len);
le16_unaligned_add_cpu(&cmd->size, len);
return 0;
}
@ -1759,7 +1761,8 @@ mwifiex_cmd_tdls_oper(struct mwifiex_private *priv,
cmd->command = cpu_to_le16(HostCmd_CMD_TDLS_OPER);
cmd->size = cpu_to_le16(S_DS_GEN);
le16_add_cpu(&cmd->size, sizeof(struct host_cmd_ds_tdls_oper));
le16_unaligned_add_cpu(&cmd->size,
sizeof(struct host_cmd_ds_tdls_oper));
tdls_oper->reason = 0;
memcpy(tdls_oper->peer_mac, oper->peer_mac, ETH_ALEN);
@ -1783,7 +1786,7 @@ mwifiex_cmd_tdls_oper(struct mwifiex_private *priv,
return -ENODATA;
}
*(__le16 *)pos = cpu_to_le16(params->capability);
put_unaligned_le16(params->capability, pos);
config_len += sizeof(params->capability);
qos_info = params->uapsd_queues | (params->max_sp << 5);
@ -1861,7 +1864,7 @@ mwifiex_cmd_tdls_oper(struct mwifiex_private *priv,
return -ENOTSUPP;
}
le16_add_cpu(&cmd->size, config_len);
le16_unaligned_add_cpu(&cmd->size, config_len);
return 0;
}
@ -2032,7 +2035,7 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
case HostCmd_CMD_VERSION_EXT:
cmd_ptr->command = cpu_to_le16(cmd_no);
cmd_ptr->params.verext.version_str_sel =
(u8) (*((u32 *) data_buf));
(u8)(get_unaligned((u32 *)data_buf));
memcpy(&cmd_ptr->params, data_buf,
sizeof(struct host_cmd_ds_version_ext));
cmd_ptr->size =
@ -2043,7 +2046,8 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
case HostCmd_CMD_MGMT_FRAME_REG:
cmd_ptr->command = cpu_to_le16(cmd_no);
cmd_ptr->params.reg_mask.action = cpu_to_le16(cmd_action);
cmd_ptr->params.reg_mask.mask = cpu_to_le32(*(u32 *)data_buf);
cmd_ptr->params.reg_mask.mask = cpu_to_le32(
get_unaligned((u32 *)data_buf));
cmd_ptr->size =
cpu_to_le16(sizeof(struct host_cmd_ds_mgmt_frame_reg) +
S_DS_GEN);
@ -2063,7 +2067,8 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
case HostCmd_CMD_P2P_MODE_CFG:
cmd_ptr->command = cpu_to_le16(cmd_no);
cmd_ptr->params.mode_cfg.action = cpu_to_le16(cmd_action);
cmd_ptr->params.mode_cfg.mode = cpu_to_le16(*(u16 *)data_buf);
cmd_ptr->params.mode_cfg.mode = cpu_to_le16(
get_unaligned((u16 *)data_buf));
cmd_ptr->size =
cpu_to_le16(sizeof(struct host_cmd_ds_p2p_mode_cfg) +
S_DS_GEN);
@ -2359,8 +2364,7 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta, bool init)
if (ret)
return -1;
if (!disable_auto_ds &&
first_sta && priv->adapter->iface_type != MWIFIEX_USB &&
if (!disable_auto_ds && first_sta &&
priv->bss_type != MWIFIEX_BSS_TYPE_UAP) {
/* Enable auto deep sleep */
auto_ds.auto_ds = DEEP_SLEEP_ON;

View File

@ -183,7 +183,7 @@ static int mwifiex_ret_802_11_snmp_mib(struct mwifiex_private *priv,
"query_type = %#x, buf size = %#x\n",
oid, query_type, le16_to_cpu(smib->buf_size));
if (query_type == HostCmd_ACT_GEN_GET) {
ul_temp = le16_to_cpu(*((__le16 *) (smib->value)));
ul_temp = get_unaligned_le16(smib->value);
if (data_buf)
*data_buf = ul_temp;
switch (oid) {
@ -741,7 +741,7 @@ mwifiex_ret_p2p_mode_cfg(struct mwifiex_private *priv,
struct host_cmd_ds_p2p_mode_cfg *mode_cfg = &resp->params.mode_cfg;
if (data_buf)
*((u16 *)data_buf) = le16_to_cpu(mode_cfg->mode);
put_unaligned_le16(le16_to_cpu(mode_cfg->mode), data_buf);
return 0;
}

View File

@ -670,7 +670,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
adapter->dbg.num_event_deauth++;
if (priv->media_connected) {
reason_code =
le16_to_cpu(*(__le16 *)adapter->event_body);
get_unaligned_le16(adapter->event_body);
mwifiex_reset_connect_state(priv, reason_code, true);
}
break;
@ -685,7 +685,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
adapter->dbg.num_event_disassoc++;
if (priv->media_connected) {
reason_code =
le16_to_cpu(*(__le16 *)adapter->event_body);
get_unaligned_le16(adapter->event_body);
mwifiex_reset_connect_state(priv, reason_code, true);
}
break;
@ -695,7 +695,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
adapter->dbg.num_event_link_lost++;
if (priv->media_connected) {
reason_code =
le16_to_cpu(*(__le16 *)adapter->event_body);
get_unaligned_le16(adapter->event_body);
mwifiex_reset_connect_state(priv, reason_code, true);
}
break;
@ -923,7 +923,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
adapter->event_body);
break;
case EVENT_AMSDU_AGGR_CTRL:
ctrl = le16_to_cpu(*(__le16 *)adapter->event_body);
ctrl = get_unaligned_le16(adapter->event_body);
mwifiex_dbg(adapter, EVENT,
"event: AMSDU_AGGR_CTRL %d\n", ctrl);

View File

@ -431,6 +431,41 @@ mwifiex_add_wmm_info_ie(struct mwifiex_private *priv, struct sk_buff *skb,
*buf++ = qosinfo; /* U-APSD no in use */
}
static void mwifiex_tdls_add_bss_co_2040(struct sk_buff *skb)
{
struct ieee_types_bss_co_2040 *bssco;
bssco = (void *)skb_put(skb, sizeof(struct ieee_types_bss_co_2040));
bssco->ieee_hdr.element_id = WLAN_EID_BSS_COEX_2040;
bssco->ieee_hdr.len = sizeof(struct ieee_types_bss_co_2040) -
sizeof(struct ieee_types_header);
bssco->bss_2040co = 0x01;
}
static void mwifiex_tdls_add_supported_chan(struct sk_buff *skb)
{
struct ieee_types_generic *supp_chan;
u8 chan_supp[] = {1, 11};
supp_chan = (void *)skb_put(skb, (sizeof(struct ieee_types_header) +
sizeof(chan_supp)));
supp_chan->ieee_hdr.element_id = WLAN_EID_SUPPORTED_CHANNELS;
supp_chan->ieee_hdr.len = sizeof(chan_supp);
memcpy(supp_chan->data, chan_supp, sizeof(chan_supp));
}
static void mwifiex_tdls_add_oper_class(struct sk_buff *skb)
{
struct ieee_types_generic *reg_class;
u8 rc_list[] = {1,
1, 2, 3, 4, 12, 22, 23, 24, 25, 27, 28, 29, 30, 32, 33};
reg_class = (void *)skb_put(skb, (sizeof(struct ieee_types_header) +
sizeof(rc_list)));
reg_class->ieee_hdr.element_id = WLAN_EID_SUPPORTED_REGULATORY_CLASSES;
reg_class->ieee_hdr.len = sizeof(rc_list);
memcpy(reg_class->data, rc_list, sizeof(rc_list));
}
static int mwifiex_prep_tdls_encap_data(struct mwifiex_private *priv,
const u8 *peer, u8 action_code,
u8 dialog_token,
@ -484,7 +519,9 @@ static int mwifiex_prep_tdls_encap_data(struct mwifiex_private *priv,
}
mwifiex_tdls_add_ext_capab(priv, skb);
mwifiex_tdls_add_qos_capab(skb);
mwifiex_tdls_add_bss_co_2040(skb);
mwifiex_tdls_add_supported_chan(skb);
mwifiex_tdls_add_oper_class(skb);
mwifiex_add_wmm_info_ie(priv, skb, 0);
break;
@ -522,7 +559,9 @@ static int mwifiex_prep_tdls_encap_data(struct mwifiex_private *priv,
}
mwifiex_tdls_add_ext_capab(priv, skb);
mwifiex_tdls_add_qos_capab(skb);
mwifiex_tdls_add_bss_co_2040(skb);
mwifiex_tdls_add_supported_chan(skb);
mwifiex_tdls_add_oper_class(skb);
mwifiex_add_wmm_info_ie(priv, skb, 0);
break;
@ -612,6 +651,9 @@ int mwifiex_send_tdls_data_frame(struct mwifiex_private *priv, const u8 *peer,
sizeof(struct ieee_types_bss_co_2040) +
sizeof(struct ieee80211_ht_operation) +
sizeof(struct ieee80211_tdls_lnkie) +
(2 * (sizeof(struct ieee_types_header))) +
MWIFIEX_SUPPORTED_CHANNELS +
MWIFIEX_OPERATING_CLASSES +
sizeof(struct ieee80211_wmm_param_ie) +
extra_ies_len;
@ -760,7 +802,10 @@ mwifiex_construct_tdls_action_frame(struct mwifiex_private *priv,
}
mwifiex_tdls_add_ext_capab(priv, skb);
mwifiex_tdls_add_bss_co_2040(skb);
mwifiex_tdls_add_supported_chan(skb);
mwifiex_tdls_add_qos_capab(skb);
mwifiex_tdls_add_oper_class(skb);
break;
default:
mwifiex_dbg(priv->adapter, ERROR, "Unknown TDLS action frame type\n");
@ -857,7 +902,7 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
struct mwifiex_sta_node *sta_ptr;
u8 *peer, *pos, *end;
u8 i, action, basic;
__le16 cap = 0;
u16 cap = 0;
int ie_len = 0;
if (len < (sizeof(struct ethhdr) + 3))
@ -879,7 +924,7 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
pos = buf + sizeof(struct ethhdr) + 4;
/* payload 1+ category 1 + action 1 + dialog 1 */
cap = cpu_to_le16(*(u16 *)pos);
cap = get_unaligned_le16(pos);
ie_len = len - sizeof(struct ethhdr) - TDLS_REQ_FIX_LEN;
pos += 2;
break;
@ -889,7 +934,7 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
return;
/* payload 1+ category 1 + action 1 + dialog 1 + status code 2*/
pos = buf + sizeof(struct ethhdr) + 6;
cap = cpu_to_le16(*(u16 *)pos);
cap = get_unaligned_le16(pos);
ie_len = len - sizeof(struct ethhdr) - TDLS_RESP_FIX_LEN;
pos += 2;
break;
@ -909,7 +954,7 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
if (!sta_ptr)
return;
sta_ptr->tdls_cap.capab = cap;
sta_ptr->tdls_cap.capab = cpu_to_le16(cap);
for (end = pos + ie_len; pos + 1 < end; pos += 2 + pos[1]) {
if (pos + 2 + pos[1] > end)
@ -969,7 +1014,7 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
case WLAN_EID_AID:
if (priv->adapter->is_hw_11ac_capable)
sta_ptr->tdls_cap.aid =
le16_to_cpu(*(__le16 *)(pos + 2));
get_unaligned_le16((pos + 2));
default:
break;
}

View File

@ -202,7 +202,7 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv)
"AP EVENT: event id: %#x\n", eventcause);
break;
case EVENT_AMSDU_AGGR_CTRL:
ctrl = le16_to_cpu(*(__le16 *)adapter->event_body);
ctrl = get_unaligned_le16(adapter->event_body);
mwifiex_dbg(adapter, EVENT,
"event: AMSDU_AGGR_CTRL %d\n", ctrl);

View File

@ -306,9 +306,17 @@ static int mwifiex_usb_submit_rx_urb(struct urb_context *ctx, int size)
}
}
usb_fill_bulk_urb(ctx->urb, card->udev,
usb_rcvbulkpipe(card->udev, ctx->ep), ctx->skb->data,
size, mwifiex_usb_rx_complete, (void *)ctx);
if (card->rx_cmd_ep == ctx->ep &&
card->rx_cmd_ep_type == USB_ENDPOINT_XFER_INT)
usb_fill_int_urb(ctx->urb, card->udev,
usb_rcvintpipe(card->udev, ctx->ep),
ctx->skb->data, size, mwifiex_usb_rx_complete,
(void *)ctx, card->rx_cmd_interval);
else
usb_fill_bulk_urb(ctx->urb, card->udev,
usb_rcvbulkpipe(card->udev, ctx->ep),
ctx->skb->data, size, mwifiex_usb_rx_complete,
(void *)ctx);
if (card->rx_cmd_ep == ctx->ep)
atomic_inc(&card->rx_cmd_urb_pending);
@ -424,10 +432,13 @@ static int mwifiex_usb_probe(struct usb_interface *intf,
epd = &iface_desc->endpoint[i].desc;
if (usb_endpoint_dir_in(epd) &&
usb_endpoint_num(epd) == MWIFIEX_USB_EP_CMD_EVENT &&
usb_endpoint_xfer_bulk(epd)) {
pr_debug("info: bulk IN: max pkt size: %d, addr: %d\n",
(usb_endpoint_xfer_bulk(epd) ||
usb_endpoint_xfer_int(epd))) {
card->rx_cmd_ep_type = usb_endpoint_type(epd);
card->rx_cmd_interval = epd->bInterval;
pr_debug("info: Rx CMD/EVT:: max pkt size: %d, addr: %d, ep_type: %d\n",
le16_to_cpu(epd->wMaxPacketSize),
epd->bEndpointAddress);
epd->bEndpointAddress, card->rx_cmd_ep_type);
card->rx_cmd_ep = usb_endpoint_num(epd);
atomic_set(&card->rx_cmd_urb_pending, 0);
}
@ -461,10 +472,16 @@ static int mwifiex_usb_probe(struct usb_interface *intf,
}
if (usb_endpoint_dir_out(epd) &&
usb_endpoint_num(epd) == MWIFIEX_USB_EP_CMD_EVENT &&
usb_endpoint_xfer_bulk(epd)) {
(usb_endpoint_xfer_bulk(epd) ||
usb_endpoint_xfer_int(epd))) {
card->tx_cmd_ep_type = usb_endpoint_type(epd);
card->tx_cmd_interval = epd->bInterval;
pr_debug("info: bulk OUT: max pkt size: %d, addr: %d\n",
le16_to_cpu(epd->wMaxPacketSize),
epd->bEndpointAddress);
pr_debug("info: Tx CMD:: max pkt size: %d, addr: %d, ep_type: %d\n",
le16_to_cpu(epd->wMaxPacketSize),
epd->bEndpointAddress, card->tx_cmd_ep_type);
card->tx_cmd_ep = usb_endpoint_num(epd);
atomic_set(&card->tx_cmd_urb_pending, 0);
card->bulk_out_maxpktsize =
@ -884,9 +901,17 @@ static int mwifiex_usb_host_to_card(struct mwifiex_adapter *adapter, u8 ep,
context->skb = skb;
tx_urb = context->urb;
usb_fill_bulk_urb(tx_urb, card->udev, usb_sndbulkpipe(card->udev, ep),
data, skb->len, mwifiex_usb_tx_complete,
(void *)context);
if (ep == card->tx_cmd_ep &&
card->tx_cmd_ep_type == USB_ENDPOINT_XFER_INT)
usb_fill_int_urb(tx_urb, card->udev,
usb_sndintpipe(card->udev, ep), data,
skb->len, mwifiex_usb_tx_complete,
(void *)context, card->tx_cmd_interval);
else
usb_fill_bulk_urb(tx_urb, card->udev,
usb_sndbulkpipe(card->udev, ep), data,
skb->len, mwifiex_usb_tx_complete,
(void *)context);
tx_urb->transfer_flags |= URB_ZERO_PACKET;

View File

@ -90,6 +90,10 @@ struct usb_card_rec {
struct urb_context tx_cmd;
u8 mc_resync_flag;
struct usb_tx_data_port port[MWIFIEX_TX_DATA_PORT];
int rx_cmd_ep_type;
u8 rx_cmd_interval;
int tx_cmd_ep_type;
u8 tx_cmd_interval;
};
struct fw_header {
@ -102,12 +106,12 @@ struct fw_header {
struct fw_sync_header {
__le32 cmd;
__le32 seq_num;
};
} __packed;
struct fw_data {
struct fw_header fw_hdr;
__le32 seq_num;
u8 data[1];
};
} __packed;
#endif /*_MWIFIEX_USB_H */

View File

@ -274,13 +274,13 @@ int mwifiex_debug_info_to_buffer(struct mwifiex_private *priv, char *buf,
val = *((u8 *)addr);
break;
case 2:
val = *((u16 *)addr);
val = get_unaligned((u16 *)addr);
break;
case 4:
val = *((u32 *)addr);
val = get_unaligned((u32 *)addr);
break;
case 8:
val = *((long long *)addr);
val = get_unaligned((long long *)addr);
break;
default:
val = -1;

View File

@ -93,4 +93,9 @@ static inline dma_addr_t MWIFIEX_SKB_DMA_ADDR(struct sk_buff *skb)
int mwifiex_debug_info_to_buffer(struct mwifiex_private *priv, char *buf,
struct mwifiex_debug_info *info);
static inline void le16_unaligned_add_cpu(__le16 *var, u16 val)
{
put_unaligned_le16(get_unaligned_le16(var) + val, var);
}
#endif /* !_MWIFIEX_UTIL_H_ */

View File

@ -201,7 +201,7 @@ endif
config RT2800SOC
tristate "Ralink WiSoC support"
depends on SOC_RT288X || SOC_RT305X
depends on SOC_RT288X || SOC_RT305X || SOC_MT7620
select RT2X00_LIB_SOC
select RT2X00_LIB_MMIO
select RT2X00_LIB_CRYPTO

View File

@ -79,6 +79,7 @@
#define RF5372 0x5372
#define RF5390 0x5390
#define RF5392 0x5392
#define RF7620 0x7620
/*
* Chipset revisions.
@ -638,6 +639,24 @@
#define RF_CSR_CFG_WRITE FIELD32(0x00010000)
#define RF_CSR_CFG_BUSY FIELD32(0x00020000)
/*
* MT7620 RF registers (reversed order)
*/
#define RF_CSR_CFG_DATA_MT7620 FIELD32(0x0000ff00)
#define RF_CSR_CFG_REGNUM_MT7620 FIELD32(0x03ff0000)
#define RF_CSR_CFG_WRITE_MT7620 FIELD32(0x00000010)
#define RF_CSR_CFG_BUSY_MT7620 FIELD32(0x00000001)
/* undocumented registers for calibration of new MAC */
#define RF_CONTROL0 0x0518
#define RF_BYPASS0 0x051c
#define RF_CONTROL1 0x0520
#define RF_BYPASS1 0x0524
#define RF_CONTROL2 0x0528
#define RF_BYPASS2 0x052c
#define RF_CONTROL3 0x0530
#define RF_BYPASS3 0x0534
/*
* EFUSE_CSR: RT30x0 EEPROM
*/
@ -1021,6 +1040,16 @@
#define AUTOWAKEUP_CFG_TBCN_BEFORE_WAKE FIELD32(0x00007f00)
#define AUTOWAKEUP_CFG_AUTOWAKE FIELD32(0x00008000)
/*
* MIMO_PS_CFG: MIMO Power-save Configuration
*/
#define MIMO_PS_CFG 0x1210
#define MIMO_PS_CFG_MMPS_BB_EN FIELD32(0x00000001)
#define MIMO_PS_CFG_MMPS_RX_ANT_NUM FIELD32(0x00000006)
#define MIMO_PS_CFG_MMPS_RF_EN FIELD32(0x00000008)
#define MIMO_PS_CFG_RX_STBY_POL FIELD32(0x00000010)
#define MIMO_PS_CFG_RX_RX_STBY0 FIELD32(0x00000020)
/*
* EDCA_AC0_CFG:
*/
@ -1095,6 +1124,12 @@
#define TX_PWR_CFG_0_OFDM6_CH1 FIELD32(0x00f00000)
#define TX_PWR_CFG_0_OFDM12_CH0 FIELD32(0x0f000000)
#define TX_PWR_CFG_0_OFDM12_CH1 FIELD32(0xf0000000)
/* bits for new 2T devices */
#define TX_PWR_CFG_0B_1MBS_2MBS FIELD32(0x000000ff)
#define TX_PWR_CFG_0B_5MBS_11MBS FIELD32(0x0000ff00)
#define TX_PWR_CFG_0B_6MBS_9MBS FIELD32(0x00ff0000)
#define TX_PWR_CFG_0B_12MBS_18MBS FIELD32(0xff000000)
/*
* TX_PWR_CFG_1:
@ -1117,6 +1152,11 @@
#define TX_PWR_CFG_1_MCS0_CH1 FIELD32(0x00f00000)
#define TX_PWR_CFG_1_MCS2_CH0 FIELD32(0x0f000000)
#define TX_PWR_CFG_1_MCS2_CH1 FIELD32(0xf0000000)
/* bits for new 2T devices */
#define TX_PWR_CFG_1B_24MBS_36MBS FIELD32(0x000000ff)
#define TX_PWR_CFG_1B_48MBS FIELD32(0x0000ff00)
#define TX_PWR_CFG_1B_MCS0_MCS1 FIELD32(0x00ff0000)
#define TX_PWR_CFG_1B_MCS2_MCS3 FIELD32(0xff000000)
/*
* TX_PWR_CFG_2:
@ -1139,6 +1179,11 @@
#define TX_PWR_CFG_2_MCS8_CH1 FIELD32(0x00f00000)
#define TX_PWR_CFG_2_MCS10_CH0 FIELD32(0x0f000000)
#define TX_PWR_CFG_2_MCS10_CH1 FIELD32(0xf0000000)
/* bits for new 2T devices */
#define TX_PWR_CFG_2B_MCS4_MCS5 FIELD32(0x000000ff)
#define TX_PWR_CFG_2B_MCS6_MCS7 FIELD32(0x0000ff00)
#define TX_PWR_CFG_2B_MCS8_MCS9 FIELD32(0x00ff0000)
#define TX_PWR_CFG_2B_MCS10_MCS11 FIELD32(0xff000000)
/*
* TX_PWR_CFG_3:
@ -1161,6 +1206,11 @@
#define TX_PWR_CFG_3_STBC0_CH1 FIELD32(0x00f00000)
#define TX_PWR_CFG_3_STBC2_CH0 FIELD32(0x0f000000)
#define TX_PWR_CFG_3_STBC2_CH1 FIELD32(0xf0000000)
/* bits for new 2T devices */
#define TX_PWR_CFG_3B_MCS12_MCS13 FIELD32(0x000000ff)
#define TX_PWR_CFG_3B_MCS14 FIELD32(0x0000ff00)
#define TX_PWR_CFG_3B_STBC_MCS0_MCS1 FIELD32(0x00ff0000)
#define TX_PWR_CFG_3B_STBC_MCS2_MSC3 FIELD32(0xff000000)
/*
* TX_PWR_CFG_4:
@ -1171,10 +1221,13 @@
#define TX_PWR_CFG_4_UKNOWN7 FIELD32(0x00000f00)
#define TX_PWR_CFG_4_UKNOWN8 FIELD32(0x0000f000)
/* bits for 3T devices */
#define TX_PWR_CFG_3_STBC4_CH0 FIELD32(0x0000000f)
#define TX_PWR_CFG_3_STBC4_CH1 FIELD32(0x000000f0)
#define TX_PWR_CFG_3_STBC6_CH0 FIELD32(0x00000f00)
#define TX_PWR_CFG_3_STBC6_CH1 FIELD32(0x0000f000)
#define TX_PWR_CFG_4_STBC4_CH0 FIELD32(0x0000000f)
#define TX_PWR_CFG_4_STBC4_CH1 FIELD32(0x000000f0)
#define TX_PWR_CFG_4_STBC6_CH0 FIELD32(0x00000f00)
#define TX_PWR_CFG_4_STBC6_CH1 FIELD32(0x0000f000)
/* bits for new 2T devices */
#define TX_PWR_CFG_4B_STBC_MCS4_MCS5 FIELD32(0x000000ff)
#define TX_PWR_CFG_4B_STBC_MCS6 FIELD32(0x0000ff00)
/*
* TX_PIN_CFG:
@ -1201,6 +1254,8 @@
#define TX_PIN_CFG_RFTR_POL FIELD32(0x00020000)
#define TX_PIN_CFG_TRSW_EN FIELD32(0x00040000)
#define TX_PIN_CFG_TRSW_POL FIELD32(0x00080000)
#define TX_PIN_CFG_RFRX_EN FIELD32(0x00100000)
#define TX_PIN_CFG_RFRX_POL FIELD32(0x00200000)
#define TX_PIN_CFG_PA_PE_A2_EN FIELD32(0x01000000)
#define TX_PIN_CFG_PA_PE_G2_EN FIELD32(0x02000000)
#define TX_PIN_CFG_PA_PE_A2_POL FIELD32(0x04000000)
@ -1547,6 +1602,95 @@
#define TX_PWR_CFG_4_EXT_STBC4_CH2 FIELD32(0x0000000f)
#define TX_PWR_CFG_4_EXT_STBC6_CH2 FIELD32(0x00000f00)
/* TXn_RF_GAIN_CORRECT: RF Gain Correction for each RF_ALC[3:2]
* Unit: 0.1 dB, Range: -3.2 dB to 3.1 dB
*/
#define TX0_RF_GAIN_CORRECT 0x13a0
#define TX0_RF_GAIN_CORRECT_GAIN_CORR_0 FIELD32(0x0000003f)
#define TX0_RF_GAIN_CORRECT_GAIN_CORR_1 FIELD32(0x00003f00)
#define TX0_RF_GAIN_CORRECT_GAIN_CORR_2 FIELD32(0x003f0000)
#define TX0_RF_GAIN_CORRECT_GAIN_CORR_3 FIELD32(0x3f000000)
#define TX1_RF_GAIN_CORRECT 0x13a4
#define TX1_RF_GAIN_CORRECT_GAIN_CORR_0 FIELD32(0x0000003f)
#define TX1_RF_GAIN_CORRECT_GAIN_CORR_1 FIELD32(0x00003f00)
#define TX1_RF_GAIN_CORRECT_GAIN_CORR_2 FIELD32(0x003f0000)
#define TX1_RF_GAIN_CORRECT_GAIN_CORR_3 FIELD32(0x3f000000)
/* TXn_RF_GAIN_ATTEN: TXn RF Gain Attenuation Level
* Format: 7-bit, signed value
* Unit: 0.5 dB, Range: -20 dB to -5 dB
*/
#define TX0_RF_GAIN_ATTEN 0x13a8
#define TX0_RF_GAIN_ATTEN_LEVEL_0 FIELD32(0x0000007f)
#define TX0_RF_GAIN_ATTEN_LEVEL_1 FIELD32(0x00007f00)
#define TX0_RF_GAIN_ATTEN_LEVEL_2 FIELD32(0x007f0000)
#define TX0_RF_GAIN_ATTEN_LEVEL_3 FIELD32(0x7f000000)
#define TX1_RF_GAIN_ATTEN 0x13ac
#define TX1_RF_GAIN_ATTEN_LEVEL_0 FIELD32(0x0000007f)
#define TX1_RF_GAIN_ATTEN_LEVEL_1 FIELD32(0x00007f00)
#define TX1_RF_GAIN_ATTEN_LEVEL_2 FIELD32(0x007f0000)
#define TX1_RF_GAIN_ATTEN_LEVEL_3 FIELD32(0x7f000000)
/* TX_ALC_CFG_0: TX Automatic Level Control Configuration 0
* TX_ALC_LIMIT_n: TXn upper limit
* TX_ALC_CH_INIT_n: TXn channel initial transmission gain
* Unit: 0.5 dB, Range: 0 to 23.5 dB
*/
#define TX_ALC_CFG_0 0x13b0
#define TX_ALC_CFG_0_CH_INIT_0 FIELD32(0x0000003f)
#define TX_ALC_CFG_0_CH_INIT_1 FIELD32(0x00003f00)
#define TX_ALC_CFG_0_LIMIT_0 FIELD32(0x003f0000)
#define TX_ALC_CFG_0_LIMIT_1 FIELD32(0x3f000000)
/* TX_ALC_CFG_1: TX Automatic Level Control Configuration 1
* TX_TEMP_COMP: TX Power Temperature Compensation
* Unit: 0.5 dB, Range: -10 dB to 10 dB
* TXn_GAIN_FINE: TXn Gain Fine Adjustment
* Unit: 0.1 dB, Range: -0.8 dB to 0.7 dB
* RF_TOS_DLY: Sets the RF_TOS_EN assertion delay after
* deassertion of PA_PE.
* Unit: 0.25 usec
* TXn_RF_GAIN_ATTEN: TXn RF gain attentuation selector
* RF_TOS_TIMEOUT: time-out value for RF_TOS_ENABLE
* deassertion if RF_TOS_DONE is missing.
* Unit: 0.25 usec
* RF_TOS_ENABLE: TX offset calibration enable
* ROS_BUSY_EN: RX offset calibration busy enable
*/
#define TX_ALC_CFG_1 0x13b4
#define TX_ALC_CFG_1_TX_TEMP_COMP FIELD32(0x0000003f)
#define TX_ALC_CFG_1_TX0_GAIN_FINE FIELD32(0x00000f00)
#define TX_ALC_CFG_1_TX1_GAIN_FINE FIELD32(0x0000f000)
#define TX_ALC_CFG_1_RF_TOS_DLY FIELD32(0x00070000)
#define TX_ALC_CFG_1_TX0_RF_GAIN_ATTEN FIELD32(0x00300000)
#define TX_ALC_CFG_1_TX1_RF_GAIN_ATTEN FIELD32(0x00c00000)
#define TX_ALC_CFG_1_RF_TOS_TIMEOUT FIELD32(0x3f000000)
#define TX_ALC_CFG_1_RF_TOS_ENABLE FIELD32(0x40000000)
#define TX_ALC_CFG_1_ROS_BUSY_EN FIELD32(0x80000000)
/* TXn_BB_GAIN_ATTEN: TXn RF Gain Attenuation Level
* Format: 5-bit signed values
* Unit: 0.5 dB, Range: -8 dB to 7 dB
*/
#define TX0_BB_GAIN_ATTEN 0x13c0
#define TX0_BB_GAIN_ATTEN_LEVEL_0 FIELD32(0x0000001f)
#define TX0_BB_GAIN_ATTEN_LEVEL_1 FIELD32(0x00001f00)
#define TX0_BB_GAIN_ATTEN_LEVEL_2 FIELD32(0x001f0000)
#define TX0_BB_GAIN_ATTEN_LEVEL_3 FIELD32(0x1f000000)
#define TX1_BB_GAIN_ATTEN 0x13c4
#define TX1_BB_GAIN_ATTEN_LEVEL_0 FIELD32(0x0000001f)
#define TX1_BB_GAIN_ATTEN_LEVEL_1 FIELD32(0x00001f00)
#define TX1_BB_GAIN_ATTEN_LEVEL_2 FIELD32(0x001f0000)
#define TX1_BB_GAIN_ATTEN_LEVEL_3 FIELD32(0x1f000000)
/* TX_ALC_VGA3: TX Automatic Level Correction Variable Gain Amplifier 3 */
#define TX_ALC_VGA3 0x13c8
#define TX_ALC_VGA3_TX0_ALC_VGA3 FIELD32(0x0000001f)
#define TX_ALC_VGA3_TX1_ALC_VGA3 FIELD32(0x00001f00)
#define TX_ALC_VGA3_TX0_ALC_VGA2 FIELD32(0x001f0000)
#define TX_ALC_VGA3_TX1_ALC_VGA2 FIELD32(0x1f000000)
/* TX_PWR_CFG_7 */
#define TX_PWR_CFG_7 0x13d4
#define TX_PWR_CFG_7_OFDM54_CH0 FIELD32(0x0000000f)
@ -1555,6 +1699,10 @@
#define TX_PWR_CFG_7_MCS7_CH0 FIELD32(0x000f0000)
#define TX_PWR_CFG_7_MCS7_CH1 FIELD32(0x00f00000)
#define TX_PWR_CFG_7_MCS7_CH2 FIELD32(0x0f000000)
/* bits for new 2T devices */
#define TX_PWR_CFG_7B_54MBS FIELD32(0x000000ff)
#define TX_PWR_CFG_7B_MCS7 FIELD32(0x00ff0000)
/* TX_PWR_CFG_8 */
#define TX_PWR_CFG_8 0x13d8
@ -1564,12 +1712,17 @@
#define TX_PWR_CFG_8_MCS23_CH0 FIELD32(0x000f0000)
#define TX_PWR_CFG_8_MCS23_CH1 FIELD32(0x00f00000)
#define TX_PWR_CFG_8_MCS23_CH2 FIELD32(0x0f000000)
/* bits for new 2T devices */
#define TX_PWR_CFG_8B_MCS15 FIELD32(0x000000ff)
/* TX_PWR_CFG_9 */
#define TX_PWR_CFG_9 0x13dc
#define TX_PWR_CFG_9_STBC7_CH0 FIELD32(0x0000000f)
#define TX_PWR_CFG_9_STBC7_CH1 FIELD32(0x000000f0)
#define TX_PWR_CFG_9_STBC7_CH2 FIELD32(0x00000f00)
/* bits for new 2T devices */
#define TX_PWR_CFG_9B_STBC_MCS7 FIELD32(0x000000ff)
/*
* RX_FILTER_CFG: RX configuration register.
@ -1760,6 +1913,8 @@
#define TX_STA_FIFO_WCID FIELD32(0x0000ff00)
#define TX_STA_FIFO_SUCCESS_RATE FIELD32(0xffff0000)
#define TX_STA_FIFO_MCS FIELD32(0x007f0000)
#define TX_STA_FIFO_BW FIELD32(0x00800000)
#define TX_STA_FIFO_SGI FIELD32(0x01000000)
#define TX_STA_FIFO_PHYMODE FIELD32(0xc0000000)
/*
@ -2135,11 +2290,14 @@ struct mac_iveiv_entry {
#define RFCSR1_TX1_PD FIELD8(0x20)
#define RFCSR1_RX2_PD FIELD8(0x40)
#define RFCSR1_TX2_PD FIELD8(0x80)
#define RFCSR1_TX2_EN_MT7620 FIELD8(0x02)
/*
* RFCSR 2:
*/
#define RFCSR2_RESCAL_EN FIELD8(0x80)
#define RFCSR2_RX2_EN_MT7620 FIELD8(0x02)
#define RFCSR2_TX2_EN_MT7620 FIELD8(0x20)
/*
* RFCSR 3:
@ -2157,6 +2315,12 @@ struct mac_iveiv_entry {
#define RFCSR3_BIT4 FIELD8(0x10)
#define RFCSR3_BIT5 FIELD8(0x20)
/*
* RFCSR 4:
* VCOCAL_EN used by MT7620
*/
#define RFCSR4_VCOCAL_EN FIELD8(0x80)
/*
* FRCSR 5:
*/
@ -2212,6 +2376,7 @@ struct mac_iveiv_entry {
*/
#define RFCSR13_TX_POWER FIELD8(0x1f)
#define RFCSR13_DR0 FIELD8(0xe0)
#define RFCSR13_RDIV_MT7620 FIELD8(0x03)
/*
* RFCSR 15:
@ -2222,6 +2387,8 @@ struct mac_iveiv_entry {
* RFCSR 16:
*/
#define RFCSR16_TXMIXER_GAIN FIELD8(0x07)
#define RFCSR16_RF_PLL_FREQ_SEL_MT7620 FIELD8(0x0F)
#define RFCSR16_SDM_MODE_MT7620 FIELD8(0xE0)
/*
* RFCSR 17:
@ -2234,6 +2401,8 @@ struct mac_iveiv_entry {
/* RFCSR 18 */
#define RFCSR18_XO_TUNE_BYPASS FIELD8(0x40)
/* RFCSR 19 */
#define RFCSR19_K FIELD8(0x03)
/*
* RFCSR 20:
@ -2244,11 +2413,14 @@ struct mac_iveiv_entry {
* RFCSR 21:
*/
#define RFCSR21_RX_LO2_EN FIELD8(0x08)
#define RFCSR21_BIT1 FIELD8(0x01)
#define RFCSR21_BIT8 FIELD8(0x80)
/*
* RFCSR 22:
*/
#define RFCSR22_BASEBAND_LOOPBACK FIELD8(0x01)
#define RFCSR22_FREQPLAN_D_MT7620 FIELD8(0x07)
/*
* RFCSR 23:
@ -2270,6 +2442,11 @@ struct mac_iveiv_entry {
#define RFCSR27_R3 FIELD8(0x30)
#define RFCSR27_R4 FIELD8(0x40)
/*
* RFCSR 28:
*/
#define RFCSR28_CH11_HT40 FIELD8(0x04)
/*
* RFCSR 29:
*/
@ -2331,6 +2508,7 @@ struct mac_iveiv_entry {
*/
#define RFCSR42_BIT1 FIELD8(0x01)
#define RFCSR42_BIT4 FIELD8(0x08)
#define RFCSR42_TX2_EN_MT7620 FIELD8(0x40)
/*
* RFCSR 49:
@ -2433,6 +2611,7 @@ enum rt2800_eeprom_word {
EEPROM_TSSI_BOUND_BG5,
EEPROM_TXPOWER_A1,
EEPROM_TXPOWER_A2,
EEPROM_TXPOWER_INIT,
EEPROM_TSSI_BOUND_A1,
EEPROM_TSSI_BOUND_A2,
EEPROM_TSSI_BOUND_A3,
@ -2987,29 +3166,4 @@ enum rt2800_eeprom_word {
*/
#define BCN_TBTT_OFFSET 64
/*
* Hardware has 255 WCID table entries. First 32 entries are reserved for
* shared keys. Since parts of the pairwise key table might be shared with
* the beacon frame buffers 6 & 7 we could only use the first 222 entries.
*/
#define WCID_START 33
#define WCID_END 222
#define STA_IDS_SIZE (WCID_END - WCID_START + 2)
/*
* RT2800 driver data structure
*/
struct rt2800_drv_data {
u8 calibration_bw20;
u8 calibration_bw40;
u8 bbp25;
u8 bbp26;
u8 txmixer_gain_24g;
u8 txmixer_gain_5g;
u8 max_psdu;
unsigned int tbtt_tick;
unsigned int ampdu_factor_cnt[4];
DECLARE_BITMAP(sta_ids, STA_IDS_SIZE);
};
#endif /* RT2800_H */

File diff suppressed because it is too large Load Diff

View File

@ -20,6 +20,34 @@
#ifndef RT2800LIB_H
#define RT2800LIB_H
/*
* Hardware has 255 WCID table entries. First 32 entries are reserved for
* shared keys. Since parts of the pairwise key table might be shared with
* the beacon frame buffers 6 & 7 we could only use the first 222 entries.
*/
#define WCID_START 33
#define WCID_END 222
#define STA_IDS_SIZE (WCID_END - WCID_START + 2)
/* RT2800 driver data structure */
struct rt2800_drv_data {
u8 calibration_bw20;
u8 calibration_bw40;
char rx_calibration_bw20;
char rx_calibration_bw40;
char tx_calibration_bw20;
char tx_calibration_bw40;
u8 bbp25;
u8 bbp26;
u8 txmixer_gain_24g;
u8 txmixer_gain_5g;
u8 max_psdu;
unsigned int tbtt_tick;
unsigned int ampdu_factor_cnt[4];
DECLARE_BITMAP(sta_ids, STA_IDS_SIZE);
struct ieee80211_sta *wcid_to_sta[STA_IDS_SIZE];
};
struct rt2800_ops {
void (*register_read)(struct rt2x00_dev *rt2x00dev,
const unsigned int offset, u32 *value);
@ -167,7 +195,8 @@ void rt2800_write_tx_data(struct queue_entry *entry,
struct txentry_desc *txdesc);
void rt2800_process_rxwi(struct queue_entry *entry, struct rxdone_entry_desc *txdesc);
void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32* txwi);
void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi,
bool match);
void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc);
void rt2800_clear_beacon(struct queue_entry *entry);

View File

@ -239,7 +239,7 @@ static bool rt2800mmio_txdone_release_entries(struct queue_entry *entry,
{
if (test_bit(ENTRY_DATA_STATUS_SET, &entry->flags)) {
rt2800_txdone_entry(entry, entry->status,
rt2800mmio_get_txwi(entry));
rt2800mmio_get_txwi(entry), true);
return false;
}

View File

@ -501,8 +501,7 @@ static int rt2800usb_get_tx_data_len(struct queue_entry *entry)
/*
* TX control handlers
*/
static enum txdone_entry_desc_flags
rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg)
static bool rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg)
{
__le32 *txwi;
u32 word;
@ -515,7 +514,7 @@ rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg)
* frame.
*/
if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags))
return TXDONE_FAILURE;
return false;
wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID);
ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED);
@ -537,10 +536,10 @@ rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg)
rt2x00_dbg(entry->queue->rt2x00dev,
"TX status report missed for queue %d entry %d\n",
entry->queue->qid, entry->entry_idx);
return TXDONE_UNKNOWN;
return false;
}
return TXDONE_SUCCESS;
return true;
}
static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev)
@ -549,7 +548,7 @@ static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev)
struct queue_entry *entry;
u32 reg;
u8 qid;
enum txdone_entry_desc_flags done_status;
bool match;
while (kfifo_get(&rt2x00dev->txstatus_fifo, &reg)) {
/*
@ -574,11 +573,8 @@ static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev)
break;
}
done_status = rt2800usb_txdone_entry_check(entry, reg);
if (likely(done_status == TXDONE_SUCCESS))
rt2800_txdone_entry(entry, reg, rt2800usb_get_txwi(entry));
else
rt2x00lib_txdone_noinfo(entry, done_status);
match = rt2800usb_txdone_entry_check(entry, reg);
rt2800_txdone_entry(entry, reg, rt2800usb_get_txwi(entry), match);
}
}

View File

@ -174,6 +174,7 @@ struct rt2x00_chip {
#define RT5390 0x5390 /* 2.4GHz */
#define RT5392 0x5392 /* 2.4GHz */
#define RT5592 0x5592
#define RT6352 0x6352 /* WSOC 2.4GHz */
u16 rf;
u16 rev;
@ -1396,7 +1397,7 @@ void rt2x00queue_flush_queues(struct rt2x00_dev *rt2x00dev, bool drop);
* rt2x00debug_dump_frame - Dump a frame to userspace through debugfs.
* @rt2x00dev: Pointer to &struct rt2x00_dev.
* @type: The type of frame that is being dumped.
* @skb: The skb containing the frame to be dumped.
* @entry: The queue entry containing the frame to be dumped.
*/
#ifdef CONFIG_RT2X00_LIB_DEBUGFS
void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
@ -1425,6 +1426,8 @@ void rt2x00lib_dmastart(struct queue_entry *entry);
void rt2x00lib_dmadone(struct queue_entry *entry);
void rt2x00lib_txdone(struct queue_entry *entry,
struct txdone_entry_desc *txdesc);
void rt2x00lib_txdone_nomatch(struct queue_entry *entry,
struct txdone_entry_desc *txdesc);
void rt2x00lib_txdone_noinfo(struct queue_entry *entry, u32 status);
void rt2x00lib_rxdone(struct queue_entry *entry, gfp_t gfp);

View File

@ -313,15 +313,172 @@ static inline int rt2x00lib_txdone_bar_status(struct queue_entry *entry)
return ret;
}
static void rt2x00lib_fill_tx_status(struct rt2x00_dev *rt2x00dev,
struct ieee80211_tx_info *tx_info,
struct skb_frame_desc *skbdesc,
struct txdone_entry_desc *txdesc,
bool success)
{
u8 rate_idx, rate_flags, retry_rates;
int i;
rate_idx = skbdesc->tx_rate_idx;
rate_flags = skbdesc->tx_rate_flags;
retry_rates = test_bit(TXDONE_FALLBACK, &txdesc->flags) ?
(txdesc->retry + 1) : 1;
/*
* Initialize TX status
*/
memset(&tx_info->status, 0, sizeof(tx_info->status));
tx_info->status.ack_signal = 0;
/*
* Frame was send with retries, hardware tried
* different rates to send out the frame, at each
* retry it lowered the rate 1 step except when the
* lowest rate was used.
*/
for (i = 0; i < retry_rates && i < IEEE80211_TX_MAX_RATES; i++) {
tx_info->status.rates[i].idx = rate_idx - i;
tx_info->status.rates[i].flags = rate_flags;
if (rate_idx - i == 0) {
/*
* The lowest rate (index 0) was used until the
* number of max retries was reached.
*/
tx_info->status.rates[i].count = retry_rates - i;
i++;
break;
}
tx_info->status.rates[i].count = 1;
}
if (i < (IEEE80211_TX_MAX_RATES - 1))
tx_info->status.rates[i].idx = -1; /* terminate */
if (test_bit(TXDONE_NO_ACK_REQ, &txdesc->flags))
tx_info->flags |= IEEE80211_TX_CTL_NO_ACK;
if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) {
if (success)
tx_info->flags |= IEEE80211_TX_STAT_ACK;
else
rt2x00dev->low_level_stats.dot11ACKFailureCount++;
}
/*
* Every single frame has it's own tx status, hence report
* every frame as ampdu of size 1.
*
* TODO: if we can find out how many frames were aggregated
* by the hw we could provide the real ampdu_len to mac80211
* which would allow the rc algorithm to better decide on
* which rates are suitable.
*/
if (test_bit(TXDONE_AMPDU, &txdesc->flags) ||
tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
tx_info->flags |= IEEE80211_TX_STAT_AMPDU |
IEEE80211_TX_CTL_AMPDU;
tx_info->status.ampdu_len = 1;
tx_info->status.ampdu_ack_len = success ? 1 : 0;
if (!success)
tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
}
if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
if (success)
rt2x00dev->low_level_stats.dot11RTSSuccessCount++;
else
rt2x00dev->low_level_stats.dot11RTSFailureCount++;
}
}
static void rt2x00lib_clear_entry(struct rt2x00_dev *rt2x00dev,
struct queue_entry *entry)
{
/*
* Make this entry available for reuse.
*/
entry->skb = NULL;
entry->flags = 0;
rt2x00dev->ops->lib->clear_entry(entry);
rt2x00queue_index_inc(entry, Q_INDEX_DONE);
/*
* If the data queue was below the threshold before the txdone
* handler we must make sure the packet queue in the mac80211 stack
* is reenabled when the txdone handler has finished. This has to be
* serialized with rt2x00mac_tx(), otherwise we can wake up queue
* before it was stopped.
*/
spin_lock_bh(&entry->queue->tx_lock);
if (!rt2x00queue_threshold(entry->queue))
rt2x00queue_unpause_queue(entry->queue);
spin_unlock_bh(&entry->queue->tx_lock);
}
void rt2x00lib_txdone_nomatch(struct queue_entry *entry,
struct txdone_entry_desc *txdesc)
{
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
struct ieee80211_tx_info txinfo = {};
bool success;
/*
* Unmap the skb.
*/
rt2x00queue_unmap_skb(entry);
/*
* Signal that the TX descriptor is no longer in the skb.
*/
skbdesc->flags &= ~SKBDESC_DESC_IN_SKB;
/*
* Send frame to debugfs immediately, after this call is completed
* we are going to overwrite the skb->cb array.
*/
rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TXDONE, entry);
/*
* Determine if the frame has been successfully transmitted and
* remove BARs from our check list while checking for their
* TX status.
*/
success =
rt2x00lib_txdone_bar_status(entry) ||
test_bit(TXDONE_SUCCESS, &txdesc->flags);
if (!test_bit(TXDONE_UNKNOWN, &txdesc->flags)) {
/*
* Update TX statistics.
*/
rt2x00dev->link.qual.tx_success += success;
rt2x00dev->link.qual.tx_failed += !success;
rt2x00lib_fill_tx_status(rt2x00dev, &txinfo, skbdesc, txdesc,
success);
ieee80211_tx_status_noskb(rt2x00dev->hw, skbdesc->sta, &txinfo);
}
dev_kfree_skb_any(entry->skb);
rt2x00lib_clear_entry(rt2x00dev, entry);
}
EXPORT_SYMBOL_GPL(rt2x00lib_txdone_nomatch);
void rt2x00lib_txdone(struct queue_entry *entry,
struct txdone_entry_desc *txdesc)
{
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
unsigned int header_length, i;
u8 rate_idx, rate_flags, retry_rates;
u8 skbdesc_flags = skbdesc->flags;
unsigned int header_length;
bool success;
/*
@ -381,73 +538,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
rt2x00dev->link.qual.tx_success += success;
rt2x00dev->link.qual.tx_failed += !success;
rate_idx = skbdesc->tx_rate_idx;
rate_flags = skbdesc->tx_rate_flags;
retry_rates = test_bit(TXDONE_FALLBACK, &txdesc->flags) ?
(txdesc->retry + 1) : 1;
/*
* Initialize TX status
*/
memset(&tx_info->status, 0, sizeof(tx_info->status));
tx_info->status.ack_signal = 0;
/*
* Frame was send with retries, hardware tried
* different rates to send out the frame, at each
* retry it lowered the rate 1 step except when the
* lowest rate was used.
*/
for (i = 0; i < retry_rates && i < IEEE80211_TX_MAX_RATES; i++) {
tx_info->status.rates[i].idx = rate_idx - i;
tx_info->status.rates[i].flags = rate_flags;
if (rate_idx - i == 0) {
/*
* The lowest rate (index 0) was used until the
* number of max retries was reached.
*/
tx_info->status.rates[i].count = retry_rates - i;
i++;
break;
}
tx_info->status.rates[i].count = 1;
}
if (i < (IEEE80211_TX_MAX_RATES - 1))
tx_info->status.rates[i].idx = -1; /* terminate */
if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) {
if (success)
tx_info->flags |= IEEE80211_TX_STAT_ACK;
else
rt2x00dev->low_level_stats.dot11ACKFailureCount++;
}
/*
* Every single frame has it's own tx status, hence report
* every frame as ampdu of size 1.
*
* TODO: if we can find out how many frames were aggregated
* by the hw we could provide the real ampdu_len to mac80211
* which would allow the rc algorithm to better decide on
* which rates are suitable.
*/
if (test_bit(TXDONE_AMPDU, &txdesc->flags) ||
tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
tx_info->flags |= IEEE80211_TX_STAT_AMPDU;
tx_info->status.ampdu_len = 1;
tx_info->status.ampdu_ack_len = success ? 1 : 0;
if (!success)
tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
}
if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
if (success)
rt2x00dev->low_level_stats.dot11RTSSuccessCount++;
else
rt2x00dev->low_level_stats.dot11RTSFailureCount++;
}
rt2x00lib_fill_tx_status(rt2x00dev, tx_info, skbdesc, txdesc, success);
/*
* Only send the status report to mac80211 when it's a frame
@ -460,30 +551,11 @@ void rt2x00lib_txdone(struct queue_entry *entry,
ieee80211_tx_status(rt2x00dev->hw, entry->skb);
else
ieee80211_tx_status_ni(rt2x00dev->hw, entry->skb);
} else
} else {
dev_kfree_skb_any(entry->skb);
}
/*
* Make this entry available for reuse.
*/
entry->skb = NULL;
entry->flags = 0;
rt2x00dev->ops->lib->clear_entry(entry);
rt2x00queue_index_inc(entry, Q_INDEX_DONE);
/*
* If the data queue was below the threshold before the txdone
* handler we must make sure the packet queue in the mac80211 stack
* is reenabled when the txdone handler has finished. This has to be
* serialized with rt2x00mac_tx(), otherwise we can wake up queue
* before it was stopped.
*/
spin_lock_bh(&entry->queue->tx_lock);
if (!rt2x00queue_threshold(entry->queue))
rt2x00queue_unpause_queue(entry->queue);
spin_unlock_bh(&entry->queue->tx_lock);
rt2x00lib_clear_entry(rt2x00dev, entry);
}
EXPORT_SYMBOL_GPL(rt2x00lib_txdone);

View File

@ -372,15 +372,16 @@ static void rt2x00queue_create_tx_descriptor_ht(struct rt2x00_dev *rt2x00dev,
/*
* Determine IFS values
* - Use TXOP_BACKOFF for management frames except beacons
* - Use TXOP_BACKOFF for probe and management frames except beacons
* - Use TXOP_SIFS for fragment bursts
* - Use TXOP_HTTXOP for everything else
*
* Note: rt2800 devices won't use CTS protection (if used)
* for frames not transmitted with TXOP_HTTXOP
*/
if (ieee80211_is_mgmt(hdr->frame_control) &&
!ieee80211_is_beacon(hdr->frame_control))
if ((ieee80211_is_mgmt(hdr->frame_control) &&
!ieee80211_is_beacon(hdr->frame_control)) ||
(tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE))
txdesc->u.ht.txop = TXOP_BACKOFF;
else if (!(tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT))
txdesc->u.ht.txop = TXOP_SIFS;

View File

@ -102,7 +102,7 @@ enum skb_frame_desc_flags {
* of the scope of the skb->data pointer.
* @iv: IV/EIV data used during encryption/decryption.
* @skb_dma: (PCI-only) the DMA address associated with the sk buffer.
* @entry: The entry to which this sk buffer belongs.
* @sta: The station where sk buffer was sent.
*/
struct skb_frame_desc {
u8 flags;
@ -116,6 +116,7 @@ struct skb_frame_desc {
__le32 iv[2];
dma_addr_t skb_dma;
struct ieee80211_sta *sta;
};
/**
@ -214,6 +215,7 @@ enum txdone_entry_desc_flags {
TXDONE_FAILURE,
TXDONE_EXCESSIVE_RETRY,
TXDONE_AMPDU,
TXDONE_NO_ACK_REQ,
};
/**

View File

@ -946,8 +946,7 @@ static int rtl8187_start(struct ieee80211_hw *dev)
(7 << 13 /* RX FIFO threshold NONE */) |
(7 << 10 /* MAX RX DMA */) |
RTL818X_RX_CONF_RX_AUTORESETPHY |
RTL818X_RX_CONF_ONLYERLPKT |
RTL818X_RX_CONF_MULTICAST;
RTL818X_RX_CONF_ONLYERLPKT;
priv->rx_conf = reg;
rtl818x_iowrite32(priv, &priv->map->RX_CONF, reg);
@ -1319,12 +1318,11 @@ static void rtl8187_configure_filter(struct ieee80211_hw *dev,
priv->rx_conf ^= RTL818X_RX_CONF_FCS;
if (changed_flags & FIF_CONTROL)
priv->rx_conf ^= RTL818X_RX_CONF_CTRL;
if (changed_flags & FIF_OTHER_BSS)
priv->rx_conf ^= RTL818X_RX_CONF_MONITOR;
if (*total_flags & FIF_ALLMULTI || multicast > 0)
priv->rx_conf |= RTL818X_RX_CONF_MULTICAST;
if (*total_flags & FIF_OTHER_BSS ||
*total_flags & FIF_ALLMULTI || multicast > 0)
priv->rx_conf |= RTL818X_RX_CONF_MONITOR;
else
priv->rx_conf &= ~RTL818X_RX_CONF_MULTICAST;
priv->rx_conf &= ~RTL818X_RX_CONF_MONITOR;
*total_flags = 0;
@ -1332,10 +1330,10 @@ static void rtl8187_configure_filter(struct ieee80211_hw *dev,
*total_flags |= FIF_FCSFAIL;
if (priv->rx_conf & RTL818X_RX_CONF_CTRL)
*total_flags |= FIF_CONTROL;
if (priv->rx_conf & RTL818X_RX_CONF_MONITOR)
if (priv->rx_conf & RTL818X_RX_CONF_MONITOR) {
*total_flags |= FIF_OTHER_BSS;
if (priv->rx_conf & RTL818X_RX_CONF_MULTICAST)
*total_flags |= FIF_ALLMULTI;
}
rtl818x_iowrite32_async(priv, &priv->map->RX_CONF, priv->rx_conf);
}

View File

@ -116,7 +116,7 @@ struct coex_dm_8192e_2ant {
u32 backup_arfr_cnt1; /* Auto Rate Fallback Retry cnt */
u32 backup_arfr_cnt2; /* Auto Rate Fallback Retry cnt */
u16 backup_retrylimit;
u16 backup_retry_limit;
u8 backup_ampdu_maxtime;
/* algorithm related */
@ -125,18 +125,18 @@ struct coex_dm_8192e_2ant {
u8 bt_status;
u8 wifi_chnl_info[3];
u8 pre_sstype;
u8 cur_sstype;
u8 pre_ss_type;
u8 cur_ss_type;
u32 prera_mask;
u32 curra_mask;
u8 curra_masktype;
u8 pre_arfrtype;
u8 cur_arfrtype;
u8 pre_retrylimit_type;
u8 cur_retrylimit_type;
u8 pre_ampdutime_type;
u8 cur_ampdutime_type;
u32 pre_ra_mask;
u32 cur_ra_mask;
u8 cur_ra_mask_type;
u8 pre_arfr_type;
u8 cur_arfr_type;
u8 pre_retry_limit_type;
u8 cur_retry_limit_type;
u8 pre_ampdu_time_type;
u8 cur_ampdu_time_type;
};
struct coex_sta_8192e_2ant {

View File

@ -75,8 +75,8 @@ enum BT_8723B_2ANT_COEX_ALGO {
struct coex_dm_8723b_2ant {
/* fw mechanism */
bool pre_dec_bt_pwr;
bool cur_dec_bt_pwr;
bool pre_dec_bt_pwr_lvl;
bool cur_dec_bt_pwr_lvl;
u8 pre_fw_dac_swing_lvl;
u8 cur_fw_dac_swing_lvl;
bool cur_ignore_wlan_act;
@ -148,6 +148,20 @@ struct coex_sta_8723b_2ant {
bool c2h_bt_inquiry_page;
u8 bt_retry_cnt;
u8 bt_info_ext;
u32 pop_event_cnt;
u8 scan_ap_num;
u32 crc_ok_cck;
u32 crc_ok_11g;
u32 crc_ok_11n;
u32 crc_ok_11n_agg;
u32 crc_err_cck;
u32 crc_err_11g;
u32 crc_err_11n;
u32 crc_err_11n_agg;
u8 a2dp_bit_pool;
};
/*********************************************************************

View File

@ -146,7 +146,7 @@ struct coex_sta_8821a_1ant {
bool hid_exist;
bool pan_exist;
bool under_Lps;
bool under_lps;
bool under_ips;
u32 special_pkt_period_cnt;
u32 high_priority_tx;

View File

@ -466,7 +466,7 @@ static bool halbtc_set(void *void_btcoexist, u8 set_type, void *in_buf)
case BTC_SET_ACT_DISABLE_LOW_POWER:
halbtc_disable_low_power();
break;
case BTC_SET_ACT_UPDATE_ra_mask:
case BTC_SET_ACT_UPDATE_RAMASK:
btcoexist->bt_info.ra_mask = *u32_tmp;
break;
case BTC_SET_ACT_SEND_MIMO_PS:

View File

@ -275,7 +275,7 @@ enum btc_set_type {
BTC_SET_ACT_NORMAL_LPS,
BTC_SET_ACT_INC_FORCE_EXEC_PWR_CMD_CNT,
BTC_SET_ACT_DISABLE_LOW_POWER,
BTC_SET_ACT_UPDATE_ra_mask,
BTC_SET_ACT_UPDATE_RAMASK,
BTC_SET_ACT_SEND_MIMO_PS,
/* BT Coex related */
BTC_SET_ACT_CTRL_BT_INFO,
@ -459,6 +459,7 @@ struct btc_bt_link_info {
bool hid_only;
bool pan_exist;
bool pan_only;
bool slave_role;
};
enum btc_antenna_pos {

View File

@ -435,7 +435,7 @@ int rtl_regd_init(struct ieee80211_hw *hw,
channel_plan_to_country_code(rtlpriv->efuse.channel_plan);
RT_TRACE(rtlpriv, COMP_REGD, DBG_DMESG,
"rtl: EEPROM regdomain: 0x%0x conuntry code: %d\n",
"rtl: EEPROM regdomain: 0x%0x country code: %d\n",
rtlpriv->efuse.channel_plan, rtlpriv->regd.country_code);
if (rtlpriv->regd.country_code >= COUNTRY_CODE_MAX) {

View File

@ -468,8 +468,10 @@ void rtl92ee_set_fw_media_status_rpt_cmd(struct ieee80211_hw *hw, u8 mstatus)
#define PSPOLL_PG 2
#define NULL_PG 3
#define PROBERSP_PG 4 /* ->5 */
#define QOS_NULL_PG 6
#define BT_QOS_NULL_PG 7
#define TOTAL_RESERVED_PKT_LEN 768
#define TOTAL_RESERVED_PKT_LEN 1024
static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
/* page 0 beacon */
@ -570,6 +572,42 @@ static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1A, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* page 6 qos null data */
0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1A, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* page 7 BT-qos null data */
0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@ -595,6 +633,8 @@ void rtl92ee_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
u8 *p_pspoll;
u8 *nullfunc;
u8 *p_probersp;
u8 *qosnull;
u8 *btqosnull;
/*---------------------------------------------------------
* (1) beacon
*---------------------------------------------------------
@ -636,6 +676,28 @@ void rtl92ee_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1rsvdpageloc, PROBERSP_PG);
/*---------------------------------------------------------
* (5) QoS null data
*----------------------------------------------------------
*/
qosnull = &reserved_page_packet[QOS_NULL_PG * 128];
SET_80211_HDR_ADDRESS1(qosnull, mac->bssid);
SET_80211_HDR_ADDRESS2(qosnull, mac->mac_addr);
SET_80211_HDR_ADDRESS3(qosnull, mac->bssid);
SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1rsvdpageloc, QOS_NULL_PG);
/*---------------------------------------------------------
* (6) BT QoS null data
*----------------------------------------------------------
*/
btqosnull = &reserved_page_packet[BT_QOS_NULL_PG * 128];
SET_80211_HDR_ADDRESS1(btqosnull, mac->bssid);
SET_80211_HDR_ADDRESS2(btqosnull, mac->mac_addr);
SET_80211_HDR_ADDRESS3(btqosnull, mac->bssid);
SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1rsvdpageloc, BT_QOS_NULL_PG);
totalpacketlen = TOTAL_RESERVED_PKT_LEN;
RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD ,

View File

@ -165,6 +165,10 @@ enum rtl8192e_c2h_evt {
SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val)
#define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val)
#define SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 3, 0, 8, __val)
#define SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 4, 0, 8, __val)
/* _MEDIA_STATUS_RPT_PARM_CMD1 */
#define SET_H2CCMD_MSRRPT_PARM_OPMODE(__cmd, __val) \

View File

@ -699,9 +699,9 @@ static bool _rtl92ee_llt_table_init(struct ieee80211_hw *hw)
u8 txpktbuf_bndy;
u8 u8tmp, testcnt = 0;
txpktbuf_bndy = 0xFA;
txpktbuf_bndy = 0xF7;
rtl_write_dword(rtlpriv, REG_RQPN, 0x80E90808);
rtl_write_dword(rtlpriv, REG_RQPN, 0x80E60808);
rtl_write_byte(rtlpriv, REG_TRXFF_BNDY, txpktbuf_bndy);
rtl_write_word(rtlpriv, REG_TRXFF_BNDY + 2, 0x3d00 - 1);

View File

@ -284,8 +284,10 @@ void rtl8723be_set_fw_media_status_rpt_cmd(struct ieee80211_hw *hw, u8 mstatus)
#define PSPOLL_PG 2
#define NULL_PG 3
#define PROBERSP_PG 4 /* ->5 */
#define QOS_NULL_PG 6
#define BT_QOS_NULL_PG 7
#define TOTAL_RESERVED_PKT_LEN 768
#define TOTAL_RESERVED_PKT_LEN 1024 /* can be up to 1280 (tx_bndy=245) */
static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
/* page 0 beacon */
@ -390,11 +392,48 @@ static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1A, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* page 6 qos null data */
0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1A, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* page 7 BT-qos null data */
0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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 rtl8723be_set_fw_rsvdpagepkt(struct ieee80211_hw *hw,
@ -413,6 +452,8 @@ void rtl8723be_set_fw_rsvdpagepkt(struct ieee80211_hw *hw,
u8 *p_pspoll;
u8 *nullfunc;
u8 *p_probersp;
u8 *qosnull;
u8 *btqosnull;
/*---------------------------------------------------------
* (1) beacon
*---------------------------------------------------------
@ -454,6 +495,28 @@ void rtl8723be_set_fw_rsvdpagepkt(struct ieee80211_hw *hw,
SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1rsvdpageloc, PROBERSP_PG);
/*---------------------------------------------------------
* (5) QoS Null
*---------------------------------------------------------
*/
qosnull = &reserved_page_packet[QOS_NULL_PG * 128];
SET_80211_HDR_ADDRESS1(qosnull, mac->bssid);
SET_80211_HDR_ADDRESS2(qosnull, mac->mac_addr);
SET_80211_HDR_ADDRESS3(qosnull, mac->bssid);
SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1rsvdpageloc, QOS_NULL_PG);
/*---------------------------------------------------------
* (5) QoS Null
*---------------------------------------------------------
*/
btqosnull = &reserved_page_packet[BT_QOS_NULL_PG * 128];
SET_80211_HDR_ADDRESS1(btqosnull, mac->bssid);
SET_80211_HDR_ADDRESS2(btqosnull, mac->mac_addr);
SET_80211_HDR_ADDRESS3(btqosnull, mac->bssid);
SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1rsvdpageloc, BT_QOS_NULL_PG);
totalpacketlen = TOTAL_RESERVED_PKT_LEN;
RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
@ -461,7 +524,7 @@ void rtl8723be_set_fw_rsvdpagepkt(struct ieee80211_hw *hw,
&reserved_page_packet[0], totalpacketlen);
RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
"rtl8723be_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
u1rsvdpageloc, 3);
u1rsvdpageloc, sizeof(u1rsvdpageloc));
skb = dev_alloc_skb(totalpacketlen);
memcpy((u8 *)skb_put(skb, totalpacketlen),
@ -476,7 +539,7 @@ void rtl8723be_set_fw_rsvdpagepkt(struct ieee80211_hw *hw,
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
"Set RSVD page location to Fw.\n");
RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, "H2C_RSVDPAGE:\n",
u1rsvdpageloc, 3);
u1rsvdpageloc, sizeof(u1rsvdpageloc));
rtl8723be_fill_h2c_cmd(hw, H2C_8723B_RSVDPAGE,
sizeof(u1rsvdpageloc), u1rsvdpageloc);
} else

View File

@ -139,6 +139,10 @@ enum rtl8723b_c2h_evt {
SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val)
#define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val)
#define SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 3, 0, 8, __val)
#define SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 4, 0, 8, __val)
void rtl8723be_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id,

View File

@ -91,7 +91,7 @@ int rtl8723be_init_sw_vars(struct ieee80211_hw *hw)
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
char *fw_name = "rtlwifi/rtl8723befw.bin";
char *fw_name = "rtlwifi/rtl8723befw_36.bin";
rtl8723be_bt_reg_init(hw);
rtlpriv->btcoexist.btc_ops = rtl_btc_get_ops_pointer();
@ -187,8 +187,16 @@ int rtl8723be_init_sw_vars(struct ieee80211_hw *hw)
rtlpriv->io.dev, GFP_KERNEL, hw,
rtl_fw_cb);
if (err) {
pr_err("Failed to request firmware!\n");
return 1;
/* Failed to get firmware. Check if old version available */
fw_name = "rtlwifi/rtl8723befw.bin";
pr_info("Using firmware %s\n", fw_name);
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");
return 1;
}
}
return 0;
}
@ -384,6 +392,7 @@ MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Realtek 8723BE 802.11n PCI wireless");
MODULE_FIRMWARE("rtlwifi/rtl8723befw.bin");
MODULE_FIRMWARE("rtlwifi/rtl8723befw_36.bin");
module_param_named(swenc, rtl8723be_mod_params.sw_crypto, bool, 0444);
module_param_named(debug_level, rtl8723be_mod_params.debug_level, int, 0644);

View File

@ -678,12 +678,13 @@ void rtl8821ae_set_fw_global_info_cmd(struct ieee80211_hw *hw)
#define PSPOLL_PG 1
#define NULL_PG 2
#define QOSNULL_PG 3
#define ARPRESP_PG 4
#define REMOTE_PG 5
#define GTKEXT_PG 6
#define BT_QOSNULL_PG 4
#define ARPRESP_PG 5
#define REMOTE_PG 6
#define GTKEXT_PG 7
#define TOTAL_RESERVED_PKT_LEN_8812 3584
#define TOTAL_RESERVED_PKT_LEN_8821 1792
#define TOTAL_RESERVED_PKT_LEN_8812 4096
#define TOTAL_RESERVED_PKT_LEN_8821 2048
static u8 reserved_page_packet_8821[TOTAL_RESERVED_PKT_LEN_8821] = {
/* page 0: beacon */
@ -813,13 +814,46 @@ static u8 reserved_page_packet_8821[TOTAL_RESERVED_PKT_LEN_8821] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1A, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* page 4: BT qos null data */
0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3C, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* page 4~6 is for wowlan */
/* page 4: ARP resp */
/* page 5~7 is for wowlan */
/* page 5: ARP resp */
0x08, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00,
@ -852,7 +886,7 @@ static u8 reserved_page_packet_8821[TOTAL_RESERVED_PKT_LEN_8821] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* page 5: H2C_REMOTE_WAKE_CTRL_INFO */
/* page 6: H2C_REMOTE_WAKE_CTRL_INFO */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@ -885,7 +919,7 @@ static u8 reserved_page_packet_8821[TOTAL_RESERVED_PKT_LEN_8821] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* page 6: Rsvd GTK extend memory (zero memory) */
/* page 7: Rsvd GTK extend memory (zero memory) */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@ -1176,13 +1210,78 @@ static u8 reserved_page_packet_8812[TOTAL_RESERVED_PKT_LEN_8812] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1A, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* page 4: BT Qos null data */
0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3C, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* page 4~6 is for wowlan */
/* page 4: ARP resp */
/* page 5~7 is for wowlan */
/* page 5: ARP resp */
0x08, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00,
@ -1247,7 +1346,7 @@ static u8 reserved_page_packet_8812[TOTAL_RESERVED_PKT_LEN_8812] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* page 5: H2C_REMOTE_WAKE_CTRL_INFO */
/* page 6: H2C_REMOTE_WAKE_CTRL_INFO */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@ -1312,7 +1411,7 @@ static u8 reserved_page_packet_8812[TOTAL_RESERVED_PKT_LEN_8812] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* page 6: Rsvd GTK extend memory (zero memory) */
/* page 7: Rsvd GTK extend memory (zero memory) */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@ -1394,6 +1493,7 @@ void rtl8812ae_set_fw_rsvdpagepkt(struct ieee80211_hw *hw,
u8 *p_pspoll;
u8 *nullfunc;
u8 *qosnull;
u8 *btqosnull;
u8 *arpresp;
/*---------------------------------------------------------
@ -1441,12 +1541,23 @@ void rtl8812ae_set_fw_rsvdpagepkt(struct ieee80211_hw *hw,
SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1RsvdPageLoc, QOSNULL_PG);
/*---------------------------------------------------------
* (5) BT Qos null data
*----------------------------------------------------------
*/
btqosnull = &reserved_page_packet_8812[BT_QOSNULL_PG * 512];
SET_80211_HDR_ADDRESS1(btqosnull, mac->bssid);
SET_80211_HDR_ADDRESS2(btqosnull, mac->mac_addr);
SET_80211_HDR_ADDRESS3(btqosnull, mac->bssid);
SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1RsvdPageLoc, BT_QOSNULL_PG);
if (!dl_whole_packets) {
totalpacketlen = 512 * (QOSNULL_PG + 1) - 40;
totalpacketlen = 512 * (BT_QOSNULL_PG + 1) - 40;
goto out;
}
/*---------------------------------------------------------
* (5) ARP Resp
* (6) ARP Resp
*----------------------------------------------------------
*/
arpresp = &reserved_page_packet_8812[ARPRESP_PG * 512];
@ -1457,14 +1568,14 @@ void rtl8812ae_set_fw_rsvdpagepkt(struct ieee80211_hw *hw,
SET_8821AE_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(u1RsvdPageLoc2, ARPRESP_PG);
/*---------------------------------------------------------
* (6) Remote Wake Ctrl
* (7) Remote Wake Ctrl
*----------------------------------------------------------
*/
SET_8821AE_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(u1RsvdPageLoc2,
REMOTE_PG);
/*---------------------------------------------------------
* (7) GTK Ext Memory
* (8) GTK Ext Memory
*----------------------------------------------------------
*/
SET_8821AE_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_EXT_MEM(u1RsvdPageLoc2, GTKEXT_PG);
@ -1518,6 +1629,7 @@ void rtl8821ae_set_fw_rsvdpagepkt(struct ieee80211_hw *hw,
u8 *p_pspoll;
u8 *nullfunc;
u8 *qosnull;
u8 *btqosnull;
u8 *arpresp;
/*---------------------------------------------------------
@ -1565,12 +1677,23 @@ void rtl8821ae_set_fw_rsvdpagepkt(struct ieee80211_hw *hw,
SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1RsvdPageLoc, QOSNULL_PG);
/*---------------------------------------------------------
* (5) Qos null data
*----------------------------------------------------------
*/
btqosnull = &reserved_page_packet_8821[BT_QOSNULL_PG * 256];
SET_80211_HDR_ADDRESS1(btqosnull, mac->bssid);
SET_80211_HDR_ADDRESS2(btqosnull, mac->mac_addr);
SET_80211_HDR_ADDRESS3(btqosnull, mac->bssid);
SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1RsvdPageLoc, BT_QOSNULL_PG);
if (!dl_whole_packets) {
totalpacketlen = 256 * (QOSNULL_PG + 1) - 40;
totalpacketlen = 256 * (BT_QOSNULL_PG + 1) - 40;
goto out;
}
/*---------------------------------------------------------
* (5) ARP Resp
* (6) ARP Resp
*----------------------------------------------------------
*/
arpresp = &reserved_page_packet_8821[ARPRESP_PG * 256];
@ -1581,14 +1704,14 @@ void rtl8821ae_set_fw_rsvdpagepkt(struct ieee80211_hw *hw,
SET_8821AE_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(u1RsvdPageLoc2, ARPRESP_PG);
/*---------------------------------------------------------
* (6) Remote Wake Ctrl
* (7) Remote Wake Ctrl
*----------------------------------------------------------
*/
SET_8821AE_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(u1RsvdPageLoc2,
REMOTE_PG);
/*---------------------------------------------------------
* (7) GTK Ext Memory
* (8) GTK Ext Memory
*----------------------------------------------------------
*/
SET_8821AE_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_EXT_MEM(u1RsvdPageLoc2, GTKEXT_PG);

View File

@ -229,6 +229,8 @@ enum rtl8821a_h2c_cmd {
SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val)
#define SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE((__ph2ccmd)+3, 0, 8, __val)
#define SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(__ph2ccmd, __val) \
SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 4, 0, 8, __val)
/* _MEDIA_STATUS_RPT_PARM_CMD1 */
#define SET_H2CCMD_MSRRPT_PARM_OPMODE(__cmd, __value) \

View File

@ -842,12 +842,8 @@ static bool _rtl8821ae_llt_table_init(struct ieee80211_hw *hw)
bool status;
maxpage = 255;
txpktbuf_bndy = 0xF8;
rqpn = 0x80e70808;
if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8812AE) {
txpktbuf_bndy = 0xFA;
rqpn = 0x80e90808;
}
txpktbuf_bndy = 0xF7;
rqpn = 0x80e60808;
rtl_write_byte(rtlpriv, REG_TRXFF_BNDY, txpktbuf_bndy);
rtl_write_word(rtlpriv, REG_TRXFF_BNDY + 2, MAX_RX_DMA_BUFFER_SIZE - 1);

View File

@ -660,6 +660,88 @@ void rtl8821ae_phy_switch_wirelessband(struct ieee80211_hw *hw, u8 band)
return;
}
static bool _rtl8821ae_check_positive(struct ieee80211_hw *hw,
const u32 condition1,
const u32 condition2)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
u32 cut_ver = ((rtlhal->version & CHIP_VER_RTL_MASK)
>> CHIP_VER_RTL_SHIFT);
u32 intf = (rtlhal->interface == INTF_USB ? BIT(1) : BIT(0));
u8 board_type = ((rtlhal->board_type & BIT(4)) >> 4) << 0 | /* _GLNA */
((rtlhal->board_type & BIT(3)) >> 3) << 1 | /* _GPA */
((rtlhal->board_type & BIT(7)) >> 7) << 2 | /* _ALNA */
((rtlhal->board_type & BIT(6)) >> 6) << 3 | /* _APA */
((rtlhal->board_type & BIT(2)) >> 2) << 4; /* _BT */
u32 cond1 = condition1, cond2 = condition2;
u32 driver1 = cut_ver << 24 | /* CUT ver */
0 << 20 | /* interface 2/2 */
0x04 << 16 | /* platform */
rtlhal->package_type << 12 |
intf << 8 | /* interface 1/2 */
board_type;
u32 driver2 = rtlhal->type_glna << 0 |
rtlhal->type_gpa << 8 |
rtlhal->type_alna << 16 |
rtlhal->type_apa << 24;
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
"===> [8812A] CheckPositive (cond1, cond2) = (0x%X 0x%X)\n",
cond1, cond2);
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
"===> [8812A] CheckPositive (driver1, driver2) = (0x%X 0x%X)\n",
driver1, driver2);
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
" (Platform, Interface) = (0x%X, 0x%X)\n", 0x04, intf);
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
" (Board, Package) = (0x%X, 0x%X)\n",
rtlhal->board_type, rtlhal->package_type);
/*============== Value Defined Check ===============*/
/*QFN Type [15:12] and Cut Version [27:24] need to do value check*/
if (((cond1 & 0x0000F000) != 0) && ((cond1 & 0x0000F000) !=
(driver1 & 0x0000F000)))
return false;
if (((cond1 & 0x0F000000) != 0) && ((cond1 & 0x0F000000) !=
(driver1 & 0x0F000000)))
return false;
/*=============== Bit Defined Check ================*/
/* We don't care [31:28] */
cond1 &= 0x00FF0FFF;
driver1 &= 0x00FF0FFF;
if ((cond1 & driver1) == cond1) {
u32 mask = 0;
if ((cond1 & 0x0F) == 0) /* BoardType is DONTCARE*/
return true;
if ((cond1 & BIT(0)) != 0) /*GLNA*/
mask |= 0x000000FF;
if ((cond1 & BIT(1)) != 0) /*GPA*/
mask |= 0x0000FF00;
if ((cond1 & BIT(2)) != 0) /*ALNA*/
mask |= 0x00FF0000;
if ((cond1 & BIT(3)) != 0) /*APA*/
mask |= 0xFF000000;
/* BoardType of each RF path is matched*/
if ((cond2 & mask) == (driver2 & mask))
return true;
else
return false;
} else
return false;
}
static bool _rtl8821ae_check_condition(struct ieee80211_hw *hw,
const u32 condition)
{
@ -1695,55 +1777,78 @@ static bool _rtl8821ae_phy_bb8821a_config_parafile(struct ieee80211_hw *hw)
return true;
}
static bool
__rtl8821ae_phy_config_with_headerfile(struct ieee80211_hw *hw,
u32 *array_table, u16 arraylen,
void (*set_reg)(struct ieee80211_hw *hw,
u32 regaddr, u32 data))
{
#define COND_ELSE 2
#define COND_ENDIF 3
int i = 0;
u8 cond;
bool matched = true, skipped = false;
while ((i + 1) < arraylen) {
u32 v1 = array_table[i];
u32 v2 = array_table[i + 1];
if (v1 & (BIT(31) | BIT(30))) {/*positive & negative condition*/
if (v1 & BIT(31)) {/* positive condition*/
cond = (u8)((v1 & (BIT(29) | BIT(28))) >> 28);
if (cond == COND_ENDIF) {/*end*/
matched = true;
skipped = false;
} else if (cond == COND_ELSE) /*else*/
matched = skipped ? false : true;
else {/*if , else if*/
if (skipped) {
matched = false;
} else {
if (_rtl8821ae_check_positive(
hw, v1, v2)) {
matched = true;
skipped = true;
} else {
matched = false;
skipped = false;
}
}
}
} else if (v1 & BIT(30)) { /*negative condition*/
/*do nothing*/
}
} else {
if (matched)
set_reg(hw, v1, v2);
}
i = i + 2;
}
return true;
}
static bool _rtl8821ae_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
u32 i, v1, v2;
u32 arraylength;
u32 *ptrarray;
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read MAC_REG_Array\n");
if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
arraylength = RTL8821AEMAC_1T_ARRAYLEN;
arraylength = RTL8821AE_MAC_1T_ARRAYLEN;
ptrarray = RTL8821AE_MAC_REG_ARRAY;
} else {
arraylength = RTL8812AEMAC_1T_ARRAYLEN;
arraylength = RTL8812AE_MAC_1T_ARRAYLEN;
ptrarray = RTL8812AE_MAC_REG_ARRAY;
}
RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
"Img: MAC_REG_ARRAY LEN %d\n", arraylength);
for (i = 0; i < arraylength; i += 2) {
v1 = ptrarray[i];
v2 = (u8)ptrarray[i + 1];
if (v1 < 0xCDCDCDCD) {
rtl_write_byte(rtlpriv, v1, (u8)v2);
continue;
} else {
if (!_rtl8821ae_check_condition(hw, v1)) {
/*Discard the following (offset, data) pairs*/
READ_NEXT_PAIR(ptrarray, v1, v2, i);
while (v2 != 0xDEAD &&
v2 != 0xCDEF &&
v2 != 0xCDCD && i < arraylength - 2) {
READ_NEXT_PAIR(ptrarray, v1, v2, i);
}
i -= 2; /* prevent from for-loop += 2*/
} else {/*Configure matched pairs and skip to end of if-else.*/
READ_NEXT_PAIR(ptrarray, v1, v2, i);
while (v2 != 0xDEAD &&
v2 != 0xCDEF &&
v2 != 0xCDCD && i < arraylength - 2) {
rtl_write_byte(rtlpriv, v1, v2);
READ_NEXT_PAIR(ptrarray, v1, v2, i);
}
while (v2 != 0xDEAD && i < arraylength - 2)
READ_NEXT_PAIR(ptrarray, v1, v2, i);
}
}
}
return true;
return __rtl8821ae_phy_config_with_headerfile(hw,
ptrarray, arraylength, rtl_write_byte_with_val32);
}
static bool _rtl8821ae_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
@ -1751,111 +1856,33 @@ static bool _rtl8821ae_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
int i;
u32 *array_table;
u16 arraylen;
u32 v1 = 0, v2 = 0;
if (configtype == BASEBAND_CONFIG_PHY_REG) {
if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
arraylen = RTL8812AEPHY_REG_1TARRAYLEN;
arraylen = RTL8812AE_PHY_REG_1TARRAYLEN;
array_table = RTL8812AE_PHY_REG_ARRAY;
} else {
arraylen = RTL8821AEPHY_REG_1TARRAYLEN;
arraylen = RTL8821AE_PHY_REG_1TARRAYLEN;
array_table = RTL8821AE_PHY_REG_ARRAY;
}
for (i = 0; i < arraylen; i += 2) {
v1 = array_table[i];
v2 = array_table[i + 1];
if (v1 < 0xCDCDCDCD) {
_rtl8821ae_config_bb_reg(hw, v1, v2);
continue;
} else {/*This line is the start line of branch.*/
if (!_rtl8821ae_check_condition(hw, v1)) {
/*Discard the following (offset, data) pairs*/
READ_NEXT_PAIR(array_table, v1, v2, i);
while (v2 != 0xDEAD &&
v2 != 0xCDEF &&
v2 != 0xCDCD &&
i < arraylen - 2) {
READ_NEXT_PAIR(array_table, v1,
v2, i);
}
i -= 2; /* prevent from for-loop += 2*/
} else {/*Configure matched pairs and skip to end of if-else.*/
READ_NEXT_PAIR(array_table, v1, v2, i);
while (v2 != 0xDEAD &&
v2 != 0xCDEF &&
v2 != 0xCDCD &&
i < arraylen - 2) {
_rtl8821ae_config_bb_reg(hw, v1,
v2);
READ_NEXT_PAIR(array_table, v1,
v2, i);
}
while (v2 != 0xDEAD &&
i < arraylen - 2) {
READ_NEXT_PAIR(array_table, v1,
v2, i);
}
}
}
}
return __rtl8821ae_phy_config_with_headerfile(hw,
array_table, arraylen,
_rtl8821ae_config_bb_reg);
} else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
arraylen = RTL8812AEAGCTAB_1TARRAYLEN;
arraylen = RTL8812AE_AGC_TAB_1TARRAYLEN;
array_table = RTL8812AE_AGC_TAB_ARRAY;
} else {
arraylen = RTL8821AEAGCTAB_1TARRAYLEN;
arraylen = RTL8821AE_AGC_TAB_1TARRAYLEN;
array_table = RTL8821AE_AGC_TAB_ARRAY;
}
for (i = 0; i < arraylen; i = i + 2) {
v1 = array_table[i];
v2 = array_table[i+1];
if (v1 < 0xCDCDCDCD) {
rtl_set_bbreg(hw, v1, MASKDWORD, v2);
udelay(1);
continue;
} else {/*This line is the start line of branch.*/
if (!_rtl8821ae_check_condition(hw, v1)) {
/*Discard the following (offset, data) pairs*/
READ_NEXT_PAIR(array_table, v1, v2, i);
while (v2 != 0xDEAD &&
v2 != 0xCDEF &&
v2 != 0xCDCD &&
i < arraylen - 2) {
READ_NEXT_PAIR(array_table, v1,
v2, i);
}
i -= 2; /* prevent from for-loop += 2*/
} else {/*Configure matched pairs and skip to end of if-else.*/
READ_NEXT_PAIR(array_table, v1, v2, i);
while (v2 != 0xDEAD &&
v2 != 0xCDEF &&
v2 != 0xCDCD &&
i < arraylen - 2) {
rtl_set_bbreg(hw, v1, MASKDWORD,
v2);
udelay(1);
READ_NEXT_PAIR(array_table, v1,
v2, i);
}
while (v2 != 0xDEAD &&
i < arraylen - 2) {
READ_NEXT_PAIR(array_table, v1,
v2, i);
}
}
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
"The agctab_array_table[0] is %x Rtl818EEPHY_REGArray[1] is %x\n",
array_table[i], array_table[i + 1]);
}
}
return __rtl8821ae_phy_config_with_headerfile(hw,
array_table, arraylen,
rtl_set_bbreg_with_dwmask);
}
return true;
}
@ -1913,10 +1940,10 @@ static bool _rtl8821ae_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
u32 v1, v2, v3, v4, v5, v6;
if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
arraylen = RTL8812AEPHY_REG_ARRAY_PGLEN;
arraylen = RTL8812AE_PHY_REG_ARRAY_PGLEN;
array = RTL8812AE_PHY_REG_ARRAY_PG;
} else {
arraylen = RTL8821AEPHY_REG_ARRAY_PGLEN;
arraylen = RTL8821AE_PHY_REG_ARRAY_PGLEN;
array = RTL8821AE_PHY_REG_ARRAY_PG;
}
@ -1980,12 +2007,10 @@ static bool _rtl8821ae_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
bool rtl8812ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
enum radio_path rfpath)
{
int i;
bool rtstatus = true;
u32 *radioa_array_table_a, *radioa_array_table_b;
u16 radioa_arraylen_a, radioa_arraylen_b;
struct rtl_priv *rtlpriv = rtl_priv(hw);
u32 v1 = 0, v2 = 0;
radioa_arraylen_a = RTL8812AE_RADIOA_1TARRAYLEN;
radioa_array_table_a = RTL8812AE_RADIOA_ARRAY;
@ -1997,69 +2022,14 @@ bool rtl8812ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
rtstatus = true;
switch (rfpath) {
case RF90_PATH_A:
for (i = 0; i < radioa_arraylen_a; i = i + 2) {
v1 = radioa_array_table_a[i];
v2 = radioa_array_table_a[i+1];
if (v1 < 0xcdcdcdcd) {
_rtl8821ae_config_rf_radio_a(hw, v1, v2);
continue;
} else{/*This line is the start line of branch.*/
if (!_rtl8821ae_check_condition(hw, v1)) {
/*Discard the following (offset, data) pairs*/
READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
while (v2 != 0xDEAD &&
v2 != 0xCDEF &&
v2 != 0xCDCD && i < radioa_arraylen_a-2)
READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
i -= 2; /* prevent from for-loop += 2*/
} else {/*Configure matched pairs and skip to end of if-else.*/
READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
while (v2 != 0xDEAD &&
v2 != 0xCDEF &&
v2 != 0xCDCD && i < radioa_arraylen_a - 2) {
_rtl8821ae_config_rf_radio_a(hw, v1, v2);
READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
}
while (v2 != 0xDEAD && i < radioa_arraylen_a-2)
READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
}
}
}
return __rtl8821ae_phy_config_with_headerfile(hw,
radioa_array_table_a, radioa_arraylen_a,
_rtl8821ae_config_rf_radio_a);
break;
case RF90_PATH_B:
for (i = 0; i < radioa_arraylen_b; i = i + 2) {
v1 = radioa_array_table_b[i];
v2 = radioa_array_table_b[i+1];
if (v1 < 0xcdcdcdcd) {
_rtl8821ae_config_rf_radio_b(hw, v1, v2);
continue;
} else{/*This line is the start line of branch.*/
if (!_rtl8821ae_check_condition(hw, v1)) {
/*Discard the following (offset, data) pairs*/
READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
while (v2 != 0xDEAD &&
v2 != 0xCDEF &&
v2 != 0xCDCD && i < radioa_arraylen_b-2)
READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
i -= 2; /* prevent from for-loop += 2*/
} else {/*Configure matched pairs and skip to end of if-else.*/
READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
while (v2 != 0xDEAD &&
v2 != 0xCDEF &&
v2 != 0xCDCD && i < radioa_arraylen_b-2) {
_rtl8821ae_config_rf_radio_b(hw, v1, v2);
READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
}
while (v2 != 0xDEAD && i < radioa_arraylen_b-2)
READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
}
}
}
return __rtl8821ae_phy_config_with_headerfile(hw,
radioa_array_table_b, radioa_arraylen_b,
_rtl8821ae_config_rf_radio_b);
break;
case RF90_PATH_C:
case RF90_PATH_D:
@ -2072,21 +2042,10 @@ bool rtl8812ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
bool rtl8821ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
enum radio_path rfpath)
{
#define READ_NEXT_RF_PAIR(v1, v2, i) \
do { \
i += 2; \
v1 = radioa_array_table[i]; \
v2 = radioa_array_table[i+1]; \
} \
while (0)
int i;
bool rtstatus = true;
u32 *radioa_array_table;
u16 radioa_arraylen;
struct rtl_priv *rtlpriv = rtl_priv(hw);
/* struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); */
u32 v1 = 0, v2 = 0;
radioa_arraylen = RTL8821AE_RADIOA_1TARRAYLEN;
radioa_array_table = RTL8821AE_RADIOA_ARRAY;
@ -2096,35 +2055,9 @@ bool rtl8821ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
rtstatus = true;
switch (rfpath) {
case RF90_PATH_A:
for (i = 0; i < radioa_arraylen; i = i + 2) {
v1 = radioa_array_table[i];
v2 = radioa_array_table[i+1];
if (v1 < 0xcdcdcdcd)
_rtl8821ae_config_rf_radio_a(hw, v1, v2);
else{/*This line is the start line of branch.*/
if (!_rtl8821ae_check_condition(hw, v1)) {
/*Discard the following (offset, data) pairs*/
READ_NEXT_RF_PAIR(v1, v2, i);
while (v2 != 0xDEAD &&
v2 != 0xCDEF &&
v2 != 0xCDCD && i < radioa_arraylen - 2)
READ_NEXT_RF_PAIR(v1, v2, i);
i -= 2; /* prevent from for-loop += 2*/
} else {/*Configure matched pairs and skip to end of if-else.*/
READ_NEXT_RF_PAIR(v1, v2, i);
while (v2 != 0xDEAD &&
v2 != 0xCDEF &&
v2 != 0xCDCD && i < radioa_arraylen - 2) {
_rtl8821ae_config_rf_radio_a(hw, v1, v2);
READ_NEXT_RF_PAIR(v1, v2, i);
}
while (v2 != 0xDEAD && i < radioa_arraylen - 2)
READ_NEXT_RF_PAIR(v1, v2, i);
}
}
}
return __rtl8821ae_phy_config_with_headerfile(hw,
radioa_array_table, radioa_arraylen,
_rtl8821ae_config_rf_radio_a);
break;
case RF90_PATH_B:

View File

@ -203,7 +203,7 @@ int rtl8821ae_init_sw_vars(struct ieee80211_hw *hw)
fw_name = "rtlwifi/rtl8812aefw.bin";
wowlan_fw_name = "rtlwifi/rtl8812aefw_wowlan.bin";
} else {
fw_name = "rtlwifi/rtl8821aefw.bin";
fw_name = "rtlwifi/rtl8821aefw_29.bin";
wowlan_fw_name = "rtlwifi/rtl8821aefw_wowlan.bin";
}
@ -214,8 +214,16 @@ int rtl8821ae_init_sw_vars(struct ieee80211_hw *hw)
rtlpriv->io.dev, GFP_KERNEL, hw,
rtl_fw_cb);
if (err) {
pr_err("Failed to request normal firmware!\n");
return 1;
/* Failed to get firmware. Check if old version available */
fw_name = "rtlwifi/rtl8821aefw.bin";
pr_info("Using firmware %s\n", fw_name);
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 normal firmware!\n");
return 1;
}
}
/*load wowlan firmware*/
pr_info("Using firmware %s\n", wowlan_fw_name);
@ -428,6 +436,7 @@ MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Realtek 8821ae 802.11ac PCI wireless");
MODULE_FIRMWARE("rtlwifi/rtl8821aefw.bin");
MODULE_FIRMWARE("rtlwifi/rtl8821aefw_29.bin");
module_param_named(swenc, rtl8821ae_mod_params.sw_crypto, bool, 0444);
module_param_named(debug_level, rtl8821ae_mod_params.debug_level, int, 0644);

File diff suppressed because it is too large Load Diff

View File

@ -29,32 +29,30 @@
#define __RTL8821AE_TABLE__H_
#include <linux/types.h>
#define RTL8821AEPHY_REG_1TARRAYLEN 344
extern u32 RTL8821AE_PHY_REG_1TARRAYLEN;
extern u32 RTL8821AE_PHY_REG_ARRAY[];
#define RTL8812AEPHY_REG_1TARRAYLEN 490
extern u32 RTL8812AE_PHY_REG_1TARRAYLEN;
extern u32 RTL8812AE_PHY_REG_ARRAY[];
#define RTL8821AEPHY_REG_ARRAY_PGLEN 90
extern u32 RTL8821AE_PHY_REG_ARRAY_PGLEN;
extern u32 RTL8821AE_PHY_REG_ARRAY_PG[];
#define RTL8812AEPHY_REG_ARRAY_PGLEN 276
extern u32 RTL8812AE_PHY_REG_ARRAY_PGLEN;
extern u32 RTL8812AE_PHY_REG_ARRAY_PG[];
/* #define RTL8723BE_RADIOA_1TARRAYLEN 206 */
/* extern u8 *RTL8821AE_TXPWR_LMT_ARRAY[]; */
#define RTL8812AE_RADIOA_1TARRAYLEN 1264
extern u32 RTL8812AE_RADIOA_1TARRAYLEN;
extern u32 RTL8812AE_RADIOA_ARRAY[];
#define RTL8812AE_RADIOB_1TARRAYLEN 1240
extern u32 RTL8812AE_RADIOB_1TARRAYLEN;
extern u32 RTL8812AE_RADIOB_ARRAY[];
#define RTL8821AE_RADIOA_1TARRAYLEN 1176
extern u32 RTL8821AE_RADIOA_1TARRAYLEN;
extern u32 RTL8821AE_RADIOA_ARRAY[];
#define RTL8821AEMAC_1T_ARRAYLEN 194
extern u32 RTL8821AE_MAC_1T_ARRAYLEN;
extern u32 RTL8821AE_MAC_REG_ARRAY[];
#define RTL8812AEMAC_1T_ARRAYLEN 214
extern u32 RTL8812AE_MAC_1T_ARRAYLEN;
extern u32 RTL8812AE_MAC_REG_ARRAY[];
#define RTL8821AEAGCTAB_1TARRAYLEN 382
extern u32 RTL8821AE_AGC_TAB_1TARRAYLEN;
extern u32 RTL8821AE_AGC_TAB_ARRAY[];
#define RTL8812AEAGCTAB_1TARRAYLEN 1312
extern u32 RTL8812AE_AGC_TAB_1TARRAYLEN;
extern u32 RTL8812AE_AGC_TAB_ARRAY[];
#define RTL8812AE_TXPWR_LMT_ARRAY_LEN 3948
extern u32 RTL8812AE_TXPWR_LMT_ARRAY_LEN;
extern u8 *RTL8812AE_TXPWR_LMT[];
#define RTL8821AE_TXPWR_LMT_ARRAY_LEN 3948
extern u32 RTL8821AE_TXPWR_LMT_ARRAY_LEN;
extern u8 *RTL8821AE_TXPWR_LMT[];
#endif

View File

@ -1529,6 +1529,10 @@ struct rtl_hal {
u8 external_lna_2g;
u8 external_pa_5g;
u8 external_lna_5g;
u8 type_glna;
u8 type_gpa;
u8 type_alna;
u8 type_apa;
u8 rfe_type;
/*firmware */
@ -2933,6 +2937,14 @@ static inline void rtl_write_byte(struct rtl_priv *rtlpriv, u32 addr, u8 val8)
rtlpriv->io.read8_sync(rtlpriv, addr);
}
static inline void rtl_write_byte_with_val32(struct ieee80211_hw *hw,
u32 addr, u32 val8)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
rtl_write_byte(rtlpriv, addr, (u8)val8);
}
static inline void rtl_write_word(struct rtl_priv *rtlpriv, u32 addr, u16 val16)
{
rtlpriv->io.write16_async(rtlpriv, addr, val16);
@ -2966,6 +2978,12 @@ static inline void rtl_set_bbreg(struct ieee80211_hw *hw, u32 regaddr,
rtlpriv->cfg->ops->set_bbreg(hw, regaddr, bitmask, data);
}
static inline void rtl_set_bbreg_with_dwmask(struct ieee80211_hw *hw,
u32 regaddr, u32 data)
{
rtl_set_bbreg(hw, regaddr, 0xffffffff, data);
}
static inline u32 rtl_get_rfreg(struct ieee80211_hw *hw,
enum radio_path rfpath, u32 regaddr,
u32 bitmask)

View File

@ -1249,7 +1249,7 @@ static ssize_t fw_logger_write(struct file *file,
}
if (wl->conf.fwlog.output == 0) {
wl1271_warning("iligal opperation - fw logger disabled by default, please change mode via wlconf");
wl1271_warning("invalid operation - fw logger disabled by default, please change mode via wlconf");
return -EINVAL;
}

View File

@ -1278,6 +1278,9 @@ static int eject_installer(struct usb_interface *intf)
u8 bulk_out_ep;
int r;
if (iface_desc->desc.bNumEndpoints < 2)
return -ENODEV;
/* Find bulk out endpoint */
for (r = 1; r >= 0; r--) {
endpoint = &iface_desc->endpoint[r].desc;