qcacmn: Ignore deauth ind received when in DEAUTH_REQ substate

P2P GO received deauth frame from p2p client and del_station is
received from userspace. As part of del_station FORCE_DEAUTH_STA
command is processed. Deauth frame is processed after this which
sends DEAUTH_IND to csr. Wm status change command is enqueued and
is not processed since there is already an active command. Cleanup
is done as part of del_station. Auth frame received is processed
and auth rsp is sent. Message is posted to lim on receiving assoc
req frame from p2p client. Wm status change command is processed
and DEAUTH_CNF msg is posted to lim. Assoc req frame is processed
and ASSOC_CNF is posted to lim. DEAUTH_CNF is processed before
ASSOC_CNF due to which sta_ds entry is removed. Assoc resp is
not transmitted as a result and p2p group formation fails.

Fix is to ignore deauth indication received when csr substate
is DEAUTH_REQ.

Change-Id: Ia1966a4cced3faf15605aeb3d69b8fafa2176c22
CRs-Fixed: 2269609
This commit is contained in:
Yeshwanth Sriram Guntuka 2018-06-22 16:57:56 +05:30 • committed by nshrivas
commit f48e5a8e20
2 changed files with 82 additions and 1 deletions

View file

@ -486,5 +486,21 @@ wlan_serialization_get_scan_cmd_using_scan_id(
struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id, uint16_t scan_id,
uint8_t is_scan_cmd_from_active_queue);
/**
* wlan_serialization_get_active_cmd() - Return active umac command which
* matches vdev and cmd type
* @psoc: pointer to soc
* @vdev_id: vdev id to pull vdev object
* @cmd_type: cmd type to match
*
* This API fetches vdev/pdev object based on vdev_id, loops through active
* command queue and find the active command which matches cmd_type as well
* as vdev object.
*
* Return: Pointer to umac command. NULL is returned if active command of given
* type is not found.
*/
void *wlan_serialization_get_active_cmd(struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id,
enum wlan_serialization_cmd_type cmd_type);
#endif

View file

@ -380,3 +380,68 @@ release_vdev_ref:
wlan_objmgr_vdev_release_ref(vdev, WLAN_SERIALIZATION_ID);
return cmd;
}
void *wlan_serialization_get_active_cmd(struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id,
enum wlan_serialization_cmd_type cmd_type)
{
uint32_t qlen;
struct wlan_objmgr_vdev *vdev;
struct wlan_objmgr_pdev *pdev;
struct wlan_serialization_pdev_priv_obj *ser_pdev_obj;
struct wlan_serialization_command_list *cmd_list = NULL;
void *umac_cmd = NULL;
qdf_list_node_t *nnode = NULL;
qdf_list_t *queue;
if (!psoc) {
serialization_err("invalid psoc");
return umac_cmd;
}
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
WLAN_SERIALIZATION_ID);
if (!vdev) {
serialization_err("invalid vdev");
return umac_cmd;
}
pdev = wlan_vdev_get_pdev(vdev);
if (!pdev) {
serialization_err("invalid pdev");
goto release_vdev_ref;
}
ser_pdev_obj = wlan_serialization_get_pdev_priv_obj(pdev);
if (!ser_pdev_obj) {
serialization_err("invalid ser_pdev_obj");
goto release_vdev_ref;
}
queue = &ser_pdev_obj->active_list;
qlen = qdf_list_size(queue);
if (!qlen) {
serialization_err("Empty Queue");
goto release_vdev_ref;
}
while (qlen--) {
if (QDF_STATUS_SUCCESS != wlan_serialization_get_cmd_from_queue(
queue, &nnode)) {
serialization_err("unsuccessful attempt");
break;
}
cmd_list = qdf_container_of(nnode,
struct wlan_serialization_command_list,
node);
if (cmd_list->cmd.cmd_type == cmd_type &&
cmd_list->cmd.vdev == vdev) {
serialization_debug("cmd_type[%d] matched", cmd_type);
umac_cmd = cmd_list->cmd.umac_cmd;
break;
}
}
release_vdev_ref:
wlan_objmgr_vdev_release_ref(vdev, WLAN_SERIALIZATION_ID);
return umac_cmd;
}