[RAMEN9610-20413][9610] wlbt: SCSC Driver version 10.6.1.0
[GitHub/MotorolaMobilityLLC/kernel-slsi.git] / drivers / net / wireless / scsc / nl80211_vendor_nan.c
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
12 struct net_device *slsi_nan_get_netdev(struct slsi_dev *sdev)
13 {
14 #if CONFIG_SCSC_WLAN_MAX_INTERFACES >= 4
15 return slsi_get_netdev(sdev, SLSI_NET_INDEX_NAN);
16 #else
17 return NULL;
18 #endif
19 }
20
21 static int slsi_nan_get_new_id(u32 id_map, int max_ids)
22 {
23 int i;
24
25 for (i = 1; i <= max_ids; i++) {
26 if (!(id_map & BIT(i)))
27 return i;
28 }
29 return 0;
30 }
31
32 static int slsi_nan_get_new_publish_id(struct netdev_vif *ndev_vif)
33 {
34 return slsi_nan_get_new_id(ndev_vif->nan.publish_id_map, SLSI_NAN_MAX_PUBLISH_ID);
35 }
36
37 static int slsi_nan_get_new_subscribe_id(struct netdev_vif *ndev_vif)
38 {
39 return slsi_nan_get_new_id(ndev_vif->nan.subscribe_id_map, SLSI_NAN_MAX_SUBSCRIBE_ID);
40 }
41
42 static bool slsi_nan_is_publish_id_active(struct netdev_vif *ndev_vif, u32 id)
43 {
44 return ndev_vif->nan.publish_id_map & BIT(id);
45 }
46
47 static bool slsi_nan_is_subscribe_id_active(struct netdev_vif *ndev_vif, u32 id)
48 {
49 return ndev_vif->nan.subscribe_id_map & BIT(id);
50 }
51
52 void slsi_nan_get_mac(struct slsi_dev *sdev, char *nan_mac_addr)
53 {
54 memset(nan_mac_addr, 0, ETH_ALEN);
55 #if CONFIG_SCSC_WLAN_MAX_INTERFACES >= 4
56 if (slsi_dev_nan_supported(sdev))
57 ether_addr_copy(nan_mac_addr, sdev->netdev_addresses[SLSI_NET_INDEX_NAN]);
58 #endif
59 }
60
61 static void slsi_vendor_nan_command_reply(struct wiphy *wiphy, u32 status, u32 error, u32 response_type,
62 u16 publish_subscribe_id, struct slsi_hal_nan_capabilities *capabilities)
63 {
64 int reply_len;
65 struct sk_buff *reply;
66
67 reply_len = SLSI_NL_VENDOR_REPLY_OVERHEAD + SLSI_NL_ATTRIBUTE_U32_LEN *
68 (3 + sizeof(struct slsi_hal_nan_capabilities));
69 reply = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, reply_len);
70 if (!reply) {
71 SLSI_WARN_NODEV("SKB alloc failed for vendor_cmd reply\n");
72 return;
73 }
74
75 nla_put_u32(reply, NAN_REPLY_ATTR_STATUS_TYPE, status);
76 nla_put_u32(reply, NAN_REPLY_ATTR_VALUE, error);
77 nla_put_u32(reply, NAN_REPLY_ATTR_RESPONSE_TYPE, response_type);
78
79 if (capabilities) {
80 nla_put_u32(reply, NAN_REPLY_ATTR_CAP_MAX_CONCURRENT_CLUSTER,
81 capabilities->max_concurrent_nan_clusters);
82 nla_put_u32(reply, NAN_REPLY_ATTR_CAP_MAX_PUBLISHES, capabilities->max_publishes);
83 nla_put_u32(reply, NAN_REPLY_ATTR_CAP_MAX_SUBSCRIBES, capabilities->max_subscribes);
84 nla_put_u32(reply, NAN_REPLY_ATTR_CAP_MAX_SERVICE_NAME_LEN, capabilities->max_service_name_len);
85 nla_put_u32(reply, NAN_REPLY_ATTR_CAP_MAX_MATCH_FILTER_LEN, capabilities->max_match_filter_len);
86 nla_put_u32(reply, NAN_REPLY_ATTR_CAP_MAX_TOTAL_MATCH_FILTER_LEN,
87 capabilities->max_total_match_filter_len);
88 nla_put_u32(reply, NAN_REPLY_ATTR_CAP_MAX_SERVICE_SPECIFIC_INFO_LEN,
89 capabilities->max_service_specific_info_len);
90 nla_put_u32(reply, NAN_REPLY_ATTR_CAP_MAX_VSA_DATA_LEN, capabilities->max_vsa_data_len);
91 nla_put_u32(reply, NAN_REPLY_ATTR_CAP_MAX_MESH_DATA_LEN, capabilities->max_mesh_data_len);
92 nla_put_u32(reply, NAN_REPLY_ATTR_CAP_MAX_NDI_INTERFACES, capabilities->max_ndi_interfaces);
93 nla_put_u32(reply, NAN_REPLY_ATTR_CAP_MAX_NDP_SESSIONS, capabilities->max_ndp_sessions);
94 nla_put_u32(reply, NAN_REPLY_ATTR_CAP_MAX_APP_INFO_LEN, capabilities->max_app_info_len);
95 } else if (publish_subscribe_id) {
96 nla_put_u16(reply, NAN_REPLY_ATTR_PUBLISH_SUBSCRIBE_TYPE, publish_subscribe_id);
97 }
98
99 if (cfg80211_vendor_cmd_reply(reply))
100 SLSI_ERR_NODEV("FAILED to reply nan coammnd. response_type:%d\n", response_type);
101 }
102
103 static int slsi_nan_get_sdea_params_nl(struct slsi_dev *sdev, struct slsi_nan_sdea_ctrl_params *sdea_params,
104 const struct nlattr *iter, int nl_attr_id)
105 {
106 switch (nl_attr_id) {
107 case NAN_REQ_ATTR_SDEA_PARAM_NDP_TYPE:
108 sdea_params->ndp_type = nla_get_u8(iter);
109 sdea_params->config_nan_data_path = 1;
110 break;
111 case NAN_REQ_ATTR_SDEA_PARAM_SECURITY_CFG:
112 sdea_params->security_cfg = nla_get_u8(iter);
113 sdea_params->config_nan_data_path = 1;
114 break;
115 case NAN_REQ_ATTR_SDEA_PARAM_RANGING_STATE:
116 sdea_params->ranging_state = nla_get_u8(iter);
117 sdea_params->config_nan_data_path = 1;
118 break;
119 case NAN_REQ_ATTR_SDEA_PARAM_RANGE_REPORT:
120 sdea_params->range_report = nla_get_u8(iter);
121 sdea_params->config_nan_data_path = 1;
122 break;
123 case NAN_REQ_ATTR_SDEA_PARAM_QOS_CFG:
124 sdea_params->qos_cfg = nla_get_u8(iter);
125 sdea_params->config_nan_data_path = 1;
126 break;
127 default:
128 return -EINVAL;
129 }
130 return 0;
131 }
132
133 static int slsi_nan_get_ranging_cfg_nl(struct slsi_dev *sdev, struct slsi_nan_ranging_cfg *ranging_cfg,
134 const struct nlattr *iter, int nl_attr_id)
135 {
136 switch (nl_attr_id) {
137 case NAN_REQ_ATTR_RANGING_CFG_INTERVAL:
138 ranging_cfg->ranging_interval_msec = nla_get_u32(iter);
139 break;
140 case NAN_REQ_ATTR_RANGING_CFG_INDICATION:
141 ranging_cfg->config_ranging_indications = nla_get_u32(iter);
142 break;
143 case NAN_REQ_ATTR_RANGING_CFG_INGRESS_MM:
144 ranging_cfg->distance_ingress_mm = nla_get_u32(iter);
145 break;
146 case NAN_REQ_ATTR_RANGING_CFG_EGRESS_MM:
147 ranging_cfg->distance_egress_mm = nla_get_u32(iter);
148 break;
149 default:
150 return -EINVAL;
151 }
152 return 0;
153 }
154
155 static int slsi_nan_get_security_info_nl(struct slsi_dev *sdev, struct slsi_nan_security_info *sec_info,
156 const struct nlattr *iter, int nl_attr_id)
157 {
158 u32 len = 0;
159
160 switch (nl_attr_id) {
161 case NAN_REQ_ATTR_CIPHER_TYPE:
162 sec_info->cipher_type = nla_get_u32(iter);
163 break;
164 case NAN_REQ_ATTR_SECURITY_KEY_TYPE:
165 sec_info->key_info.key_type = nla_get_u8(iter);
166 break;
167 case NAN_REQ_ATTR_SECURITY_PMK_LEN:
168 len = nla_get_u32(iter);
169 sec_info->key_info.body.pmk_info.pmk_len = len;
170 break;
171 case NAN_REQ_ATTR_SECURITY_PMK:
172 memcpy(sec_info->key_info.body.pmk_info.pmk, nla_data(iter), len);
173 break;
174 case NAN_REQ_ATTR_SECURITY_PASSPHRASE_LEN:
175 len = nla_get_u32(iter);
176 sec_info->key_info.body.passphrase_info.passphrase_len = len;
177 break;
178 case NAN_REQ_ATTR_SECURITY_PASSPHRASE:
179 memcpy(sec_info->key_info.body.passphrase_info.passphrase, nla_data(iter), len);
180 break;
181 case NAN_REQ_ATTR_SCID_LEN:
182 sec_info->scid_len = nla_get_u32(iter);
183 break;
184 case NAN_REQ_ATTR_SCID:
185 memcpy(sec_info->scid, nla_data(iter), sec_info->scid_len);
186 break;
187 default:
188 return -EINVAL;
189 }
190 return 0;
191 }
192
193 static int slsi_nan_get_range_resp_cfg_nl(struct slsi_dev *sdev, struct slsi_nan_range_response_cfg *cfg,
194 const struct nlattr *iter, int nl_attr_id)
195 {
196 switch (nl_attr_id) {
197 case NAN_REQ_ATTR_RANGE_RESPONSE_CFG_PUBLISH_ID:
198 cfg->publish_id = nla_get_u16(iter);
199 break;
200
201 case NAN_REQ_ATTR_RANGE_RESPONSE_CFG_REQUESTOR_ID:
202 cfg->requestor_instance_id = nla_get_u32(iter);
203 break;
204
205 case NAN_REQ_ATTR_RANGE_RESPONSE_CFG_PEER_ADDR:
206 memcpy(cfg->peer_addr, nla_data(iter), ETH_ALEN);
207 break;
208
209 case NAN_REQ_ATTR_RANGE_RESPONSE_CFG_RANGING_RESPONSE:
210 cfg->ranging_response = nla_get_u8(iter);
211 break;
212
213 default:
214 return -EINVAL;
215 }
216 return 0;
217 }
218
219 static int slsi_nan_enable_get_nl_params(struct slsi_dev *sdev, struct slsi_hal_nan_enable_req *hal_req,
220 const void *data, int len)
221 {
222 int type, tmp;
223 const struct nlattr *iter;
224
225 memset(hal_req, 0, sizeof(*hal_req));
226 nla_for_each_attr(iter, data, len, tmp) {
227 type = nla_type(iter);
228 switch (type) {
229 case NAN_REQ_ATTR_MASTER_PREF:
230 hal_req->master_pref = nla_get_u8(iter);
231 break;
232
233 case NAN_REQ_ATTR_CLUSTER_LOW:
234 hal_req->cluster_low = nla_get_u16(iter);
235 break;
236
237 case NAN_REQ_ATTR_CLUSTER_HIGH:
238 hal_req->cluster_high = nla_get_u16(iter);
239 break;
240
241 case NAN_REQ_ATTR_SUPPORT_5G_VAL:
242 hal_req->support_5g_val = nla_get_u8(iter);
243 hal_req->config_support_5g = 1;
244 break;
245
246 case NAN_REQ_ATTR_SID_BEACON_VAL:
247 hal_req->sid_beacon_val = nla_get_u8(iter);
248 hal_req->config_sid_beacon = 1;
249 break;
250
251 case NAN_REQ_ATTR_RSSI_CLOSE_2G4_VAL:
252 hal_req->rssi_close_2dot4g_val = nla_get_u8(iter);
253 hal_req->config_2dot4g_rssi_close = 1;
254 break;
255
256 case NAN_REQ_ATTR_RSSI_MIDDLE_2G4_VAL:
257 hal_req->rssi_middle_2dot4g_val = nla_get_u8(iter);
258 hal_req->config_2dot4g_rssi_middle = 1;
259 break;
260
261 case NAN_REQ_ATTR_RSSI_PROXIMITY_2G4_VAL:
262 hal_req->rssi_proximity_2dot4g_val = nla_get_u8(iter);
263 hal_req->config_2dot4g_rssi_proximity = 1;
264 break;
265
266 case NAN_REQ_ATTR_HOP_COUNT_LIMIT_VAL:
267 hal_req->hop_count_limit_val = nla_get_u8(iter);
268 hal_req->config_hop_count_limit = 1;
269 break;
270
271 case NAN_REQ_ATTR_SUPPORT_2G4_VAL:
272 hal_req->support_2dot4g_val = nla_get_u8(iter);
273 hal_req->config_2dot4g_support = 1;
274 break;
275
276 case NAN_REQ_ATTR_BEACONS_2G4_VAL:
277 hal_req->beacon_2dot4g_val = nla_get_u8(iter);
278 hal_req->config_2dot4g_beacons = 1;
279 break;
280
281 case NAN_REQ_ATTR_SDF_2G4_VAL:
282 hal_req->sdf_2dot4g_val = nla_get_u8(iter);
283 hal_req->config_2dot4g_sdf = 1;
284 break;
285
286 case NAN_REQ_ATTR_BEACON_5G_VAL:
287 hal_req->beacon_5g_val = nla_get_u8(iter);
288 hal_req->config_5g_beacons = 1;
289 break;
290
291 case NAN_REQ_ATTR_SDF_5G_VAL:
292 hal_req->sdf_5g_val = nla_get_u8(iter);
293 hal_req->config_5g_sdf = 1;
294 break;
295
296 case NAN_REQ_ATTR_RSSI_CLOSE_5G_VAL:
297 hal_req->rssi_close_5g_val = nla_get_u8(iter);
298 hal_req->config_5g_rssi_close = 1;
299 break;
300
301 case NAN_REQ_ATTR_RSSI_MIDDLE_5G_VAL:
302 hal_req->rssi_middle_5g_val = nla_get_u8(iter);
303 hal_req->config_5g_rssi_middle = 1;
304 break;
305
306 case NAN_REQ_ATTR_RSSI_CLOSE_PROXIMITY_5G_VAL:
307 hal_req->rssi_close_proximity_5g_val = nla_get_u8(iter);
308 hal_req->config_5g_rssi_close_proximity = 1;
309 break;
310
311 case NAN_REQ_ATTR_RSSI_WINDOW_SIZE_VAL:
312 hal_req->rssi_window_size_val = nla_get_u8(iter);
313 hal_req->config_rssi_window_size = 1;
314 break;
315
316 case NAN_REQ_ATTR_OUI_VAL:
317 hal_req->oui_val = nla_get_u32(iter);
318 hal_req->config_oui = 1;
319 break;
320
321 case NAN_REQ_ATTR_MAC_ADDR_VAL:
322 memcpy(hal_req->intf_addr_val, nla_data(iter), ETH_ALEN);
323 hal_req->config_intf_addr = 1;
324 break;
325
326 case NAN_REQ_ATTR_CLUSTER_VAL:
327 hal_req->config_cluster_attribute_val = nla_get_u8(iter);
328 break;
329
330 case NAN_REQ_ATTR_SOCIAL_CH_SCAN_DWELL_TIME:
331 memcpy(hal_req->scan_params_val.dwell_time, nla_data(iter),
332 sizeof(hal_req->scan_params_val.dwell_time));
333 hal_req->config_scan_params = 1;
334 break;
335
336 case NAN_REQ_ATTR_SOCIAL_CH_SCAN_PERIOD:
337 memcpy(hal_req->scan_params_val.scan_period, nla_data(iter),
338 sizeof(hal_req->scan_params_val.scan_period));
339 hal_req->config_scan_params = 1;
340 break;
341
342 case NAN_REQ_ATTR_RANDOM_FACTOR_FORCE_VAL:
343 hal_req->random_factor_force_val = nla_get_u8(iter);
344 hal_req->config_random_factor_force = 1;
345 break;
346
347 case NAN_REQ_ATTR_HOP_COUNT_FORCE_VAL:
348 hal_req->hop_count_force_val = nla_get_u8(iter);
349 hal_req->config_hop_count_force = 1;
350 break;
351
352 case NAN_REQ_ATTR_CHANNEL_2G4_MHZ_VAL:
353 hal_req->channel_24g_val = nla_get_u32(iter);
354 hal_req->config_24g_channel = 1;
355 break;
356
357 case NAN_REQ_ATTR_CHANNEL_5G_MHZ_VAL:
358 hal_req->channel_5g_val = nla_get_u8(iter);
359 hal_req->config_5g_channel = 1;
360 break;
361
362 case NAN_REQ_ATTR_SUBSCRIBE_SID_BEACON_VAL:
363 hal_req->subscribe_sid_beacon_val = nla_get_u8(iter);
364 hal_req->config_subscribe_sid_beacon = 1;
365 break;
366
367 case NAN_REQ_ATTR_DW_2G4_INTERVAL:
368 hal_req->dw_2dot4g_interval_val = nla_get_u8(iter);
369 /* valid range for 2.4G is 1-5 */
370 if (hal_req->dw_2dot4g_interval_val > 0 && hal_req->dw_2dot4g_interval_val < 5)
371 hal_req->config_2dot4g_dw_band = 1;
372 break;
373
374 case NAN_REQ_ATTR_DW_5G_INTERVAL:
375 hal_req->dw_5g_interval_val = nla_get_u8(iter);
376 /* valid range for 5g is 0-5 */
377 if (hal_req->dw_5g_interval_val < 5)
378 hal_req->config_5g_dw_band = 1;
379 break;
380
381 case NAN_REQ_ATTR_DISC_MAC_ADDR_RANDOM_INTERVAL:
382 hal_req->disc_mac_addr_rand_interval_sec = nla_get_u32(iter);
383 break;
384
385 default:
386 SLSI_ERR(sdev, "Unexpected NAN enable attribute TYPE:%d\n", type);
387 return SLSI_HAL_NAN_STATUS_INVALID_PARAM;
388 }
389 }
390 return SLSI_HAL_NAN_STATUS_SUCCESS;
391 }
392
393 int slsi_nan_enable(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
394 {
395 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
396 struct slsi_hal_nan_enable_req hal_req;
397 int ret;
398 struct net_device *dev = slsi_nan_get_netdev(sdev);
399 struct netdev_vif *ndev_vif;
400 u8 nan_vif_mac_address[ETH_ALEN];
401 u8 broadcast_mac[ETH_ALEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
402 u32 reply_status = SLSI_HAL_NAN_STATUS_SUCCESS;
403
404 if (!dev) {
405 SLSI_ERR(sdev, "No NAN interface\n");
406 ret = -ENOTSUPP;
407 reply_status = SLSI_HAL_NAN_STATUS_NAN_NOT_ALLOWED;
408 goto exit;
409 }
410
411 if (!slsi_dev_nan_supported(sdev)) {
412 SLSI_ERR(sdev, "NAN not allowed(mib:%d)\n", sdev->nan_enabled);
413 ret = WIFI_HAL_ERROR_NOT_SUPPORTED;
414 reply_status = SLSI_HAL_NAN_STATUS_NAN_NOT_ALLOWED;
415 goto exit;
416 }
417
418 ndev_vif = netdev_priv(dev);
419
420 reply_status = slsi_nan_enable_get_nl_params(sdev, &hal_req, data, len);
421 if (reply_status != SLSI_HAL_NAN_STATUS_SUCCESS) {
422 ret = -EINVAL;
423 goto exit;
424 }
425
426 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
427 if (ndev_vif->activated) {
428 ret = -EINVAL;
429 SLSI_DBG1(sdev, SLSI_GSCAN, "Already Enabled. Req Rejected\n");
430 goto exit_with_mutex;
431 }
432 ndev_vif->vif_type = FAPI_VIFTYPE_NAN;
433
434 if (hal_req.config_intf_addr)
435 ether_addr_copy(nan_vif_mac_address, hal_req.intf_addr_val);
436 else
437 slsi_nan_get_mac(sdev, nan_vif_mac_address);
438
439 ret = slsi_mlme_add_vif(sdev, dev, nan_vif_mac_address, broadcast_mac);
440 if (ret) {
441 reply_status = SLSI_HAL_NAN_STATUS_INTERNAL_FAILURE;
442 SLSI_ERR(sdev, "failed to set unsync vif. Cannot start NAN\n");
443 } else {
444 ret = slsi_mlme_nan_enable(sdev, dev, &hal_req);
445 if (ret) {
446 SLSI_ERR(sdev, "failed to enable NAN.\n");
447 reply_status = SLSI_HAL_NAN_STATUS_INTERNAL_FAILURE;
448 slsi_mlme_del_vif(sdev, dev);
449 ndev_vif->activated = false;
450 ndev_vif->nan.subscribe_id_map = 0;
451 ndev_vif->nan.publish_id_map = 0;
452 } else {
453 slsi_vif_activated(sdev, dev);
454 }
455 }
456
457 exit_with_mutex:
458 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
459 exit:
460 slsi_vendor_nan_command_reply(wiphy, reply_status, ret, NAN_RESPONSE_ENABLED, 0, NULL);
461 return ret;
462 }
463
464 int slsi_nan_disable(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
465 {
466 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
467 struct net_device *dev = slsi_nan_get_netdev(sdev);
468 struct netdev_vif *ndev_vif;
469
470 if (dev) {
471 ndev_vif = netdev_priv(dev);
472 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
473 if (ndev_vif->activated) {
474 slsi_mlme_del_vif(sdev, dev);
475 ndev_vif->activated = false;
476 ndev_vif->nan.subscribe_id_map = 0;
477 ndev_vif->nan.publish_id_map = 0;
478 } else {
479 SLSI_WARN(sdev, "NAN FWif not active!!");
480 }
481 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
482 } else {
483 SLSI_WARN(sdev, "No NAN interface!!");
484 }
485
486 slsi_vendor_nan_command_reply(wiphy, SLSI_HAL_NAN_STATUS_SUCCESS, 0, NAN_RESPONSE_DISABLED, 0, NULL);
487
488 return 0;
489 }
490
491 static int slsi_nan_publish_get_nl_params(struct slsi_dev *sdev, struct slsi_hal_nan_publish_req *hal_req,
492 const void *data, int len)
493 {
494 int type, tmp, r;
495 const struct nlattr *iter;
496
497 memset(hal_req, 0, sizeof(*hal_req));
498 nla_for_each_attr(iter, data, len, tmp) {
499 type = nla_type(iter);
500 switch (type) {
501 case NAN_REQ_ATTR_PUBLISH_ID:
502 hal_req->publish_id = nla_get_u16(iter);
503 break;
504 case NAN_REQ_ATTR_PUBLISH_TTL:
505 hal_req->ttl = nla_get_u16(iter);
506 break;
507
508 case NAN_REQ_ATTR_PUBLISH_PERIOD:
509 hal_req->period = nla_get_u16(iter);
510 break;
511
512 case NAN_REQ_ATTR_PUBLISH_TYPE:
513 hal_req->publish_type = nla_get_u16(iter);
514 break;
515
516 case NAN_REQ_ATTR_PUBLISH_TX_TYPE:
517 hal_req->tx_type = nla_get_u16(iter);
518 break;
519
520 case NAN_REQ_ATTR_PUBLISH_COUNT:
521 hal_req->publish_count = nla_get_u8(iter);
522 break;
523
524 case NAN_REQ_ATTR_PUBLISH_SERVICE_NAME_LEN:
525 hal_req->service_name_len = nla_get_u16(iter);
526 break;
527
528 case NAN_REQ_ATTR_PUBLISH_SERVICE_NAME:
529 memcpy(hal_req->service_name, nla_data(iter), hal_req->service_name_len);
530 break;
531
532 case NAN_REQ_ATTR_PUBLISH_MATCH_ALGO:
533 hal_req->publish_match_indicator = nla_get_u8(iter);
534 break;
535
536 case NAN_REQ_ATTR_PUBLISH_SERVICE_INFO_LEN:
537 hal_req->service_specific_info_len = nla_get_u16(iter);
538 break;
539
540 case NAN_REQ_ATTR_PUBLISH_SERVICE_INFO:
541 memcpy(hal_req->service_specific_info, nla_data(iter), hal_req->service_specific_info_len);
542 break;
543
544 case NAN_REQ_ATTR_PUBLISH_RX_MATCH_FILTER_LEN:
545 hal_req->rx_match_filter_len = nla_get_u16(iter);
546 break;
547
548 case NAN_REQ_ATTR_PUBLISH_RX_MATCH_FILTER:
549 memcpy(hal_req->rx_match_filter, nla_data(iter), hal_req->rx_match_filter_len);
550 break;
551
552 case NAN_REQ_ATTR_PUBLISH_TX_MATCH_FILTER_LEN:
553 hal_req->tx_match_filter_len = nla_get_u16(iter);
554 break;
555
556 case NAN_REQ_ATTR_PUBLISH_TX_MATCH_FILTER:
557 memcpy(hal_req->tx_match_filter, nla_data(iter), hal_req->tx_match_filter_len);
558 break;
559
560 case NAN_REQ_ATTR_PUBLISH_RSSI_THRESHOLD_FLAG:
561 hal_req->rssi_threshold_flag = nla_get_u8(iter);
562 break;
563
564 case NAN_REQ_ATTR_PUBLISH_CONN_MAP:
565 hal_req->connmap = nla_get_u8(iter);
566 break;
567
568 case NAN_REQ_ATTR_PUBLISH_RECV_IND_CFG:
569 hal_req->recv_indication_cfg = nla_get_u8(iter);
570 break;
571
572 case NAN_REQ_ATTR_PUBLISH_SDEA_LEN:
573 hal_req->sdea_service_specific_info_len = nla_get_u16(iter);
574 break;
575
576 case NAN_REQ_ATTR_PUBLISH_SDEA:
577 memcpy(hal_req->sdea_service_specific_info, nla_data(iter),
578 hal_req->sdea_service_specific_info_len);
579 break;
580
581 case NAN_REQ_ATTR_RANGING_AUTO_RESPONSE:
582 hal_req->ranging_auto_response = nla_get_u8(iter);
583 break;
584
585 default:
586 r = slsi_nan_get_sdea_params_nl(sdev, &hal_req->sdea_params, iter, type);
587 if (r)
588 r = slsi_nan_get_ranging_cfg_nl(sdev, &hal_req->ranging_cfg, iter, type);
589 if (r)
590 r = slsi_nan_get_security_info_nl(sdev, &hal_req->sec_info, iter, type);
591 if (r)
592 r = slsi_nan_get_range_resp_cfg_nl(sdev, &hal_req->range_response_cfg, iter, type);
593 if (r) {
594 SLSI_ERR(sdev, "Unexpected NAN publish attribute TYPE:%d\n", type);
595 return SLSI_HAL_NAN_STATUS_INVALID_PARAM;
596 }
597 }
598 }
599 return SLSI_HAL_NAN_STATUS_SUCCESS;
600 }
601
602 int slsi_nan_publish(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
603 {
604 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
605 struct slsi_hal_nan_publish_req *hal_req;
606 struct net_device *dev = slsi_nan_get_netdev(sdev);
607 struct netdev_vif *ndev_vif;
608 int ret;
609 u32 reply_status;
610 u32 publish_id = 0;
611
612 if (!dev) {
613 SLSI_ERR(sdev, "NAN netif not active!!\n");
614 ret = -EINVAL;
615 reply_status = SLSI_HAL_NAN_STATUS_NAN_NOT_ALLOWED;
616 goto exit;
617 }
618
619 hal_req = kmalloc(sizeof(*hal_req), GFP_KERNEL);
620 if (!hal_req) {
621 SLSI_ERR(sdev, "failed to alloc hal_req\n");
622 reply_status = SLSI_HAL_NAN_STATUS_NO_RESOURCE_AVAILABLE;
623 ret = -ENOMEM;
624 goto exit;
625 }
626
627 ndev_vif = netdev_priv(dev);
628 reply_status = slsi_nan_publish_get_nl_params(sdev, hal_req, data, len);
629 if (reply_status != SLSI_HAL_NAN_STATUS_SUCCESS) {
630 kfree(hal_req);
631 ret = -EINVAL;
632 goto exit;
633 }
634
635 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
636
637 if (!ndev_vif->activated) {
638 SLSI_WARN(sdev, "NAN vif not activated\n");
639 reply_status = SLSI_HAL_NAN_STATUS_NAN_NOT_ALLOWED;
640 ret = WIFI_HAL_ERROR_NOT_AVAILABLE;
641 goto exit_with_lock;
642 }
643
644 if (!hal_req->publish_id) {
645 hal_req->publish_id = slsi_nan_get_new_publish_id(ndev_vif);
646 } else if (!slsi_nan_is_publish_id_active(ndev_vif, hal_req->publish_id)) {
647 SLSI_WARN(sdev, "Publish id %d not found. map:%x\n", hal_req->publish_id,
648 ndev_vif->nan.publish_id_map);
649 reply_status = SLSI_HAL_NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID;
650 ret = -EINVAL;
651 goto exit_with_lock;
652 }
653
654 if (hal_req->publish_id) {
655 ret = slsi_mlme_nan_publish(sdev, dev, hal_req, hal_req->publish_id);
656 if (ret)
657 reply_status = SLSI_HAL_NAN_STATUS_INTERNAL_FAILURE;
658 else
659 publish_id = hal_req->publish_id;
660 } else {
661 reply_status = SLSI_HAL_NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID;
662 SLSI_WARN(sdev, "Too Many concurrent PUBLISH REQ(map:%x)\n",
663 ndev_vif->nan.publish_id_map);
664 ret = -ENOTSUPP;
665 }
666 exit_with_lock:
667 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
668 kfree(hal_req);
669 exit:
670 slsi_vendor_nan_command_reply(wiphy, reply_status, ret, NAN_RESPONSE_PUBLISH, publish_id, NULL);
671 return ret;
672 }
673
674 int slsi_nan_publish_cancel(struct wiphy *wiphy, struct wireless_dev *wdev,
675 const void *data, int len)
676 {
677 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
678 struct net_device *dev = slsi_nan_get_netdev(sdev);
679 struct netdev_vif *ndev_vif;
680 int type, tmp, ret = 0;
681 u16 publish_id = 0;
682 const struct nlattr *iter;
683 u32 reply_status = SLSI_HAL_NAN_STATUS_SUCCESS;
684
685 if (!dev) {
686 SLSI_ERR(sdev, "NAN netif not active!!");
687 reply_status = SLSI_HAL_NAN_STATUS_NAN_NOT_ALLOWED;
688 ret = -EINVAL;
689 goto exit;
690 }
691
692 ndev_vif = netdev_priv(dev);
693 nla_for_each_attr(iter, data, len, tmp) {
694 type = nla_type(iter);
695 switch (type) {
696 case NAN_REQ_ATTR_PUBLISH_ID:
697 publish_id = nla_get_u16(iter);
698 break;
699 default:
700 SLSI_ERR(sdev, "Unexpected NAN publishcancel attribute TYPE:%d\n", type);
701 }
702 }
703
704 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
705 if (!ndev_vif->activated) {
706 reply_status = SLSI_HAL_NAN_STATUS_NAN_NOT_ALLOWED;
707 ret = WIFI_HAL_ERROR_NOT_AVAILABLE;
708 goto exit_with_lock;
709 }
710 if (!publish_id || !slsi_nan_is_publish_id_active(ndev_vif, publish_id)) {
711 reply_status = SLSI_HAL_NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID;
712 SLSI_WARN(sdev, "Publish_id(%d) not active. map:%x\n",
713 publish_id, ndev_vif->nan.publish_id_map);
714 } else {
715 ret = slsi_mlme_nan_publish(sdev, dev, NULL, publish_id);
716 if (ret)
717 reply_status = SLSI_HAL_NAN_STATUS_INTERNAL_FAILURE;
718 }
719 exit_with_lock:
720 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
721 exit:
722 slsi_vendor_nan_command_reply(wiphy, reply_status, ret, NAN_RESPONSE_PUBLISH_CANCEL, publish_id, NULL);
723 return ret;
724 }
725
726 static int slsi_nan_subscribe_get_nl_params(struct slsi_dev *sdev, struct slsi_hal_nan_subscribe_req *hal_req,
727 const void *data, int len)
728 {
729 int type, tmp, r;
730 const struct nlattr *iter;
731
732 memset(hal_req, 0, sizeof(*hal_req));
733 nla_for_each_attr(iter, data, len, tmp) {
734 type = nla_type(iter);
735 switch (type) {
736 case NAN_REQ_ATTR_SUBSCRIBE_ID:
737 hal_req->subscribe_id = nla_get_u16(iter);
738 break;
739
740 case NAN_REQ_ATTR_SUBSCRIBE_TTL:
741 hal_req->ttl = nla_get_u16(iter);
742 break;
743
744 case NAN_REQ_ATTR_SUBSCRIBE_PERIOD:
745 hal_req->period = nla_get_u16(iter);
746 break;
747
748 case NAN_REQ_ATTR_SUBSCRIBE_TYPE:
749 hal_req->subscribe_type = nla_get_u8(iter);
750 break;
751
752 case NAN_REQ_ATTR_SUBSCRIBE_RESP_FILTER_TYPE:
753 hal_req->service_response_filter = nla_get_u16(iter);
754 break;
755
756 case NAN_REQ_ATTR_SUBSCRIBE_RESP_INCLUDE:
757 hal_req->service_response_include = nla_get_u8(iter);
758 break;
759
760 case NAN_REQ_ATTR_SUBSCRIBE_USE_RESP_FILTER:
761 hal_req->use_service_response_filter = nla_get_u8(iter);
762 break;
763
764 case NAN_REQ_ATTR_SUBSCRIBE_SSI_REQUIRED:
765 hal_req->ssi_required_for_match_indication = nla_get_u8(iter);
766 break;
767
768 case NAN_REQ_ATTR_SUBSCRIBE_MATCH_INDICATOR:
769 hal_req->subscribe_match_indicator = nla_get_u8(iter);
770 break;
771
772 case NAN_REQ_ATTR_SUBSCRIBE_COUNT:
773 hal_req->subscribe_count = nla_get_u8(iter);
774 break;
775
776 case NAN_REQ_ATTR_SUBSCRIBE_SERVICE_NAME_LEN:
777 hal_req->service_name_len = nla_get_u16(iter);
778 break;
779
780 case NAN_REQ_ATTR_SUBSCRIBE_SERVICE_NAME:
781 memcpy(hal_req->service_name, nla_data(iter), hal_req->service_name_len);
782 break;
783
784 case NAN_REQ_ATTR_SUBSCRIBE_SERVICE_INFO_LEN:
785 hal_req->service_specific_info_len = nla_get_u16(iter);
786 break;
787
788 case NAN_REQ_ATTR_SUBSCRIBE_SERVICE_INFO:
789 memcpy(hal_req->service_specific_info, nla_data(iter), hal_req->service_specific_info_len);
790 break;
791
792 case NAN_REQ_ATTR_SUBSCRIBE_RX_MATCH_FILTER_LEN:
793 hal_req->rx_match_filter_len = nla_get_u16(iter);
794 break;
795
796 case NAN_REQ_ATTR_SUBSCRIBE_RX_MATCH_FILTER:
797 memcpy(hal_req->rx_match_filter, nla_data(iter), hal_req->rx_match_filter_len);
798 break;
799
800 case NAN_REQ_ATTR_SUBSCRIBE_TX_MATCH_FILTER_LEN:
801 hal_req->tx_match_filter_len = nla_get_u16(iter);
802 break;
803
804 case NAN_REQ_ATTR_SUBSCRIBE_TX_MATCH_FILTER:
805 memcpy(hal_req->tx_match_filter, nla_data(iter), hal_req->tx_match_filter_len);
806 break;
807
808 case NAN_REQ_ATTR_SUBSCRIBE_RSSI_THRESHOLD_FLAG:
809 hal_req->rssi_threshold_flag = nla_get_u8(iter);
810 break;
811
812 case NAN_REQ_ATTR_SUBSCRIBE_CONN_MAP:
813 hal_req->connmap = nla_get_u8(iter);
814 break;
815
816 case NAN_REQ_ATTR_SUBSCRIBE_NUM_INTF_ADDR_PRESENT:
817 hal_req->num_intf_addr_present = nla_get_u8(iter);
818 break;
819
820 case NAN_REQ_ATTR_SUBSCRIBE_INTF_ADDR:
821 memcpy(hal_req->intf_addr, nla_data(iter), hal_req->num_intf_addr_present * ETH_ALEN);
822 break;
823
824 case NAN_REQ_ATTR_SUBSCRIBE_RECV_IND_CFG:
825 hal_req->recv_indication_cfg = nla_get_u8(iter);
826 break;
827
828 case NAN_REQ_ATTR_PUBLISH_SDEA_LEN:
829 hal_req->sdea_service_specific_info_len = nla_get_u16(iter);
830 break;
831
832 case NAN_REQ_ATTR_PUBLISH_SDEA:
833 memcpy(hal_req->sdea_service_specific_info, nla_data(iter),
834 hal_req->sdea_service_specific_info_len);
835 break;
836
837 case NAN_REQ_ATTR_RANGING_AUTO_RESPONSE:
838 hal_req->ranging_auto_response = nla_get_u8(iter);
839 break;
840
841 default:
842 r = slsi_nan_get_sdea_params_nl(sdev, &hal_req->sdea_params, iter, type);
843 if (r)
844 r = slsi_nan_get_ranging_cfg_nl(sdev, &hal_req->ranging_cfg, iter, type);
845 if (r)
846 r = slsi_nan_get_security_info_nl(sdev, &hal_req->sec_info, iter, type);
847 if (r)
848 r = slsi_nan_get_range_resp_cfg_nl(sdev, &hal_req->range_response_cfg, iter, type);
849 if (r) {
850 SLSI_ERR(sdev, "Unexpected NAN subscribe attribute TYPE:%d\n", type);
851 return SLSI_HAL_NAN_STATUS_INVALID_PARAM;
852 }
853 }
854 }
855 return SLSI_HAL_NAN_STATUS_SUCCESS;
856 }
857
858 int slsi_nan_subscribe(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
859 {
860 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
861 struct net_device *dev = slsi_nan_get_netdev(sdev);
862 struct netdev_vif *ndev_vif;
863 struct slsi_hal_nan_subscribe_req *hal_req;
864 int ret;
865 u32 reply_status;
866 u32 subscribe_id = 0;
867
868 if (!dev) {
869 SLSI_ERR(sdev, "NAN netif not active!!\n");
870 reply_status = SLSI_HAL_NAN_STATUS_NAN_NOT_ALLOWED;
871 ret = -EINVAL;
872 goto exit;
873 }
874
875 hal_req = kmalloc(sizeof(*hal_req), GFP_KERNEL);
876 if (!hal_req) {
877 SLSI_ERR(sdev, "Failed to alloc hal_req structure!!!\n");
878 reply_status = SLSI_HAL_NAN_STATUS_NO_RESOURCE_AVAILABLE;
879 ret = -ENOMEM;
880 goto exit;
881 }
882
883 ndev_vif = netdev_priv(dev);
884 reply_status = slsi_nan_subscribe_get_nl_params(sdev, hal_req, data, len);
885 if (reply_status != SLSI_HAL_NAN_STATUS_SUCCESS) {
886 kfree(hal_req);
887 ret = -EINVAL;
888 goto exit;
889 }
890
891 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
892 if (!ndev_vif->activated) {
893 SLSI_WARN(sdev, "NAN vif not activated\n");
894 reply_status = SLSI_HAL_NAN_STATUS_NAN_NOT_ALLOWED;
895 ret = WIFI_HAL_ERROR_NOT_AVAILABLE;
896 goto exit_with_lock;
897 }
898
899 if (!hal_req->subscribe_id) {
900 hal_req->subscribe_id = slsi_nan_get_new_subscribe_id(ndev_vif);
901 } else if (!slsi_nan_is_subscribe_id_active(ndev_vif, hal_req->subscribe_id)) {
902 SLSI_WARN(sdev, "Subscribe id %d not found. map:%x\n", hal_req->subscribe_id,
903 ndev_vif->nan.subscribe_id_map);
904 reply_status = SLSI_HAL_NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID;
905 ret = -EINVAL;
906 goto exit_with_lock;
907 }
908
909 ret = slsi_mlme_nan_subscribe(sdev, dev, hal_req, hal_req->subscribe_id);
910 if (ret)
911 reply_status = SLSI_HAL_NAN_STATUS_INTERNAL_FAILURE;
912 else
913 subscribe_id = hal_req->subscribe_id;
914
915 exit_with_lock:
916 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
917 kfree(hal_req);
918 exit:
919 slsi_vendor_nan_command_reply(wiphy, reply_status, ret, NAN_RESPONSE_SUBSCRIBE, subscribe_id, NULL);
920 return ret;
921 }
922
923 int slsi_nan_subscribe_cancel(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
924 {
925 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
926 struct net_device *dev = slsi_nan_get_netdev(sdev);
927 struct netdev_vif *ndev_vif;
928 int type, tmp, ret = WIFI_HAL_ERROR_UNKNOWN;
929 u16 subscribe_id = 0;
930 const struct nlattr *iter;
931 u32 reply_status = SLSI_HAL_NAN_STATUS_SUCCESS;
932
933 if (!dev) {
934 SLSI_ERR(sdev, "NAN netif not active!!");
935 reply_status = SLSI_HAL_NAN_STATUS_NAN_NOT_ALLOWED;
936 ret = WIFI_HAL_ERROR_NOT_AVAILABLE;
937 goto exit;
938 }
939
940 ndev_vif = netdev_priv(dev);
941
942 nla_for_each_attr(iter, data, len, tmp) {
943 type = nla_type(iter);
944 switch (type) {
945 case NAN_REQ_ATTR_SUBSCRIBE_ID:
946 subscribe_id = nla_get_u16(iter);
947 break;
948 default:
949 SLSI_ERR(sdev, "Unexpected NAN subscribecancel attribute TYPE:%d\n", type);
950 reply_status = SLSI_HAL_NAN_STATUS_INVALID_PARAM;
951 goto exit;
952 }
953 }
954
955 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
956 if (ndev_vif->activated) {
957 if (!subscribe_id || !slsi_nan_is_subscribe_id_active(ndev_vif, subscribe_id)) {
958 SLSI_WARN(sdev, "subscribe_id(%d) not active. map:%x\n",
959 subscribe_id, ndev_vif->nan.subscribe_id_map);
960 reply_status = SLSI_HAL_NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID;
961 } else {
962 ret = slsi_mlme_nan_subscribe(sdev, dev, NULL, subscribe_id);
963 if (ret)
964 reply_status = SLSI_HAL_NAN_STATUS_INTERNAL_FAILURE;
965 }
966 } else {
967 SLSI_ERR(sdev, "vif not activated\n");
968 reply_status = SLSI_HAL_NAN_STATUS_NAN_NOT_ALLOWED;
969 ret = WIFI_HAL_ERROR_NOT_AVAILABLE;
970 }
971 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
972 exit:
973 slsi_vendor_nan_command_reply(wiphy, reply_status, ret, NAN_RESPONSE_SUBSCRIBE_CANCEL, subscribe_id, NULL);
974 return ret;
975 }
976
977 static int slsi_nan_followup_get_nl_params(struct slsi_dev *sdev, struct slsi_hal_nan_transmit_followup_req *hal_req,
978 const void *data, int len)
979 {
980 int type, tmp;
981 const struct nlattr *iter;
982
983 memset(hal_req, 0, sizeof(*hal_req));
984 nla_for_each_attr(iter, data, len, tmp) {
985 type = nla_type(iter);
986 switch (type) {
987 case NAN_REQ_ATTR_FOLLOWUP_ID:
988 hal_req->publish_subscribe_id = nla_get_u16(iter);
989 break;
990
991 case NAN_REQ_ATTR_FOLLOWUP_REQUESTOR_ID:
992 hal_req->requestor_instance_id = nla_get_u32(iter);
993 break;
994
995 case NAN_REQ_ATTR_FOLLOWUP_ADDR:
996 memcpy(hal_req->addr, nla_data(iter), ETH_ALEN);
997 break;
998
999 case NAN_REQ_ATTR_FOLLOWUP_PRIORITY:
1000 hal_req->priority = nla_get_u8(iter);
1001 break;
1002
1003 case NAN_REQ_ATTR_FOLLOWUP_TX_WINDOW:
1004 hal_req->dw_or_faw = nla_get_u8(iter);
1005 break;
1006
1007 case NAN_REQ_ATTR_FOLLOWUP_SERVICE_NAME_LEN:
1008 hal_req->service_specific_info_len = nla_get_u16(iter);
1009 break;
1010
1011 case NAN_REQ_ATTR_FOLLOWUP_SERVICE_NAME:
1012 memcpy(hal_req->service_specific_info, nla_data(iter), hal_req->service_specific_info_len);
1013 break;
1014
1015 case NAN_REQ_ATTR_FOLLOWUP_RECV_IND_CFG:
1016 hal_req->recv_indication_cfg = nla_get_u8(iter);
1017 break;
1018
1019 case NAN_REQ_ATTR_PUBLISH_SDEA_LEN:
1020 hal_req->sdea_service_specific_info_len = nla_get_u16(iter);
1021 break;
1022
1023 case NAN_REQ_ATTR_PUBLISH_SDEA:
1024 memcpy(hal_req->sdea_service_specific_info, nla_data(iter),
1025 hal_req->sdea_service_specific_info_len);
1026 break;
1027
1028 default:
1029 SLSI_ERR(sdev, "Unexpected NAN followup attribute TYPE:%d\n", type);
1030 return SLSI_HAL_NAN_STATUS_INVALID_PARAM;
1031 }
1032 }
1033 return SLSI_HAL_NAN_STATUS_SUCCESS;
1034 }
1035
1036 int slsi_nan_transmit_followup(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
1037 {
1038 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
1039 struct net_device *dev = slsi_nan_get_netdev(sdev);
1040 struct netdev_vif *ndev_vif;
1041 struct slsi_hal_nan_transmit_followup_req hal_req;
1042 int ret;
1043 u32 reply_status = SLSI_HAL_NAN_STATUS_SUCCESS;
1044
1045 if (!dev) {
1046 SLSI_ERR(sdev, "NAN netif not active!!");
1047 ret = -EINVAL;
1048 reply_status = SLSI_HAL_NAN_STATUS_NAN_NOT_ALLOWED;
1049 goto exit;
1050 }
1051
1052 ndev_vif = netdev_priv(dev);
1053 reply_status = slsi_nan_followup_get_nl_params(sdev, &hal_req, data, len);
1054 if (reply_status) {
1055 ret = -EINVAL;
1056 goto exit;
1057 }
1058
1059 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
1060 if (!ndev_vif->activated) {
1061 SLSI_WARN(sdev, "NAN vif not activated\n");
1062 reply_status = SLSI_HAL_NAN_STATUS_NAN_NOT_ALLOWED;
1063 ret = WIFI_HAL_ERROR_NOT_AVAILABLE;
1064 goto exit_with_lock;
1065 }
1066
1067 if (!hal_req.publish_subscribe_id ||
1068 !(slsi_nan_is_subscribe_id_active(ndev_vif, hal_req.publish_subscribe_id) ||
1069 slsi_nan_is_publish_id_active(ndev_vif, hal_req.publish_subscribe_id))) {
1070 SLSI_WARN(sdev, "publish/Subscribe id %d not found. map:%x\n", hal_req.publish_subscribe_id,
1071 ndev_vif->nan.subscribe_id_map);
1072 reply_status = SLSI_HAL_NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID;
1073 ret = -EINVAL;
1074 goto exit_with_lock;
1075 }
1076
1077 ret = slsi_mlme_nan_tx_followup(sdev, dev, &hal_req);
1078 if (ret)
1079 reply_status = SLSI_HAL_NAN_STATUS_INTERNAL_FAILURE;
1080
1081 exit_with_lock:
1082 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
1083 exit:
1084 slsi_vendor_nan_command_reply(wiphy, reply_status, ret, NAN_RESPONSE_TRANSMIT_FOLLOWUP, 0, NULL);
1085 return ret;
1086 }
1087
1088 static int slsi_nan_config_get_nl_params(struct slsi_dev *sdev, struct slsi_hal_nan_config_req *hal_req,
1089 const void *data, int len)
1090 {
1091 int type, type1, tmp, tmp1, disc_attr_idx = 0, famchan_idx = 0;
1092 const struct nlattr *iter, *iter1;
1093 struct slsi_hal_nan_post_discovery_param *disc_attr;
1094 struct slsi_hal_nan_further_availability_channel *famchan;
1095
1096 memset(hal_req, 0, sizeof(*hal_req));
1097 nla_for_each_attr(iter, data, len, tmp) {
1098 type = nla_type(iter);
1099 switch (type) {
1100 case NAN_REQ_ATTR_SID_BEACON_VAL:
1101 hal_req->sid_beacon = nla_get_u8(iter);
1102 hal_req->config_sid_beacon = 1;
1103 break;
1104
1105 case NAN_REQ_ATTR_RSSI_PROXIMITY_2G4_VAL:
1106 hal_req->rssi_proximity = nla_get_u8(iter);
1107 hal_req->config_rssi_proximity = 1;
1108 break;
1109
1110 case NAN_REQ_ATTR_MASTER_PREF:
1111 hal_req->master_pref = nla_get_u8(iter);
1112 hal_req->config_master_pref = 1;
1113 break;
1114
1115 case NAN_REQ_ATTR_RSSI_CLOSE_PROXIMITY_5G_VAL:
1116 hal_req->rssi_close_proximity_5g_val = nla_get_u8(iter);
1117 hal_req->config_5g_rssi_close_proximity = 1;
1118 break;
1119
1120 case NAN_REQ_ATTR_RSSI_WINDOW_SIZE_VAL:
1121 hal_req->rssi_window_size_val = nla_get_u8(iter);
1122 hal_req->config_rssi_window_size = 1;
1123 break;
1124
1125 case NAN_REQ_ATTR_CLUSTER_VAL:
1126 hal_req->config_cluster_attribute_val = nla_get_u8(iter);
1127 break;
1128
1129 case NAN_REQ_ATTR_SOCIAL_CH_SCAN_DWELL_TIME:
1130 memcpy(hal_req->scan_params_val.dwell_time, nla_data(iter),
1131 sizeof(hal_req->scan_params_val.dwell_time));
1132 hal_req->config_scan_params = 1;
1133 break;
1134
1135 case NAN_REQ_ATTR_SOCIAL_CH_SCAN_PERIOD:
1136 memcpy(hal_req->scan_params_val.scan_period, nla_data(iter),
1137 sizeof(hal_req->scan_params_val.scan_period));
1138 hal_req->config_scan_params = 1;
1139 break;
1140
1141 case NAN_REQ_ATTR_RANDOM_FACTOR_FORCE_VAL:
1142 hal_req->random_factor_force_val = nla_get_u8(iter);
1143 hal_req->config_random_factor_force = 1;
1144 break;
1145
1146 case NAN_REQ_ATTR_HOP_COUNT_FORCE_VAL:
1147 hal_req->hop_count_force_val = nla_get_u8(iter);
1148 hal_req->config_hop_count_force = 1;
1149 break;
1150
1151 case NAN_REQ_ATTR_CONN_CAPABILITY_PAYLOAD_TX:
1152 hal_req->conn_capability_val.payload_transmit_flag = nla_get_u8(iter);
1153 hal_req->config_conn_capability = 1;
1154 break;
1155
1156 case NAN_REQ_ATTR_CONN_CAPABILITY_WFD:
1157 hal_req->conn_capability_val.is_wfd_supported = nla_get_u8(iter);
1158 hal_req->config_conn_capability = 1;
1159 break;
1160
1161 case NAN_REQ_ATTR_CONN_CAPABILITY_WFDS:
1162 hal_req->conn_capability_val.is_wfds_supported = nla_get_u8(iter);
1163 hal_req->config_conn_capability = 1;
1164 break;
1165
1166 case NAN_REQ_ATTR_CONN_CAPABILITY_TDLS:
1167 hal_req->conn_capability_val.is_tdls_supported = nla_get_u8(iter);
1168 hal_req->config_conn_capability = 1;
1169 break;
1170
1171 case NAN_REQ_ATTR_CONN_CAPABILITY_MESH:
1172 hal_req->conn_capability_val.is_mesh_supported = nla_get_u8(iter);
1173 hal_req->config_conn_capability = 1;
1174 break;
1175
1176 case NAN_REQ_ATTR_CONN_CAPABILITY_IBSS:
1177 hal_req->conn_capability_val.is_ibss_supported = nla_get_u8(iter);
1178 hal_req->config_conn_capability = 1;
1179 break;
1180
1181 case NAN_REQ_ATTR_CONN_CAPABILITY_WLAN_INFRA:
1182 hal_req->conn_capability_val.wlan_infra_field = nla_get_u8(iter);
1183 hal_req->config_conn_capability = 1;
1184 break;
1185
1186 case NAN_REQ_ATTR_DISCOVERY_ATTR_NUM_ENTRIES:
1187 hal_req->num_config_discovery_attr = nla_get_u8(iter);
1188 break;
1189
1190 case NAN_REQ_ATTR_DISCOVERY_ATTR_VAL:
1191 if (disc_attr_idx >= hal_req->num_config_discovery_attr) {
1192 SLSI_ERR(sdev,
1193 "disc attr(%d) > num disc attr(%d)\n",
1194 disc_attr_idx + 1, hal_req->num_config_discovery_attr);
1195 return -EINVAL;
1196 }
1197 disc_attr = &hal_req->discovery_attr_val[disc_attr_idx];
1198 disc_attr_idx++;
1199 nla_for_each_nested(iter1, iter, tmp1) {
1200 type1 = nla_type(iter1);
1201 switch (type1) {
1202 case NAN_REQ_ATTR_CONN_TYPE:
1203 disc_attr->type = nla_get_u8(iter1);
1204 break;
1205
1206 case NAN_REQ_ATTR_NAN_ROLE:
1207 disc_attr->role = nla_get_u8(iter1);
1208 break;
1209
1210 case NAN_REQ_ATTR_TRANSMIT_FREQ:
1211 disc_attr->transmit_freq = nla_get_u8(iter1);
1212 break;
1213
1214 case NAN_REQ_ATTR_AVAILABILITY_DURATION:
1215 disc_attr->duration = nla_get_u8(iter1);
1216 break;
1217
1218 case NAN_REQ_ATTR_AVAILABILITY_INTERVAL:
1219 disc_attr->avail_interval_bitmap = nla_get_u32(iter1);
1220 break;
1221
1222 case NAN_REQ_ATTR_MAC_ADDR_VAL:
1223 memcpy(disc_attr->addr, nla_data(iter1), ETH_ALEN);
1224 break;
1225
1226 case NAN_REQ_ATTR_MESH_ID_LEN:
1227 disc_attr->mesh_id_len = nla_get_u16(iter1);
1228 break;
1229
1230 case NAN_REQ_ATTR_MESH_ID:
1231 memcpy(disc_attr->mesh_id, nla_data(iter1), disc_attr->mesh_id_len);
1232 break;
1233
1234 case NAN_REQ_ATTR_INFRASTRUCTURE_SSID_LEN:
1235 disc_attr->infrastructure_ssid_len = nla_get_u16(iter1);
1236 break;
1237
1238 case NAN_REQ_ATTR_INFRASTRUCTURE_SSID:
1239 memcpy(disc_attr->infrastructure_ssid_val, nla_data(iter1),
1240 disc_attr->infrastructure_ssid_len);
1241 break;
1242 }
1243 }
1244 break;
1245
1246 case NAN_REQ_ATTR_FURTHER_AVAIL_NUM_ENTRIES:
1247 hal_req->fam_val.numchans = nla_get_u8(iter);
1248 hal_req->config_fam = 1;
1249 break;
1250
1251 case NAN_REQ_ATTR_FURTHER_AVAIL_VAL:
1252 hal_req->config_fam = 1;
1253 if (famchan_idx >= hal_req->fam_val.numchans) {
1254 SLSI_ERR(sdev,
1255 "famchan attr(%d) > numchans(%d)\n",
1256 famchan_idx + 1, hal_req->fam_val.numchans);
1257 return -EINVAL;
1258 }
1259 famchan = &hal_req->fam_val.famchan[famchan_idx];
1260 famchan_idx++;
1261 nla_for_each_nested(iter1, iter, tmp1) {
1262 type1 = nla_type(iter1);
1263 switch (type1) {
1264 case NAN_REQ_ATTR_FURTHER_AVAIL_ENTRY_CTRL:
1265 famchan->entry_control = nla_get_u8(iter1);
1266 break;
1267
1268 case NAN_REQ_ATTR_FURTHER_AVAIL_CHAN_CLASS:
1269 famchan->class_val = nla_get_u8(iter1);
1270 break;
1271
1272 case NAN_REQ_ATTR_FURTHER_AVAIL_CHAN:
1273 famchan->channel = nla_get_u8(iter1);
1274 break;
1275
1276 case NAN_REQ_ATTR_FURTHER_AVAIL_CHAN_MAPID:
1277 famchan->mapid = nla_get_u8(iter1);
1278 break;
1279
1280 case NAN_REQ_ATTR_FURTHER_AVAIL_INTERVAL_BITMAP:
1281 famchan->avail_interval_bitmap = nla_get_u32(iter1);
1282 break;
1283 }
1284 }
1285 break;
1286
1287 case NAN_REQ_ATTR_SUBSCRIBE_SID_BEACON_VAL:
1288 hal_req->subscribe_sid_beacon_val = nla_get_u8(iter);
1289 hal_req->config_subscribe_sid_beacon = 1;
1290 break;
1291
1292 case NAN_REQ_ATTR_DW_2G4_INTERVAL:
1293 hal_req->dw_2dot4g_interval_val = nla_get_u8(iter);
1294 /* valid range for 2.4G is 1-5 */
1295 if (hal_req->dw_2dot4g_interval_val > 0 && hal_req->dw_2dot4g_interval_val < 6)
1296 hal_req->config_2dot4g_dw_band = 1;
1297 break;
1298
1299 case NAN_REQ_ATTR_DW_5G_INTERVAL:
1300 hal_req->dw_5g_interval_val = nla_get_u8(iter);
1301 /* valid range for 5g is 0-5 */
1302 if (hal_req->dw_5g_interval_val < 6)
1303 hal_req->config_5g_dw_band = 1;
1304 break;
1305
1306 case NAN_REQ_ATTR_DISC_MAC_ADDR_RANDOM_INTERVAL:
1307 hal_req->disc_mac_addr_rand_interval_sec = nla_get_u8(iter);
1308 break;
1309
1310 default:
1311 SLSI_ERR(sdev, "Unexpected NAN config attribute TYPE:%d\n", type);
1312 return SLSI_HAL_NAN_STATUS_INVALID_PARAM;
1313 }
1314 }
1315 return SLSI_HAL_NAN_STATUS_SUCCESS;
1316 }
1317
1318 int slsi_nan_set_config(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
1319 {
1320 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
1321 struct net_device *dev = slsi_nan_get_netdev(sdev);
1322 struct netdev_vif *ndev_vif;
1323 struct slsi_hal_nan_config_req hal_req;
1324 int ret;
1325 u32 reply_status = SLSI_HAL_NAN_STATUS_SUCCESS;
1326
1327 if (!dev) {
1328 SLSI_ERR(sdev, "NAN netif not active!!");
1329 ret = -EINVAL;
1330 reply_status = SLSI_HAL_NAN_STATUS_NAN_NOT_ALLOWED;
1331 goto exit;
1332 }
1333
1334 ndev_vif = netdev_priv(dev);
1335 reply_status = slsi_nan_config_get_nl_params(sdev, &hal_req, data, len);
1336 if (reply_status) {
1337 ret = -EINVAL;
1338 goto exit;
1339 }
1340
1341 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
1342 if (!ndev_vif->activated) {
1343 SLSI_WARN(sdev, "NAN vif not activated\n");
1344 reply_status = SLSI_HAL_NAN_STATUS_NAN_NOT_ALLOWED;
1345 ret = WIFI_HAL_ERROR_NOT_AVAILABLE;
1346 } else {
1347 ret = slsi_mlme_nan_set_config(sdev, dev, &hal_req);
1348 if (ret)
1349 reply_status = SLSI_HAL_NAN_STATUS_INTERNAL_FAILURE;
1350 }
1351 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
1352 exit:
1353 slsi_vendor_nan_command_reply(wiphy, reply_status, ret, NAN_RESPONSE_CONFIG, 0, NULL);
1354 return ret;
1355 }
1356
1357 int slsi_nan_get_capabilities(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
1358 {
1359 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
1360 struct net_device *dev = slsi_nan_get_netdev(sdev);
1361 struct netdev_vif *ndev_vif;
1362 u32 reply_status = SLSI_HAL_NAN_STATUS_SUCCESS;
1363 struct slsi_hal_nan_capabilities nan_capabilities;
1364 int ret = 0, i;
1365 struct slsi_mib_value *values = NULL;
1366 struct slsi_mib_data mibrsp = { 0, NULL };
1367 struct slsi_mib_get_entry get_values[] = {{ SLSI_PSID_UNIFI_NAN_MAX_CONCURRENT_CLUSTERS, { 0, 0 } },
1368 { SLSI_PSID_UNIFI_NAN_MAX_CONCURRENT_PUBLISHES, { 0, 0 } },
1369 { SLSI_PSID_UNIFI_NAN_MAX_CONCURRENT_SUBSCRIBES, { 0, 0 } },
1370 { SLSI_PSID_UNIFI_NAN_MAX_SERVICE_NAME_LENGTH, { 0, 0 } },
1371 { SLSI_PSID_UNIFI_NAN_MAX_MATCH_FILTER_LENGTH, { 0, 0 } },
1372 { SLSI_PSID_UNIFI_NAN_MAX_TOTAL_MATCH_FILTER_LENGTH, { 0, 0 } },
1373 { SLSI_PSID_UNIFI_NAN_MAX_SERVICE_SPECIFIC_INFO_LENGTH, { 0, 0 } },
1374 { SLSI_PSID_UNIFI_NAN_MAX_VSA_DATA_LENGTH, { 0, 0 } },
1375 { SLSI_PSID_UNIFI_NAN_MAX_MESH_DATA_LENGTH, { 0, 0 } },
1376 { SLSI_PSID_UNIFI_NAN_MAX_NDI_INTERFACES, { 0, 0 } },
1377 { SLSI_PSID_UNIFI_NAN_MAX_NDP_SESSIONS, { 0, 0 } },
1378 { SLSI_PSID_UNIFI_NAN_MAX_APP_INFO_LENGTH, { 0, 0 } } };
1379 u32 *capabilities_mib_val[] = { &nan_capabilities.max_concurrent_nan_clusters,
1380 &nan_capabilities.max_publishes,
1381 &nan_capabilities.max_subscribes,
1382 &nan_capabilities.max_service_name_len,
1383 &nan_capabilities.max_match_filter_len,
1384 &nan_capabilities.max_total_match_filter_len,
1385 &nan_capabilities.max_service_specific_info_len,
1386 &nan_capabilities.max_vsa_data_len,
1387 &nan_capabilities.max_mesh_data_len,
1388 &nan_capabilities.max_ndi_interfaces,
1389 &nan_capabilities.max_ndp_sessions,
1390 &nan_capabilities.max_app_info_len };
1391
1392 if (!dev) {
1393 SLSI_ERR(sdev, "NAN netif not active!!");
1394 reply_status = SLSI_HAL_NAN_STATUS_NAN_NOT_ALLOWED;
1395 ret = -EINVAL;
1396 goto exit;
1397 }
1398
1399 ndev_vif = netdev_priv(dev);
1400
1401 /* Expect each mib length in response is 11 */
1402 mibrsp.dataLength = 11 * ARRAY_SIZE(get_values);
1403 mibrsp.data = kmalloc(mibrsp.dataLength, GFP_KERNEL);
1404 if (!mibrsp.data) {
1405 SLSI_ERR(sdev, "Cannot kmalloc %d bytes\n", mibrsp.dataLength);
1406 reply_status = SLSI_HAL_NAN_STATUS_NO_RESOURCE_AVAILABLE;
1407 ret = -ENOMEM;
1408 goto exit;
1409 }
1410
1411 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
1412
1413 values = slsi_read_mibs(sdev, NULL, get_values, ARRAY_SIZE(get_values), &mibrsp);
1414 if (!values) {
1415 ret = 0xFFFFFFFF;
1416 reply_status = SLSI_HAL_NAN_STATUS_INTERNAL_FAILURE;
1417 goto exit_with_mibrsp;
1418 }
1419
1420 for (i = 0; i < (int)ARRAY_SIZE(get_values); i++) {
1421 if (values[i].type == SLSI_MIB_TYPE_UINT) {
1422 *capabilities_mib_val[i] = values[i].u.uintValue;
1423 SLSI_DBG2(sdev, SLSI_GSCAN, "MIB value = %ud\n", *capabilities_mib_val[i]);
1424 } else {
1425 SLSI_ERR(sdev, "invalid type(%d). iter:%d\n", values[i].type, i);
1426 ret = 0xFFFFFFFF;
1427 reply_status = SLSI_HAL_NAN_STATUS_INTERNAL_FAILURE;
1428 *capabilities_mib_val[i] = 0;
1429 }
1430 }
1431
1432 kfree(values);
1433 exit_with_mibrsp:
1434 kfree(mibrsp.data);
1435 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
1436 exit:
1437 slsi_vendor_nan_command_reply(wiphy, reply_status, ret, NAN_RESPONSE_GET_CAPABILITIES, 0, &nan_capabilities);
1438 return ret;
1439 }
1440
1441 void slsi_nan_event(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb)
1442 {
1443 struct sk_buff *nl_skb = NULL;
1444 int res = 0;
1445 u16 event, identifier, evt_reason;
1446 u8 *mac_addr;
1447 u16 hal_event;
1448 struct netdev_vif *ndev_vif;
1449 enum slsi_nan_disc_event_type disc_event_type = 0;
1450
1451 ndev_vif = netdev_priv(dev);
1452 event = fapi_get_u16(skb, u.mlme_nan_event_ind.event);
1453 identifier = fapi_get_u16(skb, u.mlme_nan_event_ind.identifier);
1454 mac_addr = fapi_get_buff(skb, u.mlme_nan_event_ind.address_or_identifier);
1455
1456 switch (fapi_get_u16(skb, u.mlme_nan_event_ind.reason_code)) {
1457 case FAPI_REASONCODE_NAN_SERVICE_TERMINATED_TIMEOUT:
1458 case FAPI_REASONCODE_NAN_SERVICE_TERMINATED_COUNT_REACHED:
1459 case FAPI_REASONCODE_NAN_SERVICE_TERMINATED_DISCOVERY_SHUTDOWN:
1460 case FAPI_REASONCODE_NAN_SERVICE_TERMINATED_USER_REQUEST:
1461 case FAPI_REASONCODE_NAN_TRANSMIT_FOLLOWUP_SUCCESS:
1462 evt_reason = SLSI_HAL_NAN_STATUS_SUCCESS;
1463 break;
1464 case FAPI_REASONCODE_NAN_TRANSMIT_FOLLOWUP_FAILURE:
1465 evt_reason = SLSI_HAL_NAN_STATUS_PROTOCOL_FAILURE;
1466 break;
1467 default:
1468 evt_reason = SLSI_HAL_NAN_STATUS_INTERNAL_FAILURE;
1469 break;
1470 }
1471
1472 switch (event) {
1473 case FAPI_EVENT_WIFI_EVENT_NAN_PUBLISH_TERMINATED:
1474 hal_event = SLSI_NL80211_NAN_PUBLISH_TERMINATED_EVENT;
1475 break;
1476 case FAPI_EVENT_WIFI_EVENT_NAN_MATCH_EXPIRED:
1477 hal_event = SLSI_NL80211_NAN_MATCH_EXPIRED_EVENT;
1478 break;
1479 case FAPI_EVENT_WIFI_EVENT_NAN_SUBSCRIBE_TERMINATED:
1480 hal_event = SLSI_NL80211_NAN_SUBSCRIBE_TERMINATED_EVENT;
1481 break;
1482 case FAPI_EVENT_WIFI_EVENT_NAN_ADDRESS_CHANGED:
1483 disc_event_type = NAN_EVENT_ID_DISC_MAC_ADDR;
1484 hal_event = SLSI_NL80211_NAN_DISCOVERY_ENGINE_EVENT;
1485 break;
1486 case FAPI_EVENT_WIFI_EVENT_NAN_CLUSTER_STARTED:
1487 disc_event_type = NAN_EVENT_ID_STARTED_CLUSTER;
1488 hal_event = SLSI_NL80211_NAN_DISCOVERY_ENGINE_EVENT;
1489 break;
1490 case FAPI_EVENT_WIFI_EVENT_NAN_CLUSTER_JOINED:
1491 disc_event_type = NAN_EVENT_ID_JOINED_CLUSTER;
1492 hal_event = SLSI_NL80211_NAN_DISCOVERY_ENGINE_EVENT;
1493 break;
1494 case FAPI_EVENT_WIFI_EVENT_NAN_TRANSMIT_FOLLOWUP:
1495 hal_event = SLSI_NL80211_NAN_TRANSMIT_FOLLOWUP_STATUS;
1496 break;
1497 default:
1498 return;
1499 }
1500
1501 #ifdef CONFIG_SCSC_WLAN_DEBUG
1502 SLSI_DBG1_NODEV(SLSI_GSCAN, "Event: %s(%d)\n",
1503 slsi_print_event_name(hal_event), hal_event);
1504 #endif
1505
1506 #if (KERNEL_VERSION(4, 1, 0) <= LINUX_VERSION_CODE)
1507 nl_skb = cfg80211_vendor_event_alloc(sdev->wiphy, NULL, NLMSG_DEFAULT_SIZE, hal_event, GFP_KERNEL);
1508 #else
1509 nl_skb = cfg80211_vendor_event_alloc(sdev->wiphy, NLMSG_DEFAULT_SIZE, hal_event, GFP_KERNEL);
1510 #endif
1511 if (!nl_skb) {
1512 SLSI_ERR(sdev, "NO MEM for nl_skb!!!\n");
1513 return;
1514 }
1515
1516 res |= nla_put_be16(nl_skb, NAN_EVT_ATTR_STATUS, evt_reason);
1517 switch (hal_event) {
1518 case SLSI_NL80211_NAN_PUBLISH_TERMINATED_EVENT:
1519 res |= nla_put_be16(nl_skb, NAN_EVT_ATTR_PUBLISH_ID, identifier);
1520 ndev_vif->nan.publish_id_map &= (u32)~BIT(identifier);
1521 break;
1522 case SLSI_NL80211_NAN_MATCH_EXPIRED_EVENT:
1523 res |= nla_put_be16(nl_skb, NAN_EVT_ATTR_MATCH_PUBLISH_SUBSCRIBE_ID, identifier);
1524 break;
1525 case SLSI_NL80211_NAN_SUBSCRIBE_TERMINATED_EVENT:
1526 res |= nla_put_be16(nl_skb, NAN_EVT_ATTR_SUBSCRIBE_ID, identifier);
1527 ndev_vif->nan.subscribe_id_map &= (u32)~BIT(identifier);
1528 break;
1529 case SLSI_NL80211_NAN_DISCOVERY_ENGINE_EVENT:
1530 res |= nla_put_be16(nl_skb, NAN_EVT_ATTR_DISCOVERY_ENGINE_EVT_TYPE, disc_event_type);
1531 res |= nla_put(nl_skb, NAN_EVT_ATTR_DISCOVERY_ENGINE_MAC_ADDR, ETH_ALEN, mac_addr);
1532 break;
1533 }
1534
1535 if (res) {
1536 SLSI_ERR(sdev, "Error in nla_put*:%x\n", res);
1537 /* Dont use slsi skb wrapper for this free */
1538 kfree_skb(nl_skb);
1539 return;
1540 }
1541
1542 cfg80211_vendor_event(nl_skb, GFP_KERNEL);
1543 }
1544
1545 void slsi_nan_followup_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb)
1546 {
1547 u16 tag_id, tag_len;
1548 u8 *ptr;
1549 struct slsi_hal_nan_followup_ind *hal_evt;
1550 struct sk_buff *nl_skb;
1551 int res;
1552 int sig_data_len;
1553
1554 SLSI_DBG3(sdev, SLSI_GSCAN, "\n");
1555
1556 sig_data_len = fapi_get_datalen(skb);
1557 if (sig_data_len <= 4) {
1558 SLSI_ERR(sdev, "Invalid data len(%d)\n", sig_data_len);
1559 return;
1560 }
1561
1562 hal_evt = kmalloc(sizeof(*hal_evt), GFP_KERNEL);
1563 if (!hal_evt) {
1564 SLSI_ERR(sdev, "No memory for followup_ind\n");
1565 return;
1566 }
1567 memset(hal_evt, 0, sizeof(*hal_evt));
1568
1569 hal_evt->publish_subscribe_id = fapi_get_u16(skb, u.mlme_nan_followup_ind.publish_subscribe_id);
1570 hal_evt->requestor_instance_id = fapi_get_u16(skb, u.mlme_nan_followup_ind.match_id);
1571 ether_addr_copy(hal_evt->addr,
1572 fapi_get_buff(skb, u.mlme_nan_followup_ind.peer_nan_management_interface_address));
1573
1574 ptr = fapi_get_data(skb);
1575 tag_id = le16_to_cpu(*(u16 *)ptr);
1576 tag_len = le16_to_cpu(*(u16 *)(ptr + 2));
1577
1578 while (sig_data_len >= tag_len + 4) {
1579 if (tag_id == SLSI_NAN_TLV_TAG_SERVICE_SPECIFIC_INFO) {
1580 hal_evt->service_specific_info_len = tag_len > SLSI_HAL_NAN_MAX_SERVICE_SPECIFIC_INFO_LEN ?
1581 SLSI_HAL_NAN_MAX_SERVICE_SPECIFIC_INFO_LEN : tag_len;
1582 memcpy(hal_evt->service_specific_info, ptr + 4, hal_evt->service_specific_info_len);
1583 } else if (tag_id == SLSI_NAN_TLV_TAG_EXT_SERVICE_SPECIFIC_INFO) {
1584 if (tag_len > SLSI_HAL_NAN_MAX_SDEA_SERVICE_SPEC_INFO_LEN)
1585 hal_evt->sdea_service_specific_info_len = SLSI_HAL_NAN_MAX_SDEA_SERVICE_SPEC_INFO_LEN;
1586 else
1587 hal_evt->sdea_service_specific_info_len = tag_len;
1588 memcpy(hal_evt->sdea_service_specific_info, ptr + 4, hal_evt->sdea_service_specific_info_len);
1589 } else {
1590 SLSI_WARN(sdev, "Skip processing TLV %d\n", tag_id);
1591 }
1592 sig_data_len -= tag_len + 4;
1593 ptr += tag_len + 4;
1594 if (sig_data_len > 4) {
1595 tag_id = le16_to_cpu(*(u16 *)ptr);
1596 tag_len = le16_to_cpu(*(u16 *)(ptr + 2));
1597 } else {
1598 tag_id = 0;
1599 tag_len = 0;
1600 }
1601 }
1602
1603 #ifdef CONFIG_SCSC_WLAN_DEBUG
1604 SLSI_DBG1_NODEV(SLSI_GSCAN, "Event: %s(%d)\n",
1605 slsi_print_event_name(SLSI_NL80211_NAN_FOLLOWUP_EVENT), SLSI_NL80211_NAN_FOLLOWUP_EVENT);
1606 #endif
1607 #if (KERNEL_VERSION(4, 1, 0) <= LINUX_VERSION_CODE)
1608 nl_skb = cfg80211_vendor_event_alloc(sdev->wiphy, NULL, NLMSG_DEFAULT_SIZE, SLSI_NL80211_NAN_FOLLOWUP_EVENT,
1609 GFP_KERNEL);
1610 #else
1611 nl_skb = cfg80211_vendor_event_alloc(sdev->wiphy, NLMSG_DEFAULT_SIZE, SLSI_NL80211_NAN_FOLLOWUP_EVENT,
1612 GFP_KERNEL);
1613 #endif
1614
1615 if (!nl_skb) {
1616 SLSI_ERR(sdev, "NO MEM for nl_skb!!!\n");
1617 kfree(hal_evt);
1618 return;
1619 }
1620
1621 res = nla_put_be16(nl_skb, NAN_EVT_ATTR_FOLLOWUP_PUBLISH_SUBSCRIBE_ID,
1622 cpu_to_le16(hal_evt->publish_subscribe_id));
1623 res |= nla_put_be16(nl_skb, NAN_EVT_ATTR_FOLLOWUP_REQUESTOR_INSTANCE_ID,
1624 cpu_to_le16(hal_evt->requestor_instance_id));
1625 res |= nla_put(nl_skb, NAN_EVT_ATTR_FOLLOWUP_ADDR, ETH_ALEN, hal_evt->addr);
1626 res |= nla_put_u8(nl_skb, NAN_EVT_ATTR_FOLLOWUP_DW_OR_FAW, hal_evt->dw_or_faw);
1627 res |= nla_put_u16(nl_skb, NAN_EVT_ATTR_FOLLOWUP_SERVICE_SPECIFIC_INFO_LEN, hal_evt->service_specific_info_len);
1628 if (hal_evt->service_specific_info_len)
1629 res |= nla_put(nl_skb, NAN_EVT_ATTR_FOLLOWUP_SERVICE_SPECIFIC_INFO, hal_evt->service_specific_info_len,
1630 hal_evt->service_specific_info);
1631 res |= nla_put_u16(nl_skb, NAN_EVT_ATTR_SDEA_LEN, hal_evt->sdea_service_specific_info_len);
1632 if (hal_evt->sdea_service_specific_info_len)
1633 res |= nla_put(nl_skb, NAN_EVT_ATTR_SDEA, hal_evt->sdea_service_specific_info_len,
1634 hal_evt->sdea_service_specific_info);
1635
1636 if (res) {
1637 SLSI_ERR(sdev, "Error in nla_put*:%x\n", res);
1638 kfree(hal_evt);
1639 /* Dont use slsi skb wrapper for this free */
1640 kfree_skb(nl_skb);
1641 return;
1642 }
1643
1644 cfg80211_vendor_event(nl_skb, GFP_KERNEL);
1645 kfree(hal_evt);
1646 }
1647
1648 void slsi_nan_service_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb)
1649 {
1650 u16 tag_id, tag_len;
1651 u8 *ptr;
1652 const u8 *tag_data_ptr;
1653 int sig_data_len;
1654 struct slsi_hal_nan_match_ind *hal_evt;
1655 struct sk_buff *nl_skb;
1656 int res;
1657
1658 SLSI_DBG3(sdev, SLSI_GSCAN, "\n");
1659
1660 sig_data_len = fapi_get_datalen(skb);
1661 if (sig_data_len <= 4) {
1662 SLSI_ERR(sdev, "Invalid data len(%d)\n", sig_data_len);
1663 return;
1664 }
1665
1666 hal_evt = kmalloc(sizeof(*hal_evt), GFP_KERNEL);
1667 if (!hal_evt) {
1668 SLSI_ERR(sdev, "No memory for service_ind\n");
1669 return;
1670 }
1671
1672 memset(hal_evt, 0, sizeof(*hal_evt));
1673 hal_evt->publish_subscribe_id = fapi_get_u16(skb, u.mlme_nan_service_ind.publish_subscribe_id);
1674 hal_evt->requestor_instance_id = fapi_get_u16(skb, u.mlme_nan_service_ind.match_id);
1675 hal_evt->ranging_event_type = fapi_get_u16(skb, u.mlme_nan_service_ind.rangingindicationtype);
1676 hal_evt->range_measurement_mm = 10 * fapi_get_u16(skb, u.mlme_nan_service_ind.ranging_measurement);
1677
1678 ptr = fapi_get_data(skb);
1679 tag_id = le16_to_cpu(*(u16 *)ptr);
1680 tag_len = le16_to_cpu(*(u16 *)(ptr + 2));
1681 tag_data_ptr = ptr + 4;
1682
1683 while (sig_data_len >= tag_len + 4) {
1684 switch (tag_id) {
1685 case SLSI_NAN_TLV_TAG_MATCH_IND:
1686 if (tag_len < 0x11) {
1687 SLSI_WARN(sdev, "Invalid taglen(%d) for SLSI_NAN_TLV_TAG_MATCH_IND\n", tag_len);
1688 break;
1689 }
1690 ether_addr_copy(hal_evt->addr, tag_data_ptr);
1691 tag_data_ptr += ETH_ALEN;
1692 hal_evt->match_occurred_flag = le16_to_cpu(*(u16 *)tag_data_ptr);
1693 tag_data_ptr += 2;
1694 hal_evt->out_of_resource_flag = le16_to_cpu(*(u16 *)tag_data_ptr);
1695 tag_data_ptr += 2;
1696 hal_evt->rssi_value = *tag_data_ptr;
1697 tag_data_ptr++;
1698 hal_evt->sec_info.cipher_type = *tag_data_ptr;
1699 break;
1700 case SLSI_NAN_TLV_TAG_SERVICE_SPECIFIC_INFO:
1701 hal_evt->service_specific_info_len = tag_len > SLSI_HAL_NAN_MAX_SERVICE_SPECIFIC_INFO_LEN ?
1702 SLSI_HAL_NAN_MAX_SERVICE_SPECIFIC_INFO_LEN : tag_len;
1703 memcpy(hal_evt->service_specific_info, tag_data_ptr, hal_evt->service_specific_info_len);
1704 break;
1705 case SLSI_NAN_TLV_TAG_EXT_SERVICE_SPECIFIC_INFO:
1706 if (tag_len > SLSI_HAL_NAN_MAX_SDEA_SERVICE_SPEC_INFO_LEN)
1707 hal_evt->sdea_service_specific_info_len = SLSI_HAL_NAN_MAX_SDEA_SERVICE_SPEC_INFO_LEN;
1708 else
1709 hal_evt->sdea_service_specific_info_len = tag_len;
1710 memcpy(hal_evt->sdea_service_specific_info, tag_data_ptr, hal_evt->sdea_service_specific_info_len);
1711 break;
1712 case SLSI_NAN_TLV_TAG_DATA_PATH_SECURITY:
1713 if (tag_len < 7) {
1714 SLSI_WARN(sdev, "Invalid taglen(%d) for SLSI_NAN_TLV_TAG_DATA_PATH_SECURITY\n", tag_len);
1715 break;
1716 }
1717 hal_evt->sec_info.key_info.key_type = *tag_data_ptr;
1718 tag_data_ptr++;
1719 hal_evt->sec_info.cipher_type = *tag_data_ptr;
1720 tag_data_ptr++;
1721 break;
1722 default:
1723 SLSI_WARN(sdev, "Skip processing TLV %d\n", tag_id);
1724 break;
1725 }
1726
1727 sig_data_len -= tag_len + 4;
1728 ptr += tag_len + 4;
1729 if (sig_data_len > 4) {
1730 tag_id = le16_to_cpu(*(u16 *)ptr);
1731 tag_len = le16_to_cpu(*(u16 *)(ptr + 2));
1732 } else {
1733 tag_id = 0;
1734 tag_len = 0;
1735 }
1736 }
1737
1738 #ifdef CONFIG_SCSC_WLAN_DEBUG
1739 SLSI_DBG1_NODEV(SLSI_GSCAN, "Event: %s(%d)\n",
1740 slsi_print_event_name(SLSI_NL80211_NAN_MATCH_EVENT), SLSI_NL80211_NAN_MATCH_EVENT);
1741 #endif
1742 #if (KERNEL_VERSION(4, 1, 0) <= LINUX_VERSION_CODE)
1743 nl_skb = cfg80211_vendor_event_alloc(sdev->wiphy, NULL, NLMSG_DEFAULT_SIZE, SLSI_NL80211_NAN_MATCH_EVENT,
1744 GFP_KERNEL);
1745 #else
1746 nl_skb = cfg80211_vendor_event_alloc(sdev->wiphy, NLMSG_DEFAULT_SIZE, SLSI_NL80211_NAN_MATCH_EVENT, GFP_KERNEL);
1747 #endif
1748 if (!nl_skb) {
1749 SLSI_ERR(sdev, "NO MEM for nl_skb!!!\n");
1750 kfree(hal_evt);
1751 return;
1752 }
1753 res = nla_put_u16(nl_skb, NAN_EVT_ATTR_MATCH_PUBLISH_SUBSCRIBE_ID, hal_evt->publish_subscribe_id);
1754 res |= nla_put_u32(nl_skb, NAN_EVT_ATTR_MATCH_REQUESTOR_INSTANCE_ID, hal_evt->requestor_instance_id);
1755 res |= nla_put(nl_skb, NAN_EVT_ATTR_MATCH_ADDR, ETH_ALEN, hal_evt->addr);
1756 res |= nla_put_u16(nl_skb, NAN_EVT_ATTR_MATCH_SERVICE_SPECIFIC_INFO_LEN, hal_evt->service_specific_info_len);
1757 if (hal_evt->service_specific_info_len)
1758 res |= nla_put(nl_skb, NAN_EVT_ATTR_MATCH_SERVICE_SPECIFIC_INFO, hal_evt->service_specific_info_len,
1759 hal_evt->service_specific_info);
1760 res |= nla_put_u16(nl_skb, NAN_EVT_ATTR_MATCH_SDF_MATCH_FILTER_LEN, hal_evt->sdf_match_filter_len);
1761 if (hal_evt->sdf_match_filter_len)
1762 res |= nla_put(nl_skb, NAN_EVT_ATTR_MATCH_SDF_MATCH_FILTER, hal_evt->sdf_match_filter_len,
1763 hal_evt->sdf_match_filter);
1764 res |= nla_put_u16(nl_skb, NAN_EVT_ATTR_SDEA_LEN, hal_evt->sdea_service_specific_info_len);
1765 if (hal_evt->sdea_service_specific_info_len)
1766 res |= nla_put(nl_skb, NAN_EVT_ATTR_SDEA, hal_evt->sdea_service_specific_info_len,
1767 hal_evt->sdea_service_specific_info);
1768
1769 res |= nla_put_u8(nl_skb, NAN_EVT_ATTR_MATCH_MATCH_OCCURRED_FLAG, hal_evt->match_occurred_flag);
1770 res |= nla_put_u8(nl_skb, NAN_EVT_ATTR_MATCH_OUT_OF_RESOURCE_FLAG, hal_evt->out_of_resource_flag);
1771 res |= nla_put_u8(nl_skb, NAN_EVT_ATTR_MATCH_RSSI_VALUE, hal_evt->rssi_value);
1772 res |= nla_put_u32(nl_skb, NAN_EVT_ATTR_RANGE_MEASUREMENT_MM, hal_evt->range_measurement_mm);
1773 res |= nla_put_u32(nl_skb, NAN_EVT_ATTR_RANGEING_EVENT_TYPE, hal_evt->ranging_event_type);
1774 res |= nla_put_u32(nl_skb, NAN_EVT_ATTR_SECURITY_CIPHER_TYPE, hal_evt->sec_info.cipher_type);
1775
1776 if (res) {
1777 SLSI_ERR(sdev, "Error in nla_put*:%x\n", res);
1778 /* Dont use slsi skb wrapper for this free */
1779 kfree_skb(nl_skb);
1780 kfree(hal_evt);
1781 return;
1782 }
1783
1784 cfg80211_vendor_event(nl_skb, GFP_KERNEL);
1785 kfree(hal_evt);
1786 }