summaryrefslogtreecommitdiff
path: root/umac
diff options
context:
space:
mode:
authorLiangwei Dong <liangwei@codeaurora.org>2018-01-19 00:47:14 -0500
committersnandini <snandini@codeaurora.org>2018-02-09 00:42:25 -0800
commitbc685e88f13f625656e60e5c137d4997c9fd6839 (patch)
tree0206528da351755ddc0758d30f29f63312797180 /umac
parentf70a37bb90da6f05c97c88906dc2d2ad43433278 (diff)
downloadqca-wfi-host-cmn-bc685e88f13f625656e60e5c137d4997c9fd6839.tar.gz
qcacmn: Add 80211W support to P2P component
Newly designed P2P component doesn't contain 80211W PMF related information which is one of the mandatory requirement to make PMF work for P2P. Provide PMF support to P2P component by adding necessary callbacks to protocol stack to get 11W related information. Change-Id: I399f0d296f9461239ac9d720905b196e87983f29 CRs-Fixed: 2175898
Diffstat (limited to 'umac')
-rw-r--r--umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h4
-rw-r--r--umac/cmn_services/mgmt_txrx/dispatcher/src/wlan_mgmt_txrx_tgt_api.c15
-rw-r--r--umac/p2p/core/src/wlan_p2p_main.h4
-rw-r--r--umac/p2p/core/src/wlan_p2p_off_chan_tx.c146
-rw-r--r--umac/p2p/core/src/wlan_p2p_off_chan_tx.h4
-rw-r--r--umac/p2p/dispatcher/inc/wlan_p2p_public_struct.h10
-rw-r--r--umac/p2p/dispatcher/inc/wlan_p2p_ucfg_api.h15
-rw-r--r--umac/p2p/dispatcher/src/wlan_p2p_ucfg_api.c26
8 files changed, 192 insertions, 32 deletions
diff --git a/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h b/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h
index 9c08e3648..a196ac51f 100644
--- a/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h
+++ b/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h
@@ -25,6 +25,10 @@
#include <qdf_types.h>
#include <osdep.h>
+#define IEEE80211_CCMP_HEADERLEN 8
+#define IEEE80211_CCMP_MICLEN 8
+#define IEEE80211_FC1_WEP 0x40
+
#define WLAN_SEQ_SEQ_SHIFT 4
#define P2P_WFA_OUI {0x50, 0x6f, 0x9a}
diff --git a/umac/cmn_services/mgmt_txrx/dispatcher/src/wlan_mgmt_txrx_tgt_api.c b/umac/cmn_services/mgmt_txrx/dispatcher/src/wlan_mgmt_txrx_tgt_api.c
index 59981c830..d82a136ee 100644
--- a/umac/cmn_services/mgmt_txrx/dispatcher/src/wlan_mgmt_txrx_tgt_api.c
+++ b/umac/cmn_services/mgmt_txrx/dispatcher/src/wlan_mgmt_txrx_tgt_api.c
@@ -869,17 +869,24 @@ QDF_STATUS tgt_mgmt_txrx_rx_frame_handler(
/* mpdu_data_ptr is pointer to action header */
mpdu_data_ptr = (uint8_t *)qdf_nbuf_data(buf) +
sizeof(struct ieee80211_frame);
+ if ((wh->i_fc[1] & IEEE80211_FC1_WEP) &&
+ (mgmt_subtype == MGMT_SUBTYPE_ACTION) &&
+ !qdf_is_macaddr_group((struct qdf_mac_addr *)wh->i_addr1) &&
+ !qdf_is_macaddr_broadcast((struct qdf_mac_addr *)wh->i_addr1))
+ mpdu_data_ptr += IEEE80211_CCMP_HEADERLEN;
+
frm_type = mgmt_txrx_get_frm_type(mgmt_subtype, mpdu_data_ptr);
if (frm_type == MGMT_FRM_UNSPECIFIED) {
- mgmt_txrx_err("Unspecified mgmt frame type");
+ mgmt_txrx_err("Unspecified mgmt frame type fc: %x %x",
+ wh->i_fc[0], wh->i_fc[1]);
qdf_nbuf_free(buf);
status = QDF_STATUS_E_FAILURE;
goto dec_peer_ref_cnt;
}
- mgmt_txrx_info("Rcvd mgmt frame, mgmt txrx frm type: %u"
- "seq. no.: %u, peer: %pK",
- frm_type, *(uint16_t *)wh->i_seq, peer);
+ mgmt_txrx_info("Rcvd mgmt frame, mgmt txrx frm type: %u seq. no.: %u, peer: %pK fc: %x %x",
+ frm_type, *(uint16_t *)wh->i_seq, peer, wh->i_fc[0],
+ wh->i_fc[1]);
mgmt_txrx_psoc_ctx = (struct mgmt_txrx_priv_psoc_context *)
wlan_objmgr_psoc_get_comp_private_obj(psoc,
diff --git a/umac/p2p/core/src/wlan_p2p_main.h b/umac/p2p/core/src/wlan_p2p_main.h
index c1b60d05b..17e6bedc0 100644
--- a/umac/p2p/core/src/wlan_p2p_main.h
+++ b/umac/p2p/core/src/wlan_p2p_main.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -166,6 +166,7 @@ enum p2p_connection_status {
* data to HDD
* @cancel_roc_done: Cancel roc done event
* @roc_runtime_lock: Runtime lock for roc request
+ * @p2p_cb: Callbacks to protocol stack
* @connection_status:Global P2P connection status
*/
struct p2p_soc_priv_obj {
@@ -177,6 +178,7 @@ struct p2p_soc_priv_obj {
struct p2p_start_param *start_param;
qdf_event_t cancel_roc_done;
qdf_runtime_lock_t roc_runtime_lock;
+ struct p2p_protocol_callbacks p2p_cb;
#ifdef WLAN_FEATURE_P2P_DEBUG
enum p2p_connection_status connection_status;
#endif
diff --git a/umac/p2p/core/src/wlan_p2p_off_chan_tx.c b/umac/p2p/core/src/wlan_p2p_off_chan_tx.c
index 7510af897..62ef353e7 100644
--- a/umac/p2p/core/src/wlan_p2p_off_chan_tx.c
+++ b/umac/p2p/core/src/wlan_p2p_off_chan_tx.c
@@ -495,21 +495,6 @@ static QDF_STATUS p2p_populate_mac_header(
}
/**
- * p2p_set_protected_bit() - set protected bit
- * @tx_ctx: tx context
- * @frame: pointer to frame
- *
- * This function sets protected bit of this mgmt frame
- *
- * Return: QDF_STATUS_SUCCESS - in case of success
- */
-static QDF_STATUS p2p_set_protected_bit(
- struct tx_action_context *tx_ctx, void *frame)
-{
- return QDF_STATUS_E_INVAL;
-}
-
-/**
* p2p_get_frame_type_str() - parse frame type to string
* @frame_info: frame information
*
@@ -799,7 +784,7 @@ static QDF_STATUS p2p_rx_update_connection_status(
* Return: QDF_STATUS_SUCCESS - in case of success
*/
static QDF_STATUS p2p_packet_alloc(uint16_t size, void **data,
- void **ppPacket)
+ qdf_nbuf_t *ppPacket)
{
QDF_STATUS status = QDF_STATUS_E_FAILURE;
qdf_nbuf_t nbuf;
@@ -882,7 +867,7 @@ static QDF_STATUS p2p_send_tx_conf(struct tx_action_context *tx_ctx,
* Return: QDF_STATUS_SUCCESS - in case of success
*/
static QDF_STATUS p2p_mgmt_tx(struct tx_action_context *tx_ctx,
- uint32_t buf_len, void *packet, uint8_t *frame)
+ uint32_t buf_len, qdf_nbuf_t packet, uint8_t *frame)
{
QDF_STATUS status;
mgmt_tx_download_comp_cb tx_comp_cb;
@@ -935,7 +920,7 @@ static QDF_STATUS p2p_mgmt_tx(struct tx_action_context *tx_ctx,
tx_ctx->nbuf = packet;
status = wlan_mgmt_txrx_mgmt_frame_tx(peer, tx_ctx->p2p_soc_obj,
- (qdf_nbuf_t)packet, tx_comp_cb, tx_ota_comp_cb,
+ packet, tx_comp_cb, tx_ota_comp_cb,
WLAN_UMAC_COMP_P2P, &mgmt_param);
wlan_objmgr_peer_release_ref(peer, WLAN_P2P_ID);
@@ -1353,6 +1338,120 @@ static QDF_STATUS p2p_disable_tx_timer(struct tx_action_context *tx_ctx)
}
/**
+ * is_rmf_mgmt_action_frame() - check RMF action frame by category
+ * @action_category: action frame actegory
+ *
+ * This function check the frame is robust mgmt action frame or not
+ *
+ * Return: true - if category is robust mgmt type
+ */
+static bool is_rmf_mgmt_action_frame(uint8_t action_category)
+{
+ switch (action_category) {
+ case ACTION_CATEGORY_SPECTRUM_MGMT:
+ case ACTION_CATEGORY_QOS:
+ case ACTION_CATEGORY_DLS:
+ case ACTION_CATEGORY_BACK:
+ case ACTION_CATEGORY_RRM:
+ case ACTION_FAST_BSS_TRNST:
+ case ACTION_CATEGORY_SA_QUERY:
+ case ACTION_CATEGORY_PROTECTED_DUAL_OF_PUBLIC_ACTION:
+ case ACTION_CATEGORY_WNM:
+ case ACTION_CATEGORY_MESH_ACTION:
+ case ACTION_CATEGORY_MULTIHOP_ACTION:
+ case ACTION_CATEGORY_DMG:
+ case ACTION_CATEGORY_FST:
+ case ACTION_CATEGORY_VENDOR_SPECIFIC_PROTECTED:
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
+
+/**
+ * p2p_populate_rmf_field() - populate unicast rmf frame
+ * @tx_ctx: tx_action_context
+ * @size: input size of frame, and output new size
+ * @ppbuf: input frame ptr, and output new frame
+ * @ppkt: input pkt, output new pkt.
+ *
+ * This function allocates new pkt for rmf frame. The
+ * new frame has extra space for ccmp field.
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success
+ */
+static QDF_STATUS p2p_populate_rmf_field(struct tx_action_context *tx_ctx,
+ uint32_t *size, uint8_t **ppbuf, qdf_nbuf_t *ppkt)
+{
+ struct wlan_frame_hdr *wh, *rmf_wh;
+ struct action_frm_hdr *action_hdr;
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+ qdf_nbuf_t pkt = NULL;
+ uint8_t *frame;
+ uint32_t frame_len;
+ struct p2p_soc_priv_obj *p2p_soc_obj;
+
+ p2p_soc_obj = tx_ctx->p2p_soc_obj;
+
+ if (tx_ctx->frame_info.sub_type != P2P_MGMT_ACTION ||
+ !p2p_soc_obj->p2p_cb.is_mgmt_protected)
+ return QDF_STATUS_SUCCESS;
+ if (*size < (sizeof(struct wlan_frame_hdr) +
+ sizeof(struct action_frm_hdr))) {
+ return QDF_STATUS_E_INVAL;
+ }
+
+ wh = (struct wlan_frame_hdr *)(*ppbuf);
+ action_hdr = (struct action_frm_hdr *)(*ppbuf + sizeof(*wh));
+
+ if (!is_rmf_mgmt_action_frame(action_hdr->action_category)) {
+ p2p_debug("non rmf act frame 0x%x cat %x",
+ tx_ctx->frame_info.sub_type,
+ action_hdr->action_category);
+ return QDF_STATUS_SUCCESS;
+ }
+
+ if (!p2p_soc_obj->p2p_cb.is_mgmt_protected(
+ tx_ctx->vdev_id, wh->i_addr1)) {
+ p2p_debug("non rmf connection vdev %d "QDF_MAC_ADDR_STR,
+ tx_ctx->vdev_id, QDF_MAC_ADDR_ARRAY(wh->i_addr1));
+ return QDF_STATUS_SUCCESS;
+ }
+ if (!qdf_is_macaddr_group((struct qdf_mac_addr *)wh->i_addr1) &&
+ !qdf_is_macaddr_broadcast((struct qdf_mac_addr *)wh->i_addr1)) {
+
+ frame_len = *size + IEEE80211_CCMP_HEADERLEN +
+ IEEE80211_CCMP_MICLEN;
+ status = p2p_packet_alloc((uint16_t)frame_len, (void **)&frame,
+ &pkt);
+ if (status != QDF_STATUS_SUCCESS) {
+ p2p_err("Failed to allocate %d bytes for rmf frame.",
+ frame_len);
+ return QDF_STATUS_E_NOMEM;
+ }
+
+ qdf_mem_copy(frame, wh, sizeof(*wh));
+ qdf_mem_copy(frame + sizeof(*wh) + IEEE80211_CCMP_HEADERLEN,
+ *ppbuf + sizeof(*wh),
+ *size - sizeof(*wh));
+ rmf_wh = (struct wlan_frame_hdr *)frame;
+ (rmf_wh)->i_fc[1] |= IEEE80211_FC1_WEP;
+ p2p_debug("set protection 0x%x cat %d "QDF_MAC_ADDR_STR,
+ tx_ctx->frame_info.sub_type,
+ action_hdr->action_category,
+ QDF_MAC_ADDR_ARRAY(wh->i_addr1));
+
+ qdf_nbuf_free(*ppkt);
+ *ppbuf = frame;
+ *ppkt = pkt;
+ *size = frame_len;
+ }
+
+ return status;
+}
+
+/**
* p2p_execute_tx_action_frame() - execute tx action frame
* @tx_ctx: tx context
*
@@ -1364,7 +1463,7 @@ static QDF_STATUS p2p_execute_tx_action_frame(
struct tx_action_context *tx_ctx)
{
uint8_t *frame;
- void *packet;
+ qdf_nbuf_t packet;
QDF_STATUS status;
uint8_t noa_len = 0;
uint8_t noa_stream[P2P_NOA_STREAM_ARR_SIZE];
@@ -1411,7 +1510,7 @@ static QDF_STATUS p2p_execute_tx_action_frame(
/* Ok-- try to allocate some memory: */
status = p2p_packet_alloc((uint16_t) buf_len, (void **)&frame,
- (void **)&packet);
+ &packet);
if (status != QDF_STATUS_SUCCESS) {
p2p_err("Failed to allocate %d bytes for a Probe Request.",
buf_len);
@@ -1439,7 +1538,12 @@ static QDF_STATUS p2p_execute_tx_action_frame(
qdf_mem_copy(frame, tx_ctx->buf, buf_len);
}
- p2p_set_protected_bit(tx_ctx, frame);
+ status = p2p_populate_rmf_field(tx_ctx, &buf_len, &frame, &packet);
+ if (status != QDF_STATUS_SUCCESS) {
+ p2p_err("failed to populate rmf frame");
+ qdf_nbuf_free(packet);
+ return status;
+ }
status = p2p_mgmt_tx(tx_ctx, buf_len, packet, frame);
if (status == QDF_STATUS_SUCCESS) {
if (tx_ctx->no_ack) {
diff --git a/umac/p2p/core/src/wlan_p2p_off_chan_tx.h b/umac/p2p/core/src/wlan_p2p_off_chan_tx.h
index 87465875f..41bdc806d 100644
--- a/umac/p2p/core/src/wlan_p2p_off_chan_tx.h
+++ b/umac/p2p/core/src/wlan_p2p_off_chan_tx.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -173,7 +173,7 @@ struct tx_action_context {
uint32_t duration;
qdf_mc_timer_t tx_timer;
struct p2p_frame_info frame_info;
- void *nbuf;
+ qdf_nbuf_t nbuf;
};
/**
diff --git a/umac/p2p/dispatcher/inc/wlan_p2p_public_struct.h b/umac/p2p/dispatcher/inc/wlan_p2p_public_struct.h
index febd25f75..4f156c633 100644
--- a/umac/p2p/dispatcher/inc/wlan_p2p_public_struct.h
+++ b/umac/p2p/dispatcher/inc/wlan_p2p_public_struct.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -215,4 +215,12 @@ struct p2p_noa_info {
struct noa_descriptor noa_desc[P2P_MAX_NOA_DESC];
};
+/**
+ * struct p2p_protocol_callbacks - callback to non-converged driver
+ * @is_mgmt_protected: func to get 11w mgmt protection status
+ */
+struct p2p_protocol_callbacks {
+ bool (*is_mgmt_protected)(uint32_t vdev_id, const uint8_t *peer_addr);
+};
+
#endif /* _WLAN_P2P_PUBLIC_STRUCT_H_ */
diff --git a/umac/p2p/dispatcher/inc/wlan_p2p_ucfg_api.h b/umac/p2p/dispatcher/inc/wlan_p2p_ucfg_api.h
index 708a4bf7e..7ef8974a7 100644
--- a/umac/p2p/dispatcher/inc/wlan_p2p_ucfg_api.h
+++ b/umac/p2p/dispatcher/inc/wlan_p2p_ucfg_api.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -298,6 +298,19 @@ QDF_STATUS ucfg_p2p_set_noa(struct wlan_objmgr_psoc *soc,
uint32_t vdev_id, bool disable_noa);
/**
+ * ucfg_p2p_register_callbacks() - register p2p callbacks
+ * @soc: soc context
+ * @cb_obj: p2p_protocol_callbacks struct
+ *
+ * This function registers lim callbacks to p2p components to provide
+ * protocol information.
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success
+ */
+QDF_STATUS ucfg_p2p_register_callbacks(struct wlan_objmgr_psoc *soc,
+ struct p2p_protocol_callbacks *cb_obj);
+
+/**
* ucfg_p2p_status_scan() - Show P2P connection status when scanning
* @vdev: vdev context
*
diff --git a/umac/p2p/dispatcher/src/wlan_p2p_ucfg_api.c b/umac/p2p/dispatcher/src/wlan_p2p_ucfg_api.c
index 4415b3cbe..8e2ea051a 100644
--- a/umac/p2p/dispatcher/src/wlan_p2p_ucfg_api.c
+++ b/umac/p2p/dispatcher/src/wlan_p2p_ucfg_api.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -23,8 +23,8 @@
#include <wmi_unified_api.h>
#include <wlan_objmgr_psoc_obj.h>
#include <scheduler_api.h>
-#include "wlan_p2p_ucfg_api.h"
#include "wlan_p2p_public_struct.h"
+#include "wlan_p2p_ucfg_api.h"
#include "../../core/src/wlan_p2p_main.h"
#include "../../core/src/wlan_p2p_roc.h"
#include "../../core/src/wlan_p2p_off_chan_tx.h"
@@ -423,6 +423,28 @@ QDF_STATUS ucfg_p2p_set_noa(struct wlan_objmgr_psoc *soc,
return status;
}
+QDF_STATUS ucfg_p2p_register_callbacks(struct wlan_objmgr_psoc *soc,
+ struct p2p_protocol_callbacks *cb_obj)
+{
+ struct p2p_soc_priv_obj *p2p_soc_obj;
+
+ if (!soc || !cb_obj) {
+ p2p_err("psoc %pM cb_obj %pM context passed is NULL", soc,
+ cb_obj);
+ return QDF_STATUS_E_INVAL;
+ }
+
+ p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(soc,
+ WLAN_UMAC_COMP_P2P);
+ if (!p2p_soc_obj) {
+ p2p_err("p2p soc private object is NULL");
+ return QDF_STATUS_E_FAILURE;
+ }
+ p2p_soc_obj->p2p_cb = *cb_obj;
+
+ return QDF_STATUS_SUCCESS;
+}
+
QDF_STATUS ucfg_p2p_status_scan(struct wlan_objmgr_vdev *vdev)
{
if (!vdev) {