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 --- Notes: v2: - change expected timestamping flags to match kernel. tools/iso-tester.c | 10 +++++++++ tools/l2cap-tester.c | 15 ++++++++++++- tools/sco-tester.c | 14 ++++++++++++ tools/tester.h | 52 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 90 insertions(+), 1 deletion(-) 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..1ba7a01a2 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,50 @@ 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_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 (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(); +} -- 2.49.0