xref: /wlan-dirver/qca-wifi-host-cmn/umac/dfs/core/src/filtering/dfs_misc.c (revision 97f44cd39e4ff816eaa1710279d28cf6b9e65ad9)
1 /*
2  * Copyright (c) 2016-2017,2020 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2002-2010, Atheros Communications Inc.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 /**
19  * DOC: This file really does contain miscellaneous functions that didn't fit
20  * in anywhere else.
21  */
22 
23 #include "../dfs.h"
24 #include "wlan_dfs_lmac_api.h"
25 #include "wlan_dfs_mlme_api.h"
26 #include "../dfs_internal.h"
27 
28 /**
29  * dfs_adjust_pri_per_chan_busy() - Calculates adjust_pri.
30  * @ext_chan_busy: Extension channel PRI.
31  * @pri_margin: Primary margin.
32  *
33  * Calculates the adjust_pri using ext_chan_busy, DFS_EXT_CHAN_LOADING_THRESH
34  * and pri_margin.
35  *
36  * Return: adjust_pri.
37  */
38 static int dfs_adjust_pri_per_chan_busy(int ext_chan_busy, int pri_margin)
39 {
40 	int adjust_pri = 0;
41 
42 	if (ext_chan_busy > DFS_EXT_CHAN_LOADING_THRESH) {
43 		adjust_pri = ((ext_chan_busy - DFS_EXT_CHAN_LOADING_THRESH) *
44 				(pri_margin));
45 		adjust_pri /= 100;
46 	}
47 
48 	return adjust_pri;
49 }
50 
51 /**
52  * dfs_adjust_thresh_per_chan_busy() - Calculates adjust_thresh.
53  * @ext_chan_busy: Extension channel PRI.
54  * @thresh: Threshold value.
55  *
56  * Calculates the adjust_thresh using ext_chan_busy, DFS_EXT_CHAN_LOADING_THRESH
57  * and thresh.
58  *
59  * Return: adjust_thresh.
60  */
61 static int dfs_adjust_thresh_per_chan_busy(int ext_chan_busy, int thresh)
62 {
63 	int adjust_thresh = 0;
64 
65 	if (ext_chan_busy > DFS_EXT_CHAN_LOADING_THRESH) {
66 		adjust_thresh = ((ext_chan_busy - DFS_EXT_CHAN_LOADING_THRESH) *
67 				thresh);
68 		adjust_thresh /= 100;
69 	}
70 
71 	return adjust_thresh;
72 }
73 
74 /**
75  * dfs_get_cached_ext_chan_busy() - Get cached ext chan busy.
76  * @dfs: Pointer to wlan_dfs structure.
77  * @ext_chan_busy: Extension channel PRI.
78  */
79 static inline void dfs_get_cached_ext_chan_busy(
80 		struct wlan_dfs *dfs,
81 		int *ext_chan_busy)
82 {
83 	*ext_chan_busy = 0;
84 	/* Check to see if the cached value of ext_chan_busy can be used. */
85 
86 	if (dfs->dfs_rinfo.dfs_ext_chan_busy &&
87 			(dfs->dfs_rinfo.rn_lastfull_ts <
88 			 dfs->dfs_rinfo.ext_chan_busy_ts)) {
89 		*ext_chan_busy = dfs->dfs_rinfo.dfs_ext_chan_busy;
90 		dfs_debug(dfs, WLAN_DEBUG_DFS2,
91 				"Use cached copy of ext_chan_busy extchanbusy=%d rn_lastfull_ts=%llu ext_chan_busy_ts=%llu",
92 				*ext_chan_busy,
93 				(uint64_t)dfs->dfs_rinfo.rn_lastfull_ts,
94 				(uint64_t)dfs->dfs_rinfo.ext_chan_busy_ts);
95 	}
96 }
97 
98 #if defined(WLAN_DFS_PARTIAL_OFFLOAD)
99 int dfs_get_pri_margin(struct wlan_dfs *dfs,
100 		int is_extchan_detect,
101 		int is_fixed_pattern)
102 {
103 	int adjust_pri = 0, ext_chan_busy = 0;
104 	int pri_margin;
105 
106 	if (is_fixed_pattern)
107 		pri_margin = DFS_DEFAULT_FIXEDPATTERN_PRI_MARGIN;
108 	else
109 		pri_margin = DFS_DEFAULT_PRI_MARGIN;
110 
111 	if (WLAN_IS_CHAN_11N_HT40(dfs->dfs_curchan)) {
112 		ext_chan_busy = lmac_get_ext_busy(dfs->dfs_pdev_obj);
113 		if (ext_chan_busy >= 0) {
114 			dfs->dfs_rinfo.ext_chan_busy_ts =
115 				lmac_get_tsf64(dfs->dfs_pdev_obj);
116 			dfs->dfs_rinfo.dfs_ext_chan_busy = ext_chan_busy;
117 		} else {
118 			dfs_get_cached_ext_chan_busy(dfs, &ext_chan_busy);
119 		}
120 		adjust_pri = dfs_adjust_pri_per_chan_busy(ext_chan_busy,
121 			pri_margin);
122 		pri_margin -= adjust_pri;
123 	}
124 
125 	return pri_margin;
126 }
127 #endif
128 
129 int dfs_get_filter_threshold(struct wlan_dfs *dfs,
130 		struct dfs_filter *rf,
131 		int is_extchan_detect)
132 {
133 	int ext_chan_busy = 0;
134 	int thresh, adjust_thresh = 0;
135 
136 	thresh = rf->rf_threshold;
137 
138 	if (WLAN_IS_CHAN_11N_HT40(dfs->dfs_curchan)) {
139 		ext_chan_busy = lmac_get_ext_busy(dfs->dfs_pdev_obj);
140 		if (ext_chan_busy >= 0) {
141 			dfs->dfs_rinfo.ext_chan_busy_ts =
142 				lmac_get_tsf64(dfs->dfs_pdev_obj);
143 			dfs->dfs_rinfo.dfs_ext_chan_busy = ext_chan_busy;
144 		} else {
145 			dfs_get_cached_ext_chan_busy(dfs, &ext_chan_busy);
146 		}
147 
148 		adjust_thresh =
149 			dfs_adjust_thresh_per_chan_busy(ext_chan_busy, thresh);
150 		dfs_debug(dfs, WLAN_DEBUG_DFS2,
151 			" filterID=%d extchanbusy=%d adjust_thresh=%d",
152 			rf->rf_pulseid, ext_chan_busy, adjust_thresh);
153 
154 		thresh += adjust_thresh;
155 	}
156 
157 	return thresh;
158 }
159 
160 uint32_t dfs_round(int32_t val)
161 {
162 	uint32_t ival, rem;
163 
164 	if (val < 0)
165 		return 0;
166 	ival = val/100;
167 	rem = val - (ival * 100);
168 	if (rem < 50)
169 		return ival;
170 	else
171 		return ival + 1;
172 }
173