source: rtems/c/src/lib/libbsp/arm/nds/wifi/wifi.c @ 12d853d

4.104.115
Last change on this file since 12d853d was 311dfa6, checked in by Joel Sherrill <joel.sherrill@…>, on 04/16/08 at 18:37:33

2008-04-16 Matthieu Bucchianeri <mbucchia@…>

  • 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.
  • Property mode set to 100644
File size: 8.1 KB
Line 
1/*
2 * RTEMS for Nintendo DS WiFi driver.
3 *
4 * Copyright (c) 2008 by Matthieu Bucchianeri <mbucchia@gmail.com>
5 *                       Benjamin Ratier <agho.pwn@gmail.com>
6 *
7 * The license and distribution terms for this file may be
8 * found in the file LICENSE in this distribution or at
9 *
10 * http://www.rtems.com/license/LICENSE
11 *
12 * $Id$
13 */
14
15#include <bsp.h>
16
17#include <stdio.h>
18#include <assert.h>
19#include <errno.h>
20
21#include <rtems/error.h>
22#include <rtems/rtems_bsdnet.h>
23
24#include <sys/param.h>
25#include <sys/mbuf.h>
26#include <sys/socket.h>
27#include <sys/sockio.h>
28
29#include <net/if.h>
30
31#include <netinet/in.h>
32#include <netinet/if_ether.h>
33
34#include <irq.h>
35
36#include <nds.h>
37#include <dswifi9.h>
38
39/*
40 * RTEMS event number used by reception task to receive packet
41 */
42
43#define RECEIVE_EVENT RTEMS_EVENT_1
44
45/*
46 * RTEMS event number used to start the transmit daemon
47 */
48
49#define TRANSMIT_EVENT RTEMS_EVENT_2
50
51/*
52 * from compat.c
53 */
54
55void compat_wifi_output (struct mbuf *m);
56
57/*
58 * wifi driver structure
59 */
60
61static struct
62{
63  /* The bsdnet information structure */
64  struct arpcom arpcom;
65
66  /* indicate if the hwaddr is already set */
67  uint8_t is_hwaddr_set;
68
69  /* the thread ID of the transmit task */
70  rtems_id tx_id;
71  /* the thread ID of the receive task */
72  rtems_id rx_id;
73
74  /* reception queue (filled in compat.c:ReceiveHardwarePacket) */
75  struct ifqueue recvq;
76} softc;
77
78static void
79print_byte (unsigned char b)
80{
81  printk ("%x%x", b >> 4, b & 0x0f);
82}
83
84/*
85 * wifi timer function, must be called every 50 ms
86 */
87
88static void
89Timer_50ms (void)
90{
91  Wifi_Timer (50);
92}
93
94/*
95 * notification function to send fifo message to arm7
96 */
97
98static void
99arm9_synctoarm7 (void)
100{
101  /* send fifo message */
102  REG_IPC_FIFO_TX = 0x87654321;
103}
104
105/*
106 * interrupt handler to receive fifo messages from arm7
107 */
108
109static void
110arm9_fifo (void)
111{
112  u32 value = REG_IPC_FIFO_RX;
113
114  /* check incoming fifo messages */
115  if (value == 0x87654321)
116    Wifi_Sync ();
117}
118
119/*
120 * signal an icoming packet
121 */
122
123void
124wifi_signal (struct mbuf *m)
125{
126  rtems_interrupt_level level;
127
128  /* enqueue the incoming packet */
129  rtems_interrupt_disable (level);
130  IF_ENQUEUE (&softc.recvq, m);
131  rtems_interrupt_enable (level);
132
133  /* signal the rx daemon */
134  rtems_event_send (softc.rx_id, RECEIVE_EVENT);
135}
136
137
138/*
139 * packet reception daemon
140 */
141
142static void
143wifi_rxd (void *arg)
144{
145  rtems_interrupt_level level;
146  struct ifnet *ifp = &softc.arpcom.ac_if;
147
148  while (1) {
149    rtems_event_set events;
150
151    rtems_bsdnet_event_receive (RECEIVE_EVENT,
152                                RTEMS_WAIT | RTEMS_EVENT_ANY,
153                                RTEMS_NO_TIMEOUT, &events);
154
155    while (1) {
156      struct ether_header *eh;
157      struct mbuf *m;
158
159      rtems_interrupt_disable (level);
160      if (softc.recvq.ifq_head == NULL) {
161        rtems_interrupt_enable (level);
162        break;
163      }
164
165      /* get next packet */
166      IF_DEQUEUE (&softc.recvq, m);
167      rtems_interrupt_enable (level);
168      if (m == NULL) {
169        panic ("wifi_rxd");
170      }
171
172      m->m_pkthdr.rcvif = ifp;
173
174      /* extract ethernet header */
175      eh = mtod (m, struct ether_header *);
176      m->m_data += sizeof (struct ether_header);
177      m->m_len = m->m_pkthdr.len = m->m_len - sizeof (struct ether_header);
178
179      /* push the packet into the stack */
180      ether_input (ifp, eh, m);
181    }
182  }
183}
184
185/*
186 * packet sending daemon
187 */
188
189static void
190wifi_txd (void *arg)
191{
192  rtems_interrupt_level level;
193  struct ifnet *ifp = &softc.arpcom.ac_if;
194
195  while (1) {
196    rtems_event_set events;
197
198    rtems_bsdnet_event_receive (TRANSMIT_EVENT,
199                                RTEMS_WAIT | RTEMS_EVENT_ANY,
200                                RTEMS_NO_TIMEOUT, &events);
201    while (1) {
202      struct mbuf *m;
203
204      rtems_interrupt_disable (level);
205      if (ifp->if_snd.ifq_head == NULL) {
206        ifp->if_flags &= ~IFF_OACTIVE;
207        rtems_interrupt_enable (level);
208        break;
209      }
210
211      /* grab next packet */
212      IF_DEQUEUE (&ifp->if_snd, m);
213      rtems_interrupt_enable (level);
214
215      if (m == NULL) {
216        panic ("wifi_txd");
217      }
218
219      /* call compatibility glue to dswifi */
220      compat_wifi_output (m);
221    }
222  }
223}
224
225/*
226 * wifi device initialization procedure
227 */
228
229static void
230wifi_init (void *arg)
231{
232  struct ifnet *ifp = &softc.arpcom.ac_if;
233  int i;
234
235  /* create the receive & send daemons */
236  if (softc.tx_id == 0) {
237    Wifi_AutoConnect ();
238
239    while (1) {
240      i = Wifi_AssocStatus ();
241      if (i == ASSOCSTATUS_ASSOCIATED) {
242        printk ("Connected successfully!\n");
243        break;
244      }
245      if (i == ASSOCSTATUS_CANNOTCONNECT) {
246        printk ("Could not connect!\n");
247        break;
248      }
249    }
250
251    printk ("Starting daemon\n");
252    softc.tx_id = rtems_bsdnet_newproc ("SCtx", 4096, wifi_txd, &softc);
253    softc.rx_id = rtems_bsdnet_newproc ("SCrx", 4096, wifi_rxd, &softc);
254  }
255
256  ifp->if_flags |= IFF_RUNNING;
257}
258
259/*
260 * wifi deactivation method.
261 */
262
263static void
264wifi_shutdown (void *arg)
265{
266  /* XXX */
267}
268
269/*
270 * ioctl hook function.
271 */
272
273static int
274wifi_ioctl (struct ifnet *ifp, ioctl_command_t command, caddr_t data)
275{
276  void *sc = ifp->if_softc;
277
278  switch (command) {
279  case SIOCGIFADDR:
280  case SIOCSIFADDR:
281    return ether_ioctl (ifp, command, data);
282
283  case SIOCSIFFLAGS:
284    switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
285    case IFF_RUNNING:
286      wifi_shutdown (sc);
287      break;
288    case IFF_UP:
289      wifi_init (sc);
290      break;
291    case IFF_UP | IFF_RUNNING:
292      wifi_shutdown (sc);
293      wifi_init (sc);
294      break;
295    default:
296      break;
297    }
298    return 0;
299
300  default:
301    return EINVAL;
302  }
303}
304
305/*
306 * function for sending a packet
307 */
308
309static void
310wifi_start (struct ifnet *ifp)
311{
312  /* wake up the send daemon */
313  ifp->if_flags |= IFF_OACTIVE;
314  rtems_event_send (softc.tx_id, TRANSMIT_EVENT);
315}
316
317/*
318 * RTEMS device attach method for wiwi driver
319 */
320
321int
322rtems_wifi_driver_attach (struct rtems_bsdnet_ifconfig *config, int attach)
323{
324  struct ifnet *ifp = &softc.arpcom.ac_if;
325
326  printk ("wifi attach...\n");
327
328  /* initialize ifnet structure */
329  memset (&softc, 0, sizeof (softc));
330  ifp->if_softc = &softc;
331  ifp->if_unit = 0;
332  ifp->if_name = "dswifi";
333  ifp->if_mtu = ETHERMTU;
334  ifp->if_init = wifi_init;
335  ifp->if_ioctl = wifi_ioctl;
336  ifp->if_watchdog = NULL;
337  ifp->if_start = wifi_start;
338  ifp->if_output = ether_output;
339  ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
340  if (ifp->if_snd.ifq_maxlen == 0) {
341    ifp->if_snd.ifq_maxlen = ifqmaxlen;
342  }
343
344  if (config->mtu != 0) {
345    ifp->if_mtu = config->mtu;
346  }
347
348  if (config->hardware_address != NULL) {
349    softc.is_hwaddr_set = 1;
350    memcpy (softc.arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN);
351  } else {
352    softc.is_hwaddr_set = 0;
353  }
354
355  u32 Wifi_pass;
356  int i;
357
358  /* wifi hardware initialization took from dswifi example code */
359
360  /* send fifo message to initialize the arm7 wifi */
361  REG_IPC_FIFO_CR = IPC_FIFO_ENABLE | IPC_FIFO_SEND_CLEAR;
362
363  Wifi_pass =
364    Wifi_Init (WIFIINIT_OPTION_USELED | WIFIINIT_OPTION_USECUSTOMALLOC);
365  REG_IPC_FIFO_TX = 0x12345678;
366  REG_IPC_FIFO_TX = Wifi_pass;
367
368  /* setup fifo IRQ */
369  irqSet (IRQ_FIFO_NOT_EMPTY, arm9_fifo);
370  irqEnable (IRQ_FIFO_NOT_EMPTY);
371
372  /* enable FIFO IRQ */
373  REG_IPC_FIFO_CR = IPC_FIFO_ENABLE | IPC_FIFO_RECV_IRQ;
374
375  /* tell wifi lib to use our handler to notify arm7 */
376  Wifi_SetSyncHandler (arm9_synctoarm7);
377
378  /* set timer3 */
379  TIMER3_DATA = -6553;          // 6553.1 * 256 cycles = ~50ms;
380  TIMER3_CR = 0x00C2;           // enable, irq, 1/256 clock
381
382  /* setup timer IRQ */
383  irqSet (IRQ_TIMER3, Timer_50ms);
384  irqEnable (IRQ_TIMER3);
385
386  while (Wifi_CheckInit () == 0) {
387    /* wait for arm7 to be initted successfully */
388    while (REG_VCOUNT > 192);
389    while (REG_VCOUNT < 192);
390  }
391
392  /* wifi init complete - wifi lib can now be used! */
393
394  printk ("ok.\n");
395
396  /* retrieve MAC address if unspecified by the user */
397  if (!softc.is_hwaddr_set) {
398    Wifi_GetData (WIFIGETDATA_MACADDRESS, ETHER_ADDR_LEN,
399                  softc.arpcom.ac_enaddr);
400  }
401
402  print_byte (softc.arpcom.ac_enaddr[0]);
403  for (i = 1; i < ETHER_ADDR_LEN; i++) {
404    printk (":");
405    print_byte (softc.arpcom.ac_enaddr[i]);
406  }
407  printk ("\n");
408
409  /* attach the interface */
410  if_attach (ifp);
411  ether_ifattach (ifp);
412
413  printk ("network device '%s' initialized\n", config->name);
414
415  return 0;
416}
Note: See TracBrowser for help on using the repository browser.