diff mbox series

[5/5] USB: serial: qcserial: enable ZLP for non-QDL interfaces

Message ID 20241117083204.57738-5-intelfx@intelfx.name (mailing list archive)
State New
Headers show
Series [1/5] net: usb: qmi_wwan: add IDs for EM7565 (9X50) in "MBIM USBIF" config | expand

Checks

Context Check Description
netdev/series_format warning Series does not have a cover letter
netdev/tree_selection success Guessed tree name to be net-next
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 3 this patch: 3
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers success CCed 3 of 3 maintainers
netdev/build_clang success Errors and warnings before: 3 this patch: 3
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 4 this patch: 4
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 111 lines checked
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
netdev/contest success net-next-2024-11-17--12-00 (tests: 789)

Commit Message

Ivan Shapovalov Nov. 17, 2024, 8:31 a.m. UTC
This is a port of the corresponding change from the qcserial.c driver
distributed as part of the 9X50 SDK, tested using author's own EM7565
device.

The SDK qcserial.c driver enables ZLP unconditionally, however this was
found to break QDL mode (as exercised by the qmi-firmware-update tool
from libqmi[1], as well as the SDK-provided firmware update utility).
Thus, ZLP is limited to non-QDL interfaces.

[1]: https://www.freedesktop.org/wiki/Software/libqmi/

Signed-off-by: Ivan Shapovalov <intelfx@intelfx.name>
---
 drivers/usb/serial/qcserial.c | 36 ++++++++++++++++++++++-------------
 1 file changed, 23 insertions(+), 13 deletions(-)
diff mbox series

Patch

diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c
index b2ae0b16bc2b..d51d022d76b1 100644
--- a/drivers/usb/serial/qcserial.c
+++ b/drivers/usb/serial/qcserial.c
@@ -32,6 +32,11 @@  enum qcserial_layouts {
 	QCSERIAL_SWI_SDX55_RMNET = 7, /* Sierra Wireless SDX55 */
 };
 
+enum qcserial_flags {
+	QC_SENDSETUP = (1 << 0),
+	QC_ZLP = (1 << 1),
+};
+
 #define DEVICE_G1K(v, p) \
 	USB_DEVICE(v, p), .driver_info = QCSERIAL_G1K
 #define DEVICE_SWI(v, p) \
@@ -262,7 +267,7 @@  static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
 	__u8 nintf;
 	__u8 ifnum;
 	int altsetting = -1;
-	bool sendsetup = false;
+	unsigned long flags = 0;
 
 	/* we only support vendor specific functions */
 	if (intf->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC)
@@ -301,6 +306,9 @@  static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
 	/* default to enabling interface */
 	altsetting = 0;
 
+	/* default to enabling ZLP */
+	flags |= QC_ZLP;
+
 	/*
 	 * Composite mode; don't bind to the QMI/net interface as that
 	 * gets handled by other drivers.
@@ -386,11 +394,11 @@  static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
 			break;
 		case 2:
 			dev_dbg(dev, "NMEA GPS interface found\n");
-			sendsetup = true;
+			flags |= QC_SENDSETUP;
 			break;
 		case 3:
 			dev_dbg(dev, "Modem port found\n");
-			sendsetup = true;
+			flags |= QC_SENDSETUP;
 			break;
 		default:
 			/* don't claim any unsupported interface */
@@ -446,11 +454,11 @@  static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
 		switch (ifnum) {
 		case 2:
 			dev_dbg(dev, "Modem port found\n");
-			sendsetup = true;
+			flags |= QC_SENDSETUP;
 			break;
 		case 3:
 			dev_dbg(dev, "NMEA GPS interface found\n");
-			sendsetup = true;
+			flags |= QC_SENDSETUP;
 			break;
 		case 4:
 			dev_dbg(dev, "DM/DIAG interface found\n");
@@ -475,11 +483,11 @@  static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
 		switch (ifnum) {
 		case 0:
 			dev_dbg(dev, "Modem port found\n");
-			sendsetup = true;
+			flags |= QC_SENDSETUP;
 			break;
 		case 1:
 			dev_dbg(dev, "NMEA GPS interface found\n");
-			sendsetup = true;
+			flags |= QC_SENDSETUP;
 			break;
 		case 2:
 			dev_dbg(dev, "DM/DIAG interface found\n");
@@ -502,7 +510,7 @@  static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
 		switch (ifnum) {
 		case 3:
 			dev_dbg(dev, "Modem port found\n");
-			sendsetup = true;
+			flags |= QC_SENDSETUP;
 			break;
 		case 4:
 			dev_dbg(dev, "DM/DIAG interface found\n");
@@ -522,7 +530,7 @@  static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
 		switch (ifnum) {
 		case 1:
 			dev_dbg(dev, "Modem port found\n");
-			sendsetup = true;
+			flags |= QC_SENDSETUP;
 			break;
 		case 2:
 			dev_dbg(dev, "DM/DIAG interface found\n");
@@ -551,7 +559,7 @@  static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
 	}
 
 	if (!retval)
-		usb_set_serial_data(serial, (void *)(unsigned long)sendsetup);
+		usb_set_serial_data(serial, (void *)flags);
 
 	return retval;
 }
@@ -559,15 +567,17 @@  static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
 static int qc_attach(struct usb_serial *serial)
 {
 	struct usb_wwan_intf_private *data;
-	bool sendsetup;
+	unsigned long flags = 0;
 
 	data = kzalloc(sizeof(*data), GFP_KERNEL);
 	if (!data)
 		return -ENOMEM;
 
-	sendsetup = !!(unsigned long)(usb_get_serial_data(serial));
-	if (sendsetup)
+	flags = (unsigned long)(usb_get_serial_data(serial));
+	if (flags & QC_SENDSETUP)
 		data->use_send_setup = 1;
+	if (flags & QC_ZLP)
+		data->use_zlp = 1;
 
 	spin_lock_init(&data->susp_lock);