summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/arm/nds/wifi/wifi.c
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2008-04-16 18:37:33 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2008-04-16 18:37:33 +0000
commit311dfa65d823ebb1448a12e9a24d09c7ca7a9e2a (patch)
tree47eaf22ca7bb8cc68486ffe964abd54b535902ad /c/src/lib/libbsp/arm/nds/wifi/wifi.c
parent2008-04-16 Matthieu Bucchianeri <mbucchia@gmail.com> (diff)
downloadrtems-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.c416
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;
+}