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