1  /*
2   * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
3   * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
4   *
5   * Permission to use, copy, modify, and/or distribute this software for
6   * any purpose with or without fee is hereby granted, provided that the
7   * above copyright notice and this permission notice appear in all
8   * copies.
9   *
10   * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11   * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12   * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13   * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14   * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15   * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16   * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17   * PERFORMANCE OF THIS SOFTWARE.
18   */
19  
20  /**
21   * DOC: wlan_hdd_station_info.c
22   *
23   * WLAN station info functions
24   *
25   */
26  
27  #include "osif_sync.h"
28  #include <wlan_hdd_includes.h>
29  #include <linux/netdevice.h>
30  #include <linux/skbuff.h>
31  #include <linux/etherdevice.h>
32  #include <linux/if_ether.h>
33  #include <wlan_cfg80211_mc_cp_stats.h>
34  #include <wlan_cp_stats_mc_ucfg_api.h>
35  #include <wlan_hdd_stats.h>
36  #include <wlan_hdd_hostapd.h>
37  #include <wlan_hdd_station_info.h>
38  #include "wlan_mlme_ucfg_api.h"
39  #include "wlan_hdd_sta_info.h"
40  #include "wlan_hdd_object_manager.h"
41  #include "wlan_ipa_ucfg_api.h"
42  
43  #include <cdp_txrx_handle.h>
44  #include <cdp_txrx_stats_struct.h>
45  #include <cdp_txrx_peer_ops.h>
46  #include <cdp_txrx_host_stats.h>
47  #include <osif_cm_util.h>
48  
49  #include "wlan_hdd_stats.h"
50  
51  /*
52   * define short names for the global vendor params
53   * used by __wlan_hdd_cfg80211_get_station_cmd()
54   */
55  #define STATION_INVALID \
56  	QCA_WLAN_VENDOR_ATTR_GET_STATION_INVALID
57  #define STATION_INFO \
58  	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO
59  #define STATION_ASSOC_FAIL_REASON \
60  	QCA_WLAN_VENDOR_ATTR_GET_STATION_ASSOC_FAIL_REASON
61  #define STATION_REMOTE \
62  	QCA_WLAN_VENDOR_ATTR_GET_STATION_REMOTE
63  #define STATION_MAX \
64  	QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX
65  
66  #define STA_INFO_INVALID \
67  	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_INVALID
68  #define STA_INFO_BIP_MIC_ERROR_COUNT \
69  	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BIP_MIC_ERROR_COUNT
70  #define STA_INFO_BIP_REPLAY_COUNT \
71  	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BIP_REPLAY_COUNT
72  #define STA_INFO_BEACON_MIC_ERROR_COUNT \
73  	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT
74  #define STA_INFO_BEACON_REPLAY_COUNT \
75  	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT
76  #define STA_INFO_CONNECT_FAIL_REASON_CODE \
77  	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_CONNECT_FAIL_REASON_CODE
78  #define STA_INFO_MAX \
79  	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX
80  
81  /* define short names for get station info attributes */
82  #define LINK_INFO_STANDARD_NL80211_ATTR \
83  	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_LINK_STANDARD_NL80211_ATTR
84  #define AP_INFO_STANDARD_NL80211_ATTR \
85  	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AP_STANDARD_NL80211_ATTR
86  #define INFO_ROAM_COUNT \
87  	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_ROAM_COUNT
88  #define INFO_AKM \
89  	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AKM
90  #define WLAN802_11_MODE \
91  	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_802_11_MODE
92  #define AP_INFO_HS20_INDICATION \
93  	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AP_HS20_INDICATION
94  #define HT_OPERATION \
95  	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_HT_OPERATION
96  #define VHT_OPERATION \
97  	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_VHT_OPERATION
98  #define HE_OPERATION \
99  	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_HE_OPERATION
100  #define INFO_ASSOC_FAIL_REASON \
101  	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_ASSOC_FAIL_REASON
102  #define REMOTE_MAX_PHY_RATE \
103  	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_MAX_PHY_RATE
104  #define REMOTE_TX_PACKETS \
105  	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_TX_PACKETS
106  #define REMOTE_TX_BYTES \
107  	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_TX_BYTES
108  #define REMOTE_RX_PACKETS \
109  	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_PACKETS
110  #define REMOTE_RX_BYTES \
111  	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_BYTES
112  #define REMOTE_LAST_TX_RATE \
113  	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_LAST_TX_RATE
114  #define REMOTE_LAST_RX_RATE \
115  	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_LAST_RX_RATE
116  #define REMOTE_WMM \
117  	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_WMM
118  #define REMOTE_SUPPORTED_MODE \
119  	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_SUPPORTED_MODE
120  #define REMOTE_AMPDU \
121  	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_AMPDU
122  #define REMOTE_TX_STBC \
123  	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_TX_STBC
124  #define REMOTE_RX_STBC \
125  	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_STBC
126  #define REMOTE_CH_WIDTH\
127  	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_CH_WIDTH
128  #define REMOTE_SGI_ENABLE\
129  	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_SGI_ENABLE
130  #define REMOTE_PAD\
131  	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_PAD
132  #define REMOTE_RX_RETRY_COUNT \
133  	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_RETRY_COUNT
134  #define REMOTE_RX_BC_MC_COUNT \
135  	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_BC_MC_COUNT
136  #define DISCONNECT_REASON \
137  	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_DRIVER_DISCONNECT_REASON
138  #define BEACON_IES \
139  	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_BEACON_IES
140  #define ASSOC_REQ_IES \
141  	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_ASSOC_REQ_IES
142  #define REMOTE_CH_WIDTH_V2\
143  	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_CH_WIDTH_V2
144  #define EHT_OPERATION \
145  	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_EHT_OPERATION
146  
147  /*
148   * MSB of rx_mc_bc_cnt indicates whether FW supports rx_mc_bc_cnt
149   * feature or not, if first bit is 1 it indicates that FW supports this
150   * feature, if it is 0 it indicates FW doesn't support this feature
151   */
152  #define HDD_STATION_INFO_RX_MC_BC_COUNT (1 << 31)
153  
154  /*
155   * Use this macro to check channel bandwidth 160MHZ
156   */
157  #define MAX_CHANNEL_BW_160 160
158  
159  const struct nla_policy
160  hdd_get_station_policy[STATION_MAX + 1] = {
161  	[STATION_INFO] = {.type = NLA_FLAG},
162  	[STATION_ASSOC_FAIL_REASON] = {.type = NLA_FLAG},
163  	[STATION_REMOTE] = {.type = NLA_BINARY, .len = QDF_MAC_ADDR_SIZE},
164  };
165  
166  const struct nla_policy
167  hdd_get_sta_policy[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX + 1] = {
168  	[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAC] = {.type = NLA_BINARY,
169  						   .len = QDF_MAC_ADDR_SIZE},
170  };
171  
hdd_get_sta_congestion(struct wlan_hdd_link_info * link_info,uint32_t * congestion)172  static int hdd_get_sta_congestion(struct wlan_hdd_link_info *link_info,
173  				  uint32_t *congestion)
174  {
175  	QDF_STATUS status;
176  	struct cca_stats cca_stats;
177  	struct wlan_objmgr_vdev *vdev;
178  
179  	vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_STATS_ID);
180  	if (!vdev) {
181  		hdd_err("vdev is NULL");
182  		return -EINVAL;
183  	}
184  
185  	status = ucfg_mc_cp_stats_cca_stats_get(vdev, &cca_stats);
186  	hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_STATS_ID);
187  	if (QDF_IS_STATUS_ERROR(status))
188  		return -EINVAL;
189  
190  	*congestion = cca_stats.congestion;
191  	return 0;
192  }
193  
194  /**
195   * hdd_get_station_assoc_fail() - Handle get station assoc fail
196   * @link_info: Link info pointer in HDD adaper
197   *
198   * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION_ASSOC_FAIL.
199   * Validate cmd attributes and send the station info to upper layers.
200   *
201   * Return: Success(0) or reason code for failure
202   */
hdd_get_station_assoc_fail(struct wlan_hdd_link_info * link_info)203  static int hdd_get_station_assoc_fail(struct wlan_hdd_link_info *link_info)
204  {
205  	struct sk_buff *skb = NULL;
206  	uint32_t nl_buf_len;
207  	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(link_info->adapter);
208  	struct hdd_station_ctx *hdd_sta_ctx;
209  	uint32_t congestion;
210  
211  	nl_buf_len = NLMSG_HDRLEN;
212  	nl_buf_len += sizeof(uint32_t);
213  	skb = wlan_cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy,
214  						       nl_buf_len);
215  	if (!skb) {
216  		hdd_err("wlan_cfg80211_vendor_cmd_alloc_reply_skb failed");
217  		return -ENOMEM;
218  	}
219  	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
220  
221  	if (nla_put_u32(skb, INFO_ASSOC_FAIL_REASON,
222  			hdd_sta_ctx->conn_info.assoc_status_code)) {
223  		hdd_err("put fail");
224  		goto fail;
225  	}
226  
227  	if (hdd_get_sta_congestion(link_info, &congestion))
228  		congestion = 0;
229  
230  	hdd_info("congestion:%d", congestion);
231  	if (nla_put_u32(skb, NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY,
232  			congestion)) {
233  		hdd_err("put fail");
234  		goto fail;
235  	}
236  
237  	return wlan_cfg80211_vendor_cmd_reply(skb);
238  fail:
239  	wlan_cfg80211_vendor_free_skb(skb);
240  	return -EINVAL;
241  }
242  
243  /**
244   * hdd_convert_auth_type() - transform auth type specific to
245   * vendor command
246   * @auth_type: csr auth type
247   *
248   * Return: vendor command auth type
249   */
hdd_convert_auth_type(uint32_t auth_type)250  static int hdd_convert_auth_type(uint32_t auth_type)
251  {
252  	uint32_t ret_val;
253  
254  	switch (auth_type) {
255  	case eCSR_AUTH_TYPE_OPEN_SYSTEM:
256  		ret_val = QCA_WLAN_AUTH_TYPE_OPEN;
257  		break;
258  	case eCSR_AUTH_TYPE_SHARED_KEY:
259  		ret_val = QCA_WLAN_AUTH_TYPE_SHARED;
260  		break;
261  	case eCSR_AUTH_TYPE_WPA:
262  		ret_val = QCA_WLAN_AUTH_TYPE_WPA;
263  		break;
264  	case eCSR_AUTH_TYPE_WPA_PSK:
265  		ret_val = QCA_WLAN_AUTH_TYPE_WPA_PSK;
266  		break;
267  	case eCSR_AUTH_TYPE_AUTOSWITCH:
268  		ret_val = QCA_WLAN_AUTH_TYPE_AUTOSWITCH;
269  		break;
270  	case eCSR_AUTH_TYPE_WPA_NONE:
271  		ret_val = QCA_WLAN_AUTH_TYPE_WPA_NONE;
272  		break;
273  	case eCSR_AUTH_TYPE_RSN:
274  		ret_val = QCA_WLAN_AUTH_TYPE_RSN;
275  		break;
276  	case eCSR_AUTH_TYPE_RSN_PSK:
277  		ret_val = QCA_WLAN_AUTH_TYPE_RSN_PSK;
278  		break;
279  	case eCSR_AUTH_TYPE_FT_RSN:
280  		ret_val = QCA_WLAN_AUTH_TYPE_FT;
281  		break;
282  	case eCSR_AUTH_TYPE_FT_RSN_PSK:
283  		ret_val = QCA_WLAN_AUTH_TYPE_FT_PSK;
284  		break;
285  	case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
286  		ret_val = QCA_WLAN_AUTH_TYPE_WAI;
287  		break;
288  	case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
289  		ret_val = QCA_WLAN_AUTH_TYPE_WAI_PSK;
290  		break;
291  	case eCSR_AUTH_TYPE_CCKM_WPA:
292  		ret_val = QCA_WLAN_AUTH_TYPE_CCKM_WPA;
293  		break;
294  	case eCSR_AUTH_TYPE_CCKM_RSN:
295  		ret_val = QCA_WLAN_AUTH_TYPE_CCKM_RSN;
296  		break;
297  	case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
298  		ret_val = QCA_WLAN_AUTH_TYPE_SHA256_PSK;
299  		break;
300  	case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
301  		ret_val = QCA_WLAN_AUTH_TYPE_SHA256;
302  		break;
303  	case eCSR_AUTH_TYPE_FT_SAE:
304  		ret_val = QCA_WLAN_AUTH_TYPE_FT_SAE;
305  		break;
306  	case eCSR_AUTH_TYPE_FT_SUITEB_EAP_SHA384:
307  		ret_val = QCA_WLAN_AUTH_TYPE_FT_SUITEB_EAP_SHA384;
308  		break;
309  	case eCSR_AUTH_TYPE_SAE:
310  		ret_val = QCA_WLAN_AUTH_TYPE_SAE;
311  		break;
312  	case eCSR_AUTH_TYPE_FILS_SHA256:
313  		ret_val = QCA_WLAN_AUTH_TYPE_FILS_SHA256;
314  		break;
315  	case eCSR_AUTH_TYPE_FILS_SHA384:
316  		ret_val = QCA_WLAN_AUTH_TYPE_FILS_SHA384;
317  		break;
318  	case eCSR_AUTH_TYPE_FT_FILS_SHA256:
319  		ret_val = QCA_WLAN_AUTH_TYPE_FT_FILS_SHA256;
320  		break;
321  	case eCSR_AUTH_TYPE_FT_FILS_SHA384:
322  		ret_val = QCA_WLAN_AUTH_TYPE_FT_FILS_SHA384;
323  		break;
324  	case eCSR_AUTH_TYPE_DPP_RSN:
325  		ret_val = QCA_WLAN_AUTH_TYPE_DPP_RSN;
326  		break;
327  	case eCSR_AUTH_TYPE_OWE:
328  		ret_val = QCA_WLAN_AUTH_TYPE_OWE;
329  		break;
330  	case eCSR_AUTH_TYPE_SUITEB_EAP_SHA256:
331  		ret_val = QCA_WLAN_AUTH_TYPE_SUITEB_EAP_SHA256;
332  		break;
333  	case eCSR_AUTH_TYPE_SUITEB_EAP_SHA384:
334  		ret_val = QCA_WLAN_AUTH_TYPE_SUITEB_EAP_SHA384;
335  		break;
336  	case eCSR_NUM_OF_SUPPORT_AUTH_TYPE:
337  	case eCSR_AUTH_TYPE_FAILED:
338  	case eCSR_AUTH_TYPE_NONE:
339  	default:
340  		ret_val = QCA_WLAN_AUTH_TYPE_INVALID;
341  		break;
342  	}
343  	return ret_val;
344  }
345  
346  /**
347   * hdd_convert_dot11mode() - transform dot11mode type specific to
348   * vendor command
349   * @dot11mode: CSR dot11 mode
350   *
351   * Return: vendor command dot11 mode
352   */
hdd_convert_dot11mode(uint32_t dot11mode)353  static int hdd_convert_dot11mode(uint32_t dot11mode)
354  {
355  	uint32_t ret_val;
356  
357  	switch (dot11mode) {
358  	case eCSR_CFG_DOT11_MODE_11A:
359  		ret_val = QCA_WLAN_802_11_MODE_11A;
360  		break;
361  	case eCSR_CFG_DOT11_MODE_11B:
362  		ret_val = QCA_WLAN_802_11_MODE_11B;
363  		break;
364  	case eCSR_CFG_DOT11_MODE_11G:
365  		ret_val = QCA_WLAN_802_11_MODE_11G;
366  		break;
367  	case eCSR_CFG_DOT11_MODE_11N:
368  		ret_val = QCA_WLAN_802_11_MODE_11N;
369  		break;
370  	case eCSR_CFG_DOT11_MODE_11AC:
371  		ret_val = QCA_WLAN_802_11_MODE_11AC;
372  		break;
373  	case eCSR_CFG_DOT11_MODE_11AX:
374  		ret_val = QCA_WLAN_802_11_MODE_11AX;
375  		break;
376  	case eCSR_CFG_DOT11_MODE_11BE:
377  		ret_val = QCA_WLAN_802_11_MODE_11BE;
378  		break;
379  	case eCSR_CFG_DOT11_MODE_AUTO:
380  	case eCSR_CFG_DOT11_MODE_ABG:
381  	default:
382  		ret_val = QCA_WLAN_802_11_MODE_INVALID;
383  	}
384  	return ret_val;
385  }
386  
387  /**
388   * hdd_calculate_tx_bitrate_ie_size - calculate tx bitrate ie size
389   *
390   * Return: tx bitrate ie size
391   */
hdd_calculate_tx_bitrate_ie_size(void)392  static uint32_t hdd_calculate_tx_bitrate_ie_size(void)
393  {
394  	uint32_t nl_buf_len = nla_total_size(0);
395  
396  		/* NL80211_RATE_INFO_BITRATE32 */
397  	nl_buf_len +=  nla_total_size(sizeof(uint32_t)) +
398  		/* NL80211_RATE_INFO_BITRATE */
399  		nla_total_size(sizeof(uint16_t)) +
400  		/* NL80211_RATE_INFO_VHT_NSS */
401  		nla_total_size(sizeof(uint8_t));
402  
403  	return nl_buf_len;
404  }
405  
406  /**
407   * hdd_add_tx_bitrate() - add tx bitrate attribute
408   * @skb: pointer to sk buff
409   * @link_info: Link info pointer in HDD adapter
410   * @idx: attribute index
411   *
412   * Return: Success(0) or reason code for failure
413   */
hdd_add_tx_bitrate(struct sk_buff * skb,struct wlan_hdd_link_info * link_info,int idx)414  static int32_t hdd_add_tx_bitrate(struct sk_buff *skb,
415  				  struct wlan_hdd_link_info *link_info, int idx)
416  {
417  	struct nlattr *nla_attr;
418  	uint32_t bitrate, bitrate_compat;
419  	struct hdd_station_ctx *sta_ctx;
420  
421  	nla_attr = nla_nest_start(skb, idx);
422  	if (!nla_attr) {
423  		hdd_err("nla_nest_start failed");
424  		goto fail;
425  	}
426  
427  	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
428  
429  	/* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
430  	if (hdd_cm_is_vdev_associated(link_info))
431  		bitrate = cfg80211_calculate_bitrate(
432  				&sta_ctx->cache_conn_info.max_tx_bitrate);
433  	else
434  		bitrate = cfg80211_calculate_bitrate(
435  					&sta_ctx->cache_conn_info.txrate);
436  	/* report 16-bit bitrate only if we can */
437  	bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
438  
439  	if (bitrate > 0) {
440  		if (nla_put_u32(skb, NL80211_RATE_INFO_BITRATE32, bitrate)) {
441  			hdd_err("put fail bitrate: %u", bitrate);
442  			goto fail;
443  		}
444  	} else {
445  		hdd_err("Invalid bitrate: %u", bitrate);
446  	}
447  
448  	if (bitrate_compat > 0) {
449  		if (nla_put_u16(skb, NL80211_RATE_INFO_BITRATE,
450  				bitrate_compat)) {
451  			hdd_err("put fail bitrate_compat: %u", bitrate_compat);
452  			goto fail;
453  		}
454  	} else {
455  		hdd_err("Invalid bitrate_compat: %u", bitrate_compat);
456  	}
457  
458  	if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
459  		      sta_ctx->cache_conn_info.txrate.nss)) {
460  		hdd_err("put fail");
461  		goto fail;
462  	}
463  	nla_nest_end(skb, nla_attr);
464  
465  	hdd_nofl_debug(
466  		"STA Tx rate info:: bitrate:%d, bitrate_compat:%d, NSS:%d",
467  		bitrate, bitrate_compat,
468  		sta_ctx->cache_conn_info.txrate.nss);
469  
470  	return 0;
471  fail:
472  	return -EINVAL;
473  }
474  
475  /**
476   * hdd_calculate_sta_info_ie_size - calculate sta info size
477   *
478   * Return: sta info ie size
479   */
hdd_calculate_sta_info_ie_size(void)480  static uint32_t hdd_calculate_sta_info_ie_size(void)
481  {
482  	uint32_t nl_buf_len = nla_total_size(0);
483  
484  		/* NL80211_STA_INFO_SIGNAL */
485  	nl_buf_len += nla_total_size(sizeof(int8_t)) +
486  		hdd_calculate_tx_bitrate_ie_size();
487  
488  	return nl_buf_len;
489  }
490  
491  /**
492   * hdd_add_sta_info() - add station info attribute
493   * @skb: pointer to sk buff
494   * @link_info: Link info pointer in HDD adapter
495   * @idx: attribute index
496   *
497   * Return: Success(0) or reason code for failure
498   */
hdd_add_sta_info(struct sk_buff * skb,struct wlan_hdd_link_info * link_info,int idx)499  static int32_t hdd_add_sta_info(struct sk_buff *skb,
500  				struct wlan_hdd_link_info *link_info, int idx)
501  {
502  	struct nlattr *nla_attr;
503  	struct hdd_station_ctx *hdd_sta_ctx;
504  
505  	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
506  
507  	nla_attr = nla_nest_start(skb, idx);
508  	if (!nla_attr) {
509  		hdd_err("nla_nest_start failed");
510  		goto fail;
511  	}
512  
513  	if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL,
514  		       (hdd_sta_ctx->cache_conn_info.signal + 100))) {
515  		hdd_err("put fail");
516  		goto fail;
517  	}
518  
519  	if (hdd_cm_is_vdev_associated(link_info))
520  		hdd_get_max_tx_bitrate(link_info);
521  
522  	if (hdd_add_tx_bitrate(skb, link_info, NL80211_STA_INFO_TX_BITRATE)) {
523  		hdd_err("hdd_add_tx_bitrate failed");
524  		goto fail;
525  	}
526  
527  	nla_nest_end(skb, nla_attr);
528  	return 0;
529  fail:
530  	return -EINVAL;
531  }
532  
533  /**
534   * hdd_calculate_survey_info_ie_size - calculate survey info size
535   *
536   * Return: survey info ie size
537   */
hdd_calculate_survey_info_ie_size(void)538  static uint32_t hdd_calculate_survey_info_ie_size(void)
539  {
540  	uint32_t nl_buf_len = nla_total_size(0);
541  
542  		/* NL80211_SURVEY_INFO_FREQUENCY */
543  	nl_buf_len +=  nla_total_size(sizeof(uint32_t)) +
544  		 /* NL80211_SURVEY_INFO_NOISE */
545  		nla_total_size(sizeof(int8_t));
546  
547  	return nl_buf_len;
548  }
549  
550  /**
551   * hdd_add_survey_info() - add survey info attribute
552   * @skb: pointer to sk buff
553   * @hdd_sta_ctx: pointer to hdd station context
554   * @idx: attribute index
555   *
556   * Return: Success(0) or reason code for failure
557   */
hdd_add_survey_info(struct sk_buff * skb,struct hdd_station_ctx * hdd_sta_ctx,int idx)558  static int32_t hdd_add_survey_info(struct sk_buff *skb,
559  				   struct hdd_station_ctx *hdd_sta_ctx,
560  				   int idx)
561  {
562  	struct nlattr *nla_attr;
563  
564  	nla_attr = nla_nest_start(skb, idx);
565  	if (!nla_attr)
566  		goto fail;
567  	if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
568  			hdd_sta_ctx->cache_conn_info.chan_freq) ||
569  	    nla_put_u8(skb, NL80211_SURVEY_INFO_NOISE,
570  		       (hdd_sta_ctx->cache_conn_info.noise + 100))) {
571  		hdd_err("put fail");
572  		goto fail;
573  	}
574  	nla_nest_end(skb, nla_attr);
575  	return 0;
576  fail:
577  	return -EINVAL;
578  }
579  
580  /**
581   * hdd_calculate_link_standard_info_ie_size - calculate link standard info size
582   *
583   * Return: link standard info ie size
584   */
hdd_calculate_link_standard_info_ie_size(void)585  static uint32_t hdd_calculate_link_standard_info_ie_size(void)
586  {
587  	uint32_t nl_buf_len = nla_total_size(0);
588  
589  		/* NL80211_ATTR_SSID */
590  	nl_buf_len += nla_total_size(WLAN_SSID_MAX_LEN + 1) +
591  		/* NL80211_ATTR_MAC */
592  		nla_total_size(QDF_MAC_ADDR_SIZE) +
593  		hdd_calculate_survey_info_ie_size() +
594  		hdd_calculate_sta_info_ie_size();
595  
596  	return nl_buf_len;
597  }
598  
599  /**
600   * hdd_add_link_standard_info() - add link info attribute
601   * @skb: pointer to sk buff
602   * @link_info: Link info pointer in HDD adapter
603   * @idx: attribute index
604   *
605   * Return: Success(0) or reason code for failure
606   */
607  static int32_t
hdd_add_link_standard_info(struct sk_buff * skb,struct wlan_hdd_link_info * link_info,int idx)608  hdd_add_link_standard_info(struct sk_buff *skb,
609  			   struct wlan_hdd_link_info *link_info, int idx)
610  {
611  	struct nlattr *nla_attr;
612  	struct hdd_station_ctx *hdd_sta_ctx;
613  
614  	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
615  	if (!hdd_sta_ctx) {
616  		hdd_err("Invalid sta ctx");
617  		goto fail;
618  	}
619  
620  	nla_attr = nla_nest_start(skb, idx);
621  	if (!nla_attr) {
622  		hdd_err("nla_nest_start failed");
623  		goto fail;
624  	}
625  
626  	if (nla_put(skb,
627  		    NL80211_ATTR_SSID,
628  		    hdd_sta_ctx->cache_conn_info.last_ssid.SSID.length,
629  		    hdd_sta_ctx->cache_conn_info.last_ssid.SSID.ssId)) {
630  		hdd_err("put fail");
631  		goto fail;
632  	}
633  	if (nla_put(skb, NL80211_ATTR_MAC, QDF_MAC_ADDR_SIZE,
634  		    hdd_sta_ctx->cache_conn_info.bssid.bytes)) {
635  		hdd_err("put bssid failed");
636  		goto fail;
637  	}
638  	if (hdd_add_survey_info(skb, hdd_sta_ctx, NL80211_ATTR_SURVEY_INFO)) {
639  		hdd_err("hdd_add_survey_info failed");
640  		goto fail;
641  	}
642  
643  	if (hdd_add_sta_info(skb, link_info, NL80211_ATTR_STA_INFO)) {
644  		hdd_err("hdd_add_sta_info failed");
645  		goto fail;
646  	}
647  	nla_nest_end(skb, nla_attr);
648  	return 0;
649  fail:
650  	return -EINVAL;
651  }
652  
653  /**
654   * hdd_calculate_ap_standard_info_ie_size - calculate ap standard info size
655   * @hdd_sta_ctx: pointer to hdd station context
656   *
657   * Return: ap standard info size
658   */
hdd_calculate_ap_standard_info_ie_size(struct hdd_station_ctx * hdd_sta_ctx)659  static uint32_t hdd_calculate_ap_standard_info_ie_size(
660  			struct hdd_station_ctx *hdd_sta_ctx)
661  {
662  	uint32_t nl_buf_len = nla_total_size(0);
663  
664  	/* NL80211_ATTR_VHT_CAPABILITY */
665  	if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present)
666  		nl_buf_len += nla_total_size(sizeof(
667  				hdd_sta_ctx->cache_conn_info.vht_caps));
668  	/* NL80211_ATTR_HT_CAPABILITY */
669  	if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present)
670  		nl_buf_len += nla_total_size(sizeof(
671  				hdd_sta_ctx->cache_conn_info.ht_caps));
672  
673  	return nl_buf_len;
674  }
675  
676  /**
677   * hdd_add_ap_standard_info() - add ap info attribute
678   * @skb: pointer to sk buff
679   * @hdd_sta_ctx: pointer to hdd station context
680   * @idx: attribute index
681   *
682   * Return: Success(0) or reason code for failure
683   */
684  static int32_t
hdd_add_ap_standard_info(struct sk_buff * skb,struct hdd_station_ctx * hdd_sta_ctx,int idx)685  hdd_add_ap_standard_info(struct sk_buff *skb,
686  			 struct hdd_station_ctx *hdd_sta_ctx, int idx)
687  {
688  	struct nlattr *nla_attr;
689  	struct hdd_connection_info *conn_info;
690  
691  	conn_info = &hdd_sta_ctx->cache_conn_info;
692  	nla_attr = nla_nest_start(skb, idx);
693  	if (!nla_attr)
694  		goto fail;
695  	if (conn_info->conn_flag.vht_present) {
696  		if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
697  			    sizeof(conn_info->vht_caps),
698  			    &conn_info->vht_caps)) {
699  			hdd_err("put fail");
700  			goto fail;
701  		}
702  		hdd_nofl_debug("STA VHT capabilities:");
703  		qdf_trace_hex_dump(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
704  				   (uint8_t *)&conn_info->vht_caps,
705  				   sizeof(conn_info->vht_caps));
706  	}
707  	if (conn_info->conn_flag.ht_present) {
708  		if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
709  			    sizeof(conn_info->ht_caps),
710  			    &conn_info->ht_caps)) {
711  			hdd_err("put fail");
712  			goto fail;
713  		}
714  		hdd_nofl_debug("STA HT capabilities:");
715  		qdf_trace_hex_dump(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
716  				   (uint8_t *)&conn_info->ht_caps,
717  				   sizeof(conn_info->ht_caps));
718  	}
719  	nla_nest_end(skb, nla_attr);
720  	return 0;
721  fail:
722  	return -EINVAL;
723  }
724  
725  #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) && \
726       defined(WLAN_FEATURE_11AX)
hdd_add_he_oper_info(struct sk_buff * skb,struct hdd_station_ctx * hdd_sta_ctx)727  static int32_t hdd_add_he_oper_info(struct sk_buff *skb,
728  				    struct hdd_station_ctx *hdd_sta_ctx)
729  {
730  	int32_t ret = 0;
731  	struct hdd_connection_info *conn_info;
732  
733  	conn_info = &hdd_sta_ctx->cache_conn_info;
734  	if (!conn_info->he_oper_len || !conn_info->he_operation)
735  		return ret;
736  
737  	if (nla_put(skb, HE_OPERATION, conn_info->he_oper_len,
738  		    conn_info->he_operation)) {
739  		ret = -EINVAL;
740  	} else {
741  		hdd_nofl_debug("STA HE operation:");
742  		qdf_trace_hex_dump(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
743  				   (uint8_t *)&conn_info->he_operation,
744  				   conn_info->he_oper_len);
745  	}
746  
747  	qdf_mem_free(hdd_sta_ctx->cache_conn_info.he_operation);
748  	hdd_sta_ctx->cache_conn_info.he_operation = NULL;
749  	hdd_sta_ctx->cache_conn_info.he_oper_len = 0;
750  	return ret;
751  }
752  
hdd_get_he_op_len(struct hdd_station_ctx * hdd_sta_ctx)753  static int32_t hdd_get_he_op_len(struct hdd_station_ctx *hdd_sta_ctx)
754  {
755  	return hdd_sta_ctx->cache_conn_info.he_oper_len;
756  }
757  
758  #else
hdd_add_he_oper_info(struct sk_buff * skb,struct hdd_station_ctx * hdd_sta_ctx)759  static inline uint32_t hdd_add_he_oper_info(
760  					struct sk_buff *skb,
761  					struct hdd_station_ctx *hdd_sta_ctx)
762  {
763  	return 0;
764  }
765  
hdd_get_he_op_len(struct hdd_station_ctx * hdd_sta_ctx)766  static uint32_t hdd_get_he_op_len(struct hdd_station_ctx *hdd_sta_ctx)
767  {
768  	return 0;
769  }
770  #endif
771  
772  #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0)) && \
773  	defined(WLAN_FEATURE_11BE)
hdd_add_eht_oper_info(struct sk_buff * skb,struct hdd_station_ctx * hdd_sta_ctx)774  static int32_t hdd_add_eht_oper_info(struct sk_buff *skb,
775  				     struct hdd_station_ctx *hdd_sta_ctx)
776  {
777  	int32_t ret = 0;
778  	struct hdd_connection_info *conn_info;
779  
780  	conn_info = &hdd_sta_ctx->cache_conn_info;
781  	if (!conn_info->eht_oper_len)
782  		return -EINVAL;
783  
784  	if (nla_put(skb, EHT_OPERATION, conn_info->eht_oper_len,
785  		    &conn_info->eht_operation)) {
786  		ret = -EINVAL;
787  	} else {
788  		hdd_nofl_debug("STA EHT operation:");
789  		qdf_trace_hex_dump(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
790  				   (uint8_t *)&conn_info->eht_operation,
791  				   conn_info->eht_oper_len);
792  	}
793  
794  	return ret;
795  }
796  #else
hdd_add_eht_oper_info(struct sk_buff * skb,struct hdd_station_ctx * hdd_sta_ctx)797  static inline int32_t hdd_add_eht_oper_info(
798  					struct sk_buff *skb,
799  					struct hdd_station_ctx *hdd_sta_ctx)
800  {
801  	return 0;
802  }
803  #endif
804  
hdd_get_prev_connected_bss_ies_len(struct hdd_station_ctx * hdd_sta_ctx)805  static uint32_t hdd_get_prev_connected_bss_ies_len(
806  					struct hdd_station_ctx *hdd_sta_ctx)
807  {
808  	return hdd_sta_ctx->conn_info.prev_ap_bcn_ie.len;
809  }
810  
hdd_add_prev_connected_bss_ies(struct sk_buff * skb,struct hdd_station_ctx * hdd_sta_ctx)811  static uint32_t hdd_add_prev_connected_bss_ies(
812  					struct sk_buff *skb,
813  					struct hdd_station_ctx *hdd_sta_ctx)
814  {
815  	struct element_info *bcn_ie = &hdd_sta_ctx->conn_info.prev_ap_bcn_ie;
816  
817  	if (bcn_ie->len) {
818  		if (nla_put(skb, BEACON_IES, bcn_ie->len, bcn_ie->ptr)) {
819  			hdd_err("Failed to put beacon IEs: bytes left: %d, ie_len: %u ",
820  				skb_tailroom(skb), bcn_ie->len);
821  			return -EINVAL;
822  		}
823  
824  		hdd_nofl_debug("Beacon IEs len: %u", bcn_ie->len);
825  
826  		qdf_mem_free(bcn_ie->ptr);
827  		bcn_ie->ptr = NULL;
828  		bcn_ie->len = 0;
829  	}
830  
831  	return 0;
832  }
833  
834  /**
835   * hdd_calculate_station_info_ie_size - calculate bss ie size
836   * @hdd_sta_ctx: pointer to hdd station context
837   *
838   * Return: bss ie size
839   */
hdd_calculate_station_info_ie_size(struct hdd_station_ctx * hdd_sta_ctx)840  static uint32_t hdd_calculate_station_info_ie_size(
841  					struct hdd_station_ctx *hdd_sta_ctx)
842  {
843  	/* NLA_HDRLEN */
844  	uint32_t nl_buf_len = NLA_HDRLEN;
845  
846  	nl_buf_len += hdd_calculate_link_standard_info_ie_size() +
847  		hdd_calculate_ap_standard_info_ie_size(hdd_sta_ctx);
848  
849  		/* QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_ROAM_COUNT */
850  	nl_buf_len += nla_total_size(sizeof(uint32_t)) +
851  		/* QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AKM */
852  		nla_total_size(sizeof(uint32_t)) +
853  		/* QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_802_11_MODE */
854  		nla_total_size(sizeof(uint32_t));
855  
856  	 /* QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_HT_OPERATION */
857  	if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present)
858  		nl_buf_len += nla_total_size(sizeof(
859  				hdd_sta_ctx->cache_conn_info.ht_operation));
860  
861  	/* QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_VHT_OPERATION */
862  	if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present)
863  		nl_buf_len += nla_total_size(sizeof(
864  				hdd_sta_ctx->cache_conn_info.vht_operation));
865  
866  	/* QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_HE_OPERATION */
867  	nl_buf_len += nla_total_size(hdd_get_he_op_len(hdd_sta_ctx));
868  
869  	/* QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AP_HS20_INDICATION */
870  	if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present)
871  		nl_buf_len += nla_total_size(sizeof(
872  			hdd_sta_ctx->cache_conn_info.hs20vendor_ie) - 1);
873  
874  	 /* QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_DRIVER_DISCONNECT_REASON */
875  	nl_buf_len += nla_total_size(sizeof(uint32_t));
876  
877  	/* QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_BEACON_IES */
878  	if (hdd_sta_ctx->conn_info.prev_ap_bcn_ie.len)
879  		nl_buf_len += nla_total_size(
880  			hdd_get_prev_connected_bss_ies_len(hdd_sta_ctx));
881  
882  	return nl_buf_len;
883  }
884  
885  /**
886   * hdd_populate_station_info_skb - populate station info in skb
887   * @skb: pointer to socket buffer
888   * @link_info: Link info pointer in HDD adapter
889   *
890   * Return: QDF_STATUS_SUCCESS in case of success else failure
891   */
892  static QDF_STATUS
hdd_populate_station_info_skb(struct sk_buff * skb,struct wlan_hdd_link_info * link_info)893  hdd_populate_station_info_skb(struct sk_buff *skb,
894  			      struct wlan_hdd_link_info *link_info)
895  {
896  	uint8_t *tmp_hs20 = NULL;
897  	struct hdd_station_ctx *hdd_sta_ctx =
898  					WLAN_HDD_GET_STATION_CTX_PTR(link_info);
899  
900  	if (hdd_add_link_standard_info(skb, link_info,
901  				       LINK_INFO_STANDARD_NL80211_ATTR)) {
902  		hdd_err("link_standard_info put fail");
903  		return QDF_STATUS_E_FAILURE;
904  	}
905  
906  	if (hdd_add_ap_standard_info(skb, hdd_sta_ctx,
907  				     AP_INFO_STANDARD_NL80211_ATTR)) {
908  		hdd_err("ap standard info fail");
909  		return QDF_STATUS_E_FAILURE;
910  	}
911  
912  	if (nla_put_u32(skb, INFO_ROAM_COUNT,
913  			hdd_sta_ctx->cache_conn_info.roam_count) ||
914  	    nla_put_u32(skb, INFO_AKM,
915  			hdd_convert_auth_type(
916  			hdd_sta_ctx->cache_conn_info.last_auth_type)) ||
917  	    nla_put_u32(skb, WLAN802_11_MODE,
918  			hdd_convert_dot11mode(
919  			hdd_sta_ctx->cache_conn_info.dot11mode))) {
920  		hdd_err("Roam, AKM, dot11mode put fail");
921  		return QDF_STATUS_E_FAILURE;
922  	}
923  
924  	if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present) {
925  		if (nla_put(skb, HT_OPERATION,
926  			    (sizeof(hdd_sta_ctx->cache_conn_info.ht_operation)),
927  			    &hdd_sta_ctx->cache_conn_info.ht_operation)) {
928  			hdd_err("ht operation put fail");
929  			return QDF_STATUS_E_FAILURE;
930  		}
931  		hdd_nofl_debug("STA HT operation:");
932  		qdf_trace_hex_dump(
933  			QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
934  			(uint8_t *)&hdd_sta_ctx->cache_conn_info.ht_operation,
935  			sizeof(hdd_sta_ctx->cache_conn_info.ht_operation));
936  	}
937  
938  	if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present) {
939  		if (nla_put(skb, VHT_OPERATION,
940  			    (sizeof(hdd_sta_ctx->
941  					cache_conn_info.vht_operation)),
942  			    &hdd_sta_ctx->cache_conn_info.vht_operation)) {
943  			hdd_err("vht operation put fail");
944  			return QDF_STATUS_E_FAILURE;
945  		}
946  		hdd_nofl_debug("STA VHT operation:");
947  		qdf_trace_hex_dump(
948  			QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
949  			(uint8_t *)&hdd_sta_ctx->cache_conn_info.vht_operation,
950  			sizeof(hdd_sta_ctx->cache_conn_info.vht_operation));
951  	}
952  
953  	if (hdd_add_he_oper_info(skb, hdd_sta_ctx)) {
954  		hdd_err("he operation info put fail");
955  		return QDF_STATUS_E_FAILURE;
956  	}
957  	if (hdd_sta_ctx->cache_conn_info.conn_flag.eht_op_present) {
958  		if (hdd_add_eht_oper_info(skb, hdd_sta_ctx)) {
959  			hdd_err("eht operation info put fail");
960  			return QDF_STATUS_E_FAILURE;
961  		}
962  	}
963  
964  	if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present) {
965  		tmp_hs20 =
966  			(uint8_t *)&hdd_sta_ctx->cache_conn_info.hs20vendor_ie;
967  		if (nla_put(skb, AP_INFO_HS20_INDICATION,
968  			    (sizeof(hdd_sta_ctx->cache_conn_info.hs20vendor_ie)
969  			     - 1),
970  			    tmp_hs20 + 1)) {
971  			hdd_err("hs20 put fail");
972  			return QDF_STATUS_E_FAILURE;
973  		}
974  		hdd_nofl_debug("STA hs20 vendor IE:");
975  		qdf_trace_hex_dump(
976  			QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
977  			(uint8_t *)(tmp_hs20 + 1),
978  			sizeof(hdd_sta_ctx->cache_conn_info.hs20vendor_ie) - 1);
979  	}
980  
981  	if (nla_put_u32(skb, DISCONNECT_REASON,
982  			link_info->adapter->last_disconnect_reason)) {
983  		hdd_err("Failed to put disconnect reason");
984  		return QDF_STATUS_E_FAILURE;
985  	}
986  
987  	if (hdd_add_prev_connected_bss_ies(skb, hdd_sta_ctx)) {
988  		hdd_err("disconnect_reason put fail");
989  		return QDF_STATUS_E_FAILURE;
990  	}
991  	return QDF_STATUS_SUCCESS;
992  }
993  
994  /**
995   * hdd_get_station_info() - send BSS information to supplicant
996   * @link_info: Link info pointer in HDD adapter
997   *
998   * Return: 0 if success else error status
999   */
hdd_get_station_info(struct wlan_hdd_link_info * link_info)1000  static int hdd_get_station_info(struct wlan_hdd_link_info *link_info)
1001  {
1002  	struct sk_buff *skb = NULL;
1003  	uint32_t nl_buf_len;
1004  	struct hdd_adapter *adapter = link_info->adapter;
1005  	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1006  	struct hdd_station_ctx *hdd_sta_ctx;
1007  
1008  	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
1009  
1010  	if (hdd_cm_is_vdev_connected(link_info)) {
1011  		hdd_err("Station is connected, command is not supported");
1012  		return -EINVAL;
1013  	}
1014  
1015  	nl_buf_len = hdd_calculate_station_info_ie_size(hdd_sta_ctx);
1016  	if (!nl_buf_len) {
1017  		hdd_err("BSS ie size calculation failed");
1018  		return -EINVAL;
1019  	}
1020  
1021  	skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1022  	if (!skb) {
1023  		hdd_err("wlan_cfg80211_vendor_cmd_alloc_reply_skb failed");
1024  		return -ENOMEM;
1025  	}
1026  
1027  	if (hdd_populate_station_info_skb(skb, link_info) != QDF_STATUS_SUCCESS)
1028  		goto fail;
1029  
1030  	hdd_nofl_debug(
1031  		"STA Info:: SSID:" QDF_SSID_FMT ", BSSID:" QDF_MAC_ADDR_FMT ", freq:%d, "
1032  		"Noise:%d, signal:%d, roam_count:%d, last_auth_type:%d, "
1033  		"dot11mode:%d, disconnect_reason:%d, ",
1034  		QDF_SSID_REF(WLAN_SSID_MAX_LEN,
1035  			hdd_sta_ctx->cache_conn_info.last_ssid.SSID.ssId),
1036  		QDF_MAC_ADDR_REF(hdd_sta_ctx->cache_conn_info.bssid.bytes),
1037  		hdd_sta_ctx->cache_conn_info.chan_freq,
1038  		(hdd_sta_ctx->cache_conn_info.noise + 100),
1039  		(hdd_sta_ctx->cache_conn_info.signal + 100),
1040  		hdd_sta_ctx->cache_conn_info.roam_count,
1041  		hdd_convert_auth_type(
1042  			hdd_sta_ctx->cache_conn_info.last_auth_type),
1043  		hdd_convert_dot11mode(hdd_sta_ctx->cache_conn_info.dot11mode),
1044  		adapter->last_disconnect_reason);
1045  
1046  	return wlan_cfg80211_vendor_cmd_reply(skb);
1047  fail:
1048  	wlan_cfg80211_vendor_free_skb(skb);
1049  	return -EINVAL;
1050  }
1051  
1052  #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
remote_station_put_u64(struct sk_buff * skb,int32_t attrtype,uint64_t value)1053  static inline int32_t remote_station_put_u64(struct sk_buff *skb,
1054  					     int32_t attrtype,
1055  					     uint64_t value)
1056  {
1057  	return nla_put_u64_64bit(skb, attrtype, value, REMOTE_PAD);
1058  }
1059  #else
remote_station_put_u64(struct sk_buff * skb,int32_t attrtype,uint64_t value)1060  static inline int32_t remote_station_put_u64(struct sk_buff *skb,
1061  					     int32_t attrtype,
1062  					     uint64_t value)
1063  {
1064  	return nla_put_u64(skb, attrtype, value);
1065  }
1066  #endif
1067  
1068  /**
1069   * hdd_add_survey_info_sap_get_len - get data length used in
1070   * hdd_add_survey_info_sap()
1071   *
1072   * This function calculates the data length used in hdd_add_survey_info_sap()
1073   *
1074   * Return: total data length used in hdd_add_survey_info_sap()
1075   */
hdd_add_survey_info_sap_get_len(void)1076  static uint32_t hdd_add_survey_info_sap_get_len(void)
1077  {
1078  	return ((NLA_HDRLEN) + (sizeof(uint32_t) + NLA_HDRLEN));
1079  }
1080  
1081  /**
1082   * hdd_add_survey_info_sap() - add survey info attribute
1083   * @skb: pointer to response skb buffer
1084   * @stainfo: station information
1085   * @idx: attribute type index for nla_next_start()
1086   *
1087   * This function adds survey info attribute to response skb buffer
1088   *
1089   * Return : 0 on success and errno on failure
1090   */
hdd_add_survey_info_sap(struct sk_buff * skb,struct hdd_station_info * stainfo,int idx)1091  static int32_t hdd_add_survey_info_sap(struct sk_buff *skb,
1092  				       struct hdd_station_info *stainfo,
1093  				       int idx)
1094  {
1095  	struct nlattr *nla_attr;
1096  
1097  	nla_attr = nla_nest_start(skb, idx);
1098  	if (!nla_attr)
1099  		goto fail;
1100  	if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
1101  			stainfo->freq)) {
1102  		hdd_err("put fail");
1103  		goto fail;
1104  	}
1105  	nla_nest_end(skb, nla_attr);
1106  	hdd_nofl_debug("Remote STA freq: %d", stainfo->freq);
1107  	return 0;
1108  fail:
1109  	return -EINVAL;
1110  }
1111  
1112  /**
1113   * hdd_add_tx_bitrate_sap_get_len - get data length used in
1114   * hdd_add_tx_bitrate_sap()
1115   *
1116   * This function calculates the data length used in hdd_add_tx_bitrate_sap()
1117   *
1118   * Return: total data length used in hdd_add_tx_bitrate_sap()
1119   */
hdd_add_tx_bitrate_sap_get_len(void)1120  static uint32_t hdd_add_tx_bitrate_sap_get_len(void)
1121  {
1122  	return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN));
1123  }
1124  
hdd_add_sta_capability_get_len(void)1125  static uint32_t hdd_add_sta_capability_get_len(void)
1126  {
1127  	return nla_total_size(sizeof(uint16_t));
1128  }
1129  
1130  /**
1131   * hdd_add_tx_bitrate_sap - add vhs nss info attribute
1132   * @skb: pointer to response skb buffer
1133   * @stainfo: station information
1134   * @idx: attribute type index for nla_next_start()
1135   *
1136   * This function adds vht nss attribute to response skb buffer
1137   *
1138   * Return : 0 on success and errno on failure
1139   */
hdd_add_tx_bitrate_sap(struct sk_buff * skb,struct hdd_station_info * stainfo,int idx)1140  static int hdd_add_tx_bitrate_sap(struct sk_buff *skb,
1141  				  struct hdd_station_info *stainfo,
1142  				  int idx)
1143  {
1144  	struct nlattr *nla_attr;
1145  
1146  	nla_attr = nla_nest_start(skb, idx);
1147  	if (!nla_attr)
1148  		goto fail;
1149  
1150  	if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
1151  		       stainfo->nss)) {
1152  		hdd_err("put fail");
1153  		goto fail;
1154  	}
1155  	nla_nest_end(skb, nla_attr);
1156  	hdd_nofl_debug("Remote STA VHT NSS: %d", stainfo->nss);
1157  	return 0;
1158  fail:
1159  	return -EINVAL;
1160  }
1161  
1162  /**
1163   * hdd_add_sta_info_sap_get_len - get data length used in
1164   * hdd_add_sta_info_sap()
1165   *
1166   * This function calculates the data length used in hdd_add_sta_info_sap()
1167   *
1168   * Return: total data length used in hdd_add_sta_info_sap()
1169   */
hdd_add_sta_info_sap_get_len(void)1170  static uint32_t hdd_add_sta_info_sap_get_len(void)
1171  {
1172  	return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN) +
1173  		hdd_add_tx_bitrate_sap_get_len() +
1174  		hdd_add_sta_capability_get_len());
1175  }
1176  
1177  /**
1178   * hdd_add_sta_info_sap - add sta signal info attribute
1179   * @skb: pointer to response skb buffer
1180   * @rssi: station RSSI
1181   * @stainfo: station information
1182   * @idx: attribute type index for nla_next_start()
1183   *
1184   * This function adds sta signal attribute to response skb buffer
1185   *
1186   * Return : 0 on success and errno on failure
1187   */
hdd_add_sta_info_sap(struct sk_buff * skb,int8_t rssi,struct hdd_station_info * stainfo,int idx)1188  static int32_t hdd_add_sta_info_sap(struct sk_buff *skb, int8_t rssi,
1189  				    struct hdd_station_info *stainfo, int idx)
1190  {
1191  	struct nlattr *nla_attr;
1192  
1193  	nla_attr = nla_nest_start(skb, idx);
1194  	if (!nla_attr)
1195  		goto fail;
1196  
1197  	if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL,
1198  		       rssi)) {
1199  		hdd_err("put fail");
1200  		goto fail;
1201  	}
1202  	if (hdd_add_tx_bitrate_sap(skb, stainfo, NL80211_STA_INFO_TX_BITRATE))
1203  		goto fail;
1204  
1205  	nla_nest_end(skb, nla_attr);
1206  	hdd_nofl_debug("Remote STA RSSI: %d", rssi - HDD_NOISE_FLOOR_DBM);
1207  	return 0;
1208  fail:
1209  	return -EINVAL;
1210  }
1211  
1212  /**
1213   * hdd_add_link_standard_info_sap_get_len - get data length used in
1214   * hdd_add_link_standard_info_sap()
1215   *
1216   * This function calculates the data length used in
1217   * hdd_add_link_standard_info_sap()
1218   *
1219   * Return: total data length used in hdd_add_link_standard_info_sap()
1220   */
hdd_add_link_standard_info_sap_get_len(void)1221  static uint32_t hdd_add_link_standard_info_sap_get_len(void)
1222  {
1223  	return ((NLA_HDRLEN) +
1224  		hdd_add_survey_info_sap_get_len() +
1225  		hdd_add_sta_info_sap_get_len() +
1226  		(sizeof(uint32_t) + NLA_HDRLEN));
1227  }
1228  
1229  /**
1230   * hdd_add_link_standard_info_sap - add add link info attribute
1231   * @skb: pointer to response skb buffer
1232   * @rssi: station RSSI
1233   * @stainfo: station information
1234   * @idx: attribute type index for nla_next_start()
1235   *
1236   * This function adds link info attribute to response skb buffer
1237   *
1238   * Return : 0 on success and errno on failure
1239   */
hdd_add_link_standard_info_sap(struct sk_buff * skb,int8_t rssi,struct hdd_station_info * stainfo,int idx)1240  static int hdd_add_link_standard_info_sap(struct sk_buff *skb, int8_t rssi,
1241  					  struct hdd_station_info *stainfo,
1242  					  int idx)
1243  {
1244  	struct nlattr *nla_attr;
1245  
1246  	nla_attr = nla_nest_start(skb, idx);
1247  	if (!nla_attr)
1248  		goto fail;
1249  	if (hdd_add_survey_info_sap(skb, stainfo, NL80211_ATTR_SURVEY_INFO))
1250  		goto fail;
1251  	if (hdd_add_sta_info_sap(skb, rssi, stainfo, NL80211_ATTR_STA_INFO))
1252  		goto fail;
1253  
1254  	if (nla_put_u32(skb, NL80211_ATTR_REASON_CODE, stainfo->reason_code)) {
1255  		hdd_err("Reason code put fail");
1256  		goto fail;
1257  	}
1258  	if (nla_put_u16(skb, NL80211_ATTR_STA_CAPABILITY,
1259  			stainfo->capability)) {
1260  		hdd_err("put fail");
1261  		goto fail;
1262  	}
1263  	nla_nest_end(skb, nla_attr);
1264  	return 0;
1265  fail:
1266  	return -EINVAL;
1267  }
1268  
1269  /**
1270   * hdd_add_ap_standard_info_sap_get_len - get data length used in
1271   * hdd_add_ap_standard_info_sap()
1272   * @stainfo: station information
1273   *
1274   * This function calculates the data length used in
1275   * hdd_add_ap_standard_info_sap()
1276   *
1277   * Return: total data length used in hdd_add_ap_standard_info_sap()
1278   */
hdd_add_ap_standard_info_sap_get_len(struct hdd_station_info * stainfo)1279  static uint32_t hdd_add_ap_standard_info_sap_get_len(
1280  				struct hdd_station_info *stainfo)
1281  {
1282  	uint32_t len;
1283  
1284  	len = NLA_HDRLEN;
1285  	if (stainfo->vht_present)
1286  		len += (sizeof(stainfo->vht_caps) + NLA_HDRLEN);
1287  	if (stainfo->ht_present)
1288  		len += (sizeof(stainfo->ht_caps) + NLA_HDRLEN);
1289  
1290  	return len;
1291  }
1292  
1293  /**
1294   * hdd_add_ap_standard_info_sap - add HT and VHT info attributes
1295   * @skb: pointer to response skb buffer
1296   * @stainfo: station information
1297   * @idx: attribute type index for nla_next_start()
1298   *
1299   * This function adds HT and VHT info attributes to response skb buffer
1300   *
1301   * Return : 0 on success and errno on failure
1302   */
hdd_add_ap_standard_info_sap(struct sk_buff * skb,struct hdd_station_info * stainfo,int idx)1303  static int hdd_add_ap_standard_info_sap(struct sk_buff *skb,
1304  					struct hdd_station_info *stainfo,
1305  					int idx)
1306  {
1307  	struct nlattr *nla_attr;
1308  
1309  	nla_attr = nla_nest_start(skb, idx);
1310  	if (!nla_attr)
1311  		goto fail;
1312  
1313  	if (stainfo->vht_present) {
1314  		if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
1315  			    sizeof(stainfo->vht_caps),
1316  			    &stainfo->vht_caps)) {
1317  			hdd_err("put fail");
1318  			goto fail;
1319  		}
1320  
1321  		hdd_nofl_debug("Remote STA VHT capabilities len:%u",
1322  			       (uint32_t)sizeof(stainfo->vht_caps));
1323  	}
1324  	if (stainfo->ht_present) {
1325  		if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
1326  			    sizeof(stainfo->ht_caps),
1327  			    &stainfo->ht_caps)) {
1328  			hdd_err("put fail");
1329  			goto fail;
1330  		}
1331  
1332  		hdd_nofl_debug("Remote STA HT capabilities len:%u",
1333  			       (uint32_t)sizeof(stainfo->ht_caps));
1334  	}
1335  	nla_nest_end(skb, nla_attr);
1336  	return 0;
1337  fail:
1338  	return -EINVAL;
1339  }
1340  
1341  /**
1342   * hdd_decode_ch_width - decode channel band width based
1343   * @ch_width: encoded enum value holding channel band width
1344   *
1345   * This function decodes channel band width from the given encoded enum value.
1346   *
1347   * Returns: decoded channel band width.
1348   */
hdd_decode_ch_width(tSirMacHTChannelWidth ch_width)1349  static uint16_t hdd_decode_ch_width(tSirMacHTChannelWidth ch_width)
1350  {
1351  	switch (ch_width) {
1352  	case 0:
1353  		return 20;
1354  	case 1:
1355  		return 40;
1356  	case 2:
1357  		return 80;
1358  	case 3:
1359  	case 4:
1360  		return 160;
1361  	case 5:
1362  		return 320;
1363  	default:
1364  		hdd_debug("invalid enum: %d", ch_width);
1365  		return 20;
1366  	}
1367  }
1368  
1369  /**
1370   * hdd_get_cached_station_remote() - get cached(deleted) peer's info
1371   * @hdd_ctx: hdd context
1372   * @adapter: hostapd interface
1373   * @mac_addr: mac address of requested peer
1374   *
1375   * This function collect and indicate the cached(deleted) peer's info
1376   *
1377   * Return: 0 on success, otherwise error value
1378   */
1379  
hdd_get_cached_station_remote(struct hdd_context * hdd_ctx,struct hdd_adapter * adapter,struct qdf_mac_addr mac_addr)1380  static int hdd_get_cached_station_remote(struct hdd_context *hdd_ctx,
1381  					 struct hdd_adapter *adapter,
1382  					 struct qdf_mac_addr mac_addr)
1383  {
1384  	struct hdd_station_info *stainfo;
1385  	struct sk_buff *skb = NULL;
1386  	uint32_t nl_buf_len = NLMSG_HDRLEN;
1387  	uint8_t channel_width;
1388  	uint16_t channel_width_v2;
1389  
1390  
1391  	stainfo = hdd_get_sta_info_by_mac(&adapter->cache_sta_info_list,
1392  					  mac_addr.bytes,
1393  					  STA_INFO_GET_CACHED_STATION_REMOTE);
1394  
1395  	if (!stainfo) {
1396  		hdd_err("peer " QDF_MAC_ADDR_FMT " not found",
1397  			QDF_MAC_ADDR_REF(mac_addr.bytes));
1398  		return -EINVAL;
1399  	}
1400  
1401  	nl_buf_len += hdd_add_link_standard_info_sap_get_len() +
1402  			hdd_add_ap_standard_info_sap_get_len(stainfo) +
1403  			(sizeof(stainfo->dot11_mode) + NLA_HDRLEN) +
1404  			(sizeof(stainfo->ch_width) + NLA_HDRLEN) +
1405  			(sizeof(stainfo->tx_rate) + NLA_HDRLEN) +
1406  			(sizeof(stainfo->rx_rate) + NLA_HDRLEN) +
1407  			(sizeof(stainfo->support_mode) + NLA_HDRLEN) +
1408  			(sizeof(stainfo->rx_mc_bc_cnt) + NLA_HDRLEN) +
1409  			(sizeof(stainfo->rx_retry_cnt) + NLA_HDRLEN);
1410  	if (stainfo->assoc_req_ies.len)
1411  		nl_buf_len += stainfo->assoc_req_ies.len + NLA_HDRLEN;
1412  
1413  	skb = wlan_cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy,
1414  						       nl_buf_len);
1415  	if (!skb) {
1416  		hdd_put_sta_info_ref(&adapter->cache_sta_info_list,
1417  				     &stainfo, true,
1418  				     STA_INFO_GET_CACHED_STATION_REMOTE);
1419  		hdd_err("wlan_cfg80211_vendor_cmd_alloc_reply_skb failed");
1420  		return -ENOMEM;
1421  	}
1422  
1423  	if (hdd_add_link_standard_info_sap(skb, stainfo->rssi, stainfo,
1424  					   LINK_INFO_STANDARD_NL80211_ATTR)) {
1425  		hdd_err("link standard put fail");
1426  		goto fail;
1427  	}
1428  
1429  	if (hdd_add_ap_standard_info_sap(skb, stainfo,
1430  					 AP_INFO_STANDARD_NL80211_ATTR)) {
1431  		hdd_err("ap standard put fail");
1432  		goto fail;
1433  	}
1434  
1435  	/* upper layer expects decoded channel BW */
1436  	channel_width_v2 = hdd_decode_ch_width(stainfo->ch_width);
1437  	if (channel_width_v2 > MAX_CHANNEL_BW_160)
1438  		channel_width = MAX_CHANNEL_BW_160;
1439  	else
1440  		channel_width = channel_width_v2;
1441  
1442  	if (nla_put_u32(skb, REMOTE_SUPPORTED_MODE,
1443  			stainfo->support_mode) ||
1444  	    nla_put_u8(skb, REMOTE_CH_WIDTH, channel_width) ||
1445  	    nla_put_u16(skb, REMOTE_CH_WIDTH_V2, channel_width_v2)) {
1446  		hdd_err("remote ch put fail");
1447  		goto fail;
1448  	}
1449  	/* Convert the data from kbps to mbps as expected by the user space */
1450  	if (nla_put_u32(skb, REMOTE_LAST_TX_RATE, stainfo->tx_rate / 1000)) {
1451  		hdd_err("tx rate put fail");
1452  		goto fail;
1453  	}
1454  	/* Convert the data from kbps to mbps as expected by the user space */
1455  	if (nla_put_u32(skb, REMOTE_LAST_RX_RATE, stainfo->rx_rate / 1000)) {
1456  		hdd_err("rx rate put fail");
1457  		goto fail;
1458  	}
1459  	if (nla_put_u32(skb, WLAN802_11_MODE, stainfo->dot11_mode)) {
1460  		hdd_err("dot11 mode put fail");
1461  		goto fail;
1462  	}
1463  	if (!(stainfo->rx_mc_bc_cnt & HDD_STATION_INFO_RX_MC_BC_COUNT)) {
1464  		hdd_debug("rx mc bc count is not supported by FW");
1465  	} else if (nla_put_u32(skb, REMOTE_RX_BC_MC_COUNT,
1466  			       (stainfo->rx_mc_bc_cnt &
1467  			       (~HDD_STATION_INFO_RX_MC_BC_COUNT)))) {
1468  		hdd_err("rx mc bc put fail");
1469  		goto fail;
1470  	} else {
1471  		hdd_nofl_debug("Remote STA RX mc_bc_count: %d",
1472  			       (stainfo->rx_mc_bc_cnt &
1473  			       (~HDD_STATION_INFO_RX_MC_BC_COUNT)));
1474  	}
1475  
1476  	/* Currently rx_retry count is not supported */
1477  	if (stainfo->rx_retry_cnt) {
1478  		if (nla_put_u32(skb, REMOTE_RX_RETRY_COUNT,
1479  				stainfo->rx_retry_cnt)) {
1480  			hdd_err("rx retry count put fail");
1481  			goto fail;
1482  		}
1483  		hdd_nofl_debug("Remote STA retry count: %d",
1484  			       stainfo->rx_retry_cnt);
1485  	}
1486  
1487  	if (stainfo->assoc_req_ies.len) {
1488  		if (nla_put(skb, ASSOC_REQ_IES, stainfo->assoc_req_ies.len,
1489  			    stainfo->assoc_req_ies.ptr)) {
1490  			hdd_err("Failed to put assoc req IEs");
1491  			goto fail;
1492  		}
1493  		hdd_nofl_debug("Remote STA assoc req IE len: %d",
1494  			       stainfo->assoc_req_ies.len);
1495  	}
1496  
1497  	hdd_nofl_debug(
1498  		"Remote STA Info:: freq:%d, RSSI:%d, Tx NSS:%d, Reason code:%d,"
1499  		"capability:0x%x, Supported mode:%d, chan_width:%d, Tx rate:%d,"
1500  		"Rx rate:%d, dot11mode:%d",
1501  		stainfo->freq, stainfo->rssi,
1502  		stainfo->nss, stainfo->reason_code, stainfo->capability,
1503  		stainfo->support_mode, channel_width, stainfo->tx_rate,
1504  		stainfo->rx_rate, stainfo->dot11_mode);
1505  
1506  	hdd_sta_info_detach(&adapter->cache_sta_info_list, &stainfo);
1507  	hdd_put_sta_info_ref(&adapter->cache_sta_info_list, &stainfo, true,
1508  			     STA_INFO_GET_CACHED_STATION_REMOTE);
1509  	qdf_atomic_dec(&adapter->cache_sta_count);
1510  
1511  	return wlan_cfg80211_vendor_cmd_reply(skb);
1512  fail:
1513  	hdd_put_sta_info_ref(&adapter->cache_sta_info_list, &stainfo, true,
1514  			     STA_INFO_GET_CACHED_STATION_REMOTE);
1515  	wlan_cfg80211_vendor_free_skb(skb);
1516  	return -EINVAL;
1517  }
1518  
1519  /**
1520   * hdd_get_connected_station_info() - get connected peer's info
1521   * @link_info: Link info pointer in HDD adapter
1522   * @mac_addr: mac address of requested peer
1523   * @stainfo: location to store peer info
1524   *
1525   * This function collect and indicate the connected peer's info
1526   *
1527   * Return: 0 on success, otherwise error value
1528   */
hdd_get_connected_station_info(struct wlan_hdd_link_info * link_info,struct qdf_mac_addr mac_addr,struct hdd_station_info * stainfo)1529  static int hdd_get_connected_station_info(struct wlan_hdd_link_info *link_info,
1530  					  struct qdf_mac_addr mac_addr,
1531  					  struct hdd_station_info *stainfo)
1532  {
1533  	struct sk_buff *skb = NULL;
1534  	uint32_t nl_buf_len;
1535  	struct stats_event *stats;
1536  	bool txrx_rate = false, value;
1537  	QDF_STATUS status;
1538  	int ret;
1539  	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(link_info->adapter);
1540  
1541  	nl_buf_len = NLMSG_HDRLEN;
1542  	nl_buf_len += (sizeof(stainfo->max_phy_rate) + NLA_HDRLEN) +
1543  		(sizeof(stainfo->tx_packets) + NLA_HDRLEN) +
1544  		(sizeof(stainfo->tx_bytes) + NLA_HDRLEN) +
1545  		(sizeof(stainfo->rx_packets) + NLA_HDRLEN) +
1546  		(sizeof(stainfo->rx_bytes) + NLA_HDRLEN) +
1547  		(sizeof(stainfo->is_qos_enabled) + NLA_HDRLEN) +
1548  		(sizeof(stainfo->mode) + NLA_HDRLEN);
1549  
1550  	status = ucfg_mlme_get_sap_get_peer_info(hdd_ctx->psoc, &value);
1551  	if (status != QDF_STATUS_SUCCESS)
1552  		hdd_err("Unable to fetch sap ger peer info");
1553  	if (value) {
1554  		stats = wlan_cfg80211_mc_cp_stats_get_peer_stats(
1555  					link_info->vdev, mac_addr.bytes,
1556  					&ret);
1557  		if (ret || !stats) {
1558  			hdd_err("fail to get tx/rx rate");
1559  			wlan_cfg80211_mc_cp_stats_free_stats_event(stats);
1560  		} else {
1561  			txrx_rate = true;
1562  		}
1563  	}
1564  
1565  	if (txrx_rate) {
1566  		stainfo->tx_rate = stats->peer_stats_info_ext->tx_rate;
1567  		stainfo->rx_rate = stats->peer_stats_info_ext->rx_rate;
1568  		stainfo->tx_packets = stats->peer_stats_info_ext->tx_packets;
1569  		stainfo->tx_bytes = stats->peer_stats_info_ext->tx_bytes;
1570  		stainfo->rx_packets = stats->peer_stats_info_ext->rx_packets;
1571  		stainfo->rx_bytes = stats->peer_stats_info_ext->rx_bytes;
1572  		nl_buf_len += (sizeof(stainfo->tx_rate) + NLA_HDRLEN) +
1573  			(sizeof(stainfo->rx_rate) + NLA_HDRLEN);
1574  		wlan_cfg80211_mc_cp_stats_free_stats_event(stats);
1575  	}
1576  
1577  	/* below info is only valid for HT/VHT mode */
1578  	if (stainfo->mode > SIR_SME_PHY_MODE_LEGACY)
1579  		nl_buf_len += (sizeof(stainfo->ampdu) + NLA_HDRLEN) +
1580  			(sizeof(stainfo->tx_stbc) + NLA_HDRLEN) +
1581  			(sizeof(stainfo->rx_stbc) + NLA_HDRLEN) +
1582  			(sizeof(stainfo->ch_width) + NLA_HDRLEN) +
1583  			(sizeof(stainfo->sgi_enable) + NLA_HDRLEN);
1584  
1585  	hdd_info("buflen %d hdrlen %d", nl_buf_len, NLMSG_HDRLEN);
1586  
1587  	skb = wlan_cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy,
1588  						       nl_buf_len);
1589  	if (!skb) {
1590  		hdd_err("wlan_cfg80211_vendor_cmd_alloc_reply_skb failed");
1591  		return -ENOMEM;
1592  	}
1593  
1594  	hdd_info("stainfo");
1595  	hdd_info("maxrate %x tx_pkts %x tx_bytes %llx",
1596  		 stainfo->max_phy_rate, stainfo->tx_packets, stainfo->tx_bytes);
1597  	hdd_info("rx_pkts %x rx_bytes %llx mode %x",
1598  		 stainfo->rx_packets, stainfo->rx_bytes, stainfo->mode);
1599  	if (stainfo->mode > SIR_SME_PHY_MODE_LEGACY) {
1600  		hdd_info("ampdu %d tx_stbc %d rx_stbc %d",
1601  			 stainfo->ampdu, stainfo->tx_stbc, stainfo->rx_stbc);
1602  		hdd_info("wmm %d chwidth %d sgi %d",
1603  			 stainfo->is_qos_enabled,
1604  			 stainfo->ch_width, stainfo->sgi_enable);
1605  	}
1606  
1607  	if (nla_put_u32(skb, REMOTE_MAX_PHY_RATE, stainfo->max_phy_rate) ||
1608  	    nla_put_u32(skb, REMOTE_TX_PACKETS, stainfo->tx_packets) ||
1609  	    remote_station_put_u64(skb, REMOTE_TX_BYTES, stainfo->tx_bytes) ||
1610  	    nla_put_u32(skb, REMOTE_RX_PACKETS, stainfo->rx_packets) ||
1611  	    remote_station_put_u64(skb, REMOTE_RX_BYTES, stainfo->rx_bytes) ||
1612  	    nla_put_u8(skb, REMOTE_WMM, stainfo->is_qos_enabled) ||
1613  	    nla_put_u8(skb, REMOTE_SUPPORTED_MODE, stainfo->mode)) {
1614  		hdd_err("put fail");
1615  		goto fail;
1616  	}
1617  
1618  	if (txrx_rate) {
1619  		if (nla_put_u32(skb, REMOTE_LAST_TX_RATE, stainfo->tx_rate) ||
1620  		    nla_put_u32(skb, REMOTE_LAST_RX_RATE, stainfo->rx_rate)) {
1621  			hdd_err("put fail");
1622  			goto fail;
1623  		} else {
1624  			hdd_info("tx_rate %x rx_rate %x",
1625  				 stainfo->tx_rate, stainfo->rx_rate);
1626  		}
1627  	}
1628  
1629  	if (stainfo->mode > SIR_SME_PHY_MODE_LEGACY) {
1630  		if (nla_put_u8(skb, REMOTE_AMPDU, stainfo->ampdu) ||
1631  		    nla_put_u8(skb, REMOTE_TX_STBC, stainfo->tx_stbc) ||
1632  		    nla_put_u8(skb, REMOTE_RX_STBC, stainfo->rx_stbc) ||
1633  		    nla_put_u8(skb, REMOTE_CH_WIDTH, stainfo->ch_width) ||
1634  		    nla_put_u8(skb, REMOTE_SGI_ENABLE, stainfo->sgi_enable)) {
1635  			hdd_err("put fail");
1636  			goto fail;
1637  		}
1638  	}
1639  
1640  	return wlan_cfg80211_vendor_cmd_reply(skb);
1641  
1642  fail:
1643  	wlan_cfg80211_vendor_free_skb(skb);
1644  	return -EINVAL;
1645  }
1646  
1647  /**
1648   * hdd_get_station_remote() - get remote peer's info
1649   * @link_info: Link info pointer in HDD adapter
1650   * @mac_addr: mac address of requested peer
1651   *
1652   * This function collect and indicate the remote peer's info
1653   *
1654   * Return: 0 on success, otherwise error value
1655   */
hdd_get_station_remote(struct wlan_hdd_link_info * link_info,struct qdf_mac_addr mac_addr)1656  static int hdd_get_station_remote(struct wlan_hdd_link_info *link_info,
1657  				  struct qdf_mac_addr mac_addr)
1658  {
1659  	int status = 0;
1660  	struct hdd_adapter *adapter = link_info->adapter;
1661  	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1662  	struct hdd_station_info *stainfo =
1663  			hdd_get_sta_info_by_mac(
1664  					&adapter->sta_info_list,
1665  					mac_addr.bytes,
1666  					STA_INFO_HDD_GET_STATION_REMOTE);
1667  
1668  	if (!stainfo) {
1669  		status = hdd_get_cached_station_remote(hdd_ctx, adapter,
1670  						       mac_addr);
1671  		return status;
1672  	}
1673  
1674  	status = hdd_get_connected_station_info(link_info, mac_addr, stainfo);
1675  	hdd_put_sta_info_ref(&adapter->sta_info_list, &stainfo, true,
1676  			     STA_INFO_HDD_GET_STATION_REMOTE);
1677  	return status;
1678  }
1679  
1680  /**
1681   * __hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1682   * @wiphy: corestack handler
1683   * @wdev: wireless device
1684   * @data: data
1685   * @data_len: data length
1686   *
1687   * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1688   * Validate cmd attributes and send the station info to upper layers.
1689   *
1690   * Return: Success(0) or reason code for failure
1691   */
1692  static int
__hdd_cfg80211_get_station_cmd(struct wiphy * wiphy,struct wireless_dev * wdev,const void * data,int data_len)1693  __hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1694  			       struct wireless_dev *wdev,
1695  			       const void *data,
1696  			       int data_len)
1697  {
1698  	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
1699  	struct net_device *dev = wdev->netdev;
1700  	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1701  	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX + 1];
1702  	int32_t status;
1703  
1704  	hdd_enter_dev(dev);
1705  	if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
1706  		hdd_err("Command not allowed in FTM mode");
1707  		status = -EPERM;
1708  		goto out;
1709  	}
1710  
1711  	status = wlan_hdd_validate_context(hdd_ctx);
1712  	if (status != 0)
1713  		goto out;
1714  
1715  	status = wlan_cfg80211_nla_parse(tb,
1716  					 QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX,
1717  					 data, data_len,
1718  					 hdd_get_station_policy);
1719  	if (status) {
1720  		hdd_err("Invalid ATTR");
1721  		goto out;
1722  	}
1723  
1724  	/* Parse and fetch Command Type*/
1725  	if (tb[STATION_INFO]) {
1726  		status = hdd_get_station_info(adapter->deflink);
1727  	} else if (tb[STATION_ASSOC_FAIL_REASON]) {
1728  		status = hdd_get_station_assoc_fail(adapter->deflink);
1729  	} else if (tb[STATION_REMOTE]) {
1730  		struct qdf_mac_addr mac_addr;
1731  
1732  		if (adapter->device_mode != QDF_SAP_MODE &&
1733  		    adapter->device_mode != QDF_P2P_GO_MODE) {
1734  			hdd_err("invalid device_mode:%d", adapter->device_mode);
1735  			status = -EINVAL;
1736  			goto out;
1737  		}
1738  
1739  		nla_memcpy(mac_addr.bytes, tb[STATION_REMOTE],
1740  			   QDF_MAC_ADDR_SIZE);
1741  
1742  		hdd_debug("STATION_REMOTE " QDF_MAC_ADDR_FMT,
1743  			  QDF_MAC_ADDR_REF(mac_addr.bytes));
1744  
1745  		status = hdd_get_station_remote(adapter->deflink, mac_addr);
1746  	} else {
1747  		hdd_err("get station info cmd type failed");
1748  		status = -EINVAL;
1749  		goto out;
1750  	}
1751  	hdd_exit();
1752  out:
1753  	return status;
1754  }
1755  
hdd_cfg80211_get_station_cmd(struct wiphy * wiphy,struct wireless_dev * wdev,const void * data,int data_len)1756  int32_t hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1757  				     struct wireless_dev *wdev,
1758  				     const void *data,
1759  				     int data_len)
1760  {
1761  	struct osif_vdev_sync *vdev_sync;
1762  	int errno;
1763  
1764  	errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync);
1765  	if (errno)
1766  		return errno;
1767  
1768  	errno = __hdd_cfg80211_get_station_cmd(wiphy, wdev, data, data_len);
1769  
1770  	osif_vdev_sync_op_stop(vdev_sync);
1771  
1772  	return errno;
1773  }
1774  
1775  /**
1776   * hdd_get_peer_stats - get peer statistics information
1777   * @adapter: pointer to adapter
1778   * @stainfo: station information
1779   *
1780   * This function gets peer statistics information. If IPA is
1781   * enabled the Rx bcast/mcast count is updated in the
1782   * exception callback invoked by the IPA driver. In case of
1783   * back pressure the packets may get routed to the sw path and
1784   * where eventually the peer mcast/bcast pkt counts are updated in
1785   * dp rx process handling.
1786   *
1787   * Return : 0 on success and errno on failure
1788   */
hdd_get_peer_stats(struct hdd_adapter * adapter,struct hdd_station_info * stainfo)1789  static int hdd_get_peer_stats(struct hdd_adapter *adapter,
1790  			      struct hdd_station_info *stainfo)
1791  {
1792  	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
1793  	struct cdp_peer_stats *peer_stats;
1794  	struct cds_vdev_dp_stats dp_stats;
1795  	struct stats_event *stats;
1796  	QDF_STATUS status;
1797  	int i, ret = 0;
1798  
1799  	peer_stats = qdf_mem_malloc(sizeof(*peer_stats));
1800  	if (!peer_stats)
1801  		return -ENOMEM;
1802  
1803  	status = cdp_host_get_peer_stats(soc, adapter->deflink->vdev_id,
1804  					 stainfo->sta_mac.bytes, peer_stats);
1805  	if (status != QDF_STATUS_SUCCESS) {
1806  		hdd_err("cdp_host_get_peer_stats failed");
1807  		qdf_mem_free(peer_stats);
1808  		return -EINVAL;
1809  	}
1810  
1811  	stainfo->rx_retry_cnt = peer_stats->rx.rx_retries;
1812  	if (!ucfg_ipa_is_enabled())
1813  		stainfo->rx_mc_bc_cnt = peer_stats->rx.multicast.num +
1814  					peer_stats->rx.bcast.num;
1815  	else
1816  		stainfo->rx_mc_bc_cnt += peer_stats->rx.multicast.num +
1817  					 peer_stats->rx.bcast.num;
1818  
1819  	qdf_mem_free(peer_stats);
1820  	peer_stats = NULL;
1821  
1822  	stats = wlan_cfg80211_mc_cp_stats_get_peer_stats(adapter->deflink->vdev,
1823  							 stainfo->sta_mac.bytes,
1824  							 &ret);
1825  	if (ret || !stats) {
1826  		wlan_cfg80211_mc_cp_stats_free_stats_event(stats);
1827  		hdd_err("Failed to get peer stats info");
1828  		return -EINVAL;
1829  	}
1830  
1831  	if (cds_dp_get_vdev_stats(adapter->deflink->vdev_id, &dp_stats))
1832  		stainfo->tx_retry_succeed =
1833  					dp_stats.tx_mpdu_success_with_retries;
1834  	else
1835  		hdd_err("failed to get dp vdev stats");
1836  
1837  	/* This host counter is not supported
1838  	 * since currently tx retry is not done in host side
1839  	 */
1840  	stainfo->tx_retry_exhaust = 0;
1841  	stainfo->tx_total_fw = stats->peer_stats_info_ext->tx_packets;
1842  	stainfo->tx_retry_fw = stats->peer_stats_info_ext->tx_retries;
1843  	stainfo->tx_retry_exhaust_fw = stats->peer_stats_info_ext->tx_failed;
1844  
1845  	if (stats->peer_stats_info_ext->num_tx_rate_counts) {
1846  		stainfo->tx_pkt_per_mcs = qdf_mem_malloc(
1847  				stats->peer_stats_info_ext->num_tx_rate_counts *
1848  				sizeof(uint32_t));
1849  		if (stainfo->tx_pkt_per_mcs) {
1850  			stainfo->num_tx_rate_count =
1851  				stats->peer_stats_info_ext->num_tx_rate_counts;
1852  			qdf_mem_copy(
1853  				stainfo->tx_pkt_per_mcs,
1854  				stats->peer_stats_info_ext->tx_pkt_per_mcs,
1855  				stainfo->num_tx_rate_count * sizeof(uint32_t));
1856  		}
1857  	}
1858  	if (stats->peer_stats_info_ext->num_rx_rate_counts) {
1859  		stainfo->rx_pkt_per_mcs = qdf_mem_malloc(
1860  				stats->peer_stats_info_ext->num_rx_rate_counts *
1861  				sizeof(uint32_t));
1862  		if (stainfo->rx_pkt_per_mcs) {
1863  			stainfo->num_rx_rate_count =
1864  				stats->peer_stats_info_ext->num_rx_rate_counts;
1865  			qdf_mem_copy(
1866  				stainfo->rx_pkt_per_mcs,
1867  				stats->peer_stats_info_ext->rx_pkt_per_mcs,
1868  				stainfo->num_rx_rate_count * sizeof(uint32_t));
1869  		}
1870  	}
1871  
1872  	/* Optional, just print logs here */
1873  	if (!stats->num_peer_adv_stats) {
1874  		hdd_debug("Failed to get peer adv stats info");
1875  		stainfo->rx_fcs_count = 0;
1876  	}
1877  
1878  	for (i = 0; i < stats->num_peer_adv_stats; i++) {
1879  		if (!qdf_mem_cmp(stainfo->sta_mac.bytes,
1880  				 stats->peer_adv_stats[i].peer_macaddr,
1881  				 QDF_MAC_ADDR_SIZE)) {
1882  			stainfo->rx_fcs_count = stats->peer_adv_stats[i].
1883  								      fcs_count;
1884  			break;
1885  		}
1886  	}
1887  
1888  	wlan_cfg80211_mc_cp_stats_free_stats_event(stats);
1889  
1890  	return ret;
1891  }
1892  
1893  /**
1894   * hdd_free_tx_rx_pkts_per_mcs - Free memory for tx packets per MCS and
1895   * rx packets per MCS
1896   * @stainfo: station information
1897   *
1898   * Return: None
1899   */
hdd_free_tx_rx_pkts_per_mcs(struct hdd_station_info * stainfo)1900  static void hdd_free_tx_rx_pkts_per_mcs(struct hdd_station_info *stainfo)
1901  {
1902  	if (stainfo->tx_pkt_per_mcs) {
1903  		qdf_mem_free(stainfo->tx_pkt_per_mcs);
1904  		stainfo->tx_pkt_per_mcs = NULL;
1905  	}
1906  	if (stainfo->rx_pkt_per_mcs) {
1907  		qdf_mem_free(stainfo->rx_pkt_per_mcs);
1908  		stainfo->rx_pkt_per_mcs = NULL;
1909  	}
1910  }
1911  
1912  /**
1913   * hdd_add_peer_stats_get_len - get data length used in
1914   * hdd_add_peer_stats()
1915   * @stainfo: station information
1916   *
1917   * This function calculates the data length used in
1918   * hdd_add_peer_stats()
1919   *
1920   * Return: total data length used in hdd_add_peer_stats()
1921   */
1922  static uint32_t
hdd_add_peer_stats_get_len(struct hdd_station_info * stainfo)1923  hdd_add_peer_stats_get_len(struct hdd_station_info *stainfo)
1924  {
1925  	uint32_t tx_count_size = 0;
1926  	uint32_t rx_count_size = 0;
1927  	uint16_t i;
1928  
1929  	for (i = 0; i < stainfo->num_tx_rate_count; i++)
1930  		tx_count_size += nla_attr_size(sizeof(uint32_t));
1931  	for (i = 0; i < stainfo->num_rx_rate_count; i++)
1932  		rx_count_size += nla_attr_size(sizeof(uint32_t));
1933  
1934  	return (nla_attr_size(sizeof(stainfo->rx_retry_cnt)) +
1935  		nla_attr_size(sizeof(stainfo->rx_mc_bc_cnt)) +
1936  		nla_attr_size(sizeof(stainfo->tx_retry_succeed)) +
1937  		nla_attr_size(sizeof(stainfo->tx_retry_exhaust)) +
1938  		nla_attr_size(sizeof(stainfo->tx_total_fw)) +
1939  		nla_attr_size(sizeof(stainfo->tx_retry_fw)) +
1940  		nla_attr_size(sizeof(stainfo->tx_retry_exhaust_fw)) +
1941  		nla_attr_size(sizeof(stainfo->rx_fcs_count)) +
1942  		tx_count_size + rx_count_size);
1943  }
1944  
1945  /**
1946   * hdd_get_pmf_bcn_protect_stats_len() - get pmf bcn protect counters len
1947   * @link_info: pointer to link_info struct in adapter
1948   *
1949   * This function calculates the data length for valid pmf bcn counters.
1950   *
1951   * Return: total data length used in hdd_add_peer_stats()
1952   */
1953  static uint32_t
hdd_get_pmf_bcn_protect_stats_len(struct wlan_hdd_link_info * link_info)1954  hdd_get_pmf_bcn_protect_stats_len(struct wlan_hdd_link_info *link_info)
1955  {
1956  	if (!link_info->hdd_stats.bcn_protect_stats.pmf_bcn_stats_valid)
1957  		return 0;
1958  
1959  	/* 4 pmf becon protect counters each of 32 bit */
1960  	return nla_total_size(sizeof(uint32_t)) * 4;
1961  }
1962  
1963  static uint32_t
hdd_get_connect_fail_reason_code_len(struct hdd_adapter * adapter)1964  hdd_get_connect_fail_reason_code_len(struct hdd_adapter *adapter)
1965  {
1966  	if (adapter->connect_req_status == STATUS_SUCCESS)
1967  		return 0;
1968  
1969  	return nla_total_size(sizeof(uint32_t));
1970  }
1971  
1972  /**
1973   * hdd_add_pmf_bcn_protect_stats() - add pmf bcn protect counters in resp
1974   * @skb: pointer to response skb buffer
1975   * @link_info: Pointer to link_info holding valid bcn protect counters
1976   *
1977   * This function adds the pmf bcn stats in response.
1978   *
1979   * Return: 0 on success
1980   */
1981  static int
hdd_add_pmf_bcn_protect_stats(struct sk_buff * skb,struct wlan_hdd_link_info * link_info)1982  hdd_add_pmf_bcn_protect_stats(struct sk_buff *skb,
1983  			      struct wlan_hdd_link_info *link_info)
1984  {
1985  	struct hdd_stats *hdd_stats = &link_info->hdd_stats;
1986  
1987  	if (!hdd_stats->bcn_protect_stats.pmf_bcn_stats_valid)
1988  		return 0;
1989  
1990  	hdd_stats->bcn_protect_stats.pmf_bcn_stats_valid = 0;
1991  	if (nla_put_u32(skb, STA_INFO_BIP_MIC_ERROR_COUNT,
1992  			hdd_stats->bcn_protect_stats.igtk_mic_fail_cnt) ||
1993  	    nla_put_u32(skb, STA_INFO_BIP_REPLAY_COUNT,
1994  			hdd_stats->bcn_protect_stats.igtk_replay_cnt) ||
1995  	    nla_put_u32(skb, STA_INFO_BEACON_MIC_ERROR_COUNT,
1996  			hdd_stats->bcn_protect_stats.bcn_mic_fail_cnt) ||
1997  	    nla_put_u32(skb, STA_INFO_BEACON_REPLAY_COUNT,
1998  			hdd_stats->bcn_protect_stats.bcn_replay_cnt)) {
1999  		hdd_err("put fail");
2000  		return -EINVAL;
2001  	}
2002  
2003  	return 0;
2004  }
2005  
2006  #ifdef WLAN_FEATURE_BIG_DATA_STATS
2007  /**
2008   * hdd_get_big_data_stats_len - get data length used in
2009   * hdd_big_data_pack_resp_nlmsg()
2010   * @link_info: Link info pointer in HDD adapter.
2011   *
2012   * This function calculates the data length used in
2013   * hdd_big_data_pack_resp_nlmsg()
2014   *
2015   * Return: total data length used in hdd_big_data_pack_resp_nlmsg()
2016   */
2017  static uint32_t
hdd_get_big_data_stats_len(struct wlan_hdd_link_info * link_info)2018  hdd_get_big_data_stats_len(struct wlan_hdd_link_info *link_info)
2019  {
2020  	uint32_t len;
2021  	struct big_data_stats_event *big_data_stats =
2022  					&link_info->big_data_stats;
2023  
2024  	len = nla_total_size(sizeof(big_data_stats->last_tx_data_rate_kbps)) +
2025  	      nla_total_size(sizeof(big_data_stats->target_power_ofdm)) +
2026  	      nla_total_size(sizeof(big_data_stats->target_power_dsss)) +
2027  	      nla_total_size(sizeof(big_data_stats->last_tx_data_rix)) +
2028  	      nla_total_size(sizeof(big_data_stats->tsf_out_of_sync)) +
2029  	      nla_total_size(sizeof(big_data_stats->ani_level)) +
2030  	      nla_total_size(sizeof(big_data_stats->last_data_tx_pwr));
2031  
2032  	/** Add len of roam params **/
2033  	len += nla_total_size(sizeof(uint32_t)) * 3;
2034  
2035  	return len;
2036  }
2037  
2038  /**
2039   * hdd_big_data_pack_resp_nlmsg() - pack big data nl resp msg
2040   * @skb: pointer to response skb buffer
2041   * @link_info: Link info pointer in HDD adapter
2042   *
2043   * This function adds big data stats in response.
2044   *
2045   * Return: 0 on success
2046   */
hdd_big_data_pack_resp_nlmsg(struct sk_buff * skb,struct wlan_hdd_link_info * link_info)2047  static int hdd_big_data_pack_resp_nlmsg(struct sk_buff *skb,
2048  					struct wlan_hdd_link_info *link_info)
2049  {
2050  	struct hdd_station_ctx *hdd_sta_ctx;
2051  	struct hdd_context *hdd_ctx = link_info->adapter->hdd_ctx;
2052  	struct big_data_stats_event *big_data_stats =
2053  					&link_info->big_data_stats;
2054  
2055  	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
2056  	if (!hdd_sta_ctx) {
2057  		hdd_err("Invalid station context");
2058  		return -EINVAL;
2059  	}
2060  	if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_TX_RATE,
2061  			big_data_stats->last_tx_data_rate_kbps)){
2062  		hdd_err("latest tx rate put fail");
2063  		return -EINVAL;
2064  	}
2065  
2066  	if (WLAN_REG_IS_5GHZ_CH_FREQ(hdd_sta_ctx->cache_conn_info.chan_freq)) {
2067  		if (nla_put_u32(
2068  			skb,
2069  			QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_POWER_5G_6MBPS,
2070  			big_data_stats->target_power_ofdm)){
2071  			hdd_err("5G ofdm power put fail");
2072  			return -EINVAL;
2073  		}
2074  	} else if (WLAN_REG_IS_24GHZ_CH_FREQ(
2075  				hdd_sta_ctx->cache_conn_info.chan_freq)){
2076  		if (nla_put_u32(
2077  		       skb,
2078  		       QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_POWER_24G_6MBPS,
2079  		       big_data_stats->target_power_ofdm)){
2080  			hdd_err("2.4G ofdm power put fail");
2081  			return -EINVAL;
2082  		}
2083  		if (nla_put_u32(
2084  		       skb,
2085  		       QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_POWER_24G_1MBPS,
2086  		       big_data_stats->target_power_dsss)){
2087  			hdd_err("target power dsss put fail");
2088  			return -EINVAL;
2089  		}
2090  	}
2091  
2092  	if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_RIX,
2093  			big_data_stats->last_tx_data_rix)){
2094  		hdd_err("last rix rate put fail");
2095  		return -EINVAL;
2096  	}
2097  	if (nla_put_u32(skb,
2098  			QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TSF_OUT_OF_SYNC_COUNT,
2099  			big_data_stats->tsf_out_of_sync)){
2100  		hdd_err("tsf out of sync put fail");
2101  		return -EINVAL;
2102  	}
2103  	if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ANI_LEVEL,
2104  			big_data_stats->ani_level)){
2105  		hdd_err("ani level put fail");
2106  		return -EINVAL;
2107  	}
2108  	if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_TX_POWER,
2109  			big_data_stats->last_data_tx_pwr)){
2110  		hdd_err("last data tx power put fail");
2111  		return -EINVAL;
2112  	}
2113  	if (nla_put_u32(skb,
2114  			QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_TRIGGER_REASON,
2115  			wlan_cm_get_roam_states(hdd_ctx->psoc,
2116  						link_info->vdev_id,
2117  						ROAM_TRIGGER_REASON))){
2118  		hdd_err("roam trigger reason put fail");
2119  		return -EINVAL;
2120  	}
2121  	if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_FAIL_REASON,
2122  			wlan_cm_get_roam_states(hdd_ctx->psoc,
2123  						link_info->vdev_id,
2124  						ROAM_FAIL_REASON))){
2125  		hdd_err("roam fail reason put fail");
2126  		return -EINVAL;
2127  	}
2128  	if (nla_put_u32(
2129  		      skb,
2130  		      QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_INVOKE_FAIL_REASON,
2131  		      wlan_cm_get_roam_states(hdd_ctx->psoc,
2132  					      link_info->vdev_id,
2133  					      ROAM_INVOKE_FAIL_REASON))){
2134  		hdd_err("roam invoke fail reason put fail");
2135  		return -EINVAL;
2136  	}
2137  
2138  	return 0;
2139  }
2140  
2141  /**
2142   * hdd_reset_roam_params() - reset roam params
2143   * @psoc: psoc
2144   * @vdev_id: vdev id
2145   *
2146   * This function resets big data roam params
2147   *
2148   * Return: None
2149   */
2150  static void
hdd_reset_roam_params(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)2151  hdd_reset_roam_params(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
2152  {
2153  	wlan_cm_update_roam_states(psoc, vdev_id,
2154  				   0, ROAM_TRIGGER_REASON);
2155  	wlan_cm_update_roam_states(psoc, vdev_id,
2156  				   0, ROAM_FAIL_REASON);
2157  	wlan_cm_update_roam_states(psoc, vdev_id,
2158  				   0, ROAM_INVOKE_FAIL_REASON);
2159  }
2160  #else
2161  static inline int
hdd_big_data_pack_resp_nlmsg(struct sk_buff * skb,struct wlan_hdd_link_info * link_info)2162  hdd_big_data_pack_resp_nlmsg(struct sk_buff *skb,
2163  			     struct wlan_hdd_link_info *link_info)
2164  {
2165  	return 0;
2166  }
2167  
2168  static uint32_t
hdd_get_big_data_stats_len(struct wlan_hdd_link_info * link_info)2169  hdd_get_big_data_stats_len(struct wlan_hdd_link_info *link_info)
2170  {
2171  	return 0;
2172  }
2173  
2174  static void
hdd_reset_roam_params(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)2175  hdd_reset_roam_params(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
2176  {}
2177  #endif
2178  
2179  /**
2180   * hdd_add_connect_fail_reason_code() - Fills connect fail reason code
2181   * @skb: pointer to skb
2182   * @adapter: pointer to hdd adapter
2183   *
2184   * Return: on success 0 else error code
2185   */
hdd_add_connect_fail_reason_code(struct sk_buff * skb,struct hdd_adapter * adapter)2186  static int hdd_add_connect_fail_reason_code(struct sk_buff *skb,
2187  					    struct hdd_adapter *adapter)
2188  {
2189  	uint32_t reason;
2190  
2191  	reason = osif_cm_mac_to_qca_connect_fail_reason(
2192  					adapter->connect_req_status);
2193  	if (!reason)
2194  		return 0;
2195  
2196  	if (nla_put_u32(skb, STA_INFO_CONNECT_FAIL_REASON_CODE, reason)) {
2197  		hdd_err("put fail");
2198  		return -EINVAL;
2199  	}
2200  
2201  	return 0;
2202  }
2203  
2204  /**
2205   * hdd_add_peer_stats - add peer statistics information
2206   * @skb: pointer to response skb buffer
2207   * @stainfo: station information
2208   *
2209   * This function adds peer statistics information to response skb buffer
2210   *
2211   * Return : 0 on success and errno on failure
2212   */
hdd_add_peer_stats(struct sk_buff * skb,struct hdd_station_info * stainfo)2213  static int hdd_add_peer_stats(struct sk_buff *skb,
2214  			      struct hdd_station_info *stainfo)
2215  {
2216  	struct nlattr *nla_attr;
2217  	uint8_t i;
2218  
2219  	if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_RETRY_COUNT,
2220  			stainfo->rx_retry_cnt)) {
2221  		hdd_err("Failed to put rx_retry_cnt");
2222  		goto fail;
2223  	}
2224  
2225  	if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_BC_MC_COUNT,
2226  			stainfo->rx_mc_bc_cnt)) {
2227  		hdd_err("Failed to put rx_mc_bc_cnt");
2228  		goto fail;
2229  	}
2230  
2231  	if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_RETRY_SUCCEED,
2232  			stainfo->tx_retry_succeed)) {
2233  		hdd_err("Failed to put tx_retry_succeed");
2234  		goto fail;
2235  	}
2236  
2237  	if (nla_put_u32(skb,
2238  			QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_RETRY_EXHAUSTED,
2239  			stainfo->tx_retry_exhaust)) {
2240  		hdd_err("Failed to put tx_retry_exhaust");
2241  		goto fail;
2242  	}
2243  
2244  	if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_TX_TOTAL,
2245  			stainfo->tx_total_fw)) {
2246  		hdd_err("Failed to put tx_total_fw");
2247  		goto fail;
2248  	}
2249  
2250  	if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_TX_RETRY,
2251  			stainfo->tx_retry_fw)) {
2252  		hdd_err("Failed to put tx_retry_fw");
2253  		goto fail;
2254  	}
2255  
2256  	if (nla_put_u32(skb,
2257  		    QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_TX_RETRY_EXHAUSTED,
2258  		    stainfo->tx_retry_exhaust_fw)) {
2259  		hdd_err("Failed to put tx_retry_exhaust_fw");
2260  		goto fail;
2261  	}
2262  
2263  	if (nla_put_u32(skb,
2264  		     QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_FRAMES_CRC_FAIL_COUNT,
2265  		     stainfo->rx_fcs_count)) {
2266  		hdd_err("Failed to put rx_fcs_count");
2267  		goto fail;
2268  	}
2269  
2270  	nla_attr = nla_nest_start(skb,
2271  			QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_PER_MCS_TX_PACKETS);
2272  	if (!nla_attr) {
2273  		hdd_err("nla nest start for tx packets fail");
2274  		goto fail;
2275  	}
2276  
2277  	for (i = 0; i < stainfo->num_tx_rate_count; i++)
2278  		if (nla_put_u32(skb,
2279  			QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_PER_MCS_TX_PACKETS,
2280  			stainfo->tx_pkt_per_mcs[i])) {
2281  			hdd_err("Failed to put tx_rate_count for MCS[%d]", i);
2282  			goto fail;
2283  		}
2284  	nla_nest_end(skb, nla_attr);
2285  
2286  	nla_attr = nla_nest_start(skb,
2287  			QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_PER_MCS_RX_PACKETS);
2288  	if (!nla_attr) {
2289  		hdd_err("nla nest start for rx packets fail");
2290  		goto fail;
2291  	}
2292  
2293  	for (i = 0; i < stainfo->num_rx_rate_count; i++)
2294  		if (nla_put_u32(skb,
2295  			QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_PER_MCS_TX_PACKETS,
2296  			stainfo->rx_pkt_per_mcs[i])) {
2297  			hdd_err("Failed to put rx_rate_count for MCS[%d]", i);
2298  			goto fail;
2299  		}
2300  	nla_nest_end(skb, nla_attr);
2301  
2302  	hdd_free_tx_rx_pkts_per_mcs(stainfo);
2303  	return 0;
2304  fail:
2305  	hdd_free_tx_rx_pkts_per_mcs(stainfo);
2306  	return -EINVAL;
2307  }
2308  
2309  /**
2310   * hdd_get_connected_station_info_ex() - get connected peer's info
2311   * @hdd_ctx: hdd context
2312   * @adapter: hostapd interface
2313   * @stainfo: pointer to hdd_station_info
2314   *
2315   * This function collect and indicate the connected peer's info
2316   *
2317   * Return: 0 on success, otherwise error value
2318   */
hdd_get_connected_station_info_ex(struct hdd_context * hdd_ctx,struct hdd_adapter * adapter,struct hdd_station_info * stainfo)2319  static int hdd_get_connected_station_info_ex(struct hdd_context *hdd_ctx,
2320  					     struct hdd_adapter *adapter,
2321  					     struct hdd_station_info *stainfo)
2322  {
2323  	struct sk_buff *skb = NULL;
2324  	uint32_t nl_buf_len, guard_interval;
2325  	bool sap_get_peer_info;
2326  	struct nl80211_sta_flag_update sta_flags = {0};
2327  	const uint8_t *mac_addr;
2328  	QDF_STATUS status;
2329  
2330  	if (hdd_get_peer_stats(adapter, stainfo)) {
2331  		hdd_err_rl("hdd_get_peer_stats fail");
2332  		return -EINVAL;
2333  	}
2334  
2335  	nl_buf_len = NLMSG_HDRLEN;
2336  	nl_buf_len += nla_attr_size(QDF_MAC_ADDR_SIZE);
2337  	status = ucfg_mlme_get_sap_get_peer_info(hdd_ctx->psoc,
2338  						 &sap_get_peer_info);
2339  	if (status != QDF_STATUS_SUCCESS)
2340  		hdd_err_rl("Unable to fetch sap ger peer info");
2341  
2342  	if (sap_get_peer_info)
2343  		nl_buf_len += hdd_add_peer_stats_get_len(stainfo);
2344  
2345  	if (stainfo->mode > SIR_SME_PHY_MODE_LEGACY)
2346  		nl_buf_len += nla_attr_size(sizeof(sta_flags)) +
2347  			      nla_attr_size(sizeof(guard_interval));
2348  
2349  	skb = wlan_cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy,
2350  						       nl_buf_len);
2351  	if (!skb) {
2352  		hdd_err_rl("wlan_cfg80211_vendor_cmd_alloc_reply_skb failed");
2353  		return -ENOMEM;
2354  	}
2355  
2356  	if (qdf_is_macaddr_zero(&stainfo->mld_addr))
2357  		mac_addr = &stainfo->sta_mac.bytes[0];
2358  	else
2359  		mac_addr = &stainfo->mld_addr.bytes[0];
2360  
2361  	if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAC,
2362  		    QDF_MAC_ADDR_SIZE, mac_addr)) {
2363  		hdd_err_rl("Failed to put MAC address");
2364  		goto fail;
2365  	}
2366  
2367  	if (sap_get_peer_info && hdd_add_peer_stats(skb, stainfo)) {
2368  		hdd_err_rl("hdd_add_peer_stats fail");
2369  		goto fail;
2370  	}
2371  
2372  	if (stainfo->mode > SIR_SME_PHY_MODE_LEGACY) {
2373  		sta_flags.mask = QCA_VENDOR_WLAN_STA_FLAG_AMPDU |
2374  				 QCA_VENDOR_WLAN_STA_FLAG_TX_STBC |
2375  				 QCA_VENDOR_WLAN_STA_FLAG_RX_STBC;
2376  
2377  		if (stainfo->ampdu)
2378  			sta_flags.set |= QCA_VENDOR_WLAN_STA_FLAG_AMPDU;
2379  		if (stainfo->tx_stbc)
2380  			sta_flags.set |= QCA_VENDOR_WLAN_STA_FLAG_TX_STBC;
2381  		if (stainfo->rx_stbc)
2382  			sta_flags.set |= QCA_VENDOR_WLAN_STA_FLAG_RX_STBC;
2383  
2384  		if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_FLAGS,
2385  			    sizeof(sta_flags), &sta_flags)) {
2386  			hdd_err_rl("Failed to put STA flags");
2387  			goto fail;
2388  		}
2389  
2390  		switch (stainfo->guard_interval) {
2391  		case TXRATE_GI_0_8_US:
2392  			guard_interval = QCA_VENDOR_WLAN_STA_GI_800_NS;
2393  			break;
2394  		case TXRATE_GI_0_4_US:
2395  			guard_interval = QCA_VENDOR_WLAN_STA_GI_400_NS;
2396  			break;
2397  		case TXRATE_GI_1_6_US:
2398  			guard_interval = QCA_VENDOR_WLAN_STA_GI_1600_NS;
2399  			break;
2400  		case TXRATE_GI_3_2_US:
2401  			guard_interval = QCA_VENDOR_WLAN_STA_GI_3200_NS;
2402  			break;
2403  		default:
2404  			hdd_err_rl("Invalid guard_interval %d",
2405  				   stainfo->guard_interval);
2406  			goto fail;
2407  		}
2408  
2409  		if (nla_put_u32(skb,
2410  			       QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_GUARD_INTERVAL,
2411  			       guard_interval)) {
2412  			hdd_err_rl("Failed to put guard_interval");
2413  			goto fail;
2414  		}
2415  	}
2416  
2417  	return wlan_cfg80211_vendor_cmd_reply(skb);
2418  
2419  fail:
2420  	wlan_cfg80211_vendor_free_skb(skb);
2421  	return -EINVAL;
2422  }
2423  
2424  /**
2425   * hdd_get_station_remote_ex() - get remote peer's info, for SAP/GO mode only
2426   * @hdd_ctx: hdd context
2427   * @adapter: hostapd interface
2428   * @mac_addr: mac address of requested peer
2429   *
2430   * This function collect and indicate the remote peer's info
2431   *
2432   * Return: 0 on success, otherwise error value
2433   */
hdd_get_station_remote_ex(struct hdd_context * hdd_ctx,struct hdd_adapter * adapter,struct qdf_mac_addr mac_addr)2434  static int hdd_get_station_remote_ex(struct hdd_context *hdd_ctx,
2435  				     struct hdd_adapter *adapter,
2436  				     struct qdf_mac_addr mac_addr)
2437  {
2438  	struct hdd_station_info *stainfo =
2439  				hdd_get_sta_info_by_mac(&adapter->sta_info_list,
2440  					       mac_addr.bytes,
2441  					       STA_INFO_HDD_GET_STATION_REMOTE);
2442  	int status;
2443  
2444  	/* For now, only connected STAs are supported */
2445  	if (!stainfo) {
2446  		hdd_err_rl("Failed to get peer STA " QDF_MAC_ADDR_FMT,
2447  			   QDF_MAC_ADDR_REF(mac_addr.bytes));
2448  		return -ENXIO;
2449  	}
2450  
2451  	status = hdd_get_connected_station_info_ex(hdd_ctx, adapter, stainfo);
2452  	hdd_put_sta_info_ref(&adapter->sta_info_list, &stainfo, true,
2453  			     STA_INFO_HDD_GET_STATION_REMOTE);
2454  
2455  	return status;
2456  }
2457  
2458  /**
2459   * hdd_get_station_info_ex() - send STA info to userspace, for STA mode only
2460   * @link_info: Pointer of link info in HDD adapter.
2461   *
2462   * Return: 0 if success else error status
2463   */
hdd_get_station_info_ex(struct wlan_hdd_link_info * link_info)2464  static int hdd_get_station_info_ex(struct wlan_hdd_link_info *link_info)
2465  {
2466  	struct hdd_adapter *adapter = link_info->adapter;
2467  	struct hdd_context *hdd_ctx = adapter->hdd_ctx;
2468  	struct sk_buff *skb;
2469  	uint32_t nl_buf_len = 0, connect_fail_rsn_len;
2470  	struct hdd_station_ctx *hdd_sta_ctx;
2471  	bool big_data_stats_req = false;
2472  	bool big_data_fw_support = false;
2473  	int ret;
2474  
2475  	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
2476  	ucfg_mc_cp_get_big_data_fw_support(hdd_ctx->psoc, &big_data_fw_support);
2477  
2478  	if (hdd_cm_is_disconnected(link_info) && big_data_fw_support)
2479  		big_data_stats_req = true;
2480  
2481  	if (wlan_hdd_get_station_stats(link_info))
2482  		hdd_err_rl("wlan_hdd_get_station_stats fail");
2483  
2484  	wlan_hdd_get_peer_rx_rate_stats(link_info);
2485  
2486  	if (big_data_stats_req) {
2487  		if (wlan_hdd_get_big_data_station_stats(link_info)) {
2488  			hdd_err_rl("wlan_hdd_get_big_data_station_stats fail");
2489  			return -EINVAL;
2490  		}
2491  		nl_buf_len = hdd_get_big_data_stats_len(link_info);
2492  	}
2493  
2494  	nl_buf_len += hdd_get_pmf_bcn_protect_stats_len(link_info);
2495  	connect_fail_rsn_len = hdd_get_connect_fail_reason_code_len(adapter);
2496  	nl_buf_len += connect_fail_rsn_len;
2497  	nl_buf_len += hdd_get_uplink_delay_len(adapter);
2498  	if (!nl_buf_len) {
2499  		hdd_err_rl("Failed to get bcn pmf stats");
2500  		return -EINVAL;
2501  	}
2502  
2503  	nl_buf_len += NLMSG_HDRLEN;
2504  	skb = wlan_cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy,
2505  						       nl_buf_len);
2506  	if (!skb) {
2507  		hdd_err_rl("wlan_cfg80211_vendor_cmd_alloc_reply_skb failed");
2508  		return -ENOMEM;
2509  	}
2510  
2511  	if (hdd_add_pmf_bcn_protect_stats(skb, link_info)) {
2512  		hdd_err_rl("hdd_add_pmf_bcn_protect_stats fail");
2513  		wlan_cfg80211_vendor_free_skb(skb);
2514  		return -EINVAL;
2515  	}
2516  
2517  	if (connect_fail_rsn_len) {
2518  		if (hdd_add_connect_fail_reason_code(skb, adapter)) {
2519  			hdd_err_rl("hdd_add_connect_fail_reason_code fail");
2520  			wlan_cfg80211_vendor_free_skb(skb);
2521  			return -ENOMEM;
2522  		}
2523  	}
2524  
2525  	if (big_data_stats_req) {
2526  		if (hdd_big_data_pack_resp_nlmsg(skb, link_info)) {
2527  			wlan_cfg80211_vendor_free_skb(skb);
2528  			return -EINVAL;
2529  		}
2530  	}
2531  
2532  	if (QDF_IS_STATUS_ERROR(hdd_add_uplink_delay(adapter, skb))) {
2533  		hdd_err_rl("hdd_add_uplink_delay fail");
2534  		wlan_cfg80211_vendor_free_skb(skb);
2535  		return -EINVAL;
2536  	}
2537  
2538  	ret = wlan_cfg80211_vendor_cmd_reply(skb);
2539  	hdd_reset_roam_params(hdd_ctx->psoc, link_info->vdev_id);
2540  	return ret;
2541  }
2542  
2543  /**
2544   * __hdd_cfg80211_get_sta_info_cmd() - Handle get sta info vendor cmd
2545   * @wiphy: pointer to wireless phy
2546   * @wdev: wireless device
2547   * @data: data
2548   * @data_len: data length
2549   *
2550   * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO.
2551   * Validate cmd attributes and send the station info to upper layers.
2552   *
2553   * Return: Success(0) or reason code for failure
2554   */
2555  static int
__hdd_cfg80211_get_sta_info_cmd(struct wiphy * wiphy,struct wireless_dev * wdev,const void * data,int data_len)2556  __hdd_cfg80211_get_sta_info_cmd(struct wiphy *wiphy,
2557  				struct wireless_dev *wdev,
2558  				const void *data,
2559  				int data_len)
2560  {
2561  	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
2562  	struct net_device *dev = wdev->netdev;
2563  	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
2564  	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX + 1];
2565  	struct qdf_mac_addr mac_addr;
2566  	int32_t status;
2567  
2568  	hdd_enter_dev(dev);
2569  
2570  	if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE ||
2571  	    hdd_get_conparam() == QDF_GLOBAL_MONITOR_MODE) {
2572  		hdd_err_rl("Command not allowed in FTM / Monitor mode");
2573  		status = -EPERM;
2574  		goto out;
2575  	}
2576  
2577  	status = wlan_hdd_validate_context(hdd_ctx);
2578  	if (status != 0)
2579  		goto out;
2580  
2581  	status = wlan_cfg80211_nla_parse(tb,
2582  					 QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX,
2583  					 data, data_len,
2584  					 hdd_get_sta_policy);
2585  	if (status) {
2586  		hdd_err_rl("Invalid ATTR");
2587  		goto out;
2588  	}
2589  
2590  	switch (adapter->device_mode) {
2591  	case QDF_STA_MODE:
2592  	case QDF_P2P_CLIENT_MODE:
2593  		status = hdd_get_station_info_ex(adapter->deflink);
2594  		break;
2595  	case QDF_SAP_MODE:
2596  	case QDF_P2P_GO_MODE:
2597  		if (!tb[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAC]) {
2598  			hdd_err_rl("MAC address is not present");
2599  			status = -EINVAL;
2600  			goto out;
2601  		}
2602  
2603  		nla_memcpy(mac_addr.bytes,
2604  			   tb[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAC],
2605  			   QDF_MAC_ADDR_SIZE);
2606  		hdd_debug("STA " QDF_MAC_ADDR_FMT,
2607  			  QDF_MAC_ADDR_REF(mac_addr.bytes));
2608  		status = hdd_get_station_remote_ex(hdd_ctx, adapter, mac_addr);
2609  		break;
2610  	default:
2611  		hdd_err_rl("Invalid device_mode: %d", adapter->device_mode);
2612  		status = -EINVAL;
2613  		goto out;
2614  	}
2615  
2616  	hdd_exit();
2617  out:
2618  	return status;
2619  }
2620  
hdd_cfg80211_get_sta_info_cmd(struct wiphy * wiphy,struct wireless_dev * wdev,const void * data,int data_len)2621  int32_t hdd_cfg80211_get_sta_info_cmd(struct wiphy *wiphy,
2622  				      struct wireless_dev *wdev,
2623  				      const void *data,
2624  				      int data_len)
2625  {
2626  	struct osif_vdev_sync *vdev_sync;
2627  	int errno;
2628  
2629  	errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync);
2630  	if (errno)
2631  		return errno;
2632  
2633  	errno = wlan_hdd_qmi_get_sync_resume();
2634  	if (errno) {
2635  		hdd_err("qmi sync resume failed: %d", errno);
2636  		goto end;
2637  	}
2638  
2639  	errno = __hdd_cfg80211_get_sta_info_cmd(wiphy, wdev, data, data_len);
2640  
2641  	wlan_hdd_qmi_put_suspend();
2642  
2643  end:
2644  	osif_vdev_sync_op_stop(vdev_sync);
2645  
2646  	return errno;
2647  }
2648  
2649