summaryrefslogtreecommitdiffstats
path: root/sys/dev/ray/if_rayvar.h
blob: 0f9ed5c830c65b38cf5f7e0204df189051734b5a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
/*
 * Copyright (C) 2000
 * Dr. Duncan McLennan Barclay, dmlb@ragnet.demon.co.uk.
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the author nor the names of any co-contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY DUNCAN BARCLAY AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL DUNCAN BARCLAY OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD$
 *
 */

/*
 * Network parameters, used twice in softc to store what we want and what
 * we have.
 *
 * The current parameters are ONLY valid in a function called from the runq
 * and should not be accessed directly from ioctls.
 */
struct ray_nw_param {
    struct ray_cmd_net	p_1;
    struct ray_net_params \
    			p_2;
    u_int8_t		np_ap_status;
    int			np_promisc;	/* Promiscious mode status	*/
    int			np_framing;	/* Packet framing types		*/
    int			np_auth;	/* Authentication status	*/
    int			np_havenet;	/* True if we have a network	*/
};
#define np_upd_param	p_1.c_upd_param
#define	np_bss_id	p_1.c_bss_id
#define	np_inited	p_1.c_inited
#define	np_def_txrate	p_1.c_def_txrate
#define	np_encrypt	p_1.c_encrypt
#define np_net_type	p_2.p_net_type
#define np_ssid		p_2.p_ssid
#define np_priv_start	p_2.p_privacy_must_start
#define np_priv_join	p_2.p_privacy_can_join

/*
 * One of these structures per allocated device
 */
struct ray_softc {

    device_t dev;			/* Device */
    struct arpcom	arpcom;		/* Ethernet common 		*/
    struct callout_handle
    			tx_timerh;	/* Handle for tx timer	*/
    struct callout_handle
    			com_timerh;	/* Handle for command timer	*/

    bus_space_tag_t	am_bst;		/* Bus space tag for attribute memory */
    bus_space_handle_t	am_bsh;		/* Bus space handle for attribute mem */
    int			am_rid;		/* Resource id for attribute memory */
    struct resource*	am_res;		/* Resource for attribute memory */
    bus_space_tag_t	cm_bst;		/* Bus space tag for common memory */
    bus_space_handle_t	cm_bsh;		/* Bus space handle for common memory */
    int			cm_rid;		/* Resource id for common memory */
    struct resource*	cm_res;		/* Resource for common memory */
    int			irq_rid;	/* Resource id for irq */
    struct resource*	irq_res;	/* Resource for irq */
    void *		irq_handle;	/* Handle for irq handler */

    u_int8_t		sc_ccsinuse[64];/* ccss' in use -- not for tx	*/
    u_char		sc_gone;	/* 1 = Card bailed out		*/

    struct ray_ecf_startup_v5
    			sc_ecf_startup; /* Startup info from card	*/

    TAILQ_HEAD(ray_comq, ray_comq_entry) 
			sc_comq;	/* Command queue		*/

    struct ray_nw_param	sc_c;		/* current network params 	*/
    struct ray_nw_param sc_d;		/* desired network params	*/

    int			sc_checkcounters;
    u_int64_t		sc_rxoverflow;	/* Number of rx overflows	*/
    u_int64_t		sc_rxcksum;	/* Number of checksum errors	*/
    u_int64_t		sc_rxhcksum;	/* Number of header checksum errors */
    u_int8_t		sc_rxnoise;	/* Average receiver level	*/
    struct ray_siglev	sc_siglevs[RAY_NSIGLEVRECS]; /* Antenna/levels	*/
};

#define	sc_station_addr	sc_ecf_startup.e_station_addr
#define	sc_version	sc_ecf_startup.e_fw_build_string
#define	sc_tibsize	sc_ecf_startup.e_tibsize

/*
 * Command queue definitions
 */
typedef void (*ray_comqfn_t)(struct ray_softc *sc, struct ray_comq_entry *com);
MALLOC_DECLARE(M_RAYCOM);
MALLOC_DEFINE(M_RAYCOM, "raycom", "Raylink command queue entry");
struct ray_comq_entry {
	TAILQ_ENTRY(ray_comq_entry) c_chain;	/* Tail queue.		*/
	ray_comqfn_t	c_function;		/* Function to call */
	int		c_flags;		/* Flags		*/
	u_int8_t	c_retval;		/* Return value		*/
	void		*c_wakeup;		/* Sleeping on this	*/
	size_t		c_ccs;			/* CCS structure	*/
	struct ray_nw_param
			c_desired;		/* network settings	*/
	struct ray_param_req
    			*c_pr;			/* MIB report/update	*/
	char		*c_mesg;
};

/*
 * Macro's and constants
 */
static int mib_info[RAY_MIB_MAX+1][3] = RAY_MIB_INFO;

/* Indirections for reading/writing memory - from NetBSD/if_ray.c */
#ifndef offsetof
#define offsetof(type, member) \
    ((size_t)(&((type *)0)->member))
#endif /* offsetof */

