qcacmn: Smart Mesh-Add filtering configuration to data path

Add nac(non associated client) configuration to pdev. It will be
used to perform smart mesh filtering on rx packets.

Change-Id: I29989d379e10fcc4a0e4aa19dbb3499650d6bf39
CRs-Fixed: 2017269
This commit is contained in:
Pratik Gandhi
2017-03-09 17:41:40 +05:30
committed by snandini
parent c59be52d47
commit 8b8334baa4
5 changed files with 215 additions and 24 deletions

View File

@@ -150,10 +150,12 @@ cdp_peer_delete(ol_txrx_soc_handle soc, void *peer)
} }
static inline int static inline int
cdp_set_monitor_mode(ol_txrx_soc_handle soc, struct cdp_vdev *vdev) cdp_set_monitor_mode(ol_txrx_soc_handle soc, struct cdp_vdev *vdev,
uint8_t smart_monitor)
{ {
if (soc->ops->cmn_drv_ops->txrx_set_monitor_mode) if (soc->ops->cmn_drv_ops->txrx_set_monitor_mode)
return soc->ops->cmn_drv_ops->txrx_set_monitor_mode(vdev); return soc->ops->cmn_drv_ops->txrx_set_monitor_mode(vdev,
smart_monitor);
return 0; return 0;
} }

View File

@@ -52,6 +52,16 @@ cdp_mempools_attach(ol_txrx_soc_handle soc, void *ctrl_pdev)
return 0; return 0;
} }
/**
* @brief set filter neighbour peers
* @details
* This defines interface function to set neighbour peer filtering.
*
* @param soc - the pointer to soc object
* @param pdev - the pointer physical device object
* @param val - the enable/disable value
* @return - int
*/
static inline int static inline int
cdp_set_filter_neighbour_peers(ol_txrx_soc_handle soc, cdp_set_filter_neighbour_peers(ol_txrx_soc_handle soc,
struct cdp_pdev *pdev, u_int32_t val) struct cdp_pdev *pdev, u_int32_t val)
@@ -61,6 +71,29 @@ cdp_set_filter_neighbour_peers(ol_txrx_soc_handle soc,
(pdev, val); (pdev, val);
return 0; return 0;
} }
/**
* @brief update the neighbour peer addresses
* @details
* This defines interface function to update neighbour peers addresses
* which needs to be filtered
*
* @param soc - the pointer to soc object
* @param pdev - the pointer to physical device object
* @param cmd - add/del entry into peer table
* @param macaddr - the address of neighbour peer
* @return - int
*/
static inline int
cdp_update_filter_neighbour_peers(ol_txrx_soc_handle soc,
struct cdp_pdev *pdev, uint32_t cmd, uint8_t *macaddr)
{
if (soc->ops->ctrl_ops->txrx_update_filter_neighbour_peers)
return soc->ops->ctrl_ops->txrx_update_filter_neighbour_peers
(pdev, cmd, macaddr);
return 0;
}
/** /**
* @brief set the safemode of the device * @brief set the safemode of the device
* @details * @details
@@ -73,7 +106,6 @@ cdp_set_filter_neighbour_peers(ol_txrx_soc_handle soc,
* @param val - the safemode state * @param val - the safemode state
* @return - void * @return - void
*/ */
static inline void static inline void
cdp_set_safemode(ol_txrx_soc_handle soc, cdp_set_safemode(ol_txrx_soc_handle soc,
struct cdp_vdev *vdev, u_int32_t val) struct cdp_vdev *vdev, u_int32_t val)

View File

