diff --git a/dp/inc/cdp_txrx_cmn.h b/dp/inc/cdp_txrx_cmn.h index a681e4c774..9350c5efd5 100644 --- a/dp/inc/cdp_txrx_cmn.h +++ b/dp/inc/cdp_txrx_cmn.h @@ -1876,6 +1876,58 @@ cdp_pdev_set_dp_txrx_handle(ol_txrx_soc_handle soc, uint8_t pdev_id, soc->ops->cmn_drv_ops->set_dp_txrx_handle(soc, pdev_id, dp_hdl); } +/** + * cdp_vdev_get_dp_ext_txrx_handle() - get extended dp handle from vdev + * @soc: opaque soc handle + * @vdev_id: vdev id + * + * Return: opaque dp handle + */ +static inline void * +cdp_vdev_get_dp_ext_txrx_handle(ol_txrx_soc_handle soc, uint8_t vdev_id) +{ + if (!soc || !soc->ops) { + QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, + "%s: Invalid Instance:", __func__); + QDF_BUG(0); + return 0; + } + + if (soc->ops->cmn_drv_ops->get_vdev_dp_ext_txrx_handle) + return soc->ops->cmn_drv_ops->get_vdev_dp_ext_txrx_handle( + soc, vdev_id); + + return 0; +} + +/** + * cdp_vdev_set_dp_ext_txrx_handle() - set extended dp handle in vdev + * @soc: opaque soc handle + * @vdev_id: vdev id + * @size: size of the advance dp handle + * + * Return: QDF_STATUS + */ +static inline QDF_STATUS +cdp_vdev_set_dp_ext_txrx_handle(ol_txrx_soc_handle soc, uint8_t vdev_id, + uint16_t size) +{ + if (!soc || !soc->ops) { + QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, + "%s: Invalid Instance:", __func__); + QDF_BUG(0); + return QDF_STATUS_E_FAILURE; + } + + if (!soc->ops->cmn_drv_ops || + !soc->ops->cmn_drv_ops->set_vdev_dp_ext_txrx_handle) + return QDF_STATUS_E_FAILURE; + + return soc->ops->cmn_drv_ops->set_vdev_dp_ext_txrx_handle(soc, + vdev_id, + size); +} + /* * cdp_soc_get_dp_txrx_handle() - get extended dp handle from soc * @soc: opaque soc handle @@ -2653,4 +2705,67 @@ QDF_STATUS cdp_set_vdev_tidmap_prty(ol_txrx_soc_handle soc, return soc->ops->cmn_drv_ops->set_vdev_tidmap_prty(vdev_handle, prio); } + +/** + * cdp_tx_send_exc() - Transmit a frame on a given vdev in exception path + * + * @soc: opaque soc handle + * @vdev_id: vdev id + * @nbuf: skb + * @tx_exc_metadata: Handle that holds exception path meta data + * + * Return: NULL on success + * nbuf when it fails to send + */ +static inline qdf_nbuf_t +cdp_tx_send_exc(ol_txrx_soc_handle soc, + uint8_t vdev_id, + qdf_nbuf_t nbuf, + struct cdp_tx_exception_metadata *tx_exc_metadata) +{ + if (!soc || !soc->ops) { + QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, + "%s: Invalid Instance", __func__); + QDF_BUG(0); + return 0; + } + + if (!soc->ops->cmn_drv_ops || + !soc->ops->cmn_drv_ops->tx_send_exc) + return 0; + + return soc->ops->cmn_drv_ops->tx_send_exc + (soc, vdev_id, nbuf, tx_exc_metadata); +} + +/** + * cdp_vdev_get_peer_mac_list(): function to get peer mac list of vdev + * @soc: Datapath soc handle + * @vdev_id: vdev id + * @newmac: Table of the clients mac + * @mac_cnt: No. of MACs required + * + * return: no of clients + */ +static inline uint16_t +cdp_vdev_get_peer_mac_list(ol_txrx_soc_handle soc, + uint8_t vdev_id, + uint8_t newmac[][QDF_MAC_ADDR_SIZE], + uint16_t mac_cnt) +{ + if (!soc || !soc->ops) { + QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, + "%s: Invalid Instance", __func__); + QDF_BUG(0); + return 0; + } + + if (!soc->ops->cmn_drv_ops || + !soc->ops->cmn_drv_ops->get_peer_mac_list) + return 0; + + return soc->ops->cmn_drv_ops->get_peer_mac_list + (soc, vdev_id, newmac, mac_cnt); +} + #endif /* _CDP_TXRX_CMN_H_ */ diff --git a/dp/inc/cdp_txrx_handle.h b/dp/inc/cdp_txrx_handle.h index fe4693e95b..a3e448eb3e 100644 --- a/dp/inc/cdp_txrx_handle.h +++ b/dp/inc/cdp_txrx_handle.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. 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 @@ -57,4 +57,9 @@ struct cdp_ctrl_objmgr_peer; * cdp_cal_client - opaque handle for cal client object */ struct cdp_cal_client; + +/** + * cdp_ext_vdev - opaque handle for extended vdev data path handle + */ +struct cdp_ext_vdev; #endif diff --git a/dp/inc/cdp_txrx_host_stats.h b/dp/inc/cdp_txrx_host_stats.h index 43aff83f74..c1474d1602 100644 --- a/dp/inc/cdp_txrx_host_stats.h +++ b/dp/inc/cdp_txrx_host_stats.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. 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 @@ -447,12 +447,12 @@ cdp_update_pdev_host_stats(ol_txrx_soc_handle soc, /** * @brief Update vdev host stats * - * @param soc - soc handle - * @param vdev_id - id of the virtual device object - * @param data - pdev stats - * @param stats_id - type of stats + * @soc: soc handle + * @vdev_id: id of the virtual device object + * @data: pdev stats + * @stats_id: type of stats * - * @return - QDF_STATUS + * Return: QDF_STATUS */ static inline QDF_STATUS cdp_update_vdev_host_stats(ol_txrx_soc_handle soc, diff --git a/dp/inc/cdp_txrx_me.h b/dp/inc/cdp_txrx_me.h index f897febe74..bc65a855ff 100644 --- a/dp/inc/cdp_txrx_me.h +++ b/dp/inc/cdp_txrx_me.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. 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 @@ -121,8 +121,8 @@ cdp_tx_me_free_descriptor(ol_txrx_soc_handle soc, struct cdp_pdev *pdev) soc->ops->me_ops->tx_me_free_descriptor(pdev); } -static inline uint16_t -cdp_tx_me_convert_ucast(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, +static inline uint16_t cdp_tx_me_convert_ucast( + ol_txrx_soc_handle soc, uint8_t vdev_id, qdf_nbuf_t wbuf, u_int8_t newmac[][6], uint8_t newmaccnt) { if (!soc || !soc->ops) { @@ -137,7 +137,7 @@ cdp_tx_me_convert_ucast(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, return 0; return soc->ops->me_ops->tx_me_convert_ucast - (vdev, wbuf, newmac, newmaccnt); + (soc, vdev_id, wbuf, newmac, newmaccnt); } /* Should be a function pointer in ol_txrx_osif_ops{} */ diff --git a/dp/inc/cdp_txrx_ops.h b/dp/inc/cdp_txrx_ops.h index 1090b9323c..8668f2f33b 100644 --- a/dp/inc/cdp_txrx_ops.h +++ b/dp/inc/cdp_txrx_ops.h @@ -268,6 +268,10 @@ struct cdp_cmn_ops { void (*txrx_data_tx_cb_set)(struct cdp_soc_t *soc, uint8_t vdev_id, ol_txrx_data_tx_cb callback, void *ctxt); + qdf_nbuf_t (*tx_send_exc) + (ol_txrx_soc_handle soc, uint8_t vdev_id, qdf_nbuf_t msdu_list, + struct cdp_tx_exception_metadata *tx_exc_metadata); + /******************************************************************* * Statistics and Debugging Interface (C Interface) ********************************************************************/ @@ -442,6 +446,12 @@ struct cdp_cmn_ops { void (*set_dp_txrx_handle)(ol_txrx_soc_handle soc, uint8_t pdev_id, void *dp_hdl); + void *(*get_vdev_dp_ext_txrx_handle)(struct cdp_soc_t *soc, + uint8_t vdev_id); + QDF_STATUS (*set_vdev_dp_ext_txrx_handle)(struct cdp_soc_t *soc, + uint8_t vdev_id, + uint16_t size); + void *(*get_soc_dp_txrx_handle)(struct cdp_soc *soc_handle); void (*set_soc_dp_txrx_handle)(struct cdp_soc *soc_handle, void *dp_txrx_handle); @@ -512,6 +522,10 @@ struct cdp_cmn_ops { QDF_STATUS (*set_vlan_groupkey)(struct cdp_soc_t *soc, uint8_t vdev_id, uint16_t vlan_id, uint16_t group_key); #endif + + uint16_t (*get_peer_mac_list) + (ol_txrx_soc_handle soc, uint8_t vdev_id, + u_int8_t newmac[][QDF_MAC_ADDR_SIZE], uint16_t mac_cnt); }; struct cdp_ctrl_ops { @@ -750,8 +764,8 @@ struct cdp_me_ops { void (*tx_me_free_descriptor)(struct cdp_pdev *pdev); - uint16_t - (*tx_me_convert_ucast)(struct cdp_vdev *vdev, + uint16_t (*tx_me_convert_ucast)( + ol_txrx_soc_handle soc, uint8_t vdev_id, qdf_nbuf_t wbuf, u_int8_t newmac[][6], uint8_t newmaccnt); /* Should be a function pointer in ol_txrx_osif_ops{} */ diff --git a/dp/wifi3.0/dp_internal.h b/dp/wifi3.0/dp_internal.h index 36e9bd0adf..c3f52bb303 100644 --- a/dp/wifi3.0/dp_internal.h +++ b/dp/wifi3.0/dp_internal.h @@ -1836,4 +1836,17 @@ dp_get_pdev_from_soc_pdev_id_wifi3(struct dp_soc *soc, QDF_STATUS dp_rx_tid_update_wifi3(struct dp_peer *peer, int tid, uint32_t ba_window_size, uint32_t start_seq); +/** + * dp_get_peer_mac_list(): function to get peer mac list of vdev + * @soc: Datapath soc handle + * @vdev_id: vdev id + * @newmac: Table of the clients mac + * @mac_cnt: No. of MACs required + * + * return: no of clients + */ +uint16_t dp_get_peer_mac_list(ol_txrx_soc_handle soc, uint8_t vdev_id, + u_int8_t newmac[][QDF_MAC_ADDR_SIZE], + u_int16_t mac_cnt); + #endif /* #ifndef _DP_INTERNAL_H_ */ diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 33111d7659..6666c6a52f 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -5259,6 +5259,11 @@ static QDF_STATUS dp_vdev_detach_wifi3(struct cdp_soc_t *cdp_soc, /* debug print - will be removed later */ dp_warn("not deleting vdev object %pK (%pM) until deletion finishes for all its peers", vdev, vdev->mac_addr.raw); + + if (vdev->vdev_dp_ext_handle) { + qdf_mem_free(vdev->vdev_dp_ext_handle); + vdev->vdev_dp_ext_handle = NULL; + } /* indicate that the vdev needs to be deleted */ vdev->delete.pending = 1; vdev->delete.callback = callback; @@ -5301,7 +5306,13 @@ free_vdev: if (wlan_op_mode_monitor == vdev->opmode) pdev->monitor_vdev = NULL; + if (vdev->vdev_dp_ext_handle) { + qdf_mem_free(vdev->vdev_dp_ext_handle); + vdev->vdev_dp_ext_handle = NULL; + } + dp_info("deleting vdev object %pK (%pM)", vdev, vdev->mac_addr.raw); + qdf_mem_free(vdev); if (callback) @@ -8442,7 +8453,7 @@ dp_txrx_get_pdev_stats(struct cdp_soc_t *soc, uint8_t pdev_id, } /* dp_txrx_update_vdev_me_stats(): Update vdev ME stats sent from CDP - * @vdev_handle: DP vdev handle + * @vdev: DP vdev handle * @buf: buffer containing specific stats structure * * Returns: void @@ -8497,6 +8508,7 @@ static QDF_STATUS dp_txrx_update_vdev_host_stats(struct cdp_soc_t *soc, "Invalid vdev handle"); return QDF_STATUS_E_FAILURE; } + switch (stats_id) { case DP_VDEV_STATS_PKT_CNT_ONLY: break; @@ -9111,6 +9123,54 @@ dp_pdev_set_dp_txrx_handle(struct cdp_soc_t *soc, uint8_t pdev_id, pdev->dp_txrx_handle = dp_txrx_hdl; } +/** + * dp_vdev_get_dp_ext_handle() - get dp handle from vdev + * @soc: datapath soc handle + * @vdev_id: vdev id + * + * Return: opaque pointer to dp txrx handle + */ +static void *dp_vdev_get_dp_ext_handle(ol_txrx_soc_handle soc, uint8_t vdev_id) +{ + struct dp_vdev *vdev = + dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)soc, + vdev_id); + + if (!vdev) + return NULL; + + return vdev->vdev_dp_ext_handle; +} + +/** + * dp_vdev_set_dp_ext_handle() - set dp handle in vdev + * @soc: datapath soc handle + * @vdev_id: vdev id + * @size: size of advance dp handle + * + * Return: QDF_STATUS + */ +static QDF_STATUS +dp_vdev_set_dp_ext_handle(ol_txrx_soc_handle soc, uint8_t vdev_id, + uint16_t size) +{ + struct dp_vdev *vdev = + dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)soc, + vdev_id); + void *dp_ext_handle; + + if (!vdev) + return QDF_STATUS_E_FAILURE; + + dp_ext_handle = qdf_mem_malloc(size); + + if (!dp_ext_handle) + return QDF_STATUS_E_FAILURE; + + vdev->vdev_dp_ext_handle = dp_ext_handle; + return QDF_STATUS_SUCCESS; +} + /** * dp_soc_get_dp_txrx_handle() - get context for external-dp from dp soc * @soc_handle: datapath soc handle @@ -9825,6 +9885,8 @@ static struct cdp_cmn_ops dp_ops_cmn = { .txrx_data_tx_cb_set = dp_txrx_data_tx_cb_set, .get_dp_txrx_handle = dp_pdev_get_dp_txrx_handle, .set_dp_txrx_handle = dp_pdev_set_dp_txrx_handle, + .get_vdev_dp_ext_txrx_handle = dp_vdev_get_dp_ext_handle, + .set_vdev_dp_ext_txrx_handle = dp_vdev_set_dp_ext_handle, .get_soc_dp_txrx_handle = dp_soc_get_dp_txrx_handle, .set_soc_dp_txrx_handle = dp_soc_set_dp_txrx_handle, .map_pdev_to_lmac = dp_soc_map_pdev_to_lmac, @@ -9856,6 +9918,8 @@ static struct cdp_cmn_ops dp_ops_cmn = { #ifdef QCA_MULTIPASS_SUPPORT .set_vlan_groupkey = dp_set_vlan_groupkey, #endif + .get_peer_mac_list = dp_get_peer_mac_list, + .tx_send_exc = __dp_tx_send_exception, }; static struct cdp_ctrl_ops dp_ops_ctrl = { @@ -11369,3 +11433,39 @@ void dp_update_delay_stats(struct dp_pdev *pdev, uint32_t delay, dstats->avg_delay = ((delay + dstats->avg_delay) / 2); } } + +/** + * dp_get_peer_mac_list(): function to get peer mac list of vdev + * @soc: Datapath soc handle + * @vdev_id: vdev id + * @newmac: Table of the clients mac + * @mac_cnt: No. of MACs required + * + * return: no of clients + */ +uint16_t dp_get_peer_mac_list(ol_txrx_soc_handle soc, uint8_t vdev_id, + u_int8_t newmac[][QDF_MAC_ADDR_SIZE], + u_int16_t mac_cnt) +{ + struct dp_vdev *vdev = + dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)soc, + vdev_id); + struct dp_soc *dp_soc = (struct dp_soc *)soc; + struct dp_peer *peer; + uint16_t new_mac_cnt = 0; + + if (!vdev) + return new_mac_cnt; + + qdf_spin_lock_bh(&dp_soc->peer_ref_mutex); + TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) { + if (peer->bss_peer) + continue; + if (new_mac_cnt < mac_cnt) { + WLAN_ADDR_COPY(newmac[new_mac_cnt], peer->mac_addr.raw); + new_mac_cnt++; + } + } + qdf_spin_unlock_bh(&dp_soc->peer_ref_mutex); + return new_mac_cnt; +} diff --git a/dp/wifi3.0/dp_tx.c b/dp/wifi3.0/dp_tx.c index 36f727eca2..7f39fcf98c 100644 --- a/dp/wifi3.0/dp_tx.c +++ b/dp/wifi3.0/dp_tx.c @@ -2049,6 +2049,30 @@ static bool dp_check_exc_metadata(struct cdp_tx_exception_metadata *tx_exc) return true; } +/** + * __dp_tx_send_exception: Wrapper API for dp_tx_send_exception. + * @soc: DP soc handle + * @vdev_id: id of DP vdev handle + * @tx_exc_metadata: Handle that holds exception path meta data + * + * Return: NULL on success, + * nbuf when it fails to send + */ +qdf_nbuf_t +__dp_tx_send_exception(ol_txrx_soc_handle soc, uint8_t vdev_id, qdf_nbuf_t nbuf, + struct cdp_tx_exception_metadata *tx_exc_metadata) +{ + struct dp_vdev *vdev = + dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)soc, + vdev_id); + + if (!vdev) + return nbuf; + + return dp_tx_send_exception((struct cdp_vdev *)vdev, nbuf, + tx_exc_metadata); +} + /** * dp_tx_send_exception() - Transmit a frame on a given VAP in exception path * @vap_dev: DP vdev handle diff --git a/dp/wifi3.0/dp_tx.h b/dp/wifi3.0/dp_tx.h index 1d8141a161..dc4e013992 100644 --- a/dp/wifi3.0/dp_tx.h +++ b/dp/wifi3.0/dp_tx.h @@ -186,6 +186,11 @@ QDF_STATUS dp_tx_pdev_detach(struct dp_pdev *pdev); QDF_STATUS dp_tx_pdev_attach(struct dp_pdev *pdev); qdf_nbuf_t dp_tx_send(struct cdp_soc_t *soc, uint8_t vdev_id, qdf_nbuf_t nbuf); + +qdf_nbuf_t +__dp_tx_send_exception(ol_txrx_soc_handle soc, uint8_t vdev_id, qdf_nbuf_t nbuf, + struct cdp_tx_exception_metadata *tx_exc_metadata); + qdf_nbuf_t dp_tx_send_exception(struct cdp_vdev *data_vdev, qdf_nbuf_t nbuf, struct cdp_tx_exception_metadata *tx_exc); qdf_nbuf_t dp_tx_send_mesh(struct cdp_soc_t *soc, uint8_t vdev_id, diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 01228b04ed..441d484516 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -1955,6 +1955,8 @@ struct dp_vdev { TAILQ_HEAD(, dp_peer) mpass_peer_list; DP_MUTEX_TYPE mpass_peer_mutex; #endif + /* Extended data path handle */ + struct cdp_ext_vdev *vdev_dp_ext_handle; };