4 * This file contains a wireless device driver for Prism based wireless
7 * Created by Stevens Le Blond <slblond@few.vu.nl>
8 * and Michael Valkering <mjvalker@cs.vu.nl>
10 * * The valid messages and their parameters are:
12 * m_type DL_PORT DL_PROC DL_COUNT DL_MODE DL_ADDR DL_GRANT
13 * |------------+----------+---------+----------+---------+---------+---------|
14 * | HARDINT | | | | | | |
15 * |------------|----------|---------|----------|---------|---------|---------|
16 * | DL_WRITE | port nr | proc nr | count | mode | address | |
17 * |------------|----------|---------|----------|---------|---------|---------|
18 * | DL_WRITEV | port nr | proc nr | count | mode | address | |
19 * |------------|----------|---------|----------|---------|---------|---------|
20 * | DL_WRITEV_S| port nr | proc nr | count | mode | | grant |
21 * |------------|----------|---------|----------|---------|---------|---------|
22 * | DL_READ | port nr | proc nr | count | | address | |
23 * |------------|----------|---------|----------|---------|---------|---------|
24 * | DL_READV | port nr | proc nr | count | | address | |
25 * |------------|----------|---------|----------|---------|---------|---------|
26 * | DL_READV_S | port nr | proc nr | count | | | grant |
27 * |------------|----------|---------|----------|---------|---------|---------|
28 * | DL_CONF | port nr | proc nr | | mode | address | |
29 * |------------|----------|---------|----------|---------|---------|---------|
30 * | DL_GETSTAT | port nr | proc nr | | | address | |
31 * |------------|----------|---------|----------|---------|---------|---------|
32 * |DL_GETSTAT_S| port nr | proc nr | | | | grant |
33 * |------------|----------|---------|----------|---------|---------|---------|
34 * | DL_STOP | port_nr | | | | | |
35 * |------------|----------|---------|----------|---------|---------|---------|
37 * The messages sent are:
39 * m_type DL_PORT DL_PROC DL_COUNT DL_STAT DL_CLCK
40 * |------------|----------|---------|----------|---------|---------|
41 * |DL_TASK_REPL| port nr | proc nr | rd-count | err|stat| clock |
42 * |------------|----------|---------|----------|---------|---------|
44 * m_type m3_i1 m3_i2 m3_ca1
45 * |------------|---------|-----------|---------------|
46 * |DL_CONF_REPL| port nr | last port | ethernet addr |
47 * |------------|---------|-----------|---------------|
49 * m_type DL_PORT DL_STAT
50 * |------------|---------|-----------|
51 * |DL_STAT_REPL| port nr | err |
52 * |------------|---------|-----------|
56 #include "../drivers.h"
59 #include <minix/keymap.h>
60 #include <minix/syslib.h>
61 #include <minix/type.h>
62 #include <minix/sysutil.h>
64 #include <sys/ioc_memory.h>
67 #include <minix/endpoint.h>
68 #include "../../kernel/const.h"
69 #include "../../kernel/config.h"
70 #include "../../kernel/type.h"
72 #define tmra_ut timer_t
73 #define tmra_inittimer(tp) tmr_inittimer(tp)
74 #define VERBOSE 1 /* display message during init */
76 PRIVATE
struct pcitab
{
82 { 0x1260, 0x3873, 0 },
83 { 0x1186, 0x1300, 0 },
88 static tmra_ut or_watchdog
;
92 #include <minix/com.h>
93 #include <minix/portio.h>
95 #include <net/gen/ether.h>
96 #include <net/gen/eth_io.h>
97 #include <sys/vm_i386.h>
98 #include <sys/types.h>
105 #include "hermes_rid.h"
112 #define OR_M_ENABLED 1
113 #define OR_M_DISABLED 0
116 #define OR_F_BROAD (1<<1)
117 #define OR_F_ENABLED (1<<2)
118 #define OR_F_PROMISC (1<<3)
119 #define OR_F_READING (1<<4)
120 #define OR_F_SEND_AVAIL (1<<5)
121 #define OR_F_PACK_SENT (1<<6)
122 #define OR_F_PACK_RECV (1<<7)
123 #define ORINOCO_INTEN ( HERMES_EV_RX | HERMES_EV_ALLOC |\
124 HERMES_EV_WTERR | HERMES_EV_TXEXC|\
125 HERMES_EV_INFO | HERMES_EV_INFDROP|\
134 static int or_nr_task
= ANY
;
135 static t_or or_table
[OR_PORT_NR
];
138 u8_t h_dest
[ETH_ALEN
];
139 u8_t h_src
[ETH_ALEN
];
143 struct header_struct
{
157 #define RUP_EVEN(x) (((x) + 1) & (~1))
159 u8_t encaps_hdr
[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
160 #define ENCAPS_OVERHEAD (sizeof (encaps_hdr) + 2)
162 /********************************************************************
164 ********************************************************************/
166 /* The frequency of each channel in MHz */
167 const long channel_frequency
[] = {
168 2412, 2417, 2422, 2427, 2432, 2437, 2442,
169 2447, 2452, 2457, 2462, 2467, 2472, 2484
172 #define NUM_CHANNELS (sizeof(channel_frequency) / sizeof(channel_frequency[0]))
174 /* This tables gives the actual meanings of the bitrate IDs returned by the
175 * firmware. Not used yet */
177 int bitrate
; /* in 100s of kilobits */
182 {110, 1, 15}, /* Entry 0 is the default */
191 #define BITRATE_TABLE_SIZE (sizeof(bitrate_table) / sizeof(bitrate_table[0]))
194 _PROTOTYPE (static void or_writev
, (message
* mp
, int from_int
, int vectored
));
195 _PROTOTYPE (static void or_readv
, (message
* mp
, int from_int
, int vectored
));
196 _PROTOTYPE (static void or_writev_s
, (message
* mp
, int from_int
));
197 _PROTOTYPE (static void or_readv_s
, (message
* mp
, int from_int
));
198 _PROTOTYPE (static void reply
, (t_or
* orp
, int err
, int may_block
));
199 _PROTOTYPE (static int or_probe
, (t_or
*));
200 _PROTOTYPE (static void or_ev_info
, (t_or
*));
201 _PROTOTYPE (static void or_init
, (message
*));
202 _PROTOTYPE (static void or_pci_conf
, (void));
203 _PROTOTYPE (static void or_init_struct
, (t_or
*));
204 _PROTOTYPE (static void map_hw_buffer
, (t_or
*));
205 _PROTOTYPE (static void or_init_hw
, (t_or
*));
206 _PROTOTYPE (static void or_check_ints
, (t_or
*));
207 _PROTOTYPE (static void or_writerids
, (hermes_t
*, t_or
*));
208 _PROTOTYPE (static void or_readrids
, (hermes_t
*, t_or
*));
209 _PROTOTYPE (static void or_rec_mode
, (t_or
*));
210 _PROTOTYPE (static void mess_reply
, (message
*, message
*));
211 _PROTOTYPE (static u32_t or_get_bar
, (int devind
, t_or
* orp
));
212 _PROTOTYPE (static void or_getstat
, (message
* mp
));
213 _PROTOTYPE (static void or_getstat_s
, (message
* mp
));
214 _PROTOTYPE (static void print_linkstatus
, (t_or
* orp
, u16_t status
));
215 _PROTOTYPE (static int or_get_recvd_packet
, (t_or
*orp
, u16_t rxfid
,
217 _PROTOTYPE (static void orinoco_stop
, (void));
218 _PROTOTYPE (static void or_reset
, (void));
219 _PROTOTYPE (static void or_watchdog_f
, (timer_t
*tp
) );
220 _PROTOTYPE (static void setup_wepkey
, (t_or
*orp
, char *wepkey0
) );
221 _PROTOTYPE (static void or_getstat
, (message
*m
));
222 _PROTOTYPE (static int do_hard_int
, (void));
223 _PROTOTYPE (static void check_int_events
, (void));
224 _PROTOTYPE (static void or_getname
, (message
*m
));
225 _PROTOTYPE (static int or_handler
, (t_or
*orp
));
226 _PROTOTYPE (static void or_dump
, (message
*m
));
228 /* The message used in the main loop is made global, so that rl_watchdog_f()
229 * can change its message type to fake an interrupt message.
232 PRIVATE
int int_event_check
; /* set to TRUE if events arrived */
236 static char *progname
;
239 /* SEF functions and variables. */
240 FORWARD
_PROTOTYPE( void sef_local_startup
, (void) );
241 FORWARD
_PROTOTYPE( int sef_cb_init_fresh
, (int type
, sef_init_info_t
*info
) );
243 EXTERN
char **env_argv
;
245 /*****************************************************************************
249 * The main function of the driver, receiving and processing messages *
250 *****************************************************************************/
251 int main(int argc
, char *argv
[]) {
254 /* SEF local startup. */
255 env_setargs(argc
, argv
);
259 if ((r
= sef_receive (ANY
, &m
)) != OK
)
260 panic(__FILE__
, "orinoco: sef_receive failed", NO_NUM
);
262 if (is_notify(m
.m_type
)) {
263 switch (_ENDPOINT_P(m
.m_source
)) {
279 if (getsigset(&set
) != 0) break;
281 if (sigismember(&set
, SIGTERM
))
288 "orinoco: illegal notify from:",
292 /* done, get new message */
298 or_writev (&m
, FALSE
, TRUE
);
301 or_writev_s (&m
, FALSE
);
304 or_writev (&m
, FALSE
, FALSE
);
307 or_readv (&m
, FALSE
, FALSE
);
310 or_readv (&m
, FALSE
, TRUE
);
313 or_readv_s (&m
, FALSE
);
328 panic(__FILE__
,"orinoco: illegal message:", m
.m_type
);
333 /*===========================================================================*
334 * sef_local_startup *
335 *===========================================================================*/
336 PRIVATE
void sef_local_startup()
338 /* Register init callbacks. */
339 sef_setcb_init_fresh(sef_cb_init_fresh
);
340 sef_setcb_init_restart(sef_cb_init_fresh
);
342 /* No live update support for now. */
344 /* Let SEF perform startup. */
348 /*===========================================================================*
349 * sef_cb_init_fresh *
350 *===========================================================================*/
351 PRIVATE
int sef_cb_init_fresh(int type
, sef_init_info_t
*info
)
353 /* Initialize the orinoco driver. */
354 int fkeys
, sfkeys
, r
;
357 system_hz
= sys_hz();
359 (progname
=strrchr(env_argv
[0],'/')) ? progname
++
360 : (progname
=env_argv
[0]);
362 /* Observe some function key for debug dumps. */
363 fkeys
= sfkeys
= 0; bit_set(sfkeys
, 11);
364 if ((r
=fkey_map(&fkeys
, &sfkeys
)) != OK
)
365 printf("Warning: orinoco couldn't observe F-key(s): %d\n",r
);
367 /* Try to notify INET that we are present (again). If INET cannot
368 * be found, assume this is the first time we started and INET is
370 r
= ds_retrieve_label_num("inet", &inet_proc_nr
);
372 notify(inet_proc_nr
);
374 printf("orinoco: ds_retrieve_label_num failed for 'inet': %d\n", r
);
379 /*****************************************************************************
382 * If a hard interrupt message came in, call the or_check_ints for the right *
384 *****************************************************************************/
385 static void check_int_events(void) {
389 /* the interrupt message doesn't contain information about the port, try
392 orp
< or_table
+ OR_PORT_NR
; orp
++) {
393 if (orp
->or_mode
!= OR_M_ENABLED
)
395 if (!orp
->or_got_int
)
398 assert (orp
->or_flags
& OR_F_ENABLED
);
404 /****************************************************************************
407 * Gets the drivers name, orinoco *
408 ****************************************************************************/
409 static void or_getname(message
*mp
) {
412 strncpy(mp
->DL_NAME
, progname
, sizeof(mp
->DL_NAME
));
413 mp
->DL_NAME
[sizeof(mp
->DL_NAME
) - 1] = '\0';
414 mp
->m_type
= DL_NAME_REPLY
;
416 r
= send(mp
->m_source
, mp
);
418 panic(__FILE__
, "or_getname: send failed", r
);
422 /*****************************************************************************
425 * Process the interrupts which the card generated *
426 *****************************************************************************/
427 static int do_hard_int(void) {
433 for (i
=0; i
< OR_PORT_NR
; i
++) {
434 /* Run interrupt handler at driver level. */
435 or_handler( &or_table
[i
]);
437 /* Reenable interrupts for this hook. */
438 if ((s
=sys_irqenable(&or_table
[i
].or_hook_id
)) != OK
) {
439 printf("orinoco: error, couldn't enable");
440 printf(" interrupts: %d\n", s
);
447 /*****************************************************************************
450 * Stops the card. The signal to the card itself is not implemented yet. *
451 *****************************************************************************/
452 static void orinoco_stop () {
456 for (i
= 0, orp
= &or_table
[0]; i
<OR_PORT_NR
; i
++, orp
++) {
457 if (orp
->or_mode
!= OR_M_ENABLED
)
459 /* TODO: send a signal to the card to shut it down */
464 /*****************************************************************************
467 * Sometime the card gets screwed, behaving erratically. Solution: reset the *
468 * card. This is actually largely redoing the initialization *
469 *****************************************************************************/
470 static void or_reset() {
471 static clock_t last_reset
, now
;
476 if (OK
!= (r
= getuptime(&now
)))
477 panic(__FILE__
, "orinoco: getuptime() failed:", r
);
479 if(now
- last_reset
< system_hz
* 10) {
480 printf("Resetting card too often. Going to reset driver\n");
484 for (i
= 0, orp
= or_table
; orp
< or_table
+ OR_PORT_NR
; i
++, orp
++) {
485 if(orp
->or_mode
== OR_M_DISABLED
)
486 printf("orinoco port %d is disabled\n", i
);
488 if(orp
->or_mode
!= OR_M_ENABLED
) {
492 orp
->or_need_reset
= 0;
495 orp
->rx_last
= orp
->rx_first
= 0;
496 for(j
= 0; j
< NR_RX_BUFS
; j
++) {
497 orp
->rx_length
[0] = 0;
500 if(orp
->or_flags
& OR_F_SEND_AVAIL
) {
501 orp
->or_tx
.ret_busy
= FALSE
;
502 orp
->or_send_int
= TRUE
;
510 /*****************************************************************************
513 * Dump interesting information about the card on F-key pressed. *
514 * Not implemented yet *
515 *****************************************************************************/
516 static void or_dump (message
*m
) {
521 for (i
= 0, orp
= or_table
; orp
< or_table
+ OR_PORT_NR
; i
++, orp
++) {
522 if(orp
->or_mode
== OR_M_DISABLED
) {
523 printf("%s is disabled\n", orp
->or_name
);
526 if(orp
->or_mode
!= OR_M_ENABLED
)
529 m
->m_type
= FKEY_CONTROL
;
530 m
->FKEY_REQUEST
= FKEY_EVENTS
;
531 if(OK
!=(sendrec(TTY_PROC_NR
,m
)) )
532 printf("Contacting the TTY failed\n");
534 if(bit_isset(m
->FKEY_SFKEYS
, 11)) {
535 print_linkstatus(orp
, orp
->last_linkstatus
);
540 /*****************************************************************************
543 * The main initialization function, called when a DL_INIT message comes in. *
544 *****************************************************************************/
545 static void or_init (message
* mp
) {
549 static int first_time
= 1;
555 or_pci_conf (); /* Configure PCI devices. */
557 tmra_inittimer(&or_watchdog
);
558 /* Use a synchronous alarm instead of a watchdog timer. */
559 sys_setalarm(system_hz
, 0);
563 if (port
< 0 || port
>= OR_PORT_NR
) {
564 /* illegal port in message */
565 reply
.m_type
= DL_CONF_REPLY
;
567 mess_reply (mp
, &reply
);
571 /* the port resolves to the main orinoco structure */
572 orp
= &or_table
[port
];
573 /* resolving to the main hardware structure */
576 if (orp
->or_mode
== OR_M_DISABLED
) {
577 /* Initialize the orp structure */
578 or_init_struct (orp
);
579 if (orp
->or_mode
== OR_M_DISABLED
) {
580 reply
.m_type
= DL_CONF_REPLY
;
582 mess_reply (mp
, &reply
);
585 if (orp
->or_mode
== OR_M_ENABLED
) {
586 /* initialize card, hardware/firmware */
587 orp
->or_flags
|= OR_F_ENABLED
;
592 assert (orp
->or_mode
== OR_M_ENABLED
);
593 assert (orp
->or_flags
& OR_F_ENABLED
);
595 /* Not supported by the driver yet, but set a couple of options:
596 * multicasting, promiscuity, broadcasting, depending on the users
598 orp
->or_flags
&= ~(OR_F_PROMISC
| OR_F_MULTI
| OR_F_BROAD
);
599 if (mp
->DL_MODE
& DL_PROMISC_REQ
)
600 orp
->or_flags
|= OR_F_PROMISC
;
601 if (mp
->DL_MODE
& DL_MULTI_REQ
)
602 orp
->or_flags
|= OR_F_MULTI
;
603 if (mp
->DL_MODE
& DL_BROAD_REQ
)
604 orp
->or_flags
|= OR_F_BROAD
;
606 orp
->or_client
= mp
->m_source
;
609 /* reply the caller that the configuration succeeded */
610 reply
.m_type
= DL_CONF_REPLY
;
611 reply
.m3_i1
= mp
->DL_PORT
;
612 reply
.m3_i2
= OR_PORT_NR
;
613 *(ether_addr_t
*) reply
.m3_ca1
= orp
->or_address
;
614 mess_reply (mp
, &reply
);
617 /*****************************************************************************
620 * Configure the pci related issues of the card, e.g. finding out where the *
621 * card is in the pci configuration, it's assigned irq, etc. This can be *
622 * done if the boot monitor is provided with information, or the pci bus *
623 * can be searched (at the end: or_probe function) *
624 *****************************************************************************/
625 static void or_pci_conf () {
629 static char envfmt
[] = "*:d.d.d";
630 static char envvar
[] = OR_ENVVAR
"#";
631 static char val
[128];
633 /* extract information from the boot monitor about the pci
634 * configuration if provided */
635 for (i
= 0, orp
= or_table
; i
< OR_PORT_NR
; i
++, orp
++) {
636 strncpy (orp
->or_name
, OR_NAME
, sizeof(OR_NAME
));
637 orp
->or_name
[sizeof(OR_NAME
) - 2] = i
+ '0';
638 orp
->or_seen
= FALSE
;
639 /* whats this envvar; whats the definition;*/
640 /* i guess this whole loop could be removed*/
641 envvar
[sizeof (OR_ENVVAR
) - 1] = '0' + i
;
642 if (0 == env_get_param(envvar
, val
, sizeof(val
)) &&
643 ! env_prefix(envvar
, "pci")) {
647 (void) env_parse (envvar
, envfmt
, 1, &v
, 0, 255);
650 (void) env_parse (envvar
, envfmt
, 2, &v
, 0, 255);
653 (void) env_parse (envvar
, envfmt
, 3, &v
, 0, 255);
654 orp
->or_pci_func
= v
;
657 /* Initialize the pci bus, bridges and cards, if not yet done */
660 /* Try to find out where the card(s) are in the pci bus */
661 for (h
= 1; h
>= 0; h
--)
662 for (i
= 0, orp
= or_table
; i
< OR_PORT_NR
; i
++, orp
++) {
663 if (((orp
->or_pci_bus
| orp
->or_pci_dev
|
664 orp
->or_pci_func
) != 0) != h
) {
672 /*****************************************************************************
675 * Try to find the card based on information provided by pci and get irq and *
677 *****************************************************************************/
678 static int or_probe (t_or
* orp
) {
680 u32_t bar
, reg
, cpuspace_bar
;
683 int i
, r
, devind
, just_one
;
685 if ((orp
->or_pci_bus
| orp
->or_pci_dev
| orp
->or_pci_func
) != 0) {
686 /* The monitor has provided us with clues about where the
687 * device is. Try to find it at that place */
688 r
= pci_find_dev (orp
->or_pci_bus
, orp
->or_pci_dev
,
689 orp
->or_pci_func
, &devind
);
691 printf ("%s: no PCI found at %d.%d.%d\n",
692 orp
->or_name
, orp
->or_pci_bus
,
693 orp
->or_pci_dev
, orp
->or_pci_func
);
696 /* get the information about the card, vendor id and device
698 pci_ids (devind
, &vid
, &did
);
701 /* no clue where the card is. Start looking from the
703 r
= pci_first_dev (&devind
, &vid
, &did
);
710 /* loop through the pcitab to find a maching entry. The match
711 * being between one of the values in pcitab and the
712 * information provided by the pci bus */
713 for (i
= 0; pcitab
[i
].vid
!= 0; i
++) {
714 if (pcitab
[i
].vid
!= vid
)
716 if (pcitab
[i
].did
!= did
)
718 if (pcitab
[i
].checkclass
) {
719 panic(__FILE__
, "or_probe:class check not implmnted",
722 /* we have found the card in the pci bus */
725 if (pcitab
[i
].vid
!= 0)
729 printf ("%s: wrong PCI device", orp
->or_name
);
730 printf (" (%04x/%04x) found at %d.%d.%d\n", vid
, did
,
731 orp
->or_pci_bus
, orp
->or_pci_dev
,
736 /* if the pci device which was under consideration was not
737 * of the desired brand or type, get the next device */
738 r
= pci_next_dev (&devind
, &vid
, &did
);
743 /* Get the name as advertised by pci */
744 dname
= pci_dev_name (vid
, did
);
746 dname
= "unknown device";
747 printf ("%s: %s (%04x/%04x) at %s\n",
748 orp
->or_name
, dname
, vid
, did
, pci_slot_name (devind
));
750 pci_reserve (devind
);
752 orp
->devind
= devind
;
754 ilr
= pci_attr_r8 (devind
, PCI_ILR
);
757 /* Get the base address */
758 bar
= or_get_bar (devind
, orp
);
759 orp
->or_base_port
= bar
;
765 /*****************************************************************************
768 * Map the memory mapped registers into user space memory *
769 *****************************************************************************/
770 static void map_hw_buffer(t_or
*orp
) {
772 size_t o
, size
, reg_size
;
774 hermes_t
*hw
= &(orp
->hw
);
776 /* This way, the buffer will be at least I386_PAGE_SIZE big: see
777 * calculation with the offset */
778 size
= 2 * I386_PAGE_SIZE
;
780 buf
= (char *)malloc(size
);
782 panic(__FILE__
, "map_hw_buffer: cannot malloc size:", size
);
784 /* Let the mapped memory by I386_PAGE_SIZE aligned */
785 o
= I386_PAGE_SIZE
- ((vir_bytes
)buf
% I386_PAGE_SIZE
);
789 r
= sys_vm_map(SELF
, 1, (vir_bytes
)abuf
,
790 1 * I386_PAGE_SIZE
, (phys_bytes
)orp
->or_base_port
);
796 panic(__FILE__
, "map_hw_buffer: sys_vm_map failed:", r
);
804 /*****************************************************************************
807 * Get the base address from pci (from Base Address Register) and find out *
808 * whether the card is memory mapped or in I/O space. Currently, only *
809 * memmory mapped is supported. *
810 *****************************************************************************/
811 static u32_t
or_get_bar (int devind
, t_or
* orp
) {
813 u32_t bar
, desired_bar
;
816 hermes_t
*hw
= &(orp
->hw
);
818 /* bit 1 off the PCI_BAR register indicates whether the cards registers
819 * are mapped in io-space or shared memory */
820 is_iospace
= pci_attr_r32 (devind
, PCI_BAR
) & 1;
823 /* read where the base address is in I/O space */
824 bar
= pci_attr_r32 (devind
, PCI_BAR
) & 0xffffffe0;
826 if ((bar
& 0x3ff) >= 0x100 - 32 || bar
< 0x400)
827 panic(__FILE__
,"base address isn't properly configured",
830 /* In I/O space registers are 2 bytes wide, without any spacing
832 hermes_struct_init (hw
, bar
, is_iospace
,
833 HERMES_16BIT_REGSPACING
);
836 printf ("%s: using I/O space address 0x%lx, IRQ %d\n",
837 orp
->or_name
, bar
, orp
->or_irq
);
840 panic(__FILE__
, "Not implemente yet", NO_NUM
);
841 /* Although we are able to find the desired bar and irq for an
842 * I/O spaced card, we haven't implemented the right register
843 * accessing functions. This wouldn't be difficult, but we were
844 * not able to test them. Therefore, give an alert here */
848 /* read where the base address is in shared memory */
849 bar
= pci_attr_r32 (devind
, PCI_BAR
) & 0xfffffff0;
850 /* maybe some checking whether the address is legal... */
852 /* Memory mapped registers are 2 bytes wide, aligned on 4
854 hermes_struct_init (hw
, bar
, is_iospace
,
855 HERMES_32BIT_REGSPACING
);
858 printf ("%s: using shared memory address",
860 printf (" 0x%lx, IRQ %d\n", bar
, orp
->or_irq
);
868 /*****************************************************************************
871 * Set the orinoco structure to default values *
872 *****************************************************************************/
873 static void or_init_struct (t_or
* orp
) {
875 static eth_stat_t empty_stat
= { 0, 0, 0, 0, 0, 0 };
877 orp
->or_mode
= OR_M_DISABLED
;
880 orp
->or_mode
= OR_M_ENABLED
;
882 if (orp
->or_mode
!= OR_M_ENABLED
)
886 orp
->or_link_up
= -1;
887 orp
->or_send_int
= 0;
888 orp
->or_clear_rx
= 0;
889 orp
->or_tx_alive
= 0;
890 orp
->or_need_reset
= 0;
897 orp
->or_tx
.ret_busy
= FALSE
;
898 orp
->or_tx
.or_txfid
= NO_FID
;
900 for(i
= 0; i
< NR_RX_BUFS
; i
++) {
901 orp
->rxfid
[i
] = NO_FID
;
902 orp
->rx_length
[i
] = 0;
908 orp
->or_stat
= empty_stat
;
909 orp
->or_flags
= OR_F_EMPTY
;
911 /* Keep an administration in the driver whether the internal
912 buffer is in use. That's what ret_busy is for */
913 orp
->or_tx
.ret_busy
= FALSE
;
915 orp
->or_nicbuf_size
= IEEE802_11_FRAME_LEN
+ ETH_HLEN
;
919 /*****************************************************************************
922 * Initialize hardware and prepare for intercepting the interrupts. At the *
923 * end, the card is up and running *
924 *****************************************************************************/
925 static void or_init_hw (t_or
* orp
) {
927 hermes_t
*hw
= &(orp
->hw
);
928 static int first_time
= TRUE
;
930 /* first step in starting the card */
931 if (hermes_cor_reset(hw
) != 0) {
932 printf ("%s: Failed to start the card\n", orp
->or_name
);
935 /* here begins the real things, yeah! ;) */
936 if (err
= hermes_init (hw
)) {
937 printf ("error value of hermes_init(): %d\n", err
);
940 /* Get the MAC address (which is a data item in the card)*/
941 or_readrids (hw
, orp
);
943 /* Write a few rids to the card, e.g. WEP key*/
944 or_writerids (hw
, orp
);
947 printf ("%s: Ethernet address ", orp
->or_name
);
948 for (i
= 0; i
< 6; i
++) {
949 printf ("%x%c", orp
->or_address
.ea_addr
[i
],
954 /* Prepare internal TX buffer in the card */
955 err
= hermes_allocate (hw
,
957 &(orp
->or_tx
.or_txfid
));
960 printf ("%s:Error %d allocating Tx buffer\n",
963 /* Establish event handle */
965 orp
->or_hook_id
= orp
->or_irq
;
966 if ((s
=sys_irqsetpolicy(orp
->or_irq
, 0,
967 &orp
->or_hook_id
)) != OK
)
968 printf("orinoco: couldn't set IRQ policy: %d\n", s
);
970 if ((s
=sys_irqenable(&orp
->or_hook_id
)) != OK
)
971 printf("orinoco: couldn't enable interrupts: %d\n", s
);
975 /* Tell the card which events should raise an interrupt to the OS */
976 hermes_set_irqmask (hw
, ORINOCO_INTEN
);
978 /* Enable operation */
979 err
= hermes_docmd_wait (hw
, HERMES_CMD_ENABLE
, 0, NULL
);
981 printf ("%s: Error %d enabling MAC port\n", orp
->or_name
, err
);
986 /*****************************************************************************
989 * Read some default rids from the card. A rid (resource identifier) *
990 * is a data item in the firmware, some configuration variable. *
991 * In our case, we are mostly interested in the MAC address for now *
992 *****************************************************************************/
994 static void or_readrids (hermes_t
* hw
, t_or
* orp
) {
996 struct hermes_idstring nickbuf
;
999 /* Read the MAC address */
1000 err
= hermes_read_ltv (hw
, USER_BAP
, HERMES_RID_CNFOWNMACADDR
,
1001 ETH_ALEN
, NULL
, &orp
->or_address
);
1003 printf ("%s: failed to read MAC address!\n", orp
->or_name
);
1009 /*****************************************************************************
1012 * Write some default rids to the card. A rid (resource identifier) *
1013 * is a data item in the firmware, some configuration variable, e.g. WEP key *
1014 *****************************************************************************/
1015 static void or_writerids (hermes_t
* hw
, t_or
* orp
) {
1017 struct hermes_idstring idbuf
;
1018 u16_t port_type
, max_data_len
, reclen
;
1019 static char essid
[IW_ESSID_MAX_SIZE
+ 1];
1020 static char wepkey0
[LARGE_KEY_LENGTH
+ 1];
1022 /* Set the MAC port */
1024 err
= hermes_write_wordrec (hw
, USER_BAP
, HERMES_RID_CNFPORTTYPE
,
1027 printf ("%s: Error %d setting port type\n", orp
->or_name
, err
);
1031 if (OK
!= env_get_param("essid", essid
, sizeof(essid
))) {
1035 if(strlen(essid
) == 0) {
1036 printf("%s: no essid provided in boot monitor!\n",
1038 printf("Hope you'll connect to the right network... \n");
1041 /* Set the desired ESSID */
1042 idbuf
.len
= strlen (essid
);
1043 memcpy (&idbuf
.val
, essid
, sizeof (idbuf
.val
));
1045 err
= hermes_write_ltv (hw
, USER_BAP
, HERMES_RID_CNFDESIREDSSID
,
1046 HERMES_BYTES_TO_RECLEN (strlen (essid
) + 2),
1049 printf ("%s: Error %d setting DESIREDSSID\n",
1054 if (OK
!= env_get_param("wep", wepkey0
, sizeof(wepkey0
))) {
1058 switch(strlen(wepkey0
)) {
1060 /* No key found in monitor, using no encryption */
1062 case LARGE_KEY_LENGTH
:
1063 setup_wepkey(orp
, wepkey0
);
1066 printf("Invalid key provided. Has to be 13 chars\n");
1071 /*****************************************************************************
1074 * If a wepkey is provided in the boot monitor, set the necessary rids so *
1075 * that the card will decrypt received data and encrypt data to send by *
1076 * by default with this key. *
1077 * It appears that there is a severe bug in setting up WEP. If the driver *
1078 * doesnt function properly, please turn WEP off. *
1079 *****************************************************************************/
1080 static void setup_wepkey(t_or
*orp
, char *wepkey0
) {
1081 int default_key
= 0, err
= 0;
1082 hermes_t
*hw
= &(orp
->hw
);
1084 err
= hermes_write_wordrec (hw
, USER_BAP
,
1085 HERMES_RID_CNFWEPDEFAULTKEYID
,
1088 printf ("%s: Error %d setting the default WEP-key entry\n",
1091 err
= hermes_write_ltv (hw
, USER_BAP
,
1092 HERMES_RID_CNFDEFAULTKEY0
,
1093 HERMES_BYTES_TO_RECLEN(LARGE_KEY_LENGTH
),
1096 printf ("%s: Error %d setting the WEP-key0\n",
1099 err
= hermes_write_wordrec (hw
, USER_BAP
,
1100 HERMES_RID_CNFAUTHENTICATION
,
1103 printf ("%s: Error %d setting the authentication flag\n",
1106 err
= hermes_write_wordrec (hw
, USER_BAP
,
1107 HERMES_RID_CNFWEPFLAGS_INTERSIL
,
1108 HERMES_WEP_PRIVACY_INVOKED
);
1110 printf ("%s: Error %d setting the master wep setting flag\n",
1116 /*****************************************************************************
1119 * Set the desired receive mode, e.g. promiscuous mode. Not implemented yet *
1120 *****************************************************************************/
1121 static void or_rec_mode (t_or
* orp
) {
1125 /*****************************************************************************
1128 * The handler which is called when the card generated an interrupt. Events *
1129 * like EV_INFO and EV_RX have to be handled before an acknowledgement for *
1130 * the event is returned to the card. See also the documentation *
1131 *****************************************************************************/
1132 static int or_handler (t_or
*orp
) {
1133 int i
, err
, length
, nr
= 0;
1134 u16_t evstat
, events
, fid
;
1136 struct hermes_tx_descriptor desc
;
1141 /* Retrieve which kind of event happened */
1142 evstat
= hermes_read_reg (hw
, HERMES_EVSTAT
);
1145 /* There are plenty of events possible. The more interesting events
1146 are actually implemented. Whether the following events actually
1147 raise an interrupt depends on the value of ORINOCO_INTEN. For more
1148 information about the events, see the specification in pdf */
1150 /* Occurs at each tick of the auxiliary time */
1151 if (events
& HERMES_EV_TICK
) {
1152 events
&= ~HERMES_EV_TICK
;
1154 /* Occurs when a wait time-out error is detected */
1155 if (events
& HERMES_EV_WTERR
) {
1156 events
&= ~HERMES_EV_WTERR
;
1159 /* Occurs when an info frame is dropped because there is not enough
1160 buffer space available */
1161 if (events
& HERMES_EV_INFDROP
) {
1162 events
&= ~(HERMES_EV_INFDROP
);
1165 /* This AP-only event will be asserted at the beacon interval prior to
1166 the DTIM interval */
1167 if (events
& HERMES_EV_DTIM
) {
1168 events
&= ~(HERMES_EV_DTIM
);
1171 /* Occurs when a command execution is completed */
1172 if (events
& HERMES_EV_CMD
) {
1173 events
&= ~(HERMES_EV_CMD
);
1176 /* Occurs when the asynchronous transmission process is unsuccessfully
1178 if (events
& HERMES_EV_TXEXC
) {
1180 /* What buffer generated the event? Represented by an fid */
1181 fid
= hermes_read_reg(hw
, HERMES_TXCOMPLFID
);
1183 /* Illegal fid found */
1184 printf("unexpected txexc_fid interrupted\n");
1187 orp
->or_tx
.ret_busy
= FALSE
;
1189 if(orp
->or_flags
& OR_F_SEND_AVAIL
) {
1190 orp
->or_send_int
= TRUE
;
1191 if (!orp
->or_got_int
){
1192 orp
->or_got_int
= TRUE
;
1193 int_event_check
= TRUE
;
1197 /* To detect illegal fids */
1198 hermes_write_reg(hw
, HERMES_TXCOMPLFID
, 0xFFFF);
1199 events
&= ~(HERMES_EV_TXEXC
);
1200 /* We don't do anything else yet.
1201 * Could be used for statistics */
1204 /* Occurs when the asynchronous transmission process is successfully
1206 if (events
& HERMES_EV_TX
) {
1207 events
&= ~(HERMES_EV_TX
);
1208 /* Which buffer was sent, represented by an fid */
1209 fid
= hermes_read_reg (hw
, HERMES_TXCOMPLFID
);
1211 /* Illegal fid found */
1212 printf("unexpected tx_fid interrupted\n");
1215 orp
->or_tx
.ret_busy
= FALSE
;
1217 if(orp
->or_flags
& OR_F_SEND_AVAIL
) {
1218 orp
->or_send_int
= TRUE
;
1219 if (!orp
->or_got_int
){
1220 orp
->or_got_int
= TRUE
;
1221 int_event_check
= TRUE
;
1225 /* To detect illegal fids */
1226 hermes_write_reg(hw
, HERMES_TXCOMPLFID
, 0xFFFF);
1227 /* We don't do anything else when such event happens */
1230 /* Occurs when an info frame is available in the card */
1231 if (events
& HERMES_EV_INFO
) {
1232 events
&= ~(HERMES_EV_INFO
);
1233 /* Process the information, inside the handler (!) */
1237 /* Occurs when a TX buffer is available again for usage */
1238 if (events
& HERMES_EV_ALLOC
) {
1239 /* Which frame is now marked as free? */
1240 fid
= hermes_read_reg (hw
, HERMES_ALLOCFID
);
1242 /* An illegal frame identifier is found. Ignore */
1243 printf("Allocate event on unexpected fid\n");
1247 /* To be able to detect illegal fids */
1248 hermes_write_reg(hw
, HERMES_ALLOCFID
, 0xFFFF);
1250 events
&= ~(HERMES_EV_ALLOC
);
1254 /* Occurs when a frame is received by the asynchronous reception
1257 if (events
& HERMES_EV_RX
) {
1258 orp
->or_ev_rx
= TRUE
;
1259 events
&= ~(HERMES_EV_RX
);
1261 /* If the last buffer is still filled with data, then we don't
1262 * have any buffers available to store the data */
1263 if(orp
->rx_length
[orp
->rx_last
] != 0) {
1264 /* indeed, we are going to overwrite information
1268 /* Which buffer is storing the data (represented by a fid) */
1269 orp
->rxfid
[orp
->rx_last
]
1270 = hermes_read_reg (hw
, HERMES_RXFID
);
1272 /* Get the packet from the card and store it in
1273 * orp->rx_buf[orp->rx_last]. The length is returned by this
1275 length
= or_get_recvd_packet(orp
, orp
->rxfid
[orp
->rx_last
],
1276 (orp
->rx_buf
[orp
->rx_last
]));
1279 /* Error happened. */
1280 printf("length < 0\n");
1283 orp
->rx_length
[orp
->rx_last
] = length
;
1286 /* The next buffer will be used the next time, circularly */
1288 orp
->rx_last
%= NR_RX_BUFS
;
1290 if (!orp
->or_got_int
){
1291 orp
->or_got_int
= TRUE
;
1293 int_event_check
= TRUE
;
1297 printf("Unknown event: 0x%x\n", events
);
1300 /* Acknowledge to the card that the events have been processed. After
1301 * this the card will assume we have processed any buffer which were in
1302 * use for this event. */
1303 hermes_write_reg (hw
, HERMES_EVACK
, evstat
);
1305 evstat
= hermes_read_reg (hw
, HERMES_EVSTAT
);
1306 if(evstat
!= 0 && !(evstat
& HERMES_EV_TICK
)) {
1314 /*****************************************************************************
1317 * Will be called regularly to see whether the driver has crashed. If that *
1318 * condition is detected, reset the driver and card *
1319 *****************************************************************************/
1320 static void or_watchdog_f(timer_t
*tp
) {
1324 /* Use a synchronous alarm instead of a watchdog timer. */
1325 sys_setalarm(system_hz
, 0);
1327 for (i
= 0, orp
= &or_table
[0]; i
<OR_PORT_NR
; i
++, orp
++) {
1328 if (orp
->or_mode
!= OR_M_ENABLED
)
1331 if (!(orp
->or_flags
& OR_F_SEND_AVAIL
)) {
1332 /* Assume that an idle system is alive */
1333 orp
->or_tx_alive
= TRUE
;
1337 if (orp
->connected
== 0) {
1338 orp
->or_tx_alive
= TRUE
;
1341 if (orp
->or_tx_alive
) {
1342 orp
->or_tx_alive
= FALSE
;
1346 printf("or_watchdog_f: resetting port %d\n", i
);
1348 orp
->or_need_reset
= TRUE
;
1349 orp
->or_got_int
= TRUE
;
1354 /*****************************************************************************
1356 *****************************************************************************/
1358 static void mess_reply (message
* req
, message
* reply_mess
) {
1359 if (send (req
->m_source
, reply_mess
) != 0)
1360 panic(__FILE__
, "orinoco: unable to mess_reply", NO_NUM
);
1364 /*****************************************************************************
1367 * As far as we can see, this function is never called from 3.1.3. However, *
1368 * it is still in rtl8139, so we'll keep it here as well. It's almost a copy *
1369 * of or_writev_s. We left out the comments. For an explanation, see *
1371 ******************************************************************************/
1372 static void or_writev (message
* mp
, int from_int
, int vectored
) {
1373 int port
, or_client
, count
, size
, err
, data_len
, data_off
, tx_head
;
1374 int o
, j
, n
, i
, s
, p
, cps
;
1377 clock_t timebefore
, t0
;
1378 phys_bytes phys_user
;
1380 struct hermes_tx_descriptor desc
;
1381 struct header_struct hdr
;
1384 phys_bytes phys_databuf
;
1386 static u8_t databuf
[IEEE802_11_DATA_LEN
+ ETH_HLEN
+ 2 + 1];
1387 memset (databuf
, 0, IEEE802_11_DATA_LEN
+ ETH_HLEN
+ 3);
1390 count
= mp
->DL_COUNT
;
1391 if (port
< 0 || port
>= OR_PORT_NR
)
1392 panic(__FILE__
, "orinoco: illegal port", NO_NUM
);
1394 or_client
= mp
->DL_PROC
;
1395 orp
= &or_table
[port
];
1396 orp
->or_client
= or_client
;
1400 assert (orp
->or_flags
& OR_F_SEND_AVAIL
);
1401 orp
->or_flags
&= ~OR_F_SEND_AVAIL
;
1402 orp
->or_send_int
= FALSE
;
1403 orp
->or_tx_alive
= TRUE
;
1406 if (orp
->or_tx
.ret_busy
) {
1407 assert(!(orp
->or_flags
& OR_F_SEND_AVAIL
));
1408 orp
->or_flags
|= OR_F_SEND_AVAIL
;
1412 assert (orp
->or_mode
== OR_M_ENABLED
);
1413 assert (orp
->or_flags
& OR_F_ENABLED
);
1421 for (i
= 0; i
< count
; i
+= IOVEC_NR
,
1422 iov_offset
+= IOVEC_NR
* sizeof (orp
->or_iovec
[0])) {
1427 cps
= sys_vircopy(or_client
, D
,
1428 ((vir_bytes
) mp
->DL_ADDR
) + iov_offset
,
1429 SELF
, D
, (vir_bytes
) orp
->or_iovec
,
1430 n
* sizeof(orp
->or_iovec
[0]));
1431 if (cps
!= OK
) printf("sys_vircopy failed: %d\n", cps
);
1433 for (j
= 0, iovp
= orp
->or_iovec
; j
< n
; j
++, iovp
++) {
1435 if (size
+ s
> ETH_MAX_PACK_SIZE_TAGGED
) {
1436 printf("invalid packet size\n");
1438 cps
= sys_vircopy(or_client
, D
, iovp
->iov_addr
,
1439 SELF
, D
, (vir_bytes
) databuf
+ o
, s
);
1441 printf("sys_vircopy failed: %d\n",cps
);
1447 if (size
< ETH_MIN_PACK_SIZE
)
1448 printf("invalid packet size %d\n", size
);
1450 size
= mp
->DL_COUNT
;
1451 if (size
< ETH_MIN_PACK_SIZE
1452 || size
> ETH_MAX_PACK_SIZE_TAGGED
)
1453 printf("invalid packet size %d\n", size
);
1455 cps
= sys_vircopy(or_client
, D
, (vir_bytes
)mp
->DL_ADDR
,
1456 SELF
, D
, (vir_bytes
) databuf
, size
);
1457 if (cps
!= OK
) printf("sys_abscopy failed: %d\n", cps
);
1460 memset (&desc
, 0, sizeof (desc
));
1461 desc
.tx_control
= HERMES_TXCTRL_TX_OK
| HERMES_TXCTRL_TX_EX
;
1463 err
= hermes_bap_pwrite (hw
, USER_BAP
, &desc
, sizeof (desc
), txfid
,
1470 eh
= (struct ethhdr
*) databuf
;
1471 if (ntohs (eh
->h_proto
) > 1500) {
1473 data_len
= size
- ETH_HLEN
;
1474 data_off
= HERMES_802_3_OFFSET
+ sizeof (hdr
);
1476 memcpy (hdr
.dest
, eh
->h_dest
, ETH_ALEN
);
1477 memcpy (hdr
.src
, eh
->h_src
, ETH_ALEN
);
1478 hdr
.len
= htons (data_len
+ ENCAPS_OVERHEAD
);
1480 memcpy (&hdr
.dsap
, &encaps_hdr
, sizeof (encaps_hdr
));
1481 hdr
.ethertype
= eh
->h_proto
;
1483 err
= hermes_bap_pwrite (hw
, USER_BAP
, &hdr
, sizeof (hdr
),
1484 txfid
, HERMES_802_3_OFFSET
);
1486 printf ("%s: Error %d writing packet header to BAP\n",
1493 data_len
= size
+ ETH_HLEN
;
1494 data_off
= HERMES_802_3_OFFSET
;
1498 err
= hermes_bap_pwrite (hw
, USER_BAP
,
1499 (void *) &(databuf
[p
]), RUP_EVEN (data_len
),
1502 printf ("hermes_bap_pwrite(data): error %d\n", err
);
1506 orp
->or_tx
.ret_busy
= TRUE
;
1508 err
= hermes_docmd_wait (hw
, HERMES_CMD_TX
| HERMES_CMD_RECL
,
1511 orp
->or_tx
.ret_busy
= FALSE
;
1512 printf ("hermes_docmd_wait(TX|RECL): error %d\n", err
);
1517 orp
->or_flags
|= OR_F_PACK_SENT
;
1523 reply (orp
, OK
, FALSE
);
1527 orp
->or_tx_mess
= *mp
;
1528 reply (orp
, OK
, FALSE
);
1534 /*****************************************************************************
1537 * Write data which is denoted by the message to the card and send it. *
1538 *****************************************************************************/
1539 static void or_writev_s (message
* mp
, int from_int
) {
1540 int port
, or_client
, count
, size
, err
, data_len
, data_off
, tx_head
;
1541 int o
, j
, n
, i
, s
, p
, cps
;
1544 clock_t timebefore
, t0
;
1545 phys_bytes phys_user
;
1547 struct hermes_tx_descriptor desc
;
1549 struct header_struct hdr
;
1551 phys_bytes phys_databuf
;
1554 /* We need space for the max packet size itself, plus an ethernet
1555 * header, plus 2 bytes so we can align the IP header on a
1556 * 32bit boundary, plus 1 byte so we can read in odd length
1557 * packets from the card, which has an IO granularity of 16
1559 static u8_t databuf
[IEEE802_11_DATA_LEN
+ ETH_HLEN
+ 2 + 1];
1560 memset (databuf
, 0, IEEE802_11_DATA_LEN
+ ETH_HLEN
+ 3);
1563 count
= mp
->DL_COUNT
;
1564 if (port
< 0 || port
>= OR_PORT_NR
)
1565 panic(__FILE__
, "orinoco: illegal port", NO_NUM
);
1567 or_client
= mp
->DL_PROC
;
1568 orp
= &or_table
[port
];
1569 orp
->or_client
= or_client
;
1572 /* Switch off interrupts. The card is accessable via 2 BAPs, one for
1573 * reading and one for writing. In theory these BAPs should be
1574 * independent, but in practice, the are not. By switching off the
1575 * interrupts of the card, the chances of one interfering with the
1576 * other should be less */
1578 /* We were called with from_int, meaning that the last time we
1579 * were called, no tx buffers were available, and we had to
1580 * suspend. Now, we'll try again to find an empty buffer in the
1582 assert (orp
->or_flags
& OR_F_SEND_AVAIL
);
1583 orp
->or_flags
&= ~OR_F_SEND_AVAIL
;
1584 orp
->or_send_int
= FALSE
;
1585 orp
->or_tx_alive
= TRUE
;
1588 txfid
= orp
->or_tx
.or_txfid
;
1590 if (orp
->or_tx
.ret_busy
|| orp
->connected
== 0) {
1591 /* there is no buffer in the card available */
1592 assert(!(orp
->or_flags
& OR_F_SEND_AVAIL
));
1593 /* Remember that there is a packet to be sent available */
1594 orp
->or_flags
|= OR_F_SEND_AVAIL
;
1595 goto suspend_write_s
;
1598 assert (orp
->or_mode
== OR_M_ENABLED
);
1599 assert (orp
->or_flags
& OR_F_ENABLED
);
1602 /* Copy the data to be send from the vector to the databuf */
1605 for (i
= 0; i
< count
; i
+= IOVEC_NR
,
1606 iov_offset
+= IOVEC_NR
* sizeof (orp
->or_iovec_s
[0])) {
1612 cps
= sys_safecopyfrom(or_client
, mp
->DL_GRANT
, iov_offset
,
1613 (vir_bytes
) orp
->or_iovec_s
,
1614 n
* sizeof(orp
->or_iovec_s
[0]), D
);
1616 printf("orinoco: sys_safecopyfrom failed: %d\n", cps
);
1618 for (j
= 0, iovp
= orp
->or_iovec_s
; j
< n
; j
++, iovp
++) {
1620 if (size
+ s
> ETH_MAX_PACK_SIZE_TAGGED
) {
1621 printf("Orinoco: invalid pkt size\n");
1624 cps
= sys_safecopyfrom(or_client
, iovp
->iov_grant
, 0,
1625 (vir_bytes
) databuf
+ o
, s
, D
);
1627 printf("orinoco: sys_safecopyfrom failed:%d\n",
1635 assert(size
>= ETH_MIN_PACK_SIZE
);
1637 memset (&desc
, 0, sizeof (desc
));
1638 /* Reclaim the tx buffer once the data is sent (OK), or it is clear
1639 * that transmission failed (EX). Reclaiming means that we can reuse
1640 * the buffer again for transmission */
1641 desc
.tx_control
= HERMES_TXCTRL_TX_OK
| HERMES_TXCTRL_TX_EX
;
1642 /* Actually, this reclaim bit is the only thing which needs to be set
1643 * in the descriptor */
1644 err
= hermes_bap_pwrite (hw
, USER_BAP
, &desc
, sizeof (desc
), txfid
,
1647 printf("hermes_bap_pwrite() descriptor error:resetting card\n");
1648 /* When this happens, the card is quite confused: it will not
1649 * recover. Reset it */
1654 eh
= (struct ethhdr
*) databuf
;
1655 /* Encapsulate Ethernet-II frames */
1656 if (ntohs (eh
->h_proto
) > 1500) {
1657 /* Ethernet-II frame */
1658 data_len
= size
- ETH_HLEN
;
1659 data_off
= HERMES_802_3_OFFSET
+ sizeof (hdr
);
1662 memcpy (hdr
.dest
, eh
->h_dest
, ETH_ALEN
);
1663 memcpy (hdr
.src
, eh
->h_src
, ETH_ALEN
);
1664 hdr
.len
= htons (data_len
+ ENCAPS_OVERHEAD
);
1667 memcpy (&hdr
.dsap
, &encaps_hdr
, sizeof (encaps_hdr
));
1668 hdr
.ethertype
= eh
->h_proto
;
1670 err
= hermes_bap_pwrite (hw
, USER_BAP
, &hdr
, sizeof (hdr
),
1671 txfid
, HERMES_802_3_OFFSET
);
1673 printf ("%s: Error %d writing packet header to BAP\n",
1680 /* IEEE 802.3 frame */
1681 data_len
= size
+ ETH_HLEN
;
1682 data_off
= HERMES_802_3_OFFSET
;
1686 /* Round up for odd length packets */
1687 err
= hermes_bap_pwrite (hw
, USER_BAP
,
1688 (void *) &(databuf
[p
]), RUP_EVEN (data_len
),
1691 printf ("hermes_bap_pwrite(data): error %d\n", err
);
1695 /* this should be before the docmd_wait. Cause otherwise the bit can
1696 be cleared in the handler (if irq's not off) before it is set
1697 and then 1 reset (ret_busy=false) is lost */
1698 orp
->or_tx
.ret_busy
= TRUE
;
1700 /* Send the packet which was constructed in txfid */
1701 err
= hermes_docmd_wait (hw
, HERMES_CMD_TX
| HERMES_CMD_RECL
,
1704 printf ("hermes_docmd_wait(TX|RECL): error %d\n", err
);
1705 /* Mark the buffer as available again */
1706 orp
->or_tx
.ret_busy
= FALSE
;
1711 /* If the interrupt handler called, don't send a reply. The reply
1712 * will be sent after all interrupts are handled.
1714 orp
->or_flags
|= OR_F_PACK_SENT
;
1720 reply (orp
, OK
, FALSE
);
1724 orp
->or_tx_mess
= *mp
;
1726 reply (orp
, OK
, FALSE
);
1731 /*****************************************************************************
1734 * Send a message back to the caller, informing it about the data received *
1736 *****************************************************************************/
1737 static void reply (t_or
* orp
, int err
, int may_block
) {
1742 if (orp
->or_flags
& OR_F_PACK_SENT
)
1743 status
|= DL_PACK_SEND
;
1744 if (orp
->or_flags
& OR_F_PACK_RECV
)
1745 status
|= DL_PACK_RECV
;
1747 reply
.m_type
= DL_TASK_REPLY
;
1748 reply
.DL_PORT
= orp
- or_table
;
1749 assert(reply
.DL_PORT
== 0);
1750 reply
.DL_PROC
= orp
->or_client
;
1751 reply
.DL_STAT
= status
| ((u32_t
) err
<< 16);
1752 reply
.DL_COUNT
= orp
->or_read_s
;
1754 if (OK
!= (r
= getuptime(&now
)))
1755 panic(__FILE__
, "orinoco: getuptime() failed:", r
);
1757 reply
.DL_CLCK
= now
;
1758 r
= send (orp
->or_client
, &reply
);
1760 if (r
== ELOCKED
&& may_block
) {
1765 panic(__FILE__
, "orinoco: send failed:", r
);
1768 orp
->or_flags
&= ~(OR_F_PACK_SENT
| OR_F_PACK_RECV
);
1773 /*****************************************************************************
1776 * Process information which comes in from the card *
1777 *****************************************************************************/
1778 static void or_ev_info (t_or
* orp
) {
1780 int err
, len
, type
, i
;
1781 hermes_t
*hw
= &orp
->hw
;
1788 infofid
= hermes_read_reg (hw
, HERMES_INFOFID
);
1789 err
= hermes_bap_pread (hw
, IRQ_BAP
, &info
, sizeof (info
), infofid
,
1792 printf ("%s: error %d reading info frame.\n", orp
->or_name
,
1797 len
= HERMES_RECLEN_TO_BYTES (info
.len
);
1801 case HERMES_INQ_TALLIES
:
1803 struct hermes_tallies_frame tallies
;
1805 if (len
> sizeof (tallies
)) {
1806 printf ("%s: Tallies frame too long ",
1808 printf ("(%d bytes)\n", len
);
1809 len
= sizeof (tallies
);
1811 hermes_read_words (hw
, HERMES_DATA1
,
1812 (void *) &tallies
, len
/ 2);
1813 /* TODO: do something with the tallies structure */
1817 case HERMES_INQ_LINKSTATUS
: {
1819 struct hermes_linkstatus linkstatus
;
1821 if (len
!= sizeof (linkstatus
)) {
1822 printf ("%s: Unexpected size for linkstatus ",
1824 printf ("frame (%d bytes)\n", len
);
1827 hermes_read_words (hw
, HERMES_DATA1
,
1828 (void *) &linkstatus
, len
/ 2);
1829 newstatus
= linkstatus
.linkstatus
;
1831 if ((newstatus
== HERMES_LINKSTATUS_CONNECTED
)
1832 || (newstatus
== HERMES_LINKSTATUS_AP_CHANGE
)
1833 || (newstatus
== HERMES_LINKSTATUS_AP_IN_RANGE
)) {
1836 if(orp
->or_flags
& OR_F_SEND_AVAIL
) {
1837 orp
->or_send_int
= TRUE
;
1838 orp
->or_got_int
= TRUE
;
1839 int_event_check
= TRUE
;
1844 else if ((newstatus
==
1845 HERMES_LINKSTATUS_NOT_CONNECTED
)
1847 HERMES_LINKSTATUS_DISCONNECTED
)
1849 HERMES_LINKSTATUS_AP_OUT_OF_RANGE
)
1851 HERMES_LINKSTATUS_ASSOC_FAILED
)) {
1855 if (newstatus
!= orp
->last_linkstatus
)
1856 print_linkstatus(orp
, newstatus
);
1858 orp
->last_linkstatus
= newstatus
;
1862 printf ("%s:Unknown information frame received(type %04x).\n",
1863 orp
->or_name
, type
);
1868 /*****************************************************************************
1869 * or_print_linkstatus *
1871 * Process information which comes in from the card *
1872 *****************************************************************************/
1873 static void print_linkstatus (t_or
* orp
, u16_t status
) {
1877 hermes_t
*hw
= &(orp
->hw
);
1880 case HERMES_LINKSTATUS_NOT_CONNECTED
:
1881 s
= "Not Connected";
1883 case HERMES_LINKSTATUS_CONNECTED
:
1886 case HERMES_LINKSTATUS_DISCONNECTED
:
1889 case HERMES_LINKSTATUS_AP_CHANGE
:
1892 case HERMES_LINKSTATUS_AP_OUT_OF_RANGE
:
1893 s
= "AP Out of Range";
1895 case HERMES_LINKSTATUS_AP_IN_RANGE
:
1898 case HERMES_LINKSTATUS_ASSOC_FAILED
:
1899 s
= "Association Failed";
1905 printf ("%s: link status: %s, ", orp
->or_name
, s
);
1907 err
= hermes_read_wordrec (hw
, USER_BAP
,
1908 HERMES_RID_CURRENTCHANNEL
, &d
);
1910 printf ("%s: Error %d \n", orp
->or_name
, err
);
1913 printf("channel: %d, freq: %d MHz ",
1914 d
, (channel_frequency
[d
-1]));
1919 /*****************************************************************************
1922 * Process events which have been postponed in the interrupt handler *
1923 *****************************************************************************/
1924 static void or_check_ints (t_or
* orp
) {
1926 hermes_t
*hw
= &orp
->hw
;
1928 if (orp
->or_need_reset
)
1930 if ((orp
->rx_first
!=orp
->rx_last
) && (orp
->or_flags
& OR_F_READING
)) {
1932 if (orp
->or_rx_mess
.m_type
== DL_READV
) {
1933 or_readv (&orp
->or_rx_mess
, TRUE
, TRUE
);
1934 } else if(orp
->or_rx_mess
.m_type
== DL_READV_S
) {
1935 or_readv_s (&orp
->or_rx_mess
, TRUE
);
1937 assert(orp
->or_rx_mess
.m_type
== DL_READ
);
1938 or_readv (&orp
->or_rx_mess
, TRUE
, FALSE
);
1942 if (orp
->or_send_int
) {
1943 if (orp
->or_tx_mess
.m_type
== DL_WRITEV
) {
1944 or_writev (&orp
->or_tx_mess
, TRUE
, TRUE
);
1946 else if(orp
->or_tx_mess
.m_type
== DL_WRITEV_S
) {
1947 or_writev_s (&orp
->or_tx_mess
, TRUE
);
1949 assert(orp
->or_tx_mess
.m_type
== DL_WRITE
);
1950 or_writev (&orp
->or_tx_mess
, TRUE
, FALSE
);
1954 if (orp
->or_flags
& (OR_F_PACK_SENT
| OR_F_PACK_RECV
)) {
1955 reply (orp
, OK
, TRUE
);
1960 /*****************************************************************************
1963 * is there an LLC and SNAP header in the ethernet packet? The inet task *
1964 * isn't very interested in it... *
1965 *****************************************************************************/
1966 static int is_ethersnap(struct header_struct
*hdr
) {
1968 /* We de-encapsulate all packets which, a) have SNAP headers
1969 * (i.e. SSAP=DSAP=0xaa and CTRL=0x3 in the 802.2 LLC header
1970 * and where b) the OUI of the SNAP header is 00:00:00 or
1971 * 00:00:f8 - we need both because different APs appear to use
1972 * different OUIs for some reason */
1973 return (memcmp(&hdr
->dsap
, &encaps_hdr
, 5) == 0)
1974 && ( (hdr
->oui
[2] == 0x00) || (hdr
->oui
[2] == 0xf8) );
1977 /*****************************************************************************
1980 * As far as we can see, this function is never called from 3.1.3. However, *
1981 * it is still in rtl8139, so we'll keep it here as well. It's almost a copy *
1982 * of or_readv_s. We left out the comments. For an explanation, see *
1984 *****************************************************************************/
1985 static void or_readv (message
* mp
, int from_int
, int vectored
) {
1986 int i
, j
, n
, o
, s
, s1
, dl_port
, or_client
, count
, size
, err
, yep
, cps
;
1989 unsigned amount
, totlen
, packlen
;
1990 struct hermes_rx_descriptor desc
;
1991 phys_bytes dst_phys
;
1992 u16_t d_start
, d_end
, rxfid
, status
;
1993 struct header_struct hdr
;
1997 struct header_struct
*h
;
2003 dl_port
= mp
->DL_PORT
;
2004 count
= mp
->DL_COUNT
;
2005 if (dl_port
< 0 || dl_port
>= OR_PORT_NR
)
2006 panic(__FILE__
, "orinoco: illegal port:", dl_port
);
2008 orp
= &or_table
[dl_port
];
2009 or_client
= mp
->DL_PROC
;
2010 orp
->or_client
= or_client
;
2013 assert (orp
->or_mode
== OR_M_ENABLED
);
2014 assert (orp
->or_flags
& OR_F_ENABLED
);
2016 if (!from_int
&& (orp
->rx_first
==orp
->rx_last
)) {
2020 rxfid
= orp
->rxfid
[orp
->rx_first
];
2021 databuf
= &(orp
->rx_buf
[orp
->rx_first
][0]);
2022 length
= orp
->rx_length
[orp
->rx_first
];
2024 orp
->rxfid
[orp
->rx_first
] = NO_FID
;
2025 orp
->rx_length
[orp
->rx_first
] = 0;
2028 orp
->rx_first
%= NR_RX_BUFS
;
2036 for (i
= 0; i
< count
; i
+= IOVEC_NR
,
2037 iov_offset
+= IOVEC_NR
* sizeof(orp
->or_iovec
[0])) {
2043 cps
= sys_vircopy(or_client
, D
,
2044 (vir_bytes
) mp
->DL_ADDR
+ iov_offset
,
2045 SELF
, D
, (vir_bytes
) orp
->or_iovec
,
2046 n
* sizeof(orp
->or_iovec
[0]));
2047 if (cps
!= OK
) printf("sys_vircopy failed: %d (%d)\n",
2050 for (j
= 0, iovp
= orp
->or_iovec
; j
< n
; j
++, iovp
++) {
2052 if (size
+ s
> length
) {
2053 assert (length
> size
);
2057 cps
= sys_vircopy(SELF
, D
,
2058 (vir_bytes
) databuf
+ o
,
2062 printf("sys_vircopy failed:%d (%d)\n",
2073 assert (size
>= length
);
2076 orp
->or_stat
.ets_packetR
++;
2077 orp
->or_read_s
= length
;
2078 orp
->or_flags
&= ~OR_F_READING
;
2079 orp
->or_flags
|= OR_F_PACK_RECV
;
2082 reply (orp
, OK
, FALSE
);
2088 assert (orp
->or_flags
& OR_F_READING
);
2092 orp
->or_rx_mess
= *mp
;
2093 assert (!(orp
->or_flags
& OR_F_READING
));
2094 orp
->or_flags
|= OR_F_READING
;
2096 reply (orp
, OK
, FALSE
);
2100 /*****************************************************************************
2103 * Copy the data which is stored in orp->rx_buf[orp->rx_first] in the vector *
2104 * which was given with the message *mp *
2105 *****************************************************************************/
2106 static void or_readv_s (message
* mp
, int from_int
) {
2107 int i
, j
, n
, o
, s
, s1
, dl_port
, or_client
, count
, size
, err
, cps
;
2108 int iov_offset
= 0, length
, offset
;
2111 unsigned amount
, totlen
, packlen
;
2112 struct hermes_rx_descriptor desc
;
2113 phys_bytes dst_phys
;
2114 u16_t d_start
, d_end
, rxfid
, status
;
2115 struct header_struct hdr
;
2118 struct header_struct
*h
;
2123 phys_bytes databuf_phys
;
2127 dl_port
= mp
->DL_PORT
;
2128 count
= mp
->DL_COUNT
;
2129 if (dl_port
< 0 || dl_port
>= OR_PORT_NR
)
2130 panic(__FILE__
, "orinoco: illegal port:", dl_port
);
2132 orp
= &or_table
[dl_port
];
2133 or_client
= mp
->DL_PROC
;
2134 orp
->or_client
= or_client
;
2137 assert (orp
->or_mode
== OR_M_ENABLED
);
2138 assert (orp
->or_flags
& OR_F_ENABLED
);
2140 if (!from_int
&& (orp
->rx_first
==orp
->rx_last
))
2143 /* if we are not called from a hard int (data is not yet available) and
2144 * there are no buffers (or->rx_buf[x]) which contain any data, we cant
2145 * copy any data to the inet server. Goto suspend, and wait for data
2147 goto suspend_readv_s
;
2152 /* get the buffer which contains new data */
2153 rxfid
= orp
->rxfid
[orp
->rx_first
];
2154 /* and store the pointer to this data in databuf */
2155 databuf
= &(orp
->rx_buf
[orp
->rx_first
][0]);
2156 length
= orp
->rx_length
[orp
->rx_first
];
2158 orp
->rxfid
[orp
->rx_first
] = NO_FID
;
2159 orp
->rx_length
[orp
->rx_first
] = 0;
2161 /* Next time, the next buffer with data will be retrieved */
2163 orp
->rx_first
%= NR_RX_BUFS
;
2166 /* The data which we want to be copied to the vector starts at
2167 * *databuf and will be copied to the vecor below */
2169 for (i
= 0; i
< count
; i
+= IOVEC_NR
,
2170 iov_offset
+= IOVEC_NR
* sizeof(orp
->or_iovec_s
[0])) {
2175 cps
= sys_safecopyfrom(or_client
, mp
->DL_GRANT
, iov_offset
,
2176 (vir_bytes
)orp
->or_iovec_s
,
2177 n
* sizeof(orp
->or_iovec_s
[0]), D
);
2180 "orinoco: warning, sys_safecopytp failed:", cps
);
2182 for (j
= 0, iovp
= orp
->or_iovec_s
; j
< n
; j
++, iovp
++) {
2184 if (size
+ s
> length
) {
2185 assert (length
> size
);
2188 cps
= sys_safecopyto(or_client
, iovp
->iov_grant
, 0,
2189 (vir_bytes
) databuf
+ o
, s
, D
);
2192 "orinoco: warning, sys_safecopy failed:",
2204 assert(size
>= length
);
2206 orp
->or_stat
.ets_packetR
++;
2208 orp
->or_read_s
= length
;
2209 orp
->or_flags
&= ~OR_F_READING
;
2210 orp
->or_flags
|= OR_F_PACK_RECV
;
2213 /* There was data in the orp->rx_buf[x] which is now copied to
2214 * the inet sever. Tell the inet server */
2215 reply (orp
, OK
, FALSE
);
2221 assert (orp
->or_flags
& OR_F_READING
);
2222 /* No need to store any state */
2226 /* We want to store the message, so that next time when we are called
2227 * by hard int, we know where to copy the received data */
2228 orp
->or_rx_mess
= *mp
;
2229 assert (!(orp
->or_flags
& OR_F_READING
));
2230 orp
->or_flags
|= OR_F_READING
;
2232 reply (orp
, OK
, FALSE
);
2237 /*****************************************************************************
2238 * or_get_recvd_packet *
2240 * The card has received data. Retrieve the data from the card and put it *
2241 * in a buffer in the driver (in the orp structure) *
2242 *****************************************************************************/
2243 static int or_get_recvd_packet(t_or
*orp
, u16_t rxfid
, u8_t
*databuf
) {
2244 struct hermes_rx_descriptor desc
;
2246 struct header_struct hdr
;
2247 int err
, length
, offset
;
2251 memset(databuf
, 0, IEEE802_11_FRAME_LEN
);
2255 /* Read the data from the buffer in the card which holds the data.
2256 * First get the descriptor which will tell us whether the packet is
2258 err
= hermes_bap_pread (hw
, IRQ_BAP
, &desc
, sizeof (desc
), rxfid
, 0);
2260 printf("Orinoco: error %d reading Rx descriptor. "
2261 "Frame dropped\n", err
);
2262 orp
->or_stat
.ets_recvErr
++;
2266 status
= desc
.status
;
2268 if (status
& HERMES_RXSTAT_ERR
) {
2269 if (status
& HERMES_RXSTAT_UNDECRYPTABLE
) {
2270 printf("Error reading Orinoco Rx descriptor.Dropped");
2272 orp
->or_stat
.ets_CRCerr
++;
2273 printf("Orinoco: Bad CRC on Rx. Frame dropped\n");
2275 orp
->or_stat
.ets_recvErr
++;
2279 /* For now we ignore the 802.11 header completely, assuming
2280 that the card's firmware has handled anything vital. The only
2281 thing we want to know is the length of the received data */
2282 err
= hermes_bap_pread (hw
, IRQ_BAP
, &hdr
, sizeof (hdr
),
2283 rxfid
, HERMES_802_3_OFFSET
);
2286 printf("Orinoco: error %d reading frame header. "
2287 "Frame dropped\n", err
);
2288 orp
->or_stat
.ets_recvErr
++;
2292 length
= ntohs (hdr
.len
);
2296 /* No for even an 802.2 LLC header */
2297 printf("Orinoco: error in frame length: length = %d\n",
2299 /* orp->or_stat.ets_recvErr++; */
2303 if (length
> IEEE802_11_DATA_LEN
) {
2304 printf("Orinoco: Oversized frame received (%d bytes)\n",
2306 orp
->or_stat
.ets_recvErr
++;
2310 length
+= sizeof (struct ethhdr
);
2311 offset
= HERMES_802_3_OFFSET
;
2313 /* Read the interesting parts of the data to the drivers memory. This
2314 * would be everything from the 802.3 layer and up */
2315 err
= hermes_bap_pread (hw
,
2316 IRQ_BAP
, (void *) databuf
, RUP_EVEN (length
),
2320 printf("Orinoco: error doing hermes_bap_pread()\n");
2321 orp
->or_stat
.ets_recvErr
++;
2325 /* Some types of firmware give us the SNAP and OUI headers. Remove these.
2327 if (is_ethersnap(&hdr
)) {
2328 eh
= (struct ethhdr
*) databuf
;
2332 memcpy (databuf
+ ETH_ALEN
* 2,
2333 databuf
+ sizeof(struct header_struct
) - 2,
2334 length
- ETH_ALEN
* 2);
2337 if(length
<60) length
=60;
2342 /*****************************************************************************
2345 * Return the statistics structure. The statistics aren't updated until now, *
2346 * so this won't return much interesting yet. *
2347 *****************************************************************************/
2348 static void or_getstat (message
* mp
) {
2354 if (port
< 0 || port
>= OR_PORT_NR
)
2355 panic(__FILE__
, "orinoco: illegal port:", port
);
2356 orp
= &or_table
[port
];
2357 orp
->or_client
= mp
->DL_PROC
;
2359 assert (orp
->or_mode
== OR_M_ENABLED
);
2360 assert (orp
->or_flags
& OR_F_ENABLED
);
2362 stats
= orp
->or_stat
;
2364 r
= sys_datacopy(SELF
, (vir_bytes
)&stats
, mp
->DL_PROC
,
2365 (vir_bytes
) mp
->DL_ADDR
, sizeof(stats
));
2367 panic(__FILE__
, "or_getstat: send failed:", r
);
2370 mp
->m_type
= DL_STAT_REPLY
;
2374 r
= send(mp
->m_source
, mp
);
2376 panic(__FILE__
, "orinoco: getstat failed:", r
);
2378 /*reply (orp, OK, FALSE);*/
2382 /*****************************************************************************
2385 * Return the statistics structure. The statistics aren't updated until now, *
2386 * so this won't return much interesting yet. *
2387 *****************************************************************************/
2388 static void or_getstat_s (message
* mp
) {
2394 if (port
< 0 || port
>= OR_PORT_NR
)
2395 panic(__FILE__
, "orinoco: illegal port:", port
);
2397 orp
= &or_table
[port
];
2398 orp
->or_client
= mp
->DL_PROC
;
2400 assert (orp
->or_mode
== OR_M_ENABLED
);
2401 assert (orp
->or_flags
& OR_F_ENABLED
);
2403 stats
= orp
->or_stat
;
2405 r
= sys_safecopyto(mp
->DL_PROC
, mp
->DL_GRANT
, 0,
2406 (vir_bytes
) &stats
, sizeof(stats
), D
);
2408 panic(__FILE__
, "or_getstat_s: sys_safecopyto failed:", r
);
2411 mp
->m_type
= DL_STAT_REPLY
;
2415 r
= send(mp
->m_source
, mp
);
2417 panic(__FILE__
, "orinoco: getstat_s failed:", r
);