Commit c037874c authored by Amitkumar Karwar's avatar Amitkumar Karwar Committed by Marcel Holtmann

Bluetooth: btmrvl: add btmrvl_send_sync_cmd() function

Command preparation code is used multiple times. This patch
separate out this common code and create btmrvl_send_sync_cmd()
function.
Signed-off-by: default avatarAmitkumar Karwar <akarwar@marvell.com>
Signed-off-by: default avatarBing Zhao <bzhao@marvell.com>
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent e1d08f40
...@@ -57,8 +57,7 @@ bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb) ...@@ -57,8 +57,7 @@ bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb)
ocf = hci_opcode_ocf(opcode); ocf = hci_opcode_ocf(opcode);
ogf = hci_opcode_ogf(opcode); ogf = hci_opcode_ogf(opcode);
if (ocf == BT_CMD_MODULE_CFG_REQ && if (priv->btmrvl_dev.sendcmdflag) {
priv->btmrvl_dev.sendcmdflag) {
priv->btmrvl_dev.sendcmdflag = false; priv->btmrvl_dev.sendcmdflag = false;
priv->adapter->cmd_complete = true; priv->adapter->cmd_complete = true;
wake_up_interruptible(&priv->adapter->cmd_wait_q); wake_up_interruptible(&priv->adapter->cmd_wait_q);
...@@ -116,7 +115,6 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb) ...@@ -116,7 +115,6 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb)
adapter->hs_state = HS_ACTIVATED; adapter->hs_state = HS_ACTIVATED;
if (adapter->psmode) if (adapter->psmode)
adapter->ps_state = PS_SLEEP; adapter->ps_state = PS_SLEEP;
wake_up_interruptible(&adapter->cmd_wait_q);
BT_DBG("HS ACTIVATED!"); BT_DBG("HS ACTIVATED!");
} else { } else {
BT_DBG("HS Enable failed"); BT_DBG("HS Enable failed");
...@@ -168,11 +166,11 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb) ...@@ -168,11 +166,11 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb)
} }
EXPORT_SYMBOL_GPL(btmrvl_process_event); EXPORT_SYMBOL_GPL(btmrvl_process_event);
int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd) static int btmrvl_send_sync_cmd(struct btmrvl_private *priv, u16 cmd_no,
const void *param, u8 len)
{ {
struct sk_buff *skb; struct sk_buff *skb;
struct btmrvl_cmd *cmd; struct btmrvl_cmd *cmd;
int ret = 0;
skb = bt_skb_alloc(sizeof(*cmd), GFP_ATOMIC); skb = bt_skb_alloc(sizeof(*cmd), GFP_ATOMIC);
if (skb == NULL) { if (skb == NULL) {
...@@ -181,9 +179,11 @@ int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd) ...@@ -181,9 +179,11 @@ int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd)
} }
cmd = (struct btmrvl_cmd *) skb_put(skb, sizeof(*cmd)); cmd = (struct btmrvl_cmd *) skb_put(skb, sizeof(*cmd));
cmd->ocf_ogf = cpu_to_le16(hci_opcode_pack(OGF, BT_CMD_MODULE_CFG_REQ)); cmd->ocf_ogf = cpu_to_le16(hci_opcode_pack(OGF, cmd_no));
cmd->length = 1; cmd->length = len;
cmd->data[0] = subcmd;
if (len)
memcpy(cmd->data, param, len);
bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT; bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT;
...@@ -194,19 +194,23 @@ int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd) ...@@ -194,19 +194,23 @@ int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd)
priv->adapter->cmd_complete = false; priv->adapter->cmd_complete = false;
BT_DBG("Queue module cfg Command");
wake_up_interruptible(&priv->main_thread.wait_q); wake_up_interruptible(&priv->main_thread.wait_q);
if (!wait_event_interruptible_timeout(priv->adapter->cmd_wait_q, if (!wait_event_interruptible_timeout(priv->adapter->cmd_wait_q,
priv->adapter->cmd_complete, priv->adapter->cmd_complete,
msecs_to_jiffies(WAIT_UNTIL_CMD_RESP))) { msecs_to_jiffies(WAIT_UNTIL_CMD_RESP)))
ret = -ETIMEDOUT; return -ETIMEDOUT;
BT_ERR("module_cfg_cmd(%x): timeout: %d",
subcmd, priv->btmrvl_dev.sendcmdflag);
}
BT_DBG("module cfg Command done"); return 0;
}
int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd)
{
int ret;
ret = btmrvl_send_sync_cmd(priv, BT_CMD_MODULE_CFG_REQ, &subcmd, 1);
if (ret)
BT_ERR("module_cfg_cmd(%x) failed\n", subcmd);
return ret; return ret;
} }
...@@ -214,61 +218,36 @@ EXPORT_SYMBOL_GPL(btmrvl_send_module_cfg_cmd); ...@@ -214,61 +218,36 @@ EXPORT_SYMBOL_GPL(btmrvl_send_module_cfg_cmd);
int btmrvl_send_hscfg_cmd(struct btmrvl_private *priv) int btmrvl_send_hscfg_cmd(struct btmrvl_private *priv)
{ {
struct sk_buff *skb; int ret;
struct btmrvl_cmd *cmd; u8 param[2];
skb = bt_skb_alloc(sizeof(*cmd), GFP_ATOMIC);
if (!skb) {
BT_ERR("No free skb");
return -ENOMEM;
}
cmd = (struct btmrvl_cmd *) skb_put(skb, sizeof(*cmd));
cmd->ocf_ogf = cpu_to_le16(hci_opcode_pack(OGF,
BT_CMD_HOST_SLEEP_CONFIG));
cmd->length = 2;
cmd->data[0] = (priv->btmrvl_dev.gpio_gap & 0xff00) >> 8;
cmd->data[1] = (u8) (priv->btmrvl_dev.gpio_gap & 0x00ff);
bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT; param[0] = (priv->btmrvl_dev.gpio_gap & 0xff00) >> 8;
param[1] = (u8) (priv->btmrvl_dev.gpio_gap & 0x00ff);
skb->dev = (void *) priv->btmrvl_dev.hcidev; BT_DBG("Sending HSCFG Command, gpio=0x%x, gap=0x%x",
skb_queue_head(&priv->adapter->tx_queue, skb); param[0], param[1]);
BT_DBG("Queue HSCFG Command, gpio=0x%x, gap=0x%x", cmd->data[0], ret = btmrvl_send_sync_cmd(priv, BT_CMD_HOST_SLEEP_CONFIG, param, 2);
cmd->data[1]); if (ret)
BT_ERR("HSCFG command failed\n");
return 0; return ret;
} }
EXPORT_SYMBOL_GPL(btmrvl_send_hscfg_cmd); EXPORT_SYMBOL_GPL(btmrvl_send_hscfg_cmd);
int btmrvl_enable_ps(struct btmrvl_private *priv) int btmrvl_enable_ps(struct btmrvl_private *priv)
{ {
struct sk_buff *skb; int ret;
struct btmrvl_cmd *cmd; u8 param;
skb = bt_skb_alloc(sizeof(*cmd), GFP_ATOMIC);
if (skb == NULL) {
BT_ERR("No free skb");
return -ENOMEM;
}
cmd = (struct btmrvl_cmd *) skb_put(skb, sizeof(*cmd));
cmd->ocf_ogf = cpu_to_le16(hci_opcode_pack(OGF,
BT_CMD_AUTO_SLEEP_MODE));
cmd->length = 1;
if (priv->btmrvl_dev.psmode) if (priv->btmrvl_dev.psmode)
cmd->data[0] = BT_PS_ENABLE; param = BT_PS_ENABLE;
else else
cmd->data[0] = BT_PS_DISABLE; param = BT_PS_DISABLE;
bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT;
skb->dev = (void *) priv->btmrvl_dev.hcidev;
skb_queue_head(&priv->adapter->tx_queue, skb);
BT_DBG("Queue PSMODE Command:%d", cmd->data[0]); ret = btmrvl_send_sync_cmd(priv, BT_CMD_AUTO_SLEEP_MODE, &param, 1);
if (ret)
BT_ERR("PSMODE command failed\n");
return 0; return 0;
} }
...@@ -276,37 +255,11 @@ EXPORT_SYMBOL_GPL(btmrvl_enable_ps); ...@@ -276,37 +255,11 @@ EXPORT_SYMBOL_GPL(btmrvl_enable_ps);
int btmrvl_enable_hs(struct btmrvl_private *priv) int btmrvl_enable_hs(struct btmrvl_private *priv)
{ {
struct sk_buff *skb; int ret;
struct btmrvl_cmd *cmd;
int ret = 0;
skb = bt_skb_alloc(sizeof(*cmd), GFP_ATOMIC);
if (skb == NULL) {
BT_ERR("No free skb");
return -ENOMEM;
}
cmd = (struct btmrvl_cmd *) skb_put(skb, sizeof(*cmd));
cmd->ocf_ogf = cpu_to_le16(hci_opcode_pack(OGF, BT_CMD_HOST_SLEEP_ENABLE));
cmd->length = 0;
bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT;
skb->dev = (void *) priv->btmrvl_dev.hcidev;
skb_queue_head(&priv->adapter->tx_queue, skb);
BT_DBG("Queue hs enable Command");
wake_up_interruptible(&priv->main_thread.wait_q);
if (!wait_event_interruptible_timeout(priv->adapter->cmd_wait_q, ret = btmrvl_send_sync_cmd(priv, BT_CMD_HOST_SLEEP_ENABLE, NULL, 0);
priv->adapter->hs_state, if (ret)
msecs_to_jiffies(WAIT_UNTIL_HS_STATE_CHANGED))) { BT_ERR("Host sleep enable command failed\n");
ret = -ETIMEDOUT;
BT_ERR("timeout: %d, %d,%d", priv->adapter->hs_state,
priv->adapter->ps_state,
priv->adapter->wakeup_tries);
}
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment