blob: d2c0cdfd5da14c6ee38fb86b5ffe0fcc12457b7b [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Sandeep Puligillafdd201e2017-02-02 18:43:46 -08002 * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/**
23 * DOC: wlan_hdd_nan.c
24 *
25 * WLAN Host Device Driver NAN API implementation
26 */
27
28#include <linux/version.h>
29#include <linux/module.h>
30#include <linux/kernel.h>
31#include <net/cfg80211.h>
32#include <ani_global.h>
33#include "sme_api.h"
34#include "nan_api.h"
35#include "wlan_hdd_main.h"
36#include "wlan_hdd_nan.h"
Sandeep Puligillafdd201e2017-02-02 18:43:46 -080037#include <qca_vendor.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080038
39/**
40 * __wlan_hdd_cfg80211_nan_request() - cfg80211 NAN request handler
41 * @wiphy: driver's wiphy struct
42 * @wdev: wireless device to which the request is targeted
43 * @data: actual request data (netlink-encapsulated)
44 * @data_len: length of @data
45 *
46 * This is called when userspace needs to send a nan request to
47 * firmware. The wlan host driver simply de-encapsulates the
48 * request from the netlink payload and then forwards it to
49 * firmware via SME.
50 *
51 * Return: 0 on success, negative errno on failure
52 */
53static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
54 struct wireless_dev *wdev,
55 const void *data,
56 int data_len)
57{
58 tNanRequestReq nan_req;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053059 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080060 int ret_val;
Jeff Johnsonf049e742017-08-28 11:52:28 -070061 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080062
Jeff Johnson1f61b612016-02-12 16:28:33 -080063 ENTER_DEV(wdev->netdev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080064
65 ret_val = wlan_hdd_validate_context(hdd_ctx);
66 if (ret_val)
67 return ret_val;
68
Anurag Chouhan6d760662016-02-20 16:05:43 +053069 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080070 hdd_err("Command not allowed in FTM mode");
71 return -EPERM;
72 }
73
74 if (!hdd_ctx->config->enable_nan_support) {
75 hdd_err("NaN support is not enabled in INI");
76 return -EPERM;
77 }
78
79 nan_req.request_data_len = data_len;
80 nan_req.request_data = data;
81
82 status = sme_nan_request(&nan_req);
Srinivas Girigowda08e66362017-03-24 23:15:15 -070083 if (QDF_STATUS_SUCCESS != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080084 ret_val = -EINVAL;
Srinivas Girigowda08e66362017-03-24 23:15:15 -070085
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080086 return ret_val;
87}
88
89/**
90 * wlan_hdd_cfg80211_nan_request() - handle NAN request
91 * @wiphy: pointer to wireless wiphy structure.
92 * @wdev: pointer to wireless_dev structure.
93 * @data: Pointer to the data to be passed via vendor interface
94 * @data_len:Length of the data to be passed
95 *
96 * This function is called by userspace to send a NAN request to
97 * firmware. This is an SSR-protected wrapper function.
98 *
99 * Return: 0 on success, negative errno on failure
100 */
101int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
102 struct wireless_dev *wdev,
103 const void *data,
104 int data_len)
105
106{
107 int ret;
108
109 cds_ssr_protect(__func__);
110 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
111 cds_ssr_unprotect(__func__);
112
113 return ret;
114}
115
116/**
117 * wlan_hdd_cfg80211_nan_callback() - cfg80211 NAN event handler
118 * @ctx: global HDD context
119 * @msg: NAN event message
120 *
121 * This is a callback function and it gets called when we need to report
122 * a nan event to userspace. The wlan host driver simply encapsulates the
123 * event into a netlink payload and then forwards it to userspace via a
124 * cfg80211 vendor event.
125 *
126 * Return: nothing
127 */
Arun Khandavalli4b55da72016-07-19 19:55:01 +0530128void wlan_hdd_cfg80211_nan_callback(void *ctx, tSirNanEvent *msg)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800129{
Jeff Johnsonf049e742017-08-28 11:52:28 -0700130 struct hdd_context *hdd_ctx = ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800131 struct sk_buff *vendor_event;
132 int status;
133
134 if (NULL == msg) {
Jeff Johnson1aa29092016-01-11 15:24:59 -0800135 hdd_err("msg received here is null");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800136 return;
137 }
138
139 status = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +0530140 if (status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800141 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800142
143 vendor_event =
144 cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
145 NULL,
146 msg->event_data_len + NLMSG_HDRLEN,
147 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
148 GFP_KERNEL);
149
150 if (!vendor_event) {
Jeff Johnson1aa29092016-01-11 15:24:59 -0800151 hdd_err("cfg80211_vendor_event_alloc failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800152 return;
153 }
154 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
155 msg->event_data_len, msg->event_data)) {
Jeff Johnson1aa29092016-01-11 15:24:59 -0800156 hdd_err("QCA_WLAN_VENDOR_ATTR_NAN put fail");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800157 kfree_skb(vendor_event);
158 return;
159 }
160 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
161}
162
163/**
164 * wlan_hdd_nan_is_supported() - HDD NAN support query function
165 *
166 * This function is called to determine if NAN is supported by the
167 * driver and by the firmware.
168 *
169 * Return: true if NAN is supported by the driver and firmware
170 */
171bool wlan_hdd_nan_is_supported(void)
172{
173 return sme_is_feature_supported_by_fw(NAN);
174}