root/dev/pcmcia/if_ray.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ray_match
  2. ray_attach
  3. ray_activate
  4. ray_detach
  5. ray_enable
  6. ray_disable
  7. ray_init
  8. ray_stop
  9. ray_reset
  10. ray_reset_resetloop
  11. ray_power
  12. ray_shutdown
  13. ray_ioctl
  14. ray_if_start
  15. ray_media_change
  16. ray_media_status
  17. ray_intr_start
  18. ray_recv
  19. ray_recv_auth
  20. ray_send_auth
  21. ray_find_free_tx_ccs
  22. ray_fill_in_tx_ccs
  23. ray_update_params_done
  24. ray_check_scheduled
  25. ray_check_ccs
  26. ray_update_error_counters
  27. ray_ccs_done
  28. ray_rccs_intr
  29. ray_intr
  30. ray_free_ccs_chain
  31. ray_free_ccs
  32. ray_alloc_ccs
  33. ray_set_pending
  34. ray_cmd_schedule
  35. ray_cmd_is_scheduled
  36. ray_cmd_cancel
  37. ray_cmd_ran
  38. ray_cmd_is_running
  39. ray_cmd_done
  40. ray_issue_cmd
  41. ray_simple_cmd
  42. ray_update_subcmd
  43. ray_report_params
  44. ray_start_assoc
  45. ray_download_params
  46. ray_start_join_net
  47. ray_start_join_timo
  48. ray_start_join_net_done
  49. ray_update_promisc
  50. ray_update_params
  51. ray_update_mcast
  52. ray_user_update_params
  53. ray_user_report_params
  54. ray_read_region
  55. ray_write_region
  56. hexdump
  57. ray_dump_mbuf
  58. ray_update_siglev

    1 /*      $OpenBSD: if_ray.c,v 1.34 2006/08/18 08:17:07 jsg Exp $ */
    2 /*      $NetBSD: if_ray.c,v 1.21 2000/07/05 02:35:54 onoe Exp $ */
    3 
    4 /*
    5  * Copyright (c) 2000 Christian E. Hopps
    6  * All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. Neither the name of the author nor the names of any co-contributors
   17  *    may be used to endorse or promote products derived from this software
   18  *    without specific prior written permission.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   30  * SUCH DAMAGE.
   31  */
   32 
   33 /*
   34  * Driver for the Raylink (Raytheon) / WebGear IEEE 802.11 (FH) WLANs
   35  *
   36  *      2-way communication with the card is through command structures
   37  *      stored in shared ram.  To communicate with the card a free
   38  *      command structure is filled in and then the card is interrupted.
   39  *      The card does the same with a different set of command structures.
   40  *      Only one command can be processed at a time.  This is indicated
   41  *      by the interrupt having not been cleared since it was last set.
   42  *      The bit is cleared when the command has been processed (although
   43  *      it may not yet be complete).
   44  *
   45  *      This driver was only tested with the Aviator 2.4 wireless
   46  *      The author didn't have the pro version or raylink to test
   47  *      with.
   48  *
   49  *      N.B. Its unclear yet whether the Aviator 2.4 cards interoperate
   50  *      with other 802.11 FH 2Mbps cards, since this was also untested.
   51  *      Given the nature of the buggy build 4 firmware there may be problems.
   52  */
   53 
   54 /* Authentication added by Steve Weiss <srw@alum.mit.edu> based on advice
   55  * received by Corey Thomas, author of the Linux driver for this device.
   56  * Authentication currently limited to adhoc networks, and was added to
   57  * support a requirement of the newest windows drivers, so that 
   58  * interoperability the windows will remain possible. 
   59  *
   60  * Tested with Win98 using Aviator 2.4 Pro cards, firmware 5.63, 
   61  * but no access points for infrastructure.    (July 13, 2000 -srw)
   62  */
   63 
   64 #include "bpfilter.h"
   65 
   66 #include <sys/param.h>
   67 #include <sys/systm.h>
   68 #include <sys/timeout.h>
   69 #include <sys/mbuf.h>
   70 #include <sys/socket.h>
   71 #include <sys/ioctl.h>
   72 #include <sys/errno.h>
   73 #include <sys/device.h>
   74 #include <sys/kernel.h>
   75 #include <sys/proc.h>
   76 
   77 #include <net/if.h>
   78 #include <net/if_dl.h>
   79 #include <net/if_media.h>
   80 #include <net/if_llc.h>
   81 
   82 #ifdef INET
   83 #include <netinet/in.h>
   84 #include <netinet/in_systm.h>
   85 #include <netinet/in_var.h>
   86 #include <netinet/ip.h>
   87 #include <netinet/if_ether.h>
   88 #endif
   89 
   90 #include <net80211/ieee80211.h>
   91 #include <net80211/ieee80211_ioctl.h>
   92 
   93 #if NBPFILTER > 0
   94 #include <net/bpf.h>
   95 #endif
   96 
   97 #include <machine/cpu.h>
   98 #include <machine/bus.h>
   99 #include <machine/intr.h>
  100 
  101 #include <dev/pcmcia/pcmciareg.h>
  102 #include <dev/pcmcia/pcmciavar.h>
  103 #include <dev/pcmcia/pcmciadevs.h>
  104 
  105 #include <dev/pcmcia/if_rayreg.h>
  106 
  107 #ifndef PCMCIA_WIDTH_MEM8
  108 #define PCMCIA_WIDTH_MEM8       0
  109 #endif
  110 
  111 #ifndef offsetof
  112 #define offsetof(type, member)  ((size_t)(&((type *)0)->member))
  113 #endif
  114 
  115 /*#define       RAY_DEBUG*/
  116 
  117 #ifndef RAY_PID_COUNTRY_CODE_DEFAULT
  118 #define RAY_PID_COUNTRY_CODE_DEFAULT    RAY_PID_COUNTRY_CODE_USA
  119 #endif
  120 
  121 /* amount of time to poll for non-return of certain command status */
  122 #ifndef RAY_CHECK_CCS_TIMEOUT
  123 #define RAY_CHECK_CCS_TIMEOUT   (hz / 2)
  124 #endif
  125 
  126 /* amount of time to consider start/join failed */
  127 #ifndef RAY_START_TIMEOUT
  128 #define RAY_START_TIMEOUT       (10 * hz)
  129 #endif
  130 
  131 /* reset reschedule timeout */
  132 #ifndef RAY_RESET_TIMEOUT
  133 #define RAY_RESET_TIMEOUT       (10 * hz)
  134 #endif
  135 
  136 /*
  137  * if a command cannot execute because device is busy try later
  138  * this is also done after interrupts and other command timeouts
  139  * so we can use a large value safely.
  140  */
  141 #ifndef RAY_CHECK_SCHED_TIMEOUT
  142 #define RAY_CHECK_SCHED_TIMEOUT (hz)    /* XXX 5 */
  143 #endif
  144 
  145 #ifndef RAY_MODE_DEFAULT
  146 #define RAY_MODE_DEFAULT        SC_MODE_ADHOC
  147 #endif
  148 
  149 #ifndef RAY_DEF_NWID
  150 #define RAY_DEF_NWID    "NETWORK_NAME"
  151 #endif
  152 
  153 /*
  154  * The number of times the HW is reset in 30s before disabling.
  155  * This is needed because resets take ~2s and currently pcmcia
  156  * spins for the reset.
  157  */
  158 #ifndef RAY_MAX_RESETS
  159 #define RAY_MAX_RESETS  10
  160 #endif
  161 
  162 /*
  163  * Types
  164  */
  165 
  166 struct ray_softc {
  167         struct device   sc_dev;
  168         struct arpcom sc_ec;
  169         struct ifmedia  sc_media;
  170 
  171         struct pcmcia_function          *sc_pf;
  172         struct pcmcia_mem_handle        sc_mem;
  173         int                             sc_window;
  174         void                            *sc_ih;
  175         void                            *sc_sdhook;
  176         void                            *sc_pwrhook;
  177         int                             sc_flags;
  178 #define RAY_FLAGS_RESUMEINIT    0x01
  179 #define RAY_FLAGS_ATTACHED      0x02
  180         int                             sc_resetloop;
  181 
  182         struct timeout                  sc_check_ccs_ch;
  183         struct timeout                  sc_check_scheduled_ch;
  184         struct timeout                  sc_reset_resetloop_ch;
  185         struct timeout                  sc_disable_ch;
  186         struct timeout                  sc_start_join_timo_ch;
  187 #define callout_stop    timeout_del
  188 #define callout_reset(t,n,f,a)  timeout_add((t), (n))
  189 
  190         struct ray_ecf_startup          sc_ecf_startup;
  191         struct ray_startup_params_head  sc_startup;
  192         union {
  193                 struct ray_startup_params_tail_5        u_params_5;
  194                 struct ray_startup_params_tail_4        u_params_4;
  195         } sc_u;
  196 
  197         u_int8_t        sc_ccsinuse[64];        /* ccs in use -- not for tx */
  198         u_int           sc_txfree;      /* a free count for efficiency */
  199 
  200         u_int8_t        sc_bssid[ETHER_ADDR_LEN];       /* current net values */
  201         u_int8_t        sc_authid[ETHER_ADDR_LEN];      /* id of authenticating station */
  202         struct ieee80211_nwid   sc_cnwid;       /* last nwid */
  203         struct ieee80211_nwid   sc_dnwid;       /* desired nwid */
  204         u_int8_t        sc_omode;       /* old operating mode SC_MODE_xx */
  205         u_int8_t        sc_mode;        /* current operating mode SC_MODE_xx */
  206         u_int8_t        sc_countrycode; /* current country code */
  207         u_int8_t        sc_dcountrycode; /* desired country code */
  208         int             sc_havenet;     /* true if we have acquired a network */
  209         bus_size_t      sc_txpad;       /* tib size plus "phy" size */
  210         u_int8_t        sc_deftxrate;   /* default transfer rate */
  211         u_int8_t        sc_encrypt;
  212         u_int8_t        sc_authstate;   /* authentication state */
  213 
  214         int             sc_promisc;     /* current set value */
  215         int             sc_running;     /* things we are doing */
  216         int             sc_scheduled;   /* things we need to do */
  217         int             sc_timoneed;    /* set if timeout is sched */
  218         int             sc_timocheck;   /* set if timeout is sched */
  219         bus_size_t      sc_startccs;    /* ccs of start/join */
  220         u_int           sc_startcmd;    /* cmd (start | join) */
  221 
  222         int             sc_checkcounters;
  223         u_int64_t       sc_rxoverflow;
  224         u_int64_t       sc_rxcksum;
  225         u_int64_t       sc_rxhcksum;
  226         u_int8_t        sc_rxnoise;
  227 
  228         /* use to return values to the user */
  229         struct ray_param_req    *sc_repreq;
  230         struct ray_param_req    *sc_updreq;
  231 #ifdef RAY_DO_SIGLEV
  232         struct ray_siglev       sc_siglevs[RAY_NSIGLEVRECS];
  233 #endif
  234 };
  235 #define sc_memt sc_mem.memt
  236 #define sc_memh sc_mem.memh
  237 #define sc_ccrt sc_pf->pf_ccrt
  238 #define sc_ccrh sc_pf->pf_ccrh
  239 #define sc_ccroff       sc_pf->pf_ccr_offset
  240 #define sc_startup_4    sc_u.u_params_4
  241 #define sc_startup_5    sc_u.u_params_5
  242 #define sc_version      sc_ecf_startup.e_fw_build_string
  243 #define sc_tibsize      sc_ecf_startup.e_tib_size
  244 #define sc_if           sc_ec.ac_if
  245 #define ec_multicnt     ac_multicnt
  246 #define memmove         memcpy          /* XXX */
  247 #define sc_xname        sc_dev.dv_xname
  248 
  249 /* modes of operation */
  250 #define SC_MODE_ADHOC   0       /* ad-hoc mode */
  251 #define SC_MODE_INFRA   1       /* infrastructure mode */
  252 
  253 /* commands -- priority given to LSB */
  254 #define SCP_FIRST               0x0001
  255 #define SCP_UPDATESUBCMD        0x0001
  256 #define SCP_STARTASSOC          0x0002
  257 #define SCP_REPORTPARAMS        0x0004
  258 #define SCP_IFSTART             0x0008
  259 
  260 /* update sub commands -- issues are serialized priority to LSB */
  261 #define SCP_UPD_FIRST           0x0100
  262 #define SCP_UPD_STARTUP         0x0100
  263 #define SCP_UPD_STARTJOIN       0x0200
  264 #define SCP_UPD_PROMISC         0x0400
  265 #define SCP_UPD_MCAST           0x0800
  266 #define SCP_UPD_UPDATEPARAMS    0x1000
  267 #define SCP_UPD_SHIFT           8
  268 #define SCP_UPD_MASK            0xff00
  269 
  270 /* these command (a subset of the update set) require timeout checking */
  271 #define SCP_TIMOCHECK_CMD_MASK  \
  272         (SCP_UPD_UPDATEPARAMS | SCP_UPD_STARTUP | SCP_UPD_MCAST | \
  273         SCP_UPD_PROMISC)
  274 
  275 
  276 #define IFM_ADHOC       \
  277         IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_FH2, IFM_IEEE80211_ADHOC, 0)
  278 #define IFM_INFRA       \
  279         IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_FH2, 0, 0)
  280 
  281 typedef void (*ray_cmd_func_t)(struct ray_softc *);
  282 
  283 #define SC_BUILD_5      0x5
  284 #define SC_BUILD_4      0x55
  285 
  286 /* values for sc_authstate */
  287 #define RAY_AUTH_UNAUTH (0)
  288 #define RAY_AUTH_WAITING (1)
  289 #define RAY_AUTH_AUTH (2)
  290 #define RAY_AUTH_NEEDED (3)
  291 
  292 #define OPEN_AUTH_REQUEST (1)
  293 #define OPEN_AUTH_RESPONSE (2)
  294 #define BROADCAST_DEAUTH (0xc0)
  295 
  296 /* prototypes */
  297 int ray_alloc_ccs(struct ray_softc *, bus_size_t *, u_int, u_int);
  298 bus_size_t ray_fill_in_tx_ccs(struct ray_softc *, size_t, u_int, u_int);
  299 void ray_attach(struct device *, struct device *, void *);
  300 ray_cmd_func_t ray_ccs_done(struct ray_softc *, bus_size_t);
  301 void ray_check_ccs(void *);
  302 void ray_check_scheduled(void *);
  303 void ray_cmd_cancel(struct ray_softc *, int);
  304 void ray_cmd_schedule(struct ray_softc *, int);
  305 void ray_cmd_ran(struct ray_softc *, int);
  306 int ray_cmd_is_running(struct ray_softc *, int);
  307 int ray_cmd_is_scheduled(struct ray_softc *, int);
  308 void ray_cmd_done(struct ray_softc *, int);
  309 int ray_detach(struct device *, int);
  310 int ray_activate(struct device *, enum devact);
  311 void ray_disable(struct ray_softc *);
  312 void ray_download_params(struct ray_softc *);
  313 int ray_enable(struct ray_softc *);
  314 u_int ray_find_free_tx_ccs(struct ray_softc *, u_int);
  315 u_int8_t ray_free_ccs(struct ray_softc *, bus_size_t);
  316 void ray_free_ccs_chain(struct ray_softc *, u_int);
  317 void ray_if_start(struct ifnet *);
  318 int ray_init(struct ray_softc *);
  319 int ray_intr(void *);
  320 void ray_intr_start(struct ray_softc *);
  321 int ray_ioctl(struct ifnet *, u_long, caddr_t);
  322 int ray_issue_cmd(struct ray_softc *, bus_size_t, u_int);
  323 int ray_match(struct device *, struct cfdata *, void *);
  324 int ray_media_change(struct ifnet *);
  325 void ray_media_status(struct ifnet *, struct ifmediareq *);
  326 void ray_power(int, void *);
  327 ray_cmd_func_t ray_rccs_intr(struct ray_softc *, bus_size_t);
  328 void ray_recv(struct ray_softc *, bus_size_t);
  329 void ray_recv_auth(struct ray_softc *,struct ieee80211_frame*);
  330 void ray_report_params(struct ray_softc *);
  331 void ray_reset(struct ray_softc *);
  332 void ray_reset_resetloop(void *);
  333 int ray_send_auth(struct ray_softc *, u_int8_t *, u_int8_t);
  334 void ray_set_pending(struct ray_softc *, u_int);
  335 void ray_shutdown(void *);
  336 int ray_simple_cmd(struct ray_softc *, u_int, u_int);
  337 void ray_start_assoc(struct ray_softc *);
  338 void ray_start_join_net(struct ray_softc *);
  339 ray_cmd_func_t ray_start_join_net_done(struct ray_softc *,
  340     u_int, bus_size_t, u_int);
  341 void ray_start_join_timo(void *);
  342 void ray_stop(struct ray_softc *);
  343 void ray_update_error_counters(struct ray_softc *);
  344 void ray_update_mcast(struct ray_softc *);
  345 ray_cmd_func_t ray_update_params_done(struct ray_softc *,
  346     bus_size_t, u_int);
  347 void ray_update_params(struct ray_softc *);
  348 void ray_update_promisc(struct ray_softc *);
  349 void ray_update_subcmd(struct ray_softc *);
  350 int ray_user_report_params(struct ray_softc *,
  351     struct ray_param_req *);
  352 int ray_user_update_params(struct ray_softc *,
  353     struct ray_param_req *);
  354 
  355 #define ray_read_region(sc,off,p,c) \
  356         bus_space_read_region_1((sc)->sc_memt, (sc)->sc_memh, (off), (p), (c))
  357 #define ray_write_region(sc,off,p,c) \
  358         bus_space_write_region_1((sc)->sc_memt, (sc)->sc_memh, (off), (p), (c))
  359 
  360 #ifdef RAY_DO_SIGLEV
  361 void ray_update_siglev(struct ray_softc *, u_int8_t *, u_int8_t);
  362 #endif
  363 
  364 #ifdef RAY_DEBUG
  365 int ray_debug = 0;
  366 int ray_debug_xmit_sum = 0;
  367 int ray_debug_dump_desc = 0;
  368 int ray_debug_dump_rx = 0;
  369 int ray_debug_dump_tx = 0;
  370 struct timeval rtv, tv1, tv2, *ttp, *ltp;
  371 #define RAY_DPRINTF(x)  do { if (ray_debug) {   \
  372         struct timeval *tmp;                    \
  373         microtime(ttp);                         \
  374         timersub(ttp, ltp, &rtv);               \
  375         tmp = ttp; ttp = ltp; ltp = tmp;        \
  376         printf("%ld:%ld %ld:%06ld: ", ttp->tv_sec, ttp->tv_usec, rtv.tv_sec, rtv.tv_usec);      \
  377         printf x ;                              \
  378         } } while (0)
  379 #define RAY_DPRINTF_XMIT(x)     do { if (ray_debug_xmit_sum) {  \
  380         struct timeval *tmp;                    \
  381         microtime(ttp);                         \
  382         timersub(ttp, ltp, &rtv);               \
  383         tmp = ttp; ttp = ltp; ltp = tmp;        \
  384         printf("%ld:%ld %ld:%06ld: ", ttp->tv_sec, ttp->tv_usec, rtv.tv_sec, rtv.tv_usec);      \
  385         printf x ;                              \
  386         } } while (0)
  387 
  388 #define HEXDF_NOCOMPRESS        0x1
  389 #define HEXDF_NOOFFSET          0x2
  390 #define HEXDF_NOASCII           0x4
  391 void hexdump(const u_int8_t *, int, int, int, int);
  392 void ray_dump_mbuf(struct ray_softc *, struct mbuf *);
  393 
  394 #else   /* !RAY_DEBUG */
  395 
  396 #define RAY_DPRINTF(x)
  397 #define RAY_DPRINTF_XMIT(x)
  398 
  399 #endif  /* !RAY_DEBUG */
  400 
  401 /*
  402  * macros for writing to various regions in the mapped memory space
  403  */
  404 
  405         /* use already mapped ccrt */
  406 #define REG_WRITE(sc, off, val) \
  407         bus_space_write_1((sc)->sc_ccrt, (sc)->sc_ccrh, \
  408         ((sc)->sc_ccroff + (off)), (val))
  409 
  410 #define REG_READ(sc, off) \
  411         bus_space_read_1((sc)->sc_ccrt, (sc)->sc_ccrh, \
  412         ((sc)->sc_ccroff + (off)))
  413 
  414 #define SRAM_READ_1(sc, off) \
  415         ((u_int8_t)bus_space_read_1((sc)->sc_memt, (sc)->sc_memh, (off)))
  416 
  417 #define SRAM_READ_FIELD_1(sc, off, s, f) \
  418         SRAM_READ_1(sc, (off) + offsetof(struct s, f))
  419 
  420 #define SRAM_READ_FIELD_2(sc, off, s, f)                        \
  421         ((((u_int16_t)SRAM_READ_1(sc, (off) + offsetof(struct s, f)) << 8) \
  422         |(SRAM_READ_1(sc, (off) + 1 + offsetof(struct s, f)))))
  423 
  424 #define SRAM_READ_FIELD_N(sc, off, s, f, p, n)  \
  425         ray_read_region(sc, (off) + offsetof(struct s, f), (p), (n))
  426 
  427 #define SRAM_WRITE_1(sc, off, val)      \
  428         bus_space_write_1((sc)->sc_memt, (sc)->sc_memh, (off), (val))
  429 
  430 #define SRAM_WRITE_FIELD_1(sc, off, s, f, v)    \
  431         SRAM_WRITE_1(sc, (off) + offsetof(struct s, f), (v))
  432 
  433 #define SRAM_WRITE_FIELD_2(sc, off, s, f, v) do {       \
  434         SRAM_WRITE_1(sc, (off) + offsetof(struct s, f), (((v) >> 8 ) & 0xff)); \
  435         SRAM_WRITE_1(sc, (off) + 1 + offsetof(struct s, f), ((v) & 0xff)); \
  436     } while (0)
  437 
  438 #define SRAM_WRITE_FIELD_N(sc, off, s, f, p, n) \
  439         ray_write_region(sc, (off) + offsetof(struct s, f), (p), (n))
  440 
  441 /*
  442  * Macros of general usefulness
  443  */
  444 
  445 #define M_PULLUP(m, s) do {     \
  446         if ((m)->m_len < (s))   \
  447                 (m) = m_pullup((m), (s)); \
  448     } while (0)
  449 
  450 #define RAY_ECF_READY(sc)       (!(REG_READ(sc, RAY_ECFIR) & RAY_ECSIR_IRQ))
  451 #define RAY_ECF_START_CMD(sc)   REG_WRITE(sc, RAY_ECFIR, RAY_ECSIR_IRQ)
  452 #define RAY_GET_INDEX(ccs)      (((ccs) - RAY_CCS_BASE) / RAY_CCS_SIZE)
  453 #define RAY_GET_CCS(i)          (RAY_CCS_BASE + (i) * RAY_CCS_SIZE)
  454 
  455 /*
  456  * Globals
  457  */
  458 
  459 static const u_int8_t llc_snapid[6] = { LLC_SNAP_LSAP, LLC_SNAP_LSAP, LLC_UI };
  460 
  461 /* based on bit index in SCP_xx */
  462 static const ray_cmd_func_t ray_cmdtab[] = {
  463         ray_update_subcmd,      /* SCP_UPDATESUBCMD */
  464         ray_start_assoc,        /* SCP_STARTASSOC */
  465         ray_report_params,      /* SCP_REPORTPARAMS */
  466         ray_intr_start          /* SCP_IFSTART */
  467 };
  468 static const int ray_ncmdtab = sizeof(ray_cmdtab) / sizeof(*ray_cmdtab);
  469 
  470 static const ray_cmd_func_t ray_subcmdtab[] = {
  471         ray_download_params,    /* SCP_UPD_STARTUP */
  472         ray_start_join_net,     /* SCP_UPD_STARTJOIN */
  473         ray_update_promisc,     /* SCP_UPD_PROMISC */
  474         ray_update_mcast,       /* SCP_UPD_MCAST */
  475         ray_update_params       /* SCP_UPD_UPDATEPARAMS */
  476 };
  477 static const int ray_nsubcmdtab = sizeof(ray_subcmdtab) / sizeof(*ray_subcmdtab);
  478 
  479 struct cfdriver ray_cd = {
  480         NULL, "ray", DV_IFNET
  481 };
  482 
  483 /* autoconf information */
  484 struct cfattach ray_ca = {
  485         sizeof(struct ray_softc), (cfmatch_t)ray_match, ray_attach, ray_detach,
  486         ray_activate
  487 };
  488 
  489 
  490 /*
  491  * Config Routines
  492  */
  493 
  494 int
  495 ray_match(struct device *parent, struct cfdata *match, void *aux)
  496 {
  497         struct pcmcia_attach_args *pa = aux;
  498 
  499 #ifdef RAY_DEBUG
  500         if (!ltp) {
  501                 /* initialize timestamp XXX */
  502                 ttp = &tv1;
  503                 ltp = &tv2;
  504                 microtime(ltp);
  505         }
  506 #endif
  507         return (pa->manufacturer == PCMCIA_VENDOR_RAYTHEON
  508             && pa->product == PCMCIA_PRODUCT_RAYTHEON_WLAN);
  509 }
  510 
  511 
  512 void
  513 ray_attach(struct device *parent, struct device *self, void *aux)
  514 {
  515         struct ray_ecf_startup *ep;
  516         struct pcmcia_attach_args *pa;
  517         struct ray_softc *sc;
  518         struct ifnet *ifp;
  519         bus_size_t memoff;
  520 
  521         pa = aux;
  522         sc = (struct ray_softc *)self;
  523         sc->sc_pf = pa->pf;
  524         ifp = &sc->sc_if;
  525         sc->sc_window = -1;
  526 
  527         printf("\n");
  528 
  529         /* enable the card */
  530         pcmcia_function_init(sc->sc_pf, SIMPLEQ_FIRST(&sc->sc_pf->cfe_head));
  531         if (pcmcia_function_enable(sc->sc_pf)) {
  532                 printf(": failed to enable the card");
  533                 return;
  534         }
  535 
  536         /*
  537          * map in the memory
  538          */
  539         if (pcmcia_mem_alloc(sc->sc_pf, RAY_SRAM_MEM_SIZE, &sc->sc_mem)) {
  540                 printf(": can\'t alloc shared memory\n");
  541                 goto fail;
  542         }
  543 
  544         if (pcmcia_mem_map(sc->sc_pf, PCMCIA_WIDTH_MEM8|PCMCIA_MEM_COMMON,
  545             RAY_SRAM_MEM_BASE, RAY_SRAM_MEM_SIZE, &sc->sc_mem, &memoff,
  546             &sc->sc_window)) {
  547                 printf(": can\'t map shared memory\n");
  548                 pcmcia_mem_free(sc->sc_pf, &sc->sc_mem);
  549                 goto fail;
  550         }
  551 
  552         /* get startup results */
  553         ep = &sc->sc_ecf_startup;
  554         ray_read_region(sc, RAY_ECF_TO_HOST_BASE, ep,
  555             sizeof(sc->sc_ecf_startup));
  556 
  557         /* check to see that card initialized properly */
  558         if (ep->e_status != RAY_ECFS_CARD_OK) {
  559                 printf(": card failed self test: status %d\n",
  560                     sc->sc_ecf_startup.e_status);
  561                 goto fail;
  562         }
  563 
  564         /* check firmware version */
  565         if (sc->sc_version != SC_BUILD_4 && sc->sc_version != SC_BUILD_5) {
  566                 printf(": unsupported firmware version %d\n",
  567                     ep->e_fw_build_string);
  568                 goto fail;
  569         }
  570 
  571         /* clear any interrupt if present */
  572         REG_WRITE(sc, RAY_HCSIR, 0);
  573 
  574         /*
  575          * set the parameters that will survive stop/init
  576          */
  577         memset(&sc->sc_dnwid, 0, sizeof(sc->sc_dnwid));
  578         sc->sc_dnwid.i_len = strlen(RAY_DEF_NWID);
  579         if (sc->sc_dnwid.i_len > IEEE80211_NWID_LEN)
  580                 sc->sc_dnwid.i_len = IEEE80211_NWID_LEN;
  581         if (sc->sc_dnwid.i_len > 0)
  582                 memcpy(sc->sc_dnwid.i_nwid, RAY_DEF_NWID, sc->sc_dnwid.i_len);
  583         memcpy(&sc->sc_cnwid, &sc->sc_dnwid, sizeof(sc->sc_cnwid));
  584         sc->sc_omode = sc->sc_mode = RAY_MODE_DEFAULT;
  585         sc->sc_countrycode = sc->sc_dcountrycode =
  586             RAY_PID_COUNTRY_CODE_DEFAULT;
  587         sc->sc_flags &= ~RAY_FLAGS_RESUMEINIT;
  588 
  589         timeout_set(&sc->sc_check_ccs_ch, ray_check_ccs, sc);
  590         timeout_set(&sc->sc_check_scheduled_ch, ray_check_scheduled, sc);
  591         timeout_set(&sc->sc_reset_resetloop_ch, ray_reset_resetloop, sc);
  592         timeout_set(&sc->sc_disable_ch, (void (*)(void *))ray_disable, sc);
  593         timeout_set(&sc->sc_start_join_timo_ch, ray_start_join_timo, sc);
  594 
  595         /*
  596          * attach the interface
  597          */
  598         /* The version isn't the most accurate way, but it's easy. */
  599         printf("%s: firmware version %d, ", sc->sc_dev.dv_xname,
  600             sc->sc_version);
  601 #ifdef RAY_DEBUG
  602         if (sc->sc_version != SC_BUILD_4)
  603                 printf("supported rates %0x:%0x:%0x:%0x:%0x:%0x:%0x:%0x, ",
  604                     ep->e_rates[0], ep->e_rates[1],
  605                     ep->e_rates[2], ep->e_rates[3], ep->e_rates[4],
  606                     ep->e_rates[5], ep->e_rates[6], ep->e_rates[7]);
  607 #endif
  608         printf("address %s\n",  ether_sprintf(ep->e_station_addr));
  609 
  610         memcpy(ifp->if_xname, sc->sc_xname, IFNAMSIZ);
  611         ifp->if_softc = sc;
  612         ifp->if_start = ray_if_start;
  613         ifp->if_ioctl = ray_ioctl;
  614         ifp->if_mtu = ETHERMTU;
  615         ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST;
  616         IFQ_SET_READY(&ifp->if_snd);
  617         if_attach(ifp);
  618         memcpy(&sc->sc_ec.ac_enaddr, ep->e_station_addr, ETHER_ADDR_LEN);
  619         ether_ifattach(ifp);
  620 
  621         /* need enough space for ieee80211_header + (snap or e2) */
  622         ifp->if_hdrlen =
  623             sizeof(struct ieee80211_frame) + sizeof(struct ether_header);
  624 
  625         ifmedia_init(&sc->sc_media, 0, ray_media_change, ray_media_status);
  626         ifmedia_add(&sc->sc_media, IFM_ADHOC, 0, 0);
  627         ifmedia_add(&sc->sc_media, IFM_INFRA, 0, 0);
  628         if (sc->sc_mode == SC_MODE_ADHOC)
  629                 ifmedia_set(&sc->sc_media, IFM_ADHOC);
  630         else
  631                 ifmedia_set(&sc->sc_media, IFM_INFRA);
  632 
  633         /* disable the card */
  634         pcmcia_function_disable(sc->sc_pf);
  635 
  636         sc->sc_sdhook = shutdownhook_establish(ray_shutdown, sc);
  637         sc->sc_pwrhook = powerhook_establish(ray_power, sc);
  638 
  639         /* The attach is successful. */
  640         sc->sc_flags |= RAY_FLAGS_ATTACHED;
  641         return;
  642 fail:
  643         /* disable the card */
  644         pcmcia_function_disable(sc->sc_pf);
  645 
  646         /* free the alloc/map */
  647         if (sc->sc_window != -1) {
  648                 pcmcia_mem_unmap(sc->sc_pf, sc->sc_window);
  649                 pcmcia_mem_free(sc->sc_pf, &sc->sc_mem);
  650         }
  651 }
  652 
  653 int
  654 ray_activate(struct device *dev, enum devact act)
  655 {
  656         struct ray_softc *sc = (struct ray_softc *)dev;
  657         struct ifnet *ifp = &sc->sc_if;
  658         int s;
  659 
  660         RAY_DPRINTF(("%s: activate\n", sc->sc_xname));
  661 
  662         s = splnet();
  663         switch (act) {
  664         case DVACT_ACTIVATE:
  665                 pcmcia_function_enable(sc->sc_pf);
  666                 printf("%s:", sc->sc_dev.dv_xname);
  667                 ray_enable(sc);
  668                 printf("\n");
  669                 break;
  670 
  671         case DVACT_DEACTIVATE:
  672                 if (ifp->if_flags & IFF_RUNNING)
  673                         ray_disable(sc);
  674                 if (sc->sc_ih) {
  675                         pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ih);
  676                         sc->sc_ih = NULL;
  677                 }
  678                 pcmcia_function_disable(sc->sc_pf);
  679                 break;
  680         }
  681         splx(s);
  682         return (0);
  683 }
  684 
  685 int
  686 ray_detach(struct device *self, int flags)
  687 {
  688         struct ray_softc *sc;
  689         struct ifnet *ifp;
  690 
  691         sc = (struct ray_softc *)self;
  692         ifp = &sc->sc_if;
  693         RAY_DPRINTF(("%s: detach\n", sc->sc_xname));
  694 
  695         /* Succeed now if there is no work to do. */
  696         if ((sc->sc_flags & RAY_FLAGS_ATTACHED) == 0)
  697             return (0);
  698 
  699         if (ifp->if_flags & IFF_RUNNING)
  700                 ray_disable(sc);
  701 
  702         /* give back the memory */
  703         if (sc->sc_window != -1) {
  704                 pcmcia_mem_unmap(sc->sc_pf, sc->sc_window);
  705                 pcmcia_mem_free(sc->sc_pf, &sc->sc_mem);
  706         }
  707 
  708         ifmedia_delete_instance(&sc->sc_media, IFM_INST_ANY);
  709 
  710         ether_ifdetach(ifp);
  711         if_detach(ifp);
  712         if (sc->sc_pwrhook != NULL)
  713                 powerhook_disestablish(sc->sc_pwrhook);
  714         if (sc->sc_sdhook != NULL)
  715                 shutdownhook_disestablish(sc->sc_sdhook);
  716 
  717         return (0);
  718 }
  719 
  720 /*
  721  * start the card running
  722  */
  723 int
  724 ray_enable(struct ray_softc *sc)
  725 {
  726         int error;
  727 
  728         RAY_DPRINTF(("%s: enable\n", sc->sc_xname));
  729 
  730         if ((error = ray_init(sc)) == 0) {
  731                 sc->sc_ih = pcmcia_intr_establish(sc->sc_pf, IPL_NET,
  732                     ray_intr, sc, sc->sc_dev.dv_xname);
  733                 if (sc->sc_ih == NULL) {
  734                         ray_stop(sc);
  735                         return (EIO);
  736                 }
  737         }
  738         return (error);
  739 }
  740 
  741 /*
  742  * stop the card running
  743  */
  744 void
  745 ray_disable(struct ray_softc *sc)
  746 {
  747         RAY_DPRINTF(("%s: disable\n", sc->sc_xname));
  748 
  749         if ((sc->sc_if.if_flags & IFF_RUNNING))
  750                 ray_stop(sc);
  751 
  752         sc->sc_resetloop = 0;
  753         sc->sc_rxoverflow = 0;
  754         sc->sc_rxcksum = 0;
  755         sc->sc_rxhcksum = 0;
  756         sc->sc_rxnoise = 0;
  757 
  758         if (sc->sc_ih)
  759                 pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ih);
  760         sc->sc_ih = NULL;
  761 }
  762 
  763 /*
  764  * start the card running
  765  */
  766 int
  767 ray_init(struct ray_softc *sc)
  768 {
  769         struct ray_ecf_startup *ep;
  770         bus_size_t ccs;
  771         int i;
  772 
  773         RAY_DPRINTF(("%s: init\n", sc->sc_xname));
  774 
  775         if ((sc->sc_if.if_flags & IFF_RUNNING))
  776                 ray_stop(sc);
  777 
  778         if (pcmcia_function_enable(sc->sc_pf))
  779                 return (EIO);
  780 
  781         RAY_DPRINTF(("%s: init post-enable\n", sc->sc_xname));
  782 
  783         /* reset some values */
  784         memset(sc->sc_ccsinuse, 0, sizeof(sc->sc_ccsinuse));
  785         sc->sc_havenet = 0;
  786         memset(sc->sc_bssid, 0, sizeof(sc->sc_bssid));
  787         sc->sc_deftxrate = 0;
  788         sc->sc_encrypt = 0;
  789         sc->sc_txpad = 0;
  790         sc->sc_promisc = 0;
  791         sc->sc_scheduled = 0;
  792         sc->sc_running = 0;
  793         sc->sc_txfree = RAY_CCS_NTX;
  794         sc->sc_checkcounters = 0;
  795         sc->sc_flags &= RAY_FLAGS_RESUMEINIT;
  796         sc->sc_authstate = RAY_AUTH_UNAUTH;
  797 
  798         /* get startup results */
  799         ep = &sc->sc_ecf_startup;
  800         ray_read_region(sc, RAY_ECF_TO_HOST_BASE, ep,
  801             sizeof(sc->sc_ecf_startup));
  802 
  803         /* check to see that card initialized properly */
  804         if (ep->e_status != RAY_ECFS_CARD_OK) {
  805                 pcmcia_function_disable(sc->sc_pf);
  806                 printf("%s: card failed self test: status %d\n",
  807                     sc->sc_xname, sc->sc_ecf_startup.e_status);
  808                 return (EIO);
  809         }
  810 
  811         /* fixup tib size to be correct */
  812         if (sc->sc_version == SC_BUILD_4 && sc->sc_tibsize == 0x55)
  813                 sc->sc_tibsize = 32;
  814         sc->sc_txpad = sc->sc_tibsize;
  815 
  816         /* set all ccs to be free */
  817         ccs = RAY_GET_CCS(0);
  818         for (i = 0; i < RAY_CCS_LAST; ccs += RAY_CCS_SIZE, i++)
  819                 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd, c_status,
  820                     RAY_CCS_STATUS_FREE);
  821 
  822         /* clear the interrupt if present */
  823         REG_WRITE(sc, RAY_HCSIR, 0);
  824 
  825         /* we are now up and running -- and are busy until download is cplt */
  826         sc->sc_if.if_flags |= IFF_RUNNING | IFF_OACTIVE;
  827 
  828         /* set this now so it gets set in the download */
  829         sc->sc_promisc = !!(sc->sc_if.if_flags & (IFF_PROMISC|IFF_ALLMULTI));
  830 
  831         /* call after we mark ourselves running */
  832         ray_download_params(sc);
  833 
  834         return (0);
  835 }
  836 
  837 /*
  838  * stop the card running
  839  */
  840 void
  841 ray_stop(struct ray_softc *sc)
  842 {
  843         RAY_DPRINTF(("%s: stop\n", sc->sc_xname));
  844 
  845         callout_stop(&sc->sc_check_ccs_ch);
  846         sc->sc_timocheck = 0;
  847 
  848         callout_stop(&sc->sc_check_scheduled_ch);
  849         sc->sc_timoneed = 0;
  850 
  851         if (sc->sc_repreq) {
  852                 sc->sc_repreq->r_failcause = RAY_FAILCAUSE_EDEVSTOP;
  853                 wakeup(ray_report_params);
  854         }
  855         if (sc->sc_updreq) {
  856                 sc->sc_repreq->r_failcause = RAY_FAILCAUSE_EDEVSTOP;
  857                 wakeup(ray_update_params);
  858         }
  859 
  860         sc->sc_if.if_flags &= ~IFF_RUNNING;
  861         pcmcia_function_disable(sc->sc_pf);
  862 }
  863 
  864 /*
  865  * reset the card
  866  */
  867 void
  868 ray_reset(struct ray_softc *sc)
  869 {
  870         if (++sc->sc_resetloop >= RAY_MAX_RESETS) {
  871                 if (sc->sc_resetloop == RAY_MAX_RESETS) {
  872                         printf("%s: unable to correct, disabling\n",
  873                             sc->sc_xname);
  874                         callout_stop(&sc->sc_reset_resetloop_ch);
  875                         callout_reset(&sc->sc_disable_ch, 1,
  876                             (void (*)(void *))ray_disable, sc);
  877                 }
  878         } else {
  879                 printf("%s: unexpected failure resetting hw [%d more]\n",
  880                     sc->sc_xname, RAY_MAX_RESETS - sc->sc_resetloop);
  881                 callout_stop(&sc->sc_reset_resetloop_ch);
  882                 ray_init(sc);
  883                 callout_reset(&sc->sc_reset_resetloop_ch, RAY_RESET_TIMEOUT,
  884                     ray_reset_resetloop, sc);
  885         }
  886 }
  887 
  888 /*
  889  * return resetloop to zero (enough time has expired to allow user to
  890  * disable a whacked interface)  the main reason for all this nonesense
  891  * is that resets take ~2 seconds and currently the pcmcia code spins
  892  * on these resets
  893  */
  894 void
  895 ray_reset_resetloop(void *arg)
  896 {
  897         struct ray_softc *sc;
  898 
  899         sc = arg;
  900         sc->sc_resetloop = 0;
  901 }
  902 
  903 void
  904 ray_power(int why, void *arg)
  905 {
  906 #if 0
  907         struct ray_softc *sc;
  908 
  909         /* can't do this until power hooks are called from thread */
  910         sc = arg;
  911         switch (why) {
  912         case PWR_RESUME:
  913                 if ((sc->sc_flags & RAY_FLAGS_RESUMEINIT))
  914                         ray_init(sc);
  915                 break;
  916         case PWR_SUSPEND:
  917                 if ((sc->sc_if.if_flags & IFF_RUNNING)) {
  918                         ray_stop(sc);
  919                         sc->sc_flags |= RAY_FLAGS_RESUMEINIT;
  920                 }
  921                 break;
  922         case PWR_STANDBY:
  923         default:
  924                 break;
  925         }
  926 #endif
  927 }
  928 
  929 void
  930 ray_shutdown(void *arg)
  931 {
  932         struct ray_softc *sc;
  933 
  934         sc = arg;
  935         ray_disable(sc);
  936 }
  937 
  938 int
  939 ray_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
  940 {
  941         struct ieee80211_nwid nwid;
  942         struct ray_param_req pr;
  943         struct ray_softc *sc;
  944         struct ifreq *ifr;
  945         struct ifaddr *ifa;
  946         int error, error2, s, i;
  947 
  948         sc = ifp->if_softc;
  949         error = 0;
  950 
  951         ifr = (struct ifreq *)data;
  952 
  953         s = splnet();
  954 
  955         RAY_DPRINTF(("%s: ioctl: cmd 0x%lx data 0x%lx\n", ifp->if_xname,
  956             cmd, (long)data));
  957 
  958         if ((error = ether_ioctl(ifp, &sc->sc_ec, cmd, data)) > 0) {
  959                 splx(s);
  960                 return error;
  961         }
  962 
  963         switch (cmd) {
  964         case SIOCSIFADDR:
  965                 RAY_DPRINTF(("%s: ioctl: cmd SIOCSIFADDR\n", ifp->if_xname));
  966                 if ((ifp->if_flags & IFF_RUNNING) == 0)
  967                         if ((error = ray_enable(sc)))
  968                                 break;
  969                 ifp->if_flags |= IFF_UP;
  970                 ifa = (struct ifaddr *)data;
  971                 switch (ifa->ifa_addr->sa_family) {
  972 #ifdef INET
  973                 case AF_INET:
  974                         arp_ifinit(&sc->sc_ec, ifa);
  975                         break;
  976 #endif
  977                 default:
  978                         break;
  979                 }
  980                 break;
  981         case SIOCSIFFLAGS:
  982                 RAY_DPRINTF(("%s: ioctl: cmd SIOCSIFFLAGS\n", ifp->if_xname));
  983                 if (ifp->if_flags & IFF_UP) {
  984                         if ((ifp->if_flags & IFF_RUNNING) == 0) {
  985                                 if ((error = ray_enable(sc)))
  986                                         break;
  987                         } else
  988                                 ray_update_promisc(sc);
  989                 } else if (ifp->if_flags & IFF_RUNNING)
  990                         ray_disable(sc);
  991                 break;
  992         case SIOCADDMULTI:
  993         case SIOCDELMULTI:
  994                 if (cmd == SIOCADDMULTI) {
  995                         RAY_DPRINTF(("%s: ioctl: cmd SIOCADDMULTI\n",
  996                             ifp->if_xname));
  997                         error = ether_addmulti(ifr, &sc->sc_ec);
  998                 } else {
  999                         RAY_DPRINTF(("%s: ioctl: cmd SIOCDELMULTI\n",
 1000                             ifp->if_xname));
 1001                         error = ether_delmulti(ifr, &sc->sc_ec);
 1002                 }
 1003                 if (error == ENETRESET) {
 1004                         error = 0;
 1005                         ray_update_mcast(sc);
 1006                 }
 1007                 break;
 1008         case SIOCSIFMEDIA:
 1009                 RAY_DPRINTF(("%s: ioctl: cmd SIOCSIFMEDIA\n", ifp->if_xname));
 1010         case SIOCGIFMEDIA:
 1011                 if (cmd == SIOCGIFMEDIA)
 1012                         RAY_DPRINTF(("%s: ioctl: cmd SIOCGIFMEDIA\n",
 1013                             ifp->if_xname));
 1014                 error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
 1015                 break;
 1016         case SIOCSRAYPARAM:
 1017                 if ((error = suser(curproc, 0)) != 0)
 1018                         break;
 1019                 RAY_DPRINTF(("%s: ioctl: cmd SIOCSRAYPARAM\n", ifp->if_xname));
 1020                 if ((error = copyin(ifr->ifr_data, &pr, sizeof(pr))))
 1021                         break;
 1022                 /* disallow certain command that have another interface */
 1023                 switch (pr.r_paramid) {
 1024                 case RAY_PID_NET_TYPE:  /* through media opt */
 1025                 case RAY_PID_AP_STATUS: /* unsupported */
 1026                 case RAY_PID_SSID:      /* use SIOC80211[GS]NWID */
 1027                 case RAY_PID_MAC_ADDR:  /* XXX need interface? */
 1028                 case RAY_PID_PROMISC:   /* bpf */
 1029                         error = EINVAL;
 1030                         break;
 1031                 }
 1032                 error = ray_user_update_params(sc, &pr);
 1033                 error2 = copyout(&pr, ifr->ifr_data, sizeof(pr));
 1034                 error = error2 ? error2 : error;
 1035                 break;
 1036         case SIOCGRAYPARAM:
 1037                 RAY_DPRINTF(("%s: ioctl: cmd SIOCGRAYPARAM\n", ifp->if_xname));
 1038                 if ((error = copyin(ifr->ifr_data, &pr, sizeof(pr))))
 1039                         break;
 1040                 error = ray_user_report_params(sc, &pr);
 1041                 error2 = copyout(&pr, ifr->ifr_data, sizeof(pr));
 1042                 error = error2 ? error2 : error;
 1043                 break;
 1044         case SIOCS80211NWID:
 1045                 if ((error = suser(curproc, 0)) != 0)
 1046                         break;
 1047                 RAY_DPRINTF(("%s: ioctl: cmd SIOCS80211NWID\n", ifp->if_xname));
 1048                 /*
 1049                  * if later people overwrite thats ok -- the latest version
 1050                  * will always get start/joined even if it was set by
 1051                  * a previous command
 1052                  */
 1053                 if ((error = copyin(ifr->ifr_data, &nwid, sizeof(nwid))))
 1054                         break;
 1055                 if (nwid.i_len > IEEE80211_NWID_LEN) {
 1056                         error = EINVAL;
 1057                         break;
 1058                 }
 1059                 /* clear trailing garbages */
 1060                 for (i = nwid.i_len; i < IEEE80211_NWID_LEN; i++)
 1061                         nwid.i_nwid[i] = 0;
 1062                 if (!memcmp(&sc->sc_dnwid, &nwid, sizeof(nwid)))
 1063                         break;
 1064                 memcpy(&sc->sc_dnwid, &nwid, sizeof(nwid));
 1065                 if (ifp->if_flags & IFF_RUNNING)
 1066                         ray_start_join_net(sc);
 1067                 break;
 1068         case SIOCG80211NWID:
 1069                 RAY_DPRINTF(("%s: ioctl: cmd SIOCG80211NWID\n", ifp->if_xname));
 1070                 error = copyout(&sc->sc_cnwid, ifr->ifr_data,
 1071                     sizeof(sc->sc_cnwid));
 1072                 break;
 1073 #ifdef RAY_DO_SIGLEV
 1074                 error = copyout(sc->sc_siglevs, ifr->ifr_data,
 1075                             sizeof sc->sc_siglevs);
 1076                 break;
 1077 #endif
 1078         default:
 1079                 RAY_DPRINTF(("%s: ioctl: unknown\n", ifp->if_xname));
 1080                 error = EINVAL;
 1081                 break;
 1082         }
 1083 
 1084         RAY_DPRINTF(("%s: ioctl: returns %d\n", ifp->if_xname, error));
 1085 
 1086         splx(s);
 1087 
 1088         return (error);
 1089 }
 1090 
 1091 /*
 1092  * ifnet interface to start transmission on the interface
 1093  */
 1094 void
 1095 ray_if_start(struct ifnet *ifp)
 1096 {
 1097         struct ray_softc *sc;
 1098 
 1099         sc = ifp->if_softc;
 1100         ray_intr_start(sc);
 1101 }
 1102 
 1103 int
 1104 ray_media_change(struct ifnet *ifp)
 1105 {
 1106         struct ray_softc *sc;
 1107 
 1108         sc = ifp->if_softc;
 1109         RAY_DPRINTF(("%s: media change cur %d\n", ifp->if_xname,
 1110             sc->sc_media.ifm_cur->ifm_media));
 1111         if (sc->sc_media.ifm_cur->ifm_media & IFM_IEEE80211_ADHOC)
 1112                 sc->sc_mode = SC_MODE_ADHOC;
 1113         else
 1114                 sc->sc_mode = SC_MODE_INFRA;
 1115         if (sc->sc_mode != sc->sc_omode)
 1116                 ray_start_join_net(sc);
 1117         return (0);
 1118 }
 1119 
 1120 void
 1121 ray_media_status(struct ifnet *ifp, struct ifmediareq *imr)
 1122 {
 1123         struct ray_softc *sc;
 1124 
 1125         sc = ifp->if_softc;
 1126 
 1127         RAY_DPRINTF(("%s: media status\n", ifp->if_xname));
 1128 
 1129         imr->ifm_status = IFM_AVALID;
 1130         if (sc->sc_havenet)
 1131                 imr->ifm_status |= IFM_ACTIVE;
 1132 
 1133         if (sc->sc_mode == SC_MODE_ADHOC)
 1134                 imr->ifm_active = IFM_ADHOC;
 1135         else
 1136                 imr->ifm_active = IFM_INFRA;
 1137 }
 1138 
 1139 /*
 1140  * called to start from ray_intr.  We don't check for pending
 1141  * interrupt as a result
 1142  */
 1143 void
 1144 ray_intr_start(struct ray_softc *sc)
 1145 {
 1146         struct ieee80211_frame *iframe;
 1147         struct ether_header *eh;
 1148         size_t len, pktlen, tmplen;
 1149         bus_size_t bufp, ebufp;
 1150         struct mbuf *m0, *m;
 1151         struct ifnet *ifp;
 1152         u_int firsti, hinti, previ, i, pcount;
 1153         u_int16_t et;
 1154         u_int8_t *d;
 1155 
 1156         ifp = &sc->sc_if;
 1157 
 1158         RAY_DPRINTF(("%s: start free %d qlen %d qmax %d\n",
 1159             ifp->if_xname, sc->sc_txfree, ifp->if_snd.ifq_len,
 1160             ifp->if_snd.ifq_maxlen));
 1161 
 1162         ray_cmd_cancel(sc, SCP_IFSTART);
 1163 
 1164         if ((ifp->if_flags & IFF_RUNNING) == 0 || !sc->sc_havenet) {
 1165                 RAY_DPRINTF(("%s: nonet.\n",ifp->if_xname));
 1166                 return;
 1167         }
 1168 
 1169         if (IFQ_IS_EMPTY(&ifp->if_snd)) {
 1170                 RAY_DPRINTF(("%s: nothing to send.\n",ifp->if_xname));
 1171                 return;
 1172         }
 1173 
 1174         firsti = i = previ = RAY_CCS_LINK_NULL;
 1175         hinti = RAY_CCS_TX_FIRST;
 1176 
 1177         if (!RAY_ECF_READY(sc)) {
 1178                 ray_cmd_schedule(sc, SCP_IFSTART);
 1179                 return;
 1180         }
 1181 
 1182         /* check to see if we need to authenticate before sending packets */
 1183         if (sc->sc_authstate == RAY_AUTH_NEEDED) {
 1184                 RAY_DPRINTF(("%s: Sending auth request.\n",ifp->if_xname));
 1185                 sc->sc_authstate= RAY_AUTH_WAITING;
 1186                 ray_send_auth(sc,sc->sc_authid,OPEN_AUTH_REQUEST);
 1187                 return;
 1188         }
 1189 
 1190         pcount = 0;
 1191         for (;;) {
 1192                 /* if we have no descriptors be done */
 1193                 if (i == RAY_CCS_LINK_NULL) {
 1194                         i = ray_find_free_tx_ccs(sc, hinti);
 1195                         if (i == RAY_CCS_LINK_NULL) {
 1196                                 RAY_DPRINTF(("%s: no descriptors.\n",ifp->if_xname));
 1197                                 ifp->if_flags |= IFF_OACTIVE;
 1198                                 break;
 1199                         }
 1200                 }
 1201 
 1202                 IFQ_DEQUEUE(&ifp->if_snd, m0);
 1203                 if (!m0) {
 1204                         RAY_DPRINTF(("%s: dry queue.\n", ifp->if_xname));
 1205                         break;
 1206                 }
 1207                 RAY_DPRINTF(("%s: gotmbuf 0x%lx\n", ifp->if_xname, (long)m0));
 1208                 pktlen = m0->m_pkthdr.len;
 1209                 if (pktlen > ETHER_MAX_LEN - ETHER_CRC_LEN) {
 1210                         RAY_DPRINTF((
 1211                             "%s: mbuf too long %lu\n", ifp->if_xname,
 1212                             (u_long)pktlen));
 1213                         ifp->if_oerrors++;
 1214                         m_freem(m0);
 1215                         continue;
 1216                 }
 1217                 RAY_DPRINTF(("%s: mbuf.m_pkthdr.len %lu\n", ifp->if_xname,
 1218                     (u_long)pktlen));
 1219 
 1220                 /* we need the ether_header now for pktlen adjustments */
 1221                 M_PULLUP(m0, sizeof(struct ether_header));
 1222                 if (!m0) {
 1223                         RAY_DPRINTF(( "%s: couldn\'t pullup ether header\n",
 1224                             ifp->if_xname));
 1225                         ifp->if_oerrors++;
 1226                         continue;
 1227                 }
 1228                 RAY_DPRINTF(("%s: got pulled up mbuf 0x%lx\n", ifp->if_xname,
 1229                     (long)m0));
 1230 
 1231                 /* first peek at the type of packet and figure out what to do */
 1232                 eh = mtod(m0, struct ether_header *);
 1233                 et = ntohs(eh->ether_type);
 1234                 if (ifp->if_flags & IFF_LINK0) {
 1235                         /* don't support llc for windows compat operation */
 1236                         if (et <= ETHERMTU) {
 1237                                 m_freem(m0);
 1238                                 ifp->if_oerrors++;
 1239                                 continue;
 1240                         }
 1241                         tmplen = sizeof(struct ieee80211_frame);
 1242                 } else if (et > ETHERMTU) {
 1243                         /* adjust for LLC/SNAP header */
 1244                         tmplen= sizeof(struct ieee80211_frame) - ETHER_ADDR_LEN;
 1245                 }
 1246                 /* now get our space for the 802.11 frame */
 1247                 M_PREPEND(m0, tmplen, M_DONTWAIT);
 1248                 if (m0)
 1249                         M_PULLUP(m0, sizeof(struct ether_header) + tmplen);
 1250                 if (!m0) {
 1251                         RAY_DPRINTF(("%s: couldn\'t prepend header\n",
 1252                             ifp->if_xname));
 1253                         ifp->if_oerrors++;
 1254                         continue;
 1255                 }
 1256                 /* copy the frame into the mbuf for tapping */
 1257                 iframe = mtod(m0, struct ieee80211_frame *);
 1258                 eh = (struct ether_header *)((u_int8_t *)iframe + tmplen);
 1259                 iframe->i_fc[0] =
 1260                     (IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_DATA);
 1261                 if (sc->sc_mode == SC_MODE_ADHOC) {
 1262                         iframe->i_fc[1] = IEEE80211_FC1_DIR_NODS;
 1263                         memcpy(iframe->i_addr1, eh->ether_dhost,ETHER_ADDR_LEN);
 1264                         memcpy(iframe->i_addr2, eh->ether_shost,ETHER_ADDR_LEN);
 1265                         memcpy(iframe->i_addr3, sc->sc_bssid, ETHER_ADDR_LEN);
 1266                 } else {
 1267                         iframe->i_fc[1] = IEEE80211_FC1_DIR_TODS;
 1268                         memcpy(iframe->i_addr1, sc->sc_bssid,ETHER_ADDR_LEN);
 1269                         memcpy(iframe->i_addr2, eh->ether_shost,ETHER_ADDR_LEN);
 1270                         memmove(iframe->i_addr3,eh->ether_dhost,ETHER_ADDR_LEN);
 1271                 }
 1272                 iframe->i_dur[0] = iframe->i_dur[1] = 0;
 1273                 iframe->i_seq[0] = iframe->i_seq[1] = 0;
 1274 
 1275                 /* if not using crummy E2 in 802.11 make it LLC/SNAP */
 1276                 if ((ifp->if_flags & IFF_LINK0) == 0 && et > ETHERMTU)
 1277                         memcpy(iframe + 1, llc_snapid, sizeof(llc_snapid));
 1278 
 1279                 RAY_DPRINTF(("%s: i %d previ %d\n", ifp->if_xname, i, previ));
 1280 
 1281                 if (firsti == RAY_CCS_LINK_NULL)
 1282                         firsti = i;
 1283 
 1284                 pktlen = m0->m_pkthdr.len;
 1285                 bufp = ray_fill_in_tx_ccs(sc, pktlen, i, previ);
 1286                 previ = hinti = i;
 1287                 i = RAY_CCS_LINK_NULL;
 1288 
 1289                 RAY_DPRINTF(("%s: bufp 0x%lx new pktlen %lu\n",
 1290                     ifp->if_xname, (long)bufp, (u_long)pktlen));
 1291 
 1292                 /* copy out mbuf */
 1293                 for (m = m0; m; m = m->m_next) {
 1294                         if ((len = m->m_len) == 0)
 1295                                 continue;
 1296                         RAY_DPRINTF((
 1297                             "%s: copying mbuf 0x%lx bufp 0x%lx len %d\n",
 1298                             ifp->if_xname, (long)m, (long)bufp, (int)len));
 1299                         d = mtod(m, u_int8_t *);
 1300                         ebufp = bufp + len;
 1301                         if (ebufp <= RAY_TX_END)
 1302                                 ray_write_region(sc, bufp, d, len);
 1303                         else {
 1304                                 panic("ray_intr_start");        /* XXX */
 1305                                 /* wrapping */
 1306                                 tmplen = ebufp - bufp;
 1307                                 len -= tmplen;
 1308                                 ray_write_region(sc, bufp, d, tmplen);
 1309                                 d += tmplen;
 1310                                 bufp = RAY_TX_BASE;
 1311                                 ray_write_region(sc, bufp, d, len);
 1312                         }
 1313                         bufp += len;
 1314                 }
 1315 #if NBPFILTER > 0
 1316                 if (ifp->if_bpf) {
 1317                         if (ifp->if_flags & IFF_LINK0) {
 1318                                 m0->m_data += sizeof(struct ieee80211_frame);
 1319                                 m0->m_len -=  sizeof(struct ieee80211_frame);
 1320                                 m0->m_pkthdr.len -=  sizeof(struct ieee80211_frame);
 1321                         }
 1322                         bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
 1323                         if (ifp->if_flags & IFF_LINK0) {
 1324                                 m0->m_data -= sizeof(struct ieee80211_frame);
 1325                                 m0->m_len +=  sizeof(struct ieee80211_frame);
 1326                                 m0->m_pkthdr.len +=  sizeof(struct ieee80211_frame);
 1327                         }
 1328                 }
 1329 #endif
 1330 
 1331 #ifdef RAY_DEBUG
 1332                 if (ray_debug && ray_debug_dump_tx)
 1333                         ray_dump_mbuf(sc, m0);
 1334 #endif
 1335                 pcount++;
 1336                 m_freem(m0);
 1337         }
 1338 
 1339         if (firsti == RAY_CCS_LINK_NULL)
 1340                 return;
 1341         i = 0;
 1342         if (!RAY_ECF_READY(sc)) {
 1343                 /*
 1344                  * if this can really happen perhaps we need to save
 1345                  * the chain and use it later.  I think this might
 1346                  * be a confused state though because we check above
 1347                  * and don't issue any commands between.
 1348                  */
 1349                 printf("%s: dropping tx packets device busy\n", sc->sc_xname);
 1350                 ray_free_ccs_chain(sc, firsti);
 1351                 ifp->if_oerrors += pcount;
 1352                 return;
 1353         }
 1354 
 1355         /* send it off */
 1356         RAY_DPRINTF(("%s: ray_start issueing %d \n", sc->sc_xname, firsti));
 1357         SRAM_WRITE_1(sc, RAY_SCB_CCSI, firsti);
 1358         RAY_ECF_START_CMD(sc);
 1359 
 1360         RAY_DPRINTF_XMIT(("%s: sent packet: len %lu\n", sc->sc_xname,
 1361             (u_long)pktlen));
 1362 
 1363         ifp->if_opackets += pcount;
 1364 }
 1365 
 1366 /*
 1367  * receive a packet from the card
 1368  */
 1369 void
 1370 ray_recv(struct ray_softc *sc, bus_size_t ccs)
 1371 {
 1372         struct ieee80211_frame *frame;
 1373         struct ether_header *eh;
 1374         struct mbuf *m;
 1375         size_t pktlen, fudge, len, lenread;
 1376         bus_size_t bufp, ebufp, tmp;
 1377         struct ifnet *ifp;
 1378         u_int8_t *src, *d;
 1379         u_int frag, nofrag, ni, i, issnap, first;
 1380         u_int8_t fc0;
 1381 #ifdef RAY_DO_SIGLEV
 1382         u_int8_t siglev;
 1383 #endif
 1384 
 1385 #ifdef RAY_DEBUG
 1386         /* have a look if you want to see how the card rx works :) */
 1387         if (ray_debug && ray_debug_dump_desc)
 1388                 hexdump((caddr_t)sc->sc_memh + RAY_RCS_BASE, 0x400,
 1389                     16, 4, 0);
 1390 #endif
 1391 
 1392         nofrag = 0;     /* XXX unused */
 1393         m = 0;
 1394         ifp = &sc->sc_if;
 1395 
 1396         /*
 1397          * If we're expecting the E2-in-802.11 encapsulation that the
 1398          * WebGear Windows driver produces, fudge the packet forward
 1399          * in the mbuf by 2 bytes so that the payload after the
 1400          * Ethernet header will be aligned.  If we end up getting a
 1401          * packet that's not of this type, we'll just drop it anyway.
 1402          */
 1403         fudge = ifp->if_flags & IFF_LINK0? 2 : 0;
 1404 
 1405         /* it looks like at least with build 4 there is no CRC in length */
 1406         first = RAY_GET_INDEX(ccs);
 1407         pktlen = SRAM_READ_FIELD_2(sc, ccs, ray_cmd_rx, c_pktlen);
 1408 #ifdef RAY_DO_SIGLEV
 1409         siglev = SRAM_READ_FIELD_1(sc, ccs, ray_cmd_rx, c_siglev);
 1410 #endif
 1411         RAY_DPRINTF(("%s: recv pktlen %lu nofrag %d\n", sc->sc_xname,
 1412             (u_long)pktlen, nofrag));
 1413         RAY_DPRINTF_XMIT(("%s: received packet: len %lu\n", sc->sc_xname,
 1414             (u_long)pktlen));
 1415         if (pktlen > MCLBYTES || pktlen < (sizeof(*frame)) ) {
 1416                 RAY_DPRINTF(("%s: PKTLEN TOO BIG OR TOO SMALL\n",
 1417                     sc->sc_xname));
 1418                 ifp->if_ierrors++;
 1419                 goto done;
 1420         }
 1421         MGETHDR(m, M_DONTWAIT, MT_DATA);
 1422         if (!m) {
 1423                 RAY_DPRINTF(("%s: MGETHDR FAILED\n", sc->sc_xname));
 1424                 ifp->if_ierrors++;
 1425                 goto done;
 1426         }
 1427         if ((pktlen + fudge) > MHLEN) {
 1428                 /* XXX should allow chaining? */
 1429                 MCLGET(m, M_DONTWAIT);
 1430                 if ((m->m_flags & M_EXT) == 0) {
 1431                         RAY_DPRINTF(("%s: MCLGET FAILED\n", sc->sc_xname));
 1432                         ifp->if_ierrors++;
 1433                         m_freem(m);
 1434                         m = 0;
 1435                         goto done;
 1436                 }
 1437         }
 1438         m->m_pkthdr.rcvif = ifp;
 1439         m->m_pkthdr.len = pktlen;
 1440         m->m_len = pktlen;
 1441         m->m_data += fudge;
 1442         d = mtod(m, u_int8_t *);
 1443 
 1444         RAY_DPRINTF(("%s: recv ccs index %d\n", sc->sc_xname, first));
 1445         frag = 0;
 1446         lenread = 0;
 1447         i = ni = first;
 1448         while ((i = ni) && i != RAY_CCS_LINK_NULL) {
 1449                 ccs = RAY_GET_CCS(i);
 1450                 bufp = SRAM_READ_FIELD_2(sc, ccs, ray_cmd_rx, c_bufp);
 1451                 len = SRAM_READ_FIELD_2(sc, ccs, ray_cmd_rx, c_len);
 1452                 /* remove the CRC */
 1453 #if 0
 1454                 /* at least with build 4 no crc seems to be here */
 1455                 if (frag++ == 0)
 1456                         len -= 4;
 1457 #endif
 1458                 ni = SRAM_READ_FIELD_1(sc, ccs, ray_cmd_rx, c_nextfrag);
 1459                 RAY_DPRINTF(("%s: recv frag index %d len %lu bufp %p ni %d\n",
 1460                     sc->sc_xname, i, (u_long)len, bufp, ni));
 1461                 if (len + lenread > pktlen) {
 1462                         RAY_DPRINTF(("%s: BAD LEN current %lu pktlen %lu\n",
 1463                             sc->sc_xname, (u_long)(len + lenread),
 1464                             (u_long)pktlen));
 1465                         ifp->if_ierrors++;
 1466                         m_freem(m);
 1467                         m = 0;
 1468                         goto done;
 1469                 }
 1470                 if (i < RAY_RCCS_FIRST) {
 1471                         printf("ray_recv: bad ccs index 0x%x\n", i);
 1472                         m_freem(m);
 1473                         m = 0;
 1474                         goto done;
 1475                 }
 1476 
 1477                 ebufp = bufp + len;
 1478                 if (ebufp <= RAY_RX_END)
 1479                         ray_read_region(sc, bufp, d, len);
 1480                 else {
 1481                         /* wrapping */
 1482                         ray_read_region(sc, bufp, d, (tmp = RAY_RX_END - bufp));
 1483                         ray_read_region(sc, RAY_RX_BASE, d + tmp, ebufp - RAY_RX_END);
 1484                 }
 1485                 d += len;
 1486                 lenread += len;
 1487         }
 1488 done:
 1489 
 1490         RAY_DPRINTF(("%s: recv frag count %d\n", sc->sc_xname, frag));
 1491 
 1492         /* free the rcss */
 1493         ni = first;
 1494         while ((i = ni) && (i != RAY_CCS_LINK_NULL)) {
 1495                 ccs = RAY_GET_CCS(i);
 1496                 ni = SRAM_READ_FIELD_1(sc, ccs, ray_cmd_rx, c_nextfrag);
 1497                 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd, c_status,
 1498                     RAY_CCS_STATUS_FREE);
 1499         }
 1500 
 1501         if (!m)
 1502                 return;
 1503 
 1504         RAY_DPRINTF(("%s: recv got packet pktlen %lu actual %lu\n",
 1505             sc->sc_xname, (u_long)pktlen, (u_long)lenread));
 1506 #ifdef RAY_DEBUG
 1507         if (ray_debug && ray_debug_dump_rx)
 1508                 ray_dump_mbuf(sc, m);
 1509 #endif
 1510         /* receive the packet */
 1511         frame = mtod(m, struct ieee80211_frame *);
 1512         fc0 = frame->i_fc[0]
 1513            & (IEEE80211_FC0_VERSION_MASK|IEEE80211_FC0_TYPE_MASK);
 1514         if ((fc0 & IEEE80211_FC0_VERSION_MASK) != IEEE80211_FC0_VERSION_0) {
 1515                 RAY_DPRINTF(("%s: pkt not version 0 fc 0x%x\n",
 1516                     sc->sc_xname, fc0));
 1517                 m_freem(m);
 1518                 return;
 1519         }
 1520         if ((fc0 & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_MGT) {
 1521                 switch (frame->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) {
 1522                 case IEEE80211_FC0_SUBTYPE_BEACON: 
 1523                         break; /* ignore beacon silently */
 1524                 case IEEE80211_FC0_SUBTYPE_AUTH:
 1525                         ray_recv_auth(sc,frame);
 1526                         break;
 1527                 case IEEE80211_FC0_SUBTYPE_DEAUTH:
 1528                         sc->sc_authstate= RAY_AUTH_UNAUTH;
 1529                         break;
 1530                 default:
 1531                         RAY_DPRINTF(("%s: mgt packet not supported\n",sc->sc_xname));
 1532 #ifdef RAY_DEBUG
 1533                         hexdump((const u_int8_t*)frame, pktlen, 16,4,0);
 1534 #endif
 1535                         RAY_DPRINTF(("\n"));
 1536                         break; }
 1537                 m_freem(m);
 1538                 return;
 1539 
 1540         } else if ((fc0 & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_DATA) {
 1541                 RAY_DPRINTF(("%s: pkt not type data fc0 0x%x fc1 0x%x\n", 
 1542                 sc->sc_xname, frame->i_fc[0], frame->i_fc[1]));
 1543 #ifdef RAY_DEBUG
 1544                 hexdump((const u_int8_t*)frame, pktlen, 16,4,0);
 1545 #endif
 1546                 RAY_DPRINTF(("\n"));
 1547                 
 1548                 m_freem(m);
 1549                 return;
 1550         }
 1551 
 1552         if (pktlen < sizeof(struct ieee80211_frame) + sizeof(struct llc))
 1553         {
 1554                 RAY_DPRINTF(("%s: pkt not big enough to contain llc (%lu)\n",
 1555                         sc->sc_xname, (u_long)pktlen));
 1556                 m_freem(m);
 1557                 return;
 1558         }
 1559 
 1560         if (!memcmp(frame + 1, llc_snapid, sizeof(llc_snapid)))
 1561                 issnap = 1;
 1562         else {
 1563                 /*
 1564                  * if user has link0 flag set we allow the weird
 1565                  * Ethernet2 in 802.11 encapsulation produced by
 1566                  * the windows driver for the WebGear card
 1567                  */
 1568                 RAY_DPRINTF(("%s: pkt not snap 0\n", sc->sc_xname));
 1569                 if ((ifp->if_flags & IFF_LINK0) == 0) {
 1570                         m_freem(m);
 1571                         return;
 1572                 }
 1573                 issnap = 0;
 1574         }
 1575         switch (frame->i_fc[1] & IEEE80211_FC1_DIR_MASK) {
 1576         case IEEE80211_FC1_DIR_NODS:
 1577                 src = frame->i_addr2;
 1578                 break;
 1579         case IEEE80211_FC1_DIR_FROMDS:
 1580                 src = frame->i_addr3;
 1581                 break;
 1582         case IEEE80211_FC1_DIR_TODS:
 1583                 RAY_DPRINTF(("%s: pkt ap2ap\n", sc->sc_xname));
 1584                 m_freem(m);
 1585                 return;
 1586         default:
 1587                 RAY_DPRINTF(("%s: pkt type unknown\n", sc->sc_xname));
 1588                 m_freem(m);
 1589                 return;
 1590         }
 1591 
 1592 #ifdef RAY_DO_SIGLEV
 1593         ray_update_siglev(sc, src, siglev);
 1594 #endif
 1595 
 1596         /*
 1597          * This is a mess.. we should support other LLC frame types
 1598          */
 1599         if (issnap) {
 1600                 /* create an ether_header over top of the 802.11+SNAP header */
 1601                 eh = (struct ether_header *)((caddr_t)(frame + 1) - 6);
 1602                 memcpy(eh->ether_shost, src, ETHER_ADDR_LEN);
 1603                 memcpy(eh->ether_dhost, frame->i_addr1, ETHER_ADDR_LEN);
 1604         } else {
 1605                 /* this is the weird e2 in 802.11 encapsulation */
 1606                 eh = (struct ether_header *)(frame + 1);
 1607         }
 1608         m_adj(m, (caddr_t)eh - (caddr_t)frame);
 1609 #if NBPFILTER > 0
 1610         if (ifp->if_bpf)
 1611                 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
 1612 #endif
 1613         ifp->if_ipackets++;
 1614 
 1615         ether_input_mbuf(ifp, m);
 1616 }
 1617 
 1618 /* receive an auth packet
 1619  *
 1620  */
 1621 
 1622 void
 1623 ray_recv_auth(struct ray_softc *sc, struct ieee80211_frame *frame)
 1624 {       
 1625         /* todo: deal with timers: del_timer(&local->timer); */
 1626         u_int8_t *var= (u_int8_t*)(frame+1);
 1627         
 1628         /* if we are trying to get authenticated */
 1629         if (sc->sc_mode == SC_MODE_ADHOC) {
 1630                 RAY_DPRINTF(("%s: recv auth. packet dump:\n",sc->sc_xname));
 1631 #ifdef RAY_DEBUG
 1632                 hexdump((u_int8_t*)frame, sizeof(*frame)+6, 16,4,0);
 1633 #endif
 1634                 RAY_DPRINTF(("\n"));
 1635 
 1636                 if (var[2] == OPEN_AUTH_REQUEST) {
 1637                         RAY_DPRINTF(("%s: Sending authentication response.\n",sc->sc_xname));
 1638                         if (!ray_send_auth(sc,frame->i_addr2,OPEN_AUTH_RESPONSE)) {
 1639                                 sc->sc_authstate= RAY_AUTH_NEEDED;
 1640                                 memcpy(sc->sc_authid, frame->i_addr2, ETHER_ADDR_LEN);
 1641                         }
 1642                 }
 1643                 else if (var[2] == OPEN_AUTH_RESPONSE) {
 1644                         RAY_DPRINTF(("%s: Authenticated!\n",sc->sc_xname));
 1645                         sc->sc_authstate= RAY_AUTH_AUTH;
 1646                 }
 1647         }
 1648 }
 1649 
 1650 /* ray_send_auth
 1651  *
 1652  * dest: where to send auth packet
 1653  * auth_type: whether to send an REQUEST or a RESPONSE 
 1654  */
 1655 int
 1656 ray_send_auth(struct ray_softc *sc, u_int8_t *dest, u_int8_t auth_type)
 1657 {
 1658         u_int8_t packet[sizeof(struct ieee80211_frame) + 6];
 1659         bus_size_t bufp;
 1660         struct ieee80211_frame *frame= (struct ieee80211_frame*)packet;
 1661         int ccsindex= RAY_CCS_LINK_NULL;
 1662         ccsindex= ray_find_free_tx_ccs(sc,RAY_CCS_TX_FIRST);
 1663         if (ccsindex == RAY_CCS_LINK_NULL) {
 1664                 RAY_DPRINTF(("%x: send authenticate - No free tx ccs\n"));
 1665                 return -1;
 1666         }
 1667         bufp= ray_fill_in_tx_ccs(sc,sizeof(packet),ccsindex,RAY_CCS_LINK_NULL);
 1668         frame= (struct ieee80211_frame*) packet;
 1669         frame->i_fc[0]= IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_SUBTYPE_AUTH;
 1670         frame->i_fc[1]= 0;
 1671         memcpy(frame->i_addr1,dest,ETHER_ADDR_LEN);
 1672         memcpy(frame->i_addr2,sc->sc_ecf_startup.e_station_addr,ETHER_ADDR_LEN);
 1673         memcpy(frame->i_addr3,sc->sc_bssid,ETHER_ADDR_LEN);
 1674         memset(frame+1,0,6);
 1675         ((u_int8_t*)(frame+1))[2]= auth_type;
 1676 
 1677         ray_write_region(sc,bufp,packet,sizeof(packet));
 1678 
 1679         SRAM_WRITE_1(sc, RAY_SCB_CCSI, ccsindex);
 1680         RAY_ECF_START_CMD(sc);
 1681 
 1682         RAY_DPRINTF_XMIT(("%s: sent auth packet: len %lu\n", sc->sc_xname,
 1683             (u_long)sizeof(packet)));
 1684         return 0;
 1685 }
 1686 
 1687 /*
 1688  * scan for free buffers
 1689  *
 1690  * Note: do _not_ try to optimize this away, there is some kind of
 1691  * horrible interaction with receiving tx interrupts and they
 1692  * have to be done as fast as possible, which means zero processing.
 1693  * this took ~ever to figure out, don't make someone do it again!
 1694  */
 1695 u_int
 1696 ray_find_free_tx_ccs(struct ray_softc *sc, u_int hint)
 1697 {
 1698         u_int i, stat;
 1699 
 1700         for (i = hint; i <= RAY_CCS_TX_LAST; i++) {
 1701                 stat = SRAM_READ_FIELD_1(sc, RAY_GET_CCS(i), ray_cmd, c_status);
 1702                 if (stat == RAY_CCS_STATUS_FREE)
 1703                         return (i);
 1704         }
 1705 
 1706         if (hint == RAY_CCS_TX_FIRST)
 1707                 return (RAY_CCS_LINK_NULL);
 1708 
 1709         for (i = RAY_CCS_TX_FIRST; i < hint; i++) {
 1710                 stat = SRAM_READ_FIELD_1(sc, RAY_GET_CCS(i), ray_cmd, c_status);
 1711                 if (stat == RAY_CCS_STATUS_FREE)
 1712                         return (i);
 1713         }
 1714         return (RAY_CCS_LINK_NULL);
 1715 }
 1716 
 1717 /*
 1718  * allocate, initialize and link in a tx ccs for the given
 1719  * page and the current chain values
 1720  */
 1721 bus_size_t
 1722 ray_fill_in_tx_ccs(struct ray_softc *sc, size_t pktlen, u_int i, u_int pi)
 1723 {
 1724         bus_size_t ccs, bufp;
 1725 
 1726         /* pktlen += RAY_TX_PHY_SIZE; */
 1727         bufp = RAY_TX_BASE + i * RAY_TX_BUF_SIZE;
 1728         bufp += sc->sc_txpad;
 1729         ccs = RAY_GET_CCS(i);
 1730         SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_tx, c_status, RAY_CCS_STATUS_BUSY);
 1731         SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_tx, c_cmd, RAY_CMD_TX_REQ);
 1732         SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_tx, c_link, RAY_CCS_LINK_NULL);
 1733         SRAM_WRITE_FIELD_2(sc, ccs, ray_cmd_tx, c_bufp, bufp);
 1734         SRAM_WRITE_FIELD_2(sc, ccs, ray_cmd_tx, c_len, pktlen);
 1735         SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_tx, c_tx_rate, sc->sc_deftxrate);
 1736         SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_tx, c_apm_mode, 0);
 1737         SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_tx, c_antenna, 0);
 1738 
 1739         /* link us in */
 1740         if (pi != RAY_CCS_LINK_NULL)
 1741                 SRAM_WRITE_FIELD_1(sc, RAY_GET_CCS(pi), ray_cmd_tx, c_link, i);
 1742 
 1743         RAY_DPRINTF(("%s: ray_alloc_tx_ccs bufp 0x%lx idx %d pidx %d \n",
 1744             sc->sc_xname, bufp, i, pi));
 1745 
 1746         return (bufp + RAY_TX_PHY_SIZE);
 1747 }
 1748 
 1749 /*
 1750  * an update params command has completed lookup which command and
 1751  * the status
 1752  */
 1753 ray_cmd_func_t
 1754 ray_update_params_done(struct ray_softc *sc, bus_size_t ccs, u_int stat)
 1755 {
 1756         ray_cmd_func_t rcmd;
 1757 
 1758         rcmd = 0;
 1759 
 1760         RAY_DPRINTF(("%s: ray_update_params_done stat %d\n",
 1761            sc->sc_xname, stat));
 1762 
 1763         /* this will get more complex as we add commands */
 1764         if (stat == RAY_CCS_STATUS_FAIL) {
 1765                 printf("%s: failed to update a promisc\n", sc->sc_xname);
 1766                 /* XXX should probably reset */
 1767                 /* rcmd = ray_reset; */
 1768         }
 1769 
 1770         if (sc->sc_running & SCP_UPD_PROMISC) {
 1771                 ray_cmd_done(sc, SCP_UPD_PROMISC);
 1772                 sc->sc_promisc = SRAM_READ_1(sc, RAY_HOST_TO_ECF_BASE);
 1773                 RAY_DPRINTF(("%s: new promisc value %d\n", sc->sc_xname,
 1774                     sc->sc_promisc));
 1775         } else if (sc->sc_updreq) {
 1776                 ray_cmd_done(sc, SCP_UPD_UPDATEPARAMS);
 1777                 /* get the update parameter */
 1778                 sc->sc_updreq->r_failcause =
 1779                     SRAM_READ_FIELD_1(sc, ccs, ray_cmd_update, c_failcause);
 1780                 sc->sc_updreq = 0;
 1781                 wakeup(ray_update_params);
 1782 
 1783                 rcmd = ray_start_join_net;
 1784         }
 1785         return (rcmd);
 1786 }
 1787 
 1788 /*
 1789  *  check too see if we have any pending commands.
 1790  */
 1791 void
 1792 ray_check_scheduled(void *arg)
 1793 {
 1794         struct ray_softc *sc;
 1795         int s, i, mask;
 1796 
 1797         s = splnet();
 1798 
 1799         sc = arg;
 1800         RAY_DPRINTF((
 1801             "%s: ray_check_scheduled enter schd 0x%x running 0x%x ready %d\n",
 1802             sc->sc_xname, sc->sc_scheduled, sc->sc_running, RAY_ECF_READY(sc)));
 1803 
 1804         if (sc->sc_timoneed) {
 1805                 callout_stop(&sc->sc_check_scheduled_ch);
 1806                 sc->sc_timoneed = 0;
 1807         }
 1808 
 1809         /* if update subcmd is running -- clear it in scheduled */
 1810         if (sc->sc_running & SCP_UPDATESUBCMD)
 1811                 sc->sc_scheduled &= ~SCP_UPDATESUBCMD;
 1812 
 1813         mask = SCP_FIRST;
 1814         for (i = 0; i < ray_ncmdtab; mask <<= 1, i++) {
 1815                 if ((sc->sc_scheduled & ~SCP_UPD_MASK) == 0)
 1816                         break;
 1817                 if (!RAY_ECF_READY(sc))
 1818                         break;
 1819                 if (sc->sc_scheduled & mask)
 1820                         (*ray_cmdtab[i])(sc);
 1821         }
 1822 
 1823         RAY_DPRINTF((
 1824             "%s: ray_check_scheduled exit sched 0x%x running 0x%x ready %d\n",
 1825             sc->sc_xname, sc->sc_scheduled, sc->sc_running, RAY_ECF_READY(sc)));
 1826 
 1827         if (sc->sc_scheduled & ~SCP_UPD_MASK)
 1828                 ray_set_pending(sc, sc->sc_scheduled);
 1829 
 1830         splx(s);
 1831 }
 1832 
 1833 /*
 1834  * check for unreported returns
 1835  *
 1836  * this routine is coded to only expect one outstanding request for the
 1837  * timed out requests at a time, but thats all that can be outstanding
 1838  * per hardware limitations
 1839  */
 1840 void
 1841 ray_check_ccs(void *arg)
 1842 {
 1843         ray_cmd_func_t fp;
 1844         struct ray_softc *sc;
 1845         u_int i, cmd, stat;
 1846         bus_size_t ccs;
 1847         int s;
 1848 
 1849         s = splnet();
 1850         sc = arg;
 1851 
 1852         RAY_DPRINTF(("%s: ray_check_ccs\n", sc->sc_xname));
 1853 
 1854         sc->sc_timocheck = 0;
 1855         for (i = RAY_CCS_CMD_FIRST; i <= RAY_CCS_CMD_LAST; i++) {
 1856                 if (!sc->sc_ccsinuse[i])
 1857                         continue;
 1858                 ccs = RAY_GET_CCS(i);
 1859                 cmd = SRAM_READ_FIELD_1(sc, ccs, ray_cmd, c_cmd);
 1860                 switch (cmd) {
 1861                 case RAY_CMD_START_PARAMS:
 1862                 case RAY_CMD_UPDATE_MCAST:
 1863                 case RAY_CMD_UPDATE_PARAMS:
 1864                         stat = SRAM_READ_FIELD_1(sc, ccs, ray_cmd, c_status);
 1865                         RAY_DPRINTF(("%s: check ccs idx %d ccs 0x%lx "
 1866                             "cmd 0x%x stat %d\n", sc->sc_xname, i,
 1867                             ccs, cmd, stat));
 1868                         goto breakout;
 1869                 }
 1870         }
 1871 breakout:
 1872         /* see if we got one of the commands we are looking for */
 1873         if (i > RAY_CCS_CMD_LAST)
 1874                 ; /* nothing */
 1875         else if (stat == RAY_CCS_STATUS_FREE) {
 1876                 stat = RAY_CCS_STATUS_COMPLETE;
 1877                 if ((fp = ray_ccs_done(sc, ccs)))
 1878                         (*fp)(sc);
 1879         } else if (stat != RAY_CCS_STATUS_BUSY) {
 1880                 if (sc->sc_ccsinuse[i] == 1) {
 1881                         /* give a chance for the interrupt to occur */
 1882                         sc->sc_ccsinuse[i] = 2;
 1883                         if (!sc->sc_timocheck) {
 1884                                 callout_reset(&sc->sc_check_ccs_ch, 1,
 1885                                     ray_check_ccs, sc);
 1886                                 sc->sc_timocheck = 1;
 1887                         }
 1888                 } else if ((fp = ray_ccs_done(sc, ccs)))
 1889                         (*fp)(sc);
 1890         } else {
 1891                 callout_reset(&sc->sc_check_ccs_ch, RAY_CHECK_CCS_TIMEOUT,
 1892                     ray_check_ccs, sc);
 1893                 sc->sc_timocheck = 1;
 1894         }
 1895         splx(s);
 1896 }
 1897 
 1898 /*
 1899  * read the counters, the card implements the following protocol
 1900  * to keep the values from being changed while read:  It checks
 1901  * the `own' bit and if zero writes the current internal counter
 1902  * value, it then sets the `own' bit to 1.  If the `own' bit was 1 it
 1903  * increments its internal counter.  The user thus reads the counter
 1904  * if the `own' bit is one and then sets the own bit to 0.
 1905  */
 1906 void
 1907 ray_update_error_counters(struct ray_softc *sc)
 1908 {
 1909         bus_size_t csc;
 1910 
 1911         /* try and update the error counters */
 1912         csc = RAY_STATUS_BASE;
 1913         if (SRAM_READ_FIELD_1(sc, csc, ray_csc, csc_mrxo_own)) {
 1914                 sc->sc_rxoverflow +=
 1915                     SRAM_READ_FIELD_2(sc, csc, ray_csc, csc_mrx_overflow);
 1916                 SRAM_WRITE_FIELD_1(sc, csc, ray_csc, csc_mrxo_own, 0);
 1917         }
 1918         if (SRAM_READ_FIELD_1(sc, csc, ray_csc, csc_mrxc_own)) {
 1919                 sc->sc_rxcksum +=
 1920                     SRAM_READ_FIELD_2(sc, csc, ray_csc, csc_mrx_overflow);
 1921                 SRAM_WRITE_FIELD_1(sc, csc, ray_csc, csc_mrxc_own, 0);
 1922         }
 1923         if (SRAM_READ_FIELD_1(sc, csc, ray_csc, csc_rxhc_own)) {
 1924                 sc->sc_rxhcksum +=
 1925                     SRAM_READ_FIELD_2(sc, csc, ray_csc, csc_rx_hcksum);
 1926                 SRAM_WRITE_FIELD_1(sc, csc, ray_csc, csc_rxhc_own, 0);
 1927         }
 1928         sc->sc_rxnoise = SRAM_READ_FIELD_1(sc, csc, ray_csc, csc_rx_noise);
 1929 }
 1930 
 1931 /*
 1932  * one of the commands we issued has completed, process.
 1933  */
 1934 ray_cmd_func_t
 1935 ray_ccs_done(struct ray_softc *sc, bus_size_t ccs)
 1936 {
 1937         struct ifnet *ifp;
 1938         ray_cmd_func_t rcmd;
 1939         u_int cmd, stat;
 1940 
 1941         ifp = &sc->sc_if;
 1942         cmd = SRAM_READ_FIELD_1(sc, ccs, ray_cmd, c_cmd);
 1943         stat = SRAM_READ_FIELD_1(sc, ccs, ray_cmd, c_status);
 1944 
 1945         RAY_DPRINTF(("%s: ray_ccs_done idx %ld cmd 0x%x stat %d\n",
 1946             sc->sc_xname, RAY_GET_INDEX(ccs), cmd, stat));
 1947 
 1948         rcmd = 0;
 1949         switch (cmd) {
 1950         /*
 1951          * solicited commands
 1952          */
 1953         case RAY_CMD_START_PARAMS:
 1954                 /* start network */
 1955                 ray_cmd_done(sc, SCP_UPD_STARTUP);
 1956 
 1957                 /* ok to start queueing packets */
 1958                 sc->sc_if.if_flags &= ~IFF_OACTIVE;
 1959 
 1960                 sc->sc_omode = sc->sc_mode;
 1961                 memcpy(&sc->sc_cnwid, &sc->sc_dnwid, sizeof(sc->sc_cnwid));
 1962 
 1963                 rcmd = ray_start_join_net;
 1964                 break;
 1965         case RAY_CMD_UPDATE_PARAMS:
 1966                 rcmd = ray_update_params_done(sc, ccs, stat);
 1967                 break;
 1968         case RAY_CMD_REPORT_PARAMS:
 1969                 /* get the reported parameters */
 1970                 ray_cmd_done(sc, SCP_REPORTPARAMS);
 1971                 if (!sc->sc_repreq)
 1972                         break;
 1973                 sc->sc_repreq->r_failcause =
 1974                     SRAM_READ_FIELD_1(sc, ccs, ray_cmd_report, c_failcause);
 1975                 sc->sc_repreq->r_len =
 1976                     SRAM_READ_FIELD_1(sc, ccs, ray_cmd_report, c_len);
 1977                 ray_read_region(sc, RAY_ECF_TO_HOST_BASE, sc->sc_repreq->r_data,
 1978                     sc->sc_repreq->r_len);
 1979                 sc->sc_repreq = 0;
 1980                 wakeup(ray_report_params);
 1981                 break;
 1982         case RAY_CMD_UPDATE_MCAST:
 1983                 ray_cmd_done(sc, SCP_UPD_MCAST);
 1984                 if (stat == RAY_CCS_STATUS_FAIL)
 1985                         rcmd = ray_reset;
 1986                 break;
 1987         case RAY_CMD_START_NET:
 1988         case RAY_CMD_JOIN_NET:
 1989                 rcmd = ray_start_join_net_done(sc, cmd, ccs, stat);
 1990                 break;
 1991         case RAY_CMD_TX_REQ:
 1992                 if (sc->sc_if.if_flags & IFF_OACTIVE) {
 1993                         sc->sc_if.if_flags &= ~IFF_OACTIVE;
 1994                         /* this may also be a problem */
 1995                         rcmd = ray_intr_start;
 1996                 }
 1997                 /* free it -- no tracking */
 1998                 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd, c_status,
 1999                     RAY_CCS_STATUS_FREE);
 2000                 goto done;
 2001         case RAY_CMD_START_ASSOC:
 2002                 ray_cmd_done(sc, SCP_STARTASSOC);
 2003                 if (stat == RAY_CCS_STATUS_FAIL)
 2004                         rcmd = ray_start_join_net;      /* XXX check */
 2005                 else {
 2006                         sc->sc_havenet = 1;
 2007                         rcmd = ray_intr_start;
 2008                 }
 2009                 break;
 2010         case RAY_CMD_UPDATE_APM:
 2011         case RAY_CMD_TEST_MEM:
 2012         case RAY_CMD_SHUTDOWN:
 2013         case RAY_CMD_DUMP_MEM:
 2014         case RAY_CMD_START_TIMER:
 2015                 break;
 2016         default:
 2017                 printf("%s: intr: unknown command 0x%x\n",
 2018                     sc->sc_if.if_xname, cmd);
 2019                 break;
 2020         }
 2021         ray_free_ccs(sc, ccs);
 2022 done:
 2023         /*
 2024          * see if needed things can be done now that a command
 2025          * has completed
 2026          */
 2027         ray_check_scheduled(sc);
 2028 
 2029         return (rcmd);
 2030 }
 2031 
 2032 /*
 2033  * an unsolicited interrupt, i.e., the ECF is sending us a command
 2034  */
 2035 ray_cmd_func_t
 2036 ray_rccs_intr(struct ray_softc *sc, bus_size_t ccs)
 2037 {
 2038         ray_cmd_func_t rcmd;
 2039         u_int cmd, stat;
 2040 
 2041         cmd = SRAM_READ_FIELD_1(sc, ccs, ray_cmd, c_cmd);
 2042         stat = SRAM_READ_FIELD_1(sc, ccs, ray_cmd, c_status);
 2043 
 2044         RAY_DPRINTF(("%s: ray_rccs_intr idx %ld cmd 0x%x stat %d\n",
 2045             sc->sc_xname, RAY_GET_INDEX(ccs), cmd, stat));
 2046 
 2047         rcmd = 0;
 2048         switch (cmd) {
 2049         /*
 2050          * unsolicited commands
 2051          */
 2052         case RAY_ECMD_RX_DONE:
 2053                 ray_recv(sc, ccs);
 2054                 goto done;
 2055         case RAY_ECMD_REJOIN_DONE:
 2056                 if (sc->sc_mode == SC_MODE_ADHOC)
 2057                         break;
 2058                 /* get the current ssid */
 2059                 SRAM_READ_FIELD_N(sc, ccs, ray_cmd_net, c_bss_id,
 2060                     sc->sc_bssid, sizeof(sc->sc_bssid));
 2061                 rcmd = ray_start_assoc;
 2062                 break;
 2063         case RAY_ECMD_ROAM_START:
 2064                 /* no longer have network */
 2065                 sc->sc_havenet = 0;
 2066                 break;
 2067         case RAY_ECMD_JAPAN_CALL_SIGNAL:
 2068                 break;
 2069         default:
 2070                 ray_update_error_counters(sc);
 2071 
 2072                 /* this is a bogus return from build 4 don't free 0x55 */
 2073                 if (sc->sc_version == SC_BUILD_4 && cmd == 0x55
 2074                     && RAY_GET_INDEX(ccs) == 0x55) {
 2075                         goto done;
 2076                 }
 2077                 printf("%s: intr: unknown command 0x%x\n",
 2078                     sc->sc_if.if_xname, cmd);
 2079                 break;
 2080         }
 2081         /* free the ccs */
 2082         SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd, c_status, RAY_CCS_STATUS_FREE);
 2083 done:
 2084         return (rcmd);
 2085 }
 2086 
 2087 /*
 2088  * process an interrupt
 2089  */
 2090 int
 2091 ray_intr(void *arg)
 2092 {
 2093         struct ray_softc *sc;
 2094         ray_cmd_func_t rcmd;
 2095         u_int i, count;
 2096 
 2097         sc = arg;
 2098 
 2099         RAY_DPRINTF(("%s: ray_intr\n", sc->sc_xname));
 2100 
 2101         if ((++sc->sc_checkcounters % 32) == 0)
 2102                 ray_update_error_counters(sc);
 2103 
 2104         count = 0;
 2105         rcmd = 0;
 2106         if (!REG_READ(sc, RAY_HCSIR))
 2107                 count = 0;
 2108         else {
 2109                 count = 1;
 2110                 i = SRAM_READ_1(sc, RAY_SCB_RCCSI);
 2111                 if (i <= RAY_CCS_LAST)
 2112                         rcmd = ray_ccs_done(sc, RAY_GET_CCS(i));
 2113                 else if (i <= RAY_RCCS_LAST)
 2114                         rcmd = ray_rccs_intr(sc, RAY_GET_CCS(i));
 2115                 else
 2116                         printf("%s: intr: bad cmd index %d\n", sc->sc_xname, i);
 2117         }
 2118 
 2119         if (rcmd)
 2120                 (*rcmd)(sc);
 2121 
 2122         if (count)
 2123                 REG_WRITE(sc, RAY_HCSIR, 0);
 2124 
 2125         RAY_DPRINTF(("%s: interrupt handled %d\n", sc->sc_xname, count));
 2126 
 2127         return (count ? 1 : 0);
 2128 }
 2129 
 2130 
 2131 /*
 2132  * Generic CCS handling
 2133  */
 2134 
 2135 /*
 2136  * free the chain of descriptors -- used for freeing allocated tx chains
 2137  */
 2138 void
 2139 ray_free_ccs_chain(struct ray_softc *sc, u_int ni)
 2140 {
 2141         u_int i;
 2142 
 2143         while ((i = ni) != RAY_CCS_LINK_NULL) {
 2144                 ni = SRAM_READ_FIELD_1(sc, RAY_GET_CCS(i), ray_cmd, c_link);
 2145                 SRAM_WRITE_FIELD_1(sc, RAY_GET_CCS(i), ray_cmd, c_status,
 2146                     RAY_CCS_STATUS_FREE);
 2147         }
 2148 }
 2149 
 2150 /*
 2151  * free up a cmd and return the old status
 2152  * this routine is only used for commands
 2153  */
 2154 u_int8_t
 2155 ray_free_ccs(struct ray_softc *sc, bus_size_t ccs)
 2156 {
 2157         u_int8_t stat;
 2158 
 2159         RAY_DPRINTF(("%s: free_ccs idx %ld\n", sc->sc_xname,
 2160             RAY_GET_INDEX(ccs)));
 2161 
 2162         stat = SRAM_READ_FIELD_1(sc, ccs, ray_cmd, c_status);
 2163         SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd, c_status, RAY_CCS_STATUS_FREE);
 2164         if (ccs <= RAY_GET_CCS(RAY_CCS_LAST))
 2165                 sc->sc_ccsinuse[RAY_GET_INDEX(ccs)] = 0;
 2166 
 2167         return (stat);
 2168 }
 2169 
 2170 /*
 2171  * returns 1 and in `ccb' the bus offset of the free ccb
 2172  * or 0 if none are free
 2173  *
 2174  * If `track' is not zero, handles tracking this command
 2175  * possibly indicating a callback is needed and setting a timeout
 2176  * also if ECF isn't ready we terminate earlier to avoid overhead.
 2177  *
 2178  * this routine is only used for commands
 2179  */
 2180 int
 2181 ray_alloc_ccs(struct ray_softc *sc, bus_size_t *ccsp, u_int cmd, u_int track)
 2182 {
 2183         bus_size_t ccs;
 2184         u_int i;
 2185 
 2186         RAY_DPRINTF(("%s: alloc_ccs cmd %d\n", sc->sc_xname, cmd));
 2187 
 2188         /* for tracked commands, if not ready just set pending */
 2189         if (track && !RAY_ECF_READY(sc)) {
 2190                 ray_cmd_schedule(sc, track);
 2191                 return (0);
 2192         }
 2193 
 2194         /* first scan our inuse array */
 2195         for (i = RAY_CCS_CMD_FIRST; i <= RAY_CCS_CMD_LAST; i++) {
 2196                 /* XXX wonder if we have to probe here to make the card go */
 2197                 (void)SRAM_READ_FIELD_1(sc, RAY_GET_CCS(i), ray_cmd, c_status);
 2198                 if (!sc->sc_ccsinuse[i])
 2199                         break;
 2200         }
 2201         if (i > RAY_CCS_CMD_LAST) {
 2202                 if (track)
 2203                         ray_cmd_schedule(sc, track);
 2204                 return (0);
 2205         }
 2206         sc->sc_ccsinuse[i] = 1;
 2207         ccs = RAY_GET_CCS(i);
 2208         SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd, c_status, RAY_CCS_STATUS_BUSY);
 2209         SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd, c_cmd, cmd);
 2210         SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd, c_link, RAY_CCS_LINK_NULL);
 2211 
 2212         *ccsp = ccs;
 2213         return (1);
 2214 }
 2215 
 2216 
 2217 /*
 2218  * this function sets the pending bit for the command given in 'need'
 2219  * and schedules a timeout if none is scheduled already.  Any command
 2220  * that uses the `host to ecf' region must be serialized.
 2221  */
 2222 void
 2223 ray_set_pending(struct ray_softc *sc, u_int cmdf)
 2224 {
 2225         RAY_DPRINTF(("%s: ray_set_pending 0x%x\n", sc->sc_xname, cmdf));
 2226 
 2227         sc->sc_scheduled |= cmdf;
 2228         if (!sc->sc_timoneed) {
 2229                 RAY_DPRINTF(("%s: ray_set_pending new timo\n", sc->sc_xname));
 2230                 callout_reset(&sc->sc_check_scheduled_ch,
 2231                     RAY_CHECK_SCHED_TIMEOUT, ray_check_scheduled, sc);
 2232                 sc->sc_timoneed = 1;
 2233         }
 2234 }
 2235 
 2236 /*
 2237  * schedule the `cmdf' for completion later
 2238  */
 2239 void
 2240 ray_cmd_schedule(struct ray_softc *sc, int cmdf)
 2241 {
 2242         int track;
 2243 
 2244         RAY_DPRINTF(("%s: ray_cmd_schedule 0x%x\n", sc->sc_xname, cmdf));
 2245 
 2246         track = cmdf;
 2247         if ((cmdf & SCP_UPD_MASK) == 0)
 2248                 ray_set_pending(sc, track);
 2249         else if (ray_cmd_is_running(sc, SCP_UPDATESUBCMD)) {
 2250                 /* don't do timeout mechanism if subcmd already going */
 2251                 sc->sc_scheduled |= cmdf;
 2252         } else
 2253                 ray_set_pending(sc, cmdf | SCP_UPDATESUBCMD);
 2254 }
 2255 
 2256 /*
 2257  * check to see if `cmdf' has been scheduled
 2258  */
 2259 int
 2260 ray_cmd_is_scheduled(struct ray_softc *sc, int cmdf)
 2261 {
 2262         RAY_DPRINTF(("%s: ray_cmd_is_scheduled 0x%x\n", sc->sc_xname, cmdf));
 2263 
 2264         return ((sc->sc_scheduled & cmdf) ? 1 : 0);
 2265 }
 2266 
 2267 /*
 2268  * cancel a scheduled command (not a running one though!)
 2269  */
 2270 void
 2271 ray_cmd_cancel(struct ray_softc *sc, int cmdf)
 2272 {
 2273         RAY_DPRINTF(("%s: ray_cmd_cancel 0x%x\n", sc->sc_xname, cmdf));
 2274 
 2275         sc->sc_scheduled &= ~cmdf;
 2276         if ((cmdf & SCP_UPD_MASK) && (sc->sc_scheduled & SCP_UPD_MASK) == 0)
 2277                 sc->sc_scheduled &= ~SCP_UPDATESUBCMD;
 2278 
 2279         /* if nothing else needed cancel the timer */
 2280         if (sc->sc_scheduled == 0 && sc->sc_timoneed) {
 2281                 callout_stop(&sc->sc_check_scheduled_ch);
 2282                 sc->sc_timoneed = 0;
 2283         }
 2284 }
 2285 
 2286 /*
 2287  * called to indicate the 'cmdf' has been issued
 2288  */
 2289 void
 2290 ray_cmd_ran(struct ray_softc *sc, int cmdf)
 2291 {
 2292         RAY_DPRINTF(("%s: ray_cmd_ran 0x%x\n", sc->sc_xname, cmdf));
 2293 
 2294         if (cmdf & SCP_UPD_MASK)
 2295                 sc->sc_running |= cmdf | SCP_UPDATESUBCMD;
 2296         else
 2297                 sc->sc_running |= cmdf;
 2298 
 2299         if ((cmdf & SCP_TIMOCHECK_CMD_MASK) && !sc->sc_timocheck) {
 2300                 callout_reset(&sc->sc_check_ccs_ch, RAY_CHECK_CCS_TIMEOUT,
 2301                     ray_check_ccs, sc);
 2302                 sc->sc_timocheck = 1;
 2303         }
 2304 }
 2305 
 2306 /*
 2307  * check to see if `cmdf' has been issued
 2308  */
 2309 int
 2310 ray_cmd_is_running(struct ray_softc *sc, int cmdf)
 2311 {
 2312         RAY_DPRINTF(("%s: ray_cmd_is_running 0x%x\n", sc->sc_xname, cmdf));
 2313 
 2314         return ((sc->sc_running & cmdf) ? 1 : 0);
 2315 }
 2316 
 2317 /*
 2318  * the given `cmdf' that was issued has completed
 2319  */
 2320 void
 2321 ray_cmd_done(struct ray_softc *sc, int cmdf)
 2322 {
 2323         RAY_DPRINTF(("%s: ray_cmd_done 0x%x\n", sc->sc_xname, cmdf));
 2324 
 2325         sc->sc_running &= ~cmdf;
 2326         if (cmdf & SCP_UPD_MASK) {
 2327                 sc->sc_running &= ~SCP_UPDATESUBCMD;
 2328                 if (sc->sc_scheduled & SCP_UPD_MASK)
 2329                         ray_cmd_schedule(sc, sc->sc_scheduled & SCP_UPD_MASK);
 2330         }
 2331         if ((sc->sc_running & SCP_TIMOCHECK_CMD_MASK) == 0 && sc->sc_timocheck){
 2332                 callout_stop(&sc->sc_check_ccs_ch);
 2333                 sc->sc_timocheck = 0;
 2334         }
 2335 }
 2336 
 2337 /*
 2338  * issue the command
 2339  * only used for commands not tx
 2340  */
 2341 int
 2342 ray_issue_cmd(struct ray_softc *sc, bus_size_t ccs, u_int track)
 2343 {
 2344         u_int i;
 2345 
 2346         RAY_DPRINTF(("%s: ray_cmd_issue 0x%x\n", sc->sc_xname, track));
 2347 
 2348         /*
 2349          * XXX other drivers did this, but I think
 2350          * what we really want to do is just make sure we don't
 2351          * get here or that spinning is ok
 2352          */
 2353         i = 0;
 2354         while (!RAY_ECF_READY(sc))
 2355                 if (++i > 50) {
 2356                         ray_free_ccs(sc, ccs);
 2357                         if (track)
 2358                                 ray_cmd_schedule(sc, track);
 2359                         return (0);
 2360                 }
 2361 
 2362         SRAM_WRITE_1(sc, RAY_SCB_CCSI, RAY_GET_INDEX(ccs));
 2363         RAY_ECF_START_CMD(sc);
 2364         ray_cmd_ran(sc, track);
 2365 
 2366         return (1);
 2367 }
 2368 
 2369 /*
 2370  * send a simple command if we can
 2371  */
 2372 int
 2373 ray_simple_cmd(struct ray_softc *sc, u_int cmd, u_int track)
 2374 {
 2375         bus_size_t ccs;
 2376 
 2377         return (ray_alloc_ccs(sc, &ccs, cmd, track) &&
 2378             ray_issue_cmd(sc, ccs, track));
 2379 }
 2380 
 2381 /*
 2382  * Functions based on CCS commands
 2383  */
 2384 
 2385 /*
 2386  * run a update subcommand
 2387  */
 2388 void
 2389 ray_update_subcmd(struct ray_softc *sc)
 2390 {
 2391         int submask, i;
 2392 
 2393         RAY_DPRINTF(("%s: ray_update_subcmd\n", sc->sc_xname));
 2394 
 2395         ray_cmd_cancel(sc, SCP_UPDATESUBCMD);
 2396         if ((sc->sc_if.if_flags & IFF_RUNNING) == 0)
 2397                 return;
 2398         submask = SCP_UPD_FIRST;
 2399         for (i = 0; i < ray_nsubcmdtab; submask <<= 1, i++) {
 2400                 if ((sc->sc_scheduled & SCP_UPD_MASK) == 0)
 2401                         break;
 2402                 /* when done the next command will be scheduled */
 2403                 if (ray_cmd_is_running(sc, SCP_UPDATESUBCMD))
 2404                         break;
 2405                 if (!RAY_ECF_READY(sc))
 2406                         break;
 2407                 /*
 2408                  * give priority to LSB -- e.g., if previous loop rescheduled
 2409                  * doing this command after calling the function won't catch
 2410                  * if a later command sets an earlier bit
 2411                  */
 2412                 if (sc->sc_scheduled & ((submask - 1) & SCP_UPD_MASK))
 2413                         break;
 2414                 if (sc->sc_scheduled & submask)
 2415                         (*ray_subcmdtab[i])(sc);
 2416         }
 2417 }
 2418 
 2419 /*
 2420  * report a parameter
 2421  */
 2422 void
 2423 ray_report_params(struct ray_softc *sc)
 2424 {
 2425         bus_size_t ccs;
 2426 
 2427         ray_cmd_cancel(sc, SCP_REPORTPARAMS);
 2428 
 2429         if (!sc->sc_repreq)
 2430                 return;
 2431 
 2432         /* do the issue check before equality check */
 2433         if ((sc->sc_if.if_flags & IFF_RUNNING) == 0)
 2434                 return;
 2435         else if (ray_cmd_is_running(sc, SCP_REPORTPARAMS)) {
 2436                 ray_cmd_schedule(sc, SCP_REPORTPARAMS);
 2437                 return;
 2438         } else if (!ray_alloc_ccs(sc, &ccs, RAY_CMD_REPORT_PARAMS,
 2439             SCP_REPORTPARAMS))
 2440                 return;
 2441 
 2442         SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_report, c_paramid,
 2443             sc->sc_repreq->r_paramid);
 2444         SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_report, c_nparam, 1);
 2445         (void)ray_issue_cmd(sc, ccs, SCP_REPORTPARAMS);
 2446 }
 2447 
 2448 /*
 2449  * start an association
 2450  */
 2451 void
 2452 ray_start_assoc(struct ray_softc *sc)
 2453 {
 2454         ray_cmd_cancel(sc, SCP_STARTASSOC);
 2455         if ((sc->sc_if.if_flags & IFF_RUNNING) == 0)
 2456                 return;
 2457         else if (ray_cmd_is_running(sc, SCP_STARTASSOC))
 2458                 return;
 2459         (void)ray_simple_cmd(sc, RAY_CMD_START_ASSOC, SCP_STARTASSOC);
 2460 }
 2461 
 2462 /*
 2463  * Subcommand functions that use the SCP_UPDATESUBCMD command
 2464  * (and are serialized with respect to other update sub commands
 2465  */
 2466 
 2467 /*
 2468  * download the startup parameters to the card
 2469  *      -- no outstanding commands expected
 2470  */
 2471 void
 2472 ray_download_params(struct ray_softc *sc)
 2473 {
 2474         struct ray_startup_params_head *sp;
 2475         struct ray_startup_params_tail_5 *sp5;
 2476         struct ray_startup_params_tail_4 *sp4;
 2477         bus_size_t off;
 2478 
 2479         RAY_DPRINTF(("%s: init_startup_params\n", sc->sc_xname));
 2480 
 2481         ray_cmd_cancel(sc, SCP_UPD_STARTUP);
 2482 
 2483 #define PUT2(p, v)      \
 2484         do { (p)[0] = ((v >> 8) & 0xff); (p)[1] = (v & 0xff); } while(0)
 2485 
 2486         sp = &sc->sc_startup;
 2487         sp4 = &sc->sc_startup_4;
 2488         sp5 = &sc->sc_startup_5;
 2489         memset(sp, 0, sizeof(*sp));
 2490         if (sc->sc_version == SC_BUILD_4)
 2491                 memset(sp4, 0, sizeof(*sp4));
 2492         else
 2493                 memset(sp5, 0, sizeof(*sp5));
 2494         /* XXX: Raylink firmware doesn't have length field for ssid */
 2495         memcpy(sp->sp_ssid, sc->sc_dnwid.i_nwid, sizeof(sp->sp_ssid));
 2496         sp->sp_scan_mode = 0x1;
 2497         memcpy(sp->sp_mac_addr, sc->sc_ecf_startup.e_station_addr,
 2498             ETHER_ADDR_LEN);
 2499         PUT2(sp->sp_frag_thresh, 0x7fff);       /* disabled */
 2500         if (sc->sc_version == SC_BUILD_4) {
 2501 #if 1
 2502                 /* linux/fbsd */
 2503                 PUT2(sp->sp_dwell_time, 0x200);
 2504                 PUT2(sp->sp_beacon_period, 1);
 2505 #else
 2506                 /* divined */
 2507                 PUT2(sp->sp_dwell_time, 0x400);
 2508                 PUT2(sp->sp_beacon_period, 0);
 2509 #endif
 2510         } else {
 2511                 PUT2(sp->sp_dwell_time, 128);
 2512                 PUT2(sp->sp_beacon_period, 256);
 2513         }
 2514         sp->sp_dtim_interval = 1;
 2515 #if 0
 2516         /* these are the documented defaults for build 5/6 */
 2517         sp->sp_max_retry = 0x1f;
 2518         sp->sp_ack_timo = 0x86;
 2519         sp->sp_sifs = 0x1c;
 2520 #elif 1
 2521         /* these were scrounged from the linux driver */
 2522         sp->sp_max_retry = 0x07;
 2523 
 2524         sp->sp_ack_timo = 0xa3;
 2525         sp->sp_sifs = 0x1d;
 2526 #else
 2527         /* these were divined */
 2528         sp->sp_max_retry = 0x03;
 2529 
 2530         sp->sp_ack_timo = 0xa3;
 2531         sp->sp_sifs = 0x1d;
 2532 #endif
 2533 #if 0
 2534         /* these are the documented defaults for build 5/6 */
 2535         sp->sp_difs = 0x82;
 2536         sp->sp_pifs = 0;
 2537 #else
 2538         /* linux/fbsd */
 2539         sp->sp_difs = 0x82;
 2540 
 2541         if (sc->sc_version == SC_BUILD_4)
 2542                 sp->sp_pifs = 0xce;
 2543         else
 2544                 sp->sp_pifs = 0x4e;
 2545 #endif
 2546 
 2547         PUT2(sp->sp_rts_thresh, 0x7fff);        /* disabled */
 2548         if (sc->sc_version == SC_BUILD_4) {
 2549                 PUT2(sp->sp_scan_dwell, 0xfb1e);
 2550                 PUT2(sp->sp_scan_max_dwell, 0xc75c);
 2551         } else {
 2552                 PUT2(sp->sp_scan_dwell, 0x4e2);
 2553                 PUT2(sp->sp_scan_max_dwell, 0x38a4);
 2554         }
 2555         sp->sp_assoc_timo = 0x5;
 2556         if (sc->sc_version == SC_BUILD_4) {
 2557 #if 1 /* obsd */
 2558                 /* linux/fbsd */
 2559                 sp->sp_adhoc_scan_cycle = 0x4;
 2560                 sp->sp_infra_scan_cycle = 0x2;
 2561                 sp->sp_infra_super_scan_cycle = 0x4;
 2562 #else
 2563                 /* divined */
 2564                 sp->sp_adhoc_scan_cycle = 0x8;
 2565                 sp->sp_infra_scan_cycle = 0x1;
 2566                 sp->sp_infra_super_scan_cycle = 0x18;
 2567 #endif
 2568         } else {
 2569                 sp->sp_adhoc_scan_cycle = 0x8;
 2570                 sp->sp_infra_scan_cycle = 0x2;
 2571                 sp->sp_infra_super_scan_cycle = 0x8;
 2572         }
 2573         sp->sp_promisc = sc->sc_promisc;
 2574         PUT2(sp->sp_uniq_word, 0x0cbd);
 2575         if (sc->sc_version == SC_BUILD_4) {
 2576         /* XXX what's this value anyway... the std says 50us */
 2577                 /* XXX sp->sp_slot_time = 0x4e; */
 2578                 sp->sp_slot_time = 0x4e;
 2579 #if 1
 2580                 /*linux/fbsd*/
 2581                 sp->sp_roam_low_snr_thresh = 0xff;
 2582 #else
 2583                 /*divined*/
 2584                 sp->sp_roam_low_snr_thresh = 0x30;
 2585 #endif
 2586         } else {
 2587                 sp->sp_slot_time = 0x32;
 2588                 sp->sp_roam_low_snr_thresh = 0xff;      /* disabled */
 2589         }
 2590 #if 1
 2591         sp->sp_low_snr_count = 0xff;            /* disabled */
 2592 #else
 2593         /* divined -- check */
 2594         sp->sp_low_snr_count = 0x07;            /* disabled */
 2595 #endif
 2596 #if 0
 2597         sp->sp_infra_missed_beacon_count = 0x2;
 2598 #elif 1
 2599         /* linux/fbsd */
 2600         sp->sp_infra_missed_beacon_count = 0x5;
 2601 #else
 2602         /* divined -- check, looks fishy */
 2603         sp->sp_infra_missed_beacon_count = 0x7;
 2604 #endif
 2605         sp->sp_adhoc_missed_beacon_count = 0xff;
 2606         sp->sp_country_code = sc->sc_dcountrycode;
 2607         sp->sp_hop_seq = 0x0b;
 2608         if (sc->sc_version == SC_BUILD_4) {
 2609                 sp->sp_hop_seq_len = 0x4e;
 2610                 sp4->sp_cw_max = 0x3f;  /* single byte on build 4 */
 2611                 sp4->sp_cw_min = 0x0f;  /* single byte on build 4 */
 2612                 sp4->sp_noise_filter_gain = 0x4;
 2613                 sp4->sp_noise_limit_offset = 0x8;
 2614                 sp4->sp_rssi_thresh_offset = 0x28;
 2615                 sp4->sp_busy_thresh_offset = 0x28;
 2616                 sp4->sp_sync_thresh = 0x07;
 2617                 sp4->sp_test_mode = 0x0;
 2618                 sp4->sp_test_min_chan = 0x2;
 2619                 sp4->sp_test_max_chan = 0x2;
 2620         } else {
 2621                 sp->sp_hop_seq_len = 0x4f;
 2622                 PUT2(sp5->sp_cw_max, 0x3f);
 2623                 PUT2(sp5->sp_cw_min, 0x0f);
 2624                 sp5->sp_noise_filter_gain = 0x4;
 2625                 sp5->sp_noise_limit_offset = 0x8;
 2626                 sp5->sp_rssi_thresh_offset = 0x28;
 2627                 sp5->sp_busy_thresh_offset = 0x28;
 2628                 sp5->sp_sync_thresh = 0x07;
 2629                 sp5->sp_test_mode = 0x0;
 2630                 sp5->sp_test_min_chan = 0x2;
 2631                 sp5->sp_test_max_chan = 0x2;
 2632 #if 0
 2633                 sp5->sp_allow_probe_resp = 0x1;
 2634 #else
 2635                 sp5->sp_allow_probe_resp = 0x0;
 2636 #endif
 2637                 sp5->sp_privacy_must_start = 0x0;
 2638                 sp5->sp_privacy_can_join = 0x0;
 2639                 sp5->sp_basic_rate_set[0] = 0x2;
 2640                     /* 2 = 1Mbps, 3 = old 2Mbps 4 = 2Mbps */
 2641         }
 2642 
 2643         /* we shouldn't be called with some command pending */
 2644         if (!RAY_ECF_READY(sc))
 2645                 panic("ray_download_params busy");
 2646 
 2647         /* write the compatible part */
 2648         off = RAY_HOST_TO_ECF_BASE;
 2649         ray_write_region(sc, off, sp, sizeof(sc->sc_startup));
 2650         off += sizeof(sc->sc_startup);
 2651         if (sc->sc_version == SC_BUILD_4)
 2652                 ray_write_region(sc, off, sp4, sizeof(*sp4));
 2653         else
 2654                 ray_write_region(sc, off, sp5, sizeof(*sp5));
 2655         if (!ray_simple_cmd(sc, RAY_CMD_START_PARAMS, SCP_UPD_STARTUP))
 2656                 panic("ray_download_params issue");
 2657 }
 2658 
 2659 /*
 2660  * start or join a network
 2661  */
 2662 void
 2663 ray_start_join_net(struct ray_softc *sc)
 2664 {
 2665         struct ray_net_params np;
 2666         bus_size_t ccs;
 2667         int cmd;
 2668 
 2669         ray_cmd_cancel(sc, SCP_UPD_STARTJOIN);
 2670         if ((sc->sc_if.if_flags & IFF_RUNNING) == 0)
 2671                 return;
 2672 
 2673         /* XXX check we may not want to re-issue */
 2674         if (ray_cmd_is_running(sc, SCP_UPDATESUBCMD)) {
 2675                 ray_cmd_schedule(sc, SCP_UPD_STARTJOIN);
 2676                 return;
 2677         }
 2678 
 2679         if (sc->sc_mode == SC_MODE_ADHOC)
 2680                 cmd = RAY_CMD_START_NET;
 2681         else
 2682                 cmd = RAY_CMD_JOIN_NET;
 2683 
 2684         if (!ray_alloc_ccs(sc, &ccs, cmd, SCP_UPD_STARTJOIN))
 2685                 return;
 2686         sc->sc_startccs = ccs;
 2687         sc->sc_startcmd = cmd;
 2688         if (!memcmp(&sc->sc_cnwid, &sc->sc_dnwid, sizeof(sc->sc_cnwid))
 2689             && sc->sc_omode == sc->sc_mode)
 2690                 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_net, c_upd_param, 0);
 2691         else {
 2692                 sc->sc_havenet = 0;
 2693                 memset(&np, 0, sizeof(np));
 2694                 np.p_net_type = sc->sc_mode;
 2695                 memcpy(np.p_ssid, sc->sc_dnwid.i_nwid, sizeof(np.p_ssid));
 2696                 ray_write_region(sc, RAY_HOST_TO_ECF_BASE, &np, sizeof(np));
 2697                 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_net, c_upd_param, 1);
 2698         }
 2699         if (ray_issue_cmd(sc, ccs, SCP_UPD_STARTJOIN))
 2700                 callout_reset(&sc->sc_start_join_timo_ch, RAY_START_TIMEOUT,
 2701                     ray_start_join_timo, sc);
 2702 }
 2703 
 2704 void
 2705 ray_start_join_timo(void *arg)
 2706 {
 2707         struct ray_softc *sc;
 2708         u_int stat;
 2709 
 2710         sc = arg;
 2711         stat = SRAM_READ_FIELD_1(sc, sc->sc_startccs, ray_cmd, c_status);
 2712         ray_start_join_net_done(sc, sc->sc_startcmd, sc->sc_startccs, stat);
 2713 }
 2714 
 2715 /*
 2716  * The start/join has completed.  Note: we timeout the start
 2717  * command because it seems to fail to work at least on the
 2718  * build 4 firmware without reporting an error.  This actually
 2719  * may be a result of not putting the correct params in the
 2720  * initial download.  If this is a timeout `stat' will be
 2721  * marked busy.
 2722  */
 2723 ray_cmd_func_t
 2724 ray_start_join_net_done(struct ray_softc *sc, u_int cmd, bus_size_t ccs, u_int stat)
 2725 {
 2726         int i;
 2727         struct ray_net_params np;
 2728 
 2729         callout_stop(&sc->sc_start_join_timo_ch);
 2730         ray_cmd_done(sc, SCP_UPD_STARTJOIN);
 2731 
 2732         if (stat == RAY_CCS_STATUS_FAIL) {
 2733                 /* XXX poke ifmedia when it supports this */
 2734                 sc->sc_havenet = 0;
 2735                 return (ray_start_join_net);
 2736         }
 2737         if (stat == RAY_CCS_STATUS_BUSY || stat == RAY_CCS_STATUS_FREE) {
 2738                 /* handle the timeout condition */
 2739                 callout_reset(&sc->sc_start_join_timo_ch, RAY_START_TIMEOUT,
 2740                     ray_start_join_timo, sc);
 2741 
 2742                 /* be safe -- not a lot occurs with no net though */
 2743                 if (!RAY_ECF_READY(sc))
 2744                         return (0);
 2745 
 2746                 /* see if our nwid is up to date */
 2747                 if (!memcmp(&sc->sc_cnwid, &sc->sc_dnwid, sizeof(sc->sc_cnwid))
 2748                     && sc->sc_omode == sc->sc_mode)
 2749                         SRAM_WRITE_FIELD_1(sc,ccs, ray_cmd_net, c_upd_param, 0);
 2750                 else {
 2751                         memset(&np, 0, sizeof(np));
 2752                         np.p_net_type = sc->sc_mode;
 2753                         memcpy(np.p_ssid, sc->sc_dnwid.i_nwid,
 2754                             sizeof(np.p_ssid));
 2755                         ray_write_region(sc, RAY_HOST_TO_ECF_BASE, &np,
 2756                             sizeof(np));
 2757                         SRAM_WRITE_FIELD_1(sc,ccs, ray_cmd_net, c_upd_param, 1);
 2758                 }
 2759 
 2760                 if (sc->sc_mode == SC_MODE_ADHOC)
 2761                         cmd = RAY_CMD_START_NET;
 2762                 else
 2763                         cmd = RAY_CMD_JOIN_NET;
 2764                 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_net, c_cmd,
 2765                     RAY_CCS_STATUS_BUSY);
 2766                 SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_net, c_status,
 2767                     RAY_CCS_STATUS_BUSY);
 2768 
 2769                 /* we simply poke the card again issuing the same ccs */
 2770                 SRAM_WRITE_1(sc, RAY_SCB_CCSI, RAY_GET_INDEX(ccs));
 2771                 RAY_ECF_START_CMD(sc);
 2772                 ray_cmd_ran(sc, SCP_UPD_STARTJOIN);
 2773                 return (0);
 2774         }
 2775         /* get the current ssid */
 2776         SRAM_READ_FIELD_N(sc, ccs, ray_cmd_net, c_bss_id, sc->sc_bssid,
 2777             sizeof(sc->sc_bssid));
 2778 
 2779         sc->sc_deftxrate = SRAM_READ_FIELD_1(sc, ccs, ray_cmd_net,c_def_txrate);
 2780         sc->sc_encrypt = SRAM_READ_FIELD_1(sc, ccs, ray_cmd_net, c_encrypt);
 2781 
 2782         /* adjust values for buggy build 4 */
 2783         if (sc->sc_deftxrate == 0x55)
 2784                 sc->sc_deftxrate = RAY_PID_BASIC_RATE_1500K;
 2785         if (sc->sc_encrypt == 0x55)
 2786                 sc->sc_encrypt = 0;
 2787 
 2788         if (SRAM_READ_FIELD_1(sc, ccs, ray_cmd_net, c_upd_param)) {
 2789                 ray_read_region(sc, RAY_HOST_TO_ECF_BASE, &np, sizeof(np));
 2790                 /* XXX: Raylink firmware doesn't have length field for ssid */
 2791                 for (i = 0; i < sizeof(np.p_ssid); i++) {
 2792                         if (np.p_ssid[i] == '\0')
 2793                                 break;
 2794                 }
 2795                 sc->sc_cnwid.i_len = i;
 2796                 memcpy(sc->sc_cnwid.i_nwid, np.p_ssid, sizeof(sc->sc_cnwid));
 2797                 sc->sc_omode = sc->sc_mode;
 2798                 if (np.p_net_type != sc->sc_mode)
 2799                         return (ray_start_join_net);
 2800         }
 2801         RAY_DPRINTF(("%s: net start/join nwid %.32s bssid %s inited %d\n",
 2802             sc->sc_xname, sc->sc_cnwid.i_nwid, ether_sprintf(sc->sc_bssid),
 2803                 SRAM_READ_FIELD_1(sc, ccs, ray_cmd_net, c_inited)));
 2804 
 2805         /* network is now active */
 2806         ray_cmd_schedule(sc, SCP_UPD_MCAST|SCP_UPD_PROMISC);
 2807         if (cmd == RAY_CMD_JOIN_NET)
 2808                 return (ray_start_assoc);
 2809         else {
 2810                 sc->sc_havenet = 1;
 2811                 return (ray_intr_start);
 2812         }
 2813 }
 2814 
 2815 /*
 2816  * set the card in/out of promiscuous mode
 2817  */
 2818 void
 2819 ray_update_promisc(struct ray_softc *sc)
 2820 {
 2821         bus_size_t ccs;
 2822         int promisc;
 2823 
 2824         ray_cmd_cancel(sc, SCP_UPD_PROMISC);
 2825 
 2826         /* do the issue check before equality check */
 2827         promisc = !!(sc->sc_if.if_flags & (IFF_PROMISC | IFF_ALLMULTI));
 2828         if ((sc->sc_if.if_flags & IFF_RUNNING) == 0)
 2829                 return;
 2830         else if (ray_cmd_is_running(sc, SCP_UPDATESUBCMD)) {
 2831                 ray_cmd_schedule(sc, SCP_UPD_PROMISC);
 2832                 return;
 2833         } else if (promisc == sc->sc_promisc)
 2834                 return;
 2835         else if (!ray_alloc_ccs(sc,&ccs,RAY_CMD_UPDATE_PARAMS, SCP_UPD_PROMISC))
 2836                 return;
 2837         SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_update, c_paramid, RAY_PID_PROMISC);
 2838         SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_update, c_nparam, 1);
 2839         SRAM_WRITE_1(sc, RAY_HOST_TO_ECF_BASE, promisc);
 2840         (void)ray_issue_cmd(sc, ccs, SCP_UPD_PROMISC);
 2841 }
 2842 
 2843 /*
 2844  * update the parameter based on what the user passed in
 2845  */
 2846 void
 2847 ray_update_params(struct ray_softc *sc)
 2848 {
 2849         bus_size_t ccs;
 2850 
 2851         ray_cmd_cancel(sc, SCP_UPD_UPDATEPARAMS);
 2852         if (!sc->sc_updreq) {
 2853                 /* XXX do we need to wakeup here? */
 2854                 return;
 2855         }
 2856 
 2857         /* do the issue check before equality check */
 2858         if ((sc->sc_if.if_flags & IFF_RUNNING) == 0)
 2859                 return;
 2860         else if (ray_cmd_is_running(sc, SCP_UPDATESUBCMD)) {
 2861                 ray_cmd_schedule(sc, SCP_UPD_UPDATEPARAMS);
 2862                 return;
 2863         } else if (!ray_alloc_ccs(sc, &ccs, RAY_CMD_UPDATE_PARAMS,
 2864             SCP_UPD_UPDATEPARAMS))
 2865                 return;
 2866 
 2867         SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_update, c_paramid,
 2868             sc->sc_updreq->r_paramid);
 2869         SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_update, c_nparam, 1);
 2870         ray_write_region(sc, RAY_HOST_TO_ECF_BASE, sc->sc_updreq->r_data,
 2871             sc->sc_updreq->r_len);
 2872 
 2873         (void)ray_issue_cmd(sc, ccs, SCP_UPD_UPDATEPARAMS);
 2874 }
 2875 
 2876 /*
 2877  * set the multicast filter list
 2878  */
 2879 void
 2880 ray_update_mcast(struct ray_softc *sc)
 2881 {
 2882         bus_size_t ccs;
 2883         struct ether_multistep step;
 2884         struct ether_multi *enm;
 2885         struct arpcom *ec;
 2886         bus_size_t bufp;
 2887         int count;
 2888 
 2889         ec = &sc->sc_ec;
 2890         ray_cmd_cancel(sc, SCP_UPD_MCAST);
 2891 
 2892         /* see if we have any ranges */
 2893         if ((count = sc->sc_ec.ec_multicnt) < 17) {
 2894                 ETHER_FIRST_MULTI(step, ec, enm);
 2895                 while (enm) {
 2896                         /* see if this is a range */
 2897                         if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
 2898                                 ETHER_ADDR_LEN)) {
 2899                                 count = 17;
 2900                                 break;
 2901                         }
 2902                         ETHER_NEXT_MULTI(step, enm);
 2903                 }
 2904         }
 2905 
 2906         /* track this stuff even when not running */
 2907         if (count > 16) {
 2908                 sc->sc_if.if_flags |= IFF_ALLMULTI;
 2909                 ray_update_promisc(sc);
 2910                 return;
 2911         } else if (sc->sc_if.if_flags & IFF_ALLMULTI) {
 2912                 sc->sc_if.if_flags &= ~IFF_ALLMULTI;
 2913                 ray_update_promisc(sc);
 2914         }
 2915 
 2916         if ((sc->sc_if.if_flags & IFF_RUNNING) == 0)
 2917                 return;
 2918         else if (ray_cmd_is_running(sc, SCP_UPDATESUBCMD)) {
 2919                 ray_cmd_schedule(sc, SCP_UPD_MCAST);
 2920                 return;
 2921         } else if (!ray_alloc_ccs(sc,&ccs, RAY_CMD_UPDATE_MCAST, SCP_UPD_MCAST))
 2922                 return;
 2923         SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_update_mcast, c_nmcast, count);
 2924         bufp = RAY_HOST_TO_ECF_BASE;
 2925         ETHER_FIRST_MULTI(step, ec, enm);
 2926         while (enm) {
 2927                 ray_write_region(sc, bufp, enm->enm_addrlo, ETHER_ADDR_LEN);
 2928                 bufp += ETHER_ADDR_LEN;
 2929                 ETHER_NEXT_MULTI(step, enm);
 2930         }
 2931         (void)ray_issue_cmd(sc, ccs, SCP_UPD_MCAST);
 2932 }
 2933 
 2934 /*
 2935  * User-issued commands
 2936  */
 2937 
 2938 /*
 2939  * issue an "update params"
 2940  *
 2941  * expected to be called in sleepable context -- intended for user stuff
 2942  */
 2943 int
 2944 ray_user_update_params(struct ray_softc *sc, struct ray_param_req *pr)
 2945 {
 2946         int rv;
 2947 
 2948         if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) {
 2949                 pr->r_failcause = RAY_FAILCAUSE_EDEVSTOP;
 2950                 return (EIO);
 2951         }
 2952 
 2953         /* wait to be able to issue the command */
 2954         rv = 0;
 2955         while (ray_cmd_is_running(sc, SCP_UPD_UPDATEPARAMS) ||
 2956             ray_cmd_is_scheduled(sc, SCP_UPD_UPDATEPARAMS)) {
 2957                 rv = tsleep(ray_update_params, 0|PCATCH, "cmd in use", 0);
 2958                 if (rv)
 2959                         return (rv);
 2960                 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) {
 2961                         pr->r_failcause = RAY_FAILCAUSE_EDEVSTOP;
 2962                         return (EIO);
 2963                 }
 2964         }
 2965 
 2966         pr->r_failcause = RAY_FAILCAUSE_WAITING;
 2967         sc->sc_updreq = pr;
 2968         ray_cmd_schedule(sc, SCP_UPD_UPDATEPARAMS);
 2969         ray_check_scheduled(sc);
 2970 
 2971         while (pr->r_failcause == RAY_FAILCAUSE_WAITING)
 2972                 (void)tsleep(ray_update_params, 0, "waiting cmd", 0);
 2973         wakeup(ray_update_params);
 2974 
 2975         return (0);
 2976 }
 2977 
 2978 /*
 2979  * issue a "report params"
 2980  *
 2981  * expected to be called in sleepable context -- intended for user stuff
 2982  */
 2983 int
 2984 ray_user_report_params(struct ray_softc *sc, struct ray_param_req *pr)
 2985 {
 2986         int rv;
 2987 
 2988         if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) {
 2989                 pr->r_failcause = RAY_FAILCAUSE_EDEVSTOP;
 2990                 return (EIO);
 2991         }
 2992 
 2993         /* wait to be able to issue the command */
 2994         rv = 0;
 2995         while (ray_cmd_is_running(sc, SCP_REPORTPARAMS)
 2996             || ray_cmd_is_scheduled(sc, SCP_REPORTPARAMS)) {
 2997                 rv = tsleep(ray_report_params, 0|PCATCH, "cmd in use", 0);
 2998                 if (rv)
 2999                         return (rv);
 3000                 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) {
 3001                         pr->r_failcause = RAY_FAILCAUSE_EDEVSTOP;
 3002                         return (EIO);
 3003                 }
 3004         }
 3005 
 3006         pr->r_failcause = RAY_FAILCAUSE_WAITING;
 3007         sc->sc_repreq = pr;
 3008         ray_cmd_schedule(sc, SCP_REPORTPARAMS);
 3009         ray_check_scheduled(sc);
 3010 
 3011         while (pr->r_failcause == RAY_FAILCAUSE_WAITING)
 3012                 (void)tsleep(ray_report_params, 0, "waiting cmd", 0);
 3013         wakeup(ray_report_params);
 3014 
 3015         return (0);
 3016 }
 3017 
 3018 
 3019 /*
 3020  * this is a temporary wrapper around bus_space_read_region_1
 3021  * as it seems to mess with gcc.  the line numbers get offset
 3022  * presumably this is related to the inline asm on i386.
 3023  */
 3024 #ifndef ray_read_region
 3025 void
 3026 ray_read_region(struct ray_softc *sc, bus_size_t off, void *vp, size_t c)
 3027 {
 3028 #ifdef RAY_USE_OPTIMIZED_COPY
 3029         u_int n2, n4, tmp;
 3030         u_int8_t *p;
 3031 
 3032         p = vp;
 3033 
 3034         /* XXX we may be making poor assumptions here but lets hope */
 3035         switch ((off|(bus_addr_t)p) & 0x03) {
 3036         case 0:
 3037                 if ((n4 = c / 4)) {
 3038                         bus_space_read_region_4(sc->sc_memt, sc->sc_memh, off,
 3039                             p, n4);
 3040                         tmp = c & ~0x3;
 3041                         c &= 0x3;
 3042                         p += tmp;
 3043                         off += tmp;
 3044                 }
 3045                 switch (c) {
 3046                 case 3:
 3047                         *p = bus_space_read_1(sc->sc_memt,sc->sc_memh, off);
 3048                         p++, off++;
 3049                 case 2:
 3050                         *p = bus_space_read_1(sc->sc_memt,sc->sc_memh, off);
 3051                         p++, off++;
 3052                 case 1:
 3053                         *p = bus_space_read_1(sc->sc_memt,sc->sc_memh, off);
 3054                 }
 3055                 break;
 3056         case 2:
 3057                 if ((n2 = (c >> 1)))
 3058                         bus_space_read_region_2(sc->sc_memt, sc->sc_memh, off,
 3059                             p, n2);
 3060                 if (c & 1) {
 3061                         c &= ~0x1;
 3062                         *(p + c) = bus_space_read_1(sc->sc_memt, sc->sc_memh,
 3063                             off + c);
 3064                 }
 3065                 break;
 3066         case 1:
 3067         case 3:
 3068                 bus_space_read_region_1(sc->sc_memt, sc->sc_memh, off, p, c);
 3069                 break;
 3070         }
 3071 #else
 3072         bus_space_read_region_1(sc->sc_memt, sc->sc_memh, off, vp, c);
 3073 #endif
 3074 }
 3075 #endif
 3076 
 3077 #ifndef ray_write_region
 3078 /*
 3079  * this is a temporary wrapper around bus_space_write_region_1
 3080  * as it seems to mess with gcc.  the line numbers get offset
 3081  * presumably this is related to the inline asm on i386.
 3082  */
 3083 void
 3084 ray_write_region(struct ray_softc *sc, bus_size_t off, void *vp, size_t c)
 3085 {
 3086 #ifdef RAY_USE_OPTIMIZED_COPY
 3087         size_t n2, n4, tmp;
 3088         u_int8_t *p;
 3089 
 3090         p = vp;
 3091         /* XXX we may be making poor assumptions here but lets hope */
 3092         switch ((off|(bus_addr_t)p) & 0x03) {
 3093         case 0:
 3094                 if ((n4 = (c >> 2))) {
 3095                         bus_space_write_region_4(sc->sc_memt, sc->sc_memh, off,
 3096                             p, n4);
 3097                         tmp = c & ~0x3;
 3098                         c &= 0x3;
 3099                         p += tmp;
 3100                         off += tmp;
 3101                 }
 3102                 switch (c) {
 3103                 case 3:
 3104                         bus_space_write_1(sc->sc_memt,sc->sc_memh, off, *p);
 3105                         p++, off++;
 3106                 case 2:
 3107                         bus_space_write_1(sc->sc_memt,sc->sc_memh, off, *p);
 3108                         p++, off++;
 3109                 case 1:
 3110                         bus_space_write_1(sc->sc_memt,sc->sc_memh, off, *p);
 3111                 }
 3112                 break;
 3113         case 2:
 3114                 if ((n2 = (c >> 1)))
 3115                         bus_space_write_region_2(sc->sc_memt, sc->sc_memh, off,
 3116                             p, n2);
 3117                 if (c & 0x1) {
 3118                         c &= ~0x1;
 3119                         bus_space_write_1(sc->sc_memt, sc->sc_memh,
 3120                             off + c, *(p + c));
 3121                 }
 3122                 break;
 3123         case 1:
 3124         case 3:
 3125                 bus_space_write_region_1(sc->sc_memt, sc->sc_memh, off, p, c);
 3126                 break;
 3127         }
 3128 #else
 3129         bus_space_write_region_1(sc->sc_memt, sc->sc_memh, off, vp, c);
 3130 #endif
 3131 }
 3132 #endif
 3133 
 3134 #ifdef RAY_DEBUG
 3135 
 3136 #define PRINTABLE(c) ((c) >= 0x20 && (c) <= 0x7f)
 3137 
 3138 void
 3139 hexdump(const u_int8_t *d, int len, int br, int div, int fl)
 3140 {
 3141         int i, j, offw, first, tlen, ni, nj, sp;
 3142 
 3143         sp = br / div;
 3144         offw = 0;
 3145         if (len && (fl & HEXDF_NOOFFSET) == 0) {
 3146                 tlen = len;
 3147                 do {
 3148                         offw++;
 3149                 } while (tlen /= br);
 3150         }
 3151         if (offw)
 3152                 printf("%0*x: ", offw, 0);
 3153         for (i = 0; i < len; i++, d++) {
 3154                 if (i && (i % br) == 0) {
 3155                         if ((fl & HEXDF_NOASCII) == 0) {
 3156                                 printf("   ");
 3157                                 d -= br;
 3158                                 for (j = 0; j < br; d++, j++) {
 3159                                         if (j && (j % sp) == 0)
 3160                                                 printf(" ");
 3161                                         if (PRINTABLE(*d))
 3162                                                 printf("%c", (int)*d);
 3163                                         else
 3164                                                 printf(".");
 3165                                 }
 3166                         }
 3167                         if (offw)
 3168                                 printf("\n%0*x: ", offw, i);
 3169                         else
 3170                                 printf("\n");
 3171                         if ((fl & HEXDF_NOCOMPRESS) == 0) {
 3172                                 first = 1;
 3173                                 while (len - i >= br) {
 3174                                         if (memcmp(d, d - br, br))
 3175                                                 break;
 3176                                         d += br;
 3177                                         i += br;
 3178                                         if (first) {
 3179                                                 printf("*");
 3180                                                 first = 0;
 3181                                         }
 3182                                 }
 3183                                 if (len == i) {
 3184                                         printf("\n%0*x", offw, i);
 3185                                         return;
 3186                                 }
 3187                         }
 3188                 } else if (i && (i % sp) == 0)
 3189                         printf(" ");
 3190                 printf("%02x ", *d);
 3191         }
 3192         if (len && (((i - 1) % br) || i == 1)) {
 3193                 if ((fl & HEXDF_NOASCII) == 0) {
 3194                         i = i % br ? i % br : br;
 3195                         ni = (br - i) % br;
 3196                         j = (i - 1) / sp;
 3197                         nj = (div - j - 1) % div;
 3198                         j = 3 * ni + nj + 3;
 3199                         printf("%*s", j, "");
 3200                         d -= i;
 3201                         for (j = 0; j < i; d++, j++) {
 3202                                 if (j && (j % sp) == 0)
 3203                                         printf(" ");
 3204                                 if (PRINTABLE(*d))
 3205                                         printf("%c", (int)*d);
 3206                                 else
 3207                                         printf(".");
 3208                         }
 3209                 }
 3210                 printf("\n");
 3211         }
 3212 }
 3213 
 3214 
 3215 
 3216 void
 3217 ray_dump_mbuf(struct ray_softc *sc, struct mbuf *m)
 3218 {
 3219         u_int8_t *d, *ed;
 3220         u_int i;
 3221 
 3222         printf("%s: pkt dump:", sc->sc_xname);
 3223         i = 0;
 3224         for (; m; m = m->m_next) {
 3225                 d = mtod(m, u_int8_t *);
 3226                 ed = d + m->m_len;
 3227 
 3228                 for (; d < ed; i++, d++) {
 3229                         if ((i % 16) == 0)
 3230                                 printf("\n\t");
 3231                         else if ((i % 8) == 0)
 3232                                 printf("  ");
 3233                         printf(" %02x", *d);
 3234                 }
 3235         }
 3236         if ((i - 1) % 16)
 3237                 printf("\n");
 3238 }
 3239 #endif  /* RAY_DEBUG */
 3240 
 3241 #ifdef RAY_DO_SIGLEV
 3242 void
 3243 ray_update_siglev(struct ray_softc *sc, u_int8_t *src, u_int8_t siglev)
 3244 {
 3245         int i, mini;
 3246         struct timeval mint;
 3247         struct ray_siglev *sl;
 3248 
 3249         /* try to find host */
 3250         for (i = 0; i < RAY_NSIGLEVRECS; i++) {
 3251                 sl = &sc->sc_siglevs[i];
 3252                 if (memcmp(sl->rsl_host, src, ETHER_ADDR_LEN) == 0)
 3253                         goto found;
 3254         }
 3255         /* not found, find oldest slot */
 3256         mini = 0;
 3257         mint.tv_sec = LONG_MAX;
 3258         mint.tv_usec = 0;
 3259         for (i = 0; i < RAY_NSIGLEVRECS; i++) {
 3260                 sl = &sc->sc_siglevs[i];
 3261                 if (timercmp(&sl->rsl_time, &mint, <)) {
 3262                         mini = i;
 3263                         mint = sl->rsl_time;
 3264                 }
 3265         }
 3266         sl = &sc->sc_siglevs[mini];
 3267         memset(sl->rsl_siglevs, 0, RAY_NSIGLEV);
 3268         memcpy(sl->rsl_host, src, ETHER_ADDR_LEN);
 3269 
 3270  found:
 3271         microtime(&sl->rsl_time);
 3272         memmove(&sl->rsl_siglevs[1], sl->rsl_siglevs, RAY_NSIGLEV-1);
 3273         sl->rsl_siglevs[0] = siglev;
 3274 }
 3275 #endif

/* [<][>][^][v][top][bottom][index][help] */