Skip to content

Commit

Permalink
Bluetooth: btmrvl add firmware dump support
Browse files Browse the repository at this point in the history
This patch adds firmware dump support for marvell
bluetooth chipset. Currently only SD8897 is supported.
This is implemented based on dev_coredump, a new mechnism
introduced in kernel 3.18rc3

Firmware dump can be trigger by
echo 1 > /sys/kernel/debug/bluetooth/hci*/config/fw_dump
and when the dump operation is completed, data can be read by
cat /sys/class/devcoredump/devcd*/data

We have prepared following script to divide fw memory
dump data into multiple files based on memory type.

 [root]# cat btmrvl_split_dump_data.sh
 #!/bin/bash
 # usage: ./btmrvl_split_dump_data.sh dump_data

 fw_dump_data=$1

 mem_type="ITCM DTCM SQRAM APU CIU ICU MAC EXT7 EXT8 EXT9 EXT10 EXT11 EXT12 EXT13 EXTLAST"

 for name in ${mem_type[@]}
 do
         sed -n "/Start dump $name/,/End dump/p" $fw_dump_data  > tmp.$name.log
         if [ ! -s tmp.$name.log ]
                 then
                         rm -rf tmp.$name.log
                 else
                         # Remove the describle info "Start dump" and "End dump"
                         sed '1d' tmp.$name.log | sed '$d' > /data/$name.log
                         if [ -s /data/$name.log ]
                         then
                                 echo "generate /data/$name.log"
                         else
                                 sed '1d' tmp.$name.log | sed '$d' > /var/$name.log
                                 echo "generate /var/$name.log"
                         fi
                         rm -rf tmp.$name.log
         fi
 done

Signed-off-by: Xinming Hu <[email protected]>
Signed-off-by: Cathy Luo <[email protected]>
Signed-off-by: Avinash Patil <[email protected]>
Reviewed-by: Johannes Berg <[email protected]>
Reviewed-by: Marcel Holtmann <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
Signed-off-by: Marcel Holtmann <[email protected]>
  • Loading branch information
Xinming Hu authored and holtmann committed Dec 3, 2014
1 parent 7365d47 commit dc75961
Show file tree
Hide file tree
Showing 6 changed files with 364 additions and 0 deletions.
1 change: 1 addition & 0 deletions drivers/bluetooth/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
31 changes: 31 additions & 0 deletions drivers/bluetooth/btmrvl_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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,
Expand Down
20 changes: 20 additions & 0 deletions drivers/bluetooth/btmrvl_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
7 changes: 7 additions & 0 deletions drivers/bluetooth/btmrvl_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -335,6 +336,12 @@ int btmrvl_prepare_command(struct btmrvl_private *priv)
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;
Expand Down
Loading

0 comments on commit dc75961

Please sign in to comment.