diff mbox series

[04/10] gobi: Detect qmi_wwan pass_through support

Message ID 20241121152949.56962-4-denkenz@gmail.com (mailing list archive)
State Accepted
Commit 87aff5f3a23b356f3e91df329c251bb400b298b2
Headers show
Series [01/10] qmi: wda: Add qmi_wda_set_data_format utility | expand

Commit Message

Denis Kenzior Nov. 21, 2024, 3:29 p.m. UTC
Detect the presence of 'pass_through' sysfs entry and record it in a
flag for future reference.  pass_through mode is used when QMI_WWAN and
rmnet interfaces are used in a multiplexed fashion.
---
 plugins/gobi.c | 35 ++++++++++++++++++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/plugins/gobi.c b/plugins/gobi.c
index 4af3f3846694..87b54ae05f17 100644
--- a/plugins/gobi.c
+++ b/plugins/gobi.c
@@ -15,6 +15,7 @@ 
 #include <stdlib.h>
 #include <stdio.h>
 #include <net/if.h>
+#include <sys/stat.h>
 
 #define OFONO_API_SUBJECT_TO_CHANGE
 #include <ofono/plugin.h>
@@ -59,6 +60,7 @@ 
 #define MAX_CONTEXTS 4
 
 #define QMI_WWAN_RAW_IP "/sys/class/net/%s/qmi/raw_ip"
+#define QMI_WWAN_PASS_THROUGH "/sys/class/net/%s/qmi/pass_through"
 
 enum wda_data_format {
 	WDA_DATA_FORMAT_UNKNOWN = 0,
@@ -98,6 +100,7 @@  struct gobi_data {
 	uint32_t set_powered_id;
 	enum wda_data_format data_format;
 	bool using_mux : 1;
+	bool no_pass_through : 1;
 };
 
 static void gobi_debug(const char *str, void *user_data)
@@ -136,6 +139,11 @@  static int qmi_wwan_set_raw_ip(const char *interface, char value)
 	return l_sysctl_set_char(value, QMI_WWAN_RAW_IP, interface);
 }
 
+static int qmi_wwan_set_pass_through(const char *interface, char value)
+{
+	return l_sysctl_set_char(value, QMI_WWAN_PASS_THROUGH, interface);
+}
+
 /*
  * Probe the modem.  The following modem properties are expected to be set
  * in order to initialize the driver properly:
@@ -165,6 +173,9 @@  static int gobi_probe(struct ofono_modem *modem)
 	uint8_t interface_number;
 	int ifindex;
 	const char *bus;
+	struct stat st;
+	_auto_(l_free) char *pass_through = NULL;
+	bool no_pass_through = false;
 
 	DBG("%p", modem);
 
@@ -189,10 +200,19 @@  static int gobi_probe(struct ofono_modem *modem)
 				&interface_number) < 0)
 		return -EINVAL;
 
+	pass_through = l_strdup_printf(QMI_WWAN_PASS_THROUGH, ifname);
+	if (stat(pass_through, &st) == -1) {
+		if (errno == ENOENT)
+			no_pass_through = true;
+		else
+			return -errno;
+	}
+
 	data = l_new(struct gobi_data, 1);
 	data->main_net_ifindex = ifindex;
 	l_strlcpy(data->main_net_name, ifname, sizeof(data->main_net_name));
 	data->interface_number = interface_number;
+	data->no_pass_through = no_pass_through;
 
 	ofono_modem_set_data(modem, data);
 	ofono_modem_set_capabilities(modem, OFONO_MODEM_CAPABILITY_LTE);
@@ -504,7 +524,11 @@  static void create_wda_cb(struct qmi_service *service, void *user_data)
 	}
 
 	data->wda = service;
-	data->data_format = WDA_DATA_FORMAT_UNKNOWN + 1;
+
+	if (data->no_pass_through)
+		data->data_format = WDA_DATA_FORMAT_802_3;
+	else
+		data->data_format = WDA_DATA_FORMAT_UNKNOWN + 1;
 
 	if (!wda_get_data_format(data, &format))
 		goto error;
@@ -604,6 +628,15 @@  static void init_powered_down_cb(int error, uint16_t type,
 
 	DBG("Setting QMI_WWAN to 802.3 mode");
 
+	/* Must set pass_through first, before toggling raw_ip */
+	if (!data->no_pass_through) {
+		r = qmi_wwan_set_pass_through(data->main_net_name, 'N');
+		if (r < 0) {
+			ofono_warn("Unable to reset pass_through");
+			goto error;
+		}
+	}
+
 	r = qmi_wwan_set_raw_ip(data->main_net_name, 'N');
 	if (r < 0) {
 		ofono_warn("Unable to reset raw_ip");