@@ -75,7 +75,8 @@ struct cdp_cmn_ops {
void (*txrx_peer_delete)(void *peer); void (*txrx_peer_delete)(void *peer);
int (*txrx_set_monitor_mode)(struct cdp_vdev *vdev); int (*txrx_set_monitor_mode)(struct cdp_vdev *vdev,
uint8_t smart_monitor);
void (*txrx_set_curchan)(struct cdp_pdev *pdev, uint32_t chan_mhz); void (*txrx_set_curchan)(struct cdp_pdev *pdev, uint32_t chan_mhz);
@@ -211,7 +212,11 @@ struct cdp_ctrl_ops {
int int
(*txrx_set_filter_neighbour_peers)( (*txrx_set_filter_neighbour_peers)(
struct cdp_pdev *pdev, struct cdp_pdev *pdev,
u_int32_t val); uint32_t val);
int
(*txrx_update_filter_neighbour_peers)(
struct cdp_pdev *pdev,
uint32_t cmd, uint8_t *macaddr);
/** /**
* @brief set the safemode of the device * @brief set the safemode of the device
* @details * @details

View File

@@ -1147,6 +1147,9 @@ static struct cdp_pdev *dp_pdev_attach_wifi3(struct cdp_soc_t *txrx_soc,
TAILQ_INIT(&pdev->vdev_list); TAILQ_INIT(&pdev->vdev_list);
pdev->vdev_count = 0; pdev->vdev_count = 0;
qdf_spinlock_create(&pdev->neighbour_peer_mutex);
TAILQ_INIT(&pdev->neighbour_peers_list);
if (dp_soc_cmn_setup(soc)) { if (dp_soc_cmn_setup(soc)) {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
FL("dp_soc_cmn_setup failed")); FL("dp_soc_cmn_setup failed"));
@@ -1291,6 +1294,29 @@ static void dp_rxdma_ring_cleanup(struct dp_soc *soc,
{ {
} }
#endif #endif
/*
* dp_neighbour_peers_detach() - Detach neighbour peers(nac clients)
* @pdev: device object
*
* Return: void
*/
static void dp_neighbour_peers_detach(struct dp_pdev *pdev)
{
struct dp_neighbour_peer *peer = NULL;
struct dp_neighbour_peer *temp_peer = NULL;
TAILQ_FOREACH_SAFE(peer, &pdev->neighbour_peers_list,
neighbour_peer_list_elem, temp_peer) {
/* delete this peer from the list */
TAILQ_REMOVE(&pdev->neighbour_peers_list,
peer, neighbour_peer_list_elem);
qdf_mem_free(peer);
}
qdf_spinlock_destroy(&pdev->neighbour_peer_mutex);
}
/* /*
* dp_pdev_detach_wifi3() - detach txrx pdev * dp_pdev_detach_wifi3() - detach txrx pdev
* @txrx_pdev: Datapath PDEV handle * @txrx_pdev: Datapath PDEV handle
@@ -1315,6 +1341,8 @@ static void dp_pdev_detach_wifi3(struct cdp_pdev *txrx_pdev, int force)
dp_rx_pdev_mon_detach(pdev); dp_rx_pdev_mon_detach(pdev);
dp_neighbour_peers_detach(pdev);
/* Setup per PDEV REO rings if configured */ /* Setup per PDEV REO rings if configured */
if (wlan_cfg_per_pdev_rx_ring(soc->wlan_cfg_ctx)) { if (wlan_cfg_per_pdev_rx_ring(soc->wlan_cfg_ctx)) {
dp_srng_cleanup(soc, &soc->reo_dest_ring[pdev->pdev_id], dp_srng_cleanup(soc, &soc->reo_dest_ring[pdev->pdev_id],
@@ -1931,6 +1959,91 @@ dp_get_pdev_reo_dest(struct cdp_pdev *pdev_handle)
return cdp_host_reo_dest_ring_unknown; return cdp_host_reo_dest_ring_unknown;
} }
/*
* dp_set_filter_neighbour_peers() - set filter neighbour peers for smart mesh
* @pdev_handle: device object
* @val: value to be set
*
* Return: void
*/
static int dp_set_filter_neighbour_peers(struct cdp_pdev *pdev_handle,
uint32_t val)
{
struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle;
/* Enable/Disable smart mesh filtering. This flag will be checked
* during rx processing to check if packets are from NAC clients.
*/
pdev->filter_neighbour_peers = val;
return 0;
}
/*
* dp_update_filter_neighbour_peers() - set neighbour peers(nac clients)
* address for smart mesh filtering
* @pdev_handle: device object
* @cmd: Add/Del command
* @macaddr: nac client mac address
*
* Return: void
*/
static int dp_update_filter_neighbour_peers(struct cdp_pdev *pdev_handle,
uint32_t cmd, uint8_t *macaddr)
{
struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle;
struct dp_neighbour_peer *peer = NULL;
if (!macaddr)
goto fail0;
/* Store address of NAC (neighbour peer) which will be checked
* against TA of received packets.
*/
if (cmd == DP_NAC_PARAM_ADD) {
peer = (struct dp_neighbour_peer *) qdf_mem_malloc(
sizeof(*peer));
if (!peer) {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
FL("DP neighbour peer node memory allocation failed"));
goto fail0;
}
qdf_mem_copy(&peer->neighbour_peers_macaddr.raw[0],
macaddr, DP_MAC_ADDR_LEN);
qdf_spin_lock_bh(&pdev->neighbour_peer_mutex);
/* add this neighbour peer into the list */
TAILQ_INSERT_TAIL(&pdev->neighbour_peers_list, peer,
neighbour_peer_list_elem);
qdf_spin_unlock_bh(&pdev->neighbour_peer_mutex);
return 1;
} else if (cmd == DP_NAC_PARAM_DEL) {
qdf_spin_lock_bh(&pdev->neighbour_peer_mutex);
TAILQ_FOREACH(peer, &pdev->neighbour_peers_list,
neighbour_peer_list_elem) {
if (!qdf_mem_cmp(&peer->neighbour_peers_macaddr.raw[0],
macaddr, DP_MAC_ADDR_LEN)) {
/* delete this peer from the list */
TAILQ_REMOVE(&pdev->neighbour_peers_list,
peer, neighbour_peer_list_elem);
qdf_mem_free(peer);
break;
}
}
qdf_spin_unlock_bh(&pdev->neighbour_peer_mutex);
return 1;
}
fail0:
return 0;
}
/* /*
* dp_peer_authorize() - authorize txrx peer * dp_peer_authorize() - authorize txrx peer
* @peer_handle: Datapath peer handle * @peer_handle: Datapath peer handle
@@ -2173,10 +2286,12 @@ static struct cdp_cfg *dp_get_ctrl_pdev_from_vdev_wifi3(struct cdp_vdev *pvdev)
/** /**
* dp_vdev_set_monitor_mode() - Set DP VDEV to monitor mode * dp_vdev_set_monitor_mode() - Set DP VDEV to monitor mode
* @vdev_handle: Datapath VDEV handle * @vdev_handle: Datapath VDEV handle
* @smart_monitor: Flag to denote if its smart monitor mode
* *
* Return: 0 on success, not 0 on failure * Return: 0 on success, not 0 on failure
*/ */
static int dp_vdev_set_monitor_mode(struct cdp_vdev *vdev_handle) static int dp_vdev_set_monitor_mode(struct cdp_vdev *vdev_handle,
uint8_t smart_monitor)
{ {
/* Many monitor VAPs can exists in a system but only one can be up at /* Many monitor VAPs can exists in a system but only one can be up at
* anytime * anytime
@@ -2206,6 +2321,10 @@ static int dp_vdev_set_monitor_mode(struct cdp_vdev *vdev_handle)
pdev->monitor_vdev = vdev; pdev->monitor_vdev = vdev;
/* If smart monitor mode, do not configure monitor ring */
if (smart_monitor)
return QDF_STATUS_SUCCESS;
htt_tlv_filter.mpdu_start = 1; htt_tlv_filter.mpdu_start = 1;
htt_tlv_filter.msdu_start = 1; htt_tlv_filter.msdu_start = 1;
htt_tlv_filter.packet = 1; htt_tlv_filter.packet = 1;
@@ -2241,12 +2360,12 @@ static int dp_vdev_set_monitor_mode(struct cdp_vdev *vdev_handle)
htt_tlv_filter.enable_fp = 1; htt_tlv_filter.enable_fp = 1;
htt_tlv_filter.enable_md = 1; htt_tlv_filter.enable_md = 1;
htt_tlv_filter.enable_mo = 1; htt_tlv_filter.enable_mo = 1;
/* /*
* htt_h2t_rx_ring_cfg(soc->htt_handle, pdev_id, * htt_h2t_rx_ring_cfg(soc->htt_handle, pdev_id,
* pdev->rxdma_mon_status_ring.hal_srng, * pdev->rxdma_mon_status_ring.hal_srng,
* RXDMA_MONITOR_STATUS, RX_BUFFER_SIZE, &htt_tlv_filter); * RXDMA_MONITOR_STATUS, RX_BUFFER_SIZE, &htt_tlv_filter);
*/ */
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
} }
@@ -3400,6 +3519,9 @@ static struct cdp_ctrl_ops dp_ops_ctrl = {
.txrx_peer_set_nawds = dp_peer_set_nawds, .txrx_peer_set_nawds = dp_peer_set_nawds,
.txrx_set_pdev_reo_dest = dp_set_pdev_reo_dest, .txrx_set_pdev_reo_dest = dp_set_pdev_reo_dest,
.txrx_get_pdev_reo_dest = dp_get_pdev_reo_dest, .txrx_get_pdev_reo_dest = dp_get_pdev_reo_dest,
.txrx_set_filter_neighbour_peers = dp_set_filter_neighbour_peers,
.txrx_update_filter_neighbour_peers =
dp_update_filter_neighbour_peers,
/* TODO: Add other functions */ /* TODO: Add other functions */
}; };

View File

@@ -678,6 +678,46 @@ struct dp_soc {
struct wlan_objmgr_psoc *psoc; struct wlan_objmgr_psoc *psoc;
}; };
#define MAX_RX_MAC_RINGS 2
/* Same as NAC_MAX_CLENT */
#define DP_NAC_MAX_CLIENT 24
/* same as ieee80211_nac_param */
enum dp_nac_param_cmd {
/* IEEE80211_NAC_PARAM_ADD */
DP_NAC_PARAM_ADD = 1,
/* IEEE80211_NAC_PARAM_DEL */
DP_NAC_PARAM_DEL,
/* IEEE80211_NAC_PARAM_LIST */
DP_NAC_PARAM_LIST,
};
#define DP_MAC_ADDR_LEN 6
union dp_align_mac_addr {
uint8_t raw[DP_MAC_ADDR_LEN];
struct {
uint16_t bytes_ab;
uint16_t bytes_cd;
uint16_t bytes_ef;
} align2;
struct {
uint32_t bytes_abcd;
uint16_t bytes_ef;
} align4;
};
/**
* struct dp_neighbour_peer - neighbour peer list type for smart mesh
* @neighbour_peers_macaddr: neighbour peer's mac address
* @neighbour_peer_list_elem: neighbour peer list TAILQ element
*/
struct dp_neighbour_peer {
/* MAC address of neighbour's peer */
union dp_align_mac_addr neighbour_peers_macaddr;
/* node in the list of neighbour's peer */
TAILQ_ENTRY(dp_neighbour_peer) neighbour_peer_list_elem;
};
/* PDEV level structure for data path */ /* PDEV level structure for data path */
struct dp_pdev { struct dp_pdev {
/* PDEV handle from OSIF layer TBD: see if we really need osif_pdev */ /* PDEV handle from OSIF layer TBD: see if we really need osif_pdev */
@@ -752,6 +792,13 @@ struct dp_pdev {
/*tx_mutex for me*/ /*tx_mutex for me*/
DP_MUTEX_TYPE tx_mutex; DP_MUTEX_TYPE tx_mutex;
/* Smart Mesh */
bool filter_neighbour_peers;
/* smart mesh mutex */
qdf_spinlock_t neighbour_peer_mutex;
/* Neighnour peer list */
TAILQ_HEAD(, dp_neighbour_peer) neighbour_peers_list;
/* Band steering */ /* Band steering */
/* TBD */ /* TBD */
@@ -807,23 +854,6 @@ struct dp_pdev {
struct dp_peer; struct dp_peer;
union dp_align_mac_addr {
uint8_t raw[DP_MAC_ADDR_LEN];
struct {
uint16_t bytes_ab;
uint16_t bytes_cd;
uint16_t bytes_ef;
} align2;
struct {
uint32_t bytes_abcd;
uint16_t bytes_ef;
} align4;
struct {
uint16_t bytes_ab;
uint32_t bytes_cdef;
} align4_2;
};
/* VDEV structure for data path state */ /* VDEV structure for data path state */
struct dp_vdev { struct dp_vdev {
/* OS device abstraction */ /* OS device abstraction */