SCO packet reassembler may have a fragment of SCO packet, from
previous connection, cached and not removed when SCO connection
is ended. Packets from new SCO connection are then going to be
attached to that fragment, creating an invalid SCO packets.
Controllers like Intel's WilkinsPeak are always fragmenting
SCO packet into 3 parts (#1, #2, #3). Packet #1 contains
SCO header and audio data, others just audio data. if there is
a fragment cached from previous connection, i.e. #1, first
SCO packet from new connection is going to be attached to it
creating packet consisting of fragments #1-#1-#2. This will
be forwarded to upper layers. After that, fragment #3 is going
to be used as a starting point for another SCO packet.
It does not contain a SCO header, but the code expects it,
casts a SCO header structure on it, and reads whatever audio
data happens to be there as SCO packet length and handle.
From that point on, we are assembling random data into SCO
packets. Usually it recovers quickly as initial audio data
contains mostly zeros (muted stream), but setups of over
4 seconds were observed.
Issue manifests itself by printing on the console:
Bluetooth: hci0 SCO packet for unknown connection handle 48
Bluetooth: hci0 SCO packet for unknown connection handle 2560
Bluetooth: hci0 SCO packet for unknown connection handle 12288
It may also show random handles if audio data was non-zeroed.
Hcidump shows SCO packets with random length and handles.
Few messages with handle 0 at connection creation are OK
for some controllers (like WilkinsPeak), as there are SCO packets
with zeroed handle at the beginning (possible controller bug).
Few of such messages at connection end, with a handle looking
sane (around 256, 512, 768 ...) is also OK, as these are last
SCO packets that were assembled and sent up, before connection
was ended, but were not handled in time.
This issue may still manifest itself on WilkinsPeak as it sometimes,
at SCO connection creation, does not send third fragment of first
SCO packet (#1-#2-#1-#2-#3...). This is a firmware bug and this
patch does not address it.
Signed-off-by: Kuba Pawlak <kubax.t.pawlak@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
We need to explicitly enable the IRQ wakeup mode to let the controller
wake the system from sleep states (like suspend-to-ram).
PM suspend/resume callbacks now call the generic intel device PM
functions after enabling/disabling IRQ wake.
Signed-off-by: Loic Poulain <loic.poulain@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Change the way to insert LPM packets into the txq.
Use skb_queue_head instead of skb_queue_tail to always prioritise LPM
packets over potential tx queue content.
Signed-off-by: Loic Poulain <loic.poulain@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Retrieve the Interruption used by BCM device, which can be declared
as Interruption or GpioInt in the ACPI table.
Retrieve IRQ polarity from the ACPI table to use it for host_wake_active
parameter of Setup Sleep vendor specific command.
Configure BCM device to wake-up the host.
Enable IRQ wake while suspended.
Signed-off-by: Frederic Danis <frederic.danis@linux.intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
btintel_load_ddc_config retrieves the ddc file and sends its content
via DDC commands (opcode 0xfc8b).
The ddc file should contain one or more DDC structures.
A DDC structure is composed of the folowing fields:
field: | DDC LEN | DDC ID | DDC VALUE |
size: | 1 byte | 2 bytes | DDC LEN - 2 |
Signed-off-by: Loic Poulain <loic.poulain@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
intel_lpm_suspend/resume are only used in case of CONFIG_PM.
Signed-off-by: Loic Poulain <loic.poulain@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
if btmrvl_tx_pkt() is called, and the branch
if (skb_headroom(skb) < BTM_HEADER_LEN)
evaluates positive, a new skb is allocated via skb_realloc_headroom.
The original skb is stored in a tmp variable, before being free'd.
However on success, the new skb, is not free'd, nor is it
returned to the caller which will then double-free the original skb.
This issue exists from the original driver submission in
commit: #132ff4e5fa8dfb71a7d99902f88043113947e972
If this code path had been alive, it would have been noted from the
double-free causing a panic.
All skb's here should be allocated through bt_skb_alloc which
adds 8 bytes as headroom, which is plenty against the 4 bytes
pushed on by this driver.
This code path is dead, and buggy at the same time, so the cleanest
approach is to remove the affected branch.
Reported by coverity (CID 113422)
Signed-off-by: Kieran Bingham <kieranbingham@gmail.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Implement runtime PM suspend/resume callbacks.
If LPM supported, controller is put into supsend after a delay of
inactivity (1s). Inactivity is based on LPM idle notification and
host TX traffic.
Signed-off-by: Loic Poulain <loic.poulain@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Add PM suspend/resume callbacks which call lpm_suspend/resume.
Add LPM ack in threaded IRQ handler to notify the controller that
resume is complete.
Protect hci_uart against concurrent removing during suspend/resume.
Signed-off-by: Loic Poulain <loic.poulain@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Add LPM PM suspend/resume/host_wake LPM functions.
A LPM transaction is composed with a LPM request and ack/response.
Host can send a LPM suspend/resume request to the controller which
should respond with a LPM ack.
If resume is requested by the controller (irq), host has to send a LPM
ack once resumed.
Signed-off-by: Loic Poulain <loic.poulain@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Replace spinlock by mutex to be able to use bcm_device_lock in
sleepable context like devm_request_threaded_irq or upcomming PM support.
Signed-off-by: Frederic Danis <frederic.danis@linux.intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Replace the device_intel list spinlock with a mutex.
devm_request_threaded_irq is not atomic and upcomming PM support should
be simpler.
Signed-off-by: Loic Poulain <loic.poulain@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Enable controller Low-Power-Mode if we have a pdev to manage host
wake-up. Once LPM is enabled, controller notifies its TX status via
a vendor specific packet (tx_idle/tx_active).
tx_active means that there is more data upcoming from controller.
tx_idle means that controller can be put in suspended state.
Signed-off-by: Loic Poulain <loic.poulain@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
An IRQ can be retrieved from the pdev resources. This irq will be used
in case of LPM suspend mode to wake-up the host and resume the link.
This resource can be declared as a GPIO-Interrupt which requires to be
converted into IRQ.
Signed-off-by: Loic Poulain <loic.poulain@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
If bcm_suspend is called whithout device opened there is a crash as
it tries to use bdev->hu which is NULL.
Rename bcm_device_list_lock to bcm_device_lock as it does not only apply
to bcm_device_list.
Signed-off-by: Frederic Danis <frederic.danis@linux.intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>