xref: /freebsd/sys/dev/ath/ath_dfs/null/dfs_null.c (revision 5097809e5b72cb25db9c4c12de9272dee6bcde76)
1 /*-
2  * Copyright (c) 2011 Adrian Chadd, Xenion Pty Ltd
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer,
10  *    without modification.
11  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13  *    redistribution must be conditioned upon including a substantially
14  *    similar Disclaimer requirement for further binary redistribution.
15  *
16  * NO WARRANTY
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
20  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
22  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27  * THE POSSIBILITY OF SUCH DAMAGES.
28  *
29  * $FreeBSD$
30  */
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33 
34 /*
35  * This implements an empty DFS module.
36  */
37 #include "opt_ath.h"
38 #include "opt_inet.h"
39 #include "opt_wlan.h"
40 
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/sysctl.h>
44 #include <sys/kernel.h>
45 #include <sys/lock.h>
46 #include <sys/mutex.h>
47 #include <sys/errno.h>
48 
49 #include <machine/bus.h>
50 #include <machine/resource.h>
51 #include <sys/bus.h>
52 
53 #include <sys/socket.h>
54 
55 #include <net/if.h>
56 #include <net/if_media.h>
57 #include <net/if_arp.h>
58 #include <net/ethernet.h>		/* XXX for ether_sprintf */
59 
60 #include <net80211/ieee80211_var.h>
61 
62 #include <net/bpf.h>
63 
64 #ifdef INET
65 #include <netinet/in.h>
66 #include <netinet/if_ether.h>
67 #endif
68 
69 #include <dev/ath/if_athvar.h>
70 #include <dev/ath/if_athdfs.h>
71 
72 #include <dev/ath/ath_hal/ah_desc.h>
73 
74 /*
75  * These are default parameters for the AR5416 and
76  * later 802.11n NICs.  They simply enable some
77  * radar pulse event generation.
78  *
79  * These are very likely not valid for the AR5212 era
80  * NICs.
81  *
82  * Since these define signal sizing and threshold
83  * parameters, they may need changing based on the
84  * specific antenna and receive amplifier
85  * configuration.
86  */
87 #define	AR5416_DFS_FIRPWR	-33
88 #define	AR5416_DFS_RRSSI	20
89 #define	AR5416_DFS_HEIGHT	10
90 #define	AR5416_DFS_PRSSI	15
91 #define	AR5416_DFS_INBAND	15
92 #define	AR5416_DFS_RELPWR	8
93 #define	AR5416_DFS_RELSTEP	12
94 #define	AR5416_DFS_MAXLEN	255
95 
96 /*
97  * Methods which are required
98  */
99 
100 /*
101  * Attach DFS to the given interface
102  */
103 int
104 ath_dfs_attach(struct ath_softc *sc)
105 {
106 	return (1);
107 }
108 
109 /*
110  * Detach DFS from the given interface
111  */
112 int
113 ath_dfs_detach(struct ath_softc *sc)
114 {
115 	return (1);
116 }
117 
118 /*
119  * Enable radar check.  Return 1 if the driver should
120  * enable radar PHY errors, or 0 if not.
121  */
122 int
123 ath_dfs_radar_enable(struct ath_softc *sc, struct ieee80211_channel *chan)
124 {
125 #if 0
126 	HAL_PHYERR_PARAM pe;
127 
128 	/* Check if the current channel is radar-enabled */
129 	if (! IEEE80211_IS_CHAN_DFS(chan))
130 		return (0);
131 
132 	/* Enable radar PHY error reporting */
133 	sc->sc_dodfs = 1;
134 
135 	/*
136 	 * These are general examples of the parameter values
137 	 * to use when configuring radar pulse detection for
138 	 * the AR5416, AR91xx, AR92xx NICs.  They are only
139 	 * for testing and do require tuning depending upon the
140 	 * hardware and deployment specifics.
141 	 */
142 	pe.pe_firpwr = AR5416_DFS_FIRPWR;
143 	pe.pe_rrssi = AR5416_DFS_RRSSI;
144 	pe.pe_height = AR5416_DFS_HEIGHT;
145 	pe.pe_prssi = AR5416_DFS_PRSSI;
146 	pe.pe_inband = AR5416_DFS_INBAND;
147 	pe.pe_relpwr = AR5416_DFS_RELPWR;
148 	pe.pe_relstep = AR5416_DFS_RELSTEP;
149 	pe.pe_maxlen = AR5416_DFS_MAXLEN;
150 	pe.pe_enabled = 1;
151 
152 	/* Flip on extension channel events only if doing HT40 */
153 	if (IEEE80211_IS_CHAN_HT40(chan))
154 		pe.pe_extchannel = 1;
155 	else
156 		pe.pe_extchannel = 0;
157 
158 	ath_hal_enabledfs(sc->sc_ah, &pe);
159 
160 	return (1);
161 #else
162 	return (0);
163 #endif
164 }
165 
166 /*
167  * Process DFS related PHY errors
168  *
169  * The mbuf is not "ours" and if we want a copy, we have
170  * to take a copy.  It'll be freed after this function returns.
171  */
172 void
173 ath_dfs_process_phy_err(struct ath_softc *sc, struct mbuf *m,
174     uint64_t tsf, struct ath_rx_status *rxstat)
175 {
176 
177 }
178 
179 /*
180  * Process the radar events and determine whether a DFS event has occured.
181  *
182  * This is designed to run outside of the RX processing path.
183  * The RX path will call ath_dfs_tasklet_needed() to see whether
184  * the task/callback running this routine needs to be called.
185  */
186 int
187 ath_dfs_process_radar_event(struct ath_softc *sc,
188     struct ieee80211_channel *chan)
189 {
190 	return (0);
191 }
192 
193 /*
194  * Determine whether the DFS check task needs to be queued.
195  *
196  * This is called in the RX task when the current batch of packets
197  * have been received. It will return whether there are any radar
198  * events for ath_dfs_process_radar_event() to handle.
199  */
200 int
201 ath_dfs_tasklet_needed(struct ath_softc *sc, struct ieee80211_channel *chan)
202 {
203 	return (0);
204 }
205 
206 /*
207  * Handle ioctl requests from the diagnostic interface.
208  *
209  * The initial part of this code resembles ath_ioctl_diag();
210  * it's likely a good idea to reduce duplication between
211  * these two routines.
212  */
213 int
214 ath_ioctl_phyerr(struct ath_softc *sc, struct ath_diag *ad)
215 {
216 	unsigned int id = ad->ad_id & ATH_DIAG_ID;
217 	void *indata = NULL;
218 	void *outdata = NULL;
219 	u_int32_t insize = ad->ad_in_size;
220 	u_int32_t outsize = ad->ad_out_size;
221 	int error = 0;
222 	HAL_PHYERR_PARAM peout;
223 	HAL_PHYERR_PARAM *pe;
224 
225 	if (ad->ad_id & ATH_DIAG_IN) {
226 		/*
227 		 * Copy in data.
228 		 */
229 		indata = malloc(insize, M_TEMP, M_NOWAIT);
230 		if (indata == NULL) {
231 			error = ENOMEM;
232 			goto bad;
233 		}
234 		error = copyin(ad->ad_in_data, indata, insize);
235 		if (error)
236 			goto bad;
237 	}
238 	if (ad->ad_id & ATH_DIAG_DYN) {
239 		/*
240 		 * Allocate a buffer for the results (otherwise the HAL
241 		 * returns a pointer to a buffer where we can read the
242 		 * results).  Note that we depend on the HAL leaving this
243 		 * pointer for us to use below in reclaiming the buffer;
244 		 * may want to be more defensive.
245 		 */
246 		outdata = malloc(outsize, M_TEMP, M_NOWAIT);
247 		if (outdata == NULL) {
248 			error = ENOMEM;
249 			goto bad;
250 		}
251 	}
252 	switch (id) {
253 		case DFS_SET_THRESH:
254 			if (insize < sizeof(HAL_PHYERR_PARAM)) {
255 				error = EINVAL;
256 				break;
257 			}
258 			pe = (HAL_PHYERR_PARAM *) indata;
259 			ath_hal_enabledfs(sc->sc_ah, pe);
260 			break;
261 		case DFS_GET_THRESH:
262 			memset(&peout, 0, sizeof(peout));
263 			outsize = sizeof(HAL_PHYERR_PARAM);
264 			ath_hal_getdfsthresh(sc->sc_ah, &peout);
265 			pe = (HAL_PHYERR_PARAM *) outdata;
266 			memcpy(pe, &peout, sizeof(*pe));
267 			break;
268 		default:
269 			error = EINVAL;
270 	}
271 	if (outsize < ad->ad_out_size)
272 		ad->ad_out_size = outsize;
273 	if (outdata && copyout(outdata, ad->ad_out_data, ad->ad_out_size))
274 		error = EFAULT;
275 bad:
276 	if ((ad->ad_id & ATH_DIAG_IN) && indata != NULL)
277 		free(indata, M_TEMP);
278 	if ((ad->ad_id & ATH_DIAG_DYN) && outdata != NULL)
279 		free(outdata, M_TEMP);
280 	return (error);
281 }
282 
283 /*
284  * Get the current DFS thresholds from the HAL
285  */
286 int
287 ath_dfs_get_thresholds(struct ath_softc *sc, HAL_PHYERR_PARAM *param)
288 {
289 	ath_hal_getdfsthresh(sc->sc_ah, param);
290 	return (1);
291 }
292