qcacmn: increment vdev refcount for search by id
Add new API dp_vdev_get_ref_by_id() which will return vdev pointer by holding a reference. Caller of this API has to ensure that this reference is released by calling dp_vdev_unref_delete() API New lock soc->vdev_map_lock is introduced to protect vdev id to object array Change-Id: I883e328932e35ef31254125492dbae20cebe0e00
This commit is contained in:

committed by
snandini

parent
afac78b33d
commit
a718007f03
@@ -2414,13 +2414,12 @@ static void dp_process_ppdu_stats_user_common_tlv(
|
||||
|
||||
/* returning earlier causes other feilds unpopulated */
|
||||
if (peer_id == DP_SCAN_PEER_ID) {
|
||||
vdev =
|
||||
dp_get_vdev_from_soc_vdev_id_wifi3(pdev->soc,
|
||||
ppdu_desc->vdev_id);
|
||||
vdev = dp_vdev_get_ref_by_id(pdev->soc, ppdu_desc->vdev_id);
|
||||
if (!vdev)
|
||||
return;
|
||||
qdf_mem_copy(ppdu_user_desc->mac_addr, vdev->mac_addr.raw,
|
||||
QDF_MAC_ADDR_SIZE);
|
||||
dp_vdev_unref_delete(pdev->soc, vdev);
|
||||
} else {
|
||||
peer = dp_peer_get_ref_by_id(pdev->soc, peer_id,
|
||||
DP_MOD_ID_TX_PPDU_STATS);
|
||||
@@ -2432,13 +2431,13 @@ static void dp_process_ppdu_stats_user_common_tlv(
|
||||
* with peer id equal to previously associated
|
||||
* peer's peer_id but it was removed
|
||||
*/
|
||||
vdev =
|
||||
dp_get_vdev_from_soc_vdev_id_wifi3(pdev->soc,
|
||||
vdev = dp_vdev_get_ref_by_id(pdev->soc,
|
||||
ppdu_desc->vdev_id);
|
||||
if (!vdev)
|
||||
return;
|
||||
qdf_mem_copy(ppdu_user_desc->mac_addr,
|
||||
vdev->mac_addr.raw, QDF_MAC_ADDR_SIZE);
|
||||
dp_vdev_unref_delete(pdev->soc, vdev);
|
||||
return;
|
||||
}
|
||||
qdf_mem_copy(ppdu_user_desc->mac_addr,
|
||||
@@ -2478,11 +2477,10 @@ static void dp_process_ppdu_stats_user_rate_tlv(struct dp_pdev *pdev,
|
||||
ppdu_user_desc = &ppdu_desc->user[curr_user_index];
|
||||
ppdu_user_desc->tlv_bitmap |= (1 << tlv_type);
|
||||
if (peer_id == DP_SCAN_PEER_ID) {
|
||||
vdev =
|
||||
dp_get_vdev_from_soc_vdev_id_wifi3(pdev->soc,
|
||||
ppdu_desc->vdev_id);
|
||||
vdev = dp_vdev_get_ref_by_id(pdev->soc, ppdu_desc->vdev_id);
|
||||
if (!vdev)
|
||||
return;
|
||||
dp_vdev_unref_delete(pdev->soc, vdev);
|
||||
}
|
||||
ppdu_user_desc->peer_id = peer_id;
|
||||
|
||||
|
@@ -2128,20 +2128,47 @@ void dp_rx_fst_detach(struct dp_soc *soc, struct dp_pdev *pdev)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* dp_get_vdev_from_soc_vdev_id_wifi3() - Returns vdev object given the vdev id
|
||||
* dp_vdev_get_ref() - API to take a reference for VDEV object
|
||||
*
|
||||
* @soc : core DP soc context
|
||||
* @vdev : DP vdev
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS if reference held successfully
|
||||
* else QDF_STATUS_E_INVAL
|
||||
*/
|
||||
static inline
|
||||
QDF_STATUS dp_vdev_get_ref(struct dp_soc *soc, struct dp_vdev *vdev)
|
||||
{
|
||||
if (!qdf_atomic_inc_not_zero(&vdev->ref_cnt))
|
||||
return QDF_STATUS_E_INVAL;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_vdev_get_ref_by_id() - Returns vdev object given the vdev id
|
||||
* @soc: core DP soc context
|
||||
* @vdev_id: vdev id from vdev object can be retrieved
|
||||
*
|
||||
* Return: struct dp_vdev*: Pointer to DP vdev object
|
||||
*/
|
||||
static inline struct dp_vdev *
|
||||
dp_get_vdev_from_soc_vdev_id_wifi3(struct dp_soc *soc,
|
||||
uint8_t vdev_id)
|
||||
dp_vdev_get_ref_by_id(struct dp_soc *soc, uint8_t vdev_id)
|
||||
{
|
||||
struct dp_vdev *vdev = NULL;
|
||||
if (qdf_unlikely(vdev_id >= MAX_VDEV_CNT))
|
||||
return NULL;
|
||||
|
||||
return soc->vdev_id_map[vdev_id];
|
||||
qdf_spin_lock_bh(&soc->vdev_map_lock);
|
||||
vdev = soc->vdev_id_map[vdev_id];
|
||||
|
||||
if (!vdev || dp_vdev_get_ref(soc, vdev) != QDF_STATUS_SUCCESS) {
|
||||
qdf_spin_unlock_bh(&soc->vdev_map_lock);
|
||||
return NULL;
|
||||
}
|
||||
qdf_spin_unlock_bh(&soc->vdev_map_lock);
|
||||
|
||||
return vdev;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2278,22 +2305,4 @@ dp_hmwds_ast_add_notify(struct dp_peer *peer,
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* dp_vdev_get_ref() - API to take a reference for VDEV object
|
||||
*
|
||||
* @soc : core DP soc context
|
||||
* @vdev : DP vdev
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS if reference held successfully
|
||||
* else QDF_STATUS_E_INVAL
|
||||
*/
|
||||
static inline
|
||||
QDF_STATUS dp_vdev_get_ref(struct dp_soc *soc, struct dp_vdev *vdev)
|
||||
{
|
||||
if (!qdf_atomic_inc_not_zero(&vdev->ref_cnt))
|
||||
return QDF_STATUS_E_INVAL;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
#endif /* #ifndef _DP_INTERNAL_H_ */
|
||||
|
@@ -1786,14 +1786,14 @@ bool dp_ipa_rx_intrabss_fwd(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
|
||||
qdf_nbuf_t nbuf, bool *fwd_success)
|
||||
{
|
||||
struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
|
||||
struct dp_vdev *vdev =
|
||||
dp_get_vdev_from_soc_vdev_id_wifi3(soc, vdev_id);
|
||||
struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id);
|
||||
struct dp_pdev *pdev;
|
||||
struct dp_peer *da_peer;
|
||||
struct dp_peer *sa_peer;
|
||||
qdf_nbuf_t nbuf_copy;
|
||||
uint8_t da_is_bcmc;
|
||||
struct ethhdr *eh;
|
||||
bool status = false;
|
||||
|
||||
*fwd_success = false; /* set default as failure */
|
||||
|
||||
@@ -1809,16 +1809,16 @@ bool dp_ipa_rx_intrabss_fwd(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
|
||||
|
||||
pdev = vdev->pdev;
|
||||
if (qdf_unlikely(!pdev))
|
||||
return false;
|
||||
goto out;
|
||||
|
||||
/* no fwd for station mode and just pass up to stack */
|
||||
if (vdev->opmode == wlan_op_mode_sta)
|
||||
return false;
|
||||
goto out;
|
||||
|
||||
if (da_is_bcmc) {
|
||||
nbuf_copy = qdf_nbuf_copy(nbuf);
|
||||
if (!nbuf_copy)
|
||||
return false;
|
||||
goto out;
|
||||
|
||||
if (dp_ipa_intrabss_send(pdev, vdev, nbuf_copy))
|
||||
qdf_nbuf_free(nbuf_copy);
|
||||
@@ -1826,25 +1826,25 @@ bool dp_ipa_rx_intrabss_fwd(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
|
||||
*fwd_success = true;
|
||||
|
||||
/* return false to pass original pkt up to stack */
|
||||
return false;
|
||||
goto out;
|
||||
}
|
||||
|
||||
eh = (struct ethhdr *)qdf_nbuf_data(nbuf);
|
||||
|
||||
if (!qdf_mem_cmp(eh->h_dest, vdev->mac_addr.raw, QDF_MAC_ADDR_SIZE))
|
||||
return false;
|
||||
goto out;
|
||||
|
||||
da_peer = dp_peer_find_hash_find(soc, eh->h_dest, 0, vdev->vdev_id,
|
||||
DP_MOD_ID_IPA);
|
||||
if (!da_peer)
|
||||
return false;
|
||||
goto out;
|
||||
|
||||
dp_peer_unref_delete(da_peer, DP_MOD_ID_IPA);
|
||||
|
||||
sa_peer = dp_peer_find_hash_find(soc, eh->h_source, 0, vdev->vdev_id,
|
||||
DP_MOD_ID_IPA);
|
||||
if (!sa_peer)
|
||||
return false;
|
||||
goto out;
|
||||
|
||||
dp_peer_unref_delete(sa_peer, DP_MOD_ID_IPA);
|
||||
|
||||
@@ -1860,7 +1860,10 @@ bool dp_ipa_rx_intrabss_fwd(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
|
||||
else
|
||||
*fwd_success = true;
|
||||
|
||||
return true;
|
||||
status = true;
|
||||
out:
|
||||
dp_vdev_unref_delete(soc, vdev);
|
||||
return status;
|
||||
}
|
||||
|
||||
#ifdef MDM_PLATFORM
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -266,7 +266,7 @@ void dp_peer_find_hash_add(struct dp_soc *soc, struct dp_peer *peer)
|
||||
}
|
||||
|
||||
/*
|
||||
* dp_peer_vdev_list_add() - add peer into vdev list
|
||||
* dp_peer_vdev_list_add() - add peer into vdev's peer list
|
||||
* @soc: soc handle
|
||||
* @vdev: vdev handle
|
||||
* @peer: peer handle
|
||||
@@ -297,7 +297,7 @@ void dp_peer_vdev_list_add(struct dp_soc *soc, struct dp_vdev *vdev,
|
||||
}
|
||||
|
||||
/*
|
||||
* dp_peer_vdev_list_remove() - remove peer from vdev list
|
||||
* dp_peer_vdev_list_remove() - remove peer from vdev's peer list
|
||||
* @soc: SoC handle
|
||||
* @vdev: VDEV handle
|
||||
* @peer: peer handle
|
||||
@@ -3500,15 +3500,7 @@ dp_set_pn_check_wifi3(struct cdp_soc_t *soc, uint8_t vdev_id,
|
||||
uint8_t pn_size;
|
||||
struct hal_reo_cmd_params params;
|
||||
struct dp_peer *peer = NULL;
|
||||
struct dp_vdev *vdev =
|
||||
dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)soc,
|
||||
vdev_id);
|
||||
|
||||
if (!vdev) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: VDEV is NULL!\n", __func__);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
struct dp_vdev *vdev = NULL;
|
||||
|
||||
peer = dp_peer_find_hash_find((struct dp_soc *)soc,
|
||||
peer_mac, 0, vdev_id,
|
||||
@@ -3520,6 +3512,15 @@ dp_set_pn_check_wifi3(struct cdp_soc_t *soc, uint8_t vdev_id,
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
vdev = peer->vdev;
|
||||
|
||||
if (!vdev) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: VDEV is NULL!\n", __func__);
|
||||
dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
pdev = vdev->pdev;
|
||||
qdf_mem_zero(¶ms, sizeof(params));
|
||||
|
||||
|
@@ -483,62 +483,6 @@ dp_rx_deliver_raw(struct dp_vdev *vdev, qdf_nbuf_t nbuf_list,
|
||||
vdev->osif_rx(vdev->osif_vdev, deliver_list_head);
|
||||
}
|
||||
|
||||
|
||||
#ifdef DP_LFR
|
||||
/*
|
||||
* In case of LFR, data of a new peer might be sent up
|
||||
* even before peer is added.
|
||||
*/
|
||||
static inline struct dp_vdev *
|
||||
dp_get_vdev_from_peer(struct dp_soc *soc,
|
||||
uint16_t peer_id,
|
||||
struct dp_peer *peer,
|
||||
struct hal_rx_mpdu_desc_info mpdu_desc_info)
|
||||
{
|
||||
struct dp_vdev *vdev;
|
||||
uint8_t vdev_id;
|
||||
|
||||
if (unlikely(!peer)) {
|
||||
if (peer_id != HTT_INVALID_PEER) {
|
||||
vdev_id = DP_PEER_METADATA_VDEV_ID_GET(
|
||||
mpdu_desc_info.peer_meta_data);
|
||||
QDF_TRACE(QDF_MODULE_ID_DP,
|
||||
QDF_TRACE_LEVEL_DEBUG,
|
||||
FL("PeerID %d not found use vdevID %d"),
|
||||
peer_id, vdev_id);
|
||||
vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc,
|
||||
vdev_id);
|
||||
} else {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP,
|
||||
QDF_TRACE_LEVEL_DEBUG,
|
||||
FL("Invalid PeerID %d"),
|
||||
peer_id);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
vdev = peer->vdev;
|
||||
}
|
||||
return vdev;
|
||||
}
|
||||
#else
|
||||
static inline struct dp_vdev *
|
||||
dp_get_vdev_from_peer(struct dp_soc *soc,
|
||||
uint16_t peer_id,
|
||||
struct dp_peer *peer,
|
||||
struct hal_rx_mpdu_desc_info mpdu_desc_info)
|
||||
{
|
||||
if (unlikely(!peer)) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP,
|
||||
QDF_TRACE_LEVEL_DEBUG,
|
||||
FL("Peer not found for peerID %d"),
|
||||
peer_id);
|
||||
return NULL;
|
||||
} else {
|
||||
return peer->vdev;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef FEATURE_WDS
|
||||
static void
|
||||
dp_rx_da_learn(struct dp_soc *soc,
|
||||
@@ -1919,7 +1863,7 @@ void dp_rx_deliver_to_stack_no_peer(struct dp_soc *soc, qdf_nbuf_t nbuf)
|
||||
{
|
||||
uint16_t peer_id;
|
||||
uint8_t vdev_id;
|
||||
struct dp_vdev *vdev;
|
||||
struct dp_vdev *vdev = NULL;
|
||||
uint32_t l2_hdr_offset = 0;
|
||||
uint16_t msdu_len = 0;
|
||||
uint32_t pkt_len = 0;
|
||||
@@ -1932,7 +1876,7 @@ void dp_rx_deliver_to_stack_no_peer(struct dp_soc *soc, qdf_nbuf_t nbuf)
|
||||
goto deliver_fail;
|
||||
|
||||
vdev_id = QDF_NBUF_CB_RX_VDEV_ID(nbuf);
|
||||
vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc, vdev_id);
|
||||
vdev = dp_vdev_get_ref_by_id(soc, vdev_id);
|
||||
if (!vdev || vdev->delete.pending || !vdev->osif_rx)
|
||||
goto deliver_fail;
|
||||
|
||||
@@ -1958,6 +1902,7 @@ void dp_rx_deliver_to_stack_no_peer(struct dp_soc *soc, qdf_nbuf_t nbuf)
|
||||
vdev->osif_rx(vdev->osif_vdev, nbuf))
|
||||
goto deliver_fail;
|
||||
DP_STATS_INC(soc, rx.err.pkt_delivered_no_peer, 1);
|
||||
dp_vdev_unref_delete(soc, vdev);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1965,6 +1910,8 @@ deliver_fail:
|
||||
DP_STATS_INC_PKT(soc, rx.err.rx_invalid_peer, 1,
|
||||
QDF_NBUF_CB_RX_PKT_LEN(nbuf));
|
||||
qdf_nbuf_free(nbuf);
|
||||
if (vdev)
|
||||
dp_vdev_unref_delete(soc, vdev);
|
||||
}
|
||||
#else
|
||||
static inline
|
||||
|
@@ -4338,20 +4338,24 @@ dp_vdev_peer_stats_update_protocol_cnt_free_peer:
|
||||
dp_peer_unref_delete(peer, DP_MOD_ID_GENERIC_STATS);
|
||||
}
|
||||
|
||||
void dp_peer_stats_update_protocol_cnt(struct cdp_soc_t *soc,
|
||||
void dp_peer_stats_update_protocol_cnt(struct cdp_soc_t *soc_hdl,
|
||||
int8_t vdev_id,
|
||||
qdf_nbuf_t nbuf,
|
||||
bool is_egress,
|
||||
bool is_rx)
|
||||
{
|
||||
struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
|
||||
struct dp_vdev *vdev;
|
||||
|
||||
vdev = dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)soc,
|
||||
vdev_id);
|
||||
if (qdf_likely(!vdev->peer_protocol_count_track))
|
||||
vdev = dp_vdev_get_ref_by_id(soc, vdev_id);
|
||||
if (!vdev)
|
||||
return;
|
||||
dp_vdev_peer_stats_update_protocol_cnt(vdev, nbuf, NULL, is_egress,
|
||||
is_rx);
|
||||
|
||||
if (qdf_likely(vdev->peer_protocol_count_track))
|
||||
dp_vdev_peer_stats_update_protocol_cnt(vdev, nbuf, NULL,
|
||||
is_egress, is_rx);
|
||||
|
||||
dp_vdev_unref_delete(soc, vdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@@ -2172,14 +2172,14 @@ static bool dp_check_exc_metadata(struct cdp_tx_exception_metadata *tx_exc)
|
||||
* nbuf when it fails to send
|
||||
*/
|
||||
qdf_nbuf_t
|
||||
dp_tx_send_exception(struct cdp_soc_t *soc, uint8_t vdev_id, qdf_nbuf_t nbuf,
|
||||
dp_tx_send_exception(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
|
||||
qdf_nbuf_t nbuf,
|
||||
struct cdp_tx_exception_metadata *tx_exc_metadata)
|
||||
{
|
||||
struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
|
||||
qdf_ether_header_t *eh = NULL;
|
||||
struct dp_tx_msdu_info_s msdu_info;
|
||||
struct dp_vdev *vdev =
|
||||
dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)soc,
|
||||
vdev_id);
|
||||
struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id);
|
||||
|
||||
if (qdf_unlikely(!vdev))
|
||||
goto fail;
|
||||
@@ -2270,9 +2270,12 @@ dp_tx_send_exception(struct cdp_soc_t *soc, uint8_t vdev_id, qdf_nbuf_t nbuf,
|
||||
nbuf = dp_tx_send_msdu_single(vdev, nbuf, &msdu_info,
|
||||
tx_exc_metadata->peer_id, tx_exc_metadata);
|
||||
|
||||
dp_vdev_unref_delete(soc, vdev);
|
||||
return nbuf;
|
||||
|
||||
fail:
|
||||
if (vdev)
|
||||
dp_vdev_unref_delete(soc, vdev);
|
||||
dp_verbose_debug("pkt send failed");
|
||||
return nbuf;
|
||||
}
|
||||
@@ -2290,9 +2293,10 @@ fail:
|
||||
* nbuf when it fails to send
|
||||
*/
|
||||
#ifdef MESH_MODE_SUPPORT
|
||||
qdf_nbuf_t dp_tx_send_mesh(struct cdp_soc_t *soc, uint8_t vdev_id,
|
||||
qdf_nbuf_t dp_tx_send_mesh(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
|
||||
qdf_nbuf_t nbuf)
|
||||
{
|
||||
struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
|
||||
struct meta_hdr_s *mhdr;
|
||||
qdf_nbuf_t nbuf_mesh = NULL;
|
||||
qdf_nbuf_t nbuf_clone = NULL;
|
||||
@@ -2306,8 +2310,7 @@ qdf_nbuf_t dp_tx_send_mesh(struct cdp_soc_t *soc, uint8_t vdev_id,
|
||||
return nbuf;
|
||||
}
|
||||
|
||||
vdev = dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)soc,
|
||||
vdev_id);
|
||||
vdev = dp_vdev_get_ref_by_id(soc, vdev_id);
|
||||
if (!vdev) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"vdev is NULL for vdev_id %d", vdev_id);
|
||||
@@ -2331,13 +2334,14 @@ qdf_nbuf_t dp_tx_send_mesh(struct cdp_soc_t *soc, uint8_t vdev_id,
|
||||
if (!nbuf_clone) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"qdf_nbuf_clone failed");
|
||||
dp_vdev_unref_delete(soc, vdev);
|
||||
return nbuf;
|
||||
}
|
||||
qdf_nbuf_set_tx_ftype(nbuf_clone, CB_FTYPE_MESH_TX_INFO);
|
||||
}
|
||||
|
||||
if (nbuf_clone) {
|
||||
if (!dp_tx_send(soc, vdev_id, nbuf_clone)) {
|
||||
if (!dp_tx_send(soc_hdl, vdev_id, nbuf_clone)) {
|
||||
DP_STATS_INC(vdev, tx_i.mesh.exception_fw, 1);
|
||||
} else {
|
||||
qdf_nbuf_free(nbuf_clone);
|
||||
@@ -2349,11 +2353,12 @@ qdf_nbuf_t dp_tx_send_mesh(struct cdp_soc_t *soc, uint8_t vdev_id,
|
||||
else
|
||||
qdf_nbuf_set_tx_ftype(nbuf, CB_FTYPE_INVALID);
|
||||
|
||||
nbuf = dp_tx_send(soc, vdev_id, nbuf);
|
||||
nbuf = dp_tx_send(soc_hdl, vdev_id, nbuf);
|
||||
if ((!nbuf) && no_enc_frame) {
|
||||
DP_STATS_INC(vdev, tx_i.mesh.exception_fw, 1);
|
||||
}
|
||||
|
||||
dp_vdev_unref_delete(soc, vdev);
|
||||
return nbuf;
|
||||
}
|
||||
|
||||
@@ -2382,28 +2387,27 @@ qdf_nbuf_t dp_tx_send_mesh(struct cdp_soc_t *soc, uint8_t vdev_id,
|
||||
*/
|
||||
|
||||
static inline
|
||||
void dp_tx_nawds_handler(struct cdp_soc_t *soc, struct dp_vdev *vdev,
|
||||
void dp_tx_nawds_handler(struct dp_soc *soc, struct dp_vdev *vdev,
|
||||
struct dp_tx_msdu_info_s *msdu_info, qdf_nbuf_t nbuf)
|
||||
{
|
||||
struct dp_peer *peer = NULL;
|
||||
qdf_nbuf_t nbuf_clone = NULL;
|
||||
struct dp_soc *dp_soc = (struct dp_soc *)soc;
|
||||
uint16_t peer_id = DP_INVALID_PEER;
|
||||
uint16_t sa_peer_id = DP_INVALID_PEER;
|
||||
struct dp_ast_entry *ast_entry = NULL;
|
||||
qdf_ether_header_t *eh = (qdf_ether_header_t *)qdf_nbuf_data(nbuf);
|
||||
|
||||
if (qdf_nbuf_get_tx_ftype(nbuf) == CB_FTYPE_INTRABSS_FWD) {
|
||||
qdf_spin_lock_bh(&dp_soc->ast_lock);
|
||||
qdf_spin_lock_bh(&soc->ast_lock);
|
||||
|
||||
ast_entry = dp_peer_ast_hash_find_by_pdevid
|
||||
(dp_soc,
|
||||
(soc,
|
||||
(uint8_t *)(eh->ether_shost),
|
||||
vdev->pdev->pdev_id);
|
||||
|
||||
if (ast_entry)
|
||||
sa_peer_id = ast_entry->peer_id;
|
||||
qdf_spin_unlock_bh(&dp_soc->ast_lock);
|
||||
qdf_spin_unlock_bh(&soc->ast_lock);
|
||||
}
|
||||
|
||||
qdf_spin_lock_bh(&vdev->peer_list_lock);
|
||||
@@ -2462,17 +2466,29 @@ void dp_tx_nawds_handler(struct cdp_soc_t *soc, struct dp_vdev *vdev,
|
||||
* Return: NULL on success,
|
||||
* nbuf when it fails to send
|
||||
*/
|
||||
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(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
|
||||
qdf_nbuf_t nbuf)
|
||||
{
|
||||
struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
|
||||
uint16_t peer_id = HTT_INVALID_PEER;
|
||||
/*
|
||||
* doing a memzero is causing additional function call overhead
|
||||
* so doing static stack clearing
|
||||
*/
|
||||
struct dp_tx_msdu_info_s msdu_info = {0};
|
||||
struct dp_vdev *vdev =
|
||||
dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)soc,
|
||||
vdev_id);
|
||||
struct dp_vdev *vdev = NULL;
|
||||
|
||||
if (qdf_unlikely(vdev_id >= MAX_VDEV_CNT))
|
||||
return nbuf;
|
||||
|
||||
/*
|
||||
* dp_vdev_get_ref_by_id does does a atomic operation avoid using
|
||||
* this in per packet path.
|
||||
*
|
||||
* As in this path vdev memory is already protected with netdev
|
||||
* tx lock
|
||||
*/
|
||||
vdev = soc->vdev_id_map[vdev_id];
|
||||
if (qdf_unlikely(!vdev))
|
||||
return nbuf;
|
||||
|
||||
@@ -4123,7 +4139,7 @@ qdf_nbuf_t dp_tx_non_std(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
|
||||
enum ol_tx_spec tx_spec, qdf_nbuf_t msdu_list)
|
||||
{
|
||||
struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
|
||||
struct dp_vdev *vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc, vdev_id);
|
||||
struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id);
|
||||
|
||||
if (!vdev) {
|
||||
dp_err("vdev handle for id %d is NULL", vdev_id);
|
||||
@@ -4132,6 +4148,7 @@ qdf_nbuf_t dp_tx_non_std(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
|
||||
|
||||
if (tx_spec & OL_TX_SPEC_NO_FREE)
|
||||
vdev->is_tdls_frame = true;
|
||||
dp_vdev_unref_delete(soc, vdev);
|
||||
|
||||
return dp_tx_send(soc_hdl, vdev_id, msdu_list);
|
||||
}
|
||||
|
@@ -526,16 +526,18 @@ static inline bool
|
||||
dp_tx_desc_thresh_reached(struct cdp_soc_t *soc_hdl, uint8_t vdev_id)
|
||||
{
|
||||
struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
|
||||
struct dp_vdev *vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc,
|
||||
vdev_id);
|
||||
struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id);
|
||||
struct dp_tx_desc_pool_s *pool;
|
||||
bool status;
|
||||
|
||||
if (!vdev)
|
||||
return false;
|
||||
|
||||
pool = vdev->pool;
|
||||
status = dp_tx_is_threshold_reached(pool, pool->avail_desc);
|
||||
dp_vdev_unref_delete(soc, vdev);
|
||||
|
||||
return dp_tx_is_threshold_reached(pool, pool->avail_desc);
|
||||
return status;
|
||||
}
|
||||
#else /* QCA_LL_TX_FLOW_CONTROL_V2 */
|
||||
|
||||
|
@@ -342,10 +342,11 @@ int dp_tx_delete_flow_pool(struct dp_soc *soc, struct dp_tx_desc_pool_s *pool,
|
||||
pool->status = FLOW_POOL_INVALID;
|
||||
qdf_spin_unlock_bh(&pool->flow_pool_lock);
|
||||
/* Reset TX desc associated to this Vdev as NULL */
|
||||
vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc,
|
||||
pool->flow_pool_id);
|
||||
if (vdev)
|
||||
vdev = dp_vdev_get_ref_by_id(soc, pool->flow_pool_id);
|
||||
if (vdev) {
|
||||
dp_tx_desc_flush(vdev->pdev, vdev, false);
|
||||
dp_vdev_unref_delete(soc, vdev);
|
||||
}
|
||||
dp_err("avail desc less than pool size");
|
||||
return -EAGAIN;
|
||||
}
|
||||
@@ -371,7 +372,7 @@ static void dp_tx_flow_pool_vdev_map(struct dp_pdev *pdev,
|
||||
struct dp_vdev *vdev;
|
||||
struct dp_soc *soc = pdev->soc;
|
||||
|
||||
vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc, vdev_id);
|
||||
vdev = dp_vdev_get_ref_by_id(soc, vdev_id);
|
||||
if (!vdev) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"%s: invalid vdev_id %d",
|
||||
@@ -384,6 +385,7 @@ static void dp_tx_flow_pool_vdev_map(struct dp_pdev *pdev,
|
||||
pool->pool_owner_ctx = soc;
|
||||
pool->flow_pool_id = vdev_id;
|
||||
qdf_spin_unlock_bh(&pool->flow_pool_lock);
|
||||
dp_vdev_unref_delete(soc, vdev);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -400,7 +402,7 @@ static void dp_tx_flow_pool_vdev_unmap(struct dp_pdev *pdev,
|
||||
struct dp_vdev *vdev;
|
||||
struct dp_soc *soc = pdev->soc;
|
||||
|
||||
vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc, vdev_id);
|
||||
vdev = dp_vdev_get_ref_by_id(soc, vdev_id);
|
||||
if (!vdev) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"%s: invalid vdev_id %d",
|
||||
@@ -409,6 +411,7 @@ static void dp_tx_flow_pool_vdev_unmap(struct dp_pdev *pdev,
|
||||
}
|
||||
|
||||
vdev->pool = NULL;
|
||||
dp_vdev_unref_delete(soc, vdev);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -1508,6 +1508,8 @@ struct dp_soc {
|
||||
struct dp_last_op_info last_op_info;
|
||||
TAILQ_HEAD(, dp_peer) inactive_peer_list;
|
||||
qdf_spinlock_t inactive_peer_list_lock;
|
||||
/* lock to protect vdev_id_map table*/
|
||||
qdf_spinlock_t vdev_map_lock;
|
||||
};
|
||||
|
||||
#ifdef IPA_OFFLOAD
|
||||
|
Reference in New Issue
Block a user