FreeBSD kernel ATH device code
if_ath_spectral.c
Go to the documentation of this file.
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2013 Adrian Chadd <adrian@FreeBSD.org>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer,
12 * without modification.
13 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
14 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
15 * redistribution must be conditioned upon including a substantially
16 * similar Disclaimer requirement for further binary redistribution.
17 *
18 * NO WARRANTY
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
22 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
23 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
24 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
27 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
29 * THE POSSIBILITY OF SUCH DAMAGES.
30 *
31 * $FreeBSD$
32 */
33#include <sys/cdefs.h>
34__FBSDID("$FreeBSD$");
35
36/*
37 * Implement some basic spectral scan control logic.
38 */
39#include "opt_ath.h"
40#include "opt_inet.h"
41#include "opt_wlan.h"
42
43#include <sys/param.h>
44#include <sys/systm.h>
45#include <sys/sysctl.h>
46#include <sys/kernel.h>
47#include <sys/lock.h>
48#include <sys/malloc.h>
49#include <sys/mutex.h>
50#include <sys/errno.h>
51
52#include <machine/bus.h>
53#include <machine/resource.h>
54#include <sys/bus.h>
55
56#include <sys/socket.h>
57
58#include <net/if.h>
59#include <net/if_var.h>
60#include <net/if_media.h>
61#include <net/if_arp.h>
62#include <net/ethernet.h> /* XXX for ether_sprintf */
63
64#include <net80211/ieee80211_var.h>
65
66#include <net/bpf.h>
67
68#ifdef INET
69#include <netinet/in.h>
70#include <netinet/if_ether.h>
71#endif
72
73#include <dev/ath/if_athvar.h>
75#include <dev/ath/if_ath_misc.h>
76
78
81
82 /*
83 * Should we enable spectral scan upon
84 * each network interface reset/change?
85 *
86 * This is intended to allow spectral scan
87 * frame reporting during channel scans.
88 *
89 * Later on it can morph into a larger
90 * scale config method where it pushes
91 * a "channel scan" config into the hardware
92 * rather than just the spectral_state
93 * config.
94 */
96};
97
98/*
99 * Methods which are required
100 */
101
102/*
103 * Attach spectral to the given interface
104 */
105int
107{
108 struct ath_spectral_state *ss;
109
110 /*
111 * If spectral isn't supported, don't error - just
112 * quietly complete.
113 */
115 return (0);
116
117 ss = malloc(sizeof(struct ath_spectral_state),
118 M_TEMP, M_WAITOK | M_ZERO);
119
120 if (ss == NULL) {
121 device_printf(sc->sc_dev, "%s: failed to alloc memory\n",
122 __func__);
123 return (-ENOMEM);
124 }
125
126 sc->sc_spectral = ss;
127
129
130 return (0);
131}
132
133/*
134 * Detach spectral from the given interface
135 */
136int
138{
139
141 return (0);
142
143 if (sc->sc_spectral != NULL) {
144 free(sc->sc_spectral, M_TEMP);
145 }
146 return (0);
147}
148
149/*
150 * Check whether spectral needs enabling and if so,
151 * flip it on.
152 */
153int
154ath_spectral_enable(struct ath_softc *sc, struct ieee80211_channel *ch)
155{
156 struct ath_spectral_state *ss = sc->sc_spectral;
157
158 /* Default to disable spectral PHY reporting */
159 sc->sc_dospectral = 0;
160
161 if (ss == NULL)
162 return (0);
163
166 &ss->spectral_state);
167 (void) ath_hal_spectral_start(sc->sc_ah);
168 sc->sc_dospectral = 1;
169 }
170 return (0);
171}
172
173/*
174 * Handle ioctl requests from the diagnostic interface.
175 *
176 * The initial part of this code resembles ath_ioctl_diag();
177 * it's likely a good idea to reduce duplication between
178 * these two routines.
179 */
180int
181ath_ioctl_spectral(struct ath_softc *sc, struct ath_diag *ad)
182{
183 unsigned int id = ad->ad_id & ATH_DIAG_ID;
184 void *indata = NULL;
185 void *outdata = NULL;
186 u_int32_t insize = ad->ad_in_size;
187 u_int32_t outsize = ad->ad_out_size;
188 int error = 0;
189 HAL_SPECTRAL_PARAM peout;
191 struct ath_spectral_state *ss = sc->sc_spectral;
192 int val;
193
195 return (EINVAL);
196
197 ATH_LOCK(sc);
199 ATH_UNLOCK(sc);
200
201 if (ad->ad_id & ATH_DIAG_IN) {
202 /*
203 * Copy in data.
204 */
205 indata = malloc(insize, M_TEMP, M_NOWAIT);
206 if (indata == NULL) {
207 error = ENOMEM;
208 goto bad;
209 }
210 error = copyin(ad->ad_in_data, indata, insize);
211 if (error)
212 goto bad;
213 }
214 if (ad->ad_id & ATH_DIAG_DYN) {
215 /*
216 * Allocate a buffer for the results (otherwise the HAL
217 * returns a pointer to a buffer where we can read the
218 * results). Note that we depend on the HAL leaving this
219 * pointer for us to use below in reclaiming the buffer;
220 * may want to be more defensive.
221 */
222 outdata = malloc(outsize, M_TEMP, M_NOWAIT | M_ZERO);
223 if (outdata == NULL) {
224 error = ENOMEM;
225 goto bad;
226 }
227 }
228 switch (id) {
230 memset(&peout, 0, sizeof(peout));
231 outsize = sizeof(HAL_SPECTRAL_PARAM);
233 pe = (HAL_SPECTRAL_PARAM *) outdata;
234 memcpy(pe, &peout, sizeof(*pe));
235 break;
237 if (insize < sizeof(HAL_SPECTRAL_PARAM)) {
238 error = EINVAL;
239 break;
240 }
241 pe = (HAL_SPECTRAL_PARAM *) indata;
243 /* Save a local copy of the updated parameters */
245 &ss->spectral_state);
246 break;
249 &ss->spectral_state);
250 (void) ath_hal_spectral_start(sc->sc_ah);
251 sc->sc_dospectral = 1;
252 /* XXX need to update the PHY mask in the driver */
253 break;
255 (void) ath_hal_spectral_stop(sc->sc_ah);
256 sc->sc_dospectral = 0;
257 /* XXX need to update the PHY mask in the driver */
258 break;
260 if (insize < sizeof(int)) {
261 device_printf(sc->sc_dev, "%d != %d\n",
262 insize,
263 (int) sizeof(int));
264 error = EINVAL;
265 break;
266 }
267 if (indata == NULL) {
268 device_printf(sc->sc_dev, "indata=NULL\n");
269 error = EINVAL;
270 break;
271 }
272 val = * ((int *) indata);
273 if (val == 0)
275 else
277 break;
279 /* XXX TODO */
281 /* XXX TODO */
282 break;
283 default:
284 error = EINVAL;
285 goto bad;
286 }
287 if (outsize < ad->ad_out_size)
288 ad->ad_out_size = outsize;
289 if (outdata && copyout(outdata, ad->ad_out_data, ad->ad_out_size))
290 error = EFAULT;
291bad:
292 if ((ad->ad_id & ATH_DIAG_IN) && indata != NULL)
293 free(indata, M_TEMP);
294 if ((ad->ad_id & ATH_DIAG_DYN) && outdata != NULL)
295 free(outdata, M_TEMP);
296 ATH_LOCK(sc);
298 ATH_UNLOCK(sc);
299
300 return (error);
301}
@ HAL_PM_AWAKE
Definition: ah.h:440
#define ath_power_restore_power_state(sc)
Definition: if_ath_misc.h:131
#define ath_power_set_power_state(sc, ps)
Definition: if_ath_misc.h:129
int ath_spectral_enable(struct ath_softc *sc, struct ieee80211_channel *ch)
int ath_spectral_detach(struct ath_softc *sc)
int ath_spectral_attach(struct ath_softc *sc)
int ath_ioctl_spectral(struct ath_softc *sc, struct ath_diag *ad)
__FBSDID("$FreeBSD$")
#define ATH_DIAG_DYN
Definition: if_athioctl.h:191
#define ATH_DIAG_ID
Definition: if_athioctl.h:194
#define SPECTRAL_CONTROL_ENABLE
Definition: if_athioctl.h:451
#define SPECTRAL_CONTROL_DISABLE
Definition: if_athioctl.h:452
#define SPECTRAL_CONTROL_GET_PARAMS
Definition: if_athioctl.h:455
#define SPECTRAL_CONTROL_STOP
Definition: if_athioctl.h:454
#define SPECTRAL_CONTROL_START
Definition: if_athioctl.h:453
#define SPECTRAL_CONTROL_ENABLE_AT_RESET
Definition: if_athioctl.h:457
#define SPECTRAL_CONTROL_SET_PARAMS
Definition: if_athioctl.h:456
#define ATH_DIAG_IN
Definition: if_athioctl.h:192
#define ath_hal_spectral_get_config(_ah, _p)
Definition: if_athvar.h:1502
#define ath_hal_spectral_supported(_ah)
Definition: if_athvar.h:1500
#define ath_hal_spectral_configure(_ah, _p)
Definition: if_athvar.h:1504
#define ath_hal_spectral_start(_ah)
Definition: if_athvar.h:1506
#define ATH_LOCK(_sc)
Definition: if_athvar.h:938
#define ATH_UNLOCK(_sc)
Definition: if_athvar.h:939
#define ath_hal_spectral_stop(_ah)
Definition: if_athvar.h:1508
caddr_t ad_out_data
Definition: if_athioctl.h:197
u_int ad_out_size
Definition: if_athioctl.h:198
caddr_t ad_in_data
Definition: if_athioctl.h:196
u_int16_t ad_in_size
Definition: if_athioctl.h:195
u_int16_t ad_id
Definition: if_athioctl.h:190
device_t sc_dev
Definition: if_athvar.h:598
int sc_dospectral
Definition: if_athvar.h:876
void * sc_spectral
Definition: if_athvar.h:875
struct ath_hal * sc_ah
Definition: if_athvar.h:612
HAL_SPECTRAL_PARAM spectral_state