Skip to content

Commit fd21793

Browse files
committed
Merge branch 'bits/100-bluetooth' into asahi-wip
2 parents a2caec7 + 3ca6bca commit fd21793

3 files changed

Lines changed: 72 additions & 15 deletions

File tree

drivers/bluetooth/hci_bcm4377.c

Lines changed: 54 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,16 @@ enum bcm4377_chip {
2626
BCM4377 = 0,
2727
BCM4378,
2828
BCM4387,
29+
BCM4388,
2930
};
3031

3132
#define BCM4377_DEVICE_ID 0x5fa0
3233
#define BCM4378_DEVICE_ID 0x5f69
3334
#define BCM4387_DEVICE_ID 0x5f71
35+
#define BCM4388_DEVICE_ID 0x5f72
3436

35-
#define BCM4377_TIMEOUT 1000
37+
#define BCM4377_TIMEOUT msecs_to_jiffies(1000)
38+
#define BCM4377_BOOT_TIMEOUT msecs_to_jiffies(5000)
3639

3740
/*
3841
* These devices only support DMA transactions inside a 32bit window
@@ -495,6 +498,10 @@ struct bcm4377_data;
495498
* extended scanning
496499
* broken_mws_transport_config: Set to true if the chip erroneously claims to
497500
* support MWS Transport Configuration
501+
* broken_le_ext_adv_report_phy: Set to true if this chip stuffs flags inside
502+
* reserved bits of Primary/Secondary_PHY inside
503+
* LE Extended Advertising Report events which
504+
* have to be ignored
498505
* send_calibration: Optional callback to send calibration data
499506
* send_ptb: Callback to send "PTB" regulatory/calibration data
500507
*/
@@ -506,13 +513,15 @@ struct bcm4377_hw {
506513
u32 bar0_window1;
507514
u32 bar0_window2;
508515
u32 bar0_core2_window2;
516+
u32 bar2_offset;
509517

510518
unsigned long has_bar0_core2_window2 : 1;
511519
unsigned long clear_pciecfg_subsystem_ctrl_bit19 : 1;
512520
unsigned long disable_aspm : 1;
513521
unsigned long broken_ext_scan : 1;
514522
unsigned long broken_mws_transport_config : 1;
515523
unsigned long broken_le_coded : 1;
524+
unsigned long broken_le_ext_adv_report_phy : 1;
516525

517526
int (*send_calibration)(struct bcm4377_data *bcm4377);
518527
int (*send_ptb)(struct bcm4377_data *bcm4377,
@@ -716,7 +725,7 @@ static void bcm4377_handle_ack(struct bcm4377_data *bcm4377,
716725
ring->events[msgid] = NULL;
717726
}
718727

719-
bitmap_release_region(ring->msgids, msgid, ring->n_entries);
728+
bitmap_release_region(ring->msgids, msgid, 0);
720729

721730
unlock:
722731
spin_unlock_irqrestore(&ring->lock, flags);
@@ -830,8 +839,8 @@ static irqreturn_t bcm4377_irq(int irq, void *data)
830839
struct bcm4377_data *bcm4377 = data;
831840
u32 bootstage, rti_status;
832841

833-
bootstage = ioread32(bcm4377->bar2 + BCM4377_BAR2_BOOTSTAGE);
834-
rti_status = ioread32(bcm4377->bar2 + BCM4377_BAR2_RTI_STATUS);
842+
bootstage = ioread32(bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_BOOTSTAGE);
843+
rti_status = ioread32(bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_RTI_STATUS);
835844

836845
if (bootstage != bcm4377->bootstage ||
837846
rti_status != bcm4377->rti_status) {
@@ -1191,6 +1200,14 @@ static int bcm4387_send_calibration(struct bcm4377_data *bcm4377)
11911200
bcm4377->taurus_cal_size);
11921201
}
11931202

1203+
static int bcm4388_send_calibration(struct bcm4377_data *bcm4377)
1204+
{
1205+
/* Guess that these always use beamforming */
1206+
return __bcm4378_send_calibration(
1207+
bcm4377, bcm4377->taurus_beamforming_cal_blob,
1208+
bcm4377->taurus_beamforming_cal_size);
1209+
}
1210+
11941211
static const struct firmware *bcm4377_request_blob(struct bcm4377_data *bcm4377,
11951212
const char *suffix)
11961213
{
@@ -1814,8 +1831,8 @@ static int bcm4377_boot(struct bcm4377_data *bcm4377)
18141831
int ret = 0;
18151832
u32 bootstage, rti_status;
18161833

1817-
bootstage = ioread32(bcm4377->bar2 + BCM4377_BAR2_BOOTSTAGE);
1818-
rti_status = ioread32(bcm4377->bar2 + BCM4377_BAR2_RTI_STATUS);
1834+
bootstage = ioread32(bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_BOOTSTAGE);
1835+
rti_status = ioread32(bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_RTI_STATUS);
18191836

18201837
if (bootstage != 0) {
18211838
dev_err(&bcm4377->pdev->dev, "bootstage is %d and not 0\n",
@@ -1849,15 +1866,18 @@ static int bcm4377_boot(struct bcm4377_data *bcm4377)
18491866
iowrite32(BCM4377_DMA_MASK,
18501867
bcm4377->bar0 + BCM4377_BAR0_HOST_WINDOW_SIZE);
18511868

1852-
iowrite32(lower_32_bits(fw_dma), bcm4377->bar2 + BCM4377_BAR2_FW_LO);
1853-
iowrite32(upper_32_bits(fw_dma), bcm4377->bar2 + BCM4377_BAR2_FW_HI);
1854-
iowrite32(fw->size, bcm4377->bar2 + BCM4377_BAR2_FW_SIZE);
1869+
iowrite32(lower_32_bits(fw_dma),
1870+
bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_FW_LO);
1871+
iowrite32(upper_32_bits(fw_dma),
1872+
bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_FW_HI);
1873+
iowrite32(fw->size,
1874+
bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_FW_SIZE);
18551875
iowrite32(0, bcm4377->bar0 + BCM4377_BAR0_FW_DOORBELL);
18561876

18571877
dev_dbg(&bcm4377->pdev->dev, "waiting for firmware to boot\n");
18581878

18591879
ret = wait_for_completion_interruptible_timeout(&bcm4377->event,
1860-
BCM4377_TIMEOUT);
1880+
BCM4377_BOOT_TIMEOUT);
18611881
if (ret == 0) {
18621882
ret = -ETIMEDOUT;
18631883
goto out_dma_free;
@@ -1908,16 +1928,16 @@ static int bcm4377_setup_rti(struct bcm4377_data *bcm4377)
19081928
dev_dbg(&bcm4377->pdev->dev, "RTI is in state 1\n");
19091929

19101930
/* allow access to the entire IOVA space again */
1911-
iowrite32(0, bcm4377->bar2 + BCM4377_BAR2_RTI_WINDOW_LO);
1912-
iowrite32(0, bcm4377->bar2 + BCM4377_BAR2_RTI_WINDOW_HI);
1931+
iowrite32(0, bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_RTI_WINDOW_LO);
1932+
iowrite32(0, bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_RTI_WINDOW_HI);
19131933
iowrite32(BCM4377_DMA_MASK,
1914-
bcm4377->bar2 + BCM4377_BAR2_RTI_WINDOW_SIZE);
1934+
bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_RTI_WINDOW_SIZE);
19151935

19161936
/* setup "Converged IPC" context */
19171937
iowrite32(lower_32_bits(bcm4377->ctx_dma),
1918-
bcm4377->bar2 + BCM4377_BAR2_CONTEXT_ADDR_LO);
1938+
bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_CONTEXT_ADDR_LO);
19191939
iowrite32(upper_32_bits(bcm4377->ctx_dma),
1920-
bcm4377->bar2 + BCM4377_BAR2_CONTEXT_ADDR_HI);
1940+
bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_CONTEXT_ADDR_HI);
19211941
iowrite32(2, bcm4377->bar0 + BCM4377_BAR0_RTI_CONTROL);
19221942

19231943
ret = wait_for_completion_interruptible_timeout(&bcm4377->event,
@@ -2373,6 +2393,8 @@ static int bcm4377_probe(struct pci_dev *pdev, const struct pci_device_id *id)
23732393
set_bit(HCI_QUIRK_BROKEN_EXT_SCAN, &hdev->quirks);
23742394
if (bcm4377->hw->broken_le_coded)
23752395
set_bit(HCI_QUIRK_BROKEN_LE_CODED, &hdev->quirks);
2396+
if (bcm4377->hw->broken_le_ext_adv_report_phy)
2397+
set_bit(HCI_QUIRK_FIXUP_LE_EXT_ADV_REPORT_PHY, &hdev->quirks);
23762398

23772399
pci_set_drvdata(pdev, bcm4377);
23782400
hci_set_drvdata(hdev, bcm4377);
@@ -2477,9 +2499,25 @@ static const struct bcm4377_hw bcm4377_hw_variants[] = {
24772499
.clear_pciecfg_subsystem_ctrl_bit19 = true,
24782500
.broken_mws_transport_config = true,
24792501
.broken_le_coded = true,
2502+
.broken_le_ext_adv_report_phy = true,
24802503
.send_calibration = bcm4387_send_calibration,
24812504
.send_ptb = bcm4378_send_ptb,
24822505
},
2506+
2507+
[BCM4388] = {
2508+
.id = 0x4388,
2509+
.otp_offset = 0x415c,
2510+
.bar2_offset = 0x200000,
2511+
.bar0_window1 = 0x18002000,
2512+
.bar0_window2 = 0x18109000,
2513+
.bar0_core2_window2 = 0x18106000,
2514+
.has_bar0_core2_window2 = true,
2515+
.broken_mws_transport_config = true,
2516+
.broken_le_coded = true,
2517+
.broken_le_ext_adv_report_phy = true,
2518+
.send_calibration = bcm4388_send_calibration,
2519+
.send_ptb = bcm4378_send_ptb,
2520+
},
24832521
};
24842522

24852523
#define BCM4377_DEVID_ENTRY(id) \
@@ -2493,6 +2531,7 @@ static const struct pci_device_id bcm4377_devid_table[] = {
24932531
BCM4377_DEVID_ENTRY(4377),
24942532
BCM4377_DEVID_ENTRY(4378),
24952533
BCM4377_DEVID_ENTRY(4387),
2534+
BCM4377_DEVID_ENTRY(4388),
24962535
{},
24972536
};
24982537
MODULE_DEVICE_TABLE(pci, bcm4377_devid_table);

include/net/bluetooth/hci.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,17 @@ enum {
324324
* claim to support it.
325325
*/
326326
HCI_QUIRK_BROKEN_READ_ENC_KEY_SIZE,
327+
328+
/*
329+
* When this quirk is set, the reserved bits of Primary/Secondary_PHY
330+
* inside the LE Extended Advertising Report events are discarded.
331+
* This is required for some Apple/Broadcom controllers which
332+
* abuse these reserved bits for unrelated flags.
333+
*
334+
* This quirk can be set before hci_register_dev is called or
335+
* during the hdev->setup vendor callback.
336+
*/
337+
HCI_QUIRK_FIXUP_LE_EXT_ADV_REPORT_PHY,
327338
};
328339

329340
/* HCI device flags */

net/bluetooth/hci_event.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6312,6 +6312,13 @@ static void hci_le_ext_adv_report_evt(struct hci_dev *hdev, void *data,
63126312

63136313
evt_type = __le16_to_cpu(info->type) & LE_EXT_ADV_EVT_TYPE_MASK;
63146314
legacy_evt_type = ext_evt_type_to_legacy(hdev, evt_type);
6315+
6316+
if (test_bit(HCI_QUIRK_FIXUP_LE_EXT_ADV_REPORT_PHY,
6317+
&hdev->quirks)) {
6318+
info->primary_phy &= 0x1f;
6319+
info->secondary_phy &= 0x1f;
6320+
}
6321+
63156322
if (legacy_evt_type != LE_ADV_INVALID) {
63166323
process_adv_report(hdev, legacy_evt_type, &info->bdaddr,
63176324
info->bdaddr_type, NULL, 0,

0 commit comments

Comments
 (0)