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