|
@@ -1761,7 +1761,21 @@ static struct wlan_objmgr_peer *wma_create_objmgr_peer(tp_wma_handle wma,
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * wma_create_peer() - send peer create command to fw
|
|
|
+ * wma_increment_peer_count() - Increment the vdev peer
|
|
|
+ * count
|
|
|
+ * @wma: wma handle
|
|
|
+ * @vdev_id: vdev id
|
|
|
+ *
|
|
|
+ * Return: None
|
|
|
+ */
|
|
|
+static void
|
|
|
+wma_increment_peer_count(tp_wma_handle wma, uint8_t vdev_id)
|
|
|
+{
|
|
|
+ wma->interfaces[vdev_id].peer_count++;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * wma_add_peer() - send peer create command to fw
|
|
|
* @wma: wma handle
|
|
|
* @peer_addr: peer mac addr
|
|
|
* @peer_type: peer type
|
|
@@ -1769,12 +1783,12 @@ static struct wlan_objmgr_peer *wma_create_objmgr_peer(tp_wma_handle wma,
|
|
|
*
|
|
|
* Return: QDF status
|
|
|
*/
|
|
|
-QDF_STATUS wma_create_peer(tp_wma_handle wma,
|
|
|
- uint8_t peer_addr[QDF_MAC_ADDR_SIZE],
|
|
|
- uint32_t peer_type, uint8_t vdev_id)
|
|
|
+static
|
|
|
+QDF_STATUS wma_add_peer(tp_wma_handle wma,
|
|
|
+ uint8_t peer_addr[QDF_MAC_ADDR_SIZE],
|
|
|
+ uint32_t peer_type, uint8_t vdev_id)
|
|
|
{
|
|
|
struct peer_create_params param = {0};
|
|
|
- uint8_t *mac_addr_raw;
|
|
|
void *dp_soc = cds_get_context(QDF_MODULE_ID_SOC);
|
|
|
struct wlan_objmgr_psoc *psoc = wma->psoc;
|
|
|
target_resource_config *wlan_res_cfg;
|
|
@@ -1792,25 +1806,25 @@ QDF_STATUS wma_create_peer(tp_wma_handle wma,
|
|
|
return QDF_STATUS_E_INVAL;
|
|
|
}
|
|
|
|
|
|
- if (++wma->interfaces[vdev_id].peer_count >
|
|
|
+ if (wma->interfaces[vdev_id].peer_count >=
|
|
|
wlan_res_cfg->num_peers) {
|
|
|
wma_err("the peer count exceeds the limit %d",
|
|
|
- wma->interfaces[vdev_id].peer_count - 1);
|
|
|
- goto err;
|
|
|
+ wma->interfaces[vdev_id].peer_count);
|
|
|
+ return QDF_STATUS_E_FAILURE;
|
|
|
}
|
|
|
|
|
|
if (!dp_soc)
|
|
|
- goto err;
|
|
|
+ return QDF_STATUS_E_FAILURE;
|
|
|
|
|
|
if (qdf_is_macaddr_group((struct qdf_mac_addr *)peer_addr) ||
|
|
|
qdf_is_macaddr_zero((struct qdf_mac_addr *)peer_addr)) {
|
|
|
wma_err("Invalid peer address received reject it");
|
|
|
- goto err;
|
|
|
+ return QDF_STATUS_E_FAILURE;
|
|
|
}
|
|
|
|
|
|
obj_peer = wma_create_objmgr_peer(wma, vdev_id, peer_addr, peer_type);
|
|
|
if (!obj_peer)
|
|
|
- goto err;
|
|
|
+ return QDF_STATUS_E_FAILURE;
|
|
|
|
|
|
/* The peer object should be created before sending the WMI peer
|
|
|
* create command to firmware. This is to prevent a race condition
|
|
@@ -1822,7 +1836,7 @@ QDF_STATUS wma_create_peer(tp_wma_handle wma,
|
|
|
wma_err("Unable to attach peer "QDF_MAC_ADDR_FMT,
|
|
|
QDF_MAC_ADDR_REF(peer_addr));
|
|
|
wlan_objmgr_peer_obj_delete(obj_peer);
|
|
|
- goto err;
|
|
|
+ return QDF_STATUS_E_FAILURE;
|
|
|
}
|
|
|
|
|
|
if (peer_type == WMI_PEER_TYPE_TDLS)
|
|
@@ -1831,8 +1845,7 @@ QDF_STATUS wma_create_peer(tp_wma_handle wma,
|
|
|
if (MLME_IS_ROAM_SYNCH_IN_PROGRESS(wma->psoc, vdev_id)) {
|
|
|
wma_debug("LFR3: Created peer "QDF_MAC_ADDR_FMT" vdev_id %d, peer_count %d",
|
|
|
QDF_MAC_ADDR_REF(peer_addr), vdev_id,
|
|
|
- wma->interfaces[vdev_id].peer_count);
|
|
|
- cdp_peer_setup(dp_soc, vdev_id, peer_addr);
|
|
|
+ wma->interfaces[vdev_id].peer_count + 1);
|
|
|
return QDF_STATUS_SUCCESS;
|
|
|
}
|
|
|
param.peer_addr = peer_addr;
|
|
@@ -1851,27 +1864,106 @@ QDF_STATUS wma_create_peer(tp_wma_handle wma,
|
|
|
dp_soc, vdev_id, peer_addr,
|
|
|
1 << CDP_PEER_DO_NOT_START_UNMAP_TIMER);
|
|
|
wlan_objmgr_peer_obj_delete(obj_peer);
|
|
|
- goto err;
|
|
|
+
|
|
|
+ return QDF_STATUS_E_FAILURE;
|
|
|
}
|
|
|
|
|
|
wma_debug("Created peer peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d, peer_count - %d",
|
|
|
QDF_MAC_ADDR_REF(peer_addr), vdev_id,
|
|
|
- wma->interfaces[vdev_id].peer_count);
|
|
|
+ wma->interfaces[vdev_id].peer_count + 1);
|
|
|
|
|
|
wlan_roam_debug_log(vdev_id, DEBUG_PEER_CREATE_SEND,
|
|
|
DEBUG_INVALID_PEER_ID, peer_addr, NULL, 0, 0);
|
|
|
+
|
|
|
+ return QDF_STATUS_SUCCESS;
|
|
|
+}
|
|
|
+
|
|
|
+QDF_STATUS wma_create_peer(tp_wma_handle wma,
|
|
|
+ uint8_t peer_addr[QDF_MAC_ADDR_SIZE],
|
|
|
+ uint32_t peer_type, uint8_t vdev_id)
|
|
|
+{
|
|
|
+ void *dp_soc = cds_get_context(QDF_MODULE_ID_SOC);
|
|
|
+ QDF_STATUS status;
|
|
|
+
|
|
|
+ if (!dp_soc)
|
|
|
+ return QDF_STATUS_E_FAILURE;
|
|
|
+
|
|
|
+ status = wma_add_peer(wma, peer_addr, peer_type, vdev_id);
|
|
|
+ if (QDF_IS_STATUS_ERROR(status))
|
|
|
+ return status;
|
|
|
+
|
|
|
+ wma_increment_peer_count(wma, vdev_id);
|
|
|
cdp_peer_setup(dp_soc, vdev_id, peer_addr);
|
|
|
|
|
|
- mac_addr_raw = cdp_get_vdev_mac_addr(dp_soc, vdev_id);
|
|
|
- if (!mac_addr_raw) {
|
|
|
- wma_err("peer mac addr is NULL");
|
|
|
- return QDF_STATUS_E_FAULT;
|
|
|
+ return QDF_STATUS_SUCCESS;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * wma_create_sta_mode_bss_peer() - send peer create command to fw
|
|
|
+ * and start peer create response timer
|
|
|
+ * @wma: wma handle
|
|
|
+ * @peer_addr: peer mac address
|
|
|
+ * @peer_type: peer type
|
|
|
+ * @vdev_id: vdev id
|
|
|
+ *
|
|
|
+ * Return: QDF_STATUS
|
|
|
+ */
|
|
|
+static QDF_STATUS
|
|
|
+wma_create_sta_mode_bss_peer(tp_wma_handle wma,
|
|
|
+ uint8_t peer_addr[QDF_MAC_ADDR_SIZE],
|
|
|
+ uint32_t peer_type, uint8_t vdev_id)
|
|
|
+{
|
|
|
+ struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
|
|
|
+ struct wma_target_req *msg = NULL;
|
|
|
+ QDF_STATUS status = QDF_STATUS_E_FAILURE;
|
|
|
+ bool is_tgt_peer_conf_supported = false;
|
|
|
+
|
|
|
+ if (!mac) {
|
|
|
+ wma_err("vdev%d: Mac context is null", vdev_id);
|
|
|
+ return status;
|
|
|
}
|
|
|
|
|
|
- return QDF_STATUS_SUCCESS;
|
|
|
-err:
|
|
|
- wma->interfaces[vdev_id].peer_count--;
|
|
|
- return QDF_STATUS_E_FAILURE;
|
|
|
+ /*
|
|
|
+ * If fw doesn't advertise peer create confirm event support,
|
|
|
+ * use the legacy peer create API
|
|
|
+ */
|
|
|
+ is_tgt_peer_conf_supported =
|
|
|
+ wlan_psoc_nif_fw_ext_cap_get(wma->psoc,
|
|
|
+ WLAN_SOC_F_PEER_CREATE_RESP);
|
|
|
+ if (!is_tgt_peer_conf_supported) {
|
|
|
+ status = wma_create_peer(wma, peer_addr, peer_type, vdev_id);
|
|
|
+ goto end;
|
|
|
+ }
|
|
|
+
|
|
|
+ wma_acquire_wakelock(&wma->wmi_cmd_rsp_wake_lock,
|
|
|
+ WMA_PEER_CREATE_RESPONSE_TIMEOUT);
|
|
|
+
|
|
|
+ status = wma_add_peer(wma, peer_addr, peer_type, vdev_id);
|
|
|
+ if (QDF_IS_STATUS_ERROR(status)) {
|
|
|
+ wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock);
|
|
|
+ goto end;
|
|
|
+ }
|
|
|
+
|
|
|
+ wma_increment_peer_count(wma, vdev_id);
|
|
|
+
|
|
|
+ msg = wma_fill_hold_req(wma, vdev_id, WMA_PEER_CREATE_REQ,
|
|
|
+ WMA_PEER_CREATE_RESPONSE, (void *)peer_addr,
|
|
|
+ WMA_PEER_CREATE_RESPONSE_TIMEOUT);
|
|
|
+ if (!msg) {
|
|
|
+ wma_err("vdev:%d failed to fill peer create req", vdev_id);
|
|
|
+ wma_remove_req(wma, vdev_id, WMA_PEER_CREATE_RESPONSE);
|
|
|
+ wma_remove_peer(wma, peer_addr, vdev_id, false);
|
|
|
+ wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock);
|
|
|
+ status = QDF_STATUS_E_FAILURE;
|
|
|
+ goto end;
|
|
|
+ }
|
|
|
+
|
|
|
+ return status;
|
|
|
+
|
|
|
+end:
|
|
|
+ lim_post_join_set_link_state_callback(mac, vdev_id, status);
|
|
|
+
|
|
|
+ return status;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -2827,6 +2919,78 @@ free_req_msg:
|
|
|
return status;
|
|
|
}
|
|
|
|
|
|
+int wma_peer_create_confirm_handler(void *handle, uint8_t *evt_param_info,
|
|
|
+ uint32_t len)
|
|
|
+{
|
|
|
+ tp_wma_handle wma = (tp_wma_handle)handle;
|
|
|
+ wmi_peer_create_conf_event_fixed_param *peer_create_rsp;
|
|
|
+ WMI_PEER_CREATE_CONF_EVENTID_param_tlvs *param_buf;
|
|
|
+ struct wma_target_req *req_msg = NULL;
|
|
|
+ struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
|
|
|
+ void *dp_soc = cds_get_context(QDF_MODULE_ID_SOC);
|
|
|
+ struct qdf_mac_addr peer_mac;
|
|
|
+ QDF_STATUS status = QDF_STATUS_E_FAILURE;
|
|
|
+ int ret = -EINVAL;
|
|
|
+
|
|
|
+ param_buf = (WMI_PEER_CREATE_CONF_EVENTID_param_tlvs *)evt_param_info;
|
|
|
+ if (!param_buf) {
|
|
|
+ wma_err("Invalid peer create conf evt buffer");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ peer_create_rsp = param_buf->fixed_param;
|
|
|
+
|
|
|
+ WMI_MAC_ADDR_TO_CHAR_ARRAY(&peer_create_rsp->peer_macaddr,
|
|
|
+ peer_mac.bytes);
|
|
|
+ if (qdf_is_macaddr_zero(&peer_mac) ||
|
|
|
+ qdf_is_macaddr_broadcast(&peer_mac) ||
|
|
|
+ qdf_is_macaddr_group(&peer_mac)) {
|
|
|
+ wma_err("Invalid bssid");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ wma_debug("vdev:%d Peer create confirm for bssid: " QDF_MAC_ADDR_FMT,
|
|
|
+ peer_create_rsp->vdev_id, QDF_MAC_ADDR_REF(peer_mac.bytes));
|
|
|
+ req_msg = wma_find_remove_req_msgtype(wma, peer_create_rsp->vdev_id,
|
|
|
+ WMA_PEER_CREATE_REQ);
|
|
|
+ if (!req_msg) {
|
|
|
+ wma_err("vdev:%d Failed to lookup peer create request message",
|
|
|
+ peer_create_rsp->vdev_id);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock);
|
|
|
+
|
|
|
+ qdf_mc_timer_stop(&req_msg->event_timeout);
|
|
|
+ qdf_mc_timer_destroy(&req_msg->event_timeout);
|
|
|
+ qdf_mem_free(req_msg);
|
|
|
+
|
|
|
+ if (!peer_create_rsp->status) {
|
|
|
+ if (!dp_soc) {
|
|
|
+ wma_err("DP SOC context is NULL");
|
|
|
+ goto fail;
|
|
|
+ }
|
|
|
+
|
|
|
+ cdp_peer_setup(dp_soc, peer_create_rsp->vdev_id,
|
|
|
+ peer_mac.bytes);
|
|
|
+
|
|
|
+ status = QDF_STATUS_SUCCESS;
|
|
|
+ ret = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+fail:
|
|
|
+ if (QDF_IS_STATUS_ERROR(status))
|
|
|
+ wma_remove_peer(wma, peer_mac.bytes, peer_create_rsp->vdev_id,
|
|
|
+ (peer_create_rsp->status > 0) ? true : false);
|
|
|
+
|
|
|
+ if (mac)
|
|
|
+ lim_post_join_set_link_state_callback(mac,
|
|
|
+ peer_create_rsp->vdev_id,
|
|
|
+ status);
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* wma_peer_delete_handler() - peer delete response handler
|
|
|
* @handle: wma handle
|
|
@@ -2937,6 +3101,7 @@ void wma_hold_req_timer(void *data)
|
|
|
{
|
|
|
tp_wma_handle wma;
|
|
|
struct wma_target_req *tgt_req = (struct wma_target_req *)data;
|
|
|
+ struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
|
|
|
QDF_STATUS status;
|
|
|
|
|
|
wma = cds_get_context(QDF_MODULE_ID_WMA);
|
|
@@ -3062,6 +3227,21 @@ void wma_hold_req_timer(void *data)
|
|
|
resp->status = SET_HW_MODE_STATUS_ECANCELED;
|
|
|
wma_send_msg_high_priority(wma, SIR_HAL_PDEV_MAC_CFG_RESP,
|
|
|
resp, 0);
|
|
|
+ } else if ((tgt_req->msg_type == WMA_PEER_CREATE_REQ) &&
|
|
|
+ (tgt_req->type == WMA_PEER_CREATE_RESPONSE)) {
|
|
|
+ if (wma_crash_on_fw_timeout(wma->fw_timeout_crash))
|
|
|
+ wma_trigger_recovery_assert_on_fw_timeout(
|
|
|
+ WMA_PEER_CREATE_RESPONSE,
|
|
|
+ WMA_PEER_CREATE_RESPONSE_TIMEOUT);
|
|
|
+
|
|
|
+ wma_remove_peer(wma, (uint8_t *)tgt_req->user_data,
|
|
|
+ tgt_req->vdev_id, false);
|
|
|
+ if (!mac)
|
|
|
+ goto timer_destroy;
|
|
|
+
|
|
|
+ lim_post_join_set_link_state_callback(mac, tgt_req->vdev_id,
|
|
|
+ QDF_STATUS_E_FAILURE);
|
|
|
+
|
|
|
} else {
|
|
|
wma_err("Unhandled timeout for msg_type:%d and type:%d",
|
|
|
tgt_req->msg_type, tgt_req->type);
|
|
@@ -4988,7 +5168,8 @@ QDF_STATUS wma_add_bss_peer_sta(uint8_t vdev_id, uint8_t *bssid)
|
|
|
if (!wma)
|
|
|
goto err;
|
|
|
|
|
|
- status = wma_create_peer(wma, bssid, WMI_PEER_TYPE_DEFAULT, vdev_id);
|
|
|
+ status = wma_create_sta_mode_bss_peer(wma, bssid, WMI_PEER_TYPE_DEFAULT,
|
|
|
+ vdev_id);
|
|
|
err:
|
|
|
return status;
|
|
|
}
|