qcacmn: Implement VDEV MLME State machine

This change implement VDEV MLME State machine based on design,
and handles valid events in each state and invokes legacy callback
APIs to perform state specific operations

Change-Id: I38a11778cba31276c720bc13c085ade60b1fb0c4
CRs-Fixed: 2307722
这个提交包含在:
Srinivas Pitla
2018-08-06 17:09:48 +05:30
提交者 nshrivas
父节点 be8dac4d5d
当前提交 90713473d1
修改 11 个文件,包含 2739 行新增154 行删除

查看文件

@@ -38,6 +38,18 @@ struct wlan_find_vdev_filter {
struct wlan_objmgr_vdev *found_vdev;
};
#ifdef CMN_VDEV_MLME_SM_ENABLE
/**
* struct wlan_vdev_ch_check_filter - vdev chan check filter object
* @flag: matches or not
* @vdev: vdev to be checked against all the active vdevs
*/
struct wlan_vdev_ch_check_filter {
uint8_t flag;
struct wlan_objmgr_vdev *vdev;
};
#endif
/**
* wlan_chan_to_freq() - converts channel to frequency
* @chan: channel number
@@ -126,9 +138,9 @@ bool wlan_is_emulation_platform(uint32_t phy_version);
/**
* wlan_get_pdev_id_from_vdev_id() - Helper func to derive pdev id from vdev_id
* @psoc : psoc object
* @vdev_id : vdev identifier
* @dbg_id : object manager debug id
* @psoc: psoc object
* @vdev_id: vdev identifier
* @dbg_id: object manager debug id
*
* This function is used to derive the pdev id from vdev id for a psoc
*
@@ -142,9 +154,9 @@ uint32_t wlan_get_pdev_id_from_vdev_id(struct wlan_objmgr_psoc *psoc,
/**
* wlan_util_get_vdev_by_ifname() - function to return vdev object from psoc
* matching given interface name
* @psoc : psoc object
* @ifname : interface name
* @ref_id : object manager ref id
* @psoc: psoc object
* @ifname: interface name
* @ref_id: object manager ref id
*
* This function returns vdev object from psoc by interface name. If found this
* will also take reference with given ref_id
@@ -167,12 +179,86 @@ struct wlan_objmgr_vdev *wlan_util_get_vdev_by_ifname(
uint8_t *wlan_util_vdev_get_if_name(struct wlan_objmgr_vdev *vdev);
/*
* wlan_util_is_vap_active() - Check for vap active
* wlan_util_is_vdev_active() - Check for vdev active
* @pdev: pdev pointer
* @dbg_id: debug id for ref counting
*
* @Return: QDF_STATUS_SUCCESS in case of vap active
* @Return: QDF_STATUS_SUCCESS in case of vdev active
*/
QDF_STATUS wlan_util_is_vap_active(struct wlan_objmgr_pdev *pdev,
wlan_objmgr_ref_dbgid dbg_id);
QDF_STATUS wlan_util_is_vdev_active(struct wlan_objmgr_pdev *pdev,
wlan_objmgr_ref_dbgid dbg_id);
/*
* wlan_vdev_is_up() - Check for vdev is in UP state
* @vdev: vdev pointer
*
* @Return: true in case of vdev is in UP state
*/
bool wlan_vdev_is_up(struct wlan_objmgr_vdev *vdev);
/**
* wlan_util_pdev_vdevs_deschan_match() - function to check des channel matches
* with other vdevs in pdev
* @pdev: pdev object
* @vdev: vdev object
* @ref_id: object manager ref id
*
* This function checks the vdev desired channel with other vdev channels
*
* Return : SUCCESS, if it matches, otherwise FAILURE
*/
QDF_STATUS wlan_util_pdev_vdevs_deschan_match(struct wlan_objmgr_pdev *pdev,
struct wlan_objmgr_vdev *vdev,
wlan_objmgr_ref_dbgid dbg_id);
/**
* wlan_util_change_map_index() - function to set/reset given index bit
* @map: bitmpap
* @id: bit index
* @set: 1 for set, 0 of reset
*
* This function set/reset given index bit
*
* Return : void
*/
void wlan_util_change_map_index(uint32_t *map, uint8_t id, uint8_t set);
/**
* wlan_util_map_index_is_set() - function to check whether given index bit is
* set
* @map: bitmpap
* @id: bit index
*
* This function checks the given index bit is set
*
* Return : true, if bit is set, otherwise false
*/
bool wlan_util_map_index_is_set(uint32_t *map, uint8_t id);
/**
* wlan_pdev_chan_change_pending_vdevs() - function to test/set channel change
* pending flag
* @pdev: pdev object
* @vdev_id_map: bitmap to derive channel change vdevs
* @ref_id: object manager ref id
*
* This function test/set channel change pending flag
*
* Return : SUCCESS, if it iterates through all vdevs, otherwise FAILURE
*/
QDF_STATUS wlan_pdev_chan_change_pending_vdevs(struct wlan_objmgr_pdev *pdev,
uint32_t *vdev_id_map,
wlan_objmgr_ref_dbgid dbg_id);
/**
* wlan_chan_eq() - function to check whether both channels are same
* @chan1: channel1 object
* @chan2: channel2 object
*
* This function checks the chan1 and chan2 are same
*
* Return : SUCCESS, if it matches, otherwise FAILURE
*/
QDF_STATUS wlan_chan_eq(struct wlan_channel *chan1, struct wlan_channel *chan2);
#endif /* _WLAN_UTILITY_H_ */

