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