@@ -28,6 +28,12 @@ LOG_MODULE_REGISTER(siwx91x_wifi);
28
28
29
29
NET_BUF_POOL_FIXED_DEFINE (siwx91x_tx_pool , 1 , _NET_ETH_MAX_FRAME_SIZE , 0 , NULL );
30
30
31
+ enum {
32
+ REQUEST_TWT = 0 ,
33
+ SUGGEST_TWT = 1 ,
34
+ DEMAND_TWT = 2 ,
35
+ };
36
+
31
37
static int siwx91x_sl_to_z_mode (sl_wifi_interface_t interface )
32
38
{
33
39
switch (interface ) {
@@ -1067,6 +1073,137 @@ static int siwx91x_dev_init(const struct device *dev)
1067
1073
return 0 ;
1068
1074
}
1069
1075
1076
+ static int siwx91x_convert_z_sl_twt_req_type (enum wifi_twt_setup_cmd z_req_cmd )
1077
+ {
1078
+ switch (z_req_cmd ) {
1079
+ case WIFI_TWT_SETUP_CMD_REQUEST :
1080
+ return REQUEST_TWT ;
1081
+ case WIFI_TWT_SETUP_CMD_SUGGEST :
1082
+ return SUGGEST_TWT ;
1083
+ case WIFI_TWT_SETUP_CMD_DEMAND :
1084
+ return DEMAND_TWT ;
1085
+ default :
1086
+ return - EINVAL ;
1087
+ }
1088
+ }
1089
+
1090
+ static int siwx91x_set_twt_setup (struct wifi_twt_params * params )
1091
+ {
1092
+ sl_status_t status ;
1093
+ int twt_req_type = siwx91x_convert_z_sl_twt_req_type (params -> setup_cmd );
1094
+
1095
+ sl_wifi_twt_request_t twt_req = {
1096
+ .wake_duration_unit = 0 ,
1097
+ .wake_int_mantissa = params -> setup .twt_mantissa ,
1098
+ .un_announced_twt = !params -> setup .announce ,
1099
+ .wake_duration = params -> setup .twt_wake_interval ,
1100
+ .triggered_twt = params -> setup .trigger ,
1101
+ .wake_int_exp = params -> setup .twt_exponent ,
1102
+ .implicit_twt = 1 ,
1103
+ .twt_flow_id = params -> flow_id ,
1104
+ .twt_enable = 1 ,
1105
+ .req_type = twt_req_type ,
1106
+ };
1107
+
1108
+ if (twt_req_type < 0 ) {
1109
+ params -> fail_reason = WIFI_TWT_FAIL_CMD_EXEC_FAIL ;
1110
+ return - EINVAL ;
1111
+ }
1112
+
1113
+ if (!params -> setup .twt_info_disable ) {
1114
+ params -> fail_reason = WIFI_TWT_FAIL_OPERATION_NOT_SUPPORTED ;
1115
+ return - ENOTSUP ;
1116
+ }
1117
+
1118
+ if (params -> setup .responder ) {
1119
+ params -> fail_reason = WIFI_TWT_FAIL_OPERATION_NOT_SUPPORTED ;
1120
+ return - ENOTSUP ;
1121
+ }
1122
+
1123
+ /* implicit -> won't do renegotiation
1124
+ * explicit -> must do renegotiation for each session
1125
+ */
1126
+ if (!params -> setup .implicit ) {
1127
+ /* explicit twt is not supported */
1128
+ params -> fail_reason = WIFI_TWT_FAIL_OPERATION_NOT_SUPPORTED ;
1129
+ return - ENOTSUP ;
1130
+ }
1131
+
1132
+ if (params -> setup .twt_wake_interval > 255 * 256 ) {
1133
+ twt_req .wake_duration_unit = 1 ;
1134
+ twt_req .wake_duration = params -> setup .twt_wake_interval / 256 ;
1135
+ } else {
1136
+ twt_req .wake_duration_unit = 0 ;
1137
+ twt_req .wake_duration = params -> setup .twt_wake_interval / 1024 ;
1138
+ }
1139
+
1140
+ status = sl_wifi_enable_target_wake_time (& twt_req );
1141
+ if (status != SL_STATUS_OK ) {
1142
+ params -> fail_reason = WIFI_TWT_FAIL_CMD_EXEC_FAIL ;
1143
+ params -> resp_status = WIFI_TWT_RESP_NOT_RECEIVED ;
1144
+ return - EINVAL ;
1145
+ }
1146
+
1147
+ return 0 ;
1148
+ }
1149
+
1150
+ static int siwx91x_set_twt_teardown (struct wifi_twt_params * params )
1151
+ {
1152
+ sl_status_t status ;
1153
+ sl_wifi_twt_request_t twt_req = { };
1154
+
1155
+ twt_req .twt_enable = 0 ;
1156
+
1157
+ if (params -> teardown .teardown_all ) {
1158
+ twt_req .twt_flow_id = 0xFF ;
1159
+ } else {
1160
+ twt_req .twt_flow_id = params -> flow_id ;
1161
+ }
1162
+
1163
+ status = sl_wifi_disable_target_wake_time (& twt_req );
1164
+ if (status != SL_STATUS_OK ) {
1165
+ params -> fail_reason = WIFI_TWT_FAIL_CMD_EXEC_FAIL ;
1166
+ params -> teardown_status = WIFI_TWT_TEARDOWN_FAILED ;
1167
+ return - EINVAL ;
1168
+ }
1169
+
1170
+ params -> teardown_status = WIFI_TWT_TEARDOWN_SUCCESS ;
1171
+
1172
+ return 0 ;
1173
+ }
1174
+
1175
+ static int siwx91x_set_twt (const struct device * dev , struct wifi_twt_params * params )
1176
+ {
1177
+ sl_wifi_interface_t interface = sl_wifi_get_default_interface ();
1178
+ struct siwx91x_dev * sidev = dev -> data ;
1179
+
1180
+ __ASSERT (params , "params cannot be a NULL" );
1181
+
1182
+ if (FIELD_GET (SIWX91X_INTERFACE_MASK , interface ) != SL_WIFI_CLIENT_INTERFACE ) {
1183
+ params -> fail_reason = WIFI_TWT_FAIL_OPERATION_NOT_SUPPORTED ;
1184
+ return - ENOTSUP ;
1185
+ }
1186
+
1187
+ if (sidev -> state != WIFI_STATE_DISCONNECTED && sidev -> state != WIFI_STATE_INACTIVE &&
1188
+ sidev -> state != WIFI_STATE_COMPLETED ) {
1189
+ LOG_ERR ("Command given in invalid state" );
1190
+ return - EBUSY ;
1191
+ }
1192
+
1193
+ if (params -> negotiation_type != WIFI_TWT_INDIVIDUAL ) {
1194
+ params -> fail_reason = WIFI_TWT_FAIL_OPERATION_NOT_SUPPORTED ;
1195
+ return - ENOTSUP ;
1196
+ }
1197
+
1198
+ if (params -> operation == WIFI_TWT_SETUP ) {
1199
+ return siwx91x_set_twt_setup (params );
1200
+ } else if (params -> operation == WIFI_TWT_TEARDOWN ) {
1201
+ return siwx91x_set_twt_teardown (params );
1202
+ }
1203
+ params -> fail_reason = WIFI_TWT_FAIL_OPERATION_NOT_SUPPORTED ;
1204
+ return - ENOTSUP ;
1205
+ }
1206
+
1070
1207
static const struct wifi_mgmt_ops siwx91x_mgmt = {
1071
1208
.scan = siwx91x_scan ,
1072
1209
.connect = siwx91x_connect ,
@@ -1076,6 +1213,7 @@ static const struct wifi_mgmt_ops siwx91x_mgmt = {
1076
1213
.ap_sta_disconnect = siwx91x_ap_sta_disconnect ,
1077
1214
.iface_status = siwx91x_status ,
1078
1215
.mode = siwx91x_mode ,
1216
+ .set_twt = siwx91x_set_twt ,
1079
1217
#if defined(CONFIG_NET_STATISTICS_WIFI )
1080
1218
.get_stats = siwx91x_stats ,
1081
1219
#endif
0 commit comments