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