blob: 27b6c0013cdf8f4d43e655bb6e1db9cd83cf236c [file] [log] [blame]
Jeff Johnson2b0a7b82016-05-18 15:08:02 -07001/*
2 * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
3 *
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 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
28/**
29 * DOC: wlan_hdd_lpass.c
30 *
31 * WLAN Host Device Driver LPASS feature implementation
32 *
33 */
34
35/* Include Files */
36#include "wlan_hdd_main.h"
37#include "wlan_hdd_lpass.h"
38#include <cds_utils.h>
39#include "qwlan_version.h"
40
41static int wlan_hdd_gen_wlan_status_pack(struct wlan_status_data *data,
42 hdd_adapter_t *adapter,
Jeff Johnsond9dd4842016-05-18 16:49:29 -070043 hdd_station_ctx_t *sta_ctx,
Jeff Johnson2b0a7b82016-05-18 15:08:02 -070044 uint8_t is_on, uint8_t is_connected)
45{
46 hdd_context_t *hdd_ctx = NULL;
47 uint8_t buflen = WLAN_SVC_COUNTRY_CODE_LEN;
48
49 if (!data) {
50 hddLog(LOGE, FL("invalid data pointer"));
51 return -EINVAL;
52 }
53 if (!adapter) {
54 if (is_on) {
55 /* no active interface */
56 data->lpss_support = 0;
57 data->is_on = is_on;
58 return 0;
59 }
60 hddLog(LOGE, FL("invalid adapter pointer"));
61 return -EINVAL;
62 }
63
64 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
65 if (hdd_ctx->lpss_support && hdd_ctx->config->enable_lpass_support)
66 data->lpss_support = 1;
67 else
68 data->lpss_support = 0;
69 data->numChannels = WLAN_SVC_MAX_NUM_CHAN;
70 sme_get_cfg_valid_channels(hdd_ctx->hHal, data->channel_list,
71 &data->numChannels);
72 sme_get_country_code(hdd_ctx->hHal, data->country_code, &buflen);
73 data->is_on = is_on;
74 data->vdev_id = adapter->sessionId;
75 data->vdev_mode = adapter->device_mode;
Jeff Johnsond9dd4842016-05-18 16:49:29 -070076 if (sta_ctx) {
Jeff Johnson2b0a7b82016-05-18 15:08:02 -070077 data->is_connected = is_connected;
78 data->rssi = adapter->rssi;
79 data->freq =
Jeff Johnsond9dd4842016-05-18 16:49:29 -070080 cds_chan_to_freq(sta_ctx->conn_info.operationChannel);
Jeff Johnson2b0a7b82016-05-18 15:08:02 -070081 if (WLAN_SVC_MAX_SSID_LEN >=
Jeff Johnsond9dd4842016-05-18 16:49:29 -070082 sta_ctx->conn_info.SSID.SSID.length) {
83 data->ssid_len = sta_ctx->conn_info.SSID.SSID.length;
Jeff Johnson2b0a7b82016-05-18 15:08:02 -070084 memcpy(data->ssid,
Jeff Johnsond9dd4842016-05-18 16:49:29 -070085 sta_ctx->conn_info.SSID.SSID.ssId,
86 sta_ctx->conn_info.SSID.SSID.length);
Jeff Johnson2b0a7b82016-05-18 15:08:02 -070087 }
Jeff Johnsond9dd4842016-05-18 16:49:29 -070088 if (QDF_MAC_ADDR_SIZE >= sizeof(sta_ctx->conn_info.bssId))
89 memcpy(data->bssid, sta_ctx->conn_info.bssId.bytes,
Jeff Johnson2b0a7b82016-05-18 15:08:02 -070090 QDF_MAC_ADDR_SIZE);
91 }
92 return 0;
93}
94
95static int wlan_hdd_gen_wlan_version_pack(struct wlan_version_data *data,
96 uint32_t fw_version,
97 uint32_t chip_id,
98 const char *chip_name)
99{
100 if (!data) {
101 hddLog(LOGE, FL("invalid data pointer"));
102 return -EINVAL;
103 }
104
105 data->chip_id = chip_id;
106 strlcpy(data->chip_name, chip_name, WLAN_SVC_MAX_STR_LEN);
107 if (strncmp(chip_name, "Unknown", 7))
108 strlcpy(data->chip_from, "Qualcomm", WLAN_SVC_MAX_STR_LEN);
109 else
110 strlcpy(data->chip_from, "Unknown", WLAN_SVC_MAX_STR_LEN);
111 strlcpy(data->host_version, QWLAN_VERSIONSTR, WLAN_SVC_MAX_STR_LEN);
112 scnprintf(data->fw_version, WLAN_SVC_MAX_STR_LEN, "%d.%d.%d.%d",
113 (fw_version & 0xf0000000) >> 28,
114 (fw_version & 0xf000000) >> 24,
115 (fw_version & 0xf00000) >> 20, (fw_version & 0x7fff));
116 return 0;
117}
118
119void wlan_hdd_send_status_pkg(hdd_adapter_t *adapter,
Jeff Johnsond9dd4842016-05-18 16:49:29 -0700120 hdd_station_ctx_t *sta_ctx,
Jeff Johnson2b0a7b82016-05-18 15:08:02 -0700121 uint8_t is_on, uint8_t is_connected)
122{
123 int ret = 0;
124 struct wlan_status_data data;
125
126 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
127 return;
128
129 memset(&data, 0, sizeof(struct wlan_status_data));
130 if (is_on)
Jeff Johnsond9dd4842016-05-18 16:49:29 -0700131 ret = wlan_hdd_gen_wlan_status_pack(&data, adapter, sta_ctx,
Jeff Johnson2b0a7b82016-05-18 15:08:02 -0700132 is_on, is_connected);
133 if (!ret)
134 wlan_hdd_send_svc_nlink_msg(WLAN_SVC_WLAN_STATUS_IND,
Jeff Johnsond9dd4842016-05-18 16:49:29 -0700135 &data, sizeof(data));
Jeff Johnson2b0a7b82016-05-18 15:08:02 -0700136}
137
138void wlan_hdd_send_version_pkg(uint32_t fw_version,
139 uint32_t chip_id, const char *chip_name)
140{
141 int ret = 0;
142 struct wlan_version_data data;
143
144 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
145 return;
146
147 memset(&data, 0, sizeof(struct wlan_version_data));
Jeff Johnsond9dd4842016-05-18 16:49:29 -0700148 ret = wlan_hdd_gen_wlan_version_pack(&data, fw_version, chip_id,
149 chip_name);
Jeff Johnson2b0a7b82016-05-18 15:08:02 -0700150 if (!ret)
151 wlan_hdd_send_svc_nlink_msg(WLAN_SVC_WLAN_VERSION_IND,
Jeff Johnsond9dd4842016-05-18 16:49:29 -0700152 &data, sizeof(data));
Jeff Johnson2b0a7b82016-05-18 15:08:02 -0700153}
154
155void wlan_hdd_send_all_scan_intf_info(hdd_context_t *hdd_ctx)
156{
Jeff Johnsond9dd4842016-05-18 16:49:29 -0700157 hdd_adapter_t *adapter = NULL;
158 hdd_adapter_list_node_t *node = NULL, *next = NULL;
Jeff Johnson2b0a7b82016-05-18 15:08:02 -0700159 bool scan_intf_found = false;
160 QDF_STATUS status;
161
162 if (!hdd_ctx) {
163 hddLog(QDF_TRACE_LEVEL_ERROR,
164 FL("NULL pointer for hdd_ctx"));
165 return;
166 }
167
Jeff Johnsond9dd4842016-05-18 16:49:29 -0700168 status = hdd_get_front_adapter(hdd_ctx, &node);
169 while (NULL != node && QDF_STATUS_SUCCESS == status) {
170 adapter = node->pAdapter;
171 if (adapter) {
172 if (adapter->device_mode == QDF_STA_MODE
173 || adapter->device_mode == QDF_P2P_CLIENT_MODE
174 || adapter->device_mode ==
Jeff Johnson2b0a7b82016-05-18 15:08:02 -0700175 QDF_P2P_DEVICE_MODE) {
176 scan_intf_found = true;
Jeff Johnsond9dd4842016-05-18 16:49:29 -0700177 wlan_hdd_send_status_pkg(adapter, NULL, 1, 0);
Jeff Johnson2b0a7b82016-05-18 15:08:02 -0700178 }
179 }
Jeff Johnsond9dd4842016-05-18 16:49:29 -0700180 status = hdd_get_next_adapter(hdd_ctx, node, &next);
181 node = next;
Jeff Johnson2b0a7b82016-05-18 15:08:02 -0700182 }
183
184 if (!scan_intf_found)
Jeff Johnsond9dd4842016-05-18 16:49:29 -0700185 wlan_hdd_send_status_pkg(adapter, NULL, 1, 0);
Jeff Johnson2b0a7b82016-05-18 15:08:02 -0700186}