查看文件

@@ -26,6 +26,7 @@
#include "wlan_osif_priv.h"
#include <net/cfg80211.h>
#include <qdf_module.h>
#include <wlan_vdev_mlme_api.h>
uint32_t wlan_chan_to_freq(uint8_t chan)
{
@@ -257,36 +258,208 @@ uint8_t *wlan_util_vdev_get_if_name(struct wlan_objmgr_vdev *vdev)
}
qdf_export_symbol(wlan_util_vdev_get_if_name);
static void wlan_vap_active(struct wlan_objmgr_pdev *pdev,
void *object,
void *arg)
#ifdef CMN_VDEV_MLME_SM_ENABLE
static void wlan_vdev_active(struct wlan_objmgr_pdev *pdev, void *object,
void *arg)
{
struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object;
uint8_t *flag = (uint8_t *)arg;
wlan_vdev_obj_lock(vdev);
if (wlan_vdev_mlme_is_active(vdev) == QDF_STATUS_SUCCESS)
*flag = 1;
wlan_vdev_obj_unlock(vdev);
}
bool wlan_vdev_is_up(struct wlan_objmgr_vdev *vdev)
{
bool ret_val = false;
if (wlan_vdev_allow_connect_n_tx(vdev) == QDF_STATUS_SUCCESS)
ret_val = true;
return ret_val;
}
qdf_export_symbol(wlan_vdev_is_up);
#else
static void wlan_vdev_active(struct wlan_objmgr_pdev *pdev, void *object,
void *arg)
{
struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object;
uint8_t *flag = (uint8_t *)arg;
wlan_vdev_obj_lock(vdev);
if ((wlan_vdev_mlme_get_state(vdev) == WLAN_VDEV_S_RUN) ||
(wlan_vdev_mlme_get_state(vdev) == WLAN_VDEV_S_DFS_WAIT)) {
(wlan_vdev_mlme_get_state(vdev) == WLAN_VDEV_S_DFS_WAIT))
*flag = 1;
}
wlan_vdev_obj_unlock(vdev);
}
QDF_STATUS wlan_util_is_vap_active(struct wlan_objmgr_pdev *pdev,
wlan_objmgr_ref_dbgid dbg_id)
bool wlan_vdev_is_up(struct wlan_objmgr_vdev *vdev)
{
bool ret_val = false;
wlan_vdev_obj_lock(vdev);
if (wlan_vdev_mlme_get_state(vdev) == WLAN_VDEV_S_RUN)
ret_val = true;
wlan_vdev_obj_unlock(vdev);
return ret_val;
}
qdf_export_symbol(wlan_vdev_is_up);
#endif
QDF_STATUS wlan_util_is_vdev_active(struct wlan_objmgr_pdev *pdev,
wlan_objmgr_ref_dbgid dbg_id)
{
uint8_t flag = 0;
if (!pdev)
return QDF_STATUS_E_INVAL;
wlan_objmgr_pdev_iterate_obj_list(pdev,
WLAN_VDEV_OP,
wlan_vap_active,
&flag, 0, dbg_id);
wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP, wlan_vdev_active,
&flag, 0, dbg_id);
if (flag == 1)
return QDF_STATUS_SUCCESS;
return QDF_STATUS_E_INVAL;
}
#ifdef CMN_VDEV_MLME_SM_ENABLE
void wlan_util_change_map_index(uint32_t *map, uint8_t id, uint8_t set)
{
uint8_t map_index = 0;
uint8_t map_entry_size = 32;
uint8_t adjust_index = 0;
/*
* Derive map_index and adjust_index to find actual DWORD
* the id map is present
*/
while ((id - adjust_index) >= map_entry_size) {
map_index++;
adjust_index = map_index * map_entry_size;
}
if (set)
map[map_index] |= (1 << (id - adjust_index));
else
map[map_index] &= ~(1 << (id - adjust_index));
}
bool wlan_util_map_index_is_set(uint32_t *map, uint8_t id)
{
uint8_t map_index = 0;
uint8_t map_entry_size = 32;
uint8_t adjust_index = 0;
/*
* Derive map_index and adjust_index to find actual DWORD
* the id map is present
*/
while ((id - adjust_index) >= map_entry_size) {
map_index++;
adjust_index = map_index * map_entry_size;
}
if (map[map_index] & (1 << (id - adjust_index)))
return true;
return false;
}
static void wlan_vdev_chan_change_pending(struct wlan_objmgr_pdev *pdev,
void *object, void *arg)
{
struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object;
uint32_t *vdev_id_map = (uint32_t *)arg;
uint8_t id = 0;
struct wlan_objmgr_psoc *psoc;
psoc = wlan_pdev_get_psoc(pdev);
if (!psoc)
return;
wlan_vdev_obj_lock(vdev);
if (wlan_vdev_chan_config_valid(vdev) == QDF_STATUS_SUCCESS) {
id = wlan_vdev_get_id(vdev);
/* Invalid vdev id */
if (id >= wlan_psoc_get_max_vdev_count(psoc))
return;
wlan_util_change_map_index(vdev_id_map, id, 1);
}
wlan_vdev_obj_unlock(vdev);
}
QDF_STATUS wlan_pdev_chan_change_pending_vdevs(struct wlan_objmgr_pdev *pdev,
uint32_t *vdev_id_map,
wlan_objmgr_ref_dbgid dbg_id)
{
if (!pdev)
return QDF_STATUS_E_INVAL;
wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP,
wlan_vdev_chan_change_pending,
vdev_id_map, 0, dbg_id);
return QDF_STATUS_SUCCESS;
}
QDF_STATUS wlan_chan_eq(struct wlan_channel *chan1, struct wlan_channel *chan2)
{
if (!qdf_mem_cmp(chan1, chan2, sizeof(struct wlan_channel)))
return QDF_STATUS_SUCCESS;
return QDF_STATUS_E_FAILURE;
}
static void wlan_pdev_chan_match(struct wlan_objmgr_pdev *pdev, void *object,
void *arg)
{
struct wlan_objmgr_vdev *comp_vdev = (struct wlan_objmgr_vdev *)object;
struct wlan_vdev_ch_check_filter *ch_filter = arg;
if (ch_filter->flag)
return;
wlan_vdev_obj_lock(comp_vdev);
wlan_vdev_obj_lock(ch_filter->vdev);
if (wlan_vdev_chan_config_valid(ch_filter->vdev) == QDF_STATUS_SUCCESS)
if (wlan_chan_eq(wlan_vdev_mlme_get_des_chan(comp_vdev),
wlan_vdev_mlme_get_des_chan(ch_filter->vdev))
!= QDF_STATUS_SUCCESS)
ch_filter->flag = 1;
wlan_vdev_obj_unlock(ch_filter->vdev);
wlan_vdev_obj_unlock(comp_vdev);
}
QDF_STATUS wlan_util_pdev_vdevs_deschan_match(struct wlan_objmgr_pdev *pdev,
struct wlan_objmgr_vdev *vdev,
wlan_objmgr_ref_dbgid dbg_id)
{
struct wlan_vdev_ch_check_filter ch_filter;
if (!pdev)
return QDF_STATUS_E_INVAL;
ch_filter.flag = 0;
ch_filter.vdev = vdev;
wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP,
wlan_pdev_chan_match, &ch_filter, 0,
dbg_id);
if (ch_filter.flag == 0)
return QDF_STATUS_SUCCESS;
return QDF_STATUS_E_FAILURE;
}
#endif