qcacld-3.0: Derive NDP peer multicast address from peer MAC address
Currently, driver is depending on NS frame to be received to configure
peer multicast address for an NDP session. If there is a delay in NS
frame reception, peer multicast address list will be configured to the
FW without actual peer multicast address. Because of this, FW will drop
the NS frame from NDP peer.
To address this, derive peer multicast address from peer MAC address
and include it in multicast address list that is configured to the FW.
Change-Id: I92a575352d592b4001dc4f061e31eb7f592f8445
CRs-Fixed: 3066990
This commit is contained in:
parent
d2eefd3824
commit
f690e5c12a
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for
|
||||
* any purpose with or without fee is hereby granted, provided that the
|
||||
@ -150,6 +151,8 @@ struct nan_psoc_priv_obj {
|
||||
* @disable_context: Disable all NDP's operation context
|
||||
* @ndp_init_done: Flag to indicate NDP initialization complete after first peer
|
||||
* connection.
|
||||
* @peer_mc_addr_list: Peer multicast address list
|
||||
* @num_peer_mc_addr: Number of entries in peer multicast list
|
||||
*/
|
||||
struct nan_vdev_priv_obj {
|
||||
qdf_spinlock_t lock;
|
||||
@ -162,6 +165,8 @@ struct nan_vdev_priv_obj {
|
||||
struct qdf_mac_addr primary_peer_mac;
|
||||
void *disable_context;
|
||||
bool ndp_init_done;
|
||||
struct qdf_mac_addr *peer_mc_addr_list;
|
||||
uint8_t num_peer_mc_addr;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for
|
||||
* any purpose with or without fee is hereby granted, provided that the
|
||||
@ -92,6 +93,39 @@ QDF_STATUS ucfg_nan_set_active_peers(struct wlan_objmgr_vdev *vdev,
|
||||
*/
|
||||
uint32_t ucfg_nan_get_active_peers(struct wlan_objmgr_vdev *vdev);
|
||||
|
||||
/**
|
||||
* ucfg_nan_set_peer_mc_list: API to derive peer multicast address and add it
|
||||
* to the list
|
||||
* @vdev: pointer to vdev object
|
||||
* @peer_mac_addr: Peer MAC address
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void ucfg_nan_set_peer_mc_list(struct wlan_objmgr_vdev *vdev,
|
||||
struct qdf_mac_addr peer_mac_addr);
|
||||
|
||||
/**
|
||||
* ucfg_nan_get_peer_mc_list: API to get peer multicast address list
|
||||
* @vdev: pointer to vdev object
|
||||
* @peer_mc_addr_list: Out pointer to the peer multicast address list
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void ucfg_nan_get_peer_mc_list(struct wlan_objmgr_vdev *vdev,
|
||||
struct qdf_mac_addr **peer_mc_addr_list);
|
||||
|
||||
/**
|
||||
* ucfg_nan_clear_peer_mc_list: Clear peer multicast address list
|
||||
* @psoc: pointer to psoc object
|
||||
* @vdev: pointer to vdev object
|
||||
* @peer_mac_addr: Pointer to peer MAC address
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void ucfg_nan_clear_peer_mc_list(struct wlan_objmgr_psoc *psoc,
|
||||
struct wlan_objmgr_vdev *vdev,
|
||||
struct qdf_mac_addr *peer_mac_addr);
|
||||
|
||||
/**
|
||||
* ucfg_nan_set_ndp_create_transaction_id: set ndp create transaction id
|
||||
* @vdev: pointer to vdev object
|
||||
@ -624,5 +658,11 @@ static inline bool ucfg_get_disable_6g_nan(struct wlan_objmgr_psoc *psoc)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline void
|
||||
ucfg_nan_get_peer_mc_list(struct wlan_objmgr_vdev *vdev,
|
||||
struct qdf_mac_addr **peer_mc_addr_list)
|
||||
{
|
||||
}
|
||||
#endif /* WLAN_FEATURE_NAN */
|
||||
#endif /* _NAN_UCFG_API_H_ */
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for
|
||||
* any purpose with or without fee is hereby granted, provided that the
|
||||
@ -33,6 +34,7 @@
|
||||
#include "cfg_ucfg_api.h"
|
||||
#include "cfg_nan.h"
|
||||
#include "wlan_mlme_api.h"
|
||||
#include "cfg_nan_api.h"
|
||||
|
||||
struct wlan_objmgr_psoc;
|
||||
struct wlan_objmgr_vdev;
|
||||
@ -183,6 +185,108 @@ inline QDF_STATUS ucfg_nan_set_active_peers(struct wlan_objmgr_vdev *vdev,
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
inline void ucfg_nan_set_peer_mc_list(struct wlan_objmgr_vdev *vdev,
|
||||
struct qdf_mac_addr peer_mac_addr)
|
||||
{
|
||||
struct nan_vdev_priv_obj *priv_obj = nan_get_vdev_priv_obj(vdev);
|
||||
uint32_t max_ndp_sessions = 0;
|
||||
struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev);
|
||||
int i, list_idx = 0;
|
||||
|
||||
if (!priv_obj) {
|
||||
nan_err("priv_obj is null");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!psoc) {
|
||||
nan_err("psoc is null");
|
||||
return;
|
||||
}
|
||||
|
||||
qdf_spin_lock_bh(&priv_obj->lock);
|
||||
if (!priv_obj->peer_mc_addr_list) {
|
||||
cfg_nan_get_ndp_max_sessions(psoc, &max_ndp_sessions);
|
||||
|
||||
priv_obj->peer_mc_addr_list =
|
||||
qdf_mem_malloc(max_ndp_sessions *
|
||||
sizeof(struct qdf_mac_addr));
|
||||
if (!priv_obj->peer_mc_addr_list) {
|
||||
nan_err("Failed to allocate multicast address list");
|
||||
goto end;
|
||||
}
|
||||
priv_obj->num_peer_mc_addr = 0;
|
||||
} else {
|
||||
for (i = 0; i < max_ndp_sessions; i++) {
|
||||
if (qdf_is_macaddr_zero(
|
||||
&priv_obj->peer_mc_addr_list[i])) {
|
||||
list_idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (list_idx == max_ndp_sessions) {
|
||||
nan_err("Peer multicast address list is full");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
/* Derive peer multicast addr */
|
||||
peer_mac_addr.bytes[0] = 0x33;
|
||||
peer_mac_addr.bytes[1] = 0x33;
|
||||
peer_mac_addr.bytes[2] = 0xff;
|
||||
priv_obj->peer_mc_addr_list[list_idx] = peer_mac_addr;
|
||||
priv_obj->num_peer_mc_addr++;
|
||||
|
||||
end:
|
||||
qdf_spin_unlock_bh(&priv_obj->lock);
|
||||
}
|
||||
|
||||
inline void ucfg_nan_get_peer_mc_list(
|
||||
struct wlan_objmgr_vdev *vdev,
|
||||
struct qdf_mac_addr **peer_mc_addr_list)
|
||||
{
|
||||
struct nan_vdev_priv_obj *priv_obj = nan_get_vdev_priv_obj(vdev);
|
||||
|
||||
if (!priv_obj) {
|
||||
nan_err("priv_obj is null");
|
||||
return;
|
||||
}
|
||||
|
||||
*peer_mc_addr_list = priv_obj->peer_mc_addr_list;
|
||||
}
|
||||
|
||||
inline void ucfg_nan_clear_peer_mc_list(struct wlan_objmgr_psoc *psoc,
|
||||
struct wlan_objmgr_vdev *vdev,
|
||||
struct qdf_mac_addr *peer_mac_addr)
|
||||
{
|
||||
struct nan_vdev_priv_obj *priv_obj = nan_get_vdev_priv_obj(vdev);
|
||||
int i;
|
||||
uint32_t max_ndp_sessions = 0;
|
||||
|
||||
if (!priv_obj) {
|
||||
nan_err("priv_obj is null");
|
||||
return;
|
||||
}
|
||||
|
||||
qdf_spin_lock_bh(&priv_obj->lock);
|
||||
if (priv_obj->peer_mc_addr_list) {
|
||||
cfg_nan_get_ndp_max_sessions(psoc, &max_ndp_sessions);
|
||||
for (i = 0; i < max_ndp_sessions; i++) {
|
||||
if (qdf_is_macaddr_equal(
|
||||
&priv_obj->peer_mc_addr_list[i],
|
||||
peer_mac_addr)) {
|
||||
qdf_zero_macaddr(
|
||||
&priv_obj->peer_mc_addr_list[i]);
|
||||
priv_obj->num_peer_mc_addr--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (priv_obj->num_peer_mc_addr == 0) {
|
||||
qdf_mem_free(priv_obj->peer_mc_addr_list);
|
||||
priv_obj->peer_mc_addr_list = NULL;
|
||||
}
|
||||
}
|
||||
qdf_spin_unlock_bh(&priv_obj->lock);
|
||||
}
|
||||
|
||||
inline uint32_t ucfg_nan_get_active_peers(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
uint32_t val;
|
||||
|
@ -4892,6 +4892,54 @@ void wlan_hdd_release_intf_addr(struct hdd_context *hdd_ctx,
|
||||
QDF_MAC_ADDR_REF(releaseAddr));
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_set_derived_multicast_list(): Add derived peer multicast address list in
|
||||
* multicast list request to the FW
|
||||
* @psoc: Pointer to psoc
|
||||
* @adapter: Pointer to hdd adapter
|
||||
* @mc_list_request: Multicast list request to the FW
|
||||
* @mc_count: number of multicast addresses received from the kernel
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static void
|
||||
hdd_set_derived_multicast_list(struct wlan_objmgr_psoc *psoc,
|
||||
struct hdd_adapter *adapter,
|
||||
struct pmo_mc_addr_list_params *mc_list_request,
|
||||
int *mc_count)
|
||||
{
|
||||
int i = 0, j = 0, list_count = *mc_count;
|
||||
struct qdf_mac_addr *peer_mc_addr_list = NULL;
|
||||
uint8_t driver_mc_cnt = 0;
|
||||
uint32_t max_ndp_sessions = 0;
|
||||
|
||||
cfg_nan_get_ndp_max_sessions(psoc, &max_ndp_sessions);
|
||||
|
||||
ucfg_nan_get_peer_mc_list(adapter->vdev, &peer_mc_addr_list);
|
||||
|
||||
for (j = 0; j < max_ndp_sessions; j++) {
|
||||
for (i = 0; i < list_count; i++) {
|
||||
if (qdf_is_macaddr_zero(&peer_mc_addr_list[j]) ||
|
||||
qdf_is_macaddr_equal(&mc_list_request->mc_addr[i],
|
||||
&peer_mc_addr_list[j]))
|
||||
break;
|
||||
}
|
||||
if (i == list_count) {
|
||||
qdf_mem_copy(
|
||||
&(mc_list_request->mc_addr[list_count +
|
||||
driver_mc_cnt].bytes),
|
||||
peer_mc_addr_list[j].bytes, ETH_ALEN);
|
||||
hdd_debug("mlist[%d] = " QDF_MAC_ADDR_FMT,
|
||||
list_count + driver_mc_cnt,
|
||||
QDF_MAC_ADDR_REF(
|
||||
mc_list_request->mc_addr[list_count +
|
||||
driver_mc_cnt].bytes));
|
||||
driver_mc_cnt++;
|
||||
}
|
||||
}
|
||||
*mc_count += driver_mc_cnt;
|
||||
}
|
||||
|
||||
/**
|
||||
* __hdd_set_multicast_list() - set the multicast address list
|
||||
* @dev: Pointer to the WLAN device.
|
||||
@ -4967,6 +5015,11 @@ static void __hdd_set_multicast_list(struct net_device *dev)
|
||||
QDF_MAC_ADDR_REF(mc_list_request->mc_addr[i].bytes));
|
||||
i++;
|
||||
}
|
||||
|
||||
if (adapter->device_mode == QDF_NDI_MODE)
|
||||
hdd_set_derived_multicast_list(psoc, adapter,
|
||||
mc_list_request,
|
||||
&mc_count);
|
||||
}
|
||||
|
||||
adapter->mc_addr_list.mc_cnt = mc_count;
|
||||
|
@ -1047,6 +1047,8 @@ void hdd_ndp_peer_departed_handler(uint8_t vdev_id, uint16_t sta_id,
|
||||
|
||||
if (last_peer) {
|
||||
hdd_debug("No more ndp peers.");
|
||||
ucfg_nan_clear_peer_mc_list(hdd_ctx->psoc, adapter->vdev,
|
||||
peer_mac_addr);
|
||||
hdd_cleanup_ndi(hdd_ctx, adapter);
|
||||
qdf_event_set(&adapter->peer_cleanup_done);
|
||||
/*
|
||||
|
@ -74,6 +74,8 @@ static QDF_STATUS lim_add_ndi_peer(struct mac_context *mac_ctx,
|
||||
pe_info("Need to create NDI Peer :" QDF_MAC_ADDR_FMT,
|
||||
QDF_MAC_ADDR_REF(peer_mac_addr.bytes));
|
||||
|
||||
ucfg_nan_set_peer_mc_list(session->vdev, peer_mac_addr);
|
||||
|
||||
peer_idx = lim_assign_peer_idx(mac_ctx, session);
|
||||
if (!peer_idx) {
|
||||
pe_err("Invalid peer_idx: %d", peer_idx);
|
||||
|
Loading…
Reference in New Issue
Block a user