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