Merge tag 'master-2014-12-08' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next

John W. Linville says:

====================
pull request: wireless-next 2014-12-08

Please pull this last batch of pending wireless updates for the 3.19 tree...

For the wireless bits, Johannes says:

"This time I have Felix's no-status rate control work, which will allow
drivers to work better with rate control even if they don't have perfect
status reporting. In addition to this, a small hwsim fix from Patrik,
one of the regulatory patches from Arik, and a number of cleanups and
fixes I did myself.

Of note is a patch where I disable CFG80211_WEXT so that compatibility
is no longer selectable - this is intended as a wake-up call for anyone
who's still using it, and is still easily worked around (it's a one-line
patch) before we fully remove the code as well in the future."

For the Bluetooth bits, Johan says:

"Here's one more bluetooth-next pull request for 3.19:

 - Minor cleanups for ieee802154 & mac802154
 - Fix for the kernel warning with !TASK_RUNNING reported by Kirill A.
   Shutemov
 - Support for another ath3k device
 - Fix for tracking link key based security level
 - Device tree bindings for btmrvl + a state update fix
 - Fix for wrong ACL flags on LE links"

And...

"In addition to the previous one this contains two more cleanups to
mac802154 as well as support for some new HCI features from the
Bluetooth 4.2 specification.

From the original request:

'Here's what should be the last bluetooth-next pull request for 3.19.
It's rather large but the majority of it is the Low Energy Secure
Connections feature that's part of the Bluetooth 4.2 specification. The
specification went public only this week so we couldn't publish the
corresponding code before that. The code itself can nevertheless be
considered fairly mature as it's been in development for over 6 months
and gone through several interoperability test events.

Besides LE SC the pull request contains an important fix for command
complete events for mgmt sockets which also fixes some leaks of hci_conn
objects when powering off or unplugging Bluetooth adapters.

A smaller feature that's part of the pull request is service discovery
support. This is like normal device discovery except that devices not
matching specific UUIDs or strong enough RSSI are filtered out.

Other changes that the pull request contains are firmware dump support
to the btmrvl driver, firmware download support for Broadcom BCM20702A0
variants, as well as some coding style cleanups in 6lowpan &
ieee802154/mac802154 code.'"

For the NFC bits, Samuel says:

"With this one we get:

- NFC digital improvements for DEP support: Chaining, NACK and ATN
  support added.

- NCI improvements: Support for p2p target, SE IO operand addition,
  SE operands extensions to support proprietary implementations, and
  a few fixes.

- NFC HCI improvements: OPEN_PIPE and NOTIFY_ALL_CLEARED support,
  and SE IO operand addition.

- A bunch of minor improvements and fixes for STMicro st21nfcb and
  st21nfca"

For the iwlwifi bits, Emmanuel says:

"Major works are CSA and TDLS. On top of that I have a new
firmware API for scan and a few rate control improvements.
Johannes find a few tricks to improve our CPU utilization
and adds support for a new spin of 7265 called 7265D.
Along with this a few random things that don't stand out."

And...

"I deprecate here -8.ucode since -9 has been published long ago.
Along with that I have a new activity, we have now better
a infrastructure for firmware debugging. This will allow to
have configurable probes insides the firmware.
Luca continues his work on NetDetect, this feature is now
complete. All the rest is minor fixes here and there."

For the Atheros bits, Kalle says:

"Only ath10k changes this time and no major changes. Most visible are:

o new debugfs interface for runtime firmware debugging (Yanbo)

o fix shared WEP (Sujith)

o don't rebuild whenever kernel version changes (Johannes)

o lots of refactoring to make it easier to add new hw support (Michal)

There's also smaller fixes and improvements with no point of listing
here."

In addition, there are a few last minute updates to ath5k,
ath9k, brcmfmac, brcmsmac, mwifiex, rt2x00, rtlwifi, and wil6210.
Also included is a pull of the wireless tree to pick-up the fixes
originally included in "pull request: wireless 2014-12-03"...

