bluez: update broadcom patches to latest version from RPiOS

This adds support for board-specific firmware files to Broadcom
hciattach, like kernel does for WLAN firmware.

Signed-off-by: Matthias Reichl <hias@horus.com>
This commit is contained in:
Matthias Reichl 2022-11-19 23:06:01 +01:00
parent ee42973ca4
commit 9ac0715e91
3 changed files with 154 additions and 72 deletions

View File

@ -1,51 +0,0 @@
From 874990be3b958bd3d5d5f61989f8d6314be3358a Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Tue, 16 Feb 2016 16:40:46 +0000
Subject: [PATCH 1/4] bcm43xx: Add bcm43xx-3wire variant
---
tools/hciattach.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/tools/hciattach.c b/tools/hciattach.c
index 1904ac5..835d5ff 100644
--- a/tools/hciattach.c
+++ b/tools/hciattach.c
@@ -1144,6 +1144,9 @@ struct uart_t uart[] = {
{ "bcm43xx", 0x0000, 0x0000, HCI_UART_H4, 115200, 3000000,
FLOW_CTL, DISABLE_PM, NULL, bcm43xx, NULL },
+ { "bcm43xx-3wire", 0x0000, 0x0000, HCI_UART_3WIRE, 115200, 3000000,
+ 0, DISABLE_PM, NULL, bcm43xx, NULL },
+
{ "ath3k", 0x0000, 0x0000, HCI_UART_ATH3K, 115200, 115200,
FLOW_CTL, DISABLE_PM, NULL, ath3k_ps, ath3k_pm },
--
1.9.1
From 74e6869ecce13b1066741ba995fc47b437c4c72f Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Wed, 20 Jan 2016 16:00:37 +0000
Subject: [PATCH 3/4] Increase firmware load timeout to 30s
---
tools/hciattach.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/hciattach.c b/tools/hciattach.c
index 9391458..b1168d4 100644
--- a/tools/hciattach.c
+++ b/tools/hciattach.c
@@ -1287,7 +1287,7 @@ int main(int argc, char *argv[])
{
struct uart_t *u = NULL;
int detach, printpid, raw, opt, i, n, ld, err;
- int to = 10;
+ int to = 30;
int init_speed = 0;
int send_break = 0;
pid_t pid;
--
1.9.1

View File

@ -0,0 +1,154 @@
Description: Patches for compatibility with on-board Bluetooth on RPi 3
Author: Simon Long <simon@raspberrypi.org>
Last-Update: 2017-04-05
--- a/tools/hciattach.c
+++ b/tools/hciattach.c
@@ -1091,6 +1091,9 @@
{ "bcm43xx", 0x0000, 0x0000, HCI_UART_H4, 115200, 3000000,
FLOW_CTL, DISABLE_PM, NULL, bcm43xx, NULL },
+ { "bcm43xx-3wire", 0x0000, 0x0000, HCI_UART_3WIRE, 115200, 3000000,
+ 0, DISABLE_PM, NULL, bcm43xx, NULL },
+
{ "ath3k", 0x0000, 0x0000, HCI_UART_ATH3K, 115200, 115200,
FLOW_CTL, DISABLE_PM, NULL, ath3k_ps, ath3k_pm },
@@ -1237,7 +1240,7 @@
{
struct uart_t *u = NULL;
int detach, printpid, raw, opt, i, n, ld, err;
- int to = 10;
+ int to = 30;
int init_speed = 0;
int send_break = 0;
pid_t pid;
--- a/tools/hciattach_bcm43xx.c
+++ b/tools/hciattach_bcm43xx.c
@@ -36,6 +36,7 @@
#include <dirent.h>
#include <time.h>
#include <limits.h>
+#include <sys/stat.h>
#include "lib/bluetooth.h"
#include "lib/hci.h"
@@ -44,7 +45,7 @@
#include "hciattach.h"
#ifndef FIRMWARE_DIR
-#define FIRMWARE_DIR "/etc/firmware"
+#define FIRMWARE_DIR "/lib/firmware"
#endif
#define FW_EXT ".hcd"
@@ -303,9 +304,23 @@
static int bcm43xx_locate_patch(const char *dir_name,
const char *chip_name, char *location)
{
+ struct stat statbuf;
+ char path[PATH_MAX];
DIR *dir;
int ret = -1;
+ /* Try an exact match before scanning, otherwise a board without a specific
+ * firmware/link may end up loading a specific firmware for another board
+ * just because it is encountered first.
+ */
+ if (snprintf(path, PATH_MAX, "%s/%s%s", dir_name, chip_name, FW_EXT) < 0)
+ return -1;
+ if ((stat(path, &statbuf) == 0) && S_ISREG(statbuf.st_mode)) {
+ strcpy(location, path);
+ return 0;
+ }
+
+ /* Now search subdirectories and files with suffixes */
dir = opendir(dir_name);
if (!dir) {
fprintf(stderr, "Cannot open directory '%s': %s\n",
@@ -320,8 +335,6 @@
break;
if (entry->d_type & DT_DIR) {
- char path[PATH_MAX];
-
if (!strcmp(entry->d_name, "..") || !strcmp(entry->d_name, "."))
continue;
@@ -341,8 +354,10 @@
break;
/* found */
- snprintf(location, PATH_MAX, "%s/%s", dir_name, entry->d_name);
- ret = 0;
+ if (snprintf(location, PATH_MAX, "%s/%s", dir_name, entry->d_name) < 0)
+ ret = -1;
+ else
+ ret = 0;
break;
}
}
@@ -352,11 +367,32 @@
return ret;
}
+static int get_board_type(char *buf, int buf_size)
+{
+ int bytes_read;
+ int len;
+ int fd;
+
+ fd = open("/sys/firmware/devicetree/base/compatible", O_RDONLY);
+ if (fd < 0)
+ return -1;
+
+ bytes_read = read(fd, buf, buf_size);
+ close(fd);
+ if (bytes_read < 0)
+ return -1;
+
+ len = strnlen(buf, buf_size);
+ return (len < buf_size) ? len : -1;
+}
+
int bcm43xx_init(int fd, int def_speed, int speed, struct termios *ti,
const char *bdaddr)
{
char chip_name[20];
+ char board_specific_name[sizeof(chip_name) + 64];
char fw_path[PATH_MAX];
+ int chip_name_len;
printf("bcm43xx_init\n");
@@ -366,12 +402,17 @@
if (bcm43xx_read_local_name(fd, chip_name, sizeof(chip_name)))
return -1;
- if (bcm43xx_locate_patch(FIRMWARE_DIR, chip_name, fw_path)) {
- fprintf(stderr, "Patch not found, continue anyway\n");
+ /* Grab the board compatible string from Device Tree */
+ chip_name_len = strlen(chip_name);
+ memcpy(board_specific_name, chip_name, chip_name_len);
+ board_specific_name[chip_name_len++] = '.';
+
+ if (((get_board_type(board_specific_name + chip_name_len,
+ sizeof(board_specific_name) - chip_name_len) < 0) ||
+ bcm43xx_locate_patch(FIRMWARE_DIR, board_specific_name, fw_path)) &&
+ bcm43xx_locate_patch(FIRMWARE_DIR, chip_name, fw_path)) {
+ fprintf(stderr, "Patch not found for %s, continue anyway\n", chip_name);
} else {
- if (bcm43xx_set_speed(fd, ti, speed))
- return -1;
-
if (bcm43xx_load_firmware(fd, fw_path))
return -1;
@@ -381,6 +422,7 @@
return -1;
}
+ sleep(1);
if (bcm43xx_reset(fd))
return -1;
}

View File

@ -1,21 +0,0 @@
diff -Naur a/tools/hciattach_bcm43xx.c b/tools/hciattach_bcm43xx.c
--- a/tools/hciattach_bcm43xx.c 2016-02-25 18:23:15.468717720 +0000
+++ b/tools/hciattach_bcm43xx.c 2016-02-25 18:24:08.028997243 +0000
@@ -368,9 +368,6 @@
if (bcm43xx_locate_patch(FIRMWARE_DIR, chip_name, fw_path)) {
fprintf(stderr, "Patch not found, continue anyway\n");
} else {
- if (bcm43xx_set_speed(fd, ti, speed))
- return -1;
-
if (bcm43xx_load_firmware(fd, fw_path))
return -1;
@@ -379,6 +376,7 @@
perror("Can't set host baud rate");
return -1;
}
+ sleep(1);
if (bcm43xx_reset(fd))
return -1;