Commit ea1e76a3 authored by Andrei Emeltchenko's avatar Andrei Emeltchenko Committed by Gustavo Padovan

Bluetooth: btmrvl: Do not send vendor events to bluetooth stack

Vendor-specific events shall be processed in driver and not sent
to bluetooth stack where they screw up HCI command countings.
Signed-off-by: default avatarAndrei Emeltchenko <andrei.emeltchenko@intel.com>
Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
parent f960727e
...@@ -136,7 +136,7 @@ int btmrvl_remove_card(struct btmrvl_private *priv); ...@@ -136,7 +136,7 @@ int btmrvl_remove_card(struct btmrvl_private *priv);
void btmrvl_interrupt(struct btmrvl_private *priv); void btmrvl_interrupt(struct btmrvl_private *priv);
void btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb); bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb);
int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb); int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb);
int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd); int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd);
......
...@@ -44,23 +44,33 @@ void btmrvl_interrupt(struct btmrvl_private *priv) ...@@ -44,23 +44,33 @@ void btmrvl_interrupt(struct btmrvl_private *priv)
} }
EXPORT_SYMBOL_GPL(btmrvl_interrupt); EXPORT_SYMBOL_GPL(btmrvl_interrupt);
void btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb) bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb)
{ {
struct hci_event_hdr *hdr = (void *) skb->data; struct hci_event_hdr *hdr = (void *) skb->data;
struct hci_ev_cmd_complete *ec; struct hci_ev_cmd_complete *ec;
u16 opcode, ocf; u16 opcode, ocf, ogf;
if (hdr->evt == HCI_EV_CMD_COMPLETE) { if (hdr->evt == HCI_EV_CMD_COMPLETE) {
ec = (void *) (skb->data + HCI_EVENT_HDR_SIZE); ec = (void *) (skb->data + HCI_EVENT_HDR_SIZE);
opcode = __le16_to_cpu(ec->opcode); opcode = __le16_to_cpu(ec->opcode);
ocf = hci_opcode_ocf(opcode); ocf = hci_opcode_ocf(opcode);
ogf = hci_opcode_ogf(opcode);
if (ocf == BT_CMD_MODULE_CFG_REQ && if (ocf == BT_CMD_MODULE_CFG_REQ &&
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);
} }
if (ogf == OGF) {
BT_DBG("vendor event skipped: ogf 0x%4.4x", ogf);
kfree_skb(skb);
return false;
}
} }
return true;
} }
EXPORT_SYMBOL_GPL(btmrvl_check_evtpkt); EXPORT_SYMBOL_GPL(btmrvl_check_evtpkt);
......
...@@ -562,10 +562,12 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv) ...@@ -562,10 +562,12 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv)
skb_put(skb, buf_len); skb_put(skb, buf_len);
skb_pull(skb, SDIO_HEADER_LEN); skb_pull(skb, SDIO_HEADER_LEN);
if (type == HCI_EVENT_PKT) if (type == HCI_EVENT_PKT) {
btmrvl_check_evtpkt(priv, skb); if (btmrvl_check_evtpkt(priv, skb))
hci_recv_frame(skb);
} else
hci_recv_frame(skb);
hci_recv_frame(skb);
hdev->stat.byte_rx += buf_len; hdev->stat.byte_rx += buf_len;
break; break;
......
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