Please let me know if there are problems!
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller
2014-12-09 18:12:03 -05:00
228 changed files with 12470 additions and 3616 deletions
@@ -0,0 +1,29 @@
btmrvl
------
Required properties:
- compatible : must be "btmrvl,cfgdata"
Optional properties:
- btmrvl,cal-data : Calibration data downloaded to the device during
initialization. This is an array of 28 values(u8).
- btmrvl,gpio-gap : gpio and gap (in msecs) combination to be
configured.
Example:
GPIO pin 13 is configured as a wakeup source and GAP is set to 100 msecs
in below example.
btmrvl {
compatible = "btmrvl,cfgdata";
btmrvl,cal-data = /bits/ 8 <
0x37 0x01 0x1c 0x00 0xff 0xff 0xff 0xff 0x01 0x7f 0x04 0x02
0x00 0x00 0xba 0xce 0xc0 0xc6 0x2d 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0xf0 0x00>;
btmrvl,gpio-gap = <0x0d64>;
};
+1 -2
View File
@@ -7919,11 +7919,10 @@ S: Maintained
F: drivers/media/dvb-frontends/rtl2832_sdr*
RTL8180 WIRELESS DRIVER
M: "John W. Linville" <linville@tuxdriver.com>
L: linux-wireless@vger.kernel.org
W: http://wireless.kernel.org/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
S: Maintained
S: Orphan
F: drivers/net/wireless/rtl818x/rtl8180/
RTL8187 WIRELESS DRIVER
+1
View File
@@ -210,6 +210,7 @@ config BT_MRVL_SDIO
tristate "Marvell BT-over-SDIO driver"
depends on BT_MRVL && MMC
select FW_LOADER
select WANT_DEV_COREDUMP
help
The driver for Marvell Bluetooth chipsets with SDIO interface.
+2
View File
@@ -106,6 +106,7 @@ static const struct usb_device_id ath3k_table[] = {
{ USB_DEVICE(0x13d3, 0x3375) },
{ USB_DEVICE(0x13d3, 0x3393) },
{ USB_DEVICE(0x13d3, 0x3402) },
{ USB_DEVICE(0x13d3, 0x3408) },
{ USB_DEVICE(0x13d3, 0x3432) },
/* Atheros AR5BBU12 with sflash firmware */
@@ -158,6 +159,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = {
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3408), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 },
/* Atheros AR5BBU22 with sflash firmware */
+31
View File
@@ -167,6 +167,35 @@ static const struct file_operations btmrvl_hscmd_fops = {
.llseek = default_llseek,
};
static ssize_t btmrvl_fwdump_write(struct file *file, const char __user *ubuf,
size_t count, loff_t *ppos)
{
struct btmrvl_private *priv = file->private_data;
char buf[16];
bool result;
memset(buf, 0, sizeof(buf));
if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
return -EFAULT;
if (strtobool(buf, &result))
return -EINVAL;
if (!result)
return -EINVAL;
btmrvl_firmware_dump(priv);
return count;
}
static const struct file_operations btmrvl_fwdump_fops = {
.write = btmrvl_fwdump_write,
.open = simple_open,
.llseek = default_llseek,
};
void btmrvl_debugfs_init(struct hci_dev *hdev)
{
struct btmrvl_private *priv = hci_get_drvdata(hdev);
@@ -197,6 +226,8 @@ void btmrvl_debugfs_init(struct hci_dev *hdev)
priv, &btmrvl_hscmd_fops);
debugfs_create_file("hscfgcmd", 0644, dbg->config_dir,
priv, &btmrvl_hscfgcmd_fops);
debugfs_create_file("fw_dump", 0200, dbg->config_dir,
priv, &btmrvl_fwdump_fops);
dbg->status_dir = debugfs_create_dir("status", hdev->debugfs);
debugfs_create_u8("curpsmode", 0444, dbg->status_dir,
+20
View File
@@ -32,6 +32,24 @@
/* Time to wait for command response in millisecond */
#define WAIT_UNTIL_CMD_RESP 5000
enum rdwr_status {
RDWR_STATUS_SUCCESS = 0,
RDWR_STATUS_FAILURE = 1,
RDWR_STATUS_DONE = 2
};
#define FW_DUMP_MAX_NAME_LEN 8
#define FW_DUMP_HOST_READY 0xEE
#define FW_DUMP_DONE 0xFF
#define FW_DUMP_READ_DONE 0xFE
struct memory_type_mapping {
u8 mem_name[FW_DUMP_MAX_NAME_LEN];
u8 *mem_ptr;
u32 mem_size;
u8 done_flag;
};
struct btmrvl_thread {
struct task_struct *task;
wait_queue_head_t wait_q;
@@ -81,6 +99,7 @@ struct btmrvl_private {
u8 *payload, u16 nb);
int (*hw_wakeup_firmware) (struct btmrvl_private *priv);
int (*hw_process_int_status) (struct btmrvl_private *priv);
void (*firmware_dump)(struct btmrvl_private *priv);
spinlock_t driver_lock; /* spinlock used by driver */
#ifdef CONFIG_DEBUG_FS
void *debugfs_data;
@@ -151,6 +170,7 @@ int btmrvl_send_hscfg_cmd(struct btmrvl_private *priv);
int btmrvl_enable_ps(struct btmrvl_private *priv);
int btmrvl_prepare_command(struct btmrvl_private *priv);
int btmrvl_enable_hs(struct btmrvl_private *priv);
void btmrvl_firmware_dump(struct btmrvl_private *priv);
#ifdef CONFIG_DEBUG_FS
void btmrvl_debugfs_init(struct hci_dev *hdev);
+39 -23
View File
@@ -22,6 +22,7 @@
#include <linux/of.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <linux/mmc/sdio_func.h>
#include "btmrvl_drv.h"
#include "btmrvl_sdio.h"
@@ -41,6 +42,11 @@ void btmrvl_interrupt(struct btmrvl_private *priv)
priv->adapter->int_count++;
if (priv->adapter->hs_state == HS_ACTIVATED) {
BT_DBG("BT: HS DEACTIVATED in ISR!");
priv->adapter->hs_state = HS_DEACTIVATED;
}
wake_up_interruptible(&priv->main_thread.wait_q);
}
EXPORT_SYMBOL_GPL(btmrvl_interrupt);
@@ -209,7 +215,7 @@ int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, u8 subcmd)
ret = btmrvl_send_sync_cmd(priv, BT_CMD_MODULE_CFG_REQ, &subcmd, 1);
if (ret)
BT_ERR("module_cfg_cmd(%x) failed\n", subcmd);
BT_ERR("module_cfg_cmd(%x) failed", subcmd);
return ret;
}
@@ -245,7 +251,7 @@ int btmrvl_send_hscfg_cmd(struct btmrvl_private *priv)
ret = btmrvl_send_sync_cmd(priv, BT_CMD_HOST_SLEEP_CONFIG, param, 2);
if (ret)
BT_ERR("HSCFG command failed\n");
BT_ERR("HSCFG command failed");
return ret;
}
@@ -263,7 +269,7 @@ int btmrvl_enable_ps(struct btmrvl_private *priv)
ret = btmrvl_send_sync_cmd(priv, BT_CMD_AUTO_SLEEP_MODE, &param, 1);
if (ret)
BT_ERR("PSMODE command failed\n");
BT_ERR("PSMODE command failed");
return 0;
}
@@ -276,7 +282,7 @@ int btmrvl_enable_hs(struct btmrvl_private *priv)
ret = btmrvl_send_sync_cmd(priv, BT_CMD_HOST_SLEEP_ENABLE, NULL, 0);
if (ret) {
BT_ERR("Host sleep enable command failed\n");
BT_ERR("Host sleep enable command failed");
return ret;
}
@@ -323,12 +329,19 @@ int btmrvl_prepare_command(struct btmrvl_private *priv)
} else {
ret = priv->hw_wakeup_firmware(priv);
priv->adapter->hs_state = HS_DEACTIVATED;
BT_DBG("BT: HS DEACTIVATED due to host activity!");
}
}
return ret;
}
void btmrvl_firmware_dump(struct btmrvl_private *priv)
{
if (priv->firmware_dump)
priv->firmware_dump(priv);
}
static int btmrvl_tx_pkt(struct btmrvl_private *priv, struct sk_buff *skb)
{
int ret = 0;
@@ -487,34 +500,36 @@ static int btmrvl_download_cal_data(struct btmrvl_private *priv,
ret = btmrvl_send_sync_cmd(priv, BT_CMD_LOAD_CONFIG_DATA, data,
BT_CAL_HDR_LEN + len);
if (ret)
BT_ERR("Failed to download caibration data\n");
BT_ERR("Failed to download caibration data");
return 0;
}
static int btmrvl_cal_data_dt(struct btmrvl_private *priv)
static int btmrvl_check_device_tree(struct btmrvl_private *priv)
{
struct device_node *dt_node;
u8 cal_data[BT_CAL_HDR_LEN + BT_CAL_DATA_SIZE];
const char name[] = "btmrvl_caldata";
const char property[] = "btmrvl,caldata";
int ret;
u32 val;
dt_node = of_find_node_by_name(NULL, name);
if (!dt_node)
return -ENODEV;
for_each_compatible_node(dt_node, NULL, "btmrvl,cfgdata") {
ret = of_property_read_u32(dt_node, "btmrvl,gpio-gap", &val);
if (!ret)
priv->btmrvl_dev.gpio_gap = val;
ret = of_property_read_u8_array(dt_node, property,
cal_data + BT_CAL_HDR_LEN,
BT_CAL_DATA_SIZE);
if (ret)
return ret;
ret = of_property_read_u8_array(dt_node, "btmrvl,cal-data",
cal_data + BT_CAL_HDR_LEN,
BT_CAL_DATA_SIZE);
if (ret)
return ret;
BT_DBG("Use cal data from device tree");
ret = btmrvl_download_cal_data(priv, cal_data, BT_CAL_DATA_SIZE);
if (ret) {
BT_ERR("Fail to download calibrate data");
return ret;
BT_DBG("Use cal data from device tree");
ret = btmrvl_download_cal_data(priv, cal_data,
BT_CAL_DATA_SIZE);
if (ret) {
BT_ERR("Fail to download calibrate data");
return ret;
}
}
return 0;
@@ -526,14 +541,15 @@ static int btmrvl_setup(struct hci_dev *hdev)
btmrvl_send_module_cfg_cmd(priv, MODULE_BRINGUP_REQ);
btmrvl_cal_data_dt(priv);
priv->btmrvl_dev.gpio_gap = 0xffff;
btmrvl_check_device_tree(priv);
btmrvl_pscan_window_reporting(priv, 0x01);
priv->btmrvl_dev.psmode = 1;
btmrvl_enable_ps(priv);
priv->btmrvl_dev.gpio_gap = 0xffff;
btmrvl_send_hscfg_cmd(priv);
return 0;
+302 -2
View File
@@ -24,6 +24,7 @@
#include <linux/mmc/sdio_ids.h>
#include <linux/mmc/sdio_func.h>
#include <linux/module.h>
#include <linux/devcoredump.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
@@ -33,6 +34,24 @@
#define VERSION "1.0"
static struct memory_type_mapping mem_type_mapping_tbl[] = {
{"ITCM", NULL, 0, 0xF0},
{"DTCM", NULL, 0, 0xF1},
{"SQRAM", NULL, 0, 0xF2},
{"APU", NULL, 0, 0xF3},
{"CIU", NULL, 0, 0xF4},
{"ICU", NULL, 0, 0xF5},
{"MAC", NULL, 0, 0xF6},
{"EXT7", NULL, 0, 0xF7},
{"EXT8", NULL, 0, 0xF8},
{"EXT9", NULL, 0, 0xF9},
{"EXT10", NULL, 0, 0xFA},
{"EXT11", NULL, 0, 0xFB},
{"EXT12", NULL, 0, 0xFC},
{"EXT13", NULL, 0, 0xFD},
{"EXTLAST", NULL, 0, 0xFE},
};
/* The btmrvl_sdio_remove() callback function is called
* when user removes this module from kernel space or ejects
* the card from the slot. The driver handles these 2 cases
@@ -122,6 +141,9 @@ static const struct btmrvl_sdio_card_reg btmrvl_reg_8897 = {
.int_read_to_clear = true,
.host_int_rsr = 0x01,
.card_misc_cfg = 0xcc,
.fw_dump_ctrl = 0xe2,
.fw_dump_start = 0xe3,
.fw_dump_end = 0xea,
};
static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = {
@@ -130,6 +152,7 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = {
.reg = &btmrvl_reg_8688,
.support_pscan_win_report = false,
.sd_blksz_fw_dl = 64,
.supports_fw_dump = false,
};
static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = {
@@ -138,6 +161,7 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = {
.reg = &btmrvl_reg_87xx,
.support_pscan_win_report = false,
.sd_blksz_fw_dl = 256,
.supports_fw_dump = false,
};
static const struct btmrvl_sdio_device btmrvl_sdio_sd8797 = {
@@ -146,6 +170,7 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8797 = {
.reg = &btmrvl_reg_87xx,
.support_pscan_win_report = false,
.sd_blksz_fw_dl = 256,
.supports_fw_dump = false,
};
static const struct btmrvl_sdio_device btmrvl_sdio_sd8887 = {
@@ -154,6 +179,7 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8887 = {
.reg = &btmrvl_reg_8887,
.support_pscan_win_report = true,
.sd_blksz_fw_dl = 256,
.supports_fw_dump = false,
};
static const struct btmrvl_sdio_device btmrvl_sdio_sd8897 = {
@@ -162,6 +188,7 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8897 = {
.reg = &btmrvl_reg_8897,
.support_pscan_win_report = true,
.sd_blksz_fw_dl = 256,
.supports_fw_dump = true,
};
static const struct sdio_device_id btmrvl_sdio_ids[] = {
@@ -764,8 +791,8 @@ static void btmrvl_sdio_interrupt(struct sdio_func *func)
card = sdio_get_drvdata(func);
if (!card || !card->priv) {
BT_ERR("sbi_interrupt(%p) card or priv is "
"NULL, card=%p\n", func, card);
BT_ERR("sbi_interrupt(%p) card or priv is NULL, card=%p",
func, card);
return;
}
@@ -1080,6 +1107,277 @@ static int btmrvl_sdio_wakeup_fw(struct btmrvl_private *priv)
return ret;
}
static void btmrvl_sdio_dump_regs(struct btmrvl_private *priv)
{
struct btmrvl_sdio_card *card = priv->btmrvl_dev.card;
int ret = 0;
unsigned int reg, reg_start, reg_end;
char buf[256], *ptr;
u8 loop, func, data;
int MAX_LOOP = 2;
btmrvl_sdio_wakeup_fw(priv);
sdio_claim_host(card->func);
for (loop = 0; loop < MAX_LOOP; loop++) {
memset(buf, 0, sizeof(buf));
ptr = buf;
if (loop == 0) {
/* Read the registers of SDIO function0 */
func = loop;
reg_start = 0;
reg_end = 9;
} else {
func = 2;
reg_start = 0;
reg_end = 0x09;
}
ptr += sprintf(ptr, "SDIO Func%d (%#x-%#x): ",
func, reg_start, reg_end);
for (reg = reg_start; reg <= reg_end; reg++) {
if (func == 0)
data = sdio_f0_readb(card->func, reg, &ret);
else
data = sdio_readb(card->func, reg, &ret);
if (!ret) {
ptr += sprintf(ptr, "%02x ", data);
} else {
ptr += sprintf(ptr, "ERR");
break;
}
}
BT_INFO("%s", buf);
}
sdio_release_host(card->func);
}
/* This function read/write firmware */
static enum
rdwr_status btmrvl_sdio_rdwr_firmware(struct btmrvl_private *priv,
u8 doneflag)
{
struct btmrvl_sdio_card *card = priv->btmrvl_dev.card;
int ret, tries;
u8 ctrl_data = 0;
sdio_writeb(card->func, FW_DUMP_HOST_READY, card->reg->fw_dump_ctrl,
&ret);
if (ret) {
BT_ERR("SDIO write err");
return RDWR_STATUS_FAILURE;
}
for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
ctrl_data = sdio_readb(card->func, card->reg->fw_dump_ctrl,
&ret);
if (ret) {
BT_ERR("SDIO read err");
return RDWR_STATUS_FAILURE;
}
if (ctrl_data == FW_DUMP_DONE)
break;
if (doneflag && ctrl_data == doneflag)
return RDWR_STATUS_DONE;
if (ctrl_data != FW_DUMP_HOST_READY) {
BT_INFO("The ctrl reg was changed, re-try again!");
sdio_writeb(card->func, FW_DUMP_HOST_READY,
card->reg->fw_dump_ctrl, &ret);
if (ret) {
BT_ERR("SDIO write err");
return RDWR_STATUS_FAILURE;
}
}
usleep_range(100, 200);
}
if (ctrl_data == FW_DUMP_HOST_READY) {
BT_ERR("Fail to pull ctrl_data");
return RDWR_STATUS_FAILURE;
}
return RDWR_STATUS_SUCCESS;
}
/* This function dump sdio register and memory data */
static void btmrvl_sdio_dump_firmware(struct btmrvl_private *priv)
{
struct btmrvl_sdio_card *card = priv->btmrvl_dev.card;
int ret = 0;
unsigned int reg, reg_start, reg_end;
enum rdwr_status stat;
u8 *dbg_ptr, *end_ptr, *fw_dump_data, *fw_dump_ptr;
u8 dump_num, idx, i, read_reg, doneflag = 0;
u32 memory_size, fw_dump_len = 0;
/* dump sdio register first */
btmrvl_sdio_dump_regs(priv);
if (!card->supports_fw_dump) {
BT_ERR("Firmware dump not supported for this card!");
return;
}
for (idx = 0; idx < ARRAY_SIZE(mem_type_mapping_tbl); idx++) {
struct memory_type_mapping *entry = &mem_type_mapping_tbl[idx];
if (entry->mem_ptr) {
vfree(entry->mem_ptr);
entry->mem_ptr = NULL;
}
entry->mem_size = 0;
}
btmrvl_sdio_wakeup_fw(priv);
sdio_claim_host(card->func);
BT_INFO("== btmrvl firmware dump start ==");
stat = btmrvl_sdio_rdwr_firmware(priv, doneflag);
if (stat == RDWR_STATUS_FAILURE)
goto done;
reg = card->reg->fw_dump_start;
/* Read the number of the memories which will dump */
dump_num = sdio_readb(card->func, reg, &ret);
if (ret) {
BT_ERR("SDIO read memory length err");
goto done;
}
/* Read the length of every memory which will dump */
for (idx = 0; idx < dump_num; idx++) {
struct memory_type_mapping *entry = &mem_type_mapping_tbl[idx];
stat = btmrvl_sdio_rdwr_firmware(priv, doneflag);
if (stat == RDWR_STATUS_FAILURE)
goto done;
memory_size = 0;
reg = card->reg->fw_dump_start;
for (i = 0; i < 4; i++) {
read_reg = sdio_readb(card->func, reg, &ret);
if (ret) {
BT_ERR("SDIO read err");
goto done;
}
memory_size |= (read_reg << i*8);
reg++;
}
if (memory_size == 0) {
BT_INFO("Firmware dump finished!");
break;
}
BT_INFO("%s_SIZE=0x%x", entry->mem_name, memory_size);
entry->mem_ptr = vzalloc(memory_size + 1);
entry->mem_size = memory_size;
if (!entry->mem_ptr) {
BT_ERR("Vzalloc %s failed", entry->mem_name);
goto done;
}
fw_dump_len += (strlen("========Start dump ") +
strlen(entry->mem_name) +
strlen("========\n") +
(memory_size + 1) +
strlen("\n========End dump========\n"));
dbg_ptr = entry->mem_ptr;
end_ptr = dbg_ptr + memory_size;
doneflag = entry->done_flag;
BT_INFO("Start %s output, please wait...",
entry->mem_name);
do {
stat = btmrvl_sdio_rdwr_firmware(priv, doneflag);
if (stat == RDWR_STATUS_FAILURE)
goto done;
reg_start = card->reg->fw_dump_start;
reg_end = card->reg->fw_dump_end;
for (reg = reg_start; reg <= reg_end; reg++) {
*dbg_ptr = sdio_readb(card->func, reg, &ret);
if (ret) {
BT_ERR("SDIO read err");
goto done;
}
if (dbg_ptr < end_ptr)
dbg_ptr++;
else
BT_ERR("Allocated buffer not enough");
}
if (stat != RDWR_STATUS_DONE) {
continue;
} else {
BT_INFO("%s done: size=0x%tx",
entry->mem_name,
dbg_ptr - entry->mem_ptr);
break;
}
} while (1);
}
BT_INFO("== btmrvl firmware dump end ==");
done:
sdio_release_host(card->func);
if (fw_dump_len == 0)
return;
fw_dump_data = vzalloc(fw_dump_len+1);
if (!fw_dump_data) {
BT_ERR("Vzalloc fw_dump_data fail!");
return;
}
fw_dump_ptr = fw_dump_data;
/* Dump all the memory data into single file, a userspace script will
be used to split all the memory data to multiple files*/
BT_INFO("== btmrvl firmware dump to /sys/class/devcoredump start");
for (idx = 0; idx < dump_num; idx++) {
struct memory_type_mapping *entry = &mem_type_mapping_tbl[idx];
if (entry->mem_ptr) {
strcpy(fw_dump_ptr, "========Start dump ");
fw_dump_ptr += strlen("========Start dump ");
strcpy(fw_dump_ptr, entry->mem_name);
fw_dump_ptr += strlen(entry->mem_name);
strcpy(fw_dump_ptr, "========\n");
fw_dump_ptr += strlen("========\n");
memcpy(fw_dump_ptr, entry->mem_ptr, entry->mem_size);
fw_dump_ptr += entry->mem_size;
strcpy(fw_dump_ptr, "\n========End dump========\n");
fw_dump_ptr += strlen("\n========End dump========\n");
vfree(mem_type_mapping_tbl[idx].mem_ptr);
mem_type_mapping_tbl[idx].mem_ptr = NULL;
}
}
/* fw_dump_data will be free in device coredump release function
after 5 min*/
dev_coredumpv(&priv->btmrvl_dev.hcidev->dev, fw_dump_data,
fw_dump_len, GFP_KERNEL);
BT_INFO("== btmrvl firmware dump to /sys/class/devcoredump end");
}
static int btmrvl_sdio_probe(struct sdio_func *func,
const struct sdio_device_id *id)
{
@@ -1103,6 +1401,7 @@ static int btmrvl_sdio_probe(struct sdio_func *func,
card->reg = data->reg;
card->sd_blksz_fw_dl = data->sd_blksz_fw_dl;
card->support_pscan_win_report = data->support_pscan_win_report;
card->supports_fw_dump = data->supports_fw_dump;
}
if (btmrvl_sdio_register_dev(card) < 0) {
@@ -1134,6 +1433,7 @@ static int btmrvl_sdio_probe(struct sdio_func *func,
priv->hw_host_to_card = btmrvl_sdio_host_to_card;
priv->hw_wakeup_firmware = btmrvl_sdio_wakeup_fw;
priv->hw_process_int_status = btmrvl_sdio_process_int_status;
priv->firmware_dump = btmrvl_sdio_dump_firmware;
if (btmrvl_register_hdev(priv)) {
BT_ERR("Register hdev failed!");
+5
View File
@@ -81,6 +81,9 @@ struct btmrvl_sdio_card_reg {
bool int_read_to_clear;
u8 host_int_rsr;
u8 card_misc_cfg;
u8 fw_dump_ctrl;
u8 fw_dump_start;
u8 fw_dump_end;
};
struct btmrvl_sdio_card {
@@ -90,6 +93,7 @@ struct btmrvl_sdio_card {
const char *firmware;
const struct btmrvl_sdio_card_reg *reg;
bool support_pscan_win_report;
bool supports_fw_dump;
u16 sd_blksz_fw_dl;
u8 rx_unit;
struct btmrvl_private *priv;
@@ -101,6 +105,7 @@ struct btmrvl_sdio_device {
const struct btmrvl_sdio_card_reg *reg;
const bool support_pscan_win_report;
u16 sd_blksz_fw_dl;
bool supports_fw_dump;
};
+3 -1
View File
@@ -110,7 +110,8 @@ static const struct usb_device_id btusb_table[] = {
.driver_info = BTUSB_BCM_PATCHRAM },
/* Foxconn - Hon Hai */
{ USB_VENDOR_AND_INTERFACE_INFO(0x0489, 0xff, 0x01, 0x01) },
{ USB_VENDOR_AND_INTERFACE_INFO(0x0489, 0xff, 0x01, 0x01),
.driver_info = BTUSB_BCM_PATCHRAM },
/* Broadcom devices with vendor specific id */
{ USB_VENDOR_AND_INTERFACE_INFO(0x0a5c, 0xff, 0x01, 0x01),
@@ -185,6 +186,7 @@ static const struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3408), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 },
/* Atheros AR5BBU12 with sflash firmware */
+2
View File
@@ -2104,6 +2104,7 @@ static int b44_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
bp->flags &= ~B44_FLAG_WOL_ENABLE;
spin_unlock_irq(&bp->lock);
device_set_wakeup_enable(bp->sdev->dev, wol->wolopts & WAKE_MAGIC);
return 0;
}
@@ -2452,6 +2453,7 @@ static int b44_init_one(struct ssb_device *sdev,
}
}
device_set_wakeup_capable(sdev->dev, true);
netdev_info(dev, "%s %pM\n", DRV_DESCRIPTION, dev->dev_addr);
return 0;
+1 -1
View File
@@ -858,7 +858,7 @@ static int cc2520_probe(struct spi_device *spi)
pinctrl = devm_pinctrl_get_select_default(&spi->dev);
if (IS_ERR(pinctrl))
dev_warn(&spi->dev,
"pinctrl pins are not configured");
"pinctrl pins are not configured\n");
pdata = cc2520_get_platform_data(spi);
if (!pdata) {
+13
View File
@@ -799,6 +799,17 @@ static void ath10k_core_restart(struct work_struct *work)
mutex_unlock(&ar->conf_mutex);
}
static void ath10k_core_init_max_sta_count(struct ath10k *ar)
{
if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) {
ar->max_num_peers = TARGET_10X_NUM_PEERS;
ar->max_num_stations = TARGET_10X_NUM_STATIONS;
} else {
ar->max_num_peers = TARGET_NUM_PEERS;
ar->max_num_stations = TARGET_NUM_STATIONS;
}
}
int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode)
{
int status;
@@ -1035,6 +1046,8 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
return ret;
}
ath10k_core_init_max_sta_count(ar);
mutex_lock(&ar->conf_mutex);
ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL);
+11 -2
View File
@@ -79,10 +79,12 @@ static inline const char *ath10k_bus_str(enum ath10k_bus bus)
struct ath10k_skb_cb {
dma_addr_t paddr;
u8 eid;
u8 vdev_id;
struct {
u8 tid;
u16 freq;
bool is_offchan;
struct ath10k_htt_txbuf *txbuf;
u32 txbuf_paddr;
@@ -122,6 +124,7 @@ struct ath10k_wmi {
struct completion service_ready;
struct completion unified_ready;
wait_queue_head_t tx_credits_wq;
DECLARE_BITMAP(svc_map, WMI_SERVICE_MAX);
struct wmi_cmd_map *cmd;
struct wmi_vdev_param_map *vdev_param;
struct wmi_pdev_param_map *pdev_param;
@@ -218,6 +221,8 @@ struct ath10k_peer {
int vdev_id;
u8 addr[ETH_ALEN];
DECLARE_BITMAP(peer_ids, ATH10K_MAX_NUM_PEER_IDS);
/* protected by ar->data_lock */
struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1];
};
@@ -310,7 +315,6 @@ struct ath10k_debug {
struct ath10k_fw_stats fw_stats;
struct completion fw_stats_complete;
bool fw_stats_done;
DECLARE_BITMAP(wmi_service_bitmap, WMI_SERVICE_MAX);
unsigned long htt_stats_mask;
struct delayed_work htt_stats_dwork;
@@ -320,6 +324,7 @@ struct ath10k_debug {
/* protected by conf_mutex */
u32 fw_dbglog_mask;
u32 pktlog_filter;
u32 reg_addr;
u8 htt_max_amsdu;
u8 htt_max_ampdu;
@@ -560,8 +565,12 @@ struct ath10k {
struct list_head peers;
wait_queue_head_t peer_mapping_wq;
/* number of created peers; protected by data_lock */
/* protected by conf_mutex */
int num_peers;
int num_stations;
int max_num_peers;
int max_num_stations;
struct work_struct offchan_tx_work;
struct sk_buff_head offchan_tx_queue;
+248 -14
View File
@@ -17,9 +17,8 @@
#include <linux/module.h>
#include <linux/debugfs.h>
#include <linux/version.h>
#include <linux/vermagic.h>
#include <linux/vmalloc.h>
#include <linux/utsname.h>
#include "core.h"
#include "debug.h"
@@ -124,7 +123,7 @@ EXPORT_SYMBOL(ath10k_info);
void ath10k_print_driver_info(struct ath10k *ar)
{
ath10k_info(ar, "%s (0x%08x, 0x%08x) fw %s api %d htt %d.%d wmi %d.%d.%d.%d cal %s\n",
ath10k_info(ar, "%s (0x%08x, 0x%08x) fw %s api %d htt %d.%d wmi %d.%d.%d.%d cal %s max_sta %d\n",
ar->hw_params.name,
ar->target_version,
ar->chip_id,
@@ -136,7 +135,8 @@ void ath10k_print_driver_info(struct ath10k *ar)
ar->fw_version_minor,
ar->fw_version_release,
ar->fw_version_build,
ath10k_cal_mode_str(ar->cal_mode));
ath10k_cal_mode_str(ar->cal_mode),
ar->max_num_stations);
ath10k_info(ar, "debug %d debugfs %d tracing %d dfs %d testmode %d\n",
config_enabled(CONFIG_ATH10K_DEBUG),
config_enabled(CONFIG_ATH10K_DEBUGFS),
@@ -179,13 +179,6 @@ EXPORT_SYMBOL(ath10k_warn);
#ifdef CONFIG_ATH10K_DEBUGFS
void ath10k_debug_read_service_map(struct ath10k *ar,
const void *service_map,
size_t map_size)
{
memcpy(ar->debug.wmi_service_bitmap, service_map, map_size);
}
static ssize_t ath10k_read_wmi_services(struct file *file,
char __user *user_buf,
size_t count, loff_t *ppos)
@@ -207,8 +200,9 @@ static ssize_t ath10k_read_wmi_services(struct file *file,
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->debug.wmi_service_bitmap);
enabled = test_bit(i, ar->wmi.svc_map);
name = wmi_service_name(i);
if (!name) {
@@ -224,6 +218,7 @@ static ssize_t ath10k_read_wmi_services(struct file *file,
"%-40s %s\n",
name, enabled ? "enabled" : "-");
}
spin_unlock_bh(&ar->data_lock);
ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
@@ -866,8 +861,8 @@ static struct ath10k_dump_file_data *ath10k_build_dump_file(struct ath10k *ar)
strlcpy(dump_data->fw_ver, ar->hw->wiphy->fw_version,
sizeof(dump_data->fw_ver));
dump_data->kernel_ver_code = cpu_to_le32(LINUX_VERSION_CODE);
strlcpy(dump_data->kernel_ver, VERMAGIC_STRING,
dump_data->kernel_ver_code = 0;
strlcpy(dump_data->kernel_ver, init_utsname()->release,
sizeof(dump_data->kernel_ver));
dump_data->tv_sec = cpu_to_le64(crash_data->timestamp.tv_sec);
@@ -929,6 +924,236 @@ static const struct file_operations fops_fw_crash_dump = {
.llseek = default_llseek,
};
static ssize_t ath10k_reg_addr_read(struct file *file,
char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath10k *ar = file->private_data;
u8 buf[32];
unsigned int len = 0;
u32 reg_addr;
mutex_lock(&ar->conf_mutex);
reg_addr = ar->debug.reg_addr;
mutex_unlock(&ar->conf_mutex);
len += scnprintf(buf + len, sizeof(buf) - len, "0x%x\n", reg_addr);
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
}
static ssize_t ath10k_reg_addr_write(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath10k *ar = file->private_data;
u32 reg_addr;
int ret;
ret = kstrtou32_from_user(user_buf, count, 0, &reg_addr);
if (ret)
return ret;
if (!IS_ALIGNED(reg_addr, 4))
return -EFAULT;
mutex_lock(&ar->conf_mutex);
ar->debug.reg_addr = reg_addr;
mutex_unlock(&ar->conf_mutex);
return count;
}
static const struct file_operations fops_reg_addr = {
.read = ath10k_reg_addr_read,
.write = ath10k_reg_addr_write,
.open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
static ssize_t ath10k_reg_value_read(struct file *file,
char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath10k *ar = file->private_data;
u8 buf[48];
unsigned int len;
u32 reg_addr, reg_val;
int ret;
mutex_lock(&ar->conf_mutex);
if (ar->state != ATH10K_STATE_ON &&
ar->state != ATH10K_STATE_UTF) {
ret = -ENETDOWN;
goto exit;
}
reg_addr = ar->debug.reg_addr;
reg_val = ath10k_hif_read32(ar, reg_addr);
len = scnprintf(buf, sizeof(buf), "0x%08x:0x%08x\n", reg_addr, reg_val);
ret = simple_read_from_buffer(user_buf, count, ppos, buf, len);
exit:
mutex_unlock(&ar->conf_mutex);
return ret;
}
static ssize_t ath10k_reg_value_write(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath10k *ar = file->private_data;
u32 reg_addr, reg_val;
int ret;
mutex_lock(&ar->conf_mutex);
if (ar->state != ATH10K_STATE_ON &&
ar->state != ATH10K_STATE_UTF) {
ret = -ENETDOWN;
goto exit;
}
reg_addr = ar->debug.reg_addr;
ret = kstrtou32_from_user(user_buf, count, 0, &reg_val);
if (ret)
goto exit;
ath10k_hif_write32(ar, reg_addr, reg_val);
ret = count;
exit:
mutex_unlock(&ar->conf_mutex);
return ret;
}
static const struct file_operations fops_reg_value = {
.read = ath10k_reg_value_read,
.write = ath10k_reg_value_write,
.open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
static ssize_t ath10k_mem_value_read(struct file *file,
char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath10k *ar = file->private_data;
u8 *buf;
int ret;
if (*ppos < 0)
return -EINVAL;
if (!count)
return 0;
mutex_lock(&ar->conf_mutex);
buf = vmalloc(count);
if (!buf) {
ret = -ENOMEM;
goto exit;
}
if (ar->state != ATH10K_STATE_ON &&
ar->state != ATH10K_STATE_UTF) {
ret = -ENETDOWN;
goto exit;
}
ret = ath10k_hif_diag_read(ar, *ppos, buf, count);
if (ret) {
ath10k_warn(ar, "failed to read address 0x%08x via diagnose window fnrom debugfs: %d\n",
(u32)(*ppos), ret);
goto exit;
}
ret = copy_to_user(user_buf, buf, count);
if (ret) {
ret = -EFAULT;
goto exit;
}
count -= ret;
*ppos += count;
ret = count;
exit:
vfree(buf);
mutex_unlock(&ar->conf_mutex);
return ret;
}
static ssize_t ath10k_mem_value_write(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath10k *ar = file->private_data;
u8 *buf;
int ret;
if (*ppos < 0)
return -EINVAL;
if (!count)
return 0;
mutex_lock(&ar->conf_mutex);
buf = vmalloc(count);
if (!buf) {
ret = -ENOMEM;
goto exit;
}
if (ar->state != ATH10K_STATE_ON &&
ar->state != ATH10K_STATE_UTF) {
ret = -ENETDOWN;
goto exit;
}
ret = copy_from_user(buf, user_buf, count);
if (ret) {
ret = -EFAULT;
goto exit;
}
ret = ath10k_hif_diag_write(ar, *ppos, buf, count);
if (ret) {
ath10k_warn(ar, "failed to write address 0x%08x via diagnose window from debugfs: %d\n",
(u32)(*ppos), ret);
goto exit;
}
*ppos += count;
ret = count;
exit:
vfree(buf);
mutex_unlock(&ar->conf_mutex);
return ret;
}
static const struct file_operations fops_mem_value = {
.read = ath10k_mem_value_read,
.write = ath10k_mem_value_write,
.open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
static int ath10k_debug_htt_stats_req(struct ath10k *ar)
{
u64 cookie;
@@ -1630,6 +1855,15 @@ int ath10k_debug_register(struct ath10k *ar)
debugfs_create_file("fw_crash_dump", S_IRUSR, ar->debug.debugfs_phy,
ar, &fops_fw_crash_dump);
debugfs_create_file("reg_addr", S_IRUSR | S_IWUSR,
ar->debug.debugfs_phy, ar, &fops_reg_addr);
debugfs_create_file("reg_value", S_IRUSR | S_IWUSR,
ar->debug.debugfs_phy, ar, &fops_reg_value);
debugfs_create_file("mem_value", S_IRUSR | S_IWUSR,
ar->debug.debugfs_phy, ar, &fops_mem_value);
debugfs_create_file("chip_id", S_IRUSR, ar->debug.debugfs_phy,
ar, &fops_chip_id);
+1 -9
View File
@@ -35,6 +35,7 @@ enum ath10k_debug_mask {
ATH10K_DBG_BMI = 0x00000400,
ATH10K_DBG_REGULATORY = 0x00000800,
ATH10K_DBG_TESTMODE = 0x00001000,
ATH10K_DBG_WMI_PRINT = 0x00002000,
ATH10K_DBG_ANY = 0xffffffff,
};
@@ -61,9 +62,6 @@ int ath10k_debug_create(struct ath10k *ar);
void ath10k_debug_destroy(struct ath10k *ar);
int ath10k_debug_register(struct ath10k *ar);
void ath10k_debug_unregister(struct ath10k *ar);
void ath10k_debug_read_service_map(struct ath10k *ar,
const void *service_map,
size_t map_size);
void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb);
struct ath10k_fw_crash_data *
ath10k_debug_get_new_fw_crash_data(struct ath10k *ar);
@@ -108,12 +106,6 @@ static inline void ath10k_debug_unregister(struct ath10k *ar)
{
}
static inline void ath10k_debug_read_service_map(struct ath10k *ar,
const void *service_map,
size_t map_size)
{
}
static inline void ath10k_debug_fw_stats_process(struct ath10k *ar,
struct sk_buff *skb)
{
+39 -4
View File
@@ -20,6 +20,7 @@
#include <linux/kernel.h>
#include "core.h"
#include "debug.h"
struct ath10k_hif_sg_item {
u16 transfer_id;
@@ -31,11 +32,9 @@ struct ath10k_hif_sg_item {
struct ath10k_hif_cb {
int (*tx_completion)(struct ath10k *ar,
struct sk_buff *wbuf,
unsigned transfer_id);
struct sk_buff *wbuf);
int (*rx_completion)(struct ath10k *ar,
struct sk_buff *wbuf,
u8 pipe_id);
struct sk_buff *wbuf);
};
struct ath10k_hif_ops {
@@ -47,6 +46,8 @@ struct ath10k_hif_ops {
int (*diag_read)(struct ath10k *ar, u32 address, void *buf,
size_t buf_len);
int (*diag_write)(struct ath10k *ar, u32 address, const void *data,
int nbytes);
/*
* API to handle HIF-specific BMI message exchanges, this API is
* synchronous and only allowed to be called from a context that
@@ -84,6 +85,10 @@ struct ath10k_hif_ops {
u16 (*get_free_queue_number)(struct ath10k *ar, u8 pipe_id);
u32 (*read32)(struct ath10k *ar, u32 address);
void (*write32)(struct ath10k *ar, u32 address, u32 value);
/* Power up the device and enter BMI transfer mode for FW download */
int (*power_up)(struct ath10k *ar);
@@ -108,6 +113,15 @@ static inline int ath10k_hif_diag_read(struct ath10k *ar, u32 address, void *buf
return ar->hif.ops->diag_read(ar, address, buf, buf_len);
}
static inline int ath10k_hif_diag_write(struct ath10k *ar, u32 address,
const void *data, int nbytes)
{
if (!ar->hif.ops->diag_write)
return -EOPNOTSUPP;
return ar->hif.ops->diag_write(ar, address, data, nbytes);
}
static inline int ath10k_hif_exchange_bmi_msg(struct ath10k *ar,
void *request, u32 request_len,
void *response, u32 *response_len)
@@ -187,4 +201,25 @@ static inline int ath10k_hif_resume(struct ath10k *ar)
return ar->hif.ops->resume(ar);
}
static inline u32 ath10k_hif_read32(struct ath10k *ar, u32 address)
{
if (!ar->hif.ops->read32) {
ath10k_warn(ar, "hif read32 not supported\n");
return 0xdeaddead;
}
return ar->hif.ops->read32(ar, address);
}
static inline void ath10k_hif_write32(struct ath10k *ar,
u32 address, u32 data)
{
if (!ar->hif.ops->write32) {
ath10k_warn(ar, "hif write32 not supported\n");
return;
}
ar->hif.ops->write32(ar, address, data);
}
#endif /* _HIF_H_ */
+8 -5
View File
@@ -160,6 +160,7 @@ int ath10k_htc_send(struct ath10k_htc *htc,
ath10k_htc_prepare_tx_skb(ep, skb);
skb_cb->eid = eid;
skb_cb->paddr = dma_map_single(dev, skb->data, skb->len, DMA_TO_DEVICE);
ret = dma_mapping_error(dev, skb_cb->paddr);
if (ret)
@@ -197,15 +198,18 @@ err_pull:
}
static int ath10k_htc_tx_completion_handler(struct ath10k *ar,
struct sk_buff *skb,
unsigned int eid)
struct sk_buff *skb)
{
struct ath10k_htc *htc = &ar->htc;
struct ath10k_htc_ep *ep = &htc->endpoint[eid];
struct ath10k_skb_cb *skb_cb;
struct ath10k_htc_ep *ep;
if (WARN_ON_ONCE(!skb))
return 0;
skb_cb = ATH10K_SKB_CB(skb);
ep = &htc->endpoint[skb_cb->eid];
ath10k_htc_notify_tx_completion(ep, skb);
/* the skb now belongs to the completion handler */
@@ -317,8 +321,7 @@ static int ath10k_htc_process_trailer(struct ath10k_htc *htc,
}
static int ath10k_htc_rx_completion_handler(struct ath10k *ar,
struct sk_buff *skb,
u8 pipe_id)
struct sk_buff *skb)
{
int status = 0;
struct ath10k_htc *htc = &ar->htc;
+6 -1
View File
@@ -126,6 +126,7 @@ enum htt_data_tx_ext_tid {
* (HL hosts manage queues on the host )
* more_in_batch: only for HL hosts. indicates if more packets are
* pending. this allows target to wait and aggregate
* freq: 0 means home channel of given vdev. intended for offchannel
*/
struct htt_data_tx_desc {
u8 flags0; /* %HTT_DATA_TX_DESC_FLAGS0_ */
@@ -133,7 +134,8 @@ struct htt_data_tx_desc {
__le16 len;
__le16 id;
__le32 frags_paddr;
__le32 peerid;
__le16 peerid;
__le16 freq;
u8 prefetch[0]; /* start of frame, for FW classification engine */
} __packed;
@@ -156,6 +158,9 @@ enum htt_rx_ring_flags {
HTT_RX_RING_FLAGS_PHY_DATA_RX = 1 << 15
};
#define HTT_RX_RING_SIZE_MIN 128
#define HTT_RX_RING_SIZE_MAX 2048
struct htt_rx_ring_setup_ring {
__le32 fw_idx_shadow_reg_paddr;
__le32 rx_ring_base_paddr;
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More