From 305c1c5dd5f4a915cb5a4a5c7115c0e3b3aa20c1 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Wed, 10 Dec 2025 11:38:08 -0500 Subject: [PATCH 1/5] Bluetooth: hci_conn: Fix using conn->le_{tx,rx}_phy as supported PHYs conn->le_{tx,rx}_phy is not actually a bitfield as it set by HCI_EV_LE_PHY_UPDATE_COMPLETE it is actually correspond to the current PHY in use not what is supported by the controller, so this introduces different fields (conn->le_{tx,rx}_def_phys) to track what PHYs are supported by the connection. Fixes: eab2404ba798 ("Bluetooth: Add BT_PHY socket option") Signed-off-by: Luiz Augusto von Dentz --- include/net/bluetooth/hci_core.h | 2 ++ net/bluetooth/hci_conn.c | 17 +++++++++++------ net/bluetooth/hci_event.c | 26 +++++++++++++++++++++++--- 3 files changed, 36 insertions(+), 9 deletions(-) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 4263e71a23ef..8aadf4cdead2 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -730,6 +730,8 @@ struct hci_conn { __u16 le_per_adv_data_offset; __u8 le_adv_phy; __u8 le_adv_sec_phy; + __u8 le_tx_def_phys; + __u8 le_rx_def_phys; __u8 le_tx_phy; __u8 le_rx_phy; __s8 rssi; diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index c3f7828bf9d5..5a4374ccf8e8 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -1008,6 +1008,11 @@ static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type, /* conn->src should reflect the local identity address */ hci_copy_identity_address(hdev, &conn->src, &conn->src_type); conn->mtu = hdev->le_mtu ? hdev->le_mtu : hdev->acl_mtu; + /* Use the controller supported PHYS as default until the + * remote features are resolved. + */ + conn->le_tx_def_phys = hdev->le_tx_def_phys; + conn->le_rx_def_phys = hdev->le_tx_def_phys; break; case CIS_LINK: /* conn->src should reflect the local identity address */ @@ -2928,22 +2933,22 @@ u32 hci_conn_get_phy(struct hci_conn *conn) break; case LE_LINK: - if (conn->le_tx_phy & HCI_LE_SET_PHY_1M) + if (conn->le_tx_def_phys & HCI_LE_SET_PHY_1M) phys |= BT_PHY_LE_1M_TX; - if (conn->le_rx_phy & HCI_LE_SET_PHY_1M) + if (conn->le_rx_def_phys & HCI_LE_SET_PHY_1M) phys |= BT_PHY_LE_1M_RX; - if (conn->le_tx_phy & HCI_LE_SET_PHY_2M) + if (conn->le_tx_def_phys & HCI_LE_SET_PHY_2M) phys |= BT_PHY_LE_2M_TX; - if (conn->le_rx_phy & HCI_LE_SET_PHY_2M) + if (conn->le_rx_def_phys & HCI_LE_SET_PHY_2M) phys |= BT_PHY_LE_2M_RX; - if (conn->le_tx_phy & HCI_LE_SET_PHY_CODED) + if (conn->le_tx_def_phys & HCI_LE_SET_PHY_CODED) phys |= BT_PHY_LE_CODED_TX; - if (conn->le_rx_phy & HCI_LE_SET_PHY_CODED) + if (conn->le_rx_def_phys & HCI_LE_SET_PHY_CODED) phys |= BT_PHY_LE_CODED_RX; break; diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index a9868f17ef40..bc3a90600d73 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -6607,8 +6607,18 @@ static void hci_le_remote_feat_complete_evt(struct hci_dev *hdev, void *data, conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); if (conn) { - if (!ev->status) - memcpy(conn->features[0], ev->features, 8); + if (!ev->status) { + memcpy(conn->le_features, ev->features, 8); + + /* Update supported PHYs */ + if (conn->le_tx_def_phys & HCI_LE_SET_PHY_2M && + !(conn->le_features[1] & HCI_LE_PHY_2M)) + conn->le_tx_def_phys &= ~HCI_LE_SET_PHY_2M; + + if (conn->le_tx_def_phys & HCI_LE_SET_PHY_CODED && + !(conn->le_features[1] & HCI_LE_PHY_CODED)) + conn->le_tx_def_phys &= ~HCI_LE_SET_PHY_CODED; + } if (conn->state == BT_CONFIG) { __u8 status; @@ -7221,9 +7231,19 @@ static void hci_le_read_all_remote_features_evt(struct hci_dev *hdev, if (!conn) goto unlock; - if (!ev->status) + if (!ev->status) { memcpy(conn->le_features, ev->features, 248); + /* Update supported PHYs */ + if (conn->le_tx_def_phys & HCI_LE_SET_PHY_2M && + !(conn->le_features[1] & HCI_LE_PHY_2M)) + conn->le_tx_def_phys &= ~HCI_LE_SET_PHY_2M; + + if (conn->le_tx_def_phys & HCI_LE_SET_PHY_CODED && + !(conn->le_features[1] & HCI_LE_PHY_CODED)) + conn->le_tx_def_phys &= ~HCI_LE_SET_PHY_CODED; + } + if (conn->state == BT_CONFIG) { __u8 status; From dbdc24e6e811e2e15bab2f928385940b6e0392e1 Mon Sep 17 00:00:00 2001 From: Tedd Ho-Jeong An Date: Wed, 4 Nov 2020 21:09:48 -0800 Subject: [PATCH 2/5] workflow: Add workflow files for ci This patch adds workflow files for ci: [sync.yml] - The workflow file for scheduled work - Sync the repo with upstream repo and rebase the workflow branch - Review the patches in the patchwork and creates the PR if needed [ci.yml] - The workflow file for CI tasks - Run CI tests when PR is created Signed-off-by: Tedd Ho-Jeong An --- .github/workflows/ci.yml | 25 ++++++++++++++++++++++ .github/workflows/sync.yml | 43 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/sync.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000000..3a2c45c37553 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,25 @@ +name: CI + +on: [pull_request] + +jobs: + ci: + runs-on: ubuntu-latest + name: CI for Pull Request + steps: + - name: Checkout the source code + uses: actions/checkout@v3 + with: + path: src/src + + - name: CI + uses: tedd-an/bzcafe@main + with: + task: ci + base_folder: src + space: kernel + github_token: ${{ secrets.GITHUB_TOKEN }} + email_token: ${{ secrets.EMAIL_TOKEN }} + patchwork_token: ${{ secrets.PATCHWORK_TOKEN }} + patchwork_user: ${{ secrets.PATCHWORK_USER }} + diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml new file mode 100644 index 000000000000..3883d55a2326 --- /dev/null +++ b/.github/workflows/sync.yml @@ -0,0 +1,43 @@ +name: Sync + +on: + schedule: + - cron: "*/30 * * * *" + +jobs: + sync_repo: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + ref: master + + - name: Sync Repo + uses: tedd-an/bzcafe@main + with: + task: sync + upstream_repo: 'https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git' + github_token: ${{ secrets.GITHUB_TOKEN }} + + - name: Cleanup PR + uses: tedd-an/bzcafe@main + with: + task: cleanup + github_token: ${{ secrets.ACTION_TOKEN }} + + sync_patchwork: + needs: sync_repo + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Sync Patchwork + uses: tedd-an/bzcafe@main + with: + task: patchwork + space: kernel + github_token: ${{ secrets.ACTION_TOKEN }} + email_token: ${{ secrets.EMAIL_TOKEN }} + patchwork_token: ${{ secrets.PATCHWORK_TOKEN }} + patchwork_user: ${{ secrets.PATCHWORK_USER }} + From 990ca91a4c7c9fe409ab08b9b5d7cc4c17c3d714 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 12 Dec 2025 09:09:06 +0100 Subject: [PATCH 3/5] serdev: Provide a bustype shutdown function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To prepare serdev driver to migrate away from struct device_driver::shutdown (and then eventually remove that callback) create a serdev driver shutdown callback and migration code to keep the existing behaviour. Note this introduces a warning for each driver at register time that isn't converted yet to that callback. Signed-off-by: Uwe Kleine-König --- drivers/tty/serdev/core.c | 21 +++++++++++++++++++++ include/linux/serdev.h | 1 + 2 files changed, 22 insertions(+) diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c index b33e708cb245..40eedc15277c 100644 --- a/drivers/tty/serdev/core.c +++ b/drivers/tty/serdev/core.c @@ -414,11 +414,21 @@ static void serdev_drv_remove(struct device *dev) sdrv->remove(to_serdev_device(dev)); } +static void serdev_drv_shutdown(struct device *dev) +{ + const struct serdev_device_driver *sdrv = + to_serdev_device_driver(dev->driver); + + if (dev->driver && sdrv->shutdown) + sdrv->shutdown(to_serdev_device(dev)); +} + static const struct bus_type serdev_bus_type = { .name = "serial", .match = serdev_device_match, .probe = serdev_drv_probe, .remove = serdev_drv_remove, + .shutdown = serdev_drv_shutdown, }; /** @@ -814,6 +824,14 @@ void serdev_controller_remove(struct serdev_controller *ctrl) } EXPORT_SYMBOL_GPL(serdev_controller_remove); +static void serdev_legacy_shutdown(struct serdev_device *serdev) +{ + struct device *dev = &serdev->dev; + struct device_driver *driver = dev->driver; + + driver->shutdown(dev); +} + /** * __serdev_device_driver_register() - Register client driver with serdev core * @sdrv: client driver to be associated with client-device. @@ -830,6 +848,9 @@ int __serdev_device_driver_register(struct serdev_device_driver *sdrv, struct mo /* force drivers to async probe so I/O is possible in probe */ sdrv->driver.probe_type = PROBE_PREFER_ASYNCHRONOUS; + if (!sdrv->shutdown && sdrv->driver.shutdown) + sdrv->shutdown = serdev_legacy_shutdown; + return driver_register(&sdrv->driver); } EXPORT_SYMBOL_GPL(__serdev_device_driver_register); diff --git a/include/linux/serdev.h b/include/linux/serdev.h index 34562eb99931..5654c58eb73c 100644 --- a/include/linux/serdev.h +++ b/include/linux/serdev.h @@ -65,6 +65,7 @@ struct serdev_device_driver { struct device_driver driver; int (*probe)(struct serdev_device *); void (*remove)(struct serdev_device *); + void (*shutdown)(struct serdev_device *); }; static inline struct serdev_device_driver *to_serdev_device_driver(struct device_driver *d) From 578931a9729377a5ef0f6505a0a7c0aa9cfff2df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 12 Dec 2025 09:09:07 +0100 Subject: [PATCH 4/5] Bluetooth: hci_aml: Migrate to serdev specific shutdown function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This saves a cast in the driver. The motivation is stop using the callback .shutdown in qca_serdev_driver.driver to make it possible to drop that. Signed-off-by: Uwe Kleine-König --- drivers/bluetooth/hci_aml.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/bluetooth/hci_aml.c b/drivers/bluetooth/hci_aml.c index b1f32c5a8a3f..4981c82d634d 100644 --- a/drivers/bluetooth/hci_aml.c +++ b/drivers/bluetooth/hci_aml.c @@ -677,13 +677,6 @@ static const struct hci_uart_proto aml_hci_proto = { .dequeue = aml_dequeue, }; -static void aml_device_driver_shutdown(struct device *dev) -{ - struct aml_serdev *amldev = dev_get_drvdata(dev); - - aml_power_off(amldev); -} - static int aml_serdev_probe(struct serdev_device *serdev) { struct aml_serdev *amldev; @@ -714,6 +707,13 @@ static void aml_serdev_remove(struct serdev_device *serdev) hci_uart_unregister_device(&amldev->serdev_hu); } +static void aml_serdev_shutdown(struct serdev_device *serdev) +{ + struct aml_serdev *amldev = serdev_device_get_drvdata(serdev); + + aml_power_off(amldev); +} + static const struct aml_device_data data_w155s2 = { .iccm_offset = 256 * 1024, }; @@ -732,10 +732,10 @@ MODULE_DEVICE_TABLE(of, aml_bluetooth_of_match); static struct serdev_device_driver aml_serdev_driver = { .probe = aml_serdev_probe, .remove = aml_serdev_remove, + .shutdown = aml_serdev_shutdown, .driver = { .name = "hci_uart_aml", .of_match_table = aml_bluetooth_of_match, - .shutdown = aml_device_driver_shutdown, }, }; From 3eb2f55c43273ae3020be8172468b01e3a97a1d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 12 Dec 2025 09:09:08 +0100 Subject: [PATCH 5/5] Bluetooth: hci_qca: Migrate to serdev specific shutdown function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This saves a cast in the driver. The motivation is stop using the callback .shutdown in qca_serdev_driver.driver to make it possible to drop that. Signed-off-by: Uwe Kleine-König --- drivers/bluetooth/hci_qca.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index a3c217571c3c..b54350317a43 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -2563,11 +2563,10 @@ static void qca_serdev_remove(struct serdev_device *serdev) hci_uart_unregister_device(&qcadev->serdev_hu); } -static void qca_serdev_shutdown(struct device *dev) +static void qca_serdev_shutdown(struct serdev_device *serdev) { int ret; int timeout = msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS); - struct serdev_device *serdev = to_serdev_device(dev); struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev); struct hci_uart *hu = &qcadev->serdev_hu; struct hci_dev *hdev = hu->hdev; @@ -2789,11 +2788,11 @@ static void hciqca_coredump(struct device *dev) static struct serdev_device_driver qca_serdev_driver = { .probe = qca_serdev_probe, .remove = qca_serdev_remove, + .shutdown = qca_serdev_shutdown, .driver = { .name = "hci_uart_qca", .of_match_table = of_match_ptr(qca_bluetooth_of_match), .acpi_match_table = ACPI_PTR(qca_bluetooth_acpi_match), - .shutdown = qca_serdev_shutdown, .pm = &qca_pm_ops, #ifdef CONFIG_DEV_COREDUMP .coredump = hciqca_coredump,