1
1
// SPDX-License-Identifier: BSD-3-Clause-Clear
2
2
/*
3
3
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
4
- * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
4
+ * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
5
5
*/
6
6
7
7
#include <linux/ieee80211.h>
@@ -675,11 +675,11 @@ void ath11k_dp_reo_cmd_list_cleanup(struct ath11k_base *ab)
675
675
list_for_each_entry_safe (cmd , tmp , & dp -> reo_cmd_list , list ) {
676
676
list_del (& cmd -> list );
677
677
rx_tid = & cmd -> data ;
678
- if (rx_tid -> vaddr ) {
679
- dma_unmap_single (ab -> dev , rx_tid -> paddr ,
680
- rx_tid -> size , DMA_BIDIRECTIONAL );
681
- kfree ( rx_tid -> vaddr );
682
- rx_tid -> vaddr = NULL ;
678
+ if (rx_tid -> vaddr_unaligned ) {
679
+ dma_free_noncoherent (ab -> dev , rx_tid -> unaligned_size ,
680
+ rx_tid -> vaddr_unaligned ,
681
+ rx_tid -> paddr_unaligned , DMA_BIDIRECTIONAL );
682
+ rx_tid -> vaddr_unaligned = NULL ;
683
683
}
684
684
kfree (cmd );
685
685
}
@@ -689,11 +689,11 @@ void ath11k_dp_reo_cmd_list_cleanup(struct ath11k_base *ab)
689
689
list_del (& cmd_cache -> list );
690
690
dp -> reo_cmd_cache_flush_count -- ;
691
691
rx_tid = & cmd_cache -> data ;
692
- if (rx_tid -> vaddr ) {
693
- dma_unmap_single (ab -> dev , rx_tid -> paddr ,
694
- rx_tid -> size , DMA_BIDIRECTIONAL );
695
- kfree ( rx_tid -> vaddr );
696
- rx_tid -> vaddr = NULL ;
692
+ if (rx_tid -> vaddr_unaligned ) {
693
+ dma_free_noncoherent (ab -> dev , rx_tid -> unaligned_size ,
694
+ rx_tid -> vaddr_unaligned ,
695
+ rx_tid -> paddr_unaligned , DMA_BIDIRECTIONAL );
696
+ rx_tid -> vaddr_unaligned = NULL ;
697
697
}
698
698
kfree (cmd_cache );
699
699
}
@@ -708,11 +708,11 @@ static void ath11k_dp_reo_cmd_free(struct ath11k_dp *dp, void *ctx,
708
708
if (status != HAL_REO_CMD_SUCCESS )
709
709
ath11k_warn (dp -> ab , "failed to flush rx tid hw desc, tid %d status %d\n" ,
710
710
rx_tid -> tid , status );
711
- if (rx_tid -> vaddr ) {
712
- dma_unmap_single (dp -> ab -> dev , rx_tid -> paddr , rx_tid -> size ,
713
- DMA_BIDIRECTIONAL );
714
- kfree ( rx_tid -> vaddr );
715
- rx_tid -> vaddr = NULL ;
711
+ if (rx_tid -> vaddr_unaligned ) {
712
+ dma_free_noncoherent (dp -> ab -> dev , rx_tid -> unaligned_size ,
713
+ rx_tid -> vaddr_unaligned ,
714
+ rx_tid -> paddr_unaligned , DMA_BIDIRECTIONAL );
715
+ rx_tid -> vaddr_unaligned = NULL ;
716
716
}
717
717
}
718
718
@@ -749,10 +749,10 @@ static void ath11k_dp_reo_cache_flush(struct ath11k_base *ab,
749
749
if (ret ) {
750
750
ath11k_err (ab , "failed to send HAL_REO_CMD_FLUSH_CACHE cmd, tid %d (%d)\n" ,
751
751
rx_tid -> tid , ret );
752
- dma_unmap_single (ab -> dev , rx_tid -> paddr , rx_tid -> size ,
753
- DMA_BIDIRECTIONAL );
754
- kfree ( rx_tid -> vaddr );
755
- rx_tid -> vaddr = NULL ;
752
+ dma_free_noncoherent (ab -> dev , rx_tid -> unaligned_size ,
753
+ rx_tid -> vaddr_unaligned ,
754
+ rx_tid -> paddr_unaligned , DMA_BIDIRECTIONAL );
755
+ rx_tid -> vaddr_unaligned = NULL ;
756
756
}
757
757
}
758
758
@@ -802,10 +802,10 @@ static void ath11k_dp_rx_tid_del_func(struct ath11k_dp *dp, void *ctx,
802
802
803
803
return ;
804
804
free_desc :
805
- dma_unmap_single (ab -> dev , rx_tid -> paddr , rx_tid -> size ,
806
- DMA_BIDIRECTIONAL );
807
- kfree ( rx_tid -> vaddr );
808
- rx_tid -> vaddr = NULL ;
805
+ dma_free_noncoherent (ab -> dev , rx_tid -> unaligned_size ,
806
+ rx_tid -> vaddr_unaligned ,
807
+ rx_tid -> paddr_unaligned , DMA_BIDIRECTIONAL );
808
+ rx_tid -> vaddr_unaligned = NULL ;
809
809
}
810
810
811
811
void ath11k_peer_rx_tid_delete (struct ath11k * ar ,
@@ -831,14 +831,16 @@ void ath11k_peer_rx_tid_delete(struct ath11k *ar,
831
831
if (ret != - ESHUTDOWN )
832
832
ath11k_err (ar -> ab , "failed to send HAL_REO_CMD_UPDATE_RX_QUEUE cmd, tid %d (%d)\n" ,
833
833
tid , ret );
834
- dma_unmap_single (ar -> ab -> dev , rx_tid -> paddr , rx_tid -> size ,
835
- DMA_BIDIRECTIONAL );
836
- kfree ( rx_tid -> vaddr );
837
- rx_tid -> vaddr = NULL ;
834
+ dma_free_noncoherent (ar -> ab -> dev , rx_tid -> unaligned_size ,
835
+ rx_tid -> vaddr_unaligned ,
836
+ rx_tid -> paddr_unaligned , DMA_BIDIRECTIONAL );
837
+ rx_tid -> vaddr_unaligned = NULL ;
838
838
}
839
839
840
840
rx_tid -> paddr = 0 ;
841
+ rx_tid -> paddr_unaligned = 0 ;
841
842
rx_tid -> size = 0 ;
843
+ rx_tid -> unaligned_size = 0 ;
842
844
}
843
845
844
846
static int ath11k_dp_rx_link_desc_return (struct ath11k_base * ab ,
@@ -982,10 +984,9 @@ static void ath11k_dp_rx_tid_mem_free(struct ath11k_base *ab,
982
984
if (!rx_tid -> active )
983
985
goto unlock_exit ;
984
986
985
- dma_unmap_single (ab -> dev , rx_tid -> paddr , rx_tid -> size ,
986
- DMA_BIDIRECTIONAL );
987
- kfree (rx_tid -> vaddr );
988
- rx_tid -> vaddr = NULL ;
987
+ dma_free_noncoherent (ab -> dev , rx_tid -> unaligned_size , rx_tid -> vaddr_unaligned ,
988
+ rx_tid -> paddr_unaligned , DMA_BIDIRECTIONAL );
989
+ rx_tid -> vaddr_unaligned = NULL ;
989
990
990
991
rx_tid -> active = false;
991
992
@@ -1000,9 +1001,8 @@ int ath11k_peer_rx_tid_setup(struct ath11k *ar, const u8 *peer_mac, int vdev_id,
1000
1001
struct ath11k_base * ab = ar -> ab ;
1001
1002
struct ath11k_peer * peer ;
1002
1003
struct dp_rx_tid * rx_tid ;
1003
- u32 hw_desc_sz ;
1004
- u32 * addr_aligned ;
1005
- void * vaddr ;
1004
+ u32 hw_desc_sz , * vaddr ;
1005
+ void * vaddr_unaligned ;
1006
1006
dma_addr_t paddr ;
1007
1007
int ret ;
1008
1008
@@ -1050,49 +1050,40 @@ int ath11k_peer_rx_tid_setup(struct ath11k *ar, const u8 *peer_mac, int vdev_id,
1050
1050
else
1051
1051
hw_desc_sz = ath11k_hal_reo_qdesc_size (DP_BA_WIN_SZ_MAX , tid );
1052
1052
1053
- vaddr = kzalloc (hw_desc_sz + HAL_LINK_DESC_ALIGN - 1 , GFP_ATOMIC );
1054
- if (!vaddr ) {
1053
+ rx_tid -> unaligned_size = hw_desc_sz + HAL_LINK_DESC_ALIGN - 1 ;
1054
+ vaddr_unaligned = dma_alloc_noncoherent (ab -> dev , rx_tid -> unaligned_size , & paddr ,
1055
+ DMA_BIDIRECTIONAL , GFP_ATOMIC );
1056
+ if (!vaddr_unaligned ) {
1055
1057
spin_unlock_bh (& ab -> base_lock );
1056
1058
return - ENOMEM ;
1057
1059
}
1058
1060
1059
- addr_aligned = PTR_ALIGN (vaddr , HAL_LINK_DESC_ALIGN );
1060
-
1061
- ath11k_hal_reo_qdesc_setup (addr_aligned , tid , ba_win_sz ,
1062
- ssn , pn_type );
1063
-
1064
- paddr = dma_map_single (ab -> dev , addr_aligned , hw_desc_sz ,
1065
- DMA_BIDIRECTIONAL );
1066
-
1067
- ret = dma_mapping_error (ab -> dev , paddr );
1068
- if (ret ) {
1069
- spin_unlock_bh (& ab -> base_lock );
1070
- ath11k_warn (ab , "failed to setup dma map for peer %pM rx tid %d: %d\n" ,
1071
- peer_mac , tid , ret );
1072
- goto err_mem_free ;
1073
- }
1074
-
1075
- rx_tid -> vaddr = vaddr ;
1076
- rx_tid -> paddr = paddr ;
1061
+ rx_tid -> vaddr_unaligned = vaddr_unaligned ;
1062
+ vaddr = PTR_ALIGN (vaddr_unaligned , HAL_LINK_DESC_ALIGN );
1063
+ rx_tid -> paddr_unaligned = paddr ;
1064
+ rx_tid -> paddr = rx_tid -> paddr_unaligned + ((unsigned long )vaddr -
1065
+ (unsigned long )rx_tid -> vaddr_unaligned );
1066
+ ath11k_hal_reo_qdesc_setup (vaddr , tid , ba_win_sz , ssn , pn_type );
1077
1067
rx_tid -> size = hw_desc_sz ;
1078
1068
rx_tid -> active = true;
1079
1069
1070
+ /* After dma_alloc_noncoherent, vaddr is being modified for reo qdesc setup.
1071
+ * Since these changes are not reflected in the device, driver now needs to
1072
+ * explicitly call dma_sync_single_for_device.
1073
+ */
1074
+ dma_sync_single_for_device (ab -> dev , rx_tid -> paddr ,
1075
+ rx_tid -> size ,
1076
+ DMA_TO_DEVICE );
1080
1077
spin_unlock_bh (& ab -> base_lock );
1081
1078
1082
- ret = ath11k_wmi_peer_rx_reorder_queue_setup (ar , vdev_id , peer_mac ,
1083
- paddr , tid , 1 , ba_win_sz );
1079
+ ret = ath11k_wmi_peer_rx_reorder_queue_setup (ar , vdev_id , peer_mac , rx_tid -> paddr ,
1080
+ tid , 1 , ba_win_sz );
1084
1081
if (ret ) {
1085
1082
ath11k_warn (ar -> ab , "failed to setup rx reorder queue for peer %pM tid %d: %d\n" ,
1086
1083
peer_mac , tid , ret );
1087
1084
ath11k_dp_rx_tid_mem_free (ab , peer_mac , vdev_id , tid );
1088
1085
}
1089
1086
1090
- return ret ;
1091
-
1092
- err_mem_free :
1093
- kfree (rx_tid -> vaddr );
1094
- rx_tid -> vaddr = NULL ;
1095
-
1096
1087
return ret ;
1097
1088
}
1098
1089
0 commit comments