2 * QEMU WLAN access point 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 #include "qemu/osdep.h"
32 #if defined(CONFIG_WIN32)
33 #warning("not compiled for Windows host")
40 #include "qemu/timer.h"
43 #include <sys/socket.h>
47 #include <netinet/in.h>
53 * PCI and EEPROM definitions
55 #include "hw/atheros_wlan.h"
56 #include "hw/atheros_wlan_ap.h"
57 #include "hw/atheros_wlan_io.h"
58 #include "hw/atheros_wlan_packet.h"
61 * MadWifi OPENHAL atheros constants
63 #include "hw/ath5k_hw.h"
64 #include "hw/ath5kreg.h"
67 static int semaphore_helper(int semaphore
, int sem_op
, int semaphore_nr
, short flags
)
70 semp
.sem_num
= semaphore_nr
;
74 if (semaphore
== -1) {
76 * We don't have a semaphore... probably not
77 * that bad, but having one is better :-)
83 while ((ret
= semop(semaphore
, &semp
, 1)) < 0) {
84 if (errno
== EAGAIN
&& flags
== IPC_NOWAIT
) {
86 } else if (errno
!= EINTR
) {
87 fprintf(stderr
, "Semaphore error: 0x%x / %u\n", errno
, errno
);
96 static int signal_semaphore(int semaphore
, int semaphore_nr
)
98 return semaphore_helper(semaphore
, 1, semaphore_nr
, 0);
100 static int wait_semaphore(int semaphore
, int semaphore_nr
)
102 return semaphore_helper(semaphore
, -1, semaphore_nr
, 0);
105 void Atheros_WLAN_insert_frame(Atheros_WLANState
*s
, struct mac80211_frame
*frame
)
107 struct mac80211_frame
*i_frame
;
109 wait_semaphore(s
->access_semaphore
, 0);
111 s
->inject_queue_size
++;
112 i_frame
= s
->inject_queue
;
114 s
->inject_queue
= frame
;
116 while (i_frame
->next_frame
) {
117 i_frame
= i_frame
->next_frame
;
120 i_frame
->next_frame
= frame
;
123 if (!s
->inject_timer_running
) {
124 // if the injection timer is not
125 // running currently, let's schedule
127 s
->inject_timer_running
= 1;
128 timer_mod(s
->inject_timer
, qemu_clock_get_ns(QEMU_CLOCK_REALTIME
) + 5);
131 signal_semaphore(s
->access_semaphore
, 0);
134 static void Atheros_WLAN_beacon_timer(void *opaque
)
136 struct mac80211_frame
*frame
;
137 Atheros_WLANState
*s
= (Atheros_WLANState
*)opaque
;
139 frame
= Atheros_WLAN_create_beacon_frame();
141 Atheros_WLAN_init_frame(s
, frame
);
142 Atheros_WLAN_insert_frame(s
, frame
);
145 timer_mod(s
->beacon_timer
, qemu_clock_get_ns(QEMU_CLOCK_REALTIME
) + 500);
148 static void Atheros_WLAN_inject_timer(void *opaque
)
150 Atheros_WLANState
*s
= (Atheros_WLANState
*)opaque
;
151 struct mac80211_frame
*frame
;
153 wait_semaphore(s
->access_semaphore
, 0);
155 frame
= s
->inject_queue
;
158 s
->inject_queue_size
--;
159 s
->inject_queue
= frame
->next_frame
;
161 signal_semaphore(s
->access_semaphore
, 0);
167 if (s
->receive_queue_address
== 0) {
168 // we drop the packet
170 Atheros_WLAN_handleRxBuffer(s
, frame
, frame
->frame_length
);
176 wait_semaphore(s
->access_semaphore
, 0);
178 if (s
->inject_queue_size
> 0) {
179 // there are more packets... schedule
180 // the timer for sending them as well
181 timer_mod(s
->inject_timer
, qemu_clock_get_ns(QEMU_CLOCK_REALTIME
) + 25);
183 // we wait until a new packet schedules
185 s
->inject_timer_running
= 0;
188 signal_semaphore(s
->access_semaphore
, 0);
192 static int Atheros_WLAN_can_receive(NetClientState
*ncs
)
194 Atheros_WLANState
*s
= qemu_get_nic_opaque(ncs
);
196 if (s
->ap_state
!= Atheros_WLAN__STATE_ASSOCIATED
) {
197 // we are currently not connected
198 // to the access point
202 if (s
->inject_queue_size
> Atheros_WLAN__MAX_INJECT_QUEUE_SIZE
) {
203 // overload, please give me some time...
210 static ssize_t
Atheros_WLAN_receive(NetClientState
*ncs
,
211 const uint8_t *buf
, size_t size
)
213 Atheros_WLANState
*s
= qemu_get_nic_opaque(ncs
);
214 struct mac80211_frame
*frame
;
216 if (!Atheros_WLAN_can_receive(ncs
)) {
217 // this should not happen, but in
218 // case it does, let's simply drop
228 * A 802.3 packet comes from the qemu network. The
229 * access points turns it into a 802.11 frame and
230 * forwards it to the wireless device
232 frame
= Atheros_WLAN_create_data_packet(s
, buf
, size
);
234 Atheros_WLAN_init_frame(s
, frame
);
235 Atheros_WLAN_insert_frame(s
, frame
);
240 static void Atheros_WLAN_cleanup(NetClientState
*ncs
)
243 Atheros_WLANState
*d
= ncs
->opaque
;
244 timer_del(d
->poll_timer
);
245 timer_free(d
->poll_timer
);
249 static NetClientInfo net_info
= {
250 .type
= NET_CLIENT_DRIVER_NIC
,
251 .size
= sizeof(NICState
),
252 .can_receive
= Atheros_WLAN_can_receive
,
253 .receive
= Atheros_WLAN_receive
,
254 .cleanup
= Atheros_WLAN_cleanup
,
257 void Atheros_WLAN_setup_ap(NICInfo
*nd
, PCIAtheros_WLANState
*d
)
259 Atheros_WLANState
*s
;
260 s
= &d
->Atheros_WLAN
;
262 s
->ap_state
= Atheros_WLAN__STATE_NOT_AUTHENTICATED
;
263 s
->ap_macaddr
[0] = 0x00;
264 s
->ap_macaddr
[1] = 0x13;
265 s
->ap_macaddr
[2] = 0x46;
266 s
->ap_macaddr
[3] = 0xbf;
267 s
->ap_macaddr
[4] = 0x31;
268 s
->ap_macaddr
[5] = 0x59;
270 s
->inject_timer_running
= 0;
271 s
->inject_sequence_number
= 0;
273 s
->inject_queue
= NULL
;
274 s
->inject_queue_size
= 0;
276 s
->access_semaphore
= semget(ATHEROS_WLAN_ACCESS_SEM_KEY
, 1, 0666 | IPC_CREAT
);
277 semctl(s
->access_semaphore
, 0, SETVAL
, 1);
279 s
->beacon_timer
= timer_new_ns(QEMU_CLOCK_REALTIME
, Atheros_WLAN_beacon_timer
, s
);
280 timer_mod(s
->beacon_timer
, qemu_clock_get_ns(QEMU_CLOCK_REALTIME
));
282 // setup the timer but only schedule
283 // it when necessary...
284 s
->inject_timer
= timer_new_ns(QEMU_CLOCK_REALTIME
, Atheros_WLAN_inject_timer
, s
);
286 s
->nic
= qemu_new_nic(&net_info
, &s
->conf
, nd
->model
, nd
->name
, s
);
288 qemu_format_nic_info_str(qemu_get_queue(s
->nic
), s
->macaddr
);
291 void Atheros_WLAN_disable_irq(void *arg
)
293 Atheros_WLANState
*s
= (Atheros_WLANState
*)arg
;
294 SET_MEM_L(s
->mem
, ATH_HW_IRQ_PENDING
, ATH_HW_IRQ_PENDING_FALSE
);
295 qemu_set_irq(s
->irq
, 0);
296 DEBUG_PRINT((">> Disabling irq\n"));
299 void Atheros_WLAN_enable_irq(void *arg
)
301 Atheros_WLANState
*s
= (Atheros_WLANState
*)arg
;
303 if (!s
->interrupt_enabled
) {
304 DEBUG_PRINT((">> Wanted to enable irq, but they are disabled\n"));
305 Atheros_WLAN_disable_irq(s
);
309 DEBUG_PRINT((">> Enabling irq\n"));
310 SET_MEM_L(s
->mem
, ATH_HW_IRQ_PENDING
, ATH_HW_IRQ_PENDING_TRUE
);
311 qemu_set_irq(s
->irq
, 1);
315 void Atheros_WLAN_update_irq(void *arg
)
317 Atheros_WLANState
*s
= (Atheros_WLANState
*)arg
;
318 DEBUG_PRINT((">> Updating... irq-enabled is %u\n", s
->interrupt_enabled
));
320 * NOTE: Since we use shared interrupts
321 * the device driver will check if the
322 * interrupt really comes from this hardware
324 * This is done by checking the
325 * ATH_HW_IRQ_PENDING memory...
327 if (/*(!s->interrupt_enabled) ||*/
328 (s
->pending_interrupts
== NULL
)) {
329 SET_MEM_L(s
->mem
, AR5K_RAC_PISR
, 0);
330 goto disable_further_interrupts
;
334 * Make sure this is done atomically!!
336 wait_semaphore(s
->access_semaphore
, 0);
337 uint32_t status
= 0x0;
338 struct pending_interrupt
*i
= s
->pending_interrupts
;
339 struct pending_interrupt
*next
;
341 s
->pending_interrupts
= NULL
;
344 if (1) { //(s->interrupt_p_mask & i->status)
352 SET_MEM_L(s
->mem
, AR5K_RAC_PISR
, status
);
353 DEBUG_PRINT((">> Status set to %u\n", status
));
355 * Atomic part done...
357 signal_semaphore(s
->access_semaphore
, 0);
360 disable_further_interrupts
:
362 * NOTE: At last, it will check if any
363 * more interrupts are pending. The call
364 * to check what type of interrupt was
365 * pending already put down the interrupt_pending
366 * bit for us (check the readl function for RAC)
370 Atheros_WLAN_disable_irq(s
);
374 void Atheros_WLAN_append_irq(Atheros_WLANState
*s
, struct pending_interrupt intr
)
376 struct pending_interrupt
*new_intr
;
377 new_intr
= (struct pending_interrupt
*)malloc(sizeof(struct pending_interrupt
));
378 memcpy(new_intr
, &intr
, sizeof(intr
));
381 * Make sure this is done atomically!!
383 wait_semaphore(s
->access_semaphore
, 0);
385 if (s
->pending_interrupts
== NULL
) {
386 s
->pending_interrupts
= new_intr
;
389 * Insert at the end of the
390 * list to assure correct order
393 struct pending_interrupt
*i
= s
->pending_interrupts
;
394 while (i
->next
!= NULL
) {
398 new_intr
->next
= NULL
;
403 * Atomic part done...
405 signal_semaphore(s
->access_semaphore
, 0);
415 void Atheros_WLAN_handleRxBuffer(Atheros_WLANState
*s
, struct mac80211_frame
*frame
, uint32_t frame_length
)
417 struct ath_desc desc
;
418 struct ath5k_ar5212_rx_status
*rx_status
;
419 rx_status
= (struct ath5k_ar5212_rx_status
*)&desc
.ds_hw
[0];
421 if (s
->receive_queue_address
== 0) {
425 cpu_physical_memory_read(s
->receive_queue_address
, (uint8_t *)&desc
, sizeof(desc
));
428 * Put some good base-data into
429 * the descriptor. Length & co
430 * will be modified below...
432 * NOTE: Better set everything correctly
434 * Look at ath5k_hw.c: proc_tx_desc
437 desc
.ds_ctl1
= 0x9c0;
438 desc
.ds_hw
[0] = 0x126d806a;
439 desc
.ds_hw
[1] = 0x49860003;
445 * Filter out old length and put in correct value...
447 rx_status
->rx_status_0
&= ~AR5K_AR5212_DESC_RX_STATUS0_DATA_LEN
;
448 rx_status
->rx_status_0
|= frame_length
;
449 rx_status
->rx_status_0
&= ~AR5K_AR5211_DESC_RX_STATUS0_MORE
;
452 * Write descriptor and packet back to DMA memory...
454 cpu_physical_memory_write(s
->receive_queue_address
, (uint8_t *)&desc
, sizeof(desc
));
455 cpu_physical_memory_write((hwaddr
)desc
.ds_data
, (uint8_t *)frame
, sizeof(struct mac80211_frame
));
458 * Set address to next position
459 * in single-linked list
461 * The receive list's last element
462 * points to itself to avoid overruns.
463 * This way, at some point no more
464 * packets will be received, but (I
465 * ASSUME) that it is the drivers
466 * responsibility to reset the address
470 * NOTE: It seems the real madwifi cannot
471 * handle multiple packets at once. so we
472 * set the buffer to NULL to make the injection
473 * fail next time until an interrupt was
474 * received by the driver and a new buffer
477 s
->receive_queue_address
=
478 ((++s
->receive_queue_count
) > MAX_CONCURRENT_RX_FRAMES
)
480 : (hwaddr
)desc
.ds_link
;
483 DEBUG_PRINT((">> Enabling rx\n"));
485 * Notify the driver about the new packet
487 struct pending_interrupt intr
;
488 intr
.status
= AR5K_INT_RX
;
489 Atheros_WLAN_append_irq(s
, intr
);
490 Atheros_WLAN_enable_irq(s
);
495 void Atheros_WLAN_handleTxBuffer(Atheros_WLANState
*s
, uint32_t queue
)
497 struct ath_desc desc
;
498 struct mac80211_frame frame
;
500 if (s
->transmit_queue_address
[queue
] == 0) {
504 cpu_physical_memory_read(s
->transmit_queue_address
[queue
], (uint8_t *)&desc
, sizeof(desc
));
506 if (s
->transmit_queue_processed
[queue
]) {
508 * Maybe we already processed the frame
509 * and have not gotten the address of the
510 * next frame buffer but still got a call
511 * to send the next frame
513 * this way we have to process the next
514 * frame in the single linked list!!
516 s
->transmit_queue_address
[queue
] = (hwaddr
)desc
.ds_link
;
519 * And now get the frame we really have to process...
521 cpu_physical_memory_read(s
->transmit_queue_address
[queue
], (uint8_t *)&desc
, sizeof(desc
));
524 uint32_t segment_len
, frame_length
= 0, more
;
525 uint8_t *frame_pos
= (uint8_t *)&frame
;
526 struct ath5k_ar5212_tx_desc
*tx_desc
;
527 tx_desc
= (struct ath5k_ar5212_tx_desc
*)&desc
.ds_ctl0
;
529 more
= tx_desc
->tx_control_1
& AR5K_AR5211_DESC_TX_CTL1_MORE
;
530 segment_len
= tx_desc
->tx_control_1
& AR5K_AR5212_DESC_TX_CTL1_BUF_LEN
;
532 cpu_physical_memory_read((hwaddr
)desc
.ds_data
, frame_pos
, segment_len
);
533 frame_pos
+= segment_len
;
534 frame_length
+= segment_len
;
538 * Notify successful transmission
540 * NOTE: It'd be better to leave the
541 * descriptor as it is and only modify
542 * the transmit-ok-bits --> this way
543 * the timestamp and co. would stay
546 * Look at ath5k_hw.c: proc_tx_desc
548 * NOTE: Not sure if this acknowledgement
549 * must be copied back for every single
550 * descriptor in a multi-segment frame,
551 * but better safe than sorry!!
553 desc
.ds_ctl0
= 0x213f002f;
555 desc
.ds_hw
[0] = 0xf0000;
556 desc
.ds_hw
[1] = 0x1b;
557 desc
.ds_hw
[2] = 0xab640001;
558 desc
.ds_hw
[3] = 0x4a019;
562 * struct ath5k_tx_status *tx_status = (struct ath5k_tx_status*)&desc.ds_hw[2];
563 * tx_status->tx_status_1 |= AR5K_DESC_TX_STATUS1_DONE;
564 * tx_status->tx_status_0 |= AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK;
567 * Write descriptor back to DMA memory...
569 cpu_physical_memory_write(s
->transmit_queue_address
[queue
], (uint8_t *)&desc
, sizeof(desc
));
571 if (more
&& frame_length
< sizeof(frame
)) {
573 * This is done at the end of the loop
574 * since sometimes the next-link is not
575 * yet set (assuming frame is a 1-segment
578 * This is very strange (and maybe obsolete
579 * by this version) but let's do it the safe
580 * way and not mess it up :-)
582 s
->transmit_queue_address
[queue
] = (hwaddr
)desc
.ds_link
;
583 cpu_physical_memory_read(s
->transmit_queue_address
[queue
], (uint8_t *)&desc
, sizeof(desc
));
585 } while (more
&& frame_length
< sizeof(frame
));
588 struct pending_interrupt intr
;
589 intr
.status
= AR5K_INT_TX
;
590 Atheros_WLAN_append_irq(s
, intr
);
591 Atheros_WLAN_enable_irq(s
);
594 * Set address to next position
595 * in single-linked list
597 * The transmit list's last element
598 * points to itself to avoid overruns.
599 * This way, at some point no more
600 * packets will be received, but (I
601 * ASSUME) that it is the drivers
602 * responsibility to reset the address
605 s
->transmit_queue_processed
[queue
] = 1;
607 frame
.frame_length
= frame_length
+ 4;
608 Atheros_WLAN_handle_frame(s
, &frame
);
612 void Atheros_WLAN_handle_frame(Atheros_WLANState
*s
, struct mac80211_frame
*frame
)
614 struct mac80211_frame
*reply
= NULL
;
615 unsigned long ethernet_frame_size
;
616 unsigned char ethernet_frame
[1518];
618 if ((frame
->frame_control
.type
== IEEE80211_TYPE_MGT
) &&
619 (frame
->frame_control
.sub_type
== IEEE80211_TYPE_MGT_SUBTYPE_PROBE_REQ
)) {
620 reply
= Atheros_WLAN_create_probe_response();
621 } else if ((frame
->frame_control
.type
== IEEE80211_TYPE_MGT
) &&
622 (frame
->frame_control
.sub_type
== IEEE80211_TYPE_MGT_SUBTYPE_AUTHENTICATION
)) {
623 DEBUG_PRINT_AP(("Received authentication!\n"));
624 reply
= Atheros_WLAN_create_authentication();
626 if (s
->ap_state
== Atheros_WLAN__STATE_NOT_AUTHENTICATED
) {
627 // if everything is going according to
628 // the state machine, let's jump into the
630 s
->ap_state
= Atheros_WLAN__STATE_AUTHENTICATED
;
632 } else if ((frame
->frame_control
.type
== IEEE80211_TYPE_MGT
) &&
633 (frame
->frame_control
.sub_type
== IEEE80211_TYPE_MGT_SUBTYPE_DEAUTHENTICATION
)) {
634 DEBUG_PRINT_AP(("Received deauthentication!\n"));
635 reply
= Atheros_WLAN_create_deauthentication();
637 // some systems (e.g. WinXP) won't send a
638 // disassociation. just believe that the
639 // deauthentication is ok... nothing bad
640 // can happen anyways ;-)
641 s
->ap_state
= Atheros_WLAN__STATE_NOT_AUTHENTICATED
;
642 } else if ((frame
->frame_control
.type
== IEEE80211_TYPE_MGT
) &&
643 (frame
->frame_control
.sub_type
== IEEE80211_TYPE_MGT_SUBTYPE_ASSOCIATION_REQ
)) {
644 DEBUG_PRINT_AP(("Received association request!\n"));
645 reply
= Atheros_WLAN_create_association_response();
647 if (s
->ap_state
== Atheros_WLAN__STATE_AUTHENTICATED
) {
648 // if everything is going according to
649 // the state machine, let's jump into the
651 s
->ap_state
= Atheros_WLAN__STATE_ASSOCIATED
;
653 } else if ((frame
->frame_control
.type
== IEEE80211_TYPE_MGT
) &&
654 (frame
->frame_control
.sub_type
== IEEE80211_TYPE_MGT_SUBTYPE_DISASSOCIATION
)) {
655 DEBUG_PRINT_AP(("Received disassociation!\n"));
656 reply
= Atheros_WLAN_create_disassociation();
658 if (s
->ap_state
== Atheros_WLAN__STATE_ASSOCIATED
) {
659 // if everything is going according to
660 // the state machine, let's jump into the
662 s
->ap_state
= Atheros_WLAN__STATE_AUTHENTICATED
;
664 } else if ((frame
->frame_control
.type
== IEEE80211_TYPE_DATA
) &&
665 (s
->ap_state
== Atheros_WLAN__STATE_ASSOCIATED
)) {
667 * The access point uses the 802.11 frame
668 * and sends a 802.3 frame into the network...
669 * This packet is then understandable by
672 * If we ever want the access point to offer
673 * some services, it can be added here!!
675 // ethernet header type
676 ethernet_frame
[12] = frame
->data_and_fcs
[6];
677 ethernet_frame
[13] = frame
->data_and_fcs
[7];
679 // the new originator of the packet is
681 memcpy(ðernet_frame
[6], s
->ap_macaddr
, 6);
683 if (ethernet_frame
[12] == 0x08 && ethernet_frame
[13] == 0x06) {
684 // for arp request, we use a broadcast
685 memset(ðernet_frame
[0], 0xff, 6);
687 // otherwise we forward the packet to
688 // where it really belongs
689 memcpy(ðernet_frame
[0], frame
->destination_address
, 6);
692 // add packet content
693 ethernet_frame_size
= frame
->frame_length
- 24 - 4 - 8;
695 // for some reason, the packet is 22 bytes too small (??)
696 ethernet_frame_size
+= 22;
697 if (ethernet_frame_size
> sizeof(ethernet_frame
)) {
698 ethernet_frame_size
= sizeof(ethernet_frame
);
700 memcpy(ðernet_frame
[14], &frame
->data_and_fcs
[8], ethernet_frame_size
);
702 // add size of ethernet header
703 ethernet_frame_size
+= 14;
708 qemu_send_packet(qemu_get_queue(s
->nic
), ethernet_frame
, ethernet_frame_size
);
712 memcpy(reply
->destination_address
, frame
->source_address
, 6);
713 Atheros_WLAN_init_frame(s
, reply
);
714 Atheros_WLAN_insert_frame(s
, reply
);
718 #endif /* CONFIG_WIN32 */