diff mbox series

[BlueZ] tools: add tests for SIOCETHTOOL ETHTOOL_GET_TS_INFO

Message ID 34c98b16c31ff4e5eb1a6d23326e7e2d7763a0ee.1745272994.git.pav@iki.fi
State New
Headers show
Series [BlueZ] tools: add tests for SIOCETHTOOL ETHTOOL_GET_TS_INFO | expand

Commit Message

Pauli Virtanen April 21, 2025, 10:03 p.m. UTC
Add tests for obtaining timestamping capabilities via ethtool ioctl:

L2CAP BR/EDR Ethtool Get Ts Info - Success
L2CAP LE Ethtool Get Ts Info - Success
SCO Ethtool Get Ts Info - Success
SCO Ethtool Get Ts Info No Flowctl - Success
ISO Ethtool Get Ts Info - Success
---
 tools/iso-tester.c   | 10 ++++++++
 tools/l2cap-tester.c | 15 +++++++++++-
 tools/sco-tester.c   | 14 +++++++++++
 tools/tester.h       | 57 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 95 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/tools/iso-tester.c b/tools/iso-tester.c
index 63f6951e3..96467a973 100644
--- a/tools/iso-tester.c
+++ b/tools/iso-tester.c
@@ -3495,6 +3495,13 @@  static void test_connect2_suspend(const void *test_data)
 	trigger_force_suspend((void *)test_data);
 }
 
+static void test_iso_ethtool_get_ts_info(const void *test_data)
+{
+	struct test_data *data = tester_get_data();
+
+	test_ethtool_get_ts_info(data->mgmt_index, BTPROTO_ISO, false);
+}
+
 int main(int argc, char *argv[])
 {
 	tester_init(&argc, &argv);
@@ -3919,5 +3926,8 @@  int main(int argc, char *argv[])
 	test_iso("ISO Broadcaster AC 14 - Success", &bcast_ac_14, setup_powered,
 							test_bcast);
 
+	test_iso("ISO Ethtool Get Ts Info - Success", NULL, setup_powered,
+						test_iso_ethtool_get_ts_info);
+
 	return tester_run();
 }
diff --git a/tools/l2cap-tester.c b/tools/l2cap-tester.c
index 41ef62578..53b7d6f1a 100644
--- a/tools/l2cap-tester.c
+++ b/tools/l2cap-tester.c
@@ -994,7 +994,7 @@  static void setup_powered_server_callback(uint8_t status, uint16_t length,
 
 	tester_print("Controller powered on");
 
-	if (!test->enable_ssp) {
+	if (!test || !test->enable_ssp) {
 		tester_setup_complete();
 		return;
 	}
@@ -2494,6 +2494,13 @@  done:
 	close(sk);
 }
 
+static void test_l2cap_ethtool_get_ts_info(const void *test_data)
+{
+	struct test_data *data = tester_get_data();
+
+	test_ethtool_get_ts_info(data->mgmt_index, BTPROTO_L2CAP, false);
+}
+
 int main(int argc, char *argv[])
 {
 	tester_init(&argc, &argv);
@@ -2604,6 +2611,9 @@  int main(int argc, char *argv[])
 				&l2cap_server_nval_cid_test2,
 				setup_powered_server, test_server);
 
+	test_l2cap_bredr("L2CAP BR/EDR Ethtool Get Ts Info - Success", NULL,
+			setup_powered_server, test_l2cap_ethtool_get_ts_info);
+
 	test_l2cap_le("L2CAP LE Client - Success",
 				&le_client_connect_success_test_1,
 				setup_powered_client, test_connect);
@@ -2723,5 +2733,8 @@  int main(int argc, char *argv[])
 				&le_eatt_server_reject_test_1,
 				setup_powered_server, test_server);
 
+	test_l2cap_le("L2CAP LE Ethtool Get Ts Info - Success", NULL,
+			setup_powered_server, test_l2cap_ethtool_get_ts_info);
+
 	return tester_run();
 }
