diff options
author | Joel Sherrill <joel.sherrill@OARcorp.com> | 2008-04-16 18:37:33 +0000 |
---|---|---|
committer | Joel Sherrill <joel.sherrill@OARcorp.com> | 2008-04-16 18:37:33 +0000 |
commit | 311dfa65d823ebb1448a12e9a24d09c7ca7a9e2a (patch) | |
tree | 47eaf22ca7bb8cc68486ffe964abd54b535902ad /c/src/lib/libbsp/arm/nds/wifi/wifi.c | |
parent | 2008-04-16 Matthieu Bucchianeri <mbucchia@gmail.com> (diff) | |
download | rtems-311dfa65d823ebb1448a12e9a24d09c7ca7a9e2a.tar.bz2 |
2008-04-16 Matthieu Bucchianeri <mbucchia@gmail.com>
* ChangeLog, Makefile.am, README, bsp_specs, configure.ac,
mk_libnds.sh, patch.libnds, preinstall.am, block/block.c,
clock/clock.c, console/console.c, coproc/coproc.S, coproc/coproc.c,
coproc/coproc.ld, dswifi/dswifi_license.txt, dswifi/makefile,
dswifi/arm7/makefile, dswifi/arm7/source/wifi_arm7.c,
dswifi/arm7/source/wifi_arm7.h, dswifi/arm9/makefile,
dswifi/arm9/source/sgIP.c, dswifi/arm9/source/sgIP.h,
dswifi/arm9/source/sgIP_ARP.c, dswifi/arm9/source/sgIP_ARP.h,
dswifi/arm9/source/sgIP_Config.h, dswifi/arm9/source/sgIP_DHCP.c,
dswifi/arm9/source/sgIP_DHCP.h, dswifi/arm9/source/sgIP_DNS.c,
dswifi/arm9/source/sgIP_DNS.h, dswifi/arm9/source/sgIP_Hub.c,
dswifi/arm9/source/sgIP_Hub.h, dswifi/arm9/source/sgIP_ICMP.c,
dswifi/arm9/source/sgIP_ICMP.h, dswifi/arm9/source/sgIP_IP.c,
dswifi/arm9/source/sgIP_IP.h, dswifi/arm9/source/sgIP_TCP.c,
dswifi/arm9/source/sgIP_TCP.h, dswifi/arm9/source/sgIP_UDP.c,
dswifi/arm9/source/sgIP_UDP.h, dswifi/arm9/source/sgIP_memblock.c,
dswifi/arm9/source/sgIP_memblock.h,
dswifi/arm9/source/sgIP_sockets.c, dswifi/arm9/source/sgIP_sockets.h,
dswifi/arm9/source/wifi_arm9.c, dswifi/arm9/source/wifi_arm9.h,
dswifi/common/source/dsregs.h, dswifi/common/source/spinlock.h,
dswifi/common/source/spinlock.s, dswifi/common/source/wifi_shared.h,
dswifi/include/dswifi7.h, dswifi/include/dswifi9.h,
dswifi/include/dswifi_version.h, dswifi/include/netdb.h,
dswifi/include/sgIP_errno.h, dswifi/include/netinet/in.h, fb/fb.c,
fb/fb.h, include/bsp.h, include/my_ipc.h, include/tm27.h,
include/types.h, include/sys/iosupport.h, irq/irq.c, irq/irq.h,
libfat/gba/include/fat.h, libfat/include/fat.h,
libfat/nds/include/fat.h, libfat/source/bit_ops.h,
libfat/source/cache.c, libfat/source/cache.h, libfat/source/common.h,
libfat/source/directory.c, libfat/source/directory.h,
libfat/source/fatdir.c, libfat/source/fatdir.h,
libfat/source/fatfile.c, libfat/source/fatfile.h,
libfat/source/file_allocation_table.c,
libfat/source/file_allocation_table.h, libfat/source/filetime.c,
libfat/source/filetime.h, libfat/source/libfat.c,
libfat/source/mem_allocate.h, libfat/source/partition.c,
libfat/source/partition.h, libfat/source/disc_io/disc.c,
libfat/source/disc_io/disc.h, libfat/source/disc_io/disc_io.h,
libfat/source/disc_io/io_cf_common.c,
libfat/source/disc_io/io_cf_common.h,
libfat/source/disc_io/io_dldi.h, libfat/source/disc_io/io_dldi.s,
libfat/source/disc_io/io_efa2.c, libfat/source/disc_io/io_efa2.h,
libfat/source/disc_io/io_fcsr.c, libfat/source/disc_io/io_fcsr.h,
libfat/source/disc_io/io_m3_common.c,
libfat/source/disc_io/io_m3_common.h,
libfat/source/disc_io/io_m3cf.c, libfat/source/disc_io/io_m3cf.h,
libfat/source/disc_io/io_m3sd.c, libfat/source/disc_io/io_m3sd.h,
libfat/source/disc_io/io_mpcf.c, libfat/source/disc_io/io_mpcf.h,
libfat/source/disc_io/io_njsd.c, libfat/source/disc_io/io_njsd.h,
libfat/source/disc_io/io_nmmc.c, libfat/source/disc_io/io_nmmc.h,
libfat/source/disc_io/io_sc_common.c,
libfat/source/disc_io/io_sc_common.h,
libfat/source/disc_io/io_sccf.c, libfat/source/disc_io/io_sccf.h,
libfat/source/disc_io/io_scsd.c, libfat/source/disc_io/io_scsd.h,
libfat/source/disc_io/io_scsd_s.s,
libfat/source/disc_io/io_sd_common.c,
libfat/source/disc_io/io_sd_common.h, libnds/Makefile.arm7,
libnds/Makefile.arm9, libnds/libnds_license.txt,
libnds/basicARM7/source/defaultARM7.c,
libnds/include/default_font_bin.h, libnds/include/gbfs.h,
libnds/include/nds.h, libnds/include/nds/bios.h,
libnds/include/nds/card.h, libnds/include/nds/dma.h,
libnds/include/nds/interrupts.h, libnds/include/nds/ipc.h,
libnds/include/nds/jtypes.h, libnds/include/nds/memory.h,
libnds/include/nds/registers_alt.h, libnds/include/nds/reload.h,
libnds/include/nds/system.h, libnds/include/nds/timers.h,
libnds/include/nds/arm7/audio.h, libnds/include/nds/arm7/clock.h,
libnds/include/nds/arm7/serial.h, libnds/include/nds/arm7/touch.h,
libnds/include/nds/arm9/background.h,
libnds/include/nds/arm9/boxtest.h, libnds/include/nds/arm9/cache.h,
libnds/include/nds/arm9/console.h,
libnds/include/nds/arm9/exceptions.h,
libnds/include/nds/arm9/image.h, libnds/include/nds/arm9/input.h,
libnds/include/nds/arm9/math.h, libnds/include/nds/arm9/ndsmotion.h,
libnds/include/nds/arm9/pcx.h, libnds/include/nds/arm9/postest.h,
libnds/include/nds/arm9/rumble.h, libnds/include/nds/arm9/sound.h,
libnds/include/nds/arm9/sprite.h, libnds/include/nds/arm9/trig_lut.h,
libnds/include/nds/arm9/video.h, libnds/include/nds/arm9/videoGL.h,
libnds/source/arm7/audio.c, libnds/source/arm7/clock.c,
libnds/source/arm7/microphone.c, libnds/source/arm7/spi.c,
libnds/source/arm7/touch.c, libnds/source/arm7/userSettings.c,
libnds/source/arm9/COS.bin, libnds/source/arm9/COS.s,
libnds/source/arm9/SIN.bin, libnds/source/arm9/SIN.s,
libnds/source/arm9/TAN.bin, libnds/source/arm9/TAN.s,
libnds/source/arm9/boxtest.c, libnds/source/arm9/console.c,
libnds/source/arm9/dcache.s, libnds/source/arm9/default_font.bin,
libnds/source/arm9/default_font.s,
libnds/source/arm9/exceptionHandler.S,
libnds/source/arm9/exceptionHandler.s,
libnds/source/arm9/exceptions.c, libnds/source/arm9/gurumeditation.c,
libnds/source/arm9/icache.s, libnds/source/arm9/image.c,
libnds/source/arm9/initSystem.c, libnds/source/arm9/keys.c,
libnds/source/arm9/ndsmotion.c, libnds/source/arm9/pcx.c,
libnds/source/arm9/rumble.c, libnds/source/arm9/sound.c,
libnds/source/arm9/system.c, libnds/source/arm9/touch.c,
libnds/source/arm9/video.c, libnds/source/arm9/videoGL.c,
libnds/source/common/biosCalls.s, libnds/source/common/card.c,
libnds/source/common/gbfs.c,
libnds/source/common/interruptDispatcher.s,
libnds/source/common/interrupts.c, rtc/rtc.c, sound/sound.c,
sound/sound.h, start/start.S, startup/linkcmds, startup/start.c,
timer/timer.c, tools/Makefile.am, tools/bin2s, tools/bin2s.c,
tools/configure.ac, tools/runtest,
tools/ndstool/include/arm7_sha1_homebrew.h,
tools/ndstool/include/arm7_sha1_nintendo.h,
tools/ndstool/include/banner.h, tools/ndstool/include/bigint.h,
tools/ndstool/include/crc.h, tools/ndstool/include/default_icon.h,
tools/ndstool/include/encryption.h, tools/ndstool/include/header.h,
tools/ndstool/include/hook.h, tools/ndstool/include/little.h,
tools/ndstool/include/loadme.h, tools/ndstool/include/logo.h,
tools/ndstool/include/ndscreate.h,
tools/ndstool/include/ndsextract.h, tools/ndstool/include/ndstool.h,
tools/ndstool/include/ndstree.h, tools/ndstool/include/overlay.h,
tools/ndstool/include/passme.h, tools/ndstool/include/passme_sram.h,
tools/ndstool/include/passme_vhd1.h,
tools/ndstool/include/passme_vhd2.h, tools/ndstool/include/raster.h,
tools/ndstool/include/sha1.h, tools/ndstool/include/types.h,
tools/ndstool/source/arm7_sha1_homebrew.c,
tools/ndstool/source/arm7_sha1_nintendo.c,
tools/ndstool/source/banner.cpp, tools/ndstool/source/bigint.cpp,
tools/ndstool/source/compile_date.c, tools/ndstool/source/crc.cpp,
tools/ndstool/source/default_icon.c,
tools/ndstool/source/encryption.cpp, tools/ndstool/source/header.cpp,
tools/ndstool/source/hook.cpp, tools/ndstool/source/loadme.c,
tools/ndstool/source/logo.cpp, tools/ndstool/source/ndscodes.cpp,
tools/ndstool/source/ndscreate.cpp,
tools/ndstool/source/ndsextract.cpp,
tools/ndstool/source/ndstool.cpp, tools/ndstool/source/ndstree.cpp,
tools/ndstool/source/passme.cpp, tools/ndstool/source/passme_sram.c,
tools/ndstool/source/raster.cpp, tools/ndstool/source/sha1.cpp,
touchscreen/README.reco, touchscreen/parser.c, touchscreen/reco.c,
touchscreen/reco.h, touchscreen/touchscreen.c,
touchscreen/touchscreen.h, wifi/compat.c, wifi/compat.h, wifi/wifi.c:
New files.
Diffstat (limited to '')
-rw-r--r-- | c/src/lib/libbsp/arm/nds/wifi/wifi.c | 416 |
1 files changed, 416 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/arm/nds/wifi/wifi.c b/c/src/lib/libbsp/arm/nds/wifi/wifi.c new file mode 100644 index 0000000000..c8c6f56701 --- /dev/null +++ b/c/src/lib/libbsp/arm/nds/wifi/wifi.c @@ -0,0 +1,416 @@ +/* + * RTEMS for Nintendo DS WiFi driver. + * + * Copyright (c) 2008 by Matthieu Bucchianeri <mbucchia@gmail.com> + * Benjamin Ratier <agho.pwn@gmail.com> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * + * http://www.rtems.com/license/LICENSE + * + * $Id$ + */ + +#include <bsp.h> + +#include <stdio.h> +#include <assert.h> +#include <errno.h> + +#include <rtems/error.h> +#include <rtems/rtems_bsdnet.h> + +#include <sys/param.h> +#include <sys/mbuf.h> +#include <sys/socket.h> +#include <sys/sockio.h> + +#include <net/if.h> + +#include <netinet/in.h> +#include <netinet/if_ether.h> + +#include <irq.h> + +#include <nds.h> +#include <dswifi9.h> + +/* + * RTEMS event number used by reception task to receive packet + */ + +#define RECEIVE_EVENT RTEMS_EVENT_1 + +/* + * RTEMS event number used to start the transmit daemon + */ + +#define TRANSMIT_EVENT RTEMS_EVENT_2 + +/* + * from compat.c + */ + +void compat_wifi_output (struct mbuf *m); + +/* + * wifi driver structure + */ + +static struct +{ + /* The bsdnet information structure */ + struct arpcom arpcom; + + /* indicate if the hwaddr is already set */ + uint8_t is_hwaddr_set; + + /* the thread ID of the transmit task */ + rtems_id tx_id; + /* the thread ID of the receive task */ + rtems_id rx_id; + + /* reception queue (filled in compat.c:ReceiveHardwarePacket) */ + struct ifqueue recvq; +} softc; + +static void +print_byte (unsigned char b) +{ + printk ("%x%x", b >> 4, b & 0x0f); +} + +/* + * wifi timer function, must be called every 50 ms + */ + +static void +Timer_50ms (void) +{ + Wifi_Timer (50); +} + +/* + * notification function to send fifo message to arm7 + */ + +static void +arm9_synctoarm7 (void) +{ + /* send fifo message */ + REG_IPC_FIFO_TX = 0x87654321; +} + +/* + * interrupt handler to receive fifo messages from arm7 + */ + +static void +arm9_fifo (void) +{ + u32 value = REG_IPC_FIFO_RX; + + /* check incoming fifo messages */ + if (value == 0x87654321) + Wifi_Sync (); +} + +/* + * signal an icoming packet + */ + +void +wifi_signal (struct mbuf *m) +{ + rtems_interrupt_level level; + + /* enqueue the incoming packet */ + rtems_interrupt_disable (level); + IF_ENQUEUE (&softc.recvq, m); + rtems_interrupt_enable (level); + + /* signal the rx daemon */ + rtems_event_send (softc.rx_id, RECEIVE_EVENT); +} + + +/* + * packet reception daemon + */ + +static void +wifi_rxd (void *arg) +{ + rtems_interrupt_level level; + struct ifnet *ifp = &softc.arpcom.ac_if; + + while (1) { + rtems_event_set events; + + rtems_bsdnet_event_receive (RECEIVE_EVENT, + RTEMS_WAIT | RTEMS_EVENT_ANY, + RTEMS_NO_TIMEOUT, &events); + + while (1) { + struct ether_header *eh; + struct mbuf *m; + + rtems_interrupt_disable (level); + if (softc.recvq.ifq_head == NULL) { + rtems_interrupt_enable (level); + break; + } + + /* get next packet */ + IF_DEQUEUE (&softc.recvq, m); + rtems_interrupt_enable (level); + if (m == NULL) { + panic ("wifi_rxd"); + } + + m->m_pkthdr.rcvif = ifp; + + /* extract ethernet header */ + eh = mtod (m, struct ether_header *); + m->m_data += sizeof (struct ether_header); + m->m_len = m->m_pkthdr.len = m->m_len - sizeof (struct ether_header); + + /* push the packet into the stack */ + ether_input (ifp, eh, m); + } + } +} + +/* + * packet sending daemon + */ + +static void +wifi_txd (void *arg) +{ + rtems_interrupt_level level; + struct ifnet *ifp = &softc.arpcom.ac_if; + + while (1) { + rtems_event_set events; + + rtems_bsdnet_event_receive (TRANSMIT_EVENT, + RTEMS_WAIT | RTEMS_EVENT_ANY, + RTEMS_NO_TIMEOUT, &events); + while (1) { + struct mbuf *m; + + rtems_interrupt_disable (level); + if (ifp->if_snd.ifq_head == NULL) { + ifp->if_flags &= ~IFF_OACTIVE; + rtems_interrupt_enable (level); + break; + } + + /* grab next packet */ + IF_DEQUEUE (&ifp->if_snd, m); + rtems_interrupt_enable (level); + + if (m == NULL) { + panic ("wifi_txd"); + } + + /* call compatibility glue to dswifi */ + compat_wifi_output (m); + } + } +} + +/* + * wifi device initialization procedure + */ + +static void +wifi_init (void *arg) +{ + struct ifnet *ifp = &softc.arpcom.ac_if; + int i; + + /* create the receive & send daemons */ + if (softc.tx_id == 0) { + Wifi_AutoConnect (); + + while (1) { + i = Wifi_AssocStatus (); + if (i == ASSOCSTATUS_ASSOCIATED) { + printk ("Connected successfully!\n"); + break; + } + if (i == ASSOCSTATUS_CANNOTCONNECT) { + printk ("Could not connect!\n"); + break; + } + } + + printk ("Starting daemon\n"); + softc.tx_id = rtems_bsdnet_newproc ("SCtx", 4096, wifi_txd, &softc); + softc.rx_id = rtems_bsdnet_newproc ("SCrx", 4096, wifi_rxd, &softc); + } + + ifp->if_flags |= IFF_RUNNING; +} + +/* + * wifi deactivation method. + */ + +static void +wifi_shutdown (void *arg) +{ + /* XXX */ +} + +/* + * ioctl hook function. + */ + +static int +wifi_ioctl (struct ifnet *ifp, ioctl_command_t command, caddr_t data) +{ + void *sc = ifp->if_softc; + + switch (command) { + case SIOCGIFADDR: + case SIOCSIFADDR: + return ether_ioctl (ifp, command, data); + + case SIOCSIFFLAGS: + switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) { + case IFF_RUNNING: + wifi_shutdown (sc); + break; + case IFF_UP: + wifi_init (sc); + break; + case IFF_UP | IFF_RUNNING: + wifi_shutdown (sc); + wifi_init (sc); + break; + default: + break; + } + return 0; + + default: + return EINVAL; + } +} + +/* + * function for sending a packet + */ + +static void +wifi_start (struct ifnet *ifp) +{ + /* wake up the send daemon */ + ifp->if_flags |= IFF_OACTIVE; + rtems_event_send (softc.tx_id, TRANSMIT_EVENT); +} + +/* + * RTEMS device attach method for wiwi driver + */ + +int +rtems_wifi_driver_attach (struct rtems_bsdnet_ifconfig *config, int attach) +{ + struct ifnet *ifp = &softc.arpcom.ac_if; + + printk ("wifi attach...\n"); + + /* initialize ifnet structure */ + memset (&softc, 0, sizeof (softc)); + ifp->if_softc = &softc; + ifp->if_unit = 0; + ifp->if_name = "dswifi"; + ifp->if_mtu = ETHERMTU; + ifp->if_init = wifi_init; + ifp->if_ioctl = wifi_ioctl; + ifp->if_watchdog = NULL; + ifp->if_start = wifi_start; + ifp->if_output = ether_output; + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX; + if (ifp->if_snd.ifq_maxlen == 0) { + ifp->if_snd.ifq_maxlen = ifqmaxlen; + } + + if (config->mtu != 0) { + ifp->if_mtu = config->mtu; + } + + if (config->hardware_address != NULL) { + softc.is_hwaddr_set = 1; + memcpy (softc.arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN); + } else { + softc.is_hwaddr_set = 0; + } + + u32 Wifi_pass; + int i; + + /* wifi hardware initialization took from dswifi example code */ + + /* send fifo message to initialize the arm7 wifi */ + REG_IPC_FIFO_CR = IPC_FIFO_ENABLE | IPC_FIFO_SEND_CLEAR; + + Wifi_pass = + Wifi_Init (WIFIINIT_OPTION_USELED | WIFIINIT_OPTION_USECUSTOMALLOC); + REG_IPC_FIFO_TX = 0x12345678; + REG_IPC_FIFO_TX = Wifi_pass; + + /* setup fifo IRQ */ + irqSet (IRQ_FIFO_NOT_EMPTY, arm9_fifo); + irqEnable (IRQ_FIFO_NOT_EMPTY); + + /* enable FIFO IRQ */ + REG_IPC_FIFO_CR = IPC_FIFO_ENABLE | IPC_FIFO_RECV_IRQ; + + /* tell wifi lib to use our handler to notify arm7 */ + Wifi_SetSyncHandler (arm9_synctoarm7); + + /* set timer3 */ + TIMER3_DATA = -6553; // 6553.1 * 256 cycles = ~50ms; + TIMER3_CR = 0x00C2; // enable, irq, 1/256 clock + + /* setup timer IRQ */ + irqSet (IRQ_TIMER3, Timer_50ms); + irqEnable (IRQ_TIMER3); + + while (Wifi_CheckInit () == 0) { + /* wait for arm7 to be initted successfully */ + while (REG_VCOUNT > 192); + while (REG_VCOUNT < 192); + } + + /* wifi init complete - wifi lib can now be used! */ + + printk ("ok.\n"); + + /* retrieve MAC address if unspecified by the user */ + if (!softc.is_hwaddr_set) { + Wifi_GetData (WIFIGETDATA_MACADDRESS, ETHER_ADDR_LEN, + softc.arpcom.ac_enaddr); + } + + print_byte (softc.arpcom.ac_enaddr[0]); + for (i = 1; i < ETHER_ADDR_LEN; i++) { + printk (":"); + print_byte (softc.arpcom.ac_enaddr[i]); + } + printk ("\n"); + + /* attach the interface */ + if_attach (ifp); + ether_ifattach (ifp); + + printk ("network device '%s' initialized\n", config->name); + + return 0; +} |