[9610] wlbt: SCSC Driver version 10.9.1.0
[GitHub/LineageOS/android_kernel_motorola_exynos9610.git] / drivers / net / wireless / scsc / nl80211_vendor_nan.c
CommitLineData
533a23a1
TK
1/*****************************************************************************
2 *
3 * Copyright (c) 2014 - 2019 Samsung Electronics Co., Ltd. All rights reserved
4 *
5 ****************************************************************************/
6
7#include "cfg80211_ops.h"
8#include "debug.h"
9#include "mgt.h"
10#include "mlme.h"
11
12struct net_device *slsi_nan_get_netdev(struct slsi_dev *sdev)
13{
14#if CONFIG_SCSC_WLAN_MAX_INTERFACES >= 4
781f598d
TK
15 if (sdev->recovery_status)
16 return slsi_get_netdev_locked(sdev, SLSI_NET_INDEX_NAN);
533a23a1
TK
17 return slsi_get_netdev(sdev, SLSI_NET_INDEX_NAN);
18#else
19 return NULL;
20#endif
21}
22
23static int slsi_nan_get_new_id(u32 id_map, int max_ids)
24{
25 int i;
26
27 for (i = 1; i <= max_ids; i++) {
28 if (!(id_map & BIT(i)))
29 return i;
30 }
31 return 0;
32}
33
34static int slsi_nan_get_new_publish_id(struct netdev_vif *ndev_vif)
35{
781f598d
TK
36 WARN_ON(!SLSI_MUTEX_IS_LOCKED(ndev_vif->vif_mutex));
37 return slsi_nan_get_new_id(ndev_vif->nan.service_id_map, SLSI_NAN_MAX_SERVICE_ID);
533a23a1
TK
38}
39
40static int slsi_nan_get_new_subscribe_id(struct netdev_vif *ndev_vif)
41{
781f598d
TK
42 WARN_ON(!SLSI_MUTEX_IS_LOCKED(ndev_vif->vif_mutex));
43 return slsi_nan_get_new_id(ndev_vif->nan.service_id_map, SLSI_NAN_MAX_SERVICE_ID);
533a23a1
TK
44}
45
46static bool slsi_nan_is_publish_id_active(struct netdev_vif *ndev_vif, u32 id)
47{
781f598d
TK
48 WARN_ON(!SLSI_MUTEX_IS_LOCKED(ndev_vif->vif_mutex));
49 return ndev_vif->nan.service_id_map & BIT(id);
533a23a1
TK
50}
51
52static bool slsi_nan_is_subscribe_id_active(struct netdev_vif *ndev_vif, u32 id)
53{
781f598d
TK
54 WARN_ON(!SLSI_MUTEX_IS_LOCKED(ndev_vif->vif_mutex));
55 return ndev_vif->nan.service_id_map & BIT(id);
56}
57
58static int slsi_nan_get_new_ndp_id(struct netdev_vif *ndev_vif)
59{
60 WARN_ON(!SLSI_MUTEX_IS_LOCKED(ndev_vif->vif_mutex));
61 return slsi_nan_get_new_id(ndev_vif->nan.ndp_id_map, SLSI_NAN_MAX_NDP_INSTANCES);
62}
63
64static void slsi_nan_pre_check(struct slsi_dev *sdev, struct net_device *dev, int *ret, int *reply_status)
65{
66 *ret = WIFI_HAL_SUCCESS;
67 *reply_status = SLSI_HAL_NAN_STATUS_SUCCESS;
68 if (!dev) {
69 SLSI_ERR(sdev, "No NAN interface\n");
70 *ret = -WIFI_HAL_ERROR_NOT_SUPPORTED;
71 *reply_status = SLSI_HAL_NAN_STATUS_NAN_NOT_ALLOWED;
72 }
73
74 if (!slsi_dev_nan_supported(sdev)) {
75 SLSI_ERR(sdev, "NAN not allowed(mib:%d)\n", sdev->nan_enabled);
76 *ret = WIFI_HAL_ERROR_NOT_SUPPORTED;
77 *reply_status = SLSI_HAL_NAN_STATUS_NAN_NOT_ALLOWED;
78 }
79}
80
81int slsi_nan_ndp_new_entry(struct slsi_dev *sdev, struct net_device *dev, u32 ndp_id,
82 u16 ndl_vif_id, u8 *local_ndi, u8 *peer_nmi)
83{
84 struct netdev_vif *ndev_vif = netdev_priv(dev);
85 u16 ndl_id;
86
87 WARN_ON(!SLSI_MUTEX_IS_LOCKED(ndev_vif->vif_mutex));
88
89 if (ndl_vif_id < SLSI_NAN_DATA_IFINDEX_START ||
90 ndl_vif_id >= SLSI_NAN_DATA_IFINDEX_START + SLSI_NAN_MAX_NDP_INSTANCES) {
91 SLSI_ERR(sdev, "Invalid ndl_vif:%d\n", ndl_vif_id);
92 return 1;
93 }
94
95 if (ndp_id == 0 || ndp_id > SLSI_NAN_MAX_NDP_INSTANCES) {
96 SLSI_ERR(sdev, "Invalid ndp:%d\n", ndp_id);
97 return 1;
98 }
99
100 ndl_id = ndl_vif_id - SLSI_NAN_DATA_IFINDEX_START;
101 if (ndev_vif->nan.ndl_list[ndl_id].ndp_count < 0 ||
102 ndev_vif->nan.ndl_list[ndl_id].ndp_count > SLSI_NAN_MAX_NDP_INSTANCES) {
103 SLSI_WARN(sdev, "improper ndp count(%d) for vif_id(%d)\n",
104 ndev_vif->nan.ndl_list[ndl_id].ndp_count, ndl_vif_id);
105 }
106
107 ndev_vif->nan.ndp_id_map |= (u32)BIT(ndp_id);
108 if (peer_nmi)
109 ether_addr_copy(ndev_vif->nan.ndl_list[ndl_id].peer_nmi, peer_nmi);
110 ndev_vif->nan.ndl_list[ndl_id].ndp_count++;
111 if (local_ndi)
112 ether_addr_copy(ndev_vif->nan.ndp_ndi[ndp_id - 1], local_ndi);
113 ndev_vif->nan.ndp_id2ndl_vif[ndp_id - 1] = ndl_vif_id;
114 ndev_vif->nan.ndp_state[ndp_id - 1] = ndp_slot_status_in_use;
115 return 0;
116}
117
118void slsi_nan_ndp_del_entry(struct slsi_dev *sdev, struct net_device *dev, u32 ndp_id)
119{
120 struct netdev_vif *ndev_vif = netdev_priv(dev);
121 u16 ndl_vif_id, ndl_id;
122
123 WARN_ON(!SLSI_MUTEX_IS_LOCKED(ndev_vif->vif_mutex));
124
125 if (ndp_id == 0 || ndp_id > SLSI_NAN_MAX_NDP_INSTANCES) {
126 SLSI_WARN(sdev, "Invalid ndp:%d\n", ndp_id);
127 return;
128 }
129
130 ndl_vif_id = ndev_vif->nan.ndp_id2ndl_vif[ndp_id - 1];
131 if (ndl_vif_id < SLSI_NAN_DATA_IFINDEX_START ||
132 ndl_vif_id >= SLSI_NAN_DATA_IFINDEX_START + SLSI_NAN_MAX_NDP_INSTANCES) {
133 SLSI_WARN(sdev, "Invalid ndl_vif:%d\n", ndl_vif_id);
134 return;
135 }
136
137 ndl_id = ndl_vif_id - SLSI_NAN_DATA_IFINDEX_START;
138 ndev_vif->nan.ndp_id_map &= ~(u32)BIT(ndp_id);
139 ndev_vif->nan.ndl_list[ndl_id].ndp_count--;
140 if (ndev_vif->nan.ndl_list[ndl_id].ndp_count == 0)
141 slsi_eth_zero_addr(ndev_vif->nan.ndl_list[ndl_id].peer_nmi);
142 ndev_vif->nan.ndp_id2ndl_vif[ndp_id - 1] = 0;
143 slsi_eth_zero_addr(ndev_vif->nan.ndp_ndi[ndp_id - 1]);
144 if (ndev_vif->nan.ndl_list[ndl_id].ndp_count < 0)
145 SLSI_WARN(sdev, "ndp_count is negative %d for ndl idx %d\n",
146 ndev_vif->nan.ndl_list[ndl_id].ndp_count, ndl_id);
147 ndev_vif->nan.ndp_state[ndp_id - 1] = ndp_slot_status_free;
148}
149
150u16 slsi_nan_ndp_get_ndl_vif_id(u8 *peer_mni, struct slsi_nan_ndl_info *ndl_list)
151{
152 u16 i, free_idx = SLSI_NAN_MAX_NDP_INSTANCES + SLSI_NAN_DATA_IFINDEX_START;
153
154 for (i = 0; i < SLSI_NAN_MAX_NDP_INSTANCES; i++) {
155 if (ether_addr_equal(peer_mni, ndl_list[i].peer_nmi))
156 return i + SLSI_NAN_DATA_IFINDEX_START;
157 if (free_idx == SLSI_NAN_MAX_NDP_INSTANCES + SLSI_NAN_DATA_IFINDEX_START &&
158 ndl_list[i].ndp_count == 0)
159 free_idx = i + SLSI_NAN_DATA_IFINDEX_START;
160 }
161 return free_idx;
533a23a1
TK
162}
163
164void slsi_nan_get_mac(struct slsi_dev *sdev, char *nan_mac_addr)
165{
166 memset(nan_mac_addr, 0, ETH_ALEN);
167#if CONFIG_SCSC_WLAN_MAX_INTERFACES >= 4
168 if (slsi_dev_nan_supported(sdev))
169 ether_addr_copy(nan_mac_addr, sdev->netdev_addresses[SLSI_NET_INDEX_NAN]);
170#endif
171}
172
173static void slsi_vendor_nan_command_reply(struct wiphy *wiphy, u32 status, u32 error, u32 response_type,
781f598d 174 u16 id, struct slsi_hal_nan_capabilities *capabilities, u16 req_id)
533a23a1
TK
175{
176 int reply_len;
177 struct sk_buff *reply;
178
179 reply_len = SLSI_NL_VENDOR_REPLY_OVERHEAD + SLSI_NL_ATTRIBUTE_U32_LEN *
180 (3 + sizeof(struct slsi_hal_nan_capabilities));
181 reply = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, reply_len);
182 if (!reply) {
183 SLSI_WARN_NODEV("SKB alloc failed for vendor_cmd reply\n");
184 return;
185 }
186
187 nla_put_u32(reply, NAN_REPLY_ATTR_STATUS_TYPE, status);
188 nla_put_u32(reply, NAN_REPLY_ATTR_VALUE, error);
189 nla_put_u32(reply, NAN_REPLY_ATTR_RESPONSE_TYPE, response_type);
781f598d 190 nla_put_u16(reply, NAN_REPLY_ATTR_HAL_TRANSACTION_ID, req_id);
533a23a1
TK
191
192 if (capabilities) {
193 nla_put_u32(reply, NAN_REPLY_ATTR_CAP_MAX_CONCURRENT_CLUSTER,
194 capabilities->max_concurrent_nan_clusters);
195 nla_put_u32(reply, NAN_REPLY_ATTR_CAP_MAX_PUBLISHES, capabilities->max_publishes);
196 nla_put_u32(reply, NAN_REPLY_ATTR_CAP_MAX_SUBSCRIBES, capabilities->max_subscribes);
197 nla_put_u32(reply, NAN_REPLY_ATTR_CAP_MAX_SERVICE_NAME_LEN, capabilities->max_service_name_len);
198 nla_put_u32(reply, NAN_REPLY_ATTR_CAP_MAX_MATCH_FILTER_LEN, capabilities->max_match_filter_len);
199 nla_put_u32(reply, NAN_REPLY_ATTR_CAP_MAX_TOTAL_MATCH_FILTER_LEN,
200 capabilities->max_total_match_filter_len);
201 nla_put_u32(reply, NAN_REPLY_ATTR_CAP_MAX_SERVICE_SPECIFIC_INFO_LEN,
202 capabilities->max_service_specific_info_len);
203 nla_put_u32(reply, NAN_REPLY_ATTR_CAP_MAX_VSA_DATA_LEN, capabilities->max_vsa_data_len);
204 nla_put_u32(reply, NAN_REPLY_ATTR_CAP_MAX_MESH_DATA_LEN, capabilities->max_mesh_data_len);
205 nla_put_u32(reply, NAN_REPLY_ATTR_CAP_MAX_NDI_INTERFACES, capabilities->max_ndi_interfaces);
206 nla_put_u32(reply, NAN_REPLY_ATTR_CAP_MAX_NDP_SESSIONS, capabilities->max_ndp_sessions);
207 nla_put_u32(reply, NAN_REPLY_ATTR_CAP_MAX_APP_INFO_LEN, capabilities->max_app_info_len);
781f598d
TK
208 } else if (id) {
209 if (response_type < NAN_DP_INTERFACE_CREATE)
210 nla_put_u16(reply, NAN_REPLY_ATTR_PUBLISH_SUBSCRIBE_TYPE, id);
211 else
212 nla_put_u16(reply, NAN_REPLY_ATTR_NDP_INSTANCE_ID, id);
533a23a1
TK
213 }
214
215 if (cfg80211_vendor_cmd_reply(reply))
216 SLSI_ERR_NODEV("FAILED to reply nan coammnd. response_type:%d\n", response_type);
217}
218
219static int slsi_nan_get_sdea_params_nl(struct slsi_dev *sdev, struct slsi_nan_sdea_ctrl_params *sdea_params,
220 const struct nlattr *iter, int nl_attr_id)
221{
222 switch (nl_attr_id) {
223 case NAN_REQ_ATTR_SDEA_PARAM_NDP_TYPE:
224 sdea_params->ndp_type = nla_get_u8(iter);
225 sdea_params->config_nan_data_path = 1;
226 break;
227 case NAN_REQ_ATTR_SDEA_PARAM_SECURITY_CFG:
228 sdea_params->security_cfg = nla_get_u8(iter);
229 sdea_params->config_nan_data_path = 1;
230 break;
231 case NAN_REQ_ATTR_SDEA_PARAM_RANGING_STATE:
232 sdea_params->ranging_state = nla_get_u8(iter);
233 sdea_params->config_nan_data_path = 1;
234 break;
235 case NAN_REQ_ATTR_SDEA_PARAM_RANGE_REPORT:
236 sdea_params->range_report = nla_get_u8(iter);
237 sdea_params->config_nan_data_path = 1;
238 break;
239 case NAN_REQ_ATTR_SDEA_PARAM_QOS_CFG:
240 sdea_params->qos_cfg = nla_get_u8(iter);
241 sdea_params->config_nan_data_path = 1;
242 break;
243 default:
244 return -EINVAL;
245 }
246 return 0;
247}
248
249static int slsi_nan_get_ranging_cfg_nl(struct slsi_dev *sdev, struct slsi_nan_ranging_cfg *ranging_cfg,
250 const struct nlattr *iter, int nl_attr_id)
251{
252 switch (nl_attr_id) {
253 case NAN_REQ_ATTR_RANGING_CFG_INTERVAL:
254 ranging_cfg->ranging_interval_msec = nla_get_u32(iter);
255 break;
256 case NAN_REQ_ATTR_RANGING_CFG_INDICATION:
257 ranging_cfg->config_ranging_indications = nla_get_u32(iter);
258 break;
259 case NAN_REQ_ATTR_RANGING_CFG_INGRESS_MM:
260 ranging_cfg->distance_ingress_mm = nla_get_u32(iter);
261 break;
262 case NAN_REQ_ATTR_RANGING_CFG_EGRESS_MM:
263 ranging_cfg->distance_egress_mm = nla_get_u32(iter);
264 break;
265 default:
266 return -EINVAL;
267 }
268 return 0;
269}
270
271static int slsi_nan_get_security_info_nl(struct slsi_dev *sdev, struct slsi_nan_security_info *sec_info,
272 const struct nlattr *iter, int nl_attr_id)
273{
274 u32 len = 0;
275
276 switch (nl_attr_id) {
277 case NAN_REQ_ATTR_CIPHER_TYPE:
278 sec_info->cipher_type = nla_get_u32(iter);
279 break;
280 case NAN_REQ_ATTR_SECURITY_KEY_TYPE:
281 sec_info->key_info.key_type = nla_get_u8(iter);
282 break;
283 case NAN_REQ_ATTR_SECURITY_PMK_LEN:
284 len = nla_get_u32(iter);
285 sec_info->key_info.body.pmk_info.pmk_len = len;
286 break;
287 case NAN_REQ_ATTR_SECURITY_PMK:
288 memcpy(sec_info->key_info.body.pmk_info.pmk, nla_data(iter), len);
289 break;
290 case NAN_REQ_ATTR_SECURITY_PASSPHRASE_LEN:
291 len = nla_get_u32(iter);
292 sec_info->key_info.body.passphrase_info.passphrase_len = len;
293 break;
294 case NAN_REQ_ATTR_SECURITY_PASSPHRASE:
295 memcpy(sec_info->key_info.body.passphrase_info.passphrase, nla_data(iter), len);
296 break;
297 case NAN_REQ_ATTR_SCID_LEN:
298 sec_info->scid_len = nla_get_u32(iter);
299 break;
300 case NAN_REQ_ATTR_SCID:
781f598d
TK
301 if (sec_info->scid_len > sizeof(sec_info->scid))
302 sec_info->scid_len = sizeof(sec_info->scid);
533a23a1
TK
303 memcpy(sec_info->scid, nla_data(iter), sec_info->scid_len);
304 break;
305 default:
306 return -EINVAL;
307 }
308 return 0;
309}
310
311static int slsi_nan_get_range_resp_cfg_nl(struct slsi_dev *sdev, struct slsi_nan_range_response_cfg *cfg,
312 const struct nlattr *iter, int nl_attr_id)
313{
314 switch (nl_attr_id) {
315 case NAN_REQ_ATTR_RANGE_RESPONSE_CFG_PUBLISH_ID:
316 cfg->publish_id = nla_get_u16(iter);
317 break;
318
319 case NAN_REQ_ATTR_RANGE_RESPONSE_CFG_REQUESTOR_ID:
320 cfg->requestor_instance_id = nla_get_u32(iter);
321 break;
322
323 case NAN_REQ_ATTR_RANGE_RESPONSE_CFG_PEER_ADDR:
324 memcpy(cfg->peer_addr, nla_data(iter), ETH_ALEN);
325 break;
326
327 case NAN_REQ_ATTR_RANGE_RESPONSE_CFG_RANGING_RESPONSE:
328 cfg->ranging_response = nla_get_u8(iter);
329 break;
330
331 default:
332 return -EINVAL;
333 }
334 return 0;
335}
336
781f598d
TK
337/* NAN HAL REQUESTS */
338
533a23a1
TK
339static int slsi_nan_enable_get_nl_params(struct slsi_dev *sdev, struct slsi_hal_nan_enable_req *hal_req,
340 const void *data, int len)
341{
342 int type, tmp;
343 const struct nlattr *iter;
344
345 memset(hal_req, 0, sizeof(*hal_req));
346 nla_for_each_attr(iter, data, len, tmp) {
347 type = nla_type(iter);
348 switch (type) {
349 case NAN_REQ_ATTR_MASTER_PREF:
350 hal_req->master_pref = nla_get_u8(iter);
351 break;
352
353 case NAN_REQ_ATTR_CLUSTER_LOW:
354 hal_req->cluster_low = nla_get_u16(iter);
355 break;
356
357 case NAN_REQ_ATTR_CLUSTER_HIGH:
358 hal_req->cluster_high = nla_get_u16(iter);
359 break;
360
361 case NAN_REQ_ATTR_SUPPORT_5G_VAL:
362 hal_req->support_5g_val = nla_get_u8(iter);
363 hal_req->config_support_5g = 1;
364 break;
365
366 case NAN_REQ_ATTR_SID_BEACON_VAL:
367 hal_req->sid_beacon_val = nla_get_u8(iter);
368 hal_req->config_sid_beacon = 1;
369 break;
370
371 case NAN_REQ_ATTR_RSSI_CLOSE_2G4_VAL:
372 hal_req->rssi_close_2dot4g_val = nla_get_u8(iter);
373 hal_req->config_2dot4g_rssi_close = 1;
374 break;
375
376 case NAN_REQ_ATTR_RSSI_MIDDLE_2G4_VAL:
377 hal_req->rssi_middle_2dot4g_val = nla_get_u8(iter);
378 hal_req->config_2dot4g_rssi_middle = 1;
379 break;
380
381 case NAN_REQ_ATTR_RSSI_PROXIMITY_2G4_VAL:
382 hal_req->rssi_proximity_2dot4g_val = nla_get_u8(iter);
383 hal_req->config_2dot4g_rssi_proximity = 1;
384 break;
385
386 case NAN_REQ_ATTR_HOP_COUNT_LIMIT_VAL:
387 hal_req->hop_count_limit_val = nla_get_u8(iter);
388 hal_req->config_hop_count_limit = 1;
389 break;
390
391 case NAN_REQ_ATTR_SUPPORT_2G4_VAL:
392 hal_req->support_2dot4g_val = nla_get_u8(iter);
393 hal_req->config_2dot4g_support = 1;
394 break;
395
396 case NAN_REQ_ATTR_BEACONS_2G4_VAL:
397 hal_req->beacon_2dot4g_val = nla_get_u8(iter);
398 hal_req->config_2dot4g_beacons = 1;
399 break;
400
401 case NAN_REQ_ATTR_SDF_2G4_VAL:
402 hal_req->sdf_2dot4g_val = nla_get_u8(iter);
403 hal_req->config_2dot4g_sdf = 1;
404 break;
405
406 case NAN_REQ_ATTR_BEACON_5G_VAL:
407 hal_req->beacon_5g_val = nla_get_u8(iter);
408 hal_req->config_5g_beacons = 1;
409 break;
410
411 case NAN_REQ_ATTR_SDF_5G_VAL:
412 hal_req->sdf_5g_val = nla_get_u8(iter);
413 hal_req->config_5g_sdf = 1;
414 break;
415
416 case NAN_REQ_ATTR_RSSI_CLOSE_5G_VAL:
417 hal_req->rssi_close_5g_val = nla_get_u8(iter);
418 hal_req->config_5g_rssi_close = 1;
419 break;
420
421 case NAN_REQ_ATTR_RSSI_MIDDLE_5G_VAL:
422 hal_req->rssi_middle_5g_val = nla_get_u8(iter);
423 hal_req->config_5g_rssi_middle = 1;
424 break;
425
426 case NAN_REQ_ATTR_RSSI_CLOSE_PROXIMITY_5G_VAL:
427 hal_req->rssi_close_proximity_5g_val = nla_get_u8(iter);
428 hal_req->config_5g_rssi_close_proximity = 1;
429 break;
430
431 case NAN_REQ_ATTR_RSSI_WINDOW_SIZE_VAL:
432 hal_req->rssi_window_size_val = nla_get_u8(iter);
433 hal_req->config_rssi_window_size = 1;
434 break;
435
436 case NAN_REQ_ATTR_OUI_VAL:
437 hal_req->oui_val = nla_get_u32(iter);
438 hal_req->config_oui = 1;
439 break;
440
441 case NAN_REQ_ATTR_MAC_ADDR_VAL:
442 memcpy(hal_req->intf_addr_val, nla_data(iter), ETH_ALEN);
443 hal_req->config_intf_addr = 1;
444 break;
445
446 case NAN_REQ_ATTR_CLUSTER_VAL:
447 hal_req->config_cluster_attribute_val = nla_get_u8(iter);
448 break;
449
450 case NAN_REQ_ATTR_SOCIAL_CH_SCAN_DWELL_TIME:
451 memcpy(hal_req->scan_params_val.dwell_time, nla_data(iter),
452 sizeof(hal_req->scan_params_val.dwell_time));
453 hal_req->config_scan_params = 1;
454 break;
455
456 case NAN_REQ_ATTR_SOCIAL_CH_SCAN_PERIOD:
457 memcpy(hal_req->scan_params_val.scan_period, nla_data(iter),
458 sizeof(hal_req->scan_params_val.scan_period));
459 hal_req->config_scan_params = 1;
460 break;
461
462 case NAN_REQ_ATTR_RANDOM_FACTOR_FORCE_VAL:
463 hal_req->random_factor_force_val = nla_get_u8(iter);
464 hal_req->config_random_factor_force = 1;
465 break;
466
467 case NAN_REQ_ATTR_HOP_COUNT_FORCE_VAL:
468 hal_req->hop_count_force_val = nla_get_u8(iter);
469 hal_req->config_hop_count_force = 1;
470 break;
471
472 case NAN_REQ_ATTR_CHANNEL_2G4_MHZ_VAL:
473 hal_req->channel_24g_val = nla_get_u32(iter);
474 hal_req->config_24g_channel = 1;
475 break;
476
477 case NAN_REQ_ATTR_CHANNEL_5G_MHZ_VAL:
478 hal_req->channel_5g_val = nla_get_u8(iter);
479 hal_req->config_5g_channel = 1;
480 break;
481
482 case NAN_REQ_ATTR_SUBSCRIBE_SID_BEACON_VAL:
483 hal_req->subscribe_sid_beacon_val = nla_get_u8(iter);
484 hal_req->config_subscribe_sid_beacon = 1;
485 break;
486
487 case NAN_REQ_ATTR_DW_2G4_INTERVAL:
488 hal_req->dw_2dot4g_interval_val = nla_get_u8(iter);
489 /* valid range for 2.4G is 1-5 */
490 if (hal_req->dw_2dot4g_interval_val > 0 && hal_req->dw_2dot4g_interval_val < 5)
491 hal_req->config_2dot4g_dw_band = 1;
492 break;
493
494 case NAN_REQ_ATTR_DW_5G_INTERVAL:
495 hal_req->dw_5g_interval_val = nla_get_u8(iter);
496 /* valid range for 5g is 0-5 */
497 if (hal_req->dw_5g_interval_val < 5)
498 hal_req->config_5g_dw_band = 1;
499 break;
500
501 case NAN_REQ_ATTR_DISC_MAC_ADDR_RANDOM_INTERVAL:
502 hal_req->disc_mac_addr_rand_interval_sec = nla_get_u32(iter);
503 break;
504
781f598d
TK
505 case NAN_REQ_ATTR_HAL_TRANSACTION_ID:
506 hal_req->transaction_id = nla_get_u16(iter);
507 break;
508
533a23a1
TK
509 default:
510 SLSI_ERR(sdev, "Unexpected NAN enable attribute TYPE:%d\n", type);
533a23a1
TK
511 }
512 }
513 return SLSI_HAL_NAN_STATUS_SUCCESS;
514}
515
516int slsi_nan_enable(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
517{
518 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
519 struct slsi_hal_nan_enable_req hal_req;
520 int ret;
521 struct net_device *dev = slsi_nan_get_netdev(sdev);
522 struct netdev_vif *ndev_vif;
523 u8 nan_vif_mac_address[ETH_ALEN];
524 u8 broadcast_mac[ETH_ALEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
525 u32 reply_status = SLSI_HAL_NAN_STATUS_SUCCESS;
526
781f598d
TK
527 hal_req.transaction_id = 0;
528 slsi_nan_pre_check(sdev, dev, &ret, &reply_status);
529 if (ret != WIFI_HAL_SUCCESS)
533a23a1 530 goto exit;
533a23a1
TK
531
532 ndev_vif = netdev_priv(dev);
533
534 reply_status = slsi_nan_enable_get_nl_params(sdev, &hal_req, data, len);
535 if (reply_status != SLSI_HAL_NAN_STATUS_SUCCESS) {
536 ret = -EINVAL;
537 goto exit;
538 }
539
540 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
541 if (ndev_vif->activated) {
542 ret = -EINVAL;
543 SLSI_DBG1(sdev, SLSI_GSCAN, "Already Enabled. Req Rejected\n");
544 goto exit_with_mutex;
545 }
546 ndev_vif->vif_type = FAPI_VIFTYPE_NAN;
547
781f598d
TK
548 slsi_net_randomize_nmi_ndi(sdev);
549
533a23a1
TK
550 if (hal_req.config_intf_addr)
551 ether_addr_copy(nan_vif_mac_address, hal_req.intf_addr_val);
552 else
553 slsi_nan_get_mac(sdev, nan_vif_mac_address);
554
555 ret = slsi_mlme_add_vif(sdev, dev, nan_vif_mac_address, broadcast_mac);
556 if (ret) {
557 reply_status = SLSI_HAL_NAN_STATUS_INTERNAL_FAILURE;
558 SLSI_ERR(sdev, "failed to set unsync vif. Cannot start NAN\n");
559 } else {
560 ret = slsi_mlme_nan_enable(sdev, dev, &hal_req);
561 if (ret) {
562 SLSI_ERR(sdev, "failed to enable NAN.\n");
563 reply_status = SLSI_HAL_NAN_STATUS_INTERNAL_FAILURE;
564 slsi_mlme_del_vif(sdev, dev);
565 ndev_vif->activated = false;
781f598d 566 ndev_vif->nan.service_id_map = 0;
533a23a1
TK
567 } else {
568 slsi_vif_activated(sdev, dev);
781f598d
TK
569 ndev_vif->nan.master_pref_value = hal_req.master_pref;
570 ether_addr_copy(ndev_vif->nan.local_nmi, nan_vif_mac_address);
571 ndev_vif->nan.state = 1;
572 if (hal_req.config_24g_channel)
573 ndev_vif->nan.operating_channel[0] = hal_req.channel_24g_val;
574 if (hal_req.config_5g_channel)
575 ndev_vif->nan.operating_channel[1] = hal_req.channel_5g_val;
576 if (hal_req.config_hop_count_limit)
577 ndev_vif->nan.hopcount = hal_req.hop_count_limit_val;
578 slsi_eth_zero_addr(ndev_vif->nan.cluster_id);
579 ndev_vif->nan.random_mac_interval_sec = hal_req.disc_mac_addr_rand_interval_sec;
580 SLSI_INFO(sdev,
581 "trans_id:%d master_pref:%d 2gChan:%d 5gChan:%d mac_random_interval:%d\n",
582 hal_req.transaction_id, hal_req.master_pref, hal_req.channel_24g_val,
583 hal_req.channel_5g_val, hal_req.disc_mac_addr_rand_interval_sec);
533a23a1
TK
584 }
585 }
781f598d 586 ether_addr_copy(ndev_vif->nan.local_nmi, nan_vif_mac_address);
533a23a1
TK
587
588exit_with_mutex:
589 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
590exit:
781f598d 591 slsi_vendor_nan_command_reply(wiphy, reply_status, ret, NAN_RESPONSE_ENABLED, 0, NULL, hal_req.transaction_id);
533a23a1
TK
592 return ret;
593}
594
595int slsi_nan_disable(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
596{
597 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
598 struct net_device *dev = slsi_nan_get_netdev(sdev);
781f598d
TK
599 struct net_device *data_dev;
600 struct netdev_vif *ndev_vif, *data_ndev_vif;
601 u8 disable_cluster_merge, i;
602 int type, tmp;
603 const struct nlattr *iter;
604 u16 transaction_id = 0;
605
606 nla_for_each_attr(iter, data, len, tmp) {
607 type = nla_type(iter);
608 switch (type) {
609 case NAN_REQ_ATTR_HAL_TRANSACTION_ID:
610 transaction_id = nla_get_u16(iter);
611 break;
612 default:
613 break;
614 }
615 }
533a23a1 616
781f598d 617 SLSI_INFO(sdev, "transaction_id:%d\n", transaction_id);
533a23a1
TK
618 if (dev) {
619 ndev_vif = netdev_priv(dev);
620 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
621 if (ndev_vif->activated) {
622 slsi_mlme_del_vif(sdev, dev);
623 ndev_vif->activated = false;
533a23a1
TK
624 } else {
625 SLSI_WARN(sdev, "NAN FWif not active!!");
626 }
781f598d
TK
627 for (i = SLSI_NAN_DATA_IFINDEX_START; i < CONFIG_SCSC_WLAN_MAX_INTERFACES + 1; i++) {
628 data_dev = slsi_get_netdev(sdev, i);
629 if (data_dev) {
630 data_ndev_vif = netdev_priv(data_dev);
631 SLSI_MUTEX_LOCK(data_ndev_vif->vif_mutex);
632 slsi_vif_cleanup(sdev, data_dev, true);
633 SLSI_MUTEX_UNLOCK(data_ndev_vif->vif_mutex);
634 }
635 }
636 disable_cluster_merge = ndev_vif->nan.disable_cluster_merge;
637 memset(&ndev_vif->nan, 0, sizeof(ndev_vif->nan));
638 ndev_vif->nan.disable_cluster_merge = disable_cluster_merge;
533a23a1
TK
639 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
640 } else {
641 SLSI_WARN(sdev, "No NAN interface!!");
642 }
643
781f598d 644 slsi_vendor_nan_command_reply(wiphy, SLSI_HAL_NAN_STATUS_SUCCESS, 0, NAN_RESPONSE_DISABLED, 0, NULL, transaction_id);
533a23a1
TK
645
646 return 0;
647}
648
649static int slsi_nan_publish_get_nl_params(struct slsi_dev *sdev, struct slsi_hal_nan_publish_req *hal_req,
650 const void *data, int len)
651{
652 int type, tmp, r;
653 const struct nlattr *iter;
654
655 memset(hal_req, 0, sizeof(*hal_req));
656 nla_for_each_attr(iter, data, len, tmp) {
657 type = nla_type(iter);
658 switch (type) {
659 case NAN_REQ_ATTR_PUBLISH_ID:
660 hal_req->publish_id = nla_get_u16(iter);
661 break;
662 case NAN_REQ_ATTR_PUBLISH_TTL:
663 hal_req->ttl = nla_get_u16(iter);
664 break;
665
666 case NAN_REQ_ATTR_PUBLISH_PERIOD:
667 hal_req->period = nla_get_u16(iter);
668 break;
669
670 case NAN_REQ_ATTR_PUBLISH_TYPE:
671 hal_req->publish_type = nla_get_u16(iter);
672 break;
673
674 case NAN_REQ_ATTR_PUBLISH_TX_TYPE:
675 hal_req->tx_type = nla_get_u16(iter);
676 break;
677
678 case NAN_REQ_ATTR_PUBLISH_COUNT:
679 hal_req->publish_count = nla_get_u8(iter);
680 break;
681
682 case NAN_REQ_ATTR_PUBLISH_SERVICE_NAME_LEN:
683 hal_req->service_name_len = nla_get_u16(iter);
684 break;
685
686 case NAN_REQ_ATTR_PUBLISH_SERVICE_NAME:
687 memcpy(hal_req->service_name, nla_data(iter), hal_req->service_name_len);
688 break;
689
690 case NAN_REQ_ATTR_PUBLISH_MATCH_ALGO:
691 hal_req->publish_match_indicator = nla_get_u8(iter);
692 break;
693
694 case NAN_REQ_ATTR_PUBLISH_SERVICE_INFO_LEN:
695 hal_req->service_specific_info_len = nla_get_u16(iter);
696 break;
697
698 case NAN_REQ_ATTR_PUBLISH_SERVICE_INFO:
699 memcpy(hal_req->service_specific_info, nla_data(iter), hal_req->service_specific_info_len);
700 break;
701
702 case NAN_REQ_ATTR_PUBLISH_RX_MATCH_FILTER_LEN:
703 hal_req->rx_match_filter_len = nla_get_u16(iter);
704 break;
705
706 case NAN_REQ_ATTR_PUBLISH_RX_MATCH_FILTER:
707 memcpy(hal_req->rx_match_filter, nla_data(iter), hal_req->rx_match_filter_len);
708 break;
709
710 case NAN_REQ_ATTR_PUBLISH_TX_MATCH_FILTER_LEN:
711 hal_req->tx_match_filter_len = nla_get_u16(iter);
712 break;
713
714 case NAN_REQ_ATTR_PUBLISH_TX_MATCH_FILTER:
715 memcpy(hal_req->tx_match_filter, nla_data(iter), hal_req->tx_match_filter_len);
716 break;
717
718 case NAN_REQ_ATTR_PUBLISH_RSSI_THRESHOLD_FLAG:
719 hal_req->rssi_threshold_flag = nla_get_u8(iter);
720 break;
721
722 case NAN_REQ_ATTR_PUBLISH_CONN_MAP:
723 hal_req->connmap = nla_get_u8(iter);
724 break;
725
726 case NAN_REQ_ATTR_PUBLISH_RECV_IND_CFG:
727 hal_req->recv_indication_cfg = nla_get_u8(iter);
728 break;
729
730 case NAN_REQ_ATTR_PUBLISH_SDEA_LEN:
731 hal_req->sdea_service_specific_info_len = nla_get_u16(iter);
732 break;
733
734 case NAN_REQ_ATTR_PUBLISH_SDEA:
735 memcpy(hal_req->sdea_service_specific_info, nla_data(iter),
736 hal_req->sdea_service_specific_info_len);
737 break;
738
739 case NAN_REQ_ATTR_RANGING_AUTO_RESPONSE:
740 hal_req->ranging_auto_response = nla_get_u8(iter);
741 break;
742
781f598d
TK
743 case NAN_REQ_ATTR_HAL_TRANSACTION_ID:
744 hal_req->transaction_id = nla_get_u16(iter);
745 break;
746
533a23a1
TK
747 default:
748 r = slsi_nan_get_sdea_params_nl(sdev, &hal_req->sdea_params, iter, type);
749 if (r)
750 r = slsi_nan_get_ranging_cfg_nl(sdev, &hal_req->ranging_cfg, iter, type);
751 if (r)
752 r = slsi_nan_get_security_info_nl(sdev, &hal_req->sec_info, iter, type);
753 if (r)
754 r = slsi_nan_get_range_resp_cfg_nl(sdev, &hal_req->range_response_cfg, iter, type);
755 if (r) {
756 SLSI_ERR(sdev, "Unexpected NAN publish attribute TYPE:%d\n", type);
757 return SLSI_HAL_NAN_STATUS_INVALID_PARAM;
758 }
759 }
760 }
761 return SLSI_HAL_NAN_STATUS_SUCCESS;
762}
763
764int slsi_nan_publish(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
765{
766 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
767 struct slsi_hal_nan_publish_req *hal_req;
768 struct net_device *dev = slsi_nan_get_netdev(sdev);
769 struct netdev_vif *ndev_vif;
770 int ret;
771 u32 reply_status;
772 u32 publish_id = 0;
781f598d 773 u16 transaction_id = 0;
533a23a1 774
781f598d
TK
775 slsi_nan_pre_check(sdev, dev, &ret, &reply_status);
776 if (ret != WIFI_HAL_SUCCESS)
533a23a1 777 goto exit;
533a23a1
TK
778
779 hal_req = kmalloc(sizeof(*hal_req), GFP_KERNEL);
780 if (!hal_req) {
781 SLSI_ERR(sdev, "failed to alloc hal_req\n");
782 reply_status = SLSI_HAL_NAN_STATUS_NO_RESOURCE_AVAILABLE;
783 ret = -ENOMEM;
784 goto exit;
785 }
786
787 ndev_vif = netdev_priv(dev);
788 reply_status = slsi_nan_publish_get_nl_params(sdev, hal_req, data, len);
789 if (reply_status != SLSI_HAL_NAN_STATUS_SUCCESS) {
790 kfree(hal_req);
791 ret = -EINVAL;
792 goto exit;
793 }
781f598d 794 transaction_id = hal_req->transaction_id;
533a23a1
TK
795
796 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
797
798 if (!ndev_vif->activated) {
799 SLSI_WARN(sdev, "NAN vif not activated\n");
800 reply_status = SLSI_HAL_NAN_STATUS_NAN_NOT_ALLOWED;
801 ret = WIFI_HAL_ERROR_NOT_AVAILABLE;
802 goto exit_with_lock;
803 }
804
805 if (!hal_req->publish_id) {
806 hal_req->publish_id = slsi_nan_get_new_publish_id(ndev_vif);
807 } else if (!slsi_nan_is_publish_id_active(ndev_vif, hal_req->publish_id)) {
808 SLSI_WARN(sdev, "Publish id %d not found. map:%x\n", hal_req->publish_id,
781f598d 809 ndev_vif->nan.service_id_map);
533a23a1
TK
810 reply_status = SLSI_HAL_NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID;
811 ret = -EINVAL;
812 goto exit_with_lock;
813 }
814
815 if (hal_req->publish_id) {
816 ret = slsi_mlme_nan_publish(sdev, dev, hal_req, hal_req->publish_id);
781f598d 817 if (ret) {
533a23a1 818 reply_status = SLSI_HAL_NAN_STATUS_INTERNAL_FAILURE;
781f598d 819 } else {
533a23a1 820 publish_id = hal_req->publish_id;
781f598d
TK
821 SLSI_INFO(sdev,
822 "trans_id:%d, publish_id:%d type:%d rec_ind_cfg:0x%x\n",
823 hal_req->transaction_id, hal_req->publish_id, hal_req->publish_type,
824 hal_req->recv_indication_cfg);
825 }
533a23a1
TK
826 } else {
827 reply_status = SLSI_HAL_NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID;
828 SLSI_WARN(sdev, "Too Many concurrent PUBLISH REQ(map:%x)\n",
781f598d 829 ndev_vif->nan.service_id_map);
533a23a1
TK
830 ret = -ENOTSUPP;
831 }
832exit_with_lock:
833 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
834 kfree(hal_req);
835exit:
781f598d 836 slsi_vendor_nan_command_reply(wiphy, reply_status, ret, NAN_RESPONSE_PUBLISH, publish_id, NULL, transaction_id);
533a23a1
TK
837 return ret;
838}
839
840int slsi_nan_publish_cancel(struct wiphy *wiphy, struct wireless_dev *wdev,
841 const void *data, int len)
842{
843 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
844 struct net_device *dev = slsi_nan_get_netdev(sdev);
845 struct netdev_vif *ndev_vif;
846 int type, tmp, ret = 0;
781f598d 847 u16 publish_id = 0, transaction_id = 0;
533a23a1
TK
848 const struct nlattr *iter;
849 u32 reply_status = SLSI_HAL_NAN_STATUS_SUCCESS;
850
781f598d
TK
851 slsi_nan_pre_check(sdev, dev, &ret, &reply_status);
852 if (ret != WIFI_HAL_SUCCESS)
533a23a1 853 goto exit;
533a23a1
TK
854
855 ndev_vif = netdev_priv(dev);
856 nla_for_each_attr(iter, data, len, tmp) {
857 type = nla_type(iter);
858 switch (type) {
859 case NAN_REQ_ATTR_PUBLISH_ID:
860 publish_id = nla_get_u16(iter);
861 break;
781f598d
TK
862 case NAN_REQ_ATTR_HAL_TRANSACTION_ID:
863 transaction_id = nla_get_u16(iter);
864 break;
865
533a23a1
TK
866 default:
867 SLSI_ERR(sdev, "Unexpected NAN publishcancel attribute TYPE:%d\n", type);
868 }
869 }
781f598d 870 SLSI_INFO(sdev, "transaction_id:%d publish_id:%d\n", transaction_id, publish_id);
533a23a1
TK
871 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
872 if (!ndev_vif->activated) {
873 reply_status = SLSI_HAL_NAN_STATUS_NAN_NOT_ALLOWED;
874 ret = WIFI_HAL_ERROR_NOT_AVAILABLE;
875 goto exit_with_lock;
876 }
877 if (!publish_id || !slsi_nan_is_publish_id_active(ndev_vif, publish_id)) {
878 reply_status = SLSI_HAL_NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID;
879 SLSI_WARN(sdev, "Publish_id(%d) not active. map:%x\n",
781f598d 880 publish_id, ndev_vif->nan.service_id_map);
533a23a1
TK
881 } else {
882 ret = slsi_mlme_nan_publish(sdev, dev, NULL, publish_id);
883 if (ret)
884 reply_status = SLSI_HAL_NAN_STATUS_INTERNAL_FAILURE;
885 }
886exit_with_lock:
887 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
888exit:
781f598d 889 slsi_vendor_nan_command_reply(wiphy, reply_status, ret, NAN_RESPONSE_PUBLISH_CANCEL, publish_id, NULL, transaction_id);
533a23a1
TK
890 return ret;
891}
892
893static int slsi_nan_subscribe_get_nl_params(struct slsi_dev *sdev, struct slsi_hal_nan_subscribe_req *hal_req,
894 const void *data, int len)
895{
896 int type, tmp, r;
897 const struct nlattr *iter;
898
899 memset(hal_req, 0, sizeof(*hal_req));
900 nla_for_each_attr(iter, data, len, tmp) {
901 type = nla_type(iter);
902 switch (type) {
903 case NAN_REQ_ATTR_SUBSCRIBE_ID:
904 hal_req->subscribe_id = nla_get_u16(iter);
905 break;
906
907 case NAN_REQ_ATTR_SUBSCRIBE_TTL:
908 hal_req->ttl = nla_get_u16(iter);
909 break;
910
911 case NAN_REQ_ATTR_SUBSCRIBE_PERIOD:
912 hal_req->period = nla_get_u16(iter);
913 break;
914
915 case NAN_REQ_ATTR_SUBSCRIBE_TYPE:
916 hal_req->subscribe_type = nla_get_u8(iter);
917 break;
918
919 case NAN_REQ_ATTR_SUBSCRIBE_RESP_FILTER_TYPE:
920 hal_req->service_response_filter = nla_get_u16(iter);
921 break;
922
923 case NAN_REQ_ATTR_SUBSCRIBE_RESP_INCLUDE:
924 hal_req->service_response_include = nla_get_u8(iter);
925 break;
926
927 case NAN_REQ_ATTR_SUBSCRIBE_USE_RESP_FILTER:
928 hal_req->use_service_response_filter = nla_get_u8(iter);
929 break;
930
931 case NAN_REQ_ATTR_SUBSCRIBE_SSI_REQUIRED:
932 hal_req->ssi_required_for_match_indication = nla_get_u8(iter);
933 break;
934
935 case NAN_REQ_ATTR_SUBSCRIBE_MATCH_INDICATOR:
936 hal_req->subscribe_match_indicator = nla_get_u8(iter);
937 break;
938
939 case NAN_REQ_ATTR_SUBSCRIBE_COUNT:
940 hal_req->subscribe_count = nla_get_u8(iter);
941 break;
942
943 case NAN_REQ_ATTR_SUBSCRIBE_SERVICE_NAME_LEN:
944 hal_req->service_name_len = nla_get_u16(iter);
945 break;
946
947 case NAN_REQ_ATTR_SUBSCRIBE_SERVICE_NAME:
948 memcpy(hal_req->service_name, nla_data(iter), hal_req->service_name_len);
949 break;
950
951 case NAN_REQ_ATTR_SUBSCRIBE_SERVICE_INFO_LEN:
952 hal_req->service_specific_info_len = nla_get_u16(iter);
953 break;
954
955 case NAN_REQ_ATTR_SUBSCRIBE_SERVICE_INFO:
956 memcpy(hal_req->service_specific_info, nla_data(iter), hal_req->service_specific_info_len);
957 break;
958
959 case NAN_REQ_ATTR_SUBSCRIBE_RX_MATCH_FILTER_LEN:
960 hal_req->rx_match_filter_len = nla_get_u16(iter);
961 break;
962
963 case NAN_REQ_ATTR_SUBSCRIBE_RX_MATCH_FILTER:
964 memcpy(hal_req->rx_match_filter, nla_data(iter), hal_req->rx_match_filter_len);
965 break;
966
967 case NAN_REQ_ATTR_SUBSCRIBE_TX_MATCH_FILTER_LEN:
968 hal_req->tx_match_filter_len = nla_get_u16(iter);
969 break;
970
971 case NAN_REQ_ATTR_SUBSCRIBE_TX_MATCH_FILTER:
972 memcpy(hal_req->tx_match_filter, nla_data(iter), hal_req->tx_match_filter_len);
973 break;
974
975 case NAN_REQ_ATTR_SUBSCRIBE_RSSI_THRESHOLD_FLAG:
976 hal_req->rssi_threshold_flag = nla_get_u8(iter);
977 break;
978
979 case NAN_REQ_ATTR_SUBSCRIBE_CONN_MAP:
980 hal_req->connmap = nla_get_u8(iter);
981 break;
982
983 case NAN_REQ_ATTR_SUBSCRIBE_NUM_INTF_ADDR_PRESENT:
984 hal_req->num_intf_addr_present = nla_get_u8(iter);
985 break;
986
987 case NAN_REQ_ATTR_SUBSCRIBE_INTF_ADDR:
988 memcpy(hal_req->intf_addr, nla_data(iter), hal_req->num_intf_addr_present * ETH_ALEN);
989 break;
990
991 case NAN_REQ_ATTR_SUBSCRIBE_RECV_IND_CFG:
992 hal_req->recv_indication_cfg = nla_get_u8(iter);
993 break;
994
995 case NAN_REQ_ATTR_PUBLISH_SDEA_LEN:
996 hal_req->sdea_service_specific_info_len = nla_get_u16(iter);
997 break;
998
999 case NAN_REQ_ATTR_PUBLISH_SDEA:
1000 memcpy(hal_req->sdea_service_specific_info, nla_data(iter),
1001 hal_req->sdea_service_specific_info_len);
1002 break;
1003
1004 case NAN_REQ_ATTR_RANGING_AUTO_RESPONSE:
1005 hal_req->ranging_auto_response = nla_get_u8(iter);
1006 break;
1007
781f598d
TK
1008 case NAN_REQ_ATTR_HAL_TRANSACTION_ID:
1009 hal_req->transaction_id = nla_get_u16(iter);
1010 break;
1011
533a23a1
TK
1012 default:
1013 r = slsi_nan_get_sdea_params_nl(sdev, &hal_req->sdea_params, iter, type);
1014 if (r)
1015 r = slsi_nan_get_ranging_cfg_nl(sdev, &hal_req->ranging_cfg, iter, type);
1016 if (r)
1017 r = slsi_nan_get_security_info_nl(sdev, &hal_req->sec_info, iter, type);
1018 if (r)
1019 r = slsi_nan_get_range_resp_cfg_nl(sdev, &hal_req->range_response_cfg, iter, type);
1020 if (r) {
1021 SLSI_ERR(sdev, "Unexpected NAN subscribe attribute TYPE:%d\n", type);
1022 return SLSI_HAL_NAN_STATUS_INVALID_PARAM;
1023 }
1024 }
1025 }
1026 return SLSI_HAL_NAN_STATUS_SUCCESS;
1027}
1028
1029int slsi_nan_subscribe(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
1030{
1031 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
1032 struct net_device *dev = slsi_nan_get_netdev(sdev);
1033 struct netdev_vif *ndev_vif;
1034 struct slsi_hal_nan_subscribe_req *hal_req;
1035 int ret;
1036 u32 reply_status;
1037 u32 subscribe_id = 0;
781f598d 1038 u16 transaction_id = 0;
533a23a1 1039
781f598d
TK
1040 slsi_nan_pre_check(sdev, dev, &ret, &reply_status);
1041 if (ret != WIFI_HAL_SUCCESS)
533a23a1 1042 goto exit;
533a23a1
TK
1043
1044 hal_req = kmalloc(sizeof(*hal_req), GFP_KERNEL);
1045 if (!hal_req) {
1046 SLSI_ERR(sdev, "Failed to alloc hal_req structure!!!\n");
1047 reply_status = SLSI_HAL_NAN_STATUS_NO_RESOURCE_AVAILABLE;
1048 ret = -ENOMEM;
1049 goto exit;
1050 }
1051
1052 ndev_vif = netdev_priv(dev);
1053 reply_status = slsi_nan_subscribe_get_nl_params(sdev, hal_req, data, len);
1054 if (reply_status != SLSI_HAL_NAN_STATUS_SUCCESS) {
1055 kfree(hal_req);
1056 ret = -EINVAL;
1057 goto exit;
1058 }
781f598d 1059 transaction_id = hal_req->transaction_id;
533a23a1
TK
1060 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
1061 if (!ndev_vif->activated) {
1062 SLSI_WARN(sdev, "NAN vif not activated\n");
1063 reply_status = SLSI_HAL_NAN_STATUS_NAN_NOT_ALLOWED;
1064 ret = WIFI_HAL_ERROR_NOT_AVAILABLE;
1065 goto exit_with_lock;
1066 }
1067
1068 if (!hal_req->subscribe_id) {
1069 hal_req->subscribe_id = slsi_nan_get_new_subscribe_id(ndev_vif);
1070 } else if (!slsi_nan_is_subscribe_id_active(ndev_vif, hal_req->subscribe_id)) {
1071 SLSI_WARN(sdev, "Subscribe id %d not found. map:%x\n", hal_req->subscribe_id,
781f598d 1072 ndev_vif->nan.service_id_map);
533a23a1
TK
1073 reply_status = SLSI_HAL_NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID;
1074 ret = -EINVAL;
1075 goto exit_with_lock;
1076 }
1077
1078 ret = slsi_mlme_nan_subscribe(sdev, dev, hal_req, hal_req->subscribe_id);
781f598d 1079 if (ret) {
533a23a1 1080 reply_status = SLSI_HAL_NAN_STATUS_INTERNAL_FAILURE;
781f598d
TK
1081 } else {
1082 SLSI_INFO(sdev, "trans_id:%d subscribe_id:%d type:%d\n",
1083 hal_req->transaction_id, hal_req->subscribe_id, hal_req->subscribe_type);
533a23a1 1084 subscribe_id = hal_req->subscribe_id;
781f598d 1085 }
533a23a1
TK
1086
1087exit_with_lock:
1088 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
1089 kfree(hal_req);
1090exit:
781f598d 1091 slsi_vendor_nan_command_reply(wiphy, reply_status, ret, NAN_RESPONSE_SUBSCRIBE, subscribe_id, NULL, transaction_id);
533a23a1
TK
1092 return ret;
1093}
1094
1095int slsi_nan_subscribe_cancel(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
1096{
1097 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
1098 struct net_device *dev = slsi_nan_get_netdev(sdev);
1099 struct netdev_vif *ndev_vif;
1100 int type, tmp, ret = WIFI_HAL_ERROR_UNKNOWN;
781f598d 1101 u16 subscribe_id = 0, transaction_id = 0;
533a23a1
TK
1102 const struct nlattr *iter;
1103 u32 reply_status = SLSI_HAL_NAN_STATUS_SUCCESS;
1104
781f598d
TK
1105 slsi_nan_pre_check(sdev, dev, &ret, &reply_status);
1106 if (ret != WIFI_HAL_SUCCESS)
533a23a1 1107 goto exit;
533a23a1
TK
1108
1109 ndev_vif = netdev_priv(dev);
1110
1111 nla_for_each_attr(iter, data, len, tmp) {
1112 type = nla_type(iter);
1113 switch (type) {
1114 case NAN_REQ_ATTR_SUBSCRIBE_ID:
1115 subscribe_id = nla_get_u16(iter);
1116 break;
781f598d
TK
1117 case NAN_REQ_ATTR_HAL_TRANSACTION_ID:
1118 transaction_id = nla_get_u16(iter);
1119 break;
533a23a1
TK
1120 default:
1121 SLSI_ERR(sdev, "Unexpected NAN subscribecancel attribute TYPE:%d\n", type);
1122 reply_status = SLSI_HAL_NAN_STATUS_INVALID_PARAM;
1123 goto exit;
1124 }
1125 }
781f598d 1126 SLSI_INFO(sdev, "trans_id:%d subscribe_id:%d\n", transaction_id, subscribe_id);
533a23a1
TK
1127 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
1128 if (ndev_vif->activated) {
1129 if (!subscribe_id || !slsi_nan_is_subscribe_id_active(ndev_vif, subscribe_id)) {
1130 SLSI_WARN(sdev, "subscribe_id(%d) not active. map:%x\n",
781f598d 1131 subscribe_id, ndev_vif->nan.service_id_map);
533a23a1
TK
1132 reply_status = SLSI_HAL_NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID;
1133 } else {
1134 ret = slsi_mlme_nan_subscribe(sdev, dev, NULL, subscribe_id);
1135 if (ret)
1136 reply_status = SLSI_HAL_NAN_STATUS_INTERNAL_FAILURE;
1137 }
1138 } else {
1139 SLSI_ERR(sdev, "vif not activated\n");
1140 reply_status = SLSI_HAL_NAN_STATUS_NAN_NOT_ALLOWED;
1141 ret = WIFI_HAL_ERROR_NOT_AVAILABLE;
1142 }
1143 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
1144exit:
781f598d 1145 slsi_vendor_nan_command_reply(wiphy, reply_status, ret, NAN_RESPONSE_SUBSCRIBE_CANCEL, subscribe_id, NULL, transaction_id);
533a23a1
TK
1146 return ret;
1147}
1148
1149static int slsi_nan_followup_get_nl_params(struct slsi_dev *sdev, struct slsi_hal_nan_transmit_followup_req *hal_req,
1150 const void *data, int len)
1151{
1152 int type, tmp;
1153 const struct nlattr *iter;
1154
1155 memset(hal_req, 0, sizeof(*hal_req));
1156 nla_for_each_attr(iter, data, len, tmp) {
1157 type = nla_type(iter);
1158 switch (type) {
1159 case NAN_REQ_ATTR_FOLLOWUP_ID:
1160 hal_req->publish_subscribe_id = nla_get_u16(iter);
1161 break;
1162
1163 case NAN_REQ_ATTR_FOLLOWUP_REQUESTOR_ID:
1164 hal_req->requestor_instance_id = nla_get_u32(iter);
1165 break;
1166
1167 case NAN_REQ_ATTR_FOLLOWUP_ADDR:
1168 memcpy(hal_req->addr, nla_data(iter), ETH_ALEN);
1169 break;
1170
1171 case NAN_REQ_ATTR_FOLLOWUP_PRIORITY:
1172 hal_req->priority = nla_get_u8(iter);
1173 break;
1174
1175 case NAN_REQ_ATTR_FOLLOWUP_TX_WINDOW:
1176 hal_req->dw_or_faw = nla_get_u8(iter);
1177 break;
1178
1179 case NAN_REQ_ATTR_FOLLOWUP_SERVICE_NAME_LEN:
1180 hal_req->service_specific_info_len = nla_get_u16(iter);
1181 break;
1182
1183 case NAN_REQ_ATTR_FOLLOWUP_SERVICE_NAME:
1184 memcpy(hal_req->service_specific_info, nla_data(iter), hal_req->service_specific_info_len);
1185 break;
1186
1187 case NAN_REQ_ATTR_FOLLOWUP_RECV_IND_CFG:
1188 hal_req->recv_indication_cfg = nla_get_u8(iter);
1189 break;
1190
1191 case NAN_REQ_ATTR_PUBLISH_SDEA_LEN:
1192 hal_req->sdea_service_specific_info_len = nla_get_u16(iter);
1193 break;
1194
1195 case NAN_REQ_ATTR_PUBLISH_SDEA:
1196 memcpy(hal_req->sdea_service_specific_info, nla_data(iter),
1197 hal_req->sdea_service_specific_info_len);
1198 break;
1199
781f598d
TK
1200 case NAN_REQ_ATTR_HAL_TRANSACTION_ID:
1201 hal_req->transaction_id = nla_get_u16(iter);
1202 break;
1203
533a23a1
TK
1204 default:
1205 SLSI_ERR(sdev, "Unexpected NAN followup attribute TYPE:%d\n", type);
1206 return SLSI_HAL_NAN_STATUS_INVALID_PARAM;
1207 }
1208 }
1209 return SLSI_HAL_NAN_STATUS_SUCCESS;
1210}
1211
1212int slsi_nan_transmit_followup(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
1213{
1214 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
1215 struct net_device *dev = slsi_nan_get_netdev(sdev);
1216 struct netdev_vif *ndev_vif;
1217 struct slsi_hal_nan_transmit_followup_req hal_req;
781f598d 1218 int ret = 0;
533a23a1
TK
1219 u32 reply_status = SLSI_HAL_NAN_STATUS_SUCCESS;
1220
781f598d
TK
1221 hal_req.transaction_id = 0;
1222 slsi_nan_pre_check(sdev, dev, &ret, &reply_status);
1223 if (ret != WIFI_HAL_SUCCESS)
533a23a1 1224 goto exit;
533a23a1
TK
1225
1226 ndev_vif = netdev_priv(dev);
1227 reply_status = slsi_nan_followup_get_nl_params(sdev, &hal_req, data, len);
1228 if (reply_status) {
1229 ret = -EINVAL;
1230 goto exit;
1231 }
1232
1233 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
1234 if (!ndev_vif->activated) {
1235 SLSI_WARN(sdev, "NAN vif not activated\n");
1236 reply_status = SLSI_HAL_NAN_STATUS_NAN_NOT_ALLOWED;
1237 ret = WIFI_HAL_ERROR_NOT_AVAILABLE;
1238 goto exit_with_lock;
1239 }
1240
1241 if (!hal_req.publish_subscribe_id ||
1242 !(slsi_nan_is_subscribe_id_active(ndev_vif, hal_req.publish_subscribe_id) ||
1243 slsi_nan_is_publish_id_active(ndev_vif, hal_req.publish_subscribe_id))) {
1244 SLSI_WARN(sdev, "publish/Subscribe id %d not found. map:%x\n", hal_req.publish_subscribe_id,
781f598d 1245 ndev_vif->nan.service_id_map);
533a23a1
TK
1246 reply_status = SLSI_HAL_NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID;
1247 ret = -EINVAL;
1248 goto exit_with_lock;
1249 }
1250
1251 ret = slsi_mlme_nan_tx_followup(sdev, dev, &hal_req);
781f598d
TK
1252 if (ret) {
1253 if (ret == SLSI_HAL_NAN_STATUS_FOLLOWUP_QUEUE_FULL) {
1254 reply_status = ret;
1255 ret = 0;
1256 } else {
1257 reply_status = ret == SLSI_HAL_NAN_STATUS_INTERNAL_FAILURE;
1258 }
1259 } else {
1260 SLSI_INFO(sdev,
1261 "transId:%d serviceId:%d instanceId:%d\n",
1262 hal_req.transaction_id, hal_req.publish_subscribe_id, hal_req.requestor_instance_id);
1263 ndev_vif->nan.followup_trans_id = hal_req.transaction_id;
1264 }
533a23a1
TK
1265
1266exit_with_lock:
1267 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
1268exit:
781f598d 1269 slsi_vendor_nan_command_reply(wiphy, reply_status, ret, NAN_RESPONSE_TRANSMIT_FOLLOWUP, 0, NULL, hal_req.transaction_id);
533a23a1
TK
1270 return ret;
1271}
1272
1273static int slsi_nan_config_get_nl_params(struct slsi_dev *sdev, struct slsi_hal_nan_config_req *hal_req,
1274 const void *data, int len)
1275{
1276 int type, type1, tmp, tmp1, disc_attr_idx = 0, famchan_idx = 0;
1277 const struct nlattr *iter, *iter1;
1278 struct slsi_hal_nan_post_discovery_param *disc_attr;
1279 struct slsi_hal_nan_further_availability_channel *famchan;
1280
533a23a1
TK
1281 nla_for_each_attr(iter, data, len, tmp) {
1282 type = nla_type(iter);
1283 switch (type) {
1284 case NAN_REQ_ATTR_SID_BEACON_VAL:
1285 hal_req->sid_beacon = nla_get_u8(iter);
1286 hal_req->config_sid_beacon = 1;
1287 break;
1288
1289 case NAN_REQ_ATTR_RSSI_PROXIMITY_2G4_VAL:
1290 hal_req->rssi_proximity = nla_get_u8(iter);
1291 hal_req->config_rssi_proximity = 1;
1292 break;
1293
1294 case NAN_REQ_ATTR_MASTER_PREF:
1295 hal_req->master_pref = nla_get_u8(iter);
1296 hal_req->config_master_pref = 1;
1297 break;
1298
1299 case NAN_REQ_ATTR_RSSI_CLOSE_PROXIMITY_5G_VAL:
1300 hal_req->rssi_close_proximity_5g_val = nla_get_u8(iter);
1301 hal_req->config_5g_rssi_close_proximity = 1;
1302 break;
1303
1304 case NAN_REQ_ATTR_RSSI_WINDOW_SIZE_VAL:
1305 hal_req->rssi_window_size_val = nla_get_u8(iter);
1306 hal_req->config_rssi_window_size = 1;
1307 break;
1308
1309 case NAN_REQ_ATTR_CLUSTER_VAL:
1310 hal_req->config_cluster_attribute_val = nla_get_u8(iter);
1311 break;
1312
1313 case NAN_REQ_ATTR_SOCIAL_CH_SCAN_DWELL_TIME:
1314 memcpy(hal_req->scan_params_val.dwell_time, nla_data(iter),
1315 sizeof(hal_req->scan_params_val.dwell_time));
1316 hal_req->config_scan_params = 1;
1317 break;
1318
1319 case NAN_REQ_ATTR_SOCIAL_CH_SCAN_PERIOD:
1320 memcpy(hal_req->scan_params_val.scan_period, nla_data(iter),
1321 sizeof(hal_req->scan_params_val.scan_period));
1322 hal_req->config_scan_params = 1;
1323 break;
1324
1325 case NAN_REQ_ATTR_RANDOM_FACTOR_FORCE_VAL:
1326 hal_req->random_factor_force_val = nla_get_u8(iter);
1327 hal_req->config_random_factor_force = 1;
1328 break;
1329
1330 case NAN_REQ_ATTR_HOP_COUNT_FORCE_VAL:
1331 hal_req->hop_count_force_val = nla_get_u8(iter);
1332 hal_req->config_hop_count_force = 1;
1333 break;
1334
1335 case NAN_REQ_ATTR_CONN_CAPABILITY_PAYLOAD_TX:
1336 hal_req->conn_capability_val.payload_transmit_flag = nla_get_u8(iter);
1337 hal_req->config_conn_capability = 1;
1338 break;
1339
1340 case NAN_REQ_ATTR_CONN_CAPABILITY_WFD:
1341 hal_req->conn_capability_val.is_wfd_supported = nla_get_u8(iter);
1342 hal_req->config_conn_capability = 1;
1343 break;
1344
1345 case NAN_REQ_ATTR_CONN_CAPABILITY_WFDS:
1346 hal_req->conn_capability_val.is_wfds_supported = nla_get_u8(iter);
1347 hal_req->config_conn_capability = 1;
1348 break;
1349
1350 case NAN_REQ_ATTR_CONN_CAPABILITY_TDLS:
1351 hal_req->conn_capability_val.is_tdls_supported = nla_get_u8(iter);
1352 hal_req->config_conn_capability = 1;
1353 break;
1354
1355 case NAN_REQ_ATTR_CONN_CAPABILITY_MESH:
1356 hal_req->conn_capability_val.is_mesh_supported = nla_get_u8(iter);
1357 hal_req->config_conn_capability = 1;
1358 break;
1359
1360 case NAN_REQ_ATTR_CONN_CAPABILITY_IBSS:
1361 hal_req->conn_capability_val.is_ibss_supported = nla_get_u8(iter);
1362 hal_req->config_conn_capability = 1;
1363 break;
1364
1365 case NAN_REQ_ATTR_CONN_CAPABILITY_WLAN_INFRA:
1366 hal_req->conn_capability_val.wlan_infra_field = nla_get_u8(iter);
1367 hal_req->config_conn_capability = 1;
1368 break;
1369
1370 case NAN_REQ_ATTR_DISCOVERY_ATTR_NUM_ENTRIES:
1371 hal_req->num_config_discovery_attr = nla_get_u8(iter);
1372 break;
1373
1374 case NAN_REQ_ATTR_DISCOVERY_ATTR_VAL:
1375 if (disc_attr_idx >= hal_req->num_config_discovery_attr) {
1376 SLSI_ERR(sdev,
1377 "disc attr(%d) > num disc attr(%d)\n",
1378 disc_attr_idx + 1, hal_req->num_config_discovery_attr);
1379 return -EINVAL;
1380 }
1381 disc_attr = &hal_req->discovery_attr_val[disc_attr_idx];
1382 disc_attr_idx++;
1383 nla_for_each_nested(iter1, iter, tmp1) {
1384 type1 = nla_type(iter1);
1385 switch (type1) {
1386 case NAN_REQ_ATTR_CONN_TYPE:
1387 disc_attr->type = nla_get_u8(iter1);
1388 break;
1389
1390 case NAN_REQ_ATTR_NAN_ROLE:
1391 disc_attr->role = nla_get_u8(iter1);
1392 break;
1393
1394 case NAN_REQ_ATTR_TRANSMIT_FREQ:
1395 disc_attr->transmit_freq = nla_get_u8(iter1);
1396 break;
1397
1398 case NAN_REQ_ATTR_AVAILABILITY_DURATION:
1399 disc_attr->duration = nla_get_u8(iter1);
1400 break;
1401
1402 case NAN_REQ_ATTR_AVAILABILITY_INTERVAL:
1403 disc_attr->avail_interval_bitmap = nla_get_u32(iter1);
1404 break;
1405
1406 case NAN_REQ_ATTR_MAC_ADDR_VAL:
1407 memcpy(disc_attr->addr, nla_data(iter1), ETH_ALEN);
1408 break;
1409
1410 case NAN_REQ_ATTR_MESH_ID_LEN:
1411 disc_attr->mesh_id_len = nla_get_u16(iter1);
1412 break;
1413
1414 case NAN_REQ_ATTR_MESH_ID:
1415 memcpy(disc_attr->mesh_id, nla_data(iter1), disc_attr->mesh_id_len);
1416 break;
1417
1418 case NAN_REQ_ATTR_INFRASTRUCTURE_SSID_LEN:
1419 disc_attr->infrastructure_ssid_len = nla_get_u16(iter1);
1420 break;
1421
1422 case NAN_REQ_ATTR_INFRASTRUCTURE_SSID:
1423 memcpy(disc_attr->infrastructure_ssid_val, nla_data(iter1),
1424 disc_attr->infrastructure_ssid_len);
1425 break;
1426 }
1427 }
1428 break;
1429
1430 case NAN_REQ_ATTR_FURTHER_AVAIL_NUM_ENTRIES:
1431 hal_req->fam_val.numchans = nla_get_u8(iter);
1432 hal_req->config_fam = 1;
1433 break;
1434
1435 case NAN_REQ_ATTR_FURTHER_AVAIL_VAL:
1436 hal_req->config_fam = 1;
1437 if (famchan_idx >= hal_req->fam_val.numchans) {
1438 SLSI_ERR(sdev,
1439 "famchan attr(%d) > numchans(%d)\n",
1440 famchan_idx + 1, hal_req->fam_val.numchans);
1441 return -EINVAL;
1442 }
1443 famchan = &hal_req->fam_val.famchan[famchan_idx];
1444 famchan_idx++;
1445 nla_for_each_nested(iter1, iter, tmp1) {
1446 type1 = nla_type(iter1);
1447 switch (type1) {
1448 case NAN_REQ_ATTR_FURTHER_AVAIL_ENTRY_CTRL:
1449 famchan->entry_control = nla_get_u8(iter1);
1450 break;
1451
1452 case NAN_REQ_ATTR_FURTHER_AVAIL_CHAN_CLASS:
1453 famchan->class_val = nla_get_u8(iter1);
1454 break;
1455
1456 case NAN_REQ_ATTR_FURTHER_AVAIL_CHAN:
1457 famchan->channel = nla_get_u8(iter1);
1458 break;
1459
1460 case NAN_REQ_ATTR_FURTHER_AVAIL_CHAN_MAPID:
1461 famchan->mapid = nla_get_u8(iter1);
1462 break;
1463
1464 case NAN_REQ_ATTR_FURTHER_AVAIL_INTERVAL_BITMAP:
1465 famchan->avail_interval_bitmap = nla_get_u32(iter1);
1466 break;
1467 }
1468 }
1469 break;
1470
1471 case NAN_REQ_ATTR_SUBSCRIBE_SID_BEACON_VAL:
1472 hal_req->subscribe_sid_beacon_val = nla_get_u8(iter);
1473 hal_req->config_subscribe_sid_beacon = 1;
1474 break;
1475
1476 case NAN_REQ_ATTR_DW_2G4_INTERVAL:
1477 hal_req->dw_2dot4g_interval_val = nla_get_u8(iter);
1478 /* valid range for 2.4G is 1-5 */
1479 if (hal_req->dw_2dot4g_interval_val > 0 && hal_req->dw_2dot4g_interval_val < 6)
1480 hal_req->config_2dot4g_dw_band = 1;
1481 break;
1482
1483 case NAN_REQ_ATTR_DW_5G_INTERVAL:
1484 hal_req->dw_5g_interval_val = nla_get_u8(iter);
1485 /* valid range for 5g is 0-5 */
1486 if (hal_req->dw_5g_interval_val < 6)
1487 hal_req->config_5g_dw_band = 1;
1488 break;
1489
1490 case NAN_REQ_ATTR_DISC_MAC_ADDR_RANDOM_INTERVAL:
1491 hal_req->disc_mac_addr_rand_interval_sec = nla_get_u8(iter);
1492 break;
1493
781f598d
TK
1494 case NAN_REQ_ATTR_HAL_TRANSACTION_ID:
1495 hal_req->transaction_id = nla_get_u16(iter);
1496 break;
1497
533a23a1
TK
1498 default:
1499 SLSI_ERR(sdev, "Unexpected NAN config attribute TYPE:%d\n", type);
1500 return SLSI_HAL_NAN_STATUS_INVALID_PARAM;
1501 }
1502 }
1503 return SLSI_HAL_NAN_STATUS_SUCCESS;
1504}
1505
1506int slsi_nan_set_config(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
1507{
1508 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
1509 struct net_device *dev = slsi_nan_get_netdev(sdev);
1510 struct netdev_vif *ndev_vif;
781f598d 1511 u16 transaction_id = 0;
533a23a1
TK
1512 int ret;
1513 u32 reply_status = SLSI_HAL_NAN_STATUS_SUCCESS;
1514
781f598d
TK
1515 slsi_nan_pre_check(sdev, dev, &ret, &reply_status);
1516 if (ret != WIFI_HAL_SUCCESS)
533a23a1 1517 goto exit;
533a23a1
TK
1518
1519 ndev_vif = netdev_priv(dev);
781f598d
TK
1520
1521 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
1522 reply_status = slsi_nan_config_get_nl_params(sdev, &ndev_vif->nan.config, data, len);
533a23a1 1523 if (reply_status) {
781f598d 1524 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
533a23a1
TK
1525 ret = -EINVAL;
1526 goto exit;
1527 }
781f598d 1528 transaction_id = ndev_vif->nan.config.transaction_id;
533a23a1
TK
1529 if (!ndev_vif->activated) {
1530 SLSI_WARN(sdev, "NAN vif not activated\n");
1531 reply_status = SLSI_HAL_NAN_STATUS_NAN_NOT_ALLOWED;
1532 ret = WIFI_HAL_ERROR_NOT_AVAILABLE;
1533 } else {
781f598d
TK
1534 ret = slsi_mlme_nan_set_config(sdev, dev, &ndev_vif->nan.config);
1535 if (ret) {
533a23a1 1536 reply_status = SLSI_HAL_NAN_STATUS_INTERNAL_FAILURE;
781f598d
TK
1537 } else {
1538 if (ndev_vif->nan.config.config_master_pref)
1539 ndev_vif->nan.master_pref_value = ndev_vif->nan.config.master_pref;
1540 ndev_vif->nan.random_mac_interval_sec = ndev_vif->nan.config.disc_mac_addr_rand_interval_sec;
1541 SLSI_INFO(sdev, "transId:%d masterPref:%d\n",
1542 ndev_vif->nan.config.transaction_id, ndev_vif->nan.config.master_pref);
1543 }
533a23a1
TK
1544 }
1545 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
1546exit:
781f598d 1547 slsi_vendor_nan_command_reply(wiphy, reply_status, ret, NAN_RESPONSE_CONFIG, 0, NULL, transaction_id);
533a23a1
TK
1548 return ret;
1549}
1550
1551int slsi_nan_get_capabilities(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
1552{
1553 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
1554 struct net_device *dev = slsi_nan_get_netdev(sdev);
1555 struct netdev_vif *ndev_vif;
1556 u32 reply_status = SLSI_HAL_NAN_STATUS_SUCCESS;
1557 struct slsi_hal_nan_capabilities nan_capabilities;
1558 int ret = 0, i;
1559 struct slsi_mib_value *values = NULL;
1560 struct slsi_mib_data mibrsp = { 0, NULL };
1561 struct slsi_mib_get_entry get_values[] = {{ SLSI_PSID_UNIFI_NAN_MAX_CONCURRENT_CLUSTERS, { 0, 0 } },
1562 { SLSI_PSID_UNIFI_NAN_MAX_CONCURRENT_PUBLISHES, { 0, 0 } },
1563 { SLSI_PSID_UNIFI_NAN_MAX_CONCURRENT_SUBSCRIBES, { 0, 0 } },
1564 { SLSI_PSID_UNIFI_NAN_MAX_SERVICE_NAME_LENGTH, { 0, 0 } },
1565 { SLSI_PSID_UNIFI_NAN_MAX_MATCH_FILTER_LENGTH, { 0, 0 } },
1566 { SLSI_PSID_UNIFI_NAN_MAX_TOTAL_MATCH_FILTER_LENGTH, { 0, 0 } },
1567 { SLSI_PSID_UNIFI_NAN_MAX_SERVICE_SPECIFIC_INFO_LENGTH, { 0, 0 } },
1568 { SLSI_PSID_UNIFI_NAN_MAX_VSA_DATA_LENGTH, { 0, 0 } },
1569 { SLSI_PSID_UNIFI_NAN_MAX_MESH_DATA_LENGTH, { 0, 0 } },
1570 { SLSI_PSID_UNIFI_NAN_MAX_NDI_INTERFACES, { 0, 0 } },
1571 { SLSI_PSID_UNIFI_NAN_MAX_NDP_SESSIONS, { 0, 0 } },
1572 { SLSI_PSID_UNIFI_NAN_MAX_APP_INFO_LENGTH, { 0, 0 } } };
1573 u32 *capabilities_mib_val[] = { &nan_capabilities.max_concurrent_nan_clusters,
781f598d
TK
1574 &nan_capabilities.max_publishes,
1575 &nan_capabilities.max_subscribes,
1576 &nan_capabilities.max_service_name_len,
1577 &nan_capabilities.max_match_filter_len,
1578 &nan_capabilities.max_total_match_filter_len,
1579 &nan_capabilities.max_service_specific_info_len,
1580 &nan_capabilities.max_vsa_data_len,
1581 &nan_capabilities.max_mesh_data_len,
1582 &nan_capabilities.max_ndi_interfaces,
1583 &nan_capabilities.max_ndp_sessions,
1584 &nan_capabilities.max_app_info_len };
1585 int type, tmp;
1586 const struct nlattr *iter;
1587 u16 transaction_id = 0;
533a23a1 1588
781f598d
TK
1589 slsi_nan_pre_check(sdev, dev, &ret, &reply_status);
1590 if (ret != WIFI_HAL_SUCCESS)
533a23a1 1591 goto exit;
781f598d
TK
1592
1593 nla_for_each_attr(iter, data, len, tmp) {
1594 type = nla_type(iter);
1595 switch (type) {
1596 case NAN_REQ_ATTR_HAL_TRANSACTION_ID:
1597 transaction_id = nla_get_u16(iter);
1598 break;
1599 default:
1600 break;
1601 }
533a23a1
TK
1602 }
1603
1604 ndev_vif = netdev_priv(dev);
1605
1606 /* Expect each mib length in response is 11 */
1607 mibrsp.dataLength = 11 * ARRAY_SIZE(get_values);
1608 mibrsp.data = kmalloc(mibrsp.dataLength, GFP_KERNEL);
1609 if (!mibrsp.data) {
1610 SLSI_ERR(sdev, "Cannot kmalloc %d bytes\n", mibrsp.dataLength);
1611 reply_status = SLSI_HAL_NAN_STATUS_NO_RESOURCE_AVAILABLE;
1612 ret = -ENOMEM;
1613 goto exit;
1614 }
1615
1616 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
1617
1618 values = slsi_read_mibs(sdev, NULL, get_values, ARRAY_SIZE(get_values), &mibrsp);
1619 if (!values) {
1620 ret = 0xFFFFFFFF;
1621 reply_status = SLSI_HAL_NAN_STATUS_INTERNAL_FAILURE;
1622 goto exit_with_mibrsp;
1623 }
1624
1625 for (i = 0; i < (int)ARRAY_SIZE(get_values); i++) {
1626 if (values[i].type == SLSI_MIB_TYPE_UINT) {
1627 *capabilities_mib_val[i] = values[i].u.uintValue;
781f598d 1628 SLSI_DBG2(sdev, SLSI_GSCAN, "MIB value = %u\n", *capabilities_mib_val[i]);
533a23a1
TK
1629 } else {
1630 SLSI_ERR(sdev, "invalid type(%d). iter:%d\n", values[i].type, i);
1631 ret = 0xFFFFFFFF;
1632 reply_status = SLSI_HAL_NAN_STATUS_INTERNAL_FAILURE;
1633 *capabilities_mib_val[i] = 0;
1634 }
1635 }
1636
781f598d
TK
1637 if (!nan_capabilities.max_ndi_interfaces)
1638 nan_capabilities.max_ndi_interfaces = slsi_get_nan_max_ndi_ifaces();
1639 if (!nan_capabilities.max_ndp_sessions)
1640 nan_capabilities.max_ndi_interfaces = slsi_get_nan_max_ndp_instances();
1641
1642 if (nan_capabilities.max_ndi_interfaces > SLSI_NAN_MAX_NDP_INSTANCES) {
1643 SLSI_ERR(sdev, "max ndp if's:%d but supported:%d\n", nan_capabilities.max_ndi_interfaces,
1644 SLSI_NAN_MAX_NDP_INSTANCES);
1645 nan_capabilities.max_ndi_interfaces = SLSI_NAN_MAX_NDP_INSTANCES;
1646 }
1647
1648 if (nan_capabilities.max_ndp_sessions > SLSI_NAN_MAX_NDP_INSTANCES) {
1649 SLSI_ERR(sdev, "max ndp if's:%d but supported:%d\n", nan_capabilities.max_ndp_sessions,
1650 SLSI_NAN_MAX_NDP_INSTANCES);
1651 nan_capabilities.max_ndi_interfaces = SLSI_NAN_MAX_NDP_INSTANCES;
1652 }
1653
1654 SLSI_INFO(sdev, "transId:%d\n", transaction_id);
1655
533a23a1
TK
1656 kfree(values);
1657exit_with_mibrsp:
1658 kfree(mibrsp.data);
1659 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
1660exit:
781f598d 1661 slsi_vendor_nan_command_reply(wiphy, reply_status, ret, NAN_RESPONSE_GET_CAPABILITIES, 0, &nan_capabilities, transaction_id);
533a23a1
TK
1662 return ret;
1663}
1664
781f598d 1665int slsi_nan_data_iface_create(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
533a23a1 1666{
781f598d
TK
1667 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
1668 u8 *iface_name = NULL;
1669 int ret = 0, if_idx, type, tmp, err;
1670 struct net_device *dev = slsi_nan_get_netdev(sdev);
1671 struct net_device *dev_ndp = NULL;
1672 u32 reply_status = SLSI_HAL_NAN_STATUS_SUCCESS;
1673 const struct nlattr *iter;
1674 u16 transaction_id = 0;
533a23a1 1675
781f598d
TK
1676 slsi_nan_pre_check(sdev, dev, &ret, &reply_status);
1677 if (ret != WIFI_HAL_SUCCESS)
1678 goto exit;
533a23a1 1679
781f598d
TK
1680 nla_for_each_attr(iter, data, len, tmp) {
1681 type = nla_type(iter);
1682 if (type == NAN_REQ_ATTR_DATA_INTERFACE_NAME)
1683 iface_name = nla_data(iter);
1684 else if (type == NAN_REQ_ATTR_HAL_TRANSACTION_ID)
1685 transaction_id = nla_get_u16(iter);
533a23a1 1686 }
781f598d
TK
1687 if (!iface_name) {
1688 SLSI_ERR(sdev, "No NAN data interface name\n");
1689 ret = WIFI_HAL_ERROR_INVALID_ARGS;
1690 reply_status = SLSI_HAL_NAN_STATUS_INVALID_PARAM;
1691 goto exit;
533a23a1
TK
1692 }
1693
781f598d
TK
1694 SLSI_MUTEX_LOCK(sdev->netdev_add_remove_mutex);
1695 /* Find unused netdev idx */
1696 for (if_idx = SLSI_NAN_DATA_IFINDEX_START; if_idx < CONFIG_SCSC_WLAN_MAX_INTERFACES + 1; if_idx++) {
1697 dev_ndp = slsi_get_netdev_locked(sdev, if_idx);
1698 if (!dev_ndp)
1699 break;
533a23a1
TK
1700 }
1701
781f598d
TK
1702 if (if_idx >= CONFIG_SCSC_WLAN_MAX_INTERFACES + 1) {
1703 SLSI_ERR(sdev, "NAN no free NAN data interfaces\n");
1704 ret = WIFI_HAL_ERROR_TOO_MANY_REQUESTS;
1705 reply_status = SLSI_HAL_NAN_STATUS_INVALID_PARAM;
1706 goto exit_with_lock;
533a23a1
TK
1707 }
1708
781f598d
TK
1709 err = slsi_netif_add_locked(sdev, iface_name, if_idx);
1710 if (err) {
1711 SLSI_ERR(sdev, "NAN fail net_if_add if_name:%s, if_idx:%d\n", iface_name, if_idx);
1712 ret = WIFI_HAL_ERROR_OUT_OF_MEMORY;
1713 reply_status = SLSI_HAL_NAN_STATUS_NO_RESOURCE_AVAILABLE;
1714 goto exit_with_lock;
533a23a1
TK
1715 }
1716
781f598d
TK
1717 dev_ndp = slsi_get_netdev_locked(sdev, if_idx);
1718 err = slsi_netif_register_locked(sdev, dev_ndp);
1719 if (err) {
1720 SLSI_ERR(sdev, "NAN fail netdev err:%d if_name:%s, if_idx:%d\n", err);
1721 ret = WIFI_HAL_ERROR_UNKNOWN;
1722 reply_status = SLSI_HAL_NAN_STATUS_NO_RESOURCE_AVAILABLE;
1723 } else {
1724 SLSI_INFO(sdev, "trans_id:%d, if_name:%s, if_idx:%d\n", transaction_id, iface_name, if_idx);
1725 }
1726
1727exit_with_lock:
1728 SLSI_MUTEX_UNLOCK(sdev->netdev_add_remove_mutex);
1729exit:
1730 slsi_vendor_nan_command_reply(wiphy, reply_status, ret, NAN_DP_INTERFACE_CREATE, 0, NULL, transaction_id);
1731 return ret;
1732}
1733
1734int slsi_nan_data_iface_delete(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
1735{
1736 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
1737 u8 *iface_name = NULL;
1738 int ret = 0, if_idx, type, tmp;
1739 struct net_device *dev = slsi_nan_get_netdev(sdev);
1740 struct net_device *dev_ndp = NULL;
1741 u32 reply_status = SLSI_HAL_NAN_STATUS_SUCCESS;
1742 const struct nlattr *iter;
1743 u16 transaction_id = 0;
1744
1745 slsi_nan_pre_check(sdev, dev, &ret, &reply_status);
1746 if (ret != WIFI_HAL_SUCCESS)
1747 goto exit;
1748
1749 nla_for_each_attr(iter, data, len, tmp) {
1750 type = nla_type(iter);
1751 if (type == NAN_REQ_ATTR_DATA_INTERFACE_NAME)
1752 iface_name = nla_data(iter);
1753 else if (type == NAN_REQ_ATTR_HAL_TRANSACTION_ID)
1754 transaction_id = nla_get_u16(iter);
1755 }
1756 if (!iface_name) {
1757 SLSI_ERR(sdev, "No NAN data interface name\n");
1758 ret = WIFI_HAL_ERROR_INVALID_ARGS;
1759 reply_status = SLSI_HAL_NAN_STATUS_INVALID_PARAM;
1760 goto exit;
1761 }
1762
1763 SLSI_MUTEX_LOCK(sdev->netdev_add_remove_mutex);
1764 for (if_idx = SLSI_NAN_DATA_IFINDEX_START; if_idx < CONFIG_SCSC_WLAN_MAX_INTERFACES + 1; if_idx++) {
1765 dev_ndp = slsi_get_netdev_locked(sdev, if_idx);
1766 if (dev_ndp && strcmp(iface_name, dev_ndp->name) == 0)
1767 break;
1768 dev_ndp = NULL;
1769 }
1770
1771 if (dev_ndp) {
1772 slsi_netif_remove_locked(sdev, dev_ndp);
1773 SLSI_INFO(sdev, "Success transId:%d ifaceName:%s\n", transaction_id, iface_name);
1774 }
1775
1776 SLSI_MUTEX_UNLOCK(sdev->netdev_add_remove_mutex);
1777exit:
1778 slsi_vendor_nan_command_reply(wiphy, reply_status, ret, NAN_DP_INTERFACE_DELETE, 0, NULL, transaction_id);
1779 return ret;
1780}
1781
1782int slsi_nan_ndp_initiate_get_nl_params(struct slsi_dev *sdev, struct slsi_hal_nan_data_path_initiator_req *hal_req,
1783 const void *data, int len)
1784{
1785 int type, tmp, r;
1786 const struct nlattr *iter;
1787
1788 memset(hal_req, 0, sizeof(*hal_req));
1789 nla_for_each_attr(iter, data, len, tmp) {
1790 type = nla_type(iter);
1791 switch (type) {
1792 case NAN_REQ_ATTR_REQ_INSTANCE_ID:
1793 hal_req->requestor_instance_id = nla_get_u32(iter);
1794 break;
1795
1796 case NAN_REQ_ATTR_CHAN_REQ_TYPE:
1797 hal_req->channel_request_type = nla_get_u8(iter);
1798 break;
1799
1800 case NAN_REQ_ATTR_CHAN:
1801 hal_req->channel = nla_get_u32(iter);
1802 break;
1803
1804 case NAN_REQ_ATTR_MAC_ADDR_VAL:
1805 ether_addr_copy(hal_req->peer_disc_mac_addr, nla_data(iter));
1806 break;
1807
1808 case NAN_REQ_ATTR_DATA_INTERFACE_NAME:
1809 memcpy(hal_req->ndp_iface, nla_data(iter), IFNAMSIZ);
1810 break;
1811
1812 case NAN_REQ_ATTR_DATA_INTERFACE_NAME_LEN:
1813 break;
1814
1815 case NAN_REQ_ATTR_SDEA_PARAM_SECURITY_CFG:
1816 hal_req->ndp_cfg.security_cfg = nla_get_u8(iter);
1817 break;
1818
1819 case NAN_REQ_ATTR_SDEA_PARAM_QOS_CFG:
1820 hal_req->ndp_cfg.qos_cfg = nla_get_u8(iter);
1821 break;
1822
1823 case NAN_REQ_ATTR_APP_INFO_LEN:
1824 hal_req->app_info.ndp_app_info_len = nla_get_u16(iter);
1825 break;
1826
1827 case NAN_REQ_ATTR_APP_INFO:
1828 memcpy(hal_req->app_info.ndp_app_info, nla_data(iter), hal_req->app_info.ndp_app_info_len);
1829 break;
1830
1831 case NAN_REQ_ATTR_SERVICE_NAME_LEN:
1832 hal_req->service_name_len = nla_get_u32(iter);
1833 break;
1834
1835 case NAN_REQ_ATTR_SERVICE_NAME:
1836 memcpy(hal_req->service_name, nla_data(iter), hal_req->service_name_len);
1837 break;
1838
1839 case NAN_REQ_ATTR_HAL_TRANSACTION_ID:
1840 hal_req->transaction_id = nla_get_u16(iter);
1841 break;
1842
1843 default:
1844 r = slsi_nan_get_security_info_nl(sdev, &hal_req->key_info, iter, type);
1845 if (r)
1846 SLSI_ERR(sdev, "Unexpected NAN ndp attribute TYPE:%d\n", type);
1847 }
1848 }
1849 return SLSI_HAL_NAN_STATUS_SUCCESS;
1850}
1851
1852int slsi_nan_ndp_initiate(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
1853{
1854 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
1855 struct net_device *dev = slsi_nan_get_netdev(sdev);
1856 struct netdev_vif *ndev_vif;
1857 struct slsi_hal_nan_data_path_initiator_req *hal_req = NULL;
1858 int ret;
1859 u32 ndp_id = 0;
1860 u16 ndl_vif_id, transaction_id = 0;
1861 u32 reply_status = SLSI_HAL_NAN_STATUS_SUCCESS;
1862
1863 slsi_nan_pre_check(sdev, dev, &ret, &reply_status);
1864 if (ret != WIFI_HAL_SUCCESS)
1865 goto exit;
1866
1867 hal_req = kmalloc(sizeof(*hal_req), GFP_KERNEL);
1868 if (!hal_req) {
1869 SLSI_ERR(sdev, "Failed to alloc hal_req structure!!!\n");
1870 reply_status = SLSI_HAL_NAN_STATUS_NO_RESOURCE_AVAILABLE;
1871 ret = WIFI_HAL_ERROR_OUT_OF_MEMORY;
1872 goto exit;
1873 }
1874
1875 ndev_vif = netdev_priv(dev);
1876 reply_status = slsi_nan_ndp_initiate_get_nl_params(sdev, hal_req, data, len);
1877 if (reply_status) {
1878 ret = WIFI_HAL_ERROR_INVALID_ARGS;
1879 goto exit;
1880 }
1881 transaction_id = hal_req->transaction_id;
1882
1883 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
1884 if (!ndev_vif->activated) {
1885 SLSI_WARN(sdev, "NAN vif not activated\n");
1886 reply_status = SLSI_HAL_NAN_STATUS_NAN_NOT_ALLOWED;
1887 ret = WIFI_HAL_ERROR_NOT_AVAILABLE;
1888 goto exit_with_lock;
1889 }
1890
1891 ndp_id = slsi_nan_get_new_ndp_id(ndev_vif);
1892 if (!ndp_id) {
1893 SLSI_WARN(sdev, "NAN no free ndp slots\n");
1894 reply_status = SLSI_HAL_NAN_STATUS_NO_RESOURCE_AVAILABLE;
1895 ret = WIFI_HAL_ERROR_TOO_MANY_REQUESTS;
1896 goto exit_with_lock;
1897 }
1898
1899 ndl_vif_id = slsi_nan_ndp_get_ndl_vif_id(hal_req->peer_disc_mac_addr, ndev_vif->nan.ndl_list);
1900 if (ndl_vif_id >= SLSI_NAN_MAX_NDP_INSTANCES + SLSI_NAN_DATA_IFINDEX_START) {
1901 SLSI_WARN(sdev, "NAN no free ndl slots\n");
1902 reply_status = SLSI_HAL_NAN_STATUS_NO_RESOURCE_AVAILABLE;
1903 ret = WIFI_HAL_ERROR_TOO_MANY_REQUESTS;
1904 goto exit_with_lock;
1905 }
1906 ret = slsi_mlme_ndp_request(sdev, dev, hal_req, ndp_id, ndl_vif_id);
1907 if (ret) {
1908 reply_status = SLSI_HAL_NAN_STATUS_INTERNAL_FAILURE;
1909 ret = WIFI_HAL_ERROR_UNKNOWN;
1910 } else {
1911 SLSI_INFO(sdev, "transId:%d ndpId:%d ndlVifId:%d iface:%s\n",
1912 hal_req->transaction_id, ndp_id, ndl_vif_id, hal_req->ndp_iface);
1913 ret = WIFI_HAL_SUCCESS;
1914 }
1915
1916exit_with_lock:
1917 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
1918exit:
1919 slsi_vendor_nan_command_reply(wiphy, reply_status, ret, NAN_DP_INITIATOR_RESPONSE, (u16)ndp_id, NULL, transaction_id);
1920 kfree(hal_req);
1921 return ret;
1922}
1923
1924int slsi_nan_ndp_respond_get_nl_param(struct slsi_dev *sdev, struct slsi_hal_nan_data_path_indication_response *hal_req,
1925 const void *data, int len)
1926{
1927 int type, tmp, r;
1928 const struct nlattr *iter;
1929
1930 memset(hal_req, 0, sizeof(*hal_req));
1931 nla_for_each_attr(iter, data, len, tmp) {
1932 type = nla_type(iter);
1933 switch (type) {
1934 case NAN_REQ_ATTR_NDP_INSTANCE_ID:
1935 hal_req->ndp_instance_id = nla_get_u32(iter);
1936 break;
1937
1938 case NAN_REQ_ATTR_DATA_INTERFACE_NAME:
1939 memcpy(hal_req->ndp_iface, nla_data(iter), IFNAMSIZ);
1940 break;
1941 case NAN_REQ_ATTR_DATA_INTERFACE_NAME_LEN:
1942 break;
1943
1944 case NAN_REQ_ATTR_SDEA_PARAM_SECURITY_CFG:
1945 hal_req->ndp_cfg.security_cfg = nla_get_u8(iter);
1946 break;
1947
1948 case NAN_REQ_ATTR_SDEA_PARAM_QOS_CFG:
1949 hal_req->ndp_cfg.qos_cfg = nla_get_u8(iter);
1950 break;
1951
1952 case NAN_REQ_ATTR_APP_INFO_LEN:
1953 hal_req->app_info.ndp_app_info_len = nla_get_u16(iter);
1954 break;
1955
1956 case NAN_REQ_ATTR_APP_INFO:
1957 memcpy(hal_req->app_info.ndp_app_info, nla_data(iter), hal_req->app_info.ndp_app_info_len);
1958 break;
1959
1960 case NAN_REQ_ATTR_NDP_RESPONSE_CODE:
1961 hal_req->rsp_code = nla_get_u8(iter);
1962 break;
1963
1964 case NAN_REQ_ATTR_SERVICE_NAME_LEN:
1965 hal_req->service_name_len = nla_get_u32(iter);
1966 break;
1967
1968 case NAN_REQ_ATTR_SERVICE_NAME:
1969 memcpy(hal_req->service_name, nla_data(iter), hal_req->service_name_len);
1970 break;
1971
1972 case NAN_REQ_ATTR_HAL_TRANSACTION_ID:
1973 hal_req->transaction_id = nla_get_u16(iter);
1974 break;
1975
1976 default:
1977 r = 0;
1978 r = slsi_nan_get_security_info_nl(sdev, &hal_req->key_info, iter, type);
1979 if (r)
1980 SLSI_ERR(sdev, "Unexpected NAN ndp attribute TYPE:%d\n", type);
1981 }
1982 }
1983 return SLSI_HAL_NAN_STATUS_SUCCESS;
1984}
1985
1986int slsi_nan_ndp_respond(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
1987{
1988 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
1989 struct net_device *dev = slsi_nan_get_netdev(sdev);
1990 struct netdev_vif *ndev_vif;
1991 struct slsi_hal_nan_data_path_indication_response *hal_req = NULL;
1992 int ret;
1993 u32 reply_status = SLSI_HAL_NAN_STATUS_SUCCESS;
1994 u16 transaction_id = 0, ndp_instance_id = 0;
1995
1996 slsi_nan_pre_check(sdev, dev, &ret, &reply_status);
1997 if (ret != WIFI_HAL_SUCCESS)
1998 goto exit;
1999
2000 hal_req = kmalloc(sizeof(*hal_req), GFP_KERNEL);
2001 if (!hal_req) {
2002 SLSI_ERR(sdev, "Failed to alloc hal_req structure!!!\n");
2003 reply_status = SLSI_HAL_NAN_STATUS_NO_RESOURCE_AVAILABLE;
2004 ret = WIFI_HAL_ERROR_OUT_OF_MEMORY;
2005 goto exit;
2006 }
2007
2008 ndev_vif = netdev_priv(dev);
2009 reply_status = slsi_nan_ndp_respond_get_nl_param(sdev, hal_req, data, len);
2010 transaction_id = hal_req->transaction_id;
2011 ndp_instance_id = hal_req->ndp_instance_id;
2012 if (reply_status) {
2013 ret = WIFI_HAL_ERROR_INVALID_ARGS;
2014 goto exit;
2015 }
2016
2017 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
2018 if (!ndev_vif->activated) {
2019 SLSI_WARN(sdev, "NAN vif not activated\n");
2020 reply_status = SLSI_HAL_NAN_STATUS_NAN_NOT_ALLOWED;
2021 ret = WIFI_HAL_ERROR_NOT_AVAILABLE;
2022 goto exit_with_lock;
2023 }
2024
2025 ret = slsi_mlme_ndp_response(sdev, dev, hal_req, ndev_vif->nan.ndp_local_ndp_id[hal_req->ndp_instance_id - 1]);
2026 if (ret) {
2027 reply_status = SLSI_HAL_NAN_STATUS_INTERNAL_FAILURE;
2028 ret = WIFI_HAL_ERROR_UNKNOWN;
2029 } else {
2030 SLSI_INFO(sdev, "transId:%d ndpId:%d iface:%s\n",
2031 hal_req->transaction_id, hal_req->ndp_instance_id, hal_req->ndp_iface);
2032 ret = WIFI_HAL_SUCCESS;
2033 }
2034
2035exit_with_lock:
2036 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
2037exit:
2038 slsi_vendor_nan_command_reply(wiphy, reply_status, ret, NAN_DP_RESPONDER_RESPONSE,
2039 ndp_instance_id, NULL, transaction_id);
2040 kfree(hal_req);
2041 return ret;
2042}
2043
2044int slsi_nan_ndp_end_get_nl_params(struct slsi_dev *sdev, struct slsi_hal_nan_data_end *hal_req,
2045 const void *data, int len)
2046{
2047 int type, tmp;
2048 const struct nlattr *iter;
2049
2050 memset(hal_req, 0, sizeof(*hal_req));
2051 nla_for_each_attr(iter, data, len, tmp) {
2052 type = nla_type(iter);
2053 if (type == NAN_REQ_ATTR_NDP_INSTANCE_ID && hal_req->num_ndp_instances < SLSI_NAN_MAX_NDP_INSTANCES)
2054 hal_req->ndp_instance_id[hal_req->num_ndp_instances++] = nla_get_u32(iter);
2055 else if (type == NAN_REQ_ATTR_HAL_TRANSACTION_ID)
2056 hal_req->transaction_id = nla_get_u16(iter);
2057 }
2058 return SLSI_HAL_NAN_STATUS_SUCCESS;
2059}
2060
2061int slsi_nan_ndp_end(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
2062{
2063 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
2064 struct net_device *dev = slsi_nan_get_netdev(sdev);
2065 struct netdev_vif *ndev_vif;
2066 struct slsi_hal_nan_data_end hal_req;
2067 int ret, i;
2068 u32 reply_status = SLSI_HAL_NAN_STATUS_SUCCESS;
2069
2070 hal_req.transaction_id = 0;
2071 slsi_nan_pre_check(sdev, dev, &ret, &reply_status);
2072 if (ret != WIFI_HAL_SUCCESS)
2073 goto exit;
2074
2075 ndev_vif = netdev_priv(dev);
2076 reply_status = slsi_nan_ndp_end_get_nl_params(sdev, &hal_req, data, len);
2077
2078 if (reply_status) {
2079 ret = WIFI_HAL_ERROR_INVALID_ARGS;
2080 goto exit;
2081 }
2082
2083 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
2084 if (!ndev_vif->activated) {
2085 SLSI_WARN(sdev, "NAN vif not activated\n");
2086 slsi_nan_ndp_termination_handler(sdev, dev, 0, 0, NULL);
2087 ret = WIFI_HAL_SUCCESS;
2088 goto exit_with_lock;
2089 }
2090 for (i = 0; i < hal_req.num_ndp_instances; i++)
2091 if (hal_req.ndp_instance_id[i] > 0 && hal_req.ndp_instance_id[i] <= SLSI_NAN_MAX_NDP_INSTANCES) {
2092 ndev_vif->nan.ndp_state[hal_req.ndp_instance_id[i] - 1] = ndp_slot_status_terminating;
2093 slsi_mlme_ndp_terminate(sdev, dev, hal_req.ndp_instance_id[i]);
2094 SLSI_INFO(sdev, "transId:%d ndpId:%d [%d/%d]\n",
2095 hal_req.transaction_id, hal_req.ndp_instance_id[i], i, hal_req.num_ndp_instances);
2096 } else {
2097 SLSI_ERR(sdev, "Ignore invalid ndp_id:%d\n", hal_req.ndp_instance_id[i]);
2098 }
2099
2100exit_with_lock:
2101 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
2102exit:
2103 slsi_vendor_nan_command_reply(wiphy, reply_status, ret, NAN_DP_END, 0, NULL, hal_req.transaction_id);
2104 return ret;
2105}
2106
2107/* NAN HAL EVENTS */
2108
2109void slsi_nan_event(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb)
2110{
2111 struct sk_buff *nl_skb = NULL;
2112 int res = 0;
2113 u16 event, identifier, evt_reason;
2114 u8 *mac_addr;
2115 u16 hal_event;
2116 struct netdev_vif *ndev_vif;
2117 enum slsi_nan_disc_event_type disc_event_type = 0;
2118
2119 ndev_vif = netdev_priv(dev);
2120 event = fapi_get_u16(skb, u.mlme_nan_event_ind.event);
2121 identifier = fapi_get_u16(skb, u.mlme_nan_event_ind.identifier);
2122 mac_addr = fapi_get_buff(skb, u.mlme_nan_event_ind.address_or_identifier);
2123
2124 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
2125
2126 switch (fapi_get_u16(skb, u.mlme_nan_event_ind.reason_code)) {
2127 case FAPI_REASONCODE_NAN_SERVICE_TERMINATED_TIMEOUT:
2128 case FAPI_REASONCODE_NAN_SERVICE_TERMINATED_COUNT_REACHED:
2129 case FAPI_REASONCODE_NAN_SERVICE_TERMINATED_DISCOVERY_SHUTDOWN:
2130 case FAPI_REASONCODE_NAN_SERVICE_TERMINATED_USER_REQUEST:
2131 case FAPI_REASONCODE_NAN_TRANSMIT_FOLLOWUP_SUCCESS:
2132 evt_reason = SLSI_HAL_NAN_STATUS_SUCCESS;
2133 break;
2134 case FAPI_REASONCODE_NAN_TRANSMIT_FOLLOWUP_FAILURE:
2135 evt_reason = SLSI_HAL_NAN_STATUS_PROTOCOL_FAILURE;
2136 break;
2137 default:
2138 evt_reason = SLSI_HAL_NAN_STATUS_INTERNAL_FAILURE;
2139 break;
2140 }
2141
2142 switch (event) {
2143 case FAPI_EVENT_WIFI_EVENT_NAN_PUBLISH_TERMINATED:
2144 ndev_vif->nan.service_id_map &= (u32)~BIT(identifier);
2145 if (ndev_vif->nan.nan_sdf_flags[identifier] & FAPI_NANSDFCONTROL_PUBLISH_END_EVENT)
2146 goto exit;
2147 hal_event = SLSI_NL80211_NAN_PUBLISH_TERMINATED_EVENT;
2148 break;
2149 case FAPI_EVENT_WIFI_EVENT_NAN_MATCH_EXPIRED:
2150 if (ndev_vif->nan.nan_sdf_flags[identifier] & FAPI_NANSDFCONTROL_MATCH_EXPIRED_EVENT)
2151 goto exit;
2152 hal_event = SLSI_NL80211_NAN_MATCH_EXPIRED_EVENT;
2153 break;
2154 case FAPI_EVENT_WIFI_EVENT_NAN_SUBSCRIBE_TERMINATED:
2155 ndev_vif->nan.service_id_map &= (u32)~BIT(identifier);
2156 if (ndev_vif->nan.nan_sdf_flags[identifier] & FAPI_NANSDFCONTROL_SUBSCRIBE_END_EVENT)
2157 goto exit;
2158 hal_event = SLSI_NL80211_NAN_SUBSCRIBE_TERMINATED_EVENT;
2159 break;
2160 case FAPI_EVENT_WIFI_EVENT_NAN_ADDRESS_CHANGED:
2161 disc_event_type = NAN_EVENT_ID_DISC_MAC_ADDR;
2162 hal_event = SLSI_NL80211_NAN_DISCOVERY_ENGINE_EVENT;
2163 ether_addr_copy(ndev_vif->nan.local_nmi, mac_addr);
2164 break;
2165 case FAPI_EVENT_WIFI_EVENT_NAN_CLUSTER_STARTED:
2166 disc_event_type = NAN_EVENT_ID_STARTED_CLUSTER;
2167 hal_event = SLSI_NL80211_NAN_DISCOVERY_ENGINE_EVENT;
2168 ether_addr_copy(ndev_vif->nan.cluster_id, mac_addr);
2169 break;
2170 case FAPI_EVENT_WIFI_EVENT_NAN_CLUSTER_JOINED:
2171 disc_event_type = NAN_EVENT_ID_JOINED_CLUSTER;
2172 hal_event = SLSI_NL80211_NAN_DISCOVERY_ENGINE_EVENT;
2173 ether_addr_copy(ndev_vif->nan.cluster_id, mac_addr);
2174 break;
2175 case FAPI_EVENT_WIFI_EVENT_NAN_TRANSMIT_FOLLOWUP:
2176 if (ndev_vif->nan.nan_sdf_flags[identifier] & FAPI_NANSDFCONTROL_FOLLOWUP_TRANSMIT_STATUS)
2177 goto exit;
2178 hal_event = SLSI_NL80211_NAN_TRANSMIT_FOLLOWUP_STATUS;
2179 break;
2180 default:
2181 goto exit;
2182 }
2183
2184#ifdef CONFIG_SCSC_WLAN_DEBUG
2185 SLSI_INFO(sdev, "Event: %s(%d)\n",
2186 slsi_print_event_name(hal_event), hal_event);
2187#endif
2188
2189#if (KERNEL_VERSION(4, 1, 0) <= LINUX_VERSION_CODE)
2190 nl_skb = cfg80211_vendor_event_alloc(sdev->wiphy, NULL, NLMSG_DEFAULT_SIZE, hal_event, GFP_KERNEL);
2191#else
2192 nl_skb = cfg80211_vendor_event_alloc(sdev->wiphy, NLMSG_DEFAULT_SIZE, hal_event, GFP_KERNEL);
2193#endif
2194 if (!nl_skb) {
2195 SLSI_ERR(sdev, "NO MEM for nl_skb!!!\n");
2196 goto exit;
2197 }
2198
2199 res |= nla_put_be16(nl_skb, NAN_EVT_ATTR_STATUS, evt_reason);
2200 switch (hal_event) {
2201 case SLSI_NL80211_NAN_PUBLISH_TERMINATED_EVENT:
2202 res |= nla_put_be16(nl_skb, NAN_EVT_ATTR_PUBLISH_ID, identifier);
2203 break;
2204 case SLSI_NL80211_NAN_MATCH_EXPIRED_EVENT:
2205 res |= nla_put_be16(nl_skb, NAN_EVT_ATTR_MATCH_PUBLISH_SUBSCRIBE_ID, identifier);
2206 break;
2207 case SLSI_NL80211_NAN_SUBSCRIBE_TERMINATED_EVENT:
2208 res |= nla_put_be16(nl_skb, NAN_EVT_ATTR_SUBSCRIBE_ID, identifier);
2209 break;
2210 case SLSI_NL80211_NAN_DISCOVERY_ENGINE_EVENT:
2211 res |= nla_put_be16(nl_skb, NAN_EVT_ATTR_DISCOVERY_ENGINE_EVT_TYPE, disc_event_type);
2212 res |= nla_put(nl_skb, NAN_EVT_ATTR_DISCOVERY_ENGINE_MAC_ADDR, ETH_ALEN, mac_addr);
2213 break;
2214 case SLSI_NL80211_NAN_TRANSMIT_FOLLOWUP_STATUS:
2215 res |= nla_put_u16(nl_skb, NAN_EVT_ATTR_HAL_TRANSACTION_ID, ndev_vif->nan.followup_trans_id);
2216 ndev_vif->nan.followup_trans_id = 0;
2217 break;
2218 }
2219
2220 if (res) {
2221 SLSI_ERR(sdev, "Error in nla_put*:%x\n", res);
2222 /* Dont use slsi skb wrapper for this free */
2223 kfree_skb(nl_skb);
2224 goto exit;
2225 }
2226
2227 cfg80211_vendor_event(nl_skb, GFP_KERNEL);
2228
2229exit:
2230 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
2231 slsi_kfree_skb(skb);
2232}
533a23a1
TK
2233
2234void slsi_nan_followup_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb)
2235{
2236 u16 tag_id, tag_len;
2237 u8 *ptr;
2238 struct slsi_hal_nan_followup_ind *hal_evt;
2239 struct sk_buff *nl_skb;
2240 int res;
2241 int sig_data_len;
781f598d 2242 struct netdev_vif *ndev_vif = netdev_priv(dev);
533a23a1
TK
2243
2244 SLSI_DBG3(sdev, SLSI_GSCAN, "\n");
2245
781f598d 2246 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
533a23a1 2247 sig_data_len = fapi_get_datalen(skb);
533a23a1
TK
2248
2249 hal_evt = kmalloc(sizeof(*hal_evt), GFP_KERNEL);
2250 if (!hal_evt) {
2251 SLSI_ERR(sdev, "No memory for followup_ind\n");
781f598d 2252 goto exit;
533a23a1
TK
2253 }
2254 memset(hal_evt, 0, sizeof(*hal_evt));
2255
781f598d 2256 hal_evt->publish_subscribe_id = fapi_get_u16(skb, u.mlme_nan_followup_ind.session_id);
533a23a1
TK
2257 hal_evt->requestor_instance_id = fapi_get_u16(skb, u.mlme_nan_followup_ind.match_id);
2258 ether_addr_copy(hal_evt->addr,
2259 fapi_get_buff(skb, u.mlme_nan_followup_ind.peer_nan_management_interface_address));
2260
2261 ptr = fapi_get_data(skb);
781f598d
TK
2262 if (ptr) {
2263 tag_id = le16_to_cpu(*(u16 *)ptr);
2264 tag_len = le16_to_cpu(*(u16 *)(ptr + 2));
2265
2266 while (sig_data_len >= tag_len + 4) {
2267 if (tag_id == SLSI_NAN_TLV_TAG_SERVICE_SPECIFIC_INFO) {
2268 hal_evt->service_specific_info_len = tag_len > SLSI_HAL_NAN_MAX_SERVICE_SPECIFIC_INFO_LEN ?
2269 SLSI_HAL_NAN_MAX_SERVICE_SPECIFIC_INFO_LEN : tag_len;
2270 memcpy(hal_evt->service_specific_info, ptr + 4, hal_evt->service_specific_info_len);
2271 } else if (tag_id == SLSI_NAN_TLV_TAG_EXT_SERVICE_SPECIFIC_INFO) {
2272 if (tag_len > SLSI_HAL_NAN_MAX_SDEA_SERVICE_SPEC_INFO_LEN)
2273 hal_evt->sdea_service_specific_info_len = SLSI_HAL_NAN_MAX_SDEA_SERVICE_SPEC_INFO_LEN;
2274 else
2275 hal_evt->sdea_service_specific_info_len = tag_len;
2276 memcpy(hal_evt->sdea_service_specific_info, ptr + 4, hal_evt->sdea_service_specific_info_len);
2277 } else {
2278 SLSI_WARN(sdev, "Skip processing TLV %d\n", tag_id);
2279 }
2280 sig_data_len -= tag_len + 4;
2281 ptr += tag_len + 4;
2282 if (sig_data_len > 4) {
2283 tag_id = le16_to_cpu(*(u16 *)ptr);
2284 tag_len = le16_to_cpu(*(u16 *)(ptr + 2));
2285 } else {
2286 tag_id = 0;
2287 tag_len = 0;
2288 }
533a23a1
TK
2289 }
2290 }
2291
2292#ifdef CONFIG_SCSC_WLAN_DEBUG
781f598d
TK
2293 SLSI_INFO(sdev, "Event: %s(%d)\n",
2294 slsi_print_event_name(SLSI_NL80211_NAN_FOLLOWUP_EVENT), SLSI_NL80211_NAN_FOLLOWUP_EVENT);
533a23a1
TK
2295#endif
2296#if (KERNEL_VERSION(4, 1, 0) <= LINUX_VERSION_CODE)
2297 nl_skb = cfg80211_vendor_event_alloc(sdev->wiphy, NULL, NLMSG_DEFAULT_SIZE, SLSI_NL80211_NAN_FOLLOWUP_EVENT,
2298 GFP_KERNEL);
2299#else
2300 nl_skb = cfg80211_vendor_event_alloc(sdev->wiphy, NLMSG_DEFAULT_SIZE, SLSI_NL80211_NAN_FOLLOWUP_EVENT,
2301 GFP_KERNEL);
2302#endif
2303
2304 if (!nl_skb) {
2305 SLSI_ERR(sdev, "NO MEM for nl_skb!!!\n");
2306 kfree(hal_evt);
781f598d 2307 goto exit;
533a23a1
TK
2308 }
2309
2310 res = nla_put_be16(nl_skb, NAN_EVT_ATTR_FOLLOWUP_PUBLISH_SUBSCRIBE_ID,
2311 cpu_to_le16(hal_evt->publish_subscribe_id));
2312 res |= nla_put_be16(nl_skb, NAN_EVT_ATTR_FOLLOWUP_REQUESTOR_INSTANCE_ID,
2313 cpu_to_le16(hal_evt->requestor_instance_id));
2314 res |= nla_put(nl_skb, NAN_EVT_ATTR_FOLLOWUP_ADDR, ETH_ALEN, hal_evt->addr);
2315 res |= nla_put_u8(nl_skb, NAN_EVT_ATTR_FOLLOWUP_DW_OR_FAW, hal_evt->dw_or_faw);
2316 res |= nla_put_u16(nl_skb, NAN_EVT_ATTR_FOLLOWUP_SERVICE_SPECIFIC_INFO_LEN, hal_evt->service_specific_info_len);
2317 if (hal_evt->service_specific_info_len)
2318 res |= nla_put(nl_skb, NAN_EVT_ATTR_FOLLOWUP_SERVICE_SPECIFIC_INFO, hal_evt->service_specific_info_len,
2319 hal_evt->service_specific_info);
2320 res |= nla_put_u16(nl_skb, NAN_EVT_ATTR_SDEA_LEN, hal_evt->sdea_service_specific_info_len);
2321 if (hal_evt->sdea_service_specific_info_len)
2322 res |= nla_put(nl_skb, NAN_EVT_ATTR_SDEA, hal_evt->sdea_service_specific_info_len,
2323 hal_evt->sdea_service_specific_info);
2324
2325 if (res) {
2326 SLSI_ERR(sdev, "Error in nla_put*:%x\n", res);
2327 kfree(hal_evt);
2328 /* Dont use slsi skb wrapper for this free */
2329 kfree_skb(nl_skb);
781f598d 2330 goto exit;
533a23a1
TK
2331 }
2332
2333 cfg80211_vendor_event(nl_skb, GFP_KERNEL);
2334 kfree(hal_evt);
781f598d
TK
2335exit:
2336 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
2337 slsi_kfree_skb(skb);
533a23a1
TK
2338}
2339
2340void slsi_nan_service_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb)
2341{
2342 u16 tag_id, tag_len;
2343 u8 *ptr;
2344 const u8 *tag_data_ptr;
2345 int sig_data_len;
2346 struct slsi_hal_nan_match_ind *hal_evt;
2347 struct sk_buff *nl_skb;
2348 int res;
781f598d 2349 struct netdev_vif *ndev_vif = netdev_priv(dev);
533a23a1
TK
2350
2351 SLSI_DBG3(sdev, SLSI_GSCAN, "\n");
781f598d 2352 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
533a23a1
TK
2353 sig_data_len = fapi_get_datalen(skb);
2354 if (sig_data_len <= 4) {
2355 SLSI_ERR(sdev, "Invalid data len(%d)\n", sig_data_len);
781f598d 2356 goto exit;
533a23a1
TK
2357 }
2358
2359 hal_evt = kmalloc(sizeof(*hal_evt), GFP_KERNEL);
2360 if (!hal_evt) {
2361 SLSI_ERR(sdev, "No memory for service_ind\n");
781f598d 2362 goto exit;
533a23a1
TK
2363 }
2364
2365 memset(hal_evt, 0, sizeof(*hal_evt));
781f598d 2366 hal_evt->publish_subscribe_id = fapi_get_u16(skb, u.mlme_nan_service_ind.session_id);
533a23a1
TK
2367 hal_evt->requestor_instance_id = fapi_get_u16(skb, u.mlme_nan_service_ind.match_id);
2368 hal_evt->ranging_event_type = fapi_get_u16(skb, u.mlme_nan_service_ind.rangingindicationtype);
2369 hal_evt->range_measurement_mm = 10 * fapi_get_u16(skb, u.mlme_nan_service_ind.ranging_measurement);
2370
2371 ptr = fapi_get_data(skb);
2372 tag_id = le16_to_cpu(*(u16 *)ptr);
2373 tag_len = le16_to_cpu(*(u16 *)(ptr + 2));
2374 tag_data_ptr = ptr + 4;
2375
2376 while (sig_data_len >= tag_len + 4) {
2377 switch (tag_id) {
2378 case SLSI_NAN_TLV_TAG_MATCH_IND:
2379 if (tag_len < 0x11) {
2380 SLSI_WARN(sdev, "Invalid taglen(%d) for SLSI_NAN_TLV_TAG_MATCH_IND\n", tag_len);
2381 break;
2382 }
2383 ether_addr_copy(hal_evt->addr, tag_data_ptr);
2384 tag_data_ptr += ETH_ALEN;
2385 hal_evt->match_occurred_flag = le16_to_cpu(*(u16 *)tag_data_ptr);
2386 tag_data_ptr += 2;
2387 hal_evt->out_of_resource_flag = le16_to_cpu(*(u16 *)tag_data_ptr);
2388 tag_data_ptr += 2;
2389 hal_evt->rssi_value = *tag_data_ptr;
2390 tag_data_ptr++;
2391 hal_evt->sec_info.cipher_type = *tag_data_ptr;
2392 break;
2393 case SLSI_NAN_TLV_TAG_SERVICE_SPECIFIC_INFO:
2394 hal_evt->service_specific_info_len = tag_len > SLSI_HAL_NAN_MAX_SERVICE_SPECIFIC_INFO_LEN ?
2395 SLSI_HAL_NAN_MAX_SERVICE_SPECIFIC_INFO_LEN : tag_len;
2396 memcpy(hal_evt->service_specific_info, tag_data_ptr, hal_evt->service_specific_info_len);
2397 break;
2398 case SLSI_NAN_TLV_TAG_EXT_SERVICE_SPECIFIC_INFO:
2399 if (tag_len > SLSI_HAL_NAN_MAX_SDEA_SERVICE_SPEC_INFO_LEN)
2400 hal_evt->sdea_service_specific_info_len = SLSI_HAL_NAN_MAX_SDEA_SERVICE_SPEC_INFO_LEN;
2401 else
2402 hal_evt->sdea_service_specific_info_len = tag_len;
2403 memcpy(hal_evt->sdea_service_specific_info, tag_data_ptr, hal_evt->sdea_service_specific_info_len);
2404 break;
2405 case SLSI_NAN_TLV_TAG_DATA_PATH_SECURITY:
2406 if (tag_len < 7) {
2407 SLSI_WARN(sdev, "Invalid taglen(%d) for SLSI_NAN_TLV_TAG_DATA_PATH_SECURITY\n", tag_len);
2408 break;
2409 }
2410 hal_evt->sec_info.key_info.key_type = *tag_data_ptr;
2411 tag_data_ptr++;
2412 hal_evt->sec_info.cipher_type = *tag_data_ptr;
2413 tag_data_ptr++;
2414 break;
781f598d
TK
2415 case SLSI_NAN_TLV_TAG_MATCH_FILTER:
2416 if (tag_len > SLSI_HAL_NAN_MAX_MATCH_FILTER_LEN)
2417 hal_evt->sdf_match_filter_len = SLSI_HAL_NAN_MAX_MATCH_FILTER_LEN;
2418 else
2419 hal_evt->sdf_match_filter_len = tag_len;
2420 memcpy(hal_evt->sdf_match_filter, tag_data_ptr, hal_evt->sdf_match_filter_len);
2421 break;
533a23a1
TK
2422 default:
2423 SLSI_WARN(sdev, "Skip processing TLV %d\n", tag_id);
2424 break;
2425 }
2426
2427 sig_data_len -= tag_len + 4;
2428 ptr += tag_len + 4;
2429 if (sig_data_len > 4) {
2430 tag_id = le16_to_cpu(*(u16 *)ptr);
2431 tag_len = le16_to_cpu(*(u16 *)(ptr + 2));
781f598d 2432 tag_data_ptr = ptr + 4;
533a23a1
TK
2433 } else {
2434 tag_id = 0;
2435 tag_len = 0;
2436 }
2437 }
2438
2439#ifdef CONFIG_SCSC_WLAN_DEBUG
781f598d
TK
2440 SLSI_INFO(sdev, "Event: %s(%d)\n",
2441 slsi_print_event_name(SLSI_NL80211_NAN_MATCH_EVENT), SLSI_NL80211_NAN_MATCH_EVENT);
533a23a1
TK
2442#endif
2443#if (KERNEL_VERSION(4, 1, 0) <= LINUX_VERSION_CODE)
2444 nl_skb = cfg80211_vendor_event_alloc(sdev->wiphy, NULL, NLMSG_DEFAULT_SIZE, SLSI_NL80211_NAN_MATCH_EVENT,
2445 GFP_KERNEL);
2446#else
2447 nl_skb = cfg80211_vendor_event_alloc(sdev->wiphy, NLMSG_DEFAULT_SIZE, SLSI_NL80211_NAN_MATCH_EVENT, GFP_KERNEL);
2448#endif
2449 if (!nl_skb) {
2450 SLSI_ERR(sdev, "NO MEM for nl_skb!!!\n");
2451 kfree(hal_evt);
781f598d 2452 goto exit;
533a23a1
TK
2453 }
2454 res = nla_put_u16(nl_skb, NAN_EVT_ATTR_MATCH_PUBLISH_SUBSCRIBE_ID, hal_evt->publish_subscribe_id);
2455 res |= nla_put_u32(nl_skb, NAN_EVT_ATTR_MATCH_REQUESTOR_INSTANCE_ID, hal_evt->requestor_instance_id);
2456 res |= nla_put(nl_skb, NAN_EVT_ATTR_MATCH_ADDR, ETH_ALEN, hal_evt->addr);
2457 res |= nla_put_u16(nl_skb, NAN_EVT_ATTR_MATCH_SERVICE_SPECIFIC_INFO_LEN, hal_evt->service_specific_info_len);
2458 if (hal_evt->service_specific_info_len)
2459 res |= nla_put(nl_skb, NAN_EVT_ATTR_MATCH_SERVICE_SPECIFIC_INFO, hal_evt->service_specific_info_len,
2460 hal_evt->service_specific_info);
2461 res |= nla_put_u16(nl_skb, NAN_EVT_ATTR_MATCH_SDF_MATCH_FILTER_LEN, hal_evt->sdf_match_filter_len);
2462 if (hal_evt->sdf_match_filter_len)
2463 res |= nla_put(nl_skb, NAN_EVT_ATTR_MATCH_SDF_MATCH_FILTER, hal_evt->sdf_match_filter_len,
2464 hal_evt->sdf_match_filter);
2465 res |= nla_put_u16(nl_skb, NAN_EVT_ATTR_SDEA_LEN, hal_evt->sdea_service_specific_info_len);
2466 if (hal_evt->sdea_service_specific_info_len)
2467 res |= nla_put(nl_skb, NAN_EVT_ATTR_SDEA, hal_evt->sdea_service_specific_info_len,
2468 hal_evt->sdea_service_specific_info);
2469
2470 res |= nla_put_u8(nl_skb, NAN_EVT_ATTR_MATCH_MATCH_OCCURRED_FLAG, hal_evt->match_occurred_flag);
2471 res |= nla_put_u8(nl_skb, NAN_EVT_ATTR_MATCH_OUT_OF_RESOURCE_FLAG, hal_evt->out_of_resource_flag);
2472 res |= nla_put_u8(nl_skb, NAN_EVT_ATTR_MATCH_RSSI_VALUE, hal_evt->rssi_value);
2473 res |= nla_put_u32(nl_skb, NAN_EVT_ATTR_RANGE_MEASUREMENT_MM, hal_evt->range_measurement_mm);
2474 res |= nla_put_u32(nl_skb, NAN_EVT_ATTR_RANGEING_EVENT_TYPE, hal_evt->ranging_event_type);
2475 res |= nla_put_u32(nl_skb, NAN_EVT_ATTR_SECURITY_CIPHER_TYPE, hal_evt->sec_info.cipher_type);
2476
2477 if (res) {
2478 SLSI_ERR(sdev, "Error in nla_put*:%x\n", res);
2479 /* Dont use slsi skb wrapper for this free */
2480 kfree_skb(nl_skb);
2481 kfree(hal_evt);
781f598d 2482 goto exit;
533a23a1
TK
2483 }
2484
2485 cfg80211_vendor_event(nl_skb, GFP_KERNEL);
2486 kfree(hal_evt);
781f598d
TK
2487exit:
2488 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
2489 slsi_kfree_skb(skb);
2490}
2491
2492static void slsi_nan_get_resp_status_code(u16 fapi_result_code, u16 *resp_code, u16 *status_code)
2493{
2494 switch (fapi_result_code) {
2495 case FAPI_RESULTCODE_SUCCESS:
2496 *resp_code = NAN_DP_REQUEST_ACCEPT;
2497 *status_code = SLSI_HAL_NAN_STATUS_SUCCESS;
2498 break;
2499 case FAPI_RESULTCODE_NDP_REJECTED:
2500 *resp_code = NAN_DP_REQUEST_REJECT;
2501 *status_code = SLSI_HAL_NAN_STATUS_SUCCESS;
2502 break;
2503 case FAPI_RESULTCODE_NAN_NO_OTA_ACK:
2504 *resp_code = NAN_DP_REQUEST_REJECT;
2505 *status_code = SLSI_HAL_NAN_STATUS_NO_OTA_ACK;
2506 break;
2507 case FAPI_RESULTCODE_NAN_INVALID_AVAILABILITY:
2508 case FAPI_RESULTCODE_NAN_IMMUTABLE_UNACCEPTABLE:
2509 case FAPI_RESULTCODE_NAN_REJECTED_SECURITY_POLICY:
2510 case FAPI_RESULTCODE_NDL_UNACCEPTABLE:
2511 *resp_code = NAN_DP_REQUEST_REJECT;
2512 *status_code = SLSI_HAL_NAN_STATUS_PROTOCOL_FAILURE;
2513 break;
2514 case FAPI_RESULTCODE_TRANSMISSION_FAILURE:
2515 default:
2516 *resp_code = NAN_DP_REQUEST_REJECT;
2517 *status_code = SLSI_HAL_NAN_STATUS_INTERNAL_FAILURE;
2518 }
2519}
2520
2521u32 slsi_nan_get_ndp_from_ndl_local_ndi(struct net_device *dev, u16 ndl_vif_id, u8 *local_ndi)
2522{
2523 int i, j;
2524 struct netdev_vif *ndev_vif = netdev_priv(dev);
2525
2526 for (i = 0; i < SLSI_NAN_MAX_NDP_INSTANCES; i++) {
2527 if (ndev_vif->nan.ndp_id2ndl_vif[i] == ndl_vif_id) {
2528 for (j = 0; j < SLSI_NAN_MAX_NDP_INSTANCES; j++)
2529 if (ether_addr_equal(ndev_vif->nan.ndp_ndi[j], local_ndi))
2530 return i + 1;
2531 }
2532 }
2533 return SLSI_NAN_MAX_NDP_INSTANCES + 1;
2534}
2535
2536static int slsi_nan_put_ndp_req_ind_params(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb,
2537 struct sk_buff *nl_skb, u8 **peer_ndi, u16 *resp_code, u16 *ndp_id)
2538{
2539 int res;
2540 u16 ndl_vif_id, status_code;
2541 u8 *local_ndi;
2542
2543 ndl_vif_id = fapi_get_u16(skb, u.mlme_ndp_request_ind.ndl_vif_index);
2544 *peer_ndi = fapi_get_buff(skb, u.mlme_ndp_request_ind.peer_ndp_interface_address);
2545 local_ndi = fapi_get_buff(skb, u.mlme_ndp_request_ind.local_ndp_interface_address);
2546 slsi_nan_get_resp_status_code(fapi_get_u16(skb, u.mlme_ndp_request_ind.result_code), resp_code, &status_code);
2547 *ndp_id = slsi_nan_get_ndp_from_ndl_local_ndi(dev, ndl_vif_id, local_ndi);
2548
2549 res = nla_put_u32(nl_skb, NAN_EVT_ATTR_NDP_INSTANCE_ID, *ndp_id);
2550 res |= nla_put(nl_skb, NAN_EVT_ATTR_MATCH_ADDR, ETH_ALEN, *peer_ndi);
2551
2552 res |= nla_put_u32(nl_skb, NAN_EVT_ATTR_NDP_RSP_CODE, *resp_code);
2553 res |= nla_put_u32(nl_skb, NAN_EVT_ATTR_STATUS_CODE, status_code);
2554
2555 return res;
2556}
2557
2558static int slsi_nan_put_ndp_resp_ind_params(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb,
2559 struct sk_buff *nl_skb, u8 **peer_ndi, u16 *resp_code, u16 *ndp_id)
2560{
2561 int res;
2562 u16 ndl_vif_id, status_code;
2563 u8 *local_ndi;
2564
2565 ndl_vif_id = fapi_get_u16(skb, u.mlme_ndp_response_ind.ndl_vif_index);
2566 *peer_ndi = fapi_get_buff(skb, u.mlme_ndp_response_ind.peer_ndp_interface_address);
2567 local_ndi = fapi_get_buff(skb, u.mlme_ndp_response_ind.local_ndp_interface_address);
2568 slsi_nan_get_resp_status_code(fapi_get_u16(skb, u.mlme_ndp_response_ind.result_code), resp_code, &status_code);
2569 *ndp_id = slsi_nan_get_ndp_from_ndl_local_ndi(dev, ndl_vif_id, local_ndi);
2570
2571 res = nla_put_u32(nl_skb, NAN_EVT_ATTR_NDP_INSTANCE_ID, *ndp_id);
2572 res |= nla_put(nl_skb, NAN_EVT_ATTR_MATCH_ADDR, ETH_ALEN, *peer_ndi);
2573
2574 res |= nla_put_u32(nl_skb, NAN_EVT_ATTR_NDP_RSP_CODE, *resp_code);
2575 res |= nla_put_u32(nl_skb, NAN_EVT_ATTR_STATUS_CODE, status_code);
2576
2577 return res;
2578}
2579
2580void slsi_nan_ndp_setup_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb, bool is_req_ind)
2581{
2582 u16 tag_id, tag_len;
2583 u8 *ptr;
2584 const u8 *tag_data_ptr;
2585 int sig_data_len;
2586 struct sk_buff *nl_skb;
2587 int res;
2588 u8 *peer_ndi;
2589 u16 ndp_setup_response, ndp_id;
2590 struct netdev_vif *ndev_vif = netdev_priv(dev);
2591
2592 SLSI_DBG3(sdev, SLSI_GSCAN, "\n");
2593 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
2594 sig_data_len = fapi_get_datalen(skb);
2595
2596#if (KERNEL_VERSION(4, 1, 0) <= LINUX_VERSION_CODE)
2597 nl_skb = cfg80211_vendor_event_alloc(sdev->wiphy, NULL, NLMSG_DEFAULT_SIZE, SLSI_NAN_EVENT_NDP_CFM,
2598 GFP_KERNEL);
2599#else
2600 nl_skb = cfg80211_vendor_event_alloc(sdev->wiphy, NLMSG_DEFAULT_SIZE, SLSI_NAN_EVENT_NDP_CFM, GFP_KERNEL);
2601#endif
2602 if (!nl_skb) {
2603 SLSI_ERR(sdev, "NO MEM for nl_skb!!!\n");
2604 goto exit;
2605 }
2606
2607 if (is_req_ind)
2608 res = slsi_nan_put_ndp_req_ind_params(sdev, dev, skb, nl_skb, &peer_ndi, &ndp_setup_response, &ndp_id);
2609 else
2610 res = slsi_nan_put_ndp_resp_ind_params(sdev, dev, skb, nl_skb, &peer_ndi, &ndp_setup_response, &ndp_id);
2611
2612 if (ndp_setup_response != NAN_DP_REQUEST_ACCEPT)
2613 slsi_nan_ndp_del_entry(sdev, dev, ndp_id);
2614
2615 ptr = fapi_get_data(skb);
2616 if (ptr) {
2617 tag_id = le16_to_cpu(*(u16 *)ptr);
2618 tag_len = le16_to_cpu(*(u16 *)(ptr + 2));
2619 tag_data_ptr = ptr + 4;
2620
2621 while (sig_data_len >= tag_len + 4) {
2622 if (tag_id == SLSI_NAN_TLV_TAG_APP_INFO) {
2623 res |= nla_put_u16(nl_skb, NAN_EVT_ATTR_APP_INFO_LEN, tag_len);
2624 res |= nla_put(nl_skb, NAN_EVT_ATTR_APP_INFO, tag_len, tag_data_ptr);
2625 break;
2626 }
2627 sig_data_len -= tag_len + 4;
2628 ptr += tag_len + 4;
2629 if (sig_data_len > 4) {
2630 tag_id = le16_to_cpu(*(u16 *)ptr);
2631 tag_len = le16_to_cpu(*(u16 *)(ptr + 2));
2632 tag_data_ptr = ptr + 4;
2633 } else {
2634 tag_id = 0;
2635 tag_len = 0;
2636 }
2637 }
2638 }
2639
2640 if (res) {
2641 SLSI_ERR(sdev, "Error in nla_put*:%x\n", res);
2642 /* Dont use slsi skb wrapper for this free */
2643 kfree_skb(nl_skb);
2644 goto exit;
2645 }
2646
2647#ifdef CONFIG_SCSC_WLAN_DEBUG
2648 SLSI_INFO(sdev, "Event: %s(%d)\n",
2649 slsi_print_event_name(SLSI_NAN_EVENT_NDP_CFM), SLSI_NAN_EVENT_NDP_CFM);
2650#endif
2651
2652 cfg80211_vendor_event(nl_skb, GFP_KERNEL);
2653 if (ndp_setup_response == NAN_DP_REQUEST_ACCEPT) {
2654 struct netdev_vif *ndev_data_vif;
2655 struct net_device *data_dev = slsi_get_netdev_by_mac_addr_locked(sdev, ndev_vif->nan.ndp_ndi[ndp_id],
2656 SLSI_NAN_DATA_IFINDEX_START);
2657 struct slsi_peer *peer = NULL;
2658
2659 if (ndp_id == 0 || ndp_id > SLSI_NAN_MAX_NDP_INSTANCES + 1) {
2660 SLSI_ERR(sdev, "Invalid ndp_id:%d\n", ndp_id);
2661 goto exit;
2662 }
2663
2664 data_dev = slsi_get_netdev_by_mac_addr(sdev, ndev_vif->nan.ndp_ndi[ndp_id - 1],
2665 SLSI_NAN_DATA_IFINDEX_START);
2666
2667 if (!data_dev) {
2668 SLSI_ERR(sdev, "no data_dev for ndp:%d ndi[%pM]\n", ndp_id, ndev_vif->nan.ndp_ndi[ndp_id - 1]);
2669 goto exit;
2670 }
2671 ndev_data_vif = netdev_priv(data_dev);
2672 SLSI_MUTEX_LOCK(ndev_data_vif->vif_mutex);
2673 peer = slsi_peer_add(sdev, data_dev, peer_ndi, ndp_id);
2674 if (peer) {
2675 peer->connected_state = SLSI_STA_CONN_STATE_CONNECTED;
2676 slsi_ps_port_control(sdev, data_dev, peer, SLSI_STA_CONN_STATE_CONNECTED);
2677 peer->ndl_vif = ndev_vif->nan.ndp_id2ndl_vif[ndp_id - 1];
2678 peer->qos_enabled = true;
2679 } else {
2680 SLSI_ERR(sdev, "no peer for ndp:%d ndi[%d]\n", ndp_id, ndev_vif->nan.ndp_ndi[ndp_id - 1]);
2681 }
2682 SLSI_MUTEX_UNLOCK(ndev_data_vif->vif_mutex);
2683 }
2684exit:
2685 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
2686 slsi_kfree_skb(skb);
2687}
2688
2689void slsi_nan_ndp_requested_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb)
2690{
2691 u16 tag_id, tag_len = 0, ndl_vif_id, local_ndp_id;
2692 u8 *ptr, *peer_nmi;
2693 const u8 *tag_data_ptr;
2694 int sig_data_len, res;
2695 struct sk_buff *nl_skb;
2696 u32 ndp_id;
2697 struct netdev_vif *ndev_vif = netdev_priv(dev);
2698
2699 SLSI_DBG3(sdev, SLSI_GSCAN, "\n");
2700 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
2701 sig_data_len = fapi_get_datalen(skb);
2702
2703#if (KERNEL_VERSION(4, 1, 0) <= LINUX_VERSION_CODE)
2704 nl_skb = cfg80211_vendor_event_alloc(sdev->wiphy, NULL, NLMSG_DEFAULT_SIZE, SLSI_NAN_EVENT_NDP_REQ,
2705 GFP_KERNEL);
2706#else
2707 nl_skb = cfg80211_vendor_event_alloc(sdev->wiphy, NLMSG_DEFAULT_SIZE, SLSI_NAN_EVENT_NDP_REQ, GFP_KERNEL);
2708#endif
2709 if (!nl_skb) {
2710 SLSI_ERR(sdev, "NO MEM for nl_skb!!!\n");
2711 goto exit;
2712 }
2713
2714 local_ndp_id = fapi_get_u16(skb, u.mlme_ndp_requested_ind.request_id);
2715 ndp_id = slsi_nan_get_new_ndp_id(ndev_vif);
2716 peer_nmi = fapi_get_buff(skb, u.mlme_ndp_requested_ind.peer_nan_management_interface_address);
2717 res = nla_put_u16(nl_skb, NAN_EVT_ATTR_SERVICE_INSTANCE_ID,
2718 fapi_get_u16(skb, u.mlme_ndp_requested_ind.session_id));
2719 res |= nla_put(nl_skb, NAN_EVT_ATTR_MATCH_ADDR, ETH_ALEN, peer_nmi);
2720 res |= nla_put_u32(nl_skb, NAN_EVT_ATTR_NDP_INSTANCE_ID, ndp_id);
2721 res |= nla_put_u32(nl_skb, NAN_EVT_ATTR_SDEA_PARAM_SECURITY_CONFIG,
2722 fapi_get_u16(skb, u.mlme_ndp_requested_ind.security_required));
2723
2724 ptr = fapi_get_data(skb);
2725 if (ptr) {
2726 tag_id = le16_to_cpu(*(u16 *)ptr);
2727 tag_len = le16_to_cpu(*(u16 *)(ptr + 2));
2728 tag_data_ptr = ptr + 4;
2729
2730 while (sig_data_len >= tag_len + 4) {
2731 if (tag_id == SLSI_NAN_TLV_TAG_APP_INFO) {
2732 res |= nla_put_u16(nl_skb, NAN_EVT_ATTR_APP_INFO_LEN, tag_len);
2733 res |= nla_put(nl_skb, NAN_EVT_ATTR_APP_INFO, tag_len, tag_data_ptr);
2734 break;
2735 }
2736 sig_data_len -= tag_len + 4;
2737 ptr += tag_len + 4;
2738 if (sig_data_len > 4) {
2739 tag_id = le16_to_cpu(*(u16 *)ptr);
2740 tag_len = le16_to_cpu(*(u16 *)(ptr + 2));
2741 tag_data_ptr = ptr + 4;
2742 } else {
2743 tag_id = 0;
2744 tag_len = 0;
2745 }
2746 }
2747 }
2748
2749 if (res) {
2750 SLSI_ERR(sdev, "Error in nla_put*:%x\n", res);
2751 /* Dont use slsi skb wrapper for this free */
2752 kfree_skb(nl_skb);
2753 goto exit;
2754 }
2755
2756#ifdef CONFIG_SCSC_WLAN_DEBUG
2757 SLSI_INFO(sdev, "Event: %s(%d)\n",
2758 slsi_print_event_name(SLSI_NAN_EVENT_NDP_REQ), SLSI_NAN_EVENT_NDP_REQ);
2759#endif
2760 ndl_vif_id = slsi_nan_ndp_get_ndl_vif_id(peer_nmi, ndev_vif->nan.ndl_list);
2761 if (slsi_nan_ndp_new_entry(sdev, dev, ndp_id, ndl_vif_id, NULL, peer_nmi) == 0) {
2762 cfg80211_vendor_event(nl_skb, GFP_KERNEL);
2763 ndev_vif->nan.ndp_local_ndp_id[ndp_id - 1] = local_ndp_id;
2764 } else {
2765 struct slsi_hal_nan_data_path_indication_response response_req;
2766
2767 kfree_skb(nl_skb);
2768 SLSI_ERR(sdev, "invalid ndl_vifid:%d ndp_id:%d\n", ndl_vif_id, ndp_id);
2769 memset(&response_req, 0, sizeof(response_req));
2770 response_req.rsp_code = NAN_DP_REQUEST_REJECT;
2771 slsi_mlme_ndp_response(sdev, dev, &response_req, local_ndp_id);
2772 }
2773
2774exit:
2775 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
2776 slsi_kfree_skb(skb);
2777}
2778
2779void slsi_nan_del_peer(struct slsi_dev *sdev, struct net_device *dev, u8 *local_ndi, u16 ndp_id)
2780{
2781 struct netdev_vif *ndev_vif = netdev_priv(dev);
2782 struct net_device *data_dev;
2783 struct netdev_vif *ndev_data_vif;
2784 struct slsi_peer *peer = NULL;
2785
2786 WARN_ON(!SLSI_MUTEX_IS_LOCKED(ndev_vif->vif_mutex));
2787
2788 if (!local_ndi)
2789 return;
2790
2791 data_dev = slsi_get_netdev_by_mac_addr_locked(sdev, local_ndi, SLSI_NAN_DATA_IFINDEX_START);
2792 if (!data_dev)
2793 return;
2794
2795 if (ndp_id == 0 || ndp_id > SLSI_NAN_MAX_NDP_INSTANCES)
2796 return;
2797
2798 ndev_data_vif = netdev_priv(data_dev);
2799 SLSI_MUTEX_LOCK(ndev_data_vif->vif_mutex);
2800 peer = ndev_vif->peer_sta_record[ndp_id - 1];
2801 if (peer) {
2802 slsi_ps_port_control(sdev, dev, peer, SLSI_STA_CONN_STATE_DISCONNECTED);
2803 slsi_spinlock_lock(&ndev_data_vif->peer_lock);
2804 slsi_peer_remove(sdev, dev, peer);
2805 slsi_spinlock_unlock(&ndev_data_vif->peer_lock);
2806 } else {
2807 SLSI_ERR(sdev, "no peer for ndp:%d ndi[%pM]\n", ndp_id, ndev_vif->nan.ndp_ndi[ndp_id - 1]);
2808 }
2809 SLSI_MUTEX_UNLOCK(ndev_data_vif->vif_mutex);
2810}
2811
2812void slsi_nan_ndp_termination_handler(struct slsi_dev *sdev, struct net_device *dev, u16 ndp_id, u16 ndl_vif, u8 *ndi)
2813{
2814 struct sk_buff *nl_skb;
2815
2816 slsi_nan_ndp_del_entry(sdev, dev, ndp_id);
2817 slsi_nan_del_peer(sdev, dev, ndi, ndp_id);
2818
2819#if (KERNEL_VERSION(4, 1, 0) <= LINUX_VERSION_CODE)
2820 nl_skb = cfg80211_vendor_event_alloc(sdev->wiphy, NULL, NLMSG_DEFAULT_SIZE, SLSI_NAN_EVENT_NDP_END,
2821 GFP_KERNEL);
2822#else
2823 nl_skb = cfg80211_vendor_event_alloc(sdev->wiphy, NLMSG_DEFAULT_SIZE, SLSI_NAN_EVENT_NDP_END, GFP_KERNEL);
2824#endif
2825 if (!nl_skb) {
2826 SLSI_ERR(sdev, "NO MEM for nl_skb!!!\n");
2827 return;
2828 }
2829
2830 if (nla_put_u32(nl_skb, NAN_EVT_ATTR_NDP_INSTANCE_ID, ndp_id)) {
2831 SLSI_ERR(sdev, "Error in nla_put_u32\n");
2832 /* Dont use slsi skb wrapper for this free */
2833 kfree_skb(nl_skb);
2834 return;
2835 }
2836#ifdef CONFIG_SCSC_WLAN_DEBUG
2837 SLSI_INFO(sdev, "Event: %s(%d)\n",
2838 slsi_print_event_name(SLSI_NAN_EVENT_NDP_END), SLSI_NAN_EVENT_NDP_END);
2839#endif
2840 cfg80211_vendor_event(nl_skb, GFP_KERNEL);
2841}
2842
2843void slsi_nan_ndp_termination_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb,
2844 bool is_terminated_ind)
2845{
2846 u16 ndl_vif_id, ndp_id;
2847 u8 *local_ndi;
2848 struct netdev_vif *ndev_vif = netdev_priv(dev);
2849
2850 SLSI_DBG3(sdev, SLSI_GSCAN, "\n");
2851 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
2852
2853 if (is_terminated_ind) {
2854 ndl_vif_id = fapi_get_u16(skb, u.mlme_ndp_terminated_ind.ndl_vif_index);
2855 local_ndi = fapi_get_buff(skb, u.mlme_ndp_terminated_ind.local_ndp_interface_address);
2856 } else {
2857 ndl_vif_id = fapi_get_u16(skb, u.mlme_ndp_terminate_ind.ndl_vif_index);
2858 local_ndi = fapi_get_buff(skb, u.mlme_ndp_terminate_ind.local_ndp_interface_address);
2859 }
2860
2861 ndp_id = slsi_nan_get_ndp_from_ndl_local_ndi(dev, ndl_vif_id, local_ndi);
2862 if (ndp_id <= SLSI_NAN_MAX_NDP_INSTANCES)
2863 slsi_nan_ndp_termination_handler(sdev, dev, ndp_id, ndl_vif_id, local_ndi);
2864
2865 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
2866 slsi_kfree_skb(skb);
533a23a1 2867}