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