ofono.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 1/2] udevng: Detect embedded qmi QRTR modems
@ 2024-04-08 21:34 Steve Schrock
  2024-04-08 21:34 ` [PATCH v2 2/2] qmimodem: Default embedded modems endpoint ID Steve Schrock
  2024-04-08 22:40 ` [PATCH v2 1/2] udevng: Detect embedded qmi QRTR modems patchwork-bot+ofono
  0 siblings, 2 replies; 3+ messages in thread
From: Steve Schrock @ 2024-04-08 21:34 UTC (permalink / raw)
  To: ofono; +Cc: Steve Schrock

Embedded qmi QRTR modems are identified by the existence of
rmnet_ipaX and rmnet_dataX devices. Add a new "embedded" modem type
so that these devices can be collected during enumeration and then
configured for use by the gobi plugin. Modems of this type will be
exposed as /gobiqrtr_X.
---
 plugins/gobi.c   |  19 +++++++--
 plugins/udevng.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 119 insertions(+), 5 deletions(-)

diff --git a/plugins/gobi.c b/plugins/gobi.c
index 7a07b080d895..431df17e2332 100644
--- a/plugins/gobi.c
+++ b/plugins/gobi.c
@@ -420,16 +420,27 @@ static void discover_cb(void *user_data)
 static int gobi_enable(struct ofono_modem *modem)
 {
 	struct gobi_data *data = ofono_modem_get_data(modem);
-	const char *device;
+	const char *kernel_driver;
 	int r;
 
 	DBG("%p", modem);
 
-	device = ofono_modem_get_string(modem, "Device");
-	if (!device)
+	kernel_driver = ofono_modem_get_string(modem, "KernelDriver");
+	if (!kernel_driver)
 		return -EINVAL;
 
-	data->device = qmi_device_new_qmux(device);
+	if (!strcmp(kernel_driver, "qrtr"))
+		data->device = qmi_device_new_qrtr();
+	else {
+		const char *device;
+
+		device = ofono_modem_get_string(modem, "Device");
+		if (!device)
+			return -EINVAL;
+
+		data->device = qmi_device_new_qmux(device);
+	}
+
 	if (!data->device)
 		return -EIO;
 
diff --git a/plugins/udevng.c b/plugins/udevng.c
index 8bdcf0dbbccd..14ae2f392da4 100644
--- a/plugins/udevng.c
+++ b/plugins/udevng.c
@@ -43,6 +43,7 @@ enum modem_type {
 	MODEM_TYPE_USB,
 	MODEM_TYPE_SERIAL,
 	MODEM_TYPE_PCIE,
+	MODEM_TYPE_EMBEDDED,
 };
 
 struct modem_info {
@@ -206,7 +207,10 @@ static int setup_qmi(struct modem_info *modem, const struct device_info *qmi,
 	DBG("qmi: %s net: %s kernel_driver: %s interface_number: %s",
 		qmi->devnode, net->devnode, net->kernel_driver, net->number);
 
-	if (!qmi->kernel_driver || !net->number)
+	if (!qmi->kernel_driver)
+		return -EINVAL;
+
+	if (!net->number && modem->type != MODEM_TYPE_EMBEDDED)
 		return -EINVAL;
 
 	attr_value = udev_device_get_sysattr_value(net->udev_device,
@@ -234,6 +238,9 @@ static int setup_qmi(struct modem_info *modem, const struct device_info *qmi,
 	case MODEM_TYPE_PCIE:
 		ofono_modem_set_string(modem->modem, "Bus", "pcie");
 		break;
+	case MODEM_TYPE_EMBEDDED:
+		ofono_modem_set_string(modem->modem, "Bus", "embedded");
+		break;
 	case MODEM_TYPE_SERIAL:
 		break;
 	}
@@ -241,6 +248,75 @@ static int setup_qmi(struct modem_info *modem, const struct device_info *qmi,
 	return 0;
 }
 
+static gboolean setup_gobi_qrtr_premux(struct modem_info *modem,
+					const char *name, int premux_index)
+{
+	const char *rmnet_data_prefix = "rmnet_data";
+	int rmnet_data_prefix_length = strlen(rmnet_data_prefix);
+	char buf[256];
+	int r;
+	uint32_t data_id;
+	uint32_t mux_id;
+
+	r = l_safe_atou32(name + rmnet_data_prefix_length, &data_id);
+	if (r < 0)
+		return FALSE;
+
+	mux_id = data_id + 1;
+
+	DBG("Adding premux interface %s, mux id: %d", name, mux_id);
+	sprintf(buf, "PremuxInterface%d", premux_index);
+	ofono_modem_set_string(modem->modem, buf, name);
+	sprintf(buf, "PremuxInterface%dMuxId", premux_index);
+	ofono_modem_set_integer(modem->modem, buf, mux_id);
+
+	return TRUE;
+}
+
+static gboolean setup_gobi_qrtr(struct modem_info *modem)
+{
+	const struct device_info *ipa_info = NULL;
+	int premux_count = 0;
+	int r;
+	GSList *list;
+
+	DBG("%s", modem->syspath);
+
+	for (list = modem->devices; list; list = list->next) {
+		struct device_info *info = list->data;
+		const char *name;
+
+		name = udev_device_get_sysname(info->udev_device);
+		if (l_str_has_prefix(name, "rmnet_ipa"))
+			ipa_info = info;
+		else if (l_str_has_prefix(name, "rmnet_data")) {
+			int premux_index = premux_count + 1;
+
+			if (setup_gobi_qrtr_premux(modem, name, premux_index))
+				premux_count++;
+		}
+	}
+
+	if (premux_count < 3) {
+		DBG("Not enough rmnet_data interfaces found");
+		return FALSE;
+	}
+
+	ofono_modem_set_integer(modem->modem, "NumPremuxInterfaces",
+							premux_count);
+
+	if (!ipa_info) {
+		DBG("No rmnet_ipa interface found");
+		return FALSE;
+	}
+
+	r = setup_qmi(modem, ipa_info, ipa_info);
+	if (r < 0)
+		return FALSE;
+
+	return TRUE;
+}
+
 static gboolean setup_gobi(struct modem_info *modem)
 {
 	const struct device_info *qmi = NULL;
@@ -1594,6 +1670,7 @@ static struct {
 	{ "wavecom",	setup_wavecom		},
 	{ "tc65",	setup_tc65		},
 	{ "ehs6",	setup_ehs6		},
+	{ "gobiqrtr",	setup_gobi_qrtr		},
 	{ }
 };
 
@@ -1644,6 +1721,7 @@ static void destroy_modem(gpointer data)
 	switch (modem->type) {
 	case MODEM_TYPE_USB:
 	case MODEM_TYPE_PCIE:
+	case MODEM_TYPE_EMBEDDED:
 		for (list = modem->devices; list; list = list->next) {
 			struct device_info *info = list->data;
 
@@ -1688,6 +1766,9 @@ static gboolean check_remove(gpointer key, gpointer value, gpointer user_data)
 		if (g_strcmp0(modem->serial->devpath, devpath) == 0)
 			return TRUE;
 		break;
+	case MODEM_TYPE_EMBEDDED:
+		/* Embedded modems cannot be removed. */
+		break;
 	}
 
 	return FALSE;
@@ -2133,6 +2214,26 @@ static void check_pci_device(struct udev_device *device)
 			device, kernel_driver);
 }
 
+static void check_net_device(struct udev_device *device)
+{
+	char path[32];
+	const char *name;
+	const char *iflink;
+
+	name = udev_device_get_sysname(device);
+	if (!l_str_has_prefix(name, "rmnet_"))
+		return;
+
+	iflink = udev_device_get_sysattr_value(device, "iflink");
+	if (!iflink)
+		return;
+
+	/* Collect all rmnet devices with this iflink under a common path. */
+	sprintf(path, "/embedded/qrtr/%s", iflink);
+	add_device(path, NULL, "gobiqrtr", NULL, NULL, MODEM_TYPE_EMBEDDED,
+							device, "qrtr");
+}
+
 static void check_device(struct udev_device *device)
 {
 	const char *bus;
@@ -2149,6 +2250,8 @@ static void check_device(struct udev_device *device)
 		check_usb_device(device);
 	else if (g_str_equal(bus, "pci") == TRUE)
 		check_pci_device(device);
+	else if (g_str_equal(bus, "net") == TRUE)
+		check_net_device(device);
 	else
 		add_serial_device(device);
 
-- 
2.43.2


-- 


*Confidentiality Note:* We care about protecting our proprietary 
information, confidential material, and trade secrets. This message may 
contain some or all of those things. Cruise will suffer material harm if 
anyone other than the intended recipient disseminates or takes any action 
based on this message. If you have received this message (including any 
attachments) in error, please delete it immediately and notify the sender 
promptly.

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH v2 2/2] qmimodem: Default embedded modems endpoint ID
  2024-04-08 21:34 [PATCH v2 1/2] udevng: Detect embedded qmi QRTR modems Steve Schrock
@ 2024-04-08 21:34 ` Steve Schrock
  2024-04-08 22:40 ` [PATCH v2 1/2] udevng: Detect embedded qmi QRTR modems patchwork-bot+ofono
  1 sibling, 0 replies; 3+ messages in thread
From: Steve Schrock @ 2024-04-08 21:34 UTC (permalink / raw)
  To: ofono; +Cc: Steve Schrock

Embedded QMI QRTR modems use an endpoint ID of 1. This will not be set
by udevng, so gprs-context must handle this case.
---
 drivers/qmimodem/gprs-context.c | 32 +++++++++++++++++---------------
 1 file changed, 17 insertions(+), 15 deletions(-)

diff --git a/drivers/qmimodem/gprs-context.c b/drivers/qmimodem/gprs-context.c
index fb2069020833..33565252028c 100644
--- a/drivers/qmimodem/gprs-context.c
+++ b/drivers/qmimodem/gprs-context.c
@@ -376,21 +376,6 @@ static void qmi_gprs_context_bind_mux(struct ofono_gprs_context *gc)
 	} __attribute__((packed)) endpoint_info;
 	uint8_t u8;
 
-	interface_number = ofono_modem_get_string(modem, "InterfaceNumber");
-	if (!interface_number) {
-		ofono_error("%s: Missing 'InterfaceNumber'",
-					ofono_modem_get_path(modem));
-		goto error;
-	}
-
-	if (l_safe_atox8(interface_number, &u8) < 0) {
-		ofono_error("%s: Invalid InterfaceNumber",
-					ofono_modem_get_path(modem));
-		goto error;
-	}
-
-	endpoint_info.interface_number = u8;
-
 	bus = ofono_modem_get_string(modem, "Bus");
 	if (!bus) {
 		ofono_error("%s: Missing 'Bus'", ofono_modem_get_path(modem));
@@ -409,6 +394,23 @@ static void qmi_gprs_context_bind_mux(struct ofono_gprs_context *gc)
 		goto error;
 	}
 
+	interface_number = ofono_modem_get_string(modem, "InterfaceNumber");
+	if (!interface_number && endpoint_info.endpoint_type !=
+					QMI_DATA_ENDPOINT_TYPE_EMBEDDED) {
+		ofono_error("%s: Missing 'InterfaceNumber'",
+					ofono_modem_get_path(modem));
+		goto error;
+	} else if (!interface_number)
+		u8 = 1;	/* Default for embedded modems */
+	else if (l_safe_atox8(interface_number, &u8) < 0) {
+		ofono_error("%s: Invalid InterfaceNumber",
+					ofono_modem_get_path(modem));
+		goto error;
+	}
+
+	endpoint_info.interface_number = u8;
+
+	DBG("interface_number: %d", u8);
 	DBG("mux_id: %hhx", data->mux_id);
 
 	param = qmi_param_new();
-- 
2.43.2


-- 


*Confidentiality Note:* We care about protecting our proprietary 
information, confidential material, and trade secrets. This message may 
contain some or all of those things. Cruise will suffer material harm if 
anyone other than the intended recipient disseminates or takes any action 
based on this message. If you have received this message (including any 
attachments) in error, please delete it immediately and notify the sender 
promptly.

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH v2 1/2] udevng: Detect embedded qmi QRTR modems
  2024-04-08 21:34 [PATCH v2 1/2] udevng: Detect embedded qmi QRTR modems Steve Schrock
  2024-04-08 21:34 ` [PATCH v2 2/2] qmimodem: Default embedded modems endpoint ID Steve Schrock
@ 2024-04-08 22:40 ` patchwork-bot+ofono
  1 sibling, 0 replies; 3+ messages in thread
From: patchwork-bot+ofono @ 2024-04-08 22:40 UTC (permalink / raw)
  To: Steve Schrock; +Cc: ofono

Hello:

This series was applied to ofono.git (master)
by Denis Kenzior <denkenz@gmail.com>:

On Mon,  8 Apr 2024 16:34:38 -0500 you wrote:
> Embedded qmi QRTR modems are identified by the existence of
> rmnet_ipaX and rmnet_dataX devices. Add a new "embedded" modem type
> so that these devices can be collected during enumeration and then
> configured for use by the gobi plugin. Modems of this type will be
> exposed as /gobiqrtr_X.
> ---
>  plugins/gobi.c   |  19 +++++++--
>  plugins/udevng.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++-
>  2 files changed, 119 insertions(+), 5 deletions(-)

Here is the summary with links:
  - [v2,1/2] udevng: Detect embedded qmi QRTR modems
    https://git.kernel.org/pub/scm/network/ofono/ofono.git/?id=296347f8a4f1
  - [v2,2/2] qmimodem: Default embedded modems endpoint ID
    https://git.kernel.org/pub/scm/network/ofono/ofono.git/?id=6d7edaf5bc5a

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2024-04-08 22:40 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-04-08 21:34 [PATCH v2 1/2] udevng: Detect embedded qmi QRTR modems Steve Schrock
2024-04-08 21:34 ` [PATCH v2 2/2] qmimodem: Default embedded modems endpoint ID Steve Schrock
2024-04-08 22:40 ` [PATCH v2 1/2] udevng: Detect embedded qmi QRTR modems patchwork-bot+ofono

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).