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