qcacld-3.0: Block NDP_END_ALL req till last NDP_END is received

Firmware sends NDP_HOST_UPDATE event as an immediate response to this
request and starts cleaning peers one by one. Once an NDP session is
ended (indicating NDP_END to peer + internal cleanup), firmware sends
NDP_END_IND to host.
Currently, host driver stops the wait timer and change state from NDP
end to disconnected upon receiving the NDP_HOST_UPDATE. But firmware
might still be in the process of NDP cleanup. As the NDP_END_ALL
context is unblocked, driver may send NAN disable request to firmware.
This may cause inconsistency in firmware state machine and firmware may
drop the ongoing NDP_END request. So, peer doesn't get the NDP_END frame
in such cases.

Unblock the NDP_END_ALL-wait call only upon last NDP_END indication to
avoid such issues. This change moves the major functionality of
NDP_HOST_UPDATE processing to last NDP_END indication. Cleanup/remove
the processing of NDP_HOST_UPDATE as it's not needed anymore.

Change-Id: I19d3e40700c1c0501b9c809820262472bf9bdba4
CRs-Fixed: 3512847
此提交包含在:
Rahul Gusain
2023-05-26 13:12:52 +05:30
提交者 Rahul Choudhary
父節點 9df82708b2
當前提交 54c2fe240a
共有 6 個檔案被更改,包括 46 行新增174 行删除

查看文件

@@ -1980,6 +1980,42 @@ static void os_if_new_peer_ind_handler(struct wlan_objmgr_vdev *vdev,
osif_debug("num_peers: %d", active_peers);
}
/**
* os_if_ndp_end_all_handler: Handler for NDP_END_ALL request cmd
* @psoc: pointer to psoc object
* @vdev_id: vdev id of ndi
*
* Return: None
*/
static void os_if_ndp_end_all_handler(struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id)
{
struct wlan_objmgr_vdev *vdev;
struct nan_vdev_priv_obj *vdev_nan_obj;
struct osif_request *request;
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, WLAN_NAN_ID);
if (!vdev) {
osif_err("vdev is NULL for vdev_id %d", vdev_id);
return;
}
vdev_nan_obj = nan_get_vdev_priv_obj(vdev);
if (!vdev_nan_obj) {
osif_err("vdev_nan_obj is NULL");
return;
}
request = osif_request_get(vdev_nan_obj->disable_context);
if (!request) {
osif_debug("Obsolete request");
return;
}
osif_request_complete(request);
osif_request_put(request);
}
/**
* os_if_peer_departed_ind_handler() - Handle NDP peer departed indication
* @vdev: vdev object
@@ -2013,6 +2049,10 @@ static void os_if_peer_departed_ind_handler(struct wlan_objmgr_vdev *vdev,
cb_obj.peer_departed_ind(vdev_id, peer_ind->sta_id,
&peer_ind->peer_mac_addr,
(active_peers == 0 ? true : false));
/* if no peer left, stop wait timer for NDP_END_ALL` */
if (!active_peers)
os_if_ndp_end_all_handler(psoc, vdev_id);
}
static inline uint32_t osif_ndp_get_ndi_create_rsp_len(void)
@@ -2351,39 +2391,6 @@ ndp_sch_ind_nla_failed:
wlan_cfg80211_vendor_free_skb(vendor_event);
}
/**
* os_if_ndp_host_update_handler() - NDP Host update handler
* @vdev: vdev object pointer
* @evt: pointer to host update event
*
* Return: none
*/
static void os_if_ndp_host_update_handler(struct wlan_objmgr_vdev *vdev,
void *evt)
{
struct nan_vdev_priv_obj *vdev_nan_obj;
struct nan_datapath_host_event *event;
struct osif_request *request;
vdev_nan_obj = nan_get_vdev_priv_obj(vdev);
if (!vdev_nan_obj) {
osif_err("vdev_nan_obj is NULL");
return;
}
request = osif_request_get(vdev_nan_obj->disable_context);
if (!request) {
osif_debug("Obsolete request");
return;
}
event = osif_request_priv(request);
qdf_mem_copy(event, evt, sizeof(*event));
osif_request_complete(request);
osif_request_put(request);
}
static void os_if_nan_datapath_event_handler(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_vdev *vdev,
uint32_t type, void *msg)
@@ -2422,9 +2429,6 @@ static void os_if_nan_datapath_event_handler(struct wlan_objmgr_psoc *psoc,
case NDP_SCHEDULE_UPDATE:
os_if_ndp_sch_update_ind_handler(vdev, msg);
break;
case NDP_HOST_UPDATE:
os_if_ndp_host_update_handler(vdev, msg);
break;
default:
break;
}