1
2/*-
3 * Copyright (c) 2005, 2006 Damien Bergamini <damien.bergamini@free.fr>
4 * Copyright (c) 2006 Niall O'Higgins <niallo@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#define RUM_TX_LIST_COUNT	8
20#define RUM_TX_MINFREE		2
21
22struct rum_rx_radiotap_header {
23	struct ieee80211_radiotap_header wr_ihdr;
24	uint64_t	wr_tsf;
25	uint8_t		wr_flags;
26	uint8_t		wr_rate;
27	uint16_t	wr_chan_freq;
28	uint16_t	wr_chan_flags;
29	int8_t		wr_antsignal;
30	int8_t		wr_antnoise;
31	uint8_t		wr_antenna;
32} __packed __aligned(8);
33
34#define RT2573_RX_RADIOTAP_PRESENT					\
35	((1 << IEEE80211_RADIOTAP_TSFT) |				\
36	 (1 << IEEE80211_RADIOTAP_FLAGS) |				\
37	 (1 << IEEE80211_RADIOTAP_RATE) |				\
38	 (1 << IEEE80211_RADIOTAP_CHANNEL) |				\
39	 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |			\
40	 (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) |			\
41	 (1 << IEEE80211_RADIOTAP_ANTENNA) |				\
42	 0)
43
44struct rum_tx_radiotap_header {
45	struct ieee80211_radiotap_header wt_ihdr;
46	uint8_t		wt_flags;
47	uint8_t		wt_rate;
48	uint16_t	wt_chan_freq;
49	uint16_t	wt_chan_flags;
50	uint8_t		wt_antenna;
51} __packed;
52
53#define RT2573_TX_RADIOTAP_PRESENT					\
54	((1 << IEEE80211_RADIOTAP_FLAGS) |				\
55	 (1 << IEEE80211_RADIOTAP_RATE) |				\
56	 (1 << IEEE80211_RADIOTAP_CHANNEL) |				\
57	 (1 << IEEE80211_RADIOTAP_ANTENNA))
58
59struct rum_softc;
60
61struct rum_tx_data {
62	STAILQ_ENTRY(rum_tx_data)	next;
63	struct rum_softc		*sc;
64	struct rum_tx_desc		desc;
65	struct mbuf			*m;
66	struct ieee80211_node		*ni;
67	int				rate;
68};
69typedef STAILQ_HEAD(, rum_tx_data) rum_txdhead;
70
71union sec_param {
72	struct ieee80211_key		key;
73	uint8_t				macaddr[IEEE80211_ADDR_LEN];
74	struct ieee80211vap		*vap;
75};
76#define CMD_FUNC_PROTO			void (*func)(struct rum_softc *, \
77					    union sec_param *, uint8_t)
78
79struct rum_cmdq {
80	union sec_param			data;
81	uint8_t				rvp_id;
82
83	CMD_FUNC_PROTO;
84};
85#define RUM_CMDQ_SIZE			16
86
87struct rum_vap {
88	struct ieee80211vap		vap;
89	struct mbuf			*bcn_mbuf;
90	struct usb_callout		ratectl_ch;
91	struct task			ratectl_task;
92	uint8_t				maxretry;
93
94	int				(*newstate)(struct ieee80211vap *,
95					    enum ieee80211_state, int);
96	void				(*bmiss)(struct ieee80211vap *);
97	void				(*recv_mgmt)(struct ieee80211_node *,
98					    struct mbuf *, int,
99					    const struct ieee80211_rx_stats *,
100					    int, int);
101};
102#define	RUM_VAP(vap)	((struct rum_vap *)(vap))
103
104enum {
105	RUM_BULK_WR,
106	RUM_BULK_RD,
107	RUM_N_TRANSFER = 2,
108};
109
110struct rum_softc {
111	struct ieee80211com		sc_ic;
112	struct ieee80211_ratectl_tx_stats sc_txs;
113	struct mbufq			sc_snd;
114	device_t			sc_dev;
115	struct usb_device		*sc_udev;
116
117	struct usb_xfer			*sc_xfer[RUM_N_TRANSFER];
118
119	uint8_t				rf_rev;
120	uint8_t				rffreq;
121
122	struct rum_tx_data		tx_data[RUM_TX_LIST_COUNT];
123	rum_txdhead			tx_q;
124	rum_txdhead			tx_free;
125	int				tx_nfree;
126	struct rum_rx_desc		sc_rx_desc;
127
128	struct mtx			sc_mtx;
129
130	int				sc_sleep_end;
131	int				sc_sleep_time;
132	uint8_t				last_rx_flags;
133
134	struct rum_cmdq			cmdq[RUM_CMDQ_SIZE];
135	struct mtx			cmdq_mtx;
136	struct task			cmdq_task;
137	uint8_t				cmdq_first;
138	uint8_t				cmdq_last;
139
140	uint32_t			sta[6];
141	uint32_t			rf_regs[4];
142	uint8_t				txpow[44];
143	u_int				sc_detached:1,
144					sc_running:1,
145					sc_sleeping:1,
146					sc_clr_shkeys:1;
147
148	uint8_t				sc_bssid[IEEE80211_ADDR_LEN];
149	struct wmeParams		wme_params[WME_NUM_AC];
150
151	uint8_t				vap_key_count[1];
152	uint64_t			keys_bmap;
153
154	struct {
155		uint8_t	val;
156		uint8_t	reg;
157	} __packed			bbp_prom[16];
158
159	int				hw_radio;
160	int				rx_ant;
161	int				tx_ant;
162	int				nb_ant;
163	int				ext_2ghz_lna;
164	int				ext_5ghz_lna;
165	int				rssi_2ghz_corr;
166	int				rssi_5ghz_corr;
167	uint8_t				bbp17;
168
169	struct rum_rx_radiotap_header	sc_rxtap;
170	struct rum_tx_radiotap_header	sc_txtap;
171};
172
173#define RUM_LOCK_INIT(sc) \
174	mtx_init(&(sc)->sc_mtx, device_get_nameunit((sc)->sc_dev), \
175	    MTX_NETWORK_LOCK, MTX_DEF);
176#define RUM_LOCK(sc)			mtx_lock(&(sc)->sc_mtx)
177#define RUM_UNLOCK(sc)			mtx_unlock(&(sc)->sc_mtx)
178#define RUM_LOCK_ASSERT(sc)		mtx_assert(&(sc)->sc_mtx, MA_OWNED)
179#define RUM_LOCK_DESTROY(sc)		mtx_destroy(&(sc)->sc_mtx)
180
181#define RUM_CMDQ_LOCK_INIT(sc) \
182	mtx_init(&(sc)->cmdq_mtx, "cmdq lock", NULL, MTX_DEF)
183#define RUM_CMDQ_LOCK(sc)		mtx_lock(&(sc)->cmdq_mtx)
184#define RUM_CMDQ_UNLOCK(sc)		mtx_unlock(&(sc)->cmdq_mtx)
185#define RUM_CMDQ_LOCK_DESTROY(sc)	mtx_destroy(&(sc)->cmdq_mtx)
186