dfs_null.c revision 231099
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: head/sys/dev/ath/ath_dfs/null/dfs_null.c 231099 2012-02-06 20:23:21Z adrian $
30 */
31#include <sys/cdefs.h>
32__FBSDID("$FreeBSD: head/sys/dev/ath/ath_dfs/null/dfs_null.c 231099 2012-02-06 20:23:21Z adrian $");
33
34/*
35 * This implements an empty DFS module.
36 */
37#include "opt_inet.h"
38#include "opt_wlan.h"
39
40#include <sys/param.h>
41#include <sys/systm.h>
42#include <sys/sysctl.h>
43#include <sys/kernel.h>
44#include <sys/lock.h>
45#include <sys/mutex.h>
46#include <sys/errno.h>
47
48#include <machine/bus.h>
49#include <machine/resource.h>
50#include <sys/bus.h>
51
52#include <sys/socket.h>
53
54#include <net/if.h>
55#include <net/if_media.h>
56#include <net/if_arp.h>
57#include <net/ethernet.h>		/* XXX for ether_sprintf */
58
59#include <net80211/ieee80211_var.h>
60
61#include <net/bpf.h>
62
63#ifdef INET
64#include <netinet/in.h>
65#include <netinet/if_ether.h>
66#endif
67
68#include <dev/ath/if_athvar.h>
69#include <dev/ath/if_athdfs.h>
70
71#include <dev/ath/ath_hal/ah_desc.h>
72
73/*
74 * These are default parameters for the AR5416 and
75 * later 802.11n NICs.  They simply enable some
76 * radar pulse event generation.
77 *
78 * These are very likely not valid for the AR5212 era
79 * NICs.
80 *
81 * Since these define signal sizing and threshold
82 * parameters, they may need changing based on the
83 * specific antenna and receive amplifier
84 * configuration.
85 */
86#define	AR5416_DFS_FIRPWR	-33
87#define	AR5416_DFS_RRSSI	20
88#define	AR5416_DFS_HEIGHT	10
89#define	AR5416_DFS_PRSSI	15
90#define	AR5416_DFS_INBAND	15
91#define	AR5416_DFS_RELPWR	8
92#define	AR5416_DFS_RELSTEP	12
93#define	AR5416_DFS_MAXLEN	255
94
95/*
96 * Methods which are required
97 */
98
99/*
100 * Attach DFS to the given interface
101 */
102int
103ath_dfs_attach(struct ath_softc *sc)
104{
105	return 1;
106}
107
108/*
109 * Detach DFS from the given interface
110 */
111int
112ath_dfs_detach(struct ath_softc *sc)
113{
114	return 1;
115}
116
117/*
118 * Enable radar check
119 */
120int
121ath_dfs_radar_enable(struct ath_softc *sc, struct ieee80211_channel *chan)
122{
123#if 0
124	HAL_PHYERR_PARAM pe;
125
126	/* Check if the current channel is radar-enabled */
127	if (! IEEE80211_IS_CHAN_DFS(chan))
128		return (0);
129
130	/* Enable radar PHY error reporting */
131	sc->sc_dodfs = 1;
132
133	/*
134	 * These are general examples of the parameter values
135	 * to use when configuring radar pulse detection for
136	 * the AR5416, AR91xx, AR92xx NICs.  They are only
137	 * for testing and do require tuning depending upon the
138	 * hardware and deployment specifics.
139	 */
140	pe.pe_firpwr = AR5416_DFS_FIRPWR;
141	pe.pe_rrssi = AR5416_DFS_RRSSI;
142	pe.pe_height = AR5416_DFS_HEIGHT;
143	pe.pe_prssi = AR5416_DFS_PRSSI;
144	pe.pe_inband = AR5416_DFS_INBAND;
145	pe.pe_relpwr = AR5416_DFS_RELPWR;
146	pe.pe_relstep = AR5416_DFS_RELSTEP;
147	pe.pe_maxlen = AR5416_DFS_MAXLEN;
148	pe.pe_enabled = 1;
149
150	/* Flip on extension channel events only if doing HT40 */
151	if (IEEE80211_IS_CHAN_HT40(chan))
152		pe.pe_extchannel = 1;
153	else
154		pe.pe_extchannel = 0;
155
156	ath_hal_enabledfs(sc->sc_ah, &pe);
157
158	return (1);
159#else
160	return (0);
161#endif
162}
163
164/*
165 * Process DFS related PHY errors
166 */
167void
168ath_dfs_process_phy_err(struct ath_softc *sc, const char *buf,
169    uint64_t tsf, struct ath_rx_status *rxstat)
170{
171
172}
173
174/*
175 * Process the radar events and determine whether a DFS event has occured.
176 *
177 * This is designed to run outside of the RX processing path.
178 * The RX path will call ath_dfs_tasklet_needed() to see whether
179 * the task/callback running this routine needs to be called.
180 */
181int
182ath_dfs_process_radar_event(struct ath_softc *sc,
183    struct ieee80211_channel *chan)
184{
185	return 0;
186}
187
188/*
189 * Determine whether the DFS check task needs to be queued.
190 *
191 * This is called in the RX task when the current batch of packets
192 * have been received. It will return whether there are any radar
193 * events for ath_dfs_process_radar_event() to handle.
194 */
195int
196ath_dfs_tasklet_needed(struct ath_softc *sc, struct ieee80211_channel *chan)
197{
198	return 0;
199}
200
201/*
202 * Handle ioctl requests from the diagnostic interface.
203 *
204 * The initial part of this code resembles ath_ioctl_diag();
205 * it's likely a good idea to reduce duplication between
206 * these two routines.
207 */
208int
209ath_ioctl_phyerr(struct ath_softc *sc, struct ath_diag *ad)
210{
211	unsigned int id = ad->ad_id & ATH_DIAG_ID;
212	void *indata = NULL;
213	void *outdata = NULL;
214	u_int32_t insize = ad->ad_in_size;
215	u_int32_t outsize = ad->ad_out_size;
216	int error = 0;
217	HAL_PHYERR_PARAM peout;
218	HAL_PHYERR_PARAM *pe;
219
220	if (ad->ad_id & ATH_DIAG_IN) {
221		/*
222		 * Copy in data.
223		 */
224		indata = malloc(insize, M_TEMP, M_NOWAIT);
225		if (indata == NULL) {
226			error = ENOMEM;
227			goto bad;
228		}
229		error = copyin(ad->ad_in_data, indata, insize);
230		if (error)
231			goto bad;
232	}
233	if (ad->ad_id & ATH_DIAG_DYN) {
234		/*
235		 * Allocate a buffer for the results (otherwise the HAL
236		 * returns a pointer to a buffer where we can read the
237		 * results).  Note that we depend on the HAL leaving this
238		 * pointer for us to use below in reclaiming the buffer;
239		 * may want to be more defensive.
240		 */
241		outdata = malloc(outsize, M_TEMP, M_NOWAIT);
242		if (outdata == NULL) {
243			error = ENOMEM;
244			goto bad;
245		}
246	}
247	switch (id) {
248		case DFS_SET_THRESH:
249			if (insize < sizeof(HAL_PHYERR_PARAM)) {
250				error = EINVAL;
251				break;
252			}
253			pe = (HAL_PHYERR_PARAM *) indata;
254			ath_hal_enabledfs(sc->sc_ah, pe);
255			break;
256		case DFS_GET_THRESH:
257			memset(&peout, 0, sizeof(peout));
258			outsize = sizeof(HAL_PHYERR_PARAM);
259			ath_hal_getdfsthresh(sc->sc_ah, &peout);
260			pe = (HAL_PHYERR_PARAM *) outdata;
261			memcpy(pe, &peout, sizeof(*pe));
262			break;
263		default:
264			error = EINVAL;
265	}
266	if (outsize < ad->ad_out_size)
267		ad->ad_out_size = outsize;
268	if (outdata && copyout(outdata, ad->ad_out_data, ad->ad_out_size))
269		error = EFAULT;
270bad:
271	if ((ad->ad_id & ATH_DIAG_IN) && indata != NULL)
272		free(indata, M_TEMP);
273	if ((ad->ad_id & ATH_DIAG_DYN) && outdata != NULL)
274		free(outdata, M_TEMP);
275	return error;
276}
277
278/*
279 * Get the current DFS thresholds from the HAL
280 */
281int
282ath_dfs_get_thresholds(struct ath_softc *sc, HAL_PHYERR_PARAM *param)
283{
284	ath_hal_getdfsthresh(sc->sc_ah, param);
285	return 1;
286}
287