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