#define ATTR_READ_1(sc, off) \
    ((u_int8_t)bus_space_read_1((sc)->am_bst, (sc)->am_bsh, (off)))

#define ATTR_WRITE_1(sc, off, val) \
    bus_space_write_1((sc)->am_bst, (sc)->am_bsh, (off), (val))

#define	SRAM_READ_1(sc, off) \
    ((u_int8_t)bus_space_read_1((sc)->cm_bst, (sc)->cm_bsh, (off)))

#define SRAM_READ_REGION(sc, off, p, n) \
    bus_space_read_region_1((sc)->cm_bst, (sc)->cm_bsh, (off), (void *)(p), (n))

#define	SRAM_READ_FIELD_1(sc, off, s, f) \
    SRAM_READ_1((sc), (off) + offsetof(struct s, f))

#define	SRAM_READ_FIELD_2(sc, off, s, f)			\
    ((((u_int16_t)SRAM_READ_1((sc), (off) + offsetof(struct s, f)) << 8) \
    |(SRAM_READ_1((sc), (off) + 1 + offsetof(struct s, f)))))

#define	SRAM_READ_FIELD_N(sc, off, s, f, p, n)	\
    SRAM_READ_REGION((sc), (off) + offsetof(struct s, f), (p), (n))

#define	SRAM_WRITE_1(sc, off, val)	\
    bus_space_write_1((sc)->cm_bst, (sc)->cm_bsh, (off), (val))

#define SRAM_WRITE_REGION(sc, off, p, n) \
    bus_space_write_region_1((sc)->cm_bst, (sc)->cm_bsh, (off), (void *)(p), (n))

#define	SRAM_WRITE_FIELD_1(sc, off, s, f, v) 	\
    SRAM_WRITE_1((sc), (off) + offsetof(struct s, f), (v))

#define	SRAM_WRITE_FIELD_2(sc, off, s, f, v) do {	\
    SRAM_WRITE_1((sc), (off) + offsetof(struct s, f), (((v) >> 8 ) & 0xff)); \
    SRAM_WRITE_1((sc), (off) + 1 + offsetof(struct s, f), ((v) & 0xff)); \
} while (0)

#define	SRAM_WRITE_FIELD_N(sc, off, s, f, p, n)	\
    SRAM_WRITE_REGION((sc), (off) + offsetof(struct s, f), (p), (n))

/* Framing types */
/* XXX maybe better as part of the if structure? */
#define RAY_FRAMING_ENCAPSULATION	0
#define RAY_FRAMING_TRANSLATION		1

/* Authentication states */
#define RAY_AUTH_UNAUTH		0
#define RAY_AUTH_WAITING	1
#define RAY_AUTH_AUTH		2
#define RAY_AUTH_NEEDED		3

/* Flags for runq entries */
#define RAY_COM_FWOK		0x0001		/* Wakeup on completion	*/
#define RAY_COM_FRUNNING	0x0002		/* This one running	*/
#define RAY_COM_FCOMPLETED	0x0004		/* This one completed	*/
#define RAY_COM_FWAIT		0x0008		/* Do not run the queue */
#define RAY_COM_FCHKRUNNING	0x0010		/* Check IFF_RUNNING	*/
#define RAY_COM_FDETACHED	0x0020		/* Card is gone		*/
#define RAY_COM_FWOKEN		0x0040		/* Woken by detach	*/
#define RAY_COM_FLAGS_PRINTFB	\
	"\020"			\
	"\001WOK"		\
	"\002RUNNING"		\
	"\003COMPLETED"		\
	"\004WAIT"		\
	"\005CHKRUNNING"	\
	"\006DETACHED"

#define RAY_COM_NEEDS_TIMO(cmd)	(		\
	 (cmd == RAY_CMD_DOWNLOAD_PARAMS) ||	\
	 (cmd == RAY_CMD_UPDATE_PARAMS) ||	\
	 (cmd == RAY_CMD_UPDATE_MCAST)		\
	)

#ifndef RAY_COM_TIMEOUT
#define RAY_COM_TIMEOUT		(hz / 2)
#endif

#ifndef RAY_RESET_TIMEOUT
#define RAY_RESET_TIMEOUT	(10 * hz)
#endif

#ifndef RAY_TX_TIMEOUT
#define RAY_TX_TIMEOUT		(hz / 2)
#endif

#define RAY_CCS_FREE(sc, ccs) \
    SRAM_WRITE_FIELD_1((sc), (ccs), ray_cmd, c_status, RAY_CCS_STATUS_FREE)

#define RAY_ECF_READY(sc) \
    (!(ATTR_READ_1((sc), RAY_ECFIR) & RAY_ECFIR_IRQ))

#define	RAY_ECF_START_CMD(sc)	ATTR_WRITE_1((sc), RAY_ECFIR, RAY_ECFIR_IRQ)

#define	RAY_HCS_CLEAR_INTR(sc)	ATTR_WRITE_1((sc), RAY_HCSIR, 0)