diff --git a/tools/sco-tester.c b/tools/sco-tester.c
index 650f8bab3..8db424815 100644
--- a/tools/sco-tester.c
+++ b/tools/sco-tester.c
@@ -1098,6 +1098,14 @@  static void test_connect_acl_disc(const void *test_data)
 	test_connect(test_data);
 }
 
+static void test_sco_ethtool_get_ts_info(const void *test_data)
+{
+	struct test_data *data = tester_get_data();
+
+	test_ethtool_get_ts_info(data->mgmt_index, BTPROTO_SCO,
+				!data->disable_sco_flowctl);
+}
+
 int main(int argc, char *argv[])
 {
 	tester_init(&argc, &argv);
@@ -1166,5 +1174,11 @@  int main(int argc, char *argv[])
 	test_offload_sco("eSCO mSBC - Offload - Success",
 		&connect_success, setup_powered, test_connect_offload_msbc);
 
+	test_sco("SCO Ethtool Get Ts Info - Success",
+			NULL, setup_powered, test_sco_ethtool_get_ts_info);
+
+	test_sco_no_flowctl("SCO Ethtool Get Ts Info No Flowctl - Success",
+			NULL, setup_powered, test_sco_ethtool_get_ts_info);
+
 	return tester_run();
 }
diff --git a/tools/tester.h b/tools/tester.h
index 4e7d7226b..241fba559 100644
--- a/tools/tester.h
+++ b/tools/tester.h
@@ -15,6 +15,11 @@ 
 #include <linux/errqueue.h>
 #include <linux/net_tstamp.h>
 
+#include <linux/ethtool.h>
+#include <linux/sockios.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+
 #include <glib.h>
 
 #define SEC_NSEC(_t)  ((_t) * 1000000000LL)
@@ -198,3 +203,55 @@  static inline int tx_tstamp_recv(struct tx_tstamp_data *data, int sk, int len)
 
 	return data->count - data->pos;
 }
+
+static inline void test_ethtool_get_ts_info(unsigned int index, int proto,
+							bool sco_flowctl)
+{
+	struct ifreq ifr = {};
+	struct ethtool_ts_info cmd = {};
+	uint32_t so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE |
+		SOF_TIMESTAMPING_RX_SOFTWARE |
+		SOF_TIMESTAMPING_SOFTWARE |
+		SOF_TIMESTAMPING_OPT_ID |
+		SOF_TIMESTAMPING_OPT_CMSG |
+		SOF_TIMESTAMPING_OPT_TSONLY |
+		SOF_TIMESTAMPING_TX_COMPLETION;
+	int sk;
+
+	sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, proto);
+	if (sk < 0) {
+		if (sk == -EPROTONOSUPPORT)
+			tester_test_abort();
+		else
+			tester_test_failed();
+		return;
+	}
+
+	snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "hci%u", index);
+	ifr.ifr_data = (void *)&cmd;
+	cmd.cmd = ETHTOOL_GET_TS_INFO;
+
+	if (ioctl(sk, SIOCETHTOOL, &ifr) == -1) {
+		tester_warn("SIOCETHTOOL failed");
+		tester_test_failed();
+		return;
+	}
+	close(sk);
+
+	if (proto == BTPROTO_SCO && !sco_flowctl)
+		so_timestamping &= ~SOF_TIMESTAMPING_TX_COMPLETION;
+	if (proto == BTPROTO_L2CAP)
+		so_timestamping &= ~SOF_TIMESTAMPING_RX_SOFTWARE;
+
+	if (cmd.cmd != ETHTOOL_GET_TS_INFO ||
+			cmd.so_timestamping != so_timestamping ||
+			cmd.phc_index != -1 ||
+			cmd.tx_types != (1 << HWTSTAMP_TX_OFF) ||
+			cmd.rx_filters != (1 << HWTSTAMP_FILTER_NONE)) {
+		tester_warn("bad ethtool_ts_info");
+		tester_test_failed();
+		return;
+	}
+
+	tester_test_passed();
+}