2 * QEMU WLAN device emulation
4 * Copyright (c) 2008 Clemens Kolbitsch
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 * 2008-February-24 Clemens Kolbitsch :
26 * New implementation based on ne2000.c
30 #ifndef atheros_wlan_h
31 #define atheros_wlan_h 1
35 #include <sys/socket.h>
39 #include <netinet/in.h>
44 * debug Atheros_WLAN card
46 * i.e. show all access traces
48 // #define DEBUG_Atheros_WLAN 1
49 // #define DEBUG_Atheros_AP_WLAN 1
51 #define PCI_FREQUENCY 33000000L
53 #if defined (DEBUG_Atheros_WLAN)
54 # define DEBUG_PRINT(x) \
56 struct timeval __tt; \
57 gettimeofday(&__tt, NULL); \
58 printf("%u:%u ", (unsigned)__tt.tv_sec, (unsigned)__tt.tv_usec); \
62 # define DEBUG_PRINT(x)
65 #if defined (DEBUG_Atheros_AP_WLAN)
66 # define DEBUG_PRINT_AP(x) printf x ;
68 # define DEBUG_PRINT_AP(x)
74 * The madwifi driver crashes if too
75 * many frames are in the receive
78 * This can happen when interrupts are
79 * not picked up right away (what can
80 * happen due to qemu's lazy interrupt
81 * checking/handling)!!
83 * UPDATE: BinaryHAL suddenly seems to
84 * work with the WINDOWS_RX_FRAME as well
85 * which is even better (because more frames
86 * may be received concurrently...)
88 #define MAX_CONCURRENT_RX_FRAMES_WINDOWS_OR_OPEN_HAL 999
89 #define MAX_CONCURRENT_RX_FRAMES_BINARY_HAL 10
90 #define MAX_CONCURRENT_RX_FRAMES MAX_CONCURRENT_RX_FRAMES_WINDOWS_OR_OPEN_HAL
93 * In case we are connecting with a windows guest OS
94 * (or the ndiswrapper of the windows driver) we must
95 * define this macro... otherwise no packets will be
98 * If connecting with a linux guest/madwifi with the
99 * macro defined it won't work on the other hand!!!
101 #define WINXP_DRIVER 1
102 #define LINUX_DRIVER 2
104 #define PCI_CONFIG_AR5212 1
105 #define PCI_CONFIG_AR5424 2
111 #define IEEE80211_IDLE 0xff
113 #define IEEE80211_TYPE_MGT 0x00
114 #define IEEE80211_TYPE_CTL 0x01
115 #define IEEE80211_TYPE_DATA 0x02
117 #define IEEE80211_TYPE_MGT_SUBTYPE_BEACON 0x08
118 #define IEEE80211_TYPE_MGT_SUBTYPE_ACTION 0x0d
119 #define IEEE80211_TYPE_MGT_SUBTYPE_PROBE_REQ 0x04
120 #define IEEE80211_TYPE_MGT_SUBTYPE_PROBE_RESP 0x05
121 #define IEEE80211_TYPE_MGT_SUBTYPE_AUTHENTICATION 0x0b
122 #define IEEE80211_TYPE_MGT_SUBTYPE_DEAUTHENTICATION 0x0c
123 #define IEEE80211_TYPE_MGT_SUBTYPE_ASSOCIATION_REQ 0x00
124 #define IEEE80211_TYPE_MGT_SUBTYPE_ASSOCIATION_RESP 0x01
125 #define IEEE80211_TYPE_MGT_SUBTYPE_DISASSOCIATION 0x09
127 #define IEEE80211_TYPE_CTL_SUBTYPE_ACK 0x0d
129 #define IEEE80211_TYPE_DATA_SUBTYPE_DATA 0x00
132 #define IEEE80211_BEACON_PARAM_SSID 0x00
133 #define IEEE80211_BEACON_PARAM_SSID_STRING "\x00"
134 #define IEEE80211_BEACON_PARAM_RATES 0x01
135 #define IEEE80211_BEACON_PARAM_RATES_STRING "\x01"
136 #define IEEE80211_BEACON_PARAM_CHANNEL 0x03
137 #define IEEE80211_BEACON_PARAM_CHANNEL_STRING "\x03"
138 #define IEEE80211_BEACON_PARAM_EXTENDED_RATES 0x32
139 #define IEEE80211_BEACON_PARAM_EXTENDED_RATES_STRING "\x32"
146 #define IEEE80211_CHANNEL1_FREQUENCY 2412
147 #define IEEE80211_CHANNEL2_FREQUENCY 2417
148 #define IEEE80211_CHANNEL3_FREQUENCY 2422
149 #define IEEE80211_CHANNEL4_FREQUENCY 2427
150 #define IEEE80211_CHANNEL5_FREQUENCY 2432
151 #define IEEE80211_CHANNEL6_FREQUENCY 2437
152 #define IEEE80211_CHANNEL7_FREQUENCY 2442
153 #define IEEE80211_CHANNEL8_FREQUENCY 2447
154 #define IEEE80211_CHANNEL9_FREQUENCY 2452
155 #define IEEE80211_CHANNEL10_FREQUENCY 2457
156 #define IEEE80211_CHANNEL11_FREQUENCY 2462
159 #define IEEE80211_HEADER_SIZE 24
161 typedef struct mac80211_frame
{
162 struct mac80211_frame_control
{
163 unsigned protocol_version
: 2;
165 unsigned sub_type
: 4;
168 struct mac80211_frame_control_flags
{
170 unsigned from_ds
: 1;
171 unsigned more_frag
: 1;
173 unsigned power_mng
: 1;
174 unsigned more_data
: 1;
177 } __attribute__((packed
)) frame_control_flags
;
181 } __attribute__((packed
)) frame_control
;
182 uint16_t duration_id
;
185 uint8_t address_1
[6];
186 uint8_t destination_address
[6];
190 uint8_t address_2
[6];
191 uint8_t source_address
[6];
195 uint8_t address_3
[6];
196 uint8_t bssid_address
[6];
199 struct mac80211_sequence_control
{
200 unsigned fragment_number
: 4;
201 unsigned sequence_number
: 12;
202 } __attribute__((packed
)) sequence_control
;
204 // WHEN IS THIS USED??
205 // uint8_t address_4[6];
207 // variable length, 2312 byte plus 4 byte frame-checksum
208 uint8_t data_and_fcs
[2316];
210 unsigned int frame_length
;
211 struct mac80211_frame
*next_frame
;
213 } QEMU_PACKED mac80211_frame
;
216 #define GET_MEM_L(_mem, _addr) _mem[_addr >> 2]
217 #define SET_MEM_L(_mem, _addr, _val) _mem[_addr >> 2] = _val
219 #define WRITE_EEPROM(_mem, _val) \
220 SET_MEM_L(_mem, AR5K_EEPROM_DATA_5210, _val); \
221 SET_MEM_L(_mem, AR5K_EEPROM_DATA_5211, _val);
226 #define Atheros_WLAN_PCI_REVID_ATHEROS 0x01
227 #define Atheros_WLAN_PCI_REVID Atheros_WLAN_PCI_REVID_ATHEROS
231 #define Atheros_WLAN_MEM_SIZE (64 * KiB)
232 #define Atheros_WLAN_MEM_SANITIZE(x) (x & (Atheros_WLAN_MEM_SIZE - 1))
234 #define Atheros_WLAN__STATE_NOT_AUTHENTICATED 0
235 #define Atheros_WLAN__STATE_AUTHENTICATED 1
236 #define Atheros_WLAN__STATE_ASSOCIATED 2
239 #define Atheros_WLAN__MAX_INJECT_QUEUE_SIZE 20
243 * We use a semaphore to make sure
244 * that accessing the linked lists
245 * inside the state is done atomically
247 #define ATHEROS_WLAN_ACCESS_SEM_KEY 20071
251 * AR521X uses a very complicated algorithm to
252 * express current channel... too lazy to understand
253 * it... just use a matrix :-)
255 * ATTENTION: This matrix is valid only for little-endian
256 * as the algorithm uses bitswapping
258 * NOTE: Maybe, bitswapping also takes care of this and
259 * big-endian values thus correspond with this matrix, but
260 * I just don't care ;-)
262 struct Atheros_WLAN_frequency
{
268 struct pending_interrupt
{
270 struct pending_interrupt
*next
;
273 typedef struct Atheros_WLANState
{
275 MemoryRegion mmio_bar
;
277 uint32_t device_driver_type
;
282 uint8_t ipaddr
[4]; // currently unused
283 uint8_t macaddr
[6]; // mac address
285 uint8_t ap_ipaddr
[4]; // currently unused
286 uint8_t ap_macaddr
[6]; // mac address
290 uint32_t interrupt_p_mask
; // primary interrupt mask
291 uint32_t interrupt_s_mask
[5]; // secondary interrupt masks
292 uint8_t interrupt_enabled
;
293 struct pending_interrupt
*pending_interrupts
;
294 int access_semaphore
;
296 uint32_t current_frequency_partial_data
[2];
297 uint32_t current_frequency
;
300 hwaddr receive_queue_address
;
301 uint32_t receive_queue_count
;
303 uint32_t transmit_queue_size
;
304 uint8_t transmit_queue_enabled
[16];
305 hwaddr transmit_queue_address
[16];
306 uint32_t transmit_queue_processed
[16];
308 uint32_t mem
[Atheros_WLAN_MEM_SIZE
/ 4];
311 uint32_t *eeprom_data
;
314 int inject_timer_running
;
315 unsigned int inject_sequence_number
;
318 QEMUTimer
*beacon_timer
;
319 QEMUTimer
*inject_timer
;
321 int inject_queue_size
;
322 struct mac80211_frame
*inject_queue
;
327 /***********************************************************/
328 /* PCI Atheros_WLAN definitions */
330 typedef struct PCIAtheros_WLANState
{
332 Atheros_WLANState Atheros_WLAN
;
333 } PCIAtheros_WLANState
;
336 #endif // atheros_wlan_h