#define RAY_HCS_INTR(sc)	(ATTR_READ_1((sc), RAY_HCSIR) & RAY_HCSIR_IRQ)

#define RAY_PANIC(sc, fmt, args...) do {				\
    panic("ray%d: %s(%d) " fmt "\n", device_get_unit((sc)->dev),	\
	__func__ , __LINE__ , ##args);					\
} while (0)

#define RAY_PRINTF(sc, fmt, args...) do {				\
    device_printf((sc)->dev, "%s(%d) " fmt "\n",			\
        __func__ , __LINE__ , ##args);					\
} while (0)

#define RAY_COM_MALLOC(function, flags)	\
    ray_com_malloc((function), (flags), __STRING(function));

#define RAY_COM_FREE(com, ncom)	do {					\
    int i;								\
    for (i = 0; i < ncom; i++)						\
	    FREE(com[i], M_RAYCOM);					\
} while (0)

/*
 * This macro handles adding commands to the runq and quickly
 * getting away when the card is detached. The macro returns
 * from the current function with ENXIO.
 */
#define RAY_COM_RUNQ(sc, com, ncom, mesg, error) do {			\
    (error) = ray_com_runq_add((sc), (com), (ncom), (mesg));		\
    if ((error) == ENXIO) {						\
	    RAY_COM_FREE((com), (ncom));				\
	    return (error);						\
    } else if ((error) && ((error) != ENXIO))				\
	    RAY_PRINTF(sc, "got error from runq 0x%x", (error));	\
} while (0)

/*
 * There are a number of entry points into the ray_init_xxx routines.
 * These can be classed into two types: a) those that happen as a result
 * of a change to the cards operating parameters (e.g. BSSID change), and
 * b) those that happen as a result of a change to the interface parameters
 * (e.g. a change to the IP address). The second set of entries need not
 * send a command to the card when the card is IFF_RUNNING. The
 * RAY_COM_FCHKRUNNING flags indicates when the RUNNING flag should be
 * checked, and this macro does the necessary check and command abort.
 */
#define RAY_COM_CHKRUNNING(sc, com, ifp) do {				\
    if (((com)->c_flags & RAY_COM_FCHKRUNNING) &&			\
	((ifp)->if_flags & IFF_RUNNING)) {				\
	    ray_com_runq_done(sc);					\
	    return;							\
} } while (0)
    
    

#define RAY_COM_INIT(com, function, flags)	\
    ray_com_init((com), (function), (flags), __STRING(function));

#ifndef RAY_COM_CHECK
#define RAY_COM_CHECK(sc, com)
#endif /* RAY_COM_CHECK */

#ifndef RAY_MBUF_DUMP
#define RAY_MBUF_DUMP(sc, mask, m, s)
#endif /* RAY_MBUF_DUMP */

#ifndef RAY_RECERR
#define RAY_RECERR(sc, fmt, args...) do {				\
    struct ifnet *ifp = &(sc)->arpcom.ac_if;				\
    if (ifp->if_flags & IFF_DEBUG) {					\
	    device_printf((sc)->dev, "%s(%d) " fmt "\n",		\
		__func__ , __LINE__ , ##args);				\
} } while (0)
#endif /* RAY_RECERR */

/* XXX this should be in CCSERR but don't work - probably need to use ##ifp->(iferrcounter)++;						\*/
#ifndef RAY_CCSERR
#define RAY_CCSERR(sc, status, iferrcounter) do {			\
    struct ifnet *ifp = &(sc)->arpcom.ac_if;				\
    char *ss[] = RAY_CCS_STATUS_STRINGS;				\
    if ((status) != RAY_CCS_STATUS_COMPLETE) {				\
	if (ifp->if_flags & IFF_DEBUG) {				\
	    device_printf((sc)->dev,					\
	        "%s(%d) ECF command completed with status %s\n",	\
		__func__ , __LINE__ , ss[(status)]);			\
} } } while (0)
#endif /* RAY_CCSERR */

#ifndef RAY_MAP_CM
#define RAY_MAP_CM(sc)
#endif /* RAY_MAP_CM */

/*
 * Management information element payloads
 */
union ieee80211_information {
	char	ssid[IEEE80211_NWID_LEN+1];
	struct rates {
		u_int8_t	*p;
	} rates;
	struct fh {
		u_int16_t	dwell;
		u_int8_t	set;
		u_int8_t	pattern;
		u_int8_t	index;
	} fh;
	struct ds {
		u_int8_t	channel;
	} ds;
	struct cf {
		u_int8_t	count;
		u_int8_t	period;
		u_int8_t	maxdur[2];
		u_int8_t	dur[2];
	} cf;
	struct tim {
		u_int8_t	count;
		u_int8_t	period;
		u_int8_t	bitctl;
		/* u_int8_t	pvt[251]; The driver needs to use this. */
	} tim;
	struct ibss {
		u_int16_t	atim;
	} ibss;
	struct challenge {
		u_int8_t	*p;
		u_int8_t	len;
	} challenge;
};
OpenPOWER on IntegriCloud