diff options
| author | Naveen Rawat <nrawat@qca.qualcomm.com> | 2016-02-29 14:51:43 -0800 |
|---|---|---|
| committer | Anjaneedevi Kapparapu <akappa@codeaurora.org> | 2016-04-27 14:44:02 +0530 |
| commit | 65945c65ffd5638fa77d0e648b390ca01b70f098 (patch) | |
| tree | ffddcbcb4ab0d9b72c1b7ae5d73d16c3ae449b4f | |
| parent | 5fc3354e215e8de70e187c02eb22616b57ab2d2d (diff) | |
qcacld-2.0: Add support for NAN Data End Request
Add implementation of NAN Data End request.
Change-Id: Iddd22a83b0763dab2e7398f4d2cf5b9ada58225a
CRs-Fixed: 962367
| -rw-r--r-- | CORE/HDD/inc/wlan_hdd_assoc.h | 2 | ||||
| -rw-r--r-- | CORE/HDD/inc/wlan_hdd_tx_rx.h | 2 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_assoc.c | 4 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_nan_datapath.c | 181 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_nan_datapath.h | 8 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_tx_rx.c | 23 | ||||
| -rw-r--r-- | CORE/MAC/inc/sirApi.h | 16 | ||||
| -rw-r--r-- | CORE/MAC/inc/wniApi.h | 1 | ||||
| -rw-r--r-- | CORE/MAC/src/include/sirParams.h | 3 | ||||
| -rw-r--r-- | CORE/MAC/src/pe/lim/limProcessMessageQueue.c | 2 | ||||
| -rw-r--r-- | CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c | 1 | ||||
| -rw-r--r-- | CORE/MAC/src/pe/nan/nan_datapath.c | 86 | ||||
| -rw-r--r-- | CORE/SERVICES/WMA/wma.c | 4 | ||||
| -rw-r--r-- | CORE/SERVICES/WMA/wma_nan_datapath.c | 180 | ||||
| -rw-r--r-- | CORE/SERVICES/WMA/wma_nan_datapath.h | 6 | ||||
| -rw-r--r-- | CORE/SME/inc/csrApi.h | 2 | ||||
| -rw-r--r-- | CORE/SME/inc/smeInside.h | 1 | ||||
| -rw-r--r-- | CORE/SME/inc/smeInternal.h | 1 | ||||
| -rw-r--r-- | CORE/SME/inc/sme_nan_datapath.h | 25 | ||||
| -rw-r--r-- | CORE/SME/src/nan/nan_datapath_api.c | 186 | ||||
| -rw-r--r-- | CORE/SME/src/sme_common/sme_Api.c | 12 |
21 files changed, 648 insertions, 98 deletions
diff --git a/CORE/HDD/inc/wlan_hdd_assoc.h b/CORE/HDD/inc/wlan_hdd_assoc.h index 5a7f278d1953..6a1c0dacac39 100644 --- a/CORE/HDD/inc/wlan_hdd_assoc.h +++ b/CORE/HDD/inc/wlan_hdd_assoc.h @@ -49,6 +49,8 @@ /* Timeout in ms for peer info request completion */ #define IBSS_PEER_INFO_REQ_TIMOEUT 1000 +#define INVALID_PEER_IDX -1 + /** * enum eConnectionState - connection state values at HDD * @eConnectionState_NotConnected: Not associated in Infra or participating in diff --git a/CORE/HDD/inc/wlan_hdd_tx_rx.h b/CORE/HDD/inc/wlan_hdd_tx_rx.h index 9e46f119190d..a8d223ed8287 100644 --- a/CORE/HDD/inc/wlan_hdd_tx_rx.h +++ b/CORE/HDD/inc/wlan_hdd_tx_rx.h @@ -190,6 +190,8 @@ extern v_BOOL_t hdd_IsEAPOLPacket( vos_pkt_t *pVosPacket ); VOS_STATUS hdd_get_peer_sta_id(hdd_station_ctx_t *sta_ctx, v_MACADDR_t *peer_mac_addr, uint8_t *sta_id); +int hdd_get_peer_idx(hdd_station_ctx_t *sta_ctx, v_MACADDR_t *addr); + /**============================================================================ @brief hdd_flush_ibss_tx_queues() - Flush tx queues in IBSS mode diff --git a/CORE/HDD/src/wlan_hdd_assoc.c b/CORE/HDD/src/wlan_hdd_assoc.c index 99b82ca16c13..df910fbbf867 100644 --- a/CORE/HDD/src/wlan_hdd_assoc.c +++ b/CORE/HDD/src/wlan_hdd_assoc.c @@ -2404,6 +2404,9 @@ bool hdd_save_peer(hdd_station_ctx_t *sta_ctx, uint8_t sta_id, for (idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++) { if (0 == sta_ctx->conn_info.staId[idx]) { + hddLog(VOS_TRACE_LEVEL_DEBUG, + FL("adding peer: %pM, sta_id: %d, at idx: %d"), + peer_mac_addr, sta_id, idx); sta_ctx->conn_info.staId[idx] = sta_id; vos_copy_macaddr( &sta_ctx->conn_info.peerMacAddress[idx], @@ -5395,4 +5398,3 @@ int iw_get_ap_address(struct net_device *dev, struct iw_request_info *info, return ret; } - diff --git a/CORE/HDD/src/wlan_hdd_nan_datapath.c b/CORE/HDD/src/wlan_hdd_nan_datapath.c index 333a0ebc1d82..cb227e129984 100644 --- a/CORE/HDD/src/wlan_hdd_nan_datapath.c +++ b/CORE/HDD/src/wlan_hdd_nan_datapath.c @@ -58,6 +58,8 @@ qca_wlan_vendor_ndp_policy[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1] = { [QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_STATUS_CODE] = { .type = NLA_U16 }, [QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR] = { .type = NLA_BINARY, .len = VOS_MAC_ADDR_SIZE }, + [QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY] = { .type = NLA_BINARY, + .len = NDP_NUM_INSTANCE_ID }, }; /** @@ -424,10 +426,10 @@ static int hdd_ndi_delete_req_handler(hdd_context_t *hdd_ctx, return -EINVAL; } - /* check if there are active NDP sessions on the adapter */ - if (ndp_ctx->active_ndp_sessions > 0) { - hddLog(LOGE, FL("NDP sessions active %d, cannot delete NDI"), - ndp_ctx->active_ndp_sessions); + /* check if there are active peers on the adapter */ + if (ndp_ctx->active_ndp_peers > 0) { + hddLog(LOGE, FL("NDP peers active: %d, cannot delete NDI"), + ndp_ctx->active_ndp_peers); return -EINVAL; } @@ -689,9 +691,51 @@ static int hdd_ndp_responder_req_handler(hdd_context_t *hdd_ctx, * * Return: 0 on success or error code on failure */ -static int hdd_ndp_end_req_handler(hdd_context_t *hdd_ctx, - struct nlattr **tb) +static int hdd_ndp_end_req_handler(hdd_context_t *hdd_ctx, struct nlattr **tb) { + struct ndp_end_req req = {0}; + VOS_STATUS status; + tHalHandle hal = hdd_ctx->hHal; + + ENTER(); + + /* NAN data path coexists only with STA interface */ + if (!hdd_is_ndp_allowed(hdd_ctx)) { + hddLog(LOGE, FL("Unsupported concurrency for NAN datapath")); + return -EINVAL; + } + + if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) { + hddLog(LOGE, FL("Transaction ID is unavailable")); + return -EINVAL; + } + req.transaction_id = + nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]); + + if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) { + hddLog(LOGE, FL("NDP instance ID array is unavailable")); + return -EINVAL; + } + + req.num_ndp_instances = + nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) / + sizeof(uint32_t); + if (0 >= req.num_ndp_instances) { + hddLog(LOGE, FL("Num NDP instances is 0")); + return -EINVAL; + } + req.ndp_ids = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]); + + hddLog(LOG1, FL("sending ndp_end_req to SME, transaction_id: %d"), + req.transaction_id); + + status = sme_ndp_end_req_handler(hal, &req); + if (status != VOS_STATUS_SUCCESS) { + hddLog(LOGE, FL("sme_ndp_end_req_handler failed, status: %d"), + status); + return -ECOMM; + } + EXIT(); return 0; } @@ -1066,6 +1110,9 @@ static void hdd_ndp_new_peer_ind_handler(hdd_adapter_t *adapter, hddLog(LOGE, FL("Invalid new NDP peer params")); return; } + hddLog(LOG1, FL("session_id: %d, peer_mac: %pM, sta_id: %d"), + new_peer_ind->session_id, new_peer_ind->peer_mac_addr.bytes, + new_peer_ind->sta_id); /* save peer in ndp ctx */ if (false == hdd_save_peer(sta_ctx, new_peer_ind->sta_id, @@ -1076,6 +1123,8 @@ static void hdd_ndp_new_peer_ind_handler(hdd_adapter_t *adapter, /* this function is called for each new peer */ ndp_ctx->active_ndp_peers++; + hddLog(LOG1, FL("vdev_id: %d, num_peers: %d"), + adapter->sessionId, ndp_ctx->active_ndp_peers); hdd_roamRegisterSTA(adapter, &roam_info, new_peer_ind->sta_id, &new_peer_ind->peer_mac_addr, &tmp_bss_descp); @@ -1083,7 +1132,7 @@ static void hdd_ndp_new_peer_ind_handler(hdd_adapter_t *adapter, /* perform following steps for first new peer ind */ if (ndp_ctx->active_ndp_peers == 1) { hdd_ctx->sta_to_adapter[NDP_BROADCAST_STAID] = adapter; - hdd_save_peer(sta_ctx, new_peer_ind->sta_id, &bc_mac_addr); + hdd_save_peer(sta_ctx, NDP_BROADCAST_STAID, &bc_mac_addr); hdd_roamRegisterSTA(adapter, &roam_info, NDP_BROADCAST_STAID, &bc_mac_addr, &tmp_bss_descp); hddLog(LOG1, FL("Set ctx connection state to connected")); @@ -1118,11 +1167,13 @@ static void hdd_ndp_peer_departed_ind_handler( static void hdd_ndp_confirm_ind_handler(hdd_adapter_t *adapter, void *ind_params) { + int idx; uint32_t ndp_qos_config = 0; struct ndp_confirm_event *ndp_confirm = ind_params; struct sk_buff *vendor_event; hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter); struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter); + hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); uint32_t data_len; ENTER(); @@ -1134,8 +1185,14 @@ static void hdd_ndp_confirm_ind_handler(hdd_adapter_t *adapter, if (0 != wlan_hdd_validate_context(hdd_ctx)) return; - /* ndp_confirm is called each time user generated npd req succeeds */ - ndp_ctx->active_ndp_sessions++; + /* ndp_confirm is called each time user generated ndp req succeeds */ + idx = hdd_get_peer_idx(sta_ctx, &ndp_confirm->peer_ndi_mac_addr); + if (idx == INVALID_PEER_IDX) + hddLog(LOGE, + FL("can't find addr: %pM in vdev_id: %d, peer table."), + &ndp_confirm->peer_ndi_mac_addr, adapter->sessionId); + else + ndp_ctx->active_ndp_sessions[idx]++; data_len = (4 * sizeof(uint32_t)) + VOS_MAC_ADDR_SIZE + IFNAMSIZ + sizeof(uint16_t) + NLMSG_HDRLEN + (8 * NLA_HDRLEN) + @@ -1422,12 +1479,97 @@ ndp_responder_rsp_nla_failed: * @adapter: pointer to adapter context * @rsp_params: response parameters * + * Following vendor event is sent to cfg80211: + * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD = + * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE (4 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VELUE (4 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes) + * * Return: none */ -static void hdd_ndp_end_rsp_handler(hdd_adapter_t *adapter, - void *rsp_params) +static void hdd_ndp_end_rsp_handler(hdd_adapter_t *adapter, void *rsp_params) { + struct sk_buff *vendor_event; + hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + struct ndp_end_rsp_event *rsp = rsp_params; + struct nan_datapath_ctx *ndp_ctx; + uint32_t data_len, i; + int idx; + hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + + ENTER(); + + if (!rsp) { + hddLog(LOGE, FL("Invalid ndp end response")); + return; + } + + if (0 != wlan_hdd_validate_context(hdd_ctx)) + return; + + /* adjust active ndp instances per peer */ + if (rsp->status == NDP_CMD_RSP_STATUS_SUCCESS) { + for (i = 0; i < rsp->num_peers; i++) { + adapter = hdd_get_adapter_by_vdev(hdd_ctx, + rsp->ndp_map[i].vdev_id); + if (NULL == adapter) { + hddLog(LOGE, + FL("adapter for vdev_id: %d not found"), + rsp->ndp_map[i].vdev_id); + continue; + } + sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter); + idx = hdd_get_peer_idx(sta_ctx, + &rsp->ndp_map[i].peer_ndi_mac_addr); + if (idx == INVALID_PEER_IDX) + hddLog(LOGE, + FL("can't find addr: %pM in vdev_id: %d, peer table."), + &rsp->ndp_map[i].peer_ndi_mac_addr, + rsp->ndp_map[i].vdev_id); + else + ndp_ctx->active_ndp_sessions[idx] = + rsp->ndp_map[i].num_active_ndp_sessions; + } + } + + data_len = NLMSG_HDRLEN + (4 * NLA_HDRLEN) + (3 * sizeof(uint32_t)) + + sizeof(uint16_t); + + vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL, + data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX, + GFP_KERNEL); + if (!vendor_event) { + hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed")); + return; + } + + if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, + QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE)) + goto ndp_end_rsp_nla_failed; + + if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE, + rsp->status)) + goto ndp_end_rsp_nla_failed; + + if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, + rsp->reason)) + goto ndp_end_rsp_nla_failed; + + if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, + rsp->transaction_id)) + goto ndp_end_rsp_nla_failed; + + hddLog(LOG1, FL("NDP End rsp sent, transaction id: %d, status: %d, reason: %d"), + rsp->transaction_id, rsp->status, rsp->reason); + cfg80211_vendor_event(vendor_event, GFP_KERNEL); + EXIT(); return; + +ndp_end_rsp_nla_failed: + hddLog(LOGE, FL("nla_put api failed")); + kfree_skb(vendor_event); + EXIT(); } /** @@ -1506,7 +1648,7 @@ void hdd_ndp_event_handler(hdd_adapter_t *adapter, break; case eCSR_ROAM_RESULT_NDP_END_RSP: hdd_ndp_end_rsp_handler(adapter, - &roam_info->ndp.ndp_end_rsp_params); + roam_info->ndp.ndp_end_rsp_params); break; case eCSR_ROAM_RESULT_NDP_PEER_DEPARTED_IND: hdd_ndp_peer_departed_ind_handler(adapter, @@ -1581,14 +1723,15 @@ static int __wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy, transaction_id = nla_get_u16( tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]); - if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) { - hddLog(LOGE, FL("Interface name string is unavailable")); - return -EINVAL; + if (tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) { + iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]); + hddLog(LOG2, FL("Transaction Id: %d NDP Cmd: %d iface_name: %s"), + transaction_id, ndp_cmd_type, iface_name); + } else { + hddLog(LOG2, + FL("Transaction Id: %d NDP Cmd: %d iface_name: unspecified"), + transaction_id, ndp_cmd_type); } - iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]); - - hddLog(LOG2, FL("Transaction Id: %d NDP Cmd: %d iface_name: %s"), - transaction_id, ndp_cmd_type, iface_name); switch (ndp_cmd_type) { case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE: diff --git a/CORE/HDD/src/wlan_hdd_nan_datapath.h b/CORE/HDD/src/wlan_hdd_nan_datapath.h index 3a36427f1236..2170d1222af8 100644 --- a/CORE/HDD/src/wlan_hdd_nan_datapath.h +++ b/CORE/HDD/src/wlan_hdd_nan_datapath.h @@ -39,6 +39,7 @@ struct wireless_dev; #define NDP_APP_INFO_LEN 255 #define NDP_QOS_INFO_LEN 255 +#define NDP_NUM_INSTANCE_ID 255 #define HDD_MAX_NUM_NDP_STA (HDD_MAX_NUM_IBSS_STA) @@ -187,17 +188,14 @@ enum nan_datapath_state { * @active_ndp_peers: number of active ndp peers * @ndp_create_transaction_id: transaction id for create req * @ndp_delete_transaction_id: transaction id for delete req - * @wext_state: Wext state variable - * @conn_info: NDP connection info - * @roam_info: NDP roam info - * @gtk_offload_req_params: GTK offload request params * @ndp_key_installed: NDP security key installed * @ndp_enc_key: NDP encryption key info * @ndp_debug_state: debug state info */ struct nan_datapath_ctx { enum nan_datapath_state state; - uint32_t active_ndp_sessions; + /* idx in following array should follow conn_info.peerMacAddress */ + uint32_t active_ndp_sessions[HDD_MAX_NUM_NDP_STA]; uint32_t active_ndp_peers; uint16_t ndp_create_transaction_id; uint16_t ndp_delete_transaction_id; diff --git a/CORE/HDD/src/wlan_hdd_tx_rx.c b/CORE/HDD/src/wlan_hdd_tx_rx.c index 66ab1d251c1a..29bdfe094216 100644 --- a/CORE/HDD/src/wlan_hdd_tx_rx.c +++ b/CORE/HDD/src/wlan_hdd_tx_rx.c @@ -774,6 +774,29 @@ VOS_STATUS hdd_get_peer_sta_id(hdd_station_ctx_t *sta_ctx, } /** + * hdd_get_peer_idx() - Get the idx for given address in peer table + * @sta_ctx: pointer to HDD Station Context + * @addr: pointer to Peer Mac address + * + * Return: index when success else INVALID_PEER_IDX + */ +int hdd_get_peer_idx(hdd_station_ctx_t *sta_ctx, v_MACADDR_t *addr) +{ + uint8_t idx; + + for (idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++) { + if (sta_ctx->conn_info.staId[idx] == 0) + continue; + if (!vos_mem_compare(&sta_ctx->conn_info.peerMacAddress[idx], + addr, sizeof(v_MACADDR_t))) + continue; + return idx; + } + + return INVALID_PEER_IDX; +} + +/** * wlan_display_tx_timeout_stats() - HDD tx timeout stats display handler * @adapter: hdd adapter * diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h index 7bda8cfa07ce..3d600e757c9e 100644 --- a/CORE/MAC/inc/sirApi.h +++ b/CORE/MAC/inc/sirApi.h @@ -7208,16 +7208,14 @@ struct ndp_confirm_event { /** * struct ndp_end_req - ndp end request * @transaction_id: unique transaction identifier - * @vdev_id: session id of the interface over which ndp is being created * @num_ndp_instances: number of ndp instances to be terminated - * @ndp_instances: list of ndp instances to be terminated + * @ndp_ids: pointer to array of ndp_instance_id to be terminated * */ struct ndp_end_req { uint32_t transaction_id; - uint32_t vdev_id; uint32_t num_ndp_instances; - uint32_t ndp_instances[]; + uint32_t *ndp_ids; }; /** @@ -7236,13 +7234,19 @@ struct peer_ndp_map { /** * struct ndp_end_rsp_event - firmware response to ndp end request * @transaction_id: unique identifier for the request - * @vdev_id: session id of the interface over which ndp is being created + * @status: status of operation + * @reason: reason(opaque to host driver) + * @num_ndp_terminated: if successful, number of ndp instances terminated + * @num_peers: number of peers in ndp_map * @ndp_map: mapping of NDP instances to peer to VDEV * */ struct ndp_end_rsp_event { uint32_t transaction_id; - uint32_t vdev_id; + uint32_t status; + uint32_t reason; + uint32_t num_ndp_terminated; + uint32_t num_peers; struct peer_ndp_map ndp_map[]; }; diff --git a/CORE/MAC/inc/wniApi.h b/CORE/MAC/inc/wniApi.h index 2a85a40b7e33..9a26f210ab0e 100644 --- a/CORE/MAC/inc/wniApi.h +++ b/CORE/MAC/inc/wniApi.h @@ -414,6 +414,7 @@ enum eWniMsgTypes eWNI_SME_NDP_INDICATION, eWNI_SME_NDP_RESPONDER_REQ, eWNI_SME_NDP_RESPONDER_RSP, + eWNI_SME_NDP_END_REQ, eWNI_SME_NDP_END_RSP, eWNI_SME_NDP_PEER_DEPARTED_IND, eWNI_SME_NDP_END_IND, diff --git a/CORE/MAC/src/include/sirParams.h b/CORE/MAC/src/include/sirParams.h index 59fe800d2ec8..19ddfcce691c 100644 --- a/CORE/MAC/src/include/sirParams.h +++ b/CORE/MAC/src/include/sirParams.h @@ -773,8 +773,7 @@ typedef struct sSirMbMsgP2p #define SIR_HAL_NDP_INDICATION (SIR_HAL_ITC_MSG_TYPES_BEGIN + 356) #define SIR_HAL_NDP_CONFIRM (SIR_HAL_ITC_MSG_TYPES_BEGIN + 357) #define SIR_HAL_NDP_END_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 358) -#define SIR_HAL_SEND_FREQ_RANGE_CONTROL_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 359) - +#define SIR_HAL_SEND_FREQ_RANGE_CONTROL_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 359) #define SIR_BTC_BT_WLAN_INTERVAL_CMD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 360) #define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF) diff --git a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c index ff93a9ef8002..4e4b3cc81620 100644 --- a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c +++ b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c @@ -1459,6 +1459,7 @@ limProcessMessages(tpAniSirGlobal pMac, tpSirMsgQ limMsg) case eWNI_SME_REGISTER_MGMT_FRAME_CB: case eWNI_SME_NDP_INITIATOR_REQ: case eWNI_SME_NDP_RESPONDER_REQ: + case eWNI_SME_NDP_END_REQ: // These messages are from HDD limProcessNormalHddMsg(pMac, limMsg, false); //no need to response to hdd break; @@ -2209,6 +2210,7 @@ limProcessMessages(tpAniSirGlobal pMac, tpSirMsgQ limMsg) case SIR_HAL_NDP_INDICATION: case SIR_HAL_NDP_CONFIRM: case SIR_HAL_NDP_RESPONDER_RSP: + case SIR_HAL_NDP_END_RSP: lim_handle_ndp_event_message(pMac, limMsg); break; default: diff --git a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c index c2199a3c491c..72ec883d197d 100644 --- a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c +++ b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c @@ -6194,6 +6194,7 @@ limProcessSmeReqMessages(tpAniSirGlobal pMac, tpSirMsgQ pMsg) break; case eWNI_SME_NDP_INITIATOR_REQ: case eWNI_SME_NDP_RESPONDER_REQ: + case eWNI_SME_NDP_END_REQ: lim_handle_ndp_request_message(pMac, pMsg); break; default: diff --git a/CORE/MAC/src/pe/nan/nan_datapath.c b/CORE/MAC/src/pe/nan/nan_datapath.c index 91afbe5a6ef3..f90a34dbfa01 100644 --- a/CORE/MAC/src/pe/nan/nan_datapath.c +++ b/CORE/MAC/src/pe/nan/nan_datapath.c @@ -216,6 +216,21 @@ responder_rsp: } /** + * lim_ndp_delete_peers() - Delete peers if needed + * @mac_ctx: handle to mac context + * @ndp_map: peer map of returning ndp end rsp + * @num_peers: number of peers remaining after ndp end + * This function deletes a peer if there are no active NDPs left with that peer + * + * Return: None + */ +static void lim_ndp_delete_peers(tpAniSirGlobal mac_ctx, + struct peer_ndp_map *ndp_map, + uint8_t num_peers) +{ +} + +/** * lim_handle_ndp_event_message() - Handler for NDP events/RSP from WMA * @mac_ctx: handle to mac structure * @msg: pointer to message @@ -237,11 +252,23 @@ VOS_STATUS lim_handle_ndp_event_message(tpAniSirGlobal mac_ctx, tpSirMsgQ msg) msg->bodyptr, sizeof(struct ndp_initiator_rsp), msg->bodyval); break; - case SIR_HAL_NDP_INDICATION: { - struct ndp_indication_event *ndp_ind = msg->bodyptr; - status = lim_handle_ndp_indication_event(mac_ctx, ndp_ind); + case SIR_HAL_NDP_END_RSP: { + struct ndp_end_rsp_event *ndp_end_rsp = msg->bodyptr; + uint32_t rsp_len = sizeof(*ndp_end_rsp); + + if (ndp_end_rsp && ndp_end_rsp->ndp_map) { + lim_ndp_delete_peers(mac_ctx, ndp_end_rsp->ndp_map, + ndp_end_rsp->num_peers); + rsp_len += (ndp_end_rsp->num_peers * + sizeof(struct peer_ndp_map)); + } + lim_send_ndp_event_to_sme(mac_ctx, eWNI_SME_NDP_END_RSP, + msg->bodyptr, rsp_len, msg->bodyval); break; } + case SIR_HAL_NDP_INDICATION: + status = lim_handle_ndp_indication_event(mac_ctx, msg->bodyptr); + break; case SIR_HAL_NDP_RESPONDER_RSP: status = lim_ndp_responder_rsp_handler(mac_ctx, msg->bodyptr, msg->bodyval); @@ -355,6 +382,55 @@ send_failure_rsp: } /** + * lim_process_sme_ndp_data_end_req() - Handler for eWNI_SME_NDP_END_REQ + * from SME. + * @mac_ctx: handle to mac context + * @sme_msg: ndp data end request msg + * + * Return: Status of operation + */ +VOS_STATUS lim_process_sme_ndp_data_end_req(tpAniSirGlobal mac_ctx, + struct sir_sme_ndp_end_req *sme_msg) +{ + tSirMsgQ msg; + uint32_t len; + VOS_STATUS status = VOS_STATUS_SUCCESS; + + if (NULL == sme_msg) { + limLog(mac_ctx, LOGE, FL("invalid ndp_req")); + /* msg to unblock SME, but not send rsp to HDD */ + lim_send_ndp_event_to_sme(mac_ctx, eWNI_SME_NDP_END_RSP, NULL, + 0, true); + return VOS_STATUS_E_INVAL; + } + + msg.type = SIR_HAL_NDP_END_REQ; + msg.reserved = 0; + len = sizeof(*sme_msg->req) + (sme_msg->req->num_ndp_instances * + sizeof(uint32_t)); + msg.bodyptr = vos_mem_malloc(len); + if (NULL == msg.bodyptr) { + /* msg to unblock SME, but not send rsp to HDD */ + lim_send_ndp_event_to_sme(mac_ctx, eWNI_SME_NDP_END_RSP, NULL, + 0, true); + return VOS_STATUS_E_NOMEM; + } + vos_mem_copy(msg.bodyptr, sme_msg->req, len); + msg.bodyval = 0; + + limLog(mac_ctx, LOG1, FL("sending SIR_HAL_NDP_END_REQ to WMA")); + MTRACE(macTraceMsgTx(mac_ctx, NO_SESSION, msg.type)); + + if (eSIR_SUCCESS != wdaPostCtrlMsg(mac_ctx, &msg)) { + limLog(mac_ctx, LOGE, + FL("Post msg failed for SIR_HAL_NDP_END_REQ")); + status = VOS_STATUS_E_FAILURE; + } + + return status; +} + +/** * lim_handle_ndp_request_message() - Handler for NDP req from SME * @mac_ctx: handle to mac structure * @msg: pointer to message @@ -367,6 +443,10 @@ VOS_STATUS lim_handle_ndp_request_message(tpAniSirGlobal mac_ctx, VOS_STATUS status; switch (msg->type) { + case eWNI_SME_NDP_END_REQ: + status = lim_process_sme_ndp_data_end_req(mac_ctx, + msg->bodyptr); + break; case eWNI_SME_NDP_INITIATOR_REQ: status = lim_process_sme_ndp_initiator_req(mac_ctx, msg->bodyptr); diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index 305bebd3d5a0..f218d704c3ee 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -30134,6 +30134,10 @@ VOS_STATUS wma_mc_process_msg(v_VOID_t *vos_context, vos_msg_t *msg) wma_handle_ndp_responder_req(wma_handle, msg->bodyptr); vos_mem_free(msg->bodyptr); break; + case SIR_HAL_NDP_END_REQ: + wma_handle_ndp_end_req(wma_handle, msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; default: WMA_LOGD("unknow msg type %x", msg->type); /* Do Nothing? MSG Body should be freed at here */ diff --git a/CORE/SERVICES/WMA/wma_nan_datapath.c b/CORE/SERVICES/WMA/wma_nan_datapath.c index ee418e8d586c..eec905f3b7bf 100644 --- a/CORE/SERVICES/WMA/wma_nan_datapath.c +++ b/CORE/SERVICES/WMA/wma_nan_datapath.c @@ -330,14 +330,91 @@ send_ndi_responder_fail: /** * wma_handle_ndp_end_req() - NDP end request handler * @wma_handle: wma handle - * @req_params: request parameters + * @ptr: request parameters * * Return: VOS_STATUS_SUCCESS on success; error number otherwise */ -VOS_STATUS wma_handle_ndp_end_req(tp_wma_handle wma_handle, - struct ndp_end_req *req_params) +VOS_STATUS wma_handle_ndp_end_req(tp_wma_handle wma_handle, void *ptr) { + int ret; + uint16_t len; + uint32_t ndp_end_req_len, i; + wmi_ndp_end_req *ndp_end_req_lst; + wmi_buf_t buf; + vos_msg_t pe_msg = {0}; + wmi_ndp_end_req_fixed_param *cmd; + struct ndp_end_rsp_event *end_rsp = NULL; + struct ndp_end_req *req = ptr; + + if (NULL == req) { + WMA_LOGE(FL("Invalid ndp_end_req")); + goto send_ndp_end_fail; + } + + /* len of tlv following fixed param */ + ndp_end_req_len = sizeof(wmi_ndp_end_req) * req->num_ndp_instances; + /* above comes out to 4 byte alligned already, no need of padding */ + len = sizeof(*cmd) + ndp_end_req_len + WMI_TLV_HDR_SIZE; + buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!buf) { + WMA_LOGE(FL("Malloc failed")); + return VOS_STATUS_E_NOMEM; + } + cmd = (wmi_ndp_end_req_fixed_param *) wmi_buf_data(buf); + + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_ndp_end_req_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_ndp_end_req_fixed_param)); + + cmd->transaction_id = req->transaction_id; + + /* set tlv pointer to end of fixed param */ + WMITLV_SET_HDR((uint8_t *)&cmd[1], WMITLV_TAG_ARRAY_STRUC, + ndp_end_req_len); + + ndp_end_req_lst = (wmi_ndp_end_req *)((uint8_t *)&cmd[1] + + WMI_TLV_HDR_SIZE); + for (i = 0; i < req->num_ndp_instances; i++) { + WMITLV_SET_HDR(&ndp_end_req_lst[i], + WMITLV_TAG_ARRAY_FIXED_STRUC, + (sizeof(*ndp_end_req_lst) - WMI_TLV_HDR_SIZE)); + + ndp_end_req_lst[i].ndp_instance_id = req->ndp_ids[i]; + } + + WMA_LOGD(FL("Sending WMI_NDP_END_REQ_CMDID to FW")); + ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len, + WMI_NDP_END_REQ_CMDID); + if (ret < 0) { + WMA_LOGE(FL("WMI_NDP_END_REQ_CMDID failed, ret: %d"), ret); + wmi_buf_free(buf); + goto send_ndp_end_fail; + } return VOS_STATUS_SUCCESS; + +send_ndp_end_fail: + pe_msg.type = SIR_HAL_NDP_END_RSP; + if (req) { + end_rsp = vos_mem_malloc(sizeof(*end_rsp)); + if (NULL == end_rsp) { + WMA_LOGE(FL("Malloc failed")); + pe_msg.bodyval = true; + } else { + vos_mem_zero(end_rsp, sizeof(*end_rsp)); + end_rsp->status = NDP_CMD_RSP_STATUS_ERROR; + end_rsp->transaction_id = req->transaction_id; + pe_msg.bodyptr = end_rsp; + } + } else { + pe_msg.bodyval = true; + } + + if (VOS_STATUS_SUCCESS != + vos_mq_post_message(VOS_MODULE_ID_PE, &pe_msg)) { + WMA_LOGE("NDP_END_RSP to PE failed"); + vos_mem_free(end_rsp); + } + return VOS_STATUS_E_FAILURE; } /** @@ -375,20 +452,6 @@ static int wma_ndp_indication_event_handler(void *handle, uint8_t *event_info, fixed_params = (wmi_ndp_indication_event_fixed_param *)event->fixed_param; - WMA_LOGD(FL("WMI_NDP_INDICATION_EVENTID(0x%X) received. vdev %d, service_instance %d, ndp_instance %d, role %d, policy %d"), - WMI_NDP_INDICATION_EVENTID, fixed_params->vdev_id, - fixed_params->service_instance_id, - fixed_params->ndp_instance_id, fixed_params->self_ndp_role, - fixed_params->accept_policy); - - WMA_LOGD(FL("ndp_cfg - %d bytes"), fixed_params->ndp_cfg_len); - VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_DEBUG, - &event->ndp_cfg, fixed_params->ndp_cfg_len); - - WMA_LOGD(FL("ndp_app_info - %d bytes"), fixed_params->ndp_app_info_len); - VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_DEBUG, - &event->ndp_app_info, fixed_params->ndp_app_info_len); - ind_event = vos_mem_malloc(sizeof(*ind_event)); if (!ind_event) { WMA_LOGP(FL("Failed to allocate memory")); @@ -406,6 +469,21 @@ static int wma_ndp_indication_event_handler(void *handle, uint8_t *event_info, WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_discovery_mac_addr, ind_event->peer_discovery_mac_addr.bytes); + WMA_LOGD(FL("WMI_NDP_INDICATION_EVENTID(0x%X) received. vdev %d, service_instance %d, ndp_instance %d, role %d, policy %d, peer_mac_addr: %pM, peer_disc_mac_addr: %pM"), + WMI_NDP_INDICATION_EVENTID, fixed_params->vdev_id, + fixed_params->service_instance_id, + fixed_params->ndp_instance_id, fixed_params->self_ndp_role, + fixed_params->accept_policy, + ind_event->peer_mac_addr.bytes, + ind_event->peer_discovery_mac_addr.bytes); + + WMA_LOGD(FL("ndp_cfg - %d bytes"), fixed_params->ndp_cfg_len); + VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_DEBUG, + &event->ndp_cfg, fixed_params->ndp_cfg_len); + + WMA_LOGD(FL("ndp_app_info - %d bytes"), fixed_params->ndp_app_info_len); + VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_DEBUG, + &event->ndp_app_info, fixed_params->ndp_app_info_len); ind_event->ndp_config.ndp_cfg_len = fixed_params->ndp_cfg_len; ind_event->ndp_info.ndp_app_info_len = fixed_params->ndp_app_info_len; @@ -583,7 +661,73 @@ static int wma_ndp_confirm_event_handler(void *handle, uint8_t *event_info, static int wma_ndp_end_response_event_handler(void *handle, uint8_t *event_info, uint32_t len) { - return 0; + int ret = 0; + VOS_STATUS status; + vos_msg_t pe_msg = {0}; + struct ndp_end_rsp_event *end_rsp; + WMI_NDP_END_RSP_EVENTID_param_tlvs *event; + wmi_ndp_end_rsp_event_fixed_param *fixed_params = NULL; + wmi_ndp_end_rsp_per_ndi *end_rsp_tlv; + uint32_t i; + uint32_t len_end_rsp; + + event = (WMI_NDP_END_RSP_EVENTID_param_tlvs *) event_info; + fixed_params = (wmi_ndp_end_rsp_event_fixed_param *)event->fixed_param; + WMA_LOGD(FL("WMI_NDP_END_RSP_EVENTID(0x%X) recieved. transaction_id: %d, rsp_status: %d, reason_code: %d"), + WMI_NDP_END_RSP_EVENTID, fixed_params->transaction_id, + fixed_params->rsp_status, fixed_params->reason_code); + + len_end_rsp = sizeof(*end_rsp) + (event->num_ndp_end_rsp_per_ndi_list * + sizeof(struct peer_ndp_map)); + end_rsp = vos_mem_malloc(len_end_rsp); + if (NULL == end_rsp) { + WMA_LOGE("malloc failed"); + pe_msg.bodyval = true; + ret = -ENOMEM; + goto send_ndp_end_rsp; + } + pe_msg.bodyptr = end_rsp; + vos_mem_zero(end_rsp, len_end_rsp); + + end_rsp->transaction_id = fixed_params->transaction_id; + end_rsp->reason = fixed_params->reason_code; + end_rsp->status = fixed_params->rsp_status; + + if (end_rsp->status == NDP_CMD_RSP_STATUS_SUCCESS) { + WMA_LOGD(FL("NDP end rsp, num_peers: %d"), + event->num_ndp_end_rsp_per_ndi_list); + end_rsp->num_peers = event->num_ndp_end_rsp_per_ndi_list; + if (end_rsp->num_peers == 0) { + WMA_LOGE(FL("num_peers in NDP rsp should not be 0.")); + end_rsp->status = NDP_CMD_RSP_STATUS_ERROR; + goto send_ndp_end_rsp; + } + /* copy per peer response to return path buffer */ + end_rsp_tlv = event->ndp_end_rsp_per_ndi_list; + for (i = 0; i < end_rsp->num_peers; i++) { + end_rsp->ndp_map[i].vdev_id = end_rsp_tlv[i].vdev_id; + WMI_MAC_ADDR_TO_CHAR_ARRAY(&end_rsp_tlv[i].peer_mac_addr, + end_rsp->ndp_map[i].peer_ndi_mac_addr.bytes); + end_rsp->ndp_map[i].num_active_ndp_sessions = + end_rsp_tlv[i].num_active_ndps_on_ndi; + WMA_LOGD(FL("vdev_id: %d, peer_addr: %pM, active_ndp_left: %d"), + end_rsp->ndp_map[i].vdev_id, + &end_rsp->ndp_map[i].peer_ndi_mac_addr, + end_rsp->ndp_map[i].num_active_ndp_sessions); + } + } + +send_ndp_end_rsp: + pe_msg.type = SIR_HAL_NDP_END_RSP; + WMA_LOGD(FL("Sending SIR_HAL_NDP_END_RSP msg to PE")); + status = vos_mq_post_message(VOS_MODULE_ID_PE, &pe_msg); + if (!VOS_IS_STATUS_SUCCESS(status)) { + WMA_LOGE("SIR_HAL_NDP_END_RSP to PE failed"); + vos_mem_free(end_rsp); + ret = -EINVAL; + } + + return ret; } /** diff --git a/CORE/SERVICES/WMA/wma_nan_datapath.h b/CORE/SERVICES/WMA/wma_nan_datapath.h index a639f394cdfa..9da9f2eef732 100644 --- a/CORE/SERVICES/WMA/wma_nan_datapath.h +++ b/CORE/SERVICES/WMA/wma_nan_datapath.h @@ -58,6 +58,7 @@ void wma_ndp_wow_event_callback(void *handle, void *event, uint32_t len); void wma_add_bss_ndi_mode(tp_wma_handle wma, tpAddBssParams add_bss); void wma_add_sta_ndi_mode(tp_wma_handle wma, tpAddStaParams add_sta); VOS_STATUS wma_handle_ndp_initiator_req(tp_wma_handle wma_handle, void *req); +VOS_STATUS wma_handle_ndp_end_req(tp_wma_handle wma_handle, void *req); #else static inline void wma_add_bss_ndi_mode(tp_wma_handle wma, tpAddBssParams add_bss) {} @@ -85,6 +86,11 @@ static inline VOS_STATUS wma_handle_ndp_responder_req(tp_wma_handle wma_handle, { return VOS_STATUS_SUCCESS; } +static inline VOS_STATUS wma_handle_ndp_end_req(tp_wma_handle wma_handle, + void *req) +{ + return VOS_STATUS_SUCCESS; +} #endif /* WLAN_FEATURE_NAN_DATAPATH */ #endif /* __WMA_NAN_DATAPATH_H */ diff --git a/CORE/SME/inc/csrApi.h b/CORE/SME/inc/csrApi.h index 02e63d503838..447f3cf73c90 100644 --- a/CORE/SME/inc/csrApi.h +++ b/CORE/SME/inc/csrApi.h @@ -1476,7 +1476,7 @@ typedef struct tagCsrRoamInfo struct sme_ndp_peer_ind ndp_peer_ind_params; struct ndp_schedule_update_rsp ndp_sched_upd_rsp_params; struct ndp_end_indication_event ndp_end_ind_params; - struct ndp_end_rsp_event ndp_end_rsp_params; + struct ndp_end_rsp_event *ndp_end_rsp_params; struct ndp_confirm_event ndp_confirm_params; struct ndp_responder_rsp_event ndp_responder_rsp_params; struct ndp_indication_event ndp_indication_params; diff --git a/CORE/SME/inc/smeInside.h b/CORE/SME/inc/smeInside.h index e0de898cc3b1..e8693b6cf406 100644 --- a/CORE/SME/inc/smeInside.h +++ b/CORE/SME/inc/smeInside.h @@ -217,6 +217,7 @@ typedef struct tagSmeCmd #ifdef WLAN_FEATURE_NAN_DATAPATH struct ndp_initiator_req initiator_req; struct ndp_responder_req responder_req; + struct ndp_end_req *data_end_req; #endif }u; }tSmeCmd; diff --git a/CORE/SME/inc/smeInternal.h b/CORE/SME/inc/smeInternal.h index 46e4fab07b2d..edcdd4f450ad 100644 --- a/CORE/SME/inc/smeInternal.h +++ b/CORE/SME/inc/smeInternal.h @@ -100,6 +100,7 @@ typedef enum eSmeCommandType eSmeCommandNoAUpdate, eSmeCommandNdpInitiatorRequest, eSmeCommandNdpResponderRequest, + eSmeCommandNdpDataEndInitiatorRequest, } eSmeCommandType; diff --git a/CORE/SME/inc/sme_nan_datapath.h b/CORE/SME/inc/sme_nan_datapath.h index bec7ed381d62..30b0a00a8516 100644 --- a/CORE/SME/inc/sme_nan_datapath.h +++ b/CORE/SME/inc/sme_nan_datapath.h @@ -63,6 +63,19 @@ struct sir_sme_ndp_responder_req { struct ndp_responder_req req; }; +/** + * struct sir_sme_ndp_end_req - sme request struct for ndp end req + * @msg_type: SME msg type(sir_sme_ndp_initiator_req) + * @msg_len: lenght of message + * @req: actual ndp initiator request + * + */ +struct sir_sme_ndp_end_req { + uint16_t msg_type; + uint16_t msg_len; + struct ndp_end_req *req; +}; + /* NaN initiator request handler */ eHalStatus sme_ndp_initiator_req_handler(tHalHandle hal, struct ndp_initiator_req *req_params); @@ -72,8 +85,7 @@ eHalStatus sme_ndp_responder_req_handler(tHalHandle hal, struct ndp_responder_req *req_params); /* NaN indication response handler */ -VOS_STATUS sme_ndp_end_req_handler(uint32_t session_id, - struct ndp_end_req *req_params); +VOS_STATUS sme_ndp_end_req_handler(tHalHandle hal, struct ndp_end_req *req); /* NaN schedule update request handler */ VOS_STATUS sme_ndp_sched_req_handler(uint32_t session_id, @@ -106,6 +118,8 @@ void csr_roam_update_ndp_return_params(tpAniSirGlobal mac_ctx, void *roam_info); eHalStatus csr_process_ndp_initiator_request(tpAniSirGlobal mac_ctx, tSmeCmd *cmd); +eHalStatus csr_process_ndp_data_end_request(tpAniSirGlobal mac_ctx, + tSmeCmd *cmd); void sme_ndp_msg_processor(tpAniSirGlobal mac_ctx, vos_msg_t *msg); @@ -161,6 +175,13 @@ static inline eHalStatus csr_process_ndp_responder_request( { return eHAL_STATUS_SUCCESS; } + +static inline eHalStatus csr_process_ndp_data_end_request( + tpAniSirGlobal mac_ctx, tSmeCmd *cmd) +{ + return eHAL_STATUS_SUCCESS; +} + #endif /* WLAN_FEATURE_NAN_DATAPATH */ #endif /* __SME_NAN_DATAPATH_H */ diff --git a/CORE/SME/src/nan/nan_datapath_api.c b/CORE/SME/src/nan/nan_datapath_api.c index 0a183c676cdd..9fbb9660c590 100644 --- a/CORE/SME/src/nan/nan_datapath_api.c +++ b/CORE/SME/src/nan/nan_datapath_api.c @@ -84,6 +84,7 @@ eHalStatus sme_ndp_initiator_req_handler(tHalHandle hal, cmd->u.initiator_req.ndp_config.ndp_cfg = vos_mem_malloc(req_params->ndp_config.ndp_cfg_len); if (NULL == cmd->u.initiator_req.ndp_config.ndp_cfg) { + csrReleaseCommandRoam(mac_ctx, cmd); sme_ReleaseGlobalLock(&mac_ctx->sme); vos_mem_free( cmd->u.initiator_req.ndp_info.ndp_app_info); @@ -103,6 +104,7 @@ eHalStatus sme_ndp_initiator_req_handler(tHalHandle hal, vos_mem_free(cmd->u.initiator_req.ndp_config.ndp_cfg); cmd->u.initiator_req.ndp_info.ndp_app_info_len = 0; cmd->u.initiator_req.ndp_config.ndp_cfg_len = 0; + csrReleaseCommandRoam(mac_ctx, cmd); } sme_ReleaseGlobalLock(&mac_ctx->sme); @@ -156,6 +158,7 @@ eHalStatus sme_ndp_responder_req_handler(tHalHandle hal, cmd->u.responder_req.ndp_info.ndp_app_info = vos_mem_malloc(req_params->ndp_info.ndp_app_info_len); if (NULL == cmd->u.responder_req.ndp_info.ndp_app_info) { + csrReleaseCommandRoam(mac_ctx, cmd); sme_ReleaseGlobalLock(&mac_ctx->sme); return eHAL_STATUS_FAILED_ALLOC; } @@ -168,6 +171,7 @@ eHalStatus sme_ndp_responder_req_handler(tHalHandle hal, cmd->u.responder_req.ndp_config.ndp_cfg = vos_mem_malloc(req_params->ndp_config.ndp_cfg_len); if (NULL == cmd->u.responder_req.ndp_config.ndp_cfg) { + csrReleaseCommandRoam(mac_ctx, cmd); sme_ReleaseGlobalLock(&mac_ctx->sme); vos_mem_free( cmd->u.responder_req.ndp_info.ndp_app_info); @@ -187,6 +191,7 @@ eHalStatus sme_ndp_responder_req_handler(tHalHandle hal, vos_mem_free(cmd->u.responder_req.ndp_config.ndp_cfg); cmd->u.responder_req.ndp_info.ndp_app_info_len = 0; cmd->u.responder_req.ndp_config.ndp_cfg_len = 0; + csrReleaseCommandRoam(mac_ctx, cmd); } sme_ReleaseGlobalLock(&mac_ctx->sme); return status; @@ -194,17 +199,63 @@ eHalStatus sme_ndp_responder_req_handler(tHalHandle hal, /** * sme_ndp_end_req_handler() - ndp end request handler - * @session_id: session id over which the ndp is being created - * @req_params: request parameters + * @hal: hal handle + * @req: ndp end request parameters * * Return: VOS_STATUS_SUCCESS on success; error number otherwise */ -VOS_STATUS sme_ndp_end_req_handler(uint32_t session_id, - struct ndp_end_req *req_params) +VOS_STATUS sme_ndp_end_req_handler(tHalHandle hal, struct ndp_end_req *req) { - return VOS_STATUS_SUCCESS; -} + tSmeCmd *cmd; + VOS_STATUS ret = VOS_STATUS_SUCCESS; + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); + if (NULL == req) { + smsLog(mac_ctx, LOGE, FL("Invalid ndp end req")); + return VOS_STATUS_E_INVAL; + } + + status = sme_AcquireGlobalLock(&mac_ctx->sme); + if (eHAL_STATUS_SUCCESS != status) { + smsLog(mac_ctx, LOGE, + FL("SME lock failed, status:%d"), status); + return VOS_STATUS_E_RESOURCES; + } + cmd = csrGetCommandBuffer(mac_ctx); + if (NULL == cmd) { + sme_ReleaseGlobalLock(&mac_ctx->sme); + return VOS_STATUS_E_RESOURCES; + } + + cmd->command = eSmeCommandNdpDataEndInitiatorRequest; + cmd->u.data_end_req = vos_mem_malloc(sizeof(*req) + + (req->num_ndp_instances * sizeof(uint32))); + if (NULL == cmd->u.data_end_req) { + csrReleaseCommandRoam(mac_ctx, cmd); + sme_ReleaseGlobalLock(&mac_ctx->sme); + return VOS_STATUS_E_NOMEM; + } + + vos_mem_copy(cmd->u.data_end_req, req, sizeof(*req)); + cmd->u.data_end_req->ndp_ids = + (uint32_t *)((uint8_t *)&cmd->u.data_end_req[1]); + vos_mem_copy(cmd->u.data_end_req->ndp_ids, req->ndp_ids, + sizeof(uint32_t) * req->num_ndp_instances); + + status = csrQueueSmeCommand(mac_ctx, cmd, true); + if (eHAL_STATUS_SUCCESS != status) { + smsLog(mac_ctx, LOGE, FL("SME enqueue failed, status:%d"), + status); + vos_mem_free(cmd->u.data_end_req); + cmd->u.data_end_req = NULL; + ret = VOS_STATUS_E_FAILURE; + csrReleaseCommandRoam(mac_ctx, cmd); + } + + sme_ReleaseGlobalLock(&mac_ctx->sme); + return ret; +} /** * sme_ndp_sched_req_handler() - ndp schedule request handler @@ -493,6 +544,46 @@ free_config: } /** + * csr_process_ndp_data_end_request() - process ndp data end request + * @mac_ctx: Global MAC context + * @cmd: sme command containing ndp initiator request + * + * Return: status of operation + */ +eHalStatus csr_process_ndp_data_end_request(tpAniSirGlobal mac_ctx, + tSmeCmd *cmd) +{ + eHalStatus status; + struct sir_sme_ndp_end_req *lim_msg; + uint16_t msg_len; + + if (NULL == cmd) { + smsLog(mac_ctx, LOGE, FL("NULL sme cmd")); + return eHAL_STATUS_INVALID_PARAMETER; + } + + msg_len = sizeof(*lim_msg); + lim_msg = vos_mem_malloc(msg_len); + if (NULL == lim_msg) { + smsLog(mac_ctx, LOGE, FL("Malloc failed")); + vos_mem_free(cmd->u.data_end_req); + cmd->u.data_end_req = NULL; + return eHAL_STATUS_FAILED_ALLOC; + } + + lim_msg->msg_type = (uint16_t)eWNI_SME_NDP_END_REQ; + lim_msg->msg_len = msg_len; + lim_msg->req = cmd->u.data_end_req; + + status = palSendMBMessage(mac_ctx->hHdd, lim_msg); + if (status != eHAL_STATUS_SUCCESS) { + vos_mem_free(cmd->u.data_end_req); + cmd->u.data_end_req = NULL; + } + return status; +} + +/** * sme_ndp_msg_processor() - message processor for ndp/ndi north-bound SME msg. * @mac_ctx: Global MAC context * @msg: ndp/ndi SME message @@ -514,6 +605,10 @@ void sme_ndp_msg_processor(tpAniSirGlobal mac_ctx, vos_msg_t *msg) eSmeCommandType cmd_to_rel = eSmeNoCommand; bool send_to_user = true; + entry = csrLLPeekHead(&mac_ctx->sme.smeCmdActiveList, LL_ACCESS_LOCK); + if (entry != NULL) + cmd = GET_BASE_ADDR(entry, tSmeCmd, Link); + switch (msg->type) { case eWNI_SME_NDP_CONFIRM_IND: { result = eCSR_ROAM_RESULT_NDP_CONFIRM_IND; @@ -573,6 +668,31 @@ void sme_ndp_msg_processor(tpAniSirGlobal mac_ctx, vos_msg_t *msg) release_active_cmd = true; cmd_to_rel = eSmeCommandNdpResponderRequest; break; + case eWNI_SME_NDP_END_RSP: { + if (true == msg->bodyval) { + /* rsp was locally generated, do not send to HDD */ + send_to_user = false; + } else { + result = eCSR_ROAM_RESULT_NDP_END_RSP; + roam_info.ndp.ndp_end_rsp_params = msg->bodyptr; + /* + * NDP_END_IND is independent of session, but session_id + * is needed for csrRoamCallCallback(). Set it to 0 + * which is a valid session. + */ + session_id = 0; + } + release_active_cmd = true; + cmd_to_rel = eSmeCommandNdpDataEndInitiatorRequest; + /* + * get num of ndp requested to terminated from sme command + * being released + */ + if (cmd != NULL && cmd_to_rel == cmd->command) + roam_info.ndp.ndp_end_rsp_params->num_ndp_terminated = + cmd->u.data_end_req->num_ndp_instances; + break; + } default: smsLog(mac_ctx, LOGE, FL("Unhandled NDP rsp")); vos_mem_free(msg->bodyptr); @@ -584,39 +704,25 @@ void sme_ndp_msg_processor(tpAniSirGlobal mac_ctx, vos_msg_t *msg) eCSR_ROAM_NDP_STATUS_UPDATE, result); } + vos_mem_free(msg->bodyptr); + msg->bodyptr = NULL; /* free ndp_cfg and ndp_app_info if required * For some commands this info may be needed in HDD * so free them after roam callback. */ switch (msg->type) { case eWNI_SME_NDP_INITIATOR_RSP: - entry = csrLLPeekHead(&mac_ctx->sme.smeCmdActiveList, - LL_ACCESS_LOCK); - if (entry != NULL) { - cmd = GET_BASE_ADDR(entry, tSmeCmd, Link); - if (eSmeCommandNdpInitiatorRequest == cmd->command) { - vos_mem_free( - cmd->u.initiator_req. - ndp_config.ndp_cfg); - vos_mem_free( - cmd->u.initiator_req. - ndp_info.ndp_app_info); - } + if (cmd && eSmeCommandNdpInitiatorRequest == cmd->command) { + vos_mem_free(cmd->u.initiator_req.ndp_config.ndp_cfg); + vos_mem_free( + cmd->u.initiator_req.ndp_info.ndp_app_info); } break; case eWNI_SME_NDP_RESPONDER_RSP: - entry = csrLLPeekHead(&mac_ctx->sme.smeCmdActiveList, - LL_ACCESS_LOCK); - if (entry != NULL) { - cmd = GET_BASE_ADDR(entry, tSmeCmd, Link); - if (eSmeCommandNdpResponderRequest == cmd->command) { - vos_mem_free( - cmd->u.responder_req. - ndp_config.ndp_cfg); - vos_mem_free( - cmd->u.responder_req. - ndp_info.ndp_app_info); - } + if (cmd && eSmeCommandNdpResponderRequest == cmd->command) { + vos_mem_free(cmd->u.responder_req.ndp_config.ndp_cfg); + vos_mem_free( + cmd->u.responder_req.ndp_info.ndp_app_info); } break; case eWNI_SME_NDP_INDICATION: @@ -624,21 +730,19 @@ void sme_ndp_msg_processor(tpAniSirGlobal mac_ctx, vos_msg_t *msg) roam_info.ndp.ndp_indication_params.ndp_config.ndp_cfg); vos_mem_free( roam_info.ndp.ndp_indication_params. - ndp_info.ndp_app_info); + ndp_info.ndp_app_info); + break; + case eWNI_SME_NDP_END_RSP: + if (cmd && + eSmeCommandNdpDataEndInitiatorRequest == cmd->command) { + vos_mem_free(cmd->u.data_end_req); + cmd->u.data_end_req = NULL; + } break; default: break; } - vos_mem_free(msg->bodyptr); - if (release_active_cmd == false) - return; - - entry = csrLLPeekHead(&mac_ctx->sme.smeCmdActiveList, LL_ACCESS_LOCK); - if (entry == NULL) - return; - - cmd = GET_BASE_ADDR(entry, tSmeCmd, Link); - if (cmd_to_rel == cmd->command) { + if (release_active_cmd && cmd && cmd_to_rel == cmd->command) { /* Now put this cmd back on the avilable command list */ if (csrLLRemoveEntry(&mac_ctx->sme.smeCmdActiveList, entry, LL_ACCESS_LOCK)) diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c index bc5accf79c4b..4428ddca9b2c 100644 --- a/CORE/SME/src/sme_common/sme_Api.c +++ b/CORE/SME/src/sme_common/sme_Api.c @@ -1053,6 +1053,17 @@ sme_process_cmd: csrReleaseCommand(pMac, pCommand); } break; + case eSmeCommandNdpDataEndInitiatorRequest: + csrLLUnlock(&pMac->sme.smeCmdActiveList); + status = csr_process_ndp_data_end_request(pMac, + pCommand); + if (!HAL_STATUS_SUCCESS(status)) { + if (csrLLRemoveEntry( + &pMac->sme.smeCmdActiveList, + &pCommand->Link, LL_ACCESS_LOCK)) + csrReleaseCommand(pMac, pCommand); + } + break; case eSmeCommandDelStaSession: csrLLUnlock( &pMac->sme.smeCmdActiveList ); csrProcessDelStaSessionCommand( pMac, pCommand ); @@ -3381,6 +3392,7 @@ eHalStatus sme_ProcessMsg(tHalHandle hHal, vos_msg_t* pMsg) case eWNI_SME_NDP_INITIATOR_RSP: case eWNI_SME_NDP_INDICATION: case eWNI_SME_NDP_RESPONDER_RSP: + case eWNI_SME_NDP_END_RSP: sme_ndp_msg_processor(pMac, pMsg); break; default: |
