mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-11 07:03:09 -04:00
qcacmn: P2P protocol changes to Disable/Enable NOA
P2P-GO whenever goes offchannel, issues NOA. With this behavior, we
have issue whenever legacy STA connects to P2P-GO since legacy STA
does not understand NOA. To handle this case, changes are done in p2p
protocol component and the revised behavior will be:
1. By default no change in NOA.
2. Whenever first legacy STA connects to GO, p2p protocol component
disables NOA (i.e. P2P-GO will issue Self-CTS whenever it goes
off-channel).
3. Whenever last legacy STA disconnects from GO, p2p protocol
component enables NOA (i.e. P2P-GO will issue NOA whenever it goes
off-channel).
Change-Id: I113950ac3fa99ca68fcafcfe4c6095cf4b2def43
CRs-Fixed: 2035609
This commit is contained in:
parent
7d867d6729
commit
4475ff297c
10 changed files with 399 additions and 12 deletions
|
|
@ -121,4 +121,17 @@ QDF_STATUS target_if_p2p_lo_start(struct wlan_objmgr_psoc *psoc,
|
|||
QDF_STATUS target_if_p2p_lo_stop(struct wlan_objmgr_psoc *psoc,
|
||||
uint32_t vdev_id);
|
||||
|
||||
/**
|
||||
* target_if_p2p_set_noa() - Disable / Enable NOA
|
||||
* @psoc: soc object
|
||||
* @vdev_id: vdev id
|
||||
* @disable_noa: TRUE - Disable NoA, FALSE - Enable NoA
|
||||
*
|
||||
* Target interface API to Disable / Enable P2P NOA.
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS - in case of success
|
||||
*/
|
||||
QDF_STATUS target_if_p2p_set_noa(struct wlan_objmgr_psoc *psoc,
|
||||
uint32_t vdev_id, bool disable_noa);
|
||||
|
||||
#endif /* _TARGET_IF_P2P_H_ */
|
||||
|
|
|
|||
|
|
@ -326,6 +326,26 @@ QDF_STATUS target_if_p2p_lo_stop(struct wlan_objmgr_psoc *psoc,
|
|||
(uint8_t)vdev_id);
|
||||
}
|
||||
|
||||
QDF_STATUS target_if_p2p_set_noa(struct wlan_objmgr_psoc *psoc,
|
||||
uint32_t vdev_id, bool disable_noa)
|
||||
{
|
||||
struct vdev_set_params param;
|
||||
wmi_unified_t wmi_handle = wlan_psoc_get_tgt_if_handle(psoc);
|
||||
|
||||
if (!wmi_handle) {
|
||||
target_if_err("Invalid wmi handle");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
target_if_debug("psoc:%p, vdev_id:%d disable_noa:%d",
|
||||
psoc, vdev_id, disable_noa);
|
||||
param.if_id = vdev_id;
|
||||
param.param_id = WMI_VDEV_PARAM_DISABLE_NOA_P2P_GO;
|
||||
param.param_value = (uint32_t)disable_noa;
|
||||
|
||||
return wmi_unified_vdev_set_param_send(wmi_handle, ¶m);
|
||||
}
|
||||
|
||||
void target_if_p2p_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
|
||||
{
|
||||
struct wlan_lmac_if_p2p_tx_ops *p2p_tx_ops;
|
||||
|
|
@ -339,6 +359,7 @@ void target_if_p2p_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
|
|||
p2p_tx_ops->set_ps = target_if_p2p_set_ps;
|
||||
p2p_tx_ops->lo_start = target_if_p2p_lo_start;
|
||||
p2p_tx_ops->lo_stop = target_if_p2p_lo_stop;
|
||||
p2p_tx_ops->set_noa = target_if_p2p_set_noa;
|
||||
p2p_tx_ops->reg_lo_ev_handler =
|
||||
target_if_p2p_register_lo_event_handler;
|
||||
p2p_tx_ops->reg_noa_ev_handler =
|
||||
|
|
|
|||
|
|
@ -198,7 +198,9 @@ enum wlan_phymode {
|
|||
* enum wlan_peer_type - peer type
|
||||
* @WLAN_PEER_SELF: for AP mode, SELF PEER or AP PEER are same
|
||||
* @WLAN_PEER_AP: BSS peer for STA mode, Self peer for AP mode
|
||||
* @WLAN_PEER_P2P_GO: BSS peer for P2P CLI mode, Self peer for P2P GO mode
|
||||
* @WLAN_PEER_STA: Self Peer for STA mode, STA peer for AP mode
|
||||
* @WLAN_PEER_P2P_CLI: Self peer for P2P CLI mode, P2P CLI peer for P2P GO mode
|
||||
* @WLAN_PEER_TDLS: TDLS Peer
|
||||
* @WLAN_PEER_NAWDS: NAWDS Peer
|
||||
* @WLAN_PEER_STA_TEMP: STA Peer Temp (its host only node)
|
||||
|
|
@ -207,11 +209,13 @@ enum wlan_phymode {
|
|||
enum wlan_peer_type {
|
||||
WLAN_PEER_SELF = 1,
|
||||
WLAN_PEER_AP = 2,
|
||||
WLAN_PEER_STA = 3,
|
||||
WLAN_PEER_TDLS = 4,
|
||||
WLAN_PEER_NAWDS = 5,
|
||||
WLAN_PEER_STA_TEMP = 6,
|
||||
WLAN_PEER_IBSS = 7,
|
||||
WLAN_PEER_P2P_GO = 3,
|
||||
WLAN_PEER_STA = 4,
|
||||
WLAN_PEER_P2P_CLI = 5,
|
||||
WLAN_PEER_TDLS = 6,
|
||||
WLAN_PEER_NAWDS = 7,
|
||||
WLAN_PEER_STA_TEMP = 8,
|
||||
WLAN_PEER_IBSS = 9,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -164,7 +164,8 @@ struct wlan_objmgr_peer *wlan_objmgr_peer_obj_create(
|
|||
qdf_spinlock_create(&peer->peer_lock);
|
||||
wlan_objmgr_peer_get_ref(peer, WLAN_OBJMGR_ID);
|
||||
/* Increment ref count for BSS peer, so that BSS peer deletes last*/
|
||||
if ((type == WLAN_PEER_STA) || (type == WLAN_PEER_STA_TEMP))
|
||||
if ((type == WLAN_PEER_STA) || (type == WLAN_PEER_STA_TEMP)
|
||||
|| (type == WLAN_PEER_P2P_CLI))
|
||||
wlan_objmgr_peer_get_ref(wlan_vdev_get_bsspeer(vdev),
|
||||
WLAN_OBJMGR_ID);
|
||||
/* TODO init other parameters */
|
||||
|
|
|
|||
|
|
@ -580,7 +580,8 @@ QDF_STATUS wlan_objmgr_vdev_peer_attach(struct wlan_objmgr_vdev *vdev,
|
|||
wlan_obj_vdev_peerlist_add_tail(&objmgr->wlan_peer_list, peer);
|
||||
objmgr->wlan_peer_count++;
|
||||
|
||||
if (wlan_peer_get_peer_type(peer) == WLAN_PEER_AP) {
|
||||
if ((wlan_peer_get_peer_type(peer) == WLAN_PEER_AP) ||
|
||||
(wlan_peer_get_peer_type(peer) == WLAN_PEER_P2P_GO)) {
|
||||
if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer),
|
||||
wlan_vdev_mlme_get_macaddr(vdev)) ==
|
||||
QDF_STATUS_SUCCESS) {
|
||||
|
|
@ -615,7 +616,8 @@ QDF_STATUS wlan_objmgr_vdev_peer_detach(struct wlan_objmgr_vdev *vdev,
|
|||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (wlan_peer_get_peer_type(peer) == WLAN_PEER_AP) {
|
||||
if ((wlan_peer_get_peer_type(peer) == WLAN_PEER_AP) ||
|
||||
(wlan_peer_get_peer_type(peer) == WLAN_PEER_P2P_GO)) {
|
||||
if (wlan_vdev_get_selfpeer(vdev) == peer) {
|
||||
/*
|
||||
* There might be instances where new node is created
|
||||
|
|
|
|||
|
|
@ -253,6 +253,7 @@ struct p2p_lo_start;
|
|||
* @set_ps: function pointer to set power save
|
||||
* @lo_start: function pointer to start listen offload
|
||||
* @lo_stop: function pointer to stop listen offload
|
||||
* @set_noa: function pointer to disable/enable NOA
|
||||
* @reg_lo_ev_handler: function pointer to register lo event handler
|
||||
* @reg_noa_ev_handler: function pointer to register noa event handler
|
||||
* @unreg_lo_ev_handler: function pointer to unregister lo event handler
|
||||
|
|
@ -265,6 +266,8 @@ struct wlan_lmac_if_p2p_tx_ops {
|
|||
struct p2p_lo_start *lo_start);
|
||||
QDF_STATUS (*lo_stop)(struct wlan_objmgr_psoc *psoc,
|
||||
uint32_t vdev_id);
|
||||
QDF_STATUS (*set_noa)(struct wlan_objmgr_psoc *psoc,
|
||||
uint32_t vdev_id, bool disable_noa);
|
||||
QDF_STATUS (*reg_lo_ev_handler)(struct wlan_objmgr_psoc *psoc,
|
||||
void *arg);
|
||||
QDF_STATUS (*reg_noa_ev_handler)(struct wlan_objmgr_psoc *psoc,
|
||||
|
|
|
|||
|
|
@ -211,6 +211,8 @@ static QDF_STATUS p2p_vdev_obj_create_notification(
|
|||
}
|
||||
|
||||
p2p_vdev_obj->vdev = vdev;
|
||||
p2p_vdev_obj->noa_status = true;
|
||||
p2p_vdev_obj->non_p2p_peer_count = 0;
|
||||
|
||||
status = wlan_objmgr_vdev_component_obj_attach(vdev,
|
||||
WLAN_UMAC_COMP_P2P, p2p_vdev_obj,
|
||||
|
|
@ -285,6 +287,127 @@ static QDF_STATUS p2p_vdev_obj_destroy_notification(
|
|||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* p2p_peer_obj_create_notification() - manages peer details per vdev
|
||||
* @peer: peer object
|
||||
* @arg: Pointer to private argument - NULL
|
||||
*
|
||||
* This function gets called from object manager when peer is being
|
||||
* created.
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS - in case of success
|
||||
*/
|
||||
static QDF_STATUS p2p_peer_obj_create_notification(
|
||||
struct wlan_objmgr_peer *peer, void *arg)
|
||||
{
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
struct p2p_vdev_priv_obj *p2p_vdev_obj;
|
||||
enum tQDF_ADAPTER_MODE mode;
|
||||
enum wlan_peer_type peer_type;
|
||||
|
||||
if (!peer) {
|
||||
p2p_err("peer context passed is NULL");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
wlan_peer_obj_lock(peer);
|
||||
vdev = wlan_peer_get_vdev(peer);
|
||||
wlan_peer_obj_unlock(peer);
|
||||
p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev,
|
||||
WLAN_UMAC_COMP_P2P);
|
||||
wlan_peer_obj_lock(peer);
|
||||
peer_type = wlan_peer_get_peer_type(peer);
|
||||
wlan_peer_obj_unlock(peer);
|
||||
if ((peer_type == WLAN_PEER_STA) && p2p_vdev_obj) {
|
||||
|
||||
wlan_vdev_obj_lock(vdev);
|
||||
mode = wlan_vdev_mlme_get_opmode(vdev);
|
||||
wlan_vdev_obj_unlock(vdev);
|
||||
if (mode == QDF_P2P_GO_MODE) {
|
||||
p2p_vdev_obj->non_p2p_peer_count++;
|
||||
p2p_debug("Non P2P peer count: %d",
|
||||
p2p_vdev_obj->non_p2p_peer_count);
|
||||
}
|
||||
}
|
||||
p2p_debug("p2p peer object create successful");
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* p2p_peer_obj_destroy_notification() - clears peer details per vdev
|
||||
* @peer: peer object
|
||||
* @arg: Pointer to private argument - NULL
|
||||
*
|
||||
* This function gets called from object manager when peer is being
|
||||
* destroyed.
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS - in case of success
|
||||
*/
|
||||
static QDF_STATUS p2p_peer_obj_destroy_notification(
|
||||
struct wlan_objmgr_peer *peer, void *arg)
|
||||
{
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
struct p2p_vdev_priv_obj *p2p_vdev_obj;
|
||||
struct wlan_objmgr_psoc *psoc;
|
||||
enum tQDF_ADAPTER_MODE mode;
|
||||
enum wlan_peer_type peer_type;
|
||||
uint8_t vdev_id;
|
||||
|
||||
if (!peer) {
|
||||
p2p_err("peer context passed is NULL");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
wlan_peer_obj_lock(peer);
|
||||
vdev = wlan_peer_get_vdev(peer);
|
||||
wlan_peer_obj_unlock(peer);
|
||||
p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev,
|
||||
WLAN_UMAC_COMP_P2P);
|
||||
wlan_vdev_obj_lock(vdev);
|
||||
psoc = wlan_vdev_get_psoc(vdev);
|
||||
wlan_vdev_obj_unlock(vdev);
|
||||
if (!p2p_vdev_obj || !psoc) {
|
||||
p2p_err("p2p_vdev_obj:%p psoc:%p", p2p_vdev_obj, psoc);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
wlan_vdev_obj_lock(vdev);
|
||||
mode = wlan_vdev_mlme_get_opmode(vdev);
|
||||
wlan_vdev_obj_unlock(vdev);
|
||||
|
||||
wlan_peer_obj_lock(peer);
|
||||
peer_type = wlan_peer_get_peer_type(peer);
|
||||
wlan_peer_obj_unlock(peer);
|
||||
|
||||
if ((peer_type == WLAN_PEER_STA) && (mode == QDF_P2P_GO_MODE)) {
|
||||
|
||||
p2p_vdev_obj->non_p2p_peer_count--;
|
||||
|
||||
if (!p2p_vdev_obj->non_p2p_peer_count &&
|
||||
(p2p_vdev_obj->noa_status == false)) {
|
||||
|
||||
wlan_vdev_obj_lock(vdev);
|
||||
vdev_id = wlan_vdev_get_id(vdev);
|
||||
wlan_vdev_obj_unlock(vdev);
|
||||
|
||||
if (ucfg_p2p_set_noa(psoc, vdev_id,
|
||||
false) == QDF_STATUS_SUCCESS)
|
||||
p2p_vdev_obj->noa_status = true;
|
||||
else
|
||||
p2p_vdev_obj->noa_status = false;
|
||||
|
||||
p2p_debug("Non p2p peer disconnected from GO,NOA status: %d.",
|
||||
p2p_vdev_obj->noa_status);
|
||||
}
|
||||
p2p_debug("Non P2P peer count: %d",
|
||||
p2p_vdev_obj->non_p2p_peer_count);
|
||||
}
|
||||
p2p_debug("p2p peer object destroy successful");
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* p2p_send_noa_to_pe() - send noa information to pe
|
||||
* @noa_info: vdev context
|
||||
|
|
@ -348,6 +471,68 @@ static QDF_STATUS p2p_send_noa_to_pe(struct p2p_noa_info *noa_info)
|
|||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* process_peer_for_noa() - disable NoA
|
||||
* @vdev: vdev object
|
||||
* @psoc: soc object
|
||||
* @peer: peer object
|
||||
*
|
||||
* This function disables NoA
|
||||
*
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
static QDF_STATUS process_peer_for_noa(struct wlan_objmgr_vdev *vdev,
|
||||
struct wlan_objmgr_psoc *psoc,
|
||||
struct wlan_objmgr_peer *peer)
|
||||
{
|
||||
struct p2p_vdev_priv_obj *p2p_vdev_obj = NULL;
|
||||
enum tQDF_ADAPTER_MODE mode;
|
||||
enum wlan_peer_type peer_type;
|
||||
bool disable_noa;
|
||||
uint8_t vdev_id;
|
||||
|
||||
if (!vdev || !psoc || !peer) {
|
||||
p2p_err("vdev:%p psoc:%p peer:%p", vdev, psoc, peer);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev,
|
||||
WLAN_UMAC_COMP_P2P);
|
||||
if (!p2p_vdev_obj) {
|
||||
p2p_err("p2p_vdev_obj:%p", p2p_vdev_obj);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
wlan_vdev_obj_lock(vdev);
|
||||
mode = wlan_vdev_mlme_get_opmode(vdev);
|
||||
wlan_vdev_obj_unlock(vdev);
|
||||
|
||||
wlan_peer_obj_lock(peer);
|
||||
peer_type = wlan_peer_get_peer_type(peer);
|
||||
wlan_peer_obj_unlock(peer);
|
||||
|
||||
disable_noa = ((mode == QDF_P2P_GO_MODE)
|
||||
&& p2p_vdev_obj->non_p2p_peer_count
|
||||
&& p2p_vdev_obj->noa_status);
|
||||
|
||||
if (disable_noa && (peer_type == WLAN_PEER_STA)) {
|
||||
|
||||
wlan_vdev_obj_lock(vdev);
|
||||
vdev_id = wlan_vdev_get_id(vdev);
|
||||
wlan_vdev_obj_unlock(vdev);
|
||||
|
||||
if (ucfg_p2p_set_noa(psoc, vdev_id,
|
||||
true) == QDF_STATUS_SUCCESS) {
|
||||
p2p_vdev_obj->noa_status = false;
|
||||
} else {
|
||||
p2p_vdev_obj->noa_status = true;
|
||||
}
|
||||
p2p_debug("NoA status: %d", p2p_vdev_obj->noa_status);
|
||||
}
|
||||
p2p_debug("process_peer_for_noa");
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
QDF_STATUS p2p_component_init(void)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
|
|
@ -388,9 +573,33 @@ QDF_STATUS p2p_component_init(void)
|
|||
goto err_reg_vdev_delete;
|
||||
}
|
||||
|
||||
status = wlan_objmgr_register_peer_create_handler(
|
||||
WLAN_UMAC_COMP_P2P,
|
||||
p2p_peer_obj_create_notification,
|
||||
NULL);
|
||||
if (status != QDF_STATUS_SUCCESS) {
|
||||
p2p_err("Failed to register p2p peer create handler");
|
||||
goto err_reg_peer_create;
|
||||
}
|
||||
|
||||
status = wlan_objmgr_register_peer_destroy_handler(
|
||||
WLAN_UMAC_COMP_P2P,
|
||||
p2p_peer_obj_destroy_notification,
|
||||
NULL);
|
||||
if (status != QDF_STATUS_SUCCESS) {
|
||||
p2p_err("Failed to register p2p peer destroy handler");
|
||||
goto err_reg_peer_destroy;
|
||||
}
|
||||
|
||||
p2p_debug("Register p2p obj handler successful");
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
err_reg_peer_destroy:
|
||||
wlan_objmgr_unregister_peer_create_handler(WLAN_UMAC_COMP_P2P,
|
||||
p2p_peer_obj_create_notification, NULL);
|
||||
err_reg_peer_create:
|
||||
wlan_objmgr_unregister_vdev_destroy_handler(WLAN_UMAC_COMP_P2P,
|
||||
p2p_vdev_obj_destroy_notification, NULL);
|
||||
err_reg_vdev_delete:
|
||||
wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_P2P,
|
||||
p2p_vdev_obj_create_notification, NULL);
|
||||
|
|
@ -810,3 +1019,35 @@ fail:
|
|||
|
||||
return status;
|
||||
}
|
||||
|
||||
void p2p_peer_authorized(struct wlan_objmgr_vdev *vdev, uint8_t *mac_addr)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
struct wlan_objmgr_psoc *psoc;
|
||||
struct wlan_objmgr_peer *peer;
|
||||
|
||||
if (!vdev) {
|
||||
p2p_err("vdev:%p", vdev);
|
||||
return;
|
||||
}
|
||||
wlan_vdev_obj_lock(vdev);
|
||||
psoc = wlan_vdev_get_psoc(vdev);
|
||||
wlan_vdev_obj_unlock(vdev);
|
||||
if (!psoc) {
|
||||
p2p_err("psoc:%p", psoc);
|
||||
return;
|
||||
}
|
||||
peer = wlan_objmgr_get_peer(psoc, mac_addr, WLAN_P2P_ID);
|
||||
if (!peer) {
|
||||
p2p_debug("peer info not found");
|
||||
return;
|
||||
}
|
||||
status = process_peer_for_noa(vdev, psoc, peer);
|
||||
wlan_objmgr_peer_release_ref(peer, WLAN_P2P_ID);
|
||||
|
||||
if (status != QDF_STATUS_SUCCESS) {
|
||||
p2p_err("status:%u", status);
|
||||
return;
|
||||
}
|
||||
p2p_debug("peer is authorized");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -154,12 +154,16 @@ struct p2p_soc_priv_obj {
|
|||
|
||||
/**
|
||||
* struct p2p_vdev_priv_obj - Per vdev p2p private object
|
||||
* @vdev: Pointer to vdev context
|
||||
* @noa_info: NoA information
|
||||
* @vdev: Pointer to vdev context
|
||||
* @noa_info: NoA information
|
||||
* @noa_status: NoA status i.e. Enabled / Disabled (TRUE/FALSE)
|
||||
* @non_p2p_peer_count: Number of legacy stations connected to this GO
|
||||
*/
|
||||
struct p2p_vdev_priv_obj {
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
struct p2p_noa_info *noa_info;
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
struct p2p_noa_info *noa_info;
|
||||
bool noa_status;
|
||||
uint16_t non_p2p_peer_count;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -262,4 +262,29 @@ QDF_STATUS ucfg_p2p_lo_start(struct wlan_objmgr_psoc *soc,
|
|||
QDF_STATUS ucfg_p2p_lo_stop(struct wlan_objmgr_psoc *soc,
|
||||
uint32_t vdev_id);
|
||||
|
||||
/**
|
||||
* p2p_peer_authorized() - Process peer authorized event
|
||||
* @vdev: vdev structure to which peer is associated
|
||||
* @mac_addr: peer mac address
|
||||
*
|
||||
* This function handles disables noa whenever a legacy station
|
||||
* complete 4-way handshake after association.
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
void p2p_peer_authorized(struct wlan_objmgr_vdev *vdev, uint8_t *mac_addr);
|
||||
|
||||
/**
|
||||
* ucfg_p2p_set_noa() - Disable/Enable NOA
|
||||
* @soc: soc context
|
||||
* @vdev_id: vdev id
|
||||
* @disable_noa: TRUE - Disable NoA, FALSE - Enable NoA
|
||||
*
|
||||
* This function send wmi command to enable / disable NoA.
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS - in case of success
|
||||
*/
|
||||
QDF_STATUS ucfg_p2p_set_noa(struct wlan_objmgr_psoc *soc,
|
||||
uint32_t vdev_id, bool disable_noa);
|
||||
|
||||
#endif /* _WLAN_P2P_UCFG_API_H_ */
|
||||
|
|
|
|||
|
|
@ -35,6 +35,48 @@ ucfg_p2p_psoc_get_tx_ops(struct wlan_objmgr_psoc *psoc)
|
|||
return &(psoc->soc_cb.tx_ops.p2p);
|
||||
}
|
||||
|
||||
/**
|
||||
* is_p2p_ps_allowed() - If P2P power save is allowed or not
|
||||
* @vdev: vdev object
|
||||
* @id: umac component id
|
||||
*
|
||||
* This function returns TRUE if P2P power-save is allowed
|
||||
* else returns FALSE.
|
||||
*
|
||||
* Return: bool
|
||||
*/
|
||||
static bool is_p2p_ps_allowed(struct wlan_objmgr_vdev *vdev,
|
||||
enum wlan_umac_comp_id id)
|
||||
{
|
||||
struct p2p_vdev_priv_obj *p2p_vdev_obj;
|
||||
uint8_t is_p2pgo = 0;
|
||||
|
||||
if (!vdev) {
|
||||
p2p_err("vdev:%p", vdev);
|
||||
return true;
|
||||
}
|
||||
p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev,
|
||||
WLAN_UMAC_COMP_P2P);
|
||||
|
||||
if (wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_GO_MODE)
|
||||
is_p2pgo = 1;
|
||||
|
||||
if (!p2p_vdev_obj || !is_p2pgo) {
|
||||
p2p_err("p2p_vdev_obj:%p is_p2pgo:%u",
|
||||
p2p_vdev_obj, is_p2pgo);
|
||||
return false;
|
||||
}
|
||||
if (p2p_vdev_obj->non_p2p_peer_count &&
|
||||
p2p_vdev_obj->noa_status == false) {
|
||||
p2p_debug("non_p2p_peer_count: %u, noa_status: %d",
|
||||
p2p_vdev_obj->non_p2p_peer_count,
|
||||
p2p_vdev_obj->noa_status);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QDF_STATUS ucfg_p2p_init(void)
|
||||
{
|
||||
return p2p_component_init();
|
||||
|
|
@ -249,6 +291,8 @@ QDF_STATUS ucfg_p2p_set_ps(struct wlan_objmgr_psoc *soc,
|
|||
{
|
||||
struct wlan_lmac_if_p2p_tx_ops *p2p_ops;
|
||||
QDF_STATUS status = QDF_STATUS_E_FAILURE;
|
||||
uint16_t obj_id;
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
|
||||
p2p_debug("soc:%p, vdev_id:%d, opp_ps:%d, ct_window:%d, count:%d, duration:%d, duration:%d, ps_selection:%d",
|
||||
soc, ps_config->vdev_id, ps_config->opp_ps,
|
||||
|
|
@ -261,6 +305,20 @@ QDF_STATUS ucfg_p2p_set_ps(struct wlan_objmgr_psoc *soc,
|
|||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
for (obj_id = 0; obj_id < WLAN_UMAC_PSOC_MAX_VDEVS; obj_id++) {
|
||||
|
||||
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(soc, obj_id,
|
||||
WLAN_P2P_ID);
|
||||
if (vdev) {
|
||||
if (is_p2p_ps_allowed(vdev,
|
||||
WLAN_UMAC_COMP_P2P) == false) {
|
||||
p2p_debug("p2p set ps, NoA is disabled as legacy STA is connected to GO.");
|
||||
return QDF_STATUS_E_BUSY;
|
||||
}
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID);
|
||||
}
|
||||
}
|
||||
|
||||
p2p_ops = ucfg_p2p_psoc_get_tx_ops(soc);
|
||||
if (p2p_ops->set_ps) {
|
||||
status = p2p_ops->set_ps(soc, ps_config);
|
||||
|
|
@ -318,3 +376,18 @@ QDF_STATUS ucfg_p2p_lo_stop(struct wlan_objmgr_psoc *soc,
|
|||
|
||||
return status;
|
||||
}
|
||||
|
||||
QDF_STATUS ucfg_p2p_set_noa(struct wlan_objmgr_psoc *soc,
|
||||
uint32_t vdev_id, bool disable_noa)
|
||||
{
|
||||
struct wlan_lmac_if_p2p_tx_ops *p2p_ops;
|
||||
QDF_STATUS status = QDF_STATUS_E_INVAL;
|
||||
|
||||
p2p_ops = ucfg_p2p_psoc_get_tx_ops(soc);
|
||||
if (p2p_ops->set_noa) {
|
||||
status = p2p_ops->set_noa(soc, vdev_id, disable_noa);
|
||||
p2p_debug("p2p set noa, status:%d", status);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue