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