Hello everyone,
apparently there have been several tries for adding ath10k USB support, see
[1] & [2]. There are probably even more.
This series is a first step for supporting my actual device,
a Silex SX-USBAC. This is a Bluetooth & WiFi combo device.
I picked commit 131da4f5a5b9 ("HACK: ath10k: add start_once support") from
[2] and extracted the ath10k_hw_params_list entry from [3].
Since v5.9, the base of [3], other required changes have already been
integrated.
For now I tested a very simple STA mode usage profile, using
wpa_supplicant on a WPA interface. AP is untested, module unloading not
supported, probably affected by the firmware start/stop patch 1 adds a
workaround.
Reading the other, older series, apparently a lot has been merged already,
but I do not know what is still missing fpr proper USB support.
I would like to have a discussion for how to add support so the device is
at least probing and can be used rudimentary.
Best regards,
Alexander
[1] https://lore.kernel.org/all/[email protected]/
[2] https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git/log/?h=ath10k-pending-sdio-usb
[3] https://customergts.silexamerica.com/gpl/backports-ath10k-5.9.12-1
For completness, here are USB IDs and 'lsusb -vvv' output
Bus 001 Device 005: ID 0cf3: Ap9378 Qualcomm Atheros Communications QCA9377-7
Bus 001 Device 004: ID 0cf3:e500 Qualcomm Atheros Communications
$ lsusb -vvv -s 1:5
Bus 001 Device 005: ID 0cf3:9378 Qualcomm Atheros Communications QCA9377-7
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.01
bDeviceClass 255 Vendor Specific Class
bDeviceSubClass 255 Vendor Specific Subclass
bDeviceProtocol 255 Vendor Specific Protocol
bMaxPacketSize0 64
idVendor 0x0cf3 Qualcomm Atheros Communications
idProduct 0x9378 QCA9377-7
bcdDevice 3.00
iManufacturer 1 Qualcomm Atheros
iProduct 2 USBWLAN
iSerial 3 12345678
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 0x006f
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xa0
(Bus Powered)
Remote Wakeup
MaxPower 500mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 8
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 255 Vendor Specific Subclass
bInterfaceProtocol 255 Vendor Specific Protocol
iInterface 2 USBWLAN
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x84 EP 4 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x03 EP 3 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x04 EP 4 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 1
bNumEndpoints 4
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 255 Vendor Specific Subclass
bInterfaceProtocol 255 Vendor Specific Protocol
iInterface 2 USBWLAN
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x04 EP 4 OUT
bmAttributes 1
Transfer Type Isochronous
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 1
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 1
Transfer Type Isochronous
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 1
Binary Object Store Descriptor:
bLength 5
bDescriptorType 15
wTotalLength 0x0016
bNumDeviceCaps 2
USB 2.0 Extension Device Capability:
bLength 7
bDescriptorType 16
bDevCapabilityType 2
bmAttributes 0x0000f11e
BESL Link Power Management (LPM) Supported
BESL value 256 us
Deep BESL value 61440 us
SuperSpeed USB Device Capability:
bLength 10
bDescriptorType 16
bDevCapabilityType 3
bmAttributes 0x00
wSpeedsSupported 0x000e
Device can operate at Full Speed (12Mbps)
Device can operate at High Speed (480Mbps)
Device can operate at SuperSpeed (5Gbps)
bFunctionalitySupport 2
Lowest fully-functional device speed is High Speed (480Mbps)
bU1DevExitLat 10 micro seconds
bU2DevExitLat 256 micro seconds
can't get debug descriptor: Resource temporarily unavailable
Device Status: 0x0000
(Bus Powered)
Alexander Stein (1):
ath10k: Add support for QCA9377 hw1.1 usb
Erik Stromdahl (1):
HACK: ath10k: add start_once support
drivers/net/wireless/ath/ath10k/core.c | 48 +++++++++++++++++++++++---
drivers/net/wireless/ath/ath10k/core.h | 2 ++
drivers/net/wireless/ath/ath10k/hw.h | 14 ++++++++
drivers/net/wireless/ath/ath10k/mac.c | 7 ++--
drivers/net/wireless/ath/ath10k/usb.c | 1 +
5 files changed, 66 insertions(+), 6 deletions(-)
--
2.34.1
This adds hw_param for QCA9377 hw1.1 usb device.
Signed-off-by: Alexander Stein <[email protected]>
---
drivers/net/wireless/ath/ath10k/core.c | 28 ++++++++++++++++++++++++++
drivers/net/wireless/ath/ath10k/hw.h | 8 ++++++++
drivers/net/wireless/ath/ath10k/usb.c | 1 +
3 files changed, 37 insertions(+)
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index f69dab55fa36..e67f1a852cd1 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -646,6 +646,34 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
.use_fw_tx_credits = true,
.delay_unmap_buffer = false,
},
+ {
+ .id = QCA9377_HW_1_1_DEV_VERSION,
+ .dev_id = QCA9377_1_1_DEVICE_ID,
+ .bus = ATH10K_BUS_USB,
+ .name = "qca9377 hw1.1 usb",
+ .patch_load_addr = QCA9377_HW_1_1_PATCH_LOAD_ADDR,
+ .uart_pin = 19,
+ .otp_exe_param = 0,
+ .channel_counters_freq_hz = 88000,
+ .max_probe_resp_desc_thres = 0,
+ .cal_data_len = 8124,
+ .fw = {
+ .dir = QCA9377_HW_1_1_FW_DIR,
+ .board = QCA9377_HW_1_1_USB_BOARD_DATA_FILE,
+ .board_size = QCA9377_BOARD_DATA_SZ,
+ .board_ext_size = QCA9377_BOARD_EXT_DATA_SZ,
+ },
+ .hw_ops = &qca6174_ops,
+ .hw_clk = qca6174_clk,
+ .target_cpu_freq = 176000000,
+ .decap_align_bytes = 4,
+ .n_cipher_suites = 8,
+ .num_peers = TARGET_QCA9377_HL_NUM_PEERS,
+ .ast_skid_limit = 0x10,
+ .num_wds_entries = 0x20,
+ .uart_pin_workaround = true,
+ .start_once = true,
+ },
{
.id = QCA4019_HW_1_0_DEV_VERSION,
.dev_id = 0,
diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h
index ea3b5c5c6c9b..2e934d74d7cc 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -29,6 +29,7 @@ enum ath10k_bus {
#define QCA9888_2_0_DEVICE_ID (0x0056)
#define QCA9984_1_0_DEVICE_ID (0x0046)
#define QCA9377_1_0_DEVICE_ID (0x0042)
+#define QCA9377_1_1_DEVICE_ID (0x9378)
#define QCA9887_1_0_DEVICE_ID (0x0050)
/* QCA988X 1.0 definitions (unsupported) */
@@ -123,6 +124,13 @@ enum qca9377_chip_id_rev {
#define QCA9377_HW_1_0_BOARD_DATA_FILE "board.bin"
#define QCA9377_HW_1_0_PATCH_LOAD_ADDR 0x1234
+/* QCA9377 1.1 definitions */
+#define QCA9377_HW_1_1_FW_DIR ATH10K_FW_DIR "/QCA9377/hw1.1"
+#define QCA9377_HW_1_1_BOARD_DATA_FILE "board.bin"
+#define QCA9377_HW_1_1_SDIO_BOARD_DATA_FILE "board-sdio.bin"
+#define QCA9377_HW_1_1_USB_BOARD_DATA_FILE "board-usb.bin"
+#define QCA9377_HW_1_1_PATCH_LOAD_ADDR 0x1234
+
/* QCA4019 1.0 definitions */
#define QCA4019_HW_1_0_DEV_VERSION 0x01000000
#define QCA4019_HW_1_0_FW_DIR ATH10K_FW_DIR "/QCA4019/hw1.0"
diff --git a/drivers/net/wireless/ath/ath10k/usb.c b/drivers/net/wireless/ath/ath10k/usb.c
index b0067af685b1..efb949158aa1 100644
--- a/drivers/net/wireless/ath/ath10k/usb.c
+++ b/drivers/net/wireless/ath/ath10k/usb.c
@@ -1107,6 +1107,7 @@ static int ath10k_usb_pm_resume(struct usb_interface *interface)
/* table of devices that work with this driver */
static struct usb_device_id ath10k_usb_ids[] = {
{USB_DEVICE(0x13b1, 0x0042)}, /* Linksys WUSB6100M */
+ {USB_DEVICE(0x0CF3, 0x9378)}, /* Qualcomm QCA9377-7 */
{ /* Terminating entry */ },
};
--
2.34.1
From: Erik Stromdahl <[email protected]>
Add possibility to configure the driver to only start target once.
This can reduce startup time of SDIO devices significantly since
loading the firmware can take a substantial amount of time.
The patch is also necessary for high latency devices in general
since it does not seem to be possible to rerun the BMI phase
(fw upload) without power-cycling the device.
[kvalo: this needs more discussion as it's pretty important to be able to
reset/stop the firmware. with SDIO we should (I hope) to control the target
device power. And on USB it should be possible to reset the device via a
register.]
Signed-off-by: Erik Stromdahl <[email protected]>
Signed-off-by: Kalle Valo <[email protected]>
Signed-off-by: Alexander Stein <[email protected]>
---
This type of patch is floating around everywhere ath10k USB support is used.
I don't have any knowledge about internals, so there is not much I can add here.
I had to add a check for start_once in ath10k_halt() as well, otherwise
interface up after shutting down will timeout.
[ 410.212643] usb 1-1.1.2: Failed to submit usb control message: -110
[ 410.218961] usb 1-1.1.2: unable to send the bmi data to the device: -110
[ 410.225708] usb 1-1.1.2: Unable to read soc register from device: -110
[ 411.236646] usb 1-1.1.2: Failed to submit usb control message: -110
[ 411.242963] usb 1-1.1.2: unable to send the bmi data to the device: -110
[ 411.249703] usb 1-1.1.2: unable to write to the device (-110)
[ 411.255479] usb 1-1.1.2: settings HTC version failed
[ 411.260476] usb 1-1.1.2: Could not init core: -22
drivers/net/wireless/ath/ath10k/core.c | 20 ++++++++++++++++----
drivers/net/wireless/ath/ath10k/core.h | 2 ++
drivers/net/wireless/ath/ath10k/hw.h | 6 ++++++
drivers/net/wireless/ath/ath10k/mac.c | 7 +++++--
4 files changed, 29 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index 5eb131ab916f..f69dab55fa36 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -2927,6 +2927,9 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
int status;
u32 val;
+ if (ar->is_started && ar->hw_params.start_once)
+ return 0;
+
lockdep_assert_held(&ar->conf_mutex);
clear_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags);
@@ -3231,6 +3234,8 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
goto err_hif_stop;
}
+ ar->is_started = true;
+
return 0;
err_hif_stop:
@@ -3285,6 +3290,7 @@ void ath10k_core_stop(struct ath10k *ar)
ath10k_wmi_detach(ar);
ar->id.bmi_ids_valid = false;
+ ar->is_started = false;
}
EXPORT_SYMBOL(ath10k_core_stop);
@@ -3424,12 +3430,18 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
goto err_unlock;
}
- ath10k_debug_print_boot_info(ar);
- ath10k_core_stop(ar);
+ /* Leave target running if hw_params.start_once is set */
+ if (ar->hw_params.start_once) {
+ mutex_unlock(&ar->conf_mutex);
+ } else {
+ ath10k_debug_print_boot_info(ar);
+ ath10k_core_stop(ar);
+
+ mutex_unlock(&ar->conf_mutex);
- mutex_unlock(&ar->conf_mutex);
+ ath10k_hif_power_down(ar);
+ }
- ath10k_hif_power_down(ar);
return 0;
err_unlock:
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index f5de8ce8fb45..0ef21171db87 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -1054,6 +1054,8 @@ struct ath10k {
bool nlo_enabled;
bool p2p;
+ bool is_started;
+
struct {
enum ath10k_bus bus;
const struct ath10k_hif_ops *ops;
diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h
index 9643031a4427..ea3b5c5c6c9b 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -639,6 +639,12 @@ struct ath10k_hw_params {
bool use_fw_tx_credits;
bool delay_unmap_buffer;
+
+ /* Specifies whether or not the device should be started once.
+ * If set, the device will be started once by the early fw probe
+ * and it will not be terminated afterwards.
+ */
+ bool start_once;
};
struct htt_resp;
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index ec8d5b29bc72..c6b84f9bb0e3 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -4790,8 +4790,11 @@ void ath10k_halt(struct ath10k *ar)
ath10k_scan_finish(ar);
ath10k_peer_cleanup_all(ar);
ath10k_stop_radar_confirmation(ar);
- ath10k_core_stop(ar);
- ath10k_hif_power_down(ar);
+ /* Leave target running if hw_params.start_once is set */
+ if (!ar->hw_params.start_once) {
+ ath10k_core_stop(ar);
+ ath10k_hif_power_down(ar);
+ }
spin_lock_bh(&ar->data_lock);
list_for_each_entry(arvif, &ar->arvifs, list)
--
2.34.1