|
@@ -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);
|
|
|
}
|