|
@@ -140,13 +140,6 @@
|
|
|
#define ASSOC_REQ_IES \
|
|
|
QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_ASSOC_REQ_IES
|
|
|
|
|
|
-
|
|
|
- * it may include the beacon IEs and other miscellaneous information
|
|
|
- * in function hdd_get_station_info, malloc enough memory to save
|
|
|
- * the data.
|
|
|
- */
|
|
|
-#define WLAN_STATS_INFO_LEN 2048
|
|
|
-
|
|
|
|
|
|
* MSB of rx_mc_bc_cnt indicates whether FW supports rx_mc_bc_cnt
|
|
|
* feature or not, if first bit is 1 it indicates that FW supports this
|
|
@@ -383,6 +376,25 @@ static int hdd_convert_dot11mode(uint32_t dot11mode)
|
|
|
return ret_val;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ * hdd_calculate_tx_bitrate_ie_size - calculate tx bitrate ie size
|
|
|
+ *
|
|
|
+ * Return: tx bitrate ie size
|
|
|
+ */
|
|
|
+static uint32_t hdd_calculate_tx_bitrate_ie_size(void)
|
|
|
+{
|
|
|
+ uint32_t nl_buf_len = nla_total_size(0);
|
|
|
+
|
|
|
+
|
|
|
+ nl_buf_len += nla_total_size(sizeof(uint32_t)) +
|
|
|
+
|
|
|
+ nla_total_size(sizeof(uint16_t)) +
|
|
|
+
|
|
|
+ nla_total_size(sizeof(uint8_t));
|
|
|
+
|
|
|
+ return nl_buf_len;
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
* hdd_add_tx_bitrate() - add tx bitrate attribute
|
|
|
* @skb: pointer to sk buff
|
|
@@ -451,6 +463,22 @@ fail:
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ * hdd_calculate_sta_info_ie_size - calculate sta info size
|
|
|
+ *
|
|
|
+ * Return: sta info ie size
|
|
|
+ */
|
|
|
+static uint32_t hdd_calculate_sta_info_ie_size(void)
|
|
|
+{
|
|
|
+ uint32_t nl_buf_len = nla_total_size(0);
|
|
|
+
|
|
|
+
|
|
|
+ nl_buf_len += nla_total_size(sizeof(int8_t)) +
|
|
|
+ hdd_calculate_tx_bitrate_ie_size();
|
|
|
+
|
|
|
+ return nl_buf_len;
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
* hdd_add_sta_info() - add station info attribute
|
|
|
* @skb: pointer to sk buff
|
|
@@ -499,6 +527,23 @@ fail:
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ * hdd_calculate_survey_info_ie_size - calculate survey info size
|
|
|
+ *
|
|
|
+ * Return: survey info ie size
|
|
|
+ */
|
|
|
+static uint32_t hdd_calculate_survey_info_ie_size(void)
|
|
|
+{
|
|
|
+ uint32_t nl_buf_len = nla_total_size(0);
|
|
|
+
|
|
|
+
|
|
|
+ nl_buf_len += nla_total_size(sizeof(uint32_t)) +
|
|
|
+
|
|
|
+ nla_total_size(sizeof(int8_t));
|
|
|
+
|
|
|
+ return nl_buf_len;
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
* hdd_add_survey_info() - add survey info attribute
|
|
|
* @skb: pointer to sk buff
|
|
@@ -529,6 +574,25 @@ fail:
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ * hdd_calculate_link_standard_info_ie_size - calculate link standard info size
|
|
|
+ *
|
|
|
+ * Return: link standard info ie size
|
|
|
+ */
|
|
|
+static uint32_t hdd_calculate_link_standard_info_ie_size(void)
|
|
|
+{
|
|
|
+ uint32_t nl_buf_len = nla_total_size(0);
|
|
|
+
|
|
|
+
|
|
|
+ nl_buf_len += nla_total_size(WLAN_SSID_MAX_LEN + 1) +
|
|
|
+
|
|
|
+ nla_total_size(QDF_MAC_ADDR_SIZE) +
|
|
|
+ hdd_calculate_survey_info_ie_size() +
|
|
|
+ hdd_calculate_sta_info_ie_size();
|
|
|
+
|
|
|
+ return nl_buf_len;
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
* hdd_add_link_standard_info() - add link info attribute
|
|
|
* @skb: pointer to sk buff
|
|
@@ -585,6 +649,29 @@ fail:
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ * hdd_calculate_ap_standard_info_ie_size - calculate ap standard info size
|
|
|
+ * @hdd_sta_ctx: pointer to hdd station context
|
|
|
+ *
|
|
|
+ * Return: ap standard info size
|
|
|
+ */
|
|
|
+static uint32_t hdd_calculate_ap_standard_info_ie_size(
|
|
|
+ struct hdd_station_ctx *hdd_sta_ctx)
|
|
|
+{
|
|
|
+ uint32_t nl_buf_len = nla_total_size(0);
|
|
|
+
|
|
|
+
|
|
|
+ if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present)
|
|
|
+ nl_buf_len += nla_total_size(sizeof(
|
|
|
+ hdd_sta_ctx->cache_conn_info.vht_caps));
|
|
|
+
|
|
|
+ if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present)
|
|
|
+ nl_buf_len += nla_total_size(sizeof(
|
|
|
+ hdd_sta_ctx->cache_conn_info.ht_caps));
|
|
|
+
|
|
|
+ return nl_buf_len;
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
* hdd_add_ap_standard_info() - add ap info attribute
|
|
|
* @skb: pointer to sk buff
|
|
@@ -661,6 +748,12 @@ static int32_t hdd_add_he_oper_info(struct sk_buff *skb,
|
|
|
hdd_sta_ctx->cache_conn_info.he_oper_len = 0;
|
|
|
return ret;
|
|
|
}
|
|
|
+
|
|
|
+static int32_t hdd_get_he_op_len(struct hdd_station_ctx *hdd_sta_ctx)
|
|
|
+{
|
|
|
+ return hdd_sta_ctx->cache_conn_info.he_oper_len;
|
|
|
+}
|
|
|
+
|
|
|
#else
|
|
|
static inline uint32_t hdd_add_he_oper_info(
|
|
|
struct sk_buff *skb,
|
|
@@ -668,8 +761,19 @@ static inline uint32_t hdd_add_he_oper_info(
|
|
|
{
|
|
|
return 0;
|
|
|
}
|
|
|
+
|
|
|
+static uint32_t hdd_get_he_op_len(struct hdd_station_ctx *hdd_sta_ctx)
|
|
|
+{
|
|
|
+ return 0;
|
|
|
+}
|
|
|
#endif
|
|
|
|
|
|
+static uint32_t hdd_get_prev_connected_bss_ies_len(
|
|
|
+ struct hdd_station_ctx *hdd_sta_ctx)
|
|
|
+{
|
|
|
+ return hdd_sta_ctx->conn_info.prev_ap_bcn_ie.len;
|
|
|
+}
|
|
|
+
|
|
|
static uint32_t hdd_add_prev_connected_bss_ies(
|
|
|
struct sk_buff *skb,
|
|
|
struct hdd_station_ctx *hdd_sta_ctx)
|
|
@@ -694,43 +798,84 @@ static uint32_t hdd_add_prev_connected_bss_ies(
|
|
|
}
|
|
|
|
|
|
|
|
|
- * hdd_get_station_info() - send BSS information to supplicant
|
|
|
+ * hdd_calculate_station_info_ie_size - calculate bss ie size
|
|
|
+ * @hdd_sta_ctx: pointer to hdd station context
|
|
|
+ *
|
|
|
+ * Return: bss ie size
|
|
|
+ */
|
|
|
+static uint32_t hdd_calculate_station_info_ie_size(
|
|
|
+ struct hdd_station_ctx *hdd_sta_ctx)
|
|
|
+{
|
|
|
+
|
|
|
+ uint32_t nl_buf_len = NLA_HDRLEN;
|
|
|
+
|
|
|
+ nl_buf_len += hdd_calculate_link_standard_info_ie_size() +
|
|
|
+ hdd_calculate_ap_standard_info_ie_size(hdd_sta_ctx);
|
|
|
+
|
|
|
+
|
|
|
+ nl_buf_len += nla_total_size(sizeof(uint32_t)) +
|
|
|
+
|
|
|
+ nla_total_size(sizeof(uint32_t)) +
|
|
|
+
|
|
|
+ nla_total_size(sizeof(uint32_t));
|
|
|
+
|
|
|
+
|
|
|
+ if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present)
|
|
|
+ nl_buf_len += nla_total_size(sizeof(
|
|
|
+ hdd_sta_ctx->cache_conn_info.ht_operation));
|
|
|
+
|
|
|
+
|
|
|
+ if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present)
|
|
|
+ nl_buf_len += nla_total_size(sizeof(
|
|
|
+ hdd_sta_ctx->cache_conn_info.vht_operation));
|
|
|
+
|
|
|
+
|
|
|
+ nl_buf_len += nla_total_size(hdd_get_he_op_len(hdd_sta_ctx));
|
|
|
+
|
|
|
+
|
|
|
+ if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present)
|
|
|
+ nl_buf_len += nla_total_size(sizeof(
|
|
|
+ hdd_sta_ctx->cache_conn_info.hs20vendor_ie) - 1);
|
|
|
+
|
|
|
+
|
|
|
+ nl_buf_len += nla_total_size(sizeof(uint32_t));
|
|
|
+
|
|
|
+
|
|
|
+ if (hdd_sta_ctx->conn_info.prev_ap_bcn_ie.len)
|
|
|
+ nl_buf_len += nla_total_size(
|
|
|
+ hdd_get_prev_connected_bss_ies_len(hdd_sta_ctx));
|
|
|
+
|
|
|
+ return nl_buf_len;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+ * hdd_populate_station_info_skb - populate station info in skb
|
|
|
* @hdd_ctx: pointer to hdd context
|
|
|
+ * @skb: pointer to socket buffer
|
|
|
* @adapter: pointer to adapter
|
|
|
+ * @hdd_sta_ctx: pointer to hdd station ctx
|
|
|
*
|
|
|
- * Return: 0 if success else error status
|
|
|
+ * Return: QDF_STATUS_SUCCESS in case of success else failure
|
|
|
*/
|
|
|
-static int hdd_get_station_info(struct hdd_context *hdd_ctx,
|
|
|
- struct hdd_adapter *adapter)
|
|
|
+static QDF_STATUS hdd_populate_station_info_skb(struct hdd_context *hdd_ctx,
|
|
|
+ struct sk_buff *skb,
|
|
|
+ struct hdd_adapter *adapter,
|
|
|
+ struct hdd_station_ctx *hdd_sta_ctx)
|
|
|
{
|
|
|
- struct sk_buff *skb = NULL;
|
|
|
uint8_t *tmp_hs20 = NULL;
|
|
|
- struct hdd_station_ctx *hdd_sta_ctx;
|
|
|
-
|
|
|
- hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
|
|
|
-
|
|
|
- if (hdd_cm_is_vdev_connected(adapter)) {
|
|
|
- hdd_err("Station is connected, command is not supported");
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
-
|
|
|
- skb = wlan_cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy,
|
|
|
- WLAN_STATS_INFO_LEN);
|
|
|
- if (!skb) {
|
|
|
- hdd_err("wlan_cfg80211_vendor_cmd_alloc_reply_skb failed");
|
|
|
- return -ENOMEM;
|
|
|
- }
|
|
|
|
|
|
if (hdd_add_link_standard_info(skb, hdd_ctx, adapter,
|
|
|
LINK_INFO_STANDARD_NL80211_ATTR)) {
|
|
|
- hdd_err("put fail");
|
|
|
- goto fail;
|
|
|
+ hdd_err("link_standard_info put fail");
|
|
|
+ return QDF_STATUS_E_FAILURE;
|
|
|
}
|
|
|
+
|
|
|
if (hdd_add_ap_standard_info(skb, hdd_sta_ctx,
|
|
|
AP_INFO_STANDARD_NL80211_ATTR)) {
|
|
|
- hdd_err("put fail");
|
|
|
- goto fail;
|
|
|
+ hdd_err("ap standard info fail");
|
|
|
+ return QDF_STATUS_E_FAILURE;
|
|
|
}
|
|
|
+
|
|
|
if (nla_put_u32(skb, INFO_ROAM_COUNT,
|
|
|
hdd_sta_ctx->cache_conn_info.roam_count) ||
|
|
|
nla_put_u32(skb, INFO_AKM,
|
|
@@ -739,15 +884,16 @@ static int hdd_get_station_info(struct hdd_context *hdd_ctx,
|
|
|
nla_put_u32(skb, WLAN802_11_MODE,
|
|
|
hdd_convert_dot11mode(
|
|
|
hdd_sta_ctx->cache_conn_info.dot11mode))) {
|
|
|
- hdd_err("put fail");
|
|
|
- goto fail;
|
|
|
+ hdd_err("Roam, AKM, dot11mode put fail");
|
|
|
+ return QDF_STATUS_E_FAILURE;
|
|
|
}
|
|
|
+
|
|
|
if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present) {
|
|
|
if (nla_put(skb, HT_OPERATION,
|
|
|
(sizeof(hdd_sta_ctx->cache_conn_info.ht_operation)),
|
|
|
&hdd_sta_ctx->cache_conn_info.ht_operation)) {
|
|
|
- hdd_err("put fail");
|
|
|
- goto fail;
|
|
|
+ hdd_err("ht operation put fail");
|
|
|
+ return QDF_STATUS_E_FAILURE;
|
|
|
}
|
|
|
hdd_nofl_debug("STA HT operation:");
|
|
|
qdf_trace_hex_dump(
|
|
@@ -755,13 +901,14 @@ static int hdd_get_station_info(struct hdd_context *hdd_ctx,
|
|
|
(uint8_t *)&hdd_sta_ctx->cache_conn_info.ht_operation,
|
|
|
sizeof(hdd_sta_ctx->cache_conn_info.ht_operation));
|
|
|
}
|
|
|
+
|
|
|
if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present) {
|
|
|
if (nla_put(skb, VHT_OPERATION,
|
|
|
(sizeof(hdd_sta_ctx->
|
|
|
cache_conn_info.vht_operation)),
|
|
|
&hdd_sta_ctx->cache_conn_info.vht_operation)) {
|
|
|
- hdd_err("put fail");
|
|
|
- goto fail;
|
|
|
+ hdd_err("vht operation put fail");
|
|
|
+ return QDF_STATUS_E_FAILURE;
|
|
|
}
|
|
|
hdd_nofl_debug("STA VHT operation:");
|
|
|
qdf_trace_hex_dump(
|
|
@@ -769,10 +916,12 @@ static int hdd_get_station_info(struct hdd_context *hdd_ctx,
|
|
|
(uint8_t *)&hdd_sta_ctx->cache_conn_info.vht_operation,
|
|
|
sizeof(hdd_sta_ctx->cache_conn_info.vht_operation));
|
|
|
}
|
|
|
+
|
|
|
if (hdd_add_he_oper_info(skb, hdd_sta_ctx)) {
|
|
|
- hdd_err("put fail");
|
|
|
- goto fail;
|
|
|
+ hdd_err("he operation info put fail");
|
|
|
+ return QDF_STATUS_E_FAILURE;
|
|
|
}
|
|
|
+
|
|
|
if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present) {
|
|
|
tmp_hs20 =
|
|
|
(uint8_t *)&hdd_sta_ctx->cache_conn_info.hs20vendor_ie;
|
|
@@ -780,8 +929,8 @@ static int hdd_get_station_info(struct hdd_context *hdd_ctx,
|
|
|
(sizeof(hdd_sta_ctx->cache_conn_info.hs20vendor_ie)
|
|
|
- 1),
|
|
|
tmp_hs20 + 1)) {
|
|
|
- hdd_err("put fail");
|
|
|
- goto fail;
|
|
|
+ hdd_err("hs20 put fail");
|
|
|
+ return QDF_STATUS_E_FAILURE;
|
|
|
}
|
|
|
hdd_nofl_debug("STA hs20 vendor IE:");
|
|
|
qdf_trace_hex_dump(
|
|
@@ -793,14 +942,54 @@ static int hdd_get_station_info(struct hdd_context *hdd_ctx,
|
|
|
if (nla_put_u32(skb, DISCONNECT_REASON,
|
|
|
adapter->last_disconnect_reason)) {
|
|
|
hdd_err("Failed to put disconnect reason");
|
|
|
- goto fail;
|
|
|
+ return QDF_STATUS_E_FAILURE;
|
|
|
}
|
|
|
|
|
|
if (hdd_add_prev_connected_bss_ies(skb, hdd_sta_ctx)) {
|
|
|
- hdd_err("put fail");
|
|
|
- goto fail;
|
|
|
+ hdd_err("disconnect_reason put fail");
|
|
|
+ return QDF_STATUS_E_FAILURE;
|
|
|
+ }
|
|
|
+ return QDF_STATUS_SUCCESS;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+ * hdd_get_station_info() - send BSS information to supplicant
|
|
|
+ * @hdd_ctx: pointer to hdd context
|
|
|
+ * @adapter: pointer to adapter
|
|
|
+ *
|
|
|
+ * Return: 0 if success else error status
|
|
|
+ */
|
|
|
+static int hdd_get_station_info(struct hdd_context *hdd_ctx,
|
|
|
+ struct hdd_adapter *adapter)
|
|
|
+{
|
|
|
+ struct sk_buff *skb = NULL;
|
|
|
+ uint32_t nl_buf_len;
|
|
|
+ struct hdd_station_ctx *hdd_sta_ctx;
|
|
|
+
|
|
|
+ hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
|
|
|
+
|
|
|
+ if (hdd_cm_is_vdev_connected(adapter)) {
|
|
|
+ hdd_err("Station is connected, command is not supported");
|
|
|
+ return -EINVAL;
|
|
|
}
|
|
|
|
|
|
+ nl_buf_len = hdd_calculate_station_info_ie_size(hdd_sta_ctx);
|
|
|
+ if (!nl_buf_len) {
|
|
|
+ hdd_err("BSS ie size calculation failed");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy,
|
|
|
+ nl_buf_len);
|
|
|
+ if (!skb) {
|
|
|
+ hdd_err("wlan_cfg80211_vendor_cmd_alloc_reply_skb failed");
|
|
|
+ return -ENOMEM;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (hdd_populate_station_info_skb(hdd_ctx, skb, adapter, hdd_sta_ctx)
|
|
|
+ != QDF_STATUS_SUCCESS)
|
|
|
+ goto fail;
|
|
|
+
|
|
|
hdd_nofl_debug(
|
|
|
"STA Info:: SSID:" QDF_SSID_FMT ", BSSID:" QDF_MAC_ADDR_FMT ", freq:%d, "
|
|
|
"Noise:%d, signal:%d, roam_count:%d, last_auth_type:%d, "
|